[
  {
    "path": ".github/workflows/publish-container.yml",
    "content": "name: Publish Container Image\n\non:\n  push:\n    tags:\n      - 'v*'\n  workflow_dispatch:\n    inputs:\n      tag:\n        description: 'Tag to build and publish'\n        required: true\n        type: string\n\njobs:\n  build-and-push:\n    runs-on: ubuntu-latest\n    permissions:\n      contents: read\n      packages: write\n\n    steps:\n      - name: Checkout repository\n        uses: actions/checkout@v6\n        with:\n          ref: ${{ github.event_name == 'workflow_dispatch' && inputs.tag || github.ref }}\n\n      - name: Set up QEMU\n        uses: docker/setup-qemu-action@v3\n\n      - name: Set up Docker Buildx\n        uses: docker/setup-buildx-action@v3\n\n      - name: Free disk space\n        run: |\n          echo \"Disk space before cleanup:\"\n          df -h\n          sudo rm -rf /usr/share/dotnet /usr/local/lib/android /opt/ghc /opt/hostedtoolcache/CodeQL\n          sudo docker image prune --all --force\n          sudo docker builder prune -a -f\n          echo \"Disk space after cleanup:\"\n          df -h\n\n      - name: Log in to GitHub Container Registry\n        uses: docker/login-action@v3\n        with:\n          registry: ghcr.io\n          username: ${{ github.actor }}\n          password: ${{ secrets.GITHUB_TOKEN }}\n\n      - name: Extract metadata for Docker\n        id: meta\n        uses: docker/metadata-action@v5\n        with:\n          images: ghcr.io/${{ github.repository }}\n          tags: |\n            type=semver,pattern={{version}}\n            type=semver,pattern={{major}}.{{minor}}\n            type=raw,value=latest,enable=${{ github.event_name != 'workflow_dispatch' && github.ref == format('refs/tags/{0}', github.ref_name) }}\n            type=raw,value=${{ github.event.inputs.tag }},enable=${{ github.event_name == 'workflow_dispatch' }}\n            type=sha,prefix=,suffix=-${{ github.sha }}\n\n      - name: Build and push Docker image\n        uses: docker/build-push-action@v6\n        with:\n          context: .\n          file: ./deploy/Dockerfile\n          platforms: linux/amd64,linux/arm64\n          push: true\n          tags: ${{ steps.meta.outputs.tags }}\n          labels: ${{ steps.meta.outputs.labels }}\n          build-args: |\n            VERSION=${{ github.event_name == 'workflow_dispatch' && inputs.tag || github.ref_name }}\n"
  },
  {
    "path": ".github/workflows/release-binaries.yml",
    "content": "name: Release Binaries\n\non:\n  push:\n    tags:\n      - 'v*'\n  workflow_dispatch:\n    inputs:\n      tag:\n        description: 'Tag to build and publish'\n        required: true\n        type: string\n\njobs:\n  build-linux-binaries:\n    runs-on: ubuntu-latest\n    strategy:\n      matrix:\n        arch: [amd64, arm64]\n    steps:\n      - name: Checkout repository\n        uses: actions/checkout@v6\n        with:\n          ref: ${{ github.event_name == 'workflow_dispatch' && inputs.tag || github.ref }}\n          fetch-depth: 0  # Fetch all history for proper versioning\n\n      - name: Set up Docker\n        uses: docker/setup-buildx-action@v3\n\n      - name: Set up QEMU\n        uses: docker/setup-qemu-action@v3\n        with:\n          platforms: linux/amd64,linux/arm64\n\n      - name: Set VERSION environment variable\n        run: |\n          if [ \"${{ github.event_name }}\" = \"workflow_dispatch\" ]; then\n            echo \"VERSION=${INPUTS_TAG}\" >> $GITHUB_ENV\n          else\n            echo \"VERSION=${GITHUB_REF#refs/tags/}\" >> $GITHUB_ENV\n          fi\n        env:\n          INPUTS_TAG: ${{ inputs.tag }}\n\n      - name: Build Linux ${{ matrix.arch }} binary\n        env:\n          GOARCH: ${{ matrix.arch }}\n          OUTPUT_NAME_WITH_ARCH: \"true\"\n          VERSION: ${{ env.VERSION }}\n        run: |\n          # Create a Docker container with the appropriate architecture\n          docker run --rm -v ${PWD}:/go/src/github.com/google/cadvisor \\\n            --platform linux/${{ matrix.arch }} \\\n            golang:1.25 \\\n            /bin/bash -c \"cd /go/src/github.com/google/cadvisor && GOARCH=${{ matrix.arch }} OUTPUT_NAME_WITH_ARCH=true VERSION=${VERSION} GO_FLAGS='-buildvcs=false -tags=netgo' GO_CGO_ENABLED=0 ./build/build.sh\"\n\n      - name: Generate SHA256 checksums\n        run: |\n          cd _output\n          # List all files in the output directory\n          ls -la\n          # Generate SHA256 checksums for all binaries\n          find . -name \"cadvisor*\" -type f -not -name \"*.sha256\" -exec sh -c 'sha256sum \"$1\" > \"$1.sha256\"' _ {} \\;\n\n      - name: Upload artifacts\n        uses: actions/upload-artifact@v6\n        with:\n          name: cadvisor-linux-${{ matrix.arch }}\n          path: |\n            _output/cadvisor*\n          retention-days: 1\n\n  create-release:\n    needs: build-linux-binaries\n    runs-on: ubuntu-latest\n    permissions:\n      contents: write  # Needed for creating GitHub releases\n    steps:\n      - name: Checkout repository\n        uses: actions/checkout@v6\n        with:\n          ref: ${{ github.event_name == 'workflow_dispatch' && inputs.tag || github.ref }}\n\n      - name: Set VERSION environment variable\n        run: |\n          if [ \"${{ github.event_name }}\" = \"workflow_dispatch\" ]; then\n            echo \"VERSION=${INPUTS_TAG}\" >> $GITHUB_ENV\n          else\n            echo \"VERSION=${GITHUB_REF#refs/tags/}\" >> $GITHUB_ENV\n          fi\n        env:\n          INPUTS_TAG: ${{ inputs.tag }}\n\n      - name: Download all artifacts\n        uses: actions/download-artifact@v7\n        with:\n          path: artifacts\n\n      - name: Display structure of downloaded files\n        run: ls -R artifacts\n\n      - name: Create Release\n        id: create_release\n        uses: softprops/action-gh-release@v2\n        with:\n          tag_name: ${{ env.VERSION }}\n          name: cAdvisor ${{ env.VERSION }}\n          draft: false\n          prerelease: ${{ contains(env.VERSION, 'alpha') || contains(env.VERSION, 'beta') || contains(env.VERSION, 'rc') }}\n          generate_release_notes: true\n          files: |\n            artifacts/**/*\n"
  },
  {
    "path": ".github/workflows/stale.yaml",
    "content": "name: Stale issues and pull requests\n\non:\n  schedule:\n  - cron: \"21 4 * * *\"\n  workflow_dispatch:\n\njobs:\n  stale:\n    permissions:\n      issues: write\n      pull-requests: write\n    runs-on: ubuntu-latest\n\n    steps:\n    - uses: actions/stale@v10\n      with:\n        stale-issue-message: 'This issue is stale because it has been open 90 days with no activity. This issue will be closed in 30 days unless new comments are made or the stale label is removed. To skip these checks, apply the \"lifecycle/frozen\" label.'\n        stale-pr-message: 'This PR is stale because it has been open 90 days with no activity. This PR will be closed in 30 days unless new comments are made or the stale label is removed. To skip these checks, apply the \"lifecycle/frozen\" label.'\n        stale-issue-label: 'lifecycle/stale'\n        stale-pr-label: 'lifecycle/stale'\n        exempt-issue-labels: 'lifecycle/frozen'\n        exempt-pr-labels: 'lifecycle/frozen'\n        days-before-stale: 90\n        close-issue-message: 'This issue was automatically closed due to inactivity.'\n        close-pr-message: 'This pull request was automatically closed due to inactivity.'\n        days-before-issue-close: 30\n        days-before-pr-close: 30\n        remove-stale-when-updated: true\n        operations-per-run: 300\n"
  },
  {
    "path": ".github/workflows/test.yml",
    "content": "name: Test\non: [push, pull_request]\njobs:\n  test:\n    strategy:\n      matrix:\n        go-versions: ['1.25']\n        platform: [ubuntu-24.04]\n        environment-variables: [build/config/plain.sh, build/config/libpfm4.sh, build/config/libipmctl.sh]\n    runs-on: ${{ matrix.platform }}\n    timeout-minutes: 30\n    steps:\n    - name: Install Go\n      uses: actions/setup-go@v6\n      with:\n        go-version: ${{ matrix.go-versions }}\n        check-latest: true\n    - name: Checkout code\n      uses: actions/checkout@v6\n    - name: Run presubmit checks\n      run: |\n        source ${{ matrix.environment-variables }}\n        if [[ \"${BUILD_PACKAGES}\" != \"\" ]]; then sudo apt-get update; sudo apt-get install ${BUILD_PACKAGES}; fi\n        make -e presubmit\n    - name: Run tests\n      env:\n        GOLANG_VERSION: ${{ matrix.go-versions }}\n      run: |\n        source ${{ matrix.environment-variables }}\n        make test\n  test-integration:\n    strategy:\n      matrix:\n        include:\n          # bookworm: all environment configs\n          - go-versions: '1.25'\n            platform: ubuntu-24.04\n            environment-variables: build/config/plain.sh\n            debian-version: bookworm\n          - go-versions: '1.25'\n            platform: ubuntu-24.04\n            environment-variables: build/config/libpfm4.sh\n            debian-version: bookworm\n          - go-versions: '1.25'\n            platform: ubuntu-24.04\n            environment-variables: build/config/libipmctl.sh\n            debian-version: bookworm\n          # trixie: only plain config\n          - go-versions: '1.25'\n            platform: ubuntu-24.04\n            environment-variables: build/config/plain.sh\n            debian-version: trixie\n    runs-on: ${{ matrix.platform }}\n    timeout-minutes: 30\n    steps:\n    - name: Checkout code\n      uses: actions/checkout@v6\n    - name: Run integration tests\n      env:\n        GOLANG_VERSION: ${{ matrix.go-versions }}\n        DEBIAN_VERSION: ${{ matrix.debian-version }}\n      run: |\n        set -ex\n        source ${{ matrix.environment-variables }}\n        make docker-test-integration\n    - name: Upload cAdvisor log file\n      uses: actions/upload-artifact@v6\n      if: failure()\n      with:\n        name: cadvisor-${{ matrix.debian-version }}.log\n        path: ${{ github.workspace }}/go/src/github.com/google/cadvisor/cadvisor.log\n  test-integration-crio:\n    strategy:\n      matrix:\n        go-versions: ['1.25']\n        platform: [ubuntu-24.04]\n    runs-on: ${{ matrix.platform }}\n    timeout-minutes: 30\n    steps:\n    - name: Checkout code\n      uses: actions/checkout@v6\n    - name: Run CRI-O integration tests\n      env:\n        GOLANG_VERSION: ${{ matrix.go-versions }}\n      run: |\n        set -ex\n        source build/config/crio.sh\n        make docker-test-integration-crio\n    - name: Upload cAdvisor log file\n      uses: actions/upload-artifact@v6\n      if: failure()\n      with:\n        name: cadvisor-crio.log\n        path: ${{ github.workspace }}/go/src/github.com/google/cadvisor/cadvisor.log\n"
  },
  {
    "path": ".gitignore",
    "content": "cadvisor\n/release\n.vscode\n_output/\n\n# Log files\n*.log\n\n# Go test binaries\n*.test\n\n# Files generated by JetBrains IDEs, e.g. IntelliJ IDEA\n.idea/\n*.iml\n*.swp\n"
  },
  {
    "path": ".golangci.yml",
    "content": "version: \"2\"\n\nrun:\n  timeout: 5m\n\nlinters:\n  default: none\n  enable:\n    - govet\n    - errcheck\n    - staticcheck\n    - unused\n    - ineffassign\n  settings:\n    govet:\n      disable:\n        - fieldalignment  # too noisy, requires significant refactoring\n    errcheck:\n      exclude-functions:\n        - (io.Closer).Close\n        - (net.Conn).Close\n        - (*os.File).Close\n        - (net/http.ResponseWriter).Write\n        - os.Remove\n        - os.RemoveAll\n        - os.Setenv\n        - fmt.Fprint\n        - fmt.Fprintf\n        - fmt.Fprintln\n        - syscall.Close\n    staticcheck:\n      checks:\n        - \"all\"\n        - \"-ST1000\" # package comments - too noisy for existing codebase\n        - \"-ST1003\" # naming conventions (e.g., CrioId vs CrioID) - would break public API\n        - \"-ST1020\" # comment format on exported methods - too many to fix\n        - \"-ST1021\" # comment format on exported types - too many to fix\n        - \"-ST1022\" # comment format on exported consts - too many to fix\n        - \"-QF*\"    # disable quickfix suggestions\n  exclusions:\n    rules:\n      # Exclude errcheck in test files for cleaner test code\n      - linters:\n          - errcheck\n        path: \"_test\\\\.go$\"\n      # Exclude errcheck for Close() calls on any type\n      - linters:\n          - errcheck\n        text: \"Error return value of .*.Close.* is not checked\"\n      # Exclude govet printf check false positives\n      - linters:\n          - govet\n        text: \"printf: non-constant format string\"\n\nformatters:\n  enable:\n    - gofmt\n    - goimports\n\nissues:\n  max-issues-per-linter: 0\n  max-same-issues: 0\n"
  },
  {
    "path": "AUTHORS",
    "content": "# This is the official list of cAdvisor authors for copyright purposes.\n\n# Names should be added to this file as\n#     Name or Organization <email address>\n# The email address is not required for organizations.\n\n# Please keep the list sorted.\n\nGoogle Inc.\n"
  },
  {
    "path": "CHANGELOG.md",
    "content": "# Changelog\n\n### 0.39.0 (2021-03-08)\n\n- [do not initialize libipmctl package when getting an error from nvm_init()](https://github.com/google/cadvisor/pull/2723)\n- [Don't fail permenantly when nvml isn't installed](https://github.com/google/cadvisor/pull/2732)\n- [Update libpfm to 4.11.0](https://github.com/google/cadvisor/pull/2746)\n- [Fix race between `OnDemandHousekeeping` and `housekeepingTick`](https://github.com/google/cadvisor/pull/2755)\n- [Fix timeout flooding issue after containerd restart](https://github.com/google/cadvisor/pull/2749)\n- [Refactor process parsing to accommodate commands with spaces + Memory cgroup is not available on some systems](https://github.com/google/cadvisor/pull/2751)\n- [Switch from k8s utils/mount to moby/sys mount](https://github.com/google/cadvisor/pull/2782)\n- [Support nfs in processMounts](https://github.com/google/cadvisor/pull/2787)\n- [Update docker/runc and a few other dependencies](https://github.com/google/cadvisor/pull/2790)\n- [Add container_blkio_device_usage metric](https://github.com/google/cadvisor/pull/2795)\n- [Update heuristic for container creation time](https://github.com/google/cadvisor/pull/2800)\n- [Fix incorrect CPU topology on single NUMA and multi socket platform.](https://github.com/google/cadvisor/pull/2799)\n- [Added support for filesystem metrics on Docker](https://github.com/google/cadvisor/pull/2768)\n- [sched_getaffinity does not return number of online CPUs](https://github.com/google/cadvisor/pull/2805)\n- [Add libipmctl to the docker image.](https://github.com/google/cadvisor/pull/2674)\n- [Add cgroup_memory_migrate metric](https://github.com/google/cadvisor/pull/2796)\n- [bump runc to v1.0.0-rc93](https://github.com/google/cadvisor/pull/2809)\n- [Fix memory stats for cgroup v2](https://github.com/google/cadvisor/pull/2810)\n- [Allow gathering of stats for root cgroup on v2](https://github.com/google/cadvisor/pull/2801)\n- [Remove trailing \\0 from values read from ppc64le device-tree](https://github.com/google/cadvisor/pull/2811)\n- [Fix oomparser regex for kernels 5.0 and higher](https://github.com/google/cadvisor/pull/2817)\n- [Handling arm64: topology and online information](https://github.com/google/cadvisor/pull/2744)\n- [Bump golang to 1.16](https://github.com/google/cadvisor/pull/2818)\n- [Bump containerd to 1.4.4](https://github.com/google/cadvisor/pull/2826)\n- [Conditionally gathering FS usage metrics](https://github.com/google/cadvisor/pull/2828)\n\n### 0.38.8 (2021-02-18)\n- [Cherrypick to v0.38 - Fix incorrect CPU topology on single NUMA and multi socket platform](https://github.com/google/cadvisor/pulls/2799)\n- [Cherrypick to v0.38 - sched_getaffinity does not return number of online CPUs](https://github.com/google/cadvisor/pulls/2805)\n\n### 0.37.5 (2021-02-18)\n- [Cherrypick to v0.37 - Fix incorrect CPU topology on single NUMA and multi socket platform](https://github.com/google/cadvisor/pulls/2799)\n- [Cherrypick to v0.37 - sched_getaffinity does not return number of online CPUs](https://github.com/google/cadvisor/pulls/2805)\n\n### 0.38.7 (2021-01-13)\n- [Cherrypick to v0.37: Return correct DeviceInfo from GetDirFsDevice on / path for Btrfs - Fix kubernetes issue #94335](https://github.com/google/cadvisor/pulls/2775)\n\n### 0.37.4 (2021-01-13)\n- [Cherrypick to v0.37: Return correct DeviceInfo from GetDirFsDevice on / path for Btrfs - Fix kubernetes issue #94335](https://github.com/google/cadvisor/pulls/2776)\n\n### 0.38.6 (2020-12-9)\n- [Cherrypick to v0.37: Fix timeout flooding issue after containerd restart](https://github.com/google/cadvisor/pulls/2759)\n\n### 0.37.3 (2020-12-9)\n- [Cherrypick to v0.37: Fix timeout flooding issue after containerd restart](https://github.com/google/cadvisor/pulls/2758)\n\n### 0.38.5 (2020-11-23)\n- [Cherrypick to v0.37: don't fail permenantly when nvml isn't installed](https://github.com/google/cadvisor/pulls/2735)\n\n### 0.37.2 (2020-11-23)\n- [Cherrypick to v0.37 - update docker client method](https://github.com/google/cadvisor/pulls/2734)\n\n### 0.37.1 (2020-11-18)\n- [Cherrypick to v0.37: don't fail permenantly when nvml isn't installed](https://github.com/google/cadvisor/pulls/2737)\n\n### 0.38.4 (2020-11-12)\n- [vendor: run go mod tidy](https://github.com/google/cadvisor/pulls/2731)\n\n### 0.38.3 (2020-11-12)\n- [vendor: Rollback gopkg.in/yaml.v2 to v2.2.8](https://github.com/google/cadvisor/pulls/2728)\n\n### 0.38.2 (2020-11-10)\n- [Revert mount-utils back to utils/mount](https://github.com/google/cadvisor/pulls/2726)\n\n### 0.38.1 (2020-11-10)\n- [deps: Rollback grpc from v1.33.2 to v1.27.1](https://github.com/google/cadvisor/pull/2724)\n- [do not initialize libipmctl package when getting an error from nvm_init()](https://github.com/google/cadvisor/pull/2723)\n\n### 0.38.0 (2020-11-09)\n\n- [#1594 - chore: add storage_driver_buffer_duration in Influxdb storage docs](https://github.com/google/cadvisor/pull/1594)\n- [#1924 - add hugepages info to attributes](https://github.com/google/cadvisor/pull/1924)\n- [#2578 - Add perf event grouping.](https://github.com/google/cadvisor/pull/2578)\n- [#2590 - Use current Docker registry](https://github.com/google/cadvisor/pull/2590)\n- [#2611 - Aggregate perf metrics](https://github.com/google/cadvisor/pull/2611)\n- [#2612 - Add stats to stdout storage](https://github.com/google/cadvisor/pull/2612)\n- [#2618 - Update to containerd v1.4.0-beta.2 and runc v1.0.0-rc91](https://github.com/google/cadvisor/pull/2618)\n- [#2621 - Memory numa stats](https://github.com/google/cadvisor/pull/2621)\n- [#2627 - use Google Charts loader and not jsapi](https://github.com/google/cadvisor/pull/2627)\n- [#2631 - Add entry for libpfm related tests to Makefile](https://github.com/google/cadvisor/pull/2631)\n- [#2632 - Handling zeros in readPerfStat](https://github.com/google/cadvisor/pull/2632)\n- [#2638 - Add stats to statsd storage](https://github.com/google/cadvisor/pull/2638)\n- [#2639 - Add logs and simplify setup of raw perf events](https://github.com/google/cadvisor/pull/2639)\n- [#2640 - Remove exclude guest flag from perf event attrs. ](https://github.com/google/cadvisor/pull/2640)\n- [#2644 - Use perf attributes from unix lib.](https://github.com/google/cadvisor/pull/2644)\n- [#2646 - Fixed https proxy issue by installing 'full' wget in Docker alpine-based build stage](https://github.com/google/cadvisor/pull/2646)\n- [#2655 - Update readme to point to discuss.kubernetes.io](https://github.com/google/cadvisor/pull/2655)\n- [#2659 - Fix ordering of processes table](https://github.com/google/cadvisor/pull/2659)\n- [#2665 - add clean operation when watchForNewContainers/Start failed](https://github.com/google/cadvisor/pull/2665)\n- [#2669 - Update release documentation and process](https://github.com/google/cadvisor/pull/2669)\n- [#2676 - Fix runtime error when there are no NVM devices.](https://github.com/google/cadvisor/pull/2676)\n- [#2678 - Add checking checksum of libpfm4](https://github.com/google/cadvisor/pull/2678)\n- [#2679 - Fix typo in libipmctl](https://github.com/google/cadvisor/pull/2679)\n- [#2682 - Add missing flag to runtime_options.md](https://github.com/google/cadvisor/pull/2682)\n- [#2683 - Add flags that were not previously published](https://github.com/google/cadvisor/pull/2683)\n- [#2687 - Move mount library dependency from utils/mount to mount-utils](https://github.com/google/cadvisor/pull/2687)\n- [#2689 - Increase the readability of perf event logs.](https://github.com/google/cadvisor/pull/2689)\n- [#2690 - Try to read from sysfs before giving up on non-x86_64](https://github.com/google/cadvisor/pull/2690)\n- [#2691 - Broken build configuration when custom build tags are used](https://github.com/google/cadvisor/pull/2691)\n- [#2695 - Add information about limits of opened perf event files.](https://github.com/google/cadvisor/pull/2695)\n- [#2697 - Update to new docker(v19.03.13) and containerd(1.4.1)](https://github.com/google/cadvisor/pull/2697)\n- [#2702 - Increase golang ci lint timeout to 5 minutes](https://github.com/google/cadvisor/pull/2702)\n- [#2706 - Add a badge for the current e2e test result](https://github.com/google/cadvisor/pull/2706)\n- [#2707 - Fix Avoid random values in unix.PerfEventAttr{}](https://github.com/google/cadvisor/pull/2707)\n- [#2711 - validateMemoryAccounting: fix for cgroup v2](https://github.com/google/cadvisor/pull/2711)\n- [#2713 - Bump golang to 1.15](https://github.com/google/cadvisor/pull/2713)\n- [#2714 - update docker client method](https://github.com/google/cadvisor/pull/2714)\n- [#2716 - Update dependencies](https://github.com/google/cadvisor/pull/2716)\n\n### 0.35.1 (2020-11-05)\n- [Make a copy of MachineInfo in GetMachineInfo()](https://github.com/google/cadvisor/pull/2490)\n\n### 0.37.0 (2020-07-07)\n- Add on-demand collection for prometheus metrics\n- Fix detection of image filesystem\n- Fix disk metrics for devicemapper devices\n- Add NVM Power and NVM, Dimm, memory information to machine info\n- Fix detection of OOM Kills on 5.0 linux kernels\n- Add support for perf core and uncore event monitoring\n- Add hugetlb container metrics\n- Split into multiple go modules\n- Add referenced memory metrics\n- Publish images to gcr.io/cadvisor instead of gcr.io/google_containers\n- Add socket id to numa topology in machine info\n- Add resource control (Resctlr) metrics\n\n### 0.36.0 (2020-02-28)\n- Add support for risc and mips CPUs\n- Add advanced TCP stats\n- Fix bug in which cAdvisor could fail to discover docker's root directory\n- The stdout storage driver now supports metric timestamps\n- Add ulimit metrics\n- Support multi-arch container builds\n- Switch to go modules\n\n### 0.35.0 (2019-11-27)\n- Add hugepage info per-numa-node\n- Add support for cgoups v2 unified higherarchy\n- Drop support for rkt\n- Fix a bug that prevented running with multiple tmpfs mounts\n\n### 0.34.0 (2019-08-26)\n- Fix disk stats in LXD using ZFS storage pool\n- Support monitoring non-k8s containerd namespaces\n- The `storage_driver` flag now supports comma-separated inputs\n- Add `container_sockets`, `container_threads`, and `container_threads_max` metrics\n- Fix CRI-O missing network metris bug\n- Add `disable_root_cgroup_stats` flag to allow not collecting stats from the root cgroup.\n\n### 0.33.0 (2019-02-26)\n- Add --raw_cgroup_prefix_whitelist flag to allow configuring which raw cgroup trees cAdvisor monitors\n- Replace `du` and `find` with a golang implementation\n- Periodically update MachineInfo to support hot-add/remove\n- Add explicit timestamps to prometheus metrics to fix rate calculations\n- Add --url_base_prefix flag to provide better support for reverse proxies\n- Add --white_listed_container_labels flag to allow specifying the container labels added as prometheus labels\n\n### 0.32.0 (2018-11-12)\n- Add container process and file descriptor metrics (disabled by default)\n- Rename `type` label to `failure_type` for prometheus `memory_failures_total` metric\n- Reduce mesos error logging when mesos not present\n\n### 0.31.0 (2018-09-07)\n- Fix NVML initialization race condition\n- Fix brtfs filesystem discovery\n- Fix race condition with AllDockerContainers\n- Don't watch .mount cgroups\n- Reduce lock contention during list containers\n- Don't produce prometheus metrics for ignored metrics\n- Add option to not export container labels as prometheus labels\n- Docs: Publish cAdvisor daemonset\n- Docs: Add documentation for exported prometheus metrics\n\n### 0.30.1 (2018-06-11)\n- Revert switch from inotify to fsnotify\n\n### 0.30.0 (2018-06-05)\n- Use IONice to reduce IO priority of `du` and `find`\n- BREAKING API CHANGE: ContainerReference no longer contains Labels.  Use ContainerSpec instead.\n- Add schedstat metrics, disabled by default.\n- Fix a bug where cadvisor failed to discover a sub-cgroup that was created soon after the parent cgroup.\n\n### 0.29.0 (2018-02-20)\n- Disable per-cpu metrics by default for scalability\n- Fix disk usage monitoring of overlayFs\n- Retry docker connection on startup timeout\n\n### 0.28.3 (2017-12-7)\n- Add timeout for docker calls\n- Fix prometheus label consistency\n\n### 0.28.2 (2017-11-21)\n- Fix GPU init race condition\n\n### 0.28.1 (2017-11-20)\n- Add containerd support\n- Fix fsnotify regression from 0.28.0\n- Add on demand metrics\n\n### 0.28.0 (2017-11-06)\n- Add container nvidia GPU metrics\n- Expose container memory max_usage_in_bytes\n- Add container memory reservation to prometheus\n\n### 0.27.1 (2017-09-06)\n- Add CRI-O support\n\n### 0.27.0 (2017-09-01)\n- Fix journalctl leak\n- Fix container memory rss\n- Add hugepages support\n- Fix incorrect CPU usage with 4.7 kernel\n- OOM parser uses kmsg\n- Add tmpfs support\n\n### 0.26.1 (2017-06-21)\n- Fix prometheus metrics.\n\n### 0.26.0 (2017-05-31)\n- Fix disk partition discovery for brtfs\n- Add ZFS support\n- Add UDP metrics (collection disabled by default)\n- Improve diskio prometheus metrics\n- Update Prometheus godeps to v0.8\n- Add overlay2 storage driver support\n\n### 0.25.0 (2017-03-09)\n- Disable thin_ls due to excessive iops\n- Ignore .mount cgroups, fixing dissappearing stats\n- Fix wc goroutine leak\n- Update aws-sdk-go dependency to 1.6.10\n- Update to go 1.7 for releases\n\n### 0.24.1 (2016-10-10)\n\n- Fix issue with running cAdvisor in a container on some distributions.\n\n### 0.24.0 (2016-09-19)\n\n- Added host-level inode stats (total & available)\n- Improved robustness to partial failures\n- Metrics collector improvements\n  - Added ability to directly use endpoints from the container itself\n  - Allow SSL endpoint access\n  - Ability to provide a certificate which is exposed to custom endpoints\n- Lots of bug fixes, including:\n  - Devicemapper thin_ls fixes\n  - Prometheus metrics fixes\n  - Fixes for missing stats (memory reservation, FS usage, etc.)\n\n### 0.23.9 (2016-08-09)\n\n- Cherry-pick release:\n  - Ensure minimum kernel version for thin_ls\n\n### 0.23.8 (2016-08-02)\n\n- Cherry-pick release:\n  - Prefix Docker labels & env vars in Prometheus metrics to prevent conflicts\n\n### 0.23.7 (2016-07-18)\n\n- Cherry-pick release:\n  - Modify working set memory stats calculation\n\n### 0.23.6 (2016-06-23)\n\n- Cherry-pick release:\n  - Updating inotify to fix memory leak v0.23 cherrypick\n\n### 0.23.5 (2016-06-22)\n\n- Cherry-pick release:\n  - support LVM based device mapper storage drivers\n\n### 0.23.4 (2016-06-16)\n- Cherry-pick release:\n  - Check for thin_is binary in path for devicemapper when using ThinPoolWatcher\n  - Fix uint64 overflow issue for CPU stats\n\n### 0.23.3 (2016-06-08)\n- Cherry-pick release:\n  - Cap the maximum consecutive du commands\n  - Fix a panic when a prometheus endpoint ends with a newline\n\n### 0.23.2 (2016-05-18)\n- Handle kernel log rotation\n- More rkt support: poll rkt service for new containers\n- Better handling of partial failures when fetching subcontainers\n- Devicemapper thin_ls support (requires Device Mapper kernel module and supporting utilities)\n\n### 0.23.1 (2016-05-11)\n- Add multi-container charts to the UI\n- Add TLS options for Kafka storage driver\n- Switch to official Docker client\n- Systemd:\n  - Ignore .mount cgroups on systemd\n  - Better OOM monitoring\n- Bug: Fix broken -disable_metrics flag\n- Bug: Fix openstack identified as AWS\n- Bug: Fix EventStore when limit is 0\n\n### 0.23.0 (2016-04-21)\n- Docker v1.11 support\n- Preliminary rkt support\n- Bug: Fix file descriptor leak\n\n### 0.22.0 (2016-02-25)\n- Disk usage calculation bug fixes\n- Systemd integration bug fixes\n- Instance ID support for Azure and AWS\n- Limit number of custom metrics\n- Support opt out for disk and network metrics\n\n### 0.21.0 (2016-02-03)\n- Support for filesystem stats with docker v1.10\n- Bug fixes.\n\n### 0.20.5 (2016-01-27)\n- Breaking: Use uint64 for memory stats\n- Bug: Fix devicemapper partition labelling\n- Bug: Fix network stats when using new Docker network functionality\n- Bug: Fix env var label mapping initialization\n- Dependencies: libcontainer update\n\n### 0.20.4 (2016-01-20)\n- Godep updates\n\n### 0.20.3 (2016-01-19)\n- Bug fixes\n- Jitter added to housekeeping to smooth CPU usage.\n\n### 0.20.2 (2016-01-15)\n- New v2.1 API with better filesystem stats\n- Internal refactoring\n- Bug fixes.\n\n### 0.18.0 (2015-09-23)\n- Large bunch of bug-fixes\n- Fixed networking stats for newer docker versions using libnetwork.\n- Added application-specific metrics\n\n## 0.16.0 (2015-06-26)\n- Misc fixes.\n\n## 0.15.1 (2015-06-10)\n- Fix longstanding memory leak.\n- Fix UI on newest Chrome.\n\n## 0.15.0 (2015-06-08)\n- Expose multiple network intefaces in UI and API.\n- Add support for XFS.\n- Fixes in inotify watches.\n- Fixes on PowerPC machines.\n- Fixes for newer systems with systemd.\n- Extra debuging informaiton in /validate.\n\n## 0.14.0 (2015-05-21)\n- Add process stats to container pages in the UI.\n- Serve UI from relative paths (allows reverse proxying).\n- Minor fixes to events API.\n- Add bytes available to FS info.\n- Adding Docker status and image information to UI.\n- Basic Redis storage backend.\n- Misc reliability improvements.\n\n## 0.13.0 (2015-05-01)\n- Added `--docker_only` to limit monitoring to only Docker containers.\n- Added support for Docker labels.\n- Added limit for events storage.\n- Fixes for OOM event monitoring.\n- Changed event type to a string in the API.\n- Misc fixes.\n\n## 0.12.0 (2015-04-15)\n- Added support for Docker 1.6.\n- Split OOM event into OOM kill and OOM.\n- Made EventData a concrete type in returned events.\n- Enabled CPU load tracking (experimental).\n\n## 0.11.0 (2015-03-27)\n- Export all stats as [Prometheus](https://prometheus.io/) metrics.\n- Initial support for [events](docs/api.md): creation, deletion, and OOM.\n- Adding machine UUID information.\n- Beta release of the cAdvisor [2.0 API](docs/api_v2.md).\n- Improve handling of error conditions.\n- Misc fixes and improvements.\n\n## 0.10.1 (2015-02-27)\n- Disable OOM monitoring which is using too much CPU.\n- Fix break in summary stats.\n\n## 0.10.0 (2015-02-24)\n- Adding Start and End time for ContainerInfoRequest.\n- Various misc fixes.\n\n## 0.9.0 (2015-02-06)\n- Support for more network devices (all non-eth).\n- Support for more partition types (btrfs, device-mapper, whole-disk).\n- Added reporting of DiskIO stats.\n- Adding container creation time to ContainerSpec.\n- More robust handling of stats failures.\n- Various misc fixes.\n\n## 0.8.0 (2015-01-09)\n- Added ethernet device information.\n- Added machine-wide networking statistics.\n- Misc UI fixes.\n- Fixes for partially-isolated containers.\n\n## 0.7.1 (2014-12-23)\n- Avoid repeated logging of container errors.\n- Handle non identify mounts for cgroups.\n\n## 0.7.0 (2014-12-18)\n- Support for HTTP basic auth.\n- Added /validate to perform basic checks and determine support for cAdvisor.\n- All stats in the UI are now updated.\n- Added gauges for filesystem usage.\n- Added device information to machine info.\n- Fixes to container detection.\n- Fixes for systemd detection.\n- ContainerSpecs are now cached.\n- Performance improvements.\n\n## 0.6.2 (2014-11-20)\n- Fixes for Docker API and UI endpoints.\n- Misc UI bugfixes.\n\n## 0.6.1 (2014-11-18)\n- Bug fix in InfluxDB storage driver. Container name and hostname will be exported.\n\n## 0.6.0 (2014-11-17)\n- Adding /docker UI endpoint for Docker containers.\n- Fixes around handling Docker containers.\n- Performance enhancements.\n- Embed all external dependencies.\n- ContainerStats Go struct has been flattened. The wire format remains unchanged.\n- Misc bugfixes and cleanups.\n\n## 0.5.0 (2014-10-28)\n- Added disk space stats. On by default for root, available on AUFS Docker containers.\n- Introduced v1.2 remote API with new \"docker\" resource for Docker containers.\n- Added \"ContainerHints\" file based interface to inject extra information about containers.\n\n## 0.4.1 (2014-09-29)\n- Support for Docker containers in systemd systems.\n- Adding DiskIO stats\n- Misc bugfixes and cleanups\n\n## 0.4.0 (2014-09-19)\n- Various performance enhancements: brings CPU usage down 85%+\n- Implemented dynamic sampling through dynamic housekeeping.\n- Memory storage driver is always on, BigQuery and InfluxDB are now optional storage backends.\n- Fix for DNS resolution crashes when contacting InfluxDB.\n- New containers are now detected using inotify.\n- Added pprof HTTP endpoint.\n- UI bugfixes.\n\n## 0.3.0 (2014-09-05)\n- Support for Docker with LXC backend.\n- Added BigQuery storage driver.\n- Performance and stability fixes for InfluxDB storage driver.\n- UI fixes and improvements.\n- Configurable stats gathering interval (default: 1s).\n- Improvements to startup and CPU utilization.\n- Added /healthz endpoint for determining whether cAdvisor is healthy.\n- Bugfixes and performance improvements.\n\n## 0.2.2 (2014-08-13)\n- Improvements to influxDB plugin.\n\tTable name is now 'stats'.\n\tNetwork stats added.\n\tDetailed cpu and memory stats are no longer exported to reduce the load on the DB.\n\tDocker container alias now exported - It is now possible to aggregate stats across multiple nodes.\n- Make the UI independent of the storage backend by caching recent stats in memory.\n- Switched to glog.\n- Bugfixes and performance improvements.\n- Introduced v1.1 remote API with new \"subcontainers\" resource.\n\n## 0.2.1 (2014-07-25)\n- Handle old Docker versions.\n- UI fixes and other bugfixes.\n\n## 0.2.0 (2014-07-24)\n- Added network stats to the UI.\n- Added support for CoreOS and RHEL.\n- Bugfixes and reliability fixes.\n\n## 0.1.4 (2014-07-22)\n- Add network statistics to REST API.\n- Add \"raw\" driver to handle non-Docker containers.\n- Remove lmctfy in favor of the raw driver.\n- Bugfixes for Docker containers and logging.\n\n## 0.1.3 (2014-07-14)\n- Add support for systemd systems.\n- Fixes for UI with InfluxDB storage driver.\n\n## 0.1.2 (2014-07-10)\n- Added Storage Driver concept (flag: storage_driver), default is the in-memory driver\n- Implemented InfluxDB storage driver\n- Support in REST API for specifying number of stats to return\n- Allow running without lmctfy (flag: allow_lmctfy)\n- Bugfixes\n\n## 0.1.0 (2014-06-14)\n- Support for container aliases\n- Sampling historical usage and exporting that in the REST API\n- Bugfixes for UI\n\n## 0.0.0 (2014-06-10)\n- Initial version of cAdvisor\n- Web UI with auto-updating stats\n- v1.0 REST API with container and machine information\n- Support for Docker containers\n- Support for lmctfy containers\n"
  },
  {
    "path": "CONTRIBUTING.md",
    "content": "## How to contribute\n\nOpen an issue or a pull request, its that easy!\n\n## Contributor License Agreements\n\nWe'd love to accept your pull requests! Before we can merge them, we have to jump a couple of legal hurdles.\n\nPlease fill out either the individual or corporate Contributor License Agreement (CLA).\n\n  * If you are an individual writing original source code and you're sure you own the intellectual property, then you'll need to sign an [individual CLA](http://code.google.com/legal/individual-cla-v1.0.html).\n  * If you work for a company that wants to allow you to contribute your work, then you'll need to sign a [corporate CLA](http://code.google.com/legal/corporate-cla-v1.0.html).\n\nFollow either of the two links above to access the appropriate CLA and instructions for how to sign and return it. Once we receive it, we'll be able to accept your pull requests.\n"
  },
  {
    "path": "LICENSE",
    "content": "   Copyright 2014 The cAdvisor Authors\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n\n                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n"
  },
  {
    "path": "Makefile",
    "content": "# Copyright 2015 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\nGO := go\nGOLANGCI_VER := 2.6.2\nGO_TEST ?= $(GO) test $(or $(GO_FLAGS),-race)\narch ?= $(shell go env GOARCH)\n\nall: presubmit build test\n\ntest:\n\t@echo \">> running tests\"\n\t@# Filter out integration.\n\t$(GO) list ./... | grep -vw integration | xargs $(GO_TEST)\n\tcd cmd && $(GO_TEST) ./...\n\ntest-with-libpfm: GO_FLAGS=-race -tags libpfm\ntest-with-libpfm: test\n\ncontainer-test:\n\t@echo \">> runinng tests in a container\"\n\t@./build/unit-in-container.sh\n\ndocker-test: container-test\n\t@echo \"docker-test target is deprecated, use container-test instead\"\n\ntest-integration:\n\tGO_FLAGS=$(or $(GO_FLAGS),-race) ./build/build.sh\n\t$(GO_TEST) -c github.com/google/cadvisor/integration/tests/api\n\t$(GO_TEST) -c github.com/google/cadvisor/integration/tests/common\n\t$(GO_TEST) -c github.com/google/cadvisor/integration/tests/metrics\n\t@./build/integration.sh\n\ndocker-test-integration:\n\t@./build/integration-in-docker.sh\n\ndocker-test-integration-crio:\n\t@./build/integration-in-docker-crio.sh\n\ntest-integration-crio:\n\tGO_FLAGS=$(or $(GO_FLAGS),-race) ./build/build.sh\n\t$(GO_TEST) -c github.com/google/cadvisor/integration/tests/crio\n\t$(GO_TEST) -c github.com/google/cadvisor/integration/tests/common\n\t@./build/integration-crio.sh\n\ntest-runner:\n\t@$(GO) build github.com/google/cadvisor/integration/runner\n\ntidy:\n\t@$(GO) mod tidy\n\t@cd cmd && $(GO) mod tidy\n\nformat:\n\t@echo \">> formatting code\"\n\t@# goimports is a superset of gofmt.\n\t@goimports -w -local github.com/google/cadvisor .\n\nbuild: assets\n\t@echo \">> building binaries\"\n\t@./build/build.sh $(arch)\n\nassets:\n\t@echo \">> building assets\"\n\t@./build/assets.sh\n\nrelease:\n\t@echo \">> building release binaries\"\n\t@./build/release.sh\n\ndocker-%:\n\t@docker build -t cadvisor:$(shell git rev-parse --short HEAD) -f deploy/Dockerfile .\n\ndocker-build:\n\t@docker run --rm -w /go/src/github.com/google/cadvisor -v ${PWD}:/go/src/github.com/google/cadvisor golang:1.25 make build\n\npresubmit: lint\n\t@echo \">> checking go mod tidy\"\n\t@./build/check_gotidy.sh\n\t@echo \">> checking file boilerplate\"\n\t@./build/check_boilerplate.sh\n\nlint:\n\t@# This assumes GOPATH/bin is in $PATH -- if not, the target will fail.\n\t@# Extract the current golangci-lint version (empty if not installed),\n\t@# then use GNU sort to check if GOT >= GOLANGCI_VER.\n\t@GOT=$$(golangci-lint version 2>/dev/null | sed 's/^.* version \\([^ ]*\\) .*$$/\\1/'); \\\n\tif ! printf $(GOLANGCI_VER)\\\\n$$GOT\\\\n | sort --version-sort --check=quiet; then \\\n\t\techo \">> upgrading golangci-lint from $$GOT to $(GOLANGCI_VER)\"; \\\n\t\tcurl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $$(go env GOPATH)/bin v$(GOLANGCI_VER); \\\n\t\tGOT=$(GOLANGCI_VER); \\\n\telse \\\n\t\techo \">> using installed golangci-lint $$GOT >= $(GOLANGCI_VER)\"; \\\n\tfi\n\t@echo \">> running golangci-lint using configuration at .golangci.yml\"\n\t@golangci-lint run\n\t@cd cmd && golangci-lint run\n\nclean:\n\t@rm -f *.test cadvisor\n\t@rm -rf _output/\n\n.PHONY: all build docker format release test test-integration test-integration-crio lint presubmit tidy\n"
  },
  {
    "path": "README.md",
    "content": "![cAdvisor](logo.png \"cAdvisor\")\n\n![test status](https://github.com/google/cadvisor/workflows/Test/badge.svg)\n\ncAdvisor (Container Advisor) provides container users an understanding of the resource usage and performance characteristics of their running containers. It is a running daemon that collects, aggregates, processes, and exports information about running containers. Specifically, for each container it keeps resource isolation parameters, historical resource usage, histograms of complete historical resource usage and network statistics. This data is exported by container and machine-wide.\n\ncAdvisor has native support for [Docker](https://github.com/docker/docker) containers and should support just about any other container type out of the box. We strive for support across the board so feel free to open an issue if that is not the case. cAdvisor's container abstraction is based on [lmctfy](https://github.com/google/lmctfy)'s so containers are inherently nested hierarchically.\n\n#### Quick Start: Running cAdvisor in a Docker Container\n\nTo quickly tryout cAdvisor on your machine with Docker, we have a Docker image that includes everything you need to get started. You can run a single cAdvisor to monitor the whole machine. Simply run:\n\n```\nVERSION=0.55.1 # use the latest release version from https://github.com/google/cadvisor/releases\nsudo docker run \\\n  --volume=/:/rootfs:ro \\\n  --volume=/var/run:/var/run:ro \\\n  --volume=/sys:/sys:ro \\\n  --volume=/var/lib/docker/:/var/lib/docker:ro \\\n  --volume=/dev/disk/:/dev/disk:ro \\\n  --publish=8080:8080 \\\n  --detach=true \\\n  --name=cadvisor \\\n  --privileged \\\n  --device=/dev/kmsg \\\n  ghcr.io/google/cadvisor:$VERSION # for versions prior to v0.53.0, use gcr.io/cadvisor/cadvisor instead\n```\n\ncAdvisor is now running (in the background) on `http://localhost:8080`. The setup includes directories with Docker state cAdvisor needs to observe.\n\n**Note**: If you're running on CentOS, Fedora, or RHEL (or are using LXC), take a look at our [running instructions](docs/running.md).\n\nWe have detailed [instructions](docs/running.md#standalone) on running cAdvisor standalone outside of Docker. cAdvisor [running options](docs/runtime_options.md) may also be interesting for advanced usecases. If you want to build your own cAdvisor Docker image, see our [deployment](docs/deploy.md) page.\n\nFor [Kubernetes](https://github.com/kubernetes/kubernetes) users, cAdvisor can be run as a daemonset. See the [instructions](deploy/kubernetes) for how to get started, and for how to [kustomize](https://github.com/kubernetes-sigs/kustomize#kustomize) it to fit your needs.\n\n## Building and Testing\n\nSee the more detailed instructions in the [build page](docs/development/build.md). This includes instructions for building and deploying the cAdvisor Docker image.\n\n## Exporting stats\n\ncAdvisor supports exporting stats to various storage plugins. See the [documentation](docs/storage/README.md) for more details and examples.\n\n## Web UI\n\ncAdvisor exposes a web UI at its port:\n\n`http://<hostname>:<port>/`\n\nSee the [documentation](docs/web.md) for more details.\n\n## Remote REST API & Clients\n\ncAdvisor exposes its raw and processed stats via a versioned remote REST API. See the API's [documentation](docs/api.md) for more information.\n\nThere is also an official Go client implementation in the [client](client/) directory. See the [documentation](docs/clients.md) for more information.\n\n## Roadmap\n\ncAdvisor aims to improve the resource usage and performance characteristics of running containers. Today, we gather and expose this information to users. In our roadmap:\n\n- Advise on the performance of a container (e.g.: when it is being negatively affected by another, when it is not receiving the resources it requires, etc).\n- Auto-tune the performance of the container based on previous advise.\n- Provide usage prediction to cluster schedulers and orchestration layers.\n\n## Community\n\nContributions, questions, and comments are all welcomed and encouraged! cAdvisor developers hang out on [Slack](https://kubernetes.slack.com) in the #sig-node channel (get an invitation [here](http://slack.kubernetes.io/)). We also have [discuss.kubernetes.io](https://discuss.kubernetes.io/).\n\nPlease reach out and get involved in the project, we're actively looking for more contributors to bring on board!\n\n### Core Team\n* [@bobbypage, Google](https://github.com/bobbypage)\n* [@iwankgb, Independent](https://github.com/iwankgb)\n* [@creatone, Independent](https://github.com/creatone)\n* [@dims, VMWare](https://github.com/dims)\n* [@mrunalp, RedHat](https://github.com/mrunalp)\n\n### Frequent Collaborators\n* [@haircommander, RedHat](https://github.com/haircommander)\n\n### Emeritus\n* [@dashpole, Google](https://github.com/dashpole)\n* [@dchen1107, Google](https://github.com/dchen1107)\n* [@derekwaynecarr, RedHat](https://github.com/derekwaynecarr)\n"
  },
  {
    "path": "build/assets.sh",
    "content": "#!/bin/bash\n\n# Copyright 2015 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\nset -e\n\nGIT_ROOT=$(dirname \"${BASH_SOURCE}\")/..\n\nASSETS_INPUT_DIRS=\"$GIT_ROOT/cmd/internal/pages/assets/js/... $GIT_ROOT/cmd/internal/pages/assets/styles/...\"\nASSETS_OUTPUT_PATH=\"$GIT_ROOT/cmd/internal/pages/static/assets.go\"\nASSETS_PACKAGE=\"static\"\n\nTEMPLATES_INPUT_DIRS=\"$GIT_ROOT/cmd/internal/pages/assets/html/...\"\nTEMPLATES_OUTPUT_PATH=\"$GIT_ROOT/cmd/internal/pages/templates.go\"\nTEMPLATES_PACKAGE=\"pages\"\n\nFORCE=\"${FORCE:-}\" # Force assets to be rebuilt if FORCE=true\n\n# Install while in a temp dir to avoid polluting go.mod/go.sum\npushd \"${TMPDIR:-/tmp}\" > /dev/null\ngo install github.com/kevinburke/go-bindata/go-bindata@v3.24.0\npopd > /dev/null\n\nbuild_asset () {\n  local package=$1\n  local output_path=$2\n  local input_dirs=${@:3}\n  local tmp_output=$(mktemp)\n  local year=\"$(git log -1 --date=format:'%Y' --format=%cd -- ${output_path})\"\n\n  go-bindata -nometadata -o $output_path -pkg $package $input_dirs\n  cat build/boilerplate/boilerplate.go.txt | sed \"s/YEAR/$year/\" > \"${tmp_output}\"\n  echo -e \"// generated by build/assets.sh; DO NOT EDIT\\n\" >> \"${tmp_output}\"\n  cat \"${output_path}\" >> \"${tmp_output}\"\n  gofmt -w -s \"${tmp_output}\"\n  mv \"${tmp_output}\" \"${output_path}\"\n}\n\nfor f in $GIT_ROOT/cmd/internal/pages/assets/js/* $GIT_ROOT/cmd/internal/pages/assets/styles/*; do\n  if [ \"$FORCE\" == \"true\" ] || [ \"$f\" -nt $ASSETS_OUTPUT_PATH -o ! -e $ASSETS_OUTPUT_PATH ]; then\n    build_asset \"$ASSETS_PACKAGE\" \"$ASSETS_OUTPUT_PATH\" \"$ASSETS_INPUT_DIRS\"\n    break;\n  fi\ndone\n\nfor f in $GIT_ROOT/cmd/internal/pages/assets/html/*; do\n  if [ \"$FORCE\" == \"true\" ] || [ \"$f\" -nt $TEMPLATES_OUTPUT_PATH -o ! -e $TEMPLATES_OUTPUT_PATH ]; then\n    build_asset \"$TEMPLATES_PACKAGE\" \"$TEMPLATES_OUTPUT_PATH\" \"$TEMPLATES_INPUT_DIRS\"\n    break;\n  fi\ndone\n\nexit 0\n"
  },
  {
    "path": "build/boilerplate/boilerplate.go.txt",
    "content": "// Copyright YEAR Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n"
  },
  {
    "path": "build/boilerplate/boilerplate.py",
    "content": "#!/usr/bin/env python3\n\n# Copyright 2016 Google Inc. All Rights Reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\nfrom __future__ import print_function\n\nimport argparse\nimport glob\nimport json\nimport mmap\nimport os\nimport re\nimport sys\n\nparser = argparse.ArgumentParser()\nparser.add_argument(\"filenames\", help=\"list of files to check, all files if unspecified\", nargs='*')\nargs = parser.parse_args()\n\nrootdir = os.path.dirname(__file__) + \"/../../\"\nrootdir = os.path.abspath(rootdir)\n\ndef get_refs():\n    refs = {}\n    for path in glob.glob(os.path.join(rootdir, \"build/boilerplate/boilerplate.*.txt\")):\n        extension = os.path.basename(path).split(\".\")[1]\n\n        ref_file = open(path, 'r')\n        ref = ref_file.read().splitlines()\n        ref_file.close()\n        refs[extension] = ref\n\n    return refs\n\ndef file_passes(filename, refs, regexs):\n    try:\n        f = open(filename, 'r')\n    except:\n        return False\n\n    data = f.read()\n    f.close()\n\n    extension = file_extension(filename)\n    ref = refs[extension]\n\n    # remove build tags from the top of Go files\n    if extension == \"go\":\n        p = regexs[\"go_build_constraints\"]\n        (data, found) = p.subn(\"\", data, 1)\n\n    # remove shebang from the top of shell files\n    if extension == \"sh\":\n        p = regexs[\"shebang\"]\n        (data, found) = p.subn(\"\", data, 1)\n\n    data = data.splitlines()\n\n    # if our test file is smaller than the reference it surely fails!\n    if len(ref) > len(data):\n        return False\n\n    # trim our file to the same number of lines as the reference file\n    data = data[:len(ref)]\n\n    p = regexs[\"year\"]\n    for d in data:\n        if p.search(d):\n            return False\n\n    # Replace all occurrences of the regex \"2016|2015|2014\" with \"YEAR\"\n    p = regexs[\"date\"]\n    for i, d in enumerate(data):\n        (data[i], found) = p.subn('YEAR', d)\n        if found != 0:\n            break\n\n    # if we don't match the reference at this point, fail\n    if ref != data:\n        return False\n\n    return True\n\ndef file_extension(filename):\n    return os.path.splitext(filename)[1].split(\".\")[-1].lower()\n\nskipped_dirs = ['Godeps', 'vendor', 'third_party', '_gopath', '_output', '.git']\ndef normalize_files(files):\n    newfiles = []\n    for pathname in files:\n        if any(x in pathname for x in skipped_dirs):\n            continue\n        newfiles.append(pathname)\n    for i, pathname in enumerate(newfiles):\n        if not os.path.isabs(pathname):\n            newfiles[i] = os.path.join(rootdir, pathname)\n    return newfiles\n\ndef get_files(extensions):\n    files = []\n    if len(args.filenames) > 0:\n        files = args.filenames\n    else:\n        for root, dirs, walkfiles in os.walk(rootdir):\n            # don't visit certain dirs. This is just a performance improvement\n            # as we would prune these later in normalize_files(). But doing it\n            # cuts down the amount of filesystem walking we do and cuts down\n            # the size of the file list\n            for d in skipped_dirs:\n                if d in dirs:\n                    dirs.remove(d)\n\n            for name in walkfiles:\n                pathname = os.path.join(root, name)\n                files.append(pathname)\n\n    files = normalize_files(files)\n    outfiles = []\n    for pathname in files:\n        extension = file_extension(pathname)\n        if extension in extensions:\n            outfiles.append(pathname)\n    return outfiles\n\ndef get_regexs():\n    regexs = {}\n    # Search for \"YEAR\" which exists in the boilerplate, but shouldn't in the real thing\n    regexs[\"year\"] = re.compile( 'YEAR' )\n    # dates can be something in the 21st century\n    regexs[\"date\"] = re.compile( '20[0-9][0-9]' )\n    # strip // +build \\n\\n build and //go:build constraints\n    regexs[\"go_build_constraints\"] = re.compile(r\"^(//\\s*(\\+build|go:build).*\\n)+\\n\", re.MULTILINE)\n    # strip #!.* from shell scripts\n    regexs[\"shebang\"] = re.compile(r\"^(#!.*\\n)\\n*\", re.MULTILINE)\n    return regexs\n\ndef main():\n    regexs = get_regexs()\n    refs = get_refs()\n    filenames = get_files(refs.keys())\n\n    for filename in filenames:\n        if not file_passes(filename, refs, regexs):\n            print(filename, file=sys.stdout)\n\nif __name__ == \"__main__\":\n  sys.exit(main())\n"
  },
  {
    "path": "build/boilerplate/boilerplate.py.txt",
    "content": "#!/usr/bin/env python3\n\n# Copyright YEAR Google Inc. All Rights Reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n"
  },
  {
    "path": "build/boilerplate/boilerplate.sh.txt",
    "content": "# Copyright YEAR Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n"
  },
  {
    "path": "build/build.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright 2015 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\nset -e\n\nexport GOOS=${GOOS:-$(go env GOOS)}\nexport GOARCH=${GOARCH:-$(go env GOARCH)}\nexport CGO_ENABLED=${GO_CGO_ENABLED:-\"1\"}\nGO_FLAGS=${GO_FLAGS:-\"-tags=netgo\"}    # Extra go flags to use in the build.\nBUILD_USER=${BUILD_USER:-\"${USER}@${HOSTNAME}\"}\nBUILD_DATE=${BUILD_DATE:-$( date +%Y%m%d-%H:%M:%S )}\nVERBOSE=${VERBOSE:-}\nOUTPUT_NAME_WITH_ARCH=${OUTPUT_NAME_WITH_ARCH:-\"false\"}\n\nrepo_path=\"github.com/google/cadvisor\"\n\nversion=${VERSION:-$( git describe --tags --dirty --abbrev=14 | sed -E 's/-([0-9]+)-g/.\\1+/' )}\nrevision=$( git rev-parse --short HEAD 2> /dev/null || echo 'unknown' )\nbranch=$( git rev-parse --abbrev-ref HEAD 2> /dev/null || echo 'unknown' )\ngo_version=$( go version | sed -e 's/^[^0-9.]*\\([0-9.]*\\).*/\\1/' )\n\n\n# go 1.4 requires ldflags format to be \"-X key value\", not \"-X key=value\"\nldseparator=\"=\"\nif [ \"${go_version:0:3}\" = \"1.4\" ]; then\n\tldseparator=\" \"\nfi\n\nldflags=\"\n  -X ${repo_path}/version.Version${ldseparator}${version}\n  -X ${repo_path}/version.Revision${ldseparator}${revision}\n  -X ${repo_path}/version.Branch${ldseparator}${branch}\n  -X ${repo_path}/version.BuildUser${ldseparator}${BUILD_USER}\n  -X ${repo_path}/version.BuildDate${ldseparator}${BUILD_DATE}\n  -X ${repo_path}/version.GoVersion${ldseparator}${go_version}\"\n\necho \">> building cadvisor\"\n\nif [ -n \"$VERBOSE\" ]; then\n  echo \"Building with -ldflags $ldflags\"\nfi\n\nmkdir -p \"$PWD/_output\"\noutput_file=\"$PWD/_output/cadvisor\"\nif [ \"${OUTPUT_NAME_WITH_ARCH}\" = \"true\" ] ; then\n  output_file=\"${output_file}-${version}-${GOOS}-${GOARCH}\"\nfi\n\n# Since github.com/google/cadvisor/cmd is a submodule, we must build from inside that directory\npushd cmd > /dev/null\n  go build ${GO_FLAGS} -ldflags \"${ldflags}\" -o \"${output_file}\" \"${repo_path}/cmd\"\npopd > /dev/null\n\nexit 0\n"
  },
  {
    "path": "build/check_boilerplate.sh",
    "content": "#!/bin/bash\n\n# Copyright 2015 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\nset -o errexit\nset -o nounset\nset -o pipefail\n\nGIT_ROOT=$(dirname \"${BASH_SOURCE}\")/..\nboiler=\"${GIT_ROOT}/build/boilerplate/boilerplate.py\"\n\nfiles_need_boilerplate=($(${boiler} \"$@\"))\n\nif [[ ${#files_need_boilerplate[@]} -gt 0 ]]; then\n  for file in \"${files_need_boilerplate[@]}\"; do\n    echo \"Boilerplate header is wrong for: ${file}\"\n  done\n\n  exit 1\nfi\n"
  },
  {
    "path": "build/check_container.sh",
    "content": "#!/usr/bin/env bash\n# Copyright 2015 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n# Description:\n# This script is meant to run a basic test against each of the CPU architectures\n# cadvisor should support.\n#\n# This script requires that you have run qemu-user-static so that your machine\n# can interpret ELF binaries for other architectures using QEMU:\n# https://github.com/multiarch/qemu-user-static#getting-started\n#\n# $ docker run --rm --privileged multiarch/qemu-user-static --reset -p yes\n#\n# Usage:\n# ./check_container.sh gcr.io/tstapler-gke-dev/cadvisor:v0.44.1-test-4\ntarget_image=$1\n\n# Architectures officially supported by cadvisor\narches=( \"amd64\" \"arm\" \"arm64\" \"s390x\" )\n\n# Docker doesn't handle images with different architectures but the same tag.\n# Remove the container and the image use by it to avoid problems.\ncleanup() {\n    echo Cleaning up the container $1\n    docker stop $1\n    docker rmi $target_image\n    echo\n}\n\nfor arch in \"${arches[@]}\"; do\n  echo Testing that we can run $1 on $arch and curl the /healthz endpoint\n  echo\n  container_id=$(docker run --platform \"linux/$arch\" -p 8080:8080 --rm --detach \"$target_image\")\n  docker_exit_code=$?\n  if [ $docker_exit_code -ne 0 ]; then\n    echo Failed to run container docker exited with $docker_exit_code\n    cleanup $container_id\n    exit $docker_exit_code\n  fi\n  sleep 10\n  echo\n  echo Testing the container with curl:\n  curl --show-error --retry 5 --fail -L 127.0.0.1:8080/healthz\n  echo\n  echo\n  curl_exit=$?\n  if [ $curl_exit -ne 0 ]; then\n    echo  Curling $target_image did not work\n    cleanup $container_id\n    exit $curl_exit\n  fi\n  echo Success!\n  echo\n  cleanup $container_id\ndone\n"
  },
  {
    "path": "build/check_gotidy.sh",
    "content": "#!/bin/bash\n\n# Copyright 2020 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\n# TODO(bobbypage): Replace this with `go mod tidy --check` when it exists:\n# https://github.com/golang/go/issues/27005.\n\n# Checks if go mod tidy changes are needed for a given go module.\n# If changes are needed, prints the diff and exits 1 status code.\n# Arguments:\n#   Directory of go module\nfunction lint_gotidy() {\n    MODULE_DIRECTORY=\"$1\"\n\n    pushd \"${MODULE_DIRECTORY}\" > /dev/null\n    TMP_GOMOD=$(mktemp)\n    TMP_GOSUM=$(mktemp)\n\n    # Make a copy of the current files\n    cp go.mod \"${TMP_GOMOD}\"\n    cp go.sum \"${TMP_GOSUM}\"\n\n    go mod tidy\n\n    DIFF_MOD=$(diff -u \"${TMP_GOMOD}\" go.mod)\n    DIFF_SUM=$(diff -u \"${TMP_GOSUM}\" go.sum)\n\n    # Copy the files back\n    cp \"${TMP_GOMOD}\" go.mod\n    cp \"${TMP_GOSUM}\" go.sum\n\n    if [[ -n \"${DIFF_MOD}\" || -n \"${DIFF_SUM}\" ]]; then\n        echo \"go tidy changes are needed; please run make tidy\"\n        echo \"go.mod diff:\"\n        echo \"${DIFF_MOD}\"\n        echo \"go.sum diff:\"\n        echo \"${DIFF_SUM}\"\n        exit 1\n    fi\n\n    popd > /dev/null\n}\n\n# Check if go mod tidy changes needed on main module\nlint_gotidy \".\"\n\n# Check if go mod tidy changes needed on cmd module\nlint_gotidy \"cmd\"\n"
  },
  {
    "path": "build/config/crio.sh",
    "content": "# Copyright 2024 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\n# CRI-O plain configuration - no special build flags\nunset GO_FLAGS\nunset PACKAGES\nunset BUILD_PACKAGES\nunset CADVISOR_ARGS\n"
  },
  {
    "path": "build/config/libipmctl.sh",
    "content": "# Copyright 2020 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\nexport GO_FLAGS=\"-tags=libipmctl,cgo -race\"\nexport PACKAGES=\"sudo libipmctl5\"\nexport BUILD_PACKAGES=\"libipmctl5 libipmctl-dev\"\nexport CADVISOR_ARGS=\"-perf_events_config=perf/testing/perf-non-hardware.json\"\n"
  },
  {
    "path": "build/config/libpfm4.sh",
    "content": "# Copyright 2020 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\nexport GO_FLAGS=\"-tags=libpfm,netgo -race\"\nexport PACKAGES=\"sudo libpfm4\"\nexport BUILD_PACKAGES=\"libpfm4 libpfm4-dev\"\nexport CADVISOR_ARGS=\"-perf_events_config=perf/testing/perf-non-hardware.json\"\n"
  },
  {
    "path": "build/config/plain.sh",
    "content": "# Copyright 2020 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\n# Unsetting all the important variables.\nunset GO_FLAGS\nunset PACKAGES\nunset BUILD_PACKAGES\nunset CADVISOR_ARGS\n"
  },
  {
    "path": "build/integration-crio.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright 2024 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\nset -e\n# When running this script locally, you may need to run cadvisor with sudo\n# permissions if cadvisor can't find containers.\n# USE_SUDO=true make test-integration-crio\nUSE_SUDO=${USE_SUDO:-false}\ncadvisor_bin=${CADVISOR_BIN:-\"./_output/cadvisor\"}\n\nif ! [ -f \"$cadvisor_bin\" ]; then\n  echo Failed to find cadvisor binary for integration test at path $cadvisor_bin\n  exit 1\nfi\n\nlog_file=\"cadvisor.log\"\nif [ \"$#\" -gt 0 ]; then\n  log_file=\"$1\"\nfi\n\nTEST_PID=$$\nprintf \"\" # Refresh sudo credentials if necessary.\n\n# Check if CRI-O is available and start it if not running\nCRIO_SOCK=\"/var/run/crio/crio.sock\"\n\n# Function to start CRI-O if not running (for CI environments)\nstart_crio_if_needed() {\n  if [ -S \"$CRIO_SOCK\" ]; then\n    echo \">> CRI-O already running\"\n    return 0\n  fi\n\n  echo \">> CRI-O not running, attempting to start...\"\n\n  # Check if crio binary exists\n  CRIO_BIN=\"\"\n  if command -v crio >/dev/null 2>&1; then\n    CRIO_BIN=\"crio\"\n  elif [ -x /usr/local/bin/crio ]; then\n    CRIO_BIN=\"/usr/local/bin/crio\"\n  fi\n\n  if [ -z \"$CRIO_BIN\" ]; then\n    echo \"!! crio binary not found\"\n    return 1\n  fi\n\n  # Create required directories\n  mkdir -p /var/run/crio /var/lib/containers/storage /var/log/crio/pods /run/containers/storage /etc/crio\n\n  # Install conmon if not available (CRI-O requires it)\n  if ! command -v conmon >/dev/null 2>&1 && [ ! -x /usr/local/bin/conmon ]; then\n    echo \">> Installing conmon...\"\n    CONMON_VERSION=v2.1.8\n    curl -L https://github.com/containers/conmon/releases/download/${CONMON_VERSION}/conmon.amd64 -o /usr/local/bin/conmon 2>/dev/null && \\\n    chmod +x /usr/local/bin/conmon\n  fi\n\n  # Ensure conmon is in PATH\n  if [ -x /usr/local/bin/conmon ]; then\n    export PATH=/usr/local/bin:$PATH\n  fi\n\n  # Install CNI plugins if not available\n  if [ ! -d /opt/cni/bin ] || [ -z \"$(ls -A /opt/cni/bin 2>/dev/null)\" ]; then\n    echo \">> Installing CNI plugins...\"\n    CNI_VERSION=v1.3.0\n    mkdir -p /opt/cni/bin\n    curl -L \"https://github.com/containernetworking/plugins/releases/download/${CNI_VERSION}/cni-plugins-linux-amd64-${CNI_VERSION}.tgz\" | tar -xz -C /opt/cni/bin\n  fi\n\n  # Create CNI config for bridge networking\n  mkdir -p /etc/cni/net.d\n  if [ ! -f /etc/cni/net.d/10-bridge.conf ]; then\n    echo '{\"cniVersion\":\"0.4.0\",\"name\":\"bridge\",\"type\":\"bridge\",\"bridge\":\"cni0\",\"isGateway\":true,\"ipMasq\":true,\"ipam\":{\"type\":\"host-local\",\"subnet\":\"10.88.0.0/16\",\"routes\":[{\"dst\":\"0.0.0.0/0\"}]}}' > /etc/cni/net.d/10-bridge.conf\n    echo '{\"cniVersion\":\"0.4.0\",\"name\":\"loopback\",\"type\":\"loopback\"}' > /etc/cni/net.d/99-loopback.conf\n  fi\n\n  # Create CRI-O config (always recreate to ensure correct settings)\n  echo \">> Creating CRI-O config...\"\n  # Use vfs storage driver for Docker-in-Docker (overlay on overlay doesn't work)\n  cat > /etc/crio/crio.conf << 'EOF'\n[crio]\nroot = \"/var/lib/containers/storage\"\nrunroot = \"/var/run/containers/storage\"\nlog_dir = \"/var/log/crio/pods\"\nversion_file = \"/var/run/crio/version\"\nstorage_driver = \"vfs\"\n\n[crio.api]\nlisten = \"/var/run/crio/crio.sock\"\n\n[crio.runtime]\ndefault_runtime = \"crun\"\n[crio.runtime.runtimes.crun]\nruntime_path = \"/usr/bin/crun\"\nruntime_type = \"oci\"\nruntime_root = \"/run/crun\"\n\n[crio.image]\npause_image = \"registry.k8s.io/pause:3.9\"\nEOF\n\n  # Also configure containers storage\n  mkdir -p /etc/containers\n  cat > /etc/containers/storage.conf << 'EOF'\n[storage]\ndriver = \"vfs\"\nrunroot = \"/var/run/containers/storage\"\ngraphroot = \"/var/lib/containers/storage\"\nEOF\n\n  # Create containers policy (allow all images) if it doesn't exist\n  if [ ! -f /etc/containers/policy.json ]; then\n    echo '{\"default\":[{\"type\":\"insecureAcceptAnything\"}]}' > /etc/containers/policy.json\n  fi\n\n  # Verify policy.json exists and is valid\n  echo \">> Verifying /etc/containers/policy.json...\"\n  cat /etc/containers/policy.json\n\n  # Start CRI-O\n  echo \">> Starting CRI-O daemon...\"\n  $CRIO_BIN --log-level debug &\n  CRIO_PID=$!\n  sleep 2\n\n  # Wait for CRI-O to be ready\n  echo \">> Waiting for CRI-O to start...\"\n  CRICTL_BIN=\"crictl\"\n  if [ -x /usr/local/bin/crictl ]; then\n    CRICTL_BIN=\"/usr/local/bin/crictl\"\n  fi\n\n  for i in $(seq 1 60); do\n    if $CRICTL_BIN info >/dev/null 2>&1; then\n      echo \">> CRI-O is ready\"\n      return 0\n    fi\n    echo \"Waiting for CRI-O... attempt $i\"\n    sleep 1\n  done\n\n  echo \"!! CRI-O failed to start\"\n  return 1\n}\n\n# Try to start CRI-O if in Docker-in-Docker environment\nif [[ \"${DOCKER_IN_DOCKER_ENABLED:-}\" == \"true\" ]]; then\n  start_crio_if_needed\nfi\n\n# Diagnostic logging for CRI-O debugging\necho \">> Diagnostic information:\"\necho \"=== CRI-O version ===\"\ncrio --version 2>/dev/null || /usr/local/bin/crio --version 2>/dev/null || echo \"crio --version failed\"\necho \"=== crictl version ===\"\ncrictl version 2>/dev/null || /usr/local/bin/crictl version 2>/dev/null || echo \"crictl version failed\"\necho \"=== CRI-O socket check ===\"\nls -la /var/run/crio/ 2>/dev/null || echo \"/var/run/crio/ not found\"\nls -la /run/crio/ 2>/dev/null || echo \"/run/crio/ not found\"\necho \"=== CRI-O info ===\"\ncrictl info 2>/dev/null || /usr/local/bin/crictl info 2>/dev/null || echo \"crictl info failed\"\necho \"=== Running processes (crio) ===\"\nps aux | grep -E \"crio\" | grep -v grep || echo \"No crio processes found\"\necho \"=== Kernel version ===\"\nuname -r\necho \"=== End diagnostic information ===\"\n\n# CRI-O socket is hardcoded in cAdvisor to /var/run/crio/crio.sock\nif [ -S \"$CRIO_SOCK\" ]; then\n  echo \">> CRI-O socket found at: $CRIO_SOCK\"\nelse\n  echo \"!! CRI-O socket not found at: $CRIO_SOCK\"\n  echo \"!! CRI-O may not be running\"\nfi\n\nfunction start {\n  set +e  # We want to handle errors if cAdvisor crashes.\n  echo \">> starting cAdvisor locally\"\n  cadvisor_prereqs=\"\"\n  if [ $USE_SUDO = true ]; then\n    cadvisor_prereqs=sudo\n  fi\n  # cpu, cpuset, percpu, memory, disk, diskIO, network metrics should be enabled.\n  GORACE=\"halt_on_error=1\" $cadvisor_prereqs $cadvisor_bin --enable_metrics=\"cpu,cpuset,percpu,memory,disk,diskIO,network\" --env_metadata_whitelist=TEST_VAR --v=6 --logtostderr $CADVISOR_ARGS &> \"$log_file\"\n  exit_code=$?\n  if [ $exit_code != 0 ]; then\n    echo \"!! cAdvisor exited unexpectedly with Exit $exit_code\"\n    cat $log_file\n    kill $TEST_PID # cAdvisor crashed: abort testing.\n  fi\n}\nstart &\nRUNNER_PID=$!\n\nfunction cleanup {\n  if pgrep cadvisor > /dev/null; then\n    echo \">> stopping cAdvisor\"\n    pkill -SIGINT cadvisor\n    wait $RUNNER_PID\n  fi\n}\ntrap cleanup EXIT SIGINT TERM\n\nreadonly TIMEOUT=30 # Timeout to wait for cAdvisor, in seconds.\nSTART=$(date +%s)\nwhile [ \"$(curl -Gs http://localhost:8080/healthz)\" != \"ok\" ]; do\n  if (( $(date +%s) - $START > $TIMEOUT )); then\n    echo \"Timed out waiting for cAdvisor to start\"\n    exit 1\n  fi\n  echo \"Waiting for cAdvisor to start ...\"\n  sleep 1\ndone\n\nif [[ \"${DOCKER_IN_DOCKER_ENABLED:-}\" == \"true\" ]]; then\n  # see https://github.com/moby/moby/blob/master/hack/dind\n  # cgroup v2: enable nesting\n  if [ -f /sys/fs/cgroup/cgroup.controllers ]; then\n    echo \">> configuring cgroupsv2 for crio in container...\"\n    # move the processes from the root group to the /init group,\n    # otherwise writing subtree_control fails with EBUSY.\n    # An error during moving non-existent process (i.e., \"cat\") is ignored.\n    mkdir -p /sys/fs/cgroup/init\n    xargs -rn1 < /sys/fs/cgroup/cgroup.procs > /sys/fs/cgroup/init/cgroup.procs || :\n    # enable controllers\n    sed -e 's/ / +/g' -e 's/^/+/' < /sys/fs/cgroup/cgroup.controllers \\\n      > /sys/fs/cgroup/cgroup.subtree_control\n  fi\nfi\n\necho \">> running CRI-O integration tests against local cAdvisor\"\nif ! [ -f ./crio.test ]; then\n  echo You must compile the ./crio.test binary before\n  echo running the integration tests.\n  exit 1\nfi\n./crio.test --vmodule=*=2 -test.v\n\necho \">> running common integration tests against local cAdvisor\"\nif [ -f ./common.test ]; then\n  ./common.test -test.v\nelse\n  echo \"Skipping common tests (./common.test not found)\"\nfi\n"
  },
  {
    "path": "build/integration-in-docker-crio.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright 2024 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\nset -ex\n\nROOT=\"$(cd \"$(dirname \"${BASH_SOURCE}\")/..\" && pwd -P)\"\nTMPDIR=$(mktemp -d)\nfunction delete() {\n  echo \"Deleting ${TMPDIR}...\"\n  if [[ $EUID -ne 0 ]]; then\n    sudo rm -rf \"${TMPDIR}\"\n  else\n    rm -rf \"${TMPDIR}\"\n  fi\n}\ntrap delete EXIT INT TERM\n\nfunction run_tests() {\n\n  # Detect architecture - the bootstrap image is amd64-only\n  DOCKER_PLATFORM=\"linux/amd64\"\n\n  # Add safe.directory as workaround for https://github.com/actions/runner/issues/2033\n  # Build for amd64 to match the test container\n  BUILD_CMD=\"git config --global safe.directory /go/src/github.com/google/cadvisor && env GOOS=linux GOARCH=amd64 GO_FLAGS='$GO_FLAGS' CGO_ENABLED=0 ./build/build.sh && \\\n    env GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go test -c github.com/google/cadvisor/integration/tests/crio && \\\n    env GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go test -c github.com/google/cadvisor/integration/tests/common\"\n\n  if [ \"$BUILD_PACKAGES\" != \"\" ]; then\n    BUILD_CMD=\"apt update && apt install -y $BUILD_PACKAGES && \\\n    $BUILD_CMD\"\n  fi\n\n  # Build in amd64 container to match test environment\n  docker run --rm \\\n    --platform ${DOCKER_PLATFORM} \\\n    -w /go/src/github.com/google/cadvisor \\\n    -v ${PWD}:/go/src/github.com/google/cadvisor \\\n    golang:\"$GOLANG_VERSION-bookworm\" \\\n    bash -c \"$BUILD_CMD\"\n\n  EXTRA_DOCKER_OPTS=\"-e DOCKER_IN_DOCKER_ENABLED=true\"\n  if [[ \"${OSTYPE}\" == \"linux\"* ]]; then\n    EXTRA_DOCKER_OPTS+=\" -v ${TMPDIR}/crio-graph:/var/lib/containers\"\n  fi\n\n  mkdir -p ${TMPDIR}/crio-graph\n\n  # Run tests in a privileged container with CRI-O\n  # Use --platform to ensure consistent architecture\n  # Use --cgroupns=host and --pid=host to share host namespaces (required for systemd cgroup manager)\n  # Mount host's systemd and dbus sockets so CRI-O can use systemd cgroup manager\n  docker run --rm \\\n    --platform ${DOCKER_PLATFORM} \\\n    -w /go/src/github.com/google/cadvisor \\\n    -v ${ROOT}:/go/src/github.com/google/cadvisor \\\n    -v /sys/fs/cgroup:/sys/fs/cgroup:rw \\\n    -v /run/systemd:/run/systemd:ro \\\n    -v /run/dbus:/run/dbus:ro \\\n    ${EXTRA_DOCKER_OPTS} \\\n    --privileged \\\n    --cap-add=\"sys_admin\" \\\n    --cgroupns=host \\\n    --pid=host \\\n    --entrypoint=\"\" \\\n    gcr.io/k8s-staging-test-infra/bootstrap:v20250702-52f5173c3a \\\n    bash -c \"export DEBIAN_FRONTEND=noninteractive && \\\n    apt-get update && \\\n    apt-get install -y $PACKAGES curl conntrack iptables dbus && \\\n\n    # Check if host systemd and dbus are available\n    echo 'Checking host systemd and dbus...' && \\\n    ls -la /run/systemd/ || true && \\\n    ls -la /run/dbus/ || true && \\\n    systemctl --version || true && \\\n\n    # Install CRI-O and crictl from static binaries (more reliable than apt)\n    CRIO_VERSION=v1.28.0 && \\\n    CRICTL_VERSION=v1.28.0 && \\\n\n    # Download and install crictl\n    echo 'Installing crictl...' && \\\n    curl -L https://github.com/kubernetes-sigs/cri-tools/releases/download/\\${CRICTL_VERSION}/crictl-\\${CRICTL_VERSION}-linux-amd64.tar.gz | tar -C /usr/local/bin -xz && \\\n    chmod +x /usr/local/bin/crictl && \\\n\n    # Download and install CRI-O from Google Cloud Storage\n    echo 'Installing CRI-O...' && \\\n    mkdir -p /tmp/crio-install && \\\n    curl -L https://storage.googleapis.com/cri-o/artifacts/cri-o.amd64.\\${CRIO_VERSION}.tar.gz | tar -xz -C /tmp/crio-install && \\\n    mkdir -p /usr/local/bin /etc/crio /etc/containers && \\\n    ls -la /tmp/crio-install/cri-o/bin/ && \\\n    cp /tmp/crio-install/cri-o/bin/crio /usr/local/bin/ && \\\n    cp /tmp/crio-install/cri-o/bin/crio-status /usr/local/bin/ 2>/dev/null || true && \\\n    cp /tmp/crio-install/cri-o/bin/pinns /usr/local/bin/ 2>/dev/null || true && \\\n    cp /tmp/crio-install/cri-o/bin/conmon /usr/local/bin/ 2>/dev/null || true && \\\n    cp /tmp/crio-install/cri-o/bin/conmonrs /usr/local/bin/ 2>/dev/null || true && \\\n    chmod +x /usr/local/bin/crio* /usr/local/bin/pinns /usr/local/bin/conmon* 2>/dev/null || true && \\\n    ls -la /usr/local/bin/crio* /usr/local/bin/conmon* /usr/local/bin/pinns 2>/dev/null && \\\n\n    # Create CRI-O config with systemd cgroup manager (using host systemd via mounted socket)\n    mkdir -p /etc/crio/crio.conf.d && \\\n    cat > /etc/crio/crio.conf <<CRIOEOF\n[crio]\nroot = \\\"/var/lib/containers/storage\\\"\nrunroot = \\\"/var/run/containers/storage\\\"\nlog_dir = \\\"/var/log/crio/pods\\\"\nversion_file = \\\"/var/run/crio/version\\\"\n\n[crio.api]\nlisten = \\\"/var/run/crio/crio.sock\\\"\n\n[crio.runtime]\ncgroup_manager = \\\"systemd\\\"\nconmon_cgroup = \\\"pod\\\"\ndefault_runtime = \\\"crun\\\"\n[crio.runtime.runtimes.crun]\nruntime_path = \\\"/usr/bin/crun\\\"\nruntime_type = \\\"oci\\\"\nruntime_root = \\\"/run/crun\\\"\n\n[crio.image]\npause_image = \\\"registry.k8s.io/pause:3.9\\\"\nCRIOEOF\n\n    # Install crun as the runtime\n    apt-get install -y crun && \\\n\n    # Create containers policy (required for image pulling)\n    mkdir -p /etc/containers && \\\n    echo '{\\\"default\\\":[{\\\"type\\\":\\\"insecureAcceptAnything\\\"}]}' > /etc/containers/policy.json && \\\n    echo 'Created /etc/containers/policy.json:' && \\\n    cat /etc/containers/policy.json && \\\n\n    # Install CNI plugins\n    echo 'Installing CNI plugins...' && \\\n    CNI_VERSION=v1.3.0 && \\\n    mkdir -p /opt/cni/bin && \\\n    curl -L \\\"https://github.com/containernetworking/plugins/releases/download/\\${CNI_VERSION}/cni-plugins-linux-amd64-\\${CNI_VERSION}.tgz\\\" | tar -xz -C /opt/cni/bin && \\\n    ls -la /opt/cni/bin/ && \\\n\n    # Create CNI config for bridge networking\n    mkdir -p /etc/cni/net.d && \\\n    echo '{\\\"cniVersion\\\":\\\"0.4.0\\\",\\\"name\\\":\\\"bridge\\\",\\\"type\\\":\\\"bridge\\\",\\\"bridge\\\":\\\"cni0\\\",\\\"isGateway\\\":true,\\\"ipMasq\\\":true,\\\"ipam\\\":{\\\"type\\\":\\\"host-local\\\",\\\"subnet\\\":\\\"10.88.0.0/16\\\",\\\"routes\\\":[{\\\"dst\\\":\\\"0.0.0.0/0\\\"}]}}' > /etc/cni/net.d/10-bridge.conf && \\\n    echo '{\\\"cniVersion\\\":\\\"0.4.0\\\",\\\"name\\\":\\\"loopback\\\",\\\"type\\\":\\\"loopback\\\"}' > /etc/cni/net.d/99-loopback.conf && \\\n    echo 'CNI config created:' && \\\n    cat /etc/cni/net.d/10-bridge.conf && \\\n\n    # Configure crictl to use CRI-O socket\n    cat > /etc/crictl.yaml <<EOF\nruntime-endpoint: unix:///var/run/crio/crio.sock\nimage-endpoint: unix:///var/run/crio/crio.sock\ntimeout: 30\ndebug: true\nEOF\n\n    # Start CRI-O daemon in background\n    mkdir -p /var/run/crio /var/lib/containers/storage /var/log/crio/pods /run/containers/storage && \\\n    echo 'Starting CRI-O...' && \\\n    /usr/local/bin/crio --log-level debug &\n    CRIO_PID=\\$! && \\\n    sleep 2 && \\\n\n    # Wait for CRI-O to be ready\n    echo 'Waiting for CRI-O to start...' && \\\n    for i in \\$(seq 1 60); do \\\n      if /usr/local/bin/crictl info >/dev/null 2>&1; then \\\n        echo 'CRI-O is ready'; \\\n        break; \\\n      fi; \\\n      echo \\\"Waiting for CRI-O... attempt \\$i\\\"; \\\n      sleep 1; \\\n    done && \\\n\n    # Verify CRI-O is running\n    /usr/local/bin/crictl info && \\\n\n    # Pull required images\n    echo 'Pulling test images...' && \\\n    /usr/local/bin/crictl pull registry.k8s.io/pause:3.9 || true && \\\n    /usr/local/bin/crictl pull registry.k8s.io/busybox:1.27 || true && \\\n\n    # Add /usr/local/bin to PATH for the test runner\n    export PATH=/usr/local/bin:\\$PATH && \\\n\n    # Run the integration tests\n    CADVISOR_ARGS='$CADVISOR_ARGS' /usr/local/bin/runner.sh build/integration-crio.sh\"\n}\n\n# Note: -race requires CGO, but cross-compilation with CGO is problematic\n# So we use -tags=netgo without -race for cross-platform compatibility\nGO_FLAGS=${GO_FLAGS:-\"-tags=netgo\"}\nPACKAGES=${PACKAGES:-\"sudo\"}\nBUILD_PACKAGES=${BUILD_PACKAGES:-}\nCADVISOR_ARGS=${CADVISOR_ARGS:-}\nGOLANG_VERSION=${GOLANG_VERSION:-\"1.25\"}\nrun_tests\n"
  },
  {
    "path": "build/integration-in-docker.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright 2020 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\nset -ex\n\nROOT=\"$(cd \"$(dirname \"${BASH_SOURCE}\")/..\" && pwd -P)\"\nTMPDIR=$(mktemp -d)\nfunction delete() {\n  echo \"Deleting ${TMPDIR}...\"\n  if [[ $EUID -ne 0 ]]; then\n    sudo rm -rf \"${TMPDIR}\"\n  else\n    rm -rf \"${TMPDIR}\"\n  fi\n}\ntrap delete EXIT INT TERM\n\nfunction run_tests() {\n\n  # Add safe.directory as workaround for https://github.com/actions/runner/issues/2033\n  BUILD_CMD=\"git config --global safe.directory /go/src/github.com/google/cadvisor && env GOOS=linux GOARCH=amd64 GO_FLAGS='$GO_FLAGS' ./build/build.sh && \\\n    env GOOS=linux GOFLAGS='$GO_FLAGS' go test -c github.com/google/cadvisor/integration/tests/api && \\\n    env GOOS=linux GOFLAGS='$GO_FLAGS' go test -c github.com/google/cadvisor/integration/tests/common && \\\n    env GOOS=linux GOFLAGS='$GO_FLAGS' go test -c github.com/google/cadvisor/integration/tests/metrics\"\n\n  if [ \"$BUILD_PACKAGES\" != \"\" ]; then\n    BUILD_CMD=\"apt update && apt install -y $BUILD_PACKAGES && \\\n    $BUILD_CMD\"\n  fi\n  docker run --rm \\\n    --platform linux/amd64 \\\n    -w /go/src/github.com/google/cadvisor \\\n    -v ${PWD}:/go/src/github.com/google/cadvisor \\\n    golang:\"$GOLANG_VERSION-$DEBIAN_VERSION\" \\\n    bash -c \"$BUILD_CMD\"\n\n  EXTRA_DOCKER_OPTS=\"-e DOCKER_IN_DOCKER_ENABLED=true\"\n  if [[ \"${OSTYPE}\" == \"linux\"* ]]; then\n    EXTRA_DOCKER_OPTS+=\" -v ${TMPDIR}/docker-graph:/docker-graph\"\n  fi\n\n  mkdir ${TMPDIR}/docker-graph\n  docker run --rm \\\n    --platform linux/amd64 \\\n    -w /go/src/github.com/google/cadvisor \\\n    -v ${ROOT}:/go/src/github.com/google/cadvisor \\\n    ${EXTRA_DOCKER_OPTS} \\\n    --privileged \\\n    --cap-add=\"sys_admin\" \\\n    --entrypoint=\"\" \\\n    gcr.io/k8s-staging-test-infra/bootstrap:v20250702-52f5173c3a \\\n    bash -c \"export DEBIAN_FRONTEND=noninteractive && \\\n    apt update && \\\n    apt install -y $PACKAGES && \\\n    CADVISOR_ARGS=$CADVISOR_ARGS /usr/local/bin/runner.sh build/integration.sh\"\n}\n\nGO_FLAGS=${GO_FLAGS:-\"-tags=netgo -race\"}\nPACKAGES=${PACKAGES:-\"sudo\"}\nBUILD_PACKAGES=${BUILD_PACKAGES:-}\nCADVISOR_ARGS=${CADVISOR_ARGS:-}\nGOLANG_VERSION=${GOLANG_VERSION:-\"1.25\"}\nDEBIAN_VERSION=${DEBIAN_VERSION:-\"trixie\"}\nrun_tests\n"
  },
  {
    "path": "build/integration.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright 2016 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\nset -e\n# When running this script locally, you may need to run cadvisor with sudo\n# permissions if you cadvisor can't find containers.\n# USE_SUDO=true make test-integration\nUSE_SUDO=${USE_SUDO:-false}\ncadvisor_bin=${CADVISOR_BIN:-\"./_output/cadvisor\"}\n\nif ! [ -f \"$cadvisor_bin\" ]; then\n  echo Failed to find cadvisor binary for integration test at path $cadvisor_bin\n  exit 1\nfi\n\nlog_file=\"cadvisor.log\"\nif [ \"$#\" -gt 0 ]; then\n  log_file=\"$1\"\nfi\n\nTEST_PID=$$\nprintf \"\" # Refresh sudo credentials if necessary.\n\n# Diagnostic logging for docker/containerd debugging\necho \">> Diagnostic information:\"\necho \"=== Docker version ===\"\ndocker version || echo \"docker version failed\"\necho \"=== Docker info ===\"\ndocker info || echo \"docker info failed\"\necho \"=== Containerd socket check ===\"\nls -la /run/containerd/ 2>/dev/null || echo \"/run/containerd/ not found\"\nls -la /var/run/containerd/ 2>/dev/null || echo \"/var/run/containerd/ not found\"\nls -la /var/run/docker/containerd/ 2>/dev/null || echo \"/var/run/docker/containerd/ not found\"\necho \"=== Find all containerd sockets ===\"\nfind /var/run /run -name \"*.sock\" 2>/dev/null | head -20 || echo \"No sockets found\"\necho \"=== Docker socket check ===\"\nls -la /var/run/docker.sock 2>/dev/null || echo \"/var/run/docker.sock not found\"\necho \"=== Running processes (docker/containerd) ===\"\nps aux | grep -E \"(docker|containerd)\" | grep -v grep || echo \"No docker/containerd processes found\"\necho \"=== Kernel version ===\"\nuname -r\necho \"=== End diagnostic information ===\"\n\n# Install ctr (containerd CLI) if not available - needed for containerd integration tests\nif ! command -v ctr &> /dev/null; then\n  CTR_VERSION=\"1.7.24\"\n  CTR_ARCH=\"amd64\"\n  [ \"$(uname -m)\" = \"aarch64\" ] && CTR_ARCH=\"arm64\"\n  curl -sL \"https://github.com/containerd/containerd/releases/download/v${CTR_VERSION}/containerd-${CTR_VERSION}-linux-${CTR_ARCH}.tar.gz\" | sudo tar -xz -C /usr/local\nfi\n\n# Detect containerd socket path - Docker-in-Docker uses a different path\nexport CONTAINERD_SOCK=\"/run/containerd/containerd.sock\"\nif [ -S \"/run/docker/containerd/containerd.sock\" ]; then\n  export CONTAINERD_SOCK=\"/run/docker/containerd/containerd.sock\"\n  echo \">> Using Docker-embedded containerd socket: $CONTAINERD_SOCK\"\nfi\n\n# Set up cgroup delegation for containerd k8s.io namespace (cgroups v2)\nsudo mkdir -p /sys/fs/cgroup/init\nxargs -rn1 < /sys/fs/cgroup/cgroup.procs 2>/dev/null | sudo tee /sys/fs/cgroup/init/cgroup.procs > /dev/null 2>&1 || true\nsed -e 's/ / +/g' -e 's/^/+/' < /sys/fs/cgroup/cgroup.controllers | sudo tee /sys/fs/cgroup/cgroup.subtree_control > /dev/null 2>&1 || true\nsudo mkdir -p /sys/fs/cgroup/k8s.io\nsed -e 's/ / +/g' -e 's/^/+/' < /sys/fs/cgroup/cgroup.controllers | sudo tee /sys/fs/cgroup/k8s.io/cgroup.subtree_control > /dev/null 2>&1 || true\n\nfunction start {\n  set +e  # We want to handle errors if cAdvisor crashes.\n  echo \">> starting cAdvisor locally\"\n  cadvisor_prereqs=\"\"\n  if [ $USE_SUDO = true ]; then\n    cadvisor_prereqs=sudo\n  fi\n  # cpu, cpuset, percpu, memory, disk, diskIO, network, perf_event metrics should be enabled.\n  GORACE=\"halt_on_error=1\" $cadvisor_prereqs $cadvisor_bin --enable_metrics=\"cpu,cpuset,percpu,memory,disk,diskIO,network,perf_event\" --env_metadata_whitelist=TEST_VAR --containerd=\"$CONTAINERD_SOCK\" --v=6 --logtostderr $CADVISOR_ARGS &> \"$log_file\"\n  exit_code=$?\n  if [ $exit_code != 0 ]; then\n    echo \"!! cAdvisor exited unexpectedly with Exit $exit_code\"\n    cat $log_file\n    kill $TEST_PID # cAdvisor crashed: abort testing.\n  fi\n}\nstart &\nRUNNER_PID=$!\n\nfunction cleanup {\n  if pgrep cadvisor > /dev/null; then\n    echo \">> stopping cAdvisor\"\n    pkill -SIGINT cadvisor\n    wait $RUNNER_PID\n  fi\n}\ntrap cleanup EXIT SIGINT TERM\n\nreadonly TIMEOUT=30 # Timeout to wait for cAdvisor, in seconds.\nSTART=$(date +%s)\nwhile [ \"$(curl -Gs http://localhost:8080/healthz)\" != \"ok\" ]; do\n  if (( $(date +%s) - $START > $TIMEOUT )); then\n    echo \"Timed out waiting for cAdvisor to start\"\n    exit 1\n  fi\n  echo \"Waiting for cAdvisor to start ...\"\n  sleep 1\ndone\n\nif [[ \"${DOCKER_IN_DOCKER_ENABLED:-}\" == \"true\" ]]; then\n  # see https://github.com/moby/moby/blob/master/hack/dind\n  # cgroup v2: enable nesting\n  if [ -f /sys/fs/cgroup/cgroup.controllers ]; then\n    echo \">> configuring cgroupsv2 for docker in docker...\"\n    # move the processes from the root group to the /init group,\n    # otherwise writing subtree_control fails with EBUSY.\n    # An error during moving non-existent process (i.e., \"cat\") is ignored.\n    mkdir -p /sys/fs/cgroup/init\n    xargs -rn1 < /sys/fs/cgroup/cgroup.procs > /sys/fs/cgroup/init/cgroup.procs || :\n    # enable controllers\n    sed -e 's/ / +/g' -e 's/^/+/' < /sys/fs/cgroup/cgroup.controllers \\\n      > /sys/fs/cgroup/cgroup.subtree_control\n  fi\nfi\n\necho \">> running integration tests against local cAdvisor\"\nif ! [ -f ./api.test ] || ! [ -f ./common.test ] || ! [ -f ./metrics.test ]; then\n  echo You must compile the ./api.test, ./common.test, and ./metrics.test binaries\n  echo before running the integration tests.\n  exit 1\nfi\n./api.test --vmodule=*=2 -test.v\n./common.test -test.v\n./metrics.test -test.v\n"
  },
  {
    "path": "build/prow_e2e.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright 2018 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\nset -e\nset -x\n\nBUILDER=${BUILDER:-false} # Whether this is running a PR builder job.\n\nexport GO_FLAGS=\"-race\"\nexport GORACE=\"halt_on_error=1\"\n\n# cd to cadvisor directory\nparent_path=$( cd \"$(dirname \"${BASH_SOURCE[0]}\")\" ; pwd -P )\ncd \"$parent_path/..\"\n\n# Check whether assets need to be rebuilt.\nFORCE=true build/assets.sh\nif [[ ! -z \"$(git diff --name-only -- cmd/internal/pages)\" ]]; then\n  echo \"Found changes to UI assets:\"\n  git diff --name-only -- cmd/internal/pages\n  echo \"Run: 'make assets FORCE=true'\"\n  exit 1\nfi\n\nmake build test\n\n# compile integration tests so they can be run without go installed\ngo test -c github.com/google/cadvisor/integration/tests/api\ngo test -c github.com/google/cadvisor/integration/tests/healthz\n"
  },
  {
    "path": "build/release.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright 2015 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\nset -e\n\nif [ -z \"$VERSION\" ]; then\n  VERSION=$( git describe --tags --dirty --abbrev=14 | sed -E 's/-([0-9]+)-g/.\\1+/' )\n  # Only allow releases of tagged versions.\n  TAGGED='^v[0-9]+\\.[0-9]+\\.[0-9]+(-(alpha|beta|rc)\\.?[0-9]*)?$'\n  if [[ ! \"$VERSION\" =~ $TAGGED ]]; then\n    echo \"Error: Only tagged versions are allowed for releases\" >&2\n    echo \"Found: $VERSION\" >&2\n    exit 1\n  fi\nfi\n\nread -p \"Please confirm: $VERSION is the desired version (Type y/n to continue):\" -n 1 -r\necho\nif ! [[ $REPLY =~ ^[Yy]$ ]]; then\n  exit 1\nfi\n\n# Don't include hostname with release builds\nif ! git_user=\"$(git config --get user.email)\"; then\n  echo \"Error: git user not set, use:\"\n  echo \"git config user.email <email>\"\n  exit 1\nfi\n\nexport BUILD_USER=\"$git_user\"\nexport BUILD_DATE=$( date +%Y%m%d ) # Release date is only to day-granularity\nexport VERBOSE=true\n\n# Build the docker image\necho \">> building cadvisor docker image\"\nimage_name=${IMAGE_NAME:-\"gcr.io/cadvisor/cadvisor\"}\nfinal_image=\"$image_name:${VERSION}\"\n\ndocker buildx inspect cadvisor-builder > /dev/null \\\n|| docker buildx create --name cadvisor-builder --use\n\n# Build binaries\n\n# A mapping of the docker arch name to the qemu arch name\ndeclare -A arches=( [\"amd64\"]=\"x86_64\" [\"arm\"]=\"arm\" [\"arm64\"]=\"aarch64\" [\"s390x\"]=\"s390x\" )\n\nfor arch in \"${arches[@]}\"; do\n  if ! hash \"qemu-${arch}-static\"; then\n    echo Releasing multi arch containers requires qemu-user-static.\n    echo\n    echo Please install using apt-get install qemu-user-static or\n    echo a similar package for your OS.\n\n    exit 1\n  fi\ndone\n\nfor arch in \"${!arches[@]}\"; do\n  GOARCH=\"$arch\" GO_CGO_ENABLED=\"0\" OUTPUT_NAME_WITH_ARCH=\"true\" build/build.sh\n  arch_specific_image=\"${image_name}-${arch}:${VERSION}\"\n  docker buildx build --platform \"linux/${arch}\" --provenance=false --build-arg VERSION=\"$VERSION\" -f deploy/Dockerfile -t \"$arch_specific_image\"  --progress plain --push .\n  docker manifest create --amend \"$final_image\" \"$arch_specific_image\"\n  docker manifest annotate --os=linux --arch=\"$arch\" \"$final_image\" \"$arch_specific_image\"\ndone\ndocker manifest push \"$final_image\"\necho\necho \"Release info (copy to the release page)\":\necho\necho Multi Arch Container Image:\necho $final_image\necho\necho Architecture Specific Container Images:\nfor arch in \"${!arches[@]}\"; do\n  echo \"${image_name}-${arch}:${VERSION}\"\ndone\necho\necho Binaries:\n(cd _output && find . -name \"cadvisor-${VERSION}*\" -exec sha256sum --tag {} \\;)\nexit 0\n"
  },
  {
    "path": "build/unit-in-container.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright 2020 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\nset -ex\n\nif ! CONTAINER_ENGINE=$(command -v docker || command -v podman); then\n  echo \"Neither docker nor podman found. Exiting.\"\n  exit 1\nfi\n\nfunction run_tests() {\n  BUILD_CMD=\"make test\"\n  if [ \"$BUILD_PACKAGES\" != \"\" ]; then\n    BUILD_CMD=\"echo 'deb http://deb.debian.org/debian buster-backports main'>/etc/apt/sources.list.d/buster.list\n    apt update\n    apt install -y -t buster-backports $BUILD_PACKAGES\n    $BUILD_CMD\"\n  fi\n\n  $CONTAINER_ENGINE run --rm \\\n    -w /go/src/github.com/google/cadvisor \\\n    -v ${PWD}:/go/src/github.com/google/cadvisor \\\n    -e GO_FLAGS \\\n    golang:${GOLANG_VERSION} \\\n    bash -e -c \"$BUILD_CMD\"\n}\n\nGO_FLAGS=${GO_FLAGS:-\"-tags=netgo -race\"}\nBUILD_PACKAGES=${BUILD_PACKAGES:-}\nGOLANG_VERSION=${GOLANG_VERSION:-\"1.25\"}\nrun_tests\n"
  },
  {
    "path": "cache/cache.go",
    "content": "// Copyright 2015 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage cache\n\nimport info \"github.com/google/cadvisor/info/v1\"\n\ntype Cache interface {\n\t// Add a ContainerStats for the specified container.\n\tAddStats(ref info.ContainerReference, stats *info.ContainerStats) error\n\n\t// Remove all cached information for the specified container.\n\tRemoveContainer(containerName string) error\n\n\t// Read most recent stats. numStats indicates max number of stats\n\t// returned. The returned stats must be consecutive observed stats. If\n\t// numStats < 0, then return all stats stored in the storage. The\n\t// returned stats should be sorted in time increasing order, i.e. Most\n\t// recent stats should be the last.\n\tRecentStats(containerName string, numStats int) ([]*info.ContainerStats, error)\n\n\t// Close will clear the state of the storage driver. The elements\n\t// stored in the underlying storage may or may not be deleted depending\n\t// on the implementation of the storage driver.\n\tClose() error\n}\n"
  },
  {
    "path": "cache/memory/memory.go",
    "content": "// Copyright 2014 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage memory\n\nimport (\n\t\"errors\"\n\t\"sync\"\n\t\"time\"\n\n\tinfo \"github.com/google/cadvisor/info/v1\"\n\t\"github.com/google/cadvisor/storage\"\n\t\"github.com/google/cadvisor/utils\"\n\n\t\"k8s.io/klog/v2\"\n)\n\n// ErrDataNotFound is the error resulting if failed to find a container in memory cache.\nvar ErrDataNotFound = errors.New(\"unable to find data in memory cache\")\n\n// containerCacheMap is a typed wrapper around sync.Map that eliminates the need\n// for type assertions at every call site. It stores container name strings\n// mapped to *containerCache values.\ntype containerCacheMap struct {\n\tm sync.Map\n}\n\n// Load retrieves a container cache by name. Returns nil, false if not found.\nfunc (c *containerCacheMap) Load(name string) (*containerCache, bool) {\n\tv, ok := c.m.Load(name)\n\tif !ok {\n\t\treturn nil, false\n\t}\n\treturn v.(*containerCache), true\n}\n\n// Store saves a container cache with the given name.\nfunc (c *containerCacheMap) Store(name string, cache *containerCache) {\n\tc.m.Store(name, cache)\n}\n\n// LoadOrStore returns the existing cache if present, otherwise stores and returns the given one.\nfunc (c *containerCacheMap) LoadOrStore(name string, cache *containerCache) (*containerCache, bool) {\n\tv, loaded := c.m.LoadOrStore(name, cache)\n\treturn v.(*containerCache), loaded\n}\n\n// Delete removes a container cache by name.\nfunc (c *containerCacheMap) Delete(name string) {\n\tc.m.Delete(name)\n}\n\n// TODO(vmarmol): See about refactoring this class, we have an unnecessary redirection of containerCache and InMemoryCache.\n// containerCache is used to store per-container information\ntype containerCache struct {\n\tref         info.ContainerReference\n\trecentStats *utils.TimedStore\n\tmaxAge      time.Duration\n\tlock        sync.RWMutex\n}\n\nfunc (c *containerCache) AddStats(stats *info.ContainerStats) error {\n\tc.lock.Lock()\n\tdefer c.lock.Unlock()\n\n\t// Add the stat to storage.\n\tc.recentStats.Add(stats.Timestamp, stats)\n\treturn nil\n}\n\nfunc (c *containerCache) RecentStats(start, end time.Time, maxStats int) ([]*info.ContainerStats, error) {\n\tc.lock.RLock()\n\tdefer c.lock.RUnlock()\n\tresult := c.recentStats.InTimeRange(start, end, maxStats)\n\tconverted := make([]*info.ContainerStats, len(result))\n\tfor i, el := range result {\n\t\tconverted[i] = el.(*info.ContainerStats)\n\t}\n\treturn converted, nil\n}\n\nfunc newContainerStore(ref info.ContainerReference, maxAge time.Duration) *containerCache {\n\treturn &containerCache{\n\t\tref:         ref,\n\t\trecentStats: utils.NewTimedStore(maxAge, -1),\n\t\tmaxAge:      maxAge,\n\t}\n}\n\ntype InMemoryCache struct {\n\tcontainerCacheMap containerCacheMap\n\tmaxAge            time.Duration\n\tbackend           []storage.StorageDriver\n}\n\nfunc (c *InMemoryCache) AddStats(cInfo *info.ContainerInfo, stats *info.ContainerStats) error {\n\tname := cInfo.ContainerReference.Name\n\tcstore, ok := c.containerCacheMap.Load(name)\n\tif !ok {\n\t\tnewStore := newContainerStore(cInfo.ContainerReference, c.maxAge)\n\t\tcstore, _ = c.containerCacheMap.LoadOrStore(name, newStore)\n\t}\n\n\tfor _, backend := range c.backend {\n\t\t// TODO(monnand): To deal with long delay write operations, we\n\t\t// may want to start a pool of goroutines to do write\n\t\t// operations.\n\t\tif err := backend.AddStats(cInfo, stats); err != nil {\n\t\t\tklog.Error(err)\n\t\t}\n\t}\n\treturn cstore.AddStats(stats)\n}\n\nfunc (c *InMemoryCache) RecentStats(name string, start, end time.Time, maxStats int) ([]*info.ContainerStats, error) {\n\tcstore, ok := c.containerCacheMap.Load(name)\n\tif !ok {\n\t\treturn nil, ErrDataNotFound\n\t}\n\treturn cstore.RecentStats(start, end, maxStats)\n}\n\nfunc (c *InMemoryCache) Close() error {\n\tc.containerCacheMap = containerCacheMap{}\n\treturn nil\n}\n\nfunc (c *InMemoryCache) RemoveContainer(containerName string) error {\n\tc.containerCacheMap.Delete(containerName)\n\treturn nil\n}\n\nfunc New(\n\tmaxAge time.Duration,\n\tbackend []storage.StorageDriver,\n) *InMemoryCache {\n\treturn &InMemoryCache{\n\t\tmaxAge:  maxAge,\n\t\tbackend: backend,\n\t}\n}\n"
  },
  {
    "path": "cache/memory/memory_test.go",
    "content": "// Copyright 2014 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage memory\n\nimport (\n\t\"testing\"\n\t\"time\"\n\n\tinfo \"github.com/google/cadvisor/info/v1\"\n\n\t\"github.com/stretchr/testify/assert\"\n\t\"github.com/stretchr/testify/require\"\n)\n\nconst containerName = \"/container\"\n\nvar (\n\tcInfo = info.ContainerInfo{\n\t\tContainerReference: info.ContainerReference{Name: containerName},\n\t}\n\tzero time.Time\n)\n\n// Make stats with the specified identifier.\nfunc makeStat(i int) *info.ContainerStats {\n\treturn &info.ContainerStats{\n\t\tTimestamp: zero.Add(time.Duration(i) * time.Second),\n\t\tCpu: info.CpuStats{\n\t\t\tLoadAverage: int32(i),\n\t\t},\n\t}\n}\n\nfunc getRecentStats(t *testing.T, memoryCache *InMemoryCache, numStats int) []*info.ContainerStats {\n\tstats, err := memoryCache.RecentStats(containerName, zero, zero, numStats)\n\trequire.Nil(t, err)\n\treturn stats\n}\n\nfunc TestAddStats(t *testing.T) {\n\tmemoryCache := New(60*time.Second, nil)\n\n\tassert := assert.New(t)\n\tassert.Nil(memoryCache.AddStats(&cInfo, makeStat(0)))\n\tassert.Nil(memoryCache.AddStats(&cInfo, makeStat(1)))\n\tassert.Nil(memoryCache.AddStats(&cInfo, makeStat(2)))\n\tassert.Nil(memoryCache.AddStats(&cInfo, makeStat(0)))\n\tcInfo2 := info.ContainerInfo{\n\t\tContainerReference: info.ContainerReference{\n\t\t\tName: \"/container2\",\n\t\t},\n\t}\n\tassert.Nil(memoryCache.AddStats(&cInfo2, makeStat(0)))\n\tassert.Nil(memoryCache.AddStats(&cInfo2, makeStat(1)))\n}\n\nfunc TestRecentStatsNoRecentStats(t *testing.T) {\n\tmemoryCache := makeWithStats(t, 0)\n\n\t_, err := memoryCache.RecentStats(containerName, zero, zero, 60)\n\tassert.NotNil(t, err)\n}\n\n// Make an instance of InMemoryCache with n stats.\nfunc makeWithStats(t *testing.T, n int) *InMemoryCache {\n\tmemoryCache := New(60*time.Second, nil)\n\n\tfor i := 0; i < n; i++ {\n\t\tassert.NoError(t, memoryCache.AddStats(&cInfo, makeStat(i)))\n\t}\n\treturn memoryCache\n}\n\nfunc TestRecentStatsGetZeroStats(t *testing.T) {\n\tmemoryCache := makeWithStats(t, 10)\n\n\tassert.Len(t, getRecentStats(t, memoryCache, 0), 0)\n}\n\nfunc TestRecentStatsGetSomeStats(t *testing.T) {\n\tmemoryCache := makeWithStats(t, 10)\n\n\tassert.Len(t, getRecentStats(t, memoryCache, 5), 5)\n}\n\nfunc TestRecentStatsGetAllStats(t *testing.T) {\n\tmemoryCache := makeWithStats(t, 10)\n\n\tassert.Len(t, getRecentStats(t, memoryCache, -1), 10)\n}\n"
  },
  {
    "path": "client/README.md",
    "content": "# Example REST API Client\n\nThis is an implementation of a cAdvisor REST API in Go.  You can use it like this:\n\n```go\nclient, err := client.NewClient(\"http://192.168.59.103:8080/\")\n```\n\nObviously, replace the URL with the path to your actual cAdvisor REST endpoint.\n\n\n### MachineInfo\n\n```go\nclient.MachineInfo()\n```\n\nThis method returns a cadvisor/v1.MachineInfo struct with all the fields filled in.  Here is an example return value:\n\n```\n(*v1.MachineInfo)(0xc208022b10)({\n NumCores: (int) 4,\n MemoryCapacity: (int64) 2106028032,\n Filesystems: ([]v1.FsInfo) (len=1 cap=4) {\n  (v1.FsInfo) {\n   Device: (string) (len=9) \"/dev/sda1\",\n   Capacity: (uint64) 19507089408\n  }\n }\n})\n```\n\nYou can see the full specification of the [MachineInfo struct in the source](../info/v1/machine.go#L131)\n\n### ContainerInfo\n\nGiven a container name and a [ContainerInfoRequest](../info/v1/container.go#L101), will return all information about the specified container.  See the [ContainerInfoRequest struct in the source](../info/v1/container.go#L101) for the full specification.\n\n```go\nrequest := v1.ContainerInfoRequest{NumStats: 10}\nsInfo, err := client.ContainerInfo(\"/docker/d9d3eb10179e6f93a...\", &request)\n```\nReturns a [ContainerInfo struct](../info/v1/container.go#L128)\n\n### SubcontainersInfo\n\nGiven a container name and a [ContainerInfoRequest](../info/v1/container.go#L101), will recursively return all info about the container and all subcontainers contained within the container.  See the [ContainerInfoRequest struct in the source](../info/v1/container.go#L101) for the full specification.\n\n```go\nrequest := v1.ContainerInfoRequest{NumStats: 10}\nsInfo, err := client.SubcontainersInfo(\"/docker\", &request)\n```\n\nReturns a [ContainerInfo struct](../info/v1/container.go#L128) with the Subcontainers field populated.\n"
  },
  {
    "path": "client/client.go",
    "content": "// Copyright 2014 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n// This is an implementation of a cAdvisor REST API in Go.\n// To use it, create a client (replace the URL with your actual cAdvisor REST endpoint):\n//\n//\tclient, err := client.NewClient(\"http://192.168.59.103:8080/\")\n//\n// Then, the client interface exposes go methods corresponding to the REST endpoints.\npackage client\n\nimport (\n\t\"bytes\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"path\"\n\t\"strings\"\n\n\tv1 \"github.com/google/cadvisor/info/v1\"\n\n\t\"k8s.io/klog/v2\"\n)\n\n// Client represents the base URL for a cAdvisor client.\ntype Client struct {\n\tbaseURL    string\n\thttpClient *http.Client\n}\n\n// NewClient returns a new v1.3 client with the specified base URL.\nfunc NewClient(url string) (*Client, error) {\n\treturn newClient(url, http.DefaultClient)\n}\n\nfunc newClient(url string, client *http.Client) (*Client, error) {\n\tif !strings.HasSuffix(url, \"/\") {\n\t\turl += \"/\"\n\t}\n\n\treturn &Client{\n\t\tbaseURL:    fmt.Sprintf(\"%sapi/v1.3/\", url),\n\t\thttpClient: client,\n\t}, nil\n}\n\n// Returns all past events that satisfy the request\nfunc (c *Client) EventStaticInfo(name string) (einfo []*v1.Event, err error) {\n\tu := c.eventsInfoURL(name)\n\tret := new([]*v1.Event)\n\tif err = c.httpGetJSONData(ret, nil, u, \"event info\"); err != nil {\n\t\treturn\n\t}\n\teinfo = *ret\n\treturn\n}\n\n// Streams all events that occur that satisfy the request into the channel\n// that is passed\nfunc (c *Client) EventStreamingInfo(name string, einfo chan *v1.Event) (err error) {\n\tu := c.eventsInfoURL(name)\n\tif err = c.getEventStreamingData(u, einfo); err != nil {\n\t\treturn\n\t}\n\treturn nil\n}\n\n// MachineInfo returns the JSON machine information for this client.\n// A non-nil error result indicates a problem with obtaining\n// the JSON machine information data.\nfunc (c *Client) MachineInfo() (minfo *v1.MachineInfo, err error) {\n\tu := c.machineInfoURL()\n\tret := new(v1.MachineInfo)\n\tif err = c.httpGetJSONData(ret, nil, u, \"machine info\"); err != nil {\n\t\treturn\n\t}\n\tminfo = ret\n\treturn\n}\n\n// ContainerInfo returns the JSON container information for the specified\n// container and request.\nfunc (c *Client) ContainerInfo(name string, query *v1.ContainerInfoRequest) (cinfo *v1.ContainerInfo, err error) {\n\tu := c.containerInfoURL(name)\n\tret := new(v1.ContainerInfo)\n\tif err = c.httpGetJSONData(ret, query, u, fmt.Sprintf(\"container info for %q\", name)); err != nil {\n\t\treturn\n\t}\n\tcinfo = ret\n\treturn\n}\n\n// Returns the information about all subcontainers (recursive) of the specified container (including itself).\nfunc (c *Client) SubcontainersInfo(name string, query *v1.ContainerInfoRequest) ([]v1.ContainerInfo, error) {\n\tvar response []v1.ContainerInfo\n\turl := c.subcontainersInfoURL(name)\n\terr := c.httpGetJSONData(&response, query, url, fmt.Sprintf(\"subcontainers container info for %q\", name))\n\tif err != nil {\n\t\treturn []v1.ContainerInfo{}, err\n\n\t}\n\treturn response, nil\n}\n\n// Returns the JSON container information for the specified\n// Docker container and request.\nfunc (c *Client) DockerContainer(name string, query *v1.ContainerInfoRequest) (cinfo v1.ContainerInfo, err error) {\n\tu := c.dockerInfoURL(name)\n\tret := make(map[string]v1.ContainerInfo)\n\tif err = c.httpGetJSONData(&ret, query, u, fmt.Sprintf(\"Docker container info for %q\", name)); err != nil {\n\t\treturn\n\t}\n\tif len(ret) != 1 {\n\t\terr = fmt.Errorf(\"expected to only receive 1 Docker container: %+v\", ret)\n\t\treturn\n\t}\n\tfor _, cont := range ret {\n\t\tcinfo = cont\n\t}\n\treturn\n}\n\n// Returns the JSON container information for all Docker containers.\nfunc (c *Client) AllDockerContainers(query *v1.ContainerInfoRequest) (cinfo []v1.ContainerInfo, err error) {\n\tu := c.dockerInfoURL(\"/\")\n\tret := make(map[string]v1.ContainerInfo)\n\tif err = c.httpGetJSONData(&ret, query, u, \"all Docker containers info\"); err != nil {\n\t\treturn\n\t}\n\tcinfo = make([]v1.ContainerInfo, 0, len(ret))\n\tfor _, cont := range ret {\n\t\tcinfo = append(cinfo, cont)\n\t}\n\treturn\n}\n\nfunc (c *Client) machineInfoURL() string {\n\treturn c.baseURL + path.Join(\"machine\")\n}\n\nfunc (c *Client) containerInfoURL(name string) string {\n\treturn c.baseURL + path.Join(\"containers\", name)\n}\n\nfunc (c *Client) subcontainersInfoURL(name string) string {\n\treturn c.baseURL + path.Join(\"subcontainers\", name)\n}\n\nfunc (c *Client) dockerInfoURL(name string) string {\n\treturn c.baseURL + path.Join(\"docker\", name)\n}\n\nfunc (c *Client) eventsInfoURL(name string) string {\n\treturn c.baseURL + path.Join(\"events\", name)\n}\n\nfunc (c *Client) httpGetJSONData(data, postData interface{}, url, infoName string) error {\n\tvar resp *http.Response\n\tvar err error\n\n\tif postData != nil {\n\t\tdata, marshalErr := json.Marshal(postData)\n\t\tif marshalErr != nil {\n\t\t\treturn fmt.Errorf(\"unable to marshal data: %v\", marshalErr)\n\t\t}\n\t\tresp, err = c.httpClient.Post(url, \"application/json\", bytes.NewBuffer(data))\n\t} else {\n\t\tresp, err = c.httpClient.Get(url)\n\t}\n\tif err != nil {\n\t\treturn fmt.Errorf(\"unable to get %q from %q: %v\", infoName, url, err)\n\t}\n\tif resp == nil {\n\t\treturn fmt.Errorf(\"received empty response for %q from %q\", infoName, url)\n\t}\n\tdefer resp.Body.Close()\n\tbody, err := io.ReadAll(resp.Body)\n\tif err != nil {\n\t\terr = fmt.Errorf(\"unable to read all %q from %q: %v\", infoName, url, err)\n\t\treturn err\n\t}\n\tif resp.StatusCode != 200 {\n\t\treturn fmt.Errorf(\"request %q failed with error: %q\", url, strings.TrimSpace(string(body)))\n\t}\n\tif err = json.Unmarshal(body, data); err != nil {\n\t\terr = fmt.Errorf(\"unable to unmarshal %q (Body: %q) from %q with error: %v\", infoName, string(body), url, err)\n\t\treturn err\n\t}\n\treturn nil\n}\n\nfunc (c *Client) getEventStreamingData(url string, einfo chan *v1.Event) error {\n\treq, err := http.NewRequest(\"GET\", url, nil)\n\tif err != nil {\n\t\treturn err\n\t}\n\tresp, err := c.httpClient.Do(req)\n\tif err != nil {\n\t\treturn err\n\t}\n\tif resp.StatusCode != http.StatusOK {\n\t\treturn fmt.Errorf(\"status code is not OK: %v (%s)\", resp.StatusCode, resp.Status)\n\t}\n\n\tdec := json.NewDecoder(resp.Body)\n\tm := &v1.Event{}\n\tfor {\n\t\terr := dec.Decode(m)\n\t\tif err != nil {\n\t\t\tif err == io.EOF {\n\t\t\t\tbreak\n\t\t\t}\n\t\t\t// if called without &stream=true will not be able to parse event and will trigger fatal\n\t\t\tklog.Fatalf(\"Received error %v\", err)\n\t\t}\n\t\teinfo <- m\n\t}\n\treturn nil\n}\n"
  },
  {
    "path": "client/client_test.go",
    "content": "// Copyright 2014 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage client\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"net/http\"\n\t\"net/http/httptest\"\n\t\"path\"\n\t\"reflect\"\n\t\"strings\"\n\t\"testing\"\n\t\"time\"\n\n\tinfo \"github.com/google/cadvisor/info/v1\"\n\titest \"github.com/google/cadvisor/info/v1/test\"\n\n\t\"github.com/stretchr/testify/assert\"\n)\n\nfunc cadvisorTestClient(path string, expectedPostObj *info.ContainerInfoRequest, replyObj interface{}, t *testing.T) (*Client, *httptest.Server, error) {\n\tts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {\n\t\tif r.URL.Path == path {\n\t\t\tif expectedPostObj != nil {\n\t\t\t\texpectedPostObjEmpty := new(info.ContainerInfoRequest)\n\t\t\t\tdecoder := json.NewDecoder(r.Body)\n\t\t\t\tif err := decoder.Decode(expectedPostObjEmpty); err != nil {\n\t\t\t\t\tt.Errorf(\"Received invalid object: %v\", err)\n\t\t\t\t}\n\t\t\t\tif expectedPostObj.NumStats != expectedPostObjEmpty.NumStats ||\n\t\t\t\t\texpectedPostObj.Start.Unix() != expectedPostObjEmpty.Start.Unix() ||\n\t\t\t\t\texpectedPostObj.End.Unix() != expectedPostObjEmpty.End.Unix() {\n\t\t\t\t\tt.Errorf(\"Received unexpected object: %+v, expected: %+v\", expectedPostObjEmpty, expectedPostObj)\n\t\t\t\t}\n\t\t\t}\n\t\t\tencoder := json.NewEncoder(w)\n\t\t\terr := encoder.Encode(replyObj)\n\t\t\tassert.NoError(t, err)\n\t\t} else {\n\t\t\tw.WriteHeader(http.StatusNotFound)\n\t\t\tfmt.Fprintf(w, \"Page not found.\")\n\t\t}\n\t}))\n\tclient, err := NewClient(ts.URL)\n\tif err != nil {\n\t\tts.Close()\n\t\treturn nil, nil, err\n\t}\n\treturn client, ts, err\n}\n\n// TestGetMachineInfo performs one test to check if MachineInfo()\n// in a cAdvisor client returns the correct result.\nfunc TestGetMachineinfo(t *testing.T) {\n\tminfo := &info.MachineInfo{\n\t\tNumCores:       8,\n\t\tMemoryCapacity: 31625871360,\n\t\tDiskMap: map[string]info.DiskInfo{\n\t\t\t\"8:0\": {\n\t\t\t\tName:  \"sda\",\n\t\t\t\tMajor: 8,\n\t\t\t\tMinor: 0,\n\t\t\t\tSize:  10737418240,\n\t\t\t},\n\t\t},\n\t}\n\tclient, server, err := cadvisorTestClient(\"/api/v1.3/machine\", nil, minfo, t)\n\tif err != nil {\n\t\tt.Fatalf(\"unable to get a client %v\", err)\n\t}\n\tdefer server.Close()\n\treturned, err := client.MachineInfo()\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\tif !reflect.DeepEqual(returned, minfo) {\n\t\tt.Fatalf(\"received unexpected machine info\")\n\t}\n}\n\n// TestGetContainerInfo generates a random container information object\n// and then checks that ContainerInfo returns the expected result.\nfunc TestGetContainerInfo(t *testing.T) {\n\tquery := &info.ContainerInfoRequest{\n\t\tNumStats: 3,\n\t}\n\tcontainerName := \"/some/container\"\n\tcinfo := itest.GenerateRandomContainerInfo(containerName, 4, query, 1*time.Second)\n\tclient, server, err := cadvisorTestClient(fmt.Sprintf(\"/api/v1.3/containers%v\", containerName), query, cinfo, t)\n\tif err != nil {\n\t\tt.Fatalf(\"unable to get a client %v\", err)\n\t}\n\tdefer server.Close()\n\treturned, err := client.ContainerInfo(containerName, query)\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\n\tif !returned.Eq(cinfo) {\n\t\tt.Error(\"received unexpected ContainerInfo\")\n\t}\n}\n\n// Test a request failing\nfunc TestRequestFails(t *testing.T) {\n\terrorText := \"there was an error\"\n\t// Setup a server that simply fails.\n\tts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {\n\t\thttp.Error(w, errorText, 500)\n\t}))\n\tclient, err := NewClient(ts.URL)\n\tif err != nil {\n\t\tts.Close()\n\t\tt.Fatal(err)\n\t}\n\tdefer ts.Close()\n\n\t_, err = client.ContainerInfo(\"/\", &info.ContainerInfoRequest{NumStats: 3})\n\tif err == nil {\n\t\tt.Fatalf(\"Expected non-nil error\")\n\t}\n\texpectedError := fmt.Sprintf(\"request failed with error: %q\", errorText)\n\tif strings.Contains(err.Error(), expectedError) {\n\t\tt.Fatalf(\"Expected error %q but received %q\", expectedError, err)\n\t}\n}\n\nfunc TestGetSubcontainersInfo(t *testing.T) {\n\tquery := &info.ContainerInfoRequest{\n\t\tNumStats: 3,\n\t}\n\tcontainerName := \"/some/container\"\n\tcinfo := itest.GenerateRandomContainerInfo(containerName, 4, query, 1*time.Second)\n\tcinfo1 := itest.GenerateRandomContainerInfo(path.Join(containerName, \"sub1\"), 4, query, 1*time.Second)\n\tcinfo2 := itest.GenerateRandomContainerInfo(path.Join(containerName, \"sub2\"), 4, query, 1*time.Second)\n\tresponse := []info.ContainerInfo{\n\t\t*cinfo,\n\t\t*cinfo1,\n\t\t*cinfo2,\n\t}\n\tclient, server, err := cadvisorTestClient(fmt.Sprintf(\"/api/v1.3/subcontainers%v\", containerName), query, response, t)\n\tif err != nil {\n\t\tt.Fatalf(\"unable to get a client %v\", err)\n\t}\n\tdefer server.Close()\n\treturned, err := client.SubcontainersInfo(containerName, query)\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\n\tif len(returned) != 3 {\n\t\tt.Errorf(\"unexpected number of results: got %d, expected 3\", len(returned))\n\t}\n\tif !returned[0].Eq(cinfo) {\n\t\tt.Error(\"received unexpected ContainerInfo\")\n\t}\n\tif !returned[1].Eq(cinfo1) {\n\t\tt.Error(\"received unexpected ContainerInfo\")\n\t}\n\tif !returned[2].Eq(cinfo2) {\n\t\tt.Error(\"received unexpected ContainerInfo\")\n\t}\n}\n"
  },
  {
    "path": "client/clientexample/main.go",
    "content": "// Copyright 2014 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage main\n\nimport (\n\t\"flag\"\n\n\t\"github.com/google/cadvisor/client\"\n\tinfo \"github.com/google/cadvisor/info/v1\"\n\n\t\"k8s.io/klog/v2\"\n)\n\nfunc staticClientExample() {\n\tstaticClient, err := client.NewClient(\"http://localhost:8080/\")\n\tif err != nil {\n\t\tklog.Errorf(\"tried to make client and got error %v\", err)\n\t\treturn\n\t}\n\teinfo, err := staticClient.EventStaticInfo(\"?oom_events=true\")\n\tif err != nil {\n\t\tklog.Errorf(\"got error retrieving event info: %v\", err)\n\t\treturn\n\t}\n\tfor idx, ev := range einfo {\n\t\tklog.Infof(\"static einfo %v: %v\", idx, ev)\n\t}\n}\n\nfunc streamingClientExample(url string) {\n\tstreamingClient, err := client.NewClient(\"http://localhost:8080/\")\n\tif err != nil {\n\t\tklog.Errorf(\"tried to make client and got error %v\", err)\n\t\treturn\n\t}\n\teinfo := make(chan *info.Event)\n\tgo func() {\n\t\terr = streamingClient.EventStreamingInfo(url, einfo)\n\t\tif err != nil {\n\t\t\tklog.Errorf(\"got error retrieving event info: %v\", err)\n\t\t\treturn\n\t\t}\n\t}()\n\tfor ev := range einfo {\n\t\tklog.Infof(\"streaming einfo: %v\\n\", ev)\n\t}\n}\n\n// demonstrates how to use event clients\nfunc main() {\n\tklog.InitFlags(nil)\n\tflag.Parse()\n\tstaticClientExample()\n\tstreamingClientExample(\"?creation_events=true&stream=true&oom_events=true&deletion_events=true\")\n}\n"
  },
  {
    "path": "client/v2/README.md",
    "content": "# Example REST API Client\n\nThis is an implementation of a cAdvisor REST API in Go.  You can use it like this:\n\n```go\nclient, err := client.NewClient(\"http://192.168.59.103:8080/\")\n```\n\nObviously, replace the URL with the path to your actual cAdvisor REST endpoint.\n\n\n### MachineInfo\n\n```go\nclient.MachineInfo()\n```\n\nThere is no v2 MachineInfo API, so the v2 client exposes the [v1 MachineInfo](../../info/v1/machine.go#L131)\n\n```\n(*v1.MachineInfo)(0xc208022b10)({\n NumCores: (int) 4,\n MemoryCapacity: (int64) 2106028032,\n Filesystems: ([]v1.FsInfo) (len=1 cap=4) {\n  (v1.FsInfo) {\n   Device: (string) (len=9) \"/dev/sda1\",\n   Capacity: (uint64) 19507089408\n  }\n }\n})\n```\n\nYou can see the full specification of the [MachineInfo struct in the source](../../info/v1/machine.go#L131)\n\n### VersionInfo\n\n```go\nclient.VersionInfo()\n```\n\nThis method returns the cAdvisor version.\n\n### Attributes\n\n```go\nclient.Attributes()\n```\n\nThis method returns a [cadvisor/info/v2/Attributes](../../info/v2/machine.go#L24) struct with all the fields filled in. Attributes includes hardware attributes (as returned by MachineInfo) as well as software attributes (eg. software versions). Here is an example return value:\n\n```\n(*v2.Attributes)({\n KernelVersion: (string) (len=17) \"3.13.0-44-generic\"\n ContainerOsVersion: (string) (len=18) \"Ubuntu 14.04.1 LTS\"\n DockerVersion: (string) (len=9) \"1.5.0-rc4\"\n CadvisorVersion: (string) (len=6) \"0.10.1\"\n NumCores: (int) 4,\n MemoryCapacity: (int64) 2106028032,\n Filesystems: ([]v2.FsInfo) (len=1 cap=4) {\n  (v2.FsInfo) {\n   Device: (string) (len=9) \"/dev/sda1\",\n   Capacity: (uint64) 19507089408\n  }\n }\n})\n```\n\nYou can see the full specification of the [Attributes struct in the source](../../info/v2/machine.go#L24)\n\n"
  },
  {
    "path": "client/v2/client.go",
    "content": "// Copyright 2015 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n// Client library to programmatically access cAdvisor API.\npackage v2\n\nimport (\n\t\"bytes\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"net/url\"\n\t\"path\"\n\t\"strconv\"\n\t\"strings\"\n\n\tv1 \"github.com/google/cadvisor/info/v1\"\n\tv2 \"github.com/google/cadvisor/info/v2\"\n)\n\n// Client represents the base URL for a cAdvisor client.\ntype Client struct {\n\tbaseURL string\n}\n\n// NewClient returns a new client with the specified base URL.\nfunc NewClient(url string) (*Client, error) {\n\tif !strings.HasSuffix(url, \"/\") {\n\t\turl += \"/\"\n\t}\n\n\treturn &Client{\n\t\tbaseURL: fmt.Sprintf(\"%sapi/v2.1/\", url),\n\t}, nil\n}\n\n// MachineInfo returns the JSON machine information for this client.\n// A non-nil error result indicates a problem with obtaining\n// the JSON machine information data.\nfunc (c *Client) MachineInfo() (minfo *v1.MachineInfo, err error) {\n\tu := c.machineInfoURL()\n\tret := new(v1.MachineInfo)\n\tif err = c.httpGetJSONData(ret, nil, u, \"machine info\"); err != nil {\n\t\treturn\n\t}\n\tminfo = ret\n\treturn\n}\n\n// MachineStats returns the JSON machine statistics for this client.\n// A non-nil error result indicates a problem with obtaining\n// the JSON machine information data.\nfunc (c *Client) MachineStats() ([]v2.MachineStats, error) {\n\tvar ret []v2.MachineStats\n\tu := c.machineStatsURL()\n\terr := c.httpGetJSONData(&ret, nil, u, \"machine stats\")\n\treturn ret, err\n}\n\n// VersionInfo returns the version info for cAdvisor.\nfunc (c *Client) VersionInfo() (version string, err error) {\n\tu := c.versionInfoURL()\n\tversion, err = c.httpGetString(u, \"version info\")\n\treturn\n}\n\n// Attributes returns hardware and software attributes of the machine.\nfunc (c *Client) Attributes() (attr *v2.Attributes, err error) {\n\tu := c.attributesURL()\n\tret := new(v2.Attributes)\n\tif err = c.httpGetJSONData(ret, nil, u, \"attributes\"); err != nil {\n\t\treturn\n\t}\n\tattr = ret\n\treturn\n}\n\n// Stats returns stats for the requested container.\nfunc (c *Client) Stats(name string, request *v2.RequestOptions) (map[string]v2.ContainerInfo, error) {\n\tu := c.statsURL(name)\n\tret := make(map[string]v2.ContainerInfo)\n\tdata := url.Values{\n\t\t\"type\":      []string{request.IdType},\n\t\t\"count\":     []string{strconv.Itoa(request.Count)},\n\t\t\"recursive\": []string{strconv.FormatBool(request.Recursive)},\n\t}\n\tif request.MaxAge != nil {\n\t\tdata.Set(\"max_age\", request.MaxAge.String())\n\t}\n\n\tu = fmt.Sprintf(\"%s?%s\", u, data.Encode())\n\tif err := c.httpGetJSONData(&ret, nil, u, \"stats\"); err != nil {\n\t\treturn nil, err\n\t}\n\treturn ret, nil\n}\n\nfunc (c *Client) machineInfoURL() string {\n\treturn c.baseURL + path.Join(\"machine\")\n}\n\nfunc (c *Client) machineStatsURL() string {\n\treturn c.baseURL + path.Join(\"machinestats\")\n}\n\nfunc (c *Client) versionInfoURL() string {\n\treturn c.baseURL + path.Join(\"version\")\n}\n\nfunc (c *Client) attributesURL() string {\n\treturn c.baseURL + path.Join(\"attributes\")\n}\n\nfunc (c *Client) statsURL(name string) string {\n\treturn c.baseURL + path.Join(\"stats\", name)\n}\n\nfunc (c *Client) httpGetResponse(postData interface{}, urlPath, infoName string) ([]byte, error) {\n\tvar resp *http.Response\n\tvar err error\n\n\tif postData != nil {\n\t\tdata, marshalErr := json.Marshal(postData)\n\t\tif marshalErr != nil {\n\t\t\treturn nil, fmt.Errorf(\"unable to marshal data: %v\", marshalErr)\n\t\t}\n\t\tresp, err = http.Post(urlPath, \"application/json\", bytes.NewBuffer(data))\n\t} else {\n\t\tresp, err = http.Get(urlPath)\n\t}\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"unable to post %q to %q: %v\", infoName, urlPath, err)\n\t}\n\tif resp == nil {\n\t\treturn nil, fmt.Errorf(\"received empty response for %q from %q\", infoName, urlPath)\n\t}\n\tdefer resp.Body.Close()\n\tbody, err := io.ReadAll(resp.Body)\n\tif err != nil {\n\t\terr = fmt.Errorf(\"unable to read all %q from %q: %v\", infoName, urlPath, err)\n\t\treturn nil, err\n\t}\n\tif resp.StatusCode != 200 {\n\t\treturn nil, fmt.Errorf(\"request %q failed with error: %q\", urlPath, strings.TrimSpace(string(body)))\n\t}\n\treturn body, nil\n}\n\nfunc (c *Client) httpGetString(url, infoName string) (string, error) {\n\tbody, err := c.httpGetResponse(nil, url, infoName)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\treturn string(body), nil\n}\n\nfunc (c *Client) httpGetJSONData(data, postData interface{}, url, infoName string) error {\n\tbody, err := c.httpGetResponse(postData, url, infoName)\n\tif err != nil {\n\t\treturn err\n\t}\n\tif err = json.Unmarshal(body, data); err != nil {\n\t\terr = fmt.Errorf(\"unable to unmarshal %q (Body: %q) from %q with error: %v\", infoName, string(body), url, err)\n\t\treturn err\n\t}\n\treturn nil\n}\n"
  },
  {
    "path": "client/v2/client_test.go",
    "content": "// Copyright 2015 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage v2\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"net/http\"\n\t\"net/http/httptest\"\n\t\"reflect\"\n\t\"strings\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/stretchr/testify/assert\"\n\n\tv1 \"github.com/google/cadvisor/info/v1\"\n\tv2 \"github.com/google/cadvisor/info/v2\"\n)\n\nfunc cadvisorTestClient(path string, expectedPostObj *v1.ContainerInfoRequest, replyObj interface{}, t *testing.T) (*Client, *httptest.Server, error) {\n\tts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {\n\t\tif r.URL.Path == path {\n\t\t\tif expectedPostObj != nil {\n\t\t\t\texpectedPostObjEmpty := new(v1.ContainerInfoRequest)\n\t\t\t\tdecoder := json.NewDecoder(r.Body)\n\t\t\t\tif err := decoder.Decode(expectedPostObjEmpty); err != nil {\n\t\t\t\t\tt.Errorf(\"Received invalid object: %v\", err)\n\t\t\t\t}\n\t\t\t\tif expectedPostObj.NumStats != expectedPostObjEmpty.NumStats ||\n\t\t\t\t\texpectedPostObj.Start.Unix() != expectedPostObjEmpty.Start.Unix() ||\n\t\t\t\t\texpectedPostObj.End.Unix() != expectedPostObjEmpty.End.Unix() {\n\t\t\t\t\tt.Errorf(\"Received unexpected object: %+v, expected: %+v\", expectedPostObjEmpty, expectedPostObj)\n\t\t\t\t}\n\t\t\t}\n\t\t\tencoder := json.NewEncoder(w)\n\t\t\terr := encoder.Encode(replyObj)\n\t\t\tassert.NoError(t, err)\n\t\t} else if r.URL.Path == \"/api/v2.1/version\" {\n\t\t\tfmt.Fprintf(w, \"0.1.2\")\n\t\t} else {\n\t\t\tw.WriteHeader(http.StatusNotFound)\n\t\t\tfmt.Fprintf(w, \"Page not found.\")\n\t\t}\n\t}))\n\tclient, err := NewClient(ts.URL)\n\tif err != nil {\n\t\tts.Close()\n\t\treturn nil, nil, err\n\t}\n\treturn client, ts, err\n}\n\n// TestGetMachineInfo performs one test to check if MachineInfo()\n// in a cAdvisor client returns the correct result.\nfunc TestGetMachineInfo(t *testing.T) {\n\tmv1 := &v1.MachineInfo{\n\t\tNumCores:       8,\n\t\tMemoryCapacity: 31625871360,\n\t\tDiskMap: map[string]v1.DiskInfo{\n\t\t\t\"8:0\": {\n\t\t\t\tName:  \"sda\",\n\t\t\t\tMajor: 8,\n\t\t\t\tMinor: 0,\n\t\t\t\tSize:  10737418240,\n\t\t\t},\n\t\t},\n\t}\n\tclient, server, err := cadvisorTestClient(\"/api/v2.1/machine\", nil, mv1, t)\n\tif err != nil {\n\t\tt.Fatalf(\"unable to get a client %v\", err)\n\t}\n\tdefer server.Close()\n\treturned, err := client.MachineInfo()\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\tif !reflect.DeepEqual(returned, mv1) {\n\t\tt.Fatalf(\"received unexpected machine v1\")\n\t}\n}\n\n// TestGetVersionV1 performs one test to check if VersionV1()\n// in a cAdvisor client returns the correct result.\nfunc TestGetVersionv1(t *testing.T) {\n\tversion := \"0.1.2\"\n\tclient, server, err := cadvisorTestClient(\"\", nil, version, t)\n\tif err != nil {\n\t\tt.Fatalf(\"unable to get a client %v\", err)\n\t}\n\tdefer server.Close()\n\treturned, err := client.VersionInfo()\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\tif returned != version {\n\t\tt.Fatalf(\"received unexpected version v1\")\n\t}\n}\n\n// TestAttributes performs one test to check if Attributes()\n// in a cAdvisor client returns the correct result.\nfunc TestGetAttributes(t *testing.T) {\n\tattr := &v2.Attributes{\n\t\tKernelVersion:      \"3.3.0\",\n\t\tContainerOsVersion: \"Ubuntu 14.4\",\n\t\tDockerVersion:      \"Docker 1.5\",\n\t\tCadvisorVersion:    \"0.1.2\",\n\t\tNumCores:           8,\n\t\tMemoryCapacity:     31625871360,\n\t\tDiskMap: map[string]v1.DiskInfo{\n\t\t\t\"8:0\": {\n\t\t\t\tName:  \"sda\",\n\t\t\t\tMajor: 8,\n\t\t\t\tMinor: 0,\n\t\t\t\tSize:  10737418240,\n\t\t\t},\n\t\t},\n\t}\n\tclient, server, err := cadvisorTestClient(\"/api/v2.1/attributes\", nil, attr, t)\n\tif err != nil {\n\t\tt.Fatalf(\"unable to get a client %v\", err)\n\t}\n\tdefer server.Close()\n\treturned, err := client.Attributes()\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\tif !reflect.DeepEqual(returned, attr) {\n\t\tt.Fatalf(\"received unexpected attributes\")\n\t}\n}\n\n// TestMachineStats performs one test to check if MachineStats()\n// in a cAdvisor client returns the correct result.\nfunc TestMachineStats(t *testing.T) {\n\tmachineStats := []v2.MachineStats{\n\t\t{\n\t\t\tTimestamp: time.Now(),\n\t\t\tCpu: &v1.CpuStats{\n\t\t\t\tUsage: v1.CpuUsage{\n\t\t\t\t\tTotal: 100000,\n\t\t\t\t},\n\t\t\t\tLoadAverage: 10,\n\t\t\t},\n\t\t\tFilesystem: []v2.MachineFsStats{\n\t\t\t\t{\n\t\t\t\t\tDevice: \"sda1\",\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\tclient, server, err := cadvisorTestClient(\"/api/v2.1/machinestats\", nil, &machineStats, t)\n\tif err != nil {\n\t\tt.Fatalf(\"unable to get a client %v\", err)\n\t}\n\tdefer server.Close()\n\treturned, err := client.MachineStats()\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\tassert.Len(t, returned, len(machineStats))\n\tif !reflect.DeepEqual(returned[0].Cpu, machineStats[0].Cpu) {\n\t\tt.Fatalf(\"received unexpected machine stats\\nExp: %+v\\nAct: %+v\", machineStats, returned)\n\t}\n\tif !reflect.DeepEqual(returned[0].Filesystem, machineStats[0].Filesystem) {\n\t\tt.Fatalf(\"received unexpected machine stats\\nExp: %+v\\nAct: %+v\", machineStats, returned)\n\t}\n}\n\nfunc TestRequestFails(t *testing.T) {\n\terrorText := \"there was an error\"\n\t// Setup a server that simply fails.\n\tts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {\n\t\thttp.Error(w, errorText, 500)\n\t}))\n\tclient, err := NewClient(ts.URL)\n\tif err != nil {\n\t\tts.Close()\n\t\tt.Fatal(err)\n\t}\n\tdefer ts.Close()\n\n\t_, err = client.MachineInfo()\n\tif err == nil {\n\t\tt.Fatalf(\"Expected non-nil error\")\n\t}\n\texpectedError := fmt.Sprintf(\"request failed with error: %q\", errorText)\n\tif strings.Contains(err.Error(), expectedError) {\n\t\tt.Fatalf(\"Expected error %q but received %q\", expectedError, err)\n\t}\n}\n"
  },
  {
    "path": "cmd/cadvisor.go",
    "content": "// Copyright 2014 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage main\n\nimport (\n\t\"crypto/tls\"\n\t\"flag\"\n\t\"fmt\"\n\t\"net/http\"\n\t\"net/http/pprof\"\n\t\"os\"\n\t\"os/signal\"\n\t\"runtime\"\n\t\"strings\"\n\t\"syscall\"\n\n\tcadvisorhttp \"github.com/google/cadvisor/cmd/internal/http\"\n\t\"github.com/google/cadvisor/container\"\n\t\"github.com/google/cadvisor/manager\"\n\t\"github.com/google/cadvisor/metrics\"\n\t\"github.com/google/cadvisor/utils/sysfs\"\n\t\"github.com/google/cadvisor/version\"\n\n\t// Register container providers\n\t_ \"github.com/google/cadvisor/cmd/internal/container/install\"\n\n\t// Register CloudProviders\n\t_ \"github.com/google/cadvisor/utils/cloudinfo/aws\"\n\t_ \"github.com/google/cadvisor/utils/cloudinfo/azure\"\n\t_ \"github.com/google/cadvisor/utils/cloudinfo/gce\"\n\n\t// Register resctrl plugin\n\t_ \"github.com/google/cadvisor/resctrl/intel/install\"\n\n\t\"k8s.io/klog/v2\"\n)\n\nvar argIP = flag.String(\"listen_ip\", \"\", \"IP to listen on, defaults to all IPs\")\nvar argPort = flag.Int(\"port\", 8080, \"port to listen\")\nvar maxProcs = flag.Int(\"max_procs\", 0, \"max number of CPUs that can be used simultaneously. Less than 1 for default (number of cores).\")\n\nvar versionFlag = flag.Bool(\"version\", false, \"print cAdvisor version and exit\")\n\nvar httpAuthFile = flag.String(\"http_auth_file\", \"\", \"HTTP auth file for the web UI\")\nvar httpAuthRealm = flag.String(\"http_auth_realm\", \"localhost\", \"HTTP auth realm for the web UI\")\nvar httpDigestFile = flag.String(\"http_digest_file\", \"\", \"HTTP digest file for the web UI\")\nvar httpDigestRealm = flag.String(\"http_digest_realm\", \"localhost\", \"HTTP digest file for the web UI\")\n\nvar prometheusEndpoint = flag.String(\"prometheus_endpoint\", \"/metrics\", \"Endpoint to expose Prometheus metrics on\")\n\nvar enableProfiling = flag.Bool(\"profiling\", false, \"Enable profiling via web interface host:port/debug/pprof/\")\n\nvar collectorCert = flag.String(\"collector_cert\", \"\", \"Collector's certificate, exposed to endpoints for certificate based authentication.\")\nvar collectorKey = flag.String(\"collector_key\", \"\", \"Key for the collector's certificate\")\n\nvar storeContainerLabels = flag.Bool(\"store_container_labels\", true, \"convert container labels and environment variables into labels on prometheus metrics for each container. If flag set to false, then only metrics exported are container name, first alias, and image name\")\nvar whitelistedContainerLabels = flag.String(\"whitelisted_container_labels\", \"\", \"comma separated list of container labels to be converted to labels on prometheus metrics for each container. store_container_labels must be set to false for this to take effect.\")\n\nvar envMetadataWhiteList = flag.String(\"env_metadata_whitelist\", \"\", \"a comma-separated list of environment variable keys matched with specified prefix that needs to be collected for containers, only support containerd and docker runtime for now.\")\n\nvar urlBasePrefix = flag.String(\"url_base_prefix\", \"\", \"prefix path that will be prepended to all paths to support some reverse proxies\")\n\nvar rawCgroupPrefixWhiteList = flag.String(\"raw_cgroup_prefix_whitelist\", \"\", \"A comma-separated list of cgroup path prefix that needs to be collected even when -docker_only is specified\")\n\nvar perfEvents = flag.String(\"perf_events_config\", \"\", \"Path to a JSON file containing configuration of perf events to measure. Empty value disabled perf events measuring.\")\n\nvar resctrlInterval = flag.Duration(\"resctrl_interval\", 0, \"Resctrl mon groups updating interval. Zero value disables updating mon groups.\")\n\nvar (\n\t// Metrics to be ignored.\n\t// Tcp metrics are ignored by default.\n\tignoreMetrics = container.MetricSet{\n\t\tcontainer.MemoryNumaMetrics:              struct{}{},\n\t\tcontainer.NetworkTcpUsageMetrics:         struct{}{},\n\t\tcontainer.NetworkUdpUsageMetrics:         struct{}{},\n\t\tcontainer.NetworkAdvancedTcpUsageMetrics: struct{}{},\n\t\tcontainer.ProcessSchedulerMetrics:        struct{}{},\n\t\tcontainer.ProcessMetrics:                 struct{}{},\n\t\tcontainer.HugetlbUsageMetrics:            struct{}{},\n\t\tcontainer.ReferencedMemoryMetrics:        struct{}{},\n\t\tcontainer.CPUTopologyMetrics:             struct{}{},\n\t\tcontainer.ResctrlMetrics:                 struct{}{},\n\t\tcontainer.CPUSetMetrics:                  struct{}{},\n\t}\n\n\t// Metrics to be enabled.  Used only if non-empty.\n\tenableMetrics = container.MetricSet{}\n)\n\nfunc init() {\n\toptstr := container.AllMetrics.String()\n\tflag.Var(&ignoreMetrics, \"disable_metrics\", fmt.Sprintf(\"comma-separated list of `metrics` to be disabled. Options are %s.\", optstr))\n\tflag.Var(&enableMetrics, \"enable_metrics\", fmt.Sprintf(\"comma-separated list of `metrics` to be enabled. If set, overrides 'disable_metrics'. Options are %s.\", optstr))\n}\n\nfunc main() {\n\tklog.InitFlags(nil)\n\tdefer klog.Flush()\n\t// Default logging verbosity to V(2)\n\t_ = flag.Set(\"v\", \"2\")\n\tflag.Parse()\n\n\tif *versionFlag {\n\t\tfmt.Printf(\"cAdvisor version %s (%s)\\n\", version.Info[\"version\"], version.Info[\"revision\"])\n\t\tos.Exit(0)\n\t}\n\n\tvar includedMetrics container.MetricSet\n\tif len(enableMetrics) > 0 {\n\t\tincludedMetrics = enableMetrics\n\t} else {\n\t\tincludedMetrics = container.AllMetrics.Difference(ignoreMetrics)\n\t}\n\tklog.V(1).Infof(\"enabled metrics: %s\", includedMetrics.String())\n\tsetMaxProcs()\n\n\tmemoryStorage, err := NewMemoryStorage()\n\tif err != nil {\n\t\tklog.Fatalf(\"Failed to initialize storage driver: %s\", err)\n\t}\n\n\tsysFs := sysfs.NewRealSysFs()\n\n\tcollectorHTTPClient := createCollectorHTTPClient(*collectorCert, *collectorKey)\n\n\tresourceManager, err := manager.New(memoryStorage, sysFs, manager.HousekeepingConfigFlags, includedMetrics, &collectorHTTPClient, strings.Split(*rawCgroupPrefixWhiteList, \",\"), strings.Split(*envMetadataWhiteList, \",\"), *perfEvents, *resctrlInterval)\n\tif err != nil {\n\t\tklog.Fatalf(\"Failed to create a manager: %s\", err)\n\t}\n\n\tmux := http.NewServeMux()\n\n\tif *enableProfiling {\n\t\tmux.HandleFunc(\"/debug/pprof/\", pprof.Index)\n\t\tmux.HandleFunc(\"/debug/pprof/cmdline\", pprof.Cmdline)\n\t\tmux.HandleFunc(\"/debug/pprof/profile\", pprof.Profile)\n\t\tmux.HandleFunc(\"/debug/pprof/symbol\", pprof.Symbol)\n\t}\n\n\t// Register all HTTP handlers.\n\terr = cadvisorhttp.RegisterHandlers(mux, resourceManager, *httpAuthFile, *httpAuthRealm, *httpDigestFile, *httpDigestRealm, *urlBasePrefix)\n\tif err != nil {\n\t\tklog.Fatalf(\"Failed to register HTTP handlers: %v\", err)\n\t}\n\n\tcontainerLabelFunc := metrics.DefaultContainerLabels\n\tif !*storeContainerLabels {\n\t\twhitelistedLabels := strings.Split(*whitelistedContainerLabels, \",\")\n\t\t// Trim spacing in labels\n\t\tfor i := range whitelistedLabels {\n\t\t\twhitelistedLabels[i] = strings.TrimSpace(whitelistedLabels[i])\n\t\t}\n\t\tcontainerLabelFunc = metrics.BaseContainerLabels(whitelistedLabels)\n\t}\n\n\t// Register Prometheus collector to gather information about containers, Go runtime, processes, and machine\n\tcadvisorhttp.RegisterPrometheusHandler(mux, resourceManager, *prometheusEndpoint, containerLabelFunc, includedMetrics)\n\n\t// Start the manager.\n\tif err := resourceManager.Start(); err != nil {\n\t\tklog.Fatalf(\"Failed to start manager: %v\", err)\n\t}\n\n\t// Install signal handler.\n\tinstallSignalHandler(resourceManager)\n\n\tklog.V(1).Infof(\"Starting cAdvisor version: %s-%s on port %d\", version.Info[\"version\"], version.Info[\"revision\"], *argPort)\n\n\trootMux := http.NewServeMux()\n\trootMux.Handle(*urlBasePrefix+\"/\", http.StripPrefix(*urlBasePrefix, mux))\n\n\taddr := fmt.Sprintf(\"%s:%d\", *argIP, *argPort)\n\tklog.Fatal(http.ListenAndServe(addr, rootMux))\n}\n\nfunc setMaxProcs() {\n\t// TODO(vmarmol): Consider limiting if we have a CPU mask in effect.\n\t// Allow as many threads as we have cores unless the user specified a value.\n\tvar numProcs int\n\tif *maxProcs < 1 {\n\t\tnumProcs = runtime.NumCPU()\n\t} else {\n\t\tnumProcs = *maxProcs\n\t}\n\truntime.GOMAXPROCS(numProcs)\n\n\t// Check if the setting was successful.\n\tactualNumProcs := runtime.GOMAXPROCS(0)\n\tif actualNumProcs != numProcs {\n\t\tklog.Warningf(\"Specified max procs of %v but using %v\", numProcs, actualNumProcs)\n\t}\n}\n\nfunc installSignalHandler(containerManager manager.Manager) {\n\tc := make(chan os.Signal, 1)\n\tsignal.Notify(c, os.Interrupt, syscall.SIGTERM)\n\n\t// Block until a signal is received.\n\tgo func() {\n\t\tsig := <-c\n\t\tif err := containerManager.Stop(); err != nil {\n\t\t\tklog.Errorf(\"Failed to stop container manager: %v\", err)\n\t\t}\n\t\tklog.Infof(\"Exiting given signal: %v\", sig)\n\t\tos.Exit(0)\n\t}()\n}\n\nfunc createCollectorHTTPClient(collectorCert, collectorKey string) http.Client {\n\t//Enable accessing insecure endpoints. We should be able to access metrics from any endpoint\n\ttlsConfig := &tls.Config{\n\t\tInsecureSkipVerify: true,\n\t}\n\n\tif collectorCert != \"\" {\n\t\tif collectorKey == \"\" {\n\t\t\tklog.Fatal(\"The collector_key value must be specified if the collector_cert value is set.\")\n\t\t}\n\t\tcert, err := tls.LoadX509KeyPair(collectorCert, collectorKey)\n\t\tif err != nil {\n\t\t\tklog.Fatalf(\"Failed to use the collector certificate and key: %s\", err)\n\t\t}\n\n\t\ttlsConfig.Certificates = []tls.Certificate{cert}\n\t\ttlsConfig.BuildNameToCertificate() //nolint: staticcheck\n\t}\n\n\ttransport := &http.Transport{\n\t\tTLSClientConfig: tlsConfig,\n\t}\n\n\treturn http.Client{Transport: transport}\n}\n"
  },
  {
    "path": "cmd/cadvisor_test.go",
    "content": "// Copyright 2014 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage main\n\nimport (\n\t\"flag\"\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/assert\"\n\n\t\"github.com/google/cadvisor/container\"\n)\n\nfunc TestTcpMetricsAreDisabledByDefault(t *testing.T) {\n\tassert.True(t, ignoreMetrics.Has(container.NetworkTcpUsageMetrics))\n\tflag.Parse()\n\tassert.True(t, ignoreMetrics.Has(container.NetworkTcpUsageMetrics))\n}\n\nfunc TestAdvancedTcpMetricsAreDisabledByDefault(t *testing.T) {\n\tassert.True(t, ignoreMetrics.Has(container.NetworkAdvancedTcpUsageMetrics))\n\tflag.Parse()\n\tassert.True(t, ignoreMetrics.Has(container.NetworkAdvancedTcpUsageMetrics))\n}\n\nfunc TestUdpMetricsAreDisabledByDefault(t *testing.T) {\n\tassert.True(t, ignoreMetrics.Has(container.NetworkUdpUsageMetrics))\n\tflag.Parse()\n\tassert.True(t, ignoreMetrics.Has(container.NetworkUdpUsageMetrics))\n}\n\nfunc TestReferencedMemoryMetricsIsDisabledByDefault(t *testing.T) {\n\tassert.True(t, ignoreMetrics.Has(container.ReferencedMemoryMetrics))\n\tflag.Parse()\n\tassert.True(t, ignoreMetrics.Has(container.ReferencedMemoryMetrics))\n}\n\nfunc TestCPUTopologyMetricsAreDisabledByDefault(t *testing.T) {\n\tassert.True(t, ignoreMetrics.Has(container.CPUTopologyMetrics))\n\tflag.Parse()\n\tassert.True(t, ignoreMetrics.Has(container.CPUTopologyMetrics))\n}\n\nfunc TestMemoryNumaMetricsAreDisabledByDefault(t *testing.T) {\n\tassert.True(t, ignoreMetrics.Has(container.MemoryNumaMetrics))\n\tflag.Parse()\n\tassert.True(t, ignoreMetrics.Has(container.MemoryNumaMetrics))\n}\n\nfunc TestEnableAndIgnoreMetrics(t *testing.T) {\n\ttests := []struct {\n\t\tvalue    string\n\t\texpected []container.MetricKind\n\t}{\n\t\t{\"\", []container.MetricKind{}},\n\t\t{\"disk\", []container.MetricKind{container.DiskUsageMetrics}},\n\t\t{\"disk,tcp,network\", []container.MetricKind{container.DiskUsageMetrics, container.NetworkTcpUsageMetrics, container.NetworkUsageMetrics}},\n\t}\n\n\tfor _, test := range tests {\n\t\tfor _, sets := range []container.MetricSet{enableMetrics, ignoreMetrics} {\n\t\t\tassert.NoError(t, sets.Set(test.value))\n\n\t\t\tassert.Equal(t, len(test.expected), len(sets))\n\t\t\tfor _, expected := range test.expected {\n\t\t\t\tassert.True(t, sets.Has(expected), \"Missing %s\", expected)\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunc TestToIncludedMetrics(t *testing.T) {\n\tignores := []container.MetricSet{\n\t\t{\n\t\t\tcontainer.CpuUsageMetrics: struct{}{},\n\t\t},\n\t\t{},\n\t\tcontainer.AllMetrics,\n\t}\n\n\texpected := []container.MetricSet{\n\t\t{\n\t\t\tcontainer.ProcessSchedulerMetrics:        struct{}{},\n\t\t\tcontainer.PerCpuUsageMetrics:             struct{}{},\n\t\t\tcontainer.MemoryUsageMetrics:             struct{}{},\n\t\t\tcontainer.MemoryNumaMetrics:              struct{}{},\n\t\t\tcontainer.CpuLoadMetrics:                 struct{}{},\n\t\t\tcontainer.DiskIOMetrics:                  struct{}{},\n\t\t\tcontainer.DiskUsageMetrics:               struct{}{},\n\t\t\tcontainer.NetworkUsageMetrics:            struct{}{},\n\t\t\tcontainer.NetworkTcpUsageMetrics:         struct{}{},\n\t\t\tcontainer.NetworkAdvancedTcpUsageMetrics: struct{}{},\n\t\t\tcontainer.NetworkUdpUsageMetrics:         struct{}{},\n\t\t\tcontainer.ProcessMetrics:                 struct{}{},\n\t\t\tcontainer.AppMetrics:                     struct{}{},\n\t\t\tcontainer.HugetlbUsageMetrics:            struct{}{},\n\t\t\tcontainer.PerfMetrics:                    struct{}{},\n\t\t\tcontainer.ReferencedMemoryMetrics:        struct{}{},\n\t\t\tcontainer.CPUTopologyMetrics:             struct{}{},\n\t\t\tcontainer.ResctrlMetrics:                 struct{}{},\n\t\t\tcontainer.CPUSetMetrics:                  struct{}{},\n\t\t\tcontainer.OOMMetrics:                     struct{}{},\n\t\t\tcontainer.PressureMetrics:                struct{}{},\n\t\t},\n\t\tcontainer.AllMetrics,\n\t\t{},\n\t}\n\n\tfor idx, ignore := range ignores {\n\t\tactual := container.AllMetrics.Difference(ignore)\n\t\tassert.Equal(t, actual, expected[idx])\n\t}\n}\n"
  },
  {
    "path": "cmd/go.mod",
    "content": "module github.com/google/cadvisor/cmd\n\ngo 1.24.0\n\n// Record that the cmd module requires the cadvisor library module.\n// The github.com/google/cadvisor/cmd module is built using the Makefile\n// from a clone of the github.com/google/cadvisor repository, so we\n// always use the relative local source rather than specifying a module version.\nrequire github.com/google/cadvisor v0.0.0\n\n// Use the relative local source of the github.com/google/cadvisor library to build\nreplace github.com/google/cadvisor => ../\n\nrequire (\n\tgithub.com/SeanDolphin/bqschema v1.0.0\n\tgithub.com/Shopify/sarama v1.38.1\n\tgithub.com/abbot/go-http-auth v0.4.0\n\tgithub.com/gomodule/redigo v1.9.2\n\tgithub.com/influxdb/influxdb v1.7.9\n\tgithub.com/onsi/ginkgo v1.16.5 // indirect\n\tgithub.com/onsi/gomega v1.24.1 // indirect\n\tgithub.com/prometheus/client_golang v1.22.0\n\tgithub.com/stretchr/testify v1.11.1\n\tgolang.org/x/oauth2 v0.30.0\n\tgoogle.golang.org/api v0.235.0\n\tgopkg.in/olivere/elastic.v2 v2.0.61\n\tk8s.io/klog/v2 v2.130.1\n\tk8s.io/utils v0.0.0-20250502105355-0f33e8f1c979\n)\n\nrequire (\n\tcloud.google.com/go/auth v0.16.1 // indirect\n\tcloud.google.com/go/auth/oauth2adapt v0.2.8 // indirect\n\tcloud.google.com/go/compute/metadata v0.7.0 // indirect\n\tgithub.com/Microsoft/go-winio v0.6.2 // indirect\n\tgithub.com/aws/aws-sdk-go-v2 v1.36.3 // indirect\n\tgithub.com/aws/aws-sdk-go-v2/config v1.29.14 // indirect\n\tgithub.com/aws/aws-sdk-go-v2/credentials v1.17.67 // indirect\n\tgithub.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.30 // indirect\n\tgithub.com/aws/aws-sdk-go-v2/internal/configsources v1.3.34 // indirect\n\tgithub.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.34 // indirect\n\tgithub.com/aws/aws-sdk-go-v2/internal/ini v1.8.3 // indirect\n\tgithub.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.3 // indirect\n\tgithub.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.15 // indirect\n\tgithub.com/aws/aws-sdk-go-v2/service/sso v1.25.3 // indirect\n\tgithub.com/aws/aws-sdk-go-v2/service/ssooidc v1.30.1 // indirect\n\tgithub.com/aws/aws-sdk-go-v2/service/sts v1.33.19 // indirect\n\tgithub.com/aws/smithy-go v1.22.3 // indirect\n\tgithub.com/beorn7/perks v1.0.1 // indirect\n\tgithub.com/blang/semver/v4 v4.0.0 // indirect\n\tgithub.com/cespare/xxhash/v2 v2.3.0 // indirect\n\tgithub.com/containerd/containerd/api v1.10.0 // indirect\n\tgithub.com/containerd/errdefs v1.0.0 // indirect\n\tgithub.com/containerd/errdefs/pkg v0.3.0 // indirect\n\tgithub.com/containerd/log v0.1.0 // indirect\n\tgithub.com/containerd/ttrpc v1.2.7 // indirect\n\tgithub.com/containerd/typeurl/v2 v2.2.3 // indirect\n\tgithub.com/coreos/go-systemd/v22 v22.6.0 // indirect\n\tgithub.com/cyphar/filepath-securejoin v0.6.1 // indirect\n\tgithub.com/davecgh/go-spew v1.1.1 // indirect\n\tgithub.com/distribution/reference v0.6.0 // indirect\n\tgithub.com/docker/go-connections v0.6.0 // indirect\n\tgithub.com/docker/go-units v0.5.0 // indirect\n\tgithub.com/eapache/go-resiliency v1.7.0 // indirect\n\tgithub.com/eapache/go-xerial-snappy v0.0.0-20230731223053-c322873962e3 // indirect\n\tgithub.com/eapache/queue v1.1.0 // indirect\n\tgithub.com/euank/go-kmsg-parser v2.0.0+incompatible // indirect\n\tgithub.com/felixge/httpsnoop v1.0.4 // indirect\n\tgithub.com/go-logr/logr v1.4.3 // indirect\n\tgithub.com/go-logr/stdr v1.2.2 // indirect\n\tgithub.com/godbus/dbus/v5 v5.1.0 // indirect\n\tgithub.com/gogo/protobuf v1.3.2 // indirect\n\tgithub.com/golang/snappy v1.0.0 // indirect\n\tgithub.com/google/s2a-go v0.1.9 // indirect\n\tgithub.com/google/uuid v1.6.0 // indirect\n\tgithub.com/googleapis/enterprise-certificate-proxy v0.3.6 // indirect\n\tgithub.com/googleapis/gax-go/v2 v2.14.2 // indirect\n\tgithub.com/hashicorp/errwrap v1.1.0 // indirect\n\tgithub.com/hashicorp/go-multierror v1.1.1 // indirect\n\tgithub.com/hashicorp/go-uuid v1.0.3 // indirect\n\tgithub.com/influxdata/influxdb v1.12.0 // indirect\n\tgithub.com/jcmturner/aescts/v2 v2.0.0 // indirect\n\tgithub.com/jcmturner/dnsutils/v2 v2.0.0 // indirect\n\tgithub.com/jcmturner/gofork v1.7.6 // indirect\n\tgithub.com/jcmturner/gokrb5/v8 v8.4.4 // indirect\n\tgithub.com/jcmturner/rpc/v2 v2.0.3 // indirect\n\tgithub.com/klauspost/compress v1.18.0 // indirect\n\tgithub.com/mistifyio/go-zfs v2.1.2-0.20190413222219-f784269be439+incompatible // indirect\n\tgithub.com/moby/docker-image-spec v1.3.1 // indirect\n\tgithub.com/moby/moby/api v1.52.0 // indirect\n\tgithub.com/moby/moby/client v0.2.1 // indirect\n\tgithub.com/moby/sys/mountinfo v0.7.2 // indirect\n\tgithub.com/moby/sys/userns v0.1.0 // indirect\n\tgithub.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect\n\tgithub.com/opencontainers/cgroups v0.0.6 // indirect\n\tgithub.com/opencontainers/go-digest v1.0.0 // indirect\n\tgithub.com/opencontainers/image-spec v1.1.1 // indirect\n\tgithub.com/opencontainers/runc v1.4.0 // indirect\n\tgithub.com/opencontainers/runtime-spec v1.3.0 // indirect\n\tgithub.com/pierrec/lz4/v4 v4.1.22 // indirect\n\tgithub.com/pmezard/go-difflib v1.0.0 // indirect\n\tgithub.com/prometheus/client_model v0.6.2 // indirect\n\tgithub.com/prometheus/common v0.64.0 // indirect\n\tgithub.com/prometheus/procfs v0.16.1 // indirect\n\tgithub.com/rcrowley/go-metrics v0.0.0-20250401214520-65e299d6c5c9 // indirect\n\tgithub.com/sirupsen/logrus v1.9.3 // indirect\n\tgithub.com/stretchr/objx v0.5.2 // indirect\n\tgo.opentelemetry.io/auto/sdk v1.1.0 // indirect\n\tgo.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 // indirect\n\tgo.opentelemetry.io/otel v1.36.0 // indirect\n\tgo.opentelemetry.io/otel/metric v1.36.0 // indirect\n\tgo.opentelemetry.io/otel/trace v1.36.0 // indirect\n\tgolang.org/x/crypto v0.45.0 // indirect\n\tgolang.org/x/net v0.47.0 // indirect\n\tgolang.org/x/sync v0.19.0 // indirect\n\tgolang.org/x/sys v0.39.0 // indirect\n\tgolang.org/x/telemetry v0.0.0-20251215142616-e75fd47794af // indirect\n\tgolang.org/x/text v0.31.0 // indirect\n\tgoogle.golang.org/genproto/googleapis/rpc v0.0.0-20250528174236-200df99c418a // indirect\n\tgoogle.golang.org/grpc v1.72.2 // indirect\n\tgoogle.golang.org/protobuf v1.36.8 // indirect\n\tgopkg.in/yaml.v3 v3.0.1 // indirect\n)\n"
  },
  {
    "path": "cmd/go.sum",
    "content": "cloud.google.com/go/auth v0.16.1 h1:XrXauHMd30LhQYVRHLGvJiYeczweKQXZxsTbV9TiguU=\ncloud.google.com/go/auth v0.16.1/go.mod h1:1howDHJ5IETh/LwYs3ZxvlkXF48aSqqJUM+5o02dNOI=\ncloud.google.com/go/auth/oauth2adapt v0.2.8 h1:keo8NaayQZ6wimpNSmW5OPc283g65QNIiLpZnkHRbnc=\ncloud.google.com/go/auth/oauth2adapt v0.2.8/go.mod h1:XQ9y31RkqZCcwJWNSx2Xvric3RrU88hAYYbjDWYDL+c=\ncloud.google.com/go/compute/metadata v0.7.0 h1:PBWF+iiAerVNe8UCHxdOt6eHLVc3ydFeOCw78U8ytSU=\ncloud.google.com/go/compute/metadata v0.7.0/go.mod h1:j5MvL9PprKL39t166CoB1uVHfQMs4tFQZZcKwksXUjo=\ngithub.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY=\ngithub.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU=\ngithub.com/SeanDolphin/bqschema v1.0.0 h1:iCYFd5Qsw6caM2k5/SsITSL9+3kQCr+oz6pnNjWTq90=\ngithub.com/SeanDolphin/bqschema v1.0.0/go.mod h1:TYInVncsPIZH7kybQoIUNJ4pFX1cUc8LoP9RSOxIs6c=\ngithub.com/Shopify/sarama v1.38.1 h1:lqqPUPQZ7zPqYlWpTh+LQ9bhYNu2xJL6k1SJN4WVe2A=\ngithub.com/Shopify/sarama v1.38.1/go.mod h1:iwv9a67Ha8VNa+TifujYoWGxWnu2kNVAQdSdZ4X2o5g=\ngithub.com/Shopify/toxiproxy/v2 v2.5.0 h1:i4LPT+qrSlKNtQf5QliVjdP08GyAH8+BUIc9gT0eahc=\ngithub.com/Shopify/toxiproxy/v2 v2.5.0/go.mod h1:yhM2epWtAmel9CB8r2+L+PCmhH6yH2pITaPAo7jxJl0=\ngithub.com/abbot/go-http-auth v0.4.0 h1:QjmvZ5gSC7jm3Zg54DqWE/T5m1t2AfDu6QlXJT0EVT0=\ngithub.com/abbot/go-http-auth v0.4.0/go.mod h1:Cz6ARTIzApMJDzh5bRMSUou6UMSp0IEXg9km/ci7TJM=\ngithub.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883 h1:bvNMNQO63//z+xNgfBlViaCIJKLlCJ6/fmUseuG0wVQ=\ngithub.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8=\ngithub.com/apache/arrow/go/v7 v7.0.1 h1:WpCfq+AQxvXaI6/KplHE27MPMFx5av0o5NbPCTAGfy4=\ngithub.com/apache/arrow/go/v7 v7.0.1/go.mod h1:JxDpochJbCVxqbX4G8i1jRqMrnTCQdf8pTccAfLD8Es=\ngithub.com/aws/aws-sdk-go-v2 v1.36.3 h1:mJoei2CxPutQVxaATCzDUjcZEjVRdpsiiXi2o38yqWM=\ngithub.com/aws/aws-sdk-go-v2 v1.36.3/go.mod h1:LLXuLpgzEbD766Z5ECcRmi8AzSwfZItDtmABVkRLGzg=\ngithub.com/aws/aws-sdk-go-v2/config v1.29.14 h1:f+eEi/2cKCg9pqKBoAIwRGzVb70MRKqWX4dg1BDcSJM=\ngithub.com/aws/aws-sdk-go-v2/config v1.29.14/go.mod h1:wVPHWcIFv3WO89w0rE10gzf17ZYy+UVS1Geq8Iei34g=\ngithub.com/aws/aws-sdk-go-v2/credentials v1.17.67 h1:9KxtdcIA/5xPNQyZRgUSpYOE6j9Bc4+D7nZua0KGYOM=\ngithub.com/aws/aws-sdk-go-v2/credentials v1.17.67/go.mod h1:p3C44m+cfnbv763s52gCqrjaqyPikj9Sg47kUVaNZQQ=\ngithub.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.30 h1:x793wxmUWVDhshP8WW2mlnXuFrO4cOd3HLBroh1paFw=\ngithub.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.30/go.mod h1:Jpne2tDnYiFascUEs2AWHJL9Yp7A5ZVy3TNyxaAjD6M=\ngithub.com/aws/aws-sdk-go-v2/internal/configsources v1.3.34 h1:ZK5jHhnrioRkUNOc+hOgQKlUL5JeC3S6JgLxtQ+Rm0Q=\ngithub.com/aws/aws-sdk-go-v2/internal/configsources v1.3.34/go.mod h1:p4VfIceZokChbA9FzMbRGz5OV+lekcVtHlPKEO0gSZY=\ngithub.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.34 h1:SZwFm17ZUNNg5Np0ioo/gq8Mn6u9w19Mri8DnJ15Jf0=\ngithub.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.34/go.mod h1:dFZsC0BLo346mvKQLWmoJxT+Sjp+qcVR1tRVHQGOH9Q=\ngithub.com/aws/aws-sdk-go-v2/internal/ini v1.8.3 h1:bIqFDwgGXXN1Kpp99pDOdKMTTb5d2KyU5X/BZxjOkRo=\ngithub.com/aws/aws-sdk-go-v2/internal/ini v1.8.3/go.mod h1:H5O/EsxDWyU+LP/V8i5sm8cxoZgc2fdNR9bxlOFrQTo=\ngithub.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.3 h1:eAh2A4b5IzM/lum78bZ590jy36+d/aFLgKF/4Vd1xPE=\ngithub.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.3/go.mod h1:0yKJC/kb8sAnmlYa6Zs3QVYqaC8ug2AbnNChv5Ox3uA=\ngithub.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.15 h1:dM9/92u2F1JbDaGooxTq18wmmFzbJRfXfVfy96/1CXM=\ngithub.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.15/go.mod h1:SwFBy2vjtA0vZbjjaFtfN045boopadnoVPhu4Fv66vY=\ngithub.com/aws/aws-sdk-go-v2/service/sso v1.25.3 h1:1Gw+9ajCV1jogloEv1RRnvfRFia2cL6c9cuKV2Ps+G8=\ngithub.com/aws/aws-sdk-go-v2/service/sso v1.25.3/go.mod h1:qs4a9T5EMLl/Cajiw2TcbNt2UNo/Hqlyp+GiuG4CFDI=\ngithub.com/aws/aws-sdk-go-v2/service/ssooidc v1.30.1 h1:hXmVKytPfTy5axZ+fYbR5d0cFmC3JvwLm5kM83luako=\ngithub.com/aws/aws-sdk-go-v2/service/ssooidc v1.30.1/go.mod h1:MlYRNmYu/fGPoxBQVvBYr9nyr948aY/WLUvwBMBJubs=\ngithub.com/aws/aws-sdk-go-v2/service/sts v1.33.19 h1:1XuUZ8mYJw9B6lzAkXhqHlJd/XvaX32evhproijJEZY=\ngithub.com/aws/aws-sdk-go-v2/service/sts v1.33.19/go.mod h1:cQnB8CUnxbMU82JvlqjKR2HBOm3fe9pWorWBza6MBJ4=\ngithub.com/aws/smithy-go v1.22.3 h1:Z//5NuZCSW6R4PhQ93hShNbyBbn8BWCmCVCt+Q8Io5k=\ngithub.com/aws/smithy-go v1.22.3/go.mod h1:t1ufH5HMublsJYulve2RKmHDC15xu1f26kHCp/HgceI=\ngithub.com/benbjohnson/immutable v0.4.3 h1:GYHcksoJ9K6HyAUpGxwZURrbTkXA0Dh4otXGqbhdrjA=\ngithub.com/benbjohnson/immutable v0.4.3/go.mod h1:qJIKKSmdqz1tVzNtst1DZzvaqOU1onk1rc03IeM3Owk=\ngithub.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=\ngithub.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=\ngithub.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM=\ngithub.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ=\ngithub.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=\ngithub.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=\ngithub.com/containerd/containerd/api v1.10.0 h1:5n0oHYVBwN4VhoX9fFykCV9dF1/BvAXeg2F8W6UYq1o=\ngithub.com/containerd/containerd/api v1.10.0/go.mod h1:NBm1OAk8ZL+LG8R0ceObGxT5hbUYj7CzTmR3xh0DlMM=\ngithub.com/containerd/errdefs v1.0.0 h1:tg5yIfIlQIrxYtu9ajqY42W3lpS19XqdxRQeEwYG8PI=\ngithub.com/containerd/errdefs v1.0.0/go.mod h1:+YBYIdtsnF4Iw6nWZhJcqGSg/dwvV7tyJ/kCkyJ2k+M=\ngithub.com/containerd/errdefs/pkg v0.3.0 h1:9IKJ06FvyNlexW690DXuQNx2KA2cUJXx151Xdx3ZPPE=\ngithub.com/containerd/errdefs/pkg v0.3.0/go.mod h1:NJw6s9HwNuRhnjJhM7pylWwMyAkmCQvQ4GpJHEqRLVk=\ngithub.com/containerd/log v0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I=\ngithub.com/containerd/log v0.1.0/go.mod h1:VRRf09a7mHDIRezVKTRCrOq78v577GXq3bSa3EhrzVo=\ngithub.com/containerd/ttrpc v1.2.7 h1:qIrroQvuOL9HQ1X6KHe2ohc7p+HP/0VE6XPU7elJRqQ=\ngithub.com/containerd/ttrpc v1.2.7/go.mod h1:YCXHsb32f+Sq5/72xHubdiJRQY9inL4a4ZQrAbN1q9o=\ngithub.com/containerd/typeurl/v2 v2.2.3 h1:yNA/94zxWdvYACdYO8zofhrTVuQY73fFU1y++dYSw40=\ngithub.com/containerd/typeurl/v2 v2.2.3/go.mod h1:95ljDnPfD3bAbDJRugOiShd/DlAAsxGtUBhJxIn7SCk=\ngithub.com/coreos/go-systemd/v22 v22.6.0 h1:aGVa/v8B7hpb0TKl0MWoAavPDmHvobFe5R5zn0bCJWo=\ngithub.com/coreos/go-systemd/v22 v22.6.0/go.mod h1:iG+pp635Fo7ZmV/j14KUcmEyWF+0X7Lua8rrTWzYgWU=\ngithub.com/cyphar/filepath-securejoin v0.6.1 h1:5CeZ1jPXEiYt3+Z6zqprSAgSWiggmpVyciv8syjIpVE=\ngithub.com/cyphar/filepath-securejoin v0.6.1/go.mod h1:A8hd4EnAeyujCJRrICiOWqjS1AX0a9kM5XL+NwKoYSc=\ngithub.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=\ngithub.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=\ngithub.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=\ngithub.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk=\ngithub.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E=\ngithub.com/docker/go-connections v0.6.0 h1:LlMG9azAe1TqfR7sO+NJttz1gy6KO7VJBh+pMmjSD94=\ngithub.com/docker/go-connections v0.6.0/go.mod h1:AahvXYshr6JgfUJGdDCs2b5EZG/vmaMAntpSFH5BFKE=\ngithub.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4=\ngithub.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=\ngithub.com/eapache/go-resiliency v1.7.0 h1:n3NRTnBn5N0Cbi/IeOHuQn9s2UwVUH7Ga0ZWcP+9JTA=\ngithub.com/eapache/go-resiliency v1.7.0/go.mod h1:5yPzW0MIvSe0JDsv0v+DvcjEv2FyD6iZYSs1ZI+iQho=\ngithub.com/eapache/go-xerial-snappy v0.0.0-20230731223053-c322873962e3 h1:Oy0F4ALJ04o5Qqpdz8XLIpNA3WM/iSIXqxtqo7UGVws=\ngithub.com/eapache/go-xerial-snappy v0.0.0-20230731223053-c322873962e3/go.mod h1:YvSRo5mw33fLEx1+DlK6L2VV43tJt5Eyel9n9XBcR+0=\ngithub.com/eapache/queue v1.1.0 h1:YOEu7KNc61ntiQlcEeUIoDTJ2o8mQznoNvUhiigpIqc=\ngithub.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I=\ngithub.com/euank/go-kmsg-parser v2.0.0+incompatible h1:cHD53+PLQuuQyLZeriD1V/esuG4MuU0Pjs5y6iknohY=\ngithub.com/euank/go-kmsg-parser v2.0.0+incompatible/go.mod h1:MhmAMZ8V4CYH4ybgdRwPr2TU5ThnS43puaKEMpja1uw=\ngithub.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg=\ngithub.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=\ngithub.com/fortytw2/leaktest v1.3.0 h1:u8491cBMTQ8ft8aeV+adlcytMZylmA5nnwwkRZjI8vw=\ngithub.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g=\ngithub.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=\ngithub.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4=\ngithub.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=\ngithub.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=\ngithub.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI=\ngithub.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=\ngithub.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=\ngithub.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=\ngithub.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE=\ngithub.com/goccy/go-json v0.10.3 h1:KZ5WoDbxAIgm2HNbYckL0se1fHD6rz5j4ywS6ebzDqA=\ngithub.com/goccy/go-json v0.10.3/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M=\ngithub.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk=\ngithub.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=\ngithub.com/gofrs/uuid v3.3.0+incompatible h1:8K4tyRfvU1CYPgJsveYFQMhpFd/wXNM7iK6rR7UHz84=\ngithub.com/gofrs/uuid v3.3.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=\ngithub.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=\ngithub.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=\ngithub.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=\ngithub.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=\ngithub.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=\ngithub.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=\ngithub.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=\ngithub.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=\ngithub.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=\ngithub.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=\ngithub.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=\ngithub.com/golang/snappy v1.0.0 h1:Oy607GVXHs7RtbggtPBnr2RmDArIsAefDwvrdWvRhGs=\ngithub.com/golang/snappy v1.0.0/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=\ngithub.com/gomodule/redigo v1.9.2 h1:HrutZBLhSIU8abiSfW8pj8mPhOyMYjZT/wcA4/L9L9s=\ngithub.com/gomodule/redigo v1.9.2/go.mod h1:KsU3hiK/Ay8U42qpaJk+kuNa3C+spxapWpM+ywhcgtw=\ngithub.com/google/flatbuffers v24.3.25+incompatible h1:CX395cjN9Kke9mmalRoL3d81AtFUxJM+yDthflgJGkI=\ngithub.com/google/flatbuffers v24.3.25+incompatible/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8=\ngithub.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=\ngithub.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=\ngithub.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=\ngithub.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=\ngithub.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=\ngithub.com/google/s2a-go v0.1.9 h1:LGD7gtMgezd8a/Xak7mEWL0PjoTQFvpRudN895yqKW0=\ngithub.com/google/s2a-go v0.1.9/go.mod h1:YA0Ei2ZQL3acow2O62kdp9UlnvMmU7kA6Eutn0dXayM=\ngithub.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=\ngithub.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=\ngithub.com/googleapis/enterprise-certificate-proxy v0.3.6 h1:GW/XbdyBFQ8Qe+YAmFU9uHLo7OnF5tL52HFAgMmyrf4=\ngithub.com/googleapis/enterprise-certificate-proxy v0.3.6/go.mod h1:MkHOF77EYAE7qfSuSS9PU6g4Nt4e11cnsDUowfwewLA=\ngithub.com/googleapis/gax-go/v2 v2.14.2 h1:eBLnkZ9635krYIPD+ag1USrOAI0Nr0QYF3+/3GqO0k0=\ngithub.com/googleapis/gax-go/v2 v2.14.2/go.mod h1:ON64QhlJkhVtSqp4v1uaK92VyZ2gmvDQsweuyLV+8+w=\ngithub.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+HVt/4epWDjd4=\ngithub.com/gorilla/sessions v1.2.1/go.mod h1:dk2InVEVJ0sfLlnXv9EAgkf6ecYs/i80K/zI+bUmuGM=\ngithub.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=\ngithub.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I=\ngithub.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=\ngithub.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo=\ngithub.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM=\ngithub.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=\ngithub.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8=\ngithub.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=\ngithub.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=\ngithub.com/influxdata/flux v0.196.1 h1:RZypfrrAZeIixD/2As+qoyrwfs6Gx7VcnTRNGNjBfUA=\ngithub.com/influxdata/flux v0.196.1/go.mod h1:+Y4mBygx6q98onpdKJd6vJPrTNjHriQhwh/gM+3IvUQ=\ngithub.com/influxdata/influxdb v1.12.0 h1:hVFeHtEUh/MkI6YCmB1TAXlPgV4ZNh/V5FP6z7ywRLo=\ngithub.com/influxdata/influxdb v1.12.0/go.mod h1:11RjLuBNkuWaJQFViRF/rpNzICfU6X0nuO003yeleKY=\ngithub.com/influxdata/influxql v1.4.1 h1:UB+TMc9cB6mDdkPmH/5sBU8FQ+ZCWRX2JPcPDIFrLcs=\ngithub.com/influxdata/influxql v1.4.1/go.mod h1:VqxAKyQz5p8GzgGsxWalCWYGxEqw6kvJo2IickMQiQk=\ngithub.com/influxdb/influxdb v1.7.9 h1:KMBwwvyJyBppIwrg5t0662p+Yei/ucnIkqUl8txiQdQ=\ngithub.com/influxdb/influxdb v1.7.9/go.mod h1:GpjLgHRqWhDGlPAg7+Rj6NAYuzPojBM8XLG5Ouvvq+Q=\ngithub.com/jcmturner/aescts/v2 v2.0.0 h1:9YKLH6ey7H4eDBXW8khjYslgyqG2xZikXP0EQFKrle8=\ngithub.com/jcmturner/aescts/v2 v2.0.0/go.mod h1:AiaICIRyfYg35RUkr8yESTqvSy7csK90qZ5xfvvsoNs=\ngithub.com/jcmturner/dnsutils/v2 v2.0.0 h1:lltnkeZGL0wILNvrNiVCR6Ro5PGU/SeBvVO/8c/iPbo=\ngithub.com/jcmturner/dnsutils/v2 v2.0.0/go.mod h1:b0TnjGOvI/n42bZa+hmXL+kFJZsFT7G4t3HTlQ184QM=\ngithub.com/jcmturner/gofork v1.7.6 h1:QH0l3hzAU1tfT3rZCnW5zXl+orbkNMMRGJfdJjHVETg=\ngithub.com/jcmturner/gofork v1.7.6/go.mod h1:1622LH6i/EZqLloHfE7IeZ0uEJwMSUyQ/nDd82IeqRo=\ngithub.com/jcmturner/goidentity/v6 v6.0.1 h1:VKnZd2oEIMorCTsFBnJWbExfNN7yZr3EhJAxwOkZg6o=\ngithub.com/jcmturner/goidentity/v6 v6.0.1/go.mod h1:X1YW3bgtvwAXju7V3LCIMpY0Gbxyjn/mY9zx4tFonSg=\ngithub.com/jcmturner/gokrb5/v8 v8.4.4 h1:x1Sv4HaTpepFkXbt2IkL29DXRf8sOfZXo8eRKh687T8=\ngithub.com/jcmturner/gokrb5/v8 v8.4.4/go.mod h1:1btQEpgT6k+unzCwX1KdWMEwPPkkgBtP+F6aCACiMrs=\ngithub.com/jcmturner/rpc/v2 v2.0.3 h1:7FXXj8Ti1IaVFpSAziCZWNzbNuZmnvw/i6CqLNdWfZY=\ngithub.com/jcmturner/rpc/v2 v2.0.3/go.mod h1:VUJYCIDm3PVOEHw8sgt091/20OJjskO/YJki3ELg/Hc=\ngithub.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=\ngithub.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=\ngithub.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo=\ngithub.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ=\ngithub.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=\ngithub.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=\ngithub.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=\ngithub.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=\ngithub.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=\ngithub.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=\ngithub.com/mistifyio/go-zfs v2.1.2-0.20190413222219-f784269be439+incompatible h1:aKW/4cBs+yK6gpqU3K/oIwk9Q/XICqd3zOX/UFuvqmk=\ngithub.com/mistifyio/go-zfs v2.1.2-0.20190413222219-f784269be439+incompatible/go.mod h1:8AuVvqP/mXw1px98n46wfvcGfQ4ci2FwoAjKYxuo3Z4=\ngithub.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3Nl2EsFP0=\ngithub.com/moby/docker-image-spec v1.3.1/go.mod h1:eKmb5VW8vQEh/BAr2yvVNvuiJuY6UIocYsFu/DxxRpo=\ngithub.com/moby/moby/api v1.52.0 h1:00BtlJY4MXkkt84WhUZPRqt5TvPbgig2FZvTbe3igYg=\ngithub.com/moby/moby/api v1.52.0/go.mod h1:8mb+ReTlisw4pS6BRzCMts5M49W5M7bKt1cJy/YbAqc=\ngithub.com/moby/moby/client v0.2.1 h1:1Grh1552mvv6i+sYOdY+xKKVTvzJegcVMhuXocyDz/k=\ngithub.com/moby/moby/client v0.2.1/go.mod h1:O+/tw5d4a1Ha/ZA/tPxIZJapJRUS6LNZ1wiVRxYHyUE=\ngithub.com/moby/sys/mountinfo v0.7.2 h1:1shs6aH5s4o5H2zQLn796ADW1wMrIwHsyJ2v9KouLrg=\ngithub.com/moby/sys/mountinfo v0.7.2/go.mod h1:1YOa8w8Ih7uW0wALDUgT1dTTSBrZ+HiBLGws92L2RU4=\ngithub.com/moby/sys/userns v0.1.0 h1:tVLXkFOxVu9A64/yh59slHVv9ahO9UIev4JZusOLG/g=\ngithub.com/moby/sys/userns v0.1.0/go.mod h1:IHUYgu/kao6N8YZlp9Cf444ySSvCmDlmzUcYfDHOl28=\ngithub.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=\ngithub.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=\ngithub.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=\ngithub.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE=\ngithub.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU=\ngithub.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=\ngithub.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=\ngithub.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE=\ngithub.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU=\ngithub.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=\ngithub.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=\ngithub.com/onsi/gomega v1.24.1 h1:KORJXNNTzJXzu4ScJWssJfJMnJ+2QJqhoQSRwNlze9E=\ngithub.com/onsi/gomega v1.24.1/go.mod h1:3AOiACssS3/MajrniINInwbfOOtfZvplPzuRSmvt1jM=\ngithub.com/opencontainers/cgroups v0.0.6 h1:tfZFWTIIGaUUFImTyuTg+Mr5x8XRiSdZESgEBW7UxuI=\ngithub.com/opencontainers/cgroups v0.0.6/go.mod h1:oWVzJsKK0gG9SCRBfTpnn16WcGEqDI8PAcpMGbqWxcs=\ngithub.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=\ngithub.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=\ngithub.com/opencontainers/image-spec v1.1.1 h1:y0fUlFfIZhPF1W537XOLg0/fcx6zcHCJwooC2xJA040=\ngithub.com/opencontainers/image-spec v1.1.1/go.mod h1:qpqAh3Dmcf36wStyyWU+kCeDgrGnAve2nCC8+7h8Q0M=\ngithub.com/opencontainers/runc v1.4.0 h1:FG1Hw0GBYPsNki+mBz1QOrSzbwbAcerhrAD2r097QCc=\ngithub.com/opencontainers/runc v1.4.0/go.mod h1:sch3Bh3c1NlyAkALoAUz5Br9ubMLZzFcxuovZbnkErk=\ngithub.com/opencontainers/runtime-spec v1.3.0 h1:YZupQUdctfhpZy3TM39nN9Ika5CBWT5diQ8ibYCRkxg=\ngithub.com/opencontainers/runtime-spec v1.3.0/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=\ngithub.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs=\ngithub.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc=\ngithub.com/pierrec/lz4/v4 v4.1.22 h1:cKFw6uJDK+/gfw5BcDL0JL5aBsAFdsIT18eRtLj7VIU=\ngithub.com/pierrec/lz4/v4 v4.1.22/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=\ngithub.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=\ngithub.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=\ngithub.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=\ngithub.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=\ngithub.com/prometheus/client_golang v1.22.0 h1:rb93p9lokFEsctTys46VnV1kLCDpVZ0a/Y92Vm0Zc6Q=\ngithub.com/prometheus/client_golang v1.22.0/go.mod h1:R7ljNsLXhuQXYZYtw6GAE9AZg8Y7vEW5scdCXrWRXC0=\ngithub.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNwqPLxwZyk=\ngithub.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE=\ngithub.com/prometheus/common v0.64.0 h1:pdZeA+g617P7oGv1CzdTzyeShxAGrTBsolKNOLQPGO4=\ngithub.com/prometheus/common v0.64.0/go.mod h1:0gZns+BLRQ3V6NdaerOhMbwwRbNh9hkGINtQAsP5GS8=\ngithub.com/prometheus/procfs v0.16.1 h1:hZ15bTNuirocR6u0JZ6BAHHmwS1p8B4P6MRqxtzMyRg=\ngithub.com/prometheus/procfs v0.16.1/go.mod h1:teAbpZRB1iIAJYREa1LsoWUXykVXA1KlTmWl8x/U+Is=\ngithub.com/rcrowley/go-metrics v0.0.0-20250401214520-65e299d6c5c9 h1:bsUq1dX0N8AOIL7EB/X911+m4EHsnWEHeJ0c+3TTBrg=\ngithub.com/rcrowley/go-metrics v0.0.0-20250401214520-65e299d6c5c9/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=\ngithub.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII=\ngithub.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o=\ngithub.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0=\ngithub.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=\ngithub.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=\ngithub.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=\ngithub.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=\ngithub.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=\ngithub.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=\ngithub.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY=\ngithub.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=\ngithub.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=\ngithub.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=\ngithub.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=\ngithub.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=\ngithub.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=\ngithub.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=\ngithub.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=\ngithub.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=\ngithub.com/uber/jaeger-client-go v2.28.0+incompatible h1:G4QSBfvPKvg5ZM2j9MrJFdfI5iSljY/WnJqOGFao6HI=\ngithub.com/uber/jaeger-client-go v2.28.0+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk=\ngithub.com/uber/jaeger-lib v2.4.1+incompatible h1:td4jdvLcExb4cBISKIpHuGoVXh+dVKhn2Um6rjCsSsg=\ngithub.com/uber/jaeger-lib v2.4.1+incompatible/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U=\ngithub.com/xlab/treeprint v0.0.0-20180616005107-d6fb6747feb6 h1:YdYsPAZ2pC6Tow/nPZOPQ96O3hm/ToAkGsPLzedXERk=\ngithub.com/xlab/treeprint v0.0.0-20180616005107-d6fb6747feb6/go.mod h1:ce1O1j6UtZfjr22oyGxGLbauSBp2YVXpARAosm7dHBg=\ngithub.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=\ngithub.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=\ngithub.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=\ngo.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA=\ngo.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A=\ngo.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 h1:F7Jx+6hwnZ41NSFTO5q4LYDtJRXBf2PD0rNBkeB/lus=\ngo.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0/go.mod h1:UHB22Z8QsdRDrnAtX4PntOl36ajSxcdUMt1sF7Y6E7Q=\ngo.opentelemetry.io/otel v1.36.0 h1:UumtzIklRBY6cI/lllNZlALOF5nNIzJVb16APdvgTXg=\ngo.opentelemetry.io/otel v1.36.0/go.mod h1:/TcFMXYjyRNh8khOAO9ybYkqaDBb/70aVwkNML4pP8E=\ngo.opentelemetry.io/otel/metric v1.36.0 h1:MoWPKVhQvJ+eeXWHFBOPoBOi20jh6Iq2CcCREuTYufE=\ngo.opentelemetry.io/otel/metric v1.36.0/go.mod h1:zC7Ks+yeyJt4xig9DEw9kuUFe5C3zLbVjV2PzT6qzbs=\ngo.opentelemetry.io/otel/sdk v1.36.0 h1:b6SYIuLRs88ztox4EyrvRti80uXIFy+Sqzoh9kFULbs=\ngo.opentelemetry.io/otel/sdk v1.36.0/go.mod h1:+lC+mTgD+MUWfjJubi2vvXWcVxyr9rmlshZni72pXeY=\ngo.opentelemetry.io/otel/sdk/metric v1.36.0 h1:r0ntwwGosWGaa0CrSt8cuNuTcccMXERFwHX4dThiPis=\ngo.opentelemetry.io/otel/sdk/metric v1.36.0/go.mod h1:qTNOhFDfKRwX0yXOqJYegL5WRaW376QbB7P4Pb0qva4=\ngo.opentelemetry.io/otel/trace v1.36.0 h1:ahxWNuqZjpdiFAyrIoQ4GIiAIhxAunQR6MUoKrsNd4w=\ngo.opentelemetry.io/otel/trace v1.36.0/go.mod h1:gQ+OnDZzrybY4k4seLzPAWNwVBBVlF2szhehOBB/tGA=\ngo.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw=\ngo.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=\ngo.uber.org/multierr v1.6.0 h1:y6IPFStTAIT5Ytl7/XYmHvzXQ7S3g/IeZW9hyZ5thw4=\ngo.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=\ngo.uber.org/zap v1.16.0 h1:uFRZXykJGK9lLY4HtgSw44DnIcAM+kRBP7x5m+NpAOM=\ngo.uber.org/zap v1.16.0/go.mod h1:MA8QOfq0BHJwdXa996Y4dYkAqRKB8/1K1QMMZVaNZjQ=\ngolang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=\ngolang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=\ngolang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=\ngolang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=\ngolang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58=\ngolang.org/x/crypto v0.45.0 h1:jMBrvKuj23MTlT0bQEOBcAE0mjg8mK9RXFhRH6nyF3Q=\ngolang.org/x/crypto v0.45.0/go.mod h1:XTGrrkGJve7CYK7J8PEww4aY7gM3qMCElcJQ8n8JdX4=\ngolang.org/x/exp v0.0.0-20240604190554-fc45aab8b7f8 h1:LoYXNGAShUG3m/ehNk4iFctuhGX/+R1ZpfJ4/ia80JM=\ngolang.org/x/exp v0.0.0-20240604190554-fc45aab8b7f8/go.mod h1:jj3sYF3dwk5D+ghuXyeI3r5MFf+NT2An6/9dOA95KSI=\ngolang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=\ngolang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=\ngolang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=\ngolang.org/x/mod v0.31.0 h1:HaW9xtz0+kOcWKwli0ZXy79Ix+UW/vOfmWI5QVd2tgI=\ngolang.org/x/mod v0.31.0/go.mod h1:43JraMp9cGx1Rx3AqioxrbrhNsLl2l/iNAvuBkrezpg=\ngolang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=\ngolang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=\ngolang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=\ngolang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=\ngolang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=\ngolang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=\ngolang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=\ngolang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=\ngolang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY=\ngolang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU=\ngolang.org/x/oauth2 v0.30.0 h1:dnDm7JmhM45NNpd8FDDeLhK6FwqbOf4MLCM9zb1BOHI=\ngolang.org/x/oauth2 v0.30.0/go.mod h1:B++QgG3ZKulg6sRPGD/mqlHQs5rB3Ml9erfeDY7xKlU=\ngolang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4=\ngolang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=\ngolang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=\ngolang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=\ngolang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.39.0 h1:CvCKL8MeisomCi6qNZ+wbb0DN9E5AATixKsvNtMoMFk=\ngolang.org/x/sys v0.39.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=\ngolang.org/x/telemetry v0.0.0-20251215142616-e75fd47794af h1:JLNgZmN0uDGV+zlgKknvmvX9+atzn9b7S6M1L6J5tQs=\ngolang.org/x/telemetry v0.0.0-20251215142616-e75fd47794af/go.mod h1:ArQvPJS723nJQietgilmZA+shuB3CZxH1n2iXq9VSfs=\ngolang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=\ngolang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=\ngolang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=\ngolang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=\ngolang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=\ngolang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=\ngolang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=\ngolang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM=\ngolang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM=\ngolang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=\ngolang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=\ngolang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=\ngolang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=\ngolang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=\ngolang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=\ngolang.org/x/tools v0.38.0 h1:Hx2Xv8hISq8Lm16jvBZ2VQf+RLmbd7wVUsALibYI/IQ=\ngolang.org/x/tools v0.38.0/go.mod h1:yEsQ/d/YK8cjh0L6rZlY8tgtlKiBNTL14pGDJPJpYQs=\ngolang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=\ngolang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=\ngolang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=\ngolang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=\ngolang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 h1:+cNy6SZtPcJQH3LJVLOSmiC7MMxXNOb3PU/VUEz+EhU=\ngolang.org/x/xerrors v0.0.0-20231012003039-104605ab7028/go.mod h1:NDW/Ps6MPRej6fsCIbMTohpP40sJ/P/vI1MoTEGwX90=\ngoogle.golang.org/api v0.235.0 h1:C3MkpQSRxS1Jy6AkzTGKKrpSCOd2WOGrezZ+icKSkKo=\ngoogle.golang.org/api v0.235.0/go.mod h1:QpeJkemzkFKe5VCE/PMv7GsUfn9ZF+u+q1Q7w6ckxTg=\ngoogle.golang.org/genproto v0.0.0-20250505200425-f936aa4a68b2 h1:1tXaIXCracvtsRxSBsYDiSBN0cuJvM7QYW+MrpIRY78=\ngoogle.golang.org/genproto v0.0.0-20250505200425-f936aa4a68b2/go.mod h1:49MsLSx0oWMOZqcpB3uL8ZOkAh1+TndpJ8ONoCBWiZk=\ngoogle.golang.org/genproto/googleapis/api v0.0.0-20250505200425-f936aa4a68b2 h1:vPV0tzlsK6EzEDHNNH5sa7Hs9bd7iXR7B1tSiPepkV0=\ngoogle.golang.org/genproto/googleapis/api v0.0.0-20250505200425-f936aa4a68b2/go.mod h1:pKLAc5OolXC3ViWGI62vvC0n10CpwAtRcTNCFwTKBEw=\ngoogle.golang.org/genproto/googleapis/rpc v0.0.0-20250528174236-200df99c418a h1:v2PbRU4K3llS09c7zodFpNePeamkAwG3mPrAery9VeE=\ngoogle.golang.org/genproto/googleapis/rpc v0.0.0-20250528174236-200df99c418a/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A=\ngoogle.golang.org/grpc v1.72.2 h1:TdbGzwb82ty4OusHWepvFWGLgIbNo1/SUynEN0ssqv8=\ngoogle.golang.org/grpc v1.72.2/go.mod h1:wH5Aktxcg25y1I3w7H69nHfXdOG3UiadoBtjh3izSDM=\ngoogle.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=\ngoogle.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=\ngoogle.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=\ngoogle.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=\ngoogle.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=\ngoogle.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=\ngoogle.golang.org/protobuf v1.36.8 h1:xHScyCOEuuwZEc6UtSOvPbAT4zRh0xcNRYekJwfqyMc=\ngoogle.golang.org/protobuf v1.36.8/go.mod h1:fuxRtAxBytpl4zzqUh6/eyUujkJdNiuEkXntxiD/uRU=\ngopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=\ngopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=\ngopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=\ngopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=\ngopkg.in/olivere/elastic.v2 v2.0.61 h1:7cpl3MW8ysa4GYFBXklpo5mspe4NK0rpZTdyZ+QcD4U=\ngopkg.in/olivere/elastic.v2 v2.0.61/go.mod h1:CTVyl1gckiFw1aLZYxC00g3f9jnHmhoOKcWF7W3c6n4=\ngopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=\ngopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=\ngopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=\ngopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=\ngopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=\ngopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=\ngopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=\ngopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=\ngotest.tools/v3 v3.5.2 h1:7koQfIKdy+I8UTetycgUqXWSDwpgv193Ka+qRsmBY8Q=\ngotest.tools/v3 v3.5.2/go.mod h1:LtdLGcnqToBH83WByAAi/wiwSFCArdFIUV/xxN4pcjA=\nk8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk=\nk8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE=\nk8s.io/utils v0.0.0-20250502105355-0f33e8f1c979 h1:jgJW5IePPXLGB8e/1wvd0Ich9QE97RvvF3a8J3fP/Lg=\nk8s.io/utils v0.0.0-20250502105355-0f33e8f1c979/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=\npgregory.net/rapid v1.2.0 h1:keKAYRcjm+e1F0oAuU5F5+YPAWcyxNNRK2wud503Gnk=\npgregory.net/rapid v1.2.0/go.mod h1:PY5XlDGj0+V1FCq0o192FdRhpKHGTRIWBgqjDBTrq04=\n"
  },
  {
    "path": "cmd/internal/api/handler.go",
    "content": "// Copyright 2014 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n// Package api provides a handler for /api/\npackage api\n\nimport (\n\t\"encoding/json\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"path\"\n\t\"regexp\"\n\t\"sort\"\n\t\"strconv\"\n\t\"strings\"\n\t\"time\"\n\n\thttpmux \"github.com/google/cadvisor/cmd/internal/http/mux\"\n\t\"github.com/google/cadvisor/events\"\n\tinfo \"github.com/google/cadvisor/info/v1\"\n\t\"github.com/google/cadvisor/manager\"\n\n\t\"k8s.io/klog/v2\"\n)\n\nconst (\n\tapiResource = \"/api/\"\n)\n\nfunc RegisterHandlers(mux httpmux.Mux, m manager.Manager) error {\n\tapiVersions := getAPIVersions()\n\tsupportedAPIVersions := make(map[string]ApiVersion, len(apiVersions))\n\tfor _, v := range apiVersions {\n\t\tsupportedAPIVersions[v.Version()] = v\n\t}\n\n\tmux.HandleFunc(apiResource, func(w http.ResponseWriter, r *http.Request) {\n\t\terr := handleRequest(supportedAPIVersions, m, w, r)\n\t\tif err != nil {\n\t\t\thttp.Error(w, err.Error(), 500)\n\t\t}\n\t})\n\treturn nil\n}\n\n// Captures the API version, requestType [optional], and remaining request [optional].\nvar apiRegexp = regexp.MustCompile(`/api/([^/]+)/?([^/]+)?(.*)`)\n\nconst (\n\tapiVersion = iota + 1\n\tapiRequestType\n\tapiRequestArgs\n)\n\nfunc handleRequest(supportedAPIVersions map[string]ApiVersion, m manager.Manager, w http.ResponseWriter, r *http.Request) error {\n\tstart := time.Now()\n\tdefer func() {\n\t\tklog.V(4).Infof(\"Request took %s\", time.Since(start))\n\t}()\n\n\trequest := r.URL.Path\n\n\tconst apiPrefix = \"/api\"\n\tif !strings.HasPrefix(request, apiPrefix) {\n\t\treturn fmt.Errorf(\"incomplete API request %q\", request)\n\t}\n\n\t// If the request doesn't have an API version, list those.\n\tif request == apiPrefix || request == apiResource {\n\t\tversions := make([]string, 0, len(supportedAPIVersions))\n\t\tfor v := range supportedAPIVersions {\n\t\t\tversions = append(versions, v)\n\t\t}\n\t\tsort.Strings(versions)\n\t\thttp.Error(w, fmt.Sprintf(\"Supported API versions: %s\", strings.Join(versions, \",\")), http.StatusBadRequest)\n\t\treturn nil\n\t}\n\n\t// Verify that we have all the elements we expect:\n\t// /<version>/<request type>[/<args...>]\n\trequestElements := apiRegexp.FindStringSubmatch(request)\n\tif len(requestElements) == 0 {\n\t\treturn fmt.Errorf(\"malformed request %q\", request)\n\t}\n\tversion := requestElements[apiVersion]\n\trequestType := requestElements[apiRequestType]\n\trequestArgs := strings.Split(requestElements[apiRequestArgs], \"/\")\n\n\t// Check supported versions.\n\tversionHandler, ok := supportedAPIVersions[version]\n\tif !ok {\n\t\treturn fmt.Errorf(\"unsupported API version %q\", version)\n\t}\n\n\t// If no request type, list possible request types.\n\tif requestType == \"\" {\n\t\trequestTypes := versionHandler.SupportedRequestTypes()\n\t\tsort.Strings(requestTypes)\n\t\thttp.Error(w, fmt.Sprintf(\"Supported request types: %q\", strings.Join(requestTypes, \",\")), http.StatusBadRequest)\n\t\treturn nil\n\t}\n\n\t// Trim the first empty element from the request.\n\tif len(requestArgs) > 0 && requestArgs[0] == \"\" {\n\t\trequestArgs = requestArgs[1:]\n\t}\n\n\treturn versionHandler.HandleRequest(requestType, requestArgs, m, w, r)\n\n}\n\nfunc writeResult(res interface{}, w http.ResponseWriter) error {\n\tout, err := json.Marshal(res)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to marshall response %+v with error: %s\", res, err)\n\t}\n\n\tw.Header().Set(\"Content-Type\", \"application/json\")\n\t_, err = w.Write(out)\n\treturn err\n\n}\n\nfunc streamResults(eventChannel *events.EventChannel, w http.ResponseWriter, r *http.Request, m manager.Manager) error {\n\tflusher, ok := w.(http.Flusher)\n\tif !ok {\n\t\treturn errors.New(\"could not access http.Flusher\")\n\t}\n\n\tw.Header().Set(\"Transfer-Encoding\", \"chunked\")\n\tw.WriteHeader(http.StatusOK)\n\tflusher.Flush()\n\n\tenc := json.NewEncoder(w)\n\tfor {\n\t\tselect {\n\t\tcase <-r.Context().Done():\n\t\t\tm.CloseEventChannel(eventChannel.GetWatchId())\n\t\t\treturn nil\n\t\tcase ev := <-eventChannel.GetChannel():\n\t\t\terr := enc.Encode(ev)\n\t\t\tif err != nil {\n\t\t\t\tklog.Errorf(\"error encoding message %+v for result stream: %v\", ev, err)\n\t\t\t}\n\t\t\tflusher.Flush()\n\t\t}\n\t}\n}\n\nfunc getContainerInfoRequest(body io.ReadCloser) (*info.ContainerInfoRequest, error) {\n\tquery := info.DefaultContainerInfoRequest()\n\tdecoder := json.NewDecoder(body)\n\terr := decoder.Decode(&query)\n\tif err != nil && err != io.EOF {\n\t\treturn nil, fmt.Errorf(\"unable to decode the json value: %s\", err)\n\t}\n\n\treturn &query, nil\n}\n\n// The user can set any or none of the following arguments in any order\n// with any twice defined arguments being assigned the first value.\n// If the value type for the argument is wrong the field will be assumed to be\n// unassigned\n// bools: stream, subcontainers, oom_events, creation_events, deletion_events\n// ints: max_events, start_time (unix timestamp), end_time (unix timestamp)\n// example r.URL: http://localhost:8080/api/v1.3/events?oom_events=true&stream=true\nfunc getEventRequest(r *http.Request) (*events.Request, bool, error) {\n\tquery := events.NewRequest()\n\tstream := false\n\n\turlMap := r.URL.Query()\n\n\tif val, ok := urlMap[\"stream\"]; ok {\n\t\tnewBool, err := strconv.ParseBool(val[0])\n\t\tif err == nil {\n\t\t\tstream = newBool\n\t\t}\n\t}\n\tif val, ok := urlMap[\"subcontainers\"]; ok {\n\t\tnewBool, err := strconv.ParseBool(val[0])\n\t\tif err == nil {\n\t\t\tquery.IncludeSubcontainers = newBool\n\t\t}\n\t}\n\teventTypes := map[string]info.EventType{\n\t\t\"oom_events\":      info.EventOom,\n\t\t\"oom_kill_events\": info.EventOomKill,\n\t\t\"creation_events\": info.EventContainerCreation,\n\t\t\"deletion_events\": info.EventContainerDeletion,\n\t}\n\tallEventTypes := false\n\tif val, ok := urlMap[\"all_events\"]; ok {\n\t\tnewBool, err := strconv.ParseBool(val[0])\n\t\tif err == nil {\n\t\t\tallEventTypes = newBool\n\t\t}\n\t}\n\tfor opt, eventType := range eventTypes {\n\t\tif allEventTypes {\n\t\t\tquery.EventType[eventType] = true\n\t\t} else if val, ok := urlMap[opt]; ok {\n\t\t\tnewBool, err := strconv.ParseBool(val[0])\n\t\t\tif err == nil {\n\t\t\t\tquery.EventType[eventType] = newBool\n\t\t\t}\n\t\t}\n\t}\n\tif val, ok := urlMap[\"max_events\"]; ok {\n\t\tnewInt, err := strconv.Atoi(val[0])\n\t\tif err == nil {\n\t\t\tquery.MaxEventsReturned = int(newInt)\n\t\t}\n\t}\n\tif val, ok := urlMap[\"start_time\"]; ok {\n\t\tnewTime, err := time.Parse(time.RFC3339, val[0])\n\t\tif err == nil {\n\t\t\tquery.StartTime = newTime\n\t\t}\n\t}\n\tif val, ok := urlMap[\"end_time\"]; ok {\n\t\tnewTime, err := time.Parse(time.RFC3339, val[0])\n\t\tif err == nil {\n\t\t\tquery.EndTime = newTime\n\t\t}\n\t}\n\n\treturn query, stream, nil\n}\n\nfunc getContainerName(request []string) string {\n\treturn path.Join(\"/\", strings.Join(request, \"/\"))\n}\n"
  },
  {
    "path": "cmd/internal/api/versions.go",
    "content": "// Copyright 2015 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage api\n\nimport (\n\t\"fmt\"\n\t\"net/http\"\n\t\"path\"\n\t\"strconv\"\n\t\"time\"\n\n\tinfo \"github.com/google/cadvisor/info/v1\"\n\tv2 \"github.com/google/cadvisor/info/v2\"\n\t\"github.com/google/cadvisor/manager\"\n\n\t\"k8s.io/klog/v2\"\n)\n\nconst (\n\tcontainersAPI    = \"containers\"\n\tsubcontainersAPI = \"subcontainers\"\n\tmachineAPI       = \"machine\"\n\tmachineStatsAPI  = \"machinestats\"\n\tdockerAPI        = \"docker\"\n\tsummaryAPI       = \"summary\"\n\tstatsAPI         = \"stats\"\n\tspecAPI          = \"spec\"\n\teventsAPI        = \"events\"\n\tstorageAPI       = \"storage\"\n\tattributesAPI    = \"attributes\"\n\tversionAPI       = \"version\"\n\tpsAPI            = \"ps\"\n\tcustomMetricsAPI = \"appmetrics\"\n)\n\n// Interface for a cAdvisor API version\ntype ApiVersion interface {\n\t// Returns the version string.\n\tVersion() string\n\n\t// List of supported API endpoints.\n\tSupportedRequestTypes() []string\n\n\t// Handles a request. The second argument is the parameters after /api/<version>/<endpoint>\n\tHandleRequest(requestType string, request []string, m manager.Manager, w http.ResponseWriter, r *http.Request) error\n}\n\n// Gets all supported API versions.\nfunc getAPIVersions() []ApiVersion {\n\tv1_0 := &version1_0{}\n\tv1_1 := newVersion1_1(v1_0)\n\tv1_2 := newVersion1_2(v1_1)\n\tv1_3 := newVersion1_3(v1_2)\n\tv2_0 := newVersion2_0()\n\tv2_1 := newVersion2_1(v2_0)\n\n\treturn []ApiVersion{v1_0, v1_1, v1_2, v1_3, v2_0, v2_1}\n\n}\n\n// API v1.0\n\ntype version1_0 struct {\n}\n\nfunc (api *version1_0) Version() string {\n\treturn \"v1.0\"\n}\n\nfunc (api *version1_0) SupportedRequestTypes() []string {\n\treturn []string{containersAPI, machineAPI}\n}\n\nfunc (api *version1_0) HandleRequest(requestType string, request []string, m manager.Manager, w http.ResponseWriter, r *http.Request) error {\n\tswitch requestType {\n\tcase machineAPI:\n\t\tklog.V(4).Infof(\"Api - Machine\")\n\n\t\t// Get the MachineInfo\n\t\tmachineInfo, err := m.GetMachineInfo()\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\terr = writeResult(machineInfo, w)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\tcase containersAPI:\n\t\tcontainerName := getContainerName(request)\n\t\tklog.V(4).Infof(\"Api - Container(%s)\", containerName)\n\n\t\t// Get the query request.\n\t\tquery, err := getContainerInfoRequest(r.Body)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\t// Get the container.\n\t\tcont, err := m.GetContainerInfo(containerName, query)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"failed to get container %q with error: %s\", containerName, err)\n\t\t}\n\n\t\t// Only output the container as JSON.\n\t\terr = writeResult(cont, w)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\tdefault:\n\t\treturn fmt.Errorf(\"unknown request type %q\", requestType)\n\t}\n\treturn nil\n}\n\n// API v1.1\n\ntype version1_1 struct {\n\tbaseVersion *version1_0\n}\n\n// v1.1 builds on v1.0.\nfunc newVersion1_1(v *version1_0) *version1_1 {\n\treturn &version1_1{\n\t\tbaseVersion: v,\n\t}\n}\n\nfunc (api *version1_1) Version() string {\n\treturn \"v1.1\"\n}\n\nfunc (api *version1_1) SupportedRequestTypes() []string {\n\treturn append(api.baseVersion.SupportedRequestTypes(), subcontainersAPI)\n}\n\nfunc (api *version1_1) HandleRequest(requestType string, request []string, m manager.Manager, w http.ResponseWriter, r *http.Request) error {\n\tswitch requestType {\n\tcase subcontainersAPI:\n\t\tcontainerName := getContainerName(request)\n\t\tklog.V(4).Infof(\"Api - Subcontainers(%s)\", containerName)\n\n\t\t// Get the query request.\n\t\tquery, err := getContainerInfoRequest(r.Body)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\t// Get the subcontainers.\n\t\tcontainers, err := m.SubcontainersInfo(containerName, query)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"failed to get subcontainers for container %q with error: %s\", containerName, err)\n\t\t}\n\n\t\t// Only output the containers as JSON.\n\t\terr = writeResult(containers, w)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\treturn nil\n\tdefault:\n\t\treturn api.baseVersion.HandleRequest(requestType, request, m, w, r)\n\t}\n}\n\n// API v1.2\n\ntype version1_2 struct {\n\tbaseVersion *version1_1\n}\n\n// v1.2 builds on v1.1.\nfunc newVersion1_2(v *version1_1) *version1_2 {\n\treturn &version1_2{\n\t\tbaseVersion: v,\n\t}\n}\n\nfunc (api *version1_2) Version() string {\n\treturn \"v1.2\"\n}\n\nfunc (api *version1_2) SupportedRequestTypes() []string {\n\treturn append(api.baseVersion.SupportedRequestTypes(), dockerAPI)\n}\n\nfunc (api *version1_2) HandleRequest(requestType string, request []string, m manager.Manager, w http.ResponseWriter, r *http.Request) error {\n\tswitch requestType {\n\tcase dockerAPI:\n\t\tklog.V(4).Infof(\"Api - Docker(%v)\", request)\n\n\t\t// Get the query request.\n\t\tquery, err := getContainerInfoRequest(r.Body)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\tvar containers map[string]info.ContainerInfo\n\t\t// map requests for \"docker/\" to \"docker\"\n\t\tif len(request) == 1 && len(request[0]) == 0 {\n\t\t\trequest = request[:0]\n\t\t}\n\t\tswitch len(request) {\n\t\tcase 0:\n\t\t\t// Get all Docker containers.\n\t\t\tcontainers, err = m.AllDockerContainers(query)\n\t\t\tif err != nil {\n\t\t\t\treturn fmt.Errorf(\"failed to get all Docker containers with error: %v\", err)\n\t\t\t}\n\t\tcase 1:\n\t\t\t// Get one Docker container.\n\t\t\tvar cont info.ContainerInfo\n\t\t\tcont, err = m.DockerContainer(request[0], query)\n\t\t\tif err != nil {\n\t\t\t\treturn fmt.Errorf(\"failed to get Docker container %q with error: %v\", request[0], err)\n\t\t\t}\n\t\t\tcontainers = map[string]info.ContainerInfo{\n\t\t\t\tcont.Name: cont,\n\t\t\t}\n\t\tdefault:\n\t\t\treturn fmt.Errorf(\"unknown request for Docker container %v\", request)\n\t\t}\n\n\t\t// Only output the containers as JSON.\n\t\terr = writeResult(containers, w)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\treturn nil\n\tdefault:\n\t\treturn api.baseVersion.HandleRequest(requestType, request, m, w, r)\n\t}\n}\n\n// API v1.3\n\ntype version1_3 struct {\n\tbaseVersion *version1_2\n}\n\n// v1.3 builds on v1.2.\nfunc newVersion1_3(v *version1_2) *version1_3 {\n\treturn &version1_3{\n\t\tbaseVersion: v,\n\t}\n}\n\nfunc (api *version1_3) Version() string {\n\treturn \"v1.3\"\n}\n\nfunc (api *version1_3) SupportedRequestTypes() []string {\n\treturn append(api.baseVersion.SupportedRequestTypes(), eventsAPI)\n}\n\nfunc (api *version1_3) HandleRequest(requestType string, request []string, m manager.Manager, w http.ResponseWriter, r *http.Request) error {\n\tswitch requestType {\n\tcase eventsAPI:\n\t\treturn handleEventRequest(request, m, w, r)\n\tdefault:\n\t\treturn api.baseVersion.HandleRequest(requestType, request, m, w, r)\n\t}\n}\n\nfunc handleEventRequest(request []string, m manager.Manager, w http.ResponseWriter, r *http.Request) error {\n\tquery, stream, err := getEventRequest(r)\n\tif err != nil {\n\t\treturn err\n\t}\n\tquery.ContainerName = path.Join(\"/\", getContainerName(request))\n\tklog.V(4).Infof(\"Api - Events(%v)\", query)\n\tif !stream {\n\t\tpastEvents, err := m.GetPastEvents(query)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\treturn writeResult(pastEvents, w)\n\t}\n\teventChannel, err := m.WatchForEvents(query)\n\tif err != nil {\n\t\treturn err\n\t}\n\treturn streamResults(eventChannel, w, r, m)\n\n}\n\n// API v2.0\n\ntype version2_0 struct {\n}\n\nfunc newVersion2_0() *version2_0 {\n\treturn &version2_0{}\n}\n\nfunc (api *version2_0) Version() string {\n\treturn \"v2.0\"\n}\n\nfunc (api *version2_0) SupportedRequestTypes() []string {\n\treturn []string{versionAPI, attributesAPI, eventsAPI, machineAPI, summaryAPI, statsAPI, specAPI, storageAPI, psAPI, customMetricsAPI}\n}\n\nfunc (api *version2_0) HandleRequest(requestType string, request []string, m manager.Manager, w http.ResponseWriter, r *http.Request) error {\n\topt, err := GetRequestOptions(r)\n\tif err != nil {\n\t\treturn err\n\t}\n\tswitch requestType {\n\tcase versionAPI:\n\t\tklog.V(4).Infof(\"Api - Version\")\n\t\tversionInfo, err := m.GetVersionInfo()\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\treturn writeResult(versionInfo.CadvisorVersion, w)\n\tcase attributesAPI:\n\t\tklog.V(4).Info(\"Api - Attributes\")\n\n\t\tmachineInfo, err := m.GetMachineInfo()\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tversionInfo, err := m.GetVersionInfo()\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tinfo := v2.GetAttributes(machineInfo, versionInfo)\n\t\treturn writeResult(info, w)\n\tcase machineAPI:\n\t\tklog.V(4).Info(\"Api - Machine\")\n\n\t\t// TODO(rjnagal): Move machineInfo from v1.\n\t\tmachineInfo, err := m.GetMachineInfo()\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\treturn writeResult(machineInfo, w)\n\tcase summaryAPI:\n\t\tcontainerName := getContainerName(request)\n\t\tklog.V(4).Infof(\"Api - Summary for container %q, options %+v\", containerName, opt)\n\n\t\tstats, err := m.GetDerivedStats(containerName, opt)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\treturn writeResult(stats, w)\n\tcase statsAPI:\n\t\tname := getContainerName(request)\n\t\tklog.V(4).Infof(\"Api - Stats: Looking for stats for container %q, options %+v\", name, opt)\n\t\tinfos, err := m.GetRequestedContainersInfo(name, opt)\n\t\tif err != nil {\n\t\t\tif len(infos) == 0 {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tklog.Errorf(\"Error calling GetRequestedContainersInfo: %v\", err)\n\t\t}\n\t\tcontStats := make(map[string][]v2.DeprecatedContainerStats)\n\t\tfor name, cinfo := range infos {\n\t\t\tcontStats[name] = v2.DeprecatedStatsFromV1(cinfo)\n\t\t}\n\t\treturn writeResult(contStats, w)\n\tcase customMetricsAPI:\n\t\tcontainerName := getContainerName(request)\n\t\tklog.V(4).Infof(\"Api - Custom Metrics: Looking for metrics for container %q, options %+v\", containerName, opt)\n\t\tinfos, err := m.GetContainerInfoV2(containerName, opt)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tcontMetrics := make(map[string]map[string]map[string][]info.MetricValBasic)\n\t\tfor _, cinfo := range infos {\n\t\t\tmetrics := make(map[string]map[string][]info.MetricValBasic)\n\t\t\tfor _, contStat := range cinfo.Stats {\n\t\t\t\tif len(contStat.CustomMetrics) == 0 {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tfor name, allLabels := range contStat.CustomMetrics {\n\t\t\t\t\tmetricLabels := make(map[string][]info.MetricValBasic)\n\t\t\t\t\tfor _, metric := range allLabels {\n\t\t\t\t\t\tif !metric.Timestamp.IsZero() {\n\t\t\t\t\t\t\tmetVal := info.MetricValBasic{\n\t\t\t\t\t\t\t\tTimestamp:  metric.Timestamp,\n\t\t\t\t\t\t\t\tIntValue:   metric.IntValue,\n\t\t\t\t\t\t\t\tFloatValue: metric.FloatValue,\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tlabels := metrics[name]\n\t\t\t\t\t\t\tif labels != nil {\n\t\t\t\t\t\t\t\tvalues := labels[metric.Label]\n\t\t\t\t\t\t\t\tvalues = append(values, metVal)\n\t\t\t\t\t\t\t\tlabels[metric.Label] = values\n\t\t\t\t\t\t\t\tmetrics[name] = labels\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tmetricLabels[metric.Label] = []info.MetricValBasic{metVal}\n\t\t\t\t\t\t\t\tmetrics[name] = metricLabels\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tcontMetrics[containerName] = metrics\n\t\t}\n\t\treturn writeResult(contMetrics, w)\n\tcase specAPI:\n\t\tcontainerName := getContainerName(request)\n\t\tklog.V(4).Infof(\"Api - Spec for container %q, options %+v\", containerName, opt)\n\t\tspecs, err := m.GetContainerSpec(containerName, opt)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\treturn writeResult(specs, w)\n\tcase storageAPI:\n\t\tlabel := r.URL.Query().Get(\"label\")\n\t\tuuid := r.URL.Query().Get(\"uuid\")\n\t\tswitch {\n\t\tcase uuid != \"\":\n\t\t\tfi, err := m.GetFsInfoByFsUUID(uuid)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\treturn writeResult(fi, w)\n\t\tcase label != \"\":\n\t\t\t// Get a specific label.\n\t\t\tfi, err := m.GetFsInfo(label)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\treturn writeResult(fi, w)\n\t\tdefault:\n\t\t\t// Get all global filesystems info.\n\t\t\tfi, err := m.GetFsInfo(\"\")\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\treturn writeResult(fi, w)\n\t\t}\n\tcase eventsAPI:\n\t\treturn handleEventRequest(request, m, w, r)\n\tcase psAPI:\n\t\t// reuse container type from request.\n\t\t// ignore recursive.\n\t\t// TODO(rjnagal): consider count to limit ps output.\n\t\tname := getContainerName(request)\n\t\tklog.V(4).Infof(\"Api - Spec for container %q, options %+v\", name, opt)\n\t\tps, err := m.GetProcessList(name, opt)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"process listing failed: %v\", err)\n\t\t}\n\t\treturn writeResult(ps, w)\n\tdefault:\n\t\treturn fmt.Errorf(\"unknown request type %q\", requestType)\n\t}\n}\n\ntype version2_1 struct {\n\tbaseVersion *version2_0\n}\n\nfunc newVersion2_1(v *version2_0) *version2_1 {\n\treturn &version2_1{\n\t\tbaseVersion: v,\n\t}\n}\n\nfunc (api *version2_1) Version() string {\n\treturn \"v2.1\"\n}\n\nfunc (api *version2_1) SupportedRequestTypes() []string {\n\treturn append([]string{machineStatsAPI}, api.baseVersion.SupportedRequestTypes()...)\n}\n\nfunc (api *version2_1) HandleRequest(requestType string, request []string, m manager.Manager, w http.ResponseWriter, r *http.Request) error {\n\t// Get the query request.\n\topt, err := GetRequestOptions(r)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tswitch requestType {\n\tcase machineStatsAPI:\n\t\tklog.V(4).Infof(\"Api - MachineStats(%v)\", request)\n\t\tcont, err := m.GetRequestedContainersInfo(\"/\", opt)\n\t\tif err != nil {\n\t\t\tif len(cont) == 0 {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tklog.Errorf(\"Error calling GetRequestedContainersInfo: %v\", err)\n\t\t}\n\t\treturn writeResult(v2.MachineStatsFromV1(cont[\"/\"]), w)\n\tcase statsAPI:\n\t\tname := getContainerName(request)\n\t\tklog.V(4).Infof(\"Api - Stats: Looking for stats for container %q, options %+v\", name, opt)\n\t\tconts, err := m.GetRequestedContainersInfo(name, opt)\n\t\tif err != nil {\n\t\t\tif len(conts) == 0 {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tklog.Errorf(\"Error calling GetRequestedContainersInfo: %v\", err)\n\t\t}\n\t\tcontStats := make(map[string]v2.ContainerInfo, len(conts))\n\t\tfor name, cont := range conts {\n\t\t\tif name == \"/\" {\n\t\t\t\t// Root cgroup stats should be exposed as machine stats\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tcontStats[name] = v2.ContainerInfo{\n\t\t\t\tSpec:  v2.ContainerSpecFromV1(&cont.Spec, cont.Aliases, cont.Namespace),\n\t\t\t\tStats: v2.ContainerStatsFromV1(name, &cont.Spec, cont.Stats),\n\t\t\t}\n\t\t}\n\t\treturn writeResult(contStats, w)\n\tdefault:\n\t\treturn api.baseVersion.HandleRequest(requestType, request, m, w, r)\n\t}\n}\n\n// GetRequestOptions returns the metrics request options from a HTTP request.\nfunc GetRequestOptions(r *http.Request) (v2.RequestOptions, error) {\n\tsupportedTypes := map[string]bool{\n\t\tv2.TypeName:   true,\n\t\tv2.TypeDocker: true,\n\t\tv2.TypePodman: true,\n\t}\n\t// fill in the defaults.\n\topt := v2.RequestOptions{\n\t\tIdType:    v2.TypeName,\n\t\tCount:     64,\n\t\tRecursive: false,\n\t}\n\tidType := r.URL.Query().Get(\"type\")\n\tif len(idType) != 0 {\n\t\tif !supportedTypes[idType] {\n\t\t\treturn opt, fmt.Errorf(\"unknown 'type' %q\", idType)\n\t\t}\n\t\topt.IdType = idType\n\t}\n\tcount := r.URL.Query().Get(\"count\")\n\tif len(count) != 0 {\n\t\tn, err := strconv.Atoi(count)\n\t\tif err != nil {\n\t\t\treturn opt, fmt.Errorf(\"failed to parse 'count' option: %v\", count)\n\t\t}\n\t\tif n < -1 {\n\t\t\treturn opt, fmt.Errorf(\"invalid 'count' option: only -1 and larger values allowed, not %d\", n)\n\t\t}\n\t\topt.Count = n\n\t}\n\trecursive := r.URL.Query().Get(\"recursive\")\n\tif recursive == \"true\" {\n\t\topt.Recursive = true\n\t}\n\tif maxAgeString := r.URL.Query().Get(\"max_age\"); len(maxAgeString) > 0 {\n\t\tmaxAge, err := time.ParseDuration(maxAgeString)\n\t\tif err != nil {\n\t\t\treturn opt, fmt.Errorf(\"failed to parse 'max_age' option: %v\", err)\n\t\t}\n\t\topt.MaxAge = &maxAge\n\t}\n\treturn opt, nil\n}\n"
  },
  {
    "path": "cmd/internal/api/versions_test.go",
    "content": "// Copyright 2015 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage api\n\nimport (\n\t\"io\"\n\t\"net/http\"\n\t\"reflect\"\n\t\"testing\"\n\n\t\"github.com/google/cadvisor/events\"\n\tinfo \"github.com/google/cadvisor/info/v1\"\n\n\t\"github.com/stretchr/testify/assert\"\n)\n\n// returns an http.Request pointer for an input url test string\nfunc makeHTTPRequest(requestURL string, t *testing.T) *http.Request {\n\tdummyReader, _ := io.Pipe()\n\tr, err := http.NewRequest(\"GET\", requestURL, dummyReader)\n\tassert.Nil(t, err)\n\treturn r\n}\n\nfunc TestGetEventRequestBasicRequest(t *testing.T) {\n\tr := makeHTTPRequest(\"http://localhost:8080/api/v1.3/events?oom_events=true&stream=false&max_events=20\", t)\n\texpectedQuery := events.NewRequest()\n\texpectedQuery.EventType = map[info.EventType]bool{\n\t\tinfo.EventOom: true,\n\t}\n\texpectedQuery.MaxEventsReturned = 20\n\n\treceivedQuery, stream, err := getEventRequest(r)\n\n\tif !reflect.DeepEqual(expectedQuery, receivedQuery) {\n\t\tt.Errorf(\"expected %#v but received %#v\", expectedQuery, receivedQuery)\n\t}\n\tassert.False(t, stream)\n\tassert.Nil(t, err)\n}\n\nfunc TestGetEventEmptyRequest(t *testing.T) {\n\tr := makeHTTPRequest(\"\", t)\n\texpectedQuery := events.NewRequest()\n\n\treceivedQuery, stream, err := getEventRequest(r)\n\n\tif !reflect.DeepEqual(expectedQuery, receivedQuery) {\n\t\tt.Errorf(\"expected %#v but received %#v\", expectedQuery, receivedQuery)\n\t}\n\tassert.False(t, stream)\n\tassert.Nil(t, err)\n}\n\nfunc TestGetEventRequestDoubleArgument(t *testing.T) {\n\tr := makeHTTPRequest(\"http://localhost:8080/api/v1.3/events?stream=true&oom_events=true&oom_events=false\", t)\n\texpectedQuery := events.NewRequest()\n\texpectedQuery.EventType = map[info.EventType]bool{\n\t\tinfo.EventOom: true,\n\t}\n\n\treceivedQuery, stream, err := getEventRequest(r)\n\n\tif !reflect.DeepEqual(expectedQuery, receivedQuery) {\n\t\tt.Errorf(\"expected %#v but received %#v\", expectedQuery, receivedQuery)\n\t}\n\tassert.True(t, stream)\n\tassert.Nil(t, err)\n}\n"
  },
  {
    "path": "cmd/internal/container/install/install.go",
    "content": "// Copyright 2019 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n// The install package registers all included container providers when imported\npackage install\n\nimport (\n\t// Register all included container providers.\n\t_ \"github.com/google/cadvisor/container/containerd/install\"\n\t_ \"github.com/google/cadvisor/container/crio/install\"\n\t_ \"github.com/google/cadvisor/container/docker/install\"\n\t_ \"github.com/google/cadvisor/container/podman/install\"\n\t_ \"github.com/google/cadvisor/container/systemd/install\"\n\n\t// Register all filesystem plugins.\n\t_ \"github.com/google/cadvisor/fs/btrfs/install\"\n\t_ \"github.com/google/cadvisor/fs/devicemapper/install\"\n\t_ \"github.com/google/cadvisor/fs/nfs/install\"\n\t_ \"github.com/google/cadvisor/fs/overlay/install\"\n\t_ \"github.com/google/cadvisor/fs/tmpfs/install\"\n\t_ \"github.com/google/cadvisor/fs/vfs/install\"\n\t_ \"github.com/google/cadvisor/fs/zfs/install\"\n)\n"
  },
  {
    "path": "cmd/internal/healthz/healthz.go",
    "content": "// Copyright 2014 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage healthz\n\nimport (\n\t\"net/http\"\n\n\thttpmux \"github.com/google/cadvisor/cmd/internal/http/mux\"\n)\n\nfunc handleHealthz(w http.ResponseWriter, r *http.Request) {\n\tw.WriteHeader(http.StatusOK)\n\t_, _ = w.Write([]byte(\"ok\"))\n}\n\n// Register simple HTTP /healthz handler to return \"ok\".\nfunc RegisterHandler(mux httpmux.Mux) error {\n\tmux.HandleFunc(\"/healthz\", handleHealthz)\n\treturn nil\n}\n"
  },
  {
    "path": "cmd/internal/http/handlers.go",
    "content": "// Copyright 2015 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage http\n\nimport (\n\t\"fmt\"\n\t\"net/http\"\n\n\t\"github.com/google/cadvisor/cmd/internal/api\"\n\t\"github.com/google/cadvisor/cmd/internal/healthz\"\n\thttpmux \"github.com/google/cadvisor/cmd/internal/http/mux\"\n\t\"github.com/google/cadvisor/cmd/internal/pages\"\n\t\"github.com/google/cadvisor/cmd/internal/pages/static\"\n\t\"github.com/google/cadvisor/container\"\n\t\"github.com/google/cadvisor/manager\"\n\t\"github.com/google/cadvisor/metrics\"\n\t\"github.com/google/cadvisor/validate\"\n\n\tauth \"github.com/abbot/go-http-auth\"\n\t\"github.com/prometheus/client_golang/prometheus\"\n\t\"github.com/prometheus/client_golang/prometheus/collectors\"\n\n\t\"github.com/prometheus/client_golang/prometheus/promhttp\"\n\t\"k8s.io/klog/v2\"\n\t\"k8s.io/utils/clock\"\n)\n\nfunc RegisterHandlers(mux httpmux.Mux, containerManager manager.Manager, httpAuthFile, httpAuthRealm, httpDigestFile, httpDigestRealm string, urlBasePrefix string) error {\n\t// Basic health handler.\n\tif err := healthz.RegisterHandler(mux); err != nil {\n\t\treturn fmt.Errorf(\"failed to register healthz handler: %s\", err)\n\t}\n\n\t// Validation/Debug handler.\n\tmux.HandleFunc(validate.ValidatePage, func(w http.ResponseWriter, r *http.Request) {\n\t\terr := validate.HandleRequest(w, containerManager)\n\t\tif err != nil {\n\t\t\thttp.Error(w, err.Error(), http.StatusInternalServerError)\n\t\t}\n\t})\n\n\t// Register API handler.\n\tif err := api.RegisterHandlers(mux, containerManager); err != nil {\n\t\treturn fmt.Errorf(\"failed to register API handlers: %s\", err)\n\t}\n\n\t// Redirect / to containers page.\n\tmux.Handle(\"/\", http.RedirectHandler(urlBasePrefix+pages.ContainersPage, http.StatusTemporaryRedirect))\n\n\tvar authenticated bool\n\n\t// Setup the authenticator object\n\tif httpAuthFile != \"\" {\n\t\tklog.V(1).Infof(\"Using auth file %s\", httpAuthFile)\n\t\tsecrets := auth.HtpasswdFileProvider(httpAuthFile)\n\t\tauthenticator := auth.NewBasicAuthenticator(httpAuthRealm, secrets)\n\t\tmux.HandleFunc(static.StaticResource, authenticator.Wrap(staticHandler))\n\t\tif err := pages.RegisterHandlersBasic(mux, containerManager, authenticator, urlBasePrefix); err != nil {\n\t\t\treturn fmt.Errorf(\"failed to register pages auth handlers: %s\", err)\n\t\t}\n\t\tauthenticated = true\n\t}\n\tif httpAuthFile == \"\" && httpDigestFile != \"\" {\n\t\tklog.V(1).Infof(\"Using digest file %s\", httpDigestFile)\n\t\tsecrets := auth.HtdigestFileProvider(httpDigestFile)\n\t\tauthenticator := auth.NewDigestAuthenticator(httpDigestRealm, secrets)\n\t\tmux.HandleFunc(static.StaticResource, authenticator.Wrap(staticHandler))\n\t\tif err := pages.RegisterHandlersDigest(mux, containerManager, authenticator, urlBasePrefix); err != nil {\n\t\t\treturn fmt.Errorf(\"failed to register pages digest handlers: %s\", err)\n\t\t}\n\t\tauthenticated = true\n\t}\n\n\t// Change handler based on authenticator initialization\n\tif !authenticated {\n\t\tmux.HandleFunc(static.StaticResource, staticHandlerNoAuth)\n\t\tif err := pages.RegisterHandlersBasic(mux, containerManager, nil, urlBasePrefix); err != nil {\n\t\t\treturn fmt.Errorf(\"failed to register pages handlers: %s\", err)\n\t\t}\n\t}\n\n\treturn nil\n}\n\n// RegisterPrometheusHandler creates a new PrometheusCollector and configures\n// the provided HTTP mux to handle the given Prometheus endpoint.\nfunc RegisterPrometheusHandler(mux httpmux.Mux, resourceManager manager.Manager, prometheusEndpoint string,\n\tf metrics.ContainerLabelsFunc, includedMetrics container.MetricSet) {\n\tgoCollector := collectors.NewGoCollector()\n\tprocessCollector := collectors.NewProcessCollector(collectors.ProcessCollectorOpts{})\n\tmachineCollector := metrics.NewPrometheusMachineCollector(resourceManager, includedMetrics)\n\n\tmux.Handle(prometheusEndpoint, http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {\n\t\topts, err := api.GetRequestOptions(req)\n\t\tif err != nil {\n\t\t\thttp.Error(w, \"No metrics gathered, last error:\\n\\n\"+err.Error(), http.StatusInternalServerError)\n\t\t\treturn\n\t\t}\n\t\topts.Count = 1        // we only want the latest datapoint\n\t\topts.Recursive = true // get all child containers\n\n\t\tr := prometheus.NewRegistry()\n\t\tr.MustRegister(\n\t\t\tmetrics.NewPrometheusCollector(resourceManager, f, includedMetrics, clock.RealClock{}, opts),\n\t\t\tmachineCollector,\n\t\t\tgoCollector,\n\t\t\tprocessCollector,\n\t\t)\n\t\tpromhttp.HandlerFor(r, promhttp.HandlerOpts{ErrorHandling: promhttp.ContinueOnError}).ServeHTTP(w, req)\n\t}))\n}\n\nfunc staticHandlerNoAuth(w http.ResponseWriter, r *http.Request) {\n\tstatic.HandleRequest(w, r.URL)\n}\n\nfunc staticHandler(w http.ResponseWriter, r *auth.AuthenticatedRequest) {\n\tstatic.HandleRequest(w, r.URL)\n}\n"
  },
  {
    "path": "cmd/internal/http/mux/mux.go",
    "content": "// Copyright 2015 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage mux\n\nimport (\n\t\"net/http\"\n)\n\n// Mux interface expected by cAdvisor components.\ntype Mux interface {\n\tHandleFunc(pattern string, handler func(http.ResponseWriter, *http.Request))\n\tHandler(r *http.Request) (http.Handler, string)\n\tHandle(pattern string, handler http.Handler)\n}\n"
  },
  {
    "path": "cmd/internal/pages/assets/html/containers.html",
    "content": "<!--\n  Copyright 2014 Google Inc. All Rights Reserved.\n\n  Licensed under the Apache License, Version 2.0 (the \"License\");\n  you may not use this file except in compliance with the License.\n  You may obtain a copy of the License at\n\n      http://www.apache.org/licenses/LICENSE-2.0\n\n  Unless required by applicable law or agreed to in writing, software\n  distributed under the License is distributed on an \"AS IS\" BASIS,\n  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  See the License for the specific language governing permissions and\n  limitations under the License.\n-->\n\n<html>\n  <head>\n    <title>cAdvisor - {{.DisplayName}}</title>\n    <script src=\"{{.Root}}static/popper.min.js\"></script>\n    <!-- Latest compiled and minified CSS -->\n    <link rel=\"stylesheet\" href=\"{{.Root}}static/bootstrap-4.0.0-beta.2.min.css\">\n\n    <!-- Optional theme -->\n    <link rel=\"stylesheet\" href=\"{{.Root}}static/bootstrap-theme-3.1.1.min.css\">\n\n    <link rel=\"stylesheet\" href=\"{{.Root}}static/containers.css\">\n\n    <!-- Latest compiled and minified JavaScript -->\n    <script src=\"{{.Root}}static/jquery-3.5.1.min.js\"></script>\n    <script src=\"{{.Root}}static/bootstrap-4.0.0-beta.2.min.js\"></script>\n      <script type=\"text/javascript\" src=\"{{.Root}}static/loader.js\"></script>\n    <script type=\"text/javascript\" src=\"{{.Root}}static/containers.js\"></script>\n  </head>\n  <body>\n    <div class=\"container theme-showcase\" >\n      <a href=\"{{.Root}}\" class=\"col-sm-12\" id=\"logo\">\n      </a>\n      <div class=\"col-sm-12\">\n\t<div class=\"page-header\">\n\t  <h1>{{.DisplayName}}</h1>\n\t</div>\n\t<ol class=\"breadcrumb\">\n\t  {{range $parentContainer := .ParentContainers}}\n\t  <li><a href=\"{{$parentContainer.Link}}\">{{$parentContainer.Text}}</a></li>\n\t  {{end}}\n\t</ol>\n      </div>\n      {{if .IsRoot}}\n      <div class=\"col-sm-12\">\n        <h4><a href=\"../docker\">Docker Containers</a></h4>\n      </div>\n      <div class=\"col-sm-12\">\n          <h4><a href=\"../podman\">Podman Containers</a></h4>\n      </div>\n      {{end}}\n      {{if .Subcontainers}}\n      <div class=\"col-sm-12\">\n\t<div class=\"page-header\">\n\t  <h3>Subcontainers</h3>\n\t</div>\n\t<div class=\"list-group\">\n\t  {{range $subcontainer := .Subcontainers}}\n\t  <a href=\"{{$subcontainer.Link}}\" class=\"list-group-item\">{{$subcontainer.Text}}</a>\n\t  {{end}}\n\t</div>\n      </div>\n      {{end}}\n     {{if .DockerStatus}}\n      <div class=\"col-sm-12\">\n\t<div class=\"page-header\">\n\t  <h3>Driver Status</h3>\n\t</div>\n\t<ul class=\"list-group\">\n\t  {{range $dockerstatus := .DockerStatus}}\n\t  <li class =\"list-group-item\"><span class=\"stat-label\">{{$dockerstatus.Key}}</span> {{$dockerstatus.Value}}</li>\n\t  {{end}}\n\t  {{if .DockerDriverStatus}}\n\t\t<li class =\"list-group-item\"><span class=\"stat-label\">Storage<br></span>\n\t\t<ul class=\"list-group\">\n\t\t{{range $driverstatus := .DockerDriverStatus}}\n\t\t<li class=\"list-group-item\"><span class=\"stat-label\">{{$driverstatus.Key}}</span> {{$driverstatus.Value}}</li>\n\t\t{{end}}\n\t\t</ul>\n\t\t</li>\n\t  </ul>\n\t  {{end}}\n\t</div>\n      {{end}}\n      {{if .DockerImages}}\n      <div class=\"col-sm-12\">\n          <div class=\"page-header\">\n            <h3>Images</h3>\n          </div>\n       <div id=\"docker-images\"></div>\n       <br><br>\n       </div>\n      {{end}}\n      {{if .ResourcesAvailable}}\n      <div class=\"col-sm-12\">\n\t<div class=\"page-header\">\n\t  <h3>Isolation</h3>\n\t</div>\n\t{{if .CpuAvailable}}\n\t<ul class=\"list-group\">\n          <li class=\"list-group-item active isolation-title panel-title\">CPU</li>\n          {{if .Spec.Cpu.Limit}}\n          <li class=\"list-group-item\"><span class=\"stat-label\">Shares</span> {{printShares .Spec.Cpu.Limit}} <span class=\"unit-label\">shares</span></li>\n          {{end}}\n          {{if .Spec.Cpu.MaxLimit}}\n          <li class=\"list-group-item\"><span class=\"stat-label\">Max Limit</span> {{printCores .Spec.Cpu.MaxLimit}} <span class=\"unit-label\">cores</span></li>\n          {{end}}\n          {{if .Spec.Cpu.Mask}}\n          <li class=\"list-group-item\"><span class=\"stat-label\">Allowed Cores</span> {{printMask .Spec.Cpu.Mask .MachineInfo.NumCores}}</li>\n          {{end}}\n\t</ul>\n\t{{end}}\n\t{{if .MemoryAvailable}}\n\t<ul class=\"list-group\">\n          <li class=\"list-group-item active isolation-title panel-title\">Memory</li>\n          {{if .Spec.Memory.Reservation}}\n          <li class=\"list-group-item\"><span class=\"stat-label\">Reservation</span> {{printSize .Spec.Memory.Reservation}} <span class=\"unit-label\">{{printUnit .Spec.Memory.Reservation}}</span></li>\n          {{end}}\n          {{if .Spec.Memory.Limit}}\n          <li class=\"list-group-item\"><span class=\"stat-label\">Limit</span> {{printSize .Spec.Memory.Limit}} <span class=\"unit-label\">{{printUnit .Spec.Memory.Limit}}</span></li>\n          {{end}}\n          {{if .Spec.Memory.SwapLimit}}\n          <li class=\"list-group-item\"><span class=\"stat-label\">Swap Limit</span> {{printSize .Spec.Memory.SwapLimit}} <span class=\"unit-label\">{{printUnit .Spec.Memory.SwapLimit}}</span></li>\n          {{end}}\n\t</ul>\n\t{{end}}\n      </div>\n      <div class=\"col-sm-12\">\n\t<div class=\"page-header\">\n\t  <h3>Usage</h3>\n\t</div>\n\t<div class=\"panel panel-primary\">\n          <div class=\"panel-heading\">\n            <h3 class=\"panel-title\">Overview</h3>\n          </div>\n          <div id=\"usage-gauge\" class=\"panel-body\"></div>\n\t</div>\n\t<div class=\"panel panel-primary\">\n          <div class=\"panel-heading\">\n            <h3 class=\"panel-title\">Processes</h3>\n          </div>\n          <div id=\"processes-top\" class=\"panel-body\"></div>\n\t</div>\n\t{{if .CpuAvailable}}\n\t<div class=\"panel panel-primary\">\n          <div class=\"panel-heading\">\n            <h3 class=\"panel-title\">CPU</h3>\n          </div>\n          <div class=\"panel-body\">\n            <h4>Total Usage</h4>\n\t    <div id=\"cpu-total-usage-chart\"></div>\n\t    <!-- <h4>CPU Load Average</h4>\n\t    <div id=\"cpu-load-chart\"></div> -->\n            <h4>Usage per Core</h4>\n\t    <div id=\"cpu-per-core-usage-chart\"></div>\n            <h4>Usage Breakdown</h4>\n\t    <div id=\"cpu-usage-breakdown-chart\"></div>\n          </div>\n\t</div>\n\t{{end}}\n\t{{if .MemoryAvailable}}\n\t<div class=\"panel panel-primary\">\n          <div class=\"panel-heading\">\n            <h3 class=\"panel-title\">Memory</h3>\n          </div>\n          <div class=\"panel-body\">\n            <h4>Total Usage</h4>\n\t    <div id=\"memory-usage-chart\"></div>\n            <br/>\n            <div class=\"row col-sm-12\">\n              <h4>Usage Breakdown</h4>\n              <div class=\"col-sm-9\">\n\t\t<div class=\"progress\">\n                  <div class=\"progress-bar progress-bar-danger\" id=\"progress-hot-memory\">\n                    <span class=\"sr-only\">Hot Memory</span>\n                  </div>\n                  <div class=\"progress-bar progress-bar-info\" id=\"progress-cold-memory\">\n                    <span class=\"sr-only\">Cold Memory</span>\n                  </div>\n\t\t</div>\n              </div>\n              <div class=\"col-sm-3\" id=\"memory-text\"></div>\n\t    </div>\n          </div>\n\t</div>\n\t{{end}}\n\t{{if .NetworkAvailable}}\n\t<div class=\"panel panel-primary\">\n\t  <div class=\"panel-heading\">\n            <h3 class=\"panel-title\">Network</h3>\n\t  </div>\n          <div class=\"panel-body\">\n\t    <div class=\"dropdown\">\n              <button class=\"btn btn-default dropdown-toggle\" type=\"button\" id=\"network-selection-dropdown\" data-toggle=\"dropdown\" aria-haspopup=\"true\" aria-expanded=\"false\">\n                <span id=\"network-selection-text\"></span>\n                <span class=\"caret\"></span>\n\t      </button>\n              <ul id=\"network-selection\" class=\"dropdown-menu\" role=\"menu\" aria-labelledby=\"network-selection-dropdown\">\n              </ul>\n\t    </div>\n          </div>\n\t  <div class=\"panel-body\">\n            <h4>Throughput</h4>\n            <div id=\"network-bytes-chart\"></div>\n\t  </div>\n\t  <div class=\"panel-body\">\n            <h4>Errors</h4>\n\t    <div id=\"network-errors-chart\"></div>\n\t  </div>\n\t</div>\n        {{end}}\n\t{{if .FsAvailable}}\n\t<div class=\"panel panel-primary\">\n          <div class=\"panel-heading\">\n            <h3 class=\"panel-title\">Filesystem</h3>\n          </div>\n          <div id=\"filesystem-usage\" class=\"panel-body\">\n          </div>\n        </div>\n\t{{end}}\n\t{{if .CustomMetricsAvailable}}\n\t<div class=\"panel panel-primary\">\n\t  <div class=\"panel-heading\">\n\t    <h3 class=\"panel-title\">Application Metrics</h3>\n\t  </div>\n\t  <div class=\"panel-body\">\n\t    <div id=\"custom-metrics-chart\"></div>\n\t  </div>\n\t</div>\n\t{{end}}\n        {{if .SubcontainersAvailable}}\n\t<div class=\"panel panel-primary\">\n          <div class=\"panel-heading\">\n            <h3 class=\"panel-title\">Subcontainers</h3>\n          </div>\n          <div class=\"panel-body\">\n            <h4>Top CPU Usage:\n              <input id=\"cpu-per-subcontainer-display-count\"\n                     class=\"subcontainer-display-input\"\n                     value=10>\n            </h4>\n            <div id=\"cpu-per-subcontainer-usage-chart\">\n            </div>\n          </div>\n          <div class=\"panel-body\">\n            <h4>Top Memory Usage:\n              <input id=\"memory-per-subcontainer-display-count\"\n                     class=\"subcontainer-display-input\"\n                     value=10>\n            </h4>\n            <span class=\"subcontroller-display-block\"/>\n            <div id=\"memory-per-subcontainer-usage-chart\">\n            </div>\n          </div>\n        </div>\n        {{end}}\n      </div>\n      {{end}}\n    </div>\n    <script type=\"text/javascript\">\n      google.charts.setOnLoadCallback(startPage({{.ContainerName}}, {{.CpuAvailable}}, {{.MemoryAvailable}}, {{.Root}}, {{.IsRoot}}));\n      drawImages({{.DockerImages}});\n    </script>\n  </body>\n</html>\n"
  },
  {
    "path": "cmd/internal/pages/assets/js/containers.js",
    "content": "// Copyright 2014 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\ngoogle.charts.load('current', {packages: ['corechart', 'gauge', 'default', 'format', 'ui', 'table']});\n\nfunction humanize(num, size, units) {\n  var unit;\n  for (unit = units.pop(); units.length && num >= size; unit = units.pop()) {\n    num /= size;\n  }\n  return [num, unit];\n}\n\n// Following the IEC naming convention\nfunction humanizeIEC(num) {\n  var ret = humanize(num, 1024, ['TiB', 'GiB', 'MiB', 'KiB', 'B']);\n  return ret[0].toFixed(2) + ' ' + ret[1];\n}\n// Following the Metric naming convention\n\nfunction humanizeMetric(num) {\n  var ret = humanize(num, 1000, ['TB', 'GB', 'MB', 'KB', 'Bytes']);\n  return ret[0].toFixed(2) + ' ' + ret[1];\n}\n\n// Draw a table.\nfunction drawTable(\n    seriesTitles, titleTypes, data, elementId, numPages, sortIndex) {\n  var dataTable = new google.visualization.DataTable();\n  for (var i = 0; i < seriesTitles.length; i++) {\n    dataTable.addColumn(titleTypes[i], seriesTitles[i]);\n  }\n  dataTable.addRows(data);\n  if (!(elementId in window.charts)) {\n    window.charts[elementId] =\n        new google.visualization.Table(document.getElementById(elementId));\n  }\n\n  var cssClassNames = {\n    'headerRow': '',\n    'tableRow': 'table-row',\n    'oddTableRow': 'table-row'\n  };\n  var opts = {\n    alternatingRowStyle: true,\n    page: 'enable',\n    pageSize: numPages,\n    allowHtml: true,\n    sortColumn: sortIndex,\n    sortAscending: false,\n    cssClassNames: cssClassNames\n  };\n  window.charts[elementId].draw(dataTable, opts);\n}\n\n// Draw a line chart.\nfunction drawLineChart(seriesTitles, data, elementId, unit) {\n  var min = Infinity;\n  var max = -Infinity;\n  for (var i = 0; i < data.length; i++) {\n    // Convert the first column to a Date.\n    if (data[i] != null) {\n      data[i][0] = new Date(data[i][0]);\n    }\n\n    // Find min, max.\n    for (var j = 1; j < data[i].length; j++) {\n      var val = data[i][j];\n      if (val < min) {\n        min = val;\n      }\n      if (val > max) {\n        max = val;\n      }\n    }\n  }\n\n  // We don't want to show any values less than 0 so cap the min value at that.\n  // At the same time, show 10% of the graph below the min value if we can.\n  var minWindow = min - (max - min) / 10;\n  if (minWindow < 0) {\n    minWindow = 0;\n  }\n\n  // Add the definition of each column and the necessary data.\n  var dataTable = new google.visualization.DataTable();\n  dataTable.addColumn('datetime', seriesTitles[0]);\n  for (var i = 1; i < seriesTitles.length; i++) {\n    dataTable.addColumn('number', seriesTitles[i]);\n  }\n  dataTable.addRows(data);\n\n  // Create and draw the visualization.\n  if (!(elementId in window.charts)) {\n    window.charts[elementId] =\n        new google.visualization.LineChart(document.getElementById(elementId));\n  }\n\n  // TODO(vmarmol): Look into changing the view window to get a smoother\n  // animation.\n  var opts = {\n    curveType: 'function',\n    height: 300,\n    legend: {position: 'none'},\n    focusTarget: 'category',\n    vAxis: {\n      title: unit,\n      viewWindow: {\n        min: minWindow,\n      }\n    },\n    legend: {\n      position: 'bottom'\n    }\n  };\n  // If the whole data series has the same value, try to center it in the chart.\n  if (min == max) {\n    opts.vAxis.viewWindow.max = 1.1 * max;\n    opts.vAxis.viewWindow.min = 0.9 * max;\n  }\n\n  window.charts[elementId].draw(dataTable, opts);\n}\n\n// Gets the length of the interval in nanoseconds.\nfunction getInterval(current, previous) {\n  var cur = new Date(current);\n  var prev = new Date(previous);\n\n  // ms -> ns.\n  return (cur.getTime() - prev.getTime()) * 1000000;\n}\n\n// Checks if the specified stats include the specified resource.\nfunction hasResource(stats, resource) {\n  return stats.stats.length > 0 && stats.stats[0][resource];\n}\n\n// Checks if all containers in provided list include the specified resource.\nfunction hasResourceForAll(containerInfos, resource) {\n  if (containerInfos.length === 0) {\n    return false;\n  }\n  for (var i = 0; i < containerInfos.length; i++) {\n    if (!hasResource(containerInfos[i], resource)) {\n      return false;\n    }\n  }\n  return true;\n}\n\n// Draw a set of gauges. Data is comprised of an array of arrays with two\n// elements:\n// a string label and a numeric value for the gauge.\nfunction drawGauges(elementId, gauges) {\n  gauges.unshift(['Label', 'Value']);\n\n  // Create and populate the data table.\n  var data = google.visualization.arrayToDataTable(gauges);\n\n  // Create and draw the visualization.\n  var options = {\n    height: 100,\n    redFrom: 90,\n    redTo: 100,\n    yellowFrom: 75,\n    yellowTo: 90,\n    minorTicks: 5,\n    animation: {duration: 900, easing: 'linear'}\n  };\n  var chart =\n      new google.visualization.Gauge(document.getElementById(elementId));\n  chart.draw(data, options);\n}\n\n// Get the machine info.\nfunction getMachineInfo(rootDir, callback) {\n  $.getJSON(rootDir + 'api/v1.0/machine', function(data) { callback(data); });\n}\n\n// Get ps info.\nfunction getProcessInfo(rootDir, containerName, callback) {\n  $.getJSON(rootDir + 'api/v2.0/ps' + containerName)\n      .done(function(data) { callback(data); })\n      .fail(function(jqhxr, textStatus, error) { callback([]); });\n}\n\n// Get the container stats for the specified container.\nfunction getStats(rootDir, containerName, callback) {\n  // Request 60s of container history and no samples.\n  var request = JSON.stringify({\n    // Update main.statsRequestedByUI while updating \"num_stats\" here.\n    'num_stats': 60,\n    'num_samples': 0\n  });\n\n  $.when(\n       $.post(rootDir + 'api/v1.0/containers' + containerName, request),\n       $.post(rootDir + 'api/v1.1/subcontainers' + containerName, request))\n      .done(function(containersResp, subcontainersResp) {\n        callback(containersResp[0], subcontainersResp[0]);\n      });\n}\n\n// Draw the graph for CPU usage.\nfunction drawCpuTotalUsage(elementId, machineInfo, stats) {\n  if (stats.spec.has_cpu && !hasResource(stats, 'cpu')) {\n    return;\n  }\n\n  var titles = ['Time', 'Total'];\n  var data = [];\n  for (var i = 1; i < stats.stats.length; i++) {\n    var cur = stats.stats[i];\n    var prev = stats.stats[i - 1];\n    var intervalNs = getInterval(cur.timestamp, prev.timestamp);\n\n    var elements = [];\n    elements.push(cur.timestamp);\n    elements.push((cur.cpu.usage.total - prev.cpu.usage.total) / intervalNs);\n    data.push(elements);\n  }\n  drawLineChart(titles, data, elementId, 'Cores');\n}\n\n// Draw the graph for CPU load.\nfunction drawCpuLoad(elementId, machineInfo, stats) {\n  var titles = ['Time', 'Average'];\n  var data = [];\n  for (var i = 1; i < stats.stats.length; i++) {\n    var cur = stats.stats[i];\n\n    var elements = [];\n    elements.push(cur.timestamp);\n    elements.push(cur.cpu.load_average / 1000);\n    data.push(elements);\n  }\n  drawLineChart(titles, data, elementId, 'Runnable threads');\n}\n\n// Draw the graph for per-core CPU usage.\nfunction drawCpuPerCoreUsage(elementId, machineInfo, stats) {\n  if (stats.spec.has_cpu && !hasResource(stats, 'cpu')) {\n    return;\n  }\n\n  // Add a title for each core.\n  var titles = ['Time'];\n  for (var i = 0; i < machineInfo.num_cores; i++) {\n    titles.push('Core ' + i);\n  }\n  var data = [];\n  for (var i = 1; i < stats.stats.length; i++) {\n    var cur = stats.stats[i];\n    var prev = stats.stats[i - 1];\n    var intervalNs = getInterval(cur.timestamp, prev.timestamp);\n\n    if (cur.cpu.usage.per_cpu_usage == undefined) {\n        return;\n    }\n\n    var elements = [];\n    elements.push(cur.timestamp);\n    for (var j = 0; j < machineInfo.num_cores; j++) {\n      elements.push(\n          (cur.cpu.usage.per_cpu_usage[j] - prev.cpu.usage.per_cpu_usage[j]) /\n          intervalNs);\n    }\n    data.push(elements);\n  }\n  drawLineChart(titles, data, elementId, 'Cores');\n}\n\n// Draw the graph for CPU usage breakdown.\nfunction drawCpuUsageBreakdown(elementId, machineInfo, containerInfo) {\n  if (containerInfo.spec.has_cpu && !hasResource(containerInfo, 'cpu')) {\n    return;\n  }\n\n  var titles = ['Time', 'User', 'Kernel'];\n  var data = [];\n  for (var i = 1; i < containerInfo.stats.length; i++) {\n    var cur = containerInfo.stats[i];\n    var prev = containerInfo.stats[i - 1];\n    var intervalNs = getInterval(cur.timestamp, prev.timestamp);\n\n    var elements = [];\n    elements.push(cur.timestamp);\n    elements.push((cur.cpu.usage.user - prev.cpu.usage.user) / intervalNs);\n    elements.push(\n        (cur.cpu.usage.system - prev.cpu.usage.system) / intervalNs);\n    data.push(elements);\n  }\n  drawLineChart(titles, data, elementId, 'Cores');\n}\n\n// Return chart titles and data from an array of subcontainerInfos, using the\n// passed dataFn to return the individual data points.\nfunction getSubcontainerChartData(subcontainerInfos, dataFn) {\n  var titles = ['Time'];\n  var data = [];\n  for (var i = 0; i < subcontainerInfos.length; i++) {\n    titles.push(subcontainerInfos[i].name);\n    for (var j = 1; j < subcontainerInfos[i].stats.length; j++) {\n      var cur = subcontainerInfos[i].stats[j];\n      var prev = subcontainerInfos[i].stats[j - 1];\n\n      // Generate a sparse array with timestamp at index zero and data point at\n      // index i+1, to be used as a DataTable row.\n      var elements = [cur.timestamp];\n      subcontainerInfos.forEach(function() {\n        elements.push(null);\n      });\n      elements[i+1] = dataFn(cur, prev);\n      data.push(elements);\n    }\n  }\n  return {\n    titles: titles,\n    data: data,\n  }\n}\n\n// Draw the graph for per-subcontainer CPU usage.\nfunction drawCpuPerSubcontainerUsage(elementId, subcontainerInfos) {\n  if (!hasResourceForAll(subcontainerInfos, 'cpu')) {\n    return;\n  }\n\n  var chartData = getSubcontainerChartData(subcontainerInfos,\n      function(cur, prev) {\n    var intervalNs = getInterval(cur.timestamp, prev.timestamp);\n    return (cur.cpu.usage.total - prev.cpu.usage.total) / intervalNs;\n  });\n  drawLineChart(chartData.titles, chartData.data, elementId, 'Cores');\n}\n\n// Draw the graph for per-subcontainer memory usage.\nfunction drawMemoryPerSubcontainerUsage(elementId, subcontainerInfos) {\n  if (!hasResourceForAll(subcontainerInfos, 'memory')) {\n    return;\n  }\n\n  var chartData = getSubcontainerChartData(subcontainerInfos,\n      function(cur, prev) {\n    return cur.memory.usage / oneMegabyte;\n  });\n  drawLineChart(chartData.titles, chartData.data, elementId, 'Megabytes');\n}\n\n\n// Draw the gauges for overall resource usage.\nfunction drawOverallUsage(elementId, machineInfo, containerInfo) {\n  var cur = containerInfo.stats[containerInfo.stats.length - 1];\n  var gauges = [];\n\n  var cpuUsage = 0;\n  if (containerInfo.spec.has_cpu && containerInfo.stats.length >= 2) {\n    var prev = containerInfo.stats[containerInfo.stats.length - 2];\n    var rawUsage = cur.cpu.usage.total - prev.cpu.usage.total;\n    var intervalNs = getInterval(cur.timestamp, prev.timestamp);\n\n    // Convert to millicores and take the percentage\n    cpuUsage =\n        Math.round(((rawUsage / intervalNs) / machineInfo.num_cores) * 100);\n    if (cpuUsage > 100) {\n      cpuUsage = 100;\n    }\n    gauges.push(['CPU', cpuUsage]);\n  }\n\n  var memoryUsage = 0;\n  if (containerInfo.spec.has_memory) {\n    // Saturate to the machine size.\n    var limit = containerInfo.spec.memory.limit;\n    if (limit > machineInfo.memory_capacity) {\n      limit = machineInfo.memory_capacity;\n    }\n\n    memoryUsage = Math.round((cur.memory.usage / limit) * 100);\n    gauges.push(['Memory', memoryUsage]);\n  }\n\n  var numGauges = gauges.length;\n  if (cur.filesystem) {\n    for (var i = 0; i < cur.filesystem.length; i++) {\n      var data = cur.filesystem[i];\n      var totalUsage = Math.floor((data.usage * 100.0) / data.capacity);\n      var els = window.cadvisor.fsUsage.elements[data.device];\n\n      // Update the gauges in the right order.\n      gauges[numGauges + els.index] = ['FS #' + (els.index + 1), totalUsage];\n    }\n\n    // Limit the number of filesystem gauges displayed to 5.\n    // 'Filesystem details' section still shows information for all filesystems.\n    var max_gauges = numGauges + 5;\n    if (gauges.length > max_gauges) {\n      gauges = gauges.slice(0, max_gauges);\n    }\n  }\n\n  drawGauges(elementId, gauges);\n}\n\nvar oneMegabyte = 1024 * 1024;\nvar oneGigabyte = 1024 * oneMegabyte;\n\nfunction drawMemoryUsage(elementId, machineInfo, containerInfo) {\n  if (containerInfo.spec.has_memory && !hasResource(containerInfo, 'memory')) {\n    return;\n  }\n\n  var titles = ['Time', 'Total', 'Hot'];\n  var data = [];\n  for (var i = 0; i < containerInfo.stats.length; i++) {\n    var cur = containerInfo.stats[i];\n\n    var elements = [];\n    elements.push(cur.timestamp);\n    elements.push(cur.memory.usage / oneMegabyte);\n    elements.push(cur.memory.working_set / oneMegabyte);\n    data.push(elements);\n  }\n\n  // Get the memory limit, saturate to the machine size.\n  var memory_limit = machineInfo.memory_capacity;\n  if (containerInfo.spec.memory.limit &&\n      (containerInfo.spec.memory.limit < memory_limit)) {\n    memory_limit = containerInfo.spec.memory.limit;\n  }\n\n  // Updating the progress bar.\n  var cur = containerInfo.stats[containerInfo.stats.length - 1];\n  var hotMemory = Math.floor((cur.memory.working_set * 100.0) / memory_limit);\n  var totalMemory = Math.floor((cur.memory.usage * 100.0) / memory_limit);\n  var coldMemory = totalMemory - hotMemory;\n  $('#progress-hot-memory').width(hotMemory + '%');\n  $('#progress-cold-memory').width(coldMemory + '%');\n  $('#memory-text')\n      .text(\n          humanizeIEC(cur.memory.usage) + ' / ' + humanizeIEC(memory_limit) +\n          ' (' + totalMemory + '%)');\n\n  drawLineChart(titles, data, elementId, 'Megabytes');\n}\n\n// Get the index of the interface with the specified name.\nfunction getNetworkInterfaceIndex(interfaceName, interfaces) {\n  for (var i = 0; i < interfaces.length; i++) {\n    if (interfaces[i].name == interfaceName) {\n      return i;\n    }\n  }\n  return -1;\n}\n\n// Draw the graph for network tx/rx bytes.\nfunction drawNetworkBytes(elementId, machineInfo, stats) {\n  if (stats.spec.has_network && !hasResource(stats, 'network')) {\n    return;\n  }\n\n  // Get interface index.\n  var interfaceIndex = -1;\n  if (stats.stats.length > 0) {\n    interfaceIndex = getNetworkInterfaceIndex(\n        window.cadvisor.network.interface, stats.stats[0].network.interfaces);\n  }\n  if (interfaceIndex < 0) {\n    console.log(\n        'Unable to find interface\"', interfaceName, '\" in ',\n        stats.stats.network);\n    return;\n  }\n\n  var titles = ['Time', 'Tx bytes', 'Rx bytes'];\n  var data = [];\n  for (var i = 1; i < stats.stats.length; i++) {\n    var cur = stats.stats[i];\n    var prev = stats.stats[i - 1];\n    var intervalInSec = getInterval(cur.timestamp, prev.timestamp) / 1000000000;\n\n    var elements = [];\n    elements.push(cur.timestamp);\n    elements.push(\n        (cur.network.interfaces[interfaceIndex].tx_bytes -\n         prev.network.interfaces[interfaceIndex].tx_bytes) /\n        intervalInSec);\n    elements.push(\n        (cur.network.interfaces[interfaceIndex].rx_bytes -\n         prev.network.interfaces[interfaceIndex].rx_bytes) /\n        intervalInSec);\n    data.push(elements);\n  }\n  drawLineChart(titles, data, elementId, 'Bytes per second');\n}\n\n// Draw the graph for network errors\nfunction drawNetworkErrors(elementId, machineInfo, stats) {\n  if (stats.spec.has_network && !hasResource(stats, 'network')) {\n    return;\n  }\n\n  // Get interface index.\n  var interfaceIndex = -1;\n  if (stats.stats.length > 0) {\n    interfaceIndex = getNetworkInterfaceIndex(\n        window.cadvisor.network.interface, stats.stats[0].network.interfaces);\n  }\n  if (interfaceIndex < 0) {\n    console.log(\n        'Unable to find interface\"', interfaceName, '\" in ',\n        stats.stats.network);\n    return;\n  }\n\n  var titles = ['Time', 'Tx', 'Rx'];\n  var data = [];\n  for (var i = 1; i < stats.stats.length; i++) {\n    var cur = stats.stats[i];\n    var prev = stats.stats[i - 1];\n    var intervalInSec = getInterval(cur.timestamp, prev.timestamp) / 1000000000;\n\n    var elements = [];\n    elements.push(cur.timestamp);\n    elements.push(\n        (cur.network.interfaces[interfaceIndex].tx_errors -\n         prev.network.interfaces[interfaceIndex].tx_errors) /\n        intervalInSec);\n    elements.push(\n        (cur.network.interfaces[interfaceIndex].rx_errors -\n         prev.network.interfaces[interfaceIndex].rx_errors) /\n        intervalInSec);\n    data.push(elements);\n  }\n  drawLineChart(titles, data, elementId, 'Errors per second');\n}\n\n// Update the filesystem usage values.\nfunction drawFileSystemUsage(machineInfo, stats) {\n  var cur = stats.stats[stats.stats.length - 1];\n  if (!cur.filesystem) {\n    return;\n  }\n\n  var el = $('<div>');\n  for (var i = 0; i < cur.filesystem.length; i++) {\n    var data = cur.filesystem[i];\n    var totalUsage = Math.floor((data.usage * 100.0) / data.capacity);\n\n    // Update DOM elements.\n    var els = window.cadvisor.fsUsage.elements[data.device];\n    els.progressElement.width(totalUsage + '%');\n    els.textElement.text(\n        humanizeMetric(data.usage) + ' / ' + humanizeMetric(data.capacity) +\n        ' (' + totalUsage + '%)');\n  }\n}\n\nfunction drawImages(images) {\n  if (images == null || images.length == 0) {\n    return;\n  }\n  window.charts = {};\n  var titles = ['Repository', 'Tags', 'ID', 'Virtual Size', 'Creation Time'];\n  var titleTypes = ['string', 'string', 'string', 'number', 'number'];\n  var sortIndex = 0;\n  var data = [];\n  for (var i = 0; i < images.length; i++) {\n    var elements = [];\n    var tags = [];\n    var repos = images[i].repo_tags[0].split(':');\n    repos.splice(-1, 1);\n    for (var j = 0; j < images[i].repo_tags.length; j++) {\n      var splits = images[i].repo_tags[j].split(':');\n      if (splits.length > 1) {\n        tags.push(splits[splits.length - 1]);\n      }\n    }\n    elements.push(repos.join(':'));\n    elements.push(tags.join(', '));\n    elements.push(images[i].id.substr(0, 24));\n    elements.push(\n        {v: images[i].virtual_size, f: humanizeIEC(images[i].virtual_size)});\n    var d = new Date(images[i].created * 1000);\n    elements.push({v: images[i].created, f: d.toLocaleString()});\n    data.push(elements);\n  }\n  drawTable(titles, titleTypes, data, 'docker-images', 30, sortIndex);\n}\n\nfunction drawProcesses(isRoot, rootDir, processInfo) {\n  if (processInfo.length == 0) {\n    $('#processes-top').text('No processes found');\n    return;\n  }\n  var titles = [\n    'User', 'PID', 'PPID', 'Start Time', 'CPU %', 'MEM %', 'RSS',\n    'Virtual Size', 'Status', 'Running Time', 'Command', 'PSR'\n  ];\n  var titleTypes = [\n    'string', 'number', 'number', 'string', 'number', 'number', 'number',\n    'number', 'string', 'string', 'string', 'number'\n  ];\n  var sortIndex = 4;\n  if (isRoot) {\n    titles.push('Container');\n    titleTypes.push('string');\n  }\n  var data = [];\n  for (var i = 0; i < processInfo.length; i++) {\n    var elements = [];\n    elements.push(processInfo[i].user);\n    elements.push(processInfo[i].pid);\n    elements.push(processInfo[i].parent_pid);\n    elements.push(processInfo[i].start_time);\n    elements.push({\n      v: processInfo[i].percent_cpu,\n      f: processInfo[i].percent_cpu.toFixed(2)\n    });\n    elements.push({\n      v: processInfo[i].percent_mem,\n      f: processInfo[i].percent_mem.toFixed(2)\n    });\n    elements.push({v: processInfo[i].rss, f: humanizeIEC(processInfo[i].rss)});\n    elements.push({\n      v: processInfo[i].virtual_size,\n      f: humanizeIEC(processInfo[i].virtual_size)\n    });\n    elements.push(processInfo[i].status);\n    elements.push(processInfo[i].running_time);\n    elements.push(processInfo[i].cmd);\n    elements.push(processInfo[i].psr);\n    if (isRoot) {\n      var cgroup = processInfo[i].cgroup_path;\n      // Use the raw cgroup link as it works for all containers.\n      var cgroupLink = '<a href=\"' + rootDir + 'containers/' + cgroup + '\">' +\n          cgroup.substr(0, 30) + ' </a>';\n      elements.push({v: cgroup, f: cgroupLink});\n    }\n    data.push(elements);\n  }\n  drawTable(titles, titleTypes, data, 'processes-top', 25, sortIndex);\n}\n\n// Draw the filesystem usage nodes.\nfunction startFileSystemUsage(elementId, machineInfo, stats) {\n  window.cadvisor.fsUsage = {};\n\n  // A map of device name to DOM elements.\n  window.cadvisor.fsUsage.elements = {};\n\n  var cur = stats.stats[stats.stats.length - 1];\n  var el = $('<div>');\n  if (!cur.filesystem) {\n    return;\n  }\n  for (var i = 0; i < cur.filesystem.length; i++) {\n    var data = cur.filesystem[i];\n    el.append(\n        $('<div>')\n            .addClass('row col-sm-12')\n            .append($('<h4>').text('FS #' + (i + 1) + ': ' + data.device)));\n\n    var progressElement =\n        $('<div>').addClass('progress-bar progress-bar-danger');\n    el.append(\n        $('<div>')\n            .addClass('col-sm-9')\n            .append($('<div>').addClass('progress').append(progressElement)));\n\n    var textElement = $('<div>').addClass('col-sm-3');\n    el.append(textElement);\n\n    window.cadvisor.fsUsage.elements[data.device] = {\n      'progressElement': progressElement,\n      'textElement': textElement,\n      'index': i,\n    };\n  }\n  $('#' + elementId).empty().append(el);\n\n  drawFileSystemUsage(machineInfo, stats);\n}\n\n// Expects an array of closures to call. After each execution the JS runtime is\n// given control back before continuing.\n// This function returns asynchronously\nfunction stepExecute(steps) {\n  // No steps, stop.\n  if (steps.length == 0) {\n    return;\n  }\n\n  // Get a step and execute it.\n  var step = steps.shift();\n  step();\n\n  // Schedule the next step.\n  setTimeout(function() { stepExecute(steps); }, 0);\n}\n\n// Draw all the charts on the page.\nfunction drawCharts(machineInfo, containerInfo, subcontainers) {\n  var steps = [];\n\n  if (containerInfo.spec.has_cpu || containerInfo.spec.has_memory) {\n    steps.push(function() {\n      drawOverallUsage('usage-gauge', machineInfo, containerInfo);\n    });\n  }\n\n  // CPU.\n  if (containerInfo.spec.has_cpu) {\n    steps.push(function() {\n      drawCpuTotalUsage('cpu-total-usage-chart', machineInfo, containerInfo);\n    });\n    // TODO(rjnagal): Re-enable CPU Load after understanding resource usage.\n    // steps.push(function() {\n    // \tdrawCpuLoad(\"cpu-load-chart\", machineInfo, containerInfo);\n    // });\n    steps.push(function() {\n      drawCpuPerCoreUsage(\n          'cpu-per-core-usage-chart', machineInfo, containerInfo);\n    });\n    steps.push(function() {\n      drawCpuUsageBreakdown(\n          'cpu-usage-breakdown-chart', machineInfo, containerInfo);\n    });\n  }\n\n  // Memory.\n  if (containerInfo.spec.has_memory) {\n    steps.push(function() {\n      drawMemoryUsage('memory-usage-chart', machineInfo, containerInfo);\n    });\n  }\n\n  // Network.\n  if (containerInfo.spec.has_network) {\n    steps.push(function() {\n      drawNetworkBytes('network-bytes-chart', machineInfo, containerInfo);\n    });\n    steps.push(function() {\n      drawNetworkErrors('network-errors-chart', machineInfo, containerInfo);\n    });\n  }\n\n  // Filesystem.\n  if (containerInfo.spec.has_filesystem) {\n    steps.push(function() { drawFileSystemUsage(machineInfo, containerInfo); });\n  }\n\n  // Custom Metrics\n  if (containerInfo.spec.has_custom_metrics) {\n    steps.push(function() {\n      getCustomMetrics(\n          window.cadvisor.rootDir, window.cadvisor.containerName,\n          function(metricsInfo) {\n            drawCustomMetrics(\n              'custom-metrics-chart', containerInfo, metricsInfo);\n          });\n    });\n  }\n\n  // Subcontainers.\n  var subcontainerInfos = filterSubcontainers(containerInfo, subcontainers);\n  if (subcontainerInfos.length > 0) {\n    if (hasResourceForAll(subcontainerInfos, 'cpu')) {\n      steps.push(function() {\n        var displayCount = $('#cpu-per-subcontainer-display-count').val();\n        drawCpuPerSubcontainerUsage(\n            'cpu-per-subcontainer-usage-chart',\n            sliceByCpu(subcontainerInfos, displayCount));\n      });\n    }\n\n    if (hasResourceForAll(subcontainerInfos, 'memory')) {\n      steps.push(function() {\n        var displayCount = $('#memory-per-subcontainer-display-count').val();\n        drawMemoryPerSubcontainerUsage(\n            'memory-per-subcontainer-usage-chart',\n            sliceByMemory(subcontainerInfos, displayCount));\n      });\n    }\n  }\n\n  stepExecute(steps);\n}\n\n// Return an slice of subcontainers sorted by CPU, with at most 'count' entries.\nfunction sliceByCpu(subcontainerInfos, count) {\n  subcontainerInfos.sort(function(a, b) {\n    if (a.averages.cpu > b.averages.cpu) {\n      return -1;\n    } else if (a.averages.cpu < b.averages.cpu) {\n      return 1;\n    } else {\n      return compareByName(a, b);\n    }\n  });\n  return subcontainerInfos.slice(0, Math.min(subcontainerInfos.length, count))\n      .sort(compareByName);\n}\n\n// Return an slice of subcontainers sorted by memory, with at most 'count'\n// entries.\nfunction sliceByMemory(subcontainerInfos, count) {\n  subcontainerInfos.sort(function(a, b) {\n    if (a.averages.memory > b.averages.memory) {\n      return -1;\n    } else if (a.averages.memory < b.averages.memory) {\n      return 1;\n    } else {\n      return compareByName(a, b);\n    }\n  });\n  return subcontainerInfos.slice(0, Math.min(subcontainerInfos.length, count))\n      .sort(compareByName);\n}\n\n// Return sort comparitor based on subcontroller name.\nfunction compareByName(subA, subB) {\n  if (subA.name > subB.name) {\n    return 1;\n  } else if (subA.name < subB.name) {\n    return -1;\n  } else {\n    return 0;\n  }\n}\n\n// Return a map of the averages of the subcontainer stats.\nfunction getSubcontainerAverages(subcontainer) {\n  var cpuSum = 0;\n  var memorySum = 0;\n  subcontainer.stats.forEach(function(stat) {\n    cpuSum += stat.cpu.usage.total;\n    memorySum += stat.memory.usage / oneMegabyte;\n  });\n  return {\n    cpu: cpuSum / subcontainer.stats.length,\n    memory: memorySum / subcontainer.stats.length,\n  }\n}\n\n// Return a list of immediate subcontainers, including metric averages.\nfunction filterSubcontainers(containerInfo, subcontainers) {\n  if (!containerInfo.subcontainers ||\n      containerInfo.subcontainers.length === 0 ||\n      !subcontainers) {\n    return [];\n  }\n\n  var subcontainerNames = {};\n  containerInfo.subcontainers.forEach(function(subcontainer) {\n    subcontainerNames[subcontainer.name] = subcontainer.name;\n  });\n\n  var subcontainerInfos = [];\n  subcontainers.forEach(function(subcontainer) {\n    if (subcontainerNames[subcontainer.name] !== undefined) {\n      subcontainer.averages = getSubcontainerAverages(subcontainer);\n      subcontainerInfos.push(subcontainer);\n    }\n  });\n\n  return subcontainerInfos;\n}\n\nfunction setNetwork(interfaceName) {\n  $('#network-selection-text')\n      .empty()\n      .append($('<span>').text('Interface: '))\n      .append($('<b>').text(interfaceName));\n  window.cadvisor.network.interface = interfaceName;\n\n  // Draw the new stats.\n  refreshStats();\n}\n\n// Creates the network selection dropdown.\nfunction startNetwork(selectionElement, containerInfo) {\n  if (!hasResource(containerInfo, 'network') ||\n      containerInfo.stats.length == 0 ||\n      !containerInfo.stats[0].network.interfaces ||\n      containerInfo.stats[0].network.interfaces.length == 0) {\n    return;\n  }\n\n  window.cadvisor.network = {};\n  window.cadvisor.network.interface = '';\n\n  // Add all interfaces to the dropdown.\n  var el = $('#' + selectionElement);\n  for (var i = 0; i < containerInfo.stats[0].network.interfaces.length; i++) {\n    var interfaceName = containerInfo.stats[0].network.interfaces[i].name;\n    el.append($('<li>')\n                  .attr('role', 'presentation')\n                  .append($('<a>')\n                              .attr('role', 'menuitem')\n                              .attr('tabindex', -1)\n                              .click(setNetwork.bind(null, interfaceName))\n                              .text(interfaceName)));\n  }\n  setNetwork(containerInfo.stats[0].network.interfaces[0].name);\n}\n\n// Refresh the stats on the page.\nfunction refreshStats() {\n  var machineInfo = window.cadvisor.machineInfo;\n  getStats(\n      window.cadvisor.rootDir, window.cadvisor.containerName,\n      function(containerInfo, subcontainers) {\n        if (window.cadvisor.firstRun) {\n          window.cadvisor.firstRun = false;\n\n          if (containerInfo.spec.has_filesystem) {\n            startFileSystemUsage(\n                'filesystem-usage', machineInfo, containerInfo);\n          }\n          if (containerInfo.spec.has_network) {\n            startNetwork('network-selection', containerInfo);\n          }\n          if (containerInfo.spec.has_custom_metrics) {\n            startCustomMetrics('custom-metrics-chart', containerInfo);\n          }\n        }\n        drawCharts(machineInfo, containerInfo, subcontainers);\n      });\n}\n\nfunction addAllLabels(containerInfo, metricsInfo) {\n  if (metricsInfo.length == 0) {\n    return;\n  }\n  var metricSpec = containerInfo.spec.custom_metrics;\n  for (var containerName in metricsInfo) {\n    var container = metricsInfo[containerName];\n    for (i = 0; i < metricSpec.length; i++) {\n      metricName = metricSpec[i].name;\n      metricLabelVal = container[metricName];\n      firstLabel = true;\n      for (var label in metricLabelVal) {\n        if (label == '') {\n          $('#button-' + metricName).hide();\n        }\n\n        $('#' + metricName + '_labels')\n            .append(\n                $('<li>')\n                    .attr('role', 'presentation')\n                    .append($('<a>')\n                                .attr('role', 'menuitem')\n                                .click(setLabel.bind(null, metricName, label))\n                                .text(label)));\n        if (firstLabel) {\n          firstLabel = false;\n          setLabel(metricName, label);\n        }\n      }\n    }\n  }\n}\n\nfunction getMetricIndex(metricName) {\n  for (i = 0; i < window.cadvisor.metricLabelPair.length; ++i) {\n    if (window.cadvisor.metricLabelPair[i][0] == metricName) { return i; }\n  }\n  return -1;\n}\n\nfunction setLabel(metric, label) {\n  $('#' + metric + '-selection-text')\n      .empty()\n      .append($('<span>').text('Label: '))\n      .append($('<b>').text(label));\n\n  index = getMetricIndex(metric);\n  if (index == -1) {\n    window.cadvisor.metricLabelPair.push([metric, label]);\n  } else {\n    window.cadvisor.metricLabelPair[index][1] = label;\n  }\n\n  refreshStats();\n}\n\nfunction getSelectedLabel(metricName) {\n  index = getMetricIndex(metricName);\n  if (index == -1) { return ''; }\n  return window.cadvisor.metricLabelPair[index][1];\n}\n\nfunction startCustomMetrics(elementId, containerInfo) {\n  var metricSpec = containerInfo.spec.custom_metrics;\n  var metricStats = containerInfo.stats.custom_metrics;\n  var el = $('<div>');\n\n  if (metricSpec.length < window.cadvisor.maxCustomMetrics) {\n    window.cadvisor.maxCustomMetrics = metricSpec.length;\n    for (i = 0; i < window.cadvisor.maxCustomMetrics; i++) {\n      metricName = metricSpec[i].name;\n      var divText =\n          '<div class=\\'dropdown\\'> <button class=\\'btn btn-default' +\n          ' dropdown-toggle\\' type=\\'button\\' id=\\'button-' + metricName;\n      divText +=\n          '\\' data-toggle=\\'dropdown\\' aria-haspopup=\\'true\\'' +\n          ' aria-expanded=\\'false\\'>';\n      divText += '<span id=\\'' + metricName +\n          '-selection-text\\'></span> <span class=\\'caret\\'></span> </button>';\n      divText += '<ul id=\\'' + metricName +\n          '_labels\\' class=\\'dropdown-menu\\' role=\\'menu\\'' +\n          ' aria-labelledby=\\'button-' + metricName + '\\'> </ul> </div>';\n      divText += '<div id=\\'' + elementId + '-' + metricName + '\\'> </div>';\n      el.append($(divText));\n    }\n  }\n  el.append($('</div>'));\n\n  $('#' + elementId).append(el);\n}\n\nfunction getCustomMetrics(rootDir, containerName, callback) {\n  $.getJSON(rootDir + 'api/v2.0/appmetrics/' + containerName)\n      .done(function(data) { callback(data); })\n      .fail(function(jqhxr, textStatus, error) { callback([]); });\n}\n\nfunction drawCustomMetrics(elementId, containerInfo, metricsInfo) {\n  if (metricsInfo.length == 0) {\n    return;\n  }\n  var metricSpec = containerInfo.spec.custom_metrics;\n  for (var containerName in metricsInfo) {\n    var container = metricsInfo[containerName];\n    for (i = 0; i < window.cadvisor.maxCustomMetrics; i++) {\n      metricName = metricSpec[i].name;\n      metricUnits = metricSpec[i].units;\n      var titles = ['Time', metricName];\n      metricLabelVal = container[metricName];\n      if (window.cadvisor.firstCustomCollection) {\n        window.cadvisor.firstCustomCollection = false;\n        addAllLabels(containerInfo, metricsInfo);\n      }\n      var data = [];\n      selectedLabel = getSelectedLabel(metricName);\n      metricVal = metricLabelVal[selectedLabel];\n      for (var index in metricVal) {\n        metric = metricVal[index];\n        var elements = [];\n        for (var attribute in metric) {\n          value = metric[attribute];\n          elements.push(value);\n        }\n        if (elements.length < 2) {\n          elements.push(0);\n        }\n        data.push(elements);\n      }\n      drawLineChart(titles, data, elementId + '-' + metricName, metricUnits);\n    }\n  }\n}\n\n// Executed when the page finishes loading.\nfunction startPage(containerName, hasCpu, hasMemory, rootDir, isRoot) {\n  // Don't fetch data if we don't have any resource.\n  if (!hasCpu && !hasMemory) {\n    return;\n  }\n\n  window.charts = {};\n  window.cadvisor = {};\n  window.cadvisor.firstRun = true;\n  window.cadvisor.rootDir = rootDir;\n  window.cadvisor.containerName = containerName;\n\n  window.cadvisor.firstCustomCollection = true;\n  window.cadvisor.metricLabelPair = [];\n  window.cadvisor.maxCustomMetrics = 10;\n\n  // Draw process information at start and refresh every 60s.\n  getProcessInfo(rootDir, containerName, function(processInfo) {\n    drawProcesses(isRoot, rootDir, processInfo);\n  });\n  setInterval(function() {\n    getProcessInfo(rootDir, containerName, function(processInfo) {\n      drawProcesses(isRoot, rootDir, processInfo);\n    });\n  }, 60000);\n\n  // Get machine info, then get the stats every 1s.\n  getMachineInfo(rootDir, function(machineInfo) {\n    window.cadvisor.machineInfo = machineInfo;\n    setInterval(function() { refreshStats(); }, 1000);\n  });\n}\n"
  },
  {
    "path": "cmd/internal/pages/assets/js/loader.js",
    "content": "(function(){/*\n\n Copyright The Closure Library Authors.\n SPDX-License-Identifier: Apache-2.0\n*/\n'use strict';var m;function aa(a){var b=0;return function(){return b<a.length?{done:!1,value:a[b++]}:{done:!0}}}function n(a){var b=\"undefined\"!=typeof Symbol&&Symbol.iterator&&a[Symbol.iterator];return b?b.call(a):{next:aa(a)}}function ba(a){if(!(a instanceof Array)){a=n(a);for(var b,c=[];!(b=a.next()).done;)c.push(b.value);a=c}return a}function ca(a,b,c){a instanceof String&&(a=String(a));for(var d=a.length,e=0;e<d;e++){var f=a[e];if(b.call(c,f,e,a))return{N:e,T:f}}return{N:-1,T:void 0}}\nvar da=\"function\"==typeof Object.defineProperties?Object.defineProperty:function(a,b,c){if(a==Array.prototype||a==Object.prototype)return a;a[b]=c.value;return a};function ea(a){a=[\"object\"==typeof globalThis&&globalThis,a,\"object\"==typeof window&&window,\"object\"==typeof self&&self,\"object\"==typeof global&&global];for(var b=0;b<a.length;++b){var c=a[b];if(c&&c.Math==Math)return c}throw Error(\"Cannot find global object\");}var fa=ea(this);\nfunction q(a,b){if(b)a:{var c=fa;a=a.split(\".\");for(var d=0;d<a.length-1;d++){var e=a[d];if(!(e in c))break a;c=c[e]}a=a[a.length-1];d=c[a];b=b(d);b!=d&&null!=b&&da(c,a,{configurable:!0,writable:!0,value:b})}}q(\"Array.prototype.findIndex\",function(a){return a?a:function(b,c){return ca(this,b,c).N}});q(\"Array.prototype.find\",function(a){return a?a:function(b,c){return ca(this,b,c).T}});\nfunction r(a,b,c){if(null==a)throw new TypeError(\"The 'this' value for String.prototype.\"+c+\" must not be null or undefined\");if(b instanceof RegExp)throw new TypeError(\"First argument to String.prototype.\"+c+\" must not be a regular expression\");return a+\"\"}q(\"String.prototype.endsWith\",function(a){return a?a:function(b,c){var d=r(this,b,\"endsWith\");void 0===c&&(c=d.length);c=Math.max(0,Math.min(c|0,d.length));for(var e=b.length;0<e&&0<c;)if(d[--c]!=b[--e])return!1;return 0>=e}});\nq(\"String.prototype.startsWith\",function(a){return a?a:function(b,c){var d=r(this,b,\"startsWith\"),e=d.length,f=b.length;c=Math.max(0,Math.min(c|0,d.length));for(var g=0;g<f&&c<e;)if(d[c++]!=b[g++])return!1;return g>=f}});q(\"String.prototype.repeat\",function(a){return a?a:function(b){var c=r(this,null,\"repeat\");if(0>b||1342177279<b)throw new RangeError(\"Invalid count value\");b|=0;for(var d=\"\";b;)if(b&1&&(d+=c),b>>>=1)c+=c;return d}});\nq(\"String.prototype.trimLeft\",function(a){function b(){return this.replace(/^[\\s\\xa0]+/,\"\")}return a||b});q(\"String.prototype.trimStart\",function(a){return a||String.prototype.trimLeft});\nq(\"Promise\",function(a){function b(g){this.b=0;this.c=void 0;this.a=[];var h=this.g();try{g(h.resolve,h.reject)}catch(k){h.reject(k)}}function c(){this.a=null}function d(g){return g instanceof b?g:new b(function(h){h(g)})}if(a)return a;c.prototype.b=function(g){if(null==this.a){this.a=[];var h=this;this.c(function(){h.h()})}this.a.push(g)};var e=fa.setTimeout;c.prototype.c=function(g){e(g,0)};c.prototype.h=function(){for(;this.a&&this.a.length;){var g=this.a;this.a=[];for(var h=0;h<g.length;++h){var k=\ng[h];g[h]=null;try{k()}catch(l){this.g(l)}}}this.a=null};c.prototype.g=function(g){this.c(function(){throw g;})};b.prototype.g=function(){function g(l){return function(p){k||(k=!0,l.call(h,p))}}var h=this,k=!1;return{resolve:g(this.B),reject:g(this.h)}};b.prototype.B=function(g){if(g===this)this.h(new TypeError(\"A Promise cannot resolve to itself\"));else if(g instanceof b)this.H(g);else{a:switch(typeof g){case \"object\":var h=null!=g;break a;case \"function\":h=!0;break a;default:h=!1}h?this.A(g):this.i(g)}};\nb.prototype.A=function(g){var h=void 0;try{h=g.then}catch(k){this.h(k);return}\"function\"==typeof h?this.F(h,g):this.i(g)};b.prototype.h=function(g){this.j(2,g)};b.prototype.i=function(g){this.j(1,g)};b.prototype.j=function(g,h){if(0!=this.b)throw Error(\"Cannot settle(\"+g+\", \"+h+\"): Promise already settled in state\"+this.b);this.b=g;this.c=h;this.m()};b.prototype.m=function(){if(null!=this.a){for(var g=0;g<this.a.length;++g)f.b(this.a[g]);this.a=null}};var f=new c;b.prototype.H=function(g){var h=this.g();\ng.G(h.resolve,h.reject)};b.prototype.F=function(g,h){var k=this.g();try{g.call(h,k.resolve,k.reject)}catch(l){k.reject(l)}};b.prototype.then=function(g,h){function k(A,G){return\"function\"==typeof A?function(ua){try{l(A(ua))}catch(va){p(va)}}:G}var l,p,x=new b(function(A,G){l=A;p=G});this.G(k(g,l),k(h,p));return x};b.prototype.catch=function(g){return this.then(void 0,g)};b.prototype.G=function(g,h){function k(){switch(l.b){case 1:g(l.c);break;case 2:h(l.c);break;default:throw Error(\"Unexpected state: \"+\nl.b);}}var l=this;null==this.a?f.b(k):this.a.push(k)};b.resolve=d;b.reject=function(g){return new b(function(h,k){k(g)})};b.race=function(g){return new b(function(h,k){for(var l=n(g),p=l.next();!p.done;p=l.next())d(p.value).G(h,k)})};b.all=function(g){var h=n(g),k=h.next();return k.done?d([]):new b(function(l,p){function x(ua){return function(va){A[ua]=va;G--;0==G&&l(A)}}var A=[],G=0;do A.push(void 0),G++,d(k.value).G(x(A.length-1),p),k=h.next();while(!k.done)})};return b});\nq(\"Object.is\",function(a){return a?a:function(b,c){return b===c?0!==b||1/b===1/c:b!==b&&c!==c}});q(\"Array.prototype.includes\",function(a){return a?a:function(b,c){var d=this;d instanceof String&&(d=String(d));var e=d.length;c=c||0;for(0>c&&(c=Math.max(c+e,0));c<e;c++){var f=d[c];if(f===b||Object.is(f,b))return!0}return!1}});q(\"String.prototype.includes\",function(a){return a?a:function(b,c){return-1!==r(this,b,\"includes\").indexOf(b,c||0)}});\nq(\"Array.prototype.copyWithin\",function(a){function b(c){c=Number(c);return Infinity===c||-Infinity===c?c:c|0}return a?a:function(c,d,e){var f=this.length;c=b(c);d=b(d);e=void 0===e?f:b(e);c=0>c?Math.max(f+c,0):Math.min(c,f);d=0>d?Math.max(f+d,0):Math.min(d,f);e=0>e?Math.max(f+e,0):Math.min(e,f);if(c<d)for(;d<e;)d in this?this[c++]=this[d++]:(delete this[c++],d++);else for(e=Math.min(e,f+d-c),c+=e-d;e>d;)--e in this?this[--c]=this[e]:delete this[--c];return this}});\nq(\"Symbol\",function(a){function b(e){if(this instanceof b)throw new TypeError(\"Symbol is not a constructor\");return new c(\"jscomp_symbol_\"+(e||\"\")+\"_\"+d++,e)}function c(e,f){this.a=e;da(this,\"description\",{configurable:!0,writable:!0,value:f})}if(a)return a;c.prototype.toString=function(){return this.a};var d=0;return b});\nq(\"Symbol.iterator\",function(a){if(a)return a;a=Symbol(\"Symbol.iterator\");for(var b=\"Array Int8Array Uint8Array Uint8ClampedArray Int16Array Uint16Array Int32Array Uint32Array Float32Array Float64Array\".split(\" \"),c=0;c<b.length;c++){var d=fa[b[c]];\"function\"===typeof d&&\"function\"!=typeof d.prototype[a]&&da(d.prototype,a,{configurable:!0,writable:!0,value:function(){return ha(aa(this))}})}return a});q(\"Symbol.asyncIterator\",function(a){return a?a:Symbol(\"Symbol.asyncIterator\")});\nfunction ha(a){a={next:a};a[Symbol.iterator]=function(){return this};return a}function ia(a,b){a instanceof String&&(a+=\"\");var c=0,d={next:function(){if(c<a.length){var e=c++;return{value:b(e,a[e]),done:!1}}d.next=function(){return{done:!0,value:void 0}};return d.next()}};d[Symbol.iterator]=function(){return d};return d}q(\"Array.prototype.entries\",function(a){return a?a:function(){return ia(this,function(b,c){return[b,c]})}});\nq(\"Array.prototype.fill\",function(a){return a?a:function(b,c,d){var e=this.length||0;0>c&&(c=Math.max(0,e+c));if(null==d||d>e)d=e;d=Number(d);0>d&&(d=Math.max(0,e+d));for(c=Number(c||0);c<d;c++)this[c]=b;return this}});q(\"Array.prototype.flat\",function(a){return a?a:function(b){b=void 0===b?1:b;for(var c=[],d=0;d<this.length;d++){var e=this[d];Array.isArray(e)&&0<b?(e=Array.prototype.flat.call(e,b-1),c.push.apply(c,e)):c.push(e)}return c}});\nq(\"Array.prototype.flatMap\",function(a){return a?a:function(b,c){for(var d=[],e=0;e<this.length;e++){var f=b.call(c,this[e],e,this);Array.isArray(f)?d.push.apply(d,f):d.push(f)}return d}});\nq(\"Array.from\",function(a){return a?a:function(b,c,d){c=null!=c?c:function(h){return h};var e=[],f=\"undefined\"!=typeof Symbol&&Symbol.iterator&&b[Symbol.iterator];if(\"function\"==typeof f){b=f.call(b);for(var g=0;!(f=b.next()).done;)e.push(c.call(d,f.value,g++))}else for(f=b.length,g=0;g<f;g++)e.push(c.call(d,b[g],g));return e}});q(\"Array.prototype.keys\",function(a){return a?a:function(){return ia(this,function(b){return b})}});q(\"Array.of\",function(a){return a?a:function(b){return Array.from(arguments)}});\nq(\"Array.prototype.values\",function(a){return a?a:function(){return ia(this,function(b,c){return c})}});var ja;if(\"function\"==typeof Object.setPrototypeOf)ja=Object.setPrototypeOf;else{var ka;a:{var la={X:!0},ma={};try{ma.__proto__=la;ka=ma.X;break a}catch(a){}ka=!1}ja=ka?function(a,b){a.__proto__=b;if(a.__proto__!==b)throw new TypeError(a+\" is not extensible\");return a}:null}var na=ja;q(\"globalThis\",function(a){return a||fa});function t(a,b){return Object.prototype.hasOwnProperty.call(a,b)}\nq(\"WeakMap\",function(a){function b(k){this.a=(h+=Math.random()+1).toString();if(k){k=n(k);for(var l;!(l=k.next()).done;)l=l.value,this.set(l[0],l[1])}}function c(){}function d(k){var l=typeof k;return\"object\"===l&&null!==k||\"function\"===l}function e(k){if(!t(k,g)){var l=new c;da(k,g,{value:l})}}function f(k){var l=Object[k];l&&(Object[k]=function(p){if(p instanceof c)return p;Object.isExtensible(p)&&e(p);return l(p)})}if(function(){if(!a||!Object.seal)return!1;try{var k=Object.seal({}),l=Object.seal({}),\np=new a([[k,2],[l,3]]);if(2!=p.get(k)||3!=p.get(l))return!1;p.delete(k);p.set(l,4);return!p.has(k)&&4==p.get(l)}catch(x){return!1}}())return a;var g=\"$jscomp_hidden_\"+Math.random();f(\"freeze\");f(\"preventExtensions\");f(\"seal\");var h=0;b.prototype.set=function(k,l){if(!d(k))throw Error(\"Invalid WeakMap key\");e(k);if(!t(k,g))throw Error(\"WeakMap key fail: \"+k);k[g][this.a]=l;return this};b.prototype.get=function(k){return d(k)&&t(k,g)?k[g][this.a]:void 0};b.prototype.has=function(k){return d(k)&&t(k,\ng)&&t(k[g],this.a)};b.prototype.delete=function(k){return d(k)&&t(k,g)&&t(k[g],this.a)?delete k[g][this.a]:!1};return b});\nq(\"Map\",function(a){function b(){var h={};return h.s=h.next=h.head=h}function c(h,k){var l=h.a;return ha(function(){if(l){for(;l.head!=h.a;)l=l.s;for(;l.next!=l.head;)return l=l.next,{done:!1,value:k(l)};l=null}return{done:!0,value:void 0}})}function d(h,k){var l=k&&typeof k;\"object\"==l||\"function\"==l?f.has(k)?l=f.get(k):(l=\"\"+ ++g,f.set(k,l)):l=\"p_\"+k;var p=h.b[l];if(p&&t(h.b,l))for(h=0;h<p.length;h++){var x=p[h];if(k!==k&&x.key!==x.key||k===x.key)return{id:l,list:p,index:h,l:x}}return{id:l,list:p,\nindex:-1,l:void 0}}function e(h){this.b={};this.a=b();this.size=0;if(h){h=n(h);for(var k;!(k=h.next()).done;)k=k.value,this.set(k[0],k[1])}}if(function(){if(!a||\"function\"!=typeof a||!a.prototype.entries||\"function\"!=typeof Object.seal)return!1;try{var h=Object.seal({x:4}),k=new a(n([[h,\"s\"]]));if(\"s\"!=k.get(h)||1!=k.size||k.get({x:4})||k.set({x:4},\"t\")!=k||2!=k.size)return!1;var l=k.entries(),p=l.next();if(p.done||p.value[0]!=h||\"s\"!=p.value[1])return!1;p=l.next();return p.done||4!=p.value[0].x||\n\"t\"!=p.value[1]||!l.next().done?!1:!0}catch(x){return!1}}())return a;var f=new WeakMap;e.prototype.set=function(h,k){h=0===h?0:h;var l=d(this,h);l.list||(l.list=this.b[l.id]=[]);l.l?l.l.value=k:(l.l={next:this.a,s:this.a.s,head:this.a,key:h,value:k},l.list.push(l.l),this.a.s.next=l.l,this.a.s=l.l,this.size++);return this};e.prototype.delete=function(h){h=d(this,h);return h.l&&h.list?(h.list.splice(h.index,1),h.list.length||delete this.b[h.id],h.l.s.next=h.l.next,h.l.next.s=h.l.s,h.l.head=null,this.size--,\n!0):!1};e.prototype.clear=function(){this.b={};this.a=this.a.s=b();this.size=0};e.prototype.has=function(h){return!!d(this,h).l};e.prototype.get=function(h){return(h=d(this,h).l)&&h.value};e.prototype.entries=function(){return c(this,function(h){return[h.key,h.value]})};e.prototype.keys=function(){return c(this,function(h){return h.key})};e.prototype.values=function(){return c(this,function(h){return h.value})};e.prototype.forEach=function(h,k){for(var l=this.entries(),p;!(p=l.next()).done;)p=p.value,\nh.call(k,p[1],p[0],this)};e.prototype[Symbol.iterator]=e.prototype.entries;var g=0;return e});q(\"Math.acosh\",function(a){return a?a:function(b){b=Number(b);return Math.log(b+Math.sqrt(b*b-1))}});q(\"Math.asinh\",function(a){return a?a:function(b){b=Number(b);if(0===b)return b;var c=Math.log(Math.abs(b)+Math.sqrt(b*b+1));return 0>b?-c:c}});\nq(\"Math.log1p\",function(a){return a?a:function(b){b=Number(b);if(.25>b&&-.25<b){for(var c=b,d=1,e=b,f=0,g=1;f!=e;)c*=b,g*=-1,e=(f=e)+g*c/++d;return e}return Math.log(1+b)}});q(\"Math.atanh\",function(a){if(a)return a;var b=Math.log1p;return function(c){c=Number(c);return(b(c)-b(-c))/2}});q(\"Math.cbrt\",function(a){return a?a:function(b){if(0===b)return b;b=Number(b);var c=Math.pow(Math.abs(b),1/3);return 0>b?-c:c}});\nq(\"Math.clz32\",function(a){return a?a:function(b){b=Number(b)>>>0;if(0===b)return 32;var c=0;0===(b&4294901760)&&(b<<=16,c+=16);0===(b&4278190080)&&(b<<=8,c+=8);0===(b&4026531840)&&(b<<=4,c+=4);0===(b&3221225472)&&(b<<=2,c+=2);0===(b&2147483648)&&c++;return c}});q(\"Math.cosh\",function(a){if(a)return a;var b=Math.exp;return function(c){c=Number(c);return(b(c)+b(-c))/2}});\nq(\"Math.expm1\",function(a){return a?a:function(b){b=Number(b);if(.25>b&&-.25<b){for(var c=b,d=1,e=b,f=0;f!=e;)c*=b/++d,e=(f=e)+c;return e}return Math.exp(b)-1}});q(\"Math.fround\",function(a){if(a)return a;if(\"function\"!==typeof Float32Array)return function(c){return c};var b=new Float32Array(1);return function(c){b[0]=c;return b[0]}});\nq(\"Math.hypot\",function(a){return a?a:function(b){if(2>arguments.length)return arguments.length?Math.abs(arguments[0]):0;var c,d,e;for(c=e=0;c<arguments.length;c++)e=Math.max(e,Math.abs(arguments[c]));if(1E100<e||1E-100>e){if(!e)return e;for(c=d=0;c<arguments.length;c++){var f=Number(arguments[c])/e;d+=f*f}return Math.sqrt(d)*e}for(c=d=0;c<arguments.length;c++)f=Number(arguments[c]),d+=f*f;return Math.sqrt(d)}});\nq(\"Math.imul\",function(a){return a?a:function(b,c){b=Number(b);c=Number(c);var d=b&65535,e=c&65535;return d*e+((b>>>16&65535)*e+d*(c>>>16&65535)<<16>>>0)|0}});q(\"Math.log10\",function(a){return a?a:function(b){return Math.log(b)/Math.LN10}});q(\"Math.log2\",function(a){return a?a:function(b){return Math.log(b)/Math.LN2}});q(\"Math.sign\",function(a){return a?a:function(b){b=Number(b);return 0===b||isNaN(b)?b:0<b?1:-1}});\nq(\"Math.sinh\",function(a){if(a)return a;var b=Math.exp;return function(c){c=Number(c);return 0===c?c:(b(c)-b(-c))/2}});q(\"Math.tanh\",function(a){return a?a:function(b){b=Number(b);if(0===b)return b;var c=Math.exp(-2*Math.abs(b));c=(1-c)/(1+c);return 0>b?-c:c}});q(\"Math.trunc\",function(a){return a?a:function(b){b=Number(b);if(isNaN(b)||Infinity===b||-Infinity===b||0===b)return b;var c=Math.floor(Math.abs(b));return 0>b?-c:c}});q(\"Number.EPSILON\",function(){return Math.pow(2,-52)});\nq(\"Number.MAX_SAFE_INTEGER\",function(){return 9007199254740991});q(\"Number.MIN_SAFE_INTEGER\",function(){return-9007199254740991});q(\"Number.isFinite\",function(a){return a?a:function(b){return\"number\"!==typeof b?!1:!isNaN(b)&&Infinity!==b&&-Infinity!==b}});q(\"Number.isInteger\",function(a){return a?a:function(b){return Number.isFinite(b)?b===Math.floor(b):!1}});q(\"Number.isNaN\",function(a){return a?a:function(b){return\"number\"===typeof b&&isNaN(b)}});\nq(\"Number.isSafeInteger\",function(a){return a?a:function(b){return Number.isInteger(b)&&Math.abs(b)<=Number.MAX_SAFE_INTEGER}});q(\"Number.parseFloat\",function(a){return a||parseFloat});q(\"Number.parseInt\",function(a){return a||parseInt});var oa=\"function\"==typeof Object.assign?Object.assign:function(a,b){for(var c=1;c<arguments.length;c++){var d=arguments[c];if(d)for(var e in d)t(d,e)&&(a[e]=d[e])}return a};q(\"Object.assign\",function(a){return a||oa});\nq(\"Object.entries\",function(a){return a?a:function(b){var c=[],d;for(d in b)t(b,d)&&c.push([d,b[d]]);return c}});q(\"Object.fromEntries\",function(a){return a?a:function(b){var c={};if(!(Symbol.iterator in b))throw new TypeError(\"\"+b+\" is not iterable\");b=b[Symbol.iterator].call(b);for(var d=b.next();!d.done;d=b.next()){d=d.value;if(Object(d)!==d)throw new TypeError(\"iterable for fromEntries should yield objects\");c[d[0]]=d[1]}return c}});q(\"Reflect\",function(a){return a?a:{}});\nq(\"Object.getOwnPropertySymbols\",function(a){return a?a:function(){return[]}});q(\"Reflect.ownKeys\",function(a){return a?a:function(b){var c=[],d=Object.getOwnPropertyNames(b);b=Object.getOwnPropertySymbols(b);for(var e=0;e<d.length;e++)(\"jscomp_symbol_\"==d[e].substring(0,14)?b:c).push(d[e]);return c.concat(b)}});q(\"Object.getOwnPropertyDescriptors\",function(a){return a?a:function(b){for(var c={},d=Reflect.ownKeys(b),e=0;e<d.length;e++)c[d[e]]=Object.getOwnPropertyDescriptor(b,d[e]);return c}});\nq(\"Object.setPrototypeOf\",function(a){return a||na});q(\"Object.values\",function(a){return a?a:function(b){var c=[],d;for(d in b)t(b,d)&&c.push(b[d]);return c}});q(\"Promise.allSettled\",function(a){function b(d){return{status:\"fulfilled\",value:d}}function c(d){return{status:\"rejected\",reason:d}}return a?a:function(d){var e=this;d=Array.from(d,function(f){return e.resolve(f).then(b,c)});return e.all(d)}});\nq(\"Promise.prototype.finally\",function(a){return a?a:function(b){return this.then(function(c){return Promise.resolve(b()).then(function(){return c})},function(c){return Promise.resolve(b()).then(function(){throw c;})})}});q(\"Reflect.apply\",function(a){if(a)return a;var b=Function.prototype.apply;return function(c,d,e){return b.call(c,d,e)}});\nvar pa=\"function\"==typeof Object.create?Object.create:function(a){function b(){}b.prototype=a;return new b},qa=function(){function a(){function c(){}new c;Reflect.construct(c,[],function(){});return new c instanceof c}if(\"undefined\"!=typeof Reflect&&Reflect.construct){if(a())return Reflect.construct;var b=Reflect.construct;return function(c,d,e){c=b(c,d);e&&Reflect.setPrototypeOf(c,e.prototype);return c}}return function(c,d,e){void 0===e&&(e=c);e=pa(e.prototype||Object.prototype);return Function.prototype.apply.call(c,\ne,d)||e}}();q(\"Reflect.construct\",function(){return qa});q(\"Reflect.defineProperty\",function(a){return a?a:function(b,c,d){try{Object.defineProperty(b,c,d);var e=Object.getOwnPropertyDescriptor(b,c);return e?e.configurable===(d.configurable||!1)&&e.enumerable===(d.enumerable||!1)&&(\"value\"in e?e.value===d.value&&e.writable===(d.writable||!1):e.get===d.get&&e.set===d.set):!1}catch(f){return!1}}});q(\"Reflect.deleteProperty\",function(a){return a?a:function(b,c){if(!t(b,c))return!0;try{return delete b[c]}catch(d){return!1}}});\nq(\"Reflect.getOwnPropertyDescriptor\",function(a){return a||Object.getOwnPropertyDescriptor});q(\"Reflect.getPrototypeOf\",function(a){return a||Object.getPrototypeOf});function ra(a,b){for(;a;){var c=Reflect.getOwnPropertyDescriptor(a,b);if(c)return c;a=Reflect.getPrototypeOf(a)}}q(\"Reflect.get\",function(a){return a?a:function(b,c,d){if(2>=arguments.length)return b[c];var e=ra(b,c);if(e)return e.get?e.get.call(d):e.value}});q(\"Reflect.has\",function(a){return a?a:function(b,c){return c in b}});\nq(\"Reflect.isExtensible\",function(a){return a?a:\"function\"==typeof Object.isExtensible?Object.isExtensible:function(){return!0}});q(\"Reflect.preventExtensions\",function(a){return a?a:\"function\"!=typeof Object.preventExtensions?function(){return!1}:function(b){Object.preventExtensions(b);return!Object.isExtensible(b)}});\nq(\"Reflect.set\",function(a){return a?a:function(b,c,d,e){var f=ra(b,c);return f?f.set?(f.set.call(3<arguments.length?e:b,d),!0):f.writable&&!Object.isFrozen(b)?(b[c]=d,!0):!1:Reflect.isExtensible(b)?(b[c]=d,!0):!1}});q(\"Reflect.setPrototypeOf\",function(a){return a?a:na?function(b,c){try{return na(b,c),!0}catch(d){return!1}}:null});\nq(\"Set\",function(a){function b(c){this.a=new Map;if(c){c=n(c);for(var d;!(d=c.next()).done;)this.add(d.value)}this.size=this.a.size}if(function(){if(!a||\"function\"!=typeof a||!a.prototype.entries||\"function\"!=typeof Object.seal)return!1;try{var c=Object.seal({x:4}),d=new a(n([c]));if(!d.has(c)||1!=d.size||d.add(c)!=d||1!=d.size||d.add({x:4})!=d||2!=d.size)return!1;var e=d.entries(),f=e.next();if(f.done||f.value[0]!=c||f.value[1]!=c)return!1;f=e.next();return f.done||f.value[0]==c||4!=f.value[0].x||\nf.value[1]!=f.value[0]?!1:e.next().done}catch(g){return!1}}())return a;b.prototype.add=function(c){c=0===c?0:c;this.a.set(c,c);this.size=this.a.size;return this};b.prototype.delete=function(c){c=this.a.delete(c);this.size=this.a.size;return c};b.prototype.clear=function(){this.a.clear();this.size=0};b.prototype.has=function(c){return this.a.has(c)};b.prototype.entries=function(){return this.a.entries()};b.prototype.values=function(){return this.a.values()};b.prototype.keys=b.prototype.values;b.prototype[Symbol.iterator]=\nb.prototype.values;b.prototype.forEach=function(c,d){var e=this;this.a.forEach(function(f){return c.call(d,f,f,e)})};return b});q(\"String.prototype.codePointAt\",function(a){return a?a:function(b){var c=r(this,null,\"codePointAt\"),d=c.length;b=Number(b)||0;if(0<=b&&b<d){b|=0;var e=c.charCodeAt(b);if(55296>e||56319<e||b+1===d)return e;b=c.charCodeAt(b+1);return 56320>b||57343<b?e:1024*(e-55296)+b+9216}}});\nq(\"String.fromCodePoint\",function(a){return a?a:function(b){for(var c=\"\",d=0;d<arguments.length;d++){var e=Number(arguments[d]);if(0>e||1114111<e||e!==Math.floor(e))throw new RangeError(\"invalid_code_point \"+e);65535>=e?c+=String.fromCharCode(e):(e-=65536,c+=String.fromCharCode(e>>>10&1023|55296),c+=String.fromCharCode(e&1023|56320))}return c}});\nq(\"String.prototype.matchAll\",function(a){return a?a:function(b){if(b instanceof RegExp&&!b.global)throw new TypeError(\"RegExp passed into String.prototype.matchAll() must have global tag.\");var c=new RegExp(b,b instanceof RegExp?void 0:\"g\"),d=this,e=!1,f={next:function(){var g={},h=c.lastIndex;if(e)return{value:void 0,done:!0};var k=c.exec(d);if(!k)return e=!0,{value:void 0,done:!0};c.lastIndex===h&&(c.lastIndex+=1);g.value=k;g.done=!1;return g}};f[Symbol.iterator]=function(){return f};return f}});\nfunction sa(a,b){a=void 0!==a?String(a):\" \";return 0<b&&a?a.repeat(Math.ceil(b/a.length)).substring(0,b):\"\"}q(\"String.prototype.padEnd\",function(a){return a?a:function(b,c){var d=r(this,null,\"padStart\");return d+sa(c,b-d.length)}});q(\"String.prototype.padStart\",function(a){return a?a:function(b,c){var d=r(this,null,\"padStart\");return sa(c,b-d.length)+d}});q(\"String.prototype.trimRight\",function(a){function b(){return this.replace(/[\\s\\xa0]+$/,\"\")}return a||b});\nq(\"String.prototype.trimEnd\",function(a){return a||String.prototype.trimRight});\nq(\"WeakSet\",function(a){function b(c){this.a=new WeakMap;if(c){c=n(c);for(var d;!(d=c.next()).done;)this.add(d.value)}}if(function(){if(!a||!Object.seal)return!1;try{var c=Object.seal({}),d=Object.seal({}),e=new a([c]);if(!e.has(c)||e.has(d))return!1;e.delete(c);e.add(d);return!e.has(c)&&e.has(d)}catch(f){return!1}}())return a;b.prototype.add=function(c){this.a.set(c,!0);return this};b.prototype.has=function(c){return this.a.has(c)};b.prototype.delete=function(c){return this.a.delete(c)};return b});\nvar u=this||self,ta=/^[\\w+/_-]+[=]{0,2}$/,wa=null;function xa(a){return(a=a.querySelector&&a.querySelector(\"script[nonce]\"))&&(a=a.nonce||a.getAttribute(\"nonce\"))&&ta.test(a)?a:\"\"}function v(a){a=a.split(\".\");for(var b=u,c=0;c<a.length;c++)if(b=b[a[c]],null==b)return null;return b}function w(){}function ya(a){var b=typeof a;return\"object\"!=b?b:a?Array.isArray(a)?\"array\":b:\"null\"}function y(a){return\"function\"==ya(a)}function za(a){var b=typeof a;return\"object\"==b&&null!=a||\"function\"==b}\nfunction Aa(a,b,c){return a.call.apply(a.bind,arguments)}function Ba(a,b,c){if(!a)throw Error();if(2<arguments.length){var d=Array.prototype.slice.call(arguments,2);return function(){var e=Array.prototype.slice.call(arguments);Array.prototype.unshift.apply(e,d);return a.apply(b,e)}}return function(){return a.apply(b,arguments)}}function z(a,b,c){Function.prototype.bind&&-1!=Function.prototype.bind.toString().indexOf(\"native code\")?z=Aa:z=Ba;return z.apply(null,arguments)}\nfunction B(a,b){a=a.split(\".\");var c=u;a[0]in c||\"undefined\"==typeof c.execScript||c.execScript(\"var \"+a[0]);for(var d;a.length&&(d=a.shift());)a.length||void 0===b?c[d]&&c[d]!==Object.prototype[d]?c=c[d]:c=c[d]={}:c[d]=b}function C(a,b){function c(){}c.prototype=b.prototype;a.prototype=new c;a.prototype.constructor=a}function Ca(a){return a};function D(a){if(Error.captureStackTrace)Error.captureStackTrace(this,D);else{var b=Error().stack;b&&(this.stack=b)}a&&(this.message=String(a))}C(D,Error);D.prototype.name=\"CustomError\";function E(a,b){this.a=a===Da&&b||\"\";this.b=Ea}E.prototype.O=!0;E.prototype.M=function(){return this.a};function Fa(a){return a instanceof E&&a.constructor===E&&a.b===Ea?a.a:\"type_error:Const\"}function F(a){return new E(Da,a)}var Ea={},Da={};var H={f:{}};\nH.f.I={ha:{\"gstatic.com\":{loader:F(\"https://www.gstatic.com/charts/%{version}/loader.js\"),debug:F(\"https://www.gstatic.com/charts/debug/%{version}/js/jsapi_debug_%{package}_module.js\"),debug_i18n:F(\"https://www.gstatic.com/charts/debug/%{version}/i18n/jsapi_debug_i18n_%{package}_module__%{language}.js\"),compiled:F(\"https://www.gstatic.com/charts/%{version}/js/jsapi_compiled_%{package}_module.js\"),compiled_i18n:F(\"https://www.gstatic.com/charts/%{version}/i18n/jsapi_compiled_i18n_%{package}_module__%{language}.js\"),css:F(\"https://www.gstatic.com/charts/%{version}/css/%{subdir}/%{filename}\"),\ncss2:F(\"https://www.gstatic.com/charts/%{version}/css/%{subdir1}/%{subdir2}/%{filename}\"),third_party:F(\"https://www.gstatic.com/charts/%{version}/third_party/%{subdir}/%{filename}\"),third_party2:F(\"https://www.gstatic.com/charts/%{version}/third_party/%{subdir1}/%{subdir2}/%{filename}\"),third_party_gen:F(\"https://www.gstatic.com/charts/%{version}/third_party/%{subdir}/%{filename}\")},\"gstatic.cn\":{loader:F(\"https://www.gstatic.cn/charts/%{version}/loader.js\"),debug:F(\"https://www.gstatic.cn/charts/debug/%{version}/js/jsapi_debug_%{package}_module.js\"),\ndebug_i18n:F(\"https://www.gstatic.cn/charts/debug/%{version}/i18n/jsapi_debug_i18n_%{package}_module__%{language}.js\"),compiled:F(\"https://www.gstatic.cn/charts/%{version}/js/jsapi_compiled_%{package}_module.js\"),compiled_i18n:F(\"https://www.gstatic.cn/charts/%{version}/i18n/jsapi_compiled_i18n_%{package}_module__%{language}.js\"),css:F(\"https://www.gstatic.cn/charts/%{version}/css/%{subdir}/%{filename}\"),css2:F(\"https://www.gstatic.cn/charts/%{version}/css/%{subdir1}/%{subdir2}/%{filename}\"),third_party:F(\"https://www.gstatic.cn/charts/%{version}/third_party/%{subdir}/%{filename}\"),\nthird_party2:F(\"https://www.gstatic.cn/charts/%{version}/third_party/%{subdir1}/%{subdir2}/%{filename}\"),third_party_gen:F(\"https://www.gstatic.cn/charts/%{version}/third_party/%{subdir}/%{filename}\")}},Y:[\"default\"],na:{\"default\":[],graphics:[\"default\"],ui:[\"graphics\"],ui_base:[\"graphics\"],flashui:[\"ui\"],fw:[\"ui\"],geo:[\"ui\"],annotatedtimeline:[\"annotationchart\"],annotationchart:[\"ui\",\"controls\",\"corechart\",\"table\"],areachart:\"browserchart\",bar:[\"fw\",\"dygraph\",\"webfontloader\"],barchart:\"browserchart\",\nbrowserchart:[\"ui\"],bubbles:[\"fw\",\"d3\"],calendar:[\"fw\"],charteditor:\"ui corechart imagechart annotatedtimeline gauge geochart motionchart orgchart table\".split(\" \"),charteditor_base:\"ui_base corechart imagechart annotatedtimeline gauge geochart motionchart orgchart table_base\".split(\" \"),circles:[\"fw\",\"d3\"],clusterchart:[\"corechart\",\"d3\"],columnchart:\"browserchart\",controls:[\"ui\"],controls_base:[\"ui_base\"],corechart:[\"ui\"],gantt:[\"fw\",\"dygraph\"],gauge:[\"ui\"],geochart:[\"geo\"],geomap:[\"flashui\",\"geo\"],\ngeomap_base:[\"ui_base\"],heatmap:[\"vegachart\"],helloworld:[\"fw\"],imagechart:[\"ui\"],imageareachart:\"imagechart\",imagebarchart:\"imagechart\",imagelinechart:\"imagechart\",imagepiechart:\"imagechart\",imagesparkline:\"imagechart\",line:[\"fw\",\"dygraph\",\"webfontloader\"],linechart:\"browserchart\",map:[\"geo\"],motionchart:[\"flashui\"],orgchart:[\"ui\"],overtimecharts:[\"ui\",\"corechart\"],piechart:\"browserchart\",sankey:[\"fw\",\"d3\",\"d3.sankey\"],scatter:[\"fw\",\"dygraph\",\"webfontloader\"],scatterchart:\"browserchart\",sunburst:[\"fw\",\n\"d3\"],streamgraph:[\"fw\",\"d3\"],table:[\"ui\"],table_base:[\"ui_base\"],timeline:[\"fw\",\"ui\",\"dygraph\"],treemap:[\"ui\"],vegachart:[\"graphics\"],wordtree:[\"ui\"]},Ha:{d3:{subdir1:\"d3\",subdir2:\"v5\",filename:\"d3.js\"},\"d3.sankey\":{subdir1:\"d3_sankey\",subdir2:\"v4\",filename:\"d3.sankey.js\"},webfontloader:{subdir:\"webfontloader\",filename:\"webfont.js\"}},Ga:{dygraph:{subdir:\"dygraphs\",filename:\"dygraph-tickers-combined.js\"}},ma:{\"default\":[{subdir:\"core\",filename:\"tooltip.css\"}],annotationchart:[{subdir:\"annotationchart\",\nfilename:\"annotationchart.css\"}],charteditor:[{subdir:\"charteditor\",filename:\"charteditor.css\"}],charteditor_base:[{subdir:\"charteditor_base\",filename:\"charteditor_base.css\"}],controls:[{subdir:\"controls\",filename:\"controls.css\"}],imagesparkline:[{subdir:\"imagechart\",filename:\"imagesparkline.css\"}],orgchart:[{subdir:\"orgchart\",filename:\"orgchart.css\"}],table:[{subdir:\"table\",filename:\"table.css\"},{subdir:\"util\",filename:\"format.css\"}],table_base:[{subdir:\"util\",filename:\"format.css\"},{subdir:\"table\",\nfilename:\"table_base.css\"}],ui:[{subdir:\"util\",filename:\"util.css\"}],ui_base:[{subdir:\"util\",filename:\"util_base.css\"}]}};H.f.V={$:{\"chrome-frame\":{versions:{\"1.0.0\":{uncompressed:\"CFInstall.js\",compressed:\"CFInstall.min.js\"},\"1.0.1\":{uncompressed:\"CFInstall.js\",compressed:\"CFInstall.min.js\"},\"1.0.2\":{uncompressed:\"CFInstall.js\",compressed:\"CFInstall.min.js\"}},aliases:{1:\"1.0.2\",\"1.0\":\"1.0.2\"}},swfobject:{versions:{\"2.1\":{uncompressed:\"swfobject_src.js\",compressed:\"swfobject.js\"},\"2.2\":{uncompressed:\"swfobject_src.js\",compressed:\"swfobject.js\"}},aliases:{2:\"2.2\"}},\"ext-core\":{versions:{\"3.1.0\":{uncompressed:\"ext-core-debug.js\",\ncompressed:\"ext-core.js\"},\"3.0.0\":{uncompressed:\"ext-core-debug.js\",compressed:\"ext-core.js\"}},aliases:{3:\"3.1.0\",\"3.0\":\"3.0.0\",\"3.1\":\"3.1.0\"}},scriptaculous:{versions:{\"1.8.3\":{uncompressed:\"scriptaculous.js\",compressed:\"scriptaculous.js\"},\"1.9.0\":{uncompressed:\"scriptaculous.js\",compressed:\"scriptaculous.js\"},\"1.8.1\":{uncompressed:\"scriptaculous.js\",compressed:\"scriptaculous.js\"},\"1.8.2\":{uncompressed:\"scriptaculous.js\",compressed:\"scriptaculous.js\"}},aliases:{1:\"1.9.0\",\"1.8\":\"1.8.3\",\"1.9\":\"1.9.0\"}},\nwebfont:{versions:{\"1.0.12\":{uncompressed:\"webfont_debug.js\",compressed:\"webfont.js\"},\"1.0.13\":{uncompressed:\"webfont_debug.js\",compressed:\"webfont.js\"},\"1.0.14\":{uncompressed:\"webfont_debug.js\",compressed:\"webfont.js\"},\"1.0.15\":{uncompressed:\"webfont_debug.js\",compressed:\"webfont.js\"},\"1.0.10\":{uncompressed:\"webfont_debug.js\",compressed:\"webfont.js\"},\"1.0.11\":{uncompressed:\"webfont_debug.js\",compressed:\"webfont.js\"},\"1.0.27\":{uncompressed:\"webfont_debug.js\",compressed:\"webfont.js\"},\"1.0.28\":{uncompressed:\"webfont_debug.js\",\ncompressed:\"webfont.js\"},\"1.0.29\":{uncompressed:\"webfont_debug.js\",compressed:\"webfont.js\"},\"1.0.23\":{uncompressed:\"webfont_debug.js\",compressed:\"webfont.js\"},\"1.0.24\":{uncompressed:\"webfont_debug.js\",compressed:\"webfont.js\"},\"1.0.25\":{uncompressed:\"webfont_debug.js\",compressed:\"webfont.js\"},\"1.0.26\":{uncompressed:\"webfont_debug.js\",compressed:\"webfont.js\"},\"1.0.21\":{uncompressed:\"webfont_debug.js\",compressed:\"webfont.js\"},\"1.0.22\":{uncompressed:\"webfont_debug.js\",compressed:\"webfont.js\"},\"1.0.3\":{uncompressed:\"webfont_debug.js\",\ncompressed:\"webfont.js\"},\"1.0.4\":{uncompressed:\"webfont_debug.js\",compressed:\"webfont.js\"},\"1.0.5\":{uncompressed:\"webfont_debug.js\",compressed:\"webfont.js\"},\"1.0.6\":{uncompressed:\"webfont_debug.js\",compressed:\"webfont.js\"},\"1.0.9\":{uncompressed:\"webfont_debug.js\",compressed:\"webfont.js\"},\"1.0.16\":{uncompressed:\"webfont_debug.js\",compressed:\"webfont.js\"},\"1.0.17\":{uncompressed:\"webfont_debug.js\",compressed:\"webfont.js\"},\"1.0.0\":{uncompressed:\"webfont_debug.js\",compressed:\"webfont.js\"},\"1.0.18\":{uncompressed:\"webfont_debug.js\",\ncompressed:\"webfont.js\"},\"1.0.1\":{uncompressed:\"webfont_debug.js\",compressed:\"webfont.js\"},\"1.0.19\":{uncompressed:\"webfont_debug.js\",compressed:\"webfont.js\"},\"1.0.2\":{uncompressed:\"webfont_debug.js\",compressed:\"webfont.js\"}},aliases:{1:\"1.0.29\",\"1.0\":\"1.0.29\"}},jqueryui:{versions:{\"1.8.17\":{uncompressed:\"jquery-ui.js\",compressed:\"jquery-ui.min.js\"},\"1.8.16\":{uncompressed:\"jquery-ui.js\",compressed:\"jquery-ui.min.js\"},\"1.8.15\":{uncompressed:\"jquery-ui.js\",compressed:\"jquery-ui.min.js\"},\"1.8.14\":{uncompressed:\"jquery-ui.js\",\ncompressed:\"jquery-ui.min.js\"},\"1.8.4\":{uncompressed:\"jquery-ui.js\",compressed:\"jquery-ui.min.js\"},\"1.8.13\":{uncompressed:\"jquery-ui.js\",compressed:\"jquery-ui.min.js\"},\"1.8.5\":{uncompressed:\"jquery-ui.js\",compressed:\"jquery-ui.min.js\"},\"1.8.12\":{uncompressed:\"jquery-ui.js\",compressed:\"jquery-ui.min.js\"},\"1.8.6\":{uncompressed:\"jquery-ui.js\",compressed:\"jquery-ui.min.js\"},\"1.8.11\":{uncompressed:\"jquery-ui.js\",compressed:\"jquery-ui.min.js\"},\"1.8.7\":{uncompressed:\"jquery-ui.js\",compressed:\"jquery-ui.min.js\"},\n\"1.8.10\":{uncompressed:\"jquery-ui.js\",compressed:\"jquery-ui.min.js\"},\"1.8.8\":{uncompressed:\"jquery-ui.js\",compressed:\"jquery-ui.min.js\"},\"1.8.9\":{uncompressed:\"jquery-ui.js\",compressed:\"jquery-ui.min.js\"},\"1.6.0\":{uncompressed:\"jquery-ui.js\",compressed:\"jquery-ui.min.js\"},\"1.7.0\":{uncompressed:\"jquery-ui.js\",compressed:\"jquery-ui.min.js\"},\"1.5.2\":{uncompressed:\"jquery-ui.js\",compressed:\"jquery-ui.min.js\"},\"1.8.0\":{uncompressed:\"jquery-ui.js\",compressed:\"jquery-ui.min.js\"},\"1.7.1\":{uncompressed:\"jquery-ui.js\",\ncompressed:\"jquery-ui.min.js\"},\"1.5.3\":{uncompressed:\"jquery-ui.js\",compressed:\"jquery-ui.min.js\"},\"1.8.1\":{uncompressed:\"jquery-ui.js\",compressed:\"jquery-ui.min.js\"},\"1.7.2\":{uncompressed:\"jquery-ui.js\",compressed:\"jquery-ui.min.js\"},\"1.8.2\":{uncompressed:\"jquery-ui.js\",compressed:\"jquery-ui.min.js\"},\"1.7.3\":{uncompressed:\"jquery-ui.js\",compressed:\"jquery-ui.min.js\"}},aliases:{1:\"1.8.17\",\"1.5\":\"1.5.3\",\"1.6\":\"1.6.0\",\"1.7\":\"1.7.3\",\"1.8\":\"1.8.17\",\"1.8.3\":\"1.8.4\"}},mootools:{versions:{\"1.3.0\":{uncompressed:\"mootools.js\",\ncompressed:\"mootools-yui-compressed.js\"},\"1.2.1\":{uncompressed:\"mootools.js\",compressed:\"mootools-yui-compressed.js\"},\"1.1.2\":{uncompressed:\"mootools.js\",compressed:\"mootools-yui-compressed.js\"},\"1.4.0\":{uncompressed:\"mootools.js\",compressed:\"mootools-yui-compressed.js\"},\"1.3.1\":{uncompressed:\"mootools.js\",compressed:\"mootools-yui-compressed.js\"},\"1.2.2\":{uncompressed:\"mootools.js\",compressed:\"mootools-yui-compressed.js\"},\"1.4.1\":{uncompressed:\"mootools.js\",compressed:\"mootools-yui-compressed.js\"},\n\"1.3.2\":{uncompressed:\"mootools.js\",compressed:\"mootools-yui-compressed.js\"},\"1.2.3\":{uncompressed:\"mootools.js\",compressed:\"mootools-yui-compressed.js\"},\"1.4.2\":{uncompressed:\"mootools.js\",compressed:\"mootools-yui-compressed.js\"},\"1.2.4\":{uncompressed:\"mootools.js\",compressed:\"mootools-yui-compressed.js\"},\"1.2.5\":{uncompressed:\"mootools.js\",compressed:\"mootools-yui-compressed.js\"},\"1.1.1\":{uncompressed:\"mootools.js\",compressed:\"mootools-yui-compressed.js\"}},aliases:{1:\"1.1.2\",\"1.1\":\"1.1.2\",\"1.2\":\"1.2.5\",\n\"1.3\":\"1.3.2\",\"1.4\":\"1.4.2\",\"1.11\":\"1.1.1\"}},yui:{versions:{\"2.8.0r4\":{uncompressed:\"build/yuiloader/yuiloader.js\",compressed:\"build/yuiloader/yuiloader-min.js\"},\"2.9.0\":{uncompressed:\"build/yuiloader/yuiloader.js\",compressed:\"build/yuiloader/yuiloader-min.js\"},\"2.8.1\":{uncompressed:\"build/yuiloader/yuiloader.js\",compressed:\"build/yuiloader/yuiloader-min.js\"},\"2.6.0\":{uncompressed:\"build/yuiloader/yuiloader.js\",compressed:\"build/yuiloader/yuiloader-min.js\"},\"2.7.0\":{uncompressed:\"build/yuiloader/yuiloader.js\",\ncompressed:\"build/yuiloader/yuiloader-min.js\"},\"3.3.0\":{uncompressed:\"build/yui/yui.js\",compressed:\"build/yui/yui-min.js\"},\"2.8.2r1\":{uncompressed:\"build/yuiloader/yuiloader.js\",compressed:\"build/yuiloader/yuiloader-min.js\"}},aliases:{2:\"2.9.0\",\"2.6\":\"2.6.0\",\"2.7\":\"2.7.0\",\"2.8\":\"2.8.2r1\",\"2.8.0\":\"2.8.0r4\",\"2.8.2\":\"2.8.2r1\",\"2.9\":\"2.9.0\",3:\"3.3.0\",\"3.3\":\"3.3.0\"}},prototype:{versions:{\"1.6.1.0\":{uncompressed:\"prototype.js\",compressed:\"prototype.js\"},\"1.6.0.2\":{uncompressed:\"prototype.js\",compressed:\"prototype.js\"},\n\"1.7.0.0\":{uncompressed:\"prototype.js\",compressed:\"prototype.js\"},\"1.6.0.3\":{uncompressed:\"prototype.js\",compressed:\"prototype.js\"}},aliases:{1:\"1.7.0.0\",\"1.6\":\"1.6.1.0\",\"1.6.0\":\"1.6.0.3\",\"1.6.1\":\"1.6.1.0\",\"1.7\":\"1.7.0.0\",\"1.7.0\":\"1.7.0.0\"}},jquery:{versions:{\"1.2.3\":{uncompressed:\"jquery.js\",compressed:\"jquery.min.js\"},\"1.2.6\":{uncompressed:\"jquery.js\",compressed:\"jquery.min.js\"},\"1.3.0\":{uncompressed:\"jquery.js\",compressed:\"jquery.min.js\"},\"1.3.1\":{uncompressed:\"jquery.js\",compressed:\"jquery.min.js\"},\n\"1.3.2\":{uncompressed:\"jquery.js\",compressed:\"jquery.min.js\"},\"1.4.0\":{uncompressed:\"jquery.js\",compressed:\"jquery.min.js\"},\"1.4.1\":{uncompressed:\"jquery.js\",compressed:\"jquery.min.js\"},\"1.4.2\":{uncompressed:\"jquery.js\",compressed:\"jquery.min.js\"},\"1.4.3\":{uncompressed:\"jquery.js\",compressed:\"jquery.min.js\"},\"1.4.4\":{uncompressed:\"jquery.js\",compressed:\"jquery.min.js\"},\"1.5.0\":{uncompressed:\"jquery.js\",compressed:\"jquery.min.js\"},\"1.5.1\":{uncompressed:\"jquery.js\",compressed:\"jquery.min.js\"},\"1.5.2\":{uncompressed:\"jquery.js\",\ncompressed:\"jquery.min.js\"},\"1.6.0\":{uncompressed:\"jquery.js\",compressed:\"jquery.min.js\"},\"1.6.1\":{uncompressed:\"jquery.js\",compressed:\"jquery.min.js\"},\"1.6.2\":{uncompressed:\"jquery.js\",compressed:\"jquery.min.js\"},\"1.6.3\":{uncompressed:\"jquery.js\",compressed:\"jquery.min.js\"},\"1.6.4\":{uncompressed:\"jquery.js\",compressed:\"jquery.min.js\"},\"1.7.0\":{uncompressed:\"jquery.js\",compressed:\"jquery.min.js\"},\"1.7.1\":{uncompressed:\"jquery.js\",compressed:\"jquery.min.js\"}},aliases:{1:\"1.7.1\",\"1.2\":\"1.2.6\",\"1.3\":\"1.3.2\",\n\"1.4\":\"1.4.4\",\"1.5\":\"1.5.2\",\"1.6\":\"1.6.4\",\"1.7\":\"1.7.1\"}},dojo:{versions:{\"1.3.0\":{uncompressed:\"dojo/dojo.xd.js.uncompressed.js\",compressed:\"dojo/dojo.xd.js\"},\"1.4.0\":{uncompressed:\"dojo/dojo.xd.js.uncompressed.js\",compressed:\"dojo/dojo.xd.js\"},\"1.3.1\":{uncompressed:\"dojo/dojo.xd.js.uncompressed.js\",compressed:\"dojo/dojo.xd.js\"},\"1.5.0\":{uncompressed:\"dojo/dojo.xd.js.uncompressed.js\",compressed:\"dojo/dojo.xd.js\"},\"1.4.1\":{uncompressed:\"dojo/dojo.xd.js.uncompressed.js\",compressed:\"dojo/dojo.xd.js\"},\n\"1.3.2\":{uncompressed:\"dojo/dojo.xd.js.uncompressed.js\",compressed:\"dojo/dojo.xd.js\"},\"1.2.3\":{uncompressed:\"dojo/dojo.xd.js.uncompressed.js\",compressed:\"dojo/dojo.xd.js\"},\"1.6.0\":{uncompressed:\"dojo/dojo.xd.js.uncompressed.js\",compressed:\"dojo/dojo.xd.js\"},\"1.5.1\":{uncompressed:\"dojo/dojo.xd.js.uncompressed.js\",compressed:\"dojo/dojo.xd.js\"},\"1.7.0\":{uncompressed:\"dojo/dojo.js.uncompressed.js\",compressed:\"dojo/dojo.js\"},\"1.6.1\":{uncompressed:\"dojo/dojo.xd.js.uncompressed.js\",compressed:\"dojo/dojo.xd.js\"},\n\"1.4.3\":{uncompressed:\"dojo/dojo.xd.js.uncompressed.js\",compressed:\"dojo/dojo.xd.js\"},\"1.7.1\":{uncompressed:\"dojo/dojo.js.uncompressed.js\",compressed:\"dojo/dojo.js\"},\"1.7.2\":{uncompressed:\"dojo/dojo.js.uncompressed.js\",compressed:\"dojo/dojo.js\"},\"1.2.0\":{uncompressed:\"dojo/dojo.xd.js.uncompressed.js\",compressed:\"dojo/dojo.xd.js\"},\"1.1.1\":{uncompressed:\"dojo/dojo.xd.js.uncompressed.js\",compressed:\"dojo/dojo.xd.js\"}},aliases:{1:\"1.6.1\",\"1.1\":\"1.1.1\",\"1.2\":\"1.2.3\",\"1.3\":\"1.3.2\",\"1.4\":\"1.4.3\",\"1.5\":\"1.5.1\",\n\"1.6\":\"1.6.1\",\"1.7\":\"1.7.2\"}}}};H.f.W={af:!0,am:!0,az:!0,ar:!0,arb:\"ar\",bg:!0,bn:!0,ca:!0,cs:!0,cmn:\"zh\",da:!0,de:!0,el:!0,en:!0,en_gb:!0,es:!0,es_419:!0,et:!0,eu:!0,fa:!0,fi:!0,fil:!0,fr:!0,fr_ca:!0,gl:!0,ka:!0,gu:!0,he:\"iw\",hi:!0,hr:!0,hu:!0,hy:!0,id:!0,\"in\":\"id\",is:!0,it:!0,iw:!0,ja:!0,ji:\"yi\",jv:!1,jw:\"jv\",km:!0,kn:!0,ko:!0,lo:!0,lt:!0,lv:!0,ml:!0,mn:!0,mo:\"ro\",mr:!0,ms:!0,nb:\"no\",ne:!0,nl:!0,no:!0,pl:!0,pt:\"pt_br\",pt_br:!0,pt_pt:!0,ro:!0,ru:!0,si:!0,sk:!0,sl:!0,sr:!0,sv:!0,sw:!0,swh:\"sw\",ta:!0,te:!0,th:!0,tl:\"fil\",tr:!0,uk:!0,\nur:!0,vi:!0,yi:!1,zh:\"zh_cn\",zh_cn:!0,zh_hk:!0,zh_tw:!0,zsm:\"ms\",zu:!0};var Ga=Array.prototype.forEach?function(a,b,c){Array.prototype.forEach.call(a,b,c)}:function(a,b,c){for(var d=a.length,e=\"string\"===typeof a?a.split(\"\"):a,f=0;f<d;f++)f in e&&b.call(c,e[f],f,a)},Ha=Array.prototype.map?function(a,b){return Array.prototype.map.call(a,b,void 0)}:function(a,b){for(var c=a.length,d=Array(c),e=\"string\"===typeof a?a.split(\"\"):a,f=0;f<c;f++)f in e&&(d[f]=b.call(void 0,e[f],f,a));return d},Ia=Array.prototype.some?function(a,b){return Array.prototype.some.call(a,b,void 0)}:\nfunction(a,b){for(var c=a.length,d=\"string\"===typeof a?a.split(\"\"):a,e=0;e<c;e++)if(e in d&&b.call(void 0,d[e],e,a))return!0;return!1};function Ja(a){return Array.prototype.concat.apply([],arguments)}function Ka(a){var b=a.length;if(0<b){for(var c=Array(b),d=0;d<b;d++)c[d]=a[d];return c}return[]}\nfunction La(a,b){for(var c=1;c<arguments.length;c++){var d=arguments[c],e=ya(d);if(\"array\"==e||\"object\"==e&&\"number\"==typeof d.length){e=a.length||0;var f=d.length||0;a.length=e+f;for(var g=0;g<f;g++)a[e+g]=d[g]}else a.push(d)}};var Ma;function I(a,b){this.a=a===Na&&b||\"\";this.b=Oa}I.prototype.O=!0;I.prototype.M=function(){return this.a.toString()};function Pa(a){return a instanceof I&&a.constructor===I&&a.b===Oa?a.a:\"type_error:TrustedResourceUrl\"}\nfunction Qa(a,b){var c=Fa(a);if(!Ra.test(c))throw Error(\"Invalid TrustedResourceUrl format: \"+c);a=c.replace(Sa,function(d,e){if(!Object.prototype.hasOwnProperty.call(b,e))throw Error('Found marker, \"'+e+'\", in format string, \"'+c+'\", but no valid label mapping found in args: '+JSON.stringify(b));d=b[e];return d instanceof E?Fa(d):encodeURIComponent(String(d))});return Ta(a)}var Sa=/%{(\\w+)}/g,Ra=/^((https:)?\\/\\/[0-9a-z.:[\\]-]+\\/|\\/[^/\\\\]|[^:/\\\\%]+\\/|[^:/\\\\%]*[?#]|about:blank#)/i,Ua=/^([^?#]*)(\\?[^#]*)?(#[\\s\\S]*)?/;\nfunction Va(a,b,c){a=Qa(a,b);a=Ua.exec(Pa(a).toString());b=a[3]||\"\";return Ta(a[1]+Wa(\"?\",a[2]||\"\",c)+Wa(\"#\",b,void 0))}var Oa={};function Ta(a){if(void 0===Ma){var b=null;var c=u.trustedTypes;if(c&&c.createPolicy){try{b=c.createPolicy(\"goog#html\",{createHTML:Ca,createScript:Ca,createScriptURL:Ca})}catch(d){u.console&&u.console.error(d.message)}Ma=b}else Ma=b}a=(b=Ma)?b.createScriptURL(a):a;return new I(Na,a)}\nfunction Wa(a,b,c){if(null==c)return b;if(\"string\"===typeof c)return c?a+encodeURIComponent(c):\"\";for(var d in c)if(Object.prototype.hasOwnProperty.call(c,d)){var e=c[d];e=Array.isArray(e)?e:[e];for(var f=0;f<e.length;f++){var g=e[f];null!=g&&(b||(b=a),b+=(b.length>a.length?\"&\":\"\")+encodeURIComponent(d)+\"=\"+encodeURIComponent(String(g)))}}return b}var Na={};var Xa=String.prototype.trim?function(a){return a.trim()}:function(a){return/^[\\s\\xa0]*([\\s\\S]*?)[\\s\\xa0]*$/.exec(a)[1]};function Ya(a,b){return a<b?-1:a>b?1:0};var J;a:{var Za=u.navigator;if(Za){var $a=Za.userAgent;if($a){J=$a;break a}}J=\"\"}function K(a){return-1!=J.indexOf(a)};function ab(a,b){for(var c in a)b.call(void 0,a[c],c,a)}var bb=\"constructor hasOwnProperty isPrototypeOf propertyIsEnumerable toLocaleString toString valueOf\".split(\" \");function cb(a,b){for(var c,d,e=1;e<arguments.length;e++){d=arguments[e];for(c in d)a[c]=d[c];for(var f=0;f<bb.length;f++)c=bb[f],Object.prototype.hasOwnProperty.call(d,c)&&(a[c]=d[c])}};function db(a,b){a.src=Pa(b);(b=a.ownerDocument&&a.ownerDocument.defaultView)&&b!=u?b=xa(b.document):(null===wa&&(wa=xa(u.document)),b=wa);b&&a.setAttribute(\"nonce\",b)};function eb(a){var b=fb;return Object.prototype.hasOwnProperty.call(b,11)?b[11]:b[11]=a(11)};var gb=K(\"Opera\"),hb=K(\"Trident\")||K(\"MSIE\"),ib=K(\"Edge\"),jb=K(\"Gecko\")&&!(-1!=J.toLowerCase().indexOf(\"webkit\")&&!K(\"Edge\"))&&!(K(\"Trident\")||K(\"MSIE\"))&&!K(\"Edge\"),kb=-1!=J.toLowerCase().indexOf(\"webkit\")&&!K(\"Edge\"),lb;\na:{var mb=\"\",nb=function(){var a=J;if(jb)return/rv:([^\\);]+)(\\)|;)/.exec(a);if(ib)return/Edge\\/([\\d\\.]+)/.exec(a);if(hb)return/\\b(?:MSIE|rv)[: ]([^\\);]+)(\\)|;)/.exec(a);if(kb)return/WebKit\\/(\\S+)/.exec(a);if(gb)return/(?:Version)[ \\/]?(\\S+)/.exec(a)}();nb&&(mb=nb?nb[1]:\"\");if(hb){var ob,pb=u.document;ob=pb?pb.documentMode:void 0;if(null!=ob&&ob>parseFloat(mb)){lb=String(ob);break a}}lb=mb}var qb=lb,fb={};\nfunction rb(){return eb(function(){for(var a=0,b=Xa(String(qb)).split(\".\"),c=Xa(\"11\").split(\".\"),d=Math.max(b.length,c.length),e=0;0==a&&e<d;e++){var f=b[e]||\"\",g=c[e]||\"\";do{f=/(\\d*)(\\D*)(.*)/.exec(f)||[\"\",\"\",\"\",\"\"];g=/(\\d*)(\\D*)(.*)/.exec(g)||[\"\",\"\",\"\",\"\"];if(0==f[0].length&&0==g[0].length)break;a=Ya(0==f[1].length?0:parseInt(f[1],10),0==g[1].length?0:parseInt(g[1],10))||Ya(0==f[2].length,0==g[2].length)||Ya(f[2],g[2]);f=f[3];g=g[3]}while(0==a)}return 0<=a})};function sb(a,b){ab(b,function(c,d){c&&\"object\"==typeof c&&c.O&&(c=c.M());\"style\"==d?a.style.cssText=c:\"class\"==d?a.className=c:\"for\"==d?a.htmlFor=c:tb.hasOwnProperty(d)?a.setAttribute(tb[d],c):0==d.lastIndexOf(\"aria-\",0)||0==d.lastIndexOf(\"data-\",0)?a.setAttribute(d,c):a[d]=c})}\nvar tb={cellpadding:\"cellPadding\",cellspacing:\"cellSpacing\",colspan:\"colSpan\",frameborder:\"frameBorder\",height:\"height\",maxlength:\"maxLength\",nonce:\"nonce\",role:\"role\",rowspan:\"rowSpan\",type:\"type\",usemap:\"useMap\",valign:\"vAlign\",width:\"width\"};function ub(a){var b=document;a=String(a);\"application/xhtml+xml\"===b.contentType&&(a=a.toLowerCase());return b.createElement(a)};function vb(a,b){this.c=a;this.g=b;this.b=0;this.a=null}vb.prototype.get=function(){if(0<this.b){this.b--;var a=this.a;this.a=a.next;a.next=null}else a=this.c();return a};function wb(a,b){a.g(b);100>a.b&&(a.b++,b.next=a.a,a.a=b)};function xb(a){u.setTimeout(function(){throw a;},0)}var yb;\nfunction zb(){var a=u.MessageChannel;\"undefined\"===typeof a&&\"undefined\"!==typeof window&&window.postMessage&&window.addEventListener&&!K(\"Presto\")&&(a=function(){var e=ub(\"IFRAME\");e.style.display=\"none\";document.documentElement.appendChild(e);var f=e.contentWindow;e=f.document;e.open();e.close();var g=\"callImmediate\"+Math.random(),h=\"file:\"==f.location.protocol?\"*\":f.location.protocol+\"//\"+f.location.host;e=z(function(k){if((\"*\"==h||k.origin==h)&&k.data==g)this.port1.onmessage()},this);f.addEventListener(\"message\",\ne,!1);this.port1={};this.port2={postMessage:function(){f.postMessage(g,h)}}});if(\"undefined\"!==typeof a&&!K(\"Trident\")&&!K(\"MSIE\")){var b=new a,c={},d=c;b.port1.onmessage=function(){if(void 0!==c.next){c=c.next;var e=c.L;c.L=null;e()}};return function(e){d.next={L:e};d=d.next;b.port2.postMessage(0)}}return function(e){u.setTimeout(e,0)}};function Ab(){this.b=this.a=null}var Cb=new vb(function(){return new Bb},function(a){a.reset()});Ab.prototype.add=function(a,b){var c=Cb.get();c.set(a,b);this.b?this.b.next=c:this.a=c;this.b=c};function Db(){var a=Eb,b=null;a.a&&(b=a.a,a.a=a.a.next,a.a||(a.b=null),b.next=null);return b}function Bb(){this.next=this.b=this.a=null}Bb.prototype.set=function(a,b){this.a=a;this.b=b;this.next=null};Bb.prototype.reset=function(){this.next=this.b=this.a=null};function Fb(a,b){Gb||Hb();Ib||(Gb(),Ib=!0);Eb.add(a,b)}var Gb;function Hb(){if(u.Promise&&u.Promise.resolve){var a=u.Promise.resolve(void 0);Gb=function(){a.then(Jb)}}else Gb=function(){var b=Jb;!y(u.setImmediate)||u.Window&&u.Window.prototype&&!K(\"Edge\")&&u.Window.prototype.setImmediate==u.setImmediate?(yb||(yb=zb()),yb(b)):u.setImmediate(b)}}var Ib=!1,Eb=new Ab;function Jb(){for(var a;a=Db();){try{a.a.call(a.b)}catch(b){xb(b)}wb(Cb,a)}Ib=!1};function Kb(a){if(!a)return!1;try{return!!a.$goog_Thenable}catch(b){return!1}};function L(a){this.a=0;this.j=void 0;this.g=this.b=this.c=null;this.h=this.i=!1;if(a!=w)try{var b=this;a.call(void 0,function(c){M(b,2,c)},function(c){M(b,3,c)})}catch(c){M(this,3,c)}}function Lb(){this.next=this.c=this.b=this.g=this.a=null;this.h=!1}Lb.prototype.reset=function(){this.c=this.b=this.g=this.a=null;this.h=!1};var Mb=new vb(function(){return new Lb},function(a){a.reset()});function Nb(a,b,c){var d=Mb.get();d.g=a;d.b=b;d.c=c;return d}\nL.prototype.then=function(a,b,c){return Ob(this,y(a)?a:null,y(b)?b:null,c)};L.prototype.$goog_Thenable=!0;L.prototype.cancel=function(a){if(0==this.a){var b=new N(a);Fb(function(){Pb(this,b)},this)}};function Pb(a,b){if(0==a.a)if(a.c){var c=a.c;if(c.b){for(var d=0,e=null,f=null,g=c.b;g&&(g.h||(d++,g.a==a&&(e=g),!(e&&1<d)));g=g.next)e||(f=g);e&&(0==c.a&&1==d?Pb(c,b):(f?(d=f,d.next==c.g&&(c.g=d),d.next=d.next.next):Qb(c),Rb(c,e,3,b)))}a.c=null}else M(a,3,b)}\nfunction Sb(a,b){a.b||2!=a.a&&3!=a.a||Tb(a);a.g?a.g.next=b:a.b=b;a.g=b}function Ob(a,b,c,d){var e=Nb(null,null,null);e.a=new L(function(f,g){e.g=b?function(h){try{var k=b.call(d,h);f(k)}catch(l){g(l)}}:f;e.b=c?function(h){try{var k=c.call(d,h);void 0===k&&h instanceof N?g(h):f(k)}catch(l){g(l)}}:g});e.a.c=a;Sb(a,e);return e.a}L.prototype.A=function(a){this.a=0;M(this,2,a)};L.prototype.B=function(a){this.a=0;M(this,3,a)};\nfunction M(a,b,c){if(0==a.a){a===c&&(b=3,c=new TypeError(\"Promise cannot resolve to itself\"));a.a=1;a:{var d=c,e=a.A,f=a.B;if(d instanceof L){Sb(d,Nb(e||w,f||null,a));var g=!0}else if(Kb(d))d.then(e,f,a),g=!0;else{if(za(d))try{var h=d.then;if(y(h)){Ub(d,h,e,f,a);g=!0;break a}}catch(k){f.call(a,k);g=!0;break a}g=!1}}g||(a.j=c,a.a=b,a.c=null,Tb(a),3!=b||c instanceof N||Vb(a,c))}}\nfunction Ub(a,b,c,d,e){function f(k){h||(h=!0,d.call(e,k))}function g(k){h||(h=!0,c.call(e,k))}var h=!1;try{b.call(a,g,f)}catch(k){f(k)}}function Tb(a){a.i||(a.i=!0,Fb(a.m,a))}function Qb(a){var b=null;a.b&&(b=a.b,a.b=b.next,b.next=null);a.b||(a.g=null);return b}L.prototype.m=function(){for(var a;a=Qb(this);)Rb(this,a,this.a,this.j);this.i=!1};\nfunction Rb(a,b,c,d){if(3==c&&b.b&&!b.h)for(;a&&a.h;a=a.c)a.h=!1;if(b.a)b.a.c=null,Wb(b,c,d);else try{b.h?b.g.call(b.c):Wb(b,c,d)}catch(e){Xb.call(null,e)}wb(Mb,b)}function Wb(a,b,c){2==b?a.g.call(a.c,c):a.b&&a.b.call(a.c,c)}function Vb(a,b){a.h=!0;Fb(function(){a.h&&Xb.call(null,b)})}var Xb=xb;function N(a){D.call(this,a)}C(N,D);N.prototype.name=\"cancel\";/*\n Portions of this code are from MochiKit, received by\n The Closure Authors under the MIT license. All other code is Copyright\n 2005-2009 The Closure Authors. All Rights Reserved.\n*/\nfunction O(a,b){this.h=[];this.F=a;this.H=b||null;this.g=this.a=!1;this.c=void 0;this.A=this.U=this.j=!1;this.i=0;this.b=null;this.m=0}O.prototype.cancel=function(a){if(this.a)this.c instanceof O&&this.c.cancel();else{if(this.b){var b=this.b;delete this.b;a?b.cancel(a):(b.m--,0>=b.m&&b.cancel())}this.F?this.F.call(this.H,this):this.A=!0;this.a||(a=new P(this),Q(this),R(this,!1,a))}};O.prototype.B=function(a,b){this.j=!1;R(this,a,b)};function R(a,b,c){a.a=!0;a.c=c;a.g=!b;Yb(a)}\nfunction Q(a){if(a.a){if(!a.A)throw new Zb(a);a.A=!1}}function $b(a,b,c,d){a.h.push([b,c,d]);a.a&&Yb(a);return a}O.prototype.then=function(a,b,c){var d,e,f=new L(function(g,h){d=g;e=h});$b(this,d,function(g){g instanceof P?f.cancel():e(g)});return f.then(a,b,c)};O.prototype.$goog_Thenable=!0;function ac(a){return Ia(a.h,function(b){return y(b[1])})}\nfunction Yb(a){if(a.i&&a.a&&ac(a)){var b=a.i,c=bc[b];c&&(u.clearTimeout(c.a),delete bc[b]);a.i=0}a.b&&(a.b.m--,delete a.b);b=a.c;for(var d=c=!1;a.h.length&&!a.j;){var e=a.h.shift(),f=e[0],g=e[1];e=e[2];if(f=a.g?g:f)try{var h=f.call(e||a.H,b);void 0!==h&&(a.g=a.g&&(h==b||h instanceof Error),a.c=b=h);if(Kb(b)||\"function\"===typeof u.Promise&&b instanceof u.Promise)d=!0,a.j=!0}catch(k){b=k,a.g=!0,ac(a)||(c=!0)}}a.c=b;d&&(h=z(a.B,a,!0),d=z(a.B,a,!1),b instanceof O?($b(b,h,d),b.U=!0):b.then(h,d));c&&(b=\nnew cc(b),bc[b.a]=b,a.i=b.a)}function dc(){var a=new O;Q(a);R(a,!0,null);return a}function Zb(){D.call(this)}C(Zb,D);Zb.prototype.message=\"Deferred has already fired\";Zb.prototype.name=\"AlreadyCalledError\";function P(){D.call(this)}C(P,D);P.prototype.message=\"Deferred was canceled\";P.prototype.name=\"CanceledError\";function cc(a){this.a=u.setTimeout(z(this.c,this),0);this.b=a}cc.prototype.c=function(){delete bc[this.a];throw this.b;};var bc={};var ec,fc=[];function gc(a,b){function c(){var e=a.shift();e=hc(e,b);a.length&&$b(e,c,c,void 0);return e}if(!a.length)return dc();var d=fc.length;La(fc,a);if(d)return ec;a=fc;return ec=c()}\nfunction hc(a,b){var c=b||{};b=c.document||document;var d=Pa(a).toString(),e=ub(\"SCRIPT\"),f={P:e,S:void 0},g=new O(ic,f),h=null,k=null!=c.timeout?c.timeout:5E3;0<k&&(h=window.setTimeout(function(){jc(e,!0);var l=new kc(1,\"Timeout reached for loading script \"+d);Q(g);R(g,!1,l)},k),f.S=h);e.onload=e.onreadystatechange=function(){e.readyState&&\"loaded\"!=e.readyState&&\"complete\"!=e.readyState||(jc(e,c.la||!1,h),Q(g),R(g,!0,null))};e.onerror=function(){jc(e,!0,h);var l=new kc(0,\"Error while loading script \"+\nd);Q(g);R(g,!1,l)};f=c.attributes||{};cb(f,{type:\"text/javascript\",charset:\"UTF-8\"});sb(e,f);db(e,a);lc(b).appendChild(e);return g}function lc(a){var b;return(b=(a||document).getElementsByTagName(\"HEAD\"))&&0!=b.length?b[0]:a.documentElement}function ic(){if(this&&this.P){var a=this.P;a&&\"SCRIPT\"==a.tagName&&jc(a,!0,this.S)}}function jc(a,b,c){null!=c&&u.clearTimeout(c);a.onload=w;a.onerror=w;a.onreadystatechange=w;b&&window.setTimeout(function(){a&&a.parentNode&&a.parentNode.removeChild(a)},0)}\nfunction kc(a,b){var c=\"Jsloader error (code #\"+a+\")\";b&&(c+=\": \"+b);D.call(this,c);this.code=a}C(kc,D);H.f.o={};var mc=hc,oc=nc;function pc(a){return Va(a.format,a.K,a.ea||{})}function nc(a,b,c){c=c||{};a=Va(a,b,c);var d=mc(a,{timeout:3E4,attributes:{async:!1,defer:!1}});return new Promise(function(e){$b(d,e,null,void 0)})}H.f.o.Ca=function(a){nc=a};H.f.o.Fa=function(a){mc=a};H.f.o.Z=pc;H.f.o.load=oc;\nH.f.o.ua=function(a){a=Ha(a,pc);if(0==a.length)return Promise.resolve();var b={timeout:3E4,attributes:{async:!1,defer:!1}},c=[];!hb||rb()?Ga(a,function(d){c.push(mc(d,b))}):c.push(gc(a,b));return Promise.all(Ha(c,function(d){return new Promise(function(e){return $b(d,e,null,void 0)})}))};H.f.o.wa=function(a,b,c){return{format:a,K:b,ea:c}};H.f.v={};var S={};H.f.v.oa=function(a){return S[a]&&S[a].loaded};H.f.v.pa=function(a){return S[a]&&S[a].ga};H.f.v.aa=function(){return new Promise(function(a){\"undefined\"==typeof window||\"complete\"===document.readyState?a():window.addEventListener?(document.addEventListener(\"DOMContentLoaded\",a,!0),window.addEventListener(\"load\",a,!0)):window.attachEvent?window.attachEvent(\"onload\",a):\"function\"!==typeof window.onload?window.onload=a:window.onload=function(b){window.onload(b);a()}})};H.f.v.va=S;\nH.f.v.Ba=function(){S={}};H.f.v.Da=function(a){S[a]||(S[a]={loaded:!1});S[a].loaded=!0};H.f.v.Ea=function(a,b){S[a]={ga:b,loaded:!1}};H.f.J={1:\"1.0\",\"1.0\":\"current\",\"1.1\":\"upcoming\",\"1.2\":\"testing\",41:\"pre-45\",42:\"pre-45\",43:\"pre-45\",44:\"pre-45\",46:\"46.1\",\"46.1\":\"46.2\",48:\"48.1\",current:\"48\",upcoming:\"49\",testing:\"49\"};function qc(a,b){this.b={};this.a=[];this.c=0;var c=arguments.length;if(1<c){if(c%2)throw Error(\"Uneven number of arguments\");for(var d=0;d<c;d+=2)this.set(arguments[d],arguments[d+1])}else if(a)if(a instanceof qc)for(c=a.C(),d=0;d<c.length;d++)this.set(c[d],a.get(c[d]));else for(d in a)this.set(d,a[d])}m=qc.prototype;m.D=function(){rc(this);for(var a=[],b=0;b<this.a.length;b++)a.push(this.b[this.a[b]]);return a};m.C=function(){rc(this);return this.a.concat()};\nfunction rc(a){if(a.c!=a.a.length){for(var b=0,c=0;b<a.a.length;){var d=a.a[b];T(a.b,d)&&(a.a[c++]=d);b++}a.a.length=c}if(a.c!=a.a.length){var e={};for(c=b=0;b<a.a.length;)d=a.a[b],T(e,d)||(a.a[c++]=d,e[d]=1),b++;a.a.length=c}}m.get=function(a,b){return T(this.b,a)?this.b[a]:b};m.set=function(a,b){T(this.b,a)||(this.c++,this.a.push(a));this.b[a]=b};m.forEach=function(a,b){for(var c=this.C(),d=0;d<c.length;d++){var e=c[d],f=this.get(e);a.call(b,f,e,this)}};\nfunction T(a,b){return Object.prototype.hasOwnProperty.call(a,b)};var sc=/^(?:([^:/?#.]+):)?(?:\\/\\/(?:([^\\\\/?#]*)@)?([^\\\\/?#]*?)(?::([0-9]+))?(?=[\\\\/?#]|$))?([^?#]+)?(?:\\?([^#]*))?(?:#([\\s\\S]*))?$/;function tc(a,b){if(a){a=a.split(\"&\");for(var c=0;c<a.length;c++){var d=a[c].indexOf(\"=\"),e=null;if(0<=d){var f=a[c].substring(0,d);e=a[c].substring(d+1)}else f=a[c];b(f,e?decodeURIComponent(e.replace(/\\+/g,\" \")):\"\")}}};function uc(a){this.a=this.j=this.g=\"\";this.m=null;this.h=this.b=\"\";this.i=!1;var b;a instanceof uc?(this.i=a.i,vc(this,a.g),this.j=a.j,this.a=a.a,wc(this,a.m),this.b=a.b,xc(this,yc(a.c)),this.h=a.h):a&&(b=String(a).match(sc))?(this.i=!1,vc(this,b[1]||\"\",!0),this.j=zc(b[2]||\"\"),this.a=zc(b[3]||\"\",!0),wc(this,b[4]),this.b=zc(b[5]||\"\",!0),xc(this,b[6]||\"\",!0),this.h=zc(b[7]||\"\")):(this.i=!1,this.c=new U(null,this.i))}\nuc.prototype.toString=function(){var a=[],b=this.g;b&&a.push(Ac(b,Bc,!0),\":\");var c=this.a;if(c||\"file\"==b)a.push(\"//\"),(b=this.j)&&a.push(Ac(b,Bc,!0),\"@\"),a.push(encodeURIComponent(String(c)).replace(/%25([0-9a-fA-F]{2})/g,\"%$1\")),c=this.m,null!=c&&a.push(\":\",String(c));if(c=this.b)this.a&&\"/\"!=c.charAt(0)&&a.push(\"/\"),a.push(Ac(c,\"/\"==c.charAt(0)?Cc:Dc,!0));(c=this.c.toString())&&a.push(\"?\",c);(c=this.h)&&a.push(\"#\",Ac(c,Ec));return a.join(\"\")};\nuc.prototype.resolve=function(a){var b=new uc(this),c=!!a.g;c?vc(b,a.g):c=!!a.j;c?b.j=a.j:c=!!a.a;c?b.a=a.a:c=null!=a.m;var d=a.b;if(c)wc(b,a.m);else if(c=!!a.b){if(\"/\"!=d.charAt(0))if(this.a&&!this.b)d=\"/\"+d;else{var e=b.b.lastIndexOf(\"/\");-1!=e&&(d=b.b.substr(0,e+1)+d)}e=d;if(\"..\"==e||\".\"==e)d=\"\";else if(-1!=e.indexOf(\"./\")||-1!=e.indexOf(\"/.\")){d=0==e.lastIndexOf(\"/\",0);e=e.split(\"/\");for(var f=[],g=0;g<e.length;){var h=e[g++];\".\"==h?d&&g==e.length&&f.push(\"\"):\"..\"==h?((1<f.length||1==f.length&&\n\"\"!=f[0])&&f.pop(),d&&g==e.length&&f.push(\"\")):(f.push(h),d=!0)}d=f.join(\"/\")}else d=e}c?b.b=d:c=\"\"!==a.c.toString();c?xc(b,yc(a.c)):c=!!a.h;c&&(b.h=a.h);return b};function vc(a,b,c){a.g=c?zc(b,!0):b;a.g&&(a.g=a.g.replace(/:$/,\"\"))}function wc(a,b){if(b){b=Number(b);if(isNaN(b)||0>b)throw Error(\"Bad port number \"+b);a.m=b}else a.m=null}function xc(a,b,c){b instanceof U?(a.c=b,Fc(a.c,a.i)):(c||(b=Ac(b,Gc)),a.c=new U(b,a.i))}\nfunction zc(a,b){return a?b?decodeURI(a.replace(/%25/g,\"%2525\")):decodeURIComponent(a):\"\"}function Ac(a,b,c){return\"string\"===typeof a?(a=encodeURI(a).replace(b,Hc),c&&(a=a.replace(/%25([0-9a-fA-F]{2})/g,\"%$1\")),a):null}function Hc(a){a=a.charCodeAt(0);return\"%\"+(a>>4&15).toString(16)+(a&15).toString(16)}var Bc=/[#\\/\\?@]/g,Dc=/[#\\?:]/g,Cc=/[#\\?]/g,Gc=/[#\\?@]/g,Ec=/#/g;function U(a,b){this.b=this.a=null;this.c=a||null;this.g=!!b}\nfunction V(a){a.a||(a.a=new qc,a.b=0,a.c&&tc(a.c,function(b,c){a.add(decodeURIComponent(b.replace(/\\+/g,\" \")),c)}))}m=U.prototype;m.add=function(a,b){V(this);this.c=null;a=W(this,a);var c=this.a.get(a);c||this.a.set(a,c=[]);c.push(b);this.b+=1;return this};function Ic(a,b){V(a);b=W(a,b);T(a.a.b,b)&&(a.c=null,a.b-=a.a.get(b).length,a=a.a,T(a.b,b)&&(delete a.b[b],a.c--,a.a.length>2*a.c&&rc(a)))}function Jc(a,b){V(a);b=W(a,b);return T(a.a.b,b)}\nm.forEach=function(a,b){V(this);this.a.forEach(function(c,d){Ga(c,function(e){a.call(b,e,d,this)},this)},this)};m.C=function(){V(this);for(var a=this.a.D(),b=this.a.C(),c=[],d=0;d<b.length;d++)for(var e=a[d],f=0;f<e.length;f++)c.push(b[d]);return c};m.D=function(a){V(this);var b=[];if(\"string\"===typeof a)Jc(this,a)&&(b=Ja(b,this.a.get(W(this,a))));else{a=this.a.D();for(var c=0;c<a.length;c++)b=Ja(b,a[c])}return b};\nm.set=function(a,b){V(this);this.c=null;a=W(this,a);Jc(this,a)&&(this.b-=this.a.get(a).length);this.a.set(a,[b]);this.b+=1;return this};m.get=function(a,b){if(!a)return b;a=this.D(a);return 0<a.length?String(a[0]):b};m.toString=function(){if(this.c)return this.c;if(!this.a)return\"\";for(var a=[],b=this.a.C(),c=0;c<b.length;c++){var d=b[c],e=encodeURIComponent(String(d));d=this.D(d);for(var f=0;f<d.length;f++){var g=e;\"\"!==d[f]&&(g+=\"=\"+encodeURIComponent(String(d[f])));a.push(g)}}return this.c=a.join(\"&\")};\nfunction yc(a){var b=new U;b.c=a.c;a.a&&(b.a=new qc(a.a),b.b=a.b);return b}function W(a,b){b=String(b);a.g&&(b=b.toLowerCase());return b}function Fc(a,b){b&&!a.g&&(V(a),a.c=null,a.a.forEach(function(c,d){var e=d.toLowerCase();d!=e&&(Ic(this,d),Ic(this,e),0<c.length&&(this.c=null,this.a.set(W(this,e),Ka(c)),this.b+=c.length))},a));a.g=b};H.f.u={};var X=\"\",Y=\"\",Kc,Z,Lc=null,Mc;function Nc(){Y=X=\"\";Lc=Z=Kc=null;v(\"google.load\")||(B(\"google.load\",Oc),B(\"google.setOnLoadCallback\",H.R));var a=document.getElementsByTagName(\"script\");a=(document.currentScript||a[a.length-1]).getAttribute(\"src\");a=new uc(a);var b=a.a;Mc=b=b.match(/^www\\.gstatic\\.cn/)?\"gstatic.cn\":\"gstatic.com\";Pc(a)}\nfunction Pc(a){a=new U(a.c.toString());var b=a.get(\"callback\");\"string\"===typeof b&&(b=Qc(b),H.f.v.aa().then(b));a=a.get(\"autoload\");if(\"string\"===typeof a)try{if(\"\"!==a){var c=JSON.parse(a).modules;for(a=0;a<c.length;a++){var d=c[a];Oc(d.name,d.version,d)}}}catch(e){throw Error(\"Autoload failed with: \"+e);}}\nfunction Rc(a){var b=a,c,d=a.match(/^testing-/);d&&(b=b.replace(/^testing-/,\"\"));a=b;do{if(b===H.f.J[b])throw Error(\"Infinite loop in version mapping: \"+b);(c=H.f.J[b])&&(b=c)}while(c);c=(d?\"testing-\":\"\")+b;return{version:\"pre-45\"==b?a:c,ba:c}}\nfunction Sc(a){var b=H.f.I.ha[Mc].loader,c=Rc(a);return H.f.o.load(b,{version:c.ba}).then(function(){var d=v(\"google.charts.loader.VersionSpecific.load\")||v(\"google.charts.loader.publicLoad\")||v(\"google.charts.versionSpecific.load\");if(!d)throw Error(\"Bad version: \"+a);Lc=function(e){e=d(c.version,e);if(null==e||null==e.then){var f=v(\"google.charts.loader.publicSetOnLoadCallback\")||v(\"google.charts.versionSpecific.setOnLoadCallback\");e=new Promise(function(g){f(g)});e.then=f}return e}})}\nfunction Tc(a){\"string\"===typeof a&&(a=[a]);Array.isArray(a)&&0!==a.length||(a=H.f.I.Y);var b=[];a.forEach(function(c){c=c.toLowerCase();b=b.concat(c.split(/[\\s,]+\\s*/))});return b}function Uc(a){a=a||\"\";for(var b=a.replace(/-/g,\"_\").toLowerCase();\"string\"===typeof b;)a=b,b=H.f.W[b],b===a&&(b=!1);b||(a.match(/_[^_]+$/)?(a=a.replace(/_[^_]+$/,\"\"),a=Uc(a)):a=\"en\");return a}\nfunction Vc(a){a=a||\"\";\"\"!==X&&X!==a&&(console.warn(\" Attempting to load version '\"+a+\"' of Google Charts, but the previously loaded '\"+(X+\"' will be used instead.\")),a=X);return X=a||\"\"}function Wc(a){a=a||\"\";\"\"!==Y&&Y!==a&&(console.warn(\" Attempting to load Google Charts for language '\"+a+\"', but the previously loaded '\"+(Y+\"' will be used instead.\")),a=Y);\"en\"===a&&(a=\"\");return Y=a||\"\"}function Xc(a){var b={},c;for(c in a)b[c]=a[c];return b}\nfunction Yc(a,b){b=Xc(b);b.domain=Mc;b.callback=Qc(b.callback);a=Vc(a);var c=b.language;c=Wc(Uc(c));b.language=c;if(!Kc){if(b.enableUrlSettings&&window.URLSearchParams)try{a=(new URLSearchParams(top.location.search)).get(\"charts-version\")||a}catch(d){console.info(\"Failed to get charts-version from top URL\",d)}Kc=Sc(a)}b.packages=Tc(b.packages);return Z=Kc.then(function(){return Lc(b)})}H.ia=function(a){return H.load(Object.assign({},a,{safeMode:!0}))};B(\"google.charts.safeLoad\",H.ia);\nH.load=function(a){for(var b=[],c=0;c<arguments.length;++c)b[c]=arguments[c];c=0;\"visualization\"===b[c]&&c++;var d=\"current\";if(\"string\"===typeof b[c]||\"number\"===typeof b[c])d=String(b[c]),c++;var e={};za(b[c])&&(e=b[c]);return Yc(d,e)};B(\"google.charts.load\",H.load);H.R=function(a){if(!Z)throw Error(\"Must call google.charts.load before google.charts.setOnLoadCallback\");return a?Z.then(a):Z};B(\"google.charts.setOnLoadCallback\",H.R);\nvar Zc=F(\"https://maps.googleapis.com/maps/api/js?jsapiRedirect=true\"),$c=F(\"https://maps-api-ssl.google.com/maps?jsapiRedirect=true&file=googleapi\");\nfunction ad(a,b,c){console.warn(\"Loading Maps API with the jsapi loader is deprecated.\");c=c||{};a=c.key||c.client;var d=c.libraries,e=function(h){for(var k={},l=0;l<h.length;l++){var p=h[l];k[p[0]]=p[1]}return k}(c.other_params?c.other_params.split(\"&\").map(function(h){return h.split(\"=\")}):[]),f=Object.assign({},{key:a,sa:d},e),g=\"2\"===b?$c:Zc;Z=new Promise(function(h){var k=Qc(c&&c.callback);H.f.o.load(g,{},f).then(k).then(h)})}var bd=F(\"https://www.gstatic.com/inputtools/js/ita/inputtools_3.js\");\nfunction cd(a,b,c){za(c)&&c.packages?(Array.isArray(c.packages)?c.packages:[c.packages]).includes(\"inputtools\")?(console.warn('Loading \"elements\" with the jsapi loader is deprecated.\\nPlease load '+(bd+\" directly.\")),Z=new Promise(function(d){var e=Qc(c&&c.callback);H.f.o.load(bd,{},{}).then(e).then(d)})):console.error('Loading \"elements\" other than \"inputtools\" is unsupported.'):console.error(\"google.load of elements was invoked without specifying packages\")}var dd=F(\"https://ajax.googleapis.com/ajax/libs/%{module}/%{version}/%{file}\");\nfunction ed(a,b){var c;do{if(a===b[a])throw Error(\"Infinite loop in version mapping for version \"+a);(c=b[a])&&(a=c)}while(c);return a}\nfunction fd(a,b,c){var d=H.f.V.$[a];if(d){b=ed(b,d.aliases);d=d.versions[b];if(!d)throw Error(\"Unknown version, \"+b+\", of \"+a+\".\");var e={module:a,version:b||\"\",file:d.compressed};b=Pa(H.f.o.Z({format:dd,K:e})).toString();console.warn(\"Loading modules with the jsapi loader is deprecated.\\nPlease load \"+(a+\" directly from \"+b+\".\"));Z=new Promise(function(f){var g=Qc(c&&c.callback);H.f.o.load(dd,e).then(g).then(f)})}else setTimeout(function(){throw Error('Module \"'+a+'\" is not supported.');},0)}\nfunction Qc(a){return function(){if(\"function\"===typeof a)a();else if(\"string\"===typeof a&&\"\"!==a)try{var b=v(a);if(\"function\"!==typeof b)throw Error(\"Type of '\"+a+\"' is \"+typeof b+\".\");b()}catch(c){throw Error(\"Callback of \"+a+\" failed with: \"+c);}}}function Oc(a){for(var b=[],c=0;c<arguments.length;++c)b[c]=arguments[c];switch(b[0]){case \"maps\":ad.apply(null,ba(b));break;case \"elements\":cd.apply(null,ba(b));break;case \"visualization\":H.load.apply(H,ba(b));break;default:fd.apply(null,ba(b))}}\nB(\"google.loader.LoadFailure\",!1);Mc?console.warn(\"Google Charts loader.js should only be loaded once.\"):Nc();H.f.u.ra=Nc;H.f.u.xa=Rc;H.f.u.ya=Uc;H.f.u.za=Tc;H.f.u.Ja=Vc;H.f.u.Ia=Wc;H.f.u.Aa=Pc;H.f.u.qa=function(){return Lc};}).call(this);"
  },
  {
    "path": "cmd/internal/pages/assets/styles/containers.css",
    "content": "\n.google-visualization-toolbar{font-size:100%}.google-visualization-toolbar .google-visualization-toolbar-export-igoogle,.google-visualization-toolbar .google-visualization-toolbar-export-data,.google-visualization-toolbar .google-visualization-toolbar-html-code{margin-right:.1em}.google-visualization-toolbar-html-code-explanation{font-weight:bold}.google-visualization-toolbar-ok-button{padding:2px}.google-visualization-toolbar-triangle{position:absolute;right:0;top:0}.google-visualization-toolbar-caption-table{width:100%;padding:0;margin:0;border:0;border-collapse:collapse}.google-visualization-toolbar-small-dialog{width:500px}.google-visualization-toolbar-big-dialog{width:800px}.google-visualization-toolbar-small-dialog,.google-visualization-toolbar-big-dialog{position:absolute;background-color:#c1d9ff;border:1px solid #3a5774;padding:8px}.google-visualization-toolbar-small-dialog-bg,.google-visualization-toolbar-big-dialog-bg{background-color:#ddd;position:absolute;top:0;left:0}.google-visualization-toolbar-small-dialog-title,.google-visualization-toolbar-big-dialog-title{background-color:#e0edfe;color:#000;cursor:pointer;padding:8px;position:relative;font-size:12pt;font-weight:bold;vertical-align:middle}.google-visualization-toolbar-small-dialog-content,.google-visualization-toolbar-big-dialog-content{background-color:#fff;padding:4px;font-weight:normal;overflow:auto}.google-visualization-toolbar-small-dialog-title-close,.google-visualization-toolbar-big-dialog-title-close{background:transparent url(close_box.gif) no-repeat scroll center;height:15px;position:absolute;right:10px;top:8px;width:15px}.google-visualization-toolbar-small-dialog-content iframe,.google-visualization-toolbar-big-dialog-content iframe{width:500px;height:700px;border:1px solid black}.charts-inline-block{position:relative;display:-moz-inline-box;display:inline-block}* html .charts-inline-block,*:first-child+html .charts-inline-block{display:inline}.charts-menu{background:#fff;border-color:#ccc #666 #666 #ccc;border-style:solid;border-width:1px;cursor:default;font:normal 13px Arial,sans-serif;margin:0;outline:none;padding:4px 0;position:absolute;z-index:20000}.charts-menu-button{background:#ddd url(//ssl.gstatic.com/editor/button-bg.png) repeat-x top left;border:0;color:#000;cursor:pointer;list-style:none;margin:2px;outline:none;padding:0;text-decoration:none;vertical-align:middle}.charts-menu-button-outer-box,.charts-menu-button-inner-box{border-style:solid;border-color:#aaa;vertical-align:top}.charts-menu-button-outer-box{margin:0;border-width:1px 0;padding:0}.charts-menu-button-inner-box{margin:0 -1px;border-width:0 1px;padding:3px 4px}* html .charts-menu-button-inner-box{left:-1px}* html .charts-menu-button-rtl .charts-menu-button-outer-box{left:-1px;right:auto}* html .charts-menu-button-rtl .charts-menu-button-inner-box{right:auto}*:first-child+html .charts-menu-button-inner-box{left:-1px}*:first-child+html .charts-menu-button-rtl .charts-menu-button-inner-box{left:1px;right:auto}::root .charts-menu-button{line-height:0}::root .charts-menu-button-outer-box{line-height:0}::root .charts-menu-button-inner-box{line-height:0}::root .charts-menu-button-caption{line-height:normal}::root .charts-menu-button-dropdown{line-height:normal}.charts-menu-button-disabled{background-image:none!important;opacity:.3;-moz-opacity:.3;filter:alpha(opacity=30)}.charts-menu-button-disabled .charts-menu-button-outer-box,.charts-menu-button-disabled .charts-menu-button-inner-box,.charts-menu-button-disabled .charts-menu-button-caption,.charts-menu-button-disabled .charts-menu-button-dropdown{color:#333!important;border-color:#999!important}* html .charts-menu-button-disabled,*:first-child+html .charts-menu-button-disabled{margin:2px 1px!important;padding:0 1px!important}.charts-menu-button-hover .charts-menu-button-outer-box,.charts-menu-button-hover .charts-menu-button-inner-box{border-color:#9cf #69e #69e #7af!important}.charts-menu-button-active,.charts-menu-button-open{background-color:#bbb;background-position:bottom left}.charts-menu-button-focused .charts-menu-button-outer-box,.charts-menu-button-focused .charts-menu-button-inner-box{border-color:orange}.charts-menu-button-caption{padding:0 4px 0 0;vertical-align:top}.charts-menu-button-dropdown{height:15px;width:7px;background:url(//ssl.gstatic.com/editor/editortoolbar.png) no-repeat -388px 0;vertical-align:top}.charts-menu-button-collapse-right,.charts-menu-button-collapse-right .charts-menu-button-outer-box,.charts-menu-button-collapse-right .charts-menu-button-inner-box{margin-right:0}.charts-menu-button-collapse-left,.charts-menu-button-collapse-left .charts-menu-button-outer-box{margin-left:0}.charts-menu-button-collapse-left .charts-menu-button-inner-box{margin-left:0;border-left:1px solid #fff}.charts-menu-button-collapse-left.charts-menu-button-checked .charts-menu-button-inner-box{border-left:1px solid #ddd}.charts-menuitem{color:#000;font:normal 13px Arial,sans-serif;list-style:none;margin:0;padding:4px 7em 4px 28px;white-space:nowrap}.charts-menuitem.charts-menuitem-rtl{padding-left:7em;padding-right:28px}.charts-menu-nocheckbox .charts-menuitem,.charts-menu-noicon .charts-menuitem{padding-left:12px}.charts-menu-noaccel .charts-menuitem{padding-right:20px}.charts-menuitem-content{color:#000;font:normal 13px Arial,sans-serif}.charts-menuitem-disabled .charts-menuitem-accel,.charts-menuitem-disabled .charts-menuitem-content{color:#ccc!important}.charts-menuitem-disabled .charts-menuitem-icon{opacity:.3;-moz-opacity:.3;filter:alpha(opacity=30)}.charts-menuitem-highlight,.charts-menuitem-hover{background-color:#d6e9f8;border-color:#d6e9f8;border-style:dotted;border-width:1px 0;padding-bottom:3px;padding-top:3px}.charts-menuitem-checkbox,.charts-menuitem-icon{background-repeat:no-repeat;height:16px;left:6px;position:absolute;right:auto;vertical-align:middle;width:16px}.charts-menuitem-rtl .charts-menuitem-checkbox,.charts-menuitem-rtl .charts-menuitem-icon{left:auto;right:6px}.charts-option-selected .charts-menuitem-checkbox,.charts-option-selected .charts-menuitem-icon{background:url(//ssl.gstatic.com/editor/editortoolbar.png) no-repeat -512px 0}.charts-menuitem-accel{color:#999;direction:ltr;left:auto;padding:0 6px;position:absolute;right:0;text-align:right}.charts-menuitem-rtl .charts-menuitem-accel{left:0;right:auto;text-align:left}.charts-menuitem-mnemonic-hint{text-decoration:underline}.charts-menuitem-mnemonic-separator{color:#999;font-size:12px;padding-left:4px}\n\n.stat-label {\n    font-weight:bold;\n}\n.unit-label {\n    color:#888888;\n    font-style:italic;\n}\n.active-cpu {\n    font-weight:bold;\n    color:#000000;\n}\n.inactive-cpu {\n    color:#888888;\n}\n.raw-stats {\n    font-family: \"Courier New\";\n    white-space: pre-wrap;\n}\n.isolation-title {\n    color:#FFFFFF;\n}\n.page-header h1 {\n    word-wrap: break-word;\n}\n.table-row {\n    font-family: \"courier\", \"monospace\";\n    font-size: 15px;\n    text-align: right;\n    vertical-align: top;\n    border: 5px;\n    margin-left: 3px;\n    margin-right: 3px;\n    margin-top: 3px;\n    margin-bottom: 3px;\n}\n.subcontainer-display-input {\n    margin-left: 4px;\n    width: 40px;\n}\n#logo {\n    float:left;\n    height: 200px;\n    margin-top: 20px;\n    background-repeat: no-repeat;\n    background-size: contain;\n    background-position: center;\n    background-image:url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAB7UAAANiCAIAAACB2Qp3AAAKSWlDQ1BzUkdCIElFQzYxOTY2LTIuMQAAeNqdU3dYk/cWPt/3ZQ9WQtjwsZdsgQAiI6wIyBBZohCSAGGEEBJAxYWIClYUFRGcSFXEgtUKSJ2I4qAouGdBiohai1VcOO4f3Ke1fXrv7e371/u855zn/M55zw+AERImkeaiagA5UoU8Otgfj09IxMm9gAIVSOAEIBDmy8JnBcUAAPADeXh+dLA//AGvbwACAHDVLiQSx+H/g7pQJlcAIJEA4CIS5wsBkFIAyC5UyBQAyBgAsFOzZAoAlAAAbHl8QiIAqg0A7PRJPgUA2KmT3BcA2KIcqQgAjQEAmShHJAJAuwBgVYFSLALAwgCgrEAiLgTArgGAWbYyRwKAvQUAdo5YkA9AYACAmUIszAAgOAIAQx4TzQMgTAOgMNK/4KlfcIW4SAEAwMuVzZdL0jMUuJXQGnfy8ODiIeLCbLFCYRcpEGYJ5CKcl5sjE0jnA0zODAAAGvnRwf44P5Dn5uTh5mbnbO/0xaL+a/BvIj4h8d/+vIwCBAAQTs/v2l/l5dYDcMcBsHW/a6lbANpWAGjf+V0z2wmgWgrQevmLeTj8QB6eoVDIPB0cCgsL7SViob0w44s+/zPhb+CLfvb8QB7+23rwAHGaQJmtwKOD/XFhbnauUo7nywRCMW735yP+x4V//Y4p0eI0sVwsFYrxWIm4UCJNx3m5UpFEIcmV4hLpfzLxH5b9CZN3DQCshk/ATrYHtctswH7uAQKLDljSdgBAfvMtjBoLkQAQZzQyefcAAJO/+Y9AKwEAzZek4wAAvOgYXKiUF0zGCAAARKCBKrBBBwzBFKzADpzBHbzAFwJhBkRADCTAPBBCBuSAHAqhGJZBGVTAOtgEtbADGqARmuEQtMExOA3n4BJcgetwFwZgGJ7CGLyGCQRByAgTYSE6iBFijtgizggXmY4EImFINJKApCDpiBRRIsXIcqQCqUJqkV1II/ItchQ5jVxA+pDbyCAyivyKvEcxlIGyUQPUAnVAuagfGorGoHPRdDQPXYCWomvRGrQePYC2oqfRS+h1dAB9io5jgNExDmaM2WFcjIdFYIlYGibHFmPlWDVWjzVjHVg3dhUbwJ5h7wgkAouAE+wIXoQQwmyCkJBHWExYQ6gl7CO0EroIVwmDhDHCJyKTqE+0JXoS+cR4YjqxkFhGrCbuIR4hniVeJw4TX5NIJA7JkuROCiElkDJJC0lrSNtILaRTpD7SEGmcTCbrkG3J3uQIsoCsIJeRt5APkE+S+8nD5LcUOsWI4kwJoiRSpJQSSjVlP+UEpZ8yQpmgqlHNqZ7UCKqIOp9aSW2gdlAvU4epEzR1miXNmxZDy6Qto9XQmmlnafdoL+l0ugndgx5Fl9CX0mvoB+nn6YP0dwwNhg2Dx0hiKBlrGXsZpxi3GS+ZTKYF05eZyFQw1zIbmWeYD5hvVVgq9ip8FZHKEpU6lVaVfpXnqlRVc1U/1XmqC1SrVQ+rXlZ9pkZVs1DjqQnUFqvVqR1Vu6k2rs5Sd1KPUM9RX6O+X/2C+mMNsoaFRqCGSKNUY7fGGY0hFsYyZfFYQtZyVgPrLGuYTWJbsvnsTHYF+xt2L3tMU0NzqmasZpFmneZxzQEOxrHg8DnZnErOIc4NznstAy0/LbHWaq1mrX6tN9p62r7aYu1y7Rbt69rvdXCdQJ0snfU6bTr3dQm6NrpRuoW623XP6j7TY+t56Qn1yvUO6d3RR/Vt9KP1F+rv1u/RHzcwNAg2kBlsMThj8MyQY+hrmGm40fCE4agRy2i6kcRoo9FJoye4Ju6HZ+M1eBc+ZqxvHGKsNN5l3Gs8YWJpMtukxKTF5L4pzZRrmma60bTTdMzMyCzcrNisyeyOOdWca55hvtm82/yNhaVFnMVKizaLx5balnzLBZZNlvesmFY+VnlW9VbXrEnWXOss623WV2xQG1ebDJs6m8u2qK2brcR2m23fFOIUjynSKfVTbtox7PzsCuya7AbtOfZh9iX2bfbPHcwcEh3WO3Q7fHJ0dcx2bHC866ThNMOpxKnD6VdnG2ehc53zNRemS5DLEpd2lxdTbaeKp26fesuV5RruutK10/Wjm7ub3K3ZbdTdzD3Ffav7TS6bG8ldwz3vQfTw91jicczjnaebp8LzkOcvXnZeWV77vR5Ps5wmntYwbcjbxFvgvct7YDo+PWX6zukDPsY+Ap96n4e+pr4i3z2+I37Wfpl+B/ye+zv6y/2P+L/hefIW8U4FYAHBAeUBvYEagbMDawMfBJkEpQc1BY0FuwYvDD4VQgwJDVkfcpNvwBfyG/ljM9xnLJrRFcoInRVaG/owzCZMHtYRjobPCN8Qfm+m+UzpzLYIiOBHbIi4H2kZmRf5fRQpKjKqLupRtFN0cXT3LNas5Fn7Z72O8Y+pjLk722q2cnZnrGpsUmxj7Ju4gLiquIF4h/hF8ZcSdBMkCe2J5MTYxD2J43MC52yaM5zkmlSWdGOu5dyiuRfm6c7Lnnc8WTVZkHw4hZgSl7I/5YMgQlAvGE/lp25NHRPyhJuFT0W+oo2iUbG3uEo8kuadVpX2ON07fUP6aIZPRnXGMwlPUit5kRmSuSPzTVZE1t6sz9lx2S05lJyUnKNSDWmWtCvXMLcot09mKyuTDeR55m3KG5OHyvfkI/lz89sVbIVM0aO0Uq5QDhZML6greFsYW3i4SL1IWtQz32b+6vkjC4IWfL2QsFC4sLPYuHhZ8eAiv0W7FiOLUxd3LjFdUrpkeGnw0n3LaMuylv1Q4lhSVfJqedzyjlKD0qWlQyuCVzSVqZTJy26u9Fq5YxVhlWRV72qX1VtWfyoXlV+scKyorviwRrjm4ldOX9V89Xlt2treSrfK7etI66Trbqz3Wb+vSr1qQdXQhvANrRvxjeUbX21K3nShemr1js20zcrNAzVhNe1bzLas2/KhNqP2ep1/XctW/a2rt77ZJtrWv913e/MOgx0VO97vlOy8tSt4V2u9RX31btLugt2PGmIbur/mft24R3dPxZ6Pe6V7B/ZF7+tqdG9s3K+/v7IJbVI2jR5IOnDlm4Bv2pvtmne1cFoqDsJB5cEn36Z8e+NQ6KHOw9zDzd+Zf7f1COtIeSvSOr91rC2jbaA9ob3v6IyjnR1eHUe+t/9+7zHjY3XHNY9XnqCdKD3x+eSCk+OnZKeenU4/PdSZ3Hn3TPyZa11RXb1nQ8+ePxd07ky3X/fJ897nj13wvHD0Ivdi2yW3S609rj1HfnD94UivW2/rZffL7Vc8rnT0Tes70e/Tf/pqwNVz1/jXLl2feb3vxuwbt24m3Ry4Jbr1+Hb27Rd3Cu5M3F16j3iv/L7a/eoH+g/qf7T+sWXAbeD4YMBgz8NZD+8OCYee/pT/04fh0kfMR9UjRiONj50fHxsNGr3yZM6T4aeypxPPyn5W/3nrc6vn3/3i+0vPWPzY8Av5i8+/rnmp83Lvq6mvOscjxx+8znk98ab8rc7bfe+477rfx70fmSj8QP5Q89H6Y8en0E/3Pud8/vwv94Tz+0/JIZ8AAAAGYktHRAD/AP8A/6C9p5MAAAAJcEhZcwAALiMAAC4jAXilP3YAAAAHdElNRQfeBgQSIjPjAuUgAAAgAElEQVR42uzdd2Bb13n3cWIRIEESJLj3piRObYlatiXZluQtecojsZ2kWc2O0yZt47Rv03RkOsmbpmlG471lW8Na1rAmh0RKHCIl7j0BkgBBjIv3D6V+HQ9FIoF7D4Dv5w+3kSmc5z7n8ML84fBcldfrDQMAAAAAICg4HA6DwUAfAIQsu90eGRlJH4CrpKYFAAAAAICgUV1T+8abb1knJmgFgFDT09P7h/95urOrm1YAV0/F/nEAAAAAQNCYmZn5jx/9xOVyLV2yeN26tTHR0fQEQNDr6e09ePBQS2trSkryFz//ORoCXD3ycQAAAABAUNl/4OChw0fCwsK0Wu3yZUvXrV0TFRVFWwAEpf7+/gMHD11oabkc8d137z1lpSW0Bbh65OMAAAAAgKBit9v//Yc/drlcl/+nTqe7nJIbjUaaAyBoDAwMHnznUFNz83vhnjku7qtf+ZJKpaI5wNUjHwcAAAAABJs339p56nTV+//kckq+ds1q9pIDCHQDAwMH3zn8/mT8sttuvWXF8mX0B7gm5OMAAAAAgGAzNj7+k58+JUnSB/6clBxAQPu4ZDwsLCwyMvKJb3xNq9XSJeCakI8DAAAAAILQM88+19R84SP/FSk5gIBzhWT8suvWrb1x4wYaBVwr8nEAAAAAQBBqa2v/7e//cIUv0Ol0y5YuWbtmdXR0NO0CIKz+/oF3Dl0pGQ8LC9NoNF//6pdjYmJoF3Ct+J0LAAAAAEAQysvLTU5OGhwc+rgvcLlcx0+crKquWbJ40dq1a0zkSgAE09vb986hwxdaWv7i9tbi4gWE48DssH8cAAAAABCcTp2uevOtnVfzlVqtdvGihWvXromLjaVvABTX1dX9zqHDrRcvXuXXf+qxR3NysukbMAvk4wAAAACA4OR0Ov/13384MzNzlV+v0WgqKsqvX7fWbDbTPQCKaG/vOHT4yKW2tqv/K0lJSV/64udpHTA7nK8CAAAAAAhO4eHhFeVlp6uqr/LrPR5Pbe2Zs2frysvLrr9uXUJ8PD0EIJtLl9reOXy4o6PzWv/i8mVL6R4wa+TjAAAAAICgtWTx4qvPxy+TJOns2br6+nPFCxZct25tamoKbQTgV03NF44cOdrd0zOLv6vVahdWlNNDYNbIxwEAAAAAQSs9PS05OXlwcPBa/6IkSecbGhoaG4sKC6+7bm1WZibNBOBbXq/33PmGw0eOzuIe9Z7iBfMNBgPNBGaNfBwAAAAAEMwWL1q4e8/bs/u7Xq/3QkvLhZaW3Jyc69atLSjIp58A5k6SpDNn644efXdkdHTOt7hF9BOYC/JxAAAAAEAwW1hRvnfffo/HM5cXae/oaO/oSE9Pu27duuIF8+kqgNlxu93VNbXvvnvMYrXO/dVMJlN+fh5dBeaCfBwAAAAAEMyMRmNRYWFTc/PcX6q3t+/Z555PSkpau2Z1RXmZWq2mvQCuksPhOHW66sTJU1NTU756zUULK1QqFb0F5kLl9XrpAgAAAAAgiDU1X3jm2ed8+5qxJtPq1auWLlms0+noMIArmJycPH7i5Omq6pmZGR++rEql+uqX/9psNtNhYC7YPw4AAAAACHLzigqNRqPNZvPha1qs1p27dr9z6PCK5csqV66IjIykzwA+YGRk5Mi7x+rrz7ndbp+/eFZmJuE4MHfsHwcAAAAABL833nzrdFW1n148PDx8yeJFq1evijWZaDWAsLCw7p6eo0ePNV+4IEmSn4a49ZYtK1csp9XAHLF/HAAAAAAQ/MpKS/2XjzudzhMnT52uqi4tLVmzalVqagoNB0JW84WWY8eOt3d0+HUUtVpdWlJMt4G5Ix8HAAAAAAS/nJzs6OjoyclJ/w3h8Xjq6urr6urz8/LWrF5VWFhA24HQ4Xa7z9bVHzt2fHhkRJ57WlRUFG0H5o58HAAAAAAQ/FQqVWlJ8YmTp2QY61Jb26W2tqSkpDWrV1WUl2k0GvoPBDG73X7y1OlTp6t8+5CDKysrLaXzgG/+C4HzxwEAAAAAoaCru/vX//XfMg8aFRW1csXyFcuXRUREMAVAkBkZHT1+/MSZs3Uul0vOcTUazd888Q3uKoBPsH8cAAAAABASsjIzY00mi9Uq56BTU1P7Dxw8cvTdRQsrKleuSEhIYCKAINDW1n78xMmW1lb/PX7zCvLycgnHAV8hHwcAAAAAhIqSkuJjx0/IP67T6Tx1uup0VXVhQcGqypUFBfnMBRCI3G53Xf254ydODg4OKlhGaUkJcwH4Cvk4AAAAACBUzJ8/T5F8/DKv19vS2trS2pqYkLBy5YrFixbqdDomBQgIE5OTp06drqqusdvtylaiVqvnzytiRgBfIR8HAAAAAISK7KysiIiI6elpZcsYHhl5862d+w8cXLpk8YoVy2NNJqYGEFZPT+/xkycbGho9Ho8I9WSkpxuNRuYF8BXycQAAAABAqFCr1UVFhXV19SIUMz09ffTdY8eOn5g/r2jF8uX5+XlMECAOt9t97nzD6dNV3T09QhU2f/48ZgfwIfJxAAAAAEAImT9vniD5+GWSJDU2NTc2NSfExy9btnTxooU8dg9Q1tj4eFVVdU3tGcWPUvm4mxhzBPgQ+TgAAAAAIIQUFRZoNBpBzkl4v5HR0d173t5/4GBZWemKZcvS09OYLEBOXq+3+UJLVVX1xUuXJEkSs0hzXFxSUiKTBfgQ+TgAAAAAIITo9fqcnOxLl9rELM/lctXWnqmtPZOenrZ82bLyslKe4Qn4m81mq66praqusVgsgpfK4SqAz6m8Xi9dAAAAAACEjhMnT+3ctTsgSjUYDOVlpUsWL2Y7OeBzXq/3QktrTU1tS2urgL9T8pEe/eQj+Xk8qwDwJfaPAwAAAABCS0HgPAnT4XCcrqo+XVWdmpqyZPHihRXlBoOBGQTmaHx8vKb2TO2ZsxMTEwFUtk6ny87KYvoA3yIfBwAAAACElsTExOjo6MnJyQCqub9/4K2du97eu6+4eMHSxYtzc3OYR+BaeTyehsammpratvb2QDxQITsrS6slygN8jG8qAAAAAEDIKcjPO3O2LuDKdrlcdXX1dXX18fHxixZWVJSXxcXFMZvy83q9nv/l9Xq9Xq9Hkrz/S/U+6sv/VKs1Gs3lf6pUKhoov+7unrN1dfXnzk9PTwfwjasgn6kEfI7zxwEAAAAAIedsXf3Lr7wa8D/Sq1RZmZkVFeVlpSURERFM69Xzer3T09P26WnHtMPhuPwPh8PhmJmZcTqdM06n0+l0zjhnnDNul9vpcrlcLrfb7Xa7XS7X5Ux81kNfTsm1Wq1Wq9VdptXqdLrw8PBw/Z/+odfrDf8r4k//Vx8ZGcnpOtdqbGzsbF392br6sbGxILicL3zus6mpKUwr4FvsHwcAAAAAhJyC/DyVKuB3jHm93s6urs6urp27dhcVFlZUlM+fV8TxC2FhYS6Xa2Jycmpyaspmm5qampqampyask1N2e3TNrvdbrc7HA5JkhSpTZIkSZJcLtcs/q5arY68LCIiMjIiOjo6KirKaDQajcboqKjomOiY6GiNRsMCmJ6ePne+4ezZuq7u7qC5KKPRSDgO+APvmgAAAACAkBMVFZWUlDg4OBQcl+PxeJqam5uamw0GQ3HxgrKSkvz8PLVaHdyT6Ha7LVarZdxisVqtVqvFYpmcnJqYnJyYmHA4HEF5yZIkXY77r/A1kZGRMTExppiYmJjo2NhYk8kUazLFxsWaYmKC/miXmZmZxqbm8+cbLrW1ud3uILu6vLxcbt2AP5CPAwAAAABCUX5eXtDk4+9xOBy1tWdqa89ERkYuWDC/tKQ4Lzc3CDYUT01NjYyOjo2Nj4+Pj42Pj4+Nj42P22w2zoz9MLvdbrfbBwYGPvDnarU6JibGHBcXZ44zx8XFxcWZzXHxZnMQnMwzPT3d3HzhfENjUMbi7ynIy2N5A/7A+eMAAAAAgFDU2NT07HMvBP1lGgyGoqLC4vnzCwsL9Hq9+AW73e7h4ZGh4eHR0dGR0dGRkdHR0dGZmRlWrJ9ERkYmxMfHJ8QnxMcnJCQkJSXGm80B8csHVqu1qflCY2NTZ1eXx+MJ+pn66pf/Oj4+nhUL+Bz7xwEAAAAAoSgnOzsIjiD/ixwOR339ufr6cxqNJic7e968onlFheKkbB6PZ2hoeHBoaHBw8HIsbrFYlDoZPDTZ7fYuu/3953RrNJr4+PikxMTExITk5OSUlOR4s1mQs1m8Xm9PT++FlpbmCy0f3iMfxKKiogjHAT9h/zgAAAAAIET99KlfDA8Ph+CFx8XFFRbk5+fn5+flGgwGOYe22Wz9/QN9/f39AwODg0Ojo6OhsPM30Ol0uuSkpOSU5JTk5LTU1NTUlPDwcDkLsFgsFy+1Xbx46VJb2/T0dAhOQWlJ8f333ctSBPyBfBwAAAAAEKJe3/FGdU1tKHdArVYnJyfn5mRnZ2fnZGcZjUafDzE1NdXT29fb23s5Fp+YmGDhBcGyMZvNaWmpaamp6WlpaWmp/ji6Z2xsrKOzq6Ozs729Y3x8PMR7vmXzplWVK1l7gD+QjwMAAAAAQlRN7ZnXXt9BH94TFxeXmZmRkZ6elpqakpI8u63lLpert7evp7e3p6e3p7fXYrHQ2OCmUqni4+MzMtIz0tMz0tPT0lJnd3y5xWrt7x8YGBi4vHJsNhu9fc9nP/PpjIx0+gD4A+ePAwAAAABCVFZmBk14v/Hx8fHx8fr6c5f/p8lkSkpMjI83m81mk8kUHRUVHRNtjIzU6XTvnUbt9Xrtdvvk5OTg0HB3d3dnV/fQ0BBHpoQUr9c7MjIyMjJy9mxdWFiYTqdLT0vLzMzIzMxMSkqMMhrf/0GLJEkzMzM2u31qcmpycnLcYhkZHR0dGR0aHg7Ng1OuhlarTU1NoQ+Av77FaAEAAAAAIDQlJiYaDAaHw0ErPpLVarVara0XP+JfXY7IJUnyeDz8Yjrez+VydXR2dnR2vvcn6v8lSZLb7aZF1yotLVWj0dAHwE/UtAAAAAAAELLS09Jowiy4XC6n0+l2uwnH8RddjsUvLxi6wW0KEA35OAAAAAAgdKWlpdIEACIjHwf8inwcAAAAABC6CJ4ACC6N2xTgT+TjAAAAAIDQlcr+cQAC0+l0iYkJ9AHwH/JxAAAAAEDoijebw8PD6QMAMSUnJalUKvoA+A/5OAAAAAAgpCUnJ9EEAILeoFKSaQLgV+TjAAAAAICQlpxM/ARAUCncoAA/Ix8HAAAAAIS05CT2jwMQVFJSIk0A/Ip8HAAAAAAQ0hITePYdAG5QQIgiHwcAAAAAhLSEROInACLS6/UxMTH0AfAr8nEAAAAAQEiLNZl0Oh19ACCahIR4mgD4G/k4AAAAACDUxcXF0QQAojFzawL8j3wcAAAAABDqCKEACIiP7gAZkI8DAAAAAEKd2UwIBUDAW5OZJgD+Rj4OAAAAAAh1JpOJJgAQTSy3JsD/yMcBAAAAAKHOFBNDEwCIJoZbE+B/5OMAAAAAgFAXYyKEAiAcE7cmwP/IxwEAAAAAoS46OpomABCKTqfT6/X0AfA38nEAAAAAQKgzRkbSBABi3ZeMRpoAyIB8HAAAAAAQ6sLDw3U6HX0AIA6jkc/tADmQjwMAAAAAEBYZEUETAAh0U+L3WgBZkI8DAAAAABDGOb8AxLophXNTAuRAPg4AAAAAAPk4AMFuSgZuSoAcyMcBAAAAAAgL14fTBADi0IdzUwLkQD4OAAAAAECYRqOhCQC4KQGhhnwcAAAAAIAwjZooCoBINyXycUAW5OMAAAAAAIRpNPyADEAgajU3JUCW7zVaAAAAAACAJHlpAgBxeL3clAA5kI8DAAAAABAmSRJNACAOj8dDEwAZkI8DAAAAABDmkYiiAAiED+0AeZCPAwAAAAAQ5pxx0gQA4piZmaEJgAzIxwEAAAAACHPMOGgCAJFuSuTjgBzIxwEAAAAACJueJh8HIBAHNyVAFuTjAAAAAIBQ5/V6bTYbfQAgjonJSZoAyIB8HAAAAAAQ6qampjwens8JQCATExM0AZAB+TgAAAAAINRZLFaaAEAo09PTPKITkAH5OAAAAAAg1A0PD9MEAOLdmkZoAuBv5OMAAAAAgFA3RD4OgFsTEJLIxwEAAAAAoa6nt5cmABBNL7cmwP/IxwEAAAAAIU2SpN7ePvoAQDSdXd00AfA38nEAAAAAQEjr7u5xuVz0AYBohoaG7HY7fQD8inwcAAAAABDSmi9coAkABCRJUktLK30A/Ip8HAAAAAAQ0hqbmmkCADE1NDbRBMCvyMcBAAAAAKGrvb1jdHSUPgAQU0tr6+TkJH0A/Id8HAAAAAAQuk6eOkUTAAjL4/GcrqqmD4D/kI8DAAAAAEJUf/8Ah6sAENyJk6emp6fpA+An5OMAAAAAgBC1Z+9er9dLHwCIzOFwvHPoMH0A/IR8HAAAAAAQiqprai9daqMPAMR38tTpzs4u+gD4A/k4AAAAACDk9PT07ty1mz4ACAiSJD3/4kvWiQlaAficil8lAwAAAACElLa29udeeJHzfAEElvj4+IcefCAxIYFWAD5EPg4AAAAACCGHjxw9cPAdSZJoBYCAEx4eftedd5SVltAKwFfIxwEAAAAAIcHpdL708qtNzc20AkBAW72qctPNN6lUKloBzB35OAAAAAAg+I2Mjj7z7PPDw8O0AkAQyMvLvf/eeyIjI2kFMEfk4wAAAACAINd8oeXlV151OBy0AkDQiIuN3f7A/ampKbQCmAvycQAAAABAMDv67rF9+w9w4DiA4BMeHr5t650lxcW0Apg18nEAAAAAQHDyeDyvv/HmmTNnaQWAYKVSqTasv+H669bRCmCW30Tk4wAAAACA4GO325957vnOzi5aASDoVZSXbb3rTo1GQyuAa0U+DgAAAAAINmNjY3/44zOjo6O0AkCIyMnOfnD7/REREbQCuCbk4wAAAACAoNLV3f30M8/Z7XZaASCkJCYkPPLIQ3GxsbQCuHrk4wAAAACA4NHY1PTSy6+6XC5aASAERUVFPfzQ9vS0NFoBXCXycQAAAABAkKiqrnnzrZ2SJNEKACFLr9dvf+C+/Lw8WgFcDfJxAAAAAEAwOHT4yP4DB0PtqsPDdUajMSIiIsJgCA8P1+l0Op1OpVKp1eqwsDCv1+v1el0ul9vtdjqd0w6HY9phn7bb7dMsGAQilUoVGRkZGXl5yRsur3iNRqNSqVQqVVhYmCRJHklyu1wut9vhcDgcjunpaZvN7na7Q6pRWq1229a7ykpLWDPAX76xkI8DAAAAAALdrt17jp84GcQXqNeHJyYmJsTHx8XFmePiTCZTbKwpKipKp9PN4tUkSbLZbNaJCavFOm4ZHxsbHxsbGxoenpycYi1BEHFxsYkJCWaz2WyOizXFmmJNppiYyMjIyzn4tZqZmZmcmrJarBar5fKCHx0dGx4ZCeLcXK1W33rLluXLlrKWgCsjHwcAAAAABDCv1/v6G2/W1NQG2XVFRkZkZmampaampaampqbExMTMLha8JtPT0wODg/39A/39/d09PaOjYywwyCY5OSkrMzMlJSUtNSUpKSk8PNzfI0qSNDY+PtA/0Nff39fX193T63Q6g6mlKpXq5ptuXLN6FasLuNJ3Cvk4AAAAACBASZL08quv1defC47LiY2NzcvNycrKysrKTIiPlyEQv7Kpqamuru6u7u7Ozq6e3l7WG3xLo9FkZWZmZ2dlZ2VlZmbo9XrF7ycDg4OdnV1d3d3t7e02mz04+rz+huvX33A96w34OOTjAAAAAICAJEnS8y+81NjUFNBXodFocrKzCgsLi4oKExMShK3TZrNdvHippbW19eKl6WmOL8fsmUymosKCwoKCvLxcxTPxj+P1evv6+1taWltaW3t7+wI9PVu7ZvXNN93I2gM+Evk4AAAAACDwBHo4rtVq5xUVlpaUFBUVynCOhG87393dfb6hsaGxkfPKcfXizebS0pLS0pKU5OTAqtxutzc2NZ8/f769o0OSAjVGIyIHPg75OAAAAAAgwARuOK5Wq+cVFZaVls6bVxRYsfiHeb3ejo7O8w0N586fn552sCzxkUwmU0V5WWlpSWpKSqBfi81ma2hsOnf+fEdHZyDWv27tmptu3MiaBD6AfBwAAAAAEEi8Xu/zL7zY0Bhg4bg5Lm7JksWLFy2MiooKshlxu92NjU01tbVt7R2sT1ymVqvnzytasnhxQUG+Wq0OsqsbGR2tqak9c7bOZrMFVuXXrVt748YNrE/g/cjHAQAAAACB5KVXXq2rqw+Yn7pVqgXz561Yvjw3N0fx523628joaHV1TXVN7czMDAs1ZEVHR69csTwoPwr6AI/H03zhwomTpzo7uwKo7I0b1l9/3ToWKvD/36nJxwEAAAAAgeL1N96srq4JiFJ1Ot3iRQsrK1fGm80hNUczMzPVNbUnTp6yWq2s2JCSkpy8elVlWVmpRqMJqQvv6+s7dvzE+YaGQDmdfMvmTasqV7JigcvIxwEAAAAAgWHX7j3HT5wUv86ICMPqVZXLly2LiIgI2cmSJOl8Q8ORI+8ODg2xdINebk7OurVr8vPzgv6XJK7AYrEcP3GyqrrG7XYLXqpKpbrj9tuWLlnM0gXCyMcBAAAAAAHhyNF39+7bL3iRer1+9arKVZUr9Xo9UxYWFub1es+dO//OocMjo6N0IyhlZmZsXL8+Ly+XVlw2MTFx+MjRmtpaj0cSuU61Wn3/ffcWL5jPlAHk4wAAAAAA0dXWnnltxxsi/wCr0+kqV65Ys3pVKO8Z/ziSJNXXnzvwziGLxUI3gkZaauqG9TcUFRXSig8bt1gOHTp85myd4HetTzzyUE52NvOFEEc+DgAAAAAQWvOFlmefe16SxN2MWVFedtONG2NiYpisK3C73ceOnzhy9F2n00k3Alp0dNTGDRsWLawI5dNUrsbA4ODuPW+3tbULW6HBYPj0448mJyczWQhl5OMAAAAAAHH19fX/5re/EzZRzUhP37JlU2ZGBjN1laampvbtP1B75iytCERarWZVZeV169aGh4fTjavU1NS8Z+/esbFxMcszmUyf/cynoqOjmSmELPJxAAAAAICgrFbrr379m8nJSQFri4gw3HzTTYsXLWQL7Sz09va+vuPNgcFBWhFACgryb7/1lri4OFpxrdxu97vHjh06fNTj8QhYXmpq6qcff5TPPBCyyMcBAAAAACKamZn59W/+e3BwSMDaSkuKb9myOSoqimmaNY/H8+6x44cOH3a7PXRDcJGREZtvvnnhwgpaMRfDw8Ovv/FmV1e3gLXNKyp66MEH+LQPoYl8HAAAAAAgHK/X+8enn21pbRWtsOjo6NtvvWX+/HnMkU+MjI7u2PFmR2cnrRBWeVnpls2bjEYjrfDJne10VfXeffsFPDNq9arKzZtuZo4QgsjHAQAAAADC2fP23nePHRetqpLiBXfcfltERAQT5ENer/fdY8cPHDzo8Uh0QygGg/72W28tKyulFb41Nj7+0suv9PT0ilbY1rvuXLxoIROEUEM+DgAAAAAQy5mzda+8+ppQJel0ui2bNy1dspjZ8ZO+vr6XXn51ZHSUVggiOzvrnm1bTSYTrfAHSZIOvnPoyNF3hcrltFrtY49+IiszkwlCSCEfBwAAAAAIpL+//9e/+a3L5RKnpNTUlHvv3paQkMDs+JXT6dy5a3ftmbO0QlkqlWr9DdevW7tGrVbTDb/q7Op68aVXJiYmxCkpOjr6C5/7Kx6ugNC66ZGPAwAAAAAEMT09/cv/+5/jFos4JS1aWHHbrbfodDpmRx41tbVv7dzFQzuVEhkZee892/Lz8miFPGw224svv9LW1i5OSTk52Y998hN8OoLQQT4OAAAAABDFH/74dGvrRUGK0Wg0WzZvWr5sKfMis76+vmeff9FqtdIKmaWnpz1w372cqSIzSZL2Hzh49N1j4pS0qnLlls2bmBqECPJxAAAAAIAQDh0+sv/AQUGKiY6O3v7AfRnp6cyLIux2+4svvXxJpE21QW/J4kW33rJFq9XSCkU0Nja98tprTqcoR0ttf+C+4gULmBeEAvJxAAAAAIDyOjo6f/v7P0iSJEIxKcnJDz+0PSYmhnlRkCRJb7z5Vk3tGVohg5tu3Lh2zWr6oKy+/v6nn3l2cnJKhGIiIiK+8Lm/io2NZV4Q9MjHAQAAAAAKs9vtP//lrwR5SF1hQf59996j1+uZFxEcPnJUnN8qCEparWbbXXeVlpbQChFYrdb/efqZoaFhEYrJzMj49Kce4yByBD3Nk08+SRcAAAAAAAp6/oWX+vr6RKhk6ZLF99y9jadxiiMnOzshIf7ChRa29/lDZGTEIw8/VFhYQCsEYTAYFlaU9/b1jY+PK17MxMSE2+0uyM9nXhDc+AgIAAAAAKCk01XVF1paRKhkzepVd9x+G5slRVNeVvbg9vt1Os7F9rGoqKjHH3s0KzOTVghFr9c//OD24gXzRSjm2PETHR2dTAqCG+/6AAAAAADFjI6O7nl7rwiVrL/h+ptvupEZEVNhQcHDDz0YHh5OK3zFZDJ96vFHkxITaYWANBrNfffeU1FepnglkiS9/OprMzMzTAqCGPk4AAAAAEAZXq/3pVdedTqdileyedNNN1x/HTMistycnEc/+UhEhIFWzF18vPnTjz8abzbTCmGp1eptW+9aumSx4pVYLJa3du5iRhDM3260AAAAAACgiKPvHuvp6VW8jC2bN62qrGQ6xJeRnv7oJx4xGHh06pyYzXGPP/pJk8lEKwSnUqluv+3WZUuXKF7JmbN1zRdamBEEK/JxAAAAAIAChoeHD75zSPEybty4vnLlCqYjUKSmpj7y0IPh4TxAdZZMpphHP/FIdHQ0rQgIKpXqtltvqagoV7ySHW+86XA4mBEEJfJxAAAAAIDcvF7vK6+97na7lS1j3do169auZToCS2Zm5oMPPKDVamjFtTIajZ/8xCOxsbG0IoCoVIIcyzgAACAASURBVKqtd95RXLxA2TImJyd37trNdCAokY8DAAAAAOR28tRpxU9WWbF82Y0bNzAXgSgvL/f+e+9Vq1W04uoZDIZHP/FwQnw8rQg4arX6nm1bC/LzlC3jzNm6S21tTAeC8FuMFgAAAAAA5DQxObn/wEFla1iwYP4tWzYzF4Fr3ryi2269hT5cJY1Gvf3++5KTk2lFgNJqtfffd29KisIz+MabOz0eD9OBIEM+DgAAAACQ1c6du2ZmZhQsICM9/Z5tW1Uqdh8HtqVLlqxbu4Y+XI277rwjNzeHPgQ0vV7/8IPbY2KUPDt+dHT00OEjzAWCDPk4AAAAAEA+ra0XGxqbFCwgNjb2we3363Q84DEYbNywvqy0hD5c2Yb111eUl9OHIBATE/PwQw/q9eEK1nD03WNjY2PMBYIJ+TgAAAAAQCaSJCn7hDe9PvyRh7ZHRUUxF8FBpVJtvevOjIx0WvFxKsrLrr/uOvoQNFKSk++9524FC3C73Tt372EiEEzIxwEAAAAAMjl+4uTI6KiCBWy9887ExEQmIphotdoH7rvXaIykFR+WkpJ8x+230YcgU1RYuGH9DQoWcOFCS0trKxOBoEE+DgAAAACQg81me+fQYQULWLtmdXHxAiYi+MTExNx3zz1qNQfK/5mICMMD99/HUUJB6bp1a+fNK1KwgF2735YkiYlAcCAfBwAAAADI4cDBdxR8LGd+Xu7GDeuZhWCVm5tz04030of3u3vbVnNcHH0ISiqV6u6td8WbzUoVMDIycrqqmolAcCAfBwAAAAD43cjISE3tGaVGj4oy3nP3NrWaH4GD2epVlfPnz6MPl61bu6aosJA+BDGDwXD/ffdoNBqlCnjn0GGn08lEIAjwHwcAAAAAAL97e+9+j8ej1Ohb77zTaDQyC0Hvrjtu5+GrYWFh6Wlp62+4nj4EvZSUlBs3KvZrMTab7fCRo8wCggD5OAAAAADAv7p7epqam5UafeWK5YWFBcxCKIiMjNx61x0h3oTwcN09d29VcFsx5LSqsjIvL1ep0U+cPGWz2ZgFBDotLQAAAAAA+NWBg+8oNXRSUuLNNwXtsdROp7Ojo6O3p7evt3dwcHBiYsJisdimppwup3PGKXm9Oq02XK+PiDCYTCZTbGxCfEJ6Rnpaenp2drbJZArKnhQWFFSuXHHi5KmQ/XbbvGlTfHx8UF6ax+Npb2/vaO/o7+8bHBgcGxu1WKwTVqvT6ZxxOt0ul0aj0el04eHhMaaYmBhTbKwpJSU1NS01PT09Lz8/Ojo6+HqiUqm23XXnz3/5q+npaUVuQUeOvrt50828zSGgkY8DAAAAAPyos6vr4sVLigytVqu2bb1Lqw2en3wlSbrQfOFcff25c+daWlp6e3pmfWpNYmJifkFBSWlJeUVFaWlpZGRk0HTpphs3trZeHBkdDcFvt6LCgqVLFgfTFfX09NSdOXvu3LnGhoaOjg6XyzXrl0pKTp4/f155eUVZRXlxcXHQ3BliYmJuvWXzSy+/qsjop6uq165ZzblGCGgqr9dLFwAAAAAAfvK73//PpbY2RYZes3pVcGwelyRpeGiovv7cW2+8UVNT4/OT3LVabVl5eeWqyrVr1+bk5gZBx9o7On77uz+E2vdaeLjuS1/8QnD8ZsDk5GRnR8fhQ4f37ds7ODDo89ePiIhYsnTpysrK62+4Pji22//x6WdaWi8qMnTlyhW3bNnMmx0CF/k4AAAAAMBfenp7f/Wf/6XI0GZz3Bc//zmdThdkLbVarfv37nvrrbeam5r88fq5eXkbNmzYvGVLWnpaQDdqxxtvVtfUhtS32y1bNq1csSL4rqupsWn3rl17du+enJz0+Yur1epFixZtvOnGm266KTKQn+JrtVp/9vNfOp1O+YcODw//xte+Eky/g4JQo3nyySfpAgAAAADAH97auWt4ZESRoe+/796EYDyF2WAwFJcU33nXnQsXLhwcHOjv7/ft61vGx2tra1968cX6+jqDISInJ0elUgVio3Kys8/W1SkSFyoiIyP9jttuC9DJurLExMTKVau23b0tKjqqpaV1xuHw4Yt7vd7+/v5j77770osv9vb2JiUnJyQkBOidQa/Xtyqxhdzj8Wg0GgUfEwrMEfk4AAAAAMAvhoeHd+7ao8jQFRXlq1dVBnd709LTb7n11vz8gnPnztlsNp+/fm9v74H9+3fv3q1WqwoKCgLusGatVmuKMTU0NobC95pKpXr4oe3RQX0GtC48vKKi4vbbb5+cnLzQ3Ozz13e73S0XLrz+2mt1Z+vMZnNGZkbAtSg9Pe1CS8vk5JT8Qw8ODa1csVyj0fDGh0BEPg4AAAAA8It9+w/09fXLP254uO6h7Q/o9fpQaHJubu4dd9ze19fX5p9D3icnJ08cP/Hmm2/odLqioqLAyr+SkpLa2tutVmvQL4Ply5YuWbwoFBa83mBYs3btwoULT508OT097Y8h+vr63t6z59SJkympqenp6QHUHJVKlZyUWHvmrPxDu91uo9GYGYAfKgBh5OMAAAAAAH+w2+2vvr5DkiT5h77h+uuKiopCp9W68PD1G9abTKaTJ076aYhp+/SJ4yd27doZHx+fn58fQM1JTUmpqq4J7gVgMOi3P3B/8B21fwVp6embNm+ur6sbGhry0xBDQ0N7du2ur6ufN39+XFxcoHTGZDKNjI76ry1XMDo6unLliqA84QdBj3wcAAAAAOB7x46fuHjxkvzjxsbG3nP3NrVaHWoNLykpycvPO3zosP8+k7BN2d45+E7V6dPFJSVmszkg2hIdHT0xMdHfPxDEU3/jxo0hePRzZGTkTTff3NrS2t3d7b9R+np7d7z2+rhlfOHChYHyCURGenpVdbX8n01OOxxpaamJgXl6O0Ic+TgAAAAAwMckSXrplVdnZmbkH/r2225JTUkJzbbn5ubm5+cf2H/Ar6MMDg6+sWOHy+WqqKgIiONWMjLSq6qrPR4pKCc93mzeetedIfiBUFhYmFar3bBxQ+P5ht7eXv+N4vV6Gxsa9+zek5WVmZWVJX5bDAaD2+3p6OyUf2jblG3RooW8AyLgkI8DAAAAAHysqflCdY0Ch1okJyfdumVLKP+Cf05OjjnefOzdY34dRZKks2fOHj1yZOGiReIfPREeHu50Oju7uoJyxm/Zsik1NTVkF7xarV53/XWnT54aGRnx60A2m23v23tHhkeWLV8u/rNq01JTq6pr3G63zONarNaK8rLIyEjeBBFgdxJaAAAAAADwrarqakXG3XDDDZx+e9fWrbfceqsMA128ePGxT3zypRdfFL8na1av0uvDg2+uExMTykpLQ3zBR0ZGfv8H/xIVFSXDWDtef/0TDz98sbVV8J4YDIY1qyvlH9fr9Qb9cf8ISuTjAAAAAABfslgsly61yT9uWlrq/Pnz6H9YWNg3nvhmpiwHQczMzPzoP374D3/394qcpXP1IiIiVlVWBt9Er7/h+tA8WeUDUtPS/vY735ZnrM6Ozk8//qm39+wRvCcrV6yIjIyQf9wzZ+s8Hg9rEoGF2ygAAAAAwJfOnK2T/9FwYWwefx+DwfDEt56Qbbh9e/d++rHHhwaHRO7JqsqVBoMhmGY5OTmppLiY1X7Z+g0bVq1eJc9YDofjyX/47s9+8lORG6LX69esXi3/uDabrflCCwsSgYV8HAAAAADgS2fr6uUfNDk5qbCwgOa/Z+myZRs2bpRtuNbW1k899lhLi7i5mMFgWL5saTBN8bo1a/hA6P2+9o1vyHky+HPPPvs3T3xL5N+cWL5sqV6vV+At4GwdqxGBhXwcAAAAAOAz3d09o6Oj8o+7ZtUqssIPePxTj8s53PDw8Of/6rNnas8I25CVK5ZrNJrgmFyTKaakhM3jfyY9PX3Tls1yjnj40KEvffGLNptNzIbo9fplS5fIP25La+v09DQLEgGEfBwAAAAA4DNn6xTYORgdHV1WVkrzPyA3L2/ddevkHNFms33tK185dfKkmA2Jjo4uLy8LjsmtXLkyaLJ+H3rkkUdkHrG+rv6Ln/v8hNUq6jpZodHIHf15PJ5z5xtYjQgg5OMAAAAAAN/wer0NjU3yj1u5cgVZ4Ue67fY7ZB7R4XA88Y1vVp2uErMhq1cFw1M69Xr90iWLWd4flpmVtWix3J1pbm7+8l9/Scxd5DExMaWlCnx2eJ58HAGFfBwAAAAA4BudnV1TU1MyD6rTackKP87KypWxsbEyD+p0Or/1zW/W19cL2JDkpKT8/LxAn9bFixYqcq50QNgs7xErlzU3N3/1y19xOBwCNmTVyhXyD9rR2SnssTPAh5GPAwAAAAB843yDAnsGS4qLIyIiaP5H0mq1KysV2DE9PT39za99vbOzU8CeBMGnKXwgdAWrV69RZNxz9fXf+dtvS5IkWkPS0tJSU1NkHlSSpMamZlYjAgX5OAAAAADAN5qaL8g/KFnhX+jP0qWKjDsxMfG1r3x1fHxctIYsmD/faIwM3AnNysxMSkoSrSq73S5IJeZ4c26eMr8icPzYsR/++3+IeBNYosBTOhuVOGsLmB3ycQAAAACADwwMDFplf0hdYkJCdna2aK04V39OnGJKlHtyaV9v79888YTH4xFqdjQazcKKisD9Rlsi3gdCg4ODBoNBnHoUOXH7sldfeeXVV14RbYIqyst0Op3Mg7Z3dLhcLt4ZERDIxwEAAAAAPnChpUX+QQXMCk8cP2GxWMSpJyMjQ8GHl9bX1f/kxz8WbY4C93cO9Hp9WWmJUCU5nc6nfvoztVqgfCknJ0fB0X/yox83nD8v2rIplX3ZuN3ui5faeGdEQCAfBwAAAAD4gCL5eLlym6M/0vDQ0Pe++93MzAxxStJqtSmynz78fi+/+NKB/fuFmqaEhIS0tNRA/C4rXjBf/o3AV/bjH/3I7XYLVVKGot+ALpfr23/77cnJSaF6UlFeJv+gLUq8KQCzQD4OAAAAAJirmZmZ3t4+mQfNyc6Ojo4Wqg/fe/J7Vqs1OiZGqKqioxWu51//5QdDg0NC9US0XdhXqVSwso8eOfL6q69Fx0Sz4N9vaHDwB9//vlA9yc3Jkf/Y/UvsH0eAIB8HAAAAAMxVR2en/MdMi5YVPvvMMzXV1WFhYREREUIVZoxU+HGUk5OT//jkk0L1pKQk8PLxiAhDvkJPnvxI4+Pj3/8//xwWFmaMNArVqEgBnr968MDB3bt2idMTtVpdUlws86Bj4+NCHTYFfOw3CC0AAAAAAMxRW1u7zCOqVKqS4gXidKC3t/e//vPX79Um1vQIUE9NTc2O13eI05K42NiM9PTA+i4rXrBAwaPkP+zHP/zhn9JP4da7EAX99Mc/GR8fF6ctpUp8JiT/WwMwC+TjAAAAAIC5amvvkHnE7OysqKgocTrwg+//i8PhuPz/2+12oWZHkHp+8dRTo6Oj4rSltLQ4sL7L5N//ewXHjx3bt3ffnxaYTbAFb7OJUIbVav3Rf/xQnLbk5GQbjXLv9G/r6AgDhEc+DgAAAACYE6fTOTg4KPOg84oKxenAgf37q6uq3vufoj2ab0qMeiYnJ3/x1FPitKWosDCAvst0Om1ubo4gxbjd7h//8Ef/f4FNibXgJyenBKlk/759tbW1ghSjUqkKCwtkHrSrq5u3SIiPfBwAAAAAMCc9vb2SJMk8aKEw4ebMzMzPf/ZnsW9Pd484s+PxePr7+wUpZs/uPQ0NDYIUk5iYGBtrCpTvstzcXK1WK0gxzz/3XE9Pj5gLPiwsrKdHoEz2Jz/6sdfrFaSYItnz8bGxMZsY2/mBKyAfBwAAAADMSbfs6VhMTExyUpIgl//C8y8MDAy8/0+6OjvFmZ2+3l632y1IMV6v96mf/FSc5hQWFATKd5n8yebHmZiY+P3vfv/nd4BucSJg0b4BW1tadu0U5UGdBfn58h/O3tXNFnKIjnwcAAAAADAnPT29Mo8oTlZot9ufffrpD/xhQ8N5cWZHnP3al9XV1Z06eVKQYgLoiBVxovxnn37aNvVnB5g4HI5Lly6JtOYbhZq73/73f3s8HhEqiYiIyMiQ+7G08r9BANeKfBwAAAAAMCf9f757Wgb5+XmCXPsLzz9vtVo/8Ie1NbXibKetqa4WbcH813/+WpBKcnNz1GqV+N9icXGxZrNZhEqsVutLL770EcusSpRlZrVaW1tahJq+vt7enW+9JUgxBfn5Qf8GAVwr8nEAAAAAwOxNT09bLBaZB83OyhLh2mdmZl58/oUP/7nFYmlsFGIHq8fjOXnipGhrpqGhQZCHFur1+uTkZPG/ywRZ8GFhYa+89LLdbv/wnx8/fkyQCk8cPyHgDD7z9DOCVJKVlSnziP395OMQHfk4AAAAAGD25N8bGBsbGx0dLcK179q58+M+G9izS4gTh2uqq0dGRgRcNs/88WlBKhEner6CLDGKdDqdL7/00kf+q6rTVcPDwyIUKci33gd0dXYePXJEhEoyMzJkPoJ8cnKSR3RCcOTjAAAAAIDZGxqSOxTLln3/48f5yM3jl+19e6/D4VC8wjd2vCHmsjlx/HiPGE/tyxJmOYlf5L63946Pj3/kv/J6vbve2ql4hQMDA6dPnxZzEl/4+NuFnPR6fYrsvzMxJMZnJ8DHIR8HAAAAAMye/NuTBdlLW1dX19HR8XH/dmJiYsdrrytbYU9398EDB8RcNl6vV5DsXvz94waDISkxUYRKduzYcYV/+8Lzz8/MzChb4TN//KM4R/9/QG1NTU9PjwiVyP9xy8jIKO+VEBn5OAAAAABg9uQPPjIz0kW48Dde33HlL3jm6aeV3UL+u9/+TtisMCwsbNfOnR6PR/EyYmJiBDmu5+NkZKTLfCDGR2pvaztXX3+FLxgfH3/t1VcVrHB4aEjYX5gICwvzer1vilFeZkaG3FPD/nGIjXwcAAAAADB7I6Oy5uMajTopKUnxq3Y6nYfeeefKXzM8PPz73/1OqQrPnzu3a+dOkVfO6Oho1ekqESpJS00RuVGpKUKU9/bbb//Fr/nNf/1mbHRMqQp/8uOfOJ1Okady71X0UI4VJfuCl/ltArhW5OMAAAAAgFmSJGliYkLOEZMSkzQajeIXfvzYcbvd/he/7Jk/Pt3e1iZ/eS6X69/+9d/EXz8H9u8ToYzU1FSRu5QqRny/f99fnizb1NSPf/QjRco7cfy4sKcJvWdgYOD8uXOKl5GQkKDVauUc0TJu4e0SIiMfBwAAAADM0sTEhCRJco6YlJwkwoVfZRLndrv/7jt/J/+hzL946uetLS3ir5/Dhw6LcMRKclKSyF0SobwLFy709vRezVfu37fvzTfkPkVkeHj4H5/8XkDcMw8IEOKr1erEhAQ5R7RYrbxdQmTk4wAAAACAWZI/9RDhQYWSJJ06efIqv7jt0qV/+efvy3kO+P59+154/vmAWD+Tk5MibKdNTEoUtkVqtTo+Pl7xMk4cP371X/zDf/+P5qYm2WpzOp1//+3vWCyBsUP5mjrpxxupvGve6XROT0/zjglx77S0AAAAAAAwOxPWCZlHlHnb40dqON9wTafKvL1nz89/9pQ8tZ0+ffp7330ygJaQCHFhvNkswgMwP5I5Lk6EA4VOHj9x9V88MzPz1S9/pburS4bCPB7Pd//+H+rq6gJlwXd2dPb39SleRoLsN1Kr7G8WwNUjHwcAAAAAzNKUzSbziOZ4s+JXXXX69LX+lWefeeYXP/+5v3eRnzp58lvf+Kbb7Q6gJXRagEd0arVakylGzP6IsOCnp6cbGhqu6a9YLJYvfuGLHR0dfi3M5XJ977vf/YtPyhVNVZXyaz7eLPe6ssn+ZgFcPfJxAAAAAMAsTU1NyTyiOS5O8auun9Vm1af/54///E//x+Vy+amqPbt3f+NrX3c4HIG1hFpbWuQ/n/0j1pXZLGZ/RFjwDefPz+JDl6HBwc9++jP19fX+u/l882tf37d3X1igqa+rV35dyf65yxT5OARGPg4AAAAAmCWb3S7ncEZjpE6nU/aSvV7v+fPnZ/d3d7711mce/1Rvb69vS5qZmfnXH/zge999MrB2jl/mdruvdW+yP8SaTGL2JzY2VvEaZp3nWq3Wz//VZ5/549M+/82J5qamTzz8yKlTpwLxtlkvwGkw8i949o9DZOTjAAAAAIBZmrbL+sg1U4zyIWZXV9dcgp7m5uaHtz/47DPPeDwen9RTdbrqkYcefv3V1wJ3FTU3Nileg0nUfFyEg1+am2c/QR6P5+dPPfXXn/9CR3u7T4pxOBy/+uUvP/34p/p8/TmTbHp6ehQPiyMjI7VaWc+1t8v7YSpwTcjHAQAAAACzNOOU9WSMmJhoxS/5YmvrHF9henr6qZ/+7OHtD+7ft1+SpFm/zoXm5m9984kvffGLXZ2dAb2KLl5sVbwGEZbWxxQWI8CavzjHV6ipqXlo+4P//q//1t/fP+sXcTqdr7/22n333PuH3/8hEH9V4j1er/fixYvK1qBSqWKiZV1aTqeTd0wIS0sLAAAAAACz45yRNfKIiopS/JIvXbzkk9dpb2//++9859e/yrztjts3bdqUmJR0lX/R4XAcPnRo51s7Z/GYUDFd9FFL57S0jFFiNifKaFS2ALvNNjAwMPfX8Xg8r77yyo7XX9+wceOWW7YsXbZMo7na/cvdXV17du95Y8eOkZGR4Fjzly5erKioULYGo9E4Nj4u23AiPGYA+Djk4wAAAACAWZI58jAqnRWGhYV1d3f79tV++fNf/N9f/HL+ggVLly4tKy/Pzc1JTUv7QHQ4Ojra2dHR3NRcXV11pvZMwD2E88p6fNrSWS6tKKOYzVF8zXf39Pjw9HCPx7P37bf3vv12XFzc0mXLlixdWlRUlJ2dFfnnl+nxePr7+tra2s6cOVN9ukrx3daC30ZmJ0reNT8zw/5xiIt8HAAAAAAwS24fHaJ9lSIiIhS/5P6+Pp+/ptfrbWpsbGps/NMP6lptVFSUMcqoVmvsdpttyhZkgfgHTE9PWywWZR9EKcLS+jCNRq3X65Ve8P3+eNnx8fF9e/fu27v38v80mUxGo1FvMLhdLpvNNjExEdAnqCjVVZHXvMcTzBOKQEc+DgAAAACYJUnefNxgMCh+yXM5QPkqud1ui8VisVhCZyH19/UrnI8LsLREXfB9MoxitVqtVmsILXhZuirU6vLM4VkLgL/xfE4AAAAAwCzJHHkYDHrFLzmkYmvZjI+PKVuA4tu0ha1qfGyc9RmUXZU5H5c85OMQF/k4AAAAAGCWJHnzcZ1Op+z1TkxMSOyC9APF9w5rtVqVSiVaWxRf8CJMDQs+OFaX5OXOCXGRjwMAAAAAZvsjpVrWHyqVz8fJCv0jBOPCQClpYmKC9elzTqdT8YcK6HSyHrmsVpFAQuD/mKEFAAAAAIDZ0Wg0cg6nlXe4D5txOpl0f3DOOENtMQdKSTMzDtanf9b8TEitLrWGBBLiYnUCAAAAAGZJI+/+cZVa4Z9hXeTj/uF0Kd9YtVq481VE2HLrcrlZn/5Z8y6lF7ysq0uj1jDpEBb5OAAAAABgtj9SyrwDUekTot1ussKgbayA54+LENmz5oO1sTIveA37xyHyf8zQAgAAAADA7Mj+hDevster1WqZ9GBtrFfp1fURC15SviQBj51hzQfighfwfH/gPeTjAAAAAIBZMhj0cg7nlSRlr1dLxOMfOq3yjRUhjP5gSV5J8RrCw1nz/lnzSt9MZF7wBoOBSYewyMcBAAAAALNk0Msaebg9HqWvV8+k+4PeoHxjPUqvrg+TPCLk46x5PzU2PKQWvJ6bJwRGPg4AAAAAmCWZ94+7lX5UYHRMDJPuDzECNNbtdonWFpfLxdQEJZ1OFxEREVKri/3jEBn5OAAAAABglmSOeBSPC2NiYtRqfo72PZPJpGwBHo9HwPNVRMjHTbEm1mfwLXj5V5finwcAV8D7OgAAAABglqKiouQczjHjUPZ6VSqVCMFW8Ikzm5UtwOFwCNgWx8yM8lMTF8f6DMquzsi7uqKjo5h3CIt8HAAAAAAwSzHR0XIOJ0KImZKayrz7vqspKcoWIGg+7phWvIZUFrw/upqWKsDqknXNR0dFM+8QFvk4AAAAAGCWouXNx+124sIgZDAYzErvH5+enhawMx6P5HQ6WfDBJzU1TfEa7PKuefaPQ2Tk4wAAAACAWYqOkTUft9lsil9yZmYG8+5bGRnKt3RKgKUlZmEZmZksUT90Vfk1b5uSb2lpNBqj0ci8Q1jk4wAAAACAWYqLjVWpVLINJ0KImV9QwLwHX0unpgTNx21TU8oWEBUVlZSczCr18ZrPF2DN2+RbWiaTSc53CuBakY8DAAAAAGZJq9XKecTKxMSE4pdcQD7ua/kF+YrXIMLS+ujCJidZ86x5n/N6vZMyLi2zmae8Qmjk4wAAAACA2ZMz+LBalQ8xs3NyIiIimHcfmj9/geI1CJuPi7Dm5y+Yzyr1obS0tJiYGGVrmJ6edrncsg0Xr/QDBoArIx8HAAAAAMyenE9WtNlsbrdb2etVq9UlpaXMu69oNJrSMuX7abFaxeyPxWJRvIby8nIWqi/7WVERagveTD4OsZGPAwAAAABmLykxUc7hxsbHFb9k4kIfKigoEGE//tjYmJj9EWHBl5WVqdXER767gVQofwMZG5V1wScmJjDvEBk3OAAAAADA7CUnJ8k5nMyxzkdatnwZ8+4rSwVopsfjsYq6f1yEBR9pNC5YsIC16rMbyDLl1/zYuKzrKplHvEJs5OMAAAAAgNmTOfgYGR1R/JLLysuNUVFMvU9UVlYqXsPo2JgkecXsz9j4mCRJyk/TqlWsVZ/IyMjIyMxUvIzhYflupBERESalz1sHrox8HAAAAAAwezHR0ZGRkbINNzg0rPglazSaFSuWM/VzZzQaFy5apHgZwwIsqo/j8Uijo6OKl7Fq9WqWq08I8knD0LB8a17m3zECZoF8HAAAAAAwJ6kpKbKNNTQ4JMIl37B+A/M+d2vXxR3fMgAAIABJREFUrdNoNIqXMTg0JHKXhgSI7xcUL0hNTWXFzt36DesVr0GSJDn3j8v5BgHMDvk4AAAAAGBOMjLSZRtraHjI4/Eofslr1q4xGAxM/Rxt2LhRhDL6BwZE7pIg5a3fyGdCc5WQkCDCL0yMjo25XC7ZhsvMyGDqITjycQAAAADAnGRmyhd/uN2ekRHljyA3GAxr161j6ufCFBu7snKlCJX09/eL3ChByrvp5ptZtHN04003heCKkvMNApgd8nEAAAAAwJzIvD2wu6dHhKu+4847mPq52Lxls1arVbyMyclJq3VC5Eb19PZ6vco/PrSoqGj+/Pms27m4XYybRk9Pr2xjGY3GuLg4ph6CIx8HAAAAAMyJ0Wg0m82yDdfV1S3CVS9ZujQzM5PZnx2VSnXHnXeKUIkgy+kK7PbpEQEe0RkWFnbHXXeydGetoqIiJydHhEo6u7pkGyuLzeMIBOTjAAAAAIC5ys3NkW0scQLNu++9h6mfnWXLl4VgVjiHNS9EkZs2b46JiWH1zs49990rQhlOp3NAxhPtc3NzmXqIj3wcAAAAADBX+TKGIKNjY1NTUyJc9e133BEdHc3sz8L2Bx8UpBLx94+HhYV1ilGkwWC4a9tWVu8spKWl3bB+vQiV9PT0SpJ8x/XkkY8jEJCPAwAAAADmKi9P1hCkS5i4cNs9dzP716qwqGjFSiGezOl0Ovtl3Es7+wXfKcom93vvvU+v17OGr9UDD25Xq4WI4Lq65VtLkZGRKSnJzD7ERz4OAAAAAJirqKioxMRE2Ya71NYmyIVvf/DBqKgoFsA1+fRnPiNIJe0dHZIkid+x0bGxcYtFhErM8eat27axhq9JUnKyIKfth4WFXbwo382TzeMIFOTjAAAAAAAfmFdUKNtYLa0XBbnq6OjoB7ZvZ/av3oLi4rXr1gpSTKswC+kvunhRlFIf+eQnIiIiWMlX77HHHtPpdCJU4nA4unvk++WbIhnfFIC5IB8HAAAAAPjAvHlFso1lsViGR0YEufDtDz0o5975QPelL39JnGJaLwZMPi7OZ0KxsbEPP/IIK/kq5ebm3nr7bYIUc6mtTbbDx9Vq9TzycQQI8nEAAAAAgA9kZ2XJuatUnJ2/BoPhc1/4PAvgaqzfsGHhokWCFDM6NjY2Nh4orWtra/d4PIIU8+DDD6WkpLCer8ZXvvZVjUYjSDFy3jbT09KMRiMLAAGBfBwAAAAA4IsfL9XqwoJ82YZraW0V59o3b9lSVl7OGriyiIiIvxZp83hLS2sAdc/pdHZ0dgpSTHh4+Je+8hWW9F+07rrrlq9YIUgxXq9Xzt9CmD9/HgsAAfMfMLQAAAAAAOATJSXFso3V3t5ht9vFufZvf+fbghwxLKy/+uxnhdp03NDQGFgNFKrgG9bfsO66dazqKzBGRX3jiW+KU093d/fk5KRswxUXL2ANIFCQjwMAAAAAfGNeUVF4eLg8Y0mS1NDYJM615+TmfvLRR1kDH6e0tPTe++8Tp56JiYnOrq7A6mFDY5MkSeLU840nnoiKimJtf5zPf+HzQj2Z4Nz5BtnGSklJTkxIYA0gUJCPAwAAAAB8Q6vVyvk79ecbGoS6/E8+9mhpaSnL4MMiIyO/+4/fU6lU4pR0PtA2j4eFhdnt9rb2dnHqSUxM/Oa3nmB5f6TKVZVbt20Tpx6v19vQKN+aL+NOiIBCPg4AAAAA8Jmy0hLZxmpv77DZbAL9gK1Wf++f/olH0n3Y177+9YyMDKFKOn++IRA7KVrZN91886bNm1nhH2A2m//uH/5BqJI6OjsnJ6dkG65UxjcCwAdv37QAAAAAAOArRYWFkZGR8ozl9Xrrz50X6vL/H3v3HR/XXef/fs6cMr1o1GWry5LcQ5zEKSQhTk8oAZyEsvwusHeXspXdy5bH7j4uv+1sgd9elrqQEEJCOpAE0pw41SWusS13W7LVuzS9n/uHwBjHcTSa0ZnvmXk99/FgbSPN+erzPXO+6H2+8zkNSxr+5u/+VqiN0kV32+233/6B9ws1pKmpqf6BATMW8+ChQ+l0Wqgh/cVf/WVrayvn+RmyLP/9P/5DIBAQalT79u037FiNS5dWCvbjAxdGPg4AAAAAKBhZltesNu6T9bt27RatAtdt2PCJ3/kkZ8Kcrq6uv/zrvxJtVLt27zFpPWOx+EGR2u5bLBaHw/Gv//ZvLhqR/9rnv/iFdZdcItSQksmkkbcSL774PZwGMBfycQAAAABAIa0zMBwZHRsbEG8j8Bf/4A+uvOoqzoTq6up/+4//MOyRrfOUzWZ379lr3qru2LVLtCE1NTf9/T/8vSzLnPO33Hrr73zqU6KNav+BnmQyacyxVFU18hYpUBDk4wAAAACAQqqvr6+rqzXscDvF20JutVr/6V/+ubu7u5xPA6fT+R9f/1pNbY1oAzty5Gg4HDZvYfv6Tk1OToo2qiuvuupLf/7nZX7pu3jdxX/zd38r4MB2GnhPZcXybpvNxjoIcyEfBwAAAAAU2KUGthfYf+BAIpEQrQJ2u/0/v/71xsbG8jwBNE37l6/+a2dnp4Bj27l7t9nLK+A9IYvF8tGNH/3MZz9bthe9zq7Or/77vyuKItrARsfGBgYGDTvcJZesYwWE6ZCPAwAAAAAK7D0XrTVsC2Eymdq9R8R20oHKwDe+9c26urpym31FUf7hn/7xsvXrBRzbxOTk0aPHzF7hXbv3pFIpAQf2+5//3N0f/1gZXvFaWlr+6xvfcAvZhH3r1m2GHau2tqa1pYUVEKZDPg4AAAAAKDBN095z0VrDDrdl67ZsNitgHWpra7/57W83NDSUz9Srqvr3//gP11x7rZjD27JlawkUORaLiXlPyGKx/OmXvnTX3XeX1eWuta3tv7/9Lb/fL+DYwuHwW/v2GXa49ZddxvIHMyIfBwAAAAAU3vr1l0mSZMyxZmZmew4eFLMODUsavvO97zY1N5fDpNvt9q/++79dt2GDmMOLRqN79r5VGqXeskXQe0IWi+VLf/5nn/7sZ8rkQtfd3f3t736nsrJSzOFtf3NHOp0x7O1v5G1RoIDIxwEAAAAAhVddVdXR3m7Y4d54Q9x9wdU1Nd/7/v+sXrOmtGfc5/f/139/44orrxR2hNvf3JFOp0uj2lPT04cOHxZ2eJ/7/Oe/9Gd/ZrWWeOi0fv36b37n2z6fT8zhpVKp7W/uMOxwl6y7WFVV1j6YEfk4AAAAAGBRXH31VYYda3Bo6OTJXmFL4fP5/vtb39xw/YZSnevGpqbv3/ODNQLfA0gmk9u2v1lKNX/ttTd0XRd2eHd97O5//bev2u32Uj3n3//BD/zn//m60+kUdoQ7d+2OxWLGHEuW5SuvuJxVDyZFPg4AAAAAWBRtra1Llywx7HAvvrRZ5GpomvZP//Ivn/vC52VZLrGJvvKqq+754b1Lly4VeZDbtm+PRqOlVPbBoaEjR4+KPMKrr7nm+/feI/iJsQCKovw/X/7y3/zt34r8Xk6lUq++9rphh1u7ZrXX62XVg0mRjwMAAAAAFouRW8hP9/cfO3Zc8IJ8+jOf+dp//R9huxXnSlGU3//c5/7z619zu90ijzMej7/+xpbSe3+9+NJmkbeQWyyW9vb2e3903zXXXlMyNa+tq/3Wd77z0Ts3Cj7O7W/uCIfDxhxLkqSr33uVBTAt8nEAAAAAwGJZsXx5dXW1YYfb9NJLgseFFovlsssuu//BB668yvRx0pKlS77zve9+5nc/K/5Qt2zdFovFS+/9NTIyevDgIcEH6Xa7v/rv//7lv/yLEui1suH66+9/4IHVa1YLPs5EIvHa628YeJ3vNvI6DxQc+TgAAAAAYLFIkrThfdcadrihoeHDh4+IX5aKior//PrX/vbv/s6kHQmsVuvGOzfe/8ADK1etEn+00Wh0y9ZtpfoWe3Hz5mw2K/44P/LRj953//0XXXSRSevs9/v/3//9v//pX/7Z4/GIP9qt24zrJiRJ0obr3sdiB1MjHwcAAAAALKLVq1fV1NQYdrjnXnghk8mYojK3f+D9P3n44RtuvNFcE9re3v6d733vz7/8ZYfDYYoBv7T55UQiUarvr/HxiZ27dptiqE3NTd/+3nf/8q//yly3hSRJuv3973/40UduufUWUww4FAoZuXl85YrltbW1rHQwNfkrX/kKVQAAAAAALB6X03mg56Axx4rFYna7ramx0RSVcTgdG67fcOmllx47emxyclLw0fr9/j/6kz/+67/5m7q6OrOce2NjYz978knhm+7kZWBg8NJL1imKYorRdi9f/qE77ojHYkeOHBG/G9LKlSv/+av/uvHOjTbzNIf5xTPPDg4OGnMsq9V6150b3W4XyxxMjXwcAAAAALC4ampqDh0+YtjD4voHBtdd/B5N08xSn7q6ujs+8uGWlta+3t6ZmRkBR+h2uz/9mc/8/T/945q1ayVJMtG59+jjT0xNTZf2+yuVSmUymWUdHWYZsM1mu/Kqq66/8YaZmZm+vj4xU/LW1tYv/+Vf/MmXvmTkx1/yNzg09PTTvzTscGvWrL7s0ktY42B2kl7ad1EBAAAAAAI4ceLkvff9yLDDXbLu4g998AOmq5Ku6y9u2vTA/T8+fPiwIEMKBAIb77zzzrvvcrvdpqvn4SNHHnjwoXJ4f1mt1j/6gy9UVVWZbuQnT5780Q/ve3HTpnQ6LciQuru7P/mp37n+hhvMdSto7gLy/XvuPX2635jDKYryp3/8h36/nwUOZkc+DgAAAAAwwn0/+vGx48cNO9zv/9+fbTRJl5W327Vz5+OPPfbaq68VMTRcuXLlhz58xy233qqqqhlrmEwmv/HNb83MzJbJ+6u1peUzn/5fpot054yNjj326KO/ePrpqampYo1BUZSrr7l64513XrxunVmvG7v3/OznTxp2uPdedeUtN9/E0oYSQD4OAAAAADDCyMjot77z3Ww2a8zhaqqrv/iFz8mybN6KzczMPPvMM5uef+HgwYOG/fJeV1d3/Q033Hr7be3t7aY+35559rktW7eV1Vvsjg99YN3FF5t3/JlM5tVXXnn2mWe2b9tu5CNVO7s6b7zppttuuz1QGTBv9cLh8H9945vxeNyYwzkcjj//0p/YzdOWHbgA8nEAAAAAgEF+9uRTO3fuMuxw173v2g3Xva8E6jY8PPzKyy9v3bJl7569yWSy8NGAJHV0dFx51ZVXvffq1WtWl0DFBgYHv/c/Pyi3xMNut//JH/2BGTvhnCMajb7x+utvvP7Gtm3bZhenI7+iKGvXrr38yived911S5cuLYHZf+iRR3uMegyyxWK5/bZbr7h8PYsaSgP5OAAAAADAINFo9Ov/9Y1YLGbM4WRZ/uIXPldTXV0yBYzH4/v27dv/1r79+/cfO3o0n2YUDoejvb195apVa9auWXvRRZWVlSVTpUwm8+3vfm90dKwM32IrVyz/2N13lcyPo+v6kcOH9+7du3/f/oM9PaOjo/mkWC63u6urc83atatXr77oooucLlfJFOrQ4cMP/uRhww5XW1v7h1/8vEmb+QBvRz4OAAAAADDO9jd3PPX0Lww7XEN9/e//3u+ausvKBczMzJw8cWJwcHBkeGRsbDQYDM7MzITDkVQymUgm9WxWVVVN0+wOh8/n8/v9VVVV9fX19Q31zS0tS5YsKdVz7IVNL7762utl+xa7c+NH1qxeXZI/WjQSOXHiZF9f78jwyNDQ0MTExOzMzGwwmEwkkslkKpWSZVlVVc2meb0+n9fr8/vrG+rr6+qXNi5ta2+vq6srybJEIpH//ta3w+GIYUf83c9+urWlheUMJYN8HAAAAABgHF3Xv/nt746MjBh2xKvfe9VNN95A5ctE36lT99x7XzlnHTab7Q+++PkKv5+ToUyuqA/85KEjR44adsTVq1fdfedGKo9SYqUEAAAAAADDSJJ0xwc/YLUa99voa6+/0dvbR+XLQTwef+zxJ8p8I2AikXjs8ScMexAuimvHzp1GhuN2u/32W2+h7Cgx5OMAAAAAAEMtXbpk/WWXGnnEx574qWFNz1FETz719OxskDqcPt1fzh1mysf4+Pizzz1v5BFvvunGEngALHAO8nEAAAAAgNFuvOF6n89n2OGCweDjT/yU/qKl7c0dO/Yf6KEOcza//PLJk73UoYQlk8mHHn40lUobdsSW5uZLL1lH5VF6yMcBAAAAAEbTNO0D77/dyCMeOXrs5VdepfKlqn9g4JfPPEsdzshm9UceeywYZDd9adJ1/ac/+/nY+LhhR1QU5Y4PfYDKoySRjwMAAAAAiqC7q/M9F6018ogvbX756NFjVL70hMPhnzz0SCZDx+3fEolEH3zo4XQ6TSlKz5atWw/0HDTyiNdvuK6qqorKoySRjwMAAAAAiuP22271eb1GHvGxJ56Ympqi8qUkk8k8/MhjoVCIUrzd4ODQL375DHUoMSd7e59/YZORR2xqanzvVVdSeZQq8nEAAAAAQHHY7fY77vigJEmGHTEWi9//4wd5VmcpeerpX/SdOkUd3snOXbu3bN1KHUrGxMTEQw8/ks0a9zQFTdM++uE7jLxQAwYjHwcAAAAAFM2yjg6DH/g2MTn54EMPZzIZil8CXnn1tV2791CHC3vm2ecPHjpEHUpAJBK5/8cPxmJxIw960403VFZWUnyUMPJxAAAAAEAx3XbrLTU1NUYesa/v1E9//qSu6xTf1PbvP7DpxZeow3w89vgTA4OD1MHUUqnUAw8+NDU9beRBu7u6Ll9/GcVHaSMfBwAAAAAUk6Iod9+5UVVVIw/61lv7iFZNrbe374mf/Yw6zFMqlf7xAz+ZpPm+aWWz2ccef6J/YMDIg3q93o98+EMUHyWPfBwAAAAAUGS1tTU333SjwQd99bXXX3v9dYpvRv0DAz9+8CfpNE1ychCJRO794X2zs7OUwnR0Xf/pz35+8NBhIw9qtVo3fuTDTqeT+qPkkY8DAAAAAIrv8vWXrVyx3OCDPv/Ci9u2v0nxzWV4ZORH9z+QTCYpRa5mZ4P3/PC+UChEKUxE1/Wnnv7F3rf2GXzca6+5uq2tlfqjHJCPAwAAAACE8JEP31Fl+FPgfvHLZ3bv4QGPpjE+Pv7D++6Px+OUYmGmpqZ/eN/90WiUUpjFc8+/sGPnLoMP2tHevuG691F8lAnycQAAAACAEGw22yc+fremaQYf96c/e9L4+AkLMDIy8oN7f0i2m6ex8fEf3PvDcDhMKQSn6/ozzz73xpatBh/X7/PdfddGSZKYApQJ8nEAAAAAgChqamo+9MEPGH/cJ596esvWrdRfZAODg/f88L5IhHC8AMbGxr9/z730IheZrutPPvX0lq3bDD6uoigf+9hdDoeDKUD5kL/yla9QBQAAAACAIOpqaxOJRH//gMHHPX78hCRJrS0tTIGA+k6duu9HP04kEpSiUGKxWM/BQ11dnU6SUPFks9knfvqzPXvfMv7Qd3zwA11dnUwBygr5OAAAAABALB3t7f0DA1NT0wYft7evL5FIdLS301hAKIcOH/7JQw+nUilKUViJROJAz8H2tlaPx0M1xJFKpR5+5NGeg4eMP/SVV1x+zTVXMwUoN5Ku61QBAAAAACCUeDz+ne/+z8TkpPGHXrG8e+NHP6KqKrMggm3bt//ymefILhaPpql3bdzIlmFBhMPh+x94cGho2PhDt7e3ffp/fYq7gyhD5OMAAAAAABFNTEx8939+EIvFjD/00iVLfueTH3e5XMxCEc09nHDrtu2UYrFJkvT+22+97NJLKUVxjY2P3//jB2ZmitAXvqqy8vOf+z273c4soByvgeTjAAAAAAAx9fb13fejH6fTaeMPXVHh/+THP1ZbW8ssFEUikXjs8ScOHzlKKQxzxeXrb7n5JqvVSimK4tjx4488+lg8XoQm+y6X63O/97uBQIBZQHkiHwcAAAAAiGvvW/sef+KnRfnVVVXVD3/og6tXr2IWDDY+Pv7gQw9PTExSCoO1tDTffedGt9tNKYyk6/orr7720uaXi3Wh++yn/6/GxqVMBMoW+TgAAAAAQGgvv/LqphdfKtbRr7h8/c033SjLMhNhjJ6eg0/87OfJZLIgr+ayJW5cvr+U6jMVcb96rHvxXt/j8Xz8Y3c1LiUtNUgikXj8iZ8eOnykKEe3Wq1337Vx5YoVTATKGfk4AAAAAEB0P3/yqR07dxXr6M1NTXdu/IjP52MiFlUmk3n+hU1btm4r7Mt+6vLXumqHS6ZKP9lxZc/Q4obXsizfcvNN6y+7lEc1LrbhkZGHH3l0cnKqWAO4/bZbr7h8PROBMkc+DgAAAAAQna7rDz/y6IGeg8UagN1u/9AH379q5UrmYpGMjY8/+tjjIyOjBX/lGk/wD697ziqVQvpxeqrqe69tMOZYncs6PnzHh+i1snjXtDe2bN304ouZTLZYY3jftdfccP0G5gKQv/KVr1AFAAAAAIDIJElavry7v39genq6KANIp9M9PQdnZmba2loVRWFGCkjX9Td37Hz4kUeCwdBivH4kafM6Ykv806YvlMXyyM4rZmNOYw43OTW19619NdXVlZWVnKWFFQwGf/LwIzt37iriptXLLr3k1ltuZi4AC/vHAQAAAABmkUwm77n3voHBwSKOoaLCf8cHP9jW1sp0FMTs7OzPn3r62LHji3oUty3+Zzf8UlPSpq5Vz9DSn+y40vjjXrLu4ptvutFut3O6FsTevW/98tlnY7F4EcewauXKu+/aSP8cYA75OAAAAADANGKx2A/uvW9kZKS4w7j4PRfdcvNNDoeDGVkwXde3bX9z04svFepRnBe2oatnQ3ePecuVyVr/v5dumYwUp9uJx+N+/+23rVi+nPM2H9PT008+9fTxEyeLO4zurq5PfPxuq9XKjABzyMcBAAAAAGYSjUa/f88Px8bGijsMt9t1+623rlpFR/KFGB0b+/nPn+ofGDDsiJqc/tINv/TY4yat2NaTy36x/z3FHcOK5d3vv/02j8fDCZyrbDa7bfv2TS9uTqVSxR1J57Jln/zEx2RZZlKAM8jHAQAAAAAmEw6Hv/+DeycmJ4s+krbWlttuvaW2tpZJmadYLPbS5pff3LEjmzU6jrik+eQdF+00Y9HiKfVrm26PJrWij0TTtGuvufrKKy6nC//8nTzZ+8tnnh0t9i09i8XS3tb2qd/5BHMHnIN8HAAAAABgPqFQ6J577xufmCj+79WSdOkl667fcJ3T6WReLiCbze7YueulzZuj0ViRZkr/o+uer/HMmq50zx9c8+qxbnHGU1Hhv+Wmm1asoN3Ku5iann7uuecPHjoswmDa2lo/9clPqKrKvADnrg7k4wAAAAAAMwqHw//zg3snBdhFbrFY7Hb7NVe/9/L1lxE/vZ2u60eOHN304ktF30LbVTv8qctfM1f1ZmPOr2+6NZ0VriFGa0vLDTdsaGps5Ax/u0gk8uprr7+5Y0c6nRFhPMs6Oj75iY+xcxw4L/JxAAAAAIAppdPpXz77/L59++JxUZpKu92ua66++tJL1pFDnXH06LEXN28eGhoWZDyfvfLltuoxExXwsd3r9/Y3Czu8zmUd12+4rqGhgVN9TiwWe/2NLdu2b08mU4IMyePxXnfd+y675GJmBzgv8nEAAAAAgClt3b6jv38gk8mcPHkiFouJMzCPx3PtNe+9+D3vKee95LquHzt+/JVXXjvd3y/UwBr801+4ZpMkmSMMGZ6t+NbLN4o/1uXLu6+9+r1Lliwp5ytSNBrdtv3NLVu3JRIJcUbl9fqam5slSbp8/aVNjUtZOIC3Ix8HAAAAAJjPyd6+nbv2zP05m8329vZGImGhRuh0Oi695JLL11/mdrvLamrS6fRb+/Zv2bp1bGxczBHeuW772qWnTFHMe7dce2LcNE9/bW5ueu+VV3Z1dUqSVFbn/OTk5Jat2/bs3ZtKpYUaWEVFoPHXDXBUVb3phg0uF49JAM5FPg4AAAAAMJlwOPz8ps3p9G+iKF3XT53qCwaDog1VluW1a1avX39ZQ319yc9LKBTatXvP9jd3hMNhkcfpd0T/9IZnFGtG8HoeHa3/0barTXcaVFVVXnH55WvXrLbZbKV9wuu6frK3d9u27YePHBVyIqrP6XtTVVl53XXXlNe9C2AeyMcBAAAAAGai6/qLm1+Zmpp++78PDPRPT0+LOez6+rpL1q0rydAwm80eP35i1+7dh48czWazphjzzSv3Xd1xWOiq6tJ/b75pLOQz6VmhqurqVSvXrbu4JB/gGQqFdu/Zu3v3nilRLzh1dXU1Nef55MGqlctXLO9mHQHORj4OAAAAADCTAz2HDh56x2RzeHh4fFzcpy+qqrpy5Yo1q1a1tbXKsmz2uRgeGTlwoGfvW/sE3Ll/YXY19Wc3/MKpJYUd4a5TbT/de0kJvGFraqovWrt21coVFRUVZv9ZksnkkSNH9x84cOToMWFvBUmStGTJkkCg8rz/rdVq3XDdNQHzzwVQyHcN+TgAAAAAwCwmp6Y2b341e8HfZCcmJoaHhwT/bdfhsK9YvnzVypWtrS2mC8pHR0cP9Bw80NMzMTFp3nPpirZjt6/eI+bYkhnl65tuC8XtpfTmXbKkYdXKlatWrvD7/eYaeSqVOnr02P4DB44eOyZah/FzWK3W5uZmj8d7ga/xuN033bihBO7PAYVCPg4AAAAAMIdsNvv8Cy8FQ6F3/crZ4Gz/6dOm6PVht9va29o6Ojo6l3V4vV5hx5lMJk+e7D167Nix48dnZmZL4HSSrdk/2fBswCViq/TNR1a+eHhlqb6Ra2qql3V0dC5b1tzcJHJKOz4xcezY8ePHj/f2nTr7aQfCUhSltbXN4XC861d2Luu4aO1q1hRgDvk4AAAAAMAc3tp/4MiRY/P84mg02tfXa4pU64zamprW1pbmpqampkYRsvJEItHfP3C6v//U6dOnTp3OZDIldkatahj42KVbRBtVOGH/2gu3JTNKyb+jNU2bO+HKbfB3AAAgAElEQVSbm5sa6usVpcg/sq7rk1NTp06d7u/vP3HypLnuA9nt9paWVk3T5vPFkiRdd+3VVVWVLCuAhXwcAAAAAGAK8+msco5UKtXb1xuPxcz48/p83qampiUNDUuWNNTV1trtRrTaSKfTExMTg0PDQ0ND/QMDIyOjJR8afO6aFxsrxOoS8/O31u3oay+3N7gsyw0N9U2NjQ319Q0N9YFAwGq1GnDccDg8PDwyNDw8ODh4ur8/EomasXoej7e5uTmninnc7ptuul42pMiA4MjHAQAAAACim39nlbd/4+nTp4NB0/cD8Xo91VVVlZWVgUCgMhDw+rw+r9fpdEqStLAXTCQSs8FgcDY4MzszOTk1OTk5PjExNTWVzZZXStAcmPi9q18SZzzjIe83Nt+c1aUyf8vLslxVVVldVRUIBCorK/0+39w5r6rqgq8hkUhkNhicnZ2dmpqenJycmJgcGx+PmfP+2dmqqqobGhoW8I10WQHmkI8DAAAAAER34OChgwcPL/jbR0aGx8bGSq8sVqvV7Xa5nC6b3eaw2202m6ZpiqJYrda5naS6ruu6nkqlUqlUIpFIJBLxeCIai4ZC4VQqxXk15xOXvbGiflCQwdy//b1HRhqYlHdit9vcLrfdYXfY7Ta7XVPVuXNekqS5e0XZbDabzSaTyWQqlUomY/F4LBaLRCKRSLT0EjBJkpYsWRoIBBb87TdseF9FhZ/zCmWOfBwAAAAAILRQKPT8Cy9l8nvY5uzsTH9/vyme2AmDVbpCf7zhOdla/HOjd6LmB2+8jxnBfKiq2tzc4nQ683mRCr//hhuuk6gmyhtthgAAAAAAQtu5e28m71zb5/N3dCyz2WzUE+eYjHhE6PetWyzP9KxlOjAfTqdr2bLOPMNxi8UyPTNz7Nhx6okyRz4OAAAAABBXb9+p8fGJgryU3W7v6Fjm8XipKs7x0pEVibRa3DHsG2gamqlgLvCuKisr29vbFUUpyKsd6DkUNX8TdiAf5OMAAAAAAEElU6l9+3sK+IKyLLe2ttbV1S34sZYoSdGk7ZWj3UUcQDprfeHQGiYCF2a1WpuampcsWVrAK1g6nd6zdx+1RVm/sygBAAAAAEBM+w/0JBKJgr9sTU1ta2tboXZfojRsOdE5G3MW6+jbTi6biTqZBVyA3W5ftqzT7y/84zQHB4dGR8eoMMoW+TgAAAAAQEQzM7O9J/sW6cXdbndnZ5fb7abOmJPOypsOrSrKoWNJ7eWjK5gCXEBFRWBRn6CwZ+8+XdepM8oT+TgAAAAAQES7976VXcy8RlGUtrZ2eq3gjL39LcOzfuOPu/noinhKpf44L1mWGxubGhsbrdZFDPGCodBRHtSJckU+DgAAAAAQzqnT/RMTkwYcqKamtr29XdM0ag7dYnm2Z63BB52KuLf3dlB8nJfT6Vy2rLOiwogHtx48dCQeT1BzlCHycQAAAACAWDLZ7P4DPYYdzul0LVJXX5jOifHaY2N1Rh7xhUOrM1nCGZxLkqSampr29g7D7t6lUqkDPQepPMoQl2AAAAAAgFiOHj0WjcaMPKIsy01NzU1NTbIsU/8y92zP2qxuUMudgenA/sFGao5zaJrW1tZeV1dvcPenvr5Ts7NB6o9yQz4OAAAAABBIIpE4fORYUQ7t91d0dna53R5moZyNBn17+luMOdYzPRdRcJwjEAh0dna5XC7jD53V9bf2HWAKUG7IxwEAAAAAAjnQcyiVShXr6KqqtrW1NTQsWdRH4UFwmw6tSmUW/ZMEB4eXnJqsoto4Q1GUlpbWpUsbi3j9GRkdHRkdYy5QVljvAQAAAACiCIXCvb19RR9GVVVVsfZvQojzMO5443jXoh4iq0vPH1xDqXGG3+/v6uryer1FHwlbyFFuyMcBAAAAAKI40HMwq+sijETTtPb2DjaSl61Xj3dHErbFe/0dfe0TYTr5wGKxWBRFaW5paWpqlmVFhPHMzs6ePt3PvKB8sMwDAAAAAIQwMzM7MDgk1JDmNpK73W5mp9wk08qLh1ct0osn0upLR1ZSZFgsloqKiq6ubp/XJ9SoDhw8rItxqxIwAPk4AAAAAEAI+w/0CJjIaJrW1tbe2NikKApzVFZ2nmobDy9Ks4tXjy3u5nSYgs1mm7u2yLIs2tjC4XBv7ynmCGWCfBwAAAAAUHwTE5PDI6PCDm9uj2cgEGCmykdWl57vKXyL8NmYY8uJTspbziRJqqmpFfyzKT2HDmezWSYL5YB8HAAAAABQfAd6Dgk+QlmWly5tbGtrt9nszFeZODTS0DdZXdjXfPHwqlRGprZly+VyLVvWWVdXJ0mSyOOMxWInTvYyXygH5OMAAAAAgCKbmJgcGx83xVDdbndnZ2d9fT3P7SwTzx5YW8CmPyNB/57TrVS1PKmq2tTU1N7eYbeb4x7b4SPH2EKOcsByDgAAAAAosp5Dh000WkmSqqtrurq6/X4/c1fyBmYC+webCvVqhU3bYaKLRlVVdVdXt99fYaJhx2Kxk719TB9KHvk4AAAAAKCYJienRkfHTDdsVVWbmprb29vtDgeTWNpeOLg6nS1AfnJ8rO74eC31LDcej6ezs7OhocGMHzo5fORoVueeDkoc+TgAAAAAoJjMtXn8HC6Xu3NZ59KlSxVFYSpL1XTUtb13WZ4vouvSs4vwtE+IzGaztba2tra2mfehBdForK/3FFOJ0kY+DgAAAAAompmZ2ZGRUbP/FIFAZXf38pqaGsEfuIcFe/nI8lhSy+cV9vS3jARpyFMuZFluaGjo7OzyeLxm/1kOHznKBnKUNvJxAAAAAEDRHD5ytER+u7Za6+rqTddfGPMUS2kvH12x4G9PZeRNh1ZRxnIgSVJ1dXV39/KqqurSuGEWjkQG+geYWZQw8nEAAAAAQHFEIpGBgcFS+ok0TWtqalq2rNPtdjO/JWZbb8d01LWw733jRFcwTp/60uf3V3R1ddfXN8iyXEo/1+Ejx5hclDDycQAAAABAcRw5erwkn/zmcDja2tpbW9scPLqzhGSy1ucPLqSBeCRhe+1YNwUsbW63Z9myzqamJk3TSu+nm56ZMeNTlIF5Ih8HAAAAABRBIpHo7Svlx755PJ5lyzqbm5vN+2g+nGP/YOPAdCDX73rpyMpEmse3liyXy9Xe3t7WVuL3w9hCjhJGPg4AAAAAKIITJ3szmUzJ/5g+n7+rq6uxsbEkd5WWoWd71ub09RNhz46+dupWkhwOR2trW3t7h8tV+v2URsfGZmeDTDpKEvk4AAAAAMBoWV0/caK3fH7eiopAV1f30qVLScnNrm+y+tBIw/y//rmDa7K6RN1KjMPhaGlpWbas0+PxlM9PffT4caYeJYl8HAAAAABgtP7TA7F4vKx+ZEmSAoHKrq7uxsZGm83GOWBez/WsnWfk3TdZfWh4CRUrJU6ns6WlddmyTq/XV24/++nTA4lkknMApYd8HAAAAABgtLLdhyhJ0txe8sbGJrudvuSmNM+WKXruzVggMpfL1dra1tGxzOv1lmcFMplMWX3uB+WDfBwAAAAAYKiJicnp6ZkyL0JFRUVnZ1dLS6vT6eSUMJ35PHLzwIIe5gkBeb3e9vaO9vaOsuqmcl4nTpzUdZ1TAiWGfBwAAAAAYKjjJ05ShDler7ejY1l7e4fH46UaJhJJ2F471n2BL8hkrc8fXEOhTE2SpDP3sVwuFwWxWCyxeHxgcIg6oMSQjwMAAAAAjJNIJAaJV36by+VqbW3t7OysqAhIEs9yNIc3TnQF4453+m+39XZMR0lUzUqW5erq6u7u5fRBejtarKD0kI8DAAAAAIzT23sqk81Sh7ez2x2NjY3Ll6+oqamVZYWCCC6VkTcdWnXe/yqW0l4+uoISmZGmafX1DcuXr6ivb1BVlYK83dj4eDAUog4oJeTjAAAAAADjnOhl7+GFKIpSV1e3fPnyJUuWsnFVcHv6W0aDvrf/+ytHl8eSGvUxF5fL1dTU3N29vLq62molLrvgZfwkl3GUFN7wAAAAAACDDI+MRiJR6vDuv6tbrZWVlZ2dXW1t7T6fj6YrYtJ16dmetef843TUtfXkMopjovdaIBBYtqyzvb3D7/dTkPk41Xc6k8lQB5QMPrEFAAAAADBIb28fRciJ2+12u92pVHJycnJqaiqdTlMToRwbqzsxXttePXrmX144tDqTZTOiCWiaVllZFQgEZFmmGjlJplIDA0PNzY2UAqWBSzYAAAAAwAiJRGJoeIQ6LICqanV19cuXr2hqana73RREKM/0rNX1X23wH5wJ7BtooiYikyTJ5/O1trbNtVIhHF+Yk319FAElg/3jAAAAAAAj9J3qz/JkzjxIkuT3+/1+fyKRmJqanJ6eZju5CEZm/Xv7m9/T1GexWN7ebgXi0DQtEAgEApWKQhqWr4mJyXA44na7KAVKAFcEAAAAAIARetlvWCA2m62+vqGurj4YDE5PT4VCIV3XKUsRbTq8etWS/hPjtb0T1VRDNFar1efzVVQE+OxFAem63tvXt3rVSkqBEkA+DgAAAABYdJOTU8FgiDoU0FybCJ/Pl06np6enp6en4vE4ZSmK2Zjj9eNddFYRjdPpCgQq/P4Kq5X2woXXd+r0qlUreXYwSmE95SYzAAAAAGCx7dq998TJXuqwqGKx2MzM9MzMTCqVohoGkywW4hVB2Gw2v99fURHQNI1qLKprrr6qrraGOsDs2D8OAAAAAFhcWV3vHxikDovN4XA4HI76+oZwODQ9PTM7O0PDd8MQjhedoig+n7+iosLpdFINY5w63U8+jlK4elACAAAAAMCiGh4eSSaT1MEwbrfH7fYsXbo0GAzOzMyEQkGCcpQqWVZ8Pp/f73O7PVTDYIODQ5mLL5JlmVLA1MjHAQAAAACL69TpfopgvDMNyrPZbDA4OzMzEw6HCcpRGmRZ9nq9fr/f7fZIEk2wiyOdTg8MDjU3NVIKmBr5OAAAAABgEaVSqeHhEepQRFar1e+v8PsrstlsKBScnZ0NhUKZTIbKwHQURfH5fF6vz+12E4uL4NTpfvJxmP7CQgkAAAAAAItncHCYKFYQVqvV5/P7fH5d18Ph0OxsMBicTafTVAaC0zTN6/X5fD6Xy0U1hDI2Np5MJnkUKkyNfBwAAAAAsIj6BwYogmgkSfJ4vB6P12JZGo1Gg8FgMBSMx2JUBkKdpU6n0+v1er0+m81GQcSUzWYHBoba2looBcyLfBwAAAAAsFiSqdTo2Dh1EJnT6XQ6nXV1dclkMhQKhUJB2pSjiBRFcbvdHo/X6/XIMrGVCfQPDJCPw9yXHUoAAAAAAFgkgwNDJK1moWlaZWVlZWWlruuRSGQuK4/H41QGi02SJIfD6fF4PB6P0+mkIOYyPj6RSCTY4w/zIh8HAAAAACwWmquYkSRJbrfb7XbX19enUqnwr4RSqRTFQQHZbDa32+P2uN0utyzLFMSksro+MDjU3tZKKWBS5OMAAAAAgEWRTCbHxieog6mpqlpRUVFRUWGxWBKJxFxSHomEeaonFkbTNJdr7v6LW1VVClIaBgYGycdhXuTjAAAAAIBFMTQ8QnOVUmKz2Ww2W2VlpcViSSQSkUg4HI5EImH2leNdzxyXy+12u1wuMvHSND4xmUylNCYX5kQ+DgAAAABYFINDwxShVM1l5YFApcViSSaT0WgkEolGo5F4PK7rOvUpc5IkOZ1Op9M193+KQvpU4rLZ7NDQcEtzE6WAGXGFAgAAAAAUXiaTGR0ZpQ7lQNM0TdP8/gqLxZLNZqPRSPTXaMNSVqeB0+l0OJxzJEmiJmVlkHwcpkU+DgAAAAAovJHRsXQmQx3KjdVqdbs9brdn7q+pVCoajcZi0Wg0GovFMpwSJURVVYfDMReIOxwONomXudHRsUwmw3NWYUZcvAAAAAAAhTdEcxVYLKqq+nw+n88399dUKhmNxeKxX6FxublomuZwOB0Ou8NBII5zpdPp0dGxhoZ6SgHT4VoGAAAAACi8YZqr4G1UVfOpms/7q7g8k0nHYvF4PJ5IxBOJRDwepx+LSJOl2u12m81ut9vsdofdbrdarZQFFzA0MkI+DjMiHwcAAAAAFNjU9HQ8HqcOuDBZVtxut9vtPvMvqVQqmUym02lFkUOhUCgYjHEiLb65x2l6vV673Z7NZhVFtdlsbA9HroaHuS0KU+JiBwAAAAAoMFISLIyqqqqqWiyW7q7OuQc8ptPpcDgcCofDoVA4EgmHw+FwOBaL6bpOuRbAarU6nU632+1x/5a5veHBYGhwaIgqYWFisdjM7Kz/1/2UALMgHwcAAAAAFNjw8AhFwILJsjwXjlssFkVR/H6/3+8/+wt0XY9EIpFoNBKJROdEItFYLBaL0aFljqqqc4/NdDmdTpfL5XLN/cFht5+p7duxZxx5X/xHycdhOlz4AAAAAACFlEgkpmdmqAMW7F1TWkmSzmnMckYqlYpGo9FYLBaNxhOJeDyemGtwHo/H4/FUKlUaG88lSbLZbDabzWG32+x2u81ms9l+9dxMh8PpdC4s6VZVYiLkZXh4ZHl3J3WAyRYdSgAAAAAAKKCR0TF6XyAf+aS0qqr6fD7fO+xg1XU9mUwmEonE3P9L/ko6lUqlUslUKp1KpdJz/5FOp9OZTMaYk1mSJEVRFFlWVFVRFFVVNVVVVVVR1bk/a5pm+zVN0zRNW4xhsH8ceZqamkqlUnNdkgCz4MIHAAAAACik0dExioB8KMpihWtntl3P/1symUwmk0lnMpl0Ons++lyCrutzf5j7myRJksUiSZJFkqy//k/r28iKoiqKLMtz7b+LTpIkWZYzmQwnIRYmq+tjY+NLljRQCphp0aEEAAAAAIACIh9HnlSRdjHLsizLslY+xVcV8nHkY2RsjHwc5mKlBAAAAACAQpkNBmPxOHVAPhS6YBex+AqdMZCX0dFxigBzIR8HAAAAABQMm8eRP5WItojF5+YE8hMOhyPRKHWAiZCPAwAAAAAKZnSMnYPIFxFtUYvPzQnkvRBwoxSmQj4OAAAAACgM3WKZmJikDsgTEW0xi8/mfeRtfHyCIsBEyMcBAAAAAIUxMz2TSqWoA/KhyLIkSdShWNi8j/yNkY/DVMjHAQAAAACFQSaC/ClsHi8qNu8jf7FYLByJUAeYBfk4AAAAAKAwxsdpPo58kc8Wl6Io7N9HAZaDMW6XwjTIxwEAAAAAhTFO83Hkjf4eRacoTAHyNTZBPg7TIB8HAAAAABTAzOwszceRP43940wBzG+CfBzmQT4OAAAAACiAyYkpioD8qapGEYo8BRr5OPIViUTj8Th1gCmQjwMAAAAACmBikuYqKAD6jzMFKJVFgZumMAfycQAAAABAAZCPoyDoPy7AFJCPoxCLAk+kgEmQjwMAAAAA8hWPxyORKHVAnhRZtlpJKoqM/uMoCG6awixYdQAAAAAA+eJz9CgIOl8LMQvk4yiEmZnZbDZLHSA+8nEAAAAAQL6mpqYpAvLHwzlFoCgKu/iRv2w2Oz0zQx0gPq53AAAAAIB8TU2Tj6MANPaPi4Et5CjM0sCtU5gB+TgAAAAAIF/T02wSRAFo7B8XZCK4UYFCmGJpgBmQjwMAAAAA8hIKhVKpFHVA/ohlRZkIblSgENg/DlMgHwcAAAAA5GWSBAQFomrEsoJMBDcqUADhcJi7pxAf+TgAAAAAIC88gQ0FYbVaFVmmDiJg/zgKQtf16ZlZ6gDRVx9KAAAAAADIxwzxBwqB5irMBUpxgeAGKkRHPg4AAAAAyAv5OApCo7mKMFRVlSSJOoAFAuWAfBwAAAAAsHCRSJT2sigI8nGmA6WHfBziIx8HAAAAACwcn51HoRDIMh0oPcFQKJvNUgeIjHwcAAAAALBw07PsDURhEMgKNh20IEcBZLPZYDBEHSAy8nEAAAAAwMIFZ4MUAQVhIx9nOlCKZlkmIDbycQAAAADAws0GCT5QAIosW61kFAJhOz9YJlAmWHsAAAAAAAuUzWYj4Qh1QP40G2msYDNCPo4CCZKPQ2zk4wAAAACABQqGQlldpw7In02zUQShyLKsKAp1QP7YPw7BkY8DAAAAABaIrrIoFPaPizgpbCFHIUSjsXQmQx0gLPJxAAAAAMACBYMhioCC4GmQIk4KNy1QCLqu02IFIiMfBwAAAAAsUCgcpggoCM1GfxXhcNMCBVssQiwWEBf5OAAAAABggYg8UBBWq1Wl1bV4NJrCo1CLBTdTIfIaRAkAAAAAAAsTJvJAIdDHg3lBiS8W3EyFwMjHAQAAAAALEY1GMzxyDYVgY5+ykBRFkWWZOiB/wRAPq4C4yMcBAAAAAAtBcxUUio3m4+JODVvIUQDhcIQiQFjk4wAAAACAhSDvQKEQwgo8Ndy6QAGk0+l4PE4dICbycQAAAADAQoQj5OMoDEJYcaeG1jcokEgkShEgJvJxAAAAAMBCRMjHUQiyLCuKQh3ExK0LFAq3VCEs8nEAAAAAwEIQdqAgSGDFnh1a36AwuKUKYZGPAwAAAAAWgg/LoyDIx0XG7n4UCrdUISzycQAAAABAzpKpVCqVog7In518XPAJsjNBKABuqUJY5OMAAAAAgJxFSTpQIDbiV7HZbXaKAFYNlDDycQAAAABAzqKxGEVA/iRJYv+44GiAg4KIxeMUAWIiHwcAAAAA5CwWJR9HAaiqKkkSdRAZ/VVQENlsNk5EDiGRjwMAAAAAchaN8Ul5FADZq/g0TbNaiY9QiIWDG6sQEhc4AAAAAEDOiDlQEPS2NgWbTaMIKMDCQWMuCIl8HAAAAACQM2IOFAT7x00yTdzGQAHQmAtiIh8HAAAAAOSMNrIoCIJXc0wT2/xRCDyiE2IiHwcAAAAA5CweT1AE5ElVVVmWqYP4uI2BAi0c5OMQEfk4AAAAACA3mUwmlUpRB+SJ5ipmYbNpkiRRB+SJG6sQE/k4AAAAACA3ZBwoCLp2mIUkSTYbNzOQ/9rB/nGIiHwcAAAAAJAbMg4UBF07TDVZ5ONg7UBpIh8HAAAAAOQmnmD/OArA4SAfN89k2R0UAXlKJJM6VYB4yMcBAAAAALlJkI8jbzyc01zY7I/86bqeTCapA0RDPg4AAAAAyA0BB/LnIG81FbvdZrUSIiHv5SPB8gHhcGkDAAAAAOQmQcCBvNlprmI2PKIT+eP2KgREPg4AAAAAyA0BB/KXz/7xdDpd9PFns1ld10t7zAWcMmAO7bkgIPJxAAAAAEBuEuTjyI8kSfn0s85ms0VP2cKRiCRJpT3mc7DlHywfKEnk4wAAAACA3LB/HHnSNC2fZtaapgWDoUwmW6zxT0xOOh0O043ZkeOYz5HntwMWiyWZTFEEiIZ8HAAAAACQm1SKgAN5ceS9E9nv9w0NDxdl8KFQWM/qiqKYaczhsJ7V1dzHfDZNVWVZ5uwFywdKDPk4AAAAACA3BBzIU/47kVVVtWna2Ni4wSNPJJOjY2OVlQGTjXl0gWMu+MSB5YMiQDTk4wAAAACA3KRSaYqAfDjsBYhZq6oqZ2Zng8GQYcPOZrMDA4OVgYoFN4cx45h/a+JoQY48l480+TiEQz4OAAAAAMhNOk0+joWTZavNpuX/OlartaqycnhkJG7Ucy8Hh4YsFktFRUVZjfls7B9Hnri9CgGRjwMAAAAAcpBKp3Vdpw5YMLu9YBlrRYVfluWBgcFMJrPYwx4fnwiHIzXV1SYcc1WhXtBht0uSxDmMBUvTXwXiIR8HAAAAAOQgze4/5MdZuD3IkiTVVFenUqm5XdKLJxgKTUxOOh0Oj8dtrjE7HA6Px1Oo17RarTabjXMYC5bi40cQD/k4AAAAACAHmQzpBvLidBayR4fX63E47JFIdHRsbJEGnEgkhodHLBZLTU216cZcW6Ax/2b6aLGCPKTTGYoA0ZCPAwAAAABykM6QbmDhJEkqeA/rmuoai8UyNTU9Oxss+ICz2ezA4FA2m/V6PAUcuRnHPIcW5MgHd1ghIPJxAAAAAEAOMuz+Qx7sNlvBG1g7nQ6P222xWEZGR+PxeGFffGBwKJlMSpJUXdCN2GYc85mRcxqDFQSlhHwcAAAAAJAD9o8jH47FSVdraqolSZrbN13A516OjY1HIhGLxVLh92uqypgtFouiKOoivCxYQYBiIR8HAAAAAOQgQ7qBPDgdzsV4WU3T/H6fxWJJpVIDg4V57mUwGJqcmrJYLLIsV1VVMubfTCJbyMEKghJCPg4AAAAAyAHpBvKxeNFqdVWV1Wq1WCzRaHRkNN/nXiYSieGRkbk/V1YGZFk22ZgDizVmy6Ld5EA50HU9q+vUAUIhHwcAAAAA5EDPZikCFsZmsy1eaCvLcmVlYO7P09PTs7OzC36pTCbTPzCYzWYtFouqqoGKCvONOVCxePPodJKPg0UEpYN8HAAAAACQg2yWrX9YoMXuy1EZCKiKMvfn4ZGFP/dycGgolUrN/bm6uqrgDxS9wJhjZhizpqnKr8cM5L6IkI9DLOTjAAAAAIAcZHWiDSzQYvflkCSpurpq7s+6rg8MDC7gYYCjY2ORSHTuz3a73ef1GjnmwQWOedzIMVvYQo58FhHycQiGfBwAAAAAkAOiDSyYAc919Pl8dptt7s+pdHpwYDCnb58NBqemps/8tbam2oCyFGLMUwaPmUd0YuGLCP3HIRjycQAAAABADsjHsTCaphnTlKPmrIA4GouNjIzO8xvj8cTZX+x2uw3bJV24MbuMGbOL/eNgEUGpIB8HAAAAAOSCnX9YEJfLadSBXC6X68xfp2dmZmbe/bmXmUxmYHDwTHInSVJNdbWBxSnUmGuMGbBhdztQiosIqwjEQj4OAAAAAMgBwQYWxsgdx7U11Wc/oHJkdDQWe5fnXg4M/ub5lhaLxefz2WyakfU535hjIo+ZLeRgEUFpIB8HAAAAAOSEcAMLYeQTHW02m/esZ1Tquj4wOJhOp9/p60dHx6LR6Jm/Wq3W6qpKg+tzvjEPiTxmp4t8HKwhKAXk4wAAAACAXBBtIHY6528AACAASURBVHd2u02WZSOPWFNdZbX+JvRIp9MDg0P6+Ro7zM4Gp6anz/6XykCgKM1DzDVm9o+DVQSlgXwcAAAAAJADgg0sgNPpMviIiqIEKirO/pdYLDYyOnbOl8Xj8eGRkXO/MVBRlCqZa8yqqqqqyrkNFhGYHfk4AAAAAABYXO5i9OKorDx3S/XMzMz0zMyZv8493/KcDdrVVb+1iZsxX3BaXZzbAMyOfBwAAAAAkIOzniAIzPOckZzF6MVhtVqrKs9tyT06Ohb99XMvBwaHUqnfavBts9n8fl8Ra2WuMbtoQY4FXBAsrCIQC/k4AAAAACAHEgE5cuR0OIp12lRU+DVNO/tfdF0fHBxKp9Mjo6NnP99yTk11ddHLZaIxO50uLgjIeRGxcs5ALOTjAAAAAIBcfo2U+EUSuXEVtQvH2+PjdDrd13dqenrm3HE6nW63EA1DamrmO2ZnUccsy1a73cYZjhwXEfJxCHZOUgIAAAAAwPyxXRS5Km4+7vG4nQ7HOf+YSqff/pU1NTWCVMzjnu+Ya4s9ZhctyJHzIkIaCbFwRgIAAAAAcsBH45ETRZaLvsW4pvbdQ2Sf1yvUVmizjJl8HDkvIqwhEAz5OAAAAAAgB+wfR05cAnQscdjtXq/nwmd1tQCdx3Mfc1XRx+l0OGRZ5jzH/FmtpJEQ7JykBAAAAACA+SMLQ07cYuwvrqmuvsCtnUBFhaoqopVuHmNWRRiny+nkPMf8kY9DuHOSEgAAAAAA5k8m2sC8SZIkSP8NVVUrKvznP6VluaqqUsDqmWXMgjzUFKZZRLjJCsHwP2sAAAAAADkg2sD82e12cU6YqsrK8w6mqqpS2A2tphgzLciRwwrCHVaIh5MSAAAAAJDLr5Hk45g3t0jJqSzLlZWBc/5R07QKv1/YAr7DmFWhxqwoit1u52wHKwjMelpSAgAAAADA/CmkG5g3t9st1Hje3rO7urpK8EfOnm/M1aKNmRYrmCc+gQQBkY8DAAAAAHL5NVLmF0nMi6IodrtNqCFJklRTXXXmrw6Hw+vxCF5GU4xZtBshEBb5OET8HzaUAAAAAAAwf6qiUATMh0fIzNTr9Z5pBlJTU22KSoo/ZofdrnBlwDxwnkBA5OMAAAAAgByQbmCehN1TXFtTbbFYPB6P0+EwSzF/PWa3sGOmxQrmgzusEBD5OAAAAAAgB8pvt0IGzstqtbpcTjHH5nQ6PR53TXW1ieop/phpsYL5rSDk4xDvtKQEAAAAAID5k61Wq9WazWYpBS7A5XSK/NzLJQ0Ngj+W03RjdrtcXBnwrtg/DgGxfxwAAAAAkBtarOBdeTxC7yY2XTgu/pglSXI5nZz5YPmA6ZCPAwAAAABywwZAXJgkSXTbKEOC3xSBEMsHHbogHvJxAAAAAEBuNE2jCLgAh8MhyzJ1KDdut9uMG/Nh7PJBPg7hkI8DAAAAAHJDPo4LYx9xeZJl2eFwUAewfMBcyMcBAAAAALlhAyAuzENzlbKdem6N4F2WD/JxCId8HAAAAACQGwIOXIDdbqfFcNnyeDwUARdaPrg4QDzk4wAAAACA3LB/HBfgJSEtY6qi0GIFF1w+uL0K4ZCPAwAAAAByo2k2ioB34vWSj5f3CcANElxg+bCRj0M45OMAAAAAgNzY7eTjeKdzg+Yq5Y4W5LjQJcLG8gHhkI8DAAAAAHJjI+DAOyAbhaqqDrudOuDtZFlWFIU6QDTk4wAAAACA3LB/HO/E5/VSBHjosQPWDpgH+TgAAAAAIDd8QB7nPzForgKLxWKxeLlNgvPhs0cQE/k4AAAAACA3NptNkiTqgHOweRxzVEVxOhzUAeew03gHQiIfBwAAAADkRpIkTdOoA87hpasGfnMycLME56IxPcREPg4AAAAAyBmbQ3HuKeF08OQ9nOH1eviUCc7hcJCPQ0Tk4wAAAACAnBFz4BzsF8bZZFl2Op3UAb+9cHBjFSIiHwcAAAAA5IyYA2eTJMnrobkKfovPxy0TsHDABMjHAQAAAAA5o78KzuZ2u2RZpg44m8fttlrJnXD2wsEHjyAirlMAAAAAgJyxDRBn89FcBW9jtVo9Hjd1AAsHRL9YUQIAAAAAQK6cTmIO/Iosy243MSjOgxsnOENVFFVVqQMERD4OAAAAAMiZy8WT9/ArHo9HkiTqgPNdKFyKolAHWCwWp8tFESAm8nEAAAAAQM6cTieRKOb4eQwj3hlP6cQcN3dVISrycQAAAABAziRJopMsLBaLpmnvdCZks1kRRpjJZEp7CgSvs9/n420Ci8XiJB+HqMjHAQAAAAALQYsVWC6Yflqt1lA4XNzhJZPJjBjx8eIRvM6apjkcdt4pcDlZMiDqVZQSAAAAAAAWgLADkiRduHuGLMuhUNGi22w2GwyGtDJ4JKDgdfaxhRwWi4v+4xAV+TgAAAAAYCHcbjdFKHMul/PCT190OhyhcCiRSBZleEPDw35/WSSzgtfZ5/VarQRQLBnk4xAUlycAAAAAwEJ4CDvKnt/nf9evqaqsHBgcNL5H9tj4uKZpF47vS4nIdbZarR4Pt9PKmiRJ3FKFsMjHAQAAAAAL4SbwKm+Koswn9NQ0zeVyDg4OGTm2YCg0OzNbVVlZPtMheJ3ncysFJczhsMt8hgCi4tQEAAAAACyEh82A5e3CncfPVl1VFY3FxsbHjRlYIpEYHh6pqqost54eItfZ6XRomsa7hvUCEBD5OAAAAABgIRRFsdvt1KFszX9HsCzLlZWBycmpYCi02KPKZDL9A4OKolRUVJTbjAhe5zLpBY/z4vNGEBn5OAAAAABggdgSWLZcTqemqfP/+spAQFWU4eGRRCKxqAMbHBpOpVI11VXlOS8i19nv80mSxHuHxQIQDfk4AAAAAGCBvF4PRShPFRW5tZOWJKm6uiqbzfYPDGYymUUa1djYeCQScTgcHk+Znpki11mWZa+HK0bZLhZeigBhkY8DAAAAABaIfLw8KYqygADa5/PZbbZUKjU4NLwYowoGg5NTUxaLpbamupxnR+Q6+yt4SieLBSAc8nEAAAAAwAKxJbA8LbiRdE1NtcViiUQiY2MFfoZkPJ4YHhm1WCxej8fhcJT5BAlbZ6fDYbPZeAeVG1VRnGX/roTIyMcBAAAAAAvkY0tg+ZEkqcK/wF3ALpfL5XJZLJbJqanZ4P/P3n0HtlGf/wO/qb2nbVnezoTskBSSEFZCy8pir/bbQVugzNIWKJRvofyA0vbbQoEOdoGWxAlZZJOEJGSRhOAMktiJh2zLjm3JQ8O60/3+UDGKHTu2dJJO0vv1V6TIp9Pz+egkPfe55+kQa5d4nq93ucLhMEmS1uxePC79OBuxhDz74EwqSBzy4wAAAAAAABAjhUIhk8kQh6yi0WgYhon5z+02a6RJY1OTOxAQp4dkvashFAoRBGE0GGQsizGScpz1Oh1NIxmVXVBcBSQOhyQAAAAAAACIHRIf2cZkNMbz53K5PLKYNBwO17tE6CHpdjf7fD6CIGiatljMGCCJx5miKL1ejwHKKnqsHwdpQ34cAAAAAAAAYhdzKWpIRwq5XKWKt46wzWqhKIogiFAoVO9qiGdTXm9HW3t75N9ms4mm6Tj3LRwOSyHO8aezpRxno9EYWdsOWUKPjwmQNuTHAQAAAAAAIHYGLAXNJsb4Fo9HMAzTuwjd5/O53c2xbScQCDS53ZF/syxrEmPfKIrq7OpKbZCDPT08H87gOMtYNlIeHbLluIH8OEgb8uMAAAAAAAAQu5hbNULaoWlarxenToLZbOotYt7W3u71DruHJM/z9a6G3uXeVqtFrCXJNE13dqYsRR4Ohzs7OmUyNrPjbEKXzqyhVCrRpgIkDvlxAAAAAAAAiJ1Or6NQKiE7GA0GsXLQFEVZzN/UsG5yuwOBwLC20NsrkiAIhUIhYoFjlVLZ2dUZDPakJMgNjY0i1iySbJzVarVcLsd7KhugBhdIH/LjAAAAAAAAEDuaojRaDeKQ8UiSNIq65tdoNPSuKg2Hw/WuhqEX3W5yuyO9IiPsNqu4L9ZiNte7XMmvRd7c0iKTyXpXfGd2nE0mI95W2QA1uED6kB8HAAAAAACAuKDESjbQ6XTi5m0JgrBF5VuH3kPS6/W2t3t6b2o0GpVKJe6OyWQytVrliq+n5XB1dHZ6Pd7o5d6ZHWd9AmYUSPEDArV0QPKQHwcAAAAAAIC4iNIXESTOnIDVvlqNRqVS9t70+Xy9fSAH4g8EGpu+eQxJkjarNRGv12qx+Pz+5paW5IQ3GAw2NjZZLGaKorIkziRJ4tQaPiAApAD5cQAAAAAAAIgL6iRkvMRVi7bZbNE329s9Xq93oAdzPO+qdwmC0HuPXq+XyxPS+o+mabPZ1Nra1tHZmejw8jxfV+9iGMaYsExi/zh7JBBno9GQiPMBIB1yuTz63AyANOEwBAAAAAAAAHExGPRo0ZnZzCZTgrasVCh0Om30PY1Nbv8APSRd9a4Qx/XepCjKajEn9FWzDNPY2BQMBhMaXldDYygUStBC+IHi3CSBONM0rdfr8P7KYDh7CmkB+XEAAAAAAACIC03TOh2SXBlLoVCo1arEbd9mtZJR51cEQXDVu7h+PSSbmtw+vz/6HrPJlNAC1iRJWq2WcDhcV+8aek/L4Wpubunu7lYpldoE97mVZpzNJhOJs2uZy4Ti45AOkB8HAAAAAACAeBlNSIJkLLPZlNDtsyzbp4NfiONc9a7oezweb7vHE30PwzBJWJqq1+sVcnkoFHI1NCZi+96Ojta2NqJf/ZPsiTPLslqtFu+yTIXi45AWkB8HAAAAAACAeFlMZgQhI8lkMl3i05cWs5mm6eh7fH5/09f9If1+f/9+klaLJTmlq202K0EQ3d3dzc0i9+oMBIKR16jTapVKRTLep5KMc6JPwECqkCSJwYW0gPw4AAAAAAAAxMtsQRIkQ0fWlIyRjTTD7HNnu8fj8Xg5jqt3NUT3iiQIQi6XGwz65ERArVar1WqCIFrb2rwdHWJtluf5epcrHA6TJGm1WZPzWqQZZ4VcrtFo8F7LPBqNWiaTIQ4gfciPAwAAAAAAQLx0Wi3yIJmHZdmktU80GY0sy/a5s8ntrq2r56J6RUYktJVlf3bbfyt3NzW5AwFxenXWuxpCoRBBEEaDQdbvhWdbnC1mXICSgTCskC6QHwcAAAAAAAAR4Dr6DBzTJPZOJEnSZrX0uVMQhGCwbz5apVJpNOpkxkEul0c60IbD4XqXCL063e5mn89HEARN0xZLUnOI0oyzUpnYHrCADwWAQSA/DgAAAAAAACKwmJAKySgMwySthkmETqdTKM5dhtue+FaW/dms/y3DHQqF6l0N8WzK6+1oa2+P/NtsNvUpCJ61ccZa4wz8UMCYQppAfhwAAAAAAABEYLYgFZJZA5rExeO97OeqxK3X6RQKefKjwTCMyWiM/Nvn87ndzbFtJxAI9PbAZFm2d5uIs0qlUqmUeN9lDJlMptNpEQdIC8iPAwAAAAAAgAgsqVgJCwnCMIzRaEj+86pUqkFaNZIkae1XGyRpzGYTwzCRf7e1t3u9w+7VyfN8vashHA5HblqtluSfgZBynK0WC956GcOKM6aQPpAfBwAAAAAAADF+XlKUyWREHDJDShaPR/Q2w+zvrL0lkznDo+tFNLndgUBgWFvo7clJEIRCodDrdCkcYgnGWaVSqVSoQp4hUngqC2DYh3eEAAAAAAAAAESBhEhmSNXi8QiZTGbQn6XuefJbWfZnNBpkMlnk3+FwuN7VMPRenU1ud6QnZ8Q5K5xkZ5yx6Dhj2KxWBAHSBfLjAAAAAAAAIA4b8uMZwWxO2eLxCMvXzTDPuNNi7n9nCiZ5VF576L06vV5ve7un96ZGo5HCQmkJxhlLyDODTCZLcndfgHggPw4AAAAAAADiMJvNNIWfmemNZVmjwZDafWBo2mwyRd8jk6V+ryK0Gk10G0mfz9fbb3Mg/kCgsembx5AkKZGltdKMM06zZQALrgOAtIIvLgAAAAAAACAOmqJMZhPikNYsFnNqF49HRDfDJAjCarVKYa8ibDZb9M32do/X6x3owRzPu+pdgiD03qPX6+VymUReiwTjrFQqB+kdCmnBjuIqkFaQHwcAAAAAAADR5NhtCEL6GqgmdfKRJNlbzl6pVOq0WulESalQ6HRn7E9jk9s/QK9OV70rxHG9NymKklSJbWnGGUvI050dHwSQVpAfBwAAAAAAANEgLZLWrBYJ5SUNer1cLifOLPktEbYz11kLguCqd3H9enU2Nbl9fn/0PWbTGeu1EeezksvlOp0O78c0pVQq+5xAApA45McBAAAAAABANCajUSaTIQ7pqP+y6JSz2axarValVEotVizLGo1n1OkOcZyr3hV9j8fjbfd4ou9hGMZkMkpw6CUYZ5vVIp2KOjAsuIoI0g7y4wAAAAAAACAmuw2VZ9OSBJdpa9Tq3By7NMNlMZtpmo6+x+f3N33dh9Pv9/fv22m1WChJNrCVYJyl0CcWYvwIQH4c0g3y4wAAAAAAACAmJEfSkUajVqlUEtyxPjloSe2YuV832naPx+PxchxX72qI7slJEIRcLjcY9JKdABKMs8VilubpBBgESZI4RQppBwcaAAAAAAAAEFNuTg4KI6QXkiRtVqS0hs1kNLIs2+fOJre7tq6ei+rJGYEID9dZz0CAxBmNhkg5e4A0gvw4AAAAAAAAiEmpVOj16K2XTvR6HVJaMSBJ0mbt29FUEIRgMNjnTrVKpdGoEbHhMptM/c9AgJTl5eYgCJB2kB8HAAAAAAAAkSFFkkYoirJiaXOsdDqdQqE458NsNhQdigVJktZ+ZyBAynJzcPCHNPwcRAgAAAAAAABAXEiRpBGz2cRItcZ3WjhntWW9TqdQYHl+jPQ6nVKpQBzSgkKhMBrRVRXSD/LjAAAAAAAAIDKz2YR6HWmBZVmzCSWe46JSqTQazUD/S5IklufHyY7V92kiN8eOIEA6Qn4cAAAAAAAAxIdESVqw2axopho/+8BhNJmMLMsgRPFQKpV6HVoapIG8vFwEAdIR8uMAAAAAAAAgPocjD0GQOLVKpdNqEYf4yWQyg17f/36api1mM+ITP5vNSlFIYUkawzA5dqz0h7SEgwsAAAAAAACILyfHzjBYNitdJEnascZfPBarpX8C12IxI6srCoZhcKZB6sd8u41GJwNITzhMAwAAAAAAgPhoisJaQikzGgxymQxxEAtD030quctkMqMBvQpFYzIZZZixEoZrhiB9IT8OAAAAAAAACYF0iWQxDGO1WhAHcZnNpuhrJqxWC2q7i4gkSZxykyyKovJycxAHSNcJjBAAAAAAAABAIuTl5qC4hDTZbTYMjehIkuw966BUKlHbXXRqtVqnQ1SlyGa1sCyLOECawschAAAAAAAAJATLsnas95QetVqFJGOCGPR6uVxOEITdZkU0EgGndqTJmZ+PIED6wjEFAAAAAAAAEqUASROJIUkyx462nAlks1m1Wq1SqUQoEgGlgSSIoihHPqppQTrPYYQAAAAAAAAAEsThyKVpGnGQDovZjCaHCaVRq3NzcAYigUxGo0KhQBykw26zylBcBdIZ8uMAAAAAAACQKAzD5CBXKBlyucxsNiEOiYZzQomWm5OD3qfS4XTiOiFIb8iPAwAAAAAAQAIV5DsQBInIQVYRMoJCITcZjYiDFNA0ne9AcRVIb8iPAwAAAAAAQALl5eWyDIM4pJzRYFChKDZkCqvVwqKmhwTk5uYwOMJDmkN+HAAAAAAAABKIpul8LCFPNZZlbTYr4gAZgyTJvNwcxCHligqcCAKkO+THAQAAAAAAILEKC5FASbHcHDtFIQMAGUWlUhkNBsQhheRyeS7OUkD6w6cjAAAAAAAAJJbNalWpVIhDqhj0erVajThABh5bbFZUWUmhAmc+WhpABkB+HAAAAAAAABKuENfgpwjLMna7DXGAjERRVG4O1i+n7sCOa4MgM44kCAEAAAAAAAAkWlFhAYKQErk5uaisAhlMrVYZjUbEIfl0Oq0JkYeMgM9IAAAAAAAASDitVmO1WBCHJDMajWo1KttAhrPbrDKZDHFIspLiIgQBMgPy4wAAAAAAAJAMSKYkmUwms9usiANkPJIk8/JyUQg7mWiKwlVBkDGQHwcAAAAAAIBkyHc6ZOiklywkSTqQMYSsoVQoLGYz4pA0eY48rNmHjIH8OAAAAAAAACQDTVEF6NKZLFaLRaFQIA6QPSwWs1KpRBySo6S4EEGAjIH8OAAAAAAAACRJSUkRgpAEKpXKbDalfDc4jkv5PoTDYUEQMnu4EedejrxcmkamK+E0arXdZkMcIGPgqAEAAAAAAABJYtDrUQMh0WiaduTlSmFPeJ4P9vSkdh+6urszvsgM4tyLZVm73Y6DQKKVlhYjCJBJkB8HAAAAAACA5ClDYiXB8nJzGIaRwp7I5XKv1xsOh1O1Ay0tp9UqVcaPOOIcTa/TGfR6HAcSh6bp4iIUV4GMwiAEAAAAAACQMbq6uv79/geJfpa5374yPz8f0Y5NvjNfcbAyEAggFIlgMhk1Go109segN7gaGp35juQ/tdfrpSiKpulsGHfEOVpOjt0fCASDQRwQEqHAmY/OnJBhkB8HAAAAAIDM0dnR8fe//S3RzzJ6zBjkx2NGkWRJceHhI18hFKJTKhQ2q1VSuySTsSzLtrSctlotyXxefyBwurWtpLgoS4YecY5GkqQjL+9UTU0K19RnsLLSEgQBMu2bCUIAAAAAAAAAyVRaUkxlekno5KNp2uHIk2CtbavF3O5p7+jsTNozcjzvqndZLGYym6YZ4hxNLpfl2NFAUnxmk8loNCAOkGGQHwcAAAAAAICkUiqVjlQUgshsebm5LMtKcMdomjabzI2NTUmrd+Gqd9EMo9fpsmoCIM596PV6gwGZXJGNKC9FECDzID8OAAAAAAAAyTZyRBmCICKL2azRqCW7eyaTkabpepeL5xNe76Kpye3z+6VWZwZxTokcu02hUOD4IBaVSpWPU5uQiZAfBwAAAAAAgGQzGY0WixlxEIVarU5y1enhIknSarH09IRcDQ0JfSKPx9vu8Wg0arValYUzAXHuH5B8R16W9GhNghFlpSRKY0EmQn4cAAAAAAAAUmDkiHIEIX4syzrycqW/n3q9TqFQdHd3Nze3JOgp/H5/k9tNkmR2Lh5PYpwDaRRnlmUdeXnI6ooSyZKSIsQBMhLy4wAAAAAAAJACjrxcjUaDOMT1k56inPmOdFkeG0mntra1dXSI30OS47h6V4MgCHq9Ti6XZ/OsSHycXekVZ7VaJfELLNJCSXERwzCIA2QkzGwAAIA0097eXl1dXV1V3dba6vP5/H5fIBBI+V4tuv6GcePHYXQAAGBYRo0o37tvP+IQs9ycnDTKBavVKo1G3dXV3djUJJfLRNxzQRDqXQ0cx1EUZbVkeyY0Os4yuUyBOBOE2WQKBIIdHR04aMSGoih05oQMhvw4AABAeqitqVn+0fKtW7fW1tRIcPdmzJyJ/DgAAAxXUVHBoSNH/P4AQhEDi9ms02nTa59tVmt3ty8cDtfVu4qLCsVa+d7kbvb7/QRBmExGLHGNjnM94vy1vNycUE+PP4CjTUzH6sICpVKJOECmQn0VAAAAqWtubn7i8cdvvP6Gd995R5rJcQAAgBh/kVLUyHJUIY+FVqtNx5IRcrlcr9cRBBEKidZDst3j8Xg8BEEwDGM2mTA3EOezIkkyP9/B4vRJDAdqkhw1EgdqyOhJjhAAAABI2a6dO2+7+ZZ1a9cJgoBoAABA5ikpLZbLZIjDsCgUirToyXlWVouFoiiCILq7fe7m5ji35vP73e7mr7dsjmwZEOezYhgmP9+BSTJcjnwHekVAZsNBAQAAQLo+3br14QcfQqlEAADIYAxNl6Os7XCwLOPMd5Akma4jzjAmkzHy77a2dm8c33M4jnO5GiJrCORymcFgiH/3OI5LeYjC4XD8CyMkHudUUSgUebm56fv2ST6SJMeMGok4QGZDfhwAAECiqqqqfv3Y46FQCKEAAIDMVl5WKmNZxGFIv+Epypmfn+4lts0mU+9LaGpyx9ZpXBCEeperN51ts1pF2Tee54M9PamNT1d3tygJXCnHOYW0Wk0GvIqkycvNidTqAcjkz1aEAAAAQIIEQXjqiScD6CAEAABZgGXZ8vIyxOGcSJLMd+TJ5fJ0fyEURVks5si/w+FwvauB5/nhbqSxyd3b2VWlUolV/0Eul3u93nA4nKrgtLScVqtUGR/n1DKZjCajEYeUoRxzxo4djThAxkN+HAAAQIrWrV177NgxxAEAALLEiBFlMlQhP5ecHLtarc6M12I0GHrrzodCoXrX8HpItre3e73e3pt2m5jLgQ16g6uhMSVh8Xq9FEXRNJ0NcU4tu92m1aKm9jk48nINej3iABkP+XEAAAApWrqkAkEAAIDswTLMSCwhH5TVasmwRJUtKtnq8/l62z+ek8/ndze39N7U63QKhULEHZPJWJZlW1pOJzkg/kDgdGtbb9HwjI9zyjny8lQiLdXPSFg8DtkD+XEAAADJ6ezsPHjwIOIAAABZpby8VI4l5AMwGY0WsznDXpRGo4nOTraduVR5ICGOczU09LavJEnSarWIvm9Wi7nd097R2Zm0aHA876p3WSxm0VtHSjnOqUWSpDPfkQEFixIk35Gn16HyOGQF5McBAAAk59ixYymsegkAAJASDMOMGjUScehPp9PZ7baMfGl96nU0nquHpCAI9fXf9IokCMJkNLIJaO5K07TZZG5sbAoGg8kJhaveRTNMgtKRko1zylEUVeDMZ9Ef+GyROW/sGMQBsmXCIwQAAABS425yIwgAAJCFystKUO6gD41G48jLzdRXp1AodFEZYUEQ6l2uQXpINjY1RSd2aZru7T8pOpPJSNN0vcvF8wlftdDU5Pb5/baEVfeWcpxTjmGYwgInwzA42kQrLipEfXbIHsiPEno7MgAAIABJREFUAwAASE4o1IMgAABANv5ApajzUO42ikqlynfkZfZrtFkt0RVFQiGuvt511ke2tbV7vR3R91jMZopKVFqDJEmrxdLTE3I1NCQ0Ah6Pt93j0WjU6kSeHJJsnKWAZdkCp1PEtqjpjmGYsWNGIQ6QRV8/EAIAAACpUSqxdA4AALJUUWGBPrO6UMbxfUDpzHeIXo1aaliWNRnP6Ejp8/ub3H2vpfP5fM0tLdH3yGSs0WhI6L7p9TqFQtHd3d3c3JKgp/D7/U1uN0mSNqstBXFukkScpUAulxU485EijygvL82wXqwAg0N+HAAAQHLyMn2lGAAAwCDGnT8WQVAqFAXO/MxetNvLYjH3yUu2t3s8nm96SIZCoXrXN70iI6xWaxJOHtisVoIgWtvaOjrE79XJcVzkden1OrlcloI4e6QSZylQKBTO/Gx50w1CLpePHjkCB2HIKsiPAwAASM6IESNkMhniAAAA2Sk3x56p7SiHSKFQOJ3O7MnTURRlMfctb93kdvv9AWKAYtlKpVKn1SZh39RqlUajJgiisUnkXp2CINS7GjiOoyjKarFkeZwlQqlUOJ3ZniIfO2YUqrFDtsGMB0g2nuePHDlSdeLEqZOnmpqa/D6fz+8fvHt49tBoNC/99WWcsQeQyWTTpk//dOtWhAIAALLTxPHnr1u/KXzmOtYsoVAoCpz5NJ1dX4mNRkNbe3soFOq9J5KuLS4qdDe3BAJ9E9OJa2XZn81q7e72hcPhunpXcVGhWCU4mtxuv99PEITJZExaOlLKcZYIlVLpzM+vq68Ph8PZd/gh9HpdaWkJPoMg2yA/DpA8B/bvX1pRse3Tbd3d3YjGQLZ9um3WxbMQB4BF1y9CfhwAALKWTqcrKSk+UVWdbS9cqVAUFDizcL0ISZI2q7VPJ0yO406equE4rs+DtVqNSqlM2r7J5XK9XufxeEOhkKuhocDpjH+bvYVNGIYxm0yIs6SoVMoCZ35tXTamyCeMH0cSAFkHizQBkqGxoeFn99z74x/dtXbNWiTHB1exZAmCAEAQxLTp06decAHiAAAAWeu8saOzrdqYUqnMzuR4hE6nVSr7tgTsn7SNZHiTvG9WiyUyLt3dPndzc5xb8/n9bnfz11s2J3nEpRxnqb0Zs61dpyMv127L3kGHbIb8OEDC7di+4/Zbb9u9axdCMRS7d+1yuVyIAwBBEI/9+nG9wYA4AABAdpLJZGPHjMqe16tSqQqyvvCxzXruuvMGgz75J04YhjGZjJF/t7W1ezs6Yt4Ux3Gur3tgyuUyQyq+7Ek2zpKiVCgKnFmUIqcpavy48/HRA9kJ+XGAxPp069ZHHn64q6sLoRiicDi8rGIp4gBAEEROTs7vX/y9RqNBKAAAIDuVlZUaDPpseKUajQbJcYIgVCqlVjvYN5+ktbLsz2wy9VYJb2pyx9ZBKlLsu3exdqoWaEs5zpKiUMiLCgvY7GhWOXJkeaQVLUAWQn4cIIHqamufePzX/S9Vg8GtWL4cQQOIOH/cuNf+8feCggKEAgAAshBJEJMnTiDJDC+Hq9PpnPmOjH+ZQ2SzWgcJhdlsStV6XoqiLBZz5N/hcLje1cDz/HA30tjk9vv/m1hXqVQpXAYh2ThLjUwmKywsyPil9Gq1evToURhuyFrIjwMk0P979tlIR3IYFo/Hs3HDBsQBIKK0tPTNd96+7fbb5XI5ogEAANnGbDYVFxVm8As0GY2OvFwMdC+ZTDbQRQNscltZ9mc0GORf50lDoVC9q2FYf97e3u71entvprbQs5TjLDUsyxYWFigUigx+jZMmjKMpZAghe2H2AyTKgQMHPt/7OeIQG3TpBIimUqnu+dm9K1atfOChB6dMnZrZ384BAAD6GHf+WHmGLt60Wi12uw1D3DcsXzfD7B+ulK+yt0UltX0+X2+bzXPy+fzu5pbem3qdLuXf6KQcZ6lhaLqwwKlWqzLy1TnycnNzczDKkNXvcYQAIEFWr1yJIMTsiwNfVFVVlZaWIhQAvXR6/Y033XTjTTcJgtDQ0HDq5MnTp0/7fX6f3xcMBGPYYGtr68oVKxBYAACQOJlMNm7ceXv27sukF0WSZG6OXa/XY3z7o2nabDa1tJyOvlMhl0shXBqNRqVS+Xy+yM229naF4tw7FuI4V8N/e3JGRt9qtSDO6YWiKGd+fmNjUzzdWSWIZZiJE8ZjfCHLIT8OkCi7d+1GEOJRsXjJz3/xCOIAcNZf1A6Hw+FwxLmd48eOIT8OAABpobiosLa2Lnr5bVqjadqRl5epa1FFYTaZPO2eUFRTIltKq5FEs9usJ0/V9N5sbHLL5fJBFoMLglBf74pusGQyGlmWRZzT8Ut4Xl4uK2NPn27NmBd13nljVColBheyHOqrACSEz+drampCHOKx5uOPUb0dAAAAACKmTJ7IMJmwwCtSyxjJ8cH1WWGtVqvVarVE9k2hUOh0ut6bgiDUu1yD9OpsbGoKBAK9N2ma7u3ziTinI6vFkpebkxklaMxmU3kZLtoGQH4cIDHa2toQhDh1d3ev+XgN4gAAAAAABEGo1erzxoxO91ehUiqLiwoztZy6uPR6vUIuJwiCJEm7xBY1286s0B0KcfX1rgF+GLZ7vWeU47BYzJSUGiFKOc5SnpwFznyaptP6VdAUNXXKJIwmAIH8OECCDLJ8AIauYvFiBAEAAAAAIkaMKDOZjOm7/3q9vqDAme45tWSK1PrQ63RyuVxSO8ayrMl4xlT0+f1Nbnefh/l8vuaWM4oCyWSs0WBAnDOASqUqLipM64iNHj1Kp9ViKAEI5McBEkSr0SAI8Tt+/Hjll18iDgAAAAAQccGUyemYXyZJ0m6zZUxNhqRRq9VajUYKrSz7s1jMfaZie7vH4/H23gyFQvWub3pyRlitVgnOASnHWcpYli0qLNCk529/o9EwetQIDCJABPLjAAlhMptVKpQUFMGSxUsQBAAAAACI0Om0548dk177TNO005mf1ivfU8jhyJNm3XmKoizmvmXEm9xuvz9ADFCUXKlUSna5rmTjLHEURTnzHVZLmp1aoGl62tQpOF0H8M17GSEASJDzx52PIMRv44YNHV4v4gAAAAAAESNGlKXRQleFQlFcVKjG0plYSTmFZzQaWJaNvieSFuc4rqGxKRAI9nm8TcLVvZEqjYfFYnbmO9Lo0pbzx47R6VBZBeAbyI8DJMqll12GIMSvp6dnxYoViAMAAAAA9Jo2dXKfvKQ0GQyGosKCtNhViAFJkjZr35Q3x3EnT9V0dHT0uV+r1aiUSgQtU2k0muKiQoVCIf1dtVotI0aUYcgAoiE/DpAoc6+80mQyIQ7xW1axFEEAAAAAgF4qlWrCeElfrElRVF5ebm6OHctyM5tOp1Uq+6ZEOY7rc89ZM+mQYSLlyA3S67/aZyenTZ2MwQLo+6mNEAAkiEKh+MnddyMO8aurq9u1axfiAAAAAAC9iosKC5z50tw3lUpZXFSo1+kwTNnAZrWd8zEGg14mkyFWGY8kydwce15ermSLuU+ZPBGd0gD6Q34cIIGuufaauVfORRziV4EunQAAAABwpimTJ2rUaqntVVlZybfnXpFjt2GAsoRKpdRqNIM8gKKotOvfCDEjSXJkedncKy6VYEvekuIiZ74DYwRwlgM1QgCQUL9+8smZs2YhDnHavm1bS0sL4gAAAAAAvRiGmT59KkVJ5VetXC6/6MLpkyaMp2na4chDcZXsYbNZBxlrs9mURp0bIR4URRU4861Wi1qtvuySi0eNHCGdg4BOp504YRzGCODsb16EACDR39qfe+H5//nB9/GVKB4cx320dBniAAAAAADRTEbj+WPHSGFP8nJzrpxzmSMvt/cei8VcVOjEr4BsIJPJDAb9Wf+LZRkzulJlzTQoLS3W6bSRmyRJjjt/7CUXz5TCZS40TX9r2gU4HAEMBPlxgMS/zSjqR3fd9e57/7r8iiskW4ZM+j5atoznecQBAAAAAKKNHFmel5uTwh1gWXbK5IkzLvqWXC7v818ajaastFjR737IPFaL5ayXMlgtFlxGkA00GvVZ3+wWi3nOnMtKiotSu3uTJozX69ERAWBAyI8DJElxScnTv3tm1ZqPn/jNk1ddffXoMWPU0quWKGUtLS2fbt2KOAAAAABAH9MumJKqFZo5dtvcKwZLfvVZUgqZiqZps7nvOnGFXK7X6xGcjGexmIuLCgdanc3Q9JTJE2fNvChVjTGLiwqLiwsxTACDwFJWgKTS6/Xfueqq71x1VeRmV1eX3+8PBALBYFAQhNTu2+OPPlZz6pRYWysqKvrRj+969Je/EnEPlyxeMvuSSzCLAAAAACAay7IXXjht46YtybzcUCaTjR93XnHRubNOFEUVFjibW043N7ek/Ds/JI7ZZPK0e0Ic13uPzWZFWDIbRVEOR65hCGdBcuy2K+dc9sWXldXVp5J5HDAaDJMnTcBIAQwO+XGAVNJoNJpBe50nTXVVtYjJcYIg5s2ff+lll40YOfLYV1+Jtc29e/bU1dU5nU7MHAAAABgwF2AyPf27ZxL9LCNHjUSoJcWg10+aOH7P3n3JeTpnvmPihPEKxTAKp9isFpVKWVfn4qLyp5BJSJK0Wi0NjU2Rm2q1GlcMJwFDdKrCR1mhPUwq/GRJgMxP2lPL5fLCgnz5kAsoMQwzeeKEwgLn3s8PdHR0JGEPZTLZhd+aJp0mxgASPpIAABDEsqUV4n4Mf+eq7xAEsXDRwmef+Z1YmxUEoWLJkvvuvx/jBQAAAANRKBSXX3EF4pCFiosK29raq6pPJvRZ1GrVpIkTcnPsMfytRq0uLyupqa33+XwYr4yk1+vb2toDwSBJknYsHk8whvDmcu/o+W0k8c05pyDpaKWvbqMvExJcT9ig1zsceRQ17OLyFrN5zhWXHj361ZGjxxJ6yQtJktMumKJWqzBVAM4JJ5EAgAgGg6tXrRZxg5dceqlOrycIYu6VV4q7QH71ylU9PT0YMgAAAADob9LE8VarJUEbp2l6zJhRV869IrbkeATDMKUlRRaLGT0bM1Wkpopep5OjL2siKYS6sp5HDPzm6OQ4QRBywZXHvVYW+rlCqE3QU1MUmZeX43Q6YkiO/3cLJDlm9Kgr51ye0N7C484fG8/BCiCrID8OAMSG9eu7urpE3OD8BfP/+61FoYgsJBeL1+vdsH49hgwAAAAA+iNJ8qJvTUtEUYvc3Jy5V1x23pjRtBiVCnJz7IUFToZJwfXcauGwnf+Pk/s/J/dnG79YIdRh2ogcYbVaq9Ek7jwNEATBEN6i0NOs0DrQAxThmrLQL/XhnaI/tVwuKykpNptMYkwV1YyLvjXjwukajfiHrKLCgpEjyjFVAIYI+XEAIJYuEbO4SmFR0YSJE3tvLli0SNzVMRWLl2DIAAAAAOCsZDLZjIums+KlnnU67awZF8686Fvi5rC0Wk15WUky61PrwrtH9Nxf0vOEjfuPgf/UwG+1cx+U9zxQwP2RIbowc0TkcOSl5ORHFkWYe22Q5HgEKfQUhP5gCm8U8XkNBn1ZaYlSoRBxm3l5uVfOuXzc+eexLCvWNs0m05TJEzFPAIYO+XGAbHf8+PHKykoRNzh//vzom0VFRZMmTxJx+5WVlcePHcPAAQAAAMBZ6XW6adOmUnEv0VDI5ZMmjp97xWU5ialRwDBMSXGh3WZNdK0VmvAVcH8oDD0vF+rPEi5+e0nPYyzhwcwRC4rnJJRGqNTxu4f22LAj9JohvD3+J6UoKj8/z5nvSESvS4qiRo0s/86VV5SWFMe/fZVKedGF09GTE2B4b0OEACDLLatYKuLWejtzRlu4aJG4+7wES8gBAAAAYGB5uTkTJoyL+c8Zhhk7ZvR3vjO3rLQk0blOm81aUlwkk8kStH2Z0FLa85ie3zHIY+SCqyD0PEmEMXNA+qzcsH7AhvO5l1XCiXieUaVSlpeVGA2GhL4uuVw+edKEuXMuy893xHzYkbHsrBkXKhSofQ8wPMiPA2S1YDC4ds0aETd4yaWXRDpzRrt49myLRcwCfGvXrOnu7sbwAQAAAMBAykpLYii/S9P0iPKyq749Z+yYUQxNJ2dXVSpleVmpyWgUfcsyoaUk9IR8CEXGVeFjFn45pg1IHEu0asJfDutPSKHHGfojTfhjeDqSJO12W2lJceLOYPWh1WgunH7BZZdeHMNlKzRFXfitaTqdDvMEYLiQHwfIauvWrBW3M+e8M4ur9P7MuHbedSI+i9/v/3j1agwfAAAAAAxi/LjznM78of42pqjSkuLvXDlnwvjz5fJkr76kKNLhyBW3aSdDdBWH/pcVWob4eBtfEVsOESBp9PxuYvgXOsgEdx73j+H+lVwuLy0ptqWi1arJaJw148JLZ88aeqNXkiSnTJlks1kxSQBi+RRGCACy2dKlYhZXKSwqmjjp7KXG582fT4u6AKdC1J6iAAAAAJCRpk2dfM4EE03TZWUl3/n2nMmTJiiVihTurU6nLS8v1em08W+KJISC0IsyoXEY2QHBZ+I3YM6AlGnCX8T2hwZ+izZ8cKhvH5I0m03lZSWpPSBYLOZLLp45++KZdpvtnA8+f+yYwgInZghAbJAfB8hex746dvjQIRE3OG/evIH+y2azzZg5Q8Tnqq6qOnDgAAYRAAAAAAb7xUtRMy/6ltF49sLBLMuOHFl+1bfnTpowXqVUSmGHGZouLHA6nQ6GiWtxiY1frB5mGQqCIAzhLZgzkDQkIWiESiu/3M7/xxRerxBc5/wTZRyVxPO4fwylyL5cJisuLszLzZFIn1Wb1XLxrIsuv3S2Iy93oF0aMaJs1KgRmFEAsX/4IgQAWWvZUjGXYMtksquuvmqQByxcdP2WzWJ+4V66ZMmECRMwjgAAAAAw2I9ehpk148JNmz/t7OzsvVOpUJSXlZaWFrMsK8F9Nuj1GrXG1dDY0dERw58rhWob92EMf6gIn2KJ1hBhxrSBRNOHP8vl3mKF09F3+qmSZvr6Dmrq2d/LhJcRPLH/YhUaTPy6VvrKgR5AkqTZZMzJsUskMx7NZDJedOH0zs7Or46dqKmt43m+97+KiwsnjDsfMwogHlg/DpCl/H7/2jVrRdzgWTtzRrtg2gVOp5gXfG3auMnj8WAoAQAAAGBwcrn84lkXqVRKgiBMJuO0C6ZcddWVo0aNkGZyPIJh6MKC/AJn/nArkpOE4OBei6FGc4Rm+KvOAYYrh/+gIPRin+Q4QRDKcHVh6Lmi0HMM0dn/r2RCc5zPa+OXUAQ3wFFCVlxcmCuZZeNnpdVqp0yeeNW3544dM1qhUBAEke/ImzJ5EmYUQLyfuQgBQHZat3Ztd3e3iBs8a2fOPhYsXPh/f/qTWM8YCoVWfLT89jvvwGgCAAAAwOBUSuXsWTOCPT1mkymNdluv12k06sYmt8fjFQRhKH9iDG9ShqtifkZluKqdmj3YA4RqfXinInyKIgIh0txNne+hLgwTCswxGCIzv87KLR7kAdrwnrKeR06xjwbIM9ZXsUJrnE/NCO1GflMrPSf6TpIkrVaLzWqRcmY8mkIhHztm1OjRIxsaGvPycklMKYC4Yf04QJZaKmp/y0E6c0a76pqrI2e5RXsVovYXBQAAAIAMptFo0is5HkHTdL4jr7ioQC6XDeEXfo+d+3c8T6cQ6gb6L5VwojT067KeR6xchTa8Tx0+bOA/dYT+OrLnHl14NyYYDIVMcOfyb57zYazQUhJ6QimcOuO9QIiwwMvCr4i+qVapystK7DZruiTHv3mzk2S+I48ikR4HEOMNhRAAZKGjR48ePXpUxA0O0pkzmk6nu+zyy0V83gaX67MdOzCgAAAAAJDZ1Gp1eVmpzWalqMHSYSZ+AyO0xfNErNDS/06SIOz8f0p7HlWFj/T/X0bwFIZ+bwpvxDDBOeXw75FCz1AeSQudxaH/lQvu3nsoIRj/DsiERk34IEEQNE078nJLSorkcjnGBSDLIT8OkI3EXTx+zs6c0RYuWiTua1myeAkGFAAAAAAyHkmSdpu1rKxUq9Gc/QEEb+GXx/ksLNHe5x6KCBVwL9i4/wxa0zzsCP1NLRzFMMFgvxyFZj3/2dAfTwsdhaFnaSLw9R2CKLthCm80Gg0jR5SZTEYMCgAQyI8DZCGfz7d+3ToRN3jOzpzRxowdM3r0aBGf/bMdO9xuN4YVAAAAALKBXCYrKiooLHDKZH2bi+rDu/o3PBwuUughCT4qZcAVhp7T8buG8Kd8fuiv5ADNDwEIgjCGtwy3c6xcqM/j/hb5tyBSCksv7M3PNdI0jREBgK8/7AAgy6z9eI3P5xNxg0PpzBltgahLyHmeX1aBKuQAAAAAkEV0Ou2I8jKb1RJdbsXErxUpTfBNFYt87iVN+MAQ/1AmNBjDmzE62UAhuHL494pDT5eEnijg/mjhVzOE99zzNqY69QZ+qyG8gyCIMClSL6twkPB+gkEEgKgPPgDIMuL2tCwoLBxKZ85oc+bO0Wq1Iu7D8uXLeZ7HyAIAAABA9iBJ0m63lZeV6XU6giBkQrM6fFjcRIGVX6bntw3rLy3cSgxNhk88gs/jXi/vecDKVWjCB9Thw3p+ey73+qjgXQ7uHwzROdAfMkSnInwqtifN5V6nCR9PiPcr0rsFQwkAfT/2ACBLHD50+NhXX4m4wXnz5w33T+Ry+VVXXy3iPrSePr35E5z/BwAAAICsI5OxBQX5JSVFVnqXWNWZI1UsVMKxHO79YX/VF+qVQvXQH08Os9oGpBZJ8EWhZ8386v5lUkiCM/Frynse1AiVZ/1bZbgq5inKCB479wFH6kV7JR3bMJoA0Av5cYDssmyp6J05Y8l0L1i4gCRJEfekYgm6dAIAAABAllKrVCZyjyibEggmTMgoIuQM/YUgYrlGUxf+fPAHMESHlV9WFnr0vJ5bzgveMLrnhwXc/6mEExhH6cvjXh+83g4jtBf3/NYU3tj/vxRCbTxPbeLXEYR4PyFD7YT/KwwoAEQgPw6QRbq7u9evWy/iBmdfMluvj+UcfkFh4eQpU0Tck32f76upqcEQAwAAAEA2CrUQ/iOibIkn1QRBWPklMqExti2ow5UD/RdJhG18xcien+Zw7yrDx0ihhyAIRmjX85+W9jyaw79LYiglTC0cNvHrhjKJHKFXTeENfe6VCe54np0kOBO/VrQS5ARBdH2OMQWACOTHAbLImo8/9vv9Im5w3vwFMf/twkULRdwTQRAqFmMJOQAAAABkpY5thCBOcRWONLNEq5VfHvMWlMLJs97PEp6S0K/t3HuUEDjb/4et3LI87jUMpmTlcO8PuUCK4Aj9TRfee8YEENri3AED/2mIzBXt9XQfxJgCQATy4wBZZOkSMYurFBQWTpo8KeY/n3XxxVarVcT9Wb1qVTAYxCgDAAAAQNbp2ivWlnpIaw73XmRld2wowccSrX3ulAuNpT2/UoXPUdHCxK83hdFYSIqUQrUqPKxrFMJO7k8Koe6biUHEu1SLJDhBpCL7BEGgvgoARB2gACA7VFZWnjghZlG/GDpzRqNpet78+SLuT2dn57q16zDQAAAAAJB1xKsUwZE6A/9pnBuRCS19bhaHnmLPvHMgOdxbNNGNIZUaI791uH9CCQEn9yeK4P57kwjEvxtxFmk5Q+AkgfawAEAQBEEwCEFC8Tzfevp0c0uL1+vt6uzs7u7u7uru6uoKBAIhLsSFQjzPh0Ihng8zDMMwNE3TDMuyDKvWqFUqlUqlUipVOr3OZDQaTSaz2cyyLKIKsVlWsVTErcXcmTPadfPnvfH66xzHibVXFUuWXHPtNRhriI3H42l2N7e2nvZ4vF6Pp6ury+f3+X3+np4gx/E8z1MUybIsw7ByuUwmk7Msq9aoDQaD0WQyGY2RfygUCkQSAAAAkvuzs5MI1Iq1MXm4Kf6kISO093ZSpAl/Ueh3rHB6iH9LC10WfpWbvgEDKynacCznYBThGhv/QRN9m1i7QQni1QsN9+zcXMFqiswWi81mU6lUGGWArIX8uGiamppqa2rr6+vq6+vr6+qbmppOt7S0t7cLgiDis2i1Wpvd5nDkOxyOnNwch8NRWFSUn59PkmhkAoPp7u7esF4SnTmjWSyWmbNmfbJpk1h7deTw4aNHjowaPRojDud8R1SdqDpx4njNqZr6+rq6uvqmxsaenp74t2wymfKdTqcz35Gfn5+fX1xSUlJSQtM0Yg4AAAAi6uzsrK2tra2pra+rk/UcvPNC0basEkQoOkFHrRR2hv4sjyqyMaQvVPz6Zvp6gcCPXKlgibaY+7VauRUeamaALBREKmAgkLJ46v9Ee+tvz+4//t8v6kql0mqz2e12Z4GzwFngLCwoKirKzc2lKNRdAMh8yI/HiOf548eOHT92/PjxY8e+Onb8+PHu7mRcAtbZ2dnZ2Vl1oir6ToVCUVRUVFpWWlJaOmbMmNFjxmABI/SxetXqQCAg4gbj6cwZbeGihSLmxwmCqFiy5NHHH8eIQ/+D9pHDhyu/rDx8+NChQ4cbXC5xT172amtra2trO/jFF733yOXyktLSUaNGjRg58rzzxpaPGIHhAAAAgOGqramprDx04sTxE8dPHD92rL29vfe/FswKESLlx8XKPPZuxMyv1Yb3DDtPIbSrw5Vd1PkYd4lQhqvj+Saey711kn0iTChF2RlSEO36Y5Pum18Efr+/tqamtqZmz+7d0d/ky8rLRo4aNXLkyJGjRpWXl2PhC8CwtLS0nKw+efJktdvtbnY3n25pOX36tD8QCAYCgUCA53mZTKZQKJRKpUqtttvtOTk5drs9z+EYMXJEUVFR0vYT+fFh8Pv9Xx788sCB/fv37T9y+LC42cZ4BAKBo0ePHj16NHKTpumi4qKxY8dOmDhxypQpNrsdYwdLKyTUmTPalKlTC4uKak6dEmvf1q1d97P779doNBh0EATh6JEju3bu2r179+FDh1J10A4Gg0cOHz5y+HDkpl6vnzR58uQpk6cPdGnsAAAgAElEQVRMnZrMz3sAAABIL6FQqPLLL/ft21f5ZeWhysqOjo6BHplrFq2GskAwJCHKylySIAgZcTqHfye2v9cKB7oI5MelQjHMKwD60IQPasNf8KRYv9FEm/B6tXDOb/KHKg8dqjz03zgoFOPGj580adKkyZPHnjcWuXKA/jo7Ow8ePFh58MsD+/cfP368q6vrnO+yYDDo9XoJgqiuOmM1sEajGTV69NixY6d/a/q48eMT+o5DfvzcqqqqdmzbvnPnZ18c+ELEQsmJw/N81YmqqhNVyz9aThCE0+mcMnXqtOnTpk2frlQqMaBZ6MuDB/scZeJ03bzrRNza/AXz//SHP4q1tUAgsHrVqhtuvBHjnrUCgcBnO3Zs+/TT7du2ezweqe2e1+v9ZNOmyGUTVqt15sWzZs++ZPKUyfh6DQAAAARBHD9+fOeOz3bu/Kzyy8pgMDiUP8kxi3ZVHCX4RNmOQNIEQeSF/kEJMS5QUIcPE/hyJBlDLx8/EBv/oZ8sE2t/OJ5gxJgeCvnw3juBQGD3rl27d+0iCEKhUFwwbdpFMy66aMYMi8WCSQLZLBwOV35Z+dmOHdu3bTt+/LhY12p3dXXt3bNn7549b735pkajmTZ92oyZsy659JJE1MxAfnxA+/ft27B+w7ZPP3W73Wn9Qurq6urq6pZWVLAsO3ny5ItmzJgxa2Zubm7SdiAYDMrlcsyoFBJ38bhMJrv6GjF7YF59zTWv/vUVEdf2Vixegvx4FgoGg9u3bdu4YcP2bdulc33P4FpaWioWL6lYvESv18+cNWv2JbO/deGFSJQnjSAIgUAgHA6n70sgSTKDe0kFg8G0WJcw2PdshsFXoIwZzbNSq9UYXBAFz/P79+3b/MnmrVu2NDc3D/fPjRpBcq+IUGuEQ9rw3pi3oBBqSUJACXKpfKIR8S46UYWPBuhi0T5WQuLkx+k4SosHAoGtW7Zs3bKFJMmRI0dePHv2nCvnOhwOzJY04vf7pfxbQKFQSPy3Ic/zO3fu3LBu/Y7t2yMLwBOnq6tr44aNGzdsfOG55y697LKrr71mwoQJoh7l4EyVlZUb12/YsH59S0tLhr20UCi0c+fOnTt3/uHFF88777w5c+dePucKo9Eo+hM1u91bNm/ZsWNHdVVVW1tbKBSSy+VGo7G0rHTq1AtmXjwLnxnJ1NnZuXHDRhE3ePFsETpzRtNoNHPmzolc7iCKU6dO7ft8n1gVYED6Dn5xcNXKlRs3bDjnpVuS5fV6V65YsXLFCqPR+O2rvnPtddeh9IroTp8+/dmOz746erSqqqq2tra7qysYDCaoDH0ykSSpVCq1Wq2zoKC0tLR8RPm06dOtVmt6vYpgMLhn9+5DlYeOHz9eXVXV0dHh9/t5ns+AiUfTtFKpNBgMJaWlpaWl551/3pSpUzM7aR4MBvfu2VP5ZWVVVVV1VZXH48mY0ezDZDKtXrsGR1eI04EDB9Z+vGbTpk3eOC5606rE+TgLhgg5K1LShNTkcO/G9QEnBFnhdA9pxSSRxMeZGBcWKISTYu2PWqTFo6J8ExQEIVLw9rVXXx09ZszcuXOvmDvHbDZj2khKW2vrzp27Ir8Fak6d6uzslP5vgd8+88wVc66Q5r7t+3zf2jVrNn/ySaLT4v35fL7Ib+fSstI77rzzijlzRGmiS2bAL0NRdHi9q1et/mjZspMnT2bPq6ZpesrUKddce+0ll14qylmplpaW1//xzxXLlw+yRIiiqJmzZt5z773OggJMvCT49wcf/PHFP4i4wZdffWXy5Mni7uTRo0e/e/sdIm7wsssvf+bZ32H0M1tXV9eqlSuXVSzNyOP2uPHjr5t33RVz5shkssQ9y/Fjx26/9Taxtva/T/92zty5Egzm1i1bP3j//f379mXPd54JEybcctutsy6+WPq7WltT8+4776xbuy5dLvsQITugUFx+xRW333lHYWFhhr206qrqd95+e9PGjUOsCJHukB+HeLjd7hUfLV+1cmVjY2P8W3v/SV9xrghLIAWBIEVaru1i73GEXor3qCJ7upschdkiBaWhx1Thr+LPQBCEaKdLG1rJvLgrC73wvnzJFlb0cDEMc9GMGQsWLpg2fTomT8rt2L7jvX/96/O9e9Put4AE8+MdXu/KlSuXVSytra2VyC458vNvu/32a6+7Ns6sJtaPEwcOHFj8nw+3bN4cCoWy7bXzPL9r565dO3eZzearr7lm3vx5uXl5MW/t061bn3ryN+dcvxkOh7ds3rJj+467773npptvxgxMtGUVS0XcWkFBgejJcYIgRo0aNWbs2MOHDom1wS2bN7e1tppw0j5D1dbUfPD++x+v/tjv92fqazz4xRcHv/ji5b+8dMONNy68fpFWq8W4x5Z9+M0TT+7fty8Lv9scOHBg4sSJv37yiTypXrPF8/xfX3r53x98kJFlNwYRCARWrlix5uOPb7r55p/c/dPMKKkUCoX+8uc/L/lwcUauEwcQ1/bt25d8uHjXzp0ivl9oSpztkKLVMiEN/Ob4t8IIXpRXkQxRRoIXSBkpiNIAljhaQ+WZ430TdSXmxwTHcVs2b96yeXOewzF//vzr5s/T6XSYQ8nX0tLyv795as/u3QiFCO+4I0c+eP+DTRs39vT0SGrHXPX1zz377Pv/+tc9P/vZrItnxf6Jk7VDKwjCJ5s2/evdd3s7EWez1tbWt9588523354xc+Ytt90aQxGfd956+68vvzz003GhUOhPf/hjQ0PDgw89hPgnzoEDB8RdWnvd/HkJ2tWFixaKmB/nOG75R8u/+z/fwxzIMF8ePPjWm2/t2L49rWtGD11bW9urr7zy9ltvXTdv3s233Gyz2zEHhq6ysvKh+x9I/hV/0rF///47brv99394ccLEiVLbt+7u7ofuf+DAgQNZOzocx737zjtHjxx54Q8vpnv79I6Ojgfuuw/fqAEGFwwGV65Y8e8P/l1bUyP6xnkxvhY1tZJi9fnkSKM6LMIxgSICmDkSIYiUOxIIhiR6RJr2ZGMrmRvfpHW3UQmNW4PL9fJLL73+z39ee911N996S05ODuZS0hw/duxn99zb3t6OUMTpsx07/vXuv/bu2SPlnaytrX3k4YcnTZ78wIMPlI8YEdMnTlb+IFmyePHC+Qse/eWv8FU+Wjgc3rply49/+KMffv8Hmz/5ZOh/uHrVqpdfeimGa1X+88G/333nHUQ+ccRdPM6yrLidOaNdMWeOuGXNly1divpRmeTzvXvv+endP/z+D7Z9+mmWJMd7+Xy+9997b8G8+c8/91xbaysmw1CcOHHivnvuzebkeERXV9cD991/9OhRSe1VKBR68P77szk53mvv3r0/f+jhtF5zHQwG77v3Z/hGDTD45/hbb74575prX3ju+UQkxwmC6BYjjdzpF22ptkCwBCHC93CS4DB/JIInxWlHTIlRxzwi1xz+x8p46xA2nE7GFQp+v//fH3ywaP6Cp578zalTpzCdkqCxoeHeu+9BcjxOmzZuvPXmmx+4736JJ8d77fv88+/d+d3XXnk1hutTsys/Hg6HV3y0fNH8BS8893yDy4W5PpAvDx785SO/uPXmm7ds3nzOBze73S++8PuYn+vVv75SVVWFmCdCR0fHJ5s2ibjB2ZdcIm4KO5pMJrvqmqtF3GBTU9P2bdswDTLAF1988ZO7fnz3T36aLp/KCcJxXMXiJQvmzX/tlVe7u7sxMQYRDAYf/cUvEaXen2S/euQXPp9POrv0lz//+YsDX2BoIvbu2fOPv/09fff/D79/8cjhwxhHgIE+j9556+1511z7yst/TWiaxtsVb46vrpk0aUVbWUITYp2fpjCLJIInNFLbpVyTsPoz9nh97JOko5ts9iRvjnEc9/Hq1bfedPNvn3qqsaEBkypxBEF47NHHPHE0PYbt27ffcdvtj/7yV1Un0ixfx3HcG6+/fsettw33C2oWfd5sWL/+putveObpp5uamjDXh6LqRNUvfv7I9+64c+dnnw3ysL//7e/x5CA4jnvlpZcR7URYvXKVuA2y5i2Yn9Adnr9gAUmKeQK/YkkFpkFaO3ny5IP3P3DXD36YhfWjBxIIBN54/fUF8+a//6/3UOd3IG+9+aZ0OsZIQWNj4xuvvy6RnTl+7Nji/3yIQYn2zttvp+m6jcOHDi//6COMIEB/4XB4acXShfPmv/zSSx0dHYl+uub2eH/Xf/gJa9aLlh+nBHHqooTRL00yQqRojZ34sDi/+AxaQSCI59+Th2OduYdOpSAhxvP8qpWrblh0/e+ffwEXhibIyuUrRKzdmm0O7N//ox/88KH7Hzj21Vfp+yqqq6t/+P0fvPn6G8P45MqG0T169OiPfvDDxx99DL+WY3DkyJH7f3bfvXffU11V3f9/vV7vx6tXx/kU27dvr6urQ6hFt3RpGnTmjOZ0Oi+YdoGIG9z52WeNjY2YCenI6/U+/9xzt99y647t2xGNs8TH4/m/P/3p9ltuPbB/P6LRh9/v//f7HyAOfSz+z4cSWVD/5htvZluJpHPiOO79995Pxz1/8403UMoMoL/PP//8jltve+7ZZ0+fPp2cZ6xtjivheKqJOlglYq9g0da7SHDNctbqIa1ibSocFueDg6YIjVL4spqu2MLGtoXdR1LWIjsUCi3+8MNFCxa+89bbWPIiunfffRdBiEFLS8sTjz/+4x/ddfCLTLjQk+O4V1955d6772lraxvK4zM8P97e3v67p5/+nzu/mxmjm0J7du++/dZbn3/uuT61XDdt3BRDWZ8+BEFYv24dgiyu/fv21Yha2ixxnTmjLVy0SMSthcPhpRVYQp5+KpYsuX7BworFS+I/vGS26urqn9z1498+9RQuHoy2dcsWVFbpz+/3D6uzSIL4fL6hlG7LQuvWrUu7RHNHRwdOYQL00dba+tivfnX3j39y4sSJZD7v8fq40nwvVchsRtEOQWFCtJwjT2oxqSSih8wTa1OseFcFyGUEQRB/WSI72Tjs1JYgEJv3p/gCBZ/P9/JLL918w43b8XkqnpMnT9agyPswcRz35utv3LBw0bq1mZaa27N79+233jaUVWWZnB9f8dHyGxYuWv7RcixTEufbCc9XLF6yaP6Cj5Yt671z757d4kzZXbsRYXGJmxdmWfaqq69Owm7PmDnTbreLexxAjjWNHD927Ht3fvf5//dcEq5EzgyCIKxaueqGhYuij8xZbu+evQjCAN8OU1/B/8D+Azgmn5XX40lyNk2M0dyP0QSItnLFiptuuHHjho3Jf+pDJyku1hWoWw7Q2w4yBo14xVXEa6op4ppliFOALBDxygCfSEVAaVIgCCIYIh/7m2K4XWo//4pubJVEQqy2tvah+x945OGfJ+2Kk8y2c8dnCMKw7Ni+4+Ybbnz1lVf8fn9GvsDW06fv+endiz/88FwfXpmoweW656d3P/P0052dnZjr4urs7Hz2md/95Ed31dTUEARx+JA4HZmOHDmC2Ir5M9vr3fzJZhE3ePHs2QaDIQl7TlGUuAvV29vbN23chCkhfaFQ6LVXXv3end9Fn7cYdHR0PPvM7x68/wEUMSQIoroaPZ8Hikx1yvfh5MlqDMSAwak+mV47nHb9mgAS+EHs9T784ENP/+9vU3WC3x8kv6yOZdV2Rzf5wvtygiC0KsldwiKQMo7QY3ZJBE8oe0ibWFs71ShOJqq3Ukt1I/XEPxXDqlPy1hpWUhHeumXLTdffgCUv8WtsQoXVofJ6vU88/viD99+f8RWPOY77/fMvPPvM7wYpZ5SB+fEP3nv/lptu3rtnD+Z64uzfv//2W279+2t/E6vZaSAQaHa7EVixrFyxoqenR8QNzk9wZ85o182bxzBiXulWsXgxpoTEHT927M7bbn/j9dexFDEeO7Zvv+Wmm6VQQyPF3/M8XkyGs2ofWum9RH8Lx0AMxONpT7MZlW47DJCoX0b79t12y63bPv00tbuxfk8s35+feUd+2ksRBCET6dt3h0+0VxQk8zG7JMVHjRJrU4EeUpQi5P7gN0vat3/JPPH6UFPkW7+g9xyVXPfXrq6uZ5/53T0/vbuxoQHzLWatWIY/NOvWrrvp+hsyr6DKID5atuz+n93n8539gyqj8uNtbW333Xvvn/74x0AggLmeaD09Pf/8xz9ErJXZgqOYiG/7pWKednY6nZOnTEnazpvN5otnzxZxgwcOHDhZjRWL0vXu2+/8z3e/V40xEoPH4/nlI7946snfDPSpnw1IksRMOCsplJsjCYzOwAPEh7HDAGnn3x98cO/d9zQ3N6d8T9btYbqHeWX8W2vYLQf+myKkREoMBHpEO877yUJMMEnppkaLtSmjVuidezHjeMIXOGO+bfyceeiv5y600txOPvcvhWTjvHfPnttvvW3d2rWYcjFODKy4OpeWlpaHH3zoiccfb2/PurUOe3bv/vGP7jrrVdeZkx/f+dlnt918y66duzDX01QXiuGI5PO9e2tra0XcYHI6c0YTt0snQRBLFi/BxJAgj8dz3733vvSXv4RCIURDRB+vXv3dO+48efJkdr58g9GIOXBWen3qr1JPTqmuNKXT67DDAGmE5/lnfvv0H1/8g0RyMV1+8sPNw6gXsW4P8+oyee/NEC/CPoQ4Qq8WbflUgCzBNJOUHrloS6ZyTOG34y5v0uIh+8+2nYeYO59RVZ4cMNPV1Ebe92dla4ekT9h3dXU98fivf/vUU5laDzqx33jxbXNQKz5afvMNN6b8mqcUOvbVV3f98EctLS197s+E/Hg4HH7pz3954L772yRw4TDE/nEraj2QbLa0YqmIW2NZ9uprrknyS5g0eVJRUZGIG1zz8ce4rERq9u/bdytOaiZMbU3N97/7vQ3r12fhay8uKcYEOKui4tRHpqQUyY4BFRSm2UrJ4mKMJmSvYDD48IMPrVi+XFJ79ebHssbWIWX9Nn3O/OZ1RXRu0R8QIV24o5KWi1fSuVu8ah4QM5lMZjIanPkOi9n07AtvnBSpbrhSTlS5qM3741pC7mo5+87Ut1A/fE715Ovyo7VnPKCHIz7axtz5jEqsV5Foq1auuuPW2459dQzzcHjfT4rwW+DsPB7PIw///Jmnn+7q6sryUNTV1d3945+0nrmKPO3z4x0dHff/7L5333lHxEIfkBIYQbEOeVs2bxZxg0nrzNmHuEvIu7q61nz8MaaHdCz+8MN7774HteESyufzPf7oY//3xz/xPJ9VL3zKlKkY/bNHZuqUlO/DuPHjWZbFWPSnUqlGjx6dXvs8efIklDOC7NTd3X3PT3762Y4dUtuxQA/5y9cU/uDgv7mId9exj/1d0af6c3vX/2fvrOOiyrs/fqeH7g5BSkVFREVBDCxsBTEAKXvXWnONtbu7lbJpxe7AxEAURBBBQgFBmgEmfn+4jz9WXRfhzMy9M+f9vPbZXRY/d+7nnrlx7vme09Svs0hE3H0B1tCZV8e8/fjjZyyAkzg0Go3D4WhqapgYG7WwsbaxtjQyMnz7Nj3Qz+9FYuKt5wyoDakoEXui2XVNWH2Rnvuv6SwRQVx6xPJfozhsoeKC/dyVIZyZO7gD5iqtPcotraTSlSs7O3vi+PHnz53HyPyF+5MOHdCE77lz+7bXqNG3b91CK77w/v376VOn1u9KSu38eFpamr+v36OHWH6IIH8Td+YsbKsKSU7mrM+AQQMVFBQABaMiozA8yIBAIFizevWmDRuxMZxkOHH8+PSpU+WqRqBb927Kysp46L+By+X27tNH6h9DQUEBdsKEzODaqxeDwaDWZ9bU0nJ0dMRjh8gbPB5v5vQZSUlJ5Px4qe8Z07YpFJf/OAP4oYg2axd3VxTn+7qk/OKmJg3jkxi1cDd395KIA3v3z5s9a+6sP/bu3nX54sWMt+nYkU9MMBgMFWVlXV0dMzPTli2sra0sjAwN1NXVWCwmQRAnj5+YMXXalz7Flx+DveRmM0XvC+jHrjReMCnjv6+bH4vpN54xz91nPUhmVlTTKHrOWbFs2aYNG+Wt5KXRWNtYm5tjCfn/U11dvXb1mrmz52DLjW94m/52yaLFX0t1KZwfv3Xz5oTAcXm5uXhQEeQrMdGQzVUkPJmzPkpKSn379QMUfJOa+vLlS4wQ6VJZWTlj2vQzMbFohSR5kvBkQuC4jx8/ysn+crlcz1Ej8bh/g/sID1VVUnSL9vP3w6Lj7xMT3mN9qPjJA8aPw8OHyBV8Pn/OrNlJL16Q+UO+fMcYtVTx2BVWUenfJ1u+gEhMp687xvFconj/1Y9LvN/nNykzIBASe2I4akpge3Hv5d+pz5LPn58mJISfOrl21appUyavXrH8aEjIrZs3sjIzsdii0dDpdCUlRW1tLRNjI2sry1YtbczMTPV0dVSUleu/rK2trV3615JtW7d+tTojj56WQwf6DARBEEfOsTM/NkZQKCISXjPk55BFhIf/NnlySUkJRm9D8PX3RxP+viIkJXmP8YqNiUErfsjdu3fDQkO//DOTovsQfur01i1bhEIhJT6tioqKppaWsrKSkpKykpKSoqIih8thMVkMJoPFZNHpdKFQKBQJ+Xx+XW0dj8fj8XhVVVXlZWWlZWVlpaXl5eX4qhBpCI8fPcrJyQEUlPxkzvqM8BwBex6Pjoxs3bo1xom0KMjPnzl9RkZGBvk/KpPJ1NbW1tDUVFNVVVVTVVZWZrHYLBbrS1+Iur+praioKC+vqCgvL/78ubCggMxDFN69ezcuIHDz1i0tWshFK08/f//Lly7ngp4PKY2evv7ESZNI8mGsrK09RoyICA/H4/KVkaNHUbTQyc7ObvCQIWRrwYwg4mPt6jUJjx+T/3OWV9F2RnIOxKmaGipraigKaBoKSuoKitwBg7hcLpfJYjEYDCaDSRAEX8AXCUUCgaCmtqacd1qF28hhgGfjmRl59B72MAlrvoC4k/iDTIVAIMh89y7zfxPIGQyGsYmJiampsbGxoZGxkbExSd4Ekw0ajcZiMbkcLofL4XI5ClwFDof9n3+qrKxs7uzZic8Tv32kus2a51UDcJT5BEEQtXzakkOcQ39Ws38xNZXwmvFNpxQ2m62to6OmpqaioqKioqysrMLhsL9GO1/AFwgE/Lq6mpraiory8vKK8vLy0tLST4WFVBmElvg8MdA/YOv2bc2oNrBE8vQf0P9MbOyzp0/l3IeQ4OCD+w/gq8Sfc+jAwe49ejRr1oyS+fFdO3YeDQsj4QdTUlIyMzczNjYxMTExMjY2NDLU1tbW1tbmcDhNkRUIBMXFxUVFRYUFBXl5eR8/fMzOzs7KzMzLy8O8OfKPmxXqT+b8JofSpk0bwOWrV69cnfHHH3jfLBXeZ2VNmzotn5QlzEbGxlZWVubm5mbmZqamprp6elpaWo3QKSkp+fjxY1ZmZlZWVlZmZlpaevb79+SZrFD06dOUiZNWrV3j7Ows8/HG5XLXrFs7ecLE6upq/PYpKiquWbeWy+WS5yNNnzkjJSX51ctXeHQIgmhrZ/fb779T9/PPnjsnPS0tJSUFDyUi84SFhJ6LiyPhB1NQUDAxNTUza2ZsYmKgb2BgaKCrq6ulra2k9Ivl3O8+EcXnGvEBistpu6M5BEEwgVanP0xmNKRJtEAgyMrMzMrM/PoTFRUVYxMTQyMjPT19PX19AwMDdQ0NeVu0RKPR2GwWh81hc9gcDpvL4XK5HDr9147Nh7y8mTNm1vf2KxceMn8bXqPc5EaYVTV/H5c3OYzNJzkLfH4t5/48u/mgwR1MTE1MTU2NjY11dHUbPTSrpKSksKAgJyfn/fv3uTk5795lpr15w+PxSHhw83JzJwSOW79xg3379nhO/jnLV64Y5x9QWFgon7tfVFS0dPFfCQkJVDlrSfGpuba2dse2bZu3bqVYflwgECxbsvTK5cvkeQK3bW3btq2dtY21tY2NkZGROLbCYDB0dHR0dHS+qfvj8/lZWVmpr1+nvk5NfvUqNTWVKm8+EXFQXFwMO2xBWpM56+M+YgRgfrympubc2bgx3l4YLRIm7c2b6f/rWkgGWCyWra1t+w4Obdq0aWVrq6amBiKrrq6urq5e/0RdXl6ekpzy8mXS40ePXyYlSb1pZnV19bzZcxYvWdJ/QH+ZjzobG5tNWzbPmTVbzlPkXC534+ZNtra2pPpUbDZ767Zt06ZOTX2dKuenx5atWm3euoXSM0u5XO62nTtmTpuOKXJEtklMTNy3dy9JPoySkpJt69a2rW2trUEfQtW6Ni4/vuE4p7yKRhAEnQ6T4Dj/oJFnxfLy8pTk5JTk5Pp3fXr6+itWrdTR1aurq6utra2rrautq6PKSvT/ShTQWSw2m81is9lsFov9P5r4RuB1SsqsmX/8W6vi6hpa5C2Wn1uTbmv5AqKi6v8/ZexdVjM9oVefBmtym01cEEMQMG8+vtzDW1lbf/2JSCT6kmlJepH07NnTjLcZ5Cl5KSsrmz512uIlf/Vzc8Mz80/Q1dXdtXfP9N+n5ufny9u+34u/t3L5cvI8fdc/IVtaWdna2lpYWhoZGRkaGaqpqSkqKjIYDB6P97m4OC0tPfX16wcP7qckp0jyLB1/N/5dRgaNPN/z/z6H8vkL/1wg9XGrTCazTdu2Tk5O9u3tW7ZqRZ5hSnV1dSnJKc+fP3v44MGLxBeUm16yYdPGbt2743m80YQEB+/dvQdQcNee3R06dpR6VA8aMLAUrs+aqanp6cgIjBZJkpqaOv33qaWlpWS4SerazcXFxcW+fXvJ19LW1NQ8e/r09u3bd2/fKSgokKIPdDp9/oI/hw4bRhBE2ps3Y73Buh6vWLUSdmxA08nKyvpr0eI3qXKahLW2tl62YkVzi+bk/Hg1NTWbN206G3uGQveigNBotCFDh86eO4fNZsvA7tTU1OzetSsyPEKuljZqamqev3QRL/TyQEVFxVgv7w8fPkjxM7DZbPv29h07derYqZO1tbVYaqKFlUSiCyH8xbJZnZHZtJ+SnioAACAASURBVHEJjxMSHj+2VL4a4NbUkeBFpbShCxX5AsgdDAoJbtmq1T9zC4K6ujo+v66ujl/H//J3fl0dXyDg8/kC8lyY6HQ6g8FgMhks5pf/MVms//8HceQinj97NvuPWZWVlT/5HQ0VUdSqSoUmLJL/UEQbvujb9Q2zR9d49mhYEsPqIKEquQWRpaWlTxKexN+9cy/+HklyjnQ6fc68ue4eHnh+/jklJSUrli2/Fx9P0c+/cvXqPn37NPz3BQLB7l27Thw7Tqq7a2sbG8fOjo6Ojnbt2jWwKKS4qOjs2bPRkVESm6EVMC6QMvnx2traeXPmPrh/X1ofQEFBoVv3bt179HDs3PmXl6pJnOrq6gf379++dTv+7t2ysjJKHGLMjzcR92HDAcfVmpiYhEdFkmG/wPsp7dy9q2OnThgwkuH169fTf58q3bOQpqZmPze3fv3dyNN6+3VKyqWLly5dvCitGeI0Gm3WnDmeIz1lPj9OEIRIJLpw/vzJ4yfevHkjP189axubUaNHDRg4kPyLyl+npIQEh9y5fVt+eiMymUznrl39A/y/SdbIABlvM0JDQm5cv15TUyMPhxLz4/LDmtWrpTVdXFlZuXuPHt26d3Ps3FkSb/ezlhCffqWURNmesA4maH/nO0T5obScdU38CIfi2IfigF8cfp8f/zkCoVDA5/MFAgFfIBAIhEKh4O//CQUCgUgoEoqEQqFQJBIJ//67SCQSEYRIJCL+l2AR/e+eq/7/0+g0Go1Op//9NxqdRqfT6QzGl7/oX/760i+byWQwGIxf7YvSRB4+eDB/7ryGtBaZOLg2cGDjF68/eMWYufMHLVr83GonDa2l//zmRc+fMJ4nrbPBy5cvr1+7dvXyFenWu3yJp9+nTfUZOxZP0f8db/fvHw07+iQhgXI1Gb+UH/+Ql7dwwcL6C2iki00Lm969+/Tu09vA0LApz3GHDhzMy8sT96ft0KEDNfLjPB5v1sw/nj55IvlNMxiMLk5Obv3dXLp1a2IbcakgEAju37t38cLFu3fukLOF1lcwP97EW5kZ06YDCk6dNs3HlxTX2tzcXE93D8DFNT1dXdeuX4cxIwEyMzMnTZhYKqUx63Q6vYtTF3cPjy5OThJ+tGggQqHw/v37URER9+/dl8oi36nTpjl2dpT5/Hj9gHxw735a2pu36W/fv39fVVUlS183RUVFU1NTC0sLKyvrzk5dzMzMqPX5y0pL4+PvvXr58u3bt+8yMsrKymRj5fvX05GGhoZ58+bNm5u3srV1cnJSBWrrRE4qKysfPXyYlJSUkf727du3xcXFslpUjvlxOSExMXHyhIkSfmpmMBidu3QePGSIc9euEm3BVJNNJA8mhA3Le3LNCZujBFPj/3/y+SKRMasp26+uIYYuUCqrAn65+6v5cfnk9q1bixcuamDLVgWOKHxFlbZaI78XoRdZe2K+za5wOJyerq6jB5u34IYRtf+yXEPXizBZBNVZpSk8e/r0XNy5q1euSDfNMn7ChPETJ2D0NoSC/Pz4u/EpKcnvMt5lZmZWVFSQPx3a8Pz43Tt3VixbTobqWBUVlf4D+g8dPtzCwgJEUCAQnDp58sC+/WL9rplSYj4nn8+fN2eu5JPjWtraQ4cNHTZsmK6eHnVPAQwGo6uLS1cXl4qKinNxcbHRMRkZGXhmlD3AJ3MOHDyIJLtmZGTUydERcO3Indu3P336pK2tjWEjVj58+DDtt9+lkhxXUlIaMmzoCE9PMc2EgIJOpzs7Ozs7O+fl5oaHh8dGx0g4Y7tr5860tDT5iUkzM7P6WWOBQFBVVVVdXd3wPOz1a9d2bNsOGwN7D+zXa8JtBp1GU1BU/NK2j9JHR1VNrf+A/vU74/N4vMrKyiY2i4s4HQ4+0X37zh3NGvz6gcViKSkpkWo4qmROwj1dXXu6un79SU1NTWVlJUnG5JyLizu4/wBeppGGs2n9BknmUJSVlYcMGzpq9Gg9qTyEckwI/YlE3q7//k0FC8LqyD+S4wRBsA2auP3IWyzw5DjSEG7dvLlowcKGr+WqrqFtPc1ZPaGR6apnaf+4bzExMRnu4T5o0KC/3x+LvInCE8SncKL67f//kmILwnA6odaDJI7Zt29v3779H7NnXTh/PjI84t27d1L5GIcOHhQIBJOmTMYY/k909fSGe7gPJ9y//qSqqqqqqgp8CaP70GGSrPMQiUQH9u0PDgqSerrfwtJijJdX3379YJsHMhgML29vFxeXFctXJL14IaYPT6PRyJ4fFwqFixYsfPTwoSQ3atqsma+fb/8BA6j+tPnNndao0aNHjR798MGDsNCwhMeP8fwoMxQVFd29cwdQsFv37hoaGuTZwRGeIwDz43w+PzYmZtz48Rg54qOstHTG1GmSHxeupq4+cuTIkaNHqaioUMguQyOjGTNnBgQGnj556tTJk+Xl5RLb9KWL8lv5yGAwVFRUfilURo4adeLYccDAFgqF169e+2P2LDxpfA+Xy21iWpnP51++dAn2U3Xs1Mmxc2c8Or8Kh8MhzypMNZku3kfAuXL5isTeJaupqY3x8ho5epSioqI099lgClH1kii5+dPP6kyYbyUYyt/+XMGSoNGIxuZoyippwRfYGHWS5+GDB4sXLvrVLOG1J8w+HZg97H85t1hT9//58ZatWvn6+fbo2fMfHeFoLELXl9D1Jeo+ErxMghASHDOCbUhC65SUlEZ4eo7w9Lx7587R0LDnz59L/jMEHTnC4XD8AwMwkn8VRUVFKZ9vm8znz5//WrgoISFBuh+jc+fOXj4+nRzF2MbWxNT0wKGDhw8eOnL4sDheP2hqaJA9P7565cpbN29KbHPm5ubjJozv1bs3+ft1NhrHzp0dO3d+mZR0YP8BCb94QMTE2dgzsO88h7sPJ9UOOnftqq+vDziZITY6JiAwkJw9N2SA2traObPnvH//XpIbVVBQ8Pbx8R7ro6CgQFHfVFVVx0+cMMbbKzgoKPzUaZJ3xJJPmEymt4/Ptq1bATVjY2ICxgWqq6ujveBcOHcevDeof4A/Gosg8oNIJDq4f78ENsTlcr18vH3GjiVHpoZGNN9OZC0hin7Ucp2pRhhOJXS8f/xH6UoEx5TgZTVuwwfOsiuqsXhc0jx/9mz+3HmNW7C1JozTykygq/Frb0TuJDJ5tTTb1raTJk/5j4QaS59g6VPCxi+r9hMTE/ft2fvs6VMJb33f3r1cLne01xiMZ/n68j5/vnjBwk+fPkntakGjOXftOn7C+BYtW0pmc+MnTrBtbbtsydLS0lJYcXOL5qROD+3asfNc3DnJbEtLS2ven/OPnTzRu08fGU6Of6V1mzY7du3cvW+vlZUVnlaoTmxMDKCasbFxh44dSbWDNBptGGjKvqCgALbiHqnPimXLXyQmSmxzdDp92PDhkdFR4ydOoG5y/CtKSkq/T50aHhU5cNAgebgYUY5h7sNhc9k8Hu/k8RNoLDgikSgMurNK69atHTp0QG8RRH64c/uOBN73d+/R/XRE+MRJk0hUxkhjEWZrCatDhHpPgqlCEARBZxPK7QjjeUTrS/+aHP+CimPjtvnqHT3yJgujTsKkJCfP/mNWo8syyqpoc/dyeb/YPetBerMNmzYdDgoSa7WpVLCzs9u7f9/2nTtatGgh4U1v37btTGwshrT8cOzo0alTfpNicty5q3NQSPCmLZslkxz/Shcnp+CwUAtLC1jZDh06kDc/fiY2Frxl5A9hMBhjvL0ioqPcPTzkrZ7UwcEh9NjReX/Op1YvAqQ+9+/d+/DhA6DgsOHDSbibQ4YOhZ1NFBkRgcEjDoKPBF29ckVim2tla3skOOjPhQs0tbRkyUYdHZ2/li45cOigpaUlBhWp4HK5o8cA1+ZEhIdXVlait7DcuH7jfVYWrKavvz8aiyByxemTJ8Wqr6auvm7D+vUbN5J03pWqE2Gxm7B7SLR/Rtg/I2yOE3r+BEP1v/aqeyM2xaslVoRwRRhzkuXDhw+z/5jVxJuQ1PeMxYe4/AaPYf7EM1u04Uy37t1k2FjHzp2Dw0IXL/lLS4JPKCKRaMO69YBdSRHSwuPxFi1YsHP7DvDO6Q3Eyspq9949m7dulXBm/CsGBgYHDh1y7OwIJaiqqtrVxYWk6eAnT55sWLdeAhtq0aLFkZDgGTNnykDVYeOg0WjuHh4nw0/XH6OEUAgZnsxZH01NzR49ewIKPnr4KCcnB+MHlrt37hyQyDJkgiAUFRXnzp93JDhIWldlCdCmbduQo2G/Tf0ddsIJ0kQ8R41UVlYGFKyoqAg/dRqNhSUsJARWsLmFhWw/zCMI8g15ublPnjwRn36HDh2OnTgOe38rtidGDkE0eE2bqsu3QzsbwKaTnKyP2PlQolRUVMyaMbO4uBjgEeAFc/Ehbm1DMnV0trbDTjlZIjlo8ODwqEgvH2+JjbXj8/mLFiyU2MgERCrk5OQE+gdcu3pNKlvX1NRcsGhh6LGjUl9SqaSktGXbtsFDhoCoefl4s9lsMl6Est+/XzBvvrjfhDAYjPETJhwJCbaxscHvmJaW1tr165avXIGF5NSisLDwXnw8oCDZJnPWx2OEB6CaSCSKjozCEALkQ17e8qXLJDOqu72Dw7ETxz1GjJB5VxkMhq+fX0hYqOQXaSI/uRsDj72TJ07U1NSgt1A8evgoJSUFVtPXzxeNRRC54urVqyKRuAqa/QMCdu7Zra2tLYPG0ZiE7q8ttLr0TDvuHnZWkSgCgWD+3Lnv3r2DErz5jDltm0JR6U8T3zQa0WwlwbWQH58VFRWnz5hx8PDh5hYS2uvKysrZM/8AHCaPkIr4+PgAX7+Mt28lv2k6ne4+wiM8KnLosGEkecXFYDAW/bV4wqSJTdQxMjb29vEhCIJ0+fGampo/588vKysT61b09fV379s7fuIEHNBXn35ubsdOHG9rZ4dWUIWzZ2R8Mmd92tnbw95YxMXFNW4QDfI9fD5/4YKF5eXl4t4Qk8mcPnPGnn17DQwN5cde8+bNDwcH+fn74zWLJIzx9uJyuYCCJSUl0VH4xg6M0OBgWEFDQ8O+/fqhsQgiV1y7elVMdzKLl/w1+bcpslxCq+tLsBpccKM5sLv3xS5OThhykmT9unVPEoCXRySmM7xWKJ6/zxT+8L0SQ4kw30hoDpZDt1vZtgo7djRgXKBkCskLCgrmzppdW1uLcS5jHDl8eO6s2RJ44v6e5s2b7ztwYN78+UpKSmSzZdz48QsXL2IymY3744qKimvXrfvSy5d0T9ob1294my7elyEdO3UKO36sXbt2+AX7wc2Mnt6+A/t9/f1wLhz5EYlEsTGQIzhIOJnzG2BLyEtLSq5euYqBBMLunbtSkpPFvRUDA4P9hw56eXvLocMMBmPK779t3bGdtCs85Ap1dfWhw4bBah4LOyqtHoIyRvKr5ISEBFhNH9+x+HYKQeSKkpKSN6lvwGVZLNaGTZsGDZb1FCFDlTBZ1KDf1BpGmK/nKihu3LwJsJMs8nPOxMaeiRHLIMfSStqKEK7PSsXwm6z3+XSRiCBoNIJjROj5EbbnCI0Bcus5g8GYNHny3v37DQwMJLC5169fr1+7DkNdZqiqqpo/d+6Bffsls1a7Pmw2e+LkSWHHj7W1a0taf4YMHbpx86ZG5O5ZLNaqNWusbay//Cu57vXjzp6NO3tWrJsYOWrk9p07sIvIT6DT6b/9/vvqtWtJNEId+RH37t3L//gRUBA83QNO/wEDYMMyKjISA6npPHr46OSJE+LeipOzc9jxY7a2tvJstaOjY9jxY61bt8aokzreY31ghwYXFhaK+xZITgiF7jyupaUl+8ksBEH+ydMnT8CbqzAYjOUrVzg5y0ehtMYAwvD3nz5zsgnjuYTZmi8ZCSaTuWHTpjZt22LsiZvXKSmbNmwU6yYy8uibT3K2XHAttbhL2D8nWl8hjOcTLF00v61d26Mnjrv26iWBbZ2Li8NuorJBVlZWoJ//rZu3JL/pVra2YcePBY4bJ7Ee+o2mi5PToSOHzczMfuEOX1t7x66d9S/KJMqPZ2ZmivVMTafTZ8+ZM2vOHKwAagiuvVwPHD6kR85Z6ghBEAQBe8FjMpmDhpD9+V9RUdGtvxugYNKLFzjApImUlZWtWLZMfA06v+AzduzmrVtghyJSFG1t7b0H9rv1749WSBddXd0BAwfCaoaFhkm+KkT2HiFu3wJ+fhg9ZgzOyEUQeSPxeSK45pTffpNMXowsGPxONFtOMH5086bWlWgZTugF1P8Zh8NZs24trpMT7317aemf8+aLu/MGjUYLCAzcumO7uoYmQcPO8v9ASUlpzbq1v0+dKoGE45bNm1+9eoWeU5oH9++N8w/IzMyU8HaZTOaEiRMPHTncrFkzqnhl3rx5yNGw0WPG/GevFSaT6TFixIlTJ+3bt6//c7JkioVC4Yply3k8nviO7rIVyz1HjcQvWMOxtLQ8FHTEwtICrSAhBfn59+/dAxTs3qM7Je5H3aHH4kVjCXnT2Lxx46dPn8Snz2Kxli5fPnX6NGz6VN+TZSuW/z51KnoiXXz9/WCfbXJzcq5cvozGNoWwkFDYdwwqKioeniPQWASRN9LTgesnunbt6uM7Vu581PYkWl8ijOcR6q6EcjtCzYUwmEy0iiEsDxBcq+9/XUdHZ9mK5Xh7Iz5Wr1r1EXT98fcoKiquXb9u0pTJeBx/wlg/3207tqupqYl1K3V1dX8tWlxVVYWGU5dzcecqKiokvNHmFhZHgoPHTRhPudpiDoczc9YfJ06f8vbx+b6WnMvldnJ0nDp92pm4s3Pnz1NVVf3mF5gk2Y3goKBksb3aYrPZ6zZskJe1bKDo6Ojs3b//jxkzXr3EF4/k4kzsGYFAACg4bPhwSuy4paVlWzu7F4lgRT0XL1ycOn06dhNqHLdv3b508ZL49JWUlNauX9/JsRNa/cMbax1dnVUrVmLTamlhZGTUu09v2K9ASFBwPzc39LZxFOTnX7xwAVZzhKcnXiAQRA5JBx2IpaysvHDxIjm1kqlB6PkTev4N/HXHzp379ut36eJFDEJwzsaeEXeLBh0dnS3btlpZW6Pb/0nHTp0OHTk8c8bM3Jwc8W0lLzd388aNfy1dioYjDYFOp3t5e0+aMhm2jaSEMTExmTZj+rQZ06urqwsKCqqrq7lcrrq6uqqq6s8z/qR4G5D25s2RQ4fFdUVmMletWYPJ8Uajqqq6Y9euVvLd85dsCIXCM7HAkzk7dqJMChJ2SmdVVRV4PkVOqKys3LBOjINfNDU1d+/bi8nxn+DWv//mbVsxeSdF/PwDYMujMjIybt28icY2juPHjsO+LuJyuaPGjEZjEUQO73BKS0oABb18vDW1tNDYBvLb1N//c3U88qvk5ORs3bJFrJtobmFxOOgIJscbjomp6eGgI7atxZtpORd37trVq+g28p/o6uru3LN76vRplE6O10dBQaFZs2YtWrQwMzNTV1f/z3J46efHhULhyuUrxFT+xmAwli5f3q17N4z1pqCkpLRj105stEIe4u/eLSgoABQk/2TO+vTq3Ru2FUxUBLZYaQz79+4VX2eVL122W7RogT7/HEdHx607tjdiWjcC9CjYHPweIzgoGI1tBGWlpbExMbCaQ4YNVVdXR28RRN4oLCwEVGOz2SM8PdHVhqOnp9enb1/0ARCRSLR8yVKx9tlo167dwcOHdHF62S+irq6+Z9++Lk7ireZcv3ZdUVERuo38BJdu3Y4eP+bg4CDPJkg/Px4ZEfnmzRsxic/8448+fftgrDcdZWXlrdu2aWtroxVkICY6GlCNEpM5v/nAg4cOARRMT09/kfgC4+qXSE1NjRTbewVdXd29B/ZTaBiIdLGzs9u+cwcOL5UW/gEBsIIpyckPHz5EY3+V06dOV1dXw15rfHx80FgEkUOKQF//d+7S5fsmp8jPGQJ6q49EhEckJSWJT9+xs+P2XTuxXKNxcDicTVs293R1Fd8mysrKtmzahFYj/xaBc+bN3bh5k6qYG+KTHynnxz9//nxg3z4xiY8aPRoHcgKiq6e3buMGmVlqQV3y8/Pv37sPKEiVyZz1Ge7uDjssIjIiAkPrl9i8cRNsB/yv6Ojo7D2w38TEBE1uOK3btNmxaxc+lkiFlq1adXJ0hNUMPnwEjf0leDxe+OnTsJr93NywDg5B5BPYl20OHRzQ0l+lnb09Lt+BorCwcN+ePeLT79a9++atWzkcDlrdaBgMxpp1awcMHCC+TVy7ei3+7l20GvkGC0uLoJAQXOT0BSnnx3du315eXi4O5a4uLjNn/YEHGJbWrVtPnT4NfZAusTExQqEQUJAqkznrY2Bg0MWpC6DgjevXS0tLMboayJXLVwBHpNZHVVV1284dRkZGaPKv0sq21YZNG9lsNloheQICgUvInz17liier5isEhMVDXsOp9Ppfv5+aCyCyCc1NTWAas2bN0dLfxUajdbeAd8rwLBl0+bKykoxiXfu0mXNurXYLx4k5v9aurR3HzE2P9i4fgOPx0Orka+4e7gHhYQ0t8CL1P/u/6W47devX184L5axeKbNmi1fuQJ2ZBbyhVGjR1NokKPsIRQKz8TI72TOf5zNR4wAVKutrT175gwGWAO92r1zpziUFRQUtmzbamGBow4aiUOHDitWrWQwGGiFhLFv376tnR2sZvCRIDS2gQgEguPHjsFqdu/RwxRbPCGIHJ9VANXU1LAOujHYtLABVGPK6xro+/fu3bh+XUzi7R0c1m/cgMlxKGg02vKVK1y6iWt43sePHw8fPIQ+IwRBKCkprVqzet6ff2JxVX2kmR/fs2u3SCQSx5HesGkjLjMXH38uXIDrp6TF3Tt3YCciUmsyZ32cnJwMDQ0BBaOjojHAGkJEePjHjx/hr0Z0+vKVK1u3aYMON4UePXvO+GMm+iB5wLuQP7h/PzU1FY1tCOfPnYedWU0QhF+APxqLIHILl6sAqCYUCdHSRgDbak9RUVEOPRQKhTu37xCTeIsWLTZv3YJpAVi+NFpp166dmPRPnzoljuc4hFpY29iEHA0T62IFiiK1/HjC48ePxDN+atFff5mZmeGhFR9GRkaeI7Gxu3SIiowCVGMymQMHD6KoFTQabZg7ZGeY3Jychw8eYIz9nMrKypDgEHEo/zb1927du6HDTWfkqFEeoKsrkIbg5OxkbQNZ6SYSibCEvIGEhYbCCjp2dmzRogUaiyByi4ICF1CtuKgYLW0EJqamgGqamppy6GFsdExGRoY4lPX19Tdv26qgoICBCg6Lxdq4ZXMz8WS0ampq9uzahSbLM+4jPA4HHTE2NkYrvkdq+fHdu3aLQ3bosGGuvVzxuIobX38/vBxKng95ebBvlbp1707pm8UhQ4fCLgiKjIjEMPs5J44dLy0pAZcdOGiQz9ixaC8Us+fO6dCxI/ogYcBLyG/dvJmZmYnG/pwb16+/z8qC1fTzD0BjEUSeUVZWBlTLePsWLW0EpqamUO1StbS05PDRtaqq6uCBA2L6gmzdvk1LSwujVEyoqKhs3bZVQ0NDHOJXLl9JSU5Gk+WQv3uqzJ/Pktd+U/+JdPLj9+LvieM7aWZmNmvObDyoEkBVVXXgoEHog4SJjYnFyZz1UVdX7+kK+T4s/u5d8EX6skRlZeWpkyfBZS0tLef9OR/thby00+krV6/S0dFBKySJay9X2OVrQqEwNDgYjf05odArWlq3bt3eoT0aiyDyjL6BAaDa48eP0NJGwOFwoFqswC7wogrHjx4rLoZfu0Cn05evWmmOU2fFjKGRkZgGn4pEIjHVqiJkxtraOjgsFHuq/Mf5TSpbPRoWBq7JZDKXrVyBDbAkxuChQ9AESSIQCM6ePQsoaGRs3MmR8qNWYftICASCmGjsQv6vhJ86XV5eDquppKS0dv06PHWDo6GhsXL1KpyYJGF8/f1hBS9fuvzhwwc09t94/OhRSkoKrKZ/IBaPIwheQzUA21U/SXgCOz1IfnDu2hVEx6GDg7xZJ6aiFoIgAgIDnZ2dMTglgH379lOnTROHcsLjxy+TktBh+WHgoEGHgo7ADnWQSaSQH09+lfz0yRNwWW8fH2wWKUlsbGxgpyMiP+f2rVtFwJM5h8qALW3t2lpaWgIKnomJFQgEGG/fU1NTc/LECXDZ2XPnwPaXRL7Szt4+IDAQfZAk/dz6wV4Z+Xx+WEgIGvtvgI9DaG5h0dXFBY1FEMQYLo/A5/OPHT2KljYCkMk0NBqtV+/e8mZdRHg4eFELQRCdO3eeMGkiRqbEGO01RkzRe+TwEbRXHmCz2fMXLPhr6RLYtrSyihTy4+BjlAiCMDMzGz9xAh5OCdOxUyc0QWLA1jUzmcxBgwfLhjOwJeSfPn26dfMWxtv3nIuLK4HuPN6te/cBAweit+LDPzAA3xxLEgaD4eML3Ek/7mxcUVERevs9KcnJCY8fw2r6+fuhsQiCEATRqlUrQLXI8AjwSQnygH379haWFk0U6eriYgDaMIf81NTUnDwOX9SioaGxZPkyDEsJs2DRQj09PXDZe/Hxr1+/RntlGz19/f0HDwx3H45WNBBJ58fz8/Nv3bwJLjt3/jzsMS95WrZqCZlWwD4A/05ebu7jR5BZAKpP5qyP24D+SkpKgIJRkTil8weA32erq6svWLQQjRUrDAZj6YrlWC8gSQYPGaKtrQ0oWFtbi4WHPwS8eNzQyKhP375oLIIgBEG0tWsLeyZfumQpn89HY3+VKb/91pQ/zmQyJ02ZLG+mnYmJ/fz5M7jswsWLZOb5kUIoKysvWb6MTodP3IWFhKK9MkwnR8fQo2EtQd/1yjySzo+fgR4wSBBEn759HTp0wGMpeWAbGGmoa6Cl/0ZMTAxO5vw3FBQU3Pr3BxR8kpCANT7fcC/+3vv372E1p06fJqax7Eh9zM3Nx/r6og8Sg8Viefl4A18CoqLLSkvR2/pkZWXdvgW81mfs2LHieP5EEISK2LVruHXlBwAAIABJREFUByuYkpy8dvUaNPZX6eri0pT7/PETJsB2YqQE4eHh4JqDBg926dYNA1IqODg4jBjpCS576+bNwsJCtFf2oNFoAYGB23fuUFNTQzd+CYk+BgiFwrNnzsBqcrnc6TNn4IGUCsag+XFNLXwd/WMEAkHcGZzM+TNgW6yIRKLoKJzS+Q8iI4Dvs9u0bSszHX7Ij1+Av6GREfogMdw9PGDvR6uqqk6KZ8oWdQkLCYV9baylrT1oCJ6UEAT5392ykZG5uTms5rm4uC2bN6O3v8qCRQvt27dvxB8cMnSIHI5cfvTwEXihj4aGBqZcpMuU337T09eH1eTz+dFRUeitjKGiorJx86ZJUybTaDR041eRaH78Xnx8QUEBrOboMWN0dHTwQEoFPT09qGX7DAYDl2v9G7du3iwuLgYUlI3JnPVpbtHc3t4e9gGmpqYGY+8LHz58uH/vPuSFh06f9+d8NFZisNnsWbNnoQ8Sg8vljhozGlYz/NTpqqoq9PYLBfn5Fy9cgNUc4zUGO/UhCFKfHq49wTVPnzy1cvkKHAX/S3A4nG07tg8ZOuSXbjUDAgMXLl4sh3ZFiKF4fOasP1RVVTEUpYiCgsLceXPBZWOjY/B0JEs0b948KDQER803Gonmx8+C1sASBKGmrj7WD5eNSxNjY2OobzJ2yP03oiIh3+vK0mTO+riDlpCXlZVdvXIFY+8L587GwdZp9h8wwMrKCo2VJF1dXBpXe4U0jpGjRsHORSgvL48Mj0Bjv3D82HHYNr4qKiruHh5oLIIg9enVu7dYbqvi4qZO+e3Tp0/ocMPhcDgLFy9evXZNQ9p7tmzVau+B/XLYdpwgiIKCgvi7d2E17e3t+7m5YRCS4WbeydkZVrOoqEgc0wERqdDT1fVwcBBUgk4+kVx+vKqq6sH9+7CaY33Hwj5/Ir9KewcHEB3b1q3RzB+SnZ39JCEBUFCWJnPWx7WXK+x+RUbglM6/OX/uHKAam82eOHkSuip5pk6fhuvsJIaysrL7COB864njx3FdC0EQZaWlsTExsJojRnoqKiqitwiC1MfS0rK1eJ5Qnj175jPG6/q1a2jyL9Grd+/TkRFr1q3r5+b2/Sjs5s2bjxo9et+B/UEhwXZ2dvJp0eVLl2DLgWk0GnZWIQ/TZkxnMBiwmhcvXERjqQ6dTp88Zcra9esUFBTQjabAlNiW7ty+Dftcp6qqCtt0GGkEXZydQNZwdezUEc38IbHRMSKRCFBw6PBhMmkUg8EYMnRocFAQlGDyq1epqak2NjZyHoFPnzzNy8sDFHT38NDT08OvtuSxtbV16dYNfKQh8m+M8fIKP3Wax+NBCRYXF5+JifUcNVLOjT196nR1dTWgIJfLHT1mDEYsgiDf4zlq5MuXL8WhXFJSsvDPBd17dP9j9mx96LbCMgyNRnPt5eray5UgiPLy8pKSEl51tZqamrqGBq5FJgjiEnSus2+/fi1btUJjSYK5ufmQoUNhm4bfv3evrKwM++dQFxUVleUrVzo5O6EVTUdy9ePXrgK/IR85ahS+HpE6HTt2VFNXb6KIkpIS9kj6IXw+/1xcHKCgoZGRo6OjrNo13MMd9o16ZAR2MyCuXrkMqMZisbzH+qCr0sIvwB9NkBiampq/1Cy1IRw9elTO20TyeLzw06dhNYcOGwY7TxVBEJmhV+/e39cpA3Lr5q3RniP3791XWVmJbv8qKioqJiYmVtbWunAzsShNxtuMtLQ0QEEGgzFh0kQ0llQEjAuEHZdSV1cHnqlDJMaXhuOYHIdCQvlx8OYqHA5npNyXUJEBNps9oslV/O4eHhwOB838nhvXb3z+/Bk0CzBUhu3S09Pr4gR5bbhy6bKcP64IhcIb128ACvZzc8OJylLE1tYWqikW0hB8xo5lMiEX6uV//Hj+3Hl5tjQmKrq0tBRQkMlkevt4Y6wiCPJvp4iAcYFi3QSPxws6cmT4kKEH9u8vKSlBz5FGc/nSJVjB3n36YC9jsqGrqws+S+zK5ctoLBXBhuPgSCg/nvA4oba2FlCwT9++qljsQ5Lnf9+xTUl4aWpq+vr7oY0/TgREA0/mHDxkiGw7NsITsudSdXX1+bhz8hyBz54+hX1Dg8Xj0j9jjx2LJkjuGUZPr/+AAbCaocHBsE23KIRAIDh+7BisZv8BA3Sx4xOCIP/OsOHDDY2MxL2VsrKyI4cODxk4aNGCBfHx8bBz0RE54c6d24BqdDrdPzAAXSUhvv5+sOUXLxITy8vL0VgKQafTJ/+GDcfFYKxkNvPwwQNYQey/SR4UFBSWrVzRuHM0g8FYvGSJiooK2vg92e/fP33yFFDQpVs3mZzMWZ/OXboYgb5BjYqU6ymdt29B3mfbt29vbm6OX23p4uTsZGBggD5I8hkGtu9Tdnb21StX5dPM8+fOFxQUwD5djPXFN0YIgvzH08rkKVMks63a2tprV6/NnvnHgH5uK5cvv3rlSkVFBR4CpCF8/PjxbfpbQEHHzp3xvp2cGBgYuHTrBijI5/Mf3H+AxlIFZWXljZs3+Qfg6yt4JJQffwCaH2/ZsiUOzSMVDg4Ofy1d8qspcjqdPu/P+dgs6d+Ijo6GLRIc5j5cHnwbDrqb7969e/b0qdwG4d27d0l7aJBGM3TYMDRBYpiYmLj26gWrGQI3iJhahIWGwgr2dO1p2qwZRimCID+nb7++nSQ7v6ekpORc3LnFCxe59ek7Ydz43bt2xcfHY49y5CfEg960EwThORLrEcnLiJGewA99d+6gq1R5sjgUdMS5a1e0QhxIIj+ek5OTm5MDKNh/4AA8cmSjn5vb3v379Bq8SFlNTW3j5k2Ypvk36urqzoF29pDtyZz1GTJkCOyInqjIKPkMwvdZWYCnbhUVlZ6urvjVJgODhgym0+nog8TwC/Cn0WiAgunp6Xdu35Y3G29cv/4+KwtW09ffH+MTQZCGMO/P+VKZlsTn85NevAgLCZ09848+rr28Ro9ZuXx5+KnTLxJf8Hg8PC7IV+7egcyPGxsbYxEbmXFwcICt7n9w/77ctu+jEJ0cHY+EBJuZmaEVYkIST8jPQHtEMJnMvv364ZEjIW3atg07fszP319RUfEnv8Zms4cNH34y/DS+9fp5IqAUdESPbE/mrI+qmlqv3r0BBW/eAJ6SShUeP34MqNajZ0/YYetIo9HW1rZvb48+SAxLS8uuLi6wmsHyV0IeGhwCK9i5c2dcjIggSAMxNjaWWJeVf0MoFGa8fXsu7tzmTZsmjh/fq0dPT3ePeXPm7t295/y5cynJyVVVVXik5BOhUJj4/DmgINYjkp8BAwcCqpWWlqanpaGrZGaMl9e2HduxNbFYYUpgG0kvkwDVHDo4qKur45EjJ6qqqlN+/83bx/vu3bsP7t9PTX1TXFRUUVHB4XB0dHQsraw6duro2qsXHsH/JDoSejIn9JxrMuMxwuPC+fNQanV1dWdiY/3kr8zw0cNHgGq9+/bB7zV56N2n75OEJ+iDxPAPDICt+H718lXC48cdOnaUEwMfP3qUkpICq+kX4I+RiSBIwxnj7ZWQ8Dj+bjxJPo9AIMjOzs7Ozr5969bXH6qrqxsZGxkbm5iYmBgaGRoaGurp6eno6sJO80PIxpvUVMC3IzQaza1/f3SV5PRz67d3zx7AWb7PnydaWVujsSSEzWb/uXAB7BsR5IdI4kr58gVkfrx7jx542EiOqpragIED8QvcaDIzM589ewYo6NKtm6aWlvwY2LpNG2sbmzepqVCCMVHRvn5+sB0SyM9zuDoUNTW1jnKTyKMErr1cN65fD3hLjfwcW1vbDh07JoCuyQg+EiQ/+fEQ6OLxNm3b2rdvj5GJIMgvsWTZMp8xXoWFhaT9hCUlJSUlJa9evqr/QxqNpqGhoaurq6unp6urq6Oro6urp6unq6Otra2j8/OFvwg1btqfQRaPt27d2sjICF0lObp6enbt2gEOynr+7JkndFtzpOloaWuv37C+dZs2aIUEEHt+vLKyMjMzE0qNRqPBzupFEBISExUNKzhM/uYieozwWLt6DZTahw8f7t275+zsLD8GZmVlAXb46eToiA2vSYWamlqrVq1evnyJVkiMgHGBsPnxhISEl0lJ8nC7nJKcDGsdQRD+WDyOIEijrp4bt2yeMnFSdXU1hT62SCQqLi4uLi5+/fr19/9VWVlZV1dXW0dHV1fXwMBAT19PX19fT19fT08PdqIPIj5gK6uwHpEqdO/eHTA/DtuiB4Fi+ozpmByXGGLPj6ckJwNWqFlZWeno6OBhQ2SY2tpawN4gBEEYGhrKyWTO+vRzc9u5fUdFRQWUYHREpFzlx18kvgBU6+KEE35IRxcnJ8yPSxIHB4c2bdokJUGuqAs+ErRp6xaZtw68eNzS0hInoCAI0jhatGixYtXKP+fNFwgEsrFHFRUVFRUVGRkZ3/z8S9W5nr6+kZGRkZGRoZHhl3/Q09fHogeykfzqFaCaswteIqmBc1fnbVu3Qql9+vSpoKBAV1cXjSUVdDoDTZAYYs+Pp6enA6p16IQr9BEZ5/q1a6WlpYCCQ+RmMmd9uFzugIEDTp86DSV47969jx8/6uvry4mBKSnJgGqdOzviV5tsOHbpfPDAAfRBkvgHBsz+YxagYHx8fFpampWVlQyblpWVVb+1Lgi+8jdPAkEQQFy6dftj9qzNGzeJRCIZ3s2vVecpyf+4J2QymXr6+iYmJs2aNTMxNTEzMzM1NdXV08PAkBZlpaWAPX8MDQ3Nzc3RVUpgYmpqYmKSnZ0NJZiWlob5cUSeEXt+/F3GO0C1Dh0wP47IONFRwJM5hwwZIp9ODvfwAMyPC4XCmKjoyb9NkRP3Un+0AreRt24mJnLV/p4qtGzZksvl8ng8tEJiOHftam1t/ebNGyhBkUgUEhS8as1qGTYtLCQUtlG+kbFx7z69MRoRBGkKIzw9RSJiyyYZT5H/ED6fn5uTk5uT8+D+/a8/5HK5ps2amZubW1paWlpZWlhYYMZcYqSlpQGqdejYAS2lEA4dOgDmx9PT0uRqwTSCfIPY8+Pfr9VqNHQ63a6dHR4zRIZ5l5GR+DwRULCri4vcpibNzc3bOzg8ffIESvBMbOyESRMZDNlf4iQSid6mv4VSa2vXFr/aJITBYLRs2RK2YSXyn/gF+C9asBBQ8Pq1a9nvJ5mYmsqkXQUFBRcvXIDV9Bk7FjsDIAjSdDxHehIi0ZbNm+UwRf49PB7vTWrqm9TUS//7ibKysoWlRYsWLVu0bNmyVUszMzN0SUzA5sfb2dujpRSinX27mGiw0WXpaeloKSLPSKB+HCw/3qxZMyUlJTxmiAwTHQ08mXO4/E3mrI/HCA/A/HhxcfGN69d79+kj877l5uYClhW3boP5cZLSum0bzI9LGNdevUybNXuflQUlKBQKQ4JDFi/5SybtOn70GJ/PBxTU1tYeNHgQxiGCICB4jhqpoamxcvmKmpoadOMbKioqEp8nfq37UVJSsraxadu2bTv7dm3t7PChHpCMt28B1dq1a4eWUgjY9xlvQWMJQSiHePPjnz9/BpyP18q2FR4wRIapqam5cA5yMqempqahkVFubq7cWmppZaWsrAx4FoqMiJSH/HhWZiagmrWNNX67yYm1tQ2aIGFoNJqfv9/K5SsANS9euDBh0kQ9mVvJXlZaGhsTA6s5xtuLxWJhHCIIAkXvPn0MDA3nzZ5TVFSEbvyEysrKZ0+fPnv6NCSYoNPpllZW9vb2nbt07tCxI56Wmwjgs56ampqhkRFaSiH09fXV1dVLSkpA1PLkOG+AIIS48+P5Hz8Cqtm0aIEHDJFhrl29Wl5eDihYXFzs6e6BxgLy7OnTd+/eyfzUmiy44lYajda8eXOMHHJiYWGBJkget/79D+4/8BHuBonP5x8NDZs9d46MGXX61Onq6mpAQVVVVXcPvCYiCAKMra1tUEjwX4sXw/ZIlGGEQuGXZiynTp7kcrmdHB2duzr3dHVVVVVFcxpBXm4elJSllSX6STksrawSHj8GkeLxeJ8/f9bQ0EBXEflEvB0YP4Lmx83McJIyIstER0WjCRQ4TJGRMr+PH/I+QEkZGBgoKChg2JCTZmbNmEwm+iBhGAyGj+9YWM2zZ84UFxfLkks8Hi/89GlYTc+RI/F0hCCIONDV09u7f39AYCCON2jE2f72rVtrV68Z6NZ//tx5t27ehG2rJfMIBILCwkIoNUtLK7SUclhZQR41wMdABKEclMqPm5vhAUNklbdv3ya9eIE+kJ/z587LfJfJD3lgdSgmpiYYM6SFwWAYGBigD5JnyNChWtrasPmFE8eOy5JFMVHRpaWlgIIKCgqjRo/C2EMQRFwP1XT6pCmT9x7YL/OrDMVEXV3drZs358+dN6Cf24b167EPcgMpyM8HfKNg3hyjl3rAZsk+fMhDSxH5vZSLVT0/Px/wwUZXVxcPGCKrxGDxOEWoqKi4dPGibO8j4KlbXx/Tr6RGH/Pj0oDNZo/xGgOrGRUZCduhS4oIBILjx47Bag4bPlxVTQ1jD0EQsWJnZxd2/NiEiRPZbDa60TjKysqiIiK9R4+ZMmny9WvXBAIBevITPn36BKhmaIjNx6mHoaEhoBrgcgQEoRzizY+XfC6BkpK9wVMI8pWampoL58+jD1QhKkLGW6wANmrQ19fHgCEzBgZ4gKSDx4gRsI1WKysrT588JRvmnD93vqCgAFCQxWJ5+Xhj1CEIIgGYTOa4CeNPhZ/u5+aG7VaawrOnTxf+uWD4kKGhISFVVVVoyA+BGsz4922hIZZNUA/Ykaqwq/cQhFqI95pdVgb27dLTx/w4IrNcuXy5oqICfaAKr1+/Tn6VjLfaDUFXD9f9kBodHTxA0kFBQWHkKOB2H6dPnYIdaCktwkJDYQX7D+ivo6ODUYcgiMQwMDRcvnJFSFiok7MzjUZDQxpNQUHBnl27hw8ZeuTw4crKSjTkG2Czmdh2j4ro6ekBnmQwP47IM+LOj4Mt9dXVxfw4IrNER0WhCdQiSnandJaVlgIuZVXDhgbkRk0dD5DUGDVmtKKiIuxDsgycmm7euPE+KwtQkMFgjPXzw3hDEETyWFlbb9m2Nez4sf4DBuBA7CZe4A7s2z9s8JAjhw/L/BygX3UGSkpZWRmjlIowmUwlJSWwiCrB/Dgiv4g7P14G9gyPSRZERklLS3v18hX6QC2uXrkiM61+vwG2NkdVFU/dpAavrVJERUXF3cMDVvP4seO1tbWUtiUkKBhWsEfPniYmOCgYQRCpYWlpuXT5sqiY6IDAQFzL0hTKy8sP7Nvv6e5x4fwFdOMLZaVg+Rac0kFdAI8dYAYPQSiHePPjFXD5IxVVFTxaiEyCxeNUhMfjnYuLk8ldqwTt8KiqporRQmZUVPAASRMvby8OhwMoWPTp09kzZ6hrSMLjxykpKYCCNBrNz98fIw1BEKmjq6c3acrk2Lizm7dtde3Vi8vloieNo6CgYPnSpYH+AS+TktANwJfiWDNBXQCPXW0trs9A5Bfx5scBz9eq+AyPyCI8Hu/yxUvoAxWJjoqWzZgE7V8Mm/tDwMHnc+miqaU1eMgQWM2joWGALZIkTEhwCKxg5y5drG2sMdIQBCHLszed7uzsvGbd2ktXr6xdv67/gAGws5rlh+RXryaOn7B18xY5b7dSV1cHJaWgoIBxhffzdXV89BOR32s0Vc7XHHyGR2SRy5cu4WROipKVmfkkIUH29osPmlljsVgYKmSGxcJGk1LGx3csbLvPDx8+XLp4kYpWvE5JefzoEaymX4A/xhiCICSEw+H0dHVdunzZxSuXDx05PHHyJPv27fGu6ZcQCoWnTp70GeOVmJgotybU1oHVI+I9IZXv58FOHXy4DB6CUA7x5sf5fD4Jv/MIQh5ktQZZToiMkMEpnQI+ZNUAnrpJDg5ikjr6+vr93NxgNcGrsCUD+Me2a2fXrl07jDEEQUj9NE6nt27TJnDcuL379125fm333j2Tp0zp6uKioaGB5jSE7OzsKRMn7dqxUygUyuHuA2YzWUy8aacqbLgHrjrMjyPy/Ggs3vM1XJ6FyWTg0UJkjNTU1JTkZPSButy+dauoqEhLS0uWdgr26YJOp2OckPqxnIHXVunj5+934fx5wK9eVmbm9WvXXHv1opAJ77Oybt28Cavpi53HEQShFFwu16FDB4cOHb78a25ubkpyctqbtDdv3rx586bo0ye06N/uXY+GhSUnJ69eu0be3isIhSK8J0RocA9cArl8z4QgXxBjfhy2/SUmWRDZIwaLxykOn8+PjYkJHDdOpq4KoAXFWINAcvAAkQHTZs16urpeu3oVUDM4KJha+fGw0DDYl3NWVlbOzs4YXQiCUBcjIyMjI6Peffp8+dfPnz+nvUl79y4jKyvrXca7dxkZJSUl6NJXnj554uczds26ta3btJGfvQa8b8d7QryfJ7DNDiLfiDH6GQwGjUYTiWBeafL5OCgAkSmqq6svX8LJnJQnNjrGPyBAll7gMRiQ1wXsYUdy8ACRBP/AgOvXrkHdMhEE8SY19V78PSdnJ0rsfkFBwcULF2A1sXgcQRAZQ0NDo5Njp06Onb7+pKysLPNdZk5Odl5uXnZ2dk5Odm5OrjwnzQsKCqZMmrx4yV/gjctIC5sN11ijtha/ZXg/j212EHlGvG+HmEwm1LssfJ+JyBiXLl6srKxEH6hOfn5+/N27Lt264X32j0/d+GqT3OC1lSR8KXa+e/cuoGbQkSNUyY+fOHYcNhSNjY179+mNcYUgiGyjqqra1q5tW7u29X9YWVmZl5ubn5//8ePH/C9/+5hfkJ//6dMneSg4q6urW7ZkaWFhoc/YsfIQA0y4xtO1eE9IWWoh68cxP47ILxTKj2OSBZEpoqOi0ATZIDIiUpby40pKSoBqFRUVGCFkBg8QefAPDIDNjye9ePH0ydP2Du1JvuNlZWUx0cDdxsb6+dJoNAwqBEHkECUlJStraytr629+LhKJiouLCwsLPxUWFhZ+Kvr0qbCw8NOnwk+fPhUWFH7+/BlwDZN0EYlEu3bs5FXzxk+cIPOHG7Dat6K8HL8+VL2fhzt2LDYb/UTkFvHmx1ksVnV1NYhUJT7DIzLE65SU1Nep6INs8Ojhw7zcXEMjI9nYHUXQ/HhpSSlGCJkpKytDE0hC6zZtHDo4PEl4AqgZHBRE/vx4+KnTUPeKX9DR0Rk4aBBGFIIgSH1oNJqWlpaWlhbRosX3/5XP5xcWFOQX/P3Xp8JPeXl5OdnZubm5NTU1VNzfQwcP0ui0cePHy/ZhVVZWhpLCdvbUpbQU7IELtlIKQaiFePPjXC4X6tm7rByf4RHZIQqLx2UIoVAYHRX9+7SpsrE7KioqgGplZZgfl5f7aaTpBAQGwubHHz18mJKc3LJVK9LuMo/HO336NKyml7c37JxhBEEQ2U8KMJkGhoYGhobf/6eC/PzsnJyc7Ozs99nv3mWkp6Xn5+dTYqcO7j+grKw8avRoGT5waupqcDftmG/B+3lCTU0N/UTk91IoVnUVVZWCggKY83Upnq8RGaGqqurKpcvogyxx9syZSVMmy0ZGhs1mKykpQTXHLy4uxvAgM8VFeIBIRIeOHW1b2756+QpQM+hI0IZNG0m7yzHR0aWgBWtqamrDPdwxlhAEQaDQ1dPT1dNzcHD4+pPy8vL0tLT0tPSMjIzU1NQ3qamk7Wy+fes2fX397j16yOrRAcxm8vn8z58/a2hoYMxTi5KSEsAvIObHEXlGvNkcVVWwb9fnz5/xaCGywcULF2DXkiNkuC+5dvVqPzc32dgdDQ0NqPz4hw8fMDzIzMePH9EEUuEfEDB39hxAwTu3b2e8zWhu0ZyEOysQCE4cOw6r6TlyJJfLxUBCEAQRHyoqKvbt29u3/7t/V21t7euU1y9fJr16+fJl0ktSVZcLhcKlfy05EhxMzutg04HNZubl5WF+nHLk5eZBRpQ65scR+YUuVnVVVbB1+vn4DI/ICjFR0WiC7BEVGSkz+6Kjqwt36s7H2CAzH/EFBslw6dbN0tISUFAkEoUEB5FzZy+cPw+bRlFUVBw5ehRGEYIgiCRhs9lt7dp6eXuvXrs2Nu5sbNzZxUv+6tuvr7q6Ohk+Ho/H+3PePKjKD7KhoakJqPYhLw/jmXJ8+AB51DTU8QUJIr+IOz8O9vYJa9wQ2eDVq1dv3rxBH2SPxOeJb9++lY19MTDQh5LKy83F2CAzefggRD78AgJgBa9euZpLym9iWGgYrODQ4cNUVVUxhBAEQaSInp7eoMGDV6xadfHK5dCjR3+fOtXe3p5Op0vxI71//37l8hUy6ba+vj6gWvb7bAxgypGdDXnU9A300VJEbhFvfxVtHW0oqeLi4rq6OhaLhccMoTSwxeNMJtPY2BhdbTQ5OTmA/dqiIiLnzp8nA7YYGBhCSWVmZopEIhqNhsFGQoqKinAWEwnp3af3gX37AJ92BAJBSHDwwkWLSLWbN2/cyMrMBBRksVjePj4YPwiCIOTB2sba2sZ6rJ9vcVHRzZs3r1+7/uzpU4FAIJWLTkR4+AhPTxlzWElJSU1NDWo8Y3p6GgYt5UhPSwdUMzQyQksRuUW8+XE9PT0oKaFQmJWVBbvoGEEkTGVl5ZXLkJM5XXu5rli1Co1tNIsWLLx29SqU2sULF6ZOn6agoEB1W0xMTaCkeDxebm4uvsUhJ2/T36IJJIRGo/n6+a0GPbdfOHd+/IQJunCtk5pOSHAIrOCAgQO1tbUxfhAEQUiIppaWu4eHu4fHl5k9cWfjUpKTJfwZ9uza7dy1q4GBgYx5a2BgAJUfT3uD+XHqkZ4GdtTodDrsigQEoRbiXegE++3KeJuBBwyhNBfOn+fxeICCQ4cPR1ebgvsID0C1ysrKixcuyoAtZmZmgGpv09Mx0sgJHhrSMmDQQD3QO6i6urpjYUfJs4MJjx/DZkYYDMZYP1+MHARBEJKjrq7uMWJEUEjwsZPMU8oKAAAgAElEQVQn3Ed4KCoqSmzTVVVVa1evkT1LAQt+c3JyqqqqMEopBI/HA1xxqKOry2Aw0FVEbhFvflwPOD+OlW4ItYFtrmJqaurg4ICuNgUHBwfTZs0ABaMiImTAFtNmzQA7orx8+RIjjZzgoSEtDAbDB7pVSGxMTElJCUl2ELx43LVXL1yngiAIQiEsLCzmzZ9/9vy5qdOnSWx506OHD8+fOy9jTpqZm0FJCYXCpKQkDE4q3cwnJQE2LDIza4aWIvKMePPjBgYGgEmW1ykpeMAQSl+90kGrNYcOH4auNh13d3dAtbS0tJfUv61UVFQELEVJSnyBYUZOkl7goSEvQ4YN1dTUBBTk8Xgnjh0nw669Tkl5/OgRoCCNRvP198OYQRAEoRxKSko+Y8dGn4mdv2CBZBo77Nuzp6amRpY8tLS0AlR7/uwZhiWFSHyeSNpYQhDKId78OJfLBbzOYaUbQmmio6IA1Vgs1sBBg9DVpjNw8CAOhwMoGBkRKQO2tGhhAyWVkpICOAQVgSI/P7+goAB9IC0cDmeMlxesZmRERGVlpdR3Dbx4vIuTk5UVPtEhCIJQFQaDMdx9eER01PSZM1RUVMS6rYKCglMnT8qSe1bWoPnxp5gfpxLPnj4FVLPEuylEvqGLewPNLZpDSVVUVLx79w6PGUJFKioqrl29BijYo2dPdXV1NLbpqKio9O7TG1Dw+rVrZUBDcqSITYsWUFI1NTUvsIScfMAW8CLiwMNzBGyaoKKiIvzUaenu1PusrFs3b8Jq+gX4Y7QgCIJQHSaT6eXtHR4V2X/AALFuKDQ4pKysTGZ8MzExUVBQgFJLSkqqqKjAaKQEVVVViYmg9eNWlugqIs+IPT9ubt4cUA3fZyIU5cI54Mmcw7C5ChzDQVus1NTUnD17luqetGnTBlDt/r17GGZkAw8K+VFUVPQcNRJW8+SJE7AXo18lLDRMKBQCCrZr187Ozg6jBUEQRDZQV1dfunzZ1u3btLS1xbSJioqKqMhIWTLN2sYaSorP59+/dx/jkBI8fPCgrq4OSo3D4Zibm6OriDxDpfpxgiDu38eTNUJJYJurmJiYOHTogK5C0bpNG9i1+bCDWKVCK1tbJpMJdurGVCzJEAqFjx5i/TgFGD16tKKiIqBgSUmJFE9QBQUFFy9cgNXE4nEEQRDZo4uT0/GTJzo5OopJPzI8AnCqodSxa9cOUO3undsYgZTg7p27kE9/rVoBPv0hCBURe368RYuWgGpPEhJk6UqGyAkvEl9kZGQACuJkTnDcPTwA1bKzsx8+fEhpQzgcjg1cC/L09PTc3FwMM/Lw9MmT8vJy9IH8qKqpDXMfDqt57OhRaY0EOHHsOGChE0EQ1jY2XZycME4QBEFkDzU1te07d3j5eItDvLCw8NrVqzLjFWx+/M7tOzI2wlQmqaurg21Y187eHl1F5Bzx91dpbq6srAylVllZCTuCAEEkAPhkzkGDB6OrsPTr7wZbpBlF/SmdHTt2AlS7cvkyhhl5uIyHgzp4+/iw2WzYpECcNHpAlZWVxUQDl677+fthhCAIgsgqNBpt+owZs+bMptFo8A9okVEyY5SdnR2dDpbYqaqqAp8UgoBz984d2E7xdu2wWx0i74g9P06j0VrZ2gIKXr1yFQ8bQiHKysquX4OczNm9Rw+czAmOoqJiPzc3QMH4u3cLCwsp7UlHR8yPyyYCgeDm9RvoA1XQ0tIaNAT4nWhoSChsE/CGEH7qdHV1NaCgqampa69eGCEIgiCyzchRo2bPnQMum5iYWFRUJBsWKSsrW1pCTla8cP4CBh7JgW1Yx2Qy27Rti64icg5dAtuAnfN248YNbLGCUIjz587BrlDDyZxiAnZKJ5/Pj42OobQhbdu2Baypf5v+NjU1FcOMDNy+dausrAx9oBBjfX1hO0Lm5eZevnRJkrvA4/FOnz4Nq+njO1YcFYUIgiBlZWW3bt48uP/AqhUrlyxevH7tuv179128cKFYVtKplGOEp2dAYCCsplAovH7tusxYBNtt7OGDBx/y8jDwSEthYWH83XhAwTZt2igpKaGxiJwjifx4W9CVGqUlJQ8ePMAjh1AF2EloJiYmHTp2RFfFgbWNtW1ryMUusTExlH6Zx2KxYMciydI6VkoTTf35sfKGgYFB3359YTVDg0MkeimMji4tKQEU1NXVHTBwIMYGgiCwPH/+fO7sOQP6uc2fO+/woUNxZ89evnQ5Oioq6MiRZUuWDuw/INA/4PYtnF4oBSZNmdy5SxdYTdg1vtKlq0tXQDWhUBgRHoFRR1qiIiNhZ8k4g8YPglAUSeTH7e3tORwOoCDVqzIRObrJfvYsMzMTUHDoMCweFyOwUzoLCwvv3Kb2E5RLNxdAtcuXLlVVVWGYSZfc3NzHjx6hD5TD198fsLUoQRAZGRkS6y4qEAhOHDsOq+nl7Q1bU48giJxTWVn516LFkydMvHP79r8lnkQiUfKrV/PmzAnw88/OzkbTJMySZUvV1NQABV8mJdXW1sqGOa3btFED7cB59swZHo+HUUdC6urqwBNizl0xP44gEsmPs9lse9BhuPfi46ne2BeRE2DrNFks1sDBg9BV8dG7Tx8VFRVAwSiKV0y7uLgAZqCqqqrOxMRimEmXUydPikQi9IFymJmZ9ejZE1Yz6PARyXz4C+fP5+fnAwqqqasPcx+OUYEgCBR5ubn+Y30bPislJTk5wNfv9q1baJ0k0dTUnPL7b4CCdXV1ya9eyYY5NBrNCbTFSllZWWQElpCTkbNnzhQXFwMKGhoZmZubo7EIQpfMZmAXQ/H5/OgoXKePkJ2y0tIb1yG72nXr3l1DQwONFR8cDgd2wf7jR48oXV6kqqYG28/nxPHjOEBCipSWluIrCuriHxAA22779evXDyXSsO5oaBis4MhRI/+vvfsMiyJZ4wU+MwxhYAiCAiKSowkUFcwREyiCERAFjGvOOeesu6Y1J0wooICuOSMqqICKgChRBSQPDHHgfuBc7153dRVrerp7/r8P5znPOVjd/VZNd3V1Vb0qKipoEgBAqsc+dfKUn+2wlZSULFqwkE0bdDDCIDc3I2NjggXGxsayJji9nXuTLfB0wCmyabTg10kkEuJb5PXqjWznABwOdePjHQlvFhZ0/gLW+wDNXQ6/THbJHjJzUsBj6BCCI1C1tbVM/5hHtqudnZ1NNtk6/JTAs+fw6GQuK2sr4luvHjtyVNqnfffOHbL7jKmqqg4fMQLtAQBIWbN6zcd6pSKUSCSrV65KTk5GDCnD4/E8PT0JFsia+eMcDsepQwctolus5OXlYVYi3YSHhWVlZZEts1///ggsAIey8XETExOySzaKioouIsMY0FtICMkmamho2K59e0RV2oyNje2J7gd1OSyc0Tsb9ujZk+w8zSOHj2AKuUwUFxefO3sWcWA0P39/sgW+ePEiJiZGqud84vgJsgW6e3iQ3QgLAOTZo4hHv5Itpry8fP3adQgjlfr060swt1lGRiZrIqOgoNDb2ZlsmUePHC0pKUGro4ny8vKD+w+QLdPCwsLc3ByxBeBQNj7O4XCI36xPBQRgvQ/Q1vNnz9PT0ggWiMyclCGbpbOoqOjmjZvMjYaamlq37t0JFvghM5Pp27Iz1NEjR/CGw3St7Fq1btOGbJlSnUIeHRVFdmqekpKS1yhvtAQAIOX4sV+9B8a/fn3/3n1EksquqUPbtqRK+/jhA5uC069/P7IFFhUWHjl8GK2OJk6dDMjNzSXdZjB5HOB/qBsf70V6P6zPnz8Hnj2HKgR6IrsYjc/nuw4aiKhSo0fPHmT3eQ9meHKbgaTb3rEjR8rKytDSqJSdnR10HkmW2MDX349sgY8jIxMSEqR0tsdJb5E5wMVFR0cHzQAAiMjMzIyNIbD99MUQLGumlENbB1JFlZeXEx9wlKEWLVuamZmRLfP8ucCM9HS0OpnLyckJOEk4oQufz+/vMgCxBahD3fi4iYmJuQXhhRsnjh8XiUSoRaCbwsLCu3fuECywW3dk5qQO8a8Rr169epuUxNyAtG3XrmnTpgQLzMvLO3TgIFoalXZu38HofX7gC0dHR9tmzciWefzoMWmcasKbN1FPnxIsUEFBwWfMaLQBACAl4uFDIuVEPX2KZc1Usra2Jlhafl4+m4IzdPgwsgVWVVVt3LABrU7mtm7eQnyCUfcePTDtAOALHpUHc3UlPAlRJBId+HM/ahHoJjwsrKqqimCBg93dEVUqeXh48Hgkb49BF4KYHRCie85wOJxzZ8++f/ceLY0ajyMj79y+jTiwhh/pKeT37t4lm0KzDvHJ471692rSpAkaAACQEhcbS6Scqqoq6S3EgX8i+ywoK2fVosb+AwYIhUKyZT6LfhYeFoaGJ0N379y5f+8e8WKHjRiO2AJ8Qen4uIuri5KSEtkyg4OCEhMTUZHMVVpaKhaLWXZRl0IukuwCIjMn5RobGLR3dCRY4LWrV0tLS5kbENdBA8lm6ayurt6yaRNaGgUqKiq2bdmKOLBJ127dzIhmUqqpqSE+hTw9Le3e3bsEC+RyuaN9fVH7AEAQwU/1mRkZiCdlGmhrEyytjF2vogKBYICrC/Fi/9j5e05ODtqeTBQXFW3dvIV4sVZWVnZ2dggvwBeUjo9raGr26NmDbJkSiWTzxo21tbWoSwbJzs4+fuzYpPETunfp2qt7j57dunft1Hn4kKGbNmy8d/duTU0No68uOioqg2gX2W2wG9oM9TyGeJDseZeV/XXlCnOjoa6u7jqQ8AKgFy9enDt7Fi1N2vbu3pOBl3bW8fXzJVvgjevXP338SLDAkydOkn2ad+rUycLCAlUPAARlZWWRKkpUjD0/qaOsrEywtPLycpbFZ+TIkXw+n2yZxcXFq1euQtuTiXVr10ljl/yRXp6ILcDf8Sg+nttg8ttEvH71+lRAAOqSEXKys5cvXTpksPu+PXtjYmK+dEcqKyvT09NDgoMXzJs/bMjQsFAGL+AKCSaZoofP5xMfl4Qf0blLF11dXYIFBgcFMzognt5eZPec4XA4+/bsRcIfqXrx/Pn5wEDEgX16OzsbGhoSLLC6uvrkiROkSvv8+fPVv/4ie8ljSH8SAAA5V1VVRXAzX/aNsdJZdXU1wdJ4PAWWxcegSZM+ffsQLzY6KgqjLtQLvXSJ7IK8Ok0MDfv174/wAvx/jwOKj9fGoY2VlRXxYg/8uT8lJQXVSWe1tbXHjx0bPnTY9WvXv9+n+ZCZuW7NmgXz5pWUlDDuMgsKCsg+wLp266ZNdAkh/HBfmec2eDDBAt+/excTE8PcgDRp0oT4AqDy8vLly5aTfcmBL0Qi0aoVK5m+Ige+dYMinqkyPCyc1Oyk0wGnyCbhaN2mTctWrVDvAEAQ2YyayM9J6QtXPsmMmsoqyuwLka+fH/F5LRwOZ9+evbGEdu2HH/H27dvtW7dJo+QxvmOk0UIAmP2GRf0hR40eTbzMysrKFcuWk30ZA4KKioqmTZm6b8/eH59bce/uvXF+/sVFRcy60vDQMLKDfcjMKUODBruRXZwYEsTsLJ2+/v5cLpdsmW/i43/fsRONTRpWrVhJcOU40I2LqyvZNS6VlZVE5oUVFxdfDAkhe7FjfMegxgGArBqJhGBphYWFCCllyG4cJ1ARsC9ERsbGvXr3Jl5sdXX1koWL8vPy0AgpIBKJFs5fII21KXr6+i6urogwwFdkMD7e27m3gYEB8WKTEhOlkbUASFRNkq/P6OioqJ/9h6mpqXNmza6srGTQxV68SDIzp0GTJu0dkZlTZho1atSpcyeCBd6+dZvRr0+WlpZdu3UlXuz5wMDbt26hvZEVcPLkwwcPEAcW4/P53j6jCD/CgkN+/bP0+cBAglsWcDgcaxtrpw4dUOMAQGefPn1CECjz6tUrgqVp67Bzqe74CeOJ70LO4XByc3MXLVyI1Z/SVltbu2LZ8g+ZmdIofOy4sQoKCggywFdkMD7O4/G8RnlLo+RLFy9euXwFlUorEQ8fTpowod5dxpcvXx47epQpF/v0yVOyzzBk5pQ5jyFDCJZWVVUVdimU0QEZN2GCNNbirV295u3bt2hvpDyOjNy3Zy/iwHqD3d0bNGhAsMCysrIzZ878SgkVFRWB5whveT/G1xd1DQA09y45GUGgrp/zKJJgaY0aNWJllIyMjcnuFflFbEzsmlWr0Q6lavvWbY8iIqRRsrmF+cBBgxBhgH+SzZZDboMH6+nrS6PkTRs2kP2eDL/i3Nmz8+fOE4vFv1LI6YBT2dnZjLjekGCSCRj5fP5AZOaUNUcnJ4MmTUg2EtLbDlDM0tKytzP51ZpisXju7DlYrUlEamrq0sVLJESXjQM9KSsrj/TyJFvmhcDzpaWl9f7nF0NCioiukjEyNu7RsyfqGgBo7vPnz0x5YWG6nOxsgltga2lpKSsrszVW4ydOEAqF0ij52tWr+/f9idYoJadPnTofGCilwqfPmEF8w0wAdpDN+LiiouL4CeOlUXJFRcX8OXOxwE3mampqtm7esmPb9l8foykvL7/IhCHF/Ly8B/fvEyywS9eu2jo6aEsy5050C/iPHz5EPnrE6IBMmDRJGqs1s7Oy5s6Zi/RWv3ojys+fPXMWE5MbQ/0MHTaM7KuvSCQKunChfv9WIpGcDjhF9gJ9Ro/GWxwAMALTO3hMEXQhiGDucVMzMxbHSktLi3g27y+OHjlyPvA8GiRx165e3f3HLikV7tShg6OTE4IM8K9klrLWxdXVTDpPo/z8/NkzZhYXF6N2ZaW4qGj2jJkXzhN7Xt6/d4/+Vx0aGko4M6cHMnPSwkC3QYqKimS79YwOiKGh4ZChQ6VRcvzr1wvmzcfE53orLS2dOX3Gxw8fEAr5oaamNmz4cLJlnj19pn5fqq7+9RfZ6ZN6enoDXAaglgGAEa79dRVBkDaRSBRMNN29GavHxzkcjpe3t5GxsZQK37516+XwcDRLgu7eubNm1WqCX4D+TlFRcdac2QgywLfIbHycy+VOmjxZSoWnpKTMmjGDbHoo+EFv4uNHj/J5/PgxwTLfJb+j/weP0IuXCJZmYGDg6OiI5kQHWlpa3Xv0IFhg5KNHTF+BO3b8OA0NDWmU/DgycuXyFWh19VBZWTl31uykxESEQt6M9PIUCAQEC8zPz79Ur1zTJ4+fIPxWP8ob+aMAgCliYmLeJiUhDlJ15NBhkUhEsMDmLZqzO2KKiooLFi2U0kqs2tra9WvX3bxxAy2T1EvisiVLpZf7dIyvr7HUPpYAsABPhsfu2q2ro5O0RgBfv3o9Z9bsyspK1DGVQoJDJo6fkJWVRbzkvNxcOl/448jIjx8/EixwEDJz0onHEA+CpUkkkovBzN6FXENDY5x09sjicDg3rl9fu3oNWt1PqaysnD9n7osXLxAKOaSpqTnYnfB6o1MBp352Jce9u3dTU1MJnoOWlhbx6wIAkJ7a2toD+w8gDtKTlJhEfFPm1q1bsz5uDg4OA1xcpFS4RCJZsWz5X1f+Qvv8RQ/u318wb35VVZWUyjcxMfH190OcAb6DJ9vDz50/X0lJSUqFP3/2bPbMWeXl5ahmCojF4lUrVm7asEFK3yQKieb7Ii6E6HAnn88fhKTSdNK6TRsTExOCBYaGhjJ9F5Ghw4ZZWVtLqfDwsLA1q1bX1tai7f2IysrKeXPmkF21A8ziNcqbbG8qOyvrSvjln/onx48dJ3tRw0eOYHHONABgpQf375NNRwRfVFRUrFi2jOzUWj19/cYGBvIQvRkzZzRo0EBKhUskkjWrVtVv5RnUuXnjxqIFC6U3uZPL5S5cvEgaGaQA2ETG4+NNmzb1HjVKeuVHR0VNnzqttLQUNS1VMTExozy9/rpyRXqHUFMT0vbyc3NzIx4+JFhg5y5dkJmTbtyJTiHPy829d/cusx8ePN78hQt4PGk9RC6Hh69cvgJ7kf8nsVg8e8bMJ4+fIBTyrFGjRsSnhp04fvzHv1E9i46Of/2a6EOf/L7qAAAUWL92XS69l70y1OaNG1NSUsiW2aVLFzmJnoam5qIli6VXfk1Nzcb1G04cP46GWg8hQcErli2X3rYqHA5nxMiR9nKwVALgF/Fkfga+/n4GTZpIr/y42Ngpk37Lz8tDZUtDdXX17j92TZ44iezuIl/hcrn6jfVpG4SwS4Qzc7ojMyf9uLi6qqioECww6MIFpsekRYsW7h4e0iv/2tWr8+bMrV+eQDlRUFAweeKk6OhohAJGjxlNdlpQRkbGjes/uqMo8cnj7h4e6urqqFYAYOKjee6s2VjBTNapgIDLP7mq6Ud0695NfmLYtVs3qW7gWVtbu3f3ns0bN0optyRb7dm9e9PGjVKdEmRuYT5l2lSEGuA/yX58XFlZefmK5dKbhMjhcBISEvx9/VLev0d9kxX/Ot7XZ3TAyZPSfgqamJhIKRkgka4A2dVkBgYGjk5OaF10IxQKezs7Eyzw+bPnaWlpTA/L1OnTGjduLL3yH0VE/DZxUlFREVrgP3388GHC2HEJCQkIBXA4HIMmTcjeozgczoljx36ol/XmzdMnJFcwKCkpeXp7oU4BgKESEhKWLl6CUUJSrl+7tvuPXcSL1dHRaePgIFeRnDV7tqGhoVQPERwUPG/OHLFYjHb7nyoqKpYuXkI8t/k/+1Sr165VVFREwAH+E48OJ2HfuvUIz5FSPURWVtb4seOeYHtWQkpLSzdv2jTO3z85OZmCw3Xv2YO2oYh8FEk2H+kgN2TmpCmyW6zU1tYGXwhiekwEAsHipUu4XK70DhH/+jU+cP5TbGzsWD//jIwMhAK+GOPnS3a2QXJy8o9spHuC9Kud60BXHWwyBgBM9vDBg6WLl2CbuF935/bt1StXSSMnzQAXFwUFBbkKpkAgWLV2jbSHSiMeRviP8U1n/jQgqfr06dP4seNu3rgh7QNNmTbV3NwcAQf4ETyanMfkKVNMTU2leoiSkpLZM2cd/7HJUPAd169dHz50WPCFIGqmRfD5/IEDB9I2GiHBwYQv1g2ZOWmqefPmZDNSXrl8mQWbh7Rr337Y8GFSPcSHzMxx/mPJ7vLPaGGhYVN/m1xQUIBQwN+Zmpp27UZ4qfixo0e//wcZ6el379wheEQFBYVRPj6oTQBgutu3bi2cvwDbxP1aV/nKsiVLpbEvM5fLHSSX71zNmzefMWumtI+Smprq7+uHXLXfEvX0qe/oMUmJidI+UG9n5xEjRyLgAD+ILuPjioqKq9euUVZWlupRJBLJvj17F8ybj4yd9fMmPv63iZOWL12aR2Hamb79+kp1h/pfkZOT8ygigmCBnTp3xqQ5OvMgOoVcJBJdv3adBWGZOn26mZmZVA9RWlo6b87cA/v3S2MCEYNUVVVt3rRp3Zo1VVVV+D3CP/n6+5Et8PWr11FPn37nD06eOEH2Y3lvZ2faPvQBAH7Kg/v3J4wbl5OTg1DUQ8DJk2tWrZJS0sJOnTo1NTKSz8AOHTasX//+0j5KSUnJ/Lnzft+xU6ppJxmnpqbmwP79M6fPKCoslPaxzC3Mly5fhpgD/DgefU7F0spqzry5FBzo3t273iM9nz97jur/cR8/fFi6eIm/r9+L55TGTSgU/jZlCm3DEnYplOzCSWTmpLm+/fqpqakRLDA4KIgFYVFSUlol/Q+cNTU1Rw4dnjp5stzmW/744cN4/7Es2JYHpMfGxsaJdAaL70wh//z5819X/iJ4LC6XO9p3DOoRAFgjMSHRb4zvs2fPEIofJ5FI1q9bt/uPXdKbFTFqzGh5jvCiJYstLCykfZTa2tozp0+P9fPLSE9Hq+ZwOFlZWZMmTDxy6DAFOy8JhcJNW7aoqKgg7AA/jkersxnk5ubi6kLNvWnq5Mm7/9hVWVmJRvB9eXl5O7fvGDl8xM0bN6ifuTl95oyGDRvSMzK1tbWhoaEEC2zcuLFThw5ocnQmEAj69u9HsMA38fEJb96wIDKWlpbUfOB8Fv1slJf3/Xv35K3tXbl8efQoH2TjhP/kO9af+I/uZVzcv/5fp0+dIruUoVPnztglEwDY9jKVmztt8pQ9u3djO/IfkZubO2nCxNCLl6R3iDYODvb29vIcZGVl5S3bt2lra1NwrMSERB/vUadPnZLzNaAhwSGjPL3iYmMpOBafz1+7fp20c7ECsA+Pbic0f+FCCj5mcjicmpqagJMnvUd6PouORjv4V1lZWVs3b/FwG3z2zBmZfEhw7tOHzskqH0VEZCMzp/zxGDKEbIHsmELOofADZ35+/vy581atWFlSUiIPTa6wsHDBvPmrV66Sk+uFX2Rvb0/8tf9fp5AXFxdfCrlI9kC+fr6oQQBgn5qampPHT4wZ5fOtz41QJyIiwsfLW6pR4nK506ZPQ6gbN268dft2auYXl5eX/7Hz9/H+Y1NSUuQw1B8/fJj62+RNGzZQ1pOft2A+Zt0B1APtxseVlZW37thOzcdMDoeTkZExdfKUNatWy+2C/X+VkpKyZtWqoe4eF86fl1VWGdtmzWi+YVZIEOHMnIMGY3ycASwsLFq2bEmwwOvXrrNm3HPBokW2trbUHOuvK1dGDhvOjg3cvyM8LGzksOH37t7FTw9+HPFdyB9FPHqblPTV/3g+MFAsFhM8ShsHhxZE764AALSSnJw8Ydz49WvXFhUVIRpfKS8v37p5y9xZs6Wdfty5j7Nts2YIOIfDada82ao1q3k8ikaEXr165ePlvfuPXWQ7D3RWUVFxYP9+zxEjoymckTnG19dt8GA0b4B64NHwnPT19bds30bZZkm1tbWXw8OHegw5duSonGcYl0gkd27fnjp5iteIkZfDL8swmYaxicn2nTukvZ3xr8jJzo6MjCRYYKfOnZCZkynciU4hLy8vv3L5Mjsio6SktGnrFspacm5u7vKlS6dOnpKelsbKt+iJ48evXb2mUPoJfIBlnDp0sLGxIdtTOnb02FevfIHnAgm/0WHyOACwXW1tbeilUA+3wYcPHnCePwAAACAASURBVCorK0NA6jx98tTb0+vC+fPS3oJDKBTOmDULAf+iW/fu02fOoOxw1dXVASdPDh8y9Mrly6zfbuXG9RvDhw47cugwlUNMffv1/W3KZDRsgPrh0fO0mjdvvnzlCi6XS9kRxWLxn/v2DfMYcuH8ebKbaTJCTnb24YOH3Ae5LVqwMDoqSraPq6ZNm+7eu6dBgwZ0jtili5fI7iE42B2ZORmjt3NvDQ0NggWyKeOirq7upi2bqcwGEx0V5TXSc+vmLdKecESZ3Nzc9WvXjhnlExsTi58b1A/xKeR3bt/++4eoiyEhRUS/3NjY2Dg6OqLiAEAelJaWHjxwwMNtcMDJk6WlpfIcioyMjPlz502fOvVDZiYFh/ttymRMSPrKSE9P/3FjKe7orl65ytvT6/69+6wMaeSjR2N8fJYtWUJ2L9b/1KVr1+UrV6JJA9Qbj7Zn1rNXr2kzplN80JycnK2btwwZ7C7DfUWoVFJScunixd8mTnIbOOjggQM5OTkyPyUbG5sDhw81atSIznGrqakJI5qZU19fH3uEMYiSkpKLqyvBAlNTU58/e86a+LRo2XL5ypWUrdbkcDjV1dUXzp8f6u5xcP8BkUjE3NAVFxX9uXffMI8hoZdCkcULfkX3Hj3MzMzIPviOHzte998lEsnpU6fJnjAmjwOAvCkoKNj9xy4314F7du/Ozc2Vt8v/8OHD2tVrPIePoCzpetu2bYcMHYqG908TJk4cMXIkxQd9/+7d/Llzx/r5sWmUPCIiYsK48bNmzExMSKT40O0dHddv3KCgoID2DFBvfDqfnJe3t7hUfOjgQYqPWzdKfnD/gcHu7kOGDdXV1WVZrYtEokcREXdu33kUESGTxJvf0q59+01bNquqqsrqBCoqKsrKysrE4vKKCs63J9HHxsaS/Zbg6OSUSjRdiYqKikBVVSAQ0HmPGmrU1NSUlpaWicVl5eU15AYcW9m1OnOa5PDQ2TNnGjTQ+s4f8BQUVFVV1dTUBAIBlWtr6qdnr57TZ87YuX0HlQctLS09fOjQ2TNnPIYO8fL2pvkalK/k5eWdCggICQqmeLW1uro6wS8KOdk5Ke/f16cvoqioqqoqEAhkeP9nn9G+Y1YuX0GwwGtXrw50G6SpoREZGUl2SpSxiUmPnj1RZYwgFovLysrEYnE1Y1db5n4mNhApkUjqd9OjBS5XRVlZoKqqqqqqpKSEti0rJSUlJ4+fOHPqdJeuXQe7D3Z0cmL9Jb+Mizt96vT9e/eonAqgqam5YvUqtLdvmTVndlmZOPRSKMXHff3q9fy5c41NTEaNGtW3fz+G3oskEsmN69cDTpxMTk6WyQnY29tv2bZVUVERLZl9cnKyGdzTYFoPhEv/jZ9+37nzDOlpSj/x0s7nO3XoMHDQwM5dujD9c1xmZubD+w8ePLgfGxMrw73Fv8XF1WXRkiV8PqXfbIqLiiIjI2NexLx79y7l/XtGzzz9V0Kh0Mzc3MzMzM7evmOnjpqamqx/hNTW1sbFxUU9eZqUlJTy/v3Hjx9ZNg+Xz+cbGRmZmZvb2Ng4dexgYWFB21M9uP/A4UOHZHJoJSUl5z7OQ4cNo38KplcvX54PPH/71i3qt/YyNDScMWvmvDlz6RMNFRUVExMTUzOz5i2ad+jYsUmTJugW11tNTc1QjyEfP3yg/6kuXb7MdeBAVBk9paSkRD56FP86PiXlfXpauhxuQigPtLW1Tc1MTU3N2ji0cXRyUlNTk4erLi4q6tPbmW5nZWBg4OLq2qdvn6ZGRuwL+LWr10IvXXr79i3VQx5c7qYtm7t264Yf+/ffodauXnM5PFxWJ6ChoeHi6uru4W5kbMyUoH36+PFiyMWw0ND8/HxZnUPr1q237dyBKSZf3W3ep6SkpaYWFhaWl5WLxeKqakp7LyFBwazfYZ8UnYYNTU1NzczNWrdu7ejkJNuWzGVEtW3euDE4KFi259CgQYNevXv36NWzTZs29J+8+f9uDcXF0VFRUU+jnj59Ss22bvWgqKg4Y9bMocOGUXnQjPT0QwcPyWRMSlb4fH637t3GjhtvZm7GygusqKgIPHvuwoULFO/1JltW1tY+o0c793Gm5+nt2Lb93NmzMjwBaxvrAS4uffv109LSolVkCgsLr129ejksPCkpSSYnYGxismff3oL8fB/vUbRt3q3s7Eb5+HTt1hV9x3r2zoNDNm3YQPOT1NPXD74YghXBNHT71u2TJ068iY9HKOSKsrJyr969/MeNMzQ0ZPeV0nN8/AvbZs369OnTrXs3A4Z/Ki4qKnr44MHNGzejnj6V1QwtP3//ib9Nwq/7R2zZtDnowgUZngCXy23ZqlW//v169+6tQdepXcVFRbdu3b554/qL5y9qampkeCZOTk6btm7BkvE6cbFxVy5ffhwZmSVPowFsIhAInPv28fPza2xgIJv7D1M+a8h8kOULbW3tbt27O3VwatuuHT2nV+Tn57+Mi4uNjY15EZOYkEDzybN6+vobNm5s1py6OZ61tbWHDx46dvQoDSfRU0BBQcHL23vS5N9YNhgRExOzctlyuX0W2tvbr167RldPj4bntn3r1sBzgbI9Bz6f7+jk2L17j85du8h235WCgoKH9x/cvXvnyeMnMrwFmZqa7tm3V1tH521SEp3Hx//X9e/QYcWqlczaMIcmqqur3Qe5ff78mc4nOXvunOEjRqCyaCU3N3fl8hXRUVEIhdzi8/n+48b6+fszaFbQz6L5+PgXRsbGnTp1curYwd7enimjYBKJ5PWr19HRUZERj16/fi3bAcSOnTpt37kDP+ofJ9vl+3+/C7Vt27ZT586du3SW1WDZVz59+vTw/oOIhw+jo6PpMJLQo2fPtevXYYYBh8NJTEzcsXVbTEwMQsECioqK4yaMHz1mDPU9EC6Dpv3v27P3+LFjtOo4Nm/RvE0bhxatWrZs2VJDQ0NWZ1JSUvI2KSkpKSnhTUJcXBxt54n/U+cuXZYuX0blvM6qqqolixZTlgeGttq2bbtl+zaBQMCOywkPC9u4foN8fvD4Qltbe/vOHTa2tjQ8t+3btgWePUeHM+HxeM1btHB0dGzbvl3Lli2p6VBKJJKXL18+i4p++vTJy7iXsn1L5HA4FhYWu/ftrbvxMmJ8nMPh6Ovr79q7p2nTpugy/qyzp8/s3EHfcQEtLa1L4WGY90QrycnJs6bPoPlnFaBGt+7d121YT/Hmh5Rhyvj43989LSws7Ozt7eztbG1taTJi+EVubm7Cmzfx8fHxr17HxcWJxWI6nJWNjc2+A/tZ88pDmcMHDx06eJA+I0Wmpqbt2rdr3aZNGwcHivcLLSoqev7s2Yvnz6Ojot/TaRtoF1fXJcuW8ng8NNcL58/v3L5DzocC2Ecmn3+4zNoW5+jhI/v//JOGJ8blco2Mja2trcwtLCwsLc3MzPT19aX0uaOwsDA9LT09PS0jPSM1NeVt0ttPnz4xbnsjNTW1mbNmDXQbRPFxlyxadOvmLdxuOBxOe0fHnX/8zoJn6u1bt5YuXiLzMUc60NTUPHD4kDEt9+zbv+/Po0eO0OqUVFRUbJs1s21ma2Nja2ll2bRpU1JDADU1NZkZGUlJSfHx8W/i3yS8eUNx1s3vaNmy5bYd27+sV2XK+DiHw9HX1z9y7Ki2jg5+6T+lvLzcbeCgosJCep7epN9+8/X3QzXRx6ePH8f6+ctwH1Wgm169e62j/TZN9cO48fGv1CUZsrC0MDc3NzQ0NGjSxMDAgLIP/znZ2RkZmZmZGWmpae/evXuXnFxQUEC3EDUxNDx4+JC2tjZ+yPVwOTx8w7r1dBtz5HK5TY2MbG1trW2srW1sTE1NiddvXl5eakpKYmJiYkJiQkJCeloaDUda/MeNnTBxIloph8MJOHFy965diAMr9e3Xd9WaNZTeYRg3rkrPO/U/KSoqNjYwMDQ0bNSokU5DHW1tbR0dHQ1NTTU1NXV1daFQqPh/felnVFVVVVVVVVdXi8Xi4qKi4uJikUgkEpXk5ebm5GTnZOfUKSkpYXpDt7O3W7FyJfW76QUHBW3euAk3mi8mTJroP3Yss9/kP30a5elVWlqK2qxjYWFx7OQJek71Onv6zO87d9L2ocPn8w0NDZsaGTVurK+rp6enp9+ggZaGhqaGpsaXO3bd96Sampq6e7Wo7h4tEhUUFORk5+R8zsn6lJWWlpqRnlFZWUnDa+zWvdvqtWv/PleXQePjHA7Hyclp564/8DP/WbSdW6CmpnYpPEwoFKKOaKK2tna8/9hXr14hFPB3c+fPozhLEDWYPj7+TzweT1dXV19fX6ehjo6Ojra2jo6OjoamhkCgqiZUU1NTUxUIVAQCPp+voKBQ959f/q1EIql7Gy0vLy8vL68orygpKRGViEpEIpFIVFhQWFhYWFCQn5Odk5WVlZ+fT/MNPDkcjp6+/p/7/6TbLHtmiXr6dNGChTQffBAKhU2NjAwNDRvpNmrYsGHDho20tLQ0NDXU1dXVhUIlZWVFRcUvTb2ukVdWVIhKSur68EVFRZ9zPud8zsnJzvnw4UN6WhrN3yv5fP6iJYtdXF3RPjkczoP79+fPnYdMmCy2eOmSQW5ulB2Oy8TGxIg79U91ZWpra+XkVy0QCCZMnDjSy5P6vYREIpGH22CRSIS7zBfKysrng4N0dXWZewlLFy+5eeMGqvLvZs2ZPWLkSHqe243rN9asWkXPseMfemRyuVwul6GLFYYNHz577pyv7r3MGh/ncDibt25Fus6fVVpa6uY6kIa9Jp8xo6dMnYoKoo/L4eFrVq1GHOAr6urqwZcuqqurs+y62Dc+Xg8KCgq1tbXsW4Wpq6u778D+JgxPbUoH7969mz1zVjbzMzzxeDwWtHOhULhh08Z27dujZXI4HLFYPNTdAyve2E1TSyv4YghleR8ZubVCu/bt9x86qKevz44qr6mpkZPB8c6dO589H+jp7SWTVD+hly5hcPwrFRUVF86fZ+7552Rn376F3XK+dvrUadreUpz7OO/au0eTwpQDZDH0HZLL5U6dPm3OvLksSLN2KuAkfuM/S01NbcjQoXQ7K2VlZU9PT9QOrdAhIRvQkEgkCg8NQxxYSSKRsG9wvHHjxnv+3IfBcSLMzc2PnzzRxsGB6RfCgnZuZm5+9MRxDI5/ce7MWQyOs15RYWF4GHU9EKZuPVx3p3Zo64AWwwg6DRuu37hh647tenp6sjqHm9cxy5htYblz5w62Hf+n7Kys2NhY2p6enZ3d0WNHLSwsUFPUEAqFm7ZsGeXjw47LiY2JRdrAevD09lJRUaHVKbkMdMVu8rSSnpaWnJyMOMC/unXzJoIAjGBmbn7wyGEk9CZIS0tr157dtF2cKid69up1+OgRNOy/u3TxIoIgD27eoK4HwuDUfFpaWrv27Bnl48OCCXEsxufzhw0fHnjhfM9evWR4GuXl5YmJiaiOf/r48WNOTg5DTz42JhY1+K9inr+g8+kZNGly+NjR3s7OqClpMzU1PXLsKMs2JImNiUHN1qPL5DZ4MK36Bj5s+WbDol8WHqnwTW/evGHu3mjfwmV+jnr4SuvWrfcfPNCwYUOEgiwFBYVZc2avXL1KIBAgGtR3maZOm7Z+4wYE/+9SUlKymL/tD/xQDyQ+vqqqippjMbtbwOPxpk6ftm7DBiR3oqe2bdueCAiYM28uZRsGfUtmZiYmGn9LRkYGQ888k7FnLv06Taf5GSorK69dv27O3LlfchQDcb169zpy/JiRsTHLris9PR2VWw/ePqPo83Pr7eyMnGm0e3Bk4pEK3ySRSD59+sSyi1JSUkLNsonrwIG79+1l30b59NGvf/8TASetbawRCsoYGBj8eWD/qNGYUvC1d1jxJjeqq6s/fPhAzbHY8Nm8Z6+eAWdO29vbo+nQR+PGjTds2rh7314zczM6nE8Jdh7/NlFxMVPPHNX6DcXFzIjMsBHDDx4+1MTQEFVGlqKi4oyZM9dtYOdME/zw60dXV7e/ywA6nAmXyx3jOwY1QjfoKYG83XuVlZWVlZVRsyygoKAwdfq0pcuXKSgoIBpS1dTI6PDRo55eXljBTwHnPn1Onj7VomVLhOKfsPM4+qjSwJJlZfr6+vsO7J8waSKfz0frkS1NLa3pM2cEBl3o0bMnrbpNqJpvYe6vBtXKgjq1sbUNOH2KVjs/MJ2ZufmRY0c9vb1Y27wV8KCvpzG+vnS4bXbp2tXUzAzVQb9HKn5Z8P17Lws7XY0aNULNMp22tvYfu3eNwp5dFL5lzJg1c8fvO3V1dRENKREKhctXrlizbq3MV+ED0KOPSlEPhD3brnG5XP+xYw8cOmRuYY4GJBMCgcB/3NjgiyFe3t502zMB+9CxMjg6DZHb7RuRYVTWO4FAsGjJ4m07tuM19defgyNGjjx24rillRWbmzd++PXVpEmT3s69ZX4aozF5HA8OYCBWJtTFtzqms7e3P3EqwKFtW4SCYk4dOpwJPOc2eDAmkhPXuUuXM4HnBri4IBTfoaWlhSDIUR+VqgErtqUlada82YmAgAmTJmJHOSqpqKh4enkFhQRPmDiRnh85GxsYYDe6f6WoqMjcdwNLSyvU4L+ytmbezoCdOnc+ez7Q3cMD/ez60dPX37Vn96w5s1n/+LOywsaX9TfG10+2P7G2bdu2aNECFUFDFpYWCAJ8i6aWFivnirZq1YpIObq6usYmJmgnVOLz+b9NmbzvwH7MgpIVNTW1RUsW79qz2wAJRcjdaVetWb11+zbMGfpPZuaYFCsvtCjsgbAwbbeCgoL/2LEnT59q3bo1GpO0CQSCUT4+IaGXZsyaSfN5JU4dOqC+/sm+dWvm7r3o1MEJNfgvt3Uez5GZkVFTU1uwaOGfBw9YWlqiHn/qFXGUj8+584Ft27Vj/cWqq6u3smuFSv+F1wmzrt26yvAERvv6ohboqY2DA/Zihm/2uJwcWXldHTp1JFJO9549Tp89M33mDEzHoepZZn742NExvr6YVCFzbdu1OxN4zn/cWDxBfvH1zW3w4MAL5/v264do/AgLCwuse5MTHQk9qX/ol8jWIBobG+87sH/t+nX4niklmpqafv7+F8NCp06f1qBBA/qf8GAPd9TaP7l7eDD4raZjR8wZ+ZdHSMeOjJ7kZWdndzzg5Oy5czQ0NFCb/x0ue7sTAQFTp09TUVGRh+t1cXVFopFf5OvnJ6tD29ratndsjyqgJ1VV1Z69eiEO8K8GDhrEyuuysLCwtiGwJqlr164KCgpe3t5BIcFDhw3Dc0p6VFRUpkydevJUABPXSrKVsrLyhIkTz5w727VbN0SjHlrZ2R09cXzRksWampqIxo8b4IotaOTCYHfqBqx47A5lb2fncxfOT5k6VSgUomGRYmRkNH/hgtDL4RN/m8Sgm7iDg0PHTp1QfX/XslWrnr16Mvf8FRQUxo4bh3r8KiYTJk1i+lXweLzhI0YEXQzx9PKiWzID+tBp2HDp8mX7Dx40M5eX7VM1NDTG+Pmi6n+RbbNm7R1lMxUU1Udz/uPG4pYL/9TGwYHF65PG/PKiFhsbmy/x0dDUnDt/3plzZ/v268fj8dB4yOrarduZc2d9xoxWYGO2WKYzaNJk89Ytv+/6w8oKG2D+qMaNG69cverAoYP43lMPXt7eGOWTh9s+lUuHFVauXMnugCooKNjZ2w0a7MbhcJKSkqqrq9HI6ofL5bZ3dJwxa9bc+fNsmzVj4syIVnZ24aFhVVVVqE0Oh6OkpLRt+/YG2g0YfRW2zWxfvHj+6eMnVGgdXz+/vv36suNalJWVnTo49e/fv6RE9P7d+9raWtRvHaFQ6D927Nr165o1a/aLReXn5YUEBzPlwufOn29nb4cG8Ov09fUvh4dTfFATE5O58+cj+HSmqanJ5/OjnkYhFPCFqqrqtp07WDyr0dTMLC4u7sOHD/X753w+f92G9Xp6el/9lHr07NHLuXdhYWFqaio6ML+ueYvma9at8xk9GjvY0JyhoaH7EA8jY+N3yclFRUUIyLfo6OhMnjJl+aqVVhgZry+BQKDVQOvB/QcIBYvfebft3EFlgkOuXD2wCwoKTp44EXwhqLy8HK3tp96XXAa6egwZYmhoyPRreRYdPXvmrIqKCjmv07refLfu3VlwLUVFReP9x6anp+On2r1Hjw2bNrJyK8aUlJRDBw7euX27pqZGnqtYSUlpyNChvv5+pIYq3iYl+XiPYsS1+4wePWXaVPzMSZkwbnxcbCyVR1y+csUAF6yEZYAVy5Zfu3oVcYC67uKmrVs6sX39ZV5e3jg//0+f6jPZYs68ecOGD/vOH6SnpZ05febK5ct4+6gfKysrX39/Ri94lU8SiSQ8LOz4seMf6/vxia00tbQ8vTxHenrKydaI0rZ969bAc4GIA/uoqKjs/ON3e2qTSnLl8IN2fn7+hfPngy8EFRYWotl9B4/Ha9uunYurS4+ePZWUlFhzXREREcsWLxGLxXJbs0pKSkuWLWVT9o/8/Pw5s2a/iY+X5x+s68CBi5YsZveC07S0tBPHjl27ek0OVwKpqKgMchvk7ePz1SS1X8SU8XFPb68ZM2fiuUzQo4hHsykMqb6+ftDFEKyIZ4Ta2totmzYFBwUjFHJOKBSuXruWyrxYMpSRkTF9ytSfGiLn8Xhz5s0dMnToj/xxQUHB+cDAkKDggoICNK0f1KJFC19/v85duiAUzFVTU3Pzxs1TAScTExIRDX19fU9vr8Hu7shlStbePXtOHj+BlTpsoqamtm7DeqcOHSg+Lldum1FFRcWVy1fOnTmTmpqK9vcVMzOz/gMG9BvQv1GjRuzsBKenb9qwMTo6Wg4rt5Wd3cJFi9i3YbFEIjl04ODpU6fkcHqOjo7OlGnTBrgMkJPrzc7OPnf2bOjFSyUlJfJwvdra2kOHDxs6bJg0EpbSf3xcX19/9tw5yPgkDaNH+SQlUvS++p9TLIFubt648cfO33NychAK+eTk5LRg0cLGBgbyc8mFhYVrVq2KeBjxI39sZGS0ZPkyO7uf2/JLIpHcuX07JDj4+bPnGMr5FkVFxZ69eg0fOaJ58+aIBms8ffL0zOnTTx4/ls+VoLa2tiO9PJ379EFaAimJePhwy6bNWVlZCAV6IL+Ci2fzs2fPQi9eunvnDla9mZmZ9ezVq0evnubm5nJS9SFBwY8iIuRhLrmKiopThw7uQzwcZZSWjRqfP38ODgq6ce16ZmYm6+uUy+Xa2Nq6uLq4Dhwohwv0SktLr4RfDrpwgcXfOK1trD2GDBng4iK9jHm0HR9XUFBo0bKFq+vAfgP6I2GglNy+dXvxwoUUHEhbWzsk9BJmSzFO3VSSy2Fh8fHxcr63lfwQCoWdOnd2H+Jhb28vnxG4d/fu0cNHEhISvvUH+vr63qNGeQwd8isLYjIyMi6HhV+7erV+m7qwlZGx8QCXAYPc3LS1tRENVvr08ePFkIthoaH5+fnycL0CgaBP377uQzxsbGxQ+9JWVVX115UrYZdCX79+jU4LE6mrq3fp2sXdw6Nlq1ayOgeMj/9PaWnptatXr4Rffv36tVzFhMfj2Taz7dy5S49ePU1MTOTzThofH/8uOfld8rvPnz+LxeKyMjHTd6hXUlJWU1NTVVXV0dExtzC3tLKytbVl0yY5/ykzMzMpMfH9u/epqaklIpG4rKy8rExSI2HuFSnwFFRVVdWEakKh0NTUzMLSwrZZMx0dHdy9Xzx/Hnop9M7t26xJLCEUCvv17z/Izc3K2krax0pLS6NmhPT7FPmKAlVVVVWBtraOubm5mbm5bTNb5OCiwIxp03Jzc6V9lMGD3YeNGI5oM1dBQUF8fHzy27cp71NEomKxuEwsLkXGe6bjcrjKKsoCgaqamqq+fmMzczMLS0sbGxvsg8ThcNLT0iIjIxPeJBTk5xcWFiopK2tra1taWrZu06aNQxuCB4qJibn219Xbt28XyfG2n9ra2t179nBxdcWEcTlRXV195/ada1evPo6MZOWjhMvltmzVql//fn379aMytSB86bS8fvUq5X1KWlpaQUG+WFxWJhZXVVchMvTsgTQxNDQzM7OwsLCytpb5AguMj38tJzv79q3bt27efPXqFYuDo6Gh0d7RsVPnzh07dWRxSnoAkBNisfjWzVs3rl9/Fh0tkTDyQ4iiomLbdu2c+/Tp1bsXZtoCAADIiZqamri4uIf3H9y/d09+Es7r6el179Gje4/u9q1bszK3PPyn4qKiW7duX792LTYmhh0Tfi0tLfv07evct4++vj7qF4BxMD7+TTk5OREPIx5HRj6LjmbHLrdCodC+des2Dm3atm1HwbREAADqFRQU3L1z9/69e8+ioysrK+l/wgKBoGOnjl27devcpQvmmAAAAMiz9LS0J4+fREVFPX/2jH15VlRUVOzt7ds7OXbo0MHUzAzVDV9675GPHj2KePQ4MpJxzZ7P59u3bt2la5euXbvKVc4GAPbB+Ph/k0gkcbGx0VHRsbGxr1+9KisrY8qZ83g8ExOTZs2bN2/RokXLFhYWFvg4DwByory8/OmTJ0+fPH3y+HFGRgatzk1BQcHK2trBwcGhrUMbBwfMFgcAAIC/q6mpiY+Pj4uNff3q1cu4l8xNlquppWVnZ9fKrpW9vb2NrS2fz0flwrdIJJLYmNjnz569ePH81ctXtM0Px+PxzM3NW7dp3bpNm/aOjpjgAsAOGB//6Vv227dvX8bGxcfHJyUlpqWm0WrPLBUVFVMzMysrK0srSwtLS0tLS9ysAQCysrJePH8R8+LFy7i41NRUmSzhVFNTs7S0tG3WrG73UqFQiHoBAACAH5GTnf369eu3b98mJSYlv32bnZ1Nz7d4Lperq6tramZma2trZW1lY2ODGbVQP1VVVa9evoyLi0tKTExISPz44YNs27ymlpatjY21jU2Lli3sW7dGmhwA9sH4+K/etd+9e5f89m1aWlpmRmZmRkZmZiY1E8w1NTV1aGNVBgAABE5JREFUdXX19PSaGhk1NWpqaNjUyNgIG10BAHxfeXl5QkLC28Sk5OTk5OS3aalp0ljIqaio2NjAoGlTQxMTU2sbGxsbayNjYwQfAAAAfl1JSUlqSkpGRmZGRnp6WnpmRkZOTk5BQQGVr/Z8Pl9XV7exQePGjQ0aN25s2NTQ2MTE2NhYIBCggoC44uLipMTEd+/epaWlpaelZ6Sn5+TkSK/Bq6urGxkbGRkZGxsbm5iaWFtb40sPAOthfJy8/Ly8nM+fcz9//vw5Nz8vLzc3VyQSlf5PSUlJaUV5efXfcDgcHo+noKCgqKioqKjI5/NVBAJVgUCgqqoqEKiqqWlqajbQbtBAq4GmllaDBlqNdHX19PTQ8wAAIEIkEmVmZHz69CknOyc7Jzs/L7+osLCwsFBUUlImFpeVlVVXV0skkpqaGi6Xq6SkVHejVlZWVlJS0tDU0NLS0tLS0tTS0tTU1NbWMWhi0NTQUFdPD4EFAAAAylRVVeXk5GRlZeXl5hUVFhYV1XVnCktEInFZWZlYXPeflZWVdR2bur5N3b+textVUFDg8/nKKnWUVVRUBAJVTU0NoVBdXV1dqC5s0KBBw0aNdHR0GjVqpK2tja07QYbKy8uzsrLqRl1ycrJzP+cWFRWKRCUlIlHd8EtlZaVEIqmqqqqqqqrrxvP5/C9DLqqqqkL1OkJ1dY2GDRs20m3UsFGjRg0b6enraWpqIsIA8gbj4wAAAAAAAAAAwEK1tbX4nAMA34fxcQAAAAAAAAAAAACQRzyEAAAAAAAAAAAAAADkEMbHAQAAAAAAAAAAAEAeYXwcAAAAAAAAAAAAAOQRxscBAAAAAAAAAAAAQB5hfBwAAAAAAAAAAAAA5BHGxwEAAAAAAAAAAABAHmF8HAAAAAAAAAAAAADkEcbHAQAAAAAAAAAAAEAeYXwcAAAAAAAAAAAAAOQRxscBAAAAAAAAAAAAQB5hfBwAAAAAAAAAAAAA5BHGxwEAAAAAAAAAAABAHmF8HAAAAAAAAAAAAADkEcbHAQAAAAAAAAAAAEAeYXwcAAAAAAAAAAAAAOQRxscBAAAAAAAAAAAAQB5hfBwAAAAAAAAAAAAA5BHGxwEAAAAAAAAAAABAHmF8HAAAAAAAAAAAAADkEcbHAQAAAAAAAAAAAEAeYXwcAAAAAAAAAAAAAOQRxscBAAAAAAAAAAAAQB5hfBwAAAAAAAAAAAAA5BHGxwEAAAAAAAAAAABAHmF8HAAAAAAAAAAAAADkEcbHAQAAAAAAAAAAAEAeYXwcAAAAAAAAAAAAAOQRxscBAAAAAAAAAAAAQB5hfBwAAAAAAAAAAAAA5BHGxwEAAAAAAAAAAABAHmF8HAAAAAAAAAAAAADkEcbHAQAAAAAAAAAAAEAeYXwcAAAAAAAAAAAAAOQRxscBAAAAAAAAAAAAQB5hfBwAAAAAAAAAAAAA5BHGxwEAAAAAAAAAAABAHv0fr+hlXOtHm2kAAAAASUVORK5CYII=\");\n}\n.breadcrumb>li+li:before{content:\"/\\00a0\";padding:0 5px;color:#ccc;}"
  },
  {
    "path": "cmd/internal/pages/containers.go",
    "content": "// Copyright 2014 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n// Page for /containers/\npackage pages\n\nimport (\n\t\"fmt\"\n\t\"html/template\"\n\t\"net/http\"\n\t\"net/url\"\n\t\"path\"\n\t\"strconv\"\n\t\"strings\"\n\t\"time\"\n\n\tinfo \"github.com/google/cadvisor/info/v1\"\n\t\"github.com/google/cadvisor/manager\"\n\n\t\"k8s.io/klog/v2\"\n)\n\nconst ContainersPage = \"/containers/\"\n\n// from http://golang.org/doc/effective_go.html#constants\ntype ByteSize float64\n\nconst (\n\t_ = iota\n\t// KB - kilobyte\n\tKB ByteSize = 1 << (10 * iota)\n\t// MB - megabyte\n\tMB\n\t// GB - gigabyte\n\tGB\n\t// TB - terabyte\n\tTB\n\t// PB - petabyte\n\tPB\n\t// EB - exabyte\n\tEB\n\t// ZB - zettabyte\n\tZB\n\t// YB - yottabyte\n\tYB\n)\n\nfunc (b ByteSize) Size() string {\n\tfor _, i := range [...]ByteSize{YB, ZB, EB, PB, TB, GB, MB, KB} {\n\t\tif b >= i {\n\t\t\treturn fmt.Sprintf(\"%.2f\", b/i)\n\t\t}\n\t}\n\treturn fmt.Sprintf(\"%.2f\", b)\n}\n\nfunc (b ByteSize) Unit() string {\n\tswitch {\n\tcase b >= YB:\n\t\treturn \"YB\"\n\tcase b >= ZB:\n\t\treturn \"ZB\"\n\tcase b >= EB:\n\t\treturn \"EB\"\n\tcase b >= PB:\n\t\treturn \"PB\"\n\tcase b >= TB:\n\t\treturn \"TB\"\n\tcase b >= GB:\n\t\treturn \"GB\"\n\tcase b >= MB:\n\t\treturn \"MB\"\n\tcase b >= KB:\n\t\treturn \"KB\"\n\t}\n\treturn \"B\"\n}\n\nvar funcMap = template.FuncMap{\n\t\"printMask\":   printMask,\n\t\"printCores\":  printCores,\n\t\"printShares\": printShares,\n\t\"printSize\":   printSize,\n\t\"printUnit\":   printUnit,\n}\n\nfunc printMask(mask string, numCores int) interface{} {\n\tmasks := make([]string, numCores)\n\tactiveCores := getActiveCores(mask)\n\tfor i := 0; i < numCores; i++ {\n\t\tcoreClass := \"inactive-cpu\"\n\t\tif activeCores[i] {\n\t\t\tcoreClass = \"active-cpu\"\n\t\t}\n\t\tmasks[i] = fmt.Sprintf(\"<span class=\\\"%s\\\">%d</span>\", coreClass, i)\n\t}\n\treturn template.HTML(strings.Join(masks, \"&nbsp;\"))\n}\n\nfunc getActiveCores(mask string) map[int]bool {\n\tactiveCores := make(map[int]bool)\n\tfor _, corebits := range strings.Split(mask, \",\") {\n\t\tcores := strings.Split(corebits, \"-\")\n\t\tif len(cores) == 1 {\n\t\t\tindex, err := strconv.Atoi(cores[0])\n\t\t\tif err != nil {\n\t\t\t\t// Ignore malformed strings.\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tactiveCores[index] = true\n\t\t} else if len(cores) == 2 {\n\t\t\tstart, err := strconv.Atoi(cores[0])\n\t\t\tif err != nil {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tend, err := strconv.Atoi(cores[1])\n\t\t\tif err != nil {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tfor i := start; i <= end; i++ {\n\t\t\t\tactiveCores[i] = true\n\t\t\t}\n\t\t}\n\t}\n\treturn activeCores\n}\n\nfunc printCores(millicores *uint64) string {\n\tcores := float64(*millicores) / 1000\n\treturn strconv.FormatFloat(cores, 'f', 3, 64)\n}\n\nfunc printShares(shares *uint64) string {\n\treturn fmt.Sprintf(\"%d\", *shares)\n}\n\n// Size after which we consider memory to be \"unlimited\". This is not\n// MaxInt64 due to rounding by the kernel.\nconst maxMemorySize = uint64(1 << 62)\n\nfunc printSize(bytes uint64) string {\n\tif bytes >= maxMemorySize {\n\t\treturn \"unlimited\"\n\t}\n\treturn ByteSize(bytes).Size()\n}\n\nfunc printUnit(bytes uint64) string {\n\tif bytes >= maxMemorySize {\n\t\treturn \"\"\n\t}\n\treturn ByteSize(bytes).Unit()\n}\n\nfunc serveContainersPage(m manager.Manager, w http.ResponseWriter, u *url.URL) {\n\tstart := time.Now()\n\n\t// The container name is the path after the handler\n\tcontainerName := u.Path[len(ContainersPage)-1:]\n\n\t// Get the container.\n\treqParams := info.ContainerInfoRequest{\n\t\tNumStats: 60,\n\t}\n\tcont, err := m.GetContainerInfo(containerName, &reqParams)\n\tif err != nil {\n\t\thttp.Error(w, fmt.Sprintf(\"failed to get container %q with error: %v\", containerName, err), http.StatusNotFound)\n\t\treturn\n\t}\n\tdisplayName := getContainerDisplayName(cont.ContainerReference)\n\n\t// Get the MachineInfo\n\tmachineInfo, err := m.GetMachineInfo()\n\tif err != nil {\n\t\thttp.Error(w, fmt.Sprintf(\"failed to get machine info: %v\", err), http.StatusInternalServerError)\n\t\treturn\n\t}\n\n\trootDir := getRootDir(containerName)\n\n\t// Make a list of the parent containers and their links\n\tpathParts := strings.Split(string(cont.Name), \"/\")\n\tparentContainers := make([]link, 0, len(pathParts))\n\tparentContainers = append(parentContainers, link{\n\t\tText: \"root\",\n\t\tLink: path.Join(rootDir, ContainersPage),\n\t})\n\tfor i := 1; i < len(pathParts); i++ {\n\t\t// Skip empty parts.\n\t\tif pathParts[i] == \"\" {\n\t\t\tcontinue\n\t\t}\n\t\tparentContainers = append(parentContainers, link{\n\t\t\tText: pathParts[i],\n\t\t\tLink: path.Join(rootDir, ContainersPage, path.Join(pathParts[1:i+1]...)),\n\t\t})\n\t}\n\n\t// Build the links for the subcontainers.\n\tsubcontainerLinks := make([]link, 0, len(cont.Subcontainers))\n\tfor _, sub := range cont.Subcontainers {\n\t\tif !m.Exists(sub.Name) {\n\t\t\tcontinue\n\t\t}\n\t\tsubcontainerLinks = append(subcontainerLinks, link{\n\t\t\tText: getContainerDisplayName(sub),\n\t\t\tLink: path.Join(rootDir, ContainersPage, sub.Name),\n\t\t})\n\t}\n\n\tdata := &pageData{\n\t\tDisplayName:            displayName,\n\t\tContainerName:          escapeContainerName(cont.Name),\n\t\tParentContainers:       parentContainers,\n\t\tSubcontainers:          subcontainerLinks,\n\t\tSpec:                   cont.Spec,\n\t\tStats:                  cont.Stats,\n\t\tMachineInfo:            machineInfo,\n\t\tIsRoot:                 cont.Name == \"/\",\n\t\tResourcesAvailable:     cont.Spec.HasCpu || cont.Spec.HasMemory || cont.Spec.HasNetwork || cont.Spec.HasFilesystem,\n\t\tCpuAvailable:           cont.Spec.HasCpu,\n\t\tMemoryAvailable:        cont.Spec.HasMemory,\n\t\tNetworkAvailable:       cont.Spec.HasNetwork,\n\t\tFsAvailable:            cont.Spec.HasFilesystem,\n\t\tCustomMetricsAvailable: cont.Spec.HasCustomMetrics,\n\t\tSubcontainersAvailable: len(subcontainerLinks) > 0,\n\t\tRoot:                   rootDir,\n\t}\n\terr = pageTemplate.Execute(w, data)\n\tif err != nil {\n\t\tklog.Errorf(\"Failed to apply template: %s\", err)\n\t}\n\n\tklog.V(5).Infof(\"Request took %s\", time.Since(start))\n}\n\n// Build a relative path to the root of the container page.\nfunc getRootDir(containerName string) string {\n\t// The root is at: container depth\n\tlevels := (strings.Count(containerName, \"/\"))\n\treturn strings.Repeat(\"../\", levels)\n}\n"
  },
  {
    "path": "cmd/internal/pages/docker.go",
    "content": "// Copyright 2014 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n//go:build linux\n\npackage pages\n\nimport (\n\t\"fmt\"\n\t\"net/http\"\n\t\"net/url\"\n\t\"path\"\n\t\"strconv\"\n\t\"time\"\n\n\t\"github.com/google/cadvisor/container/docker\"\n\tdockerutil \"github.com/google/cadvisor/container/docker/utils\"\n\tinfo \"github.com/google/cadvisor/info/v1\"\n\t\"github.com/google/cadvisor/manager\"\n\n\t\"k8s.io/klog/v2\"\n)\n\nconst DockerPage = \"/docker/\"\n\nfunc toStatusKV(status info.DockerStatus) ([]keyVal, []keyVal) {\n\tds := []keyVal{\n\t\t{Key: \"Driver\", Value: status.Driver},\n\t}\n\tfor k, v := range status.DriverStatus {\n\t\tds = append(ds, keyVal{Key: k, Value: v})\n\t}\n\treturn []keyVal{\n\t\t{Key: \"Version\", Value: status.Version},\n\t\t{Key: \"API Version\", Value: status.APIVersion},\n\t\t{Key: \"Kernel Version\", Value: status.KernelVersion},\n\t\t{Key: \"OS Version\", Value: status.OS},\n\t\t{Key: \"Host Name\", Value: status.Hostname},\n\t\t{Key: \"Root Directory\", Value: status.RootDir},\n\t\t{Key: \"Execution  Driver\", Value: status.ExecDriver},\n\t\t{Key: \"Number of Images\", Value: strconv.Itoa(status.NumImages)},\n\t\t{Key: \"Number of Containers\", Value: strconv.Itoa(status.NumContainers)},\n\t}, ds\n}\n\nfunc serveDockerPage(m manager.Manager, w http.ResponseWriter, u *url.URL) {\n\tstart := time.Now()\n\n\t// The container name is the path after the handler\n\tcontainerName := u.Path[len(DockerPage)-1:]\n\trootDir := getRootDir(containerName)\n\n\tvar data *pageData\n\tif containerName == \"/\" {\n\t\t// Get the containers.\n\t\treqParams := info.ContainerInfoRequest{\n\t\t\tNumStats: 0,\n\t\t}\n\t\tconts, err := m.AllDockerContainers(&reqParams)\n\t\tif err != nil {\n\t\t\thttp.Error(w, fmt.Sprintf(\"failed to get container %q with error: %v\", containerName, err), http.StatusNotFound)\n\t\t\treturn\n\t\t}\n\t\tsubcontainers := make([]link, 0, len(conts))\n\t\tfor _, cont := range conts {\n\t\t\tsubcontainers = append(subcontainers, link{\n\t\t\t\tText: getContainerDisplayName(cont.ContainerReference),\n\t\t\t\tLink: path.Join(rootDir, DockerPage, dockerutil.ContainerNameToId(cont.ContainerReference.Name)),\n\t\t\t})\n\t\t}\n\n\t\t// Get Docker status\n\t\tstatus, err := docker.Status()\n\t\tif err != nil {\n\t\t\thttp.Error(w, fmt.Sprintf(\"failed to get docker info: %v\", err), http.StatusInternalServerError)\n\t\t\treturn\n\t\t}\n\n\t\tdockerStatus, driverStatus := toStatusKV(status)\n\t\t// Get Docker Images\n\t\timages, err := docker.Images()\n\t\tif err != nil {\n\t\t\thttp.Error(w, fmt.Sprintf(\"failed to get docker images: %v\", err), http.StatusInternalServerError)\n\t\t\treturn\n\t\t}\n\n\t\tdockerContainersText := \"Docker Containers\"\n\t\tdata = &pageData{\n\t\t\tDisplayName: dockerContainersText,\n\t\t\tParentContainers: []link{\n\t\t\t\t{\n\t\t\t\t\tText: dockerContainersText,\n\t\t\t\t\tLink: path.Join(rootDir, DockerPage),\n\t\t\t\t}},\n\t\t\tSubcontainers:      subcontainers,\n\t\t\tRoot:               rootDir,\n\t\t\tDockerStatus:       dockerStatus,\n\t\t\tDockerDriverStatus: driverStatus,\n\t\t\tDockerImages:       images,\n\t\t}\n\t} else {\n\t\t// Get the container.\n\t\treqParams := info.ContainerInfoRequest{\n\t\t\tNumStats: 60,\n\t\t}\n\t\tcont, err := m.DockerContainer(containerName[1:], &reqParams)\n\t\tif err != nil {\n\t\t\thttp.Error(w, fmt.Sprintf(\"failed to get container %q with error: %v\", containerName, err), http.StatusNotFound)\n\t\t\treturn\n\t\t}\n\t\tdisplayName := getContainerDisplayName(cont.ContainerReference)\n\n\t\t// Make a list of the parent containers and their links\n\t\tvar parentContainers []link\n\t\tparentContainers = append(parentContainers, link{\n\t\t\tText: \"Docker Containers\",\n\t\t\tLink: path.Join(rootDir, DockerPage),\n\t\t})\n\t\tparentContainers = append(parentContainers, link{\n\t\t\tText: displayName,\n\t\t\tLink: path.Join(rootDir, DockerPage, dockerutil.ContainerNameToId(cont.Name)),\n\t\t})\n\n\t\t// Get the MachineInfo\n\t\tmachineInfo, err := m.GetMachineInfo()\n\t\tif err != nil {\n\t\t\thttp.Error(w, fmt.Sprintf(\"failed to get machine info: %v\", err), http.StatusInternalServerError)\n\t\t\treturn\n\t\t}\n\t\tdata = &pageData{\n\t\t\tDisplayName:            displayName,\n\t\t\tContainerName:          escapeContainerName(cont.Name),\n\t\t\tParentContainers:       parentContainers,\n\t\t\tSpec:                   cont.Spec,\n\t\t\tStats:                  cont.Stats,\n\t\t\tMachineInfo:            machineInfo,\n\t\t\tResourcesAvailable:     cont.Spec.HasCpu || cont.Spec.HasMemory || cont.Spec.HasNetwork,\n\t\t\tCpuAvailable:           cont.Spec.HasCpu,\n\t\t\tMemoryAvailable:        cont.Spec.HasMemory,\n\t\t\tNetworkAvailable:       cont.Spec.HasNetwork,\n\t\t\tFsAvailable:            cont.Spec.HasFilesystem,\n\t\t\tCustomMetricsAvailable: cont.Spec.HasCustomMetrics,\n\t\t\tRoot:                   rootDir,\n\t\t}\n\t}\n\n\terr := pageTemplate.Execute(w, data)\n\tif err != nil {\n\t\tklog.Errorf(\"Failed to apply template: %s\", err)\n\t}\n\n\tklog.V(5).Infof(\"Request took %s\", time.Since(start))\n}\n"
  },
  {
    "path": "cmd/internal/pages/pages.go",
    "content": "// Copyright 2014 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage pages\n\nimport (\n\t\"fmt\"\n\t\"html/template\"\n\t\"net/http\"\n\t\"net/url\"\n\t\"strings\"\n\n\thttpmux \"github.com/google/cadvisor/cmd/internal/http/mux\"\n\tinfo \"github.com/google/cadvisor/info/v1\"\n\t\"github.com/google/cadvisor/manager\"\n\n\tauth \"github.com/abbot/go-http-auth\"\n\t\"k8s.io/klog/v2\"\n)\n\nvar pageTemplate *template.Template\n\ntype link struct {\n\t// Text to show in the link.\n\tText string\n\n\t// Web address to link to.\n\tLink string\n}\n\ntype keyVal struct {\n\tKey   string\n\tValue string\n}\n\ntype pageData struct {\n\tDisplayName            string\n\tContainerName          string\n\tParentContainers       []link\n\tSubcontainers          []link\n\tSpec                   info.ContainerSpec\n\tStats                  []*info.ContainerStats\n\tMachineInfo            *info.MachineInfo\n\tIsRoot                 bool\n\tResourcesAvailable     bool\n\tCpuAvailable           bool\n\tMemoryAvailable        bool\n\tNetworkAvailable       bool\n\tFsAvailable            bool\n\tCustomMetricsAvailable bool\n\tSubcontainersAvailable bool\n\tRoot                   string\n\tDockerStatus           []keyVal\n\tDockerDriverStatus     []keyVal\n\tDockerImages           []info.DockerImage\n}\n\nfunc init() {\n\tcontainersHTMLTemplate, _ := Asset(\"cmd/internal/pages/assets/html/containers.html\")\n\tpageTemplate = template.New(\"containersTemplate\").Funcs(funcMap)\n\t_, err := pageTemplate.Parse(string(containersHTMLTemplate))\n\tif err != nil {\n\t\tklog.Fatalf(\"Failed to parse template: %s\", err)\n\t}\n}\n\nfunc containerHandlerNoAuth(containerManager manager.Manager) http.HandlerFunc {\n\treturn func(w http.ResponseWriter, r *http.Request) {\n\t\tserveContainersPage(containerManager, w, r.URL)\n\t}\n}\n\nfunc containerHandler(containerManager manager.Manager) auth.AuthenticatedHandlerFunc {\n\treturn func(w http.ResponseWriter, r *auth.AuthenticatedRequest) {\n\t\tserveContainersPage(containerManager, w, r.URL)\n\t}\n}\n\nfunc dockerHandlerNoAuth(containerManager manager.Manager) http.HandlerFunc {\n\treturn func(w http.ResponseWriter, r *http.Request) {\n\t\tserveDockerPage(containerManager, w, r.URL)\n\t}\n}\n\nfunc dockerHandler(containerManager manager.Manager) auth.AuthenticatedHandlerFunc {\n\treturn func(w http.ResponseWriter, r *auth.AuthenticatedRequest) {\n\t\tserveDockerPage(containerManager, w, r.URL)\n\t}\n}\n\nfunc podmanHandlerNoAuth(containerManager manager.Manager) http.HandlerFunc {\n\treturn func(w http.ResponseWriter, r *http.Request) {\n\t\tservePodmanPage(containerManager, w, r.URL)\n\t}\n}\n\nfunc podmanHandler(containerManager manager.Manager) auth.AuthenticatedHandlerFunc {\n\treturn func(w http.ResponseWriter, r *auth.AuthenticatedRequest) {\n\t\tservePodmanPage(containerManager, w, r.URL)\n\t}\n}\n\n// Register http handlers\nfunc RegisterHandlersDigest(mux httpmux.Mux, containerManager manager.Manager, authenticator *auth.DigestAuth, urlBasePrefix string) error {\n\t// Register the handler for the containers page.\n\tif authenticator != nil {\n\t\tmux.HandleFunc(ContainersPage, authenticator.Wrap(containerHandler(containerManager)))\n\t\tmux.HandleFunc(DockerPage, authenticator.Wrap(dockerHandler(containerManager)))\n\t\tmux.HandleFunc(PodmanPage, authenticator.Wrap(podmanHandler(containerManager)))\n\t} else {\n\t\tmux.HandleFunc(ContainersPage, containerHandlerNoAuth(containerManager))\n\t\tmux.HandleFunc(DockerPage, dockerHandlerNoAuth(containerManager))\n\t\tmux.HandleFunc(PodmanPage, podmanHandlerNoAuth(containerManager))\n\t}\n\n\tif ContainersPage[len(ContainersPage)-1] == '/' {\n\t\tredirectHandler := http.RedirectHandler(urlBasePrefix+ContainersPage, http.StatusMovedPermanently)\n\t\tmux.Handle(ContainersPage[0:len(ContainersPage)-1], redirectHandler)\n\t}\n\tif DockerPage[len(DockerPage)-1] == '/' {\n\t\tredirectHandler := http.RedirectHandler(urlBasePrefix+DockerPage, http.StatusMovedPermanently)\n\t\tmux.Handle(DockerPage[0:len(DockerPage)-1], redirectHandler)\n\t}\n\tif PodmanPage[len(PodmanPage)-1] == '/' {\n\t\tredirectHandler := http.RedirectHandler(urlBasePrefix+PodmanPage, http.StatusMovedPermanently)\n\t\tmux.Handle(PodmanPage[0:len(PodmanPage)-1], redirectHandler)\n\t}\n\n\treturn nil\n}\n\nfunc RegisterHandlersBasic(mux httpmux.Mux, containerManager manager.Manager, authenticator *auth.BasicAuth, urlBasePrefix string) error {\n\t// Register the handler for the containers and docker age.\n\tif authenticator != nil {\n\t\tmux.HandleFunc(ContainersPage, authenticator.Wrap(containerHandler(containerManager)))\n\t\tmux.HandleFunc(DockerPage, authenticator.Wrap(dockerHandler(containerManager)))\n\t\tmux.HandleFunc(PodmanPage, authenticator.Wrap(podmanHandler(containerManager)))\n\t} else {\n\t\tmux.HandleFunc(ContainersPage, containerHandlerNoAuth(containerManager))\n\t\tmux.HandleFunc(DockerPage, dockerHandlerNoAuth(containerManager))\n\t\tmux.HandleFunc(PodmanPage, podmanHandlerNoAuth(containerManager))\n\t}\n\n\tif ContainersPage[len(ContainersPage)-1] == '/' {\n\t\tredirectHandler := http.RedirectHandler(urlBasePrefix+ContainersPage, http.StatusMovedPermanently)\n\t\tmux.Handle(ContainersPage[0:len(ContainersPage)-1], redirectHandler)\n\t}\n\tif DockerPage[len(DockerPage)-1] == '/' {\n\t\tredirectHandler := http.RedirectHandler(urlBasePrefix+DockerPage, http.StatusMovedPermanently)\n\t\tmux.Handle(DockerPage[0:len(DockerPage)-1], redirectHandler)\n\t}\n\n\treturn nil\n}\n\nfunc getContainerDisplayName(cont info.ContainerReference) string {\n\t// Pick a user-added alias as display name.\n\tdisplayName := \"\"\n\tfor _, alias := range cont.Aliases {\n\t\t// ignore container id as alias.\n\t\tif strings.Contains(cont.Name, alias) {\n\t\t\tcontinue\n\t\t}\n\t\t// pick shortest display name if multiple aliases are available.\n\t\tif displayName == \"\" || len(displayName) >= len(alias) {\n\t\t\tdisplayName = alias\n\t\t}\n\t}\n\n\tif displayName == \"\" {\n\t\tdisplayName = cont.Name\n\t} else if len(displayName) > 50 {\n\t\t// truncate display name to fit in one line.\n\t\tdisplayName = displayName[:50] + \"...\"\n\t}\n\n\t// Add the full container name to the display name.\n\tif displayName != cont.Name {\n\t\tdisplayName = fmt.Sprintf(\"%s (%s)\", displayName, cont.Name)\n\t}\n\n\treturn displayName\n}\n\n// Escape the non-path characters on a container name.\nfunc escapeContainerName(containerName string) string {\n\tparts := strings.Split(containerName, \"/\")\n\tfor i := range parts {\n\t\tparts[i] = url.QueryEscape(parts[i])\n\t}\n\treturn strings.Join(parts, \"/\")\n}\n"
  },
  {
    "path": "cmd/internal/pages/podman.go",
    "content": "// Copyright 2021 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage pages\n\nimport (\n\t\"fmt\"\n\t\"net/http\"\n\t\"net/url\"\n\t\"path\"\n\t\"time\"\n\n\tdockerutil \"github.com/google/cadvisor/container/docker/utils\"\n\t\"github.com/google/cadvisor/container/podman\"\n\tinfo \"github.com/google/cadvisor/info/v1\"\n\t\"github.com/google/cadvisor/manager\"\n\n\t\"k8s.io/klog/v2\"\n)\n\nconst PodmanPage = \"/podman/\"\n\nfunc servePodmanPage(m manager.Manager, w http.ResponseWriter, u *url.URL) {\n\tstart := time.Now()\n\n\tcontainerName := u.Path[len(PodmanPage)-1:]\n\trootDir := getRootDir(containerName)\n\n\tvar data *pageData\n\n\tif containerName == \"/\" {\n\t\t// Scenario for all containers.\n\t\tstatus, err := podman.Status()\n\t\tif err != nil {\n\t\t\thttp.Error(w, fmt.Sprintf(\"failed to get podman info: %v\", err), http.StatusInternalServerError)\n\t\t\treturn\n\t\t}\n\t\timages, err := podman.Images()\n\t\tif err != nil {\n\t\t\thttp.Error(w, fmt.Sprintf(\"failed to get podman images: %v\", err), http.StatusInternalServerError)\n\t\t\treturn\n\t\t}\n\n\t\treqParams := info.ContainerInfoRequest{\n\t\t\tNumStats: 0,\n\t\t}\n\t\tconts, err := m.AllPodmanContainers(&reqParams)\n\t\tif err != nil {\n\t\t\thttp.Error(w, fmt.Sprintf(\"failed to get container %q with error: %v\", containerName, err), http.StatusNotFound)\n\t\t\treturn\n\t\t}\n\t\tsubcontainers := make([]link, 0, len(conts))\n\t\tfor _, cont := range conts {\n\t\t\tsubcontainers = append(subcontainers, link{\n\t\t\t\tText: getContainerDisplayName(cont.ContainerReference),\n\t\t\t\tLink: path.Join(rootDir, PodmanPage, dockerutil.ContainerNameToId(cont.ContainerReference.Name)),\n\t\t\t})\n\t\t}\n\n\t\tpodmanStatus, driverStatus := toStatusKV(status)\n\n\t\tpodmanContainerText := \"Podman Containers\"\n\t\tdata = &pageData{\n\t\t\tDisplayName: podmanContainerText,\n\t\t\tParentContainers: []link{\n\t\t\t\t{\n\t\t\t\t\tText: podmanContainerText,\n\t\t\t\t\tLink: path.Join(rootDir, PodmanPage),\n\t\t\t\t}},\n\t\t\tSubcontainers:      subcontainers,\n\t\t\tRoot:               rootDir,\n\t\t\tDockerStatus:       podmanStatus,\n\t\t\tDockerDriverStatus: driverStatus,\n\t\t\tDockerImages:       images,\n\t\t}\n\t} else {\n\t\t// Scenario for specific container.\n\t\tmachineInfo, err := m.GetMachineInfo()\n\t\tif err != nil {\n\t\t\thttp.Error(w, fmt.Sprintf(\"failed to get machine info: %v\", err), http.StatusInternalServerError)\n\t\t\treturn\n\t\t}\n\n\t\treqParams := info.ContainerInfoRequest{\n\t\t\tNumStats: 60,\n\t\t}\n\t\tcont, err := m.PodmanContainer(containerName[1:], &reqParams)\n\t\tif err != nil {\n\t\t\thttp.Error(w, fmt.Sprintf(\"failed to get container %v with error: %v\", containerName, err), http.StatusNotFound)\n\t\t\treturn\n\t\t}\n\t\tdisplayName := getContainerDisplayName(cont.ContainerReference)\n\n\t\tvar parentContainers []link\n\t\tparentContainers = append(parentContainers, link{\n\t\t\tText: \"Podman Containers\",\n\t\t\tLink: path.Join(rootDir, PodmanPage),\n\t\t})\n\t\tparentContainers = append(parentContainers, link{\n\t\t\tText: displayName,\n\t\t\tLink: path.Join(rootDir, PodmanPage, dockerutil.ContainerNameToId(cont.Name)),\n\t\t})\n\n\t\tdata = &pageData{\n\t\t\tDisplayName:            displayName,\n\t\t\tContainerName:          escapeContainerName(cont.Name),\n\t\t\tParentContainers:       parentContainers,\n\t\t\tSpec:                   cont.Spec,\n\t\t\tStats:                  cont.Stats,\n\t\t\tMachineInfo:            machineInfo,\n\t\t\tResourcesAvailable:     cont.Spec.HasCpu || cont.Spec.HasMemory || cont.Spec.HasNetwork,\n\t\t\tCpuAvailable:           cont.Spec.HasCpu,\n\t\t\tMemoryAvailable:        cont.Spec.HasMemory,\n\t\t\tNetworkAvailable:       cont.Spec.HasNetwork,\n\t\t\tFsAvailable:            cont.Spec.HasFilesystem,\n\t\t\tCustomMetricsAvailable: cont.Spec.HasCustomMetrics,\n\t\t\tRoot:                   rootDir,\n\t\t}\n\t}\n\n\terr := pageTemplate.Execute(w, data)\n\tif err != nil {\n\t\tklog.Errorf(\"Failed to apply template: %s\", err)\n\t}\n\n\tklog.V(5).Infof(\"Request took %s\", time.Since(start))\n}\n"
  },
  {
    "path": "cmd/internal/pages/static/assets.go",
    "content": "// Copyright 2022 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n// generated by build/assets.sh; DO NOT EDIT\n\n// Code generated by go-bindata. DO NOT EDIT.\n// sources:\n// cmd/internal/pages/assets/js/bootstrap-4.0.0-beta.2.min.js (50.564kB)\n// cmd/internal/pages/assets/js/containers.js (34.605kB)\n// cmd/internal/pages/assets/js/jquery-3.5.1.min.js (89.475kB)\n// cmd/internal/pages/assets/js/loader.js (65.121kB)\n// cmd/internal/pages/assets/js/popper.min.js (19.188kB)\n// cmd/internal/pages/assets/styles/bootstrap-4.0.0-beta.2.min.css (127.343kB)\n// cmd/internal/pages/assets/styles/bootstrap-theme-3.1.1.min.css (13.186kB)\n// cmd/internal/pages/assets/styles/containers.css (132.925kB)\n\npackage static\n\nimport (\n\t\"bytes\"\n\t\"compress/gzip\"\n\t\"crypto/sha256\"\n\t\"fmt\"\n\t\"io\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"strings\"\n\t\"time\"\n)\n\nfunc bindataRead(data []byte, name string) ([]byte, error) {\n\tgz, err := gzip.NewReader(bytes.NewBuffer(data))\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"read %q: %w\", name, err)\n\t}\n\n\tvar buf bytes.Buffer\n\t_, err = io.Copy(&buf, gz)\n\tclErr := gz.Close()\n\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"read %q: %w\", name, err)\n\t}\n\tif clErr != nil {\n\t\treturn nil, err\n\t}\n\n\treturn buf.Bytes(), nil\n}\n\ntype asset struct {\n\tbytes  []byte\n\tinfo   os.FileInfo\n\tdigest [sha256.Size]byte\n}\n\ntype bindataFileInfo struct {\n\tname    string\n\tsize    int64\n\tmode    os.FileMode\n\tmodTime time.Time\n}\n\nfunc (fi bindataFileInfo) Name() string {\n\treturn fi.name\n}\nfunc (fi bindataFileInfo) Size() int64 {\n\treturn fi.size\n}\nfunc (fi bindataFileInfo) Mode() os.FileMode {\n\treturn fi.mode\n}\nfunc (fi bindataFileInfo) ModTime() time.Time {\n\treturn fi.modTime\n}\nfunc (fi bindataFileInfo) IsDir() bool {\n\treturn false\n}\nfunc (fi bindataFileInfo) Sys() interface{} {\n\treturn nil\n}\n\nvar _cmdInternalPagesAssetsJsBootstrap400Beta2MinJs = []byte(\"\\x1f\\x8b\\x08\\x00\\x00\\x00\\x00\\x00\\x00\\xff\\xdc\\xbd\\x6b\\x77\\xe3\\xb6\\x76\\x30\\xfc\\xbd\\xbf\\x42\\xe2\\xe9\\xab\\x21\\x6a\\x98\\x23\\x27\\xa7\\x3d\\x3d\\xd4\\x70\\xbc\\x3c\\xb6\\x92\\xf8\\x8d\\xc7\\x76\\x6d\\x39\\x69\\xea\\xa3\\x7a\\xd1\\x22\\x24\\x21\\x43\\x01\\x2a\\x09\\x8d\\xc7\\xb5\\xd8\\xdf\\xfe\\x2c\\x5c\\x09\\x90\\xa0\\x6c\\x4f\\x92\\xf3\\x74\\x3d\\x5f\\x66\\x2c\\x60\\x13\\xd7\\x8d\\x7d\\xc3\\xde\\x1b\\x6f\\xff\\xa9\\xff\\x0f\\xbd\\xde\\x3f\\xf5\\x3e\\x50\\xca\\x4a\\x56\\xa4\\xeb\\xde\\xe7\\x3f\\x47\\xc3\\x68\\xb8\\x7f\\x8f\\x58\\x1a\\x7d\\xd3\\x0b\\x97\\x8c\\xad\\xcb\\xf8\\xed\\xdb\\x05\\x62\\xf7\\x1a\\x26\\x9a\\xd1\\x15\\x10\\x9f\\x1d\\xd3\\xf5\\x63\\x81\\x17\\x4b\\xd6\\xfb\\x66\\x78\\x70\\xb0\\xff\\xcd\\xf0\\xe0\\x2f\\xbd\\xc9\\x12\\x59\\xcd\\x1d\\x6d\\xd8\\x92\\x16\\xa5\\xd5\\x10\\x66\\xcb\\xcd\\x3d\\x6f\\xe2\\x2d\\x7b\\xb8\\x2f\\xdf\\x9a\\x56\\xdf\\x2e\\x8a\\x74\\xbd\\x2c\\xdf\\xce\\x28\\x61\\x05\\xbe\\xdf\\x30\\x5a\\x94\\xb2\\x97\\x33\\x3c\\x43\\xa4\\x44\\x59\\x6f\\x43\\x32\\x54\\xf4\\x3e\\x9e\\x4e\\x5e\\xd2\\xdc\\x7d\\x4e\\xef\\xdf\\xae\\xd2\\x92\\xa1\\xe2\\xed\\xd9\\xe9\\xf1\\xf8\\xfc\\x7a\\x2c\\x9a\\x7b\\xfb\\x0f\\x9f\\xd3\\xa2\\x67\\xe0\\x92\\xf9\\x86\\xcc\\x18\\xa6\\x24\\x64\\x10\\x41\\x02\\x9e\\x82\\x4d\\x89\\x7a\\x25\\x2b\\xf0\\x8c\\x05\\x23\\x5d\\xd9\\xc3\\xbc\\x1a\\x3c\\xcd\\x69\\x11\\xf2\\xcf\\x49\\x32\\x1c\\x91\\x77\\x28\\xca\\x11\\x59\\xb0\\xe5\\x88\\xec\\xed\\x81\\x27\\x5e\\x8e\\x13\\x74\\x4b\\xa6\\x23\\x1c\\x21\\xb2\\x59\\xa1\\x22\\xbd\\xcf\\x51\\x62\\xff\\xd8\\x6e\\xfb\\x07\\x10\\x47\\x33\\x4a\\xe6\\x78\\xb1\\x91\\xf5\\xfd\\x21\\x0c\\x3e\\xa7\\xf9\\x06\\x05\\x98\\xf4\\xf0\\x60\\x10\\xe2\\xe8\\xa1\\xc0\\x4c\\xd5\\x01\\x78\\x71\\xff\\x2b\\x9a\\xb1\\x28\\x43\\x73\\x4c\\xd0\\x65\\x41\\xd7\\xa8\\x60\\x8f\\x21\\x83\\x38\\xfa\\x84\\x1e\\x21\\x06\\x55\\x85\\x12\\x34\\x18\\xa0\\x68\\x99\\x96\\x17\\x0f\\xc4\\x40\\x04\\x19\\x9a\\xa7\\x9b\\x9c\\x05\\xe0\\x10\\x45\\xea\\xef\\x18\\x41\\x92\\x90\\xc1\\x80\\xec\\x00\\x26\\x06\\x98\\x8c\\xf8\\x9c\\xca\\x7a\\x89\\xc0\\x93\\x59\\x10\\x16\\x32\\xf0\\x54\\x20\\xb6\\x29\\xc8\\x53\\x15\\x31\\x7a\\xcd\\x0a\\x4c\\x16\\xd1\\x2c\\xcd\\xf3\\x90\\x81\\x68\\x95\\xb2\\xd9\\x32\\x7c\\xfb\\xb7\\x32\\xbc\\x4d\\xf7\\xff\\xfb\\x68\\xff\\x3f\\xa6\\x7b\\xe0\\x2d\\xb8\\x3d\\x98\\x46\\x8c\\x9e\\xd1\\x07\\x54\\x1c\\xa7\\x25\\x0a\\x41\\x65\\xda\\xe3\\x8d\\xab\\xe6\\xee\\x31\\xc9\\x26\\x8f\\x6b\\x14\\x17\\x11\\x22\\x19\\xcc\\x50\\x8e\\x16\\x29\\x43\\x56\\xd1\\x32\\x25\\x59\\x8e\\xe2\\x7a\\xeb\\xc0\\x13\\x9e\\x87\\x28\\x64\\x11\\x4b\\x8b\\x05\\x62\\x20\\xc2\\x65\\xc8\\x96\\xb8\\x04\\x40\\xb6\\xd9\\x63\\x91\\xfc\\xe6\\xe2\\xfe\\x57\\xf5\\x57\\x11\\xa5\\xeb\\x75\\xfe\\x28\\xc0\\x60\\x5a\\x2c\\x36\\x2b\\x44\\x58\\x09\\xaa\\xaa\\xb2\\x36\\x5d\\xb4\\xfb\\x80\\x49\\x46\\x1f\\xa2\\x7f\\xbb\\x21\\x98\\xa9\\xf6\\xfa\\x07\\x62\\x69\\x58\\x92\\xd1\\x99\\xf8\\x30\\x9a\\x15\\x28\\x65\\x68\\x9c\\x23\\xfe\\x2b\\x0c\\x0c\\x7e\\x05\\x60\\xa4\\x91\\x06\\xf5\\x30\\xe9\\x51\\x80\\xe7\\x61\\xc0\\x31\\x99\\x6f\\x67\\x16\\xf4\\x13\\xf6\\xb8\\x46\\x74\\xde\\x63\\x51\\xc9\\x1e\\x73\\x74\\x8b\\xa6\\xaa\\x8f\\x27\\x44\\xb2\\x98\\xde\\xa2\\x69\\x35\\xd2\\x9d\\xd6\\x43\\x2b\\xf9\\x9c\\x25\\x26\\x8a\\x09\\xe0\\xa4\\x7f\\xa0\\xc0\\x7a\\x48\\x4e\\x3d\\xa2\\x04\\x85\\x69\\x34\\xb9\\x3a\\x3a\\xbf\\x3e\\x9d\\x9c\\x5e\\x9c\\xdf\\x8d\\xcf\\x4f\\xa0\\xb5\\x97\\x38\\xe9\\x0f\\x2b\\x00\\x4b\\xc4\\x26\\x78\\x85\\xe8\\x86\\x85\\x76\\xe5\\x76\\x9b\\x46\\xac\\xc0\\x8b\\x05\\x2a\\x26\\x45\\x4a\\x4a\\xcc\\x2b\\xc6\\x24\\x0b\\x09\\xa8\\x20\\x03\\x90\\xf7\\x51\\xf1\\x11\\x14\\x49\\xff\\x00\\xd2\\xe4\\xe9\\x67\\x74\\xff\\x09\\xb3\\x1a\\x36\\x0e\\x1e\\x1a\\x25\\x63\\x92\\x05\\xf0\\x23\\xfd\\x6f\\x1b\\x86\\x99\\xbf\\x11\\xaf\\xbd\\xb0\\xeb\\xa8\\xf3\\x69\\x8f\\x36\\x60\\x59\\x67\\x33\\x15\\x4c\\x93\\x27\\x77\\xe2\\x71\\x70\\x5f\\x36\\x46\\xb2\\x40\\xec\\xe6\\xf4\\xc4\\xc1\\xa2\\x8c\\x3e\\xb1\\xbd\\xe4\\x7f\\xfe\\x27\\x3c\\x40\\xff\\xf2\\x4f\\x1f\\x53\\xb6\\x8c\\x8a\\x94\\x64\\x74\\x15\\x02\\x50\\x3d\\x2c\\x71\\x8e\\x42\\xb3\\xe1\\x0b\\xc4\\xd4\\x6e\\x7f\\x78\\x3c\\xcd\\x42\\x06\\x80\\x5e\\x7f\\x56\\xf1\\xa6\\xaf\\x51\\x8e\\x66\\x8c\\x16\\xdf\\x15\\x74\\xa5\\x00\\x9d\\xae\\xd4\\xe6\\xf1\\x76\\x8e\\x98\\xa4\\x78\\x28\\x0c\\xb2\\x94\\xa5\\xfb\\x12\\x89\\x03\\x30\\x22\\x83\\x41\\xf0\\xa7\\xa0\\x9f\\x24\\x64\\xbb\\x0d\\xdb\\xc0\\xcb\\x02\\xcd\\x03\\xb0\\xdd\\x06\\x01\\x18\\xb1\\xe2\\xf1\\xc9\\xec\\xbf\\x1e\\x24\\x88\\xe6\\x58\\xec\\x98\\x22\\x54\\xef\\x87\\x87\\x24\\x26\\x9b\\x3c\\xaf\\x66\\xe2\\x7c\\x9a\\x23\\xdc\\x13\\x85\\x15\\x2c\\xd0\\x3c\\xa7\\x0f\\xce\\x38\\xcd\\x01\\xa2\\xf3\\x79\\x89\\xd8\\x0f\\x88\\xd3\\xfb\\x0a\\xfa\\x50\\xc3\\xf9\\x0e\\x71\\x32\\xa0\\xa0\\x42\\x71\\x6c\\x41\\x05\\xcb\\xcd\\x7a\\x4d\\x0b\\x56\\x76\\x7c\\x66\\x7a\\xfb\\x40\\x69\\x8e\\x52\\x12\\x16\\xa0\\x82\\xb8\\xf4\\x2d\\x9f\\x04\\x0c\\xd9\\xed\\x70\\xba\\xdd\\x32\\x10\\x11\\x9a\\x09\\x0a\\x51\\x41\\x7e\\x9e\\x8e\\x97\\x68\\xf6\\xe9\\x58\\x50\\xd9\\xfa\\x2b\\x04\\x09\\xc4\\x35\\x0d\\x2f\\xf9\\x71\\xc4\\xfc\\x38\\x2a\\x0a\\xbb\\x2e\\x28\\xa3\\xfc\\xeb\\x06\\x71\\x94\\x44\\x0d\\xc3\\x12\\xc8\\x5d\\x2b\\x12\\x7c\\x5b\\x4e\\x21\\x4d\\x08\\xff\\x2f\\x4f\\xe8\\x60\\x90\\x46\\x66\\x94\\x21\\x05\\x87\\x01\\x92\\x7f\\x07\\x31\\xff\\x39\\xc2\\xf3\\xb0\\x4f\\xd0\\x43\\xef\\x0a\\x2d\\xc6\\x5f\\xd6\\x61\\x01\\x22\\x86\\x4a\\x16\\xe6\\x00\\xb0\\x65\\x41\\x1f\\x7a\\xbc\\x6e\\x5c\\x14\\xb4\\x08\\x51\\xc4\\xe8\\xcd\\x7a\\xad\\xc9\\xe3\\xde\\x9b\\xb8\\x77\\xb1\\x16\\x07\\x3e\\x78\\xb3\\x57\\xee\\xbd\\x09\\x7a\\xeb\\x82\\x7e\\xc6\\x19\\xca\\x7a\\x7c\\xa0\\xbc\\x34\\xe7\\xa5\\xf7\\x1b\\xd6\\x43\\x5f\\xd6\\x68\\xc6\\xac\\x9a\\x62\\xef\\x4d\\x10\\xbd\\xe1\\x14\\x4d\\x63\\x66\\x91\\xe0\\x10\\x40\\x14\\xcd\\x49\\x84\\x56\\x9b\\x9c\\x13\\x55\\x7b\\x23\\x92\\x12\\xa6\\x91\\x77\\x8b\\x42\\x30\\x18\\x84\\x28\\x42\\x9f\\x39\\xe6\\x97\\x6b\\x34\\xc3\\x69\\x7e\\xdb\\xa4\\x2d\\xd3\\x84\\x84\\x00\\xc0\\xb4\\x0a\\x01\\x2c\\x5a\\x7c\\x55\\x23\\xe7\\x60\\x80\\x43\\x6b\\xad\\x21\\x02\\x90\\x88\\x32\\x48\\x00\\x64\\x15\\xa4\\xce\\x97\\xe0\\xc9\\x82\\x4d\\xd4\\x46\\x49\\x5a\\x1b\\xa2\\xba\\x06\\x40\\x7b\\xfb\\x66\\x94\\x94\\xac\\xd8\\xf0\\xd3\\x97\\x30\\xc8\\xa2\\xbb\\x3b\\x51\\x77\\x77\\x97\\x20\\x4e\\x19\\x2c\\x74\\x93\\x44\\x3c\\x48\\x73\\x54\\xb0\\x00\\x92\\x84\\x2f\\xcd\\x2d\\x9b\\x42\\x9c\\x3c\\x1d\\x9f\\x5d\\x5c\\x8f\\xe3\\x60\\x96\\xd3\\x12\\x45\\xf7\\x65\\xa4\\x60\\x44\\xf1\\x89\\x2a\\xcf\\x9c\\x8a\\xd3\\xe3\\x1f\\xef\\x4e\\x8e\\x26\\x47\\x77\\x47\\x97\\xa7\\x1c\\x00\\xcf\\x3e\\x99\\xfa\\x48\\x1c\\xec\\x74\\x8d\\x03\\x3e\\xc3\\xa7\\xa3\\xb3\\xf1\\xd5\\x24\\xd6\\xfd\\x7e\\x77\\x74\\x32\\x8e\\x83\\x79\\x9a\\xa1\\x00\\x5e\\xff\\x70\\xf1\\x73\\x1c\\x94\\x4b\\xfa\\x10\\x34\\xc6\\xea\\xb2\\x5e\\x4e\\x7e\\xa3\\x3b\\x85\\x67\\x09\\xab\\x34\\x39\\x31\\xab\\xa0\\xf7\\x9c\\x44\\x62\\xa8\\x89\\x7d\\x78\\x58\\xc2\\xb6\\x5b\\xa7\\x05\\xc1\\xce\\x50\\x22\\xcb\\x16\\x88\\x5d\\x51\\xaa\\xc9\\x5b\\xc8\\xc0\\x48\\x96\\xab\\xd3\\x7c\\xcc\\xdb\\x1b\\x73\\x54\\x08\\x11\\xe7\\xb4\\x27\\x52\\x5c\\xb8\\x2c\\x04\\x7a\\xa0\\x2c\\x04\\xba\\xf1\\x02\\xad\\xe8\\x67\\xc3\\x14\\x11\\xa8\\x20\\x89\\x32\\x5c\\xae\\x9d\\xf1\\x80\\x27\\x14\\x49\\xc0\\x93\\x94\\xa5\\xa1\\x33\\x2c\\x18\\x98\\x05\\x96\\x1c\\xa7\\x9e\\xb2\\xa0\\x58\\x90\\x34\\x47\\x9b\\xb4\\x69\\x6c\\x19\\xf9\\xc9\\x71\\xc8\\x80\\xc3\\x37\\x09\\x97\\xbd\\x12\\x14\\x12\\x70\\x3b\\x9c\\x02\\x88\\xb7\\x5b\\xf1\\x93\\x01\\xb9\\x82\\x25\\x0b\\x83\\x28\\xd8\\xa3\\x91\\xd8\\x3c\\x05\\x23\\x46\\xd0\\x5a\\x17\\xcf\\x20\\x50\\x24\\x57\\x0c\\x47\\x02\\x83\\x80\\xc5\\xac\\x6b\\x32\\x49\\x00\\x24\\xa2\\x45\\x67\\xe1\\x3c\\xad\\xf1\\xa5\\x18\\x89\\x4f\\x25\\xe4\\x71\\x9e\\x96\\x65\\x48\\x23\\x8e\\x3d\\x00\\x96\\xdd\\x87\\x58\\x7c\\xb3\\x4c\\x4b\\xfd\\x01\\x47\\x3d\\x70\\x28\\x4a\\xb9\\xb8\\x50\\x76\\x8a\\x0b\\xa8\\x66\\x15\\xd1\\x5d\\x86\\x4a\\x56\\xd0\\x47\\xb3\\x8e\\x10\\x81\\x0a\\x78\\x49\\x4a\\x78\\xf0\\xcf\\x43\\x10\\xcb\\x9d\\x6b\\x7e\\x25\\xd0\\xa1\\x51\\x9a\\xb4\\x58\\x48\\x86\\x58\\x3a\\x5b\\x86\\xf5\\x22\\xa9\\x15\\x3c\\xd1\\x73\\x0f\\xb9\\x3c\\x12\\xdd\\xfd\\xfa\\x6f\\x1b\\x54\\x3c\\x9e\\x12\\x86\\x8a\\x79\\x3a\\xb3\\xf0\\xab\\xa6\\x3d\\x62\\x18\\x88\\xb7\\xd6\\x20\\x01\\x62\\x9b\\xb9\\xcc\\x04\\xcb\\x04\\x8b\\xa3\\x1a\\x5a\\x88\\x37\\x2a\\xb7\\xdb\\xb0\\x4c\\x38\\x95\\x66\\x0a\\xac\\x05\\xc4\\x99\\x03\\x94\\x44\\x21\\x48\\x12\\x2e\\x62\\x97\\xb7\\x64\\x2a\\xa1\\x2b\\x39\\x40\\x29\\x76\\x9e\\xe0\\x72\\x85\\xcb\\x32\\xf1\\xb0\\x58\\x7b\\xad\\x85\\x40\\xbf\\x96\\x27\\x4a\\x9d\\xaf\\x90\\x13\\x39\\xd1\\x83\\x6a\\xb6\\x82\\x05\\xa7\\x9a\\x9b\\x3c\\x87\\xb7\\x4f\\x9f\\xd0\\x63\\x1c\\xfc\\x34\\xbe\\xba\\x3e\\xbd\\x38\\x17\\xa2\\x4d\\x9b\\xab\\x06\\xb6\\x6a\\x17\\x54\\xd5\\x94\\xd3\\xdb\\xd0\\xc2\\xc4\\x5a\\x6c\\xa0\\x44\\x2c\\xb3\\x4d\\xd1\\xe0\\xd3\\xc9\\xe9\\xf5\\xc7\\xd3\\xeb\\xeb\\xf8\\xcd\\xad\\x20\\x66\\x99\\x9a\\x89\\xa2\\x62\\xd3\\x37\\x55\\xa4\\x20\\x60\\xda\\x98\\x6d\\xc8\\xd7\\x2e\\x05\\x92\\xf5\\xdc\\xb2\\x69\\x92\\xb6\\xf6\\x4b\\x57\\x45\\xc7\\x16\\xf1\\x4e\\x4d\\x29\\xa1\\x9c\\x9b\\xe7\\x78\\xc6\\x92\\xb6\\xb4\\xa0\\x5b\\x25\\xb0\\xdd\\x6e\\x25\\xf9\\x51\\xee\\xa1\\xfa\\xf7\\x1b\\xc6\\x28\\x69\\x90\\xfd\\xa3\\xe3\\xc9\\xe9\\x4f\\xe3\\x38\\x48\\x67\\x0c\\x7f\\x46\\x01\\xfc\\x70\\x33\\x99\\x5c\\x9c\\xc7\\xc1\\x3d\\x23\\x01\\xfc\\xee\\xe2\\xf8\\xe6\\x3a\\x0e\\xe6\\x74\\xb6\\x29\\x83\\x0a\\x96\\xc9\\x93\\x58\\x9d\\xc9\\xc5\\xf7\\xdf\\x9f\\x8d\\xef\\x8e\\x8f\\xae\\xae\\x2e\\x26\\x7a\\x79\\x18\\x5d\\x2c\\x72\\xf4\\x9f\\xa6\\x9b\\xe9\\x1b\\x68\\x01\\xbb\\x50\\x1a\\xa8\\xe4\\x50\\xa7\\xe7\\x97\\x37\\x93\\x38\\xc0\\x64\\xbd\\x61\\x01\\xd4\\xe3\\x89\\x9a\\x03\\x8a\\xf8\\x88\\x04\\x33\\xe9\\xe4\\x3c\\xb2\\xd1\\x9a\\xf5\\xc8\\xf1\\xdf\\x7d\\x38\\xbb\\xb9\\xb2\\xc0\\xc5\\x6c\\x3c\\xe0\\xbd\\xfb\\x7c\\x53\\xf8\\x9a\\xf9\\xbd\\xf8\\x92\\x9a\\x7b\\x6b\\x63\\xfa\\x43\\x48\\xf8\\x3f\\x85\\x3a\\x95\\xa6\\xb9\\x9a\\x10\\x97\\x91\\xb5\\x96\\x9c\\x14\\x73\\x19\\xab\\x90\\x0d\\xd0\\xf6\\x67\\x42\\x0a\\x2e\\x23\\xb1\\xb2\\x1a\\x9a\\x0a\\xdd\\x2e\\x28\\xd2\\x0c\\x53\\x7e\\x64\\x69\\x24\\x04\\x09\\x5e\\x13\\xcd\\xb8\\xf8\\x88\\x32\\x41\\x2e\\xdd\\x96\\x0c\\xe9\\xc4\\x91\\xdc\\x19\\x00\\x18\\x67\\x21\\x28\\x2f\\x91\\xe8\\x3d\\x4d\\x10\\x17\\xf0\\x54\\x8f\\x0a\\x86\\x77\\x99\\xf2\\xd6\\x52\\x97\\x60\\x9b\\x46\\x2a\\x3c\\x57\\x4a\\x2c\\xe5\\x5d\\xd8\\x0a\\x01\\x2e\\xd3\\xfb\\x1c\\x65\\x5c\\xce\\x2f\\x76\\xd4\\xd1\\x68\\xc6\\x9b\\x3c\\xc3\\x25\\xe3\\xf2\\x0f\\x4b\\x31\\x29\\x9b\\x5f\\xef\\x86\\x50\\x6a\\xe7\\xc8\\x4c\\x3f\\xe9\\xbf\\x60\\xfa\\x10\\x85\\xb4\\xa6\\xcd\\xc1\\x6c\\x99\\x92\\x05\\x0a\\x40\\x45\\x23\\x81\\x57\\x21\\xe0\\x7b\\x79\\x50\\x55\\x64\\x30\\x70\\xda\\x8a\\x4a\\x47\\x95\\x49\\x0b\\x9c\\xee\\xaf\\x0b\\x54\\x96\\x28\\x0b\\xe0\\x4b\\x3a\\x06\\x90\\x79\\xf6\\x47\\xe2\\x54\\x73\\x75\\xbf\\x4a\\xec\\x50\\xe7\\xd6\\x2f\\x77\\xfc\\x5e\\x0c\\xa7\\xe6\\x23\\xba\\xbb\\x91\\x94\\x3b\\x6c\\x6e\\xd3\\x05\\x0b\\x31\\x67\\x3a\\x72\\xca\\x8a\\xeb\\x60\\xce\\x75\\x04\\xc7\\xf9\\x23\\x79\\x03\\x6d\\xf2\\x06\\xe7\\x3c\\x2a\\x42\\x08\\x1d\\x89\\xb3\\xc5\\xcc\\x46\\x9a\\x32\\x48\\x6d\\x77\\xc4\\xe5\\x2e\\x7b\\x9b\\x25\\x9d\\x03\\x42\\xf1\\x15\\x75\\xf5\\xd9\\x57\\x55\\xc0\\x43\\xee\\xa5\\xae\\xc6\\xe1\\xcd\\xc2\\x70\\xd1\\x44\\x8c\\xd9\\x43\\xfd\\x9e\\x1f\\xb8\\x92\\xde\\x2c\\xd3\\x52\\x6b\\x1c\\xfc\\x74\\x8b\\x11\\xba\\xc8\\x27\\xba\\x83\\x6f\\xff\\x53\\x9e\\x03\\x4c\\xc0\\xe1\\x3f\\xbe\\x95\\x8a\\x1f\\x93\\xa4\\x06\\x54\\xff\\x17\\x19\\xe2\\xd2\\xc3\\x10\\x67\\x69\\x41\\x37\\x25\\xca\\x39\\x4b\\xe4\\x68\\x56\\xff\\xc6\\x09\\x17\\x7d\\x09\\xa4\\x86\\x55\\xa6\\xc9\\x13\\xe6\\x4d\\x7e\\x4e\\xf3\\xf8\\x9f\\xd1\\xb7\\xf0\\x13\\x7a\\xbc\\xa7\\x69\\x91\\xc5\\xfd\\x21\\x2c\\x73\\x9c\\xa1\\xb8\\x7f\\x00\\xd7\\xe9\\xa6\\x44\\x71\\xb0\\xa4\\x9f\\x51\\x11\\xc0\\x87\\x22\\x5d\\xc7\\xfd\\x61\\x05\\x73\\xeb\\xdb\\x20\\x24\\x9b\\xd5\\x3d\\x2a\\xb6\\xf7\\x52\\xe5\\x07\\x41\\xdd\\x54\\xa0\\xca\\x02\\xd5\\x62\\x10\\xaa\\x82\\x6d\\x29\\xac\\x8d\\x20\\xd0\\x3d\\x84\\xb2\\xc0\\x6a\\x44\\x74\\x66\\x1a\\xa8\\xe0\\x32\\x79\\x3a\\x1f\\xff\\xfb\\x24\\x0e\\x08\\xfa\\xc2\\x02\\x78\\x79\\x35\\xfe\\x29\\x0e\\x38\\x4e\\x06\\xf0\\x6c\\xfc\\xdd\\x24\\x0e\\x72\\x34\\x67\\x01\\xbc\\x3a\\xfd\\xfe\\x87\\x49\\x1c\\x08\\xa3\\x76\\x50\\xc1\\x59\\xf2\\x74\\x7d\\x76\\xca\\xb5\\x33\\x31\\x82\\x60\\x0f\\x43\\xfe\\x5b\\xfe\\xe4\\xbf\\x7e\\x1c\\xff\\x72\\x72\\xf1\\xf3\\x79\\x1c\\x7c\\x42\\x8f\\x19\\x7d\\x20\\xbc\\xec\\xe3\\xc5\\xcd\\xf5\\x78\\x7c\\x3e\\x19\\x5f\\xc5\\xc1\\x8a\\x2f\\x20\\xd7\\x8a\\x0a\\x53\\x73\\x36\\x3e\\xe2\\x0c\\x5d\\xd4\\xe4\\x28\\xfd\\x2c\\x5a\\x9d\\x5c\\xdc\\x1c\\xff\\x20\\xcc\\x54\\x8c\\x6e\\x66\\x4b\\x44\\x44\\xeb\\x67\\x17\\x47\\x27\\x16\\xa7\\xce\\x69\\x2a\\x34\\x4e\\xbd\\x2f\\x16\\x67\\xef\\x94\\x01\\xda\\xb0\\x15\\xdc\\x24\\x4f\\xc7\\x47\\x57\\x62\\x2c\\xb1\\xb5\\xe9\\x4d\\xd1\\xc7\\x99\\xb9\\x5e\\x19\\x0d\\xbe\\x8f\\x19\\x5a\\xed\\xcb\\x75\\x52\\x2b\\xe8\\x56\\xc9\\xf5\\x94\\x6b\\xee\\xd6\\xd8\\x3b\\xe0\\xd6\\xc8\\xfd\\x38\\x9d\\x8c\\x3f\\x36\\x6a\\x82\\x0a\\x66\\xb5\\x6c\\x66\\x64\\x21\\x59\\x70\\x27\\x3f\\x50\\xa5\\x91\\xfb\\xa1\\x6a\\xad\\x59\\xca\\xc7\\x75\\x27\\x87\\x10\\xb5\\x47\\x07\\x7b\\x91\\x77\\x60\\xe7\\x27\\xa7\\xc7\\x47\\x93\\x8b\\xab\\x6b\\xe7\\x2b\\x92\\xe1\\x59\\xca\\x68\\x51\\x06\\x52\\xc2\\x53\\xeb\\x26\\x05\\x3c\\xb1\\x7a\\x53\\xd8\\xb3\\x7e\\xed\\x33\\x3a\\x55\\xa0\\x57\\x1c\\x52\\x89\\x82\\x05\\xce\\x90\\x75\\x06\\xa7\\x6f\\x2a\\x38\\xf7\\xca\\x59\\x54\\xd8\\x4a\\x94\\xa4\\xc5\\x87\\x57\\x0a\\xa6\\xa4\\xf8\\x94\\x3e\\x59\\x76\\x99\\x5c\\x99\\xb1\\xc5\\xc1\\x34\\x70\\x79\\xc9\\x0f\\x50\\x96\\xf4\\x0f\\x4c\\xc9\\x75\\x8e\\x33\\x4c\\x16\\xa6\\x48\\x20\\xa4\\xb2\\x10\\xdb\\xdf\\xca\\x4b\\x8c\\xda\\x64\\x20\\xcd\\x6d\\x9c\\xf2\\xba\\x0c\\x93\\x6b\\x71\\xb7\\xc3\\xa9\\x19\\x9e\\x5e\\xad\\x71\\x5d\\xef\\x91\\xd6\\xb2\\xa8\\x5e\\x6d\\xeb\\xf3\\x34\\xcb\\x84\\x1e\\xcd\\xa5\\x18\\x44\\x50\\x51\\x86\\x40\\x88\\x98\\xf3\\x84\\xb6\\x45\\xcc\\x79\\xc4\\x37\\xd3\\x5e\\xc3\\xc6\\x1c\\xb5\\x9d\\x42\\x6c\\x4b\\xb8\\x8c\\x38\\x56\\x80\\x0a\\xca\\xef\\x7e\\x5e\\x22\\xf2\\x13\\x2e\\xf1\\xbd\\x2b\\xa3\\xf6\\x8d\\x05\\x78\\x89\\xb3\\x0c\\x11\\x8f\\x10\\x82\\xcb\\x30\\x88\\x3f\\xcb\\x4f\\x03\\x30\\x18\\x04\\x12\\x32\\xe8\\x27\\x1e\\x89\\xb6\\x2c\\xc3\\x40\\xc0\\xe2\\x1c\\xb3\\x47\\x0e\\x2e\\x20\\xf8\\x08\\x42\\x31\\x16\\x8e\\x7b\\xaf\\x98\\x03\\x47\\x6a\\xf9\\x1d\\xdf\\x59\\xd7\\xec\\xb3\\xdd\\x86\\xcd\\x7d\\x1f\\x6a\\xf1\\xa2\\xbd\\x01\\xe6\\x8c\\xf0\\xf5\\x1f\\x0c\\x76\\x58\\x15\\xc2\\xd2\\x7f\\x55\\xe0\\xb6\\x2b\\xb7\\x70\\xf6\\x38\\xcb\\x51\\xd8\\x1f\\x02\\x00\\x67\\x39\\x4a\\x8b\\x53\\x85\\xaf\\xa1\\x8b\\xbe\\xc0\\x87\\xce\\x7c\\x5a\\xe2\\xfb\\x67\\xa7\\x75\\xd0\\xfc\\x7e\\x30\\x08\\x5f\\xdd\\x1d\\x70\\x30\\x3d\\xaa\\x9b\\xea\\xbb\\xdd\\x0d\\x06\\x8d\\xd6\\x92\\x12\\x31\\xd3\\x51\\x7d\\x65\\x50\\x6f\\xf3\\x35\\x4b\\x19\\x3a\\x34\\x1b\\x6d\\xa1\\x5a\\x6c\\x0a\\x41\\x74\\x8f\\xd5\\x1a\\x76\\x0c\\x04\\x88\\x7d\\x66\\xb4\\xcb\\x40\\xe4\\x3b\\xfc\\x5d\\x9b\\x6d\\x91\\x52\\x21\\xd0\\x48\\x29\\xd5\\x1c\\xee\\x53\\x86\\x56\\xa7\\x24\\x43\\x5f\\x42\\x4f\\xa3\\xd2\\xc2\\x1d\\xb2\\xf7\\x16\\x49\\x52\\x37\\x0e\\xfb\\x07\\xdb\\x2d\\x7b\\x37\\x04\\x5c\\xaf\\x6a\\x20\\x2e\\x68\\x0d\\x85\\x12\\x14\\xce\\x22\\x4e\\x3e\\x61\\x5b\\xa6\\xe1\\xfa\\x62\\xc8\\x40\\x05\\xa4\\xae\\x85\\xe7\\x21\\x4e\\x92\\x84\\x01\\x5b\\xd4\\x16\\x28\\x1f\\x02\\xf8\\x99\\xe2\\xac\\x67\\x61\\x1b\\x50\\x17\\x99\\xec\\x3d\\x3e\\x94\\xa7\\x3c\\x96\\x07\\x65\\x64\\x9f\\x9d\\x12\\x5a\\xe3\\xbf\\x65\\x53\\x50\\xf1\\xe5\\xf5\\x29\\x0e\\xad\\x81\\xcf\\xe7\\x21\\xe6\\xc2\\x5c\\xa7\\x42\\x61\\xa8\\x62\\x8b\\x5e\\x2b\\x32\\x6a\\x95\\x20\\x0f\\x9d\\xf6\\x10\\x75\\x83\\xec\\x4e\\x99\\xa6\\xde\\x2f\\xa2\\xfe\\x2d\\x5a\\xac\\x0f\\x59\\x4d\\xcf\\x7d\\x6a\\x0d\\x49\\x50\\x84\\xbe\\x30\\x44\\xb2\\xf0\\xa9\\x82\\x29\\x9f\\x5c\\x19\\x35\\xae\\x5d\\x38\\x8f\\x82\\xb9\\xb0\\x67\\xce\\x3d\\x64\\xbb\\x2d\\x7d\\x5a\\x18\\xab\\xd0\\x5c\\xcb\\x81\\x1e\\x0a\\x4b\\x49\\x38\\x8b\\x94\\xec\\xe5\\xb3\\x51\\xb2\\xe8\\x4e\\x09\\x64\\x21\\xe2\\x62\\xb6\\x12\\x41\\x39\\xc2\\xd8\\x3d\\x08\\x7c\\x19\\x0c\\x42\\x7f\\xfb\\xb5\\x1c\\xe7\\xef\\x42\\x62\\x1b\\x52\\xfa\\x85\\x82\\x17\\xd2\\x9d\\x1f\\x5e\\xe2\\xa2\\x1c\\x0f\\x25\\x82\\xad\\x96\\x2c\\x2d\\x58\\x80\\x49\\xcf\\xd0\\x08\\xfd\\x87\\xda\\x91\\xae\\xb9\\x6b\\x79\\xd1\\x3e\\x28\\xcc\\xe0\\x3f\\x73\\x98\\xf6\\x60\\x20\\x28\\x9f\\xbe\\xe4\\x75\\x2b\\x9b\\xc0\\x89\\xef\\x3a\\xd8\\x3b\\x0b\\xf8\\xcf\\xc3\\xe1\\x1e\\x6b\\x13\\xa5\\x4a\\x92\\x25\\xbd\\x01\\x49\\xe3\\x96\\xbe\\xff\\x56\\x58\\xb6\\xb6\\x0c\\x7d\\x61\\x69\\x81\\xd2\\xb7\\xd8\\x28\\x45\\x42\\xc1\\x8a\\x58\\xba\\x38\\x4f\\x57\\x08\\x80\\xf2\\x01\\x8b\\x4b\\xca\\xe8\\x61\\x89\\x67\\x4b\\xf0\\x34\\x4b\\x4b\\xd4\\xfb\\xf6\\x2f\\x71\\x5b\\x97\\x94\\xf8\\xcc\\x4b\\x43\\x30\\xba\\x2f\\x50\\xfa\\x69\\x24\\x81\\xff\\xda\\x09\\x2c\\xf9\\xab\\x02\\xd6\\x0e\\x0f\\x72\\x92\\x95\\x3e\\x01\\x86\\xe8\\xf9\\xac\\xb5\\xf6\\x71\\x46\\xd1\\x2a\\xfd\\x84\\x8e\\x8a\\x22\\x7d\\x0c\\x85\\xd1\\x7a\\x9d\\x16\\x88\\xb0\\xb0\\x96\\x65\\x38\\x59\\x75\\x48\\x40\\x84\\x79\\xc3\\x17\\x73\\x61\\x06\\xaf\\xbb\\xfb\\xf0\\x78\\x82\\x0b\\x24\\xfa\\x6a\\xdc\\x83\\x29\\xba\\x9e\\x24\\x89\\xa4\\x60\\x10\\xab\\x1f\\x9c\\x8e\\xc1\\xd2\\x47\\xaa\\x11\\x80\\x45\\xe2\\xa3\\xc9\\x9c\\x5e\\x87\\x78\\x30\\x18\\x26\\x49\\x52\\x6e\\xb7\\x64\\x30\\x28\\x93\\x24\\x29\\x80\\xe1\\x6c\\x6a\\x4f\\xb9\\x12\\xa5\\x09\\x2c\\x1a\\x49\\xe3\\x5a\\x58\\xee\\x85\\x75\\xc7\\x87\\xfb\\x07\\xf1\\x01\\x00\\xff\\x5f\\xbb\\x17\\x25\\x84\\xed\\x1f\\x24\\x49\\x42\\x0f\\x1d\\xca\\xea\\x19\\xd1\\x34\\xb6\\x21\\xe8\\x54\\xac\\x89\\x92\\x29\\x38\\x49\\x6b\\xdd\\xab\\x70\\x09\\xb8\\x9b\\x47\\x81\\x8e\\x05\\x79\\x19\\xf3\\xe3\\xcb\\xa6\\xef\\x6b\\x24\\x3f\\x1a\\xc3\\xa7\\x02\\xe5\\x29\\x43\\xd9\\x44\\x20\\x69\\xcc\\x60\\xa6\\xf7\\x29\\x26\\x70\\x5e\\xd0\\x55\\x5c\\x42\\x46\\x63\\x5c\\x01\\xd7\\x0d\\xc3\\xb6\\x4d\\xe9\\xcb\\x70\\x00\\x0b\\x31\\xbf\\x12\\xb1\\x23\\x41\\x9b\\x4f\\x35\\x21\\xf6\\xdd\\x82\\xd4\\x9c\\xb3\\x49\\xae\\x6b\\x4e\\xd4\\xae\\x72\\xa7\\xe6\\x9a\\x1d\\x37\\xba\\x74\\x54\\x0b\\x0b\\x9e\\x36\\xa2\\xd9\\x12\\xe7\\x59\\x81\\xc8\\xad\\x77\\x89\\xa7\\x23\\x21\\xfb\\x12\\x10\\xa5\\x59\\xd6\\x68\\x58\\x1e\\x21\\xc1\\x56\\x7d\\x7b\\x06\\x0b\\x48\\x61\\x2a\\x3d\\x57\\xf2\\x97\\x8a\\x24\\x70\\xee\\xdb\\xd2\\x1c\\xc0\\xbb\\x84\\x6c\\xb7\\xb9\\xb6\\x2f\\xb6\\x0f\\x52\\xc8\\x38\\x23\\x5a\\xf8\\xbe\\xbe\\x03\\x70\\x95\\x68\\x67\\x83\\x86\\x44\\xc8\\x0f\\x49\\x7d\\xdc\\x0e\\x43\\x9c\\x6c\\x22\\xae\\xe8\\xc2\\x22\\xd9\\xc8\\x13\\x48\\x93\\xa5\\x28\\x01\\xb1\\xa8\\x14\\x1a\\xb2\\xa8\\x15\\x47\\x92\\xd7\\x8a\\x22\\x00\\xef\\xf8\\x42\\xdd\\x59\\xe6\\xad\\x4d\\x6d\\x3d\\x6e\\x69\\x5d\\x42\\xbe\\xe9\\x71\\x4a\\xe9\\xdc\\xba\\xd6\\xa7\\x20\\xbc\\x83\\xd4\\x7f\\xef\\x3a\\x18\\xe4\\x83\\xc1\\x5d\\x4b\\x45\\x48\\xfa\\x43\\xb8\\x52\\xeb\\x63\\x58\\x84\\x14\\x7c\\xba\\x30\\x30\\xbc\\x93\\xc8\\xb1\\x6e\\x1c\\x84\\xe6\\x39\\xb8\\xb3\\xce\\x01\\x95\\xe7\\x60\\xce\\xcf\\xc1\\xa2\\x02\\xa3\\xdd\\xd7\\x90\\x1d\\xf6\\xdd\\x8d\\x3c\\x6f\\xe0\\x30\\x14\\x2b\\x66\\x50\\xab\\xe0\\x32\\x86\\x74\\x4f\\xe1\\xbb\\x86\\xc2\\xdc\\xaa\\xe4\\xb2\\x97\\x03\\x8d\\x15\\xc4\\xee\\x3b\\x4d\\x7e\\x7e\\xee\\x1a\\x16\\xf9\\xbd\\xa0\\x17\\xec\\x15\\x3e\\x9c\\x96\\x2d\\xfa\\xce\\x91\\xfc\\x46\\xfc\\x8b\\x85\\x51\\xd2\\x51\\xa2\\xfd\\xfe\\x55\\x86\\x48\\xa4\\x1e\\x0a\\xb1\\x06\\x15\\x1c\\x76\\x5e\\xa9\\xfe\\xcb\\x70\\x08\\x40\\x1c\\x76\\x0e\\xa7\\xb9\\x18\\x75\\xb9\\x47\\xc5\\xef\\xa4\\x52\\x6b\\x00\\x0c\\xd2\\x28\\x29\\xba\\xaa\\x20\\xdd\\x61\\xf7\\x66\\xaf\\xb6\\x7b\\x73\\xc1\\xb1\\x21\\x4b\\x3a\\xf5\\x00\\x8c\\x02\\x2a\\x7c\\x3e\\x82\\xc4\\xf8\\xc9\\x0d\\x06\\xe6\\x8b\\x12\\x32\\x89\\xa6\\x45\\x12\\x48\\x0b\\xa0\\x05\\x77\\xc8\\xe2\\x32\\x12\\x24\\x88\\x9f\\xe4\\xda\\xaa\\x4e\\xa5\\xcb\\x5f\\xd3\\xae\\x4e\\xa4\\x35\\x5d\\x5a\\x23\\xad\\x66\\x00\\x96\\x8a\\x87\\x39\\x96\\xad\\x9e\\x0a\\x79\\x93\\x54\\xfb\\xf4\\x99\\x1a\\x7c\\x5b\\x4c\\x5b\\x3e\\x3e\\x6f\\xce\\x69\\x6f\\x85\\xd8\\x92\\x66\\x3d\\x92\\xae\\x50\\xa6\\x5d\\x75\\xde\\x80\\x11\\x87\\x0f\\x41\\x25\\x7a\\x2a\\x2d\\x7d\\x33\\xc4\\xe6\\xdc\\x62\\xbd\\x19\\xc2\\xc8\\x4f\\xa3\\x3b\\x3e\\xf8\\xa3\\x35\\x3e\\xce\\xf1\\xec\\xd3\\x0f\\xd2\\xb3\\xb1\\xa5\\x0f\\xe2\\x1d\\x3e\\x10\\x7c\\x05\\xc4\\x02\\x69\\xe7\\x26\\x14\\x62\\x73\\xa3\\xc6\\x4f\\x6a\\xe1\\x9c\\x4e\\x6d\\x38\\x54\\xbe\\x50\\xa9\\xb3\\x7d\\x02\\x58\\xee\\x5c\\x73\\x23\\x61\\x2e\\xe9\\xaf\\xc7\\xdd\\x4d\\x1b\\xc5\\x02\\x30\\xe2\\x73\\x4d\\xcd\\xc4\\x85\\x1a\\xdf\\xc6\\x38\\x6d\\xe3\\x2f\\x00\\x4c\\x01\\xcc\\xd5\\x18\\x15\\x42\\xf1\\xcd\\xca\\xa5\\x3b\\x90\\x2b\\xf6\\x55\\xe2\\xbe\\x9c\\xfe\\x86\\x3b\\x11\\x28\\x3f\\x52\\x2d\\x76\\x7c\\xd4\\x4b\\xc5\\xe5\\x09\\xed\\xbe\\x3c\\x99\\x35\\x2f\\x4f\\xb2\\xa8\\x36\\x1b\\x72\\xb6\\xe9\\xd9\\x51\\xbe\\x9c\\xd2\\x0d\\x55\\x35\\xe1\\x58\\x86\\x5d\\x8a\\xa6\\x9a\\xbb\\xe2\\x54\\xd4\\x7b\\x08\\xb5\\x11\\x00\\x8c\\xe6\\x1d\\x6b\\xcb\\x20\\xd3\\xfb\\x56\\xd9\\xb7\\x14\\x6d\\x78\\xef\\x2d\\xc5\\xfc\\x75\\xb7\\x14\\x14\\xb6\\xdb\\xad\\xe0\\xbc\\x0a\\x01\\x9c\\xf9\\x6e\\x29\\x68\\x9e\\xa7\\xeb\\x12\\x99\\x5b\\x0a\\xf3\\x1b\\x9b\\xdb\\x09\\x9a\\x3c\\xc9\\xcb\\x98\\xb8\\x3f\\x84\\x52\\x18\\x8f\\x03\\xe9\\x16\\xaa\\xca\\xeb\\xbb\\x05\\x5d\\xad\\xef\\x10\\x34\\x25\\x0c\\xc4\\x45\\x45\\xed\\x8f\\x15\\x39\\x7d\\xf1\\xf2\\x73\\x59\\x41\\xdc\\x9a\\x1f\\x84\\xf5\\x77\\x89\\x33\\xd4\\x2a\\x3f\\x19\\x9f\\xc7\\xca\\x18\\xe8\\xd6\\x75\\x9b\\xef\\x15\\x88\\x6d\\xbe\\x5f\\xda\\xa3\\x0a\\xe0\\xf1\\xc5\\xd9\\xd9\\xd1\\xa5\\xf0\\x55\\xab\\xdb\\x93\\x65\\xa7\\xe7\\xdf\\x9b\\x52\\x4e\\xb2\\x0c\\xec\\x49\\x0d\\x9c\\xc9\\x6b\\x8e\\x9f\\x4f\\x4f\\x26\\x3f\\xc4\\xc1\\x03\\xce\\xd8\\x32\\x80\\x3f\\x8c\\xa5\\xb5\\x7f\\x89\\xd4\\x45\\xc8\\x46\\x5b\\xdf\\xaf\\xe3\\x20\\xe2\\xfd\\xc2\\x5e\\x64\\x37\\xbc\\xc3\\xb5\\xc1\\x8c\\x6a\\xfa\\xa6\\x82\\x99\\xd7\\xa2\\x8d\\x1d\\x8b\\xb6\\x25\\x2e\\xd8\\x76\\xe8\\xda\\xa9\\xe0\\x85\\x06\\x68\\xc5\\xc9\\x84\\x5a\\xd6\\x50\\xd1\\x3a\\x87\\x78\\xbb\\x2c\\xd0\\x3c\\x09\\xfe\\xf4\\x66\\x8f\\x45\\x38\\xdb\\x7b\\x13\\x4c\\x61\\x27\\xa8\\xe5\\xab\\xeb\\x7c\\xf1\\x06\\xd4\\x3e\\xdf\\x9c\\xe1\\x6d\\x1c\\x67\\x05\\x58\\x24\\xc3\\x51\\xf1\\x0e\\x1b\\x35\\x49\\xc7\\x0e\\xd0\\x84\\x93\\x7f\\x98\\x76\\xd3\\x6a\\x0a\\x46\\x9c\\x7a\\xf5\\x93\\x44\\x3b\\x13\\xcc\\x71\\xce\\x50\\xc1\\x35\\x4e\\xed\\xe0\\xab\\xc5\\x60\\x7b\\xf2\\xd1\\x7a\\x53\\x2e\\x43\\x0a\\x2a\\x59\\x25\\x11\\xbe\\x69\\x09\\xe1\\x65\\x87\\x66\\x2d\\x2f\\x95\\x02\\x1b\\xb7\\x2c\\x55\\x0a\\x54\\x9b\\x9d\\xd3\\x2c\\x3b\\x2a\\x70\\x7a\\x44\\xb2\\x63\\x8d\\x50\\x92\\x55\\xb8\\xf6\\xaf\\xf6\\xa0\\x1a\\x36\\x4d\\xb9\\xbe\\x6a\\xf4\\xf2\\x87\\x32\\xed\\x67\\x09\\x6e\\x9b\\xf6\\x33\\x8f\\xf7\\x48\\xb7\\x50\\xb9\\x94\\x8e\\x71\\x72\\x7a\\xfc\\x64\\x86\\xca\\x27\\x8d\\x63\\x72\\x08\\x2a\\x98\\x89\\xbf\\x3a\\x8c\\x52\\xb5\\x28\\xde\\x40\\xcd\\xc1\\x60\\x87\\xa3\\x82\\xea\\x53\\x71\\x55\\x48\\x47\\x46\\x8f\\x93\\x0b\\x38\\x18\\x84\\x61\\xd1\\xb4\\x1c\\x58\\xf5\\xc0\\xa8\\x5f\\xa1\\xf5\\xa7\\x96\\xe5\\xae\\x01\\xd0\\x7b\\xbe\\xdd\\x86\\x85\\x34\\x57\\x03\\xd8\\xe7\\x2c\\x3b\\xa4\\x89\\xcd\\x11\\xc1\\x60\\x40\\x5b\\x43\\xb7\\xd8\\xb7\\x14\\xef\\x73\\x39\\xdc\\x91\\x8c\\xa3\\xf0\\x8b\\x84\\x29\\x80\\xfd\\xd4\\xab\\x78\\x80\\xa7\\x42\\x48\\x29\\x3b\\x58\\xb5\\xa0\\x88\\x01\\x80\\x74\\xbb\\xb5\\x46\\x07\\xe5\\xc0\\x85\\x10\\x37\\xab\\x8f\\xf2\\x09\\x5e\\x21\\x52\\x8a\\x9d\\x18\\xb5\\x86\\x63\\xcb\\xbc\\xcb\\x48\\x93\\x34\\x4b\\xe0\\x35\\x85\\xa7\\xe7\\xdf\\x37\\x6e\\xa3\\x54\\x90\\xc5\\x6c\\x9a\\x0c\\x3d\\x38\\xa9\\x56\\xb4\\xd6\\x4f\\x1c\\x84\\xed\\xe8\\xf8\\x04\\x44\\x29\\x63\\x85\\xf2\\x61\\x41\\x5f\\xd6\\x29\\xc9\\x84\\x13\\xcb\\x50\\xf5\\xcd\\x15\\x00\\x7b\\xed\\xc3\\xfe\\x50\\x4e\\x38\\x6b\\x60\\xef\\x73\\x73\\xe4\\xd3\\xf1\\xcc\\xd2\\x9d\\xba\\x74\\x01\\x65\\x9e\\x19\\x07\\x01\\x64\\x9e\\xc1\\x1c\\x08\\x59\\xcd\\xb3\\xdd\\x12\\x25\\xce\\x41\\xc5\\x91\\xa2\\x53\\x99\\x93\\x88\\x34\\x4f\\x82\\x72\\x56\\xd0\\x3c\\x0f\\xf6\\xc2\\xd9\\xed\\x70\\xda\\xf0\\x63\\x9f\\x71\\x41\\x7c\\x86\\xc2\\x03\\xe0\\xd9\\x4f\\xaf\\x92\\x96\\xed\\x50\\x7e\\xba\\xb6\\xd4\\x29\\xbe\\x9d\\x4f\\xf7\\x82\\xf5\\x97\\x40\\x4a\\xd3\\x99\\x10\\x00\\xf9\\x41\\x5f\\x3a\\x36\\x89\\x97\\x1e\\xf4\\x17\\x9e\\x73\\x62\\x9d\\x27\\x2e\\x07\\xec\\x3e\\x4f\\x04\\xc0\\x3e\\xe9\\x38\\x4f\\x0d\\xdb\\x96\\x7d\\x20\\x0c\\x21\\x71\\x17\\x00\\x37\\x16\\x80\\x73\\x91\\x0f\\x74\\x43\\xb8\\xa6\\x77\\x9c\\x63\\x44\\xd8\\x15\\x9a\\xb1\\x10\\xdc\\x62\\xb9\\x30\\xb5\\x3e\\xdd\\xb8\\xa6\\x6b\\x8d\\xd7\\x7f\\xb0\\x3a\\xcf\\xa1\\x5b\\xae\\xf0\\xb1\\xeb\\xac\\x01\\xcd\\x29\\x25\\x5b\\xec\\x84\\xb3\\xf9\\x64\\x1b\\xe8\\x35\\x8c\\x33\\x14\\x9c\\xb3\\xb9\\x7f\\x9c\\x2a\\x51\\xef\\xe9\\xea\\x3c\\xdf\\x07\\x40\\x71\\xd4\\xce\\x03\\xee\\x88\\xaf\\x2f\\x3a\\x7b\\xaf\\x3c\\xf7\\xf5\\x51\\x95\\xd2\\x25\\xa8\\x46\\x1d\\xa8\\x11\\x04\\xdd\\x6e\\xe1\\x87\\x2f\\x3b\\x92\\xb3\\x1d\\x47\\x32\\x9e\\x49\\x0d\\x2b\\x6b\\x4d\\xd2\\xbd\\xaa\\xf5\\x4a\\x78\\x8c\\x7f\\xf7\\x3a\\x07\\x3d\\x02\\x3a\\xaf\\xcf\\x94\\x78\\xb3\\xfb\\x42\\xcd\\x91\\x0d\\x9d\\x0b\\x34\\x77\\x68\\xf2\\x42\\x2c\\x7b\\xd5\\x85\\x18\\xe5\\xa3\\x33\\xee\\xad\\xda\\xba\\xa8\\x0b\\xba\\xee\\xca\\x52\\x71\\x57\\x96\\xb9\\xa7\\xdd\\xa7\\x35\\x75\\x52\\xa2\\x59\\x24\\x84\\x78\\x70\\xa8\\xfe\\x88\\x67\\x91\\x94\\xe3\\x75\\xb3\\x52\\xa8\\xf3\\x13\\x3f\\x48\\xc4\\x5c\\x47\\xa5\\x15\\xc9\\xe4\\x11\\xfb\\xc0\\x61\\x48\\x7c\\x92\\x23\\xf4\\x86\\x34\\xb6\\xe1\\xa2\\x5f\\xff\\x8b\\x0b\\x08\\x83\\x81\\xbf\\x99\\xdb\\xe1\\x14\\x80\\x98\\x18\\x93\\xb0\\xdb\\xb7\\xbe\\x97\\x2e\\x92\\x6e\\xf9\\x5d\\x94\\x2b\\x14\\x08\\xde\\xec\\x79\\x9a\\x11\\x22\\x7a\\xad\\x9b\\x13\\x65\\x6f\\x2e\\x9a\\xca\\xb2\\x88\\x5a\\x62\\x3b\\x24\\x5c\\x2c\\x16\\x55\\x1a\\x42\\x6d\\x6a\\x43\\x00\\xbc\\x25\\x53\\xae\\x37\\xcb\\x0d\\xed\\x6a\\xa0\\x61\\x19\\x97\\x2e\\xc0\\xc6\\x4a\\xd6\\x26\\x51\\x23\\x62\\xc9\\x27\\x0d\\x77\\x43\\x8b\\x5c\\xc1\\x3e\\xee\\xa0\\x58\\x18\\x54\\x15\\xec\\x18\\xf5\\xeb\\xe2\\x66\\x8c\\x13\\xf7\\xa1\\x0a\\x97\\x91\\x51\\x85\\xb0\\x2d\\x01\\xbe\\xca\\x3c\\x58\\x9a\\x38\\x8c\\x22\\x29\\x8d\\x89\\x30\\x6d\\x9c\\xae\\x52\\x9b\\x98\\x7c\\xb6\\x41\\xe5\\x8c\\x50\\x0c\\x06\\xa9\\xd1\\x29\\xde\\x72\\xe1\\x7e\\xcb\\x19\\xbf\\x76\\xc0\\x04\\xc2\\xce\\xa4\\xd0\\x87\\x53\\xe1\\x42\\x4a\\xd1\\xe8\\x81\\xeb\\xa2\\x22\\x22\\x18\\xe8\\x7e\\x08\\x2c\\x00\\x80\\x6d\\xfb\\x62\\xa7\\xd5\\xaf\\xb8\\x65\\x2f\\xb3\\xfa\\x31\\x69\\xf5\\xe3\\xf0\\x9c\\x7a\\x0a\\xa7\\x5d\\xfc\\x87\\x1b\\xa8\\xa8\\x30\\x50\\xe1\\x6e\\x03\\x55\\xde\\x34\\x50\\x39\\x0a\\xac\\xe3\\x1d\\x1b\\x1c\\x89\\x3b\\xf5\\x68\\xb6\\x29\\xf8\\xd1\\x9a\\x38\\x37\\xb8\\x83\\x41\\x87\\xd7\\x2f\\x76\\xb6\\x79\\xa7\\x61\\x12\\xb5\\xcf\\x65\\xc3\\x88\\x05\\xcb\\x84\\x69\\x54\\x39\\xd4\\x3e\\xbf\\xb1\\x0a\\xd0\\x01\\xa3\\xac\\xd3\\xc4\\x55\\xba\\xb6\\xad\\x36\\xa0\\xd7\\xb6\\x95\\xbd\\xce\\xb6\\x85\\x61\\xbb\\xdd\\x0a\\x66\\x55\\x08\\xe0\\xc6\\xfe\\xac\\x03\\x95\\x48\\x0b\\x8f\\x82\\x3a\\xb7\\x42\\x56\\xd0\\x75\\x46\\x1f\\x48\\xaf\\x40\\xff\\xb5\\xc1\\x05\\xea\\x5d\\x52\\x2e\\x72\\x47\\xbf\\x5a\\xe9\\x16\\xd6\\xba\\x28\\xa2\\xc5\\x02\\x04\\x40\\x85\\xad\\x07\\xfa\\x5b\\xe1\\xda\\x7b\\x5f\\x46\\xf5\\x6f\\x2a\\x5c\\x7d\\xb1\\x38\\x75\\xd2\\x98\\x96\\x27\\x56\\xf0\\x6a\\xf0\\xed\\xbf\\x6e\\xff\\x3c\\xdc\\x7e\\xf3\\x97\\x00\\xc0\\x65\\xf2\\x54\\x1b\\xbb\\x82\\x3d\\xda\\x30\\x71\\xf1\\x12\\xcb\\x50\\xa5\\x7e\\x69\\xa3\\x19\\xff\\x2d\\xf0\\x4c\\x59\\xbb\\xcc\\x6f\\x9f\\x19\\x4c\\x0f\\xcf\\xf2\\x78\\x55\\xde\\x1f\\x16\\xb4\\x72\\x38\\xe8\\x86\\xbf\\xb9\\x74\\xa1\\x37\\x6b\\x3f\\xac\\x30\\x88\\x9d\\x9c\\x5e\\x1f\\x7d\\x38\\x1b\\x9f\\xc4\\x75\\x88\\x84\\x3d\\x1b\\x78\\x72\\x75\\x71\\x79\\x73\\x19\\x8b\\x95\\xdc\\xac\\x03\\xf8\\x71\\x7c\\x7e\\xa3\\x7c\\x64\\x75\\x8b\\xfb\\x2b\\x44\\x36\\xda\\x47\\x96\\xd7\\x4b\\x3f\\x59\\xb7\\x5a\\xf8\\xc9\\x0a\\x03\\xdb\\x0e\\x1b\\x9a\\xd9\\x9e\\xe9\\x1b\\xf8\\xdd\\xc5\\xd5\\xc7\\xbb\\xe3\\x1f\\x4e\\xcf\\x4e\\xe2\\xc0\\x0c\\xbe\\x37\\xa7\\xc5\\x4a\\x76\\x62\\x95\\x8a\\x1e\\x02\\x78\\x7e\\xf4\\xd3\\x87\\xa3\\xab\\xbb\\xf3\\xa3\\x9f\\xe2\\x20\\x22\\xe9\\xe7\\xfb\\xb4\\xd8\\x27\\xe9\\xe7\\x00\\xfe\\x74\\x7a\\x7d\\xfa\\xe1\\x4c\\x5e\\xb1\\x5e\\x37\\xbf\\xeb\\xd5\\x3f\\x31\\x43\\xab\\x98\\x50\\x16\\x46\\x7a\\x2d\\x80\\xf4\\xc8\\x9d\\x5c\\x5c\\xc6\\x01\\xa3\\xeb\\x7d\\xe9\\xc8\\x02\\x27\\x17\\x97\\xca\\x89\\x79\\xbd\\x2f\\x62\\xf4\\x3f\\x5c\\x4c\\x26\\x17\\x1f\\xe3\\xe0\\x9e\\x32\\x46\\x57\\x1a\\x4c\\x96\\xca\\xa8\\x7c\\x59\\x21\\xa3\\xf6\\xe7\\xc9\\x93\\x8c\\x32\\x8f\\x87\\x70\\x9e\\x63\\xe9\\x2d\\x7e\\x67\\x0a\\x8d\\xaf\\xb8\\xb2\\xd4\\xea\\xf3\\x03\\x02\\x09\\x6d\\xb9\\x7b\\x2f\\xbc\\x76\\xc6\\x54\\x85\\x14\\x7b\\xcd\\x89\\xf2\\xa8\\xbc\\xc0\\xc3\\x15\\x69\\xd9\\x93\\xaf\\x52\\x5d\\xfb\\x11\\x91\\x8d\\x26\\x5e\\xb5\\x3b\\xe1\\xb9\\x58\\x6e\\x05\\x95\\x21\\x86\\x66\\x4c\\x16\\x19\\x98\\x2e\\x97\\xd6\\x45\\x92\\xb6\\xed\\x5e\\x0b\\x8f\\xdd\\xab\\x56\\x5b\\xb5\\xd4\\xaf\\x77\\x69\\xa7\\x81\\x6a\\x16\\x69\\x14\\x07\\x9a\\xa4\\xa6\\x96\\x98\\xd8\\xa4\\xc5\\x96\\x82\\x88\\x8d\\x7c\\xc6\\x57\\xc0\\x69\\xd2\\x18\\x91\\xd2\\xe8\\x4e\\x78\\x1d\\xf1\\x55\\x29\\x43\\xc0\\x85\\x12\\xc5\\xe2\\x9b\\x9e\\x14\\x76\\xdb\\x95\\xe5\\x79\\x21\\xa5\\x1e\\x58\\x6a\\x1d\\xda\\x71\\xa0\\xe8\\x17\\x3b\\xf4\\x66\\xea\\x2a\\xc2\\x23\\x57\\x9a\\x9a\\x45\\xf2\\xe8\\x02\\xcb\\xf1\\xab\\x35\\x0f\\x7d\\x5a\\x85\\x5e\\xb8\\x03\\x46\\x5e\\xf0\\x03\\x61\\x74\\xd3\\x1e\\xae\\x06\\x93\\xd0\\x43\\x8f\\x84\\xd4\\x42\\x16\\x58\\xdb\\x57\\x05\\x88\\x42\\x28\\xf0\\x2a\\x87\\xb0\\xbe\\x13\\x92\\xbc\\x89\\xea\\xd3\\x0d\\x2c\\xf9\\x30\\xb8\\xa7\\xd9\\x63\\xe0\\x18\\x11\\x29\\x09\\x65\\xd4\\x81\\x0c\\xc7\\x10\\x88\\x8e\\x22\\x42\\xe9\\xba\\x69\\x51\\xd1\\xa1\\x5b\\x0d\\x5d\\xb2\\x1d\\xb1\\xe5\\x5a\\xbb\\xdc\\x95\\xb2\\xc5\\x53\\x85\\x18\\x50\\x6e\\x63\\xbb\\xc2\\x6c\\xad\\xbb\\xf9\\xe7\\xb0\\x04\\xd2\\x6e\\xb3\\x78\\xa5\\x7e\\x88\\x3d\\x66\\x0c\\x3a\\x9f\\x87\\xd4\\x17\\xce\\x65\\x1f\\x67\\xf1\\x5b\\x19\\x0b\\xec\\xdd\\xd4\\x76\\x75\\xc5\\x50\\x55\\xd4\\x72\\xd8\\xdc\\x72\\x21\\x05\\x2f\\xa2\\xcd\\x3a\\x4b\\x19\\xf2\\x78\\x6d\\xef\\xa4\\x07\\xcf\\x77\\x5b\\xce\\x96\\x28\\xdb\\xe4\\xe8\\x46\\xb4\\x1f\\x02\\xde\\xd7\\x8b\\x9d\\x2b\\x7d\\x9e\\x84\\x4b\\x29\\xeb\\x39\\x0e\\x8b\\x9e\\xc0\\x63\\x14\\x95\\x8c\\xae\\x2f\\x0b\\xba\\x4e\\x17\\xa9\\x6c\\x59\\xf8\\x0d\\x2a\\x33\\xbd\\x1c\\xc7\\x2b\\x54\\x64\\xe9\\x55\\x50\\x8b\\x55\\x91\\xea\\xaa\\xbd\\x69\\x4a\\xd4\\xef\\x74\\x31\\xed\\x6a\\x69\\x22\\xb2\\x42\\x10\\x3d\\x30\\x8b\\x38\\xfb\\x49\\xa7\\xc0\\xd9\\x57\\x91\\xc1\\x91\\x85\\x35\\x02\\xaf\\x85\\x1a\\xb9\\x11\\x64\\x81\\xab\\x44\\x95\\xe3\\x28\\xc8\\xc1\\xf4\\x60\\x2e\\xf3\\x74\\xd6\\x1a\\x8a\\x2d\\xd4\\x5a\\xf3\\xd7\\x9e\\x84\\x90\\x24\\x59\\x24\\xf9\\xe6\\xc8\\xca\\x69\\xd4\\xa4\\x69\\x5c\\x3d\\xcf\\xa2\\xc9\\xc5\\x25\\x7c\\x01\\xd9\\x12\\x5a\\xb8\\x80\\x1e\\x9f\\x9f\\x00\\x10\\xbf\\xfc\\x13\\xc3\\xc0\\xf5\\x12\\xdb\\x98\\xfc\\x12\\xa3\\x45\\x9d\\x51\\x41\\xca\\x23\\x41\\x7d\\x83\\x65\\x56\\xc9\\x22\\x91\\x9d\\x36\\x8b\\xa7\\x6a\\x14\\xe8\\x3a\\x4b\\x37\\xb3\\xb5\\x7e\\x29\\x3c\\x1c\\x92\\x68\\x4e\\xbc\\x88\\xa9\\x00\\x5c\\x47\\x14\\x53\\x0a\\x59\\xa3\\xa1\\xd0\\x54\\x81\\xed\\xf6\\x49\\x28\\xf9\\xb1\\x2e\\x4a\\x3c\\x1d\\x2b\\x8d\\xe7\\x69\\xad\\x37\\x3d\\xae\\x99\\x80\\x2e\\x0a\\x01\\x5c\\xd1\\x0c\\xcf\\x31\\x2a\\xca\\x58\\x4b\\x3b\\x44\\x0a\\x35\\x4f\\x88\\x08\\x5e\\x1e\\x3b\\x6d\\xf3\\x2a\\x2b\\xb1\\x8b\\x4b\\x5d\\xc4\\x55\\x8c\\x69\\x50\\xe6\\xb9\\xba\\x66\\x8f\\x39\\x4a\\x4c\\x63\\x7d\\xf7\\x8b\\x4a\\xa4\\xb2\\x68\\x07\\x0b\\xbe\\x4a\\x7b\\x27\\xae\\x73\\x0f\\xe6\\xaa\\x59\\x5b\\x45\\x3f\\x64\\xc2\\x56\\xc0\\x99\\xba\\xcc\\x6a\\x24\\x72\\x03\\xf8\\x7d\\x72\\x30\\x24\\xaf\\x53\\xbd\\xc9\\x2b\\x55\\x6f\\x52\\xab\\xde\\x8e\\xc0\\xd2\\x72\\x5a\\x66\\xdb\\xed\\xb7\\x9c\\x34\\x4b\\x5f\\xe4\\xc1\\x20\\x94\\xfa\\x43\\x20\\xca\\x78\\xe7\\xdb\\xed\\x5f\\x13\\x53\\x0f\\x40\\x9d\\x28\\xce\\xbd\\xe1\\x73\\xef\\x82\\xf9\\x0a\\x0d\\x47\\xe5\\x3b\\x6d\\xd8\\x19\\x95\\xda\\xc8\\x5d\\x74\\x12\\x21\\x72\\x5b\\x4e\\x01\\xa4\\x09\\x92\\x7f\\x99\\xb5\\xce\\x9b\\x82\\x15\\xaf\\xae\\x54\\xa4\\xbb\\xbc\\x6d\\xa2\\xf2\\x68\\x4b\\x79\\xaa\\x68\\xcb\\x6d\\x83\\x41\\x3f\\x64\\x7c\\x6e\\x52\\x21\\x4b\\xf4\\xdc\\x06\\x83\\x97\\xfa\\x6c\\x6f\\xb7\\x6a\\x5d\\xac\\x6f\\xed\\x75\\x19\\x0c\\x50\\x1d\\x7b\\x5e\\x40\\x13\\x54\\x6b\\x6e\\x91\\x6a\\xfe\\xcf\\x35\\x4b\\x98\\x2b\\x0b\\x80\\x16\\x0f\\xe6\\x00\\xce\\x3b\\x32\\xce\\x84\\xaf\\xf2\\xa9\\xf7\\x89\\x47\\xf3\\x79\\xb7\\x7c\\xc4\\x17\\x73\\xb7\\x00\\x14\\xcc\\xd3\\xbc\\x44\\x01\\xc7\\xe0\\xcc\\xb5\\xe3\\xd7\\xc2\\x4f\\xe1\\xad\\xf0\\x08\\x3f\\x52\\x91\\x86\\x39\\x50\\xe2\\x4f\\x07\\x32\\xb4\\x8d\\x76\\x70\\x97\\xab\\x97\\x31\\xf8\\x60\\x41\\xc6\\x95\\xa3\\x17\\x80\\x64\\xbb\\x65\\x8a\\xd1\\x9c\\xd3\\x0c\\x89\\xee\\x94\\x13\\xd2\\x8f\\x52\\xa7\\xf6\\x39\\x96\\x89\\x98\\x9f\\x7e\\xae\\x31\\x41\\x6e\\xf0\\x76\\xfb\\x56\\x06\\xa7\\x77\\xa2\\xc8\\x60\\xf0\\xed\\x37\\x35\\x46\\x6c\\xb7\\x2f\\x47\\xad\\xd0\\xe7\\xcb\\xef\\x13\\x4c\\x38\\x81\\xd2\\x2a\\x90\\x96\\xdf\\x3b\\x14\\x1f\\x73\\x6f\\xb7\\x8b\\xe7\\x4b\\x8d\\x87\\xf8\\x15\\x9d\\x10\\x6f\\xb7\\xdf\\xfc\\x25\\xb1\\x68\\x83\\x3d\\x3f\\xce\\x30\\xfb\\x02\\xa2\\xef\\x40\\xf4\\x2d\\x5a\\x61\\x4c\\x9f\\xc4\\xc8\\x10\\x8e\\x62\\x0e\\xf8\\x86\\xca\\x7b\\x3f\\xed\\x30\\xaf\\x89\\x84\\x15\\x46\\xa0\\x8f\\xd2\\xe8\\xdb\\x7f\\xb5\\x07\\x53\\xbc\\x1f\\x0e\\x06\\xc5\\xfe\\x3e\\xfc\\xf3\\xd0\\x29\\x7e\\x57\\xfb\\xde\\x0f\\x06\\xc5\\xde\\x1e\\x2c\\xde\\x0d\\x07\\x83\\xb0\\x48\\x86\\x00\\x96\\xb7\\xc5\\x54\\xeb\\x00\\x55\\xa5\\xc3\\xad\\xec\\x49\\xd6\\x99\\x36\\xea\\x31\\x37\\x33\\x72\\xb8\\x89\\x21\\x64\\xce\\x14\\x50\\xe9\\xdd\\xa8\\x33\\x46\\x08\\x5a\\xa3\\xdc\\xf3\\xd2\\x3f\\xdc\\xfa\\x39\\x6f\\x02\\x72\\x41\\xb1\\x0b\\xf8\\x4e\\x98\\x4a\\xd3\\x6e\\x53\\xe9\\x32\\x6a\\x9a\\xa1\\x1a\\xc6\\xd2\\x45\\xc7\\x49\\xea\\xfe\\x9a\\xcb\\x5a\\xcf\\x7d\\xe6\\xda\\xc9\\x84\\xe3\\xb1\\x68\\xcb\\x32\\x70\\xf1\\x26\\x6a\\x7e\\xe6\\xfd\\x6e\\x87\\x5d\\xf7\\x85\\x27\\x6d\\xd1\\xe9\\xf0\\x21\\x8f\\x4d\\x23\\x05\\x83\\x67\\x00\\xb5\\x31\\xab\\xd1\\x7f\\xab\\x33\\xcb\\x54\\xdb\\xee\\xd6\\x6b\\xaa\\x5d\\xbc\\xce\\x54\\x9b\\x7a\\xa6\\x53\\xc1\\x45\\x15\\x02\\xd7\\x6b\\x4d\\x59\\x50\\x57\\x34\\x4b\\x65\\xa6\\x84\\xe8\\xbe\\x8c\\xd4\\x2f\\xc7\\x03\\xf1\\x3e\\x9d\\x7d\\xca\\x0a\\xba\\x8e\\xfb\\x43\\x27\\x3d\\x82\\x38\\x0a\\x22\\x4f\\xc2\\x92\\x3e\\x08\\x13\\x57\\x6a\\x01\\x7b\\x92\\x1c\\x78\\x12\\x22\\xc8\\x36\\xac\\x04\\x09\\xbc\\x29\\xcb\\xfe\\x95\\xdb\\xa6\\x59\\x6b\\x80\\x6d\\x27\\x44\\x55\\xe1\\xfa\\x39\\x5a\\x85\\xb6\\x93\\xa3\\x2a\\x16\\x99\\x2d\\x4e\\xcf\\x55\\xea\\x20\\x6c\\x57\\x5d\\x8d\\xaf\\x4f\\xff\\x63\\x1c\\x07\\x05\\x2a\\xf1\\x7f\\xdb\\x1d\\xab\\x9d\\x57\\x29\\xa4\\x94\\x65\\x57\\xa5\\x90\\xb2\\xc0\\xcc\\x81\\xd0\\x80\\xda\\xa8\\xdb\\x06\\x15\\xe1\\x76\\x1c\\xe3\\x35\\xa8\\xe0\\xdd\\x9b\\x75\\x17\\xa8\\xdb\\xae\\x00\\xee\\x68\\xb9\\xd3\\x0c\\x2d\\xea\\x9b\\xae\\x98\\xc7\\x57\\x17\\x67\\x67\\x1f\\x8e\\xae\\xee\\x3e\\x8e\\x8f\\xae\\x6f\\xae\\x64\\xd6\\x87\\x2c\\xcd\\xf7\\xa5\\x43\\xcc\\x7d\\x5a\\xec\\xaf\\x50\\x5a\\x6e\\x0a\\x14\\xc0\\x0f\\x47\\xc7\\x3f\\x72\\x4d\\x4d\\x83\\xe8\\x5d\\x0f\\x20\\xd7\\xc1\\x74\\x29\\x5d\\x23\\xb2\\x23\\x2b\\xa0\\x30\\x4e\\x1f\\x9d\\x5d\\x7c\\x1f\\x07\\x72\\x44\\xfb\\x19\\x4e\\x73\\xba\\xdb\\x0b\\x53\\x4e\\x4d\\x27\\xa1\\xea\\x4a\\xe5\\x65\\xa0\\xbe\\x3b\\xfd\\xf7\\xf1\\xc9\\xdd\\xf1\\xc5\\xf9\\x64\\x7c\\x3e\\x89\\x83\\x68\\x8e\\xbf\\xa0\\x6c\\x9f\\xd1\\x35\\xec\\xa9\\xbf\\xa5\\xe1\\x16\\xf6\\x22\\x5c\\xee\\x8b\\x12\\xd8\\x8b\\x4a\\x86\\x67\\x9f\\x1e\\x39\\x58\\x00\\xaf\\x27\\xa7\\xc7\\x3f\\xfe\\x62\\x35\\x61\\x57\\x2a\\x9b\\x95\\x1c\\xea\\x55\\x6d\\x95\\x96\\xa3\\x2d\\x84\\x3d\\xfc\\x59\\x47\\xd1\\x97\\x26\\x20\\xd0\\x06\\x5e\\xb9\\x4a\\x96\\xae\\xce\\x05\\x01\\xbe\\x8e\\x56\\x7e\\x01\\xbd\\x21\\x8d\\xa0\\x5a\\x7e\\x00\\xec\\x1c\\x09\\x1f\\x68\\xf6\\x78\\xf1\\x19\\x15\\xf3\\x9c\\x3e\\x38\\x3e\\xaa\\x78\\x41\\x68\\x81\\x3e\\xa8\\x56\\x84\\x0b\\x77\\x5d\\x49\\x0b\\xbc\\xc0\\x24\\xcd\\xf9\\xd7\\x97\\x69\\x26\\x42\\x30\\xb4\\x1b\\x9a\\x41\\x96\\x9f\\x71\\xc6\\x96\\xc9\\x50\\x98\\x80\\x37\\x3e\\xd7\\xc7\\x4d\\xcb\\x04\\xdc\\x0a\\x4a\\x94\\x03\\xee\\x70\\x77\\x64\\xa0\\x82\\x9b\\x86\\xbf\\xa3\\x1b\\x37\\xbe\\xcb\\xe1\\xd1\\xe9\\x01\\x3c\\x7d\\x55\\x8c\\xcf\\x52\\xa6\\x1d\\xac\\xc3\\xe6\\x9b\\x1e\\xbf\\x43\\x73\\x4f\\xe8\\x78\\x27\\xb6\\x82\\xf0\\x2a\\x8f\\x37\\x99\\x49\\x13\\x08\\xdc\\xed\\xdb\\x6e\\x71\\x97\\xe6\\xd0\\xd8\\x66\\xbd\\x25\\x22\\x0d\\xd6\\xb5\\xde\\x17\\x3b\\x66\\xaa\\x5d\\x98\\x66\\xbf\\x6e\\x4a\\x76\\x22\\x30\\x4c\\x04\\x3f\\x18\\xe5\\x83\\x2b\\x1a\\x8e\\xf7\\x0e\\x3f\\xe9\\x56\\x5b\\xe3\\x72\\x96\\xae\\x55\\x60\\x97\\x55\\x7c\\x25\\x08\\xa8\\x2e\\xf6\\x99\\xee\\xcc\\x35\\xad\\x4a\\xba\\x37\\x8b\\xec\\xa3\\x0d\\x3d\\xd8\\x41\\x24\\x32\\x30\\xc1\\x4b\\x43\\xfb\\x50\\xa8\\x06\\x5b\\x74\\xd2\\x8d\\x2c\\x20\\x0d\\x0f\\x21\\xf5\\x41\\x4d\\x83\\x61\\x23\\x7b\\xa3\\x9d\\x8e\\xdb\\xfa\\x98\\x6b\\x1f\\x1d\\x47\\x65\\x28\\x2f\\x65\\xd5\\x32\\x2c\\xe9\\x83\\xae\\xf7\\xc4\\x4e\\x11\\x09\\x61\\xe5\\x93\\xe4\\xda\\x12\\xdc\\x34\\x5c\\xfc\\x5a\\xb8\\xcd\\x7c\\x17\\xd3\\xb0\\x0b\\xe3\\x1b\\x08\\xdf\\xc4\\xcb\\xe7\\xbd\\xfc\\x9a\\x88\\x38\\x18\\xf4\\xfd\\x98\\x68\\xc5\\xed\\x29\\x7a\\x33\\xd2\\x52\\xfe\\xd7\\x1f\\xb2\\x51\\xb1\\xeb\\x98\\xbd\\x1a\\x0d\\x2d\\xe9\\x77\\x3e\\x0f\\xf3\\x48\\x89\\x02\\x1e\\x0c\\xf5\\x79\\x01\\x7a\\x4d\\xf2\\x0d\\x3c\\xf6\\xa0\\xa6\\x00\\x6a\\xe1\\x26\\x80\\xc5\\x0b\\x1d\\xd7\\xbc\\x47\\xe1\\x8e\\x63\\xc9\\x47\\xce\\xef\\x04\\xe6\\xf8\\x5d\\xdb\\xbe\\x1d\\x9a\\xec\\xa5\\x35\\xb8\\xd0\\x55\\x36\\x5f\\x91\\x51\\x4e\\x72\\xd7\\x3a\\x96\\x07\\xea\\xd5\\x74\\x19\\x56\\x83\\x15\\xc9\\x05\\xd8\\xe1\\xf0\\xe6\\xb9\\xca\\x50\\xac\\xce\\x2a\\xd9\\xc5\\xd8\\x9c\\xa2\\x26\\x6b\\xb3\\x2b\\x3d\\x27\\xd6\\xaa\\x6e\\xb0\\x30\\x79\\x17\\xb2\\x51\\xe9\\xf6\\x6f\\x3a\\x6e\\x44\\x5c\\xc2\\xc9\\xe1\\x5f\\xed\\x6a\\xb7\\xcb\\x9f\\x6e\\xe3\\xd0\\x88\\x0e\\xa2\\x20\\x8c\\x26\\xbf\\xe1\\x88\\xb9\\xd7\\x64\\xb5\\x21\\xa5\\x99\\xf2\\xb0\\xae\\x31\\xe9\\xca\\x93\\x24\\x11\\xbf\\xc7\\x67\\xe3\\x8f\\xe3\\xf3\\xc9\\xdd\\xf9\\xc5\\xc9\\x78\\xbb\\x75\\x98\\x47\\x94\\xae\\xd7\\x88\\x64\\xc7\\x4b\\x9c\\xfb\\x33\\xea\\xb8\\xce\\x9e\\x02\\x2f\\xf3\\xf4\\x31\\x09\\xee\\x73\\x3a\\xfb\\x14\\x34\\x60\\x24\\x82\\x36\\xcd\\x58\\xca\\x61\\xa3\\xd5\\xa0\\xd8\\xd1\\x09\\x5d\\x27\\x43\\x88\\x07\\x83\\xaf\\x71\\x18\\xb6\\xdd\\x7f\\xb5\\xed\\x9a\\x6b\\x0d\\x66\\x6d\\xc8\\x9c\\x16\\x33\\xf4\\x9d\\xb4\\x36\\x28\\x82\\xe7\\xb2\\xfd\\x73\\x0f\\xdf\\xb7\\xd3\\x84\\x83\\x27\\xd2\\x6c\\x9b\\xb4\\xef\\x32\\x89\\x37\\xb2\\xc8\\x65\\x6a\\xf5\\x05\\x73\\x35\\xc2\\x87\\x6d\\x16\\xe9\\xa1\\x2d\\x74\\x17\\xe5\\xa0\\x0a\\xa3\\xed\\x49\\x76\\x5e\\xce\\x75\\x91\\x56\\xc9\\x9a\\xd5\\x2f\\x68\\x1f\\x09\\xfd\\x45\\x92\\x24\\x44\\xb1\\xda\\xed\\xb6\\xf6\\x26\\x76\\x8a\\x5d\\x37\\xe3\\x65\\xca\\x19\\xb2\\xe6\\xce\\x3a\\x8e\\x84\\xb5\\x56\\xad\\x92\\xe3\\x77\\xf9\\xc3\\xce\\xdc\\x2d\\x86\\xc9\\x39\\x5b\\xae\\x35\\x58\\x1f\\xc1\\x0e\\xf3\\xa8\\xa1\\xf5\\x39\\xb7\\x91\\xc2\\xec\\x84\\x8c\\xdd\\xdd\\x9b\\x15\\x59\\xca\\xb8\\xa0\\xd2\\xb4\\xda\\x88\\x7c\\x1d\\x0c\\xa7\\xd1\\x9f\\x99\\xa4\\xc5\\xed\\x5e\\x32\\xc9\\x43\\x27\\x28\\x33\\x8f\\xa4\\xf2\\xeb\\x4f\\xfe\\x62\\x53\\x41\\x91\\x03\\x26\\xb6\\x3e\\x16\\x83\\x92\\x5f\\xcb\\xb1\\x18\\x66\\xb3\\x73\\x18\\x1d\\xe7\\x9e\\x50\\x82\\x9a\\xc7\\xde\\x63\\xba\\x56\\x67\\xbe\\x8e\\x53\\xe9\\x8e\\xbc\\xeb\\x12\\xc4\\x5a\\x62\\xae\\xcb\\xf4\\x95\\xa4\\x1b\\xdd\\x15\\x88\\xf7\\x2f\\x28\\x3d\\x07\\x16\\xae\\x05\\xaa\\xd4\\x16\\xa5\\xbb\\xc2\\x50\\xb4\\x6f\\xbb\\x5c\\x1b\\xd9\\x87\\x1e\\x4e\\x9b\\xa3\\x68\\x4e\\x67\\xb9\\x77\\xd4\\xac\\x54\\xa7\\x0c\\xf7\\x71\\x45\\x60\\xd8\\x45\\xbb\\xf1\\x26\\xbf\\x78\\x96\\x29\\x1c\\xca\\xff\\xe3\\x20\\x18\\xd9\\xa9\\xaf\\x3c\\x67\\xc3\\x0c\\xee\\xe9\\x59\\x69\\x0f\\xd7\\x6d\\x99\\x91\\x77\\xbd\\x40\\x93\\xe1\\xcf\\x41\\x73\\x9a\\x32\\x03\\xf0\\x79\\xba\\x42\\xc9\\x32\\xd2\\xb6\\x08\\x4e\\xd9\\xdb\\x0b\\xe5\\xa6\\x52\\x68\\xd5\\x0a\\x96\\x34\\xa1\\x8d\\xfd\\x7f\\x91\\x9e\\x62\\xaf\\xa9\\x5f\\x0d\\x38\\xec\\xd2\\x0e\\x0e\\x62\\xad\\x52\\xb4\\xbd\\x4e\\x07\\x83\\x30\\x28\\x59\\xca\\xf0\\x4c\\xa4\\xc2\\x6d\\x2d\\xef\\x61\\x9b\\x27\\xc4\\xa4\\xa6\\x1c\\xb0\\x68\\xf1\\x37\\x33\\x5d\\xdf\\x02\\x34\\x39\\x5c\\x5f\\x67\\x22\\x93\\xee\\xc7\\x3a\\x6b\\x8e\\xcc\\x44\\x66\\x45\\xb1\\x59\\x52\\x9d\\x8f\\x9d\\xb0\\x1d\\x69\\xf4\\xab\\x46\\x62\\x90\\x06\\x3a\\xd5\\x78\\xd4\\x85\\xf6\\xae\\x37\\xb9\\xb4\\xe0\\xbb\\x5c\\xd4\\x3d\\x5b\\xa1\\xc8\\xb1\\xcc\\x42\\x50\\x7d\\x5d\\x2e\\x8f\\x65\\xfd\\xbc\\xc0\\x4b\\xe6\\xde\\xc5\\x4a\\xc5\\x13\\x02\\x54\\xe7\\x45\\x50\\x23\\xe2\\x47\\xd5\\x96\\x1d\\xfd\\x84\\xb2\\x29\\xca\\xc8\\xd7\\x6b\\xde\\x77\\xdd\\x0c\\x46\\x33\\x11\\x27\\x25\\xa1\\x46\\xfd\\x0e\\x91\\x78\\x30\\x60\\x46\\xa7\\x72\\x49\\xf0\\x5a\\x1a\\x75\\xce\\xd0\\x5c\\x77\\xef\\xca\\xc4\\x22\\xee\\x0a\\x74\\x89\\xda\\x83\\x41\\xff\\x99\\x86\\xaf\\xf8\\xb8\\x76\\xb4\\xac\\xe8\\xa3\\x4b\\x6c\\xdb\\x14\\xb2\\x7b\\xd0\\x41\\x8b\\x6f\\xb4\\xbb\\x0f\\x02\\xd1\\x8d\\x6b\\x1d\\x69\\x2f\\xbf\\x2b\\xc3\\x76\\xc4\\xa2\\x8d\\xba\\xb4\\x0e\\x16\\xe5\\x68\\xce\\xf6\\x58\\x24\\xbc\\x67\\xdf\\xa9\\x27\\xb8\\x30\\x21\\x48\\xce\\xd7\\xaf\\x72\\x18\\x53\\xe0\\xb5\\x53\\x1e\\x1a\\x06\\xbf\\x63\\xbc\\xc6\\x3a\\xe0\\x1f\\x11\\x3f\\x55\\xb3\\xc8\\x31\\x8b\\x36\\x1d\\xd3\\xc5\\xeb\\x42\\xfa\\x2e\\x4f\\x5c\\xad\\x7a\\x96\\x0f\\xca\\x04\\x1b\\x32\\xef\\xa7\\xaa\\x50\\x2e\\xc2\\x9c\\x48\\x60\\x9d\\xe5\\xdb\\xad\\x82\\xa5\\xf7\\x0b\\xb8\\x4e\\x8b\\x12\\x7d\\x97\\xd3\\x94\\x85\\x05\\xd8\\x63\\x1d\\x58\\xc1\\x09\\xd8\\x2c\\x72\\x0d\\xb2\\x2f\\x1e\\xfc\\x2a\\x2d\\x16\\x98\\xb4\\xc7\\x2e\\xcb\\x7d\\x43\\x77\\x6a\\xcc\\xc8\\xdd\\x52\\x67\\xe0\\xfb\\xbb\\x07\\xee\\x1a\\x8b\\xff\\x37\\x0d\\xbc\\x7b\\xc5\\x55\\x66\\x2d\\xf7\\x10\\x78\\xb0\\x81\\x4b\\x12\\xc6\\x17\\xc1\\x8f\\x12\\xba\\xda\\x8b\\x17\\xe4\\x59\\xbc\\xc0\\x60\\x6f\\x07\\xc1\\xa8\\x29\\x86\\xf7\\x68\\x3c\\x8b\\xf3\\x56\\x1e\\x36\\x71\\x17\\xec\\x1b\\x24\\x18\\xf9\\x82\\xc3\\xb0\\x8a\\x62\\xf2\\x0d\\x1f\\x03\\xdb\\x90\\xd2\\x6c\\xce\\x8b\\xcf\\x7b\\x01\\xec\\x05\\x7b\\xcf\\x21\\x8b\\x7f\\xb8\\x0d\\x8c\\x78\\x76\\xb4\\x2e\\x46\\x34\\x06\\xeb\\x36\\x56\\xe9\\x88\\x8b\\xdd\\xfb\\xe8\\xef\\xd4\\xf5\\x54\\xf1\\xac\\x13\\xdb\\xbd\\x4e\\xca\\x98\\xe2\\x12\\xc3\\x1d\\x94\\xda\\x27\\x41\\x8e\\x98\\x23\\x34\\xb6\\x6f\\xbb\\xe0\\x0e\\x63\\x05\\xd0\\xcf\\x4a\\x75\\xd1\\xff\\x48\\xe4\\x1b\\xd9\\xd7\\x8c\\x57\\x0c\\xd0\\xa4\\x78\\x70\\xda\\x55\\x12\\x8c\\x6a\\x17\\xa2\\x67\\x62\\xcd\\xe0\\x0b\\x1e\\x61\\x28\\xdb\\x8f\\x30\\x68\\x0b\\x5d\\xe1\\x58\\x99\\x70\\xc3\\x3d\\x15\\x3c\\x1f\\x80\\x56\\x3f\\x19\\xa4\\xe2\\xc9\\x0a\\xcf\\x33\\x0e\\xea\\xba\\xb1\\x7c\\x9d\\x8f\\x5b\\xf9\\x4a\\x1f\\x37\\x0e\\x1f\\x12\\x25\\x3d\\x15\\xe2\\xe2\\x47\\x24\\x73\\x5e\\xd2\\x07\\x5e\\xfc\\xbf\\x36\\xea\\x6c\\xd6\\xe9\\x9d\\xa0\\x3d\\x9d\\xe4\\xc2\\x3e\\x17\\x42\\x56\\x28\\x67\\xa7\\x42\\x38\\x3b\\x8d\\x2c\\xc7\\x95\\xe6\\xb6\\xd7\\xe1\\x63\\x6e\\x52\\x2b\\xd2\\x95\\xd4\\x6a\\x14\\x1c\\x05\\xda\\x61\\xdb\\x04\\xbd\\x05\\x47\\x57\\xe3\\x56\\xb1\\xf0\\xb0\\xf2\\xc5\\xc2\\xa5\\x72\\x28\\xf2\\x3a\\x45\\x5c\\x72\\xb9\\x7e\\x10\\xfe\\x2b\\xab\\x54\\x7d\\xa0\\xfc\\xc4\\x1c\\x8a\\x8d\\xdb\\x09\\xc8\\xb1\\x65\\xcf\\x01\\xa3\\xcd\\xae\\x57\\x33\\x64\\xb8\\x82\\xed\\x6d\\xd1\\x06\\xf7\\x7a\\x5b\\x6c\\x5e\\x1b\\x18\\xd7\\x6e\\xb7\\x82\\x9b\\x2a\\x04\\x6e\\xd6\\xfb\\xaf\\x09\\x8c\\x63\\x94\\xe6\\x0c\\xaf\\xcb\\xaf\\x09\\x8c\\x53\\xdf\\xca\\x27\\x2f\\xee\\xcb\\xc8\\xfc\\xb6\\x9f\\xbe\\xb0\\xe3\\xe1\\xc2\\xff\\xdc\\xfe\\xed\\x6f\\x25\\xb8\\x2f\\xf7\\x15\\xe8\\xdf\\xfe\\x76\\xbd\\x17\\xc0\\x60\\x11\\x08\\x9f\\xcc\\x94\\xe0\\x95\\xf0\\x60\\xb1\\x9c\\x35\\x18\\x5a\\xad\\xb9\\x9a\\x13\\xeb\\x53\\x0f\\x19\\x66\\x39\\x6a\\xa5\\xa0\\xb2\\x03\\x9c\\x94\\x35\\xa4\\xfe\\x24\\x43\\x79\\xfa\\x58\\x87\\x44\\x49\\x4a\\x04\\x02\\xb8\\x64\\xab\\xdc\\x76\\x0c\\x51\\xe7\\xc2\\xf7\\x46\\x46\\xed\\x92\\x6c\\x2a\\xad\\x1e\\xfd\\x41\\x57\\x20\\x80\\xca\\x81\\x13\\x15\\xed\\x01\\xd7\\x6d\\xcf\\x53\\xce\\x72\\x66\\x9f\\x2e\\xdb\\x7d\\xa4\\x22\\x9b\\x8a\\xf4\\x9e\\x38\\xba\\x99\\x5c\\xc4\\x41\\xba\\x61\\x54\\x04\\x8f\\x89\\xc8\\xb1\\xc6\\x2b\\x1c\\x8d\\x18\\x32\\xe7\\xbd\\x0e\\xe1\\x0c\\x51\\x2f\\x71\\x7f\\x58\\xaf\\xed\\x9b\\x77\\x19\\xfe\\xdc\\x13\\xbc\\xab\\xde\\xd5\\x5e\\x41\\x73\\x54\\xff\\x7c\\x6f\\xc3\\xa4\\x45\\x41\\x1f\\x82\\xf7\\xef\\xde\\x66\\xf8\\xf3\\x7b\\xcf\\xc7\\xfb\\x42\\xfb\\x30\\x00\\xe2\\xdf\\x37\\xf5\\xbe\\x88\\x0c\\xd3\\x3d\\xe9\\xe6\\xa6\\xf7\\x53\\xef\\xd2\\x50\\xee\\x8a\\x48\\x06\\xa9\\xb6\\xa3\\x7f\\x60\\x2f\\xbf\\x98\\xb5\\x09\\x7d\\xab\\x17\\xb8\\x7f\\xe0\\x5b\\xc8\\x79\\x8e\\xd7\\x32\\x64\\xd0\\x0e\\x48\\xbc\\xb8\\x99\\xc4\\x01\\xdd\\x30\\x19\\x99\\x67\\x07\\x66\\xe2\\x56\\x60\\x26\\x76\\x02\\x33\\x71\\x23\\x30\\x13\\xc3\\xd3\\xf3\\xeb\\xf1\\xd5\\x64\\x7c\\x12\\x07\\x98\\x94\\xa8\\x60\\x48\\x3c\\x47\\xe2\\x86\\x6b\\xe2\\x96\\x1f\\x90\\x29\\x13\\x43\\x11\\x85\\x7c\\x3c\\x5f\\xf7\\x24\\x8a\\x88\\x06\\xec\\xf4\\x81\\xb9\\x4b\\x9e\\x26\\x17\\x17\\x67\\x93\\xd3\\xcb\\x38\\xa8\\xcf\\xa8\\x2a\\xba\\x3b\\x3d\\x3f\\x17\\x5e\\x25\\xee\\xce\\xc1\\xa3\\xab\\x2b\\xde\\x44\\x24\\x77\\xba\\x82\\x8b\\xe4\\xe9\\x87\\x8b\\x9f\\x38\\xa4\\x7a\\xa1\\xc6\\x79\\xdf\\xcd\\x9d\\x2e\\xfc\\x78\\x74\\x7e\\x73\\x74\\x16\\x07\\xab\\x94\\x6c\\xd2\\x3c\\xa8\\xe0\\xaa\\xf3\\x71\\x0e\\x54\\xdf\\xe4\\x8e\\xa5\\xbf\\x7d\\xed\\x54\\xc0\\x54\\x9a\\x6d\\xfd\\x5b\\xf4\\x2c\\x9e\\x03\\xa8\\x95\\x6f\\x99\\xb0\\x7d\\x22\\x31\\x2b\\xd1\\xe1\\x32\\xed\\x00\\xc5\\x86\\x83\\xcb\\x33\\xe1\\x8a\\x0c\\x3b\\x97\\x7f\\x25\\x6a\\x45\\x1c\\xae\\x7c\\x8f\\x68\\xac\\x22\\x19\\x33\\xe0\\x7b\\x82\\xa2\\x9e\\x5d\\x05\\x57\\xda\\xe5\\x76\\x27\\xe0\\x01\\x07\\x94\\x5c\\x56\\x97\\xed\\x02\\x6f\\x14\\xd4\\x1f\\x77\\x64\\x48\\xd6\\x80\\xa0\\x4e\\xa6\\xa0\\xf2\\x4c\\x38\\x21\\x42\\x5c\\xae\\xf8\\x71\\xfc\\x8b\\xb4\\xe3\\xba\\x66\\x44\\x93\\x36\\xcb\\x7e\\x87\\xab\\xd1\\x40\\xf3\\x9b\\x3a\\xac\\xef\\x44\\xbd\\x55\\x5e\\x07\\xf6\\x75\\x76\\x20\\xd2\\x8d\\xe2\\xc6\\x66\\x47\\x33\\x69\\xe8\\xf4\\x97\\x73\\x70\\x5c\\xfe\\x8c\\xd9\\xf2\\xc8\\xae\\x0c\\xc1\\x21\\x8e\\xee\\xc4\\x89\\x0a\\xc5\\x06\\x63\\x10\\xe3\\xe8\\x4e\\x1c\\x24\\x5d\\x60\\xbc\\x78\\x95\\x2d\\x6e\\x81\\xd8\\x04\\xaf\\x4d\\xb8\\xaa\\x65\\xb4\\x9b\\xab\\x7c\\x46\\x8e\\x01\\x53\\xcc\\xcf\\x6a\\x50\\x4a\\x56\\xfa\\x06\\xcf\\x74\\xcc\\xd4\\xbb\\x94\\x2b\\xdf\\xe5\\xb8\\x9b\\x84\\xde\\x3e\\x0c\\xbe\\x97\\x13\\x9c\\xbb\\x70\\xdf\\xe6\\x19\\xab\\xac\\x73\\xb7\\xd3\\x02\\x1f\\xff\\x34\\x3e\\x9f\\xf8\\xe1\\xeb\\x18\\x24\\x25\\xff\\xc9\\x10\\x00\\xd7\\x63\\xb2\\x3e\\x3c\\xc6\\xd2\\xc9\\x70\\xfb\\x22\\xa1\\xc6\\x59\\x3b\\xc9\\x4c\\xfb\\xd1\\x1c\\xeb\\xb8\\xb7\\x5e\\x68\\xd0\\x07\\xfe\\xb7\\x87\\x20\\xba\\xe4\\xa1\\x2e\\x69\\xf9\\x0e\\x68\\x9a\\xc0\\xb7\\x6c\\x77\\x06\\x3c\\x79\\xab\\x94\\x98\\x17\\x6c\\xdc\\x07\\x6c\\xd4\\xdd\\x53\\xd0\\x7e\\xd1\\x3a\\xb8\\xcc\\x51\\x5a\\xa2\\xde\\xa6\\x44\\x3d\\xde\\x43\\x8f\\x92\\x9e\\x92\\x4c\\x7b\\xaa\\x8d\\x32\\x68\\xba\\x7b\\xb5\\x77\\x51\\x3c\\x3c\\x6d\\x7c\\xee\\x45\\xbd\\x3c\\x09\\xc7\\x94\\x30\\x81\\xc2\\xb5\\xa7\\x8e\\xa6\\x01\\x4f\\xcd\\xa1\\xd6\\x1e\\x39\\xe6\\x9e\\xd9\\x04\\xa3\\xd8\\x90\\x11\\x7d\\x20\\xa8\\x38\\xe9\\x30\\x12\\x3b\\x8b\\x2b\\x53\\xe7\\x76\\x48\\xe9\\xe6\\x1a\\x40\\x49\\xfa\\xbe\\x93\\x07\\x73\\xa9\\xbf\\xdc\\x9c\\x9e\\xb4\\xa7\\x7d\\x7e\\xf4\\x71\\x0c\\x46\\x69\\xe3\\xf6\\x0e\\x67\\x01\\xd4\\x6f\\xd3\\xec\\xb8\\xdf\\xcb\\x50\\x39\\x2b\\xf0\\x3d\\xca\\xee\\x1f\\x6b\\xf8\\x52\\xb0\\x05\\x66\\x79\\xf9\\xa8\\x6b\\x12\\x23\\x44\\xa9\\xcc\\x92\\xe6\\x82\\x63\\xae\\x9c\\x1c\\xf8\\x14\\x96\\x49\\x57\\xb0\\x9d\\xce\\xb0\\xa3\\x85\\x94\\x43\\x6f\\xa9\\x4a\\xbd\\x21\\xf2\\xab\\xb8\\xcb\\x18\\x7b\\xe1\\xa1\\x95\\x12\\xf0\\x88\\xb1\\x74\\xb6\\x14\\x8b\\xb6\\x54\\xa4\\x27\\xcd\\xb2\\xba\\x54\\x05\\x66\\xe8\\xcc\\x7a\\xfd\\x03\\xfd\\xd8\\x87\\x6a\\xd4\\x08\\x55\\x87\\x8e\\x61\\x41\\x07\\x3d\\x36\\xa1\\xc0\\x48\\x2c\\x43\\x66\\x08\\x92\\x97\\x81\\x30\\xf9\\x3e\\xe3\\xd7\\xa3\\x11\\xa7\\x25\\xdb\\xad\\x5c\\x71\\x73\\xa7\\xd6\\x26\\x55\\x1a\\x73\\x3b\\x0e\\x86\\x16\\xd7\\xbc\\x01\\xe8\\x0e\\x39\\x4d\\xa1\\x15\\x88\\x38\\xf3\\x44\\x1d\\xea\\xff\\xed\\x45\\x91\\x45\\x95\\x8a\\x47\\xbc\\x47\\xcb\\xf4\\x33\\xa6\\x85\\x03\\xd2\\x92\\x52\\x2b\\x28\\xa4\\xac\\xf8\\x49\\xf5\\x1c\\xdf\\x45\\x42\\xfc\\xaa\\x2a\\x48\\xc9\\xb1\\x30\\x34\\xc5\\x6e\\xd0\\xb1\\xf6\\x8e\\x35\\x4d\\xf4\\x93\\x04\\xd5\\xb8\\x30\\x18\\x98\\x37\\x94\\xa5\\x3a\\x67\\xe0\\x8e\\xc5\\x9b\\xa3\\xe2\\x49\\x12\\x4a\\xe4\\x0d\\xbb\\xd3\\xf4\\xf3\\xdf\\x09\\x8b\\xa2\\x8b\\xf4\\xf2\\x56\\xef\\x37\\xc7\\x94\\x75\\x87\\xdc\\x8f\\x64\\x8e\\x07\\x27\\x41\\x5c\\xfb\\x2c\\xb2\\xe8\\x6e\\x8e\\xbf\\xd4\\xf7\\x61\\xd6\\xbb\\x99\\x16\\x2f\\x19\\xb1\\x36\\x67\\xe1\\x82\\x47\\x1b\\x7f\\x3a\\xa8\\xea\\x39\\x80\\x24\\x49\\x92\\x4d\\x74\\x71\\x33\\x11\\x9d\\xda\\xbc\\xfe\\x45\\xd7\\x7f\\x82\\x29\\x5a\\x42\\x84\\x73\\xf3\\x27\\x2a\\xbd\\x77\\x7e\\x8b\\x8e\\x3b\\x3f\\x1a\\xdd\\x59\\x90\\x27\\x37\\x57\\x47\\xfc\\x0f\\x10\\x2f\\x42\\x29\\x5f\\xec\\x70\\xf1\\x54\\x86\\xa1\\x16\\xa1\\x2d\\x9e\\x63\\x2f\\xc2\\x95\\xb3\\xe5\\x58\\x54\\xaf\\x6b\\x9f\\x2f\\x10\\x5f\\xad\\xc1\\x00\\x3b\\x5e\\x5e\\xf6\\x2f\\xc7\\x50\\x89\\x85\\xdb\\x11\\x17\\x7c\\xc8\\x04\\xaf\\xe5\\xd2\\xf0\\xa2\\xdd\\xce\\x58\\x36\\xe1\\x06\\xc2\\x43\\xa9\\x9d\\x39\\xd2\\x3f\\xfc\\x93\\xf1\\xb9\\xc9\\x22\\x40\\x6a\\xb1\\x81\\xf8\\x64\\x06\\x75\\xb1\\xdb\\x45\\x69\\x0a\\x00\\xfd\\x29\\x36\\xb6\\xdb\\x50\\xd8\\x98\\xec\\x2b\\xe5\\xdf\\xed\\xb8\\xec\\x0a\\xc1\\xf4\\x88\\x4a\\xb7\\x0b\\x69\\x34\\x9c\\xd6\\xae\\x2a\\xcd\\x7a\\xa1\\xd2\\xed\\xa8\\x17\\x0a\\xa0\\xa8\\xff\\x7a\\x1c\\xc7\\x5f\\x79\\xa1\\xed\\x53\\x01\\x01\\xc7\\xee\\x76\\xfa\\x88\\xaf\\x49\\x0d\\xb1\\x72\\x45\\x24\\x8f\\x31\\xce\\x79\\xf9\\x44\\x9c\\x17\\x26\\x9f\\x16\\x80\\x2b\\x0f\\x73\\x6d\\xbe\\xcd\\xef\\xd5\\x23\\x0c\\x09\\x0d\\x6a\\x8b\\xd8\\x7e\\xb0\\xc7\\x44\\x9b\\x0e\\xb4\\x67\\x3c\\x46\\x26\\xd5\\x7f\\x18\\x0f\\x2e\\x9d\\x25\\x5a\\x59\\x77\\xea\\x88\\x0d\\x86\\xd7\\x42\\x78\\x35\\x72\\x4d\\x67\\x4e\\x85\\xe6\\x50\\x47\\x5a\\x20\\x52\\x45\\x5a\\x2e\\x62\\x32\\x38\\xe4\\x2e\\x72\\xac\\x09\\x6a\\xb3\\xac\\x45\\x82\\xac\\x71\\x06\\x38\\x3a\\x88\\x58\\x3c\\x75\\x1c\\xd4\\xb8\\xdc\\xe6\\xbb\\x9f\\x30\\x52\\x53\\x5c\\xb2\\x55\\xde\\x7e\\xf5\\x82\\x08\\x9f\\x79\\xed\\x35\\xba\\xdd\\x12\\x95\\x48\\x11\\x1c\\x62\\x91\\x82\\xaf\\x7e\\x71\\x0a\\x97\\x21\\x03\\xdb\\x2d\\x8b\\xd0\\x6a\\xcd\\x1e\\x43\\x2d\\x57\\x84\\x04\\xc4\\x2c\\x62\\xe8\\x0b\\x0b\\x65\\xf2\\x40\\xf1\\xfe\\x15\\x88\\xd9\\x2d\\x3e\\x0c\\x78\\x9f\\x41\\x1c\\xf0\\xb2\\x40\\xdc\\x15\\xe8\\xbd\\x62\\xbe\\xf7\\xd9\\x1d\\x19\\xc7\\xf3\\x9e\\x83\\x66\\xe4\\xfb\\xc2\\x0a\\x16\\x18\\x83\\xbf\\x78\\xa7\\xf1\\x39\\x09\\x52\\x7c\\x73\\xd8\\x2a\\xa9\\x25\\x47\\xbf\\xc8\\x28\\x80\\x00\\x64\\x7c\\xe4\\xae\\xb4\\xe8\\x0b\\x93\\x59\\xde\\x32\\x37\\x41\\xf1\\x54\\x7c\\x67\\x9b\\x44\\x76\\x39\\xde\\xe9\\x3e\\x95\\x6e\\x5e\\xae\\x73\\xcc\\xc2\\xa0\\x17\\x80\\x68\\x4e\\x8b\\xb1\\x7b\\x3b\\x2d\\x2d\\xd8\\x26\\xa0\\x9e\\x00\\x87\\x2f\\xf3\\x51\\x79\\x48\\xb9\\xcc\\xc9\\x62\\xe4\\x01\\x6d\\x34\\xf4\\x7b\\x16\\xaa\\x2c\\x2c\\x48\\x3f\\x8d\\xd8\\xc3\\xf3\\x90\\xf4\\x93\\x64\\x11\\x49\\x93\\x95\\x46\\x32\\xce\\xe0\\x15\\xbd\\x3b\\xf4\\x75\\x6a\\xd9\\xe8\\x7c\\xd5\\xda\\x01\\xb5\\x7c\\x59\\x43\\xd2\\xa4\\xd7\\xd9\\xd0\\xc5\\xcd\\x64\\xd4\\x5c\\x09\\xfc\\xd2\\x19\\x2b\\x93\\x83\\x7e\\x79\\xaf\\x7c\\xf1\\x77\\x52\\xaa\\xe1\\xdf\\x55\\x4e\\xe7\\x1e\\x4b\\x00\\x69\\x1a\\x02\\x3c\\x4f\\x52\\x6a\\xc7\\xd3\\x3a\\x64\\xa5\\x31\\x0c\\x1b\\x8f\\xbd\\xf9\\x6f\\xe6\\x78\\x01\\x9f\\x8c\\x09\\x59\\x99\\x16\\x2d\\x9b\\x7d\\x60\\x5c\\x5a\\xb9\\x14\\x28\\x09\\x8f\\x40\\x55\\xfd\\xd3\\x83\\xa6\\xd6\\x99\\x7a\\xcd\\x21\\x0d\\x77\\x7c\\xa1\\x60\\xb6\\x5b\\x7d\\xfb\\xc0\\x59\\x91\\x89\\xdf\\xf2\\xeb\\xa0\\xbe\\x5e\\xe0\\x8b\\xfa\\x08\\x76\\xea\\xb6\\xaa\\xa5\\x20\\x90\\x6c\\x4a\\xe2\\xc2\\x4e\\xaa\\xda\\x52\\xdb\\x46\\x21\\x49\\xa4\\x73\\xb0\\xd7\\x34\\x87\\x01\\x30\\x89\\x49\\xfe\\x08\\xd3\\x9f\\xcc\\x6a\\xc2\\x64\\x14\\x94\\x2b\\x8f\\x18\\x4b\\xba\\xc9\\x9f\\x71\\xa8\\x44\\x98\\xb8\\x16\\x55\\x86\\x52\\x28\\x7c\\xd6\\x84\\xc7\\xb9\\x84\\x2d\\x5c\\x68\\xf1\\xf5\\xd0\\x2d\\x96\\x85\\x71\\xe8\\xd8\\xe7\\x88\\x65\\x9c\\xf3\\x81\\x43\\xa2\\x71\\x5d\\xdc\\x70\\x70\\x19\\xd3\\xfe\\x2d\\x8c\\x49\\x87\\x75\\x23\\xde\\x57\\x25\\x1b\\xe2\\x75\\x52\\x8b\\xd7\\xc4\\x3c\\xcc\\xe0\\x69\\x16\\xc4\\xba\\x5a\\x22\\x80\\x38\\xd4\\xff\\x6f\\x21\\x00\\xdd\\xb0\\x9d\\x18\\x70\\xa0\\xc2\\x19\\x3c\\xa6\\xe0\\xed\\xf6\\xe5\\x1b\\x79\\x71\\x33\\x79\\x6e\\x1f\\x39\\x81\\xfb\\x9a\\x7d\\x14\\x7a\\xa4\\x76\\xaf\\x6d\\x6d\\x23\\x2f\\xb6\\xbd\\x6f\\xf9\\x36\\x7a\\x66\\xe3\\x5c\\xb0\\xa8\\x84\\x3a\\xac\\x87\\x75\\x98\\xab\\xb3\\x72\\xf5\\x03\\xc3\\xee\\x82\\xb2\\xa9\\xb2\\xc1\\xf5\\x87\\x4a\\x0e\\x91\\x77\\x10\\x3b\\xa3\\x8c\\x9a\\xaf\\x80\\x85\\xaf\\xcb\\x5e\\xd6\\x4e\\x5e\\x06\\xf4\\xf2\\x86\\x44\\xfe\\x95\\x3c\\x89\\x88\\x7d\\xf5\\x0b\\xf2\\x85\\xd0\\x3f\\x2a\\xcf\\x2b\\x64\\x44\\x0a\\x38\\xe2\\x7b\\xf1\\x57\\xa2\\xfe\\x8f\\x18\\xbd\\x16\\x24\\x39\\xf4\\x3d\\x5e\\x26\\x96\\x9d\\xc9\\xc7\\x46\\xcc\\xdf\\x89\\xf9\\xcb\\xf9\\xf8\\x2b\\xd3\\xab\\xad\\x3c\\xb8\\xdf\\x66\\x4a\\x4f\\x95\\x31\\xdb\\x4a\\x44\\x30\\x09\\x92\\x90\\xd9\\x4f\\x55\\xd1\\xd5\\xe3\\x2d\\x9a\\xf6\\x1d\\x8b\\xde\\x2d\\x9a\\x72\\x0e\\x74\\x8b\\xa6\\x8d\\xd2\\x5a\\xe0\\x14\\xc3\\x73\\xd4\\xef\\x17\\x6b\\x07\\x90\\x24\\x4c\\x65\\xd1\\x16\\xd7\\xc0\\x01\\x88\\x56\\x29\\x9b\\x2d\\xc3\\xd4\\xbc\\x25\\x40\\x38\\x86\\x5b\\xef\\xee\\x38\\xea\\x00\\x89\\x7e\\xa5\\x98\\x84\\x86\\x4d\\xed\\xb0\\x40\\x79\\x32\\xe4\\x37\\x4d\\x06\\x5d\\xe6\\x4e\\x9f\\x75\\x94\\xd5\\x36\\x33\\x50\\x0b\\x0b\\x46\\x01\\xed\\x90\\xe7\\x9b\\xd6\\x12\\x92\\x78\\xad\\xc3\\x62\\xee\\x82\\x34\\xb9\\xdc\\xfb\\xcb\\xbe\\xe9\\x34\\x50\\x89\\x35\\x9b\\x26\\x02\\xa1\\x2d\\xfb\\x6d\\xce\\x46\\x3d\\x97\\x04\\x41\\x99\\xaa\\x05\\x8d\\xef\\xf8\\x80\\x80\\xdf\\xfc\\x16\\x21\\x69\\xbb\\x7f\\xe9\\x8b\\x64\\x00\\xb1\\x27\\x73\\xd9\\x60\\xc0\\x44\\xc2\\x1f\\xb2\\xdd\\xf6\\xdf\\xaa\\x0b\\x2e\\x37\\xab\\xb8\\x88\\x6c\\x36\\xac\\x43\\x3d\\x34\\x88\\x3d\\x9e\\x5f\\xe6\\xc6\\xba\\x23\\xbf\\xd9\\x1f\\x91\\xe0\\xec\\xef\\xf1\\xf8\\xdd\\xcc\\x00\\x9e\\x1f\\x7d\\x1c\\x77\\x41\\xb1\\xba\\x39\\xc5\\x90\\xbb\\x06\\x61\\x2d\\x95\\xf9\\x46\\x68\\x11\\x5d\\x4d\\x67\\x35\\x98\\xbe\\xf8\\xeb\\x02\\xc5\\xaf\\xc9\\x04\\x94\\xb7\\x5f\\xf5\\x53\\x8e\\x4c\\xab\\x97\\xb9\\x47\\xad\\x5e\\xfb\\x26\\x5e\\xbb\\xdd\\x0a\\xae\\xaa\\x10\\xc0\\x3b\\x4f\\x32\\x9a\\x35\\x5d\\x2b\\x8b\\x99\\xf4\\x5a\\x32\\xbf\\xeb\\x84\\x34\\x65\\x87\\xd7\\x92\\x02\\xb5\\xbc\\x96\\xdc\\x7c\\xfb\\x73\\xc3\\xdd\\xac\\x9b\\x03\\xed\\x9a\\x63\\x54\\x17\\xe5\\x24\\xa1\\x18\\x4b\\x1c\\x04\\x1d\\x8e\\x38\\x7a\\x60\\x2f\\x77\\xc4\\x59\\x7e\\xdb\\xf8\\x76\\x7f\\x89\\xd2\\x4c\\x3a\\xe2\\x2c\\xbf\\x7d\\xef\\x69\\x7c\\x5f\\x18\\x16\\x5d\\x3f\\x9d\\x0a\\xc0\\xdc\\x3f\\x2d\\xbe\\xeb\\xf0\\xc9\\x0c\\xbc\\xdb\\x05\\xab\\x12\\x09\\xcf\\x77\\x65\\x65\\x99\\x9c\\x4e\\xce\\xc6\\x71\\x10\\x35\\x06\\x0a\\xeb\\x1c\\x28\\xce\\x08\\x85\\x07\\x8f\\xed\\xa7\\x43\\x5a\\x7e\\x3a\\xc4\\xf1\\xd3\\x21\\x0d\\x3f\\x1d\\xe2\\xf5\\xd3\\x21\\x0d\\x3f\\x1d\\xe2\\xf1\\xd3\\x21\\x5e\\x3f\\x1d\\xd2\\xe9\\xa7\\x43\\x3a\\xfd\\x74\\x88\\xf3\\xa6\\x1f\\xb6\\x3c\\x61\\x32\\xeb\\xa8\\xc9\\x1c\\x94\\xea\\xe6\\xaf\\x58\\x08\\x53\\x70\\x09\\xe4\\x1b\\x72\\x15\\x0d\\x33\\xa8\\xae\\x64\\xe7\\x49\\xd6\\xf6\\x40\\x99\\x3f\\x6b\\xc7\\x6c\\x98\\xe6\\xf4\\xdb\\x74\\x0b\\xeb\\xb2\\x93\\xef\\xf8\\xef\\x61\\xd2\\xd4\\x3b\\x28\\x4d\\x9a\\xf3\\x3f\\xcc\\xa4\\x39\\xff\\x03\\x4c\\x9a\\xb3\\x48\\x60\\xa8\\xcf\\x94\\xf9\\xcc\\x77\\xda\\xfb\\x1f\\xb6\\x17\\xb6\\x69\\x07\\x5d\\xd6\\x76\\xd0\\xa5\\xb6\\x83\\xce\\xed\\x4f\\xba\\x16\\x69\\x87\\xb1\\x42\\x9d\\xce\\x40\\xa4\\x79\\xdc\\x6d\\x3f\\x54\\xa0\\x87\\x9e\\xb2\\xe7\\x6c\\x88\\x0a\\x4c\\x8e\\xf7\\x77\\x96\\x1a\\xcb\\xaf\\x90\\x1a\\xdb\\x2f\\x47\\xfc\\x56\\xf9\\x46\\x53\\x5f\\xbf\\x7c\\x63\\x65\\x66\\x55\\x32\\x8e\\xbc\\x2d\\xda\\x25\\xe3\\x64\\xdd\\x32\\x4e\\xcd\\x93\\xfe\\x9e\\x32\\x4e\\xf6\\xf7\\x78\\xe0\\xf7\\xf7\\x96\\x71\\xf4\\x52\\xbd\\x4c\\xc6\\xd9\\xbc\\x5c\\xc6\\x21\\xaf\\x97\\x71\\xb2\\x2a\\x9c\\xb7\\x84\\x9c\\xbf\\xfb\\xe3\\x28\\x1e\\x1d\\x52\\x3d\\x30\\x58\\xae\\x1f\\xb9\\x98\\xa3\\xc5\\x1a\\x6c\\x5e\\x87\\x38\\x18\\x42\\x89\\x20\\xda\\x9f\\x58\\x46\\x0a\\x8b\\x77\\x7f\\x69\\xfd\\x86\\x84\\xd2\\x91\\x0d\\xac\\x71\\xc1\\x56\\xd0\\x9e\\x67\\x80\\x53\\xf5\\xf8\\xed\\xd1\\x64\\x1c\\x07\\xc2\\xbc\\x90\\x32\\x61\\x19\\xb6\\x46\\x24\\x03\\x63\\x62\\x35\\xc8\\x46\\xa5\\xf3\\x5a\\x73\\x1c\\xe4\\x34\\xcd\\x1c\\x08\\x3b\\xa5\\x5c\\x9e\\x3c\\x9d\\x5c\\x5d\\x5c\\x8a\\xfc\\x04\\xa7\\x93\\xf1\\x47\\xeb\\xbd\\x10\\xcc\\xd0\\x4a\\x3e\\x3c\\x22\\x6a\\xe5\\x63\\x1f\\x8d\\xb7\\x3e\\xe4\\xf3\\xa0\\x6a\\x98\\x48\\x3a\\x59\\xcb\\xe7\\xa5\\x2f\\x7f\\xd1\\xe9\\xde\\xca\\xf5\\xa3\\x79\\xae\\x71\\xfa\\xc6\\x7c\\x12\\xa9\\x6f\\xe0\\xf9\\xd1\\x4f\\x77\\x67\\xa7\\xd7\\x93\\xbb\\xef\\xaf\\x2e\\x6e\\x2e\\x65\\x76\\x36\\xd8\\x8b\\x72\\x5c\\xb2\\xfd\\x45\\x41\\x37\\x6b\\x0d\\x72\\xfe\\xe3\\xb5\\xac\\xdd\\xcf\\x31\\xf9\\x24\\x4b\\xf5\\x5b\\x22\\xbc\\x54\\x0e\\x58\\x34\\xa5\\x8b\\xeb\\x46\\x1a\\xd3\\xb1\\x9e\\x1f\\xb1\\xe6\\xd8\\x7a\\x99\\xa4\\xb1\\x06\\x2a\\xd9\\x9d\\x05\\xa0\\x42\\x38\\x84\\x40\\x76\\xf1\\xdd\\x77\\xd7\\xe3\\x49\\x1c\\xc8\\xbd\\x0f\\xe0\\xe5\\x85\\xbc\\x9d\\x8d\\x83\\x35\\x95\\xda\\x70\\x67\\xa6\\xb9\\x96\\x21\\xd1\\xcd\\xb9\\x60\\x92\\xca\\xc9\\x65\\xd4\\xfc\\x3f\\xf8\\x70\\x71\\xf2\\x8b\\x32\\xdd\\xc9\\xc0\\x8f\\x43\\x19\\xba\\x1a\\xbf\\xf4\\xd1\\x62\\x6d\\xfb\\x77\\x53\\x89\\x4b\\xe4\\x54\\x4c\\xd5\\xac\\x3d\\x17\\xd8\\xf7\\xba\\xe1\\xea\\x75\\x7f\\x06\\xd0\\x5d\\x6d\\x9d\\xac\\x4e\\x65\\x45\\xbf\\xd5\\xa9\\xf1\\xe4\\x27\\x56\\x81\\x32\\xb4\\xc9\\x78\\xfc\\x56\\x1e\\x20\\x19\\x44\\x9d\\x0c\\x4d\\xf0\\xbc\\xb3\\x52\\xe2\\x86\\x25\\x55\\xe1\\x64\\xbe\\x04\\x4d\\x38\\xba\\x5b\\x17\\x74\\x86\\xca\\x52\\xe6\\x2b\\x13\\x6d\\x14\\x68\\x5e\\xa0\\x72\\x59\\xbb\\x3c\\x2a\\x08\\xa0\\xb2\\xe5\\x11\\x5f\\xb6\\x3c\\xf5\\x51\\x67\\x0a\\x79\\xcf\\xe8\\xcc\\x4d\\xbb\\x53\\x1a\\xc9\\xad\\x3c\\x9c\\x45\\x06\\x8f\\x66\\x91\\x44\\x31\\xce\\x4f\\x05\\xd1\\xd1\\x4e\\x67\\x7a\\x9d\\x25\\x95\\x39\\x24\\xb1\\xa7\\x14\\x16\\x09\\x4e\\x92\\xa4\\x6e\\xae\\x7e\\x7e\\xf9\\x5a\\x27\\xde\\x09\\x41\\x3c\\x1c\\xbd\\x74\\x43\\x9c\\x85\\x6f\\xb4\\x25\\x4b\\xc5\\x53\\x0e\\xed\\x17\\x87\\x35\\xd2\\x01\\x2e\\xae\\x58\\x19\\x3e\\x4c\\xac\\x15\\xdd\\x99\\x55\\x1a\\xcf\\x43\\xaa\\x82\\xac\\xa8\\xca\\x28\\xad\\x9f\\x17\\x26\\x9d\\x91\\xdf\\xe2\\x8d\\x18\\x11\\xfe\\xb7\\xdd\\xa6\\x91\\x7c\\x68\\x5c\\x99\\x6a\\x6f\\xc5\\xa3\\x72\\x78\\x1a\\x82\\x88\\xd1\\xf5\\x5e\\x01\\xa9\\x79\\x4c\\x41\\x38\\xab\\x9a\\x77\\xaf\\x7d\\xe2\\x50\\x05\\xa2\\x92\\x16\\xcc\\x8e\\xf9\\xb4\\xee\\x00\\x6f\\x87\\xd3\\x7d\\x74\\x3b\\x9c\\x56\\x9e\\xbb\\x5a\\xe9\\x2a\\xa6\\x96\\x59\\xbe\\x99\\x8d\\xc4\\x6c\\x98\\x59\\x6b\\x5d\\x7a\\x30\\x55\\xd9\\x48\\x5e\\x9f\\x04\\xac\\x66\\x0b\\xa0\\xf3\\x68\\xcc\\xe7\\x61\\x10\\x35\\x60\\x5d\\xf2\\xd3\\x3a\\x6e\\xe3\\x76\\x45\\x3b\\x53\\x98\\x21\\x2e\\x56\\x99\\x46\\x2b\\xdb\\x6f\\x59\\x21\\x56\\xdb\\x43\\x79\\xf7\\x59\\xd7\\x19\\xbf\\x3a\\x6c\\xeb\\x5c\\xdc\\x33\\xf7\\x87\\x5e\\xc3\\xba\\xb8\\x18\\xd1\\x69\\x89\\x54\\x3a\\x14\\x64\\x25\\x2a\\x92\\x92\\x35\\xce\\x02\\x30\\x92\\x0f\\xf6\\xd5\\xae\\xb3\\xf2\\x4e\\xac\\x05\\x28\\xde\\xee\\xd3\\xe5\\x49\\xf0\\xa7\\x60\\xaf\\xd0\\xa8\\xe4\\x37\\x78\\x53\\x9d\\x36\\xcc\\x3e\\x85\\x5d\\x2a\\x4b\\x63\\xed\\x93\\x44\\x51\\x08\\x1f\\xf1\\x58\\xa7\\x0b\\xf4\\xcb\\x85\\xe5\\x5c\\xd9\\xa8\\x37\\xb9\\xb6\\xdc\\xde\\xd5\\xd2\\xbe\\x68\\x00\\x4e\\x92\\x8b\\xed\\xf6\\x63\\xca\\x96\\xd1\\x2a\\xfd\\x12\\x36\\xa2\\xd0\\x2d\\x20\\xd8\\x99\\x09\\xc3\\x86\\x32\\x91\\xc4\\x72\\xf8\\xaf\\x19\\x52\\xbd\\x26\\x76\\x0a\\x07\\xd9\\x82\\x77\\x19\\xba\\x02\\x85\\x25\\x81\\x10\\x03\\x51\\x54\\xbf\\x2b\\xe3\\x87\\x4b\\x3e\\x5d\\xb6\\x27\\x91\\x1d\\xa2\\x4e\\xea\\x48\\x7c\\x4f\\x78\\xec\\xa1\\x7d\\x03\\x6f\\x2f\\x81\\xfd\\x16\\xb3\\xbd\\x5e\\xfd\\x24\\xd1\\xb9\\xdf\\x2c\\x8e\\xf5\\x3e\\x71\\x2f\\x26\\xf5\\x31\\xbb\\x75\\x7e\\x99\\xac\\xec\\xd3\\x51\\xfb\\xe4\\xf5\\x93\\x04\\x6b\\xb7\\x2f\\x2d\\x87\\x86\\x56\\x70\\x47\\xfb\\x8b\\xc1\\x80\\xbd\\x73\\xce\\xf9\\xed\\x70\\xaa\\x5b\\xa8\\x4b\\xde\\x0f\\x81\\xb3\\x85\\xed\\xd3\\x6e\\x85\\x81\\x88\\xeb\\xc5\\x10\\x8c\\xf4\\x0d\\x4e\\x99\\x38\\xcd\\x99\\xa7\\x2c\\xf6\\xf7\\x47\\xc0\\x3b\\x05\\x77\\xf6\\x25\\x1f\\xcf\\x7b\\xb7\\x0d\\x51\\xe8\\xd5\\x0d\\x1b\\x60\\x7b\\x07\\xd3\\xed\\xb6\\x39\\x43\\x5e\\x0a\\x5a\\xcb\\xd4\\xec\\x55\\xe5\\x3e\\xd0\\xf5\\x9e\\x4b\\x18\\x67\\x15\\x8c\\xfc\\xa6\\x66\\x6f\\x85\\x16\\x19\\xb2\\xaa\\x3d\\x81\\x60\\x00\\x46\\x24\\x21\\x2e\\x2f\\xad\\x99\\x10\\xda\\xd3\\xb9\\x99\\x15\\x55\\x92\\x9a\\xec\\x14\\xbe\\xd9\\xe3\\x55\\xcb\\x02\\xcd\\x4d\\xd9\\x9b\\xaa\\x7e\\x32\\x53\\x1b\\x07\\x60\\x00\\xc0\\x08\\xd7\\xd7\\xfd\\xb9\\x2b\\xc0\\x81\\xc3\\x10\\x1b\\x8f\\x96\\x5a\\xb8\\x53\\x39\\x8f\\x2d\\x69\\x4f\\xe5\\xea\\xaf\\xed\\x5b\\x79\\x24\\x55\\x01\\x00\\xb1\\xa7\\x10\\xc4\\xa1\\xaf\\x18\\x6a\\xef\\xd7\\x32\\xd4\\xa2\\xa9\\xd6\\x1c\\x80\\x08\\x79\\x0e\\x5d\\x89\\xb5\\x21\\x9a\\x76\\x74\\xff\\xa2\\x26\\x55\\x03\\xc6\\x81\\xd4\\xea\\xc8\\xd7\\x6c\\x27\\xbf\\xd5\\x3e\\xaf\\x69\\xa4\\xd5\\x3c\\x4f\\xc6\\x41\\x99\\xf4\\x86\\xef\\x7e\\xe3\\xd5\\x7e\\x57\\x82\\xd2\\xa2\\xc9\\x52\\xf7\\xea\\xd8\\x77\\xcc\\x58\\x2a\\x48\\x7e\\x9b\\x75\\x07\\xb7\\xad\\x3b\\xb6\\xb4\\xe0\\x7b\\x79\\x47\\xdd\\x5f\\xd5\\x71\\x6d\\xc4\\xff\\xea\\x8e\\xdb\\x96\\x88\\x53\\x7b\\x45\\x7a\\x02\\xfc\\x4a\\xeb\\x0d\\xb6\\xad\\x37\\xe4\\x0f\\xb7\\xde\\x60\\x61\\xe4\\x20\\x4e\\x1e\\x02\\x2b\\x89\\x5f\\x1a\\x39\\xba\\x3a\\xf4\\x79\\x20\\x34\\x9e\\xf4\\x59\\x46\\x5a\\xbf\\x56\\xf6\\x3f\\x45\\x00\\x09\\x27\\x80\\xf5\\x5e\\xdd\\x92\\x69\\x77\\xe8\\x3d\\x86\\xfa\\xc1\\x5a\\x19\\x8c\\xf0\\x87\\x86\\xde\\x93\\xee\\xd0\\xfb\\x95\\xc7\\xd2\\x19\\xcd\\xb9\\xfc\\x74\\x0f\\x49\\xf3\\x49\\x01\\x96\\xde\\xfb\\x1e\\x14\\x10\\xc5\\xee\\x73\\x02\\xa6\\xc8\\x7e\\x4c\\x40\\x14\\x76\\xa6\\xda\\x67\\xe9\\xbd\\x6d\\x15\\xc1\\x96\\x55\\xe4\\x25\\x76\\x0f\\xe8\\x7b\\xbe\\xb5\\xf3\\xee\\x86\\xd6\\xad\\x3b\\x66\\x88\\x17\\x18\\x42\\x5a\\xc6\\x13\\x59\\x70\\x77\\x73\\x16\\x07\\xef\\x7b\\x39\\xee\\xbd\\xef\\x99\\xaa\\x1d\\xe9\\xf9\\xf9\\x62\\x4c\\x61\\xcf\\x2d\\x5c\\xe3\\x3c\\x6f\\x97\\xf2\\xde\\x45\\x22\\xff\\x67\\x6d\\x20\\x35\\x88\\x1a\\x94\\x7a\\x35\\xf6\\x7d\\xaf\\xf9\\xd2\\xab\\xb1\\x16\\xa5\\x5e\\x63\\x08\\xab\\x99\\xa2\\xb1\\x7f\\x54\\x2a\\xa6\\xad\\xad\\x72\\xa7\\xcf\\x84\\x12\\xf6\\x1b\\x29\\xce\\x7e\\x73\\xc2\\xdc\\x5d\\x39\\xe8\\xb0\\xa6\\xb8\\x9e\\x64\\xa0\\x16\\x90\\xf5\\x22\\x90\\xd4\\x3b\\x60\\x0a\\xf3\\x76\\x96\\x47\\xcd\\x56\\x69\\x93\\x2d\\xdd\\x0e\\xa7\\x70\\xb9\\x3b\\x13\\x89\\xf5\\x72\\x20\\x9e\\x87\\xb9\\xec\\x67\\x96\\x04\\x37\\x67\\x41\\x92\\x24\\xb9\\x98\\xa1\\xb0\\x18\\xd1\\xa8\\xc6\\x21\\xfd\\xf7\\x28\\x6d\\x50\\x9d\\x5c\\xbf\\x61\\x00\\x00\\x4c\\x93\\xf4\\x36\\xad\\x05\\x47\\x65\\x0c\\xd1\\xd1\\x2e\\x44\\x3e\\xa5\\xb5\\xf3\\xd9\\x55\\x00\\x33\\x0b\\xde\\x97\\x6b\\x3f\\xad\\xa4\\xca\\xae\\xc2\\x03\\x35\\xcb\\xdc\\x78\\x72\\x3e\\xea\\xba\\x0c\\xc0\\x7e\\xe6\\x8d\\x21\\x19\\x0c\\xfa\\x9b\\x8e\\x14\\xe8\\x4b\\xf1\\x08\\x11\\x0a\\x97\\xd2\\x90\\xe0\\x15\\xe2\\xb4\\x3a\\x9d\\xeb\\x4b\\xc3\\x36\\x6f\\xb4\\xe7\\x7e\\x32\\x6e\\x67\\x10\\xb6\\xa7\\x5e\\x36\\xa6\\xde\\x82\\x4e\\x2b\\x15\\x0d\\x68\\xa5\\x74\\xf7\\xe7\\x2a\\x2d\\x41\\x35\\x52\\x5e\\xbf\\xf5\\xa0\\x0b\\x58\\x58\\x98\\x0c\\xe7\\x20\\x9e\\xcb\\x1c\\xe2\\xe9\\x57\\x98\\x0f\\x38\\xa1\\xf0\\x19\\x03\\xc4\\xa3\\x5d\\x1e\\x61\\x16\\x12\\x58\\x28\\x63\\x0c\\xcc\\xa5\\xc9\\x6b\\x99\\x84\\xa9\\x46\\x3b\\x52\\xa3\\x5d\\xfd\\x96\\x93\\x85\\x80\\x20\\x96\\x69\\xaf\\xb4\\x88\\x45\\x8d\\x30\\xc5\\x31\\x7e\\x96\\x88\\xac\\x99\\x9d\\x71\\x33\\xe2\\x25\\xda\\xa5\\x73\\xd0\\xa4\\x17\\xd0\\xc6\\xc3\\x9e\\xf2\\xe8\\x8e\\x99\\x06\\x8e\\xe9\\x6a\\x9d\\x23\\xbe\\xe3\\x70\\x09\\x67\\xb0\\x00\\xd5\\x68\\x39\\x18\\xcc\\x0e\\x45\\x73\\xde\\x60\\x9b\\xcd\\xae\\x60\\x9b\\x4d\\x08\\xa0\\x1e\\x8c\\x2d\\x8f\\x61\\x7d\\x43\\x99\\xfa\\x3a\\x6f\\x2c\\x23\\x4c\\x85\\xd0\\x43\\xc4\\x53\\x08\\xcd\\x76\\xd4\\xb2\\x08\\x84\\xcc\\x85\\xb0\\x5e\\x6f\\xb9\\x59\\x56\\x2f\\x3d\\x16\\x8f\\x65\\xe5\\x7c\\x70\\x79\\x47\\xa3\\x50\\xb0\\x07\\xb1\\x5b\\xee\\xe5\\x68\\x41\\x65\\x7e\\x1f\\xe2\\x8b\\xff\\x95\\x22\\xa9\\x78\\x9b\\xf7\\x00\\x54\\xfa\\x0d\\xe5\\x3a\\xaf\\x6b\\xab\\xf5\\xe6\\xd5\\xab\\x6e\\xdd\\x1b\\x5d\\x6c\\xb5\\x3e\\x04\\xb0\\x38\\x0c\\xeb\\xe4\\xa9\\xea\\x99\\x5f\\xab\\x27\\x99\\x51\\x20\\x6e\\x39\\x85\\x69\\x74\\x70\\x79\\x00\\x3f\\x5a\\xf6\\xe2\\xd9\\x64\\xda\\x96\\x01\\x14\\xa9\\x5e\\x26\\xce\\x83\\xc8\\xf5\\x2a\\x8b\\x85\\xd5\\xbb\\xde\\xdc\\x81\\x96\\xf2\\x53\\xaf\\xc7\\xf3\\x2f\\x1d\\x57\\xe9\\x60\\x90\\x86\\xa0\\x82\\x6c\\x87\\x10\\xff\\x82\\x0c\\x64\\x46\\x88\\x87\\x65\\x82\\x2d\\xef\\x30\\x7e\\xc6\\xdd\\x2c\\x62\\xe6\\x21\\x3a\\x17\\xca\\x9f\\x3b\\x8c\\xec\\xc8\\x1d\\x46\\x5e\\x26\\x9c\\x13\\x9d\\x3b\\x8c\\xd4\\xc2\\x39\\xfb\\x0d\\xc2\\x39\\x27\\xe5\\xdd\\xb9\\xbf\\x48\\x33\\xf7\\x17\\x7d\\xcd\\xcb\\x64\\xed\\x67\\x4b\\x1b\\xaf\\x90\\x09\\x29\\x4f\\xa7\\xb4\\xe2\\xeb\\x96\\xb4\\x3f\\x31\\x75\\x8e\\x64\\x9d\\xd6\\xc5\\xcf\\x8a\\xd6\\xa2\\x61\\xe6\\x19\\x4d\\xe5\\xbc\\x20\\xf7\\x7c\\x6e\\x2b\\xb4\\x23\\xb7\\xd5\\x9b\\xb2\\xf7\\xff\\xa7\\x9f\\xd3\\xeb\\x59\\x81\\xd7\\x4c\\xe7\\xb7\\x2a\\x7b\\xb2\\xc7\\x48\\xfd\\xdf\\x5b\\x6d\\x4a\\xd6\\xbb\\x47\\x3d\\x4c\\x66\\xf9\\x26\\x43\\x59\\xef\\x1e\\xcd\\x69\\x81\\x7a\\xfe\\x66\\x22\\x93\\xfd\\x4a\\x4c\\x43\\x06\\x96\\x59\\x51\\x4d\\x22\\xa5\\xa6\\xfc\\x15\\x49\\xbc\\x64\\xb7\\xc3\\xe9\\xbb\\x6f\\x06\\x03\\x76\\x7b\\x30\\x7d\\xf7\\xd7\\xed\\x56\\xc4\\xda\\x0b\\xcb\\x92\\x78\\xec\\xf3\\xf6\\x60\\xca\\xeb\\xbe\\x99\\xbe\\x3b\\xd8\\x6e\\x79\\xf9\\xfb\\xe4\\xcf\\xaf\\x9f\\x53\\xca\\x7a\\x39\\x4a\\x4b\\xa6\\x27\\xf5\\xf9\\x20\\xfa\\x6b\\x74\\xd0\\xbb\\xdf\\xf0\\xf2\\xb2\\xec\\xb1\\x65\\x4a\\x7a\\x9f\\x05\\x9e\\x05\\xa0\\x12\\x29\\xc5\\x6f\\x18\\xce\\x93\\x12\\xb2\\xe8\\x28\\x47\\x05\\x4b\\x52\\xc8\\xa2\\x0f\\xe2\\x35\\xca\\x24\\x87\\x2c\\x3a\\x4e\\x0b\\xe1\\xb8\\x94\\x2c\\xf9\\x0f\\x9a\\xe7\\xe9\\xba\\x44\\xc9\\x0c\\xb2\\xe8\\x44\\x49\\xc3\\xc9\\x06\\xb2\\x48\\xe6\\x5d\\xcf\\x20\\x8b\\x2e\\xe5\\xb5\\x7c\\x72\\x07\\x59\\x74\\xad\\x15\\xe2\\x64\\x01\\x59\\x34\\x49\\xef\\x93\\x15\\xff\\x5f\\xfa\\xaf\\x25\\x73\\x8e\\xdd\\x4f\\x15\\xfc\\x47\\x28\\x3d\\x7c\\xc1\\xe8\\x1f\\xde\\xbe\\xfd\\x53\\xaf\\xa4\\x9b\\x62\\x86\\x3e\\xa6\\xeb\\x35\\x26\\x8b\\x9b\\xab\\xb3\\xe4\\x5e\\xcf\\x39\\x5a\\x61\\x12\\xfd\\x5a\\x46\\xab\\x74\\xfd\\x7f\\x02\\x00\\x00\\xff\\xff\\x83\\xb8\\xb6\\x8d\\x84\\xc5\\x00\\x00\")\n\nfunc cmdInternalPagesAssetsJsBootstrap400Beta2MinJsBytes() ([]byte, error) {\n\treturn bindataRead(\n\t\t_cmdInternalPagesAssetsJsBootstrap400Beta2MinJs,\n\t\t\"cmd/internal/pages/assets/js/bootstrap-4.0.0-beta.2.min.js\",\n\t)\n}\n\nfunc cmdInternalPagesAssetsJsBootstrap400Beta2MinJs() (*asset, error) {\n\tbytes, err := cmdInternalPagesAssetsJsBootstrap400Beta2MinJsBytes()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tinfo := bindataFileInfo{name: \"cmd/internal/pages/assets/js/bootstrap-4.0.0-beta.2.min.js\", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)}\n\ta := &asset{bytes: bytes, info: info, digest: [32]uint8{0x18, 0x86, 0xbc, 0x56, 0x1d, 0xec, 0x7c, 0x44, 0xa7, 0x54, 0x1d, 0x82, 0x37, 0x7a, 0xd8, 0x1a, 0x40, 0xff, 0x32, 0x49, 0x6f, 0x32, 0xad, 0x25, 0x98, 0x84, 0xf0, 0x79, 0xc, 0x44, 0xd6, 0xa5}}\n\treturn a, nil\n}\n\nvar _cmdInternalPagesAssetsJsContainersJs = []byte(\"\\x1f\\x8b\\x08\\x00\\x00\\x00\\x00\\x00\\x00\\xff\\xec\\x7d\\x69\\x73\\x1b\\xb9\\x11\\xe8\\xe7\\xa7\\x5f\\xd1\\xeb\\x6c\\x76\\xc8\\x88\\x1c\\x52\\xde\\xe3\\xd5\\x52\\xa6\\xab\\x64\\xd9\\xde\\x28\\xf1\\x55\\x92\\x9c\\x54\\x4a\\x56\\xa9\\xa0\\x19\\x90\\x84\\x3d\\x1c\\x4c\\x00\\x8c\\x28\\xae\\x57\\xff\\xfd\\x15\\xae\\x01\\x30\\x07\\x49\\x69\\xbd\\x9b\\xe4\\x25\\xfe\\x60\\x91\\x33\\x8d\\x46\\xa3\\xd1\\xe8\\x0b\\x0d\\x70\\x34\\x82\\x63\\x5a\\xac\\x19\\x99\\x2f\\x04\\x3c\\x1e\\x1f\\x7c\\x07\\x3f\\x51\\x3a\\xcf\\x30\\x9c\\xe4\\x49\\x0c\\x47\\x59\\x06\\xa7\\xf2\\x15\\x87\\x53\\xcc\\x31\\xbb\\xc1\\x69\\xbc\\x37\\x1a\\xed\\x8d\\x46\\xf0\\x8a\\x24\\x38\\xe7\\x38\\x85\\x32\\x4f\\x31\\x03\\xb1\\xc0\\x70\\x54\\xa0\\x64\\x81\\xed\\x9b\\x01\\xfc\\x0d\\x33\\x4e\\x68\\x0e\\x8f\\xe3\\x31\\xf4\\x24\\xc0\\x23\\xf3\\xea\\x51\\xff\\x50\\xa2\\x58\\xd3\\x12\\x96\\x68\\x0d\\x39\\x15\\x50\\x72\\x0c\\x62\\x41\\x38\\xcc\\x48\\x86\\x01\\xdf\\x26\\xb8\\x10\\x40\\x72\\x48\\xe8\\xb2\\xc8\\x08\\xca\\x13\\x0c\\x2b\\x22\\x16\\xaa\\x1f\\x83\\x45\\x52\\x02\\xff\\x30\\x38\\xe8\\xb5\\x40\\x24\\x07\\x04\\x09\\x2d\\xd6\\x40\\x67\\x3e\\x20\\x20\\x61\\x88\\x96\\xff\\x16\\x42\\x14\\x93\\xd1\\x68\\xb5\\x5a\\xc5\\x48\\x11\\x1c\\x53\\x36\\x1f\\x65\\x1a\\x94\\x8f\\x5e\\x9d\\x1c\\xbf\\x78\\x73\\xf6\\x62\\xf8\\x38\\x1e\\x9b\\x46\\xef\\xf3\\x0c\\x73\\x0e\\x0c\\xff\\xb3\\x24\\x0c\\xa7\\x70\\xbd\\x06\\x54\\x14\\x19\\x49\\xd0\\x75\\x86\\x21\\x43\\x2b\\xa0\\x0c\\xd0\\x9c\\x61\\x9c\\x82\\xa0\\x92\\xe8\\x15\\x23\\x82\\xe4\\xf3\\x01\\x70\\x3a\\x13\\x2b\\xc4\\xb0\\x44\\x93\\x12\\x2e\\x18\\xb9\\x2e\\x45\\xc0\\x33\\x4b\\x22\\xe1\\x01\\x00\\xcd\\x01\\xe5\\xf0\\xe8\\xe8\\x0c\\x4e\\xce\\x1e\\xc1\\xb3\\xa3\\xb3\\x93\\xb3\\x81\\x44\\xf2\\xf7\\x93\\xf3\\x3f\\xbf\\x7d\\x7f\\x0e\\x7f\\x3f\\x3a\\x3d\\x3d\\x7a\\x73\\x7e\\xf2\\xe2\\x0c\\xde\\x9e\\xc2\\xf1\\xdb\\x37\\xcf\\x4f\\xce\\x4f\\xde\\xbe\\x39\\x83\\xb7\\x2f\\xe1\\xe8\\xcd\\x3f\\xe0\\xaf\\x27\\x6f\\x9e\\x0f\\x00\\x13\\xb1\\xc0\\x0c\\xf0\\x6d\\xc1\\xe4\\x08\\x28\\x03\\x22\\xb9\\xa9\\x27\\x11\\xce\\x30\\x0e\\x48\\x98\\x51\\x4d\\x12\\x2f\\x70\\x42\\x66\\x24\\x81\\x0c\\xe5\\xf3\\x12\\xcd\\x31\\xcc\\xe9\\x0d\\x66\\x39\\xc9\\xe7\\x50\\x60\\xb6\\x24\\x5c\\xce\\x2a\\x07\\x94\\xa7\\x12\\x4d\\x46\\x96\\x44\\x20\\xa1\\x1e\\x35\\xc6\\x15\\xef\\xed\\xcd\\x95\\x3c\\xc5\\xc9\\x02\\x31\\xc1\\xe3\\x8c\\xa2\\xb4\\x17\\x25\\x25\\x63\\x38\\x17\\xd1\\x00\\x3e\\x17\\x28\\xf9\\x84\\xe6\\x98\\x4f\\xe0\\x22\\x4a\\x28\\xc3\\x0a\\x2e\\x1a\\x40\\x34\\x47\\xe5\\x1c\\xcb\\x0f\\x29\\x9e\\xa1\\x32\\x53\\xcf\\x66\\x94\\x2d\\x91\\xfa\\x54\\x12\\xf9\\xbf\\x90\\x53\\x10\\x5d\\xde\\xf5\\x0f\\xf7\\xf6\\x66\\x65\\x9e\\x48\\x2a\\x60\\x51\\x2e\\x51\\x4e\\x7e\\xc6\\xbd\\xbc\\x5c\\x0e\\x80\\x93\\x9f\\xf1\\x00\\xca\\x9c\\x08\\xde\\x87\\xcf\\x7b\\x00\\x37\\x88\\xa9\\xaf\\x87\\x7b\\xa0\\x86\\xdc\\x93\\x5f\\x60\\xaa\\x41\\xe2\\x82\\x16\\xbd\\xfe\\xa1\\xf9\\x92\\xe1\\x7c\\x2e\\x16\\xf0\\xcd\\x37\\x90\\x97\\x4b\\x78\\x3a\\x55\\xc8\\xf4\\xcb\\xb0\\x81\\xc6\\x0c\\x0a\\x6c\\x64\\xc0\\xf6\\x00\\xee\\xf6\\x00\\x18\\x16\\x25\\xcb\\xe1\\x42\\x11\\x23\\x9b\\x5c\\x1e\\xee\\xdd\\xed\\x49\\xc6\\xbd\\xa4\\x59\\x46\\x57\\x92\\xab\\x92\\x61\\x27\\x2f\\x8e\\x21\\x47\\x4b\\xf9\\x35\\xa1\\xf9\\x0d\\xce\\xe5\\x58\\x9a\\x83\\x3a\\x79\\x71\\x2c\\xc7\\xe5\\x86\\xc2\\xb0\\xa4\\x25\\x1c\\xf3\\xc1\\xf8\\xf1\\x77\\x03\\xb8\\x88\\xce\\xc9\\x33\\xc9\\xa5\\x9f\\xf4\\x9f\\xd7\\xfa\\xcf\\x5f\\xf5\\x9f\\x67\\xd1\\x65\\xff\\xd0\\xd1\\xc7\\xb0\\xb8\\x18\\x5f\\xc6\\x82\\xbe\\x24\\xb7\\x38\\xed\\x3d\\xee\\xc3\\x3e\\x44\\x10\\xc1\\xbe\\x7a\\x73\\xa0\\x88\\x6e\\xd0\\xfc\\x1a\\x0b\\x46\\x92\\x16\\xb2\\x9b\\x74\\x6b\\xd0\\x5d\\x48\\x1f\\x8f\\x15\\xe9\\x9a\\x72\\x4d\\xb8\\xa6\\x5b\\x93\\xbd\\x16\\x98\\xdf\\x9f\\x74\\x49\\xfb\\x73\\x86\\x56\\x80\\x40\\xc9\\x4c\\xec\\x28\\x4c\\x19\\x5a\\x9d\\xcb\\x67\\x3d\\x35\\x85\\x1c\\x33\\x82\\xf9\\x39\\x11\\x19\\xe6\\x03\\x10\\xf2\\xef\\xf9\\xba\\x90\\x9f\\x53\\x24\\xd0\\x00\\x70\\x86\\x97\\x38\\x17\\x27\\xe9\\x40\\xce\\xf6\\x3b\\x29\\xba\\x72\\x9d\\x33\\x71\\x92\\xa7\\xf8\\xd6\\x0d\\x4e\\x42\\x2b\\xb4\\x30\\x85\\x1c\\xaf\\xc0\\x2c\\x83\\x1b\\xc2\\x4b\\x94\\x91\\x9f\\xd5\\x82\\x89\\x9f\\x5b\\xa0\\x5e\\xbf\\x12\\x47\\xd9\\x98\\xc0\\x14\\xc6\\x87\\x40\\xe0\\x49\\x40\\x8f\\x11\\xc8\\x43\\x20\\xfb\\xfb\\x56\\xe4\\xaa\\x7e\\x62\\x94\\xa6\\xc7\\x34\\x2b\\x97\\x79\\xcf\\x51\\x7d\\x41\\x2e\\x07\\x01\\x8a\\x0b\\xa2\\x79\\x27\\x45\\x33\\x68\\x7a\\x4a\\x57\\xbc\\x27\\x9f\\xa8\\xd7\\x64\\x06\\xbd\\xaf\\x7a\\xd5\\x58\\x95\\x52\\x23\\x79\\x4a\\x57\\x66\\x1d\\x57\\x12\\x1f\\x3c\\xbd\\xa8\\x1a\\x5c\\xc2\\x54\\xbd\\x56\\x8b\\xa2\\x6b\\xf4\\x7a\\xe4\\x29\\x4d\\x4a\\xd9\\x28\\x9e\\x63\\xf1\\x42\\xb7\\x7f\\xb6\\x3e\\x49\\x5d\\xe7\\x7d\\x43\\xb0\\x61\\x6c\\xc2\\xf9\\x71\\x86\\x38\\x7f\\x83\\x96\\x98\\xc3\\xd4\\xd0\\x11\\x2d\\x30\\x4a\\x31\\x3b\\xa5\\xab\\x68\\x02\\x51\\x34\\xd0\\x0f\\xd5\\x5c\\x9b\\x67\\xea\\xf3\\x90\\xd1\\x95\\x7d\\x49\\xd3\\xf4\\xbc\\xf5\\xbd\\xec\\xed\\xd0\\xf4\\x46\\x0b\\xe1\\x3a\\x41\\x99\\xc0\\x2c\\x47\\x52\\xb7\\x9f\\xd2\\xd5\\x99\\x58\\x67\\x78\\x02\\x82\\x95\\x58\\x63\\x2c\\xd0\\x1c\\x4f\\x20\\xc2\\xb9\\xd2\\x4a\\xee\\xd9\\x19\\xf9\\x19\\x4f\\x9c\\xb4\\x18\\x54\\x19\\x5d\\xfd\\x59\\x2c\\x33\\x1f\\x81\\x14\\x23\\x3d\\x85\\x13\\x27\\x52\\xee\\xd5\\x11\\x4f\\x70\\x9e\\x92\\x7c\\x3e\\x81\\x19\\xca\\xb8\\x69\\x14\\xf0\\x63\\x12\\x7e\\xb5\\x23\\xe9\\x9a\\xa5\\x58\\x0a\\x7f\\xaf\\x92\\x83\\x81\\x1a\\x6e\\xbf\\xb6\\x60\\x32\\x92\\x63\\x50\\x4d\\x6b\\xab\\xe6\\x15\\xc9\\xf1\\xb1\\x7c\\xde\\x0b\\x17\\x4d\\x63\\xa1\\x48\\xb5\\xe7\\x56\\xc6\\x92\\xe4\\x30\\x85\\x93\\x7c\\x46\\x72\\x22\\xd6\\x96\\xd1\\x4b\\x74\\x0b\\x53\\x18\\xfa\\x8f\\xdb\\x96\\x83\\xc4\\xdd\\xb6\\x0c\\x94\\x1f\\x93\\xdf\\x60\\x26\\x94\\x66\\x9a\\x11\\xc6\\x05\\x24\\x8a\\x97\\xd2\\x28\\x23\\x78\\x8e\\x04\\x8e\\x15\\xa8\\x94\\x6d\\x89\\xe6\\x82\\x5c\\xc2\\x57\\x53\\xc8\\xcb\\x2c\\xb3\\x58\\xf4\\x9a\\xb8\\x20\\x97\\x17\\xe3\\x4b\\xb3\\x6e\\x65\\xbb\\x9e\\x7b\\xaa\\x64\\xd1\\x48\\xa3\\xea\\xf5\\x25\\xc9\\x53\\x39\\xa4\\x81\\x1c\\x81\\xee\\xa0\\xa2\\xfb\\x23\\x4c\\xe1\\xe0\\x10\\x3e\\x1a\\xba\\x2f\\xc8\\x65\\x45\\xfa\\x47\\x47\\xba\\x1e\\xff\\x0d\\xca\\x60\\x5a\\x75\\xff\\xf1\\xf2\\xd0\\xbc\\x93\\xd4\\xca\\x77\\x4f\\x64\\x27\\xae\\x09\\x18\\x36\\xde\\xa0\\xcc\\x42\\xde\\xd5\\x5a\\x3c\\x95\\x14\\x05\\x2d\\x14\\x8b\\x1b\\x2d\\xee\\xec\\xea\\x92\\xfe\\x05\\x86\\x94\\xe6\\x91\\x80\\x15\\xca\\x85\\x64\\x1c\\x5f\\xd0\\x15\\xa0\\x7c\\x2d\\x9b\\x95\\x98\\x83\\x72\\x85\\xc4\\x02\\xe5\\x30\\x06\\x4e\\x21\\x41\\x85\\xe2\\xb7\\x24\\x46\\x41\\x00\\x92\\x13\\x80\\x44\\xac\\xf1\\x1d\\xe9\\xe9\\xe0\\x68\\x89\\x41\\x90\\x25\\x1e\\x68\\x84\\x07\\xe3\\x3f\\x5a\\x1f\\x6d\\xce\\x50\\xb1\\x80\\x6b\\x9c\\xd1\\x55\\x0d\\x13\\x99\\xc1\\x0a\\x43\\x82\\xf2\\xd8\\x09\\xce\\xdf\\x95\\x20\\xc3\\x54\\x81\\x0d\\xa1\\x27\\x87\\x34\\xd4\\x9c\\x19\\xc1\\xc1\\xd8\\xaa\\x2e\\x07\\xf9\\x04\\xc6\\x96\\x05\\x7e\\xf3\\xf1\\xa1\\x37\\xe8\\xa3\\x34\\x55\\x5d\\xa7\\x58\\xc9\\x9e\\x14\\x6f\\x3a\\x03\\x8c\\x92\\x85\\x95\\x20\\x94\\x6b\\x88\\x1c\\x27\\x98\\x73\\xc4\\xd6\\x5a\\x0e\\x7f\\x85\\xaa\\x6f\\x53\\xdb\\x51\\x8a\\x04\\x96\\x5c\\x8a\\x6a\\x3a\\xdb\\x88\\x5d\\xb0\\x1e\\x0e\\x1e\\x6e\\x1e\\xa2\\xbc\\x5c\\x5e\\x63\\x56\\xef\\x65\\x17\\xcb\\xa0\\x19\\x76\\xcc\\x30\\x12\\x58\\x71\\x45\\xea\\x01\\xc5\\x9a\\x70\\xb4\\xbf\\x97\\x09\\x71\\x2a\\xe8\\x3e\\x66\\x64\\x34\\x82\\xf3\\xb7\\xcf\\xdf\\xf6\\x6e\\x96\\x88\\x2d\\x69\\xd6\\x9f\\xc0\\x2b\\x4a\\x3f\\x01\\xc9\\x05\\x95\\x8a\\x2e\\x9f\\x5b\\x07\\xe7\\x86\\xe0\\x95\\xa1\\x4f\\x2e\\x86\\x39\\x16\\x80\\x80\\x2f\\x29\\x95\\x7e\\xb5\\x46\\x84\\x72\\xb2\\xac\\xc6\\xdc\\xb0\\x18\\x49\\xc9\\x6e\\x94\\x25\\x9e\\x40\\x64\\x75\\xa7\\xb1\\x0c\\x0b\\x2c\\x03\\xab\\x09\\x7c\\x3b\\x1e\\xeb\\x07\\x19\\x9e\\xe3\\x3c\\x9d\\xc0\\xe7\\x82\\x72\\x25\\x85\\x13\\x88\\x72\\x9a\\xe3\\xe8\\x6e\\x60\\xd4\\x4a\\x52\\xf2\\x73\\xc4\\xe6\\x58\\x4c\\x20\\x4a\\x90\\xc0\\x73\\xca\\xd6\\x06\\xdb\\xcd\\xd1\\x2d\\xe1\\x93\\x6a\\xb1\\x2b\\x0f\\x60\\xa2\\x14\\xef\\xc0\\x2a\\x19\\x82\\x57\\x5a\\xfe\\x27\\xa1\\x16\\x99\\xb8\\x95\\x31\\x08\\x15\\x43\\x8d\\x2e\\xf3\\xd2\\x23\\xef\\x9a\\x0a\\x41\\x97\\x91\\x53\\x23\\x87\\x9a\\x29\\x27\\x7a\\x6d\\xaf\\x16\\x34\\xc3\\x4a\\x98\\x8c\\xa4\\xc1\\x02\\x71\\xa7\\x10\\xd4\\x32\\x1f\\x80\\x60\\x6b\\xc9\\xdc\\x04\\xe7\\x02\\x33\\x20\\x2a\\xec\\x93\\x30\\xc6\\xe4\\x54\\x2b\\x1a\\xa6\\x53\\x5f\\xa3\\x49\\x3e\\xc7\\x6a\\xd8\\xb1\\x1b\\x5a\\xac\\x75\\xdc\\x41\\x7c\\x00\\x7f\\x92\\xc0\\x87\\x9b\\x40\\x95\\x02\\x1d\\xc7\\x3f\\x3a\\x50\\x25\\x1d\\x0f\\x33\\x96\\x3f\\x61\\xa1\\x87\\x66\\x82\\x06\\xa3\\xde\\x88\\x1c\\x94\\xd4\\xc6\\x24\\x87\\x1c\\xe5\\x94\\xe3\\x84\\xe6\\x29\\xf7\\x2c\\xe9\\x1c\\x8b\\x13\\x03\\xd4\\x33\\x71\\xd1\\x00\\x0a\\x86\\x6f\\x08\\x2d\\xbd\\x90\\x25\\x29\\x99\\x6f\\x91\\x0c\\x64\\xdf\\x9a\\x4f\\xd9\\xc0\\x7f\\x5f\\x21\\xb0\\x6b\\x76\\xc9\\x61\\xf8\\x14\\x72\\x1e\\x3b\\xc7\\x59\\x22\\x91\\xcb\\xe5\\x9c\\x2c\\x71\\xaf\\x0f\\x43\\x85\\xc4\\x3d\\xe8\\xc3\\x9f\\x94\\x3b\\x3e\\x1e\\x8f\\xed\\x20\\x8f\\x17\\x38\\xf9\\xc4\\xe5\\x84\\x78\\x81\\x22\\x4e\\x81\\x0b\\x24\\x38\\x90\\x3c\\xc9\\xca\\x14\\xd7\\xde\\x31\\xcc\\x69\\xc9\\x12\\xdf\\xe5\\x5e\\x20\\x7e\\x6a\\x9e\\xf6\\x54\\xd3\\x41\\x05\\xa5\\x07\\x6c\\x08\\x54\\xef\\x62\\xfd\\xbf\\x61\\xeb\\x53\\x18\\xcb\\x78\\xcc\\x7b\\x73\\x31\\xbe\\xbc\\xb0\\xad\\x2f\\x9b\\x84\\xa2\\x2c\\x93\\x91\\x89\\x40\\x24\\xc7\\x4c\\xd2\\x08\\x05\\xa3\\x37\\x24\\xc5\\x29\\x64\\x84\\x8b\\x07\\x11\\xfd\\x92\\xb2\\xa3\\x2c\\xeb\\x55\\x68\\x4f\\xf2\\x19\\x6d\\x8c\\x41\\x4a\\x6d\\x08\\x61\\xc7\\x30\\x9d\\x4e\\x9d\\x55\\x32\\x43\\x55\\x0e\\x9d\\x55\\xbf\\x6d\\x8e\\x4f\\x2b\\xaa\\x40\\xd5\\x2b\\x85\\xeb\\xb3\\x36\\x6c\\xa2\\x42\\x81\\x8a\\x44\\xe7\\x17\\xd4\\x09\\xb0\\x0e\\x41\\xf5\\x46\\xfa\\xa7\\x35\\x97\\x90\\x63\\x21\\x05\\x5c\\x85\\xe8\\x3c\\x96\\x12\\x87\\x80\\x70\\x95\\xac\\x61\\x84\\xe3\\x54\\xbe\\x44\\x39\\x20\\xc6\\x90\\x4a\\xc6\\xa8\\x0f\\xdc\\x64\\x70\\x56\\x54\\x62\\x32\\xeb\\x8a\\x4f\\xe4\\x17\\x04\\x5c\\x30\\xa9\\x74\\x33\\x74\\x8d\\x33\\x65\\x58\\x90\\x74\\x98\\xb1\\x0c\\x2f\\xb5\\x37\\x60\\xb3\\x13\\xaa\\xcf\\x9a\\x23\\xfa\\x93\\xa2\\xa3\\xe7\\x79\\x9c\\x9a\\x32\\x3d\\x48\\x43\\x65\\x99\\xf3\\x05\\x99\\x89\\xde\\x45\\xf4\\x4a\\x76\\x22\\x83\\xc9\\xbf\\x49\\xcc\\x2a\\x98\\x6c\\xd8\\xb5\\x82\\x16\\x65\\x26\\xbf\\x28\\xc7\\x40\\x8e\\xcf\\xc4\\x8d\\xce\\xe4\\xc3\\xb4\\xdd\\x26\\xa9\\xc1\\x9e\\x53\\x67\\xf0\\x0d\\x31\\xf7\\xb2\\x9e\\xc6\\x92\\xa8\\xac\\x8a\\x35\\x26\\xd6\\x62\\x1c\\x58\\x8b\\xc1\\x70\\xfa\\x92\\xd1\\xe5\\x04\\x7e\\x74\\x0f\\xce\\xa9\\x07\\xb0\\xc6\\x32\\xcc\\xd0\\x30\\xff\\xf7\\x7b\\xff\\x99\\x04\\xb3\\xad\\x96\\x24\\xa7\\xec\\x9c\\x24\\x9f\\xf8\\x04\\x0c\\x50\\x65\\xd5\\x26\\xf0\\x39\\x2d\\x99\\xf9\\xf8\\xa3\\x8c\\xcd\\x31\\xe2\\x2a\\x04\\x89\\x64\\x5c\\x80\\x58\\x74\\xe7\\x87\\x4b\\x4a\\x69\\x56\\x86\\xbb\\xd3\\x6c\\xab\\x09\\xdb\\xd5\\x64\\x6b\\x3b\\x50\\x29\\xdf\\x81\\xe5\\x8b\\xaf\\x7a\\xb5\\xeb\\x88\\x92\\x85\\x8c\\x55\\x48\\x3e\\xa3\\xa1\\x82\\x7d\\xad\\xdf\\xc8\\x75\\xd0\\x63\\x94\\x8a\\xe7\\x84\\x0d\\x20\\x41\\x59\\x76\\x8d\\x92\\x4f\\x5a\\x4a\\xbe\\x96\\x54\\xfc\\xe5\\xec\\xed\\x1b\\x0b\\x00\\xfb\\x10\\xa1\\x82\\x8c\\x6e\\x0e\\xe2\\xf1\\xc8\\xa0\\x8e\\x06\\x60\\xd1\\x6a\\x8f\\x08\\x3e\\x57\\x68\\x8c\\x8b\\x04\\x77\\x01\\x5d\\x05\\x6f\\x21\\xe7\\x1d\\xa3\\xd2\\x8f\\xac\\x91\\x63\\x57\\xab\\x8c\\xdc\\x76\\xa7\\xee\\x71\\x3c\\x1e\\x15\\x3c\\x82\\xfd\\x10\\x41\\xdf\\x4c\\x41\\x9c\\xd2\\x1c\\xf7\\x76\\x20\\xda\\xc2\\xcf\\x10\\xc9\\x1c\\xfc\\xc7\\x7f\\x2e\\x6e\\xd9\\x00\\x04\\xbe\\x15\\x67\\x02\\x89\\x92\\x0f\\x00\\x33\\x46\\x59\\x80\\xe3\\xe2\\xb2\\x31\\x6c\\x65\\xbf\\x2d\\x3d\\xc6\\x3c\\xd4\\xf2\\x8b\\x38\\x75\\x10\\x21\\x7b\\x64\\x4f\\x7c\\x47\\xc6\\x8c\\x46\\x70\\x8a\\xff\\x59\\x62\\x2e\\xe0\\x87\\x31\\x97\\xba\\xc6\\x75\\xbb\\x20\\x5c\\x50\\xb6\\x56\\x2b\\x2d\\xa7\\xd2\\xe7\\x28\\xa4\\x97\\x5c\\x65\\x9f\\x74\\xb3\\x29\\x48\\xbe\\xc6\\x5a\\x01\\x91\\xd9\\xba\\x57\\x05\\x94\\xef\\x0b\\xe9\\x90\\xc3\\x12\\x91\\x5c\\x9b\\x1a\\xd3\\x13\\x4e\\x9f\\xad\\xdf\\x9f\\xc0\\x6a\\x41\\x32\\x0c\\xa5\\x04\\x92\\xaa\\xeb\\x51\\x5e\\x2e\\xaf\\x14\\xd8\\x23\\x58\\x60\\x66\\x82\\xcd\\xa8\\x7a\\x1a\\x4d\\xe0\\x07\\xb3\\xe0\\xf4\\x43\\x4d\\x4e\\x34\\x81\\xb1\\x5c\\x41\\x5a\\x3d\\x7c\\x1d\\xaf\\x16\\x38\\xef\\x59\\xf7\\xec\\xeb\\xb8\\xa0\\x5c\\xb4\\x4a\\xa4\\xb3\\x69\\x8d\\xb9\\x1f\\xd8\\xb1\\xf5\\x07\\x5b\\x11\\x1d\\x8c\\x78\\x79\\xbd\\x13\\xae\\x0e\\x89\\x72\\x6d\\x4f\\x31\\x2f\\x06\\x10\\xa0\\x93\\x8f\\xfc\\x08\\xb4\\x12\\x99\\x10\\xe4\\x62\\x7c\\xd9\\xd2\\xd0\\x45\\xdb\\xe0\\x49\\xd7\\x73\\xab\\x32\\x75\\xe0\\x28\\x85\\xea\\xf8\\xdd\\x7b\\x28\\x39\\x6a\\x98\\x85\\xe3\\xa2\\x3c\\xa7\\x02\\x65\\xef\\xe5\\x3b\\xdf\\x3a\\x2c\\x9d\\x3a\\x18\\x68\\xe1\\x74\\x26\\xdb\\x78\\x16\\x05\\x4e\\xe2\\x05\\xe2\\x57\\x49\\x51\\x4a\\x7f\\xe3\\xab\\x16\\x97\\x25\\x4a\\x8a\\x32\\xea\\x87\\x76\\x3c\\xc8\\x54\\x29\\x27\\x5c\\xaa\\xef\\x8b\\xe8\\x5c\\x47\\x75\\x91\\xa2\\x27\\xba\\x3c\\x0c\\xcd\\xc8\\xc5\\x65\\x67\\x78\\xd7\\xf0\\x80\\x02\\x93\\xef\\x1c\\x43\\xdf\\x21\\x22\\x26\\x79\\xe0\\xf9\\x85\\xc1\\x6b\\x18\\xc2\\x81\\x07\\x62\\x5d\\xd4\\x37\\x92\\xd4\\x9a\\x37\\x1a\\xcb\\x70\\x94\\x0b\\xb4\\x2c\\xb4\\x4f\\xea\\xbe\\x6b\\x79\\xd5\\x18\\xac\\x2d\\xaf\\x86\\x02\\xd5\\xa3\\xb8\\x28\\xf9\\x22\\xc4\\xd4\\x6f\\x83\\x50\\x20\\x49\\x51\\xc6\\x7a\\x22\\x85\\xe4\\x93\\xf5\\x48\\x6b\\x8f\\x65\\xa8\\xef\\x68\\x36\\xd8\\x54\\x3c\\xae\\x30\\x59\\xbc\\x2e\\x98\\x0d\\x52\\x55\\xa2\\x2b\\x49\\x15\\x1d\\x53\\x86\\x79\\xb4\\x4d\\xd0\\x32\\x8a\\xd2\\xa6\\x9c\\xbd\\xa2\\x28\\xdd\\x45\\xc2\\x3a\\xc4\\xe2\\xe8\\x06\\x33\\x34\\xc7\\xbf\\x87\\x60\\x7c\\xc9\\x49\\xb3\\x73\\x26\\x79\\x72\\x85\\xf4\\x18\\x54\\x1e\\x66\\x3c\\xfe\\x72\\xd3\\x72\\x5a\\xe6\\x2a\\xa1\\x0a\\x62\\xc1\\x30\\x4a\\x37\\xcf\\x50\\x81\\xd9\\x30\\xa1\\x0c\\x6f\\xd2\\x09\\xef\\x30\\x93\\x53\\xfd\\xaf\\xd0\\x0a\\x26\\xd9\\x84\\xb4\\x0c\\x28\\x8a\\x4d\\x9a\\x89\\x55\\xae\\x65\\x5d\\x3c\\x9a\\x22\\x60\\x22\\x02\\x8f\\xde\\x58\\x1a\\x14\\x89\\x84\\x07\\x52\\xa0\\x51\\x69\\xfe\\x2b\\xf1\\x56\\xbb\\x22\\xa4\\x9a\\x82\\xff\\x4f\\x54\\x90\\x8a\\xb4\\x02\\xf5\\x51\\x60\\x26\\xe7\\xe8\\x4a\\x7d\\x83\\xe9\\x54\\x6d\\x4c\\xce\\x48\\x8e\\x53\\xdf\\x1a\\xb9\\xc9\\xa9\\x12\\xba\\x0f\\x5e\\x18\\x41\\xce\\x77\\xac\\x73\\xbe\\x1d\\x13\\x14\\xa4\\x7e\\x43\\xcc\\x15\\x69\\xb0\\x71\\x44\\x17\\x1f\\x2f\\x9b\\xba\\xb1\\x0e\\xd1\\x87\\x91\\x87\\xae\\xa1\\x30\\xef\\x7e\\x5f\\xb5\\xa9\\x67\\xe2\\x9a\\x61\\xf4\\x29\\xa5\\xab\\xbc\\xb9\\x2a\\xd5\\x72\\x7c\\x66\\xdf\\x77\\xae\\xcb\\x20\\xa6\\xed\\x08\\xb4\\x37\\xaf\\xd3\\x00\\xf4\\x61\\x56\\xfc\\x3d\\x57\\xd9\\xd3\\xe8\\xaf\\x98\\xe5\\xf8\\x3e\\xe6\\xbc\\x46\\xe6\\xf6\\x35\\xd5\\xd2\\xa0\\x6d\\x6d\\xb5\\x82\\xfd\\x07\\x98\\xf9\\x92\\x63\\xd6\\x94\\x64\\xf9\\xb4\\xd5\\xc8\\x77\\x2c\\x96\\x1a\\x52\\xbe\\xe6\\x02\\x2f\\x9b\\x68\\xf5\\xf3\\xdf\\xc9\\x7b\\x38\\xd5\\xb9\\x13\\x1d\\x0f\\x1b\\x11\\x52\\x11\\xbf\\x14\\x91\\x19\\xa3\\xcb\\x20\\x3f\\xe2\\xfb\\xbe\\x26\\x99\\x54\\x72\\x93\\x84\\x96\\xd8\\x0a\\xc4\\x39\\xd6\\x8d\\x5f\\xaa\\xfd\\x2c\\x9b\\x9a\\x51\\x19\\xc6\\x94\\xdc\\x90\\xb4\\x44\\x99\\x46\\x5e\\x50\\x22\\x59\\x14\\x46\\x54\\x1e\\x7e\\x35\\x90\\xe7\\x48\\xa0\\x5e\\x4b\\xaf\\xba\\x87\\x6e\\x5f\\x65\\x07\\x51\\xb7\\xfb\\xd6\\x75\\xe4\\x6d\\x82\\xee\\x1b\\xa8\\x46\\x83\\x0b\\x72\\x19\\xe7\\x32\\x94\\x6d\\xd1\\xb0\\x66\\x57\\xad\\xb5\\x4d\\xb8\\xac\\x1a\\x1b\\x6d\\xc6\\x58\\x75\\xb6\\xf4\\xf6\\xde\\x7c\\xeb\\xb5\\x01\\xde\\x2c\\x34\\xd3\\x48\\x45\\xc0\\x39\\x66\\x2a\\xc7\\x03\\xbc\\x40\\x8c\\x63\\x33\\xd3\\x3a\\xff\\x65\\x17\\x08\\x20\\x21\\x27\\x0f\\xdf\\xc2\\xcf\\x98\\x51\\x27\\x1d\\x6a\\x02\\x01\\x09\\x87\\x4f\\x43\\x91\\xfd\\x83\\x81\\x9c\\xfb\\x6b\\x0c\\xa5\\x94\\x06\\xc4\\xf5\\xb6\\xa6\\xd9\\x7b\\x62\\x74\\x15\\x7b\\x74\\xfb\\x8b\\x35\\x58\\x97\\xd5\\xe8\\x9a\\x33\\x34\\xa3\\xec\\x05\\x4a\\x16\\x2e\\xb8\\xf3\\xad\\x65\\xb8\\xf8\\xd4\\xae\\xa9\\x1f\\x9d\\x85\\x40\\x17\\x64\\xff\\xe0\\xd2\\xec\\x67\\xbe\\xcc\\xe5\\x02\\xd5\\x8a\\xa5\\x02\\xec\\x58\\x71\\x8d\\xe4\\xa3\\x2f\\x27\\x13\\xf3\\x77\\x50\\xad\\xd9\\x89\\x5e\\x88\\xaa\\xc9\\x46\\x9f\\xd0\\x1f\\xeb\\x16\\xdf\\xd0\\x5f\\x2b\\x0d\\x1f\\xb1\\xc1\\x33\\x67\\x82\\xbe\\x6a\\x26\\x88\\x5b\\x16\\xd8\\x56\\x73\\x93\\xd8\\xe5\\xa9\\xb5\\xf4\\xae\\x2b\\xd7\\xb0\\xd5\\x85\\xe5\\x15\\xc7\\x3d\\x9b\\xf2\\x60\\x13\\xe0\\x68\\xad\\x2b\\xdb\\xdd\\x03\\xb5\\xc3\\x3d\\x2b\\x28\\xa1\\x4a\\xad\\x06\\x1c\\x5b\\xe5\\xea\\x9e\\x3c\\xc4\\xdb\\x68\\x4c\\xf7\\x12\\x2f\\x29\\x5b\\xb7\\xce\\xf8\\x6b\\xf5\\xea\\xb7\\x9f\\x74\\x4d\\xc2\\xbf\\x64\\xde\\xcd\\xb4\\xc9\\x59\\xd3\\x54\\xe8\\x19\\x82\\x11\\xd0\\x1c\\xbf\\xc6\\x73\\x74\\xbd\\x16\\xf8\\xcb\\xcc\\x8d\\xc5\\x66\\xe7\\x27\\x9c\\x20\\x95\\x04\\x57\\x33\\x44\\x65\\xa4\\x98\\x65\\xd5\\x66\\x44\\xeb\\xd4\\xbc\\xd5\\x40\\x9b\\xa3\\xb4\\x16\\x6f\\x70\\xb3\\xef\\xd4\\xed\\x80\\x55\\xde\\x92\\x44\\x60\\x88\\xd5\\xf6\\xcd\\x22\\x35\\x3e\\xaa\\xad\\x1e\\xd8\\xee\\x76\\x6e\\xe8\\xec\\xe9\\x14\\x1e\\xfb\\x2b\\x73\\x83\\x1f\\xb7\\x91\\xe4\\xc7\\x9e\\x83\\xc7\\xd0\\xca\\x12\\xb8\\xfb\\x1a\\xfd\\x52\\xfe\\xa1\\x5f\\x7f\\x43\\x61\\x49\\xb2\\x8c\\xa8\\x70\\x47\\x97\\x4e\\xa0\\x4f\\x7a\\x23\\xa5\\xc0\\x2c\\xc1\\xb9\\x40\\x73\\xac\\x77\\xc7\\x2b\\x96\\x56\\x56\\xe6\\x35\\x12\\x8b\\x98\\xd1\\x32\\x4f\\x7b\\xbd\\x5e\\x35\\xa2\\xc0\\x65\\x83\\x51\\x7b\\x64\\x65\\xf6\\x2b\\x8d\\xba\\x52\\xd3\\x63\\xf1\\x3f\\x55\\x2f\\x2a\\x63\\xe6\\x4d\\xe5\\xc1\\x78\\xec\\xc7\\x43\\x66\\xaf\\x48\\x19\\xa6\\x8b\\xe8\\xf8\\xdd\\xfb\\x68\\x50\\x41\\x5f\\x86\\x75\\x68\\x7a\\x35\\xed\\x2a\\x12\\x1a\\xda\\xab\\x56\\x3a\\x43\\xa2\\x54\\x3e\\x82\\xa0\\xc1\\xe6\\x05\\x27\\x3f\\x9b\\xd4\\xb1\\xec\\x44\\x15\\xd7\\x36\\x05\\x43\\x62\\x35\\xab\\x59\\x41\\xb8\\x21\\xeb\\x06\\x4f\\x03\\x0e\\x69\\xc8\\xab\\x04\\x15\\x28\\x21\\x62\\xed\\xf8\\x60\\xb1\\x6f\\x00\\x0e\\xa2\\xe3\\x70\\xc8\\xfe\\x54\\xb5\\xa8\\x17\\x85\\x3c\\x9c\\x93\\x90\\xbb\\x5a\\xf9\\x46\\x03\\x1f\\x6d\\x8d\\xc7\\x79\\xb9\\xfc\\xc9\\x2e\\x45\\xd3\\xd8\\xf8\\x75\\x7b\\x2e\\xec\\x9f\\x91\\x0c\\x5b\\xdf\\xfe\\x73\\xe8\\x2a\\xfa\\xfb\\xa7\\x01\\x64\\x9b\\x33\\x1a\\x38\\xb6\\x21\\x78\\x15\\x73\\x19\\xaf\\xb8\\xca\\x2a\\x5b\\x36\\xcc\\x32\\x4a\\x59\\x4f\\xed\\xa6\\x18\\x06\\xa8\\x71\\xc7\\x63\\x29\\xad\\xea\\x69\\xc5\\xfd\\xc3\\xc0\\x49\\x93\\x23\\xb3\\x05\\x07\\x28\\xbd\\x21\\x9c\\xb2\\x78\\xc6\\x15\\xee\\xb8\\x72\\xa6\\x14\\x82\\x14\\xdf\\x10\\xb5\\xc3\\xed\\xfc\\x42\\xb3\\x41\\xe1\\xa9\\x57\\x53\\x3a\\xa1\\xcb\\xf9\\x29\\x4b\\x31\\xb3\\x3e\\xa1\\x06\\xb8\\x70\\x1c\\xdd\\x97\\xbd\\xc7\\xca\\xb5\\xbc\\x54\\x0e\\xfe\\xcb\\x33\\xf8\\x43\\x04\\xfb\\xd0\\xab\\x9e\\xc3\\x3e\\x1c\\xf4\\x07\\xde\\x70\\x2f\\xeb\\xd5\\x6f\\xaf\\x94\\x04\\xa9\\xd2\\x28\\x55\\x53\\x24\\x83\\x19\\xc7\\x36\\x4b\\x55\\x4a\\x78\\x91\\xa1\\xb5\\xae\\x8f\\xff\\x3e\\xb6\\x8d\\xa3\\x97\\x0e\\x32\\xc5\\x02\\x91\\x8c\\x47\\xc0\\xb1\\xb6\\x01\\x5c\\x90\\x2c\\x53\\xd5\\x62\\x7a\\x07\\x8d\\xe9\\xfd\\x48\\x35\\xb7\\xd2\\x78\\xb8\\x5e\\xb8\\x5b\\x2e\\x4b\\x74\\x7b\\x55\\xe9\\x6e\\x7f\\xa8\\xdf\\xbb\\x15\\x12\\xc8\\x91\\x2e\\x92\\xbb\\xf2\\xb7\\x8b\\x1d\\xb3\\x9c\\xd0\\xf1\\x8c\\x24\\xb8\\x37\\x1e\\xf8\\xc0\\xbe\\xbb\\x6a\\x0c\\x67\\xe7\\x3e\\xb4\\x32\\x87\\x6a\\x4b\\xd7\\xd9\\x5c\\xa5\\x7c\\x1e\\x7f\\xa7\\x04\\xe5\\xf1\\x77\\x87\\xf6\\xf5\\x4f\\xa4\\xfe\\x3a\\xb0\\xd3\\x6d\\xfe\\xcb\\xbd\\x6d\\xe4\\x56\\x3d\\xb5\\x35\\x69\\xb2\\x83\\x43\\xd3\\xb9\\xfb\\x31\\x80\\xe8\\xcf\\x54\\xdc\\x23\\x94\\xfc\\x62\\x59\\x93\\x2f\\x9d\\xfb\\xee\\x76\\xa8\\xb6\\x35\\x59\\x51\\xf6\\x89\\xe4\\xf3\\x2b\\x8e\\x45\\x6b\\xc3\\xce\\x84\\xc4\\x9e\\x09\\x30\\xcd\\x8e\\xb7\\x9e\\x2d\\xa5\\x6a\\x07\\xc0\\xb7\\x98\\x14\\x67\\xb5\\xae\\x76\\xd4\\xfc\\x1d\\x82\\xe2\\x9b\\x1e\\xf8\\xe6\\x9b\\x3d\\x9b\\x86\\xd9\\x02\\xf9\\x24\\xe8\\xbd\\x92\\x9d\\x1a\\x49\\x3b\\x98\\x3a\\xcb\\x86\\xf7\\x76\\xef\\x55\\xf9\\x16\\x8c\\xce\\xd5\\x31\\x97\\x6b\\xc4\\xe2\\x2f\\xe5\\x08\\x2e\\xa8\\xd0\\x6b\\xac\\xa6\\xe8\\x3b\\xa6\\xd2\\x53\\xfa\\xc1\\x50\\x2d\\x3a\\xa5\\x49\\xb7\\x21\\x6c\\xd8\\x8f\\x56\\x54\\x09\\xcd\\xd2\\x0a\\x93\\x8f\\x77\\xe8\\x88\\x96\\xb0\\x5f\\xf7\\xa2\\x3f\\x58\\xd6\\x0c\\x17\\x54\\x0c\\xed\\xd2\\x8d\\x57\\x24\\x15\\x8b\\x9e\\x1b\\xe1\\x3e\\x44\\x7f\\x8c\\xfa\\x8d\\x36\\xb2\\xa3\\x7a\\x23\\xaf\\xf3\\xb0\\x95\\x86\\x1b\\x0a\\x7c\\x2b\\xa2\\x6a\\xc3\\x58\\x7e\\xf3\\x53\\xdb\\xfe\\x59\\x96\\xfa\\xb8\\xf5\\xe1\\x8d\\x91\\xda\\xa8\\xf0\\xe1\\x02\\x1e\\xc0\\xbe\\x87\\x2d\\x82\\x9e\\x04\\xf6\\x59\\x20\\x69\\xea\\x47\\xda\\x35\\xdd\\x35\\x7f\\x57\\x0f\\x5e\\xbc\\x55\\xa6\\x6d\\xa1\\x5f\\xd0\\x37\\x43\\xfe\\x79\\x34\\x57\\xd0\\x90\\xa3\\x25\\x0e\\x33\\x6f\\x6f\\xb0\\x90\\x02\\x72\\x62\\x5b\\xa9\\x92\\xfe\\x5e\\x85\\x44\\x6f\\xb1\\x57\\x5f\\x8d\\x09\\x6a\\x53\\x82\\x0e\\xa6\\xab\\xf6\\xcb\\x41\\xd8\\xcc\\x19\\x4c\\xa7\\x10\\x74\\xd5\\xa8\\xfa\\x22\\xad\\x49\\x97\\xe1\\xc1\\x86\\xf8\\x3a\\xd7\\x23\\x02\\x71\\x3b\\x62\\xb7\\xa0\\x58\\x56\\x0b\\xdd\\xcc\\x98\\xd5\\x51\\x9d\\x07\\x6e\\xb0\\xd9\\x4e\\xba\\x36\\xd9\\xcc\\xfb\\x4d\\x1b\\x6d\\x72\\xf6\\xdc\\x64\\xa9\\x39\\xb4\\x6a\\x81\\x04\\xb3\\x01\\x53\\x35\\xe0\\x80\\x8e\\x5a\\xc9\\x61\\xc5\\xe6\\x7a\\xc3\\xce\\x19\\xae\\x04\\xb4\\xee\\xdc\\x19\\xca\\xe3\\x0a\\xd5\\xa0\\x56\\xcc\\xd8\\x84\\x70\\xc9\\xe8\\x60\\x9a\\x35\\x0d\\x5e\\x81\\x7b\\x42\\x73\\x4e\\x33\\x1c\\x67\\x74\\xee\\xfa\\x8f\\xde\\x9b\\xdd\\x53\\x0a\\x33\\x92\\xa7\\x6e\\x08\\x8f\\xa2\\x01\\xd4\\xe4\\x30\\x7a\\x24\\x1d\\xc8\\xa8\\xaa\\x1a\\x09\\xf6\\xfe\\x0c\\x59\\x41\\x36\\x68\\xab\\xc1\\x37\\x02\\x22\\x3f\\x9f\\xda\\xcf\\xff\\x9e\\xd5\\x0f\\x27\\xf9\\x19\\x4e\\xee\\x15\\xf9\\x9a\\x9d\\x6e\\x5b\\x21\\xfb\\x25\\x9d\\x8b\\x70\\x6b\\xa3\\x29\\x10\\x17\\xa1\\x10\\x5c\\xc6\\xe2\\xf6\\x4a\\x31\\x17\\x86\\x4e\\x33\\x2a\\x72\\xef\\xd1\\xd6\\xdf\\x30\\x0c\\xb8\\xf2\\x65\\x48\\x64\\xbf\\x82\\x44\\xb6\\x23\\x89\\x5f\\x60\\x1f\\x47\\x69\\x2d\\x28\\x30\\x03\\x5d\\xaa\\xbd\\x31\\xd7\\x68\\xd5\\x94\\xaa\\x89\\xe3\\xad\\x5a\\xf0\\x85\\x7a\\xf5\\x3f\\x35\\xf8\\xdf\\xad\\x06\\xb5\\x02\\xfc\\x9f\\xea\\xfb\\x6d\\x54\\x9f\\x5e\\x7e\\x0f\\xd4\\x7d\\xba\\xf1\\x6f\\xaf\\xfc\\x1e\\x4e\\x24\\xdb\\x95\\xc8\\x2f\\xa0\\xfe\\xb4\\xba\\x6a\\xd5\\x7f\\x5e\\xb6\\xc9\\x4b\\xf1\\xe8\\x68\\x45\\x9f\\x0e\\xac\\xf9\\x81\\x2f\\x49\\x86\\xcf\\x14\\x94\\xce\\x50\\x6c\\x2a\\x8a\\x6b\\x0a\\x73\\x8b\\x0a\\xb2\\xe2\\xab\\x76\\x5e\\xda\\x53\\x7f\\x2d\\x0b\\x12\\x67\\x30\\x95\\xc1\\xc9\\x93\\x94\\xdc\\x3c\\x8d\\x3a\\x0f\\x5a\\x6f\\x4f\\x10\\x6e\\x4f\\x0f\\x7e\\x81\\xe4\\xa0\\x4d\\x8e\\x19\\x6e\\x3f\\x7f\\xfb\\xda\\xc9\\x9e\\xb7\\xce\\x1e\\x90\\x37\\xd4\\x62\\xcc\\x63\\x1b\\xd9\\x99\\x92\\x7b\\x13\\xd2\\x79\\x64\\xbb\\x90\\x4e\\x37\\x90\\xf1\\x9b\\x05\\x0e\\x63\\xb9\\xda\\xe9\\x7e\\x37\\xc2\\xb6\\x30\\xce\\x07\\x72\\xb9\\x68\\x17\\xca\\xf9\\x81\\x9c\\x23\\xa4\\x1f\\x19\\x19\\xbe\\xab\\xe5\\xbe\\x4e\\x96\\x68\\x8e\\x79\\x8f\\xa8\\x3f\\xce\\x82\\xea\\xef\\x32\\xf2\\xc9\\xcb\\x2c\\x83\\x5f\\x7e\\x01\\xfd\\xc4\\x1d\\xbe\\xa9\\x9f\\xbd\\xb1\\x4b\\x24\\x38\\xf7\\x05\\x53\\xf8\\x5c\\x9d\\x6a\\xf0\\x54\\xfa\\x29\\x56\\xc7\\xdf\\x74\\xe2\\x3a\\x3a\\x47\\x73\\xe5\\xdb\\x9e\\x3c\\x57\\xc7\\x49\\x08\\x13\\x25\\xca\\xe0\\x8c\\xfc\\xac\\xd4\\xbe\\x3a\\xe8\\x21\\xc9\\x0d\\x4b\\x27\\xdc\\xe9\\x7c\\x85\\x51\\x17\\x9e\\x4b\\xf8\\xb6\\x4f\\xd5\\x51\\x4d\\xfb\\xa9\\x42\\x53\\x1d\\x10\\xb7\\xbb\\x0f\\x3b\\xe5\\xd2\\x02\\x66\\x34\\xa4\\xbb\\x45\\x7f\\x2b\\x8a\\xd1\\xbc\\xfe\\x88\\x49\\x3e\\xc0\\xd4\\xe0\\x93\\x01\\xa7\\x7c\\x72\\x25\\x21\\xa5\\xf1\\xe6\\x45\\x46\\x44\\x2f\\x9a\\x44\\x95\\x9d\\x2c\\x28\\x57\\x4f\\x13\\xdc\\x1b\\x1e\\x0c\\xe0\\x60\\x43\\xdd\\x5c\\x0b\\xce\\xee\\x72\\x0e\\xd5\\x53\\x17\\x25\\x1f\\x9b\\x94\\x18\\xff\\x46\\xb5\\x72\\xae\\xcd\\x81\\x5f\\xe9\\xa0\\x3a\\xd4\\x35\\x29\\x0a\\xec\\x22\\x84\\x96\\x5a\\xc8\\x95\\x3e\\x78\\x9b\\x47\\xa1\\x8d\\xd0\\x43\\xfe\\x48\\x49\\xae\\x7a\\x6f\\xb5\\x23\\xaa\\x27\\x0d\\x32\\x80\\x0e\\x18\\x37\\x2e\\x92\\xc6\\xbc\\xbc\\xe6\\x82\\xf5\\xc6\\x03\\x78\\xfc\\x5d\\x3b\\x78\\x35\\x8a\\xcf\\x37\\x13\\x8f\\x27\\x37\\x5a\\x36\\xaf\\xf4\\x75\\x28\\xb3\\x49\\x90\\x5c\\x69\\x07\\xeb\\xdb\\xb2\\x0e\\x25\\x58\\xfe\\xe1\\x42\\x07\\x9f\\xa8\\xb3\\x4c\\xa9\\x39\\x29\\xd8\\x4a\\x50\\x48\\x87\\x69\\xa0\\x48\\x48\\x63\\x41\\x5f\\xd1\\x04\\x65\\xf8\\x4c\\xc9\\x7b\\xaf\\xea\\x71\\x8b\\x21\\xd3\\xc7\\xaa\\x44\\xe7\\x1d\\x1d\\x51\\x4a\\x93\\x4f\\x98\\x0d\\x75\\xb7\\xd1\\x00\\xbe\\x1d\\xfb\\x77\\x74\\x1c\\x36\\x74\\x89\\x39\\x90\\x23\\xd5\\x09\\x3f\\xa5\\x54\\x0c\\xa0\\x3a\\x7d\\x52\\xb8\\xb3\\x3a\\x4e\\xc9\\x78\\x0f\\xdb\\xf4\\x8a\\xc9\\x9f\\x69\\x94\\x43\\x41\\x8b\\xa8\\xaf\\x15\\x67\\xf4\\x86\\x42\\xf5\\x02\\x66\\xb4\\xd4\\xf6\\xb5\\xa9\\x8b\\x42\\xad\\xb3\\xa7\\x3d\\x58\\x53\\x75\\xf8\\x4e\\x6b\\x9b\\x77\\xe6\\xef\\x99\\x40\\x4c\\x80\\x75\\x35\\x8f\\xdf\\xbd\\x87\\x3f\\xaa\\x4b\\x53\\x5e\\xbc\\xd6\\x1f\\x4e\\xcf\\xce\\xec\\x8d\\x17\\x75\\x05\\xa5\\x8f\\xf4\\x44\\xa6\\xc8\\x9a\\xe4\\x73\\x87\\x86\\x2e\\x97\\x28\\x4f\\x55\\x3f\\x67\\xa7\\xd1\\x1e\\x40\\x87\\xfa\\xd2\\x88\\x37\\xe8\\xab\\xcd\\xda\\xcc\\xfb\\xa4\\x31\\xb5\\xb5\\xda\\xa0\\x17\\x7d\\xc2\\x7c\\x85\\xf8\\x9d\\x75\\x13\\xf4\\x7c\\x76\\x14\\x44\\x9b\\x14\\xb0\\x9d\\x02\\x37\\x32\\x03\\x61\\xba\\xdb\\xb1\\x5e\\xda\\x68\\xd8\\xa6\\x6c\\xec\\xa2\\x66\\xc3\\x35\\xe3\\xe1\\x90\\x8b\\x46\\x15\\x44\\xee\\x00\\x57\\x90\\x74\\x27\\x30\\xc4\\x70\\x2e\\xae\\x76\\x84\\xe6\\x52\\xbe\\xae\\xa4\\xd3\\xde\\xbe\\xbc\\xad\\x2e\\x9e\\x40\\xbd\\x1b\\xbd\\xd9\\x7f\\x95\\x14\\x65\\x55\\xa6\\xb2\\x09\\xc8\\xbb\\xc1\\x47\\x2b\\xd5\\x07\\xf6\\xb7\\xc4\\xcb\\xed\\xfd\\x2d\\xf1\\x72\\xc7\\xfe\\x9a\\x1d\\x31\\xce\\x1b\\x2a\\xb4\\x09\\xd2\\xbf\\x2f\\xfd\\x81\\x8a\\x76\\x03\\xd8\\xd0\\x4b\\xa0\\xad\\x37\\x8c\\xa1\\x39\\xa3\\xa2\\x6c\\xaf\\xa9\\xad\\x0f\\x43\\xab\\x85\\xee\\xd9\\xaf\\xc1\\x27\\xcb\\xdd\\x04\\x90\\x33\\xaf\\x4a\\x23\\x5c\\xa2\\x26\\x1c\\x98\\x33\\x5a\\x16\\x30\\xad\\xf3\\x48\\x3f\\xbf\\x2a\\x90\\x2e\\x01\\xb0\\xbe\\x32\\xd7\\x61\\x09\\x43\\x2b\\xdb\\x32\\x23\\xf9\\x27\\x40\\x1c\\x88\\x00\\x19\\x5e\\xf1\\x6a\\xdf\\xd8\\x9d\\x31\\x8b\\x1b\\xfd\\xbd\\x92\\x8d\\xa6\\x10\\x3d\\x41\\xb0\\x60\\x78\\x36\\x7d\\xa4\\x2e\\x91\\x72\\x67\\xe6\\x5c\\xdb\\x91\\x3a\\x28\\xa7\\xbb\\xda\\x87\\xe8\\xd1\\xd3\\x28\\xd8\\x93\\xd0\\x6f\\x3c\\x6b\\xfd\\xed\\x58\\x7b\\xc4\\x4f\\x46\\xe8\\x69\\x54\\x2f\\x96\\x74\\x82\\xa6\\xdb\\x29\\xe1\\x72\\x14\\xdd\\xdd\\xa7\\x62\\x7f\\xab\\x69\\x0c\\xed\\xd2\\x00\\x1e\\x7f\\xdf\\x30\\x8d\\x7e\\xae\\xab\\x11\\xe9\\xe5\\x34\\x0d\\x02\\x3d\\xa5\\x1e\\xea\\x91\\xde\\x0e\\xd9\\xae\\x8e\\xe0\\xc5\\xf8\\xdd\\xe6\\xac\\x0c\\x2c\\x51\\x01\\x74\\x06\\x3a\\x86\\x51\\xdb\\x2b\\x20\\x68\\x23\\x28\\xda\\x16\\x08\\x39\\xa4\\xf7\\x0e\\x35\\x3b\\x02\\xc8\\x1d\\x23\\xd0\\xdf\\x2e\\xd2\\xc4\\x59\\x8c\\x8a\\x02\\xe7\\xa9\\x73\\xf8\\x1c\\x85\\x9e\\x24\\x02\\xa8\\x8b\\x5f\\x32\\xc4\\x79\\x2f\\x62\\x74\\x05\\x09\\xcd\\x86\\x7c\\x39\\x3c\\x78\\xdc\\x00\\xd3\\xe8\\x24\\x96\\xc5\\x77\\x4f\\x2b\\x8f\\xa5\\xaa\\x0a\\x21\\xaa\\x1a\\x44\\x4a\\xf1\\x44\\x85\\x75\\x5e\\x70\\xd9\\xef\\xfb\\xc7\\x04\\x6a\\xf1\\xa5\\x57\\xdc\\xe5\\x28\\xf4\\x88\\xaa\\x36\\x1a\\xaf\\xbd\\xb6\\xf2\\xcb\\x30\\x45\\xf9\\xdc\\x59\\xe7\\x07\\x8d\\xd8\\x8c\\xf6\\xc7\\x0d\\x83\\xed\\x24\\x48\\x3e\\xd4\\x60\\xb5\\x11\\x85\\xc3\\xf5\\xa2\\xe3\\x40\\x4c\\x9a\\x54\\x7c\\xdb\\x1c\\x8a\\xd7\\xd8\\xe2\\xbc\\x57\\x54\\x5f\\xdd\\x0d\\x00\\x10\\xd5\\xa8\\x8c\\x26\\xf5\\x99\\xb0\\x46\\x25\\xf2\\x7a\\x8d\\x26\\xfe\\x00\\x2a\\x08\\x95\\x27\\x8e\\x26\\x40\\xf4\\x93\\x3b\\x2b\\xce\\xd2\\xb3\\x8d\\x54\\xe9\\x90\\x3d\\xa2\\x1f\\xe3\\x65\\x21\\xd6\\xbd\\x8a\\x57\\x38\\x73\\xfb\\xae\\x3b\\x24\\x80\\xac\\xc2\\x79\\x71\\x5b\\xe0\\x44\\xf0\\xe0\\x54\\x44\\x92\\x51\\x5e\\x32\\xcc\\xd5\\xed\\x30\\x28\\xcb\\x62\\x38\\x9a\\x09\\x6c\\x8e\\xcc\\xe1\\x5b\\x9c\\x94\\x4a\\x03\\x49\\x35\\xf5\\x97\\x33\\x60\\x65\\x2e\\xcd\\x14\\x10\\x2e\\xf1\\xcd\\xc9\\x0d\\xce\\x95\\xb2\\x67\\x34\\x83\\x6b\\x94\\x7c\\x82\\x6b\\x3c\\xa3\\x4c\\x1f\\x4b\\x27\\x79\\x49\\xf2\\xb9\\xba\\x05\\xf3\\x5c\\x5d\\x3a\\x6a\\xb5\\x99\\x5e\\xbc\\x1c\\x10\\x5f\\xe7\\xc9\\x82\\xd1\\x9c\\x96\\x3c\\x5b\\xfb\\xda\\x0e\\x17\\x2f\\x54\\xcf\\xb8\\x27\\x3f\\xf3\\xea\\x14\\xfa\\x1b\\xaa\\x5e\\x72\\x39\\x30\\x5a\\xc4\\x55\\x1e\\x1d\\x17\\x5b\\x53\\x0f\\x2e\\x51\\x8f\\x14\\x0e\\x55\\x33\\xa9\\xc7\\x87\\x81\\x08\\x9b\\xae\\x57\\xaf\\xa6\\xba\\x97\\x58\\xdf\\x65\\xa1\\xe4\\x49\\x3e\\xe8\\x55\\xb7\\x4b\\x9c\\x25\\x0b\\x9c\\x96\\x19\\x36\\xf7\\x55\\xdd\\x0a\\xf5\\x5e\\xe2\\xe0\\xfa\\x62\\x17\\x5a\\x8a\\xa0\\xc0\\xbf\\x65\\x4c\\x87\\x70\\x37\\x80\\x71\\xed\\x1e\\xb8\\x2c\\x73\\xb7\\xf2\\x70\\x30\\x7c\\x2f\\x5a\\xaa\\xe8\\x15\\x40\\xaf\\xbb\\x06\\xa9\\x76\\xd4\\xdb\\xe5\\x00\\x55\\xe7\\xae\\xe8\\x76\\x4b\\x81\\xed\\x2f\\xbf\\xb4\\x95\\x8a\\x34\\x6b\\x2d\\x35\\xbf\\x94\\xc5\\x6c\\x39\\xd7\\xd0\\x28\\x35\\x8e\\x94\\x99\\x1b\\xda\\xdb\\x47\\x37\\x94\\x52\\x1d\\x7a\\x1e\\x97\\x9d\\xc4\\xe3\\x77\\xef\\xe3\\xad\\xa4\\xef\\x4e\\x59\\x78\\x82\\x3d\\x4a\\x8a\\x72\\xa8\\xd2\\x63\\x43\\x4d\\xa4\\xbd\\x2b\\x75\\x47\\x22\\xdd\\xc5\\x57\\xec\\x63\\x8e\\xe6\\x28\\xeb\\x4f\\xe0\\x14\\x0f\\xf5\\x7d\\x85\\xea\\x54\\xc4\\x2b\\x8a\\x52\\x40\\x6a\\x91\\xa9\\xab\\x5c\\xb9\\x40\\xea\\xc2\\xc1\\x46\\xa9\\xb6\\x41\\xb6\\x69\\x04\\xa3\\x11\\xfc\\x1f\\xff\\x74\\xf4\\x23\\x49\\x7d\\x46\\x51\\xaa\\xc9\\x7e\\xb4\\x03\\xd9\\xa3\\x51\\x45\\xf9\\x4e\\xbc\\x0a\\x4e\\xf6\\x7a\\x0a\\x5f\\x31\\xce\\x1e\\x0d\\x7e\\x28\\xef\\x76\\xa2\\xa0\\x76\\x8a\\xb1\\x4e\\x83\\xee\\xba\\x3a\\x05\\x79\\x5f\\x22\\xac\\x94\\xe9\\x32\\x97\\x2d\\x82\\x76\\xdf\\x55\\xe0\\xd7\\x12\\x9a\\xfa\\xbe\\x87\\xb1\\xca\\x52\\x69\\x76\\x04\\xb7\\x90\\x69\\xf7\\xd3\\x76\\xa6\\x33\\xa8\\x2e\\xb1\\x3b\\xa0\\x43\\xb5\\x3d\\xfc\\x5b\\x4c\\x6a\\xb8\\x8d\\x5b\\xf5\\xa7\\x37\\x64\\x1e\\xca\\x1a\\x57\\xf8\\xba\\x85\\x3b\\x4d\\xf7\\xb2\\x83\\xe2\\xed\\xf6\\xb6\\x46\\x55\\x5d\\x71\\x95\\x5c\\xd0\\xa5\\xb9\\xd1\\x97\\x6f\\x51\\x61\\x0a\\xf6\\x6a\\xa9\\x61\\x77\\x9b\\xb9\\x39\\x16\\xba\\x0b\\xd3\\x83\\xbf\\x34\\xea\\x1e\\x4f\\x95\\x7b\\xab\\xbf\\x08\\x6f\\x26\\xf1\\x30\\x54\\x1d\\x1a\\x9a\\x5c\\xb6\\xce\\xfd\\x53\\x2b\\xb4\\x8b\\x04\\xbd\\x42\\xd5\\xdb\\xa1\\xc1\\x51\\xcd\\x6d\\xcd\\x78\\xf9\\x5d\\x1c\\x7a\\x28\\xee\\x5a\\x67\\xda\\x3f\\xc7\\x53\\x5d\\x3d\\xd3\\x38\\xc6\\x03\\x53\\x19\\x68\\x89\\xf0\\x1c\\x12\\xaf\\x57\\xdd\\x86\\x66\\xb3\\xda\\xaa\\xef\\x38\\x68\\x19\\x6c\\xd8\\xcf\\xa0\\xf7\\x80\\xe3\\x69\\xdb\\x26\\xd5\\x04\\x2a\\xba\\xba\\xfb\\x98\\x96\\xd6\\x03\\xfe\\x83\\xd5\\xb7\\x7e\\x0f\\x43\\x03\\x37\\x4c\\x24\\x60\\xd4\\x8f\\x6f\\x50\\xd6\\xf3\\x38\\xb8\\xe9\\x04\\xde\\x5e\\x38\\x4f\\x6d\\xd8\\x03\\x55\\x15\\xc0\\xab\\xe2\\xed\\x67\\xeb\\xe3\\xa2\\x6c\\x3d\\xf1\\xea\\x51\\xdf\\x6f\\x9c\\x68\\xbc\\xdb\\xbb\\x27\\xff\\xea\\x85\\xd1\\x0f\\x66\\xa1\\xd1\\xc0\\x0f\\xe1\\xe2\\x86\\x53\\x6d\\x21\\x23\\xbb\\xfa\\xd8\\xca\\x4b\\xdd\\xc3\\x43\\xd8\\x69\\x58\\xda\\xe2\\x73\\x86\\x07\\xa7\\x51\\xae\\xfb\\xaa\\x9f\\x8e\\xe6\\x2a\\x59\\xa1\\x6f\\xe1\\x3f\\x7e\\xf7\\x7e\\xa0\\xab\\x30\\x91\\x80\\x25\\xe5\\x02\\x22\\xcd\\x15\\xc0\\xb9\\x60\\x24\\x4c\\x53\\x6c\\x14\\x02\\xd5\\x4c\\x4f\\x4a\\x73\\x39\\xc9\\x0e\\xdd\\xd4\\xa1\\x01\\x5c\\xfb\\xcb\\x0a\\xc5\\xe6\\xe2\\x13\\x1e\\x4b\\xaf\\xf4\\x29\\x5c\\x07\\x0f\\x1a\\x15\\x97\\xba\\xc6\\x06\\xe0\\x0e\\x70\\xc6\\x71\\x1b\\x8a\\x27\\xdb\\x50\\x84\\x18\\x6a\\x2f\\x13\\xba\\x2c\\x10\\xc3\\xcf\\xd6\\x52\\x47\\x6a\\x6a\\x3d\\xde\\xfb\\xf7\\xa6\\xb7\\x8c\\xd4\\x1e\\x73\\x50\\xdb\\xd6\\x4b\\x92\\x77\\x2a\\x17\\xcb\\xb2\\xaa\\xc6\\x57\\x31\\x29\\xe8\\xfb\\x21\\x33\\xaa\\x05\\xb2\\x7d\\x52\\xd5\\xa5\\x81\\x5d\\xf3\\xda\\x2d\\x90\\x5f\\x66\\x6a\\x4d\\xa1\\x7d\\x30\\xbb\\xa1\\x83\\xb5\\xe3\\x04\\x1b\\x44\\x4f\\x76\\x40\\xf4\\x9f\\x39\\xcd\\x12\\xc2\\x50\\x47\\x04\\x65\\x70\\x8d\\xb8\\xfe\\x3d\\x0b\\xd3\\x07\\xa3\\x59\\x86\\x59\\xbd\\x52\\x3a\\x1c\\x0e\\x2f\\xaf\\x8f\\x94\\xb9\\x7b\\xe6\\x55\\xc6\\x95\\xd7\\x47\\xba\\xa8\\xf9\\xa9\\x7a\\xa3\\xaf\\x06\\x08\\x0f\\xb9\\x2a\\x8e\\x79\\x7c\\x77\\x6d\\x9e\\x74\\xb6\\x19\\xfa\\x8d\\x82\\x37\\xe3\\x43\\xef\\x5c\\xb9\\x15\\x62\\x9b\\x91\\x94\\xc1\\xaf\\x9d\\x40\\xfb\\x3d\\x38\\x75\\xac\\xb3\\x89\\x9d\\xb7\\x30\\x98\\x1b\\x9f\\x78\\xc0\\x7a\\xaf\\x1c\\xa6\\x28\\xcf\\xca\\xa5\\xbf\\xb3\\xaf\\x85\\xc4\\x7b\\xe8\\x37\\x34\\xb9\\xcb\\xc6\\xf9\\x7d\\xf9\\xb8\\x2a\\x8b\\xd3\\x28\\xf7\\x75\\xea\\xb3\\xfd\\x1c\\xa8\\xeb\\xc4\\x82\\xed\\x72\\x66\\x38\\x38\\xaa\\x9f\\x14\\xe5\\xc4\\xf6\\x35\\x6a\\x23\\xd2\\x48\\x96\\xd7\\xdf\\xc4\\xeb\\x77\\x4b\\x93\\xc6\\x74\\xa8\\x3b\\x5c\\xe9\\x0c\\xc8\\x72\\x89\\x53\\x82\\x44\\x38\\x0b\\x7c\\x60\\xee\\x77\\x95\\x31\\xac\\x76\\xdc\\xaa\\x59\\xf3\\xe6\\xe6\\xde\\xbe\\x97\\x3b\\xff\\x5d\\x73\\x91\\x03\\xbd\\xf6\\xcb\\x2f\\x66\\xd9\\x6c\\x00\\x0a\\xee\\x84\\x75\\x2d\\xbe\\x6a\\xe9\\xcf\\xfd\\x96\\xc8\\x65\\x50\\xdf\\xe4\\x83\\x56\\x3f\\x8a\\xa0\\x32\\x76\\x9b\\xfa\\x6d\\xca\\x4a\\x43\\x10\\xa1\\x89\\xfa\\x22\\x98\\x1d\\xb9\\x9c\\x2e\\x6b\\x97\\x63\\xa8\\x87\\x87\\xee\\x46\\xc3\\x2e\\x7f\\x57\\x0f\\xe2\\x01\\x34\\xd5\\x7d\\xde\\x4e\\xba\\xbe\\x6a\\xbf\\xf7\\x29\\x80\\xac\\x96\\x70\\xe3\\xd0\\x7d\\xfb\\x02\\x3d\\x6c\\x41\\xa2\\x15\\x66\\xe3\\x0e\\x93\\x9a\\x3e\\xde\\xa0\\x90\\xc3\\x7a\\x04\\x5e\\xd5\\xd2\\xf6\\x5a\\xce\\x6e\\x48\\xd7\\xd0\\xc6\\xa0\\x1c\\x67\\xfa\\xb0\\x64\\xed\\xbc\\x8d\\xc9\\xc8\\xda\\xaf\\x5e\\xae\\x9b\\x17\\x28\\x77\\xa9\\xfd\\xaa\\x56\\x77\\x02\\x51\\xbf\\x0d\\xfc\\xba\\x82\\x0d\\x29\\x51\\x43\\xdb\\x5a\\xd1\\x0b\\xb5\\xc3\\x27\\x36\\x43\\x59\\xed\\x2d\\xe5\\x78\\x65\\xd5\\xa4\\x64\\xce\\x8c\\x61\\xbe\\xd0\\x77\\x7f\\x56\\x46\\x45\\xdf\\x95\\xcb\\x0d\\xb8\\x2e\\x86\\xae\\x86\\x0d\\x29\\xa3\\x45\\xed\\x36\\x29\\xb5\\x1d\\x65\\xf9\\x57\\x41\\xda\\xf4\\x76\\xd7\\x61\\xc8\\x8d\\x67\\x1d\\xab\\x22\\xeb\\xce\\x05\\xed\\x6f\\x1c\\xd5\\xd6\\x71\\xdb\\xd9\\xb3\\xd6\\xe2\\xe6\\x8d\\xc8\\xdb\\x9b\\xec\\x90\\x57\\xee\\x98\\xa4\\x4a\\x43\\xec\\x32\\x89\\x51\\x74\\xe8\\xdf\\x5d\\x97\\x65\\xde\\x59\\x24\\x7b\\xd4\\xd0\\xcd\\x44\\xb8\\x65\\xa6\\x36\\x0b\\xea\\xd3\\xd0\\x5d\\x82\\x79\\xcf\\x91\\x37\\xf6\\xcc\\x02\\x79\\xeb\\x38\\xf9\\xd7\\x8a\\xd0\\x9e\\x98\\xaa\\xef\\xcf\\xc8\\x55\\x90\\x91\\xfa\\x06\\x93\\x5d\\x29\\x42\\xb0\\x5e\\xc4\\x68\\xa6\\x4a\\x66\\x0a\\x86\\x39\\xce\\xf5\\x2f\\x61\\x75\\xc0\\x3b\\x9c\\xa8\\x1d\\xe5\\x06\\xf4\\x4b\\x9c\\x97\\x44\\xe0\\xe5\\xae\\xed\\x04\\xba\\xd6\\x9b\\x38\\x03\\x18\\x1e\\x6c\\x6d\\x93\\x64\\x24\\x91\\xeb\\xc5\\x2e\\x9d\\x58\\x36\\x56\\x97\\xfc\\xd4\\xaa\\xe3\\xfb\\x5b\\x51\\xb5\\xe9\\x8b\\x6a\\x8b\\xda\\x53\\x6e\\xbb\\xcf\\xcd\\xb8\\xba\\x07\\xca\\x1a\\x7f\\xa5\\x2a\\xb4\\xcf\\xa5\\xae\\x16\\x6e\\xdf\\x8d\\x08\\x55\\x4a\\xe5\\x5b\\x79\\x59\\xb1\\x96\\x22\\x5a\\xef\\xad\\x24\\xba\\xba\\x8e\\xd8\\x0c\\xfb\\xd7\\xe5\\xaa\\x9a\\xb7\\xe6\\x76\\x7a\\x17\\xfa\\x9f\\x54\\x4e\\x8d\\x0d\\x41\\xc2\\xb8\\x38\\x2d\\xf3\\x30\\xc1\\xd5\\x05\\x05\\x53\\x7b\\xb5\\xbb\\x07\\x7c\\xaf\\x8c\\xa3\\xfd\\xd7\\xba\\xd3\\xdf\\x90\\x86\\xc8\\x21\\xd0\\x79\\x84\\x5d\\xb2\\xa3\\xfa\\xdf\\xdd\\x6e\\x14\\xd6\\x32\\xc6\\x01\\x79\\x56\\xb8\\xa2\\x86\\x8d\\xac\\x27\\xf2\\x1e\\xd2\\x73\\x7b\\xe2\\x33\\x20\\x20\\xcc\\x30\\xee\\x94\\x52\\xec\\xa0\\xe4\\x2e\\xcc\\x8c\\xdd\\x77\\x57\\xcd\\x4f\\xbd\\xf8\\xee\\x05\\x4a\\xd3\\xa3\\x2c\\x53\\x57\\xe0\\x37\\x9c\\xdc\\x46\\xf6\\x54\\xfd\\xf2\\x86\\x7b\\xb8\\xbd\\x86\\x5a\\x47\\x2a\\xb2\\xc1\\x59\\xa1\\xce\\x94\\xb4\\x70\\x32\\xe4\\x62\\x60\\x0b\\x82\\x45\\x03\\x24\\x6f\\x52\\x64\\x0f\\x3f\\xdb\\x30\\x6b\\xea\\x83\\x5c\\x04\\xed\\x2f\\xbd\\x0a\\x63\\xff\\xda\\xd4\\x8a\\xbc\\xf6\\x4b\\x40\\xf4\\x7b\\x63\\x40\\x1c\\x70\\x68\\x21\\x2c\\x98\\xe2\\xe3\\xdf\\xd4\\x4f\\x37\\x55\\x7d\\x5f\\x38\\x0c\\xd5\\xad\\x21\\x6a\\x35\\x2a\\x60\\x98\\x9a\\x1f\\x54\\x30\\x2f\\xec\\xd0\\xf5\\x2f\\x1f\\x54\\x43\\xb6\\x88\\xeb\\xca\\x40\\x83\\x4d\\xa5\\x55\\x0e\\xe5\\x4f\\x1a\\xdb\\xeb\\x52\\x08\\x9a\\x0f\\xa5\\xcd\\x75\\x34\\xf4\\xe3\\x05\\x49\\xb1\\x9f\\x23\\xbc\\x73\\xaa\\xc0\\x9a\\x68\\x6f\\xd0\\xfb\\x10\\x5d\\xa9\\x5e\\x78\\x47\\xd1\\x44\\x63\\xc9\\x6f\\x32\\x92\\xf7\\x37\\x93\\xf7\\x36\\x94\\x0f\\x37\\x95\\xbe\\xe1\\x53\\x0c\\xf7\\xcd\\x9e\\x63\\xc9\\x40\\x4f\\xce\\x56\\xd3\\x67\\x8d\\x9f\\x81\\xf6\\x38\\x2e\\x67\\xce\\x89\\x40\\x38\\x71\\x81\\x68\\x78\\xbf\\xc2\\xa1\\xff\\x59\\xca\\x7a\\x4d\\x72\\x0e\\x1b\\xaa\\xc2\\xff\\x3d\\x2f\\x7f\\xcd\\xcf\\xb1\\xd0\\x1a\\x49\\x1f\\xca\\xf3\\x64\\xc3\\x1d\\x37\\xf7\\x56\\x48\\xc3\\x24\\x3a\\x89\\x7c\\x87\\x08\\xab\\x96\\xcd\\xfe\\x3e\\xf1\\x83\\xb2\\x2d\\xcd\\xec\\xaf\\xaa\\x4d\\x21\\xe8\\xdf\\x9d\\x44\\xef\\x38\\x85\\xee\\x07\\x46\\x3e\\x2b\\x2c\\x1b\\xaa\\xb0\\xc8\\xc9\\xb1\\x94\\xe1\\x5f\\x1d\\x1d\\xa9\\xbe\\xb6\\x47\\x46\\x66\\xb2\\x75\\xc5\\x82\\x3b\\x0e\\xd9\\xe4\\x77\\xb5\\x61\\x63\\xa0\\xa6\\xd2\\x2f\\x33\\xec\\xdb\\xc6\\x71\\x7d\\x63\\x52\\x30\\x6e\\x73\\x53\\x92\\x9f\\xb7\\xda\\x3a\\x01\\xea\\x38\\xd9\\x85\\xba\\x98\\x51\\xe1\\xa8\\xc2\\x84\\x96\\xe0\\x2b\\x48\\x5c\\x29\\x56\\xe2\\xb4\\x2e\\x89\\xc6\\x48\\x6c\\x1a\\xf5\\x1b\\x7b\\x81\\x67\\x73\\xe4\\x76\\x9e\\xa3\\xe8\\xd0\\x9f\\xf6\\x9d\\x47\\x51\\x93\\x8e\\xa6\\xf5\\xf5\\xaa\\x10\\x3b\\x2e\\x8a\\xbb\\xbf\\xa9\\xf2\\x5a\\x29\\xcf\\xb3\\x35\\xc6\\xe8\\x68\\xd7\\xa8\\x23\\x0c\\x2c\\xac\\x67\\x91\\xda\\xd6\\x20\\xba\\x0d\\x06\\xd7\\x29\\x39\\x35\\xb8\\xc0\\x86\\x79\\x97\\x67\\xed\\xb0\\xea\\x6b\\x98\\x1e\\x66\\x26\\xf5\\xee\\xd6\\xcd\\x39\\xbe\\xf5\\x0b\\x01\\x01\\x14\\x13\\x20\\xc9\\x10\\xe7\\xd3\\x0f\\x91\\x0d\\x1f\\x3f\\x44\\x4f\\xe1\\x89\\xb6\\x62\\xd5\\xbb\\x6b\\x91\\xc3\\xb5\\xc8\\x87\\xf6\\x67\\x80\\x6b\\x97\\x7f\\xd8\\xa6\\x43\\x41\\xe7\\xf3\\x0c\\x7f\\x88\\x40\\xac\\x0b\\x2c\\xdb\\x29\\x34\\x1f\\x22\\x20\\x69\\xf5\\xad\\x66\\x1a\\x2d\\x91\\x96\\xc0\\xfd\\x80\\xc2\\x0f\\x91\\xaa\\x71\\x34\\x88\\x03\\x2a\\x01\\x31\\x82\\x86\\x0b\\xc4\\x0b\\x5a\\x94\\xc5\\xf4\\x43\\x24\\x4d\\xfa\\x87\\xa8\\x4e\\x9b\\x82\\xc2\\xb7\\x05\\xca\\x53\\x2c\\x89\\x50\\xda\\xfd\\x43\\xe4\\x2a\\x80\\x5d\\xc7\\xa0\\xd5\\x8f\\x26\\xb6\\x6e\\x91\\x7d\\xa4\\x35\\xbd\\xf6\\x21\\x7a\\xfa\\x64\\xa4\\x14\\x17\\x68\\x04\\x96\\x6d\\x09\\x62\\x38\\x78\\x3b\\xd2\\x2c\\xe8\\xe8\\xbc\\xcc\\xb6\\x77\\x6d\\xdc\\x82\\x0f\\x51\\x63\\xde\\x86\\xd2\\xe4\\x7e\\x88\\x40\\x5a\\xe0\\xe9\\x87\\x48\\x7f\\x6b\\xe5\\x86\\x42\\x91\\xe1\\xf4\\x7a\\xdd\\x35\\x29\\x52\\x79\\x2b\\x39\\x18\\x95\\x99\\xfc\\x5f\\x2d\\x96\\x56\\x9a\\xa5\\x04\\x55\\x44\\xbb\\x1f\\x1a\\x94\\xca\\xbf\\x0b\\x65\\x80\\xcc\\x0f\\xf3\\x0d\\xe2\\x7e\\xed\\x16\\xda\\x30\\x13\\xa0\\x9b\\x1b\\x65\\xdf\\x52\\x0a\\xe9\\x97\\x40\\xd6\\x54\\x68\\xa8\\x99\\xbe\\xc4\\x8f\\xfe\\xa0\\xa2\\x30\\xfa\\x65\\xf4\\x6f\\xf3\\xeb\\x3f\\x61\\x21\\xe0\\x4e\\xca\\xf8\\xbf\\x24\\xea\\xf8\\x6d\\xb4\\xab\\x7e\\xf3\\x3e\\xd7\\x27\\x20\\x43\\x38\\xf5\\xf3\\xe4\\xbe\\x1a\\x6e\\x5e\\x4c\\xd0\\x12\\xa8\\xdc\\x2f\\xac\\xe9\\x4c\\x4f\\xe8\\xb1\\x1d\\xd3\\xcc\\xe8\\x2a\\xdf\\xe5\\xdd\\xa9\\x41\\xd3\\x17\\xde\\x35\\x70\\x3d\\xdc\\x0b\\x9d\\xe2\\xc6\\xa1\\x2d\\x50\\x6e\\xb5\\xe7\\xd1\\x98\\xe4\\x7f\\x97\\x93\\x13\\xb2\\x46\\x73\\x25\\x64\\xd3\\x45\\x80\\xee\\xb2\\x11\\xdb\\x99\\xfb\\xbb\\x73\\x87\\xc2\\xe7\\x87\\xf1\\x59\\xa7\\xee\\xad\\xf1\\x71\\xdc\\xd8\\x3b\\x0e\\x8d\\x05\\x9d\\xc8\\x18\\x88\\x5c\\xab\\x92\\x61\\xdb\\x51\\x18\\x68\\xe8\\xdf\\xd1\\xb3\\xdd\\x5c\\x54\\xf0\\x97\\x7e\\xbc\\x11\\x9e\\x49\\x51\\x4d\\x5a\\x02\\x0d\\x3d\\xf3\\x15\\x6c\\xe5\\xb5\\x3c\\x0e\\x7b\\x0c\\x91\\x8d\\x5b\\x11\\x75\\x5e\\x04\\xee\\x80\\x76\\xba\\xbb\\xa0\\x45\\xed\\x0f\\xfc\\xf5\\x11\\x28\\x76\\x5b\\x73\\xae\\x0a\\x50\\x52\\x58\\x2d\\xb0\\x4b\\x20\\xc2\\x8c\\xe4\\x84\\x2f\\x30\\x57\\x3f\\xf5\\xa3\\xca\\xc4\\x43\\x27\\xf3\\x1d\\x9a\\x7b\\x9b\\x04\\xba\\xa3\\x05\\xe2\\xc7\\x45\\xa9\\xfe\\xbe\\x36\\x35\\x0c\\x95\\x8e\\xf7\\xcf\\x37\\x8d\\x46\\xf0\\x5c\\xfd\\xbe\\xf2\\x0c\\x8b\\x64\\xa1\\xe5\\x52\\xff\\xce\\xb1\\xfe\\xd9\\xe5\\x05\\xba\\xc1\\xea\\xe7\\x96\\xdd\\x0f\\x50\\xba\\x1d\\x8a\\x63\\xf7\\x6b\\x16\\xaf\\x83\\x92\\x81\\x8e\\xa4\\x7f\\x78\\x90\\xbd\\xb6\\xec\\x3a\\xb7\\x00\\xbc\\xc4\\xa1\\x4d\\x54\\x74\\x24\\x3d\\x61\\x6a\\x07\\xd9\\x06\\x14\\x6a\\xd5\\x69\\xa8\\x65\\x0f\\xdb\\x36\\x27\\xba\\x14\\x41\\x17\\x19\\xb5\\xc8\\xa0\\x5a\\x18\\x3b\\xf8\\xc4\\x07\\xe3\\x60\\x37\\xca\\x1c\\x8a\\x0a\\x2e\\x1a\\x45\\x42\\x4f\\xb7\\xaa\\xc6\\x37\\x01\\x12\\xe0\\x1b\\xcc\\xd6\\xf0\\xc3\\x58\\x6d\\x59\\xed\\xf8\\x4b\\x7e\\x95\\x39\\x6d\\x1c\\x25\\x86\\xfb\\x1c\\x3e\\x76\\xfb\\xed\\xdc\\xbb\\xa7\\xa5\\x51\\x52\\xf6\\x05\\x88\\xba\\x37\\x59\\x55\\xd1\\xe3\\x00\\x7e\\x18\\xeb\\x73\\xe0\\xee\\x4c\\x83\\xff\\xab\\x8c\\x03\\xb9\\xca\\x94\\x3f\\xe4\\x25\\xef\\x35\\x4f\\x0f\\x2c\\x4b\\x5b\\x7f\\xab\\xd1\\x15\\x78\\xba\\xb7\\xdd\\x21\\x90\\x9f\\xdf\\xaf\\xe5\\xf3\\xbb\\xb9\\x57\\x0f\\x82\\xe5\\x68\\xaa\\x43\\xed\\xda\\xbf\\xf9\\x7f\\x01\\x00\\x00\\xff\\xff\\x09\\xd4\\x28\\x41\\x2d\\x87\\x00\\x00\")\n\nfunc cmdInternalPagesAssetsJsContainersJsBytes() ([]byte, error) {\n\treturn bindataRead(\n\t\t_cmdInternalPagesAssetsJsContainersJs,\n\t\t\"cmd/internal/pages/assets/js/containers.js\",\n\t)\n}\n\nfunc cmdInternalPagesAssetsJsContainersJs() (*asset, error) {\n\tbytes, err := cmdInternalPagesAssetsJsContainersJsBytes()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tinfo := bindataFileInfo{name: \"cmd/internal/pages/assets/js/containers.js\", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)}\n\ta := &asset{bytes: bytes, info: info, digest: [32]uint8{0xa9, 0x8b, 0x82, 0xb8, 0xe0, 0x68, 0x92, 0x21, 0x9, 0xc6, 0xea, 0xfa, 0x2d, 0x53, 0xd5, 0xf3, 0x57, 0x2, 0xe9, 0xae, 0x9b, 0x54, 0x52, 0xc9, 0xa4, 0xf3, 0x48, 0x7b, 0x72, 0x98, 0xd5, 0x8c}}\n\treturn a, nil\n}\n\nvar _cmdInternalPagesAssetsJsJquery351MinJs = []byte(\"\\x1f\\x8b\\x08\\x00\\x00\\x00\\x00\\x00\\x00\\xff\\xb4\\xfd\\x69\\x97\\xdb\\x36\\x12\\x30\\x0a\\x7f\\x7f\\x7f\\x45\\x8b\\xe3\\x61\\x00\\x0b\\x52\\x4b\\x76\\x92\\x7b\\x43\\x35\\xa2\\xe3\\xb4\\xed\\xc4\\x33\\x59\\xdd\\xce\\x24\\x19\\x8a\\xce\\x61\\x8b\\x50\\x8b\\x31\\x05\\x2a\\x24\\xd8\\x4b\\x44\\xce\\x6f\\x7f\\x0f\\x0a\\x0b\\x41\\x8a\\xea\\x64\\xe6\\x79\\x6e\\x72\\xdc\\xe2\\x02\\x62\\x2d\\x54\\x15\\x6a\\x3d\\x7f\\x3a\\x3a\\xfb\\xed\\x87\\x8a\\x15\\x0f\\x67\\xb7\\xcf\\xa7\\x9f\\x4c\\xe7\\x67\\xf5\\x19\\x5a\\xe3\\xb3\\x7f\\x5c\\x9d\\xbd\\xce\\x2b\\x9e\\xc4\\x22\\xcd\\xf9\\x59\\xcc\\x93\\xb3\\x5c\\x6c\\x59\\x71\\xb6\\xce\\xb9\\x28\\xd2\\xeb\\x4a\\xe4\\x45\\x79\\x56\\x9f\\xfd\\xf6\\xbb\\xfc\\x74\\x9a\\x17\\x37\\xe7\\x59\\xba\\x66\\xbc\\x64\\x67\\x4f\\xcf\\xff\\x7f\\xa3\\x4d\\xc5\\xd7\\xf2\\x43\\xc4\\x88\\xc0\\x07\\xaf\\x2a\\xd9\\x59\\x29\\x8a\\x74\\x2d\\xbc\\x85\\x97\\x5f\\xff\\xc6\\xd6\\xc2\\xa3\\x54\\x3c\\xec\\x59\\xbe\\x39\\xdb\\xe5\\x49\\x95\\x31\\xdf\\x3f\\xf1\\x62\\xca\\xee\\xf7\\x79\\x21\\xca\\x65\\xf7\\x96\\xb2\\x69\\x92\\xaf\\xab\\x1d\\xe3\\x62\\x29\\x10\\x23\\xa3\\x19\\x0e\\xda\\x56\\xf1\\x21\\xdd\\xa0\\x51\\x5b\\x04\\x8b\\x6d\\x91\\xdf\\x9d\\x71\\x76\\x77\\xf6\\xaa\\x28\\xf2\\x02\\x79\\x7a\\xcc\\x05\\xfb\\xbd\\x4a\\x0b\\x56\\x9e\\xc5\\x67\\x77\\x29\\x4f\\xf2\\xbb\\xb3\\xbb\\x54\\x6c\\xcf\\xe2\\x33\\xf3\\xa5\\x87\\x17\\x05\\x13\\x55\\xc1\\xcf\\x04\\x62\\xb8\\x09\\xe0\\x2f\\xf2\\x2a\\x9e\\xb0\\x4d\\xca\\x59\\xe2\\x8d\\x4c\\x77\\xd5\\xf7\\x4b\\xf5\\x13\\x88\\x6d\\x5a\\x12\\xdb\\xa1\\x4b\\xc2\\x7a\\xd3\\x70\\x1b\\x17\\x67\\x82\\x86\\x11\\x29\\xe8\\x77\\x30\\xee\\xe9\\x0d\\x13\\xdf\\x17\\xb9\\xc8\\x65\\x75\\xdf\\x6d\\x48\\x49\\xc5\\xb4\\x94\\x73\\x4a\\x6e\\xa8\\x98\\x6e\\xb2\\x58\\x2c\\xdd\\xf1\\x99\\x4e\\xc1\\x9b\\xe9\\x3a\\xce\\x32\\xe8\\xde\\x60\\x91\\x75\\xce\\xd7\\xb1\\x98\\xc6\\xfb\\x7d\\xf6\\x80\\xc2\\x88\\x30\\xdc\\x90\\x8a\\x8a\\xe9\\xbe\\x2a\\xb7\\x24\\xa5\\x62\\x9a\\xf2\\x84\\xdd\\x7f\\xb7\\x21\\x9c\\x1e\\x1a\\x92\\x53\\x3e\\x15\\xf9\\x95\\x28\\x52\\x7e\\x43\\x6e\\x29\\x9f\\x6e\\xe3\\xf2\\xbb\\x3b\\xfe\\x7d\\x91\\xef\\x59\\x21\\x1e\\x48\\x4c\\x6f\\xdb\\xf7\\x19\\x8d\\x55\\xe3\\x6a\\x10\\x98\\x3c\\xc8\\x2a\\x76\\xf4\\xb8\\x1f\\x9e\\x79\\xd4\\x2e\\xb0\\x5c\\x74\\x5e\\xed\\xae\\x59\\xd1\\xce\\x22\\x9b\\xf2\\x3c\\x61\\xef\\x1e\\xf6\\xac\\x21\\xf7\\x03\\xd5\\x9c\\xf1\\x2a\\xcb\\x46\\x94\\xf9\\x3e\\xa3\\x94\\xb2\\xa9\\x9a\\xee\\x86\\xbc\\xa2\\x97\\x76\\xb5\\xc9\\x9a\\x1e\\x64\\x75\\xc1\\x68\\x46\\xca\\x62\\x2d\\x7f\\x78\\xce\\xd7\\x4c\\x5d\\x7c\\x03\\x70\\x14\\x8c\\x66\\xcd\\xc2\\x54\\x7f\\x76\\x2d\\x01\\x95\\x70\\x7c\\x90\\xcb\\x52\\x90\\x94\\xe4\\x14\\x71\\xca\\xeb\\xfa\\x15\\x9e\\xae\\x0b\\x16\\x0b\\xf6\\x2a\\x63\\xb2\\x6a\\xe4\\x95\\xeb\\x22\\xdd\\x4b\\xb0\\x48\\x37\\x28\\x9f\\x0a\\x76\\x2f\\xa8\\x04\\xf2\\x4d\\x5e\\xa0\\xe2\\x2c\\xe5\\x67\\x6b\\x8c\\x52\\x2a\\xc2\\x22\\xaa\\x6b\\x58\\xd3\\x17\\x42\\xed\\x17\\xe6\\xfb\\xdd\\x7b\\x54\\x60\\xec\\xfb\\xf9\\xb4\\xec\\x3c\\x23\\x29\\x5e\\xf0\\xe9\\x96\\xc5\\x89\\x5c\\x2f\\xc6\\x93\\xcb\\x6d\\x9a\\x25\\x28\\xc7\\xd3\\x7d\\x5c\\x30\\x2e\\xbe\\xcd\\x13\\x36\\x2d\\xd8\\x2e\\xbf\\x65\\xe6\\x4d\\x63\\x87\\x71\\xd7\\x9b\\x27\\x4a\\xd9\\x92\\x8d\\x3d\\x2f\\x38\\xda\\x5b\\xac\\xae\\x87\\x16\\x64\\xc9\\xc3\\xdc\\x00\\x53\\x54\\xd7\\xe6\\xb3\\xc0\\xbc\\x6f\\xe4\\xfc\\x6c\\xa8\\x07\\x98\\xc2\\x23\\x57\\xb4\\xbb\\xd1\\x4d\\xd3\\xec\\xee\\xec\\x6a\\xba\\xe1\\xd3\\x94\\xa7\\x02\\xde\\x38\\x53\\xbd\\x97\\x7d\\x54\\xd0\\x3f\\x1a\\x49\\x08\\xc8\\x18\\xbf\\x11\\x5b\\x2f\\xe5\\x12\\x1e\\xd8\\x54\\xdd\\x12\\x4e\\xe5\\x60\\xf4\\xde\\x1b\\xed\\x10\\xc3\\xbe\\x3f\\xba\\x87\\x1f\\xe4\\xc5\\x45\\x11\\x3f\\x78\\x94\\xca\\x15\\x9a\\x51\\x4a\\x45\\x5d\\x1b\\x40\\xb2\\x63\\x11\\xbe\\x3f\\xbb\\x10\\xbe\\x2f\\x26\\x73\\xb9\\x2c\\x0c\\x37\\xb2\\x4b\\xf4\\x6a\\xba\\x37\\x9b\\x8c\\x1e\\x14\\xf6\\x0a\\x36\\x64\\x9d\\xf3\\x52\\x14\\xd5\\x5a\\xe4\\x45\\x70\\x45\\x54\\x17\\x82\\x19\\x11\\xf9\\x0b\\xd9\\x52\\xbb\\xab\\xec\\x10\\x4b\\x35\\x4b\\x72\\x97\\xe3\\x86\\xdc\\x30\\x31\\xb4\\xf3\\xcc\\x12\\xb8\\x85\\x03\\x76\\x31\\x5b\\xca\\xab\\x90\\x8d\\xe5\\x8f\\x1e\\x6f\\x14\\xa8\\x67\\x51\\x43\\xe4\\xae\\xbc\\x12\\xf1\\xfa\\x43\\xa7\\x4a\\x35\\x63\\x57\\xd3\\x1d\\x2b\\x6e\\x18\\x54\\x35\\x75\\x3a\\x8d\\x30\\x61\\x2d\\xa2\\x9a\\xee\\x0b\\x76\\xab\\x36\\x24\\x05\\x3c\\x24\\x1a\\xc2\\xe2\\xf5\\x76\\xa8\\x8f\\x57\\x53\\xf9\\x06\\x2a\\x04\\xbc\\xb0\\x8b\\xf7\\x6d\\x31\\xde\\x22\\x11\\xd9\\xa0\\xed\\x19\\xba\\x9a\\xee\\xe2\\x3d\\xea\\xe2\\xb8\\x0e\\x04\\x68\\x20\\x22\\x42\\x56\\x8a\\x71\\x43\\x00\\x95\\x0d\\x4c\\x64\\xaf\\xe2\\x52\\x63\\x29\\xa8\\x3a\\x2e\\x6e\\x60\\x3f\\x97\\xb2\\x82\\x4d\\x5a\\x94\\xe2\\x54\\x05\\xec\\x77\\x34\\xc3\\x0d\\xc9\\xe2\\x47\\x8b\\x4c\\xe6\\xb8\\x21\\xec\\x96\\xf1\\x3f\\xef\\xc7\\xd5\\xf4\\xa6\\x60\\x8f\\x8c\\x10\\x89\\xf1\\x1c\\xff\\xfd\\x19\\x0c\\x2d\\x4f\\x92\\xff\\xf3\\x0a\\xcf\\x84\\xae\\x8d\\xfd\\x3e\\xb0\\xee\\x0e\\xa4\\x10\\x4e\\xc7\\x6c\\x8c\\x00\\x8c\\x82\\x59\\xbb\\xe8\\xdd\\xe6\\x66\\x17\\x94\\xfb\\x3e\\xbf\\x10\\xcb\\x10\\x00\\x8b\\x47\\x51\\x10\\x46\\xb2\\x7a\\x7e\\xba\\xb3\\x16\\x6a\\xea\\xfa\\x18\\xc0\\x14\\x60\\x06\\x15\\x29\\xf3\\x42\\x04\\x62\\x2a\\x7f\\x48\\xb9\\x87\\x65\\x15\\x53\\x75\\xd1\\x90\\xab\\x29\\xbb\\x17\\x8c\\x27\\x14\\xf6\\xbf\\xbe\\x76\\xda\\x93\\xc3\\x01\\x54\\x4b\\x00\\xcb\\x92\\x98\\xda\\x45\\x0e\\x67\\x51\\x5d\\x1f\\x1a\\x52\\xd2\\x39\\xa9\\xda\\xc7\\x66\\xd8\\x19\\x1d\\xcd\\x17\\x12\\xcb\\x7a\\xd7\\x79\\x9e\\xb1\\xd8\\x41\\x5b\\xb1\\xef\\xa3\\x8c\\xc6\\x9d\\xca\\x4a\\x5d\\xd9\\x78\\x8c\\xc9\\x11\\xf6\\x8b\\xeb\\x7a\\x87\\x62\\x5c\\xd7\\x28\\xa6\\x87\\x06\\x93\\x92\\x52\\x5a\\xf9\\x3e\\x8a\\xd5\\x76\\x29\\x27\\x13\\xbc\\x28\\x2f\\xaa\\x85\\xfc\\x3a\\xdd\\x20\\x45\\x72\\x10\\xeb\\x54\\x8f\\x01\\xe5\\x0b\\x85\\x5b\\x0a\\xca\\x42\\x11\\x11\\xef\\xd7\\x5f\\x01\\xbb\\xfc\\xfa\\xab\\x37\\xa2\\x54\\xf8\\x7e\\x3c\\xa2\\xb4\\x90\\xbd\\xf3\\x7d\\xf9\\x73\\x35\\x4d\\xcb\\xef\\xb3\\x38\\xe5\\x6a\\x9a\\x51\\x21\\xbb\\x90\\x52\\x40\\x32\\xd3\\xb4\\x84\\x5f\\x49\\x16\\xf0\\x12\\x71\\x1a\\xcb\\x1a\\x73\\x9a\\xfa\\xfe\\xa8\\x5b\\x80\\xe3\\x65\\x18\\x05\\x69\\x5d\\xf7\\xab\\xe3\\x78\\xc9\\x83\\x43\\x43\\x52\\x3a\\x9a\\x13\\xf9\\x39\\x35\\xcb\\x81\\x32\\x92\\x93\\x02\\xe3\\xe0\\x36\\x4f\\x93\\xb3\\x99\\xee\\x15\\x14\\x29\\xb0\\x85\\xa1\\xb8\\x5d\\x3f\\x74\\x60\\xf7\\xfb\\x98\\x27\\x79\\xa0\\x39\\x25\\x6f\\x8c\\x36\\xe3\\x6f\\x62\\xb1\\x9d\\x16\\xf2\\xf1\\x0e\\x61\\x3c\\x2d\\xd8\\x3e\\x8b\\xd7\\x0c\\x9d\\xaf\\x5e\\x9e\\xdf\\x10\\xcf\\xc3\\x24\\x2d\\xdf\\xb2\\x38\\x79\\x90\\x84\\x96\\x49\\x3e\\xab\\x03\\xca\\x7d\\x1e\\x4c\\xa2\\x1b\\x9e\\xe7\\x7b\\x17\\x1e\\x1b\\xd2\\x19\\xd2\\xf1\\x56\\x20\\xdc\\xd0\\x04\\x34\\x92\\x44\\x2c\\x54\\x6b\\x7b\\xa6\\xca\\x47\\x72\\xde\\x2d\\x05\\x93\\xb4\\x62\\x84\\x04\\x95\\x4d\\xe1\\x21\\x82\\x87\\x38\\xbd\\xd5\\xb8\\x99\\x78\\x0e\\xb4\\x7b\\x58\\x12\\x6b\\xe7\\x01\\xf6\\x7d\\xcd\\xe7\\x70\\x4c\\x29\\xcd\\xb0\\xec\\xe7\\xab\\xdd\\x5e\\x3c\\x9c\\xea\\xe7\\xc2\\x85\\x0e\\xd5\\xe1\\xb9\\xe9\\xf9\\xac\\x21\\x37\\x59\\x7e\\x1d\\x67\\xaf\\x6e\\xe3\\x2c\\x70\\xb1\\x81\\x64\\x41\\x24\\x2f\\x72\\x50\\xfc\\x8a\\x24\\x5f\\x53\\xb8\\x6c\\x08\\xc7\\x47\\x48\\x5c\\x62\\x0f\\xd9\\x18\\x27\\x05\\x9d\\x49\\x7e\\x44\\xd2\\x56\\x7c\\x90\\x2d\\x73\\x6a\\x28\\xe9\\xa2\\xb8\\xe0\\x8b\\x42\\x01\\xf2\\x68\\x2e\\x89\\xa5\\x9e\\x9e\\xb0\\x88\\x48\\x41\\xe4\\x0f\\xc6\\xd7\\x05\\x8b\\x3f\\x34\\x2c\\x2b\\xd9\\x99\\x65\\x64\\xd8\\x9f\\x7f\\x61\\x00\\x87\\x49\\xba\\xf1\\x81\\xf5\\x88\\x65\\xdb\\x3f\\x49\\xa0\\xc3\\x68\\xd1\\xe7\\xe0\\xd0\\x5e\\xb3\\x8d\\xb2\\xdb\\x4b\\x43\\xdb\\x38\\xf1\\x4a\\x60\\x2e\\x5d\\xbe\\x24\\x64\\x51\\xc0\\x70\\x50\\xe9\\x45\\x20\\x0c\\x63\\xc2\\x1b\\x92\\xf2\\xe3\\x36\\x09\\xef\\x11\\x60\\xb1\\x9c\\xcc\\x83\\xd4\\xac\\x33\\x83\\x99\\x84\\xa6\\x7a\\x5d\\x95\\x23\\x57\\xdd\\x1d\\x0b\\x83\\x75\\x0a\\x3a\\x23\\xe9\\xf1\\x5c\\xb2\\x30\\x1d\\x8f\\x23\\x60\\xf3\\xec\\x1c\\xe8\\x32\\x34\\x25\\xac\\x21\\x12\\xd9\\x1f\\xf5\\xca\\x34\\x50\\x48\\xbe\\x3f\\xa5\\x33\\x92\\xdb\\x9a\\x49\\x4c\\x47\\x7c\\x91\\x5e\\xe4\\x8b\\x74\\x3c\\xc6\\x23\\x81\\x58\\x98\\x46\\x24\\xc5\\x23\\x4a\\x63\\xdf\\x2f\\x00\\xb3\\xc3\\x33\\xbb\\x59\\x8b\\x1e\\xad\\x3e\\x62\\x60\\x67\\x24\\xa6\\x61\\x64\\xc1\\x02\\xd6\\xb5\\x1d\\x49\\x7e\\x51\\x2c\\xf2\\xf1\\x18\\x6b\\xdc\\x96\\x52\\xd9\\x64\\x1e\\x91\\x9c\\x70\\x0c\\xd0\\x0e\\x2d\\xa6\\x78\\x61\\x81\\x22\\x57\\x40\\xf1\\xa7\\x1f\\xe8\\xfe\\xdd\\xa0\\x58\\x72\\x46\\x55\\x9a\\x04\\x73\\x52\\x56\\x7b\\x79\\x6a\\x0b\\x1e\\x1a\\x4c\\x06\\xf8\\xce\\xab\\x87\\xdd\\x75\\x9e\\x01\\x82\\xdc\\xf0\\x50\\xdd\\x4d\\x53\\xc1\\x8a\\x58\\xe4\\x85\\x9c\\xe6\\xfe\\x23\\x4c\\x34\\xdf\\xe2\\x7d\\xa1\\x88\\xc1\\xd9\\xb7\\xc0\\xfe\\x9d\\xa9\\x63\\xc9\\xd9\\x6b\\xc3\\x6d\\x02\\x78\\x9c\\xbd\\x8c\\x05\\x3b\\x7b\\xcb\\x6e\\x5e\\xdd\\xef\\x35\\xa2\\x50\\x28\\x48\\x37\\xec\\x01\\xf9\\x12\\xc8\\x3b\\xf3\\x70\\x8f\\x38\\xf3\\xd0\\x62\\x18\\x6f\\x2c\\xc6\\x5e\\xe4\\x45\\x54\\x4c\\x45\\xfe\\x75\\x7e\\xc7\\x8a\\xcb\\xb8\\x64\\x08\\x37\\x18\\x0e\\x73\\x0e\\x99\\xe3\\x86\\xce\\x25\\xe4\\x9a\\xe4\\x24\\x25\\x5b\\xb2\\x21\\x37\\xe4\\x8e\\x54\\x24\\x23\\xef\\xc8\\x25\\x89\\xc9\\x2b\\x72\\x4b\\x4a\\xb2\\x26\\x0f\\xe4\\x8a\\x7a\\x65\\xfa\\xc7\\x1f\\x19\\xf3\\xc6\\xf3\\xa7\\x12\\x39\\xca\\xce\\x92\\x3d\\xe5\\xed\\x71\\xe6\\x03\\x9d\\x01\\x20\\xee\\x68\\xc5\\x10\\x26\\xf7\\xea\\xe7\\x85\\xfa\\xf9\\x56\\xfd\\xbc\\x1c\\x66\\xc5\\xe5\\x21\\x49\\x00\\x79\\x1c\\xcd\\x30\\x99\\x35\\xe4\\x37\\x7a\\x68\\xfa\\x27\\x3a\\x38\\x87\\xfe\\x2e\\x0f\\x84\\xf9\\x9e\\x7c\\x6d\\x0e\\x86\\x5f\\x99\\x8b\\xef\\xec\\x49\\xf4\\x7b\\x7a\\x6a\\xc7\\xc8\\x0e\\x5a\\xd8\\xe2\\x17\\xc5\\x82\\x2b\\x8c\\xc3\\x42\\x1e\\xc9\\x2e\\x60\\xb3\\x23\\x35\\x78\\x4c\\xe6\\x0d\\x79\\x4b\\xbd\\xf5\\x96\\xad\\x3f\\xb0\\xa4\\x2e\\x59\\xc6\\xd6\\x82\\x25\\x75\\x5c\\x3e\\xf0\\x75\\x1d\\x57\\x22\\xdf\\xe4\\xeb\\xaa\\x84\\xab\\x7d\\x16\\x3f\\xd4\\x20\\x77\\xc8\\xb3\\xb2\\x4e\\xd8\\x86\\x15\\x75\\x92\\x96\\xf1\\x75\\xc6\\x92\\x7a\\x9b\\x26\\x09\\xe3\\x75\\x5a\\xee\\xe2\\x7d\\x9d\\xe5\\xf9\\xbe\\xde\\x55\\x99\\x48\\xf7\\x19\\xab\\xf3\\x3d\\xe3\\x75\\xc1\\xe2\\x24\\xe7\\xd9\\x43\\xad\\x4f\\xfa\\x49\\x5d\\xae\\xf3\\x3d\\x4b\\x3c\\xf2\\x0d\\xf5\\xc2\\xd5\\xea\\xfe\\xd9\\x6c\\xb5\\x12\\xab\\x55\\xb1\\x5a\\xf1\\xd5\\x6a\\x13\\x79\\xe4\\x0d\\xf5\\xd0\\x32\\x58\\xad\\x56\\xab\\x70\\xb5\\x4a\\xe2\\xc9\\xe6\\xc5\\xe4\\x75\\x74\\x98\\x93\\x4f\\x1b\\x6f\\xfc\\xcd\\xd8\\x5b\\xd6\\xf0\\xea\\x7d\\xfb\\x49\\x1d\\xae\\x56\\x77\\x93\\xa8\\x0e\\xdf\\xaf\\x66\\x93\\xd5\\xea\\xfe\\xff\\xd9\\x44\\x78\\xec\\x91\\x9f\\xa8\\xb7\\x5a\\x85\\xf0\\xcd\\x53\\xe4\\x8d\\xdf\\x8c\\x3d\\x8c\\x96\\x81\\xbe\\x0f\\x9f\\xbe\\x7f\\x52\\x8f\\xfe\\x13\\x2d\\x29\\xd6\\x4f\\x96\\xc1\\x47\\x48\\xb7\\x3b\\x95\\x55\\xad\\x56\\xab\\x8f\\x22\\xfc\\x14\\x7f\\x54\\xaf\\xbc\\xfe\\x8b\\x95\\x27\\xdf\\xac\\xbc\\x5a\\xd7\\x8b\\x6b\\x5d\\xcb\\x6a\\x15\\x79\\xe4\\x35\\xf5\\x82\\xb6\\xc1\\xd5\\x0a\\x21\\xf4\\xdf\\x57\\x8d\\xeb\\xfe\\x1b\\x84\\xc3\\xd5\\x2a\\x8a\\x6a\\x6f\\xfc\\xd3\\xd8\\xc3\\x4f\\x71\\x3d\\x7d\\x8a\\x57\\x2b\\xd9\\x34\\xf9\\x82\\x4a\\xc0\\x55\\x1b\\x0c\\x7d\\x33\\xf6\\xc6\\x1e\\xf1\\x6e\\x3c\\x4c\\x9e\\xb8\\xcf\\xbd\\xf7\\xd0\\xc7\\x31\\x54\\xfc\\x5e\\x57\\x1a\\x61\\xd3\\x0a\\x7e\\xaa\\xc6\\x30\\x7e\\xa2\\x3f\\xfe\\x75\\xe0\\xe3\\xa7\\x44\\xfd\\x78\\x98\\xfc\\x31\\xf4\\x1a\\x85\\x9f\\x8f\\xff\\x23\\xbb\\xf8\\xcd\\xd8\\xc3\\xb6\\xe8\\x8f\\xbd\\xee\\xd5\\x9f\\x7b\\x98\\xfc\\xec\\x3e\\x7c\\x8d\\xc9\\xbf\\xfa\\xf5\\xbd\\x19\\x7b\\x4f\\x3c\\x4c\\xbe\\xa4\\x87\\x37\\x2f\\x83\\xce\\xbb\\xbf\\xe9\\xd9\\xf5\\x30\\xb9\\xfc\\xfa\\xc5\\xd5\\x55\\xf7\\xed\\x6a\\x35\\x6d\\xdf\\xbf\\x7b\\xf1\\x65\\xf7\\xad\\x7a\\x55\\x87\\x4f\\x23\\xf9\\xfa\\xc5\\xbb\\x77\\x6f\\x83\\x5e\\xbb\\x3f\\x61\\xf2\\xfd\\xd5\\xab\\x1f\\x5f\\x7e\\xd7\\x7f\\xf1\\x1a\\x93\\xcb\\xaf\\xde\\x7c\\xdd\\xeb\\x4c\\x80\\x00\\xbc\\xe1\\x78\\x54\\xcb\\x03\\x50\\xcd\\xc5\\x56\\xfe\\x9b\\xc8\\x1b\\x3c\\x41\\xeb\\x6d\\x9a\\x25\\x75\\xbe\\x99\\x48\\x64\\xab\\x21\\x42\\xcf\\x96\\x3c\\x0b\\xd5\\x79\\x92\\xd4\\x08\\x85\\xe3\\x49\\x54\\x63\\xb4\\x5a\\x25\\x4f\\x31\\xaf\\x5b\\xa0\\xd4\\x2f\\xf4\\xfd\\x6a\\x95\\x8c\\x71\\x8d\\x2d\\xb4\\xc1\\xea\\x7b\\xa9\\x87\\x89\\x64\\xca\\x7b\\x23\\x95\\xc0\\xfe\\x76\\xec\\xe1\\x27\\xba\\x08\\x67\\x2c\\x29\\x2f\\x73\\x2e\\xd8\\xbd\\xe8\\x8f\\x4d\\x56\\xa7\\xd6\\x2e\\x68\\x7b\\xc5\\x7e\\xaf\\x6f\\x44\\x9d\\xa9\\x11\\xb5\\x03\\xec\\x8e\\x01\\x2d\\x83\\xc9\\x6a\\x95\\xe0\\x25\\x74\\xdd\\xe9\\x18\\x5a\\xd2\\xf0\\xfd\\x24\\xaa\\x9f\\xe8\\x2e\\x36\\xe4\\x17\\x7a\\xfe\\xd5\\xbb\\x6f\\xbe\\x7e\\x72\\x9e\\x92\\x1f\\xe8\\xb9\\xec\\x60\\xca\\xf7\\x95\\xd0\\xd8\\xa7\\x96\\xfd\\x8a\\x0b\\x16\\xd7\\xd7\\x95\\x10\\x39\\xc7\\xb2\\xdc\\x3f\\xe8\\xf9\\xfb\\xed\\x2a\\x91\\x97\\xff\\xa4\\xe7\\xef\\xc3\\xf7\\x87\\x68\\xbc\\x3a\\xac\\xca\\xa7\\xab\\x90\\xc7\\x22\\xbd\\x65\\x67\\xab\\xbb\\x73\\xf2\\x6f\\x55\\xdb\\xdf\\x50\\x28\\x11\\xc1\\x18\\xd7\\x68\\x75\\x37\\xc6\\xf5\\x6a\\x6a\\x1e\\xe0\\x27\\xe7\\x84\\x31\\x7a\\x1e\\x8e\\xff\\x13\\x9d\\x13\\xc1\\x3a\\xb0\\xf6\\x27\\xa8\\x06\\xb9\\xb8\\x06\\xeb\\xcd\\xc1\\x19\\x1d\\xe2\\xb3\\xbc\\xd9\\xbd\\x37\\x66\\x0a\\x5b\\xa3\\x39\\x9e\\x7c\\xfa\\xc9\\x27\\xcf\\x3f\\xb5\\x47\\xc4\\xba\\x46\\xfc\\x62\\xb6\\x54\\x34\\x72\\xba\\x29\\xf2\\xdd\\xe5\\x36\\x2e\\x2e\\xf3\\x84\\x21\\x3e\\x86\\xa2\\x38\\x18\\x7c\\xf9\\xf9\\xe7\\xf3\\x59\\xfd\\xc9\\x27\\xcf\\x3e\\xfb\\x94\\xcc\\x67\\xcf\\x9e\\xfb\\xbc\\xfe\\xe4\\xd3\\xe7\\xcf\\x66\\xf2\\xb8\\x5a\\x30\\x7a\\x8e\\x42\\x89\\xf8\\xee\\xe7\\x1b\\xc0\\x7d\\xf5\\xfb\\xc9\\x72\\x95\\xe0\\xfa\\xfd\\xe4\\x89\\x46\\x89\\xfa\\xcd\\x64\\x55\\xbd\\x7e\\xfd\\xfa\\xb5\\x9c\\x91\\xf3\\x1b\\x92\\xf6\\x47\\x60\\x7a\\xb9\\xf4\\x56\\x33\\x8f\\x52\\xca\\x96\\xde\\xaa\\xda\\x6c\\x36\\x89\\x17\\x98\\x11\\xcd\\xc8\\x64\\x8e\\xc7\\xde\\x6a\\x25\\x07\\xb9\\xd6\\xdd\\x7b\\x21\\x90\\xa1\\x3c\\x93\\x39\\xb6\\xa2\\x49\\x34\\xff\\x14\\x8f\\xbd\\x33\\x2f\\x50\\xc5\\x1b\\x92\\x33\\xf7\\x20\\xfa\\x4e\\x9e\\x68\\x63\\x46\\xaf\\x19\\x3a\\x96\\x8a\\x8c\\x66\\x20\\x5b\\x34\\x44\\xc6\\xf7\\xbd\\x4d\\xca\\xb2\\xa4\\x64\\x02\\x3a\\x06\\x22\\xca\\x6f\\xe3\\x1d\\xeb\\x31\\x02\\xe4\\x90\\xa4\\x45\\xe0\\xb5\\x82\\x3a\\x8f\\x70\\x09\\xeb\\x5e\\xc6\\x6e\\x18\\x4f\\xbc\\x06\\x2f\\x44\\xf1\\x70\\xf8\\xca\\xc8\\x38\\xe8\\x77\\x8a\\x29\\xdd\\x4f\\x61\\x8f\\xca\\x2f\\x4a\\x4c\\xba\\x77\\x22\\x74\\xef\\x8d\\xb4\\xa8\\x15\\x92\\xae\\x63\\xb1\\xde\\xca\\x9e\\x7f\\x45\\x0f\\x50\\x6d\\x60\\x78\\xd7\\x65\\x77\\x7a\\xbf\\xd6\\xad\\x32\\xa2\\x5b\\x15\\xb8\\x23\\x2f\\x6e\\x81\\x88\\x39\\xcc\\xef\\xe2\\x6e\\x9b\\x66\\x4c\\x92\\x71\\xcd\\xef\\x8e\\xc7\\x11\\x5e\\x58\\x5e\\x57\\xd2\\xf1\\xa6\\x95\\x3f\\x96\\x4c\\x31\\xd8\\xa4\\x50\\x75\\xc1\\x09\\x9f\\x94\\xc0\\xf7\\xac\\xc9\\x06\\xa4\\xb6\\xd3\\xfc\\x8e\\xb3\\xe2\\xa5\\xe1\\x6d\\xf6\\x94\\x2d\\x5b\\x99\\x6f\\xf0\\x99\\xe4\\x57\\x41\\xf2\\x1a\\x46\\xf6\\x1c\\x60\\x85\\xc3\\xa2\\xae\\x47\\xa2\\xae\\xe7\\x23\\x4a\\xf7\\xbe\\xff\\x99\\xfa\\x99\\xc3\\x6d\\xcb\\x60\\xc8\\x53\\x8b\\x3c\\xdd\\xbe\\x43\\x0c\\x13\\x46\\x59\\x5d\\x5f\\x92\\x57\\x18\\x34\\x02\\x73\\xfd\\x25\\xaa\\xe8\\xbf\\xa7\\xec\\x9e\\xad\\xe5\\x24\\x48\\x36\\x25\\xa5\\x55\\x38\\x8f\\xa0\\xcc\\x67\\x54\\xd6\\x06\\xfa\\x03\\x14\\x53\\x36\\xbd\\x61\\x42\\xcb\\x7e\\xbf\\x78\\x78\\x93\\xa0\\x14\\xe3\\x4e\\x53\\xf1\\x34\\x4d\\x28\\xa5\\xa9\\x7d\\xa8\\xf8\\xe0\\x58\\x1e\\x4f\\x80\\x75\\x4e\\x37\\x68\\x03\\xa2\\x85\\xcd\\x40\\x55\\xbe\\x2f\\x17\\x24\\x06\\xfe\\xf9\\xf1\\x7a\\x64\\x87\\xaa\\xf0\\x59\\x64\\xde\\x1b\\x20\\xe2\\xc4\\xed\\x62\\xf9\\xc5\\xc3\\xbb\\xf8\\x46\\x82\\xa6\\x1c\\x19\\x81\\x1e\\xc2\\xe0\\x9e\\x47\\xd8\\xf7\\x93\\x6e\\xc9\\xcb\\x2c\\x2e\\x4b\\x59\\x56\\xae\\xca\\xf0\\x9b\\x3f\\x6d\\xcd\\x96\\x94\\xa3\\x21\\xbc\\x49\\x37\\x28\\x99\\xfe\\x5e\\xc6\\xbe\\x3f\\xfa\\x36\\x14\\x72\\xff\\x45\\xf2\\x10\\x7e\\x5b\\xd7\\xa3\\xdb\\xa9\\x60\\xa5\\x90\\xfd\\xf2\\x7d\\x04\\x0b\\xd1\\x0a\\x98\\x47\\xa7\\x77\\x95\\x5a\\xb9\\x35\\x15\\x12\\x7e\\x88\\x3c\\x8e\\xca\\x05\\xfc\\xd1\\x54\\x56\\xd7\\x7f\\xd8\\x7a\\xf1\\x01\\x6d\\x28\\x63\\xe6\\xde\\xf7\\x1f\\x18\\x62\\x8e\\xdc\\x1c\\xd7\\x35\\x93\\xc7\\x77\\x26\\xa7\\x02\\xd8\\xc0\\xba\\x46\\xa8\\x54\\x8b\\xdc\\xca\\xe0\\xbd\\x34\\xf1\\x30\\x5e\\x96\\xb4\\xb4\\x12\\x8e\\x82\\x91\\x94\\x61\\x89\\x87\\xfa\\x05\\x49\\x49\\xaf\\x30\\x26\\x39\\x45\\x19\\xdd\\xca\\x4e\\x18\\x26\\x58\\x6d\\x9c\\x7c\\x32\\xc1\\x59\\x98\\x47\\x14\\x95\\x4b\\xef\\x6f\\xde\\xb8\\x0c\\xbc\\x00\\x5a\\xf6\\x00\\x39\\x8d\\xef\\x19\\x92\\xaf\\xf1\\x62\\x4d\\xb3\\xe9\\x6f\\x79\\xca\\x91\\x47\\x3c\\xdc\\x48\\x34\\x71\\x34\\xf5\\x9b\\x29\\x88\\xab\\xaf\\x80\\x5a\\xe5\\xc5\\x8b\\x2c\\x43\\x6b\\x98\\x74\\x8b\\x03\\xbe\\x45\\x82\\x8c\\x66\\xb8\\xd9\\xa4\\x3c\\xce\\xb2\\x87\\x43\\x49\\x29\\xbd\\x92\\xab\\xab\\x14\\x06\\xbd\\x21\\x36\\x4d\\x63\\xcf\\x6a\\xc2\\x0e\\xf5\\x09\\xf1\\x9e\\xcc\\x3d\\xac\\xb7\\x71\\xbb\\xb7\\xe5\\x29\\xe3\\x60\\x4e\\xaf\\x86\\xa4\\xd8\\xb7\\x72\\xe3\\xb7\\xe7\\x6e\\x7d\\x5e\\x85\\xf5\\xc7\\x9f\\x5f\\x4f\\xd7\\xf1\\x7a\\xcb\\xbe\\x86\\x79\\xf1\\xfd\\x84\\x65\\x4c\\xb0\\x33\\x16\\x16\\xd3\\x72\\x9b\\x6e\\x04\\xc2\\x11\\x61\\x1a\\x56\\x28\\x77\\xb0\\x89\\xc4\\x3b\\xed\\x41\\x26\\xbc\\x8a\\xe8\\x68\\x46\\x58\\xfb\\x7e\\xcd\\x5a\\x01\\xe9\\x65\\x5f\\x4d\\x63\\x11\\xb6\\xc2\\xb9\\x1a\\xaf\\x8f\\xe4\\xbe\\x68\\xe7\\xcb\\x08\\x66\\xec\\x84\\x09\\x07\\x5a\\x7c\\x5f\\x9c\\xd2\\xb9\\x08\\x4c\\x04\\x95\\x07\\x61\\xa7\\xb7\\x1b\\xd6\\xc5\\xa1\\xfa\\x48\\x59\\x7b\\x98\\x14\\x94\\x77\\xa1\\xa2\\x98\\x4c\\xf0\\xf5\\x34\\x16\\xa2\\xf8\\x2a\\xe6\\x49\\xc6\\x42\\x1e\\x16\\x51\\x44\\x45\\x5b\\xdb\\xbe\\x53\\x9b\\xf0\\x7d\\x26\\x6b\\xf1\\xfd\\xb9\\xa5\\x3f\\x12\\x5d\\xaa\\x7b\\xe1\\xdc\\xb3\\x69\\x99\\x57\\xc5\\x9a\\xbd\\xe1\\x09\\xbb\\x9f\\x08\\xf7\\x4e\\xe2\\x82\\xc2\\x6c\\xe8\\x02\\xf0\\x2c\\x56\\xdd\\xe1\\x94\\x4f\\x25\\xa1\\xba\\x4a\\xaf\\xb3\\x94\\xdf\\x80\\xc8\\xd3\\x39\\xb4\\x4d\\xe6\\x56\\xc6\\xb1\\x9c\\x07\\x93\\x79\\xdb\\xcb\\x44\\x4e\\xe7\\xa1\\x07\\x0b\\x8e\\xca\\x0f\\xd8\\xab\\xc7\\x48\\xa6\\xec\\x30\\xa8\\x62\\x28\\x15\\xce\\x5c\\x6e\\x99\\xa3\\x7a\\x38\\x96\\x86\\x9f\\xaa\\x4d\\x77\\x13\\xb5\\xed\\x8a\\xba\\xf6\\x14\\x37\\x07\\x77\\x6e\\x7b\\x2e\\xa4\\xdd\\xfc\\xc9\\x38\\x36\\x79\\xb1\\x03\\x05\\xd5\\x92\\x75\\x00\\x64\\x34\\xef\\xf0\\x09\\x4b\\x2f\\x8b\\xaf\\x59\\xa6\\x4a\\x3a\\xd7\\xce\\x37\\x9d\\x0a\\xec\\x87\\xb2\\x6f\\xc1\\xd1\\x6d\\x5a\\xbe\\x74\\x1e\\xd4\\xb5\\xfb\\x64\\x44\\xe9\\x48\\xf8\\x7e\\x2c\\xb7\\xc0\\xd0\\xd7\\x4e\\xeb\\x72\\xcc\\xee\\x3b\\x67\\xdc\\xb7\\x0c\\xc5\\x76\\xdc\\x99\\xc3\\x09\\xe5\\xf6\\x69\\x4e\\xc7\\x39\\x71\\x5f\\x75\\xa4\\x8e\\x31\\xa8\\x93\\x0d\\xbf\\x90\\x63\\x92\\xd2\\xa2\\x0b\\xea\\xe9\\x64\\x82\\x59\\xc8\\x69\\x11\\xa6\\x91\\x24\\x05\\x20\\x10\\x18\\x21\\x21\\x7f\\xe4\\x35\\xc6\\x8d\\xfc\\xdf\\x76\\xe9\\xa1\\xb3\\xe9\\x7d\\x7f\\x48\\xd3\\x3e\\x4c\\xf1\\x7c\\x9f\\x35\\x9b\\xbc\\x40\\xec\\x2c\\xe5\\x67\\x09\\x2d\\xd9\\x54\\x4b\\x9d\\x28\\x88\\xc4\\x4b\\x39\\x7d\\x3f\\x7f\\xf3\\x35\\x1d\\x84\\xa7\\x78\\xc7\\xca\\x7d\\xbc\\x66\\x3f\\xbe\\x7d\\x43\\x38\\x45\\x3d\\x2e\\x45\\xd2\\x0d\\x2b\\x8e\\xd1\\x0d\\x1b\\x61\\xee\\x2f\\x9a\\xdc\\xd4\\x35\\xf7\\x7d\\x6e\\x21\\xb3\\xae\\x3d\\x79\\xd6\\x90\\xc7\\x8e\\x77\\xd0\\x17\\x26\\x4c\\x6d\\xc7\\x3d\\x90\\xa8\\x16\\xf8\\xa0\\x7e\\xab\\xc1\\xde\\x8a\\xfb\\x46\\xf4\\xd2\\xf7\\x25\\x73\\x52\\x38\\xdb\\xbd\\xe8\\xf7\\x0a\\x38\\x0d\\x74\\x49\\x8b\\xa3\\xfe\\x92\\x57\\x74\\x94\\xa2\\x4b\\x4c\\xf6\\x50\\x13\\xe2\\xf4\\x72\\x9a\\xb0\\x4d\\x5c\\x65\\xe2\\x5f\\x29\\xbb\\xc3\\xb2\\xf3\\x22\\xdf\\x8f\\xa8\\x44\\x33\\x88\\x4f\\xe3\\x24\\x79\\x75\\xcb\\xb8\\xf8\\x3a\\x2d\\x05\\xe3\\xac\\x58\\x1e\\x3f\\x42\\x5e\\xc5\\xb3\\x3c\\x4e\\x3c\\x92\\x33\\x32\\x9a\\xe3\\x80\\x4b\\x9c\\x16\\xaf\\xb7\\x50\\x4a\\x56\\xe8\\xdc\\x22\\x2f\\xe7\\x6d\\x71\\x8c\\x89\\x26\\xc1\\x74\\x3d\\xc4\\x81\\x9f\\xc5\\x1d\\xf5\\x37\\xc3\\x9d\\xdb\\x23\\x6c\\x9f\\xa4\\xb7\\x1e\\xc6\\x64\\x18\\x58\\xfa\\x54\\xd3\\xf7\\x47\\xc7\\x0f\\x91\\xa6\\xcb\\x67\\x86\\x70\\x9c\\x41\\x9d\\x1a\\x98\\x1b\\xd9\\xdd\\xd8\\x90\\xcf\\xf2\\x44\\x9f\\xd9\\x74\\x6d\\xd8\\x21\\xea\\xa5\\x1e\\x19\\xf5\\x19\\x0b\\xfb\\xda\\xc3\\x50\\xe3\\x10\\x18\\x9f\\xac\\x7b\\x68\\x02\\x2e\\xf3\\x9d\\x9a\\x00\\x39\\xfa\\xd1\\x09\\x4e\\xd0\\x7b\\xda\\x1d\\xc7\\x30\\x03\\x47\\xff\\xa9\\x00\\xf9\\xf2\\x14\\x2b\\xa8\\xbe\\x94\\x9c\\xeb\\x5f\\x5d\\xb2\\x34\\xa1\\x57\\x64\\xd4\\xab\\x50\\x6d\\x8e\\xa1\\xa7\\xe8\\xaa\\xdf\\x4d\\xd9\\xd8\\x12\\x5d\\x4f\\x37\\x69\\x26\\x58\\x31\\x7d\\xf3\\x72\\x70\\xf3\\x1a\\xce\\x45\\x30\\xc2\\x5b\\x2d\\xf8\\xe0\\x1c\\x1e\\xf3\\x79\\x0a\\x23\\x12\\xd9\\x06\\x4f\\xba\\x2d\\x48\\x44\\x97\\x6e\\x06\\x6d\\x7d\\x44\\x8f\\x97\\xf7\\xfd\\x57\\x96\\x56\\xf7\\xd9\\xfc\\xb6\\x4b\\x7c\\x19\\xf2\\x28\\x08\\xa3\\xa6\\xc1\\xc1\\xa3\\xa3\\xe2\\x7f\\x69\\x54\\x6a\\xfc\\x27\\x11\\xa4\\x1d\\xa8\\xa2\\x55\\xc7\\xcf\\xd4\\x04\\x58\\xe9\\x80\\xe4\\x77\\x6e\\xe3\\xac\\xd2\\xc4\\xf1\\xff\\xde\\x94\\x28\\x55\\xef\\xe0\\xc4\\xa4\\x1b\\x49\\x6a\\xe4\\x21\\x85\\xd3\\xfc\\x44\\x07\\x01\\x33\\x99\\x8e\\x99\\x13\\x49\\x98\\x47\\x8b\\xb4\\x53\\xa5\\x01\\x22\\x86\\x9d\\x73\\x6b\\x4e\\x53\\x75\\x64\\xfd\\xdf\\x9a\\xd0\\xfc\\x31\\xac\\x98\\x99\\x8f\\x77\\x2f\\xbe\\xa4\\xc3\\x3b\\x77\\x39\\x24\\xcf\\xf8\\xb3\\xa9\\x72\\x3e\\x1f\\x7e\\x8c\\x18\\x0e\\xe0\\x48\\xb5\\x14\\xc7\\x48\\x8b\\x19\\x8d\\xee\\xe0\\x49\\x9e\\x38\\x8a\\xa6\\x93\\x95\\xcb\\x35\\xf0\\x9e\\x02\\x93\\x86\\x0f\\x86\\x1f\\xcc\\x41\\xbf\\x85\\x25\\x7b\\xc3\\x3b\\xe4\\x06\\xf8\\x7a\\xee\\x28\\xa1\\x0c\\x9b\\x60\\xe1\\x05\\x24\\xa2\\xfd\\x19\\x72\\x8e\\x9a\\xff\\x35\\x30\\x75\\x3f\\x7f\\x85\\xad\\x95\\xcb\\x89\\x83\\x28\\xc3\\x0d\\x29\\xe5\\xc0\\x6f\\xe5\\x1f\\x75\\x1c\\x6d\\x91\\x5b\\x7f\\x0a\\xe1\\x34\\xda\\xc3\\x67\\x4a\\x81\\x7b\\x8c\\xce\\x38\\x67\\x85\\x24\\xea\\xd4\\xbb\\x88\\xcf\\xd2\\x84\\x7e\\xe4\\x8d\\xaf\\xc6\\xde\\x47\\x9f\\x5f\\x9c\\xc7\\x9f\\x5f\\x28\\x21\\x62\\xfb\\x78\\xb2\\x2a\\x56\\xab\\x8f\\xce\\x76\\x65\\x9c\\x65\\xf9\\xdd\\x3a\\xde\\x8b\\xaa\\x60\\xf4\\xa3\\x8f\\x3e\\xbf\\xc8\\xf7\\x5a\\x58\\xa2\\x74\\x1e\\xf0\\xec\\x5c\\x3d\\xfc\\xfc\\xe2\\x5c\\x3d\\xfe\\xdc\\x23\\x43\\x34\\x2a\\xec\\x56\\xf7\\x9e\\x7e\\xf4\\x51\\x64\\x91\\xbb\\xef\\xdf\\xaa\\xf5\\xf1\\xc2\\xa7\\xef\\x9f\\x44\\xb4\\x55\\x2c\\x7c\\x54\\xaf\\xbc\\x15\\xc8\\xa3\\x07\\x2b\\x35\\x3d\\x69\\xab\\xaa\\x6b\\x53\\x55\\xab\\xc2\\x58\\x06\\xb0\\x43\\x6a\\x25\\xd4\\x3d\\x55\\x57\\x9a\\xfc\\x87\\xaa\\xf1\\x0f\\xd5\\xf6\\x1f\\xea\\x61\\x82\\x06\\x8e\\x6b\\x8a\\x63\\xc7\\xb8\\x77\\xc0\\x96\\x7c\\x99\\x07\\x96\\x05\\x5d\\xfa\\x27\\x4e\\xb4\\x2e\\xcb\\x77\\xe6\\x64\\x60\\x20\\x50\\x27\\x5c\\xfd\\xe5\\x19\\x0a\\xb4\\x9e\\x6a\\xa0\\xda\\xf6\\xd5\\xe0\\x97\\xf1\\xdf\\x60\\x32\\xc6\\x4f\\x07\\x3e\\x9d\\xfe\\x6d\\x3a\\x0e\\xc7\\xff\\x89\\x4e\\x7c\\xba\\x5a\\xad\\x36\\x1e\\x26\\x76\\x4d\\x1d\\x1d\\x95\\xe4\\x1e\\x7a\\x30\\xcb\\x7a\\xe0\\xb9\\x2d\\xd8\\x86\\x7e\\xf4\\xd1\\x99\\xe5\\xfc\\x3f\\x32\\x57\\x5d\\x78\\x1d\\x7c\\xaf\\x80\\xf1\\xdc\\x81\\xc6\\xc5\\x89\\x63\\xb6\\x5e\\xb7\\x85\\xe8\\x2d\\x9c\\xdc\\xc7\\x1e\\xf1\\x94\\x76\\x6e\\x60\\xf9\\x86\\xd7\\xf9\\xe5\\x29\\xa8\\x82\\x75\\x4d\\x86\\x40\\xbd\\x5d\\xcd\\x56\\xa5\\xe6\\x61\\xf2\\x0c\\x24\\x4a\\x03\\x2b\\xc9\\x38\\x0c\\x72\\xa0\\x26\\xfb\\x8a\\x78\\x81\\x99\\x0b\\x0f\\x93\\x23\\x34\\x60\\x67\\x6c\\x34\\x3b\\xdd\\x4c\\x5b\\xc1\\x5f\\x6d\\x67\\xa8\\x9a\\xa7\\x24\\xb8\\x77\\x40\\x80\\x4c\\x9f\\x06\\x72\\xed\\xb1\\xc4\\x6a\\xbb\\x58\\xac\\xb7\\xac\\x34\\xe5\\x0d\\x86\\x5b\\xd3\\xd8\\xbc\\xaa\\xeb\\x78\\x7a\\xc7\\xae\\x3f\\xa4\\xe2\\x9b\\x6e\\x59\\xf9\\x62\\x97\\xff\\x31\\xf0\\x34\\x1f\\x2a\\x59\\xf6\\x1e\\x4a\\x94\\xd9\\x83\\xbe\\x44\\xce\\xca\\x3a\\xe7\\x1c\\xf0\\x08\\x94\\xa7\\x6b\\x63\\x03\\x08\\x3a\\xb8\\xf6\\x2e\\x2c\\x47\\x72\\x8b\\xc2\\xc8\\x4a\\x3d\\xb2\\x11\\xf5\\xc8\\x6b\\x09\\xd5\\xb7\\xf4\\xd6\\x4e\\x98\\xa3\\x23\\xb9\\xd5\\xb2\\xb1\\x5a\\xf2\\xb9\\x25\\x2d\\x87\\xca\\x94\\x6e\\x19\\x61\\xe6\\x23\\x9e\\xae\\xf3\\x9d\\x3c\\x72\\x9b\\x53\\xd5\\xf7\\x79\\x99\\xca\\x6e\\x63\\xf2\\x20\\x0f\\xd5\\x4e\\x31\\x2e\\xe2\\x94\\x97\\x78\\x39\\x24\\x13\\xff\\xac\\x23\\x77\\x59\\xb2\\xfe\\xe9\\x2a\\x60\\xa4\\xa0\\xa2\\x2b\\x32\\x5a\\x38\\x3a\\xf8\\xa2\\xae\\x47\\x68\\x54\\x28\\xd9\\x75\\x7b\\x82\\x93\\x4f\\xb9\\x6d\\x7a\\xd9\\x5e\\xa2\\x02\\x07\\xec\\x54\\xd7\\x7d\\x7f\\xfe\\xa9\\x7f\\xf2\\x2d\\x18\\x90\\xf5\\xf9\\x81\\x74\\x83\\x84\\x96\\xf6\\x08\\xea\\x76\\x52\\x72\\x46\\xc2\\xe1\\x7a\\x46\\xb3\\x85\\x95\\x8a\\x91\\x97\\x54\\x2c\\x8f\\xea\\x61\\xae\\x3e\\x3f\\x93\\xbb\\x60\\xb6\\x50\\x93\\x34\\x3a\\xd9\\xa7\\xc9\\x48\\x9c\\x7a\\x65\\x99\\xe3\\xba\\x46\\x73\\x79\\x2c\\x1d\\x3a\\x7c\\x53\\x8a\\x44\\xff\\xa9\\xc0\\xcb\\xd3\\x73\\x20\\x70\\x30\\xc7\\x75\\x3d\\x4a\\xc0\\x4e\\xf1\\x25\\x93\\xc7\\x50\\x96\\x28\\xab\\xae\\xe1\\x2f\\x40\\x8e\\xc2\\x97\\x8c\\xd2\\xcb\\xba\\xee\\x75\\x01\\x64\\xce\\x0f\\x68\\x4f\\x18\\x5e\\x4e\\xe6\\x81\\x80\\x32\\xe2\\x44\\x19\\x81\\x97\\xf3\\xa0\\x5a\\x7e\\x8f\\x2a\\xc2\\xf0\\x44\\xfe\\x08\\x1c\\xcc\\x82\\x8f\\x7d\\x2e\\xbf\\x9d\\x0f\\x2d\\xcd\\xc9\\x29\\xb5\\xf6\\x47\\xed\\x82\\x01\\x2f\\xe7\\xdc\\xc6\\x34\\x64\\x91\\x64\\x78\\x04\\xd8\\xfa\\x8c\\xd2\\xba\\x1e\\xe5\\xb8\\x05\\xbd\\x4b\\xd3\\xe3\\xe5\\x3c\\x48\\xe5\\x75\\x3e\\xd4\\xbd\\x05\\x28\\x41\\x28\\xb5\\x5f\\x6a\\x01\\xe4\\x82\\x53\\xb6\\x68\\xa5\\x84\\x0e\\xdc\\xc4\\xd3\\x8a\\x2b\\xf9\\x2d\\x97\\xa5\\xc4\\x70\\xa9\\xd2\\x2d\\xa5\\x4a\\xc4\\x61\\x11\\x51\\x4a\\xcb\\xb0\\x88\\x70\\x31\\x1e\\x5b\\x56\\x72\\xb9\\x57\\xef\\x08\\xbc\\x09\\x54\\xb1\\xbd\\xec\\x71\\xa9\\x2f\\xe7\\xc1\\xac\\xc1\\xe4\\xb2\\x21\\x25\\x33\\x38\\x6e\\x58\\x87\\x58\\xca\\xce\\xf3\\x2a\\xcb\\xd4\\x1f\\x81\\xdd\\x4f\\x2c\\xc6\\x3c\\x5a\\x06\\xd0\\x18\\x1d\\x61\\x56\\xdf\\x7f\\xd5\\xd3\\x66\\x94\\x75\\x3d\\x2a\\x5d\\x6d\\x46\\x4f\\xbf\\x81\\x45\\xf1\\xa0\\xf1\\x86\\x45\\x7b\\x02\\x18\\x6d\\x5e\\xd7\\x03\\xa8\\x52\\xc2\\x9b\\xc1\\x27\\x5a\\x9f\\xd5\\x3e\\xb0\\xb8\\xc2\\x6a\\x86\\x8e\\xe5\\xfd\\xfa\\xcd\\xec\\x02\\x14\\x70\\x97\\x6a\\xd4\\x21\\x8b\\xec\\x79\\x5a\\x0e\\xdf\\xa0\\x96\\xc1\\x29\\x1b\\xda\\x74\\x20\\x27\\x82\\x39\\x79\\x50\\x46\\xfc\\xb2\\x96\\x58\\x88\\xfe\\xcc\\x3d\\xfa\\xad\\x46\\x0d\\x1d\\x69\\x77\\xcf\\x80\\x2a\\x52\\xa2\\xed\\xdf\\xd4\\x54\\xb9\\x25\\x49\\xaf\\x24\\x5e\\x2a\\x3b\\xb7\\xd1\\x2b\\x73\\xee\\x31\\xd0\\xd3\\xda\\xb5\\x2e\\x8b\\xc0\\x15\\xd5\\xd4\\xf5\\xe8\\xd5\\xb2\\x77\\xf0\\x17\\x38\\x00\\x53\\xb8\\xa3\\xc3\\x20\\xac\\x66\\x31\\x2d\\xf7\\x6c\\x9d\\x6e\\x52\\x96\\x2c\\x0b\\x75\\x2a\\x0c\\x40\\xd6\\x2f\\x87\\xcf\\xca\\x75\\xbc\\x67\\x03\\x7e\\x29\\x88\\x8d\\x3d\\x0f\\xf7\\x14\\x46\\xea\\x93\\xa2\\xe8\\x00\\xdb\\xb1\\x21\\xac\\x77\\xf5\\xc0\\x45\\x7c\\x7f\\x06\\x25\\xc9\\x59\\xc5\\x0b\\xb6\\xce\\x6f\\x78\\xfa\\x07\\x4b\\xce\\xd8\\xfd\\xbe\\x60\\x65\\x99\\xe6\\x3c\\x38\\xf3\\xc6\\xba\\xca\\x8a\\xa7\\xbf\\x57\\xec\\x2a\\x2f\\x06\\x65\\x89\\xca\\xab\\x48\\xe2\\x0d\\xd8\\xd6\\x19\\x1d\\x25\\xd3\\x84\\x09\\xb6\\x16\\x2f\\xab\\x7d\\x96\\xae\\x63\\xc1\\x4a\\x52\\x51\\x8d\\x1b\\xaf\\x84\\xe4\\x40\\x40\\x73\\xa0\\x74\\xec\\x92\\x15\\x91\\x2f\\xd0\\x4b\\x4c\\x32\\x73\\x24\\x14\\x54\\x99\\x3c\\x62\\xa0\\x15\\x61\\x2a\\xf7\\x41\\x41\\xb9\\x31\\xfa\\xc3\\x8e\\x62\\x83\\x69\\x63\\x70\\xc4\\xe5\\x66\\x9e\\x5b\\xe8\\xac\\x40\\x63\\x42\\x58\\x43\\x72\\x5a\\xc2\\xe4\\xbf\\x63\\xf7\\xc3\\x03\\xf0\\x3c\\x8b\\xf8\\x0c\\xf4\\x03\\x82\\x52\\x4a\\x5c\\x4a\\x69\\x5a\\xd7\\x9f\\xa9\\x9f\\x39\\xdc\\xaa\\x83\\xe4\\x91\\xd9\\x28\\xb8\\xe7\\x80\\xc5\\x09\\xb7\\xe8\\xb5\\xf3\\x10\\xac\\x74\\x19\\x65\\x53\\xb0\\x2e\\x01\\x16\\x6f\\xc1\\x16\\xf2\\x81\\xab\\x0f\\xe1\\x63\\x9a\\xcb\\x63\\xa5\\xd1\\xe7\\x3e\\x57\\x4d\\x7f\\xec\\xea\\x6b\\x55\\x4f\\xff\\x25\\xa1\\x45\\x95\\x6b\\xe7\\x0d\\x04\\x10\\x50\\x87\\x68\\x45\\x41\\x0d\\x41\\xd7\\x4a\\x2e\\xac\\xb0\\x4c\\x49\\x0f\\x8e\\x96\\x2c\\xf8\\x64\\x46\\x14\\xa7\\xfd\\x7d\\xc9\\xaa\\x24\\x0f\\x32\\x46\\x00\\x2d\\x05\\x5f\\x92\\x76\\x7b\\x04\\x87\\x86\\xc8\\x33\\xb7\\xfc\\x2d\\x58\\x06\\xf6\\x28\\xc1\\xc1\\xfb\\xdc\\x0b\\x8e\\x0d\\x11\\x94\\xfb\\xc4\\x68\\xd6\\x10\\xef\\x6c\\xe0\\x7d\\x43\\xbc\\xb1\\x7d\\x5c\\xb0\\xdb\\x34\\xaf\\x4a\\x3d\\xfc\\xce\\xb7\\xff\\x39\\x55\\xa8\\x69\\xc8\\xbe\\x60\\xaf\\x41\\xa4\\x15\\x1c\\xc0\\xae\\x69\\x48\\x02\\x17\\xce\\x23\\x2a\\xff\\xf4\\xc4\\x5b\\x84\\x85\\xcf\\x23\\x8a\\xe4\\xdf\\xba\\x66\\xe1\\xc7\\xf0\\xf7\\x93\\xa8\\xae\\xdd\\x3d\\xa5\\x8b\\xca\\x43\\x24\\x00\\xe1\\x33\\xa5\\x4f\\x78\\x1e\\x51\\x4f\\x6e\\x8d\\xf0\\x79\\x04\\xfa\\x46\\xd2\\x5a\\x8b\\x7c\\x8c\\x1b\\x6d\\x32\\xf5\\x68\\x5f\\x3a\\x38\\x86\\x78\\x5c\\x6c\\x55\\x03\\xf3\\xc8\\xd6\\xf4\\x1c\\x2f\\x75\\xef\\xcc\\x8e\\x46\\x2c\\x9c\\x45\\xb2\\xe3\\x1f\\x47\\x74\\x8c\\xe4\\xcf\\x52\\x76\\x59\\x5e\\x7e\\x1a\\xd5\\xf5\\x1c\\x07\\xcf\\x9e\\x22\\x8f\\xdd\\x32\\xae\\x2a\\x7b\\x0e\\xfe\\x54\\x49\\x62\\xee\\xb0\\xfc\\xf6\\x13\\xf5\\xed\\xff\\x13\\x8d\\x59\\xf8\\xff\\x1e\\x15\\x08\\xe4\\x8f\\xef\\xf7\\x5b\\x6c\\x8c\\x7d\\xd8\\xd0\\xd6\\x19\\xc9\\xe6\\x7d\\x5f\\xce\\x8e\\x81\\xb5\\x2f\\xa7\\x30\\x07\\x8a\\x3c\\x41\\x1d\\x4b\\xb9\\x13\\x03\\x18\\xd0\\x52\\x96\\xa4\\xdd\\x29\\x0f\\xb8\\xef\\xff\\xac\\x8a\\x73\\x49\\xde\\x04\\xdd\\x22\\x2e\\x09\\x8d\\xba\\xe1\\xc6\\x5f\\x10\\x79\\xd8\\x23\\x46\\xb5\\x39\\x11\\x78\\x62\\xae\\x31\\x2c\\xcc\\x4c\\xd6\\x3b\\x6b\\xe7\\x50\\x1e\\xda\\x65\\x63\\xdc\\x79\\xe2\\xae\\xd6\\x73\\x8c\\x1b\\x09\\xd0\\x0a\\x84\\xde\\xbd\\xf8\\x72\\xc0\\x11\\xa6\\x2f\\x17\\x1d\\x54\\x00\\x6a\\x71\\xd6\\xf2\\xc8\\xcf\\x65\\x34\\x1b\\xf4\\x90\\x6c\\xf5\\x89\\x12\\x0d\\x0e\\xeb\\x16\\xb5\\x9c\\x58\\xd9\\xfb\\x1d\\xf7\\x6b\\x17\\x32\\x60\\x0f\\x5c\\x5b\\x2b\\xd1\\xb1\\xf2\\x42\\xef\\xad\\x59\\x22\\x1b\\x7b\\xca\\x7a\\xad\\x7e\\x82\\x41\\xf8\\xb8\\x43\\x8c\\x0c\\x7a\\x6e\\xc2\\x1a\\x0c\\xe0\\xb5\\xb5\\x6b\\xba\\x61\\x6f\\xea\\xfa\\xcf\\x85\\xc1\\x7d\\x41\\xb0\\x56\\x4a\\x78\\x18\\xf6\\x5a\\x83\\x1b\\xd2\\xdd\\xbb\\x20\\xbd\\x7d\\x44\\x17\\xab\\x59\\x02\\xc9\\x6f\\xe1\\x45\\xcf\\xec\\x5e\\x1e\\xeb\\xe4\\xd9\\x27\\x90\\x07\\x1f\\x24\\xc6\\x12\\xaf\\x7b\\xea\\xd1\\x52\\xd2\\x91\\x34\\x30\\x25\\x96\\x62\\x04\\xb7\\xef\\xf5\\x6d\\xea\\xfb\\xe0\\xd7\\x67\\x21\\x2d\\xc5\\x81\\xf7\\xb4\\x7d\\x39\\x99\\x5f\\x74\\xdf\\x3d\\x69\\xdf\\x69\\x63\\x65\\x34\\x49\\x0d\\x34\\xaa\\xa6\\xfe\\xa3\\x8b\\x4c\\xe6\\x17\\x48\\x22\\x8c\\xd6\\xe4\\xe1\\x0b\\x89\\x13\\xc1\\x1e\\x03\\x77\\x2a\\xad\\xd5\\x17\\x00\\xf4\\x80\\xf1\\x85\\x85\\x55\\x53\\xf7\\x78\\x0e\\xb5\\x8f\\xbd\\x89\\x07\\xd0\\xdb\\xc3\\x36\\x5b\\x22\\xd9\\x95\\x1b\\x72\\xab\\xa6\\xeb\\x81\\x02\\x72\\x19\\x51\\xba\\x75\\xa0\\x9e\\xec\\xa8\\x97\\xc5\\xa5\\x70\\x9f\\x4f\\x3e\\xc6\\xe4\\x9e\\x7a\\xda\\x6a\\x13\\xc0\\xd9\\xcc\\xae\\x24\\x78\\x37\\x6a\\x7e\\x6e\\x07\\x5c\\x82\\x47\\x23\\xf7\\xb4\\xd0\\x9c\\x76\\x10\\x30\\x96\\x59\\xf4\\x61\\x44\\xe9\\x6e\\xe9\\x39\\x14\\xcf\\x1b\\x20\\x02\\xeb\\xee\\x29\\x64\\x43\\xef\\x4f\\x6f\\x16\\xb2\\xa7\\x23\\xee\\xfb\\xa3\\x7b\\x92\\xd0\\xd1\\x5c\\x92\\xee\\x35\\x50\\xe8\\x07\\xc3\\x4e\\x64\\xf8\\x10\\xdb\\x83\\x45\\x4c\\xe3\\x30\\x03\\x11\\xfd\\xfd\\x32\\x3e\\xbd\\xfd\\x36\\x81\\x1c\\x79\\xdc\\xe7\\x87\\x47\\xf3\\x45\\x45\\x33\\xea\\xe5\\x3c\\x03\\x97\\xd0\\xad\\xef\\x8f\\x2a\\xdf\\xef\\x0c\\xa7\\xb1\\xdb\\x3f\\xdd\\xa0\\x8a\\x86\\xbb\\xe5\\xda\\xa1\\xf8\\xc1\\x7a\\x2a\\xa7\\x1f\\xae\\x23\\xb2\\xf3\\xfd\\x3d\\x3e\\x24\\x14\\x95\\x14\\x15\\x14\\xa5\\x14\\xe5\\x14\\xc5\\x74\\x8d\\xc3\\xab\\xa8\\xae\\x51\\x1c\\x5e\\x45\\xf4\\xd0\\x60\\x1c\\xc6\\x9a\\x0d\\x7b\\xf3\\x52\\x3e\\xcf\\xdd\\x7b\\x55\\x60\\x1b\\xd5\\x75\\x18\\x61\\x89\\x07\\x29\\xfd\\xe0\\xfb\\x45\\x38\\x8f\\x24\\x7f\\x19\\x3e\\x8b\\x48\\x4c\\x4b\\xdf\\x5f\\x3b\\x96\\x7d\\x61\\x19\\xd9\\xe9\\x18\\x8f\\x4b\\xdf\\x8f\\x7d\\x5f\\x4e\\x4b\\x5d\\xa3\\x84\\x96\\x74\\x86\\xeb\\xba\\x9a\\xee\\xf3\\x3d\\x02\\x7b\\xb5\\xee\\x4c\\xf8\\xfe\\x78\\x9c\\xf8\\x7e\\xac\\x64\\xf8\\x69\\xb8\\x8d\\x68\\xf8\\x81\\x94\\x24\\x89\\x16\\xca\\xb1\\xc7\\x72\\x2e\\x7b\\xdf\\x87\\xea\\xdc\\x91\\xb1\\xff\\x4b\\x23\\x23\\x60\\x0d\\x91\\xe0\\xbf\\x3e\\x8a\\xff\\x72\\xbd\\xf5\\x30\\x61\\x10\\xaa\\xf7\\xf1\\xff\\xd0\\x73\\x39\\x35\\x49\\x84\\x89\\x9a\\xad\\x8e\\x1f\\x13\\x4a\\x26\\xf4\\x56\\x36\\x7d\\x53\\xd7\\xc9\\xdf\\x6f\\x28\\x9d\\xf9\\xfe\\xec\\x82\\x26\\xe7\\x37\\x4d\\x33\\x40\\x74\\x49\\x6e\\xc8\\x6e\\x4c\\xaf\\xa7\\x7b\\x60\\xd4\\xca\\x90\\x45\\x75\\x7d\\x3d\\x2d\\x99\\x50\\xbc\\x50\\x19\\xf6\\x46\\xe6\\xb2\\x10\\x5e\\xc5\\xb5\\x8d\\x02\\x4b\\xce\\x54\\x05\\x8a\\xcb\\xb7\\x1e\\x79\\xe1\\x55\\xb4\\x8c\\x51\\x8e\\x83\\xf9\\x45\\x6c\\xec\\x3a\\x91\\xa0\\x21\\x23\\x8c\\x78\\x1e\\xc9\\x23\\xe2\\xb6\\xd5\\x73\\xec\\x40\\x7d\\x53\\xba\\xe5\\x23\\x86\\x1c\\xec\\x51\\xf3\\x8d\\xef\\x11\\x23\\x45\\x98\\x46\\xd8\\x1a\\x6f\\xc0\\x5d\\x83\\x87\\xe8\\xa9\\xac\\x4c\\x12\\xf7\\x06\\x07\\xb1\\xe4\\x0b\\xd5\\xcc\\x04\\x07\\x9e\\x8b\\x20\\x3b\\x56\\xb5\\x68\\x2d\\x55\\x18\\x91\\x92\\x6e\\x10\\xeb\\x5b\\xa2\\xd9\\xc9\\x28\\xe5\\x64\\xf4\\x46\\xd0\\xb1\\x35\\xa5\\xa5\\x39\\xf6\\x17\\x24\\x84\\x25\\x66\\xdd\\xd1\\xc4\\x93\\x09\\x46\\x29\\xcd\\xc3\\x38\\x52\\x2c\\x4a\\xac\\x86\\x13\\x47\\x34\\xc5\\xdd\\xc1\\x74\\xfc\\xc8\\x0a\\xe0\\x65\\x48\\x89\\x0a\\x2d\\x55\\x20\\x29\\x26\\xf0\\x10\\x6e\\x47\\xa9\\x82\\xe9\\xa6\\xc1\\x64\\x1b\\x97\\x9d\\x31\\x3e\\x66\\x57\\x64\\x0e\\xec\\xcc\\x9e\\xd3\\x1b\\x4c\\xcc\\x31\\xfd\\x44\\x2d\\x82\\x8a\\x3e\\x43\\x7c\\x5c\\xb1\\x24\\x71\\x9d\\x73\\x4e\\x5d\\xcb\\x03\\x4c\\x4b\\xdd\\x04\\xf4\\x35\\x8b\\xf9\\x4d\\xa7\\x99\\x76\\xc4\\xff\\xd2\\xec\\x1f\\x70\\x05\\xa7\\x20\\x16\\xbe\\x3f\\xf3\\xc6\\x1c\\x13\\x4e\\xf9\\xa3\\x9c\\x19\\x39\\xd6\\xaf\\x25\\x39\\x48\\x25\\xa9\\x3c\\x9e\\x43\\x4d\\x7d\\xc6\\xe4\\x7e\\x97\\x05\\xf2\\x85\\xec\\x40\\xff\\x9d\\x7a\\x8e\\x8d\\x33\\x76\\xdf\\x27\\x0b\\x3b\\xb1\\x01\\xec\\xa0\\x39\\x50\\xe9\\x46\\x81\\x02\\x9c\\xfa\\x1c\\x41\\x55\\xdf\\xb4\\x0e\\xb7\\x62\\xd0\\x06\\x13\\x11\\x17\\x7d\\x1f\\x7f\\xc5\\xfe\\xf0\\x69\\x96\\xaf\\x63\\x25\\x94\\x6d\\xaf\\xe5\\x3e\\xdc\\x76\\x14\\xeb\\xc6\\x22\\x1f\\xda\\x48\\x93\\x86\\x14\\x79\\x3e\\x18\\x33\\x80\\x49\\x9c\\xd7\\x10\\xf0\\x7e\\x3a\\xf5\\xfe\\x72\\x1a\\xaf\\xe5\\x59\\xaf\\xb5\\xf9\\x19\\x5d\\xca\\x26\\x5f\\x83\\xcb\\x54\\xdd\\x5e\\x23\\xc9\\x5c\\x8e\\x46\\x48\\x19\\xbd\\xc9\\x59\\xdc\\x16\\x6c\\x53\\xd7\\xff\\x61\\x53\\x11\\x5f\\x83\\x55\\x20\\xb8\\x84\\x83\\x0e\\x22\\xb8\\x61\\x68\\x34\\xc7\\xc4\\xe8\\x24\\xe0\\x7e\\x86\\x89\\x56\\x70\\x0d\\x32\\xe3\\x8f\\xda\\xe1\\x39\\x66\\x78\\xb2\\x17\\x6c\\x6a\\xbc\\xbd\\x6a\\x4f\\x29\\x98\\x9c\\x57\\x46\\x05\\xd9\\x10\\x73\\x35\\xcc\\xa8\\xbb\\xd6\\x77\\x1d\\x53\\x3a\\xf3\\x19\\x0c\\x8a\\x68\\x03\\xfe\\xb6\\x56\\xb6\\xdb\\x8b\\x87\\x4e\\x95\\x7f\\xe9\\xe4\\x9f\\x4a\\x7c\\x64\\x40\\xe2\\xe2\\xd3\\x21\\x4f\\x5e\\xd5\\x87\\x81\\xde\\x8e\\x2c\\x4d\\x98\\x42\\xeb\\xa0\\x98\\xde\\xb2\\x38\\x61\\xc5\\xd0\\xd8\\xfe\\xa1\\xcf\\x67\\x76\\x4e\\x71\\x43\\x60\\x02\\x87\\x0a\\xff\\x30\\x50\\x58\\xd9\\x39\\xfe\\x1f\\x2e\\x93\\x63\\x2d\\x69\\x80\\xc6\\x35\\xa0\\x6c\\x08\\x38\\xef\\x1c\\x6f\\xe6\\xbf\\x6e\\xf0\\xe9\\xc9\\x1a\\xda\\xfa\\x7d\\x1f\\xa9\\xe3\\x02\\x12\\x47\\x76\\xd8\\xc0\\xfa\\x82\\xe7\\xb6\\xf9\\xa6\\xbf\\xcd\\x4d\\x58\\x88\\x5b\\x07\\x89\\x99\\x49\\x0a\\x67\\x11\\xe0\\xb8\\xde\\x6b\\x47\\xe8\\x19\\x8a\\xc9\\x5c\\x96\\x61\\xbf\\xf7\\x4b\\xb4\\xb8\\x3f\\xe4\\x17\\xb3\\x25\\x1f\\x8b\\x80\\x43\\xc9\\x5b\\xc6\\x8f\\x6b\\x73\\xdc\\x20\\x17\\xfc\\x42\\x2c\\xf8\\x98\\x3e\\xc3\\xac\\x6f\\x2b\\xc1\\x1a\\x0c\\xa1\\x22\\x1e\\xf9\\x7c\\xfe\\x27\\x9f\\x67\\x47\\x43\\xe9\\xba\\x15\\x9b\\xbe\\x8a\\x0b\\xbe\\x14\\x01\\x5f\\xcc\\x2e\\xe8\\x64\\x52\\x2c\\x4c\\x65\\x45\\xa7\\xb2\\x9b\\xbf\\x58\\x19\\x5f\\x8c\\xc7\\xc5\\x85\\x18\\xae\\xa5\\x69\\xb0\\x85\\x72\\x2e\\xb6\\xd4\\x81\\xf9\\xdf\\xc9\\xa1\\x88\\x93\\x34\\x0f\\x46\\x33\\x85\\x43\\xae\\xf3\\x7b\\x79\\xbd\\x49\\x21\\xfa\\x0e\\xd9\\xc7\\x65\\x79\\x97\\x17\\x89\\xbc\\x4e\\x77\\xf1\\x0d\\x84\\xe4\\xc1\\x2e\\x23\\x45\\x13\\x30\\x50\\x31\\x46\\x9d\\x87\\xb2\\xba\\xde\\xa5\\x42\\x96\\x2f\\x58\\xc9\\xc4\\x71\\xf9\\xad\\x2a\\x6f\\x6c\\x49\\x77\\x0c\\xe1\\x43\\x6b\\x5a\\x7a\\xcf\\xcc\\xbe\\x57\\xfb\\x62\\x46\\x3a\\xbe\\x2e\\x9e\\xb7\\x10\\x17\\x7c\\x21\\xc6\\x63\\x5c\\x8c\\x21\\x9e\\x83\\x12\\xfe\\xb6\\xb6\\x2e\\xb6\\xa6\\x6b\\x86\\x4a\\x62\\xf9\\xa7\\x0a\\x4c\\x80\\x0b\\x92\\x69\\xe4\\x41\\xd6\\x34\\xab\\xeb\\x8a\\x6c\\x60\\x43\\x39\\x42\\x36\\x4a\\xe9\\x9a\\xec\\xa9\\xa3\\xf4\\xd0\\xe8\\x67\\xd9\\x5f\\x05\\xed\\x75\\x43\\x59\\x58\\x45\\x86\\xdf\\x67\\x8e\\xd6\\x70\\x63\\xc4\\x8e\\xa5\\xfe\\xa2\\xa5\\x56\\x8f\\x1d\\xf8\\x24\\xef\\xbb\\x8f\\x94\\xe9\\xf7\\x51\\x1b\\x03\\x8d\\xf8\\xbe\\xa9\\xdf\\x6a\\x07\\x5d\\xe1\\xe6\\x63\\xfd\\x03\\x7d\\x12\\xca\\x29\\x53\\x2c\\x3a\\xb3\\x2c\\x3a\\xeb\\xb1\\xe8\\xac\\xcb\\xa2\\x93\\xcc\\xf7\\xb3\\x47\\x10\\x08\\x56\\x8d\\xd6\\x35\\x5b\\x18\\xb7\\x18\\x54\\xd0\\x34\\x5c\\xab\\xa3\\x95\\x7b\\x22\\xa1\\x8e\\x5b\\x50\\x1c\\x3e\\x93\\x2c\\xeb\\xb3\\x48\\x79\\xc4\\x84\\xeb\\x88\\xc6\\x58\\x3e\\x3b\\x1e\\x60\\x4b\\xf7\\xed\\x7a\\xdf\\x31\\xd4\\xca\\x40\\xe6\\x17\\xe9\\x90\\x87\\x95\\x9d\\x6a\\x9a\\x1e\\x1b\\xfb\\x83\\x62\\x2e\\x2c\\xa2\\x5e\\x63\\x0e\\x1d\\x09\\x52\\x89\\xaf\\x6c\\x8b\\xef\\x18\\xb2\\x61\\x52\\x5a\\x98\\x85\\x25\\x94\\x6c\\xf2\\x8c\\x54\\x2d\\xe8\\x66\\x54\\xf9\\xe4\\x0b\\x1b\\xb3\\x04\\xe6\\xbd\\x04\\x1e\\x57\\x1e\\xc3\\x39\\xca\\xa1\\x1e\\x79\\x54\\x52\\x7b\\x38\\x87\\x79\\x56\\xfe\\xdd\\xa8\\xc4\\x6e\\x08\\x10\\xdb\\x85\\x4b\\x86\\x12\\xb2\\x25\\x37\\xe4\\x96\\x3c\\x90\\x96\\xf4\\xdc\\xfa\\xfe\\xe8\\x36\\xbc\\x8a\\x7c\\x1f\\xdd\\xd2\\x4b\\x86\\x6e\\x31\\x26\\x0f\\xbe\\x3f\\x7a\\x50\\xcf\\x1e\\xe4\\xb3\\x07\\x88\\xcf\\xf0\\x18\\xab\\x4e\\x62\\x65\\xa3\\x55\\xc9\\x3f\\x19\\xb5\\xf1\\x16\\xd6\\x54\\x42\\xcf\\x49\\x9c\\x34\\x83\\x70\\x65\\x36\\x18\\x43\\x0a\\xc1\\x18\\x40\\xdb\\x27\\xc2\\x22\\x72\\x45\\x50\\x0d\\xda\\xd6\\xb5\\xf7\\xd4\\x23\\xad\\xfd\\x1a\\x58\\x5f\\x72\\x38\\x19\\x6c\\xe8\\x28\\xa9\\xeb\\x11\\xf3\\xfd\\xed\\x72\\x1d\\xbc\\x63\\x68\\x2d\\x8f\\xcb\\xd0\\x43\\xb2\\xa7\\x37\\xcb\\x07\\x09\\xb2\\xcb\\x24\\xc8\\xea\\xfa\\x16\\xa2\\xad\\x88\\x60\\x23\\x21\\xe7\\xc6\\xf7\\x6f\\xd0\\x86\\xec\\x55\\xc9\\x5b\\x7c\\x48\\xe9\\x3b\\x86\\xf6\\xa4\\xc2\\xe4\\x16\\xa5\\x24\\x8c\\xd4\\x8b\\xbc\\x0f\\x03\\xb9\\x3c\\x78\\xc4\\x34\\x0d\\x73\\x58\\x94\\x7d\\x58\\x85\\x79\\x24\\xcf\\x1e\\x1b\\x7d\\x15\\x63\\xdc\\x48\\x66\\x43\\x89\\x49\\xea\\x3a\\x31\\xf2\\x12\\x38\\x17\\xe5\\x74\\x3f\\x58\\xdf\\x5e\\xd5\\x97\\xaa\\x75\\xdc\\x84\\xb9\\xac\\x68\\xf1\\x00\\x14\\x95\\xec\\xe1\\x58\\x45\\x0a\\xdc\\xfc\\xc9\\xe7\\xf2\\xb4\\x90\\xd2\\x87\\xe5\\xf7\\xe0\\x8a\\x16\\x94\\xba\\x93\\x2c\\x4c\\xd5\\xe9\\x28\\x55\\xdd\\x53\\x3b\\x7f\\x0f\\x03\\x96\\xa4\\x78\\xb9\\x37\\x8a\\x9e\\x8c\\x98\\xfa\\x71\\xb0\\xc7\\xe4\\x61\\xa9\\x7b\\x20\\xc8\\x9e\\x14\\x38\\xb0\\xfe\\x8e\\x64\\xdf\\x31\\xf5\\x7f\\xd5\\xc1\\xc7\\x29\\xd1\\x66\\xf0\\xd6\\x9b\\x80\\x5e\\x4f\\x8d\\x56\\x23\\x04\\x41\\xb2\\xe4\\x07\\x22\\x12\\xd3\\x5c\\x9e\\xb0\\xed\\x2b\\xef\\xcc\\x93\\x5b\\x22\\x5f\\xce\\x03\\xb9\\x2d\\x06\\x1d\\x3a\\x81\\x6d\\x4e\\x1b\\x12\\x13\\xc9\\xd1\\x66\\xc3\\x85\\x26\\xf3\\x8b\\xef\\x51\\x0a\\x51\\xb0\\x54\\xb9\\x35\\x0d\\x87\\x77\\xf8\\x28\\x97\\x3b\\xab\\xae\\xc5\\x88\\xd2\\x3b\\xb9\\xad\\x50\\x4a\\x05\\x6e\\x01\\xad\\xd2\\xc5\\x83\\xcc\\x6c\\x78\\x03\\x97\\xa9\\x3a\\x31\\x16\\x4d\\xb4\\x28\\x2f\\x0a\\x13\\x60\\x48\\x74\\x87\\x5a\\xea\\xa1\\xe2\\x35\\x0d\\xaf\\x19\\xba\\x63\\x68\\x8d\\x89\\xc0\\x51\\x8b\\xf1\\xe4\\x07\\x4a\\x50\\xee\\x14\\x37\\x8e\\x62\\xa0\\x65\\x93\\x4f\\xb5\\x22\\x1b\\xe3\\xf0\\x2a\\x32\\x61\\x61\\xc6\\xe3\\xd2\\x8d\\xcf\\xd0\\x69\\x97\\x9b\\x76\\x3b\\xc1\\x5d\\x2e\\x19\\x9a\\x5f\\x94\\xbe\\xaf\\xba\\x01\\x97\\x92\\x92\\x5a\\x01\\x66\\x39\\x99\\x63\\x1d\\x62\\x10\\x1d\\x94\\xba\\xd4\\x3b\\x53\\x4a\\x8c\\x72\\xf2\\x4c\\x55\\xb9\\xf4\\x9e\\x7a\\x81\\xe7\\x35\\x4e\\xd0\\x20\\xe3\\x67\\x26\\x48\\x79\\xc1\\x7d\\xff\\x55\\x5b\\x65\\x29\\x27\\x8c\\xf0\\x8b\\x42\\x3d\\xa5\\xe6\\xb9\\x7d\\x0a\\x84\\x1c\\x37\\x6b\\xed\\x65\\x66\\x35\\x8c\\xd0\\x43\\x73\\xb3\\x63\\x4e\\xa4\\x37\\x33\\x5b\\x65\\xcb\\xa0\\x74\\x04\\x27\\x20\\xa9\\xdf\\x31\\xb2\\xa5\\xa5\\xa4\\x37\\x1f\\x18\\x4f\\xff\\x18\\xf4\\xb0\\x26\\x5d\\xd1\\xe9\\xbd\\x11\\xfb\\xa7\\x1b\\x94\\x59\\xcb\\xd4\\xe5\\x2c\\xc8\\xac\\x36\\x75\\x11\\x53\\x66\\x70\\xdd\\xf5\\xd4\\xea\\xc8\\x8c\\x44\\x42\\xad\\x0b\\xc4\\x56\\x91\\xa8\\x1a\\x15\\xf4\\x57\\xe5\\x99\\x1a\\x4b\\xc6\\x17\\x41\\x98\\x26\\x1a\\xeb\\xda\\x24\\x7d\\x33\\x3b\\xad\\xae\\x63\\x6b\\x3f\\x25\\x91\\x84\\x9c\\x1c\\x3a\\x9a\\x13\\x54\\xd0\\x3f\\x6c\\x0d\\xe0\\xe7\\x61\\xfd\\xec\\x88\\x46\\x14\\x7a\\x95\\x38\\x81\\x20\\x89\\x50\\xa9\\xb3\\x2a\\x67\\x60\\x5e\\xd8\\x36\\x6a\\x95\\x3a\\xca\\x04\\x5a\\x76\\x1e\\xcb\\x7e\\x7e\\x19\\xe6\\x91\\xd3\\x55\\x89\\xc7\\xd4\\x00\\xe4\\x15\\x2a\\xa0\\xfb\\x7f\\xda\\x78\\x4e\\x34\\x90\\x06\\xc5\\x89\\x46\\xc1\\xa8\\x85\\xeb\\x08\\x45\\x76\\x86\\x8d\\x30\\x2c\\x88\\x97\\xad\\x7a\\x0c\\x07\\xf7\\x88\\x91\\x12\\xdb\\xb9\\x6f\\xc8\\x86\\x96\\xca\\x48\\x28\\xcd\\x86\\xd7\\x53\\x12\\xb7\\x1d\\xb9\\x97\\xeb\\xaa\\x30\\x6d\\x28\\x31\\xcc\\x0b\\x67\\x5d\\x47\\x31\\x3e\\x28\\x75\\xce\\x16\\x41\\xd8\\xa1\\x96\\x02\\x69\\x93\\x17\\x85\\x4d\\x5f\\x31\\x10\\x8c\\xc1\\x6e\\x5b\\xa6\\xc6\\x7d\\x37\\xc8\\xcd\\xd5\\x02\\xc5\\xf4\\x05\\x62\\x04\\xdd\\xd2\\x9c\\xec\\xe8\\xec\\x02\\x3d\\xd0\\xd4\\x48\\x7e\\xc8\\x3d\\x9d\\x5d\\xdc\\xb6\\xcc\\x68\\x9f\\x70\\x4a\\x2e\\x40\\x73\\x00\\x12\\xf4\\xe8\\x8c\\x64\\xd4\\x9b\\x81\\x54\\xde\\xf7\\xc3\\x88\\x6c\\x64\\xbf\\xf7\\xf4\\x8e\\x24\\x92\\x80\\xde\\xfb\\x7e\\x6b\\xad\\x8e\\x24\\x15\\x4c\\x31\\xd9\\xd2\\x0f\\x63\\xaa\\xce\\x5a\\xfb\\xe5\\x3c\\xe8\\xc4\\xf2\\xaa\\xeb\\xe9\\x9c\\xdc\\xd0\\xc4\\x0c\\x4c\\xc2\\x64\\xea\\xfb\\xe8\\x8e\\x6a\\x5b\\xa7\\xba\\x4e\\xf1\\x22\\x1b\\x81\\xe6\\x41\\x47\\x00\\xca\\x69\\x12\\x66\\x11\\x5e\\x64\\xe3\\x31\\x10\\xab\\x7b\\xdf\\xcf\\xf1\\x21\\xa6\\x33\\x22\\xea\\x3a\\xef\\x1b\\x47\\x5d\\xd6\\x35\\x7a\\x27\\xf9\\x0e\\x4e\\x47\\xaf\\x8c\\xb9\\x40\\x49\\x6f\\xc3\\x58\\x9b\\xe7\\x97\\x28\\x97\\x1f\\x5e\\xca\\xcd\\x7f\\x28\\x0c\\x9b\\xa2\\x05\\xd8\\xb2\\x2f\\x1f\\xe8\\x16\\x37\\x3b\\xdf\\x47\\x28\\xa7\\xa3\\x52\\x36\\xe6\\xfb\\xd5\\x64\\x42\\x98\\xef\\xaf\\x4d\\x71\\x20\\xa2\\xd5\\x98\\x66\\x64\\xe7\\xfb\\xb2\\xbb\\x15\\xf4\\xc8\\x36\\xf7\\xa0\\x9a\\x2b\\xd1\\x9a\\x6c\\x14\\xdf\\x6c\\x89\\xee\\xec\\xa2\\xd2\\xa2\\xeb\\x6c\\x32\\xc1\\x6b\\x10\\x5a\\x6f\\x94\\xe8\\x5a\\xfe\\xd0\\xdf\\x95\\x79\\x4a\\x81\\xf1\\x62\\x23\\x69\\xe0\\x06\\x37\\x86\\xb0\\x15\\x64\\x83\\x49\\xea\\xfb\\x92\\x9f\\x98\\x5d\\x6c\\xac\\x71\\xe2\\xfc\\xa2\\x1a\\x3f\\xd8\\xbb\\x8e\\xdd\\x06\\x2a\\x2c\\xa2\\xd2\\x63\\x23\\x77\\x74\\x8f\\xc9\\xba\\x21\\xbb\\xa5\\x64\\x1a\\x71\\x50\\x60\\x30\\x87\\xd6\\xc6\\x4a\\xac\\xb1\\x1c\\x1a\\xb9\\x69\\x0d\\x07\\x8e\\x00\\xe5\\xc8\\xf1\\x9e\\x0e\\x07\\x5e\\x65\\x64\\x4d\\x47\\x85\\xef\\x6f\\x11\\xa3\\x99\\x6d\\xa6\\xae\\x95\\x43\\x80\\xf1\\xc0\\x97\\x7c\\xfd\\xda\\x6c\\x45\\x39\\x4b\\xcf\\x2e\\x50\\x4e\\xd7\\x92\\xcd\\x5e\\x3b\\xaa\\x5d\\xdc\\x5a\\xb9\\x7a\\x6f\\x5e\\x4a\\xdc\\x8f\\x62\\x9a\\x87\\xb3\\x08\\xeb\\x33\\xfe\\x67\\x3d\\x37\\xd5\\x57\\x12\\x40\\x2d\\xe5\\xc9\\x41\\x09\\x0f\\x94\\x47\\xf9\\xdd\\x0b\\x8a\\xac\\xf7\\x09\\xb2\\xf6\\xac\\x2e\\x9e\\xd2\\xa2\\x4f\\x81\\x8d\\x22\\xc2\\xf1\\xca\\xcf\\x40\\x61\\xd7\\x31\\x72\\x24\\x2d\\x15\\xc9\\x0d\\x42\\x52\\xa7\\x3b\\x33\\xb8\\x26\\xa5\\x5f\\x4e\\xdd\\x08\\x25\\x5a\\xc2\\x82\\x97\\xb3\\x20\\x3f\\x96\\x89\\xcb\\x7e\\xca\\x21\\xa6\\x11\\x71\\x06\\x52\\xd2\\xb8\\x43\\x41\\x25\\xa9\\xae\\xa8\\x1a\\x8a\\xe6\\xc7\\x0b\\x5a\\x3d\\x3a\\x22\\xe3\\xbe\\x9e\\x1b\\x86\\x47\\xb9\\xb1\\x8b\\xae\\x1b\\xbb\\xd0\\x6e\\xf1\\xb9\\x61\\xc1\\x52\\x32\\xc7\\x64\\x84\\x98\\x95\\xdf\\x03\\x95\\xcc\\xdb\\x60\\x05\\xad\\x1b\\x79\\x81\\x09\\x37\\x7a\\x21\\x0d\\x54\\x28\\xab\\xeb\\x0d\\x62\\x64\\x8d\\x31\\x2a\\xc0\\xbe\\x8a\\x70\\x32\\x12\\x75\\x6d\\x7a\\x73\\xaa\\x17\\x84\\x37\\xc4\\x35\\x23\\xa2\\x57\\xc6\\xef\\xd9\\xc3\\xc6\\x88\\x48\\x9b\\xe5\\x82\\xab\\xd5\\x15\\x39\\x36\\x45\\xa2\\xa3\\x51\\x46\\xde\\x21\\x4c\\xba\\xb6\\x9a\\x27\\x9c\\xcc\\xe6\\x8f\\x18\\xbe\\x3e\\xe2\\x04\\x3e\\x60\\x31\\x6f\\x8f\\xe0\\x43\\x86\\xf3\\x7f\\x53\\x56\\xf2\\x1e\\xf1\\xfe\\xa6\\x64\\x55\\xad\\x98\\xb0\\x27\\xa4\\x92\\xe5\\x25\\xc5\\xac\\xeb\\x8d\\x16\\x59\\xd5\\x20\\x64\\xdd\\xb2\\xf4\\x66\\x2b\\xea\\xbb\\x34\\x11\\x5b\\x8f\\xf4\\xf9\\x48\\x45\\xd4\\x86\\xfd\\xd2\\x04\\xf1\\x8c\\xd2\\xb7\\x27\\xef\\x5a\\xce\\x83\\x67\\xb8\\xe7\\x8b\\x78\\x64\\x8b\\x3d\\x38\\x2e\\x10\\xcc\\x9d\\x83\\x57\\x89\\x33\\x92\\xae\\x11\\x3e\\xec\\x07\\xe5\\x6d\\xe1\\xfd\\xc9\\xa0\\x55\\x51\\x3b\\x6a\\xfd\\xe5\\xe0\\x20\\x7d\\xff\\xcf\\xa5\\x82\\xed\\x44\\x18\\x8f\\x54\\xb0\\xa3\\x3a\\xb5\\x64\\x3a\\xae\\x6e\\xaf\\x4f\\xad\\x2d\\xbd\\xee\\xd6\\xdb\\xa3\\x0e\\x01\\xf7\\xbe\\x70\\xe7\\x5e\\x09\\x8a\\x43\\x11\\x2d\\x7b\\x53\\xfd\\x3f\\x59\\x08\\x62\\x52\\xb2\\x06\\x5d\\xe2\\xc5\\x15\\x6c\\x79\\x9a\\x40\\x3c\\xcd\\x7d\\x41\\x93\\xd6\\xce\\x4b\\x3f\\x0a\\xbd\\xc0\\x53\\xf1\\x39\\xf7\\x85\\x65\\x49\\xaf\\x5c\\xcb\\x3e\\x73\\x43\\x13\\xe7\\x29\\xb9\\x52\\x21\\xa7\\x13\\x63\\x3f\\x47\\xae\\x94\\x5b\\xf3\\xcb\\x7c\\x4d\\x13\\x75\\x49\\xae\\x5a\\x5b\\xcf\\xc4\\x5e\\xca\\x76\\xc1\\x78\\xd1\\xda\\xbf\\x26\\xfa\\x01\\x98\\x68\\x6e\\xe9\\xf0\\x51\\x07\\x54\\x73\\xd6\\xba\\x92\\x2f\\x5a\\xed\\x49\\x28\\x24\\x42\\xfb\\x6c\\xd4\\xd1\\x9a\\x1c\\xc9\\x82\\x00\\x0a\\x52\\xdf\\xbf\\x02\\x0f\\xaa\\x52\\x32\\xf1\\xfa\\x74\\xa1\\x63\\x1a\\x5a\\x3a\\x58\\x34\\xe4\\xdd\\xc9\\xf8\\x72\\x61\\x34\\x20\\x9d\\xef\\x07\\x43\\x60\\x2a\\xe8\\x2a\\x37\\x35\\x3b\\xc6\\x76\\x1f\\xcc\\x54\\x03\\xe6\\xed\\x20\\xfa\\x56\\x5e\\xf8\\xa2\\x1b\\x3a\\xef\\x2f\\x5a\\x05\\xf5\\x82\\x00\\xc9\\xfe\\x7e\\x4b\\xcf\\xdf\\x5f\\xa0\\x30\\x9e\\xfc\\x11\\x85\\xef\\x57\\xe7\\xab\\xd9\\xe7\\x01\\x04\\x9a\\x13\\xab\\x62\\xc5\\x57\\x9b\\xe8\\x29\\x0e\\xbb\\xf7\\xab\\xf3\\xe5\\xe7\\x68\\x19\\x5c\\xac\\xce\\x57\\xf3\\xcf\\x6b\\xfc\\xe4\\x3c\\x6d\\x7b\\xf5\\x12\\xe9\\x88\\x3a\\xe6\\x60\\x83\\x38\\x5e\\xea\\x70\\xc2\\x6c\\x30\\x96\\xf0\\x68\\xd4\\x89\\xbf\\x3c\\xa2\\xb4\\x68\\x70\\xe0\\x08\\x42\\x06\\xbe\\xee\\x9c\\x94\\xb9\\xfe\\xe4\\x28\\x00\\x0f\\x7f\\xec\\xd3\\xc9\\xfc\\x22\\x6d\\xe3\\x73\\xea\\x2a\\xae\\xf4\\x91\\x41\\x3e\\x23\\x05\\x04\\xe1\\x86\\xfb\\x13\\xe0\\x26\\xc2\\x59\\x1b\\x27\\xd4\\xf7\\x11\\xa3\\x5e\\xc0\\x73\\x81\\xc0\\x68\\x0a\\x7b\\x98\\xa8\\x80\\x17\\x96\\xc3\\xea\\xf8\\xc3\\x2f\\xd5\\xb6\\xeb\\x1b\\x70\\xa3\\x82\\x30\\xbc\\x0c\\x8b\\x28\\x08\\xa3\\xa0\\x5b\\x04\\x31\\x62\\x02\\x33\\x0f\\xcd\\x45\\x17\\xc0\\x20\\x3c\\xb3\\x13\\xd7\\x18\\x1d\\xc0\\xf8\\x72\\xd8\\x9b\\xdf\\x8d\\xd8\\x9c\\xc2\\xdd\\xc2\\x31\\x51\\x6d\\x8d\\xb3\\xec\\xa1\\xb1\\x17\\x2e\\x5a\\x6e\\x17\\x3d\\x73\\x8e\\x66\\x03\\x82\\xca\\xd2\\xd9\\x42\\x5c\\x14\\x20\\xa8\\x4e\\x37\\xa8\\xdd\\xec\\x28\\x0d\\x45\\x44\\x20\\xca\\x78\\x2b\\xcd\\xc4\\x4a\\x7e\\xce\\x69\\xaf\\x81\\x30\\xc2\\xc4\\xad\\x49\\xcd\\x0b\\x62\\x04\\x2a\\x69\\x05\\x69\\xf3\\x8b\\x62\\xe9\\xa2\\x25\\xc4\\x71\\xc0\\xad\\x95\\xde\\x90\\xd1\\x5a\\xb7\\x9d\\x97\\x3a\\xb4\\x38\\xb0\\x93\\xa3\\x39\\x86\\x98\\xbf\\x83\\x3a\\xad\\x47\\x3f\\x84\\x58\\x63\\xe9\\x90\\x46\\x74\\x34\\xd2\\x25\\x8f\\xcd\\xe4\\x7c\\xff\\x83\\xe5\\xe2\\xe4\\x84\\x06\\xb6\\x17\\xad\\xbe\\x1d\\x90\\xdf\\x6f\\xe4\\x77\\x15\\xc1\\x6d\\x55\\x3e\\x45\\x17\\xe1\\xea\\x6e\\xf5\\x53\\x34\\xfe\\x1c\\x87\\xef\\x3f\\x8f\\x9e\\xd6\\x7f\\x73\\x82\\xb8\\x2d\\x90\\x8d\\x6b\\x3f\\x0c\\xc0\\x24\\x05\\xf2\\xd2\\x59\\x56\\xcb\\x50\\xff\\x36\\xd0\\x47\\xcd\\xf1\\x16\\xd4\\xbb\\x50\\x32\\x93\\x59\\xe4\\xfb\\xde\\xe7\\xea\\xba\\x8d\\x6b\\x16\\xf9\\xfe\\xf3\\x0b\\x2b\\x1b\\x5b\\x86\\x4a\\xc8\\x03\\xd6\\x08\\x51\\xf0\\xbb\\x3a\\x86\\x43\\x90\\xe3\\x51\\x11\\xca\\xc2\\xc6\\xdc\\x59\\x32\\x71\\x62\\xaa\\xe2\\xdc\\x2f\\x21\\x48\\x05\\xd6\\x0b\\x8d\\x83\\xa3\\x18\\xdf\\xc2\\xbe\\x83\\x58\\x31\\x26\\x22\\x96\\xa0\\xe2\\x2c\\xe5\\xa5\\x88\\xf9\\x1a\\x82\\xb5\\x2e\\xe5\\x26\\x0d\\x24\\xe5\\x69\\x83\\xd1\\x93\\x2b\\xc9\\x1a\\x96\\x4c\\xb2\\x1b\\xf0\\x25\\xd1\\xb1\\x8b\\xf5\\xce\\x3c\\xf6\\xde\\x09\\x5e\\xc1\\xaa\\x92\\x6f\\xd5\\x12\\x69\\xe3\\xa8\\x7e\\x48\\x6b\\x81\\xdb\\xcc\\x0a\\x02\\xef\\xa0\\xad\\xb0\\x88\\xf0\\x52\\x5f\\x20\\x01\\xce\\x22\\x30\\x14\\xb0\\x43\\x2c\\x40\\x12\\xdc\\x09\\x8b\\x6e\\x98\\xdc\\x94\\xbe\\xea\\xbb\\xa0\\x17\\xe1\\xb3\\x48\\x59\\xb5\\xca\\xea\\x66\\x11\\x4d\\x89\\xb3\\x71\\xe9\\x1c\\x13\\xa7\\x02\\x27\\x37\\xc5\\xd2\\x7e\\xc0\\xba\\x1f\\xa8\\xed\\x17\\xec\\x24\\xc8\\xb5\\x54\\x73\\x5a\\xb0\\x38\\x79\\x58\\xea\\x5f\\x80\\x44\\x74\\x25\\x71\\xa3\\x8d\\x9a\\x8c\\x54\\x3d\\xb8\\xc1\\x8e\\xd4\\x4a\\xc2\\x1a\\xf9\\x8d\\x5e\\xa1\\x57\\x0a\\x4c\\xbf\\x56\\x40\\xaa\\x78\\xf0\\xb2\\xde\\x17\\xec\\x16\\x2d\\x83\\x1f\\xb9\\x48\\xb3\\x1a\\x5c\\x99\\xcf\\xc9\\x57\\xf4\\x00\\x36\\x65\\x05\\xe3\\xa0\\x77\\x53\\xe6\\x1f\\x25\\x64\\xbe\\x60\\xf7\\xa0\\x3b\\x93\\x9f\\x75\\xb3\\x5f\\x7c\\xa7\\x88\\x47\\x9f\\xb4\\xcf\\x47\\x43\\x06\\x11\\x67\\xac\\xe9\\xe0\\xc0\\x6d\\x5c\\x0e\\x25\\x2a\\x30\\x03\\x72\\xc5\\x25\\xee\\x46\\x1f\\xc6\\x6d\\x10\\x36\\x97\\xce\\x16\\xec\\x82\\x2f\\xd8\\x11\\x7e\\x53\\xb9\\x0c\\x42\\x16\\xb9\\xf8\\xad\\x21\\xeb\\x2c\\x2f\\x99\\x1b\\xf8\\xbf\\x1b\\x18\\x5b\\xa3\\xdf\\x56\\xac\\x0c\\x12\\x9e\\x63\\x4c\\xac\\x78\\x14\\xd8\\xbe\\x16\\x6d\\x00\\xf0\\x59\\x45\\x43\\x8b\\x48\\xc3\\x22\\x5a\\x70\\xdf\\x97\\x74\\x52\\x2c\\x7a\\x2e\\x4f\\x72\\xb7\\xb7\\x36\\x03\\xf3\\xb9\\xef\\xa3\\x78\\x39\\x99\\x5f\\xc4\\xca\\x10\\x45\\x22\\xd0\\xbe\\x5f\\xfd\\x09\\xba\\x05\\x61\\xae\\xf1\\x21\\xb7\\xaa\\xe0\\xae\\x10\\xac\\x8b\\x2f\\xe7\\x17\\xe6\\x98\\xda\\xc5\\xd7\\x39\\x0e\\x72\\x30\\x25\\x48\\xd8\\xfd\\xa0\\x4d\\xc5\\x72\\x20\\xdc\\xb6\\xa6\\xe3\\x72\\x42\\x88\\x86\\x74\\x6c\\x43\\x68\\x03\\x5a\\x36\\x38\\x45\\x22\\xac\\x40\\x23\\x13\\xc0\\x5d\\xfa\\xc2\\x8d\\x79\\xa4\\x17\\xbc\\x28\\xe5\\xa9\\x5b\\x82\\xdf\\x8b\\x2c\\x43\\x06\\x07\\x07\\x93\\x79\\x43\\x62\\x37\\x85\\x42\\x27\\x1a\\x64\\x3f\\x8b\\x82\\x33\\xb2\\x4e\\x32\\x8c\\x1b\\x26\\x10\\x26\\x00\\x76\\x18\\x4b\\x62\\x11\\x27\\xc9\\x17\\xfd\\x24\\x1a\\x6e\\xa5\\x71\\x92\\x20\\x93\\xa0\\xa3\\x97\\xfe\\x20\\xe8\\xdd\\x1b\\x60\\x65\\x18\\xcc\\xa6\\x74\\xe8\\xe9\\xc3\\x80\\xe5\\x87\\x31\\xb8\\x38\\x76\\x02\\x35\\x8e\\x5d\\x2e\\x4e\\xd4\\x6e\\x45\\x7a\\x3f\\x0f\\xf5\\x74\\x8b\\x18\\x71\\x35\\xc8\\xd8\\x96\\x86\\x5d\\x7f\\xca\\x5e\\xad\\xff\\x19\\x84\\x3c\\xe7\\x7d\\xcb\\x0d\\x5d\\x58\\xee\\xfe\\x8e\\xb5\\x2c\\x6e\\x14\\x8e\\x38\\x55\\xb6\\x6f\\x1a\\xac\\xeb\\x7e\\x91\\x65\\x27\\x87\\x30\\x50\\xfd\\x63\\xc5\\x4f\\xb4\\xf0\\xe7\\x63\\x76\\xdb\\x81\\x41\\xcb\\x9a\\xfe\\xc2\\x54\\xf5\\x8d\\x9d\\xe5\\xa7\\xa5\\xba\\x19\\x5c\\x97\\x77\\xa8\\x13\\x58\\xb0\\xae\\x0f\\x0d\\x76\\x4e\\xcb\\xa0\\x43\\xb2\\x78\\x78\\xf0\\x7b\\xf7\\x70\\x2d\\x0b\\x1b\\x44\\x7d\\xe2\\xb8\\x3b\\xa2\\xca\\x81\\x8f\\x71\\x1b\\x46\\xca\\xf7\\x0b\\x74\\xf4\\x50\\xf9\\xc4\\x76\\x1e\\x05\\x48\\x9e\\x6b\\x3c\\xc1\\x76\\xfb\\x2c\\x16\\xcc\\x03\\xdd\\x5e\\x5b\\x5d\\x5d\\x33\\x6c\\x49\\x39\\x44\\xf3\\x72\\xc2\\x8f\\x82\\x43\\x86\\xe9\\x11\\x08\\xa1\\x21\\x42\\x7b\\x11\\x0d\\x46\\x9f\\x75\\xb2\\xc2\\xa4\\x6d\\x3e\\x1a\\x0f\\xe6\\xdf\\x03\\xbf\\x67\\x6d\\xdc\\xfe\\x89\\x72\\x24\\x91\\xc8\\xc5\\xf7\\x8f\\xd0\\x8f\\x00\\xad\\x85\\x3d\\x38\\x80\\xfe\\x8c\\xcc\\x2f\\x1c\\x24\\xee\\xfb\\xe8\\x2b\\xc8\\xb0\\xd4\\xe3\\x4c\\xc9\\xd7\\x9a\\x99\\x80\\x80\\x2e\\x05\\xbb\\x65\\x05\\x88\\x17\\x48\\x0f\\x8d\\x70\\x6c\\x38\\xbf\\xef\\xe9\\x79\\xf8\\xbe\\x73\\x16\\x1b\\x9f\\xdf\\xb4\\x94\\xf1\\xad\\x8b\\x28\\x5b\\xcd\\xe5\\x37\\xad\\x17\\x9f\\xf3\\xf4\\x4d\\x4f\\x06\\x0b\\x81\\x07\\x99\\xef\\xef\\x10\\x78\\xf0\\x16\\xf9\\x2e\\x2d\\x19\\x36\\xb8\\x15\\x22\\x8a\\x71\\x06\\x4c\\x57\\x9c\\x66\\x92\\x2c\\xd8\\xb2\\x62\\xcb\\x78\\x5b\\x50\\xa9\\x12\\x4d\\xfe\\x2e\\xc5\\x55\\x90\\x90\\x19\\xe9\\x6b\\x81\\x9d\\x88\\x86\\xfc\\xa8\\x14\\x6e\\x9a\\xab\\xe9\\x65\\x9c\\x65\\xd7\\xf1\\xfa\\x83\\xe3\\xfc\\x59\\x98\\x20\\xf5\\x7c\\x51\\xd0\\xa3\\x35\\x28\\x96\\x88\\xd1\\x42\\x25\\x04\\xd3\\xf8\\x4e\\x3b\\xd0\\xa2\\xef\\x41\\xe6\\x7a\\x14\\x27\\x5f\\x44\\x54\\x92\\x63\\xd9\\xd5\\x36\\x89\\x48\\x43\\x0a\\x35\\xcf\\x29\\x11\\x47\\x4a\\xff\\xc9\\x9c\\xac\\x69\\x8f\\x01\\x88\\x69\\x5c\\xd7\\xc5\\x34\\xe7\\x6b\\x46\\x72\\x9a\\xd2\\xd1\\x6c\\x51\\x19\\xf6\\x41\\x7e\\x81\\x0f\\x82\\x56\\x46\\x82\\xab\\x85\\x11\\xe3\\x71\\x76\\x61\\x20\\x03\\x83\\x11\\x7a\\x19\\x66\\x46\\x1b\\x2a\\x79\\x55\\x22\\xb4\\xe5\\xfd\\xb4\\x14\\xf9\\xfe\\x3b\\xfe\\x3a\\xce\\x4a\\x06\\x41\\xf1\\x2d\\x57\\x20\\xe8\\x68\\x8e\\x9b\\x62\\xba\\x63\\xbb\\xbc\\x78\\x00\\x6d\\xcf\\x68\\x8e\\x75\\x26\\x15\\xdf\\x47\\x25\\x15\\xcb\\x30\\x0a\\x3c\\x0f\\x74\\x4a\\x87\\x78\\x30\\xe5\\x4f\\x29\\xa1\\xda\\xf7\\x47\\x69\\xa7\\xee\\xc9\\x9c\\x54\\x46\\x53\\xd9\\xda\\xc1\\x9e\\xc1\\x0e\\x37\\x53\\xdb\\x9b\\xcd\\x1d\\x12\\x78\\x59\\x68\\xd8\\xf6\\xfd\\xcd\\x74\\x1b\\x97\\x10\\xeb\\xb4\\x34\\x15\\xa9\\xd4\\x20\\x56\\xe8\\x6e\\x99\\x19\\x7a\\x07\\x81\\x4f\\x39\\x12\\xb8\\xc1\\x0d\\x6a\\x33\\x28\\x11\\xdd\\xb1\\xb5\\xd9\\x0e\\x0d\\x51\\x11\\x2d\\x07\\xc6\\xa1\\x7b\\x65\\x3f\\x26\\x03\\x9b\\x5d\\xcf\\xfd\\x64\\x7e\\x01\\x7b\\x55\\x27\\xe2\\x40\\x82\\x80\\xf6\\x16\\x97\\xd6\\x09\\x94\\xcc\\x31\\xe1\\x17\\x34\\xf3\\xfd\\x6c\\x32\\x69\\x4c\\xdb\\x7d\\xae\\xd1\\x32\\x23\\x93\\xf9\\x45\\x5b\\x1b\\x23\\x25\\x0e\\x66\\x76\\x71\\x8f\\xcc\\x38\\x3b\\x33\\x2f\\x41\\xcb\\x54\\xaf\\x65\\x81\\x03\\x25\\x63\\x5a\\x29\\x13\\x1a\\x41\\x3d\\xaf\\x5b\\x7a\\x60\\x49\\x47\\x65\\x43\\xb2\\xdc\\xe5\\x22\\xfa\\x15\\x89\\xba\\x4e\\xeb\\x1a\\xa9\\xfa\\x4c\\xf3\\xf2\\x93\\xc1\\xea\\x46\\x31\\x58\\x2c\\xb2\\x9f\\x52\\xd1\\x4f\\xe4\\x62\\xaa\\x05\\xd8\\x0b\\x19\\x91\\xc7\\x2e\\x50\\x6e\\xa8\\x6d\\xbe\\x34\\x36\\xc4\\x38\\x10\\x51\\x0b\\x50\\x24\\xad\\x6b\\x67\\x49\\x65\\xdd\\x03\\x7d\\xdd\\x4c\\x4d\\xa3\\xfd\\xc4\\x5a\\xce\\x77\\x83\\xfd\\xcd\\x9b\\xc6\\x86\\x1e\\x73\\xb3\\x03\\xbd\\x64\\x1b\\x56\\x14\\x03\\x56\\xc1\\x39\\x0d\\x43\\x8f\\xe7\\x22\\xdd\\x3c\\x78\\x92\\xb0\\xe6\\x37\\x05\\x2b\\x4b\\x8f\\x38\\x38\\x08\\x79\\x6a\\x97\\x79\\xf8\\xc4\\xd3\\x67\\x11\\x09\\xbd\\x82\\x95\\x79\\x76\\xcb\\x3c\\xe2\\x49\\x34\\xd9\\xab\\x40\\xe2\\x87\\xb3\\xe1\\x5a\\xba\\xaf\\x66\\xc4\\x54\\x94\\x78\\xaa\\x56\\x88\\x37\\x4c\\x3c\\x89\\x73\\xff\\xd7\\x4a\\xe7\\x44\\xd7\\x23\\x2b\\x8d\\x48\\x4a\\xbd\\x3d\\xe3\\x09\\x30\\x0e\\x31\\x3d\\x94\\x22\\x16\\x43\\x8b\\x90\\x36\\x24\\xce\\xee\\xe2\\x87\\x72\\x30\\x9d\\x1c\\xd0\\x82\\x76\\x5d\\x14\\x4d\\x38\\x5a\\x27\\x0f\\x10\\xbd\\x37\\xe8\\x74\\x01\\x54\\x43\\x5b\\x7f\\x48\\xce\\x27\\xdd\\x77\\x7a\\x01\\x58\\xb8\\xcd\\x60\\xb5\\xb0\\x7b\\xdd\\x2c\\x25\\x72\\x49\\x83\\x46\\x01\\xf9\\xd0\\xd6\\xa7\\x3b\\x94\\x86\\x22\\xfc\\x38\\x02\\xdb\\x23\\x75\\xb5\\x28\\x43\\x89\\x64\\x23\\xd4\\x6b\\x91\\x41\\x1a\\xb2\\xe1\\xa4\\x6e\\x0b\\xa0\\x77\\x0e\\x65\\xb4\\x97\\x70\\x4c\\x50\\x90\\x83\\x8a\\xa9\\x82\\x26\\x4d\\x2e\\x8b\\xa9\\x5e\\x4f\\x3d\\x45\\xf2\\x1e\\x32\\x4f\\x06\\x45\\x28\\x71\\xfd\\xd8\\x93\\x60\\xee\\x45\\xaa\\x31\\x0e\\x89\\x83\\xda\\x26\\x1b\\xdc\\x48\\xa4\\xae\\x84\\xf5\\x6d\\x6b\\x0d\\x91\\x73\\xd7\\xce\\x96\\x43\\xc5\\x2b\\x3a\\x6b\\xd9\\x81\\x0c\\x69\\xc5\\xea\\xb1\\x53\\x87\\x0d\\xff\\x27\\x9b\\x2d\\xda\\x79\\x26\\x6c\\x20\\xfd\\x19\\x1c\\x32\\x51\\x7a\\x51\\x29\\x2d\\x1e\\x62\\x34\\x76\\xd4\\x73\\x98\\x52\\x9a\\xb7\\x9d\\x73\\x72\\x97\\xca\\x63\\x83\\x0e\\x19\\xf0\\x6e\\xab\\xcc\\xf6\\xcf\\x4a\\x96\\x6d\\x26\\x30\\x27\\x15\\x28\\x79\\xf1\\x42\\x40\\x6e\\xa5\\xbf\\x9a\\xf2\\x51\\xc5\\xc4\\xdd\\x32\\x4e\\x80\\xea\\x94\\x4b\\x93\\xed\\x89\\x64\\xa8\\x22\\x39\\x79\\x4b\\x4a\\xac\\x2f\\xbf\\x21\\x25\\xc6\\x01\\xaa\\xc6\\x63\\xf2\\x78\\x21\\xfb\\x34\\xd7\\x8b\\x27\\xd7\\x04\\xcb\\x6f\\xe3\\x11\\xa5\\x6f\\x81\\xbf\\xd3\\x1c\\x4a\\x41\\x25\\x8f\\x42\\x50\\x59\\xd7\\xb9\\x59\\x5a\\x28\\xad\\xa6\\xa2\\x69\\x88\\xa0\\xe5\\xb2\\x03\\xc9\\xc0\\x56\\x21\\x87\\xe9\\x69\\x61\\x78\\xca\\xee\\xd7\\x0c\\x7c\\x0b\\xbe\\xca\\xf3\\x0f\\xf2\\x60\\x3d\\xfc\\x46\\x42\\xf3\\xb4\\x94\\xbc\\xe0\\xbb\\x22\\x5e\\x33\\x4c\\xaa\\x0b\\x9a\\x8e\\xe1\\xa8\\x3e\\xa2\\xf4\\x9b\\x81\\x0e\\xe6\\x1a\\xce\\x00\\x89\\xea\\xae\\x2d\\xd2\\xa5\\x40\\x38\\x40\\x4e\\x2b\\x37\\x4c\\x00\\x8b\\xa9\\x9a\\x47\\x6e\\x23\\xf4\\x44\\x31\\x89\\xbd\\x2f\\xa7\\x25\\x13\\xef\\xd2\\x1d\\xcb\\x2b\\x90\\x79\\xd9\\xc8\\xdc\\x43\\xdb\\x93\\xe1\\x43\\x1e\\xce\\xa2\\xf0\\x79\\x04\\x87\\xd8\\x0c\\xcd\\x08\\x23\\x3b\\x54\\xe0\\x65\\x11\\xbc\\x25\\xac\\x33\\xe5\\x24\\x0f\\xe7\\x47\\x25\\x05\\x5e\\x8a\\xe0\\x2d\\xbc\\x7c\\x76\\xf4\\x12\\x92\\xc8\\x7d\\x83\\x71\\x77\\x7f\\xe8\\xcb\\x47\\x8e\\x27\\x4b\\x4b\\x1c\\xc0\\x8a\\x30\\x6e\\x1a\\x52\\xd2\\x43\\xb3\\xe8\\xf2\\x14\\xc3\\x08\\x45\\x84\\xcf\\x22\\x52\\x50\\x11\\x7e\\x12\\x2d\\x62\\x85\\x48\\x28\\x84\\x9b\\x25\\x05\\x60\\x8f\\x24\\x71\\xf1\\x4a\\x4a\\x8b\\x86\\xe4\\xe1\\xf3\\x09\\x8b\\xc2\\x67\\x91\\x89\\xc7\\x65\\x9e\\x3c\\x77\\x9f\\xcc\\xa0\\x84\\x24\\xc7\\xc4\\x4c\\x99\\xbc\\xc1\\x44\\x55\\x2a\\xe4\\x03\\x49\\xfb\\x30\\x29\\x01\\x7b\\x44\\x74\\x00\\x37\\x1f\\xe3\\x15\\xc9\\x62\\x6a\\xf1\\x5e\\x30\\x4c\\x50\\xbb\\x1f\\x51\\x6e\\x09\\x70\\x83\\x49\\x6c\\x27\\xb6\\xc4\\x44\\x79\\x70\\xcb\\xbd\\x54\\xca\\x8d\\x53\\x36\\xe4\\x6e\\xcb\\x8e\\xbd\\x38\\xf8\\x71\\x42\\x44\\x41\\x39\\x29\\xa8\\x66\\xbb\\x24\\x56\\xd3\\x69\\x46\\x9d\\xbe\\xe4\\x0e\\xcc\\x21\\x4c\\x62\\xfa\\x67\\x6e\\x69\\x92\\x8b\\x57\\xe7\\x37\\x79\\x35\\xbf\\xe8\\x37\\xba\\x3c\\x6a\\x23\\x60\\x64\\x32\\xe1\\xbd\\xcd\\x0b\\x47\\x45\\xb9\\x3f\\x36\\x88\\x5f\\x50\\xb9\\xad\\xe4\\xd9\\x28\\xd7\\x44\\x0e\\xa2\\xe4\\xeb\\xd2\\x76\\x5f\\x91\\x11\\xc7\\xc4\\xd2\\x51\\xc0\\x80\\x40\\x48\\x11\\xae\\x6b\\xa0\\x37\\x11\\xd0\\x9a\\x48\\x9d\\x8d\\xac\\xc6\\x38\\x57\\x54\\xcf\\x1c\\x05\\xc4\\x64\\x82\\xdf\\x28\\x3d\\x88\\x6c\\xc6\\xd6\\x6e\\x85\\x97\\x0e\\x5e\\x35\\x47\\xc0\\x9f\\xe8\\xf9\\x7b\\xf4\\xea\\x36\\xce\\xea\\x37\\x5c\\xb0\\x82\\xc7\\x59\\xfd\\x36\\xe6\\x37\\xac\\x7e\\x2b\\x67\\x8e\\xf1\\x35\\xab\\x55\\x7c\\x96\\x1a\\x6c\\xdb\\x7f\\x7c\\xfb\\x06\\x03\\x0e\\x7e\\x72\\xbe\\x38\\x85\\x5e\\x7a\\xa7\\xe3\\x4b\\x90\\xb2\\xe7\\x19\\xf3\\x7d\\x7b\\x39\\xbd\\x8b\\x0b\\xee\\xfb\\xcc\\xf7\\x7f\\xb2\\xbe\\x3c\\xf1\\x4e\\x62\\xe3\\x6e\\x11\\x93\\xa9\\xda\\xb6\\x74\\x66\\x5b\\x02\\x57\\xd1\\xe9\\x8e\\x95\\x65\\x7c\\xc3\\x08\\x53\\xa8\\x06\\xe2\\xf4\\x5c\\x29\\x41\\xf3\\x2b\\x53\\xb2\\x13\\x64\\xa5\\x83\\x6b\\x5c\\xb4\\xaa\\xcf\\xb3\\xb8\\x81\\x69\\x79\\xdd\\x81\\x9d\\x96\\x06\\x7e\\x81\\xf0\\xe1\\x95\\x8e\\x86\\xdf\\x8b\\x06\\xfd\\xf2\\xbb\\x6f\\xb4\\xbf\\xe1\\xd7\\x79\\x9c\\xb0\\xc4\\x23\\x5f\\x48\\xd4\\x36\\x58\\x56\\x05\\x82\\xfe\\x02\\x9b\\xbe\\x22\\x95\\x9f\\x57\\xdd\\x0c\\xe5\\x7d\\x7e\\xad\\x56\\x9a\\xe1\\x50\\x33\\x41\\x51\\x07\\x23\\xf6\\x87\\x8c\\x18\\xb6\\x87\\x8d\\x96\\x6d\\xb5\\xf9\\x29\\xe7\\x04\\x8a\\xff\\x14\\xa7\\x22\\xd0\\xd7\\x9d\\x3d\\x87\\x94\\x61\\xc0\\x72\\x32\\xd1\\x15\\x43\\xc9\\xab\\xa9\\xae\\x00\\xd7\\x35\\xb2\\x37\\x74\\x34\\xc3\\x23\\xc8\\x2a\\x31\\xbb\\xe8\\x94\\xaf\\xeb\\xd7\\x9d\\x5d\\xf1\\x8a\\x84\\x57\\x91\\x16\\x21\\x42\\x21\\x18\\x12\\x55\\x23\\x23\\xde\\x3a\\xdf\\xed\\x33\\x26\\xc0\\xf0\\xe3\\x95\\x2a\\x70\\x25\\xb7\\x40\\x5d\\xc3\\x6c\\xe9\\x03\\x9e\\xfb\\xc6\\xf7\\x47\\xaf\\xfa\\x91\\xe8\\xa6\\x49\\x7e\\xb5\\x2e\\xf2\\x2c\\x5b\\x76\\x16\\x5a\\xb7\\x88\\x03\\xf4\\x6a\\x20\\x8e\\xf7\\x89\\x95\\x3b\\x2e\\x68\\x96\\x4d\\x6d\\x9d\\x27\\x03\\x76\\x8a\\x92\\x41\\x52\\x38\\x6b\\xd0\\x4d\\x81\\x52\\x48\\x4a\\xd2\\x72\\x27\\xf4\\x0e\\x71\\x25\\x67\\x2f\\xcf\\x52\\x7e\\x26\\x8f\\xfc\\x84\\xe3\\x27\\x50\\x61\\x49\\x78\\x58\\x46\\x64\\x34\\x83\\x4a\\x17\\xc6\\x8b\\xbd\\x93\\xc4\\x14\\x3e\\xd8\\xa9\\x54\\xaa\\x31\\x64\\xb9\\xcb\\x40\\xe2\\x8e\\x2c\\x8b\\x52\\x98\\x6c\\x0d\\x38\\x40\\x19\\x15\\xe4\\x58\\x75\\xa7\\x41\\x2c\\x73\\xa4\\xde\\x1c\\xe2\\x2c\\x6a\\xf5\\x93\\x75\\xac\\x10\\x88\\xc9\\x0e\\x71\\x12\\x2f\\x8b\\xa0\\x30\\x69\\x31\\xcb\\x88\\x94\\xc4\\xbc\\x72\\x9c\\x29\\xd2\\x25\\x0b\\x32\\xcb\\x4f\\xe1\\xa0\\x5a\\xaa\\xf8\\x2b\\x84\\xe3\\x20\\x6f\\xc8\\xaf\\xf4\\xfc\\xfd\\x64\\x57\\x4e\\xce\\xc9\\x1f\\xf4\\x7c\\xa2\\xcc\\x05\\xb0\\x2b\\x7d\\xfa\\xb1\\x2b\\x0a\\x9f\\x8a\\xfc\\xc7\\xfd\\xde\\x1a\\x1a\\xd8\\x62\\x3f\\x77\\xac\\x7e\\x8c\\x3d\\xd9\\xaf\\xc4\\xdb\\x95\\x13\\x27\\x7c\\xce\\x1f\\xe4\\x47\\x65\\x9d\\xf0\\xaf\\xa1\\xed\\xd5\\xf7\\xe0\\xf9\\xac\\x77\\x3f\\x1a\\x3b\\x8a\\xf0\\xb6\\x8b\\x5f\\x02\\xe2\\x48\\xcb\\xa9\\x4e\\x17\\xab\\xcc\\x2c\\xe4\\xd5\\xf8\\xcb\\x69\\x95\\x26\\xe3\\x71\\x03\\xbf\\x74\\x4e\\xbe\\x74\\x33\\x6f\\x43\\xac\\xa3\\x21\\xd1\\x79\\xe8\\xd6\\xd6\\x0b\\xa7\\x72\\x68\\xc8\\xbf\\x54\\x06\\x70\\x37\\x14\\x63\\xf7\\x0b\\x2a\\x02\\x2d\\xb4\\x57\\x81\\x50\\x5a\\x5f\\x78\\xe2\\x96\\x23\\xda\\x0c\\x59\\x90\\x75\\xce\\x37\\xe9\\x4d\\x55\\x80\\xbc\\x00\\x14\\xe6\\x98\\x88\\x86\\x94\\x4c\\x9c\\xf2\\xa4\\x52\\xea\\x24\\x18\\x81\\x89\\x9f\\x7c\\x24\\xc2\\xc4\\x69\\xf8\\x33\\x12\\x38\\xa2\\x7c\\xd1\\xcd\\xaa\\xaa\\xde\\x14\\xb8\\x9b\\x3c\\x34\\xed\\xe7\\x10\\x77\\xd6\\x5d\\x41\\x3b\\x78\\x5c\\x74\\x1a\\x0e\\x7a\\x23\\xf7\\xfd\\xde\\x03\\xd5\\x83\\x86\\xc4\\xeb\\x35\\x2b\\xcb\\x53\\x02\\xf0\\xb6\\xfa\\xba\\x3e\\x21\\x8d\\xb5\\x45\\xf8\\xd2\\xea\\x5a\\x64\\x0f\\x03\\xa5\\x7a\\x29\\xd5\\x2d\\xe1\\x98\\xb4\\x2a\\xcf\\x25\\x0f\\x04\\x3e\\x96\\x31\\x75\\x54\\x73\\xfd\\xc5\\xee\\x6c\\x6d\\x38\\x19\\xd9\\x5b\\x81\\x0f\\x9c\\x22\\xd1\\x4b\\x95\\x2c\\x19\\x59\\x90\\x39\\xff\\x2c\\xfb\\x42\\xe5\\x78\\x71\\xca\\xcf\\x8a\\x65\\x28\\xa2\\x40\\x74\\xe4\\x95\\xf8\\xd8\\x66\\x5b\\x27\\xa2\\x91\\xe7\\x46\\x1e\\x45\\x0d\\x72\\x67\\x42\\x22\\x77\\x27\\xbf\\xaf\\xca\\xd5\\xff\\x18\\xd8\\x69\\x6e\\xd0\\x26\\xb7\\xe9\\xbc\\x95\\xc7\\x98\\x6d\\x5c\\xbe\\x8c\\x45\\xfc\\xd7\\x61\\xbe\\x1d\\xbb\\xef\\x8f\\xfa\\xfd\\x11\\x92\\xbd\\x92\\x9f\\xff\\x02\\xae\\x0b\\x5f\\x92\\x1f\\xf4\\xef\\x3f\\xb4\\x21\\xc3\\x41\\x59\\x31\\x3c\\x5d\\x35\\xf5\\x2a\\x34\\xd7\\x11\\x7e\\x72\\x4e\\xfe\\x49\\xcf\\xc3\\x17\\x93\\x7f\\x47\\x2e\\xa6\\xf9\\xf7\\x80\\x11\\x43\\xbb\\xea\\x47\\xbe\\xf1\\xe9\\x06\\x15\\xd4\\x4b\\x62\\x11\\x4f\\xdc\\x38\\x3a\\xff\\x24\\xde\\xe4\\x89\\xef\\xf5\\x5d\\xff\\xfb\\x20\\x05\\xc9\\x89\\x3b\\xb6\\x7b\\x05\\xc6\\xea\\x58\\xc7\\xa9\\x27\\x8a\\x0a\\x28\\x20\\x4a\\x29\\x87\\xa4\\xcd\\x71\\x56\\x32\\x49\\xf8\\x52\\x79\\xa8\\x95\\x68\\x5c\\xbe\\x4d\\x55\\x08\\xab\\x94\\x52\\x3a\\x4e\\xc7\\x9e\\xb7\\x1c\\xa7\\x81\\xf6\\xa0\\x4e\\xf1\\xf2\\x1f\\x57\\xdf\\x7d\\xab\\xec\\x11\\x50\\x8a\\x83\\xd4\\x39\\x2a\\x36\\x3f\\x38\\xe0\\xaa\\x3c\\x9a\\xcc\\x49\\xaf\\xb5\\x16\\xbb\\x72\\x95\\xdb\\x47\\x8b\\x66\\x5d\\xb0\\xf5\\x4b\\xc4\\x70\\x5d\\xff\\xe2\\xdc\\x35\\x24\\xe9\\x7e\\xd3\\xd9\\x6f\\x3f\\x4c\\xd5\\x7e\\x34\\x7d\\xd0\\x5b\\xe4\\x65\\xff\\x13\\x7c\\xf8\\x41\\x73\\x4e\\x3a\\xf8\\xe2\\xaf\\x8f\\xd5\\xfa\\x4b\\xbf\\xd6\\x5f\\x4f\\x56\\xfb\\x4b\\xa7\\x5a\\x60\\x46\\x1c\\x75\\x7e\\xb7\\x11\\x4e\\xac\\x51\\x93\\x0e\\xe2\\xaf\\xb4\\xbb\\x24\\xa6\\xb9\\xef\\xe7\\x8e\\x19\\x6a\\x17\\x62\\x94\\xdd\\x48\\x47\\x61\\x93\\xd2\\x1f\\x00\\x71\\xe4\\xca\\x86\\x2b\\x77\\xd4\\xdf\\xa3\\x5f\\xd4\\x1b\\xe2\\xe9\\x49\\x94\\x90\\x51\\x7a\\x00\\x14\\x34\\xee\\x6e\\x5c\\xc9\\xe1\\xc7\\x70\\x1a\\x90\\x0d\\xa1\\x02\\xd2\\xa4\\x2b\\xd6\\xb9\\x0d\\x4b\\xa6\\x20\\x53\\x99\\x5b\\xff\\x8c\\x8c\\xda\\xe9\\x13\\x8c\\xc9\\xbf\\x95\\x2b\\x24\\xa4\\xb0\\x5e\\xfc\\x02\\xb0\\xd0\\x6f\\xd6\\x8d\\xa8\\x99\\xea\\x8b\\x23\\x61\\x8a\\xc6\\x84\\x70\\xa6\\x75\\x78\\x68\\x05\\x5d\\x4a\\xf4\\x84\\x1b\\x1c\\x3c\\xe9\\x27\\xfc\\x37\\xfe\\xf2\\xe9\\x06\\xe5\\x0e\\x62\\xb5\\xf6\\x42\\x76\\xd3\\x23\\x61\\xe6\\x4b\\xb2\\x14\\x4b\\x11\\xb8\\x6f\\xfe\\xdd\\x7b\\xba\\xf8\\xd3\\xce\\x10\\x06\\xb1\\xbd\\xb4\\xd9\\xd0\\xf1\\xc1\\x4e\\xbd\\x91\\x23\\x1f\\x86\\xc7\\xae\\xee\\xfc\\xb8\\x25\\x0d\\x52\\xca\\x36\\x00\\x37\\x46\\x4f\\xae\\x81\\xea\\xf7\\x8a\\x55\\x6c\\x98\\x9c\\x2a\\x07\\x0c\\x53\\x39\\x45\\x42\\x6e\\xf9\\x7b\\x0f\\x8f\\x3d\\xf8\\xc8\\x23\\x05\\xfd\\xc5\\x12\\x1c\\xc2\\x7d\\x1f\\xa2\\x28\\x1f\\x25\\xc4\\x97\\xa5\\x9c\\x1d\\xe0\\x5a\\xd6\\x70\\x8c\\x03\\x9b\\xb8\\x00\\x93\\x42\\x52\\x83\\x86\\x24\\xec\\xb8\\x53\\x12\\xdc\\x74\\xfb\\x0b\\xa3\\xd1\\x84\\x52\\xaa\\xf1\\x36\\x8d\\x17\\x49\\x29\\xb7\\x7e\\x4d\\x92\\xe7\\xf9\\x15\\x8a\\xc9\\xa3\\x5f\\xa9\\x62\\xbd\\x7a\\x29\\xb7\\xb2\\x6f\\xaa\\x70\\x97\\xfb\\x4d\\x31\\x99\\x80\\xc7\\x08\\x92\\x6d\\x51\\x6d\\xb5\\x6a\\x22\\xe5\\xba\\xdf\\x62\\xa2\\x29\\x4a\\x0e\\xba\\x2b\\x62\\x75\\x82\\xce\\xec\\x5f\\x4d\\xf5\\x60\\x34\\xa2\\xc8\\x31\\x26\\xa3\\xc2\\xf7\\x61\\x87\\x82\\xc6\\x04\\xa4\\x0f\\x48\\x62\\x85\\xb6\\x9f\\xc3\\x79\\xda\\xf5\\xb4\\x43\\x09\\x6f\\x61\\x91\\x8b\\x5a\\x00\\x0e\\x88\\xce\\x4e\\x33\\x27\\x07\\xa5\\x8f\\x39\\x2d\\x2a\\xef\\x8b\\x6e\\x1c\\xdc\\x13\\x0a\\xbb\\xc4\\x3c\\x52\\x49\\xa0\\xfa\\xb8\\xa8\\xb7\\x42\\x16\\x68\\x18\\x7d\\x66\\x74\\xcb\\x47\\x19\\x22\\x41\\x74\\x27\\x79\\x7c\\x39\\xb3\\x84\\xc9\\x79\\xee\\xc3\\xfa\\x05\\x5b\\x9a\\x75\\x35\\xe8\\x4c\\x98\\x78\\xb2\\x96\\xc9\\x09\\x06\\x01\\x5d\\xb5\\xee\\x7e\\xad\\xbc\\x88\\xba\\x10\\xa0\\x9e\\x63\\xd2\\x2e\\xae\\xbb\\xa4\\x23\\x63\\xe5\\xd7\\xae\\x9b\\xfe\\x40\\xee\\xd0\\x63\\xb8\\x7c\\x7c\\xeb\\xf5\\x2a\\x51\\xdb\\x7c\\x9d\\xb1\\xb8\\xf8\\xe1\\xd1\\x7a\\x34\\xc0\\x28\\x68\\x27\\x61\\x34\\x28\\xe3\\x73\\x99\\xb5\\x39\\x49\\xbb\\xd2\\x24\\x45\\x0c\\x48\\xdc\\xb1\\xae\\x2a\\x5d\\x01\\xda\\x64\\x52\\xd4\\x75\\xda\\x39\\x02\\xe7\\x24\\x94\\xec\\xd0\\x62\\xc8\\xfc\\x0a\\x09\\xca\\x08\\xd3\\xd4\\x58\\xa7\\xee\\x84\\xbd\\xe8\\x04\\x6f\\xe2\\x1a\\x1b\\xe4\\x61\\x1c\\x11\\xd6\\x81\\x56\\x95\\xc5\\x05\\x20\\x52\\x22\\xfe\\xf1\\x98\\xe8\\x3b\\x00\\xc2\\xd2\\x89\\x23\\xa5\\x9c\\x11\\xb5\\x1c\\x48\\x58\\x41\\x90\\x4a\\xd0\\x3b\\x89\\x96\\x92\\x7f\\x4a\\x9e\\xae\\xa6\\x35\\x5e\\x25\\x63\\xb4\\x0c\\x42\\xf6\\x2a\\x82\\x17\\xab\\x64\\x5c\\xe3\\x73\\x9d\\x54\\xaf\\x9f\\xc6\\xf7\\xbd\\xc9\\x96\\x8c\\x69\\x8d\\x91\\x37\\x66\\x6c\\xec\\x61\\x38\\xd5\\xfd\\x3d\\x7a\\xea\\x24\\x41\\xa6\\xa1\\xf7\\x2e\\xdf\\x7b\\xc4\\x7b\\x9b\\xde\\x6c\\x85\\x47\\xbc\\x2f\\x72\\x21\\xf2\\x9d\\x47\\xbc\\xaf\\xd9\\x46\\x78\\x11\\x29\\x18\\x3d\\x3a\\xd5\\x77\\xd3\\xe5\\x3a\\x9a\\x5a\\x6b\\x1c\\xd7\\x4f\\xac\\x2a\\xf9\\x90\\x5c\\x9e\\xb4\\xf2\\xdd\\x3e\\x2f\\x59\\x02\\x26\\x7f\\x05\\x30\\x5e\\x6f\\xf3\\x5c\\x87\\xd0\\x41\\xff\\x43\\xb5\\x3a\\x18\\x93\\xa9\\x04\\xe5\\x2a\\xa7\\x66\\xb7\\x9c\\x9e\\xd2\\x78\\x38\\xc9\\xaf\\xc7\\x73\\xae\\x98\\x3c\\x46\\x55\\x72\\xb5\\x52\\x3c\\x64\\x90\\xa6\\x0e\\x92\\xbd\\xd7\\xda\\xff\\xa4\\xf3\\xd4\\xf7\\x53\\x06\\xa7\\x3f\\xfb\\xf5\\xd5\\x74\\x0d\\x88\\xc8\\xd3\\x25\\x3c\\xec\\x9c\\x4c\\x4b\\x36\\xe0\\x12\\x47\\x9f\\xcd\\x48\\x49\\x8b\\xe3\\xc8\\xa0\\x67\\xc5\\x74\\x5d\\x15\\xc8\\x0d\\xce\\xee\\xce\\x86\\x26\\x2b\\xa0\\xfe\\xaf\\xa8\\x04\\xa0\\x0c\\x14\\x5b\\x10\\xd5\\x15\\x41\\x81\\x6f\\xab\\xdd\\x35\\x2b\\x42\\x11\\x2d\\x3d\\x2f\\xf0\\xf6\\xf7\\x1e\\x86\\x90\\x89\\x2d\\x97\\xd3\\x2b\\x56\\xd7\\xb2\\xd0\\x88\\xd2\\xcc\\xf7\\xc7\\x15\\xf6\\x7d\\xc1\\x94\\x19\\xaf\\x6d\\x4e\\xf9\\xbe\\xae\\x7d\\x7f\\x1d\\x3e\\x8f\\x64\\x41\\x7c\\xa8\\xce\\xe9\\x33\\x92\\xd1\\xac\\xae\\xe5\\x33\\xb2\\xa6\\xe3\\xaa\\xae\\xe7\\xce\\x06\\xb9\\x52\\x73\\x06\\xbd\\x5d\\x8f\\x33\\x4c\\xd0\\x7c\\x92\\xe3\\xa7\\x68\\x3e\\x41\\xb9\\xec\\xf7\\x79\\x55\\xd7\\xd3\\x4f\\x30\\xbe\\xa0\\x33\\xf0\\x2c\\x9e\\x61\\xb2\\x3e\\xa7\\xf9\\x62\\xfd\\x94\\x3e\\x23\\x47\\x1f\\x6b\\x37\\xc0\\xc6\\x31\\xc8\\x5f\\xd3\\xf1\\xba\\xae\\x65\\xb3\\x33\\x49\\x05\\xc3\\x79\\xb4\\x5c\\x8f\\x91\\xfc\\x1d\\xcf\\xf1\\x53\\x1e\\x3e\\x8b\\x82\\x31\\x07\\x71\\xbe\\xdc\\x84\\xd3\\x8a\\xa7\\x82\\x66\\xa4\\x98\\x96\\x22\\x2e\\x04\\x5d\\x93\\x62\\xca\\x78\\x42\\x53\\x8c\\x49\\x0a\\xc2\\x88\\x8a\\xd1\\x83\\xb3\\x6a\\x19\\xeb\\x79\\x7e\\xf4\\x1c\\xae\\x43\\x39\\xe8\\x19\\xd9\\xb4\\x91\\xdd\\xd6\\x17\\x9b\\xc5\\x7a\\x3c\\xc6\\x48\\x9e\\x27\\xd7\\x91\\x06\\x25\\xe3\\xf8\\xec\\x02\\x10\\x11\\x4b\\x64\\x61\\x47\\x8e\\x25\\x0b\\xd7\\x91\\xc6\\x27\\x85\\x03\\x44\\x75\\x0d\\xcc\\x90\\x7c\\x5b\\xd7\\xa8\\x57\\x09\\x85\\x54\\x6b\\x00\\x9f\\x45\\x1f\\x3e\\x63\\x06\\x96\\x47\\xaa\\x5e\\x54\\xd1\\x98\\xe6\\x46\\x8b\\x14\\xcb\\xf3\\x4c\\x81\\x7b\\x9b\\xa9\\xa4\\xa9\\x75\\x2c\\x21\\xa8\\xa2\\x15\\x44\\xed\\xa8\\x6b\\x94\\xd3\\x78\\x7a\\x9d\\x27\\x0f\\x9d\\xdc\\x23\\x71\\xcf\\xbd\\xad\\xc4\\x98\\x54\\x7a\\x13\\xe4\\x4e\\xff\\x49\\x7e\\x2a\\x6f\\x69\\x8e\\x89\\x9d\\x80\\x0a\\xd2\\x20\\x7b\\xd7\\x59\\xbe\\xfe\\xe0\\x61\\x02\\x4d\\xd3\\x0a\\x63\\x8c\\x03\\x55\\x66\\xe4\\x4c\\x92\\x7a\\x42\\x14\\xc3\\xec\\xcc\\x95\\x12\\x77\\xc9\\xc5\\x5a\\xd3\\x99\\x5d\\x0a\\xa5\\x11\\x92\\x1f\\x42\\x18\\x89\\x75\\xd4\\x9b\\x42\\xf9\\xe6\\x94\\x39\\x71\\xb9\\xcd\\xef\\x06\\xf6\\x60\\xa6\\xe9\\x1b\\x70\\xa8\\xdb\\x34\\x19\\x52\\xb0\\xeb\\x32\\xb8\\x21\\x22\\xbf\\xb9\\xc9\\x86\\x68\\x9f\\x77\\x9d\\xe7\\x19\\x8b\\x5d\\xfd\\xe7\\x52\\x9b\\x7f\\xca\\x86\\x91\\xb6\\x24\\x97\\x0d\\x98\\xeb\\x3e\\xc1\\x8d\\x75\\x2b\\xcb\\x2b\\xf5\\x6b\\x3e\\x34\\xb7\\xea\\xdb\\xc6\\x52\\x95\\x35\\x23\\x1b\\x46\\xf6\\x4c\\x9d\\xcb\\x4d\\x20\\xa4\\x1a\\x42\\x23\\x41\\x8a\\xf9\\x84\\xd1\\xf3\\xae\\xb3\\x50\\xcf\\x57\\xe8\\x3c\\x25\\x5b\\xf9\\xf9\\x93\\xfa\\xfd\\x2e\\x4f\\xaa\\x8c\\x3d\\xa9\\x57\\xe7\\x68\\x19\\xfc\\x16\\xdf\\xc6\\x35\\x5b\\xef\\x62\\x5c\\xae\\x8b\\x74\\x2f\\xce\\xd3\\xc5\\x5a\\x92\\x0e\\x05\\x25\\x06\\xc8\\x5e\\x17\\xf1\\x0d\\x80\\x4b\\x37\\x85\\xe2\\xab\\x13\\x29\\x14\\xd1\\xa6\\xad\\xe2\\xcf\\xb2\\x33\\xe9\\x24\\x3f\\x30\\x14\\x0f\\x93\\x4d\\x3f\\x3d\\xb2\\x49\\x8d\\x44\\xbc\\x36\\x49\\xd2\\x51\\x21\\x9d\\xfa\\x47\\x48\\x7c\\xd9\\xcd\\x12\\xb4\\x61\\x98\\x3c\\xa8\\xa0\\x71\\x97\\x59\\xce\\x19\\x5d\\xb3\\xe9\\x5a\\x5e\\x00\\xd9\\x19\\xcd\\x70\\xef\\xce\\x06\\x71\\x35\\x81\\xe6\\x64\\x85\\xae\\x13\\xa4\\x49\\xf0\\xff\\xf9\\xfd\\xc5\\xb9\\xbd\\xf6\\xc8\\xc3\\x94\\xe7\\xd0\\xc0\\xa5\\xfa\\x8c\\x8e\\x46\\x47\\x2d\\xb5\\x75\\xbb\\x1e\\x8a\\xfd\\x06\\x6c\\x12\\x2f\\x7d\\x21\\xeb\\x56\\x97\\xaa\\x4e\\x5b\\x0b\\x40\\xc6\\x0d\\xa3\\x07\\xb1\\x65\\x71\\x12\\x84\\x73\\xe2\\x5d\\x80\\x03\\xed\\xe7\\x1e\\xf1\\x2e\\xce\\xf5\\x65\\x44\\xd6\\x79\\x16\\x84\\xcf\\xec\\xcb\\x8b\\x75\\x9e\\xdd\\x14\\x79\\xb5\\x57\\xc5\\xec\\x9d\\xf3\\x85\\x28\\x3a\\x1f\\x08\\x89\\x45\\x74\\xa5\\x70\\xe9\\x16\\x4d\\x82\\xf0\\x79\\xbf\\xe8\\x85\\x28\\x74\\xf1\\xe2\\xf3\\x81\\x6f\\x7e\\xd5\\xc3\\x0f\\xc2\\x19\\xf1\\x3c\\xe2\\x79\\x91\\x83\\xbc\\x6f\\xdd\\xa4\\xc5\\x56\\x9c\\x72\\x3a\\x43\\xe1\\x71\\x0a\\xbc\\x53\\xb9\\xcc\\x21\\x94\\x0f\\x0e\\xfe\\x5a\\x7e\\xcf\\xe5\\x40\\x2a\\x25\\x53\\x43\\x18\\x91\\x9e\\xc0\\x53\\x39\\xfd\\x2d\\xad\\x05\\x2c\\x03\\xf1\\x3c\\xef\\x66\\xa4\\xed\\x45\\x79\\x73\\xc2\\xd4\\xd8\\x60\\x2a\\x0a\\x37\\xb2\\x90\\x47\\xc4\\xbb\\xc9\\xf2\\xeb\\x38\\x7b\\x75\\x1b\\x67\\x1e\\xb8\\x51\\x2b\\x1a\\x23\\xfa\\xef\\x30\\x6e\\x6e\\xd8\\x14\\xe6\\x98\\xca\\x8b\\x4d\\x9e\\x0b\\x79\\x61\\xd6\\x15\\xae\\x63\\x05\\x3f\\x37\\x60\\xa4\\x11\\x27\\x04\\x2e\\xe0\\x36\\xb1\\xd0\\x55\\xd7\\xe8\\x86\\xc9\\x6b\\xfb\\x99\\x86\\x3a\\x00\\x2c\\x9d\\xe9\\x6b\\x57\\x65\\x22\\xdd\\x67\\x8c\\x7e\\x64\\xae\\x3e\\x52\\x2b\\x6d\\x72\\x7c\\x45\\x0a\\x61\\xed\\x24\\x3e\\xaa\\xfd\\xbf\\x2d\\x57\\x77\\xe3\\xc5\\x79\\xbb\\xba\\xf7\\xa7\\x42\\x52\\x39\\x09\\xfe\\xc5\\x49\\xe4\\xa3\\xc2\\x11\\x25\\x74\\x46\\xb6\\xed\\xdc\\x25\\x17\\xdb\\x45\\xa2\\xdc\\x3c\\x20\\x64\\x55\\x22\\x89\\xdf\\x0c\\xd2\\xd0\\xf4\\x75\\x44\\x39\\xc6\\x66\\x89\\xf6\\x24\\x77\\x62\\x3a\\xe5\\x51\\x90\\xb7\\xaa\\xa1\\x9d\\x71\\x9f\\xc7\\xf8\\x00\\xb6\\xa4\\x9b\\x6e\\xe2\\xb1\\x13\\x58\\xaf\\xa4\\x28\\xd1\\xec\\x57\\x8e\\xeb\\x3a\\x54\\xa0\\x8d\\x8f\\x93\\x03\\x54\\xf4\\x46\\x12\\xca\\xba\\xbe\\x61\\x53\\xb3\\x17\\x48\\xec\\x20\\x81\\x4a\\x72\\x42\\x57\\xd3\\xad\\xd8\\x65\\xdf\\x17\\x4c\\x9b\\x30\\xe7\\x78\\x5c\\x49\\x9e\\x68\\x4d\\xab\\x70\\x66\\xe2\\x3c\\xaf\\x27\\x13\\x1c\\xd3\\xd8\\x41\\x0a\\xed\\x00\\x63\\xd7\\x08\\x9b\\xa0\\x98\\x6e\\x5c\\x73\\x71\\x37\\xb2\\x2b\\xf5\\x3c\\x1d\\x98\\x49\\x9b\\x04\\xea\\x11\\xbe\\x63\\xf7\\x9a\\x3d\\x97\\x04\\xba\\xf7\\x85\\x5c\\x07\\x9b\\x21\\x73\\x1f\\x26\\x3a\\x04\\x47\\x01\\xb1\\xa0\\x5a\\xf3\\xcb\\x9c\\x14\\x18\\xa7\\x36\\xbe\\x94\\x33\\xcd\\x19\\x4d\\x65\\xcd\\x24\\xa6\\xb7\\x0c\\x75\\xa7\\x58\\xf2\\x18\\x8a\\x1e\\x79\\xa0\\x8a\\x7b\\x60\\x28\\xc6\\xf2\\xe4\\xbe\\x76\\xda\\x8c\\xc3\\xb5\\x6c\\x73\\x6b\\x56\\xcb\\x84\\x9a\\xf4\\xb0\\x75\\xdf\\xcd\\xad\\x10\\x6e\\x03\\x8c\\xe2\\xb5\\x24\\x81\\x1f\\xd8\\xc3\\x39\\xb9\\xd3\\xb4\\x74\\x97\\x57\\x25\\xab\\xf7\\x79\\xca\\x05\\x2b\\xea\\xb5\\xf2\\xe6\\xdd\\x31\\x5e\\xd5\\x49\\x11\\xdf\\xd4\\x49\\x91\\xef\\x71\\xbd\\xce\\xd2\\xf5\\x87\\x73\\xf2\\x0e\\xbe\\x09\\xdf\\x4f\\xa3\\xa7\\x58\\x1e\\xef\\xa6\\x68\\x3a\\xc6\\x35\\x76\\xc0\\xfb\\x92\\xb9\\x69\\x02\\xec\\xe3\\x57\\xce\\x63\\x27\\xf3\\xf9\\x15\\xeb\\xfa\\x0a\\x53\\x4a\\x7b\\x16\\x4a\\xfa\\xcd\\xab\\x6e\\xac\\x56\\x47\\x12\\xdd\\x20\\x4c\\x29\\xf2\\x20\\xd2\\xab\\xca\\x4e\\xde\\x56\\xff\\x81\\xb9\\x0a\\x55\\x85\\x51\\x63\\x52\\x76\\x35\\xa7\\x56\\xd7\\x74\\x30\\xda\\xd3\\x63\\x7f\\x5d\\x10\\x81\\x16\\x75\\xcd\\x09\\xb7\\x07\\x6b\\x81\\xa1\\xfa\\x12\\xaa\\x17\\x61\\x19\\x91\\xdc\\xe1\\xc6\\xd2\\x8d\\x76\\x8b\\x29\\x54\\xa4\\x17\\x4a\\xd3\\x25\\x4a\\xc1\\xd6\\xc4\\x56\\x11\\xe8\\x17\\xbe\\x7f\\xac\\xfa\\xe2\\xb2\\x74\\x41\\x0a\\x5b\\x56\\xdf\\x3a\\x3d\\xd0\\xa1\\xc2\\x53\\x9c\\xd2\\x57\\xcc\\xc2\\xd4\\xa8\\xcd\\xa5\\xe2\\x86\\xba\\xcf\\xe1\\x9c\\x92\\x12\\x94\\x0e\\x9e\\x54\\x11\\x9e\\xe6\\x9b\\x0d\\x62\\x3a\\x51\\xdf\\xb1\\x95\\x61\\x83\\xa7\\x37\\x55\\x9a\\xd0\\x18\\x7e\\x20\\x04\\x1e\\xdc\\x5f\\xc1\\xcf\\x78\\x0c\\x29\\x28\\x8e\\xa5\\x2a\\xec\\x96\\x71\\xa1\\x8c\\x84\\x94\\x94\\x27\\x25\\x05\\xc8\\x74\\xdb\\x45\\x7a\\x21\\x67\\x11\\x96\\x27\\x5f\\x22\\x8d\\xfe\\x49\\x4a\\x46\\x73\\x10\\x7d\\xda\\xef\\xe5\\xb3\\x83\\x4d\\x30\\x1e\\x8c\\xe6\\x64\\x0b\\xd9\\x5b\\x8a\\x13\\x9e\\xc3\\x9a\\x58\\x80\\x15\\x0e\\x9c\\x00\\xe7\\x3e\\x9b\\xa6\\xe5\\xbb\\x22\\xbd\\xb9\\x61\\x85\\x76\\xb0\\x4a\\x95\\x6b\\xa6\\x89\\xf6\\x81\\x91\\x69\\x11\\x22\\x13\\xc4\\x59\\x98\\x46\\xca\\x29\\x25\\x61\\x19\\xbb\\x91\\xf8\\x40\\x79\\xc8\\x83\\x14\\xf1\\xfb\\x22\\xdf\\xc7\\x37\\xb1\\x1a\\xab\\x9d\\xff\\x62\\xc0\\x80\\xe8\\x97\\x56\\x84\\x9c\\x2a\\x3d\\x7a\\x6e\\x7a\\x46\\x74\\x3f\\x10\\x26\\xc5\\x88\\x52\\x2b\\x99\\xd1\\xaf\\x71\\x5d\\x8b\\x65\\xe7\\x73\\x48\\x10\\x4e\\x0f\\x0d\\x14\\x77\\x62\\x5f\\xc8\\x1e\\xbd\\xd9\\xed\\x58\\x92\\xc6\\x82\\x75\\xba\\x46\\x18\\x38\\x61\\x31\\x2e\\x5e\\x2a\\x4c\\x8b\\x30\\xd1\\x79\\x7a\\x15\\xce\\x6b\\x83\\x9d\\xa0\\x4e\\x53\\x5a\\xb9\\x6b\\xe6\\x44\\xa8\\xa9\\x43\\x56\\x20\\x5d\\x84\\xb3\\x88\\x5c\\x4d\\xc1\\xb6\\xa1\\xd5\\x4a\\x63\\x52\\xd8\\x38\\xcd\\xc6\\x1b\\x93\\x3c\\xd6\\x3f\\xc9\\xe3\\x3b\\x82\\x43\\x23\\x26\\x4d\\xc1\\x8f\\xb5\\x0b\\x00\\x97\\x0c\\x37\\xfa\\x19\\x3d\\x28\\x16\\x20\\x38\\xf4\\xfc\\xde\\x04\\x61\\x03\\xa1\\x9e\\x14\\x65\\x25\\x7b\\xa2\\x83\\x31\\x9a\\x69\\x06\\xd0\\xf8\\x17\\x12\\x18\\x1f\\xf8\\x54\\x43\\x14\\x9c\\x7a\\x51\\x4e\\x39\\x36\\x4f\\x48\\x4a\\x73\\x1b\\x7b\\x02\\x44\\xce\\xa7\\x7c\\xe4\\x65\\xbf\\x09\\x37\\x9b\\x84\\xf7\\x36\\x89\\x3c\\x9d\\xde\\xaa\\xfe\\x97\\xf2\\x80\\xda\\xde\\x51\\xad\\x6e\\x57\\x64\\x07\\x70\\x07\\x06\\x92\\x75\\xab\\xfb\\xa0\\x0c\\x33\\xcc\\xdd\\xc0\\x26\\x1e\\xe2\\xea\\xae\\xda\\x29\\xd4\\xab\\xc7\\x92\\x91\\x89\\x19\\xbc\\x34\\xaf\\xe4\\x81\\x12\\xe2\\x39\\x98\\x00\\x83\\x8e\\x5d\\x9a\\xce\\x8b\\x8c\\x49\\x46\\x11\\xa3\\x48\\x51\\x17\\x57\\x25\\x2c\\x09\\x7c\\x57\\xb7\\x94\\x4d\\x26\\x38\\xa1\\x37\\x14\\x95\\xf4\\x9d\\xe6\\x06\\x58\\x98\\x45\\x3a\\xc6\\xd0\\x3c\\x22\\x5b\\x8a\\xca\\xf0\\x99\\x4e\\x4b\\xa4\\x03\\xdd\\x4c\\x4d\\xa4\\x1b\\x4c\\x12\\xdf\\x47\\x1b\\xda\\xdf\\x89\\x09\\xec\\x44\\x92\\x50\\x94\\x2e\\x37\\x9d\\xfd\\x18\\x6c\\xa6\\xd7\\x29\\x4f\\x40\\xa5\\x5a\\xd7\\x09\\x39\\xf9\\xed\\x9a\\xb6\\xba\\x14\\x08\\x9b\\x96\\x90\\xbc\\x48\\x6f\\xa0\\x8e\\x1b\\xa5\\x6d\\x2c\\x2c\\x56\\xe1\\x44\\xae\\x59\\xa0\\x56\\x90\\x98\\xb5\\x0f\\x52\\xe2\\x06\\xbd\\x08\\x00\\x12\\x4e\\x44\\xc4\\x30\\x7a\\x54\\xd2\\x62\\xad\\xad\\x8e\\xe2\\x33\\xf5\\x40\\xc1\\x40\\xd0\\x9e\\x56\\x8a\\x5d\\x43\\xfa\\x92\\x86\\x51\\x8b\\x6d\\x2e\\xf3\\x8a\\x0b\\x3a\\x23\\x1b\\xb9\\x2b\\xab\\xbd\\xef\\x8f\\xe6\\x23\\x4a\\xf5\\x9d\\x76\\x23\\x25\\x05\\xd9\\x92\\x58\\xe2\\x89\\x23\\x3b\\x23\\xdf\\x3f\\x7e\\x86\\x12\\x12\\x63\\x4c\\x36\\xf2\\x85\\x9c\\x67\\xf9\\x6b\\x6a\\x5a\\x63\\xb2\\x36\\x10\\x6f\\x20\\xb8\\xfb\\x80\\xaa\\xe9\\xc0\\x98\\xa4\\x6d\\xdc\\xca\\x7d\\xb7\\xbf\\xe3\\x31\\x99\\x91\\x35\\x0e\\x34\\x27\\xb5\\x6e\\xd1\\xb8\\xda\\xb0\\x72\\x90\\xa3\\x19\\x6e\\x06\\xad\\x1a\\xfe\\xda\\xce\\x6d\\x95\\xc4\\xbe\\xaf\\xd1\\x05\\xec\\xe3\\x5b\\x10\\xc6\\xd8\\x0d\\x86\\x0f\\x19\\x45\\x5a\\x19\\xf6\\x57\\x80\\x36\\xdd\\xa0\\x1e\\xdc\\x8a\\xff\\x0a\\x6e\\xf1\\xe1\\x24\\xe8\\xc1\\xe2\\x52\\x54\\x3c\\x0e\\xba\\x90\\x0f\\x84\\x94\\xb4\\x84\\xa4\\x5c\\xbd\\xb4\\x47\\xab\\xd5\\x14\\x7b\\x63\\x03\\x41\\xab\\xd5\\x14\\x2d\\x83\\xe9\\xd3\\xd5\\x6a\\x5a\\x63\\x0f\\x8f\\x3d\\x24\\xaf\\x9e\\x60\\x4f\\x72\\x93\\x83\\x91\\x4a\\xd7\\x10\\xa8\\x94\\x8c\\x52\\xdf\\xbf\\x19\\x51\\xba\\x9e\\x1a\\xd8\\xaf\\x6b\\x70\\x2e\\x90\\x0b\\x0b\\xcf\\xd5\\xca\\x97\\xbe\\x6f\\xb2\\x33\\xae\\xa7\\x16\\x82\\x71\\x5d\\x17\\xbe\\x5f\\x40\\xb9\\xd2\\x66\\x76\\x44\\xde\\xd3\\xa7\\xe0\\x99\\x58\\xd7\\xa3\\xf6\\xb9\\x84\\x6a\\x0b\\x24\\x39\\x99\\x4b\\xe8\\x6a\\xbf\\xe9\\x41\\xcd\\x64\\x42\\x36\\x5a\\xc8\\xe6\\xfb\\xe6\\xca\\x68\\xe9\\xd6\\x18\\x2f\\x62\\xdf\\x1f\\xed\\x5b\\x42\\x25\\x79\\xf1\\xb8\\x48\\xf2\\x3b\\x6e\\x77\\x85\\x79\\x60\\xbe\\xda\\x12\\x07\\x77\\x5e\\xb9\\xf6\\x93\\x88\\x91\\xa4\\x7d\\x69\\x74\\x83\\xb0\\x13\\x1b\\x6b\\x67\\x94\\x9c\\xa5\\xfc\\xac\\xc2\\x66\\x41\\xad\\xc6\\x2d\\x19\\x4b\\xa8\\x00\\x40\\x1d\\xcd\\xf0\\xa2\\x6f\\x52\\x52\\x01\\x4c\\xda\\xd2\\x9e\\x6a\\xe4\\x4c\\x81\\xa4\\x27\\xc1\\xde\\xa0\\xdb\\x61\\xc6\\xc5\\xc8\\x69\\x41\\x29\\xa2\\x0e\\x10\\x7d\\xcd\\x9b\\x92\\x57\\xaa\\x6e\\x6d\\xd2\\x7b\\xc9\\xb5\\x65\\x14\\x39\\x7c\\x83\\x67\\x5a\\xab\\xeb\\x21\\xb2\\x12\\x56\\x2a\\xbc\\x1a\\x40\\xdb\\xfa\\x08\\x64\\xed\\xdb\\x43\\x03\\x32\\x49\\x08\\xd0\\x50\\x11\\x41\\xe7\\x0b\\x71\\xa4\\xf1\\x86\\xa8\\x27\\x65\\x28\\xa2\\xd6\\xb2\\x5a\\xa7\\x50\\xad\\x5a\\x48\\x87\\xb4\\x0f\\x4a\\xcf\\x35\\x5a\\x4b\\x66\\xe4\\xa5\\x9e\\x82\\xba\\x86\\xb5\\xeb\\x3c\\x73\\xdc\\xe3\\x2b\\x38\\x7e\\x9a\\xfe\\x69\\x44\\x54\\xba\\x05\\x48\\xa6\\xe2\\xaf\\xe8\\xa0\\x0b\\x29\\x8d\\x43\\x21\\x8f\\x44\\xbe\\x3f\\xaa\\xa6\\x69\\xe9\\xf0\\x19\\x57\\x22\\xdf\\xef\\x59\\x82\\x30\\x3e\\x54\\xd3\\x75\\x55\\x14\\x8c\\x0b\\xdd\\xb1\\x74\\xca\\x32\\xb6\\x23\\xbc\\xad\\x27\\xa7\\xa9\\x6d\\x2e\\xe4\\x4e\\x85\\x43\\x1c\\x4c\\x5b\\x73\\x35\\x2d\\xec\\x4e\\xd1\\x60\\x99\\x4f\\xdd\\x27\\x6e\\x01\\x73\\x66\\x73\\xf7\\x16\\xaa\\x74\\xb3\\xdf\\x5d\\xff\\x46\\x73\\x52\\x4d\\x25\\x51\\xa2\\x39\\xfc\\xb4\\x56\\x61\\xa8\\xa0\\xe8\\x88\\x53\\xcd\\xed\\x7e\\xd6\\x2c\\xab\\xaa\\xa8\\xae\\x73\\x33\\x12\\xac\\xe9\\xbb\\x1e\\x6e\\x09\\x59\\x2d\\xe4\\xd9\\x00\\x55\\xd3\\x82\\x95\\x55\\x26\\x28\\xc8\\xdd\\xab\\x63\\x76\\xb1\\x3a\\x66\\x78\\xb1\\x3d\\x58\\xae\\xa7\\xfb\\xbc\\x14\\x66\\xf9\\x20\\x8c\\xa4\\x73\\xdf\\x59\\x4e\\x62\\x5a\\x02\\x4b\\x2e\\x35\\xbf\\xc3\\x8a\\x52\\xd2\\x89\\x6e\\x2d\\xba\\xc8\\x02\\x62\\xc4\\xab\\x64\\x22\\x00\\x69\\xbe\\x9f\\xb9\\x76\\x30\\xc8\\x83\\xe3\\xaa\\x9b\\x1d\\x61\\x7e\\x41\\xd9\\x54\\x65\\x60\\xd0\\xb6\\xa8\\xd9\\x88\\xaa\\x78\\x42\\x19\\xcd\\x3a\\x3e\\xe8\\xc0\\xb2\\xea\\x00\\x5c\\x6e\\xb5\\xa6\\xd6\\x51\\x9b\\xd3\\x61\\x24\\x57\\x23\\xb3\\xa9\\xcc\\xb1\\x8e\\x42\\xab\\x42\\x63\\x1c\\x1a\\xa2\\x32\\x19\\x54\\x20\\xd8\\xb2\\xfc\\x6d\\x1c\\xa6\\x72\\x05\\x21\\xc8\\xa9\\xc5\\x87\\x26\\x29\\x6e\\x1c\\xa6\\x11\\x2d\\x3a\\x6c\\x04\\xf8\\x72\\x22\\x15\\x51\\x45\\x1b\\xe7\\xa0\\x0c\\xeb\\x08\\x4c\\xfa\\xb9\\x4e\\x55\\x9b\\x59\\xaa\\x86\\x49\\x0c\\xd9\\x45\\x73\\x9b\\x6c\\x20\\x6f\\x23\\x68\\xea\\x08\\xb2\\x12\\x0a\\x82\\xac\\x5d\\x87\\xbc\\xb1\\x4b\\x9a\\xa9\\xcd\\x5a\\x5d\\x88\\x3f\\xfd\\xca\\x38\\x54\\x56\\x92\\xcd\\x2f\\x81\\x17\\x97\\x70\\xd2\\xe1\\xc7\\xf1\\x61\\xd8\\x98\\xf4\\xe8\\xec\\x40\\x04\\x39\\x30\\x5e\\xed\\x98\\xb1\\x23\\xed\\xdb\\x95\\x82\\x7d\\x27\\x84\\x85\\x71\\x3d\\x59\\xb4\\x91\\x94\\xdc\\x00\\x29\\x8f\\x33\\xa8\\xd4\\x9e\\x8c\\x86\\xde\\x75\\xf4\\x93\\x8f\\x7e\\x7e\\xfc\\x26\\x14\\x51\\xdf\\xae\\xf5\\xd4\\xf8\\xf4\\x99\\xf7\\x4f\\x86\\x74\\x57\\xa4\\xc2\\x5c\\xab\\x13\\x97\\xca\\x08\\xd1\\x90\\x4d\\x3a\\x1c\\x6b\\x24\\xb4\\xe6\\xc1\\xd1\\x92\\x05\\x92\\x50\\xe8\\x99\\x04\\xb3\\x39\\x8d\\x11\\x82\\x43\\x96\\xc7\\x49\\x70\\xe0\\xf9\\x17\\xd5\\xb5\\xb6\\xca\\x25\\x00\\xc2\\xc1\\x01\\x18\\xc8\\x01\\x1b\\x4a\\xd9\\xe1\\xba\\xb6\\x82\\x83\\xbd\\x46\\x52\\xc2\\x84\\xd0\\x14\\x53\\xa8\\xc0\\xf7\\x5f\\x20\\x41\\x8c\\x3e\\xc3\\xf7\\x5f\\x40\\xb4\\x45\\xb5\\x3d\\xe4\\x19\\x8d\\x8c\\xe6\\x0d\\xd1\\x07\\x8e\\xff\\x6f\\x5a\\xc1\\x44\\x8e\\xc6\\x8a\\xd1\\x07\\xac\\x41\\x0d\\x7e\\xf8\\x2f\\x1b\\xd1\\x54\\xd4\\xb6\\x53\\xd7\\xf0\\x3e\\x06\\xca\\x7d\\xcd\\x36\\x79\\xc1\\x2a\\xae\\x26\\xd6\\xc5\\x72\\xdd\\x1e\\x18\\x44\\xcd\\x34\\xb6\\xf3\\x7d\\xd6\\x85\\x21\\x30\\x82\\xed\\x3c\\x99\\xaa\\x7e\\x82\\x3e\\xc4\\x7e\\x87\\x9b\\xa6\\x51\\x6e\\x28\\x96\\x75\\x39\\x32\\xba\\x67\\x43\\x8e\\x21\\xb2\\xc1\\x21\\x7f\\x11\\x65\\xd4\\xa8\\x81\\xe5\\x38\\x73\\xf7\\x08\\x20\\xb6\\x13\\xa5\\x4a\\x15\\x6d\\xc3\\xc2\\xba\\xb0\\x46\\x04\\x38\\x9f\\xea\\xd3\\xe4\\xc0\\x26\\x32\\x61\\x9d\\xc0\\x58\\x5d\\x15\\x53\\x0f\\xd2\\x52\\xd3\\x96\\xef\\x15\\xa5\\x61\\x09\\xb5\\x41\\x2b\\xed\\xa3\\xba\\x6e\\x0d\\xfb\\x8e\\x5e\\x6a\\xd2\\xc5\\xdc\\x79\\x5b\\x5e\\xb2\\xe0\\x95\\x69\\x52\\x91\\x76\\x03\\x06\\xbe\\xff\\x5c\\x51\\x03\\xb8\\x73\\xec\\x8f\\xcd\\x93\\x96\\x02\\x04\\xe6\\x99\\xaa\\xa8\\xcb\\x2a\\xb0\\xee\\xbd\\x2a\\x02\\x81\\x6b\\x59\\x62\\x8b\\x74\\xee\\xb5\\xfe\\x53\\x4d\\x01\\x11\\xea\\xbc\\x08\\x67\\x50\\x63\\xdf\\xa4\\xde\\xa7\\x3b\\x76\\x25\\xe2\\xdd\\x9e\\xaa\\x19\\x35\\xb7\\x75\\xfd\\x32\\x16\\x6c\\xca\\xf3\\x3b\\xa4\\x65\\x45\\xed\\xde\\xa7\\x72\\x0f\\x1c\\xe1\\x50\\x7a\\x70\\x82\\x91\\x05\\xfa\\x35\\x39\\x9e\\x71\\x39\\x55\\x43\\x1c\\x92\\x7a\\xfe\\x08\\xa3\\xa3\\x0a\\x5c\\xa5\\xbb\\x0a\\x86\\x19\\x8c\\xe6\\xa4\\xcb\\x30\\xf4\\xfd\\xa5\\x19\\x3d\\x06\\x8d\\xc5\\x29\\x38\\xb8\\x64\\x44\\xd2\\x70\\xfd\\xda\\xb6\\x02\\x79\\xaa\\x7a\\x6c\\x49\\x43\\x7a\\x5c\\xc9\\x7f\\xd3\\xf0\\xf1\\xb8\\x1e\\x6b\\xfa\\x88\\xfd\\x51\\x6d\\x0f\\xcd\\xd2\\x7f\\xd3\\x89\\x47\\x66\\xf9\\xcf\\x7a\\x73\\x42\\xd6\\xa7\\x94\\xf0\\x47\\xbd\\xb5\\xe1\\x47\\x0e\\x71\\x26\\xfe\\xc9\\x1e\\x24\\xad\\xb9\\x06\\xb2\\x00\\x41\\xcd\\xd6\\x72\\xbb\\x67\\x96\\x40\\x6d\\x63\\x7e\\xc3\\x92\\x77\\x79\\x05\\x21\\xe5\\xe5\\x13\\x51\\x64\\xfa\\xab\\x84\\x89\\x38\\xcd\\xe4\\x15\\x2c\\xc6\\xf7\\xdb\\xb8\\x84\\x8f\\x76\\x4c\\xc4\\xba\\xc8\\x3e\\xbe\\x61\\x3f\\x9b\\x8b\\x5f\\xe4\\x05\\x58\\x64\\xea\\xb7\\xb7\\x29\\xbb\\x93\\xbf\\xde\\x7a\\x1b\\x17\\x9e\\x22\\x88\\x89\\x69\\xb7\\xb8\\xd4\\xd7\\x1f\\x54\\xe1\\x0f\\xec\\xc1\\x3c\\xd1\\x89\\xb9\\xec\\x95\\xea\\x58\\x96\\x32\\x2e\\x7e\\x6e\\x2f\\xa1\\xb9\\x7c\\xb3\\x29\\x99\\x7a\\xaa\\x2e\\xe1\\xa9\\x56\\x71\\xbc\\x49\\x9c\\x1b\\x38\\x84\\xcb\\x0e\\xae\\x0b\\xc6\\xf8\\xcf\\xed\\x25\\x7c\\xa1\\xf0\\x80\\x33\\x0f\\x22\\xd7\\x0a\\x08\\x75\\x63\\x9f\\xdf\\x6d\\xd3\\xa1\\xf3\\x9c\\xe5\\x39\\x17\\xbd\\x90\\xbb\\x50\\xde\\xf7\\xaf\\x4d\\x5c\\x68\\x45\\x94\\x96\\x36\\x44\\x91\\x9e\\x88\\x65\\x7b\\x19\\xb0\\xa9\\x9d\\x0b\\xfb\\xbd\\xeb\\xdb\\x70\\xd7\\xab\\x6b\\xee\\x8b\\xe5\\x3c\\x78\\xe6\\x8b\\xe5\\xf3\\xe0\\x63\\x5f\\x2c\\x9f\\x05\\xb3\\x40\\x7f\\xa8\\xa0\\xc1\\x08\\x56\\x25\\xa0\\xb4\\xd1\\xb8\\x54\\xc6\\x3c\\xa5\\x4e\\x49\\xb9\\x47\\xae\\xb3\\xaa\\xd0\\xb7\\x79\\x25\\xbc\\xa6\\xe7\\x78\\xdc\\x3f\\x85\\xb0\\x88\\xf6\\x99\\x0b\\xcb\\xb6\\xbc\\x30\\xc6\\x95\\xe4\\xea\\x14\\x8b\\x70\\x5c\\x56\\x11\\xfa\\x8e\\xcc\\x44\\xb8\\xd1\\xc3\\x40\\x7b\\x25\\x31\\x47\\x11\\x78\\x70\\x9d\\xdf\\xb2\\xc2\\x23\\x70\\x99\\xb1\\xf8\\x96\\x99\\xc7\\x95\\xf0\\xcc\\xa2\\xeb\\xe2\\xfa\\x4e\\x7d\\xa0\\x6f\\xf4\\x27\\xe6\\x55\\x7f\\xc4\\xe9\\xf0\\x88\\x3b\\xdd\\x4b\\x89\\x11\\xe9\\x04\\xa9\\x66\\x93\\x07\\x53\\x8c\\xf7\\xe8\\x04\\x28\\xc3\\xed\\xe1\\xcf\\x0d\\xde\\xca\\x29\\xd5\\x2c\\x53\\x3f\\x88\\x1f\\x87\\xec\\x10\\x6a\\xc5\\x69\\x61\\x0f\\x80\\x44\\xd0\\xc2\\x8a\\xed\\x06\\xb5\\x39\\x44\\x7f\\x93\\x62\\x22\\x9a\\x23\\x83\\xe1\\x4e\\xfa\\x3b\\x63\\xfc\\xa7\\x3b\\xf4\\xc1\\x2e\\xa2\\x7a\\xde\\x90\\x9c\\x1f\\x8b\\xf0\\x4e\\x15\\x27\\x73\\xf9\\xc1\\x66\\x73\\xca\\x27\\x0c\\xcc\\xd8\\x8f\\x51\\xbd\\x7c\\x62\\xa7\\xc6\\xb0\\x22\\x9d\\xf9\\x22\\x57\\x88\\xf5\\xe4\\x0d\\x4a\\xa3\\x55\\xb4\\xe7\\xeb\\x65\\x3b\\x43\\x63\\x6f\\xea\\x8d\\x9d\\x57\\x81\\x33\\x79\\x85\\x3d\\x94\\x11\\x3b\\x8b\\x0a\\xaf\\x0e\\xea\\x0d\\x75\\xee\\x9d\\xf4\\x2c\\xe5\\x67\\x0c\\x2b\\x54\\xbf\\xd9\\xc8\\x73\\x19\\x61\\x61\\x3a\\x18\\x42\\x13\\x04\\x03\\xc2\\xf7\\xdb\\x38\\x12\\xad\\xe1\\x35\\x64\\xfb\\x10\\x44\\x58\\x35\\x23\\xb0\\x39\\x0a\\x0c\\x5e\\xe9\\x30\\x82\\x27\\xf5\\x6c\\x1d\\xf7\\x01\\xc2\\x95\\x2d\\xb4\\x36\\xa0\\xfa\\x96\\xd1\\xf3\\x0b\\xa5\\x51\\xae\\x2f\\xc0\\x90\\xac\\xbe\\xc8\\x52\\xfe\\xe1\\x3c\\x25\\x2f\\x19\\x3d\\xd7\\xb6\\x3e\\xab\\xf2\\x29\\x5a\\x06\\xe1\\x7b\\x1a\\xd5\\x74\\x55\\x3e\\x35\\x26\\x40\\x53\\x7c\\x9e\\x92\\xdf\\x18\\x3d\\x7f\\xbf\\x2a\\x9f\\x5e\\x8c\\xd0\\x32\\x58\\x85\\x97\\x2f\\x5f\\xbc\\x7b\\xb1\\x0a\\xeb\\xc9\\x04\\xd7\\xf2\\x41\\xb4\\x8a\\xe4\\xf5\\xe7\\xab\\xf2\\xe9\\x13\\xd7\\x29\\xea\\xf7\\xae\\x8e\\x57\\x45\\x51\\x93\\xa4\\x06\\x78\\x7a\\x74\\x1c\\xce\\x4f\\xb8\\x21\\xe0\\x3c\\x51\\xc8\\x72\\x10\\xc8\\xd7\\x84\\x82\\x43\\x1e\\x18\\x7b\\x78\\x38\\x9c\\x45\\x75\\xed\\x84\\x0e\\xfb\\x9a\\x75\\x7c\\x38\\x01\\xc4\\x91\\x42\\xaa\\xa7\\xb2\\x22\\x8e\\xbd\\x73\\x6f\\xac\\x59\\x53\\xa7\\xa6\\xaf\\x9c\\x9a\\xc0\\x97\\xea\\x5c\\xd9\\xd9\\xb6\\x1a\\x76\\x9b\\xb8\\xe7\\x13\\xbc\\x64\\x2e\\x87\\x6b\\xdd\\x64\\x02\\xc3\\x83\\x1f\\xb5\\xea\\xb6\\xf4\\x1d\\x1b\\x94\\x7b\\x2c\\xb4\\x04\\x42\\x74\\x43\\x80\\x77\\x65\\xdf\\xa8\\x34\\xda\\x32\\x6c\\x65\\xde\\x16\\x18\\xad\\x10\\x52\\x1c\\x09\\x21\\x49\\xa9\\x83\\x70\\xce\\x48\\x41\\xcb\\x30\\x8d\\xfa\\x56\\x38\\x1d\\xc5\\x2d\\x49\\x89\\x2c\\x13\\xf2\\x08\\x2f\\x7e\\xe8\\xb6\\x9f\\xd3\\xd6\\x0f\\x0b\\x93\\x98\\xba\\x21\\xcb\\x72\\x4c\\xb4\\xeb\\x0c\\x81\\xbc\\x57\\x76\\xc4\\xdf\\x33\\x64\\x35\\xf2\\x05\\xbd\\x41\\x3a\\xb6\\x99\\xc4\\x04\\x56\\xe0\\x0f\\xc6\\xa9\\xd6\\x4f\\x64\\x4f\\x37\\x93\\x39\\x49\\x28\\x28\\x1c\\xb7\\x74\\x87\\x12\\x10\\xf7\\x6f\\xeb\\x7a\\x7e\\xb1\\x19\\x70\\xb6\\x94\\xa7\\x03\\xd7\\xe4\\xcd\\xf7\\x5f\\x6a\\xea\\x98\\xb4\\x27\\x99\\xde\\x2e\\x72\\x72\\xd1\\xb2\\xdf\\x11\\xc3\\x8b\\xad\\xef\\x83\\x86\\x93\\x26\\x6e\\xc0\\x4e\\x22\\xc0\\x28\\x05\\x61\\x8c\\xc9\\xf7\\x0c\\x69\\x87\\x2e\\xdc\\x40\\x87\\x36\\x60\\x7d\\x8f\\x18\\xbd\\x67\\xa8\\x20\\x3c\\x9c\\x45\\x3d\\x4b\\xd5\\xd1\\x9c\\x70\\x92\\xe3\\x4e\\x90\\x43\\x75\\x8c\\x69\\x0d\\x55\\x5a\\x19\\x37\\xa3\\xf2\\x74\\x50\\xd7\\xb9\\x16\\x2c\\x95\\x14\\xc5\\x3a\\x3a\\xa0\\x92\\x2d\\x5b\\x03\\x91\\xaf\\x99\\xcd\\x1d\\x62\\xcd\\x47\\x2b\\xca\\xc8\\x7a\\x44\\xe9\\x1e\\x94\\x22\\x57\\xca\\x12\\x0f\\x55\\x64\\x34\\x83\\xac\\x5c\\xa5\\x3c\\x89\\x28\\x43\\x99\\x98\\xdc\\xca\\x17\\xb6\\x3a\\x8c\\x8d\\x83\\x0c\\x0f\\xd7\\x11\\xa9\\xc8\\x1a\\x46\\xa7\\x80\\x26\\xa3\\x71\\x18\\xb7\\x01\\x95\\x7b\\x03\\x54\\xbd\\x8b\\xc9\\x57\\x0c\\x13\\x65\\xcb\\x5a\\xea\\xce\\xc4\\xb2\\x2a\\x63\\xa9\\x52\\xb9\\x96\\x2a\\x23\\xeb\\x0c\\x53\\x75\\xed\\xba\\x64\\x0f\\x2d\\xc1\\xcb\\x48\\xa5\\x84\\x93\\x65\\xb1\\xf6\\x7d\\x4f\\x99\\x70\\x7a\\x23\\x90\\x5e\\xb6\\x9b\\xb2\\x9b\\xe7\\xe1\\x6a\\xfa\\x2b\\xbb\\x8d\\xb3\\x1f\\x8b\\x0c\\x64\\xaf\\x3c\\xff\\x06\\xbe\\x92\\xf5\\x9a\\x17\\xaa\\x42\\x72\\xe0\\x39\\x5f\\xb3\\x40\\x96\\xe1\\x6b\\x56\\xd7\\x55\\x0f\\x5b\\xc0\\x63\\x0f\\x37\\x24\\xc3\\xc1\\xb5\\x6c\\xb1\\x35\\x04\\xb2\\x7e\\x9b\\xbf\\x31\\x48\\xfa\\x50\\x91\\xac\\x95\\x8d\\x3a\\x06\\x70\\x6f\\xd9\\x51\\x22\\x3e\\x92\\x52\\xb1\\x74\\x22\\x34\\x32\\x1c\\x30\\x92\\xd3\\xd9\\x42\\xe7\\x06\\x2a\\x54\\xaa\\xbb\\x45\\x3e\\x1e\\x63\\x5e\\xd7\\xf3\\x91\\x1b\\xa6\\x1d\\xd8\\x81\\x8c\\xc5\\x1c\\xb6\\xe3\\x2d\\xb8\\x7f\\x92\\xa2\\x93\\xda\\x17\\x71\\xb0\\xf6\\x2f\\x54\\xda\\x11\\x59\\xc4\\x59\\xe4\\x4e\\xd9\\x8e\\x7d\\x73\\x81\\x3b\\x66\\xc5\\xd6\\x8b\\xd3\\x35\\xc6\\x1a\\x94\\x4b\\x41\\x10\\xe1\\x23\\x76\\xa0\\x93\\x3b\\xd3\\x6e\\xf0\\x9e\\x69\\x28\\xd9\\xd0\\xd4\\xf8\\x81\\x8f\\x50\\xdf\\x96\\x54\\x8d\\xdd\\x75\\x03\\x98\\x77\\x1f\\x28\\x57\\x63\\x95\\xc0\\x01\\x31\\xac\\xd0\\x20\\x98\\x55\\xad\\xb1\\x8e\\x5e\\x8c\\x72\\x79\\xeb\\x6c\\x14\\x9b\\xf8\\x90\\xe6\\x61\\x11\\x11\\x09\\xa2\\x85\\xb1\\x6b\\x24\\x6d\\xb6\\x0d\\x94\\xd1\\xea\\x54\\xc2\\x0d\\xdf\\x37\\x72\\xa5\\x52\\xb3\\xdd\\x95\\x21\\x99\\xb4\\x34\\x57\\x81\\xae\\x4b\\x39\\x29\\x78\\xc6\\x64\\x16\\xee\\x41\\xe4\\xef\\xda\\xc2\\xd2\\xb2\\x73\\x0b\\xf3\\x21\\x20\\x18\\x32\\x56\\xb2\\xe5\\xbc\\xae\\x61\\x18\\x04\\xec\\xf2\\xdc\\x01\\xe6\\xfd\\x81\\x7d\\xc7\\x10\\x8c\\x2c\\x86\\x50\\xde\\xa0\\xd8\\x02\\x6a\\xb3\\xb6\\xcb\\x3b\\xbb\\xd0\\x93\\xe4\\xc0\\x85\\xc5\\x3f\\x0f\\x12\\x33\\x8c\\x36\\xbe\\xdf\\x45\\x36\\x90\\x5d\\xc9\\x02\\xde\\x51\\x32\\x68\\x47\\x91\\xd5\\xd7\\x2c\\x01\\x68\\xb7\\x5a\\x0c\\x4e\\x99\\x85\\x6e\\x30\\xc2\\xe0\\x58\\x07\\x4a\\xe7\\xe1\\x2f\\xad\\xd3\\x37\\x3c\\x32\\xe4\\xad\\x0d\\x00\\x60\\x9e\\xa4\\x61\\x11\\x2d\\x7b\\x0c\\x90\\xe4\\x40\\x83\\xae\\xc6\\x0f\\x8c\\xb4\\x8c\\xc6\\x6f\\xe1\\x36\\xa0\\x39\\xad\\x86\\x87\\x3f\\x38\\x41\\x00\\x90\\x7b\\x6b\\x98\\xb1\\x63\\x56\\x39\\x81\\x34\\x3b\\x43\\x9b\\xe1\\xad\\xe5\\xc3\\x1c\\x77\\xd0\\x47\\x0b\\xe2\\x81\\xb4\\xd0\\xba\\xcc\\x80\\x03\\x6c\\x3f\\xee\\x00\\x5b\\xaa\\x9c\\x26\\xca\\x7e\\x5e\\x1b\\xdd\\x43\\xc2\\x6c\\x7c\\xc4\\x2f\\xce\\xb5\\xee\\xa3\\xbf\\x9f\\x7a\\xcf\\x3e\\xeb\\x3f\\xaa\\x6b\\x25\\xe4\\x73\\xcd\\x20\\x3b\\x1e\\xb1\\x47\\x9a\\xca\\x86\\x28\\xa3\\xc6\\x81\\x23\\xde\\xf7\\xac\\x77\\x2a\\xe9\\x0c\\xef\\x7f\\xef\\xe2\\xef\\x76\\x3e\\x3b\\x06\\x95\\xaa\\x9f\\xfb\\x82\\xfd\\x4f\\xdd\\x31\\xdc\\x58\\xb7\\xa9\\xf9\\xc0\\xb3\\xcf\\xfa\\x8f\\x0c\\x5f\\xd1\\xf6\\x6b\\x21\\xa6\\x29\\x2f\\x59\\x21\\xbe\\x00\\x79\\x32\\x44\\x51\\x73\\xc3\\x18\\xcb\\x8e\\x2a\\x51\\xf3\\x7f\\xdd\\x4f\\x68\\xd9\\x25\\x01\\xbd\\x07\\x47\\x0d\\x2b\\xfb\\xac\\x86\\xc4\\x1b\\x31\\x78\\x10\\xff\\xbf\\xdf\\x5c\\x27\\xf7\\x8c\\x6c\\xfa\\x28\\x1a\\xa9\\x0d\\x61\\x0f\\xaa\\x5d\\x4d\\x0b\\x95\\x18\\x2d\\x14\\x11\\x06\\x95\\x73\\x3f\\x69\\x0d\\xea\\x11\\x43\\x06\\x59\\x32\\xe4\\x39\\xb7\\x63\\xb2\\xdb\\x3d\\x8e\\x0d\\x90\\x2b\\xc7\\x16\\x55\\x4b\\x63\\x7c\\x9f\\xe9\\xc0\\x37\\x94\\x8a\\x25\\x0b\\xb4\\xd0\\x57\\xf2\\x39\\x83\\x4e\\x6e\\xc0\\x66\\x19\\x66\\x11\\x06\\x28\\x09\\xe7\\x5f\\xdc\\xd5\\xad\\x82\\x04\\xce\\x36\\x4a\\x87\\xd8\\xcd\\x83\\xd2\\x09\\x11\\xc0\\x54\\x50\\x09\\xe7\\x94\\x60\\xc3\\xdc\\x58\\x63\\xea\\xc1\\xd0\\x2a\\xcc\\xf7\\x47\\xdf\\x3a\\x69\\xc9\\x46\\x37\\x2c\\xb4\\xc6\\xdb\\xec\\x31\\xe3\\xed\\x08\\x1f\\x18\\xed\\x9b\\x66\\x4b\\xa0\\x2e\\x1e\\x60\\xe5\\xec\\x21\\x02\\x54\\xcb\\x7a\\x30\\x5c\\x2b\\xa5\\x4f\\x2f\\x98\\x50\\x0b\\xe6\\xf4\\x9b\\xca\\x4a\\xe9\\xcc\\xb5\\xf5\\x15\\x1a\\xc2\\x0c\\x62\\x53\\x1b\\x1c\\xb4\\x5e\\xa7\\x31\\x90\\xe6\\xcf\\xba\\xc1\\x62\\x8d\\xab\\x76\\x68\\x03\\x85\\x3c\\x0e\\xe9\\xed\\xc2\\xb8\\x51\\xe9\\x9d\\x88\\xbd\\x4a\\x1e\\x73\\x31\\x1b\\x18\\x19\\xa4\\x92\\x51\\x99\\x3c\\x74\\x5f\\x34\\x4a\\xd2\\x59\\x66\\x1a\\xc2\\x3b\\x11\\xf1\\xd5\\xa8\\xde\\xe5\\x81\\xa7\\xae\\x3c\\x83\\xb6\\xe4\\x23\\x7d\\xe9\\x11\\x77\\x6b\\x05\\x9e\\xc2\\x17\\xe6\\xe9\\x0b\\xd8\\xcd\\x1e\\x6c\\x6a\\xcf\\x4c\\xc0\\x8b\\x2c\\x0b\\x3c\\x67\\x32\\xba\\xa2\\xad\\x58\\x07\\x25\\x67\\x11\\x3d\\x41\\xd2\\x69\\x18\\x91\\x82\\x42\\x58\\xa7\\xd4\\x26\\xc8\\x9b\\xcc\\x81\\xaa\\xe7\\x17\\x34\\x05\\x42\\x2e\\x68\\x0e\\x71\\x45\\x5a\\xe7\\x6f\\xb5\\x21\\x24\\x8b\\x77\\x85\\x0a\\x49\\xf0\\xc3\\x38\\x42\\x02\\x93\\xca\\xc6\\xea\\x14\\x2a\\xed\\x40\\x67\\x6f\\x0e\\x86\\x19\\xff\\xa6\\xef\\x2a\\x6c\\xdc\\x83\\x97\\xa3\\xfd\\x3d\\x56\\x3e\\xc2\\x63\\xe3\\x22\\xfc\\xa6\\x6b\\x24\\x69\\x04\\xb2\\x9d\\xf3\\x8a\\xe5\\xb5\\x52\\x76\\xe7\\xa4\\x18\\x10\\xd3\\x7c\\xcf\\x38\\x2b\\x20\\x5c\\xd2\\x25\\x56\\x1d\\xbc\\xcc\\x77\\xfb\\x4a\\xb0\\xe4\\x4a\\x39\\x77\\xe2\\x86\\xfc\\xc4\\x4e\\x65\\xaf\\x21\\x39\\xd5\\xc6\\x33\\xa9\\x8a\\x56\\x94\\x87\\x69\\x64\\x3c\\x71\\xc3\\x34\\x22\\xed\\x25\\x15\\x61\\x1a\\xb5\\x45\\x0b\\x6a\\xec\\x97\\x30\\x11\\xd8\\x29\\x26\\x6b\\x68\\x73\\xe8\\x93\\xd7\\x9d\\xa9\\xe0\\x4c\\x9b\\x85\\xd5\\x1e\\x86\\xd1\\x3b\\x81\\xe6\\xd8\\x20\\x17\\x6e\\x3a\\xa3\\xab\\x54\\x99\\x75\\xde\\x00\\x7f\\xec\\xfb\\xc8\\x83\\x83\\x55\\x4c\\xb9\\x1c\\xb8\\x51\\x67\\x03\\x43\\x0a\\xf1\\xb3\\xb9\\x44\\xc3\\x75\\x0d\\x0c\\x3b\\x98\\xa5\\x3a\\x2e\\xaf\\x18\\x93\\xd1\\xc3\\x74\\x9f\\xde\\xb3\\xec\\x8b\\xfc\\x1e\\x26\\xab\\x44\\xd8\\xf7\\xbf\\xd1\\xc8\\x26\\xc6\\xbe\\xff\\xda\\x28\\x63\\x55\\x6c\\x91\\x72\\x0a\\xe9\\xfd\\x20\\xf6\\xe2\\x2e\\xe5\\x3f\\xc1\\x4d\\x2e\\x6f\\xe2\\x7b\\x75\\xd3\\x3e\\x77\\x9e\\x9a\\xef\\x68\\x4c\\x64\\x4f\\xef\\x74\\x49\\xf5\\xac\\x70\\xbf\\x49\\x89\\xf3\\x55\\x8e\\x9d\\x00\\x4b\\xf1\\x32\\x1e\\x7b\\x5e\\xe0\\xe4\\x6b\\x7f\\xd2\\x11\\x57\\x1d\\x3a\\xf1\\xa4\\x94\\x92\\xb4\\xcd\\xb4\\x67\\x73\\x66\\x50\\x81\\x4f\\x04\\xe7\\xd5\\xb6\\x65\\xa6\\x60\\xd3\\x34\\x23\\x97\\xd2\\x99\\x56\\x99\\xaa\\x3b\\xc3\\x87\\x4a\\x7b\\x79\\xae\\xcb\\xf2\\x1d\\xbb\\x17\\xd4\\xdb\\xeb\\xbc\\x8c\\x41\\x7c\\x0d\\xd1\\x69\\xd9\\x22\\x63\\x1b\\x11\\x4c\\xe6\\xf2\\xbf\\xfd\\xfd\\x02\\xc6\\x1b\\x7c\\x3a\\xdb\\xdf\\x2f\\x76\\x71\\x71\\x93\\xf2\\x89\\xc8\\xf7\\x81\\x7c\\xb3\\x8f\\x93\\x24\\xe5\\x37\\xc1\\x6c\\x71\\x9d\\x17\\x09\\x2b\\x82\\x99\\x47\\xb2\\x93\\xd5\\x9b\\xf4\\x9b\\x0b\\xed\\x5f\\x1a\\x80\\x4f\\xeb\\xe2\\x3a\\xbf\\x9f\\x94\\xe9\\x1f\\xb2\\x1e\\x55\\xcb\\xe4\\x3a\\xbf\\x5f\\xe4\\xb7\\xac\\xd8\\x64\\xf9\\x5d\\x50\\x42\\x90\\x3c\\xdd\\x72\\x10\\x57\\x22\\x37\\x8d\\xb9\\x3d\\x70\\xfb\\xf9\\xf7\\x05\\xf4\\xef\\xef\\x12\\x2f\\x75\\x38\\xb4\\xaa\\xcb\\xb0\\x65\\x5a\\x2c\\x44\\x2f\\x8f\\x77\\x5f\\x86\\x17\\x9c\\x7a\\xf3\\xbf\\x6b\\x63\\x9c\\x7c\\x4f\\x4a\\x3a\\x7f\\x26\\x09\\x21\\xc4\\xd7\\x97\\x7d\\xf9\\x9a\\x6d\\x04\\xb6\\xc3\\x2d\\xd2\\x9b\\xad\\xa0\\xde\\xa7\\xb3\\xbf\\x7b\\x24\\xa7\\xcf\\x3f\\xd5\\x45\\xe1\\xb1\\x3c\\x3f\\xd9\\x27\\xd0\\xcb\\xf6\\x3b\\x33\\x3b\\xd4\\x33\\xb3\\xef\\x91\\xd4\\x34\\x95\\x4d\\x95\\x76\\x09\\xe0\\xea\\xfc\\x39\\x96\\x03\\x72\\xcf\\xd1\\x15\\xd6\\xd1\\xfa\\x1c\\xe1\\x97\\x70\\xe8\\xbf\\xca\\x1d\\x9c\\x57\\x3c\\x41\\x10\\x65\\xe9\\x75\\x96\\xc7\\x90\\x2e\\xa7\\x39\\xf2\\xd9\\x3e\\x76\\x26\\x05\\x97\\x2b\\x92\\x9d\\x78\\xb1\\xc8\\xac\\x03\\xb7\\x19\\xca\\x75\\xbc\\xfe\\x70\\x03\\xad\\x5d\\x66\\xe9\\x9e\\x7a\\x3a\\x71\\x85\\x5c\\x4e\\x09\\x16\\x5d\\x47\\xcd\\xe1\\x4f\\x3c\\xf2\\x00\\xa4\\xad\\x80\\xb3\\x39\\x2c\\x45\\xb7\\x1e\\x30\\x99\\x1a\\xfa\\xb6\\x8d\\x62\\xf3\\x40\\x0e\\xd7\\xf9\\xfd\\x15\\x40\\xd4\\x5b\\x96\\xa5\\x27\\x02\\xcc\\x33\\x84\\x49\\xd1\\x90\\x2e\\x1e\\x39\\x51\\x2e\\xd7\\xe5\\x4c\\x06\\xd3\\x13\\xc5\\xb8\\x64\\x05\\x54\\x83\\xdf\\x58\\x10\\x39\\x51\\xb6\\x6c\\x88\\x82\\x6c\\xd5\\xd7\\x53\\x3d\\x4c\\xdb\\x2a\\xdf\\x15\\x2f\\xd3\\x1d\\xe3\\x65\\x9a\\xf3\\xf2\\x48\\x05\\xac\\xb4\\x1f\\x5d\\x2d\\x60\\x0c\\x12\\xbe\\xa3\\xe5\\xd3\\xa2\\x71\\x22\\x06\\x5e\\x15\\x1e\\x26\\xfc\\x14\\x28\\xb0\\xff\\x12\\x71\\x78\\x10\\xbb\\x59\\x7e\\xa1\\x72\\xac\\x52\\x0f\\x1e\\xf2\\xde\\xc3\\xcf\\xe4\\xc3\\xde\\x4e\\xed\\x1d\\xad\\x44\\xf7\\x96\\xcb\\x0d\\x35\\xb0\\x69\\x05\\x26\\x31\\x7d\\x7e\\x01\\xa0\\xfe\\x86\\x0b\\x54\\xe8\\x36\\x8e\\xf6\\x0d\\xc3\\x98\\xc4\\x4d\\x83\\x71\\x83\\x14\\x0e\\xf8\\x95\\xd1\\xd0\\xfb\\x89\\x5d\\x7f\\x48\\x85\\x47\\xbc\\x6f\\xf2\\x3f\\x3c\\xe2\\xed\\x4a\\x2f\\x22\\x7f\\x0c\\x4c\\x20\\xcc\\x86\\x1a\\x04\\xf9\\xb1\\x1b\\x16\\xe1\\x67\\xe6\\xa4\\xd6\\x92\\x13\\x25\\x49\\x5b\\x19\\xb2\\xa8\\xae\\x7f\\x64\\x21\\xeb\\xc4\\x49\\x64\\x92\\x1a\\xff\\xc1\\x96\\x2c\\x80\\x57\\x43\\xbc\\x04\\xe4\\x16\\x76\\x83\\x49\\x8e\\x59\\xeb\\xf9\\xc2\\xe9\\xaf\\xec\\x38\\x58\\x9e\\x0a\\x53\\xfe\\x2b\\x0b\\x79\\x34\\x16\\x18\\x5a\\xb0\\x86\\x6a\\x0d\\x50\\x53\\xa6\\xa3\\x4b\\x82\\xa7\\x1d\\xcf\\x39\\xab\\x01\\x22\\xd0\\x72\\x34\\x59\\x87\\x2c\\x8e\\xf0\\x74\\x8c\\xcf\\xc9\\x97\\xf2\\xf5\\x64\\x72\\x4e\\x7e\\x61\\xf4\\x60\\x17\\xda\\x41\\x52\\xb7\\x69\\x99\\x5e\\xa7\\x59\\x2a\\x1e\\x02\\x6f\\x9b\\x26\\x09\\xe3\\x1e\\x31\\x88\\x5d\\x47\\x2b\\x68\\xc8\\x0f\\x8c\\x1e\\x32\\x26\\x04\\x2b\\xae\\xf6\\xf1\\x5a\\x22\\x6a\\x6f\\xe6\\x91\\x4d\\xce\\xc5\\x4f\\xb0\\x32\\x81\\xf7\\xf1\\x6c\\xe6\\x39\\x13\\xf8\\x0f\\xd6\\xcb\\x33\\x69\\xec\\xe4\\x2d\\xef\\x56\\x2c\\x01\\xab\\xed\\xe2\\x7b\\x34\\x23\\x45\\xf8\\x2c\\x9a\\x20\\x5e\\xd7\\x33\\x8c\\xc7\\xa8\\x80\\x30\\x1f\\x10\\xd3\\x23\\x10\\x2d\\x46\\xfc\\xe7\\x90\\x93\\x1e\\xf5\\x54\\xc6\\x5f\\x88\\xd7\\x38\\x0f\\x66\\x44\\x45\\x41\\x9d\\xa9\\x24\\x80\\x94\\xa2\\x62\\xe9\\x29\\x3a\\xe3\\x05\\x06\\x03\\x79\\x56\\xb6\\x3f\\x03\\x7e\\x6a\\x11\\x5f\\x7c\\xbc\\x88\\xc7\\xf4\\x19\\xf6\\x14\\x49\\x30\\x01\\x2b\\xaa\\xb1\\x8d\\x79\\xc2\\xc7\\x9c\\x85\\x31\\xc4\\x46\\x4d\\x31\\x26\\xc5\\x12\\xd9\\xda\\x4c\\xe1\\x49\\x1b\\x20\\x45\\x93\\x33\\xaf\\xfb\\x91\\xa9\\x7d\\x74\\xfc\\x81\\xee\\xa2\\x2a\\x3f\\xf6\\x7e\\x52\\x59\\x8c\\xd5\\x77\\x10\\x02\\xfe\\xf1\\xba\\xdb\\xa7\\x10\\x0b\\xd2\\x2d\\xfe\\x48\\xcd\\x41\\xf9\\xd7\\xca\\x99\\x35\\x1b\\x15\\xbe\\x3f\\xbb\\x00\\x0f\\xc1\\x6a\\x4c\\x9d\\xe5\\x83\\xcb\\x35\\x4b\\x33\\xc4\\x42\\x4f\\x91\\x3a\\x6f\\x2c\\x8e\\xa1\\x5e\\x58\\xa8\\x8f\\x26\\xf9\\xa4\\x9a\\x94\\x93\\xe9\\x27\\x18\\xcb\\x55\\x27\\x55\\xbb\\xce\\xff\\xee\\xc1\\x0e\\x30\\x9b\\x24\\xa5\\x68\\xf4\\x30\\x3d\\xa2\\x08\\x48\\x72\\x99\\xd8\\xf7\\xbd\\x96\\xe7\\xe8\\x84\\xaa\\xb1\\x1f\\x78\\x64\\x34\\x27\\x05\\x26\\x39\\x4d\\x49\\x4c\\x35\\xb3\\x5b\\x60\\x52\\xd2\\xbf\\xd6\\x63\\x09\\x50\\x2d\\x6b\\xda\\xcb\\x28\\x1d\\x2f\\x62\\xea\\x49\\x9e\\xc6\\x33\\xc9\\x0f\\x87\\xfb\\xea\\xfb\\x69\\x5d\\x8f\\x1e\\xa6\\x43\\xb4\\x00\\x61\\xe5\\x1c\\x0f\\xd8\\xbb\\xae\\x55\\x75\\x94\\xd2\\xb8\\xae\\x47\\x0e\\xd5\\x97\\x6c\\xb1\\x97\\xf2\\x2c\\x3d\\x11\\x93\\x47\\x0d\\x13\\xb2\\x0c\\x48\\xc4\\x0a\\xb6\\x2e\\x6f\\xd9\\x5a\\x94\\x08\\xbb\\xc1\\x01\\xff\\xf2\\x7c\\xa1\\x9c\\x96\\x4a\\x65\\x0d\\x8e\\xa1\\x10\\x31\\x05\\xfc\\xcd\\x3a\\x7d\\x92\\x6b\\x38\\x36\\x1b\\xb4\\xae\\x51\\x3a\\xb4\\xeb\\x48\\x4e\\x0a\\x12\\xe3\\xb1\\xdc\\xd9\\xed\\x72\\x9b\\xf0\\x90\\xca\\x9f\\xc7\\x31\\x1f\\x64\\x8e\\xad\\x1a\\xa4\\x00\\x75\\xca\\x39\\xda\\x86\\x75\\x59\\xaa\\x00\\x6b\\x87\\x5c\\xe2\\x26\\xf1\\x10\\x1c\\x8e\\x63\\xbb\\x82\\x70\\x5c\\x9f\\xe4\\x61\\xed\\x3d\\x5d\\xd8\\x0a\\x7a\\x20\\xc4\\x0c\\x5f\\x7a\\x73\\x2f\\xe0\\x60\\x4d\\x69\\x83\\x07\\x05\\x87\\x98\\xa7\\x3b\\x30\\x90\\x7a\\x23\\x58\\x01\\x17\\x60\\x5d\\xae\\x4c\\x92\\xb2\\x6a\\xd7\\xde\\x6e\\xd2\\x2c\\xfb\\x4e\\x77\\x43\\xde\\x66\\xec\\xfe\\xcb\\x22\\xbf\\x33\\xd7\\x57\\xdb\\x22\\xe5\\x1f\\xe0\\xae\\xc5\\x9d\\xa3\\x19\\xb9\\x29\\xd2\\xe4\\x45\\xc1\\x62\\x73\\x7d\\x09\\xb5\\x76\\xef\\x5e\\xf1\\xa4\\xfb\\xe0\\x4a\\xc4\\x85\\xfd\\xfa\\xad\\x6a\\x44\\x5f\\x3a\\x65\\xdf\\xe6\\x77\\xb6\\xa0\\x04\\x9a\\xaf\\x6c\\xa3\\x79\\xdb\\x4f\\xc5\\x88\\xc3\\xc5\\x7e\\x1b\\x2b\\x8b\\xa9\\xbb\\x34\\xc9\\xef\\xe0\\xea\\x8f\\x37\\x90\\xcc\\x50\\x5e\\xe5\\xf9\\x4e\\x99\\x07\\x6b\\x92\\x18\\x1c\\x1a\\x02\\x14\\x74\\xc0\\xb2\\x43\\x99\\x68\\x3c\\xef\\xe9\\x63\\xfe\\xdf\\xde\\xbd\\xe6\\x46\\x9c\\xa0\\x51\\xa4\\x84\\xc8\\xb2\\xa4\\xa2\\x5f\\xda\\xe3\\x1f\\x18\\xf2\\xab\\x73\\x68\\xba\\x41\\x15\\x9c\\xb7\\x7f\\x66\\x10\\x92\\x27\\x56\\xc0\\x0b\\x30\\x00\\x71\\x9e\\x9c\\xdb\\xd2\\x09\\x3f\\xd1\\x6e\\x56\\xdf\\xf7\\x6e\\x98\\xf0\\x52\\xb8\\x6c\\xd5\\x0c\\x29\\x8d\\xb5\\x47\\xa9\\xda\\x42\\xcb\\x34\\xc8\\x42\\x11\\x2d\\x5a\\x91\\x18\\x45\\xb9\\x75\\xbb\\xc6\\xb0\\x8d\\x0c\\x5d\\xe3\\x18\\x72\\xb3\\xcc\\x41\\x21\\x40\\x75\\x2c\\xac\\x54\\x62\\x1b\\x8f\\x03\\x10\\x49\\x86\\x0c\\xc4\\x84\\xdc\\xf7\\xb9\\xc2\\xff\\xe6\\xcd\\x88\\xd2\\xbc\\xae\\xe5\\x98\\xf8\\x98\\xa6\\xb2\\x9a\\xa3\\x28\\x57\\x65\\x1b\\xe5\\x0a\\x1f\\xb3\\xd6\\x75\\x0d\\xc7\\x70\\x49\\x3e\\xc1\\x44\\xc2\\xc6\\xe5\\x6c\\x59\\x6b\\x89\\x51\\x90\\x1c\\x0d\\xf5\\x52\\xbe\\x65\\x45\\x2a\\xb7\\xa3\\x9c\\x88\\xb2\\x37\\x11\\x14\\xf4\\x2d\\xb1\\xf6\\xae\\x86\\xc4\\x1b\\x75\\x8d\\xaa\\x65\\x26\\x9f\\xb4\\xf6\\xea\\x84\\x63\\x98\\x1c\\xca\\x21\\x67\\xc8\\xfa\\x28\\xde\\x71\\x27\\x0c\\x98\\x5e\\x51\\x43\\xfa\\xdb\\x65\\x75\\xd7\\x11\\x3d\\xbe\\x90\\xb8\\xb3\\x6a\\xee\\x62\\xcd\\x20\\x61\\x9d\\xed\\xbe\\x8a\\xfd\\x68\\x11\\x3c\\x84\\x60\\x2a\\x76\\x71\\xa6\\xe3\\x42\\x0a\\x89\\xcc\\x7e\\x60\\x2a\\x42\\x2a\\x64\\x5e\\x55\\xd1\\xa5\\x78\\x5d\\xf3\\x25\\xca\\x5d\\xb4\\x96\\x62\\x02\\x61\\xe9\\x79\\x5d\\xa7\\xe5\\x6b\\x89\\x81\\x18\\xca\\xf1\\x32\\xaf\\xeb\\x59\\x90\\xe2\\x20\\x75\\x44\\x71\\xa1\\xa7\\x58\\x54\\x8f\\x68\\x7e\\xa4\\x93\\xb0\\xad\\xc2\\x07\\x67\\x2c\\x55\\x44\\x8f\\x30\\x94\\x4e\\xdf\\x6f\\xd3\\x08\\xff\\x4b\\x4f\\xd1\\x71\\xc8\\x35\\x13\\x0f\\x6e\\x18\\xb3\\xc3\\xab\\x2f\\xe4\\x8a\\xa7\\xfc\\xa6\\x2d\\x82\\xb0\\x3a\\xaf\\x2e\\x81\\xb6\\x56\\x72\\xf5\\x7e\\x92\\x57\\xbf\\x74\\x02\\x5b\\xea\\xe5\\xb1\\x65\\x1a\\xfc\\x78\\x5c\\x6e\\x45\\x98\\x73\\x3a\\x7a\\x98\\x76\\xce\\x40\\x92\\x92\\xb5\\x1c\\xa6\\x9c\\x76\\x7b\\x3c\\x26\\x31\\x45\\xf9\\x7f\\x43\\xb1\\x53\\x49\\xa1\\xf9\\xf2\\x9f\\xba\\x4f\\x24\\x96\\x7c\\x8b\\x8d\\x1d\\x1c\\x43\\xd4\\x4d\\x54\\x4e\\xe8\\x20\\x0b\\x52\\x1d\\x13\\xf4\\xca\\x61\\x41\\xdc\\xa5\\x0e\\xab\\x08\\x4f\\x74\\x2b\\x86\\x74\\xa9\\xf6\\x81\\x47\\x21\\x25\\x08\\xa0\\x5a\\x36\\x56\\x0e\\x40\\xc5\\x93\\x73\\xd9\\x55\\x30\\xd7\\x57\\x92\\xb8\\x2a\\x02\\xeb\\x2c\\x33\\xac\\x0a\\x63\\xf2\\x0f\\x86\\x66\\x44\\x90\\xd2\\xa8\\x07\\x0d\\x44\\x38\\x82\\x08\\xfa\\x84\\xa1\\x96\\x3d\\x68\\x4f\\x9f\\x64\\x80\\x9c\\x69\\x4e\\xc3\\x19\\x85\\xa2\\x6c\\x6d\\x6d\\x2d\\xb4\\x0c\\x82\\x84\\x3c\\xe5\\x4d\\x00\\x0e\\x0e\\xed\\x37\\xc1\\xac\\x19\\x80\\x89\\xc7\\x2b\\x69\\xb0\\x26\\xea\\x8e\\xb9\\xa5\\x92\\xf3\\x78\\x1e\\x31\\xa2\\x1d\\xcf\\x23\\x5a\\xe0\\xa3\\x99\\x4b\\xa7\\x1d\\xe0\\xe7\\x9d\\x2d\\x92\\x8e\\xf3\\x88\\x1e\\x94\\x56\\x75\\x58\\x71\\x4c\\x67\\x2a\\x59\\xe2\\x40\\x2e\\x45\\xb6\\x64\\xc6\\xe9\\xf6\\xcc\\xc3\\x81\\x3c\\xae\\x89\\x8b\\x8f\\x41\\x19\\xc4\\xc3\\x54\\x32\\xb8\\x22\\x92\\xf5\\xab\\xa8\\x80\\x45\\x28\\x26\\xcf\\xe0\\xd7\\xc9\\x84\\xdf\\x34\\x2e\\xb3\\x9e\\x9a\\x60\\x82\\x6d\\xe7\\x24\\x36\\xa4\\xff\\x80\\x9c\\x17\\x1d\\x35\\x6f\\x1f\\x11\\x9e\\x56\\xe1\\x1c\\x8b\\x81\\x49\\xac\\x8e\\x2d\\xfd\\x98\\xeb\\x6a\\xd4\\x2d\\x1f\\x6c\\xf3\\x3b\\xc7\\x17\\xe9\\x22\\x1e\\x8f\\x71\\x1e\\x8a\\x30\\x8e\\x22\\x0b\\x6b\\x02\\xce\\x05\\x92\\x86\\xd9\\x34\\x2c\\x4d\\x3f\\xde\\x31\\x5f\\xba\\xd1\\x07\\x21\\x89\\xa4\\x09\\x83\\xd8\\x80\\x11\\xe6\\x71\\xcc\\x62\\x50\\x3d\\x20\\x74\\x35\\x7d\\x77\\xc7\\x18\\xa7\\x4c\\xe0\\x53\\xbe\\x04\\x4c\\x10\\x89\\x2d\\x07\\x1c\\xb6\\xe5\\x3a\\x2b\\xc5\\x4c\\xc6\\x76\\xc6\\xeb\\x63\\x5f\\xe4\\x7b\\xca\\x8d\\xc5\\x62\\x99\\xf2\\x1b\\x9a\\x4a\\xec\\xaf\\xae\\xdb\\xb8\\x3f\\xca\\x66\\x12\\x22\\x2d\\x95\\x54\\x18\\x0b\\xf6\\xb8\\x10\\x46\\x8f\\x7a\\x47\\x8d\\x27\\x86\\x31\\x70\\x67\\x3c\\xa1\\x85\\xba\\x84\\xd0\\x88\\x79\\x8f\\xb0\\xf2\\x96\\xb0\\x36\\x64\\x5d\\x15\\xc7\\x36\\xf9\\x8a\\x0b\\xdd\\x6b\\xaa\\x64\\xba\\x6b\\x41\\x85\\x69\\x9c\\xab\\x42\\x69\\x69\\x9d\\xba\\xfb\\x8d\\xed\\x7e\\xfb\\xbe\\x21\\x45\\x75\\x9c\\x72\\x08\\x4c\\x7d\\x1f\\x6f\\xcc\\x9d\\x80\\x69\\x52\\x29\\x56\\x54\\x67\\x53\\xce\\x4b\\x2a\\xb1\\x8d\\x9a\\xb3\\xd0\\x99\\xcb\\xc8\\xa8\\x53\\xfb\\x1f\\x3e\\x65\\x64\\x46\\xe6\\xc3\\xef\\xb4\\x5d\\x80\\xaa\\xd5\\xa8\\x63\\xf3\\x3b\\x8a\\xcc\\xac\\x4e\\xda\\xd9\\xc7\\x4f\\xc5\\xb8\\xbd\\xeb\\xd6\\x57\\x0a\\xb6\\xd7\\xaa\\x38\\xf7\\x51\\x6b\\x28\\xa7\\x5c\\x4c\\x4d\\xfd\\x26\\x87\\xb9\\xef\\x73\\xb9\\xc3\\x96\\xdc\\x46\\x19\\x39\\x35\\xa9\\xf6\\xbd\\xca\\x3d\\xd3\\x60\\x38\\x29\\x38\\x80\\xe9\\x9e\\x22\\x08\\x72\\x2b\\xa1\\x07\\xeb\\x16\\xd6\\xa3\\xc7\\x26\\x6a\\xb8\\x09\\x8b\\x03\\x2c\\xab\\xec\\xa8\\xa3\\xbe\\x37\\x26\\xf8\\xf2\\x71\\xc8\\xd4\\x3a\\x99\\x08\\x3e\\xba\\xb0\\x22\\x04\\xfa\\xdd\\xb2\\x5b\\x34\\x40\\x96\\x36\\xa8\\x29\\x50\\xcf\\x89\\x07\\x71\\x75\\xd5\\xe1\\x6f\\x04\\x39\\x28\\x24\\x42\\xee\\x7b\\x11\\x5e\\x4d\\x37\\xf7\\x30\\x91\\xb6\\xf6\\xa3\\x27\\x88\\xe1\\x60\\xb0\\xe3\\x23\\x07\\x95\\x3d\\xd6\\xef\\x9f\\x99\\xca\\x15\\xb8\\xc7\\xfd\\xbe\\x03\\xff\\x7e\\x17\\x58\\x04\\xd2\\x19\\x00\\xbc\\x1b\\x33\\xd8\\x6e\\x40\\xe8\\x34\\x6f\\xf0\\x2e\\xdf\\x77\\xc0\\x5b\\x3f\\x06\\xa2\\x77\\xe8\\x8f\\xaf\\xd7\\x69\\xb9\\xc7\\xe0\\x41\\xc7\\x66\\x6d\\xa8\\x53\\xc6\\x81\\x05\\x90\\xc8\\x41\\x9e\\x77\\xe2\\x53\\x16\\x68\\xe5\\x9d\\xa4\\x4a\\xc7\\xef\\xa6\\x9f\\x4c\\x14\\x33\\x91\\x97\\x88\\x3d\\x85\\xcb\\xef\\xdf\\xe0\\xf3\\x67\\x8e\\x17\\xa1\\x07\\xdf\\x7a\\xb2\\xa9\\xcd\\x3d\\x3d\\x3a\\xa7\\x12\\xbb\\x18\\xf4\\xa0\\xb2\\x46\\x08\\x41\\xb8\\x20\\x85\\x20\\xa9\\x20\\xb9\\x50\\xe1\\xb4\\x54\\xd0\\xcc\\xba\\xdc\\xe6\\x77\\xf5\\x36\\x4d\\x18\\x7e\\x72\\x4e\\x62\\x41\\xcf\\xdb\\x10\\xcb\\x4f\\x9c\\x70\\x59\\xa5\\x40\\xf8\\x00\\xfe\\x80\\x60\\xe7\\xfd\\x6a\\xaa\\x64\\x75\\xbe\\x7f\\x39\\x2d\\xd8\\xef\\x15\\x2b\\xc5\\x0b\\x73\\x48\\x7d\\x5d\\xc4\\x3b\\xb6\\x3c\\xf1\\x1c\\x95\\x02\\x07\\x9d\\x4c\\x45\\xa5\\xee\\x2f\\x38\\x32\\xdc\\xc6\\x19\\x56\\xb7\\x22\\x5d\\x7f\\x40\\xd8\\x09\\xbf\\x54\\x89\\x96\\x1d\\x38\\x99\\xd3\\xca\\x98\\xa3\\x37\\x98\\x08\\x41\\x5b\\x8f\\xb4\\xb6\\x9a\\x4c\\x74\\xe3\\x5c\\xcf\\x48\\x4a\\x0f\\x8a\\x79\\x0e\\x98\\x52\\x85\\x0a\\x25\\xca\\x5b\\x14\\x17\\x1f\\x2f\\x8a\\x31\\x7d\\x36\\x11\\x38\\x0d\\x0d\\x3d\\x1e\\x23\\x4e\\x39\\x0b\\x8b\\x08\\x47\\x34\\x0d\\x1d\\x69\\x58\\x44\\xdd\\xe4\\xef\\x28\\x9d\\xea\\xf3\\x2d\\x4d\\xb5\\xa6\\x4f\\x12\\xcf\\xb6\\x1f\\x6b\\x31\\x64\\x65\\x89\\x36\\x62\\x2a\\x24\\x79\\x63\\xff\\x7f\\xde\\xbe\\xff\\xb9\\x71\\x1b\\xd9\\xf3\\x5f\\xb1\\x70\\x73\\x2c\\x60\\x04\\xcb\\xf2\\x24\\x75\\xf5\\x8e\\x1a\\x3c\\x56\\x76\\x32\\xb3\\xc9\\x56\\x26\\x93\\x8d\\x9d\\xec\\x6c\\x69\\xb8\\x29\\x5a\\x82\\x6c\\x26\\x14\\xa9\\x05\\x21\\xd9\\x5e\\x53\\xff\\xfb\\x15\\xba\\x01\\x10\\xa0\\xe8\\x49\\xf6\\xbd\\xbb\\xfb\\x61\\xc6\\x22\\x08\\x82\\x20\\xbe\\x34\\x1a\\x8d\\xee\\xcf\\x47\\xe1\\x1e\\x64\\x99\\xb3\\xd9\\xaa\\xa9\\x57\\x85\\x8e\\x6e\\x91\\x97\\x24\\x37\\xaa\\xef\\x9c\\x17\\xa2\\x74\\xeb\\x71\\xf3\\xba\\x70\\x3e\\x6a\\xe8\\x90\\x69\\x7d\\x63\\xb9\\xe6\\xd2\\x9b\\x1c\\x55\\x5f\\x85\\x8d\\xa6\\x0d\\x0f\\x1a\\xa3\\xb0\\xcd\\xb1\\x31\\x03\\xca\\x3a\\x4c\\x04\\x48\\xdf\\x21\\x1a\\xf8\\x0c\\xa9\\x4d\\xc3\\xb6\\x77\\xe0\\x14\\x30\\x2b\\x8e\\x66\\xfb\\x1c\\x1f\\x47\\x16\\x6e\\x6f\\x71\\xb9\\xf0\\x7e\\x33\\x42\\xeb\\xae\\x33\\x1d\\xcb\\x75\\x68\\xcf\\xab\\x50\\x94\\x9b\\x0e\\x9e\\x56\\x7e\\x4d\\x38\\x97\\x8c\\xd7\\xe2\\xf2\\x9c\\xea\\x8b\\x3e\\x11\\x8c\\x77\\x58\\xed\\x0a\\x9b\\xa7\\x1d\\x7a\\x17\\xba\\xf4\\xa5\\xca\\x67\\x6a\\x5f\\xd3\\xba\\x47\\x06\\x0f\\xb8\\x13\\x69\\xc3\\x97\\x15\\xaf\\xb9\\xd9\\x90\\xd5\\xaf\\x2f\\x93\\xa4\\xcc\\x74\\x4a\\xcb\\xae\\x3b\\xcd\\x74\\xc9\\xe7\\x39\\xe3\\xed\\x10\\xe8\\xbc\\xca\\x19\\x9f\\x5c\\xb2\\x23\\xaf\\x44\\xeb\\xe1\\xc6\\x31\\x0c\\xbd\\xe1\\x3b\\xb0\\x56\\x84\\x6e\\xe7\\x66\\xeb\\xb2\\xd3\\x41\\xda\\x64\\xce\\x9f\\xac\\x03\\xe2\\x5b\\x10\\x20\\xa9\\xc9\\x85\\xbf\\x4e\\x94\\x91\\x23\\xd7\\x8c\\xbb\\x50\\x3d\\xbb\\x2f\\x2e\\x65\\x9b\\x4a\\x9f\\xf8\\x01\\xd7\\xbb\\x54\\x73\\xdf\\x98\\xa9\\x6f\\x6e\\xd7\\x7c\\xa9\\xf6\\x2d\\xc9\\xb1\\x95\\xd2\\x65\\xce\\x2d\\xa4\\xa0\\xb9\\x1e\\xa5\\x0d\\xb0\\x2a\\x18\\x6d\\x78\\x65\\x96\\x55\\x8c\\x9a\\xc1\\x9f\\xb3\\xe8\\x0b\\xe0\\xc4\\xc2\\xde\\xc0\\x0f\\xf0\\x6d\\xef\\x7b\\xcb\\x32\\x35\\xf0\\x1a\\x23\\x15\\x47\\x82\\xd3\\x8c\\xaa\\x2d\\xb3\\x41\\xf7\\xa6\\xa0\\xab\\x16\\x61\\xf8\\xfb\\x02\\x7d\\x69\\x27\\xf3\\x85\\x7e\\x5d\\x83\\xbe\\xed\\xbb\\x5e\\x63\\xd7\\x5f\\xf6\\xfe\\xc2\\x19\\xfd\\xe3\\x1d\\xcb\\x65\\xce\\x58\\xda\\x86\\x94\\xa0\\x2e\\xd9\\x2d\\xfb\\x7c\\x25\\x2a\\x58\\x08\\xb0\\x16\\x93\\xcf\\x60\\x45\\x40\\x86\\x1a\\x6d\\x9a\\xe5\\x86\\x96\\x42\\x2f\\x95\\xf8\\x48\\x6b\\x96\\xf3\\x46\\x00\\xa0\\x68\\xac\\x81\\x37\\x68\\xea\\x69\\x96\\x97\\x2e\\x83\\x68\\x96\\xa6\\xa2\\xb5\\xa5\\x44\\x33\\xd2\\x48\\x34\\xdc\\x73\\x11\\xd5\\xf9\\xd0\\x9a\\xa1\\xc0\\x7c\\x81\\xfb\\x19\\xb0\\x60\\x30\\x5f\\x87\\x46\\x14\\xd6\\x7d\\x94\\x36\\xac\\x2f\\x43\\xe5\\xbc\\x61\\x58\\xc9\\xae\\xa3\\xf6\\xa5\\x75\\xce\\xb5\\xf9\\x55\\x5a\\x27\\x5d\\x6d\\x5e\\x5c\\x1e\\xe9\\x6a\\xb4\\xf3\\x99\\x9f\\x81\\x70\\x16\\x12\\x49\\x15\\x33\\x17\\x41\\x38\\x55\\xbc\\xe1\\xee\\x71\\x2f\\xa3\\xb6\\xb4\\x86\\xd0\\x50\\x06\\x1b\\x9f\\x90\\x6a\\xa1\\xc2\\xb5\\xde\\xbe\\x0e\\x6e\\x30\\xc8\\x2a\\xf0\\x09\\x40\\x29\\x02\\xde\\x8f\\xba\\x67\\x22\\xdd\\x16\\x3b\\xba\\xe2\\x2b\\xcd\\x2b\\xc6\\xb7\\xd4\\x55\\x15\\x54\\xc7\\x24\\x09\\x2f\\xb1\\x4a\\x8d\\xc9\\x57\\xf5\\x8c\\xc4\\x36\\x87\\xbb\\xb6\\xc4\\xc4\\x36\\xd5\\xfc\\x76\\xd5\\x71\\x84\\x7e\\x96\\xaa\\xd8\\xa6\\x9a\\xdf\\x5e\\x5e\\xda\\x34\\xbc\\xf2\\x2b\\xdd\\x36\\x04\\xab\\xdb\\x73\\x27\\x33\\x8a\\xba\\xdc\\xa6\\x15\\x47\\x82\\x88\\xf0\\x93\\x8f\\x8c\\xf1\\xea\\x78\\x35\\xf3\\x4b\\x6b\\x1f\\xcf\\xb2\\xd1\\xfc\\xc9\\xad\\x12\\xe9\\x13\\x79\\x49\\xd2\\xe5\\xd8\\x0c\\xc6\\x7d\\x4a\\x3f\\xcd\\x31\\x46\\xde\\x89\\x45\\x49\\x6b\\xab\\x53\\xf1\\xde\\xe2\\xc0\\x61\\x8e\\xe6\\x47\\x6e\\x8b\\x1f\\x48\\x06\\xc0\\xba\\xb0\\x94\\x0e\\xb8\\x3c\\xa5\\x52\\x48\\x8f\\x65\\xb5\\x08\\x10\\xde\\x41\\x5a\\xcb\\xa1\\x98\\xae\\x05\\x8c\\xba\\x70\\x95\\xab\\x73\\x11\\x5f\\x02\\x10\\x50\\x9c\\xe4\\x69\\x54\\x34\\x7a\\xcd\\xda\\x01\\x16\\x7f\\xf6\\x33\\xbe\\xfd\\x7c\\xe3\\x8e\\xef\\x4a\\x38\\x4b\\x75\\x46\\x34\\x73\\xc5\\x77\\x08\\x2d\\xb2\\x36\\x3b\\xe3\\x3b\\x67\\xfd\\xe5\\xb7\\x91\\xf1\\xb8\\x80\\x2d\\xf1\\xc1\\x43\\x01\\x92\\xcd\\x83\\xd1\\xa7\\x08\\x7e\\x2e\\xf8\\x7f\\xd7\\xd8\\x65\\x5d\\x67\\x61\\x36\\x61\\x62\\xc6\\xfc\\x31\\x40\\x80\\xc3\\x66\\xfb\\x1a\\x52\\xd7\\x49\\x42\\x0b\\x7f\\x21\\xe6\\xbc\\x35\\x33\\xd4\\xd3\\xba\\xf0\\xf0\\x22\\x5c\\x62\\xfb\\x67\\xba\\xae\\xa5\\x0c\\x88\\x67\\x5d\\xca\\x74\\xca\\x77\\x23\\x4b\\xf6\\x58\\x5a\\xff\\xd0\\xf9\\x39\\xef\\xf9\\x70\\xa0\\x8e\\xb6\\xcb\\xba\\xae\\x88\\x79\\x66\\x2c\\x77\\xa2\\x13\\x66\\x39\\x6f\\x3c\\xa6\\x1c\\x2c\\xfd\\xce\\xb7\\x08\\x6e\\x99\\x3d\\x30\\x41\\xe5\\x13\\x6c\\x73\\xbc\\x14\\x42\\xd0\\xdb\\x8c\\x18\\x25\\x94\\xa4\\x04\\x1b\\x10\\x9e\\xc3\\xdf\\x13\\x61\\xb6\\xe3\\x93\\x43\\x00\\xb3\\x70\\x30\\x12\\x6d\\xd5\\xd4\\xba\\xac\\xf7\\x72\\x71\\x2b\\x26\\xf3\\xe3\\xda\\xc8\\xa2\\x43\\x92\\x98\\x5b\\x66\\xf3\\xee\\x8c\\x0b\\x8a\\x1d\\xcb\\x0d\\xa5\\x7b\\x31\\xc2\\xa9\\xc6\\x60\\x37\\x12\\xa7\\xae\\x59\\xef\\xbb\\xbf\\x19\\x32\\xa1\\x25\\x09\\xad\\x67\\xce\\xa5\\x48\\x2c\\xef\\xfc\\x6f\\xde\\xff\\xfc\\x18\\xfc\\xfe\\x7b\\xce\\x6d\\xaf\\x57\\x50\\x37\\x07\\x89\\x0f\\xac\\x01\\xfd\\xa8\\xe9\\x8d\\xab\\x3d\\x5e\\x3f\\x5d\\x8d\\xf0\\x5d\\xc0\\x73\\xd9\\x4a\\x54\\x29\\xad\\x10\\xbb\\x1a\\x08\\x30\\x87\\xd4\\x19\\x5d\\x57\\xf1\\xb1\\xc7\\x39\\x3e\\xc4\\x18\\xe3\\x34\\x38\\xc3\\x5b\\x75\\x9d\\xbd\\x3a\\xc7\\x03\\x77\\x93\\x86\\x7b\\xb2\\x89\\xa8\\x46\\x19\\x38\\x36\\x55\\x53\\x00\\x0c\\x09\\x9c\\x85\\xec\\x50\\x24\\x06\\xa3\\xe8\\xae\\x07\\xff\\x3f\\x32\\xdb\\x06\\x15\\xd0\\x49\\xf8\\x3b\\xbc\\x12\\xbe\\xdc\\x55\\x46\\x48\\xba\\x62\\x8c\\xf7\\xcf\\xc5\\x35\\x32\\x02\\xdd\\xb7\\x6a\\x92\\xd0\\xbe\\x89\\x85\\xf7\\x1a\\x18\\x1b\\xcd\\x41\\xbe\\xfe\\x79\\x08\\xce\\xeb\\xfb\\x2b\\xbc\\x73\\x19\\xde\\xf9\\x7b\\x78\\xe7\\x55\\x7e\\x04\\xfe\\x85\\xc9\\x25\\x5f\\x33\\xf3\\xd1\\x87\\xcc\\xbd\\xb9\\xac\\xcf\\x0e\\x49\\x42\\x6f\\xc5\\xc1\\xee\\x8a\\x58\\x7a\\x08\\xf9\\xa9\\x9c\\x54\\xe0\\x4f\\xce\\xb1\\xc1\\x34\\x4a\\x93\\x24\\xd4\\x3d\\x20\\x26\\xb7\\x8c\\xdf\\x26\\x49\\xd0\\xa9\\xa7\\x6d\\xea\\x87\\xe5\\x6d\\xd7\\xd9\\x8e\\xe4\\x21\\x80\\x9b\\x93\\x3d\\x7c\\x1d\\xd0\\x82\\x28\\x6e\\x26\\x06\\xc3\\xba\\xaf\\x34\\xbd\\xcd\\xcc\\x04\\x49\\xe7\\x5c\\xf1\\x1d\\xe3\\x50\\xdc\\xc1\\x7c\\x8c\\x99\\x3d\\x7b\\x6b\\x41\\xb9\\x85\\xf0\\x35\\x59\\xaf\\x7d\\x8a\\xfd\\x2b\\xe6\\x8c\\x1d\\xf3\\x5e\\xca\\x0e\\xd9\\xb4\\xb2\\x78\\xe7\\xe0\\x24\\xb3\\x64\\x69\\x7c\\x03\\x54\\x3e\\x69\\x5d\\x89\\xdb\\x9d\\x94\\xeb\\x71\\xff\\x54\\x21\\x93\\xe4\\x34\\x8e\\x39\\x8b\\xb5\\xe8\\xf4\\xc9\\xad\\xbb\\x69\\xdd\\x75\\x93\\x3a\\x49\\x74\\xd7\\x6d\\xc1\\x57\\x5c\\xf6\\x7a\\xae\\x74\\x9a\\x34\\xde\\xd7\\x49\\x32\\xd9\\x82\\x5b\\xa7\\x0e\\x28\\xcb\\x37\\x0f\\xb3\\x66\\xb3\\xc9\\x94\\xd7\\x89\\xc5\\x3c\\xed\\x4f\\xc9\\xec\\xfb\\xfb\\xbb\\xc0\\x78\\xe2\\x2e\\x4c\\x4b\\xe2\\xbe\\xdb\\x7c\\x4f\\x1b\\x16\\x12\\x24\\x2f\\xfb\\xe4\\x3c\\x1d\\xcf\\xe2\\x55\\x7c\\x77\\x62\\xa7\\x50\\x08\\x27\\x09\\xa0\\x78\\x29\\xbf\\x9e\\xd8\\x5f\\xc0\\x7c\\xc5\\xb8\\x9a\\x35\\xd5\\x5a\\x28\\xaf\\x84\\xf0\\xfe\\x67\\xb8\\x4a\\x6c\\x29\\x64\\x64\\x49\\x02\\x7f\\x7b\\x43\\x98\\x29\\xc1\\xbe\\x67\\xc0\\x31\\x65\\xd3\\xd9\\x91\\xab\\x63\\x6c\\x6d\\xde\\x14\\x6b\\x79\\xdd\\x3c\\x1f\\x54\\x0f\\x5a\\x86\\x75\\xbc\\x2f\\x24\\x03\\xe1\\xe1\\x0f\\xbe\\xf9\\xdc\\x71\\x69\\x98\\xa1\\x66\\xb6\\x94\\xa0\\xcd\\x48\\xea\\xcf\\xd1\\xf5\\x11\\x11\\x72\\xd9\\x91\\xdb\\x7b\\x27\\xe0\\xb9\\xf6\\x90\\x4f\\x9c\\xca\\x76\\xe0\\x69\\x83\\x16\\xb5\\xe7\\x88\\x21\\x1d\\xba\\x33\\xae\\x6e\\x2c\\x0e\\x61\\x38\\xa2\\xcc\\xa3\\x6c\\x61\\x76\\x7e\\x21\\x50\\xe1\\xa6\\xac\\xcb\\xf6\\x8e\\xa0\\x63\\x83\\xd1\\x34\\xe9\\x64\\xce\\xfc\\xd0\\x29\\x66\\x78\\x5f\\x14\\xdc\\x2c\\x55\\x48\\x78\\x08\\xad\\x16\\xf0\\x06\\x16\\xd6\\xa8\\x89\\x4d\\x6b\\xef\\xf3\\x82\\x0d\\xf7\\x3d\\x25\\x97\\xbd\\x7b\\xd1\\x98\\x67\\xb8\\xc9\\xee\\xfc\\x75\\xf1\\x8a\\x6b\\xda\\xf8\\xda\\x9c\\xa0\\x82\\x97\\x10\\x00\\x6d\\x14\\x33\\xb3\\xd8\\x7a\\xbe\\x2d\\x6b\\x17\\xc5\\xea\\x94\\x3d\\x33\\xd8\\x78\\xe8\\x3e\\x36\\xd8\\x64\\x6e\\x43\\x4c\\x26\\x70\\x52\\x1c\\x11\\x72\\x71\\x33\\x8c\\x41\\x99\\x6d\\x23\\x58\\x6b\\x1b\\x1a\\xa8\\x80\\xc5\\xd1\\xfc\\x0f\\x55\\x4e\\x92\\x82\\x2a\\x88\\x92\\xf1\\x40\\x96\\x70\\x34\\xaa\\x46\\x32\\xea\\xde\\x0b\\xdb\\x3d\\x84\\x76\\x9a\\xda\\x83\\x3b\\x9e\\x9f\\x2f\\x58\\x6d\\x1e\\x31\\x7a\\xeb\\xc4\\xe1\\x50\\xf8\\x9a\\xc2\\x2d\\xa8\\x2b\\x6a\\x13\\x14\\x12\\xcc\\xa8\\xc2\\xce\\x6c\\x18\\x97\\x46\\xb4\\xd7\\x0e\\x06\\x54\\xf3\\x4b\\xc6\\x16\\x13\\x99\\x24\\x8d\\xd1\\x26\\xa2\\x09\\x51\\x32\\xc4\\x3c\\x33\\x3d\\xde\\x77\\x5b\\xd1\\xe3\\xc6\\x4f\\xd0\\x69\\x12\\x02\\x1f\\x71\\x76\\x3e\\xdf\\xa4\\x5c\\x87\\x4d\\xc5\\x6b\\xa1\\x97\\x85\\x63\\xca\\xcb\\xb9\\x0a\\x2e\\xb1\\x95\\x73\\x08\\x57\\xb4\\xcd\\xdc\\x88\\x3a\\xab\\xfb\\x0d\\x31\\x34\\x8a\\x1b\\x8a\\x93\\x39\\x8f\\x88\\xeb\\x0a\\xe8\\x5b\\x65\\x26\\x3e\\x36\\x2b\\xfe\\x0d\\x62\\xc6\\x27\\xc0\\xc2\\xe6\\xcd\\x49\\xd2\\xb4\\x69\\xb9\\x94\\xd8\\xa6\\x36\\x5a\\x2c\\x49\\x20\\x05\\x25\\x0f\\x7e\\x26\\x24\\xf4\\x4d\\x69\\x4a\\x29\\x5d\\x33\\x4a\\x68\\x46\\x53\\x2f\\x29\\xe6\\x0b\\xf9\\xba\\x59\\x48\\x38\\x06\\x93\\xb9\\xe9\\x13\\x99\\xdb\\xca\\x46\\x17\\x81\\x4c\\xf2\\x5e\\xe9\\xf6\\xd6\\x91\\x45\\x67\\xde\\x56\\x8b\\xe4\\xa8\\x27\\x72\\xd4\\x20\\xa3\\x93\\xef\\x40\\x40\\x6c\\xea\\xa5\\xca\\x17\\xf6\\xef\\x73\\x94\\xe0\\xd6\\x0e\\xdd\\x75\\x63\\xcc\\x41\\xe5\\xb8\\xeb\\x3c\\xce\\x6a\\x27\\xbd\\x2a\\x4d\\x15\\xb6\\x24\\x32\\xb3\\x06\\x67\\x92\\x6d\\x55\\xae\\xe5\\xd7\\xcd\\x7d\\x9d\\x56\\xda\\xea\\xb6\\x8c\\x43\\xe2\\x4f\\x3b\\x48\\x82\\xfa\\xdb\\xa4\\x6b\\xe4\\x34\\x32\\xc9\\xf6\\x33\\x19\\x37\\xf2\\xf6\\xdb\\xba\\x77\\x34\\xc2\\x32\\x8e\\x90\\xfe\\x61\\xaf\\x83\\x1b\\x50\\x12\\xde\\xb0\\x05\\xf5\\xf7\\x6c\\x71\\xc7\\xe3\\xa0\\xa1\\x4e\\xa3\\x6a\\xa2\\xa6\\x89\\xbe\\x52\\x45\\x9f\\x87\\xa3\\x51\\x2c\\xf3\\xde\\x74\\x7b\\x22\\x6b\\x39\\xda\\x71\\x5c\\x66\\x1c\\xab\\xa1\\x89\\x76\\xa1\\x5f\\xd7\\x21\\x56\\x2b\\x95\\x02\\xc2\\x37\\xa8\\x8d\\xe3\\x98\\x40\\xbf\\xf4\\x13\\xf4\\xfc\\x9c\\x5f\\xb2\\x45\\xed\\xf7\\x24\\xd6\\xe8\\xdd\\xec\\x28\\xd8\\x7e\\xad\\x1d\\x38\\xd8\\x62\\x8b\\xf8\\x04\\x03\\xeb\\xe1\\x74\\x11\\x67\\x33\\x2f\\x14\\xe0\\x75\\x45\\x16\\x69\\x71\\xf9\\x45\\x70\\x3b\\xfc\\xb2\\x1a\\x60\\x50\\xb4\\x99\\x6b\\xad\\xa6\\xcc\\x3d\\x08\\x06\\x89\\x28\\x1b\\x7a\\xd7\\xf3\\x60\\x99\\x17\\x4f\\x6d\\xd5\\xdc\\xa7\\xff\\x6b\\x3e\\xe7\\x9b\\xa2\\xd5\\xe9\\xab\\xf9\\xbc\\x37\\xf0\\x7f\\x39\\x9f\\xdb\\xa5\\x76\\x2d\\x8d\\x32\\xec\\xcb\\x52\\xbc\\x3f\\x43\\x50\\xa0\\x35\\x00\\xc2\\x7b\\xaf\\x5e\\xe4\\x5d\\xa7\\x7a\\x2a\\x45\\x1e\\x48\\x78\\xc9\\xc7\\x0c\\x01\\x91\\x25\\xdd\\x0c\\x83\\x85\\x3e\\xa9\\xfe\\x1b\\x74\\xf8\\x71\\xb9\\x6a\\x0c\\xfc\\x54\\x23\\x8e\\xdf\\x16\\x9d\\x90\\x97\\x23\\xf7\\x10\\xac\\x86\\xfc\\x0e\\x2d\\x15\\x9e\\xd2\\x41\\xd4\\x3f\\x22\\x20\\x0a\\xe2\\x38\\xb4\\x88\\x63\\x87\\xfa\\x50\\x0b\\x70\\x38\\x52\\x1a\\xc9\\x01\\x90\\x17\\x07\\xa1\\xed\\xe5\\x5a\\x94\\xda\\x02\\xe3\\xc8\\x35\\xa7\\x9f\\xa9\\x25\\xc3\\xa7\\x05\\xd1\\xa4\\x7f\\x19\\x92\\x5b\\xf1\\xc7\\x19\\xfc\\xf8\\xd9\\x65\\x10\\xfd\\xdb\\xe0\\x40\\x65\\xa7\\xf9\\x5a\\x0b\\x8b\\xa8\\x5e\\x68\\xad\\xbe\\x81\\x80\\xed\\x45\\xa4\\x1e\\x99\\xf4\\xcf\\x9e\\xc6\\x5f\\xc1\\xa3\\xcf\\x1e\\x77\\xf3\\x1e\\x95\\xe5\\xdf\\xe0\\x07\\xed\\x1f\\x7a\\x8e\\x9e\\xf7\\xa4\\x5e\\xb1\\x27\\x40\\xbf\\xdd\\x35\\x0b\\xf7\\x17\\x13\\xe0\\xe4\\xf8\\x0f\\xfc\\xf3\\xca\\xfc\\x61\\x27\\x38\\xfe\\x22\\xe2\\x79\\xf2\\x70\\x14\\xd9\\x15\\x98\\x44\\xdd\\x11\\x3f\\xb5\\xfc\\x1e\\x11\\x02\\x42\\xd7\\x51\\x23\\x9d\\xa1\\x0d\\xf1\\xd8\\x79\\x10\\xc5\\x09\\x27\\xe6\\x01\\x72\\xbd\\x11\\xcc\\x4e\\x1f\\xc8\\x76\\x8e\\x12\\x99\\xc5\\x64\\xf4\\x20\\xc6\\x45\\x9d\\x41\\x5a\\xd4\\x26\\x40\\x64\\x5f\\xf6\\x9e\\x67\\x65\\xe8\\x82\\xa7\\x44\\xe9\\x3d\\xcf\\x34\\x63\\x99\\x4a\\xe9\\x80\\xbf\\x4c\\xf3\\x7a\\x4a\\x08\\x33\\x9f\\x53\\xf6\\x1e\\x61\\xa5\\xdb\\x2d\\x63\\x11\\x8e\\xbf\\xd8\\x14\\x60\\xf7\\xff\\x30\\x59\\xcb\\x7a\\x0d\\x1f\\x6a\\x6f\\x5a\\x0e\\x79\\xd0\\x6f\\xdd\\xe7\\xa7\\x08\\xf8\\xff\\x34\\xf4\\x7b\\x42\\x87\\xdf\\x70\\x58\\x26\\x89\\x1d\\xac\\x48\\x39\\x0b\\xae\\xbb\\x6e\\x64\\xdb\\xc9\\x2d\\xed\\x88\\xed\\xb9\\x37\\x46\\xf8\\xdc\\x2c\\xcd\\xb2\\xcd\\x2b\\x6a\\x44\\xda\\x7a\\x66\\xf0\\x0d\\x4f\\xce\\x20\\x06\\xd1\\xdb\\xf8\\xca\\x0d\\x2d\\x4f\\xc8\\xe3\\x6d\\x4c\\x81\\x28\\x97\\x6a\\x3a\\xcd\\xd9\\x29\\xd6\\x10\\xae\\x22\\xbb\\x93\\x63\\xd8\\x70\\xf5\\x01\\x95\\x5a\\x67\\x83\\x9e\\xac\\x59\\x3a\\xf8\\xa6\\x1a\\xad\\x94\\x1e\\x45\\xf0\\x74\\xe4\\x20\\x99\\xab\\xad\\xf3\\xc5\\xa7\\xfb\\xe9\\xc5\\x2d\\x1b\\x91\\x8c\\x85\\x58\\x6b\\xeb\\x04\\xe8\\xbb\\x6d\\x01\\x49\\x9f\\x09\\xa5\\x1c\\x0c\\x5d\\xef\\xce\\x03\\x63\\x7c\\xad\\x97\\x4d\\xce\\xe1\\x7f\\x24\\xc8\\x81\\x01\\x53\\xd8\\x52\\xb2\\x06\\x46\\x8a\\xbd\\x5f\\x32\\xae\\x5c\\x2c\\xe9\\x9d\\x3d\\xaf\\x85\\xbe\\xed\\x50\\xb2\\x75\\x0e\\x9b\\xa3\\xb3\\x50\\xd1\\x2f\\x2e\\x4a\\x7e\\x6b\\x33\\x16\\x9d\\xb9\\x63\\x92\\x02\\xaa\\xb6\\x20\\x9c\\x8b\\xca\\x90\\x61\\x20\\x67\\x36\\x22\\xf3\\x8c\\x04\\xa7\\xa4\\x8f\\x3a\\x02\\xa8\\x0a\\x27\\xb5\\x75\\x38\\x09\\x79\\xff\\xaa\\xa2\\x05\\x0c\\x77\\x12\\xb8\\x55\\x6f\\xc3\\x12\\xe2\\x03\\x0d\\xc9\\x32\\x99\\x8e\\x05\\x7a\\xc7\\x15\\x8b\\x89\\x22\\x77\\x11\\x56\\xf3\\xa8\\x30\\xc5\\xf3\\xff\\xcf\\x0b\\xd3\\x18\\xf2\\xf9\\x77\\x84\\x69\\x10\\x13\\xb9\\xc4\\xe2\\xdf\\x95\\x0f\\x70\\xa6\\x25\\xf3\\xa1\\x50\\x3d\\xa9\\xdf\\x7f\\x4d\\xa8\\x9e\\x3d\\x23\\x23\\xcd\\x62\\xe3\\x2a\\x60\\x86\\xa5\\x86\\x6d\\x40\\xe0\\xac\\x93\\x47\\x02\\xf0\\x8f\\x0b\\x38\\x09\\x5e\\xb4\\x7f\\x50\\x98\\x49\\xc0\\x94\\xf6\\x6f\\x4d\\x9f\\x74\\x71\\x83\\xce\\xd9\\xe3\\x1e\\x2c\\x03\\xa1\\x47\\x74\\x71\\x03\\xce\\xc1\\x01\\xbc\\x41\\xe6\\xc3\\xac\\x34\\xbf\\x9c\\xb3\\xf4\\x4e\\x3b\\x78\\x48\\x07\\x65\\xc3\\xba\\xee\\xf6\\x34\\x11\\xa0\\xf6\\x94\\xdc\\x64\\xf3\\xf4\\xfc\\xd2\\xc8\\x2b\\xdb\\x3a\\xe9\\x13\\xd9\\x34\\x8a\\xa4\\xe4\\x4e\\x6f\\xab\\x77\\x8d\\x22\\xdc\\x8e\\xcf\\x14\\xff\\x9a\\x87\\x89\\xe9\\xba\\x48\\x69\\x80\\x45\\x26\\xf0\\x0d\\x71\\xba\\xc4\\x33\\x9f\\x25\\xc3\\xd8\\xfa\\x30\\x1c\\x3b\\x82\\x98\\x08\\xf1\\x25\\x5c\\x89\\xd0\\x5a\\x1c\\xb5\\xc1\\xa1\\xd7\\xc9\\x48\\xd9\\x3a\\x49\\xa8\\x1e\\x3c\\xfc\\x47\\xdf\\x32\\xd8\\x2b\\xd9\\x9e\\x22\\x9c\\x28\\x59\\xac\\x3f\\xd4\\xd5\\x23\\xe1\\x64\\x5b\\x3c\\x7c\\x07\\x13\\xc4\\x34\\x93\\xac\\x2a\\x1b\\x5e\\x65\\xaf\\x7e\\xb0\\xce\\x0d\\x9c\\xa8\\xe6\\xfe\\x6a\\x57\\xd4\\x26\\xbd\\xa9\\xec\\xaf\\x7d\\x2b\\xdf\\x17\\x3b\\xc2\\xc9\\x46\\x15\\x5b\\xf9\\x27\\xeb\\xb3\\xea\\xc2\\x2d\\xde\\xae\\x11\\x2c\\x3c\\xdc\\x8f\\x19\\xf5\\xc4\\x0f\\x62\\xc0\\x67\\x89\\x56\\x7a\\xd8\\x60\\x0e\\x3d\\x1a\\x8b\\xf5\\xfa\\x8d\\xe9\\xb7\\xc0\\xf4\\xe3\\x76\\x14\\x71\\xe0\\x29\\x9c\\x07\\x6f\\x69\\x0f\\x01\\x3d\\x32\\xa5\\x8d\\xe2\\x6f\\x79\\x5b\\x5d\\xb9\\x54\\x47\\xa8\\x69\\x8f\\x76\\x23\\xce\\x2c\\x52\\x1a\\x95\\x62\\x0b\\x47\\x05\\x4e\\x90\\xb8\\xe5\\x0c\\x84\\xc2\\xde\\x32\\xe9\\x95\\xe2\\x51\\x63\\x38\\x21\\x80\\x20\\x06\\xe7\\x05\\xe4\\x8c\\x4c\\x0f\\x9a\\x96\\x6c\\x6a\\x04\\xec\\x53\\x11\\x90\\xe2\\xc9\\x65\\x61\\x1e\\x57\\xbd\\xbf\\xfc\\x19\\x99\\x36\\x90\\x0f\\xd0\\x19\\xd4\\x54\\xe0\\xd5\\xa2\\x34\\x73\\xb1\\x15\\x07\\x4d\\x15\\xb2\\x9e\\xb7\\x23\\xf2\\x97\\xb7\\x1e\\xcc\\x0b\\x31\\x43\\x6c\\xa4\\xe2\\xff\\x8b\\xc6\\x0b\\x8a\\xfe\\x9d\\xf6\\x9b\\x9c\\x48\\xe2\\x68\\x3b\\x69\\xe4\\x82\\xab\\x3f\\x21\\xff\\x9f\\x5a\\x1c\\x2f\\xcf\\x2f\\x5f\\x8f\\x35\\x3d\\x53\\x42\\x79\\xa4\\x34\\x9f\\xcc\\xff\\x1b\\xfd\\x80\\xfb\\xed\\x41\\x3f\\x94\\x4e\\xd1\\xf0\\x11\\x1d\\x25\\x2f\\x02\\x5f\\x62\\xd1\\x74\\x5d\\xbc\\x6a\\x96\\x3e\\x52\\xe8\\xc4\\x34\\xa1\\x93\\xa4\\xc8\\x34\\x9a\\x1a\\xfd\\xb8\\x2e\\xad\\x61\\x22\\xec\\xab\\x92\\xa5\\x5b\\x5a\\xb2\\xec\\xf3\\xbd\\x1b\\x54\\x98\\x96\\xa3\\xbd\\x0b\\x68\\xe0\\xec\\xf8\\x0c\\x65\\x72\\x18\\x49\\x0c\\x3e\\x1a\\x4f\\x76\\xef\\xef\\x0c\\xcd\\xa6\\x83\\x4b\\x66\\xbb\\x45\\x0a\\x85\\x54\\x28\\xf5\\xec\\xae\\x68\\xf1\\xad\\x92\\x65\\x75\\x54\\x71\\xc9\\xd2\\xba\\xff\\x34\\x69\\xd9\\x6f\\xfc\\xba\\x56\\x82\\x3b\\x3f\\xb6\\x0a\\x86\\xb3\\x98\\x61\\xe4\\xc7\\x62\\x92\\x04\\x74\\x71\\xe4\\x97\\x5f\\xfc\\x42\\xf0\\xcb\\x2f\\x84\\x3b\\xac\\xd2\\x36\\xd2\\x71\\x4e\\x92\\x7c\\xf7\\x4a\\x6b\\xe0\\x2d\\x33\\x42\\xd2\\xd0\\x44\\x1c\\x97\\x0b\\xea\\x10\\x43\\x58\\x1d\\xfb\\x59\\xcf\\x10\\x00\\xce\\x17\\x5a\\x98\\x81\\x26\\xcd\\x40\\x5b\\x44\\xa3\\x5d\\xd9\\xd1\\x3e\\x1c\\xe3\\xe7\\x97\\xaf\\xa9\\x1d\\xe7\\x30\\x0d\\x70\\xac\\xfb\\xd1\\xec\\xa7\\xf1\\xc4\\x45\\x2a\\x4c\\x2e\\x9d\\x3a\\xf9\\xa0\\xc5\\xc5\\x27\\x75\\x71\\x1b\\x6f\\x55\\x0f\\x45\\x00\\xfc\\xe3\\x15\\x17\\xc9\\x4b\\xee\\x41\\x7e\\xbc\\xad\\x7b\\x30\\xa1\\x33\\x5a\\x8a\\xad\\x99\\x8a\\xe3\\x83\\x0a\\x3d\\x59\\x4f\\xf0\\xa7\\x92\\xc4\\x9d\\x87\\x6b\\x51\\x66\\x75\\x34\\xca\\xdc\\x38\\x3c\\x14\\x15\\x65\\x2c\\xad\\x59\\xa6\\x05\\x21\\xfe\\x24\\xa6\\x1f\\xf6\\x99\\x9e\\x9a\\x1b\\x43\\x87\\x75\\x00\\xb7\\x44\\xb7\\x0f\\x3d\\x06\\x45\\x66\\x8d\\x7c\\xa6\\xff\\xe4\\x94\\x90\\x23\\x63\\x1c\\xf6\\x67\\x87\\xa2\\x0a\\x3c\\x9f\\x2d\\xb7\\xd0\\x30\\x79\\x1c\\x60\\x0f\\xfc\\x6b\\xac\\xc2\\xa5\\x02\\x85\\x4b\\xf5\\xe3\\x4e\\x73\\x02\\x3b\\x2c\\x08\\x85\\x82\\xa2\\x70\\xc3\\xa5\\xcd\\x20\\x61\\xa9\\xce\\x06\\x75\\x18\\xab\\xc0\\xe7\\xde\\x7e\\x7b\\xfa\\x76\\x33\\xb7\\x1c\\x4d\\x84\\x7d\\xf7\\x98\\xea\\x4d\\xa5\\xb0\\xb6\\x0d\\x96\\x49\\x2f\\xfb\\x1e\\xb4\\x91\\xc8\\x69\\xd8\\x58\\x8e\\x64\\x2f\\x52\\x7c\\x5d\\xed\\xd2\\x27\\xb4\\xdd\\xfc\\x41\\x55\\xd0\\xd6\\x27\\x84\\x1a\\x98\\x80\\xbb\\xf1\\x41\\x53\\x0b\\x10\\x27\\x21\\xb6\\x0b\\x75\\x9a\\x67\\x4a\\xb5\\xf8\\x7d\\x8e\\x00\\xb9\\x05\\x4d\\x3b\\x56\\x97\\x8c\\x54\\x85\\x84\\x73\\x7b\\xd8\\x6c\\x41\\x74\\x5b\\x51\\x80\\x9d\\x20\\x05\\xe2\\x9e\\x22\\x6b\\xa6\\x97\\xa9\\xb7\\x7d\\x63\\xc4\\x43\\xf3\\x7a\\x9e\\xed\\xd3\\x22\\x6b\\xc0\\x19\\x74\\xef\\x7c\\x99\\x28\\xee\\x66\\x3d\\x2b\\x8e\\x51\\x1f\\x15\\xb0\\x18\\x27\\xc9\\xa4\\xf6\\x2c\\x3b\\x49\\x42\\x27\\x75\\xa8\\x9d\\xb9\\x1b\\x5d\\x37\\xf9\\x8a\\x86\\x77\\x38\\x71\\x5c\\xce\\x84\\x39\\x68\\xc1\\x2b\\x5a\\xdb\\x19\\xc0\\x7b\\x27\\xb7\\x85\\xb5\\x57\\x6a\\xbf\\xc4\\xb4\\xa7\\x21\\x52\\x81\\xbb\\x59\\xd4\\x30\\x66\\x46\\xfc\\x26\\xdd\\x24\\x09\\x1d\\x47\\x51\\xe6\\x14\\xe7\\xe7\\x8c\\x82\\xe7\\x68\\x11\\x7c\\x9a\\x88\\x28\\x82\\xfb\\xc1\\x68\\x0b\\x86\\xe1\\xa5\\x18\\x6f\\xc0\\x37\\xa1\\x16\\x93\\x79\\xb4\\xed\\x1d\\x74\\x86\\x38\\xbf\\x64\\xbc\\x39\\x1e\\x23\\xcd\\xd4\\x9a\\xdc\\x7a\\x3b\\xdf\\x40\\x63\\x8c\\xe6\\x5f\\x7e\\x6a\\x25\\x80\\x06\\x3b\\x09\\x5a\\xf1\\x7b\\x57\\x07\\x73\\x19\\x7f\\x07\\x95\\xae\\x75\\xb5\\x19\\x64\\xde\\xb2\\x08\\x1b\\x81\\xf8\\x8d\\x80\\x9b\\xf3\\xac\\x18\\x39\\xc1\\x6b\\xb6\\x03\\x3b\\x23\\x4d\\x4d\\x52\\x6b\\x55\\x39\\x32\\xd8\\x70\\x58\\xb0\\x7a\\x41\\x9a\\xda\\xe1\\xd6\\x97\\xf5\\xd9\\x1b\\x90\\xcb\\x37\\x76\\xf7\\x6e\\x6f\\xc0\\x9f\\xce\\xc1\\xd9\\xdf\\x54\\x7b\\xc5\\x5e\\x5c\\xf0\\xfb\\xb8\\x22\\x63\\x74\\x0f\\x0b\\x3f\\x33\\x2d\\xd6\\x24\\x7f\\x3a\\x25\\xb8\\x19\\x89\\x90\\xec\\xf9\\x0b\\xc5\\xb2\\xee\\xba\\xb7\\x39\\x5f\\x8b\\x83\\x63\\xa8\\xb3\\x70\\xd0\\x16\\x3f\\x3a\\x95\\xfc\\x2e\\xb8\\xe7\\xc1\\xc9\\x21\\x43\\x4f\\x1b\\xd6\\x13\\x0f\\xa6\\x4b\\x20\\x5a\\x6b\\xc4\\x46\\x14\\x02\\x00\\x9c\\xde\\x72\\xb3\\x05\\xae\\x07\\x71\\xb9\\xe1\\xf5\\xe4\\xc6\\xee\\xf9\\xd6\\xd3\\x13\\x66\\x50\\x33\\xd4\\xce\\x2f\\x5f\\xaf\\x7b\\xf5\\x6d\\x06\\xbe\\x28\\x6b\\x41\\xef\\xc4\\x3a\\x78\\x31\\x9b\\xa1\\x07\\x02\\xe3\\x77\\x96\\xfc\\x90\\xf1\\xbd\\x08\\x9e\\x4b\\x51\\xd7\\x36\\x7d\\x35\\x5d\\x73\\x2a\\xc5\\x67\\x28\\x8b\\xd6\\xfc\\xd4\\x17\\x21\\x49\\x24\\x63\\x3d\\x5b\\xaf\\x50\\xd9\\xab\\xf4\\x0b\\x1e\\xb4\\x82\\x08\\x98\\x34\\xb9\\x0c\\x58\\xd5\\x44\\x90\\x29\\xfb\\x2f\\x32\\x28\\xa2\\xc9\\xc8\\x91\\xf0\\xd8\\x23\\x0f\\xee\\x68\\x61\\x10\\x71\\x1f\\xb9\\x5e\\xcc\\xf2\\xec\\xa1\\x01\\x97\\x32\\x4f\\x23\\x61\\xc0\\xc1\\x97\\xe4\\x94\\x60\\xcf\\x72\\x42\\x22\\x5b\\xa2\\x6d\\x7d\\xcf\\x84\\x67\\xaf\\x7b\\x70\\x34\\x2b\\xba\\x26\\x2a\\x49\\x26\\xab\\x99\\x63\\x73\\x4a\\x92\\xc9\\x03\\x00\\xa6\\x22\\x30\\xf4\\x2a\\xa2\\x95\\xec\\xba\\x35\\x77\\xfd\\xdc\\x4e\\xd7\\x66\\x65\\x6c\\x44\\x13\\x48\\x46\\xb6\\x68\\x16\\x83\\x94\\x9d\\xe3\\x0b\\xe7\\x85\\x68\\x16\\x05\\x04\\x0c\\xc7\\x60\\x69\\x5d\\xf7\\x96\\x25\\x89\\xcd\\x57\\x84\\xd0\\x69\\x5d\\x57\\xd8\\xa2\\xfe\\x56\\xd6\\xeb\\xe6\\xbe\\xeb\\xde\\xb0\\x63\\x19\\xd2\\xe9\\xed\\x96\\xa5\\x65\\xd1\\x93\\xcf\\xd1\\xf2\\x6d\\x44\\xe3\\x68\\x09\\x2e\\x5f\\x97\\x59\\x9b\\xae\\x3c\\x37\\xa6\\xf9\\x1e\\xea\\x29\\x0e\\x9b\\xdf\\xe5\\x37\\xc4\\x62\\x72\\xc7\\xe6\\xd4\\x38\\x00\\x74\\xf0\\x33\\xa8\\x6c\\xd3\\x36\\x46\\xdb\\xa6\\x95\\xd8\\x27\\x49\\xb3\\xdc\\xe7\\xfd\\x9d\\x24\\xf9\\x19\\x9d\\x83\\xfd\\x08\\x88\\x1e\\xf1\\xbc\\x43\\x8e\\xd9\\x69\\x48\\x4b\\xd3\\x3b\\x43\\xe3\\xd7\\xac\\x4d\\x4f\\xcb\\x11\\xae\\x1b\\xca\\xba\\x6e\\xe5\\xfd\\x52\\x2c\\x61\\x60\\x9f\\x60\\x5f\\xba\\x9b\\xed\\xf0\\xf0\\x8d\\x75\\xdd\\xe4\\x67\\x5a\\xb3\\xae\\xdb\\x27\\xc9\\x96\\xd6\\xcb\\x35\\x34\\xa8\\x19\\x06\\x49\\x42\\x69\\x21\\x6a\\xfc\\x0c\\x6a\\xfe\\xc2\\xa8\\xec\\xa9\\x57\\xfd\\x1c\\x17\\x6b\\xfe\\x5c\\x0f\\x24\\xc9\\x66\\x8c\\x2e\\xf6\\x5e\\x33\\x6e\\xde\\x05\\x44\\xd2\\xcf\\x3f\\x39\\x46\\x37\\x85\\x0f\\x9f\\xd6\\xc1\\xce\\xa8\\xc2\\xd5\\xb5\\x00\\xa4\\x4e\\xcf\\x0c\\xd8\\x5a\\xae\\x9b\\x71\\xbb\\x5f\\xef\\x94\\x1b\\x48\\x11\\x5e\\xf3\\x27\\x2b\\x43\\x23\\x6a\\xa2\\xf9\\x91\\x2d\\x86\\xfc\\xd5\\x0a\\xb1\\x22\\x35\\x3b\\x41\\xf3\\x1d\\x93\\xe8\\xbf\\x77\\x2e\\x14\\x97\\x6d\\x2a\\xaa\\x1d\\xa6\\xaa\\x4d\\xfc\\xe6\\x84\\xa7\\x3c\\x76\\x18\\x36\\x9b\\x00\\x00\\x78\\xf6\\x0e\\x53\\xa7\\x65\\xd6\\x80\\x22\\x1c\\xae\\x76\\x18\\x49\\xf9\\xef\\x51\\xb6\\x04\\x9e\\x3d\\xf1\\xa1\\xad\\x95\\x4f\\xb6\\xdd\\xa8\\xf2\\xc2\\x8e\\xc7\\x3c\\xa3\\xb8\\x0e\\x46\\xc2\\x4c\\x8d\\x31\\xbe\\x84\\xbc\\x47\\xb1\\x08\\x81\\xb4\\x75\\x74\\x09\\xae\\x1a\\xde\\xab\\x4f\\xb1\\x85\\x36\\xd3\\xe5\\x64\\x24\\xd6\\xbc\\x04\\x07\\x80\\x30\\x2f\\xa7\\x1a\\x20\\x4a\\x2e\\x01\\x3b\\x19\\xe9\\x5f\\xff\\xaf\\xd5\\xe3\\xfc\\x72\\xa1\\xb3\\xe8\\x6d\\x9a\\xa5\\x74\\x9c\\x58\\xad\\xaf\\x9c\\x77\\x1c\\x54\\x0c\\xe2\\xe4\\x40\\x0b\\xb9\\xd6\\xe2\\xcd\\xac\\x6a\\x56\\x18\\x11\\xf2\\x46\\x8b\\x27\\x20\\x97\\x0e\\x02\\xa9\\xf8\\x5b\\xb3\\x81\\xcc\\x2e\\x16\\x57\\x33\\xb0\\xdc\\x7e\\x7c\\xff\\xdd\\xa9\\x93\\x12\\x58\\x7e\\x64\\xd7\\x9d\\xb8\\x22\\x79\\x10\\x29\\x33\\xb2\\x01\\x89\\x55\\x0b\\x98\\x1e\\x6f\\x66\\x5f\\x7f\\x78\\xff\\x83\\x29\\x50\\x31\\x2c\\xf8\\x9d\\x6a\\xb6\\x57\\xf0\\x38\\x28\\x20\\xf2\\x41\\x5f\\x3c\\x6c\\x2b\\xc2\\x7a\\x98\\x55\\x7f\\xc8\\xdf\\x5b\\x60\\x27\\x10\\xe6\\x6a\\x4f\\x7a\\xdb\\x3f\\x3d\\x5e\\x17\\xb7\\x66\\xbb\\x44\\x09\\x14\\xa9\\xa4\\x52\\x8d\\x0a\\xfc\\x98\\xaf\\x66\\x90\\x42\\xc9\\xb7\\xf5\\xa1\\xa8\\xca\\xf5\\xd9\\xc7\\xf7\\xdf\\xa5\\x66\\x2b\\xce\\xb8\\xc6\\xc8\\xb9\\x2b\\xf3\\xb5\\xcb\\x4f\\xf9\\x8b\\x0b\\xfe\\x1b\\xec\\x9c\\xb3\\x4f\\xf5\\xc5\\x2d\\xff\\xca\\x6a\\x6b\\xed\\xfe\\x66\\x5b\\x6a\\x7b\\x0a\\xd3\\x95\\xdb\\xe2\\x56\\x76\\x4a\\xb6\\x52\\x77\\x9b\\xb2\\x92\\x70\\x2c\\xf3\\xfd\\x67\\xcf\\x6f\\x7e\\x93\\x8f\\xb7\\xb2\\x66\\xe1\\x59\\xcd\\xd7\\x9a\\xd6\\x5c\\xf6\\xf4\\xd2\\xfa\\x34\\x28\\x5b\\x32\\x66\\x27\\xd5\\xf0\\x54\\x5f\\x75\\xdd\\x95\\x5d\\x50\\x6b\\x96\\x95\\xb0\\x2e\\xa7\\xa6\\xc4\\x29\\x59\\x92\\xe9\\x29\\x2b\\x8c\\x76\\xc6\\x7e\\x6d\\x36\\x86\\x46\\xbb\\xc8\\x09\\xd7\\x88\\x71\\x63\\x5d\\xb3\\xca\\x0d\\x55\\x5d\\xe7\\x9e\\x9c\\x08\\x71\\x6f\\xde\\x6f\\x8a\\x96\\x43\\xe7\\x2d\\xc9\\xfc\\xab\\x34\\x94\\x24\\x97\\x3a\\x77\\x80\\x39\\xbb\\x42\\x15\\x5b\\x31\\x7e\\x96\\xb8\\xcc\\x79\\x39\\x76\\x4b\\x6c\\xa9\\x66\\x99\\xa6\\x2c\\xd5\\x0b\\xb5\\x74\\x58\\xae\\xb9\\x90\\xf5\\xaa\\x59\\xcb\\x9f\\x7e\\xfc\\xf6\\x4d\\xb3\\xdd\\x35\\x35\\x32\\x4a\\x4e\\x89\\x20\\xd3\\x91\\x3b\\xa8\\xf7\\xd4\\x66\\x0b\\x5b\\xb3\\x23\\x88\\x30\\xdc\\xd4\\xba\\x83\\x6c\\x32\\xd6\\xc2\\x66\\x6e\\xff\\xfa\\xcf\\xbd\\x54\\x8f\\x49\\x02\\x5e\\xe2\\x3f\\x54\\x45\\x59\\x5b\\xff\\xc2\\xd1\\x0e\\x60\\x4f\\x25\\x6e\\xec\\x8d\\x62\\xc7\\xfb\\x2d\\xbe\\x6f\\xc9\\x20\\xf0\\x07\\x3b\\x19\\x22\\x6a\\x78\\xd9\\x83\\x92\\x59\\x95\\x2f\\x21\\x6c\\xe0\\x6a\\xd9\\x4a\\x55\\x16\\xd5\\x38\\xc0\\x9f\\x6d\\x5a\\x6a\\x6d\\x56\\x36\\x23\\x7e\\x07\\x03\\x0c\\x8d\\x30\\x69\\xa4\\x00\\x3d\\x82\\x13\\x8d\\x12\\xc9\\x1e\\xe0\\xa3\\x81\\x4b\\xda\\x69\\x45\\x82\\x28\\xaa\\x50\\x8f\\x94\\x68\\x0f\\x3c\\x32\\xe7\\xf3\\x39\\x2e\\xe0\\xcc\\xc8\\x8b\\x22\\xca\\x4d\\x73\\x99\\x36\\xb6\\x66\\x9f\\xb2\\xa5\\x24\\x75\\x7b\\x65\\xa3\\xd7\\x7f\\xef\\xfc\\xff\\x42\\xfb\\x8b\\xd1\\x28\\xbe\\xd2\\x3d\\x2e\\x34\\xde\\x5d\\x39\\x1a\\x86\\xc9\\xce\\x63\\x46\\xb3\\x23\\x8b\\x3f\\x2e\\x8c\\x64\\x0b\\x4d\\x4d\\x31\\xec\\x21\\x7a\\x11\\x0c\\x8c\\x4b\\x35\\xcb\\xd0\\xb0\\x54\\x8f\\x18\\x96\\x9e\\xcc\\x87\\xa4\\x1a\\xbb\\xdf\\x12\\xa4\\x7a\\x73\\xca\\x6f\\x9a\\x93\\x4f\\xea\\x53\\x4d\\xcc\\xea\\x98\\x8e\\x64\\xad\\xc7\\xb3\\x22\\xe4\\xb0\\x93\\xcf\\xbf\\x6a\\x71\\xf1\\x3f\\x5f\\xcd\\x2f\\x6e\\xf9\\x3f\\xb5\\xb8\\xf8\\x1f\\xb3\\x97\\x2f\\x2e\\xf8\\x77\\x5a\\x5c\\xd0\\x65\\x96\\xe4\\xec\\x17\\xb1\\xfc\\x47\\x92\\xbf\\xbc\\xe0\\xdf\\x80\\xcc\\x99\\xbd\\xcc\\x58\\xba\\x3c\\xfb\\xa4\\xf3\\x97\\x74\\xf9\\x0f\\x53\\x62\\xfe\\x92\\xbd\\xb8\\xb8\\xdd\\xf2\\x0f\\x56\\x26\\xfd\\xf9\\xed\\x75\\xf7\\xcd\\xdb\\xaf\\xbe\\x36\\x7b\\xcb\\x1f\\x4c\\xda\\xa7\\x8b\\x4f\\x17\\x17\\xfc\\x47\\x2d\\x9e\\x8e\\xfc\\x3d\\xfc\\xff\\xad\\x16\\xe4\\xe5\\x05\\x71\\x41\\xa8\\xe4\\x25\\x61\\xfc\\x6f\\x23\\x4e\\x35\\x45\\x88\\xe5\\xfb\\x4e\\xd3\\xc6\\x8f\\xae\\xb8\\xdd\\x4f\\x97\\x04\\x30\\xd7\\x49\\x2e\\x85\\x29\\x7b\\x11\\xc7\\x08\\x45\\x66\\xae\\xe8\\x74\\xd8\\x1f\\x58\\x0c\\xfc\\x0b\\xc8\\x14\\xd0\\x74\\x96\\xf3\\x3c\\xa3\\xb5\\xa8\\x3d\\xdc\\x4a\\xd7\\x91\\x97\\x84\\xd3\\xc6\\x45\\xb2\\xe1\\xd1\\x77\\x1f\\x3c\\xc4\\xd2\\xe1\\x3d\\x67\\x69\\xe9\\xcf\\xb4\\xff\\xa4\\x81\\x64\\xa8\\xe1\\x05\\x8e\\x9f\\xd6\\x34\\xd0\\x5e\\x68\\x21\\xc4\\x7b\\xdd\\x7f\\x7d\\xe5\\xd6\\x41\\x0f\\xa4\\xd9\\x2e\\x65\\x8e\\x0e\\x99\\x20\\x33\\xf4\\xd2\\x72\\x9a\\x8f\\x6a\\x5a\\x14\\xdf\\xf0\\x9c\\x37\\x6f\\x0d\\x58\\x4d\\xed\\xb2\\xce\\xb3\\x7d\\x36\\xa1\\x4a\\xd4\\xcc\\xda\\xe5\\x52\\x5a\\x02\\x01\\xb7\\xd9\\x89\\xf4\\xde\\xf7\\x35\\xe3\\x95\\xf9\\x6f\\x72\\xc9\\x8e\\x8c\\x2b\\xcf\\x9c\\x1c\\x66\\x5e\\xce\\x73\\xa3\\xb4\\x63\\x5c\\x71\\x92\\x54\\xd0\\xcd\\x01\\xd4\\xb0\\x1e\\xda\\x95\\xae\\x66\\xc5\\xaf\\xc5\\xc3\\x95\\xd4\\xba\\xac\\x6f\\xdb\\xd9\\xa6\\x2a\\xb4\\x8d\\x37\\xf5\\x6c\\xec\\x35\\x02\\x4a\\xf7\\xd4\\x7f\\xcb\\x3a\\x37\\xea\\x7f\\x69\\x6a\\x2e\\x53\\xd5\\x75\\x54\\x89\\xa7\\x23\\x63\\xa6\\xd5\\x81\\x64\\xda\\x4b\\xc1\\x80\\x7b\\x74\\x32\\x37\\x4b\\x21\\xe3\\xf2\\xf8\\x37\\x0d\\xe7\\xbd\\xe2\\x1a\\xff\\x86\\xfe\\x4c\\x2b\\x5d\\x1e\\x64\\x3a\\xe7\\x55\\xd1\\xea\\xf7\\xcd\\xba\\xdc\\x94\\x72\\x0d\\xc1\\xb3\\xba\\x80\\x20\\xda\\xb0\\xae\\xe9\\xd3\\x5e\\x55\\xa9\\x2b\\x04\\x54\\x71\\xf2\\xe7\\xb7\\xd7\\x84\\x97\\xed\\x77\\xcd\\xaa\\xa8\\x52\\xf4\\xa1\\xb8\\x69\\xf6\\xba\\x2b\\x76\\x3b\\xf3\\xef\\xbc\\xd5\\x8d\\x32\\x2b\\xfb\\x6c\\x7a\\x0e\\xef\\x6c\\xcb\\xa6\\x86\\x05\\xde\\xac\\xf5\\xdd\\x7d\\xb9\\x06\\xfa\\xd4\\x17\\x17\\x28\\x71\\xae\\x6d\\x3c\\xfe\\xaa\\xa9\\x18\\x47\\x9a\\x20\\x20\\x72\\x54\\x8d\\xd1\\xcf\\x80\\x8b\\x64\\x32\\xe7\\x45\\xfb\\x58\\xaf\\x2c\\xcb\\xb2\\x96\\xb5\\x06\\x1e\\x3e\\x62\\x76\\x52\\x25\\x6a\\x5f\\x17\\x0f\\xe7\\xf7\\xf7\\xf7\\xe7\\x9b\\x46\\x6d\\xcf\\xf7\\xaa\\xc2\\x75\\x6d\\xbd\\x38\\x5b\\xdd\\x19\\x55\\x46\\x8b\\x9f\\xae\\xdf\\x9d\\xff\\x07\\xe1\\x46\\xeb\\xdb\\x69\\x1b\\xeb\\xf7\\xad\\x46\\x66\\x0e\\x54\\x97\\x76\\x66\\xc1\\x22\\x88\\xea\\x8f\\x29\\xe6\\x27\\xe1\\x0f\\xe6\\x3a\\x7a\\xd3\\xb6\\xe2\\x67\\x5e\\xc3\\xe2\\xbf\\xb6\\x00\\xd1\\x19\\x64\\x30\\x29\\x36\\xc7\\xaf\\xc5\\xa1\\xb0\\x0c\\x2b\\x47\\x57\\xf7\\x36\\x7d\\x32\\x65\\x5e\\x7c\\xba\\x79\\xd8\\x56\\x9f\\x6e\\x2e\\xf0\\x95\\x17\\x9f\\x6e\\xcc\\xdf\\x0b\\x2c\\xef\\xe2\\xd3\\x8d\\xf9\\xfb\\xe9\\xe6\\xe2\\xc8\\x95\\x6c\\x77\\x4d\\xdd\\xca\\x77\\xa5\\xac\\xd6\\xf6\\x61\\xe2\\x12\\x3f\\xbe\\xff\\x8e\\xd8\\xaf\\x70\\x49\\xd7\\xf2\\x41\\xbb\\x6a\\xb9\\xb4\\xbf\\x5c\\x7d\\xf8\\x1e\\x6b\\x70\\x90\\x4a\\xdb\\x68\\x47\\xa8\\x22\\x49\\x51\\x6d\\x44\\xa5\\xf1\\x0c\\xbe\\x19\\x78\\x3c\\xe1\\xd2\\x94\\x42\\x52\\xf3\\x34\\xaa\\x99\\x36\\xd9\\x7c\\x78\\xda\\xab\\xb4\\x47\\x1e\\x0c\\x69\\x1c\\x32\\xae\\xab\\x1e\\xb4\\xd9\\xad\\xf9\\x41\\xb5\\x7f\\xc6\\x2b\\x45\\x67\\x2f\\x34\\x85\\x89\\x13\\xcf\\x15\\xb3\\x3f\\x4e\\x5f\\x68\\x1a\\xa7\\x02\\xa9\\x8a\\x49\\xe8\\x79\\x8b\\xde\\x69\\xfa\\xa3\\x66\\x90\\x78\\xad\\x8a\\xba\\xdd\\x35\\x4a\\x9b\\xc4\\xf7\\x36\\x71\\xf0\\xda\\x31\\xdb\\x94\\x95\\xab\\xce\\xe3\\x5f\\x0b\\x0d\\xb3\\xd3\\x4c\\x63\\xb0\\xf4\\xf1\\x9a\\xaf\\xb9\\xe2\\x77\\xfc\\x16\\xa4\\xda\\xa1\\x9f\\xd6\\xfb\\x9d\\x0d\\x85\\x78\\x14\\x87\\x99\\xfd\\xec\\xae\\x3b\\xf0\\x6d\\x7f\\x99\\x24\\xc0\\x7e\\xe4\\x60\\x3d\\x1e\\xad\\xb2\\xc4\\xb2\\x2b\\xfa\\xc8\\x52\\x67\\x7c\\x7c\\x88\\x60\\x03\\xf8\\x8d\\xb8\\x9a\\xbd\\x29\\xaa\\xea\\xa6\\x58\\xfd\\xd6\\x52\\xd2\\xd4\\x2b\\x79\\xb6\\x95\\xdb\\x46\\x3d\\x12\\xc6\\xef\\xc5\\x61\\xd6\\xea\\x42\\xef\\xdb\\x37\\x40\\x70\\x0f\\x90\\x44\\x4f\\x47\\x6e\\xc5\\x2c\\x41\\xf2\\x57\\xb9\\x26\\xfc\\x5a\\x3c\\x29\\x59\\xac\\x1f\\xaf\\xb4\\xd9\\x7d\\x03\\xd9\\xfa\\x8f\\x76\\x5c\\x7c\\x23\\x8b\\xf5\\x18\\x99\\x37\\xf0\\xb0\\x39\\xd8\\xcc\\xa7\\x5a\\x3c\\x1d\\xad\\xd1\\x47\\x8b\\x6f\\x34\\xc6\\xb8\\xee\\x18\\xab\\x97\\xfa\\x84\\x47\\x02\\x28\\xef\\x05\\x7d\\xf6\\x56\\x04\\xd2\\xa0\\x97\\xaf\\x72\\x76\\xd4\\xa2\\x5e\\xca\\x91\\xac\\xc7\\x48\\xc3\\xd0\\xa8\\x61\\x68\\xab\\xf4\\xf1\\x33\\xa3\\xf5\\xdd\\x4a\\xfd\\x55\\x55\\xc5\\x5f\\x33\\x86\\x27\\x7d\\x97\\xed\\x52\\xef\\x46\\xf2\\x23\\x42\\x6d\\x9c\\x7c\\x7b\\x30\\x1e\\xf1\\x95\\xc8\\xd6\\xd6\\x0e\\x2b\\x97\\x8f\\x24\\x75\\x9d\\xe4\\x85\\x59\\xb7\\x2c\\xf3\\xf3\\x91\\x37\\x07\\xa9\\x54\\xb9\\x96\\xef\\xcb\\x2d\\x32\\x88\\x3e\\x6b\\x14\\xbf\\x83\\xd8\\xb6\\xad\\xcd\\x27\\xa4\\x2b\\xa1\\xef\\xdd\\xf1\\x0e\\x82\\x80\\xf8\\x3b\\x76\\xed\\x22\\xf9\\xe4\\xf2\\xda\\x8e\\x88\\x93\\x38\\x11\\xc9\\xee\\x97\\x3a\\x17\\x4b\\xf3\\x3f\\x6c\\x33\\xf2\\x98\\x31\\xa5\\xb8\\x31\\xf3\\x65\\xc4\\xbd\\xa6\\xeb\\xf6\\x2e\\xe7\\x2a\\x49\\x56\\x33\\xc8\\x08\\x10\\x8f\\x74\\xee\\x58\\xae\\x8f\\xb0\\x4b\\x78\\xf0\\x28\\x0e\\xd7\\x8c\\x1f\\x66\\x7b\\x55\\x09\\x4a\\x65\\xd7\\xc1\\xcf\\xae\\xb3\\x6b\\x08\\x9b\\x12\\xc2\\xbc\\xee\\xf6\\x83\\xe6\\x81\\xfc\\x9f\\x92\\x8b\\x0b\\x62\\x9e\\x05\\xfb\\x9a\\x9e\\x6d\\xa5\\xbe\\x6b\\xd6\\x5d\\xa7\\x2d\\x13\\xdc\\xc1\\xa7\\x60\\x16\\x7e\\xe8\\xd7\\x64\\x41\\xfb\\x0b\\x50\\x5e\\xd8\\xf3\\xda\\x10\\x21\\x2e\\xd0\\xf4\\x30\\x5b\\xa9\\xa6\\x6d\\xbf\\x6e\\xb6\\x45\\x59\\xb3\\x27\\x35\\xae\\xa8\\x99\\x8d\\xb7\\xc2\\xe5\\x14\\x3e\\x86\\xdb\\x0b\\xfc\\xc3\\xa3\\x42\\xc4\\xdf\\x06\\xdf\\x33\\x35\\x2b\\x71\\xd3\\xea\\x89\\x50\\x83\\x1b\\x0a\\xd2\\xfb\\x0d\\x7a\\x5c\\x8e\\x91\\x9a\\xe5\\xc6\\x7e\\x55\\x92\\x1c\\x66\\xc1\\x8a\\xd8\\x73\\x23\\x7a\\x3d\\xc7\\xe5\\xb3\\x0f\\x08\\xb7\\xcb\\xc1\\x4b\\xd3\\xa6\\xaa\\x58\\x03\\xa8\\x5f\\x51\\x31\\xc6\\xff\\x64\\xc4\\x25\\x3f\\x70\\xcd\\xaf\\x19\\xf7\\x5e\\x26\\xd7\\x9e\\xb0\\x82\\xde\\x3a\\xf3\\xb6\\x79\\x35\\x2e\\xcb\\x2c\\x49\\xe6\\xc2\\x08\\x3d\\x50\\x20\\xa6\\x53\\xd0\\x3b\\x22\\x93\\x16\\x01\\x79\\xa8\\x0b\\xa5\\xfb\\x6e\\xc4\\x3f\\x31\\xae\\x1f\\x3f\\x80\\xf3\\x82\\xa5\\xef\\x99\\x7c\\xb0\\x1b\\x13\\xcc\\xca\\xb8\\x6d\\x66\\x3f\\x4a\\xfe\\x09\\x67\\xab\\xd1\\x43\\xd9\\x33\\xed\\x02\\x88\\x98\\x56\\xe8\\xa2\\x96\\x80\\x04\\x82\\xfe\\x08\\xe3\\x77\\x55\\x06\\x38\\x1a\\xb1\\x8d\\x88\\x7f\\x7a\\x26\\x40\\xcd\\xc9\\x94\\x80\\xee\\x6b\\x6b\\x88\\xea\\xf2\\xc6\\xf9\\xde\\xf0\\xa0\\x17\\x82\\x6a\\xf5\\x96\\x1d\\x11\\x77\\x97\\x79\\xd5\\x66\\x2a\\xe8\\x5b\\xdb\\x00\\x1b\\x96\\x91\\x84\\xa4\\x24\\x23\\x6c\\x6a\\x3b\\xce\\x3a\\x55\\xda\\xfc\\x68\\xa5\\x3e\\xcc\\x56\\xc5\\xea\\xce\\xac\\x58\\x1b\\xb1\\xf1\\xb5\\xfb\\x4e\\x73\\xf2\\xe2\\x92\\x30\\xde\\x8c\\x17\\x48\\x7e\\x11\\x64\\xfa\\x46\\xcf\\x6e\\xf7\\xe5\\x7a\\x3a\\x9d\\x36\\x6e\\x92\\x6e\\xf0\\x67\\xb9\\x71\\xba\\x20\\xc0\\x48\\x84\\xca\\xe1\\x72\\x93\\x27\\xc9\\xf5\\x6c\\x28\\x39\\x29\\xf9\\x76\\x73\\xee\\xf2\\x9c\\x5f\\x95\\xf5\\x4a\\x12\\x7e\\xf2\\x24\\x18\\x8a\\x75\\x71\\xfb\\xb9\\x42\\xbe\\x6f\\x6a\\x79\\xfe\\xde\\xcc\\x03\\xd2\\xe7\\x66\\x8c\\x07\\xa3\\xbf\\xef\\x7a\\x6b\\x50\\x1f\\x74\\xb2\\x0e\\x2f\\xd9\\xf8\\x9b\\x6c\\x01\\xe7\\xd7\\xe0\\xc9\\x1d\\x15\\xc0\\xf8\\xd8\\x03\\x5f\\x81\\xb6\\x48\\x42\\x39\\xb3\\x9c\\xe7\\xa6\\x3a\\x56\\x8f\\x5c\\xc6\\x77\\xf2\\xec\\xd9\\x3b\\x53\\xb3\\x49\\x80\\x6a\\x87\\xc9\\x99\\x59\\xc6\\xa6\\xdf\\xea\\x29\\x59\\x9c\\xfd\\x53\\xcc\\x67\\xf3\\x4b\\x92\\x12\\xc2\\xd2\\xbe\\x18\\x84\\x2e\\x3a\\xcc\\xee\\x70\\x69\\x63\\x23\\xd5\\x2c\\xfb\\xdb\\xc0\\x4c\\x0c\\x52\\x03\\x89\\x83\\xae\\x64\\xbd\\x76\\x20\\x54\\x61\\x1a\\x9e\\x46\\x3e\\xf2\\x6b\\x7e\\x60\\x5d\\x77\\xe7\\xcf\\x7f\\xaf\\xad\\x7c\\x87\\x42\\xf6\\x82\\xc0\\x15\\xe1\\x37\\xc0\\x18\\x7b\\xe8\\x21\\x3b\\xf8\\x35\\xc6\\x5b\\x1f\\x66\\xed\\x1e\\xec\\xa8\\x26\\x05\\x60\\x3c\\x0e\\x68\\x23\\x64\\x7c\\x25\\xfe\\x64\\xb4\\x2f\\x2b\\x63\\x40\\x95\\xb8\\x9e\\xf5\\x6a\\x88\\xb8\\xe4\\xb7\\x49\\xb2\\x1d\\x88\\x0e\\x60\\x40\\x5a\\x5e\\xf3\\x43\\x1e\\x49\\xa5\\xc3\\x0c\\xf4\\xff\\x24\\x99\\xbf\\x3e\\x40\\x24\\x52\\xb3\\xd7\\x70\\x80\\xf9\\x1c\\xb2\\x95\\xfb\\x0e\\x62\\x33\\x1b\\x55\\xc1\\x3f\\xc9\\x50\\xa2\\xdf\\x89\\xc9\\x25\\x5f\\xcd\\x5a\\xb3\\x29\\x2a\\x78\\x15\\x58\\x4a\\x61\\x55\\xd5\\x77\\xaa\\xb9\\x3f\\x93\\x8b\\x8a\\x9e\\x5f\\x1a\\x7d\\x13\\x7d\\xa8\\xe0\\x8a\\x7c\\xdf\\x9c\\x79\\x25\\x33\\xdc\\xc8\\x57\\xcf\\x9e\\x15\\x0b\\xbd\\xb8\\xeb\\x3a\\x0a\\x71\\x86\\xeb\\x24\\x19\\xc4\\x08\\xad\\x4d\\x73\\xd9\\xd3\\x93\\x9d\\x50\\x46\\x64\\xf1\\xa8\\xb1\\xe6\\xaf\\x65\\xf6\\x65\\x6a\\x36\\xf9\\xaf\\xe6\\xf3\\xd7\\x40\\x5e\\xf6\\xfa\\x8b\\xf9\\xbc\\xeb\\xbe\\x98\\x7f\\x29\\x84\\x90\\x10\\x93\\xd0\\x3e\\xef\\x6b\\x6f\\xa9\\x81\\xdc\\x06\\x84\\xef\\x85\\xec\\xc7\\xa1\\xd5\\xec\\xc8\\x4b\\x22\\x84\\xd8\\x9b\\xcd\\xed\\xde\\x1f\\x04\\x7b\\x0c\\x09\\x05\\x88\\xaa\\xd2\\x6b\\x29\\x66\\xc6\\x9d\\xe8\\x91\\x83\\x29\\xc6\\x60\\x18\\xa9\\x9e\\xbb\\xb8\\x35\\x0a\\x8b\\x19\\xa4\\x49\\x02\\xf4\\xc4\\x20\\xa3\\x14\\x63\\x4f\\x7b\\xbf\\xff\\x2e\\xd9\\xe2\\x46\\xc9\\xe2\\x37\\xb3\\xf6\\x99\\xba\\x94\\xf5\\x59\\xcd\\x1a\\xa8\\x16\\xa8\\x34\\x3d\\x2b\\x37\\x62\\xf0\\x4e\\xf6\\xc8\\x16\\x3d\\xeb\\xb7\\x36\\xcb\\xd2\\x68\\x8f\\x00\\x27\\x9b\\xb3\\xa7\\x46\\x94\\xb6\\xc4\\x02\\x38\\x8d\\x4a\\x76\\x04\\x50\\x8d\\xc2\\xbc\\xc1\\xfb\\x91\\x37\\x13\\xfc\\xf4\\x24\\xe9\\xab\\xd2\\x30\\x5e\\x2f\\x9b\\xfc\\x48\\x0f\\xfc\\x1a\\x40\\x8b\\x27\\x25\\xf8\\x92\\xf5\\x7e\\x11\\x8e\\x3c\\x33\\x14\\x10\\xb8\\x7c\\x04\\xb5\\xc1\\x1d\\x93\\xcd\\x99\\x87\\x91\\x62\\x47\\xc6\\x87\\x7d\\x36\\x36\\x74\\x9e\\x8e\\xc0\\xab\\xda\\xdb\\x2a\\x70\\xd5\\x81\\xc6\\x5d\\x2d\\x2f\\x73\\x24\\x45\\x05\\x2d\\x2f\\x78\\x2f\\xab\\x96\\xc5\\x50\\x6d\\x8d\\x5a\\xa9\\xc8\\x17\\x8d\\x58\\xb9\\x9e\\x76\\x5e\\x9f\\xa6\\x87\\xe0\\xcc\\x2e\\xd8\\x72\\x2e\\x2d\\x73\\xe6\\x48\\x3a\\xe8\\xbb\\x93\\x7d\\x92\\xa8\\x24\\xc1\\x2a\\xbe\\x83\\xfd\\x18\\xee\\xa6\\x82\\x04\\xaa\\x79\\xff\\x09\\xe0\\x57\\xd0\\xf0\\xe0\\xf5\\xe6\\xb5\\x38\\x00\\x1b\\xd3\\xdb\\xde\\x94\\x8e\\x42\\x73\\x9f\\x24\\x7b\\xf0\\xfa\\x87\\x1e\\xa7\\x85\\xa8\\x96\\x7b\\xe8\\xe3\\x26\\xef\\xba\\x6a\\x49\\x5e\\xc2\\xcf\\x80\\x24\\xbb\\x02\\xc7\\xa3\\x56\\x94\\x01\\xb4\\x2c\\x5b\\x5e\\xe6\\x18\\x2d\\x10\\x14\\x00\\xb2\\xd9\\x97\\x01\\x57\\x8c\\x3d\\x01\\x8e\\x74\\x91\\x99\\x6c\\x65\\x9e\\x02\\x90\\x40\\x05\\xa3\\x96\\x36\\xc2\\xe4\\xe1\\x2b\\x3f\\x48\\x5a\\xd3\\x01\\xc1\\x98\\x85\\xcc\\x85\\x79\\x7d\\x91\\x24\\x72\\x49\\x40\\x8c\\xb4\\x24\\x67\\x5a\\x14\\x54\\x3b\\x24\\x28\\x38\\xc9\\x31\\xd7\\xbd\\xd0\\xb1\\x46\\xd1\\x16\\xf6\\x68\\xd1\\x01\\x0c\\x87\\x3f\\x69\\x91\\xc9\\xd4\\x48\\x1e\\xec\\xc2\\x16\\x20\\xe9\\x54\\xb3\\x35\\x23\\x7d\\x4a\\xce\\x74\\x63\\xda\\xe0\\x78\\x3c\\xc6\\xe5\\x58\\xf1\\x4c\\xb8\\x69\\xfa\\x54\\x1f\\xcd\\x60\\x6e\\xf9\\x35\\x2f\\x19\\x2f\\x33\\x3a\\x58\\xf5\\xe9\\x5e\\x5c\\x8f\\x4d\\xea\\xef\\x8a\\x56\\xfb\\x85\\x1e\\x61\\x55\\x4e\\x96\\x79\\xb1\\x67\\xfc\\xb9\\xe7\\xcd\\x82\\xee\\x1e\\xb3\\x8b\\xbb\\xd8\\x33\\xc6\\x5f\\xa1\\xf0\\xea\\x3a\\xf2\\xcd\\xdb\\xaf\\xbe\\x26\\xb0\\x46\\x19\\xfd\\x28\\x03\\xac\\x13\\x47\\x44\\x90\\x5a\\x19\\x87\\xa9\\x7a\\xeb\\xea\\x91\\xd2\\x4a\\x00\\x12\\x95\\x96\\xc0\\x2a\\x06\\xea\\x52\\x29\\xcc\\xf0\\x68\\xed\\x22\\x64\\x54\\xb5\\x42\\x54\\x7c\\x22\\x93\\xa4\\xea\\x3a\\x5a\\x09\\xe2\\x9a\\x14\\x7c\\xc6\\xa5\\x98\\x33\\x06\\x4b\\x3f\\xec\\x9a\\x84\\xf4\\x3f\\x81\\x6a\\x87\\xea\\xae\\xab\\xcc\\x86\\x85\\x97\\xd9\\x43\\x04\\x73\\xf6\\xc8\\x97\\x0d\\xaf\\xf8\\x75\\xce\\xd2\\x87\\x10\\xe7\\xec\\xd1\\x2c\\x5e\\x15\\x2f\\xf2\\xbe\\x50\\xb3\\x7d\\xa3\\xf7\\xb0\\x5d\\x47\\x01\\x1f\\x2d\\x7b\\x65\\x86\\x0b\\x9f\\xed\\xa6\\x14\\xae\\xde\\x62\\x1d\\xcd\\x3a\\xc8\\xcb\\xac\\x49\\x4d\\x71\\x37\\x80\\x1e\\x14\\xbc\\x24\\x07\\x08\\x14\\x3a\\x58\\x41\\xdf\\xd8\\x15\\xda\\xaf\\xa2\\xe7\\xe7\\x4e\\x61\\x87\\xf3\\xbb\\x31\\x75\\xbd\\x01\\x3f\\x3a\\xb7\\xd9\\xbe\\x86\\x4d\\xf5\\x5f\\xae\\x3e\\x7c\\xff\\x4c\\x70\\xd9\\xd9\\x95\\x0b\\x72\\xe1\\x35\\x27\\x60\\x20\\xc2\\x8d\\xf8\\x15\\x88\\xb8\\xf1\\xfd\\xb4\\x7b\\xc6\\xb6\\x81\\xee\\x79\\x87\\x23\\xe7\\xb6\\x5b\\xa9\\x09\\x27\\xbb\\xa6\\xd5\\x71\\x60\\x7a\\xc9\\x9e\\xae\\x96\\xe5\\x30\\x98\\x2c\\xc0\\xce\\xd8\\x3a\\xd2\\x39\\xd5\\x75\\x35\\xaf\\x01\\xcc\\xdb\\x19\\x72\\xd0\\x4c\\xd3\\x43\\x86\\x81\\x7d\\x4a\\xa2\\x31\\xb3\\xe4\\x4e\\x26\\xa5\\xca\\xce\\x11\\x6e\\xe7\\x4c\\x5a\\x1f\\xf9\\xe9\\x41\\x16\\xb8\\x30\\x61\\x9d\\x23\\x03\\xd4\\x88\\x17\\x6f\\xbf\\xf9\\xf6\\xda\\x9b\\x67\\xd5\\x02\\x0f\\x31\\x60\\xf8\\x8c\\x44\\x34\\x78\\xa7\\x04\\x6a\\xa9\\xf0\\x8f\\x42\\x18\\x13\\x21\\x08\\x61\\xed\\x58\\xce\\x9f\\x0b\\x3e\\xb7\\x5f\\x1c\\x7e\\x28\\x5a\\x6d\\xfd\\xc7\\xfa\\x95\\x0b\\x76\\x12\\x81\\x85\\xf5\\xd2\\xdb\\x60\\x2f\\x63\\x6b\\x61\\xb8\\x8a\\x85\\x06\\x96\\xe3\\x91\\xf7\\x52\\x7e\\x00\\x7b\\xdb\\xb3\\xbe\\x53\\x1f\\x00\\x3f\\x38\\xa9\\xbb\\x57\\xc5\\xee\\xab\\xaa\\x7a\\x1e\\xce\\xd7\\xba\\x52\\x98\\xa1\\x8e\\x27\\x57\\xa6\\x51\\xbc\\xff\\xb3\\xd1\\x56\\x18\\xd7\\xe2\\xca\\xc2\\x26\\x9f\\x70\\xf3\\xb3\\x99\\xfc\\x27\\x9d\\xb3\\x80\\xae\\xd2\\x65\\x8b\\xc3\\x82\\x22\\x46\\x5b\\x57\\x32\\xd7\\xe3\\xe7\\x7c\\x00\\x9f\\x68\\xfd\\xf1\\x91\\xe2\\xd7\\xda\\x0b\\x90\\xe9\\xd7\\xd4\\xf0\\x24\\xb5\\xa7\\x5e\\xf7\\xfc\\xa6\\xda\\x32\\x88\\x82\\x05\\xc6\\x34\\xc4\\xb7\\x75\\x84\\x14\\x57\\x07\\xc3\\xbb\\xfe\\xbd\\x30\\x04\\xff\\x3c\\x8d\\xdc\\xc3\\xd9\\xe7\\xe3\\x0e\\x7c\\x94\\x81\\x0e\\xd4\\x43\\xca\\x16\\x0e\\xb5\\x3c\\xd3\\x33\\xdb\\x43\\x14\\xc2\\x47\\x6d\\xcd\\x91\\x6d\\xc0\\xdc\\x39\\x89\\x95\\xc1\\x43\\xe8\\xc5\\x1f\\x0a\\x8c\\xf1\\x45\\x67\\x51\\x58\\x0c\\x4b\\x91\\x60\\x77\\x5f\\xc7\\x6f\\x18\\xc4\\x1f\\x62\\x07\\x52\\xc9\\x66\\x75\\xa3\\x29\\xb9\\x69\\xd6\\x8f\\xe4\\x94\\x14\\xbb\\x0f\\xc2\\xf1\\x0c\\xa9\\xee\\xf0\\xb3\\xac\\xd6\\xa6\\xfb\\x5b\\x33\\xa9\\x1c\\x30\\xa5\\x0d\\x81\\xdd\\xb5\\x72\\xbf\\x6e\\x5a\\x07\\x38\\x75\\x5a\\x85\\xc9\\x20\\x23\\x10\\x73\\x59\\x02\\xd1\\xf1\\x5b\\x63\\x85\\x4c\\xa8\\x0c\\xc9\\x06\\x8d\\x1e\\x8b\\x97\\xc8\\xfb\\xf2\\x19\\xf2\\x08\\x78\\x4d\\x74\\xaa\\xf4\\x70\\xa7\\x42\\xe5\\x12\\x8c\\x56\\x3d\\x3d\\xcf\\x9b\\xd9\\xc7\\xf7\\xdf\\x7d\\xa3\\xf5\\xce\\xee\\x1d\\x43\\xfa\\x5d\\x24\\x63\\xd3\\xe2\\x69\\x0e\\xb8\\x0a\\x97\\xaf\\x5e\\x7d\\x91\\xbe\\x9a\\x7f\\x79\\xe4\\xff\\xd2\\xc3\\xa3\\xab\\x87\\x3b\\x45\\xd9\\xe2\\x71\\xb6\\x6a\\x54\\x2b\\x26\\x93\\x7f\\xe9\\x24\\x21\\xf7\\xa5\\xbe\\x7b\\xa3\\xe4\\x5a\\xd6\\xba\\x2c\\xaa\\x96\\x94\\xf5\\xd9\\xbf\\x34\\x7f\\x84\\x07\\xc5\\xbf\\x34\\x64\\xb3\\x95\\xf5\\xbb\\xa6\\xbe\\x87\\xac\\xdb\\x46\\xc3\\x0b\\xa3\\xcf\\x62\\xc9\\x5d\\x67\\x0a\\x9e\\x94\\x91\\x75\\xce\\x29\\x36\\x11\\xcf\\x77\\xe4\\x16\\x51\\xda\\xea\\x99\\x4d\\x07\\x50\\xbd\\xd2\\x12\\xed\\x84\\x25\\x58\\xed\\x4a\\xdc\\x45\\x9a\\xab\\x56\\x82\\x6b\\x29\\x2f\\x67\\xbb\\xa2\\x6d\\xef\\x1b\\xb5\\x66\\x1c\\x9e\\x46\\xc5\\xb6\\xc7\\xfb\\x0c\\x13\\x15\\x80\\x79\\xf6\\x09\\xcb\\x3a\\x5f\\x04\\x19\\xdd\\xce\\x08\\xb0\\xa2\\x06\\xb6\\xdf\\xb1\\x34\\xda\\x3f\\x62\\x5e\\x1e\\x7c\\x6a\\xd7\\xc9\\x25\\xf9\\x78\\x6e\\x7b\\x4a\\xae\\xcf\\x81\\xd6\\x37\\x07\\x64\\xd1\\x91\\x74\\x41\\xe2\\xae\\x25\\x8c\\x4b\\xa6\\x4e\\xed\\x04\\xe8\\x41\\xc1\\x16\\xcd\\x98\\x7b\\x76\\x30\\x72\\x1a\\xd0\\x73\\x0b\\xa1\\x66\\x4d\\x5d\\x35\\xc5\\x1a\\x7e\\x80\\xde\\x04\\xbf\\x60\\x67\\x0d\\xbf\\xec\\x7e\\x1a\\x7e\\xc3\\x66\\x15\\x94\\xb1\\xd5\\x5d\\x51\\xdf\\x22\\xcd\\x36\\xb7\\x06\\x04\\x50\\xdf\\x94\\xb3\\x2d\\xa4\\x56\\x09\\x83\\xd4\\x11\\xc0\\x30\\xd4\\x9b\\x32\\x4d\\xe7\\xdc\\xe6\\x64\\xa9\\xa6\\x2e\\x9d\\xab\\x40\\x45\\x33\\x37\\x7e\\xd1\\x4b\\x97\\x94\\x77\\xdd\\x68\\x36\\x3c\\xb5\\x42\\xfa\\x0f\\xbf\\x87\\xb1\\xc6\\x41\\xb8\\xc3\\x46\\x9c\\xaf\\x82\\x9c\\xf2\\x41\\x67\\x4f\\x37\\x65\\x5d\\xa8\\xc7\\xb4\\x4f\\x3e\\xa6\\x4f\\x70\\xbe\\x15\\x67\\x3c\\x72\\x08\\x22\\x39\\x3d\\x95\\xa0\\x0c\\x02\\x34\\x7c\\xab\\x36\\x94\\xf1\\x62\\xd0\\xb6\\xae\\x45\\x1b\\xea\\xbe\\x9c\\x07\\xc1\\x31\\xb6\\xed\\xb3\\xbe\\x17\\x8a\\x74\\xb4\\xed\\x83\\xce\\x34\\xaa\\xb3\\x0a\\x4c\\x09\\x49\\xf2\\x9c\\xcd\\xa4\\x49\\x92\\x02\\xd0\\x29\\x79\\x63\\xde\\x8f\\x3d\\xe7\\x8c\\xdf\\x60\\x25\\x29\\x23\\x2b\\x1c\\x1e\\x88\\x23\\x6a\\x54\\x6c\\x3c\\x69\\x9c\\xf1\\xe4\\x78\\x72\\xb0\\x00\\xaf\\x69\\xa8\\xe3\\x54\\x79\\x5e\\x85\\x92\\xe1\\x84\\x08\\xd5\\x22\\x80\\xa2\\x2f\\x77\\x5a\\xe0\\x09\\x7d\\x74\\x06\\xe7\\x4f\\x77\\x31\\x8b\\x3d\\xc6\\xed\\xcf\\x60\\xf9\\x59\\x74\\x4c\\xfb\\x4c\\xba\\x5c\\x6d\\x47\\xd3\\x1f\\xce\\xfb\\x3b\\xd1\\x69\\xae\\x7d\\xdb\\xc5\\xa7\\x1b\\x9a\\xa5\\xa6\\xd4\\xce\\x64\\x64\\x98\\x0c\\x47\\xb8\\x7f\\x40\\x93\\x92\\xa1\\xae\\x1c\\xe8\\x4d\\x8c\\xcb\\xd1\\xc6\\xf2\\x1a\\x5c\\xa4\\x39\\x79\\x02\\x79\\x6f\\x22\\xb6\\xbf\\x4c\\x73\\xf1\\xd3\\x46\\x45\\x18\\x17\\xa3\\x1b\\xf6\\x8d\\xd9\\x0b\\xe9\\xd3\\x77\\xf4\\x46\\x25\\x70\\x0c\\x8b\\xa5\\x56\\x6d\\xbb\\xe6\\x2b\\xad\\x55\\xfb\\x19\\x79\\xad\\xc4\\x15\\x25\\xaf\\x31\\xef\\x7f\\x12\\x86\\x41\\x4e\\xd1\\xc3\\xc8\\x2a\\x0f\\xce\\x54\\x4f\\xf6\\x04\\x3f\\x75\\x19\\xde\\xe0\\x35\\x6f\\xd5\\x2a\\xad\\x8d\\x60\\x3f\\xb2\\x59\\x53\\x53\\x62\\x26\\xd5\\x99\\xdd\\xde\\xc5\\x8e\\xb0\\xca\\x79\\x6f\\x32\\x5e\\xa2\\x5c\\x32\\x2a\\x1f\\x0d\\xc4\\x10\\x6e\\x3b\\xbf\\x9c\\x7f\\x09\\x0b\\x20\\x5e\\x9a\\x06\\x79\\x0b\\xea\\x77\\x84\\xc1\\xa3\\x8c\\x62\\x38\\x32\\xae\\xcb\\x24\\x29\\x69\\xef\\x1a\\xfa\\x93\\xe6\\x1f\\xb5\\x58\\xe6\\xfc\\x67\\x2d\\x2e\\xa8\\x60\\x9f\\x32\\x9a\\x89\\xa4\\x7b\\xc1\\xba\\x4f\\x19\\xfa\\x83\\x06\\xe3\\xd6\\x6c\\xa2\\x76\\x29\\x59\\xd9\\xa3\\x5e\\x3c\\xbc\\xdf\\xb9\\x93\\xdf\\x53\\xcf\\xd7\\x8f\\x1a\\x9d\\xc7\\x61\\x4b\\x87\\xe1\\x17\\x53\\xf2\\x4b\\x60\\xdd\\x8f\\x94\\x67\\x74\\xa6\\x91\\xa3\\x83\\xc8\\xbc\\x08\\x0e\\xf9\\x77\\xe4\\x79\\xb6\\x1b\\x5e\\x88\\x09\\x92\\x53\\x40\\xce\\x24\\xa1\\x3f\\x7b\\x84\\x81\\xbd\\xaa\\x58\\x46\\xf6\\xaa\\x22\\x23\\x18\\x15\\xd6\\x7a\\x0f\\x87\\x32\\xf2\\xbf\\x7b\\x28\\xd3\\xbf\\xd3\\x1e\\x9d\\x10\\xf3\\x17\\xa3\\xa0\\x8b\\xae\\x23\\xf8\\x15\\xd0\\x9b\\x91\\xa7\\x8e\\xc7\\x7f\\xb2\\xd5\\x77\\xcd\\x2a\\xb6\\x74\\x90\\xc2\\xb2\\x41\\x02\\x35\\x2a\\x6f\\x94\\xc2\\x8b\\x4c\\x2e\\x8b\\x5c\\x98\\xff\\xfc\\xc9\\xcb\\xcf\\x78\\xf2\\x32\\x55\\x2c\\x1d\\xb4\\x13\\xb4\\x4f\\x70\\xc0\\xe3\\xda\\xcb\\x9d\\xc9\\xd8\\x9c\\xe0\\x8a\\xa9\\x60\\x7e\\x06\\x76\\x43\\x1c\\xee\\xe8\\x82\\x11\\xd9\\x0d\\x9d\\xcd\\xb2\\xf7\\xc8\\x55\\x53\\x72\\x76\\x5f\\xb4\\x67\\x75\\xa3\\xcf\\xcc\\x28\\x32\\x2d\\xc6\\x9b\\xe5\\x3c\\x3f\\xf2\\xb8\\x35\\x04\\x6e\\xd8\\x79\\x29\\xde\\x2c\\x55\\xce\\xdf\\x44\\xe0\\x6e\\xec\\xa9\\x11\\x3e\\x5e\\xf5\\xc8\\xeb\\x11\\x84\\xd8\\x9e\\xb7\\x2d\\xbb\\xa2\\x6f\\x5c\\x68\\xfb\\x0f\\x66\\xa2\\x2a\\x96\\x42\\x71\\x25\\x97\\x4b\\x95\\xc3\\xc7\\xc7\\xed\\xad\\x07\\x4d\\x69\\x46\\xf1\\xbe\\xbd\\xa3\\x8a\\x01\\xbc\\xeb\\x96\\x96\\xcc\\xcc\\x21\\x44\\x6b\\x6f\\x44\\xd9\\x93\\x53\\x38\\x39\\x04\\x8e\\xf2\\x78\\x40\\xfb\\xcd\\x35\\xc0\\x7d\\x40\\x5d\\x05\\xa5\\x3f\\x69\\xf1\\x76\\x56\\x6e\\x77\\xb8\\xe1\\x82\\x91\\x34\\x92\\x91\\x9a\\x51\\x67\\xf6\\x09\\x66\\xec\\xd5\\x52\\x99\\x7b\\x82\\xbc\\x36\\x83\\xed\\x3f\\x5f\\x5f\\xe0\\x9f\\xf0\\x82\\xf0\\x57\\x42\\x88\\x9f\\x74\\xb0\\x57\\xf0\\x47\\x7d\\xd6\\xfb\\x05\\x8a\\x18\\xdf\\x86\\x9f\\xfa\\xee\\x65\\xcb\\x3c\\xa5\\xa3\\x01\\xe9\\x14\\x4d\\x16\\x46\\x48\\xeb\\xae\\xa3\\x63\\x5f\\x99\\x51\\xaa\\x04\\xfd\\xc3\\xdf\\xc9\\x86\\x27\\xd9\\x37\\x45\\x2b\\x4d\\x32\\x1c\\x5d\\xbf\\xf5\\x6e\\xeb\\xd6\\xb3\\x6b\\x44\\xd0\\x31\\x96\\x6a\\xf1\\x16\\x28\\xe3\\xea\\x24\\x59\\xe6\\x9c\\x96\\xe2\\x7b\\xf4\\xfd\\x90\\x8c\\x65\\x4b\\x3d\\x78\\x43\\xb9\\xbc\\xcc\\x59\\x9e\\xd2\\x52\\x3c\\x20\\x30\\xaf\\xe6\\x0d\\xf4\\x6c\\xe3\\x09\\xef\\xae\\x68\\xc3\\x7a\\x61\\x7c\\x35\\xdb\\x4a\\x75\\x2b\\xe9\\x32\\x37\\xfa\\x6f\\xbf\\x1d\\x63\\x28\\x42\\x41\\xf6\\x58\\x73\\x01\\x68\\x4c\\x9f\\x13\\x50\\xb0\\x73\\x6c\\x85\\x0c\\x31\\x0a\\xdc\\x2e\\xf4\\xfc\\xf2\\x35\\x12\\xc2\\x1d\\xcc\\x0c\\x44\\xeb\\xb9\\xd9\\x78\\x9b\\x7d\\x3a\\x5e\\xcd\\xb9\\xb9\\x06\\xef\\x69\\x1a\\x19\\x8f\\x52\\x3d\\x82\\xa9\\xab\\x91\\x93\\xf5\\x87\\x0f\\x57\\xd7\\x84\\xf1\\xf9\\xeb\\xa2\\xff\\xbe\\x53\\xc3\\x4b\\xd9\\x75\\x43\\xdb\\x0b\\xfa\\x95\\x59\\x8b\\x2c\\x1b\\x20\\x17\\xcb\\x68\\x16\\xf2\\x62\\x66\\x72\\x53\\x95\\x99\\x25\\x73\\x5d\\x1e\\xfe\\xd3\\x43\\xc2\\xd1\\x60\\x04\\x9a\\x0e\\x81\\x80\\x61\\x33\\x0b\\xcd\\xca\\xe5\\xa6\\x6e\\x9d\\x24\\xf1\\xda\\x5b\\x9c\\x6c\\x90\\xeb\\x10\\xa7\\xb1\\xe9\\xba\\xc0\\xcc\\x0f\\xba\\xb3\\xe6\\x32\\x07\\xd0\\x72\\x6b\\xa8\\x18\\xec\\x6e\\x2d\\xc6\\x61\\xd0\\x3b\\x91\\xd5\\x4f\\xc9\\x1d\\xf5\\x00\\x9c\\x63\\x3b\\x79\\xe1\\x88\\x8c\\x8e\\x6e\\x6b\\x6b\\x5e\\x81\\xbb\\x60\\x08\\x41\\xf9\\x00\\x3f\\x9f\\x07\\x0b\\xf2\\xe7\\x24\\x3d\\xe7\\xb2\\xa5\\x2f\\x24\\x10\\xa5\\x47\\xc1\\xa3\\xe0\\xe9\\xb8\\x20\\x46\\x45\\x2e\\x57\\xc0\\x66\\xdf\\x53\\xff\\x79\\xb2\\x43\\x41\\x94\\xac\\x0a\\x5d\\x1e\\x00\\x54\\x52\\xac\\x6c\\x1d\\x28\\x62\\xe3\\xda\\xa2\\xc1\\x58\\xca\\xf7\\x7d\\x42\\x05\\xc4\\x7d\\x9c\\x46\\x0c\\x8a\\x55\\xd7\\x91\\x4d\\xf9\\x00\\x50\\x6f\\x00\\x09\\x7e\\x7e\\xf9\\x9a\\x36\\xd3\\x7d\\xb8\\xe4\\xed\\x75\\x43\\x58\\x46\\x0b\\x41\\x95\\x58\\xf9\\x4a\\x50\\xc6\\x66\\xba\\xd9\\xf1\\x52\\x28\\xe0\\xea\\x03\\x03\\x76\\xc0\\x19\\xd8\\xb0\\xae\\x9b\\xf3\\x32\\x4c\\xda\\x23\\x25\\xf3\\xd6\\x85\\xf2\\x6b\\x17\\x6a\\x5a\\x47\\x40\\xbd\\x66\\x5a\\x59\\x88\\x64\\x3d\\x03\\x44\\x53\\xba\\x31\\x7f\\xf1\\xea\\xbc\\x35\\xff\\x4f\\x8b\\x3e\\x8b\\x79\\x3b\\xe4\\x31\\x3f\\xec\\xf5\\x79\\x0b\\x7f\\xa6\\x25\\xe3\\x64\\xdf\\x1a\\xd9\\x56\\xd6\\x67\\x3a\\xd3\\x33\\xb8\\x70\\xef\\xdd\\xb0\\x94\\x9e\\xa0\\x0f\\x6c\\xc2\\x77\\x4e\\x05\\x70\\xb8\\xf1\\x91\\x5c\\xd1\\x6b\\x5d\\xbe\\x15\\xb4\\xf6\\x86\\x21\\x5f\\x54\\x60\\x3d\\x6c\\x06\\x63\\x03\\xa3\\x9b\\x9f\\x03\\x51\\xf1\\x8b\\x17\\x82\\x7f\\x8c\\x99\\xc5\\xc0\\x6c\\x89\\xa5\\xce\\xfc\\xd8\\x73\\x88\\x04\\x10\\x9a\\xe0\\xf1\\x60\\x86\\x48\\x0f\\x2a\\x53\\xcf\\x19\\x6b\\x32\\x07\\x2d\\x30\\xc6\\xc9\\xc8\\x6b\\xb3\\xb5\\x0b\\x6d\\x96\\x61\\x0c\\x26\\x7f\\xd2\\xcd\\x2e\\x95\\xd0\\x6a\\xf5\\x6c\\x57\\xdc\\xca\\xbf\\x63\\xa5\\x38\\xb0\\xfe\\x4b\\x6c\\x27\\xbc\\xf3\\x11\\xef\\x1c\\x59\\x0a\\x0f\\xcd\\x31\\xcb\\xfc\\xe8\\x80\\x08\\xb8\\x67\\x94\\x0f\\xf5\\xd6\\x8d\\x37\\x77\\x86\\x50\\x24\\xee\\xeb\\x78\\x29\\xe2\\xc2\\x8c\\xba\\xd5\\x0f\\x6e\\x9c\\x07\\x2a\\x9c\\x73\\x4c\\x3f\\xff\\xad\\x78\\x84\\x6b\\x19\\x00\\xfd\\xfc\\x3a\\x69\\x00\\x6e\\x9a\\x0b\\x6f\\xff\\x00\\x46\\x3e\\xb3\\xb7\\x70\\x51\\x5d\\x76\\xb9\\x71\\xf6\\x57\\xb0\\x08\\x0b\\x51\\xc3\\xba\\xde\\x75\\xf8\\x7b\\x90\\x17\\xe0\\x26\\xfc\\xe4\\x1f\\x91\\x13\\x60\\xb2\\x0d\\x80\\xa4\\x64\\x92\\x48\\xa4\\x8b\\x39\\x61\\x34\\xa0\\x25\\x88\\x14\\x5f\\x7b\\x86\\x03\\x7a\\xc0\\xcc\\x7e\\xdd\\xec\\x3c\\x27\\x3b\\xe3\\xa5\\x1d\\xcd\\x83\\x4c\\xdf\\xc9\\x8d\\xee\\x73\\xb9\\x13\\x18\\x68\\x6e\\x9c\\x94\\x25\\xfc\\xef\\xdb\\x18\\x39\\xb5\\xae\\x9b\\x1d\\x96\\x0a\\x1d\\x62\\x27\\x26\\xbe\\x61\\x98\\x15\\x58\\x45\\x31\\xc4\\xf0\\xc8\\xc3\\xf6\\xfc\\xb7\\xa2\\x5a\\x82\\xce\\xc2\\xa7\\xfb\\xa6\\xff\\x03\\xad\\x1a\\x3d\\xe8\\x6c\\xe0\\x5d\\xa7\\xe4\\x31\\x46\\xfb\\xf5\\xfc\\x72\\x29\\x09\\xc6\\x32\\xe1\\x9e\\x8f\\x0e\\xd3\\xed\\xe8\\x0f\\xc3\\x1f\\xb5\\x0b\\xfd\\x6a\\x44\\x94\\xc5\\x68\\xa9\\x88\\x60\\x1c\\xc1\\x10\\xfe\\x21\\x92\\x4f\\x70\\x68\\xa4\\x92\\x65\\x4a\\xc8\\xf4\\x7f\\x0f\\xc7\\x80\\xd9\\x4b\\x04\\x73\\x94\\x8d\\xd0\\x56\\xab\\x4c\\x2d\\xcb\\x1c\\x20\\xe0\\x16\\x46\\x32\\xb8\\xcf\\xa0\\x4d\\xa6\\xc2\\xc9\\x9a\\xd6\\xbc\\xc9\\xea\\x54\\x85\\x53\\x9b\\x59\\x98\\xb9\\xa3\\x91\\x39\\x7c\\x94\\xd8\\x33\\x00\\x75\\xde\\x11\\xbb\\x0a\\x45\\x27\\x66\\x75\\xc4\\xd0\\x5a\\xe7\\x48\\x55\\xbb\\x2b\\x1f\\x64\\xf5\\x83\\x63\\xf7\\x3d\\x81\\x85\\xd0\\x1e\\x3a\\x03\\x19\\x99\\x6b\\xc6\\xdf\\x7b\\xf6\\xe7\\x0c\\x86\\x7d\\xbf\\x50\\x2d\\xeb\\x1c\\x68\\x64\\x8d\\x0e\\x13\\x74\\xa4\\x65\\x2c\\xf7\\x0c\\xcb\\x30\\xc0\\x53\\x4b\\x1c\\x13\\xf4\\x5a\\xc1\\x5b\\x08\\x51\\x85\\x87\\x3c\\xeb\\x2c\\xa8\\xe5\\x64\\x5a\\x38\\xeb\\x4a\\xda\\x72\\x42\\x52\\xd2\\xec\\x35\\x24\\x07\\xcf\\x2b\\x24\\xa1\\xdd\\xd4\\xcb\\x26\\x1f\\x8d\\x85\\x1b\\xb6\\x9b\\xe9\\xb7\\x00\\xa9\\x3a\\x08\\xb2\\x34\\xab\\x6d\\xd7\\x51\\x38\\xf5\\x97\\x5d\\x37\\xc1\\x25\\xc2\\x51\\xd8\\xa5\\x8e\\x60\\xd8\\x1f\\x6a\\x7c\\x76\\xe0\\xd8\\x3c\\x30\\x78\\xe6\\x80\\x6c\\xef\\xd7\\x7c\\xfc\\x0a\\x96\\xc9\\xa5\\xff\\xce\\x3c\\x95\\x5e\\x58\\x0d\\xa5\\xd6\\x92\\xac\\x40\\x74\\x42\\xb6\\x78\\x0c\\x66\\x38\\x04\\xe3\\xfc\\xdc\\x73\\xc2\\x49\\x10\\x86\\xb0\\x83\\x6c\\xaa\\xca\\x3c\\xcf\\x55\\x74\\xe5\\x32\\x38\\xea\\x65\\xcc\\x10\\x5f\\xf5\\x2f\\x67\\x2e\\x64\\x46\\x20\\x13\\xad\\xa5\\x9e\\xe5\\x25\\x4b\\x23\\x5a\\x5a\\x5e\\xb2\\x23\\x6f\\x79\\x9d\\x39\\xe8\\x1b\\x7b\\xe2\\x17\\x0c\\xd7\\xde\\x41\\x94\\xf7\\xa7\\xcf\\x7c\\x70\\x74\\x1d\\x1e\\x82\\x47\\xc7\\xe3\\xbc\\xf7\\x12\\x1b\\x46\\x03\\x7d\\x66\\x9e\\xa3\\xfc\\x02\\x12\\x84\\xd3\\xd8\\xf0\\x9b\\x72\\x60\\x9e\\x1a\\x62\\x78\\xe3\\x6c\\x82\\xc8\\x72\\xf3\\x39\\x7c\\x5f\\x9f\\x3c\\x32\\x78\\x60\\xb3\\xf1\\x4f\\xb0\\x23\\x77\\x00\\x0e\\xbf\\xc3\\xfb\\x10\\x90\\x34\\x98\\x77\\x3c\\xf3\\x94\\x7f\\xc6\\x2c\\x4b\\x27\\xd0\\x52\\xc1\\xeb\\xc9\\xcb\\x97\\xc4\\x9e\\xfb\\x99\\x04\\xcd\\xc1\\x29\\xfa\\x25\\x81\\x4f\\xb8\\x6b\\x0e\\x9f\\x8d\\x86\\xdf\\x36\\xfb\\x56\\xca\\x5a\\x4b\\x65\\x66\\x3c\\x5c\\x55\\xb2\\x38\\x48\\xaa\\xbb\\x4e\\x86\\xe2\\x87\\xdc\\x54\\x7b\\x75\\x06\\x21\\xe9\\x67\\x36\\x4e\\xfd\\xcc\\x05\\xa8\\x9f\\x29\\xd9\\x96\\xff\\x92\\x67\\x38\\xea\\xce\\x56\\x55\\xb9\\xfa\\xed\\x6c\\x7d\\x53\\xe1\\x0f\\x28\\x74\\xdd\\xdc\\xd7\\xf8\\x6b\\xbf\\xc3\\xbf\\x66\\x63\\x88\\xbf\\x4c\\x15\\xed\\xaf\\xbd\\x3e\\xeb\\x6b\\x74\\xd6\\x57\\xe7\\x0c\\xad\\xdd\\x67\\x18\\x24\\x7c\\x86\\xc1\\xc5\\x67\\xbf\\xc9\\x47\\x28\\xf7\\x37\\xf9\\xb8\\x53\\xb2\\x6d\\xcd\\x8f\\xfd\\xee\\xcc\\x86\\x61\\x6c\\x65\\xbd\\x27\\x81\\x53\\xd0\\x89\\xc8\\xdc\\xd4\\xc0\\xa3\\x35\\xd6\\x36\\xf3\\x13\\x9c\\xd4\\xcc\\x75\\x5d\\x8d\\xfd\\x0d\\x68\\xc9\\x18\\xb5\\x69\\x5d\\x2c\\x6a\\x1f\\x8b\\xf8\\x67\\x2d\\x2e\\xfe\\xb1\\xfc\\xd4\\x7e\\xda\\xbf\\x7b\\xfb\\xee\\xdd\\xa7\\x87\\xaf\\xe6\\xf9\\xb4\\x1b\\x5c\\xbf\\x00\\xa0\\xb1\\x9d\\x6a\\x1e\\x1e\\xc7\\x23\\x7f\\xd1\\xec\\x7a\\x62\\x68\\x43\\x03\\x02\\x44\\x0f\\x63\\x0c\\x4b\\x6d\\xf6\\x03\\x01\\x8b\\xa5\\x68\\x51\\x39\\xef\\xf7\\x95\\xaf\\x98\\xd9\\xce\\x9f\\xaa\\x01\\xd2\\xed\\x06\\x6d\\xf0\\xbc\\x72\\xa1\\x1a\\xc3\\x12\\x00\\xb3\\x10\\xcc\\x8d\\x42\\x86\\x7f\\xba\\xee\\xca\\x1a\\x21\\x79\\x69\\xb4\\xf5\\xbb\\xa6\\x5a\\xff\\x28\\x8b\\xf5\\x63\\x8c\\xc5\\x03\\xe0\\xc4\\xc5\\xfa\\xf1\\x6f\\x45\\xa9\\xa7\\xd3\\xd4\\x5e\\x01\\x4d\\x08\\x78\\x5d\\x80\\x83\\x9d\\x88\\xc2\\x49\\x9d\\xc9\\xe5\\x2f\\x57\\x1f\\xbe\\x17\\x41\\x48\\xd2\\x95\\x8f\\x72\\x15\\x5f\\xc1\\xb3\\xef\\xec\\x8b\\xc4\\x16\\x2e\\x11\\xbc\\x44\\x3c\\xf0\\xab\\xd9\\xaa\\xd8\\xca\\xea\\x4d\\xd1\\x4a\\xf1\\x91\\x5f\\xa1\\xf1\\xfb\\x1e\\x9e\\xbf\\xf7\\xd0\\xfa\\xf0\\xc8\\xf7\\xfb\\xad\\x54\\xe5\\x6a\\x84\\x4f\\x04\\x9f\\xa2\\xd2\\x2d\\x06\\xc1\\x4e\\x47\\xe8\\xd0\\xd1\\x5b\\x18\\xad\\x73\\x52\\xb6\\xdf\\x17\\xdf\\x53\\x19\\x92\\xd7\\x4b\\x04\\xbe\\xd7\\xaa\\xdc\\x3e\\x8f\\x93\\x04\\x08\\x62\\x54\\x46\\xc1\\x12\\x7f\\x06\\x37\\xf8\\x23\\x27\\xee\\xa9\\x7e\\x00\\x20\\xb2\\x78\\x92\\xe0\\xdf\\x59\\xb1\\x5d\\xbb\\xdf\\x94\\x60\\xa0\\x11\\xe1\\xcb\\x7c\\x84\\x29\\xfe\\xca\\x8e\\xce\\xbf\\x6b\\xf1\\x66\\xf6\\xeb\\x5f\\x4d\\x4e\\xfe\\x57\\xf3\\xfb\\x45\\xcf\\xf3\\x53\\x37\\x6f\\x9a\\x7a\\x53\\x95\\xab\\x51\\x5c\\xa7\\x37\\xb3\\x17\\x46\\xfb\\x4b\\x12\\x6a\\x7e\\xfd\\x55\\x03\\x55\\x8a\\x2b\\xcb\\xdf\\xb1\\x97\\x7f\\xd7\\x8c\\x5f\\x1d\\xf9\\x28\\x16\\x7a\\x98\\xcf\\x14\\x75\\x65\\xb2\\xb2\\xc5\\xff\\x09\\x00\\x00\\xff\\xff\\x49\\x22\\x74\\xca\\x83\\x5d\\x01\\x00\")\n\nfunc cmdInternalPagesAssetsJsJquery351MinJsBytes() ([]byte, error) {\n\treturn bindataRead(\n\t\t_cmdInternalPagesAssetsJsJquery351MinJs,\n\t\t\"cmd/internal/pages/assets/js/jquery-3.5.1.min.js\",\n\t)\n}\n\nfunc cmdInternalPagesAssetsJsJquery351MinJs() (*asset, error) {\n\tbytes, err := cmdInternalPagesAssetsJsJquery351MinJsBytes()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tinfo := bindataFileInfo{name: \"cmd/internal/pages/assets/js/jquery-3.5.1.min.js\", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)}\n\ta := &asset{bytes: bytes, info: info, digest: [32]uint8{0x61, 0x50, 0xa3, 0x5c, 0xf, 0x48, 0x6c, 0x46, 0xca, 0xdf, 0xe, 0x23, 0xe, 0x2a, 0xa1, 0x59, 0xc7, 0xc2, 0x3e, 0xcf, 0xbb, 0x56, 0x11, 0xb6, 0x4e, 0xe3, 0xf2, 0x5f, 0xcb, 0xff, 0x34, 0x1f}}\n\treturn a, nil\n}\n\nvar _cmdInternalPagesAssetsJsLoaderJs = []byte(\"\\x1f\\x8b\\x08\\x00\\x00\\x00\\x00\\x00\\x00\\xff\\xbc\\xbd\\x79\\x97\\xda\\xb6\\xf7\\x38\\xfc\\xff\\xbc\\x0a\\x70\\x5b\\x2a\\x05\\x8d\\x81\\x99\\x49\\xda\\xd8\\x51\\xf8\\x4d\\xb3\\xb7\\xd9\\x3e\\x59\\xba\\x11\\x9a\\x23\\xc9\\x32\\x38\\x18\\x4c\\x6d\\x33\\x4b\\xc0\\xef\\xfd\\x39\\xda\\x6c\\x19\\x4c\\x32\\xd3\\xc9\\xf7\\x39\\x27\\x61\\x6c\\x59\\xba\\xda\\xae\\xee\\xa6\\xab\\x2b\\x10\\xae\\x16\\x2c\\x8f\\x92\\x05\\x80\\xeb\\xde\\xad\\x83\\x83\\xd6\\x83\\x64\\x79\\x99\\x46\\x93\\x69\\xde\\x7a\\x37\\xe5\\xad\\x07\\x71\\x92\\xad\\x52\\xde\\x7a\\x1e\\xd1\\x94\\xa4\\x97\\xad\\xd3\\x55\\x3e\\x4d\\xd2\\xcc\\x3d\\x68\\xbd\\x7d\\xfd\\xf0\\xcf\\xc3\\xe7\\x11\\xe3\\x8b\\x8c\\x1f\\x3e\\x0b\\xf8\\x22\\x8f\\xc2\\x88\\xa7\\x5e\\xeb\\x74\\x49\\xd8\\x94\\x1f\\x1e\\xb9\\xfd\\x83\\x5b\\xbd\\x83\\x1f\\x57\\x19\\x6f\\x65\\x79\\x1a\\xb1\\xfc\\x47\\xff\\x8c\\xa4\\xad\\xb9\\x6f\\x6a\\x6c\\x11\\x02\\x08\\x5c\\x8b\\x44\\x8a\\xfb\\x7e\\xca\\xf3\\x55\\xba\\x68\\x59\\xed\\xd1\\x29\\xf4\\x1e\\x71\\x63\\xbe\\x98\\xe4\\xd3\\xe1\\x3a\\x48\\x16\\xdc\\x6b\\x0f\\xd0\\x19\\x89\\x57\\xdc\\x23\\x23\\xda\\xed\\x8e\\x0b\\x4f\\x27\\xf7\\x8b\\xa2\\x28\\x81\\x2f\\x2a\\xd8\\xce\\x6a\\x11\\xf0\\x30\\x5a\\xf0\\xc0\\x69\\xe3\\xfc\\x72\\xc9\\x93\\xb0\\xf5\\xf6\\x72\\x4e\\x93\\xb8\\xd3\\x51\\x7f\\xdd\\x28\\xe7\\x29\\xc9\\x93\\xb4\\xd3\\x21\\xa3\\xad\\xa4\\xb1\\x69\\x19\\x1d\\x52\\x97\\x91\\x38\\x06\\x04\\x7a\\xeb\\x05\\xbf\\xc8\\x3d\\xd9\\x01\\xab\\x4e\\x2a\\x3b\\x14\\x85\\xa0\\x0d\\x48\\x2b\\x5a\\x64\\x39\\x59\\x30\\x51\\xd9\\x69\\x9a\\x92\\x4b\\x08\\xd7\\x04\\x8b\\x56\\xf9\\x61\\x92\\x02\\xd9\\x32\\xc4\\xf0\\x68\\xec\\xb7\\x01\\xc5\\xc4\\x15\\x00\\x01\\x84\\xae\\xe8\\x8a\\x0f\\x99\\xbb\\x5c\\x65\\x53\\x40\\x5d\\xd9\\x51\\xe8\\x13\\xcc\\x0a\\xdd\\x0c\\x52\\xd5\\xc7\\x08\\x20\\x88\\x22\\x06\\xd7\\xb5\\xea\\xde\\xe6\\x69\\xb4\\x98\\x74\\x3a\\x80\\x60\\xf5\\x08\\x08\\xac\\x6a\\x0d\\xb0\\x19\\x4e\\xc4\\x71\\xdf\\xe7\\xf7\\x02\\x9f\\x77\\xbb\\x6a\\xac\\x42\\x4c\\x46\\x7c\\xec\\x47\\x21\\xd0\\x5d\\x65\\x28\\x44\\x1c\\x11\\x08\\x55\\xe5\\xeb\\x97\\x1e\\x47\\xef\\xbc\\xb0\\x28\\xca\\xf7\\xc3\\x01\\x7a\\xe7\\x9d\\x25\\x51\\xd0\\xea\\x17\\xc5\\x81\\xac\\x80\\x60\\xc7\\x34\\xd1\\xc1\\x66\\xc0\\x5f\\xd1\\x4f\\x9c\\xe5\\xae\\x9a\\x88\\xd7\\x69\\xb2\\xe4\\x69\\x1e\\xf1\\x6c\\xd8\\x94\\x7e\\xe9\\x95\\x58\\xa0\\xfb\\x17\\x85\\x80\\x60\\x2c\\xc7\\xd1\\x5d\\xa6\\x49\\x9e\\x08\\xa8\\x9b\\x0d\\xc1\\x58\\x97\\x2f\\x13\\xa1\\x19\\x26\\x9f\\x8c\\xe8\\x18\\x33\\x35\\x82\\x7e\\x39\\x78\\x15\\xfa\\x71\\x39\\x5b\\x04\\x8f\\x9c\\x44\\xc2\\xa8\\xda\\x3a\\x89\\x13\\x4a\\xe2\\x77\\xd3\\x28\\xeb\\x74\\xaa\\x67\\x44\\xd0\\x4e\\xce\\xf3\\x68\\x11\\x24\\xe7\\x9d\\x8e\\xfa\\xbb\\xfb\\x3d\\xe3\\x71\\xd8\\xe9\\x88\\xdf\\xdd\\x6f\\x0a\\xb2\\xa9\\x61\\x5c\\xa1\\x05\\xee\\xfb\\x15\\xce\\xfb\\xdd\\x2e\\x55\\x93\\xc3\\xb0\\xe8\\x91\\x98\\x1c\\xd6\\xe9\\x30\\xf7\\x05\\xc9\\xa7\\x18\\x8b\\x5f\\xd3\\x65\\x56\\xe4\\xd3\\x34\\x39\\x6f\\x3d\\x4a\\xd3\\x24\\x05\\xce\\x03\\xb2\\x58\\x24\\x79\\x2b\\x8c\\x16\\x81\\xae\\xab\\xa5\\x9b\\x00\\xfd\\x42\\xce\\x36\\xc1\\x9c\\x80\\x7c\\x1a\\x65\\xd0\\x3f\\x28\\x87\\xe5\\x5f\\x31\\xe6\\x72\\xc4\\x29\\x24\\x9e\\xae\\x39\\x24\\x3e\\xc1\\xc4\\xcd\\x96\\x71\\x94\\x03\\xc7\\x75\\x6c\\x74\\xea\\xfb\\x41\\xd9\\xda\\xc3\\x81\\x1f\\x18\\x64\\xe2\\x98\\x8c\\x02\\xd9\\xde\\x36\\xe0\\xad\\x68\\xd1\\x62\\x10\\xd2\\x94\\x93\\x59\\x8b\\xf8\\x0c\\xb3\\x11\\x1f\\x17\\x04\\x93\\x51\\x55\\x74\\xec\\x07\\x98\\x8d\\xc8\\xd8\\xa7\\x98\\x82\\x00\\xfa\\xb4\\x8d\\x83\\x4e\\x67\\xb1\\x8a\\xe3\\x36\\xa6\\x9d\\x4e\\x40\\x00\\x43\\x04\\xad\\x59\\xb2\\x08\\xa3\\xc9\\x2a\\x25\\x34\\x16\\x8b\\x1e\\x9d\\xa7\\x51\\x6e\\x9e\\x15\\x5d\\xa0\\x05\\x2c\\x8a\\x7f\\x81\\xb3\\x85\\x2f\\xae\\x18\\x8a\\x67\\x8b\\x80\\x5f\\x38\\xa8\\x42\\xb0\\x92\\xce\\x90\\x21\\xa9\\xf0\\x4e\\x62\\x9d\\x19\\x57\\x35\\x48\\x12\\x13\\xdd\\x97\\x45\\x01\\xfd\\x3d\\xb0\\x6f\\x00\\xf6\\x9d\\x00\\x5b\\x4d\\x42\\x6a\\x21\\xbe\\x18\\x00\\x8c\\x09\\x54\\x93\\xbb\\xe0\\xe7\\xad\\x77\\x97\\x4b\\xae\\x27\\x59\\x10\\xe9\\x1f\\x05\\x98\\x1f\\x5b\\xb2\\xef\\xad\\x30\\x49\\x35\\x01\\xb0\\x1a\\xe7\\x74\\x59\\xd7\\x69\\xcd\\x57\\x59\\xde\\x12\\x28\\x41\\x79\\x4b\\x00\\x6d\\x25\\x69\\xab\\x22\\x8d\\x50\\x2e\\x7b\\x9b\\x8e\\xbc\\xe1\\x93\\x47\\x17\\xcb\\xe6\\x7a\\x1f\\x47\\x69\\x96\\xb7\\x48\\x3a\\x59\\xcd\\xf9\\x22\\x6f\\xe5\\xc9\\x55\\x2a\\x25\\xad\\x94\\x4f\\x56\\xb1\\xc0\\x8d\\x8b\\x65\\xca\\xb3\\x4c\\x50\\x08\\x58\\xae\\xcd\\xae\\xe3\\x88\\x59\\xdb\\x01\\xc4\\x17\\x41\\xf6\\x47\\x94\\x4f\\xaf\\x38\\xbc\\x0a\\x2b\\x53\\x33\\xb8\\x4e\\x59\\x1c\\xfa\\x8a\\x4e\\x61\\x8c\\x59\\xa7\\x03\\x18\\x0e\\x34\\xea\\x41\\x9f\\xc9\\x85\\xe4\\xce\\xc9\\x05\\xe8\\x23\\xf5\\x18\\x2d\\x00\\xdb\\xf4\\x51\\x99\\xa7\\x42\\x79\\x8e\\xa9\\x59\\x9c\\xfd\\x7b\\xbc\\xd3\\xe9\\xdf\\x63\\x3e\\x8c\\x42\\x10\\x8c\\x0e\\x0f\\xd9\\xb8\\x8d\\xe9\\xe8\\xf0\\x90\\x8f\\xf5\\xaa\\x6c\\x0f\\x4c\\xff\\xfa\\xf7\\x31\\x97\\xb3\\xdc\\xd4\\xc7\\x2c\\x27\\x69\\x7e\\x93\\x5e\\x5a\\x00\\x20\\xe2\\x65\\xd7\\x50\\x58\\x35\\xf6\\x5a\\x9d\\x9c\\xe0\\xbe\\x3f\\xb9\\x17\\x76\\x3a\\xec\\x1e\\xd7\\xbd\\x63\\xdd\\xae\\xec\\xdd\\xa4\\xdb\\xdd\\xed\\xdd\\xe4\\x3e\\x0e\\xf5\\xd2\\xd8\\xe9\\x5c\\xca\\x97\\x9c\\xe4\\x57\\xe8\\x98\\x21\\x74\\xba\\x5b\\x02\\x49\\x91\\xa3\\x4b\\x4b\\xfc\\xec\\xdf\\xa7\\x9b\\xcd\\xe0\\xf8\\xe4\\x68\\xf0\\xd3\\x4f\\x47\\x3f\\xdd\\xbd\\x47\\x2d\\xec\\x7c\\x43\\x16\\x13\\x83\\x9e\\xcf\\x16\\x67\\x24\\x8e\\x82\\x16\\x4b\\x56\\x8b\\x5c\\xad\\x0c\\x07\\xfa\\x74\\x83\\xfb\\x16\\xe1\\x72\\x1c\\x9f\\xca\\xae\\xd1\\xce\\xa0\\xd3\\x01\\x41\\x17\\x33\\x88\\xe8\\xfd\\xfb\\xf7\\xf1\\x00\\xb2\\x2e\\x66\\xa6\\x6b\\xc1\\xde\\x59\\xcb\\xd3\\x68\\xfe\\x9c\\x87\\x5b\\x5d\\xab\\xe4\\x81\\x4a\\x88\\x11\\xfd\\x11\\xe3\\x10\\x13\\xc6\\x41\\xef\\x9f\\xd1\\x87\\xec\\xc3\\x05\\xe9\\x8f\\xbb\\x3d\\xe4\\x38\\xb0\\x64\\xed\\x9b\\x0d\\xdd\\x33\\x84\\xa2\\xa6\\xb7\\x62\\x8a\\x9b\\x47\\x71\\xb3\\xd9\\xdb\\x36\\xdd\\xf6\\xd7\\x69\\x32\\x8f\\x32\\xbe\\xb7\\xa5\\x13\\xb8\\x96\\x6d\\x14\\xdc\\x47\\x3e\\x30\\xac\\x56\\x8b\\x7a\\x23\\x42\\x52\\x11\\xc3\\x36\\xc5\\xf2\\x7d\\x02\\xa0\\x9f\\xa7\\x97\\xeb\\x09\\x98\\xba\\x29\\xcf\\x92\\xf8\\x8c\\x23\\xf1\\x24\\xf8\\x0b\\x2c\\x18\\xc9\\xd9\\x14\\xcc\\xe0\\xda\\x24\\x81\\x99\\x2d\\x27\\x31\\xa0\\x2b\\x23\\x58\\x4c\\x71\\xf5\\x21\\x10\\xcd\\x30\\x08\\x65\\x93\\x22\\x3a\\x9c\\x78\\x62\\x8e\\x69\\x25\\xaf\\x4e\\xe1\\x7a\\x0a\\x26\\xb0\\x80\\x85\\x10\\x0e\\x2a\\xb6\\xcf\\xac\\x31\\xa0\\xb8\\xcc\\x3e\\xb1\\x68\\xa9\\xaa\\xbb\\x6c\\x43\\xad\\x67\\xba\\xf3\\xb6\\x5c\\x3c\\x75\\xa7\\x40\\xd4\\xa3\\xb2\\x2b\\xc9\\x6c\\x02\\x0b\\x5f\\xd1\\x82\\x90\\xb8\\x19\\xcf\\xdf\\x45\\x73\\x9e\\xac\\xf2\\x5a\\xed\\xac\\x56\\x3b\\x07\\x13\\xd4\\x87\\x45\\x2d\\xc7\\x14\\x5b\\xd5\\x08\\xc4\\xd4\\x83\\xdd\\xe9\\xe8\\xba\\xf4\\xca\\x55\\xeb\\x62\\xa2\\x1b\\x6e\\xcd\\x88\\x41\\xe6\\x29\\xee\\xfb\\xd3\\x7b\\x93\\x4a\\x66\\x98\\xaa\\x22\\x33\\x7c\\x30\\x19\\x4d\\xc7\\xbe\\xf8\\x91\\x63\\x2d\\x27\\x6d\\x06\\xcc\\x14\\xc5\\x7a\\x10\\x26\\x20\\x86\\x45\\x51\\xd8\\x93\\x52\\x6b\\xe8\\xa4\\xd6\\x95\\xdd\\x21\\x52\\xab\\x70\\xe2\\x17\\xb0\\xf0\\x69\\x73\\x39\\x0b\\xdb\\x44\\x6d\\xeb\\x6d\\x79\\x7f\\x09\\xd7\\xb3\\xcd\\x06\\xcc\\x70\\xbb\\x8f\\x62\\x25\\x7d\\x4e\\xd1\\x12\\xc2\\xa2\\xa8\\x26\\x07\\xcd\\x70\\x49\\x71\\xd6\\x1a\\xed\\xbc\\x89\\x24\\x16\\xee\\x2f\\x10\\x29\\x5c\\x33\\x09\\x53\\x58\\xd4\\x1b\\xf3\\xcb\\x36\\x36\\x4c\\xb0\\xc2\\x05\\xa8\\xf2\\x83\\x2d\\x1e\\x77\\xda\\xd2\\x8b\\xa6\\xc5\\x94\\x28\\xa5\\x6b\\x14\\xdc\\x2e\\xca\\x85\\x50\\xe7\\x40\\xe8\\xf3\\x38\\xe3\\x2d\\x01\\xac\\x86\\xaf\\x0a\\xe4\\x53\\x30\\x51\\x19\\xd6\\xc4\\xcb\\xce\\x23\\x31\\xe2\\x46\\xf8\\x83\\x6b\\x46\\x32\\xde\\x32\\x52\\xa1\\xa7\\x3a\\xa9\\x84\\x9d\\x89\\x5f\\xca\\x49\\x32\\x4f\\x29\\x4d\\x7b\\x53\\xdc\\xee\\x97\\x1f\\x03\\x1e\\x92\\x55\\x9c\\x8b\\xc4\\x41\\x31\\x1d\\xca\\x1a\\x4f\\xc1\\x04\\x7a\\xf2\\x29\\x12\\x38\\x5a\\xf8\\x07\\xf6\\x08\\x9c\\xd6\\x46\\x40\\x55\\x69\\x56\\x79\\x7a\\xb9\\x9e\\xe2\\x89\\x9b\\x4f\\xf9\\xa2\\x5a\\xbf\\x7a\\x60\\x66\\x86\\x49\\x17\\x0d\\x92\\xbd\\xae\\xf9\\x31\\x98\\xa2\\x5a\\xdd\\xb5\\xb1\\x9f\\xee\\x22\\xd0\\x27\\x70\\x84\\xb6\\xb3\\x45\\x4d\\xd9\\x06\\x3b\\xd9\\x3e\\x59\\xd9\\xd0\\x54\\xce\\x65\\xbf\\xad\\x56\\x87\\xe1\\x08\\x75\\x21\\x38\\xe3\\x79\\x1e\\x73\\xe0\\x74\\x27\\x5d\\x07\\xb5\\x9c\\xee\\xb4\\xeb\\x40\\xaf\\x9c\\x5e\\x12\\xa7\\x9c\\x04\\x97\\x3a\\x57\\x20\\x64\\xd5\\x2c\\x27\\x39\\x77\\xba\\x1a\\xa4\\xaf\\x49\\xe3\\xc4\\x90\\xc6\\xa9\\x7a\\x98\\x83\\xad\\x86\\xcd\\x6d\\x7c\\xd7\\xf4\\xa6\\x5d\\xd2\\x9b\\x3a\\x6f\\xad\\x2f\\xf1\\x6e\\x77\\x02\\x43\\x97\\x2a\\xd4\\x25\\xa3\\xc9\\x18\\xfa\\xf6\\x6a\\x54\\xd4\\x26\\xc4\\x02\\x45\\x59\\xad\\xca\\xa7\\x0d\\x73\\x5a\\x92\\xe8\\x83\\x89\\xfb\\xa4\\x91\\x42\\xd7\\x40\\x3c\\xde\\x1a\\x4e\\x45\\x39\\xea\\x74\\xde\\xac\\xc8\\x59\\x09\\x6c\\xb6\\x45\\xee\\x63\\xb8\\x36\\x49\\x92\\x9a\\xd4\\xaa\\x10\\x68\\xb5\\x55\\x4b\\x49\\x0e\\x66\\xe0\\x14\\x3d\\x31\\x04\\xa1\\x01\\xc1\\x4e\\x87\\x65\\xc1\\x95\\xa0\\xda\\xe9\\xe5\\x3a\\x06\\xa7\\xe2\\xd9\\x54\\x7d\\x46\\xe0\\x7a\\x29\\x7e\\x8b\\xc2\\x7b\\x22\\xe9\\x45\\x8c\\x96\\xe8\\x02\\x6f\\xb1\\x0c\\x59\\x4d\\x8c\\x4f\\xfd\\x25\\x7e\\x52\\xe8\\xf1\\x7d\\x02\\x66\\x60\\x82\\x62\\x88\\x66\\x8a\\xdc\\x18\\xa6\\x7f\\x51\\x6f\\xbf\\xac\\xa7\\x36\\xd2\\x36\\x63\\x17\\xbd\\x03\\x6a\\x21\\xed\\xe0\\xea\\x93\\xfd\\xdd\\x86\\x6b\\x4d\\x14\\x62\\x97\\x6a\\x7a\\x30\\xf0\\x26\\x20\\x76\\x19\\x54\\x8b\\x5c\\xad\\xff\\x23\\x6f\\x6a\\xa7\\x99\\x65\\x5f\\xc3\\xf3\\xf7\\x0b\\x7e\\xb1\\xe4\\x2c\\xe7\\x81\\x42\\x5d\\xaf\\xe5\\x74\\x0f\\x04\\x58\\x5f\\xd1\\xcf\\x58\\x31\\x37\\x9b\\xff\\x0d\\x05\\xba\\xcd\\xf4\\x8a\\xd5\\x6c\\x6d\\x26\\x1b\\xaf\\x67\\x18\\x07\\xf2\\x59\\x4c\\x68\\x53\\xcf\\xb7\\xf9\\x31\\x9a\\xc1\\xf5\\x4c\\x71\\x64\\x51\\x8e\\x30\\x7e\\xd5\\x52\\x66\\x5d\\xc4\\x58\\xe4\\x44\\x4b\\x1c\\x6b\\x73\\x88\\xdf\\x5e\\x2a\\x83\\x48\\x95\\x04\\x03\\xb0\\xd4\\x56\\x11\\x81\\xda\\x68\\xa6\\xeb\\x23\\x71\\xdc\\xb0\\x10\\x24\\xbc\\x19\\x9e\\x1a\\x78\\xba\\x11\\x33\\x09\\x75\\x18\\x80\\xd1\\x18\\x6e\\xcb\\x15\\x31\\x5a\\x5a\\x93\\x74\\x21\\x51\\x6e\\x9b\\x57\\x09\\x7c\\x3b\\x1d\\xad\\xc8\\x18\\x9f\\x11\\xff\\xc9\\xe1\\xa1\\xdf\\xc7\\xf8\\x49\\xa7\\x13\\x83\\x53\\xcd\\xae\\x4e\\xf1\\x68\\x8c\\x9e\\x08\\xd5\\x38\\x69\\x9d\\xaa\\xa1\\x55\\xe8\\x01\\xd1\\x93\\x6e\\x17\\x05\\x60\\x56\\xf5\\xe1\\x02\\x9c\\x96\\x2a\\x30\\x44\\xcb\\x5a\\x7b\\xcf\\xa7\\x51\\xcc\\x41\\x5b\\xb5\\x57\\xf6\\xd4\\x18\\xa3\\xb4\\x58\\xa7\\xcd\\x1f\\x51\\x76\\x3d\\xdd\\x93\\x0a\\x1d\\x68\\xd8\\x6f\\x63\\x2c\\xe4\\xe9\\x9e\\x78\\x1d\\xf4\\x98\\x47\\x45\\x42\\xa7\\xc3\\xda\\x18\\xb3\\x3d\\x7a\\x6e\\xb4\\x60\\xf1\\x2a\\xe0\\x57\\xad\\x4f\\x49\\xda\\x12\\xf7\\x82\\x46\\x1b\\x55\\x60\\x6c\\x54\\x01\\x84\\x5a\\xa2\\x0a\\x2a\\x85\\x85\\x6d\\x36\\x4a\\x62\\xef\\xdf\\x57\\x2a\\x5b\\xa9\\xc1\\xb0\\x2e\\x47\\x7d\\x08\\x7d\\xa1\\x9e\\xb0\\xca\\x7e\\x15\\x8c\\x98\\x34\\x39\\x84\\x58\\x76\\xad\\x1c\\x1e\\x10\\x22\\x6a\\xac\\x58\\xed\\x7e\\x61\\xb4\\x97\\x7d\\x1a\\xcb\\x35\\x7b\\xa9\\x3e\\x1c\\x0e\\xda\\xd8\\xd2\\xc8\\x4a\\x18\\xd0\\x8d\\x16\\x01\\xbf\\x78\\x15\\x8a\\xcc\\x9b\\x4d\\x1f\\x1a\\x7d\\x62\\x7b\\x6c\\x59\\xb2\\xbc\\x14\\x1a\\x5c\\xb4\\xd8\\x2b\\xa6\\x33\\xb8\\x66\\xf8\\xe5\\x6a\\x4e\\x79\\x0a\\x58\\x89\\xcf\\xcf\\x16\\x61\\xb4\\x88\\xf2\\x4b\\x31\\xab\\x9b\\xcd\\xa1\\xfd\\x3a\\x64\\x1e\\xdb\\xf4\\x8b\\xa6\\xa6\\x33\\x14\\x20\\x6e\\x06\\x4e\\x52\\x81\\x72\\xdc\\x45\\x45\\x7e\\xa0\\xcc\\x30\\x1c\\x97\\x6a\\x33\\x1f\\x86\\x1e\\x05\\x5c\\xe8\\xcb\\xfd\\xfb\\x6c\\x58\\x4e\\x46\\xd8\\x65\\xa8\\x0f\\xbd\\x4a\\xa7\\x44\\xa1\\x28\\xde\\xbf\\x1f\\xd8\\x79\\x82\\x5a\\x9e\\x40\\xe4\\xe1\\xb8\\x7f\\x9f\\xdb\\x79\\x78\\x2d\\x0f\\x17\\x79\\xa2\\x10\\xb0\\x7b\\x01\\x94\\xe2\\x71\\x20\\x94\\x51\\xc9\\xa0\\x45\\x7b\\xa5\\xe0\\x21\\xd5\\x52\\xd9\\xfc\\x51\\xd0\\xed\\x8e\\x3d\\x10\\xf0\\x98\\xe7\\xbc\\x55\\x7e\\x43\\x41\\xb7\\xab\\xc5\\x34\\x01\\x83\\x63\\x1b\\x7c\\x37\\x38\\x64\\x10\\xb1\\x2e\\xe6\\x87\\x81\\xcf\\xef\\x07\\x3e\\x3c\\x3c\\xe4\\x75\\xf8\\x42\\xa9\\x57\\xf0\\xf9\\xd8\\xb3\\x81\\x8b\\x0f\\xbe\\xc5\\x06\\x4a\\x35\\x51\\x1a\\x90\\xf7\\x4e\\x21\\x97\\x92\\x81\\x28\\xb0\\x2d\\x31\\x36\\xd8\\x59\\x14\\xac\\x56\\x94\\x49\\x1b\\x0a\\x69\\xb1\\x64\\x91\\xe5\\xe9\\x8a\\xe5\\x49\\x5a\\x59\\x4e\\xa4\\x50\\x00\\x9c\\x4f\\x19\\x4b\\xe6\\xcb\\x8f\\x99\\x2c\\xf2\\xd1\\xe9\\x02\\xbe\\xd9\\x38\\x0e\\xec\\x3a\\x1f\\x9d\\x6e\\xd0\\xed\\x22\\x0e\\x6d\\x15\\x4c\\x8c\\xad\\xd1\\x80\\xb8\\x1f\\x68\\x63\\x94\\x13\\xf0\\x8c\\xa5\\xd1\\x52\\x72\\xe0\\xab\\xd8\\xda\\xc2\\x2f\\x2a\\x60\\x79\\xa2\\x96\\x16\\xde\\x35\\xeb\\xab\\xaa\\x95\\x5c\\x13\\x54\\xf6\\x7f\\x5a\\x1b\\xc4\\xd2\\x0a\\x5f\\x1f\\xcd\\x7a\\x85\\x04\\xab\\xcc\\xbb\\x85\\x2c\\x5b\\x3b\\x56\\xab\\xad\\xf5\\x6c\\x91\\xff\\xac\\x9e\\xde\\x47\\xf5\\xc7\\x07\\x31\\x99\\x2f\\x79\\x50\\x66\\x1b\\xdc\\xa9\\x3e\\x9a\\xe7\\x67\\x8b\\xfc\\xf8\\xa8\\x4a\\x36\\xcf\\x8f\\xe3\\x84\\xd4\\x5f\\xee\\x9c\\xc8\\x17\\xc7\\x98\\x4c\\x5b\\x0e\\x44\\x0c\\xf7\\x7d\\x76\\xaf\\x32\\xc7\\x18\\xaa\\x15\\xe0\\x90\\x8c\\xe8\\x88\\x8d\\xc7\\xbe\\x2d\\xfd\\x18\\xf1\\x27\\xe8\\x74\\xaa\\xe4\\x72\\x03\\x23\\xa8\\x46\\x79\\x44\\xc6\\xd2\\x3a\\x6a\\x25\\x5d\\xcd\\x4e\\xba\\x3b\\x29\\x53\\x02\\x88\\x36\\x09\\x0b\\x2a\\x55\\xed\\x39\\x28\\x32\\xa9\\x86\\x97\\x64\\x97\\x0b\\xf6\\xac\\x71\\x62\\x2c\\x32\\xb3\\x35\\x27\\xf5\\x42\\xb0\\x66\\xed\\x9c\\x6a\\x4b\\xbc\\xde\\x55\\x29\\xfc\\xdd\\x4d\\x98\\x3d\\x08\\x54\\xf8\\xbb\\xbb\\x22\\x11\\x51\\x16\\xec\\x3d\\x7b\\x22\\x5d\\xec\\x38\\x8a\\xd3\\x30\\xdc\\x47\\x81\\xae\\xb4\\x2e\\xb6\\xb3\\xd2\\xa0\\x6d\\x4c\\xd9\\xac\\xdb\\x35\\x7a\\xa7\\xb6\\x31\\x03\\x8e\\xc8\\x88\\x8f\\x21\\xd2\\x7b\\x52\\x45\\x11\\x48\\xae\\xbd\\xdb\\x52\\xb3\\x3d\\xa5\\x47\\xdd\\x6c\\x96\\x94\\xe6\\x25\\xcd\\xec\\x8b\\xc2\\x0f\\xae\\xd2\\xef\\xa0\\x2a\\xd9\\x64\\xe4\\xe6\\x8b\\x3c\\x8d\\xae\\xc2\\xb9\\xca\\xd4\\x48\\xaf\\xfd\\x26\\x9e\\x36\\xa2\\x88\\x8d\\x8b\\xbd\\x1c\\x2b\\x8c\\xe2\\xf8\\x4a\\x3c\\x12\\x05\\x66\\x24\\x2d\\x46\\x23\\x98\\xfb\\x0e\\x63\\xef\\x23\\xde\\x65\\x50\\x92\\x7d\\x25\\xad\\x06\\x9b\\x4d\\x70\\x9f\\xc3\\x40\\x50\\x29\\xc3\\xfa\\x02\\xe8\\xf7\\xef\\x07\\x52\\x7c\\xa8\\x15\\x0c\\xb4\\x05\\xb3\\xe2\\x91\\x82\\xdf\\xfa\\xec\\x5e\\x20\\x97\\x9b\\xe2\\x09\\x63\\x4c\\xb7\\xc9\\x76\\x53\\xd7\\xe2\\x2b\\x9a\\x2c\\x69\\xc5\\x1f\\xe9\\x70\\xe0\\xd1\\x92\\xe6\\x30\\x21\\x04\\xaa\\xfd\\x11\\x9b\\xbb\\x5a\\x1b\\x24\\x8a\\x6b\\x8d\\x7d\\x55\\x77\\x94\\xc9\\xbf\\x80\\xc3\\x4e\\xa7\\x7f\\x8f\\x0e\\x01\\xdf\\xde\\xf1\\x92\\x8d\\x52\\x9a\\x18\\x47\\x54\\x88\\x8b\\x6a\\xa3\\xd0\\x25\\xcb\\x65\\x7c\\x09\\x18\\xe2\\x10\\x7a\\x7a\\xef\\x90\\x97\\xab\\x97\\xed\\x9d\\xbd\\x98\\xe4\\x2f\\xc8\\xf2\\x8a\\x42\\x4e\\x65\\x38\\x1d\\x8d\\xf5\\xd6\\xa1\\xdd\\x2d\\x6b\\x13\\xb1\\xdc\\x3c\\xd4\\x5c\\x13\\x71\\xa4\\x76\\x99\\xea\\xfd\\x0c\\xe1\\x30\\xb0\\x9b\\x2f\\x24\\x02\\x4f\\xa5\\x80\\xb0\\x6c\\x7d\\x50\\x6f\\x7d\\x98\\x26\\xf3\\x2b\\x63\\x1c\\xd3\\x06\\x15\\x21\\x05\\xd9\\x86\\x43\\x43\\xed\\x8c\\x0d\\x6f\\x34\\x46\\xe1\\xf5\\xb6\\x89\\xe9\\xee\\x36\\x71\\x14\\x82\\x06\\xe5\\x35\\x14\\x08\\x12\\xaa\\x01\\xa1\\x75\\xf3\\x7a\\x1b\\x88\\xa1\\xaa\\x6f\\xfc\\x72\\xd5\\x7d\\xa6\\x0a\\x04\\x28\\x54\\x7a\\x02\\x9a\\x74\\xbb\\x10\\x16\\xa5\\x10\\x53\\x59\\xf5\\x91\\x36\\xd4\\xfb\\x22\\xc7\\x76\\x69\\x3a\\x9a\\x8c\\xd1\\xa4\\x52\\x6a\\xf9\\x1e\\x5c\\x9f\\xf1\\xcb\\x9b\\x11\\x8c\\x4a\\xb1\\x50\\xb4\\xa2\\xac\\x23\\x09\\xaf\\xb4\\x86\\x74\\x72\\x35\\xc5\\xc0\\x6c\\x2d\\x65\\x7b\\x69\\x8f\\x1c\\x98\\x6f\\x45\\xe7\\x5a\\x4c\\x35\\x5c\\xcc\\xcd\\x27\\xb2\\x67\\x2e\\xb5\\x36\\x91\\xf1\\xfc\\xb5\\x69\\xc5\\xab\\x10\\x7e\\x22\\xb8\\xf1\\x83\\x32\\xfc\\x49\\x5b\\x0a\\xf1\\xf5\\x4e\\x6a\\x4c\\xf0\\xfa\\x4f\\xaf\\xdd\\x2f\\xd0\\x9c\\xe0\\x75\\x21\\x4d\\x2b\\x73\\xe2\\x7e\\xfc\\x28\\xbb\\xf5\\xf1\\x23\\x8e\\x89\\x3f\\x23\\x78\\x4e\\xdc\\x3f\\x8d\\x99\\x4f\\x9b\\x38\\x08\\x5c\\x17\\x33\\x82\\xdb\\x83\\xe2\\x13\\xc1\\x33\\x32\\xb4\\x77\\xc8\\xe1\\xda\\x06\\x41\\x45\\xeb\\xad\\x04\\xa1\\xd3\\x35\\x0a\\x97\\xa4\\xeb\\x18\\xc1\\x92\\x5f\\xe4\\x7c\\x91\\x45\\x34\\xe6\\xd6\\x7e\\x5c\\xe1\\x49\\xd3\\x93\\x68\\xf7\\x82\\xe0\\x4f\\x44\\xcc\\x6a\\xb5\\x1d\\xbe\\x6f\\x23\\x22\\x14\\xc2\\x42\\xc9\\x8c\\x73\\xd5\\x3e\\xfd\\x79\\x7b\\xb3\\xde\\x9d\\x92\\xec\\xd5\\xf9\\xc2\\x6c\\xfb\\x6b\\xf7\\x0a\\x44\\x61\\x21\\x26\\xfc\\x0f\\x4e\\x66\\x3b\\xe4\\xc9\\x12\\xa4\\x67\\xa5\\xfc\\x0a\\xa6\\x5d\\xc5\\x07\\x52\\xb2\\x08\\x92\\x39\\x80\\xdd\\x01\\x2c\\x65\\x4f\\x20\\x79\\xc9\\x0c\\xae\\x67\\x78\\x01\\x66\\xd5\\x12\\x8c\\xfd\\x36\\x88\\xf1\\x6c\\x6b\\x01\\xc6\\x38\\xd6\\x4b\\x4e\\xc2\\xce\\x78\\x0e\\xe2\\x51\\x7f\\x8c\\xe2\\xd1\\x60\\xbc\\xbd\\x87\\x61\\x6f\\x5c\\xcc\\x14\\xf1\\x8b\\x0d\\xae\\xcc\\xf4\\x30\\x56\\xdb\\xfe\\x38\\x36\\x9b\\xd9\\x78\\xb6\\xd9\\xd4\\x24\\x3d\\x6b\\x0b\\x84\\x0b\\x48\\x51\\x08\\xda\\x39\\x98\\x89\\xa5\\xab\\xa1\\x2a\\xbb\\x5f\\x40\\x44\\x22\\xd2\\x22\\x48\\x5c\\xd8\\x0d\\x0a\\xab\\x26\\xa8\\x61\\x1e\\xcd\\xc6\\x7e\\xdc\\xe9\\x80\\xf2\\x0d\\xdb\\xb6\\xf6\\x28\\x04\\x4b\\x5b\\x40\\x62\\x46\\x9e\\x5e\\xfa\\xa5\\xd2\\xfc\\xa8\\xc4\\x0a\\xb0\\x84\\x9d\\x8e\\xf8\\x35\\xc8\\x11\\x83\\xa5\\xde\\x7a\\xa9\\x4b\\x4e\\x6d\\xb2\\xd9\\xb4\\xcb\\xe5\\x40\\xe2\\x6a\\x9f\\x50\\xa0\\xba\\x32\\x2c\\x5a\\x9f\\xc1\\xba\\x80\\x28\\xde\\x49\\x39\\x58\\xca\\x0e\\x13\\x30\\x1a\\xcd\\xd0\\xd1\\x18\\x8d\\x62\\x74\\x3c\\x1e\\xcb\\x79\\x3c\\x6a\\xe3\\xa5\\x3b\\xe1\\x39\\x98\\xc1\\xcd\\xe6\\xd8\\xbc\\xc4\\xb0\\xaa\\x68\\xe9\\x2a\\x25\\x4d\\xcc\\xf5\\x52\\x4d\\x20\\x3a\\x31\\x0d\\x6f\\x2f\\x05\\xce\\x81\\x19\\xec\\x74\\x4e\\x70\\x59\\x58\\xaf\\xb1\\x0b\\x83\\xa8\\x42\\x9a\\x03\\xb0\\xd2\\x30\\x14\\xc5\\x76\\xbe\\xd7\\x1a\\xd6\\x34\\x0a\\x02\\xbe\\xf8\\xe8\\x74\\x6b\\x38\\xe7\\x0b\\x9a\\x91\\x72\\xfe\\x59\\xac\\xa1\\x10\\x38\\xcb\\x94\\x9f\\xf1\\x45\\xae\\x07\\x31\\x59\\x64\\x2a\\x59\\x74\\x52\\x0b\\xa0\\x53\\xdc\\xaf\\x99\\x0a\\x33\\x6e\\x49\\x8f\\x33\\x14\\xab\\x11\\x15\\xb8\\x55\\x37\\x6a\\x9b\\xdd\\x4d\\xbd\\x40\\x5a\\x33\\x7e\\xe9\\x40\\x5f\\x76\\xd8\\xc2\\x9c\\x5a\\x11\\x2b\\x6b\\x2b\\x24\\x51\\xec\\xb5\\x9c\\xee\\x0c\\xfa\\xb3\\xd1\\x64\\x3c\\x52\\x8b\\x68\\x8c\\xe3\\x9a\\x54\\x54\\xdf\\xc7\\xa9\\xb5\\xac\\x12\\x45\\xe5\\x40\\xaa\\xfa\\x86\\x36\\x2c\\x23\\xe4\\xd6\\xf7\\x00\\x48\\xf6\\x65\\x20\\x07\\x13\\xf5\\x20\\xb8\\x96\\xb6\\x99\\xd7\\x21\\xa8\\x89\\xfd\\x5a\\x4b\\xb6\\x61\\x0c\\xb5\\xd2\\x5e\\x6b\\x60\\x7b\\xb0\\x63\\x4b\\xfb\\x12\\xad\\x31\\x06\\xc5\\x75\\x59\\x6a\\xea\\x66\\xda\\x4e\\x87\\xa7\\xee\\x94\\x93\\x00\\x4f\\x6d\\xea\\x20\\x0d\\x9b\\x6a\\x39\\x4e\\x5d\\xe2\\x57\\xfa\\x55\\x7d\\xbd\\xc4\\x7a\\xdf\\x2f\\x96\\x20\\xda\\x32\\xaf\\xa4\\x41\\x99\\xaf\\xd3\\x45\\x0d\\x6d\\xac\\xbe\\xfb\\x06\\x25\\x63\\x6d\\x0f\\x45\\x5b\\x1e\\x71\\x33\\x81\\xcc\\x7e\\xac\\xf6\\x0c\\xbe\\xa8\\x7d\\x40\\x9b\\x78\\x59\\x8d\\x9d\\x75\\x3a\\x25\\x05\\xab\\x68\\x57\\x5c\\x27\\x58\\xf1\\x30\\xd4\\xcb\\x68\\x18\\xe3\\x50\\x2f\\x47\\x0f\\xc4\\xd8\\x71\\xba\\xad\\x6e\\x77\\x82\\x42\\xb9\\xee\\x04\\x0a\\x43\\x2f\\xc6\\xce\\xf2\\xa3\\xd3\\x9d\\x49\\x94\\x5f\\xe2\\xa9\\x4b\\x47\\xb1\\x94\\x96\\x96\\x62\\xa2\\xa6\\x2e\\x15\\xb9\\x44\\x67\\xd5\\x26\\xe6\\xd2\\x08\\x94\\x53\\x23\\x50\\x5e\\xe0\\xe5\\x68\\x2a\\x4b\\xcc\\x04\\xed\\xec\\x74\\x2e\\x84\\xc0\\xd2\\xc6\\x58\\xfe\\xdd\\x6c\\x66\\x58\\x3f\\x1a\\x2f\\xb5\\x28\\xf0\\x62\\x14\\x47\\x59\\xee\\x2d\\x91\\x34\\xbd\\x79\\x53\\x14\\x7b\\x17\\xa5\\xd7\\x9a\\xfd\\xfd\\x40\\x65\\x38\\x1c\\xa0\\xb8\\x1c\\x1b\\x8b\\x18\\x4f\\xcb\\x6d\\x71\\xc1\\xad\\x15\\xb7\\xa1\\x40\\xef\\x1d\\x64\\xd1\\x67\\x21\\x07\\x47\\xa1\\xdc\\x8c\\xc6\\x42\\xb4\\x2c\\xb9\\xcb\\xcc\\x6f\\x83\\xca\\x90\\x6b\\xb8\\xcb\\x0c\\xcf\\xb6\\xb9\\xcb\\x4c\\x70\\x97\\x99\\xe2\\x2e\\x8d\\xe4\\xb4\\x41\\xf9\\x17\\x44\\x96\\xec\\xea\\x7c\\x8d\\x79\\xbf\\x48\\x8c\\xa7\\x75\\xd2\\x7b\\xe1\\x9d\\x14\\x10\\xcd\\x34\\xf1\\x5d\\x80\\xd1\\x68\\x8a\\x9c\\xcc\\x19\\x8f\\x95\\x3e\\xe6\\x64\\x4e\\x1b\\xcf\\xe4\\x74\\x4f\\xe1\\x66\\x33\\x10\\x2f\\x62\\x0c\\x36\\x1b\\x95\\xa8\\xca\\x8b\\xb7\\xcc\\xbc\\x21\\x27\\x77\\x60\\x5b\\x30\\xbc\\x23\\x93\\xbb\\x6a\\x85\\xc6\\x38\\xd3\\x7c\\x50\\x33\\xfd\\x0b\\x04\\x91\\xa3\\xb6\\xd9\\x68\\x83\\xff\\xa8\\x3f\\x6e\\xe3\\xe9\\x66\\x23\\x9b\\x61\\xd2\\x06\\x96\\x2b\\x8a\\x55\\xda\\x30\\x33\\x0d\\xe1\\xa4\\x2a\\xd0\\x1f\\xbb\\x17\\x9b\\xcd\\x81\\x93\\xd7\\x80\\x6c\\x36\\x6d\\x53\\x56\\xed\\x0d\\xb4\\x07\\x42\\x4c\\xbb\\x02\\x5f\\x50\\x7b\\x72\\x9a\\xbe\\xfa\\x7c\\x1f\\x39\\x97\\x4b\\x6c\\x8a\\x85\\x96\\x38\\x1d\\xf6\\xbd\\xa9\\xee\\x7c\\xa0\\x44\\xd2\\x29\\xf4\\x63\\x57\\x60\\xe4\\x66\\x03\\xd4\\x83\\xde\\xcd\\x1c\\xc5\\x6e\\x14\\x8c\\xf1\\x68\\x2c\\x33\\x0c\\x63\\x57\\x4b\\x27\\x78\\xe6\\x89\\x8c\\xda\\x7a\\xa1\\x10\\x13\\x65\\x66\\x2f\\x27\\x43\\x82\\x5a\\x98\\xe4\\x19\\xbf\\xf4\\xa6\\x86\\x40\\x14\\x48\\xc1\\x57\\x9a\\x42\\xec\\xc6\\x10\\x99\\x42\\x8a\\x98\\xc5\\x6e\\x5c\\xa6\\x54\\x2f\\x62\\xe2\\xba\\x5d\\x58\\xe7\\x10\\xfc\\x0b\\xa4\\x59\\xae\\x88\\xaa\\x77\\x25\\xd1\\x8c\\x3b\\x9d\\xa9\\x6c\\xc0\\x10\\xa8\\xbf\\xd2\\x42\\xc6\\x38\\x98\\x2a\\x2b\\x39\\x1a\\x40\\xa4\\x3f\\x18\\x23\\x81\\x65\\x73\\x75\\xe9\\x68\\x2a\\x06\\x44\\x64\\x31\\x0d\\x16\\x8f\\x92\\x16\\x9a\\x07\\x49\\x98\\x63\\x31\\x08\\xae\\x22\\x9b\\x92\\x1c\\x56\\xfd\\x38\\x3c\\x44\\x07\\xed\\x3e\\x94\\x2c\\xc0\\xee\\x02\\x8b\\x39\\x49\\x71\\xcd\\xab\\x61\\x6b\\xe5\\x97\\xe3\\xb2\\x45\\x02\\xea\\x70\\x6a\\x7c\\xae\\xd4\\x36\\xdb\\xed\\x72\\x34\\xdc\\xb8\\x5e\\xa0\\xc6\\x5d\\xcb\\x02\\xc0\\x1a\\x3f\\x37\\x86\\x62\\xdc\\xe4\\x1c\\xd6\\xcb\\xea\\xb5\\xd3\\x60\\x27\\x62\\x5b\\xda\\x4e\\x09\\x78\\x34\\x15\\xc4\\x12\\x69\\x70\\xe3\\x02\\xd6\\x21\\x0a\\x65\\xf0\\x3a\\xe0\\x5a\\x12\\xdc\\x36\\x14\\xa5\\x9d\\x5d\\x13\\x8e\\xea\\xdf\\x16\\xa4\\x30\\x49\\x1f\\x11\\x7b\\xf3\\x75\\x6b\\xcf\\x50\\xce\\x83\\x45\\x42\\xfc\\x36\\xb0\\xb6\\x0b\\x35\\xe1\\x5d\\x9a\\xb5\\x8e\\x0e\\xa6\\x4a\\xcd\\x98\\xa1\\xe5\\x68\\x30\\x46\\x4b\\x41\\x7e\\xa5\\x75\\xa2\\x56\\xeb\\xae\\x21\\xae\\x61\\xd0\\x7d\\xa3\\xc9\\x97\\xea\\xb5\\xd4\\x7c\\xa5\\x54\\x48\\x58\\x92\\x5d\\xc5\\x97\\x0f\\xae\\xa9\\xb1\\x55\\xd1\\x72\\x99\\x48\\x08\\x71\\x32\\x01\\x54\\x89\\x98\\xd9\\xbf\\x69\\x0e\\xe8\\x2d\\x7a\\x38\\x80\\x46\\xbd\\x56\\x95\\x64\\xd1\\xe2\\xfa\\x95\\x44\\x21\\x90\\xc6\\x2a\\x43\\xc7\\xa8\\xb6\\x86\\x96\\xb5\\x2a\\xd8\\x34\\x03\\x14\\xd6\\xeb\\xef\\x0e\\x2a\\x5b\\x42\\xff\\x3e\\x1d\\x1e\\x32\\xaf\\x34\\x2e\\x99\\xd2\\x83\\xab\\xd8\\x93\\x76\\x1a\\xe4\\x1e\\xdd\\xbe\\x4f\\x3b\\x9d\\x43\\xf7\\xe8\\xf6\\x3d\\x5a\\xcd\\x2e\\xc3\\x14\\x05\\x78\\x80\\x38\\xa6\\x28\\xc4\\x7d\\x34\\xc1\\x03\\x3f\\x6c\\x63\\xee\\x43\\x76\\x0b\\x53\\x34\\xb9\\x85\\x0f\\xc5\\x47\\x10\\x62\\x0e\\xbb\\x93\\x5b\\xac\\xd7\\xed\\x06\\xd5\\x6c\\x6c\\x8f\\xe6\\xa0\\x4b\\xeb\\xc3\\x97\\x93\\xed\\xe1\\xab\\xef\\x2c\\xa8\\x9d\\x83\\xaa\\x67\\x3b\\x87\\x14\\x1a\\xb7\\xe3\\x00\\x05\\x0c\\x1e\\x52\\x70\\xc8\\x20\\xec\\x1d\\xd9\\x15\\x32\\xba\\xcf\\x81\\x6f\\x6b\\x74\\x76\\xa7\\xc8\\x1e\\x2f\\x6b\\xba\\x96\\xc9\\xb9\\x3d\\x5d\\x68\\xd0\\x3b\\xfe\\xf2\\x0c\\xb1\\xf8\\xf3\\xf1\\xd1\\x75\\x67\\xe8\\xfe\\xfd\\xfb\\xfd\\x1d\\xb4\\x39\\x3e\\x32\\x56\\x74\\x5f\\xa4\\x03\\xda\\x39\\x39\\xba\\x7b\\x72\\xb7\\x3f\\xf8\\xe9\\x4e\\x1f\\x76\\x3a\\x80\\xde\\xbb\\x87\\x07\\x77\\x10\\xeb\\xe2\\xc1\\x1d\\x58\\x65\\xf9\\xe9\\xe7\\xc1\\xdd\\x7e\\xff\\xe7\\x32\\xcb\\xcf\\x22\\xc7\\xcf\\x55\\x86\\xfe\\xd1\\x9d\\xdb\\xc7\\x83\\x9f\\x4f\\xca\\x0c\\x27\\x22\\xc3\\x49\\x99\\xe1\\xf8\\xe8\\x68\\x70\\x74\\x74\\xfb\\xe4\\xa7\\x23\\x93\\xe1\\x48\\x64\\x38\\x2a\\x33\\x1c\\x0d\\x4e\\x7e\\x3a\\xf9\\xf9\\xf8\\xce\\xc9\\xcf\\xb0\\xd3\\xa9\\xec\\xf6\\x2d\\x56\\x9b\\x89\\x9d\\xd5\\xb9\\x77\\xe6\\xf9\\xc5\\x75\\xe6\\xbd\\x6b\\xcf\\x7b\\x39\\xea\\xfc\\x62\\x39\\x1f\\xfc\\xdf\\xad\\x0b\\x6b\\x4d\\x88\\x15\\x50\\xae\\x08\\xd6\\xbc\\x16\\xf8\\xc5\\x12\\x50\\x78\\x38\\xb0\\x07\\x24\\x4c\\x93\\xd5\\xb6\\x07\\x7b\\x7d\\x48\\x6a\\x36\\xb1\\x76\\x69\\x14\\xb3\\xf7\\xbe\\x60\\xc3\\x38\\x95\\xa3\\xaf\\xc7\\x54\\x48\\x4b\\x76\\x19\\x30\\x80\\x4d\\xc3\\x4b\\x47\\xfd\\x71\\xe5\\x82\\x2b\\xde\\x6a\\x03\\x3a\\xbd\\x5c\\x26\\x57\\x5e\\x4a\\x47\\xf7\\x4b\\x6b\\xa2\\xd9\\xd6\\x31\\x99\\xb7\\xd2\\x87\\xe5\\x5a\\x2a\\xbf\\x8c\\xfa\\x63\\xe8\\xf5\\x15\\xaa\\xa3\\x00\\x71\\xbd\\xbf\\xc0\\xe5\\x66\\xde\\x76\\x79\\xb9\\xcb\\xc0\\xab\\x3d\\x09\\x8e\\x1a\\x00\\x32\\x2d\\x4e\\x0f\\x1e\\x0d\\xfa\\xfd\\x7b\\x7c\\xb3\\x19\\x3c\\x3a\\x1c\\xf4\\xfb\\xf7\\xd5\\xc6\\x70\\xbb\\x3c\\xc2\\x62\\xaa\\x0a\\xf6\\x57\\xa5\\x0d\\xee\\x1a\\x65\\x6a\\x55\\xf4\\xb8\\x1f\\x74\\x71\\x78\\x2b\\xac\\x4d\\xbd\\xa4\\xe4\\x01\\xbc\\xc5\\x8b\\xaf\\xc2\\x6e\\x06\\x8b\\x14\\x50\\xbf\\x01\\x68\\x6d\\x82\\xa2\\xf9\\xea\\x6a\\x3b\\x43\\x75\\x94\\xb7\\x57\\x95\\xda\\x6c\\xa0\\x9d\\x3b\\xb7\\x6f\\x1f\\xdf\\x46\\x1c\\x33\\xf5\\x54\\xee\\x7e\\xdd\\xe2\\x5d\\x00\\xe8\\xfd\\xfb\\xf7\\x07\\x77\\xd4\\x17\\x78\\x8b\\x77\\x83\\x5b\\x80\\xd9\\x49\\xf7\\xee\\x0d\\xee\\x08\\xf2\\x05\\x37\\x7d\\x1b\\xdd\\x05\\x39\\xef\\x5f\\xc7\\x34\\x5d\\xb1\\x64\\xd8\\x93\\xcf\\xcf\\x5f\\x0e\\xb6\\x21\\x5e\\x8d\\xae\\xee\\x07\\x58\\xe3\\x15\\x59\\x34\\x59\\xfc\\x57\\xf9\\xa1\\xaf\\xbc\\x5f\\xa2\\xec\\x25\\x79\\x09\\x28\\x1c\\x52\\xaf\\x7f\\x8f\\x0e\\x07\\x9e\\x5a\\xf2\\x07\\x55\\x15\\x57\\x66\\x7f\\x57\\x26\\x82\\xea\\x78\\xc5\\x90\\x79\\xfb\\xb9\\xe0\\x2e\\xd7\\xbd\\xa9\\xd0\\x22\\x08\\xda\\xe1\\xd1\\x2d\\x8b\\x11\\x0a\\x4c\\x02\\x83\\x43\\x06\\x7b\\x60\\xd0\\x65\\x8d\\x2c\\xb1\\x6c\\x4e\\xba\\x5a\\xb0\\xff\\xd2\\x1e\\x33\\xbc\\x9b\\x8d\\xe5\\x70\\x43\\xeb\\xfe\\x37\\x74\\xb3\\xd9\\xdf\\xec\\x30\\x4e\\x92\\x14\\xd4\\x5a\\xdd\\xdc\\x4e\\x55\\xad\\xfb\\xe8\\xf5\\xdb\\x67\\xcf\\x5f\\xbd\\xb4\\xda\\x5a\\xc7\\x26\\x21\\x0c\\x1c\\xa1\\xc3\\xdb\\x47\\x50\\xcf\\xb2\\x2e\\xf7\\xe2\\xf4\\xcf\\x8f\\x6f\\x4f\\x1f\\x3f\\xfa\\xf8\\xec\\xe5\\xbb\\x47\\x4f\\x1e\\xbd\\x69\\x02\\x70\\xb7\\xdf\\xff\\x69\\x70\\xf7\\xae\\x60\\xac\\x27\\xfd\\xbb\\x77\\x07\\xb5\\x8a\\x5f\\x3c\\x7b\\xf9\\x35\\x00\\x87\\x5f\\x04\\x10\\x65\\x8f\\xc5\\x88\\xf0\\x6b\\x2c\\x10\\x67\\x21\\x8b\\x5a\\x9c\\x86\\x4a\\xa5\\xdc\\x8c\\x7a\\xa7\\x63\\x86\\x59\\x39\\xad\\x1d\\xda\\xaf\\xc5\\x56\\xed\\xcf\\x16\\x39\\x9f\\xf0\\xfd\\xce\\x0a\\x0d\\xeb\\x73\\xab\\xe5\\x72\\x19\\x61\\x6c\\x4f\\x1c\\x95\\x2a\\xe4\\x56\\x4d\\x2f\\xc9\\xcb\\xff\\xd0\\xc9\\xca\\xdb\\x83\\x76\\x3a\\xa6\\x87\\x45\\x7d\\x16\\xa3\\xec\\x2d\\x09\\xf9\\x4d\\x7a\\xa2\\xcb\\xca\\xc1\\xb3\\xb0\\xee\\x1e\\xde\\x83\\x27\\xf5\\xbe\\x2d\\x49\\x9a\\x71\\xc9\\xb9\\xf7\\x6d\\xfd\\x54\\x39\\x76\\x0b\\x3e\\x5b\\x7c\\xb9\\xd8\\xb3\\x45\\xae\\xb7\\xdf\\x92\\x2f\\x9d\\x1f\\x25\\x99\\xa0\\x8b\\xc3\\xda\\x9b\\x57\\xdf\\x0b\\xab\\x64\\xa4\\xc1\\x17\\xd9\\x66\\x80\\x6d\\xc6\\x26\\x16\\xb4\\x72\\x32\\x93\\x5b\\xc2\\xad\\x68\\xd1\\x0a\\x60\\x0e\\x02\\xc4\\x85\\x98\\x49\\x46\\x7c\\x8c\\x83\\x11\\x1f\\x5b\\x2e\\x31\\x7e\\xe5\\x7e\\xa9\\xda\\xb1\\xaf\\x7f\\x09\\xa9\\x3b\\x6b\\x5e\\xd9\\x43\\xa3\\x3c\\x0f\\x35\\x1a\\xa3\\x40\\x0a\\x03\\xd2\\xf5\\x8d\\xc2\\x1c\\x50\\x14\\x08\\xe9\\x56\\x59\\x71\\x46\\x01\\xa2\\xa3\\x60\\x3c\\x86\\xdb\\xa2\\xae\\xae\\x30\\x4c\\x93\\xf9\\xa3\\x6b\\x57\\xba\\x2e\\xd4\\xd9\\xcd\\x2d\\x4d\\x58\\xb5\\xa0\\xd9\\x5b\\xcd\\xe9\\xd2\\x6a\\x4f\\x51\\x16\\x50\\x3b\\x8a\\x14\\xef\\xee\\x97\\xef\\x6c\\x89\\x07\\xe5\\x66\\xb8\\xdf\\x0e\\x94\\xda\\x5e\\x25\\xc1\\x75\\x80\\x03\\x7d\\x96\\x37\\x0a\\xf5\\x9e\\x16\\x08\\x60\\x1b\\xe3\\xa0\\xb9\\x2d\\xa6\\x7a\\x79\\x22\\xd2\\x1a\\x81\\x56\\x36\\x4d\\x56\\x71\\xd0\\xba\\x8c\\x78\\x1c\\xe8\\x13\\xb1\\x99\\x03\\x7d\\x36\\x0a\\x46\\xfd\\xb1\\x98\\xe5\\xc1\\xb8\\xd8\\x1a\\xc7\\x37\\x3c\\x8c\\x39\\xdb\\x2f\\x6f\\xae\\x8b\\xfa\\x0c\\x4f\\x78\\x6e\\x6d\\x6b\\xaa\\x9e\\x5f\\x63\\xa7\\x7a\\x34\\xae\\xd7\\xeb\\x26\\xe7\\x8b\\xdf\\xae\\xb4\\x45\\x5f\\xc3\\x18\\xdc\\xd8\\x9a\\x97\\x64\\xce\\xc5\\xaa\\xf7\\x69\\xf3\\x77\\xdd\\x5a\\x7b\\x66\\xf4\\x39\\x71\\xdb\\xd3\\x63\\xc7\\xdb\\x10\\xcb\\xe5\\xe1\\x66\\x2b\\x9a\\xa9\\x5d\\xd7\\x3e\\x1a\\x9c\\x08\\xc9\\x83\\x41\\x85\\xa4\\x72\\xf5\\x94\\x08\\xea\\xb2\\x64\\xc1\\x48\\x0e\\x4a\\x85\\xbc\\xb1\\x2d\\x0f\\xb5\\x33\\x62\\x92\\x5e\\xad\\xef\\xd5\\xd2\\x5f\\x17\\x28\\xc0\\x5b\\xc3\\x27\\xf4\\xe3\\x86\\xae\\x88\\x89\\xe7\\xe3\\x71\\xf3\\x68\\x54\\x2d\\x10\\x4b\\xae\\xd6\\x85\\xad\\x39\\xaf\\x6f\\xfe\\xef\\xa3\\x05\\x0b\\x52\\xeb\\xee\\x55\\x7d\\x18\\xae\\x4a\\x09\\x04\\x19\\xd8\\xa1\\x02\\xfa\\x98\\x8b\\x4b\\xe2\\xf8\\xad\\x3a\\xe1\\xb2\\x77\\x9b\\x2b\\x28\\x7d\\xd6\\xb2\\x9c\\xe4\\xab\\xcc\\x73\\xc2\\x55\\x1c\\x46\\xb1\\x2c\\xa3\\x2c\\xc8\\x41\\x6d\\x13\\x7c\\xb7\\x80\\x3a\\x30\\x20\\xf2\\xa7\\x9c\\x64\\xc9\\x42\\x14\\x68\\xea\\x52\\xcd\\x21\\xcc\\x0f\\xb0\\xe5\\xfb\\x11\\x54\\xcd\\x0b\\xcb\\xf1\\xe0\\xe6\\x58\\x02\\x08\\xa1\\x3a\\x70\\x21\\x94\\x87\\xa2\\xf2\\x6d\\x71\\xa5\\xcf\\x4b\\xc9\\x35\\x4d\\xaf\\x6b\\x47\\xb4\\x49\\x1c\\x5f\\x5e\\x87\\x75\\x56\\xa7\\x3b\\x1a\\x54\\x5a\\x53\\x83\\x69\\x17\\x05\\x10\\x6e\\x65\\xae\\xb9\\x97\\xa0\\xff\\x0a\\x43\\xd1\\x37\\xe6\\x17\\xb0\\xf4\\xae\\x31\\xa8\\x2d\\x3d\\xa7\\xbe\\x2e\\xc3\\x3f\\xd6\\xdf\\xad\\xd1\\x90\\x25\\x77\\x65\\x7a\\xe5\\x13\\x6e\\xa4\\x55\\xe3\\xc8\\x25\\x12\\xe5\\xc0\\xca\\x3d\\xbc\\x2f\\x31\\x68\\x96\\x72\\x92\\xf3\\x61\\xed\\xcd\\xdb\\xbb\\xa9\\x5a\\x58\\xbb\\xbb\\x98\\xd8\\xfe\\xcc\\xb4\\x40\\xff\\x92\\xc6\\xd3\\x83\\xc4\\x7e\\x91\\x6e\\x18\\xca\\x39\\xc2\\x0c\\x49\\xe9\\x22\\x0d\\x18\\x1a\\x8d\\x6d\\x49\\xb5\\xa8\\x7b\\x4c\\xd7\\xdc\\x1f\\x8a\\x28\\x04\\x4d\\x1e\\x60\\x1a\\x6a\\xa7\\xb3\\x03\\x5e\\x8d\\x74\\xb5\\x1d\\xb4\\x93\\x41\\x8f\\xfd\\x6e\\xfa\\x9e\\x41\\x97\\x6e\\xf7\\x28\\x80\\x3e\\xaf\\x6a\\xab\\x53\\x15\\xc0\\x90\\x85\\xd0\\xf6\\x42\\xdf\\x03\\xb2\\xf2\\xdc\\xef\\x74\\x00\\xc7\\x0c\\xfa\\x1c\\x2f\\x09\\xe0\\x76\\x10\\x8d\\x9d\\x08\\x1a\\x06\\xec\\x3e\\xa4\\x31\\x48\\x71\\xc0\\x51\\x00\\x37\\x1b\\x5e\\x14\\xa0\\x86\\x93\\x65\\x47\\x9b\\xf4\\x8c\\x7f\\x49\\x1d\\x81\\xeb\\x81\\x3f\\xae\\xec\\xd9\\x97\\xa7\\x97\\xeb\\xc6\\xd0\\x21\\x3a\\x83\\x76\\xec\\xfb\\x3a\\x4d\\xaf\\x74\\x43\\x3e\\xe4\\xae\\xed\\x33\\x8d\\x31\\x06\\x41\\x2d\\x65\\xb3\\x69\\x0f\\x60\\xa7\\xc3\\x5d\\xbe\\x58\\xcd\\xb9\\x95\\xa9\\x7a\\xd7\\x59\\x80\\xa3\\xce\\x9c\\x47\\x0a\\xac\\xda\\xb2\\xc3\\x46\\x82\\x11\\x20\\x8c\\x37\\xb6\\x02\\x60\\xde\\x64\\x71\\x4f\\xed\\x08\\x89\\xec\\x13\\x9e\\x8b\\xcc\\x99\\x7e\\xcd\\x78\\x2e\\x75\\x0e\\xb5\\x2d\\x19\\xda\\xdb\\x92\\xdb\\xa3\\x1a\\xf3\\xfc\\x7a\\xa3\\x6a\\xbc\\x8e\\xc4\\x63\\x79\\x50\\x46\\x6e\\x14\\x1b\\x7b\\x8b\\xda\\x86\\xa3\\x23\\x36\\xd6\\x0d\\x08\\xb6\\x1a\\x70\\x60\\xb5\\x60\\xdf\\x90\\xef\\x63\\x8c\\x5f\\x99\\xa9\\x7a\\xf7\\x26\\x57\\xe2\\xb5\\x15\\x48\\x2b\\xb3\\xed\\x9c\\x96\\x92\\x4a\\x63\\xf0\\x89\\x6f\\x78\\xec\\xd7\\xba\\x20\\x0b\\xc9\\x63\\x29\\x65\\xe4\\x15\\x9f\\xe0\\xe6\\xb6\\xc9\\x00\\x41\\xf5\\x96\\x5f\\x19\\xc7\\xa5\\xe5\\x12\\xef\\x33\\x5d\\x8a\\x79\\xd0\\x58\\x9e\\x12\\x85\\xc8\\x51\\x08\\x2a\\xe3\\xa1\\xa8\\x6a\\x28\\x7f\\xb5\\x37\\xa8\\xc0\\x2b\\xb5\\xc1\\x56\\x1f\\xcc\\x29\\xb9\\xe6\\xe1\\x31\\x26\\x45\\x8f\\xed\\x09\\xb7\\xdd\\xc5\\xf6\\xc2\\xdb\\xcf\\x37\\xec\\xe2\\xc3\\x86\\xb4\\x5d\\x29\\xb9\\xdd\\xdf\\xea\\xc8\\xae\\xc3\\xd5\\xd7\\x9b\\xb1\\xed\\x26\\xb1\\x03\\x63\\xb8\\x5b\\xef\\xa0\\xa8\\x89\\x0a\\xfb\\x4a\\x56\\xf6\\xb8\\x76\\x93\\x47\\x5d\\xa5\\xdf\\x5b\\xb4\\xfe\\x8a\\xb8\\x51\\x1d\\xdb\\x32\\x53\\x6f\\xe8\\xff\\x50\\x7a\\xde\\x0c\\x81\\xfc\\xa3\\x26\\xfe\\x78\\x47\\x07\\x1e\\x72\\x4f\\x48\\x8d\\xa8\\xdd\\x87\\x5e\\x58\\xd2\\x9e\\x4e\\xa7\\x6a\\xe7\\xe3\\x34\\xf9\\x2c\\x24\\x2c\\x38\\x04\\x02\\xcf\\x70\\x80\\xd4\\x86\\xb9\\xd7\\x34\\xdb\\xbb\\xd9\\xb6\\x26\\xe6\\x2a\\xa2\\xf1\\x90\\x78\\x0b\\xcb\\xab\\x55\\xe2\\x9b\\x45\\x7c\\x16\\xaa\\x9f\\xa8\\xf4\\xc9\\xa8\\xd1\\x1e\\xe5\\xa8\\xaa\\x0f\\x0e\\x6d\\x8f\\xa2\\x25\\x70\\xb0\\x2a\\xee\\x04\\x3f\\x6f\\xbd\\x20\\x4b\\xb5\\x8a\\xd7\\x0c\\x0b\\x99\\xac\\xd2\\x44\\xfd\\x36\\x08\\x30\\xdb\\xda\\x42\\x56\\x25\\x83\\x00\\x68\\x2a\\xae\\x03\\x42\\x48\\x0f\\x00\\xe3\\x18\\x10\\x7d\\xe6\\xff\\xff\\x3b\\xf1\\xb0\\x26\\x27\\x9e\\xa0\\x72\\xe2\\x31\\xfb\\x0d\\xed\\x40\\x3a\\x6d\\x31\\xe5\\xba\\x13\\x68\\xd7\\x9d\\x40\\xf6\\x89\\xc1\\x36\\x0e\\x1a\\xd2\\x15\\x34\\xf9\\xed\\xc8\\x7c\\xab\\x3b\\xf0\\x70\\x1c\\x58\\xbb\\xef\\x21\\xe6\\x96\\x03\\x4f\\xa8\\xdd\\x6f\\x42\\xcb\\x81\\x87\\x55\\xaf\\x03\\xf1\\x5a\\x41\\xb3\\xca\\x1a\\x74\\xde\\x29\\x2f\\x0f\\x38\\x9e\\xb4\\x71\\x58\\xf7\\xe6\\xb1\\x21\\x56\\x9f\\x86\\xed\\x81\\xc7\\x6d\\xaf\\x1e\\x8d\\x3b\\x93\\x7d\\xfe\\x3c\\xb6\\xaf\\x21\\x09\\x02\\x5c\\x37\\x75\\x2b\\xcb\\x76\\xdf\\x63\\xbe\\x99\\x6e\\x2e\\x64\\x4c\\x66\\xbb\\x82\\x58\\x88\\xb0\\xdf\\x9b\\x72\\xdb\\x57\\x46\\x42\\xd7\\x25\\xb5\\xef\\xea\\xd7\\x80\\xb2\\xad\\xe3\\xe9\\x8d\\xae\\x2b\\x44\\xa5\\x6f\\xfb\\xaa\\xec\\xf5\\xc9\\x64\\x5b\\x87\\xf3\\x34\\xba\\xd4\\x4b\\xec\\x77\\x38\\xd1\\x85\\x4a\\x64\\xa8\\x97\\xdb\\xeb\\x10\\xa2\\x8b\\xa9\\xef\\xdb\\xa5\\xa4\\x33\\xca\\x2e\\x18\\x3b\\xcf\\xae\\xab\\xc6\\xc1\\x97\\x0b\\xec\\x7a\\x94\\x6c\\x1d\\x4f\\x32\\xf3\\xab\\xf3\\x81\\x06\\x6d\\xb4\\x3a\\xa0\\x81\\x42\\xb4\\x73\\x32\\xbb\\xe9\\x48\\x31\\x4b\\x02\\xfe\\x3a\\x89\\x16\\xf9\\xe9\\x7f\\x8e\\x84\\x64\\x83\\x10\\x2b\\x9c\\x19\\x33\\x86\\xb5\\x31\\xb1\\xd9\\xa8\\x9d\\xfa\\x7b\\x98\\x76\\x3a\\xf4\\x5e\\x00\\xd7\\x32\\xea\\x91\\x3e\\xc5\\xe6\\xb2\\x29\\x49\\x1f\\x24\\x01\\x3f\\xcd\\xf5\\x26\\xc6\\xed\\xdb\\x47\\x77\\xef\\xdc\\xe7\\x9b\\xcd\\xed\\x3b\\xc7\\x83\\xbb\\xf7\\xf8\\x66\\x43\\xbb\\x03\\x21\\x6c\\x56\\xbb\\x90\\x74\\xab\\x5c\\xb7\\xda\\xb1\\xbd\\x7d\\xe7\\xf8\\x48\\xc6\\x64\\xba\\xfd\\xd3\\xf1\\xc9\\xf1\\x3d\\x3a\\xe4\\xde\\xa0\\x7f\\x74\\x72\\x0b\\xf0\\x43\\x09\\x18\\x76\\x69\\xf7\\xee\\xd1\\xe0\\x4e\\xb1\\x15\\x42\\x49\\xa8\\xf9\\x0f\\x4c\\x6f\\xae\\x69\\xda\\x71\\x1c\\x7d\\xa8\\x6a\\xc7\\xb4\\x6b\\x9d\\xac\\xda\\xd9\\xba\\x0c\\xc6\\x3a\\x80\\x14\\xdf\\x6c\\x06\\x83\\xc1\\xc9\\x60\\x30\\x10\\x9d\\xe5\\xed\\x9a\\x49\\x9f\\xc3\\x3d\\x01\\xa5\\x22\\xe5\\x72\\xfd\\x51\\x4c\\xc1\\xc7\\xa5\\x68\\x75\\xcb\\xe9\\x72\\xe8\\xcb\\x4d\\xc6\\xfb\\x98\\x0f\\x59\\x17\\xdb\\x7d\\xd3\\xc3\\x05\\x38\\xf4\\x00\\x3f\\xc4\\x22\\x9b\\x74\\x85\\x68\\xcc\\x73\\xff\\xfe\\xfd\\x41\\xbf\\x33\\xe8\\x1f\\x1d\\x6f\\xd4\\xa8\\xed\\xcd\\xa9\\x33\\x89\\x51\\x87\\xbb\\xe7\\xbb\\x76\\x70\\x6e\\x2e\\xc8\\xdd\\xe9\\x95\\x8e\\xe8\\xa9\\x88\\x7f\\xbb\\xe1\\xdf\\x3a\\x9d\\x36\\x75\\xd5\\xa9\\x8f\\x66\\x3b\\xab\\xca\\xd6\\x5a\\x92\\x2c\\x93\\xa1\\x53\\x9a\\x42\\xc1\\x99\\x76\\x00\\xa8\\xe2\\xc1\\x4d\\xc9\\x19\\x37\\x31\\x09\\x73\\x32\\x71\\xcb\\x03\\x99\\x72\\xd8\\x25\\x40\\x40\\x51\\x43\\x6b\\x86\\x4a\\xa1\\xf5\\x9c\\x89\\x5c\\x00\\x72\\x6d\\x70\\xdc\\x1e\\xa0\\x70\\xf7\\x1c\\xa7\\x72\\xce\\x5a\\x17\\x68\\x2a\\x16\\x0a\\xc9\\x72\\x19\\xfa\\xcf\\x16\\x92\\xd7\\xb6\\x4b\\x34\\x32\\x41\\x44\\x7d\\x75\\x4a\\x81\\xb9\\xfc\\x82\\x33\\x10\\x28\\xd6\\x39\\x2b\\x97\\x03\\x6e\\xf7\\xd1\\x9e\\x82\\x56\\x35\\x18\\xe3\\x69\\xa7\\x03\\xac\\x94\\x2e\\x1e\\x40\\x7f\\x62\\xbc\\x37\\xfd\\x89\\x64\\x48\\xd8\\x0a\\xa0\\x56\\x14\\x7e\\x78\\x95\\xf3\\x9f\\x61\\x49\\x6a\\xc2\\x7a\\xd0\\xc0\\xcc\\x1c\\x7c\\xd5\\x07\\x12\\xdb\\x18\\x93\\x61\\x19\\x01\\xd4\\x73\\x5a\\x4e\\xb9\\xbd\\x78\\x8f\\x76\\x3a\\x64\\x48\\x74\\x64\\x36\\xb5\\x05\\xc9\\x78\\x14\\x03\\xda\\x2b\\x4f\\xbe\\xc2\\x9a\\x31\\x97\\x42\\x6f\\x4f\\x78\\xbe\\x25\\x09\\x1e\\x5d\\x39\\xf6\\x61\\x2d\\x6c\\x9d\\xa2\\x6a\\x4b\\x12\\xa8\\xc8\\x66\\x25\\x55\\x09\\xba\\x19\\x01\\x0c\\xd1\\xc3\\x32\\x2e\\xdd\\xbe\\x38\\x0d\\x65\\xd9\\x6f\\x58\\xfb\\x76\\xdd\\xdd\\x60\\x5f\\xed\\x79\\x1a\\xcd\\xdf\\x44\\x93\\xe9\\xb5\\xe3\\xbf\\x95\\xe1\\xdf\\xbe\\x6f\\x8a\\xff\\xb6\\x37\\xd4\\xdc\\xde\\x61\\xde\\x13\\xfe\\x4d\\xb6\\x4d\\x03\\xfc\\x83\\x93\\xd9\\xd5\\x45\\x63\\xe3\\xce\\x7c\\x23\\xf1\\xf8\\xbf\\x9c\\x0e\\x62\\x3b\\x67\\x81\\x82\\x9d\\x14\\x6e\\x0e\\x07\\x31\\x45\\xd3\\xdb\\xbc\\x94\\x6b\\xd5\\x53\\x60\\x9d\\x06\\xe2\\x96\\x44\\xc5\\x55\\xfb\\x4a\\xb5\\xcc\\x94\\xeb\\x74\\x4c\\xb9\\x26\\xcb\\xca\\x55\\x05\\xc4\\x9a\\x50\\xd8\\xee\\xc3\\xfd\\xf2\\xdf\\xf5\\x85\\xae\\x06\\x89\\xb1\\x5e\\xa8\\xec\\x64\\xfd\\x54\\x8b\\x18\\xd2\\x95\\x24\\x93\\x9b\\x8d\\x8c\\x42\\x9b\\x13\\xdc\\xfb\\x67\\xf4\\xe1\\xbc\\xdb\\xfb\\x78\\x38\\xee\\x8e\\xf0\\x78\\xdd\\x47\\x47\\xc5\\xf7\\x3d\\x74\\xae\\x02\\x4d\\x55\\xc6\\x91\\x0b\\x52\\x61\\x18\\x20\\x98\\xb8\\xff\\xae\\x78\\x7a\\xf9\\x96\\x0b\\x8d\\x4e\\x06\\x4a\\xae\\x27\\x00\\x47\\x99\\x47\\x46\\x8b\\x64\\xc1\\xf8\\xd8\\x81\\x72\\xdb\\x14\\x13\\x57\\xbe\\x6f\\x36\\xc4\\x9d\\xf0\\xfc\\x34\\xcf\\xd3\\x88\\xae\\x72\\x0e\\x1c\\x99\\x2c\\x73\\xe5\\xc4\\xcd\\x79\\x96\\x03\\x02\\x85\\x66\\xee\\x54\\xbb\\x0b\\x67\\x2a\\x2a\\x40\\x63\\xd8\\x59\\x8a\\x57\\x3a\\x9e\\x02\\xb1\\x37\\x76\\x05\\x0f\\xc3\\x74\\x44\\x46\\x6c\\x3c\\x46\\xea\\xf8\\x78\\xe9\\x7a\\x21\\xbb\\x57\\x0e\\x4e\\x59\\xcb\\x79\\xed\\x20\\xdf\\xa5\\x15\\x93\\xda\\xe8\\x69\\x5b\\x27\\xf9\\xda\\x98\\x0e\\xa9\\x47\\x86\\xf5\\xc3\\xcc\\x04\\x0e\\x1d\\x22\\x43\\x3e\\x78\\xd4\\x73\\x44\\x5d\\x56\\x4f\\x2e\\xab\\xa1\\xb4\\x2d\\x20\\xb2\\xb2\\x2a\\xd7\\xe7\\xaf\\xd7\\x2d\\x3d\\x1d\\xd4\\x21\\x42\\x52\\x3f\\x92\\x43\\x8b\\x8a\\x11\\x9c\\x96\\x71\\xa1\\x0d\\xe2\\x4a\\x69\\x55\\x1f\\xb3\\x26\\x2e\\x8d\\x16\\x01\\xb2\\x0e\\xd8\\x96\\x05\\x7f\\x21\\x56\\xdc\\xd9\\x36\\xa9\\x1d\\x21\\x53\\xa7\\xef\\x76\\x84\\x2e\\x43\\x54\\xb7\\x4f\\xe7\\x66\\x71\\xc4\\xb8\\x3e\\xd0\\x69\\x8a\\xa0\\xa3\\x5d\\x57\\x3f\\x23\\xb0\\x5d\\xa5\\xbc\\x39\\x40\\x5e\\xe5\\x5a\\x2d\\xb2\\x69\\x14\\xea\\x6d\\x10\\xc0\\x51\\x50\\x9d\\x5e\\xd5\\x69\\x54\\xee\\x5c\\xec\\xd6\\xba\\x93\\xcd\\x3e\\x70\\x5c\\x4d\\x89\\x19\\x8f\\x06\\x5b\\xb8\\x18\\xc5\\x4e\\xe7\\x70\\xd0\\x6e\\xda\\x5d\\x11\\x1f\\xad\\x13\\xa8\\x65\\x04\\x20\\x67\\x41\\xf2\\xe8\\x8c\\xb7\\x84\\x1c\\xe9\\xc0\\xe1\\x67\\x7c\\x4a\\xbc\\xcf\\xf8\\x97\\x72\\xeb\\xe3\\xb3\\x6e\\x8f\\x64\\x4e\\x56\\x93\\xaa\\xc9\\xfd\\xc5\\x30\\xf9\\xda\\xba\\x50\\xb4\\x73\\xe5\\x93\\x51\\x7f\\x1c\\x2d\\x5a\\x6c\\xb3\\xb1\\x36\\x33\\x4a\\x5b\\x9b\\x92\\x69\\xde\\xca\\x85\\xba\\xd9\\xd8\\x6f\\xc0\\x11\\x10\\x9c\\xae\\x28\\x6f\\x53\\x7a\\xb3\\xba\\x64\\xa8\\x05\\xe2\\xca\\xd1\\x06\\x10\\xfa\\x90\\x94\\xc7\\x33\\xac\\xe8\\x07\\x6c\\x14\\x8c\\x3b\\x1d\\xf1\\xdb\\xde\\x8d\\xcc\\x3d\\x0a\\xc6\\x43\\x86\\xc5\\x47\\x4f\\xfd\\xc1\\xeb\\xc2\\x93\\x7f\\xad\\xd5\\xf8\\x40\\x5b\\x64\\x6b\\xfb\\x3b\\x56\\x44\\x19\\x5b\\x17\\xf4\\x2d\\xeb\\x89\\x3e\\x20\\x4b\\x6a\\x0a\\x57\\x19\\x2a\\x07\\x5b\\xe1\\x41\\x1e\\x10\\x9b\\x73\\x5a\\xf1\\xc0\\x1f\\xea\\xcd\\x33\\x89\\xee\\x2e\\x23\\xcb\\x7c\\x95\\xf2\\xb7\\x39\\x61\\xb3\\x77\\x29\\x61\\x1c\\xee\\x49\\x57\\xc2\\xc4\\x43\\x58\\x1d\\xf7\\xa6\\x58\\xaf\\x18\\x37\\x13\\xb9\\x7c\\xda\\xe9\\xa8\\xb0\\x7e\\xf2\\x15\\x53\\x58\\x10\\x93\\x32\\xe7\\x59\\x46\\x26\\xdc\\x8a\\xd3\\x5e\\x3c\\x00\\x0f\\x91\\x2c\\x0f\\xfd\\x87\\x56\\x6f\\x16\\x64\\xce\\xb1\\xf3\\x60\\x95\\xe5\\xc9\\x5c\\x7e\\x76\\xaa\\x96\\x3f\\x52\\x83\\xa6\\xf9\\x37\\xc1\\x18\\x3f\\x24\\x9d\\x0e\\xdd\\x6c\\x1c\\xc7\\x44\\x2e\\x7c\\x44\\x8a\\x47\\x16\\xb4\\x57\\xb8\\xdd\\xf7\\xed\\x84\\x17\\x5f\\x88\\xd0\\x53\\xd6\\xf3\\xb8\\x36\\x74\\xb6\\x74\\xfe\\x48\\xf0\\x03\\x7b\\xc0\\x31\\x96\\x49\\x54\\x3c\\x08\\x41\\x93\\x78\\x8e\\xa8\\xe7\\x23\\x17\\x4d\\xf7\\x1e\\x88\\x9c\\x16\\x7d\\x7c\\x6c\\xc1\\x15\\x13\\xf9\\x08\\x3c\\x24\\x88\\x40\\x79\\xf4\\xfc\\x11\\x11\\x32\\xfc\\x43\\x79\\x5c\\x5e\\xbc\\x3f\\xc5\\xeb\\xd0\\x5b\\x17\\x85\\x7f\\xf0\\xd4\\x0d\\xdd\\x67\\x78\\x3d\\x25\\xde\\xda\\x99\\x64\\x39\\xc9\\x23\\xe6\\xb2\\x64\\xee\\x78\\xeb\\x38\\x21\\x01\\x4f\\xbd\\xc7\\xc0\\x99\\xe6\\xf9\\x32\\xf3\\x7a\\xbd\\xf3\\xf3\\x73\\xd7\\xca\\xd3\\x13\\xfa\\x6c\\x9e\\xf5\\x7e\\x58\\x9f\\xf1\\x34\\x8b\\x92\\x45\\xd1\\x53\\x65\\xdc\\x4f\\x99\\xd0\\x2c\\x38\\x5d\\x4d\\xae\\x50\\x5c\\xe6\\xb3\\x81\\x7c\\xca\\x7a\\x9f\\x32\\xb2\\x8c\\x3e\\xca\\x2f\\x1f\\x7f\\x58\\x2f\\x09\\x9b\\x91\\x09\\x2f\\x3e\\xce\\x93\\x60\\x15\\x73\\x0b\\xfc\\xc7\\x68\\xf0\\xf3\\xe2\\xbf\\xd4\\x21\\xca\\xd5\\x6a\\x11\\x09\\xbb\\x55\\x7d\\xfc\\xf8\\xc3\\x3a\\x26\\x8b\\xc9\\x4a\\xa4\\xa9\\x7a\\x59\\x32\\x5f\\x46\\x31\\x0f\\xae\\x37\\x30\\x65\\x9f\\x4c\\xf1\\x7d\\xdd\\x2a\\xbf\\x5f\\xb1\\x67\\xcd\\x7d\\xaa\\x41\\xb9\\x5a\\xb7\\xb2\\xec\\x7a\\xb5\\xb1\\x4c\\xbc\\x66\\x2b\\x1a\\x44\\x69\\xd1\\xfb\\x61\\x1d\\x46\\x31\\x17\\xeb\\xab\\x70\\x20\\x3a\\x60\\x59\\x76\\xf4\\xdf\\xc1\\x0d\\x8a\\xf2\\xf1\\x68\\x1b\\x74\\x3e\\x8d\\xd2\\xe0\\xe3\\x92\\xa4\\xf9\\xe5\\xf5\\x2a\\xb0\\x0a\\xee\\x6d\\xb7\\x95\\xe7\\x9a\\xcd\\x6f\\x82\\x7e\\xc5\\x6e\\x7c\\x9c\\xf0\\x6b\\x4e\\xf4\\x15\\xba\\x52\\xa0\\x6a\\x35\\x2f\\xbe\\xbe\\x98\\x17\\x37\\x5a\\xcb\\x8b\\x1b\\x2e\\xe5\\x83\\x2b\\xac\\xe5\\xfd\\x75\\xfc\\x1f\\x2e\\xe5\\xa6\\x61\\xf9\\xc6\\x2b\\xb9\\xa9\\x8a\\xff\\xb3\\x85\\xdc\\x54\\xd9\\x97\\xd6\\xf1\\x17\\x97\\xf1\\xd7\\x80\\xdd\\x74\\x15\\x37\\xc1\\xbf\\xca\\x22\\x3e\\xb8\\xd2\\x2a\\xbe\\x2a\\xf4\\x6f\\xb1\\x88\\xff\\x63\\x4f\\x8a\\x02\\xfd\\xe5\\x8d\\x1c\\x1d\\xaa\\xd6\\x19\\xa3\\x85\\x60\\xd2\\xe6\\xd5\\x1b\\x8d\\xd1\\x24\\x25\\xcb\\x69\\xc4\\xb2\\x5a\\xae\\x55\\xe4\\x8d\\x1c\\xf3\\x45\\xbe\\x7f\\xa4\\x24\\xe3\\xf5\\xc4\\x30\\x26\\xd9\\x54\\xe6\\x5c\\x45\\xe2\\xf5\\xdc\\x3c\\x4d\\x78\\x62\\x1e\\x65\\xd4\\x67\\x92\\xf3\\x20\\x8f\\xe6\\x3c\\x8e\\x16\\x02\\x84\\x4e\\x8b\\x92\\x85\\xec\\x52\\x95\\xcb\\xa4\\xa8\\xc2\\xc8\\x61\\xc9\\x22\\x4f\\xa5\\xc3\\xa6\\xc3\\x92\\x94\\xab\\xdc\\xc8\\x91\\x9b\\xa4\\xa2\\x54\\xca\\x89\\xca\\xef\\xd0\\x34\\x39\\xcf\\x78\\xaa\\x73\\x50\\x92\\x7a\\x23\\x27\\x3c\\x77\\x90\\x13\\x5c\\xca\\x06\\x3b\\xc8\\x39\\xe7\\x34\\x4c\\x16\\xb9\\xa2\\x48\\xce\\x58\\x64\\x6a\\x2c\\x7c\\x60\\xbf\\x9a\\x6e\\xd0\\x15\\xa5\\x31\\xcf\\x4a\\xa8\\xc7\\xce\\x18\\x31\\x12\\xf3\\x45\\x60\\xaa\\x1a\\x23\\x59\\x80\\x07\\x51\\x9e\\xa4\\x9e\\xb3\\x8a\\x5a\\x65\\x93\\x5b\\xd1\\x9c\\x4c\\xf4\\xe3\\xce\\x78\\xb4\\x26\\x64\\x35\\xe1\\xad\\x09\\x4f\\x54\\x86\\x79\\x52\\x0e\\x43\\x2b\\x49\\x27\\xea\\x41\\xf5\\xb8\\x16\\xc2\\xb0\\xaa\\x4c\\xcd\\x8c\\xa3\\xa7\\xe8\\x9b\\x57\\x2b\\xa1\\xd6\\xeb\\x8e\\x52\\xb6\\x33\\x18\\xf1\\x2a\\xcb\\xab\\x41\\xb3\\xa7\\x4b\\x7d\\x4f\\xe2\\xd5\\x7c\\xd1\\x38\\xe0\\x66\\x96\\xcd\\x58\\x9b\\x77\\x83\\x71\\xba\\x63\\xf2\\x8b\\x86\\x5a\\x22\\x1a\\x59\\xe4\\xf9\\xf6\\x54\\x8b\\xe4\\xd5\\x84\\x5b\\xc8\\x68\\xca\\x4c\\x78\\xa2\\x12\\xe6\\x64\\x29\\x4a\\x29\\xfc\\x75\\x90\\xfe\\x70\\xa0\\xbe\\xec\\xd6\\x3b\\xe5\\x24\\x57\\x45\\xce\\xf8\\x84\\x18\\xa4\\x9d\\xf2\\x38\\x4e\\xce\\x93\\x34\\x0e\\x0c\\x06\\x54\\x03\\x6e\\x2a\\x97\\x29\\x16\\x9e\\x56\\x39\\x1c\\xf5\\xad\\xc2\\xc2\\x9d\\x4f\\x62\\x9a\\xf6\\x7d\\x5b\\x46\\x7b\\x3f\\x65\\x4b\\x92\\xce\\xe4\\x4a\\xab\\x7d\\xd3\\x6b\\xef\\x2b\\x8b\\xc2\\xaa\\xb3\\x3e\\x49\\xaa\\xfb\\x6a\\x9c\\x2c\\x5c\\xb1\\x46\\x71\\x8c\\x0c\\xde\\x98\\xce\\x27\\x67\\x3c\\x15\\xf8\\xa6\\x08\\x57\\xb5\\xa8\\x0d\\x6a\\x8c\\x51\\xd5\\x8d\\x7a\\x6d\\x19\\x59\\xcc\\xf8\\xa5\\x85\\x60\\xe2\\xc7\\x55\\xa9\\xce\\x18\\x65\\x8c\\xe4\\x39\\xbf\\xc2\\x1a\\xd7\\x19\\x9b\\xeb\\x58\\x2d\\xe8\\x2a\\xcd\\x0c\\xfa\\x1c\\x28\\x3c\\xcd\\xf2\\x94\\x93\\xb9\\x84\\x57\\xc3\\x6f\\x15\\xb0\\x53\\x77\\xac\\x5a\\x17\\x35\\x34\\xb1\\x48\\x9c\\x2c\\x28\\xbb\\x5b\\x61\\x65\\x9e\\x72\\xae\\x86\\x51\\x02\\x29\\x51\\xa9\\x4e\\x54\\xcf\\x93\\x34\\x10\\x39\\x75\\xb6\\x02\\x3d\\x25\\xde\\x3a\\x38\\xf6\\x0c\\x2b\\xf1\\xe4\\x70\\x68\\x66\\xe2\\x39\\x67\\xb7\\x1d\\x64\\xc8\\xbd\\xf8\\x24\\xf8\\x77\\x61\\x8f\\x56\\xad\\xe0\\x47\\x9d\\x68\\x95\\x3f\\xd9\\x2a\\xaf\\x72\\x28\\x30\\xb5\\xe1\\x34\\x80\\xbc\\xad\\x51\\xb6\\x8a\\xeb\\x0f\\xb2\\x70\\x81\\x9e\\x88\\x86\\xab\\xde\\x57\\x65\\x75\\x42\\x56\\xab\\x55\\xa5\\x1d\\xe6\\x11\\x9b\\xf1\\x34\\x3b\\x64\\xc9\\x9c\\x46\\x0b\\x1e\\x68\\x38\\xf3\\x3a\\xc7\\x2a\\x41\\x09\\x44\\xb2\\xc1\\xe4\\x49\\x12\\xe7\\xd1\\xd2\\x65\\x59\\xe6\\x14\\x0d\\x3c\\xa5\\x2c\\xb8\\xcd\\x7f\\xd0\\x41\\x05\\x64\\xeb\\x9b\\x01\\x66\\xd3\\x76\\xab\\x05\\x55\\xaa\\xdd\\x10\\x2b\\xb9\\xa1\\xbc\\xc6\\x9b\\x26\\x20\\x0a\\x91\\x9a\\x21\\xc9\\x6f\\x25\\xb8\\x92\\x64\\x5a\\xa3\\x61\\x78\\xa5\\x55\\x5c\\xa7\\x99\\x62\\x5b\\xf4\\xa1\\x2a\\x6c\\x13\\x8a\\xaa\\x78\\x3d\\xbb\\x01\\x52\\xad\\xf2\\xb2\\xb8\\x49\\xb2\\x0b\\x9b\\x34\\x53\\x4c\\x2f\\xa0\\xb2\\x8c\\x62\\x69\\xf6\\xf4\\x89\\x04\\x95\\x1b\\x95\\xb9\\x56\\x79\\x14\\xdb\\x99\\xc2\\x24\\x9d\\x93\\x3a\\xcc\\xed\\xf1\\xfc\\x52\\x11\\xb4\\x5d\\xfd\\xc1\\x56\\xfd\\xb5\\x51\\x16\\xa2\\xcd\\x5e\\xb0\\xe2\\xbd\\xca\\xf8\\xb5\\x46\\x88\\x77\\x1b\\x76\\x51\\xf8\\x4f\\xdd\\xd0\\xfd\\x1d\\xaf\\xbf\\xf7\\xd6\\x0e\\x9b\\xa6\\xc9\\x9c\\x1f\\x86\\x29\\x99\\x73\\xc7\\x33\\xf2\\x5d\\xe6\\xad\\x9d\\x81\\xdb\\x77\\xfb\\x8e\\xb7\\x5e\\x2d\\x84\\x10\\x9f\\xf2\\x2c\\xe3\\x81\\xe7\\x3c\\x78\\xfc\\x6c\\x91\\xe5\\x24\\x8e\\xc5\\x0a\\x41\\xcd\\x5f\\xe6\\xd1\\x42\\xd3\\x02\\x01\\x63\\xf0\\x0d\\x60\\x1c\\xdd\\x08\\x46\\x81\\x48\\x1c\\x91\\x8c\\x67\\xde\\x7a\\xe0\\x69\\x78\\x12\\xae\\x63\\xde\\x8a\\x02\\x65\\xe7\\xa1\\xb2\\xaf\\xd7\\x06\\xe1\\xa8\\xa1\\xf9\\x65\\xce\\x8f\\x59\\xca\\x76\\xaa\\x2f\\xbf\\xea\\xe6\\x1f\\x35\\x34\\xfe\\x3a\\x10\\xac\\xc6\\x1f\\x79\\x12\\x5a\\x51\\x20\\x87\\x5f\\xe4\\x87\\x92\\x08\\xd5\\x5a\\x7b\\xec\\x0e\\x1a\\xa6\\xcc\\xe4\\x3d\\x94\\xea\\xa5\\xac\\xee\\xa0\\xe9\\xbb\\x6e\\xf0\\x71\\xe3\\xbc\\x37\\x00\\xd9\\x0b\\xc3\\x6a\\xf2\\xb1\\xa7\\x1b\\x25\\xe1\\x3a\\x9e\\x86\\x2e\\xde\\x06\\x8e\\xf9\\x26\\x46\\x5f\\x1a\\xa0\\x09\\x5b\\xc5\\xc9\\x2a\\xdb\\x42\\xc3\\x9f\\xdd\\xe3\\xdd\\x11\\xb4\\xf3\\xef\\x8e\\xe0\\xf6\\x57\\x89\\x46\\x77\\x1b\\xba\\xf5\\x5f\\xe0\\xfc\\xdc\\x84\\x13\\xff\\x09\\x4e\\x03\\x66\\x5c\\x13\\xce\\x36\\x6a\\xdf\\x95\\x83\\x3b\\x70\\x7f\\x96\\xa8\\x2d\\x46\\x4e\\xf6\\xdc\\x31\\xdf\\x8a\\x02\\x1d\\x68\\x56\\xb9\\xb3\\xd8\\x07\\xbb\\xcd\\xd1\\x59\\x3f\\x36\\x4f\\xba\\xcd\\x73\\xf5\\x5a\\xdf\\x9d\\xa9\\x6b\\x83\\x38\\xb9\\x39\\x88\\xdb\\x37\\x07\\xb1\\x8b\\x2a\\xd7\\x06\\xb1\\x8b\\x25\\xd7\\x05\\x71\\xf4\\xd3\\xcd\\x41\\xfc\\x7c\\x05\\x10\\x07\\x5f\\x81\\x71\\xf7\\xe6\\xcd\\xb8\\x39\\x62\\x1c\\xdd\\x1c\\x31\\x8e\\x6e\\x8e\\x18\\x47\\x77\\x6e\\x0e\\xe2\\x1b\\x20\\xc6\\xcd\\x97\\xea\\x55\\x26\\xe4\\x2b\\x78\\x71\\xf3\\x09\\xb9\\xf9\\x7c\\xdc\\x7c\\x3a\\x6e\\x8e\\xdc\\x83\\x9b\\x37\\x62\\x70\\xf3\\x95\\xfe\\x0d\\x28\\xd6\\x37\\xa0\\x15\\x37\\xc7\\xed\\xc1\\x37\\xa0\\x36\\x37\\x80\\xd0\\x20\\x2c\\xde\\xad\\x4b\\x8b\\x77\\x45\\xa6\\x4f\\xd2\\xf1\\x65\\x15\\xed\\xc8\\x2a\\x0d\\x33\\xa9\\xf2\\x1e\\xae\\xa2\\x9d\\x8a\\xab\\x2f\\xb6\\xbc\\xfb\\x73\\x13\\x46\\xfd\\x07\\x20\\xbb\\xab\\xeb\\x3f\\x00\\xd9\\x5d\\xe4\\x75\\x20\\x07\\x57\\x81\\xf2\\x35\\x20\\x57\\x6a\\xc9\\x2e\\xc5\\xba\\x3e\\x90\\x6f\\x32\\x24\\xbb\\xe8\\x75\\x7d\\x20\\xdf\\x64\\x82\\x77\\x17\\xdb\\xf5\\x81\\xdc\\x10\\x5d\\x0f\\x54\\x4b\\x76\\x89\\xcf\\xf5\\x5b\\xb2\\x4b\\x7d\\xae\\x0f\\x63\\x97\\x76\\x5c\\x17\\xc6\\x9d\\x06\\x42\\x7a\\x5d\\x18\\x3f\\x7d\\x03\\x18\\xb7\\x1b\\xa8\\xd8\\xf5\\xc7\\xe3\\x5b\\xf4\\xe5\\x6b\\x58\\x76\\x05\\x0a\\x70\\xbb\\x41\\xdc\\xf8\\x0f\\xf8\\xfe\\x0d\\x3a\\xf3\\x2d\\x06\\xf5\\xe6\\x30\\x7e\\xba\\xe1\\x78\\x6c\\x33\\x29\\xc9\\x76\\xe4\\x40\\x4b\\x26\\x75\\x5b\\xeb\\x7d\\x77\\xe4\\xdb\\x1d\\xad\\x13\\xfe\\x24\\xdf\\x7e\\xd2\\xdf\\x8c\\x86\\xa8\\x0b\\x4a\\x25\\x5b\\xd3\\xea\\xa2\\x40\\xf3\\x24\\xc9\\x93\\x24\\xde\\x56\\xc5\\x8f\\x1b\\x10\\xca\\x64\\xdd\\xc5\\x05\\xf3\\xe5\\xf0\\x72\\x15\\x1d\\x56\\x1f\\xca\\x51\\x68\\x32\\xae\\xd4\\xa0\\x5d\\x07\\xd8\\xa0\\x61\\x5a\\xfe\\x33\\xb0\\x93\\xaf\\xf5\\xf3\\x3a\\xc0\\x8e\\xbf\\x65\\x37\\x9b\\xcc\\x49\\x37\\xe8\\xe6\\xb7\\x6a\\xd9\\x81\\xec\\xe7\\x37\\x6c\\xda\\x51\\xc3\\x0a\\xb9\\x41\\x3f\\xbf\\x69\\xcb\\x76\\xa5\\x99\\x1b\\x00\\xdb\\x95\\x48\\x6e\\xb0\\x04\\xbe\\xd1\\x74\\x6e\\x93\\x97\\x81\\x36\\x98\\x0e\\x1c\\xfb\\xed\\x48\\xbe\\x89\\x1e\\xa8\\xe9\\x97\\xaf\\xc7\\xfa\\xe3\\x89\\x7c\\x3b\\x31\\x05\\x4d\\xc9\\x81\\x00\\xbe\\x2d\\x36\\x1f\\x09\\x46\\x95\\xee\\x8e\\x2a\\x5d\\x45\\x71\\xd0\\xbb\\x5c\\x45\\x6a\\xbb\\xa7\\x7a\\xda\\xe9\\xcc\\xde\\x9c\\x87\\x15\\xd5\\x3d\\x6a\\x34\\x00\\x7e\\xeb\\x3a\\x9a\\xb8\\xd4\\xb7\\xae\\xa3\\x49\\x44\\xf9\\xd6\\x75\\x34\\x89\\x30\\x5f\\xae\\xe3\\xe0\\xba\\x95\\x1c\\x37\\xb2\\x93\\xb2\\xa4\\xf8\\xbf\\xbf\\xf1\\xe2\\xff\\xd6\\xc0\\x1f\\xa5\\xff\\xb7\\x43\\xbf\\x6d\\x89\\x57\\xb6\\xd6\\x23\\xc9\\x65\\x8f\\x34\\x97\\x3d\\x92\\x5c\\x56\\x0d\\x9f\\x6c\\x95\\x7c\\x53\\x6d\\x53\\xad\\xec\\xeb\\x14\\x81\\xf0\\xba\\xdd\\x5b\\x79\\xee\\x3a\\x25\\x74\\x69\\x3e\\x3f\\xd6\\x06\\xf3\\x63\\xc7\\xbc\\x15\\x05\\x2a\\xbd\\x76\\xb7\\x38\\xf4\\x9d\\xc6\\x2d\\x00\\xeb\\xd6\\xf4\\xad\\x6e\\xd7\\xbe\\x18\\x01\\xb8\\x81\\x5c\\x5e\\x19\\xc2\\x81\\x92\\x7f\\xbf\\x41\\x23\\x76\\x19\\xc0\\x55\\x21\\x6c\\xd3\\xaf\\x9f\\xf4\\xa6\\x43\\x25\\x11\\x0d\\xcc\\xbb\\x56\\xeb\\x55\\x7d\\x2a\\x65\\xb0\\x95\\xc7\\xc8\\x4d\\x06\\xc6\\x4f\\xba\\x8c\\x4a\\x29\\x6d\\x01\\x5b\\x13\\xd1\\xc4\\xc0\\x54\\xc6\\x3d\\xf2\\x5d\\x4d\\x40\\x3c\\xda\\xab\\x20\\x5e\\xa5\\x74\\xd3\\xba\\xba\\x4e\\xe9\\x7d\\x82\\xf6\\x57\\x4b\\xef\\x13\\x03\\xae\\x5e\\x79\\x93\\xe4\\x75\\x9d\\xd2\\xff\\xb9\\xe9\\x7b\\xc4\\x84\\xeb\\x94\\xbe\\xc9\\x84\\x9f\\xec\\xb5\\x91\\x5c\\xa5\\xf4\\xed\\x1b\\x8d\\xda\\xed\\x1b\\x8d\\xda\\x7e\\x45\\x75\\x9f\\x76\\x78\\x45\\x7d\\xfb\\x2a\\x95\\xdf\\xb9\\x51\\xd3\\xef\\xdc\\x68\\xc2\\xef\\xdc\\x68\\xc2\\xef\\xdc\\x68\\xc2\\xf7\\x5b\\x18\\xae\\x56\\xfa\\xbf\\x8e\\xda\\x2e\\x65\\x1d\\xd4\\x64\\xc1\\x3b\\xf2\\xcd\\x12\\x05\\x0f\\x2c\\x59\\xf0\\xa4\\xa6\\xa2\\x1e\\xd5\\x08\\xf2\\x49\\x8d\\xd4\\x4a\\x31\\x31\\x48\\x3e\\x25\\x57\\xd0\\x3f\\x45\\xb6\\x9e\\xf8\\x71\\x2f\\x84\\xf4\\xea\\xda\\x5f\\x77\\xba\\xb3\\x95\\x79\\x3f\\xcd\\xb9\\x39\\xd4\\x26\\x32\\x7a\\x73\\xa8\\x4d\\x2b\\xfd\\x5b\\x8c\\xc0\\x37\\x6f\\xeb\\x3e\\x56\\x70\\xf3\\xc6\\x36\\x71\\xd6\\x9b\\x43\\x6d\\xa2\\x43\\xdf\\x62\\xba\\xfe\\x2f\\x90\\xa0\\x69\\xf5\\x57\\x19\\xaf\\x0e\\xf2\\x4b\\x54\\xf4\\x1b\\x4c\\x7f\\x13\\x47\\xfc\\x16\\x9d\\xff\\x52\\x63\\xaf\\xdf\\xf9\\x26\\x9b\\xe0\\x4d\\xe0\\x1d\\xfd\\x9f\\x20\\x52\\x93\\x6e\\x7f\\x33\\xa8\\xdb\\xa4\\xfc\\x8e\\x26\\xe5\\x95\\xaa\\x6e\\x13\\xf6\\xe3\\x6d\\xc2\\x6e\\xd1\\xf5\\xe3\\x1a\\x5d\\x1f\\x28\\xa2\\x5f\\x4a\\xda\\x35\\xc2\\x7e\\xe4\\x14\\x85\\x76\\x40\\xfb\\x03\\xaf\\x49\\xe8\\xb5\\xfb\\x88\\xcc\\xe5\\xef\\x67\\xf9\\x9b\\xaa\\x5f\\xea\\x39\\x24\\x75\\x10\\x9d\\x88\\x57\\xba\\x10\\xbf\\x8c\\xc8\\xdf\\x4c\\xfe\\xce\\x17\\x9e\\xf3\\x79\\xea\\xa0\\x40\\x26\\x06\\xf2\\x6e\\x43\\x1e\\xcb\\xdf\\x85\\xfa\\xfd\\x38\\xa1\\xf2\\x21\\x53\\xbf\\x1f\\x4f\\x06\\x77\\xe5\\x53\\x2e\\x7f\\x57\\xe2\\x37\\x94\\x85\\xc3\\x48\\xfd\\xca\\xd2\\x61\\xaa\\x7e\\x3f\\xaa\\xda\\x26\\x32\\x71\\xa6\\x9e\\x65\\x99\\x29\\xf7\\x9c\\xe8\\xdc\\x41\\x53\\x59\\x6a\\x2a\\xb3\\x4f\\xd5\\x97\\x4b\\xf1\\x1b\\x05\\xe2\\xd7\\x89\\x16\\x8e\\xe7\\x44\\x81\\x83\\x22\\x59\\x7f\\x24\\x6b\\x8d\\xce\\xc5\\xef\\x27\\x09\\xed\\x53\\xe4\\x39\\x97\\x91\\x83\\x3e\\x9d\\x79\\xed\\x01\\xfa\\x74\\xee\\x39\\x9f\\xce\\x1c\\x34\\x93\\x43\\x31\\x93\\x5d\\x98\\x25\\xe2\\x37\\x56\\xbf\\xb2\\x7c\\x7c\\x26\\x7e\\xe7\\xb2\\x4d\\x73\\x99\\x67\\x9e\\x78\\x4e\\x9a\\x38\\x68\\x2e\\xdb\\x31\\x97\\x75\\x2d\\xa8\\xe7\\x2c\\x12\\x07\\xa9\\x0b\\x1f\\x17\\x32\\xf7\\x42\\x42\\x59\\xca\\xe7\\x65\\xee\\x39\\xcb\\xfc\\x23\\x4d\\x1d\\x24\\xff\\xa8\\xb4\\x8f\\x4b\\x59\\x45\\x2a\\x33\\xa6\\xb2\\x43\\x99\\xec\\x62\\x36\\x93\\xbf\\xb2\\x68\\x26\\x33\\x67\\xb2\\x19\\xd9\\xb9\\xfa\\x9d\\x7a\\x4e\\x76\\xee\\xa0\\x5c\\xf6\\x2a\\x97\\x75\\xe6\\x53\\xf9\\x1b\\x7b\\x4e\\x18\\xc5\\x0e\\xca\\x65\\xa9\\x95\\x84\\x73\\xb0\\x92\\x2f\\x67\\x12\\xf4\\x65\\x24\\xfa\\xfe\\x79\\x2a\\xa6\\xf2\\x23\\x5b\\x38\\x48\\xfe\\x11\\x5f\\x3e\\x4f\\x3f\\x4e\\x67\\xfa\\x21\\x97\\x15\\x7d\\xce\\xe6\\x9e\\x33\\xcf\\x1c\\xf4\\x79\\x55\\xc6\\x67\\x79\\x42\\x76\\xef\\x46\\x57\\xd1\\x9a\\x6a\\x37\\x23\\x23\\x06\\xd7\\x7b\\xf2\\x95\\x97\\x0d\\x23\\x06\\x0b\\x6f\\xbb\\x50\\x15\\x94\\xdc\\x1c\\x74\\x46\\x1c\\x3b\\x2a\\x1a\\x8a\\x15\\xad\\x9f\\x0c\\xcb\\x53\\xd8\\x0e\\xf4\\x88\\xba\\x8b\\xe7\\x5e\\xe0\\x87\\xdd\\x2e\\x0c\\x5b\\xd1\\xa2\\xc5\\x3b\\x9d\\x32\\x88\\x2e\\x1f\\x85\\x63\\x14\\x22\\x02\\x0b\\xf4\\x74\\xb7\\xf9\\x73\\xb2\\xdc\\xba\\xd4\\x59\\x1f\\x88\\x6d\\xc8\\x58\\xb5\\x5d\\x1d\\xbe\\xde\\xea\\x80\\x1d\\x2d\\xa9\\x6c\\xbe\\x3e\\xa2\\x0f\\x18\\xbc\\x46\\x4f\\x58\\xad\\x27\\x20\\x18\\x85\\x63\\x73\\xbb\\xbb\\x0e\\x7e\\x53\\x76\\xaa\\x8a\\xde\\x52\\xa0\\x67\\xbb\\xdd\\xcb\\x92\\x39\\xbf\\x5a\\xff\\x44\\xce\\x86\\x0e\\x1e\\x5c\\xa1\\x87\\x5f\\xef\\x96\\x8a\\xff\\xcd\\x64\\xe0\\xef\\x28\\x04\\x2a\\xce\\x7f\\x39\\x47\\x26\\xa0\\x8f\\xba\\xb3\\x9e\\x58\\x71\\x50\\xcb\\x70\\x20\\xd5\\x69\\xe8\\x5f\\xed\\xd3\\xd0\\xdb\\x9d\\x50\\xe1\\xcd\\xf5\\x61\\xfe\\xd1\\xb8\\x31\\xda\\xc2\\x6f\\x56\\xbc\\x87\\x32\\x8a\\x85\\x8c\\xdd\\x55\\xeb\\x9f\\x9a\\x36\\x0a\\x75\\xd4\\x2b\\x2a\\xc3\\x5c\\xc9\\x73\\xf3\\x64\\x14\\x8c\\xab\\x80\\x70\\x65\\xec\\xf8\\x2a\\x56\\xc0\\x73\\x72\\x93\\x2b\\x11\\x10\\xc7\\x97\\x44\\x07\\x40\\xd2\\xb1\\x2d\\x30\\xe6\\x9b\\x4d\\x15\\x8c\\x82\\x77\\x3a\\xd5\\x0d\\x16\\x7a\\xc4\\xcb\\xb8\\x39\\x6b\\x8e\\xab\\x20\\x01\\x7d\\x7d\\x57\\x66\\x60\\xa5\\x98\\xaf\\x98\\x77\\xc3\\xda\\xc5\\xf8\\xe6\\x3a\\x7b\\x32\\xe2\\xdd\\xc9\\x18\\x07\\xa3\\xc9\\x58\\x5d\\x7d\\x4f\\x74\\x28\\x79\\x58\\x28\\x2a\\xf0\\x82\\x54\\xd3\\xf1\\x6c\\xe7\\x10\\xfc\\xcb\\xed\\x43\\xf0\\xaf\\x48\\xf1\\x6c\\xfb\\x10\\xfc\\xb3\\x2b\\x1d\\x82\\xb7\\x42\\x39\\x58\\x18\\xf0\\x7a\\xef\\x79\\xf8\\x67\\xbb\\xe7\\xe1\\x9f\\x99\\xf3\\xf0\\xaf\\x76\\xcf\\xc3\\xbf\\x4b\\x57\\x59\\xce\\x83\\x37\\x3c\\x4b\\x56\\x29\\xe3\\xef\\xd3\\xd8\\xb1\\x66\\xf1\\x7f\\x7a\\x16\\xd5\\x0c\\xca\\x43\\xf8\\x32\\xec\\xcd\\x1b\\x1d\\x38\\x85\\xed\\xb9\\x1e\\x7a\\x17\\x6a\\x4b\\x79\\xa5\\x7b\\x2d\\xa7\\xcb\\xa0\\x4f\\x30\\x2b\\x43\\x12\\xbd\\x25\\x55\\x60\\x20\\x19\\x5e\\x54\\x54\\x70\\xa5\\xeb\\xda\\x29\\xe2\\xf5\\xfa\\x7f\\x7c\\x9c\\xac\\x16\\x41\\x6b\\x4e\\xd2\\x19\\x4f\\x51\\xcb\\xf9\\xb1\\xcb\\xbb\\x3f\\x3a\\x48\\xac\\x34\\x55\\x7d\\x4b\\xad\\x52\\xf9\\x89\\xc9\\x4f\\x74\\x95\\xb7\\x16\\x49\\x4b\\x35\\x3b\\x26\\x94\\xc7\\xad\\x39\\x59\\x2e\\xa3\\xc5\\xa4\\x15\\x4a\\x60\\x91\\xbc\\xaa\\x2b\\xf3\\x5a\\x3f\\x76\\x7f\\x7d\\xfb\\xea\\xa5\\xab\\x20\\x44\\xe1\\xa5\\xbc\\x34\\x27\\xc0\\x74\\xc4\\xcb\\x95\\x10\\xd4\\x02\\x13\\x0c\\x1f\\x13\\x19\\xfa\\x76\\xc1\\x92\\x80\\xbf\\x7f\\xf3\\xec\\x41\\x32\\x5f\\x26\\x0b\\xbe\\xc8\\x81\\x9e\\xd0\\x00\\x5a\\x41\\xe4\\xdf\\xc9\\x88\\x2c\\x62\\xa0\\xdf\\x12\\xdc\\xfb\\x61\\x0d\\x3e\\x9c\\x77\\x61\\xd1\\x9b\\xa0\\x37\\x04\\xf7\\xfe\\x01\\x40\\x9d\\x91\\x84\\xc3\\x0f\\xbd\\x0f\\xbd\\x51\\xff\\xf0\\x2e\\x39\\xfc\\xec\\x7a\\xa3\\x0f\\xe3\\xc3\\x71\\xf7\\x43\\x6f\\xf3\\xa1\\x37\\xfa\\xa7\\xf7\\xe1\\xc3\\x78\\x33\\xfa\\xc7\\xeb\\x7d\\xf8\\xf0\\x83\\x4c\\x34\\xcf\\xb7\\x46\\xc3\\xef\\xc6\\x1b\\x42\\x93\\x55\\xee\\xd1\\x98\\x2c\\x66\\xdf\\xc1\\x5e\\x84\\xde\\x4b\\xb8\\xa3\\x7f\\x86\\xdf\\x8d\\x6f\\x41\\xf0\\x61\\x38\\xfa\\x47\\x3c\\x0c\\xc1\\x77\\xa3\\x0f\\xd9\\x87\\xb7\\xe2\\xb1\\x67\\x45\\xf8\\xfa\\xbd\\x8c\\xcf\\x42\\xb0\\xc6\\x0a\\x9f\\xe0\\xf7\\x44\\x85\\x2a\\x93\\xe8\\x68\\x61\\x2a\\xf4\\x29\\x26\\xa3\\xe3\\xb1\\x5c\\x02\\x56\\x07\\x47\\x83\\x71\\xf7\\x0f\\x02\\x9c\\xa1\\x83\\xc8\\xe8\\x48\\x7e\\x46\\x0c\\xca\\xa4\\xef\\x9c\\x8a\\xe4\\xaa\\x71\\x78\\x25\\x03\\x2f\\x94\\x2d\\x90\\x03\\x24\\x90\\xa3\\x8c\\xfa\\xf1\\xa2\\xa4\\x61\\x32\\xc0\\x8e\\x0e\\x44\\xe2\\xe6\\x0a\\xf9\\xde\\x5d\\x2e\\x79\\x26\\xc3\\x48\\x75\\x3a\\x4c\\x87\\x83\\x7f\\x9d\\xc4\\x11\\xbb\\x54\\xe1\\x5d\\x65\\x6c\\x41\\x2b\\x15\\x38\\x93\\x24\\x99\\x7c\\x37\\xcd\\xe7\\xb1\\x83\\xd6\\xea\\xcb\\xd3\\x77\\x2f\\x9e\\x7b\\x0f\\x08\\x52\\x6f\\x2a\\x5e\\xc9\\xf6\\xfb\\xfb\\x37\\x22\\x4b\\x01\\xab\\xe8\\xb0\\x2b\\xb9\\xfe\\x92\\x98\\x77\\x3a\\xe5\\xa3\\x2b\\x97\\x1b\\x08\\x4c\\xdc\\x0d\\x58\\xbc\\x20\\x98\\x2a\\xda\\x22\\x9f\\x08\\x06\\x54\\xf4\\x68\\x48\\xdd\\x2d\\xe8\\x80\\x40\\xaf\\x16\\xa0\\xfe\\x19\\x78\\x29\\x63\\x54\\x54\\xb3\\xf3\\x87\\x1d\\x3d\\x47\\x05\\x1f\\x62\\xd5\\xbd\\x4f\\xf2\\xfe\\xe4\\x6d\\xf6\\x54\\x45\\x90\\x1e\\x92\\x6e\\x03\\x8e\\x32\\xe8\\x39\\x4e\\x15\\x8e\\x45\\xac\\x03\\x06\\xcb\\xfb\\x4f\\xbe\\xb2\\x32\\x19\\x0a\\xa0\\x09\\xaf\\x23\\xf8\\x85\\x6f\\xa2\\xec\\x98\\x98\\x45\\x1c\\x0e\\xb9\\x27\\x56\\x8e\\xa9\\x40\\x31\\x7d\\x6e\\xf8\\x42\\x68\\xf8\\xc2\\x04\\x0b\\x36\\xef\\xab\\xc0\\x43\\x93\\x4e\\x07\\xd0\\xcd\\x06\\x50\\x4c\\x20\\xa2\\x5d\\x0c\\xa8\\xce\\x7f\\xdf\\x10\\xf4\\xa1\\xd3\\x71\\x3c\\xc7\\x81\\x4d\\x3d\\x0a\\x60\\xd7\\xc1\\x4e\\xd3\\x17\\x8d\\xb6\\x13\\x08\\xab\\x80\\x3d\\x54\\xe2\\xe0\\xcb\\x32\\xf8\\xc7\\x9f\\x04\\x37\\x46\\x3a\\x1b\\x36\\x45\\x45\\x93\\x5f\\x40\\x4d\\x36\\x32\\x1f\\x7b\\xff\\x98\\x10\\x6c\\xb7\\x80\\x5e\\x69\\x43\\x58\\x26\\x7d\\xdf\\x53\\x0b\\x8a\\xc0\\xd1\\x60\\x6c\\x21\\xff\\x5f\\xa4\\x26\\xb8\\x90\\x7b\\x74\\x78\\x38\\xf0\\xc8\\x7d\\x3a\\x1c\\x78\\x5a\\x2e\\xfd\\xd5\\x27\\x9e\\x1c\\xb2\\xbf\\x09\\x5e\\xb9\\x0b\\x72\\x16\\x4d\\x48\\x9e\\xa4\\x62\\xf6\\xff\\xd6\\x0b\\xe5\\x7b\\x82\\xff\\x26\\xee\\x2a\\xe3\\xe9\\xe9\\x84\\x2f\\x72\\xf1\\xe9\\x7b\\x02\\xd7\\xbf\\xe2\\xef\\x89\\x4f\\x53\\x4e\\x66\\x2d\\x52\\x14\\xbf\\x62\\x3b\\x12\\xd6\\x6f\\x55\\xcb\\x0f\\x07\\x6d\\xfc\\x6b\\x19\\x4e\\x88\\xd8\\xec\\x88\\xd0\\x2d\\x6e\\x2f\\xc9\\x26\\xac\\xcb\\x36\\x44\\x30\\x76\\x66\\x82\\xab\\x50\\x8a\\x1d\\x8b\\x4d\\xb5\\xea\\x68\\xd4\\x8a\\x32\\x2b\\x6e\\x73\\x6b\\xa9\\x93\\x9f\\x65\\x8f\\xca\\x78\\xf7\\xad\\x3c\\x79\\x9e\\x30\\x12\\x73\\x35\\x2d\\x2d\\x43\\x7d\\x5a\\x32\\x06\\xdc\\xab\\xd0\\x3e\\xc1\\x5b\\xb5\\x94\\x6d\\xb7\\x14\\x05\\x88\\xe3\\x81\\xcf\\x77\\x65\\x13\\x21\\xa8\\xad\\x6d\\xb9\\x44\\xa3\\x2b\\x53\\x37\\x34\\x11\\x19\\x76\\x7a\\xc4\\xb6\\x71\\x98\\x52\\x1b\\x89\\x19\\xa6\\x54\\xc8\\xa9\\x57\\x5a\\x36\\x01\\x62\\xea\\xca\\x27\\x0d\\x59\\x08\\x1b\\x65\\xcb\\x03\\xdd\\x72\\xe2\\x66\\x29\\xc3\\xaf\\x09\\xa0\\xd0\\x17\\x2b\\xc1\\x4d\\xce\\x17\\x3c\\x7d\\x98\\x30\\xd9\\x4a\\xc1\\xea\\x6b\\x09\\xae\\x3e\\x48\\xf8\\x7b\\xc4\\xcf\\x61\\xa7\\x43\\xdb\\x78\\x35\\xa4\\xf8\\x82\\x00\\xea\\x06\\x3a\\x0b\\xf4\\x34\\xcd\\xc0\\xe7\\xa4\\xd3\\x01\\xe7\\x44\\x7c\\x5e\\x55\\x9f\\x21\\xa2\\xf8\\x9c\\x40\\x9f\\x0a\\xe0\\x59\\x43\\x2c\\x35\\x44\\x6d\\x64\\xe0\\xb4\\x12\\x2e\\x43\\x6a\\x08\\xd7\\x15\\x39\\xfa\\x60\\x00\\x87\\x74\\x34\\x18\\x8c\\x3d\\xf9\\x8b\\x09\\x18\\x0c\\xa0\\x42\\xf0\\x09\\xc5\\xbf\\x01\\xe7\\xd5\\x92\\xa7\\xc4\\x81\\x68\\x2a\\xdf\\xde\\xa5\\x51\\xc0\\x17\\xb9\\x03\\x37\\x9b\\xdf\\x80\\xf3\\xe2\\xed\\xb3\\x47\\x0e\\x44\\x91\\xfc\\xf4\\x28\\x98\\x70\\x07\\xa2\\x4f\\xf2\\xe5\\x09\\x67\\xb3\\xc4\\x81\\x9d\\x4e\\x1b\\x28\\x34\\x16\\xc8\\x73\\xce\\xd3\\x07\\x24\\xe3\\x76\\x8c\\xac\\x73\\x4e\\x67\\x51\\x2e\\x33\\x96\\x20\\x64\\xa9\\x3d\\x75\\xd5\\x32\\xa2\\x19\\xc5\\xd7\\x86\\x8e\\x62\\xea\\x1f\\xe8\\x95\\x3b\\xa7\\xd8\\x71\\xd0\\x82\\xe2\\xad\\x18\\x65\\x04\\xff\\x2a\\xd6\\xea\\x27\\x13\\x50\\xae\\x97\\x9e\\x79\\x60\\xf4\\xcf\\x07\\xe8\\x8f\\xbb\\x10\\x7c\\x80\\x1b\\x1f\\x96\\x74\\x43\\x5e\\x0f\\x58\\x66\\x14\\x75\\x7c\\xe8\\x81\\xd1\\x87\\xe0\\x83\\x3b\\xee\\xd6\\x73\\x4d\\xcb\\x5c\\x1f\\x28\\x18\\x7a\\xa2\\x43\\x9b\\xf4\\x0c\\x8e\\xbc\\xd6\\xf8\\x4b\\xc0\\x67\\x65\\xb1\\x3f\\x38\\xfd\\x2d\\xca\\x3f\\xf4\\xc0\\x87\\xb7\\x5b\\xa0\\x27\\x65\\x1e\\x30\\xf4\\x7e\\x57\\xb6\\x74\\x38\\x6a\\x7d\\xe8\\x8d\\x87\\xf5\\xcc\\x05\\x80\\xfe\\x82\\x76\\x3a\\x60\\x4e\\xf1\\x82\\x0e\\x17\\x74\\x34\\x18\\x0b\\xfa\\xad\\xdb\\x27\\x7b\\x9f\\x50\\xb4\\xa4\\xb8\\xc2\\x47\\x3f\\xa1\\x78\\x49\\x87\\xcb\\x0a\\x81\\x5f\\x24\\x81\\x09\\x89\\xea\\x6b\\x06\\xd8\\xc6\\x09\\xed\\x74\\x12\\x7a\\xbf\\xba\\x19\\x0e\\xcc\\x29\\x84\\xeb\\x98\\x9a\\x90\\x57\\x09\\x85\\x15\\xd5\\x8b\\x29\\x9e\\x2b\\x92\\xff\\x2f\\xc5\\x31\\x45\\xa1\\xbc\\x7c\\xbd\\xe2\\xb0\\xa9\\x15\\x51\\x93\\x53\\x3b\\xb8\\xa4\\x59\\xfd\\x04\\xf7\\x11\\xc5\\x7f\\x12\\xc3\\x4d\\xfe\\xa5\\x10\\x5a\\x71\\xd2\\x10\\x13\\xdf\\x9c\\xc1\\xc0\\xa9\\xa5\\x06\\xd5\\x8d\\xad\\x86\\x6e\\x20\\x13\\x5c\\x59\\xdd\\x19\\xd5\\xc7\\x98\\x74\\x3a\\xfc\\x5e\\xa0\\x08\\x92\\x22\\x34\\x42\\xea\\x94\\xd2\\xd3\\x04\\x33\\xfd\\xe8\\x07\\xc9\\x3a\\xc4\\x3d\\xf0\\x21\\x10\\xe2\\xdc\\xc3\\x5b\\x10\\xb8\\xb7\\xcc\\x40\\x87\\x70\\xb3\\x19\\x39\\x0e\\x32\\xff\\xc6\\xfe\\x64\\x4f\\xce\\xc9\\x4e\\x4e\\x75\\xfd\\x65\\x38\\xea\\x8f\\xcb\\x80\\x6c\\x7d\\x8c\\x27\\xd5\\x3b\\x94\\x83\\xe8\\x13\\xfc\\x17\\x51\\x39\\x07\\xe6\\xcb\\xb0\\xef\\x99\\x1b\\xf6\\x80\\x48\\x46\\x83\\x3e\\x44\\xb2\\x70\\x63\\x96\\x89\\xce\\x02\\x37\\x1b\\x03\\xea\\xc8\\xe4\\x53\\xc5\\xca\\x57\\x95\\x45\\x7c\\x47\\x22\\x15\\xfa\\x21\\x0e\\x47\\xc7\\xa2\\x5b\\x93\\xd1\\xf1\\xb8\\x38\\x9f\\x46\\x31\\x17\\x10\\x48\\x19\\xe1\\xb4\\x7f\\x0f\\x0b\\x21\\xad\\x22\\x53\\x99\\xa1\\xa7\\x14\\x50\\x54\\x8f\\xc7\\xcd\\x3a\\x9d\\x4a\\xd3\\x34\\xf2\\x92\\x90\\x22\\x5f\\x75\\x3a\\x80\\x61\\xe6\\xbe\\x10\\x22\\xae\\x93\\xe5\\x97\\x31\\x77\\x30\\x0e\\x84\\xa6\\x2f\\x9e\\x5d\\x96\\x65\\xef\\xf8\\x45\\x8e\\x99\\xe7\\xb0\\x98\\x64\\x99\\xfe\\x28\\x9f\\x5f\\x92\\x39\\x17\\x1f\\xc2\\x24\\xd5\\xc9\\x42\\xd4\\x7c\\x9c\\xa4\\x98\\x79\\x39\\xdd\\x22\\x87\\x20\\x80\\xc3\\x2d\\x5a\\x9b\\xd3\\x51\\x30\\x46\\x0c\\x7a\\x7d\\x2c\\x74\\x59\\x13\\xdc\\xf7\\x95\\xd4\\x90\\x23\\x72\\xe8\\xa0\\x3e\\x94\\x57\\x7e\\x6e\\x7d\\x0c\\x48\\xae\\x3e\\x6e\\x03\\x14\\xdc\\xc6\\x13\\x8a\\x3c\\x66\\x05\\x2c\\x64\\xc0\\xce\\x9c\\xe2\\x35\\xe3\\x71\\xbc\\x24\\x41\\x10\\x2d\\x26\\x9e\\x23\\x5e\\x5e\\xab\\x17\\x07\\x89\\x97\\x6c\\x49\\x58\\xf9\\xe5\\xad\\x7a\\x71\\x10\\x4b\\xc4\\x87\\x85\\xe7\\xb0\\x44\\x24\\x2e\\x1c\\x24\\x8f\\xf6\\xd2\\x24\\x0d\\x78\\xea\\x39\\xf2\\xe5\\x17\\xf9\\xe2\\xa0\\x29\\x8f\\x26\\xd3\\xdc\\x73\\xd4\\x5f\\x07\\xcd\\xc9\\x85\\x9a\\x53\\xcf\\x99\\x93\\x8b\\xe7\\xf2\\xd1\\x41\\x92\\xb1\\x78\\x86\\xbf\\xa4\\x49\\xcc\\x3d\\x47\\xfc\\x8a\\xe7\\x73\\x55\\x57\\x9a\\x9c\\xab\\xba\\xa4\\x43\\x8a\\x54\\x6a\\x1d\\xb4\\xca\\x64\\xc8\\x01\\x67\\x95\\xf1\\x17\\x64\\x29\\x6f\\x0e\\x8b\\x26\\x0b\\xcf\\x39\\x3b\\x8d\\xe5\\x3d\\x89\\xe7\\x51\\x20\\x6a\\x92\\x7f\\x1c\\x0b\\x1b\\x56\\x16\\xd3\\x2a\\x09\\x0d\\xa9\\xa2\\xe3\\xf9\\x0e\\x59\\x2e\\xe3\\x88\\xc9\\x93\\xf2\\xbd\\x0b\\x31\\x75\\xdd\\x8b\\x79\\x2c\\x04\\x6a\\x2a\\x64\\xfc\\x9c\\x2f\\x72\\xa1\\x71\\xe8\\xd0\\xa3\\x35\\x06\\x50\\xea\\x78\\x46\\xb4\\x7f\\x14\\x73\\x01\\xbf\\x2e\\x43\\x9d\\x51\\xcb\\x8c\\xc0\\x30\\x51\\xa6\\x83\\x09\\xa6\\xc6\\x86\\xd0\\xf7\\x4d\\x98\\xdc\\x55\\x1c\\x17\\x67\\x76\\x90\\xd6\\x09\\xcf\\x71\\x3d\\xde\\x6d\\xff\\x9e\\x2a\\xa5\\xe1\\xd1\\xc3\\x43\\x5f\\x11\\x29\\x05\\xc3\\x80\\x22\\x32\\x94\\xae\\xaf\\xfe\\x28\\xc0\\xca\\xdc\\xa1\\xf2\\xb1\\xea\\x42\\x04\\x3b\\x1a\\xdf\\x79\\x29\\x8a\\x4c\\x84\\x14\\x32\\xe8\\xf7\\xef\\x13\\x57\\x50\\x71\\xe2\\xd2\\x6e\\x17\\xa9\\x9b\\x13\\x31\\x71\\x09\\x22\\x2e\\xc1\\x35\\xe1\\xe0\\x42\\x8e\\xf3\\x4a\\x60\\xe2\\xbb\\x68\\xce\\x93\\x55\\xbe\\x7b\\xdd\\x18\\xf1\\x0b\\xd4\\x57\\x52\\xe2\\x25\\xb5\\x68\\xf0\\x67\\x5a\\xf2\\xc3\\x95\\xfb\\x42\\xe9\\x51\\x0f\\xa6\\x64\\xb1\\xe0\\xb1\\x5f\\x8b\\x39\\x59\\x9a\\xe0\\x3a\\x9d\\xda\\xc5\\x5a\\x26\\xfd\\x3c\\x5a\\x04\\xc9\\x79\\xa7\\xa3\\xfe\\xba\\xcb\\x24\\xcb\\x35\\xb8\\x32\\x8d\\x04\\xc1\\xa3\\x33\\xbe\\xc8\\x9f\\x47\\x59\\xce\\x17\\x3c\\x55\\x2c\\xfb\\x75\\xca\\xb3\\x5c\\xca\\x11\\x80\\x6c\\x33\\x69\\x8e\\x57\\x14\\x38\\xcf\\x1e\\xbf\\x39\\x7d\\xf1\\xc8\\x81\\x3e\\xd7\\x24\\x21\\x88\\xb2\\x65\\x4c\\x2e\\xb1\\x40\\x65\\x2e\\x88\\xb4\\x11\\xcb\\xf4\\x83\\xc6\\x05\\x97\\x2c\\x97\\x7c\\x11\\x3c\\x98\\x46\\x71\\x00\\x38\\xd4\\x36\\x2b\\x6e\\x50\\xeb\\x0f\\xd9\\x2a\\x9f\\xe3\\xb0\\x62\\x83\\xdc\\x4d\\x96\\x7c\\x01\\x44\\x55\\x2c\\x4e\\x04\\xa2\\x29\\x31\\x09\\x3b\\x42\\x96\\x7a\\x36\\x9f\\xf3\\x20\\x22\\x39\\x77\\xba\\x92\\xc3\\xa4\\x64\\x11\\x24\\x73\\x00\\xd1\\x14\\x3b\\x61\\x24\\x96\\x13\\xc6\\xa1\\x1b\\x27\\x0a\\xa3\\x15\\x2e\\xb1\\x24\\x1e\\x3a\\xb7\\x1c\\xaf\\x21\\xbd\\xeb\\xf4\\x7a\\x4e\\xd7\\xfa\\x30\\x4d\\xb2\\xdc\\xe7\\xf8\\x73\\x35\\x7d\\x33\\x89\\x78\\xc0\\xb9\\xe5\\x60\\x3c\\xdd\\x6c\\x66\\x6e\\x92\\x46\\x93\\x68\\x81\\xf1\\x14\\x76\\x3a\\x33\\x57\\xd0\\x21\\x8c\\x27\\x2a\\x5a\\xf3\\x32\\x49\\xf3\\x81\\x9b\\x2c\\xb4\\x36\\x0c\\x60\\x81\\x44\\x3a\\xf4\\xc3\\x9d\\x91\\x07\\x8e\\xce\\xe4\\xa0\\x03\\x8e\\xda\\x03\\x7d\\xa5\\x84\\x84\\x20\\x78\\x74\\xf9\\x76\\x84\\xd7\\xd6\\x4c\\xda\\xf1\\xd8\\x43\\x7b\\x8a\\xc1\\x04\\x4d\\xa1\\xbc\\x15\\x60\\xfb\\xde\\x35\\x0b\\x6d\\xda\\xb6\\xbc\\xa7\\x5e\\xb5\\xc0\\xb7\\xae\\xee\\x92\\x27\\x48\\xdf\\xf6\\xc8\\x7c\\xba\\xdd\\xa3\\xad\\xe5\\x58\\x86\\x45\\x57\\xb1\\xab\\xe1\\x9a\\xe9\\xa7\\xf2\\x7a\\x84\\xe7\\x3e\\x73\\x9f\\x2b\\x43\\x86\\x18\\x8e\\x62\\x27\\x5c\\x2d\\x87\\xeb\\x40\\x2d\\xac\\xf5\\x73\\x8f\\x17\\x7e\\x80\\xd5\\xab\\xae\\xfb\\xa8\\xd6\\xc7\\x7e\\x43\\xe4\\x59\\xbe\\xb5\\xee\\xb8\\x58\\x64\\xd6\\xd2\\x3c\\xa5\\xe6\\xf6\\x0e\\x8a\\x6b\\x94\\x86\\xa4\\xad\\x07\\xaa\\xc7\\x67\\xb4\\xe1\\x82\\x41\\xf1\\xe1\\x17\\x5a\\xd4\\xc2\\x7b\\x13\\x37\\xe5\\x19\\xcf\\x01\\x2c\\xa0\\x7f\\xba\\x37\\x74\\xb5\\x65\\x5b\\x7c\\x40\\x05\\x11\\x03\\xd0\\x67\\x32\\x8c\\xb5\\xb4\\x2f\\xa9\\xb6\\x0c\\xd5\\x1f\\xd5\\x75\\xe6\\xe9\\x96\\x31\\x43\\x15\\x99\\x1d\\x47\\xb5\\x22\\x10\\x8f\\x28\\xd2\\x66\\x21\\xe2\\x0a\\xa5\\x86\\x96\\xe4\\x88\\xb8\\x8a\\xda\\x89\\x97\\xcd\\x46\\x90\\x2c\\x99\\x0f\\x1a\\xb2\\x25\\x5f\\x1a\\xa2\\x35\\xff\\x52\\x0e\\x8f\\xcc\\xd6\\x30\\x50\\xbf\\xd8\\x1d\\xcd\\x6c\\x92\\x5c\\xb3\\x0f\\x9b\\x96\\x6b\\xc2\\x5e\\x51\\x5e\\xbf\\x06\\x40\\x0e\\xe0\\xce\\xc5\\x2a\\xfb\\xea\\xb6\\x42\\xa5\\x6a\\xe2\\xfc\\x84\\x6e\\x36\\x4f\\x29\\x80\\xfe\\x33\\xba\\xd9\\x80\\x27\\x14\\x40\\xf4\\x8c\\xe2\\x76\\x1f\\xfa\\x8f\\xa8\\x8c\\x46\\x2e\\x72\\xc9\\xc9\\x7d\\x42\\xab\\xd2\\xa2\\x84\\x40\\xd8\\x95\\xab\\xef\\x87\\xec\\x74\\xca\\x47\\x73\\x55\\x64\\x45\\x84\\xb7\\xef\\x90\\xd4\\xf6\\x3b\\xff\\x49\\x4d\\x85\\x21\\xea\\x5a\\xc9\\x5f\\x29\\x2c\\x14\\x77\\x79\\xb2\\xa3\\xe1\\x50\\xfc\\x2b\\xf5\\xdb\\x97\\x40\\x22\\x68\\x49\\xba\\xe0\\x66\\xb3\\x72\\xff\\xd0\\xc4\\xda\\x3c\\x55\\x43\\x64\\xab\\x51\\x4d\\xdf\\x6b\\xb0\\x30\\xae\\xc3\\x1e\\x82\\x4b\\x31\\x2e\\x97\\x14\\x0b\\xb6\\x02\\xd1\\x25\\x05\\x14\\x42\\xaf\\x9e\\x49\\x5e\\x95\\x25\\xda\\x27\\x46\\x6e\\x80\\x1e\\xa9\\x55\\x70\\x6a\\x8d\\xd7\\xaf\\xd4\\x56\\x01\\x7c\\x82\\x05\\x0e\\xfa\\xca\\xc2\\x28\\x30\\x4d\\xed\\x26\\xb9\\xd4\\x98\\x07\\x29\\x5c\\x5f\\x88\\x9a\\x8a\\x73\\x0a\\x1e\\x50\\x44\\x60\\x21\\x41\\x5b\\xf3\\xf7\\x1b\\xd5\\x76\\xce\\x36\\xa9\\x07\\xa9\\xd7\\x2f\\x6d\\xe2\\x7e\\x3f\\x49\\x92\\xc9\\xc7\\x77\\x53\\xbe\\x20\\x34\\xe6\\x15\\xe4\\x2a\\x72\\x7c\\x05\\xee\\xb9\\x80\\xa6\\x31\\x45\\x4b\\x10\\x9f\\xf4\\x2d\\x0d\\x46\\xc2\\xb0\\xd1\\x89\\xa9\\x45\\x23\\x9f\\xa7\\x2a\\x29\\xc2\\xed\\x81\\xa0\\x95\\xa4\\x8d\\xcf\\xa1\\x89\\x96\\xaf\\xb2\\xfb\\xa4\\x66\\xe1\\xb1\\x83\\xc4\\xbf\\x00\\x14\\x1d\\x21\\xb6\\x75\\xf7\\xa8\\x48\\x3d\\x96\\x97\\xa7\\xea\\x56\\xcb\\x34\\x19\\xc7\\x58\\x26\\x57\\xcb\\xed\\x79\\xc3\\x72\\x63\\xb5\\xa6\\x4e\\xec\\x05\\x60\\x5a\\xdc\\x1e\\x14\\xcf\\xbf\\xbe\\x8a\\xae\\x06\\x48\\x6d\\xf4\\x7c\\x85\\xf2\\x3d\\xff\\x02\\xe5\\x2b\\x3b\\xf3\\x92\\x1a\\xfb\\xac\\xda\\xeb\\x7a\\x61\\xa8\\x5d\\xe0\\x4e\\x30\\xf1\\x03\\x49\\x0d\\x02\\x97\\x61\\x56\\x6d\\x65\\x1e\\x3c\\xb7\\x2d\\x8d\\x53\\xbe\\xc0\\xdb\\x3b\\xc5\\xa5\\x65\\x45\\x0d\\xe0\\xa5\\x8a\\x63\\x2f\\xe3\\x77\\x5f\\xca\\x4b\\xe3\\xd5\\x33\\x83\\x85\\x6f\\xc3\\xaa\\x63\\x0f\\x6e\\xf7\\x6b\\x5f\\x19\\x59\\x30\\x1e\\x63\\xbb\\x4b\\x4a\\x03\\x54\\x63\\x64\\xf3\\xbf\\x97\\x42\\x2e\\x7e\\x5c\\x1b\\x98\\xd7\\xba\\x2d\\xd4\\x30\\x74\\x1b\\x15\\x5f\\x6b\\xca\\xa4\\xe0\\x11\\x97\\x40\\x81\\x55\\x2e\\x33\\x3c\\x80\\xb8\\x4c\\xda\\xeb\\x5d\\x6a\\xef\\x82\\xf7\\x11\\x97\\x13\\x83\\x42\\xf5\\x67\\x82\\x99\\x4b\\xfd\\x49\\xa7\\x03\\x26\\xee\\x74\\xb3\\x01\\x41\\xb7\\x8b\\x26\\x2e\\x91\\x5a\\x32\\xe0\\x78\\x02\\x51\\x1b\\xf0\\x4e\\x67\\x70\\x2f\\x80\\x10\\x0a\\x85\\x50\\x71\\x5c\\xbe\\xd9\\x80\\x10\\x4f\\xe4\\x15\\xa7\\xa2\\x7a\\x26\\xd8\\xc2\\x40\\x28\\x62\\xaf\\x29\\x60\\x88\\x42\\x0f\\x84\\x43\\x10\\xe0\\x10\\x69\\x2e\\x8b\\x99\\x3b\\x91\\xf7\\xa8\\x4c\\x70\\x00\\x4d\\xa2\\xfa\\xa3\\x20\\x7a\\xff\\xa3\\x80\\x41\\xf4\\x46\\x14\\xe7\\xe8\\x18\\x51\\x08\\x61\\x41\\xf4\\x0a\\xd2\\x96\\x7d\\x40\\xe4\\x07\\xcb\\x54\\xff\\xb6\\x94\\x9d\\xa9\\xbc\\xd8\\x4c\\xb2\\xa7\\x63\\xf9\\x77\\xb3\\x79\\x27\\xd6\\xbe\\x4f\\xdc\\xc9\\x90\\xb8\\xaa\\xdd\\x98\\x7a\\x44\\x62\\x07\\x11\\xaa\\x40\\xb5\\x3c\\x5e\\x69\\x8c\\xaa\\xae\\x8f\\x7a\\x49\\x55\\xe8\\xf6\\xf2\\x47\\xde\\x3a\\x21\\x27\\xea\\xb9\\x75\\x8f\\x14\\x9a\\xc0\\x35\\x17\\xb0\\x2a\\xc3\\xf5\\x54\\x91\\x2b\\x75\\xf9\\x0c\\x35\\xa6\\xc8\\x29\\xf4\\x43\\x30\\x33\\xeb\\x34\\x86\\xeb\\x09\\x88\\x61\\x51\\x78\\xa1\\xcf\\x05\\xdb\\xdd\\x53\\x9c\\x59\\xc5\\xcb\\x8d\\x9a\\x59\\xa7\\x33\\xb5\\xb7\\xc6\\x5e\\x0e\\x27\\x60\\x0a\\xbd\\x46\\xf0\\x93\\x42\\xb6\\x5b\\x6a\\x40\\x72\\xac\\xb8\\x7d\\xcf\\x72\\x61\\xa3\\xea\\x69\\x0d\\x4b\\x4b\\x1a\\xa7\\xe9\\xc9\\x91\\x20\\xae\\x35\\xd4\\xfe\\xe5\\x8b\\xf9\\x8f\\x65\\xfe\\x6a\\xa2\\x5e\\x58\\x5b\\x2a\\x1a\\x5d\\xd7\\x04\\x63\\xcc\\xa4\\x34\\x71\\x8c\\xd4\\x95\\x41\\xd6\\x75\\x44\\x9a\\x19\\xb6\\x98\\x0c\\xa9\\xd6\\xd2\\x3c\\xb1\\x95\\x27\\xad\\x28\\xcf\\x78\\x1c\\x3a\\x50\\x4c\\x2d\\xc1\\x03\\x63\\xa8\\x0f\\x30\\x43\\x1c\\x13\\xf7\\x14\\x85\\x98\\xb8\\xbf\\x08\\xdc\\xaf\\xed\\x20\\x3e\\x87\\xeb\\xb7\\x14\\x04\\xe8\\x25\\x05\\x7c\\xb3\\x39\\x47\\xe1\\x66\\xa3\\x82\\xf3\\x43\\x23\\xe9\\xb7\\xfb\\x0a\\xcf\\xa2\\x10\\xfc\\x46\\x41\\x00\\x61\\xa0\\x58\\x2d\\x97\\x7e\\x11\\x48\\x64\\x50\\xc1\\xe1\\xa3\\x10\\x7c\\x26\\x22\\x83\\x99\\xa9\\x29\\x56\\x59\\x45\\xa5\\x97\\x60\\x0a\\xe1\\xfa\\xbd\\xa8\\x6a\\x8a\\x54\\x51\\x5f\\x16\\x2d\\xad\\x63\\x6a\\x92\\x66\\x42\\x92\\xd6\\xee\\x11\\xb3\\xad\\x2c\\x13\\x41\\x30\\x8b\\x89\\x14\\xa8\\x3e\\x61\\xa6\\x14\\x3f\\x64\\x56\\x03\\x92\\x88\\x8d\\x8e\\xdb\\x98\\x6e\\x36\\xb5\\xdb\\x8f\\x5f\\x6e\\x36\\xbf\\x8b\\x59\\x66\\x10\\x16\\xd6\\x2a\\x79\\x5f\\xa2\\x37\\xe2\\x56\\x4c\\x7e\\x81\\x31\\x6b\\xb1\\xe8\\xa7\\xb8\\xdd\\x47\\x81\\x6a\\x0c\\x47\\x33\\x68\\xf9\\x36\\x4c\\x6a\\x79\\x98\\x9d\\x47\\x75\\x5c\\xb3\\x53\\x6a\\xba\\x32\\x41\\x21\\xb4\\x7a\\x28\\x90\\xb2\\x82\\x26\\x1b\\xbe\\x26\\x6e\\x24\\x7b\\x16\\x09\\x90\\x42\\xc0\\x72\\xe7\\x62\\x16\\xaa\\x6c\\xff\\xb3\\xcc\\x07\\x5a\\xea\\xa4\\x5a\\xea\\x14\\xa3\\x40\\xb1\\x12\\x2e\\xeb\\x32\\xa6\\x24\\x01\\x40\\x2c\\xec\\x2d\\x99\\xd3\\x46\\xda\\x39\\x6e\\xb2\\x35\\xfa\\x04\\xff\\x4f\\x91\\x5a\\xe8\\xc3\\x37\\x9a\\xe8\\x12\\xa4\\x70\\x5a\\xfd\\xf9\\xa4\\x05\\xe8\\x48\\xb2\\xb2\\x6a\\x68\\xdf\\x58\\x94\\x23\\x0a\\xc1\\xb1\\xc4\\x68\\x2a\\x9a\\xdb\\xa6\\xee\\x14\\xaa\\x1b\\x69\\x3b\\x1d\\xe2\\x4e\\x7d\\x21\\x2c\\x33\\x48\\x24\\x37\\x14\\x88\\x42\\x5d\\x02\\xa9\\x5b\\x4e\\xea\\x1f\\xd4\\x5c\\x79\\x2c\\x91\\x50\\x0d\\xea\\x74\\x48\\xdd\\x89\\xb6\\xe6\\xbb\\x0c\\x7a\\x65\\x26\\x3d\\xc4\\x1c\\xae\\xff\\xd4\\x43\\x2f\\x81\\x70\\x29\\x0a\\xbd\\xa0\\x82\\x4a\\x56\\xfb\\x99\\x25\\xbf\\x3c\\xc2\\x98\\x4a\\x62\\xa8\\x05\\x29\\x26\\x8d\\x56\\xae\\xdc\\x8a\\xa0\\x76\\x62\\x55\\xf8\\xf7\\x92\\xc2\\x0a\\x0c\\xd8\\x62\\x50\\xc4\\x9d\\x76\\x3a\\xb5\\x06\\x50\\x21\\x8c\\xc8\\x1d\\x3e\\x8a\\x2f\\x2c\\xc9\\x4e\\x70\\xb7\\xf5\\x43\\x95\\x51\\x0d\\x2f\\x2c\\x1e\\x80\\x97\\xe8\\x21\\xf4\\x5f\\xee\\xdc\\x8e\\xa0\\xb8\\xa6\\xe3\\xf7\\x6e\\x1d\\xb4\\x5e\\x27\\xa9\\x00\\x90\\xb5\\x92\\x50\\xfa\\x70\\xc8\\x1b\\x37\\x5a\\x24\\xe5\\xad\\x30\\x4d\\xe6\\xad\\x17\\x09\\x9b\\x46\\xbf\\x45\\x39\\x6a\\xa5\\x9c\\xf1\\xe8\\x8c\\x07\\x2d\\x7a\\x79\\xd0\\x7a\\x37\\xe5\\xad\\x07\\x71\\x92\\xad\\x52\\xde\\x3a\\x5d\\xe5\\xd3\\x24\\xcd\\x5a\\x42\\x39\\x4d\\x5b\\xf9\\x94\\xb7\\x5e\\x3c\\x7b\\xd7\\x8a\\x23\\xc6\\x17\\x19\\x77\\x5b\\xa7\\x71\\xdc\\x4a\\xf2\\x29\\x4f\\x15\\xe4\\x28\\x6b\\x3d\\x48\\x96\\x97\\x69\\x34\\x99\\xe6\\x07\\xad\\xa3\\x7e\\xff\\xf6\\xe1\\x51\\xbf\\x7f\\xb7\\x09\\xa2\\x2a\\x2b\\x2f\\x67\\xca\\x5a\\x6f\\x78\\xc6\\xd3\\x33\\x1e\\xb8\\x07\\xb7\\x7a\\x15\\x7a\\xbc\\xb2\\x94\\x95\\x29\\x1e\\x8d\\x15\\x12\\x3d\\x36\\x6a\\xcb\\x53\\xb1\\x82\\x2b\\x39\\xa9\\x14\\x9d\\xc4\\xa2\\x52\\x92\\x95\\x2d\\x5b\\x9e\\xaa\\xcf\\xef\\xb1\\x96\\x3b\\x4d\\xae\\xc8\\x88\\xa2\\xd4\\x92\\xb9\\xe6\\xb8\\x5f\\xbc\\xfa\\xaa\\x24\\xa2\\xc5\\x10\\x55\\x99\\x4d\\x49\\x5e\\x75\\x3a\\x2a\\x51\\x17\\x04\\xb0\\x24\\x7d\\xc6\\x14\\x56\\x09\\xae\\x2e\\xf5\\xf5\\xa5\\xd2\\xfa\\x8d\\x0c\\xa9\\x29\\x47\\xa0\\x07\\xa8\\x3b\\x3f\\x3c\\x44\\xfd\\xfb\\x98\\xba\\x73\\xe5\\xa3\\xa5\\x40\\xea\\x9b\\x57\\x1f\\x2b\\xa5\\xf4\\x71\\x85\\x1d\\xee\\x53\\x25\\xef\\x78\\xba\\xdf\\x6d\\x63\\xad\\x13\\x2b\\x5c\\x72\\x8a\\xd7\\x6a\\xb9\\xa2\\xff\\xe9\\xbf\\x6f\\x14\\x56\\xb5\\x07\\x92\\x92\\x14\\xfe\\xab\\x3d\\x9c\\xaa\\x9c\\x0d\\x39\\x7c\\x6f\\xcc\\x52\\xaf\\x59\\xd5\\xde\\x94\\xce\\x19\\x62\\x2a\\xfa\\x42\\x2c\\xc7\\x4c\\x8a\\x0c\\x6d\\xea\\xff\\x25\\x68\\x93\\xed\\xd4\\x63\\xae\\xea\\x77\\x8d\\x9e\\xe1\\x9e\\x5a\\x17\\xec\\xfd\\xad\\x65\\x90\\x53\\x49\\xd1\\xcb\\x52\\xdf\\x5b\\x64\\x83\\xb8\\x53\\xe5\\x0e\\x35\\x92\\x09\\x63\\xa8\\x94\\x6c\\x59\\x51\\x65\\x2f\\x7c\\xf5\\x35\\xf9\\x55\\xf2\\x40\\xc1\\x70\\xb6\\x85\\x94\\x09\\x9a\\xc2\\x75\\x80\\x27\\x3e\\xc7\\xd3\\x02\\xfa\\xdf\\x6b\\xfa\\x16\\x54\\x82\\xf6\\x04\\xae\\x27\\xf6\\xe4\\xbf\\x1e\\x86\\xe5\\x1c\\x79\\x1c\\x4c\\x2c\\xc7\\x9a\\x50\\xb1\\x44\\xed\\x6e\\x59\\x1b\\xe6\\x5d\\x49\\xb8\\xda\\xd1\\x66\\xd6\\x7e\\xfe\\x33\\x02\\x88\\x3b\\xad\\x6a\\xaf\\x36\\xe2\\x2f\\x01\\x1d\\x0d\\xc6\\x82\\x82\\x54\\xe3\\xfb\\x17\\x2d\\x07\\x38\\x12\\x64\\x4a\\x10\\x53\\x01\\xad\\x72\\xb8\\x8b\\x10\\xc3\\x94\\x8d\\xe8\\xd8\\x17\\xc2\\xc4\\x4a\\xdd\\x95\\x6a\\xcc\\x32\\xcc\\x25\\x10\\x99\\x1b\\xcf\\x45\\x26\\x31\\xba\\x11\\xee\\x17\\xa5\\x89\\x55\\xe2\\xa6\\xce\\x21\\x54\\x4b\\x9f\\x4a\\xd1\\xb9\\x12\\x99\\x99\\xc0\\x14\\x31\\x49\\x66\\xc3\\xa6\\x4d\\xdc\\x4f\\xbe\\x11\\x14\\xc5\\x07\\x7d\\x9b\\x0e\\x0a\\x31\\x1f\\xf5\\xc7\\x68\\x82\\xf9\\x68\\x30\\xf6\\x39\\xe6\\xa3\\x23\\xb9\\xe3\\x23\\x04\\x92\\xc9\\x70\\xe2\\x85\\x96\\xc0\\xa0\\x79\\xbf\\xbc\\x51\\xeb\\x29\\xa2\\x46\\xbe\\x6b\\xab\\xfb\\x06\\x05\\xb2\\x11\\x29\\x31\\x4f\\xb1\\xa0\\x11\\x35\\x81\\x4f\\xdd\\x2a\\x23\\xc5\\x01\\x8a\\xa7\\xd2\\xf2\\xf6\\x1b\\x95\\x57\\x86\\xda\\x17\\x49\\x19\\xfb\\x9b\\x65\\x7b\\xa8\\x5d\\xc4\\x58\\xa6\\xc3\\x40\\xf0\\x61\\x21\\x68\\x94\\x97\\x32\\xcf\\xe0\\x9a\\xe2\\x19\\x92\\x28\\xdf\\x47\\x72\\xbc\\x37\\x1b\\xc0\\x70\\xbb\\x0f\\x0b\\x29\\x94\\x53\\x3f\\x90\\x6d\\xfb\\x0c\\x88\\xfb\\x0b\\x22\\xa8\\xdd\\x87\\x28\\xa8\\xde\\x06\\xb0\\x7e\\xe9\\xe3\\xab\\x21\\xf8\\x5e\\x70\\xae\\x29\\x0a\\x20\\xa2\\xee\\x7b\\x01\\xc8\\xa3\\x0a\\x95\\x44\\x1a\\xf4\\x95\\x1c\\x78\\x20\\x6f\\xff\\x61\\x80\\x42\\x24\\x26\\xcb\\x25\\x63\\x29\\xf6\\x44\\x58\\xf0\\xca\\x6a\\xf5\\x04\\xac\\xb4\\x4c\\x89\\x02\\xaf\\x7c\\xb1\\x08\\x7d\\xb1\\x6c\\xdb\\x7d\\x54\\xe3\\xfe\\xd6\\x7d\\x41\\x7f\\x0b\\x15\\xd8\\xe2\\x40\\x82\\xff\\xfc\\x4d\\x05\\x03\\xfa\\xdb\\x56\\x71\\x8d\\xc5\\xd1\\x79\\xc8\\x43\\x9e\\xa6\\x3c\\x68\\x4d\\x49\\xd6\\x22\\x71\\xca\\x49\\x70\\xd9\\x0a\\xa3\\x94\\x07\\x4e\\xbd\\x84\\xe2\\x59\\xa7\\x2a\\xc7\\x03\\x12\\xc7\\x3c\\xd8\\xbe\\xd8\\xe7\\xf5\\x6e\\xd5\\xaf\\x45\\xcd\\xaf\\xbf\\x58\\xf1\\x39\\xc9\\x5a\\x6a\\x19\\x8a\\x3a\\x5f\\xef\\x5e\\x22\\xa4\\xbf\\x6d\\xd7\\xc6\\x98\\x25\\x91\\xd7\\x8c\\x94\\x9f\\x15\\x75\\x65\\x8a\\xba\\xa2\\xbe\\xb1\\x0a\\x62\\x52\\x30\\x66\\x33\\x0b\\x5b\\x4c\\xaa\\x56\\x8f\\x02\\x29\\x98\\x98\\x20\\x6f\\x9a\\xd6\\x2b\\xc5\\x9e\\x32\\xe3\\xda\\xc3\\x19\\x0a\\x99\\x60\\x75\\x95\\x0c\\xc9\\x1a\\x2e\\x83\\x32\\xab\\x47\\xaf\\x1d\\x41\\x9c\\x18\\xe0\\xd2\\x11\\xae\\x5c\\x68\\xdf\\x53\\xc0\\x11\\x43\\xcc\\x78\\xb2\\x95\\xaa\\x4b\\xa1\\x08\\x6d\\xfd\\x22\\x7d\\x81\\x15\\xbe\\x5a\\xb2\\x61\\x79\\xa3\\xee\\x73\\x02\\x42\\x86\\xd4\\x3e\\x7a\\x75\\x15\\x2e\\xf3\\x09\\x0e\\x4b\\xeb\\x00\\x67\\x98\\x01\\x9b\\xe6\\x4c\\x99\\x6d\\x4c\\xa5\\x9b\\xcd\\xba\\x90\\x97\\xe7\\x9a\\xcd\\x82\\xcd\\xa6\\xdc\\x36\\x50\\xf5\\x6d\\x7b\\xec\\x21\\xb5\\x7d\\xf1\\xf6\\xc1\\x9b\\x67\\xaf\\xdf\\x39\\x82\\x30\\xac\\x5f\\x7b\\x1c\\xbd\\xd5\\xdb\\xea\\x05\\x9a\\x28\\xc4\\x05\\x11\\x43\\x21\\x44\\x53\\x25\\x01\\xce\\xb0\\xda\\x6b\\x67\\x6e\\xae\\xe6\\x6b\\x58\\x3e\\x79\\xb7\\x1f\\x1d\\xfb\\xfd\\x7b\\x33\\xb9\\xe8\\xf4\\xa6\\x4a\\xf3\\xa6\\xcf\\x27\\x31\\x8a\\xed\\xbe\\x1a\\x89\\x58\\x56\\x33\\x63\\x60\\x80\\x1c\\x9d\\xb7\\x25\\xa3\\xc9\\xf3\\xa0\\x15\\x26\\x69\\x2b\\x4e\\x48\\x10\\x2d\\x26\\x2d\\x15\\x94\\xb4\\xe5\\x74\\x03\\xe8\\xff\\x0f\\x4c\\xc4\\x5a\\x9a\\x08\\x5e\\x1a\\xc3\\x02\\xcd\\x20\\x0a\\xdd\\xb7\\x82\\xce\\x70\\x37\\x59\\x88\\x12\\x58\\x3c\\x48\\x6c\\xcf\\x72\\x92\\x73\\x36\\x25\\x8b\\xba\\x89\\x9e\\xbb\\xf2\\xeb\\x5b\\xf1\\xb5\\xd3\\x71\\xe4\\x19\\xfc\\xc0\\x69\\xe3\\xad\\x74\\x96\\xcc\\x97\\x02\\xb5\\xb6\\xbe\\x6c\\x36\\x40\\x76\\x82\\xb9\\x31\\xd9\\x6c\\xda\\x03\\x34\\x15\\x6c\\x7e\\x22\\x78\\xfc\\xa4\\x5c\\xe0\\xb0\\x90\\xcd\\x91\\x7e\\x80\\x78\\xb7\\xfb\\x52\\x61\\xb6\\x07\\xa0\\x8f\\x1c\\xb9\\x4c\\x5a\\x72\\x33\\x7b\\xb7\\xe3\\x07\\xbb\\x3d\\xf7\\x43\\xcc\\x5c\\x62\\x36\\x78\\x33\\x89\\x05\\x8c\\x82\\x10\\xad\\xf5\\x16\\x29\\xbf\\xc8\\x7b\\x9f\\xc8\\x19\\x51\\x40\\x1c\\x19\\xa5\\x3b\\xe3\\xb9\\xe7\\xbc\\x7f\\xf7\\xf8\\xf0\\x67\\xa7\\x80\\x7e\\x26\\x10\\x38\\x84\\x7e\\x20\\xfe\\x12\\xe8\\xc7\\x82\\xb4\\x6d\\x6f\\x4e\\x95\\xf7\\xc6\\x96\\xf8\\x17\\xb3\\x52\\xff\\xd1\\x5f\\x01\\xc5\\x80\\x54\\x68\\x07\\xdd\\x09\\x37\\x7b\\x5d\\xd9\\x2f\\x97\\xef\\xc8\\xe4\\x25\\x99\\x73\\xe0\\x3c\\x7d\\x74\\xfa\\x50\\xba\\xd1\\xf4\\xdb\\xd8\\x38\\x40\\x0c\\xe9\\xa8\\x3f\\xf6\\xc8\\xf6\\x16\\x59\\x55\\x5b\\xc4\\x40\\x29\\x0b\\x6a\\xa9\\xef\\xb5\\x21\\xaf\\xea\\x4d\\x68\\x30\\x06\\x99\\x85\\xee\\x9e\\xab\\xfa\\x3a\\x9d\\x4f\\x4c\\xd1\\x5c\\x99\\xed\\xad\\xad\\xe9\\xc9\\x2f\\x52\\x2e\\xd1\\x38\\x2d\\xbd\\x37\\x6b\\x9c\\x59\\xac\\x74\\x8d\\x50\\xe7\\xf2\\x51\\x4d\\xa6\\x7a\\xde\\x41\\xaf\\x73\\x9f\\x96\\xdb\\x89\\xcd\\x98\\x2f\\xd5\\xac\\x25\\x49\\xf9\\x22\\x7f\\x99\\x04\\xbc\\xfe\\xe6\\xa6\\x7c\\x9e\\x9c\\x71\\x35\\xe8\\x04\\xca\\x2d\\xd1\\x6a\\xc1\\xcf\\x6a\\x0b\\xde\\xf9\\x35\\x53\\x61\\x23\\x5a\\xb2\\x45\\x2d\\x20\\x15\\x83\\xef\\x9c\\x2e\\xe9\\x3a\\xd0\\x91\\xd7\\xc0\\xb1\\x2e\\x76\\xbc\\x96\\xd3\\xa5\\xd0\\xb7\\x95\\x1a\\x73\\xdb\\xbb\\x28\\x80\\x49\\xf1\\x00\\xcc\\x98\\x20\\xf3\\x4f\\xdd\\xd0\\x4d\\x0c\\x7d\\x9c\\x33\\x3c\\x65\\x28\\x61\\x78\\xc1\\x2a\\x12\\xb9\\xb4\\x05\\xa4\\xdf\\x85\\x80\\xa4\\x5c\\xac\\x11\\x71\\x7f\\x43\\xc4\\xe5\\x44\\x60\\x9f\\xc5\\x01\\x17\\xe5\\xf0\\x32\\xcc\\x24\\x66\\x12\\x5c\\x3a\\x15\\x6b\\xa2\\x34\\x17\\x79\\xd6\\x86\\x80\\x1c\\x3f\\x3a\\x41\\x15\\x32\\x7b\\x6b\\x92\\x5d\\x2e\\x98\\xd7\\x1e\\xa0\\x40\\xb0\\x1b\\x4f\\x48\\xa7\\xd0\\x76\\x8b\\xd5\\xc2\\x01\\xb0\\x37\\xbc\\xbe\\xa7\\x40\\x48\\x98\\x92\\x58\\x99\\xf3\\x1c\\xb0\\x90\\xbd\\x73\\x1f\\x90\\x9a\\x6e\\xb1\\x60\\x98\\xa8\\x33\\x62\\x89\\xfb\\xb8\\xfe\\x69\\x6e\\x7d\\xfa\\x1b\\x2f\\x99\\x7e\\x94\\x88\\x90\\x30\\x75\\x1d\\x5c\\xe2\\xae\\xea\\x85\\x08\\x7e\\x2a\\xba\\xb7\\x64\\xd0\\x37\\x16\\xa4\\x3a\\xf5\\xdf\\xde\\x3c\\x51\\xa3\\x40\\xf1\\x75\\x06\\x00\\x49\\xbe\\xd5\\x9e\\xd2\\xcd\\x26\\xa5\\x00\\x0e\\x9f\\x88\\x2a\\x2b\\x77\\x7a\\xb8\\x66\\x4a\\x50\\x9f\\x33\\x10\\x20\\x0a\\x61\\x01\\x3d\\x9d\\xa2\\x59\\x5c\\x39\\x82\\xa6\\x35\\x02\\x33\\x9e\\x12\\xc0\\x6a\\x50\\xbe\\x32\\xca\\xfa\\x73\\xf3\\x60\\x0b\\xc2\\xa7\\x06\\xe8\\x9c\\xec\\x31\\x61\\xaf\\xf5\\xe1\\x00\\x82\\x7e\\xf3\\x28\\xe2\\xc4\\x63\\xfa\\xb4\\xde\\x99\\x41\\xc1\\xb7\\xe2\\x41\\xa6\\xb8\\x49\\x7d\\x98\\x75\\xdd\\x6f\\x47\\x64\\xdc\\xe9\\x88\\x5f\\x57\\x11\\x6f\\x93\\x7d\\xf9\\xb5\\xec\\x13\\x62\\xb2\\x12\\xd2\\x70\\x0a\\xa3\\xb1\\xcf\\x04\\xae\\x9b\\x2e\\xb9\\x54\\x8b\\x7d\\xb3\\xa9\\xf8\\x04\\xc6\\xa5\\x37\\x89\\xc5\\x2f\\x86\\x04\\x40\\x6f\\x8f\\xa3\\xc1\\x10\\x94\\x05\\x76\\x77\\xc2\\x1f\\xbe\\x7a\\xf1\\x40\\x39\\x04\\x3c\\x57\\x1c\\x4a\\x0b\\xb2\\x7b\\x60\\x01\\xc9\\xc8\\x74\\xa6\\xaa\\xc6\\x3c\\x27\\x6c\\x2a\\x33\\x0e\\x77\\x93\\x80\\xa3\\x28\\x9c\\x83\\x08\\xf4\\x2a\\xe9\\x7c\\xdb\\x79\\x42\\xd3\\xc1\\x61\\xed\\x0d\\x13\\xaf\\xfe\\x6e\\x6b\\x4c\\xb5\\x2f\\x40\\x48\\x4d\\x00\\x16\\x05\\x34\\x83\\x7f\\x46\\xf0\\x5b\\xb5\\x92\\xce\\xdc\\x5f\\x6a\\x13\\x21\\xe6\\xde\\xe4\\x7a\\x58\\x9f\\x4d\\x31\\x81\\x9b\\x0d\\x10\\x7f\\xb0\\xba\\xad\\x2d\\x10\\xcb\\x02\\xfa\\x16\\x22\\x08\\x1d\\x41\\x97\\x7e\\x44\\xb6\\xf4\\x6a\\x55\\x70\\x42\\x3c\\x8a\\xaa\\xd2\\x2a\\xf7\\xaf\\x58\\x47\\x62\\x2d\\xc3\\xb0\\xb2\\x55\\x2a\\x68\\x73\\x79\\x5c\\x75\\xb5\\x64\\xc9\\x5c\\xba\\x3f\\xe9\\x13\\xab\\x39\\xcf\\x72\\xf9\\x7e\\x32\\xf0\\x9c\\x65\\xca\\x0f\\x4f\\x6e\\x3b\\xe8\\xe4\\xc8\\x7a\\x3e\\xb6\\x9e\\x4f\\xac\\xe7\\x3b\\x9e\\x73\\xa2\\x0e\\xad\\x9e\\xa8\\x48\\x30\\x27\\x77\\xdc\\x23\\x07\\x9d\\xfc\\xec\\x39\\x27\\x3f\\x8b\\x74\\x5d\\xb7\\x78\\x75\\x90\\xa9\\xd8\\x73\\x4e\\xee\\x3a\\x48\\xd7\\x2a\\x5f\\x2c\\x93\\xc0\\xbf\\xcc\\x32\\x1d\\xd0\\xd2\\x51\\x82\\x94\\x26\\x1d\\x86\\xfb\\xfa\\xc8\\xc4\\x8e\\xe7\\x73\\x14\\x82\\xc1\\x3d\\x65\\xf9\\x66\\x3f\\x1c\\xd5\\x8f\\xf8\\xbc\\x5f\\xf0\\x33\\xbe\\x68\\xa9\\xb3\\x57\\xad\\x24\\x6c\\x95\\xa5\\xad\\x3b\\x92\\xd5\\x79\\x31\\xe6\\x07\\x5d\\x7c\\xa4\\x4c\\x35\\x72\\x53\\xbf\\xf4\\xa4\\x0e\\xac\\x63\\x69\\xa3\\xa0\\x2b\\x34\\x68\\x63\\xc7\\x56\\x9b\\x42\\xb6\\x2a\\xf6\\x2f\\x93\\x46\\x49\\x86\\x89\\xfb\\x00\\x98\\xb3\\x68\\xa5\\xb8\\x1c\\x74\\xbb\\x55\\x0d\\x4c\\x42\\x96\\x7b\\x6b\\xe2\\x11\\x6a\\xcb\\xa4\\x28\\xae\\x4e\\xf2\\x54\\x59\\x03\\x44\\x44\\x8e\\x62\\x8e\\xff\\xb5\\xf4\\x08\\x7f\\xee\\x3e\\xac\\x11\\x01\\xa6\\x8d\\xac\\x95\\x97\\xe7\\x68\\x8c\\x28\\xee\\xfb\\xf4\\x9e\\x3e\\x9f\\xa5\\xdb\\x41\\xbb\\x5d\\xa8\\x0f\\x89\\xa9\\x21\\xd7\\xba\\xc7\\x88\\x8e\\xc7\\xb6\\x13\\xd5\\xdc\\x7d\\xd0\\x58\\x41\\xfd\\xd0\\x97\\x3a\\xc4\\x07\\x6a\\x1b\\x12\\x29\\x2b\\xed\\x0a\\x4c\\xee\\x17\\x95\\xc7\\xdd\\xaa\\xab\\xa9\\xfb\\xf2\\x6a\\x6a\\x7a\\xaf\\xfa\\xea\\x97\\xe7\\xeb\\x64\\x5b\\xfc\\x77\\x80\\xb8\\x14\\x05\\xd2\\x85\\xc9\\x25\\x23\\xd6\\xed\\x8e\\x71\\x00\\x45\\xf3\\x8b\\xaa\\x10\\x66\\x45\\x53\\x3d\\x4a\\x03\\x5a\\x17\\xca\\x0d\\x1e\\xd3\\x9d\\xaa\\x4c\\x2d\\xe8\\x9d\\xbc\\x11\\x59\\x5a\\xb7\\x4d\\x1d\\x88\\x8f\\x82\\x31\\x16\\x7a\\x76\\xb7\\xeb\\xd7\\xaa\\x2a\\xe6\\x75\\x07\\x36\\xfb\\xa4\\xc3\\x3b\\x3d\\x9a\\x88\\x40\\xed\\x08\\x32\\x22\\x63\\x8f\\x8a\\x71\\xdc\\xf5\\xb0\\xb0\\x32\\x6f\\x36\\x5a\\x71\\xec\\x76\\xb5\\x55\\x5c\\xcd\\x0d\\x81\\x46\\x83\\x14\\x4b\\x5f\\xc2\\xd1\\xa7\\x72\\xb7\\x60\\x55\\x07\\x17\\x65\\xf6\\x3d\\x98\\x67\\x9d\\x71\\x41\\xa1\\xde\\x4d\\xe6\\xb9\\x90\\x91\\x89\\xf1\\x68\\x0f\\x11\\x2f\\xb7\\x42\\xab\\xc9\\x7c\\x57\\xeb\\xe5\\x95\\x9c\\xe3\\x95\\xcd\\x4f\\x54\\x98\\x31\\xdc\\xfb\\x07\\x0c\\x3d\\x30\\xfa\\xc7\\xeb\\x0d\\xbf\\x73\\xc7\\x5d\\xe8\\xc1\\x21\\x18\\x7a\\x1f\\x7a\\x1f\\x7a\\x2a\\xfd\\xc3\\x87\\x9e\\x3c\\xd8\\xf5\\xff\\xe0\\xb0\\x7a\\x1b\\x42\\x30\\xf4\\x3c\\x30\\xea\\x1f\\xde\\x1d\\x77\\xa1\\x28\\x81\\x47\\xea\\xd3\\xe6\\x7b\\x28\\x33\\x0e\\xbf\\x1b\\x77\\x15\\x24\\xf1\\x26\\x00\\xc8\\xb7\\xef\\xcc\\x51\\x15\\x08\\x87\\xdf\\xf7\\x2a\\x22\\x93\\xb3\\x72\\x47\\xb7\\x7e\\x61\\x7a\\xc7\\x22\\x06\\x0d\\x97\\xa5\\x1b\\x94\\x1c\\xb1\\x71\\xe5\\x1d\\x8f\\x1d\\xa8\\xb7\\x7a\\xd5\\x51\\x54\\x1c\\x18\\x6f\\x67\\x99\\x2f\\x5b\\x51\\x75\\x88\\x09\\xf4\\xe5\\x96\\xc3\\x76\\x6a\\xd0\\x1d\\x68\\x2a\\xa2\\x0a\\xf8\\x42\\xf1\\xe1\\xc3\\x80\\xef\\x1c\\xf7\\xe1\\xe5\\xd9\\xc3\\xde\\x87\\x6e\\x6f\\x82\\x9c\\x96\\x03\\xa1\\xe7\\x38\\xb0\\xb0\\x77\\xab\\x57\\xb6\\x4d\\x42\\x1b\\x60\\xb5\\xcd\\xdb\\x9c\\xeb\\x9c\\xef\\x3a\\x4b\\xd0\\xf2\\xa3\\x74\\x9b\\x50\\x1a\\x51\\x8d\\x9c\\xad\\xd8\\x10\\xe8\\x0c\\xc4\\x8d\\xd0\\x19\\xd3\\x16\\x5d\\x77\\x02\\xf5\\xc6\\x0d\\x26\\xee\\x27\\x64\\xbc\\x85\\x5c\\x82\\xce\\xcb\\x2c\\x73\\x9d\\x45\\xed\\x2b\\x5d\\xe8\\xf4\\x4b\\x26\\x77\\xd1\\xf5\\xb7\\x29\\x26\\xee\\x14\\x7a\\xca\\xe9\\xa9\\xf4\\x5f\\x75\\xe7\\xd2\\x4c\\x96\\x31\\x31\\xa1\\x65\\xfb\\xca\\xda\\xe9\\x68\\xa0\\xfc\\xc9\\x85\\x34\\xa1\\x5b\\xf1\\x99\\x01\\xaa\\x0f\\xe9\\x41\\xd3\\x1c\\x99\\x76\\x5c\\x65\\x3d\\x2f\\xcb\\x9f\\x8c\\xcb\\xb6\\xc9\\x4c\\xb7\\xab\\x4c\\x17\\x65\\xa6\\x3b\\x5b\\x95\\x4c\\x55\\xde\\x9f\\x54\\x25\\xd0\\xb3\\x5a\\x66\\xbc\\x51\\xf8\\x79\\xeb\\xbd\\xda\\xa8\\x51\\xdf\\x20\\x2c\\x0e\\x56\\xb6\\xe5\\xc7\\xd8\\x30\\x76\\x0f\\x4d\\x48\\x4a\\xad\\xa6\\x4c\\x9d\\x5d\\x91\\x14\\xe0\\x94\\x01\\x8a\\x7e\\x61\\xb2\\x11\\x8e\\x57\\x5e\\x60\\xae\\x3a\\x28\\xfd\\x0f\\x36\\x1b\\xe9\\x21\\xe9\\x60\\x4c\\x0d\\x49\\x77\\x7a\\x3d\\x07\\x22\\xa0\\xc1\\x7d\\x82\\xcd\\xd0\\xfe\\x9f\\x03\\x91\\x4e\\xdf\\x7f\\xca\\x8c\\x41\\x58\\xe1\\xdf\\x0f\\x47\\xb7\\x81\\x3a\\xcd\\x19\\x9e\\x1e\\x3e\\x1e\\xaf\\x8f\\x0a\\x28\\x10\\xf2\\x87\\xef\\x07\\x0e\\x84\\x48\\xb7\\x6a\\x8e\\x4a\\x8d\\xd4\\x34\\xc7\\x73\\x50\\x05\\x4e\\x36\\x5a\\xa3\\x9f\\x62\\x70\\x42\\xfb\\xed\\x39\\x6d\\xcc\\x5c\\xa1\\xe1\\x9f\\xe6\\xa0\\x5f\\xb5\\xd8\\xe9\\x55\\xad\\x3c\\x65\\x80\\x21\\xa7\\xe7\\x60\\x3b\\xe7\\xf0\\x01\\xf3\\x1e\\xca\\x1e\\x41\\xdf\\xc0\\x65\\xf6\\xe1\\xce\\x0a\\xd4\\xd0\\x11\\xca\\x9b\\xc9\\x34\\xb5\\xbe\\x7c\\xe7\\x20\\x09\\xfc\\x11\\x83\\xd6\\xc5\\xf8\\x9f\\x92\\x68\\x01\\xc4\\x42\\xf3\\xeb\\x73\\xa8\\x55\\xa0\\x9a\\x6c\\x57\\xf9\\x99\\xac\\x34\\x8f\\x44\\x0c\\xb7\\xdb\\xc4\\x9d\\xf8\\x6c\\x78\\x26\\x86\\x5d\\x2c\\x19\\x4f\\xa5\\x7d\\xf2\\xd9\\x90\\xaa\\x95\\xa3\\x53\\x88\\x4c\\x91\\x0b\\xc8\\x63\\xda\\x4c\\x45\\xdc\\xb9\\x6f\\x98\\xa1\\x3c\\x16\\xc9\\xe0\\xb9\\x02\\x34\\xd7\\x92\\x82\\x1c\\x49\\x51\\x5c\\x11\\x35\\x39\\x88\\x41\\x35\\x34\\xb0\\xdc\\x80\\xea\\x74\\xda\\x7a\\xc0\\x03\\xec\\xf4\\x9c\\x6e\\x50\\x5d\\xc2\\xce\\x31\\x75\\x69\\xdd\\x07\\xbf\\xe7\\x40\\xff\\x70\\xd0\\xc6\\x32\\x92\\x81\\xfc\\xac\\xe8\\x16\\xe8\\x23\\xde\\x1d\\xc0\\x6e\\x00\\x0b\\x8e\\x03\\xe9\\x90\\xea\\xba\\xfa\\xa8\\xbb\\xfc\\x2b\\xa0\\x3b\\x65\\xd3\\x24\\x88\\x8a\\x60\\xba\\x3d\\x07\\x6e\\x36\\x5b\\x89\\x3d\\xd7\\x81\\x70\\x1d\\xe0\\x3e\\xc6\\x7c\\xbb\\x11\\xa8\\x2f\\xe8\\x26\\x37\\x44\\xba\\x67\\x11\\xe9\\x50\\xac\\x16\\x75\\x02\\x9e\\xd7\\x25\\x87\\x29\\xe6\\xa3\\x49\\xb7\\x3b\\xf6\\x65\\x8b\\xa6\\xc3\\xa0\\xd3\\x99\\x48\\xd8\\xda\\xe4\\x19\\xea\\x19\\x77\\xa0\\xa7\\x1a\\x3f\\x1d\\x02\\x30\\xb8\\x17\\x96\\xc7\\xed\\x07\\xd2\\xd1\\x58\\xe7\\x3e\\x70\\x9c\\xb6\\x3c\\x4c\\x02\\x65\\xc9\\x64\\x29\\xf8\\xea\\x5e\\x88\\xd0\\x03\\xfa\\x65\\x2a\\xd8\\x6f\\xbb\\x0f\\x8b\\x00\\x87\\x1a\\x8d\\x7a\\x8e\\xa6\\xf7\\x01\\xe6\\x85\\x98\\x6c\\x8a\\x03\\x8f\\x61\\x51\\x01\\x26\\x35\\x8c\\xf5\\xd9\\xf0\\x42\\xcc\\xb3\\x21\\x94\\x1a\\x45\\xa6\\xca\\x86\\xaf\\x29\\x66\\xb5\\xfd\\x6e\\xf9\\xe4\\xb3\\x6a\\x63\\x6d\\x82\\xd9\\x50\\x50\\x2b\\x24\\x77\\x02\\x7c\\xb5\\xd7\\xa1\\x77\\x3d\\xaa\\x05\\xed\\x7d\\xdf\\x43\\xa2\\xe1\\x95\\xe1\\xe3\\xbc\\xe2\\x91\\x14\\xae\\x29\\x7e\\x29\\x25\\x67\\xa1\\x00\\x45\\x21\\x88\\xb2\\x97\\xe4\\xa5\\xdc\\x08\\xe9\\xdf\\xa7\\x75\\x41\\xfb\\x17\\x12\\xb4\\x96\\x49\\x9a\\x1b\\x51\\x5b\\x9a\\x6e\\x88\\x3b\\x37\\xa7\\x86\\x89\\x66\\x3f\\x55\\x4d\\x17\\x65\\x6b\\x6b\\x5b\\x19\\xef\\x87\\x40\\x6e\\x80\\xa0\\xc7\\xb2\\xfb\\x88\\x08\\x22\\xea\\x09\\x32\\x07\\x28\\x96\\xf4\\xeb\\x89\\x60\\x1e\\xa4\\xa4\\xb6\\x54\\x65\\xb1\\xac\\x4d\\x9f\\x59\\xfd\\xf8\\xe9\\x90\\x56\\x7c\\x15\\x90\\x1a\\x39\\x93\\xe4\\xeb\\xe8\\xf6\\xd1\\x6d\\x31\\x7b\\x0d\\xcc\\x57\\x68\\x95\\xd6\\xf9\\xd2\\x53\\x56\\x37\\x05\\x34\\xc5\\xd1\\x00\\x04\\x97\\xe4\\x54\\xb0\\x32\\x53\\x1d\\x45\\x4f\\x19\\x44\\x4c\\x1f\\xb9\\xb8\\x22\\x4d\\x25\\xd0\\xab\\x8f\\xda\\x53\\x66\\x64\\x17\\xb1\\xcc\\x1f\\x24\\x01\\x97\\x4b\\x5d\\xa3\\x83\\xf3\\x83\\xd3\\x05\\xe4\\xfe\\xfd\\x93\\xce\\xe0\\xb6\\x65\\x2f\\x1f\\xdc\\x81\\x5d\\x40\\x76\\xd2\\xa4\\x1f\\xc1\\x2f\\x0c\\xf7\\x46\\xdf\\x7d\\xe8\\x7d\\x18\\xfe\\xbf\\x71\\x6f\\x82\\x1e\\xaa\\xd7\\xa1\\x27\\x5e\\x1e\\xe8\\x17\\xf1\\xfc\\x44\\x3f\\xcb\\x5c\\x8f\\x18\\xee\\x7d\\xd7\\x9b\\x54\\xa8\\xf7\\xbe\\xa6\\xbe\\xed\\x38\\x28\\x32\\x4c\\xea\\xfb\\xf0\\xed\\x36\\xb5\\x26\\xec\\x77\\xe5\\xb5\\xa2\\x1c\\x9c\\xd5\\x9e\\xd3\\xbf\\x4c\\x3a\\xa2\\xf4\\xc5\\x44\\x77\\x3a\\xb9\\xc2\\x85\\x4a\\x41\\xd7\\xbb\\xc7\\x41\\x00\\x1a\\x26\\x8d\\x36\\x49\\x4c\\xd2\\x8d\\x53\\x28\\x50\\xef\\x6b\\xfa\\xd3\\xae\\x87\\xf7\\xef\\x5a\\xc5\\xc9\\x2d\\x07\\x53\\x82\\xff\\x30\\x5e\\x15\\x35\\x06\\x2c\\xc5\\x67\\x02\\x7d\\xb6\\xd9\\xe8\\x04\\xe5\\x0e\\xce\\xf0\\x68\\x0c\\x7d\\x6d\\xbb\\x2a\\x7d\\xc3\\xbb\\x78\\x60\\x2b\\x4e\\xd6\\xca\\x7d\\xc6\\x4c\\xdd\\x04\\xfa\\x14\\xff\\xa1\\x3c\\xca\\x85\\xf2\\x23\\x24\\x27\\xaa\\xd4\\x1f\\xed\\xc7\\x42\\x5c\\x7a\\x28\\xf5\\x1c\\x51\\x37\\x85\\xe6\\xc4\\x99\\x12\\xbe\\x94\\xbe\\x24\\x0b\\x54\\x5b\\xae\\x42\\xc5\\x21\\x2e\\x3b\\x3c\\x44\\x95\\x22\\x73\\xff\\xe8\\x96\\x1c\\x59\\xa9\\xa6\\xd9\\x04\\xe0\\xd7\\xc6\\xa6\\x94\\xfa\\x8d\\x69\\x51\\x71\\xb0\\x4f\\x15\\xa9\\x8d\\x1f\\x31\\x99\\x2a\\x6b\\x94\\xdc\\x93\\x7f\\x52\\xb3\\xd9\\x71\\x31\\x99\\x26\\x48\\x06\\x0a\\xb4\\x02\\x52\\xff\\xb3\\xad\\x8a\\xfe\\xbe\\xa3\\xea\\xea\\x0a\\x1f\\x02\\x68\\x04\\x29\\xa5\\x82\\x8b\\xc9\\x30\\x31\\x61\\x6c\\x6d\\xc8\\x94\\xe4\\x32\\x3e\\x0c\\x6a\\x38\\xd3\\x6f\\x26\\x50\\xa8\\xde\\x55\\xfc\\x98\\xba\\xd6\\x4d\\xaa\\xa6\\x28\\x19\\x60\\x34\\x6e\\x0e\\x61\\x40\\xe0\\xaf\\x46\\x32\\x86\\x52\\xda\\xfd\\x95\\x00\\x8a\\x2c\\x3c\\x2a\\x51\\x0c\\x6a\\x4b\\xc0\\xda\\xee\\xd3\\x97\\x14\\x14\\x0d\\x8b\\xc8\\x43\\xd8\\x15\\x63\\x38\\x68\\xd2\\x3a\\xbf\\x86\\xde\\xb5\\x46\\x2a\\xbc\\x3d\\xac\\x63\\xbb\\x51\\xb0\\xfd\\x1a\\xca\\xcb\\xad\\xff\\x3d\\x78\\xde\\xa4\\x31\\xdb\\x2e\\xe3\\x42\\xe9\\x50\\x75\\x3c\\xb4\\x7c\\x32\\xfa\\x65\\x27\\x87\\x46\\x31\\x10\\x9c\\x58\\xa9\\xd3\\x4d\\x72\\xb4\\x11\\x77\\xca\\x60\\x11\\xea\\x4d\\xc6\\x80\\xd1\\x8e\\x38\\x9a\\x4c\\x3a\\xdb\\x16\\x92\\x1a\\xba\\x88\\xf1\\xa5\\x0d\\x0a\\x20\\x55\\xb1\\x7e\\xbe\\x18\\x22\\xc5\\x0f\\x4c\\x47\\x02\\xb8\\x75\\xd4\\x3e\\x68\\x0a\\x17\\xe1\\x4b\\x01\\x20\\x18\\x85\\xe3\\x4e\\x07\\x4c\\xba\\xf8\\xcb\\x31\\x1f\\x44\\x3e\\x28\\x1d\\x33\\x95\\x55\\xbc\\x3a\\x37\\x63\\xc8\\xac\\x96\\x36\\x3a\\x4e\\xcd\\x18\\x73\\xc9\\xea\\x32\\xea\\x7b\\x9f\\xba\\xca\\x83\\x59\\x9f\\x37\\x29\\xa9\\xae\\xf4\\xb3\\x41\\x54\\xe9\\x6c\\x4d\\x07\\x4b\\x14\\x41\\x58\\x97\\xca\\x9a\\x64\\xf3\\x32\\xd4\\x05\\xa6\\xfb\\x0e\\x12\\x56\\xa5\\x1f\\x6b\\xea\\x42\\xa5\\x97\\x87\\x28\\x26\\xe8\\x0c\\xb2\\x88\\xdb\\x3e\\x8a\\xa1\\x56\\x6a\\x50\\xaf\\xc2\\x0f\\x94\\x94\\xfa\\x4c\\x23\\x6d\\x00\\x91\\x79\\xe4\\x10\\xf5\\x4b\\xeb\\x87\\x41\\x65\\x5d\\x8b\\x85\\xb8\\x7f\\x94\\xb9\\x7f\\x23\\xa0\\xd4\\x4a\\x69\\x17\\x97\\xc7\\x9a\\x61\\x21\\x5d\\x58\\x95\\x47\\xb3\\x34\\xb6\\xae\\xca\\x28\\x1b\\xd8\\x71\\xd0\\x5f\\xe2\\xe7\\x37\\x86\\xfe\\x46\\xcf\\x35\\xf8\\x17\\xd6\\xc6\\xd3\\x4b\\x06\\xe0\\xfa\\x2f\\x2c\\x72\\xfa\\xcf\\x19\\xfe\\x1b\\xff\\xa6\\xd7\\xdc\\x99\\x8a\\xe0\\x12\\x73\\x69\\xf8\\x15\\xa2\\x31\\xf8\\xa5\\x9e\\x84\\x5e\\x31\\x88\\xaa\\xb4\\x8c\\xe7\\xaf\\x16\\xcf\\x13\\x12\\x3c\\x20\\x71\\x4c\\x09\\x9b\\x39\\xe8\\xa9\\xfb\\x46\\x3b\\xd7\\x92\\xca\\x70\\xdf\\xbc\\x73\\xa9\\xf7\\x50\\xa1\\x4f\\x70\\x65\\xb2\\xd7\\x76\\x5a\\x15\\xbb\\x65\\xb3\\x21\\x23\\xb3\\xe0\\x0e\\x07\\x63\\xb9\\x05\\x6a\\xc5\\x4e\\xc8\\x52\\x26\\x4b\\x6b\\x15\\x87\\x18\\x72\\x27\\x74\\x97\\x17\\x0c\\x8b\\xd9\\x57\\x4a\\x7b\\xef\\x9f\\xf3\\xf3\\xf3\\x0f\\xee\\x24\\xcb\\x49\\x1e\\xb1\\x0f\\x2e\\x5b\\xf4\\xe0\\xd0\\xd1\\xaf\\x2e\\x5b\\x38\\x5e\\xf5\\x92\\xcc\\x1d\\xff\\x35\\xab\\x3b\\x7c\\xbd\\xd6\\x12\\x8e\\x92\\xee\\xea\\xa2\\x71\\x55\\xa9\\x20\\x45\\xf2\\xe4\\xa0\\x1c\\x09\\x79\\xbc\\x79\\x8b\\xde\\x2a\\x8f\\xd6\\xff\\x49\\x67\\x17\\xb3\\x63\\x02\\xa0\\xf2\\x89\\xa1\\x62\\x42\\x0d\\x14\\xb2\\xca\\x13\\x35\\x07\\xfb\\x08\\x77\\x9e\\x5e\\x4a\\xfd\\x4a\\xca\\xea\\x66\\x17\\x53\\xc6\\x57\\x92\\xa7\\xc1\\xa5\\xc1\\x22\\x09\\x56\\x31\\xcf\\xe4\\x92\\x27\\xb8\\xef\\x93\\xca\\xf2\\x46\\x2a\\x0a\\xc2\\x46\\x64\\xec\\xbf\\x62\\x20\\x90\\x1e\\x26\\x28\\x70\\x75\\xe4\\x5e\\x14\\xc0\\xa2\\xa8\\x5c\\x4e\\x6b\\x92\\xf5\\xa9\\x6e\\x5e\\x2b\\x24\\x51\\xcc\\x83\\xd6\\x79\\x94\\x4f\\xbd\\x96\\xd3\\xe5\\xd0\\xb7\\x7d\\x90\\xdf\\x58\\x4b\\x9c\\x20\\x86\\x84\\xd6\\x68\\x26\\x44\\x1b\\xdd\\x0f\\x7b\\x50\\xba\\x15\\x89\\xb9\\x2a\\x25\\xa4\\xea\\xa3\\xd4\\x04\\x7c\\x82\\xa9\\x1f\\x24\\x52\\xfe\\xc7\\x18\\xcb\\xbd\\x05\\x41\\xda\\xb7\\x02\\x67\\x85\\xd1\\x22\\xca\\x79\\x2b\\x4e\\x92\\x65\\x2b\\x5a\\xb4\\x74\\x37\\x4c\\x30\\x2a\\xbd\\x73\\x0b\\x58\\x55\\x5e\\x56\\xcb\\xa0\\x3e\\xeb\\xce\\xa0\\xcf\\x30\\x08\\x86\\x66\\x13\\xe2\\x50\\x85\\xc1\\x31\\xbb\\xf1\\x26\\xa0\\x71\\xb9\\xe7\\x20\\xdd\\x6a\\x3d\\x86\\xa8\\xdc\\x6c\\xb3\\x8e\\x27\\x58\\x9d\\x16\\x55\\x3d\\x73\\xa7\\x64\\xf4\\x82\\xe9\\xcd\\x94\\x14\\x31\\x2c\\x87\\xc5\\x10\\xa2\\x6a\\x23\\x14\\x50\\x54\\x56\\xc2\\x5c\\x4a\\x0a\\x8d\\x18\\x5b\\x56\\x99\\x00\\x57\\xcb\\x54\\x5d\\x93\\xaf\\x21\\xbb\\x3a\\x4c\\xc4\\xdb\\x25\\x67\\x51\\x18\\xb1\\x72\\x11\\xef\\xcb\\xbf\\x5c\\xd1\\x38\\x62\\xcf\\xf7\\xe5\\x3a\\x6b\\x04\\x27\\x39\\x57\\xb0\\xab\\x68\\x99\\x96\\xb7\\x9c\\x2e\\x81\\x82\\xac\\xd8\\x92\\x14\\xc7\\x01\\x60\\x25\\x62\\x71\\xe8\\x97\\x41\\x96\\xb8\\x92\\xc1\\x85\\xf2\\x2a\\x3a\\x6b\\xec\\x95\\x5f\\x6e\\xf2\\xdb\\x1d\\xb2\\x73\\x95\\xf6\\xef\\x12\\x2b\\xa1\\xcb\\x37\\xee\\x4e\\x4e\\xe0\\x3a\\x54\\x2e\\x90\\xc6\\xf1\\xb2\\x28\\xdd\\x90\\x6a\\x9e\\x8a\\xef\\xe4\\x64\\x37\\xac\\x4f\\xa9\\x52\\x8d\\xc8\\x18\\xfa\\xf5\\xb0\\x4d\\x44\\x39\\x6a\\x58\\xd1\\xf5\\x00\\xd1\\x68\\xf2\\x97\\x25\\xad\\x35\\x71\\x1c\\x75\\xe4\\xb5\\xce\\x6b\\xa8\\x3a\\x3b\\xcf\\x48\\x0e\\x98\\x36\\x4a\\xf4\\x46\\x1f\\x32\\x34\\xee\\x7e\\xc8\\x6e\\xf5\\xec\\xe8\\x68\\x16\\xc3\\x7b\\x6f\\xf4\\x35\\x19\\xf4\\xa2\\xda\\xfa\\xb0\\x34\\xc0\\x43\\xa1\\xa2\\x7c\\x74\\xe0\\x56\\x75\\x0d\\x14\\xcd\\x87\\x04\\x53\\xa4\\x50\\xfd\\x0f\\x21\\xd5\\x8b\\x25\\xaa\\x4c\\xa7\\xed\\x01\\xf4\\x95\\x7f\\xbe\\x5e\\xf4\\x1f\\x47\\xff\\x7c\\x1c\\x77\\xbf\\xef\\xc1\\x61\\x5d\\xdf\\x34\\xe9\\x62\\xb5\\x23\\x82\\x65\\xfb\\xa0\\x47\\xb0\\xc3\\x17\\x8e\\xb5\\xf3\\x63\\x29\\x67\\xb5\\x1e\\x48\\x1a\\xf8\\x67\\xa7\\xf3\\x67\\x5b\\xd5\\x6c\\x02\\x86\\x9d\\x93\\x74\\x01\\x9c\\xd6\\x69\\x9e\\xf3\\xf9\\x32\\x57\\x11\\x8e\\xa4\\x17\\x50\\x49\\x1b\\x7e\\x94\\xfe\\x1d\\x3f\\xb6\\x92\\xb0\\xf5\\x44\\xe2\\x4e\\xeb\\x81\\xc4\\x1d\\x15\\xd5\\x2e\\x9f\\xf2\\xd6\\x32\\xe5\\x67\\x51\\xb2\\xca\\xe2\\xcb\\x96\\xda\\xdf\\x14\\x65\\xc0\\x9f\\xa2\\xd0\\x79\\x14\\xc7\\x2d\\xca\\x5b\\xab\\x8c\\xab\\x43\\x27\\x9c\\x04\\xae\\x54\\x90\\xf1\\x9f\\x65\\xab\\xff\\x54\\x6d\\xb4\\x64\\x95\\xdd\\xa6\\xff\\xd5\\xe9\\xfc\\x75\\xe5\\xa6\\xd7\\xda\\xa9\\x1c\\xba\\xc8\\x62\\xb2\\x22\\x13\\x6e\\x7a\\xf3\\xb5\\xc6\\xff\\xf5\\x95\\xc6\\xff\\x05\\x7d\\x31\\xf0\\x7a\\x1a\\x09\\x76\\xaa\\x39\\xf8\\x6b\\xbb\\x37\\x7f\\x5a\\xc4\\x6e\\x5d\\x20\\x56\\x85\\x77\\x22\\x50\\x88\\xa6\\x6a\\x1f\\xa1\\x44\\x41\\xcb\\xc5\\xd7\\x08\\x5d\\xf8\\x4f\\xc1\\x0d\\x7d\\xea\\x06\\xc9\\x9c\\x44\\x0b\\xfc\\x82\\xf9\\xea\\x6c\\x81\\x58\\xa1\\x92\\x55\\x96\\x6f\\x82\\x11\\xfc\\x5e\\xb2\\x79\\x86\\xa9\\x6b\\xba\\xee\\x33\\xfc\\x07\\x03\\xef\\x99\\xb4\\xe5\\x56\\xc9\\x58\\xc9\\xd9\\xbf\\xa9\\x8d\\x58\\xea\\x2a\\x2f\\xe5\\xf7\\x69\\xfc\\x96\\xe7\\x62\\x50\\xb3\\xd2\\xbb\\xe8\\xfd\\x9b\\xe7\\x6f\\x39\\x49\\xd9\\xf4\\x35\\x49\\xc9\\x3c\\x93\\xdc\\x95\\x60\\x20\\xf9\\x7d\\xfd\\x13\\xc8\\x93\\x65\\x75\\x86\\x3f\\x93\\x5f\\x20\\xd4\\xbc\\x5f\\x4e\\xca\\xa1\\xc6\\x2e\\x41\\x94\\x48\\x15\\xd3\\xce\\x4c\\x6d\\xb4\\x08\\x13\\xe0\\x3c\\x56\\x8c\\x33\\x4f\\x5a\\x13\\x9e\\xb7\\xea\\x05\\xd5\\x29\\x87\\x3c\\x59\\x8a\\xba\\x1d\\xc1\\x87\\x7f\\x63\\x58\\xb2\\x95\\x82\\xba\\x4b\\xc2\\x66\\x64\\xc2\\x33\\xfc\\x4e\\x0c\\x8d\\x79\\x2b\\x67\\x48\\x08\\x73\\x3b\\x6c\\x43\\x7f\\x7b\\x2e\\x46\\x5a\\x3a\\xef\\x44\\x8d\\x2e\\x1d\\x4f\\x15\\x1b\\xd2\\x5b\\x69\\x24\\xcb\\xa2\\xc9\\x02\\xac\\x0b\\x44\\xd0\\x3a\\x23\\x21\\x97\\x31\\x82\\xda\\x7d\\xe9\\x8e\\xf2\\xcb\\x36\\xb1\\x15\\x19\\x24\\x27\\x41\\x02\\x3a\\xf4\\x0f\\x14\\xb0\\x5a\\x35\\x15\\xa5\\x19\\x8d\\xb5\\x4a\\xb3\\xb3\\x71\\xde\\xed\\x32\\x8d\\x38\\x56\\x30\\x53\\x5f\\x64\\x76\\xce\\xa2\\x6c\\x45\\xe2\\xe8\\x33\\x31\\xce\\xce\\x22\\x5f\\xa7\\xc3\\xba\\x5d\\x6d\\x92\\x2e\\xfd\\x0b\\x9a\\x65\\x26\\x91\\x7d\\xb3\\xa9\\x62\\x9e\\xda\\xe9\\x30\\x28\\x75\\x07\\xf1\\x86\\x0c\\x50\\xb9\\x57\\xfb\\x99\\xa8\\x54\\x79\\x3a\\x52\\x3e\\x95\\xeb\\x81\\xc9\\x80\\x9b\\x0d\\xe3\\x11\\xeb\\xb1\\x10\\x7f\\xa1\\xff\\xd4\\x7d\\xb3\\x7d\\x0a\\xa3\\xfd\\x77\\x9d\\x87\\xbe\\x58\\x65\\x79\\x4b\\x60\\x7a\\x6b\\x17\\x50\\x8b\\xf2\\x30\\x49\\xf9\\xd6\\x97\\x26\\x7e\\x56\\x9a\\x17\\xff\\xd6\\x3e\\xfb\\xd0\\xfb\\xbb\\x69\\xb6\\x9a\\xe5\\x76\\x5f\\x86\\xb0\\xf9\\x9b\\xe1\\xc7\\xc0\\x51\\xd1\\x32\\x7b\\xbd\\x39\\x59\\x66\\xae\\x2a\\x4d\\x96\\xd2\\xcd\\x6d\\x2e\\xd3\\x7a\\x64\\x19\\xf5\\x3e\\x65\\xc3\\x4f\\x19\\x59\\x46\\x6f\\x78\\x10\\xa5\\x9c\\xe5\\x38\\x4f\\x57\\xdc\\x81\\xe8\\xfb\\x1d\\x10\\x87\\x64\\x19\\x1d\\x66\\x59\\xec\\x9a\\x86\\x68\\x30\\x0d\\xe5\\x3b\\x61\\x14\\x73\\x5c\\x56\\xe9\\x40\\x4b\\x69\\x24\\x41\\xe9\\x03\\x57\\xa3\\x94\\xcf\\xb5\\x6f\\xe7\\x0b\\xb2\\xcc\\x5a\\xa7\\xaf\\x9f\\x49\\x89\\x54\\xd2\\x40\\x09\\xbf\\xa5\\x7d\\xfb\\xa2\\xac\\x15\\xf0\\x65\\xca\\x19\\xc9\\xb9\\x20\\x77\\x7e\\xe5\\x49\\xc7\\xdc\\x19\\xbf\\xdc\\x6c\\x98\\xcb\\xe2\\xa8\\x72\\xf2\\x65\\x6e\\x1c\\xd1\\x94\\xa4\\x11\\xcf\\x90\\xb5\\xb9\\x62\\x79\\x0c\\xcc\\x04\\xdd\\x8b\\x71\\xdf\\x8f\\xef\\x99\\xd3\\x02\\x7e\\x6c\\xa4\\xeb\\x25\\x9e\\x8e\\xe2\\xb1\\x3f\\x1b\\x2d\\x47\\xfd\\xf1\\x18\\x2f\\x47\\x83\\xb1\\x11\\x24\\x66\\x05\\x60\\xae\\x3c\\x83\\xf4\\x71\\x29\\x09\\xcb\\xb0\\xfe\\x6a\\xed\\x03\\xbb\\x73\\xb2\\x04\\x76\\xdd\\x1a\\xc4\\xd4\\xe4\\xc1\\x0e\\x2c\\xa0\\x37\\x1a\\x43\\x14\\xe2\\x9d\\xd5\\xbb\\x9e\\xf1\\x4b\\x8f\\xa0\\x8c\\x78\\x41\\x21\\x74\\xca\\x09\\x76\\x8e\\xe4\\xea\\x19\\x7e\\xcf\\xbc\\xbf\\x99\\xff\\x77\\xb3\\x08\\xa4\\x9d\\x15\\x24\\x09\\x56\\xf1\\x3f\\x4b\\x2a\\x6c\\x89\\xac\\x13\\xb4\\x2e\\x50\\xa8\\x05\\xd5\\x99\\xfe\\x3b\\x35\\xe7\\xc1\\x68\\x60\\xa3\\xc1\\xf9\\xf9\\xb9\\x6b\\x69\\x59\\xbd\\x68\\xb1\\x5c\\xe5\\xf2\\x2e\\xbb\\xde\\xa7\\xac\\x17\\xe5\\xc4\\x4a\\xf9\\x78\\xec\\x7e\\xca\\x6a\\x33\\xcf\\xca\\x99\\xff\\x2c\\x94\\x62\\xd1\\x22\\x43\\xfc\\x86\\xa0\\x2e\\x63\\x55\\x5f\\xe0\\xb0\\x7a\\xf6\\x46\\xd5\\xf3\\x18\\xba\\xd1\\x82\\xc5\\xab\\x80\\x67\\xc0\\xa9\\x6a\\x75\\xe0\\xb0\\xce\\x81\\x7f\\x34\\x78\\xe5\\x70\\xad\\xbe\\x3a\\x57\\xc2\\xac\\x0f\\x8b\\xd7\\x31\\x27\\x99\\xf2\\x39\\x6e\\xfd\\xd8\\x05\\x34\\xe8\\x3a\\x2d\\x85\\xe3\\xf1\\xa5\\xe4\\xb3\\x7b\\x86\\xbd\\xb4\\x2a\\x7c\\x71\\xd8\\x69\\x20\\xc6\\x7d\\x6d\\x34\\x04\\xae\\xff\\x06\\xb0\\x80\\xd0\\xab\\xc7\\x4b\\x6d\\xea\\x82\\x3a\\xfa\\x96\\x4f\\xc9\\xa2\\x65\\xf7\\x5e\\x74\\x62\\xb5\\xc8\\x56\\xcb\\x65\\x92\\x8a\\x5e\\xfc\\xb8\\x0d\\xcb\\x36\\x05\\x08\\x99\\xc9\\x40\\x94\\xa7\\x16\\xa2\\xc5\\x59\\x32\\xd3\\xba\\x60\\xb2\\xca\\x5b\\x99\\x94\\xbb\\x2f\\x45\\xd5\\x66\\xd8\\x1d\\x85\\x16\\x41\\x0d\\x2d\\xc8\\x27\\x72\\xb1\\x4d\\x60\\x44\\x5a\\x2f\\x8e\\x68\\xd6\\xfb\\x61\\xad\\xb4\\xd8\\xa2\\xf7\\x83\\x51\\x8e\\xc4\\xa3\\x20\\x11\\x45\\x0d\\x3f\\x78\\x60\\xb9\\xf3\\x6a\\x6d\\x91\\x48\\x26\\x41\\xae\\xa9\\x29\\x4a\\xa1\\xca\\xa4\\x49\\x6d\\x06\\x30\\x05\\x46\\x8a\\x43\\xb6\\xc2\\xd8\\x20\\x9a\\x86\\x41\\x3d\\x50\\x81\\x98\\xb5\\xdf\\xdd\\xef\\x85\\x92\\x2d\\x8f\\x23\\xac\\x29\\xe6\\x42\\xd5\\x0b\\x5c\\x7d\\x8d\\x03\\x94\\x71\\x68\\xcc\\x75\\x39\\x23\\x3a\\x6e\\xd2\\xb0\\xde\\x2f\\x66\\x8b\\xe4\\xbc\\x6c\\x2a\\x12\\xca\\x6c\\xd7\\x41\\x62\\x12\\xa4\\xd0\\xe7\\xea\\x5d\\x78\\x8e\\xf5\\x78\\x79\\x04\\x19\\x8d\\x4c\\x86\\xd1\\x46\\x32\\x62\\x51\\xe0\\x56\\x57\\x4b\\x14\\x3e\\xc5\\xaf\\x09\\xd0\\x3e\\xb9\\xc0\\x78\\x90\\x06\\x01\\xfa\\xcd\\xe3\\x05\\x84\\xb5\\xdd\\xbf\\x46\\x62\\xab\\xed\\x0b\\xff\\x61\\x45\\x38\\x5d\\x40\\xac\\x05\\xa1\\x04\\x1e\\xd9\\x25\\xb1\\x36\\xf6\\x91\\xa4\\xd0\\x58\\x28\\xbf\\xb8\\x36\\x02\\xc1\\x91\\xd5\\x7a\\x98\\x18\\x0d\\x5a\\x10\\x24\\xb9\\xe5\\xf7\\xa5\\xa0\\x59\\x3a\\x02\\xf6\\x0b\\xd9\\xab\\x96\\xf3\\x63\\x97\\x74\\x7f\\x94\\x6b\\x62\\x91\\xe4\\x2d\\x7b\\x55\\xf8\\x5b\\x9e\\xe4\\xff\\xb3\\x1d\\xb9\\xeb\\xb6\\xdf\\xa6\\xc3\\x59\\x04\\x12\\x50\\x6d\\x96\\x37\\xea\\x8e\\xda\\xaa\\x53\\x85\\x0a\\x39\\xd3\\x61\\x21\\x9b\\xdc\\x49\\xb7\\x76\\x3d\\xdf\\x5d\\x2e\\xb9\\xc0\\x0b\\xa3\\xdb\\x44\\x59\\xcb\\xe9\\x9a\\xac\\x0a\\x53\\x28\\xb0\\x82\\x87\\xd4\\x0a\\x1b\\x79\\xa0\\x44\\xac\\x6d\\x0b\\x0f\\x83\\x7e\\x61\\xb9\\xfc\\xbf\\x62\\x37\\x13\\xec\\xb2\\xf3\\x48\\x46\\x5e\\x19\\xf5\\xc7\\x70\\xcd\\x04\\x7e\\x38\\x42\\x2a\\x70\\x3c\\x12\\xe8\\xf8\\xfb\\xea\\x84\\x31\\x91\\xe6\\x31\\x15\\x26\\x51\\x65\\x2b\\xa9\\x99\\xc7\\xbe\\x96\\xb5\\x2e\\x38\\x7a\\x4a\\x28\\xd3\\x65\\x9e\\xd6\\x0b\\xe8\\x50\\xaf\\x5e\\xd8\\x00\\xb3\\x28\\x0e\\xea\\xd6\\x50\\x9e\\xba\\x62\\x29\\x08\\x51\\x7e\\x95\\x72\\x47\\x46\\xd6\\x7a\\xc1\\x86\\xf5\\xc5\\x52\\xd7\\xd7\\xca\\x4b\\x2c\\x5b\\xd9\\x34\\x59\\xc5\\x41\\x2b\\x59\\xc4\\x97\\x42\\x0f\\xd3\\xfa\\x59\\xb2\\x60\\xdc\\x75\\xa0\\xf7\\x92\\x01\\x85\\xd4\\x2b\\x37\\x25\\xf8\\x25\\xd3\\xcf\\x17\\x04\\xbf\\x31\\xcf\\x97\\x42\\x51\\xd6\\xcf\\x9f\\x09\\x7e\\x67\\x9e\\x7f\\x15\\x4a\\x92\\x7e\\x7e\\x46\\xf0\\x1f\\xe6\\xf9\\x94\\xe0\\xd7\\xe6\\xf9\\xdf\\x26\\x3f\\xed\\xe7\\xac\\xf0\\x0b\\x68\\x9d\\x58\\xf3\\xff\\xbf\\x00\\x00\\x00\\xff\\xff\\x02\\x42\\xb6\\x13\\x61\\xfe\\x00\\x00\")\n\nfunc cmdInternalPagesAssetsJsLoaderJsBytes() ([]byte, error) {\n\treturn bindataRead(\n\t\t_cmdInternalPagesAssetsJsLoaderJs,\n\t\t\"cmd/internal/pages/assets/js/loader.js\",\n\t)\n}\n\nfunc cmdInternalPagesAssetsJsLoaderJs() (*asset, error) {\n\tbytes, err := cmdInternalPagesAssetsJsLoaderJsBytes()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tinfo := bindataFileInfo{name: \"cmd/internal/pages/assets/js/loader.js\", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)}\n\ta := &asset{bytes: bytes, info: info, digest: [32]uint8{0x3a, 0xb4, 0xfb, 0x83, 0x63, 0xfe, 0xa4, 0xd4, 0xad, 0x17, 0x76, 0xa7, 0x11, 0x50, 0x35, 0x18, 0xf5, 0x8e, 0xf2, 0x13, 0xb0, 0x3d, 0xc5, 0x45, 0x1b, 0xd7, 0xb7, 0xe5, 0xfe, 0x7d, 0x64, 0x34}}\n\treturn a, nil\n}\n\nvar _cmdInternalPagesAssetsJsPopperMinJs = []byte(\"\\x1f\\x8b\\x08\\x00\\x00\\x00\\x00\\x00\\x00\\xff\\x9c\\x7c\\x6b\\x97\\xdb\\xb6\\xb5\\xe8\\xf7\\xfe\\x0a\\xea\\x9c\\x96\\x00\\x2c\\x88\\x23\\xa5\\x37\\xf7\\xdc\\x4b\\x19\\xd1\\x72\\x9c\\x71\\xe3\\xd4\\xf6\\xb8\\xf6\\xb8\\x4e\\x4a\\x73\\xc5\\x1c\\x11\\x1a\\x21\\xa6\\x08\\x16\\x80\\xe6\\x51\\x49\\xff\\xfd\\x2c\\xbc\\x48\\x50\\xe2\\x8c\\xd3\\x7e\\xf0\\x88\\xc4\\x63\\x63\\xef\\x8d\\xfd\\x06\\xe8\\xb3\\x27\\x7f\\x88\\x9e\\xf3\\xe6\\x5e\\xb0\\xeb\\xb5\\x8a\\xe0\\x73\\x14\\xbd\\xa0\\x25\\x15\\x6c\\xc9\\xa3\\x7f\\xb0\\x1b\\x5e\\xf1\\xe8\\x9b\\xe9\\xec\\x7f\\xfe\\x10\\xfd\\xc0\\xa4\\x12\\xec\\x6a\\xab\\x68\\x19\\x6d\\xeb\\x92\\x8a\\x48\\xad\\x69\\xf4\\xfa\\xe5\\x65\\xf4\\x8a\\x2d\\x69\\x2d\\x69\\x04\\x2b\\xf7\\xa0\\xa8\\xd8\\xc8\\xa8\\x10\\x34\\x2a\\x54\\xb4\\x56\\xaa\\x49\\xcf\\xce\\x78\\x43\\x6b\\xc9\\xb7\\x62\\x49\\x13\\x2e\\xae\\xcf\\xdc\\x50\\x79\\xf6\\xfa\\xe5\\x25\\x4a\\xfe\\x10\\x3d\\x39\\x83\\xab\\x6d\\xbd\\x54\\x8c\\xd7\\x90\\x62\\x85\\x76\\x80\\x5f\\xfd\\x46\\x97\\x0a\\x10\\xa2\\xee\\x1b\\xca\\x57\\x11\\xbd\\x6b\\xb8\\x50\\x32\\x8e\\x81\\x5e\\x7d\\xc5\\x6a\\x5a\\x82\\x91\\xef\\xdc\\xf0\\x72\\x5b\\xd1\\x85\\xfd\\x49\\xdc\\x50\\xa2\\x20\\x4a\\x81\\x07\\xdb\\x41\\xb2\\xb3\\xe3\\xd8\\xfe\\x26\\xc5\\xa6\\x5c\\xd8\\x47\\xa8\\x50\\x4a\\x93\\xb7\\xbc\\x69\\xa8\\xd0\\x93\\x0f\\x08\\xaa\\x35\\x93\\xb8\\xc5\\x0c\\xed\\xc0\\x56\\xd2\\x48\\x33\\x62\\xa9\\xc0\\xdc\\xb7\\x47\\x14\\x52\\xb4\\x13\\x54\\x6d\\x45\\x1d\\xd1\\x38\\x06\\x99\\x45\\x3e\\x7a\\xe1\\x06\\xe4\\x80\\x10\\xb2\\x3b\\x24\\x8a\\xbf\\x57\\x82\\xd5\\xd7\\xc9\\xb2\\xa8\\x2a\\x48\\xd1\\xa1\\x85\\xa0\\x2c\\xd5\\x6c\\x05\\x67\\x23\\x42\\x68\\x52\\xf3\\x92\\x5e\\xde\\x37\\x14\\x59\\xa8\\x59\\x3e\\xbf\\x29\\x44\\xc4\\xc9\\x35\\x55\\xcf\\xf9\\xa6\\xd1\\xbb\\xf0\\x5e\\xdd\\x57\\x14\\x52\\x5c\\x6f\\xab\\x0a\\xcd\\xdd\\xea\\x6a\\xc1\\x33\\x95\\xa7\\xbc\\x83\\xcc\\x3b\\xdc\\xc0\\x8f\\x97\\xaf\\x5f\\x69\\x54\\x2c\\xfc\\x37\\xc5\\x86\\x2e\\x68\\x4a\\x93\\xa6\\x10\\xb4\\x56\\x6f\\x78\\x49\\xf7\\x7b\\x9a\\xac\\xb9\\x54\\xdd\\xf4\\x5a\\x4f\\x67\\x2b\\x38\\xf2\\xa8\\x44\\x25\\x5f\\x6e\\x37\\xb4\\x56\\xc9\\x15\\x2f\\xef\\xe7\\xf2\\x96\\xa9\\xe5\\x1a\\x76\\x10\\xd1\\x6e\\x59\\x48\\x6a\\x97\\x4a\\xcd\\xe3\\xf7\\x17\\x3f\\xfc\\x02\\x52\\xcf\\x9e\\x84\\xdf\\xd6\\x54\\xfc\\xd0\\x03\\x62\\x86\\xfd\\xb7\\x07\\x1c\\x8c\\x35\\xbd\\x07\\x4d\\x3a\\x23\\x0a\\x52\\x84\\x05\\x61\\x09\\xbf\\xa1\\x62\\x55\\xf1\\x5b\\xdc\\x04\\x2f\\x3f\\x63\\x19\\xbc\\xfd\\xe2\\xf9\\x71\\x06\\x8b\\xad\\xe2\\x7b\\xb9\\x14\\xbc\\xaa\\xd0\\x59\\xa2\\xa8\\x54\\x50\\x8c\\xe5\\xb8\\x41\\x0b\\x9a\\xd6\\x50\\x73\\x27\\xd8\\x06\\xa1\\xa9\\xb5\\x9c\\xa6\\x71\\x4c\\x13\\xbe\\x5a\\x49\\xaa\\xde\\x1a\\xfe\\x60\\x46\\x78\\x1c\\xf3\\x96\\x50\\xbf\\x04\\x8b\\x63\\x4b\\xe2\\x88\\x10\\xfd\\x6c\\x28\\xd7\\xcf\\x8b\\x89\\xde\\xcb\\x0c\\x5c\\xfe\\x00\\x30\\xb8\\x7c\\xf6\\xfd\\xab\\x73\\x90\\x27\\xac\\x2e\\xe9\\xdd\\xc5\\x0a\\x76\\x70\\x50\\x1c\\x03\\xa9\\x0a\\xc5\\x96\\x7a\\x6b\\x14\\xe4\\x18\\x34\\x5c\\x32\\x23\\xb3\\x68\\x21\\x20\\x47\\x29\\x4f\\xe9\\xe2\\x98\\x71\\x9e\\x5b\\xe7\\x15\\xd5\\x3f\\x69\\xf9\\x40\\x47\\x47\\x5c\\xe3\\x89\\x53\\x81\\x00\\x38\\x2a\\x5a\\x0a\\x54\\x1c\\xc3\\x56\\x4e\\xd4\\x7e\\x2f\\x20\\x4d\\x56\\x4c\\x48\\x0f\\xee\\xf9\\x9a\\x55\\x25\\xd2\\x32\\x14\\xb0\\x4d\\x06\\xf2\\xaf\\xc5\\xd1\\x88\\x58\\x27\\x55\\x0b\\x9a\\x4a\\x18\\x36\\x04\\x53\\xcb\\x56\\xf0\\x47\\x74\\xbf\\x1f\\x75\\x92\\xbf\\xdf\\x8f\\x94\\xfe\\x77\\xac\\x0a\\xd1\\x43\\x84\\x3a\\x0d\\xa1\\xc9\\x92\\x6f\\xf4\\x52\\x9e\\x53\\x6f\\x1d\\x33\\xa1\\x42\\xb1\\x5e\\x3c\\xf9\\xe1\\xe2\\xf9\\x87\\xd7\\xe7\\x6f\\x2e\\x7f\\x7d\\x7b\\xf1\\xfe\\xe5\\xe5\\xcb\\x8b\\x37\\xbf\\xbe\\xb8\\x78\\xf5\\xea\\xe2\\xe3\\xcb\\x37\\x7f\\xd1\\x7b\\xbc\\xa0\\xa9\\xc2\\x35\\xe1\\x0b\\x95\\x52\\x5c\\x90\\x76\\xb9\\xa5\\xa0\\x85\\xa2\\xef\\x8a\\xfa\\x9a\\x42\\x34\\x2f\\x12\\x49\\xd5\\x7b\\x55\\x08\\x05\\x19\\x9e\\x22\\x6c\\xde\\xcf\\xeb\\x12\\xd6\\x78\\x8a\\x0c\\x2a\\x15\\x29\\x34\\x2a\\x1b\\x5e\\x3f\\xab\\x97\\x54\\x2a\\x2e\\x9e\\xf3\\x5a\\x15\\xac\\xa6\\x62\\xce\\x56\\x90\\x8e\\x08\\xa9\\xe2\\x58\\xe9\\x9f\\xfd\\x9e\\x25\\x4b\\xdb\\x29\\x61\\x8d\\x3c\\xa5\\x0d\\xac\\xd0\\xa2\\x4a\\x05\\xac\\x2c\\xc4\\x15\\xd1\\x8c\\xf6\\x72\\xb7\\x32\\x9a\\xba\\x28\\xa1\\x7d\\xc0\\x0a\\xa5\\x9a\\x99\\x12\\x2a\\x64\\x1a\\x02\\x26\\x17\\xdd\\xce\\xcf\\x9e\\x16\\xe2\\xda\\x10\\x24\\x93\\x8a\\xd6\\xd7\\x6a\\x1d\\xc7\\x37\\x9c\\x95\\xd1\\x74\\x44\\x48\\xdb\\x95\\xcd\\xf2\\x45\\xf8\\x92\\x02\\xc5\\x1b\\x80\\x39\\x31\\xbf\\x5a\\x32\\x16\\xc0\\xea\\xd4\\x25\\x6f\\x40\\xea\\x9e\\x5f\\xd1\\x95\\x02\\x98\\x85\\xd2\\xc5\\x56\\xd0\\x8a\\x16\\x21\\x84\\xed\\xf7\\xad\\x64\\x31\\x8b\\x4f\\x4d\\xbe\\x22\\xd6\\x58\\x9c\\x8c\\xb0\\x6b\\xb1\\xfa\\xda\\x0d\\xd9\\xef\\x6b\\xcf\\x12\\x91\\xf1\\xfc\\xe0\\x8d\\x87\\x7e\\x6e\\x39\\x50\\x59\\x31\\xb3\\x22\\xf2\\xcd\\xef\\xe3\\xc1\\x37\\x79\\x1c\\x87\\x6f\\x98\\x91\\x02\\x2a\\x6c\\x58\\x80\\x70\\x6d\\x5f\\x2a\\x4d\\xb3\\xb6\\x4b\\x7c\\x31\\x99\\xa5\\xb3\\x79\\x6b\\xba\\x14\\x6f\\xc6\\x84\\x3d\\x11\\x58\\x5b\\x31\\xa5\\xf8\\xc6\\xbf\\xe9\\x19\\x63\\x52\\x9b\\x67\\xe3\\x74\\xdd\\x4b\\x87\\xec\\x2a\\x44\\x16\\xdc\\x39\\x7e\\x1b\\xee\\xa6\\x40\\x33\\x1c\\x33\\x62\\x5f\\x09\\xe1\\x0b\\xf0\\x4e\\x03\\x01\\x29\\xf8\\xde\\x2c\\x03\\x3c\\x0a\\x4d\\x21\\x24\\x7d\\x51\\xf1\\x42\\x41\\x9a\\x81\\x2b\\x2e\\x4a\\x2a\\xc0\\x98\\x8f\\xc1\\x47\\x56\\xaa\\x35\\xc8\\xf1\\x6c\\x8a\\xc6\\xc3\\x83\\x58\\x6f\\x50\\x87\\xd8\\x46\\x23\\x86\\x39\\x66\\xad\\xb6\\xff\\x04\\x55\\x06\\xac\\x95\\x04\\x63\\x9a\\x63\\x95\\x39\\x59\\x30\\x6f\\x3c\\x03\\xcb\\x8a\\x69\\x93\\xee\\xde\\x82\\x91\\xbc\\x37\\x92\\x51\\x88\\x16\\xbd\\x01\\x63\\x96\\x81\\x4d\\x21\\xae\\x59\\x0d\\xc6\\x10\\xfc\\x48\\x0d\\x91\\xda\\xb0\\x2c\\x80\\x95\\x39\\xc3\\x00\\xf4\\xd8\\x38\\xc7\\x90\\xd4\\x71\\x08\\xe5\\x69\\x48\\xcc\\x1a\\x5a\\x16\\x53\\xd2\\xf3\\x68\\x58\\x91\\x87\\x2c\\x0c\\xe6\\x44\\xe3\\x19\\xc7\\x27\\x5e\\x58\\x79\\xad\\xdc\\xad\\x0d\\x02\\xe9\\xa6\\x45\\x05\\x1b\\x96\\x21\\x7c\\xab\\x19\\xaa\\xdb\\x2d\\x67\\x5d\\xf3\\xa1\\xc3\\x67\\x19\\x18\\x51\\x49\\xe1\\xee\\x80\\x29\\xde\\x19\\x01\\x49\\x9d\\xd0\\xd0\\xc4\\x00\\xc1\\x56\\x9e\\x52\\x2b\\x63\\x34\\xb1\\x4b\\x1e\\x02\\xd2\\xae\\x3b\\x37\\xb6\\x3b\\x68\\x1d\\xd4\\x68\\x23\\x25\\xee\\x77\\xda\\x3e\\x5e\\x53\\xf5\\x3d\\xdf\\xd6\\x25\\xab\\xaf\\x9f\\x9b\\xdd\\x79\\x47\\x97\\x0a\\x5a\\x13\\xa3\\x45\\x9c\\x86\\x22\\x4e\\xbd\\x88\\xcf\\xb9\\x13\\x69\\xcc\\xbd\\x08\\x63\\xde\\x89\\x36\\xe6\\xad\\x30\\x1f\\x96\\x85\\x09\\x09\\xd0\\xee\\x40\\x2b\\x49\\xa3\\xaf\\xad\\x29\\xc8\\x4e\\x03\\x4c\\x2d\\x5c\\xac\\x78\\x93\\x9a\\xb5\\x1c\\xcb\\x1c\\xe0\\x89\\xeb\\x76\\x0c\\xf6\\x4b\\x4f\\xcc\\xd0\\x03\\x6e\\xc8\\x50\\x74\\xb3\\x86\\x28\\xdd\\x1d\\xb0\\x24\\x8d\\x65\\x9d\\x8e\\x6f\\xac\\x44\\x7e\\xb4\\xaf\\xc2\\x01\\x17\\x16\\x78\\x49\\x1a\\xc7\\xce\\x6e\\xe4\\x8f\\xee\\x5d\\xf8\\x15\\x85\\x41\\xae\\x22\\x3e\\x3c\\x30\\xa0\\x26\\x12\\x6f\\xda\\x16\\x3b\\x65\\x52\\x6a\\xd6\\x57\\xfb\\xfd\\xc6\\x6e\\xc6\\xb5\\x09\\x61\\xe6\\xd5\\x84\\xac\\xe0\\x35\\x06\\x77\\x00\\xe1\\x8d\\x7b\\xbe\\xd7\\x26\\xc4\\xa2\\x38\\x21\\x15\\x16\\x0e\\x89\\x09\\xd9\\x78\\x73\\xb6\\x84\\x22\\xd8\\xe0\\x2d\\xa4\\x98\\x5b\\xa8\\xcc\\xc8\\x24\\x16\\x1d\\xfd\\x5d\\x68\\x81\\x1b\\xa2\\x45\\x01\\x4b\\x72\\x0d\\x39\\xc2\\x25\\xd1\\xd1\\x1c\\x2e\\x74\\x90\\x81\\xf0\\x8a\\x04\\xca\\x5f\\x24\\x56\\xf7\\x2f\\x79\\x63\\xc8\\xd1\\x7a\\x8f\\x37\\x43\\x23\\xb4\\xda\\x75\\x43\\xd6\\x64\\x09\\x77\\x7a\\xc7\\x1a\\xcd\\x94\\x89\\x34\\x7f\\x57\\xd8\\xec\\x67\\x63\\x78\\x3a\\x91\\xf6\\x67\\xe3\\xb6\\xd3\\xed\\x84\\xdf\\xc7\\xa6\\x15\\x5f\\xcd\\xac\\x75\\x62\\x55\\xf9\\x92\\x37\\x64\\x8a\\xfd\\x9b\\x5e\\x92\\x4c\\xf1\\x88\\xc5\\xb1\\xb0\\x44\\x6f\\xfb\\x98\\xb5\\x93\\x0c\\x4e\\x57\\x43\\x9d\\x1a\\x86\\xee\\x9d\\xaf\\x0d\\x8a\\x64\\x35\\xd9\\xe2\\xb5\\xdf\\x51\\xf7\\x66\\xf0\\x24\\x9b\\xc9\\x15\\x5e\\x3b\\xb1\\x70\\x2f\\x1d\\x52\\xdb\\x3e\\x52\\x57\\x6e\\x7b\\x20\\x5b\\xf0\\xce\\x83\\x97\\x28\\xe5\\x84\\x90\\x32\\x08\\x0c\\xcb\\x30\\xdc\\x83\\x6b\\x52\\xc1\\x35\\xe6\\x08\\xe1\\x75\\xb7\\xa7\\x57\\x61\\x78\\xf6\\xb8\\x53\\xe4\\x64\\x6b\\x5c\\x04\\x66\\xe4\\x27\\xa8\\x42\\x89\\xc6\\xb7\\xac\\x2e\\xf9\\x6d\\xc2\\xea\\x9a\\x0a\\x27\\xe3\\x53\\xad\\xc9\\xdd\\x38\\x2b\\x9c\\xbd\\x81\\x5e\\xc4\\xa7\\x5a\\x8e\\x0a\\xa8\\x10\\x6e\\x7a\\xde\\x4d\\x12\\xb3\\xc7\\xc2\\x2a\\xdb\\x98\\x07\\x0c\\xb7\\x3b\\xed\\x94\\xb3\\xed\\x31\\xdc\\xb6\\xfb\\xcd\\xfc\\x4e\\xd7\\x87\\x79\\x2b\\xcb\\x32\\x90\\xe5\\x5b\\x4f\\x37\\x7b\\x28\\x2c\\x3d\\x8e\\x1d\\x16\\xa3\\x59\\x0a\\x56\\xec\\x8e\\x96\\x36\\x62\\xa6\\x61\\xc4\\xbc\\xdf\\xdf\\x1e\\x47\\xf5\\xf7\\xc6\\x6d\\x31\\xec\\x84\\xa7\\xb1\\xd4\\x4c\\x2d\\xee\\x53\\x6d\\x1e\\x6c\\x14\\x6a\\xa2\\x95\\x1b\\x46\\x6f\\x75\\xfa\\xa8\\x41\\x0b\\xd4\\x90\\x2b\\x28\\xd1\\x5c\\xdb\\x31\\x33\\xb7\\x98\\x3b\\xaf\\x65\\x73\\x02\\x33\\x68\\x01\\x0b\\xa2\\x33\\x09\\x85\\x10\\x6e\\x11\\x2e\\x5a\\x52\\xe2\\x18\\x16\\x5f\\xdb\\x51\\x84\\x52\\x60\\x37\\xc4\\x42\\xfc\\xea\\x84\\xb4\\x20\\xc2\\x45\\x99\\x5b\\x58\\x60\\x69\\x71\\xf7\\x1c\\x0a\\x17\\x1f\\xdd\\x42\\x89\\x2c\\xe1\\x2b\\xb2\\x86\\x5a\\xab\\x57\\x4e\\xe7\\xf0\\x92\\xac\\xac\\x36\\xce\\x1b\\x6b\\xdc\\x2b\\xa3\\x1c\\x55\\xb0\\xbf\\x8d\\xd3\\x11\\xb2\\x19\\x9b\\x4e\\xdc\\x38\\xeb\\x5f\\x59\\x75\\xa9\\xc2\\x1d\\x6f\\xac\\xda\\x90\\xe5\\xd8\\xf6\\x5a\\xfb\\xdf\\x90\\xca\\x5b\\x31\\x3f\\x99\\xe1\\xc6\\x7b\\x93\\xc6\\xab\\x1a\\x6b\\xd7\\x32\\xcf\\xdd\\xf6\\x9d\\x87\\x8a\\x61\\x8d\\x87\\x76\\x29\\x96\\x86\\x36\\xf1\\x7d\\x12\\xe4\\xbc\\x37\\x3e\\x4e\\xc1\\xb5\\x9d\\x29\\xc8\\xb7\\xbf\\x2f\\xe6\\xfb\\x36\\x8c\\x7b\\xbf\\xcd\\xd3\\xa9\\xe6\\xeb\\x64\\x66\\xbc\\x8a\\x4f\\xdd\\x80\\x4e\\x29\\x41\\x1b\\xa5\\xd3\\xb9\\x15\\xaa\\x7b\\xa8\\x17\\x14\\xb8\\x6e\\xf5\\x65\\x37\\x68\\xf1\\x94\\xe1\\x71\\x63\\xdd\\x96\\xf5\\xef\\xed\\x40\\xcb\\x0a\\x65\\x7f\\x4f\\x4c\\xa4\\x77\\xfc\\xc3\\x70\\x5b\\xee\\x29\\xf7\\x70\\xb0\\x02\\xee\\x46\\x2b\\xbb\\x5f\\x4d\\xcf\\x8b\\xb6\\xa0\\x0f\\xb8\\x24\\x17\\xa6\\x68\\x91\\x7c\\xa1\\xf7\\x12\\x4a\\x94\\x6c\\x8a\\x26\\xa8\\xc9\\xf4\\x42\\x93\\x2f\\xf4\\x3e\\xa5\\x07\\x2c\\x33\\x9a\\xe3\\x5d\\x21\\x68\\x91\\x9e\\x43\\xfd\\x82\\x0e\\xe8\\x80\\x12\\xc9\\x85\\x3a\\xaa\\xe6\\xf8\\x4d\\x4a\\xf4\\xe0\\x09\\x35\\x3f\\x07\\xed\\x89\\xca\\x64\\xc5\\x2a\\x45\\x45\\x6f\\xa5\\xfe\\x5e\\xb3\\xd3\\xbd\\xfe\\x8e\\xf0\\xd0\\xe8\\xc5\\x31\\xeb\\x5a\\x7e\\x74\\xee\\x04\\x57\\x64\\xfa\\xb4\\x70\\x7b\\xbd\\x28\\xb2\\x69\\xae\\x29\\x4b\\x4b\\xf7\\x80\\x57\\x84\\x26\\xb2\\xa9\\x98\\x82\\x60\\x02\\x50\\x36\\xcb\\x3d\\xf4\\x6a\\x0c\\x57\\x0b\\x30\\x01\\xe3\\x55\\x0a\\x40\\x60\\x45\\x2e\\xac\\x50\\x79\\x5b\\x55\\x42\\xfd\\xe2\\x27\\x6d\\xf5\\xe6\\x07\\x83\\x5f\\x75\\x74\\x9c\\x96\\x6c\\x10\\xe6\\xa1\\x8b\\x52\\x9d\\xba\\xf5\\x02\\x72\\xdf\\x6e\\xc3\\x58\\x6d\\xec\\x07\\x3a\\xb5\\xde\\x0d\\xce\\x32\\x31\\xaf\\xb6\\xfc\\x6e\\xff\\x7b\\xd1\\xca\\xb8\\xb5\\xca\\xfd\\x90\\x65\\xcc\\x5b\\x23\\x5d\\x77\\xc4\\xdc\\x75\\xc4\\xd8\\x48\\x0d\\x08\\x1b\\xda\\x5a\\xe9\\xb5\\x5e\\xc2\\x0b\\xa7\\xcd\\x14\\xb5\\xf8\\x03\\xdb\\x02\\x0e\\x5d\\x52\\x24\\x68\\x53\\x15\\x4b\\x0a\\xcf\\xf4\\x94\\xbd\\x99\\xbe\\xb7\\xa3\\xf6\\x8a\\x37\\x67\\xd7\\x78\\x40\\xe0\\x54\\x46\\xf3\\x30\\xb8\\x7d\\xef\\xf7\\x81\\x13\\x1e\\xee\\xe0\\x34\\x77\\x11\\xac\\xe6\\x7d\\x47\\x37\\xeb\\x6b\\x09\\x6b\\x95\\x49\\x10\\x57\\x9f\\x71\\xc4\\x58\\x32\\x82\\x0a\\x8d\\xf6\\x82\\x62\\x61\\xe8\\xf1\\x34\\x4a\\xdd\\x50\\xd9\\x44\\xcc\\xd0\\x59\\xea\\x06\\x0b\\x11\\x68\\x13\\x6e\\x42\\xfb\\x42\\x37\\xda\\xe7\\xd4\\x77\\xb6\\x6c\\xcd\\x9a\\x9c\\xa8\\xac\\xc9\\xc7\\x2a\\x2b\\xf3\\xb3\\x6f\\x26\\xcc\\xfc\\xe0\\x3a\\x93\\x39\\xd1\\x51\\x83\\x5c\\xa8\\x4c\\xe6\\x13\\x96\\x15\\x79\\xaa\\xb2\\x3b\\x28\\x51\\x8e\\x83\\xbd\\xb8\\xec\\x29\\xd4\\x33\\x21\\x8a\\xfb\\xa4\\x11\\x5c\\x71\\x75\\xdf\\xd0\\x64\\xc5\\xea\\x72\\x61\\x7f\\x6c\\x31\\xd3\\x69\\x97\\xd2\\xec\\xe9\\x80\\xfc\\xe0\\x59\\xc8\\x56\\x70\\x08\\xc4\\x4b\\xcd\\x82\\xd6\\xbe\\x75\\x4d\\x43\\xf6\\x80\\x66\\x2a\\xd7\\x41\\xe7\\xc1\\x27\\x10\\x1a\\xc3\\xc7\\xc7\\xb5\\x80\\x3d\\xab\\x43\\xcd\\x79\\x0e\\x5d\\x86\\x69\\xeb\\x03\\xd6\\x46\\x1b\\xaf\\xaf\\x4d\\xa7\\xac\\xd8\\x92\\xc2\\x29\\xfe\\x41\\x47\\x27\\x75\\xb1\\xa1\\x00\\x33\\xd4\\x42\\xac\\x93\\x15\\x17\\xe7\\xc5\\x72\\xdd\\x21\\xaa\\xd0\\x4e\\x65\\x5d\\x11\\x38\\x8f\\xe3\\x25\\xaf\\x25\\xaf\\x68\\x72\\x5b\\x88\\x1a\\x82\\xcf\\x1b\\x5e\\xb2\\x15\\xa3\\x22\\xf1\\x63\\x3e\\x47\\x4c\\x46\\x25\\x6d\\x04\\x5d\\x16\\x8a\\x96\\x38\\xda\\x4a\\x1a\\x05\\xc3\\xea\\xcf\\x23\\xe0\\x69\\xed\\x81\\xde\\xef\\x55\\xb2\\xaa\\xe7\\x2a\\xa1\\x75\\x71\\x55\\xd1\\x32\\x8e\\x29\\x64\\x3a\\xdc\\xe3\\x4e\\xc7\\x64\\xd2\\xd8\\xda\\xf2\\xf2\\xa4\\x09\\xe1\\xae\\x45\\xd0\\x15\\x15\\xb4\\x5e\\xd2\\xde\\xb8\\xb6\\x55\\x5b\\x0f\\x06\\x39\\x56\\x08\\x1d\\x10\\x0e\\xbc\\xde\\x1b\\x68\\xeb\\x68\\x6a\\xcd\\x64\\x22\\x55\\xa1\\x68\\xc2\\xe4\\x0f\\x54\\x2a\\xc1\\xef\\x69\\xe9\\x93\\xdd\\x1d\\xab\\xa5\\x2a\\xea\\x25\\x4d\\x4d\\x6d\\x5b\\x6a\\x93\\x24\\x75\\x92\\x54\\x08\\xc1\\x6f\\xdf\\x77\\xaf\\xca\\x95\\xfb\\xcd\\xdb\\xaa\\x62\\x4d\\x43\\xcb\\x74\\x34\\xc3\\x0e\\xa1\\x74\\x77\\x38\\xcc\\xe9\\x00\\xd2\\x17\\xb0\\x43\\x00\\x9b\\x47\\x4b\\xa2\\x7d\\x0e\\xc8\\xa0\\x89\\x31\\x06\\xda\\xd7\\x92\\x1b\\x3b\\x89\\x37\\x9a\\x12\\xd9\\x75\\xe0\\x81\\x15\\x1e\\x01\\x8a\\x7b\\x50\\xfc\\x9e\\xc9\\x44\\xa3\\x9f\\x5c\\xe9\\x04\\xb4\\x10\\x8c\\x4a\\x1f\\x47\\x3f\\x36\\xba\\x29\\x4a\\x9d\\xad\\x6a\\x34\\xb9\\x60\\xd7\\xac\\x2e\\xaa\\xb7\\x2d\\xba\\x74\\x10\\x43\\xb7\\xbb\\xef\\x61\\x88\\xe0\\x10\\x01\\xc1\\x74\\x74\\x32\\x3f\\xf1\\xb1\\x2c\\x01\\xc5\\x95\\xe4\\xd5\\x56\\x51\\x80\\x29\\x79\\x6e\\xa1\\xb6\\x58\\x62\\x8a\\x70\\x6f\\xa7\\x9f\\x9b\\xfa\\x64\\xb9\\xe8\\x11\\xc5\\xeb\\x0f\\x4d\\x59\\x28\\xed\\x74\\x52\\x38\\x34\\x9c\\x8c\\xa6\\xf8\\x68\\x86\\xed\\x31\\x21\\x74\\x27\\x5c\\x5f\\x7a\\x76\\x87\\x26\\x92\\x6f\\xe8\\x89\\xd3\\xd6\\x61\\x99\\x56\\x4a\\xe3\\xb3\\x9d\\x16\\x04\\x65\\x72\\x6d\\xde\\x7a\\x75\\x8a\\x8f\\x7a\\xe2\\x8a\\x0b\\x68\\x9d\\x4b\\x36\\x9a\\x61\\xb0\\x91\\x00\\x83\\x8f\\xf4\\xea\\x0b\\xd3\\x36\\xf9\\x35\\xff\\x17\\xc0\\xe0\\x02\\xe4\\x26\\xe4\\x5b\\xae\\x0b\\xf1\\x4c\\xc1\\x29\\x4a\\x14\\xff\\xa0\\x79\\xf5\\xbc\\x90\\x14\\xa2\\x31\\x75\\x76\\x61\\xa6\\xed\\xfe\\x74\\x5e\\x3f\\x55\\xce\\xef\\x4f\\x66\\xf3\\x7a\\x3c\\xf6\\x2e\\x5b\\x65\\x75\\x8e\\x05\\x61\\x0b\\x00\\xc6\\x6c\\xcc\\x53\\x5b\\x9e\\x1c\\x38\\x4e\\xea\\x15\\x84\\x12\\xa3\\x22\\x99\\xc8\\xbd\\x41\\x14\\x87\\xa0\\xd4\\xdd\\x11\\xf3\\x16\\x76\\x2e\\x6b\\x50\\x03\\x35\\xab\\xbf\\x1c\\xef\\x22\\x28\\x9a\\xa6\\xba\\x37\\x6a\\x07\\xb4\\xad\\x08\\x44\\x27\\x11\\x74\\xc3\\x6f\\xe8\\x33\\xaf\\x88\\x10\\xdc\\x4d\\x5a\\xb9\\x01\\x28\\x54\\x03\\x8b\\xa3\\x09\\xed\\x08\\x00\\x03\\x3d\\x9d\\x4c\\x0d\\xf5\\x2a\\xde\\x0c\\x76\\x64\\x1f\\x21\\x50\\xa2\\xa8\\xe5\\x8a\\x8b\\x0d\\x40\\x39\\x01\\x7e\\xd9\\x92\\x49\\xbd\\xbb\\xe7\\x37\\xb4\\x56\\xaf\\x98\\x54\\xb4\\xa6\\x42\\x42\\xd4\\x17\\x25\\x8b\\xff\\x45\\xed\\x38\\x10\\xc7\\xe1\\x02\\xdd\\x69\\x80\\x1b\\x67\\x4e\\x16\\x42\\xfa\\x2d\\xb4\\x8e\\xc1\\xdf\\x3f\\x98\\x20\\x77\\xa7\\x5f\\x2a\\x29\\xe9\\xaa\\xd8\\x56\\xea\\xef\\x8c\\xde\\xa6\\x36\\xa5\\xea\\x20\\xfc\\xd8\\xd5\\x2f\\x6d\\x56\\xd0\\xa6\\x6b\\x34\\xac\\x99\\x88\\xd3\\xc3\\x96\\x00\\x28\\x9d\\x37\\x49\\x51\\x96\\x3d\\xd2\\x8d\\xcf\\xda\\x35\\x85\\x94\\xec\\x86\\xa6\\xa3\\xe9\\x01\\x61\\xb1\\xdf\\xff\\x08\\x6b\\xd8\\x84\\xc7\\x1e\\x6e\\x71\\xcc\\x92\\x66\\x2b\\xd7\\xb0\\x09\\x54\\xe1\\x59\\x87\\x1a\\x4f\\xb6\\x46\\x67\\x4d\\xc1\\x8c\\x30\\xac\\xe9\\x3e\\x5d\\x11\\x08\\x2a\\xd9\\xbf\\x28\\xc0\\xbd\\xe1\\x7d\\x24\\x5c\\x79\\xad\\x0e\\x4e\\x0d\\x7e\\x84\\x02\\xfb\\xc2\\xeb\\xd1\\x54\\x9e\\x84\\xa9\\xad\\x44\\x6d\\x83\\x33\\x97\\x44\\x60\\x9e\\x50\\x8d\\x84\\x3c\\xb7\\xba\\xad\\x25\\x3a\\x70\\x40\\x2f\\x21\\xda\\x05\\xa2\\xdf\\x1b\\xba\\xdf\\x07\\xe6\\x87\\x3c\\x83\\x8f\\xd8\\x6d\\x7c\\xec\\x3f\\xe4\\x72\\x4d\\xcb\\x6d\\x45\\xad\\x29\\x0b\\x33\\xfb\\xd7\\x3d\\xab\\x64\\x18\\x65\\x85\\xe9\\x01\\x5e\\xa9\\x90\\x60\\x84\\x55\\x9f\\xe2\\xd3\\xe8\\x81\\xa2\\x1d\\x1d\\x86\\xe8\\x59\\xd8\\x87\\x78\\x40\\xfd\\x06\\xa2\\x4d\\xc4\\xf1\\x32\\x24\\xcb\\xdb\\x26\\xcf\\x5a\\x37\\xee\\x88\\xbb\\x33\\x1c\\x1c\\xdf\\xbd\\x7b\\x84\\xbb\\x71\\x0c\\x97\\xda\\xa7\\x57\\xcf\\x6a\\xb6\\x29\\xf4\\xf0\\x17\\xa2\\xd8\\x50\\x38\\xc4\\xbe\\x80\\xbd\\xe4\\xf5\\xe0\\x3e\\x98\\xbe\\x90\\xcd\\x1f\\x82\\x33\\x64\\x30\\x22\\x84\\xc6\\xf1\\x88\\xc9\\x37\\xc5\\x1b\\x18\\x9e\\x1f\\x20\\x14\\xc7\\x4c\\xbe\\x60\\x35\\x33\\xde\\xa3\\x9b\\xfe\\x8b\\xdd\\xa5\\x30\\xbf\\x54\\xe8\\x94\\xd9\\x6d\\x6a\\x05\\xc0\\xdc\\x85\\xe6\\x2e\\xa0\\xf6\\x41\\xb4\\x2d\\x4c\\xe3\\x36\\x62\\x77\\x09\\xc6\\x40\\xe8\\x1e\\xc7\\x1f\\xa0\\xca\\x78\\xae\\x4d\\x2a\\x23\\xa0\\xb9\\x03\\xda\\xd1\\x5a\\xa3\\xc6\\x75\\x00\\xce\\xf3\\x31\\x0b\\x5d\\xd1\\x6f\\xff\\x26\\x8e\\x1a\\xc2\\x7c\\x34\\x33\\x81\\x29\\x3d\\xb1\\xd4\\x5c\\xc7\\xde\\x92\\xaa\\xa0\\x05\\x1b\\x74\\xc2\\x25\\x5f\\xf4\\x13\\xca\\xe3\\xb8\\x39\\x74\\xa8\\x5e\\x7b\\x9d\\x07\\xc5\\x35\\x19\\x8d\\x58\\x1c\\x0f\\xb8\\xe1\\xd6\\x41\\xeb\\x69\\x3a\\xde\\xd6\\xa3\\xba\\x80\\x34\\x31\\x35\\xdc\\xa7\\xcc\\xfe\\xda\\xa2\\xeb\\xa8\\x2d\\x92\\x80\\xcf\\x60\\xac\\xc6\\xe0\\x33\\x98\\x1f\\x05\\xc9\\xe6\\xdc\\xe8\\x33\\x18\\x83\\xc8\\x7b\\x2e\\x1d\\x24\\x0b\\xfa\\xcf\\x2d\\x13\\xb4\\x8c\\xae\\xee\\x23\\x30\\x16\\xbd\\xde\\x3a\\x32\\x2b\\x44\\x8a\\x47\\xb7\\x5c\\x7c\\xc1\\xd1\\x15\\x8d\\xe4\\x56\\x50\\xdd\\xc0\\xea\\x65\\xb5\\x2d\\x69\\xc4\\x54\\x74\\x45\\x57\\x5c\\x50\\x3b\\x7b\\x04\\xd0\\xe1\\x34\\xf9\\xfc\\x6b\\x20\\x7b\\xb4\\x2e\\xdd\\xd1\\x8e\\x54\\x85\\xd0\\x19\\x97\\xfd\\xb5\\x6d\\xba\\x37\\x0d\\x8e\\xd1\\xfe\\xf9\\x1f\\x9c\\x7a\\x86\\x27\\x7e\\x33\\x1d\\x74\\x14\\x5d\\x96\\x42\\x75\\x0a\\x5e\\xf8\\x58\\x83\\x8f\\x67\\x28\\x59\\xf2\\x7a\\x59\\x28\\xd8\\x36\\x4e\\x31\\x47\\xc1\\x5d\\x0c\\x96\\x08\\x7a\\x43\\x85\\x8e\\x51\\x52\\xd6\\x21\\xf6\\xf7\\xbe\\x1b\\xaa\\x09\\x4d\\x36\\xe6\\xc8\\xe4\\x0c\\xc2\\x45\\xfa\\x69\\xb2\\xff\\x34\\x46\\x8b\\x4f\\xe5\\x93\\x4f\\x89\\xfe\\x8b\\x60\\xf2\\x04\\x9d\\x21\\x2c\\xc8\\xb8\\xd6\\x38\\x35\\xa4\\xce\\xbe\\xc9\\xcd\\xc6\\x89\\xae\\x06\\xc5\\x56\\x50\\x67\\x49\\x4d\\x57\\xa5\\xfa\\x13\\x70\\x65\\x3f\\xe9\\x2f\\x69\\x34\\xee\\x6e\\xc6\\x9f\\x1a\\x90\\x4a\\xc2\\xe7\\x57\\x82\\x16\\x5f\\xec\\xe5\\x8b\\x3f\\xb9\\xbb\\x1a\\x7f\\x12\\x20\\x75\\xce\\x2e\\x95\\x84\\xd9\\xbb\\x17\\x25\\x59\\x42\\xd9\\x92\\x55\\x66\\x2a\\x3f\\x9b\\x4d\\xa7\\x4f\\xc4\\xc1\\xd4\\x4b\\xd7\\x9a\\xfd\\xcd\\x7e\\x0f\\x6e\\x4c\\xf1\\xb2\\x41\\xae\\x50\\xea\\x86\\x17\\xc4\\x0f\\x59\\xfc\\x04\\x1f\\x3a\\x59\\xfb\\x3d\\xa5\\xe9\\xf4\\xab\\xd3\\x1f\\xab\\x80\\x17\\x0e\\xe5\\x36\\x86\\x6b\\x77\\xe3\\x5f\\xc7\\xbb\\x91\\x4d\\xf1\\x34\\xff\\x6a\\x79\\x80\\x21\\xdc\\xb4\\x25\\xa4\\x33\\xf8\\x69\\xbc\\xff\\x34\\x41\\x67\\x0f\\x96\\xcd\\x68\\xa2\\x04\\xdb\\x40\\xed\\x21\\x64\\xb0\\x4b\\x97\\xb0\\x19\\x48\\x96\\x27\\xf6\\x12\\x90\\xa4\\x85\\xd0\\x52\\x81\\xf7\\x9f\\xe4\\x19\\x3a\\x20\\x34\\x6f\\x32\\x99\\xc7\\xb1\\xa9\\x47\\xea\\xc7\\x6e\\xb3\\xb1\\x0e\\x1e\\xfb\\x4a\\x7b\\x61\\xb3\\x8a\\x48\\xd2\\xa6\\x10\\x3a\\xd4\\xd7\\x6a\\x7a\\xbb\\x66\\x8a\\x46\\xb2\\x29\\x96\\x14\\x4a\\x64\\xee\\x68\\x1d\\xa7\\xba\\x45\\xb4\\xe4\\x9b\\x4d\\x11\\x41\\x8c\\x22\\x9d\\x2b\\xd2\\xa2\\x4c\\x5c\\xc2\\x5b\\x92\\xb3\\x4f\\xf2\\x09\\xfe\\x24\\x9f\\xec\\x3f\\xc9\\xf1\\x19\\x2e\\x88\\x41\\x45\\x2e\\xb2\\x26\\x4f\\xb3\\xa6\\x55\\x02\\xd9\\x6a\\x46\\x66\\xd0\\xb4\\x4c\\x2a\\x51\\x36\\xcd\\x73\\x84\\x8f\\xda\\x66\\x79\\xee\\x47\\x7b\\x08\\x72\\x3c\\x43\\x28\\xef\\x24\\xa8\\x38\\xe2\\x6a\\xb7\\x57\\xd0\\x5a\\xe0\\x91\\x48\\x05\\x3a\\x2d\\xc4\\x34\\x64\\x34\\x0b\\x8b\\x4f\\xe5\\x76\\x49\\x07\\x2b\\x93\\xc0\\x98\\x90\\x8c\\xb6\\x69\\x83\\xe1\\xb2\\xd9\\xfe\\x31\\xc0\\x60\\x12\\xec\\xbb\\x42\\x0b\\xd8\\x1b\\x49\\x94\\x5e\\x67\\x8a\\x29\\x4a\\x9b\\xa3\\xae\\xb1\\xed\\x9b\\xe9\\x3e\\xea\\x89\\x54\\xe8\\x80\\xb3\\xfc\\x41\\x41\\xd1\\xc6\\xa1\\xb6\\x67\\xc3\\x5a\\x58\\x8a\\x81\\xa0\\x44\\xe3\\x4d\\x07\\x7c\\x93\\x66\\xcb\\x07\\xe3\\xfc\\x60\\x9d\\xa9\\x7c\\x4c\\xf8\\x13\\x08\\x26\\x96\\x34\\x36\\x99\\xe5\\xe6\\x86\\x02\\xb2\\x70\\x03\\x0b\\xfb\\x97\\xe0\\xba\\x01\\x66\\x44\\xb9\\x7c\\x14\\xd7\\xbd\\x34\\x57\\xb4\\xa7\\x9b\\x52\\x87\\xc8\\x3e\\xbd\\x95\\x44\\x04\\xe1\\x43\\x49\\xea\\xa3\\x92\\x5c\\xeb\\xb8\\x3e\\xc0\\x31\\x43\\x8b\\x6c\\xcc\\xf0\\x34\\x4f\\xff\\x05\\x19\\x6e\\xb0\\xc4\\x25\\x72\\x7a\\x45\\x08\\x29\\x17\\xd0\\x1d\\x0a\\xf0\\x6c\\x9a\\xbb\\x73\\x86\\x09\\xe1\\xd9\\x2c\\x47\\xbe\\xe2\\xf8\\xd0\\xb0\\xb1\\x1f\\xe6\\xae\\xa7\\x98\\x41\\xbe\\xc3\\x8c\\x32\\x87\\x7e\\x6e\\x90\\x0b\\x1b\\xec\\x11\\xdd\\xc0\\x40\\x07\\x4d\\xa7\\xe9\\x36\\xa3\\x6f\\x30\\x3d\\xf8\\x34\\xf5\\x57\\xf2\\xba\\x50\\xeb\\x64\\xc3\\x6a\\xfc\\xb3\\x7d\\x5c\\x55\\x9c\\x0b\\xfc\\x93\\x6b\\x2f\\xee\\xf0\\xdf\\xc8\\x50\\x52\\x69\\xed\\xd2\\xf0\\xfd\\x45\\x6f\\xcf\\xf0\\x3f\\x48\\x06\\xce\\xcb\\x6b\\x0a\\x30\\xb8\\x14\\xac\\xd4\\x89\\x1e\\x06\\x2f\\x98\\xa0\\x2b\\x7e\\x07\\x72\\xfc\\x47\\x32\\xc5\\x94\\x92\\xe9\\x9c\\xd2\\xa7\\xff\\x70\\x72\\x36\\xa7\\x74\\x4c\\x66\\x88\\xad\\xe0\\xdf\\xe2\\x78\\xfa\\x94\\xd4\\xc5\\x0d\\xbb\\x2e\\x14\\x17\\xc9\\x56\\x52\\xf1\\xec\\x5a\\xdb\\x47\\x2f\\xbc\\xff\\xc8\\x28\\xcd\\x11\\xda\\xfd\\x91\\xcc\\xac\\xf5\\xb7\\x77\\xeb\\xb0\\xa2\\xe4\\x6f\\x71\\xec\\x2c\\xe7\\x5b\\xc1\\x37\\x4c\\x52\\xcc\\x29\\x51\\x74\\x71\\x5a\\x98\\xef\\x74\\x2a\\xb8\\x18\\xa9\\x74\\x80\\xaf\\xd5\\xa0\\x0f\\x24\\x11\\x54\\xf2\\xea\\x86\\x42\\x94\\xa8\\x35\\xad\\x61\\x38\\xc3\\x28\\x86\\xb6\\x88\\xe8\\x70\\x48\\xff\\xdd\\x65\\x24\\x55\\x97\\x6c\\x43\\xf9\\x56\\x0d\\xc2\\xc4\\x7f\\xd4\\x50\\x31\\xa3\\x24\\xe8\\x75\\xe0\\x7c\\x49\\x91\\x99\\xd8\\xd0\\xa8\\x79\\xc7\\xb3\\xa2\\x69\\xfe\\x4e\\x85\\x64\\xbc\\xee\\x8c\\xeb\\xeb\\xf7\\x2f\\xcf\\xa3\\xd9\\x14\\x20\\x84\\xd9\\x01\\xd7\\x01\\xcc\\xf6\\xee\\x1a\\xa4\\x91\\xaf\\xab\\xf1\\x55\\xa4\\x10\\x52\\x6b\\xc1\\x6f\\xa3\\x9a\\xde\\x46\\x97\\xf7\\x0d\\x3d\\x17\\x82\\x0b\\x08\\x9e\\x17\\x75\\xcd\\x55\\xb4\\x2c\\xaa\\x4a\\x9b\\xd9\\xaa\\x90\\x32\\x2a\\x64\\x54\\xb4\\x14\\x02\\x74\\xc0\\xa2\\x87\\x73\\x78\\xc7\\x54\\x2f\\xe6\\xc5\\x90\\x1f\\x55\\x3a\\x4c\\x9d\\x83\\xdb\\x12\\x07\\x4f\\x68\\xbd\\xdd\\x50\\xa1\\x83\\x3e\\x12\\xbe\\xec\\xf7\\xa3\\x19\\x36\\x07\\xd5\\x2b\\x76\\xbd\\xb5\\xfd\\xa3\\x29\\x06\\x37\\x45\\xb5\\xa5\\x40\\xc7\\x6c\\xa6\\x5a\\x79\\x2b\\x98\\x72\\x7d\\x08\\xbb\\x88\\xd8\\x8a\\xec\\x5b\\xc1\\x1b\\x2a\\xd4\\x3d\\xa4\\x98\\x9b\\x53\\x14\\xde\\x86\\x6c\\x5d\\xc5\\xb5\\x77\\x41\\x48\\xc7\\x9f\\x50\\x75\\xf5\\x65\\xcc\\x11\\x66\\xa6\\x4d\\x27\\xc2\\xea\\x70\\x80\\x08\\x37\\x7d\\x8e\\xea\\x90\\xd8\\x87\\x50\\x3a\\x90\\xa4\\x8b\\x87\\x70\\x50\\x78\\x67\\x50\\x4f\\x39\\xee\\x88\\x4c\\x47\\x53\\x1c\\x52\\xa8\\xdf\\x3d\\x45\\x26\\x2b\\x4e\\x4d\\x29\\x9a\\x63\\x7a\\xc0\\x92\\xfa\\x53\\x2f\\x9d\\x35\\x5f\\xd7\\xfb\\x7d\\x28\\x87\\x6d\\x65\\x0a\\x73\\x32\\x9b\\xf3\\x93\\x18\\x72\\xce\\xc7\\x63\\xe4\\x07\\x31\\x8d\\xaa\\x0a\\x82\\x49\\x9e\\x63\\x85\\x1c\\xf4\\xae\\xbc\\xbe\\x2e\\xe4\\xc5\\x6d\\xed\\x69\\xb0\\x17\\x81\\x35\\x2b\\xe2\\x18\\xd2\\x8c\\xe9\\xcc\\x84\\xe5\\x5d\\x85\\xfc\\x80\\x4b\\x4a\\x32\\x73\\xe0\\x38\\xb1\\xa1\\x2e\\xb6\\xa7\\x8f\\xf6\\x67\\xa2\\x43\\x5e\\x93\\x14\\xb5\\xbd\\x36\\x41\\xd2\\x2d\\xb6\\xcf\\x9e\\x28\\xfa\\x5e\\x1f\\xcb\\xd8\\x56\\x3b\\xc2\\x9d\\x1a\\x86\\x2f\\x5d\\xab\\x9f\\x68\\x6c\\xb1\\x1d\\x62\\x4f\\x42\\x6c\\x8b\\xed\\xce\\x71\\x41\\x49\\xe9\\x63\\xe0\\x3f\\x23\\x5c\\x51\\xb2\\x7b\\xf1\\xea\\xe5\\xdb\\x14\\xac\\x2a\\xd6\\x00\\xfc\\xfc\\xd5\\xc5\\xf3\\xbf\\x7e\\x7c\\xf9\\xfe\\x3c\\x05\\xcb\\x8a\\x2f\\xbf\\xdc\\x32\\x49\\x01\\x7e\\x7e\\xf1\\xe1\\xcd\\xe5\\xf9\\xbb\\xb0\\x93\\x6f\\x6b\\x45\\x45\\x37\\xe6\\x80\\x57\\xc3\\xda\\xa0\\x60\\x10\\xb0\\x99\\x42\\xb6\\xf8\\xfd\\xd7\\xfa\\x16\\xe1\\x4b\\xba\\x3b\\xcc\\x6b\\x9b\\x29\\x63\\x85\\x86\\x0a\\x0e\\x03\\x26\\x44\\x67\\x3e\\x54\\xaa\\xa3\\x6c\\xbb\\x76\\xa9\\x3f\\x3a\\x58\\x30\\xf6\\x8d\\x70\\x97\\x87\\xdb\\xd7\\xe4\\xca\\x1c\\xce\\xac\\x99\\x44\\xfd\\x72\\x19\\xb1\\x97\\xbe\\x54\\xf2\\x83\\x8d\\xbf\\x25\\x16\\xbd\\x5c\\x7d\\x17\\x94\\x12\\xd3\\xd1\\x0c\\xb7\\x25\\x5c\\xfd\\xd2\\x2b\\x30\\xa4\\x59\\x7e\\x38\\x2a\\x8c\\xdb\\xab\\xcb\\xbf\\xfd\\x73\\x4b\\xc5\\xfd\\x42\\x7b\\xba\\x94\\x87\\xe5\\x3e\\x6d\\x0b\\x99\\xef\\x66\\xba\\x9b\\x3d\\x50\\x1c\\x27\\xbb\\x03\\xee\\x1d\\x14\\x1f\\x21\\x1d\\x94\\x36\\x45\\xf7\\x8c\\x06\\x52\\x69\\x8a\\x76\\xf5\\x29\\xfc\\x8c\\xe6\\x27\\x8c\\xe8\\xf5\\xee\\xf7\\xbb\\x43\\x08\\x7a\\x21\\x7a\\xdd\\xe9\\xce\\x84\\x37\\xfd\\x2a\\x6b\\xef\\x68\\x7b\\x98\\xae\\x47\\xcf\\xbb\\x75\\x2e\\x9d\\xd2\\x03\\x1e\\xc6\\xf7\\xf1\\x33\\x6f\\x97\\x72\\x4f\\x94\\x4f\\xb9\\x8f\\x70\\x1b\\x3e\\xb2\\x0a\\xcf\\x90\\x54\\xc2\\xeb\\x57\\xbc\\x28\\x51\\x1c\\xfb\\x47\\x58\\x07\\x41\\x57\\xed\\x63\\xb1\\xba\\xab\\xa0\\xe1\\xda\\x55\\x71\\xfc\\x7a\\x56\\xf8\\xdc\\x8d\\xbb\\x86\\xf4\\x98\\xd0\\x2b\\x25\\xcd\\x1b\\x57\\xa7\\xb5\\x18\\x0c\\x57\\x78\\x07\\x4a\\x50\\xa4\\x69\\x73\\x2b\\x6d\\xdc\\x33\\x73\\x49\\x00\\xd8\\x65\\x01\\xb6\\x66\\xfa\\x54\\x91\\xde\\x38\\x0b\\xa8\\xd5\\xe1\\x70\\xc0\\x76\\x52\\x69\\xc5\\xfc\\xe1\\x59\\x6f\\x87\\x66\\x0d\\xe1\\xfb\\x30\\x88\\x97\\x83\\x0b\\x0f\\x55\\xb5\\x1f\\x86\\xf1\\xae\\x07\\x23\\xd7\\xee\\x0c\\x76\\xd7\\xb3\\x69\\xf2\\x41\\xb1\\x4a\\x92\\xf0\\x84\\x81\\xf4\\x83\\xc1\\xc5\\x75\\xc5\\xaf\\x8a\\xca\\xd5\\xa9\\x91\\xfb\\xf4\\xc4\\x4c\\xc3\\xab\\x20\\xf8\\x96\\xa4\\xa4\\xba\\xc1\\x2b\\x04\\xd9\\xb5\\x5d\\x6d\\x34\\x8b\\x7b\\xbb\\xa1\\x9d\\xde\\x51\\xf9\\xdd\\x9c\\xdd\\xb9\\xc3\\x9d\\x90\\x98\\x03\\xf6\\x87\\x44\\xfd\\xd6\\x56\\x42\\xd3\\x9d\\x5c\\xb3\\x95\\x4a\\x77\\x46\\x80\\xd3\\xd9\\x74\\x8a\\x69\\xb7\\xca\\xaa\\x1e\\x88\\xdd\\xc2\\xc4\\x81\\x13\\xd5\\xcf\\x09\\x4c\\x8e\\xd1\\xbf\\x7a\\xc1\\x74\\x3e\\xdd\\xdd\\x08\\x77\\x69\\x86\\x20\\xa1\\x98\\x37\\xa4\\xee\\x92\\x0e\\x97\\x9c\\xb5\\xee\\x4a\\xbb\\xbd\\xde\\xd1\\x7d\\x49\\x64\\xff\\xa4\\xbe\\xd0\\x0d\\x47\\x87\\xf2\\xb8\\x22\\x3b\\xe3\\xc2\\xd2\\xc6\\x98\\x9c\\x12\\x8b\\xac\\xd4\\x81\\x7f\\x5d\\xf6\\x5a\\xc6\\x22\\x2b\\xf2\\x49\\x93\\x15\\x39\\x0a\\xcf\\x3c\\x9d\\xed\\xb4\\xe6\\xaa\\xc1\\x95\\x76\\xdd\\xed\\xf5\\xf3\\xc3\\xc1\\x9d\\x94\\x7a\\xbe\\x7d\\x73\\xc2\\xb7\\xbf\\xf8\\x11\\xd3\\x03\\x6e\\x84\\xd9\\xbf\\x0b\\xf7\\x01\\x8b\\x9f\\xf4\\xe7\\x47\\x98\\xdd\\xdd\\x11\\x57\\xa7\\x67\\x9b\\xf6\\xcb\\x0d\\x1f\\x93\\xfa\\x13\\x95\\x79\\xd0\\xd4\\xf9\\x06\\x53\\x25\\x84\\x9c\\x08\\xc8\\x91\\x3f\\xd9\\xbe\\x3f\\x9d\\x8d\\x87\\x26\\x63\\xe5\\x4f\\x4a\\x31\\x47\\xf3\\x10\\x11\\xc2\\xe6\\xce\\x3d\\x27\\x8d\\x60\\x5c\\x30\\x75\\x6f\\x2a\\x26\\x7d\\xee\\x61\\x2d\\xcc\\x82\\x6d\\x0a\\x71\\x7f\\x22\\x47\\x9c\\x34\\x19\\x6d\\x53\\x48\\xfd\\xfc\\x94\\x65\\x34\\x8f\\xe3\\x91\\x4a\\xa8\\x5c\\x16\\x0d\\xfd\\xc8\\xd4\\xfa\\x9d\\x47\\xc5\\xd0\\xf0\\x13\\xd4\\xe3\\xb0\\x1e\\x87\\x74\\x64\\x69\\xef\\x51\\x73\\xa4\\x63\\xbd\\x25\\xd7\\xa8\\x0d\\xad\\xd3\\xa5\\x97\\xb4\\x2f\\x35\\x35\\x69\\x32\\xde\\x43\\xe1\\xbb\\xaf\\xa0\\x50\\x93\\x5f\\xa1\\x9e\\x63\\x50\\x98\\xc0\\x10\\xb2\\xbb\\xb0\\xd5\\xde\\xba\\x42\\x2d\\x86\\x1c\\xd7\\xe8\\x70\\x78\\xe4\\x1a\\x43\\xab\\x59\\xa6\\xe0\\x92\\xf9\\x20\\xac\\x2f\\xf6\\x14\\x2d\\x40\\x4b\\x25\\x48\\x81\\xe3\\x2b\\x98\\x37\\xad\\x8c\\xca\\x4c\\xe5\\xe6\\x64\\xf7\\xf4\\xdc\\xd9\\x64\\xb9\\xd8\\x6f\\x55\\xda\\xae\\x21\\x7a\\xa5\\x77\\xa7\\x71\\x39\\x76\\xbb\\x9e\\x7e\\x8b\\x4f\\x64\\x2f\\xed\\xdf\\x91\\x3c\\xe0\\x2f\\x94\\x36\\x97\\xfc\\x9a\\xaa\\x35\\x15\\x5e\\xb2\\xff\\xcf\\xef\\x32\\x23\\xde\\x14\\x68\\x19\\x77\\x02\\xa3\\xad\\x47\\xe0\\xfc\\x42\\x5b\\x73\\x64\\x67\\x04\\xf9\\x19\\x37\\xde\\x54\\xf4\\xd1\\x6f\\x79\\x66\\x6e\\xeb\\x35\\x0b\\x47\\x65\\x67\\x4d\\x4b\\xdd\\xd8\\xb7\\x1f\\xcd\\x83\\x97\\x7a\\x78\\x26\\xf3\\xa7\\x02\\x32\\x6d\\x3c\\x74\\x20\\x7f\\xc4\\xd9\\xac\\xcc\\x89\\xeb\\x9d\\x70\\x6d\\x44\\x30\\xcf\\xca\\xfc\\x3b\\xdd\\x24\\x1f\\x9d\\x20\\xb5\\x0c\\x6b\\x4b\\x62\\xee\\x66\\x78\\xce\\x7d\\xfb\\x98\\x4d\\xf0\\xc7\\x09\\xa6\\x3e\\xfc\\x22\\x54\\xe2\\xf0\\xcc\\x59\\x83\\x03\\x18\\x84\\xfb\\x72\\x7c\\xa1\\xb1\\xd6\\x99\\xa3\\xfb\\xb2\\x8a\\xad\\x20\\x90\\xe6\\xcb\\xc5\\xce\\x83\\xd5\\x26\\xf1\\xad\\xc9\\x89\\x99\\x48\\x4c\\x14\\xf9\\x9e\\x56\\x74\\xa9\\xb8\\xd0\\x0c\\x1e\\xd5\\x1d\\x68\\x7b\\x25\\xd4\\x7c\\xee\\x75\\x32\\x71\\xe0\\x13\\xa8\\x7e\\x49\\xf3\\xe3\\xb3\\x77\\x6f\\x5e\\xbe\\xf9\\x4b\\x1a\\x7d\\x36\\x14\\x78\\xfc\\x3e\\x47\\x9b\\xad\\x54\\xd1\\x15\\x8d\\x96\\x6b\\x56\\x95\\x11\\x5f\\x45\\x4c\\xc9\\xc8\\x42\\x8d\\xdc\\xa0\\x11\\x40\\x98\\xba\\x03\\xd1\\x87\\x45\\x26\\x30\\x50\\xa6\\x4e\\xeb\\x64\\xae\\x24\\x4d\\x20\\x73\\x85\\x97\\xa9\\x9e\\x86\\x74\\x32\\x25\\x10\\xae\\x48\\x71\\x5a\\x8e\\x5c\\xe9\\xc6\\xe0\\xe3\\x15\\x73\\x15\\x57\\xf1\\x57\\xfc\\xd6\\xdf\\x64\\xc0\\x6b\\x3d\\x24\\x14\\xbb\\x6b\\xdd\\x70\\xe5\\x3f\\x64\\x71\\xba\\xb8\\x25\\xaf\\x60\\x8d\\xb2\\x2a\\x9f\\x97\\xd9\\x75\\x3e\\xd9\\x3e\\x95\\xd9\\x26\\x1f\\x92\\xa3\\x4d\\x3e\\x21\\xba\\x6f\\x02\\xed\\x40\\x84\\x70\\x99\\x6d\\xf2\\xf1\\xf6\\x3b\\x99\\x5d\\x3f\\x30\\x63\\x4c\\xec\\x90\\x89\\x1e\\x32\\x60\\x26\\x96\\x27\\x93\\xac\\xcf\\xb8\\xb2\\xf3\\xca\\xac\\xca\\xcf\\xbe\\x99\\x6c\\xcf\\xbe\\xc1\\xb7\\x44\\x0d\\xf8\\x20\\x7c\\x1f\\xde\\x63\\xbc\\xed\\xbe\\xde\\x59\\x99\\xaf\\x8d\\xf0\\xf9\\x51\\xb7\\xff\\x28\\x69\\xd5\\xfb\\x28\\x09\\xdf\\x90\\xab\\xc9\\x10\\xbd\\xf7\\x93\\x73\\xaf\\x96\\x37\\xe4\\x27\\xf8\\x2b\\x94\\x59\\x95\\x4f\\xb6\\xf8\\x06\\xe1\\xa9\\xa6\\xc6\\x48\\x4e\\x7b\\xec\\x1a\\x90\\x67\\x3a\\x08\\x64\\x3a\\xc3\\x69\\x28\\x64\\x78\\x83\\x4d\\x45\\x4f\\x68\\xf3\\x06\\x6f\\xac\\xad\\x66\\x78\\x8d\\x01\\x40\\x98\\x69\\xbd\\xc4\\xd4\\xdb\\xbb\\xec\\x6e\\x62\\xa6\\xe7\\xc0\\x5e\\x95\\xf2\\xaa\\xfa\\x7f\\xbf\\xe2\\xbe\\xd9\\x0a\\x7e\\x79\\x40\\x47\\xcd\\xf9\\x45\\xa8\\x94\\x6c\\x05\\x69\\xe2\\xee\\x61\\xc5\\x71\\x78\\x79\\x8a\\x90\\x81\\x3b\\x4a\\x7d\\x6d\\xe6\\xff\\x89\\x43\\x1f\\x08\\x2b\\x90\\xb9\\xda\\xf3\\x90\\xf6\\xd4\\xe4\\x0e\\x32\\x84\\x1f\\x54\\xb0\\x59\\xbe\\xdf\\x03\\x80\\x1b\\x92\\xe5\\xfe\\x4c\\x4a\\x25\\x57\\x74\\x5d\\xdc\\x30\\x2e\\xec\\xe1\\x54\\x54\\xd1\\xc4\\x94\\x0e\\x1a\\x92\\x31\\x5c\\xe7\\xc1\\x21\\x95\\xee\\xea\\x8a\\x05\\x0d\\xf9\\x27\\x64\\xe8\\xb8\\xfb\\xb8\\xa4\\x60\\x46\\xe1\\xd1\\xd4\\x0f\\xf4\\x67\\x5b\\x0d\\xe9\\x16\\x9e\\x77\\xb7\\xd3\\x4f\\xfc\\xae\\xc4\\xa5\\xd9\\x25\\x36\\x22\\x44\\xee\\xf7\\x8d\\x2b\\x2c\\x10\\x42\\xca\\xf1\\x2c\\xd8\\x9b\\xaf\\x32\\xc5\\xec\\x42\\x71\\x1a\\xfe\\x54\\x64\\xe8\\x82\\xd8\\x8a\\xfc\\x8c\\x37\\xa4\\x2d\\x8d\\xb3\\x38\\x5e\\xc1\\xc2\\xde\\x0a\\x47\\xdf\\xad\\xa0\\xbd\\x5d\\x8f\\xf6\\xfb\\x2e\\xba\\x70\\x43\\x4c\\xfb\\x53\\x3d\\xc2\\x0e\\xde\\xef\\x7d\\x49\\xdc\\x0d\\xb0\\xa6\\xc4\\x02\\x51\\xbc\\xd1\\x03\\xba\\x72\\xb8\\x1b\\xa3\\xdb\\x0d\\x0c\\x37\\x18\\xaf\\x49\\x08\\xdb\\x7e\\xeb\\x81\\xf0\\x92\\xf4\\x90\\x72\\xdf\\x69\\x21\\x7c\\x4d\\x02\\x20\\xe6\\x8b\\x11\\x84\\xb7\\xa4\\xbf\\x38\\x6f\\x61\\x5f\\xf5\\xc8\\x5c\\x1f\\xd1\\xb4\\xec\\x11\\x70\\x7d\\x8c\\xed\\x16\\xdf\\x7e\\xc5\\xbf\\x33\\x6d\\x6f\\x46\\x23\\x65\\x34\\xe7\\xef\\x85\\x60\\xa6\\x5e\\x23\\xe3\\x18\\xde\\xda\\xef\\xae\\xdd\\x97\\x1e\\x66\\x69\\xdd\\xe4\\xce\\x98\\x85\\x59\\x7b\\x74\\x3c\\xe8\\xda\\xb5\\x75\\xa3\\xb6\\x68\\x0e\\x37\\xfb\\xfd\\xd5\\x7e\\x7f\\x6f\\x5d\\xb9\\x53\\x51\\x32\\x9a\\x62\\xd3\\x61\\xaf\\x20\\x34\\x59\\x39\\x9e\\xe5\\x08\\xdf\\xc7\\x31\\x14\\xe4\\xaf\\x50\\xa0\\xfe\\x05\\x48\\x36\\x86\\xc2\\xdc\\x3a\\x17\\x29\\x00\\x03\\x56\\xd7\\x7d\\x11\\x78\\x2c\\x3e\\xef\\x07\\xb5\\xfa\\xf1\\x1b\\x87\\xc8\\xdc\\x26\\x1c\\xb4\\x3a\\x14\\xdb\\x8a\\x9d\\x0d\\x10\\x0f\\xd8\\xab\\x88\\x2f\\xe4\\x3d\\x1a\\xf4\\xb5\\x5f\\xce\\x1c\\xb0\\x31\\x5e\\xde\\x08\\xfe\\x4f\\x68\\x04\\x67\\xff\\x59\\xc2\\xd8\\x79\\xe5\\x9a\\x30\\x4f\\xa8\\x20\\xac\\x97\\x1f\\x3e\\xee\\x95\\x39\\x32\\x79\\x23\\xe9\\x84\\xe5\\xe4\\xd6\\x48\\x70\\x49\\xbb\\xe7\\x85\\x73\\x22\\x32\\x9e\\x4f\\xa0\\x5c\\x98\\x9e\\xa3\\x28\\x30\\x4f\\xa7\\xfd\\xbd\\xbc\\x83\\x03\\xd7\\x3a\\xc9\\x52\\x87\\x42\\x3a\\x98\\x5b\\xb3\\x92\\x7a\\xde\\xfc\\xbf\\x47\\xa3\\xe0\\xc7\\x62\\x38\\x0d\\x05\\x60\\x70\\x94\\x37\\x1e\\x47\\x71\\x6a\\xd0\\xbc\\x70\\x72\\x39\\x0c\\xf5\\xb4\\xfe\\x75\\xb2\\x80\\xbd\\x2c\\x57\\x6c\\xe8\\x01\\x05\\xee\\x41\\x7b\\x27\\xff\\xdd\\xc9\\x53\\xa3\\xf3\\xfb\\xbd\\xfd\\xe2\\xe4\\x3b\\x67\\x17\\xf4\\xbb\\xe2\\xcd\\x77\\x5e\\xf3\\xf5\\xbb\\xe9\\x78\\xea\\xec\\x89\\xa1\\x76\\x6a\\xc0\\x6b\\xda\\x3a\\x3a\\xec\\xbb\\x39\\x62\\x4d\\xba\\x5b\\xc9\\x19\\xb8\\x9b\\xf0\\xad\\x9a\\xf0\\xd5\\xa4\\x43\\x03\\xe4\\x04\\x00\\x13\\x62\\x1a\\x68\\xb3\\x47\\xa0\\xcd\\x7e\\x17\\xb4\\xd1\\x2c\\x4c\\xe8\\x97\\xf6\\x3b\\x0e\\x73\\x5b\\xb3\\xdd\\xc1\\x6f\\x7f\\x5f\\x86\\x7e\\x67\\x12\\x97\\x7b\\x5c\\x9f\\xfa\\x80\\xe6\\xdf\\xd8\\x8e\\xe0\\xba\\x68\\xb8\\x13\\xd7\\xcd\\xf6\\xd9\\x72\\x49\\x2b\\x2a\\x8c\\x7d\\x9b\\xb7\\x75\\xef\\xe6\\xf8\\x5a\\x40\\x17\\x43\\x1f\\xcd\\xf9\\x1c\\xd9\\x7a\\x60\\xb4\\xe1\\x37\\xb4\\x8c\\x14\\x8f\\x3e\\x87\\xf4\\x7e\\xee\\x2e\\xf7\\x14\\x75\\x19\\xdd\\xb2\\xaa\\x8a\\x6a\\xae\\xec\\xbd\\x9e\\x46\\xeb\\x3d\\x2d\\x23\\x56\\x47\\xab\\xad\\xda\\x0a\\x1a\\xdd\\xd8\\x43\\x34\\xa9\\x83\\x71\\x5b\\xd6\\x4a\\x7e\\x93\\xfe\\xe2\\xbc\\xc4\\x25\\x2e\\xba\\xab\\xfd\\xcd\\x42\\x1d\\x13\\x90\\x36\\xb8\\x22\\x43\\x15\\x0c\\xbc\\x22\\xd7\\xb0\\x42\\x78\\x43\\x76\\xfe\\x4e\\x6b\\x5a\\xb7\\xd7\\x5b\\x0f\\x78\\xed\\x3e\\x51\\xf9\\x19\\xd6\\xce\\x4d\\x29\\xde\\x98\\x37\\xe3\\x87\\xdc\\x47\\x2a\\xfa\\xdd\\x3b\\x20\\xfb\\x11\\x8b\\x6e\\xb1\\xfe\\xeb\\x80\\x97\\x24\\xf0\\x32\\xdc\\x7f\\x01\\xe2\\x33\\xc3\\x6d\\x50\\x2d\\x60\\xad\\x99\\x70\\x91\\xf9\\x15\\xe9\\x5f\\x99\\xd5\\x7a\\x51\\x06\\xe0\\x96\\x8b\\x89\\xff\\xfa\\x6e\\xec\\x3f\\x3f\\x4d\\xcd\\x27\\xa9\\x58\\x76\\x70\\xb7\\x7a\\x94\\xb1\\x32\\x63\\xf7\\x25\\x6a\\x6a\\xbf\\x4e\\xc5\\x45\\x1c\\x5f\\xa1\\x4d\\x76\\x95\\x13\\xbb\\x4a\\x55\\x28\\xfa\\xe7\\x12\\x82\\xb1\\x1c\\x83\\xe6\\x0e\\x47\\x60\\x5c\\xda\\x87\\x29\\x02\\x78\\x93\\x2d\\x73\\x32\\xc5\\x9b\\x6c\\x6b\\x7e\\x12\\xbd\\x67\\xcf\\xd7\\x45\\x7d\\x4d\\x49\\x80\\x63\\xf7\\x71\\xe3\\x6d\\x1f\\xd1\\x59\\x3a\\xc3\\xf7\\x3d\\xa4\\x66\\xe9\\x6c\\x6e\\x80\\x96\\x4f\\x6e\\x2d\\x58\\xf9\\xe4\\xbe\\x0f\\x78\\x39\\x06\\x1a\\x8b\\xad\\x39\\x58\\x3e\\x27\\xbb\\xff\\x0a\\xee\\x2c\\xff\\x57\\x1a\\x58\\xc9\\xe0\\xab\\xa0\\x4e\\x0d\\x9d\\x9b\\x3b\\xef\\xe9\\x66\\x7b\\x73\\xcf\\x77\\x6f\\xda\\x86\\x36\\xa0\\x7f\\x1f\\xf6\\x1f\\xc5\\xf4\\xfd\\x31\\xc6\\xaf\\x1d\\x4b\\xdb\\x68\\x8a\\xef\\xba\\x1d\\xbe\\xf7\\xdb\\x79\\xc0\\x9d\\xba\\x79\\x7d\\xff\\xff\\x8f\\x5a\\x6c\\x47\\xd3\\x2f\\x83\\x6e\\xd9\\xe3\\xfc\\xdb\\x60\\x6f\\x9f\\xe0\\x30\\x4d\\x89\\xe3\\xf0\\xfc\\xa2\\x4f\\x4d\\x7b\\xd2\\xf5\\x0b\\xec\\x4f\\x1a\\xa0\\xda\\x9e\\x1d\\xa4\\xfd\\xb3\\xd6\\xf0\\x23\\xc9\\x0b\\x58\\x63\\x85\\x29\\xc2\\x0d\\xb9\\x81\\x3c\\xbc\\xfc\\xa1\\x9b\\x31\\xff\\xfa\\x17\\x15\\x27\\x43\\xfc\\x67\\x14\\xed\\xa5\\xb8\\xfe\\xb5\\xc8\\xde\\x95\\x76\\xdc\\x20\\xfc\\x0b\\x54\\xb8\\xd3\\xec\\xee\\x0b\\x08\\xf3\\xa9\\xcb\\xc9\\xbe\\x59\\x13\\x72\\x38\\x1c\\xf0\\x8a\\x1e\\xd0\\xfc\\x0f\\x67\\x67\\xff\\x1d\\xd9\\xff\\x65\\xea\\x75\\xd1\\x34\\xac\\xbe\\xfe\\xf0\\xee\\x15\\x71\\xd5\\x85\\x0d\\xab\\x93\\xdf\\x64\\xb2\\x29\\x9a\\x3f\\xfc\\x6f\\x00\\x00\\x00\\xff\\xff\\x10\\xa0\\xcc\\x28\\xf4\\x4a\\x00\\x00\")\n\nfunc cmdInternalPagesAssetsJsPopperMinJsBytes() ([]byte, error) {\n\treturn bindataRead(\n\t\t_cmdInternalPagesAssetsJsPopperMinJs,\n\t\t\"cmd/internal/pages/assets/js/popper.min.js\",\n\t)\n}\n\nfunc cmdInternalPagesAssetsJsPopperMinJs() (*asset, error) {\n\tbytes, err := cmdInternalPagesAssetsJsPopperMinJsBytes()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tinfo := bindataFileInfo{name: \"cmd/internal/pages/assets/js/popper.min.js\", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)}\n\ta := &asset{bytes: bytes, info: info, digest: [32]uint8{0xa5, 0x2f, 0x7a, 0xa5, 0x4d, 0x7b, 0xca, 0xaf, 0xa0, 0x56, 0xee, 0xa, 0x5, 0x2, 0x62, 0xdf, 0xc5, 0x69, 0x4a, 0xe2, 0x8d, 0xee, 0x8b, 0x4c, 0xac, 0x34, 0x29, 0xaf, 0x37, 0xff, 0xd, 0x66}}\n\treturn a, nil\n}\n\nvar _cmdInternalPagesAssetsStylesBootstrap400Beta2MinCss = []byte(\"\\x1f\\x8b\\x08\\x00\\x00\\x00\\x00\\x00\\x00\\xff\\xec\\xbd\\x6b\\x8f\\xe3\\x38\\x92\\x28\\xfa\\xfd\\xfc\\x0a\\x6d\\x16\\x0a\\x5d\\x39\\x6d\\xb9\\x24\\xf9\\x99\\x4e\\x54\\x63\\x66\\x1a\\xb3\\x38\\x03\\x4c\\xef\\x87\\x9d\\xb3\\xc0\\x05\\xfa\\xd4\\x05\\xf4\\xa0\\x6d\\x4d\\x49\\x96\\xae\\x24\\x57\\x2a\\xc7\\xf0\\xfe\\xf6\\x0b\\xbe\\x24\\x3e\\x82\\x94\\xe4\\x74\\x76\\xcf\\x01\\xce\\xd6\\x4e\\xa7\\x4c\\x05\\x23\\x82\\x8c\\x60\\x44\\x90\\x22\\x83\\x9f\\xff\\xf0\\x6f\\xff\\xc3\\xf9\\x83\\xf3\\xe7\\xa2\\x68\\xea\\xa6\\x0a\\x4b\\xe7\\xfb\\x72\\xee\\xcd\\x3d\\x37\\x42\\x4d\\x38\\x0f\\x9c\\x4f\\xc7\\xa6\\x29\\xeb\\xdd\\xe7\\xcf\\x07\\xd4\\x44\\x1c\\x66\\x1e\\x17\\xf9\\x23\\xae\\xf5\\x73\\x51\\xbe\\x56\\xe9\\xe1\\xd8\\x38\\x81\\xe7\\xfb\\x6e\\xe0\\xf9\\x1b\\xe7\\x7f\\x1d\\x91\\x80\\xed\\x4f\\xe7\\xe6\\x58\\x54\\xb5\\x11\\xf8\\x25\\x6d\\x1a\\x54\\xcd\\x9c\\xbf\\x9e\\xe2\\x39\\x06\\xfa\\x5b\\x1a\\xa3\\x53\\x8d\\x12\\xe7\\x7c\\x4a\\x50\\xe5\\xfc\\xf2\\xd7\\xff\\x25\\xb0\\x90\\x36\\xc7\\x73\\x84\\x89\\x7f\\x6e\\x5e\\xa2\\xfa\\x73\\xc7\\xcf\\xe7\\x28\\x2b\\xa2\\xcf\\x79\\x58\\x37\\xa8\\xfa\\xfc\\xb7\\xbf\\xfe\\xfc\\x97\\xff\\xf8\\xfb\\x5f\\x30\\x7f\\x9f\\x77\\x55\\x51\\x34\\x17\\xd7\\x8d\\xb2\\x33\\xda\\x7d\\xf0\\xbc\\x4d\\xb4\\xdf\\x3f\\xbb\\x6e\\x7a\\x4a\\xd2\\x43\\xb1\\xfb\\xb0\\x5e\\xfb\\xde\\x3e\\x78\\x76\\xdd\\xf2\\x5c\\x95\\x19\\xda\\x7d\\x58\\xef\\x97\\x41\\xec\\xe3\\x82\\xf4\\xf4\\x6d\\xf7\\x01\\x6d\\x17\\x68\\x1b\\x3f\\xbb\\x6e\\x85\\x92\\xdd\\x87\\x24\\x5e\\xac\\x96\\xab\\x67\\xd7\\x2d\\xaa\\xf0\\x74\\x40\\xbb\\x0f\\xfb\\x64\\x83\\xfc\\xe5\\xb3\\xeb\\xbe\\xa2\\x2c\\x2b\\x5e\\x76\\x1f\\xf6\\xfb\\xd8\\xf7\\x36\\xcf\\xae\\x7b\\xa8\\x10\\x3a\\xed\\x3e\\x04\\xdb\\x70\\x43\\x6a\\x34\\x28\\xcc\\x76\\x1f\\x02\\x2f\\x7e\\x7a\\xc2\\xaf\\xe3\\xd7\\xf0\\xb4\\xfb\\xe0\\x6f\\xc2\\x20\\xda\\x3e\\xbb\\xee\\xcb\\x31\\x6d\\x30\\x3a\\xc2\\xdb\\xa1\\x0a\\x5f\\x77\\x1f\\xb6\\xeb\\x2d\\x7a\\x5a\\xb3\\x9f\\x6e\\x12\\x56\\xdf\\x76\\x1f\\x16\\xcb\\x45\\xb8\\xf4\\x30\\x73\\x55\\x9a\\x87\\xd5\\xab\\xd0\\xa0\\x1a\\xc5\\xc5\\x29\\x21\\x65\\x5d\\xcd\\xfa\\x1c\\xc7\\xa8\\xae\\x05\\x2e\\xd2\\xd3\\xbe\\x10\\xc9\\x86\\xd5\\x29\\x3d\\x1d\\x04\\xb6\\x13\\xdc\\xae\\x4a\\x68\\x69\\x86\\xc5\\xb5\\xfb\\xb0\\xdf\\xee\\x9f\\xf6\\x21\\x01\\x90\\x18\\x89\\x2a\\x14\\x7e\\x2b\\x8b\\xf4\\xd4\\xb8\\x6d\\xbd\\x53\\x4a\\xea\\x7c\\xb7\\xda\\xac\\xcb\\x56\\x2e\\xcd\\x93\\xdd\\x66\\xbd\\x55\\x4b\\xb3\\xc3\\xee\\xe9\\x29\\x50\\x4b\\xdb\\x6c\\xe7\\x07\\x9e\\x47\\x8a\\xf7\\xc5\\xa9\\x71\\xf7\\x61\\x9e\\x66\\xaf\\x6e\\x1d\\x9e\\x6a\\xb7\\x46\\x55\\xba\\xdf\\xb9\\x61\\x59\\x66\\xc8\\xad\\x5f\\xeb\\x06\\xe5\\xb3\\x3f\\x67\\xe9\\xe9\\xdb\\x2f\\x61\\xfc\\x77\\xf2\\xf3\\xdf\\x8b\\x53\\x33\\x7b\\xf8\\x3b\\x3a\\x14\\xc8\\xf9\\xaf\\xbf\\x3e\\xcc\\xfe\\xb3\\x88\\x8a\\xa6\\x98\\x3d\\xfc\\x4f\\x94\\x7d\\x47\\x4d\\x1a\\x87\\xce\\x7f\\xa0\\x33\\x7a\\x98\\xfd\\xa9\\x4a\\xc3\\x6c\\xd6\\x23\\x9d\\x3d\\xfc\\x09\\x23\\x75\\x7e\\x2e\\xb2\\xa2\\x72\\xfe\\x92\\x17\\xff\\x48\\x1f\\x7a\\x3c\\x7a\\xc1\\xdf\\x5f\\xf3\\xa8\\xc8\\x1e\\x14\\x26\\xf3\\xe2\\x54\\xd4\\x65\\x18\\xa3\\xdd\\xc3\\xdf\\xff\\xfd\\x97\\xe2\\x54\\xb8\\xff\\x89\\x0e\\xe7\\x2c\\xac\\x1e\\x66\\xbf\\xa0\\x53\\x56\\xcc\\x7e\\x29\\x4e\\x61\\x5c\\xcc\\x7e\\x2e\\x4e\\x75\\x91\\x85\\xf5\\xec\\xe1\\x6f\\x69\\x84\\xaa\\xb0\\x49\\x8b\\x93\\x83\\xe1\\x1f\\x66\\x0f\\x3f\\x17\\xe7\\x2a\\x45\\x95\\xf3\\x1f\\xe8\\xe5\\x61\\xd6\\x21\\xbc\\xfe\\x31\\x47\\x49\\x1a\\x3a\\x65\\x95\\x9e\\x9a\\xcb\\x1f\\x66\\xbb\\x5d\\xb8\\xc7\\x63\\x68\\xb7\\x8b\\xd0\\xbe\\xa8\\xd0\\xa5\\x41\\x6d\\xe3\\xd6\\xc7\\x30\\x29\\x5e\\x76\\xa7\\xe2\\x84\\xfe\\x2d\\xcd\\xcb\\xa2\\x6a\\xc2\\x53\\xf3\\x1c\\x15\\x2d\\xfc\\xe6\\x1a\\xce\\xc2\\xdd\\xf7\\xb4\\x4e\\x1b\\x94\\x50\\x04\\x09\\x8a\\x0b\\xca\\xce\\x8e\\x8c\\xc5\\x2c\\x3d\\xa1\\x6b\\x18\\x45\\xd5\\xaf\\x4d\\xda\\x64\\xe8\\x2b\\x23\\x7b\\x89\\x8b\\x53\\x83\\x4e\\xcd\\xee\\xc1\\xf9\\xf4\\xe0\\x84\\x4d\\x53\\x7d\\x22\\xef\\x1f\\x9d\\x87\\xc7\\x87\\x6b\\x59\\xa1\\x0b\\x51\\x6f\\x97\\xf6\\x45\\x59\\x21\\xf7\\xa5\\x0a\\x4b\\x81\\x70\\x94\\x15\\xf1\\xb7\\xff\\xef\\x5c\\x34\\x68\\x86\\xa1\\xa3\\xa2\\x4a\\x50\\xb5\\xf3\\xcb\\xd6\\xa9\\x8b\\x2c\\x4d\\x9c\\x0f\\x4f\\x4f\\x4f\\xcf\\x65\\x78\\x40\\x54\\x35\\xdc\\xf4\\x54\\xa7\\x09\\xda\\x85\\xdf\\x8b\\x34\\xb9\\x36\\x47\\x14\\x26\\x97\\x24\\xad\\xcb\\x2c\\x7c\\xdd\\x35\\x61\\x94\\x21\\x17\\x17\\xa1\\xca\\x3d\\x54\\xc5\\xb9\\xbc\\xa6\\xf9\\x61\\xd6\\x54\\x17\\x53\\xfd\\x63\\x30\\x3b\\x2e\\x66\\xe5\\xa5\\xa8\\xca\\x63\\x78\\xaa\\x77\\x8b\\xe7\\x97\\x34\\x29\\x5e\\xea\\xdd\\x82\\xbe\\x12\\x2b\\x92\\xe6\\xb2\\x7a\\xf3\\x53\\xf8\\x3d\\x0a\\xab\\x8e\\x32\\xee\\xcc\\xeb\\x3c\\x0a\\x93\\x03\\xd4\\x02\\xcf\\xf3\\xae\\x73\\xc2\\x1c\\x7b\\xe9\\xc6\\x45\\x96\\x85\\x65\\x8d\\x76\\xfc\\x41\\xe8\\x10\\x0a\\xe9\\x34\\xc9\\x8c\\x3f\\x1d\\x2f\\x51\\x18\\x7f\\xc3\\x0d\\x3a\\x25\\xb8\\x6a\\x51\\x11\\x6b\\xa1\\xd5\\x71\\x29\\x76\\x94\\xf4\\x95\\x85\\xa2\\x23\\xc0\\x59\\x92\\x24\\x02\\x96\\x2b\\xa0\\x4c\\x44\\x63\\xd2\\x7f\\x62\\x43\\xc1\\x78\\x8f\\x8a\\xf6\\x7a\\x6c\\xf2\\xec\\x22\\xa8\\xfb\\xae\\x1f\\x3e\\xcf\\x58\\x51\\xdc\\x23\\x22\\xa6\\xc3\\x9f\\xfb\\xab\\x67\\xf7\\x05\\x45\\xdf\\xd2\\xc6\\xa5\\x7a\\x99\\xfe\\x13\\xb9\\x61\\xf2\\x8f\\x73\\xdd\\xec\\x7c\\xcf\\xfb\\xf8\\xec\\xe6\\xb5\\xe5\\x4d\\xf1\\x1d\\x55\\xfb\\xac\\x78\\x71\\xeb\\xe6\\x35\\x43\\xbb\\x3a\\xae\\x8a\\x2c\\x8b\\xc2\\xaa\\x47\\x1a\\x96\\xee\\x31\\x3d\\x1c\\x89\\xa9\\x62\\x9d\\xd3\\x54\\xe1\\xa9\\x2e\\xc3\\x0a\\x9d\\x9a\\xeb\\x1f\\x31\\x96\\xef\\x29\\x7a\\xc1\\x8d\\xbc\\xbc\\xa4\\x49\\x73\\xdc\\x25\\xe8\\x7b\\x1a\\x23\\x97\\xfc\\xb8\\x86\\x55\\x93\\xc6\\x19\\x9a\\x85\\x58\\x2d\\x66\\x49\\x1a\\x66\\xc5\\x61\\xb6\\x4f\\x0f\\x71\\x58\\x62\\xe5\\xc7\\x8f\\xe7\\x0a\\xcd\\xf6\\x45\\x81\\xfb\\x85\\x2a\\xd7\\xec\\x48\\xb4\\x6b\\x96\\x87\\xe9\\x69\\x76\\x0a\\xbf\\xcf\\x6a\\x14\\x63\\xe0\\x4e\\x1f\\x88\\x52\\x5f\\xa3\\x22\\x79\\xbd\\xe4\\x61\\x75\\x48\\x4f\\x3b\\xef\\x59\\xec\\xae\\x7f\\x25\\xbb\\x45\\xf8\\xc2\\x9d\\xbf\\xf3\\x2b\\x94\\xd3\\x9f\\x2f\\x54\\x7c\\x4b\\xcf\\x53\\xc4\\xb9\\x7a\\x66\\xfa\\x17\\xf8\\xc1\\x2a\\x78\\x7a\\x26\\x92\\x0b\\xb3\\xf4\\x70\\xda\\x65\\x68\\xdf\\x3c\\x83\\x8a\\x7a\\xfd\\xb5\\x09\\xa3\\xf4\\x94\\xa0\\xf6\\xcb\\x83\\xeb\\x3f\\x7c\\xdd\\xed\\x8b\\xf8\\x5c\\x5f\\x8a\\x73\\x83\\x91\\xef\\x3c\\x41\\x05\\x8f\\x95\\xa8\\x71\\xcc\\xb6\\x60\\x95\\x7b\\x66\\x2c\\x78\\xcf\\x5c\\x25\\x88\\xb9\\x8a\\x32\\x74\\x3d\\xfa\\x33\\x3a\\x8e\\x8f\\xcb\\xd9\\x71\\x35\\x3b\\xae\\x59\\x9f\\xbb\\x4d\\x51\\xee\\xbc\\x67\\xf6\\x23\\x2a\\x9a\\xa6\\xc8\\x77\\xf3\\x55\\x85\\xf2\\x6b\\x69\\x03\\xc1\\xdd\\x40\\x2d\\x5d\\x12\\x36\\xa1\\x5b\\x54\\xe9\\x21\\x3d\\x85\\x99\\x4b\\xed\\xde\\x4c\\xb0\\x81\\x66\\x4b\\x29\\x2b\\x3d\\x04\\xe1\\x24\\x45\\xd3\\xa0\\xe4\\x79\\x10\\x20\\x3e\\x57\\x75\\x51\\xed\\x8e\\x28\\x2b\\x9f\\xbb\\x21\\x48\\x18\\xf5\\xae\\x61\\x92\\x54\\xa8\\xae\\x2f\\x7a\\x03\\x98\\x58\\xc9\\xa8\\x39\\x15\\x55\\x1e\\x66\\x92\\x24\\xd3\\xd3\\x11\\x55\\x69\\x73\\x4d\\xb2\\x59\\x91\\xcd\\xce\\xd9\\x60\\x7f\\x14\\x99\\x53\\x60\\x58\\xe7\\x8c\\xc1\\x1d\\x52\\xc9\\xe9\\xeb\\x75\\x1c\\x25\\xcd\\x45\\xd4\\xa0\\x8d\\xe7\\x5d\\x93\\xe4\\x02\\xc8\\x80\\x13\\xc1\\x6a\\xb3\\xf3\\x04\\x37\\xd0\\x8d\\x18\\xc7\\x73\\x08\\xe9\\x64\\x7f\\xba\\x08\\xad\\x49\\x9b\\x30\\x4b\\xe3\\x6b\\x34\\xab\\x9b\\xaa\\x38\\x1d\\x24\\x72\\x51\\x91\\x25\\xa8\\xba\\xd6\\x79\\x98\\x31\\xfb\\x44\\x14\\x7b\\xeb\\x7d\\xbc\\xd6\\xe7\\x68\\x56\\x9f\\xcb\\x4b\\x59\\xd4\\x29\\xe9\\xe8\\x0a\\x65\\x61\\x93\\x7e\\x47\\xc2\\x00\\xd8\\xac\\x3e\\x4a\\xbd\\xe4\\x3d\\x7f\\x47\\xd8\\x3c\\x84\\x19\\xd3\\xf1\\x28\\xac\\x11\\x71\\x84\\xf5\\x39\\xba\\xb0\\xd6\\xb8\\xf3\\x60\\x85\\xf2\\x2b\\xc6\\x8d\\x7b\\xcf\\x9d\\xe3\\x5f\\xe1\\x85\\xa9\\x3f\\x8b\\xd1\\x54\\x29\\x63\\x87\\xa1\\x0f\\x16\\xc1\\x70\\x99\\x14\\xc8\\xad\\xbf\\xa5\\xe5\\xae\\x88\\xfe\\x81\\xe2\\xa6\\xbe\\x86\\xbb\\x23\\x1e\\x0e\\x3d\\xb1\\xd5\\x3a\\x5a\\x98\\x55\\xea\\x1a\\xee\\x4e\\x45\\xf3\\xe9\\xd7\\x63\\x85\\xf6\\x5f\\x1f\\xe9\\x33\\x1f\\x9a\\x5f\\x1f\\x19\\x16\\xa6\\x1a\\x20\\xcb\\x76\\x04\\x74\\x5c\\xcf\\xec\\x30\\x22\\xc3\\x6f\\x25\\xd5\\x9b\\x90\\x6b\\x5c\\x24\\x68\\xf6\\x2d\\x4a\\x70\\x10\\x31\\xab\\xc3\\xbc\\x94\\xdc\\x53\\x17\\x3c\\xf5\\x61\\x94\\x68\\xf7\\xb0\\x45\\xa8\\xd0\\xd0\\x18\\xe8\\x2d\\x4f\\x78\\x6e\\x0a\\xab\\x7b\\xba\\x52\\xaf\\xa1\\xa9\\x72\\x9a\\x1f\\x2e\\x8a\\x4a\\xe5\\x69\\x92\\x64\\x88\\x8f\\x6c\\x3e\\x60\\xb1\\x8a\\x7d\\x3f\\x90\\x56\\x93\\x49\\xcc\\xe3\\xa5\\x23\\x7e\\x4c\\x93\\x04\\x9d\\xae\\xbf\\x56\\x45\\x86\\xbe\\x44\\xe7\\xa6\\x29\\x4e\\x5f\\x67\\xe1\\x2c\\xac\\x50\\x38\\xa3\\x3f\\x67\\xe9\\xa9\\x3c\\x37\\xac\\xcb\\x5e\\x4b\\xf4\\x85\\x4c\\x58\\xbe\\x3e\\xce\\xb2\\x30\\x42\\xd9\\xac\\x46\\x19\\x8a\\x9b\\x59\\x7d\\xce\\xf1\\x34\\x62\\x86\\x3b\\x1f\\x57\\xbe\\x10\\x4f\\x5c\\x9c\\xe3\\xa3\\x1b\\x12\\x6f\\xb6\\xcb\\xc3\\x53\\x5a\\x9e\\x33\\x22\\x93\\x67\\xe3\\x9b\\xab\\x3d\\xb2\\xb9\\x32\\x47\\x7a\\x29\\xc3\\x24\\x49\\x4f\\x07\\xd2\\xbd\\xf3\\x0d\\x31\\x01\\xbc\\x88\\xdb\\x05\\x5a\\xca\\x94\\x99\\xcd\\x64\\x54\\x0f\\xc3\\xd0\\xb9\\x24\\x8a\\xa3\\x15\\xaf\\xcd\\xf1\\x22\\x80\\x71\\xdb\\x46\\x5a\\xdb\\xb9\\xe4\\xf4\\x44\\x46\\x36\\xb1\\x33\\xa0\\x4f\\xa0\\x7d\\xc7\\xdb\\x51\\x85\\x49\\x7a\\xae\\xb1\\x61\\x22\\xc5\\x8a\\xbe\\xe1\\x10\\x8a\\x99\\x67\\x5e\\xb4\\x2a\\x5b\\x07\\xeb\\x85\\xc3\\x07\\x2e\\xa9\\xe1\\x56\\xb8\\x7d\\xa4\\x45\\x57\\x51\\x38\\xb3\\xa2\\x6c\\x68\\x0c\\xc1\\xa4\\xd1\\x49\\x01\\x8c\\x17\\xf8\\x40\\xe9\\x75\\x96\\x97\\x40\\x46\\x5d\\x24\\x74\\xd1\\xdc\\x25\\x7b\\x4b\\xe9\\xd2\\x7e\\x23\\x76\\x67\\x5f\\x54\\x39\\xd5\\x3c\\xa6\\x34\\xa8\\x46\\xcd\\xd7\\x19\\xfd\\x51\\x9f\\xa3\\x3c\\x6d\\xbe\\x72\\x05\\xc3\\xf1\\x9f\\x43\\xdf\\x30\\x0d\\xbc\\xf0\\x66\\x87\\x65\\x89\\xc2\\x2a\\x3c\\xc5\\x68\\x47\\x5f\\x5d\\x25\\xb8\\xdd\\xce\\xcd\\x8b\\x7f\\xb2\\xce\\x49\\x4f\\x27\\x54\\xcd\\x44\\x72\\xc6\\xd7\\x8c\\x01\\xe0\\x3d\\x13\\x90\\xf6\\x82\\x2b\\xdc\\xce\\x03\\x06\\x17\\xe9\\x1b\\x8a\\x39\\x3e\\xa2\\xf8\\x5b\\x54\\xb4\\x5f\\x67\\x42\\x21\\x16\\x7f\\xf1\\x15\\x8e\\x7e\\x9f\\x3b\\xc4\\x22\\x9a\\x24\\x6c\\x90\\x84\\x02\\x17\\x34\\x69\\x8e\\xdc\\xac\\x88\\xc3\\x4c\\x7a\\x95\\x17\\xa7\\xe6\\x28\\x95\\x60\\x40\\xb0\\x0f\\xb3\\xb4\\x6e\\x70\\xc4\\xdd\\xe9\\x87\\x6c\\x84\\x2a\\x44\\xb4\\x81\\xdb\\x94\\xeb\\x3e\\x45\\x59\\x52\\xa3\\xe6\\x92\\xa7\\x27\\x1a\\xe0\\xee\\xbc\\x9e\\xdf\\xe7\\x4e\\xb9\\xd8\\x54\\xc0\\xbb\\x66\\xe8\\x80\\x4e\\x89\\x1c\\xb8\\x3e\\xd3\\x8a\\x24\\x08\\xcf\\xc3\\xd6\\x15\\x7e\\xaa\\xa8\\x64\\x97\\x2e\\x98\\x54\\x5a\\x00\\x68\\xe7\\xb3\\x6c\\xfa\\xc5\\xd9\\x21\\x8d\\x53\\xae\\x65\\x55\\x1c\\x48\\x54\\x63\\x72\\xbe\\xb4\\xcb\\x4e\\xe7\\x3c\\x42\\x15\\xd6\\x08\\xd6\\x6b\\x44\\xea\\x6e\\x5d\\x62\\xae\\xa8\\x9a\\x1a\\x00\\x8b\\x73\\x23\\x03\\x5e\\x18\\x8b\\xb8\\x4b\\x19\\xf6\\x1a\\x85\\x55\\x7c\\xfc\\xca\\x47\\xbc\\x5b\\xec\\xf7\\x35\\x6a\\x76\\x2e\\x59\\xa5\\xd0\\xc5\\x24\\x8c\\x1b\\x56\\xb3\\x27\\x47\\x0b\\xdc\\x18\\x03\\x66\\x32\\x6b\\x26\\xd8\\xde\\x17\\x42\\x3a\\x41\\x88\\xf5\\x75\\xf6\\x69\\x86\\xdc\\x73\\x99\\x15\\x61\\xc2\\xdb\\x83\\x05\\xd1\\x75\\xb1\\x79\\x64\\x16\\xe7\\x06\\x9b\\x08\\xc8\\x44\\x5e\\x99\\x7b\\xe8\\x5e\\x62\\x45\\x74\\xd3\\x06\\xe5\\xd7\\x06\\xe5\\x65\\x16\\x36\\x48\\x9e\\xfd\\xfe\\x4a\\xfd\\xd2\\x57\\xa9\\x54\\x9c\\xa2\\x1e\\xfd\\xd9\\xfc\\x18\\xcc\\xe6\\xc7\\xc5\\x6c\\x7e\\x5c\\xce\\xe6\\xc7\\xd5\\x6c\\x7e\\x5c\\xcf\\x8c\\xd1\\xbb\\xae\\x59\\x90\\x31\\x64\\x81\\xdf\\x4a\\x9b\\xa9\\x04\\xb2\\xa2\\x11\\xfa\\x47\\x5f\\x08\\x0a\\x03\\x6a\\xf6\\x31\\x4f\\xc7\\x40\\x2c\\xa7\\xa5\\x0b\\x3c\\xfd\\x17\\x15\\x7a\\xc3\\xc0\\x97\\xb3\\xe3\\xf2\\xa2\\x6a\\xfa\\x15\\x37\\xe7\\xb8\\x92\\xca\\x03\\xf6\\x62\\x8d\\x1b\\x25\\xcf\\xb2\\xae\\xf3\\x0c\\x85\\x89\\x0e\\x2d\\xb5\\x69\\xe1\\x79\\xd7\\x39\\xeb\\x4d\\x57\\xe4\\x7c\\x0d\\x40\\xaa\\xad\\xef\\x6b\\x8a\\x6d\\x5b\\xcd\\x21\\x2a\\xe6\\xba\\x62\\x0f\\x2c\\x27\\xd6\\x15\\x3b\\x69\\x31\\xae\\xee\\xb1\\x12\\x63\\x30\\x5f\\x98\\x25\\x88\\x61\\x18\\xb7\\x5d\\xdc\\xac\\x13\\xd8\\x6e\\x4d\\xa3\\x3a\\x44\\xe1\\x27\\x6f\\x86\\xff\\xcd\\xfd\\xc7\\xeb\\x9c\\xcc\\x05\\x66\\xc0\\x8c\\x40\\x9d\\xe9\\x5e\\xe7\\x79\\x58\\x7d\\x9b\\xe1\\xff\\x74\\xae\\x63\\x1e\\x60\\x7a\\xfa\\x9c\\x36\\xde\\x6f\\xd1\\xe2\\x3a\\x27\\x63\\xe2\\x7c\\x22\\x7e\\x25\\xe9\\x02\\x1c\\x3a\\xa3\\x79\\x26\\x2f\\x05\\x97\\x43\\xa1\\xe9\\x18\\x9b\\x02\\x4b\\x06\\x1d\\x3c\\x46\\x35\\x30\\x1a\\x30\\x66\\x61\\xdd\\xb8\\xf1\\x31\\xcd\\x92\\x47\\xde\\x9f\\x15\\x1d\\x25\\x65\\x7b\\x9d\\xa7\\xa7\\xb4\\x49\\xc3\\x2c\\xad\\x73\\xa1\\x3f\\x9e\\xbc\\x8f\\xcf\\x4a\\x28\\x70\\x2e\\x4b\\x54\\xc5\\x61\\x8d\\xae\\x73\\x6d\\x72\\x06\\xcc\\x34\\x25\\x9d\\xef\\x2b\\xb8\\x74\\xe1\\x44\\x71\\x30\\xb2\\x20\\xa4\\x80\\x0f\\xa8\\xdc\\x2d\\x46\\x75\\x6b\\x8d\\xff\\x3b\\xf0\\xfc\\xa5\\xf3\\xbf\\x3d\\xef\\x4f\\xde\\xc3\\x75\\x9e\\xe6\\x07\\x77\\x9f\\x9d\\x53\\x3c\\xcf\\x94\\xbc\\x95\\x68\\xd6\\x09\\x54\\x73\\x3c\\xe7\\xd1\\x29\\x4c\\x33\\x41\\xc2\\x44\\x33\\xc1\\x75\\x8b\\x67\\x70\\xc1\\xec\\x59\\x8e\\x10\\x19\\x02\\xd2\\x6f\\x74\\x62\\x19\\x66\\x99\\x33\\x0f\\x6a\\x07\\x85\\x35\\x72\\xd3\\x13\\x76\\x37\\xaa\\x1b\\x95\\x18\\x63\\x73\\x05\\x58\\xc2\\xf4\\xa5\\x8b\\x27\\x0e\\x90\\x5d\\x94\\x46\\x50\\x07\\xcd\\x43\\x6e\\x59\\xbe\\x72\\x37\\xdb\\x27\\x4c\\xf2\\x9a\\xf5\\x9b\\x97\\xac\\x31\\x31\\xa1\\xcb\\x2b\\x94\\x3b\\xf3\\xa5\\xac\\x3b\\x02\\x87\\x51\\xb2\\xf4\\x97\\x1b\\x48\\x26\\xf4\\x43\\x04\\x24\\x80\\x6b\\xf8\\x93\\x44\\xc4\\x53\\xe2\\x0c\\x0d\\x19\\xf7\\x0b\\xdf\\xa2\\x64\\x3c\\x67\\x44\\x29\\x34\\xb6\\xd8\\x5a\\x98\\xca\\x16\\xe6\\xea\\x5b\\x94\\x38\\x22\\x05\\x4f\\x1c\\x2d\\x9e\\x62\\x84\\x36\\x9e\\x47\\xe6\\xa1\\xf2\\x58\\x19\\x9a\\x95\\x82\\x8c\\x52\\x96\\x30\\x36\\x47\\xe9\\x16\\x7d\\x0a\\x31\\xd0\\x51\\xe2\\xa2\\x84\\x3a\\x39\\x9a\\x97\\x15\\x72\\xe9\\xac\\x97\\x4c\\x02\\xb1\\x9a\\x33\\x6d\\x5c\\x2c\\xbd\\xb2\\xed\\xa6\\xcc\\xee\\x2b\\x9b\\x1c\\x5f\\xe7\\x78\\x10\\x87\\x29\\x0e\\xd0\\xf5\\xb8\\x92\\xd9\\x29\\x7f\\x55\\x76\\x51\\x36\\x35\\x91\\xa4\\x44\\xb2\\x65\\x24\\xfc\\x15\\xd7\\x90\\xc8\\x60\\x62\\xdf\\x46\\x3e\\xf5\\xe1\\x2f\\xf9\\x08\\xf5\\x78\\x11\\xc8\\xf6\\x63\\x71\\x85\\x79\\xbc\\x02\\x95\\xc8\\x37\\x2a\\x43\\xa5\\x4d\\x60\\xa8\\x44\\x3e\\x61\\x19\\x2a\\x3d\\xad\\x0d\\x95\\xe8\\x17\\x2e\\x43\\x2d\\xdf\\xa7\\x0c\\xf6\\x2f\\x99\\x9d\\x7b\\x87\\x9e\\x9b\\x57\\xc5\\x4b\\xa7\\x79\\x6e\\x5e\\xbb\\xfb\\x0c\\xb5\\x78\\xb6\\xc3\\xcb\\xf0\\xef\\x67\\xfe\\x82\\x7c\\xc5\\xd9\\xe1\\xff\\x3c\\x2b\\x3f\\x25\\x52\\xae\\x48\\x9d\\xd0\\x22\\x25\\xd7\\xf9\\xa9\\x70\\x0f\\xe7\\xa6\\x41\\x55\\x2d\\x7b\\x28\\x4f\\x59\\x16\\x14\\x00\\x7f\\x9a\\xc7\\x45\\x36\\x13\\x0b\\x7e\\x8d\\xb3\\xb0\\xae\\xff\\xf0\\x25\\x2e\\x32\\xf7\\xeb\\x45\\xee\\x08\\x4f\\xee\\x05\\xef\\x4a\\x6b\\x63\\x50\\x9f\\xfd\\xf1\\xd8\\x5f\\xfe\\x3b\\xa0\\x7f\\xd9\\x9f\\x05\\xfd\\xb3\\xa4\\x7f\\x56\\xf4\\xcf\\x9a\\xfe\\xd9\\xd0\\x3f\\x5b\\xfa\\xe7\\x89\\xfe\\xc1\\xbd\\x48\\x9f\\xb2\\x03\\xff\\xcb\\x69\\xe1\\x27\\xaf\\x7f\\x14\\x4a\\x83\\xee\\xb1\\x7f\\x5a\\x74\\x4f\\xcb\\xee\\x69\\xd5\\x3d\\xad\\xbb\\xa7\\x4d\\xf7\\xb4\\xed\\x9e\\x9e\\xba\\xa7\\x9e\\x9f\\x3c\\xe1\\x7f\\x39\\x3f\\xf8\\xc9\\xeb\\x1f\\x85\\xd2\\xa0\\x7b\\xec\\x9f\\x16\\xdd\\xd3\\xb2\\x7b\\x5a\\x75\\x4f\\xeb\\xee\\x69\\xd3\\x3d\\x6d\\xbb\\xa7\\xa7\\xee\\xa9\\xe7\\xa7\\xce\\xf9\\x5f\\xce\\x0f\\x7e\\xf2\\xfa\\x47\\xa1\\x34\\xe8\\x1e\\xfb\\xa7\\x45\\xf7\\xb4\\xec\\x9e\\x56\\xdd\\xd3\\xba\\x7b\\xda\\x74\\x4f\\xdb\\xee\\xe9\\xa9\\x7b\\xea\\xf9\\x69\\x33\\xfe\\x97\\xf3\\xd3\\xf6\\xea\\xd1\\xf6\\x1a\\xd2\\xf6\\x4a\\xd2\\x76\\x7a\\xd2\\x76\\xaa\\xd2\\x76\\xda\\xd2\\x76\\x0a\\xd3\\x76\\x3a\\xd3\\x76\\x6a\\xd3\\x76\\x9a\\xd3\\x76\\xca\\xd3\\x52\\xfd\\x01\\x56\\xa7\\xc5\\xb9\\x78\\x7a\\xea\\x7c\\xbd\\x30\\xcc\\x6d\\x23\\x9f\\xa8\\xfd\\xa5\\x1b\\xb5\\x65\\x85\\xf6\\xa8\\xaa\\x50\\x42\\x3d\\x80\\x47\\x07\\x6f\\x14\\xd6\\x29\\xf9\\x7e\\xdf\\x81\\x11\\x2e\\xbe\\xa3\\x9d\\x4f\\x01\\x0e\\x55\\xf1\\xb2\\xf3\\x95\\x20\\xe6\\xda\\x69\\x7d\\x87\\x9f\\x2c\\x74\\x12\\xf3\\x22\\xff\\xa2\\x95\\x98\\xdd\\xe1\\x38\\x68\\xa0\\x4b\\x46\\x9e\\x8c\\x60\\x3b\\x5f\\x90\\xff\\xfb\\xf8\\x0c\\x14\\xf5\\xf5\\xbb\\x32\\x8a\\x24\\x90\\x91\\xf8\\xeb\\xf9\\x1a\\xff\\xdf\\x46\\xc0\\x22\\x94\\x09\\x4d\\xe9\\x0a\\x29\\x9e\\x85\\x8c\\x27\\x58\\x09\\x08\\xf0\\x8f\\xbe\\x66\\xb0\\x62\\x55\\x96\\x72\\x95\\xc5\\x42\\x6f\\x80\\x50\\xd6\\x23\\xe8\\x0b\\x29\\x9e\\x95\\x8c\\x67\\xe9\\xeb\\x4d\\x10\\xca\\x7a\\x3c\\x7d\\x21\\xc5\\xb3\\x96\\xf1\\xac\\x3c\\x01\\xc1\\x4a\\x5a\\xd3\\x59\\x71\\x31\\x6e\\x94\\x2a\\x80\\x0c\\x56\\x90\\x10\\x56\\x8a\\x14\\xb6\\x32\\x9e\\x35\\x20\\x85\\x35\\x24\\x85\\xb5\\x22\\x85\\x27\\x19\\xcf\\x46\\x94\\xc2\\x46\\x92\\xc2\\x86\\x4b\\xc1\\xf7\\x14\\x35\\x02\\xc4\\xb0\\x85\\xc4\\xb0\\x55\\xc4\\xe0\\x2b\\xfa\\xf8\\x04\\xc8\\xe1\\x09\\x92\\xc3\\x93\\x22\\x07\\x5f\\xd5\\x49\\x4f\\x94\\x04\\xb0\\xbc\\x76\\x9d\\xd3\\xf8\\x6a\\x9f\\x56\\x75\\xd3\\x8f\\x5a\\x3a\\x0b\\x71\\xfd\\x67\\xfe\\xc0\\xe1\\x7c\\x15\\x86\\x83\\x74\\x10\\x81\\x0a\\x11\\x30\\x88\\x80\\x43\\x2c\\x54\\x88\\x05\\x83\\x58\\x70\\x88\\xa5\\x0a\\xb1\\x64\\x10\\x4b\\x0e\\xb1\\x52\\x21\\x56\\x0c\\x62\\xc5\\x21\\xd6\\x2a\\xc4\\x9a\\x41\\xac\\x39\\xc4\\x46\\x85\\xd8\\x30\\x88\\x0d\\x87\\xd8\\xaa\\x10\\x5b\\x06\\xb1\\xe5\\x10\\x4f\\x2a\\xc4\\x13\\x83\\x78\\xea\\x7a\\xcc\\xd3\\xba\\xcc\\xe3\\x7d\\xe6\\x75\\x40\\x7a\\xbf\\x76\\x1d\\xdb\\xf7\\xbd\\xd6\\xb5\\x3e\\xef\\x5b\\x1f\\x77\\x2e\\x59\\x2f\\x74\\xfd\\x8b\\x18\\xcf\\x08\\x83\\x85\\xbd\\x0f\\xa4\\xf7\\xa2\\x2d\\x62\\x00\\x0b\\x09\\x80\\x98\\x1c\\xf6\\x66\\x29\\xbd\\x11\\x6d\\x09\\x03\\x58\\x49\\x00\\xa2\\x91\\x60\\x00\\x6b\\x09\\x80\\xd8\\x02\\xf6\\x66\\x23\\xbf\\xd1\\xf9\\xde\\x4a\\x00\\x6b\\x9d\\xef\\x27\\x09\\x60\\x23\\xf0\\xed\\x7b\\x72\\x9f\\xe8\\x8c\\xfb\\x72\\xaf\\x09\\xc3\\xca\\x16\\xde\\x63\\xa7\\xfe\\x9e\\x9e\\x8e\\x85\\x0c\\x6f\\x75\\x76\\x38\\xa8\\xb9\\x87\\xbf\\xc3\\x11\\xd1\\x9d\\x5c\\x1e\\x0e\\xa9\\xa6\\x7b\\x3d\\x1c\\x7e\\xdd\\xc9\\xf1\\xe1\\xf8\\xed\\x4e\\xbe\\x0f\\x07\\x80\\xd3\\xdd\\x1f\\x0e\\x16\\xef\\xe4\\x01\\x71\\xb4\\x79\\x27\\x27\\x88\\xc3\\xd5\\xe9\\x7e\\x90\\xc4\\xd2\\x77\\x72\\x85\\x24\\x18\\xbf\\x93\\x37\\x24\\xd1\\xfc\\x8d\\x0e\\xb1\\xce\\x47\\xfb\\x44\\x69\\x7c\\x99\\xdc\\xa2\\x34\\x78\\x4c\\x9e\\x51\\x1a\\x16\\x26\\xe7\\x28\\x8d\\x02\\x93\\x7f\\x94\\xf4\\xdb\\xe4\\x22\\x25\\xcd\\x35\\x79\\x49\\x49\\x51\\x4d\\x8e\\x52\\x52\\x41\\x93\\xaf\\x94\\x94\\xcb\\xe4\\x2e\\x65\\x5d\\x32\\x7b\\x4c\\x59\\x4f\\xcc\\x4e\\x53\\xd6\\x01\\x8b\\xdf\\xac\\x73\\x57\\x76\\x13\\x9e\\xf8\\x6a\\xc8\\xab\\x12\\xf1\\x0e\\x38\\x56\\x22\\x5d\\x93\\x6f\\x25\\x52\\x1d\\x70\\xaf\\x44\\xa8\\x03\\x1e\\x96\\xc8\\xd4\\xe4\\x64\\x89\\x2c\\x07\\xfc\\x2c\\x11\\xe5\\x80\\xab\\x25\\x92\\x34\\x79\\x5b\\x2a\\xc1\\x01\\x87\\x4b\\xc5\\x67\\xf0\\xb9\\xd6\\xe5\\x31\\x3c\\xb3\\x7f\\x4f\\xa7\\xcb\\xd6\\x0d\\xde\\xea\\x74\\xf3\\xe4\\x3e\\x4e\\x37\\x4f\\xee\\xe6\\x74\\xf3\\xe4\\x16\\xa7\\x9b\\x27\\x77\\x73\\xba\\x79\\x72\\x37\\xa7\\x9b\\x27\\xb7\\x38\\xdd\\x3c\\xb9\\x9b\\xd3\\xcd\\x93\\xbb\\x39\\xdd\\x3c\\xb9\\xc5\\xe9\\x92\\x05\\xb5\\x3b\\x39\\x5d\\xb2\\x22\\x77\\x27\\xa7\\x4b\\x96\\xf4\\x6e\\x74\\xba\\x79\\x32\\xda\\xe9\\x4a\\xe3\\xcb\\xe4\\x74\\xa5\\xc1\\x63\\x72\\xba\\xd2\\xb0\\x30\\x39\\x5d\\x69\\x14\\x98\\x9c\\xae\\xa4\\xdf\\x26\\xa7\\x2b\\x69\\xae\\xc9\\xe9\\x4a\\x8a\\x6a\\x72\\xba\\x92\\x0a\\x9a\\x9c\\xae\\xa4\\x5c\\x26\\xa7\\x2b\\xeb\\x92\\xd9\\xe9\\xca\\x7a\\x62\\x76\\xba\\xb2\\x0e\\x58\\x9c\\x6e\\x9e\\x18\\x9d\\x2e\\x11\\xb0\\xdd\\xe9\\x12\\xf1\\x0e\\x38\\x5d\\x22\\x5d\\x93\\xd3\\x25\\x52\\x1d\\x70\\xba\\x44\\xa8\\x03\\x4e\\x97\\xc8\\xd4\\xe4\\x74\\x89\\x2c\\x07\\x9c\\x2e\\x11\\xe5\\x80\\xd3\\x25\\x92\\x34\\x39\\x5d\\x2a\\xc1\\x01\\xa7\\x4b\\xc5\\x37\\xde\\xe9\\xf6\\x9f\\x97\\x32\\x37\\x3b\\xbc\\xa7\\xd3\\x65\\x1f\\x0f\\xde\\xea\\x74\\xb3\\xc3\\x7d\\x9c\\x6e\\x76\\xb8\\x9b\\xd3\\xcd\\x0e\\xb7\\x38\\xdd\\xec\\x70\\x37\\xa7\\x9b\\x1d\\xee\\xe6\\x74\\xb3\\xc3\\x2d\\x4e\\x37\\x3b\\xdc\\xcd\\xe9\\x66\\x87\\xbb\\x39\\xdd\\xec\\x70\\x8b\\xd3\\x25\\x5f\\xd5\\xee\\xe4\\x74\\xc9\\x67\\xb9\\x3b\\x39\\x5d\\xf2\\x5d\\xef\\x46\\xa7\\x9b\\x1d\\x46\\x3b\\x5d\\x69\\x7c\\x99\\x9c\\xae\\x34\\x78\\x4c\\x4e\\x57\\x1a\\x16\\x26\\xa7\\x2b\\x8d\\x02\\x93\\xd3\\x95\\xf4\\xdb\\xe4\\x74\\x25\\xcd\\x35\\x39\\x5d\\x49\\x51\\x4d\\x4e\\x57\\x52\\x41\\x93\\xd3\\x95\\x94\\xcb\\xe4\\x74\\x65\\x5d\\x32\\x3b\\x5d\\x59\\x4f\\xcc\\x4e\\x57\\xd6\\x01\\x8b\\xd3\\xcd\\x0e\\x46\\xa7\\x4b\\x04\\x6c\\x77\\xba\\x44\\xbc\\x03\\x4e\\x97\\x48\\xd7\\xe4\\x74\\x89\\x54\\x07\\x9c\\x2e\\x11\\xea\\x80\\xd3\\x25\\x32\\x35\\x39\\x5d\\x22\\xcb\\x01\\xa7\\x4b\\x44\\x39\\xe0\\x74\\x89\\x24\\x4d\\x4e\\x97\\x4a\\x70\\xc0\\xe9\\x52\\xf1\\x8d\\x77\\xba\\xc2\\xf6\\x8c\\xcc\\x6d\\xdf\\xf5\\x4b\\x6a\\x7b\\x9f\\x8f\\xa9\\xed\\x9d\\xbe\\xa7\\xb6\\xf7\\xfb\\xa4\\xda\\xde\\xf4\\x55\\xb5\\xbd\\xdf\\x87\\xd5\\xf6\\x7e\\xdf\\x56\\xdb\\x9b\\x3e\\xaf\\xb6\\xf7\\xfb\\xc2\\xda\\xde\\xef\\x23\\x6b\\x7b\\xd3\\x77\\xd6\\xf6\\x8e\\x9f\\x5a\\xdb\\x3b\\x7e\\x6d\\x6d\\xdf\\xf0\\xc1\\xb5\\xcd\\x46\\x7b\\x5d\\x69\\x7c\\x99\\xbc\\xae\\x34\\x78\\x4c\\x5e\\x57\\x1a\\x16\\x26\\xaf\\x2b\\x8d\\x02\\x93\\xd7\\x95\\xf4\\xdb\\xe4\\x75\\x25\\xcd\\x35\\x79\\x5d\\x49\\x51\\x4d\\x5e\\x57\\x52\\x41\\x93\\xd7\\x95\\x94\\xcb\\xe4\\x75\\x65\\x5d\\x32\\x7b\\x5d\\x59\\x4f\\xcc\\x5e\\x57\\xd6\\x01\\x8b\\xd7\\x6d\\x33\\xa3\\xd7\\x25\\x02\\xb6\\x7b\\x5d\\x22\\xde\\x01\\xaf\\x4b\\xa4\\x6b\\xf2\\xba\\x44\\xaa\\x03\\x5e\\x97\\x08\\x75\\xc0\\xeb\\x12\\x99\\x9a\\xbc\\x2e\\x91\\xe5\\x80\\xd7\\x25\\xa2\\x1c\\xf0\\xba\\x44\\x92\\x26\\xaf\\x4b\\x25\\x38\\xe0\\x75\\xa9\\xf8\\x4c\\x5e\\x97\\xa5\\x46\\x30\\x1f\\x3a\\x82\\xce\\x00\\x58\\x76\\xa9\\x82\\x19\\x14\\xba\\x2d\\xbe\\xf4\\x8c\\xa1\\x72\\xb4\\xa8\\x29\\x4a\\xf8\\x34\\xc1\\x07\\xf4\\x84\\x62\\xb4\\xef\\x50\\x1e\\x51\\x48\\x52\\x29\\xa8\\x47\\x93\\x08\\x6b\\xca\\xf1\\xec\\xc0\\x88\\x25\\x2a\\x92\\xd7\\x1f\\xc9\\x7f\\x2f\\x02\\x55\\x23\\x3c\\xcf\\x1d\\x01\\x9e\\xad\\x67\\x79\\x1e\\xea\\x5c\\x48\\xfa\\x80\\x7f\\x08\\x4d\\x5e\\x90\\x3d\\xf9\\x72\\x3e\\x08\\x20\\x19\\x84\\x44\\x74\\x7a\\x2e\\x09\\x53\\x75\\xda\\x65\\x10\\x12\\xd6\\x97\\x52\\xaf\\xf1\\x28\\xa0\\x6c\\xbb\\x96\\x35\\x55\\x5a\\x62\\x78\\xdc\\x5f\\x4e\\x53\\xed\\x4e\\xcd\\xd1\\x2d\\xf6\\x6e\\xf3\\x5a\\xa2\\x4f\\x45\\x92\\x3c\\xea\\x1d\\x23\\x9e\\x01\\xf1\\x56\\x8f\\x1c\\x13\\x39\\x7a\\xdc\\xe3\\xa1\\x27\\x91\\xed\\x95\\x37\\x7d\\x6d\\x96\\x76\\x67\\x26\\xff\\xfc\\xa9\\x6f\\x59\\x57\\x02\\xe5\\xeb\\x88\\xb6\\x49\\xd8\\x4b\\x8b\\x72\\x22\\xd7\\x33\\xf1\\xf3\\xe1\\x69\\x1f\\x27\\x63\\xaa\\x0a\\xac\\xd8\\x80\\x20\\xee\\x64\\x12\\x5d\\x3a\\xa1\\x99\\x5a\\x20\\x90\\x10\\xca\\x20\\x8c\\x49\\x92\\xec\\x51\\x00\\x32\\xdd\\x67\\x2b\\x32\\xb5\\x38\\xde\\x27\\x41\\xb2\\x1e\\x53\\xd9\\xd4\\x66\\x0d\\x0c\\xe2\\x51\\x26\\xc3\\x12\\x26\\xcd\\xe4\\x9f\\x62\\x8b\\x79\\x09\\x88\\x6b\\x81\\xd6\\x71\\x04\\xb3\\xcc\\x32\\x31\\x99\\x5a\\x1b\\xf9\\xc9\\x3e\\x1a\\x51\\xd5\\xd8\\x56\\x19\\x08\\xd4\\x3e\\x89\\x44\\x7a\\xda\\x17\\x33\\xe1\\x59\\x40\\x4c\\x7f\\x82\\x28\\x10\\x5a\\x21\\x98\\x4b\\x92\\x58\\xca\\xd4\\xba\\x30\\x4a\\x12\\xb4\\x1a\\xa8\\x67\\x6a\\x9a\\x08\\x01\\x31\\x25\\x23\\x67\\x19\\xad\\x66\\xf2\\x4f\\x01\\x77\\x57\\x02\\x67\\xd4\\x41\\x28\\x0a\\x41\\x46\\x79\\xaa\\x2c\\x53\\x1b\\xf7\\x7b\\xb4\\x0d\\xfd\\xe1\\xaa\\xa6\\x66\\x2a\\x40\\x06\\xee\\x04\\x12\\x34\\x53\\xd7\\x4c\\xfa\\x25\\x20\\xe7\\x05\\x20\\xa2\\x55\\x6c\\x52\\x54\\x96\\xff\\xcb\\xd8\\x4a\\x3f\\xf2\\xa2\\xcd\\x60\\x4d\\x53\\x23\\x65\\x18\\x90\\x35\\x89\\x00\\xc9\\xe8\\x33\\x13\\x7f\\x08\\x98\\xd9\\x6f\\x10\\x4b\\xb2\\x4f\\xf6\\x08\\x64\\x93\\xe6\\x33\\x33\\xb5\\x0f\\xc5\\x28\\xde\\xc3\\x56\\x47\\xa8\\x68\\x6a\\x9e\\x04\\x02\\xf1\\x25\\xa3\\x4f\\xc2\\xea\\xdb\\x4c\\x78\\x96\\xa4\\x87\\x7f\\x82\\x46\\x66\\x1d\\x6f\\x63\\x58\\x45\\x49\\x6a\\x36\\xa3\\x85\\x79\\x8a\\xa2\\x08\\xee\\x92\\xbe\\x9e\\x59\\x6e\\x3d\\x04\\x68\\x18\\x24\\xe4\\x61\\xdc\\xa4\\xdf\\xd1\\x4c\\xfa\\x25\\x60\\xe6\\x05\\x00\\x22\\x93\\xdf\\x95\\x98\\xa1\\xf5\\xa7\\xba\\x6e\\x23\\x0a\\x53\\x9b\\x65\\x98\\xf1\\xcc\\x3a\\x73\\x12\\xd5\\x90\\x3e\\xc3\\xa1\\xcd\\x84\\x63\\x63\\xac\\x70\\x11\\x2c\\xb6\\x0b\\xa4\\xa0\\x23\\xba\\x25\\xe0\\x5b\\x3e\\xad\\xbc\\x15\\x74\\x40\\x8e\\xc6\\x60\\x0a\\x4a\\x39\\x30\\xc3\\xac\\x8d\\xe1\\x4b\\x84\\x77\\x64\\xe5\\x74\\x9a\\xa3\\xf2\\x53\\x8e\\xe4\\xa0\\xa6\\x10\\x48\\x43\\x0c\\xea\\x01\\x30\\xb7\\x46\\x7d\\xc1\\x6a\\x35\\xe3\\xff\\x13\\x63\\x3f\\x01\\xf5\\x84\\x30\\x50\\xc6\\x86\\xe5\\xdc\\x2d\\x11\\xf6\\x0b\\x34\\x9b\\x15\\x59\\x21\\xa4\\xc8\\x2b\\x54\\x97\\xc5\\xa9\\x4e\\xbf\\xe3\\x28\\xdc\\x9c\\x56\\xa1\\x3b\\x17\\xd7\\xb2\\x64\\x32\\x3c\\x35\\x41\\x97\\x50\\x86\\x9c\\x96\\xc3\\x4e\\x81\\x24\\x5e\\x81\\xb2\\xcd\\xe0\\x22\\x5c\\xf9\\x98\\x92\\x33\\x1f\\x7d\\xf2\\x19\\x88\\x15\\x63\\xd7\\x03\\x2d\\xda\\xac\\x37\\x70\\x8b\\x72\\x4b\\xa2\\x88\\xdf\\xb8\\x45\\x79\\x32\\xa5\\x45\\x4f\\x4f\\x3e\\xdc\\xa2\\xec\\xf0\\x2f\\xd3\\xa2\\xec\\x30\\xa5\\x45\\xbe\\xff\\xf4\\x04\\x37\\xa9\\xcd\\xfe\\x65\\x9a\\xd4\\x66\\xe6\\x26\\x69\\xd0\\xff\\x2a\\x5c\\x9b\\x8d\\xd4\\xbe\\xa8\\x72\\x37\\x2e\\x4e\\x4d\\x55\\x58\\xfa\\xb8\\x9f\\x76\\x93\\xa5\\x06\\x87\\xad\\x38\\x28\\x69\\xf6\\x0c\\x69\\xf5\\x8c\\x96\\x5d\\x31\\xd5\\x69\\x1e\\x1e\\x90\\x9e\\x45\\x2c\\x4b\\xcb\\x5d\\x9f\\x54\\xa9\\x05\\x0e\\xb0\\xc7\\x28\\x59\\x26\\xf0\\x11\\x6a\\xf1\\x0c\\xbb\\x68\\xc9\\xc5\\x83\\xec\\xce\\xdc\\x5f\\xd5\\xb3\\x3e\\x8d\\xa8\\xf6\\x4e\\xee\\xa5\\x1d\\xe9\\x77\\xd4\\x96\\xe1\\x29\\xd1\\x4d\\xac\\x7e\\xb2\\x58\\xed\\x65\\x96\\x76\\x69\\x54\\xe7\\x48\\xbe\\x67\\xeb\\x45\\xc9\\x7e\\xdf\\x25\\x67\\xf2\\xc4\\xcc\\xa7\\x9e\\x83\\xff\\xd1\\xb3\\xde\\xcc\\x8f\\xfb\\xc1\\x82\\xda\\xf8\\x00\\x7b\\x0c\\xa5\\x05\\x5d\\x7a\\x99\\xf2\\xdc\\xb8\\x65\\x16\\xc6\\xe8\\x48\\xd2\\xcc\\x5d\\xe4\\x44\\x55\\x45\\x19\\xc6\\x69\\xf3\\x4a\\x8e\\xe1\\x8b\\x08\\x70\\x0f\\xdc\\x5a\\xf7\\x6d\\x95\\xa7\\x57\\x49\\xd2\\x1a\\x2b\\x7f\\x32\\x93\\x8a\\x7f\\xad\\x50\\x98\\x14\\xa7\\xec\\xf5\\x2b\\x14\\xd6\\xd2\\x90\\xa3\\xc7\\x48\\x13\\x4b\\xc9\\x78\\x49\\x2a\\x32\\xac\\xfc\\x3c\\x93\\x5b\\x7e\\xce\\x9a\\xb4\\xcc\\xd0\\xd7\\x47\\x9e\\x7b\\x27\\x0e\\xb3\\xf8\\x53\\x40\\x35\\xd1\\xf9\\xd1\\x09\\xca\\xf6\\x11\\x44\\x45\\x34\\x82\\x76\\xcc\\xf7\\x30\\x3b\\xa3\\x31\\xca\\x21\\xb7\\x92\\x24\\xcc\\x91\\x5b\\xe8\\x92\\x0c\\x69\\x4a\\xfa\\x4e\\xf2\\x55\\x81\\x40\\xd1\\x4c\\x62\\x62\\x02\\x33\\xc2\\x2d\\x1f\\xe1\\x3f\\x3a\\xd8\\xbb\\xa8\\xd9\\xcc\\x20\\x10\\x25\\x5b\\xa2\\x6a\\x05\\x54\\x92\\xd8\\x3d\\xe9\\x54\\x07\\x69\\x8a\\x00\\x7a\\x8a\\x99\\x21\\x9a\\x75\\x0e\\xd0\\x0c\\x06\\x89\\x06\\x30\\xd5\\xf9\\x76\\x33\\x44\\x95\\x66\\xa0\\x92\\xd2\\xc3\\x2d\\xe0\\xfc\\x70\\xac\\x58\\xed\\x45\\x35\\xb7\\x8e\\x24\\xd9\\x32\\x0b\\xd3\\x53\\x83\\xda\\xe6\\x2d\\x14\\x54\\x6b\\x3d\\xc6\\x94\\x51\\x83\\x0b\\x64\\x4f\\x60\\xbe\\xa2\\x6c\\x1d\\xcf\\xc4\\xab\\x5c\\x9c\\x1d\\x66\\xa3\\xe0\\xea\\x7c\\x36\\xa7\\xc6\\x82\\xa4\\x96\\x73\\xb3\\xc3\\x4f\\x63\\xea\\x8d\\xae\\x24\\x82\\x85\\x49\\x52\\x9c\\xf4\\x9a\\xe2\\xef\\xa8\\x39\\x19\\x51\\x45\\x8d\\x52\\xb9\\xce\\x6f\\xe0\\xd5\\x52\\x69\\x80\\x57\\x5c\\x73\\x02\\xaf\\x83\\xc9\\x05\\xac\\x72\\x50\\xd9\\xb4\\xb3\\x32\\x96\\x5b\\x81\\x2d\\xe6\\xc0\\x1d\\x35\\x0b\\x9b\\x61\\xf0\\x81\\x99\\x4a\\x06\\x09\\x32\\x63\\x1c\\x35\\x27\\x9b\\x39\\xd7\\x18\\x9f\\xe8\\x0e\\x4c\\xf5\\xb5\\x1e\\xb2\\x22\\x01\\x88\\xba\\x75\\x3e\\xda\\x0d\\xf9\\xf3\\xad\\x2f\\x39\\x22\\x7d\\x3c\\xda\\x86\\x8c\\x7d\\x58\\x8c\\x1d\\x39\\x92\\x7c\\x09\\x33\\x70\\xb6\\xa5\\x21\\xe9\\x2e\\x34\\xe9\\x42\\xe4\\x6e\\x91\\x6e\\x76\\x78\\x9b\\x74\\xfb\\xfa\\x6f\\x97\\x6e\\x76\\x98\\x10\\x64\\x6c\\x37\\xba\\x70\\x09\\x71\\x20\\xbd\\x15\\x7b\\x4d\\x3c\\x88\\x31\\x31\\x0f\\xcf\\x7b\\x45\\x40\\xdf\\x25\\x91\\x8a\\x96\\x47\\x85\\x24\\x77\\xe0\\xf4\\x58\\x6e\\x94\\xee\\xa7\\x2d\\x33\\x8a\\x96\\x27\\xa2\\xc7\\x44\\x52\\x61\\x02\\x39\\x28\\xc0\\x76\\x4b\\xc9\\x53\\x85\\xfa\\x73\\x1e\\x44\\x3a\\x42\\x21\\x0b\\xa1\\x94\\x4c\\x5f\\xda\\x7b\\x39\\x7f\\x05\\xd3\\x6f\\x35\\xc5\\xb4\\x58\\x8d\\xe6\\x38\\xed\\x38\\x0e\\xa3\\xba\\xc8\\xce\\x0d\\xd2\\x65\\xa3\\x24\\xa1\\x91\\x04\\xc6\\x51\\x91\\xcc\\x6c\\xb6\\x7c\\xb1\\xb4\\x03\\x79\\x26\\x40\\xad\\x2e\\xd0\\x60\\x30\\xd9\\xef\\x75\\xfe\\x3d\\xcc\\xd2\\xc4\\xdd\\x23\\x94\\xe0\\x48\\x42\\x4a\\x99\\x08\\xb0\\xae\\x1b\\x74\\xbe\\x52\\x47\\xae\\xf6\\xe0\\xe8\\x9a\\xa2\\xc0\\xfa\\x0e\\xf4\\x06\\xf9\\xa6\\x8d\\xe7\\xa6\\xff\\x74\\x49\\xfe\\xe4\\xdd\\xea\\x59\\x22\\xc9\\x77\\x5e\\x79\\xbd\\x6a\\xc8\\x49\\xba\\x09\\x33\\xfe\\x08\\xe7\\x62\\x4d\\x94\\x45\\x26\\x5b\\x4b\\x6f\\xe6\\xaf\\x37\\xb3\\xf5\\xd3\\x6c\\xbe\\x7d\\x84\\x3d\\x51\\x7c\\xae\\x9b\\x22\\x77\\xb9\\x6d\\x20\\x81\\x7e\\xaa\\xcc\\x49\\x84\\xe2\\x97\\x90\\x3d\\x86\\x0d\\x56\\x3a\\xa9\\xf6\\x0e\\x86\\x91\\xec\\x15\\x29\\x57\\xd6\\x2e\\x79\\xcf\\xc2\\xac\\xb0\\x44\\xd7\\x30\\x43\\xfc\\xe5\\x30\\x5b\\x06\\x48\\x9d\\x39\\x36\\x0d\\xb6\\xcd\\x61\\x85\\x6e\\x25\\x73\\x58\\x98\\xf1\\xff\\x56\\x34\\x6f\\x36\\x00\\xc7\\x54\\xca\\xd0\\x52\\x1d\\x9b\\x15\\xac\\x43\\x36\\xdc\\x33\\x3a\\xe6\\xf1\\x75\\x4c\\x64\\xf4\\x6e\\x1d\\xa4\\x62\\xae\\xc2\\xc7\\x9a\\x32\\x63\\x54\\x2d\\x53\\xd7\\x07\\x3f\\x6a\\xa6\\xc1\\x40\\xac\\xaf\\xbb\\x33\\x54\\xbc\\xc0\\x2a\\xca\\x1d\\xa1\\x4c\\xf7\\xbf\\xf5\\xd7\\x49\\x1a\\x87\\x4d\\x51\\x99\\xba\\x54\\xc2\\xb3\\x1b\\x40\\x62\\x58\\x36\\x37\\x28\\xe3\\x48\\x16\\x13\\x54\\xc7\\x55\\x4a\\x6f\\xdf\\x78\\x03\\x93\\x02\\x1a\\x43\\x97\\x91\\xc4\\xb9\\x06\\x66\\xc8\\xbb\\x2e\\x9e\\x83\\xb9\\xe8\\xeb\\xef\\xcc\\x95\\xed\\x86\\x65\\x2c\\x0b\\x3c\\x05\\xe6\\x9b\\x58\\x11\\x2e\\x75\\x11\\x58\\xea\\x12\\xe4\\x9a\\x59\\xb2\\x9b\\x34\\x95\\xf6\\x0d\\xd6\\x2a\\x3d\\xdd\\xc9\\x23\\xd2\\xab\\xab\\x7a\\x84\\xff\\x67\\xf8\\xc4\\x20\\xf0\\x66\\xab\\xc5\\x34\\x9f\\xc8\\x5a\\xa8\\xdb\\xdc\\xee\\x85\\xd5\\x64\\x9a\\xa0\\x24\\x93\\xc7\\x80\\x14\\x15\\xe6\\x7d\\x6c\\x62\\xc9\\xe4\\x1d\\x95\\xd7\\x63\\xd8\\x1b\\xe3\\x21\\x25\\x50\\xab\\xd6\\x09\\xdd\\x0c\\xfb\\x48\\x86\\xea\\xbf\\x35\\x7d\\x04\\xfc\\xa4\\x06\\x6b\\xf4\\x95\\x16\\xac\\x83\\xa0\\xe3\\x7c\\xa6\\x85\\xc2\\xb4\\x7a\\xa3\\x7c\\xe7\\x78\\x6a\\xf6\\x6a\\x13\\x7c\\x28\\xab\\x72\\x8b\\x17\\x35\\x56\\xbd\\xc0\\xea\\xac\\x39\\xa9\\x8e\\xef\\xb7\\x79\\xd2\\x41\\x34\\xa6\\x4f\\xd0\\xb0\\xd2\\x8e\\x66\\x73\\xb2\\x37\\x1d\\x81\\xc8\\xd0\\x75\\xb2\\xe7\\x50\\xf1\\x4c\\xf4\\xa8\\xb6\\xea\\x76\\x83\\x34\\x9e\\x8d\\x09\\x5e\\x75\\x0c\\x9a\\x29\\x7e\\x75\\x94\\x31\\xd4\\xe9\\xdf\\x60\\xe5\\x88\\xde\\x2b\\x93\\xdb\\xe1\\x65\\x09\\x72\\xc5\\x44\\x55\\xbc\\x38\\xfd\\xd2\\x84\\x5c\\xd4\\x41\\xd2\\x99\\x6d\\x8c\\x4e\\x0d\\xaa\\x9e\\xc9\\x0f\\x92\\x8a\\xbc\\x66\\x45\\x12\\x03\\xe2\\xf8\\x14\\x36\\x7c\\x5b\\xf2\\x7a\\x89\\x95\\xe5\\x0b\\x5d\\x86\\xdb\\x30\\xc0\\x99\\x70\\x4a\\x2b\\x8c\\xbf\\xf1\\xc2\\x7f\\x9c\\xeb\\x26\\xdd\\xbf\\xba\\x3c\\xd7\\x38\\x2b\\x86\\x17\\x21\\xa4\\x56\\xd1\\x15\\xa4\\xd1\\xec\\x99\\xce\\x77\\xdd\\x5f\\x04\\x63\\x98\\x57\\x3f\\x6b\\x4b\\xcb\\x1f\\xc2\\x91\\x33\\xc3\\x82\\x86\\x11\\xa1\\xf0\\xfd\\xc5\\x90\\xe0\\x5c\\xac\\x29\\xac\\x03\\x5e\\x7a\\xa2\\x66\\x15\\xfa\\x7d\\x74\\x41\\x3a\\x81\\x67\\x4c\\xce\\x0d\\x77\\xb3\\x69\\xb1\\xcb\\x02\\xad\\xac\\x71\\x75\\xab\\x72\\x10\\x6d\\xb6\\x42\\xa5\\x2f\\x79\\xa9\\xf8\\x65\\xe3\\xfe\\x3b\\x75\\xa4\\xb5\\x07\\x8c\\x7e\\xb2\\xeb\\x89\\xba\\x09\\x9b\\x34\\x7e\\x1e\\xb1\\x62\\x17\\x80\\x87\\x3e\\x50\\xdb\\x30\\x61\\x29\\xa4\\x8f\\x61\\xdd\\x05\\x35\\x8a\\x3a\\x77\\x33\\x14\\xd2\\xed\\xd7\\x2b\\x59\\xa6\\x07\\x39\\x50\\x2f\\x52\\x14\\x6e\\xa8\\xe2\\x7a\\x24\\xdd\\x7d\\x43\\x86\\x34\\x7c\\x39\\x18\\xdf\\x82\\x70\\xae\\x51\\xc5\\x63\\x37\\x32\\x49\\x21\\x77\\x1e\\x01\\xa5\\xb5\\x5e\\xa8\\x15\\x68\\x7b\\x43\\xc4\\x4f\\x95\\xb7\\x6d\\x62\\x19\\xdc\\x55\\xa2\\x44\\x38\\x64\\xc7\\x88\\xb8\\x85\\x64\\x26\\xed\\x3b\\x01\\xde\\x76\\xfb\\x4e\\xd4\\x77\\x44\\x10\\xdc\\x9b\\xe2\\x47\\xba\\xad\\x0f\\xbc\\x59\\x0e\\xbf\\x9f\\x0b\\xa0\\xca\\x5d\\x72\\x93\\xf6\\x8a\\x60\\x54\\xfd\\xae\\x09\\x8c\\x8d\\xff\\xba\\xf0\\x2d\\x11\\xf3\\xf5\\xea\\xda\\x7f\\x58\\xe1\\xaf\\xd9\\x47\\x8a\\xae\\xf2\\xe3\\x9c\\x6f\\x9d\\x1d\\x06\\xdd\\x51\\xd0\\x0b\\xb8\\x21\\xe8\\x1a\\xca\\x4c\\xf1\\x2b\\xa1\\x7a\\x74\\x4e\\x48\\x3f\\x2e\\x15\\xd8\\x30\\x57\\x2e\\xfa\\x8e\\x4e\\x4d\\xdd\\x77\\x0d\\x3f\\x30\\x62\\xdf\\x25\\xca\\x2e\\x36\\x94\\x23\\x31\\x5a\\x28\\x61\\x91\\x6f\\x28\\x34\\xe1\\x5a\\x3f\\x25\\xea\\x4e\\x58\\xcf\\x5b\\x07\\x71\\x2c\\xe1\\x12\\x84\\xd6\\xa1\\x1f\\x0e\\x88\\x04\\x91\\x31\\x89\\x75\\xf8\\x24\\xc9\\x75\\x28\\x3b\\x09\\xbe\\xa1\\xd5\\xe3\\x65\\x3d\\xb2\\xca\\x8e\\x57\\xa9\\x8f\\xc5\\xcb\\x4f\\x72\\x2b\\xaa\\xa2\\x4c\\x8a\\x17\\xec\\x0a\\x0e\\x87\\x0c\\x0d\\xf6\\x75\\x10\\xc7\\x5a\\x0b\\x56\\x71\\xb4\\x1f\\xab\\xf8\\xbc\\x17\\xbb\\x43\\x36\\x76\\x8a\\x6c\\xcf\\x91\\xb2\\x41\\x8b\\x5f\\xf6\\x22\\xe2\\x19\\xa3\\x2b\\x9b\\x60\\x13\\x6d\\x97\\x0a\\xb6\\x75\\xbc\\x59\\x6d\\x12\\x05\\x9b\\xa8\\x2d\\x3d\\x89\\x61\\x7d\\xf1\\x17\\xcb\\x99\\xbf\\x0c\\x66\\xfe\\xca\\x03\\xda\\xaa\\xe8\\x4c\\x8f\\xd8\\xa2\\x35\\x13\\x7a\\x60\\x82\\xde\\x8c\\xad\\x04\\x68\\x8e\\xd0\\x9a\\x29\\xba\\x43\\xbb\\x59\\xed\\xfb\\xf5\\x1a\\x6d\\xd6\\x56\\xdd\\x81\\x7b\\x94\\x1e\\x5b\\x1a\\xd8\\x8b\\x4e\\x2f\\xaf\\x87\\xd7\\x50\\x05\\x2c\\x63\\x34\\x27\\xf0\\xb7\\xdb\\xc5\\x56\\xc1\\xe5\\xa3\\x0d\\x5a\\x2c\\x25\\x5c\\x92\\xde\\x30\\xf4\\x93\\x96\\x34\\x95\\x16\\xaa\\x1a\\xc3\\x50\\x5a\\xf4\\x65\\x74\\xab\\xa7\\x68\\xcb\\xa8\\x2a\\x90\\xae\\xf0\\x56\\x4c\\xd1\\x14\\xda\\xad\\x6a\\x5f\\xc7\\x9b\\xe5\\xc2\\xee\\x5e\\x81\\x5e\\x4c\\x4f\\xfb\\x62\\x80\\xd8\\x26\\x0c\\x22\\x4d\\xb0\\xa4\\xb0\\x47\\x31\\x46\\x43\\xfc\\xc5\\x76\\xa9\\x8d\\x53\\xdf\\xdf\\x84\\xdb\\xa8\\x47\\x24\\xaa\\x07\\x41\\x3c\\x62\\x4a\\xbe\\x98\\xf9\\xeb\\x60\\xe6\\x6f\\x97\\x72\\xb3\\x14\\xcd\\x20\\xd8\\x2c\\x6a\\x31\\xae\\x9d\\x13\\x74\\x62\\x04\\x3c\\xa0\\x10\\x94\\xf3\\x49\\xda\\x40\\xba\\x50\\x65\\xdc\\xdb\\x78\\x1b\\xbb\\xcf\\x81\\xfa\\x8d\\x9d\\x95\\xbb\\x74\\xa8\\x7d\\x70\\xcf\\x67\\xec\\x7b\\x1b\\x85\\x20\\x2d\\x94\\xb0\\xc8\\x4a\\x01\\xe3\\x42\\x5e\\xb8\\xf5\\x3c\\x05\\x57\\xb2\\x78\\x42\\x9e\\x27\\xe1\\x12\\xf5\\x82\\xa3\\x1f\\xa1\\x1a\\xab\\xd5\\xcc\\x7f\\x5a\\xcc\\x36\\x5a\\x0b\\x15\\xe5\\xe0\\x28\\x2d\\xfa\\x31\\xba\\xd5\\x13\\x54\\x64\\x5c\\x15\\x40\\x4b\\xba\\x56\\xc0\\x8a\\x02\\xf7\\x35\\xed\\x56\\xa5\\x05\\xf1\\xfa\\x69\\xe5\\xd9\\xcd\\x06\\xd0\\x8b\\xf4\\xb8\\xa1\\x5d\\x2f\\xe9\\xc2\\xa1\\x2a\\x5a\\xb6\\x9a\\xd8\\x23\\x19\\x63\\x3a\\xe2\\x6d\\xb0\\x58\\x2c\\x14\\x54\\x51\\x12\\xf8\\x0b\\x4f\\x44\\x25\\x2a\\x09\\x43\\x3e\\x69\\x45\\x4f\\x6e\\x9d\\xa2\\x22\\x0c\\xa1\\x45\\x43\\xc6\\x36\\x78\\x82\\x82\\x8c\\xaa\\x01\\xe8\\x07\\x6f\\xc1\\x14\\x3b\\x42\\xfb\\x53\\xed\\xe4\\xc0\\xdf\\x07\\x89\\x5d\\x3d\\xf4\\x0e\\x24\\x47\\xea\\x06\\x8c\\x88\\x74\\xdb\\x9c\\x54\\x28\\xe0\\x18\\x65\\x42\\x02\\xb4\\x46\\x2a\\xa6\\x24\\x44\\x1e\\x5a\\x09\\x98\\x44\\xdd\\xa0\\xa8\\x47\\xa8\\xc6\\x72\\x3b\\x0b\\x96\\x4f\\xb3\\x40\\x8c\\xac\\x28\\x36\\x59\\x37\\x28\\x42\\x9b\\xf1\\x18\\xd7\\xda\\x09\\x9a\\x31\\xa6\\x02\\xa0\\x18\\x8c\\xfb\\x49\\x66\\x83\\x74\\xa5\\x66\\xa2\\x93\\xa7\\x64\\xc0\\xbf\\x40\\xbd\\x37\\x7c\\x40\\x72\\xb1\\x5c\\x84\\x4b\\x55\\x0d\\x69\\x61\\x8f\\x62\\x54\\x44\\xba\\x08\\x36\\x81\\xe6\\x17\\x93\\xc0\\x0f\\x96\\x3d\\x22\\xd9\\x64\\x54\\xdf\\x46\\x68\\xc5\\x2a\\x98\\xad\\xb6\\xb3\\xf5\\x52\\x6e\\x94\\x66\\x2d\\xaa\\x6f\\x36\\x85\\x18\\xd7\\xca\\x49\\x96\\x62\\x10\\x1e\\xb4\\x13\\x98\\xf3\\x49\\xd1\\x06\\xe9\\x40\\x2d\\x4c\\xf2\\x43\\xdf\\x6e\\x25\\xf4\\x5e\\xe3\\x97\\x3f\\x2b\\x0b\\x22\\x7c\\x11\\xc0\\x7a\\x08\\x00\\x3e\\xab\\x65\\x5c\\x37\\x50\\x48\\x8d\\x5b\\x35\\x19\\x58\\x8b\\x50\\x70\\x8a\\x8a\\xa4\\x92\\xbb\\x69\\x15\\x45\\xc5\\x2f\\xeb\\x97\\x4a\\xa2\\x53\\xb5\\xf1\\xbd\\x08\\x77\\xcd\\x04\\x95\\x9b\\x56\\x15\\xd0\\x3e\\xad\\x89\\xd3\\x96\\x5a\\x8c\\x02\\x9a\\xba\\xd4\\xc2\\xf9\\xd0\\x96\\x5c\\xf8\\xd2\\xc2\\x5b\\x75\\x51\\x5c\\x8d\\xd0\\x88\\x8d\\xd1\\xc6\\xc1\\x35\\x0e\\x0d\\x2b\\xa4\\x8f\\x6f\\x5e\\xa7\\xd1\\xa9\\xc0\\x5a\\x09\\xac\\xdb\\x8c\\xef\\x51\\x53\\x37\\xdd\\xa0\\x99\\x6f\\x58\\xc4\\x01\\x9a\\x3a\\x45\\x3b\\x2d\\x02\\x9b\\xbe\\x98\\xd3\\xf1\\x22\\x2f\\xea\\xf0\\x85\\x8c\\xb7\\x6a\\xa7\\xb8\\xf6\\xa1\\x90\\x1a\\xe5\\x67\\x87\\xd6\\x53\\x14\\x9c\\xa0\\x66\\xbe\\x65\\x25\\x48\\xc5\\x6f\\xd0\\x49\\x75\\x65\\x68\\x7c\\x2f\\xc2\\x5d\\x73\\x8b\\x3e\\xde\\xba\\x4c\\xa4\\x35\\x71\\x8a\\x2e\\x5a\\x04\\x34\\x75\\xb9\\x88\\xf3\\x21\\x2e\\x1b\\xf1\\x85\\x93\\xb7\\xaa\\xa1\\xb8\\xd6\\x22\\xd2\\x19\\xb5\\xb6\\x34\\xb4\\x78\\x23\\x22\\x84\\x14\\xf0\\x0d\\x6b\\x4d\\x12\\x6a\\x58\\xf7\\xe4\\xb5\\xa7\\xf1\\xfd\\x06\\x74\\xc6\\x0d\\x5a\\x77\\xdb\\x42\\x94\\xdc\\xac\\x49\\x21\\xa2\\x59\\x18\\x93\\x17\\xa4\\x38\\x17\\xca\\xc2\\x14\\x5f\\x8c\\x79\\xab\\xce\\x89\\xeb\\x37\\x0a\\xa9\\x31\\x6a\\x37\\xb8\\x26\\xa4\\xe0\\x84\\x34\\xef\\x4d\\xab\\x59\\x2a\\x7e\\x58\\xfd\\xb4\\xd5\\xad\\xf1\\xbd\\x08\\x77\\xcd\\x0d\\x4a\\x78\\xf3\\x52\\x97\\xd6\\xc4\\x29\\xaa\\x68\\x11\\xd0\\xd4\\x25\\x2f\\xce\\x87\\xbc\\xf4\\xc5\\xd7\\x7c\\xde\\xaa\\x88\\xe2\\x32\\x91\\x4c\\x69\\x8c\\x1e\\x0e\\xae\\x3c\\xc9\\x28\\x21\\x35\\x7c\\xcb\\x7a\\x99\\x82\\x1d\\x56\\x42\\x75\\xfd\\x6c\\x7c\\x07\\x82\\xbd\\x72\\x83\\x0a\\xde\\xba\\x98\\xa6\\x36\\x6f\\x8a\\x02\\x5a\\x24\\x33\\x75\\x51\\x8d\\xb3\\x21\\x2d\\xae\\xf1\\x85\\xa5\\x37\\x1b\\x42\\x61\\x2d\\x4a\\x22\\x24\\xab\\x1f\\xcf\\xaa\\x35\\x7d\\x81\\x4b\\x42\\x0a\\x29\\xe0\\x9b\\x16\\xe5\\x64\\xec\\xb0\\x02\\x2a\\x8b\\x74\\xe3\\x3b\\x10\\xea\\x95\\x1b\\xd4\\xef\\xc6\\x15\\x3b\\xa5\\x69\\xb0\\xf2\\xdd\\x22\\x97\\xe9\\x8b\\x77\\xfd\\x40\\xe8\\x17\\xf1\\xf8\\x42\\xd6\\x5b\\x15\\x50\\x5c\\xfb\\x12\\xe9\\x8c\\x31\\x7f\\x83\\x8b\\x69\\x22\\x42\\xd8\\xf8\\xdd\\xb8\\xf2\\x27\\x21\\x36\\xd9\\x3d\\x71\\x25\\x70\\x7c\\xaf\\x01\\x5d\\x71\\x93\\xcd\\xbb\\x65\\x59\\x50\\x6e\\xd6\\x14\\x7b\\x67\\x11\\xc5\\xc4\\xe5\\xc1\\x2c\\x3d\\x7d\\xbb\\xa8\\xdb\\xfc\\xa6\\xae\\x6e\\x61\\x24\\xb2\\x06\\x79\\xde\\x6a\\x1d\\x2d\\x9e\\xd5\\xad\\x6b\\xe7\\x53\\x82\\x2a\\xdc\\xe6\\x31\\xd9\\x47\\x6c\\xd4\\xe4\\xef\\x0c\\xa7\\x5e\\xad\\xe0\\x8a\\x62\\xa7\\xf4\\x7b\\xc4\\x08\\x22\\xf5\\x13\\xc3\\x49\\x57\\x23\\x71\\x05\\xa8\\xcf\\x3e\\x40\\xd2\\x7f\\x90\\x3a\\x87\\x3b\\xe6\\x38\\xe8\\x69\\xd4\\xb9\\x40\\xa3\\x4f\\x68\\x73\\x97\\x3c\\x19\\x18\\x25\\xd9\\xe1\\x69\\x4c\\x01\\x26\\xc0\\xfc\\x28\\x80\\x8b\\xe7\\xc6\\xc8\\x09\\x72\\xb2\\xb1\\xf7\\xd7\\xe6\\xb5\\x44\\x5f\\xa2\\x73\\xd3\\x14\\xa7\\xaf\\x3d\\xf4\\x4c\\x78\\x59\\xa1\\x1a\\x35\\x86\\x77\\xf5\\x39\\xca\\x53\\xf1\\xa5\\xb8\\xad\\x7e\\xbe\\x0f\\x13\\xd4\\xed\\x43\\xf4\\xc4\\xad\\x98\\xac\\x90\\xee\\xa3\\xc4\\xed\\x0e\\x2b\\x0a\\x4e\\xc6\\xd8\\x45\\x48\\x10\\x15\\x17\\x59\\x16\\x96\\x35\\x92\\xce\\xe4\\xf5\\xc5\\x14\\x5e\\x3e\\xc3\\xd3\\x54\\x86\\xd7\\x2c\\xd7\\x5a\\xf1\\x72\\x25\\xe9\\x17\\x87\\xa0\\xa8\\x34\\x3b\\x5a\\x78\\x76\\xa5\\x6f\\x83\\x66\\xf2\\xf2\\xba\\x34\\x71\\xbb\\x63\\x9a\\x24\\xe8\\x24\\xb6\\x96\\xc2\\x38\\xf3\\x05\\xdb\\x34\\x7a\\xed\\x4c\\xc6\\x8c\\x3c\\x9d\\x4b\\x1d\\xf1\\x55\\x35\\x2b\\xbb\\x5d\\xb8\\x6f\\x50\\x65\\xdb\\x22\\xef\\xf5\\xdc\\x88\\x9b\\xaf\\xe7\\xc1\\x6a\\xa5\\xef\\x3f\\x66\\xa5\\x7c\\x4f\\xf4\\xc3\\x83\\x98\\x82\\x7e\\xbe\\x40\\x39\\xdd\\x97\\xdb\\x69\\x21\\xdd\\xca\\xdc\\x95\\x43\\xa9\\x85\\xba\\x84\\x45\\xec\\x37\\xa5\\x0e\\x56\\xd1\\x9b\\x87\\xf2\\xb2\\x79\\xe5\\x8d\\x54\\xf6\\x8e\\x77\\xb0\\x39\\x3a\\x9d\\x6d\\xa7\\x29\\x69\\x85\\xee\\x50\\xa5\\xef\\x79\\x9e\\x7c\\xae\\x72\\x9f\\x15\\x61\\xb3\\xc3\\x60\\xcf\\xc2\\x35\\x3b\\x9e\\x90\\x8c\\x89\\x59\\x02\\xde\\x85\\xbb\\x39\\xcb\\xc5\\xe2\\x39\\x6a\\xaa\\xa7\\x67\\x39\\xb6\\x10\\x76\\x58\\x13\\xfc\\x59\\x5a\\x37\\x2c\\xfd\\x9f\\x96\\x29\\x0f\\xf6\\x10\\x83\\xf9\\xf3\\xc4\\xbc\\xaf\\xfe\\x4a\\x3f\\xab\\x49\\x33\\x43\\x50\\x95\\x72\\x94\\x5e\\xb3\\x9c\\x15\\x60\\x4d\\x04\\x6a\\xfe\\x0e\\xaa\\xe7\\xdd\\xa0\\x71\\xba\\xba\\x0e\\xaa\\x1e\\xd4\\xcc\\x51\\x2a\\x98\\xa4\\xdf\\xd3\\x04\\x55\\x17\\xa5\\xbd\\x9d\\xda\\xa8\\x76\\xc0\\x7e\\xb1\\x43\\x87\\x36\\x6d\\x90\\x25\\x61\\xab\\xe2\\x41\\x7c\\xea\\x42\\xe2\\x0c\\x85\\xd5\\x2e\\x2a\\x9a\\xa3\\xb6\\xdd\\xdf\\xa8\\x9a\\xec\\x5c\\x18\\xb4\\xfb\\xbf\\x57\\x45\\x1c\\x7e\\x08\\x39\\x11\\x25\\x26\\xf9\\x2e\\x77\\xb9\\x50\\xde\\x86\\xb0\\xf6\\xb7\\x7e\\xa4\\x85\\x10\\xa6\\x51\\xc0\\x26\\x41\\x12\\xc2\\x2e\\x56\\x93\\xc9\\xb0\\x9d\\xe7\\xc2\\xf8\\x19\\x49\\x84\\x7f\\x98\\x94\\x89\\xf4\\x11\\x84\\x4c\\xe6\\xa6\\x8f\\x32\\xd2\\x70\\x83\\xfc\\x52\\x0f\\x71\\x44\\x61\\x22\\x8c\\x27\\x2a\\x6e\\x25\\x12\\x99\\x0f\\x24\\x9b\\x53\\x8e\\x9e\\x33\\x16\\x75\\xb1\\x0a\\x81\\xc9\\x4c\\x88\\x51\\xf8\\x90\\xb4\\xe4\\xdb\\xa1\\xd9\\x1f\\xc9\\x50\\x57\\x0f\\xe5\\x08\\xc5\\xa6\\x33\\x59\\x3a\\x29\\x21\\x28\\x22\\x2f\\x58\\x92\\x29\\x8d\\xbe\\x70\\x44\\xcd\\x97\\x8e\\xa8\\xd1\\x5f\\x46\\xd4\\x54\\x09\\x55\\x02\\x4c\\x35\\xb9\\x4b\\x08\\x8c\\xd5\\xa5\\xe9\\x01\\x84\\x7e\\xe8\\xbd\\x10\\xd8\\xf6\\xe4\\x75\\xac\\x06\\x64\\x02\\x0e\\x90\\x59\\x07\\x3f\\xfe\\xa8\\x74\\x61\\x5f\\xa8\\x49\\xd8\\xe9\\x1f\\xc1\\x5a\\xc2\\x2b\\xb3\\x76\\x80\\x44\\x81\\xb7\\x03\\x18\\x60\\x36\\x8c\\x30\\x72\\x36\\x2c\\x96\\x33\\xa9\\x6c\\x69\\x67\\x34\\x45\\x91\\x45\\x61\\x75\\x8f\\x1c\\x57\\xf2\\x61\\xb1\\xba\\x09\\xab\\x46\\x3b\\x2b\\x46\\xde\\x93\\x57\\x12\\x79\\xf3\\x61\\x41\\x45\\xa0\\x78\\x2a\\xb9\\x23\\xb7\\x7b\\xb9\\xf1\\x31\\xcd\\x12\\x3a\\xb9\\xdc\\x65\\xa1\\x5c\\xa0\\xfa\\xa2\\xc7\\x8b\\xec\\xdb\\x3d\\x0d\\xb1\\x80\\x53\\xf5\\x55\\x66\\xc8\\x89\\xc4\\x9b\\xa2\\xa4\\x6e\\xb8\\x63\\x43\\x76\\xbc\\xca\\x4b\\x8d\\x72\\x4f\\x48\\xef\\x07\\x49\\xf5\\x55\\x4f\\xac\\x41\\x8b\\x1c\\xe1\\x66\\x9a\\x18\\x92\\xde\\xa9\\xfc\\x30\\x69\\xf5\\x31\\x20\\x0c\\x30\\x42\\x66\\xd4\\x74\\x0d\\x88\\x88\\x61\\xb3\\x75\\xbf\\xda\\x4d\\xaa\\x3d\\x18\\x85\\x42\\x5d\\x7f\\xb8\\x8f\\xf0\\x18\\x69\\x9b\\x08\\x75\\x45\\xbc\\x59\\x4a\\x3f\\xaa\\xad\\x70\\xeb\\x32\\x4b\\x1b\\x25\\x79\\xdc\\x7c\\xb5\\x0e\\xa4\\xc4\\xa9\\x34\\xcc\\x63\\xa5\\x36\\x44\\x86\\xa8\\x4e\\x9b\\xb3\\x1b\\xaa\\xf3\\xa9\\xfc\\x48\\x36\\x95\\xf4\\xae\\x2c\\x18\\xdd\\xac\\x94\\x75\\x02\\xb6\\x16\\x61\\xa5\\x99\\x1d\\x46\\xd2\\x84\\x48\\x6a\\x14\\x3b\\xaf\\xdf\\x99\\xbe\\x24\\xad\\x50\\x4c\\xfc\\x6f\\x5c\\x64\\xe7\\xfc\\xf4\\x0c\\x97\\x2a\\x07\\x70\\xa9\\xad\\x14\\xcf\\xdf\\xf6\\x76\\x72\\xca\\x19\\x5c\\x88\\x37\\x67\\x84\\x9b\\xb8\\xa8\\xcb\\x1d\\x80\\x3f\\x36\\xba\\x9b\\x9f\\x46\\xb8\\xad\\x9f\\x46\\xb8\\x2d\\x15\\x46\\x76\\x5b\\x38\\xe0\\xc7\\x5e\\x4b\\x3d\\x07\\x6d\\x8a\\x1e\\x86\\x8d\\x8e\\xc5\\xde\\xa8\\x91\\x88\\xc5\\x5e\\x5c\\x6c\\x46\\x60\\xa4\\x35\\x55\\xc8\\xd9\\x6c\\xc4\\xa0\\x49\\xd0\\xcd\\x94\\x91\\xd0\\xdd\\xcc\\x33\\x88\\xf6\\x46\\x3b\\x7d\\x03\\x2e\\x83\\xc1\\xbe\\x9f\\x44\\xde\\xc5\\x76\\x03\\x82\\xfa\\x35\\x09\\x9b\\x90\\xb5\\x82\\x2d\\x22\\xd6\\x5f\\x09\\x66\\x47\\x58\\x24\\x24\\x79\\x04\\xa2\\xa2\\xfd\\x3a\\x1b\\x07\\x8f\\xd1\\x17\\x36\\x60\\xc1\\x4b\\x4d\\xa5\\x63\\xa8\\x4a\\x49\\x02\\x2b\\x4b\\x64\\x4d\\x06\\xdb\\x42\\xb6\\xec\\xe2\\x3d\\x3e\\x83\\x07\\x97\\xc5\\x68\\xd0\\x3e\\xa3\\x1a\\x93\\xdf\\xa0\\x6e\\x2a\\xd4\\xc4\\x47\\xc9\\xc0\\xf2\\x32\\xd1\\xf2\\x09\\x54\\x95\\x44\\x1a\\x3a\\x0f\\xdd\\x9c\\xa2\\x9f\\x5f\\xf9\\xd2\\xfc\\xaa\\xfb\\xc5\\x28\\xa8\\x37\\x5f\\x7a\\x16\\x7a\\xdd\\x74\\xc6\\x0c\\xc1\\x66\\x47\\x66\\x00\\x79\\x9e\\xb6\\xb0\\x50\\x9b\\x0d\\x65\\x34\\x16\\xb3\\x22\\xbc\\x39\\xa7\\x84\\xad\\xd9\\xc3\\xa6\\x08\\xe0\\x75\\x72\\xad\\x5b\\xdd\\xc3\\x88\\x5e\\x82\\xd6\\x0b\\xb4\\x6a\\x17\\x43\\x3e\\x06\\x7b\\x26\\x7c\\x6d\\x4d\\xca\\x7e\\xe9\\x88\\x9e\\xa0\\x62\\xe0\\x82\\xa9\\x91\\xf7\\x8a\\x00\\xed\\x19\\xce\\x97\\x7e\\x4b\\x46\\x74\\x9d\\xcc\\x84\\x1c\\xe9\\x83\\x39\\xd1\\x01\\xc6\\xa1\\x44\\xe0\\xb7\\xa4\\xfa\\x1e\\x60\\xdc\\xf6\\x61\\x6c\\x30\\xd9\\x37\\xc1\\x07\\x1b\\x69\\x3b\\x1c\\xb3\\xc8\\xe2\\xaa\\xf5\\xe0\\x40\\x1c\\x33\\xec\\xa6\\x0d\\x32\\x2d\\xec\\x50\\x63\\x82\\xb1\\x38\\x46\\x4e\\xbc\\x0d\\xe8\\x46\\x52\\x55\\xc1\\x04\\x67\\x37\\xa6\\xc6\\xbd\\xe6\\x91\\xc3\\x3d\\x7f\\x91\\x96\\xf8\\x87\\x05\\x2b\\xaf\\x1b\\x8c\\x30\\xa8\\x63\\xc5\\x32\\x4d\\x05\\xc6\\x57\\x51\\xba\\x72\\x92\\xbc\\xa6\\xb1\\xaa\\x05\\xa9\\xf7\\x5a\\x3a\\x11\\xa5\\xf0\\xe3\\x98\\x3e\\xbf\\x88\\x9f\\x5e\\x14\\x35\\xb0\\x2f\\xf4\\x8e\\x88\\x7a\\x7a\\xd3\\xe3\\x81\\x6b\\xdc\\xf0\\xfd\\x05\\xfa\\x47\\x55\\x08\\x8e\\x4c\\xde\\x80\\xd5\\x46\\x08\\x16\\x0a\\x74\\xfa\\x97\\x7a\\x8c\\xd3\\xbf\\xb3\\x85\\x37\\xae\\x12\\x8b\\x1b\\xd8\\xd2\\x3b\\xf5\\x0e\\xe6\\xe1\\x22\\x67\\xfa\\x87\\x5a\\x7e\\x97\\xc1\\xd3\\x2f\\x6a\\xab\\x33\\xe2\\x49\\x56\\x58\\x28\\x1f\\x6d\\x7b\\x4d\\x4b\\xa5\\x53\\x1a\\xcb\\xc8\\x1b\\xc4\\x3f\\xc0\\x33\\xa8\\x16\\xf6\\x3a\\xec\\x5b\\xc6\\xc8\\x16\\x4e\\x63\\x6b\\x1a\\x43\\xba\\xe6\\x2a\\xd9\\xdb\\xde\\xfc\\x05\\x29\\x4f\\x4f\\x42\\x5c\\xa8\\x2d\\x63\\xc9\\x9f\\xc2\\xa8\\x9e\\xfa\\x62\\x5a\\x62\\x29\\x83\\x28\\x30\\x89\\xe3\\xac\\xbb\\x7e\\x77\\x51\\x98\\x07\\x57\\xde\\x91\\xf0\\x04\\xd9\\xf2\\xa4\\x8e\\x38\\x73\\x67\\xc0\\x4d\\x7a\\xdd\\x96\\x81\\x55\\xdd\\xfe\\x85\\x03\\x5c\\x4c\\x68\\x36\\x98\\x07\\x0c\\xa4\\x47\\x95\\xe2\\xd6\\xa6\\x44\\x8b\\x64\\x63\\x6c\\x0a\\xff\\x40\\x3a\\x25\\x9f\\x6c\\xf7\\xcd\\x7b\\x1a\\x46\\x20\\xf1\\x2b\\xdf\\xd5\\x35\\x9c\\xa3\\x4f\\xda\\x21\\xc2\\x37\\x73\\xd1\\x3d\\x22\\xe0\\xb7\\x76\\xfc\\x9e\\x6b\\x22\\xd1\\x43\\x7d\\xae\\xff\\x4e\\xe9\\xf0\\xa0\\x2b\\xec\\xc5\\xd2\\x0a\\x95\\x28\\xc4\\xc0\\xec\\x49\\x7c\\xd7\\x35\\x97\\x4e\\x9c\\x1c\\x7d\\xfe\\x44\\x3c\\xe7\\xca\\xfb\\xe8\\xac\\xbc\\x8f\\x7d\\xbf\\xb1\\x50\\xdc\\x92\\xec\\x10\\x9e\\x50\\x0d\\xd7\\x1f\\x37\\x94\\xb4\\x6d\\xaf\\xe7\\x2a\\xfb\\xf4\\x90\\x84\\x4d\\xb8\\x23\\xbf\\x3f\\xd7\\xdf\\x0f\\x3f\\xb6\\x79\\xf6\\x1c\\x1f\\xc3\\xaa\\x46\\xcd\\x97\\x73\\xb3\\xdf\\xce\\x3e\\x2e\\x7e\\xae\\xbf\\x1f\\x9c\\x36\\xcf\\x4e\\xf5\\x97\\x1f\\x8e\\x4d\\x53\\xee\\x3e\\x7f\\x7e\\x79\\x79\\x99\\xbf\\x2c\\xe6\\x45\\x75\\xf8\\x1c\\x78\\x9e\\x87\\x6b\\xfe\\xe0\\x7c\\x4f\\xd1\\xcb\\x9f\\x8b\\xf6\\xcb\\x0f\\x78\\xf4\\x6c\\x9d\\xed\\x0f\\x1f\\x17\\x7f\\xf9\\xb8\\xf8\\xb9\\x0c\\x9b\\xa3\\xb3\\x4f\\xb3\\xec\\xcb\\x0f\\x1f\\x83\\xc5\\x7e\\xbf\\xff\\xc1\\x49\\xbe\\xfc\\xf0\\xcb\\x7a\\xbe\\x5a\\x2f\\xe7\\x9b\\x55\\xe6\\x2e\\xe6\\xab\\x27\\x67\\x31\\x5f\\xfb\\x81\\xeb\\xcf\\x57\\x8b\\x2d\\xfe\\xef\\xea\\x6f\\x9e\\xb3\\x9c\\x07\\x6b\\x27\\x98\\x3f\\x6d\\x96\\xce\\x66\\x1e\\xac\\x9c\\xad\\x13\\xcc\\xfd\\xa7\\xc5\\x3f\\x7f\\xf8\\x4c\\x11\\x63\\xaa\\x1f\\x17\\x7f\\x79\\x78\\x1c\\xdb\\x45\\xd8\\x2c\\x35\\xa8\\xca\\xd3\\x53\\xd8\\xd8\\x06\\xaa\\xf9\\x70\\xef\\x6f\\xd9\\x83\\x4b\\x67\\x29\\xf6\\x60\\xdd\\x54\\xc5\\x37\\x24\\xf7\\xa1\\xe7\\x04\\xc7\\xa5\\xb9\\x3b\\xc8\\xa4\\x6e\\xb4\\xba\\x89\\xba\\x6a\\xaa\\xf9\\x2f\\xa6\\x68\\xee\\xd2\\x71\\x97\\x82\\xaa\\xc5\\x69\\x15\\x67\\xc8\\xa9\\xbe\\xfc\\xb0\\xf8\\x41\\x56\\x39\\xb3\\xca\\x50\\xee\\x6b\\xb7\\x6e\\x42\\xdc\\xac\\x09\\x0b\\x59\\xe3\\xbe\\xe5\\x18\\x29\\x69\\x69\\x59\\x95\\x5d\\x62\\xca\\xe8\\x1f\\xa8\\xfd\\xa3\\x01\\x1b\\x8f\\xfa\\xa4\\x5c\\xf0\\xa6\\x7b\\x8f\\xba\\xfb\\x86\\x3d\\xef\\xe3\\xb3\\xf9\\xaa\\x4e\\x2d\\x61\\xa8\\x3f\\x67\\x0b\\x55\\xf2\\x82\\x95\\x7d\\x05\\x0a\\xce\\x7e\\x2a\\xec\\x8a\\xc2\\x9e\\xd2\\x79\\xdf\\x11\\xb6\\x02\\x6d\\xd4\\x62\\xb1\\xa0\\xe3\\x2b\\x70\\xbc\\xbf\\x91\\x31\\xf6\\xcf\\xdc\\x73\\xb0\\x49\\x5a\\x1c\\x97\\xba\\xf9\\x71\\x3a\\x2f\\xe1\\x54\\x74\\xe7\\x29\\xed\\x05\\x83\\x5f\\xd8\\x96\\xad\\xe3\\x7b\\xe5\\xd4\\xfb\\x7a\\xb9\\x1f\\x0c\\xcb\\x12\\x85\\x55\\x78\\x8a\\x91\\xe0\\x06\\xd5\\x42\\xe5\\xb7\\x22\\x7e\\x68\\x0f\\xb8\\x76\\x89\\x2e\\x58\\x67\\xf2\\x55\\xac\\x12\\x8e\\xfe\\x8e\\x36\\xbe\\x9d\\x8f\\x2c\\x80\\xc3\\x89\\x4d\\x15\\xf2\\x63\\xf7\\x88\\xa9\\x61\\x0f\\xab\\x2e\\x5e\\x4d\\xac\\x07\\xa5\\x14\\xc8\\xad\\x73\\xeb\\xc5\\x80\\xcf\\x13\\xee\\x14\\xed\\x27\\xd0\\x9b\\xd5\\x47\\x29\\x2b\\xbc\\x25\\x7e\\xbf\\x71\\x34\\x6a\\xdf\\x0d\\xb4\\x84\\xf2\\x17\\x61\\xf3\\xed\\x92\\x06\\xf7\\xd3\\x90\\xef\\x3c\\x20\\x94\\x17\\x12\\xd6\\xcb\\xb1\\xb6\\x92\\xbd\\x5f\\x3d\\x65\\xe1\\xd1\\xe1\\xa1\\x85\\xda\\x6a\\x38\\x2f\\xa1\\x81\\x63\\x4c\\xef\\x99\\xdf\\xd1\\xa9\\x6c\\x45\\x5e\\x4d\\x31\\x5f\\xa3\\xcc\\xd5\\xef\\x18\\x9b\\xf6\\x37\\x5e\\x8f\\x5e\\x84\\x87\\x2e\\x2e\\xc8\\xc2\\xd3\\xe1\\x13\\x3a\\x3d\\xca\\x1b\\x6f\\xbb\\x6d\\xc1\\x3f\\x1f\\x8b\\xa2\\x46\\xd8\\x0a\\xa2\\xf9\\x7c\\xfe\\x00\\xe3\\xe0\\x97\\x1f\\xc0\\xe2\\x20\\x1f\\xe0\\xfb\\x95\\x8d\\x67\\xa6\\x92\\xe4\\x99\\x4b\\x66\\xad\\x4c\\x05\\xee\\x2d\\xa7\\xb7\\x7e\\xc6\\xc0\\xda\\x48\\xa9\\xb1\\x8d\\xe8\\x03\\x9d\\xc9\\x7b\\xa4\\xeb\\xc7\\x3f\\x57\\xc5\\x4b\\x8d\\x1e\\xae\\xf3\\x53\\xf8\\xfd\\x1e\\xdb\\xe6\\xe4\\xbc\\xe9\\xc0\\x6d\\xc5\\xd2\\xbe\\x77\\x42\\x96\\x1e\\x56\\xb2\\xee\\x77\\x25\\x5a\\xc2\\x41\\xf9\\x0a\\x45\\xf7\\xdb\\x96\\x4f\\x9b\\x03\\xcd\\x4d\\xa7\\x7f\\x30\\x40\\x13\\x46\\xb5\\xfc\\xa1\\x5d\\xec\\xf8\\x24\\x49\\x7a\\x30\\x87\\x3c\\x91\\x0d\\xd9\\x72\\xdb\\xe8\\x7a\\x91\\x0c\\x46\\x1a\\x66\\x4d\\x66\\x6e\\x58\\x7e\\x95\\xbf\\xa0\\x68\\x8b\\xec\\x7c\\xdc\\xe8\\xd4\\xc4\\xbe\\x51\\xde\\xd0\\x5e\\x92\\xdd\\x28\\x55\\x36\\xa7\\xfb\\x0b\\x34\\xd5\\xd2\\x79\\xb7\\x9e\\xf6\\xd2\\xfb\\x92\\xec\\x88\\xee\\xe9\\x41\\xfc\\xcf\\xe5\\xed\\xdd\\x13\\x2e\\xdc\\x4f\\x12\\x2a\\x44\\x87\\x3a\\xf9\\x1e\\xb5\\xf1\\x0c\\x04\\x33\\x07\\xd3\\xf7\\xa6\\x60\\xdc\\x65\\x9a\\x65\\xba\\xfc\\x21\\xd1\\x29\\x90\\xdd\\x6e\\x60\\xe1\\x1d\\x3d\\x55\\xd8\\xe1\\x1a\\xb5\\xbe\\x84\\xa1\\x71\\x74\\x28\\xa8\\xea\\xd0\\x57\\x7d\\xed\\xfb\\x2a\\xc5\\x42\\xf7\\x65\\xa5\\x38\\x7e\\xd7\\x50\\xb9\\x65\\x85\\xf6\\xa8\\xaa\\x50\\xc2\\x97\\xde\\x49\\x69\\x14\\xd6\\x29\\xee\\xa4\\x1e\\x8c\\xd8\\xde\\xef\\x68\\xe7\\x53\\x80\\x43\\x55\\xbc\\xec\\x7c\\x88\\x62\\x13\\x46\\x7c\\x07\\xd8\\x4f\\xe4\\x47\\x19\\x9e\\xd4\\xa3\\x5d\\x12\\x0c\\xd3\\x08\\x65\\x23\\xfd\\x29\\xfc\\x1e\\x85\\xd5\\x9b\\x36\\x5a\\x0c\\x6f\\x0a\\x9e\\x76\\xd5\\x04\\xdb\\xdf\\xa6\\xed\\x73\\x23\\x9f\\x29\\xdc\\x08\\x35\\x2f\\x08\\x9d\\x4c\\x36\\x2f\\x0a\\xab\\x9f\\xe6\\xb8\\x46\\x98\\x9e\\x50\\x35\\xd3\\x8b\\xdc\\x7d\\x76\\x4e\\xa7\\x4c\\x05\\x7f\\x97\\xe6\\xf1\\xb6\\xb8\\x51\\x85\\xc3\\x5a\\x30\\x8a\\x94\\x43\\x56\\x3f\\x80\\x63\\x56\\x3f\\x80\\x97\\x7c\\x07\\xce\\x66\\x9a\\x0f\\xb7\\xc8\\xac\\x09\\x26\\xb4\\x2f\\x1b\\x70\\x31\\x18\\x70\\x9a\\x03\\x1d\\xb9\\xb5\\xf2\\x06\\x77\\xca\\x78\\x11\\x2c\\xd0\\xd0\\x0d\\xf1\\x62\\x25\\xc3\\x69\\x3a\\x76\\x9f\\x09\\xdd\\x1d\\x2d\\x91\\x32\\xde\\x9f\\x23\\x4b\\x13\\x14\\xe5\\x4a\\xd0\\x71\\xb7\\x3b\\xcc\\x69\\xb2\\x30\\x24\\xf8\\x17\\x8c\\x0c\\xf9\\x3d\\x64\\x67\\xc6\\x6f\\xe4\\xe1\\xed\\x21\\x1f\\x65\\x2b\\x6d\\x6f\\x86\\x76\\xcb\\x08\\x74\\xfc\\xd7\\x70\\x4c\\xca\\xea\\xfb\\x75\\xc7\\x20\\xb0\\xa1\\x28\\x23\\x2f\\x1d\\xa1\\x8e\\x0c\\xd4\\x4d\\xe3\\xc2\\x70\\x0b\\x0c\\x9b\\x52\\xcd\\x57\\xc2\\xba\\xf6\\x1c\\x38\\x91\\xc7\\xd6\\x3a\\xc4\\x13\\x79\\x7d\\x2b\\xfb\\xd5\\x04\\xfb\\xfa\\x32\\x16\\x96\\x23\\x5f\\xa8\\xd5\\xcd\\xea\\x56\\x9b\\x15\\xb9\\x50\\x8b\\x71\\x4e\\x27\\xbe\\x64\\x1f\\x8d\\x66\\xf6\\xc0\\x97\\xcc\\x00\\x0e\\xa8\\xb9\\xe5\\x26\\x2f\\x15\\xf7\\x45\\xbf\\xe8\\x8a\\x1d\\x83\\x03\\x0b\\xa7\\x1e\\x15\\x51\\xc9\\x39\\xa2\\x09\\x01\\x2c\\x44\\x55\\xbc\\xa8\\xe6\\xa1\\x2a\\x5e\\xec\\x78\\x8c\\x23\\x99\\x4f\\x81\\x26\\x55\\xa7\\x7d\\x7a\\x91\\xa6\\xaf\\xf4\\x44\\x8b\\x1d\\x89\\xc1\\x04\\x01\\xdf\\xf1\\x64\\x5b\\x70\\xab\\x0a\\xc8\\x2e\\x4e\\x94\\x99\\x50\\x60\\x61\\x5a\\x3b\\x50\\x2e\\x18\\xf2\\x7f\\x4b\\xf3\\xb2\\xa8\\x9a\\xf0\\xd4\\x48\\x26\\x5d\\x28\\x36\\x19\\xae\\x2e\\xe0\\x62\\x86\\x6b\\xa0\\xe7\\xb8\\x05\\x92\\x23\\x1f\\x1d\\x1c\\x3e\\xca\\x8b\\xad\\x2d\\x5d\\xa8\\x62\\x13\\x19\\x3c\\xe6\\x80\\x41\\xb7\\x59\\x6f\\x00\\xdd\\xcf\\x13\\x4b\\x8f\\x4b\\x2f\\x6f\\x1e\\x74\\x9b\\xf5\\x16\\x24\\xfc\\x9b\\x0e\\xba\\x3c\\xb9\\xcf\\xa0\\x93\\xf1\\x4c\\x1e\\x74\\xd6\\xea\\x63\\x07\\x9d\\x8a\\xe4\\x8d\\x83\\x6e\\xb2\\x0a\\xdc\\x34\\xe8\\x04\\xa6\\x7f\\xbf\\x41\\x27\\x30\\x31\\x66\\xd0\\x61\\xf0\\xb7\\x0d\\xba\\xa7\\x27\\x1f\\xd0\\xfd\\xec\\x60\\xe9\\x71\\xe9\\xe5\\xcd\\x83\\xee\\xe9\\x29\\x00\\x09\\xff\\xa6\\x83\\x2e\\x3b\\xdc\\x67\\xd0\\xc9\\x78\\x26\\x0f\\x3a\\x6b\\xf5\\xb1\\x83\\x4e\\x45\\xf2\\xc6\\x41\\x37\\x59\\x05\\x6e\\x1a\\x74\\x02\\xd3\\xbf\\xdf\\xa0\\x13\\x98\\x18\\x33\\xe8\\x30\\xf8\\xdb\\x06\\x9d\\xef\\x3f\\x3d\\x01\\xca\\xdf\\x66\\x96\\x2e\\x97\\x5e\\xde\\x3c\\xea\\xfc\\xc0\\xf3\\x40\\xca\\xbf\\xe9\\xb0\\x6b\\xb3\\xfb\\x0c\\x3b\\x19\\xcf\\xe4\\x61\\x67\\xad\\x3e\\x76\\xd8\\xa9\\x48\\xde\\x38\\xec\\x26\\xeb\\xc0\\x4d\\xc3\\x4e\\x60\\xfa\\xf7\\x1b\\x76\\x02\\x13\\x63\\x86\\x1d\\x06\\x9f\\x32\\xec\\xe4\\xea\\xbf\\xa5\\x7e\\x9b\\x25\\x38\\x79\\x08\\xcb\\xd5\\xef\\x32\\x6a\\xde\\x32\\x64\\xde\\x3e\\x5e\\xee\\x39\\x58\\xa6\\xf4\\xf3\\x2d\\xc3\\xe4\\xf7\\x1f\\x23\\x53\\x06\\xc8\\xa4\\xd1\\xc1\\xab\\x66\\x74\\xc3\\x85\\xb4\\x10\\x4a\\x17\\xef\\xc5\\xe4\\x4d\\x4f\\x8f\\xb6\\x0a\\xca\\x8a\\x10\\x04\\x21\\xe6\\xdb\\x19\\x85\\x58\\xd6\\x0e\\xbd\\xe2\\x6a\\x54\\x45\\x2b\\x67\\x32\\xa4\\x89\\xc3\\xcd\\x28\\x42\\xea\\xe7\\x28\\x11\\xc3\\xc2\\x8a\\x81\\x7e\\x31\\xe8\\x3f\\xa8\\x8c\\x61\\x56\\xfc\\x2c\\x33\\x04\\x5a\\x1f\\x8b\\x17\\x1b\\x20\\xf8\\x39\\x67\\x94\\x88\\xb8\\x4a\\x42\\xc2\\x91\\xbf\\x77\\x49\\x79\\xc0\\x06\\xd0\\xd1\\xd5\\xc1\\x37\\xed\\x80\\x93\\xf6\\x28\\x2d\\xf0\\xff\\xff\\x30\\x62\\x6b\\x13\\xb0\\x55\\x90\\xf1\\xed\\xb0\\xff\\x9f\\xaf\\x1e\\x7f\\x60\\xef\\x68\\x34\\xf5\\xe5\\x87\\xa0\\x2b\\xc8\\xd2\\x13\\x8a\\xc3\\xf2\\xcb\\x0f\\x84\\xeb\\xae\\x38\\x4f\\x1b\\x54\\x65\\x69\\x9e\\x36\\x5f\\x7e\\xf0\\x3d\\xba\\x2b\\x6a\\xe9\\x6c\\x8e\\x41\\xf0\\xcb\\xd2\\xf1\\x57\\xf4\\x6f\\xb0\\x38\\x06\\x01\\xb0\\xc5\\x0e\\xee\\x27\\xd4\\x36\\x53\\x06\\x04\\x86\\x77\\xc2\\x49\\x82\\x25\\x35\\xac\\x63\\x87\\x81\\x8c\\x18\\xd6\\x49\\x58\\x7d\\x03\\xed\\x4b\\xf7\\xe9\\x13\\x86\\x52\\xc8\\x03\\x00\\x6a\\x22\\x59\\x18\\x99\\xd1\\x90\\x04\\xab\\xd5\\x8c\\xff\\x4f\\xec\\x3d\\x73\\x6d\\x1b\\x4b\\x03\\xc6\\x44\\x22\\xb6\\x19\\x45\\x0d\\x34\\x29\\x12\\x9e\\xc0\\x8a\\xc7\\x68\\x58\\x2c\\x24\\x15\\xbb\\x62\\x81\\x94\\xcc\\x8a\\x0e\\x67\\xfc\\x48\\x0c\\x33\\x0c\\x98\\x12\\x45\\x3c\\x80\\x41\\x91\\x20\\x7c\\x43\\x57\\xfc\\xab\\x5a\\x15\\xcc\\xb4\\xd3\\xff\\xe7\\x77\\xb3\\x2d\\x72\\x67\\x29\\xa6\\x65\\xd4\\x10\\x91\\xec\\x8b\\x45\\xc4\\x90\\x51\\x81\\x20\\xf4\\x61\\x1d\\x87\\x55\\xf2\\xa6\\x8f\\xe7\\x23\\xbf\\x6c\\xf6\\xb3\\x64\\xef\\xf9\\xa5\\xa8\\x12\\x1a\\x19\\x46\\x15\\x0a\\xbf\\xb9\\xf8\\xf7\\xc8\\x94\\x98\\xdd\\xae\\x9d\\xa1\\x8c\\x98\\x81\\x31\\x25\\x26\\x6e\\xf1\\x4f\\xc7\\x4a\\x3e\\xeb\\xe6\\xa9\\x07\\xd1\\x08\\xd4\\x9c\\x7c\\x70\\xd5\\x0e\\x9b\\x39\\x42\\x39\\xcb\\x83\\x38\\x9c\\x3b\\x63\\xe4\\x1e\\x1f\\x8d\\x6e\\x7f\\x52\\x4f\\x27\\xdb\\xbf\\xb3\\xe5\\x0d\\x91\\x29\\x03\\x27\\x3c\\x45\\xda\\x6e\\x54\\x24\\xaf\\x83\\x1b\\x48\\xf8\\xd7\\x52\\x5f\\xaa\\xda\\xa4\\x4d\\x86\\xd4\\x9d\\xe2\\x1b\\x01\\xa0\\x3e\\x47\\x12\\x0c\\xd9\\x7c\\xc3\\x77\\xa5\\xea\\x3b\\x45\\x09\\x4e\\xd4\\x36\\x62\\x3b\\x61\\xa8\\xc1\\x7d\\x61\\x1d\\xd4\\x8f\\xfd\\xa3\\xb4\\x0b\\x5d\\x6e\\x09\\x4b\\xca\\xd8\\x7d\\x14\\xe6\\x3b\\xc9\\x03\\x30\\xd7\\x81\\xa6\\xba\\xa2\\x26\\x7a\\x8b\\xc7\\x67\\xd3\\x5e\\x33\\x55\\x63\\x25\\xea\\x90\\x52\\x31\\x81\\x91\\xfd\\x88\\xec\\x4b\\xb5\\xeb\\xf8\\x65\\xfb\\xe8\\x00\\x45\\x9e\\xe3\\x49\\x08\\x7f\\x14\\xf4\\x67\\xac\\x0a\\x77\\x3d\\xbc\\x2f\\x8a\\xc6\\xdc\\x23\\x63\\x7b\\x40\\xce\\x7c\\x6a\\x68\\x3e\\x25\\x05\\x28\\x77\\xb7\\x09\\xd2\\x83\\x9a\\xab\\x17\\x49\\xad\\xa7\\xbb\\xfe\\xe4\\x03\\xae\\xf3\\x35\\x24\\x50\\x57\\x4e\\x69\\x41\\x8f\\x87\\x72\\x50\\x25\\xbd\\xb1\\x4c\\x82\\xec\\xe2\\xb2\\xd3\\x90\\xb0\\xb1\\xda\\x69\\x7e\\x70\\xb1\\xee\\x66\\xe1\\xeb\\xe0\\x56\\xe2\\x7e\\x2f\\x08\\xdd\\x22\\x02\\x8f\\xc4\\x34\\x3f\\x08\\x69\\xb1\\x9e\\x87\\xb4\\x47\\xe0\\xa3\\x29\\x4a\\xa0\\xa6\\x6a\\xcc\\x74\\x14\\x46\\xc3\\x66\\xa5\\x46\\x5b\\x03\\x10\\x84\\xec\\x98\\x99\\x28\\x60\\xd3\\x8c\\x64\\x13\\x24\\xe4\\x4b\\xbf\\xe3\\x39\\x1a\\x8e\\xdb\\xa1\\x2e\\x55\\x56\\x29\\x7f\\x55\\xb6\\x96\\x0d\\x09\\x3d\\x63\\xfa\\x42\\x1a\\xb0\\x8c\\x46\\x8a\\x94\\xa3\\xda\\x2b\\x25\\xbb\\x18\\x29\\xd1\\xd9\\x1a\\xdd\\xf0\\x9d\\x8f\\xed\\xc7\\xc7\\x67\\xf1\\x79\\xb2\\xcf\\x97\\xb6\\x6c\\x09\\x1c\\x76\\x4a\\x2c\\x59\\x60\\xcc\\x30\\xe3\\x98\\x9e\\x12\\x7f\\x27\\x29\\x31\\x03\\x78\\xa3\\x98\\x28\\x6b\\xa3\\xe5\\x04\\xd0\\xb4\\x75\\x31\\xec\\xde\\x84\\xda\\x3f\\x4a\\x7c\\x33\\x23\\xa0\\x64\\x5b\\x50\\xeb\\x98\\xc2\\x93\\x49\\x99\\x3c\\x6c\\x48\\x1d\\xd9\\x7e\\x58\\x76\\xcc\\x8e\\xc4\\xc2\\xec\\xc2\\x44\\x8e\\x74\\x8f\\x31\\x31\\xcf\\x85\\x05\\xa3\\xb9\\x89\\x37\\xe1\\x00\\x1b\\x38\\x84\\xa9\\x38\\x65\\xaf\\xa0\\x47\\x94\\x6c\\x3f\\x5c\\x63\\x1c\\xff\\x13\\x82\\xd4\\x61\\x3a\\xc3\\x42\\x9c\\x16\\x99\\x8a\\x04\\x47\\xa6\\xd2\\x15\\x18\\x03\\x72\\x62\\xdd\\x03\\xab\\xd6\\xde\\xd9\\xbd\\xd1\\x0a\\xe2\\xea\\x58\\x67\\xbc\\x53\\xb3\\x56\\x83\\xb6\\x8c\\x05\\xde\\x03\\xd6\\x8c\\x61\\xb8\\xf0\\xc3\\x42\\xf4\\xb7\\x1b\\x17\\xe7\\x53\\xb3\\x5b\\x3c\\x2b\\x3f\\x15\\xa8\\x43\\x58\\x76\\xfb\\x22\\xf5\\x22\\x90\\x47\\xdb\\xce\\x44\\xfa\\x61\\x09\\x4f\\x09\\x93\\xb8\\x3a\\xe7\\xd1\\x1d\\xcf\\xa7\\x74\\xf1\\xaa\\x1e\\xed\\xf9\\x74\\x57\\xe7\\xd0\\xfd\\x0c\\xd2\\x39\\x1d\\x55\\x3d\\x7b\\x9e\\x49\\x2c\\xfd\\xa3\\x5a\\xd0\\x9d\\xc3\\xb1\\x6e\\x9c\\xb5\\x7f\\x9e\\x51\\x92\\xbb\\x77\\xdb\\x33\\x3f\\x3f\\x8c\\xa0\\x4f\\xa6\\x46\\x1d\\x17\\xc6\\xfb\\x7c\\xde\\x8c\\x89\\xdd\\xca\\x23\\xd7\\x51\\x8e\\x72\\xf0\\x93\\x38\\x65\\x78\\x48\\x4f\\xa4\\xda\\xb0\\xa0\\x95\\x7d\\xd1\\x9a\\xb8\\x40\\xa9\\x94\\xe1\\x01\\x69\\x73\\x1b\\x87\\x16\\x6b\\xf3\\x3f\\x6f\\xdc\\xd9\\x1c\\x8b\\x8d\\xea\\xc9\\x89\\x16\\xbf\\xa7\\x66\\x37\\xaa\\x36\\xef\\xab\\x51\\x60\\x3d\\x2a\\x62\\xef\\x33\\xea\\x8c\\x38\\x34\\x62\\xb8\\xa9\\xbd\\xc7\\xcf\\x97\\x47\\x45\\x0a\\xb2\\xfe\\x41\\x27\\x0e\\x47\\x9e\\xce\\xb9\\x0a\\x48\\xcd\\x2b\\x4f\\xd0\\xc1\\x30\\x68\\x62\\xe6\\x97\\xad\\x72\\xe8\\x2e\\x58\\x0d\\x5d\\x7d\\x65\\x38\\xb4\\x28\\xf3\\xc6\\x97\\xd3\\xfa\\x82\\x31\\x77\\x63\\x8d\\x32\\x1f\\x4a\\x5f\\xb0\\x61\\x40\\xf6\\xbe\\x08\\x5d\\xa3\\x4e\\xb5\\xc7\\xec\\x48\\x9f\\xaf\\x60\\x8c\\xb6\\x61\\x60\\x52\\xfc\\xc5\\x80\\xde\\x2f\\xb8\\x52\\xc2\\xd4\\x26\\x8e\\x02\\x80\\x9a\\x0e\\x20\\x91\\xab\\x73\\xb0\\xbb\\x26\\x5d\\xac\\x05\\x23\\xbc\\xa5\\xb7\\x82\\x21\\x2b\\x61\\x64\\xff\\x26\\x9b\\x31\\x68\\x32\\xa8\\x63\\x0a\\x93\\x83\\xdd\\xeb\\xe0\\xfe\\xc2\\xdd\\xb5\\x54\\xcf\\x85\\x4b\\x29\\x3b\\x37\\x6a\\xca\\x4e\\x20\\x45\\x27\\x70\\x8b\\x8c\\x72\\xb2\\x20\\x0a\\x6b\\x44\\xaf\\x8d\\x83\\xbd\\x28\\x66\\x96\\x9e\\xff\\x55\\x3e\\xc5\\x47\\xcd\\xc9\\x61\\x6d\\xd1\\x0d\\x06\\x3f\\xc1\\xc7\\x10\\x90\\x45\\x18\\x75\\xcb\\xc3\\x5a\\x73\\xa9\\x6b\\x2d\\x63\\x25\\xb9\\xf9\\xa9\\x43\\x52\\xa5\\x79\\x58\\xbd\\x8e\\x3b\\x81\\x27\\x55\\xf9\\xf5\\x58\\xa1\\xfd\\xd7\\xee\\x02\\x10\\xe0\\x95\\x76\\x49\\xe3\\xe8\\x7b\\x6b\\xd6\\x41\\x1c\\x73\\x72\\xdd\\x5d\\xfb\\x63\\xee\\xd6\\xd7\\x2a\\x41\\x5c\\xaa\\x2f\\x6f\\xe5\\x73\\x1d\\x6f\\x56\\x9b\\xa4\\x23\\x29\\xdf\\xc3\\x6f\\xbb\\x75\\x5d\\xa9\\x02\\xf2\\x28\\xbd\\xba\\x95\\x43\\x1f\\x6d\\xd0\\x62\\xc9\\xc9\\x89\\xf7\\xb3\\xdb\\x2e\\xe9\\x16\\xe1\\x21\\xde\\x84\\xf2\\x9b\\x19\\xf3\\x37\\xe1\\x36\\xe2\\x84\\x94\\x7b\\xbc\\x7d\\xdf\\x37\\xde\\xda\\xac\\x54\\x81\\xd8\\x93\\x5f\\xc9\\x97\\x34\\xf9\\xfe\\x58\\x0e\\x93\\xc5\\x13\\xf2\\x3c\\x4e\\x4e\\xbe\\xdf\\xd9\\x76\\xab\\xaf\\x5c\\x03\\xe2\\x4f\\x7a\\x73\\x6b\\x07\\x46\\x49\\xe0\\x2f\\x3a\\xf6\\xa4\\xdb\\x7f\\x0d\\xdd\\xc7\\xaf\\xdd\\xed\\x2b\\x40\\xcc\\x89\\x2f\\x6e\\xee\\xba\\x10\\x79\\x48\\xe8\\x88\\x6a\\xe0\\x80\\x6f\\x77\\x29\\x6b\\x07\\x0f\\x77\\x5b\\x57\\x7e\\xb3\\xd6\\x25\\x81\\x1f\\x2c\\xaf\\xf3\\x7f\\x9c\\xf3\\xa8\\x68\\x2a\\x21\\xc9\\x73\\x60\\x98\\x34\\x05\\xe0\\xa2\\xbf\\x61\\x92\\xb4\\xb0\\xcf\\x43\\x75\\xaa\\x4b\\x4c\\x95\\x38\\x30\\x81\\xa7\\x51\\x5b\\xfa\\xd4\\x74\\x09\\xd7\\x79\\x98\\xa1\\xaa\\x01\\xbc\\xc6\\xa8\\x4f\\x3b\\x7e\\xef\\x65\\x27\\x1d\\xea\\x23\\x44\\xc9\\x47\\x81\\x7e\\xf8\\xb2\\xf3\\xa8\\xfc\\xa5\\x76\\x63\\xeb\\xc6\\xe3\\xdc\\xba\\x49\\x5a\\xe7\\x69\\x5d\\xa7\\x51\\x86\\x9c\\x79\\x9c\\x15\\xb5\\x29\\xa5\\x45\\xff\\x59\\xc0\\xd0\\x1c\\x90\\xb4\\xe2\\xdb\\x3c\\x6f\\xe9\\x6d\\x81\\x4b\\xc5\\x3f\\xc4\\x31\\x5a\\x69\\xf1\\x7b\\xb4\\x4d\\x42\\xec\\xf3\\x24\\x54\\xce\\xb1\\x12\\x43\\x15\\x06\\xfa\\xb4\\x8f\\x13\\x1d\\x54\\x6c\\x7f\\xc7\\x41\\xb0\\x59\\x05\\x1c\\x50\\x73\\x6c\\xcb\\xf5\\x32\\x5c\\x82\\x41\\xf5\\x06\\x6d\\x91\\x7a\\x5f\\x73\\x92\\x24\\x7b\\xa4\\x23\\x83\\x59\\x8c\\xf7\\x49\\x90\\xac\\x75\\x60\\x80\\xc9\\x00\\x2d\\xfc\\xc5\\xa2\\x03\\x95\\xbd\\x9a\\xbf\\x5a\\x6d\\x82\\x25\\x34\\xe6\\x97\\x28\\x49\\x54\\x16\\xe3\\x05\\x5a\\xc7\\x91\\x82\\x0a\\x66\\x30\\xf2\\x93\\x7d\\xa4\\x81\\x42\\x7d\\x18\\x05\\xc8\\xef\\xd8\\x13\\x5d\\x9a\\x17\\xaf\\x96\\x6b\\xe0\\x23\\xe5\\x87\\xc4\\x47\\xf1\\xde\\x57\\xe5\\x8b\\xd0\\x0a\\x45\\x22\\x1e\\x98\\xb1\\x30\\x4a\\x12\\x6c\\xcc\\x04\\x38\\x88\\xab\\x75\\x10\\xf7\\x9d\\xa6\\xf8\\xb3\\xed\\x6a\\xbd\\xf4\\xa0\\x4e\\xdb\\xef\\xf7\\x8b\\x38\\x51\\xef\\xe1\\xde\\x23\\x14\\x85\\x0a\\x2a\\x98\\xb7\\xfd\\x1e\\x6d\\x43\\x5f\\x05\\x05\\xd8\\x5b\\x2d\\x16\\x7b\\xaf\\x63\\x4f\\x76\\x66\\x9b\\xc0\\x8f\\x41\\x91\\xee\\xb7\\xc9\\x46\\x13\\xe9\\x7e\\x15\\x0b\\x22\\xa5\\x98\\x0c\\xcc\\xf9\\x91\\x17\\x6d\\x14\\x48\\x80\\xb7\\xe5\\x93\\x1f\\xf8\\x9b\\xde\\x5c\\x08\\x9e\\x6c\\xeb\\x6f\\xfd\\x6d\\x00\\xb1\\x86\\xf0\\x3f\\x95\\xb5\\x64\\x9f\\xec\\x91\\x84\\x08\\xe6\\x0c\\xc5\\x28\\xde\\xaf\\x65\\x40\\x80\\xb1\\xf5\\x16\\xff\\xeb\\x1b\\xd0\\xbb\\x31\\x3f\\xf2\\x51\\x00\\x39\\xd9\\x64\\x9d\\x6c\\x93\\x27\\x75\\x14\\xac\\xe3\\x6d\\x1c\\x8a\\x78\\x0c\\x43\\xe0\\x29\\x8a\\x22\\x24\\xc1\\x41\\x9a\\xb6\\xf4\\x56\\xde\\xea\\xfa\\x47\\xbe\\x44\\xf9\\x0d\\xbd\\xee\\xab\\x30\\x47\\xb5\\x53\\x56\\xc5\\xa1\\x42\\x75\\xed\\x46\\x61\\xe5\\xd6\\x4d\\x95\\x96\\xa8\\xbe\\xec\\xab\\x22\\xbf\\x40\\x69\\x33\\x7d\\x9a\\x56\\xa7\\x29\\xc0\\xb7\\x9e\\xe3\\x5d\\xaf\\x7f\\x7c\\x47\\xdc\\x73\\x8e\\x71\\x78\\x4d\\x4c\\xcc\\x4d\\xaa\\x5e\\x34\\x2a\\xcc\\x7b\\x37\\xf0\\x07\\x7a\\xfb\\x82\\xa6\\xd8\\xae\\xfb\\xdd\\x9e\\x31\\xe5\\x36\\xa8\\x31\\xcb\\x58\\x32\\x9f\\xac\\xff\\x13\\x7d\\x27\\x1a\\xbd\\x54\\xda\\x3d\\xe0\\x46\\xa2\\x53\\xf3\\x69\\xb9\\x4a\\xd0\\x61\\x06\\xec\\x73\\x5b\\x3d\\x3a\\xc1\\xea\\xe3\\x4c\\x70\\xf0\\xda\\xef\\x95\\xf7\\xd1\\x50\\xd3\\xfc\\x66\\xa3\\xe0\\x50\\x7e\\x3f\\xea\\xa7\\xe7\\xfb\\x8c\\x20\\x52\\x0b\\xc3\\x53\\x9a\\x87\\x0d\\x4a\\xba\\xe5\\x7a\\x5a\\x80\\xb5\\x07\\xd2\\x44\\xc7\\xe7\\x17\\x6a\\x3b\\xe9\\x69\\x9f\\x9e\\xd2\\x06\\x3d\\x4f\\xae\\x71\\x9d\\x93\\xc8\\x6d\\xb2\\x16\\xd8\\xae\\x05\\x63\\x38\\xd5\\xbd\\x46\\xec\\x4b\\xe8\\x55\\xd8\\x9b\\xf2\\x5b\\xa7\\xd8\\xb8\\xaa\\xfb\\x62\\xdc\\x90\\xd4\\x16\\xb7\\x28\\xc8\\x29\\x89\\xf4\\xfb\\x74\\x4d\\x38\\x78\\xdc\\x6e\\x78\\x2b\\x45\\xef\\x22\\xf2\\xf1\\xd7\\xe6\\x1a\\x30\\xcb\\xeb\\xef\\xec\\x1e\\x60\\x73\\x72\\x42\\x05\\xcb\\xf8\\x35\\x5a\\x5b\\x28\\x4d\\x73\\x2c\\x8d\\x5b\\x88\\xd5\\xf7\\x05\\xbd\\xdf\\x7e\\x3b\\xcb\\x96\\x3a\\x6d\\x9b\\xd7\\x1d\\x3e\\x64\\x6a\\x0d\\x01\\x55\\xc2\\xba\\x95\\x4d\\x81\\x15\\x2e\\x2e\\x56\\xb1\\x8c\\x4e\\x4b\\x49\\x76\\x82\\xaa\\x78\\x99\\xd6\\xdc\\xe3\\xc3\\x82\\x80\\x7a\\x9f\\x9d\\xeb\\xa3\\xb6\\xfb\\x4c\\xb9\\x04\\x44\\xde\\xd0\\xa0\\x4f\\xea\\x54\\x7c\\xb7\\x6c\\xce\\x04\\xf1\\xdc\\xb2\\xd9\\x12\\x32\\x1a\\x63\\xa7\\x58\\x6c\\x36\\x15\\x9a\\x10\\xcc\\xe8\\x85\\x65\\xe3\\xf0\\x9b\\xd1\\x30\\x35\\x33\\xbf\\xa7\\x37\\x0c\\xd8\\x89\\x31\\x24\\x03\\x40\\xca\\x37\\x12\\x43\\xbb\\xd9\\xd4\\xd0\\xc8\\x10\\xdf\\x2c\\x6f\\x27\\x36\\xd7\\xaf\\x00\\x87\\x14\\x93\\xf2\\xa0\\x28\\x26\\xe9\\x30\\x0d\\xf1\\xf8\\xb9\\x27\\x9b\\x66\\xea\\x2d\\xe8\\x50\\x98\\x98\\x37\\xd0\\xb0\\xa1\\x32\\xca\\xaf\\x87\\xb0\\x4a\\x50\\x45\\x34\\x08\\x26\\xfb\\x22\\x53\\x1f\\xb0\\xd9\\xb3\\x85\\xad\\x01\\x39\\xaa\\x70\\x76\\x49\\x72\\x3e\\x24\\x49\\xb2\\xce\\xd3\\x51\\x8f\\x9c\\xa0\\xb3\\xb9\\x38\\xd0\\x06\\x8a\\xc0\\xc8\\x3a\\x84\\xdf\\x8c\\xc6\\x2c\\x41\\xf6\\xde\\x2e\\x3f\\x09\\xc9\\x00\\x90\\xbc\\x3c\\x69\\x6a\\x37\\x5b\\x58\\x30\\x32\\x34\\x24\\x39\\x09\\x6a\\x60\\xf5\\x9c\\xf1\\x20\\xc9\\x8d\\x75\\x98\\x86\\x78\\xd4\\xca\\x05\\x5b\\xa4\\xd0\\x99\\xc7\\xb5\\x4d\\x2c\\xeb\\x98\\x0d\\x08\\x8c\\xb2\\x22\\x2f\\xad\\x82\\x12\\xaa\\xdb\\x20\\x64\\x23\\x69\\x6a\\x25\\x5b\\x62\\x81\\xf9\\x18\\x90\\x8f\\x00\\x32\\x60\\x1e\\x19\\x75\\xd9\\x3c\\xd2\\xee\\xd1\\xb0\\x8e\\x5f\\xc0\\x21\\x6b\\x35\\x3a\\xe7\\x0c\\x81\\x89\\x6b\\x10\\xbf\\x19\\x8d\\x51\\x50\\xfc\\xbd\\x55\\x56\\x32\\x92\\x01\\x20\\x49\\x62\\xb6\\x76\\x6f\\x43\\xdf\\xcc\\xf0\\x80\\xd0\\x64\\xa8\\x81\\xef\\x7a\\x8c\\x07\\x39\\x4d\\x3a\\xed\\x30\\x0d\\xf1\\xd8\\x95\\x2d\\xba\\x88\\xa5\\xb3\\x4f\\xeb\\x9b\\xd8\\x86\\xb0\\x1b\\x91\\x18\\x65\\xc6\\x5e\\x5b\\x45\\x26\\xa1\\xb0\\xc3\\x48\\x02\\x33\\xb7\\x98\\x2e\\xc6\\x99\\xb8\\x19\\x90\\x97\\x04\\x64\\x17\\x17\\xe7\\x40\\x12\\x17\\xeb\\x2a\\x0d\\xef\\xc8\\xc5\\x3e\\xba\\xae\\xa7\\xf3\\x4e\\xaa\\x9b\\x78\\x06\\x70\\x9b\\x50\\x18\\x45\\x45\\xdf\\x5a\\x25\\x25\\x22\\xb0\\x82\\xc8\\x03\\xcb\\xd4\\x56\\xb6\\x34\\x69\\x60\\x65\\x40\\x4c\\x22\\xcc\\xc0\\xa0\\x62\\xf4\\xe5\\x41\\x45\\x3b\\x09\\x90\\xfe\\x88\\x95\\x4f\\xb6\\xc8\\x09\\x29\\x58\\xf5\\xcd\\xac\\x57\\x2a\\x66\\x03\\x02\\xcb\\x60\\xaa\\xbe\\x0d\\x0d\\xa5\\xae\\xba\\x0d\\x42\\x0e\\x26\\x4c\\xad\\x64\\x4b\\xb4\\x30\\x1f\\x83\\x83\\xa8\\x52\\x93\\x3d\\x1b\\xc2\\x08\\x46\\x5d\\x0e\\x23\\x68\\xf7\\xb0\\xaf\\x64\\x34\\x5f\\x29\\x99\\x44\\x4a\\x1b\\xa5\\x56\\xea\\x15\\xb4\\xfa\\x7e\\x96\\x6e\\x62\\xe0\\xd1\\x45\\x97\\xee\\x56\\x00\\xbf\\x6c\\x1d\\x8f\\xe4\\x92\\xee\\x6e\\x19\\x98\\xaf\\x18\\x41\\x3e\\x7d\\xa7\\x3f\\x94\\xa9\\x8f\\x07\\xaf\\xde\\x74\\x48\\x36\\xab\\x2b\\xeb\\x12\\xf6\\x89\\x8f\\x2d\\xa3\\x78\\x86\\xac\\xa2\\x9e\\xe9\\x96\\x8d\\xeb\\x3c\\x2f\\x92\\x30\\x73\\x8b\\x12\\x9d\\x2e\\xca\\x4a\\x30\\x7b\\xd7\\xaf\\xe1\\xec\\xd3\\x16\\x25\\x03\\x67\\x8a\\xf8\\x94\\xdf\\xf7\\x56\\xfd\\xdd\\x58\\x94\\x79\\x65\\x9d\\x59\\xb8\\x90\\x83\\xd0\\x99\\xef\\xc3\\x04\\x39\\x8c\\x9f\\x24\\x0d\\xb3\\xe2\\x70\\x21\\x2b\\x9d\\x94\\x38\\x6f\\x00\\x29\\xda\\x17\\x55\\xee\\xcc\\x17\\xb5\\x83\\xc2\\x1a\\xb9\\xc5\\xb9\\x79\\x16\\x20\\x6f\\x85\\x98\\x0d\\x90\\xd0\\x5e\\x53\\x3c\\x59\\xd8\\xa0\\x4f\\xde\\xcc\\x0d\\x56\\x1f\\x1f\\x9f\\x2d\\xef\\x78\\x33\\x69\\xfe\\x72\\xa9\\x99\\x76\\xcc\\x9e\\x09\\xad\\xf7\\x28\\x8a\\x8f\\xe1\\xec\\xa4\\xe8\\xb6\\x5d\\x4f\\xf3\\x92\\x57\\x96\\xca\\x44\\x22\\xae\\x2f\\xd1\\xd1\\xf5\\x4a\\x72\\x58\\x93\\xdd\\x92\\x41\\xae\\x75\\x01\\x2f\\x2c\\xa7\\xa8\\xd8\\xfa\\xfb\\x6f\\x71\\x18\\x58\\xe1\\x42\\xbd\\x68\\xc5\\x60\\x06\\xb2\\xb4\\xdc\\xf5\\x29\\x85\\x07\\x0e\\x00\\x07\\xda\\xf1\\x5f\\xb2\\xc1\\x50\\x55\\x58\\x17\\x13\\x48\\xaa\\xa2\\xbc\\x75\\x84\\x2c\\xa1\\xc8\\xdd\\xf3\\x34\\xfc\\x64\\x64\\x88\\xb7\\xbb\\x28\\xaf\\xb1\\x46\\x5d\\x44\\x03\\x43\\xdf\\xb3\\x83\\xa8\\xf7\\x5c\\x7c\\x7f\\x53\\xb2\\x72\\x72\\x8a\\xcb\\x78\\x75\\x82\\xfc\\x4d\\xc9\\xba\\xa1\\x14\\xde\\x00\\x2a\\x37\\xdb\\x51\\x2c\\xa3\\x70\\x84\\x8c\\x9e\\x6f\\x73\\xc4\\xff\\x8a\\xc3\\x02\\x3a\\x89\\xac\\x5d\\x3a\\xde\\xc9\\xa0\\x48\\x5e\\x2d\\x37\\xd2\\x0e\\x9e\\x81\\x26\\x07\\xed\\x28\\x2a\\x76\\x4a\\xf6\\xbd\\xbe\\x98\\xa1\\x53\\x02\\x27\\xca\\xc2\\x2f\\x20\\x11\\xc9\\xe7\\x6d\\xbb\\x15\\x7e\\x91\\xd9\\x9f\\x80\\xdb\\x7b\\xc5\\x0d\\xd6\\x7c\\xe5\\x1a\\xa8\\x23\\xde\\xe2\\x2c\\x9d\\xf5\\x93\\xeb\\xd4\\x71\\x55\\x64\\x59\\x14\\x56\\x6e\\x8e\\xc2\\xfa\\x6c\\xbe\\xa0\\xe5\\xe9\\xe9\\xe9\\xa9\\x6c\\x99\\xe9\\x5a\\x61\\x73\\xc5\\x84\\x45\\x9e\\x3b\\xdf\\x43\\xf1\\x59\\x76\\x14\\x49\\xa6\\x51\\xc8\\x3b\\xed\\x79\\xbd\\xfe\\x2c\\x3c\\x45\\x65\\xea\\x5c\\x00\\x5d\\x60\\x50\\x5b\\x62\\x4d\\x5a\\x27\\x13\\xd1\\x6f\\x69\\x9d\\x79\\x53\\x14\\x59\\x93\\x96\\x96\\xbb\\x47\\x7d\\x6f\\xa3\\xde\\x39\\xd9\\xdd\\x64\\x44\\xa2\\x94\\x7d\\x98\\xa7\\xd9\\xeb\\x0e\\x3b\\xfa\\x0c\\xb9\\xf5\\x6b\\xdd\\xa0\\x7c\\xf6\\xe7\\x2c\\x3d\\x7d\\xfb\\x25\\x8c\\xff\\x4e\\x7e\\xfe\\x7b\\x71\\x6a\\x66\\x0f\\x7f\\x47\\x87\\x02\\x39\\xff\\xf5\\xd7\\x87\\xd9\\x7f\\x16\\x51\\xd1\\x14\\xb3\\x87\\xff\\x89\\xb2\\xef\\xa8\\x49\\xe3\\xd0\\xf9\\x0f\\x74\\x46\\x0f\\xb3\\x3f\\x55\\x69\\x98\\xcd\\xea\\xf0\\x54\\xbb\\x35\\xaa\\xd2\\xfd\\xec\\xe1\\x4f\\x18\\xa9\\xf3\\x33\\xb6\\x54\\xce\\x5f\\xf2\\xe2\\x1f\\xe9\\x43\\x8f\\x47\\x2f\\xf8\\xfb\\x6b\\x1e\\x15\\xd9\\x03\\x0b\\xa7\\xd8\\x91\\x8b\\x2a\\x0f\\xb3\\xc1\\x2b\\xfd\\x85\\x0f\\x63\\x58\\x91\\xc4\\xdf\\xd4\\x0e\\x81\\xe1\\x91\\x18\\x7c\\xf5\\x05\\xbd\\xef\\x24\\x65\\x19\\x6a\\xb0\\xfb\\xc0\\x26\\x0a\\x6b\\x3c\\x63\\x88\\xa4\\x95\\x20\\x19\\x25\\xa4\\x12\\x15\\x4a\\xda\\xa6\\x4c\\x8a\\xe8\\xae\\x68\\x52\\x91\\x8e\\x73\\x6d\\xd7\\x38\\x98\\xb1\\x42\\x30\\xe6\\x4c\\xe6\\x8a\\x15\\x7f\\xea\\x5e\\x38\\xf3\\xb0\\xaa\\x8a\\x17\\x40\\x27\\xa0\\xab\\x47\\x57\\x82\\xe6\\x63\\xdb\\x22\\x23\\xb1\\x5c\\x73\\x64\\xba\\x83\\x85\\xbf\\xa0\\xf2\\x23\\xc6\\xa0\\xe7\\x39\\xaa\\x5d\\xf6\\xe8\\xe2\\xd6\\xff\\xda\\xba\\x65\\x16\\xc6\\x28\\x47\\xa7\\xe6\\xff\\xfd\\xd2\\x14\\xe5\\xd7\\x19\\x04\\xda\\x60\\x97\\xc9\\x2c\\x0e\\xb6\\xbe\\xde\\x04\\x84\\xac\\x21\\x26\\xbc\\xbc\\xb3\\xfa\\xcf\\x2b\\x53\\x31\\xf3\\x2e\\x1a\\xa0\\xd0\\xf5\\xa4\\x74\\xa0\\x64\\x51\\xb6\\x52\\xf2\\x7b\\xda\\x75\\x9d\\x64\\x1c\\xd2\\xda\\x67\\x7d\\x9f\\x0a\\x71\\xfa\\xa3\\x38\\x25\\x46\\x12\\xee\\x56\\x9a\\xe7\\xaf\\x9b\\x0a\\x38\\xa2\\xfc\\xc7\\x20\\xb5\\x75\\x2d\\xbb\\xff\\x8f\\x76\\x2e\\x3f\\x2b\\x3c\\x1d\\xb7\\xb5\\x73\\x45\\x1a\\x6a\\xf7\\x12\\x1b\\x3f\\xa6\\x77\\xa5\\x1e\\xa6\\x41\\xc2\\xe4\\x3e\\xa6\\xca\\x03\\x77\\x32\\x3b\\x98\\x7a\\x8b\\xfa\\x32\\xb4\\xb6\\x6e\\xa6\\x20\\xbc\\x9f\\xd9\\x97\\xc6\\x1b\\x90\\x5b\\xfb\\x59\\x22\\x32\\x5d\\x8f\\x3d\\xde\\xcf\\xca\\x27\\xeb\\xc9\\xdd\\x8c\\x49\\xc1\\x9d\\x8c\\xdf\\xdc\\xa4\\xc8\\x04\\xa5\\xad\\x83\\x31\\x00\\xef\\x5e\\x16\\xa0\\xdf\\x80\\xda\\xda\\xbd\\x02\\x89\\xae\\x73\\x95\\x44\\x41\\xa3\\xb4\\x59\\xeb\\x67\\x12\\x0f\\x03\\xbd\\xec\\xa6\\xa7\\x13\\xaa\\x84\\x68\\x82\\xa4\\x12\\xee\\x62\\xba\\x45\\xd9\\x3a\\x5b\\x42\\xab\\x9b\\x19\\xe9\\x07\\x70\\xc0\\x79\\x88\\x69\\x83\\x57\\x51\\x92\\xd5\\x0a\\xd3\\xbe\\x62\\x6d\\x9e\\xb3\\xd6\\x23\\x96\\x8e\\x55\\x1c\\x76\\xfd\\xdf\\xc0\\xe5\\xff\\x9c\\xc0\\xe5\\x37\\x99\\x6a\\x77\\x3a\\x36\\x2d\\xf6\\x99\\x6f\\x85\\x7b\\xd7\\xe7\\x4b\\x00\\x11\\xbb\\x1b\\x72\\xa6\\x15\\x1b\\xc3\\x22\\x99\\xce\\xa4\\x20\\xc9\\x40\\xc3\\x34\\xe6\\x09\\xf7\\x06\\x86\\x47\\x56\\xc2\\x66\\x88\\x3d\\x1a\\xe3\\x31\\x00\\x14\\xc7\\x63\\x4a\\x02\\x80\\x89\\x68\\x3b\\x93\\x0b\\x63\\xd7\\xa3\\xb2\\xa9\\x98\\x55\\xc1\\x4d\\xa8\\xc8\\x4d\\xb5\\x95\\x35\\x1b\\x7e\\x20\\xe8\\x93\\x3d\\x1f\\xf3\\x8b\\xb7\\xb4\\x6a\\x24\\x73\\x1d\\x59\\x96\\x64\\x6a\\xab\\x67\\x85\\xda\\x2a\\x0b\\x24\\x54\\x47\\xa5\\xb1\\xb6\\x7a\\xbc\\x6f\\xc7\\x6b\\xdd\\xc7\\x19\\x24\\x09\\x94\\x3e\\x11\\x96\\x78\\x86\\xad\\x3f\\x38\\xae\\xff\\x38\\x8a\\x65\\xba\\xa3\\x6c\\x14\\x9f\\x3c\\x18\\x06\\x80\\x69\\x30\\x2c\\x2d\\x46\\x4c\\xd0\\x69\\x25\\x20\\x36\\xe1\\x57\\x03\\xe2\\xe9\\xb8\\xa7\\xe9\\xb5\\x21\\x96\\x1e\\x60\\xcf\\x46\\x63\\x30\\xe6\\x96\\x84\\x44\\x22\\x90\\x69\\xda\\x7e\\x2b\\xcb\\x8c\\x15\\x40\\x53\\xc4\\xa0\\xfe\\x36\\xf5\\x1e\\x2d\\x01\\xa0\\x17\\x29\\x47\\x46\\x05\\x87\\x26\\x1e\\xe3\\xf5\\xb9\\x9b\\x78\\x00\\xd0\\x6c\\xe2\\x21\\xc8\\x66\\x8a\\x42\\xab\\x73\\x0f\\x23\\x01\\x65\\xee\\x71\\x03\\xf2\\x69\\x2a\\x6d\\x9a\\xb7\\x0c\\x31\\x68\\xa3\\x32\\x62\\x82\\xa3\\xd9\\x9e\\x69\\x5a\\x7d\\x3b\\xd7\\x3c\\xf9\\x89\\x36\\xb6\\xa4\\x59\\xd4\\x6d\\x7a\\x3d\\x5e\\x0e\\x50\\x57\\x12\\x9e\\x86\\x14\\x5b\\x9e\\xeb\\x4d\\xd6\\x6c\\x87\\x43\\xf3\\x3c\\x95\\x63\\x7a\\x0e\\xae\\x62\\x9f\\x7e\\xac\\xbc\\x8f\\x60\\x88\\x18\\x78\\x5a\\xae\\x3b\\x0f\\x9c\\x87\\xe9\\x1f\\x28\\xf6\\x1b\\xfc\\x6f\\x64\\x7b\\xd9\\xdc\\x16\\x80\\x25\\x73\\x5b\\x79\\xc5\\x7b\\xc2\\x38\\x96\\x27\\xb8\\x06\\xf4\\xda\\x04\\x77\\x32\\xea\\x69\\x63\\x18\\x9e\\x1a\\xdb\\x99\\xb3\\x51\\x80\\x66\\xd0\\x46\\x9f\\x44\\x4d\\xed\\xb4\\xe1\\x7b\\x1b\\xc3\\xd2\\x5c\\x1e\\x70\\x8c\\x6f\\x19\\xba\\x63\\x3b\\x5f\\xef\\x41\\xc6\\xcf\\xd0\\xc0\\x15\\x17\\x0f\\xc4\\x61\\xab\\xa5\\xab\\x05\\x92\\xe5\\x74\\x1f\\xc1\\x84\\x7d\\x11\\xda\\x09\\x61\\x68\\x66\\x48\\x46\\x8c\\xe5\\x93\\x5f\\x84\\xff\\xd9\\xf3\\x84\\x2e\\x46\\xa7\\x09\\x5d\\x88\\xe9\\x3a\\x15\\x9b\\x01\\x25\\x06\\xe9\\xcd\\x4c\\xf2\\x0a\\x37\\x5f\\x3a\\xf4\\x42\\x52\\x92\\x15\\xe7\\x1a\\x65\\xfa\\xf7\\xbe\\xfe\\x1d\\x5b\\x8b\\x31\\x7d\\x53\\x27\\x67\\x80\\xb4\\x6d\\x16\\x7d\\x65\\xfb\\x91\\x19\\xb2\\x0c\\x30\\xfa\\xf3\\x9f\\x40\\xd1\\xbe\\x8d\\x62\\x4d\\xf7\\x38\\x18\\x36\\x48\\x8c\\x7a\\x0b\\x6d\\x9d\\xe0\\x15\\xf9\\x2b\\xac\\x1f\\xfb\\x30\\x46\\xee\\xf7\\xb4\\x4e\\xa3\\x34\\x4b\\x9b\\x57\\xbe\\x41\\xc1\\xf2\\x8a\\xd7\\x2e\\x51\\x55\\x97\\x28\\xa6\\xd7\\xf6\\x7a\\x74\\x81\\x4b\\x2b\\x52\\xba\\xd2\\x3d\\xa1\\xb6\\x99\\x29\\x65\\x65\\x85\\xbe\\x2b\\x65\\x86\\xdb\\xc1\\xc7\\xe1\\x32\\xf9\\x21\\xa8\\xbe\\x52\\x84\\xb5\\x1d\\x42\\xa9\\x14\\xd1\\xa9\\x8c\\x65\\x8f\\xc8\\xff\\xf3\\x09\\xde\\x22\\x82\\xcb\\xaf\\x7f\\xac\\xcf\\x65\\x59\\x54\\x4d\\xed\\x7c\\xfa\\xa4\\xe1\\x60\\x0b\\x16\\x65\\x85\\x6a\\x54\\x7d\\x47\\xee\\x22\\x79\\x74\\x8a\\xca\\xf9\\x64\\x03\\xa0\\xe9\\xff\\x7e\\x9b\\x96\\x2d\\x12\\x6a\\x4a\\xc1\\xe6\\x75\\x2f\\xaf\\x57\\x26\\x41\\x08\\xbd\\xca\\x06\\xe6\\xd6\\xde\\x99\\x78\\xc8\\x18\\xfa\\x93\\xbc\\x7a\\x97\\x2e\\xbd\\x5f\\x03\\x16\\x09\\x61\\xd3\\xd6\\x6d\\xdd\\x7b\\x53\\xcf\\x99\\xe4\\x67\\xef\\x38\\xd7\\xd2\\x73\\xee\\x6f\\xdc\\x75\\xb7\\xb4\\x60\\x91\\x50\\x36\\x6d\\x5d\\xe7\\x8a\\x7d\\xd7\\xa1\\xc7\\xf1\\x63\\x55\\x64\\xaa\\x91\\xe0\\xc5\\x36\\x3b\\xd1\\xef\\x0f\\xfa\\x7d\\xce\\x4a\\x33\\x37\\xb1\\xfa\\x68\\xff\\x40\\x20\\xed\\x5f\\x84\\x9a\\xdd\\xed\\x67\\x04\\x5f\\xd2\\xfd\\xa4\\x70\\xcf\\x18\\x6b\\x92\\x97\\xe3\\x12\\xd3\\x74\\x7b\\xb3\\x9e\\xc5\\x2f\\xe8\\xb0\\x20\\x84\\x54\\xc7\\x3a\\xa7\\x7d\\xd0\\x0c\\xbe\\x26\\xf7\\x95\\x18\\x58\\x1d\\xbc\\x3f\\x3d\\x10\\xb6\\xa5\\x90\\x67\\x61\\xb3\\xa6\\x78\\xc6\\x7b\\xfa\\x45\\xe9\\x36\\x86\\xde\\x74\\xb9\\xca\\xf0\\x45\\x2a\\xce\\x3e\\xcd\\xb2\\x2f\\x3f\\x7c\\x0c\\x16\\xfb\\xfd\\xfe\\x07\\xf9\\x36\\x96\\xad\\xb3\\x15\\x2f\\x5a\\x49\\xbe\\xfc\\xf0\\xcb\\x6a\\x1e\\xac\\x1c\\x2f\\x73\\x97\\x0e\\xfd\\xe7\\xcf\\x57\\x2e\\xfe\\x5f\\x40\\xff\\xe7\\xb0\\xbf\\x2e\\x2b\\xff\\x27\\x70\\x43\\x8a\\x59\\x30\\xff\\x62\\x6d\\x0d\\xe6\\x1b\\xd2\\x56\\x7f\\xbe\\xc2\\xed\\x74\\x84\\xf6\\x91\\x67\\x5e\\xbe\\x74\\xc9\\x3f\\x6b\\x5b\\xd3\\x53\\x92\\xc6\\x61\\x53\\x54\\x35\\x60\\x48\\x94\\xad\\x86\\x64\\x4a\\xab\\x7e\\x85\\x5b\\x4d\\xb0\\x2f\\x23\\xcc\\x06\\x7c\\x14\\x9e\\xa7\\x6b\\xff\\xa8\\x64\\x67\\xff\\xa8\\xa6\\x5d\\x05\\x5b\\xe6\\x64\\xa9\\x6d\\x2f\\x9d\\x27\\xed\\xa5\\xeb\\x7e\\xf1\\x5d\\x57\\xfd\\xd8\\x5a\\xf4\\x73\\xfc\\x4a\\x2d\\x20\\x0c\\xe1\\xdf\\xc4\\x8c\\xe0\\xbe\\x39\\x35\\x64\\xf7\\x18\\x74\\xc4\\x1c\\xbe\\x6c\\x07\\xe6\\x7c\\x60\\x5d\\xc2\\x15\\x85\\x32\\x90\\xc9\\xb8\\x4b\\xcf\\x21\\x2f\\x4d\\x98\\x29\\xd3\\x89\\x20\\xb4\\xa7\\x87\\x9d\\x9f\\x7f\\x27\\xda\\x3c\\x70\\x36\\x9c\\x0a\\xef\\x07\\x6a\\x58\\x92\\x44\\x08\\x26\\xcd\\xc5\\x0a\\xc2\\xb3\\x83\\x75\\xac\\xe2\\xc2\\xfe\\x1b\\x72\\xa7\\x70\\xb8\\x33\\x03\\xe1\\xfb\\xb6\\x2b\\x56\\xb4\\xb9\\xb0\\xeb\\x9c\\x7a\\x4a\\x9e\\x49\\xf2\\x62\\xc8\\x30\\xd9\\x5f\\x10\\xc9\\x6b\\x34\\x45\\xa9\\x02\\x37\\x45\\xa9\\xc3\\xe5\\x69\\x92\\x64\\x1a\\x5e\\x5a\\xaa\\x43\\xb3\\x05\\x5d\\x95\\x0b\\x52\\x0a\\xf0\\x80\\x9b\\x03\\x57\\x11\\x5e\\x19\\xea\\x41\\x0d\\x60\\xe5\\x62\\x8d\\xe8\\xd0\\x1d\\x0e\\x37\\x1d\\xd2\\x17\\xc0\\x43\\x01\\xbe\\x3b\\x4c\\x22\\x14\\x51\\xc7\\x6d\\x4a\\x45\\xa9\\xd0\\xed\\x0f\\x36\\x9b\\xd2\\x50\\xaa\\x94\\xf5\\x03\\xce\\x52\\xa1\\x89\\x3a\\x4d\\x30\\xa9\\x52\\x67\\x07\\x72\\x4d\\xc9\\x25\\x35\\xda\\xca\\xc1\\x5c\\xa1\\xc8\\x44\\x97\\xa6\\x8d\\x54\\xe8\\x92\\x63\\xa5\\xa6\\x94\\x91\\x2a\\x51\\xe9\\x78\\x29\\xff\\x6d\\x24\\x47\\x92\\x41\\x2a\\xe4\\xf8\\x11\\x49\\x53\\x22\\x48\\x95\\xa2\\x7a\\x54\\x52\\x28\\x32\\xd1\\xa5\\x29\\x1e\\x15\\xba\\xec\\x90\\x9f\\x29\\xbd\\xa3\\x4a\\x56\\x39\\xec\\xd7\\x97\\x98\\x88\\xd2\\xc4\\x8d\\x0a\\x51\\x7a\\x58\\xcd\\x94\\xef\\x44\\xa5\\x29\\x1f\\x5a\\xeb\\x0a\\x8c\\xcd\\x24\\xe9\\x18\\xb5\\x66\\x56\\xdf\\x00\\x58\\x9a\\x8a\\x51\\x6f\\xa4\\x70\\x04\\x8b\\xff\\x36\\x4a\\x93\\x24\\x59\\x54\\xa5\\x79\\x4c\\x1b\\x83\\xe9\\x55\\x20\\x85\\xd8\\x52\\x87\\x17\\x5e\\x4a\\xd5\\xc8\\x5a\\xdb\\x45\\x4f\\x74\\x4d\\xf7\\x81\\xeb\\xa0\\xae\\xc7\\x81\\x3d\\xe0\\x65\\x53\\x94\\x1d\\x00\\xcd\\xa0\\x01\\x00\\xd1\\x45\\x3d\\x4f\\x49\\xe8\\x01\\x00\\xb2\\xaf\\x10\\x9e\\x9a\\x4c\\x03\\x00\\x25\\x2b\\x8a\\x1d\\x20\\xf5\\x81\\x00\\x58\\x67\\xf7\\x80\\x1c\\x24\\x00\\xb8\\x60\\xae\\xe4\\xf3\\x7e\\xaa\\xa9\\xea\\x2a\\x70\\x0b\\x23\\x81\\x6b\\xd6\\x85\\x83\\x53\\xc3\\x20\\x9f\\x56\\x53\\x8d\\x02\\x87\\xed\\x46\\xb5\\x92\\xf2\\x4e\\x19\\xd1\\x1c\\x9c\\x0f\\x46\\x39\\xf1\\xa1\\x3a\\x10\\xbb\\xee\\xa3\\xa3\\x48\\x46\\xad\\x8e\\xa0\\x1e\\x75\\xf5\\x4d\\x81\\xd5\\x94\\xbf\\xe3\\x9a\\x6a\\xaf\\xc2\\xb3\\xd4\\xd7\\x44\\x4b\\x11\\x7c\\x5f\\x09\\x00\\x37\\x7c\\x37\\x89\\x70\\xf5\\xb3\\x3d\\xb5\\x0f\\x84\\xbd\\x12\\x7b\\x62\\xb0\\xde\\x70\\xc2\\x1f\\x88\\xc6\\xd8\\x5b\\x4f\\x8c\\x74\\x6c\\x6d\\xee\\xc9\\x90\\x4f\\x50\\x13\\x7b\\x6a\\x12\\x81\\x38\\xad\\xe2\\x0c\\x29\\x82\\x5b\\x79\\x1f\\x21\\x58\\x4f\\xbd\\xa0\\x44\\x04\\x8a\\x33\\x14\\x56\\xfb\\xb4\\xe5\\x21\\xae\\xfc\\x49\\x8f\\xbc\\xc5\\x11\\xd3\\x51\\x8a\\x54\\x13\\x17\\xcf\\x30\\xa4\\xd5\\x7e\\x11\\x67\\xe2\\xd2\\xd0\\x57\\x99\\xa9\\x43\\x20\\x34\\x3a\\x06\\xa7\\xf4\\x32\\xb8\\x0c\\x07\\x00\\x34\\x61\\x94\\xf5\\x14\\xc9\\x2f\\x00\\xc0\\xad\\x8a\\x17\\x19\\x08\\x97\\x40\\x80\\x31\\xca\\x32\\x05\\x12\\x17\\xc9\\xa0\\x78\\x9e\\x74\\xd3\\xcd\\xe8\\x42\\x0f\\x68\\x38\\x84\\x72\\x18\\x95\\x00\\x20\\x60\\x34\\x9f\\xb8\\x49\\xdc\\x3a\\x1f\\x92\\x58\\x9d\\x8f\\x11\\x5a\\x07\\x35\\x5a\\x6e\\x75\\x3e\\x2c\\xba\\x3a\\x1f\\x96\\x1e\\x87\\x19\\x23\\xc0\\x0e\\x76\\x94\\x0c\\xeb\\xfc\\x6d\\x62\\xec\\xfb\\xe4\\x5e\\x92\\x04\\x44\\xb9\\x59\\x6f\\x99\\x28\\xf3\\xc1\\xc1\\x97\\x8f\\x1a\\x7f\\xf9\\xe4\\x21\\x98\\x8f\\x18\\x85\\xf9\\x88\\x81\\x98\\x4f\\x18\\x8b\\xf9\\xa4\\xe1\\x98\\xbf\\x71\\x44\\xe6\\x77\\x1f\\x94\\x96\\x43\\x6a\\x89\\x9b\\x1d\\x86\\x44\\x99\\x1d\\xc6\\x88\\xb2\\x83\\x1a\\x2d\\xca\\xec\\x30\\x2c\\xca\\xec\\x30\\x2c\\x4a\\x0e\\x33\\x46\\x94\\x1d\\xec\\x28\\x51\\x66\\x87\\xb7\\x89\\xb2\\xef\\x93\\x77\\x14\\xa5\\x4f\\xce\\x01\\x10\\x59\\xb6\\xd9\\x90\\x2c\\xdb\\x6c\\x8c\\x2c\\x3b\\xa8\\xd1\\xb2\\x6c\\xb3\\x61\\x59\\xb6\\xd9\\xb0\\x2c\\x39\\xcc\\x18\\x59\\x76\\xb0\\xa3\\x64\\xd9\\x66\\x6f\\x93\\x65\\xdf\\x27\\x77\\x93\\xe5\\x3c\\xc1\\x13\\x92\\x53\\xa3\\x74\\x9d\\x22\\x35\\x26\\x71\\x02\\x79\\x31\\x54\\x51\\x7b\\xbb\\x47\\xad\\x48\\x7b\\x14\\xee\\x21\\x0d\\x51\\xb1\\xdf\\xc2\\xff\\x14\\xfd\\x32\\xa0\\xb0\\xa9\\xfa\\x75\\x8e\\xf2\\x08\\x87\\xf3\\xa8\\x2e\\x8b\\x53\\x9d\\x7e\\x87\\xae\\x85\\x81\\x76\\x8e\\x91\\xc5\\xd1\\x3e\\xcf\\x86\\xb6\\x89\\x43\\x45\\xab\\xdd\\xdb\\xc6\\x62\\x56\\x21\\x50\\x55\\xab\\x38\\x5a\\x09\\xf9\\xac\\x37\\xd3\\x01\\x49\\x01\\x50\\x9e\\x92\\xdc\\xd2\\xc0\\x8b\\x22\\xfa\\x07\\x8a\\x1b\\xe0\\xc5\\xf7\\x34\\x41\\xc5\\xf0\\xb7\\x49\\xb6\\x78\\x0c\\xad\\x13\\x77\\x17\\xef\\xee\\x3c\\xbd\\x49\\x6e\\xe0\\x47\\xaf\\x4f\\xfd\\xda\\xb8\\xb0\\x88\\xbb\\x0c\\xe6\\xdb\\xd5\\xc6\\x5f\\x2e\\x3e\\x02\\xd5\\xfc\\xb5\\xa9\\xda\\x6a\\x3d\\x0f\\x56\\x50\\x95\\x65\\xf4\\xba\\x00\\x6b\\x6c\\x40\\x70\\x3f\\x7a\\xf5\\x41\\x70\\xfa\\x41\\x8d\\x7c\\x07\\xc1\\xb6\\x06\\xc8\\x4f\\x21\\x19\\x1c\\x35\\x4d\\x85\\x62\\x8d\\xc8\\x5b\\x9a\\xba\\x02\\x42\\x45\\xdf\\x98\\xb1\\xa9\\xef\\x7b\\xc6\\xdc\\x0a\\x7d\\x47\\x55\\x8d\\x0c\\x0c\\xf2\\xd7\\x56\\x46\\x75\\x20\\x89\\x61\\x1b\\x09\\x19\\x62\\xa8\\x01\\x46\\x42\\x2f\\x55\\x28\\x5c\\x88\\xdb\\xdd\\xbd\\xa8\\xe2\\x03\\x5e\\x30\\x04\\xf4\\xb6\\x28\\x05\\x05\\x2d\\x04\\x91\\xa8\\xaf\\x04\\x3e\\xf4\\xe6\\x76\\x64\\x4d\\xed\\xb4\\x00\\x5c\\xe7\\xca\\x97\\x33\\x9a\\x41\\xe3\\x22\\x7f\\x64\\x23\\x65\\x02\\x56\\x30\\x43\\x83\\x02\\xa4\\x63\\x46\\xa7\\xe4\\xa2\\x65\\x7b\\x18\\xc2\\x2a\\x81\\xe8\\x38\\xe9\\x47\\x93\\x0b\\xf4\\x4d\\xd0\\x82\\x59\\x05\\xd0\\xf1\\xb2\\xac\\x20\\x17\\x30\\x93\\x88\\x05\\xb3\\x94\\x53\\xc4\\x46\\x20\\x24\\x2b\\x0b\\x0a\\xfe\\x24\\xad\\x9b\\x2a\\x8d\\xce\\x0d\\x1a\\x24\\x41\\xeb\\x8b\\x14\\x84\\x1d\\x16\\xaa\\x10\\x85\\xa3\\x7d\\x02\\x62\\x38\\x79\\x8a\\x09\\xa5\\x24\\x3d\\x8a\\x50\\x16\\x9f\\x86\\x0e\\x99\\xf9\\x53\\xc5\\x26\\x7e\\x01\\x33\\xa0\\xd4\\x65\\x26\\x22\\xec\\x3e\\x97\\x29\\x28\\xf5\\xcf\\x65\\x12\\x52\\xf3\\xd7\\x34\\xde\\x8f\\x15\\x6a\\xe2\\xa3\\xde\\x93\\xa4\\xd8\\x80\\x54\\x7b\\xcb\\x71\\x1a\\x86\\x18\\x09\\x1a\\xc0\\x71\\x26\\x55\\xb3\\xca\\x08\\x1c\\x63\\x3d\\x62\\x48\\x52\\xb6\\x61\\x26\\x23\\x55\\xa5\\xd5\\xe3\\x35\\x48\\xcc\\x3c\\xce\\x64\\xc4\\xda\\x28\\xeb\\x31\\xeb\\x43\\x4d\\x46\\x6d\\x1c\\x68\\x32\\x05\\x75\\x98\\xf5\\x04\\xc0\\xb1\\x06\\xd1\\x30\\x8d\\xb4\\x5e\\x9a\\x8a\\x8e\\x88\\xf2\\x84\\xf5\\xa4\\x23\\x60\\xd2\\x94\\x1a\\x65\\x7b\\xb2\\xff\\xba\\xc7\\x4a\\xd3\\xdd\\x13\\xf5\\xc3\\x2f\\x34\\x9c\\xb8\\x8a\\xf2\\x46\\xc2\\xa6\\x28\\x9d\\x80\\x0e\\xd6\\x3a\\x82\\xcf\\xa6\\x72\\x04\\xab\\xa4\\x6f\\x02\\x4e\\x48\\xe1\\x7a\\x8c\\xa0\\xb6\\x11\\x7c\\xaa\\xaa\\x09\\x28\\x0d\\xba\\x46\\xb0\\x9a\\x14\\x8d\\xe0\\xd4\\x6d\\x83\\x80\\xd5\\x68\\x20\\x08\\x5e\\xb3\\x7d\\x60\\x7d\\xaa\\x88\\x5e\\xea\\x55\\x58\\xf6\\x04\\xaf\\x2e\\x78\\xf3\\xca\\x23\\x95\\x41\\x7e\\xb7\\x30\\xaf\\xce\\xef\\x1f\\xe9\\x51\\xf6\\xde\\x35\\xd8\\xeb\\xd8\\xfe\\x0d\\xe2\\xbd\\x3a\\x7f\\x7b\\xc8\\x47\\x96\\x8b\\xef\\x12\\xf5\\x31\\x6e\\xde\\x3d\\xf0\\xcb\\xdf\\x31\\xf6\\xab\\xf3\\x77\\x09\\xff\\xb0\\x52\\xbc\\x53\\x04\\x58\\xe7\\xef\\x1f\\x04\\xd6\\xf9\\x7b\\xc7\\x81\\x9a\\x4c\\xef\\x11\\x0a\\xaa\\xc2\\x7c\\x6b\\x34\\x08\\x48\\xf1\\xcd\\x01\\x21\\x16\\xdf\\x3b\\xc5\\x84\\xf9\\x7b\\x85\\x85\\x9a\\xb0\\xee\\x19\\x19\\xaa\\x42\\xbb\\x57\\x70\\x08\\x08\\xef\\x6e\\xf1\\x21\\x34\\x06\\xef\\x1e\\x22\\x02\\x83\\xf0\\x3d\\xa2\\x44\\x40\\x6b\\xee\\x15\\x28\\xe2\\x16\\xdc\\x37\\x56\\xd4\\x34\\xf1\\x4e\\xe1\\xa2\\xaa\\x84\\x77\\x88\\x18\\x01\\xfd\\xbb\\x47\\xd0\\x08\\xda\\x8f\\xbb\\xc5\\x8d\\x80\\x32\\xdc\\x1e\\x3a\\x5a\\x3e\\x75\\x12\\xcc\\x79\\x72\\xb7\\xd8\\x31\\x4f\\xee\\x1f\\x3b\\x52\\xf6\\xde\\x35\\x76\\xec\\xd8\\xfe\\x0d\\x62\\xc7\\x3c\\x79\\x7b\\xec\\x48\\xbe\\x4f\\xdf\\x25\\x76\\x64\\xdc\\xbc\\x77\\xec\\x98\\x27\\xef\\x18\\x3b\\xe6\\xc9\\xbb\\xc4\\x8e\\x58\\x29\\xde\\x29\\x76\\xcc\\x93\\xf7\\x8f\\x1d\\xf3\\xe4\\x9d\\x63\\x47\\x5d\\xa6\\xf7\\x88\\x1d\\x55\\x61\\xbe\\x35\\x76\\x04\\xa4\\xf8\\xe6\\xd8\\x11\\x8b\\xef\\x7d\\x62\\x47\\xd2\\xa7\\xef\\x11\\x3b\\xea\\xc2\\xba\\x67\\xec\\xa8\\x0a\\xed\\x5e\\xb1\\x23\\x20\\xbc\\xbb\\xc5\\x8e\\xd0\\x18\\xbc\\x7b\\xec\\x08\\x0c\\xc2\\x77\\x88\\x1d\\x21\\xad\\xb9\\x57\\xec\\x88\\x5b\\x70\\xd7\\xd8\\x51\\xd7\\xc4\\x3b\\xc5\\x8e\\xaa\\x12\\xde\\x21\\x76\\x04\\xf4\\xef\\x1e\\xb1\\x23\\x68\\x3f\\xee\\x15\\x3b\\x42\\xca\\x70\\xd7\\xd8\\x91\\xef\\xad\\xa2\\x6a\\x76\\xb8\\x5b\\xec\\x98\\x1d\\xee\\x1f\\x3b\\x52\\xf6\\xde\\x35\\x76\\xec\\xd8\\xfe\\x0d\\x62\\xc7\\xec\\xf0\\xf6\\xd8\\x91\\x6c\\x88\\xbb\\x4b\\xec\\xc8\\xb8\\x79\\xef\\xd8\\x31\\x3b\\xbc\\x63\\xec\\x98\\x1d\\xde\\x25\\x76\\xc4\\x4a\\xf1\\x4e\\xb1\\x63\\x76\\x78\\xff\\xd8\\x31\\x3b\\xbc\\x73\\xec\\xa8\\xcb\\xf4\\x1e\\xb1\\xa3\\x2a\\xcc\\xb7\\xc6\\x8e\\x80\\x14\\xdf\\x1c\\x3b\\x62\\xf1\\xbd\\x4f\\xec\\x48\\xfa\\xf4\\x3d\\x62\\x47\\x5d\\x58\\xf7\\x8c\\x1d\\x55\\xa1\\xdd\\x2b\\x76\\x04\\x84\\x77\\xb7\\xd8\\x11\\x1a\\x83\\x77\\x8f\\x1d\\x81\\x41\\xf8\\x0e\\xb1\\x23\\xa4\\x35\\xf7\\x8a\\x1d\\x71\\x0b\\xee\\x1a\\x3b\\xea\\x9a\\x78\\xa7\\xd8\\x51\\x55\\xc2\\x3b\\xc4\\x8e\\x80\\xfe\\xdd\\x23\\x76\\x04\\xed\\xc7\\xbd\\x62\\x47\\x48\\x19\\xee\\x1a\\x3b\\x76\\x9b\\xb9\\x09\\xea\\x36\\xbb\\x5b\\xf0\\xd8\\x66\\xf7\\x0f\\x1e\\x29\\x7b\\xef\\x1a\\x3c\\x76\\x6c\\xff\\x06\\xc1\\x63\\x9b\\xbd\\x3d\\x78\\x24\\x3b\\xf0\\xef\\x12\\x3c\\x32\\x6e\\xde\\x3b\\x78\\x6c\\xb3\\x77\\x0c\\x1e\\xdb\\xec\\x5d\\x82\\x47\\xac\\x14\\xef\\x14\\x3c\\xb6\\xd9\\xfb\\x07\\x8f\\x6d\\xf6\\xce\\xc1\\xa3\\x2e\\xd3\\x7b\\x04\\x8f\\xaa\\x30\\xdf\\x1a\\x3c\\x02\\x52\\x7c\\x73\\xf0\\x88\\xc5\\xf7\\x3e\\xc1\\x23\\xe9\\xd3\\xf7\\x08\\x1e\\x75\\x61\\xdd\\x33\\x78\\x54\\x85\\x76\\xaf\\xe0\\x11\\x10\\xde\\xdd\\x82\\x47\\x68\\x0c\\xde\\x3d\\x78\\x04\\x06\\xe1\\x3b\\x04\\x8f\\x90\\xd6\\xdc\\x2b\\x78\\xc4\\x2d\\xb8\\x6b\\xf0\\xa8\\x6b\\xe2\\x9d\\x82\\x47\\x55\\x09\\xef\\x10\\x3c\\x02\\xfa\\x77\\x8f\\xe0\\x11\\xb4\\x1f\\xf7\\x0a\\x1e\\x21\\x65\\x78\\x43\\xf0\\x38\\x27\\x57\\x19\\xd3\\x53\\xfe\\xf4\\x56\\x63\\xfc\\x28\\xc7\\x11\\x18\\x80\\x66\\x34\\x10\\xee\\x3d\\xd6\\x41\\xc8\\x49\\x2a\\x0a\\x01\\x1f\\xde\\x02\\x77\\x55\\xe2\\x9a\\x75\\x3e\\xcc\\x40\\x9d\\x8f\\xe1\\x81\\x9f\\x0e\\x07\\xd9\\xb0\\x7e\\xa1\\xc7\\xb5\\xf3\\x64\\x98\\x8f\\x3c\\x19\\xc3\\x07\\x3f\\xda\\x3c\\x96\\x8f\\x7e\\xb5\\x97\\x48\\xe3\\x30\\xcc\\x47\\x76\\x18\\xc3\\x07\\x3f\\x97\\x3b\\x96\\x0f\\x61\\xe6\\x80\\xab\\xb7\\xd9\\x30\\x23\\x38\\x7e\\x1f\\x66\\x84\\x1f\\x2a\\x85\\x19\\x99\\xf3\\x33\\x65\\xd8\\x02\\x34\\x69\\xdc\\x9f\\x31\\xa3\\xbf\\x45\\x7c\\x1d\\x28\\x3f\\x81\\xa7\\x9f\\xc9\\x03\\xc1\\xf9\\x69\\x35\\xfd\\xfc\\x1a\\x08\\x4e\\x6e\\xe7\\x55\\x2e\\xeb\\x05\\x01\\xeb\\x26\\x8d\\xbf\\x09\\xf7\\xba\\xf2\\x9c\\xa1\\xb4\\x5c\\x18\\x88\\x42\\x9b\\xe4\\x37\\xd7\\x39\\xc1\\x4e\\xaf\\x3a\\xb4\\xdd\\x0e\\xac\\x5d\\x96\\xb5\\xf0\\x78\\x5d\\x7e\\xd5\\x9c\\x5c\\x7d\\xf8\\x5a\\xe1\\x85\\x27\\xa5\\x59\\x35\\xb4\\x82\\xa6\\x56\\x55\\x1a\\xf0\\xf8\\x78\\x99\\xd3\\x27\\x99\\x73\\xb9\\xaa\\xda\\x6c\\xd6\\xa4\\x9e\\x83\\xc0\\xbb\\x5e\\xe7\\x75\\xe5\\x16\\xa7\\xec\\x15\\x38\\x5b\\xc8\\xf4\\xb2\\x4f\\xd8\\xe7\\x0b\\xd7\\x95\\x69\\x47\\x2b\\x9f\\xc9\\x8d\\x52\\x78\\xaa\\xc6\\xd2\\xaa\\x7b\\x8f\\xca\\x7d\\x56\\x78\\x4a\\xd3\\x25\\x8a\\xc6\\xd0\\x6e\\x19\\x36\\xc7\\x5d\\x7a\\xaa\\x51\\xf3\\x69\\xe5\\x7d\\x7c\\x7c\\x06\\x0b\\xfb\\x53\\x8b\\x8c\\x55\\x97\\xe4\\x63\\x0a\\xa3\\x0c\\xed\\xd8\\xbd\\xf3\\xc0\\x1b\\xf2\\xa4\\x2a\\xb3\\x78\\x65\\x36\\x6b\\x13\\x79\\xee\\x9a\\x42\\x12\\x5b\\x67\\x88\\xb6\\x85\\xa6\\x2d\\xd4\\xaf\\xe4\\xd2\\x9b\\x40\\x72\\x9b\\xca\\x3f\\xaf\\xf3\\x17\\x37\\x58\\x5d\\x58\\x46\\xd1\\x95\\x94\\x53\\xe5\\xc5\\x5d\\x79\\x17\\x7e\\x61\\xad\\xf2\\x66\\xc3\\xeb\\x6c\\xd4\\x3a\\xbe\\xc7\\x2b\\xf9\\x9e\\x5c\\xeb\\x88\\x29\\xf1\\x84\\xa5\\x2b\\xe5\\xd5\\xca\\xbb\\x74\\x57\\xec\\x2a\\xaf\\x36\\x5d\\xad\\x8d\\x5a\\x0b\\x13\\x13\\x8e\\x8e\\x8a\\x2f\\x73\\xca\\x4a\\x7f\\x39\\x9c\\x06\\x70\\xec\\x00\\x4c\\x28\\x5c\\xef\\xc2\\xaf\\xc3\\x95\\xca\\x1b\\xd7\\x9b\\xcd\\xf3\\xd7\\xee\\xb5\\x9e\\x83\\x2a\\xaf\\x08\\x48\\xdb\\x83\\x00\\xf9\\xa7\\xf2\\x48\\xc5\\x03\\xa5\\x9e\\xca\\x33\\x15\\x95\\x9e\\x77\\x2a\\x77\\x7d\\xce\\xa9\\x9e\\x47\\x27\\x6f\\x5c\\x9f\\x90\\xf1\\xa5\\xfb\\x5e\\x74\\xb8\\x8a\\xc0\\xb5\\x3d\\x9c\\x78\\x87\\xb2\\xc2\\xb8\\x82\\x91\\xdf\\xf4\\xa5\\x83\\x66\\x2a\\x52\\xe1\\x2e\\x67\\xb9\\x09\\x41\\xd7\\x04\\xa0\\x05\\x01\\xa1\\x17\\x48\\x2d\\x00\\x1a\\x10\\x10\\x5a\\x81\\xd2\\x00\\x80\\x7f\\x05\\x1f\\xe7\\x1f\\x60\\x5f\\x41\\x49\\xd9\\xd7\\xb9\\x5f\\x70\\xee\\x7d\\x9d\\xf9\\x05\\x21\\xb6\\x10\\x99\\xd7\\xa0\\x2a\\x02\\xd5\\xf6\\x50\\x2c\\x99\\xa5\\xce\\xba\\x82\\x8d\\xa7\\x69\\xd5\\x39\\x57\\x10\\xd2\\x3c\\x98\\x1a\\xe3\\xcb\\x8e\\x71\\xa8\\xdf\\x97\\x84\\xd8\\x52\\x62\\x1d\\xea\\xf8\\x25\\xa1\\xb5\\x54\\x98\\x87\\x7a\\x5e\\xc1\\xc8\\xd9\\x87\\xba\\x5e\\x41\\x4a\\x1b\\x00\\xf4\\xfd\\x8a\\x37\\x61\\xa1\\x37\\x60\\x45\\xc8\\xad\\xc4\\x06\\x68\\x50\\x15\\x81\\x6a\\x7b\\x28\\x96\\xe8\\x55\\x67\\x5e\\xc1\\xc6\\x98\\xd7\\x00\\x33\\x15\\x21\\x4d\\x14\\xab\\x80\\x95\\xae\\xd7\\xdf\\x4b\\x2a\\xbd\\x20\\x06\\xa6\\x7c\\xed\\xdf\\xeb\\x16\\xa6\\x24\\x16\\xa6\\x6c\\x05\\x18\\xc0\\xc4\\x94\\x91\\x86\\x09\\xb2\\x31\\x65\\xa6\\x21\\xd3\\x8d\\x4c\\xe9\\xfa\\xfd\\xcd\\x16\\xda\\xf8\\x2d\\x89\\x95\\x29\\x5f\\x7b\\x20\\x83\\x99\\x29\\x89\\x99\\x29\\x5b\\x01\\xd0\\x64\\x67\\xca\\x48\\xc3\\x69\\x34\\x34\\x65\\xa6\\xa1\\x35\\x58\\x9a\\xd2\\x0d\\xe4\\x1b\\x3a\\x94\\x66\\x04\\x84\\x64\\x20\\x37\\x03\\x68\\x45\\x40\\xc8\\x05\\x6a\\x2b\\x80\\x46\\xa8\\x18\\x4d\\xd6\\xa6\\xcc\\x34\\xa4\\xb0\\xb9\\x29\\xdd\\x45\\xd7\\x04\\x75\\x44\\x97\\xc4\\xde\\x94\\xaf\\x3d\\x08\\x68\\x70\\x4a\\x62\\x70\\xca\\x56\\x00\\x83\\x2d\\x4e\\x19\\x69\\xf8\\x0c\\x26\\xa7\\xcc\\x34\\x94\\xa0\\xcd\\x29\\xdd\\x65\\xcf\\x3d\\x24\\x81\\x25\\xa1\\xb7\\x94\\xf9\\x87\\x44\\xb0\\x24\\xe4\\x96\\x6a\\x0b\\x20\\x19\\xa8\\x38\\x8d\\x76\\xa7\\xcc\\x34\\xb4\\x06\\xc3\\x53\\xba\\xab\\xae\\x1d\\xda\\xd8\\x26\\x96\\xa7\\x7c\\xed\\x41\\x40\\xd3\\x53\\x12\\xd3\\x53\\xb6\\x02\\x18\\x6c\\x7b\\xca\\x48\\xc3\\x67\\x30\\x3e\\x65\\xa6\\xa1\\x04\\xad\\x0f\\x3b\\x8c\\xc0\\x2c\\xa7\\xba\\x60\\x93\\x37\\xe4\\x35\\x31\\x77\\x02\\x1c\\x69\\x84\\x06\\x5b\\x71\\xd8\\x56\\x82\\xad\\xba\\xd0\\x55\\xb1\\xa2\\x20\\x66\\xd6\\x1c\\x0d\\x3c\\x83\\x91\\x93\\x36\\x29\\xc0\\xe6\\x65\\x84\\x1c\\x4f\\xfc\\x8d\\xd1\\x1c\\x7e\\x47\\xf8\\x11\\x80\\xc0\\x98\\x8e\\x01\\xb6\\x12\\x20\\x1c\\xd9\\x81\\x38\\x0d\\xf1\\x1d\\x88\\x16\\x8a\\xf2\\xea\\xa1\\x40\\x0f\\x03\\x70\\xaa\\xc3\\xe1\\x1e\\x83\\x6e\\x25\\x68\\x4b\\xd0\\x07\\x62\\xb7\\x85\\x7e\\x20\\x01\\x63\\x00\\x58\\x0f\\xc4\\x80\\xf8\\x3d\\x27\\x3f\\x18\\x09\\x32\\xe0\\x56\\x02\\x36\\xc7\\x83\\x20\\x6e\\x4b\\x54\\x08\\xa2\\x37\\xc5\\x86\\xb5\\x3d\\x3c\\xc4\\xaf\\x39\\xed\\xa1\\x20\\x91\\xc1\\xb6\\x12\\xac\\x31\\x54\\x04\\x31\\x9b\\x03\\x46\\x10\\xb9\\x21\\x6c\\xac\\x87\\x22\\x47\\x0c\\xc0\\x69\\x0f\\xc7\\x8f\\x0c\\xba\\x95\\xa0\\x2d\\x51\\x24\\x88\\xdd\\x16\\x4b\\x82\\x04\\x8c\\x11\\x65\\x6d\\x0f\\x2a\\xf1\\x6b\\x4e\\x7d\\x28\\xb4\\x64\\xb0\\xad\\x04\\x6b\\x0c\\x30\\x41\\xcc\\xe6\\x30\\x13\\x44\\x6e\\x08\\x36\\x89\\x71\\x31\\xc5\\x9b\\xd4\\x04\\x95\\xaf\\x12\\x14\\x18\\x75\\x32\\xc8\\x56\\x86\\x84\\x63\\x4f\\x18\\xab\\x21\\x02\\x85\\x11\\x43\\x71\\x28\\xb1\\x26\\xd6\\x50\\x94\\x1a\\x9e\\xf2\\x55\\x02\\x35\\x07\\xa4\\x0c\\xbc\\x95\\xc1\\x2d\\x61\\x29\\x8c\\xdf\\x16\\x9c\\xc2\\x24\\x8c\\x21\\x2a\\x31\\x2b\\xb6\\x28\\x95\\x1a\\xa0\\xf2\\x55\\x82\\x34\\xc6\\xaa\\x0c\\xba\\x95\\xa1\\xcd\\x11\\x2b\\x8c\\xdd\\x12\\xb7\\xc2\\x04\\x4c\\xd1\\x2b\\xb1\\x2f\\x96\\x00\\x96\\x1a\\xa2\\xf2\\x55\\x02\\x34\\x85\\xb1\\x0c\\xb8\\x95\\x81\\x8d\\xc1\\x2c\\x8c\\xdb\\x1c\\xd2\\xc2\\xe8\\x0d\\x81\\x2d\\x31\\x2e\\xd6\\xd8\\x96\\xda\\xa1\\xf2\\x55\\x02\\x35\\x47\\xb8\\x0c\\xbc\\x95\\xc1\\x2d\\x71\\x2e\\x8c\\xdf\\x16\\xed\\xc2\\x24\\x8c\\x31\\x2f\\xb1\\x34\\x96\\xb0\\x97\\x9a\\xa4\\xf2\\x55\\x02\\x34\\x05\\xbf\\x0c\\xb8\\x95\\x81\\x8d\\x21\\x30\\x8c\\xdb\\x1c\\x08\\xc3\\xe8\\x0d\\xe1\\x70\\x3d\\x18\\x11\\x33\\x08\\x6e\\x9f\\x47\\xc4\\xc5\\x7d\\x8d\\x56\\xad\\x61\\x8c\\x8e\\x2d\\x54\\xcc\\x31\\xb2\\x85\\x10\\x14\\x29\\x5b\\xbe\\x74\\xe5\\x6e\\x9e\\x98\\x43\\x65\\xfc\\x8e\\x70\\x26\\x00\\x81\\xa1\\x32\\x03\\x6c\\x25\\x40\\x38\\x54\\x06\\x71\\x1a\\x42\\x65\\x10\\x2d\\x14\\x2a\\xe7\\xc9\\x40\\xa8\\x8c\\x01\\x38\\xd5\\xe1\\x50\\x99\\x41\\xb7\\x12\\xb4\\x25\\x54\\x06\\xb1\\xdb\\x42\\x65\\x90\\x80\\x31\\x54\\xce\\x13\\x7b\\xa8\\x8c\\xdf\\x73\\xf2\\x83\\xa1\\x32\\x03\\x6e\\x25\\x60\\x73\\xa8\\x0c\\xe2\\xb6\\x84\\xca\\x20\\x7a\\x53\\xa8\\x9c\\x27\\xd6\\x50\\x19\\xbf\\xe6\\xb4\\x87\\x42\\x65\\x06\\xdb\\x4a\\xb0\\xc6\\x50\\x19\\xc4\\x6c\\x0e\\x95\\x41\\xe4\\x86\\x50\\x39\\x4f\\x06\\x42\\x65\\x0c\\xc0\\x69\\x0f\\x87\\xca\\x0c\\xba\\x95\\xa0\\x2d\\xa1\\x32\\x88\\xdd\\x16\\x2a\\x83\\x04\\x8c\\xa1\\x72\\x9e\\x58\\x43\\x65\\xfc\\x9a\\x53\\x1f\\x0a\\x95\\x19\\x6c\\x2b\\xc1\\x1a\\x43\\x65\\x10\\xb3\\x39\\x54\\x06\\x91\\x1b\\x42\\x65\\x62\\x5c\\x4c\\xa1\\x32\\x35\\x41\\xe5\\xab\\x04\\x05\\x86\\xca\\x0c\\xb2\\x95\\x21\\xe1\\x50\\x19\\xc6\\x6a\\x08\\x95\\x61\\xc4\\x50\\xa8\\x4c\\xac\\x89\\x35\\x54\\xa6\\x86\\xa7\\x7c\\x95\\x40\\xcd\\xa1\\x32\\x03\\x6f\\x65\\x70\\x4b\\xa8\\x0c\\xe3\\xb7\\x85\\xca\\x30\\x09\\x63\\xa8\\x4c\\xcc\\x8a\\x2d\\x54\\xa6\\x06\\xa8\\x7c\\x95\\x20\\x8d\\xa1\\x32\\x83\\x6e\\x65\\x68\\x73\\xa8\\x0c\\x63\\xb7\\x84\\xca\\x30\\x01\\x53\\xa8\\x4c\\xec\\x8b\\x25\\x54\\xa6\\x86\\xa8\\x7c\\x95\\x00\\x4d\\xa1\\x32\\x03\\x6e\\x65\\x60\\x63\\xa8\\x0c\\xe3\\x36\\x87\\xca\\x30\\x7a\\x43\\xa8\\x4c\\x8c\\x8b\\x35\\x54\\xa6\\x76\\xa8\\x7c\\x95\\x40\\xcd\\xa1\\x32\\x03\\x6f\\x65\\x70\\x4b\\xa8\\x0c\\xe3\\xb7\\x85\\xca\\x30\\x09\\x63\\xa8\\x4c\\x2c\\x8d\\x25\\x54\\xa6\\x26\\xa9\\x7c\\x95\\x00\\x4d\\xa1\\x32\\x03\\x6e\\x65\\x60\\x63\\xa8\\x0c\\xe3\\x36\\x87\\xca\\x30\\x7a\\x43\\xa8\\xcc\\x4f\\x23\\x9b\\x43\\x65\\x06\\xc1\\xed\\xf3\\x88\\x50\\xb9\\xaf\\xd1\\xaa\\x35\\x8c\\xa1\\xb2\\x85\\x8a\\x39\\x54\\xb6\\x10\\x1a\\x19\\x2a\\xf3\\xcd\\x58\\xb9\\x9b\\x1d\\xcc\\xa1\\x32\\x7e\\x47\\x38\\x13\\x80\\xc0\\x50\\x99\\x01\\xb6\\x12\\x20\\x1c\\x2a\\x83\\x38\\x0d\\xa1\\x32\\x88\\x16\\x0a\\x95\\xb3\\xc3\\x40\\xa8\\x8c\\x01\\x38\\xd5\\xe1\\x50\\x99\\x41\\xb7\\x12\\xb4\\x25\\x54\\x06\\xb1\\xdb\\x42\\x65\\x90\\x80\\x31\\x54\\xce\\x0e\\xf6\\x50\\x19\\xbf\\xe7\\xe4\\x07\\x43\\x65\\x06\\xdc\\x4a\\xc0\\xe6\\x50\\x19\\xc4\\x6d\\x09\\x95\\x41\\xf4\\xa6\\x50\\x39\\x3b\\x58\\x43\\x65\\xfc\\x9a\\xd3\\x1e\\x0a\\x95\\x19\\x6c\\x2b\\xc1\\x1a\\x43\\x65\\x10\\xb3\\x39\\x54\\x06\\x91\\x1b\\x42\\xe5\\xec\\x30\\x10\\x2a\\x63\\x00\\x4e\\x7b\\x38\\x54\\x66\\xd0\\xad\\x04\\x6d\\x09\\x95\\x41\\xec\\xb6\\x50\\x19\\x24\\x60\\x0c\\x95\\xb3\\x83\\x35\\x54\\xc6\\xaf\\x39\\xf5\\xa1\\x50\\x99\\xc1\\xb6\\x12\\xac\\x31\\x54\\x06\\x31\\x9b\\x43\\x65\\x10\\xb9\\x21\\x54\\x26\\xc6\\xc5\\x14\\x2a\\x53\\x13\\x54\\xbe\\x4a\\x50\\x60\\xa8\\xcc\\x20\\x5b\\x19\\x12\\x0e\\x95\\x61\\xac\\x86\\x50\\x19\\x46\\x0c\\x85\\xca\\xc4\\x9a\\x58\\x43\\x65\\x6a\\x78\\xca\\x57\\x09\\xd4\\x1c\\x2a\\x33\\xf0\\x56\\x06\\xb7\\x84\\xca\\x30\\x7e\\x5b\\xa8\\x0c\\x93\\x30\\x86\\xca\\xc4\\xac\\xd8\\x42\\x65\\x6a\\x80\\xca\\x57\\x09\\xd2\\x18\\x2a\\x33\\xe8\\x56\\x86\\x36\\x87\\xca\\x30\\x76\\x4b\\xa8\\x0c\\x13\\x30\\x85\\xca\\xc4\\xbe\\x58\\x42\\x65\\x6a\\x88\\xca\\x57\\x09\\xd0\\x14\\x2a\\x33\\xe0\\x56\\x06\\x36\\x86\\xca\\x30\\x6e\\x73\\xa8\\x0c\\xa3\\x37\\x84\\xca\\xc4\\xb8\\x58\\x43\\x65\\x6a\\x87\\xca\\x57\\x09\\xd4\\x1c\\x2a\\x33\\xf0\\x56\\x06\\xb7\\x84\\xca\\x30\\x7e\\x5b\\xa8\\x0c\\x93\\x30\\x86\\xca\\xc4\\xd2\\x58\\x42\\x65\\x6a\\x92\\xca\\x57\\x09\\xd0\\x14\\x2a\\x33\\xe0\\x56\\x06\\x36\\x86\\xca\\x30\\x6e\\x73\\xa8\\x0c\\xa3\\x37\\x84\\xca\\xfc\\xf0\\xb5\\x39\\x54\\x66\\x10\\xdc\\x3e\\x8f\\x08\\x95\\xfb\\x1a\\xad\\x5a\\xc3\\x18\\x2a\\x5b\\xa8\\x98\\x43\\x65\\x0b\\xa1\\x91\\xa1\\x72\\x77\\x5e\\x20\\x77\\xdb\\xcc\\x1c\\x2b\\xb7\\x19\\x8b\\x6b\\x05\\x20\\x30\\x56\\x6e\\xf9\\x6e\\x58\\x11\\x10\\x8e\\x95\\x41\\x9c\\x86\\x58\\x19\\x44\\x0b\\xc5\\xca\\x6d\\x36\\x10\\x2b\\xb7\\x19\\x8b\\x66\\x05\\x48\\x73\\xac\\xdc\\xf2\\xed\\xb1\\x22\\xb4\\x25\\x56\\x06\\xb1\\xdb\\x62\\x65\\x90\\x80\\x31\\x56\\x6e\\x33\\x7b\\xac\\xdc\\x66\\x2c\\x9e\\x15\\x00\\x8d\\xb1\\x72\\xcb\\xf7\\xce\\x8a\\xc0\\xe6\\x58\\x19\\xc4\\x6d\\x89\\x95\\x41\\xf4\\xa6\\x58\\xb9\\xcd\\xac\\xb1\\x72\\x9b\\xb1\\x88\\x56\\x80\\x33\\xc5\\xca\\x2d\\xdf\\x58\\x2b\\xc2\\x1a\\x63\\x65\\x10\\xb3\\x39\\x56\\x06\\x91\\x1b\\x62\\xe5\\x36\\x1b\\x88\\x95\\xdb\\x8c\\x45\\xb3\\x02\\xa4\\x39\\x56\\x6e\\xf9\\x7e\\x5b\\x11\\xda\\x12\\x2b\\x83\\xd8\\x6d\\xb1\\x32\\x48\\xc0\\x18\\x2b\\xb7\\x99\\x35\\x56\\x6e\\x33\\x16\\xd1\\x0a\\x70\\xa6\\x58\\xb9\\xe5\\xdb\\x71\\x45\\x58\\x63\\xac\\x0c\\x62\\x36\\xc7\\xca\\x20\\x72\\x43\\xac\\x4c\\x8c\\x8b\\x29\\x56\\xa6\\x26\\xa8\\x7c\\x95\\xa0\\xc0\\x58\\xb9\\xe5\\xbb\\x75\\x25\\x48\\x38\\x56\\x86\\xb1\\x1a\\x62\\x65\\x18\\x31\\x14\\x2b\\x13\\x6b\\x62\\x8d\\x95\\xa9\\xe1\\x29\\x5f\\x25\\x50\\x73\\xac\\xdc\\xf2\\xed\\xbb\\x12\\xb8\\x25\\x56\\x86\\xf1\\xdb\\x62\\x65\\x98\\x84\\x31\\x56\\x26\\x66\\xc5\\x16\\x2b\\x53\\x03\\x54\\xbe\\x4a\\x90\\xc6\\x58\\xb9\\xe5\\x7b\\x7b\\x25\\x68\\x73\\xac\\x0c\\x63\\xb7\\xc4\\xca\\x30\\x01\\x53\\xac\\x4c\\xec\\x8b\\x25\\x56\\xa6\\x86\\xa8\\x7c\\x95\\x00\\x4d\\xb1\\x72\\xcb\\x37\\xfe\\x4a\\xc0\\xc6\\x58\\x19\\xc6\\x6d\\x8e\\x95\\x61\\xf4\\x86\\x58\\x99\\x18\\x17\\x6b\\xac\\x4c\\xed\\x50\\xf9\\x2a\\x81\\x9a\\x63\\xe5\\x96\\xef\\x07\\x96\\xc0\\x2d\\xb1\\x32\\x8c\\xdf\\x16\\x2b\\xc3\\x24\\x8c\\xb1\\x32\\xb1\\x34\\x96\\x58\\x99\\x9a\\xa4\\xf2\\x55\\x02\\x34\\xc5\\xca\\x2d\\xdf\\x2e\\x2c\\x01\\x1b\\x63\\x65\\x18\\xb7\\x39\\x56\\x86\\xd1\\x1b\\x62\\x65\\x7e\\xd6\\xdc\\x1c\\x2b\\xb7\\x59\\x1f\\xc5\\xca\\xd0\\xa6\\x58\\xb9\\x15\\xf6\\x0f\\x2b\\x35\\x8c\\xb1\\xb2\\x85\\x8a\\x39\\x56\\xb6\\x10\\x02\\x63\\xe5\\x79\\x83\\xda\\xc6\\x65\\x79\\x06\\x2e\\xe4\\x07\\x3d\\xa1\\xad\\xa5\\x1e\\x60\\xa0\\x2c\\xe3\\x8b\\x7e\\x5a\\x51\\x83\\x6c\\xaa\\xf3\\x29\\x0e\\x1b\\x74\\x51\\x0f\\x3f\\x92\\xb7\\x5d\\x21\\xca\\xb2\\xb4\\xac\\xd3\\x1a\\x38\\x00\\xc9\\x10\\x91\\xb3\\xbd\\x02\\x6b\\xea\\x01\\x5f\\xf2\\x8a\\x1e\\xee\\x15\\xa0\\xb4\\x13\\xbe\\xe4\\x1d\\x3b\\x48\\x2f\\xc0\\x69\\x67\\xe4\\xcd\\xfb\\xb7\\x49\\x2d\\x7e\\x0a\\x7c\\x88\\xa1\\xee\\x24\\xf8\\x20\\x4f\\x7d\\x52\\x7a\\x1b\\x5b\\x96\\xcd\\x32\\xa4\\x1a\\x3f\\x15\\x3e\\xc4\\x57\\x77\\x32\\x7c\\x90\\xaf\\x3e\\xe1\\xe9\\x44\\xbe\\xf8\\x97\\x09\\x2a\\xbd\\xc3\\x38\\xbe\\xba\\x93\\xe2\\x83\\x7c\\xf5\\xc9\\xb4\\x26\\xf2\\xd5\\x4d\\x03\\x49\\x3d\\x7e\\x6a\\x7c\\x88\\xb1\\xee\\xe4\\xf8\\x20\\x63\\x7d\\xa2\\x06\\x2b\\x63\\xac\\x15\\xc5\\x0b\\xaa\\xe2\\xb0\\x46\\x17\\x36\\x5a\\xc2\\x53\\xbd\\x2f\\xaa\\x7c\\xd7\\xbd\\xd0\\xf0\\x9f\\xcb\\x12\\xae\\xd2\\xbd\\xd0\\xf5\\x3d\\x2c\\xd3\\x26\\xcc\\xd2\\x7f\\x6a\\x75\\xfa\\x37\\x62\\xa5\\x7d\\x71\\x6a\\xdc\\x17\\x72\\x12\\xd5\\xcd\\xe8\\x79\\xf9\\xbe\\x64\\xb7\\xf0\\x3c\\x13\\x30\\x3d\\xef\\x2b\\x41\\x2f\\xcd\\xd0\\x51\\x91\\x25\\x12\\xec\\x06\\x80\\x25\\xec\\xc5\\x14\\xac\\x6e\\x5e\\x33\\xb4\\xa3\\x25\\x5a\\x23\\x89\\xe5\\xb8\\xc4\\x45\\x56\\x54\\xbb\\x0f\\xfb\\xfd\\x5e\\x03\\x28\\xab\\x34\\x0f\\xab\\x57\\x0e\\xe2\\x79\\x9b\\x48\\x82\\x0a\\x25\\x30\\x7a\\x1e\\x7a\\xa6\\x14\\x1e\\xb1\\xc5\\xea\\x31\\xac\\x83\\x58\\x67\\xa4\\x46\\x71\\x71\\x4a\\x04\\x4a\\xdb\\xf5\\x16\\x3d\\xad\\x75\\x4a\\x1d\\xa0\\x4c\\xab\\x2f\\x96\\xa8\\xad\\xe3\\xcd\\x6a\\x93\\xe8\\xd4\\xce\\x71\\x8c\\xea\\x9a\\x43\\x05\\xdb\\x70\\xb3\\x5c\\x01\\xb4\\x28\\x98\\x42\\x89\\x15\\x4a\\x74\\x7c\\xb4\\x41\\x8b\\xa5\\x46\\x27\\x3d\\xed\\x8b\\x0e\\x64\\x13\\x06\\xd1\\x56\\x27\\x82\\x61\\x64\\x0a\\xa4\\x44\\x46\\xef\\x6f\\xc2\\x6d\\xa4\\x4b\\x2f\\xac\\x4e\\xe9\\xe9\\xd0\\xcb\\x2f\\xf6\\xbd\\x8d\\x4e\\x81\\x81\\xc9\\x44\\x78\\xa1\\x44\\x27\\x59\\x3c\\x21\\x59\\x9d\\x08\\x6c\\x12\\x9e\\x0e\\x02\\x50\\xbc\\x58\\x41\\xbd\\x45\\xa1\\x64\\x2a\\xac\\x4c\\x22\\x12\\x25\\x81\\xbf\\xd0\\x89\\xd0\\x31\\xc3\\x9b\\xb2\\xdd\\x3f\\xed\\x43\\x9d\\x06\\x01\\x92\\x49\\xd0\\x22\\xb9\\x19\\x21\\xf2\\xd0\\x0a\\x68\\x46\\xf5\\x8d\\x83\\x2c\\x96\\x8b\\x70\\xe9\\x41\\x8d\\xa8\\xbe\\xa9\\x4d\\xa8\\xbe\\x29\\xd2\\x48\\x02\\x3f\\xd0\\x85\\x9d\\x9f\\x1b\\x94\\x18\\xd5\\x97\\xc2\\x1c\\xd3\\x04\\x91\\x61\\xb9\\xf3\\x3e\\x7b\\x4e\\xf8\\x4c\\xa1\\x89\\x69\\x29\\xc3\\x0a\\x9d\\x1a\\xea\\xe2\\xeb\\x63\\x98\\x14\\x2f\\xf4\\xc0\\x7f\\x14\\xc6\\xdf\\x0e\\x24\\x81\\x90\\xab\\x43\\xf7\\x59\\x0b\\x58\\x4e\\x81\\x0b\\xf9\\x9b\\x66\\x69\\xf3\\xca\\xd3\\x0c\\x88\\x4c\\xa4\\x27\\x00\\x8e\\x06\\x17\\x02\\xd8\\xff\\xf8\\xfc\\x87\\x0f\\x4e\\x5d\\x9c\\xab\\x18\\xfd\\x12\\x96\\x65\\x7a\\x3a\\xfc\\xd7\\x7f\\xfe\\xed\\x4b\\x54\\x14\\x4d\\xdd\\x54\\x61\\x39\\xcf\\xd3\\xd3\\x3c\\xae\\xeb\\x79\\x1e\\x96\\xce\\x1f\\x3e\\xff\\xff\\x01\\x00\\x00\\xff\\xff\\xc4\\xaa\\x95\\x3d\\x6f\\xf1\\x01\\x00\")\n\nfunc cmdInternalPagesAssetsStylesBootstrap400Beta2MinCssBytes() ([]byte, error) {\n\treturn bindataRead(\n\t\t_cmdInternalPagesAssetsStylesBootstrap400Beta2MinCss,\n\t\t\"cmd/internal/pages/assets/styles/bootstrap-4.0.0-beta.2.min.css\",\n\t)\n}\n\nfunc cmdInternalPagesAssetsStylesBootstrap400Beta2MinCss() (*asset, error) {\n\tbytes, err := cmdInternalPagesAssetsStylesBootstrap400Beta2MinCssBytes()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tinfo := bindataFileInfo{name: \"cmd/internal/pages/assets/styles/bootstrap-4.0.0-beta.2.min.css\", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)}\n\ta := &asset{bytes: bytes, info: info, digest: [32]uint8{0x41, 0x4c, 0xaa, 0x66, 0xbb, 0x79, 0xbc, 0x88, 0xc1, 0xba, 0x6a, 0x2a, 0x41, 0x5d, 0x23, 0x33, 0xc0, 0xa0, 0x1a, 0xab, 0x1c, 0x15, 0xf7, 0x46, 0x84, 0xdf, 0xa7, 0x54, 0x2a, 0x97, 0xd2, 0xf7}}\n\treturn a, nil\n}\n\nvar _cmdInternalPagesAssetsStylesBootstrapTheme311MinCss = []byte(\"\\x1f\\x8b\\x08\\x00\\x00\\x00\\x00\\x00\\x00\\xff\\xe4\\x5a\\x4d\\x6f\\xdb\\x38\\x13\\xbe\\xe7\\x57\\xe8\\x45\\xf1\\xa2\\x4d\\x61\\xc9\\xfa\\xb0\\x63\\xcb\\x41\\x73\\xd8\\x6e\\xb1\\x08\\xd0\\xee\\x65\\x73\\xd8\\x2b\\xbf\\xe4\\x08\\xb5\\x25\\x81\\xa2\\x13\\x17\\x81\\xff\\xfb\\x82\\xa4\\x64\\x4b\\x36\\x69\\xda\\x94\\xe5\\x1c\\x1a\\x21\\x68\\x45\\x51\\xcf\\x8c\\x1e\\x3e\\x24\\x67\\x86\\x19\\x7e\\xfe\\xdf\\x8d\\xf3\\xd9\\xf9\\x23\\xcf\\x59\\xc9\\x28\\x28\\x9c\\x97\\xc8\\x0b\\xbc\\xc0\\xf9\\xf4\\xcc\\x58\\x31\\x1b\\x0e\\xe7\\x84\\xc1\\xfa\\x99\\x87\\xf2\\xe5\\x2d\\xef\\xfd\\x35\\x2f\\x7e\\xd1\\x74\\xfe\\xcc\\x9c\\xd0\\x0f\\x02\\x37\\xf4\\x83\\x91\\xf3\\xf4\\x9a\\x32\\x46\\xe8\\xc0\\x79\\xcc\\x90\\xc7\\x3b\\x7d\\x4f\\x11\\xc9\\x4a\\x82\\x9d\\x55\\x86\\x09\\x75\\x7e\\x3c\\x3e\\x49\\xd0\\x92\\xa3\\xa6\\xec\\x79\\x05\\x39\\xde\\x90\\xbd\\xc2\\x72\\xb8\\x35\\x31\\x84\\x8b\\x1c\\x0e\\x97\\xa0\\x64\\x84\\x0e\\xbf\\x3f\\x7e\\xfd\\xf6\\xf7\\x3f\\xdf\\xb8\\xc9\\xe1\\xcd\\x8d\\x07\\x59\\xe6\\x62\\x92\\x80\\xd5\\x82\\x0d\\xc4\\x4d\\x41\\xd3\\x25\\xa0\\xbf\\xe4\\x4d\\xb9\\x42\\x88\\x94\\xa5\\xbc\\x49\\xb3\\x24\\x97\\xff\\x7b\\x05\\x34\\x4b\\xb3\\xb9\\xbc\\xc1\\x20\\x9b\\x13\\xfa\\xc6\\xc8\\x9a\\xb9\\xe5\\x33\\xc0\\xf9\\xeb\\xcc\\x77\\xdc\\xa0\\x58\\x3b\\xbe\\x43\\xe7\\x10\\x7c\\xf2\\x07\\xfc\\xf2\\xc2\\xdb\\x7b\\xf7\\x95\\xc0\\x9f\\x29\\x73\\x61\\xbe\\xae\\xbb\\xa6\\x59\\x49\\x98\\xe3\\x3b\\x8d\\xfe\\xe1\\x78\\x3c\\xa8\\x7f\\xbd\\x60\\x7c\\x3b\\x90\\x4f\\xf9\\x6f\\x13\\xcf\\x9f\\x8c\\x6f\\xef\\x2f\\x86\\xb4\\x69\\x32\\x31\\x03\\x88\\xa5\\x2f\\xa4\\x45\\x48\\xab\\xad\\xe2\\xa5\\xd5\\xc6\\xe9\\x69\\x35\\x54\\x2c\\xb5\\xda\\x24\\x59\\xed\\x26\\x69\\xd3\\x53\\xd8\\xf4\\x14\\x36\\xbd\\x7d\\x9b\\x9e\\xc2\\xa6\\x77\\x68\\xb3\\x6a\\x7a\\x3b\\x32\\x06\\x51\\xb1\\x76\\xc6\\x7b\\xdc\\x04\\xa1\\x9a\\x65\\x5d\\x5f\\xc1\\x63\\xf3\\xfb\\x6a\\xbb\\x10\\xa0\\x9f\\x73\\x9a\\xaf\\x32\\xec\\xa6\\x4b\\x30\\x27\\xb3\\x2c\\xcf\\x48\\x8b\\xf5\\xc3\\x2e\\xb5\\xaf\\x8b\\x34\\x23\\x80\\xba\\x73\\x0a\\x70\\x4a\\x32\\xf6\\x89\\xe5\\xc5\\xe0\\x43\\x92\\x24\\x8e\\x3f\\xf8\\x40\\x7c\\x7e\\x39\\x81\\xef\\xff\\xff\\xf6\\xfe\\x00\\xe1\\xf0\\x4d\\x07\\xe6\\x8c\\xe5\\x4b\\xf5\\xfb\\x49\\xba\\x60\\x84\\xce\\x0a\\x9a\\xcf\\x53\\x3c\\xfb\\xf3\\xdf\\x47\\x0e\\xf2\\x44\\x41\\x56\\x26\\x39\\x5d\\x7a\\x3f\\x52\\x44\\xf3\\x32\\x4f\\x98\\xb7\\x05\\x2c\\x19\\xa0\\xec\\x6b\\xbe\\xc8\\x69\\xc9\\xe8\\x97\\x8f\\x1c\\x55\\xfc\\x7c\\x1c\\x38\\x24\\xc3\\xad\\x07\\xd2\\xd2\\xc7\\x81\\xf3\\x57\\xf5\\xf2\\xd3\\xaf\\x82\\x7c\\xf1\\x6d\\xac\\x92\\x0c\\xc0\\x05\\xc1\\x5f\\x12\\xb0\\x28\\x49\\xeb\\xb3\\x29\\x29\\x08\\x60\\x33\\xf9\\x8f\\xbb\\xbe\\x87\\x39\\xc5\\x84\\xba\\x88\\x3b\\x32\\xfb\\x80\\x21\\xbf\\xee\\xdb\\x73\\x55\\x4e\\x18\\xee\\xf9\\x5e\\x6f\\x84\\x50\\x7b\\x5a\\x3c\\xe7\\x2f\\x84\\xb6\\x54\\x3b\\x4b\\x72\\xb4\\x2a\\x9b\\x23\\x57\\xbd\\x2b\\x3f\\xb6\\xe9\\x59\\x91\\x97\\x29\\x4b\\xf3\\x4c\\xac\\x0e\\xe3\\x62\\xad\\x9f\\x71\\xed\\x19\\x71\\x04\\x5c\\xf1\\x6d\\x9b\\xe6\\xfc\\x39\\x53\\x51\\xa3\\x70\\x0a\\x11\\xe0\\xa2\\x08\\xf1\\x1d\\x02\\xa1\\x85\\xa8\\x34\\x10\\x97\\xd0\\x95\\x84\\x56\\xe8\\x4a\\x5a\\x7a\\x57\\x5d\\x85\\xf0\\xee\\x2e\\x06\\x2d\\xee\\x9b\\x62\\xa9\\x9b\\x74\\x62\\x91\\x5f\\x60\\x16\\x8b\\x6a\\x29\\x6e\\x2f\\x95\\x47\\xc0\\xb5\\x0e\\x57\\x0b\\xeb\\x99\\x62\\x19\\x23\\x38\\x1d\\x23\\x3e\\xd2\\xa3\\x20\\xbe\\x1b\\x05\\x16\\x62\\xd1\\x40\\x5c\\x42\\x2c\\x12\\x5a\\x21\\x16\\x69\\xe9\\x5d\\xc5\\x12\\x91\\x69\\x12\\x91\\x16\\xf7\\x4d\\xb1\\xd4\\x4d\\x3a\\xb1\\xc8\\x2f\\x30\\x8b\\x45\\xb5\\x47\\xb7\\xf7\\xd0\\x23\\xe0\\x5a\\x87\\xf9\\x8e\\x7b\\xae\\x52\\x20\\xf2\\x31\\x11\\x6b\\x02\\x00\\x10\\xdb\\x2c\\x2b\\x1a\\x88\\x8b\\x28\\x45\\x40\\xab\\x96\\x15\\x61\\xe9\\x7d\\x97\\x95\\x29\\x18\\xa1\\x78\\x47\\x7c\\x53\\x26\\xe2\\x5e\\xbb\\xa0\\x08\\xdf\\xcd\\x1a\\x39\\x88\\xd9\\x1a\\x01\\xd5\\x11\\x58\\xad\\x93\\x55\\xf8\\x75\\x6e\\x24\\xe3\\x03\\x3c\\x12\\xa3\\x4b\\x60\\x1c\\x05\\x77\\x36\\xc1\\x8c\\x1a\\xe2\\x22\\xf1\\x8c\\x80\\x56\\xc5\\x33\\xc2\\xd2\\xbb\\x0a\\x84\\x44\\x53\\x1c\\x44\\x2d\\xee\\x9b\\x1a\\xa9\\x9b\\xb4\\x41\\x8a\\xf8\\x02\\xb3\\x4c\\x54\\x91\\x7c\\x3b\\xd2\\x3e\\x02\\xae\\x75\\xb8\\x4a\\x9c\\xce\\xd3\\x0a\\x8e\\xc7\\xd1\\x48\\x04\\xae\\x28\\x08\\x49\\x08\\x2c\\xb4\\xa2\\x81\\xb8\\x84\\x56\\x24\\xb4\\x42\\x2b\\xd2\\xd2\\xbb\\x6a\\x05\\xc6\\x21\\x0a\\xa7\\x4d\\xea\\x5b\\xf1\\xac\\x6c\\xd1\\x29\\x45\\xfa\\x7f\\x42\\x38\\xab\\xc8\\xef\\x5a\\xe9\\x97\\x1e\\x5a\\xe9\\x2c\\x7b\\x5e\\x2d\\x61\\x06\\xd2\\xc5\\xc0\\x4b\\x97\\x73\\x77\\x7b\\xab\\x4a\\xe3\\x64\\x24\\x1f\\x1a\\xd2\\x64\\x7d\\xaf\\x8d\\x87\\x69\\x5e\\xe0\\xfc\\x35\\x73\\x97\\x24\\x5b\\x3d\\x2c\\xd2\\x07\\x50\\x53\\xa4\\x78\\x72\\x40\\xd5\\x29\\x2b\\xdd\\x98\\x5f\\x62\\x99\\x9a\\xf2\\xcb\\x66\\xa5\\x33\\x42\\xec\\xcb\\xe0\\x22\\x8b\\xa0\\xb0\\xaa\\x5a\\x04\\x85\\x13\\x0a\\x61\\x2b\\x16\\x04\\xd1\\x75\\x9f\\xe5\\x4a\\x18\\x0f\\x60\\x9f\\xe4\\xed\\x03\\xf5\\x18\\xec\\x1e\\xdb\\x0c\\xc4\\x2e\\x4f\\x89\\xc6\\x13\\x02\\x71\\xa7\\x54\\x47\\x07\\xd1\\xc7\\x40\\x68\\xb3\\x20\\xe9\\xc4\\x49\\x03\\x21\\xbb\\x6e\\xbc\\x0c\\xbc\\x40\\x40\\xbb\\x95\\x1f\\x92\\x29\\xbf\\xec\\xcb\\x0f\\xba\\xf7\\x7b\\x11\\xb1\\xae\\x32\\x21\\x9d\\xe8\\x65\\x75\\x96\\xab\\x1a\\x7f\\xba\\x2a\\x67\\xa3\\x62\\xdd\\xad\\x06\\xb8\\x5f\\x71\\xb2\\xaf\\x01\\xaa\\x90\\xf6\\x15\\xe1\\xd4\\xf7\\x19\\x78\\xd9\\xcd\\xb7\\x33\\x75\\x42\\x20\\xbf\\xc4\\x50\\x47\\xfc\\xb2\\x90\\x8a\\x19\\xa2\\x0f\\xb5\\x48\\xab\\x2a\\xb5\\x08\\x27\\x14\\x6a\\x31\\x94\\x16\\xe3\\x13\\x07\\x4f\\xd7\\x77\\x3b\\x3c\\x90\\x82\\x0c\\x0f\\x9a\\x83\\xc3\\x37\\xa4\\x37\\x55\\x55\\xeb\\x50\\x02\\x61\\x03\\x28\\xcd\\x5e\\x08\\x2d\\x15\\xb5\\xc9\\xa3\\x23\\x1a\\x21\\x7e\\x89\\x64\\x2c\\xb4\\x49\\xe6\\x0c\\xef\\xf7\\x31\\x96\\xd2\\xa4\\x2a\\xc9\\x13\\x3f\\x3d\\xcc\\xfc\\x7d\\x8e\\x2f\\x32\\x97\\x38\\x5f\\x9c\\xb6\\x29\\xbf\\x2c\\x98\\x37\\xbc\\xdf\\x07\\xf3\\x5b\\x82\\x0f\\x98\\x17\\x4e\\x74\\x9f\\x45\\x47\\xea\\xf3\\x8a\\xae\\xda\\x61\\x69\\xcf\\x29\\xd5\\xa0\\x29\\xe6\\x98\\xea\\x94\\xa7\\x61\\xa3\\x64\\x80\\xa5\\xc8\\xe5\\x43\\x57\\x37\\x25\\xe9\\x9a\\x60\\x45\\x8b\\x1c\\xa1\\xb7\\xf6\\x76\\xe1\\x6f\\x3c\\xb0\\x20\\x94\\x9d\\x3a\\xb3\\xad\\x0e\\x98\\xc2\\xed\\x96\\x70\\x10\\x13\\x9f\\xb7\\xb7\\x1c\\x05\\xaa\\xbe\\xc4\\xb2\\xd6\\x88\\x93\\xc4\\xc7\\x53\\x91\\xb1\\x4d\\xc9\\x18\\x22\\x9b\\xa4\\xcf\\x08\\xd1\\x87\\xfa\\xa5\\x55\\x55\\x3e\\x28\\x9c\\x50\\x45\\x6b\\xed\\x34\\x28\\xc4\\x10\\x04\\x35\\x79\\x16\\xb5\\x37\\x1c\\x13\\x9c\\x4c\\xf8\\x67\\xc3\\x18\\x93\\xc4\\xe6\\x9c\\xc8\\x0c\\xd1\\x0b\\x73\\xc2\\xaa\\x82\\x39\\xe9\\x84\\x91\\xb9\\x18\\xa0\\x84\\x80\\x9a\\x39\\xcb\\xba\\x14\\x4a\\xa6\\x24\\x92\\x51\\x2a\\x49\\x90\\xd5\\x21\\x9b\\x11\\xa2\\x97\\x40\\x57\\x58\\x55\\x06\\xba\\xdc\\x09\\x23\\x79\\xc9\\x98\\x4c\\x62\\x52\\x93\\x67\\x55\\xa7\\x49\\x42\\x4c\\x64\\xc5\\x96\\x4c\\xf8\\xe6\\x6b\\xc3\\x9d\\x11\\xa2\\x17\\xee\\x84\\x55\\x55\\xa6\\x2b\\x9c\\x30\\x72\\x87\\x11\\x98\\x80\\xc9\\xc6\\xe3\\x4e\\xd0\\xf3\\x97\\xba\\x46\\xac\\x2b\\x13\\xfd\\x4e\\xe1\\xb2\\x06\\xe2\\xba\\xe1\\x72\\x5d\\x3a\\xd8\\xe3\\x6d\\x47\\x91\\x0b\\xc1\\xb9\\xf2\\x6a\\x24\\xdf\\xfe\\x24\\x00\\x71\\xb7\\xfc\\x5d\\x03\\x71\\xdd\\xfc\\x5d\\x38\\x61\\xa2\\xa9\\xfb\\x61\\xdd\\x28\\xc6\\xa3\\x51\\xb7\\xc3\\x3a\\x0d\\x44\\x1f\\x74\\xe9\\xcf\\xf1\\x84\\x13\\x46\\xba\\x3a\\x1d\\x57\\x45\\x01\\xf4\\xb1\\xcd\\x0c\\x34\\x43\\xf4\\xc2\\x95\\xee\\x24\\x4b\\x3a\\x61\\xe4\\xaa\\xf3\\xe1\\x0d\\x8a\\x27\\x41\\xd2\\xed\\xf0\\x46\\x03\\xd1\\xcb\\x42\\xaf\\x3d\\xd7\\x11\\x4e\\x18\\xe9\\xea\\x7a\\x7c\\x11\\x47\\x7e\\x68\\x15\\xc9\\x1a\\x21\\xfa\\x89\\xc7\\x74\\x27\\x1b\\xc2\\x09\\x15\\x5b\\x8b\\xb4\\x64\\x2e\\x77\\xa9\\x78\\x3b\\xa9\\x0c\\xd6\\xbd\\x7e\\xbf\\xb3\\xe8\\xa6\\x8c\\x2c\\xb7\\x7f\\x05\\xa6\\x6e\\xaf\\xeb\\xca\\x9a\\xa7\\xb2\\xac\\xac\\x4c\\xf8\\xaa\\x1d\\xe3\\x70\\xd8\\x4e\\xdd\\xb3\\xc2\\xc9\\x14\\xda\\x84\\x44\\x66\\x88\\xeb\\xee\\x59\\xc2\\x09\\x63\\x48\\x24\\xbb\\x6d\\xbc\\x02\\x64\\xe4\\x9c\\x93\\x9b\\x93\\x06\\x9e\\x8f\\xbb\\x00\\xae\\xab\\x96\\x0f\\xd5\\xed\\x33\\x01\\xd8\\x62\\x39\\xfb\\x6d\\x4e\\x68\\x6a\\xda\\xaa\\x3f\\x20\\xea\\x46\\xdb\\xef\\x73\\x9e\\x52\\xd3\\x56\\x05\\x62\\xdd\\x68\\xdb\\x55\\x25\\xb0\\x4f\\x62\\x64\\xf3\\x97\\x0f\\x66\\x88\\xab\\x16\\x36\\xa4\\x13\\x7a\\xda\\x78\\x40\\xd6\\x91\\xb3\\x6d\\x3d\\x02\\x8d\\x88\\xdd\\x81\\x82\\x19\\xe2\\xaa\\x25\\x0d\\xe9\\x84\\x9e\\xb3\\x2a\\x30\\xeb\\xb8\\xb0\\xed\\x2a\\x11\\x20\\x09\\x91\\x4d\\xe4\\x61\\x86\\xb8\\x6e\\x31\\x43\\x38\\xa1\\xa7\\x4d\\x06\\x68\\x1d\\x59\\xdb\\xd5\\x20\\x20\\x42\\x76\\xac\\x19\\x21\\xae\\x5b\\xc6\\x10\\x4e\\xa8\\x58\\x7b\\x25\\x8b\\xc5\\xb9\\xd5\\x0a\\xb9\\xc1\\x75\\xaa\\x56\\x18\\x21\\x7a\\xa9\\x56\\xd4\\x9b\\xe2\\xa9\\xd5\\x8a\\x83\\x2a\\x0f\\xbf\\x4c\\xf5\\xf6\\xe8\\x30\\x58\\x19\\x1c\\x39\\x9c\\xd5\\x96\\xdb\\xcf\\xc5\\xd9\\xdc\\xfc\\x17\\x00\\x00\\xff\\xff\\x3b\\xfc\\x2f\\xb1\\x82\\x33\\x00\\x00\")\n\nfunc cmdInternalPagesAssetsStylesBootstrapTheme311MinCssBytes() ([]byte, error) {\n\treturn bindataRead(\n\t\t_cmdInternalPagesAssetsStylesBootstrapTheme311MinCss,\n\t\t\"cmd/internal/pages/assets/styles/bootstrap-theme-3.1.1.min.css\",\n\t)\n}\n\nfunc cmdInternalPagesAssetsStylesBootstrapTheme311MinCss() (*asset, error) {\n\tbytes, err := cmdInternalPagesAssetsStylesBootstrapTheme311MinCssBytes()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tinfo := bindataFileInfo{name: \"cmd/internal/pages/assets/styles/bootstrap-theme-3.1.1.min.css\", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)}\n\ta := &asset{bytes: bytes, info: info, digest: [32]uint8{0x9a, 0xa3, 0xa3, 0xf9, 0x25, 0xf2, 0xa8, 0xa6, 0x23, 0x60, 0x11, 0x85, 0x51, 0xe5, 0xe1, 0x2c, 0xa9, 0x80, 0x52, 0x74, 0x43, 0x29, 0xb1, 0x3c, 0x5d, 0x4c, 0x10, 0x8b, 0xe7, 0x22, 0xcb, 0xe1}}\n\treturn a, nil\n}\n\nvar _cmdInternalPagesAssetsStylesContainersCss = []byte(\"\\x1f\\x8b\\x08\\x00\\x00\\x00\\x00\\x00\\x00\\xff\\xac\\xb9\\xd7\\x8e\\xe3\\x68\\x9a\\x28\\x78\\xdf\\x4f\\x91\\x3b\\x83\\x05\\xce\\x39\\xec\\x6c\\x7a\\x57\\x85\\xbd\\xa0\\x11\\x45\\x27\\x7a\\x7f\\xb3\\xa0\\x27\\x25\\x7a\\x27\\x92\\x85\\x79\\xf7\\x85\\x22\\x22\\x23\\xb3\\x4c\\x57\\x75\\xcf\\x6c\\x20\\x95\\x11\\xfc\\xf9\\x7f\\xde\\x7f\\xfa\\xdb\\x3f\\xca\\xbe\\x2f\\x9b\\xfc\\xeb\\x56\\xcf\\x6b\\xdc\\xd4\\x67\\xbc\\xd4\\x7d\\xf7\\x75\\xe9\\xfb\\x26\\x89\\xa7\\x5f\\x8a\\xbe\\x5b\\xbe\\xce\\xf5\\x99\\xff\\x04\\x43\\xd0\\xff\\xfd\\x5f\\x7f\\x7a\\xf9\\xcb\\x9f\\xbe\\xfd\\x9a\\xef\\x43\\x3f\\x2d\\x5f\\xeb\\xf7\\x4b\\x7f\\xff\\xff\\x01\\x55\\x16\\x2f\\xf1\\xff\\x08\\x4f\\xb5\\xb4\\xcd\\xd7\\xb4\\xcf\\xf2\\x5f\\xda\\x78\\x2a\\xeb\\xee\\xeb\\x54\\x97\\xd5\\xf2\\xd3\\x3f\\xe0\\xbc\\xfd\\x73\\x51\\xbf\\x43\\xbe\\x78\\x69\\xe2\\xee\\xed\\xed\\xbb\\xb6\\x9e\\xf9\\x1b\\x92\\xa4\\x6f\\xb2\\xbf\\x40\\xd2\\x3f\\xbe\\x26\\xeb\\xb2\\xf4\\xdd\\x2f\\x43\\x9c\\x65\\x75\\x57\\xfe\\x84\\x0c\\xfb\\x5f\\xc0\\x2c\\x53\\x1d\\x77\\x65\\x93\\xff\\x32\\xf4\\x73\\xfd\\x7a\\xf3\\x53\\x9c\\xcc\\x7d\\xb3\\x2e\\xf9\\xcf\\xef\\xcc\\x43\\x3f\\x2f\\xfd\\xf0\\x13\\xf4\\x17\\x68\\xd2\\x78\\x78\\x7f\\x8e\\x93\\x26\\xff\\xe5\\x59\\x67\\x4b\\xf5\\x66\\xe1\\x9f\\xbf\\x71\\x02\\xfd\\xfc\\xae\\x92\\x9f\\xa0\\x9f\\x93\\x7e\\xca\\xf2\\xe9\\xf3\\x8f\\xaf\\x69\\xdf\\x34\\xf1\\x30\\xe7\\x3f\\x7d\\xfb\\xe3\\x2f\\x68\\xcd\\x6d\\xdc\\x34\\x5f\\xb3\\x3a\\x6e\\xfa\\xf2\\x83\\x14\\x0e\\x41\\x7f\\x29\\x69\\x52\\x97\\xbf\\x06\\xa2\\xfe\\x05\\xa0\\x1f\\x69\\xfd\\xb9\\x6b\\xfc\\x88\\xff\\xf7\\xba\\x4c\\xe2\\xf4\\x51\\x4e\\xfd\\xda\\x65\\x2f\\x71\\xfb\\xe9\\xa7\\xff\\x4c\\xe1\\x8c\\x2e\\x8a\\x6f\\xca\\x80\\x87\\xfd\\xcb\\xdc\\x37\\x75\\xf6\\xe5\\x3f\\xd1\\x18\\x27\\x49\\xec\\x53\\x71\\xd4\\xbf\\xc5\\xe3\\xd7\\xe4\\x5f\\x67\\xf3\\x6b\\x52\\xfe\\xf2\\x7b\\xbe\\xb2\\x2c\\xfb\\xf9\\xf7\\xfc\\xbf\\xf9\\xc0\\xcf\\x4d\\x5e\\x2c\\x7f\\xe9\\x0a\\xbf\\x62\\x67\\xa9\\x97\\xbf\\x8a\\xcd\\x1f\\x39\\x7a\\xbb\\xfe\\x07\\x4c\\xe5\\x50\\x9e\\x15\\xf9\\xcf\\x1f\\x4f\\x10\\x04\\xfd\\x9c\\xae\\xd3\\xdc\\x4f\\x3f\\x0d\\x7d\\xdd\\x2d\\xf9\\xf4\\xa3\\xb6\\xbe\\x73\\x3f\\xe5\\x4d\\xbc\\xd4\\x5b\\xfe\\xf3\\x0f\\x59\\x07\\x19\\x96\\x9f\\x7f\\x1b\\x56\\x3f\\x6f\\xf9\\xb4\\xd4\\x69\\xdc\\x7c\\x8d\\x9b\\xba\\xec\\x7e\\x6a\\xeb\\x2c\\x6b\\xfe\\x1d\\x2f\\xfc\\x9a\\xf6\\xdd\\x92\\x77\\xcb\\xbf\\x2e\\xe8\\x07\\xc0\\x1f\\x88\\x5a\\x14\\xc5\\xa7\\x34\\xd8\\xb0\\xff\\x8a\\xd9\\xae\\x9f\\xda\\xb8\\xf9\\xb9\\xdf\\xf2\\xa9\\x68\\xfa\\xe7\\x4f\\xf1\\xba\\xf4\\xff\\xb6\\x35\\xbe\\xa6\\x4d\\x3f\\xff\\xbb\\x36\\x79\\x07\\xfa\\x81\\xdd\\x9f\\x96\\x29\\xee\\xe6\\x21\\x9e\\xf2\\x6e\\xf9\\xb2\\x4e\\xcd\\xff\\x7a\\xbb\\xf0\\xff\\x26\\xfd\\xfe\\x8f\\xb2\\x2e\\xfe\\xf7\\x97\\xae\\xff\\x3a\\xe5\\x43\\x1e\\x2f\\x5f\\xe6\\x74\\xea\\x9b\\xe6\\x4b\\x9a\\xbf\\x19\\xaa\\x7a\\x97\\x04\\xc6\\x7f\\x34\\xd4\\x6f\\x52\\x0e\\x0c\\x0d\\xfb\\x9b\\xc7\\xbd\\xac\\xf9\\x91\\x4b\\xf0\\x7f\\x2f\\x0c\\x3e\\xf4\\xfb\\xa5\\x2e\\xa6\\xb8\\xfd\\x37\\x84\\xfd\\x35\\xdc\\x8f\\xd9\\xe5\\x1b\\xe7\\xe4\\xdb\\xc3\\xef\\xc2\\x36\\x69\\xe2\\xf4\\xf1\\x5f\\xff\\x48\\xab\\x78\\x5a\\xe6\\xaf\\x75\\xd7\\xd4\\x5d\\xfe\\x35\\x69\\xfa\\xf4\\xf1\\xcb\\xef\\xfd\\x31\\xab\\xe7\\xa1\\x89\\x8f\\x9f\\xbe\\xb6\\xfd\\xf9\\x79\\xb7\\xdf\\x3f\\xcf\\x7f\\x04\\xff\\xaf\\xff\\xf3\\xe5\\x55\\x1c\\xbe\\xfc\\x11\\xea\\xbf\\xff\\x9f\\x9f\\x8a\\x7a\\x9a\\x97\\xaf\\x69\\x55\\x37\\x19\\xf0\\x4f\\xef\\xfd\\xf2\\x6b\\xc4\\x9f\\x6c\\xb6\\x79\\xb7\\xfe\\x68\\xd3\\x37\\xe7\\xfb\\x9e\\x95\\xdf\\xd2\\x54\\x9a\\x7e\\xf9\\x4f\\x82\\x20\\x3e\\xfe\\x4b\\xd3\\xf4\\xdb\\x85\\x79\\x39\\x9a\\xfc\\xa7\\x37\\xe9\\xbf\\x1d\\x7d\\xd8\\x6a\\xd8\\xbf\\x85\\x67\\x96\\x17\\xf1\\xda\\xbc\\x47\\xdc\\x87\\xf7\\x7e\\x81\\xd1\\x61\\xff\\xc2\\x4c\\x75\\xdc\\xfc\\x7d\\x8e\\xbb\\xf9\\xeb\\x9c\\x4f\\x75\\xf1\\xbd\\x3a\\xf4\\xeb\\xf2\\xe2\\xf1\\xa7\\xae\\xef\\xf2\\x1f\\x03\\xe1\\x0b\\xf4\\x07\\xfe\\xf2\\xd2\\x5e\\x96\\xef\\x3f\\x21\\x10\\x04\\x41\\xbf\\x12\\xeb\\x5b\\x25\\xfc\\x51\\xba\\x2c\\xcb\\xde\\x5c\\x15\\x04\\xe7\\xb9\\xf9\\x47\\x39\\x2f\\xf1\\x52\\xa7\\xff\\x48\\xfb\\x16\\xcc\\xb3\\x7a\\xe9\\x27\\xf0\\x1d\\xe6\\x6b\\x52\\xfe\\x63\\xe8\\xca\\xff\\xfd\\xe5\\xdd\\x81\\xbf\\xee\\x5f\\x96\\x7e\\xf8\\xf2\\xca\\x7d\\xdf\\x4b\\xd7\\x3f\\xcf\\x44\\x4d\\x3d\\x2f\\x1f\\xba\\x79\\x13\\xe1\\x43\\x30\\x64\\xd8\\xff\\x58\\x34\\xe8\\xe7\\x25\\xdf\\x97\\xaf\\x59\\x9e\\xf6\\xd3\\x9b\\x5b\\xbe\\xbf\\xfe\\x27\\x29\\xe9\\xf7\\x12\\x7e\\xed\\xd7\\x25\\x9f\\x5e\\xee\\xf3\\xf7\\x3f\\x7a\\x5b\\x77\\xdd\\xfb\\xdb\\x5f\\xfe\\xb9\\xd9\\x3e\\x84\\x89\\xe3\\xf8\\xb7\\x64\\x97\\x7e\\xf8\\x73\\x9a\\xbf\\xfc\\xa6\\xaa\\x7f\\x77\\x81\\x97\\xbd\\xbe\\x89\\xf8\\x87\\x38\\xbe\\x73\\xf6\\x0d\\xc7\\x97\\xaf\\xf0\\x67\\x68\\x7d\\x20\\x82\\xbe\\xbc\\x8e\\xbe\\x21\\x7a\\x79\\x0e\\x36\\xec\\xbf\\x0d\\x89\\x3f\\xc6\\xfa\\x56\\xac\\x5e\\x18\\xff\\xec\\xfa\\xb4\\xfc\\xf1\\xf9\\x77\\x01\\x3f\\xd1\\x7c\\x24\\xa7\\xb7\\x9c\\xfb\\xdf\\xc0\\xf8\\x9d\\xb1\\x1f\\xf1\\xfc\\xf3\\xf8\\xfd\\x4b\\xa1\\xfe\\x35\\xd0\\xbf\\x66\\xe7\\x0d\\xe5\\x6f\\xe4\\xfb\\xe9\\xa7\\xa9\\xef\\x97\\x3f\\x02\\xfc\\xe5\\x2d\\xab\\x7c\\xe4\\x42\\xe8\\x4f\\x2e\\xfe\\xa8\\xc2\\x7f\\x15\\xe4\\x07\\xa6\\xfe\\x55\\x90\\x8f\\xc6\\xf3\\x57\\x00\\xef\\x89\\xe6\\xcf\\xa0\\xb2\\xa9\\x1f\\xb2\\xfe\\xf9\\x87\\x60\\x7f\\x78\\xbf\\x9e\\x5f\\x8d\\x6d\\xf6\\x63\\xbd\\xae\\xdb\\xb8\\x7c\\x8f\\xe5\\xff\\xab\\x6e\\x5f\\xf3\\x43\\xdc\\x2d\\x3f\\xf7\\x43\\x9c\\xd6\\xcb\\xf1\\xd3\\x3f\\xd0\\x9f\\xdf\\x92\\xfb\\x0f\\xcf\\x45\\xdd\\x2c\\xf9\\xf4\\x53\\xdc\\x0c\\x55\\xfc\\xbf\\x3e\\xce\\xff\\x1f\\x14\\xfa\\xdf\\x7f\\x4a\\xf0\\xcf\\x35\\xfb\\x87\\x11\\xff\\xa7\\xa0\\x9f\\x1a\\xfe\\xf7\\x41\\x3f\\x34\\xfd\\xef\\x03\\x7e\\x2a\\xfb\\x23\\xcf\\xa0\\x28\\xfa\\x83\\xc6\\x7e\\x9d\\x83\\x68\\x9a\\xfe\\xfe\\xee\\xcf\\xc2\\xec\\x1b\\xc5\\x3f\\x2b\\x81\\x7f\\x68\\xc1\\xef\\xf9\\xf8\\x95\\x5a\\x7e\\x60\\xe4\\x33\\x5b\\xfd\\xfa\\xfc\\x0f\\xcd\\x53\\xbd\\x5a\\xb0\\xff\\x86\\x6d\\xfe\\x39\\xdc\\xef\\xf2\\xf4\\x37\\x85\\xa4\\xc5\\x97\\xff\\x24\\xe8\\xfc\\xe3\\x3f\\x32\\x2e\\xfe\\x82\\xb5\\x38\\x7d\\xb5\\x18\\x7f\\x48\\xbd\\x1f\\xf2\\xee\\x0f\\x3a\\xce\\x24\\x49\\x7e\\x9c\\x4f\\x3e\\xab\\x6c\\xd2\\x2f\\x4b\\xdf\\xbe\\x15\\xbe\\x3f\\xa4\\x54\\xf4\\xe9\\x3a\\xff\\xb7\\x5c\\xf4\\xcf\\x20\\xff\\x89\\x22\\xfa\\x29\\xee\\xca\\x3f\\x2e\\x80\\xdf\\x52\\xc0\\x77\\x03\\xbe\\xb5\\x0b\\x5f\\xa0\\x7f\\xb5\\x9a\\x7d\\x3a\\xe8\\x8f\\xcd\\xe9\\x7b\\xfd\\x21\\x5f\\x05\\xe9\\x7b\\x0b\\xf1\\xa7\\xdd\\xc3\\xfb\\xaf\\x8f\\xa6\\xf2\\xbd\\x83\\xf8\\xde\\x05\\x7f\\x45\\x29\\xea\\xad\\x28\\xfe\\x8b\\x3c\\x7d\\x9b\\x85\\xdf\\x57\\x08\\x7f\\xa8\\xc5\\x5f\\x5f\\xf9\\x6f\\x98\\xe1\\x5f\\x40\\xf0\\xdb\\x22\\xfd\\xb1\\xd1\\xf8\\xe3\\x8a\\xfe\\x89\\xef\\xe5\\x32\\x7f\\x4e\\xf1\\x75\\xe3\\x2f\\xaa\\xc6\\x07\\xc1\\x6f\\x33\\xe7\\x7f\\x0b\\xdb\\xef\\xd8\\x7f\\xc7\\xf6\\x2d\\xe9\\x7c\\x2b\\x7d\\xdf\\x46\\xef\\xa2\\x28\\xfe\\x9a\\xd0\\x1f\\x5e\\xa8\\xf2\\xf4\\xf1\\xaf\\x3a\\xf4\\x6f\\xa9\\x66\\x59\\xf6\\x2b\\xaa\\xf5\\x92\\xb7\\xbf\\xfc\\xd0\\x60\\xfe\\x75\\xf3\\xfc\\x4f\\x7a\\x4e\\xe8\\x57\\xfd\\x33\\x99\\xb7\\x6f\\x81\\x81\\xbc\\x4d\\x55\\x55\\xbd\\xe4\\x5f\\xe7\\x21\\x4e\\x5f\\x20\\xcf\\x29\\x1e\\x7e\\xc7\\xc2\\x6f\\x9f\\x5f\\xad\\xc4\\xb7\\x18\\x7b\\x97\\x81\\xcc\\xdb\\x6f\\x14\\x3e\\xfc\\x02\\x79\\xdb\\x56\\xfc\\xa8\\x84\\xae\\x7f\\xd3\\x4d\\xd2\\xef\\x5f\\x7e\\x8b\\xf0\\xef\\xbf\\xb9\\x58\\xa7\\x7d\\xf7\\xbb\\x4b\\xbf\\xa6\\x08\\x23\\xbf\\xc7\\x1f\\xa7\\x69\\xde\\xfc\\x73\\xb8\\x0f\\xc6\\xa0\\xdf\\x00\\xbe\\x49\\xf4\\x6d\\x0a\\xff\\x77\\x94\\xfd\\x7b\\x2c\\x7f\\x58\\xfc\\xde\\xde\\xbc\\xb1\\xf6\\xf7\\x7f\\x03\\xe0\\x37\\x0c\\xa5\\x69\\xfa\\x4f\\xb2\\xfd\\x5f\\xe0\\x79\\xa9\\xf2\\x97\\xff\\x69\\x2f\\xf2\\x86\\xa9\\xaa\\xcb\\xaa\\xf9\\x5d\\x0a\\x7a\\x7f\\xf5\\x2a\\x66\\x7f\\xb4\\x41\\x22\\x72\\xba\\xa0\\x7e\\x53\\xd8\\x7f\\x7d\\xf8\\xee\\xab\\x59\\xbf\\x2c\\xf9\\xef\\x87\\xc7\\xef\\x93\\xc3\\xd7\\xf7\\x12\\xf4\\xea\\xfb\\x3f\\x8f\\x96\\x7e\\x78\\x3d\\xff\\x81\\x31\\x3f\\xfc\\xec\\xf7\\x8c\\xbe\\x69\\xe3\\x07\\x3e\\xdf\\x53\\xf2\\x4f\\x9f\\xc9\\xf9\\x73\\x29\\x41\\x0c\\xfb\\xfb\\x8e\\x8b\\xf8\\x93\\xed\\xc4\\xab\\x41\\xfe\\xe3\\xf1\\xec\\xdb\\xae\\x82\\xf8\\x23\\xf6\\x7e\\xdb\\x88\\xff\\x05\\xcf\\x7f\\x78\\xfd\\x4d\\x90\\x37\\x06\\xdf\\x98\\x78\\xe7\\xe7\\x47\\x6a\\xfd\\xfb\\x16\\x76\\xce\\x9b\\x3c\\x5d\\xfe\\xd0\\xc1\\x7e\\x4b\\xf0\\x2f\\x21\\x7e\\xa3\\xbc\\xff\\x49\\x09\\xc4\\x5f\\xe1\\xfb\\x05\\xfa\\xbd\\x6e\\xde\\xe2\\xe4\\x97\\xef\\x2d\\xe0\\xcf\\x59\\x3d\\xe5\\xe9\\x9b\\xf2\\x9b\\x65\\xfa\\xf9\\xbb\\xc4\\xdf\\x4b\\xfc\\x9f\\x59\\xe8\\x63\\xa4\\x7e\\x37\\xcd\\xdb\\xd1\\xbf\\x68\\x8e\\x77\\x3e\\x3e\\x6a\\xc4\\x0f\\xd6\\xfe\\x01\\xdd\\xef\\xba\\xa1\\x37\\xc0\\xb6\\xcb\\xdb\\xbe\\xab\\xd3\\xaf\\x55\\xdd\\x2d\\xbf\\xfc\\x76\\xa0\\x5f\\xbb\\x2c\\x9f\\x7e\\xb7\\x78\\xf9\\x35\\xe0\\x9c\\x0f\\xf1\\x14\\x2f\\xfd\\xf4\\xa3\\x1a\\x7e\\xb5\\xb7\\xfc\\x1e\\x02\\x6f\\x0c\\xbe\\xe6\\xe0\\xbf\\xfd\\xed\\x1f\\x2f\\x1b\\x7c\\x6d\\xe2\\x24\\x6f\\xbe\\xfc\\xf2\\xb7\\x2f\\x5f\\xbe\\x7c\\xf9\\xdd\\x72\\xf3\\x6f\\xff\\xf5\\xb7\\x7f\\xac\\x5d\\xfd\\xeb\\x5b\\x1f\\x44\\xa8\\xb7\\x9f\\x9f\\xbf\\x03\\xbe\\x07\\x66\\xbd\\xc4\\x4d\\x9d\\xbe\\x41\\xbe\\xb7\\x93\\x5f\\xd3\\x61\\xfd\\xa7\\xf8\\x7f\\xc0\\x07\\xbd\\xfd\\xbc\\x01\\xd6\\xdd\\xef\\x40\\x7f\\x43\\xf4\\xbf\\xfe\\xf6\\x8f\\x29\\x7e\\x7e\\x7d\\x49\\x30\\xff\\x88\\xbc\\x88\\xdb\\xba\\x39\\x7e\\xfa\\xf2\\x1f\\x5c\\xbf\\x4e\\x75\\x3e\\x7d\\xd1\\xf2\\xe7\\x7f\\xbc\\x93\\xf9\\xb1\\x6c\\x7d\\x19\\xa6\\xfc\\xeb\\xab\\x72\\xbd\\x93\\x9b\\xfb\\xe6\\x63\\xab\\x57\\x2f\\x4d\\xfe\\x6b\\x8a\\xc2\\xdb\\xcf\\xdb\\xbd\\x21\\x2e\\x5f\\x03\\x5f\\x9c\\xe5\\xd3\\x97\\x0a\\xfe\\xb8\\xf6\\xec\\xa7\\xec\\x0d\\xd5\\x4f\\x5f\\x92\\x29\\x8f\\x1f\\x5f\\x5f\\x07\\x6f\\xd7\\xdf\\xbe\\xcf\\xf8\\x3a\\xf5\\xcf\\x3f\\x64\\x30\\x7d\\x67\\xf0\\x3f\\xfe\\xfe\\xe5\\x3f\\xda\\xbe\\xeb\\xdf\\xf8\\xfa\\x8f\\x1f\\xb5\\xf9\\x32\\xdd\\x97\\xb7\\x76\\xf2\\xed\\xf0\\x07\\x3f\\xfa\\xf2\\xe6\\x5e\\xef\\xc7\\xbf\\x49\\x26\\x5f\\x96\\x7e\\x78\\x7f\\xf1\\xb1\\x6e\\xfa\\xf2\\x89\\xe0\\xc7\\x2e\\xe6\\x0b\\xfa\\x9b\\xd3\\x77\\x87\\xfd\\xdd\\xf1\\x2b\\x61\\xfe\\xee\\xf0\\x23\\xb1\\xbe\\x9f\\xff\\xd7\\xdf\\xfe\\x31\\xaf\\xc9\\xab\\xf6\\xc4\\xf5\\xab\\x57\\xf9\\xd8\\x16\\x7e\\xad\\xbb\\x61\\x5d\\x3e\\x04\\xff\\x15\\x65\\xec\\x1b\\xb6\\xf7\\x84\\xf7\\x05\\x83\\xde\\xd1\\xfc\\x67\\xd3\\x97\\xfd\\x37\\x4d\\x35\\x7d\\xbc\\xbc\\x85\\xcb\\xfb\\xd5\\x8f\\x1c\\xfb\\x05\\x79\\xdb\\x9f\\xfe\\x8e\\x41\\xe4\\xf3\\xf4\\xf7\\x89\\xfa\\x7b\\x0e\\xf9\\xdd\\x8d\\x77\\x0d\\x7f\\xb0\\xfe\\xbb\\xb7\\x9f\\x09\\xe2\\xdb\\xf6\\xf9\\xb7\\x17\\xde\\x67\\xf8\\x57\\x4a\\xfb\\x8f\\x2c\\x5e\\xe2\\x9f\\xde\\x9e\\xc1\\xa1\\x2b\\x7f\\x4e\\xe2\\x39\\x27\\xb0\\xbf\\xd7\\x1e\\xab\\x5b\\x4f\\x48\\xb9\\x96\\x3d\\xc3\\x30\\x8c\\x66\\xbb\\xd5\\xc5\\x2d\\x19\\x86\\x25\\xdd\\xd7\\x63\\xcd\\x31\\x12\\xc3\\x30\\x1c\\x8b\\x98\\x03\\xca\\x30\\x8c\\x62\\xfb\\x0d\\x6f\\xc2\\xec\\xe9\\x3e\\x32\\x4e\\xba\\x34\\x82\\x79\\x86\\xbb\\xee\\x84\\x88\\xea\\x48\\xeb\\xcd\\x64\\x98\\x5c\\x1b\\x33\\x17\\xcd\\xc2\\x07\\x98\\xfa\\xc6\\x02\\xa2\\x91\\x49\\xfb\\xe6\\x72\\x7f\\xce\\x51\\x36\\x97\\x26\\x53\\x4b\\xc4\\x53\\x3a\\x58\\x36\\xea\\x2b\\xce\\x66\\xae\\xd7\\xcb\\x85\\x95\\x99\\x3d\\xf4\\x25\\xae\\x09\\x5d\\xc1\\xba\\xa6\\xb6\\x10\\x5c\\xca\\xc5\\x55\\x6c\\x19\\x91\\xb0\\x91\\xe9\\xd7\\x6b\\xc6\\xd6\\x7d\\x15\\xd7\\xb0\\x97\\xea\\x3a\\x56\\xa0\\x4a\\x0e\\x17\\xc1\\xb4\\x91\\x39\\x4a\\xc2\\xe0\\x4a\\xe1\\xf8\\xd9\\x81\\x37\\x1c\\x3f\\x9f\\x00\\x73\\xb1\\xa4\\xf6\\x91\\xc7\\x75\\x5c\\x32\\xb8\\xdb\\xbb\\x94\\xbe\\x94\\xc5\\x1d\\xa2\\xa5\\xfd\\xd6\\xd2\\x25\\x23\\x79\\xb6\\xce\\x5c\\x24\\x96\\x6f\\x0f\\x4a\\xee\\xd8\\xd4\\x65\\x18\\x83\\xe1\\xf3\\xa0\\x02\\x32\\x95\\x01\\x41\\xe6\\xba\\x25\\x4f\\x86\\x63\\x44\\xde\\x53\\x6b\\xd3\\xde\\x01\\x11\\x2c\\xc9\\xc1\\x94\\x9b\\x94\\x91\\xe4\\x0b\\x83\\x71\\x92\\x8d\\x3f\\x67\\xf6\\x21\\x48\\xcc\\xc1\\xe1\\xee\\xc1\\x9a\\xcc\\xc1\\x96\\xcc\\x2c\\xe8\\x67\\xc4\\xf4\\x4c\\xc3\\x30\\x4c\\x22\\x36\\x94\\x59\\x4b\\xcc\\x58\\x42\\x0c\\x69\\x58\\xb2\\x51\\xba\\x0c\\xa2\\xb4\\x0e\\xca\\xa6\\x0c\\xa2\\x48\\xe9\\x68\\x96\\xcc\\xdd\\xbc\\x30\\xad\\x5d\\x89\\x32\\x23\\x33\\xeb\\x93\\x2d\\xbd\\x50\\xb0\\x55\\x46\\x65\\x9e\\x25\\x57\\x4e\\x17\\xa6\\x56\\x4b\\x87\\x99\\xca\\x2b\\xe3\\x27\\xe1\\x61\\x3d\\x15\\x66\\x33\\x5d\\x26\\xeb\\xf1\\xf0\\xc1\\xd0\\x4c\\xc8\\x70\\x4c\\xeb\\x4a\\xf3\\xc9\\x30\\xa5\\xce\\x48\\x8c\\xb9\\x63\\xce\\x69\\xde\\x4a\\x87\\xd1\\xcb\\x9b\\xa6\\x80\\x98\\xd2\\x14\\xa9\\xe4\\x63\\x36\\x73\\x61\\x9e\\xb7\\xd5\\x3b\\xa3\\x4c\\x85\\xee\\x37\\x77\\x95\\x03\\xf3\\xda\\x15\\x07\\xa5\\xf3\\xb5\\x94\\xab\\x5c\\xa2\\x0a\\x5c\\x68\\xa5\\xc3\\xe5\\x1a\\xca\\x38\\xa7\\xa4\\x0d\\x3e\\xdf\\x2f\\xd0\\xbd\\x63\\xa0\\x53\\xe7\\x19\\x86\\xb9\\x6e\\x9d\\xf5\\x2c\\x30\\xcc\\xc0\\xf9\\x0e\\x5f\\x9d\\x0a\\x6f\\x93\\x2e\\xd1\\x41\\x68\\x8f\\x55\\x20\\x06\\xd9\\x4d\\xba\\x63\\x15\\x95\\x81\\xc0\\x26\\x3d\\x39\\x96\\x61\\x4c\\x67\\x06\\x37\\xa4\\x01\\x1b\\x3c\\x0b\\xf9\\xf4\\x96\\xb2\\xb3\\xe8\\x83\\x31\\xd1\\x24\\x8c\\x36\\xf8\\xcc\\xf5\\x5e\\x00\\x1e\\x74\\x22\\xcf\\xb6\\xf4\\xcb\\xc9\\xcc\\xb7\\x56\\xcd\\x9d\\x3b\\x65\\xb2\\x44\\xde\\x7b\\xbc\\x64\\xb0\\x50\\xca\\x95\\xb3\\x4a\\xda\\x5e\\xdd\\x27\\xd0\\x13\\xc3\\x66\\x00\\x3c\\x8d\\x2a\\x01\\x38\\xb5\\xd8\\x12\\xca\\x64\\x49\\x00\\x41\\xa7\\x27\\x23\\x5e\\x63\\x53\\x6e\\x97\\xa7\\xa2\\xf3\\x60\\x20\\x54\\x49\\x17\\xaf\\x6e\\x4f\\x76\\xc7\\xd3\\xe2\\x6e\\x3e\\x89\\xe2\\x87\\x01\\xec\\x98\\x07\\x82\\x21\\x36\\x40\\xb9\\x04\\xcd\\xde\\x73\\x16\\xc2\\x69\\xf7\\xa5\\x16\\x73\\x39\\x59\\xdb\\xd1\\x16\\x77\\x07\\xe1\\x22\\xa5\\xad\\x87\\x55\\xea\\x50\\x9c\\xea\\x2e\\xe2\\x09\\xcd\\x45\\x1a\\xca\\x9b\\xdc\\x5c\\x3d\\x40\\xc6\\x99\\x42\\x71\\x49\\x97\\xf9\\x29\\x92\\x2b\\x63\\x2a\\x2a\\xdf\\xdc\\xed\\xac\\x64\\x99\\x62\\xbb\\x2d\\x77\\xb6\\x57\\x1f\\x26\\x63\\x46\\xa7\\x79\\xe4\\x45\\xca\\x30\\xb2\\x0e\\x02\\x21\\xcd\\x28\\xcf\\x0b\\x73\\x46\\xf9\\x03\\x7b\\x32\\xcc\\xa6\\x97\\x61\\xa0\\xd4\\xae\\x00\\x9d\\x57\\x8e\\x61\\x18\\x4b\\xe1\\x58\\x65\\x62\\x59\\xf6\\x79\\xb2\\x82\\x72\\x32\\xfc\\x70\\xb2\\x62\\x72\\x32\\xc2\\x53\\xae\\xd8\\x87\\xc5\\xf0\\x9c\\xc3\\x18\\x2c\\xcb\\xb1\\xab\\xcd\\x88\\xcc\\x58\\x5d\\xe5\\x88\\xbd\\x7a\\x0e\\xa3\\x2f\\xe5\\x65\\x49\\x18\\xfe\\x3a\\x32\\x56\\xbb\\x5e\\xcc\\xe5\\x76\\xd9\\x75\\x06\\xed\\x30\\x56\\x4e\\xcb\\x7c\\x79\\x0a\\xcf\\xa8\\xbc\\xca\\x24\\x77\\x55\\x8f\\x2b\\x67\\x5a\\xec\\xc1\\x94\\x4e\\x68\\x5f\\x88\\x9a\\x15\\xea\\xfb\\x52\\xd6\\x67\\x59\\x06\\x6d\\x88\\x5d\\xa4\\x56\\x90\\x34\\x59\\x61\\x06\\x8e\\x1f\\x6a\\xd6\\xb2\\xa4\\x39\\x78\\x39\\x21\\x37\\xba\\xf2\\xf8\\xf0\\x60\\x49\\x02\\xa5\\x25\\xad\\x4c\\xfc\\xee\\xed\\x0c\\x30\\xf0\\xc9\\xc1\\x31\\x47\\xbd\\x1d\\xca\\x76\\x49\\xf7\\x46\\xba\\x1e\\xae\\x69\\xb8\\x4c\\xe7\\x31\\x6b\\x5c\\x16\\xd7\\x7e\\xba\\xf6\\xa2\\x61\\x65\\xbc\\x69\\x04\\x21\\xe7\\xf7\\xed\\x66\\x5d\\x27\\x33\\x37\\x42\\x0e\\xe9\\xc7\\xc2\\xb2\\x81\\x0a\\xce\\x18\\x96\\xae\\x7b\\xfc\\x5e\\x6a\\x97\\x9d\\x6f\\xe3\\x1b\\xe2\\x0b\\xe9\\x5d\\xca\\x84\\x50\\x6a\\xc2\\x6b\\x9d\\x88\\x42\\x6b\\x34\\x3e\\xef\\xf9\\xf7\\xd3\\xbb\\x8b\\x5e\\x89\\x66\\x95\\x9b\\x3c\\x65\\xbc\\x22\\x9f\\xe5\\x83\\xe9\\x57\\xe6\\x02\\x3c\\xa5\\xa0\\x37\\xcd\\x67\\x7b\\x70\\x0f\\x99\\x15\\xfd\\xcb\\x1e\\x9a\\x44\\xd9\\x90\\x9c\\x0e\\x5d\\xa6\\x5e\\xf2\\x9e\\x2d\\x5f\\xf1\\x22\\x27\\x1f\\x8a\\x33\\x5e\\x00\\x48\\x0e\\x7a\\x1b\\x48\\x2d\\x2c\\xbc\\x8f\\xfb\\x43\\xa8\\xae\\x13\\x97\\xac\\x92\\x85\\x55\\x5d\\xed\\xe5\\xf2\\x13\\x73\\x02\\x5c\\x93\\x64\\x86\\x94\\x1f\\xab\\xa5\\x73\\xf5\\xa5\\x79\\xf0\\xb2\\xcc\\x41\\xcd\\x64\\x6b\\x8b\\xa4\\xc6\\x96\\x33\\xf0\\xa4\\x7d\\xb9\\xb6\\xa9\\xc3\\x25\\xd3\\xe3\\x8a\\xca\\xe8\\x6a\\x4a\\x73\\xcf\\xcd\\x92\\x9c\\x5b\\x0b\\xce\\x18\\x8f\\x0b\\x60\\x03\\x54\\xc7\\xe3\\x6a\\xea\\xea\\xb3\\x2f\\x61\\x8f\\xa7\\xdc\\xd7\\x96\\x3d\\xc8\\xa6\\x6d\\xdf\\xbd\\xc6\\x00\\xdc\\xcb\\x10\\x51\\x87\\x39\\xb4\\xe5\\xd8\\x88\\xda\\x18\\x91\\x2e\\xa7\\x8c\\x92\\x3e\\xd0\\xb1\\xed\\x23\\x65\\xd6\\x30\\x9b\\x8b\\xe5\\xc3\\xe5\\xb4\\xe0\\xb6\\x0e\\xb4\\x76\\x8f\\xf8\\x83\\x30\\x97\\x9e\\x0e\\xcc\\xb6\\x6d\\xba\\xb8\\xc8\\x7a\\x15\\x68\\xa0\\xb5\\xec\\xb2\\x72\\xc7\\x85\\x86\\xe6\\x02\\xa8\\xdd\\x7a\\x16\\xe8\\x3a\\x22\\x34\\xa0\\xec\\xf9\\xd4\\xaa\\x12\\xe1\\x77\\xa8\\xaa\\x15\\xb6\\x99\\xae\\xc1\\x1c\\x0d\\x7b\\x8d\\x5e\\x6d\\x20\\x72\\x94\\x50\\x80\\xf0\\x3c\\x3a\\x04\\xf3\\x09\\x9f\\x52\\xd2\\xfa\\x79\\xc8\\xe3\\xd5\\xe6\\x79\\xe5\\x48\\xd7\\x03\\x25\\x44\\xa2\\x72\\x19\\x5c\\xa2\\xf1\\x62\\xaf\\x18\\x82\\x6e\\x6c\\x2c\\x2f\\x85\\x5d\\x10\\x0e\\xda\\x91\\x83\\xed\\xc9\\x33\\x81\\x29\\x68\\x22\\x7a\\x78\\x44\\xde\\x0c\\xf3\\xf7\\xd1\\xec\\x5c\\x61\\xdc\\xbc\\xd1\\x82\\xbd\\x95\\x78\\x20\\xd3\\x8c\\xdb\\x19\\xac\\x18\\xee\\x8d\\xb6\\x02\\x42\\x07\\x02\\x10\\xe1\\x80\\xf6\\xa6\\xcd\\x7d\\x2c\\x58\\x23\\x77\\xb5\\x15\\xcd\\x0d\\xc9\\xe2\\x7a\\x0d\\xa1\\x4a\\x98\\xc3\\x23\\x2a\\x84\\xd0\\x5c\\xa2\\xc3\\x2b\\x8d\\x49\\xbd\\xae\\xa1\\xe3\\xcb\\xc9\\xbc\\x75\\xb3\\x23\\x86\\x02\\xb0\\x2f\\x88\\x8a\\x2e\\x37\\x17\\xd2\\xce\\xb1\\x8d\\xe7\\x68\\x10\\xda\\x2e\\x8f\\xf6\\xd3\\xbc\\xe8\\xfb\\x24\\x96\\x14\\xdf\\x45\\xdd\\x65\\xd2\\xa5\\x14\\xd3\\xce\\x6e\\x5e\\x98\\x03\\x02\\xd5\\x44\\xf4\\xe3\\x11\\x6e\\xa7\\x80\\x58\\x34\\x7a\\x20\\x90\\x89\\x8c\\xc3\\x15\\x3e\\x48\\x2b\\x59\\x08\\x7a\\xda\\xb2\\x80\\xcb\\x4c\\x19\\x9a\\xbb\\xc2\\x25\\x12\\x67\\x42\\x33\\xb3\\x25\\xb4\\x69\\xb0\\xd6\\xde\\x27\\x10\\x34\\x30\\x88\\x3b\\xe9\\x84\\xc0\\x82\\x13\\x66\\x07\\x1f\\x9b\\xab\\x13\\x19\\x6a\\x59\\xa0\\xb7\\xd0\\x8a\\x01\\x0b\\xc0\\xb4\\xc1\\x2b\\x68\\x89\\x67\\xfa\\xd4\\x98\\x12\\x79\\xb0\\xcd\\x7c\\x73\\xaa\\x3b\\x75\\x3b\\xcc\\x10\\xa8\\xa6\\xf6\\xda\\x62\\x50\\xc1\\x5d\\xb0\\xb8\\xb4\\x0e\\xa4\\x26\\x1e\\xa9\\xd5\\xf7\\xb4\\x20\\xf7\\x47\\x8e\\xc9\\x2b\\x21\\x46\\xc0\\x0d\\xce\\xd9\\x14\\x88\\xc6\\x7d\\x13\\xaf\\xca\\xac\\x69\\x78\\x83\\x5e\\x67\\x2a\\xf4\\xe5\\xe1\\xb6\\xac\\x8f\\x5d\\x71\\x04\\x5c\\xc5\\x86\\x33\\xb2\\xa6\\xb6\\x8d\\x09\\x28\\x71\\x9c\\xec\\x76\\xde\\x0e\\xee\\x4c\\x27\\xad\\x9e\\x8f\\xfc\\xd0\\xf5\\xcc\\x4f\\x63\\x1c\\xaf\\xb6\\xa5\\xa5\\x10\\xf0\\xd0\\xaa\\xd8\\x13\\xba\\x9b\\xa7\\xd4\\x67\\xac\\xee\\x78\\x12\\x37\\xdd\\xa9\\xb2\\x51\\xa4\\x35\\x5b\\x3e\\xb7\\x42\\x08\\x78\\x5d\\xe3\\xd3\\x5e\\x12\\x4c\\x97\\xce\\x0f\\xf4\\x79\\x26\\x10\\xd4\\xf7\\x90\\xdd\\xbc\\xc2\\x79\\xc2\\xcb\\x33\\xd1\\x52\\x2b\\x32\\x2a\\x48\\x32\\xa5\\x16\\xd2\\x22\\x68\\x21\\xe8\\x92\\x7b\\x3f\\x3a\\x5b\\x29\\x3c\\x27\\x59\\xfa\\x9d\\x34\\xce\\x99\\x5b\\x8f\\x98\\x64\\x92\\x45\\x2f\\xa2\\x8a\\xae\\x03\\x24\\x29\\x12\\x43\\x4c\\x9f\\xe9\\xa5\\x42\\x7d\\x1d\\x35\\xc9\\x42\\x94\\xa1\\x2c\\xdd\\x91\\x44\\xe4\\x28\\x82\\x70\\x2a\\xed\\xa6\\x0f\\xbb\\xd2\\xf1\\x84\\x97\\x75\\x57\\x24\\xaf\\x52\\x1c\\x3d\\x35\\x2b\\x6f\\x6d\\x9c\\x57\\x2f\\x43\\x86\\x34\\x7b\\xe6\\x24\\x71\\xae\\x0c\\x08\\x51\\xe4\\xf3\\xea\\xe1\\xd6\\xb4\\xae\\x8b\\x02\\x43\\xa0\\x7f\\x6f\\xc9\\x35\\x41\\x15\\x34\\x4a\\x32\\x27\\x3b\\x79\\x54\\x28\\xe2\\x8d\\x74\\x6c\\x22\\xb9\\x52\\x4d\\xf6\\x3c\\xd1\\xcd\\x2c\\x9c\\x27\\x0d\\xdf\\xeb\\x34\\x3d\\xef\\x5d\\x9c\\x27\\x03\\xa5\\x9e\\x0f\\x3d\\xdd\\x82\\x2e\\xca\\x7d\\x8f\\x24\\x37\\x0b\\x37\\x66\\xfc\\xd9\\x76\\x4b\\xf8\\x4c\\xd2\\x7b\\xb2\\x0b\\x5b\\xb9\\xa5\\x0b\\x19\\xf2\\x3d\\x60\\xf8\\x01\\x71\\xae\\x0f\\xde\\x98\\x43\\x80\\x19\\x68\\xa2\\xc3\\x72\\x60\\x98\\xb0\\x1a\\x3d\\x11\\x40\\x42\\x49\\xbf\\x18\\x1a\\x80\\x05\\x8f\\x1c\\x38\\x37\\xe2\\x00\\x11\\x03\\x50\\xc1\\x2a\\x2f\\x24\\x9f\\x72\\x31\\x21\\x64\\x44\\x96\\xc9\\x5d\\x76\\x0b\\x2f\\x71\\x99\\xdc\\xf8\\xf8\\x79\\x2b\\x58\\xf9\\x71\\x19\\xcc\\x14\\x66\\x43\\x48\\x58\\x9f\\xe1\\xc6\\xf3\\x98\\x67\\x96\\x4f\\x99\\xf7\\x1e\\x45\\x3a\\x68\\xdb\\x93\\x2d\\x8e\\x2b\\xd8\\xdc\\x6f\\xf4\\xde\\xa9\\xf2\\x64\\x09\\x69\\x2f\\x75\\x96\\x17\\x5f\\xc1\\xfe\\x79\\x72\\xd1\\x4d\\x5c\\x42\\xeb\\xde\\x27\\x06\\xa7\\x51\\x66\\xd1\\x02\\x2d\\xe0\\x9e\\xc3\\xa9\\x86\\x52\\xad\\xb3\\x62\\x22\\xd5\\x98\\x88\\x3c\\xa2\\xd6\\x2a\\xf0\\xc2\\x32\\x07\\xe5\\xae\\x8c\\xea\\x3a\\x58\\x8b\\xa0\\x41\\x69\\xe0\\xa0\\xaa\\x16\\xcf\\xb8\\xd0\\x91\\x11\\x89\\xe8\\x54\\x08\\x0c\\x77\\xf5\\x41\\x22\\xc8\\x88\\xa4\\x5d\\xd4\\x4d\\xd7\\x61\\x76\\xdb\\xfd\\x4e\\xca\\x2b\\x56\\xaa\\xf5\\xb8\\x4a\\x02\\x56\\x81\\x95\\x40\\x45\\xa9\\x9d\\xb1\\xb7\\x07\\x97\\x23\\x32\\x7e\\x73\\xc2\\x9d\\x47\\x64\\x0c\\xbd\\x71\\x38\\x72\\xc4\\x37\\xfc\\x7c\\xb4\\x8d\\xed\\x67\\x57\\x7d\\xc5\\xb3\\xa3\\x5e\\xad\\xa2\\x25\\x52\\x52\\xed\\xba\\x94\\xf2\\x1d\\x2f\\x7a\\x88\\x4f\\xac\\x8a\\x4a\\xbb\\x21\\x25\\x10\\x0f\\x6f\\xa5\\xd9\\x30\\xdb\\xf5\\x02\\x36\\x03\\x82\\x6b\\xa2\\x65\\x1c\\x95\\xbc\\x0a\\x0e\\xe4\\x03\\x7d\\x8f\\xd4\\x6e\\x72\\x45\\xd7\\x4b\\x4f\\x3d\\xd6\\x38\\xf3\\x86\\x00\\xd1\\x35\\x88\\x2c\\x5c\\x83\\x88\\xa5\\xc8\\xb0\\xba\\xe0\\x7a\\x7b\\x36\\x86\\x5b\\x2f\\xf8\\xc3\\x6a\\xed\\xd5\\x36\\x4e\\xc7\\x8b\\x2e\\xf0\\x42\\xcc\\x27\\xdd\\xec\\x88\\x0d\\xe1\\x8d\\x7c\\xb8\\x9d\\xa2\\xd9\\xbc\\xdf\\xfa\\x0b\\xb7\\x05\\x37\\x35\\xed\\x17\\x88\\x6e\\x95\\x63\\x75\\xf8\\xdc\\xc2\\xf1\\x16\\x55\\xae\\xb8\\x2e\\x1e\\x5b\\xf1\\x90\\xc0\\xe6\\xa4\\xe8\\xd9\\x4b\\x24\\xef\\x06\\xc5\\x3a\\xe4\\x8e\\xb8\\xc9\\x57\\xd1\\x4d\\x25\\xca\\x29\\x17\\xe6\\xd0\\x47\\x6b\\xcc\\x56\\x61\\xc9\\x5f\\xcc\\x13\\x45\\x12\\x80\\xd8\\x1e\\x77\\x0e\\x93\\xfc\\x42\\x45\\xcc\\x59\\xe0\\xb0\\x59\\x35\\xc2\\x55\\xac\\x22\\x2a\\x67\\xea\\x0d\\xf2\\x49\\xa1\\xd6\\x55\\x77\\xcf\\x50\\xf5\\x2e\\x64\\xee\\x34\\x3c\\xf2\\x6b\\xf7\\x84\\x3a\\x54\\x8d\\x6f\\xeb\\xd1\\x6c\\xb0\\x89\\x35\\x95\\xed\\x15\\xf2\\x98\\x67\\xe7\\x71\\x6f\\x14\\x1e\\x1a\\xfd\\xc6\\x3c\\x56\\xce\\x3b\\x6d\\x6f\\x8c\\x1c\\xf9\\x40\\x88\\x95\\x16\\x46\\x3c\\xdc\\xbd\\xaa\\xf1\\x2d\\x8f\\x44\\xc6\\x00\\xf6\\x16\\xbf\\x38\\xfa\\xa0\\xf1\\x80\\x39\\x55\\x8e\\x7e\\xda\\xea\\xa7\\x35\\xdd\\x5b\\xac\\xc9\\xf4\\x80\\xf6\\x28\\x3a\\x68\\x16\\x64\\x99\\x72\\x7b\\x2a\\x14\\x32\\x5f\\x24\\x82\\x70\\xa6\\x64\\x3c\\x51\\x3f\\x01\\x36\\x7b\\x82\\x47\\x33\\x0b\\xcc\\x6a\\x63\\xb4\\xc9\\xda\\xf6\\x7b\\xee\\x26\\x01\\x02\\x2b\\x68\\x67\\x57\\x79\\x3b\\xc1\\xf7\\x19\\x81\\x5e\\xd9\\x81\\x39\\xbd\\x4a\\xcb\\xe1\\xe4\\x54\\xe3\\x19\\x01\\x95\\x4a\\x1b\\x0d\\x24\\x1f\\x60\\x30\\x48\\x17\\x1f\\x8c\\x91\\x69\\x21\\xc9\\x48\\x5e\\x26\\x7f\\xa3\\x61\\x34\\x07\\x6f\\x7a\\xb9\\x43\\x9e\\x4e\\x93\\x5b\\xa3\\x1f\\xd4\\x62\\x2f\\x98\\x87\\xac\\xb4\\x15\\xa0\\x70\\xb2\\xa8\\x6b\\xb9\\x20\\xc6\\xb5\\x95\\x92\\x75\\x02\\xdb\\x62\\x41\\x30\\x0b\\xcd\\x8c\\x3d\\x22\\x8c\\x9c\\xf0\\x48\\x16\\x8c\\x04\\x12\\x58\\xc6\\xec\\x4a\\xcf\\xa8\\x02\\x80\\x1b\\x29\\xc9\\x89\\x27\\x21\\x77\\x0b\\x97\\xf4\\x8e\\x6f\\x5a\\x8c\\xdd\\x90\\x61\\x5b\\xda\\x2e\\x87\\x53\\xa1\\x1f\\xf9\\x59\\x66\\xf1\\xf4\\xd2\\xa1\\x44\\x44\\xe5\\x80\\x66\\x12\\x8a\\xa8\\x3f\\xe9\\x93\\x3f\\x33\\x20\\x2a\\xc8\\x02\\xe6\\xf4\\x45\\xca\\xed\\xcd\\xd6\\x27\\x1a\\x9e\\x38\\xe4\\x9e\\xc4\\x0c\\xdd\\x27\\xe8\\x46\\x48\\xc7\\xbd\\xb3\\xe0\\x5c\\x74\\x73\\x60\\x01\\x69\\x80\\x3c\\xc5\\x7b\\x88\\x06\\xa2\\x16\\xd2\\x41\\x37\\x72\\x99\\xc2\\xa3\\x3b\\x90\\xdb\\xdc\\x03\\xd0\\xbb\\x48\\xc9\\xf3\\xce\\xc5\\x40\\x23\\xb3\\x23\\x54\\xec\\x50\\xc7\\x38\\xa2\\x18\\x86\\xad\\x20\\x81\\x3b\\x93\\x02\\x72\\x63\\xcf\\x20\\xf2\\x71\\xa0\\x01\\x58\\xc8\\x14\\x4d\\x76\\x77\\x18\\x7d\\x6e\\x22\\x0f\\x49\\x5b\\x56\\x23\\x87\\x8f\\xda\\x04\\x44\\x4f\\x77\\x58\\x2c\\x3a\\x9e\\xc6\\xdc\\x7a\\xf3\\x11\\x70\\x8a\\x8a\\x42\\x25\\xbd\\x94\\x9a\\x3a\\x07\\x72\\xf2\\x99\\x84\\x72\\xd0\\x29\\xc0\\x61\\x7c\\x6a\\xde\\x09\\x83\\xf7\\x40\\x6d\\x90\\x22\\x4f\\xd0\\x6d\\x5f\\x9f\\xc9\\x82\\x60\\x2d\\x6a\\x1d\\x98\\x9c\\x4c\\x30\\x20\\x26\\x08\\x69\\x65\\x28\\xb7\\xe2\\x37\\x54\\x80\\x89\\x3b\\x5a\\x6f\\xa0\\x4a\\xc6\\x60\\xde\\x8b\\x40\\x09\\x8e\\x05\\xe9\\x00\\xb3\\x1f\\x30\\x49\\xce\\x63\\xe1\\x8d\\x2d\\x4f\\x4a\\x8b\\x78\\x80\\xd2\\xb9\\x30\\xcf\\xc1\\xc1\\x01\\x21\\xac\\xa8\\xa0\\x47\\x71\\xb3\\x68\\xf7\\x6e\\xd5\\xba\\x76\\xc7\\xa1\\x42\\xdc\\x67\\xed\\x3a\\xa1\\x47\\x74\\x23\\x1c\\x2c\\xce\\x8f\\x61\\x37\\x8c\\xa3\\xc3\\x7d\\x10\\xed\\xa6\\x94\\xd8\\x3a\\x14\\x44\\x6b\\x00\\xda\\x0c\\xdf\\x38\\x43\\x8a\\xd9\\xf0\\x9a\\x02\\xc0\\xa9\\x6b\\x07\\x0a\\x55\\xb7\\x91\\x68\\x37\\x7d\\x4e\\xef\\xfb\\x0e\\x50\\x67\\xf7\\xa0\\xa9\\x38\\xa1\\xa6\\x94\\x4c\\x8a\\x1c\\xc0\\x48\\x72\\x2a\\x76\\x12\\x2a\\x5a\\xfb\\x4e\\x99\\x06\\x6e\\x52\\xb4\\x48\\x84\\x54\\xde\\x41\\x17\\x10\\x35\\xd6\\x8c\\x02\\xb7\\xe7\\x46\\x63\\xce\\x09\\x40\\xa0\\x2c\\x45\\xd4\\x6b\\xce\\xbb\\x86\\x8f\\x45\\xb4\\x18\\x1e\\x64\\x0c\\x8a\\x01\\x09\\x8e\\x1e\\xf0\\xdb\\xeb\\x5c\\x4e\\x2f\\x55\\x94\\x3e\\x19\\x46\\xad\\x6f\\x0c\\xc3\\x61\\x77\\x26\\xa8\\x1b\\x03\\x0d\\x5f\\xef\\xc4\\xec\\xd2\\x68\\x96\\x59\\xe4\\x6c\\x69\\xda\\xd2\\xdd\\xb8\\x33\\xeb\\x6b\\x52\\x64\\x4a\\xe6\\xd2\\x5c\\x4c\\xcf\\xc2\\x90\\xf5\\xcc\\x32\\x84\\x4d\\x60\\xb4\\x43\\x53\\x5f\\xb2\\xa4\\xcb\\xc5\\x96\\xd5\\x3b\\x3a\\xd4\\x96\\x9e\\x84\\x4d\\xbc\\xd4\\x41\\xd4\\xac\\xe6\\x92\\xa7\\xfd\\x7d\\x8e\\x90\\x87\\x9f\\x22\\x3a\\x74\\x44\\x0b\\x46\\x5a\\x1b\\x84\\x5a\\x0f\\x7d\\x6e\\x93\\xa1\\x6d\\xae\\x18\\x09\\x37\\x3e\\xa5\\xc5\\xf0\\xc4\\xb4\\x15\\x64\\x29\\x22\\x27\\x35\\xe4\\x1d\\x62\\x1f\\x25\\xcb\\xde\\xa5\\x0d\\xe5\\x09\\x0f\\x10\\x4d\\x5a\\x90\\x7a\\x81\\xe4\\x31\\x7e\\xc3\\x9f\\x00\\xfa\\xb0\\xdb\\x14\\x3f\\xc9\\x8e\\xba\\xa9\\x14\\x56\\xb0\\x69\\x93\\x15\\x13\\x6f\\xbe\\xc9\\xc4\\x48\\x5c\\x89\\x89\\x0c\\xc1\\x3f\\x5d\\xa6\\x60\\x24\\x73\\x5e\\x69\\x28\\xbf\\x5a\\x8d\\x2c\\x62\\xdc\\x34\\x28\\xa1\\xf0\\xed\\x92\\xeb\\xc1\\x0e\\x40\\xc5\\x49\\x02\\x3f\\x3a\\xb9\\x2d\\x85\\x52\\xe0\\x1d\\x88\\x36\\xc8\\x0a\\xa4\\xf1\\x75\\xd2\\xa7\\x16\\x0e\\x19\\x0f\\x02\\x05\\xb0\\xbb\\xbc\\x81\\x98\\x1a\\x17\\xb6\\x51\\x87\\xdf\\x77\\x90\\xde\\x75\\xef\\x50\\x3d\\xe4\\xc8\\x35\\x84\\x58\\x1c\\xd1\\x82\\x0a\\xf3\\x62\\x6a\\xfc\\x44\\xe4\\x10\\x9d\\x1b\\xac\\x69\\x23\\xcb\\x64\\x3f\\xa6\\x43\\x38\\x41\\x50\\xb7\\x7a\\x2e\\xe0\\xd1\\x23\\x35\\x5f\\x58\\x58\\xc6\\xd5\\x1a\\x10\\xd3\\xb9\\xea\\x09\\x15\\xdc\\x73\\x56\\x20\\x7f\\x45\\x8f\\xc8\\xdd\\x82\\xc9\\x83\\x1c\\xc1\\xf2\\x04\\xff\\xc9\\x5c\\x86\\x82\\x04\\xc0\\xf2\\x26\\xf2\\x30\\xdc\\xc7\\xc9\\x23\\xa5\\x32\\x18\\x25\\x4f\\xb8\\x19\\x6c\\x1f\\x62\\x93\\x8a\\xc0\\xf5\\x77\\x59\\x4b\\x85\\xad\\x17\\x7a\\x03\\xc1\\x30\\x05\\xb3\\xa9\\x49\\x1b\\x10\\xe8\\x9c\\x31\\x27\\x3b\\x59\\x4a\\xee\\x6e\\x1c\\x33\\x07\\xdb\\xf3\\xcc\\xf3\\x26\\x76\\x67\\xe7\\x0a\\xda\\x49\\xa1\\x5b\\xd5\\xdd\\x1f\\x2b\\x39\\x2e\\x05\\x10\\xc9\\xca\\x10\\x4b\\xf8\\x53\\x73\\xef\\xe2\\x33\\x7d\\xc3\\xc7\\xca\\x33\\x8a\\xd2\\x03\\x4e\\x74\\x8e\\x07\\x80\\xe0\\x23\\x7d\\x8c\\x40\\x36\\xc3\\x23\\x3d\\x48\\x3c\\x27\\x9a\\x6f\\xa8\\xd0\\xb3\\xa3\\xc0\\xd6\\xa1\\xe6\\x65\\x59\\x37\\x3f\\x10\\xa8\\x36\\x80\\x58\\xb2\\x6c\\x3f\\x79\\xba\\x32\\xa7\\x76\\x27\\x81\\x07\\x4e\\x01\\xb2\\xdb\\xd9\\x2c\\x48\\xa4\\x0d\\xbb\\x33\\xa6\\xb1\\x62\\x11\\xff\\x9c\\x55\\xee\\x79\\xdc\\x36\\x45\\x4e\\xd0\\x5d\\x1b\\xe9\\xc0\\x96\\x73\\x2e\\x7e\\x48\\x14\\xff\\x6e\\x17\\xd5\\xbc\\x51\\x14\\x00\\xd3\\x16\\x85\\xd9\\x06\\x28\\xd8\\x0f\\xbc\\x94\\xd8\\xb3\\xf2\\x1d\\x6a\\x5e\\x37\\x7f\\x4a\\xe0\\x1d\\x7b\\x86\\x31\\xeb\\x3d\\x27\\xea\\x9b\\x5d\\x58\\x76\\x8c\\x91\\x0d\\x24\\x73\\x10\\x4c\\x25\\x77\\x83\\xf4\\x06\\x3a\\xf0\\x70\\xf5\\x93\\xa5\\xcd\\x02\\x0b\\xd2\\x74\\x88\\x93\\x94\\x13\\x00\\x7b\\x01\\xe5\\x1b\\x68\\xb8\\x9a\\x94\\xca\\xd1\\x5a\\xaf\\x09\\x20\\x48\\x0c\\xd9\\x3d\\x6c\\xe5\\x5e\\x40\\xb9\\x05\\x90\\x21\\xf5\\x0d\\xe1\\x85\\x31\\x8f\\x79\\x53\\x1d\\x17\\xd7\\xaf\\xd5\\x33\\x05\\xa6\\x72\\x4b\\xd5\\x26\\xdd\\x21\\x20\\x9d\\x94\\x71\\xf5\\x13\\x19\\x83\\xb2\\x11\\x8e\\xa1\\xf3\\x61\\x97\\xcc\\x05\\xa2\\xb7\\x84\\xa6\\x88\\xea\\xb9\\x67\\xb1\\xbf\\x91\\x35\\xbd\\x24\\x35\\x56\\xfa\\x17\\x8c\\xe2\\xe7\\x59\\xa4\\x3e\\x14\\xcb\\xa5\\xce\\x80\\xac\\xf9\\xa6\\x2f\\x9d\\x57\\x9c\\x8d\\x37\\x2e\\xd9\\x76\\xad\\x2b\\x7f\\x0b\\xa6\\xbe\\x55\\xef\\xb1\\xb7\\x31\\xac\\x13\\xc0\\x59\\x40\\x9f\\xa3\\xc8\\x4f\\x56\\xba\\x05\\x6b\\x10\\x14\\xc0\\xb8\\x5b\\xa8\\x76\\xcc\\xeb\\x23\\xb9\\x31\\xdb\\xdb\\xdc\\xc9\\x30\\x1c\\x83\\xe9\\x16\\xa4\\x6f\\x20\\x8c\\xa2\\x14\\x76\\x3b\\xb5\\xb3\\xf1\\x80\\x0d\\xf2\\xcb\\x51\\x99\\xc7\\x2d\\x20\\x0b\\x3f\\xe1\\x13\\xc7\\x30\\x39\\x25\\xbe\\x82\\x9b\\x2e\\x3a\\xd8\\xa1\\xf8\\xc8\\x32\\x6e\\xa0\\x02\\x35\\xb2\\xed\\x81\\x04\\xb6\\x66\\x83\\xe8\\x30\\x64\\xa7\\x50\\xdc\\x1b\\x7f\\x4c\\xa5\\x63\\xb9\\x58\\x09\\xb9\\xd7\\x0c\\xc4\\x3a\\x4e\\xa0\\x3a\\x19\\x16\\x6e\\x24\\x39\\x12\\xcd\\x48\\x31\\xbd\\xf4\\x31\\x4d\\xf4\\x1a\\xb8\\x32\\x65\\xf0\\xd0\\x45\\x92\\x17\\xb5\\xa1\\xa7\\x5c\\x0f\\x0e\\xac\\x27\\x8c\\xd3\\xdf\\xc0\\x9a\\x6a\\x3d\\x95\\xb0\\xb0\\x67\\x0c\\x38\\xf7\\x6f\\x31\\xb6\\xf8\\xce\\x8e\\x8d\\x9b\\xb1\\x1f\\x80\\x23\\xeb\\xdd\\x8c\\x24\\x13\\x01\\x74\\x86\\xc0\\xed\\x51\\xba\\x20\\xf8\\x12\\xb7\\xbd\\x92\\x98\\x4e\\xe9\\x41\\xa8\\x26\\x60\\x58\\xaa\\x67\\x53\\x06\\x9d\\xba\\xba\\x11\\x9b\\x17\\x57\\x99\\xdf\\x68\\x1a\\x1f\\x6a\\x89\\xb4\\x3f\\x3f\\x6c\\x6d\\xcf\\xb4\\x61\\x43\\xb8\\x1e\\x34\\xcf\\xd4\\x60\\x63\\x90\\x90\\x1e\\x76\\x9e\\x26\\xd7\\xaa\\x8f\\xaf\\xd8\\xac\\x70\\x04\\x40\\x26\\x2d\\xec\\x47\\x75\\xa2\\xb1\\x3a\\x9b\\x04\\x23\\x88\\xa2\\x46\\x7b\\x7d\\x42\\xb9\\x7e\\xae\\x52\\x4e\\x47\\x64\\xcd\\x16\\x37\\x8d\\x2d\\x0d\\x8d\\xbd\\xc6\\x5a\\xc1\\x3e\\xdf\\x4d\\x7e\\x7b\\xfa\\x2a\\x3c\\x62\\x39\\x05\\x26\\x33\\xb8\\x92\\x2f\\x38\\xf3\\xb1\\xa9\\x55\\x14\\xfb\\xa8\\x7c\\xa4\\x04\\x1d\\x2f\\xaa\\x7d\\x97\\x06\\x9c\\x62\\xf0\\x07\\x61\\x0f\\xbc\\xd6\\x11\\x18\\x96\\x17\\x41\\xf6\\xc8\\x44\\x47\\x5f\\xc8\\x4a\\xa0\\x59\\x3d\\xe4\\x40\\x79\\xff\\xf0\\xa1\\xa7\\x0f\\x57\\xd6\\xd6\\x15\\x45\\xd1\\x83\\xe2\\x0d\\x4f\\x83\\x38\\x07\\xfb\\x58\\x07\\x7b\\xfb\\x42\\x1b\\x2b\\x42\\x66\\xeb\\x2a\\x09\\x14\\xf0\\x18\\x4b\\xad\\xd9\\x57\\x1a\\xf5\\xb4\\x24\\xd8\\xb6\\x6e\\xbb\\x85\\x53\\xa0\\x83\\x99\\x77\\x93\\x1b\\x0d\\x28\\x2a\\x3c\\x63\\xf3\\x98\\xfb\\xce\\xe7\\x71\\xb3\\x5a\\xcd\\x0a\\x7d\\xc1\\x49\\x41\\x23\\x0d\\x88\\x11\\x5d\\x00\\x30\\xc2\\x71\\xdc\\xb0\\x1f\\x43\\xbc\\x22\\x11\\x6c\\x05\\x6d\\xe4\\x8f\\x48\\xbb\\x99\\xdc\\xfa\\x98\\x8d\\x4a\\x17\\x7d\\x82\\x98\\x1d\\xd9\\x85\\x35\\xc7\\x25\\x71\\xe2\\x74\\x5d\\x55\\x81\\xcd\\x51\\x48\\x20\\x01\\x7f\\xa8\\x0d\\x1d\\x4c\\x03\\x53\\xbe\\x87\\x6e\\xcd\\xbb\\x70\\x80\\xde\\x5b\\x24\\xcf\\x28\\x00\\x1f\\x77\\x79\\x31\\x46\\x38\\x5e\\x7d\\xb5\\x69\\x67\\x08\\xe8\\xfa\\x9b\\xc4\\x4c\\xad\\x7c\\xa4\\x86\\x48\\xd6\\xb8\\xde\\x8e\\xc4\\xd0\\x46\\x57\\x0b\\x00\\xa6\\xcb\\xd8\\x00\\xeb\\x18\\x80\\xf4\\x30\\x6b\\x8b\\x56\\x85\\x1c\\x19\\x1a\\x4f\\xec\\x0d\\x29\\x27\\xaa\\x67\\x5d\\x8e\\x9a\\x35\\x1a\\x5a\\xb4\\x19\\x55\\x0c\\x8f\\x33\\x3c\\x20\\x64\\x36\\xd1\\x27\\x61\\x70\\x0a\\x9e\\xce\\xa3\\x47\\x10\\xd2\\x5d\\x3a\\x1e\\xe7\\x93\\x01\\xc2\\xab\\xf5\\xc0\\x6f\\x35\\xb9\\x03\\xd3\\x74\\x92\\x5d\\x96\\x0c\\x00\\x98\\x0b\\x51\\x2b\\xaf\\x17\\xec\\x26\\x16\\xf3\\x67\\xae\\x52\\x29\\x14\\xed\\xce\\x29\\x13\\x7c\\xb8\\x83\\x31\\xca\\xe0\\x77\\xea\\xc8\\x65\\x61\\x84\\xf3\\xad\\xbe\\xfb\\x51\\xcc\\xfb\\xcc\\x2b\\xd9\\x90\\x03\\x91\\xf7\\x50\\x6e\\x68\\x1e\\x80\\x49\\x97\\xd6\\xee\\xb0\\x18\\xa3\\xa3\\x70\\x51\\xe0\\x74\\x1e\\xe8\\x80\\x11\\x55\\x01\\x14\\xdf\\x83\\xc0\\x04\\x6f\\x83\\x62\\x83\\x48\\x70\\x3f\\xd7\\xec\\xac\\x6e\\x9d\\x83\\x23\\xeb\\x58\\x63\\x8b\\xea\\xb5\\x67\\xdc\\x78\\x63\\x5c\\xf6\\x1a\\x0b\\xc9\\x3e\\x85\\xf9\\x7e\\x48\\xe5\\xfa\\x82\\x66\\x10\\x20\\xba\\xee\\xe2\\x0d\\x99\\xdf\\xc8\\xb7\\x05\\xbb\\xe2\\xd2\\x4e\\x7d\\xa0\\xb3\\xc1\\x4e\\x3e\\x67\\x42\\xbf\\xf7\\x47\\xda\\xc8\\xe0\\x13\\xad\\xa8\\xe0\\x3e\\x12\\xeb\\x34\\x11\\xeb\\x74\\x52\\xa0\\xea\\x4f\\x02\\xee\\xf9\\x42\\xc5\\x20\\x98\\x68\\x62\\x41\\x4c\\x9e\\x74\\xe2\\x89\\xe7\\x82\\x14\\x62\\xf5\\xb0\\x64\\x9c\\xf4\\x1b\\xcb\\x15\\xae\\x90\\x88\\xf7\\x38\\xf5\\xc9\\xa3\\x60\\x8e\\x9e\\xdf\\xc8\\x54\\xd8\\x3a\\x03\\x62\\x86\\x04\\x2c\\x27\\x08\\xf1\\x8a\\x6f\\xfb\\x31\\xf0\\xfe\\xe4\\xc1\\xbe\\xdb\\x20\\x0f\\xe8\\xba\\xf5\\x06\\xcb\\x5f\\x49\\x34\\x20\\x0f\\x58\\x6f\\x9c\\x81\\x58\\x28\\x00\\xe7\\x78\\xe5\\x98\\x27\\x35\\x0e\\xce\\xf2\\x0a\\x02\\x1c\\x26\\x9e\\xdf\\x62\\xab\\x8f\\xb9\\x69\\x05\\xb7\\x00\\x04\\x83\\xe2\\x56\\x52\\xb1\\x60\\xf9\\x70\\x3a\\x07\\x87\\x90\\xae\\x81\\xe5\\x5a\\x97\\x1b\\xe3\\x31\\x0f\\xf6\\x11\\x89\\x0e\\x0c\\x80\\x37\\x3b\\x9a\\x51\\x77\\x6d\\xa0\\x4d\\x4f\\x1d\\x37\\x3e\\x33\\x8a\\xa2\\x4c\\x74\\x55\\x7a\\xd6\\xf8\\x9e\\xf3\\x18\\x7b\\xbe\\x4b\\x67\\x08\\x41\\x6d\\x4d\\xbb\\x23\\x4e\\xb0\\x8e\\x0b\\x1b\\x24\\xbf\\x3f\\xa9\\x74\\x73\\x32\\xcb\\x9c\\x27\\xa5\\xc9\\x57\\xfb\\x52\\x49\\x21\\xa7\\x30\\x92\\xc6\\xfb\\x70\\x47\\x52\\xfb\\xad\\xf5\\xe1\\x26\\x01\\x8d\\x80\\x3c\\xb9\\x4d\\x3d\\xd2\\xb2\\x13\\x19\\x8f\\xaa\\xbe\\xd9\\xbd\\x92\\x46\\xfb\\xb1\\xca\\xf7\\x1d\\x02\\x25\\x83\\x20\\x1d\\xc2\\xd9\\xe1\\x75\\x1d\\x20\\x2f\\xf0\\x2a\\x33\\xbd\\x8e\\xc7\\xe0\\x0a\\x6c\\xd1\\xdd\\x58\\x8b\\x93\\xd0\\x2b\\x8e\\x06\\x05\\x82\\x63\\x47\\xa6\\xf3\\x25\\xa6\\x2b\\x4d\\x75\\x8d\\xdd\\x87\\x9c\\x3e\\x45\\x8c\\xdb\\x1e\\x1f\\x0e\\xca\\xba\\xa7\\x4c\\x81\\x0e\\x2e\\x50\\x20\\xaf\\x6c\\x30\\xbd\\xbd\\x95\\x6f\\x64\\x18\\xc3\\x87\\xca\\x1e\\x78\\x38\\x09\\xf5\\x9e\\x8c\\x19\\xdf\\xb7\\xac\\x59\\x4a\\x17\\x5c\\x77\\x06\\x88\\xc8\\xa6\\x71\\x5c\\xe7\\x6c\\x5b\\x8e\\x26\\xae\\xbd\\x71\\xeb\\xce\\x63\\xa9\\xad\\x92\\x2d\\x24\\xeb\\xc3\\x54\\x92\\xad\\x90\\xca\\x31\\xd7\\x52\\x2d\\x11\\x79\\x33\\x44\\xe9\\x1c\\x8a\\x55\\x83\\x53\\x04\\x92\\x01\\x4f\\x2a\\x0d\\xd4\\xe1\\x41\\x85\\xbd\\x77\\x20\\x9a\\x26\\x8f\\xe1\\xf5\\x22\\x44\\x86\\x03\\x80\\xfb\\xe3\\x78\\xcb\\x67\\xb4\\xd8\\x53\\x12\\xed\\xdb\\x8f\\x61\\x5f\\x35\\x6b\\x0d\\x05\\x8a\\x0d\\x3e\\x7b\\x88\\x51\\xe0\\x26\\xd8\\xf5\\x84\\x2a\\xf0\\x60\\xda\\x96\\xdc\\xdb\\x09\\xd1\\x45\\xe1\\x64\\x2f\\x9f\\xec\\xf0\\x12\\x9c\\x90\\xbb\\x40\\xad\\x01\\x0e\\x04\\xcd\\xed\\xc2\\x31\\xfa\\x42\\x2f\\x34\\xd9\\x9d\\x3c\\x91\\x69\\x1e\\xea\\x40\\xb4\\x59\\xb9\\x48\\x01\\x62\\x54\\x54\\x16\\x4f\\xa9\\xf8\\xcc\\x59\\x52\\xeb\\xd0\\x5b\\x57\\xf3\\x38\\x70\\xf5\\x6d\\x99\\x77\\x11\\xcd\\x49\\x11\\xcd\\x2e\\x2e\\xfb\\x41\\x27\\x4b\\xe7\\xec\\x7d\\xef\\x52\\x59\\x49\\x9b\\xf0\\x72\\xc7\\x72\\xc1\\xf3\\x32\\x17\\x5d\\xae\\xa9\\x6f\\xb8\\x5b\\x8b\\xb5\\x7b\\x75\\xb2\\x46\\x69\\x02\\xce\\x7b\\x32\\x91\\x24\\xd3\\x15\\xac\\xa8\\xd7\\xd8\\x81\\x3d\\x1f\\x0d\\xb6\\xe1\\xa2\\x05\\x65\\x30\\x89\\x2e\\x38\\x88\\x5d\\xd9\\xc8\\xcf\\x5b\\x25\\x4a\\x37\\x1b\\xa2\\xf5\\x50\\xbd\\xb0\\x7a\\x30\\x02\\x28\\xe0\\xca\\xaa\\xe7\\x05\\xf0\\xee\\xae\\x81\\x7c\\x79\\xd8\\x33\\x54\\x9d\\x81\\xb0\\xdb\\x6e\\xad\\x38\\x6c\\xf1\\x23\\x6e\\xa7\\xa7\\x8b\\x31\\xed\\xf4\\xfd\\x55\\x87\\x2e\\xea\\x0d\\x6c\\xd2\\x25\\xf0\\xbb\\xb1\\x5d\\x8c\\x48\\xcf\\xbb\\x29\\xa2\\x90\\x44\\x3d\\xe6\\x46\\xc9\\x31\\xb3\\xc3\\x5a\\x0a\\x6e\\x47\\x82\\x18\\xa6\\x78\\x5c\\x67\\xaf\\x9c\\xcb\\xa1\\x50\\x30\\x7b\\x64\\x4e\\xa2\\xa5\\x82\\x9a\\xce\\xde\\x43\\x8b\\xbb\\xdc\\x5f\\x31\\x0f\\xa0\\xe9\\xe2\\xcc\\xa5\\x7d\\x77\\x43\\x5e\\xf7\\x9a\\xc1\\x9d\\x7d\\x15\\x09\\x49\\x3d\\x67\\xcf\\xf7\\xba\\xb0\\x4c\\x8e\\x0b\\x2f\\x36\\xb2\\x4e\\xa5\\x4a\\x3b\\xd4\\x70\\xc9\\xc1\\xdc\\xbc\\x03\\xc1\\x83\\x1a\\x9f\\xfc\\x53\\x2e\\x62\\x83\\x79\\xbe\\x17\\x7d\\x1b\\x12\\x4b\\x83\\xe9\\x1c\\x2c\\xe0\\xd2\\x69\\xec\\x81\\xc0\\xf3\\xb3\\x76\\x18\\x8f\\xc8\\x10\\xeb\\xca\\x0a\\x1a\\xb6\\xd7\\xd9\\xab\\xe9\\xb4\\xb1\\xb8\\x53\\x9b\\x92\\x20\\x8e\\x8e\\x44\\xf3\\x7e\\x73\\x2e\\x4f\\xc1\\x5d\\x1e\\x44\\x77\\x50\\xa4\\x12\\x6e\\x3d\\x83\\x1e\\xd2\\x47\\x09\\xe0\\x2e\\xcd\\xec\\x5c\\x76\\xfd\\xde\\x13\\xb7\\x4e\\x3e\\x4c\\x6e\\x5c\\x13\\x1a\\xc4\\x14\\x24\\x5b\\x69\\x32\\x5f\\x09\\x00\\xcb\\x6f\\xa2\\xbd\\x87\\xcb\\x99\\xa2\\x7a\\x68\\x01\\x6c\\x9c\\x3b\\x47\\x5e\\xcd\\x71\\xdb\\x0e\\x53\\xbc\\x6c\\x09\\x62\\xf2\\xbb\\x29\\x39\\xf3\\x64\\x13\\x73\\x73\\x94\\x1a\\x75\\xbf\\x52\\xe3\\xbb\\xfd\\x79\\x49\\x49\\xef\\x86\\x8e\\xea\\x88\\xba\\xf2\\xca\\xab\\x9f\\xcc\\x82\\x57\\x4b\\x12\\xc0\\x54\\x21\\xee\\xf5\\x1e\\xf9\\x9e\\x6c\\x07\\x7b\\x1a\\x08\\xb7\\x68\\x3b\\x28\\x74\\xa4\\xbb\\x0d\\x6c\\xe8\\x60\\x7c\\xfd\\x13\\x1f\\xd3\\x09\\xda\\xa0\\x0b\\x10\\xf3\\x06\\x7a\\xca\\x0c\\x5f\\x67\\xb4\\x29\\x88\\xc1\\x55\\xaa\\xbe\\xdf\\x00\\x72\\xed\\x26\\x0d\\xce\\x8a\\xa0\\x3b\\x1f\\xb4\\xe1\\x3c\\x8b\\xe7\\x3d\\x9e\\xcb\\x8e\\x78\\x5c\\x0a\\x89\\xfc\\xcc\\x41\\x52\\x9e\\xcd\\x41\\x81\\xaa\\x13\\xf9\\x8c\\x29\\x1e\\xb4\\x47\\xd8\\x8a\\xda\\xe8\\xe1\\xbd\\xf5\\x25\\xb6\\x6b\\x5d\\x2c\\xe1\\x46\\xd0\\xc1\\x99\\x4f\\x2f\\x2f\\x36\\x10\\xc2\\xef\\xc4\\xe5\\x66\\x54\\xab\\xf1\\x34\\x2a\\xca\\xa8\\x5a\\xb9\\x8d\\x52\\x67\\xcc\\x6e\\x10\\xd1\\x41\\x40\\x03\\x9d\\xf7\\xaa\\xeb\\x78\\x6d\\x6d\\xe8\\x6d\\x48\\xa7\\x26\\x55\\xa7\\x22\\x21\\x83\\x98\\x0c\\x6c\\x32\\xc0\\xdd\\x9d\\x82\\x1f\\x5a\\xe1\\xcc\\x2d\\xec\\x8f\\xb0\\x3f\\xd2\\x5e\\x36\\x2c\\xc1\\x98\\xa9\\xd3\\x93\\x32\\xd8\\x27\\x18\\x81\\x40\\xff\\x9a\\x2b\\x0a\\x6a\\xc2\\x1e\\x20\\xe8\\xed\\x54\\x74\\x4d\\xbb\\x41\\x5f\\xb2\\x31\\xb9\\x9e\\x73\\x22\\xa0\\xf4\\xab\\x9f\\x99\\x93\\xeb\\x2e\\xa9\\x75\\xaa\\xa2\\xe7\\x3a\\x13\\xed\\xa0\\xb8\\xcf\\x09\\x13\\xb6\\xcf\\x3a\\x55\\xc9\\x07\\x07\\xf2\\x87\\xa7\\xac\\x2c\\x7a\\x17\\x5b\\x1a\\x9d\\x89\\x75\\x7a\\x7d\\x5e\\x35\\xb0\\x4a\\x3d\\xa1\\x89\\xdc\\xe6\\x06\\x14\\x1e\\xe5\\xec\\x1c\\x22\\x54\\xa1\\x4d\\x04\\x31\\x22\\x1f\\x69\\x3b\\x1c\\xf1\\x3c\\xb4\\x2d\\x3e\\xc6\\xed\\xf0\\xfa\\x1c\\xf1\\xfc\\x80\\x35\\x24\\x47\\x1d\\x6d\\xda\\xb2\\x64\\x4a\\x49\\x91\\xc1\\xe5\\x47\\x65\\x0f\\x4e\\x24\\x3d\\xec\\x48\\x4e\\xd5\\x25\\x9d\\xc1\\x11\\x8f\\xa7\\x90\\xa0\\x54\\x4e\\xaa\\x6f\\x77\\xa9\\x7e\\xb9\\x8a\\x52\\x4f\\x4a\\xcc\\x9b\\xf1\\x3d\\x4d\\xfa\\x51\\xb9\\xf7\\xad\\x5e\\x87\\xc4\\xb5\\xd6\\xac\\xf9\\xc6\\xb5\\x32\\x91\\x1b\\x5d\\x0e\\x60\\xf9\\x19\\xad\\x23\\xb9\\x92\\x23\\x87\\x2b\\x8a\\x61\\xd9\\x7c\\xa9\\x03\\x8c\\xb1\\xb5\\xe5\\x7b\\xcf\\xf9\\x60\\x6f\\x9e\\x10\\xf9\\x6e\\xf3\\x4a\\xa4\\xac\\x99\\x36\\x80\\xb1\\xe7\\xf2\\x18\\xb7\\xf8\\x1a\\xb7\\x4f\\xe8\\x6a\\xa2\\xe2\\x5e\\x4e\\x8a\\xfd\\xd8\\x4e\\xca\\x50\\xbd\\x58\\xcc\\x0e\\x87\\x10\\x63\\x52\\xf5\\xe2\\x29\\xca\\xf6\\x7a\\xf6\\xc6\\xc5\\x1b\\x37\\x21\\x1c\\xda\\xb4\\x93\\xc7\\xb0\\x93\\x8f\\xb0\\x15\\x19\\x4c\\xbc\\x08\\xf8\\x11\\x49\\x8f\\x20\\x24\\xc9\\x09\\x64\\xe0\\x47\\x74\\xb5\\x6e\\xce\\x65\\x1f\\x86\\x3a\\x6c\\xe5\\x7b\\x8f\\x68\\x55\\xf8\\xa0\\x1e\\x6e\\x7c\\xaa\\xc2\\x3e\\xfb\\x71\\xd8\\x2a\\x1c\\xd8\\xd6\\x41\\x1b\\xb5\\xd1\\x3e\\x26\\x2d\\x05\\xa4\\x89\\x3a\\xf9\\xf0\\x9a\\xa1\\xab\\xa4\\xae\\xc4\\xa6\\xee\\x69\\xb2\\x20\\x8c\\x81\\x73\\x9f\\x71\\xe8\\x06\\x78\\x1e\\x2c\\xfc\\x03\\x03\\xe8\\x5d\\x67\\x0f\\x78\\xf1\\xb3\\x31\\xa6\\xe8\\x8b\\xf5\\x08\\x57\\x9f\\xe7\\xc0\\x45\\x31\\x31\\xf5\\x4c\\x51\\x8e\\x0f\\x5d\\x07\\x82\\xb5\\x7b\\x78\\xe8\\x2f\\xca\\x77\\x0c\\x30\\xee\\x18\\x62\\xdc\\x31\\x40\\x7b\\xfd\\x46\\x90\\x27\\x72\\xf6\\x27\\x7d\\x53\\x5f\\xfa\\x2f\\x12\\xf6\\x19\\x5e\\x8d\\x8d\\xef\\xe2\\xc9\\x25\\xe4\\x3a\\xb9\\x8a\\x6c\\x1a\\x44\\x18\\x76\\xee\\x54\\x20\\xec\\xa9\\x1f\\x9d\\x81\\xb8\\x47\\xdd\\xcd\\xec\\x6e\\xcf\\xd3\\x70\\xd0\\x0c\\x15\\xcf\\xaa\\xb8\\x68\\x77\\xf7\\x96\\xd4\\xe4\\xd1\\x49\\x07\\xa2\\xe1\\x0c\\x48\\x32\\x40\\xfe\\x31\\x3b\\x09\\x6f\\x49\\x17\\x22\\xc5\\xdb\\xc6\\x1a\\x70\\x73\\x2d\\x8f\\x6b\\x3f\\xaa\\x1c\\xb6\\x75\\x27\\xf7\\x9c\\x55\\x5a\\x1c\\x69\\x80\\xf1\\x49\\x34\\x27\\x2b\\x2c\\xba\\x56\\x58\\xfe\\xca\\xa9\\xd7\\xb7\\xcf\\x23\\x7b\\xfb\\x3b\\x6a\\xad\\xc6\\x9f\\xe4\\x37\\xd9\\xda\\xfd\\x56\\x88\\x32\\x65\\x76\\xfb\\x2d\\xed\\x64\\xce\\x7c\\xc8\\x76\\x70\\x6d\\x29\\x88\\xa5\\xd2\\x59\\xf4\\xc6\\x15\\x1e\\x8b\\x86\\x0b\\x11\\xcd\\x89\\xe0\\x3c\\xd8\\x81\\x9b\\x0c\\x0c\\x1d\\x41\\x0c\\x05\\xa8\\xdf\\x31\\xa0\\xab\\x5c\\x15\\x60\\x4f\\xf2\\xb3\\x3f\\xb0\\xcb\\x4e\\x3f\\x67\\xe9\\x5e\\xf3\\x60\\xbd\\x3f\\x75\\x0b\\x45\\xe9\\xb5\\x98\\x88\\x74\\x1f\\x35\\xb9\\x4e\\xc9\\x9c\\x26\\xa8\\xbe\\x6b\\x84\\x2a\\x57\\x1e\\x09\\x4b\\x18\\x11\\x52\\xf5\\xb9\\xc8\\xf6\\xb1\\xc8\\x3e\\x29\\x51\\x9a\\x93\\x49\\x08\\x1b\\xbe\\x8f\\x0c\\xde\\x89\\xc8\\x22\\x5c\\x57\\x10\\xa5\\x71\\xd4\\x9a\\x34\\x79\\xc2\\x00\\xa3\\x7e\\xbc\\xd2\\xde\\x2e\\x39\\x0f\\x5c\\xb7\\xdd\\x46\\xb7\\xb0\\x19\\x6e\\xcd\\x19\\x6e\\xa9\\xa0\\xa5\\x0d\\x07\\x00\\x84\\x66\\x48\\x5a\\xee\\x80\\x0a\\xb4\\xbe\\x15\\xbb\\xa2\\xd4\\x7d\\x79\\x17\\x19\\x87\\xae\\xc0\\xf3\\xa3\\x26\\x5c\\x1c\\x9a\\x56\\x9a\\x82\\x67\\x28\\xa3\\x02\\x38\\xe1\\x65\\x03\\xc1\\x4a\\x1e\\x38\\x50\\x74\\x38\\x50\\x34\\xd7\\xf2\\x79\\xd5\\xc3\\x1c\\x41\\xfc\\x93\\x06\\x4d\\x8d\\x06\\x0b\\x94\\x66\\x9e\\x3a\\x5f\\x42\\xaf\\x08\\xd1\\xab\\xd9\\xb8\\xa1\\xaf\\xd9\\x71\\x5d\\xed\\xc7\\xa0\\xdb\\x2e\\x2e\\x3b\\x0f\\x5c\\x75\\xde\\xda\\xe6\\xc6\\xe0\\x9f\\x29\\xff\\x50\\x67\\xa1\\x9c\\x85\\x03\\x80\\x83\\x64\\xc7\\x08\\x4f\\x4e\\x10\\xd0\\x81\\x32\\xa6\\xd2\\xcd\\x57\\x3f\\x56\\xa0\\x28\\x9a\\x2e\\x36\\x6b\\x1c\\xec\\x67\\xbf\\xae\\xc8\\x39\\x0a\\x0a\\xd7\\xcc\\x85\\x17\\x45\\xcc\\x98\\xc9\\x7b\\xb9\\x7d\\xd1\\xe1\\xad\\xd5\\x45\\x48\\xd1\\x45\\xd7\\x34\\xba\\xbb\\x71\\xc1\\x9f\\x17\\x58\\xcb\\x02\\x07\\xa1\\x8b\\x04\\x41\\x67\\x5c\\x18\\x80\\xb0\\xbd\\xf2\\x15\\x9b\\x5e\\x8f\\x5b\\xb4\\x69\\xb1\\xdf\\x0e\\x71\\xdc\\x0e\\x84\\xdf\\x0c\\xaf\\xbf\\xc1\\x7b\\x4d\\x44\\xc8\\x3e\\x4f\\x8a\\x7e\\x8e\\x84\\x7e\\xce\\x24\\x42\\x87\\xe8\\x4e\\x19\\x37\\x8b\\xdc\\xda\\xe0\\x1c\\x1a\\xdf\\x53\\xe0\\x86\\x2c\\x79\\xc0\\xbc\\x3f\\xdf\\x7d\\xcb\\x6c\\x2c\\x8d\\x8c\\xba\\x20\\x58\\x68\\x56\\xa4\\x31\\x47\\xd8\\xf3\\x57\\x0c\\x59\\x8f\\xe8\\xd5\\x9d\\x8c\\xf1\\x63\\x90\\xa8\\x95\\x40\\x1b\\x75\\xc8\\xa7\\x85\\xcc\\xb7\\x81\\xcc\\xd1\\x81\\xc8\\xd1\\x81\\x2c\\x82\\x70\\x12\\x4d\\x44\\xe7\\x5a\\x77\\xec\\x6a\\x0c\\xb8\\x9d\\xb7\\x45\\x3a\\xa1\\xe5\\x76\\x42\\x8b\\xe1\\x40\\x8d\\xdc\\x65\\xe8\\x81\\xef\\xfe\\xb4\\x90\\x3b\\x15\\x5e\\xd9\\x1a\\xdb\\x44\\x79\\xd6\\xaa\\x95\\x2e\\x52\\xba\\x33\\x40\\x63\\xb8\\x4b\\x3b\\x04\\x94\\x3c\\xc6\\x00\\xf9\\x67\\x4c\\x7a\\x42\\xd4\\xb2\\x0f\\x18\\xdb\\x40\\x71\\x7f\\xd5\\x17\\xea\\xe5\\x4b\\x78\\x01\\x0e\\x54\\xf3\\xb0\\x1f\\xc3\\xed\\x2e\\x51\\xe8\\xab\\x6e\\xbf\\x62\\x5f\\xb4\\x5c\\x4f\\xb4\\xb4\\xe5\\x2e\\x9d\\x2e\\x11\\x38\\x5b\\xe7\\x26\\x0b\\x1d\\x4c\\x4b\\xb6\\x6d\\x0f\\x5c\\x77\\x4a\\x48\\x64\\xd1\\x0c\\xcd\\x3a\\x0f\\x2c\\x4c\\x88\\x65\\xc5\\xa1\\x37\\xdd\\x89\\x4e\\xc9\\xdb\\x5d\\x3a\\x6e\\x77\\xf9\\xa0\\xdb\\x3d\\xf3\\x85\\x3a\\x74\\xc6\\x4c\\x75\\xa0\\x4d\\x3d\\x6f\\xa7\\x74\\xde\\xf6\\x9b\\xfd\\x18\\x6f\\xb7\\x6a\\x2a\\x40\\xe8\\xaa\\xca\\x97\\xc7\\x79\\x3b\\x6f\\xc8\\x8a\\xc2\\xe3\\x2b\\xf7\\xa6\\x9d\\x9a\\x86\\xd5\\x23\\xfa\\x88\\xb0\\x58\\x2c\\x49\\xad\\x84\\xf5\\xb5\\x6a\\xe2\\x57\\xfd\\xd7\\x7a\\x13\\x60\\x36\\x92\\x14\\x62\\xe6\\xa3\\x76\\xf1\\x66\\x23\\xd7\\x61\\xcc\\x33\\xb1\\xf8\\x84\\x2e\\x93\\x31\\xbc\\x32\\x9f\\x17\\x4f\\x31\\x14\\x18\\x80\\x5c\\x04\\x21\\x29\\xc9\\x6e\\x77\\xe4\\xfc\\x49\\x85\\xf7\\x29\\x3f\\x01\\xef\\xc8\\x02\\x0b\\xc9\\x3a\\x0b\\xd9\\xb6\\xb4\\x23\\x36\\xaa\\xb1\\x23\\x35\\x21\\xe3\\x48\\x80\\x8f\\x7e\\x51\\x3d\\xff\\x0e\\x65\\x8c\\xf8\\xbc\\x80\\xee\\xf2\\xde\\xa0\\x30\\x17\\x55\\xb5\\x21\\x5a\\xee\\x9f\\xf5\\x81\\x05\\xdc\\x5b\\x8d\\x43\\xd6\\x67\\x27\\x52\\x56\\x96\\xdd\\x67\\x77\\x53\\xf7\\x9a\\x78\\xfa\\x90\\x72\\x61\\x50\\x5c\\x7f\\x07\\x29\\x33\\xc5\\x6f\\x86\\x4c\\xba\\x30\\x9c\\x74\\x17\\x9f\\x05\\x55\\x77\\xdf\\x06\\x28\\x8e\\xe0\\x64\\x8c\\xe1\\x38\\x42\\x43\\x76\\xa7\\x74\\x3e\\xe7\\x76\\xde\\x6c\\xd2\\x09\\x48\\x4d\\x86\\x7b\\xd5\\xd0\\x3a\\x7c\\xc8\\x34\\x23\\x3e\\xc5\\xcf\\xd9\\x96\\xef\\xeb\\x7b\\x9e\\x3c\\x29\\x83\\x27\\xcc\\x1b\\x73\\xb3\\xdd\\x4e\\x8e\\x1b\\x57\\xd9\\x7a\\x06\\x60\\xc0\\x4f\\xba\\x03\\xe7\\x76\\x32\\x7d\\xb9\\x30\\x92\\x9a\\xf7\\x82\\x62\\xc7\\xa6\\x5a\\x7a\\xdf\\x77\\x03\\x66\\x33\\xec\\x37\\x90\\xb1\\x18\\x97\\xeb\\xd2\\x9e\\x61\\xc0\\xcf\\xb9\\x49\\xb2\\x21\\x9c\\x73\\x90\\xfb\\xf3\\x66\\x7a\\x82\\x6c\\x4b\\x0f\\x88\\x01\\xa5\\xe1\\x73\\xfe\\x81\\x2a\\xc9\\xc9\\x8d\\x30\\x63\\xae\\xb8\\x69\\x4a\\x65\\xfd\\x59\\x67\\x55\\xfb\\x62\\xe9\\x52\\xc7\\x70\\xaa\\x4d\\x80\\xee\\x7e\\x73\\x44\\x88\\x29\\x98\\xef\\x7b\\xa2\\x4b\\xad\\x6a\\x51\\x03\\xe9\\x15\\x4c\\x33\\x1c\\x17\\x57\\x92\\x85\\xb5\\x25\\x8f\\x5d\\xc1\\x6f\\x73\\x00\\xef\\xbe\\x7a\\x1b\\xc8\\x34\\x99\\xfe\\x2e\\x9c\\xf1\\x53\\xa5\\xee\\xe8\\x37\\x5d\\xf1\\x23\\xa7\\xbc\\x54\\x58\\x1b\\x64\\xc9\\x44\\x9f\\xfb\\xaa\\x8b\\x92\\x21\\xee\\x53\\x62\\x5d\\x9e\\xf1\\x71\\x3d\\x92\\x4b\\x1e\\xb0\\xee\\xd8\\x87\\x0a\\x2a\\x58\\x1e\\x74\\x59\\x2e\\x19\\xd3\\xb1\\x0f\\x54\\x9e\\x79\\xf0\\xb8\\xa5\\xec\\xdb\\x2b\\x45\\xd4\\x05\\x56\\xe3\\x2f\\x4f\\x4e\\x92\\xfb\\x28\\xb9\\x00\\x2c\\xf8\\xb9\\x3f\\x13\\x98\\x20\\x3c\\x94\\x0b\\x53\\x33\\xe9\\x85\\x4c\\xdb\\xa7\\x01\\x4a\\xdf\\x73\\x30\\x46\\xe8\\x43\\xdf\\x32\\x2c\\xa7\\x38\\x63\\xe1\\x10\\x60\\xf0\\x92\\x11\\xfd\\x94\\x51\\x29\\x4f\\xeb\\x91\\xd8\\x2c\\xc3\\xd6\\x68\\x94\\xdf\\xac\\xa1\\x67\\x0e\\x89\\xfd\\xd4\\x1d\\x31\\xab\\xfc\\x13\\x75\\x09\\x31\\x80\\x18\\x89\\x21\\xee\\x8f\\x14\\x5c\\x18\\xbe\\xfd\\xcc\\x11\\x17\\x36\\x8c\\x2e\\xee\\xc5\\x61\\x98\\x0a\\x72\\x01\\x15\\xf5\\x4b\\xf6\\xbb\\xac\\x2c\\x7f\\xd5\\x13\\x8a\\xd9\\xd5\\x7e\\xa8\\x02\\xcd\\x61\\x56\\x8b\\x31\\xca\\x77\\xd5\\x31\\xc6\\x03\\x63\\x6e\\xc2\\x6a\\x97\\xd1\\x6a\\xf7\\x4c\\xfa\\x29\\x27\\x53\\xaa\\x30\\x56\\x38\\x2c\\xc3\\xd7\\x90\\x94\\x9d\\xee\\x53\\x7d\\x98\\xfc\\x87\\x7e\\x2e\\x5c\\x68\\x8d\\x7a\\xc5\\x99\\x1c\\xa6\\x98\\xd7\\xaa\\xfa\\xe6\\x97\\x12\\xf3\\xbc\\x47\\x7d\\xcf\\xf5\\xac\\xa4\\x1d\\xc1\\x91\\xba\\x2f\\xd5\\xbe\\xf3\\xc7\\x48\\xd6\\xa0\\x19\\x07\\xc3\\x5f\\x98\\x32\\xbe\\xbb\\xa8\\xec\\x72\\x3e\\x79\\x7a\\xf1\\x47\\xff\\xce\\xc8\\x62\\x33\\x30\\x25\\xbb\\xe7\\x2a\\x9a\\x36\\x0c\\x83\\x7f\\xe7\\x9d\\x69\\x6d\\x4b\\xd6\\x18\\x8e\\xd1\\xef\\x54\\xc6\\x5f\\x9e\\xcc\\x8f\\x72\\xb5\\x8f\\xb0\\xae\\x19\\xa6\\xbe\\xf0\\x00\\xc4\\xe4\\xd1\\xb7\\xbe\\x81\\x31\\xf1\\x61\\xdf\\xa1\\xd2\\x64\\xb0\\xa1\\x8e\\xda\\xf8\\x22\\x97\\xcc\\xf9\\x69\\x0b\\x4e\\x34\\x6e\\xfa\\xb5\\xe4\\x18\\x59\\x58\\xed\\xd5\\xb9\\x97\\xec\\x0f\\xef\\xe4\\x35\\x97\\x2b\\x4a\\x94\\x58\\x46\\xd4\\x0e\\x8f\\x11\\xd6\\x6f\\x7e\\xcf\\x9a\\x38\\xe8\\x11\\x89\\x13\\x26\\x85\\xc9\\x94\\xf7\\xbe\\x93\\xed\\xe8\\x37\\x36\\x7a\\xb5\\x7a\\xf7\\x67\\xde\\xcd\\x94\\x6c\\x72\\x8c\\x73\\xd9\\x6f\\x10\\x13\\x31\\xec\\xe7\\xec\\xa3\\x59\\x91\\x2a\\xc4\\xaf\\xb4\\xd3\\x43\\xb4\\xe1\\x18\\x8a\\xe4\\x3c\\x18\\xf1\\x33\\xee\\x60\\x06\\x32\\x78\\xfa\\x76\\x61\\x74\\x35\\x6b\\x1f\\x51\\xcf\\xac\\xec\\xf6\\x83\\x6f\\xa1\\x16\\x8f\\xe9\\xa5\\x30\\x3b\\x17\\x59\\xfd\\xee\\x57\\x31\\xd1\\x2d\\x78\\xda\\x32\\x2c\\xab\\xa9\\xbf\\xf1\\x39\\xc9\\x45\\xec\\x41\\x23\\x73\\x63\\xeb\\x19\\x93\\xb7\\xb3\\x20\\x83\\x7e\\xed\\x73\\x97\\xfb\\x44\\xae\\xf8\\xbe\\x7a\\x27\\xc4\\x84\\x6c\\x5f\\xf5\\xf1\\x95\\x14\\x43\\xb2\\x30\\xf9\\x1f\\x72\\x0d\\x6f\\xb7\\x35\\x9d\\xf6\\xcc\\x83\\x61\\x39\\x4b\\x76\\x1f\\x8b\\xaa\\xa0\\xbf\\x8d\\xeb\\x31\\x69\\xdb\\x07\\xc7\\xf0\\x17\\x58\\xe3\\x13\\x8b\\xbd\\x71\\xdb\\xf7\\x78\\xb9\\x4e\\x5b\\x02\\xdf\\x33\\xd1\\x76\\x8d\\x92\\x31\\x5d\\x68\\x99\\x08\\xc0\\x79\\xc8\\xe2\\x0b\\x47\\xf6\\x89\\x63\\x7d\\x10\\xb9\\xfe\\x70\\x1d\\x86\\xb9\\xab\\x18\\x78\\x4d\\xa7\\x71\\x6c\\x79\\x8c\\x07\\xbf\\xc7\\xab\\xec\\x16\\x20\\xc5\\x54\\xc4\\xcc\\x5c\\xb4\\x43\\x7e\\x10\\x79\\x3b\\x10\\xc5\\xc0\\x00\\x4c\\xf7\\xa9\\x23\\x96\\x83\\x23\\x80\\xce\\x27\\x3a\\x53\\xc5\\x27\\x27\\x9d\\xba\\xf0\\xdc\\x44\\xa3\\xbf\\xbd\\xd1\\xb2\\x3e\\x69\\xd5\\xe3\\x30\\xc5\\x35\\x9d\\xc5\\xe3\\xcd\\x60\\x6e\\x16\\x4a\\x2d\\xce\\x70\\xce\\xd8\\xfa\\x56\\xe7\\xbe\\xe7\\x94\\xd7\\xb4\\x03\\x91\\xcb\\x01\\xb7\\x27\\xc6\\x70\\x4c\\x6d\\xcb\\x3c\\x0a\\x62\\x8f\\xcd\\xaf\\xcd\\x26\\x66\\x8a\\x3a\\xad\\x1b\\xaa\\x61\\xbe\\xcd\\x76\\x6a\\x8c\\xd0\\x6b\\x96\\xe7\\xb2\\x78\\x16\\xcc\\xe5\\xd2\\x6c\\x77\\x0c\\x90\\xd2\\xbc\\xe0\\x98\\x5d\\x0a\\x05\\x9f\\xe1\\xf1\\xcb\\xb7\\x98\\xe3\\xb8\\xab\\x78\\xdf\\x9f\\x74\\x6a\\x30\\x99\\x1d\\xc9\\x3d\\x1b\\x72\\xcc\\x65\\xc7\\xf2\\x62\\xc9\\xb3\\x0c\\xb7\\xbd\\x66\\x61\\x94\\xa7\\x50\\x7c\\xb7\\x63\\x2a\\x0e\\x99\\x4a\\x42\\xd4\\xb8\\x68\\x67\\x8a\\x40\\xcc\\x83\\x65\\x7c\\x12\\x19\\xd3\\xc5\\xd0\\x34\\xa2\\x71\\x95\\xa6\\x67\\x4f\\xf6\\x7b\\xdd\\x00\\x24\\xe4\\x76\\xbf\\x93\\x27\\x69\\x18\\xfc\\x93\\xd2\\x21\\xe6\\xc1\\x98\\xc7\\x6d\\x53\\xb7\\x02\\xcc\\xf3\\x43\\xba\\x4b\\xc8\\x43\\xb8\\x5d\\x8a\\xcf\\x9d\\xb4\\xa4\\x65\\x54\\x9f\\x07\\x8d\\x07\\xe3\\xb0\\xce\\x1e\\x10\\xf3\\xe0\\xcd\\x5a\\x5a\\x35\\xb4\\x20\\x19\\x30\\x6e\\x07\\x25\\x31\\xb9\\x96\\xd9\\x3e\\x77\\x18\\x37\\x7e\\x23\\xc8\\x49\\xa0\\x81\\x27\\xfd\\xc4\\xf8\\x9a\\xc1\\xd8\\x5b\\x2e\\x4e\\xf8\\x42\\xe0\\x50\\xb3\\xa7\\x3e\\xc4\\x0c\\x25\\xfc\\xe9\\x63\\x22\\x7f\\xe4\\xfc\\xb1\\x6d\\xa0\\xd8\\xb6\\x8e\\xd6\\xc5\\xa6\\xcf\\x84\\x8a\\x67\\x8f\\x4e\\x3c\\x6f\\x80\\x48\\x10\\x74\\x62\\x71\\x2d\\xe7\\xa3\\x90\\xf3\\x7d\\x47\\x7e\\xd5\\x51\\x04\\xa7\\x71\\x72\\xeb\\xf4\\xb3\\xc6\\x63\\xc6\\xe6\\x7b\\x2f\\xb2\\x83\\x24\\x41\\x27\\xa7\\x87\\xaf\\xe6\\xb1\\x32\\x31\\xe4\\x02\\xfc\\xb7\\xb0\\x6a\\xb5\\x7b\\x88\\x82\\x18\\x76\\xbe\\xf5\\x83\\x10\\xf3\\xe0\\xa4\\xe3\\xd6\\xe9\\x45\\xc7\\x93\\xa0\\x75\\xb1\\x2e\\x89\\xc9\\xad\\x5c\\xf2\\x89\\xbf\\xd7\\x54\\x0f\\x2d\\x50\\xe8\\x46\\x81\\x11\\x19\\x44\\x31\\x63\\x73\\x0f\\x99\\x0b\\x1f\\x86\\xa1\\x4a\\x26\\x7a\\xdd\\xe7\\xd7\\x7d\\x71\\xfa\\xce\\x8f\\x26\\x86\\xb0\\xe1\\xd8\\x07\\x01\\x10\\x01\\xf7\\xe2\\x87\\xb9\\x58\\xae\\x27\\x18\\xc5\\x69\\xd2\\x9b\\x0d\\x69\\x42\\xcf\\x06\\xdc\\xf7\\x1d\\xcf\\x43\\xa9\\xc7\\xa9\\xeb\\xce\\x29\\x42\\x6c\\x59\\xbb\\x28\\x0c\\x27\\xa8\\x13\\x9d\\x6d\\x05\\xc0\\x01\\xa0\\xfa\\xa4\\xfc\\x52\\x48\\xf9\\xef\\xbb\\x9b\\xe7\\xdb\\x9e\\xdf\\xc0\\x78\\x16\\x32\\x96\\x71\\x36\\xf8\\xcc\\x8d\\xef\\x37\\x5b\\xaa\\xa5\\x59\\x2e\\x39\\x86\\x32\\x60\\xa0\\x81\\xf4\\x01\\xd6\\x07\\x4f\\x19\\xe0\\x7c\\x7c\\xce\\x3c\\xb7\\xc1\\xc0\\x06\\xe7\\x0d\\xf4\\x9a\\x8f\\x97\\xec\\x3e\\x66\\xd0\\x93\\x10\\x43\\x7a\\xa8\\x3a\\x32\\x49\\xc8\\xec\\x36\\x5f\\x19\\xb3\\x6e\\xdc\\xde\\xbb\\x5a\\x8f\\xe8\\x1a\\x34\\xf8\\x61\\xcd\\xeb\\x84\\xd6\\x9a\\x35\\x6a\\xf6\\xe8\\x99\\xa3\\xe7\\x55\\x61\\xcb\\x59\\xb2\\xf8\\x68\\x8e\\x15\\x7e\\xae\\x0b\\xbd\\x55\\x29\\x5f\\xa6\\xf7\\xb5\\x1b\\xe2\\x68\\xd3\\xc8\\x2e\\x26\\x4d\\x62\\xb0\\xfc\\x11\\x46\\x10\\x3a\\x26\\x8f\\xc7\\xa0\\xfa\\xbc\\xc1\\x04\\x24\\xb1\\x7f\\xc6\\x24\\xa3\\x66\\xd3\\x02\\x93\\xf7\\x81\\xc2\\xae\\xa9\\x19\\x8c\\x5a\\x2e\\xbe\\x46\\x43\\x79\\x76\\xc4\\x57\\x0f\\xdf\\xe6\\x46\\xed\\x70\\x91\\x93\\x28\\xcf\\x41\\xa9\\x07\\x65\\xa0\\x0d\\x0d\\x5b\\xdc\\x87\\x9d\\xa8\\x51\\xa2\\xc5\\x32\\x17\\x6f\\x82\\xde\\x62\\x91\\xb8\\xcf\\xc9\\xeb\\x73\\xdd\\xfb\\xbc\\x1b\\x8e\\x34\\xac\\x61\\xf6\\x22\\x0a\\xfb\\x1c\\x3e\\x64\\xce\\x8f\\x4f\\xc4\\x3f\\xf4\\xfa\\x0c\\x84\\xb6\\x95\\xb5\\xd7\\x6c\\x79\\xbc\\x9a\\xc3\\xb3\\xc3\\x96\\x68\\x8c\\xda\\xa8\\x4d\\xdb\\x49\\x8e\\x27\\x36\\x9e\\xf0\\x42\\xe1\\xc4\\x1d\\xca\\xae\\x3b\\x16\\x71\\xb9\\x9a\\x06\\x0a\\xec\\xa3\\xe8\\xa4\\x36\\x6b\\xa0\\x36\\x93\\xe2\\x97\\xdc\\xfc\\xfd\\xfb\\xb2\\x97\\x0e\\xc1\\x8d\\xb8\\x22\\xa0\\x0f\\x6b\\xe6\\x15\\x09\\x3c\\xc1\\x7a\\x44\\x8f\\xa8\\x8d\\xdf\\x1b\\xf6\\xd7\\x67\\x4c\\x2e\\xfb\\xcd\\xb9\\xa9\\x55\\x4c\\xc9\\xaf\\x7e\\xf9\\x35\\x73\\x80\\x28\\xcd\\x80\\x28\\x0d\\x66\\x10\\x6d\\xc4\\xfa\\x3d\\x3c\\x9e\\xcf\\x83\\x0b\\x71\\xdd\\x7e\\x4c\\xb7\\xf3\\xd6\\xc8\\xb6\\xbb\\x68\\xb6\\x3b\\x28\\xf6\\x83\\x32\\xb4\\xb3\\x90\\xa0\\xd1\\xd6\\xf8\\x10\\x30\\x16\\x06\\x84\\xb4\\xa2\\x40\\xe9\\x22\\x80\\x69\\xd4\\x21\\x50\\x93\\x28\\x89\\xb6\\x51\\x86\\x60\\xc4\\x87\\x65\\x0d\\x54\\x8d\\x10\\xe2\\x59\\x5d\\x35\\x19\\xfd\\x61\\xbf\\xc9\\xd8\\x91\\x0a\\x51\\xe3\\xba\\xc1\\x59\\x5e\\x70\\x18\\xa9\\xd6\\x21\\xa2\\x9d\\xe9\\xa6\\x1d\\xe9\\xa4\\x1c\\xf3\\xa4\\x38\\x52\\x6d\\x34\\xc7\\xc5\\xdc\\x48\\x65\\x18\\xe3\\x76\\x9d\\x56\\x62\\x25\\x57\\xf2\\x35\\x5c\\xe4\\x68\\x43\\xfa\\x57\\x74\\x57\\x7b\\x5a\\x78\\x44\\x7e\\xd4\\x46\\x48\\xd6\\x44\\x88\\xd7\\x44\\x6d\\xd2\\xd3\\xc1\\x24\\x90\\x47\\xca\\x97\\x98\\x9e\\x75\\x1e\\x9c\\xa1\\x19\\xba\\x90\\x39\\x84\\xb4\\x27\\x84\\x01\\xd3\\x09\\x54\\xeb\\x16\\xa0\\x28\\x43\\x13\\x4f\\x14\\xd3\\xf5\\xcf\\xde\\x8f\\x91\\x2f\\x9d\\x4d\\x1d\\x00\\x05\\x6b\\x77\\x57\\xd0\\xd8\\xa0\\xcf\\x84\\x3e\\x9d\\x94\\x93\\x2b\\x67\\xb5\\xc6\\x7a\\xe5\\xb2\\xdf\\xec\\x4a\\x41\\x9d\\x68\\xd2\\xb2\\x4d\\xac\\x87\\x21\\xf1\\x61\\x3a\\x57\\x1a\\xc2\\x6f\\x75\\x95\\x2a\\xe6\\xd6\\x3d\\xda\\x7e\\x56\\xb8\\x67\\xaf\\x70\\xaf\\x79\\x7f\\x77\\x8c\\xfd\\x0e\\x18\\x70\\xbe\\x6d\\x04\\x00\\x2f\\xb1\\xdf\\x2c\\xb1\\x8f\\x2e\\x24\\xf0\\x94\\x68\\xc3\\x5b\\xc9\\x68\\x0b\\x34\\x8d\\x46\\x25\\xa4\\xbc\\x01\\x97\\x4f\\xbd\\xf0\\x4f\\x56\\xec\\xb1\\x69\\xf1\\x46\\x7c\\x77\\xbd\\x66\\x88\\x5d\\x81\\x75\\xbd\\xa3\\xe3\\xf4\\xea\\x4a\\x91\\x28\\x8d\\x66\\x45\\x42\\x54\\x73\\x7c\\xdd\\x1f\\x85\\xa1\\xa4\\x45\\x50\\x9f\\x79\\x62\\x43\\x83\\x6a\\x43\\x83\\xe2\\xe2\\xba\\xc3\\x8c\\xcb\\xbe\\x2e\\x67\\x8a\\x68\\x11\\x05\\x16\\x24\\x41\\xf7\\x90\\x6e\\x33\\x77\\xef\\x2a\\x1d\\x92\\x68\\x94\\xe4\\x67\\x2e\\x7d\\x32\\xd6\\xaa\\x2b\\xb8\\x3f\\x02\\xa9\\x27\\x44\\xb1\\xd7\\xcc\\x44\\xe2\\xed\\x56\\x38\\x17\\xb5\\x98\\x27\\x68\\x7e\\xef\\x49\\x9d\\x7a\\x42\\x1a\\x4e\\x11\\x45\\x87\\xe3\\xc8\\xcc\\x9d\\xfb\\xc3\\x7d\\xb6\\x2e\\xe4\\xe1\\xbe\\xdf\\x0c\\xb6\\x3f\\x28\\xf6\\xc8\\x16\\x35\\x05\\xb7\\x31\\x52\\xcd\\x7a\\x57\\x00\\xc5\\x25\\x13\\xa3\\x83\\xf7\\x37\\x84\\x5c\\xda\\x61\\x59\\xd1\\x5b\\x1d\\xb3\\x3c\\xc1\\x7c\\xce\\x9e\\x97\\x9a\\x0a\\x56\\xf0\\x54\\xc9\\x33\\x84\\xd8\\xaa\\xc4\\x92\\x12\\x57\\x5b\\x52\\x7e\\xcc\\xbe\\x2a\\x1c\\xc8\\xad\\xee\\x7b\\x65\\xae\\x9a\\x7d\\xa5\\x11\\xed\\xee\\x42\\xf0\\x92\\x78\\x0b\\x69\\x21\\xb3\\x03\\x1f\\xed\\xc7\\x3e\\x3b\\x9e\\xbb\\x6a\\x37\\xdd\\x2b\\xe0\\x8f\\x90\\x3e\\x8f\\x73\\x72\\xb5\\x90\\x65\\x8c\\x1f\\x74\\x4a\\x26\\x7a\\x34\\xdd\\x04\\x6f\\x0d\\x82\\xc9\\x5b\\x48\\x8c\\x0a\\xb5\\xe9\\x02\\x96\\x60\\x7a\\x17\\x19\\xf3\\xdd\\xe9\\x70\\xc5\\x0b\\x82\\x11\\x99\\xc6\\x27\\x10\\x76\\xe4\\xe0\\x8d\\x65\\x70\\xe2\\x04\\x1c\\x6e\\xf7\\x27\\xaa\\x41\\xc5\\x8e\\x23\\x28\\x81\\x50\\xf7\\x3e\\x16\\x3d\\xd8\\x09\\x3c\\x8d\\x4c\\xcf\\x1b\\xcf\\xcc\\x70\\x74\\xf1\\x44\\x8b\\xa0\\xd3\\xd9\\x79\\xf6\\xc6\\x73\\x22\\x18\\x09\\x14\\x21\\xf4\\xac\\x9e\\x7d\\xeb\\x0c\\x67\\x4f\\xae\\x4f\\xa5\\x27\\x25\\x28\\x81\\x1b\\x1a\\x44\\x9d\\xde\\x57\\x36\\x1e\\x44\\x89\\x4e\\xfe\\x56\\xe7\\xca\\x5c\\x85\\x35\\x9a\\x98\\xa7\\x11\\x93\\x6b\\x41\\x86\\xf5\\x05\\xad\\xdf\\xbe\\x6b\\x80\\x8b\\x6b\\x4b\\x41\\x95\\xe6\\xa6\\xe7\\xed\\x34\\x3c\\x2d\\x71\\x3b\\x67\\x20\\x0e\\x7f\\x44\\x66\\x44\\xe6\\xec\\xc7\\x70\\x50\\x79\\xe3\\x35\\xbe\\xd7\\x0e\\xd6\\x78\\x93\\x47\\xf3\\xe5\\x4c\\x33\\x99\\x6d\\xe7\\x05\\x08\\xe3\\xab\\xc9\\xb7\\x59\\x71\\xdb\\x5a\\x27\\x9e\\x47\\x8f\\x94\\xeb\\x32\\xdd\\x3e\\x6b\\x6b\\xe9\\x8b\\x01\\x79\\x47\\x45\\x07\\x7f\\xba\\x1b\\x45\\x48\\xdc\\xcd\\x18\\xbd\\x28\\x50\\x9b\\x03\\x51\\x6b\\xa9\\x94\\x90\\xb4\\xb5\\x65\\xbd\\xa1\\x4c\\x4a\\xb7\\x24\\x80\\xd2\\xf9\\x12\\xd9\\x33\\x49\\xcb\\x93\\x07\\xa9\\xaf\\x93\\x37\\x51\\x9b\\x71\\x96\\x1b\\x11\\xc8\\x0a\\xc9\\x84\\xd3\\x25\\x35\\xd0\\xeb\\x31\\x4e\\xd3\\x95\\x0c\\x42\\x35\\x18\\x07\\x65\\x48\\xa6\\x3b\\xbd\\xac\\xbe\\xda\\x74\\x37\\xa8\\x0c\\xb8\\xef\\xfd\\xb5\\x58\\x1d\\x9a\\x80\\xd2\\x00\\x99\\xa8\\x68\\x6d\\xe5\\x13\\x0c\\xd0\\xf1\\xa4\\x78\\x91\\x3b\\xd1\\x41\\x4f\\xbb\\x7b\\xe8\\x0b\\x6b\\x02\\xe7\\x33\\x90\\xe9\\x20\\xa8\\xf7\\xe9\\xed\\xde\\x13\\x1a\\x24\\x1d\\x55\\x13\\xb5\\xd1\\x1c\\xa8\\x14\\xa0\\x1e\\x40\\xe0\\x35\\x4f\\xe4\\xe6\\x08\\x3b\\x70\\xbb\\x5b\\xed\\x32\\xc4\\x77\\x28\\xb5\\x57\\x97\\x80\\xfd\\x0e\\x05\\x8b\\x22\\xf5\\x55\\xfc\\x6e\\x34\\x8c\\xf8\\x51\\xcb\\x18\\x06\\xca\\x02\\xbf\\xeb\\x9a\\x65\\xdf\\xe7\\x1a\\x7c\\x72\\x13\\x04\\x3c\\x46\\x8f\\xc0\\xc3\\x19\\x1d\\x3c\\x45\\xa7\\x22\\xf0\\xac\\x6d\\x59\\x0b\\x82\\xee\\xdc\\x9e\\x67\\x7d\\x55\\x77\\x57\\x42\\xcb\\x47\\x14\\xc7\\xeb\\x78\\xa5\\x9d\\xd4\\x15\\xac\\xc0\\xae\\x4b\\x2a\\x59\\xe0\\x52\\x17\\x9d\\x81\\xc2\\xdb\\x23\\xc3\\xc4\\x7c\\x71\\xce\\xf3\\x70\\x2f\\x38\\xa2\\x6d\\xba\\x70\\xb9\\xa4\\xdf\\x6a\\xb3\\xe9\\x6f\\xba\\xd0\\xb4\\x79\\x91\\xc3\\x84\\xbd\\x6b\\xc8\\xcd\\xf7\\x84\\x3c\\x5b\\x74\\xed\\x8a\\x68\\x75\\x38\\xd4\\xb3\\x82\\x72\\x24\\x9a\\xe6\\x7a\\x77\\x56\\x07\\x2d\\x20\\x1d\\x04\\x3d\\x50\\xa6\\x19\\xa0\\x4c\\x73\\xae\\xbc\\x35\\xfb\\x6a\\xfc\\x94\\xf0\\x4c\\x73\\xa7\\x39\\x61\\x30\\x9d\\x5f\\x0d\\x1f\\x40\\x97\\xc4\\x55\\x7d\\x42\\x64\\x43\\xe3\\x0e\\x61\\x18\\xd5\\xca\\x47\\x7a\\xfa\\x66\\xd5\\x7c\\xce\\x1a\\xa2\\x08\\xd3\\x45\\x00\\xe2\\x53\\x0e\\x5e\\xce\\xc8\\x3a\\xdd\\xca\\x40\\x49\\xb9\\x71\\x91\\xe8\\xca\\xde\\x35\\xb8\\x79\\xe5\\xf6\\x2d\\x59\\x0c\\x98\\x25\\xf1\\xfa\\x58\\xb8\\x8b\\x15\\x4f\\x7e\\xe4\\x45\\xb9\\x07\\x13\\x74\\x7c\\xad\\xb0\\xc2\\xb9\\xc7\\x9b\\x0b\\x6b\\x36\\x15\\x01\\x60\\x3e\\x27\\xc2\\x7e\\x4b\\xe7\\xb3\\x75\\x8f\\x02\\x4c\\x8f\\xae\\x1f\\xf5\\x7b\\x6b\\xb7\\x17\\xd5\\xf8\\xa8\\xe1\\x12\\x57\\x4e\\x42\\x32\\x4d\\x28\\x49\\xb7\\x54\\x27\\xdb\\xa6\\x30\\xd5\\x58\\xf9\\x44\\xc5\\xd3\\x71\\xc2\\x39\\x50\\x7d\\x53\\x25\\xed\\x13\\xa2\\xb7\\x18\\xd8\\x56\\x43\\x2b\\x53\\x81\\xf5\\x2b\\x81\\xe1\\xca\\xe9\\x48\\x48\\x10\\x6e\\xa6\\x1a\\xd3\\x85\\x61\\x9f\\xb2\\x7d\\xa5\\xc9\\x4d\\xbc\\x57\\x10\\x51\\x68\\xce\\x9d\\x32\\xab\\x30\\x68\\x87\\x91\\x18\\xd3\\xa2\\xc0\\x1d\\xc3\\x60\\xb9\\xe3\\xd3\\x7f\\x38\\x25\\x6e\\xa3\\x0e\\xa7\\x7d\\x10\\xc8\\x51\\xf6\\x69\\xdf\\xf8\\xd8\\x7e\\xac\\x4a\\x42\\xb7\\x87\\x6e\\xf7\\x63\\xdd\\xb6\\xb1\\x16\\x82\\x22\\x05\\x10\\x3b\\x86\\xa5\\xba\\x88\\xc6\\xa4\\x11\\x58\\x7c\\x2a\\x5f\\xad\\x4b\\xb4\\x6c\\x5b\\xd7\\x55\\xcf\\x72\\x88\\x6f\\x56\\xf1\\xea\\x11\\xb7\\x0d\\x14\\x5a\\x0f\\xce\\xd1\\x52\\x0d\\x34\\xe5\\x18\\x08\\xe2\\x76\\x11\\x01\\xd5\\x34\\xfa\\xb0\\xf9\\xd6\\x37\\x97\\xa2\\x02\\x06\\x00\\x95\\x77\\x1d\\x02\\x0f\\x89\\xe5\\x2f\\xf3\\xab\\xdd\\xd2\\x96\\x6d\\xf3\\x03\\x00\\x14\\xbb\\xdb\\xc3\\x05\\x6e\\x77\\x89\\x5c\\x11\\x43\\x68\\x2d\\x24\\xed\\x26\\x8b\\xf5\\x73\\xaf\\x1b\\x9a\\x19\\x49\\xee\\x97\\xf0\\x3e\\x15\\xbc\\xdc\\xe5\\x30\\xe4\\x15\\x41\\x5e\\x14\\xb3\\x60\\xf0\\xda\\xf8\\xf2\\xf9\\x33\\x5a\\xd6\\xa8\\xc7\\xcc\\x72\\xfe\\x96\\x83\\x78\\x0e\\x29\\x0c\\x04\\xed\\x72\\x43\\xb4\\xf2\\x65\\x1c\\xd4\\x9a\\x0d\\x8a\\xb4\\x68\\x96\\x8b\\xc5\\x98\\x0e\\x7e\\xd1\\xf2\\x09\\x2c\\xb2\\x90\\x4a\\x0d\\x91\\x3f\\x7b\\xca\\xad\\x20\\xf3\\x28\\xaf\\x25\\x48\\x22\\x3e\\x42\\x2d\\xca\\xb1\\x36\\x42\\x82\\xc1\\xda\\x9d\\x04\\xa0\\x79\\xdd\\x5e\\x7d\\x7c\\xdd\\x24\\x21\\x3c\\x6d\\x6b\\xa0\\xee\\xbd\\x64\\xe9\\x17\\xf7\\x72\\xfb\\xf4\\xd1\\x03\\x6f\\xcf\\x2c\\x06\\x28\\x60\\x18\\x4c\\xf9\\xd5\\x54\\xd5\\x48\\xa2\\x1d\\x70\\x36\\x0f\\xf7\\x88\\x8a\\x74\\x60\\x9b\\x88\\x20\\xe8\\x70\\x38\\x12\\x6d\\xd7\\x2b\\xcb\\x5a\\x3f\\xb7\\xa9\\x6b\\xe1\\xc4\\xb1\\x43\\x67\\x2a\\x18\\xd1\\x8e\\x24\\x7d\\xeb\\x8c\\xfe\\x15\\xcf\\x55\\x3a\\x35\\x8b\\x30\\x2d\\x21\\x46\\x03\\x52\\x3d\\x9f\\x8f\\x67\\xc3\\xd9\\xdc\\xe5\\x5b\\x6a\\x97\\x06\\x15\\x00\\x41\\x3a\\x07\\x81\\x18\\x55\\x71\\x4b\\xe9\\x06\\xcd\\x71\\x1b\\x71\\xdb\\xd0\\x21\\x36\\x1f\\x37\\x7e\\x06\\xe4\\xc0\\x21\\xb2\\x03\\x8f\\xd1\\x62\\x69\\x13\\x1d\\x32\\x9b\\xc7\\xd8\\xf8\\x13\\xcd\\x67\\xf9\\xe6\\x93\\xcb\\x75\\xf2\\x12\\x87\\x4f\\xc0\\x91\\xd4\\x07\\x82\\x8a\\xbd\\x40\\xae\\xc3\\x76\\xe7\\x1e\\x83\\x7e\\x9f\\x08\\x0e\\x07\\x49\\x65\\x27\\xd6\\x52\\xe3\\x08\\x22\\xba\\x7e\\x9b\\x85\\x2f\\x37\\x07\\xa2\\xc1\\x74\\x03\\x01\\x1c\\xbc\\x0b\\xfd\\x8c\\xc9\\x36\\x1c\\xfb\\xa2\\x98\\x4c\\x49\\xd1\\x67\\xfc\\xd0\\x5a\\x3b\\xf6\\xaa\\x21\\x1b\\x99\\x9d\\x82\\x79\\xae\\xde\\xa5\\x7a\\x44\\x79\\x4e\\xd1\\x08\\xa8\\x9e\\x54\\x5b\\x0b\\xc6\\xf5\\x89\\x20\\xd8\\xbc\\x6d\\xb4\\xea\\xc3\\x35\\xae\\xdb\\xce\\x03\\x47\\x42\\x9a\\xa6\\x2a\\x8d\\xd2\\x7b\\xd5\\x34\\x9d\\x8f\\xbd\\x00\\xcb\\x0b\\x22\\x48\\x62\\xd9\\x75\\x9b\\x2c\\xf7\\xaa\\x40\\x7e\\x09\\xf9\\x67\\xb4\\xf9\\x13\\x3e\\x2b\\xc5\\xad\\x9e\\x49\\x02\\xd8\\xda\\xbc\\x28\\x68\\x61\\x5c\\x32\\x49\\x69\\x63\\xbf\\x1b\\x4e\\xf8\\x89\\x92\\x48\\x3a\\xda\\xd2\\x69\\x47\\x2a\\x22\\x9e\\x15\\x46\\x6b\\xf0\\x1d\\x1b\\x6c\\x68\\xec\\xd4\\xe6\\xe5\\x3b\\x2d\\x3b\\x5e\\xb8\\xcf\\x58\\x63\\x4c\\xbe\\x82\\x80\\x79\\x03\\x19\\xd3\\xbd\\x2a\\x75\\x48\\xe8\\xe8\\x46\\x32\\x85\\xd5\\x0d\\x44\\x7a\\xa8\\xd2\\xba\\x23\\xc0\\x8b\\xd7\\x60\\x97\\x87\\x0b\\x02\\x9b\\x3e\\x28\\x63\\x8f\\x57\\x1b\\x28\\x0b\\x23\\x1d\\xd8\\xdc\\xc3\\x85\\xb4\\x7b\\x4c\\x53\\xcb\\x30\\x39\\x63\\xda\\x5b\\xd0\\xb2\\xbc\\xfa\\x72\\xac\\x74\\xd5\\x96\\xcd\\x2f\\xcc\\xf6\\x8d\\x0e\\x7f\\xbc\\xdc\\xbb\\x00\\x37\\xd2\\x80\\x6a\\x5b\\xbe\\x48\\xbb\\x92\\x76\\x32\\x7f\\x02\\x90\\x61\\x87\\x6d\\xd5\\x35\\xd6\\x83\\xb3\\xe4\\x84\\x3c\\x71\\xef\\x81\\x2e\\x57\\xaf\\xaf\\x4a\\x7c\\x59\\x51\\xb5\\x42\\x4e\\x7f\\x22\\x7a\\xe5\\x00\\xc0\\x8d\\xe8\\x3a\\xb4\\x41\\xd2\\x4e\\x56\\xaa\\xab\\x54\\x4b\\xb5\\x02\\x50\\x6a\\x0b\\xd6\\x3d\\xa2\\x45\\x1e\\x66\\xd2\\xb7\\x6f\\xfe\\xce\\x28\\x33\\xbd\\x2d\\x06\\x08\\x36\\xd3\\xd3\\xc2\\x6d\\x01\\xae\\xcc\\x02\\xa7\\x69\\x9a\\xb8\\xc3\\xc0\\x1a\\x09\\xfb\\x25\\x35\\x3a\\xd9\\xed\\x34\\x6a\\xe4\\x2e\\x43\\x3c\\xf9\\x49\\x12\\x04\\xb9\\xd7\\x0c\\x89\\xc9\\x55\\x42\\x38\\x65\\x09\\x98\\x17\\x63\\xd4\\xc7\\x42\\x75\\x09\\x27\\xf9\\xbc\\xdd\\x31\\x5a\\x49\\x73\\xec\\x60\\x0f\\x96\\x47\\xb5\\x07\\x44\\x01\\xb6\\xf5\\xde\\xf7\\x32\\xcc\\x40\\x80\\xbd\\x1f\\xbc\\x9c\\xda\\x52\\xaa\\x07\\x11\\xa9\\x02\\x4d\\x1f\\xf4\\x3d\\xce\\xf6\\xba\\xbe\\x75\\xfa\\x39\\x57\\x52\\x41\\x72\\x95\\x15\\x23\\x34\\xd8\\xf0\\xd1\\xd5\\xb9\\x48\\x4f\\x0a\\xf4\\x84\\x2a\\x34\\xb9\\xf9\\x12\\x3a\\x4c\\x28\\x34\\xb1\\x4b\\x83\\x09\\x7c\\x0f\\x01\\x43\\x81\\xc9\\xdb\\x7e\\xb3\\x2f\\x08\\x00\\xad\\xc7\\x8d\\xee\\x82\\x8a\\x4f\\x01\\xa6\\x94\\xde\\xa5\\xe2\\x1e\\x10\\x1c\\x78\\x02\\x3c\\xc4\\x2f\\x5a\\x67\\x3e\\x78\\x19\\xbd\\x03\\x57\\x7c\\x6e\\x2c\\x4f\\xcb\\xbd\\x2d\\x29\\xe9\\x6d\\x81\\xf5\\x99\\x14\\xe8\\xe9\\xda\\x8f\\xca\\x5d\\x14\\xd1\\x19\\x52\\x4e\\xdd\\xf1\\xca\\x4a\\x98\\xe8\\x14\\x04\\x75\\x1e\\xc1\\xca\\xe0\\xb4\\xec\\x7b\\x8b\\x18\\x17\\x47\\xb4\\x90\\xcc\\x61\\x46\\xee\\x0a\\x80\\xc4\\xbb\\x3c\\xbc\\x70\\x97\\x08\\x9d\\xec\\x1a\\x72\\x7a\\xd6\\xde\\xa4\\x82\\x15\\x30\\x2c\\xdb\\x3a\\x5c\\xa2\\x8b\\xa7\\x55\\x66\\x2a\\xf2\\xfc\\x09\\x85\\x62\\x85\\xeb\\x0a\\x7a\\x0a\\x11\\x2f\\xd3\\xc4\\x26\\x88\\x8f\\x5d\\x72\\xe2\\xd0\\x67\\x34\\x76\\xd2\\x8a\\xa2\\xc8\\x5d\\x58\\xc8\\x87\\xae\\x6c\\x1e\\xb5\\x4d\\x83\\xfa\\xf0\\xea\\xe5\\xcf\\x37\\x3a\\xc6\\x47\\xcf\\x79\\x61\\xa2\\x60\\x04\\xd1\\xc1\\xcb\\xf2\\xcc\\x19\\xb3\\xba\\xc9\\x8f\\x3c\\xd3\\x34\\x0d\\xde\\x41\\xd1\\xb9\\xd5\\xf3\\x72\\xa4\\xdd\\x25\\x05\\x01\\xb7\\xba\\x54\\x92\\xe0\\x9f\\x02\\x4c\\x6d\\x46\\xe7\\xdc\\x4f\\x2a\\x4e\\xce\\xc4\\xe1\\xda\\xeb\\x00\\xe7\\xc3\\xe2\\x03\\x74\\xbc\\xb6\\xf6\\x8e\\x0d\\x5e\\xa8\\xca\\x31\\x9a\\xad\\x78\\x6d\\x55\\xfc\\x0d\\x45\\x08\\xe8\\x5d\\x1e\\xae\\xac\\x15\\x63\\x13\\xd7\\x6d\\x20\\x3c\\x9f\\xba\\x73\\x48\\xa2\\x11\\xc8\\x38\\x5d\\x4d\\x62\\x97\\x73\\xab\\xdb\\xc8\\x5e\\xde\\xb1\\xfd\\x2a\\x56\\x10\\x31\\x1c\\xe1\\x19\\x5c\\x0d\\x03\\x1c\\xe4\\x07\\xd5\\x5c\\x94\\xa7\\xdd\\xb9\\x63\\xb3\\x6e\\x00\\xea\\x47\\xee\\x1a\\x28\\x02\\x29\\xb7\\x89\\x06\\x9f\\x56\\x16\\xb7\\xec\\xe5\\xa2\\x80\\x9f\\x31\\xc4\\x55\\x7d\\x2e\\xf2\\x24\\x7e\\xda\\xc6\\xe5\\x48\\x96\\x03\\xdb\\x3a\\xb5\\xe1\\xc6\\xf0\\xee\\x2a\\x76\\x3b\\xdc\\xc9\\x03\\x92\\x8c\\x0a\\x73\\x76\\x26\\x8b\\xa2\\xdb\\x30\\x54\\xa2\\x01\\x0a\\x52\\x26\\x9a\\xd0\\x64\\x96\\xd2\\x6b\\x66\\x59\\x9a\\x65\\x1b\\xe3\\xb2\\xf7\\xc8\\xc3\\x16\\x7d\\x80\\x22\\x02\\x06\\x7b\\xd1\\x90\\x8b\\xcf\\xf8\\x49\\x37\\x81\\xdc\\x14\\x02\\xa0\\x5f\\xb3\\x64\\x63\\xc3\\x77\\x34\\xeb\\x5f\\xf5\\x75\\x8d\\x9c\\x9e\\xb3\\x91\\xa8\\xc5\\xfb\\x9b\\x61\\x28\\xbc\\x17\\xb7\\x77\\x61\\x71\\xa4\\xf8\\x1e\\x81\\xd4\\xce\\xe9\\xaf\\x49\\x10\\x92\\x7a\\xae\\xf7\\x24\\x29\\x3d\\xce\\xf2\\x35\\x82\\x33\\xb6\\x6b\\xb1\\x9e\\x32\\x2e\\x19\\x8d\\x5b\\x81\\xba\\x33\\x88\\x23\\xb5\\xf2\\x91\\xa1\\xe4\\x32\\x69\\x19\\xc7\\xf4\\x8f\\xf0\\x63\\x26\\xd5\\x2d\\x84\\x5a\\xac\\x61\\x77\\x69\\xdf\\x4f\\x04\\x0a\\x09\\xa1\\x44\\x3b\\x99\\xa0\\xb4\\xcb\\x4d\\x05\\x0b\\x20\\x07\\x68\\x6f\\x84\\x7d\\x08\\x5b\\xfb\\x88\\x97\\xa2\\x97\\x5c\\x4f\\xb3\\x7b\\x52\\x93\\x59\\x62\\xf1\\x14\\x10\\xaf\\xbc\\xce\\x81\\xea\\xd9\\x70\\xe8\\xfd\\xd4\\x5a\\xc2\\x46\\xe0\\xc5\\x61\\x72\\x8e\\x12\\xd6\\x9b\\xf0\\x5e\\x2f\\x18\\x9c\\x37\\x77\\x3d\\xe9\\xc0\\xe7\\x45\\x68\\x62\\xb8\\x7e\\x86\\x06\\xb6\\xf8\\x67\\x78\\x0a\\x98\\x30\\xa1\\xd3\\x51\\x23\\x08\\x41\\x57\\x0e\\x9e\\xca\\x21\\x7c\\xdd\\x0a\\x14\\x00\\x70\\xc5\\x79\\x20\\x8d\\x50\\x6a\\xf2\\xb8\\x14\\x45\\x91\\x21\\xb4\\x52\\xcf\\xd2\\x09\\xdc\\xe2\\x44\\x3f\\xa1\\x9c\\xa7\\x75\\x56\\xfa\\xac\\x47\\x9c\\x09\\xa7\\x44\\xb6\\x22\\x51\\x1b\\x55\\xe6\\x2c\\x71\\x37\\x1a\\x8c\\xf0\\xc5\\x87\\xdd\\x31\\xab\\x28\\x71\\x19\\x3d\\xb5\\x19\\xf7\\x64\\xc5\\x42\\x20\\x90\\x10\\x92\\x9c\\x9e\\x77\\xed\\xcc\\x45\\xa3\\x34\\xa1\\xcd\\x23\\x41\\x4a\\x32\\x92\\x10\\x51\\x5c\\x83\\x5f\\x80\\x4c\\x74\\x20\\x48\\xbf\\xdc\\x4f\\xc6\\xe7\\xf8\\xef\\x7e\\x0c\\x4c\\x31\\x14\\x5c\\xf7\\x31\\x11\\xb8\\x67\\xa9\\xdd\\x13\\xe4\\x99\\xa3\\x28\\x81\\x9a\\x14\\xc6\\x5f\\xc2\\x44\\x3b\\x9e\\xdb\\x78\\x40\\x15\\x8f\\xa7\\x48\\x98\\xc0\\x30\\x9c\\xbb\\x0d\\xad\\x8b\\x12\\xcb\\x38\\x17\\xd0\\x78\\x9a\\x4f\\x70\\xa4\\xf3\\x8b\\x02\\x77\\x3c\\x84\\xfa\\xda\\x3d\\x44\\x8c\\x1b\\x1b\\x4a\\xf2\\xb7\\x1d\\xa7\\xc9\\xc5\\xb6\\xcc\\x75\\x64\\xc5\\xe7\\xb4\\xb1\\x1d\\x56\\x45\\x46\\xa2\\xe5\\xba\\xbb\\x40\\x09\\xec\\xe0\\xc9\\xcb\\x96\\x6f\\xfa\\x5d\\xda\\x21\\x7f\\x13\\x76\\x65\\x9e\\xd4\\x69\\x02\\x57\\x7d\\xeb\\x4d\\x4d\\x50\\xec\\x07\\x00\\xd0\\x38\\x82\\x09\\xdc\\xab\\x27\\x74\\x16\\x94\\x44\\x2e\\xf5\\xe5\\xf2\\x7d\\x37\\x7b\\xbb\\x37\\x00\\xb6\\x3a\\x12\\xa1\\xd4\\x1c\\xeb\\x1f\\x34\\x45\\x91\\x97\\xfd\\x62\\xb6\\xd2\\x50\\xf5\\x4b\\xd6\\x8b\\xe4\\xb4\\x05\\xb1\\x74\\x3c\\x04\\x0b\\xf0\\x1f\\x83\\x4c\\xed\\x00\\x82\\x42\\x61\\x5a\\xba\\xb0\\x15\\xae\\x57\\x91\\xe6\\xcd\\xde\\x4f\\x75\\x81\\xb3\\xa1\\x65\\x52\\x76\\x9d\\xed\\x2f\\x97\\x4f\\x9d\\x97\\x14\\xdc\\xe6\\x40\\x61\\x86\\xa6\\xab\\xfa\\xea\\xd2\\x66\\x81\\xb8\\x33\\x75\\x58\\x03\\x37\\xe7\\xb2\\x6b\\x3b\\x7a\\x9e\\xf0\\xa8\\x99\\x85\\x02\\xe2\\xad\\xc4\\xdd\\x6e\\x3c\\x4d\\x83\\xa2\\xeb\\xca\\x2c\\x91\\x0c\\x70\\x0c\\x14\\x9a\\x02\\x2b\\xcf\\x52\\x40\\x48\\x14\\x0f\\x1f\\x75\\xd8\\x30\\x29\\xf7\\x6d\\x9c\\xe3\\x25\\x2c\\xe5\\xd9\\x6c\\xb7\\x28\\xf5\\x9a\\x01\\xc1\\x4a\\x5e\\xf9\\x7c\\x8d\\x2a\\x9f\\xf3\\x5a\\x7c\\x39\\x21\\x0c\\x42\\xa1\\xbe\\x40\\x57\\x74\\x4b\\xbc\\x4e\\x4b\\x45\\x11\\x92\\xec\\x7a\\xf4\\x88\\x95\\x58\\x32\\xca\\x4f\\x4e\\xb7\\xf7\\x6e\\xbc\\x74\\xbc\\x2d\\x44\\xfb\\x5f\\xe1\\xc5\\xd0\\xf4\\x2e\\xd9\\x17\\x74\\xb9\\xc6\\xde\\xf5\\x8e\\xf5\\x07\\xda\\x19\\xa8\\x36\\xf9\\xb1\\x88\\x5d\\x79\\x24\\x1f\\xbc\\xa6\\x30\\xba\\x93\\xb8\\x19\\x0d\\x01\\x27\\x2b\\x11\\xf7\\xb3\\xcc\\x00\\x2c\\x7f\\xe5\\x9f\\x01\\x0f\\x16\\x45\\xd6\\x6b\\xec\\xd8\\x70\\xdd\\xbd\\x83\\xae\\xd7\\x0e\\xa2\\x9a\\x8b\\xc4\\xdc\\x9f\\xdf\\xf6\\x23\\x8c\\x4a\\x93\\x39\\x40\\x03\\x77\\x2a\\xbf\\xc3\\x7a\\x95\\x90\\xe4\\xe9\\xc4\\xbc\\x79\\x70\\x90\\xb8\\x4d\\xf7\\x65\\xc5\\x81\\xeb\\x14\\xfa\\x42\\x45\\xf8\\xcd\\x40\\x20\\x00\\xd6\\xdd\\xb1\\xcb\\x16\\xd9\\x6e\\xc3\\xce\\xa8\\xb2\\x45\\xd3\\xcd\\x89\\x13\\xb2\\xe0\\xac\\x9e\\x7a\\x72\\x65\\xc9\\x7f\\xcc\\xd3\\x3c\\xb3\\x91\\x03\\x99\\x0f\\x63\\xdc\\xe2\\x6e\\x5c\\xe4\\xbe\\x82\\x87\\xbe\\xc0\\xa6\\x3b\\xa7\\x48\\xf5\\xed\\xae\\xed\\x04\\xbc\\x43\\x15\\xda\\x3b\\xcf\\x54\\x83\\xe8\\x0c\\xa1\\xbd\\x54\\x98\\x77\\x5c\\xb5\\xc7\\xf9\\x2e\\x6d\\x2a\\x9c\\x0f\\x90\\x0b\\xa4\\xc6\\xd5\\x3f\\x91\\xa8\\x14\\x58\\xbe\\x5f\\xd4\\xf7\\xfa\\xc9\\x00\\x9a\\xcf\\x96\\x00\\xd5\\x6b\\x81\\x65\\xbb\\xab\\xaa\\x69\\xcf\\x60\\x99\\x33\\x4b\\x1f\\xc8\\xb7\\x9d\\x20\\x3a\\x90\\xf9\\xb6\\xa0\\xd9\\x33\\x15\\xd9\\x3a\\x9c\\xe5\\x7a\\xce\\xea\\x76\\x18\\x9e\\xeb\\x80\\x1a\\x57\\x25\\x68\\x69\\x7d\\x84\\x90\\x40\\x01\\x8c\\x9a\\xe7\\xc2\\xb7\\x9d\\xd5\\x75\\xe7\\x8a\\x8b\\x4c\\x58\\xdd\\x10\\xe7\\xdd\\x80\\x64\\x53\\x22\\x47\\xcc\\xa4\\x74\\x95\\xe9\\x0b\\x82\\xbd\\x06\\xa2\\x58\\xe3\\x4a\\x6b\\x82\\x41\\x92\\x6c\\xd7\\xc6\\x29\\xc4\\x9d\\x72\\x05\\x22\\xde\\x01\\x6d\\x48\\x10\\x70\\x8b\\x75\\xb0\\x27\\x01\\x2a\\x11\\xd9\\x32\\xbd\\xee\\x2b\\xec\\x2b\\x4f\\xc7\\x1b\\x37\\x87\\x88\\xf6\\x5d\\x5f\\xa0\\xb5\\x81\\xe2\\x3b\\x94\\x37\\x10\\x96\\x8b\\xd5\\x2d\\x8e\\xc3\\x96\\xad\\xde\\xf6\\x64\\xb2\\xfd\\x1a\\x3b\\x20\\xd8\\x70\\x20\\x5a\\x3d\\x29\\xf0\\xc5\\x3d\\x20\\x8e\\xb5\\x3b\\xb6\\x08\\xfa\\x1a\\xcb\\x50\\x10\\x1f\\x81\\x6e\\x88\\x5d\\x6f\\x35\\xdd\\x5c\\xdf\\xa6\\x05\\x87\\x28\\x84\\x3a\\xed\\x6b\\xf9\\x99\\x03\\x8d\\xa3\\x9f\\x89\\x6d\\xc2\\x66\\x4f\\xad\\xcb\\x63\\xf1\\xc6\\x15\\x49\\x12\\x58\\x1d\\x9f\\x48\\xde\\xa1\\xcf\\xc6\\x4e\\x26\\xb3\\xd0\\x85\\xb4\\x28\\x10\\x3c\\x05\\xb2\\xf8\\x65\\xc2\\x1c\\x1d\\xda\\xc2\\x1f\\xb4\\xb0\\x95\\xeb\\xe2\\x21\\xb0\\xb6\\xdf\\xc8\\xb9\\xeb\\x09\\xaf\\x97\\xd1\\xd5\\x7a\\x40\\xa2\\x33\\x0c\\xd5\\x8c\\x2e\\x53\\x94\\x8b\\xec\\x23\\xe3\\x53\\x61\\x5b\\x08\\x95\\x2b\\x47\\x4f\\x15\\xca\\xc2\\x11\\x8a\\x00\\xa2\\x35\\x3b\\xd3\\x83\\x6d\\x45\\xd5\\xee\\x5a\\xf5\\xb1\\x7e\\x2f\\x89\\xe0\\x38\\x83\\xa9\\x81\\x06\\xc5\\x19\\x30\\xb0\\x80\\x71\\x3c\\x77\\xbd\\xc8\\x0a\\x9a\\x3d\\x0d\\x44\\x13\\x65\\x9b\\x3a\\x6c\\xe5\\x75\\xf3\\x83\\xd3\\x3e\\x00\\x70\\x9c\\xef\\xfd\\x40\\xac\\x23\\x4c\\xe0\\xd1\\x99\\x34\\x57\\xee\\x5a\\x8e\\x13\\x9d\\xa9\\xc2\\xc7\\xec\\x5a\\x6c\\x0a\\x89\\x82\\xa0\\x31\\x24\\x21\\x62\\x85\\x51\\xfe\\x9a\\x59\\xd3\\xeb\\x33\\x6f\\x0e\\x6b\\xc8\\xaf\\x75\\xbf\\x6d\\x64\\xea\\x23\\x00\\xe5\\x7a\\x9a\\x83\\x81\\xba\\x83\\xaa\\x5e\\x9c\\x78\\x0d\\x9e\\xe7\\xfe\\x78\\x4c\\xde\\x04\\x03\\xc9\\x03\\x2f\\x23\\x76\\xa7\\x7b\\x52\\xef\\x48\\x72\\x3d\\x81\\x0b\\xb2\\x65\\x71\\xae\\xde\\x57\\x1b\\x06\\x29\\xb3\\xe3\\xa9\\x68\\xe6\\x1f\\xf8\\xd5\\xea\\x2c\\xaa\\xa8\\x4c\\xac\\x40\\xc9\\x6c\\x26\\x75\\x9e\\xef\\x29\\x3a\\x37\\x6a\\xa9\\x0a\\xe7\\xce\\x19\\x8e\\x79\\x52\\x5e\\x3e\\x6f\\xdc\\x6b\\x04\\x01\\xc1\\x9d\\xf0\\xb3\\xd8\\xaf\\xa9\\xf1\\xd6\\x39\\xcd\\x51\\xf9\\x68\\xa2\\x75\\xb7\\x76\\x87\\x38\\xe1\\xdb\\x77\\x09\\x37\\xb6\\xc8\\xbb\\x81\\x2c\\x40\\xbf\\x00\\x89\\x40\\x82\\xae\\xd1\\x89\\xb2\\x29\\x08\\x9e\\x6d\\xe6\\x54\\xd9\\x43\\x4d\\xbc\\x78\\x2a\\x36\\x94\\xec\\xb6\\x69\\x4a\\xf2\\xb8\\xc5\\x27\\x8a\\x2a\\x46\\x3c\\x0f\\x1e\\x89\\xd6\\x9e\\xe1\\x76\\xf5\\x54\\xbf\\x1b\\x62\\x93\\xcf\\xc6\\x7d\\x5f\\x36\\x6f\\x29\\xdc\\x6a\\xb1\\x51\\xe4\\x80\\x13\\x6d\\x84\\xd3\\xd9\\x56\\xb1\\x69\\x5c\\x87\\xd9\\xef\\xd0\\xa9\\x81\\xc9\\x6c\\x05\\xf2\\x4e\\x3e\\x21\\x20\\x5c\\xff\\x3f\\xaa\\xae\\x63\\xcd\\x55\\xa4\\x59\\x3e\\x10\\x8b\\xc2\\x43\\x2d\\x25\\x21\\xe1\\x8d\\xf0\\xb0\\xc3\\x7b\\xef\\x79\\xfa\\xfb\\xf5\\xf9\\xe7\\xf4\\xcc\\x5d\\xb7\\x3e\\x75\\x43\\x55\\x66\\x46\\x64\\x46\\x46\\xcf\\x58\\x36\\x7e\\xaa\\x33\\x5c\\x77\\xbd\\xe7\\x3b\\x9c\\xa6\\x65\\x5b\\xfe\\xf6\\x88\\x34\\xaf\\xee\\x08\\xe0\\xae\\xe5\\xfa\\x88\\xe9\\x48\\x90\\xe8\\xdc\\x01\\xc0\\xb9\\x66\\xc8\\xbb\\xb9\\x40\\x41\\x4a\\xdf\\x81\\xe8\\xaf\\xcb\\xca\\xff\\xd1\\x17\\x73\\x0f\\x01\\x32\\xd1\\xe6\\xad\\x64\\xf8\\xb6\\xcc\\x21\\x43\\x00\\x03\\xe9\\x77\\xc0\\x5d\\x1f\\xdc\\x7b\\x1c\\x1f\\x29\\x71\\x08\\xa2\\xf7\\xfb\\xef\\xe2\\x2b\\xe5\\x91\\x08\\x7a\\xbd\\x33\\x20\\x5f\\x69\\x6c\\xe7\\x4f\\x7c\\x9d\\x23\\x0c\\xd2\\x6c\\xe2\\xd3\\x48\\x3d\\x71\\xa2\\x25\\xf6\\x12\\x9a\\xb5\\x4e\\xe1\\x56\\x03\\x21\\x5f\\x0b\\x0b\\x3c\\xcc\\x6a\\xac\\xcf\\x35\\x54\\xe2\\x65\\xc0\\x7a\\x5d\\xb7\\x17\\xe4\\xa4\\x6d\\x56\\xde\\xa7\\x6a\\xcb\\x6e\\xb4\\xe1\\x44\\x8c\\xae\\x72\\x3d\\x4d\\x63\\xe4\\x62\\xe7\\x26\\x1c\\x64\\xb0\\x32\\x7b\\xca\\x20\\x60\\xa7\\x6a\\x86\\x61\\x18\\x74\\x58\\x76\\xb8\\xc7\\xb8\\x54\\x39\\xbd\\x74\\x7d\\x9b\\xa7\\x5e\\xa5\\xdf\\x08\\xf8\\xeb\\x35\\x9d\\x65\\x7a\\xd7\\xac\\x57\\xa0\\x7c\\xe1\\xe4\\xef\\x63\\xfe\\x33\\xf6\\xf8\\xdf\\x99\\x3c\\xf6\\x1f\\x0c\\x94\\x22\\x4c\\x34\\xb0\\xf5\\xf7\\x63\\xfa\\xed\\x84\\xa5\\xee\\xb3\\x4f\\x19\\x14\\x2a\\x76\\xcc\\xf4\\x18\\xb6\\xdf\\x6c\\xd1\\x1b\\xfd\\xbd\\xb6\\x8b\\x36\\x22\\x20\\xef\\xe0\\xce\\x90\\x02\\x44\\x88\\x7c\\x27\\x26\\xcc\\x9b\\x8e\\x41\\x7e\\x15\\xca\\xb6\\xf0\\xd1\\xea\\x76\\x9b\\xac\\xda\\x0e\\xaa\\x0d\\xf1\\x0b\\x52\\xa3\\x3c\\xfa\\x33\\x39\\x64\\x84\\xf9\\xf5\\x51\\x7e\\x7d\\x91\\xec\\x2e\\xcb\\x15\\xb9\\xc7\\x71\\x4c\\x21\\x49\\xaf\\xdc\\x5f\\x42\\xbf\\x6f\\x8c\\xc8\\x18\\xc2\\x42\\x7d\\x65\\xbe\\x11\\xbc\\x5b\\xb1\\x10\\xd9\\xd5\\xb0\\xd7\\xf8\\xb0\\x89\\x1f\\xab\\x55\\x40\\x23\\xc3\\x5e\\x16\\xbb\\x37\\x94\\x64\\xb3\\xdf\\x83\\xd5\\xb9\\x08\\x4b\\x16\\xf7\\xaa\\xd1\\x9c\\xe3\\x4b\\xf4\\xf9\\x3b\\x4f\\x62\\xc5\\x15\\x22\\x07\\x40\\x61\\xee\\x2b\\x06\\x4e\\x91\\x9b\\x4e\\x97\\xcc\\x17\\x0c\\x30\\x1f\\xbf\\x91\\x20\\x6d\\xf1\\x46\\xa6\\x29\\xbc\\x33\\x0c\\xe6\\x3e\\x35\\x42\\x8e\\xa8\\x92\\x5e\\x42\\xd9\\xc4\\x00\\x42\\xd7\\xe1\\x60\\x48\\x95\\xa9\\x1a\\x26\\xe5\\x71\\xcd\\x88\\xd5\\x8c\\x4a\\x84\\xaf\\xdb\\xea\\x76\\xfb\\x57\\x21\\x8d\\xf6\\x7f\\xfb\\x18\\xc7\\xf0\\x79\\x46\\x2c\\xd1\\x3d\\x83\\x85\\x88\\xd7\\x63\\x70\\x14\\x9b\\x42\\x59\\xdd\\x46\\x21\\x13\\xb0\\xe5\\x0f\\x97\\x20\\x56\\xfa\\xa6\\xa0\\x25\\x35\\x57\\x37\\x4e\\x59\\x3f\\xd2\\x5f\\xc1\\x11\\x24\\x57\\x6e\\xc3\\xcb\\xf1\\x84\\xbd\\x9b\\x8d\\x93\\xdb\\x20\\xb6\\x0d\\x90\\x0f\\xf8\\xe0\\x91\\xcb\\xc5\\xb3\\xfc\\xb7\\x5f\\x83\\x1c\\x38\\x82\\xef\\xfb\\x4c\\x71\\x4d\\x65\\x53\\x25\\xc3\\x94\\xc8\\xb6\\xc9\\xd5\\x30\\xbe\\x46\\xe8\\xd1\\xac\\xc1\\x61\\x3c\\x8c\\x62\\x5b\\x8e\\x6c\\x09\\x65\\xe8\\x28\\x28\\x47\\x04\\x58\\x12\\x79\\xa5\\x38\\x93\\x0e\\xa1\\x70\\x22\\x79\\x4f\\xb1\\xf9\\x57\\xc5\\x24\\xdb\\xe9\\xc6\\x69\\x22\\x25\\xa6\\x70\\x0b\\x55\\xaf\\x08\\x83\\x78\\x02\\xf6\\x89\\x63\\xf9\\xe1\\x8e\\x74\\xd6\\xc5\\x5a\\x87\\x6c\\x7f\\x94\\x7f\\xe5\\x7c\\xa1\\xe7\\x93\\xfb\\xa2\\x1a\\x93\\x6e\\xf8\\x36\\xd3\\x5b\\xae\\x11\\x10\\xf1\\x3f\\x67\\x32\\x08\\x36\\x1f\\x72\\xb2\\x56\\x8b\\x0c\\x3d\\x5f\\x98\\xaf\\x72\\x03\\xbd\\xf5\\x4a\\x5b\\x4d\\x0f\\x96\\xfc\\xa6\\xcf\\x5f\\x6d\\x81\\xfe\\x64\\x4e\\x92\\xce\\x37\\xa1\\x3e\\x9b\\xfd\\xae\\x7f\\x80\\xeb\\xff\\x6a\\xb0\\x1b\\x09\\xde\\xa0\\x29\\x57\\x33\\x5e\\xc9\\x6e\\xe8\\xc4\\x3d\\x2c\\x06\\x8b\\x34\\xcc\\x53\\xc3\\x53\\x92\\x42\\xde\\x8c\\x4b\\xa7\\xc6\\x47\\xb2\\xdc\\x6e\\xb9\\x9b\\x02\\x2f\\xc5\\x1f\\xa8\\x76\\xaa\\xa9\\x90\\x1b\\x27\\xf7\\x76\\x08\\x50\\x9f\\x03\\x5a\\x66\\x86\\x79\\x87\\xbc\\xdd\\xd8\\x76\\x9e\\x13\\xda\\x6c\\xe1\\x2b\\x91\\x32\\x31\\x34\\x91\\x7e\\x64\\x52\\xe6\\xc6\\x91\\xb9\\x6c\\x73\\x5d\\x78\\x95\\x81\\x70\\xbd\\x1c\\x93\\xcf\\xfa\\xd1\\x4d\\x63\\x9f\\xed\\x51\\x4c\\xd7\\xcf\\x73\\x8c\\xa2\\x4e\\x2a\\xfc\\x96\\xd6\\x51\\x31\\xf9\\x8b\\xcf\\x0e\\x35\\x69\\x2c\\x7f\\x1e\\x5b\\x37\\xed\\xc3\\x2e\\x6e\\x04\\x30\\xe3\\x38\\x4e\\x49\\xb6\\xd3\\x48\\x77\\x1c\\xf7\\xd4\\x16\\x77\\x14\\x92\\xe4\\xb8\\x00\\x1e\\x33\\xad\\xaa\\x5c\\x41\\x23\\x8b\\xa7\\x0b\\x17\\xe2\\x4d\\x93\\x5c\\x88\\x95\\xae\\x79\\x6a\\xad\\x58\\x13\\x3d\\xcd\\x86\\x49\\x8e\\xf2\\x2b\\x81\\x44\\x77\\x67\\xd9\\x9a\\xa5\\x62\\x5e\\x3d\\x9d\\x4f\\x19\\x74\\x9f\\x68\\x26\\xe2\\xe7\\xf9\\x45\\x0c\\xaa\\x5c\\x99\\xcc\\xdf\\x11\\x8d\\xdc\\x5d\\x9a\\x3f\\x97\\x08\\x22\\x77\\xd6\\x50\\x9e\\xdb\\x85\\x9e\\x2b\\xf9\\x54\\xcc\\x3d\\x22\\x0e\\x47\\x88\\x91\\xd6\\x2f\\x27\\xc7\\xeb\\xb8\\xe5\\x09\\x73\\x18\\x3c\\xf6\\x71\\x29\\xc5\\xef\\x9c\\x49\\xb8\\x96\\x29\\x6f\\x5f\\x69\\x80\\xbe\\x4a\\x6c\\x68\\xa4\\x2b\\x4f\\xb7\\xce\\x55\\x64\\x03\\x79\\xe5\\x28\\xa5\\xd7\\x75\\x9f\\xe5\\xfa\\x9d\\x06\\x04\\x99\\x9a\\xa1\\xdc\\x2c\\x78\\xae\\x0b\\x35\\x76\\x85\\x3a\\x5f\\x99\\x99\\x98\\x1b\\xe6\\x3b\\x13\\x36\\x0a\\xd5\\xeb\\x8d\\xd9\\x06\\xe9\\x3a\\x3b\\x10\\x2e\\x55\\x83\\x69\\xb6\\xdb\\x7c\\x98\\x33\\x9a\\x5d\\x8a\\x00\\xbe\\xd7\\xdb\\x14\\x19\\xf1\\x66\\x7f\\xd2\\xe8\\x03\\xef\\x70\\x62\\xc7\\x89\\x55\\x28\\x9b\\xcc\\x53\\x5c\\x76\\x03\\xb3\\x36\\xa1\\x98\\x64\\x4f\\xf4\\x38\\x13\\x3c\\x4d\\xdc\\xba\\x16\\xcd\\x5a\\x24\\xb3\\xb3\\x22\\x5e\\xef\\x3a\\x7b\\x3e\\x3f\\x45\\x7a\\x4a\\xff\\xe8\\x19\\xb8\\x63\\x8e\\xe6\\x29\\x6a\\x7c\\x9e\\xf0\\x39\\x8e\\x0b\\x4f\\x24\\x83\\xb9\\x37\\xc7\\x79\\x92\\x4d\\x8b\\xfa\\xc0\\x70\\x36\\x33\\xf8\\xd3\\x26\\xee\\x6b\\x34\\xd3\\xfc\\xa3\\xb0\\x7d\\x84\\x45\\x3b\\xba\\xed\\x5c\\x81\\x23\\xdb\\x4f\\xe2\\xbb\\x9a\\x51\\xf9\\x12\\xf7\\xd3\\x44\\x43\\x3e\\xdf\\x59\\x01\\x9c\\xa2\\xfb\\xb1\\x7c\\xce\\xe3\\xd6\\x2c\\x07\\xa8\\xcd\\xdd\\x90\\x5d\\x62\\xd7\\x65\\x25\\x32\\xe0\\xc4\\x00\\x9b\\xae\\xbd\\x15\\x60\\x3e\\xc3\\x6f\\x0c\\x93\\x9c\\x15\\xad\\xbf\\xba\\x85\\xc7\\x33\\x5f\\xda\\x62\\x69\\x2f\\x1a\\xbb\\x6c\\xb8\\x79\\xed\\x3c\\x81\\x1f\\x58\\x28\\xc0\\xc0\\xd3\\x0a\\xa2\\xdf\\xcb\\x6e\\xac\\x0e\\xe1\\xfb\\xa7\\xb5\\x7e\\x0f\\x06\\xc1\\x90\\x1c\\x01\\x08\\x48\\x4e\\xc9\\xe8\\x1b\\x98\\x58\\x89\\x95\\xdb\\xba\\xde\\x73\\x85\\xef\\x99\\x01\\x25\\xb2\\x3e\\x58\\x2f\\x73\\x38\\x67\\x35\\x2c\\xb0\\x07\\x0c\\x41\\x85\\xfd\\xac\\xd2\\xfa\\xdd\\xb0\\x00\\x4c\\x1d\\x01\\x91\\xc3\\xdc\\x5f\\xc9\\xec\\xd2\\x97\\x58\\x8b\\xd7\\x37\\x87\\xc7\\x1d\\x22\\x0b\\x2b\\x14\\x70\\x7e\\x0f\\xfc\\x07\\xbf\\xfe\\xb9\\x87\\x52\\xae\\xf7\\x32\\x6e\\x03\\xf8\\x39\\x02\\xef\\xc8\\xf2\\x13\\xe1\\x8e\\x9c\\x7b\\xaf\\x14\\xfd\\x8d\\xe3\\x12\\x66\\x20\\x45\\x90\\x59\\x10\\xca\\x23\\x12\\x4c\\x9d\\x91\\xa6\\x65\\x72\\x9f\\x83\\x5a\\x76\\x7c\\x40\\xe9\\x76\\x37\\x8e\\x4a\\x15\\x60\\x3e\\x13\\x22\\x05\\x1a\\xbb\\x13\\x96\\x49\\x09\\x0c\\xb8\\x21\\xaf\\x2f\\x1f\\x90\\xcc\\x02\\x11\\xb6\\xd5\\x4d\\x9e\\x56\\x7c\\x1a\\x66\\x8b\\x5f\\x11\\x60\\xe3\\xa2\\x78\\xce\\xdb\\xd7\\xeb\\x58\\xac\\x22\\x70\\xff\\xe9\\x69\\x72\\x85\\x85\\xe7\\x33\\xbd\\x39\\xb9\\xc6\\x35\\xd4\\x14\\xbf\\x8e\\x42\\x8f\\x40\\x88\\x74\\x57\\x68\\x2e\\x78\\x3c\\x9a\\xeb\\xa6\\xc5\\x1e\\xd6\\xb0\\x10\\xb6\\xa5\\x52\\x31\\x15\\xd5\\xa9\\x9f\\xc2\\x53\\xa8\\x25\\xb2\\x9f\\x1a\\x1b\\x0f\\x58\\x04\\xca\\x07\\x6d\\xe0\\x08\\x1c\\xb0\\xfd\\x12\\x9a\\x0b\\x11\\x0c\\xc3\\xd8\\x17\\xc2\\x26\\x4e\\x85\\xd2\\x90\\xe4\\xe7\\xb3\\x93\\x4b\\xef\\x2e\\xf2\\x58\\x49\\xfe\\x48\\xa7\\x93\\x7f\\x96\\xfe\\xdf\\xfc\\xf1\\xb8\\x89\\x14\\x85\\x03\\xad\\xd7\\xec\\x80\\x30\\xe1\\xea\\x4c\\xcb\\x22\\x1a\\x99\\x71\\xda\\x35\\xbb\\x50\\xc4\\x9f\\xf1\\x7d\\x0e\\xe8\\x59\\xeb\\xa3\\x85\\x15\\x71\\xea\\xe5\\xca\\x54\\x38\\x6b\\xd2\\x5c\\x74\\x9f\\xcb\\x96\\xa3\\xa8\\x29\\x55\\xa2\\xce\\xaf\\x00\\x1a\\x3e\\x61\\xb7\\x0b\\x76\\xd5\\x7d\\x4d\\xa2\\xf2\\x7b\\xcf\\x73\\x5e\\xd1\\xc6\\x55\\xbb\\xc5\\xf8\\xa7\\x0e\\xb4\\x16\\x95\\x8b\\x06\\x4e\\x29\\x11\\xb2\\xa3\\x90\\xfb\\x2a\\xef\\x82\\xff\\x6d\\x4a\\x92\\x9c\\xd6\\xd3\\xa7\\x1d\\xe8\\x66\\x91\\x0a\\x2e\\xe6\\xb9\\xcd\\x7c\\x1b\\xd7\\x83\\x50\\x70\\x90\\xa6\\xd9\\xde\\x08\\xda\\xa7\\x5b\\x08\\x62\\x95\\x31\\x96\\x4a\\x73\\xb9\\xe9\\x1e\\xb8\\x54\\x0f\\xe4\\xa6\\x5c\\xac\\x52\\x2f\\xdd\\xea\\x2b\\xcd\\x15\\x29\\x12\\x22\\x10\\x73\\xd3\\x38\\x69\\x23\\xcc\\x3c\\x32\\xef\\xb4\\xd2\\x83\\x9d\\x2d\\x35\\x67\\xa2\\xeb\\x31\\x1c\\x52\\x41\\x14\\x72\\x8c\\x32\\x24\\xea\\xa6\\xce\\x35\\xa8\\xbf\\x45\\xf1\\x9b\\xff\\x35\\x70\\x64\\x33\\xaa\\xd5\\x0e\\x71\\xd5\\xd8\\x46\\x25\\x85\\x1b\\x92\\x4e\\x46\\x33\\x79\\xc0\\x84\\x4f\\xc6\\x24\\xfd\\x07\\xcb\\x06\\xd8\\xee\\x8e\\xf8\\xf6\\x9e\\xd5\\x72\\xc2\\x92\\xcf\\x81\\xa9\\x34\\xf4\\x67\\x88\\x56\\x9e\\xe2\\xa5\\x64\\xde\\x8e\\x9d\\xbb\\x7a\\xd5\\x49\\x48\\xd8\\x18\\x77\\x0c\\xc2\\xb6\\x10\\x58\\xc9\\x99\\x52\\xdc\\xfb\\x54\\x23\\xaf\\x7d\\xf5\\x27\\x9e\\x49\\x14\\x2b\\x3c\\xf8\\xcf\\xef\\x73\\x3f\\xb7\\xb4\\x77\\x31\\xdb\\xc1\\xd4\\x8b\\xa3\\x67\\x3b\\x4a\\x1a\\xd9\\x60\\x19\\xf9\\x1a\\xbd\\x73\\x89\\xdf\\x17\\x87\\x8c\\xa8\\x3e\\x03\\xec\\xf6\\x80\\x87\\xc1\\x44\\xc1\\x25\\xae\\x19\\x65\\x9b\\x05\\xca\\xf9\\xe8\\x61\\xfc\\xa9\\xce\\x60\\x4a\\x26\\x0a\\xfd\\x6a\\xc5\\xc2\\x9c\\xef\\xb9\\xbd\\x1d\\x42\\x23\\x00\\x76\\x61\\xf0\\xd4\\x9f\\xc7\\x4b\\xeb\\x6c\\xf7\\x2a\\xfd\\x8b\\x83\\xb3\\x89\\x5b\\xfd\\xb2\\xd8\\xc6\\xa3\\xa4\\xfe\\xf6\\x65\\x9f\\x2c\\x49\\x5c\\xdc\\xa3\\x5f\\x78\\x8b\\x9c\\x14\\xf1\\x12\\xab\\xc8\\xa0\\x04\\xb4\\x9b\\x30\\xf9\\x5a\\x5c\\x9c\\x7b\\x43\\xc3\\x26\\xe0\\x1d\\x41\\xb8\\xc7\\xfa\\xed\\xb0\\xaf\\xec\\xa9\\xf2\\xbd\\xec\\x1f\\x45\\xfa\\xf0\\x66\\x97\\x86\\x66\\xa8\\x9d\\x37\\xcc\\xfd\\x1c\\x49\\xd7\\xdd\\xa2\\xc4\\xc6\\x6b\\x0c\\x0b\\x5d\\xff\\x30\\x88\\x46\\x68\\x2d\\x6b\\x54\\xa3\\x2e\\x6c\\x83\\xfa\\x51\\xf8\\xbf\\xfc\\x4b\\xa3\\xa6\\x48\\x61\\x0b\\x20\\x7f\\xfa\\xd2\\x47\\x6a\\x03\\x9d\\x3c\\xb9\\xe6\\x96\\x53\\xcd\\x79\\x6c\\x26\\x4e\\x2c\\x17\\xce\\x64\\x15\\x83\\xa5\\xe3\\x40\\x1e\\x89\\x87\\x4a\\x3c\\x7a\\xed\\x5a\\x4e\\xd5\\x6a\\x06\\x6b\\xb6\\x26\\x86\\xb0\\x28\\x51\\xca\\x42\\x32\\xc1\\xe9\\x4c\\x9d\\xd9\\x2a\\x31\\xee\\x60\\x31\\x01\\x82\\x10\\x88\\x98\\x3d\\xb5\\x60\\x58\\x9e\\xb6\\x5e\\x6e\\xae\\xce\\x2f\\x4a\\xf7\\xfc\\xbb\\x3b\\xfb\\x7a\\x70\\xc7\\xa1\\x72\\x9f\\xb1\\xcd\\xd1\\x32\\x0d\\x1a\\xe9\\x95\\xf6\\x11\\x1e\\xc9\\x28\\xe9\\x12\\x50\\xef\\x79\\x49\\x6e\\x85\\xf5\\x8a\\x5c\\xb8\\x33\\x90\\x65\\xd9\\xc0\\x16\\xc8\\xf3\\x33\\xa5\\xf5\\x37\\xba\\x13\\x59\\xae\\x16\\x0e\\x9a\\xed\\x52\\x11\\x45\\xfa\\x2a\\x48\\x9d\\x7b\\x0e\\xda\\xb3\\x17\\x06\\x47\\xf7\\x05\\x66\\x69\\xd3\\x3c\\xcb\\x7c\\xd7\\xc5\\x48\\x33\\x0e\\xc4\\xe9\\x5a\\x56\\x54\\x1f\\x09\\xb5\\x60\\x42\\x22\\x55\\xca\\x44\\xf9\\x81\\xac\\x26\\xf7\\xdb\\x43\\x30\\xfa\\x57\\x39\\x3a\\x3e\\xf2\\xfd\\xfa\\xea\\xab\\x61\\x13\\x03\\xe7\\x4f\\x4f\\xb5\\x46\\xe9\\x52\\xeb\\x2f\\xcb\\x0b\\x2d\\x8c\\x7d\\x2c\\x07\\xcd\\x79\\xb3\\x5e\\x1c\\x90\\x2f\\x48\\x24\\x3a\\x14\\x46\\xe8\\x79\\x9d\\xe4\\xbc\\x1c\\xaa\\x4f\\xe8\\x3e\\xdf\\x87\\x7b\\x75\\xa7\\x22\\x7f\\x35\\xbd\\x84\\xe6\\x4f\\xd4\\x07\\xd7\\x70\\xb2\\x44\\xcf\\xb1\\x3b\\x3e\\x8b\\x63\\xeb\\x13\\xe1\\xa6\\x11\\x5b\\x45\\xe5\\x51\\xc6\\xa7\\xef\\xef\\x7f\\x38\\x7b\\xf1\\x52\\xa8\\x4c\\x69\\xaf\\x8e\\x56\\x01\\xba\\x73\\x5f\\xd4\\xc8\\x10\\x04\\x12\\xea\\xfd\\x38\\x4f\\x6b\\x95\\xa6\\xd5\\xea\\xae\\xfe\\x66\\xd8\\xbc\\x42\\x00\\xa2\\xc9\\x4f\\x90\\x6f\\x9f\\x6e\\x8a\\xde\\xa5\\x68\\xa1\\xab\\x66\\x3e\\xc0\\x8b\\x9c\\xfd\\xfa\\x99\\x83\\x81\\x78\\xb8\\x20\\xae\\x05\\x40\\x88\\x8c\\x1f\\x28\\xae\\x2b\\xf3\\xc3\\x8a\\x3c\\x94\\x31\\x9f\\x71\\x02\\x30\\x4c\\xd2\\x4b\\x56\\xf4\\xa1\\x9d\\xf6\\x93\\x49\\x3b\\x52\\x28\\xce\\xc4\\xca\\xdf\\xd7\\xfd\\xab\\xe1\\x93\\xaa\\xb9\\x0b\\xbb\\x90\\x58\\x49\\xa4\\xfb\\xe6\\xda\\x95\\xd0\\x7a\\x3d\\x90\\xde\\x54\\x80\\x3c\\x03\\x12\\xe3\\x4e\\x0b\\xa6\\x57\\x21\\x3f\\xc9\\x53\\x35\\x9c\\xde\\x46\\x61\\x00\\x50\\xdf\\x94\\x2b\\x50\\xed\\x05\\x1d\\x0b\\xf5\\xd3\\xd2\\x9f\\x5c\\xeb\\x58\\x06\\x36\\xd3\\x73\\x85\\x9e\\x68\\xf8\\x39\\x51\\xeb\\x26\\x35\\xb8\\x47\\x02\\x77\\x3c\\x21\\x00\\x7b\\xfb\\x80\\x57\\x42\\x48\\x4d\\x0e\\x02\\xe0\\xec\\x8b\\x80\\x66\\x8f\\x5f\\xb9\\x9c\\x7a\\xba\\x26\\x9e\\xf5\\x40\\x4d\\xd5\\x8a\\x0a\\x5c\\x63\\xdf\\x55\\xf5\\xf6\\x5d\\xcc\\xfb\\x94\\x81\\xf9\\x36\\xdf\\x8e\\xe8\\x86\\xc3\\xe9\\x20\\x02\\xef\\x34\\x94\\x6e\\x03\\x50\\x37\\x0d\\xaa\\x60\\xa3\\xfc\\x6d\\x58\\x43\\x39\\xab\\x47\\xc9\\xed\\x8d\\x64\\xf4\\xfb\\x29\\x92\\x88\\x51\\x13\\x80\\x05\\xe0\\x3c\\xbc\\x4f\\x17\\xa9\\xda\\x63\\x76\\xa7\\x77\\xf1\\xec\\x67\\x48\\xb3\\x2a\\xf7\\x24\\xe2\\x15\\xaf\\x52\\xd5\\x5e\\xdd\\x31\\x75\\xda\\x63\\x61\\xe9\\x67\\x4d\\x22\\xda\\x4b\\xb0\\x83\\x4f\\xae\\x1f\\xc4\\xeb\\xf5\\x4f\\xeb\\x55\\x3d\\x4d\\x0f\\xdb\\x98\\xfb\\xa5\\x4f\\xae\\x3c\\x59\\x64\\xe1\\x57\\xa9\\xfc\\x22\\x56\\x90\\x01\\xb0\\x1b\\x3e\\x03\\x9d\\x0e\\xdb\\xbf\\xa2\\xf3\\x86\\x9a\\x9d\\xe0\\x3a\\x46\\x64\\x22\\x4a\\xc9\\x24\\xae\\x55\\x2a\\x34\\xec\\x07\\x52\\x91\\xb3\\x3f\\x3f\\x1f\\x47\\x64\\x34\\x06\\x72\\x0b\\x06\\xb8\\xcb\\x1e\\x4a\\x06\\x99\\x46\\xcc\\xfb\\xe1\\x43\\xa8\\x26\\x80\\x37\\xd9\\xfc\\x43\\x27\\xeb\\xe8\\x8c\\xac\\x54\\xd9\\xc0\\x3b\\xd4\\xe3\\xf5\\xaf\\xb6\\x96\\x8a\\xba\\x7d\\x6f\\x84\\xfe\\xcd\\xe8\\xd7\\x32\\xc9\\xc5\\x90\\xd8\\xf3\\x51\\x20\\x00\\x54\\xac\\x51\\x6e\\xc6\\x0d\\x70\\x04\\xc3\\x07\\x2f\\x14\\x1a\\x61\\x44\\xd8\\xd4\\xb4\\x7f\\x6a\\x07\\x39\\x5b\\xed\\xaa\\x7c\\xc9\\x45\\x61\\x14\\x4a\\x03\\x20\\x3b\\x7c\\xa1\\x3e\\x89\\x78\\x25\\xf2\\xbc\\x3f\\xa3\\xc0\\x8e\\x1f\\x9f\\x98\\xd1\\x25\\x47\\x8c\\xdd\\x68\\x27\\xcc\\x1c\\x9c\\xdf\\x5e\\x89\\x1b\\x8a\\xff\\xc6\\xb5\\xaf\\xec\\x90\\x07\\x33\\xfd\\x28\\xb8\\xf2\\x77\\x6e\\xfb\\x0a\\xde\\x74\\x6e\\xeb\\x76\\x41\\xca\\x86\\x5e\\xb0\\xe4\\x20\\x9f\\x59\\xff\\x28\\x72\\x82\\x99\\xe8\\x6d\\x22\\xf6\\x2d\\x1f\\x6a\\x3c\\x8a\\xd1\\x49\\xcd\\xaa\\xa0\\x97\\x08\\x70\\x62\\x1f\\xa3\\x5a\\x65\\x6f\\x58\\xb8\\xd7\\x63\\xff\\x89\\xc1\\x0e\\xdb\\xe2\\x81\\x2c\\xce\\xb8\\x4e\\x99\\x12\\x00\\xf6\\x9d\\x83\\x9c\\xfc\\x68\\x55\\xec\\x17\\xd2\\x95\\xf5\\x4f\\xb9\\x6d\\x00\\x43\\xc1\\x35\\xf6\\xb0\\xa2\\xb4\\x6a\\x67\\x6a\\xe4\\xd7\\xb1\\x36\\xc2\\x6c\\xcd\\x13\\xb5\\x11\\x96\\x58\\x19\\x7f\\xf3\\xb4\\xfa\\x4a\\x7e\\xe8\\x9d\\x25\\xa9\\x0d\\x1b\\xc9\\xef\\x83\\xcc\\x62\\xf5\\x07\\xad\\xe4\\x20\\xec\\x17\\x0f\\x1a\\x29\\xc9\\x92\\x0b\\x62\\x9c\\x99\\x31\\x33\\xc8\\xe1\\x8c\\xe1\\x02\\x36\\xe3\\x8b\\x6a\\x5c\\x20\\x3a\\x0d\\x55\\x05\\xfc\\x73\\x9d\\x5f\\xa3\\xbd\\x2f\\xeb\\xfd\\x47\\x13\\x24\\xa3\\xc5\\x79\\xdf\\x80\\xf0\\xdf\\xd0\\xa8\\xa9\\x42\\x31\\xaa\\x63\\x99\\xe5\\x54\\x18\\xde\\x37\\x2e\\xdd\\x80\\x5e\\xd2\\x7c\\xfe\\x44\\x56\\x20\\xae\\xfd\\xcd\\xc6\\xfc\\xa9\\x86\\x4b\\x80\\x83\\xee\\x29\\x5f\\xbf\\x71\\xac\\x5a\\x71\\xbe\\xd0\\x6e\\xa9\\xda\\xef\\xf3\\x72\\x46\\xb1\\x68\\x01\\x78\\xb1\\x17\\xab\\x72\\x8f\\x8b\\x05\\x28\\x42\\xeb\\xf5\\xfe\\xe9\\x42\\x1c\\x21\\x5a\\xfa\\x87\\xa7\\x8b\\xaa\\x4b\\xef\\x90\\xee\\x72\\xf0\\xb1\\x12\\xaa\\xfc\\x7a\\x9f\\x87\\x2d\\xa7\\x54\\xcf\\x5e\\x59\\x2c\\x74\\x61\\x15\\x20\\x06\\xb1\\xe7\\x3b\\xe8\\x53\\xf2\\xb9\\x25\\x96\\x54\\xa0\\x31\\xf9\\xf4\\xb0\\x35\\x4a\\x37\\xd4\\xa1\\x1c\\x3e\\x7d\\xfe\\x30\\x9c\\x12\\xe8\\xc4\\xea\\x6b\\x9f\\x5e\\x16\\xeb\\xbf\\xfa\\x4c\\xee\\xd1\\x1b\\x36\\x0e\\xd5\\x81\\x1d\\xec\\x36\\x1c\\x56\\xb8\\xe5\\x79\\x3e\\x8f\\x1c\\x38\\xcb\\x2f\\xab\\x51\\x89\\x17\\x0a\\xbd\\x41\\x44\\x2d\\xf4\\x5d\\x2c\\x44\\xe9\\xcc\\x95\\xbf\\x41\\xa1\\x0c\\xd5\\xd3\\x3d\\x87\\xfd\\xec\\x7b\\x82\\x89\\xb4\\xdd\\xed\\x9f\\x54\\x41\\x0a\\x22\\xa5\\xb4\\x17\\x2d\\xad\\x7a\\x10\\x97\\xe1\\xc4\\x10\\x80\\x21\\x72\\x62\\x61\\x85\\xf2\\x3d\\x55\\x41\\x25\\x5e\\x6a\\xf5\\x45\\x18\\x1e\\x65\\x67\\xf8\\x7c\\x68\\x99\\xfc\\xef\\xf9\\xe4\\x30\\x67\\x28\\xc6\\x2b\\x62\\x0a\\xf1\\xbb\\x97\\x6f\\x2c\\xca\\x7d\\xc3\\x7d\\x75\\x07\\xc0\\x8a\\x19\\xa6\\xc5\\x7e\\x15\\xcb\\xd9\\x3a\\x45\\xa4\\x17\\x27\\x02\\x8b\\x11\\x00\\xf1\\xc6\\xa7\\x9c\\xf4\\xda\\x8d\\xf1\\x93\\x8b\\x68\\xb0\\x4a\\x7c\\xfe\\x0c\\x67\\x2d\\x2c\\xdf\\xd3\\xe2\\x6e\\xab\\xa2\\x30\\x0c\\xfa\\x4e\\xb6\\xc5\\x1a\\xcd\\x36\\x9c\\xdd\\xe8\\xe7\\x5d\\x94\\xd2\\x84\\xec\\x2b\\x93\\xf5\\x1e\\x02\\x25\\xa7\\x38\\x7f\\xde\\xc9\\x37\\x67\\xf9\\xc7\\x7f\\x3c\\x05\\x0e\\xfd\\xd4\\x6c\\x14\\xc6\\xca\\x33\\x0a\\x9f\\x2c\\xa1\\x5f\\xa5\\x52\\xe2\\x5d\\xda\\x85\\x2d\\xc5\\x82\\xc1\\x31\\x00\\xd3\\x7f\\x82\\xae\\x5d\\x3e\\xbc\\x28\\x4c\\x6c\\x5e\\xeb\\x7e\\x5f\\x8d\\x7c\\x39\\x8f\\x13\\x5f\\x7e\\xc3\\x97\\xf0\\xd9\\x66\\x0c\\xd9\\xec\\x26\\x34\\x78\\x70\\x1d\\x66\\xc8\\xf2\\x9f\\x32\\x88\\x10\\x16\\x2a\\x4a\\x1a\\xef\\xe0\\xe8\\x4f\\x16\\xe4\\xcd\\xf5\\xfd\\x53\\x3b\\x2e\\xa1\\xe0\\x38\\xe6\\x86\\x9c\\xfe\\x72\\x25\\xd9\\x6d\\xad\\xfe\\xae\\x0c\\x02\\x52\\xba\\xfa\\x15\\xfe\\xf6\\x19\\x78\\x0e\\xa7\\x34\\x36\\xe6\\x9f\\x4b\\xcc\\x9f\\x68\\xaa\\x24\\x32\\xc6\\xc0\\x89\\x62\\x11\\x15\\xe1\\x61\\x75\\x5b\\x64\\x61\\x97\\xf8\\x36\\x4d\\x68\\xca\\x9b\\x85\\x99\\x68\\x0b\\x60\\x59\\xaf\\x7d\\xca\\xe5\\xbb\\xcf\\x66\\xfa\\xa5\\x70\\xbc\\x9c\\x72\\x53\\xaa\\x30\\x00\\x45\\x9b\\x1c\\x99\\xe8\\xd9\\x76\\x13\\x83\\x3b\\x2e\\xd1\\x91\\x93\\x8a\\x20\\x8a\\x14\\x4d\\xfd\\x20\\x33\\x7c\\xe9\\x5d\\xbe\\x87\\x4b\\xbd\\xa5\\xc6\\x18\\x24\\x36\\xe9\\x65\\xcb\\x24\\xcc\\x57\\xf2\\xab\\xdd\\xe2\\x42\\xfe\\x9c\\x2c\\xfd\\xb4\\x95\\xb6\\x27\\x00\\xc9\\xe6\\xd4\\xa5\\x12\\x75\\x8b\\x60\\x30\\xa3\\x01\\x47\\xba\\x2f\\xf6\\xa8\\x53\\x7c\\x7f\\x09\\xdd\\x52\\xb7\\x27\\x10\\x2a\\x83\\x7f\\x83\\xf5\\x3a\\xa5\\x4e\\x0f\\xda\\x9c\\x52\\x68\\x02\\x92\\xf4\\x4f\\xa2\\x6d\\x76\\x20\\xd1\\x7b\\xbc\\x67\\xf8\\xd4\\x92\\xe5\\x57\\xe5\\x1e\\x74\\x6a\\xf4\\x67\\x78\\xbf\\x5b\\x40\\x22\\xda\\xf6\\xe9\\x0d\\x93\\xce\\x83\\x79\\xd9\\x6f\\xf5\\x94\\xd4\\xb0\\x97\\x58\\x4e\\xf8\\x95\\xdf\\xaa\\x57\\x06\\xb4\\xcd\\x7e\\xa6\\xad\\xe2\\x61\\xa9\\x8f\\x41\\xc1\\x64\\x7d\\x01\\xa4\\x9d\\x54\\x05\\x4b\\x3a\\xcf\\xd7\\x1a\\x07\\x0e\\x24\\x20\\xfb\\xe6\\x9e\\xac\\x99\\x68\\x2d\\xbd\\xbb\\x14\\xb7\\xf8\\xfb\\x0d\\xc9\\x23\\xe2\\x44\\xab\\x39\\x9d\\xc0\\x94\\xd3\\xed\\x0e\\x92\\xc0\\x05\\x08\\xab\\xdc\\x37\\x0b\\xd4\\xfb\\x55\\xc6\\xa4\\xad\\x01\\x20\\xab\\xa4\\x09\\x20\\xf8\\xf2\\x98\\x66\\x3b\\xd0\\xa8\\x8f\\xca\\xbd\\x0c\\x78\\x5e\\x6c\\x2d\\xca\\x3a\\xe2\\xbe\\x9f\\xfd\\x3f\\x58\\xe8\\x59\\xc0\\xed\\x6b\\x18\\xb5\\x78\\xa3\\x8d\\x47\\xb2\\x5c\\x9a\\x11\\x84\\xd0\\x2a\\x44\\xdd\\xd1\\x51\\xe6\\x12\\x8e\\x82\\x6c\\x10\\x20\\xf6\\x5a\\x2d\\xea\\xeb\\x58\\x62\\x2d\\xd7\\x7b\\x93\\x36\\x4c\\xf0\\xbe\\x82\\x4e\\xaa\\x9e\\x5c\\xb7\\x51\\x88\\xd6\\x84\\xb2\\xad\\xe4\\x2f\\x8e\\x37\\xf1\\x71\\x8f\\xee\\xd5\\xf7\\x09\\xe4\\xa3\\x9c\\x45\\x2e\\x10\\x60\\xc5\\xdc\\xc4\\x9d\\x85\\x27\\x19\\xbd\\xeb\\xc0\\xa7\\x0a\\xf1\\x75\\xec\\x77\\x36\\x63\\x7b\\xd5\\x7e\\xb2\\xb0\\x89\\x78\\xe2\\x63\\x70\\xa0\\xe7\\xc5\\xfa\\x2f\\x1f\\xe0\\x9e\\x8c\\x48\\xeb\\x17\\xb5\\xa9\\x51\\x6d\\x0f\\xa3\\xec\\xf4\\xe7\\x44\\x04\\x74\\x1f\\xe4\\x59\\x96\\xe5\\xb2\\x7f\\xab\\xac\\x61\\xdc\\x0c\\x01\\x30\\x7d\\xfa\\xce\\x46\\x7f\\x6f\\x44\\x84\\xa4\\x7a\\xe3\\xe6\\x3a\\xad\\x97\\x03\\x96\\x35\\xd3\\xdb\\x1a\\x25\\x0b\\x45\\xcd\\xcd\\xe5\\x47\\xd9\\x91\\x1d\\x08\\xe2\\x38\\x06\\xe0\\x33\\x83\\x5e\\xcb\\x01\\xd6\\xc5\\x82\\xa9\\x4e\\xdf\\x11\\xb0\\x9b\\x9e\\xeb\\x12\\xa6\\x37\\x51\\x7a\\x31\\x98\\x8f\\x3a\\x22\\xe9\\x4a\\xf9\\xf6\\x6a\\x41\\xbb\\x3e\\xe6\\xd2\\xfb\\x57\\x77\\xde\\x59\\x12\\xdf\\x56\\x41\\xa3\\xe8\\xef\\x50\\xb5\\x9a\\xfb\\x1b\\xd5\\x99\\xe8\\xe7\\xfb\\x1d\\x24\\xf1\\x9e\\x82\\x32\\x03\\x8c\\xd4\\x00\\x63\\x25\\x32\\xac\\x0a\\x41\\x66\\xd1\\x3e\\x0d\\x01\\x02\\x53\\xf0\\xf6\\x6f\\x56\\x80\\x1b\\x6b\\x0f\\xc1\\xed\\x60\\x1f\\xcb\\xdc\\xa8\\xef\\x64\\xf6\\x17\\xc8\\x21\\xcc\\xfb\\xea\\x8e\\x31\\xcd\\x32\\x72\\xf0\\xad\\xcd\\x64\\x60\\x92\\xfc\\x22\\x17\\x39\\x91\\x76\\x2f\\x2d\\x02\\x9d\\x63\\x37\\x5f\\x97\\x5b\\x8a\\xff\\x36\\x32\\xe7\\x46\\x9b\\x93\\xa0\\xb6\\xb4\\x91\\x19\\x6a\\x89\\x95\\xfa\\x9b\\x83\\xd1\\xc5\\x7e\\x97\\x2f\\x53\\x4a\\x06\\x3a\\x68\\xa5\\xa3\\x39\\x06\\x37\\x0f\\x4d\\xa5\\x4f\\xe7\\x1d\\x30\\xf5\\x0a\\x24\\x80\\x94\\xb7\\x02\\x49\\x7a\\xcb\\x56\\xc5\\x22\\xaa\\x99\\x02\\x5c\\x79\\xd0\\x4a\\xa2\\x9a\\x72\\xd2\\xca\\xd6\\xf5\\x41\\xad\\x21\\x3e\\x94\\xcf\\xc5\\xa0\\x70\\x37\\xb3\\xdb\\xcd\\x37\\x82\\xc9\\xf7\\xdb\\xce\\x1b\\xa3\\x71\\x9b\\x4c\\xa8\\x49\\x81\\x02\\xac\\xdf\\x70\\x89\\x7a\\xb0\\xe2\\x5b\\x97\\x67\\x2c\\x9b\\xdf\\xe5\\xe3\\x4b\\x99\\x8c\\x19\\xcc\\xf1\\x99\\x7e\\xbb\\x7f\\x75\\xcb\\x5e\\x28\\x02\\x68\\x72\\xe5\\x37\\xf0\\x2c\\x49\\x42\\xe9\\x2c\\x17\\xa7\\x9d\\xa9\\x57\\x74\\x72\\x01\\x92\\xe5\\xfb\\x45\\x34\\x3a\\x62\\x50\\x10\\xc1\\x28\\x12\\xec\\xdd\\xc3\\xe3\\x10\\xbb\\xa1\\xd4\\x2a\\x96\\x53\\xcd\\x7e\\x0f\\xce\\xda\\xb8\\xd3\\x6a\\x0f\\x88\\xd1\\x32\\xa7\\xda\\x90\\x89\\x41\\x30\\x98\\x0f\\x6e\\x2e\\x07\\x88\\x41\\x4d\\x41\\x87\\x7b\\xe3\\xad\\x8f\\x18\\x00\\x08\\xb1\\x7b\\xaf\\xeb\\xb9\\x38\\x06\\xd5\\xd5\\xf3\\x78\\x9e\\xdb\\xb8\\xf3\\x7b\\x46\\xfb\\xa6\\x6e\\xa3\\xe0\\xae\\x8b\\xf6\\x64\\x18\\xeb\\x1f\\x50\\xf3\\x93\\x12\\x0d\\xef\\x15\\xb6\\x42\\x2b\\xf4\\x31\\x89\\xa6\\x93\\xae\\xc1\\xc3\\x8e\\x72\\x79\\x57\\xb0\\xfe\\x66\\x21\\x80\\xe3\\x97\\x5d\\x43\\x14\\xc9\\xf3\\x91\\x21\\x08\\xf4\\x2a\\xa4\\xe8\\xfb\\x12\\x3e\\xe5\\xae\\x35\\xcb\\x51\\xa8\\x87\\x41\\x89\\x94\\xd2\\xd0\\xef\\x07\\xe9\\xea\\x42\\x0d\\x4f\\xe8\\xb2\\xac\\x7a\\x1b\\x37\\x66\\x41\\x30\\xc6\\xdb\\x6c\\x91\\xf1\\xcb\\x78\\x32\\x46\\x0a\\x00\\x22\\x20\\xf3\\x44\\x17\\x52\\x7b\\xf8\\x29\\x9e\\x1a\\x31\\x01\\xad\\x36\\x33\\x07\\x65\\xd1\\x30\\x79\\x66\\x78\\xd6\\xfb\\xaf\\x67\\xcd\\xad\\xc9\\xce\\x6d\\xc5\\x77\\xa5\\x87\\xe4\\x82\\x48\\xbe\\xef\\xfb\\x34\\x54\\x7c\\xa4\\xf5\\xb2\\x3c\\xcb\\x02\\xdf\\x00\\x08\\xb5\\x13\\x99\\xd9\\xdf\\x23\\xc5\\xb6\\x7b\\x8e\\xc8\\x71\\xcc\\x7c\\xe9\\x42\\xf2\\xcd\\xa8\\x78\\xa7\\x68\\x34\\xbb\\x51\\x73\\xb5\\xfc\\x6d\\xd0\\xe2\\xa2\\xbf\\xfa\\x91\\x4e\\x62\\xbe\\x9c\\x36\\x3a\\x82\\x81\\x22\\x05\\x7b\\xbe\\xf1\\x8a\\x60\\xa2\\x69\\x5e\\x11\\x2a\\xe5\\x4b\\x90\\x61\\xf6\\x1c\\x04\\xab\\x71\\x95\\xae\\xe6\\x86\\xfe\\x15\\xdd\\x4c\\xa6\\x18\\x19\\xbd\\x2c\\x3d\\x12\\x16\\x9f\\xc4\\xf8\\x3b\\xbb\\x56\\x1f\\x8b\\xed\\x60\\xda\\x65\\x5f\\x95\\x6e\\x51\\x3a\\x1b\\x6d\\x5b\\x0f\\xdd\\x0e\\x8b\\x72\\x40\\x91\\x00\\x80\\x37\\x00\\x27\\xe2\\x5e\\x48\\xd4\\x4d\\xc6\\x0f\\xca\\x42\\xb4\\xd9\\x27\\x12\\x52\\x10\\x79\\xac\\xfc\\x8c\\xb1\\xb7\\x7d\\x41\\x0f\\xd0\\x1a\\x1b\\xfd\\x50\\xe1\\x43\\x60\\x7e\\xea\\x83\\xcb\\x72\\xe3\\x46\\x24\\xae\\xa5\\x85\\xe7\\x91\\x40\\x04\\xa9\\x0d\\x0c\\xe6\\x3e\\xb2\\x81\\x96\\x65\\xf1\\x35\\x27\\x98\\x94\\xf0\\xb1\\xaa\\x98\\x22\\x64\\x76\\x09\\x2a\\xbd\\x72\\x9a\\xba\\x4e\\x9b\\xd2\\x1f\\x26\\xff\\xb7\\xcf\\xdb\\xbd\\xbc\\x98\\xb0\\x98\\x3e\\x79\\x87\\xf5\\xf8\\xa6\\x7b\\x07\\x44\\xd6\\xee\\x32\\x3b\\x92\\x1b\\x7d\\x08\\x52\\x22\\x65\\x18\\x0c\\xeb\\x92\\x0c\\x60\\xe6\\x1e\\xd3\\x70\\xb7\\xa8\\x29\\xec\\xf2\\xde\\x17\\xc0\\x5d\\x64\\x10\\x42\\x75\\x7e\\xe2\\x75\\x0b\\xba\\x74\\xde\\xf6\\xd4\\x43\\x2e\\x83\\xb5\\x22\\x9b\\x57\\x70\\xe9\\x0e\\x70\\x77\\x7f\\x47\\xe1\\x48\\xf4\\xde\\x44\\x78\\x37\\x00\\x6e\\x48\\x01\\x8a\\x84\\x2a\\x02\\x58\\x5c\\xa2\\xa6\\xa8\\xb3\\xef\\x9b\\xbd\\xe4\\xd6\\x1e\\x0f\\xe5\\x5c\\xdb\\x66\\x3f\\xf8\\xe6\\x60\\x2b\\x48\\xc2\\x01\\x72\\xe1\\x6f\\x8d\\x79\\x86\\xdd\\x1c\\x2b\\xc8\\x52\\x60\\x0e\\x79\\x5f\\xa2\\x17\\xfa\\x2e\\x4c\\x93\\x62\\x64\\x3a\\x6a\\x8b\\x84\\xf5\\x06\\x24\\xc3\\x19\\x46\\xc6\\x1d\\x59\\x0f\\x4d\\x3b\\x8d\\xe7\\xa9\\x09\\x92\\x2c\\xdf\\x09\\x17\\x3b\\x24\\xe2\\x63\\x3b\\x84\\x56\\xb5\\x59\\x81\\xf6\\x4e\\xfe\\xb9\\xde\\x05\\x86\\x44\\x1d\\x9e\\x80\\xaf\\x49\\x1b\\x14\\x92\\x1a\\x46\\xee\\xfb\\x3d\\x80\\x2f\\x93\\xd8\\x18\\x9b\\x1c\\x4f\\xfd\\x79\\x01\\x64\\x73\\x76\\x03\\x10\\xe4\\x08\\x46\\x16\\xd8\\x9d\\x1d\\x0b\\x23\\x9d\\x95\\x5f\\xa3\\xba\\xd4\\x5a\\x64\\xdc\\xc8\\x4b\\x10\\x6c\\x65\\x77\\x26\\xb0\\xc6\\xc3\\xfe\\x57\\xe3\\x7a\\x6b\\xba\\xee\\x40\\xcf\\x52\\x3b\\xa9\\x1c\\x4e\\x0b\\x50\\x41\\xb7\\xcf\\xc2\\x07\\x96\\x59\\x3f\\xd3\\x53\\x08\\x10\\x46\\x17\\x56\\x0e\\x61\\xf2\\x15\\x43\\xac\\xf1\\xd3\\x81\\x7b\\xf0\\x3b\\xaa\\x83\\x90\\x25\\x9b\\x3f\\xbd\\x15\\x3f\\xc4\\xd3\\x47\\x8c\\xcb\\x4a\\x4b\\x2d\\x6e\\x7c\\xf0\\xef\\x30\\xf6\\xce\\xf3\\xeb\\x89\\xec\\x2b\\xda\\xef\\x5a\\x70\\xe9\\x6a\\x9c\\xfc\\x76\\x40\\x48\\x03\\x80\\x09\\x00\\x6c\\x05\\xb9\\x81\\x2c\\x7e\\x62\\x4f\\xe9\\xcc\\x00\\x1c\\xef\\x09\\x82\\x30\\x36\\x81\\x00\\x6c\\xf9\\x16\\xa0\\x4b\\xd6\\x58\\x36\\x83\\xbc\\x3a\\x83\\x5d\\xc6\\xa6\\xa7\\x35\\x79\\x72\\x15\\xba\\x58\\x64\\x4f\\x99\\x9d\\xa2\\x87\\x68\\xa1\\x8b\\xf2\\x8f\\x3e\\xe4\\x26\\xa9\\xcb\\xd4\\x72\\x59\\xac\\x86\\xd1\\x02\\x92\\xb8\\xfb\\xf1\\xdd\\x34\\x30\\x1d\\x63\\x1c\\x00\\x04\\x81\\x2c\\x05\\x33\\x70\\xcd\\xf7\\x5a\\xaf\\x0b\\x11\\xa7\\x93\\xd3\\x49\\x26\\xda\\xfa\\xc0\\x24\\xfd\\x47\\x62\\xf4\\xe6\\x40\\x61\\x0b\\x13\\x02\\x3e\\x70\\xb8\\x4f\\x0a\\x3f\\x1f\\x85\\x62\\x2c\\xb4\\xfe\\x7c\\x2a\\xad\\xca\\xe5\\xe8\\x63\\xe1\\x0f\\x65\\xd7\\xb4\\xfa\\x71\\xa8\\x46\\xee\\xb3\\x7e\\xc1\\xce\\x0c\\x73\\x5d\\x03\\xe3\\xfb\\x10\\x39\\x92\\x4c\\xf7\\x3c\\x26\\x58\\xfc\\x38\\x54\\x07\\xa6\\x8f\\x40\\xb2\\xa7\\xbe\\x8b\\x31\\xe9\\x06\\xa9\\x80\\xcd\\xf4\\x26\\xe4\\x4d\\xf2\\x53\\xdf\\xed\\x45\\x65\\xb3\\x5c\\x0d\\x8e\\x12\\xf0\\x03\\x7c\\x93\\x5a\\x4d\\x6e\\x38\\xf1\\xa8\\x0c\\x3e\\x78\\x20\\x5c\\xfd\\xdf\\x9c\\x49\\xb1\\xf5\\x63\\xea\\x4d\\x8f\\x2f\\x03\\x17\\x4b\\x89\\x9c\\x81\\xab\\x8b\\x20\\xb9\\x96\\x03\\x0d\\xe6\\x40\\x50\\x90\\xa2\\x70\\x95\\xf6\\x22\\x57\\xf9\\x02\\xc6\\x9d\\x60\\x92\\xed\\xec\\xcc\\x57\\xf8\\x92\\x7a\\x3d\\x47\\x78\\x2a\\x98\\x84\\x66\\x26\\xbe\\x8b\\x61\\xe3\\x1e\\xaa\\x07\\x87\\xbf\\x59\\x76\\xa4\\x73\\x6d\\xb6\\x3c\\x8b\\x5e\\x65\\x59\\x0f\\x6e\\xf7\\xc3\\xde\\x7e\\x4e\\xfc\\xa0\\x01\\x28\\xbc\\x8c\\x93\\x31\\x08\\x26\\xce\\x89\\x7d\\xc7\\x70\\xff\\x73\\x27\\x68\\xe7\\x2b\\x6d\\x75\\xa6\\x5e\\x6b\\x3a\\xad\\x84\\xa7\\x9f\\xbc\\xef\\x5b\\xa4\\xff\\x1f\\x9f\\x58\\xe7\\x08\\x5f\\xe8\\x44\\x77\\x35\\xb8\\x35\\xf3\\x49\\xa4\\xd1\\x8b\\x40\\xc3\\x4e\\x42\\xe7\\x4c\\xb3\\xd9\\xfb\\x00\\xd4\\x59\\x89\\xeb\\x5f\\x8d\\xe4\\x61\\xe1\\x64\\x2e\\x44\\x12\\x6c\\x2d\\xb1\\x12\\x4b\\x0b\\x50\\x06\\x8d\\x18\\x23\\x02\\xc6\\x35\\x9f\\x63\\x6f\\x5c\\x62\\x7e\\x5c\\x80\\xa6\\x1a\\x74\\x3b\\xae\\xee\\xc7\\x72\\xd4\\x64\\x1a\\xdc\\x6e\\x5f\\xd2\\x71\\x5d\\xaf\\x32\\x6c\\x8a\\xbc\\x10\\xec\\x37\\x34\\xbc\\xeb\\xf0\\x42\\x13\\xbe\\xe5\\x44\\xb1\\x90\\xfa\\xa5\\x99\\x13\\xe1\\xd3\\x94\\x9b\\xb1\\x06\\x81\\x64\\x5a\\x7f\\xb2\\xf9\\x07\\x66\\x20\\xdf\\x70\\x66\\x27\\xd8\\x9d\\x45\\x3b\\xe7\\xe4\\x07\\xec\\xb3\\xab\\x4a\\x99\\x2a\\xe3\\xcf\\xf9\\xbd\\xcf\\x77\\xfa\\xe8\\xa7\\x57\\xed\\xba\\xa1\\xe0\\xef\\x6a\\x62\\xdf\\x4f\\x5d\\xfe\\xfe\\x87\\xe3\\x49\\x4e\\x9f\\xe5\\xda\\x59\\xa8\\xaf\\x12\\xb9\\x7c\\x95\\xfa\\x1a\\xcd\\xb4\\xa5\\xd8\\x56\\xb1\\x6e\\xb5\\xb8\\xe5\\x2b\\xbc\\x04\\x0c\\x02\\x67\\xee\\x45\\x56\\x59\\x14\\xf3\\xed\\xe7\\x4f\\xa8\\x0e\\x67\\xb5\\xba\\xd3\\xea\\x76\\x8b\\xa8\\xf8\\x65\\xb8\\x55\\xb3\\x43\\xef\\x8a\\x4a\\xba\\x8d\\x52\\x28\\xe0\\xcc\\xdf\\xff\\xcb\\x55\\xc7\\xeb\\x96\\x04\\xa1\\x09\\x38\\x61\\xfe\\x28\\x77\\xd7\\x04\\xdd\\x1e\\xd6\\x22\\x62\\xc8\\xee\\xf6\\x20\\xd7\\x0d\\x2d\\x23\\x6c\\xca\\xf9\\x2b\\x81\\x66\\xe7\\xf8\\xa1\\x43\\x09\\x54\\xc2\\xfe\\xe0\\xe6\\xdf\\x99\\x29\\xff\\xf2\\x24\\xa1\\xbf\\x93\\x10\\xd3\\x47\\xe4\\xc6\\xec\\xe6\\x54\\x2d\\xfd\\x7a\\xc1\\x87\\xf1\\x81\\x07\\x35\\xaf\\xee\\xe4\\x5a\\x95\\x1b\\x79\\xa7\\x99\\xb3\\x2f\\x49\\xe5\\xbe\\x0b\\xa2\\x7f\\x22\\x9f\\xd2\\x7d\\xfd\\xe5\\xf3\\xe6\\xdf\\xbd\\xc8\\x70\\x5f\\xea\\xd1\\x9d\\x3d\\xe1\\x9a\\xdc\\x9b\\xcd\\xa5\\xd7\\x8e\\xd6\\x4f\\xdd\\x78\\x7d\\x5f\\xed\\x18\\x74\\xf2\\x0b\\x66\\xed\\x6d\\x4f\\xa9\\xcd\\x06\\x89\\x4c\\x0b\\xd6\\x25\\xcc\\xdd\\xe2\\x8e\\x9f\\xc7\\x77\\xe3\\x40\\x27\\xbf\\x3f\\x7f\\xb1\\x33\\xea\\x15\\x68\\x52\\xd0\\x7d\\xeb\\x67\\x24\\x47\\xad\\xa7\\x3e\\xb6\\x68\\x4e\\x70\\xba\\xfe\\xd6\\x56\\xf5\\x9b\\xca\\x96\\xad\\xde\\xdc\\x1a\\xf5\\x39\\x8c\\x59\\xfb\\x5d\\xad\\xca\\xec\\xf1\\xcf\\xa7\\x52\\x05\\xbd\\xf3\\x3f\\x9f\\x2e\\x3e\\x94\\x44\\x04\\x20\\x49\\xe8\\x46\\x64\\x08\\x4b\\x3f\\xb3\\x6b\\xb0\\x7d\\x50\\x39\\x85\\xc1\\xea\\x4e\\x24\\x8b\\xb9\\x6f\\x5c\\x50\\xe6\\x64\\x6e\\xc3\\x1e\\x50\\x21\\x7b\\xd1\\xed\\x87\\xb9\\x96\\x09\\xdd\\x6a\\xac\\xe6\\xc6\\xf7\\x33\\xfe\\xc5\\xad\\x6b\\x0d\\xad\\x6b\\x3e\\x38\\x27\\x6b\\xec\\x61\\xc5\\xb6\\x65\\x91\\x8b\\x38\\xba\\x1e\\x14\\x89\\x28\\x6f\\xad\\xbb\\xa9\\x41\\xc7\\x16\\x5b\\xdc\\xb3\\x07\\xc1\\x9c\\x97\\x70\\xe5\\xec\\xfd\\xfd\\x3b\\xc7\\x65\\xd4\\x1a\\x29\\xb9\\x6c\\x5f\\xd6\\x6c\\xc6\\xbc\\x29\\x84\\x3f\\xe4\\xf8\\x93\\x8f\\x58\\xee\\x98\\x2f\\x8c\\xb2\\xf6\\xea\\xfb\\xac\\x29\\xac\\xbc\\xbf\\x79\\x55\\x94\\xf9\\x91\\x0b\\xa0\\x30\\xb2\\x7f\\xf3\\xbb\\x5a\\xd6\\x68\\x52\\x30\\x7d\\x6b\\x99\\xed\\x8c\\xa5\\xca\\xa9\\xab\\xb9\\x3e\\x11\\x57\\x6d\\x3a\\x65\\x6d\\x50\\x85\\xe5\\x52\\x12\\x6b\\xce\\xaf\\x03\\xeb\\x6f\\xd0\\xf6\\xb7\\xb5\\x42\\x35\\xfc\\x30\\xc7\\x73\\xd0\\x9f\\x56\\x90\\x1d\\xbf\\xfa\\x65\\x45\\x6b\\x50\\x75\\x89\\xb2\\xb8\\x80\\xc2\\xe4\\xed\\x2e\\x8b\\x34\\x08\\x69\\x64\\x83\\x70\\xd6\\x86\\x33\\xed\\x73\\x81\\xd8\\xc6\\x4b\\x69\\x48\\xfa\\xa4\\x8c\\xdb\\xc1\\x0d\\xf9\\xeb\\xed\\x12\\x1d\\x4b\\xc7\\xff\\xab\\x87\\x21\\x24\\x11\\xa6\\xf5\\x29\\x27\\x10\\x4c\\x95\\x93\\x8c\\x8d\\xbb\\xdf\\x2f\\x4d\\x8b\\xd7\\x74\\xe8\\xbd\\xcf\\x98\\x2b\\x67\\xfa\\x7d\\x4b\\x21\\xa6\\x7f\\xce\\xb7\\xf9\\x76\\xe5\\xb9\\x02\\x44\\xfd\\x5f\\x0e\\xd0\\x76\\x96\\x9e\\x3d\\x2d\\xe3\\x85\\x6b\\x55\\xb0\\x9a\\x53\\x3e\\x30\\xb8\\x11\\x1a\\xd2\\xc8\\x1f\\x4f\\x61\\x80\\xc2\\x61\\x68\\xae\\xa9\\xd6\\x82\\x1d\\xbf\\x3b\\xac\\xcb\\x0f\\xc5\\xaf\\x29\\x97\\xca\\xff\\xac\\x47\\xba\\x2c\\xc7\\xe8\\xc5\\x3f\\xdf\\x33\\xc9\\xd5\\xb0\\x7d\\x93\\xbb\\x16\\x6a\\xc7\\x08\\x69\\xd7\\x9a\\xdc\\x97\\xfa\\xf1\\x58\\xb1\\xb9\\x3b\\xca\\x59\\x0f\\xfd\\x73\\xbc\\xb4\\xc2\\x3b\\xd9\\x4b\\x65\\x5b\\xd5\\xfe\\xb0\\x39\\xcd\\xa9\\xd3\\x76\\x2f\\x15\\xb3\\x4d\\x72\\x3d\\x50\\x25\\xf1\\xfa\\x6f\\x1e\\xb9\\x05\\x13\\xf5\\x45\\x5d\\x42\\x65\\xb1\\x0b\\xe5\\xe8\\x9a\\x6f\\x66\\x9f\\x96\\x51\\x4e\\x06\\x4f\\xe4\\x0b\\x84\\x19\\x4b\\x6f\\x17\\x43\\xe7\\x33\\x1f\\x60\\x1b\\x27\\x4f\\x5e\\xb8\\xa9\\xe9\\x7d\\xcd\\x44\\xd3\\x8f\\x8a\\xb0\\xdf\\xcf\\xfe\\x6f\\x1c\\x0d\\x9b\\xaf\\x9d\\x08\\x86\\x93\\x8b\\x58\\x84\\xdc\\x23\\xb8\\xdf\\xf3\\x2e\\x50\\x48\\xd6\\x97\\xd1\\xa1\\x9e\\xb4\\x41\\x09\\x5f\\xda\\xcb\\xb9\\xa7\\x74\\x3b\\x98\\x9d\\xbf\\x23\\xc6\\x90\\xb7\\x2c\\x8f\\x8c\\x2f\\xfe\\x1f\\x6c\\x1b\\x4c\\x7a\\x63\\x3b\\xf9\\x0a\\xdb\\xa5\\x6a\\xe1\\x15\\x76\\x01\\xcf\\x22\\x54\\xcc\\x9b\\xbd\\xbc\\x12\\xa6\\x5c\\xc8\\x4e\\x1b\\x76\\xef\\xb0\\x0b\\x9b\\xc5\\xb1\\x21\\xea\\xe6\\x0d\\x16\\x53\\x9b\\x15\\xe3\\xed\\xa8\\x3d\\xa7\\x1a\\x4d\\x2a\\xf6\\x8b\\xd5\\xff\\xfd\\x3e\\xa5\\x76\\xbd\\xd1\\x55\\x44\\xed\\xcf\\x33\\xba\\xf0\\x7b\\x28\\x87\\xe0\\xa3\\x5b\\x3f\\x16\\xb6\\x76\\xe2\\x98\\xed\\xb0\\x83\\xf7\\x7e\\x3a\\x6e\\x1b\\x5a\\xc9\\xfd\\x9a\\x31\\x36\\x9c\\x8d\\x0f\\xce\\x69\\x38\\x62\\xc6\\x5e\\x15\\xd9\\x56\\x42\\x11\\xaf\\xed\\x19\\xfd\\xea\\x5e\\xf8\\x50\\x9a\\xa0\\x2f\\x67\\x89\\x2d\\x9f\\xaa\\xf5\\x26\\xc7\\x34\\xf9\\x72\\xcc\\x16\\x81\\xe6\\x83\\x04\\xb3\\x2f\\xaa\\x8a\\x85\\x6c\\xf5\\x4b\\xaa\\xd2\\x90\\xa5\\x4f\\xaa\\x07\\x1a\\xbd\\x87\\xea\\xa5\\x54\\xf8\\xdd\\x45\\x19\\xfb\\xed\\xfe\\xfd\\xfb\\xf0\\x50\\xbd\\x11\\xe5\\x19\\xb5\\x5f\\xf6\\x5c\\x08\\xed\\x12\\x2b\\xb1\\xea\\x84\\x24\\xef\\x6a\\x08\\x8a\\x4c\\xc4\\x5e\\xd2\\x66\\x54\\x0c\\xd7\\x51\\x17\\x12\\xdc\\xd7\\x8c\\x0d\\xb1\\x85\\xae\\x52\\x15\\xf0\\xbc\\x3b\\x77\\x12\\x9d\\xa5\\x73\\x9f\\x2c\\x05\\xea\\xcf\\xe0\\xcb\\x3d\\x87\\xc7\\xfc\\xbb\\x23\\xaf\\x5e\\x59\\xff\\x86\\xde\\xaa\\xb5\\x4b\\x3c\\xa7\\x31\\x9e\\xad\\xee\\x04\\x9d\\x76\\x8c\\x7c\\x75\\xa3\\xe1\\xa0\\x49\\xb3\\xa5\\x6e\\x3e\\x13\\xc5\\x9f\\xe8\\xcc\\x2e\\xe3\\xf4\\x24\\x73\\x17\\xe3\\x8b\\xed\\x45\\x6f\\xaa\\x00\\xe3\\xb9\\x6f\\x33\\x2a\\xf6\\xcc\\xe6\\x48\\x7d\\xf9\\xd5\\x78\\x3f\\x3b\\xe5\\x6a\\x4e\\x27\\x61\\xca\\x73\\x89\\x85\\x4f\\x0c\\x1b\\xb2\\x11\\x73\\xb9\\x2a\\x86\\x37\\xff\\x06\\x60\\xad\\x83\\x4e\\xaa\\xe1\\xdb\\x13\\x9e\\x2d\\xe5\\xb9\\x53\\xea\\xbf\\x4d\\x86\\x66\\x0a\\xf7\\x3b\\xe4\\x87\\x1a\\xf2\\x94\\x8b\\x1d\\x56\\xd2\\x49\\x35\\xb7\\xbf\\x9f\\x0d\\xf1\\x77\\x56\\xc0\\xbc\\x9c\\x5e\\x62\\x1b\\xaa\\x57\\xaf\\xf3\\x6e\\xd2\\x68\\xed\\x8f\\x90\\x45\\xc8\\xd9\\x3a\\xdc\\x61\\x5c\\xf2\\x7a\\x09\\x26\\x3a\\xc7\\xae\\xf7\\xd3\\x84\\xa3\\xf6\\xa2\\x82\\x45\\x7c\\x61\\xf4\\xac\\xc6\\x17\\xa7\\xb4\\x18\\xb8\\x83\\x4d\\xbe\\x67\\x79\\x6c\\x85\\xfd\\x2d\\x2d\\xbf\\x7c\\x52\\xeb\\x6c\\x3d\\x2f\\x02\\xde\\xc4\\x4c\\x20\\x29\\xca\\xb5\\x6c\\x9a\\xe3\\x7e\\xd4\\xdd\\x81\\x8e\\xdb\\x06\\x93\\xbf\\x18\\x03\\x2e\\x15\\x4d\\x96\\xf8\\xcb\\x0d\\x6b\\xb2\\x7b\\x99\\xd2\\xd5\\x00\\x7b\\x6a\\xbd\\xc5\\x0d\\x81\\xf8\\x67\\xf7\\x4f\\x3d\\x9d\\x5d\\xbc\\xcb\\x20\\x6f\\xb7\\xf1\\xf9\\x36\\xdf\\x56\\xd4\\xde\\xd8\\x22\\xcc\\xc3\\xaf\\x81\\xdb\\x91\\xfd\\xc4\\x4f\\xc8\\x9b\\x4d\\x2c\\x6a\\xda\\x5d\\xa0\\xb3\\x51\\xb4\\xd1\\x6d\\x45\\x1f\\x6b\\xf3\\x54\\xe0\\xde\\xe1\\xfd\\x8d\\x3e\\x17\\x15\\x8d\\x42\\x11\\x1e\\x87\\xb8\\x4c\\x03\\xa8\\x59\\xa7\\xaa\\x07\\x5a\\x97\\x5b\\xe6\\x33\\x41\\x6f\\xf2\\x26\\x94\\x15\\xd9\\xa6\\xe7\\x50\\xe5\\xc9\\x46\\x18\\xd3\\x11\\xf7\\xfb\\x15\\x0e\\x9f\\xdf\\xdf\\x21\\xd1\\xcd\\x28\\xc7\\xb2\\xa6\\xd9\\x5f\\x52\\x52\\xc5\\x96\\x60\\x9e\\xc8\\x03\\xa8\\x48\\x8a\\xef\\xfe\\x69\\x12\\xb9\\x5a\\x3c\\x1e\\xe2\\xe3\\x29\\x99\\xef\\x8f\\x33\\xa7\\xda\\xa0\\x89\\x93\\xaf\\xda\\x05\\x2a\\x09\\xb2\\x5f\\x16\\x96\\xc8\\x9c\\x89\\xa3\\xa0\\xa5\\x66\\x7b\\xfe\\xe7\\x5e\\x09\\x9a\\xcb\\x16\\x77\\x46\\x79\\x4b\\xe2\\x7a\\xa2\\x66\\x77\\xea\\x59\\x08\\x2a\\xf7\\x1b\\xc7\\x4f\\x5d\\xad\\x15\\x2b\\x34\\xd7\\x39\\x12\\x6a\\x91\\x04\\xef\\x21\\x5f\\xda\\x19\\x9b\\xc8\\x93\\x7f\\x9c\\x2a\\x30\\xcf\\x15\\x57\\x4a\\xb3\\xe4\\x14\\xfa\\x79\\x84\\x6f\\x66\\x14\\x0b\\x2a\\x22\\xf2\\x8b\\x4f\\x5f\\x09\\xe5\\x7d\\x9b\\x17\\xf7\\x52\\xd0\\x4b\\xad\\x07\\x9c\\xf2\\x5f\\x4c\\x58\\x2e\\xbb\\x7a\\xf1\\xdc\\x24\\xda\\xf5\\x3f\\x33\\x1a\\xee\\xd1\\xf3\\x66\\x77\\x95\\x29\\xd8\\x34\\x3c\\x6b\\x4c\\xa1\\xad\\xaf\\x07\\xc1\\x3f\\xce\\x19\\xa3\\xb1\\x9a\\xde\\xf2\\xd7\\xe7\\xb9\\x31\\x4b\\x2f\\xb7\\x2f\\xc9\\x47\\x21\\xc8\\x14\\xe2\\x55\\x3e\\xaf\\x79\\x1f\\xa9\\x71\\x0d\\x57\\x41\\x43\\x49\\x14\\x25\\xca\\xec\\x25\\x37\\xbb\\xaa\\x3d\\xc6\\x22\\xfd\\xed\\xc9\\x49\\xb7\\xb8\\x73\\xf8\\xb1\\xd1\\xa9\\x50\\xca\\x1b\\x42\\xb2\\x24\\xd3\\x19\\x13\\x85\\x2b\\x67\\xbb\\x60\\xd1\\xec\\xc6\\x97\\x7a\\x25\\xad\\x34\\x11\\xee\\x8b\\x7a\\xc7\\x18\\x34\\x42\\x7a\\x4f\\x06\\x60\\xcc\\xd6\\x30\\xf1\\x35\\x02\\x8c\\x6e\\xc1\\x99\\x8e\\xf4\\x83\\x2b\\x36\\x1b\\x68\\xcc\\xf8\\x59\\xf3\\x01\\xc1\\x6f\\x4a\\x41\\x8e\\x25\\xfd\\xfa\\x4f\\x6c\\x49\\x3f\\x75\\xba\\x63\\xf1\\x8b\\x4b\\x73\\x17\\xb3\\x88\\x97\\x6b\\xc1\\x70\\xab\\xbf\\xb7\\x4a\\x19\\x61\\x7f\\xe2\\xae\\xd5\\xfb\\x42\\xef\\x67\\xb2\\x23\\x36\\xc5\\x85\\x34\\x32\\x63\\xc4\\xe3\\xfb\\xfb\\xce\\x50\\xb3\\xf1\\x3e\\x7d\\x2c\\xf8\\x7e\\x76\\xa5\\x7c\\xb6\\x0e\\x93\\x58\\x49\\x57\\x2a\\x94\\xef\\x81\\xde\\x98\\xb1\\xe1\\xaf\\x4d\\xb9\\x33\\x55\\x7c\\xfe\\xbb\\x0b\\x49\\x5d\\x0b\\xa1\\x35\\x1e\\xba\\x24\\x5f\\x45\\xdb\\x10\\x04\\x96\\x74\\x97\\xf7\\x9e\\xaf\\xb4\\xa4\\x5b\\xb8\\x75\\x25\\x68\\x16\\x7c\\x37\\xe1\\x82\\xc7\\x24\\x2d\\x55\\x9e\\x80\\xdd\\x0b\\x09\\x21\\x44\\xe7\\x6f\\xd9\\xea\\x23\\xa1\\x3d\\xce\\xd2\\x58\\x13\\x42\\xbb\\x3b\\x7f\\x12\\x7f\\x35\\x25\\xdc\\xd3\\x47\\x6c\\x99\\x17\\x65\\xad\\x0e\\x30\\xcd\\x76\\x2e\\x29\\x81\\x19\\x46\\x10\\xcf\\x77\\x2a\\x24\\xc4\\x72\\xb3\\x0a\\xfe\\x3c\\x59\\x67\\x7c\\x2a\\x27\\x24\\x11\\xe1\\x07\\x33\\x57\\x2d\\xdf\\x1c\\xde\\x8b\\x8c\\xe0\\xea\\xb9\\x1b\\xbb\\x8c\\xb2\\xd7\\x12\\xf1\\x13\\xd9\\xbf\\x95\\x0b\\x0d\\x1b\\xb5\\x46\\x89\\x3d\\x81\\xdf\\x34\\x01\\x5b\\xbf\\xa5\\xbf\\x1e\\x09\\x5c\\x27\\x57\\xd0\\xc0\\xca\\x57\\x63\\x51\\x15\\x99\\x68\\x0b\\x4c\\x6f\\x83\\xc1\\xe8\\xe9\\x98\\xf8\\xfa\\x63\\x55\\x7c\\x76\\xeb\\x2d\\xaa\\xef\\x6b\\x4b\\xbc\\x17\\x06\\x39\\xfc\\x5c\\x4e\\x86\\x0e\\x12\\xfb\\xbe\\x3b\\xc8\\x8e\\x31\\x3a\\x3f\\x43\\x87\\xe3\\x70\\xca\\x9f\\x48\\x4f\\x24\\x95\\x89\\xa6\\xdc\\x55\\xf9\\xc1\\xff\\xb2\\xd5\\x4b\\x37\\xc7\\xbc\\xcd\\xfb\\xdf\\x59\\xd3\\x4f\\x79\\x3c\\x55\\xf3\\x8d\\x07\\x11\\x83\\x69\\x41\\x77\\x89\\xee\\x9e\\x03\\xee\\x39\\xc9\\xc5\\xf0\\x59\\x1e\\x18\\x92\\x9b\\xbd\\x51\\x69\\xa2\\x94\\xa1\\xa9\\x10\\x8a\\x4d\\x95\\x22\\x27\\x1a\\xf3\\x67\\x12\\xac\\x9f\\xf2\\x3d\\xab\\x6c\\x16\\xad\\x38\\x13\\x9d\\xe5\\x04\\x25\\xa7\\x97\\x2f\\x51\\xce\\xd7\\x92\\xf4\\x3e\\x7e\\x7c\\x0c\\x04\\x8b\\xdb\\x3f\\x67\\xf3\\xf9\\x7b\\x36\\x8f\\x47\\xde\\x7d\\x52\\x47\\xd6\\xd6\\x40\\x89\\x50\\xff\\x19\\xf7\\x13\\xad\\xd7\\xc3\\x93\\x09\\xf7\\x10\\x44\\x3b\\x31\\x28\\x7f\\x26\\x35\\x58\\x31\\x5a\\xb6\\xbc\\x1c\\x2f\\xa4\\xd9\\xb7\\xbe\\x34\\xdb\\x8f\\x98\\x23\\xd9\\xb7\\xff\\xc9\\xf5\\x9e\\xda\\xfa\\x0c\\x23\\x08\\xc2\\x6a\\x8c\\xe9\\x4b\\x72\\xc8\\xfe\\x41\\x6e\\xfd\\xde\\x20\\x88\\x17\\x8b\\x65\\x9f\\x7f\\xc4\\x17\\xf5\\x3b\\xcb\\x32\\xea\\xc7\\x2e\\xb4\\x9f\\x65\\xc0\\xda\\xc5\\xad\\x78\\x13\\x0d\\xde\\x5b\\xce\\xad\\xdc\\x8d\\x0e\\x14\\x64\\xa8\\xaf\\x91\\xb5\\x0a\\x01\\xa5\\x9e\\x97\\x22\\xe5\\x08\\x55\\xa3\\x62\\xf4\\x10\\x95\\xcf\\x25\\x7e\\x1b\\x06\\x10\\x45\\x19\\x34\\x13\\x95\\xc5\\x1d\\xd1\\xcf\\x4c\\x1c\\x88\\x4e\\x42\\x77\\xab\\x1d\\xc7\\xdc\\x09\\xdd\\x09\\xda\\xf7\\x95\\x7c\\xbf\\xe2\\xdf\\x58\\x2a\\x1e\\xb0\\x09\\x71\\x5f\\xda\\xa2\\xd5\\xe9\\x25\\x1c\\x3c\\x07\\xa3\\x4c\\x30\\x40\\x1a\\x8f\\xbd\\x88\\xa6\\x3b\\x5f\\x78\\xa1\\x1c\\x1a\\xef\\xf5\\xe1\\x54\\x5a\\xab\\x03\\x5c\\x2b\\xc9\\x61\\xf6\\xd6\\x39\\x02\\x29\\x69\\x88\\xa2\\xc3\\x22\\x1c\\xc7\\xd1\\x5e\\x33\\x2a\\xaf\\x6c\\x66\\x43\\x7f\\xdf\\x43\\xb7\\x76\\x82\\xda\\xe2\\x3e\\x17\\x51\\xc7\\x36\\x0a\\x65\\xd5\\xac\\x54\\xe5\\x27\\xe1\\xfc\\xce\\xc9\\xc5\\x25\\x57\\xa0\\x3f\\x1d\\x83\\xc4\\xe2\\x41\\x38\\x47\\x1e\\xea\\x52\\x70\\x20\\x62\\xd8\\x5a\\x6e\\xfb\\x73\\x11\\xaa\\xab\\x12\\x2b\\x71\\x3f\\xc3\\x91\\x25\\x4a\\xc5\\xc2\\x97\\x47\\x9a\\x80\\x31\\x15\\x42\\x34\\xfd\\x79\\xc7\\x42\\x49\\x22\\x52\\x86\\xb0\\xa5\\xe7\\xc1\\x0f\\x82\\x32\\xf3\\x3c\\xb7\\x13\\x0c\\x44\\xa7\\x38\\xfd\\x09\\xfa\\xf7\\x0a\\x5f\\x1d\\x07\\x81\\x50\\x2c\\x8f\\x47\\xae\\xe6\\xea\\x5f\\x51\\xaf\\xfe\\xb0\\x25\\xcb\\xff\\x2c\\x03\\xe1\\x12\\x2b\\x55\\xae\\x70\\xff\\x6c\\x79\\xb8\\xe7\\x48\\x1e\\x17\\xe5\\x71\\x2a\\xf2\\x0f\\xff\\x3f\\xfb\\x32\\x1d\\x51\\x42\\xe3\\xbe\\xfc\\xa7\\xd0\\x3e\\xf2\\x5c\\xf0\\x30\\xce\\x17\\x9d\\xa6\\xd3\\xe8\\x9e\\xe4\\xfb\\xc9\\x9b\\x3e\\x51\\x57\\x1e\\x22\\x3b\\x28\\x24\\x52\\x90\\x37\\x94\\x6c\\x2e\\xc7\\xe9\\xf8\\x0a\\xfe\\xd0\\xc4\\xcf\\xeb\\xd7\\x43\\x25\\xe7\\xb5\\xcc\\x71\\x3f\\x64\\xa6\\x14\\x6c\\x80\\x76\\x16\\xa6\\x71\\x81\\xa4\\xd2\\x18\\x85\\xd8\\x5d\\xbe\\x2b\\xa6\\x89\\x35\\x9c\\x40\\x67\\xe8\\x6a\\xd8\\x19\\x82\\xb0\\xf6\\x48\\xd1\\x52\\x15\\xf4\\xfa\\x3c\\x31\\x0f\\xba\\xfb\\x70\\x01\\xa5\\x36\\x56\\xa6\\x38\\x2c\\x89\\xf6\\xfd\\x50\\xc9\\x55\\x27\\xad\\x39\\x75\\x1b\\x39\\x22\\xdc\\xdf\\x1a\\x0f\\x49\\xed\\xa6\\x9e\\x6b\\xcf\\x5b\\x4d\\x2b\\xd9\\xcd\\x29\\x06\\x0f\\xb4\\x70\\x7e\\xe3\\xf1\\xc9\\x7e\\xe9\\xdd\\xbd\\xf6\\x86\\x81\\x59\\x12\\xf3\\x83\\x45\\x83\\x37\\x8b\\xc0\\xae\\x1c\\x23\\xab\\x57\\x48\\x55\\xad\\xc4\\x4b\\x07\\x08\\x09\\x72\\x87\\x6e\\x1d\\x72\\x34\\x51\\x63\\x7d\\xe0\\x35\\x99\\x7d\\xca\\xb4\\x5f\\xe1\\x1c\\xe3\\x69\\x2f\\x4c\\x96\\x73\\xaa\\x40\\x8f\\x88\\xbe\\x7b\\x52\\x39\\x6d\\xcb\\x6e\\xe8\\xc6\\x2b\\x8e\\xda\\xe3\\x49\\xef\\x18\\xdc\\xbf\\xb2\\x86\\x44\\x0a\\xa2\\xe9\\x95\\xf8\\x7c\\xfd\\xea\\x07\\xa5\\xee\\x42\\x4b\\x25\\x3c\\xbb\\x71\\x67\\x18\\x2e\\x8c\\x1f\\x0a\\x2c\\x64\\xcc\\xcb\\x11\\x24\\x07\\x43\\x2b\\xa0\\x3d\\x11\\x60\\x0c\\x83\\xc0\\xe0\\x52\\x39\\xf9\\x23\\xeb\\x3d\\x82\\x88\\xe6\\x83\\x91\\xdd\\x39\\xd4\\x20\\xc6\\xb2\\x74\\xac\\x75\\x58\\x5f\\x0a\\xf8\\x03\\xef\\x00\\xd8\\x04\\x40\\x3d\\x27\\x49\\xa4\\xf5\\x7a\\xe9\\x25\\x3a\\x6d\\x78\\x9a\\x72\\xce\\x3a\\x79\\x1d\\x8f\\x74\\x27\\x98\\xdf\\xb3\\x9d\\xcd\\xc0\\xfb\\xfc\\xe4\\x0b\\x76\\xb8\\x5b\\xe8\\xcf\\xf3\\x4d\\xa1\\x3e\\xbd\\x2b\\x40\\x20\\x76\\x42\\x30\\x81\\xef\\x67\\x39\\xc8\\x17\\x3a\\x51\\x67\\x6c\\xc0\\x78\\x6f\\xbe\\x28\\x25\\xf9\\x52\\xf7\\x5b\\xb6\\xbe\\xa5\\xdd\\xb0\\xc3\\x23\\xbc\\xde\\xcb\\x7e\\x6c\\x8b\\x90\\xf9\\xcb\\xe8\\xa7\\x17\\x15\\x0b\\x4c\\x4d\\x6e\\x3b\\x82\\x2d\\x45\\x0a\\xb3\\x76\\x9e\\xbe\\xef\\xb7\\xf4\\xd2\\xc7\\xc7\\x1b\\x1d\\x0f\\x12\\xb3\\xbc\\x6d\\xb1\\x30\\xc2\\x63\\x14\\x77\\xbb\\x2d\\xd8\\x83\\x4d\\x38\\x9e\\xb5\\x90\\xd8\\x56\\x84\\x86\\xfd\\xde\\xf9\\x0d\\x84\\xe0\\x53\\xc4\\x96\\xa1\\x21\\xd9\\x7c\\x1b\\xbe\\x8e\\xd0\\x02\\x8e\\xb0\\x77\\xa3\\x59\\xe7\\x8c\\x50\\x1b\\x40\\xdc\\xa9\\xd2\\xd0\\xc6\\x25\\x70\\x04\\x27\\x08\\x40\\x3f\\xe1\\xb1\\x60\\xa3\\xdc\\x8d\\x53\\x4e\\x3f\\x1f\\xb6\\xea\\xb1\\xc8\\xab\\xfc\\x22\\x2d\\xea\\x4d\\x45\\x09\\x12\\x37\\x07\\x9e\\x3b\\x47\\xd7\\xde\\x23\\x66\\x77\\x29\\x06\\x80\\x06\\xa0\\x38\\xf1\\xf9\\xf8\\x46\\xad\\xcd\\xc0\\x0d\\x25\\x98\\x4f\\xa5\\x59\\x54\\xea\\xbd\\xf6\\xb8\\x7e\\x9c\\xe9\\x2f\\xb7\\x91\\x9f\\x65\\xd8\\xae\\xd9\\xa2\\x6d\\xb4\\x0d\\xe3\\x15\\x67\\xcc\\x68\\x7d\\xac\\xe9\\x8a\\x1b\\x2f\\x89\\x00\\x4d\\x13\\xb2\\x72\\x32\\x4f\\xf4\\xb6\\x83\\x7b\\xde\\x4f\\x69\\x75\\x95\\x15\\x67\\xee\\xcf\\x68\\x78\\xfa\\x89\\xbc\\x79\\x13\\xdf\\xa8\\x58\\x79\\x46\\xc2\\x01\\xf8\\x1d\\x80\\x70\\x57\\xca\\xc9\\x04\\x70\\xee\\x77\\x50\\x7d\\xd2\\x30\\x4d\\xc4\\xd5\\xfa\\x36\\x4b\\xd7\\x34\\x71\\x62\\x29\\x0c\\x43\\x1a\\xe1\\xc1\\xab\\xcf\\xfc\\xd7\\xc3\\x42\\x8c\\xd0\\x5b\\x7d\\x1e\\xa1\\x60\\x2e\\xf1\\x9b\\x67\\x6b\\xf6\\x99\\x03\\xf2\\x81\\x6c\\xbb\\x3e\\x4c\\xf7\\x60\\x4f\\xf4\\x36\\xfe\\xdc\\x45\\xa0\\xea\\x97\\x39\\xe7\\xba\\x73\\x7b\\x21\\xc1\\xc0\\x76\\x26\\xa6\\x79\\xc3\\x15\\x57\\x59\\x5f\\x6f\\x4c\\xb3\\x73\\x08\\x6c\\xc0\\xee\\xd6\\xad\\xf4\\x86\\x4e\\x10\\xc2\\x3c\\x33\\xc4\\x3d\\x39\\xb4\\xac\\x45\\x3b\\xf2\\xec\\xbb\\xef\\x15\\x25\\xd7\\xe9\\x7e\\x1c\\x8c\\x2d\\x83\\xd1\\x79\\x72\\xbf\\xf8\\xfb\\x3b\\x4d\\xfb\\x4c\\x23\\xf3\\x74\\xfb\\x4b\\xc2\\xed\\x1f\\x1c\\x95\\xb6\\xd5\\x9d\\x01\\xed\\x02\\x64\\x8b\\x37\\x66\\xa3\\x4e\\xe3\\x41\\xe7\\x36\\x62\\xc2\\x1c\\x60\\xa3\\x16\\x07\\xd8\\xf0\\xb8\\xd7\\x8b\\xe2\\x0b\\x52\\xe0\\xc2\\x3d\\xc8\\x77\\xda\\x6e\\x30\\xdd\\x1e\\x06\\x7c\\xaa\\xb6\\x7d\\xdb\\x46\\x25\\x07\\x4c\\x1f\\xfa\\xcc\\xb8\\x11\\x75\\x7a\\xfa\\xe0\\x4e\\x09\\x76\\x26\\xd5\\x27\\xce\\xf7\\xa5\\x11\\x26\\xfe\\x15\\x8f\\xbb\\x76\\xd6\\x83\\x98\\x5c\\xbf\\xd2\\x28\\x07\\x97\\x1d\\x7e\\x2d\\xf3\\x20\\x47\\x9e\\x0f\\x71\\x7c\\x7f\\xe7\\xaf\\x84\\x6f\\x00\\x05\\x3b\\x60\\xb0\\x73\\x89\\x79\\xb6\\x3e\\x9e\\xda\\x9b\\x60\\x5a\\x1a\\x20\\x11\\x9e\\xf6\\x23\\xf9\\xac\\x71\\xa6\\x65\\x56\\xd8\\x2b\\x32\\xf2\\x80\\x62\\xb0\\x7f\\xd8\\x95\\xd7\\x04\\x40\\xa8\\xe1\\x0d\\xe3\\xb5\\xcc\\xe0\\x3d\\x31\\xfa\\x0c\\x18\\x66\\xbf\\x36\\x59\\x5c\\xe7\\x87\\xb9\\xe4\\xfc\\xb3\\x08\\x78\\xce\\xde\\x13\\x29\\xcc\\x96\\xe0\\xf0\\xde\\xf4\\xbf\\x5e\\x46\\x32\\xc3\\xa1\\xfe\\x6c\\xbb\\xcb\\x0b\\x7f\\x5f\\x5d\\x3a\\x41\\x93\\x35\\x71\\x74\\x10\\xe4\\x83\\xcb\\x10\\x98\\xe0\\xf4\\x36\\x8f\\x57\\x47\\x60\\x1f\\x27\\x67\\xca\\x1e\\x30\\xe7\\xb2\\xfb\\xf3\\xd3\\xbc\\xe3\\x53\\xb7\\x1b\\x34\\x32\\x84\\xfb\\xc3\\x94\\x7e\\xbc\\x13\\xe3\\x47\\x1c\\x1f\\xdf\\x1c\\x47\\x28\\x00\\x08\\x0d\\xcd\\x01\\x56\\x84\\xfe\\xfe\\x89\\xbc\\x76\\x46\\xe8\\x73\\xcf\\x93\\xc7\\x1e\\x96\\x02\\x31\\x63\\x1d\\xce\\x0b\\xd1\\x86\\xaf\\x53\\x84\\x8d\\x81\\xe3\\xbe\\xe5\\x90\\xfb\\xbd\\x97\\xdc\\x53\\x43\\x21\\x75\\xa3\\xee\\xcc\\x71\\x73\\xda\\xd2\\x4c\\xb8\\x68\\xd5\\x5a\\x08\\xde\\x38\\x47\\x0c\\xa0\\x18\\x8f\\x25\\x34\\xce\\x72\\x6e\\x68\\xcd\\xd3\\x3e\\x13\\x00\\x14\\x06\\x86\\x9d\\xcc\\x1c\\xd6\\x1c\\xce\\x48\\x6d\\x74\\x34\\x8e\\x6e\\x46\\x4a\\xe5\\xb7\\xc6\\xc5\\xcb\\x27\\xd0\\x3b\\x7f\\xef\\x6d\\x9f\\xf0\\x33\\x1f\\xcb\\xbc\\x6d\\x8d\\x88\\x75\\x67\\x00\\x54\\x62\\x90\\x2b\\x08\\x17\\x1c\\x9b\\x70\\x78\\x60\\xc7\\x79\\x3f\\x22\\x61\\x98\\xa6\\xe7\\x2e\\x0a\\xea\\xaf\\xa7\\xea\\xc3\\x21\\xf6\\x19\\x6b\\xd1\\xce\\x0a\\xd5\\xeb\\x0c\\xbb\\xb0\\xcb\\x0e\\x32\\xfb\\x28\\xaa\\xce\\x39\\x4b\\xb4\\xef\\x3a\\x64\\xee\\x00\\xd3\\xa8\\x9c\\x1b\\xb5\\x7d\\x85\\x13\\x40\\x10\\x06\\xa6\\x2b\\xce\\x73\\x9d\\xaa\\x2b\\xe6\\xa4\\x31\\x70\\xa6\\x5c\\x7e\\xf2\\xb3\\xa5\\xf1\\xbf\\x19\\x2a\\x7a\\x15\\xe2\\x2a\\x39\\xa0\\xfa\\x1e\\x30\\x4b\\xc8\\xce\\xcd\\x77\\xcd\\x53\\x22\\x27\\x56\\x86\\xa0\\xfb\\x65\\x96\\xac\\x5b\\xff\\xac\\x39\\xa1\\x09\\xfa\\x88\\x9e\\x8c\\x8e\\xed\\x14\\x8f\\x99\\x83\\xf8\\xaf\\xbe\\xa8\\x74\\xd3\\xd4\\x4d\\x7d\\x93\\xe8\\x98\\x80\\x4c\\x29\\xf2\\x0b\\x4f\\x78\\xa4\\x0e\\xa6\\xa5\\x80\\x01\\x3b\\xb2\\xf8\\xb3\\xde\\xad\\x7c\\x9e\\x50\\x20\\x07\\x18\\x01\\x01\\x49\\x0e\\xf3\\x7c\\x9a\\x78\\xa9\\xed\\x39\\x21\\x7d\\xf4\\x11\\xdd\\x6a\\xbc\\x35\\x6c\\x94\\x4c\\x74\\xe1\\x0c\\xf1\\x4c\\x02\\x0c\\xd0\\x33\\x00\\xf9\\x14\\x84\\xb3\\xe7\\x65\\x7a\\x85\\xe6\\x3b\\x41\\xc7\\x04\\xd3\\xe3\\x37\\x9d\\xdb\\xec\\x5d\\x8e\\xae\\x3c\\x32\\x1e\\xd8\\x54\\xfd\\x3c\\x5a\\xfa\\x62\\xbc\\x8f\\xeb\\x62\\x35\\x1d\\xfc\\x6a\\xdd\\xf9\\xa7\\xe9\\x0b\\x04\\xe6\\x06\\x41\\x1a\\x11\\xcf\\x81\\xd6\\x6d\\xc9\\xef\\x3e\\x0a\\x99\\x1b\\x14\\xd8\\xd7\\x98\\x80\\xe7\\x01\\x82\\xd0\\xea\\xb3\\x9d\\x1f\\xa7\\x78\\x27\\x80\\xce\\x69\\x5f\\x25\\x7f\\xa0\\x45\\xd7\\xc0\\x0d\\xdf\\xb1\\x56\\xd6\\x7c\\xb0\\xae\\x76\\x8a\\xfa\\x66\\x8a\\x67\\x42\\x0a\\x19\\x9d\\x02\\x20\\xce\\x76\\x7c\\x23\\x70\\xa7\\x26\\x7a\\x02\\x80\\x27\\x07\\xee\\x1e\\x80\\x8e\\x46\\x91\\xc6\\x49\\x87\\x2f\\x93\\x22\\xb8\\x7e\\x7a\\x0a\\x2f\\xbc\\x37\\x8f\\xb2\\xb6\\x7d\\x93\\x4e\\x97\\xbb\\xc2\\xcf\\xdf\\xbb\\xe4\\x3d\\x7f\\xc8\\x0c\\xa6\\xb4\\xd7\\x71\\x32\\xc2\\x63\\xdf\\x67\\x33\\xa4\\xf8\\x71\\xe8\\xf6\\xd0\\x00\\x40\\xdc\\x7b\\xb0\\xbf\\x28\\xdc\\x0d\\x95\\x99\\x97\\xf6\\x5d\\x9e\\x26\\x84\\xa1\\xc8\\xf8\\xe7\\xf3\\xa4\\x9b\\x85\\x5c\\xbc\\x76\\x88\\x61\\x4e\\x7a\\xeb\\x1a\\xf1\\x73\\x88\\xde\\xb5\\x49\\x22\\xb2\\xa1\\xca\\xf3\\xcc\\xf4\\x1d\\x02\\xf2\\x4c\\x04\\x95\\xb4\\x7c\\x5f\\xf2\\xb0\\x1f\\xc0\\x07\\xcc\\x45\\x80\\x7b\\x25\\xc8\\x99\\xf5\\x1b\\xba\\x75\\x26\\x04\\x81\\xf3\\x58\\x96\\xd8\\xc6\\x84\\xb3\\xef\\xd3\\xb8\\xef\\x16\\x68\\xf7\\xdb\\x37\\xfc\\x0c\\x9b\\xe9\\xb1\\xa5\\x01\\x41\\x92\\xeb\\x44\\x98\\xb0\\xa2\\xc4\\x22\\xb5\\x9e\\x23\\xe9\\x08\\x80\\x09\\xcb\\xed\\xf4\\x7b\\xab\\xe5\\x1d\\x02\\x80\\x84\\x02\\xcc\\x4d\\x63\\xf0\\xde\\x20\\x5a\\xd5\\xb7\\x9a\\xd5\\x0c\\x40\\xce\\x31\\xb6\\x32\\x02\\x81\\x88\\x26\\x75\\x4d\\x9c\\x7d\\xbd\\xeb\\xf2\\xe0\\x1e\\xe3\\x19\\x01\\x51\\xe2\\xf6\\x7d\\xbf\\x55\\x2f\\x2d\\x42\\xd6\\x09\\x10\\x5e\\xca\\x30\\x37\\x6a\\x2f\\xc4\\xab\\x66\\xf4\\x9f\\x73\\x7c\\x89\\x39\\x77\\x96\\xa7\\xd2\\x4c\\xd6\\x4c\\x10\\x9b\\xfb\\xb4\\x1f\\xeb\\x2f\\x97\\xe2\\xa5\\x70\\xf1\\x4f\\x2a\\xf5\\x3d\\x2c\\x08\\xf2\\x18\\x6a\\x92\\x52\\x2c\\xd9\\xe7\\x33\\xec\\xed\\xb2\\x2c\\xdb\\x06\\xc0\\xf3\\x49\\xd3\\xec\\xb5\\x9b\\x27\\x3a\\xca\\xad\\xc5\\x30\\xf7\\x9e\\x41\\x84\\xea\\x13\\x20\\x03\\xea\\xbb\\xe2\\x77\\xfa\\x19\\xf6\\x8f\\x85\\x00\\xa8\\xd9\\xe2\\x95\\xed\\x5c\\x21\\x26\\x6f\\x81\\xf6\\x23\\x66\\x07\\xf3\\x0e\\x00\\xd3\\xee\\xe0\\x52\\xde\\x5b\\x85\\x2d\\x9b\\x40\\xd3\\x08\\x04\\xa4\\x28\\xb8\\x11\\x16\\x28\\xc6\\x42\\xbd\\xc5\\x5d\\x88\\x68\\x9c\\x0d\\x32\\x89\\xd8\\xb5\\x5d\\xa4\\xb9\\xf3\\xfb\\xab\\x2d\\x0f\\x94\\x8f\\xd8\\xcc\\x76\\x99\\xa7\\x49\\x94\\xce\\xd5\\x9f\\x15\\xd3\\x92\\x44\\x44\\x9f\\x8a\\xe4\\x6a\\x98\\x01\\x30\\x66\\x1f\\xec\\xf1\\x0e\\x16\\xba\\x11\\xbe\\xdd\\xe2\\x6e\\x3b\\xaf\\xdf\\x79\\x06\\xd8\\x07\\x27\\x63\\xd9\\xfa\\xee\\x11\\x14\\xf5\\x4a\\xf4\\x82\\xe1\\x3a\\xe6\\x83\\x97\\x11\\xc2\\x4d\\x75\\x07\\x2e\\x03\\x92\\x34\\x80\\x62\\xd6\\x90\\x22\\x00\\x40\\x7d\\xdf\\xb7\\x4c\\x2b\\xdb\\x17\\x08\\x76\\x40\\x00\\x00\\x77\\x00\\x46\\x1f\\x30\\x21\\x09\\x78\\xd1\\x80\\xd3\\x8a\\x93\\xf7\\x2c\\x55\\xa6\\x84\\x0e\\xf1\\x4c\\x2c\\x69\\xf5\\xc4\\xd4\\xdf\\x99\\xa3\\x22\\x2b\\xee\\x84\\xe5\\x2e\\xa6\\x7d\\x83\\x74\\xae\\x7b\\xbf\\x2f\\xca\\x86\\xed\\x82\\xa1\\x96\\x89\\x1c\\xe1\\xa0\\x41\\xf4\\x24\\x69\\xae\\xdb\\xae\\x7d\\x92\\x37\\x9c\\x33\\x62\\xa7\\x53\\x86\\x20\\xf6\\x9b\\x01\\x6c\\x18\\xe4\\x5c\\x10\\x0c\\xcf\\x9d\\xb1\\x29\\xca\\xf9\\x56\\x4e\\x34\\xef\\x33\\x10\\xce\\x2a\\xc4\\x99\\x74\\x5c\\xab\\xe9\\x4d\\x68\\x76\\x0a\\x10\\xa2\\xcf\\x01\\x3b\\x01\\x70\\xb5\\x17\\x51\\x5a\\xa6\\xb4\\xed\\x04\\x64\\x08\\x40\\xa2\\x4e\\xba\\x6d\\xb9\\xe3\\x39\\xc7\\x41\\x7e\\x1e\\x43\\xb8\\xf9\\x2d\\x4b\\x05\\x73\\xbb\\xc6\\x1e\\x36\\x0b\\xdf\\x43\\xcb\\x9b\\xd9\\x07\\x8d\\xec\\xfe\\x03\\x91\\x94\\x27\\xed\\xa3\\x44\\x57\\x50\\xf4\\xe3\\x3c\\xc9\\xf9\\x13\\xf4\\x11\\x33\\x47\\xdd\\x89\\x9a\\x96\\x9b\\xd8\\x45\\xca\\xd3\\x4c\\x9e\\xe8\\x5d\\xdb\\x9e\\x24\\x93\\x75\\xe7\\x95\\xb4\\xca\\x81\\xe6\\x33\\x04\\x35\\xa0\\x9b\\x1b\\x20\\x34\\x03\\xa8\\x8e\\x99\\x68\\x7d\\xd6\\x93\\x0c\\xd7\\xea\\xe0\\x86\\x0c\\xdb\\xf4\\x65\\x87\\x30\\x4d\\xe8\\x3d\\x0b\\x56\\x93\\x14\\xac\\xea\\xe4\\x60\\x98\\xcd\\xb4\\x82\\x39\\x98\\xde\\x0c\\x33\\xd4\\x42\\xd0\\x64\\xba\\xf0\\xe4\\x01\\x0f\\x15\\xb9\\xb5\\x76\\x80\\x44\\x3b\\xd8\\x76\\x41\\xaf\\xed\\xf8\\xd6\\xc4\\x9c\\x3a\\x6d\\xc3\\xe0\\x0a\\x52\\xe7\\x7b\\x75\\x99\\xa0\\x4b\\x63\\x14\\x1a\\x13\\x1e\\xe9\\x5f\\xe7\\xa9\\xfe\\x6a\\x19\\x94\\x17\\x19\\x75\\xe3\\xc4\\x95\\x28\\x12\\xac\\x35\\x47\\xee\\x83\\xf0\\x5c\\xd3\\x14\\x3c\\x29\\x0d\\x65\\x4f\\xab\\x67\\x26\\x7a\\xab\\x17\\x84\\xdd\\x78\\xaf\\x5d\\x23\\x84\\x58\\xe9\\xb0\\x33\\x9b\\xa7\\x89\\x94\\xf8\\x76\\x03\\xd8\\x25\\x80\\x05\\x36\\x80\\x24\\x35\\x61\\xd1\\xe5\\x4a\\xea\\xca\\x53\\x10\\xa9\\x6b\\x1b\\x3d\\x35\\x3b\\xcc\\x71\\xe4\\xda\\x5c\\xab\\x73\\xae\\xce\\x73\\x52\\xc1\\x0b\\xc2\\x45\\xc5\\xba\\x0d\\xc8\\xd3\\x44\\xd3\\x80\\x0d\\xa2\\x9f\\x52\\x80\\xec\\x35\\x79\\x3a\\x40\\xf1\\xb0\\x35\\xd8\\x01\\xe2\\xe6\\x40\\xed\\xfc\\xbd\\xb3\\x9b\\x13\\x03\\x97\\x76\\x17\\x28\\x34\\x6c\\x7b\\xbf\\xed\\x25\\xe1\\x77\\x6f\\x56\\x98\\x05\\x6d\\xd6\\x80\\xc4\\x9f\\x78\\xd3\\x32\\x51\\x8a\\xbd\\xff\\xf1\\x69\\x11\\xc9\\x24\\x53\\x9a\\x3d\\xcf\\xe1\\xa5\\x70\\x9c\\x1f\\x2b\\x1b\\x59\\x40\\xc8\\x3e\\xf4\\x6e\\xa2\\xe4\\x8d\\xbe\\x7e\\x12\\xa4\\xfd\\x00\\x36\\x8b\\xe4\\x46\\x75\\x88\\x6f\\x55\\x7e\\x3e\\xc4\\x98\\x61\\xee\\xfb\\x9e\\xf7\\x3d\\x99\\xf7\\x74\\x9c\\xf6\\x9e\\xb4\\x34\\x41\\xe8\\xeb\\x63\\xf0\\x25\\x32\\xc7\\xba\\x15\\xab\\x01\\x5d\\x5c\\xd0\\x71\\x5d\\x2f\\x8c\\xb7\\x6f\\x6f\\x53\\x0c\\x8b\\x7e\\xc1\\x9e\\x11\\x82\\x3d\\xf6\\x5f\\x5a\\x49\\xaa\\xef\\x36\\x6f\\x8c\\x01\\xba\\x91\\x60\\x7a\\xa4\\x2c\\x77\\x35\\xb5\\xd6\\x81\\x29\\x94\\x0b\\xf8\\xfb\\x66\\xf8\\x38\\x4d\\x50\\x35\\x27\\x07\\xf3\\x35\\x12\\x80\\x2d\\x09\\x1a\\xf4\\x87\\xa3\\x87\\xcd\\xaf\\xf7\\xca\\x71\\xf4\\x28\\x40\\x76\\xfe\\x24\\xd9\\x44\\xd3\\xe1\\xbd\\x03\\x88\\xe4\\xb1\\x6d\\x4a\\x2d\\xe5\\x11\\x38\\xe3\\xde\\x14\\xa2\\x1b\\x46\\x1e\\x47\\x13\\xcd\\xba\\xaa\\x6d\\x26\\x9b\\xaf\\xb4\\xe5\\x4d\\xb1\\xe7\\x85\\x13\\xc4\\x34\\x4d\\x53\\xd9\\xce\\xdd\\xfb\\xe8\\x76\\x20\\x68\\x31\\x4b\\xa8\\xb7\\x14\\x4b\\x08\\xbd\\x61\\x63\\xe6\\xdc\\x3d\\xa0\\xf2\\x71\\x58\\x51\\x8a\\xbc\\xb4\\xba\\x26\\x70\\x5a\\xd6\\x41\\x66\\xcc\\x7f\\xdc\\xae\\x83\\x01\\x7b\\x3a\\xa1\\x35\\xcf\\x4c\\x4b\\x93\\x14\\x46\\xf8\\xf3\\xb9\\xf5\\x6e\\xb7\\xf3\\xcc\\x4f\\x69\\xb9\\x7b\\xfb\\x1c\\xf1\\xcd\\x48\\xb3\\x34\\x73\\x56\\x0d\\x82\\x37\\x3a\\x04\\xd6\\xaf\\x2e\\x95\\xe3\\x5e\\x97\\x5a\\x0f\\x2b\\xc3\\xdc\\x84\\x77\\xe0\\x11\\x7b\\x97\\xd1\\x34\\xcd\\x3f\\xb8\\xf5\\x66\\xbb\\x2b\\xd6\\x68\\xf9\\x4e\\x6e\\xd5\\x30\\x76\\x55\\xa5\\xb6\\x2c\\x47\\x84\\xe2\\x08\\x74\\x1e\\xe4\\x52\\xe6\\x62\\x29\\x01\\xbe\\xe8\\x0f\\xce\\x64\\xe2\\x8c\\x58\\x99\\x28\\x40\\x08\\x8a\\xa2\\xe0\\xdc\\xac\\x1e\\x93\\xb9\\x98\\xbb\\x2f\\x75\\x01\\x61\\xa0\\x11\\x9f\\x0f\\xb5\\x12\\x40\\x6a\\x55\\x6a\\x75\\x7d\\xbf\\xef\\xf1\\xce\\xcb\\xf0\\x18\\xae\\x1b\\xf5\\xd2\\x5c\\x9d\\x59\\xe8\\x98\\xb9\\xc7\\x71\\x5d\\xb7\\xed\\xc6\\xbe\\xbc\\xfd\\xdc\\x61\\xa2\\x94\\xac\\x00\\x21\\x49\\xed\\x67\\xa6\\x5d\\xc1\\x71\\x37\\x49\\x5d\\x03\\x80\\x8e\\x20\\xb8\\x53\\xdd\\x13\\xe2\\xe2\\xf1\\xcb\\xd1\\xdf\\x1f\\x04\\x6e\\xa6\\xad\\x13\\xf9\\xa6\\x6e\\xe7\\x81\\x31\\xc4\\x8e\\x17\\x84\\xbf\\x47\\xec\\x9b\\xae\\x03\\xd6\\x30\\x6e\\xf9\\xba\\xe0\\x4e\\xc4\\x52\\xcb\\x50\\x34\\xbc\\x3c\\xeb\\x62\\x35\\xfe\\x21\\x09\\x2e\\x9a\\x7e\\x4e\\x0a\\x0b\\x5d\\x7f\\xcf\\xf3\\x09\\xf3\\x56\\xaf\\x45\\xb9\\xcf\\xb3\\x08\\x84\\x1d\\x24\\xc0\\xb8\\x2a\\xe2\\x54\\xb5\\x6d\\x05\\x40\\x12\\x00\\xfe\\xe4\\xed\\xbd\\xec\\x5f\\x6a\\x54\\xc7\\xcc\\x89\\x6c\\xeb\\xbe\\x1b\\x0c\\xbf\\x76\\x44\\x1c\\x96\\x59\\x2f\\x32\\x48\\x25\\xf3\\xbb\\x3f\\xcf\\x04\\x7b\\x55\\x7b\\x96\\x42\\x0c\\xb3\\xa8\\x64\\x53\\x02\\x21\\xcc\\x91\\xca\\x34\\x89\\x4d\\xcd\\x8a\\xeb\\x3a\\x3d\\x99\\x02\\x71\\x18\\xcf\\x4c\\xc9\\x1a\\xc1\\x12\\x59\\x85\\xf1\\xab\\x15\\x17\\xb5\\xcf\\x00\\xf5\\x1d\\xc0\\x00\\x0b\\x14\\x3e\\x56\\x49\\xcf\\x0c\\xc1\\x26\\xfa\\x46\\x9b\\xda\\xbe\\x8b\\x5e\\xcf\\xe0\\x16\\x48\\xb0\\xe3\\x4c\\xba\\x03\\x6c\\x66\\x20\\xf2\\xa7\\x56\\x0e\\x68\\x8f\\x07\\x0e\\x37\\x64\\xf5\\x1e\\x63\\x90\\x8a\\x46\\x37\\x82\\xd1\\xe6\\xf9\\xbb\\x69\\x86\\x9e\\xdb\\x5a\\xae\\x3d\\x3a\\x47\\xc7\\x22\\xc4\\x9e\\x77\\x10\\x4d\\xe5\\x43\\x25\\x70\\x71\\x76\\xaf\\x1b\\xe0\\x1a\\x46\\xb4\\xc9\\x65\\x0c\\xc8\\x4e\\x37\\x89\\x2e\\x40\\x84\\x49\\x37\\x02\\xe4\\x60\\x50\\xff\\x78\\xad\\x0d\\xa0\\x6b\\xbc\\x17\\x4d\\x6c\\xf4\\x36\\x27\\x2c\\x11\\xad\\xd1\\xea\\xcf\\x0c\\x33\\x0c\\xc3\\x96\\x28\\x6d\\x2e\\x7d\\xf4\\xf9\\x4b\\x26\\xaa\\x01\\x36\\xb3\\x3c\\x0e\\xca\\xf7\\xb0\\x9d\\x29\\x31\\xc0\\xee\\xef\\x2e\\x46\\xbe\\xcf\\xfd\\xb7\\x1f\\xc5\\x71\\x3a\\xac\\x53\\xc2\\x30\\x7c\\x54\\x39\\x0e\\xc6\\x7f\\x6b\\x10\\x64\\x00\\x10\\x1b\\x12\\x6d\\xcb\\x2e\\x3f\\x93\\x5b\\xbd\\xa5\\x83\\x4d\\x3c\\xe9\\x48\\x84\\x67\\x93\\xf1\\xe6\\x12\\x73\\xdf\\x80\\x53\\x19\\xf5\\x16\\x6d\\xae\\x71\\xbf\\x57\\xe7\\x14\\x1d\\xf4\\x4e\\xcf\\x75\\x5d\\x0d\\x45\\x0e\\xbd\\x64\\x41\\xcf\\x82\\x1d\\xba\\xae\\xeb\\xfe\\xb1\\x78\\xfb\\x12\\xd8\\x6d\\xa1\\xab\\x45\\x05\\x8b\\x9c\\xba\\x37\\x23\\xba\\x9a\\xc2\\x30\\x34\\xbe\\xad\\x2d\\x72\\x46\\x4c\\x82\\x68\\x02\\x36\\x9d\\x99\\x1f\\x8a\\xc0\\xab\\xbf\\x96\\xee\\x0b\\x55\\xf8\\x81\\x39\\xc3\\xd6\\xc7\\xa5\\x71\\x5f\\x54\\xb5\\xdf\\xa7\\x7e\\xab\\x37\\x7f\\x1c\\xdd\\xfb\\x68\\x9a\\xa5\\x6d\\xe4\\xd1\\xb3\\x42\\xb7\\x75\\xdd\\x04\\xef\\xb2\\x18\\x45\\x7a\\x98\\xcf\\x2c\\xd8\\x67\\x1e\\x99\\x67\\x1a\\x99\\x7c\\xad\\xa2\\xd6\\x08\\x47\\xf6\\x89\\x5e\\xe6\\x2b\\x96\\xde\\xe2\\x28\\x00\\xb0\\x46\\xc4\\x81\\xf0\\x62\\xe0\\xe4\\x2c\\x91\\x40\\x64\\x9b\\xbd\\xb6\\xcc\\x1c\\x55\\x0a\\xb4\\x7f\\x9a\\x57\\xcf\\x42\\xf8\\x10\\xfe\\x0e\\xfa\\x95\\x21\\x69\\xb5\\x7e\\x96\\xf8\\x29\\xef\\x79\\x06\\x5d\\x4d\\x83\\xd4\\x83\\x4a\\xd6\\x37\\x41\\xb7\\x36\\x84\\x27\\xe3\\xdf\\x6d\\x2f\\xd8\\x51\\xcc\\x7c\\x11\\x04\\x31\\x1a\\x79\\xa7\\x10\\x7b\\x70\\xae\\x6d\\x7a\\x00\\x96\\x92\\x7f\\xf0\\x17\\x19\\xa5\\x8b\\xfd\\x53\\x5f\\xd3\\x3c\\x4b\\x79\\x79\\x80\\x56\\x30\\x39\\xff\\x0b\\x8a\\x07\\xc7\\x59\\x92\\x84\\x9e\\x47\\x02\\x02\\xc5\\x89\\x20\\xdc\\x87\\x88\\x46\\x00\\x9a\\xee\\xb1\\x89\\xf8\\xca\\xd7\\x3e\\xb2\\x1c\\xb9\\x4f\\x89\\x1d\\x59\\x11\\x7f\\x54\\x8d\\x5f\\x2f\\xac\\x95\\xa8\\xd9\\xf9\\xd8\\xaa\\x6e\\x17\\xee\\x11\\xe3\\xcb\\x4d\\xc3\\x37\\x40\\xe0\\x1e\\x8e\\x94\\xcc\\xab\\x38\\x7f\\xf7\\x47\\xde\\xea\\xea\\xc7\\x63\\x03\\x3c\\xcf\\xe7\\xfb\\xfe\\x7d\\x52\\x0c\\x39\\x79\\x1f\\xed\\xc6\\x3e\\x6f\\xfb\\x66\\x30\\xa8\\x9f\\x4b\\xc3\\x4d\\x89\\xb1\\x62\\xf9\\x5d\\x62\\xdd\\xb5\\xe4\\x24\\x62\\x54\\xf7\\x7d\\x63\\x3b\\xf5\\xfc\\xec\\xfb\\xd6\\xf3\\xef\\xbe\\x78\\x28\\xc2\\x43\\xff\\x8d\\x61\\xed\\xb3\\xed\\xfa\\x87\\xee\\x59\\xd8\\xe3\\x3a\\xff\\x3a\\x32\\xae\\xb6\\xc1\\xe5\\x80\\x49\\x6e\\x99\\x04\\x4d\\x75\\x10\\xe4\\xb4\\xfc\\xd6\\x93\\x3b\\x02\\xc0\\x50\\xa4\\x86\\x21\\x9c\\x21\\xf8\\xb6\\x0d\\xdb\\x09\\x42\\x4f\\xa2\\xad\\x33\\xc4\\xe9\\x62\\x79\\xd4\\x16\\x2a\\x0a\\xd6\\x0a\\x94\\xfb\\xa1\\x7f\\x67\\x9f\\xef\\xd8\\xd6\\x74\\x94\\x63\\x18\\x90\\x5e\\x2f\\x35\\xd3\\xfd\\x79\\xa1\\xdc\\x34\\x1b\\x73\\xb9\\x9d\\x7a\\x58\\x90\\x52\\x6e\\x18\\xef\\x25\\xbd\\x97\\xb2\\x83\\x4e\\x92\\x65\\xd7\\x11\\x84\\x5c\\x0a\\xa3\\x54\\xc2\\x40\\x94\\x00\\x04\\xf4\\x01\\xa2\\x94\\xa5\\x89\\x7d\\x1d\\x2a\\x20\\x8d\\x3c\\xe0\\xe4\\xe1\\xb2\\x7e\\xb1\\x6b\\x35\\xbd\\x98\\x09\\xa8\\xf0\\x43\\xa3\\x18\\x3b\\x14\\x7b\\xec\\x33\\x14\\xad\\x7d\\x6a\\x57\\x61\\xd0\\x52\\x35\\xca\\xfe\\xbe\\x51\\xeb\\x15\\x72\\x27\\x42\\xe4\\xef\\xa1\\x7d\\x0b\\xc4\\x3d\\x90\\xfe\\x97\\xb6\\xad\\x56\\xbe\\xa9\\x68\\xf5\\x0e\\x80\\x0a\\x9c\\x7d\\x55\\x5a\\xba\\x6f\\x32\\x3d\\x4d\\xc3\\xfc\\xff\\xbf\\x7f\\x33\\x70\\x1c\\x67\\xb0\\x2c\\xc6\\x78\\x61\\xe7\\x4f\\x89\\xa2\\x83\\x6e\\x9c\\x2a\\x76\\x72\\x9a\\x86\\x6d\\x58\\xa0\\x96\\xf5\\xe0\\xbe\\x44\\x67\\xbe\\x53\\x52\\xe7\\xbe\\x0a\\xc1\\x50\\x9c\\xe0\\x0c\\xaa\\x95\\x32\\x19\\x05\\x41\\x10\\xea\\xa6\\x89\\x9f\\x53\\xd4\\xdf\\xbb\\xeb\\xa6\\x56\\x16\\x7e\\xa7\\x7f\\xfd\\x42\\x85\\x80\\xc9\\x03\\x86\\xd9\\xab\\x42\\x7a\\x77\\xbc\\x60\\xbf\\xbd\\x0a\\x02\\x40\\x1e\\x29\\xe5\\x76\\xc9\\x98\\x65\\xf3\\xe8\\x03\\x2b\\xd5\\x1b\\x27\\x25\\x96\\x5e\\xf7\\xe3\\x8d\\x88\\x35\\x4c\\x16\\x9c\\x99\\x3f\\x55\\xfb\\xfd\\x3d\\x58\\xd0\\x2c\\x68\\x04\\xef\\xef\\xc7\\x4e\\x55\\x04\\xd9\\xde\\x4c\\xad\\x9c\\xdf\\xc7\\x11\\xfc\\x62\\xc0\\x8f\\x8a\\x5f\\x75\\x41\\x73\\x02\\x28\\x70\\xd5\\xee\\x29\\xf2\\xad\\x1a\\xe1\\x2d\\x86\\x55\\xcb\\xbe\\xfc\\xbe\\xc7\\x56\\x17\\x67\\x20\\xf6\\x12\\x5e\\xc4\\xde\\xe1\\x59\\x62\\x08\\xf5\\xf8\\x16\\x9c\\xf1\\x21\\x3d\\x65\\x0a\\xb0\\x89\\x71\\x76\\xd2\\x29\\x1e\\x90\\x46\\x49\\x94\\xf8\\xf3\\x8f\\x15\\xfa\\xcb\\x51\\x8d\\x5f\\x3f\\xcf\\x93\\xf0\\xe3\\xf9\\x8f\\xfd\\xbc\\x13\\x64\\x4b\\x04\\x76\\xec\\x0d\\x01\\x98\\xac\\x8d\\x3e\\xed\\x1c\\x33\\xe2\\xdd\\x60\\xb8\\xf1\\x0c\\xb3\\xe1\\x20\\x0e\\x16\\xee\\x85\\xfd\\x20\\x75\\x0e\\x53\\x05\\xc7\\x99\\x7a\\xe7\\x71\\xb0\\x88\\xc6\\x39\\x30\\xce\\xcc\\xe7\\xc6\\x6c\\xb4\\xd2\\x42\\xc0\\x27\\xae\\x10\\x59\\xea\\x2f\\xe7\\x6d\\x68\\x71\\x48\\x21\\x42\\x39\\xae\\xeb\\x8a\\x07\\xa0\\xb1\\x76\\x67\\xaa\\x4f\\xa8\\xcd\\x71\\x46\\x30\\x64\\x97\\x83\\xe0\\xa0\\xef\\x8f\\x3a\\xb5\\x39\\x73\\x3e\\x6e\\x24\\x1c\\x8d\\x0e\\x89\\x3c\\xef\\xc6\\x93\\x24\\xcb\\x69\\x09\\x04\\x2a\\x27\\x16\\xc4\\x04\\x89\\x01\\xb2\\xc8\\x5b\\x75\\x84\\xcb\\xfb\\xd5\\xda\\x3b\\xbc\\x85\\xad\\xb6\\x43\\x10\\x84\\x55\\x1f\\xdf\\x14\\xc2\\xd8\\xf7\\x7d\\x62\\x87\\x69\\x30\\xee\\xe6\\x8e\\x72\\x8f\\x1b\\x22\\xec\\x2b\\x1f\\xb5\\x37\\x76\\x25\\xe5\\x4b\\x32\\x75\\x06\\x92\\x3e\\x7e\\x2f\\x8c\\xee\\x1c\\xbd\\x89\\xfa\\x39\\x18\\x6f\\x82\\x42\\x58\\xed\\x59\\x8a\\x07\\x9c\\x56\\x77\\x20\\xf2\\xcd\\xe6\\xec\\x29\\xb3\\x91\\xc9\\x68\\x7e\\x67\\xb5\\xe2\\xbc\\xb3\\xbb\\xe7\\xcf\\xee\\x75\\x12\\xfa\\x8b\\x33\\x76\\xf0\\xaa\\x7e\\xa0\\x14\\xda\\x9f\\xb7\\xe7\\x92\\xa1\\x6e\\x0a\\xf0\\x46\\xbe\\xf6\\x2b\\x18\\xcd\\x88\\xea\\x42\\xd2\\x20\\x80\\xf1\\x42\\x9c\\x57\\xf9\\x96\\x9d\\xf3\\x8d\\x01\\xaf\\xef\\x77\\xe6\\x43\\xcc\\x39\\xce\\xfb\\x77\\x12\\xd1\\x08\\xb5\\x4d\\xf8\\xda\\xe6\\x53\\x2d\\xfc\\xf6\\x54\\x5f\\x6f\\x56\\x7a\\x1b\\x04\\xf6\\x69\\x91\\x8f\\x51\\xe4\\xbb\\xa0\\x84\\x44\\xbc\\x93\\x5f\\xde\\x18\\xeb\\x37\\x62\\xec\\x0c\\x87\\x20\\xb4\\x71\\x22\\xba\\x13\\x74\\x7c\\x37\\x4e\\x21\\xc8\\x34\\x00\\x51\\xaf\\x72\\x9c\\xb1\\xfe\\x24\\x2c\\x02\\x16\\xde\\xe8\\x95\\x41\\x35\\xf0\\x55\\xc8\\xf6\\x8d\\xa7\\x21\\xf6\\x61\\xdb\\x47\\xff\\xbb\\xd7\\xf4\\xe6\\x0f\\x1c\\xbf\\x12\\x24\\x9f\\xb3\\x2e\\xfa\\x06\\x39\\xa4\\x13\\x90\\x41\\x85\\x44\\x1e\\x8d\\xa2\\x72\\xe2\\xc5\\x0e\\x1a\\x93\\xa3\\x15\\xde\\xd1\\xd9\\xc9\\xe6\\xef\\x9c\\x30\\x76\\x2e\\xe1\\x4a\\x55\\xfe\\x5a\\x3d\\x0d\\x86\\xfb\\xbe\\x19\\xe2\\x1c\\xa3\\xf5\\x59\\x02\\x9f\\x01\\x46\\x9a\\xa7\\x29\\x6f\\x85\\x72\\xf0\\x18\\xbf\\xd2\\x6f\\x2e\\x7a\\x95\\x53\\xd4\\x0d\\x08\\x54\\xdf\\x06\\x2f\\x80\\x44\\xa2\\x20\\x9d\\x2d\\xbb\\x37\\xa7\\x66\\x1e\\x3e\\x74\\xae\\x00\\x39\\xcb\\x2a\\x94\\x58\\x0a\\x2f\\xf6\\xa1\\xc6\\xfc\\x39\\x43\\x70\\x33\\x04\\x2a\\x96\\x59\\x38\\x6f\\xab\\x61\\xec\\x3e\\xda\\x4e\\x44\\xcc\\x71\\xf4\\x36\\x54\\x45\\x8e\\xc0\\x32\\xe5\\x86\\x8c\\x93\\x1d\\x8e\\x6a\\x14\\x70\\xb5\\x11\\xfc\\x3e\\xff\\x79\\x1e\\x51\\x1f\\xa7\\xe8\\xd4\\x25\\x53\\x00\\xa0\\x50\\x05\\xc1\\xf0\\x19\\xb6\\x7c\\x99\\xd2\\x6c\\xa1\\xab\\x2d\\xf2\\x0f\\xa4\\xa1\\xd3\\x6d\\x83\\x82\\x81\\x92\\xcd\\x7b\\xb4\\x2a\\x87\\x97\\x4f\\x4f\\x05\\xcf\\x2f\\x86\\xa5\\xbd\\x43\\x5b\\x8e\\xf1\\x69\\x16\\xd8\\xf4\\xf9\\x3e\\xdd\\x86\\xbf\\xe7\\xea\\xce\\x7c\\x53\\xe2\\x3e\\x1e\\x7f\\x7e\\x7e\\x3c\\xaf\\x62\\xfe\\xab\\xbd\\x78\\x28\\x4f\\x62\\x65\\x72\\x94\\x7b\\x60\\x9a\\x8d\\x1e\\x41\\xbe\\x32\\xd9\\xae\\x50\\x1f\\x31\\x55\\x2c\\x02\\xc5\\xca\\x87\\x2c\\x26\\xba\\x00\\x18\\xe9\\x7b\\x20\\xbd\\x53\\xb5\\xb2\\xe3\\x56\\x92\\xa9\\x4b\\x8f\\x9b\\x15\\xf0\\xb5\\x8d\\x8c\\x13\\x55\\xb1\\x53\\xfa\\xc8\\xa3\\x49\\x21\\x94\\xc6\\x67\\x05\\x99\\xa9\\x06\\xb0\\x5c\\x17\\x3b\\x91\\xdb\\x76\\x7d\\xf5\\x70\\x06\\xed\\x07\\xa3\\x63\\xdf\\x7f\\x3c\\xf3\\x5e\\x4e\\xc6\\xdd\\x48\\x9f\\x01\\xe4\\x66\\xed\\x66\\x34\\x78\\xc1\\x9f\\x79\\x36\\x43\\x34\\xc1\\xa0\\xe5\\x49\\x9e\\xd5\\xa2\\xe8\\x88\\x78\\x05\\xe0\\xea\\xb2\\x5c\\x54\\xca\\xc8\\x18\\xa7\\x96\\x88\\xd3\\x5b\\x6c\\xbb\\xcf\\xf3\\x27\\x77\\x22\\x27\\x24\\x13\\xbe\\x1c\\x70\\xa3\\xe4\\x56\\x26\\x23\\xf2\\x7c\\x04\\x79\\x30\\x31\\xc5\\x55\\x72\\xbf\\xf5\\xe8\\xf9\\xd1\\xec\\xf7\\xc9\\x42\\x02\\x22\\x6f\\x71\\xff\\xd4\\x1c\\x40\\xd1\\xca\\x55\\xf2\\x2d\\xb3\\x05\\x22\\xa3\\x7c\\xf5\\x7c\\xbd\\x13\\x14\\xf6\\x02\\x37\\xaf\\x1b\\xee\\x04\\xf3\\x47\\x6a\\x76\\x1b\\xc1\\x71\\x04\\x32\\x9a\\xa4\\xc8\\x8e\\x7b\\xd6\\x01\\x6e\\x10\\x00\\xd4\\x4f\\x3c\\xec\\xaa\\xf5\\xe1\\xef\\xd3\\x74\\xb1\\xbb\\x9e\\x23\\x37\\xce\\x10\\x09\\xb9\\x0c\\xcf\\x6b\\x2f\\xb2\\xdf\\x79\\xd7\\x09\\xf3\\x18\\x23\\xf2\\xac\\x16\\xe8\\xdc\\x8e\\x32\\xd5\\xf0\\x5d\\xa1\\x04\\x88\\x2d\\x18\\x58\\x18\\x7b\\xec\\xb2\\x7c\\xde\\xce\\xdf\\x9a\\xaa\\x0b\\x77\\x2b\\xcb\\xdf\\xf3\\x3e\\x33\\x7f\\x8e\\x99\\x9e\\x92\\xa6\\xdd\\xb5\\xaa\\x4e\\x26\\xd7\\xfa\\x24\\x49\\x96\\x45\\xda\\x82\\xf5\\x87\\x6f\\x87\\x5c\\xb4\\x4f\\x13\\x3a\\x80\\xcc\\xf6\\xfc\\x8a\\xcf\\xf0\\x2b\\x34\\xbf\\x9e\\xfd\\x15\\xbf\\xef\\x1e\\x58\\xb2\\x1c\\x91\\x7b\\x33\\xef\\x5d\\xd7\\xf5\\x5d\\x8e\\x00\\x43\\x41\\xaf\\xfe\\x8c\\x8b\\x1e\\xc7\\x05\\x3f\\xf1\\x55\\x7c\\x0f\\x68\\xd8\\xef\\xd3\\x7a\\x0d\\x3a\\xb6\\x72\\x76\\xfe\\x83\\x0b\\x56\\xb8\\x6a\\x72\\x70\\x35\\x34\\x18\\xe6\\x99\\x61\\x70\\x74\\x8b\\xfc\\x8a\\xf0\\x4a\\x04\\xb9\\x7a\\x40\\x03\\xfe\\x9c\\x5c\\xf5\\xa9\\x0e\\xde\\xaf\\xa7\\x10\\x5f\\xec\\x3b\\x50\\xa6\\xb1\\x4c\\x73\\x79\\x8d\\xcd\\x1f\\xac\\x0a\\x12\\xf4\\x27\\x45\\x29\\x6a\\xa9\\x95\\xb5\\x44\\x67\\x05\\x0a\\x58\\x46\\xcf\\xa5\\x50\\x11\\x8b\\x19\\x89\\x2e\\xc9\\xa3\\x92\\x7d\\x46\\x1c\\xba\\x56\\xdd\\x24\\x86\\xf4\\x2c\\xec\\xa7\\xbf\\x82\\x9a\\xf5\\x6f\\x36\\x20\\x12\\x4c\\xa9\\x9c\\x55\\x73\\x8a\\x9f\\x77\\xc2\\x56\\x21\\x9b\\xe9\\xfd\\xd5\\xc8\\xef\\x8c\\xf0\\x26\\x8c\\x20\\x18\\xf7\\xa4\\x82\\xc1\\xb5\\x1f\\xb6\\xcc\\xff\\xed\\xa1\\xbd\\x9f\\xa8\\x41\\x80\\x6b\\x32\\x51\\x26\\x3d\\xfd\\x99\\x56\\x31\\xcd\\xf6\\xd3\\x0d\\x88\\xb5\\x41\\xe1\\x6a\\xf5\\x69\\x9d\\xae\\x21\\x7a\\xa4\\x74\\xb0\\x78\\xed\\xc8\\x99\\x51\\x57\\x84\\xde\\x15\\x7f\\xeb\\x26\\xc1\\xa2\\x43\\xd9\\x80\\xed\\x19\\x26\\xe0\\x4b\\x0e\\xb1\\xbf\\x54\\x77\\x9e\\xec\\x9a\\x46\\x5f\\x08\\xd3\\xbe\\x13\\x4c\\x99\\xe3\\xb2\\x09\\x79\\x41\\x20\\x5a\\x34\\xe9\\xe5\\xc9\\x7b\\xe8\\xe4\\x2f\\x26\\x37\\xf5\\xa7\\xfa\\x2f\\xa7\\xfb\\xf6\\x11\\x33\\x73\\x37\\xb8\\x68\\x91\\xcf\\x0a\\xd6\\x89\\x0a\\x0d\\xdb\\x00\\x7c\\x08\\x04\\x03\\x27\\xca\\x99\\xbb\\x60\\xe4\\xd5\\x3a\\x60\\x01\\xb2\\xd6\\xb5\\x78\\xe9\\xf5\\xd3\\x07\\x2d\\xdf\\x80\\x83\\xa3\\x21\\x73\\x57\\x93\\xfb\\xdd\\xc7\\x33\\x9b\\xe6\\x29\\xa3\\xe1\\xaa\\xea\\x61\\xd0\\x27\\x0b\\x6d\\xf4\\xb7\\x50\\x22\\x15\\xb6\\xf4\\xb5\\xbf\\x72\\x19\\x1e\\x6b\\x04\\x4a\\x0e\\x5b\\x68\\x2b\\x61\\x10\\x10\\x75\\xbe\\xa6\\x79\\x92\\x18\\x28\\x4f\\x15\\xf2\\x77\\x07\\xb2\\x3b\\x63\\x8f\\xbf\\xba\\x38\\x51\\x7a\\xb7\\xd1\\x3e\\x5f\\xcc\\x4e\\xc0\\x22\\xeb\\x27\\x5a\\x7e\\x68\\xe2\\x08\\x55\\x68\\x7c\\xff\\xf8\\x0b\\x44\\x78\\x3b\\xb8\\xa6\\xf7\\xe1\\x5f\\x4d\\xed\\x43\\x3b\\x25\\x18\\xe1\\x26\\x1b\\x27\\x7b\\x1d\\xe9\\xb3\\xda\\x05\\xb2\\x89\\x72\\x95\\x0e\\x9a\\x9d\\x45\\xe9\\x60\\x6f\\x55\\xff\\xba\\x54\\x72\\x0e\\x3b\\x4d\\x0f\\x0e\\x92\\xd0\\x6d\\x0f\\x83\\x34\\x06\\xb5\\xd4\\x77\\xdb\\xd0\\x73\\x7b\\xd9\\xfb\\x7c\\xbe\\x07\\x9f\\x03\\xe5\\x10\\xef\\x95\\x60\\xaa\\xb9\\x1a\\x57\\x5f\\x51\\x66\\xa2\\xc1\\xda\\x75\\x0b\\x2b\\xf2\\xf1\\x02\\xfb\\x3f\\x1a\\xdf\\x67\\xd7\\x38\\x47\\xc7\\x30\\x3d\\xb1\\x0f\\xc2\\xf3\\xb0\\x64\\x7d\\x88\\x94\\x57\\xce\\x26\\x82\\x01\\x6b\\x0f\\x5b\\x46\\xf4\\xa3\\xda\\x0b\\xa3\\xdf\\x46\\x4f\\xcc\\x34\\xae\\x08\\x75\\x45\\x0c\\xce\\x7a\\x11\\x48\\x78\\xe7\\xac\\xd3\\x1a\\xd6\\x38\\x51\\xee\\x0d\\x39\\xab\\x47\\x2e\\x12\\xdd\\xeb\\xda\\x9f\\x95\\x8d\\x1c\\xd7\\xff\\xa3\\xea\\xba\\x76\\xdd\\xe6\\x99\\xed\\x03\\xe9\\x42\\xbd\\x5d\\xaa\\xf7\\xde\\x75\\xa7\\x2e\\x59\\xbd\\x59\\xe5\\xe9\\x0f\\x92\\x2f\\xd9\\xf9\\x8f\\x01\\x23\\x31\\xe0\\x4d\\x8a\\xe6\\x70\\xca\\x9a\\xe1\\x9a\\xef\\x79\\x88\\xe7\\x81\\x5a\\x84\\xb8\\xfb\\xd5\\x37\\x02\\x69\\xea\\x18\\xa6\\x84\\x14\\x31\\xa1\\xa8\\xae\\xec\\x8c\\xb5\\x13\\x00\\x33\\xcf\\xa6\\x8a\\x84\\x21\\xff\\xdd\\xbb\\x95\\xb4\\x1b\\x61\\xc0\\xf3\\x1b\\xd1\\x7d\\xaa\\x79\\xd8\\x45\\x7e\\x30\\xdb\\xad\\xcb\\x5f\\x72\\xf0\\x4b\\x17\\x4b\\x61\\x7f\\xc5\\x65\\x85\\xe6\\x31\\xfd\\x42\\xd8\\xfe\\x15\\xab\\xc5\\x9d\\xd8\\x0a\\x99\\xb3\\x63\\x72\\xd0\\xca\\xae\\x8a\\x33\\x7c\\xc2\\x0d\\xfc\\xe2\\xe5\\x39\\x26\\x57\\xb0\\xd0\\xa7\\x7a\\x03\\x26\\x00\\x02\\x08\\xba\\x85\\x1d\\x30\\xd9\\x06\\x22\\xd3\\xb6\\x0f\\x41\\x14\\x40\\xd7\\xfe\\x2d\\x3c\\x95\\x6e\\x61\\xef\\xb9\\xad\\xb8\\x5d\\xdb\\xf7\\xb9\\xd2\\xb1\\xf6\\x61\\xd8\\xf7\\xc7\\x07\\x95\\x12\\xef\\x13\\x64\\xbf\\x2c\\x87\\x7d\\x53\\xb9\\xd4\\x7d\\x76\\xe3\\xa0\\x0f\\x18\\x20\\x10\\x74\\x1b\\x16\\xd1\\x05\\x35\\x51\\x62\\xa1\\x1c\\x00\\x27\\x7b\\x02\\xe6\\x5a\\xe2\\xf9\\xbd\\x53\\xd7\\x02\\x3c\\x14\\xf3\\x0b\\xfa\\x09\\xf6\\x64\\x07\\x62\\x66\\xfe\\x83\\x12\\x37\\xf8\\xa2\\xa2\\x5c\\x58\\x1a\\x5e\\xa2\\xdf\\x2f\\x08\\x21\\x1f\\xaa\\xe6\\xb9\\xf4\\xd9\\x72\\x3e\\x23\\xf3\\xfa\\x8b\\xf8\\x1e\\x7d\\xfa\\x6b\\xe8\\xdd\\x2e\\xac\\xe2\\xa4\\x3a\\x4c\\xe0\\x2b\\xdc\\x88\\x9b\\xa6\\x83\\xc6\\x18\\xd4\\x0f\\x07\\xe2\\x28\\x5c\\x84\\xfc\\x05\\x01\\xbe\\x7a\\x8a\\x51\\xc5\\x76\\xa0\\xdf\\xf2\\x68\\x38\\x8e\\xf3\\x9b\\x45\\xc8\\xb1\\xa4\\xea\\x98\\x95\\x89\\x6e\\xe7\\x1e\\xbe\\xd4\\x35\\xaa\\x0b\\x9f\\xf1\\x0d\\x88\\xcf\\xd6\\xf5\\x40\\xe5\\x94\\x22\\x00\\x41\\x09\\x2d\\x77\\x5a\\x1d\\x6e\\x23\\x42\\xd8\\xea\\x16\\x75\\x1f\\xc8\\xf7\\x0f\\xe9\\xfc\\x9e\\xf5\\xa6\\x69\\x0f\\x31\\x71\\x20\\x48\\x4d\\xfe\\x9b\\x02\\xd4\\x31\\x4d\\x2d\\x74\\xd0\\x1d\\x44\\x77\\x54\\xec\\xa1\\x47\\x8e\\xac\\x25\\x88\\xb3\\xb2\\x21\\x4f\\xca\\xbf\\xb8\\xc8\\x5e\\x45\\x87\\x50\\x71\\x92\\xbc\\xcf\\x7a\\xe4\\x3e\\x00\\x49\\x47\\xbf\\x1c\\xcf\\x81\\x20\\xc8\\xba\\x50\\x51\\x9f\\x88\\xdc\\x4a\\xef\\xb8\\xfc\\xad\\xc8\\xe4\\xac\\xce\\xe1\\x4d\\xcf\\x0f\\x14\\x76\\x6e\\xda\\x6f\\xe0\\x0c\\x9c\\xd5\\x06\\xca\\xc6\\xb8\\xe2\\xd0\\x7b\\xd3\\x05\\x05\\xac\\x77\\x3e\\xc9\\x52\\x00\\xcb\\xed\\x17\\x88\\xc6\\x11\\xce\\xf6\\xd9\\x44\\xb5\\x13\\xef\\xb2\\x69\\x22\\xcf\\xf3\\xb7\\x9f\\x39\\xef\\xd7\\xc8\\xff\\x3a\\x33\\x20\\x5d\\x0c\\xf6\\xaa\\x6d\\xda\\x97\\xe1\\xa7\\xad\\x21\\x7f\\xf8\\x7b\\x8d\\x6b\\x95\\x2f\\x10\\x7c\\x1b\\x74\\x9f\\xd8\\xb2\\x15\\xf3\\x4d\\x4c\\x48\\x39\\x27\\xcd\\xb0\\x02\\x69\\x50\\x87\\x87\\x5b\\x00\\xbf\\x29\\x72\\x12\\x50\\x65\\xc9\\xbf\\xce\\x71\\x7f\\x88\\x28\\xa4\\xe7\\xa1\\xff\\xa5\\xd6\\xe2\\xa8\\x0d\\xb8\\x86\\xd3\\xd1\\xb6\\x36\\x04\\x20\\xcc\\x14\\x0a\\xb7\\x4e\\x94\\x32\\xe8\\xab\\xf3\\x7e\\xb9\\x67\\xd2\\xb2\\xe3\\xcc\\x0d\\x9e\\x50\\xd3\\x53\\xe7\\xb2\\x6d\\x24\\x80\\x27\\x50\\x41\\x4c\\xae\\xd8\\xda\\xc6\\x4e\\x58\\x1f\\x12\\xef\\x12\\xe0\\x2e\\xee\\x0b\\xd3\\xff\\x71\\x09\\x2e\\x4b\\x69\\x2f\\xf1\\x4b\\x92\\xa0\\x8e\\xd3\\x00\\xa0\\xde\\x41\\xba\\x68\\x27\\x8d\\x9c\\x19\\x41\\x00\\xc0\\xa1\\xea\\xf0\\x22\\xf2\\x53\\x2c\\x43\\x84\\x2e\\xc4\\x26\\x42\\x55\\x52\\x3b\\x47\\x29\\xff\\xd4\\xdf\\x5a\\x1f\\x8e\\x73\\xbe\\x85\\x3b\\xbe\\xf6\\x12\\xdd\\x68\\x30\\x41\\xb9\\xf7\\xa4\\xde\\x31\\x28\\x61\\x04\\xc0\\xb6\\x55\\x6a\\x9b\\xd0\\xa4\\xfd\\xee\\x8a\\x2a\\x10\\x31\\xf5\\xf2\\x44\\x72\\x88\\x1a\\x03\\x4c\\x31\\x9e\\xca\\xbe\\xe3\\xa9\\x2e\\x81\\x87\\x20\\x71\\x49\\x1d\\xd9\\xb7\\xf9\\xfe\\xf3\\x97\\x86\\x03\\xcd\\x89\\xcf\\x17\\xa5\\x9a\\x9e\\x1a\\x0b\\x5b\\xee\\x3b\\x71\\x3e\\x55\\xe3\\xe5\\xec\\x1b\\xb5\\x0f\\xb3\\x02\\x68\\x80\\x47\\xbf\\x5a\\x55\\xd1\\xb8\\xbe\\x9e\\xf2\\x7b\\x00\\xa0\\x1a\\xc6\\xf1\\xe7\\x5b\\xa2\\x0f\\x18\\x5c\\xec\\x46\\x41\\x30\\x80\\xa5\\x8b\\xd1\\x8f\\x9e\\x61\\x48\\x29\\x71\\x00\\x66\\xae\\x9b\\xd8\\x0c\\xc2\\x67\\xac\\x9f\\x04\\x40\\x03\\x1b\\xac\\x0f\\xdd\\xb5\\xe0\\xcf\\xe1\\x99\\xec\\x56\\x1e\\x5f\\xd4\\xd4\\xc3\\x13\\x55\\x5d\\x45\\x2d\\x82\\x7c\\xa0\\xeb\\x35\\x1b\\xf1\\x7d\\xf0\\xf2\\x85\\x02\\xb3\\xd0\\xfc\\x04\\x47\\x6a\\x29\\x1c\\xfa\\x53\\xab\\xa4\\x7e\\xec\\xa7\\x24\\x80\\x29\\xff\\x22\\xaf\\x0d\\xe1\\x23\\x85\\x22\\xf4\\x37\\x95\\x94\\x51\\x6a\\xdd\\xb3\\x85\\xac\\x8e\\xa0\\x71\\x55\\xd7\\x61\\x18\\x1c\\xcb\\xed\\xab\\x67\\xe3\\xe6\\x11\\xb5\\x9b\\x03\\x60\\xfa\\x45\\xf2\\x05\\xce\\xa5\\xbb\\x78\\x59\\xb9\\x3a\\x23\\x92\\x44\\xd6\\x68\\xf2\\x45\\xd9\\xa8\\xc8\\xb2\\xa8\\x10\\xbd\\x30\\x05\\x1a\\xcc\\x23\\xfc\\xac\\x4e\\x20\\x0c\\xd1\\x14\\x2e\\x83\\xd5\\x0b\\xc5\\x7c\\x02\\x2d\\xbf\\xc7\\xd5\\xec\\x40\\xc0\\x7c\\x47\\xd3\\x43\\x5b\\x92\\x20\\x8b\\x84\\x50\\x9c\\x6d\\x39\\xe6\\x63\\x36\\x08\\x73\\x74\\x69\\x1b\\xe8\\x14\\x31\\x5a\\x65\\x0c\\xfc\\x27\\x4f\\x63\\xa8\\xc3\\x65\\xd9\\x2f\\xb5\\xec\\xe8\\x42\\x4b\\x40\\xa7\\x89\\x68\\xec\\xe3\\xe8\\xca\\x5d\\x19\\x3f\\x37\\x70\\x38\\x9c\\x11\\x9c\\xc1\\xd9\\x37\\x46\\xe9\\xd4\\x41\\x61\\xfa\\x29\\x68\\x5d\\x63\\xfd\\xec\\x88\\xbf\\x36\\xfd\\x29\\xd1\\xd6\\x30\\xdb\\xbe\\xa8\\x97\\x12\\xf2\\x41\\x5a\\x49\\x27\\x51\\x3a\\x24\\x4a\\x9e\\x2b\\x39\\x43\\x41\\x28\\xcf\\x36\\x3f\\x2e\\xb2\\x50\\x0c\\xc3\\x78\\x92\\x71\\x3c\\xfa\\xc6\\x9b\\x9e\\xa7\\xb9\\x16\\xd2\\xd7\\x79\\x12\\xf5\\xa6\\xa1\\x25\\x7d\\x22\\x64\\x52\\xd9\\x32\\x1b\\x3e\\xca\\xba\\xd9\\x44\\x7c\\xf8\\x61\\x38\\xe0\\x68\\x1c\\xc7\\x83\\x59\\xd1\\x1c\\xc2\\x54\\xff\\xf4\\x5a\\xd6\\x11\\xe0\\xaa\\x8f\\x30\\x90\\x8e\\xcb\\x02\\x00\\x24\\x65\\xf3\\xb6\\x6b\\xfb\\x10\\xa0\\x5b\\xd5\\x4b\\x00\\xdb\\xa2\\xc3\\x2b\\xb4\\x3d\\x25\\x73\\x8d\\x14\\x54\\xd9\\x28\\xde\\xc1\\x00\\x59\\xb6\\x18\\x55\\xbc\\x51\\xf6\\x2e\\xed\\xe7\\x7d\\xbd\\x2f\\x1a\\x97\\xf0\\x1d\\x59\\xdd\\x4a\\x1c\\x2a\\x98\\x93\\xf8\\xa2\\x5b\\xce\\x4b\\x84\\x63\\xbb\\x9e\\xdb\\x1a\\x7a\\xdf\\x78\\xcb\\x4f\\x4c\\x65\\xc1\\x46\\x72\\x56\\xb1\\x3c\\xc1\\xf4\\x44\\xbf\\xe8\\xd4\\x0d\\xae\\xfe\\xb6\\x70\\x19\\x07\\xb0\\x59\\xd5\\x38\\x6e\\x48\\xeb\\x50\\x1c\\xb1\\x6e\\xd1\\xa3\\xec\\xc8\\xd6\\x4f\\x7f\\x21\\x9e\\xf3\\x99\\x17\\x91\\xf9\\x16\\x27\\x6e\\xc4\\x7d\\x2b\\xb9\\xc5\\x6a\\xf1\\x2d\\x96\\x07\\x58\\xd7\\x6d\\x79\\xf0\\x64\\x86\\x57\\x38\\x83\\x8f\\x3c\\xd6\\xf6\\xf1\\x45\\x4e\\xb7\\xa9\\x24\\x7f\\xb8\\x66\\xa9\\xfe\\xe5\\x73\\x09\\xa8\\x3e\\x80\\x49\\x9c\\xc0\\x74\\x54\\xa0\\xa0\\xa1\\x2d\\x6a\\x12\\x94\\x58\\x86\\xfb\\xb9\\x0f\\x96\\x15\\xd4\\xab\\x5f\\x49\\xdc\\xb2\\x75\\xfe\\x46\\xdb\\x81\\xc0\\xc5\\x1c\\x8a\\x6e\\x10\\xa6\\x5f\\x3a\\xed\\xf7\\xa9\\xef\\x3d\\x53\\xa6\\x6f\\x0a\\x2b\\x2c\\x7f\\x36\\x22\\xf1\\xcb\\x06\\xa3\\x77\\x48\\xbe\\xda\\xf7\\x5c\\x43\\x6d\\x2f\\xb8\\x95\\xe1\\x8a\\xc6\\x7c\\x69\\x3a\\xf2\\xfb\\x5e\\xa1\\xf3\\xc8\\x85\\xf9\\xc3\\x1d\\xc4\\x5d\\xe3\\x42\\x24\\x48\\x8e\\x62\\x70\\x45\\xc9\\x75\\xca\\x15\\xa3\\x3a\\x67\\x72\\x7b\\xf9\\x60\\x5e\\xd6\\xed\\xae\\xd1\\xc9\\x77\\x7a\\xc3\\x67\\x89\\x8e\\xcd\\x43\\x46\\x8e\\x5a\\x64\\x17\\x2a\\x6c\\x9a\\xbd\\x28\\xc8\\x34\\x5e\\xc3\\x17\\x17\\x74\\xb2\\x97\\x6e\\x4b\\x3f\\x07\\x01\\x56\\x0a\\x90\\x27\\x7d\\x3b\\x0d\\x04\\x7e\\x9c\\x1c\\x15\\x1f\\x4b\\xed\\x8f\\x71\\xae\\xf5\\x49\\x19\\x6b\\x43\\x76\\x44\\xdb\\x97\\x27\\xc1\\x2a\\xc9\\x2a\\x6f\\x0d\\xad\\x69\\x83\\x10\\x1b\\xe3\\x59\\x0c\\xab\\xac\\x27\\xcd\\x5a\\x50\\x7c\\x23\\x0d\\x8d\\xf0\\x33\\x1d\\x3f\\x54\\x49\\x36\\x19\\x78\\x9f\\x26\\x84\\xa2\\x79\\xd7\\xb2\\x16\\x69\\x33\\x49\\xf8\\x53\\xdf\\x62\\x28\\xe5\\x6e\\x7e\\xbf\\x14\\xf7\\x50\\xa2\\x43\\x88\\x28\\x58\\x6c\\x29\\x26\\xbd\\x20\\x51\\x5a\\x23\\x61\\x87\\xed\\x41\\x7f\\x33\\xe4\\x37\\x0b\\xcb\\x4c\\x0c\\x68\\x88\\x7d\\x43\\xbc\\xbd\\xf1\\xc1\\x50\\x7b\\xa0\\x22\\x79\\x98\\x20\\xcd\\xee\\xc6\\xa8\\x5f\\xfe\\x4c\\xaa\\x63\\xb2\\xe7\\x6d\\x65\\x0f\\x22\\x35\\xbb\\x5f\\x5c\\xd8\\xad\\xa0\\x6f\\xba\\x70\\x06\\x54\\x72\\x3b\\xac\\x39\\xe1\\x66\\xc8\\xba\\x0e\\x68\\x08\\x95\\x1c\\x9e\\xc3\\xc7\\x5b\\xa8\\xb2\\xaa\\x59\\x2f\\x76\\x17\\xd5\\x9b\\x50\\x95\\x2d\\x7f\\xc0\\x1a\\x99\\xfc\\x8d\\xcc\\x9c\\x9a\\x0b\\x5a\\x6f\\x38\\xf2\\xd8\\xc4\\x62\\x8e\\x22\\xe0\\x12\\xd1\\xcf\\x13\\xcb\\x2c\\x78\\x85\\x5b\\xb7\\xf9\\xa9\\xfb\\x34\\x98\\x02\\x3d\\x16\\x10\\x33\\x3a\\x37\\x01\\x6d\\x0a\\x1b\\x1b\\x08\\x39\\xea\\x38\\xc3\\x96\\x80\\xc0\\xde\\x6c\\x5c\\xb6\\x08\\x5e\\xf2\\xff\\xda\\x4c\\xf6\\x89\\xbb\\x7f\\x55\\x41\\x39\\xe4\\xda\\x46\\x39\\xe2\\x0b\\x82\\x01\\x51\\x5a\\x93\\xbf\\xa0\\x56\\xca\\x2b\\x43\\xd9\\x67\\x47\\xd6\\x7e\\x30\\x44\\x0b\\x73\\x97\\x3d\\x42\\x4b\\x92\\x41\\xa4\\x39\\x51\\xd5\\x37\\xb5\\x27\\x07\\x3e\\x66\\x80\\xe4\\x16\\x20\\x6b\\x79\\xcd\\xa2\\xbf\\x4b\\xcd\\x84\\x41\\x70\\x42\\x2f\\x1f\\xf1\\x3d\\x23\\xce\\x3d\\x5c\\x8a\\x06\\xdc\\x57\\x72\\xeb\\x61\\xf3\\x77\\x1f\\x5d\\xf2\\x04\\xbf\\x36\\x2a\\x3f\\x8b\\x3e\\x9d\\x0c\\x3d\\x1d\\xf4\\x92\\x45\\x61\\x8f\\xfa\\xf8\\xd7\\x16\\xfb\\xce\\x2d\\x4b\\x00\\x0d\\xc3\\x30\\x0a\\x75\\xee\\x64\\x7e\\x38\\x6f\\x24\\x46\\xa3\\x80\\x71\\x2f\\x66\\x3c\\xd0\\x8e\\x38\\x87\\xef\\xd3\\xbe\\x8b\\x17\\xa3\\xc0\\x85\\x42\\x7f\\xad\\xa1\\x0b\\x4c\\x3e\\x38\\x23\\xd3\\xf4\\x43\\xf8\\xd8\\x0e\\x77\\xf3\\x33\\x4f\\xab\\x7d\\xe1\\x36\\xfc\\x06\\xb2\\x79\\x07\\x32\\x79\\xd0\\xf9\\x15\\x59\\x5b\\x1f\\xd5\\xa5\\xb2\\xda\\x22\\x32\\xf1\\xde\\xb7\\xdb\\x9a\\x3d\\x0a\\xb4\\x50\\xf8\\x44\\xe7\\xec\\x01\\x50\\x93\\x6c\\xf6\\xe7\\x82\\x4c\\x3a\\x40\\xcc\\xcf\\x2f\\xa5\\xe4\\x40\\x26\\x9d\\x88\\xcc\\x25\\xad\\xb0\\x34\\xf1\\x45\\xc1\\x37\\x94\\xcd\\x5f\\x8f\\xc9\\x5f\\x94\\xc5\\xb7\\xd8\\xb9\\x51\\xa0\\x30\\x8f\\xd9\\x1e\\xcf\\xd5\\x87\\xac\\xf0\\xd3\\x1f\\xa7\\x6e\\x9a\\x0a\\x72\\x39\\xce\\x73\\xc0\\x90\\xc5\\xe8\\x18\\xec\\x87\\xaf\\x99\\xeb\\x46\\x94\\x9e\\x86\\xbc\\x04\\x31\\x60\\xf2\\x17\\xcc\\x64\\x21\\xb0\\xe0\\xa9\\x78\\xa6\\xe1\\x30\\xfc\\xed\\xab\\x36\\x01\\xd7\\x18\\x2d\\x7f\\x01\\xdb\\x05\\x6c\\x74\\xbd\\x94\\xc2\\xea\\x1d\\x3a\\x13\\xfb\\x9c\\xe3\\xed\\x94\\xd8\\x14\\x7c\\x82\\x19\\xef\\xfe\\x5a\\xbf\\x8b\\x54\\x7a\\xdc\\xfe\\x08\\xb7\\xe9\\x47\\xe1\\x9b\\xa6\\xb1\\x77\\x30\\xc5\\x68\\x77\\xf4\\x0a\\x53\\x5e\\xfa\\xbe\\x1f\\xa5\\xa2\\x50\\xf3\\x00\\x0a\\x38\\x0b\\x9e\\x9a\\xfa\\xea\\xfb\\x70\\xff\\x9a\\xa5\\x0c\\xdd\\x40\\x61\\xb9\\x79\\xd3\\x40\\x08\\x40\\xe9\\x0b\\xdf\\x88\\x6d\\x6d\\x56\\xaa\\xed\\x83\\xb6\\x37\\xdb\\xae\\x98\\x52\\xa4\\xfc\\xcd\\xc6\\xa6\\xfe\\x72\\xa8\\x9a\\x42\\xba\\x01\\x7b\\xac\\x6d\\x00\\x29\\xc7\\x75\\x5d\\xe7\\xfc\\x97\\x1d\\xa6\\x14\\x18\\x8a\\x1c\\x79\\xfc\\xd7\\x67\\xc9\\x45\\x31\\x8b\\x6b\\x9b\\xab\\xb0\\x75\\xf0\\x93\\xbb\\x50\\x26\\xfd\\xf2\\x0f\\xbd\\x95\\xda\\xc3\\xf5\\x1b\\x92\\x71\\x86\\x4f\\x1c\\x91\\xa3\\x55\\x76\\x21\\x08\\x84\\x8c\\x44\\xba\\x74\\xab\\x9a\\x6c\\x65\\x86\\x4f\\x99\\x47\\x6c\\xe7\\x49\\x4c\\xfd\\x3a\\x04\\xeb\\x10\\x28\\x8b\\xa8\\xa8\\xac\\x7e\\x57\\x9c\\x92\\x75\\x58\\xca\\x61\\xa1\\xb3\\xde\\x71\\x0f\\xe3\\xb7\\x15\\x7f\\x73\\xa9\\xab\\x07\\xce\\xb9\\xca\\x07\\x04\\x73\\x58\\x76\\xdb\\x35\\x19\\xe4\\xb2\\x3b\\xe8\\x6f\\xa1\\x6f\\x75\\x99\\xc4\\x75\\x42\\xfa\\x19\\x19\\x87\\x76\\x78\\xc6\\x66\\xd5\\xaf\\x1e\\x5e\\x41\\x71\\x9a\\xf3\\x59\\xfe\\x7a\\x99\\xff\\x44\\xce\\x3a\\x04\\xf3\\x98\\x80\\x22\\xa6\\xb3\\x99\\xee\\x72\\x9a\\xeb\\xe9\\x3e\\x24\\x7c\\x58\\xb5\\x5f\\x92\\x3d\\x72\\x67\\x85\\x65\\x73\\x8a\\xf4\\xcb\\xbd\\x12\\x69\\xb1\\x4d\\xc1\\x97\\x1b\\x23\\xeb\\x87\\x88\\x5d\\x77\\x1d\\xcd\\xf6\\x29\\xee\\xa1\\x07\\x6a\\xfa\\x26\\xf8\\xf9\\xee\\xbe\\x4c\\x83\\xdf\\x67\\xac\\x10\\x66\\xe4\\xc3\\x7c\\xe1\\x6a\\xf2\\x6d\\xad\\x72\\xc8\\x40\\xd9\\xfa\\x94\\x84\\x3e\\xb2\\x08\\x40\\x7d\\xee\\x89\\xad\\xb5\\x6e\\x45\\x8e\\xb7\\xc0\\x26\\x87\\xa0\\xd0\\xd1\\xe5\\x36\\x10\\x6c\\xdb\\xf3\\xec\\x89\\x66\\x7c\\xda\\xe3\\x68\\xff\\xf0\\x04\\x3b\\xc7\\x89\\x57\\x08\\x35\\x92\\xf0\\x9b\\xe3\\xa0\\x89\\x96\\xdc\\xf3\\x22\\xd1\\x1b\\x08\\x40\\x95\\x7c\\xe4\\x56\\x20\\xec\\xea\\x88\\x9e\\xd7\\xa6\\xb5\\x7b\\xb0\\x3e\\x4c\\xed\\xaf\\xe5\\x86\\xe4\\xba\\x65\\x1b\\xe6\\xdd\\x51\\xc1\\x63\\xfb\\xe6\\x4b\\x9a\\xed\\x4d\\xcc\\xfd\\xf3\\x93\\xbb\\x60\\xd9\\x38\\xa7\\x81\\x85\\xaa\\x25\\xb5\\xd9\\x9e\\x00\\x8d\\xc8\\x2f\\x21\\x7e\\x46\\x2a\\xee\\x16\\x6d\\x27\\x6f\\x68\\x11\\xc2\\x2e\\x77\\x33\\x94\\x97\\x77\\x09\\x69\\xb2\\x71\\x1d\\x1a\\xfd\\xcb\\x9d\\x5a\\xb7\\x6f\\x08\\xfd\\xcd\\xc5\\x20\\x58\\x1e\\x6d\\x2f\\x09\\xbe\\x0f\\xcc\\x98\\xf2\\xcb\\x8e\\xa9\\xff\\xe1\\xe8\\xc2\\x10\\x10\\x03\\x0d\\xa0\\xbb\\x06\\x28\\xda\\xa3\\xeb\\x15\\x72\\x1c\\x79\\x08\\x7b\\x28\\xb6\\xa7\\xc9\\xec\\x95\\x52\\x4f\\xa6\\xd1\\x07\\x0d\\x82\\xc2\\xe1\\x97\\xad\\xae\\x64\\x47\\xea\\x12\\x4e\\x44\\x32\\x38\\x5a\\xce\\x6c\\x5c\\x8a\\x3d\\x0a\\x37\\x46\\x83\\x1b\\x62\\x2a\\x89\\xb7\\xbc\\x01\\xd8\\x0d\\x47\\x70\\x7f\\x9a\\x3f\\xb8\\x37\\x6b\\x00\\x17\\x08\\xa9\\xac\\xa6\\x36\\x1b\\xbd\\xfb\\x01\\x7c\\x64\\xc8\\x91\\xcf\\x71\\x5a\\xcf\\x1f\\x77\\xb7\\x4a\\x01\\x97\\x50\\x23\\x22\\x80\\x4f\\xee\\x77\\x44\\xde\\xf9\\x6b\\xca\\x86\\x0f\\x83\\x46\\x78\\x7d\\xac\\xaf\\x4f\\x3e\\x20\\x85\\xbd\\x8e\\xcc\\x62\\xa5\\xe4\\x52\\xd5\\x6c\\xfc\\x2f\\x46\\x20\\x38\\xaf\\x41\\x5a\\xb4\\x0a\\xee\\x11\\x51\\xc4\\x65\\x3e\\x95\\x53\\x8a\\xd7\\x39\\x99\\xe5\\xd6\\xa8\\xda\\xd6\\xb3\\xec\\xd6\\xe6\\x6d\\xda\\x1c\\x99\\x2a\\x59\\x45\\x1f\\x0d\\x6f\\xb8\\x58\\x60\\x45\\x37\\x62\\xdd\\x89\\xe0\\xae\\x14\\xa0\\x80\\xb8\\xac\\x16\\x83\\x9a\\xfd\\x7f\\x63\\x7a\\x24\\x4d\\x12\\x61\\x5c\\x3c\\x94\\x3b\\x48\\xc1\\xb1\\xa5\\x48\\xb5\\xa2\\xcd\\x47\\x47\\x69\\xbd\\xb0\\xde\\xfa\\xb4\\xec\\x13\\x9c\\xe6\\x6e\\x6a\\xb5\\xa5\\xc6\\x30\\x1d\\x1e\\x23\\xe9\\x3e\\x73\\xa9\\xdd\\xf3\\xad\\x4c\\x45\\xde\\x96\\xb8\\xb9\\x64\\x5d\\xf9\\xf0\\xd4\\xa2\\xff\\xe9\\x57\\xe5\\xbc\\xeb\\xe4\\x83\\xae\\xe1\\xf7\\x57\\x52\\xac\\x5a\\x36\\x1e\\x1b\\x42\\xc7\\xa5\\x01\\x65\\x0d\\x59\\x26\\xd3\\x88\\xa4\\x04\\xca\\xb2\\x38\\xa2\\x9d\\x7a\\x8d\\x96\\x03\\x4b\\x4d\\x6a\\xed\\x13\\xe1\\x83\\x6c\\xba\\xd5\\x5d\\x73\\x23\\x1f\\xbf\\xac\\x11\\xe7\\x54\\x3e\\xcc\\xbe\\x03\\x27\\xff\\x60\\x91\\x11\\xaf\\xa7\\xa4\\x8d\\xf1\\x76\\x92\\x94\\xef\\x39\\x40\\x7a\\xa8\\xc6\\x31\\xfe\\xb1\\xba\\x5a\\xce\\x12\\xc4\\x84\\xdd\\x96\\xbc\\xdb\\xc0\\xda\\x0c\\x78\\xe2\\xa4\\xf4\\x77\\x7d\\xc9\\x2f\\xfb\\x81\\xd0\\x0d\\xc9\\x93\\x07\\x31\\x04\\x6b\\xcf\\xdb\\x4e\\xb5\\xd8\\xc6\\xec\\x0c\\xc8\\x7f\\x22\\xd1\\x88\\x9d\\x25\\x7f\\xa0\\xe8\\x53\\x64\\x86\\xad\\x29\\xfb\\x03\\xc1\\xe6\\x1b\\xc0\\xa6\\x9f\\x2b\\x7b\\x00\\x52\\x0f\\x8d\\xbc\\x36\\xb2\\xde\\x67\\x60\\x9c\\x65\\x53\\x4d\\x0c\\xb8\\x8b\\x52\\x36\\xe3\\x6f\\xa6\\x6e\\x11\\x7c\\xa4\\x55\\x08\\x97\\xdf\\xc2\\xae\\xa6\\xef\\x86\\xfb\\x3b\\x69\\xb2\\xc4\\x4c\\x3f\\xce\\x3f\\x59\\x56\\x94\\x45\\xc0\\x6a\\xcb\\x4d\\x02\\x87\\x3c\\x68\\xb8\\x84\\xca\\x29\\xc3\\x51\\x17\\x1f\\xe7\\xf4\\x31\\xd9\\x09\\x26\\x81\\xe1\\x34\\xac\\x32\\x79\\x6d\\xb7\\x74\\x0b\\xf5\\xfa\\x08\\x4c\\xfb\\xfb\\x3b\\x31\\x47\\x7e\\x78\\x1c\\x0d\\xe9\\xbc\\x46\\xe4\\x88\\xd1\\x02\\x89\\xfc\\xa9\\xc1\\x62\\x3e\\x93\\x53\\x3c\\x5d\\xe8\\xb5\\xf1\\x46\\x68\\xeb\\x7a\\x6c\\x11\\x6c\\xfa\\xce\\x1e\\x95\\xae\\x8c\\x05\\xe2\\x35\\x5e\\xc4\\xe1\\x8d\\x41\\x04\\xa6\\x86\\xc0\\x62\\x55\\x3c\\xa9\\xeb\\x3e\\x1f\\x33\\xe6\\xc0\\x52\\x30\\x2c\\x79\\xb4\\x04\\x7b\\xde\\xa1\\x1f\\xfa\\xbf\\xce\\xbc\\x7d\\x99\\x3c\\xb8\\x13\\x0e\\x9f\\xef\\x5f\\xdd\\xcf\\x29\\x31\\xf7\\xcd\\x61\\xda\\x75\\x69\\x29\\x0c\\xc3\\x70\\xaf\\xd3\\xaf\\x33\\x7f\\x5e\\xc3\\xc2\\x31\\x0c\\xfd\\xc4\\x73\\x8b\\x75\\x2b\\xf4\\xb5\\x65\\xf8\\xe6\\xd7\\x58\\x92\\x50\\x00\\xfc\\x12\\xe7\\xf6\\x54\\x1b\\x2c\\xca\\xd7\\x90\\x3f\\xa2\\x78\\xfe\\xeb\\x8f\\xa7\\x60\\x90\\x6c\\x5c\\x2b\\xb0\\x77\\x1f\\xc1\\xf7\\x0f\\x3b\\x47\\xf8\\x4f\\xe6\\x0d\\x04\\x1c\\x7f\\xd0\\x52\\x16\\xb6\\x5c\\xac\\x40\\xa8\\xac\\x2b\\xc8\\x4f\\xfc\\x0d\\xbf\\x24\\xed\\x8e\\x58\\x57\\xcc\\x22\\x7c\\xc9\\xa2\\x65\\x1d\\xc6\\x50\\x6c\\x6d\\xd9\\x78\\x77\\xa2\\xb2\\x0f\\xd4\\xfe\\x6a\\x2c\\xb5\\x1b\\xd7\\x1f\\x8c\\xdd\\xb9\\x8c\\xd7\\x20\\x0d\\xbe\\xe9\\x61\\x95\\x1f\\xcd\\x45\\x23\\xd1\\x08\\x1f\\x17\\xfa\\xea\\x21\\x6a\\xd5\\x5b\\xb8\\x38\\xa0\\x79\\x9f\\xa0\\x73\\xd1\\x5d\\x38\\xf5\\x52\\xb1\\xd9\\x87\\x79\\xd5\\xba\\x95\\x38\\xf3\\x05\\x8c\\x55\\xda\\x9b\\xf9\\xf6\\xa2\\x36\\xe5\\xb8\\xd7\\x5b\\xb9\\x98\\x7f\\x1c\\xe2\\xca\\xaf\\x73\\xcc\\xa9\\x1f\\xe5\\xbf\\x7d\\xce\\x2b\\xc4\\xec\\x7a\\x8d\\x59\\xde\\x50\\x4c\\x91\\x69\\x9c\\x73\\xfe\\xa1\\xb5\\x1d\\x3b\\xe2\\xcf\\x83\\x9e\\xf8\\xe4\\x25\\xcd\\x0e\\x8f\\x23\\x79\\x22\\x8f\\xae\\xec\\xc8\\xf1\\xe1\\xb0\\x98\\xfd\\x92\\xcf\\x34\\x72\\x52\\xc4\\xfd\\xe4\\x1e\\xe4\\xcb\\x17\\x70\\x9b\\x57\\x08\\x9b\\xe3\\x47\\xfa\\xfc\\x20\\x45\\x23\\x48\\xdc\\xf8\\xf4\\x65\\x34\\xe0\\xe4\\x57\\x8b\\x1f\\x9d\\x32\\xc7\\x24\\xa1\\x4e\\xd5\\xdf\\x97\\xfc\\xed\\x5c\\x75\\x5d\\xc7\\x45\\xac\\x9f\\x57\\xf3\\x11\\x99\\x1f\\xab\\x37\\xf2\\x12\\x1d\\x4f\\xfe\\x16\\xe6\\xb3\\x4e\\xcd\\x94\\x04\\xdf\\xf4\\x80\\x33\\x8c\\xd1\\xf0\\xe0\\x47\\x2e\\x1d\\xdb\\x41\\x4f\\xfb\\x2b\\x56\\xa9\\xc5\\xfb\\x1e\\xc4\\x97\\x69\\x5c\\x7e\\xe2\\xda\\x96\\xaf\\x75\\x70\\xa5\\x65\\x4b\\x87\\x07\\x08\\x1f\\x3d\\xfc\\x46\\x51\\x58\\xc6\\x2a\\x34\\x7a\\x8f\\x65\\x19\\x77\\xa4\\x4c\\xfe\\x37\\x79\\xe2\\xa7\\x91\\x7f\\xee\\x32\\x71\\x5a\\xfe\\x9f\\x5d\\xa5\\xd0\\x3b\\xe4\\xff\\xd3\\x39\\x48\\x49\\xd7\\x3e\\x6a\\x93\\xde\\xe5\\xbf\\x37\\x9e\\x44\\x14\\x37\\xda\\x8f\\xc9\\x82\\x38\\xe9\\x6f\\xa1\\x07\\xdb\\xda\\xb8\\x22\\x87\\x1f\\xc0\\x26\\x59\\x25\\x79\\x95\\x63\\x37\\x99\\x63\\x9e\\x2d\\x23\\x82\\x66\\x15\\x3b\\xfb\\xfc\\xd1\\x11\\xf3\\xbe\\xe0\\x7c\\x0b\\x41\\x50\\xd4\\x8f\\xde\\x2f\\x09\\x3e\\xb7\\x95\\x00\\x63\\x0c\\x2c\\xe0\\xfa\\x61\\xc7\\x84\\x03\\xae\\x2a\\xe7\\xbe\\xe1\\xda\\x06\\x68\\x9e\\x64\\x9a\\xee\\x0e\\x61\\x58\\x86\\x65\\x7c\\xd0\\x74\\x9d\\x64\\x6a\\x7b\\x23\\xda\\xdd\\x93\\x30\\xed\\xb3\\xb4\\x26\\xff\\xf5\\x25\\x35\\x2e\\x51\\xbb\\x6a\\x72\\xfb\\x5a\\xf6\\xf9\\x72\\x0f\\xc3\\x28\\x1f\\x97\\x2d\\x47\\xe8\\xef\\xc1\\x37\\x95\\x1f\\x99\\x4b\\x65\\xe9\\x0d\\x31\\x79\\x30\\x53\\x4f\\x2a\\xb5\\x59\\x24\\x56\\x71\\x28\\xac\\xf3\\x45\\xf5\\x21\\xaa\\x77\\x27\\xad\\x76\\x2e\\x24\\x43\\x7e\\x67\\xbc\\xb6\\xdc\\x39\\x3c\\xab\\x8a\\xef\\xe7\\x9f\\xfa\\xaf\\x59\\xfd\\x18\\x47\\x3c\\x51\\x32\\x47\\xc4\\x27\\x6a\\xa6\\x38\\xad\\x0d\\xde\\x1d\\x8a\\x89\\xb7\\xe8\\x70\\xec\\x07\\x47\\x0e\\xa3\\x51\\x8a\\x7d\\xe7\\xf3\\xeb\\xed\\xd8\\xf7\\x3a\\x04\\x40\\x79\\xa5\\xec\\x3d\\xf2\\x0c\\x39\\xb6\\x0c\\x19\\xeb\\xaa\\x65\\x4b\\xf1\\x97\\x43\\x83\\x8a\\xa2\\xa5\\x42\\x7d\\xf2\\x57\\x67\\xce\\xe3\\x32\\xa6\\x48\\x2a\\xb9\\x41\\x6e\\x83\\xa2\\x22\\x32\\x69\\x5c\\xa3\\xd4\\xb2\\x66\\xd2\\x2e\\xd4\\xa7\\x52\\x88\\x15\\x38\\x29\\xd4\\xd0\\x7a\\x0f\\x50\\x84\\xf4\\xd7\\x43\\x3f\\x8c\\xbb\\x3c\\xa2\\x71\\xa6\\xe2\\x70\\x66\\xd2\\x67\\x26\\xad\\xf7\\xa9\\xf4\\x7b\\x04\\xe1\\xde\\x92\\xdf\\x49\\x63\\x27\\x2d\\x30\\xbf\\x3f\\x7d\\x71\\x5d\\x99\\xc7\\x9f\\x43\\x70\\x81\\x93\\x4c\\x33\\x02\\xd8\\x56\\xbf\\x2c\\x6b\\xc9\\x36\\x02\\x0f\\xe9\\xbf\\x32\\x8c\\xdc\\x98\\x44\\xdb\\x69\\xe5\\x9a\\x2d\\x9c\\xba\\xf7\\xa4\\x34\\x5e\\xa8\\xc2\\x65\\x1c\\xa2\\x34\\xa8\\xad\\xeb\\xb9\\x79\\xa7\\x24\\x44\\x9f\\xde\\x91\\x80\\xa6\\x4a\\xa2\\xd4\\xb9\\xfe\\xe5\\x33\\x45\\x41\\x59\\x24\\xb6\\x29\\x44\\x0f\\x98\\x7b\\xc8\\x8f\\x8e\\x35\\x1b\\x56\\x64\\x33\\xed\\xa3\\xfc\\x58\\xa0\\x1a\\xa5\\x79\\x4e\\x95\\x10\\xac\\x47\\x17\\x89\\xa2\\x1f\\x57\\x2c\\x2e\\x7f\\x01\\x09\\xe8\\xac\\xd1\\x10\\x75\\xe1\\xb2\\xac\\x63\\x93\\xea\\x9e\\x58\\x98\\x41\\x18\\x10\\x3e\\x37\\xde\\x16\\x03\\xcf\\xff\\xd4\\x69\\x17\\xee\\x85\\x57\\xdb\\xd5\\x4f\\xe0\\x3b\\x16\\xfc\\x27\\x43\\x8e\\x25\\x8f\\xe8\\xbd\\xb0\\xf5\\xf5\\x6d\\x25\\xef\\x81\\xcf\\x5f\\xff\\xf5\\xd8\\x8a\\x73\\xdb\\x0a\\x80\\x13\\xf3\\x0a\\xf6\\x3c\\x22\\xd0\\x94\\x1e\\x9f\\x77\\xcd\\x46\\xb5\\x47\\x7d\\xef\\x04\\xa6\\x11\\x27\\x52\\xa3\\x32\\xfd\\x41\\x11\\x71\\xa5\\xfd\\x7b\\x7c\\x5c\\x56\\x59\\xe4\\x99\\xf4\\xbe\\xc3\\x4d\\xe2\\xb8\\xad\\xe2\\xc3\\xf3\\xae\\xf9\\x88\\x7f\\x4d\\x00\\x69\\x80\\x49\\xb2\\xc1\\xc4\\xb2\\x99\\x92\\xe3\\x63\\x12\\xdd\\x96\\xc7\\x58\\x84\\x71\\xaf\\xd0\\xa1\\x7b\\xe2\\x87\\x8e\\x2b\\xf4\\x20\\xa3\\xf0\\xd4\\xd1\\x8b\\x6e\\xb9\\x4f\\xab\\xfe\\xab\\x6d\\x57\\x14\\x5f\\x45\\xf7\\x77\\x0c\\x5e\\x15\\xc4\\x1b\\x60\\x22\\x81\\x6d\\x25\\xce\\x7b\\xcf\\x85\\xbe\\xc4\\xa3\\x68\\x8e\\x4a\\x12\\x3e\\x73\\x88\\x76\\xcd\\xf6\\xc5\\x08\\xa0\\x3c\\x97\\xa8\\x6f\\x2f\\xcb\\x45\\x8e\\x2d\\x42\\x0f\\xb2\\xa5\\x8e\\x10\\xf8\\x22\\x81\\xbb\\xd7\\x52\\x3a\\x56\\xbc\\xcf\\x2f\\xda\\x4f\\x6f\\x38\\x83\\x9d\\xa3\\x10\\x02\\x8b\\x4c\\x43\\x6b\\x99\\xac\\xba\\x79\\x61\\x42\\xb8\\x46\\xa1\\x35\\xd4\\xbd\\x62\\x32\\xb7\\x11\\x78\\x80\\x83\\x55\\x2e\\xf0\\x01\\xc1\\x6d\\xe4\\x33\\x52\\x23\\x5c\\x13\\xd6\\x3e\\x86\\xdd\\x66\\xd2\\xb0\\x44\\x79\\xb6\\x43\\x80\\x7d\\x0f\\x06\\x6d\\xd7\\xb5\\x8f\\x15\\x59\\x52\\xa9\\x3f\\x3d\\x90\\xd8\\xe6\\xb0\\x49\\x9f\\x21\\x45\\xec\\xab\\xdd\\x40\\x2a\\x8c\\x1e\\x33\\xcb\\xda\\xb6\\x92\\xe7\\xbd\\xa7\\xd2\\x48\\xa1\\x92\\x15\\xb1\\xd5\\x0b\\x46\\xfb\\x14\\xd5\\x3d\\xea\\x97\\x69\\x1d\\xb5\\x18\\xe7\\x06\\x9b\\x1a\\x10\\xd3\\x4e\\x44\\x43\\x59\\x8e\\x8f\\xbf\\x82\\x71\\x88\\x60\\x20\\x00\\x4c\\x3e\\x83\\x0d\\x7d\\x3f\\x19\\xcc\\x92\\x94\\xff\\xe6\\xd0\\xf5\\xb2\\x7d\\x5a\\x15\\x3a\\xee\\x8a\\xda\\x73\\x49\\xdd\\xce\\xf2\\x7b\\x7a\\xa3\\x69\\x00\\x91\\x16\\x6f\\xe7\\x1b\\x36\\x8d\\xb1\\xd4\\x3a\\x5c\\x6e\\x19\\x7c\\x48\\xf7\\x6b\\x7d\\xe1\\x61\\x2c\\x44\\x63\\x19\\x8c\\x28\\x46\\x4f\\x16\\x88\\xf8\\xbf\\x3a\\x35\\xd1\\x3a\\xb5\\x2b\\xa6\\x85\\x48\\xfb\\x47\\x87\\x54\\xd1\\x0d\\xc2\\x29\\x85\\x4b\\xdd\\x23\\xbe\\x3e\\x51\\x79\\x81\\xa1\\xa2\\xb8\\x2d\\xeb\\xef\\xa5\\x28\\x15\\xde\\xf4\\x6c\\x95\\xa3\\x15\\xfd\\xcd\\xac\\x5f\\xef\\xfd\\x5c\\xc7\\x62\\xc0\\x26\\x7f\\x79\\x83\\x32\\x85\\x7d\\xa6\\x8b\\xa4\\x7f\\xe3\\x7e\\x3e\\x2a\\x84\\x7b\\x2d\\x3f\\x54\\x1b\\x59\\x7d\\x12\\x78\\x20\\x2b\\xac\\x96\\x31\\x22\\xc8\\xd4\\x56\\x55\\x11\\x11\\x23\\xe1\\x09\\x61\\x75\\xaa\\xed\\xb7\\x82\\xaa\\x63\\xc1\\x6a\\x7d\\x01\\xf1\\x16\\xde\\x46\\xf7\\xf0\\x3a\\xc5\\x2b\\xba\\x23\\xee\\xb9\\x2b\\xf9\\x6e\\x0a\\xa5\\x21\\x66\\xc3\\xfb\\xb9\\x87\\xf3\\x51\\x4d\\x45\\x65\\x32\\x35\\x44\\x89\\xfc\\x01\\xc2\\x35\\xff\\xb5\\xe9\\xd6\\xb3\\xaf\\x4c\\xab\\x08\\x3b\\xfd\\x98\\x4a\\x81\\xfa\\x93\\x23\\x62\\x18\\x8e\\x02\\x23\\x80\\xd2\\x71\\x6a\\xb8\\xd0\\x10\\xbc\\xc1\\x1a\\xe1\\xd5\\x2f\\x51\\x22\\x4f\\xbc\\x76\\xd9\\xea\\x73\\x64\\x9b\\xc6\\x43\\x3f\\xb1\\x8d\\xf2\\xfa\\x08\\xba\\xaf\\x3d\\x05\\x7b\\x2d\\x59\\xbd\\xc8\\x8d\\x98\\x9f\\x04\\xd5\\x07\\x02\\x98\\xd7\\x6c\\x0c\\xd3\\x24\\xe2\\x38\\x8e\\x08\\x7b\\xbf\\x28\\xa3\\x29\\xae\\xc0\\x67\\x8d\\xa0\\x01\\x03\\xce\\x59\\xf1\\xc6\\x54\\x1a\\xb3\\x3a\\x86\\xf9\\xe2\\x8c\\x37\\xa2\\xfb\\xe6\\x30\\x1b\\x0e\\x89\\x46\\xa1\\xe5\\x07\\xab\\x78\\x26\\x98\\x1b\\x6c\\x56\\x7f\\xf2\\x71\\xfc\\x67\\xb2\\xda\\x81\\x04\\x24\\x51\\x53\\x16\\x2f\\x84\\x2b\\xb4\\xb6\\xa7\\x47\\x0d\\xce\\x68\\x9f\\xc4\\xb0\\x90\\xbf\\x44\\x04\\x65\\xfc\\x77\\xab\\x41\\xe0\\x39\\xe4\\x81\\xaa\\x3c\\xe9\\x1b\\xdc\\x22\\xfe\\x6b\\x4f\\xfd\\x00\\x35\\x11\\xfa\\xab\\xaf\\x04\\x32\\xce\\x83\\xbe\\x7d\\x9b\\xb4\\xbe\\xfa\\x01\\x95\\x02\\xd1\\x24\\xff\\xa0\\xc0\\x1c\\xcf\\x2b\\x80\\xe1\\x76\\xaa\\x4b\\x7c\\xf9\\xf3\\x4b\\x1c\\xf9\\x96\\x46\\xe1\\x90\\x22\\x65\\x1c\\xc1\\x07\\xe9\\x13\\xf5\\x87\\x48\\xb6\\xe4\\x50\\x61\\xa2\\x1c\\xab\\xa3\\xaa\\x29\\x0c\\xf5\\x83\\xa3\\x8e\\x7b\\x63\\x5e\\x3e\\xf3\\xb7\\xcc\\x14\\x96\\x4d\\x8e\\xf5\\x79\\xbf\\x39\\xca\\x93\\x60\\xe9\\xf7\\x76\\x8f\\xc1\\x71\\x41\\xf4\\xd4\\xe0\\xb0\\xb8\\x63\\xd8\\xdb\\x1f\\xee\\x03\\x9e\\x55\\x72\\x84\\xaa\\xdd\\xa2\\x53\\x11\\x00\\x46\\x4e\\x1a\\x59\\x42\\x59\\x7d\\x8a\\x49\\x5d\\xb3\\x6e\\x2d\\xfd\\xc1\\xf0\\x67\\xf7\\xca\\xd7\\x77\\xbf\\xe3\\xe3\\xa8\\xec\\x78\\x1b\\x63\\x18\\xc3\\x0e\\x7e\\xf5\\x53\\xdf\\xea\\xb8\\xa8\\xcb\\xc2\\x61\\x48\\x45\\xa7\\x11\\x52\\x71\\x1c\\xa5\\xcf\\xa0\\x2e\\x83\\xc2\\x33\\x90\\x6d\\xbe\\x09\\x12\\x30\\x6b\\xc4\\x7a\\x6f\\xf2\\x1f\\xbe\\xc4\\x74\\xaa\\x2b\\xa9\\x73\\xa5\\x38\\x84\\xae\\x70\\x6b\\x36\\x85\\x30\\xfd\\xeb\\xf7\\x46\\xda\\x35\\x9b\\x32\\x12\\x75\\x5d\\x41\\x33\\x40\\x68\\x33\\x63\\x38\\x46\\xd0\\x4b\\xc6\\x2f\\x95\\x64\\x8f\\x79\\xee\\x92\\xae\\x7f\\x7c\\x15\\x07\\x2d\\xf8\\xd8\\x72\\xf3\\x08\\x95\\x56\\x16\\x81\\xa4\\x47\\x61\\x5a\\x64\\x84\\xa1\\x01\\xd1\\xbf\\x79\\xd2\\x0f\\xad\\xa2\\xeb\\x0b\\xaa\\xfd\\xfb\\xb9\\x95\\xfe\\xf4\\x51\\x00\\x84\\x81\\xfa\\xd1\\xdc\\x51\\x5d\\xb3\\x49\\x25\\xaa\\xf4\\x73\\xe2\\x9c\\x90\\x8e\\x60\\xfc\\x25\\x47\\x1a\\xf4\\x61\\xa9\\xba\\x23\\x93\\xac\\xf2\\x26\\xee\\x20\\xde\\x39\\x04\\xa6\\x11\\x98\\x25\\xd2\\x9c\\x76\\x8d\\x36\\x6c\\x54\\x9f\\x98\\xc1\\xb0\\x29\\x23\\x35\\x26\\xd4\\x18\\xb1\\xf8\\xd3\\xb0\\x97\\x71\\xab\\x63\\xf8\\x46\\x1c\\x83\\x8c\\x04\\x02\\x7c\\x57\\xe9\\xdc\\x3e\\x58\\xc2\\x0b\\xb8\\xed\\x63\\x21\\xa7\\x84\\x68\\xac\\x05\\xbb\\x9b\\xfb\\x2b\\x55\\x1d\\x91\\x07\\xb6\\xf6\\xe7\\xc8\\x21\\x1f\\x0e\\x5d\\xde\\x14\\xb3\\x0d\\xae\\xea\\x37\\x0c\\x1d\\x01\\xb0\\x6e\\x91\\xa9\\x46\\x02\\x3d\\xbe\\xf1\\x81\\x6e\\xa1\\xd7\\xaf\\xac\\xd0\\x33\\x7f\\x6c\\x22\\x9b\\x94\\xaa\\xe5\\x07\\x94\\xd8\\x74\\xfc\\x1c\\x40\\xe2\\x93\\x73\\x2a\\x68\\x0f\\x10\\x31\\x2d\\x44\\xf5\\xfb\\x8d\\x7d\\x05\\x2c\\xf5\\x46\\x0d\\x49\\x3f\\x1f\\xba\\x32\\xcb\\x52\\x4c\\xdc\\x4f\\x69\\x2f\\x5c\\xe3\\xac\\xa0\\x8d\\x69\\x2b\\x1e\\x23\\xd7\\x1c\\xc7\\x25\\xb0\\x41\\xeb\\x10\\x6c\\x55\\x9c\\x5c\\xde\\x28\\xd0\\xb8\\x97\\xbc\\xff\\x61\\x35\\xdc\\x4d\\x96\\x2b\\x4d\\x53\\xbe\\x1a\\x9f\\xeb\\xb5\\x4a\\xda\\x8d\\x18\\xaf\\x41\\x1b\\xaf\\xe1\\x73\\x6b\\x38\\xb7\\xb3\\xd4\\x3f\\x57\\x84\\xb5\\x21\\x8b\\x48\\x17\\xf2\\xa5\\xe9\\x3a\\x70\\x65\\xc7\\x54\\xe0\\x55\\xd7\\x96\\x6d\\xdb\\x88\\x75\\xdb\\x32\\xc9\\xda\\xf9\\x1d\\xe1\\xa9\\xff\\x7c\\x7e\\xb1\\x2d\\xa2\\x10\\xfd\\xca\\x77\\xd7\\xf3\\xf3\\xd7\\xc4\\x62\\x06\\x93\\x15\\x92\\x00\\xe6\\xf4\\xb2\\x78\\x87\\xb6\\x7d\\x83\\xb4\\x20\\x9b\\x2f\\x29\\xc3\\xf9\\xb4\\x55\\x39\\x77\\xbf\\xed\\x43\\x37\\xef\\xfa\\x52\\x8a\\x8a\\x99\\xe0\\x17\\x81\\x06\\x14\\xf0\\x19\\x34\\xac\\x1a\\x98\\xff\\xb8\\x35\\x0c\\xae\\x93\\x5a\\xac\\xf2\\xbc\\xcc\\x87\\x0d\\xe1\\xca\\xb7\\x5a\\x26\\xeb\\x64\\x8f\\xf3\\x19\\x92\\x98\\xd7\\x7a\\x8d\\x47\\x70\\x7a\\x89\\x2b\\x16\\x67\\x8d\\xc2\\x94\\xb2\\x17\\xb0\\x26\\x51\\x8b\\xb4\\x43\\x9f\\x4f\\x14\\x8b\\x77\\xf0\\x51\\xd7\\x71\\x75\\x18\\x43\\x9d\\x81\\xff\\x61\\x3c\\x3a\\x41\\xfb\\x4b\\x3d\\x2f\\xcd\\x97\\x37\\xcc\\x67\\xb3\\xd3\\x9c\\x67\\x30\\xeb\\x35\\x5e\\xe1\\x22\\x64\\xae\\x58\\x5c\\x69\\x74\\x53\\x7a\\x5a\\xe9\\x7a\\x03\\x6b\\xb2\\x4e\\x15\\xa1\\x47\\xae\\xee\\xb1\\x4a\\xbf\\xa1\\x0c\\xfe\\x13\\xa0\\x66\\xa8\\x68\\x23\\xfb\\x53\\xef\\xd0\\x08\\x59\\xe8\\xad\\x95\\xdc\\x0a\\xd5\\xe2\\xb8\\xbf\\xf7\\x19\\xf8\\x52\\xf6\\xbe\\xed\\xc7\\xb0\\x6b\\xac\\x57\\x4c\\x29\\x64\\xb6\\x81\\x96\\xfa\\x4a\\xae\\x5d\\xb2\\x13\\xb8\\xb5\\x8c\\xd7\\x22\\xf1\\x7d\\x01\\x18\\x11\\xb0\\x53\\xc7\\x4c\\x7f\\xa9\\xbf\\xea\\x3d\\xda\\x24\\xe7\\x34\\xfd\\x7f\\x12\\xad\\x1c\\x53\\x21\\x73\\x89\\x26\\x26\\x4e\\xb8\\x7e\\x43\\x1c\\xb4\\xc9\\x5a\\xc6\\x4b\\x98\\xb2\\x5b\\xc8\\xba\\x77\\x83\\xed\\x0a\\x3f\\xab\\xfd\\x90\\xc9\\x38\\xe8\\xf5\\x4d\\x02\\x8c\\xf1\\x9a\\x27\\xe2\\x07\\x0a\\xe0\\x96\\x57\\x10\\x73\\xc1\\x0d\\x75\\xea\\x03\\xad\\x7f\\xcc\\xbf\\xba\\x7d\\x57\\x3e\\x04\\x7b\\x25\\x73\\x33\\x36\\xbd\\x57\\xab\\xd8\\x97\\x25\\x6c\\x18\\x51\\x53\\x69\\x86\\xa5\\x86\\x12\\x1b\\x83\\xf5\\x8c\\x1b\\x51\\x03\\xb6\\xd7\\xca\\x25\\x20\\x26\\x08\\xf8\\xc2\\xd5\\x06\\x01\\x23\\x05\\x4b\\x4e\\xe1\\x05\\x6f\\x94\\xc8\\xec\\xfc\\x3b\\xf7\\x3b\\xb3\\xc5\\xa3\\xff\\x8c\\x2b\\x76\\xde\\x5a\\xfa\\x33\\xc2\\xb7\\xb0\\xa0\\x4e\\x3e\\x11\\x3b\\xc4\\x14\\x87\\x70\\x59\\x0c\\xbd\\xd1\\x3a\\x5a\\x1b\\xa8\\x2c\\xb2\\x78\\x9f\\x8e\\x75\\xc5\\x22\\xff\\x96\\xf2\\x0c\\xc6\\x04\\x18\\x2b\\xc6\\x26\\x85\\x5c\\xed\\xd8\\xbc\\xca\\xd9\\x17\\xfd\\xc4\\x72\\x30\\xff\\xb7\\x76\\xb1\\xe9\\x9b\\xcb\\xe4\\x55\\x0d\\x1e\\xe7\\x68\\xc8\\x7e\\xab\\xc0\\x28\\x1a\\xb6\\xf3\\x74\\x3d\\xc9\\x39\\x35\\x0c\\x94\\x31\\xd8\\x91\\x3a\\x08\\xf1\\x54\\xa5\\xe6\\x89\\x5a\\xc4\\x6c\\x96\\xb0\\x21\\x60\\xec\\x15\\x2b\\x79\\xec\\x0f\\xe1\\x7a\\x9c\\x9f\\x60\\x17\\xf8\\xfe\\xf8\\x3c\\xdc\\x15\\x8d\\xeb\\x99\\xf4\\x9e\\xab\\xe6\\x5b\\x9d\\x93\\x71\\x1e\\xc3\\x74\\x35\\x05\\xeb\\x74\\x6d\\x98\\xeb\\xad\\xae\\x2f\\x3a\\x8e\\x9c\\xe6\\x7c\\x86\\x22\\x80\\x8d\\x9c\\x26\\x74\\x1e\\xcf\\xab\\x8b\\x86\\xd7\\xef\\xdb\\x0c\\xfc\\xde\\xf8\\x23\\xd5\\xb4\\x88\\xf5\\x7e\\xe2\\x04\\x21\\x72\\x7d\\x2e\\x97\\xef\\xae\\x9a\\x1b\\x62\\x5c\\xd6\\x61\\x71\\x83\\x50\\x74\\x83\\x48\\xba\\x23\\x56\\x53\\x6f\\xf1\\xf6\\xe4\\x79\\x14\\xaa\\x6c\\x9e\\xc4\\x3e\\xf7\\x4d\\xb5\\xdc\\xc8\\x2f\\xa1\\x47\\x70\\x18\\x72\\x83\\x92\\xb1\\x4d\\x22\\x3d\\x45\\xd9\\xc6\\xff\\x7a\\xd1\\x8b\\x86\\xef\\x50\\xce\\x64\\x85\\xc1\\xa8\\xbd\\x48\\x74\\x21\\x11\\x12\\x0e\\x4b\\x11\\x76\\x9e\\xe7\\x78\\x7d\\xf0\\x9b\\xcb\\x53\\x50\\x46\\x19\\x19\\x2a\\xb3\\x7c\\xef\\x27\\x7e\\x7e\\xe9\\x6e\\xf8\\x3a\\x8d\\xaf\\xec\\x99\\x3c\\x76\\x8f\\xc1\\x33\\x98\\x5c\\x12\\xe3\\xbd\\xf3\\xa3\\x4f\\x44\\xc5\\xe4\\xaf\\xdb\\x6b\\x43\\x03\\x1e\\xf0\\x44\\x64\\xfe\\x1b\\x2f\\xf3\\xa1\\xa8\\xe9\\x85\\x79\\x90\\x66\\x5c\\xc4\\x6c\\x8d\\xdc\\xac\\x6f\\xb0\\x14\\xb8\\xd2\\x5b\\x29\\x6c\\x2d\\xb4\\x01\\xd3\\x28\\xa0\\x39\\xdf\\x25\\xc0\\x36\\x3d\\x25\\x4d\\xde\\x29\\x84\\xe3\\x15\\x88\\x88\\x91\\x62\\x49\\xfc\\x8f\\x77\\x86\\x09\\xe2\\x2e\\xf3\\x25\\x17\\x4a\\x17\\x87\\x1c\\x1c\\xd3\\x80\\xfc\\xd2\\xa6\\xc0\\x66\\xd5\\xef\\x54\\x37\\xd3\\xd5\\x76\\x3d\\xdb\\x8f\\x33\\xc3\\xf4\\xc2\\xb5\\x62\\x21\\x60\\x80\\x2c\\xf5\\x7e\\x55\\x61\\xec\\xd4\\x31\\x1c\\x7a\\xf9\\x2a\\x96\\x7f\\xf8\\xc9\\xfc\\x55\\x65\\x77\\x8f\\x9d\\xd1\\xb9\\x51\\xed\\x53\\x86\\x6b\\x99\\xef\\x74\\xbe\\x95\\x13\\xb9\\x02\\x4b\\xc8\\xcd\\xd9\\xa7\\x48\\x3b\\x28\\x6a\\x20\\x69\\xfe\\x8a\\xc6\\x72\\x79\\x6a\\xe0\\x86\\x61\\x52\\xf3\\x86\\x5b\\x29\\xd6\\x7d\\x59\\xe6\\x3c\\xc6\\x67\\x29\\xbb\\x7b\\x70\\x8d\\x17\\x6a\\x46\\x49\\x90\\x16\\xdf\\x3f\\x06\\xa2\\xf5\\x4b\\xa1\\xb8\\xc3\\x44\\xd7\\xd6\\x15\\x98\\x2e\\x60\\xa2\\x28\\x94\\xa6\\xcb\\x40\\x6b\\x47\\xf3\\xae\\xb4\\x3b\\x26\\xc4\\xfb\\xcc\\x87\\x79\\x3c\\xd3\\xcb\\x62\\x21\\xeb\\xa4\\x4c\\x56\\x51\\xf0\\x77\\x29\\xed\\x05\\x2a\\xa5\\xbb\\x9d\\x53\\xc2\\x6b\\x64\\x1f\\x0b\\x67\\xe9\\x3f\\x79\\xea\\xa8\\x24\\x5d\\x37\\x4c\\x82\\x83\\xb0\\xb6\\x96\\x71\\x07\\xc9\\x95\\x6c\\xa8\\x1e\\x9a\\xe4\\xe4\\x2b\\x62\\xb6\\x8a\\x2b\\x37\\x6b\\xa9\\x2e\\x7f\\x55\\xcb\\x0d\\xe8\\x9e\\x6a\\x0d\\xc8\\x09\\x23\\x23\\x05\\x9f\\x07\\xfd\\xdd\\xcb\\xb9\\x2e\\xf3\\xad\\xcc\\xb6\\xd4\\x11\\xc5\\x97\\x81\\x8c\\x5e\\x01\\xf8\\x8f\\xf1\\x53\\x87\\x23\\x9a\\x9f\\x80\\x96\\x1d\\x4a\\x5e\\x0b\\xeb\\xe4\\xd9\\x34\\x3c\\xee\\x5f\\x7f\\x77\\xd8\\x5f\\xe3\\xbb\\x86\\xce\\x3a\\x06\\xcf\\x08\\x21\\x83\\xd8\\x07\\x56\\x1b\\x70\\x4d\\xf2\\x91\\x85\\x4e\\xcf\\x09\\xfc\\x46\\x06\\xe2\\x1b\\x12\\x24\\x9a\\x92\\x66\\xda\\x86\\xe2\\x51\\x0e\\x7b\\xce\\xd0\\xf2\\x36\\x67\\xf2\\xe9\\x41\\x5a\\x00\\xa8\\xdd\\x9f\\x63\\x3b\\x1b\\xa2\\xe2\\xe9\\xca\\xb3\\xfe\\x7a\\x45\\xdd\\x13\\x91\\x2b\\x69\\x9d\\x4e\\x41\\x2d\\x87\\xbd\\x14\\x7c\\x53\\x70\\x73\\xcd\\xcf\\x21\\x83\\x09\\xcd\\x28\\x5f\\x80\\x78\\x59\\x6c\\xa6\\x13\\xf9\\x62\\x9d\\x6e\\xce\\x64\\x5b\\x40\\x4c\\x01\\x81\\x22\\x00\\x7c\\x83\\x78\\x86\\x7f\\x2b\\x99\\x4d\\xa4\\xf6\\xca\\x94\\x66\\x4d\\x22\\xb1\\xdb\\xcb\\x8f\\x41\\x6a\\x2f\\x08\\x83\\x48\\xc0\\xe8\\x46\\xf3\\x3f\\xeb\\xba\\x28\\xa6\\x15\\x2f\\x45\\x57\\xf7\\xcf\\x15\\x7f\\x86\\x7d\\x17\\xfb\\xd0\\x05\\x65\\x02\\x44\\x01\\x0a\\x04\\xae\\x03\\x8a\\x13\\x5a\\x50\\x16\\x71\\x36\\x59\\x4d\\x75\\xad\\x52\\x50\\x0e\\x31\\xd1\\xd9\\x4c\\x87\\x32\\x71\\xf8\\xac\\xeb\\x5a\\x60\\xa0\\x59\\xf2\\x63\\xe9\\x2f\\xb5\\x8e\\xc7\\xba\\x09\\x16\\x62\\x7b\\xe0\\xc0\\x42\\x96\\xe7\\x9d\\xde\\x37\\x1e\\x83\\xb7\\xfc\\xeb\\x5c\\x59\\xc3\\x8b\\xfd\\xf1\\xab\\xc4\\x41\\x68\\xfa\\x65\\x2c\\xc7\\x95\\x31\\x22\\x52\\x84\\xfd\\x5f\\xf1\\xf7\\x3b\\x4e\\x46\\xd1\\x27\\xeb\\x90\\x2c\\xd2\\x4c\\xff\\x9e\\xc3\\xbc\\x5b\\x4b\\xad\\xf8\\xa7\\x1a\\xa5\\xe3\\x92\\x67\\x50\\xc6\\x40\\x31\\xd0\\x86\\x20\\x93\\x28\\x6a\\xf8\\xdd\\xdf\\x9c\\xcf\\xf2\\x37\\x92\\x50\\x04\\xb8\\x91\\x93\\x82\\xc7\\x9d\\x1e\\x00\\xba\\xbc\\x8d\\x96\\xb2\\x97\\x92\\xc3\\x76\\x22\\x4c\\xc3\\xa4\\xd3\\xfb\\x34\\x6e\\xb1\\x54\\x1e\\x50\\x15\\x8d\\x98\\xc7\\x4d\\x4a\\xef\\x0f\\x76\\xac\\x69\\x9c\\x0b\\xf9\\x22\\x11\\x3f\\x4c\\x0d\\x64\\x1e\\xb4\\xae\\x1b\\x51\\xf3\\x64\\x6d\\x01\\x77\\x03\\xc7\\x01\\x3d\\x06\\xd7\\x28\\xcc\\x93\\x80\\xda\\xb4\\x0e\\xf6\\x33\\xf1\\x1b\\x70\\xdf\\x87\\x40\\x5b\\x60\\x6d\\x29\\xd5\\x17\\xc4\\x45\\x6b\\xa1\\xad\\xd4\\x37\\xb2\\xa4\\x87\\x47\\x4f\\x15\\x42\\x57\\x14\\x87\\x28\\x14\\x7f\\xfd\\x1b\\x86\\x66\\xf8\\xfb\\xe5\\xc2\\x79\\x0f\\x66\\xf8\\x32\\x02\\x6f\\x68\\x42\\xaf\\x6b\\x46\\xd8\\xdd\\xee\\x32\\x55\\x54\\xe9\\x9a\\x8d\\xfd\\x3a\\x04\\x93\\x59\\xf6\\x0d\\xf7\\x62\\x86\\xf2\\x47\\x3f\\x76\\x3d\\x54\\x0a\\x77\\x37\\xb3\\x94\\x66\\x2c\\x5d\\x1b\\x1d\\xd3\\x31\\xa0\\x36\\x08\\xef\\xcf\\xaf\\x67\\xea\\xa1\\x61\\x32\\x96\\x01\\xb2\\xa6\\x1d\\x00\\x86\\x87\\xdb\\xce\\xe3\\xad\\xf1\\x0f\\x39\\x3e\\xae\\xda\\xef\\x41\\xe7\\xa5\\xaa\\xd8\\xaf\\x0f\\x08\\xf6\\xe0\\x86\\x50\\x9d\\x36\\x77\\xab\\xa6\\x1b\\xc7\\x4b\\xe6\\x80\\xee\\x2f\\x4a\\x1f\\xa5\\xc9\\x3b\\x3a\\xd7\\xa4\\xb8\\xc9\\xb8\\x02\\xc7\\x27\\x01\\x4c\\x7d\\xf8\\xb8\\x0e\\xb7\\xb4\\x0b\\x94\\x09\\x7f\\xfd\\x2b\\x4e\\x69\\x69\\x79\\x1a\\x3c\\xb7\\xfc\\xc8\\xfa\\xde\\xbd\\xfa\\x3e\\x24\\xc0\\x1d\\x16\\x21\\x35\\xc9\\x7d\\x82\\xb8\\xbf\\x1b\\xbd\\xe3\\xa3\\x36\\xfc\\x29\\xfc\\x63\\x9c\\xa5\\x37\\xd9\\xd1\\xbe\\x2d\\x39\\x64\\xec\\xd6\\x23\\x12\\xb6\\xba\\x01\\x66\\x2d\\x8d\\x94\\x8b\\xa1\\x52\\xbc\\xbb\\x86\\x7d\\x7f\\x38\\x6a\\x59\\xc7\\x18\\xa9\\xca\\xb5\\xf1\\x48\\x39\\xe6\\x8f\\x88\\x03\\x89\\x40\\xb5\\x86\\xd5\\x3e\\xb6\\xab\\xc9\\x11\\xd3\\xfd\\xcf\\xdd\\xdc\\x74\\xf2\\x8c\\x29\\xb1\\x15\\xf1\\x16\\x8f\\x20\\xf9\\xda\\xaf\\x33\\xf5\\x5f\\x97\\xbd\\xe6\\xdb\\x1b\\x9d\\xbf\\xf9\\x5e\\xae\\x31\\xd0\\x48\\x4b\\x47\\xb5\\xeb\\xf9\\xbd\\xf1\\x85\\x08\\xba\\x3b\\x0a\\x1c\\xeb\\xca\\x3d\\x6a\\xf9\\xe1\\x94\\x9d\\x15\\x7e\\xf0\\x40\\x25\\xb8\\x8d\\x17\\xf1\\xbd\\x35\\x9a\\x19\\x50\\x6b\\x1f\\x5d\\xe9\\xbd\\xd2\\x6b\\x23\\xb3\\xa3\\x3e\\xe0\\x63\\xf6\\x09\\xc8\\x87\\xff\\x7c\\x14\\xd1\\xf1\\x32\\x0e\\xe4\\x86\\x5d\\xee\\xa8\\xd5\\x3c\\xa9\\x4f\\x4d\\xfe\\x92\\xcf\\x47\\x0d\\x98\\x2a\\x61\\xff\\xd6\\xae\\x69\\xcc\\x75\\xef\\xe5\\x62\\xcf\\x38\\xd5\\x17\\x54\\x34\\x10\\xca\\x4c\\x9a\\xb4\\xcc\\xa4\\x19\\x6f\\x44\\x44\\x7c\\x7d\\xfc\\x7f\\xf7\\x57\\x7d\\xd1\\xa2\\x50\\xb9\\xff\\xd4\\x58\\xe5\\x66\\xc5\\xec\\x33\\xf2\\x63\\xfa\\x29\\x6b\\x37\\xa4\\xff\\xc3\\x77\\xc1\\xfa\\xcc\\x6b\\x5d\\xfb\\x5b\\x54\\xae\\x8d\\xa1\\x34\\x06\\x5d\\xec\\x2b\\x01\\x5c\\xcd\\xbe\\xe3\\x4f\\x2f\\x58\\xae\\x63\\x9e\\xa4\\x5f\\xba\\x99\\xa7\\xd6\\x6c\\x91\\x84\\x64\\xa6\\x58\\x77\\xc3\\x2d\\x5b\\x09\\xbb\\xc0\\xff\\x50\\x7e\\x0b\\x37\\xdc\\xf8\\x13\\xf3\\x71\\x23\\xdb\\xf5\\x67\\xb2\\x6a\\x0c\\x4f\\x7c\\x5e\\x43\\xd4\\xd4\\x50\\x6c\\xd2\\x73\\x34\\x98\\x7f\\x77\\xd2\\x99\\x94\\xb3\\xe7\\x87\\x9f\\xed\\x87\\x64\\x44\\x95\\xb3\\xe7\\x9b\\xd3\\x99\\x1e\\xe8\\x1b\\xe1\\xdf\\x38\\x54\\x1b\\xd9\\xf7\\x63\\xb9\\x9a\\x1c\\x32\\x53\\xeb\\xa6\\xc7\\xb0\\xa8\\xda\\xbc\\x1a\\xe0\\x69\\xcc\\x9c\\x44\\x64\\x57\\x77\\x27\\xe5\\xdf\\x9e\\x71\\x95\\xfa\\xd2\\x5c\\xa3\\x58\\x03\\xa5\\x1b\\xce\\xb7\\xc7\\x9e\\x4e\\x18\\xd3\\x29\\xcd\\xf9\\x54\\x97\\x3d\\x06\\xf8\\xc1\\x70\\xf4\\x5f\\x46\\x3b\\x59\\x98\\xaf\\x2e\\x5f\\xef\\x20\\xce\\x5c\\xa3\\x9d\\x60\\xe7\\x7e\\x91\\x0b\\xb1\\x5e\\xe8\\x75\\x6e\\xa8\\xb1\\x57\\x1c\\xfd\\x63\\x9b\\x29\\x3f\\x40\\xfc\\x0f\\x61\\x30\\xa6\\x9d\\xd9\\x1d\\x26\\x1c\\x38\\xf7\\x31\\xa0\\x9d\\x3b\\x02\\xbc\\x61\\xff\\x62\\x65\\x8a\\x08\\xfa\\x10\\x72\\x79\\x2e\\x23\\xce\\x24\\x4b\\xc5\\x29\\xa7\\x61\\x41\\x22\\x72\\xa3\\xa4\\x2e\\x0d\\xfb\\xbf\\xeb\\x51\\xb4\\x36\\xd4\\x16\\x51\\x0e\\x19\\x70\\x6e\\x07\\x37\\xed\\x95\\x7c\\xf0\\x1a\\xc1\\x6c\\x40\\x7e\\xf8\\xa7\\x2f\\x71\\x29\\xf2\\x58\\xc6\\x11\\xe7\\x71\\x13\\xf6\\x59\\x35\\x58\\xbe\\x58\\x03\\x86\\x6f\\x0b\\xb5\\x23\\x97\\x9b\\xa9\\x7f\\xe6\\xe5\\x28\\xaa\\x71\\x20\\x31\\xc9\\xc3\\x4c\\x0c\\xc7\\x91\\xef\\xd4\\x06\\x7c\\x1b\\xcd\\x39\\x6a\\x98\\x48\\x87\\x94\\x68\\x78\\x37\\xbc\\x69\\xed\\x4f\\x1c\\xab\\xdc\\xd7\\x7b\\xb3\\xd7\\xca\\xe2\\xdd\\x66\\xb0\\xc1\\x72\\x37\\x15\\x23\\x69\\xbd\\x2b\\xff\\xc5\\x72\\x1e\\xe6\\x8b\\x5b\\xcc\\xc2\\xcd\\xe4\\xa8\\x19\\xa2\\x1b\\x0e\\x9e\\xa7\\x5a\\x33\\x23\\x32\\x67\\xf4\\xd3\\xcf\\x7e\\x97\\x39\\xd7\\x53\\x7d\\x64\\xef\\x1a\\x85\\x9a\\xa4\\x91\\x21\\x22\\xb9\\x66\\xdf\\xee\\xa7\\x16\\x86\\xbb\\x8a\\x09\\x87\\xe5\\xd9\\xe5\\x15\\xa3\\x85\\x66\\xbb\\x10\\x1d\\x4d\\xfd\\x9a\\x41\\x53\\x29\\xff\\x2e\\x6e\\xb2\\x17\\x44\\xda\\x3b\\x1f\\xb8\\xad\\x60\\x34\\x9a\\xd9\\x22\\x90\\x22\\x14\\x6c\\xaa\\xdb\\x69\\xc2\\xb3\\x82\\xec\\x31\\xcf\\xcf\\x1d\\x59\\x43\\x11\\x53\\xcc\\x08\\x18\\x27\\x6c\\x95\\x9b\\x9e\\xac\\x81\\xd3\\xd2\\xa1\\x1f\\x15\\x3e\\xff\\xe1\\x3a\\xba\\x76\\x48\\xe2\\x7c\\xdc\\x61\\x94\\x79\\x8f\\x08\\xb8\\x17\\x19\\xb5\\xb5\\x5e\\x3a\\x51\\x07\\x66\\x8c\\xe4\\xfd\\x8f\\x37\\x70\\xfe\\xf2\\x65\\x3f\\x98\\xd3\\xc2\\x8e\\x8d\\x41\\x12\\x32\\xee\\x09\\x6f\\x72\\xf6\\x8c\\x71\\x5c\\xaa\\xd9\\x0e\\xf2\\xfe\\xf0\\x15\\xb0\\xce\\x2a\\x39\\xc3\\x50\\x2e\\x17\\xa9\\x4c\\x10\\xf2\\x06\\x8e\\xd7\\x3e\\xba\\xb6\\x6b\\xcc\\x02\\x3b\\x36\\x99\\xd8\\x17\\xc9\\xfe\\xd4\\xbe\\xb3\\x99\\xb2\\x6d\\xca\\x2c\\xfe\\x92\\x8f\\xb7\\x59\\x72\\x4e\\x94\\x95\\xc0\\xfb\\xfc\\xe7\\xd3\\x40\\xcd\\x4f\\x5f\\x71\\x83\\xe1\\xd8\\xc4\\x68\\xbb\\x99\\xe3\\x30\\x69\\x74\\x94\\x1e\\xd3\\xcc\\x07\\x76\\x38\\x7d\\x3d\\x21\\x44\\x11\\xff\\x71\\x21\\x33\\x7b\\xc0\\x35\\xc5\\xd2\\x34\\x33\\x67\\xc0\\x52\\x7d\\xc7\\x6d\\x61\\x1a\\x1c\\x1b\\xee\\xbb\\xd3\\x5d\\x91\\xc0\\xd6\\x3f\\x31\\x48\\x93\\x34\\x54\\xc0\\xb2\\xd1\\x0a\\x47\\x03\\x9c\\x87\\x98\\xa9\\x6e\\xdc\\x0c\\x73\\x3a\\xeb\\x97\\xbe\\x52\\x2b\\x99\\xcb\\xfc\\x89\\x2b\\x98\\xdd\\x57\\xbf\\x2a\\xa3\\x94\\xbc\\xdc\\xa0\\x03\\xdb\\x79\\x54\\x84\\x0a\\x8f\\x78\\xfd\\xeb\\x59\\xac\\x0b\\x09\\x2c\\x19\\xef\\xfd\\xf0\\x49\\xd8\\x24\\x38\\xf0\\xf4\\xac\\x2b\\xf6\\x51\\x94\\x5a\\x1d\\x0b\\x5e\\x2e\\x63\\xaf\\x18\\x87\\xfd\\xeb\\x77\\x7f\\xb0\\xc5\\x1d\\x04\\xdd\\x8c\\x8e\\x18\\xa0\\x5a\\x7c\\xf8\\x55\\x02\\x87\\x6f\\x0b\\xc5\\xe9\\x1c\\xf1\\x1f\\xef\\x5a\\xeb\\xf1\\x5f\\x47\\x13\\x9c\\xab\\x99\\x29\\xb3\\x7c\\x08\\x87\\x91\\x7a\\x08\\x18\\x30\\x5b\\xc0\\x4a\\x85\\xfb\\xb7\\x7f\\xce\\xec\\x7c\\x70\\xcb\\x98\\x79\\x41\\x4d\\x8a\\xac\\x92\\xe0\\x4f\\x31\\xf7\\x42\\xd3\\x7b\\xad\\xd0\\xa8\\x7f\\x71\\x5d\\x83\\xe5\\x5c\\xe3\\x23\\x07\\x4e\\xf7\\xe8\\xdc\\xa9\\x39\\x2d\\x2a\\xdc\\x1a\\xa4\\x8b\\xcc\\x8a\\x86\\x9c\\xb0\\xff\\xc8\\x8b\\xa0\\x38\\xe5\\xca\\x34\\x9e\\xc4\\x8b\\x53\\x0b\\x67\\x28\\xc1\\x5c\\xa7\\x16\\x68\\xc9\\xbf\\x1e\\xda\\x51\\xd3\\x80\\xfa\\xfc\\xf0\\xca\\x0d\\xc5\\x12\\x39\\x61\\x01\\xb7\\x95\\x81\\xe2\\xbd\\x3f\\xba\\xe9\\x5d\\xb4\\x25\\xfc\\x15\\x13\\x37\\xa4\\x32\\xe1\\x30\\x15\\xdb\\x8c\\xba\\x7f\\x4c\\x56\\x63\\xd8\\x73\\x0d\\xd4\\xe4\\x27\\x16\\x50\\x6f\\xd1\\xf3\\x17\\x47\\xe1\\xf3\\x2e\\x24\\xe5\\x34\\x8f\\x33\\x8d\\x11\\x13\\xf3\\x7f\\x31\\xdd\\x77\\xd5\\x6e\\x49\\x08\\x19\\xb0\\x73\\xd5\\xe4\\x0b\\x60\\x98\\xd4\\x31\\x0d\\xa6\\x29\\x77\\x65\\x04\\x4c\\xa4\\xfc\\xf8\\x7e\\x38\\x77\\x45\\xaa\\x4b\\xcb\\x4c\\xd6\\xad\\x5a\\xdf\\x7b\\xa5\\xcb\\xa4\\x60\\x18\\x3a\\x82\\x39\\xec\\x66\\x8f\\x0b\\x7c\\xf7\\x8f\\x07\\xb3\\x68\\x33\\x93\\x0a\\x06\\x5c\\x64\\xf8\\x74\\x05\\x1b\\xc8\\xcf\\xcd\\xac\\x4b\\x68\\xa7\\x53\\x22\\x5e\\x22\\x76\\x47\\x68\\x8b\\x3f\\xb9\\x1d\\xde\\xea\\xf8\\xc1\\x11\\x6c\\x0f\\x31\\x9b\\x28\\xf7\\x33\\x43\\xd1\\x0c\\x9e\\x73\\x22\\xe3\\xe4\\x94\\xbf\\x38\\x28\\xe7\\x18\\x88\\x62\\x89\\x8c\\x4f\\xde\\x10\\xf4\\xf8\\xe5\\x2b\\x39\\x8c\\xec\\x8c\\xcc\\xd1\\xfd\\xc4\\x51\\x96\\x67\\x98\\x9b\\x32\\x73\\x8a\\x1a\\x17\\xd0\\xe5\\x23\\xe0\\xed\\x72\\xfc\\xd3\\x09\\xc8\\xff\\x7b\\xfe\\xca\\x87\\x19\\x01\\x17\\x86\\x30\\x0c\\xc7\\x68\\x4d\\x6c\\xec\\x54\\x10\\x96\\xe9\\xa0\\x02\\xb7\\x0c\\xe7\\x87\\xbf\\x80\\x63\\xd0\\x5f\\xbe\\xc5\\x10\\x2c\\x2e\\x0b\\x78\\x2a\\xde\\x2d\\x63\\x92\\x9b\\x4b\\xdf\\xb9\\xbf\\x3f\\xff\\x7e\\x7e\\xf0\\xdf\\x77\\x53\\xf6\\x9a\\x39\\x7d\\x41\\x46\\x25\\xe8\\x3d\\x3f\\xc9\\xcd\\xd7\\x72\\x40\\x7a\\x63\\xc1\\x49\\xfa\\x37\\xb9\\xca\\xe4\\x46\\x83\\x05\\xac\\x08\\x91\\x3e\\x1f\\xa6\\xb8\\x65\\x36\\x64\\xc0\\x2e\\xff\\x9e\\xdf\\x19\\xa7\\x91\\x07\\x2d\\x66\\x63\\x30\\x8f\\xa9\\x4d\\x8a\\xee\\x11\\x17\\x0a\\x98\\x78\\xd0\\x54\\xd5\\x20\\xc2\\x84\\xfd\\x27\\xdb\\xfa\\xa0\\xf6\\x0a\\xf5\\xc9\\xdf\\xa7\\x80\\xe0\\x37\\x21\\x15\\x90\\x22\\xf2\\xb5\\xf2\\xb9\\x6c\\x61\\x20\\x97\\xff\\xa7\\x2b\\x21\\x96\\x05\\xf5\\x49\\x91\\x28\\x58\\xcc\\xbf\\x65\\xba\\x05\\x9e\\xd2\\xc9\\x5f\\xdc\\xb3\\x59\\xaa\\x91\\xdb\\x42\\xea\\xf9\\xbf\\x73\\x3b\\x05\\xc7\\x7e\\xcd\\x61\\xd9\\x46\\x05\\xb1\\x35\\xc5\\x07\\x2a\\x1b\\xd1\\x1a\\x57\\xf8\\xff\\x63\\x69\\xf1\\x0b\\x92\\x77\\xc9\\x2f\\x25\\x6d\\x8b\\xd3\\x0e\\x0f\\x25\\x0c\\x1d\\xe4\\xcb\\x44\\x85\\x31\\x32\\x16\\x99\\xf7\\x8d\\xf2\\x73\\x2f\\x89\\x3d\\x85\\xd3\\xff\\x3c\\x0a\\xd5\\x7b\\xf5\\x04\\xed\\x14\\x3e\\xee\\x50\\x68\\x23\\x85\\xe6\\x76\\x9c\\xab\\x2e\\x3e\\x3a\\x16\\x24\\x3f\\xc8\\xcf\\x55\\x6b\\xc2\\xf4\\x73\\x1e\\x51\\x9d\\x05\\x65\\x79\\xf2\\x4c\\x0e\\xa9\\xd3\\x23\\xcb\\x96\\x26\\xe2\\xe7\\xe0\\x1a\\x23\\xe2\\xbd\\x7d\\xe8\\xb6\\xac\\x16\\xb2\\x20\\x0c\\x4d\\xfb\\xca\\x4a\\x5e\\x5c\\x9e\\x8e\\xcb\\xf8\\x15\\x22\\xa4\\xbe\\x28\\x08\\x9d\\x92\\xfe\\xc8\\xcb\\x08\\x7b\\x5a\\xc3\\x98\\x78\\x51\\x79\\xb4\\x40\\x4f\\x5f\\xfa\\x82\\x4c\\xfe\\x2e\\x07\\x4a\\x13\\x9d\\xc8\\x00\\xd7\\x6e\\xd5\\x92\\xac\\x78\\xdb\\x5d\\x25\\x43\\xb8\\x7c\\xe5\\x9a\\x4f\\xcd\\x30\\x0a\\x53\\xfc\\xbc\\xc4\\xe7\\x2a\\xb5\\x9f\\xfe\\xc5\\x1c\\x83\\xb2\\xec\\xab\\x04\\x20\\x46\\xf6\\x61\\x18\\x1e\\xd1\\x94\\x21\\x66\\x87\\x5d\\x9e\\x69\\xab\\xaa\\xf5\\x49\\x10\\x2b\\x1c\\x1c\\xc9\\xff\\xc4\\x03\\xd4\\x44\\xc6\\x09\\x18\\x1e\\x8b\\x27\\x46\\xe7\\xf0\\xff\\xb8\\x2c\\x51\\xcd\\xf5\\xb2\\x64\\x65\\x6a\\xfe\\xb3\\xb3\\x49\\x9b\\xae\\xc4\\xbc\\xa6\\x48\\x3a\\x35\\x94\\xe4\\x24\\x85\\x6d\\xa5\\x9b\\xc1\\x33\\x98\\x15\\x36\\xc9\\x2c\\x9a\\x58\\x71\\x63\\x78\\x0b\\x66\\x80\\x3a\\x3b\\x09\\x46\\x0d\\x18\\x05\\x01\\x7e\\x27\\xfc\\xe4\\xb0\\x8d\\xd6\\xb4\\x7a\\x08\\xf8\\xcc\\x91\\x9f\\x66\\x5f\\x73\\x39\\x63\\xd0\\x1a\\xb2\\xed\\xc8\\xd6\\xa7\\x98\\xda\\x5e\\x95\\xc8\\xa0\\x78\\x28\\xb9\\xc5\\x92\\x5d\\xec\\x8f\\xdf\\xa5\\x78\\x9f\\x7a\\xd8\\x49\\x96\\x96\\xa7\\xad\\xa3\\xb9\\xe6\\x7f\\xce\\xe8\\xc2\\x6a\\x0b\\x1a\\x96\\xcb\\x85\\x27\\x86\\x7e\\xd2\\x09\\x3b\\x6c\\x6e\\x12\\xd6\\xc3\\x19\\xb1\\x4d\\x21\\x1a\\xea\\x66\\x27\\xd7\\x8d\\xd5\\xd3\\xd5\\xc9\\xca\\x1b\\x87\\xb0\\x97\\x14\\x05\\x1c\\xb5\\xf1\\xc1\\xb6\\x07\\x74\\x7a\\x37\\x3f\\x1a\\x6c\\xf0\\xf5\\xe3\\x2b\\xee\\x7e\\x7c\\x59\\xcb\\x69\\xde\\x0a\\x03\\x71\\xa3\\x4c\\x4f\\x1e\\x55\\xfa\\xce\\x0f\\x43\\xb1\\x9a\\x82\\x75\\xc4\\xe3\\x52\\xd3\\xd5\\xbb\\xd1\\xfc\\xe0\\xbf\\x7d\\xfc\\x50\\xe5\\xb1\\x7d\\x04\\x52\\x66\\x08\\xfb\\x86\\xad\\x19\\x26\\xdd\\x6c\\xf3\\xb3\\xfc\\x13\\x1b\\x09\\x87\\xe7\\x1d\\x06\\x15\\x0e\\xff\\xef\\x9c\\xc9\\xa3\\xf3\\x2e\\xec\\x57\\xef\\x4a\\x36\\x7b\\x5c\\xac\\x8e\\x09\\x54\\xc0\\x48\\x55\\x54\\x7e\\x85\\xd6\\xb9\\x2a\\x48\\x93\\xd0\\xf4\\xed\\x5c\\xca\\x3a\\x9b\\xea\\x7e\\x80\\xc0\\x44\\x91\\x16\\x11\\xc1\\xdc\\x20\\x92\\x13\\x99\\x2e\\x71\\xb6\\xe6\\xfb\\x52\\x32\\x33\\xd0\\x8f\\x3f\\xcd\\x3e\\xbd\\x41\\x38\\xf9\\xc8\\xb7\\xaa\\xd0\\xaf\\x15\\x03\\x6e\\xe3\\x39\\x67\\x1d\\x15\\x3c\\xa6\\x1f\\xd0\\xd6\\xbd\\xef\\x80\\xc2\\xbd\\x48\\xf5\\x32\\x98\\xc8\\x20\\x23\\x18\\x12\\x36\\x13\\x14\\xa7\\x3b\\xc9\\xb6\\x52\\x44\\xb8\\xd1\\xc8\\x25\\xdc\\xb4\\xff\\x64\\x9e\\xb1\\x8c\\xf3\\x05\\x9c\\x9b\\xdc\\xcd\\xe1\\xcb\\x4a\\x70\\x43\\x4e\\x0e\\x61\\x23\\x08\\x72\\x47\\x42\\x2a\\xb9\\x80\\x7d\\x57\\x92\\x58\\xd7\\x12\\x7b\\x69\\xea\\x60\\x78\\x8b\\x1a\\xc4\\x25\\x67\\x22\\x52\\x52\\x50\\xf8\\xe8\\x16\\xf7\\xca\\x8b\\x8e\\x37\\xb4\\xff\\x74\\x06\\x4f\\xcf\\xd4\\x47\\xc6\\x48\\xd1\\x0b\\xcb\\x2d\\x5b\\xe7\\xc1\\x4b\\xb7\\xdc\\x84\\x51\\x06\\x87\\x09\\xeb\\x93\\xc0\\xb2\\xd2\\x4a\\xfa\\x1d\\xea\\x2d\\x8d\\x9c\\xeb\\xb3\\x34\\x87\\x38\\x9f\\x9d\\x66\\xcd\\xdd\\x97\\xbb\\x13\\x27\\x61\\xff\\xdf\\xbe\\x38\\xe4\\xca\\xda\\x7c\\x53\\xbe\\x7b\\x88\\x45\\x01\\xea\\x83\\x32\\x51\\xdf\\x91\\xaa\\x2e\\xa1\\xc2\\x37\\x58\\x88\\x93\\x63\\x70\\x49\\xea\\x5a\\x8c\\x9b\\x9a\\xe8\\xba\\xb2\\x87\\x70\\x18\\x1a\\x67\\x5e\\xfb\\x9c\\x9a\\x3f\\x86\\xa0\\x35\\xad\\xca\\xfd\\xd3\\x07\\xf2\\xc2\\x7e\\xb5\\xbb\\x32\\xc5\\xb5\\x0c\\xa3\\x10\\xfe\\x65\\xe1\\xb9\\xd7\\xcd\\x64\\xb7\\x37\\x4d\\x70\\x8a\\xbb\\xc4\\xeb\\x2a\\xc9\\xed\\xf3\\x1e\\x0c\\xe1\\x44\\x4a\\xc5\\x1e\\x41\\xd2\\x86\\xef\\xde\\x70\\x7c\\x08\\xbd\\xc4\\x05\\x06\\x87\\xe4\\x80\\x5e\\x81\\x6f\\xc0\\x04\\xca\\xcf\\x92\\x71\\x81\\xb7\\xd3\\xae\\xe7\\xc4\\x3d\\x1d\\xf7\\x07\\xae\\x32\\xee\\xab\\x17\\x63\\x38\\x24\\x16\\x69\\x43\\xb4\\xfd\\xfb\\x02\\x05\\x87\\x12\\x8b\\xcf\\xe5\\xbe\\xfd\\x72\\xc9\\x1b\\x25\\xbf\\xd6\\xbc\\xae\\xb3\\xa4\\x71\\x5f\\xcb\\xb4\\x42\\xee\\xae\\x6c\\x7b\\x2e\\x55\\xcd\\x6e\\xa0\\x40\\x58\\x7e\\xee\\x1d\\x73\\x4e\\x83\\x3c\\xd1\\x16\\xd3\\xc9\\x6c\\xc4\\xe7\\x03\\x0b\\x29\\xa7\\x75\\x9a\\xf1\\xad\\x27\\x2c\\x95\\x44\\x1b\\x2c\\x9f\\x42\\x6a\\xe6\\x21\\xd8\\x4c\\x30\\x1f\\x89\\x73\\xdd\\x1a\\xfe\\xf6\\xe8\\x4b\\x6d\\x3f\\x69\\xdb\\xbd\\xcb\\x3a\\x69\\x1b\\x55\\x18\\xb8\\x4e\\x28\\xbd\\x42\\xf3\\xfa\\x0f\\x2f\\x23\\x53\\xa4\\x72\\xd4\\xf1\\xde\\xeb\\x24\\xdf\\x7a\\xe8\\x39\\x6f\\x39\\xb7\\x65\\x25\\x77\\x80\\xd8\\x1a\\xca\\xe0\\x39\\xb2\\x49\\x12\\xee\\x97\\x9e\\x70\\x3d\\xd9\\x3f\\x5f\\x34\\x23\\xd1\\xaa\\x86\\xa5\\xcf\\x34\\x5e\\x4e\\x64\\x55\\xe5\\xab\\x18\\xe1\\x37\\x71\\x66\\x9c\\x12\\x5b\\xf9\\x29\\x9c\\xee\\x27\\xe7\\xd5\\x33\\x56\\xc7\\x7b\\x4f\\xc2\\x14\\x34\\x4c\\xdb\\x03\\x55\\x2e\\xc7\\x41\\xee\\xc0\\x52\\xca\\xcb\\x95\\xf0\\xdc\\x94\\xe3\\x94\\xc9\\xae\\xd5\\xb8\\xec\\x20\\x75\\xe4\\xd9\\x88\\xcc\\xdc\\x23\\x4a\\xba\\x11\\x5c\\x99\\x3d\\x06\\x25\\x94\\x9c\\x92\\xce\\xd9\\xa8\\xac\\xb8\\x9f\\x1f\\x5b\\xcf\\xef\\x1f\\x79\\xff\\x65\\x28\\xda\\xc9\\x1f\\x34\\x7b\\xdc\\x14\\x06\\x93\\xe6\\xd3\\xfc\\x28\\xaf\\x45\\xdd\\xdf\\x0f\\x55\\xf8\\x69\\x0c\\xdc\\xc8\\x79\\xa1\\xb9\\x1a\\x22\\x98\\x91\\x9f\\x86\\x94\\x5b\\x3a\\x58\\x99\\x8d\\x10\\x48\\xcb\\x4f\\x4c\\x66\\x79\\xdc\\x14\\xd3\\x89\\xa0\\xd6\\x7a\\x56\\x7a\\x6c\\xcc\\x11\\x31\\x41\\xdd\\xf5\\x82\\x94\\x63\\x3a\\xe6\\x15\\x98\\x8f\\xf1\\x18\\xdc\\x63\\x22\\xf3\\x97\\x2f\\x2b\\x93\\x17\\xaa\\x66\\x99\\x47\\xec\\xed\\x4d\\xc1\\x28\\xfd\\x1a\\x93\\x6d\\xcb\\xf7\\x70\\xba\\x79\\x57\\xd6\\xeb\\x23\\xfc\\xc4\\xae\\x46\\xc3\\x5e\\x4e\\x12\\xdd\\x7b\\x53\\xde\\x64\\x00\\xc3\\x51\\x01\\xce\\xb2\\xda\\x97\\xbc\\x13\\x55\\x78\\x3d\\xc5\\x0d\\x66\\x80\\x67\\x8e\\x0f\\x6d\\xa6\\xdf\\x55\\xfd\\x22\\xd1\\x93\\xf5\\x75\\x80\\xa3\\x78\\xfb\\x51\\x66\\x20\\xd5\\x2b\\xb7\\x11\\x02\\xf1\\x7f\\x9f\\x53\\x28\\x18\\x43\\x4f\\x2a\\xc7\\x97\\x23\\x08\\x19\\xc1\\x6a\\x4f\\x61\\x7f\\x3d\\x3f\\xd8\\x65\\xa9\\xad\\xb5\\xd0\\xe0\\x42\\x40\\xa5\\x7c\\x13\\xba\\x4b\\xa8\\x23\\x18\\xad\\x68\\x44\\xac\\x8b\\xd6\\x00\\xc7\\xfb\\xfd\\x08\\x76\\xe7\\xdf\\xe3\\x82\\x1d\\x94\\xac\\x5d\\xad\\xc6\\xc4\\x3f\\x3a\\x3d\\x66\\xd9\\x43\\x91\\x13\\x02\\x47\\xa8\\x5f\\x1f\\x19\\x2f\\x70\\xd9\\x50\\x2e\\x91\\x13\\x42\\xa2\\xd4\\xb3\\xec\\x48\\x34\\xcb\\x34\\x8f\\x01\\xf5\\xeb\\x2a\\x0b\\x6d\\xf0\\x0d\\x64\\x13\\x80\\x3b\\x93\\xaf\\x81\\x49\\x0b\\x91\\x4d\\x2f\\x48\\xc4\\x4f\\xcf\\x35\\x9a\\x01\\xf3\\x2f\\x1f\\x8e\\xf4\\x0c\\xf0\\xa1\\xe3\\x0d\\x4d\\xfc\\xef\\xec\\x37\\x0d\\xb4\\x37\\xa6\\xbd\\x18\\xdf\\x4e\\xe9\\x56\\x45\\xd0\\xba\\xcd\\x02\\x97\\x32\\xd1\\xf9\\xe4\\xb1\\xa6\\xdc\\x1a\\xa8\\xf8\\x43\\xfd\\x3a\\x63\\xb1\\x05\\x1a\\x21\\xeb\\x0e\\xdc\\x9a\\x66\\xd4\\x7f\\xb8\\xd9\\xb3\\xf5\\xa6\\xd8\\x4a\\xc9\\x4f\\x5f\\x20\\x86\\x4d\\x62\\x0b\\xef\\x68\\x4b\\x9b\\x37\\xfe\\x46\\x3d\\x30\\x36\\x5e\\xe3\\x85\\x5e\\xe3\\x49\\xbf\\x14\\x46\\xa3\\xa0\\x56\\xf0\\xe5\\x16\\x86\\x39\\x00\\x77\\xe9\\x7e\\xc7\\x28\\x9b\\xc5\\xe9\\x9b\\x33\\xc6\\xf3\\x53\\xc3\\xd8\\x2b\\xd6\\x3b\\x75\\x8c\\xf2\\xda\\x56\\xd1\\xa7\\xaf\\x48\\x18\\x61\\x7b\\x84\\xeb\\xa6\\xed\\xf4\\xf1\\xf8\\x10\\x61\\xb5\\x39\\x4d\\xc7\\xc6\\x97\\xbd\\x32\\x39\\x58\\xa7\\x3a\\xfb\\xb2\\xc7\\x4e\\x4f\\x54\\x3d\\x50\\x6e\\x86\\x44\\xa7\\x91\\x1f\\xbf\\x6c\\x9a\\x18\\xb3\\xcc\\xbe\\x71\\x8a\\xc3\\xfd\\x8f\\x6e\\x17\\x1a\\x01\\x2f\\x4e\\x17\\xb2\\x94\\x05\\x46\\x06\\x37\\x00\\xf8\\xd0\\xb4\\xc0\\xa3\\x2e\\x45\\xa8\\x96\\xd9\\x5b\\x5b\\x68\\xe3\\x33\\x13\\xe6\\x64\\xd3\\xf4\\xe3\\xf7\\x30\\x5c\\x96\\xb2\\x9e\\x66\\xca\\x6d\\xe1\\xd0\\xa9\\x37\\x1f\\xa5\\x72\\xa5\\xbb\\xd8\\x71\\xe6\\xdf\\xb9\\x64\\x8b\\x7a\\x46\\x02\\x40\\x08\\xbc\\x33\\x16\\xc2\\xc3\\xf9\\xca\\x08\\x60\\x7f\\x4a\\x7e\\x2b\\x61\\xb4\\x5c\\xab\\x69\\x1b\\x51\\x59\\x20\\xa6\\x88\\x40\\x05\\x06\\xe6\\xb3\\x71\\x1b\\x2d\\x24\\x9d\\x82\\xa2\\xd8\\x1f\\x38\\x23\\xd1\\x22\\x49\\x3f\\xed\\x15\\x0b\\xb5\\x7a\\x73\\x72\\x6a\\x05\\x8d\\xf2\\x9f\\xef\\x6e\\x3f\\x77\\xec\\x7a\\xb8\\x36\\x62\\x00\\xf9\\x95\\xb0\\xc9\\x21\\x65\\xab\\x06\\x12\\x6f\\xad\\x6b\\x70\\x09\\x60\\xd3\\x8f\\xb8\\xd0\\x78\\x3f\\xd3\\x09\\x24\\x19\\xb6\\xd3\\x69\\x5b\\x1c\\x8f\\x2a\\xbf\\x4a\\xaf\\x64\\x5c\\x2e\\x5e\\xee\\x9f\\x71\\x8a\\x9d\\x95\\x31\\x5c\\xf0\\xdd\\x34\\xd3\\xbf\\x7b\\x84\\x2d\\xdf\\xbc\\x74\\x10\\xaf\\x86\\x9f\\x6f\\x10\\x8e\\xdd\\xfb\\x51\\x07\\x4a\\xe6\\xfb\\xaf\\xb2\\x5e\\xad\\xc0\\xbc\\x7f\\xe2\\x29\\xa6\\x61\\x81\\xab\\x76\\x21\\xbc\\x60\\x26\\x67\\x2f\\xca\\xcf\\x11\\xaf\\xe0\\x74\\x8d\\x25\\x7c\\x38\\x5c\\x79\\xa3\\x46\\x5d\\xc0\\xb1\\x7b\\x03\\x03\\x64\\x49\\x6e\\x8a\\x7f\\x5e\\x19\\x14\\xc7\\x63\\x51\\x05\\x87\\x54\\x9f\\xfe\\x2f\\x36\\x05\\x78\\x86\\xee\\x40\\x64\\x91\\x9c\\xd7\\x77\\x5b\\xc7\\xf3\\xbb\\x73\\xc7\\x14\\xb0\\x62\\x9b\\xcd\\xeb\\xbc\\x84\\xa7\\x3c\\x9a\\x91\\xeb\\x76\\xd3\\x03\\x4c\\xbd\\x6d\\xd4\\x54\\x9f\\xd0\\xfc\\x29\\x5b\\x9e\\xf0\\x07\\x2b\\xc4\\x7b\\x6a\\x44\\x76\\x8e\\xf2\\x52\\xa5\\xf7\\x6c\\xca\\x0c\\xc3\\x60\\xd3\\xbe\\xef\\x64\\x13\\xe1\\x70\\x66\\xeb\\x1a\\xec\\xfc\\x3a\\x46\\xb1\\xd1\\x7c\\xde\\x40\\xd4\\xd2\\xd4\\xd5\\x3f\\x2a\\xb7\\xcb\\x97\\x8d\\xfc\\x89\\x73\\xf9\\xbe\\x41\\x76\\x9e\\x42\\x2a\\x18\\x29\\x02\\x22\\x59\\xf7\\x4d\\xa3\\x2e\\x62\\x5c\\xd7\\xc5\\x43\\x18\\xe4\\x58\\xda\\xe6\\xd5\\x8b\\xce\\xbd\\xae\\x8d\\x93\\xc3\\x4c\\x69\\x71\\xc3\\xfb\\xef\\x4c\\xf0\\xfa\\x86\\xcb\\x3d\\x86\\x37\\xe8\\x01\\x7d\\xd4\\xd5\\x7b\\xf5\\x21\\x8d\\xd8\\x02\\xc4\\x5d\\x88\\x74\\xb4\\x2f\\x0c\\x26\\xcc\\x46\\xf2\\xa3\\x18\\xb5\\xf7\\x7a\\xcd\\xdd\\x01\\x9f\\x38\\x72\\xc9\\xda\\xf5\\x31\\xaa\\x61\\xf1\\xfe\\x72\\xd2\\x83\\xdc\\xd8\\x4b\\xbf\\xc6\\xa0\\xf7\\x03\\x96\\x3f\\x15\\xba\\x59\\xe4\\xb9\\x2d\\x1a\\x25\\xd4\\xd6\\x34\\x82\\x06\\x9c\\x69\\xe6\\xe8\\x26\\xdb\\xc8\\x15\\x40\\xe3\\x38\\xff\\xe2\\x68\\x59\\xc7\\xcd\\x50\\x1f\\x45\\x68\\x32\\x3a\\x42\\x99\\xcb\\xed\\x30\\x57\\x4e\\x54\\xfb\\xc1\\xf5\\xe3\\x38\\x1e\\xb7\\x8b\\x90\\x2f\\xe0\\x7b\\x73\\x22\\x2e\\x05\\xd8\\x9d\\x1e\\xec\\xde\\xfe\\xe6\\xd1\\x17\\x7c\\x4a\\x7e\\xb3\\xe0\\x4f\\xa0\\x7b\\xd5\\xc4\\xda\\x05\\x8c\\x6f\\xb4\\x50\\xad\\xbc\\xa6\\xbf\\xd1\\x29\\xbe\\xb0\\x83\\xea\\x07\\x08\\xa2\\x79\\xf3\\x0c\\xa6\\x73\\x5d\\x6e\\x13\\x3b\\x5c\\xfc\\x7d\\x4d\\x3d\\xcb\\xfc\\xc4\\x72\\xec\\xe3\\xe4\\x23\\x57\\xb5\\x26\\xec\\xc7\\xe2\\xe1\\xe7\\xb9\\x98\\xfc\\x97\\x5f\\x12\\x2e\\xef\\x15\\x41\\x3b\\xca\\xd0\\x5d\\xb2\\xc6\\xdb\\xd9\\xc6\\xe6\\x3d\\x77\\x81\\xe5\\xff\\xc9\\x0d\\xb5\\x7c\\x0f\\x48\\x91\\xde\\xfd\\x58\\x8f\\x7c\\x29\\xfc\\x8f\\x2c\\xe3\\xbf\\x9c\\x13\\x17\\x47\\xfd\\x38\\x82\\xbb\\x6a\\x5e\\xc0\\xa5\\x5d\\xf6\\x44\\xc7\\x37\\x8f\\xef\\xb1\\x9b\\xff\\x1e\\x9a\\xf3\\x07\\xff\\xe4\\xf1\\x9e\\x80\\xa3\\x95\\x8e\\xb2\\x37\\x4a\\x16\\xd6\\x23\\x19\\x3c\\xf6\\x34\\xd0\\x7c\\x75\\xd5\\x81\\xcc\\xe6\\x03\\x44\\x10\\xea\\x7e\\xca\\xed\\x28\\x62\\x76\\xba\\xb6\\xa3\\x01\\xf9\\x46\\xba\\xeb\\xfb\\x8f\\xde\\x60\\x8f\\x6c\\xb3\\xd8\\xb2\\xf2\\x6f\\x8e\\x7c\\x12\\x24\\xf6\\x9b\\x13\\x5c\\x9a\\xc1\\x8b\\x15\\x7c\\x4a\\x5f\\x3c\\xb1\\x47\\x86\\xf8\\x1f\\x9f\\xec\\xba\\x52\\x26\\x56\\x9b\\xde\\x8b\\xfd\\x5c\\x13\\x2c\\x0e\\xbd\\x3d\\x56\\x30\\x76\\x59\\xce\\xe7\\x46\\xfe\\xfe\\x8b\\x2f\\x4c\\x01\\xf9\\x70\\x7a\\xc3\\xb4\\x94\\xd1\\x3e\\xaf\\x0a\\x6b\\x7c\\x79\\x1e\\xf4\\x69\\x48\\xa0\\xd9\\x92\\xb6\\xca\\xda\\x0d\\xd9\\xfe\\xeb\\xe9\\xac\\xf2\\xf6\\x8c\\xe9\\xc9\\x4d\\xdf\\x55\\xaa\\x0e\\x48\\x25\\x5e\\x01\\x53\\x5d\\xb5\\xc1\\x16\\xff\\x13\\x57\\xb5\\xcc\\xc3\\x9c\\xaf\\x60\\xbe\\x43\\xae\\x95\\xd5\\x48\\x98\\x98\\x88\\x44\\x3c\\xa8\\xde\\x9c\\x52\\xfe\\xf8\\x11\\xd2\\xa5\\x58\\xb1\\xc2\\x97\\xf9\\x5a\\x8b\\x85\\x39\\x3d\\x15\\x7f\\x05\\x8c\\x5b\\x66\\xf6\\xd6\\x60\\x0e\\xff\\xfe\\xff\\x58\\x86\\xad\\x1b\\xd5\\x13\\x8e\\x84\\x58\\x3b\\x48\\x52\\x44\\x11\\xbe\\x80\\x53\\x87\\x34\\xec\\x7f\\xd6\\x3b\\x23\\x3d\\xd2\\xcd\\x2c\\x8a\\x7d\\x23\\xef\\x83\\xd7\\x28\\x57\\x30\\xa6\\x30\\xdc\\x0d\\x90\\x73\\xee\\x07\\x32\\xb0\\x7f\\x5c\\xe6\\x6f\\x42\\x56\\xfe\\xa7\\xd2\\xca\\xb7\\x01\\x92\\x15\\x4f\\xb0\\x08\\xd7\\x3f\\x8e\\x5a\\xe8\\xd2\\xaf\\x78\\xee\\x7f\\xd6\\xfa\\x51\\x00\\x9e\\xb1\\x1e\\x26\\x6f\\xb3\\x75\\xe5\\xb7\\xb3\\xb4\\x4e\\xfe\\x48\\xc5\\x21\\x12\\x95\\x80\\xf8\\x7f\\xb1\\xc9\\xaf\\x67\\xb4\\x40\\x01\\x07\\x43\\x8f\\x95\\x3f\\xf3\\xee\\xd8\\x11\\xbf\\x34\\xf2\\x0f\\x7e\\xc7\\x97\\x94\\xc3\\x92\\x93\\xfd\\x8a\\xf3\\xd6\\x68\\xfa\\x1d\\x69\\x77\\xa5\\x0f\\x66\\xf3\\xb5\\xdb\\x1d\\x2a\\xfe\\x5f\\x1c\\x6c\\x2e\\x87\\xd9\\x77\\xfe\\xda\\xc8\\xd6\\x55\\xb9\\xf7\\x1b\\x0a\\xe1\\x6d\\xb5\\x6f\\xc0\\x54\\xd5\\x05\\xa1\\x8d\\xec\\x74\\x7f\\x79\\x14\\xf9\\xde\\x5d\\x94\\xde\\x2f\\xad\\x99\\xa1\\xc8\\x76\\xc9\\x76\\xa9\\x9e\\x8c\\xa7\\xd0\\x0d\\x01\\x27\\x94\\xdb\\x2e\\xfe\\x27\\xee\\x64\\xc7\\xdc\\x41\\xe5\\x53\\xab\\x44\\x88\\xb2\\x1c\\x7a\\xb2\\x64\\xb8\\xfa\\x76\\x01\\x57\\x90\\x6d\\xa1\\x72\\xb6\\x03\\xfd\\x5b\\xcb\\xc4\\x8a\\x2f\\xc6\\xbe\\xbb\\x48\\xe5\\x69\\x2a\\x0e\\x88\\xb5\\xa0\\x01\\x93\\x03\\x74\\x21\\xb3\\x1f\\xd1\\xfb\\x1f\\x1c\\x40\\x79\\x12\\x06\\xa9\\x7c\\xd5\\x98\\xb6\\x39\\xef\\xb5\\x7a\\xfe\\xda\\xf7\\x03\\xf9\\xbb\\xcc\\x33\\xec\\x3f\\xbc\\x09\\x9f\\x49\\x4a\\x7b\\xcf\\x14\\x39\\x11\\x37\\x5d\\x1a\\x0c\\x1b\\xa9\\xfa\\x38\\x86\\x4d\\x9d\\x62\\x1e\\xb9\\x76\\x41\\xfe\\x3c\\x4c\\xb7\\x0d\\x7f\\x71\\x96\\xe7\\xe6\\x5d\\x76\\xa2\\x68\\xb1\\x60\\x23\\xfa\\x73\\x84\\x33\\x2d\\x7f\\x4a\\x98\\x61\\x76\\xd9\\xd5\\xe9\\x24\\x70\\xfe\\xd3\\xfb\\x8e\\x46\\x14\\xfe\\xa8\\x58\\xa0\\x32\\xef\\x0f\\x82\\xa1\\x86\\xf7\\xb1\\x9a\\x7b\\x9f\\x2c\\xc1\\x0c\\x45\\x31\\x0c\\x57\\xc7\\x10\\xdc\\xbf\\xdc\\x54\\x46\\x97\\x3e\\x54\\xe4\\xd3\\x20\\xb3\\xc9\\x33\\x2d\\xff\\xfe\\x6d\\x6d\\xb3\\xd4\\xc4\\x47\\x9b\\x07\\x46\\x8e\\xb8\\x2b\\x5a\\xa8\\x43\\x14\\x3c\\x66\\xfc\\xc1\\x8e\\x0d\\xa2\\xf0\\xbb\\xca\\xd5\\xac\\x1c\\xab\\x9c\\xeb\\x83\\xb6\\x83\\x4d\\x14\\x4e\\x61\\xa2\\x65\\xa8\\x78\\xdb\\x3f\\xcc\\xa7\\x73\\xd5\\x79\\x31\\x76\\x9d\\xcd\\xf4\\x65\\x9c\\xbe\\x25\\x97\\xf6\\x3b\\xdc\\xbb\\xee\\xf2\\x51\\x53\\x61\\x21\\xb9\\xc6\\xfb\\xee\\x34\\x38\\x61\\x08\\xc4\\x75\\x54\\xdc\\xa9\\x2c\\x20\\xaf\\xff\\x83\\xc5\\x39\\xc9\\x1e\\x46\\x1c\\x91\\xd4\\xc3\\x7a\\xc0\\x03\\x83\\xc5\\xe6\\xdb\\xaa\\xa9\\xad\\x7e\\xd8\\xcf\\x4d\\x55\\x8a\\xfb\\x35\\x88\\x6c\\xf9\\xf4\\x45\\x79\\x60\\x4b\\xc1\\x0f\\xa9\\xd1\\xf1\\x6b\\x98\\x3a\\xde\\x1f\\x1d\\x18\\x35\\x3a\\xc3\\xf7\\x9d\\x5b\\x9e\\xf2\\x29\\xe9\\xc6\\xd9\\x06\\xa6\\xd4\\x21\\xc8\\x85\\x48\\xd7\\x23\\x1d\\xbc\\x8a\\xa9\\x1a\\xdf\\x94\\x75\\x76\\xb7\\xee\\x15\\x75\\xd8\\x17\\xc0\\x6e\\x26\\xfc\\xe1\\xfd\\xe3\\xe4\\x22\\xff\\x94\\xa2\\x26\\x1b\\xe7\\x00\\xda\\x9c\\x0f\\xd3\\x90\\xd5\\x3e\\x6d\\xc1\\x75\\xae\\xc7\\xa6\\x43\\x25\\xd8\\xfc\\x85\\xe2\\x60\\xe4\\x79\\x6f\\x73\\xd4\\x29\\x0e\\x86\\xd9\\xe6\\xb8\\x8e\\xce\\x4e\\x3d\\x76\\x33\\xc1\\xf0\\xfc\\x27\\x07\\x97\\xa0\\x62\\x1c\\xff\\xd5\\xa6\\x03\\x9c\\x6a\\xba\\xfa\\xae\\xd9\\xba\\xcb\\x6c\\x53\\x98\\x3a\\x2e\\xd3\\xc7\\x07\\x3b\\xb5\\x74\\x11\\x31\\xf2\\xeb\\x61\\x93\\x52\\xe6\\x69\\xb6\\xb9\\x98\\x7d\\xd0\\xb6\\x36\\x76\\xae\\x8a\\x8a\\x9a\\xb8\\xff\\xcf\\xef\\x81\\x79\\xf9\\xa5\\x8d\\x80\\x36\\xef\\xd7\\x44\\x9b\\x0e\\xf4\\x56\\xe1\\xf3\\x9b\\xb3\\xce\\x1f\\x91\\x84\\x6b\\x20\\xeb\\x35\\xf3\\x30\\x1c\\x52\\xfb\\x30\\xda\\x4a\\x45\\xa7\\xe2\\xd9\\x45\\xb5\\x78\\xdb\\xdd\\x38\\xa8\\xb6\\xe1\\x3a\\xec\\xf8\\xa3\\x6b\\xb9\\x47\\x68\\x29\\x84\\xc1\\x2b\\x94\\x9b\\x8a\\xda\\x0e\\x07\\x38\\x14\\x13\\x54\\xbc\\xf7\\x5c\\xfe\\xb8\\x43\\xa2\\x2c\\x42\\x22\\xb7\\xc4\\xb2\\xae\\xf3\\x7e\\xe0\\x58\\xa5\\x1c\\x75\\x4a\\xc4\\xee\\x3c\\xee\\x19\\xd9\\x7e\\x03\\xee\\x9f\\xce\\x67\\x1b\\xc5\\x75\\xc5\\xbd\\xfc\\x1e\\xb0\\x26\\xee\\x6f\\x4c\\xcb\\x3b\\xf7\\x9f\\xbd\\x7c\\x8a\\x71\\x49\\xb8\\x0e\\x42\\x34\\x5b\\x4b\\x79\\x9d\\x66\\x30\\x4b\\x9b\\x07\\x37\\x08\\x55\\x3f\\xff\\x30\\x6d\\x85\\xbf\\xfa\\xc2\\x26\\xe0\\x8b\\x7d\\x4d\\xe9\\x7f\\x7b\\x97\\x34\\x65\\xe3\\x45\\x7a\\x5a\\xf8\\x6b\\x35\\xae\\xb5\\x0d\\x02\\xfb\\xc2\\x38\\x62\\x14\\x60\\x95\\xe4\\xba\\x9c\\x76\\xaf\\x8c\\x91\\xcb\\xec\\x62\\x2d\\xa1\\x02\\xc3\\x61\\x3c\\x58\\x1e\\xd5\\xc1\\xf4\\xf4\\xa5\\xa0\\xd1\\xbb\\xe5\\x53\\xbe\\x1d\\xc5\\xe1\\x7f\\x38\\x42\\x39\\xf6\\x2b\\x62\\xb6\\xeb\\xb5\\xb6\\xe8\\x46\\xf8\\x91\\x5a\\x91\\xaa\\x8d\\xc4\\xd9\\xad\\xf9\\x5b\\x27\\x36\\x2f\\x25\\xcf\\x18\\x04\\x19\\x5c\\x7e\\x92\\x8a\\x73\\xbc\\xc2\\x6f\\x0a\\xb9\\x07\\xd2\\x69\\xe9\\x3b\\x18\\x1e\\xa3\\x34\\x03\\x64\\x0d\\xca\\x53\\xbd\\x4d\\xab\\xae\\x61\\xdb\\xff\\xc5\\xba\\x6b\\xfd\\xa2\\xb4\\x64\\x7d\\x1a\\x86\\xcf\\x70\\xd0\\x4e\\xf3\\x3c\\x0d\\xb4\\x4f\\x80\\x99\\xfa\\x95\\xcc\\xd7\\x2c\\x35\\xb8\\xe9\\x07\\x77\\xa6\\x2f\\x79\\x36\\x9e\\xcb\\x3d\\xb9\\x80\\x43\\x00\\xcf\\x81\\x79\\x5d\\xa5\\xb3\\x1e\\x53\\xfc\\xe0\\xb4\\x8c\\x76\\xab\\x39\\x43\\xe9\\x79\\xe7\\x96\\x02\\x6c\\x1e\\x45\\xd8\\x75\\x81\\xd3\\x25\\x88\\x21\\xd6\\x73\\xda\\xdb\\x2a\\x96\\xc8\\xed\\x08\\x47\\xdc\\x5d\\x7d\\xa8\\xba\\x2d\\x54\\x1f\\x67\\x99\\x21\\x4f\\x89\\x9a\\x4f\\x72\\x3b\\xad\\x98\\x2a\\x94\\xe0\\xd0\\x9d\\xa4\\x18\\xdc\\x66\\x5f\\xf9\\x87\\x4d\\x7f\\xfb\\x04\\x3a\\x1a\\x20\\x15\\xfa\\xb5\\xd0\\xc0\\x4b\\x44\\x19\\xfd\\x77\\xce\\x58\\x4d\\x75\\x35\\x57\\xd7\\x6c\\x4a\\x31\\x1b\\xb4\\xd1\\x09\\x92\\x8f\\x41\\xaa\\xc1\\xcb\\x02\\xd7\\x1c\\x99\\xf2\\x70\\xaa\\xde\\xd9\\xdf\\x7b\\xd6\\xf3\\x04\\x31\\xe5\\x1e\\x6a\\xe9\\x36\\x30\\xcf\\x9d\\xf0\\x6c\\x5e\\x53\\x89\\x34\\xd5\\xfd\\xce\\xf5\\xc3\\x40\\xdf\\x3c\\x77\\x66\\xc1\\x2a\\x67\\x29\\xba\\x99\\x21\\x4d\\x55\\x4b\\x50\\x25\\xcf\\x6d\\x2d\\xc6\\xe8\\x8f\\x4e\\x6d\\x91\\x57\\xff\\x8c\\xa8\\xea\\x50\\x16\\x01\\x81\\x28\\x10\\xf0\\x92\\x26\\xfb\\x27\\x52\\xaa\\xaa\\x05\\x7d\\xbf\\x70\\x48\\xf8\\xca\\x42\\xdb\\x2f\\x50\\x35\\xbd\\x5d\\x57\\x38\\x0e\\xf4\\x4e\\x86\\x97\\xd8\\xb4\\xd2\\xe8\\x59\\xe8\\xad\\x21\\x8c\\x1e\\x7c\\xde\\x95\\xcd\\x91\\xb4\\xc5\\x9e\\x77\\xcb\\xbf\\x24\\x26\\x5c\\xab\\xc7\\xbe\\xcf\\xdf\\x7b\\xe3\\x0c\\xcb\\x7c\\xda\\x40\\x69\\x7b\\xaa\\x77\\x5a\\xe2\\xe9\\xa0\\xa8\\x49\\xda\\x79\\xc2\\x5f\\x00\\x42\\x32\\xc2\\x55\\x13\\xd8\\xf2\\xad\\x9b\\x71\\x16\\xac\\xec\\xbf\\xd9\\xde\\x8a\\xcc\\xec\\xb2\\x92\\x00\\x49\\x92\\xb3\\x77\\xaf\\xe4\\x15\\xcb\\x0b\\x5b\\x2d\\x6c\\x2a\\xf7\\x18\\xc6\\x21\\x5b\\xb0\\x9e\\x63\\xb5\\xcf\\x9f\\x44\\x1a\\xc3\\x29\\xb2\\xab\\xd4\\x48\\x91\\xf6\\xa6\\x91\\xbf\\x38\\xaa\\xe1\\xb6\\xae\\x25\\x26\\x7b\\x59\\x30\\x79\\x08\\x04\\x27\\x2f\\xe5\\xa7\\x26\\x6b\\x9e\\xe0\\x14\\xa9\\xcb\\x8e\\xe1\\x63\\x48\\x1c\\xa7\\xde\\xf8\\xd8\\x69\\x3a\\x5c\\x7d\\x2e\\x59\\xd3\\xa6\\x75\\x97\\xaf\\x72\\x71\\x50\\xac\\xf8\\x33\\x28\\x93\\xb4\\xe5\\xab\\x45\\x8b\\xe2\\x5e\\x2b\\x1e\\x6b\\x91\\x76\\x60\\xc4\\xf5\\x46\\x6b\\xab\\x29\\x73\\xd3\\x89\\xcc\\x1c\\x5a\\xf4\\xda\\x49\\xa5\\x1f\\x8f\\xb4\\x1c\\xa1\\x07\\x89\\x9b\\xf4\\xb8\\x63\\xe3\\x48\\xf8\\x1f\\x54\\x77\\x2f\\xcb\\x7b\\x64\\x8b\\xca\\xaa\\x77\\x71\\xef\\x69\\xa6\\x85\\x24\\x2a\\x77\\x2b\\x0a\\x34\\xfb\\x73\\x8d\\x8e\\x79\\xfa\\x7f\\x75\\x05\\xa3\\xc8\\x89\\xa4\\x33\\xb1\\xa9\\xee\\x39\\x26\\xce\\xb4\\x6c\\x30\\xaf\\x7f\\x5e\\x9f\\x12\\x07\\x2d\\x1c\\x2d\\x90\\x3b\\xf7\\x0a\\x87\\xe3\\x3d\\x1c\\x4d\\x45\\x70\\x7f\\xee\\x4d\\x18\\xed\\x5a\\x53\\xb6\\x95\\xb4\\x16\\x2d\\x4f\\x39\\xde\\xf6\\x21\\x4a\\xa6\\xc8\\xc6\\x32\\x8e\\xc4\\x1c\\x94\\x4a\\xce\\xf5\\xe1\\x54\\x64\\xca\\x12\\x9a\\x9c\\x3a\\x8d\\xbf\\xcb\\x71\\x4e\\xbc\\xcd\\xcd\\x40\\xcf\\xe6\\x68\\xc8\\xb6\\xbb\\x9a\\xfc\\x59\\x4f\\x73\\x6b\\x3e\\x92\\x83\\x8c\\xd0\\x93\\x84\\xf9\\xed\\x94\\x55\\x03\\x7c\\xe9\\x8c\\x90\\xd0\\x33\\xae\\xc2\\xf5\\x10\\x37\\x2e\\x56\\x4d\\xe1\\x57\\x84\\x94\\xec\\xae\\x8b\\x59\\xed\\xbb\\x93\\xd6\\x18\\x3c\\xe6\\x66\\x7f\\x72\\x41\\x8b\\xdf\\xf5\\x69\\x43\\x6e\\x73\\x97\\x46\\xe9\\xf9\\xef\\x70\\xff\\x9d\\xac\\x53\\x61\\x6b\\x23\\x4c\\x47\\xeb\\x04\\x52\\x62\\x20\\x69\\x8f\\x75\\x47\\x14\\xc2\\xf4\\x35\\xc1\\x60\\x97\\xf0\\xe7\\xbc\\x2c\\xf6\\xd2\\x39\\x04\\x32\\xf7\\xad\\xef\\x18\\xe5\\x97\\x6c\\x24\\xb3\\xf8\\x19\\x42\\x3d\\x45\\xca\\x20\\xe5\\xed\\xac\\x57\\x8d\\xc6\\xfc\\x24\\x50\\x07\\x77\\x8f\\x97\\xab\\x6f\\x98\\x6d\\x61\\xa1\\xef\\x25\\xa9\\xb5\\x67\\xc3\\xb6\\xa5\\x22\\x83\\xfa\\xdf\\xba\\x4a\\x46\\xe0\\xcf\\x6c\\xfe\\xb8\\x19\\x5f\\x69\\x0e\\x15\\x74\\x9e\\xa9\\xac\\x04\\x7e\\x94\\xb3\\x69\\x7b\\xa7\\xd6\\x20\\xf2\\x05\\x46\\x67\\xbb\\x0a\\x31\\x1a\\xe1\\xcf\\xf9\\x58\\xb4\\xd2\\xd9\\xbb\\xb9\\x9e\\x98\\x4e\\xa7\\x9d\\x79\\x54\\x64\\x6c\\x8c\\x5f\\xb7\\x24\\x0b\\xa8\\xd3\\xfc\\x27\\x5e\\xe2\\x5a\\x2a\\x91\\x49\\x80\\x46\\x85\\xc6\\x23\\xc4\\x61\\xe0\\x53\\xe0\\x89\\xfe\\x2f\\x86\\xc0\\x70\\xcc\\xa9\\xf1\\x82\\xf7\\xc9\\x1d\\x22\\xf6\\x3b\\x7c\\x84\\xd4\\x66\\x63\\x45\\x3c\\x3c\\x65\\xb4\\xb7\\x3d\\x02\\x8c\\x90\\x03\\x3d\\x88\\x1c\\x99\\x21\\x69\\x09\\x35\\xb5\\x22\\xac\\x27\\x72\\x9e\\x23\\xdc\\x86\\x6e\\x05\\x26\\x3c\\x66\\xe1\\x52\\x4e\\x09\\xbb\\x24\\x67\\xbc\\x24\\x52\\x39\\x2a\\x69\\x66\\x4c\\x02\\xcf\\x16\\x78\\x66\\x0b\\x21\\xc7\\xd6\\x9c\\xbf\\xbe\\x09\\xa3\\x70\\x58\\x67\\x2a\\xb1\\xe0\\xf9\\xd6\\xa4\\xf0\\xe1\\x77\\x58\\x4d\\x77\\x0d\\x3d\\xfa\\x20\\x21\\x20\\x7e\\xe8\\xda\\x63\\x64\\xac\\xa1\\x04\\x69\\x39\\x81\\xca\\xb9\\xd5\\xfe\\x93\\x6d\\xa6\\x2b\\x7d\\x61\\x64\\xbd\\x01\\xfb\\x05\\xf0\\x25\\x8b\\x70\\xc5\\x41\\x25\\xe6\\x42\\xcc\\x4f\\x9a\\xea\\x52\\xa6\\xcd\\x9b\\xd2\\xff\\xb2\\xf7\\xd8\\xe1\\x64\\x76\\xc7\\x30\\x0b\\xc3\\xe3\\xc5\\xdf\\xa3\\xa4\\x34\\x3a\\xd1\\xb9\\xfd\\xd7\\x70\\xc3\\x8e\\xcc\\xd3\\xdc\\x14\\x50\\x84\\xde\\xe9\\x78\\xa5\\xd1\\x99\\x29\\x5f\\xdb\\x02\\xd6\\xf2\\x1a\\x39\\x48\\x3e\\xed\\x78\\x05\\xe2\\xe7\\xb6\\x3d\\x60\\x06\\xc6\\x2c\\xb7\\x53\\xd8\\xdc\\x32\\xf8\\x90\\xd3\\xb1\\xfa\\x5c\\xd4\\xe7\\xae\\x43\\x80\\xee\\x24\\x23\\x4b\\x76\\xe1\\xee\\xc0\\xb7\\x25\\x55\\x96\\x9d\\x66\\x5a\\x72\\x3a\\xdb\\x60\\x15\\x16\\x7e\\x4e\\xff\\x25\\x50\\xe6\\x61\\x4c\\x4b\\xb8\\xd8\\xbf\\x1b\\x29\\x0b\\xb7\\x64\\xbb\\x33\\x94\\x4e\\xe9\\xcb\\xa5\\x7e\\xb3\\x65\\x7b\\xc8\\xb5\\x90\\x35\\xa2\\x90\\x9d\\xc0\\x66\\xfe\\xa5\\x18\\xdb\\x73\\x4b\\x3a\\xc3\\x9c\\x1b\\x8c\\xab\\x85\\xfb\\x68\\xd9\\x47\\x98\\x68\\x31\\x7a\\x79\\xd3\\x4e\\x10\\xd6\\x31\\xd8\\xd6\\xc8\\xe2\\xa1\\xe4\\x93\\xa7\\x09\\xbc\\x83\\xe5\\x00\\x45\\xee\\x50\\xce\\x63\\x2d\\xd3\\x80\\xb6\\xb2\\xde\\x28\\x9b\\xd4\\x12\\xbe\\x25\\xb9\\xb1\\x67\\x81\\x58\\xf8\\xd1\\x21\\x1c\\x84\\xfa\\x56\\x8b\\x78\\x31\\x3b\\xe8\\x73\\xc8\\xcd\\x70\\xb6\\x09\\x79\\x49\\x8f\\x47\\xaa\\xba\\x38\\x5c\\x08\\x4e\\xcc\\x87\\x27\\xd9\\x02\\xb6\\xe7\\xe5\\xe3\\x71\\x01\\xdf\\x17\\x24\\xe4\\xcd\\x56\\x07\\x93\\xe1\\xe0\\xce\\x55\\xa3\\x15\\x89\\x0a\\xbe\\x2d\\x42\\x80\\xca\\xaa\\x1e\\xd4\\xb1\\x68\\x39\\xf3\\x73\\x3a\\xc9\\x21\\x59\\x86\\x72\\x16\\x68\\x72\\x0c\\xd3\\xe5\\x35\\xd5\\xd6\\x52\\x77\\xe4\\x4c\\x1f\\xcc\\xef\\x30\\x9c\\xb1\\xfe\\x57\\xae\\x2a\\x76\\x30\\x3d\\x45\\xed\\x75\\xdd\\x4e\\x07\\x93\\x3f\\xf6\\xe7\\xcd\\x17\\xcc\\xac\\x3b\\xcb\\x2c\\xe8\\x8c\\x9c\\xab\\xf7\\xaa\\x72\\xf2\\x2b\\x0b\\x28\\x64\\x5f\\x2f\\xab\\x46\\xea\\xba\\xc2\\xc0\\x1e\\x16\\x53\\x3f\\x8b\\xb2\\x02\\x9b\\x5c\\xda\\x01\\x34\\x61\\x7d\\x8e\\x0c\\x31\\x57\\xb5\\x06\\x53\\x7b\\xef\\x7c\\x5b\\xdf\\x87\\xf5\\x10\\x4f\\xe0\\xf1\\x95\\xf8\\xd7\\x9c\\xd1\\xff\\x9b\\x53\\x1c\\x8c\\xb4\\x71\\x5a\\x85\\x1a\\x7a\\x63\\x40\\x3b\\x08\\x2f\\xa2\\x1d\\x1f\\x47\\xa2\\x6a\\xc9\\x5a\\xc6\\x41\\x88\\xae\\x69\\xa5\\x86\\x81\\x1a\\xa4\\x81\\x7e\\xc8\\x74\\xd5\\x1f\\x87\\x15\\x81\\x10\\x0d\\x12\\x1c\\xb4\\x44\\xcb\\xb7\\x80\\x3a\\x1a\\x98\\x0d\\x56\\xd1\\x5c\\x98\\xf8\\xf8\\xd9\\x12\\x6a\\xae\\xaf\\x57\\x0b\\xae\\x19\\x05\\xa1\\xda\\x97\\xc0\\xad\\x3d\\xe7\\xa9\\x57\\x12\\x41\\x8d\\x7d\\x61\\x7f\\xb7\\xfa\\x36\\x8e\\xdd\\x71\\x95\\xde\\x81\\xea\\x68\\x50\\x1e\\xf7\\xe3\\xfb\\x3c\\x29\\x9b\\xd3\\x49\\xd5\\x1f\\x2a\\x6e\\xf0\\xcf\\x7a\\xa0\\x66\\xe0\\xa3\\x5d\\xe7\\x28\\x4e\\x47\\xc4\\xd2\\xf5\\x12\\xb8\\xe0\\x32\\x5b\\x98\\x6d\\x70\\xb4\\x72\\x8a\\xb8\\xe5\\xc8\\x76\\x95\\x72\\xa4\\x1e\\xc3\\x59\\xe3\\xd5\\x52\\x6c\\x32\\x43\\xf8\\xaa\\x34\\xc2\\x51\\x6a\\xbf\\xd1\\xea\\xa4\\x29\\x16\\x16\\xdb\\x21\\xce\\x94\\x48\\xea\\x36\\xbb\\x9a\\x51\\x97\\xf9\\x8a\\x83\\x35\\x75\\xd1\\xfd\\xcd\\xad\\x32\\x8e\\x7e\\x43\\x51\\x87\\x3e\\x8a\\x3a\\xca\\x69\\x39\\xf6\\x47\\x40\\x41\\x52\\x02\\xed\\x0f\\x98\\xe1\\x3b\\x35\\x1d\\xdb\\x8a\\x6c\\x38\\xa1\\x12\\x6e\\x90\\xf4\\x87\\x1a\\x0e\\x35\\x9a\\xe7\\xf5\\x73\\xa0\\xe6\\x1b\\xe1\\xcc\\x25\\xde\\xd5\\x14\\x47\\xe7\\xbd\\x70\\xb3\\xcb\\xb2\\x82\\x90\\xf1\\x4e\\x99\\x7f\\xdb\\xa8\\xcc\\x27\\x0e\\x1e\\x63\\x85\\xf3\\x1a\\x9f\\xdb\\x7b\\x8e\\xf8\\x77\\xa6\\x19\\xc6\\xc5\\xf8\\x8d\\xe0\\xd9\\xd7\\x57\\xed\\xd4\\x52\\x85\\xc9\\x4b\\xb7\\x18\\x3a\\x43\\xc3\\x69\\x25\\xee\\xca\\x5f\\x3c\\x5b\\x42\\x75\\x31\\xad\\xa5\\xbf\\x7b\\xe1\\x1c\\xa0\\x82\\x80\\x94\\x9c\\xc7\\xe2\\x35\\xe6\\x74\\x88\\x40\\x2b\\x7c\\x9c\\x28\\x5a\\x16\\x18\\xd7\\x84\\xee\\x54\\x0f\\x26\\x4b\\x81\\xe6\\xe7\\x0d\\x96\\x29\\x91\\x37\\x8e\\xe1\\xaf\\x88\\x71\\x3c\\x06\\xfc\\x53\\xaf\\xc8\\x30\\x9c\\x76\\x8d\\x2a\\xa3\\x3d\\x5e\\x63\\x5c\\x8f\\x77\\xb4\\xfd\\x28\\xf8\\x6b\\xe9\\x6b\\x06\\x5e\\xb6\\xc7\\x59\\x01\\x62\\x16\\x81\\xe5\\xb8\\x83\\x0f\\xca\\xcb\\xce\\x2a\\x12\\x03\\x64\\x52\\xd1\\xab\\x11\\x00\\x3c\\x67\\x08\\x60\\x83\\xe6\\xb1\\x9b\\xdf\\x60\\xe1\\x54\\x02\\x2e\\x8a\\x34\\xc3\\xae\\x97\\x0a\\x0c\\x2e\\x71\\x96\\x85\\xa9\\xdb\\x1f\\x03\\x2f\\x24\\x7a\\xd2\\x88\\xa9\\x9a\\x32\\xf8\\x26\\xdc\\x95\\x45\\x93\\x56\\xb5\\xde\\x1a\\x1a\\xff\\x1f\\x57\\x6f\\xb1\\x2c\\xbb\\xb2\\x73\\x8d\\x3e\\x90\\x1b\\x66\\x6a\\x9a\\x99\\xd9\\x3d\\x97\\x99\\x19\\x9f\\xfe\\xc6\\x5a\\x7b\\x7f\\xe7\\x9c\\xff\\xc6\\xec\\xcd\\x08\\x57\\x65\\x65\\x4a\\x1a\\x63\\x28\\x65\\x89\\x70\\x1d\\xad\\xac\\xb4\\xee\\xf6\\x39\\xe3\\x8d\\x5a\\x03\\x34\\xaf\\x89\\x22\\xa7\\xe2\\xfb\\x89\\x87\\xfa\\x30\\x0a\\x6d\\xff\\x98\\x54\\x1c\\x91\\x02\\x3f\\x95\\x1d\\x5a\\x87\\x60\\x1d\\x83\\xd2\\xa4\\x07\\x5e\\x1d\\x8c\\xe5\\x30\\x17\\xc1\\x29\\x14\\x8e\\xfa\\xef\\x79\\xd5\\x4c\\xbd\\xaf\\x61\\xad\\x72\\xf7\\xc4\\x19\\xca\\xe7\\x66\\x42\\x07\\x50\\xc4\\x12\\xac\\xbd\\x98\\x99\\xa9\\xd2\\x67\\x25\\x1c\\x4b\\xaf\\xbb\\x7c\\x52\\xe2\\xdf\\x1f\\xe7\\x56\\x64\\x09\\x1f\\xe8\\x49\\xdf\\x00\\x19\\xbe\\x95\\x49\\xfd\\xe1\\x17\\x32\\x83\\xcb\\xbf\\x61\\x3d\\x86\\xd3\\xab\\xea\\x94\\x7d\\x27\\x0d\\x8a\\x38\\x1a\\x27\\xa4\\xdc\\xd2\\x0c\\x22\\x73\\xec\\xe5\\x3f\\xe5\\x23\\x0c\\xc3\\x8b\\x40\\x3c\\x68\\xc1\\x1b\\xb9\\x82\\xcc\\xab\\xbc\\xd7\\x64\\xb6\\x0b\\x3a\\xc8\\x0d\\x7c\\xd7\\xa6\\x43\\x43\\xff\\x4d\\xfc\\x0c\\x1c\\xa2\\xa9\\x4f\\x45\\x1d\\xb0\\x75\\x24\\x5e\\x33\\x99\\x0f\\xaa\\xa0\\xb8\\xdc\\x5c\\xf0\\x5b\\xc1\\xf5\\x79\\x52\\x4f\\x52\\x94\\x85\\xde\\x1a\\x7a\\xb3\\xb3\\x60\\x4d\\x30\\xd5\\x2b\\x87\\xf0\\x49\\x83\\x96\\xff\\x17\\x80\\x18\\x46\\xf0\\xd8\\x46\\x68\\x46\\xcf\\x8c\\x5b\\xca\\x69\\x53\\x5f\\xfa\\x39\\x13\\x11\\x9f\\x65\\xa5\\xfe\\xa2\\x2a\\x9d\\x4c\\x76\\xe9\\x8d\\x61\\xea\\x51\\x40\\xbc\\x4f\\x93\\x0c\\x0d\\xdb\\x2d\\xa7\\x00\\x3e\\x0b\\xc2\\x99\\x52\\xca\\xc1\\x35\\xfc\\xe9\\x53\\xfc\\x7d\\x08\\xbe\\xe9\\x10\\xed\\x89\\x58\\x46\\xf6\\xd8\\xea\\xbf\\x18\\xa9\\x30\\xd8\\x1f\\x3e\\x90\\xde\\xd1\\x63\\x21\\xa5\\xfe\\x70\\xc6\\x15\\x7f\\x3e\\x6f\\x9f\\xa6\\xd9\\x92\\x13\\x3d\\x71\\x6d\\x8a\\x87\\x22\\x4e\\x12\\x3a\\x44\\x5c\\x21\\x7e\\x95\\xe4\\x39\\xd1\\x44\\x2a\\xcd\\xb8\\xcc\\x39\\x63\\xaf\\x3e\\xcd\\xa0\\xbf\\xbc\\xc5\\xfb\\x5c\\xaa\\xe7\\x53\\x51\\xd5\\x72\\xfd\\x3f\\xee\\xcc\\xb7\\x86\\x7a\\x99\\xa6\\x12\\x55\\x63\\x39\\x9a\\x69\\x38\\x76\\x77\\xca\\x67\\x55\\xc4\\xce\\xc8\\x78\\xbf\\x6e\\x41\\x75\\x3d\\x11\\x02\\xdb\\xab\\x41\\x52\\x0f\\x43\\x12\\x34\\x56\\x1f\\x5d\\xfd\\x7e\\xa8\\x51\\x83\\x3d\\x57\\xef\\xe5\\xf8\\x7b\\x70\\xa6\\xd7\\x52\\x69\\x38\\x0a\\xcd\\x30\\x20\\xe2\\x4b\\x1d\\x46\\xdf\\x6a\\x8b\\x39\\x14\\xe5\\xd2\\xff\\x63\\xcb\\x8c\\x35\\xae\\xaa\\x91\\x36\\x76\\xdb\\x9b\\xc9\\x2e\\x4e\\xe6\\x2a\\x62\\xb4\\xec\\xf2\\x15\\xaf\\x32\\x1d\\x97\\x6d\\xa1\\x96\\x64\\x54\\xfb\\xe3\\xd3\\x1f\\x6d\\xa0\\x48\\x31\\x83\\x31\\xf1\\xa0\\xf3\\xed\\x7e\\xf6\\x09\\x2c\\x45\\xdd\\xf2\\x10\\xba\\xda\\x31\\x01\\x84\\xef\\x18\\xb8\\x65\\x7b\\xfb\\xdd\\x26\\x3a\\x2b\\x0b\\xf4\\x05\\x37\\x4e\\x6c\\x77\\x2a\\x7f\\xcc\\xe8\\x7f\\x7c\\x95\\x77\\x71\\xb3\\x39\\x38\\x41\\x27\\xa4\\xb5\\x1e\\x8b\\x4a\\x73\\x55\\x73\\xf8\\x7d\\x03\\xb1\\x84\\xd6\\x0a\\x45\\xe7\\x20\\x78\\xd9\\xe0\\x10\\xb2\\x3b\\x91\\x02\\xdd\\xf5\\xf4\\x0e\\x3a\\x1a\\x6d\\x85\\x24\\xb4\\x3d\\xb2\\x44\\x9b\\xef\\xa8\\xf5\\x83\\xa7\\xfe\\xa2\\x49\\x92\\x82\\x4b\\x81\\x70\\xa8\\x90\\x6f\\xcf\\x09\\xff\\xd7\\xbe\\x4c\\xa1\\xd6\\x53\\x3d\\xda\\xd8\\x44\\xc5\\xbd\\xc0\\x2c\\x37\\x38\\xd7\\xdb\\xca\\xd2\\xed\\xfe\\x10\\x7e\\xc9\\x07\\xc3\\xbd\\x5e\\x9f\\xdc\\x5a\\xa0\\x32\\x5d\\x4e\\x01\\x62\\xfe\\x06\\xba\\x9a\\x40\\xc8\\x8e\\x7e\\xbe\\x54\\x9e\\xb0\\x50\\x96\\x5f\\xbf\\x5f\\x83\\xb5\\x40\\x16\\x49\\xe5\\xd0\\x12\\x3a\\x2b\\x80\\x3f\\x7f\\x80\\x1d\\xc3\\xff\\xa3\\x31\\x58\\xc6\\xe4\\xb2\\x2e\\xf0\\xfe\\xc4\\x3f\\x72\\x59\\x6d\\xe0\\x25\\x54\\xef\\x43\\xb2\\x27\\xdb\\xc2\\x6c\\x08\\x85\\xf9\\x08\\xdb\\x4f\\x97\\x66\\x78\\x82\\xad\\xde\\xca\\xd3\\x77\\x43\\x9b\\x90\\xee\\xa8\\xaa\\xfb\\x55\\x05\\x36\\x9f\\x74\\x23\\x19\\x69\\x6f\\xf4\\xcb\\x4d\\x70\\x41\\x92\\xe2\\x57\\xa8\\x2c\\x88\\x66\\x75\\xcc\\x7e\\x2a\\xb3\\x02\\xd5\\xe4\\x7f\\xb9\\x3e\\xc7\\x8c\\xe7\\x8d\\x84\\x29\\x6d\\x79\\xac\\x5a\\x2c\\x19\\xed\\xaf\\x28\\xfb\\x92\\xa6\\x61\\x0e\\x46\\x7a\\x2c\\xe3\\x4c\\x00\\x0f\\x50\\xa1\\x26\\x8a\\x16\\x0d\\x6d\\x5f\\x34\\x58\\x5d\\x08\\xf2\\x47\\x37\\x35\\xaa\\xb9\\x71\\x61\\xa2\\xbe\\x03\\xc4\\xe5\\x51\\x72\\xdd\\x8a\\x23\\x63\\x39\\x54\\xa3\\xff\\xcf\\x67\\xab\\x42\\xe5\\xf5\\x41\\xd6\\x85\\xeb\\x10\\x08\\xc7\\xfb\\xd8\\xdd\\x30\\x7b\\x25\\x92\\x9c\\x21\\x85\\x22\\x53\\x66\\x3f\\x80\\xfd\\xe4\\xcd\\x13\\x93\\xc8\\xaa\\x90\\xfb\\x5f\\x3f\\xcc\\xf5\\x2e\\x4f\\x68\\x55\\x2b\\x18\\x56\\x33\\x76\\x2a\\x6c\\x87\\xf3\\xb7\\xb0\\x6c\\x2d\\x78\\xa9\\x82\\xb9\\xce\\xb2\\xb0\\x77\\x9e\\xfd\\xc7\\x0d\\x45\\xf3\\xf4\\x6b\\x4c\\x53\\x08\\x27\\xee\\x5b\\xf7\\x08\\x57\\x0f\\x6a\\x76\\xb8\\x37\\x75\\x65\\x47\\x80\\xca\\x52\\xb7\\x92\\x3c\\x56\\xa2\\x6c\\x81\\x4d\\x95\\x12\\x41\\xe1\\xe9\\x22\\xfd\\x20\\x8e\\x79\\xd8\\xd1\\x6c\\xfa\\x1a\\x2f\\x31\\x06\\xaa\\xaf\\xff\\xe2\\x5c\\x2b\\x8c\\x4b\\x68\\x75\\x30\\xa1\\x21\\xb1\\x7f\\xb9\\x84\\x1c\\xaa\\x99\\xe1\\xb1\\x2a\\x34\\xfe\\x0e\\x84\\x16\\x03\\x41\\x71\\x6b\\xc3\\xec\\x26\\x7f\\x0b\\xb5\\xa5\\x90\\x66\\xe1\\x27\\x37\\xc6\\x72\\x18\\x60\\x4e\\x33\\xb5\\xea\\x0f\\x78\\x99\\xd4\\x9c\\xca\\x22\\xff\\xc5\\x6c\\x86\\xe9\\x3d\\x51\\xec\\xfb\\x64\\x6e\\x37\\xb5\\xcd\\x62\\x6b\\x2f\\xf8\\xb5\\x70\\x56\\x01\\xc3\\x29\\x73\\x37\\x1b\\xa7\\x68\\xeb\\x50\\xed\\x8f\\x14\\x48\\x5f\\x96\\x79\\x27\\xf5\\xcb\\x6d\\x4e\\x36\\xed\\x3b\\x77\\x99\\xff\\x73\\x24\\x96\\x89\\x85\\xd6\\x5d\\x58\\xe9\\x43\\x72\\x57\\x39\\xf2\\x14\\x8d\\xba\\x66\\x3a\\xa2\\x88\\xf6\\xd7\\xc2\\x49\\xe4\\x01\\xe8\\x6c\\x87\\x98\\x42\\x6d\\x71\\xd8\\xcf\\xab\\x7b\\xad\\x31\\xd8\\xcd\\x0d\\xdd\\xd8\\xe3\\xff\\x87\\x77\\x2b\\xbc\\xf6\\x21\\x89\\x4b\\xc8\\xd1\\xc8\\xa6\\xe1\\xf8\\x71\\x5e\\x54\\x62\\x84\\xea\\xad\\xbe\\x93\\x7d\\x01\\x0f\\x7a\\xb8\\xd2\\x0f\\x67\\x25\\xbf\\x09\\x19\\xd2\\x48\\xdf\\x9a\\x54\\x69\\x29\\x02\\x43\\x38\\xd3\\x7f\\x75\\xd6\\xa3\\x14\\x82\\x17\\xae\\x37\\x92\\x3d\\xf3\\xd2\\xcc\\x20\\x40\\xb1\\x8d\\xa9\\x8e\\x86\\x6e\\xec\\xb5\\x6b\\x8b\\x8e\\xb6\\x84\\x84\\x1c\\xce\\xd9\\xa2\\x48\\xd4\\x25\\xde\\x02\\x53\\x28\\xee\\xff\\xe8\\x9a\\xda\\x9e\\xf3\\x8e\\x87\\x24\\xc7\\xd2\\xff\\xec\\x9f\\xb9\\x0a\\x49\\x85\\xfd\\xe1\\xdb\\x35\\x4c\\x56\\x20\\x4a\\x64\\x4b\\x0b\\x8f\\x06\\xa0\\xf8\\x36\\x7e\\x99\\xde\\x20\\x2a\\x49\\xd0\\x67\\xf7\\xc7\\xe0\\xc5\\xfa\\x41\\x0d\\xe9\\x09\\xf5\\xbd\\xff\\x87\\x03\\xea\\x6f\\x25\\x7f\\x1d\\x9b\\x98\\xed\\x51\\xa8\\xc2\\x94\\xed\\x79\\x5a\\xd9\\x6c\\xb6\\x2d\\x31\\xc5\\xc1\\x88\\xf2\\x28\\xc4\\xbe\\x71\\x73\\xda\\xe4\\x5a\\xca\\x12\\x7b\\x41\\x9d\\x18\\x2c\\xa9\\xb7\\xa9\\xf8\\x5f\\x63\\xfc\\x07\\x9f\\xec\\x66\\x6e\\x77\\x35\\x73\\xda\\xfe\\x93\\xea\\xe7\\x1d\\x9d\\xe7\\x11\\x98\\x83\\x87\\x50\\x68\\x3d\\xf3\\xa3\\x37\\x56\\x83\\xbd\\x9c\\x45\\x4c\\x3e\\x25\\x4d\\xd3\\xf6\\x11\\xe6\\x74\\x6b\\x5a\\x96\\x56\\xfc\\x7f\\xdf\\x51\\xfa\\x3b\\x1d\\x59\\x84\\xda\\xc8\\x79\\x78\\xc9\\x82\\xa3\\x86\\x91\\xf3\\x74\\x32\\x97\\xb3\\xd9\\xd4\\xf5\\x89\\x38\\x64\\x25\\x5b\\xac\\xee\\xbd\\xf4\\x79\\xfb\\xf7\\xd5\\xe6\\x4b\\x7d\\xf3\\x87\\x91\\x3d\\x33\\x57\\xbb\\xff\\x10\\x69\\x96\\x51\\x4e\\x7f\\xc0\\x57\\x0e\\x6b\\x78\\x3f\\xfd\\xf9\\x89\\xd1\\x95\\x8d\\xd2\\x9f\\x37\\x4d\\x10\\x6c\\xa0\\x0d\\xf2\\x2f\\x8e\\xdd\\xf5\\x08\\xd7\\xc9\\x81\\xbd\\xe1\\x95\\x32\\x78\\xe7\\x5e\\xdd\\x12\\xb8\\xec\\xde\\xf3\\xe6\\xff\\x3e\\x45\\x65\\x7c\\x7d\\x9f\\xb2\\x9d\\xc6\\x9d\\xf2\\x08\\x57\\x51\\x95\\x2c\\x4e\\xb2\\x5d\\xe2\\x0c\\x1f\\x4b\\x50\\xfc\\x22\\xed\\x03\\x48\\xa8\\xa5\\xa9\\x58\\x7d\\x75\\x4c\\x01\\x5b\\x11\\x78\\xe2\\xee\\xfe\\x7d\\x77\\xef\\x8f\\x2f\\xad\\x01\\xe3\\xb9\\x96\\xaa\\x04\\xfd\\xfb\\x60\\x04\\x32\\x31\\x43\\xbf\\xc3\\x23\\x1c\\xad\\xb0\\xb7\\x06\\xce\\x2c\\xd4\\xd2\\x50\\x7b\\x9e\\x32\\xb7\\x8d\\x6c\\xaf\\xcb\\xe2\\xf8\\x9b\\x9d\\x24\\xce\\x7f\\x21\\x71\\xf7\\x9b\\x57\\x0b\\x17\\x69\\x92\\x1c\\x7e\\xbe\\xd2\\x8e\\xcb\\x64\\x2e\\x0b\\xdd\\x15\\x35\\xbf\\x9c\\x49\\xda\\x3a\\x78\\xa4\\x19\\xd2\\x1a\\x87\\x7d\\xfb\\x1b\\x21\\xbe\\x77\\x60\\x73\\xb6\\x50\\xd2\\xff\\xda\\x07\\xe7\\x68\\xcc\\xc7\\xe3\\x1c\\x1b\\x6b\\xec\\xf0\\x9e\\xf9\\xb3\\x9b\\xad\\x60\\xb5\\x49\\xfa\\x39\\xf3\\x18\\x8d\\xb8\\xc5\\xa3\\x6b\\xe5\\x61\\xb1\\xdf\\x5a\\xad\\xa8\\xfc\\xfe\\x87\\x67\\x38\\x8c\\x12\\xe2\\xfc\\xee\\xb0\\xca\\xa4\\x38\\x61\\xe2\\x1a\\xb3\\xca\\x29\\x7e\\x9e\\x76\\x49\\xcb\\x8b\\x26\\x03\\x4d\\x25\\xcd\\xe4\\x6e\\xf8\\xff\\x7b\\x46\\x1f\\xf0\\x32\\x7a\\x79\\xc5\\xc0\\x16\\xf5\\x73\\x13\\x91\\x6b\\x34\\x3e\\xed\\xb9\\xf5\\x0a\\xef\\x55\\x1b\\x9b\\xdb\\xef\\xf1\\x33\\xb9\\x2d\\x43\\xe5\\xc7\\xde\\x04\\xfe\\xe3\\xd0\\xac\\xa6\\x2c\\xe7\\x40\\xe9\\x9c\\x68\\x9b\\x69\\x3a\\xfc\\xfc\\x64\\xc3\\x6a\\x26\\xad\\x5f\\x5f\\xbd\\xcc\\x3b\\x7f\\x38\\x79\\x68\\xeb\\x35\\xe7\\x18\\xad\\xb7\\x80\\xff\\xc9\\x1d\\xe8\\x82\\xc6\\xe1\\x22\\xe3\\xfd\\xe4\\x5c\\xe6\\x0f\\x51\\x71\\x0c\\x46\\x0a\\xa2\\x21\\x68\\x7a\\x93\\xdd\\x9d\\xa6\\x29\\xdd\\xb7\\xf4\\x48\\x2b\\xe8\\x79\\xe2\\x26\\xf2\\xff\\xf8\\xad\\xaa\\xfe\\xcc\\x6c\\x88\\x96\\x50\\x69\\xf8\\xb5\\xe9\\xa0\\x72\\x0b\\xb3\\xce\\x6f\\x18\\xb6\\xc1\\x7f\\x3f\\x31\\x0d\\xa2\\x60\\x6c\\x98\\x31\\x07\\xa2\\x66\\x61\\xd8\\x9e\\xfd\\xdf\\x75\\x9e\\x82\\x59\\xd5\\xcb\\xdd\\xe9\\xc6\\x94\\x91\\x7c\\x2c\\x31\\x9d\\xe0\\xba\\xa1\\x84\\x59\\x70\\x0b\\x4c\\xe4\\xce\\x59\\x19\\x66\\xd4\\x06\\x86\\xf5\\x1c\\xf3\\x1f\\x6a\\xd3\\x47\\x83\\xd8\\x30\\x89\\xe6\\x08\\x5b\\x8f\\x9f\\x59\\xbb\\x33\\xcd\\x60\\x6c\\x61\\x92\\x76\\xc1\\x4f\\x50\\xaa\\x01\\xb2\\x56\\x48\\xed\\x93\\xd2\\xa8\\x0d\\x5a\\xf9\\xbf\\x87\\x3c\\xbe\\x3d\\xc2\\xd1\\x82\\x23\\x96\\x93\\x55\\xde\\xc8\\xba\\x68\\x86\\xb5\\xe3\\x60\\x9a\\xcd\\xfe\\x6d\\xbc\\x96\\xf2\\xb2\\xa8\\xec\\x8b\\xde\\x2a\\xb5\\xc3\\x1a\\xb5\\xfd\\x5f\\x8c\\x50\\x19\\xc3\\xd3\\x92\\x7e\\x0c\\xee\\x71\\xa7\\xcf\\xbd\\x65\\xcc\\xde\\x56\\x95\\x9e\\x02\\xd5\\x37\\x70\\x6a\\x72\\x8c\\x5a\\xed\\x1e\\x42\\xb6\\xe7\\xa5\\xff\\xd1\\xd9\\x6c\\xff\\xca\\x39\\x91\\x5a\\x6d\\x3f\\xbc\\x77\\xef\\xf9\\xab\\x63\\x24\\xde\\x3e\\x87\\xce\\xac\\x4b\\xc9\\x87\\x2d\\x0c\\x54\\x26\\x18\\xb5\\x99\\xa3\\xdc\\x29\\xf2\\xff\\x38\\xaa\\xc3\\xfb\\xa1\\x20\\x12\\xa6\\x96\\xea\\x62\\xa6\\xbb\\x99\\xe8\\x28\\x0c\\xe1\\xd8\\xde\\x1d\\xed\\xb0\\xb6\\xb8\\xec\\xeb\\xcd\\x84\\x87\\x09\\x82\\xc4\\xfc\\xbf\\xcf\\xb9\\xaa\\x17\\xf4\\x6e\\xbd\\x30\\x82\\xb6\\xc4\\xda\\x8f\\xcf\\x86\\x8a\\xcf\\xb1\\xae\\xbf\\x70\\x7b\\xf6\\xf9\\x24\\x10\\x1c\\x63\\x3a\\x31\\xa1\\x2c\\xca\\x6e\\x7b\\xf2\\xb1\\xcf\\x46\\x0d\\x10\\xa0\\x6c\\x8b\\x8b\\xb4\\x37\\x72\\x45\\xb2\\xeb\\xf5\\x3f\\xfb\\xcb\\xaa\\xc9\\xc1\\x6f\\x81\\x63\\x34\\x50\\xd4\\x66\\xc5\\xe9\\x0f\\xde\\x28\\xda\\xa5\\x8a\\xd9\\xf4\\xe5\\xf5\\x45\\x03\\x10\\xe7\\xb6\\x7f\\xd7\\x5e\\x1b\\xd8\\xf1\\xea\\x69\\x38\\x92\\x68\\x42\\xf0\\x8e\\xa6\\x85\\x43\\x93\\x74\\x9c\\xca\\xaa\\xff\\xab\\x07\\x71\\x6e\\xe0\\x93\\x36\\x66\\xa9\\x49\\xfd\\x24\\x25\\x73\\xef\\x85\\x54\\xf0\\x58\\xbb\\xe0\\x67\\xb7\\x1a\\xd8\\x82\\x99\\x17\\x3a\\x16\\x3a\\x58\\xc3\\x3c\\xb3\\x2d\\x4b\\xc9\\xfd\\x0c\\xf4\\xa5\\xca\\x25\\x64\\x26\\xf7\\x1a\\xe2\\xb7\\x60\\xad\\x12\\x84\\x98\\x64\\xdc\\xed\\xff\\x2d\\x90\\x73\\x8c\\xdf\\x4a\\x9c\\x17\\x49\\x83\\x75\\xa9\\x56\\x4b\\x86\\xa3\\x24\\xf6\\xda\\x1f\\x55\\x41\\x09\\x6e\\x5e\\x9d\\x59\\xe5\\x3f\\xe6\\x15\\x98\\xba\\x16\\x95\\xa1\\x36\\x9a\\x1e\\x96\\x66\\x18\\xa2\\xf7\\xb2\\x36\\xc9\\x3a\\x93\\x16\\x14\\xef\\x4e\\x07\\x3c\\x8a\\x6a\\x5b\\xbc\\x56\\x5b\\xce\\x61\\x97\\xe4\\x4a\\xb0\\xc2\\xc5\\xea\\x0e\\xa8\\xe2\\x18\\x8f\\x77\\xdc\\xdb\\x11\\x56\\x99\\x19\\x13\\xd0\\x9a\\x54\\xb6\\xf9\\xcf\\xef\\x51\\x78\\x03\\x2a\\x26\\x97\\xaa\\x4a\\x10\\xf4\\x50\\xf7\\xfb\\x54\\xe2\\x63\\xbb\\xfe\\x41\\x4c\\xa9\\x8f\\x5c\\x35\\x2f\\xe5\\x46\\x81\\xa9\\x46\\xd4\\x54\\x5f\\x6b\\x1c\\x64\\x85\\x43\\xef\\x7c\\x3d\\x7f\\xf7\\x3e\\xfd\\xd8\\xbc\\xfc\\x18\\xe6\\xe3\\x8d\\x9f\\xb2\\x7a\\xd9\\xfb\\xdc\\xa2\\x63\\xd1\\xeb\\xd9\\xc3\\x92\\x32\\x4f\\x70\\xa9\\x5f\\x9d\\x4e\\x07\\xe8\\xc0\\x0f\\x20\\x0d\\xa6\\xdd\\x69\\xd7\\x75\\x4f\\xf8\\x63\\x8b\\x27\\xf2\\xe3\\x82\\xff\\x98\\x31\\xf3\\x86\\x6e\\x16\\xf4\\xcf\\x50\\xf6\\xd3\\x8c\\x6b\\xe6\\x82\\x9c\\xb2\\xd2\\x23\\xdc\\xf1\\xcb\\x2e\\x11\\xb5\\xf0\\x85\\x04\\xba\\xdd\\x37\\xe7\\x2f\\xef\\xbe\\x6b\\x9d\\x8a\\x54\\x97\\x92\\x77\\x24\\x92\\x14\\x6b\\x1e\\x53\\x5f\\xaa\\x01\\x31\\x45\\x26\\x98\\x9e\\xb1\\xa7\\x86\\xd9\\xe4\\x18\\xab\\x97\\xfe\\xd7\\x6e\\xb9\\x3e\\x68\\xd7\\xb0\\x1b\\x9c\\xa0\\xde\\x9b\\xbd\\xfc\\x8d\\xb8\\x6e\\x1c\\x5a\\x6e\\x14\\xf3\\xd8\\x65\\xbf\\x4f\\x41\\x4c\\x3f\\x18\\xb7\\x02\\x90\\xd6\\x82\\x16\\x8c\\x99\\xae\\x96\\x7d\\x9c\\x39\\xc5\\xc0\\x69\\xc2\\x0e\\x89\\xfa\\x96\\xd2\\x58\\x95\\x4c\\x8d\\xa3\\x45\\x81\\xe3\\x3f\\x85\\xff\\xaf\\x89\\xbe\\x7e\\xfa\\xba\\xec\\xc8\\x29\\x9c\\xa6\\x23\\xd9\\xe7\\xae\\x5c\\x44\\x96\\x6f\\xe6\\xf7\\xd9\\x6f\\x29\\x97\\x52\\xc7\\x1f\\xb3\\x24\\x09\\x6d\\x79\\x4b\\xf4\\x03\\x88\\x30\\x4a\\xef\\xf4\\xf1\\xe7\\x3e\\x3f\\x21\\xa4\\x09\\x2c\\x1e\\x53\\xd8\\x2c\\xf4\\x96\\xc8\\x0e\\xf0\\xd3\\x69\\xd3\\xff\\xf2\\xdd\\x5a\\x72\\x3e\\x29\\x81\\xa2\\xf6\\x19\\x1e\\x41\\x09\\xb3\\x2d\\xc0\\x5f\\xb8\\x9c\\x1a\\xa5\\x9f\\xbc\\x6c\\x93\\x21\\x5a\\x71\\x73\\xde\\x81\\xd4\\xca\\xd3\\xec\\x87\\xbe\\x4e\\x2a\\xaa\\xa1\\xbf\\x24\\x35\\x09\\x3e\\x26\\x96\\x4f\\x19\\x67\\x29\\x17\\x26\\x22\\x5a\\x6a\\xcc\\xba\\x11\\x87\\xc5\\x73\\xb5\\x04\\x12\\xc6\\xff\\xe5\\x14\\xc1\\xc8\\xf7\\xad\\xac\\x08\\x4a\\x8c\\xed\\xef\\xb7\\xbd\\xf9\\x1a\\x81\\x13\\xba\\xd2\\xfe\\x2a\\x3a\\x85\\x5c\\xa0\\xe6\\x57\\xa2\\xaa\\x55\\x2f\\xa0\\x8c\\x83\\x3d\\x7d\\x98\\xfd\\xe8\\x22\\x7a\\x83\\xdb\\xc9\\x72\\xf3\\x99\\xeb\\x4e\\xc3\\x18\\x14\\x65\\x3c\\x29\\xc4\\x3c\\x7b\\x6f\\xaa\\x79\\xca\\xee\\xb0\\x46\\xa3\\xff\\x6f\\x8c\\xe1\\xfe\\xf8\\x65\\x17\\x64\\xbc\\x65\\xf8\\x70\\x8f\\x13\\xed\\x64\\x8f\\x56\\x21\\xf6\\xa5\\x04\\x8d\\xd3\\xb1\\x65\\x70\\x11\\x7b\\x0a\\x0a\\x59\\x1e\\x46\\x36\\x44\\x88\\x19\\x35\\x27\\xaf\\xb4\\xdf\\x12\\x71\\x0a\\x5a\\xbb\\x27\\xbf\\x79\\x5c\\xf6\\x61\\x4a\\x86\\x99\\x5a\\x09\\xba\\x6e\\xaa\\x9c\\x17\\x0b\\xee\\xfd\\x71\\x0a\\x83\\x38\\xfd\\x27\\xdd\\x7f\\x04\\x1b\\x04\\xd1\\x64\\x19\\x0f\\x70\\x11\\x87\\x70\\x88\\x16\\xbf\\x8c\\xb8\\x6c\\x1c\\x94\\xf1\\x4a\\x61\\x59\\x05\\x08\\xb1\\xe3\\xbc\\x08\\x29\\x2f\\x6d\\x39\\x89\\x1d\\x86\\x91\\xd8\\xc4\\x9d\\xa1\\x19\\x25\\x8f\\xcb\\x06\\x14\\x67\\xa7\\xdf\\x7c\\xe2\\x7d\\x8d\\xcd\\xae\\x50\\x9b\\x61\\x09\\x2d\\xe2\\x10\\x2d\\xba\\x40\\x55\\x2b\\xdd\\x35\\x9f\\xcf\\x71\\xf9\\x35\\x76\\xa0\\xfc\\x81\\x85\\x20\\xfd\\x85\\x7d\\xf9\\x26\\x90\\xb5\\x63\\xef\\x19\\xbc\\xac\\xc5\\x5a\\x02\\x12\\x39\\x1a\\xab\\x28\\x85\\xec\\x42\\x58\\x66\\x78\\xd2\\xdc\\x36\\x10\\x3e\\x3b\\x46\\xf3\\x97\\xdb\\xb2\\x4c\\xb9\\xb6\\xc7\\x1a\\x4e\\x00\\x54\\x69\\x47\\x44\\x56\\x11\\x7c\\xb8\\x4a\\x6e\\x17\\xe3\\xa7\\xbe\\xea\\x3f\\xc9\\x87\\x27\\x0e\\x42\\x99\\x9d\\x3d\\x53\\x06\\x6d\\x8c\\x71\\x1a\\x81\\x6f\\xe9\\x71\\x87\\x90\\xc9\\xcf\\x70\\xfa\\x08\\xc7\\x03\\x3d\\x5e\\x2a\\xe7\\x8f\\x2a\\x3c\\xb1\\x55\\xe7\\xf6\\x30\\x03\\x0a\\xb2\\xff\\x5d\\x3f\\x12\\x74\\x5c\\x76\\x14\\x1e\\x49\\x97\\x25\\xb3\\x9b\\x0c\\x1a\\xbb\\x5e\\xf8\\x32\\xdf\\x3c\\x10\\x00\\xdb\\xc6\\xb8\\xce\\x0f\\x3e\\x99\\xd8\\x15\\x6e\\x09\\x35\\xd5\\x12\\xb8\\xd1\\x99\\xa0\\xf0\\xcf\\xb1\\xac\\xd1\\x71\\xfe\\x26\\xb2\\xa5\\xf2\\xe2\\xba\\x6c\\x42\\x2a\\x68\\x1a\\x77\\xf1\\x4d\\xcd\\x1d\\x86\\xa9\\xd9\\x06\\xec\\x43\\x3d\\x78\\x65\\x35\\x50\\x12\\x40\\x0c\\xd7\\xc3\\x7c\\x70\\xc5\\xcd\\xb7\\x21\\xdf\\xe8\\xdc\\x65\\x59\\x41\\x6b\\x8b\\x94\\xdf\\x0f\\xb4\\xa3\\xe2\\x9a\\x62\\x05\\xe1\\xe6\\x25\\x03\\x19\\x7d\\x06\\x15\\xac\\xf2\\x53\\xfa\\xfe\\xb5\\x69\\x90\\xc5\\x2e\\x57\\xe5\\x99\\x62\\xed\\x9b\\x1b\\x16\\xea\\x62\\x7d\\xad\\x46\\xed\\xfe\\x32\\x26\\x56\\x41\\x32\\xa2\\xb0\\x10\\x80\\x04\\xd2\\x14\\xce\\xe8\\x5c\\xad\\x67\\x76\\xfe\\xb3\\x57\\x78\\xdb\\x2f\\x7a\\xfa\\xd3\\x53\\xa5\\xe3\\x77\\xae\\x0e\\xda\\xcd\\x9f\\xdf\\x78\\x88\\xc2\\xf9\\x14\\xe7\\xb6\\xe5\\x14\\x7d\\x25\\xab\\x92\\x1c\\xf1\\xae\\x45\\xf1\\xcb\\x26\\xd1\\x92\\x1c\\x37\\xb2\\xd8\\xbb\\xf1\\x4e\\xff\\x7c\\x77\\xd2\\xd4\\xa3\\x4d\\x03\\xac\\xe7\\xab\\x79\\x37\\xdd\\x72\\xd9\\x87\\x4c\\xba\\x9b\\xec\\x1f\\x1e\\xe0\\xe8\\x33\\x80\\xfe\\x36\\x18\\x73\\xf2\\xca\\x59\\x07\\x81\\x61\\x78\\x25\\x61\\x1e\\x73\\x20\\xac\\x9d\\x8c\\xb9\\x5b\\xb7\\x6c\\xa3\\xc0\\x99\\x7e\\xcc\\xb0\\xee\\xeb\\x98\\xb1\\xff\\xe4\\x97\\x24\\x33\\xa4\\x18\\xa9\\x1c\\x45\\x0d\\xac\\x9b\\x2c\\x5c\\x6a\\xd5\\x8d\\xb3\\xdc\\x77\\xcc\\xc5\\xba\\x95\\x41\\xd4\\x52\\x70\\xbd\\x4c\\x3a\\x0e\\x8b\\x79\\x8a\\x7b\\x8d\\x5e\\x3e\\x8b\\x20\\xf0\\xea\\xe0\\x4f\\x7c\\x21\\xaa\\x0b\\xf1\\x7c\\xc2\\x53\\x8d\\xd2\\x90\\xe6\\x1e\\x73\\xa4\\x94\\xff\\x9b\\x07\\x12\\xb8\\x76\\x5d\\xd7\\xb5\\xba\\xd0\\x04\\x23\\x44\\x87\\xd3\\x84\\xbf\\xf1\\x37\\x1c\\xf0\\x48\\x1b\\xcd\\xf4\\x91\\x44\\xe5\\x02\\x84\\xe5\\x5d\\xc6\\x6a\\x02\\xb0\\xe1\\xd8\\xa1\\x31\\x00\\x68\\x3d\\x93\\x96\\xf7\\xa1\\xd3\\x25\\x66\\x39\\xa1\\x5c\\xca\\xcd\\xc4\\xe1\\x63\\x87\\x17\\x11\\xf1\\xcb\\x12\\xc7\\x0c\\xda\\xce\\x46\\xd3\\x87\\x0b\\xf4\\x78\\x6b\\x35\\xe6\\x26\\xd9\\x4a\\x22\\x28\\xea\\x21\\xe9\\x52\\xd6\\xfe\\xcd\\x2f\\xb3\\x2d\\xfc\\x95\\xc9\\xbb\\xfe\\x83\\xb3\\xbf\\x78\\xe3\\x28\\x8a\\xe0\\xc4\\xdd\\xda\\x7a\\x39\\x4f\\xfc\\x25\\x21\\x6c\\x5a\\x4b\\x71\\x4a\\x5d\\xca\\xfb\\x58\\x52\\xee\\xa9\\xba\\x51\\x00\\xbe\\x8a\\x57\\x2a\\x54\\xbd\\x42\\xe0\\x86\\xfd\\x8e\\xef\\x2d\\x78\\x03\\xe2\\x7d\\x65\\x27\\x8b\\x83\\x53\\xf3\\x5b\\xbd\\xe7\\x2d\\xd0\\x1f\\x12\\x46\\x43\\x30\\x0f\\x21\\x08\\x09\\xe7\\x80\\x9e\\x34\\x3a\\x31\\xd8\\xa4\\x6d\\xf5\\xa1\\x7b\\x79\\xb8\\x1e\\x81\\xe4\\x82\\x13\\xcc\\x6b\\x7f\\x78\\x69\\x27\\x24\\x65\\x30\\xbb\\xcf\\xf7\\xcc\\x58\\xf1\\x87\\x4b\\x3d\\xff\\xf2\\x3b\\x47\\xd9\\xa2\\x2d\\x84\\x49\\xd2\\xac\\x9f\\xe7\\xcf\\x72\\x74\\x5d\\x68\\x59\\x71\\x30\\x06\\xa7\\xb1\\xf1\\x32\\x97\\xf5\\x23\\xdb\\x72\\xc2\\x80\\x11\\x05\\x92\\xe4\\x6d\\xfb\\xe6\\x82\\x9b\\xe3\\x2d\\xa6\\xe4\\x45\\x39\\xb6\\x12\\x2d\\x49\\xb4\\x44\\x97\\x03\\x19\\xf1\\x4e\\xaf\\x1d\\x98\\xa8\\x89\\xb3\\x31\\xbc\\xb0\\xa1\\xe2\\x95\\x16\\x85\\xd8\\x35\\x55\\xc8\\xcc\\x03\\xec\\x38\\x69\\x64\\x84\\x33\\x6d\\xa4\\xbb\\x1e\\xa3\\x26\\xc5\\x2c\\x3b\\xb4\\x65\\xd8\\xde\\xfe\\x37\\xc7\\xbd\\x44\\xdb\\xda\\x33\\xfd\\xdf\\x33\\xd9\\x6f\\x5f\\x37\\x3c\\xee\\x6e\\x64\\xdc\\x0f\\xb3\\x7d\\xbc\\x5d\\x35\\x38\\xb4\\x63\\x5a\\x29\\x70\\x20\\x90\\x0f\\x28\\x7b\\x0a\\x9c\\x8a\\xaf\\x44\\x69\\x93\\x0c\\x08\\xd4\\xd1\\x9a\\x40\\x17\\xe4\\xd4\\x56\\x23\\x35\\x1d\\x22\\x78\\xb1\\xd4\\xaf\\xaf\\xc1\\x9e\\xaf\\x0b\\xe9\\xf8\\xfd\\x68\\xf9\\xee\\x14\\xfa\\x7b\\xbb\\xe9\\xa5\\x06\\xa7\\xd5\\x8b\\xd8\\xf6\\xc4\\x9a\\xe2\\x8f\\x9e\\xff\\xe7\\xbb\\x79\\x95\\x28\\xbf\\xdd\\x96\\xbb\\x5b\\xb1\\xfe\\xe0\\x22\\x9b\\x2e\\xbf\\x97\\x0a\\x15\\x6c\\xc0\\x19\\xe3\\xfe\\x83\\x05\\xfb\\x37\\xf1\\xf1\\xe2\\x4a\\x33\\x36\\x59\\xfe\\x96\\x15\\x67\\xe8\\xe2\\x0a\\x27\\x59\\xf9\\x17\\x40\\xb4\\x9e\\x5d\\xaa\\xf0\\x07\\x1b\\x22\\xe5\\x1a\\xe9\\xa8\\x25\\xa7\\x02\\xa2\\x49\\x17\\x49\\x47\\x28\\x93\\x19\\x8a\\x24\\x16\\x34\\xf2\\x9e\\x11\\x0a\\x0f\\xd9\\xeb\\x26\\x6b\\x0d\\x22\\x6f\\xe1\\xed\\xaa\\x77\\x04\\xb1\\x7d\\x94\\x1e\\xc5\\xa5\\x09\\x26\\xe4\\xd7\\x92\\x1c\\xf1\\xdf\\x7c\\x48\\x8f\\xd3\\xed\\x93\\xbc\\xe3\\x5e\\xd6\\xfd\\x9f\\x58\\xee\\xf1\\x86\\x65\\x48\\x5d\\xe0\\xe5\\x65\\x63\\x2f\\xb4\\x9d\\x92\\xbf\\xcc\\xa8\\xa4\\x81\\x26\\xa6\\x00\\x9a\\xd6\\x53\\x5e\\x38\\x46\\xa1\\xab\\xb8\\xa2\\x95\\xb9\\xe7\\x0c\\xb5\\x37\\x75\\x45\\xcd\\x2c\\x5c\\x83\\x48\\x3f\\x4d\\x25\\x7c\\xff\\x31\\xb3\\x54\\x53\\xbd\\xda\\x64\\x57\\xe9\\xfa\\xa6\\x51\\x1f\\x9a\\xdb\\xcf\\xf0\\xf7\\x0e\\x42\\x10\\x96\\xbc\\x91\\xd2\\x42\\x05\\x48\\xaf\\x6b\\x45\\xe0\\x2e\\x19\\x0e\\xbb\\x8f\\x31\\xa7\\xdc\\x7f\\x48\\x3c\\xeb\\x61\\x08\\xfe\\x2a\\x77\\xcd\\x30\\x2a\\x27\\xbe\\xfb\\xa1\\x05\\x16\\x51\\xf3\\x18\\x2c\\x61\\x54\\xa7\\x7f\\x85\\x1b\\x2f\\x30\\x33\\x17\\xa2\\x90\\xfe\\xe1\\x84\\xc4\\x80\\x9c\\x4e\\xbc\\x28\\x66\\x97\\xc0\\xae\\x57\\x20\\x59\\xba\\x9d\\xa4\\x4f\\x2d\\xd6\\x62\\xab\\x9e\\x69\\x42\\x57\\x7e\\x89\\xd4\\x3d\\x54\\x47\\xc1\\x07\\xb8\\xfd\\xc3\\xc1\\x5f\\x26\\x84\\x55\\x19\\xe5\\xcb\\xe3\\x77\\xa3\\x94\\xdc\\xb5\\x32\\xdd\\x1f\\x83\\x21\\xbd\\xb3\\xe9\\xed\\x22\\x54\\xf1\\x4f\\x91\\xf7\\xd6\\x16\\xa6\\x99\\x34\\xea\\x3f\\x90\\xc3\\xaa\\xae\\x20\\x06\\x7f\\xf4\\x8c\\x27\\x60\\x33\\xac\\xfc\\xf9\\x2f\\xcb\\x98\\x17\\xce\\x2c\\x59\\xf7\\x05\\x16\\x86\\xb4\\xfd\\x3a\\xbc\\x53\\xd5\\xa7\\x55\\xba\\x1d\\x62\\x7f\\x40\\x6e\\x28\\x3a\\xad\\x74\\x5e\\x07\\x0e\\xc3\\x7d\\x89\\x1c\\xbf\\x90\\xbc\\x5c\\xd4\\xa5\\xe1\\xce\\x48\\xe7\\x45\\x0b\\xc5\\x95\\x57\\x85\\x71\\x7b\\x0a\\xdd\\x17\\x50\\x05\\x36\\x39\\x07\\x62\\x1a\\xc2\\x3e\\x68\\xb4\\x83\\xa2\\x2e\\x20\\x7a\\xaf\\x94\\x55\\x75\\x9f\\xb4\\x88\\x49\\x8b\\x9e\\x5b\\x60\\x5b\\x38\\xd6\\x6e\\xf9\\xb3\\xde\\x3d\\x32\\x25\\xc5\\x21\\x1c\\x37\\xa4\\x40\\x81\\xf9\\x63\\x3b\\xdc\\x12\\x78\\xeb\\x53\\x30\\x18\\xc3\\xe8\\x6a\\x10\\x44\\x12\\x6b\\x6f\\x16\\x11\\x18\\xbf\\xa7\\x0a\\xf8\\xe5\\x93\\x4b\\x25\\x9e\\xe1\\x2c\\x1b\\xda\\xc8\\x74\\x27\\x9b\\x10\\xba\\x85\\x02\\xcf\\x1f\\x2a\\x23\\xd7\\x52\\xd9\\x78\\x65\\x40\\x87\\x5e\\xc8\\xe8\\x2b\\x79\\x3b\\x14\\x35\\x0a\\xa1\\x93\\xcb\\x5f\\x52\\x70\\xc8\\x05\\x5a\\xa0\\x39\\xaa\\x6a\\xf5\\x02\\xf2\\x24\\x18\\xc0\\xa7\\x09\\x8d\\x9e\\xb9\\xee\\x07\\x1b\\x8b\\x67\\xdf\\x7b\\xf9\\x12\\x30\\xe7\\xf0\\x04\\x18\\x85\\x0b\\x6d\\xf7\\xd6\\x97\\x4e\\x21\\x77\\xbc\\xde\\x4c\\x0d\\xfd\\xeb\\xe7\\xb2\\xfe\\x1a\\x13\\x32\\x48\\x7f\\x7b\\x15\\xf3\\xd2\\xe4\\x53\\x91\\x13\\x32\\xab\\xc8\\xc4\\x16\\x68\\x3c\\xe5\\x61\\x5e\\x7a\\xd2\\xc9\\xe8\\x1b\\x9c\\xc8\\x81\\xee\\xd4\\x34\\xd2\\x84\\xa7\\xa4\\x7f\\x7d\\xdd\\x24\\xa1\\x56\\x21\\x9e\\x28\\x7b\\x54\\x4b\\x3e\\xda\\x3d\\x9c\\x95\\x3a\\x3a\\xae\\xcc\\xea\\x36\\x81\\xa4\\x63\\x35\\x0f\\xbf\\xbe\\x28\\x27\\xd8\\xda\\x86\\x7c\\x98\\x15\\xac\\x24\\x1c\\x2f\\x7d\\x07\\x47\\x63\\x7d\\x0b\\x94\\x1e\\x1c\\xba\\x61\\x4e\\x5f\\x4a\\x5b\\xee\\x7a\\x8e\\x45\\x64\\x45\\xdb\\xff\\xd1\\xa4\\x9e\\x41\\x28\\x82\\x67\\xf6\\x46\\x33\\xb5\\x7f\\x82\\x00\\xe2\\xf5\\xe8\\x83\\x13\\x0b\\xe9\\xb5\\xb2\\xa7\\x89\\x8e\\xa5\\xa2\\x16\\x69\\x4c\\x7e\\xe0\\xba\\x83\\x51\\xe5\\xc7\\x8f\\x46\\xfb\\xe2\\xba\\x68\\x26\\xd2\\x98\\xe4\\x18\\xb4\\x25\\xd4\\x26\\xd8\\x4b\\x1b\\x94\\x76\\xd7\\x21\\xc8\\x3a\\xb5\\x6e\\xdb\\x3d\\x98\\xfa\\x78\\x41\\x38\\xc5\\xf4\\x48\\xa9\\x6b\\xad\\xf9\\xed\\xb4\\x6c\\x13\\xfb\\x32\\xbd\\x07\\x67\\x1d\\x02\\x4b\\x45\\xd3\\xa9\\x55\\x2a\\x0b\\x49\\x82\\x75\\x13\\xf9\\x63\\x97\\x0c\\x16\\xaa\\x91\\xe9\\x2c\\x6d\\x99\\x1f\\xbc\\xa2\\xd4\\x85\\x35\\xb5\\xa6\\x71\\x59\\x33\\x90\\x27\\xaa\\x0f\\xa0\\xaa\\x4b\\x3e\\x30\\xfa\\x60\\x67\\x93\\x03\\x69\\x3a\\x8a\\xf2\\xdd\\x29\\x9d\\x37\\xf2\\xfd\\xa5\\x07\\xc1\\xc2\\x3a\\xa2\\xe6\\xcf\\xd9\\xeb\\xba\\xff\\xd8\\xf2\\xb4\\xc1\\x27\\xa8\\xc5\\xdf\\x68\\x1d\\xc9\\x3e\\x87\\xcc\\xcc\\x2d\\x1f\\x6e\\xaa\\x70\\x11\\x63\\xa3\\xe9\\xf6\\xe6\\xaf\\x44\\xf7\\x59\\xb4\\x56\\x5a\\xc5\\xb5\\x53\\xf7\\xb0\\xb5\\xe0\\x4b\\x94\\x65\\x54\\x5a\\xa0\\x2d\\x35\\x43\\xe2\\x74\\xa2\\xe0\\x95\\x2c\\x49\\xa4\\xc9\\xed\\xe6\\x9c\\x96\\x38\\x0f\\xa5\\x26\\xe2\\x02\\x6c\\x3c\\x9e\\xf3\\xa2\\x69\\x5b\\x50\\x7c\\x35\\x15\\x9e\\xcc\\x1a\\x74\\x2d\\x4f\\x13\\x65\\x08\\xf5\\xe5\\x33\\x80\\x6b\\x25\\x28\\xbb\\xa1\\xec\\xb4\\x00\\xeb\\x86\\x96\\x97\\x22\\x8b\\x7a\\xd5\\x9e\\x8d\\x1a\\x79\\x19\\x90\\x5f\\x18\\x8a\\x05\\x7f\\x57\\x0c\\x2f\\xee\\x5e\\xa2\\xfe\\xef\\x8f\\x35\\x25\\x9d\\xe4\\xe8\\x29\\x7d\\x8e\\x68\\xf4\\xfc\\x0c\\x87\\xc5\\x58\\x11\\x7e\\x69\\xee\\x2f\\x56\\xea\\x5a\\xe4\\xaf\\xf9\\xa6\\x79\\x3d\\x10\\x84\\x51\\xf1\\xf3\\xe8\\x7c\\x0d\\x99\\x40\\xe4\\xdb\\x2f\\xd7\\x21\\xc5\\x4b\\x15\\x64\\x25\\x43\\x5b\\x85\\x5e\\x0b\\x83\\x88\\x72\\x3d\\x05\\x6c\\xdb\\x01\\xfe\\x08\\x57\\xd3\\x5b\\x07\\x03\\xd9\\x48\\x15\\x8f\\x35\\x3a\\x3e\\xab\\xa7\\x14\\xac\\xa6\\xd7\\xce\\x66\\xce\\xf9\\xa5\\x93\\x81\\xdf\\x95\\x84\\xa6\\xa4\\x24\\xcf\\x08\\xbd\\xca\\x4e\\x78\\x73\\x68\\xcc\\x5c\\x8a\\xe2\\x47\\xec\\x67\\xe3\\xcb\\x95\\x86\\x0c\\xe5\\x1e\\x23\\xf6\\x72\\xfb\\x39\\x6c\\xbf\\x4a\\xcf\\x5c\\x8a\\x13\\x4d\\x7f\\x24\\xf6\\x80\\xc5\\x11\\xff\\xcc\\xa8\\xf5\\x65\\x16\\x2e\\x9f\\x94\\x19\\xff\\xa0\\xa7\\xf3\\xe8\\x7f\\xdb\\x2d\\x97\\x39\\x23\\xff\\xb5\\xa1\\xa8\\x3c\\xa9\\x3d\\xb3\\xbe\\xad\\x58\\x93\\x60\\x9d\\x8c\\xef\\x74\\xb1\\x46\\x20\\xa6\\xd0\\xdb\\xc8\\xa3\\xf6\\xf7\\x89\\xf4\\xcc\\x54\\x6e\\xfd\\x4b\\xa2\\xa3\\xf6\\x0d\\x5e\\xfd\\x40\\x0b\\x7b\\x2a\\xbe\\x1c\\x7f\\x7e\\x14\\x38\\xd1\\xbf\\xa9\\xfa\\x60\\x78\\x47\\x54\\x74\\x12\\x16\\xf7\\x99\\xd6\\x1f\\x94\\xee\\x04\\x5c\\x2c\\xaf\\x71\\xc1\\x08\\xa9\\xa3\\xbd\\x24\\xff\\x94\\x1f\\x65\\x09\\x3c\\x47\\x16\\x2d\\x80\\x81\\xe9\\xef\\x47\\x9f\\x74\\xf6\\x14\\x9c\\xe1\\x7a\\x64\\x01\\xc0\\xef\\x19\\xbe\\x0a\\x73\\xb3\\xac\\xa0\\x80\\x34\\x30\\x49\\xf4\\x9d\\x30\\x7f\\x39\\x69\\xb1\\xe8\\x6a\\x2a\\xd9\\x72\\x67\\xac\\x25\\x4c\\x1c\\xde\\xea\\xac\\xef\\x75\\x71\\xcf\\x17\\x6f\\xe7\\x79\\x19\\x52\\xfd\\x91\\xb8\\x0a\\x61\\x49\\xd3\\x49\\x69\\xa7\\x8a\\xe0\\x41\\x46\\x70\\xf9\\xed\\x44\\x72\\x60\\xc1\\x83\\x4a\\xe7\\x86\\x1e\\xf5\\x1f\\x02\\xec\\xbc\\x2b\\x40\\x0a\\x3d\\xf2\\x2d\\x5a\\x1b\\x72\\xb5\\x36\\x89\\x63\\xa0\\xac\\xf9\\x92\\x5d\\x2f\\x46\\x81\\xb2\\xcb\\xd0\\xbd\\x0a\\xc4\\x12\\xf3\\xd8\\x0b\\x44\\xd0\\xa9\\x2c\\x4f\\x04\\xb6\\x12\\xbb\\x3e\\xbb\\x6d\\x9b\\xf3\\x2d\\xb5\\x49\\xca\\x82\\xd5\\x2c\\x23\\x08\\xae\\xe5\\xef\\xe4\\x15\\x83\\x2f\\xed\\xae\\x26\\xab\\xfd\\x95\\xa4\\x67\\x38\\xa4\\x41\\xc6\\xdb\\xcb\\x5e\\x6a\\x41\\xd6\\x39\\x3f\\x35\\x4f\\x94\\x3a\\xe4\\xd6\\x21\\xec\\xae\\xc4\\xc4\\x81\\xfe\\xf8\\xe9\\xfb\\x87\\xdc\\x2f\\x1d\\x26\\xea\\x0f\\xf9\\xcb\\x8f\\x58\\x6d\\xd0\\xf7\\x13\\x2d\\x9f\\x62\\x9d\\xa3\\x4c\\xd8\\xf1\\x3f\\x6b\\x0b\\x8c\\x56\\xe7\\xea\\x2b\\x21\\xa5\\x26\\xb2\\x62\\xb5\\x2f\\x33\\x27\\xd4\\x03\\x26\\xfa\\xa3\\x85\\x14\\x45\\x5e\\xb3\\xf1\\xac\\x4a\\xfb\\x8b\\x41\\x8f\\x0e\\x6b\\x4a\\x3a\\x22\\x1d\\xcb\\x1d\\xc7\\x52\\x2c\\x19\\xcc\\x4f\\xb3\\x02\\xa8\\xaa\\xe4\\xea\\x5a\\x13\\x98\\x9a\\x61\\xf6\\x86\\x55\\x05\\xd5\\x98\\xfc\\x96\\x57\\x79\\x0e\\x90\\x57\\xda\\x5e\\xfe\\x68\\x9a\\x4e\\x06\\x52\\x07\\xf1\\xbe\\xa8\\xce\\xd5\\xa6\\x18\\x76\\xef\\x08\\x89\\x78\\x5e\\x5b\\x9d\\x4d\\x3f\\xdc\\x04\\x9b\\x5c\\xef\\x4a\\x38\\xe7\\x3f\\x50\\x66\\x50\\xe8\\xe8\\x7a\\xfa\\xba\\xc0\\x11\\x6e\\xe2\\x35\\x74\\x96\\x98\\x49\\x1a\\xc4\\x6f\\xf4\\x2e\\xb8\\x47\\xed\\xbd\\xf7\\xd7\\x6e\\x07\\x5a\\x5a\\xe1\\xf2\\xf2\\xe7\\xc0\\x6d\\xce\\x57\\xdc\\x94\\xee\\x36\\x7a\\xc8\\xa6\\x49\\xfa\\x18\\x14\\x17\\x55\\x12\\x71\\x06\\xe5\\x1d\\x95\\x79\\x76\\x77\\x58\\x45\\xd3\\xa0\\xc3\\xf6\\xcd\\x82\\x26\\x00\\xb2\\xfa\\xfd\\xf0\\x58\\xc1\\xe7\\x5a\\x60\\x18\\x73\\x92\\x7e\\x7c\\x12\\x8a\\x4f\\x38\\x52\\xcc\\x0e\\x49\\x09\\x62\\x5d\\xe2\\x6d\\x14\\x1c\\x90\\xfa\\xfc\\xcf\\x71\\x1d\\x73\\xcf\\x87\\x23\\xa5\\xc7\\x1c\\x92\\x2c\\xb7\\xc2\\xa1\\x81\\x9f\\x43\\x8e\\x5e\\x11\\x31\\xa9\\x68\\xb2\\x44\\x4f\\x12\\x2e\\xa7\\xe3\\x5a\\xb6\\x9f\\xb3\\xe3\\x7e\\xa7\\xf3\\xc1\\xfe\\x3e\\x49\\x24\\xb6\\x75\\xd0\\xd6\\x0f\\xd0\\xa5\\xc6\\xd8\\x69\\xc6\\x92\\x32\\x75\\x53\\x22\\x32\\xc2\\xbc\\xbe\\x56\\x3b\\x86\\x6c\\x1f\\x20\\x69\\x95\\x8a\\x23\\xa1\\xfe\\xc2\\x2a\\xed\\x18\\xac\\xd3\\x09\\x14\\x23\\xad\\xc1\\xd9\\x51\\x59\\x5c\\xc3\\x12\\x85\\x31\\xa5\\x5b\\x8a\\x52\\x18\\xcb\\x30\\x3c\\x21\\xc9\\x15\\x10\\xc9\\xa3\\xa4\\x1f\\x04\\x14\\xb5\\x30\\x72\\xde\\x30\\x8f\\xf2\\xf9\\x1e\\x7f\\x15\\x4f\\xb2\\xc0\\x39\\x68\\xc0\\x7b\\x40\\xc1\\x70\\xc4\\x10\\x10\\x23\\xc0\\xef\\x8b\\xed\\x17\\xa8\\xbe\\x13\\x5f\\x7e\\xe5\\x88\\xae\\x85\\x7e\\xc6\\x15\\xa1\\x39\\x79\\x4a\\x0c\\x4d\\xa6\\xaf\\xf7\\xad\\x0d\\xd1\\xfa\\xe9\\x2f\\xec\\x4f\\x6f\\x3e\\x99\\x5f\\xfe\\xf1\\x5a\\x6f\\xc6\\x57\\x9e\\x38\\x8c\\x22\\x88\\xd1\\x06\\xbf\\xaa\\x62\\xf8\\x7b\\x7b\\x9b\\x55\\x28\\x86\\xe1\\x90\\x66\\x91\\xd2\\x38\\xcc\\x15\\xbb\\x04\\x98\\x40\\x28\\x1a\\xfb\\x9d\\xef\\xe7\\x6a\\x7d\\xf0\\x0e\\x24\\xf3\\x2b\\x6e\\x4c\\xfe\\x02\\x81\\x64\\x15\\x13\\x15\\xfa\\xe4\\x06\\x2b\\xd9\\x49\\x22\\x1d\\x1b\\x41\\xcd\\xa1\\xf6\\xb0\\x09\\xc3\\x70\\x8e\\xa5\\x0e\\x86\\x39\\x92\\x79\\x19\\x5f\\x08\\xb9\\x9f\\xbd\\x08\\x45\\x5e\\x2a\\x11\\x56\\x9c\\x81\\x71\\x82\\x7e\\xe4\\x8c\\x4c\\xd9\\x8f\\xcf\\xe0\\x43\\x7d\\xad\\x6b\\x30\\x9a\\x01\\xda\\x9b\\x98\\xfd\\xa7\\x4e\\x05\\x88\\x5f\\xe0\\x35\\x10\\x84\\x9e\\x32\\x11\\x3b\\x6e\\x52\\x3c\\x15\\x2c\\xa4\\x4c\\xb0\\x44\\x55\\xc9\\x3d\\xe8\\xf5\\xf0\\x78\\x8b\\x48\\xa2\\x56\\x93\\x0a\\xa0\\x1a\\xcd\\x2e\\xf8\\xbe\\x22\\xf2\\x22\\x25\\x4d\\x5b\\x55\\xa0\\xd2\\xae\\xe2\\x64\\x5d\\xf1\\x29\\xab\\xe7\\xda\\x3f\\x7e\\x2f\\x09\\x96\\xea\\xee\\x71\\xa7\\x7e\\x28\\xf8\\x70\\x96\\xc2\\xe4\\x66\\x5a\\xc1\\x0c\\xf1\\xb7\\xef\\xcb\\xa3\\x8f\\x05\\x46\\x95\\xd6\\x3f\\x79\\x74\\x76\\x99\\x7f\\xed\\xbc\\xeb\\x19\\xa2\\x4f\\x1b\\xfe\\x0b\\xd7\\x2e\\x2b\\x56\\x77\\xc0\\xcb\\x25\\x83\\x45\\x31\\xf1\\xb3\\xd4\\xb6\\x90\\x32\\x10\\x5d\\x5f\\x19\\x0e\\x6d\\xc5\\x45\\x61\\xa7\\xcf\\x5d\\x85\\xc0\\x90\\x36\\xf1\\xfd\\x27\\xeb\\x3a\\x5e\\xa9\\xac\\x38\\x1b\\x7a\\x3d\\xb0\\x15\\x89\\x2d\\xe7\\x2e\\x39\\xaf\\x34\\x8c\\x91\\x9b\\x7e\\x3e\\x15\\x1c\\x58\\x3c\\x60\\xa7\\x86\\x98\\xf6\\x84\\x90\\xe6\\xc8\\x16\\x30\\x3a\\x0d\\x5d\\xc8\\xcd\\x03\\xdb\\x94\\xaf\\x6c\\xad\\x1b\\xc3\\x79\\xc2\\x07\\x14\\x5b\\x36\\x2e\\x9c\\x6c\\x69\\x0f\\x7e\\x5a\\x76\\xf0\\x83\\x8a\\x7f\\x52\\x62\\xda\\xe8\\xab\\xa4\\x62\\xa8\\xe3\\x7d\\x73\\x87\\xf7\\x3e\\x9d\\x4a\\xe5\\x32\\x1c\\x45\\xd2\\x11\\xae\\x57\\x98\\x6d\\xa1\\x40\\xf7\\x48\\x13\\x58\\x0d\\x74\\x1e\\xc4\\xaf\\x6e\\xf9\\xe0\\x84\\x5f\\x9e\\xb6\\x96\\xfd\\x27\\xcd\\x1a\\xcb\\x68\\xb4\\x89\\x8c\\x19\\x79\\xa2\\x5f\\xeb\\xb7\\x93\\x42\\x5c\\x62\\xbf\\x94\\xbf\\xfe\\xe9\\x87\\xcc\\x78\\xc6\\x00\\xed\\x53\\xfd\\x98\\x25\\x47\\xc6\\x72\\x85\\x97\\x33\\xe4\\x98\\x9d\\x86\\x6f\\xe0\\x02\\x2d\\x2f\\x20\\xae\\x4d\\xec\\xdf\\x6b\\x20\\x56\\x90\\x66\\xb8\\xdc\\xbe\\x67\\x7e\\x2c\\x1a\\x2e\\x9b\\xa0\\x5d\\xf5\\xf6\\x9e\\xbf\\x23\\x7d\\x89\\xd3\\x76\\x89\\x2b\\x50\\x4e\\xf5\\x6e\\x39\\x55\\x18\\xc9\\x87\\x4d\\x60\\x84\\x22\\x76\\x88\\x85\\xb4\\xbc\\x8a\\xe1\\xad\\x16\\x01\\x49\\x4f\\xc9\\x2b\\x2a\\x03\\x8c\\x64\\x93\\x4f\\xf5\\x02\\xa9\\x15\\x35\\x2b\\xc7\\xbd\\x69\\xb9\\xc5\\x6f\\x7a\\xb3\\xe5\\xb0\\x89\\xb0\\x60\\x02\\x33\\x8e\\x35\\x55\\xb9\\x47\\xe6\\x6f\\x5d\\x1a\\xc7\\xf1\\xba\\x4a\\x31\\x4a\\x76\\x26\\x97\\xd8\\xb2\\xff\\xa6\\x09\\x95\\x3e\\x33\\x34\\xde\\x4a\\x3b\\x6b\\x24\\x41\\x74\\xa5\\xaf\\x95\\x67\\xc6\\x12\\xc3\\x8f\\xc8\\xd3\\x60\\x7b\\x73\\x08\\xd4\\x7d\\xcf\\xf0\\xf1\\x2c\\x2a\\x7b\\x37\\x63\\xc0\\x9e\\xc1\\x87\\x80\\x0a\\x36\\x7f\\x53\\x59\\x35\\xe0\\x40\\x5d\\x67\\x16\\x19\\xd8\\xcc\\xbd\\xd1\\x1f\\x6e\\xc7\\x32\\x13\\x6f\\x31\\xde\\x1a\\xac\\x7a\\xbb\\x18\\x04\\xd6\\x9a\\x72\\x07\\x6b\\x0b\\x1d\\xb6\\x1a\\x23\\x28\\x7f\\x74\\x80\\xd0\\x7b\\x1b\\xe4\\x31\\x0a\\xe5\\x1f\\x00\\x28\\x77\\xc3\\x00\\x53\\xed\\xff\\xf5\\xc8\\xce\\x73\\x29\\x78\\xcb\\x31\\x89\\xdf\\x54\\x85\\x46\\xe2\\x4b\\x83\\xc7\\x6c\\x56\\xd7\\x5d\\xe9\\x30\\xeb\\x82\\x44\\xdb\\xbc\\x8f\\xdc\\xe1\\xce\\xa8\\xb2\\xb4\\x2d\\xc9\\x4b\\xc6\\x40\\x19\\x41\\xeb\\x57\\x74\\xae\\xe8\\xfc\\xa1\\xcb\\xeb\\x0e\\xed\\x11\\xd6\\x93\\xc5\\x78\\x93\\x1c\\xe5\\x4b\\x32\\xb4\\xd0\\xaa\\x9b\\x5c\\x8f\\x23\\x34\\x38\\xd3\\xc2\\x5d\\x1e\\x8e\\xc2\\x73\\x2a\\xc3\\xda\\x7a\\xc7\\x30\\x43\\x63\\x2c\\x47\\xa8\\x2d\\x4e\\x20\\x1a\\x92\\xf7\\x04\\xfb\\xff\\x0d\\x8c\\x53\\x20\\x6b\\x84\\x70\\x8c\\x2a\\x7a\\x98\\x24\\x7d\\xd3\\x82\\x20\\x7c\\xac\\xe0\\xf6\\xaa\\x02\\xaa\\x6b\\x5e\\xd5\\x1c\\xd1\\x78\\xd4\\xe6\\xf6\\x1b\\xaf\\x31\\x16\\x46\\xfa\\x39\\xaf\\x8f\\x66\\x78\\x91\\x0b\\x62\\x6d\\x08\\xbc\\x29\\xc3\\xb7\\xd1\\xef\\x74\\x59\\x08\\x5c\\x7f\\xfa\\xe4\\x30\\xd5\\xc7\\x05\\xce\\x66\\x69\\x20\\x90\\xc3\\x59\\x2c\\x11\\x92\\x29\\x03\\x26\\x25\\x4f\\x60\\x3c\\x95\\xff\\x1e\\x1c\\xb1\\x15\\xc3\\xbd\\x30\\x2c\\x31\\xe5\\x10\\xbb\\xfe\\xcf\\x46\\x04\\xcf\\x94\\x06\\x2d\\x76\\x9d\\xa1\\x14\\x9d\\x41\\xcc\\x43\\xad\\x93\\xa0\\x65\\x48\\x3c\\x7f\\x14\\xd3\\xcf\\xc9\\x22\\x35\\x33\\xaf\\xb6\\xf4\\xc4\\x33\\xc7\\xb6\\x55\\x7a\\x34\\x97\\x51\\xe8\\x69\\xa4\\xfc\\x5c\\x0f\\xaf\\x54\\x58\\xbb\\xa4\\x12\\x93\\xe9\\x37\\x5a\\xb4\\x3e\\x43\\xcb\\xef\\x7b\\x30\\xd2\\x25\\x42\\x36\\x65\\x4b\\xe6\\xf7\\x2a\\x14\\xaf\\x1a\\xeb\\x30\\xc0\\x88\\xa4\\x18\\xde\\xb5\\x10\\xc5\\xf4\\x24\\x73\\xd8\\x32\\xff\\xdc\\xdf\\xd0\\xea\\x8c\\x14\\xb1\\x56\\x5d\\x9a\\x03\\xfd\\x71\\xbf\\x79\\xd7\\xb8\\xc3\\x6c\\xc2\\x96\\x11\\xd5\\xbe\\x4b\\x37\\x14\\x77\\xd0\\x07\\x15\\x26\\x9f\\x0e\\xa1\\x42\\xf6\\xa1\\x33\\x04\\x36\\x38\\x6b\\x03\\xaf\\x76\\x8e\\x00\\xe9\\xa1\\xf1\\xd4\\x5a\\x67\\x0e\\x39\\xa5\\x82\\x8b\\x23\\x9c\\x0f\\x05\\xca\\x82\\x24\\xaf\\x99\\xb9\\x15\\xfe\\x70\\xb6\\x39\\x27\\x00\\x0a\\x1a\\x9d\\x57\\x71\\xc8\\x27\\x82\\xb3\\x47\\xfc\\xb7\\xc5\\x4f\\x2d\\x62\\xeb\\x10\\x6d\\x5c\\x29\\x0c\\xd5\\x26\\x0c\\x6e\\x28\\xe2\\xe5\\x6f\\x24\\x2c\\x39\\x3f\\x5e\\x03\\x3f\\xac\\x05\\x0e\\x56\\x80\\x48\\x05\\x2b\\x21\\xb7\\x9c\\xa2\\x53\\x03\\x18\\x9d\\xc4\\xd3\\x87\\x97\\x41\\x3d\\x82\\x04\\xb3\\xf4\\x2d\\x27\\x3f\\x45\\x8c\\xdb\\xd1\\x67\\x80\\x18\\x4d\\x81\\x61\\xfa\\x56\\xd0\\x1a\\xc0\\x98\\x8a\\xe2\\x35\\x2c\\x2a\\x3b\\xb7\\x95\\x3e\\xe1\\xec\\xa9\\xda\\x7f\\x73\\xe4\\x74\\xfb\\xe7\\xc7\\xe1\\x1f\\x0e\\x1d\\x37\\x3a\\x04\\x4b\\x1a\\x8b\\xde\\x0c\\x03\\xfd\\xed\\x9b\\x13\\x93\\x6e\\x51\\x41\\x7d\\x82\\x54\\xc3\\xd8\\xd8\\xbf\\x62\\x24\\x25\\x54\\xff\\x16\\x77\\x5e\\xc2\\x78\\xb9\\x8d\\x9e\\x7e\\x06\\x40\\x6a\\xb3\\x52\\x01\\xd5\\x3c\\xe1\\xa0\\x7f\\xb0\\x5f\\x3a\\xcf\\x2a\\xcb\\xce\\xb0\\xb2\\x5c\\xf7\\x6b\\x43\\x4c\\x38\\xa7\\x7f\\x6a\\xfd\\xef\\xa5\\x1d\\x7d\\x15\\xd9\\x82\\x6c\\x9d\\x8e\\x3f\\x08\\xf1\\xfe\\xaa\\x29\\x5e\\xc4\\xee\\x40\\x24\\x66\\x9f\\x5d\\x6d\\x29\\xdc\\xd5\\x54\\x0c\\xaa\\xd6\\xb4\\xf9\\xb0\\xae\\x8a\\xe3\\x85\\xce\\xfb\\xc3\\x2d\\x8a\\x29\\xd7\\x5e\\x22\\x4c\\x84\\xab\\xec\\x4f\\xa5\\x4d\\x49\\x8c\\x4f\\x6e\\xf7\\x1e\\x6a\\x03\\x76\\x6a\\xce\\x09\\x74\\x1a\\xa0\\xf6\\x31\\xdd\\x91\\xa4\\xe1\\x27\\x39\\xbb\\x46\\xf8\\xe7\\x41\\xbb\\xfe\\x7f\\x76\\x74\\xb9\\xad\\x34\\xfa\\x38\\xad\\xf5\\xa1\\x8a\\x87\\xe5\\x11\\x73\\x04\\x48\\x18\\xfa\\xd2\\xbf\\x99\\xb1\\x20\\x53\\x86\\xe5\\x0d\\x9f\\xa7\\xf1\\x9e\\xfc\\xcc\\x94\\x7d\\x86\\x6d\\xa7\\xc7\\xc0\\x5d\\xa0\\x9f\\xe2\\x62\\x81\\xeb\\x06\\x18\\x45\\xc0\\x51\\x0b\\xaf\\xc7\\x75\\xbe\\x5e\\x0b\\x95\\xa6\\xcc\\x49\\x45\\x8d\\xb1\\xd6\\x82\\x43\\x58\\xe2\\x7e\\x12\\x67\\xf1\\xfb\\x0f\\x26\\x04\\x86\\xe3\\x5d\\x94\\x5e\\xab\\x12\\x90\\x71\\x10\\x9c\\x58\\x1a\\x94\\x42\\x8d\\xc5\\xf2\\x07\\x45\\xa0\\x82\\x9d\\xfe\\xdd\\x6f\\xde\\xf5\\x85\\x5f\\x07\\x44\\xb6\\xec\\x49\\xa2\\x4d\\x4d\\xea\\xb7\\x2d\\xcf\\x37\\x7a\\xc6\\x75\\x80\\x79\\xd9\\x52\\x61\\x1e\\x5a\\x9d\\xb0\\x61\\xec\\xae\\xa8\\xb6\\xca\\x33\\x3f\\x3a\\xaa\\x00\\x3d\\x75\\xfb\\xef\\x1c\\xd4\\xe1\\xf3\\x9d\\x59\\xf7\\xd0\\x88\\xf8\\x79\\xee\\xf8\\xba\\x6a\\xd7\\x1d\\x20\\xc9\\x05\\xf1\\x87\\xfb\\x5c\\xea\\x61\\x90\\x1f\\xd3\\x1b\\x52\\x07\\x98\\xcc\\x08\\x06\\x6b\\x0f\\x4f\\x6d\\x78\\xe0\\xe7\\x75\\xab\\x8b\\x56\\x05\\x5d\\xe2\\x24\\x48\\x6e\\x54\\xdb\\xee\\x7d\\x84\\xa5\\x06\\xd0\\xe1\\xd9\\x31\\x7f\\x53\\x99\\xff\\xeb\\xf6\\x9a\\x66\\xca\\xe2\\x58\\x0e\\xf8\\xe9\\xdf\\x0d\\x5c\\x47\\xf1\\x4f\\xc3\\x95\\xfe\\xd3\\xaf\\x35\\x8a\\x39\\xf2\\xa2\\x60\\x2a\\xeb\\xb2\\x6c\\x3f\\xc4\\xce\\x25\\x51\\x52\\xb1\\xc5\\x4c\\xc7\\xb3\\x37\\x36\\x86\\xfa\\x10\\x87\\x47\\xea\\x19\\x08\\x92\\xae\\x30\\x45\\x81\\x3b\\x6a\\xd1\\xc9\\x9a\\x8c\\x43\\x6b\\xe7\\xc3\\x3b\\xd1\\xd3\\x57\\xe7\\x2f\\x26\\x68\\xc1\\x65\\x22\\x96\\xf9\\xeb\\x7b\\xc2\\xf0\\x78\\xf9\\xe4\\x5f\\xe8\\x31\\xc2\\xe9\\x6a\\x4f\\x60\\x67\\xf6\\x70\\x51\\x54\\x55\\x3c\\x1b\\x91\\x1d\\x40\\xeb\\x19\\x69\\x52\\x70\\xe8\\x1e\\x52\\xfd\\x0e\\x44\\xfb\\xbf\\xd9\\x99\\x32\\x6d\\x9c\\xa3\\xaa\\xad\\x62\\x3a\\xe3\\xc5\\x71\\xe5\\xda\\x9d\\xea\\xd5\\x15\\xa6\\x41\\xbd\\xa6\\xed\\x9a\\x2e\\x3b\\x39\\x5d\\xd6\\x24\\x89\\xb1\\x46\\xc6\\xc4\\x23\\xe5\\x9d\\x54\\x3e\\xa3\\x72\\xea\\x5c\\x5d\\x64\\x53\\x8e\\x3a\\xb4\\xea\\xab\\x02\\x52\\x99\\x17\\xd7\\x84\\x9d\\x2f\\xe9\\xed\\xfd\\x07\\x77\\xf6\\xc7\\x67\\x38\\xfe\\x16\\xd5\\xa8\\xd6\\x7c\\x8f\\x00\\xe3\\xea\\x2c\\xd7\\x95\\x84\\x1f\\x38\\x2c\\xdd\\x31\\x84\\xcb\\x18\\x05\\x28\\x9b\\x65\\x74\\x36\\x11\\x19\\xa7\\x31\\xfd\\x13\\x01\\x2c\\xdb\\x1e\\xd2\\x8f\\x58\\xdc\\x24\\x7a\\xf7\\x55\\xbb\\x36\\xb7\\x03\\x68\\x82\\x56\\x4b\\x50\\x98\\x04\\x7b\\x78\\x9f\\xd2\\xb8\\x4e\\xcf\\xfb\\x38\\xfd\\xdf\\xeb\\xad\\xec\\x25\\x95\\x38\\xee\\x9a\\x03\\x23\\x92\\xe3\\xfd\\x7d\\x79\\xc0\\x65\\x7e\\xe7\\xd2\\x68\\x3c\\xc9\\xee\\xf9\\x33\\x2d\\x51\\x08\\x42\\xb1\\x6b\\x7f\\x11\\x84\\xa1\\x26\\x59\\xf6\\x20\\xbf\\x83\\xaa\\x42\\xa6\\xa9\\xad\\x41\\x25\\xa4\\xe4\\x30\\x7a\\xda\\x5f\\x94\\x8a\\x11\\xaf\\xfc\\xdc\\x50\\xb0\\x5c\\x02\\x6f\\x38\\xa9\\x60\\xf3\\xf3\\x45\\x34\\xa0\\xc8\\xe9\\x3d\\x8a\\x87\\x22\\x0e\\x17\\x5c\\xc5\\x65\\x9e\\xc9\\xf8\\x3f\\x9c\\x3a\\x67\\x15\\xc6\\xb9\\xad\\x3f\\x9a\\x21\\x34\\xd5\\xd9\\x54\\x17\\xb6\\xc4\\xa1\\xc9\\x8f\\xc3\\xf0\\x48\\xba\\xbf\\xfc\\x1f\\xdf\\x91\\xaa\\x02\\x86\\x61\\xc0\\xa0\\xc4\\xaa\\xf4\\x24\\x84\\x01\\xf5\\xc8\\x11\\xba\\x04\\x7f\\x01\\x5c\\x04\\xf8\\x14\\x90\\xc6\\xdf\\x4b\\x2d\\xb6\\xbe\\x45\\x84\\x79\\xed\\x0a\\x21\\xd3\\x47\\xa7\\x75\\xce\\x94\\xbb\\xc0\\x9b\\xd5\\x3c\\xaa\\x61\\x08\\xc8\\x2c\\x99\\xb4\\xd1\\x09\\x55\\x4b\\x7f\\x99\\xae\\xd1\\x6e\\x1b\\x5b\\xd0\\x1e\\x9f\\xd1\\x16\\xba\\xdd\\xc5\\x25\\xd4\\xa2\\xb0\\x9a\\xb0\\x55\\x7f\\x17\\x9c\\x55\\x3d\\x55\\x83\\xa2\\x16\\x32\\xbb\\x00\\x71\\x47\\x64\\x85\\xa5\\x21\\x37\\xd4\\x5b\\xe4\\x0b\\x6d\\xe3\\x5c\\x78\\x6c\\xec\\xe0\\x5e\\x41\\xc9\\x55\\x6b\\xe3\\xb1\\x91\\xc1\\xd6\\xf1\\x4a\\xe7\\xea\\xe9\\xc3\\x7b\\x66\\x9f\\x0d\\xe7\\xfe\\xca\\x52\\x13\\xee\\x5a\\x9f\\xd0\\x9d\\xb2\\x0b\\xd9\\x85\\x54\\x49\\xb0\\x53\\x5f\\x4f\\x9b\\x02\\xc8\\xd4\\x05\\x1a\\x9f\\x9a\\xf1\\xec\\x45\\x61\\x18\\x96\\x17\\xf6\\x35\\x08\\xb1\\x09\\x33\\x2a\\xa0\\x5c\\xc9\\x87\\x11\\xf6\\x98\\x77\\xef\\xb1\\xac\\x80\\x14\\x4e\\xc6\\x27\\x10\\xe6\\x48\\x57\\xfb\\xeb\\x3a\\xaf\\x07\\xec\\xfe\\x99\\x07\\x6b\\xba\\x1a\\xeb\\xc5\\x31\\x2a\\x88\\xd8\\xc2\\x89\\x7f\\xe2\\x23\\x42\\x6f\\xd9\\x4a\\x2c\\xb6\\x7a\\xb9\\x29\\x2c\\x6d\\xe1\\xa2\\xf4\\x7e\\x3e\\xd9\\xbb\\x51\\xbd\\x87\\xbb\\x42\\xa7\\xfe\\x9e\\xcb\\x9a\\xa1\\x28\\x10\\xdf\\xc9\\x86\\xbd\\x3d\\x0c\\x5c\\x3f\\xe4\\x98\\xf9\\xdb\\x63\\xd5\\x7e\\x4a\\x76\\xb9\\xa7\\xee\\xe6\\xe2\\xc7\\xfc\\x04\\x67\\x20\\x82\\x7a\\x2a\\x87\\xf0\\xe5\\xe5\\x97\\x4c\\x8b\\xae\\xdf\\x6a\\x5c\\xc2\\xa3\\xe6\\x3e\\xdd\\xd6\\xf0\\xb7\\xe7\\xa5\\xeb\\xc0\\xa4\\xa5\\xbf\\xe2\\x66\\xe2\\x5f\\x13\\xc5\\x72\\x87\\x12\\x70\\x2a\\x75\\xcf\\xa3\\x12\\xaf\\x73\\xa8\\xfd\\x61\\x9c\\xa3\\xa6\\x46\\xeb\\xc7\\x86\\x8c\\x81\\xa9\\x2a\\xfe\\x47\\x46\\xd5\\xd2\\xdf\\x19\\xa4\\x6e\\xfa\\xd4\\x78\\x91\\x97\\xeb\\x60\\x6d\\x6f\\xae\\x24\\x27\\x11\\x86\\xd8\\x4a\\x3a\\x32\\x09\\xbf\\x43\\x40\\xdb\\x3e\\x94\\x18\\xff\\xbc\\x7f\\x3a\\xff\\x68\\x5d\\xa0\\xc2\\x6c\\x53\\x03\\xe1\\xb7\\x20\\x03\\xf1\\xa9\\x8d\\x1b\\x52\\x04\\xad\\x6c\\xbf\\xbe\\x64\\x7c\\xde\\xd0\\x82\\xc1\\x75\\x33\\x5d\\xf2\\xa1\\x9f\\x01\\x47\\xfd\\x32\\x2f\\xe5\\x82\\x5b\\x9d\\x8e\\xec\\xad\\x96\\x78\\xc4\\xbe\\xe0\\x32\\x6f\\x7f\\x23\\x61\\x39\\x98\\xe3\\xb2\\xef\\x9d\\xc6\\xf2\\x15\\x26\\x11\\xb0\\x0d\\xdc\\x2a\\xa0\\x4e\\x00\\x1b\\xc1\\x98\\x96\\x31\\x86\\x3a\\x44\\xd2\\xb7\\x16\\x88\\xe6\\xba\\xca\\x0f\\x23\\xad\\xd5\\x1b\\x0e\\xbf\\x25\\x64\\x92\\x1c\\x46\\x61\\x95\\x44\\x81\\x2c\\xd7\\x72\\xdb\\xdf\\x3b\\x40\\xc3\\x93\\xe8\\xf2\\x24\\xcf\\x6d\\x11\\x50\\x8b\\xa7\\xd8\\xca\\x06\\x01\\x02\\x16\\xe7\\xa4\\xde\\x55\\xb6\\xd4\\x61\\xe0\\x2a\\x76\\x19\\xa3\\x9b\\xfa\\x9f\\x0b\\x31\\xa0\\x35\\x55\\x6a\\x55\\x2f\\x3f\\x38\\x84\\x20\\xb9\\x72\\x54\\x7d\\xf1\\x10\\x7e\\x10\\x74\\xe9\\xdc\\x83\\x6d\\x43\\x6e\\x52\\x3f\\x52\\x09\\x44\\x7f\\x4e\\xd5\\xbb\\x8a\\xf3\\xec\\x94\\xee\\xa9\\x02\\xec\\x1e\\xdc\\x41\\x15\\x2c\\x26\\x89\\xa4\\x13\\xa5\\x70\\x1b\\x64\\xae\\xf3\\xe4\\x17\\x66\\x2b\\x2d\\xf4\\x64\\x77\\x9b\\x02\\xe3\\xb3\\x82\\x49\\xb4\\x90\\x69\\xed\\x10\\xbf\\x39\\xcc\\xe3\\x37\\xe3\\xa6\\x3b\\x3a\\x18\\x37\\x53\\xa6\\x80\\x47\\x78\\x9f\\xda\\xdb\\x2f\\xe6\\x72\\x18\\x49\\x7f\\x87\\x70\\xf2\\xea\\x57\\x17\\x77\\xf7\\xd9\\x67\\x5d\\xd5\\xca\\x9b\\xa6\\x73\\xf5\\x22\\x74\\x6f\\x27\\x86\\x8c\\x92\\x28\\x40\\x2c\\x30\\x8a\\x9a\\x9c\\xc2\\xcf\\xc2\\xbc\\x51\\x74\\xa1\\xc4\\x53\\x05\\xf4\\xb8\\xf4\\xa1\\x85\\x3c\\xf3\\x0b\\x0d\\x37\\xd2\\x07\\x84\\xff\\xe7\\xf2\\xd6\\xe2\\xf6\\x94\\xd7\\xd3\\x4e\\x39\\xc7\\x1d\\xd0\\x86\\x69\\x0a\\x08\\x32\\xbb\\x53\\x91\\x22\\x28\\x42\\xbc\\x5a\\x7c\\xe3\\xa0\\xa8\\x87\\xf1\\x28\\xe8\\x5f\\x02\\xb6\\xb7\\x7b\\x3b\\x64\\xda\\x7c\\x2a\\xe8\\xb2\\x84\\xae\\x3a\\xed\\xba\\x02\\x83\\x5b\\x02\\xe0\\xfc\\x01\\x02\\xfa\\x7b\\x9c\\xdb\\x46\\x5c\\xe5\\x37\\xdf\\x39\\xe4\\xf7\\xb9\\xe5\\x0d\\xb8\\xe5\\xca\\x62\\x1f\\x25\\x25\\x82\\x38\\xb8\\x5c\\x0b\\x5a\\xe5\\x04\\x8d\\x8d\\xd7\\xdc\\x48\\x05\\x54\\xdc\\x9b\\xec\\x04\\xa7\\x59\\x32\\x78\\xb3\\xcb\\x3e\\x23\\x3a\\xe0\\x7f\\xb0\\xfc\\x8c\\xbf\\x1c\\x28\\xcb\\x47\\xe7\\xae\\xc8\\xdc\\xa1\\x11\\xc2\\x7d\\x55\\xf8\\x44\\x9b\\x51\\x92\\xbf\\xb1\\xe5\\x27\\x57\\x14\\x60\\xcb\\xda\\xdb\\xcf\\xae\\xf9\\x35\\x20\\x78\\x7d\\xf3\\x08\\x85\\xa2\\x9b\\x1a\\xa3\\xff\\xa8\\x0f\\x80\\x47\\xe1\\x90\\x97\\xb6\\x9c\\xdb\\xcc\\xdf\\x1a\\x12\\x83\\x4d\\x89\\x38\\x22\\xb2\\xc2\\x1a\\x83\\x49\\xb8\\xa0\\x90\\x57\\xf0\\x3f\\xda\\x77\\xa1\\xc9\\x27\\x0a\\xf0\\x36\\x1b\\xdc\\x9b\\x67\\x0d\\x2f\\x96\\x1a\\x34\\x4a\\xcd\\x42\\x83\\xc2\\xf1\\x62\\xc2\\x5c\\xa6\\x66\\x9e\\x87\\x2e\\x11\\xd8\\x6c\\xa1\\xc5\\x81\\x12\\x9a\\xec\\xe4\\xfd\\x9a\\x3b\\xbf\\x5d\\x0e\\xdb\\x26\\x55\\x75\\xa5\\xd5\\xf4\\x9f\\x13\\xab\\x10\\x44\\x67\\x3a\\x5a\\x9d\\x9b\\x8b\\x47\\x01\\x95\\x08\\x66\\xad\\xa3\\xc0\\x0f\\x9f\\x2e\\x4f\\xf0\\x2e\\x0f\\x5b\\x5b\\x77\\x86\\x76\\x90\\x22\\xc2\\x10\\xf7\\x22\\xd1\\x28\\xc1\\x2a\\x0d\\xb5\\xb2\\x90\\x44\\x88\\x96\\x7c\\x01\\x61\\xb1\\x1f\\x64\\xfd\\xc1\\x74\\x5d\\xcf\\x8e\\x44\\x3b\\xf5\\xa8\\xec\\x8e\\xcf\\x1d\\x4e\\x2c\\x53\\x25\\x0c\\x20\\x6f\\xc1\\xa3\\xfe\\x99\\xef\\x93\\x48\\x2c\\x7e\\xfa\\xbd\\xaf\\xce\\xaf\\x0e\\xe4\\x54\\xda\\x34\\x3d\\x99\\x5e\\x2e\\x7a\\x75\\x16\\xba\\xe9\\x4e\\x0f\\xfd\\x06\\x6b\\xa4\\xe0\\x2c\\x18\\xee\\xbe\\xa7\\x7a\\xef\\x90\\x91\\x14\\x12\\xf5\\x8c\\xc2\\xdb\\x12\\xfd\\x64\\x25\\x01\\x3c\\x6e\\x7d\\x79\\xc8\\x16\\x46\\xc1\\x88\\x4d\\x06\\x58\\xbf\\x7c\\x97\\x49\\xa6\\xb9\\x2c\\x7c\\x80\\x63\\xae\\x8d\\xdb\\x32\\xc8\\x42\\x6f\\x58\\xca\\x50\\x62\\x10\\xa9\\xd1\\xb1\\xf3\\x0c\\x6f\\xa0\\x2c\\x34\\xe1\\x8c\\x8d\\xf3\\xa5\\x68\\xf4\\x91\\xbf\\xa4\\xff\\xc9\\xfb\\xc6\\xf6\\xb1\\xd6\\x78\\x73\\xe5\\x50\\xb7\\x6d\\xb4\\x36\\x83\\x78\\x70\\xc2\\x73\\x58\\xb1\\x43\\x99\\xe0\\x17\\xd8\\x9b\\x45\\xb1\\xcb\\x2f\\x9f\\xbb\\x1d\\x18\\x3d\\xbe\\xba\\x9b\\xdf\\x5c\\x25\\x5d\\xf1\\x66\\x4d\\x27\\xb9\\xff\\xee\\x7f\\xcf\\x86\\x79\\xfb\\x45\\x4f\\xda\\x16\\xf4\\x68\\x1b\\x6a\\x6d\\xed\\x5d\\x49\\x8c\\x4e\\x81\\x37\\x09\\x9c\\xc7\\x54\\x91\\x22\\x0e\\xbd\\x65\\x28\\xc3\\x71\\x79\\xa3\\x3a\\xa8\\xf2\\xfd\\x9d\\xb3\\xa0\\xa7\\x15\\x97\\xe2\\x84\\x58\\x0a\\x4b\\xb1\\x13\\x27\\x0c\\x5f\\x6a\\x58\\x91\\x85\\x13\\xca\\x76\\xb5\\xe2\\xcf\\xc3\\xf6\\x34\\x59\\x96\\xaa\\xb9\\xf3\\xab\\xa6\\x2b\\xf9\\xd5\\x53\\x2d\\x18\\x89\\x90\\x41\\xcd\\x4b\\xdd\\x4a\\xec\\xa8\\x81\\xa3\\xfa\\x9c\\x64\\x92\\x4d\\xd3\\xa2\\x94\\x0d\\x73\\xd0\\x3e\\x57\\x8c\\xab\\xf6\\xc8\\xfc\\xb5\\xe0\\x2f\\x43\\x48\\xf4\\xd6\\x91\\xef\\x4a\\xc9\\xce\\x2b\\xda\\xd8\\x08\\x35\\x80\\x92\\x32\\xb0\\x73\\xa3\\x6d\\xd2\\x38\\xe5\\x5f\\x59\\x78\\x0a\\xd0\\xd2\\xe0\\x05\\xa2\\x1d\\x9c\\xd5\\x77\\xf5\\x0f\\xdf\\x7a\\x5a\\x50\\xef\\xbe\\xc9\\x20\\xa9\\xb9\\xc2\\x90\\x65\\xed\\xbc\\xfe\\xd4\\xaf\\x98\\x1f\\xa6\\xfb\\xea\\x3e\\xbc\\x52\\xfb\\x8d\\x24\\x7a\\xcd\\xd4\\x9b\\x97\\x8d\\xd0\\xcc\\x2b\\xf8\\x82\\x8d\\x64\\x70\\xc9\\xc3\\x68\\xfe\\x61\\x25\\x7b\\x54\\x42\\xb8\\x5b\\x82\\xc7\\x2e\\xb4\\xfd\\x9c\\xc9\\x55\\xc7\\xd6\\x5e\\x0b\\xc5\\x43\\xa2\\x1d\\x20\\x03\\x43\\x78\\x9f\\xfa\\x0b\\x2d\\xc7\\x1a\\xb5\\x70\\xb6\\xa9\\x99\\x7a\\xc3\\x18\\xa5\\xea\\x29\\x45\\x65\\xe5\\x6a\\xc6\\x7d\\xeb\\x4d\\xbe\\x3a\\xf4\\x3b\\xdc\\x3f\\x9e\\xc3\\xb6\\x80\\xeb\\x4a\\x1c\\xc3\\xbd\\x48\\xa1\\x0d\\x49\\x93\\xc6\\x9a\\x77\\xaf\\x63\\xd7\\x2d\\xa4\\x16\\x4b\\x38\\x85\\x54\\x3e\\x76\\x12\\x8c\\x56\\x70\\xb0\\x4a\\xfc\\xc3\\x17\\x55\\xce\\x5d\\x7a\\xa4\\xa8\\x0c\\x4c\\x10\\x20\\xd4\\x4f\\xa3\\x60\\x40\\xc1\\x09\\x99\\x8c\\xd1\\x57\\xdb\\x36\\x6c\\x1b\\xff\\xdc\\x02\\x62\\xd2\\x3d\\xea\\x82\\xcb\\x11\\xa2\\x22\\x40\\x53\\x15\\x8f\\x83\\x94\\xfd\\x9d\\x63\\x21\\x41\\x1c\\x99\\x4d\\x01\\x05\\x4d\\x0c\\x82\\x19\\xa4\\x89\\x8b\\x29\\x1f\\x69\\xee\\x14\\x68\\xbf\\x94\\xca\\xb5\\xe6\\x92\\x71\\x05\\x1a\\x21\\x74\\x48\\xbd\\x68\\xb1\\x3d\\x36\\xd1\\xad\\x54\\xd7\\x17\\x0c\\x07\\x00\\x2d\\x2d\\x96\\xeb\\x98\\x18\\x0a\\xa8\\x80\\xf7\\xef\\xfd\\x4d\\x5a\\x37\\xcc\\x4f\\x65\\x2a\\x96\\x6a\\xca\\x87\\xc4\\x88\\xe2\\xea\\x1c\\xc5\\x15\\x50\\x4b\\x02\\xcb\\x4b\\x91\\x81\\x17\\xc9\\xbe\\x2f\\xad\\x71\\x87\\xf2\\xa7\\x75\\x25\\x56\\x6b\\xfa\\xa3\\x6a\\x13\\xf7\\x9f\\x73\\xf8\\x91\\x4f\\x70\\xb8\\xc6\\x0b\\x12\\xc3\\x21\\x62\\xf4\\xae\\xb3\\xba\\x71\\x5a\\xb2\\x38\\x00\\xf0\\xaf\\x9a\\xfc\\x65\\xbe\\xe3\\x35\\x0c\\xbc\\x51\\x92\\xa5\\x74\\x3e\\x75\\x99\\x21\\x26\\x87\\x90\\xda\\xe8\\x78\\xda\\x04\\xae\\x36\\x16\\x1f\\x25\\x67\\xe5\\x14\\xe6\\x6b\\xf4\\xb4\\xfe\\x7a\\xde\\xe9\\x95\\xa8\\x15\\xbc\\xf6\\x04\\x51\\x83\\x04\\x9f\\xc7\\x2d\\xb7\\x87\\xcd\\x71\\xf0\\xf6\\x53\\xf7\\x0d\\x1f\\xdb\\xc2\\xaa\\xfb\\x1d\\x5e\\x1d\\xcf\\xd5\\x76\\x3f\\xf5\\xfd\\xd3\\xbf\\x54\\x54\\x26\\x38\\xfa\\xc1\\xb1\\xfe\\x6c\\xca\\x7e\\x5e\\xa8\\x87\\x28\\x2f\\x8d\\xce\\x22\\x94\\x19\\x99\\xba\\xc3\\x5a\\xed\\x8e\\xa2\\xc0\\xec\\x31\\x88\\x29\\xb5\\xc3\\x44\\xd1\\x95\\x06\\x9d\\x14\\x27\\xc6\\xd1\\xef\\xeb\\x79\\x5e\\xe3\\xea\\xb0\\xef\\x93\\x17\\x36\\x12\\x7d\\x91\\x0a\\x60\\x21\\x41\\xa4\\xc6\\x28\\x70\\xae\\x71\\x77\\xff\\x8e\\x8a\\x44\\x14\\xba\\x6c\\x96\\xfe\\x8f\\x0d\\x98\\xe3\\x07\\x1e\\xa4\\xf5\\xed\\x57\\x68\\x2d\\x81\\xea\\xc5\\x43\\x9a\\x45\\xe2\\x66\\xec\\x1a\\x25\\xd2\\xe6\\xd9\\xc1\\xd2\\x16\\x4b\\x70\\xc1\\x27\\x50\\x21\\xb8\\x37\\x4e\\x6d\\x4d\\x34\\xff\\x68\\x44\\x30\\x2a\\xa2\\x56\\x26\\x44\\x53\\xe1\\x86\\x6d\\x9e\\xcd\\x63\\x5d\\xd3\\x92\\x6d\\xea\\x1a\\xd0\\x51\\x13\\x21\\x5a\\x44\\x81\\x75\\xf4\\xd2\\x6b\\x23\\xf8\\x71\\x5b\\x91\\x02\\xd4\\x1b\\x35\\x77\\x6d\\x5d\\x06\\x93\\x26\\xc8\\x7c\\xfb\\x25\\xc2\\x6b\\xd3\\x6a\\x17\\x67\\xfa\\xd5\\x4f\\x53\\xe3\\x53\\xf7\\x60\\xef\\x8d\\x87\\x34\\x53\\x5e\\x2d\\x0b\\x4b\\x86\\xbe\\x9d\\xb4\\x36\\x8c\\x28\\x56\\x6d\\x3c\\x30\\x74\\x04\\x68\\x12\\xd0\\xda\\x7b\\x9f\\x3a\\x7e\\xaf\\x8c\\x7b\\xae\\xe5\\xa1\\x06\\xf9\\x85\\x1b\\x40\\x99\\x04\\x91\\x2e\\xdc\\xdc\\xe2\\xab\\x23\\xff\\xf8\\x13\\x33\\x6a\\xa4\\x0e\\xad\\x05\\xaf\\xe3\\x4a\\x42\\xb3\\xd3\\x98\\x3a\\x2a\\x62\\xe6\\xbf\\x31\\x43\\x62\\xef\\x7c\\x9b\\x28\\x6c\\xe8\\xe3\\x35\\x74\\xb5\\xba\\x65\\x0d\\xf5\\xb4\\x20\\x8e\\x48\\xf3\\xa2\\x88\\xc2\\x19\\xca\\xcc\\x5e\\x4a\\x5f\\x5b\\x51\\x1b\\xc2\\xd0\\x38\\x90\\x51\\x27\\x70\\x62\\xb6\\x7e\\xb1\\x04\\xcc\\x62\\xcb\\x96\\x10\\xa5\\x1c\\x73\\x47\\x40\\xbb\\x2c\\x26\\x49\\xb6\\x06\\x04\\x6a\\xc5\\x76\\xdb\\x09\\xf8\\xc3\\x2d\\x78\\x2d\\x97\\xc3\\x86\\xd0\\xc7\\x16\\x92\\x0d\\x03\\x2a\\x26\\x70\\x43\\x5c\\x2e\\xc7\\x3f\\x3b\\x03\\xac\\x38\\x60\\x1c\\xf4\\x16\\x45\\x2e\\x1c\\x9e\\x7c\\xe4\\xce\\x34\\x2d\\xcd\\x69\\x29\\xc2\\x75\\x81\\xde\\xb2\\x34\\x23\\x14\\xc7\\xb0\\xc2\\x80\\xd7\\x26\\x60\\x19\\xa1\\x2f\\x41\\x65\\xfc\\x54\\x5c\\x18\\x93\\xc0\\xd1\\xdf\\xea\\x74\\x6a\\xd6\\x91\\xd3\\xec\\x40\\xd3\\xa3\\x40\\x4b\\xb4\\x65\\x77\\x2a\\x43\\x2a\\xcb\\x6e\\x92\\x3d\\xb6\\x1b\\xb0\\x02\\x57\\x3f\\x32\\xa8\\x84\\x9b\\xc3\\xa8\\xd2\\x7d\\x8a\\xee\\xae\\xeb\\x96\\xea\\xbf\\xfd\\xf7\\x6f\\x8b\\x0d\\xbc\\x33\\xde\\x23\\xdf\\xe2\\x6c\\x1f\\x1e\\xfb\\x77\\x34\\x8b\\xe1\\xbc\\x60\\xa4\\x87\\x88\\x3d\\x19\\x0f\\xaa\\xea\\x44\\xc7\\x6d\\x34\\x99\\x6e\\x79\\x89\\xf6\\x9a\\xf5\\x68\\xab\\x3e\\x1d\\x4e\\x6d\\x2d\\xc6\\x0e\\x4d\\x18\\xcc\\x5d\\xab\\xb8\\x9d\\x94\\xe9\\xd5\\x94\\x5a\\x69\\xa0\\xe3\\x31\\xa7\\x12\\x68\\xf4\\xfa\\xf6\\xb9\\xfd\\x7e\\x24\\x4e\\xf9\\x2e\\x8a\\xd4\\x74\\x97\\xec\\x99\\x62\\xbb\\xa7\\x4d\\x2b\\x5d\\x88\\x78\\xba\\xfb\\xa7\\x18\\x74\\x1a\\xef\\x81\\xba\\x4d\\x02\\x68\\x72\\x16\\x2c\\x55\\x83\\xb1\\xd9\\x5e\\x45\\xf8\\x8b\\xd2\\x6f\\x61\\xa6\\x7f\\xd1\\xea\\xe6\\x63\\x42\\x8d\\xbd\\xd2\\xc8\\xdf\\x31\\xc2\\x56\\xe7\\x2a\\xcf\\x9e\\x49\\x97\\xfd\\xe6\\xfd\\x60\\x68\\x09\\x87\\x25\\x15\\x84\\x39\\x6a\\x9a\\x69\\xe3\\x02\\xbe\\x90\\x40\\xe4\\x50\\x46\\x12\\xcb\\xba\\x29\\x48\\x89\\xbb\\xf1\\x1e\\xce\\x57\\x12\\xff\\xe5\\xc3\\x0a\\x63\\x2c\\x87\\x38\\x43\\xed\\x8e\\xcb\\xbd\\xec\\x17\\x3a\\xd6\\x6d\\x64\\x3b\\x3b\\x1c\\x11\\xf3\\xa5\\x10\\x57\\x33\\x50\\x00\\x68\\x4e\\xf9\\x44\\xee\\x10\\xf5\\x8f\\xd0\\xf1\\xf0\\x9e\\x3b\\x1f\\x22\\x48\\xad\\x74\\x89\\x27\\x6f\\xfc\\x8c\\xf2\\x1f\\x08\\xf8\\x59\\x0c\\x58\\x24\\x3e\\x60\\x6d\\xfa\\x24\\x0f\\x30\\x66\\xbe\\x49\\xc2\\x2b\\xa1\\x91\\x5b\\xd5\\xfb\\xc3\\xc9\\x2f\\xc9\\x3e\\x27\\x68\\x54\\xc2\\x69\\xc7\\xdc\\x3a\\x2d\\xda\\x51\\xda\\xfb\\x36\\x2e\\x6e\\xc3\\x5a\\x60\\x0d\\xb3\\xe5\\xdd\\x0f\\x8d\\xe4\\xd3\\xed\\x6c\\x7d\\xf9\\x42\\xc7\\xaf\\x47\\x3c\\x40\\xc1\\xa8\\xb6\\x77\\x31\\x59\\xb0\\x0c\\xb3\\x71\\x19\\x26\\xd5\\xa4\\xce\\xc5\\xa8\\xd2\\x8e\\x97\\xe0\\x61\\x20\\x0b\\x5a\\xfa\\x6f\\xec\\x89\\xe9\\x04\\xbe\\xf7\\x85\\x42\\x0a\\xad\\xb3\\x98\\x20\\x8d\\xc2\\xfa\\xb8\\x7f\\x3c\\x56\\xe5\\x53\\x58\\x5a\\xe0\\x3f\\x58\\xf6\\x45\\xd9\\xb0\\x1a\\xb2\\x97\\x78\\x29\\xc0\\xbc\\x16\\xf4\\x54\\xa6\\xb0\\x99\\xbc\\x07\\x42\\x84\\xa7\\x58\\x1f\\x55\\x41\\x0b\\x29\\x0f\\x91\\xd8\\x81\\x3e\\x18\\x43\\xbf\\x5b\\x54\\x52\\xe0\\x77\\x2f\\xd7\\xc3\\xf3\\xac\\x55\\xc6\\x37\\x89\\x8b\\xdc\\x07\\x33\\xa5\\xe7\\x9c\\xc5\\x93\\xc9\\xe0\\xe0\\x5c\\x27\\x3a\\xed\\xb3\\xe2\\x76\\x20\\xbf\\xb7\\x82\\xdb\\xa3\\x98\\x22\\x08\\x8e\\x29\\x40\\x24\\x35\\xa9\\xba\\x37\\x6f\\x7d\\xde\\x4d\\x12\\xeb\\xf1\\xff\\xe4\\x9a\\x15\\x54\\x88\\xfd\\x07\\xf8\\x76\\x22\\x87\\xdc\\xe4\\x8c\\x5a\\xff\\xcc\\xe0\\xf1\\x2d\\x99\\x5e\\xfa\\xb7\\xb0\\xf9\\x95\\xfb\\xd1\\x2b\\x96\\x13\\xde\\xb4\\x27\\x58\\x69\\x29\\x07\\x1d\\x41\\xf8\\x01\\x52\\xfc\\x80\\xfd\\xae\\x9b\\x72\\x89\\x3f\\x84\\xc6\\xb1\\xe1\\xad\\xd3\\x2d\\x06\\xde\\x4f\\x06\\x7d\\xdf\\xce\\xd9\\xb0\\xa9\\xbb\\x9f\\x68\\x18\\x62\\x7d\\x3d\\xaf\\x98\\x76\\x28\\x88\\x14\\x4c\\xe5\\xdf\\x7b\\xd1\\x64\\xe2\\x94\\x79\\xfa\\x4d\\xbb\\x08\\xa7\\xe9\\x47\\xc3\\x8d\\x14\\x24\\xd5\\x50\\xe7\\xe2\\x5e\\xea\\x0b\\x89\\xc1\\xd5\\x8c\\xf3\\x47\\xaf\\xa7\\x9c\\x54\\x7d\\x64\\x01\\xa0\\xfe\\xec\\x9a\\x68\\x67\\x7d\\xcb\\xe7\\x3e\\xf3\\x5d\\x18\\xe8\\x06\\x65\\xac\\x54\\x81\\x3f\\xa3\\xb0\\xe8\\xe7\\x34\\xb1\\xe4\\x6f\\x3d\\x14\\xa3\\x6b\\x6c\\xcc\\x25\\x9b\\xd6\\xce\\xb3\\x2e\\xf3\\x5a\\x2a\\x23\\xbf\\x16\\xd8\\xf8\\x13\\x9c\\x51\\x9b\\xbd\\xcf\\xe0\\xac\\x1b\\xce\\xc7\\xd6\\x34\\x67\\xc2\\x66\\x21\\x7d\\xea\\x77\\x4a\\x94\\x56\\x50\\xd5\\xd9\\x5e\\x38\\xc3\\x9b\\xfc\\x2d\\x28\\x75\\xc7\\x49\\xc7\\xfd\\xa2\\x39\\xf1\\xe4\\xab\\x01\\x76\\x60\\xf3\\xc3\\x8f\\x97\\xf5\\xb8\\x7e\\xbf\\x48\\x03\\xb5\\xcd\\x42\\x81\\x3a\\x57\\x60\\x6b\\x8d\\x02\\x49\\x86\\xa9\\x5f\\xe2\\xa3\\x4b\\x05\\xb5\\xf1\\xc7\\x7c\\x6a\\xc8\\x5e\\x3e\\x76\\x38\\xea\\xac\\xd1\\x5f\\x79\\x2c\\x63\\x38\\x63\\xb5\\xf3\\x9f\\xe2\\xe5\\x5e\\x08\\x21\\xeb\\x44\\x14\\xaa\\xd3\\x7e\\xb0\\xab\\x16\\xbf\\x3d\\x16\\xb6\\x27\\x58\\xfc\\x8a\\x35\\xc5\\xe4\\xa0\\xc8\\x36\\x34\\x01\\x83\\x71\\x40\\x98\\x19\\x4d\\xb6\\xe3\\xc7\\x4f\\x20\\x90\\x80\\x69\\x4e\\x59\\xc7\\x68\\x6c\\xe1\\x7d\\xbc\\x14\\xa6\\xb6\\xab\\xc1\\xb1\\x6b\\xc2\\xcf\\x12\\x68\\xfa\\xfb\\xcc\\x35\\x21\\x68\\x27\\x05\\xd6\\x57\\xa2\\xea\\x97\\x53\\x0c\\x6e\\xf0\\x74\\xe2\\xb8\\x7b\\x9b\\x05\\xea\\x5e\\x10\\x6a\\xad\\xb6\\xed\\x9a\\x57\\x8c\\x53\\x47\\x0e\\xee\\x9e\\x75\\xf6\\xd1\\x52\\x0a\\x9f\\x73\\xe0\\x67\\x41\\xd1\\x0a\\x2b\\x27\\xc9\\x53\\x67\\xac\\x97\\x29\\x29\\xbf\\x7f\\xeb\\x0d\\x58\\x86\\x6e\\x59\\x15\\x1a\\x09\\x74\\x48\\xcb\\x90\\x88\\x03\\xa2\\x6e\\xd9\\xde\\xd9\\x0c\\xa2\\x12\\xbb\\xdc\\x55\\xa4\\x30\\x26\\x7e\\xd3\\x71\\xa3\\x9b\\xfe\\xa2\\xb9\\x57\\x3f\\x66\\xd3\\x53\\x54\\xbd\\x83\\x5d\\xdc\\x82\\x57\\x99\\xf3\\x5a\\x18\\x75\\x1c\\x4b\\xfb\\xcd\\x8d\\x2e\\x40\\xf9\\x92\\x28\\xb0\\x76\\x75\\xec\\x90\\xa7\\x7c\\x7f\\xae\\x55\\x30\\x95\\xd1\\x7b\\x93\\x32\\xdd\\x7f\\xa2\\x92\\x89\\x87\\xc4\\xc4\\xb9\\xb4\\xdd\\xda\\xf9\\x06\\x6d\\xbb\\xe8\\xdc\\x3d\\x53\\xf9\\x20\\xc2\\x70\\xac\\x2e\\xf3\\x38\\x04\\x98\\x4d\\x1c\\x63\\x23\\x76\\xc7\\xd3\\x87\\xdf\\x28\\xea\\x03\\xee\\x0b\\x84\\x61\\x1c\\xbf\\x68\\x6b\\x6f\\x5e\\x69\\x6f\\x28\\x2e\\xe0\\x1f\\xf8\\xb7\\xd6\\x52\\xe1\\x76\\x05\\xb7\\x1e\\xd6\\x89\\x71\\xd5\\x0b\\xc5\\x70\\x5a\\xe3\\xc8\\x8c\\x52\\x05\\x0e\\xf6\\xd0\\xd0\\x1e\\xd9\\x22\\xe9\\x24\\x06\\x43\\x11\\x58\\x43\\xe7\\x8a\\x1d\\x19\\xa2\\xac\\x9d\\x9e\\xa5\\x85\\x4d\\x55\\x4a\\x88\\x9a\\x94\\x42\\x29\\xe2\\xc2\\x87\\xa0\\x6f\\x39\\x03\\x14\\xb7\\x77\\xda\\x4b\\x98\\x69\\xc3\\x14\\x84\\x7f\\xe9\\xaf\\x5e\\xf1\\x76\\xd2\\x38\\x16\\x23\\xe9\\x5b\\x94\\x89\\x3e\\x24\\x55\\x17\\xfd\\x19\\xea\\xcc\\x40\\xcc\\x85\\xe7\\x09\\xbf\\xef\\xe3\\xbb\\x10\\x2a\\x84\\x27\\xd4\\x00\\xe9\\x70\\x8b\\xd5\\x9c\\xab\\x0a\\x55\\xd9\\x27\\xf5\\x48\\x14\\xff\\xee\\xed\\x30\\x68\\x5b\\xc8\\xa5\\x6f\\xf7\\xb6\\x3f\\xa1\\xae\\x47\\xdf\\xa8\\x67\\xe5\\x74\\x0c\\x30\\x09\\xea\\x64\\x1b\\xa4\\xe0\\xa9\\x80\\xca\\x66\\x64\\x43\\xf0\\xe4\\x21\\xa4\\x23\\x71\\xda\\xa0\\x4b\\xc5\\x7f\\x5f\\x7d\\x95\\x86\\xbe\\x4d\\xcd\\x1d\\xe7\\x20\\x31\\x0a\\xc2\\xd3\\xc8\\x44\\x7e\\x75\\x71\\x03\\x50\\x68\\x8d\\x75\\x07\\x5b\\xa1\\xa0\\x99\\x04\\xe8\\xd1\\x81\\xd7\\xe3\\x72\\x3f\\xff\\xb1\\x7f\\xa5\\x1e\\x0b\\x89\\x8b\\xd9\\xaf\\xc8\\x93\\x89\\x0f\\x6a\\xf7\\x3d\\x33\\x82\\x53\\xdb\\x37\\xe1\\xb8\\xbf\\x95\\x3c\\xe9\\xf2\\x8a\\x5e\\xb0\\x65\\xc7\\xa2\\x32\\x86\\xf3\\xea\\x80\\x20\\xaf\\x7a\\xb1\\xc1\\x4a\\x67\\x09\\x20\\x3f\\xef\\x51\\xa4\\x22\\x89\\x73\\x59\\x73\\xc1\\xf9\\x5b\\xef\\x2f\\x30\\x08\\xb7\\x05\\x0e\\xd8\\x5a\\xed\\x4f\\xe9\\x27\\xd8\\x71\\xd9\\xc8\\xee\\x07\\x63\\x15\\x9e\\xa3\\x45\\xe6\\x1b\\x0f\\x78\\xd0\\x2d\\xd4\\x46\\x82\\xa9\\x27\\x6f\\xcb\\x09\\x48\\x6f\\xf2\\xdd\\xf8\\x07\\x6a\\x9b\\xe6\\x65\\x14\\x77\\xec\\x62\\x0a\\x07\\x22\\xba\\x7b\\xb3\\x9b\\xa4\\xf5\\xa4\\xad\\x07\\x9f\\x83\\x72\\xf3\\x92\\xb7\\xa6\\xd3\\x54\\x59\\x13\\x63\\xbf\\x14\\xcc\\xaa\\x24\\x42\\xae\\xc4\\xb1\\x69\\x81\\x7a\\x8b\\xb5\\xc0\\x70\\x73\\x3c\\x9c\\x71\\xd9\\x42\\x46\\x2c\\xc3\\x89\\x18\\xce\\xf2\\x65\\xe6\\xa7\\x2b\\xe3\\x4c\\x81\\xf4\\x75\\xd1\\xca\\x88\\xdf\\xe8\\x75\\x8b\\x46\\x05\\x1e\\x77\\x1f\\xe8\\x6e\\x71\\xfb\\x8e\\xcb\\xac\\xe2\\x68\\xa8\\xd6\\x3f\\x39\\xe0\\x7e\\x49\\xf0\\xa3\\xe1\\x58\\x2b\\x77\\x23\\xcb\\xd4\\x4d\\x61\\xc5\\xc3\\x4a\\xbe\\x8c\\x68\\x30\\x74\\x75\\xa7\\x49\\x5b\\x58\\x08\\x0f\\xd2\\xc0\\x03\\x95\\xcf\\x40\\xe0\\xbb\\x1f\\x88\\x95\\x07\\xaa\\x2b\\x14\\xd9\\x05\\xc6\\x32\\xfa\\x43\\x6e\\x51\\xf6\\x19\\x70\\x1a\\xc6\\x74\\xb4\\xef\\x56\\x65\\x49\\x25\\x82\\x60\\x6e\\x2d\\xca\\x08\\x3c\\x88\\x8c\\xca\\xc7\\xc6\\x07\\x1d\\x3b\\xd5\\xa3\\xd6\\x9c\\xc3\\xf8\\x2f\\x76\\xb3\\x69\\x6a\\xf5\\x9e\\x91\\x9c\\x9b\\xc8\\x3a\\x91\\xbf\\xcc\\x94\\x56\\x26\\xe0\\x84\\xc6\\xcf\\xf3\\xf7\\xcd\\x7e\\x9f\\x8e\\x7e\\xf0\\x1a\\xfa\\x4c\\xf2\\x70\\xf5\\xdf\\xde\\x1d\\x8e\\xf9\\x5b\\x90\\xf6\\x8a\\x86\\x69\\x51\\xb2\\x9b\\x44\\xe3\\xd1\\x1d\\x0a\\xe4\\x9e\\xef\\x3c\\xf7\\xb6\\x18\\x3d\\x07\\xe6\\x34\\x17\\x1f\\x01\\x83\\x39\\xb6\\x83\\x42\\xe6\\x1e\\x8d\\x42\\x9b\\x42\\x4c\\x3c\\x65\\x0d\\x9c\\x2d\\x58\\x6d\\xed\\xd9\\x44\\x43\\xb5\\xc8\\x9e\\xd2\\xe6\\x92\\xf8\\xb5\\x81\\x2c\\x9c\\xb0\\xa7\\xab\\x7c\\xc3\\x2e\\x9c\\x4e\\xb2\\x82\\x54\\x5f\\xf5\\xcc\\xb8\\x2c\\x52\\x33\\x1c\\x43\\x86\\x62\\x1a\\x4d\\x5d\\xdd\\xa4\\x83\\x04\\x4a\\x7f\\xb4\\xd9\\x6a\\x2e\\xe5\\x41\\x52\\x80\\xa7\\x9f\\x3e\\x52\\x4c\\x38\\xb9\\xc2\\xc4\\xc7\\xff\\x13\\xbc\\x54\\x16\\x7e\\xb4\\x3d\\xb8\\x53\\x81\\x60\\x40\\x7a\\x99\\xd8\\xd3\\xe5\\x3c\\x98\\xfe\\x35\\x99\\x3c\\x8d\\xba\\x7d\\xc9\\x46\\x6d\\x15\\xcf\\xcf\\x34\\x25\\x53\\x49\\x83\\x4c\\x21\\x69\\xf8\\x94\\x69\\x8e\\x73\\x84\\x89\\x7e\\x4b\\x0d\\xb3\\x71\\xb2\\xbf\\x3b\\xe1\\x7a\\x8e\\x47\\x1c\\x7b\\xdc\\x01\\x98\\xbe\\xae\\xb2\\x9b\\x11\\x18\\x87\\x15\\x84\\x9b\\x13\\x44\\x8e\\xf2\\xbf\\xaa\\xbc\\x16\\x28\\x87\\x4e\\x1d\\x06\\xae\\x83\\x38\\xbf\\x9d\\x3c\\xff\\xfc\\x6d\\x27\\x71\\xce\\x1a\\xcb\\x28\\x8d\\xbe\\x7b\\xa2\\xd3\\x7d\\x76\\x03\\x29\\xcd\\x54\\x53\\x1f\\x6f\\x18\\xb7\\x29\\xa0\\x3e\\x6f\\x9c\\x2f\\xaf\\x5d\\xd1\\x2a\\x06\\xff\\x0c\\x43\\x6e\\x97\\xd0\\xda\\x50\\x2b\\xe5\\x9d\\xcc\\xf7\\xb2\\x0f\\xc9\\xdf\\x57\\xd7\\x14\\x6d\\x0f\\x87\\x68\\x0f\\x7d\\x61\\xcb\\xe3\\x7c\\xf4\\xed\\xac\\xa8\\xec\\xe9\\xaa\\x64\\x82\\x78\\x3e\\xb9\\xfd\\x85\\xb1\\x18\\x9c\\x51\\x2c\\xdb\\x87\\xe9\\x36\\x5b\\xab\\xa0\\x32\\x86\\x0c\\x88\\x49\\x96\\xc8\\x74\\xa5\\xd8\\x25\\x12\\xf6\\x42\\x9c\\xdb\\x0b\\x54\\x28\\x10\\xa3\\xc0\\xb4\\x60\\xf5\\x03\\x0a\\xd4\\x07\\x1b\\xc1\\xfb\\x53\\xf6\\x9b\\x64\\xdf\\x33\\xb8\\xc7\\x9e\\x34\\xf6\\x95\\xce\\x66\\xde\\xc9\\x78\\x28\\x72\\x5e\\x29\\x41\\xdc\\xea\\xad\\x03\\xae\\xff\\xa7\\xff\\x4f\\x7f\\x9d\\xdf\\x8e\\x1b\\x0a\\xac\\xac\\xb0\\x11\\x8f\\x98\\x56\\x11\\xbd\\xe2\\x59\\x10\\x8d\\xa6\\xde\\xc2\\x0c\\x60\\x50\\x36\\xe8\\x26\\xb3\\x44\\x2b\\xd3\\x3a\\x07\\x43\\x51\\xb5\\x44\\xbf\\xab\\x16\\x78\\xed\\x9d\\xb2\\x9c\\xfb\\xa6\\x84\\xf5\\x1b\\xa9\\xb9\\x40\\xc7\\x35\\xe9\\x11\\x6e\\x49\\xc7\\x99\\x5a\\xd8\\xd9\\x4d\\x1a\\xf8\\xf2\\xd8\\x10\\xd7\\x76\\xbf\\xa3\\x96\\x82\\xc7\\x80\\x18\\x02\\x49\\x8a\\x98\\x4d\\x89\\xa9\\x53\\x6a\\xb3\\x71\\x59\\xd6\\x0c\\xd9\\x36\\x02\\xb8\\x56\\x02\\xb8\\x36\\x02\\x58\\x7f\\xe3\\xb2\\x58\\x07\\xe9\\x41\\x07\\x99\\xeb\\x75\\xcb\\xb7\\x3b\\xd2\\xc2\\xd1\\x72\\x15\\xf8\\xc4\\xf7\\xd6\\xf3\\x5a\\x93\\x79\\xe7\\x0d\\x65\\xba\\x91\\xe8\\x05\\x13\\x4e\\xdb\\xfd\\xd8\\xf4\\xcc\\x6c\\x2f\\xe4\\x49\\x96\\xbb\\x88\\x79\\x93\\x3f\\x76\\x91\\xf7\\x46\\xe3\\xcf\\x1c\\xab\\x9f\\xba\\xf4\\x70\\x43\\x16\\xa5\\x7f\\x63\\x99\\x29\\x77\\xf3\\x9d\\xd9\\xee\\xdc\\xf1\\x67\\x41\\xb9\\xb0\\x57\\xac\\xfc\\xf2\\x60\\x53\\x67\\xae\\xe9\\x46\\xfc\\x9d\\x40\\x78\\xad\\xe3\\xb3\\x67\\xe5\\xb4\\x90\\xd8\\x81\\xdc\\xef\\x58\\x69\\x85\\xbf\\xe6\\x1f\\x8a\\x4b\\xd5\\x84\\x03\\x55\\x0c\\x3f\\x5e\\x30\\xa8\\x9e\\x73\\x18\\x50\\xf2\\x4f\\x3f\\xac\\xf6\\x8f\\x4d\\x6c\\xda\\xdf\\xf1\\x95\\xcb\\x96\\x01\\x5b\\x0f\\x06\\xf9\\x65\\x9b\\x1c\\xf4\\xcb\\x76\\xa1\\x77\\x66\\xab\\x17\\xe5\\xcd\\x75\\x91\\xe6\\xc2\\xf6\\xee\\x5d\\x5f\\x23\\x73\\xae\\xd0\\xfe\\x88\\xf4\\x5a\\x88\\x3a\\xe7\\xec\\x58\\x1b\\xea\\xf6\\x97\\x25\\x00\\x19\\x66\\xa7\\x1b\\x94\\xd9\\x98\\x31\\x3a\\xeb\\x0a\\xda\\xc8\\xd4\\xbd\\xae\\x62\\xc4\\x45\\x0b\\x25\\x70\\x5c\\x1f\\x80\\x81\\xe0\\x41\\x5d\\x44\\xbf\\x0e\\xd0\\xb8\\x7e\\x48\\x09\\x23\\x29\\x26\\x7d\\xb7\\x38\\xd5\\x3a\\x77\\xcf\\x5a\\xbb\\x69\\x5f\\x8e\\x0c\\x9a\\xe9\\x16\\x8c\\xd1\\x50\\xaf\\x02\\xca\\xad\\x55\\xe1\\x18\\x55\\x5a\\xb2\\x4f\\x23\\xa0\\xdd\\x3d\\x09\\x55\\x02\\xd6\\xf4\\xa3\\x00\\x5b\\x3e\\xc9\\xd1\\xcd\\x99\\xe3\\x97\\x22\\xc5\\x94\\x22\\xe1\\x00\\xcf\\xed\\x46\\xf8\\x73\\xc8\\x05\\xa1\\x1b\\x84\\xe2\\x12\\x45\\x83\\x9a\\x59\\xe3\\xcf\\x18\\x4d\\xb1\\x7b\\x46\\x86\\x55\\x40\\xef\\x29\\x8f\\x78\\x75\\x38\\xa6\\xc6\\xea\\x5f\\x47\\xe4\\x77\\xfa\\x2b\\xa5\\xb6\\xf1\\xf4\\xf1\\xb9\\x47\\x6e\\x15\\xdb\\x17\\x37\\x65\\x59\\xa6\\x4a\\xc5\\x01\\x01\\x9e\\x5e\\x64\\xbe\\x79\\x4f\\x70\\xe3\\x1f\\x0a\\x30\\xb9\\xc6\\xc1\\xf2\\x5f\\xcc\\xe1\\x8f\\x0f\\x93\\x48\\x36\\xfe\\xd9\\xae\\x63\\xb3\\xc0\\x4e\\x14\\x49\\x14\\x7d\\xad\\xf8\\xed\\x0f\\xdd\\x0b\\x32\\x53\\xea\\xdc\\x1a\\xa7\\xb6\\xef\\x7b\\x96\\xcc\\x96\\x14\\xf9\\x6f\\x55\\x77\\x6d\\x49\\xeb\\x96\\x8d\\xcb\\x9f\\xc8\\x8d\\xed\\xfe\\x23\\x50\\x85\\x2d\\xf3\\x34\\xb2\\xe9\\x08\\x7d\\x55\\x25\\x28\\xee\\xb7\\x26\\x78\\xfa\\xf0\\x50\\xb1\\x66\\xdb\\xe9\\xf9\\x18\\xef\\x05\\x27\\x3f\\x94\\xe7\\x0f\\x5b\\xf9\\x79\\xdb\\x8d\\x87\\x05\\x6c\\xf7\\x49\\x81\\x0d\\x4e\\xb3\\x5e\\x1d\\xe0\\x65\\xe5\\x4b\\xc2\\x70\\x3f\\x41\\xad\\xcf\\x35\\x22\\xe2\\x0e\\x9e\\x60\\xa1\\x44\\x82\\xdb\\xe7\\x08\\x53\\x42\\xb5\\x01\\xe0\\xb1\\x66\\xe3\\xb1\\xa6\\xe3\\x07\\x90\\x05\\x54\\x80\\xfd\\x4b\\x6d\\xba\\x3b\\x63\\x99\\x19\\xeb\\xfd\\xab\\x4a\\x9d\\xbb\\x44\\xf1\\x80\\xd8\\x0d\\x47\\x71\\xf7\\xa1\\x7b\\xd0\\xa4\\xdd\\x40\\x59\\xa9\\xfd\\x51\\x5c\\xc7\\x6f\\x4a\\xd0\\x09\\xc1\\x17\\x2b\\x46\\x89\\x83\\xa7\\x1c\\x8e\\x49\\xb8\\x3a\\xe0\\x18\\x1c\\x1d\\x53\\x5f\\x4b\\x1d\\x4d\\x75\\xb5\\x25\\x58\\x8f\\xe3\\xb8\\x0e\\xcb\\xef\\xf1\\x62\\xdb\\xe9\\x0f\\x10\\x12\\x23\\x56\\x85\\x20\\x14\\x5d\\xe8\\x4a\\x7c\\xa0\\x12\\x1b\\xca\\xbe\\xe8\\xf8\\x21\\x29\\x6a\\xe7\\x58\\xb0\\xba\\x50\\xd2\\xa7\\x5f\\x40\\xe7\\x30\\x24\\x4f\\x31\\x96\\xd1\\xd8\\x19\\x2a\\x6d\\xb9\\x83\\x09\\x53\\xd6\\xfc\\xe5\\x1c\\x5b\\x6c\\xd5\\x9e\\x84\\x2a\\xac\\x91\\x6f\\x9e\\x77\\x71\\x16\\x73\\xdb\\x8b\\xe4\\x2e\\x74\\xed\\xf5\\x83\\x3f\\xb1\\x65\\xd0\\x06\\x9f\\xc3\\x4e\\x2d\\xeb\\x89\\x42\\x18\\xaf\\x0a\\x5e\\xe1\\x82\\x26\\x6d\\x92\\xa4\\x8b\\xd9\\x64\\x1b\\x48\\x60\\xfc\\x86\\x50\\x85\\xee\\x44\\x7f\\x27\\xb2\\xc1\\x24\\x0d\\x88\\x7c\\x03\\xab\\x30\\xc4\\x60\\x52\\x0d\\xe5\\x96\\xfc\\xe1\\x2f\\x20\\xf3\\xfd\\x32\\x10\\xd7\\xf4\\xb9\\x38\\x75\\x3a\\x4b\\x4f\\xe4\\x76\\x21\\x4d\\xfb\\xdf\\xb6\\x00\\xc2\\x20\\x38\\xa1\\x6b\\x4c\\xe9\\x66\\x7c\\xe8\\xfe\\xb7\\x1e\\x5f\\x27\\x44\\x67\\xb5\\x75\\x5d\\x07\\xab\\x03\\x81\\x2b\\x3c\\x2d\\xa3\\xe6\\xdd\\x57\\xab\\x9b\\x09\\x56\\x5e\\x86\\x4d\\x5c\\x11\\x69\\xef\\x99\\x5b\\xe5\\x64\\xed\\x1d\\x5e\\x4f\\x61\\xea\\x34\\xf7\\x57\\xb9\\x7a\\x4b\\xe4\\xa2\\x73\\x8d\\x25\\x67\\x05\\x37\\xca\\xc1\\xe9\\x64\\x43\\xbb\\x79\\x02\\x52\\x1c\\x3b\\xdb\\xcd\\x8a\\xd2\\xdc\\xe4\\xa2\\x45\\x61\\x04\\x59\\xe2\\x88\\x79\\xeb\\x07\\x6a\\xb2\\x56\\x53\\xc5\\xda\\x7d\\x10\\xfa\\xd5\\xb3\\x68\\xd9\\x52\\x87\\x53\\x50\\x56\\x68\\xfd\\x9b\\xda\\xf2\\xd4\\xe5\\xd1\\x19\\x6b\\x0c\\xd8\\xcd\\xa4\\x75\\x53\\xa5\\x2d\\x36\\x38\\x65\\xec\\x3c\\x00\\xe6\\x95\\x8d\\x12\\xd4\\x4a\\x5c\\xdb\\x64\\x01\\x6f\\xc2\\xf3\\x33\\x1d\\xcf\\x6a\\xbd\\xb6\\xa7\\x35\\x1a\\xf0\\x2e\\x64\\x9d\\xe4\\x87\\x04\\x6d\\xb6\\x4f\\x42\\x14\\x60\\x06\\xae\\x18\\x55\\x1a\\x3e\\x30\\xe3\\x7c\\x75\\x7d\\xf9\\xba\\xae\\x6b\\x31\\x7e\\xbf\\x6b\\xb2\\xa7\\x14\\xa6\\x72\\x40\\xd0\\x05\\x67\\x1f\\xd5\\x1b\\x34\\x29\\x38\\x19\\xd7\\xb5\\x31\\xc3\\xf7\\xa3\\x33\\xbf\\xe1\\x04\\x08\\x18\\x73\\x63\\x8a\\xd7\\xc3\\x9a\\xfc\\xa5\\x47\\xaa\\x6d\\x70\\x56\\x23\\x63\\x53\\xc2\\x38\\x79\\x16\\xdc\\xf3\\xb4\\x54\\x21\\xf4\\xf7\\x6d\\xae\\xf9\\x65\\x20\\x13\\x7f\\x20\\xe8\\xc9\\x36\\xb6\\xc2\\x47\\xc0\\xd4\\xbb\\xbc\\x85\\x6b\\x73\\x9c\\x17\\x2b\\x77\\xd3\\x16\\x70\\x75\\xce\\x4e\\x16\\x9a\\xee\\x00\\xe8\\xfb\\x64\\x71\\x22\\xe5\\x77\\x97\\x6b\\x89\\x94\\x30\\x70\\xd1\\xa9\\x69\\x8d\\xaf\\x14\\xf8\\xe1\\x7a\\xc0\\xf8\\x1e\\x7d\\xe9\\x0e\\x00\\xa9\\xad\\x05\\x6f\\xd5\\x10\\xff\\xa0\\xa7\\xcb\\xca\\x3c\\x0d\\x54\\x56\\x69\\x7d\\xe8\\xef\\x04\\xb5\\xef\\x7d\\xa9\\xa5\\x36\\xf8\\x36\\xb0\\xa9\\xfe\\x69\\xd1\\x34\\x94\\xb9\\x18\\x73\\xcd\\xd1\\x72\\x4c\\x45\\x70\\x4a\\x4f\\x04\\x7b\\x41\\x35\\x3c\\xdc\\x09\\x94\\xdc\\x16\\xc0\\xe6\\x55\\xd9\\x81\\xd7\\x1f\\x0a\\x14\\xd8\\x0b\\x9c\\x53\\x6a\\x17\\x90\\x03\\xb4\\x54\\xbc\\x7e\\xd4\\xba\\xe4\\xae\\xe9\\x46\\xbb\\x93\\x75\\x24\\x1e\\xdd\\x06\\x84\\x2c\\x00\\xa8\\xe5\\x04\\xad\\x09\\xc4\\xfb\\xfe\\x15\\x8b\\x68\\xbc\\x04\\x91\\x19\\x89\\xd1\\x52\\x11\\xe7\\x39\\x7a\\xaa\\xb3\\xb7\\x15\\xa2\\x78\\x0a\\x14\\xa3\\x25\\x17\\x27\\xfa\\xf3\\x0f\\x00\\xd4\\x9b\\x04\\x46\\x16\\xb4\\x88\\xe3\\x03\\xfd\\x99\\x13\\x89\\x63\\xf4\\x8f\\x44\\xf1\\xa5\\xcf\\xba\\xd1\\x4f\\x69\\x64\\x7e\\xd3\\xfd\\x25\\x70\\x5a\\x55\\x05\\xd8\\x78\\x98\\x6a\\x7a\\x18\\xe0\\x8f\\x8d\\x91\\x2c\\x70\\x93\\xa9\\x6d\\xa3\\x11\\x89\\x46\\x13\\xed\\x9c\\x7f\\x02\\xfb\\xb6\\x12\\x4b\\x1a\\x85\\x3a\\xb3\\x5b\\xe8\\xf4\\xe2\\xca\\x31\\x7e\\x6a\\xfd\\x64\\x48\\x7a\\xfe\\x46\\xd2\\x2b\\x5a\\x26\\xe1\\x8d\\x6d\\xc8\\xf7\\x77\\x16\\x59\\x15\\xa5\\x7e\\x8d\\xa1\\x6e\\x17\\x21\\x75\\x22\\x99\\x88\\x38\\xfd\\xf9\\xd1\\x05\\x5e\\x41\\x28\\x14\\x15\\x12\\xb6\\x4f\\x59\\x5f\\x0f\\x26\\xd6\\xb3\\x54\\xd3\\x27\\xfa\\x2b\\x4e\\x2c\\xc9\\x6d\\xe4\\x57\\x9c\\x43\\x8e\\xa2\\x36\\x26\\x2e\\x59\\xd4\\xce\\x91\\x4e\\x0c\\xc9\\x25\\x78\\x17\\x4c\\x01\\xb9\\x19\\x5d\\x88\\xfa\\xb3\\xc0\\xa2\\x94\\x44\\x4f\\x75\\xa6\\xce\\x63\\x94\\x3a\\x60\\x6a\\x99\\x21\\x26\\x12\\xda\\x6b\\xcf\\xd7\\xf8\\x12\\xea\\xc5\\x9a\\x92\\xa0\\x48\\xcd\\x6f\\xc4\\x2e\\xf6\\x66\\x17\\xe3\\x59\\xb9\\xd3\\xef\\x67\\x7a\\x2b\\x1d\\x24\\x31\\xcb\\x88\\x1f\\x68\\x93\\x34\\x80\\xfe\\x40\\x63\\x1a\\xb7\\xf0\\x44\\x4c\\x3e\\x47\\x79\\xb0\\xb2\\x3b\\x77\\x61\\xf3\\x15\\x50\\x02\\xe9\\x14\\x1c\\x7a\\xbb\\xd1\\xa5\\x45\\x67\\x96\\x5d\\xbd\\x40\\x65\\xb8\\x58\\x5b\\x2a\\x4d\\x71\\x29\\x0f\\x23\\x82\\x24\\xb2\\xd9\\xb3\\x69\\x21\\x1f\\x8f\\x9c\\x53\\xef\\x1f\\xa0\\xc7\\xbc\\x79\\x97\\x99\\x59\\x3a\\x22\\x32\\xdd\\xd1\\x9f\\x26\\xaa\\xc6\\xff\\x47\\xd2\\x59\\x2b\\x49\\xaf\\x43\\x41\\xf8\\x81\\x1c\\xc8\\x0c\\xe1\\x18\\x66\\xcc\\xcc\\x99\\x99\\x99\\xfd\\xf4\\xb7\\xf6\\xbf\\xd1\\xd6\\x26\\x2e\\x59\\x6a\\x9d\\xfe\\x5a\\x75\\xc6\\x1a\\x6c\\x09\\xce\\x0b\\x53\\x3c\\xd1\\x91\\x3b\\x47\\xa3\\xbe\\x8c\\x57\\x8e\\x60\\xfc\\x2c\\xa9\\xb9\\xbc\\x53\\x4b\\xf9\\x5a\\x8e\\xf9\\x60\\x52\\x06\\x5e\\x03\\x2b\\x0f\\x4c\\x65\\x0f\\x10\\x51\\x3b\\xfa\\x68\\xea\\xc5\\x1a\\xe3\\x42\\xee\\x2b\\x8e\\x27\\xfa\\xef\\xcd\\xb7\\xd2\\xf8\\x11\\xc4\\x43\\x32\\x94\\xaa\\xac\\x2b\\x85\\x0c\\xd7\\x64\\xc9\\x53\\x4d\\xf5\\xb8\\xf0\\xf8\\x7d\\xec\\xa5\\x08\\x0a\\xa2\\x4d\\x24\\x18\\x07\\xde\\xd5\\x7a\\x45\\x61\\x8f\\x6b\\xe0\\x0c\\x2a\\x8d\\xd1\\xdd\\x31\\x70\\x88\\xdf\\x2f\\x4d\\x53\\x14\\x75\\x11\\x19\\x94\\x17\\xe6\\x91\\x29\\x13\\x23\\x4c\\x50\\xad\\x21\\x07\\x83\\xa4\\xfa\\x00\\xe2\\x2d\\xd0\\xc5\\xdc\\xf7\\xfd\\x00\\xd9\\x53\\x85\\x75\\x9c\\x07\\xf2\\x7f\\x13\\xf5\\x83\\x57\\xd1\\x5d\\x90\\xcf\\x3e\\x84\\xed\\xa5\\x8e\\xf7\\x28\\x23\\xfa\\x18\\x1f\\xa1\\xc8\\xdb\\xb5\\x80\\x15\\xe6\\x77\\x13\\xdc\\xf9\\xb5\\x77\\x7d\\xd2\\x45\\x73\\x78\\xa7\\x3e\\xa3\\x1a\\x4e\\xf1\\xc8\\xdc\\xa0\\xca\\x9d\\x1e\\x91\\xca\\x8f\\x04\\x9e\\xe4\\x47\\xe2\\xce\\xf4\\x50\\xe9\\xed\\x0d\\x4b\\xf9\\x76\\x9c\\xfd\\xc3\\x21\\x4a\\x9f\\xf4\\x49\\x22\\xda\\x42\\xf5\\xcb\\x2d\\xa6\\x0d\\x19\\xe8\\x7a\\x8e\\xe6\\x9e\\xe7\\x45\\xcd\\x48\\xeb\\xe4\\xce\\x34\\x04\\xf2\\xc1\\x78\\x29\\x9c\\x2c\\x56\\xe7\\xaf\\x34\\xfc\\x81\\x01\\xb5\\x3c\\x5b\\xc4\\x73\\xc9\\xc4\\x8b\\xf0\\xd3\\x39\\xce\\xec\\x73\\x0b\\x12\\x2c\\xe8\\x3b\\x29\\x1c\\xbc\\xab\\x36\\x6d\\x9b\\x03\\x4c\\xe6\\xc6\\xee\\x0f\\x3b\\x79\\x46\\x73\\xa5\\xa9\\xf5\\xc8\\x40\\x04\\xdf\\x47\\x85\\x21\\xbe\\x4c\\x11\\xfa\\xa1\\x0f\\xe7\\x62\\xcd\\x80\\x9d\\x18\\x37\\xe8\\xd3\\x78\\xa5\\xbb\\x7f\\x95\\x59\\x67\\x2b\\x4d\\x4e\\x82\\x7e\\x4e\\x82\\x9e\\x20\\x10\\x80\\xcd\\xce\\xec\\xbd\\x1a\\x95\\xd8\\xb8\\xc6\\x9e\\xe5\\x81\\xfa\\x26\\x11\\x07\\xff\\xee\\xf9\\x42\\xfc\\x38\\x14\\x71\\x7a\\x88\\xe0\\xe2\\xe5\\x63\\x5e\\xd9\\xc3\\x75\\xfb\\xd9\\x48\\x21\\xc1\\xb8\\xc0\\xb3\\x4c\\x0c\\x9d\\xbf\\xd4\\x9d\\x3b\\xac\\x30\\x38\\x82\\x84\\xc9\\x55\\x80\\xdc\\x4a\\xad\\xab\\x8a\\x50\\x10\\xd5\\xa9\\x75\\xb7\\xcb\\x0c\\xf0\\x63\\x2c\\x61\\x64\\xbf\\x63\\x9d\\x7f\\x98\\xf9\\x76\\x1c\\xfb\\xd6\\x8a\\xf8\\xc7\\x66\\x81\\x22\\x39\\x6e\\x74\\xa0\\x66\\xb0\\xb8\\xdf\\x89\\x94\\x69\\xe1\\xb6\\x04\\xc9\\x57\\x2f\\x66\\xf5\\xc3\\xf0\\x86\\x99\\x78\\x7b\\xb3\\x23\\x34\\xce\\x81\\x3f\\xc5\\x94\\x8f\\x5b\\xb4\\xab\\x95\\x00\\x3d\\xd7\\x77\\x46\\x29\\x69\\xa5\\xbf\\x7f\\x7e\\xf4\\xc7\\x51\\xbd\\x49\\x9c\\x55\\x4e\\x43\\x34\\x7d\\xf9\\x19\\x49\\x5a\\xc4\\x4a\\xed\\x10\\xf6\\x96\\x68\\xeb\\xaf\\xfa\\x08\\x1e\\x27\\x51\\x5d\\xfc\\xc4\\x88\\x52\\xa5\\xa4\\x14\\x2a\\x9d\\x6d\\x97\\x28\\x6a\\x7d\\xdf\\xa6\\xed\\x5f\\xfb\\x37\\x34\\x0e\\x9a\\x7e\\x54\\x58\\xb7\\x73\\xb1\\x61\\x16\\xa4\\xd8\\xc1\\xd0\\xc6\\xdb\\xac\\x8d\\x2e\\x9a\\x9a\\x0b\\x19\\xcf\\xc5\\xb6\\x7a\\x4a\\x9e\\x67\\x05\\x04\\xf7\\x3d\\x82\\x2f\\x4f\\x3f\\xcc\\x7f\\x93\\x87\\x00\\x70\\xbf\\x77\\xa8\\xf6\\x17\\xf4\\xd8\\x52\\xd3\\x2c\\xf2\\xf0\\xc6\\x3b\\xf1\\x52\\x14\\x66\\x54\\x95\\xac\\x9d\\x9c\\x8b\\x33\\x57\\x56\\x02\\x53\\xfc\\x9a\\x78\\x83\\x5f\\x71\\x5e\\x96\\x41\\xf8\\x10\\xda\\xd8\\x50\\x87\\x6b\\x4f\\x70\\x01\\x0a\\xb0\\xe5\\xd2\\x40\\x5d\\xdb\\xb6\\x9d\\x25\\x94\\xc6\\x18\\x2a\\xc2\\x1a\\xb2\\x87\\x3e\\x53\\x2c\\xbd\\x73\\x84\\xbe\\xf3\\xea\\x8f\\x61\\xa2\\x87\\x29\\xb6\\x2b\\xb1\\x63\\x98\\xed\\xbf\\xc4\\x56\\x77\\xdb\\x66\\x31\\x0f\\xf8\\xb6\\x37\\x4a\\x02\\xc6\\x4d\\xee\\xfd\\x4c\\x80\\x0b\\x18\\xf4\\xdd\\x1f\\x42\\xa8\\xde\\x01\\x69\\x90\\xd4\\xc4\\x5a\\x00\\x4a\\x8c\\x62\\x86\\xd0\\xcc\\x09\\x5c\\x16\\x9e\\x34\\xcb\\xf6\\x63\\xdf\\x1e\\x12\\x0a\\xcc\\x85\\x0a\\xfa\\xdd\\xa5\\x21\\x9c\\xa2\\xc8\\x3b\\x3d\\x1e\\x22\\x57\\xcf\\xcd\\x92\\xdc\\xa3\\xf2\\xbe\\x37\\x74\\xdb\\x01\\x86\\x61\\xbd\\x18\\x05\\xdf\\xfa\\x6f\\x8f\\x91\\xcb\\xba\\xe4\\x0c\\x01\\x15\\x8c\\xf9\\x6b\\x3d\\x63\\xe3\\x64\\xf1\\xe8\\x58\\x48\\x2c\\xd4\\x36\\xa7\\x6a\\xaf\\x54\\x7d\\x08\\xc9\\x06\\xbf\\x8d\\x50\\x93\\x0e\\xb0\\x13\\x38\\x3e\\x73\\xaf\\x55\\xad\\x4a\\x9f\\x80\\x95\\x04\\x3f\\x59\\x0f\\xa4\\xa1\\xb0\\x9f\\x10\\x4e\\x2b\\xb6\\x70\\x32\\x75\\xcc\\x5b\\x56\\xe7\\x5d\\xc3\\x26\\x41\\x7d\\x23\\x6e\\xbd\\x42\\xaa\\x69\\xb1\\x9c\\x90\\x28\\xb9\\xfa\\x43\\x56\\xf9\\x54\\xab\\x95\\xa3\\xb0\\xeb\\x1c\\x5f\\xf9\\xdb\\xa7\\x70\\xc6\\x0b\\x5a\\xc6\\xfc\\xb4\\x9f\\xb5\\x05\\xea\\x5c\\xa1\\xa5\\x3b\\x0d\\x2e\\xbd\\xee\\xa8\\x4a\\xb5\\x67\\x08\\x18\\x12\\x18\\x4c\\xc1\\x98\\xc7\\x8e\\x7f\\x04\\x1a\\xd2\\xf2\\xf0\\x00\\xca\\xff\\xf3\\xf7\\xfc\\x41\\xa3\\xff\\x70\\x38\\x41\\x9f\\xfa\\x79\\x00\\x0c\\x4d\\x48\\x88\\xd2\\x37\\x72\\x93\\xf7\\xc4\\x14\\xae\\xcc\\x10\\xbf\\x2d\\x3d\\x5e\\x10\\x96\\xea\\x78\\xc6\\x4d\\xc1\\x43\\xa5\\xe1\\x6b\\xaa\\xcc\\x4a\\x90\\x44\\x6e\\x60\\x45\\xfc\\x16\\xc9\\xba\\x52\\xfd\\x80\\x9d\\x37\\x71\\x84\\x3d\\xa1\\x05\\x60\\x87\\x49\\x24\\x1d\\xb1\\xf5\\xd1\\xa1\\x3c\\x3b\\xef\\xce\\xa8\\xa9\\x7c\\xc3\\x56\\xb9\\x85\\x70\\x92\\xa2\\x28\\x6c\\x9c\\xe7\\xfd\\xbc\\xab\\x5b\\xdb\\x7f\\x9e\\xef\\xc0\\x61\\x16\\x74\\x5f\\xb6\\x2a\\xfe\\xef\\x17\\xb1\\x27\\x38\\xd1\\x83\\x74\\x43\\x35\\x43\\xe4\\xa7\\x01\\xb9\\x1c\\x34\\xd5\\xa9\\x02\\xd9\\xe7\\xf9\\x82\\x5b\\x82\\x47\\xf2\\xd4\\x2b\\x4d\\x1e\\x82\\x6e\\xe8\\x04\\x7b\\x7b\\x32\\x68\\xb9\\x24\\xef\\x8b\\xdf\\x76\\x26\\x9e\\xa0\\x6d\\x88\\x14\\xa2\\x73\\xcd\\xd0\\xf5\\x87\\xa4\\xcb\\xf9\\x1b\\x2c\\x74\\x80\\xdf\\x44\\xcc\\x40\\x1a\\xec\\xba\\x10\\x55\\xee\\x0f\\xad\\x9e\\xcc\\x96\\x19\\x22\\x5b\\xe1\\x9b\\x23\\x9f\\x18\\xf5\\x34\\xee\\x33\\x87\\xab\\xf9\\xa5\\xc1\\x5d\\x86\\xd8\\x4a\\x60\\x37\\x43\\x77\\xf2\\xb7\\xd7\\xaf\\xc8\\xe6\\x3e\\x76\\xb0\\xf6\\xcd\\xbf\\x3e\\xd7\\x94\\x5a\\x09\\x62\\x06\\x19\\xc8\\x4d\\x4d\\x51\\x3a\\x8f\\x9b\\x42\\x88\\x3e\\x32\\xa0\\x82\\xfe\\xca\\xbc\\xe4\\x10\\xae\\xcc\\x42\\x40\\xba\\xa3\\x44\\x4e\\x1f\\x62\\x1b\\xbe\\x33\\xdc\\x9c\\x3d\\x33\\x39\\xf3\\xbb\\x77\\x8a\\xea\\x6b\\x8d\\xa0\\x03\\x23\\xc5\\x77\\x5a\\x92\\xc2\\xd9\\x0e\\x3b\\xeb\\xb6\\xed\\x49\\x0a\\x1d\\xb6\\x9b\\x1b\\x5d\\xfa\\xf4\\x6d\\x9d\\x58\\x50\\x10\\xe3\\x18\\xec\\xe6\\x4e\\x38\\xdc\\x97\\x2b\\x66\\xfe\\x86\\xa6\\x0c\\xf9\\x14\\xa1\\x51\\x5c\\xef\\x17\\x80\\xf3\\x5d\\x89\\x0d\\xb8\\x64\\xe8\\x44\\x16\\x3d\\x86\\xf0\\xae\\x3e\\x27\\xc5\\x10\\xc9\\x06\\x0e\\xcc\\x6a\\xbe\\x9c\\x01\\xe1\\x12\\x9c\\x41\\x85\\x09\\xf1\\xae\\xbd\\x61\\xcc\\xe9\\xc2\\xce\\x6f\\x15\\x43\\x33\\x44\\xde\\x17\\xa3\\x28\\xf3\\x04\\xd0\\x9e\\x31\\x26\\x38\\xe3\\x55\\xda\\xc7\\xbb\\x24\\xe5\\x8e\\xf2\\x79\\xe5\\x6a\\x39\\x99\\xd8\\x50\\x50\\x9c\\x79\\x8e\\x6d\\x94\\x10\\x14\\x2f\\xb2\\xa7\\xc1\\xce\\x10\\x34\\x4d\\xa0\\x18\\x46\\xe0\\x77\\x06\\x45\\xfb\\xce\\xc0\\x89\\x75\\xff\\xca\\x9c\\x21\\x48\\x88\\xa4\\xcf\\xf3\\x7d\\x61\\x18\\xfb\\xd5\\x9e\\x51\\x9b\\x25\\xa8\\x5b\\x0b\\x36\\xf9\\xea\\xa2\\x99\\xda\\xac\\xc6\\x77\\x12\\x78\\x96\\xb6\\xf3\\x60\\x3c\\x73\\x20\\x76\\x32\\xba\\x07\\xdf\\xe6\\x4e\\x94\\x81\\x05\\xa3\\xf1\\xa3\\x08\\x9b\\x3e\\x00\\xf4\\x82\\xf2\\xba\\x5f\\x49\\xfb\\xd2\\x85\\x69\\xb6\\xc1\\x80\\x82\\x1d\\x55\\x71\\x66\\x0d\\xf6\\x1f\\x8f\\x20\\x69\\xc0\\x1c\\xeb\\x4a\\xbd\\x0f\\xd3\\xef\\x67\\xe8\\xe6\\x27\\xb6\\xa1\\x18\\xf6\\x7b\\x5e\\xf4\\x15\\xc4\\x7a\\x21\\x9f\\xed\\x54\\x6a\\xe8\\x66\\x24\\x50\\xfb\\x00\\x5e\\xbf\\x00\\x00\\x9c\\x4a\\xd7\\x93\\x61\\x30\\x06\\xcf\\x32\\x55\\x68\\x7c\\x35\\xdd\\x21\\xea\\xa0\\xa6\\xf2\\x28\\x21\\xfe\\x53\\x59\\x7a\\x6c\\xbc\\x53\\x76\\x53\\x18\\xf5\\xb6\\xbb\\xd8\\xde\\x37\\x81\\x5b\\xf4\\x39\\x8f\\x27\\xc5\\x48\\xa4\\xd1\\x56\\xe5\\x71\\x5c\\xa0\\x5c\\x3e\\xc2\\xef\\x7b\\x5d\\xbf\\x3f\\x6f\\xa2\\x0b\\xda\\x04\\x3d\\x92\\x7a\\x8f\\x49\\xde\\x63\\x77\\x9f\\x75\\x84\\xec\\xb1\\xdc\\x30\\xe5\\xd8\\x39\\x8a\\x46\\xaa\\x9a\\x74\\x57\\x8e\\xc4\\x0d\\x7c\\xe7\\x48\\x51\\xe3\\x19\\xb7\\x24\\xd5\\x8d\\x4d\\xda\\xf2\\x8a\\xc6\\x3f\\x6d\\x1d\\xec\\xb3\\x9c\\xc5\\x00\\xf3\\xac\\x41\\x0f\\x70\\x53\\x65\\x4a\\x59\\x55\\x29\\x0c\\x7a\\x31\\xa6\\x28\\x18\\x04\\xd1\\x19\\x86\\x74\\x60\\xc2\\xe0\\x8f\\xd8\\x81\\xeb\\x0b\\xe4\\xc7\\x3d\\x32\\xcc\\x9b\\x62\\x3b\\x69\\x78\\x9a\\x3b\\x6f\\x37\\x4c\\x81\\x33\\x3c\\x4e\\x90\\x1e\\xa8\\x63\\xf6\\x63\\xf2\\xec\\x6b\\x88\\x75\\x78\\x94\\x8d\\x6e\\x4c\\xd1\\x97\\xa4\\x99\\xbd\\x44\\x47\\x42\\xae\\x8d\\x6e\\x9f\\x42\\xd2\\x77\\x78\\x0a\\x53\\xe4\\x20\\x6b\\x2b\\x40\\x11\\x9c\\xf4\\xd7\\x83\\x82\\xb6\\xca\\xb0\\x75\\xee\\x1f\\x9c\\x01\\x90\\xa2\\x95\\xe5\\x49\\x8b\\xc3\\x0b\\x88\\xd8\\xa8\\xc1\\xf1\\xc7\\xc1\\x73\\x5e\\x16\\xcd\\xf0\\x4b\\x90\\x10\\xa2\\xe9\\x1f\\xc0\\x30\\x6c\\x14\\x3d\\x0b\\xca\\x32\\x3b\\x37\\x35\\xf2\\x59\\xd5\\x26\\x37\\x12\\x3d\\xd7\\x82\\xc2\\x38\\x7e\\xa1\\xde\\x3f\\x48\\xde\\x9c\\xb3\\x3d\\x14\\xee\\x7b\\x86\\xe7\\x09\\x15\\x63\\x6e\\x82\\x17\\xe2\\xa9\\x98\\x81\\x86\\x21\\x90\\xb5\\x9c\\x82\\xc2\\x07\\x62\\x18\\x86\\x4a\\xe9\\x1f\\x0d\\x65\\x34\\x60\\x90\\x3b\\x4d\\x9e\\x6d\\xb8\\x10\\x2e\\x33\\x44\\xb1\\x39\\xc7\\xf3\\x78\\x8b\\xb4\\x2b\\x04\\x3b\\xf4\\x99\\x8c\\x67\\x18\\x04\\x30\\x46\\x6d\\x3b\\x05\\xe2\\x2b\\xac\\x4d\\xd2\\x26\\x45\\x6d\\x6f\\x47\\x60\\xc3\\x79\\x62\\x2b\\x0c\\x4a\\xa8\\xad\\xf7\\x2f\\xf1\\x8a\\xd6\\xf5\\xa3\\xa8\\x13\\x8b\\x41\\xfd\\xe3\\x5d\\x1e\\x27\\x40\\x9d\\xa6\\x14\\x4e\\x50\\xc4\\xbc\\x86\\x58\\x7b\\x40\\x9e\\xd5\\xfd\\xe5\\x67\\x92\\x8d\\xda\\x36\\x7f\\xe7\\x2f\\x8a\\xce\\x7b\\xc7\\x5d\\x2c\\x27\\x72\\x0c\\xc6\\x39\\x38\\xcf\\x02\\x59\\x92\\xc6\\x3b\\xe8\\x45\\x57\\xea\\xed\\xfb\\xbd\\x1a\\xe4\\x7e\\xa1\\x9b\\x9e\\x71\\xf2\\xfe\\xa0\\xa3\\x40\\xfd\\xbe\\xd6\\x0c\\x9d\\x00\\x94\\x22\\xf6\\x5c\\x89\\x49\\x72\\x33\\x41\\xd1\\x6f\\xd2\\xbb\\xf3\\xcb\\xe5\\xdd\\xc2\\xdd\\x53\\x21\\x16\\x07\\xc4\\xb0\\x59\\x7b\\x1b\\xc3\\x1b\\x1f\\xa7\\x19\\x0e\\xc3\\x0d\\xe1\\x14\\x46\\xca\\x32\\x9d\\x53\\x54\\x79\\xd2\\x7f\\xe4\\x02\\xe5\\x58\\x18\\x8e\\x1d\\x52\\x1f\\xbb\\xbb\\x3d\\x1b\\x10\\x2b\\x52\\xf4\\xb1\\x07\\x2e\\x75\\x91\\x66\\x1d\\x9a\\x66\\xb0\\x87\\x7f\\xf0\\x80\\x30\\xe7\\xcf\\xc9\\xdf\\x14\\x4d\\x38\\x06\\x38\\xfe\\x9e\\xf5\\x57\\x33\\xc7\\xd7\\x60\\xdf\\x82\\xc2\\x1c\\x08\\xa2\\xcd\\x23\\x1a\\xa1\\xd3\\x3f\\x29\\xc2\\xf1\\xfd\\xe0\\x3b\\x70\\x39\\x67\\xc3\\xa5\\xf8\\xb7\\x67\\x9b\\xb4\\x65\\xd1\\x38\\xcf\\xa4\\x01\\x57\\x0c\\x62\\xfe\\xe3\\xec\\x65\\x58\\xf6\\x2f\\xf6\\x63\\x5d\\x8f\\xf9\\xe3\\xe8\\xed\\xe2\\x5d\\xf5\\xf3\\x45\\x18\\x9a\\x8e\\x0d\\xaa\\x1c\\x5f\\xcc\\xc5\\xc8\\x44\\x9d\\x81\\xc2\\x65\\xf2\\x1d\\x6a\\x61\\x23\\x5b\\xe7\\xf0\\x86\\x60\\xef\\xfd\\x82\\x3a\\xa8\\xed\\xd6\\xac\\xc8\\xe6\\x3f\\x51\\x09\\x32\\xef\\x14\\x92\\xb0\\x18\\x51\\x07\\x14\\x87\\x15\\x9a\\x33\\x63\\x1a\\xeb\\x09\\xf7\\x2f\\x00\\x50\\xb4\\xf1\\x21\\xca\\x4e\\xd2\\x99\\x1e\\x68\\x69\\x98\\x27\\x80\\x99\\xb2\\x2c\\x01\\x4f\\x31\\x80\\xce\\xda\\xfa\\xba\\x6b\\xb1\\x92\\x04\\xa8\\x65\\x08\\x82\\x84\\x10\\x02\\x41\\x5e\\xea\\xd9\\x76\\xe0\\x06\\x4d\\x72\\xef\\x9b\\x9f\\xe2\\xe4\\xb9\\xce\\x1d\\x9c\\x78\\x7e\\x1a\\x78\\x92\\x1b\\xcd\\x68\\x39\\xb7\\x9c\\xfa\\xb7\\x36\\xfa\\x57\\x4d\\x67\\xff\\x71\\x37\\x73\\x7a\\x99\\xb1\\x66\\x28\\xd9\\xe8\\x26\\x62\\xdf\\x98\\xc6\\x3e\\xdb\\x51\\xc8\\x18\\x20\\x2e\\x48\\x5a\\x16\\xb9\\xa9\\x9f\\x23\\xb6\\x2c\\x5b\\x22\\xb0\\xdd\\x33\\xdf\\xac\\xf0\\xc5\\x29\\x5d\\x14\\x4d\\x51\\x80\\xcd\\x28\\xdd\\x51\\xaa\\x2c\\xb3\\xfc\\xdc\\x5b\\x40\\x3d\\x3e\\xe2\\x8d\\x70\\x73\\x97\\x37\\x26\\x66\\x3f\\x12\\x02\\xe5\\x56\\xec\\xfb\\x85\\x61\\x1c\\x3a\\x05\\x65\\x4e\\x6c\\x81\\x0a\\xa0\\xf9\\xd8\\xcf\\xc2\\x48\\xe7\\x99\\x38\\x92\\xa1\\xe5\\xc3\\x9a\\x54\\x17\\x5b\\xf7\\xce\\xf2\\xa4\\x24\\x06\\x22\\xf1\\x0c\\xca\\xc7\\xf1\\xc2\\x9e\\x4d\\x05\\x80\\x2a\\xc0\\x4d\\x70\\x1f\\xbc\\x1d\\xcf\\x7e\\x8e\\x33\\x9b\\xf2\\xec\\xe8\\x0c\\x15\\xff\\xf8\\xa0\\x0f\\xd1\\xa0\\xd1\\xc8\\x7c\\xf2\\x71\\x65\\xaa\\x8f\\x37\\x28\\x85\\xa5\\x80\\xa8\\xeb\\xbe\\x73\\xf7\\x4d\\xfe\\xcf\\x4b\\x26\\x66\\x62\\x7c\\xc8\\x63\\x64\\x54\\x97\\x41\\xcb\\xde\\x92\\xc4\\xea\\x04\\x0e\\x4a\\xef\\x4b\\x43\\x09\\x00\\x24\\xc0\\x3c\\x23\\xc7\\xa4\\x1f\\xc4\\x40\\x49\\x0c\\x1b\\x5b\\x2c\\x59\\x81\\xde\\xe2\\xf7\\x71\\x9e\\x0f\\x69\\x8f\\x6e\\x0f\\x51\\x7a\\xdb\\x00\\xec\\x91\\xac\\x68\\x44\\xdf\\x7d\\x3f\\x67\\x68\\x20\\xdb\\xcc\\x10\\xf9\\x06\\x00\\x92\\x33\\x34\\x49\\x60\\x01\\x1e\\xb2\\x78\\x92\\x85\\x4e\\x5d\\x9a\\xc3\\x09\\x5e\\xc7\\xb9\\xe1\\x5c\\x8c\\x7a\\xe8\\x38\\x52\\xb4\\x10\\x41\\x58\\x82\\x4a\\x4e\\x98\\x44\\xed\\x6b\\x68\\x64\\x45\\x71\\x99\\x26\\xd7\\x56\\x61\\xf8\\xb1\\x16\\x7b\\x6a\\x63\\x0c\\xdf\\xf8\\x06\\x40\\x9f\\x3b\\xb1\\x1c\\x4e\\x22\\x18\\xc8\\xad\\x51\\x23\\x3f\\xa2\\xdc\\x98\\x9d\\x4f\\x7d\\x9f\\x26\\xbd\\xcc\\xc1\\x9a\\xf6\\x35\\x0c\\x0a\\xa8\\x2c\\x2f\\x21\\xac\\x9b\\x54\\x7a\\x0e\\x6f\\xb5\\x95\\x37\\x1f\\x06\\xd8\\xa0\\x74\\x00\\xa6\\x1b\\xd0\\xb4\\x22\\x52\\xe2\\xdb\\xa2\\x88\\x5f\\xce\\xd0\\xb3\\x2c\\x0b\\xb9\\x03\\xc8\\x84\\xcb\\xd3\\x1c\\xc9\\x1f\\x6d\\xe2\\x84\\xb6\\xfc\\x60\\x17\\x21\\x19\\xa3\\x31\\xcb\\x93\\xe7\\xef\\x9b\\x61\\x78\\x15\\x0a\\x22\\x8c\\xef\\x1e\\x59\\xa4\\x4a\\x2c\\x2d\\xcf\\xb0\\x2c\\x3d\\x04\\xf1\\xb1\\x92\\x01\\xa7\\x4f\\x9d\\x37\\xb9\\x87\\x37\\xe8\\x3c\\x94\\xca\\xcf\\x95\\x3c\\x56\\x8b\\xac\\xbf\\x3b\\x66\\xcf\\xbf\\xd1\\x1d\\x5a\\x23\\x86\\x8d\\x06\\x8a\\xf2\\xe9\\x27\\xfd\\x98\\x97\\x40\\x83\\x42\\x6f\\x23\\x34\\xe2\\x8a\\x51\\x22\\x81\\x07\\x01\\xe6\\x7e\\x77\\x86\\x79\\x48\\x9c\\xda\\xd1\\xfb\\xa7\\x6f\\xb4\\x2b\\xe2\\x60\\x00\\x26\\xc0\\x66\\xa6\\xdf\\x0f\\x33\\x65\\x81\\x49\\xaa\\x76\\xcd\\x80\\xbf\\x32\\x40\\x89\\xcf\\xc7\\x28\\x9d\\x17\\x7a\\xf1\\xcc\\x09\\x7c\\x1e\\x10\\xf5\\x7e\\xc6\\xfd\\x21\\xcf\\xa2\\xd9\\x18\\x06\\xc5\\x30\\x0c\\x61\\xde\\x2f\\x02\\x68\\x1c\\xc6\\x3c\\x6d\\xd2\\x26\\x15\\x98\\x26\\x00\\x74\\xdb\\xef\\x67\\x01\\x51\\x71\\x0c\\x43\\xa5\\x39\\xa3\\x59\\x4c\\xde\\x7b\\xdb\\x9c\\x75\\xa1\\x2c\\xb2\\xd1\\x57\\x7d\\xb4\\x30\\x15\\x9c\\x27\\x94\\x23\\xf2\\x7a\\xb6\\xa7\\x8b\\x94\\x20\\x4d\\xea\\x4c\\xd9\\xf7\\x28\\xf8\\x8a\\x8c\\xa4\\xd6\\x57\\xf1\\x6d\\x5e\\x0e\\x54\\x53\\x7f\\xfb\\x14\\xe6\\x36\\xa2\\x06\\x52\\xbb\\x79\\x5c\\x83\\x41\\xb4\\xa6\\x7f\\xb9\\x3b\\x81\\x68\\x26\\x4d\\x03\\x53\\x6a\\x8e\\xb1\\x2c\\x4b\\x3b\\x67\\x1b\\xe1\\xab\\x3a\\xf4\\xe6\\xb6\\x2f\\x80\\xf0\\x1b\\xe4\\x79\\xc9\\xa9\\xae\\xda\\x5a\\x1d\\x64\\xe0\\x3e\\xc2\\x10\\x44\\x4e\\x52\\x14\\xda\\xaf\\xc9\\x7d\\x2a\\xf8\\xab\\xd1\\x26\\x43\\x15\\xd8\\x49\\x52\\x33\\x01\\xa0\\xf1\\x3d\\xc0\\x70\\x0f\\xed\\x00\\xcb\\x54\\x7e\\x40\\x10\\xc8\\xe3\\x74\\xc4\\xc0\\x71\\xb8\\x24\\x12\\xf2\\xf9\\x8e\\xb1\\x36\\x1f\\xc4\\x34\\xc4\\x0a\\xdf\\xe8\\x44\\xf1\\xbc\\x6a\\x9e\\x03\\x94\\x27\\x8a\\x44\\x75\\x82\\x36\\xf7\\xfd\\x37\\xf5\\xaa\\xff\\xc0\\x8e\\xe6\\xec\\x75\\x66\\xd6\\xb3\\xed\\x47\\xd6\\x4c\\x40\\xca\\x1c\\x6d\\x47\\x48\\xb1\\xd7\\xb4\\x7e\\x1d\\x48\\x02\\xe7\\xcf\\x41\\xc9\\x63\\x5d\\x46\\xe6\\x45\\x70\\x86\\x86\\x18\\xdb\\x3a\\xc4\\xe9\\x41\\xf3\\x6c\\x0b\\xfc\\x6f\\x3a\\xbf\\x10\\xc0\\x78\\xf2\\x78\\x1d\\x49\\xc5\\x4b\\x95\\xac\\xfb\\x1f\\xa5\\x5a\\xc7\\x19\\xac\\xde\\x41\\xd9\\xa2\\x2e\\xda\\x57\\x6e\\x44\\x96\\x0a\\xc3\\x79\\x9a\\x40\\x7b\\x73\\x96\\x63\\x88\\xb5\\x18\\xf3\\xfc\\x31\\x5d\\xcc\\x53\\x27\\x5d\\x2e\\x38\\x3c\\x5e\\xa7\\x9f\\xd5\\x9b\\xbd\\x0b\\x86\\x15\\x7c\\xb9\\x5d\\xbe\\x5a\\x17\\x9d\\xee\\xc5\\x71\\x9a\\x9a\\xbe\\xdc\\x04\\x31\\xb6\\xe2\\x9b\\x7d\\x9f\\x9f\\x27\\x58\\x36\\x0b\\x02\\x47\\xa2\\x50\\xb7\\xdd\\x10\\x39\\xaa\\x04\\xf9\\xc4\\x66\\x50\\x71\\x6c\\x0c\\x4c\\x06\\xc8\\xaa\\xca\\x20\\xf4\\x85\\x63\\x29\\x1d\\x76\\xcb\\xf8\\x97\\x7f\\x98\\xa4\\x7a\\xcc\\xed\\xca\\xec\\x17\\x23\\x8e\\xfd\\xc4\\x54\\xf6\\x82\\xd3\\x05\\x19\\xe2\\x24\\x41\\x29\\x9d\\x62\\x20\\x14\\xc3\\xda\\xc4\\xf3\\x83\\x20\\x1e\\x59\\xa6\\xa4\\x73\\xf1\\xf9\\xdd\\xd1\\x11\\x9c\\x94\\x9d\\x35\\xb7\\x2b\\x1c\\x65\\xca\\x65\\x4c\\xa8\\x7e\\xc9\\xe7\\xcf\\x5f\\x5a\\x22\\xda\\x49\\x0a\\x79\\x29\\x82\\xca\\xf1\\xee\\x8d\\xc3\\x74\\xb3\\xa3\\xf0\\x27\\x0f\\x77\\x3e\\x04\\x65\\xb2\\x2c\\x24\\x63\\x5c\\x03\\x65\\x0e\\xfc\\xe8\\xa6\\x6b\\xa1\\x16\\xf7\\xfd\\x69\\xdb\\x40\\x17\\x79\\x06\\xa5\\xc4\\x1d\\x2b\\xcf\\x92\\x00\\x20\\xcf\\x84\\x85\\x10\\xde\\xea\\xe1\\x24\\xe5\\x4e\\x8e\\x62\\xf9\\xd5\\xd1\\xd1\\xb4\\xf4\\x1d\\xa7\\x07\\x54\\x9c\\x56\\xcb\\x7d\\x74\\xda\\xf0\\x10\\xc0\\x02\\x9a\\x87\\x3e\\x6f\\x35\\x8c\\x44\\x18\\xe2\\x70\\xff\\xe8\\x1d\\xaa\\xc1\\xf9\\x63\\xc2\\x96\\x23\\xed\\xa3\\xfa\\x6d\\xe6\\xfd\\x38\\x44\\xb1\\xad\\x27\\x4c\\x2e\\xa1\\x99\\x97\\x9f\\xee\\x40\\xea\\x60\\x0a\\x2e\\xca\\x42\\x2f\\xfc\\x61\\x27\\x04\\xbf\\xfd\\x50\\x48\\xc8\\x69\\xc6\\xe7\\xb9\\x6f\\xbe\\xc6\\x47\\x65\\xf9\\xfb\\xa9\\xb8\\xd2\\x11\\xfc\\x4f\\xe2\\x4b\\x15\\xc7\\x49\\x91\\x54\\x03\\x6a\\x40\\x15\\x3c\\x0c\\x26\\x00\\xf0\\xf9\\x48\\x65\\x5f\\xb0\\x96\\x07\\xdd\\xcf\\xe4\\x8f\\xdb\\x70\\xc2\\xf8\\x95\\x32\\x84\\x2a\\x1d\\xfd\\xa0\\x19\\x9d\\x8f\\x9c\\xa6\\x5c\\x94\\xde\\x40\\x38\\x14\\xa5\\xe9\\xf8\\x22\\xbd\\x5f\\xd2\\xe5\\xc8\\xfc\\xce\\x8d\\x0f\\x60\\xb2\\xfc\\xc7\\x19\\xcd\\x0b\\x68\\xfa\\x7b\\x95\\xe1\\x3c\\x4c\\x57\\x11\\x90\\x04\\x99\\x63\\x26\\x30\\x61\\x98\\x40\\xf3\\x31\\x6e\\x57\\xfc\\x58\\x37\\x4a\\x7c\\xd1\\x21\\x07\\x0c\\x21\\xe4\\x18\\x92\\xbb\\x9e\\xf0\\xb1\\x6f\\x48\\xfe\\xe0\\x62\\x3c\\x18\\x22\\x3f\\x70\\xa8\\xb4\\x12\\x1a\\x73\\xae\\x58\\xf9\\xca\\xf1\\xbf\\x33\\x0c\\x71\\x43\\xad\\x84\\x97\\xac\\x9e\\x72\\xfb\\x9f\\x77\\x7c\\x4e\\x1f\\x65\\xce\\x54\\x47\\xb1\\xac\\xe6\\xba\\xba\\x4c\\xbe\\x16\\xa9\\xfa\\x61\\x78\\x62\\xc5\\x98\\x33\\xdf\\x91\\xca\\xa2\\x5c\\xb4\\x61\\xd3\\x3c\\x35\\xea\\x26\\x69\\x70\\x09\\x9e\\xe6\\x58\\xd2\\xb4\\x4e\\x89\\x19\\xd3\\x62\\xd3\\xdd\\xc8\\x73\\x96\\x35\\xa1\\xf5\\x0b\\xaf\\x39\\x9f\\x2b\\xe9\\xa0\\xc1\\xc7\\xa9\\x51\\x4c\\x99\\xa1\\xfa\\x38\\x90\\x20\\x6e\\x8c\\x4b\\xd1\\xb8\\xa0\\x9b\\x00\\x62\\x4e\\x0f\\x0b\\x38\\xec\\xa6\\xbb\\x93\\x7c\\x8c\\x38\\xf7\\x51\\xfb\\x2d\\x89\\xeb\\xdc\\x9f\\xaa\\xe1\\x60\\x65\\xeb\\xf3\\xab\\x51\\x2c\\x6d\\xa2\\xac\\x08\\x8b\\x65\\x56\\xa0\\xa7\\x02\\x6e\\xd2\\xe0\\xbb\\x51\\x88\\x53\\x1b\\xf2\\xb2\\x60\\x5e\\xb7\\x23\\x12\\x08\\x05\\xf3\\x0e\\xf9\\xa5\\x37\\x1f\\xa4\\x9e\\x03\\xaf\\x16\\x8b\\x63\\x08\\x55\\x37\\x2f\\xcb\\x8a\\xf3\\x4e\\x3a\\xd8\\x37\\x6b\\x0a\\xfd\\xa9\\x94\\xc9\\xd3\\xa3\\x69\\x70\\x36\\x3c\\xc3\\x40\\x25\\x6d\\x07\\xa6\\x11\\x51\\x14\\x28\\xb5\\xf3\\xdf\\xfb\\x5c\\xd1\\x1c\\x13\\x0e\\x0b\\x95\\x82\\x89\\x8d\\x27\\xe8\\xe7\\xfd\\xc0\\xd6\\x7d\\xe4\\xa1\\x98\\xc4\\x8f\\xb7\\x3c\\x01\\x40\\x03\\xf4\\x4f\\xe2\\x3b\\x10\\xc8\\x33\\x4e\\x9c\\x8f\\x95\\x88\\x09\\x25\\xf8\\xcd\\xbd\\x7e\\x9f\\x7b\\x5a\\x8a\\xd1\\xa6\\x2d\\xfd\\xed\\x98\\x2b\\xa6\\x89\\x09\\xa1\\xd1\\xf4\\x7e\\xd9\\x26\\x3c\\xfa\\x60\\x0b\\xab\\x7b\\x9e\\x5c\\x41\\x74\\x19\\x94\\xd2\\xa8\\x34\\x1d\\x41\\xcb\\xe4\\xc5\\xfd\\xe5\\x85\\xc2\\xa0\\xe2\\xf3\\x84\\x82\\x61\\x20\\x7d\\xcb\\x7a\\xcc\\x2f\\x06\\x34\\x3a\\xec\\x9e\\xdf\\x86\\x4e\\x65\\x70\\x0c\\x8c\\x2d\\xd2\\xea\\x0d\\x7f\\xb4\\xdb\\xd0\\x67\\x97\\xd2\\xe2\\x3e\\xc0\\x29\\x5e\\xe6\\xa6\\x10\\x4e\\x29\\x66\\x47\\xd0\\x87\\xc4\\x52\\xf3\\x84\\xe1\\x3d\\x3d\\xee\\xb2\\xa3\\x37\\x8c\\x80\\xca\\xc2\\xcb\\x21\\xb4\\xdb\\x6c\\x96\\x13\\x5c\\x32\\xdf\\xb1\\x1a\\x86\\x60\\xff\\xb6\\x3a\\xfa\\xfd\\x51\\xb2\\xe6\\x8b\\xad\\x2d\\xaf\\x1e\\x2e\\x14\\xde\\x6c\\x35\\x84\\x49\\x55\\x3a\\x7c\\x26\\x3b\\x06\\x64\\xd3\\x14\\x49\\xef\\x6b\\x76\\x01\\x05\\x55\\xcc\\xfd\\xf8\\xa1\\x59\\x86\\xeb\\x42\\x1e\\x31\\x01\\x08\\xcc\\x85\\xc1\\x99\\x1e\\xf7\\x64\\x89\\xaf\\x1a\\x24\\x7b\\x20\\x45\\x40\\x37\\xce\\x60\\x5d\\xcf\\x19\\xaa\\xb7\\x67\\x25\\x79\\x45\\xe2\\x89\\x64\\x3f\\x5e\\x68\\x64\\xb0\\x91\\x26\\x30\\xa6\\x7a\\x96\\x96\\x3e\\xf4\\x3d\\x0d\\x30\\x0c\\x0b\\xcf\\x73\\x04\\x14\\x7e\\xc3\\x9f\\xaa\\x52\\x87\\x22\\xe1\\x61\\xc6\\x2c\\x01\\x7d\\xbf\\x8c\\xb0\\xca\\x61\\x5c\\x2d\\x46\\xd4\\xfc\\x00\\x35\\x07\\x4a\\x91\\x8f\\x11\\x39\\xc6\\xc6\\xe8\\x0a\\x63\\xf2\\xce\\xa7\\x4e\\x4c\\xfb\\xf8\\xde\\xf1\\x5d\\xfd\\x65\\x73\\xbe\\x8e\\x5b\\x3b\\x50\\xe1\\x33\\x3c\\x50\\x08\\xd0\\x2f\\x56\\x00\\x1f\\x87\\x6f\\x61\\x32\\x45\\x1c\\x8c\\xbd\\x44\\x31\\x38\\xb9\\x8d\\x25\\x6f\\x3a\\xf3\\x78\\x21\\x52\\xb7\\xd9\\x9a\\xc1\\x6d\\x73\\x2f\\x6f\\x2d\\x17\\xbd\\xc6\\xf5\\x31\\x85\\x9a\\x12\\xf9\\xcf\\x6f\\x1c\\xff\\x32\\x6f\\x66\\x80\\x9c\\x79\\x2d\\x4c\\x27\\x73\\xda\\x65\\xd2\\x3d\\x4a\\x17\\xb1\\x08\\x42\\x3a\\x40\\xcf\\x48\\xb5\\x4a\\x68\\x78\\x94\\xce\\x16\\x26\\x8d\\x15\\x67\\xc1\\xa0\\x29\\xea\\xf1\\x64\\x4d\\x13\\xc6\\x79\\xee\\x12\\x75\\x77\\x86\\xd6\\x3f\\x9a\\xbc\\x78\\xc5\\xb6\\xd0\\xa4\\xd0\\xf8\\x19\\x50\\x5a\\x3e\\x59\\x51\\x34\\x27\\xf1\\x90\\x30\\xbc\\xdf\\x86\\x79\\x66\\x67\\x1d\\xb8\\xed\\x29\\x96\\xe6\\xb8\\xef\\xe7\\x19\\x60\\x39\\xba\\x06\\x51\\xd6\\x7e\\x0d\\x5e\\x79\\x70\\x63\\x2e\\x82\\x7e\\x4e\\x44\\x11\\x7b\\xa7\\x26\\xcb\\xca\\x14\\x05\\xe6\\xb1\\x7a\\x46\\x81\\xa5\\x27\\x38\\x7f\\x26\\xd5\\xae\\xab\\x9f\\x17\\x71\\x77\\x83\\x12\\xca\\xfb\\x71\\x67\\x10\\xfa\\x21\\xc9\\xfc\\x78\\xf9\\x10\\x46\\xac\\xb0\\x39\\x7e\\x12\\x61\\x1a\\x4c\\x81\\xee\\x6b\\x02\\x87\\x59\\x24\\x4a\\x64\\x06\\x47\\xee\\x0e\\x6f\\xa3\\x65\\xb3\\xea\\xb7\\x01\\xec\\x2d\\x7f\\xaa\\x96\\xce\\x5f\\x8c\\xc2\\xb0\\xf3\\x74\\xc2\\x13\\xb7\\x39\\xc9\\xb3\\x79\\x9b\\x85\\xce\\xf0\\xc4\\x72\\x03\\xc2\\xe9\\xa2\\x94\\xbb\\x7c\\x25\\xe8\\x8a\\xf9\\x49\\x46\\xc8\\x06\\xc5\\x88\\x2d\\x2b\\x22\\x9b\\xee\\x32\\x1c\\xba\\x12\\xba\\x24\\xc5\\xf3\\x9f\\xdf\\x20\\x10\\xa0\\x1f\\xcb\\xf3\\x84\\x45\\x04\\xd0\\x15\\x6c\\x3f\\x9a\\x8f\\x40\\xf4\\x66\\xea\\x17\\x59\\x85\\x5b\\x80\\x9b\\x34\\x34\\x3d\\x45\\x01\\x74\\x81\\x03\\x9c\\x39\\x59\\xb8\\xb5\\xd0\\x41\\x5a\\xf6\\x5e\\xc5\\xbd\\xac\\x2e\\x1b\\x9e\\xb8\\xf6\\x93\\x43\\xc6\\x8f\\x6b\\xfc\\x30\\xfc\\x21\\x4e\\xf8\\x90\\x6a\\x88\\x86\\xd0\\x31\\x2a\\x22\\x83\\x60\\x6c\\x3f\\xc6\\x33\\x4d\\x37\\x7d\\x44\\x48\\x0b\\x06\\xcd\\xfb\\x04\\x2f\\x3a\\x97\\xa9\\xb1\\x3c\\xf4\\x18\\xba\\x6c\\xce\\x12\\x9c\\x9e\\x47\\xf4\\x09\\xff\\x2e\\x37\\x86\\xb5\\x77\\x1a\\xea\\x96\\xf2\\x12\\x49\\x79\\x6a\\xba\\x4e\\xa6\\xf4\\xb0\\x64\\x9e\\x71\\xa6\\xfe\\x1f\\x30\\xd1\\x42\\xb6\\xab\\x0e\\xc2\\x50\\x1b\\x24\\x00\\xb1\\xc2\\x45\\x91\\x9a\\x5f\\x8c\\x21\\x70\\x95\\xa2\\xd0\\xc7\\xbe\\x70\\x97\\x17\\xc0\\x28\\xac\\x49\\x8b\\x5a\\xa9\\x9a\\xc0\\xd1\\x32\\x48\\x01\\xaa\\xc7\\xcc\\x31\\xaf\\x6b\\x37\\x3e\\x0e\\x51\\xc1\\x85\\x2f\\xdb\\x5e\\xfc\\x93\\x7e\\xc8\\xfb\\xd2\\x59\\x81\\xaf\\x82\\xbd\\x30\\x07\\x48\\xf3\\x67\\x37\\x92\\x26\\xd6\\x52\\x0f\\xd3\\x19\\x0a\\x50\\xa7\\x85\\xad\\x08\\x5a\\xd6\\xc9\\x43\\x1f\\x4a\\x16\\x09\\x86\\x72\\x34\\xf8\\x6e\\x8b\\xf3\\x62\\x79\\x4f\\x84\\xb3\\x5f\\xdb\\x19\\x50\\x6f\\x95\\xf1\\x41\\xd1\\xe4\\xc1\\x39\\x23\\x9e\\xc7\\x69\\x49\\x33\\x57\\xbf\\x81\\xc2\\xaf\\x4c\\x31\\x45\\x2a\\x6e\\x5b\\x1a\\x48\\x41\\xc8\\xe8\\x23\\x66\\x00\\x23\\x46\\xec\\xd0\\x3e\\x60\\x9b\\xb6\\x24\\x1f\\xc5\\x27\\x42\\x09\\x1a\\xa4\\x74\\x0e\\xff\\xa0\\x93\\x1a\\xb7\\x34\\xa2\\xd7\\xe2\\x56\\x4a\\x46\\xb3\\x33\\x1a\\x66\\x84\\xa9\\xcf\\x7e\\x8e\\xac\\x33\\xa7\\x6b\\xed\\xb8\\xbd\\x43\\x2c\\x1a\\x46\\xe1\\xc8\\xcc\\x51\\xc3\\x44\\x40\\x34\\xe5\\xed\\xc8\\x07\\x94\\x02\\x85\\x10\\xc6\\xf9\\x4c\\x94\\x3f\\x9a\\x0a\\x27\\x4a\\x2f\\x95\\xdc\\xfb\\x4b\\xb4\\xc2\\xb2\\xf9\\xc4\\x77\\x5a\\x90\\xe4\\x38\\x0e\\x33\\x40\\x71\\x82\\xc9\\xad\\xf7\\xcd\\xc4\\xb6\\x74\\xf1\\xf5\\x0a\\x20\\x7e\\x33\\x59\\xca\\x94\\x2e\\x00\\x80\\x3c\\x8c\\x23\\x44\\x2d\\xe4\\xb6\\x3e\\x9e\\xee\\xfa\\x48\\x8e\\x31\\x38\\x01\\xc1\\xe3\\x3a\\x28\\xa6\\x81\\xbd\\xf8\\x1f\\x6b\\x97\\x25\\xa0\\x54\\xe2\\xdf\\x79\\xe1\\x2d\\x48\\x65\\xc7\\x4a\\x91\\x95\\x0a\\x46\\xe1\\x6f\\x68\\xfa\\xb7\\x8f\\xe1\\x71\\x7d\\xf5\\x41\\x3c\\x84\\x53\\x3a\\xa8\\x85\\x44\\xc6\\x97\\xd6\\x92\\x44\\xcc\\xb9\\xf7\\x8f\\xef\\x28\\x8a\\xc2\\xc5\\xbd\\x10\\x9c\\xe7\\x28\\x5f\\xb3\\xa4\\xa6\\x08\\x00\\xec\\x7e\\xc1\\x6d\\xca\\x8c\\xaf\\x62\\xaf\\xd2\\x2b\\x5d\\x04\\x52\\x5d\\x8c\\x8f\\xc5\\xeb\\x0d\\xc0\\x1f\\xa6\\xd8\\x06\\x71\\xfa\\x0d\\x4c\\x67\\xf4\\x96\\xfe\\xd7\\xde\\x64\\x1e\\x9e\\x1b\\x5d\\x94\\x52\\xd7\\xf3\\x06\\x47\\xe9\\x6e\\x8e\\x85\\x98\\xe9\\x62\\x14\\x89\\x46\\x78\\xee\\xed\\xc7\\x6d\\x7d\\x00\\xf1\\x30\\x99\\x07\\x0e\\xbe\\x3a\\xa9\\x41\\xca\\x99\\xe2\\x6e\\x01\\x92\\xc3\\x49\\x49\\x66\\xd8\\x19\\x02\\xb4\\x3c\\x57\\xc3\\x68\\x9e\\x75\\x03\\xe5\\x52\\x88\\x54\\x45\\xb0\\x4e\\xe7\\x7f\\x6d\\xc1\\x67\\x79\\xee\\xde\\x58\\x57\\xf8\\x28\\xe1\\x19\\x06\\xa3\\xa1\\xef\\xe9\\x41\\xf5\\xa9\\x3c\\xdf\\x05\\xf5\\xb9\\x85\\x8f\\x67\\xb3\\x2c\\x6b\\x55\\x5f\\x76\\xa8\\x84\\x7f\\x1f\\xc8\\x6a\\x5f\\x26\\x08\\xed\\xb2\\x7e\\xb5\\x87\\xd1\\xa0\\x92\\x39\\xcd\\x34\\x0e\\xed\\x08\\xe4\\x10\\x35\\x8e\\x6b\\x7f\\x53\\xe7\\x50\\xc0\\x8c\\x73\\x6e\\x70\\x2d\\x60\\x22\\xcc\\x22\\x3b\\x17\\xfb\\x74\\x41\\x83\\xb2\\x6d\\xe3\\xe7\\xf9\\x74\\x6f\\x05\\xff\\x26\\x8c\\xc7\\x83\\x7a\\x49\\xe6\\x2a\\xfa\\x51\\xc1\\xb5\\xa5\\xc9\\xbd\\xb7\\xd6\\xa3\\x8d\\x2f\\xa5\\xb7\\x98\\xf5\\x42\\xcc\\x37\\x3a\\x94\\x9d\\xb8\\x9e\\x89\\x4f\\xba\\x49\\x08\\x8f\\x06\\x0d\\x7d\\x3d\\x10\\x51\\x7b\\x3c\\x8f\\x93\\x74\\x2e\\xdb\\xf2\\x6f\\xf2\\x36\\xe5\\x72\\x7a\\xeb\\x6d\\x2a\\x14\\x0e\\xe4\\x8f\\x2f\\xc5\\x4f\\x6c\\x50\\x15\\x4f\\x34\\xcb\\x6e\\x66\\xd3\\xbe\\x26\\xae\\xd3\\x3b\\x1b\\x65\\x60\\x67\\x03\\x99\\xe2\\xf8\\x12\\x98\\xf8\\x98\\xcf\\x17\\x22\\x34\\x43\\xcc\\x39\\x81\\xa2\\xfa\\x17\\xa2\\xd2\\x70\\xd1\\x7f\\x58\\xca\\x20\\x9c\\x42\\x51\\x17\\x38\\x31\\x8a\\xf4\\x8d\\x11\\x39\\x18\\xc5\\x39\\x30\\xba\\xf8\\xce\\xc9\\xb0\\x42\\x27\\x46\\x1a\\x62\\x20\\x92\\x92\\x24\\xd2\\x6e\\x0e\\x45\\x5b\\xaa\\x6c\\x8a\\xe3\\x51\\xc3\\xaa\\x41\\x1f\\xcb\\xd2\\xfc\\x2f\\x6b\\x7d\\xd8\\x44\\x6b\\xa6\\xf7\\x43\\x3f\\x12\\xfb\\x91\\xbe\\xcd\\x5b\\x9c\\xc1\\xc0\\xdb\\xc7\\xad\\xc5\\x77\\x67\\x88\\x22\\x0d\\x99\\xce\\xec\\x41\\xc1\\x62\\x2f\\x6c\\xca\\xa0\\x94\\xf2\\x6c\\x33\\x4e\\xaa\\x10\\xfb\\x40\\x21\\x4a\\xed\\xba\\x48\\xd6\\x0c\\x6f\\x79\\x02\\x9b\\x6f\\x8a\\xf0\\x1a\\x7c\\xb2\\xdc\\x05\\x7f\\x25\\x7c\\x10\\x33\\xa9\\x07\\x8f\\x32\\x9c\\x6b\\x76\\x5b\\xd3\\x55\\x6a\\xb2\\xc4\\x49\\x9c\\x56\\xec\\x78\\xbd\\x4c\\x98\\x37\\xbe\\x14\\x74\\x0c\\x53\\xd1\\xfc\\x95\\x4b\\x60\\x7c\\x4c\\x7c\\x8a\\x2a\\x34\\xb9\\x73\\xcc\\xbf\\xdd\\x3f\\x79\\x77\\xc0\\x50\\x06\\xb9\\xc2\\xda\\xee\\x6e\\x90\\x8c\\xcf\\x31\\x86\\x50\\xa4\\x0f\\x76\\x62\\x2f\\xb1\\x31\\x09\\x44\\x6e\\x26\\x48\\x0f\\x6c\\x0c\\x09\\x7c\\x0b\\xb4\\x1d\\x1a\\xa3\\xce\\x63\\x34\\x8d\\xad\\xb4\\x6f\\xe0\\xf7\\xa1\\x0f\\xe7\\xda\\x6b\\xba\\x7d\\x83\\x6e\\x6b\\x02\\x6f\\xed\\xe7\\xd2\\x11\\x3d\\xf4\\x03\\xee\\x1a\\x2c\\xfb\\x33\\xb6\\x04\\x14\\x69\\x61\\x98\\xf4\\x2f\\xf5\\xed\\x6f\\x88\\x3f\\x0b\\x7b\\xd0\\xe0\\xf0\\xe4\\xa0\\x56\\x5c\\x5b\\xbb\\xd0\\xb8\\xb1\\x3d\\x49\\x28\\x15\\xf1\\x73\\xd6\\x09\\xfc\\x7e\\x19\\x64\\x34\\xbd\\x7a\\xf0\\x7b\\xd7\\x55\\xc4\\xd5\\x08\\xd2\\xef\\x86\\x26\\x91\\xfe\\x83\\x82\\x9d\\x50\\x42\\x3b\\xd0\\xf7\\x68\\x20\\xf6\\x96\\x2b\\x47\\xe0\\x21\\x48\\x7e\\x86\\x29\\x32\\xac\\xc3\\x4b\\xa0\\xbc\\xda\\x06\\x0c\\x3e\\x00\\x02\\x7d\\x12\\xf5\\x1b\\xc2\\x3b\\xa2\\xc4\\x57\\x79\\x62\\xe1\\x4b\\x4c\\xee\\x27\\x0b\\x07\\xe2\\x08\\x6b\\x4b\\x28\\xac\\x55\\xcb\\x7f\\xd6\\xeb\\x7b\\x9d\\x29\\x0f\\xaf\\xd9\\xcd\\x8a\\x33\\x62\\x14\\x63\\x69\\x5e\\x29\\x1b\\x09\\x74\\xaa\\xbd\\x83\\x5f\\x16\\xe9\\xcb\\x71\\xe0\\xf6\\x2d\\x7a\\x5a\\xaf\\x96\\x7e\\xa7\\xda\\xb1\\x89\\xee\\x64\\x3b\\xeb\\xe0\\xf0\\xf6\\xa6\\xc1\\xb3\\x8d\\x50\\xb6\\xf6\\xd9\\x8b\\x08\\x2d\\x9d\\xd6\\xa0\\x02\\x9b\\xc4\\x23\\xbe\\xef\\x8d\\x8e\\xca\\x9c\\x26\\x76\\x91\\x6a\\x4b\\xdd\\x9a\\x8b\\x0d\\x3a\\xb3\\x98\\xad\\xfc\\xa1\\x13\\xf3\\xa2\\x0d\\xf1\\x61\\x7d\\xda\\x1c\\x81\\xb1\\xea\\xbd\\xac\\x22\\xa4\\x05\\x79\\x06\\x54\\x6a\\x59\\xb4\\xfb\\xee\\x8d\\xb2\\x7e\\xe0\\x15\\x63\\x29\\x23\\x07\\x54\\x09\\xb5\\x36\\x93\\x34\\x75\\x9f\\xdf\\x6c\\x1a\\x5b\\x80\\x44\\x8c\\x7a\\xea\\x60\\xd4\\x9f\\xee\\x95\\xd8\\x8f\\x53\\xa0\\x12\\x9e\\x74\\x73\\x55\\x60\\xe2\\x49\\xe4\\xd0\\xfc\\x12\\xaa\\x39\\x12\\xf4\\x20\\x4b\\x4e\\x69\\xac\\x3d\\x8a\\x24\\xf3\\xec\\x3d\\xc9\\x19\\xae\\x22\\x9d\\x08\\xad\\xb4\\xc6\\x1b\\xb6\\xb5\\xd2\\xbb\\xe5\\x4d\\x03\\xe7\\xfc\\x9c\\x73\\x5e\\x6f\\x07\\xc8\\xae\\xda\\x7a\\x2b\\xa1\\xdb\\xfa\\x20\\xd1\\x9e\\x66\\xaf\\xe6\\x9a\\x3e\\x9c\\xfb\\x8e\\xd7\\x17\\x07\\xf8\\xd7\\xa3\\xe3\\x63\\x24\\x42\\xc8\\x7b\\x40\\xe5\\xd0\\xee\\x4e\\x6d\\x4b\\x90\\x81\\x75\\x95\\x24\\xff\\xb1\\x59\\x41\\x28\\x8d\\xcd\\xd5\\x80\\xde\\xc5\\x96\\xc2\\x49\\x4e\\xd8\\x9a\\x1d\\x41\\xb0\\xdf\\x5a\\x2a\\x81\\x3e\\xf6\\x8f\\xe3\\x75\\xb2\\x3d\\x30\\x3c\\x6d\\x86\\x98\\x7d\\x9b\\xd0\\xd9\\x48\\x9d\\x1c\\x0e\\x26\\x1d\\x2d\\x7a\\xe3\\x09\\x6b\\xb9\\xb5\\xf9\\x81\\x95\\xbc\\xd5\\x19\\x00\\xf0\\x86\\x3b\\x9d\\x9b\\x55\\x1e\\x2b\\x8c\\x34\\x48\\x5a\\x0b\\x52\\x2d\\xbb\\xe4\\xde\\x4c\\x8b\\x32\\xcf\\x49\\xb0\\xad\\x8a\\xd3\\xcd\\xca\\xf3\\xb7\\x5c\\xd3\\x22\\x35\\x35\\xbd\\xd7\\x9a\\xdf\\x69\\xf2\\x64\\x7e\\x63\\x5d\\x9c\\x73\\xe5\\x6b\\x29\\xac\\x25\\x43\\xe1\\x0d\\x85\\x01\\x9c\\xb7\\xff\\xee\\xe3\\xa8\\x7d\\xdf\\x0f\\xfb\\x38\\x08\\xfa\\x38\\xf0\\xfb\\x39\\x09\\x7b\\xa2\\x08\\xf1\\xa5\\x66\\x67\\x4e\\xa2\\x4b\\x33\\x5b\\xe5\\xc7\\x12\\xbc\\xde\\xbc\\xbb\\xf7\\x5c\\x34\\x9a\\xbd\\xd8\\xe2\\x26\\xcd\\x76\\xba\\x37\\x2c\\x9d\\x90\\x7b\\x1a\\x60\\x45\\x6b\\xcd\\xf1\\xed\\x19\\xbb\\x8b\\x7f\\xec\\xd9\\x01\\x65\\x36\\x65\\x44\\x4f\\x03\\x64\\xe7\\x3d\\xff\\xab\\xfb\\xbe\\xef\\xbb\\xbe\\x1f\\x07\\xf1\\x2a\\x46\\x2a\\x9b\\xae\\x0e\\x02\\x49\\xc7\\x0a\\xcd\\x6b\\xd2\\x4c\\x0a\\x07\\x9d\\x0b\\x57\\x9d\\x2a\\xa0\\xe8\\x23\\xe5\\xaa\\x4a\\xbb\\xf9\\xaf\\x4e\\x32\\xc5\\x9b\\x1d\\x92\\xc8\\xbf\\x48\\x03\\xef\\xc1\\x56\\x7f\\x15\\x98\\x06\\x25\\x00\\x6a\\xff\\x50\\x63\\x35\\xe3\\xa6\\x12\\xa1\\xc5\\x79\\x52\\x82\\x13\\xeb\\x12\\x3d\\xfc\\xb6\\x55\\x81\\x19\\x7b\\x7a\\x24\\xee\\x03\\x44\\x1c\\x28\\x7e\\x97\\xe8\\xa2\\x97\\xba\\xd6\\x93\\x51\\x46\\x7a\\x72\\x96\\x14\\xd8\\xeb\\x15\\x5d\\x15\\x3e\\x98\\x3b\\xd9\\x7a\\x72\\x7b\\x43\\x2e\\xc0\\x8c\\xc0\\x67\\xbe\\xa8\\x3d\\x4a\\xc6\\xad\\x0c\\xc9\\xaf\\xf9\\x1b\\x52\\xa5\\x24\\xec\\xa4\\x38\\xc7\\xa4\\x34\\xfb\\xc5\\x56\\x54\\x9d\\xa9\\x73\\x29\\x47\\xad\\x10\\xf1\\x5c\\xc2\\x3b\\xf6\\x47\\x08\\xe9\\x4f\\xc8\\x79\\x1e\\x57\\x25\\xdc\\xb0\\x2f\\x49\\x96\\x23\\xcb\\x17\\xa5\\xeb\\xba\\xfa\\x95\\xed\\x60\\xf7\\x04\\xc3\\x52\\xa8\\xf6\\xe9\\xd7\\x73\\xe2\\xf0\\x0e\\x34\\xbc\\x2b\\xf9\\x1f\\x49\\xab\\x69\\xe6\\xa1\\xde\\xf2\\x36\\xa5\\x9f\\xf5\\xfc\\xb6\\x68\\x90\\x9b\\x64\\x98\\xb7\\xf4\\x77\\x4f\\xf1\\xef\\xee\\x52\\xe1\\x76\\x72\\x5c\\xe8\\x2e\\x38\\x69\\xb3\\xb8\\xd1\\xd2\\x2e\\x53\\xa7\\x52\\xc5\\x43\\x89\\xe0\\xfa\\xeb\\xcb\\x4f\\x25\\x33\\x62\\xd0\\xb2\\x2a\\xf7\\x46\\x1d\\x6f\\xdc\\x64\\xb4\\x7b\\x62\\x68\\x77\\x6c\\x68\\x42\\x20\\x1e\\xff\\xef\\x4e\\x32\\x41\\xb0\\xf6\\xf0\\x4d\\xba\\xce\\xc8\\x2c\\x8c\\x09\\x36\\x8c\\xbe\\xf5\\x38\\xbc\\x86\\xf3\\xab\\xcf\\xb7\\x85\\x0e\\x24\\xba\\x4f\\xa4\\x31\\xcc\\x4b\\xf2\\x27\\x99\\x66\\x5a\\x9e\\x6d\\xd5\\xd4\\x7a\\x53\\x99\\x9f\\x81\\x80\\xcf\\xf7\\xaa\\x04\\xa0\\x2e\\xe4\\xf0\\x6f\\x65\\xd6\\x87\\x3e\\x15\\x85\\x3e\\xd5\\x07\\xde\\x55\\xc7\\xc5\\x83\\xaf\\xcf\\x0e\\x42\\x7f\\x56\\xb4\\x96\\x7f\\x40\\x64\\x9c\\x68\\x9a\\xa1\\x93\\xbe\\xb2\\x02\\x7d\\x5a\\x25\\x6c\\x32\\x5a\\x6a\\x3c\\xef\\x0c\\x83\\x1e\\x93\\x0a\\x0b\\x37\\x38\\x1e\\xba\\x40\\xb5\\xd0\\x4e\\x99\\x41\\xed\\xe7\\x2a\\x70\\xa6\\x68\\xed\\x15\\x99\\x1e\\x07\\x2a\\xbf\\xb9\\x81\\x45\\x05\\x6f\\x6d\\x2d\\x6e\\xe5\\xae\\xd7\\x4b\\x8f\\xf6\\x66\\xaf\\xde\\x46\\xb7\\xe6\\x0a\\xb7\\xd6\\x46\\xa8\\xce\\xab\\x1e\\xb2\\xff\\x69\\x28\\x1d\\x32\\xbe\\xd6\\x3b\\xdb\\x93\\x58\\x2d\\xfc\\xde\\x9e\\xff\\xb5\\x23\\xef\\xcb\\xfe\\xc9\\xd4\\xa6\\x41\\xa9\\xbd\\xc6\\xbb\\x51\\xca\\xab\\xbd\\xea\\x43\\x1b\\xb4\\x51\\x2a\\xe6\\x70\\x87\\x8b\\x0b\\xa5\\xb4\\x3c\\x95\\xce\\xdc\\xc1\\xe9\\x65\\x04\\xab\\x4f\\x32\\xd9\\x58\\x8a\\xa2\\x88\\xb5\\xa5\\xca\\x86\\x45\\x8c\\xfa\\xfa\\xf0\\x4e\\xfb\\x48\\x58\\xfd\\x2b\\xa4\\xbf\\xfb\\x4f\\xfd\\x47\\x3a\\x10\\x43\\x3a\\xc4\\x4b\\x32\\xcc\\xeb\\x4c\\x16\\xfd\\x9c\\x04\\x13\\x66\\xfd\\xed\\x2a\\xa8\\x6c\\xef\\x08\\x89\\x87\\xf8\\xdf\\x2e\\xf9\\xfb\\x3b\\x27\\xc5\\x99\\x52\\x0c\\xe4\\xc4\\xeb\\x97\\x87\\xc9\\xdc\\xf0\\x9a\\x58\\x0f\\x56\\x1f\\x6b\\x29\\xe3\\xda\\x68\\x20\\xfe\\x88\\x50\\x0d\\xd7\\xef\\x46\\x15\\x99\\x2a\\x90\\xc7\\xbc\\x00\\x33\\x9a\\x95\\x66\\x39\\x82\\xb4\\x08\\x1e\\x28\\x70\\x88\\x47\\xd7\\xc7\\xb7\\x6b\\x65\\x27\\x24\\x90\\x6c\\x0f\\x0b\\xd1\\x92\\xaa\\xa1\\x5e\\x63\\x50\\xa6\\x14\\xc5\\xb8\\x0c\\x30\\xcd\\xb1\\xdd\\x46\\xd3\\x81\\x77\\xd9\\xf1\\xbe\\xfc\\xe3\\x35\\x34\\xee\\x7c\\x6b\\x99\\x54\\x9b\\xc7\\xac\\x59\\x44\\xb7\\x3c\\xfe\\x73\\xeb\\xae\\xf7\\x26\\x68\\xbc\\x45\\x83\\x52\\xa5\\x28\\x5b\\x25\\x0a\\xf7\\x17\\xd3\\xfa\\x35\\x41\\x3b\\x46\\x3a\\x7b\\xcc\\xa0\\x21\\x21\\x0b\\xc7\\xdf\\x29\\xb0\\xcd\\xb6\\xcf\\x07\\xa9\\xfd\\x69\\xe5\\xaa\\xfc\\x64\\x34\\xe1\\x7b\\xd0\\x15\\x5b\\xde\\x85\\x4f\\xf5\\x68\\xab\\xf6\\x6a\\xab\\x06\\xcc\\xc9\\xfd\\xda\\x9e\\xff\\xb7\\x1a\\xd6\\xa3\\xb5\\xa6\\x8b\\x30\\x66\\x88\\x30\\x9f\\x4b\\xe3\\x73\\x0b\\xd6\\x0b\\xff\\x80\\x6d\\xc5\\xb4\\xd1\\xdf\\x15\\xd4\\x34\\x52\\x67\\x4c\\x95\\xf1\\xf3\\xa9\\xe2\\xa1\\x42\\x88\\xfc\\xca\\x20\\x38\\xa5\\xd7\\xd4\\x43\\x0f\\xae\\x3e\\x20\\x67\\x89\\x2a\\x77\\x56\\x68\\x23\\x9d\\x86\\x8b\\x99\\x11\\x42\\x12\\xf9\\xae\\x0f\\x44\\x22\\xc3\\x8c\\xe8\\xd5\\xe5\\xb7\\x53\\x4b\\x11\\xdf\\x09\\x80\\xd3\\x07\\x18\\xaa\\xcb\\x46\\x34\\x57\\x40\\x34\\xd7\\x43\\xf5\\x36\\x42\\x90\\x5c\\xf4\\x52\\xd3\\x75\\xd6\\x59\\x71\\xba\\x4d\\xf9\\x54\\xf2\\x53\\x8e\\xa0\\x3c\\xb1\\xc3\\xed\\x08\\x8a\\x21\\xfa\\x79\\x45\\x88\\x0b\\x32\\x6f\\x47\\xac\\x2f\\x1a\\x93\\x5f\\xf9\\x72\\x8c\\x80\\x62\\xee\\x0a\\xc3\\x28\\x66\\xac\\x0d\\xd0\\x8e\\xaa\\x4f\\xe2\\x11\\x71\\x33\\x56\\xf0\\xad\\xa6\\x91\\xda\\x4b\\xff\\xeb\\xc0\\xb9\\xf9\\x2d\\x39\\xab\\x93\\x7d\\xbe\\x5f\\x9d\\xf2\\x37\\x1f\\x69\\x82\\xe6\\x5b\\x81\\xa6\\xf1\\x81\\xa5\\x8b\\x1f\\x95\\xfd\\x55\\x09\\xdc\\x9d\\x6e\\xa7\\xab\\x10\\xd9\\xd9\\x15\\x96\\x82\\xa5\\x01\\x96\\xee\\x0b\\x9a\\xef\\x11\\x8a\\xec\\x11\\xaa\\x77\\xf1\\xcf\\x36\\xd4\\x94\\x8b\\x78\\x16\\xce\\x45\\x1b\\xce\\x45\\x07\\x5a\\xca\\xb3\\xa5\\xc1\\x9f\\x48\\x86\\x79\\x45\\xa0\\xf1\\xec\\x08\\xbd\\x3c\\xbd\\x45\\x77\\x03\\x5f\\x19\\x68\\x48\\x08\\xbf\\x56\\xf8\\xbd\\x34\\x03\\xbd\\xd9\\x60\\xd6\\x08\\x12\\xd2\\xa0\\xa8\\xb2\\xab\\x72\\x7d\\x86\\xf9\\x48\\x33\\x34\\xad\\x6e\\xac\\xc7\\x23\\xd5\\x96\\x06\\x2a\\x43\\x53\\xb2\\x04\\x6b\\xd0\\x55\\xbf\\x80\\x7b\\x82\\x35\\x41\\x76\\xe8\\xc2\\x8d\\x34\\x5f\\xe0\\x24\\xf0\\xd7\\x85\\x4c\\x06\\xb6\\x51\\xd6\\xff\\x3b\\x91\\x88\\x02\\xc0\\x76\\x1e\\xf6\\x64\\xd1\\xcd\\xef\\x43\\x0f\\xa1\\x83\\xc3\\x85\\x19\\x3e\\x51\\xef\\xa4\\xc8\\x1c\\x8f\\x3e\\xc2\\xa4\\x6f\\x9c\\xdd\\xd1\\x19\\xe4\\x32\\xb0\\x44\\x28\\x6e\\xdf\\x29\\xfd\\x11\\xbb\\x1e\\xbc\\xa9\\x39\\xb8\\x7e\\xfa\\xf6\\x66\\x17\\x72\\x04\\x86\\x43\\xb1\\xfe\\xaf\\xf1\\xd4\\x9c\\xbd\\x94\\x8f\\x29\\x92\\x8a\\x77\\x98\\x8c\\x0d\\x37\\x44\\x73\\xe5\\x28\\xc6\\x9b\\x48\\xf6\\x60\\xc0\\x8a\\x63\\x0a\\x1d\\x0d\\x3e\\x88\\xd0\\x20\\xd1\\xd1\\xdd\\x07\\x77\\x3e\\x0c\\x25\\x94\\x85\\xbd\\xeb\\x35\\x57\\x7f\\xb0\\xfc\\x61\\x64\\x73\\x7a\\x9c\\x6e\\x96\\x77\\x92\\x49\\xd0\\x35\\x40\\xf7\\xd5\\x13\\x4a\\x6b\\x0f\\x48\\xbd\\xc1\\xc1\\x79\\x08\\xf8\\x4c\\x3d\\x8a\\x5d\\x7f\\x84\\xd1\\x22\\x5d\\x9c\\x6f\\xc1\\x24\\x7f\\xc7\\xbb\\x54\\x1f\\x7a\\x76\\x3b\\x42\\x76\\x3b\\xc2\\x9c\\xb1\\x32\\x5c\\x49\\xa8\\xd9\\x83\\x35\\x77\\x6d\\x24\\xf9\\xd7\\x78\\xf5\\x37\\xbc\\x75\\x4d\\x8e\\x7d\\x21\\x4d\\xc5\\x39\\x5d\\xe0\\xd4\\xae\\x15\\x38\\x17\\x3a\\xd0\\x48\\xb3\\x31\\xfd\\xf6\\x9d\\x4e\\xc6\\x24\\x56\\xdc\\x3e\\x58\\xc4\\xd9\\x96\\x6d\\x08\\x01\\x1d\\x90\\x67\\x43\\xd6\\x73\\x42\\x70\\x68\\x30\\x22\\x87\\x9b\\x0e\\x27\\xf1\\x59\\x94\\x86\\x3c\\x69\\x10\\x17\\x77\\xee\\xb7\\x1a\\x33\\xf9\\x45\\xc9\\x0e\\xfb\\x33\\xc0\\x48\\x26\\x08\\x9a\\xa5\\xfd\\x68\\xe8\\xdc\\x5f\\x3e\\x40\\xfa\\xb4\\x04\\xa8\\xec\\x70\\x2e\\xd9\\x0d\\xbd\\x5c\\xcc\\x22\\x4c\\xe9\\xa3\\xdb\\xaa\\x59\\x4c\\x70\\x3d\\xa1\\x38\\xdb\\x1f\\x61\\x21\\xe8\\x21\\xf5\\x25\\xf0\\xdf\\x8c\\xd6\\x5e\\x1a\\x06\\x16\\x92\\x87\\xf9\\x1e\\x96\\x26\\xa3\\x43\\x23\\x71\\x94\\xe3\\xc3\\x1c\\x10\\x86\\x1f\\x60\\xc7\\x54\\x22\\x3b\\x25\\xba\\xcc\\x33\\x20\\xf9\\x7b\\x12\\xe4\\x63\\x82\\xf6\\x73\\x14\\xd4\\x53\\xfc\\xb3\\xbb\\xe4\\x97\\x2c\\xf3\\xe2\\x74\\x8b\\xd2\\x4a\\x11\\xcf\\x92\\x26\\x43\\x0d\\xb8\\xc1\\xc1\\xbb\\x59\\x86\\x08\\x79\\x65\\x26\\xb5\\x64\\xdd\\x0c\\xb7\\x8f\\xca\\x22\\x40\\x07\\x44\\x6e\\x57\\x89\\x6e\\xea\\xe0\\x05\\x2f\\x29\\xd2\\x67\\xa7\\x02\\xe4\\xaa\\x98\\xf0\\xb7\\xba\\x5c\\xf2\\xba\\xf9\\x81\\xba\\x1d\\x61\\x30\\x07\\xb6\\x07\\x54\\xbc\\xd8\\x31\\x51\\x3b\\xa3\\x8f\\xe4\\xce\\x28\\x2b\\x19\\x54\\x9a\\xd8\\x89\\xe3\\xda\\x4f\\xbd\\xd9\\xc2\\x1b\\x10\\xf2\\x89\\x72\\xf3\\x97\\xee\\x28\\x85\\x63\\x03\\x0d\\x47\\x96\\xc0\\x42\\x20\\x3f\\xad\\xdc\\xca\\xf4\\xa2\\xc0\\x6c\\x98\\xcc\\x67\\x9b\\xf4\\x3f\\x74\\xa2\\xa9\\x1f\\x6f\\xdd\\xa0\\x64\\x49\\xc6\\x99\\xcc\\x2a\\xa9\\x65\\x63\\xb9\\x9b\\x97\\xc4\\x38\\x31\\x6c\\x49\\x82\\x7e\\x0e\\x1c\\xdc\\x29\\xd6\\xe4\\xcd\\xc2\\xef\\x9d\\x05\\x50\\x19\\x9e\\x32\\xc2\\xa8\\x01\\xa2\\x5b\\x74\\x01\\x56\\xf8\\x5f\\x9b\\x1b\\x0a\\x4a\\xc5\\xa9\\xa6\\x4e\\x91\\xcc\\x9c\\x9f\\x19\\x30\\x49\\xa0\\xbe\\xf0\\xd4\\xae\\x59\\x01\\x9d\\x37\\x2c\\xa2\\x30\\xf6\\xa8\\xc9\\x33\\x50\\x3d\\x27\\x1f\\xee\\x0f\\x4c\\x8f\\xca\\x73\\xce\\x2b\\x5c\\x48\\xd8\\x12\\x2a\\x49\\xad\\x06\\xe8\\xde\\x93\\x68\\xd4\\xf9\\x6f\\x03\\xa5\\x1d\\x10\\x2b\\x44\\x77\\x83\\x54\\x47\\x61\\xf2\\x87\\x1d\\x3f\\xeb\\x2c\\x9a\\x4a\\x67\\xa7\\x9d\\xfb\\xf2\\x35\\x4d\\x16\\x06\\x5e\\xea\\xf1\\x76\\x7e\\xa8\\xdd\\xf5\\x10\\xe3\\x2d\\x76\\x67\\x7b\\x4c\\x41\\x39\\xfa\\xf6\\xaf\\xea\\x2f\\xc5\\x89\\x59\\xb6\\x0a\\xdc\\xc7\\x12\\xfc\\xef\\xed\\x57\\x27\\x75\\xd1\\xa5\\xd9\\xb5\\xb7\\x46\\xf1\\x71\\x6a\\x9e\\x28\\x53\\xc3\\x54\\x5e\\xac\\xd1\\x12\\x1b\\xc8\\x9e\\xfa\\x51\\xb2\\x28\\xdf\\xde\\x73\\x1a\\xee\\x11\\xe9\\x3b\\x95\\xe3\\x31\\x16\\xe3\\x5d\\x86\\x9c\\xb1\\x99\\x3e\\x1f\\xee\\xf3\\x71\\x3c\\x9b\\xf5\\x45\\x41\\x6e\\x6f\\xcd\\x11\\x5b\\x08\\xf5\\x55\\x3c\\xc1\\xf5\\xd4\\xeb\\x0a\\xf6\\x3b\\xa7\\x4e\\xcd\\xdd\\x21\\xf1\\xd9\\xaa\\x9c\\xff\\x4c\\x72\\xba\\x0f\\x0b\\xe2\\x32\\x2f\\x87\\x2b\\xe4\\xd1\\x4e\\xd0\\x49\\x92\\x47\\xdb\\x03\\x11\\x00\\x19\\x2b\\x7b\\x38\\x0f\\x1f\\xbe\\xa2\\x41\\xc7\\xd1\\xfd\\x13\\x91\\xa2\\x45\\x56\\xf4\\xb7\\xd2\\xea\\x6e\\x23\\xe6\\x12\\x68\\xfe\\xb0\\x01\\x40\\x8b\\x59\\x61\\x35\\x63\\xcb\\x50\\xfa\\x79\\x98\\xc1\\x9f\\x55\\xb9\\x80\\x10\\x2d\\xd8\\xf7\\x72\\x67\\x71\\x26\\x6f\\x50\\x65\\x15\\x78\\x82\\x95\\x9e\\x47\\x9b\\x32\\x16\\xfa\\xda\\x4c\\x8e\\x33\\x43\\x1d\\x09\\x9b\\xb9\\x48\\x8a\\xb0\\x1c\\x56\\x60\\xcf\\x49\\xd0\\xbb\\xb7\\x52\\xdc\\x3a\\xc4\\x64\\x0f\\x80\\xc4\\xae\\x7f\\xda\\xd1\\x22\\xcb\\x8c\\xa4\\x8f\\x02\\x2f\\xc4\\xb1\\x86\\x40\\xdb\\xf5\\xb2\\xe3\\xad\\x7d\\x83\\x82\\xef\\xcd\\x98\\x70\\x06\\x81\\xec\\x0c\\x17\\x73\\xc4\\x28\\xdd\\x7c\\x31\\xd6\\x52\\x59\\xaa\\x47\\x29\\xb7\\xbe\\x28\\x77\\x59\\xa8\\x04\\xdd\\xd2\\x1f\\x5d\\x1a\\xed\\x44\\x1a\\xed\\x98\\xee\\x68\\x1b\\x5c\\x8a\\xe2\\xe0\\x8b\\xd1\\x6e\\x68\\x6a\\xda\\x9d\\x2f\\x38\\x03\\x29\\xf8\\x1a\\x47\\x5a\\xda\\x39\\xde\\xe8\\xbe\\x26\\x45\\x68\\x0e\\xe6\\x5a\\x83\\x10\\x99\\x4a\\x4b\\xf8\\xb2\\x93\\x7f\\x62\\xe9\\x8e\\x50\\x8c\\xc8\\x6f\\x98\\x39\\x84\\x3d\\x39\\xcb\\xa3\\xb1\\x2e\\x64\\x55\\x62\\x14\\x03\\x41\\xb9\\x7b\\x42\\xd4\\x8e\\x3e\\x5b\\x2b\\x2b\\xe2\\x4f\\xd5\\xda\\x37\\xb3\\x19\\x54\\xe4\\x3f\\x59\\xe9\\x0f\\x73\\x13\\xd5\\x42\\xfe\\xed\\x86\\x1f\\xb8\\xcc\\x6d\\xa6\\xf2\\x87\\x59\\x50\\x63\\x74\\xeb\\xea\\xea\\x0e\\x11\\x21\\x99\\xd2\\x2d\\x09\\x7a\\xc1\\x52\\xc3\\x9a\\x97\\x78\\x30\\xdf\\x02\\x2b\\x4f\\x2c\\x7f\\x74\\x9d\\x84\\x30\\x5f\\x79\\x96\\x40\\xed\\x1f\\x22\\x3f\\xb9\\x66\\xff\\x15\\x12\\xfc\\x1b\\xb0\\x60\\xe4\\x87\\x42\\x7a\\x91\\xde\\x6c\\x19\\x43\\x90\\x6c\\x49\\x56\\xe7\\x0b\\x9c\\xaf\\x8c\\x3f\\x65\\x71\\x8a\\x5d\\x6b\\x22\\x34\\x93\\xdc\\x47\\xea\\x25\\xba\\xc8\\xdb\\x15\\xde\\x99\\x8f\\xfa\\xf4\\xd0\\x38\\x4b\\x96\\x50\\x33\\x0f\\x51\\xfa\\x3b\\x54\\x34\\xda\\x33\\x78\\xef\\xb8\\xf6\\x18\\xf3\\x01\\x0f\\x70\\xf2\\x54\\xfa\\xb0\\xfd\\xa9\\xc1\\x32\\x6f\\x0d\\x44\\x76\\x22\\x84\\xeb\\x3d\\x9a\\x59\\xdf\\xea\\x8b\\x03\\x95\\x1f\\xf6\\x60\\x9d\\x5d\\x3f\\x0f\\xbf\\x7d\\x7c\\x84\\x87\\x29\\xee\\x28\\x99\\x63\\xe6\\x86\\x7d\\x3b\\x27\\x05\\xc5\\xdb\\xd7\\x5c\\x59\\x2e\\x81\\x67\\xeb\\x43\\xb1\\x7d\\xf0\\x21\\x11\\xc1\\x68\\xc0\\x2e\\x31\\xa5\\x4e\\x96\\x7b\\x18\\xcd\\x49\\x65\\x83\\x4a\\x65\\x53\\x7d\\xe9\\xac\\x9c\\xe9\\x12\\xbc\\x1d\\x37\\xf9\\xfc\\x87\\x00\\xda\\xf7\\x53\\x7d\\xcb\\xbf\\xd8\\x5d\\x0b\\x4a\\x8d\\x1b\\x00\\x70\\x96\\xc7\\x55\\x5e\\x35\\x09\\xd3\\x22\\x58\\xcb\\xd7\\x92\\x59\\x49\\x06\\x80\\xa4\\x1c\\xce\\x72\\x84\\xc8\\x96\\x64\\x4e\\x85\\x7a\\xf4\\x63\\x83\\x02\\x2a\\x16\\x40\\x01\\x18\\xaa\\xe0\\xdf\\x84\\x18\\x33\\x00\\x8c\\x7e\\x2f\\xb9\\xbd\\x94\\x2e\\x69\\xbd\\xbf\\x9e\\x02\\x53\\x08\\x28\\x12\\x6e\\xa0\\xf4\\x09\\xac\\xeb\\x27\\xdd\\x25\\x15\\x9d\\x8e\\xcd\\xe2\\x50\\xc1\\xb3\\x80\\x5a\\x9f\\xdf\\xce\\x26\\xb1\\xa1\\x56\\x68\\xf6\\xe3\\xdb\\x2f\\x49\\x83\\x42\\x0b\\xa2\\xa3\\xd4\\x44\\xd5\\x5f\\x69\\xec\\x37\\x8d\\x7c\\x82\\xf6\\x00\\xbc\\x83\\x9d\\x41\\xa5\\x26\\xe3\\xe3\\x9a\\x9a\\xec\\x43\\x64\\xe7\\x8a\\x40\\x54\\x7e\\x86\\xcf\\xb7\\x18\\x83\\x03\\x7b\\xe4\\x99\\x81\\x46\\xb7\\xf4\\x62\\xe3\\x8e\\x4d\\xb8\\xa4\\xf3\\x14\\x94\\xa7\\x78\\xc1\\x14\\xd4\\x58\\x75\\x15\\x4a\\xc8\\x2f\\x85\\x3c\\x11\\x40\\x56\\x4f\\xe5\\xd7\\x95\\xa9\\x24\\x87\\x36\\x5d\\x03\\xc3\\xea\\xc0\\x90\\x0c\\x04\\xdc\\x03\\x66\\xce\\x0f\\xac\\x7e\\xe6\\x17\\xfb\\x89\\x7c\\xfd\\x6a\\x0f\\xbd\\xb9\\x0c\\x59\\xee\\xb0\\x22\\xf0\\x7a\\xa9\\xb6\\x26\\x4b\\x9c\\xc8\\x76\\x81\\xb1\\x25\\x08\\xe9\\xec\\x75\\xed\\x6e\\x34\\xb5\\x23\\x8c\\xf4\\xc4\\xf2\\x50\\x9d\\x91\\x04\\x95\\xd2\\x2c\\xe9\\x2a\\xe1\\xd3\\x1e\\x18\\xb5\\x63\\x74\\xa6\\x7e\\x0f\\xac\\x3c\\x3a\\xd5\\xf8\\x22\\x7d\\x76\\x99\\x0c\\x25\\x04\\x44\\x17\\xc3\\x64\\xc4\\x73\\x1d\\x99\\xeb\\x1b\\x26\\xf6\\xb7\\x1b\\xa2\\xfb\\x9b\\x85\\x02\\x83\\xf1\\x34\\xff\\xd5\\xdd\\x3f\\xd7\\x28\\x8e\\x10\\xcf\\x6e\\xe9\\x12\\x1e\\xed\\xd5\\x46\\x37\\xae\\x23\\x65\\xf1\\x6e\\x12\\xb3\\xc8\\x33\\xda\\xdd\\x2f\\x96\\x99\\xed\\x43\\x18\\x6e\\x2d\\x43\\xfb\\xaf\\xaa\\xac\\x45\\xfc\\x77\\xee\\xe2\\xd9\\x82\\xcd\\x40\\x20\\xef\\xe9\\xa9\\xc1\\xc8\\xd1\\x9d\\xdb\\x1e\\xcd\\x67\\x97\\x00\\x62\\xcb\\x54\\xe2\\x7d\\x51\\x18\\x91\\xa0\\xf3\\x81\\x91\\xc1\\x1f\\x45\\x31\\xa5\\xef\\x7b\\xbd\\x83\\xd0\\x98\\xed\\xf9\\x5f\\x0f\\xd1\\x5d\\x0e\\xde\\x54\\xe5\\x39\\xd7\\xb7\\x23\\xf2\\x57\\x7b\\xb5\\xc5\\x0c\\x89\\x07\\x9e\\x55\\x1c\\x32\\xcf\\x33\\x5c\\x09\\xfa\\xc0\\xd2\\x1d\\xa2\\x1f\\x6d\\x5b\\x95\\x67\\xb0\\x5b\\xa2\\x3c\\x43\\x98\\xf8\\xfd\\xea\\x29\\x26\\x68\\x28\\xd5\\x07\\xe2\\xc0\\xb6\\xd5\\x47\\xb2\\x51\\x76\\xd8\\x60\\x5d\\x6d\\x01\\x5f\\x94\\x67\\x2b\\xff\\x81\\x88\\xec\\x78\\x5d\\x49\\xa1\\x54\\x7e\\x60\\x77\\x16\\x7e\\xb7\\x7e\\xf6\\xda\\xb3\\xbf\\x0d\\x47\\xb8\\xb5\\x50\\x7c\\x6a\\xa9\\x73\\xca\\x61\\x1e\\x34\\xb6\\xc9\\x0f\\xcc\\x2a\\xcc\\x9f\\x23\\x65\\x4c\\x71\\x08\\x03\\xc6\\xfa\\xb2\\xae\\xcb\\x1f\\x7a\\xa8\\x3f\\x98\\x5a\\x60\\xaa\\xce\\xc5\\x47\\xcb\\x7e\\xcd\\x16\\x60\\xe0\\x81\\x1c\\xc5\\xd6\\x92\\x6d\\x46\\x49\\xe8\\x90\\xa2\\xe8\\xf0\\xb8\\x65\\xfd\\x8c\\x24\\x01\\x91\\x27\\x91\\x95\\x63\\xc7\\x2c\\x48\\xda\\xdc\\xd9\\x91\\x0c\\xbc\\xea\\x57\\x81\\xa1\\x88\\xf7\\xb7\\x4f\\xe3\\x44\\xa2\\xe8\\x70\\xb2\\xf3\\xb8\\x40\\x15\\xe8\\x4d\\x88\\xcb\\x90\\x9f\\x62\\x5d\\xc8\\x96\\x25\\x0e\\x0c\\x97\\x22\\x7b\\x2f\\xa1\\x27\\x14\\xcc\\xb0\\x79\\xd9\\x98\\xd5\\xfd\\x78\\x76\\xba\\x7f\\xbe\\x15\\xea\\x0f\\xb1\\x20\\xc5\\xe1\\xf0\\xa5\\xae\\x8d\\x14\\x57\\x9b\\x82\\x2b\\xa3\\x3c\\xac\\x4f\\x0e\\x07\\xcc\\x17\\x3f\\x80\\x30\\x2b\\xd9\\x78\\x6a\\x3b\\xf1\\x97\\x14\\x02\\xff\\xeb\\x58\\xe6\\x8d\\x25\\xb4\\xf9\\xe2\\x98\\xbb\\x63\\x7e\\x73\\xa7\\xee\\x94\\x2e\\x01\\xeb\\xf9\\x7d\\x89\\xf3\\x50\\x45\\xe7\\xe6\\xfe\\x72\\x57\\x25\\x0b\\x1e\\xf7\\xb1\\x46\\x7e\\x26\\xe8\\x8d\\x83\\x40\\xa0\\x32\\xeb\\xdc\\x3b\\x51\\x8b\\x8f\\x23\\x0d\\x95\\x3a\\x5a\\x1c\\x84\\x6c\\xb6\\xc1\\xbe\\x26\\x16\\x9e\\xe9\\xa2\\x1b\\x6f\\x83\\x42\\x16\\xe2\\xe8\\x9b\\x1f\\xeb\\xfa\\x4d\\xe4\\xa1\\x3a\\x48\\x16\\xf6\\xf8\\xa2\\x34\\xa3\\x7e\\x67\\xa9\\x68\\x6b\\x7f\\xa1\\x3c\\xac\\x87\\x9e\\xc7\\x3e\\x32\\xa6\\x19\\x22\\xff\\x48\\xb2\\xba\\x0f\\xf1\\xcf\\xf5\\x9e\\x5c\\xb0\\x33\\x03\\x93\\xc6\\xfc\\xc0\\x4c\\x0c\\x23\\x67\\x05\\xdd\\xdb\\x40\\x68\\xfd\\x96\\xa0\\x21\\x9e\\xdf\\x77\\x06\\xea\\xbb\\xfa\\x0e\\xbd\\x5e\\x4a\\xb4\\xe1\\x9d\\x38\\x81\\x31\\xb5\\x0c\\x15\\x2a\\x49\\x36\\xe6\\x77\\xa3\\xfe\\x82\\x97\\x01\\x95\\x3d\\x31\\x25\\x62\\x4d\\xe7\\xbf\\x1b\\xae\\xf0\\x88\\xda\\x57\\x82\\x26\\xe1\\x9d\\x77\\x89\\xc6\\xeb\\x5e\\x8d\\x32\\xc9\\x20\\x30\\x58\\xeb\\xcb\\xfa\\xbe\\xef\\xe7\\x61\\x8e\\x5d\\xa6\\xf1\\x22\\x09\\x93\\xa3\\xa9\\xbe\\x19\\xbf\\x4b\\xa7\\x78\\xe8\\x0d\\x13\\x5a\\xde\\xd9\\x19\\xf9\\x79\\x08\\xeb\\x01\\x5d\\x41\\x5b\\x46\\x16\\x6d\\xc4\\xd7\\xd7\\x12\\xfa\\x80\\xd3\\xa3\\x70\\xa0\\xe3\\xa7\\xb6\\x2a\\x4f\\x13\\xa1\\x0d\\xbe\\xe1\\xa2\\x85\\x43\\x70\\x88\\x51\\x6f\\x8d\\xe9\\xbf\\xf3\\x25\\xab\\xcc\\x6f\\xfe\\x72\\x5a\\x17\\x4c\\xf8\\x32\\xd8\\xc6\\xd5\\x22\\x79\\x18\\x1e\\xe4\\x31\\x52\\x8c\\xf3\\x27\\xec\\xc0\\xef\\x65\\x6f\\xfc\\x11\\xf2\\xa3\\x36\\xef\\x81\\x83\\x8b\\x2d\\xe6\\xf9\\xf7\\xdb\\xd0\\x91\\x61\\xbb\\x71\\xf0\\x64\\xc7\\xef\\xa3\\x4c\\xfb\\xbd\\xf3\\xc2\\xfc\\x2a\\x66\\x71\\x1f\\x21\\xeb\\x2e\\x09\\x44\\xbd\\x80\\x2d\\x14\\x00\\x1d\\xfc\\xe5\\x68\\x75\\x79\\x78\\xc8\\xc1\\x2f\\x9b\\xdd\\x3e\\x68\\x72\\x98\\x98\\x14\\x3c\\xef\\x45\\xf0\\xad\\x23\\xfc\\xa8\\xfc\\x54\\xfb\\xe9\\xca\\x94\\xdf\\x0a\\x05\\xcb\\xba\\x7c\\x77\\x33\\x43\\x62\\x33\\xf9\\xd9\\x64\\x32\\x8f\\x49\\x09\\xe1\\xe9\\x2b\\xdc\\x9a\\x3d\\x1e\\xb8\\x4b\\x4c\\xb0\\xc2\\x01\\xec\\x86\\xd4\\x53\\x1a\\x39\\x81\\x76\\xc6\\x4c\\x51\\x49\\xaa\\x04\\xa0\\x1b\\x24\\xf5\\x1a\\x3f\\xe4\\x94\\x27\\xbc\\x2c\\x51\\xf1\\x8e\\x32\\x27\\x46\\x51\\x8c\\x48\\xe9\\x63\\xe8\\xd6\\xc0\\x6c\\x25\\x1a\\xdf\\x51\\x2a\\x47\\x54\\xe2\\x27\\x65\\x86\\x58\\x5b\\x12\\x2b\\x1b\\x83\\xab\\x45\\x11\\xe8\\x18\\x98\\x29\\x9d\\x5f\\x41\\x55\\xa6\\xcc\\x3c\\x00\\x2c\\xff\\x7a\\xc5\\x97\\xa5\\x9a\\x69\\x2e\\x31\\x29\\xf8\\xf7\\x73\\x56\\x53\\xb3\\x1a\\xcf\\x12\\x99\\x03\\x36\\xf9\\x6a\\x71\\x8a\\x75\\x2d\\xaf\\x5d\\x6e\\x5a\\x39\\x0f\\xff\\x22\\x53\\x24\\x6f\\xa2\\x56\\x57\\x9a\\x8a\\x32\\xe7\\xf7\\x2e\\xc2\\x6f\\xb6\\x87\\xb2\\x8a\\xe0\\x52\\x12\\x99\\x2e\\x69\\xda\\x8f\\x8c\\x97\\xdf\\x6b\\xf9\\x36\\x77\\xb4\\x95\\xa6\\x7b\\x4d\\x8e\\x85\\x25\\xfb\\xb2\\x0d\\x09\\x54\\xa6\\x80\\x66\\x3f\\x64\\x0b\\xed\\xe6\\xa8\\x8f\\x79\\x32\\xc1\\x89\\x2e\\xb6\\x36\\xc5\\xd0\\xda\\x8f\\xdf\\x74\\xee\\xaa\\xb5\\xc2\\xa4\\xcb\\x6b\\xd2\\x6e\\xcb\\xff\\xe6\\x28\\x93\\x5d\\xb9\\xb5\\x7d\\x4f\\x8c\\xaa\\xa7\\xe4\\x77\\xb8\\xf1\\x65\\xff\\x0a\\xe9\\xe2\\x5f\\x1c\\xbb\\x20\\xf3\\x8d\\x86\\x78\\x7f\\x71\\xda\\xae\\x08\\x7c\\x31\\xb6\\x5d\\x74\\x7f\\xc8\\x6f\\x70\\xc4\\xbb\\x38\\xe6\\x05\\x87\\xb2\\xc3\\x95\\xba\\x44\\x17\\x97\\xa4\\x99\\x3c\\xad\\x3a\\xac\\xc7\\x68\\x7f\\xae\\x3e\\xb2\\x95\\xf5\\xfb\\xab\\xcd\\xe4\\xee\\xca\\x1d\\x14\\xf6\\x84\\xad\\xa6\\x8c\\x12\\xa8\\x74\\x7f\\x12\\xcf\\xef\\x73\\xf9\\x5f\\xdb\\x2b\\x9b\\xde\\xb3\\x27\\x3c\\xc9\\x0b\\x35\\xca\\x32\\xfe\\xf3\\xad\\x96\\x2f\\x42\\x32\\x05\\x84\\x9a\\xa8\\xca\\xdf\\x73\\xf9\\x81\\xc2\\x07\\x45\\x9a\\x60\\x1e\\x4d\\x02\\x81\\xa0\\xfc\\x33\\xa2\\x1e\\x16\\x6e\\x88\\x36\\xdc\\x19\\x9a\\xd1\\xc6\\x4a\\x2b\\x35\\xad\\xd5\\xef\\x33\\x6b\\x7a\\xdc\\x1d\\x58\\x57\\x7e\\x8e\\x50\\x25\\x9a\\xcd\\x2d\\xe4\\xe4\\x98\\x97\\x08\\xbb\\xe9\\x7a\\x22\\x8a\\xd9\\x69\\xa6\\x45\\x82\\x19\\xa6\\xaf\\xb8\\x5e\\x44\\xba\\xa6\\x21\\xa0\\xdc\\x34\\xc9\\xee\\x89\\xd2\\xc7\\x8b\\x9e\\x1d\\x40\\xa1\\xf6\\x73\\x26\\xfd\\x27\\xdd\\x47\\x3c\\x3d\\xcd\\x3c\\x5f\\x76\\x19\\xfd\\xc4\\xc0\\x21\\xa0\\x1f\\xcf\\xe2\\x5b\\xa8\\x9e\\xab\\xaf\\x1a\\x3f\\x44\\xa6\\x2f\\x48\\x8c\\x2b\\x86\\x12\\x69\\x62\\x47\\x6a\\x97\\x01\\x80\\xa0\\xe3\\x64\\x0f\\xce\\x91\\x84\\xca\\x74\\x42\\x4b\\xad\\x14\\x8b\\xef\\xa4\\x0a\\x6a\\xd8\\x33\\x3c\\x22\\x17\\x13\\x24\\xac\\xb7\\x56\\xd5\\x1f\\x47\\xe4\\x0d\\x2e\\xf5\\x6a\\x8e\\x24\\x1c\\xaf\\x17\\x62\\xbc\\x98\\xa8\\x8b\\x51\\x6f\\x8a\\xa0\\x29\\x1b\\x56\\xf9\\xf1\\x25\\x18\\x15\\xb4\\x9a\\x20\\xba\\xe3\\xbf\\x7b\\x41\\x3e\\x97\\x76\\x75\\x23\\xfd\\xef\\x17\\x7b\\x4a\\xcc\\x9c\\x03\\xfd\\x8e\\x2f\\x01\\x40\\xb0\\x56\\x93\\xe4\\x7c\\xd9\\xa3\\x86\\xda\\x0c\\x2a\\x8d\\xb0\\xc5\\xa1\\xd1\\x7e\\xbf\\xa8\\x96\\x06\\xb7\\xee\\xc2\\x97\\xf2\\xe3\\xeb\\x8b\\x2e\\x8c\\x51\\xc5\\x37\\xbe\\x2e\\x4c\\xb4\\x5e\\x12\\xf9\\xc3\\x98\\x14\\x41\\x12\\xd9\\x9c\\xea\\x28\\xa3\\xa4\\xa2\\x39\\x10\\x47\\xda\\xca\\xd3\\x7b\\x22\\xe9\\x86\\x41\\xe5\\x8e\\xe8\\xf5\\x2a\\xbe\\x33\\x9c\\x1b\\x58\\x0e\\x0d\\xb1\\x0d\\x47\\x26\\xcd\\x72\\x29\\x83\\x5b\\x9a\\x2b\\xa0\\x79\\xf5\\x6e\\x06\\x4d\\xd7\\xd4\\x66\\xca\\x8c\\x67\\x18\\x63\\xb9\\x2f\\x0b\\x74\\xf2\\x6f\\x13\\x4b\\x6e\\x44\\xca\\xcd\\xe7\\xea\\xe4\\x8b\\xd1\\x51\\xe7\\xf3\\xc7\\x8c\\x46\\x6a\\x8e\\xa7\\x08\\x40\\x38\\x4b\\xa9\\xef\\xb3\\x16\\x6d\\xa6\\x37\\x6d\\x53\\xeb\\x44\\x72\\x95\\xf5\\x15\\xff\\x7d\\x3b\\xf9\\x86\\xa1\\x4c\\xd3\\xd2\\x54\\x79\\xab\\x49\\x31\\x5f\\x2f\\x89\\x65\\xec\\x96\\x65\\x73\\x10\\x9e\\x61\\xc7\\x81\\xb9\\x2f\\x48\\xfa\\x71\\xfd\\x36\\x42\\x25\\xee\\xae\\x82\\x65\\x21\\x8f\\xf6\\x2c\\xd8\\xcc\\x10\\xb3\\xe2\\xe4\\x8b\\xa9\\xc4\\x3f\\xe0\\x37\\x6d\\x15\\x3d\\xe9\\x92\\xcc\\x2f\\x78\\x49\\xd1\\x82\\xbe\\xb9\\x7d\\xb6\\x22\\xf4\\x29\\x62\\xbf\\xb6\\xf1\\xc5\\x79\\x8a\\x7f\\xba\\xce\\x18\\x31\\x07\\xd7\\xcd\\x48\\x79\\xd9\\x8c\\xce\\x76\\x5d\\x1b\\x72\\xe8\\xd0\\x25\\xb8\\x45\\xd2\\x9b\\x84\\x9b\\x70\\xab\\xd8\\xf5\\x8f\\xeb\\x2a\\x8d\\xad\\x39\\x96\\x2d\\xac\\x33\\xb8\\xbd\\x01\\x33\\xbc\\x10\\x26\\x0e\\x7a\\x40\\x71\\x88\\x3c\\xbd\\xee\\xd3\\x3d\\xd5\\x02\\xbe\\x6b\\x0a\\xbb\\x87\\xcc\\xcb\\xc4\\xee\\xba\\x29\\xb2\\x26\\xae\\xdc\\x01\\xa2\\xc5\\xad\\xc4\\x21\\x98\\x8a\\xf4\\x4d\\xee\\x6e\\xa0\\x95\\xa9\\x35\\x57\\x00\\xe5\\x8e\\x96\\xe7\\x46\\xfa\\x9a\\x9c\\x62\\x58\\x89\\xad\\x48\\xa6\\x8e\\x05\\x8c\\xdc\\x8d\\x16\\x83\\x91\\xa4\\x5b\\x02\\x9c\\x63\\xcb\\x5e\\x1d\\x54\\x9a\\xdd\\xb8\\x27\\xdd\\xaf\\x35\\xc2\\x72\\x37\\x46\\x8a\\x83\\xd8\\x68\\x0f\\xe0\\x79\\xc8\\x20\\x6d\\x74\\x57\\x76\\x4f\\xd3\\x7d\\x7b\\x72\\xd5\\x81\\x7b\\x39\\xca\\x42\\x43\\x25\\x16\\xdb\\xe0\\x21\\x2c\\xd9\\x4a\\x3d\\xc3\\xf8\\x51\\x4e\\x85\\x5d\\x75\\xd0\\xb3\\x18\\x81\\x61\\x8e\\xee\\x6b\\x1f\\x30\\x5d\\xfe\\x3c\\xd2\\x28\\x49\\x1f\\x19\\xde\\xe8\\xcf\\xea\\xb3\\x33\\x80\\xce\\x3e\\xf6\\xfc\\xb1\\x4f\\x26\\x77\\xb8\\x35\\x5e\\xe1\\x92\\x2d\\xfd\\xde\\x35\\x8e\\xe7\\x4e\\x1a\\xf0\\x3a\\x3b\\xef\\xbf\\x5f\\xab\\x9c\\x0b\\x57\\x7d\\xd4\\xb4\\x11\\x97\\xd1\\x6c\\x86\\x50\\x0d\\x1f\\x6b\\x70\\x86\\xfb\\xfd\\xcb\\x85\\xa8\\xc9\\xd7\\x5d\\xfe\\xb5\\xf1\\x27\\x37\\xa6\\x1f\\xf1\\x00\\x6e\\x57\\x9c\\x6e\\x01\\x2e\\x01\\x27\\x62\\xed\\x11\\x99\\xfe\\xa9\\x8a\\xb4\\x8a\\xbc\\x88\\xa8\\xa9\\x4d\\xaf\\x33\\xa6\\xa3\\xc5\\x03\\x74\\xb4\\xad\\x4f\\x2a\\x5f\\x35\\x9d\\x53\\x69\\xc7\\xaa\\x2b\\x24\\x93\\xec\\xa2\\x3b\\xc3\\xd6\\x8f\\xb6\\x6d\\x91\\xc4\\x33\\x70\\x18\\xac\\x4e\\x61\\x39\\x04\\x6c\\x10\\xda\\x02\\xa4\\xd9\\x72\\x07\\xd7\\xde\\xdd\\xd5\\xad\\x10\\xc4\\x2b\\x97\\xec\\x7c\\x2d\\xce\\x66\\xb5\\xf4\\x9c\\xf0\\xb1\\xd9\\xf8\\x36\\x15\\xca\\x6a\\xdb\\xc2\\x73\\x57\\x07\\x40\\x89\\x68\\x42\\x5c\\x33\\x98\\xed\\x7e\\x8e\\x8b\\xe8\\x62\\x8f\\x5c\\x1d\\xad\\xbb\\x29\\x9d\\xcc\\x95\\x26\\x18\\xf4\\x60\\xa2\\xb7\\xe7\\x59\\xe6\\x29\\x03\\xf9\\x53\\xa4\\x20\\x32\\x8b\\x9d\\x2d\\x56\\x4d\\x1f\\xde\\x28\\xe7\\xab\\xc9\\x49\\xa8\\x60\\xf6\\x55\\xee\\xdd\\x98\\x83\\x2a\\x19\\x80\\x8e\\xee\\x9e\\xec\\xbf\\xaa\\xc6\\x3d\\xe4\\xc4\\xa8\\x74\\x77\\x7f\\xd7\\x56\\xaf\\x2e\\x9d\\x19\\xef\\x04\\x27\\xbd\\x5b\\xce\\x7a\\x93\\xed\\x0f\\xb1\\x60\\xba\\xe5\\x98\\xdc\\xa0\\xc6\\x5b\\xdf\\xdd\\x2f\\x70\\xea\\x6c\\x9c\\x21\\xee\\xf2\\x3e\\xbb\\xca\\x21\\x6d\\xcc\\xd7\\x30\\xd9\\xf1\\x19\\x28\\x9b\\x08\\xfd\\xae\\x77\\x4f\\x7c\\x98\\x5a\\x63\\xeb\\xf6\\x54\\xe1\\x66\\x5a\\xcc\\xcc\\x74\\xdf\\x6e\\x8d\\x29\\xef\\xca\\x84\\x9a\\xd1\\x5b\\xbb\\x08\\x81\\x31\\x23\\xd1\\xf9\\x59\\x2c\\xe8\\x8f\\x1f\\x21\\xc0\\xd7\\x1f\\x92\\xaf\\x36\\x43\\xe4\\x9d\\xb4\\x49\\x2d\\x3c\\x32\\xea\\x18\\xd1\\xbf\\x6c\\x67\\x57\\x99\\xd0\\xf2\\x93\\x62\\xb2\\x5f\\x94\\xc9\\x3a\\xbf\\x19\\xd0\\xbd\\x4f\\xb0\\xad\\x33\\x8c\\xd6\\xac\\xad\\x0d\\xde\\x53\\xbb\\x7b\\xbc\\x28\\x17\\x63\\x14\\xf4\\x0d\\x4e\\x64\\x46\\x53\\xcd\\x89\\xd7\\xb3\\x75\\x30\\xe3\\xa2\\x42\\x4c\\x74\\xf6\\x41\\xa0\\x58\\xa8\\xa5\\x3c\\xf4\\xfb\\xa4\\xd9\\x29\\x3e\\x3b\\x44\\xaa\\x2d\\xfd\\x28\\x58\\x95\\xe4\\x3c\\x5f\\x3a\\x69\\x1e\\xf6\\xb9\\x8b\\xc1\\x95\\xe9\\x60\\x59\\xc9\\xe4\\x38\\x07\\x8a\\x87\\x4e\\x2f\\xd5\\x09\\x19\\xc6\\xe6\\x60\\x11\\xd0\\xdf\\x3d\\x50\\x2c\\xe5\\xa8\\x36\\xb0\\xf7\\x0a\\x48\\xe8\\x63\\x08\\xd8\\x0a\\xb1\\x82\\x89\\x9c\\x20\\x59\\x8a\\x47\\x43\\xef\\x64\\xeb\\xfd\\xc9\\xbe\\x6c\\xbb\\x7e\\xbb\\x23\\xe4\\xeb\\x0b\\x7a\\x01\\xd1\\xfa\\xb7\\x7c\\x58\\x88\\x59\\x68\\x77\\x54\\xe0\\xe0\\x93\\x98\\x51\\x49\\x09\\x1a\\x72\\xc0\\xb8\\xf7\\x60\\xd4\\x8e\\x74\\xe8\\xb7\\x15\\xdf\\x19\\xe5\\x2f\\x58\\x0a\\x55\\xd0\\xab\\x0e\\x2e\\x9b\\x0a\\xa7\\xd8\\x89\\x66\\x90\\x4c\\xc4\\xe6\\x8e\\x2d\\x3a\\xd7\\x61\\xde\\xdf\\x06\\x89\\x36\\xd1\\xa4\\xf8\\x93\\x37\\x48\\x0b\\x13\\x9e\\x6d\\x5e\\x18\\x06\\x67\\x06\\x2a\\x3f\\xfa\\x90\\x1d\\x00\\xb7\\xfd\\xd8\\x2a\\x12\\xf9\\x1a\\x79\\x28\\xe3\\x92\\xe4\\xa4\\x59\\x96\\x7d\\xf5\\xef\\x28\\xe8\\xc8\\xe2\\x33\\xba\\x04\\xb1\\x05\\x6a\\x5e\\x7c\\xea\\x7d\\x81\\x13\\xf5\\xdb\\xc5\\x7c\\xf5\\xe7\\x61\\x4f\\xc7\\xfb\\x51\\x61\\x54\\x70\\xd0\\x1e\\x62\\x8d\\x8f\\x17\\x0c\\x42\\x91\\x34\\x04\\xef\\x53\\xc5\\xe3\\x76\\xc7\\x22\\x8c\\xe8\\xaf\\x8d\\x33\\xc5\\x25\\x29\\xe6\\xb8\\xe2\\x0a\\x97\\x8d\\x2c\\xa4\\x89\\xfd\\xba\\x63\\x54\\xfd\\x58\\x0f\\x2f\\x77\\x55\\xf3\\xf1\\xbe\\x76\\x38\\xbe\\x33\\x83\\xc9\\x7c\\x2d\\x05\\x7d\\xde\\x73\\x39\\x37\\xa4\\xf9\\x61\\x4d\\xe8\\x0f\\xb8\\x25\\x9c\\xe7\\x9b\\x24\\xc3\\x9d\\x45\\xdb\\x38\\xe2\\xf9\\x7d\\xf4\\xfb\\x2a\\xcf\\xb4\\x7c\\x2a\\x90\\xdb\\x8b\\x5e\\x3b\\xde\\x26\\x7f\\xec\\x60\\x53\\x87\\x6f\\x1d\\x5c\\xe0\\xe5\\x34\\x89\\xae\\x10\\xe2\\x48\\x7b\\x73\\x6c\\x2f\\x7b\\xc4\\x48\\x91\\xaf\\xff\\x02\\x74\\x65\\x14\\x18\\xbd\\xee\\x4d\\xfe\\xe3\\x3b\\x01\\x2e\\x04\\x34\\x5d\\xb6\\x03\\xb3\\xde\\x2d\\xbd\\x94\\xc4\\x1d\\x95\\xc7\\x44\\xcd\\xde\\x9a\\x7a\\xdb\\xf3\\xb5\\x27\\xd1\\x52\\x03\\x3f\\xd8\\xb6\\x12\\x8a\\xcf\\x37\\x03\\x42\\x9d\\x0e\\x08\\xaf\\x8d\\x3e\\xbc\\xaf\\x29\\xef\\xb6\\x7d\\x2c\\xb5\\xfd\\x44\\x1b\\xfc\\xb5\\x08\\xd5\\x29\\xa2\\x90\\xdc\\xa6\\x61\\x4b\\x83\\x41\\xfd\\x36\\x8f\\x87\\x6a\\x95\\x60\\x73\\x6b\\x47\\x18\\x96\\x00\\x55\\x79\\x76\\x60\\xb3\\xae\\xf4\\x67\\x88\\xe8\\x76\\xb6\\xfd\\xea\\x9a\\x54\\x7f\\xad\\xd7\\x33\\xce\\x92\\x38\\xdd\\xfe\\x0b\\xd3\\x7d\\xfb\\xf2\\xf5\\xc4\\x4d\\x45\\xd9\\xe3\\x1b\\xd3\\x6f\\x5a\\x4f\\x0a\\xdb\\x0e\\x81\\xf0\\x65\\xcf\\x73\\x6d\\xcb\\x9a\\xff\\x44\\xed\\x1f\\xbb\\xd7\\x97\\xcc\\xa5\\xc9\\xbd\\x65\\xe2\\x39\\xc8\\x49\\x80\\xec\\x2b\\x42\\x12\\xc9\\x19\\x4a\\xbf\\x2f\\xa1\\x3b\\xcd\\xa6\\xf2\\x57\\x38\\x5e\\xf4\\xc4\\xf1\\xb1\\x3c\\x9a\\xc1\\x8d\\x1a\\x02\\x4b\\x72\\x89\\xc3\\x39\\x4a\\x3b\\xbd\\x9c\\xf0\\x51\\x3b\\x0b\\xa1\\x0a\\x7a\\x09\\x55\\x99\\x37\\x96\\x83\\x42\\xf9\\x8b\\x12\\xdc\\xfb\\x45\\x7e\\xad\\xcc\\x12\\xfe\\xdd\\x69\\xf5\\x02\\x95\\x21\\x5c\\x47\\x8b\\x61\\x85\\x89\\x23\\x81\\xc3\\xde\\xf8\\x96\\x42\\x5d\\x19\\xa6\\x3c\\x44\\x77\\xaa\\x1d\\xf9\\xd0\\xc5\\x59\\x4d\\xb2\\xe3\\x7d\\xfd\\xdd\\x0c\\xdf\\xbb\\xd0\\x6d\\x9b\\x23\\xf0\\x63\\xf5\\x97\\x47\\xb1\\x8f\\xcf\\x92\\x00\\x4b\\xe3\\xf2\\x83\\x8a\\xd7\\x04\\xdd\\xd5\\xc8\\xfc\\xc1\\x71\\x23\\x50\\x0b\\xbd\\xef\\xea\\x0a\\xbb\\xfc\\x79\\x88\\x63\\x1c\\x74\\x4e\\xc5\\x55\\x01\\x0f\\x61\\xea\\x78\\x62\\x2b\\xca\\x0b\\xeb\\x4b\\xb4\\x7c\\xbf\\x0f\\xb0\\x6c\\x93\\x1e\\xed\\x62\\xaf\\x95\\xc0\\xc1\\xd5\\x5f\\x69\\x60\\x89\\x04\\xed\\x7f\\xed\\x60\\x7c\\x89\\xfa\\xa6\\x4d\\xbe\\x26\\xea\\xc8\\x41\\x8f\\x53\\x79\\xb6\\x35\\xd6\\x00\\xfd\\x11\\xb9\\xc4\\xec\\xa4\\x15\\x87\\xcc\\xea\\x13\\x52\\x90\\xb6\\xa3\\x74\\x7f\\xa2\\x1d\\x39\\x16\\x38\\x74\\x35\\x1a\\xad\\x8c\\xea\\xb4\\xfd\\x84\\xae\\xc8\\xc2\\x6f\\xc4\\x7f\\x02\\x90\\xfa\\xf8\\xb5\\x38\\xb2\\x9b\\x5b\\xb7\\xd6\\xa6\\x28\\x73\\x0a\\x35\\x27\\xc9\\x30\\x54\\xfe\\x92\\x61\\x9e\\x00\\x41\\xd3\\x7f\\x0f\\x77\\x49\\x24\\x85\\x99\\xd2\\xc7\\x28\\x66\\xa3\\xca\\x43\\x12\\x44\\x9d\\x0d\\x47\\x8c\\x38\\xd2\\x2d\\x37\\xc4\\x1f\\xb3\\xc6\\x78\\x1e\\x78\\x52\\xf0\\xc6\\xa8\\x4d\\x6b\\x43\\xce\\xa0\\xfb\\x98\\x5e\\x0c\\x11\\xdd\\x5a\\xf8\\xd5\\x03\\xdc\\xe2\\x4b\\x89\\x29\\x79\\x02\\xe0\\x91\\xf2\\x25\\x8a\\xb0\\xc7\\x77\\xdc\\xea\\xe8\\x21\\x33\\x47\\xf3\\x37\\x8e\\x08\\xc5\\x5b\\x97\\x4e\\x64\\x79\\xf1\\x97\\x47\\xf9\\x2b\\x13\\xa1\\x72\\xa4\\xf0\\x37\\x50\\x65\\xe9\\xbd\\x99\\x43\\x7e\\x8e\\x88\\xe3\\x64\\xc7\\xeb\\x61\\x5f\\xc4\\xef\\x8a\\xd4\\x60\\x83\\xad\\x02\\xe1\\xcb\\x5b\\xb4\\x01\\x81\\x72\\xa9\\x37\\xab\\x6a\\x7c\\xe4\\xa1\\x8a\\xde\\xd7\\xf2\\x57\\x51\\x7b\\x70\\x21\\x50\\x9a\\xcd\\x5b\\x7f\\x73\\x0b\\xb4\\xab\\x1b\\x3b\\x67\\x99\\xa2\\x11\\x9b\\x7a\\x62\\xb7\\xf3\\x97\\xc1\\xeb\\xa7\\x1b\\x5c\\xe6\\x18\\x7d\\x53\\x98\\xb8\\xd0\\x7e\\x9c\\x41\\xa3\\xee\\x40\\x91\\x49\\xf0\\xde\\x2e\\x44\\xab\\xb0\\x63\\xe1\\xdd\\x85\\xc1\\xf5\\xc4\\xcf\\x31\\xbf\\x23\\x67\\xbc\\x57\\x13\\x95\\xb7\\x76\\x15\\x2a\\x6c\\xc7\\x6d\\x9d\\xca\\x55\\xeb\\xf0\\xce\\x73\\x1e\\x20\\x87\\x9a\\x39\\x44\\x2b\\xf2\\x3d\\x5d\\x18\\xe4\\x86\\xda\\x32\\x8e\\x9f\\x64\\x41\\x6c\\x68\\x4a\\xbd\\xfb\\x15\\xe9\\x14\\x0d\\x79\\xb3\\xe2\\x0c\\xce\\x1b\\xe7\\x2f\\x4e\\x5b\\x5b\\xa8\\xa2\\xd2\\x33\\x44\\x18\\x85\\xff\\xe5\\xbe\\xe1\\x0c\\xd7\\xf2\\x74\\x1e\\x22\\x87\\x5d\\x66\\x4a\\x11\\x94\\xc1\\x87\\xbf\\x57\\x79\\x84\\xdc\\xc0\\x3c\\xc5\\xc0\\xc8\\x2d\\x4c\\x77\\x14\\xfa\\x84\\xd4\\x95\\xa1\\xda\\xb8\\x93\\xd0\\x07\\xec\\x0c\\x28\\x91\\x4b\\xad\\x5f\\x42\\x88\\x7a\\x61\\x73\\x7f\\x96\\xf4\\xd6\\x92\\x21\\x8f\\xef\\x0f\\x65\\xd5\\xe7\\xcf\\xe3\\x17\\xa2\\x38\\xa2\\x85\\x65\\x35\\xf5\\x18\\xd3\\xdd\\xe9\\x66\\xf3\\x7b\\xda\\x1e\\xff\\xc1\\x4d\\xa6\\xbe\\x08\\xb2\\x08\\x4f\\x75\\xca\\x34\\x8d\\x1d\\x4c\\x85\\xa2\\x98\\x1d\\x4b\\x7f\\xf9\\xce\\x6d\\x34\\xf1\\x99\\x91\\xbc\\x0c\\xea\\x0b\\x4f\\xd9\\xa4\\xc6\\x55\\xe3\\x59\\x76\\x71\\x92\\x1e\\xfb\\x54\\x56\\x42\\x72\\x04\\xf6\\x5b\\xeb\\x22\\x03\\xdd\\x90\\x18\\x29\\x56\\xe1\\x28\\xdd\\xac\\x38\\x3a\\xd9\\x9f\\xd7\\xcf\\x8f\\x55\\x3d\\xf9\\xb9\\xf1\\xf6\\xe3\\xe3\\x14\\xf9\\x72\\x5f\\xbe\\x77\\xd9\\x18\\x51\\xf8\\x12\\x61\\xe7\\xdf\\xa0\\x80\\x51\\x69\\xea\\x03\\x53\\x2f\\x79\\x93\\xb5\\x8d\\x1e\\x4d\\xe3\\xd6\\x92\\xa2\\xb1\\x45\\x55\\xd2\\x4a\\xc7\\xd9\\x17\\x45\\x50\\x28\\xd3\\xd9\\xc2\\x6b\\x20\\x5f\\x0c\\x0a\\x1d\\xbb\\xe1\\xd8\\x3f\\x62\\x6b\\x6d\\xa3\\x25\\x84\\x34\\x1d\\x39\\x09\\x66\\xb3\\x63\\x23\\x2a\\xfa\\x17\\xe9\\xe2\\xf8\\x60\\x27\\xf6\\xa7\\x1d\\x4d\\x56\\x39\\x02\\x21\\x99\\x72\\x45\\x20\\x8a\\xef\\xf4\\x3c\\x5e\\x9a\\x65\\x99\\x27\\x90\\x43\\x24\\x5b\\x96\\x5b\\xbf\\x21\\x09\\x65\\x0e\\x17\\x5a\\x40\\x6a\\xe7\\x04\\xa2\\xd8\\x52\\x01\\x92\\xc0\\x7b\\x52\\xe2\\x91\\x26\\xa6\\xf3\\x4d\\x93\\xf1\\x8f\\x30\\x88\\xbf\\xf1\\x2f\\x7a\\x70\\x6c\\x69\\xf2\\x00\\xc0\\x1d\\x04\\x75\\x86\\xed\\x3b\\x93\\xba\\x81\\xed\\xc1\\x2a\\x6f\\x91\\x11\\xac\\x1d\\x33\\xc3\\xd4\\x26\\x9d\\x92\\x4b\\xf2\\x2e\\x99\\x02\\x06\\x9c\\xe7\\xb2\\x07\\xbb\\xac\\x0b\\x52\\x0e\\xd9\\x22\\x46\\xed\\x98\\x0a\\x40\\x65\\x7b\\xec\\x87\\xc6\\x2c\\xdd\\x00\\x97\\xc0\\x47\\x9a\\xf6\\x28\\xad\\xe4\\x7c\\xc8\\x71\\x36\\xc5\\x15\\x27\\x0d\\x47\\x16\\x20\\xb5\\x68\\x66\\xe3\\xcd\\x98\\xf6\\x8e\\xa8\\x04\\xdd\\x4f\\x79\\xdb\\x13\\xa3\\x8d\\xfe\\xfe\\x27\\x91\\x74\\xa7\\x93\\xa9\\x7b\\xd7\\x22\\xc2\\x90\\xaa\\xbe\\xa2\\xf0\\x5b\\x27\\x0a\\x74\\xc7\\x92\\x5b\\x35\\x5f\\xaa\\x7d\\x8e\\x3f\\x7f\\x86\\xe8\\x6e\\x63\\x05\\x11\\x7a\\x72\\x6d\\x74\\x69\\x2e\\x5d\\xde\\x4f\\xd4\\x1a\\xde\\xea\\xbf\\x15\\xf1\\xc0\\x45\\xbd\\x6b\\xd1\\xe7\\x3a\\x79\\x6c\\x7c\\x89\\x77\\xab\\xc6\\xf6\\x88\\xdc\\x78\\x68\\xe8\\x98\\x73\\x12\\xf7\\x08\\x44\\x77\\x6e\\xe3\\x1d\\x45\\xd5\\xad\\x89\\xcf\\x50\\x71\\x86\\x54\\x1f\\x2e\\x8f\\x7c\\xa2\\x87\\x3e\\x9a\\xd4\\xc5\\x14\\x34\\x14\\x3f\\xfb\\x9e\\xd6\\x2a\\xca\\xd3\\x63\\xd0\\xd3\\x75\\x6b\\x64\\xae\\xfa\\x85\\xe1\\x93\\x44\\x72\\x94\\xd4\\xc6\\x76\\x3d\\x51\\xb2\\x09\\xd8\\x34\\x46\\xd5\\x86\\xd6\\x8f\\x69\\x95\\x59\\xbf\\x8f\\x83\\x49\\x06\\x60\\x8d\\x0f\\x4c\\x56\\xc1\\xec\\xaf\\x09\\x1a\\x65\\x85\\xc9\\x46\\x78\\x2a\\x53\\x42\\x01\\x4d\\xe8\\xd0\\x10\\xa6\\x3b\\x39\\x86\\xf8\\x66\\xaf\\x56\\x1e\\x82\\x11\\x22\\x3b\\x75\\x93\\x64\\xce\\x38\\x40\\x91\\xb5\\xc5\\x8c\\xd1\\x78\\x68\\x4e\\x5f\\x73\\x93\\xd2\\x8d\\x69\\x28\\xd6\\xd0\\xd3\\x10\\x95\\xeb\\x93\\x54\\xcd\\x71\\xfa\\x97\\x29\\xf2\\x64\\x67\\xd3\\x44\\x4c\\x56\\x35\\x2b\\x7c\\x2c\\xb6\\xa0\\xbf\\xad\\x36\\x0f\\x7c\\x3d\\xf3\\x0c\\xe4\\x33\\xb6\\x97\\xff\\xf6\\xf3\\x3e\\xaa\\x48\\x57\\xd4\\xef\\xdb\\x7e\\x66\\x69\\xf0\\xfa\\x38\\xd8\\x03\\x35\\xd6\\xca\\x0f\\x4c\\x9e\\xd0\\xe7\\xcd\\x8f\\x77\\x58\\xfd\\xbd\\xaa\\x1f\\xd9\\xf9\\xfe\\x90\\x9d\\x4a\\x61\\x91\\x59\\x4f\\x84\\xc2\\x99\\xc0\\x61\\xf3\\x3c\\xcc\\x61\\xf6\\x73\\x95\\x5c\\x32\\x25\\xdf\\xba\\x1b\\x20\\xa5\\x73\\x51\\xb1\\xf9\\x1e\\xd8\\x25\\x43\\x65\\x5d\\x31\\x71\\xf5\\x1a\\x8f\\xe0\\x59\\x85\\x63\\xde\\x85\\xa3\\xe0\\xc4\\xec\\x96\\xe5\\xac\\x6b\\xe1\\x74\\x6d\\x3f\\xf3\\x36\\xf4\\xef\\x6e\\x68\\x22\\x01\\xd3\\x64\\x1a\\xf4\\x41\\x15\\xbb\\x47\\xf5\\x45\\x4c\\x3a\\xae\\x69\\x3d\\xde\\x50\\x7c\\x5f\\x67\\xcd\\xa5\\x30\\x84\\x4a\\x8a\\xa1\\xa4\\xa1\\x44\\x3d\\x80\\xf6\\x6b\\xbd\\x48\\xe5\\x3e\\x6f\\x76\\x0c\\x06\\x75\\x4c\\xd1\\x60\\x65\\xa6\\x41\\x9f\\xcc\\xc7\\xf1\\xfa\\xf9\\x4d\\x17\\xe4\\x84\\xa1\\x5c\\x99\\x7e\\x02\\x4e\\xa4\\xfa\\x80\\x40\\x4c\\x31\\x05\\x85\\x47\\x4c\\x22\\x03\\x41\\x3a\\x7d\\x01\\xe9\\xd5\\x1e\\x8f\\x16\\x93\\xd8\\x35\\x12\\xa1\\xb1\\x35\\x53\\x74\\xc7\\x6c\\xfd\\x76\\xef\\x32\\xd6\\x3d\\xb6\\xde\\xc4\\xa3\\xff\\x2e\\x38\\x30\\x7f\\xe0\\x57\\x9c\\x5f\\x27\\x71\\x49\\xf7\\xdb\\xdc\\x52\\xef\\xca\\x10\\x96\\xee\\x24\\x00\\x19\\x25\\x77\\xcd\\xe4\\x73\\x78\\x34\\xf7\\x0f\\xd6\\xd1\\xe3\\xd9\\x18\\xd4\\x2a\\xf9\\xcf\\x8b\\x88\\x6d\\x66\\x9d\\x81\\x66\\xdc\\xbb\\x6a\\xd1\\x5f\\xd1\\x15\\xae\\x5d\\xe2\\x56\\xe7\\x53\\xb3\\xe5\\x48\\xfc\\xf1\\xe7\\xe7\\x76\\x37\\x6c\\xd1\\x28\\xb9\\x20\\x44\\x2c\\x11\\x45\\xbc\\xf3\\x5b\\x2e\\x1c\\x5d\\x54\\xbd\\x6f\\x9c\\xcc\\xcd\\x91\\x76\\xc6\\x17\\x55\\xee\\xbe\\x21\\x4a\\x73\\x0c\\x49\\xfd\\xf7\\x92\\xbe\\x0e\\xb9\\xb1\\x73\\x04\\xe0\\x25\\x10\\x65\\x9c\\x9a\\x30\\x7c\\x19\\x10\\x70\\x65\\x1a\\xca\\x6f\\xb6\\x10\\xd9\\x39\\xbd\\x3f\\x7d\\x0a\\xae\\xee\\xcb\\x47\\xf9\\x75\\x2d\\x4a\\x33\\x15\\x63\\x63\\x5a\\xc1\\xc7\\xb1\\x75\\x46\\x75\\xab\\x62\\x1b\\xff\\x8a\\x1b\\x79\\x68\\x94\\x7f\\x10\\x34\\x62\\x46\\x5d\\xd0\\xd3\\x4d\\x6b\\x64\\x36\\xb9\\x90\\x42\\xd6\\xee\\xdc\\x1b\\x79\\xd7\\x20\\x3c\\x70\\xd3\\x08\\x1b\\x7f\\xb3\\xd9\\x02\\x31\\x20\\xf4\\x72\\x31\\x66\\x06\\x85\\x08\\x6b\\x4a\\x7a\\x89\\x60\\x45\\x56\\x44\\x08\\x5d\\x86\\x2e\\xb3\\x49\\x69\\x96\\x23\\x4c\\x99\\x03\\x9e\\x5d\\xb9\\x60\\x6f\\x70\\xf5\\x15\\xc0\\x50\\x98\\xda\\x97\\x63\\x5e\\xa2\\x1e\\x51\\x30\\x1f\\xc9\\x43\\x7a\\x0f\\xfa\\xdb\\xf7\\xa3\\xe0\\xe7\\x11\\xf9\\x9b\\x15\\xd9\\xdf\\xd8\\xba\\x53\\x17\\x87\\x6f\\x1d\\x8b\\xd5\\x64\\x8a\\xae\\x5d\\x9b\\x47\\x3e\\x37\\xfc\\x94\\xbd\\x19\\x13\\x95\\x32\\x4c\\x96\\xf4\\x99\\xde\\xff\\xd1\\x74\\x16\\x4b\\xd6\\x32\\xcd\\x16\\xbe\\x20\\x06\\xb8\\x0d\\xb1\\x8d\\xbb\\x33\\xc3\\xdd\\x9d\\xab\\x3f\\xd1\\xef\\x77\\xfe\\x01\\x11\\x1d\\x1d\\x7b\\x40\\x15\\x59\\x2b\\xd7\\x93\\x50\\x59\\x40\\x46\\x84\\x93\\x7e\\x0d\\xc5\\xa4\\x40\\xd3\\x1f\\x27\\x2d\\x23\\xb6\\xa3\\xd6\\xf4\\xc1\\x46\\x10\\x54\\xe8\\xf8\\xc3\\xeb\\x1e\\x89\\xd1\\x7a\\x56\\xd9\\x7e\\xcf\\xd0\\x34\\xde\\xac\\x84\\xf8\\x92\\xbd\\x57\\x4a\\x38\\x53\\xf9\\x99\\x30\\xbb\\x1d\\xcd\\x40\\xb0\\x7b\\xfa\\x2f\\xda\\x50\\xe1\\x87\\x81\\x3d\\xd6\\x7f\\xbb\\x18\\xff\\x18\\x86\\xab\\xb1\\xcc\\x6a\\x6e\\xf7\\x7c\\xb1\\x25\\x0d\\x86\\xf0\\x3b\\xc9\\x1f\\x36\\xd4\\x8e\\x07\\x45\\x1a\\xfc\\xe6\\xe6\\x04\\x11\\x45\\x63\\xac\\x92\\x56\\x5c\\x68\\x86\\x43\\x54\\xa2\\x61\\xb4\\x12\\xfa\\x83\\x91\\x9e\\x11\\x0d\\x2a\\xbb\\x63\\xa4\\x60\\xae\\x67\\xe9\\x03\\x17\\x53\\xe0\\x6f\\xc1\\xa8\\x79\\xe9\\x38\\x34\\x89\\xe8\\xf9\\x27\\x44\\x5f\\x88\\x4a\\x33\\xee\\x8f\\xbd\\xad\\x2f\\x47\\x69\\x2d\\x79\\x7e\\xa6\\x37\\x45\\xe4\\x73\\x33\\x41\\xf2\\x35\\x6a\\x3e\\x45\\x2d\\x63\\x3b\\x0c\\xae\\xb0\\x0f\\x22\\x2f\\xe9\\xbb\\x5f\\x12\\xff\\xc8\\xdd\\x08\\xf7\\xeb\\xc0\\x12\\x56\\xef\\x95\\x17\\x66\\x80\\x52\\x24\\x7d\\x0b\\x4a\\xd2\\xe7\\x81\\x12\\xa5\\xf2\\xe3\\x05\\xe5\\xfe\\xf6\\xb4\\x14\\xa2\\x52\\x63\\x1b\\xa8\\x98\\x5c\\x34\\x3b\\x86\\x25\\x09\\x09\\x2b\\x03\\xa1\\xe9\\x0f\\xfd\\x4c\\xc9\\xeb\\xa9\\x9c\\xca\\x74\\x54\\xb9\\x73\\x2a\\x84\\x06\\xed\\x2b\\x50\\x8a\\x4a\\x8d\\xea\\x85\\x8b\\x76\\x8e\\x3b\\x3e\\xfe\\x99\\x0b\\x7a\\xe0\\x25\\x04\\xa4\\x7a\\x33\\x22\\x5d\\xea\\x0a\\xba\\x27\\x3c\\xa3\\x97\\x74\\xc0\\x66\\x27\\x10\\x71\\x6e\\xeb\\xbd\\xab\\xdc\\xba\\x6e\\x2b\\x39\\xe4\\xff\\x5e\\xc0\\xaf\\xeb\\x4a\\xec\\xd4\\x07\\xae\\x0e\\x26\\xe2\\x3c\\x82\\xef\\x88\\x63\\x63\\xd5\\xaf\\xf0\\x83\\x51\\x1f\\xca\\x23\\x8c\\x2d\\x85\\xf2\\xd3\\xee\\xef\\x67\\x31\\x5d\\x9e\\xc1\\xa5\\x15\\x14\\x5e\\xec\\x9c\\x1c\\x71\\x3a\\x29\\x31\\xfd\\xd7\\x93\\xc5\\xaa\\xe8\\x5c\\xa3\\x20\\xee\\x58\\x04\\x81\\x13\\x60\\x56\\x1f\\x98\\xab\\xfa\\xee\\xa8\\xc6\\x9a\\x9d\\x6c\\x54\\x06\\xef\\xc3\\x05\\x00\\x66\\x2d\\x35\\x3d\\x13\\xc0\\x87\\x17\\x08\\x8e\\x59\\xb0\\x3f\\xa5\\x5b\\xfc\\x40\\xeb\\xe6\\x63\\xfd\\xec\\xf4\\x4e\\x7e\\xb3\\x03\\xa1\\xda\\x3c\\x46\\xba\\xd3\\x92\\xba\\xdd\\x04\\xb4\\x3f\\xcf\\x93\\x5a\\x62\\x27\\x24\\x9d\\xe0\\xdb\\x26\\x89\\xb2\\xaa\\x0b\\xcd\\x0c\\x9b\\xc1\\xd4\\xc5\\x87\\xf0\\x61\\xf0\\x31\\x7b\\x69\\x19\\x6c\\x80\\x60\\x8e\\xfa\\x14\\xb5\\x5e\\x3d\\x6e\\x3a\\x3b\\x9a\\x29\\xbf\\x4d\\x39\\xe6\\x6c\\xfc\\x3d\\xa6\\x59\\xcb\\xca\\x9e\\x67\\xdd\\x3c\\x2e\\x44\\x29\\xd6\\x32\\x99\\x1e\\x4f\\x72\\x2c\\xa6\\x53\\xa0\\xe4\\xb1\\x05\\x2b\\x50\\x23\\xd4\\x02\\xce\\xc4\\xb9\\x9d\\xa8\\x66\\x90\\xc4\\xe5\\x2c\\x83\\x40\\x98\\x30\\x54\\xb0\\x76\\xfa\\x4b\\x76\\x24\\x3e\\xc2\\xcd\\xbe\\xf5\\xcf\\xf0\\x02\\xb8\\x02\\x3f\\x54\\xc1\\x88\\xb2\\x92\\x1a\\x5f\\x6b\\xde\\xd3\\xdf\\x9e\\x9f\\x07\\x3c\\x23\\x73\\xff\\xad\\x67\\x74\\x85\\x49\\x03\\xfb\\xe0\\x65\\xe5\\xfa\\x45\\x73\\x3a\\x18\\xc2\\xf7\\x43\\x90\\x4b\\xec\\x04\\x4b\\xcd\\xad\\x67\\x86\\xb5\\x7b\\x10\\xf1\\x4c\\xe0\\xf2\\x56\\xd4\\x39\\x91\\x9f\\xff\\xf8\\xac\\x96\\xc4\\xa9\\xfd\\x91\\x34\\x80\\x05\\x11\\x52\\x06\\x1a\\x8c\\x20\\x21\\xe9\\xcc\\xb5\\x47\\x82\\x92\\x50\\x48\\x0f\\x01\\x91\\x47\\x57\\xb4\\x61\\x97\\x73\\x34\\xd7\\xc5\\x92\\x75\\x97\\xf2\\x57\\xcf\\xa2\\x0c\\x1f\\xac\\x18\\x0e\\x4b\\x26\\x3c\\x7a\\xc6\\xa5\\x36\\x16\\x1b\\x41\\x50\\x44\\x0e\\x42\\x39\\x8e\\x81\\xcd\\x1a\\x77\\x0b\\x81\\x68\\x7e\\x88\\xab\\x53\\x56\\x21\\x05\\xcd\\x6a\\x4e\\x0b\\x5d\\x4e\\x19\\x0c\\x42\\x8c\\xc3\\x39\\xae\\xe6\\x50\\x6f\\xa0\\x3e\\xf4\\x31\\xcc\\x30\\x41\\x16\\x77\\x6e\\x4a\\x85\\xf4\\x23\\x10\\x17\\x68\\xb7\\x95\\x00\\x12\\x1a\\x00\\xb4\\x9e\\x6c\\xb7\\x32\\xc9\\x2f\\x34\\x29\\xfc\\x40\\x70\\xce\\x19\\xa5\\x58\\xa5\\x38\\xd1\\x18\\x2b\\x2d\\x20\\xab\\x31\\x8e\\xb7\\x94\\xbe\\x06\\xad\\x07\\x4b\\x84\\x6a\\x1a\\x3f\\x67\\x7f\\xda\\x1c\\xa4\\x30\\x8c\\x02\\xaa\\xea\\xa8\\x37\\x3e\\x2f\\x92\\x30\\x1a\\xb6\\xe2\\x44\\xd2\\xf0\\xd8\\xe6\\x27\\xe8\\x65\\x2e\\x26\\xc4\\x81\\x33\\x84\\x45\\xc7\\x2f\\x70\\x62\\x6a\\x2c\\x37\\x19\\xc7\\xd1\\x3d\\x88\\x06\\xfb\\xaa\\xe6\\x30\\x60\\x8d\\x5c\\x01\\x36\\x3a\\xc7\\xcb\\xca\\x3b\\x28\\xa2\\x02\\xa1\\x59\\x30\\xf1\\x52\\xb6\\x95\\x0b\\x4d\\xfc\\x76\\xfa\\x04\\xf2\\x3b\\x37\\x35\\xdc\\x0f\\xc1\\x5a\\x60\\x77\\x59\\x5e\\xde\\xbc\\xb7\\xa4\\x3f\\x0b\\x88\\x02\\x01\\x44\\x14\\xe6\\x9f\\x32\\xdd\\x30\\xbe\\x55\\xd2\\x43\\x41\\xbf\\x5a\\xe8\\x7d\\x53\\xb5\\x7f\\x20\\x58\\x00\\xa4\\x8b\\x57\\xfb\\xb8\\x50\\x9d\\x25\\xda\\x0a\\xb1\\x62\\xb4\\xd0\\x08\\x79\\xaf\\xb8\\xa1\\xe2\\xd1\\xc0\\xb3\\x03\\x16\\x12\\x79\\xe7\\x13\\xa9\\xc6\\x93\\xf3\\x6d\\xee\\x05\\x3b\\x42\\xa3\\x0e\\xfc\\x2b\\xa8\\xf1\\xdd\\x37\\xf5\\x18\\xbf\\xb4\\xf9\\xc5\\x1d\\xf8\\xa4\\x6c\\x0e\\x64\\x06\\x9a\\x35\\x78\\x4f\\xac\\xb1\\x08\\xa8\\x9e\\xf4\\x4e\\xd3\\xf3\\xd1\\x20\\x38\\x3d\\x35\\xfa\\x61\\x4f\\x1b\\x53\\xa9\\xe5\\xcc\\x52\\x5e\\xab\\xed\\x4a\\x94\\x68\\x76\\xea\\xe2\\x18\\x0c\\xab\\x1d\\xa0\\x2f\\x05\\x5a\\x17\\x4a\\xee\\x96\\x2a\\xb4\\xc1\\x9b\\x7c\\xb0\\x58\\x92\\x27\\xdf\\xed\\xbb\\xdc\\xc9\\x2d\\xd3\\x5b\\xdb\\x40\\xb7\\x54\\xee\\x18\\x3b\\x0b\\xbe\\x17\\x61\\x76\\x33\\xc9\\x23\\x37\\x4a\\x79\\x02\\x2b\\xc0\\xa7\\xa9\\xa2\\xd9\\x61\\x8c\\x4f\\xfa\\xe4\\xc0\\xd0\\xb7\\xbf\\x61\\x85\\xd3\\x22\\x52\\xa0\\xc6\\xf0\\x75\\x6b\\xba\\x85\\xae\\x82\\x86\\x92\\x7f\\x4a\\xc0\\x9c\\xbc\\x5d\\xd9\\x68\\xd4\\x78\\x6f\\xbe\\xc6\\x59\\x9c\\xb5\\xe2\\x01\\x81\\x4c\\xc9\\xf9\\x6c\\x68\\x00\\x86\\x29\\x83\\x68\\xed\\x00\\xd8\\x79\\xe3\\xee\\xdc\\x00\\x4a\\xab\\xd4\\x3c\\x92\\x4e\\x69\\x00\\x48\\x8f\\xf0\\xeb\\x73\\x7e\\xd8\\x8a\\x94\\xad\\xf5\\x67\\x59\\xe0\\xf4\\xce\\x75\\x89\\xe3\\x00\\x2f\\x78\\xc9\\xb2\\x45\\x01\\x72\\x40\\x20\\xf1\\xea\\x45\\x0e\\x3a\\xb5\\x59\\x61\\xec\\xc8\\xf4\\x20\\xd6\\x9d\\xa6\\x07\\x2d\\x4e\\x14\\xc6\\xcb\\xa8\\xc5\\x4c\\x3c\\xc5\\x4e\\xad\\x33\\x26\\x30\\x16\\x24\\x51\\xc9\\xc2\\x2d\\x38\\xac\\xc9\\xc3\\x8c\\x2a\\x61\\xce\\xdd\\x13\\x1e\\x7b\\x15\\x6c\\x5f\\x61\\xd6\\xfe\\x9b\\xb6\\x18\\x61\\x6b\\x48\\x0f\\x17\\x8e\\xe0\\xeb\\xae\\xbc\\x22\\x17\\x3a\\x34\\x3d\\x9b\\xd3\\x57\\x89\\xb4\\xe0\\x66\\xa5\\xc5\\x48\\xa4\\x20\\x08\\x60\\x84\\xc2\\x0a\\xa7\\x4f\\xc4\\xd4\\x52\\x2f\\x68\\x5f\\x11\\x38\\x4e\\x0c\\x91\\x1e\\x76\\x63\\x98\\x9b\\xd2\\x96\\xb9\\xda\\xbf\\xe4\\xe9\\x83\\xc9\\xa1\\x6d\\xcb\\x0d\\x6f\\x77\\xa1\\xd1\\x03\\x3e\\xda\\xcd\\x85\\xb6\\x96\\xea\\xc2\\x81\\x94\\x7b\\xb9\\x97\\xcb\\x61\\xc3\\x0b\\x99\\x74\\x47\\x32\\x03\\x2a\\xb4\\xea\\xf1\\xd3\\xae\\xc8\\x4a\\xa6\\xa0\\xb6\\x5b\\x63\\x07\\x08\\xc8\\xd4\\xb7\\x9f\\x9f\\x36\\xaa\\x4e\\x68\\x8c\\x8c\\x73\\x8b\\x62\\xed\\xc1\\x7a\\xfc\\xa2\\xd3\\x73\\x73\\x50\\xe9\\x13\\x10\\x8b\\x6e\\xb1\\xaa\\x36\\xad\\x07\\x32\\xb7\\x3e\\x05\\xb0\\x92\\xac\\xa5\\x26\\xb6\\xa1\\x83\\xe2\\x34\\xd8\\x02\\x4f\\x90\\x08\\x31\\xb2\\x28\\xaf\\x08\\xa6\\x30\\x0d\\x4f\\x9f\\x52\\xcd\\x8c\\xb1\\x85\\xab\\xd3\\x56\\x90\\x84\\xcd\\xde\\x26\\x10\\x3b\\x07\\x36\\xe6\\x5e\\xb5\\x76\\xd9\\xb1\\xd5\\x8f\\xf2\\x64\\x12\\xf1\\xcc\\x0a\\xff\\x0c\\x07\\xbb\\x99\\x40\\x3d\\x8f\\xcd\\x83\\x49\\xbc\\xbe\\xc5\\x90\\x31\\x69\\x64\\x83\\xbf\\xe5\\x6b\\xfd\\x9f\\x63\\xfb\\xc7\\xf8\\x65\\xe9\\x28\\xb2\\xf3\\x8d\\xa5\\xad\\x6f\\x4a\\x7c\\x7b\\x84\\x5b\\x68\\xdf\\xa2\\xd8\\xfe\\x1a\\xed\\x77\\xa1\\x24\\x71\\x4c\\x0e\\xb2\\x27\\x17\\xe7\\xc8\\xbc\\x8b\\xd4\\x76\\x2d\\xd4\\xff\\xf4\\xf4\\xb7\\x16\\x27\\xe8\\xdc\\x8f\\x93\\x59\\x9c\\x28\\x4b\\x0a\\x1d\\x30\\x46\\xe4\\xc3\\x1a\\x63\\x9e\\x9d\\x14\\x1f\\x1a\\xc3\\x06\\xa2\\xa5\\x12\\xcf\\x36\\x03\\x60\\x75\\xa2\\x59\\x03\\x44\\xfe\\xd7\\x92\\x0e\\x94\\xc3\\x23\\x98\\xd7\\xfa\\xf0\\xa8\\x62\\x0d\\x21\\x97\\x1a\\xa8\\xf0\\x4b\\xb4\\xe1\\x81\\xa1\\x7b\\x69\\x49\\x37\\x55\\x59\\xb2\\x0d\\xc8\\xb7\\xc3\\xaa\\x5c\\xbf\\x6c\\xc1\\xfa\\x95\\x07\\x51\\x55\\x88\\xf2\\x04\\x11\\xd2\\x8f\\x0e\\x58\\xed\\xc8\\x89\\xba\\x9c\\xed\\x3e\\xb8\\x54\\xee\\x62\\xdf\\x69\\x9d\\x1e\\x49\\x28\\x75\\x46\\x32\\xbf\\x2d\\x84\\xf7\\x43\\xbd\\x03\\x8d\\xb9\\xbc\\xf5\\xc7\\xfd\\x4d\\x50\\x24\\x9f\\x94\\x5b\\xe7\\x6d\\x88\\x65\\x53\\xb3\\x9b\\x3b\\x89\\x11\\x7b\\x45\\x28\\xad\\x4e\\xea\\x1e\\xb0\\xd9\\xa0\\x04\\x02\\xfe\\xdd\\xc3\\x89\\xa6\\xb1\\x6e\\x1a\\x98\\x5f\\x5a\\xd1\\x65\\x02\\xa2\\x3e\\x02\\x2d\\x8b\\xdf\\xda\\x69\\x5b\\x64\\x03\\x5a\\x9f\\x0f\\xff\\x62\\xf8\\xe0\\xcc\\xca\\x9a\\xe2\\xb2\\x08\\x7d\\xc8\\x6e\\x7e\\x00\\x63\\x3d\\xab\\x26\\x4b\\xb2\\x36\\x10\\x3b\\xb3\\x72\\xb1\\xcf\\x15\\x92\\xeb\\xd4\\x7c\\x96\\xf6\\xb4\\xe3\\x07\\x82\\x69\\x39\\xb6\\xda\\x78\\x27\\x4a\\x3e\\x9c\\x57\\xca\\x7b\\xa8\\x79\\xc9\\x85\\xc6\\xca\\xc2\\x04\\x2d\\x60\\xfc\\x96\\x05\\x26\\x88\\x62\\xb4\\x1c\\x6b\\xfa\\xe6\\xa1\\x3b\\x73\\xac\\xf9\\x2d\\x31\\x42\\xb7\\x82\\xc4\\x40\\x1e\\x81\\xc8\\xbf\\xb6\\x55\\x61\\x50\\xea\\x38\\x8c\\x2a\\xad\\x87\\x37\\x80\\xf4\\xf8\\x55\\x15\\x3e\\x26\\x63\\x29\\x36\\x3f\\x87\\x16\\x9d\\x3e\\x2d\\x65\\x52\\x7c\\x4e\\xd4\\x95\\xdb\\xf9\\xe6\\x02\\x51\\x7f\\x47\\x5b\\x97\\x78\\x42\\x9d\\x7f\\x9e\\x9d\\x66\\x49\\x4d\\x26\\x62\\x19\\xa3\\xca\\x9b\\x37\\x37\\x55\\xc6\\xf2\\x47\\x4f\\xfa\\xa6\\xbe\\x0b\\x5f\\x0b\\x92\\x30\\x83\\x5f\\x06\\xd3\\x08\\x59\\x9c\\x84\\xc4\\x7b\\x61\\xd5\\xaf\\x3f\\xa1\\x9c\\xd5\\x7d\\xeb\\xe5\\xac\\xc6\\xcd\\xa7\\xcf\\x6c\\x23\\x21\\xdc\\xd8\\x6d\\x33\\x4e\\xb8\\x64\\x51\\x68\\xe2\\x8c\\xe3\\xba\\x05\\x29\\xc6\\xcf\\x99\\x6b\\xff\\x5f\\x7d\\xb2\\xc5\\x64\\xee\\x07\\x73\\xc7\\xa9\\xd6\\xb1\\x16\\x42\\x82\\xb2\\xa6\\x63\\x2d\\xae\\xe9\\xb8\\x2c\\x2f\\x21\\xfe\\xf6\\x42\\x78\\x44\\x67\\x8e\\xb1\\xc1\\x8a\\x60\\xda\\x2b\\x2e\\x84\\x58\\xeb\\x59\\xe6\\x58\\xae\\x26\\xb4\\xa7\\x58\\xb1\\x24\\xd2\\x3f\\x2a\\x74\\xa1\\x74\\x5c\\x56\\xfa\\xfc\\xd2\\xc6\\xcd\\x34\\x1d\\xc0\\x3a\\x8b\\xc1\\x24\\xc9\\x13\\x10\\xa3\\x8f\\xb7\\xab\\x2f\\x56\\xa0\\x92\\x8a\\x13\\x4d\\x35\\x1b\\xcd\\xe6\\x5d\\x14\\xcf\\x2b\\xf8\\x9e\\x53\\x9e\\xb3\\x08\\xa5\\xc0\\x8b\\x7d\\xd4\\xa9\\xa6\\xf1\\x32\\x63\\xaf\\x21\\x5b\\x60\\x12\\x22\\x97\\x91\\xf2\\x1b\\x1b\\xab\\x38\\xad\\x6e\\xd5\\x4e\\xee\\x04\\xdd\\xda\\x71\\x05\\xc3\\x0a\\xed\\x85\\x16\\x26\\xc9\\x0b\\x53\\x6c\\xed\\x8f\\x6e\\x9f\\x94\\xa3\\xfc\\x1d\\xa8\\x4c\\xa2\\xe0\\x1e\\x19\\x9c\\xeb\\x38\\x67\\xb5\\x57\\x04\\x8b\\x4b\\x19\\x93\\x31\\x9e\\x44\\x70\\xb9\\x33\\x98\\x00\\xc0\\x8f\\x5a\\x39\\xb8\\xf2\\x3e\\x1e\\x62\\x3b\\xc1\\x77\\x4b\\x3f\\x48\\x42\\x76\\xf0\\xb4\\xd2\\xda\\xc3\\xbf\\x71\\x2f\\x6b\\x3a\\xfa\\x26\\xec\\x1e\\x99\\x0b\\xe1\\x16\\xef\\x1c\\xe9\\xba\\x12\\x27\\xc7\\x32\\x88\\x46\\xd4\\xe3\\x57\\x5c\\x3d\\xac\\xb9\\xf7\\xd9\\x05\\xc2\\x3b\\xaf\\x6a\\xb3\\xa3\\x59\\x12\\xd8\\x90\\xc1\\x4b\\xa6\\x12\\x69\\x03\\xad\\xb8\\x3e\\x2e\\xf6\\x40\\x68\\x5f\\xe8\\xb9\\x7e\\x0a\\x68\\xf5\\x47\\x01\\xf8\\x20\\xa0\\x14\\x96\\xd6\\xd1\\x80\\x76\\xb5\\xa5\\x4e\\xa6\\x61\\x32\\x1a\\xe3\\x65\\x66\\xfc\\x3b\\x0b\\x3d\\x1b\\x04\\x51\\x54\\xcf\\x82\\x34\\xd7\\x98\\xab\\x74\\xf1\\xf4\\xfb\\xd3\\x7f\\x3f\\x28\\x22\\x12\\xe8\\x55\\xc0\\xc3\\x76\\xf0\\xc4\\x0b\\x4a\\x88\\x88\\xbd\\x77\\x86\\xa4\\x0c\\x97\\xfe\\xad\\xd8\\xe4\\x4f\\x10\\xcb\\x8a\\x36\\x1d\\xf0\\x68\\xb2\\x17\\x82\\x80\\x7e\\x0b\\x08\\xd0\\x85\\x8a\\x1f\\xab\\xbe\\xae\\x92\\xbe\\x74\\x84\\x98\\xc1\\x66\\xaf\\xc2\\x6d\\xf0\\x75\\xdc\\x55\\x10\\x3e\\x17\\xcc\\x16\\x0e\\x2b\\x9a\\x1d\\x68\\x39\\x7b\\x50\\xda\\xbe\\xfc\\xdb\\x69\\x04\\xcb\\xa4\\x7c\\xfa\\x17\\x9b\\x90\\xa1\\x88\\xb7\\xf9\\xbb\\xe7\\xdf\\xba\\xdf\\x1c\\x79\\xcf\\xf5\\x26\\x75\\x0f\\xb6\\x69\\x73\\x52\\x9d\\x10\\x37\\x41\\x78\\x79\\x85\\xe3\\x68\\xfa\\x48\\xf5\\xeb\\x54\\xd1\\xe9\\x93\\x5a\\x9c\\xb0\\x45\\x90\\x3b\\x29\\x58\\x5b\\xa5\\x7f\\x8e\\x2d\\x35\\xbb\\x7a\\xff\\x49\\xe7\\x0a\\xea\\x15\\xee\\xb9\\x4b\\x66\\x39\\x73\\xc8\\xae\\xa4\\x92\\xf0\\x6a\\xb4\\x05\\x2f\\xcb\\x67\\x4c\\xff\\x9c\\x5c\\x63\\xd3\\x8c\\xe0\\xba\\xb2\\xcd\\xe9\\x44\\x69\\xd9\\xfb\\x9c\\x8a\\xce\\x8e\\xea\\xa3\\x43\\xad\\x46\\x18\\x57\\x87\\xcc\\x31\\x2e\\x37\\x8a\\xdd\\x6e\\x5f\\xc4\\xd5\\x28\\x14\\x11\\x05\\x78\\xc9\\xaf\\xe7\\xb2\\xa8\\x2e\\x54\\x5c\\x10\\x61\\x49\\x21\\x3f\\x13\\x62\\xb3\\x47\\x1a\\xac\\x2e\\x6f\\xac\\x88\\x3f\\x0a\\xac\\xe0\\x86\\x75\\xe9\\xea\\xbc\\xbe\\xe6\\xbe\\x73\\x88\\x3e\\x68\\x0c\\x34\\x1b\\xc7\\xed\\x67\\x75\\x53\\x13\\x50\\x66\\x53\\x4b\\xbe\\x9b\\xd2\\xfe\\x7c\\x06\\x81\\x7d\\xd0\\x8d\\x6a\\xce\\xfc\\x60\\xb9\\x9a\\xf8\\x13\\x69\\x02\\xe1\\x21\\x44\\xbe\\x26\\x9f\\x44\\x21\\xd2\\xf6\\x37\\xcb\\x35\\x53\\xcb\\xfc\\x94\\x20\\x85\\xee\\xd5\\x43\\x2d\\xa1\\x24\\x3d\\x98\\x93\\xe7\\x98\\x52\\xbe\\x6b\\xdd\\xf3\\x02\\x5e\\x7f\\xb0\\x0d\\x10\\x4a\\xf5\\x2c\\x88\\x52\\x3d\\x93\\x0c\\x3f\\x85\\xb6\\x9b\\xba\\xb6\\x04\\xd1\\xc0\\x50\\x7d\\xd0\\xeb\\x18\\x77\\x18\\x52\\x95\\x84\\xdc\\xa1\\xea\\x0f\\x7b\\x26\\x3e\\xf5\\xf2\\xea\\xad\\x05\\x54\\xc8\\x16\\x1c\\xbf\\x5b\\xd1\\xf1\\x86\\x5a\\x19\\x2d\\x44\\x0f\\x64\\x58\\xd2\\xb0\\x96\\xd5\\x69\\x1e\\x95\\x9f\\x5d\\x0b\\xa2\\x08\\x56\\x3e\\x6c\\x78\\x39\\xa8\\x09\\x5c\\xc4\\x27\\x48\\x64\\x4d\\xb7\\x95\\x46\\x8e\\x46\\xba\\xdf\\x81\\x01\\x32\\xcf\\xd8\\x55\\xc2\\xf4\\x60\\xf1\\x11\\x77\\x80\\x25\\x40\\xf4\\x00\\xa1\\x50\\xcb\\xe2\\x75\\x5c\\xb5\\x4c\\xf3\\xa9\\x88\\x37\\x50\\x11\\xfd\\xd8\\x18\\xfe\\x09\\xba\\x1d\\x6b\\x33\\xc8\\xe0\\xa0\\x69\\x49\\x1e\\xa2\\x0e\\x5d\\xcc\\xf5\\x7a\\x0f\\x19\\xec\\x7a\\x04\\x00\\x58\\x52\\x63\\x52\\x38\\x52\\x8d\\x95\\x3f\\x41\\xb3\\x1d\\xae\\x30\\xd1\\xb2\\xd4\\xc5\\xbe\\x75\\xd6\\x4c\\x10\\x4d\\x08\\x76\\xfa\\xcf\\x29\\x01\\xef\\x16\\x32\\x27\\x92\\x46\\xee\\x43\\x2a\\x3d\\xd2\\xac\\x66\\x23\\x1c\\x2d\\x3e\\x36\\xf7\\x6d\\x1b\\xef\\xc5\\x00\\xb6\\x1b\\x98\\x96\\xd3\\x79\\xfd\\x13\\x3f\\xfa\\x61\\x1a\\xdc\\xe4\\x0a\\xf3\\xf1\\xdf\\x1c\\xb2\\x43\\x8d\\x81\\x3b\\xff\\x1b\\xf3\\x87\\xad\\xef\\x4a\\x6b\\x3a\\xf3\\x56\\x4a\\xb7\\xb2\\x26\\x84\\x28\\x2a\\x3d\\x7c\\x8e\\x0b\\x9d\\xe4\\x53\\x53\\x31\\xe9\\xb4\\x0c\\xe2\\x28\\xc1\\x9c\\x65\\xee\\xb2\\x3d\\x00\\x8d\\xb7\\x3e\\x86\\x41\\x9f\\x47\\x13\\xea\\x94\\xc7\\x4a\\x5d\\x43\\x85\\x1e\\x24\\xc7\\x27\\xff\\xf3\\x9e\\xe5\\xb5\\xd3\\x6a\\x3e\\x29\\x5c\\x4c\\x55\\x37\\xb2\\x11\\x40\\x75\\x36\\xbb\\xdd\\x72\\x02\\xe3\\x39\\xeb\\xe0\\x6f\\xb6\\x16\\xc9\\x14\\xd3\\xdd\\xae\\x3d\\xbd\\xff\\x9e\\x5f\\x93\\x86\\xbf\\x1e\\xf2\\x89\\x72\\x6b\\xe3\\x9a\\x4f\\x75\\xb9\\xa2\\x60\\xc3\\xf3\\x27\\xfe\\x36\\x23\\xda\\x6d\\xe7\\x54\\x7c\\x12\\xab\\x7f\\x79\\x61\\x57\\x76\\x84\\x77\\xec\\x0e\\xa2\\xad\\x88\\x4f\\x4a\\x50\\x7a\\x36\\x18\\x00\\x9d\\xe9\\x18\\xc4\\x0f\\xa6\\xc1\\x0a\\x92\\xf8\\xfb\\x41\\x25\\x0c\\x0f\\x0d\\x96\\x55\\x70\\xaa\\xfa\\x28\\xd0\\xb8\\xd0\\xec\\x56\\xb4\\xee\\x40\\xc1\\xee\\xdb\\x75\\x97\\xc6\\xc3\\x2d\\x59\\xb9\\x64\\x08\\x6f\\x1e\\x63\\x40\\x08\\x2f\\xb3\\x93\\xec\\x1c\\x9c\\x4d\\x18\\x75\\xb1\\xf0\\xf5\\xb5\\x10\\x8c\\x07\\xdc\\x7e\\x51\\x6b\\x59\\x71\\x7a\\xaf\\x1d\\xa8\\xbb\\x64\\x50\\xa4\\xdc\\x56\\x62\\xbf\\x42\\xcd\\xb6\\x3b\\xc7\\xdf\\x78\\x26\\xe9\\x88\\x78\\x1b\\x42\\x8e\\xaa\\x5d\\x3b\\xb6\\xc4\\x54\\x3d\\x36\\x1b\\x9a\\xc3\\xdf\\x91\\xb5\\x58\\x28\\x59\\xb7\\x4b\\x95\\xc6\\x67\\xbf\\x6a\\x63\\xa1\\x24\\x3e\\x6b\\xb2\\x5c\\xb3\\x82\\x08\\x1d\\xe1\\xae\\x95\\x6f\\x52\\x9d\\xa3\\xbd\\x4c\\x14\\x2d\\xfd\\xf9\\x60\\x35\\x03\\x69\\x78\\xb1\\xc1\\x6f\\xb4\\x5f\\x05\\x42\\x12\\x4d\\x04\\xc6\\x29\\x1e\\x15\\xb0\\xfa\\x70\\x9d\\xec\\xf6\\x7b\\x0f\\xb5\\xc4\\xcc\\xf0\\xde\\x97\\x67\\xf5\\xdd\\xaf\\x30\\x23\\x74\\x6f\\x2e\\x2c\\x54\\x0e\\x7f\\x8d\\xaa\\xd2\\x7a\\x7f\\x4f\\x0e\\x55\\xd9\\x33\\x22\\x1c\\x76\\x01\\xc2\\x6f\\xf7\\xba\\xdf\\x0c\\x54\\xb5\\x83\\xdd\\x2e\\xcb\\x0a\\x13\\x89\\xd3\\x7f\\x50\\x7a\\x8b\\xfa\\x52\\x86\\x4c\\x26\\x8a\\xe3\\x9c\\x12\\xdc\\x00\\x42\\x89\\xee\\x31\\x8f\\x89\\x5f\\x37\\xfa\\x63\\x6d\\x1f\\xb5\\x36\\x94\\x7d\\x1c\\xaa\\x5f\\x38\\xc6\\xf0\\xc8\\x2a\\xe7\\x40\\x00\\xbd\\x2e\\x94\\x44\\x04\\x78\\x81\\x88\\x4a\\x59\\xd3\\x87\\x14\\x1a\\xfa\\xd3\\x51\\xe3\\x01\\x37\\x62\\xae\\x29\\xb7\\xa6\\x82\\xb6\\xac\\x06\\x8c\\x81\\x29\\x6e\\x5e\\x35\\xcd\\xed\\x2f\\x07\\x01\\x97\\x3e\\x09\\xa3\\xe2\\xaa\\x43\\x0a\\x1e\\xab\\x1d\\xd1\\xa4\\xb6\\xb4\\x70\\x41\\x90\\x5d\\x15\\xd1\\x82\\xed\\x94\\xa2\\x81\\xbd\\x19\\x46\\x66\\x58\\xc5\\x11\\x7e\\x3e\\xfb\\x9e\\x71\\xbf\\xbc\\x54\\x71\\xf9\\xa9\\x61\\x25\\xd1\\x5f\\x1c\\x40\\x8b\\x47\\x82\\x96\\xe0\\x29\\x3b\\x8b\\xc4\\xab\\x2d\\x60\\xa5\\xd4\\x60\\xca\\xca\\xb3\\x35\\x8d\\x10\\x45\\x6c\\x30\\xb0\\xbc\\x9a\\x7c\\x8d\\x75\\x6c\\xb7\\x70\\x2e\\x4e\\x12\\x40\\x66\\xdc\\xbb\\xc2\\x1d\\xbf\\x0a\\x99\\x8d\\xdf\\xcc\\xc4\\x22\\x8b\\xa0\\xd5\\xe9\\xff\\x0c\\xcf\\xfe\\x0a\\x80\\x8b\\x7b\\x80\\xad\\xdb\\xdf\\xbd\\x19\\xd3\\xb7\\xb3\\x6b\\xbe\\x4d\\x39\\xe1\\x19\\x13\\x26\\x8b\\x3e\\xb7\\xa7\\x35\\x10\\xfd\\x0c\\x2d\\xba\\x0b\\x30\\xd4\\x05\\xa6\\x97\\x72\\x31\\xf9\\x74\\xc0\\x33\\xea\\x90\\x78\\x65\\x47\\xd5\\x66\\x55\\xf9\\x5c\\xc0\\xa6\\x5a\\x19\\xe3\\xaf\\x9d\\x3e\\xa1\\xcc\\xdd\\x3f\\x29\\x22\\xe5\\x0e\\x06\\x98\\x8b\\x10\\x1d\\xa1\\x9a\\x6b\\xbd\\xb8\\x69\\x4b\\xe4\\x2f\\xe7\\x8f\\xd4\\x7b\\x42\\x4d\\xa8\\x39\\x2c\\xec\\x5e\\xe3\\xe2\\x80\\xce\\xd2\\x77\\xd8\\x3c\\x78\\xe6\\x14\\xc2\\x17\\x18\\x0f\\x47\\x69\\xe4\\xed\\x13\\x11\\x3f\\xbd\\x71\\xc7\\xb7\\x11\\x3b\\x39\\x24\\x33\\x08\\x13\\xbd\\xa8\\x95\\x73\\xec\\xeb\\x40\\xc8\\xe2\\x7a\\x58\\x2a\\xd7\\x27\\x57\\x96\\x64\\x3c\\xaf\\x2e\\xef\\x16\\xa2\\xb6\\xe9\\xb0\\x54\\x64\\xd7\\x24\\x5f\\xf4\\xd3\\x47\\x51\\xd2\\x83\\xe8\\x52\\x82\\x4b\\xef\\x03\\x8a\\x9f\\xe3\\x97\\xed\\xd1\\xa9\\x62\\x3b\\x6f\\xca\\x43\\x11\\x89\\xe2\\xbf\\x99\\x97\\xf2\\x0e\\x84\\xc1\\xa5\\x93\\x4a\\x24\\x15\\x4d\\x0f\\x65\\xfb\\x02\\xbb\\x99\\xd9\\xac\\x87\\x06\\x54\\x48\\xde\\x6d\\x0b\\xf3\\xcf\\xf2\\x20\\x7a\\x15\\x23\\x92\\x67\\x62\\x7e\\x40\\x2e\\x5a\\x24\\x8b\\x13\\x6d\\xef\\x53\\xab\\x63\\x7f\\x90\\x51\\x65\\xb2\\x82\\x25\\x3b\\xa4\\x1c\\x3d\\xb0\\x92\\xae\\xc5\\x71\\x59\\x63\\x31\\x06\\x28\\x4d\\xfa\\x70\\xea\\x94\\xc0\\xcb\\x3a\\xdd\\x5f\\x03\\x11\\x15\\x0d\\x14\\x94\\xf1\\x4b\\xda\\xdd\\x98\\xf6\\x30\\x33\\xa6\\xd9\\xfe\\x8b\\x8f\\x6b\\xe8\\x9a\\xf9\\x13\\x87\\xf8\\x03\\x0d\\x6f\\x59\\xd7\\x79\\xa5\\xad\\x58\\x63\\xab\\x09\\xff\\xbd\\x74\\x5e\\x1b\\x7e\\x8e\\x7d\\xbe\\x68\\x82\\x7e\\xc3\\xfd\\xd4\\x4a\\x5a\\x31\\xfa\\xf6\\x02\\x6b\\xfa\\x5e\\x38\\xbf\\x7a\\x55\\x62\\x22\\xd0\\x45\\x19\\x6c\\x12\\x21\\xf2\\xa8\\xa9\\xc4\\x3c\\xdd\\x28\\xeb\\x7c\\x9e\\xa9\\xf5\\x48\\x1b\\xb0\\xbd\\x41\\x93\\x5f\\xab\\xfe\\xb0\\xca\\x4c\\x77\\x0b\\x76\\x82\\xc0\\x13\\xfc\\x25\\x6e\\xb9\\x7a\\xd7\\xf2\\x32\\xb2\\xd8\\x24\\x34\\xbb\\x18\\x64\\x21\\x45\\xd8\\xa1\\x8c\\xc6\\x28\\x95\\xb7\\x05\\x87\\x82\\x50\\x71\\x9e\\xc6\\x87\\x02\\x38\\x78\\x67\\x5c\\x56\\x15\\xc7\\xad\\x23\\x43\\x1e\\x2f\\x0d\\xf7\\x31\\xba\\x18\\x31\\xe7\\xec\\x53\\x90\\xd7\\x82\\xd0\\xb9\\x95\\x1b\\x14\\xb8\\x54\\x68\\xf4\\x4c\\x60\\x6b\\xf9\\x61\\xe1\\xa2\\x21\\x09\\x8a\\x2b\\x92\\x7f\\x7f\\x73\\x80\\x53\\xa4\\x78\\x17\\xc9\\x42\\x37\\xd4\\x7d\\xeb\\x9b\\xca\\xcd\\x48\\xa0\\xfc\\xe0\\x22\\x62\\x97\\xa8\\xc4\\x7c\\xa8\\x5b\\xc4\\xce\\xd9\\x25\\xd3\\x71\\xeb\\x4b\\xc3\\x28\\xbd\\x83\\xd8\\xee\\x42\\x79\\x0a\\x91\\xa4\\xd8\\xd8\\xb0\\x55\\x6d\\xb7\\x53\\x6a\\xfe\\xd3\\x07\\xba\\x9c\\x82\\x93\\x2c\\xe2\\x6c\\xbd\\x5a\\x6c\\x4d\\x4c\\xa0\\x44\\xbd\\x05\\x02\\xe7\\x5c\\xb7\\x9a\\x9c\\xaf\\xb5\\xdf\\x4b\\x97\\x57\\x94\\x18\\x36\\xbd\\x90\\xc7\\xf8\\x05\\xe9\\x09\\xb0\\x60\\xa4\\xc5\\xc5\\x72\\xd7\\xad\\xac\\x72\\xf5\\xd5\\x92\\x05\\x22\\xc0\\x64\\x89\\x1e\\x00\\x39\\xe2\\xb1\\xc3\\xb9\\x58\\x98\\x95\\x6f\\xd1\\x27\\xc1\\x66\\xce\\xab\\x50\\xe7\\xd0\\x2d\\x38\\x6b\\xc1\\x7b\\x70\\x15\\xdc\\x39\\xcb\\xfa\\x75\\x8f\\x01\\x7d\\xf0\\x00\\x97\\xba\\xae\\xc4\\x2e\\xd1\\x00\\xc9\\xa5\\x31\\x8a\\x4a\\x77\\x87\\x83\\xf2\\x46\\xab\\xe5\\x9d\\x4b\\x02\\x8b\\x66\\xf0\\x8a\\x3a\\x1f\\x0b\\xb8\\x53\\x82\\xd2\\x0a\\x27\\xb0\\xfe\\x8f\\x0b\\xff\\xbd\\xa7\\x24\\xc3\\x48\\x05\\x1e\\xc0\\xf1\\xb3\\x7a\\xd0\\x09\\xd0\\x8c\\xc0\\x53\\x52\\x99\\x74\\xa4\\x90\\xd2\\x94\\x7a\\xf7\\x6c\\x17\\x7c\\xe9\\x89\\xaa\\x39\\xaf\\x5d\\x91\\xd3\\x77\\xdf\\x34\\x92\\x33\\x59\\x8a\\xc0\\xa6\\xee\\x41\\x7f\\x05\\x07\\x09\\x76\\x92\\x86\\xc3\\x1f\\x67\\xee\\xca\\xdc\\x39\\xd3\\xbc\\xaa\\xed\\xda\\x1e\\x77\\xcb\\xc1\\x7a\\xe5\\x42\\x9b\\x0a\\x97\\x0a\\x6e\\x4f\\x1d\\x4c\\xe2\\x9d\\x25\\x12\\xe0\\x0a\\xa7\\x48\\xf7\\x6a\\xb4\\xb8\\x15\\x00\\xe8\\xf5\\xce\\x6f\\x83\\x57\\x74\\xc3\\x81\\x0c\\x01\\xdd\\x6e\\xc7\\x77\\x24\\xeb\\x9e\\x99\\x2e\\x0f\\x80\\x05\\x7d\\xa1\\xb9\\xa3\\x04\\x29\\x2e\\x65\\x81\\xca\\x40\\x1b\\x10\\x5e\\xab\\xc3\\x1e\\x12\\xa7\\x24\\x94\\x6d\\xd0\\x4b\\xfa\\x67\\xd2\\xd9\\xf6\\x1e\\x9b\\xfc\\x8a\\x04\\xa7\\x5b\\x6d\\xa2\\xf0\\x16\\x8a\\x4a\\xf2\\x2d\\xa5\\xcb\\xdd\\xff\\xb1\\x9e\\xdd\\xa5\\x19\\x33\\x18\\x6d\\x48\\x1e\\x2f\\xc0\\x57\\x47\\xbe\\x10\\xeb\\xca\\x1d\\x07\\x24\\x8a\\xbd\\x10\\x25\\x6f\\x61\\x1b\\xc9\\x5d\\x94\\x9f\\x2f\\xe4\\x28\\x25\\x67\\x92\\xa3\\xbb\\xaa\\xc3\\xfd\\xd8\\x9b\\xb0\\xd8\\x46\\x1f\\x7b\\xbf\\xa6\\x84\\x58\\x9f\\x9c\\x39\\xff\\x31\\xf6\\x20\\xf2\\xef\\x0a\\x97\\xcb\\x9a\\xf6\\x88\\xd1\\x25\\xaf\\x34\\xff\\xac\\xe9\\xfb\\x8c\\x97\\xda\\xf9\\x9f\\xe4\\xa1\\x94\\xc1\\x7b\\x10\\x65\\x5e\\xc7\\xe9\\x3e\\x47\\x16\\xc0\\x7f\\x3a\\x57\\xa9\\x76\\x43\\x8d\\x80\\x4e\\x55\\xb2\\x6a\\xa1\\x61\\xfa\\x00\\x06\\xcb\\x39\\x71\\xf4\\xc3\\x01\\xa5\\xad\\xfc\\xdc\\x08\\x34\\xb3\\xf3\\x60\\x9a\\x98\\x1c\\xb8\\xf0\\xc2\\x5a\\x56\\x2a\\x4d\\xf2\\xe0\\x91\\x17\\xe2\\xbd\\x6e\\xf9\\x0a\\xfb\\x86\\x15\\xd7\\xcf\\x48\\xa3\\xc2\\x26\\xfa\\x29\\xee\\x7e\\xf1\\x16\\x5b\\xc0\\x64\\x61\\xd1\\x1d\\x3d\\x3e\\x34\\xa1\\x65\\x9c\\x5e\\xbf\\x86\\x33\\x59\\x07\\x5e\\x6e\\xe9\\x8b\\xfb\\x75\\x6b\\x69\\x2f\\xb5\\xa8\\xae\\x30\\xe0\\xf0\\x91\\xac\\xe9\\xb8\\xad\\x22\\xbb\\xe2\\x3f\\xa5\\xee\\x5a\\x61\\x72\\xcf\\x1d\\x01\\xc0\\xaa\\x85\\xb3\\xc3\\x57\\x3a\\x37\\x56\\xf1\\xb3\\x1a\\xed\\xd9\\x37\\x9a\\x11\\xcb\\xaa\\x0b\\x2d\\xaf\\x4d\\xbd\\x75\\x00\\x28\\xec\\xdf\\xe3\\x07\\x43\\xe9\\x6f\\xc1\\x37\\xe3\\x26\\x21\\x04\\x9e\\x5f\\xbc\\x74\\x69\\x45\\x5b\\xad\\x82\\xb2\\x43\\xe1\\x69\\xe3\\x02\\xd2\\x22\\x10\\x92\\x77\\x20\\xc1\\xcf\\x88\\x32\\x42\\x95\\xfb\\x45\\x76\\xe9\\xbe\\x23\\xe4\\xe8\\x06\\x40\\xf8\\xc9\\x25\\x95\\xab\\xe7\\x44\\x74\\x66\\xc2\\xec\\x36\\x63\\x86\\x51\\x5d\\x2f\\xe8\\x19\\x26\\x12\\xc6\\x41\\xf4\\x97\\x3b\\xa3\\xad\\xd7\\x57\\x3d\\x69\\xf7\\xec\\x93\\x80\\x95\\xdb\\xa0\\x5d\\xbe\\x6e\\x96\\x36\\x7a\\xb6\\xfd\\x43\\x1e\\x10\\xe6\\x5e\\x58\\x76\\x6e\\xba\\x1c\\x3c\\x13\\x81\\xbc\\xb7\\xd4\\xbe\\xfb\\x5f\\x45\\x39\\xce\\x4d\\xf1\\x8e\\x49\\xef\\x09\\x58\\x41\\x19\\x9b\\x3f\\xbf\\x85\\xd2\\xf9\\xc2\\xa0\\xda\\x86\\xaf\\xa8\\x33\\xb5\\x16\\x4a\\xd2\\x70\\x14\\x06\\xa3\\x92\\x5d\\xd4\\xbf\\x9d\\x8c\\x4a\\x1b\\x8f\\xc1\\x91\\x85\\xe7\\xc4\\x7c\\xbb\\xdb\\x18\\xcf\\x71\\xea\\x87\\x66\\x43\\xb6\\x20\\x88\\xf5\\xf7\\x6b\\xa0\\xde\\x86\\x86\\xc1\\x16\\x3a\\xe6\\x14\\xa4\\xa4\\x70\\x03\\x38\\x97\\xa6\\x75\\xe0\\x15\\x3d\\x8d\\x9a\\xd3\\x8c\\x25\\xb9\\xe0\\xec\\x6b\\x78\\x28\\x33\\x5e\\x25\\x06\\x9f\\x16\\xe3\\x8d\\x7c\\x45\\x60\\x8d\\x65\\xa7\\xe7\\x7d\\x08\\x40\\xf3\\x2f\\xcb\\xdd\\x26\\x4b\\xa1\\xd4\\xd4\\x5c\\x51\\x86\\x7e\\x00\\xc8\\xf6\\x10\\xf7\\xb1\\x7e\\x73\\xa2\\x2e\\x44\\x5b\\x1b\\x56\\x3b\\x78\\x96\\x35\\x2f\\x91\\xa9\\xb9\\x45\\x60\\x72\\x93\\xcb\\x19\\x8c\\x50\\x0c\\x77\\x25\\x5f\\x4e\\x99\\xca\\x3b\\x68\\x02\\x7c\\xc4\\xe1\\xda\\xf6\\x21\\xd4\\xb0\\xd4\\x33\\xe3\\x83\\xde\\x0a\\x11\\x71\\x06\\x20\\x28\\x75\\x00\\x2a\\x0d\\xf8\\xd1\\xd9\\xa3\\xba\\xad\\xd0\\xc1\\x3a\\x76\\xaf\\x0f\\x7d\\x79\\x1d\\x58\\x4c\\xdc\\x2d\\x67\\x29\\xd7\\x82\\xb5\\x4c\\x1e\\xff\\x5a\\xd4\\x76\\xad\\xe7\\xde\\x89\\x7c\\xf4\\xb0\\x5e\\x15\\x24\\xfa\\xa4\\x2e\\xd5\\x1d\\xd8\\x0f\\xff\\x89\\x39\\x38\\xb9\\x4a\\xd0\\xb1\\xe8\\x84\\x12\\x31\\x47\\x77\\xfb\\x2a\\x6e\\xeb\\xbd\\x03\\x2e\\xf0\\xa9\\x78\\x7e\\xcc\\x1a\\x1b\\xb1\\xcd\\x69\\xd5\\x2e\\x57\\x83\\xd3\\xc5\\x60\\x73\\x96\\x22\\xbf\\x81\\xbb\\x3d\\x1a\\x00\\xd6\\xa1\\xdb\\x6d\\x5c\\x9b\\x2a\\x1a\\x78\\x3c\\x7f\\xc0\\xd2\\x70\\x59\\x81\\x6b\\x23\\xe7\\x18\\x02\\xbd\\xda\\x11\\x18\\x08\\x1c\\x25\\xfe\\xe9\\x5b\\xf1\\x26\\x8d\\x5d\\xf6\\xf6\\xb3\\x70\\x8b\\x28\\x82\\x81\\xac\\xf9\\xa8\\xe6\\x65\\x3f\\x1c\\x03\\x9a\\x08\\xe6\\x6b\\x2a\\xea\\xa0\\x8e\\xee\\xba\\x07\\xd1\\x94\\xbe\\x3b\\x45\\x3f\\xb1\\x36\\x10\\x60\\x98\\x8c\\x4b\\xe7\\x5c\\x62\\x77\\x01\\x41\\x55\\xd9\\x61\\x64\\xbe\\x01\\x48\\xb6\\xdd\\x93\\x8b\\x62\\x19\\xd4\\x7d\\xb0\\xc7\\xe4\\x64\\x0b\\x34\\x77\\x53\\xe2\\xf9\\x18\\xd1\\x1f\\x0d\\x09\\xf6\\x4d\\x7d\\x65\\x2c\\x37\\xf9\\xa7\\xc7\\x52\\x43\\xe4\\xd8\\x4a\\x7a\\xa8\\x8c\\xfd\\x20\\x47\\xc0\\xb1\\x9c\\x28\\x10\\x8c\\x5d\\x0b\\x7e\\x2b\\xfe\\x3c\\x6f\\xe4\\xfa\\xcd\\x75\\xe1\\xc0\\x6e\\xfa\\x91\\xf6\\xc8\\xde\\x4b\\x5d\\x1a\\x14\\xd4\\xaa\\x9d\\x56\\x9e\\x02\\x02\\x22\\x9f\\x57\\xbf\\x58\\x7d\\x7a\\xe3\\xb2\\xee\\xdb\\x36\\x62\\xbb\\x7c\\x41\\xd7\\xc1\\xfc\\x1f\\xeb\\x86\\x5b\\xf0\\x39\\xa7\\xa4\\x43\\x35\\xf5\\x8b\\x2f\\xd1\\x55\\xda\\x79\\x56\\x91\\xab\\xa6\\x91\\x12\\xac\\x2c\\x14\\x7d\\x7f\\x3f\\xde\\x5e\\x82\\x1d\\x1d\\x93\\x4f\\x0f\\x13\\xd0\\x8c\\xb2\\x39\\xae\\x33\\x9c\\xed\\xe2\\xd5\\x27\\xde\\xb1\\x38\\x10\\x9a\\x45\\xc7\\x2a\\x3b\\x10\\xfa\\xca\\x46\\xc2\\x8c\\x10\\x74\\xc1\\x4e\\x6f\\x4f\\x44\\xb6\\xae\\x79\\x5c\\xa6\\x9a\\x5e\\x3c\\x4e\\xda\\x2b\\xa6\\x0c\\x81\\xdd\\x23\\xc2\\x0b\\x4b\\xa7\\x80\\xca\\xfc\\x3d\\xb6\\x7f\\xf3\\x78\\xd1\\x59\\xd1\\xcf\\x80\\x62\\xb9\\xbe\\x3e\\x09\\xa2\\xb6\\x5e\\x0d\\xf4\\x7e\\x27\\xd0\\x14\\x39\\x96\\x3f\\x46\\x35\\xa6\\x6b\\x92\\x6a\\x09\\x3f\\x55\\x3c\\xbf\\x2e\\x74\\x1b\\xdc\\x3e\\xf8\\xb1\\x0e\\xc6\\x2d\\xdc\\x8f\\x02\\xad\\xee\\xc9\\xaa\\x25\\xb3\\x05\\x49\\xfa\\x16\\xf4\\xb9\\x16\\x24\\x17\\xd9\\x3a\\x3e\\x25\\x6f\\x63\\xdb\\x4e\\xc6\\x41\\xbd\\x42\\x25\\x80\\x79\\x06\\xf9\\x97\\x84\\xd1\\xd0\\x25\\x3b\\x0a\\xd8\\x55\\x4d\\xbc\\x07\\xa6\\x28\\x76\\x55\\xdd\\x5c\\x2a\\x21\\x60\\xb2\\xb7\\xbe\\xf9\\xb9\\x7a\\xc0\\xd7\\x98\\x59\\xbd\\x70\\x41\\xad\\xfb\\x92\\x77\\x6b\\x61\\x9d\\xa0\\x05\\x14\\xf5\\x4e\\x14\\x80\\xdc\\xcd\\x84\\xa8\\x39\\x72\\x8e\\x77\\x78\\x2e\\x4d\\x77\\xc6\\x6f\\x6b\\x46\\xd2\\x04\\x5d\\x82\\x19\\xb4\\x16\\xb7\\x88\\x15\\x08\\x59\\x40\\x03\\x99\\x2a\\xac\\xa8\\xa3\\x5e\\xac\\xf3\\x0e\\x1b\\x2f\\x6d\\x3c\\x6a\\x1d\\x42\\xd4\\xe1\\x26\\xda\\x32\\xda\\x2a\\x4d\\xda\\xc8\\xa1\\x78\\xd7\\x1b\\x52\\x98\\xf0\\x82\\xac\\x77\\xe2\\xb4\\x23\\x27\\xf3\\xc0\\x94\\x91\\x00\\x30\\xb9\\x36\\x79\\x11\\x65\\xbf\\x98\\x4e\\x8e\\x6a\\xd3\\x8f\\x7b\\x4a\\x9c\\x2e\\x7b\\x32\\x2e\\x3e\\x0c\\xcd\\x0e\\xe4\\xc9\\x2b\\x29\\xc6\\xe8\\x17\\xe7\\x2a\\xa1\\xa6\\x09\\x48\\xb8\\xbd\\xc6\\x74\\xb4\\x4d\\xc8\\x27\\xad\\x55\\xc4\\xf2\\x66\\x68\\xba\\x00\\x88\\x7a\\x85\\x1d\\x7c\\xef\\x6a\\xbf\\xd0\\x5d\\x3c\\x85\\x4b\\xc8\\x6e\\x1e\\x59\\xee\\x80\\xb2\\xc7\\x4d\\x6f\\xc4\\x75\\x5e\\x35\\x1a\\x10\\x63\\x18\\x2a\\x1f\\xdd\\x6e\\xc2\\xaf\\x0c\\xbd\\x50\\x92\\x66\\x57\\xca\\xfd\\x0d\\x86\\x17\\xa2\\x1d\\xde\\x23\\xf1\\x72\\xf5\\x28\\x71\\x6e\\xeb\\x37\\xff\\x10\\x7a\\xe1\\x8f\\x7f\\x75\\x66\\x4f\\xe9\\x39\\xf3\\x95\\xa7\\xb5\\x93\\x55\\xab\\xd7\\xef\\xab\\x48\\xc2\\x98\\x9b\\xb2\\xc6\\x0f\\x86\\x84\\x38\\xb7\\xab\\x0b\\x94\\xda\\xe4\\x9b\\xfa\\x1d\\x21\\x60\\x9a\\x6b\\xca\\xbb\\x39\\x90\\x9b\\xa0\\xb0\\x65\\xea\\x73\\x5a\\x88\\xa8\\x38\\x51\\x3c\\x46\\x45\\x84\\xce\\x2f\\x10\\x03\\xd4\\xfb\\x08\\x21\\xba\\xaa\\x24\\x40\\xf7\\xec\\x84\\x13\\x75\\x13\\xb4\\x80\\x40\\x4d\\x86\\xdd\\x9b\\x28\\xdc\\x28\\x2f\\xa6\\xd6\\xb8\\x04\\xa2\\x29\\x8c\\x02\\xb6\\x0d\\xa1\\x9c\\x99\\x4e\\xce\\xe8\\xc1\\x01\\x75\\xf2\\xb4\\x47\\xa9\\x28\\xa9\\xa6\\x2c\\x8e\\x94\\x03\\x80\\x2c\\xeb\\xfc\\xb5\\xc4\\x67\\xcf\\xe2\\x47\\xc8\\xc6\\xe8\\x77\\xe7\\x32\\x77\\x90\\x13\\x7d\\x83\\x24\\x99\\x1f\\x27\\xd0\\x09\\x0a\\x94\\x4b\\x31\\x20\\xb0\\xca\\x99\\x8c\\xa9\\x10\\xc4\\xbd\\xec\\x7a\\x54\\x67\\xd9\\xd2\\x21\\xe8\\xca\\xa4\\x5f\\x17\\x4a\\x60\\x89\\xd0\\xc9\\x21\\x9a\\x1e\\x35\\x44\\x56\\xfb\\x67\\xa1\\x30\\xed\\xf8\\x95\\x30\\x5d\\x54\\x32\\xee\\x58\\x6e\\x48\\x28\\xf6\\x82\\xbc\\x0b\\xd0\\xd5\\x82\\xcb\\x2b\\xe3\\x17\\x82\\x6b\\x65\\x02\\x38\\x6e\\x32\\xb0\\x8e\\xc3\\x7a\\xa1\\x1b\\xc4\\xb2\\x21\\x58\\x32\\x0a\\xe1\\xba\\x8d\\x5f\\x5a\\x28\\xa6\\xaf\\x46\\xda\\x25\\x10\\x18\\xc7\\xe5\\x21\\xcf\\xb4\\x14\\xc2\\x5b\\x72\\x65\\x18\\x05\\xb8\\xcc\\xa3\\xb9\\xd4\\x79\\x6a\\x2d\\x71\\x8f\\xbb\\xf4\\x06\\x90\\x5c\\x8a\\xcd\\xcd\\xa9\\x74\\x8b\\xe7\\x48\\x91\\x77\\x72\\x5d\\xbb\\x8c\\xfe\\x18\\x5d\\x1a\\x86\\x4a\\x19\\x54\\x90\\x3e\\xff\\xc4\\x94\\xaa\\xa2\\xfd\\x24\\x8f\\x6f\\xf4\\x92\\x7d\\xec\\x1a\\xb0\\x5a\\xa1\\xc2\\xf2\\xd0\\xd2\\x2a\\x23\\x6b\\x24\\x0f\\x84\\xc6\\xc1\\x17\\xcf\\xdf\\x49\\x79\\x83\\x20\\x08\\xa2\\xb6\\xc7\\x59\\xb3\\xf1\\x95\\x0e\\x03\\xf9\\xb1\\x96\\x8d\\xb8\\xeb\\x17\\x8a\\x65\\xee\\x9c\\x5b\\x97\\x30\\x1c\\xd6\\x74\\x5a\\x52\\x71\\x4b\\xc4\\x54\\x1f\\xe8\\x12\\x91\\x8a\\xf3\\x31\\xb2\\x5f\\x1c\\xfb\\x4b\\x2d\\x42\\xfd\\xd5\\xdf\\x7c\\x20\\xf1\\x33\\xb6\\xaa\\xe7\\x86\\xe1\\x42\\xa7\\x10\\xeb\\xba\\x0e\\x06\\x00\\x52\\x68\\xf6\\x80\\xd7\\x89\\x66\\xbb\\x45\\x1e\\xb4\\xe5\\x45\\xb0\\x17\\xfd\\x1c\\xdf\\x0f\\x24\\x16\\x8b\\x58\\xa8\\x90\\xec\\x7d\\x4b\\x6f\\xa2\\x38\\xb7\\x19\\x59\\xf7\\x48\\xda\\x25\\x50\\xe1\\x67\\xb7\\xec\\xe4\\x89\\x56\\x9e\\x4d\\x3f\\xf5\\xe7\\x3e\\x2d\\x0e\\xa8\\x0c\\x3b\\x9d\\x02\\xb8\\x08\\x8b\\x36\\x06\\xd1\\x7e\\xa3\\xbe\\x1b\\xca\\x0d\\xa9\\x16\\x57\\x1a\\x00\\x33\\x96\\xfc\\x02\\x9c\\x30\\x90\\x89\\xc4\\x4d\\x41\\x01\\x5a\\xfe\\xb1\\x18\\x8b\\x97\\xb9\\x03\\x90\\x48\\x98\\x1a\\x22\\x0e\\xa3\\xf2\\xc2\\x9c\\x52\\x5f\\xb8\\xf5\\xca\\x42\\x57\\xbf\\x5f\\x64\\x6e\\x05\\xfa\\x08\\x93\\x01\\xa7\\x75\\x59\\xf9\\x7e\\xa6\\x8e\\x4c\\x42\\x9b\\xe2\\x3b\\x20\\xeb\\x1e\\xc5\\x9a\\x69\\x46\\xd6\\xbb\\x7f\\xdb\\x37\\xbe\\x0d\\xa7\\x09\\x3a\\x8b\\x24\\x62\\xdd\\xd6\\x67\\xff\\xd7\\x89\\x60\\xc4\\xdb\\x78\\x64\\xeb\\x54\\x74\\xe6\\x54\\x3c\\xb7\\x85\\x28\\xa7\\x99\\xd8\\x15\\x93\\x82\\x2c\\xf9\\x59\\x2e\\x3f\\xd0\\x39\\x54\\xfe\\xec\\xf4\\x4b\\x61\\xb0\\x42\\xdd\\x00\\xb7\\x9c\\x8f\\x20\\x0b\\xf4\\x7b\\x48\\x26\\xcc\\x48\\x6b\\x7a\\x8b\\x34\\x0c\\xce\\x6e\\x77\\x5d\\xe1\\x0b\\x33\\xf0\\x8c\\x18\\x96\\x64\\x77\\x07\\x97\\x0b\\x19\\xeb\\x37\\x9c\\xaa\\x83\\xbe\\xda\\x1e\\xb2\\x7b\\x70\\x0c\\x11\\x5a\\x73\\x5d\\xb6\\xb4\\x96\\x05\\x9e\\xb2\\xaf\\x3c\\xe5\\xe5\\x4f\\xc7\\x29\\xba\\xbc\\xe3\\x99\\x30\\xd4\\x63\\x24\\xd2\\x70\\xb8\\xee\\x18\\xd1\\x16\\x43\\x44\\xf6\\x6c\\xfc\\xca\\x65\\x0d\\x38\\x4e\\x0f\\x24\\xe7\\x9a\\x70\\x60\\x67\\x21\\xf7\\xd5\\xe9\\xef\\xe4\\x67\\xdf\\xf0\\x42\\xb8\\x9b\\x54\\xef\\x55\\x75\\x61\\xdb\\xe0\\xdc\\x20\\xf0\\x8a\\x47\\x1b\\xad\\xab\\xee\\x3c\\x84\\xaf\\x8c\\x6f\\x20\\x52\\x99\\xb9\\xf3\\xb5\\x6b\\x40\\x68\\x6d\\x10\\xa8\\x04\\x9b\\x30\\xb5\\xc7\\x18\\xd1\\x0c\\xd9\\x8a\\xab\\xc3\\x45\\x45\\xd6\\xeb\\x6b\\x0f\\xbd\\x44\\x5f\\xa8\\x27\\x9a\\xc3\\x5f\\x93\\x7a\\x74\\xc3\\xf9\\x83\\xe2\\xfa\\x83\\x92\\xd2\\xe5\\xb5\\x6e\\xa0\\xfd\\xac\\xc6\\xb2\\x8a\\xcd\\xfc\\xdf\\x5e\\xe4\\x69\\xf9\\x77\\x10\\x84\\xb9\\xcd\\xc4\\xdf\\x64\\x9d\\xd3\\x4a\\x98\\xc7\\x96\\x22\\x1d\\x05\\x9a\\xbf\\xeb\\xae\\xe1\\xec\\x58\\x2b\\xdb\\x49\\xad\\x3f\\x70\\x44\\xf6\\x4e\\xe6\\x7e\\xd0\\x60\\x66\\x7f\\xd3\\x9a\\x1d\\x48\\x2d\\x98\\xef\\xb4\\x01\\xa4\\xd2\\x4f\\xc5\\xef\\xf8\\x16\\x73\\x98\\xd3\\xf0\\xbc\\x50\\x92\\x03\\x8a\\x64\\x47\\x52\\xd9\\x17\\x04\\xe9\\x00\\x2e\\x4d\\x7d\\xf5\\x4e\\xff\\x04\\x68\\x35\\x9c\\xd5\\x62\\xbf\\x73\\xf9\\x09\\xac\\xec\\x0a\\x8f\\x6f\\xa8\\x5f\\xa3\\x83\\x67\\xdc\\x96\\xf3\\x77\\x87\\xda\\x41\\xf0\\x89\\x97\\x36\\x37\\x55\\x91\\x07\\x42\\xe2\\xc0\\xb7\\x6b\\x3c\\x25\\x26\\x63\\x30\\x30\\x51\\x86\\x11\\xa5\\x37\\xb7\\x0c\\x72\\xb9\\x71\\x98\\x8e\\xc3\\xba\\x05\\x2b\\x5c\\x5e\\xd3\\xab\\x04\\x7d\\xab\\xd7\\x92\\xc8\\xee\\xd6\\xf4\\x34\\xb2\\x2b\\x0c\\xd0\\xa0\\x50\\x13\\x47\\x4e\\x8a\\x9a\\xf3\\xe2\\x5e\\xd8\\x0e\\x0f\\x84\\xfc\\x6b\\xca\\x42\\xdb\\x6d\\x0b\\x96\\x1d\\xc8\\x5b\\xea\\xd3\\xcf\\x2d\\x22\\x1f\\x6e\\x3c\\x02\\x71\\x39\\x7b\\xd5\\x5a\\xec\\xd4\\x5a\\x1c\\x00\\xab\\x0d\\xa6\\x41\\x3a\\x08\\x83\\x21\\x09\\xe0\\x22\\x0a\\xa1\\x42\\x0a\\xe0\\x2a\\xba\\x75\\x96\\xf9\\xff\\x56\\x02\\x95\\xf7\\x77\\x41\\x94\\x55\\xac\\xb2\\x25\\x77\\x78\\xad\\x12\\xe7\\x2d\\x2d\\xc2\\x5a\\x98\\x60\\x29\\x79\\x0c\\xc8\\x1f\\x67\\xcb\\x62\\xbf\\x16\\x98\\xbf\\x65\\x64\\xdf\\x48\\x14\\x35\\xab\\x23\\xf2\\x5e\\xb9\\x8d\\x70\\xfd\\x0d\\x49\\xf8\\x17\\x93\\x26\\xdb\\xd8\\x88\\x1b\\x23\\xc7\\x92\\xde\\x06\\x56\\xb3\\x82\\x10\\x8b\\xcd\\xa6\\xbe\\xa1\\x67\\x02\\x97\\xf3\\xe5\\xf4\\x89\\x57\\x7e\\xf1\\x73\\xec\\xd0\\x8f\\x25\\x47\\x58\\x7e\\xdf\\xf0\\xc0\\x54\\x7f\\xd5\\xac\\x4f\\x00\\xaa\\x20\\xa0\\xb8\\xec\\x3c\\xf9\\xa4\\x50\\xaf\\xe5\\x3e\\xb2\\xc4\\x62\\x39\\x92\\x15\\x73\\xaf\\xf8\\xe2\\xb9\\x32\\x3b\\x20\\x6c\\xce\\x42\\x3c\\x69\\x72\\xdc\\x04\\x55\\x1a\\x9f\\x0b\\x35\\xf2\\x34\\x73\\x8c\\x0c\\x75\\x4d\\x7a\\x88\\xed\\x13\\x1f\\x91\\x6a\\x01\\x95\\xf1\\xbb\\x6b\\x61\\xdf\\x7e\\xd2\\xcf\\xf1\\x83\\xbf\\x4b\\x74\\xfa\\x04\\x05\\x3f\\xca\\xa5\\x43\\x7c\\xda\\x08\\xa0\\x4f\\xfe\\xfe\\x23\\x3a\\x73\\x22\\x35\\x03\\x0a\\xda\\x10\\x5d\\x49\\x73\\x5d\\xbe\\x7d\\xf5\\xad\\xbf\\x94\\x4b\\xf7\\xfb\\x28\\xe5\\x75\\x64\\x73\\xb8\\x9a\\xb2\\xe0\\x44\\xed\\x75\\xa0\\x81\\xcb\\x5d\\x66\\x95\\x65\\x02\\x38\\x8f\\x3a\\xd7\\x0f\\x0a\\x7e\\xe6\\xbd\\x84\\x89\\xe3\\x1d\\xb0\\xfe\\x22\\x87\\x21\\x16\\x98\\x90\\xed\\x8d\\x66\\x85\\x04\\xff\\xe3\\x2e\\x22\\x1c\\x96\\x98\\xe3\\x6c\\xc0\\x19\\xf5\\xb1\\xa0\\xcf\\xdf\\x77\\xfe\\xad\\x29\\x6f\\xa1\\x08\\xde\\x0d\\xb0\\xbf\\x1c\\xdd\\x3d\\x14\\x48\\x9c\\xd7\\xf6\\x62\\x23\\xab\\xba\\x93\\x52\\x8b\\x6b\\x61\\x7e\\x57\\x1b\\xe0\\xc7\\x6e\\x4a\\xd9\\x52\\x59\\x3c\\xc3\\x54\\x0e\\xdb\\x5f\\xb5\\xc4\\xee\\x1f\\x10\\x3f\\x69\\x1d\\x4b\\x0f\\x55\\xfd\\x96\\x74\\x5c\\xc2\\x60\\xb0\\xdf\\x6c\\x58\\xc2\\x20\\xc8\\x00\\x58\\xab\\x5b\\x80\\xea\\x0a\\x8b\\xe9\\x05\\xdb\\xfe\\xbd\\x44\\x51\\x1d\\x1d\\xbd\\x7e\\x86\\xf8\\x95\\x8a\\xc3\\xc9\\x09\\xba\\x23\\x57\\x50\\xe6\\xcb\\x5b\\x01\\x98\\x82\\xd8\\xef\\xf8\\x6f\\x0f\\x7f\\x3c\\x2a\\x3b\\x92\\x1a\\x9e\\xfe\\x18\\x9e\\xf0\\xe9\\x9f\\x0e\\x1b\\x45\\x14\\x40\\x94\\xc5\\xf4\\x6c\\x32\\x2c\\x69\\xc8\\x58\\x11\\xa5\\xf3\\x36\\x6a\\x7c\\x39\\xea\\x04\\xfe\\x52\\xc7\\xe3\\xb2\\xc6\\xa3\\xea\\x4e\\x09\\x64\\x28\\x49\\x1b\\x0e\\x73\\x86\\xe7\\xbe\\x5b\\x0a\\xd1\\x01\\x80\\x3f\\x54\\x34\\x21\\x0e\\xe6\\x1b\\xe8\\xb6\\x30\\x52\\x36\\x8d\\x9f\\xf3\\xaf\\x3e\\x7c\\xdf\\x89\\xbc\\xd0\\x26\\x7f\\x55\\x37\\xa3\\xbf\\x16\\x87\\x45\\xdc\\xa8\\x76\\xf3\\x9b\\xd1\\x46\\xef\\x58\\xa8\\x3f\\x01\\x10\\xb3\\x95\\xce\\x81\\x60\\xa3\\x32\\x69\\x01\\xb8\\x60\\xeb\\x21\\x7e\\x49\\xbf\\x5f\\x03\\x35\\xd5\\xd4\\x21\\x28\\xad\\x29\\x55\\x47\\x3a\\xc2\\x07\\x58\\x66\\x86\\xf8\\x36\\x6c\\xef\\xd7\\xbe\\xd0\\xb8\\x54\\xba\\xc3\\xab\\xe8\\xc5\\x87\\xc6\\xd9\\xfe\\x31\\x88\\x40\\x9f\\xfd\\x1e\\xf2\\x23\\x68\\xdd\\x99\\x1d\\x56\\xec\\x55\\xf9\\xbb\\x69\\xc7\\x55\\xda\\xf7\\x8d\\x13\\x0f\\x97\\x40\\x81\\x27\\xaa\\x09\\x3f\\xbd\\x1e\\x3f\\x3d\\x0a\\xe0\\x01\\x30\\xa5\\x40\\x5c\\x52\\xf1\\x65\\x47\\xd2\\x31\\x39\\xb3\\x10\\x5e\\xd2\\x70\\x58\\x92\\x70\\x68\\xe2\\x58\\x4f\\xf2\\x78\\x75\\x87\\xc5\\x16\\xd7\\xa2\\xec\\x62\\xc6\\x45\\x06\\x81\\xc1\\x0a\\xb3\\xe6\\xc7\\x87\\xb6\\x3c\\xe8\\x74\\xd6\\xdb\\x73\\xb9\\x4a\\xb6\\x62\\x0a\\xb0\\xaa\\x8d\\x0e\\x56\\x43\\xb2\\x09\\x34\\x25\\x0a\\xc9\\xc1\\x3e\\x47\\x4e\\xf0\\x01\\x17\\x1d\\x80\\xbf\\x1d\\x5f\\xe3\\xb6\\x16\\xbb\\xf2\\xa5\\xcd\\xfe\\xe6\\x32\\x33\\xbf\\x9a\\xaa\\x2a\\x59\\x70\\x2f\\x56\\xcf\\xcc\\x57\\x70\\x1d\\x3d\\xe1\\x8d\\xa1\\xc2\\x5a\\xdb\\x6d\\x0b\\x62\\xbc\\xb0\\xc0\\x4d\\x91\\x2b\\xfa\\x6d\\x60\\xaa\\xc8\\x1e\\x1b\\x6b\\xce\\x8e\\x38\\x2a\\x12\\xbb\\xd1\\x3b\\x81\\xf5\\x0f\\xe0\\xe8\\x74\\x67\\x59\\x9b\\xb2\\x56\\x38\\xa5\\xa7\\x4b\\xc1\\xc7\\x78\\xdc\\xd7\\x3e\\xb2\\xfd\\x1f\\xeb\\xe4\\x57\\x24\\xf3\\x01\\xcd\\xf6\\xe4\\xaf\\xdb\\x79\\x99\\xe9\\xdc\\x82\\x7f\\xa4\\xb2\\x91\\x5b\\x28\\xc9\\x8c\\x11\\xf0\\x6f\\xa7\\xc2\\x68\\x8b\\x25\\x2f\\x2f\\xdc\\xd6\\x91\\xf6\\x7c\\x17\\x04\\xc9\\x36\\x53\\xdf\\x7d\\x0e\\x07\\x27\\xde\\x43\\x2d\\x38\\xa1\\xcc\\x18\\xdf\\xc0\\xdf\\x3f\\xfd\\x33\\x20\\xd7\\xff\\x18\\x7c\\xaf\\x32\\xa4\\x38\\xbb\\xc5\\x71\\xdb\\x29\\x42\\xc8\\x51\\x6c\\x6f\\x28\\x8c\\x96\\xb4\\x1c\\x66\\xd5\\xd5\\x2c\\x57\\x65\\x01\\x89\\xbb\\x41\\x74\\x7d\\x12\\xfd\\xf5\\x07\\xc5\\x7b\\xc6\\x96\\xb9\\x3d\\xc9\\x86\\xa8\\x31\\x32\\x31\\x50\\x40\\xc7\\x4d\\x06\\x25\\x8e\\x01\\x19\\x50\\x6a\\x9e\\xbc\\x12\\x0d\\x82\\x2e\\x48\\x1a\\xe8\\x3b\\x8a\\x24\\x07\\xfc\\x8c\\xb9\\xa1\\x09\\xd1\\x6c\\xb6\\xf0\\x3c\\xd1\\xdc\\x73\\x84\\xb2\\x4f\\xa6\\x35\\xd1\\x28\\xca\\xcb\\x7f\\x33\\x23\\x3a\\xab\\xc1\\xf6\\x07\\x95\\xb5\\x55\\x1b\\x53\\xf8\\x5f\\x0b\\xe2\\xee\\x9b\\x1d\\xe6\\x44\\x42\\xa2\\x02\\x5a\\xec\\xe3\\xf9\\xf0\\x11\\x97\\x86\\x54\\xdb\\x4f\\x2b\\x72\\x32\\xc7\\x62\\x5d\\xb3\\x2e\\x73\\x3a\\x3e\\xf9\\x35\\xaa\\xe3\\x32\\xa7\\x85\\xa9\\x67\\x7f\\x7c\\x2a\\x2c\\xd4\\x54\\xad\\x28\\xe9\\x07\\x8a\\xbb\\x6f\\xe9\\x93\\x16\\x27\\x92\\x79\\x17\\x59\\x8c\\xe8\\x41\\x5a\\x5c\\x23\\x2d\\x9c\\x7e\\x20\\x14\\x0b\\x17\\x2b\\x9c\\x62\\x65\\xe8\\xd7\\x5d\\x4c\\x3f\\xc3\\x65\\x87\\xba\\x62\\xbb\\xad\\x54\\x5a\\x56\\x37\\x7d\\x34\\xc8\\x2e\\xaf\\x05\\x53\\x2b\\xf2\\x73\\xb0\\xdb\\x91\\xd3\\x65\\x4d\\x47\\x3c\\x67\\xf0\\x57\\x5f\\xcb\\x71\\x59\\xd3\\xa6\\x0f\\x7e\\x67\\xb6\\x92\\x79\\x38\\x2e\\x4b\\x92\\x86\\xfb\\xc6\\x3c\\xd8\\x6f\\x5e\\xf5\\x56\\x71\\x25\\x50\\x6a\\xc2\\xa4\\x4d\\xeb\\x71\\x0b\\x0d\\x23\\x22\\xc8\\x37\\x1e\\xe1\\xc3\\x46\\x52\\x59\\xfc\\xcd\\x86\\xb2\\x56\\x17\\x0d\\xaa\\xb8\\xbb\\x33\\x86\\x4b\\x97\\x27\\xcf\\xfe\\x31\\x33\\x3d\\x06\\x97\\x12\\x0d\\x49\\x2a\\x36\\xbb\\xc7\\x10\\x3b\\xfe\\x1c\\xa7\\xf6\\x84\\x4a\\x23\\x71\\xb2\\xcc\\xf4\\xd1\\x65\\x4d\\x90\\xce\\x33\\xe8\\xf4\\x25\\xb8\\x17\\xfc\\x5c\\x21\\xbb\\x5e\\xe1\\xdd\\x37\\xf5\\x5f\\xaf\\xe7\\xe9\\x22\\x0c\\xce\\x8d\\x67\\xc3\\x5a\\x86\\x21\\x09\\xe9\\x2b\\x43\\xa6\\xec\\x80\\xc8\\x83\\x7b\\x64\\x9c\\x08\\xc7\\xbb\\xab\\x77\\x9c\\x48\\xc7\\x65\\x6d\\x7a\\xe7\\x97\\xba\\xad\\x04\\xd1\\x55\\x14\\xc0\\x45\\xa0\\xb9\\xfd\\xc2\\xc0\\x96\\xd6\\x9b\\x22\\xc0\\xc8\\xb2\\x8b\\x51\\x80\\x85\\x4b\\x1f\\xc5\\xad\\xc7\\x08\\xa5\\xb2\\x20\\xf1\\xca\\xaf\\xd9\\x06\\x84\\x0e\\x07\\xbc\\xe4\\xdb\\x26\\x8e\\x7e\\xdf\\x4e\\x94\\x04\\xfb\\xd4\\xda\\x4b\\x9a\\x93\\x57\\x00\\x60\\xf9\\x56\\x9f\\x3f\\xb6\\x2f\\x86\\x0d\\x71\\xda\\x15\\x29\\x55\\x46\\xa6\\x2e\\x49\\x4a\\x1b\\x87\\x22\\xab\\xf4\\x75\\x79\\x80\\x24\\xcd\\x03\\x18\\x48\\xb1\\xd2\\xc9\\xce\\x93\\x85\\x3f\\x94\\xc1\\x27\\x3b\\x5d\\x60\\x84\\x2e\\x46\\x11\\x01\\x9b\\xd3\\x4a\\x8c\\x0b\\x63\\xff\\xf3\\x90\\xb9\\x75\\x71\\x71\\xcb\\x31\\xaa\\xbe\\xa5\\xf0\\xe1\\x0b\\xdd\\x1d\\x61\\x7b\\x74\\x83\\x89\\x3c\\x88\\xa2\\x60\\x9f\\x62\\x94\\xb4\\xef\\xe4\\x2d\\x64\\x9f\\x6f\\x63\\x21\\xb1\\x48\\x71\\x7e\\x1b\\x5a\\x48\\xff\\xce\\xc9\\xf9\\xe5\\xcf\\xc2\\x46\\x23\\x56\\x0e\\x8a\\x3b\\x0c\\x6e\\x44\\xb8\\x5e\\xff\\xe7\\x0d\\x5d\\xa9\\xa3\\xc4\\xbe\\xd4\\x9e\\x52\\xa1\\xc0\\x8a\\xce\\x6c\\x48\\x60\\x23\\xa1\\x1a\\x84\\x8b\\x85\\x62\\x0b\\xd3\\xc6\\x87\\x42\\xf5\\x5c\\x91\\x5f\\x79\\x3f\\x04\\x07\\x0a\\x3b\\xce\\xb1\\x31\\x4f\\x11\\x1d\\x7d\\x03\\x2c\\x09\\x94\\x01\\x5b\\xe8\\xff\\x10\\x73\\x56\\xb9\\xa6\\x46\\x14\\xce\\x4b\\xc6\\xcc\\x18\\x85\\x7b\\x04\\x5a\\xb6\\x11\\x99\\x57\\xec\\x00\\x3a\\x0e\\x75\\xe4\\x4b\\x28\\xcc\\xff\\x3d\\x95\\xd6\\xf7\\x3b\\x25\\xb5\\x20\\x45\\x8b\\x43\\xec\\xe5\\x80\\x23\\x83\\x3f\\xa8\\xe1\\x38\\xd9\\x34\\xf8\\x00\\xa2\\x4f\\xb2\\x42\\x69\\x26\\xe6\\x38\\xd3\\x40\\x3a\\x01\\xa9\\x48\\x64\\x0b\\x8e\\x2d\\x20\\xa8\\x84\\x30\\x12\\x10\\x3c\\x1e\\xfc\\x40\\xc8\\xb2\\x11\\x91\\x4d\\xa9\\x74\\x99\\x95\\x35\\xee\\xee\\xe5\\xd9\\xf0\\x0f\\x4d\\x25\\x5d\\x3f\\x1f\\x9a\\xc4\\x76\\x30\\xf8\\xd6\\x0b\\x86\\x55\\x85\\x7c\\xd0\\x57\\x6b\\xc4\\xaf\\x86\\xf1\\x8d\\x7e\\xc8\\x8a\\x0b\\x7d\\x53\\xba\\x94\\x05\\xa0\\x57\\xc0\\x0f\\xa7\\x48\\xad\\x52\\x2a\\x85\\x47\\x87\\xba\\x70\\xeb\\x71\\x69\\xe3\\x58\\x27\\xdc\\xdf\\x1d\\x32\\xb1\\xc8\\xb6\\x35\\x8f\\x2b\\xd3\\x6b\\x70\\x4d\\x78\\x6c\\xe9\\x6e\\x8d\\x3f\\x81\\x2a\\xcd\\x17\\x57\\x7e\\x7f\\xbe\\xef\\x4f\\x31\\x6b\\x59\\x56\\xb9\\x7a\\xed\\x9c\\x19\\xe4\\x10\\x41\\xb7\\x9d\\xdf\\x6d\\xc1\\x91\\x47\\x2c\\xdc\\xe8\\xd1\\x0f\\x19\\x6b\\xa0\\xb9\\xf1\\x7a\\x20\\x44\\x01\\x5a\\x6c\\xc9\\x8e\\xe2\\x14\\x50\\x18\\x04\\x57\\x21\\x58\\x06\\x13\\xa4\\x60\\xe5\\xb5\\xbe\\xbc\\x3a\\x25\\x55\\xaa\\x51\\xa3\\xcd\\xdb\\x0d\\xe8\\xc6\\x24\\x7b\\x0f\\x54\\x7a\\xc3\\xbb\\x8f\\x84\\x5f\\x89\\xab\\x05\\x1e\\x04\\x5a\\x0f\\x78\\xdf\\x7e\\x12\\x05\\x4f\\x6e\\x89\\x9c\\xba\\x3d\\x22\\xff\\x98\\x42\\x38\\xaf\\x6a\\x8b\\x15\\x96\\xd8\\x66\\x26\\xd5\\x61\\xea\\x90\\x45\\x0f\\xe8\\x6d\\x84\\x23\\x4a\\xa0\\xd5\\x41\\x33\\x6f\\x24\\x33\\xf8\\x88\\xb5\\xb9\\x89\\x8e\\x9f\\x70\\xc5\\xd9\\xb8\\xd8\\xfc\\x37\\x5f\\xdd\\x83\\x91\\x6c\\x5a\\x63\\x99\\x35\\x3c\\x81\\x67\\xc3\\x1d\\x0f\\x09\\xf6\\x1e\\x2a\\x53\\xf2\\x14\\x08\\x68\\xb4\\x42\\xeb\\x58\\x49\\xc6\\xa7\\x04\\xe4\\x75\\xea\\xbb\\xaf\\xad\\xdc\\xaa\\xb4\\x83\\x01\\x89\\x3e\\x4e\\x2f\\x1d\\x5e\\x11\\xcb\\xc8\\x6c\\x79\\xc9\\x9e\\x35\\xa1\\x04\\xab\\x36\\x63\\x2a\\x77\\xc6\\x43\\x8c\\xd2\\x9c\\x0a\\xcd\\xcc\\x6e\\x75\\x5e\\xdb\\xc2\\xec\\x7c\\xed\\x17\\x03\\x51\\xc5\\x11\\x6c\\xbf\\xa8\\xf4\\x1d\\xe8\\x32\\xb5\\x84\\xe9\\xb8\\xcc\\x1a\\x4e\\x01\\x1d\\x0f\\xdb\\x8d\\xda\\x6b\\x62\\x48\\xdc\\x8c\\x31\\x6e\\x36\\x4c\\x57\\x52\\xcd\\x09\\x1f\\x5b\\x27\\x58\\xad\\xba\\xfc\\x83\\xd5\\xce\\x2e\\xc3\\xa1\\xfa\\xee\\x9b\\x87\\x53\\x94\\xe2\\x5c\\xe3\\xc4\\xd3\\xe8\\xbf\\xfd\\x79\\x3f\\xce\\x7e\\x42\\x05\\x07\\xa2\\xa6\\x83\\x39\\x41\\x96\\x6b\\x31\\xf6\\xcc\\x14\\xe3\\x4a\\xc3\\x6a\\x12\\xf0\\xc4\\x81\\x54\\x24\\x83\\x34\\xbd\\x37\\x73\\xf2\\x9e\\x0a\\x38\\x43\\x1e\\xeb\\x55\\xb1\\x91\\xdd\\xdf\\xdf\\x3a\\x98\\x5f\\x06\\x60\\xc5\\xfd\\xc3\\x68\\x04\\x69\\xe4\\x24\\x31\\x7c\\x06\\x8c\\xfb\\x74\\xbd\\x57\\x30\\xb7\\x9b\\xdf\\x2a\\xd3\\xf8\\x52\\x04\\x75\\x86\\x90\\x85\\xe6\\x3d\\xe0\\x8d\\xc9\\x9b\\x91\\x9f\\xd1\\x8b\\xcf\\xab\\xcc\\x55\\x29\\xa3\\x6e\\x30\\x00\\x7a\\x13\\x11\\x74\\x5a\\x95\\xf2\\xfe\\x2f\\xe2\\xe9\\x8a\\xee\\xd9\\xb9\\x90\\xbc\\x87\\x81\\xfa\\x1f\\x6b\\x87\\x52\\xaf\\x9a\\x2c\\x22\\x11\\x85\\x35\\xc5\\x72\\x91\\x72\\xfd\\x71\\xf7\\x0a\\x1f\\xdb\\x11\\xc9\\x03\\xed\\x35\\x13\\x26\\xef\\xc7\\x79\\xdd\\xea\\xf6\\xad\\xf3\\x4e\\x7e\\x4d\\xca\\xcf\\xfd\\xb5\\x73\\x4f\\xea\\x5f\\xe7\\x27\\xbc\\xfd\\x2c\\x86\\xed\\x4b\\xec\\x34\\x20\\x64\\x73\\x53\\x49\\x79\\x7a\\x37\\x96\\x6f\\xaa\\xdb\\x79\\xbd\\x88\\x70\\xdf\\x58\\x34\\x48\\x87\\x6d\\x33\\x51\\xf6\\xec\\x34\\xda\\xff\\x7c\\x87\\x0e\\x68\\x66\\x87\\xe9\\x07\\x5d\\x44\\xc1\\x53\\xfd\\xbb\\xe7\\xbf\\xb5\\xda\\x70\\x85\\xdd\\xba\\x53\\x3a\\x15\\x4a\\x1a\\x0c\\xb5\\x7c\\x26\\x41\\xc4\\x37\\x75\\xd6\\x3b\\x3d\\x54\\xf0\\x38\\xef\\x8b\\x7c\\x30\\x1e\\xaa\\xda\\xca\\xe7\\xc3\\xef\\xf5\\x9b\\x8f\\x23\\x59\\x9e\\x96\\x00\\xa8\\xf7\\x61\\xf7\\xfa\\xaf\\xee\\xac\\xe8\\xbb\\xd1\\x86\\x17\\x04\\xef\\x0d\\x7f\\x43\\x96\\xd1\\x23\\x62\\x94\\x1f\\xb6\\x57\\x18\\xcf\\x9e\\x2c\\x43\\x72\\x49\\x89\\x31\\xe4\\x8e\\x7c\\xf4\\x4e\\x29\\x4c\\xd7\\xdc\\xa0\\x06\\xb2\\x6f\\x1d\\xa1\\xbe\\xe8\\xf6\\x4b\\x12\\x3a\\x63\\x37\\xc8\\xf3\\x3d\\xfa\\xf7\\xa0\\xb8\\xe1\\xdd\\x72\\x1b\\x0b\\xf2\\x75\\x7b\\x61\\x35\\x69\\xc1\\x98\\x48\\xd7\\xaf\\xe5\\x3a\\x89\\xe0\\xf4\\x83\\xe6\\xa2\\x17\\x4c\\x35\\x11\\x61\\x73\\xc8\\x19\\x6d\\x7d\\xab\\x13\\x30\\x70\\xdd\\x22\\x62\\xf4\\x45\\xf0\\xf3\\xc1\\x62\\x61\\xd2\\x6b\\x0b\\x14\\xc1\\xf1\\xa3\\x1f\\x9a\\xeb\\x7c\\x70\\x59\\xd8\\x5e\\x9a\\xf0\\x91\\x85\\xfe\\xd1\\xfa\\xbd\\xca\\x36\\xe1\\x2e\\x54\\xd6\\xd4\\xc6\\xa3\\xc9\\xd5\\xb1\\xed\\x70\\x4b\\x1c\\x0e\\xcb\\x19\\x79\\xf8\\xbe\\xb6\\x31\\x21\\xf3\\x8c\\xfd\\xfb\\x34\\xa8\\xf1\\xd4\\x97\\xda\\x2d\\xd2\\xb8\\x2e\\xa2\\xc4\\x1f\\xac\\xba\\x7f\\x85\\xa9\\x6b\\x49\\x1a\\xd4\\x80\\x93\\xe6\\x50\\xff\\x2b\\x18\\x99\\x2a\\x62\\x26\\xb6\\xfe\\x97\\xf7\\x7e\\x11\\x8f\\xcb\\x4f\\x10\\xfc\\xbc\\x27\\x6d\\x85\\x97\\x7b\\x4a\\xc3\\x6f\\xf4\\xaa\\x9b\\xe2\\x53\\xeb\\xa9\\xa1\\x58\\x6f\\xef\\xa0\\xd4\\x76\\x5d\\xe6\\xcd\\xb1\\xc7\\xc4\\x0f\\x2c\\x86\\x71\\x1d\\xfd\\xca\\x5e\\xca\\x6c\\x6e\\x7d\\x0e\\x2d\\x6f\\x81\\xe8\\xfe\\x4b\\x88\\x66\\x73\\x75\\xad\\x7b\\xde\\x7e\\x51\\x63\\x8e\\x33\\xd8\\xcd\\xf8\\x68\\xaa\\x92\\x6f\\x98\\x15\\xd4\\xb1\\x5b\\x89\\x1c\\x4d\\xf3\\xad\\x47\\xb4\\xf6\\x1b\\xc9\\xe2\\x28\\x4a\\x34\\x68\\xa9\\x6b\\x98\\xdb\\xd2\\x98\\x09\\xae\\x8e\\xad\\xc9\\x5d\\x62\\x09\\x60\\x5c\\xc0\\xeb\\x0f\\xc6\\xb8\\x95\\xaa\\x0d\\x79\\x83\\x8d\\x6c\\xce\\x8a\\x42\\xe8\\xd8\\x76\\x9a\\xc1\\xd9\\xea\\xc1\\xf7\\x9c\\xfd\\xe8\\x72\\x05\\x98\\xd7\\x7a\\x39\\x99\\x92\\x4e\\xf0\\x7d\\xfc\\x6b\\x66\\x9e\\x50\\xe9\\xe6\\x35\\xfc\\x92\\x5a\\x20\\x03\\x4a\\x1f\\xc1\\x83\\xbf\\x75\\x69\\xca\\x81\\xb1\\x5d\\x53\\x1f\\x2e\\xf5\\xda\\x0e\\x75\\xa4\\x9b\\x43\\x91\\xd1\\x12\\xb9\\xf7\\x84\\xe6\\xe6\\xd4\\xa7\\xc6\\x5f\\xbc\\xd8\\x44\\x64\\xd7\\x0b\\xd9\\x66\\x39\\x49\\xdb\\xbf\\xb2\\x20\\xcf\\x6f\\xbf\\xc4\\xac\\x40\\xfa\\x23\\xda\\x88\\xa7\\xb8\\x08\\x12\\xac\\x19\\xf1\\xde\\xf1\\x6d\\x68\\x00\\x27\\xda\\xde\\xd4\\x9c\\x48\\x16\\xa6\\x9e\\x18\\xcf\\xc8\\xff\\xea\\xdd\\x4a\\x1a\\xd6\\xb3\\xcc\\x3e\\x4d\\x55\\x7d\\x45\\x14\\x50\\x34\\x6b\\x3a\\x28\\xb2\\x43\\x41\\x4e\\x46\\x92\\xf4\\x8a\\x0e\\xe2\\x3a\\x2f\\x9e\\x9f\\x58\\xe8\\x98\\xed\\xa2\\x06\\x63\\xd5\\xf7\\xb2\\x2f\\x21\\xf4\\xbc\\x5b\\xe3\\x30\\x74\\x7b\\x50\\xc7\\xea\\xe8\\x8a\\x4f\\xae\\x88\\x3d\\xac\\x89\\x0f\\x9a\\xef\\x99\\x76\\x59\\xfc\\x43\\x01\\x91\\xb6\\x60\\x7d\\xbc\\x84\\x97\\x80\\x2b\\x65\\xf5\\xcd\\x42\\xfa\\x8e\\x11\\xc6\\x80\\x4f\\xd3\\x72\\x32\\xe7\\x0a\\x37\\x20\\xfd\\x51\\x60\\x71\\x4e\\x5f\\xf2\\xb8\\x67\\xc4\\x3f\\x10\\x6e\\x49\\xd2\\xab\\x58\\x17\\x42\\x56\\xe2\\x49\\x24\\xb9\\xcd\\xcd\\xe1\\x5f\\xfe\\x84\\xc4\\xd2\\x0c\\x46\\xa5\\x9e\\x8f\\x37\\xf3\\xe1\\x59\\x0a\\x64\\x40\\xa6\\xe5\\x24\\xba\\x70\\xea\\x67\\x4a\\xd1\\x8b\\xf1\\x2c\\xc1\\xf9\\x0c\\xf9\\xe0\\x7b\\x85\\x57\\x3c\\xa6\\x5c\\xa0\\x2e\\xdb\\x0d\\xde\\x1f\\x76\\x92\\x78\\x73\\xab\\xf7\\xba\\xb0\\x4c\\xb6\\x0c\\xfc\\xa9\\xcb\\xb4\\x2d\\x0a\\x5f\\xe3\\x6d\\xdf\\x6d\\x04\\x70\\x6d\\x34\\x6a\\x3c\\xb5\\x91\\x8b\\xdb\\xce\\xf9\\x3c\\xa0\\x97\\x48\\x8a\\x54\\xd1\\x36\\x40\\x64\\xc7\\x0b\\x82\\xed\\x77\\xb4\\x21\\x10\\xd3\\x81\\x90\\x9e\\x32\\xf1\\xf9\\xa9\\xa1\\x24\\x0d\\x23\\x78\\x35\\xa2\\x28\\xda\\x21\\xde\\x02\\x7d\\x0b\\x71\\xaa\\xed\\x9c\\x8a\\x2c\\xde\\xb9\\x02\\x69\\x7e\\xbb\\xea\\xe8\\x13\\x59\\xac\\x8f\\xff\\xd6\\xfe\\x7b\\x4a\\x27\\x83\\xc4\\x5f\\xe8\\xbf\\x54\\x9a\\xe6\\x6b\\xa6\\xd5\\xd2\\xd6\\x6d\\x7a\\xf7\\x5a\\x2f\\x28\\xd6\\x3b\\x7a\\xe9\\x70\\xa4\\x10\\xbf\\x37\\xf4\\x6a\\xc8\\x57\\xfa\\xce\\xf0\\x7c\\x58\\xf1\\xfa\\xc4\\x72\\xd9\\xf3\\x78\\x81\\x22\\x3d\\xe7\\x55\\x68\\x34\\x17\\x3a\\xc3\\xa2\\xde\\x10\\x22\\x56\\xcc\\x05\\x31\\xf3\\xde\\x5a\\x9f\\x49\\x96\\xa2\\xe0\\x9c\\x3a\\x1c\\xa0\\x51\\xac\\x7a\\xf0\\x5b\\xa5\\xcb\\x60\\xcc\\xc6\\xbf\\x9c\\x10\\x49\\x17\\x3c\\x2f\\x8c\\x42\\x92\\xe6\\xbf\\x6f\\xbf\\xb9\\xf4\\x5a\\x5a\\x1c\\x95\\x04\\xdb\\x6d\\x7e\\xbf\\xfb\\x84\\x89\\x1f\\xcf\\x62\\xb9\\x29\\x65\\x24\\x95\\x22\\xf8\\x99\\xf5\\xcb\\x9b\\x1f\\x6b\\x76\\xf0\\xc5\\x85\\x6e\\x0f\\x4e\\x11\\xd9\\x0c\\xbd\\x25\\x44\\x18\\xe0\\x19\\xc5\\x80\\xd8\\xb8\\xfe\\xa4\\x10\\x74\\x79\\x42\\x59\\x89\\xb6\\xbb\\xdc\\xb8\\x2a\\xa5\\x40\\xce\\x9c\\x33\\x74\\xce\\x6c\\x03\\xf5\\x61\\x76\\x1d\\x3d\\x6c\\x57\\x35\\x2f\\x02\\xba\\xfe\\x18\\x3a\\x7c\\x22\\xdf\\xa9\\xf6\\xbc\\xbd\\x39\\x51\\x80\\xd5\\xc5\\xbd\\x22\\xf1\\x85\\xb9\\xac\\x98\\x3a\\x33\\xd1\\x2f\\x94\\x0d\\x26\\xbf\\x18\\xa6\\xb7\\x25\\x2f\\xd9\\x61\\xe2\\xdc\\x96\\xf2\\x44\\xe7\\xc0\\xe7\\x75\\x4c\\x55\\x9a\\x14\\xa8\\xc4\\x1b\\xe2\\xf9\\x78\\x40\\x8d\\x30\\x18\\x32\\xf3\\xdb\\xb1\\x38\\xb2\\x5b\\xce\\x67\\xf3\\x4e\\x7e\\xf5\\x4e\\x26\\xac\\xb2\\xaa\\x16\\x0a\\x28\\x2a\\x6b\\xfa\\x80\\xe9\\xf2\\x07\\x92\\x7e\\xb1\\x4e\\x7d\\xaf\\x2d\\xca\\x53\\xb2\\x78\\xfa\\x44\\x71\\xfd\\x81\\x30\\x94\\x68\\xea\\x70\\x1c\\x3b\\xf3\\xaf\\xd8\\x11\\xe2\\x48\\xd1\\xec\\x50\\xc4\\xea\\xb2\\x53\\x2a\\xa3\\x0a\\xd2\\xde\\xde\\x4a\\x21\\x79\\x83\\x6f\\xb5\\xaa\\xe5\\x25\\x42\\xb4\\x6f\\xb1\\xf3\\x63\\xaf\\x0d\\xd9\\x32\\xad\\x34\\xdc\\xe4\\x6a\\xa6\\x77\\xc7\\x75\\x25\\xf6\\x2b\\xa2\\x34\\x65\\x52\\xec\\xc9\\xe8\\x36\\xd1\\x7a\\x59\\x66\\x18\\xc8\\x5a\\x77\\x5a\\x1b\\xbe\\xa3\\x3d\\xf6\\x8b\\x97\\x62\\x38\\x87\\xb5\\x40\\xa6\\x36\\xaf\\x68\\xeb\\xa5\\x42\\x6f\\x04\\x81\\x72\\x63\\x98\\x0e\\x48\\xca\\x72\\x8b\\x49\\x81\\xb6\\xbd\\xea\\x7f\\xec\\x9d\\xfb\\xda\\x0f\\x61\\xe0\\x3d\\xaa\\x73\\xdb\\x61\\x12\\x1b\\x32\\xf8\\x19\\x37\\xba\\x05\\x22\\xcc\\x29\\x23\\x81\\x45\\x7d\\x77\\xcd\\x32\\x8a\\xa4\\xc7\\xcd\\x62\\xc0\\xcf\\x68\\x4a\\x90\\xe2\\xef\\xef\\x11\\x37\\xb7\\xee\\x9e\\x3e\\x7b\\x57\\xb9\\x35\\xd1\\xc7\\xed\\xc1\\xde\\x00\\xac\\xbb\\xfc\\x90\\x39\\x7c\\x37\\x60\\xb8\\xed\\x8e\\x26\\x05\\x93\\xa8\\x06\\x3b\\x04\\x46\\x04\\x69\\x10\\x2f\\x11\\x90\\xfe\\xbc\\x1f\\xac\\xed\\x7b\\xa5\\x00\\xca\\xcb\\xb6\\x91\\x36\\x10\\xfb\\xa6\\x3e\\x82\\x44\\x34\\x66\\x35\\xe1\\x00\\x68\\x20\\xa4\\x76\\x20\\x04\\x16\\xa1\\x48\\x07\\x81\\x05\\x20\\xae\\x1e\\x6a\\x72\\xf0\\xe0\\x3a\\x94\\x1a\\xa5\\x40\\x09\\xe6\\xe7\\x2c\\x66\\x76\\xef\\x1a\\xfe\\x1b\\x03\\x95\\x29\\xc5\\xb9\\xd1\\xb8\\x46\\x17\\xc3\\x24\\x0d\\x8c\\x46\\x1e\\xfb\\x75\\x2b\\xbe\\xdd\\xba\\x6e\\x29\\xbc\\xe2\\x47\\x48\\x9e\\x08\\x1d\\xd1\\x71\\x18\\x8c\\xc9\\x80\\x9f\\xd9\\x84\\x83\\x20\\x55\\x5a\\x12\\xc8\\xd1\\x20\\x80\\x37\\x55\\xaf\\x80\\x20\\x51\\xe8\\x53\\xe9\\xd6\\xd8\\x4a\\x9c\\x5b\\x48\\x26\\x7d\\x1a\\xfe\\x9a\\x39\\x07\\xe3\\xbd\\x92\\x6d\\x06\\x7a\\xb1\\xe7\\x30\\xe1\\x52\\xa0\\xe5\\x30\\x9c\\x1b\\x82\\xca\\x9f\\xbf\\x9c\\xaa\\x3d\\x9e\\xda\\x21\\xa6\\xcb\\x26\\xc2\\x32\\xaf\\x66\\x0b\\x31\\x5e\\x22\\xf3\\x72\\xeb\\x2f\\xd9\\x8b\\x41\\x8b\\xea\\xce\\xec\\xfa\\xaf\\xd6\\xc2\\xfd\\x7a\\xb6\\xa6\\xec\\xb2\\x62\\x2c\\x5e\\xe6\\x8d\\xee\\x2d\\xe9\\xd2\\x92\\xa0\\xb7\\xb0\\x10\\xfe\\x84\\x95\\xeb\\x34\\x86\\x24\\xf4\\x1f\\x28\\xe7\\x8b\\x67\\xcf\\x08\\xa0\\x50\\x66\\x83\\xb9\\x57\\x56\\x90\\x7a\\xe1\\x5f\\x5d\\xef\\xd8\\xd2\\xf7\\xd8\\x08\\x84\\x06\\xb4\\x46\\x55\\xda\\xf9\\xd4\\xb8\\x7b\\xd7\\xac\\xc7\\x0f\\x7f\\x4d\\x02\\xa8\\xd7\\x06\\xad\\x19\\x77\\x53\\x86\\x39\\xfd\\xeb\\x97\\xd0\\xf8\\xe1\\x4f\\x22\\x01\\x90\\x1d\\x6e\\x3e\\x31\\x20\\x21\\x1e\\x84\\x13\\xcd\\x76\\xfc\\x17\\x7d\\x4f\\x0f\\xe4\\xb2\\x65\\x4a\\x22\\xc9\\xa7\\x07\\xa1\\x52\\x92\\x46\\x01\\x81\\x86\\x54\\xcd\\x77\\x20\\x1a\\x1f\\x67\\xa0\\xef\\xf5\\xbf\\x4b\\x1a\\x1f\\xb8\\xdf\\x83\\x29\\x80\\x8d\\xb8\\xf1\\x15\\x8f\\xe4\\xe5\\x4f\\x13\\x08\\xdc\\xf5\\x61\\xa3\\x5c\\x08\\xd9\\xd8\\x29\\xb3\\x6b\\x6e\\xf2\\xcb\\x23\\x41\\xef\\x64\\x7a\\x8a\\x25\\x3f\\xb2\\x41\\xa9\\x59\\x5c\\x77\\x10\\x39\\xa5\\x5f\\xd4\\xf7\\xe0\\x05\\xa8\\xe1\\x88\\x2f\\x39\\x24\\x7e\\xc6\\x2c\\x61\\xc0\\x98\\xb5\\x4e\\x24\\xd6\\x11\\xc0\\xeb\\xc1\\x00\\x75\\xf2\\x7c\\xab\\x54\\x23\\x9a\\x77\\x20\\xa7\\xc7\\x52\\x96\\x15\\x7f\\xb2\\x5c\\xbb\\x12\\xfc\\xc7\\x79\\xff\\x1d\\xec\\xd9\\x64\\xce\\xbc\\x47\\x28\\x88\\x47\\x16\\xfe\\xe4\\xe1\\xcf\\xb4\\x23\\xd0\\x42\\xa3\\x85\\x52\\xac\\x32\\x1a\\x70\\xb3\\x98\\x92\\x33\\x1b\\xf1\\x3f\\x89\\x0a\\x8c\\xaf\\xb2\\xef\\xdc\\x82\\xce\\x16\\xca\\x4b\\x4b\\x7a\\xc1\\xa4\\x09\\x82\\x24\\x6c\\x16\\x8d\\x2b\\xae\\xcc\\x5f\\x32\\xdb\\x27\\x65\\x41\\x3b\\x06\\x59\\xb5\\xd3\\xf6\\xf7\\x97\\xb3\\x23\\x0e\\x8b\\x88\\x63\\x24\\x37\\xf6\\xad\\x30\\x47\\x4a\\x64\\x7b\\xd5\\x1e\\xc4\\x97\\xe7\\x80\\x89\\x25\\x27\\xa2\\x01\\xd2\\x5d\\xf6\\x4d\\x20\\xff\\xd8\\xb8\\x16\\x97\\x21\\x49\\xea\\x6a\\xc0\\x2b\\x32\\x4d\\xbd\\x85\\x65\\x6c\\xf1\\x3e\\x33\\x49\\xfa\\x60\\x6a\\x54\\xd4\\x1c\\xd5\\x94\\x40\\xa5\\xb5\\x53\\x9f\\x41\\xc9\\x44\\x51\\xc2\\x50\\xdf\\x71\\x20\\x73\\x94\\x54\\x9e\\x86\\x15\\x04\\x1b\\xf1\\x29\\x55\\x57\\x7a\\xb1\\x99\\x63\\xb1\\x99\\xb3\\x0a\\x24\\x4a\\x0e\\xb4\\xbe\\x7d\\x52\\xde\\xfc\\x4f\\xa3\\x69\\x7a\\xba\\xd0\\x31\\xec\\x17\\x22\\x9a\\x70\\xa0\\xf0\\xe2\\x35\\x37\\xc9\\x0e\\xa8\\x37\\xf5\\xa6\\xd2\\xcb\\x99\\x45\\x0f\\xbf\\xd3\\x73\\x59\\x73\\xbe\\x3a\\x46\\x11\\x64\\x01\\x74\\xe0\\x3c\\x1f\\x32\\xfe\\x9e\\x17\\x0d\\xcb\\x73\\x30\\xf9\\x7f\\xc3\\xe5\\xea\\x5a\\x8d\\x29\\xd4\\x5f\\xa6\\x95\\x72\\xc4\\x54\\x5c\\xd7\\x73\\x53\\x97\\xfc\\x9a\\xeb\\xf7\\x79\\xe8\\xfd\\x4d\\xdc\\x40\\x1f\\x5f\\x28\\x11\\x9b\\x1d\\x1e\\xd5\\xb7\\x5f\\x6c\\x2f\\x92\\xb4\\x17\\x3b\\x9f\\x8b\\xa9\\x75\\x2a\\xf8\\x95\\x32\\x2b\\x3b\\x72\\x69\\x4a\\x21\\x9c\\x21\\x24\\x4e\\x00\\xf6\\x62\\xeb\\x40\\x23\\x43\\x72\\x62\\x88\\xd0\\x48\\xbe\\x9f\\xe4\\x40\\x69\\x58\\xb3\\xe1\\xb1\\xa6\\xe3\\xc6\\x5b\\xc5\\xfd\\x0c\\x0d\\x23\\xd8\\x29\\x6f\\xc3\\x85\\xe5\\xc1\\x85\\xf1\\xe5\\x12\\x8f\\x01\\x8b\\xf5\\xef\\xd5\\xe6\\xa1\\x79\\xd0\\x61\\xb9\\x7a\\x27\\x7f\\x3e\\x6c\\xd8\\xe8\\x9a\\x8e\\x3d\\x19\\xbe\\x40\\x55\\xee\\x48\\x15\\xa1\\x34\\xd9\\xc1\\xc4\\x6b\\x6e\\x0e\\x93\\x3f\\x23\\x75\\x4d\\xd4\\x87\\x53\\x60\\x8a\\x34\\x73\\xac\\x3f\\x5e\\x8b\\xab\\xae\\xb0\\x33\\x97\\x6c\\x66\\x92\\x10\\x0d\\xe2\\x65\\xf4\\x79\\x10\\x84\\x77\\x46\\x57\\xd3\\x87\\x83\\x4f\\xca\\x89\\xef\\x7f\\xda\\xc5\\x47\\x7d\\x6b\\xf4\\x27\\x07\\xe0\\xc5\\x15\\xac\\xd6\\x97\\xa3\\x48\\x51\\x17\\xbc\\x0d\\x19\\xab\\xf5\\x61\\xcd\\x4d\\x55\\x3a\\xff\\xc9\\x9f\\x5e\\x5a\\x12\\x2d\\x08\\xfe\\x29\\x54\\x02\\xcf\\xa2\\x74\\xf3\\x30\\xb7\\x77\\xa2\\x19\\x52\\x52\\x5f\\xd8\\x9c\\x50\\xf2\\x0a\\xe6\\xbb\\xdb\\x9c\\x80\\xe5\\xe6\\x4d\\x6c\\x84\\x37\\xbc\\x8a\\x52\\x69\\x8f\\xcf\\x72\\x02\\x63\\x3b\\xd2\\x3b\\xaf\\xea\\x95\\x1d\\x08\\x7d\\xa2\\x20\\x79\\x80\\x01\\x02\\x1f\\x64\\x79\\xfa\\xf0\\x4b\\x57\\xca\\x06\\x13\\x40\\xa5\\x0c\\x50\\x7f\\xb8\\x41\\x92\\x6b\\x4d\\xae\\x0e\\xd5\\x0b\\xe1\\x42\\xf3\\xe8\\xdf\\x79\\xd4\\x10\\x26\\x19\\xc9\\x99\\x0d\\x78\\xf8\\x03\\x26\\x49\\xeb\\xf1\\x32\\x61\\x9d\\xc5\\x26\\xf0\\x3d\\x77\\x80\\xd8\\x3f\\x83\\x29\\x08\\x82\\x8c\\x85\\x81\\x6b\\xc2\\x78\\x19\\x94\\xb9\\xee\\xe7\\x40\\x61\\xcb\\x91\\xac\\x10\\x88\\x6e\\xff\\x01\\x84\\xda\\xad\\xf7\\x81\\x12\\x3b\\x29\\x21\\x1c\\xf3\\x49\\xa0\\xf0\\x63\\xf7\\xe1\\x26\\x8a\\xcc\\x80\\x0e\\xd9\\xf5\\x7f\\x4c\\x2f\\xcc\\xbe\\xc0\\xe2\\xbf\\x2f\\x79\\x81\\xdc\\xba\\x81\\xcc\\x19\\x7e\\x7e\\xc0\\xde\\x78\\xd9\\x38\\xa2\\x10\\xcb\\x75\\xcb\\x39\\xcd\\x4e\\x0f\\x07\\x59\\x2c\\x44\\x19\\x9d\\x57\\xb4\\xed\\x88\\x71\\xe2\\x7b\\x66\\x7c\\xc9\\xe3\\x5f\\x00\\x71\\x9c\\xd7\\x46\\xae\\x84\\xd9\\xf4\\x80\\x34\\x83\\x12\\x80\\x5a\\xa5\\xa5\\x76\\x2a\\x4f\\xaa\\xcd\\x9c\\xf6\\xca\\x6a\\xc5\\x8d\\x76\\x83\\xdd\\x18\\x29\\x14\\xc0\\xb0\\x38\\xcc\\x7b\\x3e\\x65\\xfb\\x8a\\xbc\\x01\\xb2\\xf9\\x51\\x26\\x7d\\xc5\\x4a\\x4a\\xdf\\x36\\x52\\xf2\\xc1\\x0a\\xff\\xcb\\xdb\\xac\\x84\\xb8\\xd6\\x63\\x96\\x4a\\x46\\x03\\xc0\\x10\\xc3\\xb4\\xee\\xf1\\x76\\x83\\x6b\\xea\\x4b\\xa1\\xbf\\xbf\\x71\\x94\\x55\\x5d\\x3b\\x3c\\x49\\x31\\xb5\\x52\\xb3\\x29\\x5d\\x9e\\xc9\\xa2\\xbd\\x23\\xdd\\x86\\x62\\x1d\\x6f\\x26\\x6f\\x63\\xb9\\xe1\\x07\\x81\\xff\\x34\\xec\\x5f\\x8c\\xb9\\xf2\\xb4\\x90\\xe5\\xac\\x8b\\x7c\\x40\\x3c\\x69\\x51\\x49\\x2a\\x5e\\x70\\x9d\\x83\\x02\\x95\\x79\\x44\\x25\\xba\\xe0\\xe6\\x02\\x5d\\x8f\\x4c\\xc2\\x20\\x88\\x92\\x03\\xd5\\xf8\\x2f\\x91\\xa5\\xc0\\xd5\\x11\\x75\\x78\\x65\\x64\\xc6\\x3c\\xf5\\xbb\\x88\\x05\\x1f\\x4d\\x3e\\xcd\\xa0\\x10\\x14\\x28\\x42\\xd6\\xfc\\xae\\xea\\x09\\x0e\\x29\\x84\\xe6\\xb5\\xd4\\x5a\\x6c\\xfb\\x1b\\x7f\\xaa\\x35\\x79\\xae\\xcf\\x9e\\x7b\\x3f\\xa5\\xa1\\x2b\\x87\\x15\\x23\\x6c\\x53\\x64\\x9e\\x8d\\x9b\\xde\\xc8\\x80\\xc5\\x1f\\xf3\\x6a\\xd3\\xb7\\x50\\x13\\x43\\xc6\\xb1\\xc8\\x36\\x9c\\xfb\\x97\\x5c\\xe6\\x45\\x90\\x9b\\xd5\\x68\\xf6\\x9f\\x68\\xff\\xd1\\xf7\\xc4\\x84\\xc2\\x3d\\x2d\\x68\\x5a\\xa1\\x75\\x84\\x92\\x8c\\x42\\x23\\x2c\\xa3\\xb0\\xae\\xc4\\xdf\\x77\\x1f\\x6a\\xae\\x16\\x66\\x06\\x02\\xe6\\xaf\\xbe\\xe9\\x2c\\xeb\\xf4\\x7b\\xd0\\x95\\x56\\x87\\xc5\\xd6\\xdd\\x72\\xb2\\xe9\\xb1\\xc8\\x9e\\xa5\\xc8\\x9e\\x10\\x9b\\x42\\x5f\\x79\\x20\\x39\\x5f\\xb2\\xa3\\x1b\\x0c\\x90\\xe0\\xf9\\x2d\\x3e\\xf6\\x63\\x64\\x25\\xd4\\xbc\\xde\\xc1\\x00\\xa6\\xb1\\xbc\\x67\\xf8\\x42\\x61\\x50\\xfe\\x14\\x9a\\x0f\\x67\\x2a\\x46\\x17\\x42\\xac\\xe3\\x03\\xf7\\x1b\\xcb\\xbd\\x0b\\x5f\\xff\\xec\\xd7\\xee\\x77\\xe7\\xf4\\x43\\x0a\\x88\\x04\\xda\\xf2\\xa0\\x59\\x4d\\x7f\\xf6\\xa8\\x84\\x01\\x9b\\x5d\\xb3\\x28\\x08\\xbd\\x27\\x06\\x03\\x9e\\x44\\x5a\\xaf\\xe8\\x78\\x14\\x9d\\xf8\\x36\\xb4\\x30\\x37\\xc3\\x87\\x21\\xef\\xa1\\xa6\\x3d\\x08\\xed\\xae\\x3e\\xb2\\xfb\\xda\\x8f\\x48\\xcc\\x89\\x48\\xeb\\x59\\x60\\xe1\\x10\\x7a\\x74\\x2f\\xe5\\xfa\\x92\\x7f\\xca\\x6c\\xc4\\xce\\x6b\\xf7\\x1b\\x05\\x01\\x3d\\x94\\x90\\x15\\x45\\x76\\xc4\\x19\\x9c\\x08\\x20\\x85\\x44\\x2b\\x2b\\x2a\\x53\\x2a\\x00\\x50\\xb6\\x95\\x73\\xe2\\x8e\\x1e\\x5f\\x4c\\x57\\x62\\xe4\\xcd\\xe4\\x98\\xda\\xfe\\x63\\x34\\xff\\xa9\\xfe\\x74\\xc4\\x6f\\xe5\\x65\\x49\\xc3\\x13\\x2b\\xa5\\x13\\xab\\xa4\\x01\\xef\\xe9\\x3c\\xac\\x3a\\x7f\\x51\\x3d\\xa5\\xba\\x13\\xfa\\xfc\\x52\\xb2\\x78\\xe1\\x15\\x13\\xd9\\x3a\\x7e\\xf0\\x14\\x61\\x6b\\x46\\xf1\\x2b\\x0f\\x3d\\x79\\x20\\x92\\xd6\\x3e\\xc1\\xc4\\xe2\\xf0\\xe6\\x82\\xdf\\xf6\\xf6\\x5f\\x9d\\x21\\x6b\\xa3\\xb2\\x16\\x00\\x00\\x55\\x4b\\xe5\\x64\\xd9\\xfb\\x6d\\x0c\\xb6\\x32\\x27\\xa0\\x7a\\x4a\\x99\\xe3\\x6c\\x2c\\xb7\\x1c\\xb8\\xcc\\xea\\x6b\\x97\\x79\\x88\\x83\\xdf\\x7d\\x53\\xdb\\x27\\x3f\\xdf\\x99\\x39\\x92\\x31\\x19\\x6b\\x71\\xb9\\x20\\x5a\\x7f\\xa0\\xbd\\x56\\xa4\\x3f\\x34\\x1b\\x79\\xdb\\xe6\\x51\\xdb\\x24\\xda\\x3f\\x8f\\xd8\\xc5\\x7e\\xa5\\xec\\x98\\xae\\x74\\x0f\\xc8\\x27\\x7d\\x1c\\xf3\\x7a\\x12\\x5b\\x30\\xa0\\x4b\\x8c\\xc3\\x0a\\x8a\\xda\\x6d\\x2b\\x79\\xea\\xa1\\x22\\xf8\\x42\\x77\\xef\\x89\\xa5\\xfb\\xd4\\xac\\x32\\x0c\\x53\\x33\\xc2\\x20\\xd8\\x81\\x3d\\xa1\\x42\\x81\\xa9\\xdc\\xbc\\xba\\xe3\\xe7\\x05\\x41\\x10\\xa4\\x70\\x79\\xf5\\x1e\\xac\\x31\\xf6\\x01\\xe4\\xa8\\xf2\\xae\\xeb\\xba\\xea\\xc2\\xbc\\xb0\\x32\\x28\\x31\\xf0\\xf3\\xac\\xaa\\xb9\\xbd\\x08\\x73\\x43\\xbf\\xe0\\xbf\\xd8\\x1d\\x6e\\xcb\\xe4\\x01\\x73\\x08\\x31\\xf9\\x88\\x7f\\xc7\\x36\\x2a\\x6b\\x7a\\x6e\\x35\\x26\\x73\\xa7\\x51\\xfb\\x12\\x7b\\x57\\x5e\\xb2\\x43\\xff\\xce\\xac\\x90\\x47\\x8f\\xf9\\x1d\\xc6\\xf8\\xd9\\x0c\\x39\\x6f\\x0f\\x05\\x38\\x72\\xd7\\x25\\x5f\\x3d\\xbb\\xc2\\xc1\\x33\\x19\\xcf\\x92\\x4b\\xe0\\x8a\\x8f\\xee\\x09\\x83\\xc2\\xf9\\x03\\x22\\x68\\x0f\\x86\\x6a\\x41\\xa4\\xc1\\xef\\x54\\xb7\\x8c\\x6c\\xb7\\xc2\\xae\\x71\\xdf\\xf8\\x25\\x34\\x48\\x5f\\x2f\\xbe\\x16\\xe6\\xe4\\x86\\x0f\\x0e\\x11\\xa6\\xc4\\x53\\x40\\x65\\xbe\\x74\\xe7\\x2d\\x6b\\x32\\x42\\x3f\\x85\\x8b\\x23\\x6e\\x51\\xed\\x9e\\x17\\xb0\\x15\\xcd\\xef\\x49\\xb1\\x05\\x44\\xe3\\xe5\\x2f\\xc5\\xd2\\x50\\xbe\\x54\\xfd\\x2f\\xff\\xb2\\x75\\x2c\\xd6\\xc2\\x18\\xc2\\x6f\\xbf\\x94\\x3a\\x63\\xbb\\x03\\x40\\x43\\xbd\\xb8\\x19\\x71\\x6e\\x4a\\x58\\x7a\\x1a\\x0d\\x8c\\x16\\x68\\xc1\\x1c\\x99\\x0b\\x1d\\x4a\\xe5\\x5f\\x04\\xec\\x07\\x3f\\x5b\\xd0\\x84\\x40\\x71\\xa7\\x97\\x8d\\xfd\\xc4\\xec\\x07\\xf2\\xef\\xfe\\x2f\\x1b\\x8b\\x0d\\xb8\\xf0\\x7c\\x96\\xf5\\x7a\\x2a\\xaa\\xa7\\xae\\x81\\xa6\\x9b\\x20\\x68\\xaf\\x1f\\x70\\xd0\\xac\\x9d\\x99\\xe3\\x0c\\xe7\\xb2\\x60\\x9a\\x32\\x63\\xdb\\x61\\x84\\xd9\\x79\\x54\\xb7\\x9f\\x81\\x98\\x2a\\xc4\\x09\\x1b\\x8b\\x0b\\xe1\\xd8\\x84\\x9d\\x49\\xd2\\x38\\xbf\\x85\\x48\\x47\\x67\\x89\\xa9\\x43\\x73\\x21\\x66\\x70\\x48\\xf0\\xbc\\x93\\xa6\\x0d\\x7f\\xae\\xf4\\x96\\xae\\xb1\\xc4\\x76\\xc3\\xab\\x72\\x41\\x52\\xa6\\x52\\x69\\x6c\\xf6\\x99\\x71\\xea\\x67\\xf6\\x38\\xb6\\x33\\x21\\x33\\x70\\x50\\xef\\xf0\\xce\\xb2\\x35\\xcd\\x07\\x4b\\x67\\xdc\\x14\\xc7\\xfc\\xe3\\x7b\\x91\\xed\\x1d\\xd5\\x36\\x91\\x43\\x6c\\x1a\\xe6\\x0d\\x83\\x7e\\x91\\x39\\x93\\xb1\\x83\\xda\\x95\\x41\\x8b\\x04\\xea\\x99\\x61\\x69\\x99\\x83\\x72\\x7e\\x2c\\xf5\\xe1\\x29\\xf7\\x64\\x74\\x04\\x47\\x0c\\x86\\xa5\\x70\\x50\\x3e\\x7b\\xb0\\x4b\\x3e\\xbd\\x1e\\xf7\\x03\\xeb\\xf8\\xd7\\xaf\\xc4\\xfe\\xd9\\x29\\xaf\\x17\\x0f\\x5d\\x0a\\x0e\\x04\\x5b\\x6e\\xa2\\xc3\\x8e\\x1f\\xe8\\x2e\\xb1\\xc5\\x2a\\x57\\x0f\\xfa\\xe4\\x51\\xab\\x5b\\xc2\\x59\\x38\\x5b\\xd3\\xb3\\xe0\\x75\\xb5\\x3c\\x9a\\x35\\x75\\xd8\\x2f\\xd0\\x2c\\xe1\\x7c\\x07\\xe1\\x5a\\x45\\xad\\xbc\\x2d\\x43\\x4b\\x16\\xde\\x0d\\x02\\x3f\\xd0\\x1e\\x92\\xbe\\x09\\x4b\\xf4\\x95\\xdf\\x9f\\xdf\\xd9\\x06\\x84\\x66\\xdb\\x2e\\x9e\\x91\\xc2\\x2a\\xa2\\x00\\x36\\xb4\\x6c\\x59\\xd5\\x76\\xa6\\x4d\\xd2\\x13\\x61\\xfe\\x06\\xb6\\x60\\x4b\\x7c\\x96\\xcf\\x57\\x57\\xf6\\xe2\\x3d\\xf4\\x7f\\x32\\x6c\\x78\\xfe\\xb5\\xcb\\x6e\\x5e\\xe9\\x4c\\x48\\x71\\x5a\\x7b\\xeb\\xc6\\xc7\\x8a\\x6f\\x3a\\xab\\x6a\\x2b\\x5f\\x9f\\x9f\\x96\\xd3\\x09\\x5b\\xe7\\xbe\\xfd\\x76\\x34\\xa3\\x94\\x15\\xa8\\x23\\x2c\\x26\\xed\\xfa\\x6f\\x3c\\x92\\x9b\\x7a\\x44\\x19\\x1d\\x92\\x83\\x05\\x48\\x04\\x32\\x8c\\xf6\\x3b\\x55\\xde\\xc6\\xfe\\xd8\\xc3\\x13\\x13\\x4a\\xff\\x84\\xc7\\x0f\\x58\\xbb\\xfe\\x29\\x9a\\xdb\\xaf\\xeb\\xaa\\x76\\x4c\\xaa\\xda\\xc2\\xdf\\x9a\\x69\\xe3\\xb1\\xa6\\x4b\\x23\\x1c\\xce\\x7a\\x95\\x77\\x40\\xb6\\x3c\\xfa\\xcc\\x0e\\x2c\\xf7\\x19\\xb4\\x4a\\x5e\\xd9\\xc7\\x73\\x19\\xc7\\xf4\\x31\\xbf\\x49\\x0e\\xe7\\x9a\\x8f\\xb7\\x83\\x73\\xff\\x6f\\x7f\\x00\\x4c\\x0e\\xe7\\x5a\\x1e\\xe2\\xe4\\xb1\\x03\\x7f\\x80\\x1b\\x4c\\x8a\\x62\\xd2\\x33\\x37\\xa5\\x02\\xc1\\xcf\\x0f\\x2c\\x3b\\x37\\x1c\\x25\\xa4\\x00\\x57\\x11\\x48\\x26\\x9a\\x61\\x6a\\xd0\\x78\\x47\\x57\\x59\\x9b\\xe3\\xb6\\x64\\x83\\x29\\xd2\\xfc\\x6a\\xa2\\x63\\x7d\\xc1\\x76\\xf8\\xc4\\x0e\\xe0\\xa2\\x3a\\xa7\\x2f\\x81\\x4f\\x34\\x3b\\x34\\x17\\x7e\\x32\\x57\\x69\\xe7\\x55\\x5d\\xf5\\x46\\x0e\\x3d\\xcd\\x40\\xf6\\x38\\x75\\xe7\\xcd\\xfa\\xd7\\x3c\\xe0\\x01\\xbb\\x9e\\x95\\xa9\\xca\\xe2\\xea\\x6d\\xc5\\x4c\\x77\\x46\\x79\\x2c\\x69\\xb3\\x91\\x30\\xb7\\x96\\x7f\\xf8\\xa5\\x5a\\x9e\\xba\\xe5\\x4f\\x94\\x2a\\x3d\\xc3\\x57\\x94\\x58\\x39\\xb7\\x51\\x69\\x63\\x53\\xf2\\xe6\\x5a\\xc5\\x39\\x28\\x5b\\x0c\\x91\\x6e\\x61\\x20\\xe3\\xf8\\x50\\x0d\\x38\\x15\\x3e\\x32\\x65\\xd1\\x95\\xe2\\xdc\\xc4\\x80\\xfb\\x14\\x81\\x59\\x7f\\xdd\\x83\\xb7\\xa0\\x57\\xff\\x44\\x1e\\x26\\xfe\\xd5\\xf0\\x56\\xb6\\x76\\xfd\\x51\\xf9\\x09\\xb4\\xcd\\xda\\xfe\\xef\\xbf\\xef\\xa7\\x23\\x01\\x9b\\x84\\x7f\\x03\\x98\\xb1\\xd3\\x83\\x40\\xd1\\x53\\xbe\\x19\\x37\\xe7\\x45\\xb1\\x3e\\x99\\x62\\x26\\x6e\\x9d\\x0b\\xf7\\x49\\xe9\\xdc\\xf4\\x4d\\xf4\\x9c\\x8a\\x3d\\xae\\x13\\xaf\\x26\\x17\\x84\\xec\\x05\\x1a\\xdc\\x82\\x99\\xb5\\x2e\\xa8\\xe1\\x58\\xdf\\x29\\x51\\x82\\x72\\xe2\\x33\\xac\\xc5\\xc5\\x12\\x1a\\xa5\\x27\\xfc\\x55\\x7c\\x99\\xfe\\x12\\x06\\xba\\x4f\\x44\\x9b\\xe1\\x4e\\xa5\\xf7\\x26\\x3e\\xb7\\xbc\\x9b\\x81\\x33\\xf5\\xdb\\x1f\\x0a\\xa8\\x84\\x66\\xb1\\xbf\\x3a\\xef\\x6a\\x38\\xe7\\x40\\x0d\\xa2\\x2d\\x2f\\x47\\x7f\\xb7\\xae\\x83\\xda\\x4d\\xeb\\xa3\\x47\\x5d\\xca\\x4b\\xcb\\x12\\xb5\\xaa\\xeb\\xc2\\x47\\x7a\\xc5\\xaf\\x07\\x4e\\x9a\\x8d\\x93\\xc6\\x90\\x60\\x4a\\xd2\\x6e\\x8a\\x5c\\x23\\x40\\x82\\x0d\\x77\\x31\\x12\\x25\\x6f\\xae\\x0b\\x98\\xcd\\x0a\\xbf\\x9e\\xff\\x7c\\xf8\\x28\\x21\\xb2\\x40\\x3b\\xbc\\x94\\x0f\\xfe\\xd2\\xfe\\xf8\\x68\\x0b\\xd6\\x4f\\xeb\\x7e\\xe1\\x03\\x80\\x3a\\x79\\x98\\x9f\\x8c\\xdc\\x83\\x3d\\xfe\\x13\\x4c\\x04\\x8e\\x61\\x8a\\x2c\\xa5\\x01\\xfe\\xe1\\xec\\xf7\\xd0\\x70\\xb1\\x64\\x2b\\xb1\\x6f\\xcc\\x3b\\x04\\xc3\\x90\\x70\\xde\\xc9\\x31\\x82\\xd0\\x33\\x56\\xd3\\x7f\\xbd\\xc8\\xb3\\x84\\xb9\\xed\\x96\\xb7\\x91\\x77\\x92\\x2d\\xec\\xf0\\x03\\xdd\\xb1\\x90\\xbc\\x03\\x61\\x06\\x97\\xcc\\xaf\\xfe\\x6d\\x9a\\x01\\x3f\\xe5\\x57\\xaa\\xbf\\x05\\x03\\xc0\\xf6\\x46\\xc2\\x2f\\x5e\\x04\\x2e\\x37\\xa4\\x85\\x19\\x92\\x30\\x78\\x7c\\x9b\\x1f\\x08\\x92\\x04\\xaa\\xa3\\x69\\x38\\x46\\xae\\xf7\\x7a\\x35\\xd8\\xe5\\x00\\xe6\\x3b\\xd9\\x81\\x4c\\x5f\\x8e\\xdf\\x4c\\x31\\xf4\\xdc\\x07\\xc2\\x1b\\xe3\\x6e\\x31\\x39\\x48\\xc1\\x2f\\x59\\xbc\\xa6\\xeb\\xca\\x2c\\x94\\x5f\\xcf\\xec\\x47\\x53\\x58\\x81\\x08\\xe4\\x53\\x9c\\xc8\\x1d\\x3e\\x50\\x4b\\x62\\x35\\x6d\\x41\\x44\\x07\\x05\\x5b\\x82\\xd4\\xb2\\x1a\\x6d\\xf0\\xfb\\xb3\\xa9\\xcc\\x6e\\x25\\xf5\\xdd\\xd7\\x33\\xc2\\xcc\\xfc\\x33\\x46\\xda\\xb9\\x81\\xfc\\x63\\x46\\x73\\x5e\\x95\\xf6\\xcf\\x2b\\xdb\\xba\\x84\\x9d\\x68\\xfe\\xc7\\x94\\x0b\\xf9\\x7f\\x2c\\x9d\\xb5\\xd6\\xb4\\xcc\\x12\\x85\\x2f\\x88\\x00\\xb7\\x10\\x67\\x70\\xb7\\x0c\\x77\\x77\\xae\\xfe\\xac\\xf7\\xfb\\xcf\\x24\\x93\\x0c\\x2c\\x56\\x4f\\x57\\xed\\x67\\x37\\xd5\\xd5\\xfe\\x20\\x3b\\xd4\\x6b\\xbd\\x6f\\xcc\\xd5\\x25\\x3f\\xd2\\xce\\x35\\x33\\x70\\x64\\x43\\xc7\\x2f\\x35\\x18\\x0f\\x9b\\xc2\\x66\\x76\\xb9\\x66\\x17\\x40\\x4e\\x12\\x64\\x72\\x2d\\xe4\\x00\\x36\\x52\\xae\\x5e\\xd3\\x71\\x49\\x09\\xba\\x94\\x38\\xe1\\x0f\\x34\\xdf\\x2f\\x6f\\x9c\\x19\\xc9\\xac\\xc9\\xd6\\xcf\\x11\\x6f\\xe3\\x50\\x74\\x7c\\x85\\xdd\\x43\\xd5\\xdd\\xb7\\x10\\x5e\\x38\\x6f\\x48\\xa9\\xdc\\xc2\\x38\\xb6\\x21\\x95\\x3a\\x84\\xe3\\x07\\xb1\\x5f\\x84\\x74\\x8e\\x96\\xc0\\xda\\xbc\\xc6\\x0b\\xe6\\x38\\x99\\xa9\\x32\\x10\\x8c\\x8a\\x8d\\x4c\\x93\\x38\\xff\\xd7\\x7d\\x38\\x45\\xb2\\xdb\\xc0\\xf3\\x6f\\xf2\\xb4\\xcc\\x94\\xa8\\x0a\\x0e\\x5a\\x1d\\x86\\x98\\x73\\x66\\x37\\x59\\x71\\x22\\x6c\\xfa\\x2e\\x15\\x7e\\x01\\x46\\xe7\\xc3\\x62\\x6e\\xea\\xbc\\xf1\\x6f\\xbd\\x6a\\xdf\\x98\\x87\\x9e\\x59\\xb6\\xab\\x22\\xb8\\x31\\x21\\x6d\\xc4\\xcb\\xa4\\xbc\\x26\\x47\\xe9\\xb7\\x8b\\xc1\\x40\\xd1\\x9c\\x3e\\xcc\\x58\\x81\\xa9\\x33\\xe1\\x38\\x17\\x63\\xff\\x57\\xb7\\xec\\x90\\x84\\x21\\x9a\\x1d\\x18\\x75\\x5a\\x20\\xb3\\x36\\xfe\\x36\\xbc\\x4f\\x79\\xc9\\xe4\\x71\\x5e\\x30\\x49\\xc3\\x08\\x95\\xab\\x62\\x1c\\x1c\\xea\\x32\\x48\\xa6\\xb0\\x20\\x05\\x13\\x73\\xdc\\xbe\\x0c\\xcc\\xfc\\xef\\x37\\xfb\\x13\\xb3\\xc6\\x71\\x90\\xa6\\xc4\\xb3\\x0f\\xf8\\x52\\x1d\\x7f\\xbb\\xc2\\xd1\\xc4\\xa1\\x4c\\xa1\\x51\\xc3\\xdc\\x5e\\x72\\x20\\x6d\\xbd\\xa8\\xa9\\xf4\\xb4\\xca\\xdd\\xb5\\xd5\\x83\\x85\\x34\\x17\\x48\\xab\\x3f\\x28\\x36\\x55\\x5a\\x3a\\xd3\\x35\\x30\\x23\\x22\\xc2\\x30\\x2b\\x6d\\x3c\\xca\\xde\\x82\\x38\\x62\\x25\\xd6\\x59\\x68\\x1c\\x21\\xbc\\xbd\\xba\\xff\\x6f\\x5f\\xf5\\x20\\x13\\xc9\\x83\\xa8\\x4f\\xac\\xe7\\xed\\x5b\\xfc\\x88\\xa0\\x9f\\x3d\\xaf\\x42\\xf1\\xbd\\x52\\xa5\\x3a\\x16\\x59\\x14\\xc5\\xe9\\xd8\\x0b\\xf8\\x1a\\xd2\\xfb\\xb2\\x1d\\xf5\\xae\\xc5\\x0e\\xd5\\x16\\x7c\\xd8\\x88\\x02\\xd9\\x63\\xef\\x9f\\x1e\\x4b\\x75\\xcb\\xdd\\x96\\x0c\\x02\\x95\\x49\\xee\\xa6\\x6d\\x11\\x67\\x8e\\x54\\x26\\x00\\xde\\xb3\\x6f\\x3c\\x09\\x45\\x97\\xd7\\x64\\xe3\\x66\\x3b\\xaf\\x84\\xde\\x3a\\x89\\x7f\\x86\\xfc\\x79\\x83\\x3f\\x83\\x01\\x31\\x2b\\x3e\\x26\\x11\\x9b\\x59\\x37\\x31\\xc6\\xe2\\xc5\\xdd\\xa7\\x88\\xbd\\xa2\\x86\\xaf\\x43\\x1d\\x56\\xe8\\x88\\x6c\\x3e\\x6c\\x7c\\xb6\\x76\\xe4\\x59\\x74\\x1c\\xf8\\x8f\\x97\\x8d\\x26\\xa1\\x7a\\xac\\xa6\\x62\\xab\\x1e\\x18\\xdf\\x2d\\x3d\\x99\\x2c\\xd1\\xc3\\x74\\x6e\\x73\\xe6\\xf8\\x60\\xfd\\x7e\\x8e\\x99\\x6d\\x4a\\x75\\xc5\\xbb\\xfe\\xe9\\x9e\\x2f\\xf3\\xb3\\xce\\xdd\\xa5\\xf8\\x9a\\xb7\\xff\\xcd\\x1a\\x77\\x5f\\x17\\xaa\\x66\\x88\\x80\\x3b\\x9a\\xf1\\x14\\xcc\\x91\\x9f\\x91\\x36\\x04\\x41\\x10\\x4a\\xb1\\x9b\\x54\\x39\\x6a\\x7c\\x72\\xf7\\x10\\x0d\\x8f\\x7b\\x3c\\x4c\\x53\\xd5\\xae\\xf9\\xb3\\xed\\x30\\x89\\xe4\\xf4\\x2e\\xf1\\x62\\xab\\xc0\\x34\\xa6\\xcc\\xef\\xe6\\x0a\\x4c\\x03\\x69\\xc3\\x99\\x8f\\x51\\x75\\xab\\x3c\\x5e\\x18\\x4c\\x38\\x4c\\x68\\x62\\xff\\x16\\xfa\\x25\\x5b\\x24\\xbd\\x51\\xc3\\xd4\\xdb\\xad\\x5f\\xa9\\x5b\\x00\\x5a\\xe3\\xc7\\x4c\\x37\\x45\\x81\\xe6\\xd7\\x67\\x9e\\xa2\\xbf\\x6e\\xe2\\x5f\\x01\\x6c\\xd8\\x0c\\x1b\\x50\\xa3\\x52\\x44\\x21\\xbc\\xaf\\x92\\x99\\xa2\\xd9\\x21\\x0a\\x3c\\x99\\xb3\\x38\\xbd\\xdf\\x89\\x3c\\x03\\xb2\\xef\\x17\\xdc\\xbf\\x16\\x1c\\xac\\xd1\\x7e\\x03\\xf4\\x58\\x18\\x56\\x0b\\xfb\\x68\\xed\\xf4\\xb0\\x97\\x34\\xdb\\x9c\\x56\\xd5\\x62\\xc4\\x54\\x22\\x6c\\xe9\\x08\\x08\\xbf\\x19\\x62\\xbf\\xc3\\x3b\\xcf\\xd6\\x34\\x1b\\x50\\x85\\x44\\x7a\\x0f\\x15\\x88\\x4e\\xc0\\xdc\\x6e\\xab\\x06\\xd0\\x4b\\x9e\\x5a\\xcd\\x24\\x2b\\xb7\\xae\\xeb\\x66\\x3e\\xba\\xd3\\x8e\\xc2\\x18\\xf9\\x6f\\x61\\xb5\\xbd\\xdd\\xd2\\x3f\\xf1\\x1d\\x95\\x31\\xa1\\xcb\\x2e\\x11\\xe0\\xf8\\x23\\x2c\\xc6\\x79\\xa3\\x0f\\xe3\\x80\\xca\\xc2\\x81\\x6a\\x62\\xee\\x75\\x5d\\xd3\\xdd\\xca\\x1f\\xc0\\xf4\\x63\\xa1\\xe6\\x58\\x07\\x3f\\xb3\\x09\\x88\\x51\\x28\\xb3\\xda\\x7d\\x50\\xbc\\x1e\\xbf\\x8d\\xea\\xa2\\x57\\x38\\x4b\\x15\\xa8\\x87\\x0a\\xcf\\x9f\\x2c\\x8d\\xcc\\x30\\x8e\\xfb\\xd3\\xfe\\x37\\xa5\\xcb\\x37\\x8e\\x71\\x83\\xdd\\x0c\\x2e\\xf3\\x44\\x77\\xf8\\x0b\\x0f\\x5b\\x18\\x16\\xce\\xeb\\x33\\x63\\xfa\\x9a\\x7f\\xc7\\x85\\xa8\\x52\\x33\\x27\\x63\\x72\\x66\\x33\\x29\\xfc\\xec\\xa5\\xd2\\x93\\x91\\x89\\x6c\\x50\\xfe\\xe3\\xaf\\x39\\x52\\x4b\\xab\\x57\\x90\\x17\\x3a\\x7e\\x19\\xfc\\x4a\\x24\\x32\\x45\\x1b\\x3a\\xc0\\xbc\\x7d\\x9b\\x86\\xe8\\x50\\x39\\x5f\\x17\\xc8\\x5d\\x91\\x9d\\x83\\x51\\x73\\x14\\x10\\xfd\\xba\\xc6\\x12\\x42\\x81\\xd3\\x63\\xc9\\x9d\\x29\\xb0\\x5c\\xbb\\xb8\\xe1\\x70\\xfe\\x36\\xee\\xdc\\x5a\\xf9\\x61\\x18\\x04\\x21\\x49\\xba\\xbc\\x22\\xfe\\x8d\\xdc\\xdd\\xc4\\xe7\\x94\\x6d\\x77\\x4c\\x6f\\x9c\\x1f\\x08\\x5c\\x57\\xb5\\xeb\\xed\\xab\\x24\\xd8\\xed\\x03\\xfa\\xfd\\x34\\x31\\xd3\\x72\\x4c\\xab\\xba\\xf3\\xdd\\xfb\\x62\\x7e\\x3b\\xc2\\xdb\\x72\\x82\\xc3\\x88\\x9d\\x74\\x99\\x66\\x59\\xee\\x27\\x11\\xc3\\x0a\\x74\\xcf\\xf3\\x8f\\x3b\\x4d\\x57\\x5f\\xd7\\x1f\\xa7\\xd6\\x5c\\xe3\\xb0\\xae\\x6d\\xf1\\xb2\\x5c\\x57\\x27\\x9b\\x93\\x30\\x8e\\x16\\x4e\\xb0\\x95\\xdb\\x42\\x82\\x1b\\x65\\xe1\\xdf\\x64\\x99\\x41\\x57\\x80\\x41\\x62\\x14\\x68\\x00\\x07\\x19\\xb4\\xaa\\xed\\x32\\x0b\\x35\\xcb\\xac\\x7b\\x0e\\x14\\x95\\xea\\x4f\\x00\\x72\\x0f\\x89\\xeb\\x6b\\xe2\\x7a\\xf7\\x02\\x94\\x15\\x3c\\xcf\\xfd\\xf8\\x1c\\xfd\\x21\\x46\\x57\\xd7\\x91\\xf4\\xec\\xe9\\xab\\x74\\x2d\\x3d\\x45\\xa7\\xa7\\x55\\x2c\\x74\\x73\\xe3\\x9b\\x66\\x5e\\x0d\\x43\\x7d\\x2f\\x9c\\x4a\\x86\\x5b\\xd1\\xda\\x85\\xdf\\xc4\\xb0\\xb7\\x59\\x94\\x56\\x27\\xdb\\xc3\\x25\\x36\\x09\\x04\\xd6\\x5a\\x08\\xdc\\xbc\\x11\\xd9\\x04\\xe8\\xc9\\x99\\x22\\x77\\xca\\xe7\\xef\\x6c\\x47\\xb0\\x1c\\xf7\\x83\\x39\\xf8\\xc8\\x02\\x1d\\xc4\\x1b\\xf9\\x58\\xcf\\x62\\x4a\\x60\\xc3\\x38\\x7a\\x02\\x54\\x3c\\x66\\x07\\xaa\\x9b\\x90\\xec\\x53\\x45\\xf6\\x0d\\x1b\\xce\\x4b\\xee\\x8e\\x37\\x30\\xd6\\xa9\\xaa\\x2a\\x53\\xce\\x34\\xb2\\x53\\xc7\\x75\\xad\\xb1\\x4a\\xb7\\xb5\\x83\\xb1\\xd9\\x5f\\x98\\x19\\xc4\\x97\\x17\\xc4\\xe2\\xaa\\xbe\\xcb\\xb9\\x5b\\x40\\xe0\\xaa\\xd7\\xe3\\x12\\xcf\\x4d\\x3c\\x06\\x0a\\x94\\xe5\\x41\\x8a\\xb8\\xb7\\x29\\x50\\xea\\x39\\xbf\\x97\\x8b\\x7d\\xe7\\xc7\\x3c\\x9c\\x3b\\x6e\\x46\\x43\\x1c\\xc4\\x2d\\x1a\\xbb\\x72\\x13\\x06\\x43\\x92\\x08\\xc7\\x0e\\x83\\x20\\x58\\xd7\\x3b\\xf3\\x2b\\x5f\\x2a\\x12\\x3c\\xe1\\x31\\x5f\\xf7\\x4b\\xd5\\x76\\x9e\\xcf\\xdf\\xae\\xc7\\x90\\x78\\xfc\\x38\\xbd\\x1f\\xd3\\xb1\\x99\\x11\\x15\\xa7\\x4b\\xc8\\x09\\x90\\xf9\\x35\\xba\\x12\\x51\\xc8\\xba\\x80\\x4d\\xf7\\xcd\\x21\\x6f\\xcf\\xe8\\xb3\\x4b\\x7a\\xe0\\xa6\\x3e\\xd7\\x94\\x3b\\x84\\x51\\x4f\\xff\\xf6\\xc5\\xa7\\xac\\x4c\\x74\\x0f\\xf3\\x90\\x81\\x2c\\x94\\x06\\xf7\\x3a\\x04\\x4a\\x4b\\x68\\x95\\x36\\x91\\xd6\\xb3\\xa0\\xb0\\xab\\x56\\xf6\\x3a\\x24\\x4a\\xb4\\xb5\\x51\\xbb\\xd6\\x18\\xd3\\x4b\\x66\\xac\\x91\\x2f\\xfc\\x77\\x2c\\xdb\\x4b\\x55\\x16\\x9a\\x16\\x76\\xdd\\x0d\\xd5\\x06\\x11\\xd0\\x7e\\x1f\\xf0\\x20\\x39\\x6d\\xb2\\xfd\\x56\\xb3\\x9e\\x0d\\x3e\\x43\\x92\\x61\\x1f\\xfd\\xd2\\x92\\x39\\x68\\x51\\x7d\\x69\\x9b\\xb1\\xe9\\xa5\\x2e\\x95\\x07\\x6e\\xc0\\xd6\\x0a\\x8b\\xbb\\x77\\x2d\\x47\\xd9\\xf7\\x61\\x4b\\xd6\\x36\\x3a\\xd2\\xc4\\x22\\xee\\x87\\x12\\x8f\\xc5\\xda\\x4e\\x7d\\xd9\\xa0\\x0d\\x5f\\xc6\\xf4\\xfd\\x39\\xee\\xba\\x0e\\x5b\\xfd\\xcd\\x07\\x4e\\xca\\x96\\xcc\\x9c\\x57\\xb3\\x1b\\xbb\\xe4\\xd2\\xbb\\x38\\x4d\\xc7\\x61\\x45\\xc9\\x03\\x52\\xc4\\xab\\x6e\\x74\\xdc\\x5a\\x10\\xf2\\xf7\\xc1\\x86\\xd0\\x39\\x20\\x27\\xdd\\xa8\\x7b\\x90\\xe2\\x0a\\x67\\x87\\x29\\x65\\xca\\xe0\\x4e\\xfe\\xaf\\x94\\x9d\\x40\\x2c\\xc6\\xb5\\xec\\x17\\xd5\\x85\\xdf\\xe6\\x3a\\x18\\x9b\\xf9\\x99\\x11\\xb6\\x07\\x00\\xcd\\x52\\x29\\x58\\x4d\\x28\\x88\\x4e\\xb0\\xd0\\xef\\xeb\\xb9\\xfa\\x56\\x76\\xac\\x8e\\x0a\\x80\\x5d\\xc3\\xe0\\x27\\x07\\x11\\x34\\x68\\x91\\x3f\\x51\\x6c\\xfc\\x50\\xee\\x06\\x4a\\x52\\x11\\x53\\xe9\\x89\\x82\\xd7\\x3b\\xe3\\x73\\xa3\\x22\\xe9\\x58\\x5c\\x36\\x59\\x70\\x65\\xf7\\x8a\\x84\\x02\\xc2\\x22\\x3e\\x6b\\xfa\\x28\\x79\\xea\\x10\\x59\\xad\\x1d\\xe2\\xb7\\xed\\x71\\x97\\x83\\xd3\\x79\\x63\\x69\\xab\\x36\\xee\\x0c\\x55\\x96\\x3c\\x7a\\x68\\x69\\xd3\\x63\\x29\\xab\\x59\\x9d\\x7a\\x19\\xba\\x09\\x9d\\x43\\x6d\\xea\\x7b\\xf0\\xee\\xaa\\xfc\\xf1\\x0b\\x0c\\xc9\\xfd\\x18\\x22\\x3a\\x1f\\xa1\\x18\\xbd\\xd7\\x31\\xd5\\xfd\\x1e\\xdd\\x15\\x56\\x07\\x3a\\xf6\\x42\\xc9\\x70\\x01\\xbf\\xf5\\x40\\x74\\xa0\\x5c\\xfe\\x6c\\x86\\x69\\xf5\\x4e\\xff\\x7e\\xaf\\xf1\\xcb\\x78\\x9a\\xd6\\x7d\\x5b\\x93\\xce\\x71\\x10\\x8c\\x8c\\x85\\x15\\x71\\x48\\xca\\x48\\x78\\xe8\\x7b\\x50\\x85\\x50\\x0b\\xce\\x74\\x4c\\x46\\x47\\xab\\x2c\\xea\\xcc\\x39\\x9d\\x96\\x5d\\xc8\\x5c\\x26\\xed\\xcd\\x7b\\xc5\\x14\\x7a\\x6c\\xb6\\xcf\\xea\\x03\\xc0\\x4b\\xaf\\xb9\\x87\\x4d\\x1b\\x1e\\xad\\x5a\\xac\\x8d\\x47\\xe5\\xb4\\xa3\\xa6\\x71\\xf6\\xa9\\x6b\\xa8\\xa8\\xf5\\xdd\\xd9\\x49\\xb9\\xec\\xde\\x35\\xee\\x44\\xab\\x53\\xe0\\xde\\x3b\\x44\\x8b\\x1e\\x5f\\x6d\\x93\\x4a\\x29\\x67\\x83\\x09\\xba\\x5c\\x4e\\xff\\x31\\x5e\\xe6\\x90\\xd0\\x68\\x1b\\x27\\x6f\\xa9\\x6d\\xed\\xd3\\x2f\\xcd\\x44\\xbd\\xfa\\x27\\xce\\xe9\\x10\\x25\\x27\\x4a\\xc9\\x73\\x15\\x91\\x35\\x07\\x15\\xb2\\x43\\x1f\\xe3\\x97\\xb7\\x61\\x59\\x7d\\xb3\\x1e\\x8e\\x79\\xba\\xab\\x99\\x01\\x8b\\xd6\\xf4\\xfc\\x76\\x5f\\x10\\xd9\\x3b\\xac\\xf4\\x54\\xb3\\x59\\x86\\x63\\x06\\xec\\x14\\xf9\\xdf\\x19\\x08\\x56\\x84\\xa8\\x49\\x0e\\xfb\\xfb\\x96\\x22\\xca\\xd0\\xa4\\xd5\\x80\\x01\\x23\\xf6\\xfb\\x0a\\xab\\xbe\\xf7\\x3a\\x08\\x83\\x20\\x38\\x50\\x8d\\x61\\x37\\x9f\\x1c\\x8f\\x91\\x2c\\xed\\xe9\\xe5\\xfc\\x2a\\x2f\\x2d\\x8f\\x3f\\x18\\x93\\xd1\\xe4\\xc5\\x97\\x73\\xd4\\x1f\\x2c\\x66\\x70\\x14\\xf6\\x57\\x00\\xb2\\x0e\\xa6\\x8d\\x3c\\x2b\\xdd\\xbd\\x6f\\xea\\xba\\xb6\\x23\\xc7\\xd6\\x34\\x5a\\x08\\x81\\xbf\\x96\\x51\\x83\\x51\\x72\\xdd\\x67\\x18\\xcd\\x8a\\x98\\x1a\\xcb\\x0e\\xd7\\x96\\x14\\x7e\\x9b\\xca\\xf3\\x25\\x14\\x00\\x54\\x60\\x5e\\x6a\\x31\\x94\\x76\\xaf\\xde\\x91\\xf4\\x0b\\x74\\x5e\\x7b\\x37\\x0d\\xb8\\xa8\\xa5\\x87\\x92\\x07\\x36\\x8c\\x90\\xfa\\xf1\\x97\\xac\\x60\\x24\\x4c\\xd0\\xc8\\xe6\\x2e\\x4c\\x9f\\x32\\x0c\\x67\\x0b\\x4d\\x9e\\xb9\\x84\\x9b\\xaf\\xeb\\xbc\\x12\\x2e\\x2a\\xd4\\x11\\xd5\\x02\\xef\\x3d\\xab\\x48\\x15\\xcc\\x7b\\x06\\x30\\x77\\xfc\\x6b\\x7c\\xf5\\x4d\\x3c\\x42\\xab\\x9a\\xb8\\x14\\xe7\\x54\\x52\\x20\\x03\\x25\\xe9\\x17\\xaf\\x00\\xaa\\xa4\\x42\\x55\\xee\\x9c\\xd6\\x44\\x18\\x85\\xb2\\xcb\\x09\\x3b\\x7f\\xe7\\xf6\\x6f\\x1d\\xf8\\xe8\\xdf\\x1a\\x33\\x39\\xa1\\xd1\\x3d\\x3f\\x91\\xf5\\x20\\x58\\x52\\xb5\\x49\\xb5\\x30\\x4a\\x9c\\x01\\xfa\\x9d\\xfd\\x79\\x73\\xbf\\x4e\\x9f\\x70\\x67\\xce\\x24\\xcd\\x41\\x0b\\xce\\x89\\x31\\x2d\\xdc\\x02\\xe8\\xd0\\x5c\\xbc\\xcf\\x04\\xa3\\x60\\x19\\x6a\\x18\\x89\\xf4\\x3d\\xb7\\x83\\x78\\x53\\xc7\\x48\\xa5\\xda\\x5f\\xd5\\x76\\x45\\xb2\\x62\\x54\\x4d\\x8d\\x55\\x60\\x84\\x2c\\xbe\\x5f\\x33\\xfa\\xeb\\xba\\xac\\xae\\x00\\x34\\xde\\x4d\\x6b\\x25\\x5a\\xa2\\xd9\\x2e\\x70\\x80\\xf3\\x9e\\xa9\\x41\\x57\\x81\\x4c\\x32\\x02\\x63\\xdf\\x3e\\x08\\x8f\\x4e\\x9f\\xb4\\x5c\\x31\\x48\\x63\\xb3\\x09\\xef\\x7b\\x74\\x22\\x72\\xcd\\xb5\\xca\\xc6\\x3f\\x6e\\xe3\\x40\\xb1\\x05\\xe9\\x0e\\x2f\\x21\\xdc\\xe4\\x8f\\xb5\\xf4\\x58\\x3b\\x12\\x43\\xb4\\xb8\\x7e\\x01\\xb6\\x07\\x49\\x18\\x4c\\x09\\x52\\xd4\\xf5\\x75\\xb3\\xa5\\xdf\\xcd\\xf4\\x96\\x4a\\x1b\\x42\\x18\\x23\\x9f\\x29\\xbd\\xdb\\x86\\xde\\xf7\\xcc\\x08\\x7c\\x64\\xe1\\xec\\xde\\x99\\xf2\\xed\\x18\\x50\\x9d\\x5f\\xbc\\x58\\x82\\x77\\x4e\\xd5\\x82\\xac\\x07\\xd9\\xe1\\x64\\x71\\x4e\\xd5\\x01\\xcb\\x13\\xd6\\xab\\x52\\x66\\x8c\\x2f\\x55\\x80\\xc5\\xe9\\xf9\\x90\\x31\\x13\\xd4\\xf9\\xc7\\x6c\\x35\\x52\\x47\\x48\\x88\\xdc\\x12\\x3d\\xeb\\xb4\\xf7\\x4a\\xa5\\xc2\\xef\\x65\\x52\\x06\\x60\\x14\\x0d\\xdc\\x64\\x76\\x73\\x4a\\x9c\\x64\\xb7\\xda\\x14\\xa3\\xd6\\xe2\\x4b\\x97\\x13\\x7f\\x90\\x62\\x0b\\x1b\\xc8\\x95\\x9d\\xe8\\x62\\xb2\\x03\\x9a\\x85\\x54\\x15\\x7d\\x4a\\x70\\xfd\\xeb\\xd5\\x63\\xa1\\x28\\xe5\\x6a\\x3c\\xd3\\xbf\\x85\\xd9\\x4f\\x48\\x5a\\x00\\x9b\\xff\\xe6\\x1a\\xc7\\x0c\\xbe\\xc5\\x30\\xce\\x1f\\x14\\x38\\x6a\\xbf\\xf8\\x1d\\x0f\\x81\\x6b\\x6a\\xee\\x9b\\xf0\\xde\\x87\\xa5\\xbd\\xf9\\x92\\x89\\x09\\xe0\\xfd\\xfa\\xe8\\x06\\x26\\xe4\\x4d\\x9e\\x3c\\x12\\x57\\xb8\\x3c\\xed\\xe3\\xf4\\xda\\x28\\xd8\\x60\\x68\\xe8\\x06\\xf0\\x75\\xa2\\x85\\xf8\\x69\\x39\\x5f\\x51\\x6e\\x0d\\x4c\\xc7\\x51\\x53\\xc7\\x21\\x5c\\x32\\x09\\x03\\x83\\xc3\\x30\\xe6\\xea\\x0a\\x91\\xfa\\xee\\x78\\x7e\\x45\\xde\\xd2\\xef\\xd6\\x09\\x58\\xd1\\xd1\\xc5\\xa3\\x0a\\x14\\x42\\xbe\\xaa\\xef\\xe5\\x41\\xb4\\xc1\\xd7\\xb3\\x1e\\x7d\\xca\\x0e\\x66\\x7a\\x67\\xef\\x22\\x23\\x69\\x00\\xa3\\x72\\x6e\\x9a\\xcc\\x73\\x65\\xe1\\x8f\\x5e\\x0d\\x98\\x5d\\x41\\xd9\\xa0\\x89\\x30\\x5c\\x44\\xf1\\x4f\\x64\\xeb\\x5c\\xd4\\xbf\\xb9\\x9e\\x0e\\xbc\\x4c\\xac\\x32\\xc7\\x22\\x06\\x03\\xc0\\x6c\\x77\\xf2\\x5f\\xb5\\x46\\xdb\\x03\\x5a\\x13\\x7e\\x0b\\xbc\\x50\\x47\\x30\\x61\\x7e\\x7b\\x26\\x35\\xb3\\xab\\x69\\x1c\\x71\\x5e\\x5b\\xdf\\x3a\\x66\\xef\\x5e\\x17\\x05\\x54\\x56\\x70\\x81\\x58\\x5b\\x52\\x43\\xe7\\xca\\x94\\xcb\\x30\\x0c\\x1e\\xc0\\x41\\xe0\\x44\\xcc\\x17\\x81\\xa9\\xb1\\x17\\x4a\\x52\\x44\\x3e\\x7c\\x17\\x0a\\x66\\x31\\x61\\xf8\\xe4\\x65\\xed\\x26\\x3a\\x50\\x55\\xbb\\xad\\x7d\\x31\\xa1\\xd6\\x6b\\xa7\\x1d\\xb6\\x76\\x45\\xae\\x42\\xfe\\x54\\xca\\xec\\x21\\x9d\\xaf\\x2e\\x98\\xc4\\xc0\\x9b\\xb9\\x1e\\xb0\\xbb\\x4d\\xb5\\xa3\\x2b\\x69\\x8e\\x91\\x60\\x70\\xa2\\x27\\xae\\x41\\xea\\xf4\\xa8\\x41\\xb1\\xa3\\xc0\\x0d\\x4b\\xf8\\xc8\\x22\\xb9\\x7b\\xa0\\xcc\\x9a\\xbc\\x98\\x0e\\xaf\\xe8\\xa2\\x81\\x09\\x48\\xb8\\xe4\\x0c\\x49\\x63\\xac\\xa3\\x0f\\x5f\\x42\\x7f\\xe0\\xf9\\x53\\xaf\\x77\\x95\\xdb\\x6b\\xe0\\xd6\\x16\\x84\\x20\\x12\\xa3\\x60\\xfa\\x06\\x94\\xd9\\x6a\\x2c\\x73\\xa4\\xe4\\x79\\x96\\x39\\x00\\xb0\\x7c\\x72\\x4f\\xa0\\xac\\xbc\\xe6\\x9d\\x05\\x9a\\x3d\\x8c\\x59\\xf9\\x97\\xba\\xb4\\xe1\\xc5\\x53\\xaf\\xca\\x47\\x56\\x83\\xec\\x16\\x4a\\xe7\\x40\\xc5\\x47\\xe0\\x57\\x97\\x40\\x11\\xeb\\xed\\xb4\\xf6\\xaf\\xc5\\xbd\\x39\\x6c\\xbe\\x3d\\x74\\x4b\\xd3\\xcb\\x65\\x4d\\x6a\\x20\\xa3\\x97\\x1f\\xe1\\x16\\xf0\\xd7\\x5f\\xbc\\x20\\xf1\\x9b\\xbe\\x3a\\xad\\x10\\xf6\\x11\\x59\\xfb\\xa8\\x8f\\xfb\\xbc\\xbe\\xe7\\xad\\xf5\\x29\\x50\\xc9\\xa0\\x88\\x6b\\xce\\x6d\\x26\\x34\\x50\\x5e\\x99\\x24\\x14\\x27\\x22\\xcb\\xa0\\x8c\\x90\\xc5\\x75\\x84\\x64\\xa1\\xcc\\x80\\xfd\\x5c\\xa3\\xd9\\x43\\xfe\\x8f\\x19\\x2d\\x44\\x72\\x2a\\xa8\\x71\\x30\\xa8\\xf4\\xb2\\x4f\\x7f\\xf7\\x4d\\x15\\xf3\\x33\\xec\\x51\\x28\\x61\\x30\\x55\\x6d\\xe7\\x75\\xf4\\x92\\x91\\xc8\\x28\\xb0\\x94\\x71\\x3a\\xcb\\x4b\\xf0\\xbc\\x22\\x11\\x00\\xf7\\x40\\x74\\xf2\\x97\\x80\\x2e\\xde\\xd6\\x35\\x95\\xaf\\xf2\\x4e\\x57\\x7d\\x93\\x67\\xb7\\xd3\\x89\\x92\\x3b\\x16\\x76\\x6f\\xd7\\x14\\x04\\x00\\x2f\\x3c\\xd7\\x96\\x62\\x1f\\x43\\xb0\\xc5\\x50\\xb0\\xda\\x1d\\xd3\\xf0\\x9c\\x25\\xdc\\x82\\x46\\xc9\\x4d\\x1f\\x83\\x7e\\x88\\xb6\\xbe\\x57\\x62\\xb8\\x44\\x30\\x24\\x81\\x80\\xcf\\x7e\\x20\\x3e\\x45\\xc5\\x33\\x7d\\x53\\x92\\x62\\x57\\xe9\\x65\\xfd\\xd4\\x12\\xb3\\xb1\\xab\\xd2\\x48\\xec\\xd2\\xc4\\xa1\\xc8\\x71\\xc3\\xf0\\x4a\\x58\\xae\\xc0\\x8c\\xb3\\x73\\xb4\\xe0\\xec\\x99\\x74\\x45\\x1b\\xaa\\x0c\\xf8\\x5e\\x44\\x11\\xdc\\xcf\\xa1\\x46\\x5d\\xd6\\x0b\\x31\\xf5\\xf2\\x63\\x55\\x45\\xdc\\xf1\\xea\\xf7\\x43\\x60\\xf5\\x5f\\x3d\\x3a\\x71\\x6e\\x73\\x7d\\xdf\\x62\\xd1\\xeb\\x3c\\x59\\x22\\xe4\\x88\\xd6\\xb1\\xc0\\x52\\xa1\\xea\\x09\\x8d\\x39\\xf4\\x99\\xcf\\xb8\\xa2\\x63\\xf4\\x2b\\x68\\x11\\x7f\\x41\\xaf\\x80\\x74\\x43\\x8c\\xcb\\x1a\\x19\\xe3\\x97\\x12\\xfb\\x26\\x79\\xf6\\x13\\x10\\x94\\xcb\\xff\\xbe\\x05\\x92\\x3c\\xe5\\x84\\x8a\\x3e\\x19\\xbc\\xa4\\x99\\xe1\\xf4\\x70\\x97\\xfc\\x2d\\x39\\xb6\\x20\\x80\\x22\\xb9\\x9c\\x0d\\x02\\xc2\\x61\\x49\\x8a\\x13\\xf5\\x87\\xe8\\xfc\\xf0\\x5b\\xe7\\xb3\\x03\\x21\\x9a\\x2b\\x11\\x82\\xdc\\xd2\\xfa\\xfb\\xce\\x2d\\x81\\xc9\\x43\\x0c\\xb4\\x70\\xb4\\x23\\x3a\\x8e\\x07\\xb9\\xba\\x37\\x00\\x30\\xb3\\x20\\x20\\x67\\x99\\x7a\\xd8\\xc3\\x9c\\xaf\\xf3\\xf4\\x39\\xb6\\xe5\\xc6\\x0a\\xdf\\xd4\\x19\\x5b\\x2a\\x2b\\x6b\\x82\\x39\\x81\\xeb\\x3e\\xe2\\xf0\\xb7\\x7a\\x0d\\x16\\x82\\x64\\xbf\\xb5\\x24\\x31\\xae\\x34\\x15\\x12\\xd2\\x4c\\x2c\\x62\\xdf\\x1c\\xd5\\x23\\x2d\\x78\\x7f\\x70\\x02\\xba\\xc1\\x70\\x64\\x27\\xa2\\x25\\x54\\x0d\\x24\\x63\\xf1\\x9b\\x2b\\xf3\\xc5\\x76\\x7b\\x56\\xb9\\xba\\x7e\\xff\\x3f\\x0e\\x26\\x06\\x4a\\x94\\x33\\x0d\\xda\\x0c\\x38\\xff\\xf6\\xb5\\x9f\\xd1\\x2d\\x0e\\xfe\\xbc\\x09\\x36\\x55\\x79\\xcb\\x7c\\xcf\\x05\\x5e\\x3c\\x4b\\x7e\\x45\\x0f\\x46\\x96\\x8b\\xbd\\x88\\xe0\\x05\\xbd\\x81\\xf9\\x7e\\x1f\\xdb\\xe3\\x8b\\x8d\\x77\\xaf\\xc8\\x73\\x4a\\x12\\x06\\x81\\x1f\\x14\\xed\\xe8\\x43\\xb6\\x90\\x18\\x88\\xc4\\x19\\x46\\xd6\\x6e\\x01\\x42\\xe3\\x27\\x9a\\x1d\\x48\\x73\\x2d\\xfc\\x6b\\x76\\xc6\\x8b\\x26\\x2f\\xd8\\xde\\xf2\\xca\\xa3\\x05\\x94\\x19\\x52\\xc3\\xec\\x3a\\xf7\\xee\\xdb\\xef\\x4b\\x28\\x92\\x72\\xeb\\x3e\\x10\\x9d\\x90\\xc5\\xef\\xe6\\x2a\\x3d\\x50\\x82\\x9f\\x02\\xe6\\x6d\\x06\\xa2\\x5f\\x0c\\x97\\x7c\\xa9\\xde\\x16\\xf0\\x53\\x15\\xa5\\x4e\\x63\\x28\\x35\\x42\\x65\\x18\\x7e\\xaf\\xde\\xe5\\xd3\\x29\\x56\\x83\\x98\\x09\\xdf\\x3e\\x0e\\xe1\\x06\\xd9\\xc4\\x90\\x5e\\x57\\x98\\xc5\\x54\\xfb\\x5b\\x1d\\x67\\xdf\\x46\\x11\\xc8\\x59\\xb6\\x7e\\xd8\\xa6\\x96\\x01\\xf7\\x4b\\x12\\x3e\\x9b\\x75\\x99\\x00\\xa6\\xcd\\x25\\xac\\xde\\x73\\x76\\xa4\\xb7\\x90\\x92\\xd7\\xc0\\x16\\x35\\xc6\\x8f\\x02\\x2a\\x53\\xc0\\x2e\\xf1\\x82\\xb5\\x1f\\x11\\xb3\\x1e\\x52\\x4c\\x49\\xa7\\x75\\x65\\x2f\\x71\\x2e\\xe7\\x74\\x78\\x65\\xe1\\x4c\\x62\\xa6\\xbe\\xe1\\xe7\\x93\\x82\\xe9\\xa3\\xe7\\xd7\\x88\\x70\\x68\\x19\\x3f\\xf0\\x3a\\x74\\xa8\\xef\\xf1\\x59\\x38\\x9c\\x2c\\xed\\x1e\\x75\\x27\\xc9\\x0f\\xf1\\xe6\\x0f\\x42\\x3a\\x6e\\x2b\\xb4\\x07\\x9a\\x22\\xb8\\x51\\x67\\xeb\\xb4\\xea\\xee\\x5b\\x07\\x7a\\xaf\\x22\\x5e\\x63\\x93\\xf3\\xdf\\x92\\x86\\x03\\x5d\\x91\\x93\\x08\\x19\\x5c\\x3b\\xb7\\x67\\xdf\\x09\\xaf\\x71\\x92\\xce\\xfe\\x56\\xab\\x54\\xb3\\x33\\x79\\x59\\xd3\\x07\\x3d\\x78\\x1c\\x4a\\xc4\\x64\\x3e\\x7b\\x3d\\x1c\\x75\\x8a\\x0c\\xcb\\xdf\\x7d\\xf6\\x2f\\x08\\xb1\\xb7\\x30\\x05\\x66\\x15\\xa1\\xb6\\xc3\\x91\\x23\\xdc\\x00\\xb0\\xa2\\xdb\\x22\\x9e\\x95\\xb4\\xb0\\x26\\x6f\\xae\\x24\\xae\\x1d\\xee\\xb5\\xb2\\x46\\x41\\xa4\\x6e\\xe8\\x66\\x8a\\x85\\x37\\x00\\xad\\x6d\\xe7\\x53\\xfb\\x9b\\x3b\\x83\\x1f\\x29\\xa2\\x93\\x47\\x94\\x19\\x99\\xcf\\x2d\\xa0\\x63\\x3a\\x2e\\xeb\\x1f\\x17\\xed\\xa3\\x95\\xd1\\x03\\x55\\xcd\\x6f\\x7f\\x69\\x24\\xf8\\x6b\\x38\\x59\\x04\\xb5\\x97\\x62\\xc1\\xea\\x12\\xde\\xf7\\x76\\xe9\\xf2\\x44\\xba\\x99\\x48\\x85\\xfd\\xc5\\x21\\x1c\\xe2\\xc0\\xf6\\x5f\\x4f\\x41\\x6b\\xda\\x04\\xe2\\xc7\\xea\\x23\\xef\\x28\\xd2\\xba\\xc3\\x3b\\x69\\xbe\\xf8\\x4e\\x24\\x2d\\xe8\\x84\\x17\\x3a\\x77\\xef\\x0e\\x54\\x56\\xa4\\x87\\x02\\xae\\x67\\x36\\x08\\xe9\\xb2\\x97\\xea\\xa4\\x7a\\x5e\\x2e\\x67\\xab\\xe7\\xc4\\x35\\xd5\\x45\\x87\\xbf\\x45\\xca\\xf9\\xae\\x11\\xe9\\x5a\\xa1\\x9d\\x19\\x94\\xc2\\xe7\\x66\\x74\\x46\\xf3\\x4c\\xb4\\xd1\\x85\\xc8\\x6e\\x5a\\x89\\x3f\\xf3\\x40\\xff\\xf4\\x27\\x93\\xdd\\xfe\\xd0\\x5a\\xb4\\x46\\xc8\\x17\\x30\\xe5\\x6e\\x78\\xad\\x8b\\xa1\\xa4\\xd6\\x79\\x60\\x02\\x2f\\xd1\\x0a\\x95\\xb5\\xb6\\x0f\\xc8\\xc3\\x6d\\x6a\\xc2\\xf4\\x04\\xec\\xa7\\x53\\x2a\\xdd\\x0f\\x9b\\x16\\x3e\\x45\\x14\\x78\\xfc\\x62\\xcd\\xe0\\x47\\x81\\x46\\xff\\x25\\x4d\\x1c\\x89\\x84\\x81\\x24\\x69\\x88\\xad\\x52\\x87\\x74\\x4a\\x1f\\x7d\\x8d\\x41\\x46\\x07\\x01\\x16\\x18\\x08\\x04\\x0f\\x94\\x4a\\xfd\\x8c\\xe9\\x44\\x2e\\xeb\\x93\\xe5\\xde\\x3d\\x87\\xda\\xf1\\xaa\\xb6\\xa3\\x4b\\xd2\\xf1\\x6d\\xb6\\xaa\\xd4\\x60\\x09\\xd7\\xd8\\x44\\xe0\\xe4\\xd7\\xb7\\xc1\\xf7\\x35\\x7e\\x79\\x25\\xe0\\xe8\\xbc\\x69\\x2e\\x52\\x98\\x11\\x2a\\x3d\\x37\\x55\\x09\\xcc\\x86\\xcf\\x69\\x3a\\x1a\\xe3\\x87\\xe5\\x9a\\x32\\x4c\\x1d\\x4c\\x2f\\x13\\x5e\\xad\\x2b\\x09\\xd0\\x4e\\x95\\x10\\x89\\x41\\x94\\xd3\\xcc\\x47\\x4c\\x5a\\x0f\\xb5\\xc4\\x08\\x29\\x49\\x17\\x4e\\xc0\\xf6\\x7c\\xea\\xb8\\xac\\xa3\\x1b\\x06\\x42\\x4b\\xe9\\x25\\x3f\\x5f\\x9f\\x77\\x4b\\x89\\x1e\\xb8\\xf4\\xec\\x89\\xad\\xa2\\x24\\x0e\\x13\\x40\\x74\\xe7\\xbc\\xa3\\xd5\\x27\\x59\\x9e\\x99\\x31\\xc2\\xe1\\xca\\x45\\x18\\x0f\\x78\\x83\\xe8\\xe4\\x45\\x9a\\x23\\x76\\xfd\\xde\\x5a\\xf5\\xcb\\xe4\\x37\\x7f\\x81\\xc0\\x1c\\xbb\\x27\\x71\\xe7\\x70\\x5a\\x54\\x4f\\x1f\\x3b\\x89\\xcf\\xe4\\x79\\x06\\x04\\xf1\\xc2\\x4e\\x43\\xee\\x40\\x05\\x07\\xad\\xfa\\xb9\\x3d\\xad\\x52\\x32\\xa0\\x03\\xef\\xd2\\x82\\x7e\\x67\\xc4\\x29\\xc9\\x18\\x4b\\x7c\\x4d\\x98\\xed\\x0f\\xef\\x6d\\x39\\x1c\\x96\\x14\\x8d\\x2e\\xe8\\x27\\x36\\x35\\xae\\x1a\\xb2\\x27\\x02\\xac\\x89\\x66\\x94\\xc9\\x40\\x06\\x1f\\x8e\\x3e\\xc8\\xd7\\x6f\\x7e\\x46\\xaf\\x18\\x36\\x30\\x1d\\xb0\\x49\\xe8\\x0d\\x28\\x7c\\xbe\\xfd\\x23\\xb8\\x82\\x7d\\x10\\x3a\\x6d\\xfd\\x7c\\x8e\\xb1\\x05\\x8e\\xfa\\xac\\x8f\\xa4\\xfd\\x0d\\xfe\\x3c\\x05\\x03\\xaa\\x9f\\xf5\\x84\\x16\\x35\\x67\\x40\\xaa\\x33\\x35\\x37\\xb4\\xf1\\xa8\\x95\\x4a\\xeb\\x37\\xfc\\xa0\\xc0\\xb8\\xc1\\x36\\xbd\\xdf\\x08\\xbb\\xce\\x8f\\x5a\\xb2\\x7e\\x26\\xf2\\xa7\\x59\\xb3\\x26\\xb6\\x88\\x0f\\xf5\\xeb\\x8e\\x1c\\x5b\\xfa\\xa7\\xe1\\x68\\xf6\\x3c\\xcc\\x8b\\x78\\xb0\\x70\\xb5\\x7b\\x1b\\x68\\x4b\\x52\\x91\\xc5\\xef\\xbd\\x36\\x52\\xf6\\xad\\x25\\x66\\x76\\x86\\xb5\\x9a\\xbd\\x3a\\x91\\x15\\xd9\\x66\\xdc\\x84\\x9c\\x9a\\xad\\x2e\\x74\\xa6\\x13\\x3a\\xdb\\xdf\\x7d\\x51\\x61\\x5e\\x0a\\xec\\x59\\xe1\\x95\\x99\\xa8\\x7a\\x25\\x0c\\x9c\\xec\\xeb\\x2f\\xe3\\xc9\\xcd\\x01\\xc4\\x30\\xaa\\xfb\\x75\\x0f\\x05\\x0a\\xed\\x73\\x0b\\xbc\\xf2\\x41\\xf3\\x24\\x0b\\x0c\\xc0\\x2d\\x7e\\xdf\\xf7\\xf3\\xc5\\x7e\\x06\\x21\\x46\\x82\\xc1\\xc7\\xf8\\x03\\xd1\\x7b\\xd7\\xe6\\x7c\\x8d\\x6e\\x03\\x5d\\x9d\\xe8\\x6c\\x84\\x07\\x6c\\xad\\xe9\\xbb\\x4f\\x3c\\x3d\\x91\\xf3\\x1e\\x69\\x0f\\xa3\\x9a\\xa9\\xbb\\xac\\xde\\x14\\x4f\\x15\\x4b\\xcc\\xb0\\xce\\x2e\\x28\\x8e\\x28\\x79\\x49\\x9f\\x68\\xe1\\xf9\\xb0\\xae\\x4c\\xb3\\x19\\x0e\\x4d\\xf6\\x10\\xf7\\x8f\\xe9\\x15\\x32\\x45\\x8e\\x99\\x07\\x6e\\xaa\\xe6\\x0f\\xd5\\x1b\\x94\\x46\\xa8\\x44\\x6b\\x84\\x57\\x38\\xdb\\x3f\\xfc\\xe4\\x6b\\xcc\\x64\\xe0\\x27\\x5f\\x44\\x17\\x73\\x38\\x25\\xd9\\xc3\\x0f\\x8f\\xe0\\x0a\\xb0\\xaf\\x8b\\x72\\x6c\\xf0\\x44\\x61\\xea\\xce\\x50\\x3c\\x08\\x92\\xd0\\x7f\\xbb\\xfc\\xd1\\x2b\\x19\\xa6\\x21\\x33\\x67\\x32\\x82\\x57\\xe8\\x8b\\xff\\x70\\x08\\x8c\\xa0\\x41\\x71\\xfd\\x55\\xb4\\x50\\x10\\xc9\\xac\\x4c\\x0f\\xcb\\x68\\xc0\\xd3\\x66\\xe4\\xe6\\x4e\\xc4\\x06\\x7f\\x0b\\x46\\x32\\xdd\\x05\\x51\\x45\\x5f\\x5b\\x6d\\xcb\\x8c\\xfc\\xb5\\x84\\x40\\xc8\\xcc\\x34\\x51\\x54\\xd5\\xa8\\x9e\\x5b\\x18\\x2a\\xe1\\x39\\xbb\\x27\\x3c\\x26\\xc7\\xc6\\xa9\\xd4\\x74\\x0a\\x2d\\xe2\\x52\\x73\\x63\\x49\\x12\\x06\\x87\\xb6\\x56\\xfc\\xbd\\x6b\\xcc\\xdf\\x23\\x47\\xf0\\x91\\xb6\\x64\\x85\\xfc\\xfe\\x38\\xa4\\x8c\\xac\\xb1\\x17\\x11\\x98\\xa1\\xbe\\xd6\\xc8\\xd7\\x2c\\x93\\xa8\\xd5\\x7c\\xaf\\xcd\\xbd\\xba\\x61\\x02\\xe7\\xe9\\xc1\\xa8\\x42\\x41\\x0f\\xe7\\x86\\x4a\\x33\\x96\\x65\\xd3\\x60\\xd8\\x7a\\xb1\\x2b\\x94\\xc4\\x0d\\xc3\\xb9\\x9d\\x2a\\x10\\x1d\\x7f\\x13\\x5b\\xa4\\x33\\x3f\\x3f\\xec\\x60\\x1a\\xcc\\x63\\x89\\xbd\\x7e\\xf6\\xe5\\xf4\\x5f\\xf2\\x39\\x33\\x24\\xb0\\x6a\\xe3\\xef\\x7d\\xdf\\x85\\x5b\\x70\\x04\\x17\\xee\\x4c\\xfe\\x19\\x4d\\xdd\\xb3\\xfe\\x44\\x8e\\xf0\\xd1\\x33\\xb1\\x34\\xdc\\xc5\\xf3\\x4b\\xa8\\x53\\x29\\xb5\\x19\\x44\\xf0\\x24\\x0c\\x30\\x8c\\xf1\\xcb\\x60\\xb9\\x0b\\xd4\\xf2\\x0c\\x64\\x07\\x0a\\x8c\\xe9\\x5b\\x8f\\x43\\xb3\\x7d\\xc3\\x85\\x03\\xdd\\x13\\x9e\\xf9\\x7b\\x69\\x70\\x5b\\x5e\\x27\\x5a\\x65\\x5f\\xd4\\x3d\\xe8\\xca\\xde\\x1c\\x35\\xbe\\xdf\\x83\\x01\\xca\\x5f\\x6c\\xbc\\x78\\xd1\\x2b\\xa3\\x97\\x1d\\xaf\\xe2\\xb5\\xb2\\xf5\\x52\\x08\\x5d\\x80\\xf9\\xb9\\x3f\\x54\\x69\\x19\\x24\\xd5\\xd8\\x07\\x66\\x49\\x3d\\xed\\x70\\x84\\xdc\\x10\\x74\\x7e\\xd5\\x0a\\xd9\\x57\\xd4\\xb4\\x07\\x35\\x55\\x52\\x99\\xfe\\x2f\\x26\\x58\\xef\\xdd\\x44\\xa9\\x73\\x76\\x77\\x6a\\x16\\x08\\xab\\xae\\x4f\\xbe\\x60\\x81\\x6e\\x31\\xc2\\xac\\x40\\x24\\x25\\x04\\xb3\\x02\\x35\\x72\\x65\\x18\\xc6\\x0f\\x35\\x1a\\x89\\x5c\\x82\\x1e\\x48\\xe8\\x85\\xcd\\xd4\\x90\\x60\\xc3\\xf5\\xf7\\x36\\x44\\xd2\\x40\\x13\\xbf\\x51\\x99\\xe6\\x74\\xc4\\xd7\\xdf\\xd0\\x12\\x41\\x54\\xf5\\xb0\\xf1\\xe5\\x19\\x2c\\x41\\x58\\x6e\\x61\\x84\\x14\\xd6\\x54\\x63\\xe7\\xc2\\x36\\xb4\\x48\\x84\\x6e\\xff\\xf5\\xc9\\x78\\xf4\\xd6\\xa1\\x27\\xf5\\x0e\\x18\\xad\\x16\\x41\\xb1\\xaf\\xea\\x14\\x00\\x27\\x4c\\xf2\\x92\\xe5\\xb7\\x81\\x2f\\x86\\x18\\xf5\\xd2\\xa3\\xa4\\xf6\\x51\\x07\\x9f\\xf8\\x07\\xff\\xc7\\x64\\x64\\x47\\x23\\x5e\\x82\\x61\\x6d\\xf9\\x9d\\xbf\\x01\\x6c\\xf2\\x6d\\x22\\xba\\x2a\\x58\\x24\\xcc\\xbd\\x5d\\xcc\\xfe\\x72\\x72\\xee\\xf4\\xb7\\xa2\\x4f\\xad\\x25\\xd6\\xb5\\x9d\\x05\\xee\\xbe\\x09\\xfd\\x27\\x2e\\x7b\\xd9\\x3b\\xf1\\x1e\\x92\\x0d\\x56\\x42\\xed\\x05\\xfe\\xe9\\x1a\\x05\\x64\\xfa\\x16\\x00\\xa5\\xcd\\x0f\\x8e\\x2f\\x32\\x77\\x59\\xaa\\x3d\\x61\\x36\\x73\\xc3\\x28\\x52\\xf7\\x0c\\x46\\x31\\x2c\\xb6\\xd3\\x67\\x52\\x57\\xee\\xe0\\xb9\\xea\\x33\\x95\\x4f\\xdd\\xdf\\xf5\\xc4\\xb9\\xad\\xab\\x18\\x33\\xb1\\xa9\\x76\\x65\\x49\\xec\\x48\\xd0\\xb1\\x9e\\x91\\x2e\\xf5\\x8f\\xd7\\x2c\\x72\\x5c\\x09\\xbf\\x80\\x08\\x1a\\x37\\xaa\\x51\\x8b\\x8f\\x60\\x47\\xd7\\x90\\xac\\xc3\\xe0\\xc8\\x4e\\xb4\\x42\\xa7\\x1d\\xca\\x0c\\x68\\x5e\\x8e\\xd7\\xc9\\xc8\\x62\\xa4\\x4b\\xda\\x92\\xba\\x40\\x2d\\x84\\xd1\\x39\\x63\\x0f\\x1f\\x90\\xc1\\x15\\xa4\\x93\\x01\\xdf\\x08\\xa7\\x22\\x71\\x48\\xca\\x6a\\x54\\xf1\\x42\\xcd\\x1a\\xbd\\x6b\\x72\\xf6\\xe7\\x0a\\xd7\\x43\\x83\\x81\\x56\\x5e\\x50\\x41\\xf7\\x4f\\x04\\x9a\\x07\\x19\\x25\\xa8\\xc7\\xbc\\x89\\xe5\\x56\\xf5\\x9a\\x8e\\x4a\\xf3\\x53\\x9d\\xbe\\xee\\x53\\x8c\\x41\\x8a\\xa0\\x67\\xeb\\x58\\xea\\x7a\\xdc\\x4c\\x45\\x18\\xfa\\x3d\\xb6\\x5a\\x7e\\x3b\\x29\\xbc\\xdf\\x0d\\x64\\xd6\\x94\\x86\\xc3\\xe2\\x31\\xa0\\x06\\x9b\\x93\\x27\\x75\\xc5\\xa9\\x69\\xe8\\x2b\\x43\\x81\\x00\\xf2\\xc9\\xe3\\x0f\\xa2\\x23\\x04\\x5b\\xfd\\xe7\\x2d\\x29\\x49\\xe6\\x10\\x59\\x50\\x38\\xbb\\xff\\xb1\\x11\\x83\\xc9\\x3f\\x7d\\xf4\\xf2\\xae\\x9c\\xbf\\x3a\\xff\\xe6\\xa1\\x7b\\x50\\x62\\x1e\\xc0\\x68\\xfc\\x0a\\x7d\\x52\\xc4\\xfc\\x56\\xb9\\x7e\\x29\\xa3\\x85\\x9c\\x7d\\x8c\\xad\\x55\\xc1\\x15\\x1a\\x35\\xd4\\x06\\x82\\xf3\\x7d\\xc5\\xdd\\x06\\x80\\x3c\\xae\\xd3\\x8a\\x72\\x57\\x83\\x0b\\xd9\\x49\\x4b\\xab\\xfe\\x89\\xa5\\x33\\xf1\\x01\\x79\\xac\\x52\\x33\\x07\\xb6\\x25\\x38\\xb7\\x6f\\x49\\xa0\\x29\\x6b\\x62\\xdc\\xc9\\x19\\x39\\xbd\\xf3\\xaa\\x2e\\xf1\\x19\\xf5\\x3f\\xea\\x00\\x7b\\x10\\x80\\xdd\\x0d\\x26\\xf0\\x20\\x10\\x1d\\xe1\\x66\\x64\\x40\\xc0\\x28\\x53\\x41\\xe4\\xea\\xbc\\xfc\\xdf\\x87\\x8b\\xae\\xe5\\x3b\\x7f\\xc3\\x8d\\xed\\xa5\\x59\\xc6\\xf2\\x11\\xda\\xfd\\xa2\\xb9\\x5f\\x71\\x21\\x9d\\x67\\xa2\\x1f\\x85\\x9b\\xc9\\xc8\\xdd\\x68\\x74\\x21\\xb1\\x89\\xcc\\x71\\x43\\x89\\x42\\x8f\\xc8\\x40\\x5f\\x1b\\x88\\x37\\x2e\\xdc\\xf8\\x86\\xc4\\xe7\\xc3\\x47\\x2c\\x45\\x77\\xd3\\x96\\xfd\\x2d\\x30\\xbb\\xdc\\x2e\\xfe\\x89\\x45\\x2a\\x09\\xf1\\x8d\\x0c\\x02\\x9d\\x0f\\xe4\\x16\\xee\\x65\\xd2\\xb7\\x87\\x3c\\x08\\x76\\xbf\\x5b\\x6f\\x18\\x15\\x90\\x4c\\x6b\\x72\\xd1\\x14\\xb1\\x23\\xe5\\xa5\\x66\\x7a\\x5f\\xe4\\x93\\xa3\\xd5\\xb3\\x20\\x20\\x36\\x92\\xc3\\xfb\\x65\\x6b\\x56\\xa7\\x2f\\x9e\\xad\\x89\\x50\\x1b\\x10\\x2e\\x3b\\x45\\x1a\\xc5\\xc1\\xec\\x80\\xdd\\x23\\x72\\x5d\\x7d\\xfa\\x6c\\x26\\x12\\x6f\\x5f\\x64\\xb3\\x5e\\x5d\\x7a\\xa6\\x0e\\xb5\\x00\\xe9\\x32\\x57\\x76\\x5b\\xbd\\x74\\xae\\xd6\\xa2\\x7c\\x78\\x02\\x3b\\xbb\\x5e\\xab\\x0d\\x22\\x0a\\x0b\\xdb\\x4b\\xe3\\x44\\xb7\\xba\\x21\\x6d\\xc3\\x18\\xbd\\x2c\\x40\\x8d\\x3b\\x67\\xec\\x0a\\x13\\xbc\\x37\\x9d\\xf4\\xaa\\x57\\x03\\x43\\xf7\\x7c\\x64\\x28\\xe7\\xd6\\xed\\x17\\x2d\\xd1\\x91\\xbc\\x00\\x49\\x59\\xf1\\x2d\\xa6\\x80\\x09\\xba\\x90\\x3f\\x1c\\x0a\\x2d\\x4e\\xfc\\x49\\xeb\\xe8\\x54\\x3c\\x0e\\xfe\\x04\\x9e\\xa5\\x7f\\x88\\xd4\\xca\\xec\\x1d\\xdb\\x17\\x5c\\x23\\x89\\x19\\x8e\\x6b\\x59\\x59\\x63\\xc2\\x1b\\x6e\\xb4\\x0d\\xd4\\x68\\x87\\x59\\x43\\x3a\\x1b\\x8a\\x92\\x31\\x25\\x89\\xae\\x95\\xbb\\xf2\\xa7\\x3f\\x0f\\x38\\x5a\\x0a\\x79\\x69\\x56\\x2a\\x49\\x4d\\x1c\\x18\\xe0\\x08\\x3f\\xb6\\xff\\x63\\xed\\xdb\\x00\\x92\\x71\\x59\\x10\\xd2\\x4f\\xb0\\xb5\\x6a\\x9f\\x19\\x2a\\x41\\xf0\\xce\\x13\\xa2\\x1c\\x50\\x92\\xbe\\x9b\\x52\\xb0\\x45\\x36\\x0e\\x1c\\xab\\x23\\x66\\xcf\\x66\\xeb\\xf3\\x38\\xd1\\xac\\x45\\xf2\\xeb\\xe6\\xb3\\xc7\\x82\\xd3\\x00\\x9c\\xd4\\x7f\\x3a\\x9b\\x09\\x97\\x8e\\x57\\x9a\\xec\\xba\\x11\\x09\\x7f\\xc6\\xf8\\x95\\x95\\x1e\\x9e\\xe3\\xf1\\x03\\xdc\\x71\\xd9\\x56\\x12\\x38\\xe5\\x48\\x8b\\x2a\\xe1\\x8a\\xa0\\xb5\\x04\\x67\\xdd\\x1f\\x95\\xb6\\xf8\\x01\\xbe\\x44\\x4f\\xf8\\x23\\x74\\xce\\xab\\xd5\\x0c\\x0f\\xfc\\xb4\\xd3\\xea\\xfe\\xbd\\xfb\\xa7\\xcb\\xd3\\x0f\\x92\\x70\\x38\\x17\\x47\\x61\\x35\\xe5\\xea\\x60\\x52\\xa4\\xde\\xac\\xc3\\xde\\x82\\xae\\xf4\\xd1\\xba\\x08\\xb4\\x4d\\xcc\\x50\\x83\\x91\\xd4\\x41\\xe4\\x74\\xcc\\x48\\x1a\\xe8\\x17\\xb8\\x01\\x97\\xaa\\x4f\\x4c\\x8f\\x7a\\xeb\\xb6\\x1e\\x39\\x76\\xf2\\x16\\xf4\\x59\\x6d\\xdc\\xbc\\xf4\\xda\\x9c\\x83\\x5c\\x61\\x95\\xe2\\x42\\xd3\\x82\\x0d\\xa5\\xc4\\x9c\\x10\\x62\\x4c\\xc6\\x24\\x60\\x68\\x27\\x1c\\x66\\x22\\xa3\\xc8\\x9c\\x01\\x2f\\xd4\\x45\\x74\\x4e\\x88\\x0d\\xff\\xdf\\xba\\xe1\\xe6\\x2c\\x68\\x32\\xc3\\x41\\x10\\x04\\x00\\x8f\\x72\\x16\\x38\\x11\\x00\\x2e\\x1c\\x94\\x15\\x6e\\x30\\x2c\\x5a\\x13\\x4a\\x4e\\x3c\\x44\\x94\\xa6\\x20\\x23\\x31\\x3a\\x5c\\x09\\x52\\xa5\\xd6\\x65\\xb3\\x8c\\x4c\\xaa\\x35\\x78\\xa1\\x0a\\x76\\x67\\x03\\x6e\\x7a\\x35\\xcc\\xfb\\x36\\xc5\\x2b\\xfd\\x5f\\x62\\x4b\\x14\\x17\\xda\\x15\\x73\\xf2\\x66\\xd8\\xf0\\x54\\xf7\\xa3\\x18\\x53\\xf6\\xd2\\x3d\\x02\\x41\\x00\\xea\\x70\\xd5\\xf5\\x27\\x05\\xd4\\xa6\\xaf\\x3a\\x80\\xc7\\x27\\x96\\x45\\x79\\xc6\\x69\\x59\\xb3\\xf1\\xb6\\x48\\x5a\\x27\\x2a\\x4b\\xe5\\xe6\\x7d\\xb0\\xd2\\xe7\\xe3\\x50\\x7d\\x78\\xf1\\xaa\\x59\\x6a\\x1e\\xe4\\xeb\\xb2\\xf2\\x49\\x11\\xda\\x97\\xf5\\xdb\\x5e\\x5c\\x64\\xbf\\x19\\x3d\\x10\\x12\\x6d\\x75\\x7a\\xfa\\x68\\xb2\\x3b\\x37\\x30\\x77\\x28\\xb0\\x12\\x5b\\xa2\\xfc\\x8d\\xe0\\x46\\x03\\x1a\\x8e\\x7b\\x92\\xe7\\xd6\\x3e\\xd8\\x25\\x03\\x37\\xa2\\xbc\\x30\\xc5\\xcb\\x60\\x7e\\x9c\\x1b\\x7a\\xe3\\xa2\\x8d\\x00\\x58\\xad\\xcb\\x9a\\xf6\\x8e\\xc6\\x33\\x98\\xfa\\xab\\xc5\\x38\\x10\\x5d\\x7f\\x98\\x07\\xd0\\x06\\x72\\xc3\\xf3\\x61\\xe7\\xc6\\x8a\\xa9\\x5b\\xf0\\xfd\\xf8\\xc6\\x10\\x24\\x31\\x2c\\x37\\x30\\x90\\x14\\x76\\x44\\x89\\xe5\\x45\\xaf\\xa4\\x67\\x4f\\x95\\x82\\x49\\x35\\x12\\xba\\x1b\\x10\\xfc\\x70\\x0a\\xa6\\x23\\xb0\\x55\\x30\\x8d\\x23\\x22\\x93\\x5e\\x50\\xde\\x9c\\x1d\\x46\\xac\\x3b\\xdd\\x95\\x9d\\x0c\\xfb\\xae\\x1d\\xa9\\x2c\\xe1\\x37\\x57\\x0a\\x2e\\xfe\\xe0\\x95\\xce\\x0e\\xf0\\xb4\\xa2\\x42\\xcd\\x44\\x4f\\x5c\\x3f\\xa9\\xc1\\xbb\\x8b\\x6b\\x95\\x78\\x3f\\x34\\xee\\xed\\xab\\xc4\\xfb\\xe3\\xa1\\x6f\\x81\\x00\\x8b\\xae\\x2c\\xcd\\x15\\x68\\x79\\x05\\x92\\xdb\\x14\\x87\\x24\\x4c\\xf4\\xd1\\xe3\\x9f\\x97\\xe0\\x19\\xd1\\x7c\\x29\\xa5\\xc9\\x15\\x23\\x24\\xd3\\x79\\x55\\xeb\\x9a\\x64\\x18\\xb0\\xeb\\xcb\\x6d\\x7f\\xa6\\x1e\\x3f\\xb3\\x96\\xe8\\x35\\xe3\\x0a\\xa7\\x15\\xd7\\x47\\x12\\xa4\\x9b\\x20\\x0c\\x46\\xc5\\xb9\\x58\\xfa\\x5f\\x9d\\x34\\x59\\x5d\\x12\\x3f\\x50\\x8f\\x0e\\x65\\x06\\xd1\\x56\\xa7\\x37\\xd0\\xf8\\xfc\\x4a\\xbc\\x73\\xb9\\xfa\\xa7\\xc2\\x47\\x16\\x36\\x73\\x2a\\x08\\x1c\\xf2\\xe5\\xa7\\x26\\x7a\\xcd\\x8d\\xcf\\xf9\\x64\\x8f\\x02\\xd3\\x11\\xf4\\x49\\xcb\\xbb\\xce\\xa0\\x54\\x25\\x28\\x19\\x4d\\xdc\\x3f\\x5e\\x0d\\x87\\x25\\xf3\\x2b\\x93\\xa5\\xc4\\x0b\\xde\\x07\\xa5\\x42\\xc1\\xe8\\x42\\x71\\x15\\x3d\\xa2\\x6c\\xa0\\xca\\xca\\x9e\\x65\\xc4\\xeb\\x1a\\x0b\\xec\\x4d\\x3a\\xad\\x80\\x1f\\x78\\x26\\xc1\\x97\\x5f\\x20\\x5e\\x2d\\x10\\x50\\xfc\\xb6\\xd3\\x9f\\x03\\x6b\\xfa\\x8e\\x7a\\x10\\x6e\\x3e\\xa6\\x3b\\x35\\x18\\xbf\\xe3\\xa0\\x16\\xfb\\x8f\\x17\\x3b\\x13\\xfc\\x55\\x7d\\x72\\x66\\x26\\x32\\x71\\x8f\\xc1\\x69\\x03\\xe1\\xa0\\x2d\\x1f\\x9b\\xfc\\x95\\x21\\xf4\\xf5\\xcb\\x13\\x29\\x18\\x70\\xf7\\xcf\\x9b\\x0f\\x5b\\x0a\\x1b\\xf7\\xa6\\xbb\\x82\\xc3\\x82\\x97\\xff\\xe7\\x19\\x13\\xed\\x33\\x52\\xa6\\xb9\\x5d\\xa9\\xb3\\x34\\xb4\\x8d\\x47\\x7d\\x31\\xd9\\xb4\\xfa\\x60\\x80\\xac\\x16\\x04\\xca\\x49\\x81\\xdb\\x19\\xc0\\xca\\xda\\x1c\\xaa\\x00\\x91\\xe3\\x3a\\x7c\\xcc\\xbb\\x36\\x1f\\x97\\x35\\xad\\x15\\x7d\\xba\\xfc\\x82\\xb0\\xe6\\xd3\\x74\\xba\\x0b\\x0b\\xe0\\x21\\x09\\x83\\x1d\\xcd\\x40\\xf1\\x96\\xd0\\x0f\\xf9\\xd8\\x31\\xa9\\x84\\xe6\\x26\\x0f\\x53\\xfe\\xf6\\x7e\\xfd\\xd3\\xaf\\x84\\xd3\\xbf\\x05\\xfc\\x1e\\x89\\x57\\x85\\xec\\x27\\xef\\xa3\\xa0\\x99\\x73\\xc5\\xf0\\x09\\x8a\\x03\\xe0\\xf5\\xe2\\x14\\x9c\\x1e\\xa1\\x38\\xb8\\x7e\\xfb\\xb3\\xbc\\x94\\xb8\\x77\\x99\\x67\\x2f\\x6b\\xdc\\x02\\x82\\x70\\x7b\\xe0\\x14\\x23\\xc4\\xb9\\x32\\x08\\xa4\\x8e\\x8a\\xae\\x16\\x9c\\x89\\xc4\\xa7\\xa8\\xb8\\x6d\\xf8\\xd1\\x3d\\x07\\x54\\x1b\\x31\\xdb\\x36\\x5b\\x4f\\xf8\\x9a\\x8e\\x8b\\x25\\x7b\\xd8\\x9d\\xe0\\x95\\x79\\x7c\\x18\\x6c\\x2b\\xef\\xaf\\xbd\\xf7\\x4a\\x0b\\x89\\xc5\\xc1\\x26\\x15\\x87\\x88\\xc4\\xb2\\x89\\x3a\\x33\\x10\\x82\\x2a\\xaa\\x03\\x49\\xcf\\x38\\x1a\\xf0\\x32\\x02\\x49\\xf9\\xa3\\x41\\x19\\x88\\xff\\xf8\\xe9\\xb4\\x6f\\x98\\xa5\\xc0\\x4a\\xe9\\x08\\x04\\x70\\x0c\\xe9\\x4b\\x6c\\x78\\x31\\xab\\x03\\x61\\x80\\xe4\\x80\\x58\\x98\\xb1\\x8e\\x67\\x2f\\x83\\x21\\x09\\x51\\xf2\\x68\\xcc\\x2f\\x2f\\x74\\x7e\\x2e\\xbd\\x3e\\x11\\x9e\\xa2\\x52\\x7d\\x23\\x3d\\xc2\\x17\\x40\\x38\\x30\\x02\\x82\\x7e\\x51\\xdf\\xe4\\x08\\xd7\\xb9\\xc4\\x4a\\x91\\x22\\xaa\\x01\\x0e\\x42\\xa9\\x38\\xc6\\x2f\\x6c\\x81\\x38\\x48\\x7e\\x82\\x29\\xeb\\xd3\\x4f\\x97\\x62\\xf4\\xcd\\x19\\xf7\\xde\\x35\\x71\\x45\\x32\\x61\\xbc\\x6f\\xf3\\x8a\\xb6\\xcd\\x18\\x51\\xd9\\x62\\xe7\\x3e\\x44\\x8e\\x2d\\xf3\\x65\\xf3\\xbc\\x54\\xb8\\x90\\xf8\\xe6\\x32\\xbb\\x1a\\xcd\\xaf\\x57\\xa7\\x34\\xe9\\xeb\\x77\\x53\\x46\\xc9\\x83\\x14\\xbd\\x9b\\x06\\x64\\x4b\\x2c\\x5e\\x96\\x16\\x2d\\x79\\xcd\\x06\\xcb\\x0b\\x40\\xb4\\x06\\x74\\x91\\xd9\\xc5\\x46\\xa7\\xdc\\x66\\x97\\x9b\\x27\\x11\\x48\\x02\\x63\\x18\\xcd\\x75\\x27\\xe5\\xa6\\xe2\\xe2\\xc3\\xfe\\x3c\\x94\\xd8\\xf8\\xc1\\xcf\\x59\\x2a\\xd5\\xa5\\x2e\\x94\\x5c\\xf0\\x97\\x7e\\x92\\x9d\\x08\\x8b\\xea\\x78\\xf1\\x8e\\x34\\x8e\\x1d\\x89\\x7f\\xe6\\xaf\\xe2\\xd3\\x22\\xa5\\x90\\x74\\x86\\x57\\xb4\\xa7\\xda\\x3e\\x15\\xa2\\x3f\\xd5\\x2f\\xad\\xe1\\xaa\\x4e\\x2b\\x0a\\x6d\\x92\\x47\\x9d\\xd0\\x0f\\xc4\\x27\\xb6\\x68\\xe0\\x7b\\x84\\x6e\\x7e\\xc7\\xbc\\xf7\\x26\\x09\\xa6\\x8b\\x83\\x92\\x18\\x28\\xc3\\x58\\x02\\x33\\xe4\\x7b\\xb2\\x3c\\x98\\xce\\x8a\\x1d\\x85\\xb2\\x24\\xe9\\xc7\\xbf\\xb8\\x8a\\x6e\\xca\\x94\\xcb\\xfa\\xc6\\x8b\\xd3\\x9d\\x27\\x29\\x8f\\x07\\xa8\\xee\\x0b\\x84\\xac\\xfe\\xf2\\x4d\\x7b\\x94\\xbf\\x3e\\xa9\\x78\\x8d\\xda\\xef\\x31\\x4e\\x9f\\x36\\x9f\\x90\\xc9\\x3b\\xfb\\x2b\\x41\\x9f\\x8d\\xea\\x94\\x6f\\x26\\xf4\\x8e\\x73\\xe2\\x58\\xad\\xcc\\x29\\xe1\\x92\\xfe\\x9d\\xf2\\xd6\\xc7\\x1a\\xed\\xa5\\xae\\x0b\\xd5\\x70\\xbd\\xdb\\xdb\\x99\\x70\\xfb\\x43\\x9a\\x36\\x71\\x5f\\xd2\\x7c\\xc4\\x4f\\xf2\\x52\\x07\\x97\\x28\\xcc\\x69\\x51\\xcb\\x61\\xcf\\xd4\\x03\\x68\\x15\\x8c\\x2a\\xaf\\x28\\x43\\x46\\xdf\\x9a\\x95\\xea\\xc7\\x0e\\x13\\xbf\\x40\\xbb\\x26\\x3d\\xbf\\xe2\\xf0\\xcc\\x29\\x83\\x10\\xb1\\xbc\\xaa\\x9f\\x3c\\x31\\xf5\\x08\\x42\\xa1\\xfc\\x9a\\x0c\\x77\\x47\\x21\\x7c\\x64\\x65\\x3b\\xf8\\x0c\\x80\\xde\\x71\\x6e\\xc9\\x13\\x57\\x5a\\x37\\xc3\\x30\\x1c\\xc3\\xb8\\xbe\\xc3\\x06\\xdc\\xbc\\xa9\\x90\\xc1\\x10\\xdd\\x43\\x53\\x87\\x97\\x41\\xc0\\xc5\\x01\\x95\\xe5\\xa2\\xb3\\xc2\\xab\\xac\\x67\\x8e\\xbc\\xaf\\x31\\x15\\xd0\\x86\\x60\\x75\\x42\\x48\\x65\\xce\\xe6\\x73\\xc3\\x45\\x14\\x30\\x6e\\x61\\xf1\\x0d\\xf5\\xd2\\xfa\\x36\\xbc\\xc4\\x57\\x65\\x67\\x24\\xd1\\xce\\xc5\\x37\\x37\\x46\\xe6\\x67\\x7d\\x0f\\xbe\\xa1\\x57\\xd5\\x05\\x83\\x21\\xaa\\x26\\xbc\\xb3\\xd7\\xd6\\xd6\\x40\\x95\\x09\\x8d\\x5d\\x71\\x5d\\xd3\\x37\\x70\\x2d\\x11\\xb9\\x74\\xef\\x3c\\xa1\\xf6\\x4c\\xe0\\x85\\xf0\\x95\\x1e\\xe7\\xa7\\x4c\\x95\\x99\\x9a\\xa5\\x9e\\xc2\\x79\\x53\\x86\\x60\\xb1\\x29\\xa3\\x4c\\x89\\x6b\\xc1\\x7a\\xeb\\xfc\\xbc\\xba\\x5b\\x6a\\xad\\x44\\x62\\x8c\\x00\\x59\\x9e\\x44\\xc1\\xd6\\x77\\x02\\x75\\x47\\x3b\\xb4\\x78\\xf5\\x23\\x5b\\x01\\x43\\x58\\x24\\x31\\x9d\\xb1\\x3b\\x50\\xe3\\xe2\\x6d\\xc8\\xa8\\xeb\\xf0\\x55\\x4b\\xb3\\xdd\\x56\\xf2\\x5c\\x5a\\x24\\x5b\\xf3\\x5b\\x12\\x1e\\x28\\xc0\\xbd\\xc8\\xcd\\x81\\x6b\\xd4\\x0a\\xb5\\xcc\\x05\\x37\\x41\\x8d\\x2f\\xff\\x9b\\x67\\x5d\\x33\\x0d\\xc2\\xb3\\x7b\\x2d\\x4e\\x65\\x30\\x03\\x3e\\x6a\\xe9\\xa0\\xd9\\x01\\x02\\x00\\x56\\xce\\xed\\x2b\\x34\\x8e\\xef\\x82\\xa8\\xd1\\xc5\\x08\\x5f\\x13\\xe6\\xaa\\xb5\\x8c\\xc0\\x94\\x83\\x92\\x86\\x72\\xf7\\xdc\\xb7\\x6e\\x1c\\xb9\\xce\\x2b\\x3d\\x11\\x0e\\x4b\\xf5\\xcb\\xdb\\xf9\\xd5\\x3b\\x6b\\xf8\\xf0\\xbf\\x41\\xbb\\x02\\x3e\\x69\\x63\\xb1\\x01\\x8f\\xe3\\x1d\\x1d\\xdd\\xb5\\x36\\xd5\\x15\\x68\\x0b\\x44\\xc5\\x4e\\x2d\\xc9\\x79\\x1b\\x08\\xfc\\x3d\\x2e\\x8f\\x00\\x09\\x1a\\x20\\x6e\\x3d\\x2d\\xdd\\xce\\x41\\x0c\\xaa\\x52\\xe2\\x23\\xf4\\x15\\x44\\xa3\\x33\\x10\\x56\\x83\\x0d\\x06\\xfc\\x2d\\x20\\x14\\x85\\xa1\\xed\\xac\\x23\\x93\\x09\\xde\\x8c\\x68\\x43\\xfa\\x6f\\x19\\x0c\\x0a\\x52\\xde\\x7c\\x52\\x91\\xec\\xb8\\xef\\x84\\xe4\\x48\\xbe\\xf2\\xc3\\x39\\x10\\x15\\x37\\x3f\\xa7\\xf6\\x29\\xa8\\xd1\\x9b\\x7e\\x99\\x69\\x76\\x75\\x6d\\xeb\\xb8\\xe9\\xf5\\xaf\\xf5\\xfa\\x99\\x84\\xef\\x7c\\x73\\xff\\x65\\x37\\xf7\\xf7\\x4d\\xd2\\xb6\\xa6\\xbd\\xf2\\xc3\\xd7\\xc4\\x87\\xe9\\x4a\\x46\\x4f\\x41\\x8f\\xff\\x38\\x50\\xd5\\xd6\\xf7\\x62\\x99\\xc1\\xf0\\x7c\\x9c\\x02\\x4b\\x8a\\x48\\x01\\xcd\\x99\\x91\\x48\\xc3\\xdf\\x25\\xf4\\xb7\\x22\\xeb\\x73\\xbe\\x0b\\xe0\\xc2\\x8f\\xbe\\x85\\xaa\\x88\\x13\\x7f\\x72\\x8b\\x62\\x7b\\xbf\\x13\\x50\\x83\\x09\\xc4\\x27\\xa2\\xcf\\xa8\\xaa\\xf4\\x1f\\xd5\\xcc\\x49\\xc1\\xf5\\xb9\\xaf\\x55\\x7d\\x84\\xca\\x1d\\xaa\\x7f\\xfa\\xf7\\xb3\\xae\\xd6\\x94\\xbf\\xa3\\xa4\\x69\\x6a\\x10\\xf6\\x69\\xf1\\x89\\x4a\\x99\\x3a\\x66\\xec\\x6e\\x93\\xb9\\xb8\\x7e\\x56\\x8d\\x8e\\x7e\\x5e\\x0c\\x85\\x31\\x91\\x2c\\x4e\\xd0\\xfc\\x72\\x24\\x38\\xa8\\x0b\\xa4\\x4c\\x99\\x47\\x8e\\x60\\xb3\\x7e\\xa5\\x35\\x73\\xdf\\x52\\x1e\\x27\\x92\\xc5\\xb9\\x2e\\xc7\\xab\\x44\\x43\\x94\\xa7\\xf4\\x58\\xae\\x47\\xbf\\xfe\\xb1\\x0b\\x1a\\x04\\xc8\\x02\\xd4\\x86\\xef\\x01\\x37\\x7c\\x0f\\x47\\xdf\\xe2\\x7e\\x6d\\xbc\\xab\\x18\\x95\\x19\\xe3\\x27\\x3c\\xba\\xab\\x7a\\x18\\x64\\x42\\x85\\x5c\\x14\\x17\\xaa\\x72\\xf5\\xfc\\xe3\\x11\\x5e\\x64\\xaf\\x8a\\x5f\\xab\\x49\\x29\\xd1\\x83\\x6c\\xfc\\xca\\xec\\x6a\\x3b\\x5e\\xad\\xf0\\x2b\\xd4\\x6a\\xe2\\xc1\\x3a\\x97\\x4f\\xb2\\x37\\x25\\xbe\\x88\\x02\\x38\\x0c\\x92\\x2d\\x3e\\x84\\xb9\\xcf\\x1d\\x21\\x2a\\x4e\\x14\\xed\\x7d\\xc1\\x95\\xbc\\x47\\xb9\\x2a\\x68\\xc5\\x69\\x00\\x82\\x33\\x63\\x3d\\xd7\\x75\\xdf\\x56\\x96\\x9b\\x57\\x75\\xdf\\xd4\\x77\\xdf\\x04\\xec\\x52\\x55\\x6e\\x27\\x50\\x85\\x96\\xe5\\x67\\x4f\\x5d\\x30\\xc9\\x6a\\xc2\\x74\\x7d\\xb7\\x73\\x8a\\x36\\x5e\\xd5\\xb6\\x67\\x83\\xc0\\x65\\x6c\\x48\\x1e\\x2d\\x69\\xdc\\xfc\\xbf\\xf4\\x3f\\x2c\\x69\\xd8\\xe6\\xc1\\x80\\x97\\x3e\\x8c\\x33\\x71\\x1e\\xd2\\x23\\x6c\\x4e\\x66\\x8a\\x5b\\xbc\\x8d\\x78\\xc6\\x24\\x75\\x9e\\x0d\\xec\\x58\\x45\\xb1\\xb6\\x1f\\x88\\x41\\xf0\\xaf\\x96\\x9a\\xf9\\xb1\\x43\\x78\\x6c\\xc4\\x5a\\x4c\\x1b\\x4e\\x7a\\x09\\x45\\xc6\\x67\\x04\\xc9\\x83\\x9d\\x1f\\x9a\\x0b\\xd1\\x95\\xd9\\xfd\\xbb\\xd6\\xfa\\xc5\\x26\\x55\\x69\\xc8\\x72\\xf5\\xe9\\xa0\\x82\\x3d\\x5e\\x86\\x05\\x57\\xd7\\x3f\\xce\\x5e\\xc7\\x52\\x0b\\xe1\\x73\\x9b\\x89\\xdb\\xa5\\x54\\xb3\\xe8\\x71\\xb5\\x04\\x2b\\x98\\xc8\\xaf\\x79\\x6d\\xe7\\x75\\x9d\\x57\\x81\\x69\\xfa\\xd2\\xa2\\xa7\\x89\\x96\\x80\\x18\\xfe\\xbb\\xbd\\x74\\xdf\\xd2\\x11\\x6d\\x37\\x0e\\x49\\x84\\xbb\\xcc\\x8e\\x90\\x48\\xfe\\x80\\xb8\\x8b\\xfb\\xb4\\xfe\\x68\\x4d\\x1d\\xec\\x24\\xf1\\x5d\\x8b\\xf3\\xa5\\xfd\\x8d\\x45\\x3c\\x09\\x70\\x0c\\x17\\x19\\x3e\\x61\\xa3\\xd1\\x30\\x4b\\xef\\x77\\x6b\\x41\\x9b\\x1d\\xeb\\xe2\\x91\\x13\\x0c\\xc9\\xac\\xfe\\x77\\xbc\\xf8\\xa2\\xba\\xc2\\xd1\\x42\\xdb\\xbf\\x1e\\x59\\x18\\x50\\x99\\xb2\\xb5\\x16\\x4a\\x79\\x46\\x76\\x49\\xf2\\x68\\x02\\xe5\\xa3\\x46\\x2b\\x19\\xa0\\xb7\\xdf\\x41\\x13\\x97\\x47\\x97\\x60\\x39\\x4f\\xcc\\xfa\\xe7\\x74\\xf1\\xf8\\xf2\\xd7\\x43\\x2b\\xae\\xd1\\x0b\\xa6\\x62\\x18\\x13\\xd3\\x72\\x5c\\x55\\x8f\\xe4\\xaa\\x42\\x57\\xba\\x7a\\xf1\\x1c\\x83\\x0d\\x4f\\x48\\x0d\\xe9\\x08\\xd1\\xea\\x03\\x24\\x74\\xde\\x7b\\x61\\x1f\\x0d\\x82\\xce\\x79\\x6f\\x79\\x74\\xaf\\x27\\xc2\\xd7\\x9e\\x62\\x84\\x3e\\x2e\\x24\\x4b\\x02\\x3f\\x10\\x1c\\x2d\\x19\\xe8\\x7c\\x52\\x5f\\xa9\\xf8\\xbc\\x58\\x9c\\xad\\x46\\xb8\\xc0\\x2e\\xa1\\x01\\x94\\x9c\\x3e\\xde\\x1c\\x16\\xb7\\x03\\x1f\\x68\\x27\\x27\\x13\\x8d\\x66\\x5d\\xe6\\xed\\x5b\\xc7\\x8b\\xb3\\xe3\\xe9\\x1c\\x7e\\xc6\\xe4\\xcc\\x78\\xe0\\xa6\\x4a\\x4b\\xab\\x2b\\xe9\\xd1\\xb7\\x9b\\x44\\xc5\\x8b\\x8a\\x44\\x38\\x8c\\x9c\\xbe\\x0d\\x28\\x6b\\x8d\\xaa\\xec\\xb7\\x6a\\x6d\\xfb\\xeb\\x7e\\x88\\x51\\x3e\\xda\\x43\\xd2\\x2f\\x39\\x80\\xd1\\x21\\x7d\\xdf\\x47\\x07\\x90\\xda\\x40\\xfa\\x97\\xff\\x8b\\x24\\x9d\\x2c\\xaf\\xd1\\x9c\\xba\\x65\\x4d\\xc7\\xf5\\x01\\x1b\\xc3\\x0b\\xe1\\x3d\\x13\\x1f\\xdf\\xa7\\xcb\\x64\\xf5\\x07\\xc5\\x7b\\xc1\\x0b\\x95\\xbb\\x87\\x4e\\x8c\\x1a\\x88\\x3e\\x20\\xcf\\x24\\xe7\\xcf\\x6d\\x5c\\x19\\x62\\xd4\\x58\\x51\\x3e\\x75\\x1c\\x8a\\x2c\\x02\\xeb\\xf4\\x69\\x81\\x0c\\xe6\\x9b\\x72\\x22\\x2b\\xf3\\xdf\\x38\\xe3\\x1f\\x69\\xda\\x58\\x6e\\xcc\\x28\\xa5\\x2e\\x43\\x7e\\x45\\x38\\x66\\x59\\x32\\x48\\xc2\\x2d\\xba\\x1e\\x60\\xfc\\x1a\\xbc\\x9b\\xeb\\xe1\\x35\\x5e\\xfc\\xf0\\x11\\x8e\\x6e\\x88\\x8e\\x1f\\x08\\x8f\\xee\\xf9\\x9f\\xf9\\xe1\\x2d\\x92\\x16\\x40\\x17\\xef\\xfe\\xe8\\x29\\x67\\x1d\\xc2\\xf0\\x61\\x78\\x39\\x6c\\x77\\xaf\\x50\\x59\\xe8\\x5b\\x83\\x44\\x7f\\x46\\x19\\xa9\\x17\\x25\\xcb\\x04\\x6c\\x4f\\x2f\\xa9\\xdb\\x3b\\x3c\\x4e\\x88\\x16\\x45\\x58\\x6d\\x34\\x54\\xd1\\x92\\x9e\\xcd\\x73\\xda\\x6d\\x6d\\x1d\\x5a\\x08\\x7b\\x39\\xac\\x7b\\x3e\\x6a\\x20\\x5d\\x0b\\xe5\\x91\\xf3\\xfa\\x83\\xe1\\xf5\\x58\\xb9\\x69\\x2d\\xb6\\x12\\x87\\x95\\x8d\\x21\\x3e\\x25\\x21\\x5b\\x63\\xa6\\xb6\\x22\\x6b\\x71\\x4d\\x44\\x22\\x39\\xe7\\xad\\x01\\x5a\\xb8\\xc1\\xd0\\xef\\x8a\\xa2\\x8d\\xa4\\x5b\\x34\\xb0\\x1f\\x3c\\x27\\xd7\\xf8\\x18\\xc9\\x03\\x21\\xb0\\xb8\\x02\\xc0\\xaa\\x9a\\x8b\\xf4\\x8c\\x26\\x1d\\xb7\\xc4\\x27\\x54\\x08\\xae\\x99\\x4b\\xb9\\x25\\xce\\xed\\xc4\\x42\\xbc\\xcf\\xf4\\xd7\\x9f\\x65\\x94\\x00\\x2c\\xb1\\x7d\\xf5\\xf0\\x86\\x0c\\x9e\\x02\\xe5\\x27\\x99\\x7c\\x6b\\x83\\x57\\x04\\x25\\x8b\\x97\\x55\\xdd\\xa4\\x42\\x43\\xb4\\x5c\\x08\\xb7\\x5f\\xd2\\x38\\x14\\x9b\\x34\\x1c\\xf0\\x50\\x7b\\x4a\\x75\\x4d\\xfb\\x85\\xd4\\x5e\\x91\\xbd\\xd3\\xaf\\x8a\\x13\\xca\\x9f\\xe2\\xf8\\xcf\\xb2\\x18\\x5f\\xfe\\x19\\xe1\\x56\\x9c\\x64\\xd9\\xf5\\x8a\\x71\\x86\\x9f\\x14\\x08\\x47\\x88\\x96\\x27\\x2f\\x60\\xaa\\xd8\\x22\\x38\\xcd\\xd5\\x76\\x6c\\x94\\x57\\x74\\xa1\\x84\\x11\\x7e\\x5e\\xb2\\x23\\xb4\\x02\\x50\\x40\\x45\\x9f\\x7c\\x1e\\x89\\x50\\x20\\x3a\\xbe\\x0f\\x74\\x53\\x87\\xd3\\xee\\x8e\\x20\\xd9\\x15\\xd6\\xab\\x5a\\x63\\x31\\x9d\\xe9\\x73\\x6e\\x4a\\x7e\\x34\\xd9\\x9d\\xe5\\x41\\xf6\\x9d\\x5b\\x6f\\xe8\\xe8\\xee\\x90\\x61\\x95\\x4c\\xa0\\xe4\\x81\\x4a\\x5d\\x73\\x5c\\xc9\\x48\\x4a\\x6f\\x7d\\xee\\xab\\x5a\\xff\\x2c\\xf9\\x3a\\xef\\xd9\\xd7\\x44\\x13\\x84\\x95\\xe1\\x08\\xe1\\x23\\x06\\x66\\x28\\x27\\x69\\x54\\x1a\\x71\\x60\\x3a\\x10\\x2d\\xa3\\x51\\x63\\xfc\\xf4\\xee\\x66\\xd3\\xe7\\xda\\x18\\x17\\x3b\\xff\\x34\\x1e\\xa2\\x35\\x77\\x1e\\x82\\x9e\\xab\\x77\\x6d\\x83\\x11\\xba\\xec\\xfa\\xdd\\xe2\\xfa\\xc5\\x75\\xe3\\x29\\x96\\x9e\\x76\\x1f\\xab\\x0a\\x9d\\x35\\xaa\\xfa\\xe3\\xfb\\xcc\\x39\\xd0\\x15\\xdd\\x49\\x21\\xc3\\x01\\xd9\\x3b\\xe0\\x26\\xa0\\x1f\\x74\\x43\\xbe\\xd9\\xe0\\x8d\\x11\\x8d\\x6d\\xcb\\xf4\\x60\\xc3\\x8a\\x78\\x12\\x8b\\xeb\\x26\\x62\\x0d\\xd9\\x23\\xe1\\x13\\xf1\\x14\\x88\\xa0\\xda\\x98\\x96\\x55\\xd3\\x55\\xf7\\x4d\\x79\\x37\\x9a\\xa0\\x41\\xbd\\x34\\xf4\\xcf\\x86\\x12\\xab\\x0c\\xa0\\xc9\\xa0\\x40\\xe6\\xca\\x92\\x1d\\x25\\x68\\x73\\xf2\\xb6\\x68\\x47\\x19\\x2c\\x01\\xd5\\x16\\x5b\\xd5\\x69\\xc3\\x30\\x5d\\x36\\xa4\\xaf\\xec\\xa6\\x8e\\x08\\x60\\xfb\\x3e\\x2c\\x14\\x04\\xdb\\x8c\\x36\\xee\\x15\\x24\\x1d\\xe4\\x4b\\x0e\\x7e\\x9a\\xef\\xda\\x4f\\xa6\\x9a\\x8b\\x5e\\x04\\x4d\\xd6\\x21\\x04\\xc1\\x0b\\xfe\\x13\\xe4\\xc3\\x2e\\xca\\x25\\xca\\x03\\xd1\\xc9\\x8a\\x13\\xcd\\x70\\x1c\\x03\\x57\\x0d\\x7f\\xe9\\x3f\\xa0\\xef\\x4b\\x2e\\x31\\xbd\\x9e\\xc8\\x8e\\x91\\x64\\xfb\\x4b\\x20\\xf2\\x4c\\x7c\\x82\\x17\\xaf\\xaa\\xe6\\x4e\\x46\\x37\\xb0\\xe6\\x5b\\xdc\\x7f\\x0d\\xf3\\x9b\\xac\\x0b\\xa1\\x2a\\xeb\\x4b\\x91\\xa7\\xfe\\x29\\x17\\xc9\\xc3\\x3a\\x90\\x52\\x0d\\xd5\\x9b\\xbe\\x96\\x85\\xe8\\x91\\x1d\\x08\\x69\\xa2\\xc1\\x9d\\x1e\\xe7\\x29\\x7b\\xc8\\x14\\x00\\xde\\x84\\x93\\x80\\xde\\x62\\xa7\\xd1\\xc5\\x30\\x2e\\x24\\x66\\xdc\\x0b\\xfc\\xf7\\x66\\x06\\x01\\x5c\\x73\\x66\\x8c\\xf8\\x0e\\x2f\\x2f\\x61\\x26\\xc4\\x1f\\x9f\\xca\\xfc\\x83\\x11\\xc5\\x65\\xcf\\xbc\\x5b\\x39\\x3e\\xc4\\xb2\\x76\\x2e\\x6b\\x08\\x7a\\xb9\\xb8\\x41\\xc7\\x46\\x53\\x3b\\xc2\\x63\\x7e\\xf9\\x31\\xbc\\x67\\x04\\x85\\xc8\\x71\\x65\\x1b\\x4c\\x90\\xce\\x50\\x58\\x1d\\x96\\x4d\\xc7\\x84\\x6e\\xf0\\xce\\x7e\\x75\\xf6\\xa3\\xd9\\x8f\\xa8\\x48\\xa0\\xeb\\x11\\x0d\\x26\\x3b\\x0a\\x2f\\x4e\\xaa\\x41\\x50\\x3c\\xe4\\xea\\x59\\x95\\xe9\\x07\\xcc\\xaf\\xe8\\x9a\\xde\\x52\\x9f\\xf4\\xed\\x16\\xc7\\x64\\x4d\\xc9\\x63\\x44\\x03\\xf8\\x90\\x71\\x04\\x76\\x85\\x05\\x95\\x1f\\x10\\x8c\\xe8\\x12\\xb4\\xe3\\x3c\\x5c\\x87\\xfc\\x4b\\xf5\\x5f\\x3e\\xae\\xeb\\xb9\\xa1\\x76\\x89\\x57\\x15\\x49\\x8d\\x39\\x36\\x99\\xd1\\x75\\x4e\\xa6\\xd0\\x39\\x2b\\xf7\\xa6\\x9c\\x8f\\x1a\\x68\\x35\\x50\\x4d\\xf4\\x97\\x35\\x7e\\x4d\\xf1\\xb5\\x14\\x38\\x01\\x18\\x95\\x11\\x40\\xb5\\x7f\\xa9\\x98\\xd9\\x1f\\xa1\\xe1\\x80\\x55\\x47\\xce\\x9e\\x49\\x93\\xb7\\xc0\\xf9\\xb9\\xc5\\x77\\x41\\x96\\x53\\x3b\\x76\\x31\\xab\\x2a\\xb8\\x15\\x6e\\x30\\x2d\\x3b\\x7e\\x22\\x38\\x1d\\x4c\\x80\\x55\\x8b\\x66\\x4c\\xee\\x9a\\x93\\xb7\\x1c\\x28\\xd9\\xf3\\x16\\x30\\x57\\x0a\\x7d\\x0d\\x00\\x0a\\x80\\x1c\\x19\\x1c\\x08\\x99\\x78\\x38\\x45\\x14\\x27\\xea\\x86\\x70\\xc8\\x27\\xc1\\x87\\xd3\\xc0\\xe5\\xdd\\xe0\\x6c\\xfe\\x9a\\x1b\\xe8\\x66\\xc2\\x5a\\x74\\x45\\xb3\\x67\\xa4\\xb2\\x8e\\xf2\\x8a\\xe2\\x38\\x66\\x1b\\xca\\x50\\x3c\\xe1\\xcb\\xf7\\x28\\xc8\\x3c\\xe1\\xd6\\xed\\x5d\\xe0\\xda\\x79\\x55\\xb1\\x37\\xd5\\xe5\\x0f\\x1e\\x79\\xcb\\xa7\\x05\\x8e\\xe0\\x97\\x0b\\xbd\\x10\\xd2\\x42\\x01\\x4d\\xec\\x0e\\x73\\xc6\\x8c\\x11\\x74\\x2e\\x01\\xca\\x9a\\x27\\x3d\\xc2\\x2d\\xd9\\x91\\x40\\xf9\\x43\\xd3\\x30\\x81\\x15\\xd7\\xbf\\x7e\\x88\\xfa\\x47\\x58\\xee\\xd4\\x78\\xbe\\x92\\x47\\xec\\x73\\xe0\\xd8\\x04\\xfa\\x40\\x7e\\x46\\xc9\\x9f\\x86\\x66\\xc3\\xa5\\x13\\xeb\\xba\\xce\\x43\\xfb\\x24\\xde\\x50\\x97\\xd2\\x71\\xac\\x48\\x96\\x1d\\x03\\xf0\\xa5\\xac\\xad\\x73\\xe6\\x7b\\xf7\\x16\\x47\\x9f\\x58\\x35\\x1b\\x54\\x75\\xf1\\x98\\x3d\\x1c\\x59\\x09\\x5e\\xa6\\xec\\xa5\\xc8\\xd1\\xd9\\xd4\\x01\\xa0\\xd9\\x51\\x87\\xa5\\xe5\\x97\\xb2\\x0e\\xc8\\x4f\\xa9\\xc3\\xd9\\x21\\xb3\\x50\\x21\\x7d\\xd9\\x35\\xa0\\xda\\xd0\\x22\\x0b\\x11\\xb0\\xaa\\xa2\\xa8\\x91\\x06\\x53\\x40\\x8b\\x2d\\x00\\x70\\x79\\xca\\x4b\\xb6\\xd1\\x3e\\xc1\\x1a\\x2e\\x33\\x98\\xd8\\xc4\\xe1\\x09\\x56\\xc7\\x96\\x5d\\x8f\\x3e\\x2a\\xd4\\xa4\\x5b\\x0d\\x61\\x5e\\x1b\\x49\\xaf\\xe4\\x82\\x4c\\xde\\x72\\xd6\\x2f\\xb8\\xbe\\xdf\\x42\\x81\\x3b\\x2a\\xc8\\x55\\x6e\\x0b\\x87\\x96\\xc2\\x1a\\x16\\x4a\\x31\\x0d\\xd9\\xdb\\x9b\\x4f\\xca\\x4e\\x64\\xd6\\x6c\\x0d\\x93\\x98\\xb2\\xd2\\x01\\x90\\x05\\x8c\\xc0\\xb1\\x07\\xca\\x63\\x83\\x3b\\xcd\\x7b\\x75\\x18\\x4a\\x53\\xb4\\xe6\\xde\\x3b\\x69\\x7e\\x07\\x59\\x7e\\x47\\x26\\xc1\\x47\\xea\\x29\\x2d\\x20\\x04\\x67\\x36\\x92\\xdc\\xf8\\x55\\x0f\\x55\\xc9\\xcf\\x06\\x93\\xf2\\x93\\x87\\xca\\x13\\xfe\\x88\\x49\\x09\\x8d\\x2e\\x47\\x00\\x06\\x3c\\x12\\x8a\\x5a\\xf8\\x31\\xd7\\x65\\xfe\\x81\\x88\\x52\\x61\\x80\\x1f\\x14\\x8e\\xcb\\x9a\\x1d\\xc8\\x56\\x6c\\x68\\x9a\\x18\\xd2\\x9d\\xcb\\xed\\x95\\x6b\\x9a\\x3b\\xaf\\xe5\\x45\\xee\\x48\\x7c\\x4d\\x1f\\x61\\x76\\xf3\\x01\\x7a\\xa9\\x73\\xcc\\x22\\x5c\\x45\\x4a\\x7e\\x86\\xd4\\x54\\x53\\x86\\x91\\x6b\\x38\\x05\\xfe\\x59\\x33\\xfe\\x9b\\x73\\x0e\\x11\\xf2\\x71\\x42\\x01\\xec\\x33\\xe6\\x10\\x07\\xba\\xe6\\x07\\x5e\\x20\\xa8\\x98\\x92\\x42\\x65\\x43\\x3e\\x23\\x7a\\x97\\x22\\xc7\\x96\\xdf\\x87\\xf6\\x5f\\x05\\xa9\\xfe\\xfd\\xf9\\xc7\\x34\\x82\\xce\\xd4\\xbc\\x77\\x9e\\xa1\\x35\\x0f\\xa2\\x2d\\x17\\xea\\x2c\\x57\\x87\\x8d\\x32\\x38\\xa0\\xe3\\xb0\\xa6\\x0f\\x7b\\xb2\\x69\\xef\\xfe\\x64\\x7a\\xcc\\x8c\\x91\\x8f\\xec\\xcc\\xb1\\xc4\\x67\\x78\\x9f\\xb4\\x30\\xff\\xbc\\xc9\\x73\\x9a\\xec\\x63\\x96\\x50\\x25\\x4f\\x11\\x48\\x7d\\xb3\\x32\\x11\\x27\\x9c\\x1d\\x78\\x7c\\x46\\xad\\xf6\\xe9\\x7e\\x4e\\x40\\x86\\xe7\\x5b\\x32\\x8f\\xf5\\xbc\\x70\\xd0\\xc0\\x97\\x5d\\x00\\x68\\xcd\\x50\\x69\\x42\\xe6\\xfa\\xaf\\x39\\x64\\xa6\\xec\\xf0\\x8e\\xc0\\x63\\x8a\\x18\\x5d\\x8a\\x0c\\x03\\x92\\x39\\x8b\\x0f\\x2b\\x3c\\xc3\\xfb\\xb0\\x91\\xf4\\x7f\\x3c\\xa6\\xb8\\x95\\xfc\\x50\\x21\\xd8\\xa2\\xaf\\x4b\\x95\\xbe\\xf1\\xc0\\x3b\\x7a\\xa5\\xc6\\xf8\\xe2\\x59\\x5c\\x20\\x24\\xb0\\x07\\x48\\xa4\\x02\\x7c\\x2b\\xdf\\xb4\\x1c\\xc1\\x1f\\xfd\\x92\\x6a\\x8b\\x74\\x35\\x0e\\x10\\x1e\\x30\\x5c\\xda\\x97\\x67\\x25\\x57\\xcf\\xbb\\xc2\\x95\\x0b\\x59\\x2e\\x06\\x0d\\x50\\x60\\x84\\xda\\x5f\\xe4\\x3c\\x44\\x69\\xc9\\x54\\x45\\x00\\xf9\\x71\\xcb\\x70\\x58\\x8f\\x30\\x41\\x97\\x04\\xd2\\x81\\x5e\\x62\\xd0\\xb9\\x89\\x51\\x95\\x74\\xc1\\x9c\\x9f\\xec\\x1b\\x07\\xe9\\x7c\\x8e\\x1a\\x9f\\x0d\\x19\\x52\\xe7\\x3e\\x3a\\xcf\\xd4\\xda\\xcf\\x02\\xbf\\x29\\x41\\x9c\\x3e\\xf9\\x23\\x14\\x29\\x1c\\x97\\xb4\\x04\\xcb\\x2b\\x3a\\xa3\\x49\\x7c\\x6c\\x5f\\xe0\\x50\\x81\\xf7\\x1f\\x83\\x7f\\x30\\x40\\xe1\\x90\\xa3\\x4b\\x80\\xd7\\x0a\\x6e\\xd3\\x7b\\xa8\\x9b\\xdc\\xe0\\x82\\x3d\\x3e\\x5c\\x56\\x71\\x2f\\x46\\xf4\\xbf\\x79\\xb4\\x85\\xc8\\xbe\\x85\\xf0\\xee\\x09\\xb0\\xd1\\x16\\xc5\\x15\\x0d\\x78\\x99\\xf6\\x8b\\x1a\\x8f\\x4a\\x1b\\xf7\\x4a\\x6b\\xf7\\x0a\\x57\\x0e\\x73\\xca\\xfb\\x45\\xfa\\xa7\\x29\\x93\\xc7\\x3e\\xbf\\x61\\x5e\\x1a\\x4a\\x57\\x4c\\x59\\x7c\\x69\\x02\\x2f\\x5a\\x46\\xdf\\xe8\\x12\\x8d\\x0a\\x3a\\x4c\\x8d\\xc4\\x2b\\x63\\xa7\\x46\\xb7\\x7e\\xb3\\x4c\\xd0\\x07\\x55\\x77\\x5e\\x8d\\x2e\\xfe\\x77\\x00\\x5a\\x66\\xb8\\x73\\xef\\xe3\\xbc\\xfc\\xe7\\xbb\\x1d\\xa8\\x90\\x6d\\xd8\\xf0\\xbc\\x7f\\x5b\\x35\\xe0\\x22\\x15\\xed\\xd5\\x6a\\xc0\\xaa\\x1c\\xa6\\xe0\\x5f\\x8b\\xaa\\xbf\\x4f\\x11\\xb5\\x54\\xf4\\xa7\\x52\\x2d\\x76\\x2a\\x6d\\xef\\xd7\\xbd\\xb0\\x44\\x3d\\x5e\\x66\\x23\\x2e\\x79\\x53\\x62\\x56\\xfe\\x5f\\x8e\\x88\\xa3\\x85\\x3f\\x48\\x13\\x0d\\x49\\xf1\\x55\\xaa\\x90\\x24\\x6c\\x5f\\x66\\xff\\x38\\x81\\xe9\\xd1\\xb1\\xa5\\x46\\x4f\\xd9\\x66\\x0b\\x8d\\xf7\\x9d\\x06\\x7b\\x0b\\x85\\x52\\xbc\\x1c\\x82\\x70\\x58\\x55\\x64\\x7d\\xba\\x38\\x14\\x1f\\xd2\\xb4\\x95\\xb2\\x27\\x61\\x73\\xba\\x88\\xcf\\xa4\\xc8\\x82\\xd6\\x90\\x39\\xb7\\x26\\xea\\x8f\\x64\\x92\\x3d\\x95\\xbc\\xe0\\xdc\\x54\\xe0\\x5f\\x03\\xde\\x85\\x06\\xea\\x3a\\x49\\xa5\\x66\\x4d\\xa5\\x65\\x4f\\x23\\x13\\xcd\\x0a\\x9a\\x70\\xd3\\x71\\x59\\x89\\x92\\x0c\\x67\\xb2\\xc1\\x0e\\xa1\\xf1\\x7d\\xd1\\x74\\x7a\\x1c\\x70\\xa8\\x6f\\x9f\\x88\\x41\\x09\\xc3\\x61\\x59\\x9d\\x69\\x10\\x93\\xd0\\x9f\\xf8\\x14\\xf8\\xc2\\xab\\xb8\\xd6\\x23\\xbc\\x40\\x6b\\x28\\x23\\xbb\\xb4\\x3a\\x99\\x21\\xe5\\x37\\x1f\\x16\\x9c\\xc0\\x40\\x8a\\xb7\\xc0\\x30\\x73\\x8b\\x90\\xe0\\xc6\\x65\\x8a\\x17\\x4b\\xb8\\x67\\x51\\x55\\xcd\\x54\\x55\\x91\\x63\\x4a\\x29\\x90\\x6e\\xa2\\x0d\\xc6\\x1a\\xd1\\x62\\xd1\\x1c\\xa8\\xac\\xf9\\x6b\\x34\\x81\\x0f\\x63\\xab\\x23\\x01\\xef\\xbb\\x4b\\x0f\\xfe\\x33\\x5e\\x74\\x15\\x11\\x65\\xd3\\xfd\\x3b\\x14\\x20\\x45\\xfe\\x7d\\xcf\\xe9\\xd8\\xf4\\x5c\\xbd\\xb6\\x89\\xef\\xc3\\x86\\xe7\\x3f\\xfe\\x2f\\x60\\x6c\\xce\\x5a\\x80\\x6b\\x56\\x59\\x9b\\xc6\\xe9\\x0a\\x5c\\x61\\xe1\\xb7\\x0e\\xa4\\xf4\\x42\\x97\\xf6\\x52\\x97\\x46\\x50\\xf3\\xf6\\xd6\\x8b\\xea\\x48\\x41\\x2b\\x2c\\xc2\\x6f\\x11\\x7f\\x81\\xd8\\xd8\\xa1\\xf8\\xaf\\xea\\xcb\\x9e\\xf0\\x3f\\xc7\\x13\\x06\\x43\\x02\\x54\\x1e\\xa8\\x1b\\x16\\xdf\\xe7\\xdd\\x42\\x00\\xe0\\x02\\x92\\x20\\xe1\\x65\\x9a\\x7c\\x8c\\x6d\\xb4\\x11\\x85\\x21\\x71\\x8d\\x67\\x57\\x15\\xcb\\xa8\\x8d\\x8f\\x18\\x1d\\x73\\x1b\\xbc\\x73\\x2d\\xc6\\xb8\\xc5\\xbb\\x24\\xf3\\xcd\\x8c\\x40\\x87\\x66\\x43\\x06\\x1f\\xf9\\x7f\\x8f\\xdf\\xf8\\xbf\\x21\\x09\\x03\\xd1\\xc9\\xfd\\xcb\\xcb\\x90\\xb3\\x0f\\x8a\\x30\\xf8\\x35\\xaa\\x7b\\x6e\\x04\\x25\\x04\\xa2\\x93\\xd0\\x9f\\x75\\x16\\x7f\\xe3\\xab\\x7c\\xd7\\x74\\x63\\xbe\\x41\\x84\\xcd\\x66\\xa0\\xef\\x85\\x57\\x16\\xd1\\x2a\\xf1\\x51\\x44\\x22\\xea\\x58\\x5d\\x9f\\x7f\\xb3\\x45\\xd2\\x40\\x65\\x4d\\x71\\xa1\\x8f\\xdc\\x8b\\x94\\xe6\\xe8\\xda\\x21\\x7e\\x0e\\x2c\\x62\\xbe\\x94\\x27\\x3d\\xbf\\x9a\\xa4\\x7d\\x1a\\x4e\\xc2\\x65\\x4b\\x81\\xa8\\x0f\\x5e\\xc8\\xe6\\xb8\\x44\\x9f\\xf8\\xce\\x7d\\x71\\x8b\\xb8\\x62\\x47\\xf8\\x2d\\x92\\x8c\\x20\\x9c\\xe3\\xfe\\x5c\\xf2\\x63\\xab\\x3f\\x8f\\x3a\\xd5\\x98\\x01\\x15\\x51\\x98\\x94\\xf7\\xa0\\x89\\x2f\\x80\\x97\\xa5\\x2e\\xad\\x97\\x76\\x25\\x3b\\x92\\x58\\xa1\\xd6\\xbb\\xf2\\x5a\\x22\\x18\\xba\\x19\\x74\\xba\\x87\\x7d\\x64\\xed\\xa5\\x5e\\x95\\xa3\\xf3\\x9e\\xc1\\x7d\\x0e\\x84\\xa4\\x89\\x71\\x6c\\xc8\\x1f\\x4e\\x92\\xcb\\x7b\\x91\\x1b\\xaa\\x4b\\x0d\\x38\\xe5\\x7c\\x9b\\x1d\\x08\\x2e\\x9e\\x3b\\x51\\x05\\xc1\\x92\\x12\\x67\\x4c\\xf4\\xbf\\x94\\x56\\x16\\xea\\x99\\x89\\x42\\x9f\\xe2\\x59\\x9d\\x67\\x50\\xc3\\x4a\\x71\\x0b\\x56\\x58\\x92\\x4d\\x66\\xfb\\xb7\\x07\\x27\\xc9\\xcf\\x3f\\x96\\xd8\\x81\\x97\\x40\\xf8\\x1c\\x88\\x6a\\x4a\\xe5\\xea\\x15\\x3e\\xb2\\x68\\x0f\\xb1\\x70\\x59\\x89\\x93\\x24\\x29\\x1e\\x50\\xea\\xc7\\xca\\xfc\\x59\\x26\\x69\\x82\\x1e\\x3f\\xf8\\x0b\\xba\\xec\\xd3\\xbf\\xef\\x29\\xf9\\x3b\\x3c\\x64\\xb3\\xf1\\xb5\\xa6\\x81\\xa8\\x04\\x21\\x8b\\xb3\\x4b\\xa2\\x1f\\x26\\x6b\\x62\\x6c\\x19\\x5e\\xc1\\xbc\\x57\\x89\\x08\\xb0\\xe7\\xbe\\xd7\\x1f\\x7c\\x0e\\xa5\\x43\\x25\\x67\\x16\\x70\\x27\\x98\\x1d\\xf4\\x43\\x11\\xab\\x5a\\x5e\\x1f\\x86\\xad\\x1b\\x31\\x2e\\x7d\\x62\\xb1\\x54\\x4e\\x14\\x26\\x4e\\xd1\\x32\\xd0\\x2d\\xa4\\x1b\\x7a\\x01\\x0f\\x34\\xc3\\x8b\\x37\\xb9\\x75\\x6f\\xff\\xfa\\xf3\\x52\\x44\\x95\\x00\\x24\\x8e\\x23\\xce\\x84\\x92\\x84\\x88\\x46\\x2a\\x50\\x5c\\x9b\\x9f\\x16\\x5b\\xe9\\x2f\\x1f\\x69\\x9a\\x60\\x7a\\x42\\xa5\\x77\\x2f\\x36\\x9f\\xf0\\x32\\x24\\x27\\x9a\\x86\\xfb\\x44\\x61\\x8d\\xa8\\x79\\x69\\xfd\\xee\\x6a\\x06\\xa2\\x9e\\x4c\\x5f\\x9d\\x3a\\xe8\\x42\\xb0\\x91\\xe5\\x9d\\x3d\\x47\\x36\\xa9\\x22\\xc1\\x90\\xf8\\xb4\\xe5\\xd1\\xb6\\xb9\\x15\\x4c\\xf3\\x73\\x2e\\xbb\\x17\\xea\\x9e\\xab\\x29\\xc3\\x7e\\x9e\\xd8\\x75\\x55\\x67\\x97\\xe8\\xfb\\x92\\xe5\\xee\\x99\\x2e\\x00\\xfd\\x55\\x6c\\xee\\x6a\\xfa\\x97\\x23\\xd6\\xf4\\x7d\\xce\\xb3\\x4b\\x2c\\xe1\\x54\\x5c\\x3d\\x25\\x67\\x32\\xe2\\x00\\xad\\x3b\\x0f\\xff\\xc3\\xc1\\xbc\\x24\\xf5\\xd0\\x7e\\xcd\\x1d\\xc6\\x9d\\x38\\x14\\x31\\x49\\xf6\\x69\\x41\\x4d\\x4e\\x2b\\x78\\xd0\\x05\\x4d\\x66\\x02\\x63\\xc2\\xfb\\xae\\x09\\xde\\x39\\x4f\\x94\\x6c\\x1a\\x02\\x23\\x8f\\x72\\x5a\\x88\\xbd\\x5b\\xe5\\x91\\xce\\x9f\\x17\\x6f\\x8e\\x38\\x1b\\x3e\\xfc\\x26\\x10\\xb9\\x02\\x26\\x52\\x7d\\x77\\xc4\\x68\\x62\\xe4\\x2f\\xa9\\x24\\x68\\x01\\x85\\x86\\xfc\\xa7\\xf1\\xbe\\x68\\xf9\\x02\\xb3\\x8a\\x23\\x99\\xec\\x52\\x19\\x75\\x37\\x46\\x6a\\x6d\\x8c\\x28\\x4e\\xb1\\x31\\xe5\\xc5\\x43\\xf4\\xa0\\x38\\x7e\\x2a\\x07\\x6a\\xd6\\xeb\\x85\\x1e\\x9c\\xd4\\xe6\\xba\\xd3\\x92\\x86\\x93\\xf2\\xea\\xa6\\xce\\x81\\xe7\\x14\\x7d\\xca\\xfc\\x63\\x3a\\x89\\x1d\\xb3\\x89\\xbc\\x5f\\x49\\xe8\\x69\\x2e\\xf9\\xb9\\xd0\\xb1\\xc1\\x38\\x59\\x1c\\x22\\x92\\xab\\x6d\\x41\\xd0\\xe7\\x02\\x03\\x66\\xed\\x18\\xe6\\x0b\\x9e\\xa8\\xf7\\xfc\\xe6\\x5f\\xcd\\x23\\x64\\x39\\xab\\x98\\x7c\\x9f\\xbc\\x5f\\x89\\x4b\\x1a\\x6e\\x17\\x42\\xb2\\xd3\\x80\\x51\\x26\\xc7\\x45\\xc2\\xfe\\x9c\\xd5\\xd7\\xdc\\x7f\\xa2\\xdb\\x35\\x95\\x4e\\x97\\x57\\xe8\\x60\\xd2\\x19\\x0d\\xf8\\x9f\\x58\\xa4\\xad\\x59\\x81\\x1b\\x46\\x85\\x86\\xe9\\xd5\\x38\\xef\\x7d\\x18\\xa2\\x34\\x31\\x0c\\xa8\\x74\\x3b\\x6d\\x40\\x4d\\x01\\x7d\\x62\\x48\\xc3\\x0b\\x18\\x9d\\x83\\xee\\xa4\\xb9\\x72\\xc3\\xa2\\x7f\\x3e\\x6c\\x45\\xda\\xae\\xea\\x3b\\xa2\\xfc\\x46\\xa3\\xf5\\x65\\x03\\x5e\\x2d\\x0d\\xe7\\x13\\x4c\\x57\\x51\\x82\\xed\\xf0\\x1d\\x08\\x33\\x7e\\x1e\\xa8\\x50\\x5e\\xa7\\xdb\\x0b\\xc1\\xf2\\x92\\xe4\\x13\\x1d\\xbb\\xea\\x1e\\x03\\xa0\\x9b\\x36\\xcc\\x3d\\xaf\\x70\\xab\\xf2\\xca\\x32\\xb8\\x3b\\xf6\\x4d\\xa1\\x6e\\x6f\\x91\\x8d\\x83\\x24\\x47\\xd2\\x2b\\xd2\\x60\\xf5\\xc7\\x32\\xb5\\x74\\x38\\xe8\\x98\\x26\\xe6\\x48\\x26\\x00\\x76\\xc7\\x02\\x08\\xd0\\xae\\x3f\\xa8\\xef\\xa8\\x81\\x07\\x0f\\x3e\\x36\\xff\\xda\\xc0\\xb5\\xae\\x6b\\xbb\\x2c\\x9d\\x9e\\x1d\\xd9\\x6d\\x5a\\xcf\\xd2\\x13\\xd5\\x31\\x92\\x3c\\xdb\\x3a\\xe8\\xbc\\x96\\x48\\x56\\x9c\\x25\\xc7\\xb4\\xb1\\x8e\\x50\\x67\\xe2\\xec\\x52\\xe5\\x1f\\x63\\xd2\\xc6\\xa3\\x34\\xd1\\x9a\\xd3\\xc7\\x92\\x4d\\x51\\x54\\x4f\\x8a\\x93\\x76\\x41\\x84\\x97\\x56\\xb8\\xe4\\xce\\x9b\\x4a\\xd0\\xc5\\xf5\\x67\\x5d\\xb4\\xa1\\xca\\x1b\\x9b\\xcf\\x33\\x98\\xa0\\xbf\\xe5\\x05\\x95\\xd6\\xd9\\x3d\\x59\\xdb\\xda\\x9d\\xb6\\x1c\\x24\\x08\\x6f\\xb0\\xb4\\x56\\x6b\\xa6\\x50\\x6b\\x23\\xcb\\x57\\x9f\\xa4\\x11\\x2a\\x51\\xb6\\xc7\\x16\\x41\\x45\\x5f\\xd7\\x71\\x79\\x9c\\x06\\x76\\xf7\\x6d\\xff\\xb8\\xb8\\xd7\\x8c\\x7d\\x9e\\xb6\\xfb\\x27\\x91\\x34\\x00\\x0f\\x28\\x94\\xe1\\xb4\\x21\\x5d\\x15\\x48\\x79\\x8c\\x5b\\x1e\\x59\\x7a\\x3b\\xdc\\x3e\\xc7\\x12\\xdb\\x51\\x65\\xc8\\x83\\xab\\x21\\xc5\\xfe\\xc5\\xc1\\x05\\xdc\\x3d\\x4a\\x57\\xae\\x2b\\xb1\\x83\\x95\\xd5\\x30\\x5f\\x26\\xc7\\x94\\x31\\x52\\x09\\x01\\x94\\x4c\\x58\\x98\\x08\\x7d\\x65\\x33\\x30\\xd9\\x0e\\x60\\x49\\x9d\\x57\\xec\\xc8\\xd6\\x90\\x28\\x8c\\x7d\\xf9\\xa7\\x13\\x93\\x40\\x29\\x45\\x43\\x82\\xc6\\x20\\x3e\\x7a\\x60\\x59\\xb2\\x11\\x11\\x7f\\xfe\\xfa\\xfb\\x75\\xfa\\xce\\xca\\xfc\\x1f\\x6a\\xc0\\xba\\x67\\x0b\\x62\\x20\\x0d\\x7f\\x5a\\x3d\\xbf\\x89\\x4e\\x17\\x47\\x6c\\x16\\xba\\x00\\x7e\\x37\\x01\\x15\\x51\\x40\\x96\\xe0\\x7b\\x33\\xc4\\xc4\\x8c\\xd1\\xfb\\xa0\\x9d\\x79\\xc7\\xb0\\xdd\\x55\\xb3\\x1a\\x4b\\x14\\x1a\\x9d\\xc1\\x5f\\xb2\\x1f\\x92\\xc0\\xd9\\xdf\\xb7\\x9e\\x55\\xe6\\x2e\\xaa\\x15\\x5a\\xf2\\x33\\x52\\xdd\\x7a\\xfe\\xb1\\x8b\\x0b\\x17\\xde\\x8f\\xb0\\x78\\x67\\xc6\\xf1\\x32\\x1a\\x3a\\xd6\\xbb\\xe5\\xc9\\x9a\\x60\\x73\\xea\\xc8\\x60\\x1e\\x03\\xad\\x31\\xd5\\x6a\\xb7\\x74\\x0c\\x58\\x3b\\xf7\\x56\\x94\\x21\\xa9\\x36\\x02\\xb8\\x76\\x93\\x54\\xa8\\x3b\\x75\\xd5\\xea\\x83\\xaa\\xad\\x77\\x61\\x43\\x4b\\xd1\\x45\\x47\\x72\\x81\\x1d\\xd0\\x19\\xca\\xf4\\x69\\xcb\\x16\\x63\\x55\\x96\\x2b\\x2e\\x89\\x8b\\x3d\\x22\\xb5\\xee\\x56\\x78\\xcf\\x7c\\xc3\\x94\\x11\\x35\\xe8\\x76\\x50\\x57\\x90\\xe4\\xac\\x46\\x27\\x86\\x72\\xfa\\xca\\xe0\\x18\\x21\\xef\\x80\\x52\\xb9\\x6b\\xf9\\x24\\xe0\\x9a\\x5c\\x2c\\x8b\\xb2\\x05\\x39\\x22\\xff\\x63\\xbe\\xc0\\xce\\x68\\x59\\x9d\\xf0\\x84\\xb2\\x60\\x52\\xbb\\x77\\x32\\x8a\\xa1\\xd4\\xf0\\x35\\x43\\x5f\\x10\\xe4\\xb8\\xe2\\xea\\x44\\x4b\\xe3\\x5e\\xf0\\x42\\xd4\\xf0\\xe1\\x53\\x6a\\x38\\xa7\\xaa\\xcb\\x44\\x03\\xb8\\x70\\x04\\x43\\x75\\x04\\xb5\\xc9\\x8f\\x68\\x1b\\xda\\x2f\\x5b\\x51\\x3d\\x00\\x04\\x1e\\x52\\x4d\\xcb\\x1d\\x04\\xab\\xe1\\xd1\\x6c\\x9b\\x24\\x3c\\xb2\\x80\\x27\\xbe\\xa9\\xdc\\x1c\\x9d\\x33\\x8e\\x31\\x49\\x61\\x75\\xae\\xce\\x59\\x10\\x35\\xba\\xba\\x7d\\xc5\\x12\\x3d\\x70\\x08\\xf9\\x74\\x16\\xa0\\xb9\\x47\\xef\\x6a\\x82\\x4f\\xe4\\x8c\\x74\\x4e\\x27\\x0e\\xbc\\xd0\\xc4\\x44\\x66\\x97\\x3a\\x05\\x1b\\x21\\xf2\\x38\\x75\\x98\\x2e\\xca\\xaa\\x7e\\x0d\\xa9\\xeb\\x1e\\x04\\xdb\\xda\\x61\\x70\\xc2\\x6c\\xfc\\x0a\\x00\\xb0\\xa2\\x60\\x11\\x46\\x0f\\xdd\\x09\\x3a\\x89\\xb0\\x74\\xfe\\x44\\x5c\\x66\\x28\\x33\\xe6\\xd8\\x50\\x39\\x3c\\xf1\\xf8\\xd6\\x71\\x27\\x4b\\xd4\\x42\\x85\\xf5\\x56\\xc5\\x23\\xc4\\x5c\\x2e\\xee\\xb1\\xc2\\x5c\\x6e\\xc5\\x32\\x73\\xa4\\xe4\\x99\\xb1\\x6f\\xac\\xe8\\xf4\\xcf\\x48\\xc7\\xe4\\x89\\xdd\\x5a\\xec\\xc7\\x7a\\xd5\\x9c\\x86\\x43\\xe3\\xf2\\x3f\\xdf\\x01\\x82\\xb5\\x16\\xb6\\x63\\xf5\\x87\\x7f\\xef\\xa4\\xe2\\x91\\xa9\\x99\\xd1\\x53\\x46\\x45\\x36\\xdd\\x75\\x59\\xd5\\x06\\x2b\\xa7\\x5e\\x6c\\x6c\\xc7\\x1a\\xf9\\xd6\\x99\\x1a\\x0a\\x97\\x9e\\x3d\\x8e\\xf9\\x92\\xa8\\x88\\x70\\x5e\\xf5\\x2e\\x2f\\x6e\\x43\\x73\\xdf\\xcb\\xc7\\x34\\xe0\\x3d\\xc6\\xac\\xfc\\x66\\xae\\x30\\xa7\\x1c\\x28\\x3f\\xd2\\x46\\x73\\x9d\\x07\\xcb\\x8f\\x80\\x0a\\x2b\\x42\\xc9\\x60\\xa2\\x89\\x1b\\xdf\\xe1\\x09\\x04\\x34\\xf3\\xbd\\xf7\\x34\\xa2\\xbd\\x4a\\x82\\x21\\x00\\xb1\\x48\\xe9\\x2f\\xa6\\x91\\xd4\\x10\\x38\\xd1\\x17\\x79\\x71\\x89\\x43\\x8e\\x51\\xa8\\x96\\x48\\x43\\xb1\\xbd\\xa6\\x76\\x4b\\x56\\x38\\x5e\\x7e\\x66\\xb6\\x12\\xe7\\x1e\\x8f\\xca\\x58\\x4f\\x81\\xa9\\x7d\\x40\\x46\\x1b\\x63\\xf6\\x5d\\xb7\\x4c\\xea\\xf5\\xf2\\x0b\\xfe\\x3c\\x8a\\xe3\\xef\\x21\\x49\\xaf\\x1f\\x72\\x33\\x8a\\x93\\x77\\x45\\x1a\\x94\\x47\\x98\\xc1\\x30\\xf0\\x65\\xba\\x54\\x2d\\x56\\x72\\xa6\\xb1\\xc8\\xed\\xd7\\xc1\\x75\\x7b\\x9d\\x31\\x77\\xf6\\xcf\\x18\\x68\\x20\\xa2\\x09\\x93\\x87\\xd3\\x2b\\x9a\\xcd\\xb0\\xb4\\x98\\x10\\x67\\xbb\\x9c\\xef\\x61\\xc0\\x2f\\x95\\xa2\\x64\\x7f\\x53\\xb7\\x32\\x70\\xc5\\xc7\\x0a\\x73\\xe5\\x00\\x70\\x1f\\x81\\x22\\xbc\\x46\\x72\\x43\\x67\\x58\\x17\\x14\\xa3\\xaa\\xaf\\x03\\xf5\\xcb\\x0f\\x97\\x92\\x3e\\x10\\x3d\\x1f\\x3e\\xef\\xd4\\x94\\x2a\\xf6\\xa6\\xe3\\x70\\x58\\x5b\\x79\\x02\\x57\\x31\\x92\\xfc\\x8e\\x02\\x70\\x0a\\x13\\x0f\\x84\\x0c\\x3a\\x30\\x0f\\xd7\\x95\\x38\\xd1\\x7d\\x3c\\x45\\xf7\\x02\\x44\\xf8\\x1e\\xbf\\xed\\x40\\x88\\xf7\\x62\\x04\\xe7\\xba\\x88\\xb9\\xc9\\xe6\\x35\\x46\\x78\\x06\\x4c\\xda\\x66\\x04\\x91\\x53\\xb9\\xf3\\x30\\x1a\\x0a\\xd9\\x5b\\x60\\x45\\x54\\x4c\\x1a\\xc7\\x68\\x6f\\xa1\\x68\\x1d\\x45\\x47\\x5e\\xf8\\xe4\\xb9\\x5c\\x92\\x64\\x22\\x31\\xc4\\x10\\x9e\\x6b\\x23\\xe2\\x80\\x13\\xbf\\xac\\x38\\x61\\xf3\\x31\\xb0\\x6f\\x02\\xf3\\x90\\x7f\\xd8\\xea\\x92\\xe1\\x2f\\x44\\x6f\\x4c\\x67\\x34\\x1c\\xbc\\x10\\x02\\x2b\\x66\\x90\\xa9\\x35\\xee\\x3e\\xf7\\x12\\xd7\\x3d\\xd9\\xee\\xe9\\x35\\x02\\xe7\\x81\\xea\\xc2\\x1f\\x3b\\x67\\x12\\x40\\x91\\xbb\\x0c\\x1e\\xc0\\x14\\x61\\x53\\xdb\\x0f\\xe3\\xb2\\xa6\\xd5\\x45\\x02\\x22\\x65\\x70\\x0b\\x44\\x54\\xf0\\xca\\xb2\\x0c\\xb8\\x56\\x94\\xc4\\x58\\x05\\xed\\xa5\\x16\\x39\\x90\\x25\\xcf\\x63\\x5b\\x9a\\x74\\x0e\\x75\\x27\\x40\\x52\\xc8\\xae\\x5e\\x9a\\x9d\\x42\\xf6\\x49\\x58\\x4c\\xc5\\xf7\\xd5\\xb8\\xf9\\xe2\\xf9\\x9f\\x87\\x12\\xb9\\x0c\\x7c\\xa0\\xb3\\x24\\x77\\x8f\\xb1\\x45\\x6f\\x81\\x68\\xcf\\x0f\\x24\\xa7\\x01\\x0e\\x38\\x8f\\x02\\x71\\x5e\\xc4\\x0a\\x37\\xaf\\x49\\x21\\x0e\\x1e\\xa1\\xb7\\xf4\\x98\\x8a\\xbd\\x7b\\xd7\\x5a\\x81\\x83\\x00\\x4e\\x08\\xba\\x6c\\x05\\x93\\x52\\x29\\x89\\x6f\\x36\\xe1\\x3d\\xcf\\x77\\xd7\\xb8\\xfb\\x68\\xa5\\x5b\\x59\\x87\\x0d\\x26\\x30\\x95\\xab\\xff\\x15\\xfc\\xb2\\xbf\\x5c\\xe4\\x9b\\x1b\\xe5\\x73\\x68\\x21\\xfe\\xbc\\xe6\\xd2\\xbf\\x45\\x79\\x29\\x3e\\xc3\\x5a\\x91\\xbb\\xa9\\xc1\\xbe\\x69\\x6f\\xf3\\xeb\\xbd\\x0f\\xbf\\x49\\x84\\x0c\\x32\\x03\\x72\\x3b\\x79\\xd8\\x12\\xc4\\x81\\xe8\\x3c\\xfa\\x9c\\x7e\\x0f\\xff\\xfc\\xc4\\xef\\x99\\xa9\\x0c\\xfb\\xcd\\x47\\x6a\\x7a\\x5c\\x2c\\x57\\x2b\\xbb\\x3e\\x18\\xc9\\xe0\\x43\\x86\\x54\\x53\\xfe\\x54\\xa6\\x87\\xf7\\x44\\xe0\\xd6\\xfe\\x3c\\x4a\\x4e\\x3c\\x3a\\xbd\\x21\\x83\\x4d\\x7d\\xf0\\x1a\\xe6\\x18\\xe0\\x48\\xb9\\xf5\\x48\\xb6\\x7c\\x0d\\x59\\x7f\\x7f\\x9f\\x5d\\x45\\x60\\xb4\\x0f\\xe1\\x36\\x6d\\x30\\xa1\\x5f\\x15\\x25\\x3a\\xb6\\xff\\xcc\\x58\\xd6\\xa0\\x1b\\xa5\\xb6\\xb1\\xa7\\xf4\\x70\\x0b\\x0c\\xd1\\x5d\\x6a\\x5f\\xf3\\x83\\x62\\x21\\xb2\\xbf\\x87\\xb6\\xd4\\x36\\xfc\\x7e\\x3c\\x70\\xb0\\x0b\\x22\\xf3\\x0b\\x35\\x46\\x24\\xff\\x60\\x90\\x8e\\x97\\x11\\x19\\xe8\\xb0\\xc1\\x7b\\x12\\x60\\x8d\\x2d\\x31\\x01\\x4e\\x96\\x19\\x23\\xe9\\xc0\\x83\\xfe\\xf8\\x3e\\xec\\x17\\x1f\\x78\\x5a\\x12\\xb6\\xc4\\x1a\\x48\\x7b\\xd2\\x1d\\xcb\\x22\\x81\\x5b\\x12\\x68\\xa9\\xad\\xd8\\xec\\xd9\\xf8\\x82\\x0f\\x54\\xf0\\xfe\\xc4\\x1f\\x20\\xba\\x0c\\x5f\\xf2\\x37\\x2f\\xa8\\xaa\\xa3\\x0a\\x16\\x7b\\xcd\\x2d\\xdd\\x8a\\x33\\xc9\\x91\\x82\\x7e\\xe6\\x27\\x8c\\xff\\xc7\\xde\\x75\\xb4\\xde\\x8f\\x73\\xe7\\xfd\\xfb\\x29\\xc2\\x64\\x15\\x0c\\x71\\x6f\\x33\\x24\\x60\\xdf\\xeb\\x5e\\xaf\\xbb\\x4d\\x36\\xee\\xbd\\x77\\x87\\xf7\\xbb\\x87\\xfb\\x1b\\x08\\xff\\xc9\\x2e\\xfb\\x11\\x78\\x61\\x21\\x74\\x2c\\xe9\\x41\\xe7\\x3c\\xb2\\xa4\\x47\\x30\\x10\\x5f\\x09\\x9f\\x58\\x97\\x5b\\x8a\\x0e\\xb7\\x03\\x00\\x89\\x93\\x1a\\x15\\x01\\x79\\x03\\xb3\\x16\\xeb\\x02\\x41\\xa7\\x47\\xbe\\x30\\x63\\x68\\x62\\x68\\xa7\\x99\\xc1\\x46\\xe6\\x82\\xe1\\x3b\\x15\\xbd\\x02\\x9d\\xbb\\x8b\\xbc\\x17\\xef\\x81\\x36\\xec\\xe5\\x6b\\x1c\\x15\\xbd\\x89\\x90\\x13\\x8a\\x49\\x2d\\xa9\\x52\\x59\\xb1\\xdb\\x79\\x5e\\x66\\x5a\\x94\\x88\\xb1\\x50\\xf1\\x24\\x42\\x33\\xf9\\xbc\\x62\\x3a\\x49\\x81\\x42\\x5f\\xfb\\xc7\\x6b\\xb0\\xf5\\x96\\xbc\\x21\\x42\\xb0\\x98\\xaf\\xbe\\x6c\\x74\\xe6\\x20\\xa3\\x22\\x8c\\x76\\x52\\xad\\x0d\\x00\\x43\\x01\\x29\\xa1\\xb0\\xb0\\x7c\\xe4\\xf1\\xaf\\xe2\\x10\\x1b\\x80\\xc8\\xb5\\xc1\\x13\\xca\\x2c\\x78\\x00\\xf0\\x38\\x50\\x62\\xdd\\xf5\\xb8\\x93\\x7d\\x6f\\x70\\x46\\x8c\\xce\\xc1\\xe2\\x20\\x2c\\x8e\\x36\\xc9\\x0c\\xa0\\x97\\xd8\\xdf\\xac\\x43\\x8c\\xf9\\x0f\\xf1\\xa6\\x11\\x52\\x5f\\x60\\x02\\x1f\\xe1\\x18\\x8c\\x55\\x2b\\x0f\\x06\\x3c\\x74\\x39\\xf6\\x31\\xbb\\x73\\x2f\\x8c\\x01\\xa1\\x87\\x04\\x4b\\x05\\xca\\x38\\x20\\xba\\x70\\x8f\\x0a\\xcb\\x9c\\x82\\x67\\x1c\\x0e\\x37\\x70\\x0a\\x48\\x1b\\x40\\xb4\\xfb\\x39\\x1e\\x64\\x1c\\x34\\x9a\\xa1\\x0d\\x2b\\xde\\x7c\\xf1\\xdf\\x66\\x6d\\x13\\x44\\xfa\\xef\\x7b\\x81\\x32\\x47\\x53\\x5f\\xd8\\x4e\\xae\\x86\\xf8\\x06\\x03\\x12\\x47\\x4f\\xa0\\xa0\\x11\\x81\\x0e\\x26\\x22\\xef\\x40\\xba\\x13\\x17\\x88\\xd4\\x45\\x75\\x0f\\xb2\\x2f\\xa1\\x9b\\xe3\\x7a\\x24\\x34\\x15\\xd8\\xf3\\xf0\\xe8\\x63\\x3a\\xde\\xa8\\xab\\xa5\\x85\\xe6\\x08\\x21\\xf9\\xae\\xc6\\x58\\x24\\x39\\x86\\x6a\\x42\\x40\\x47\\xef\\xb4\\xe3\\x2d\\xd7\\x95\\x6e\\xb5\\x18\\x09\\xa3\\xd2\\x86\\x46\\xee\\x80\\x78\\xf6\\xbc\\xaa\\x8c\\x96\\x1b\\x60\\x3f\\xca\\xdb\\xfb\\x18\\x07\\x0b\\x7e\\x52\\x89\\x0d\\x8f\\x22\\x4f\\x8a\\x0d\\xe5\\xf8\\xae\\x6c\\x8d\\x3d\\x78\\x23\\xe7\\xeb\\x1c\\x15\\x67\\xc2\\x30\\x2e\\x38\\xab\\x59\\xbd\\x29\\x51\\x41\\xb7\\x89\\x26\\x82\\x80\\x89\\x89\\xbc\\x3c\\xa3\\xb0\\xaf\\xc6\\xdb\\xb4\\x96\\xdc\\x0a\\x33\\x33\\x38\\xfa\\x45\\x9a\\x95\\x57\\xd3\\x1f\\x10\\xb9\\xe4\\x85\\x5a\\xec\\xa8\\xd7\\x9d\\xaa\\xeb\\xf1\\x56\\x6e\\xd2\\x17\\x11\\x0f\\x13\\x60\\x0c\\xc8\\x02\\x8b\\xcd\\x89\\x24\\xfa\\x22\\xdf\\x0a\\x15\\xbb\\x9d\\x6c\\xbd\\xd9\\x93\\xcc\\xf7\\x00\\x21\\xa7\\x39\\x12\\x86\\x79\\x0b\\x6d\\xb7\\x9b\\x6e\\xfd\\xf5\\xa3\\x4f\\x36\\x49\\xe1\\x8c\\xd6\\x61\\x07\\x04\\xb5\\x19\\xae\\x36\\x0c\\x60\\x67\\x6e\\xfa\\x41\\xec\\x99\\x8f\\x66\\x47\\xed\\x99\\x0c\\x57\\x9a\\xbc\\x6e\\xcf\\x82\\x6f\\x20\\x5d\\x5d\\x86\\x27\\x6e\\x2e\\x0a\\x19\\xef\\xc6\\xa3\\x62\\x47\\x47\\x2f\\x0d\\x5f\\x04\\xb9\\x2b\\xfd\\xe2\\xad\\xc4\\x1a\\xa0\\x74\\xe4\\xe1\\x39\\xda\\x94\\x20\\x08\\x01\\x05\\xd1\\x98\\x51\\xb8\\x12\\x54\\x9e\\x1a\\xc2\\x1b\\x3c\\x0c\\x91\\xb0\\x87\\x29\\x82\\xf0\\x22\\x4f\\x14\\x3c\\xdd\\x30\\x80\\x28\\x7f\\x48\\x64\\x80\\xd2\\xa0\\x55\\xd3\\x58\\xe7\\x52\\x76\\x6d\\x7f\\x28\\xd5\\x78\\xb0\\x2f\\x4f\\x24\\xc0\\xe3\\xaa\\x63\\x08\\xda\\x92\\x0f\\x75\\x38\\x97\\x98\\x0f\\x8b\\x72\\x67\\xb1\\x04\\x2d\\x11\\x4d\\xd0\\x09\\x93\\x62\\x82\\xc4\\x80\\xfb\\x38\\x2b\\xcd\\x0a\\x1a\\x3a\\x9a\\x23\\xb3\\x63\\x0f\\x6a\\x47\\x49\\x3a\\x52\\x0c\\x24\\x50\\x15\\xe6\\x50\\xde\\x14\\xc7\\x5b\\xa1\\x3f\\x6e\\x1d\\xcd\\x62\\xa0\\x18\\xd3\\xfb\\x3e\\x84\\xfb\\x62\\x63\\x40\\x6e\\x46\\xbe\\xdb\\xf1\\xd5\\x13\\x58\\x9c\\xc5\\xa5\\xab\\xaf\\x5e\\x82\\x7a\\x05\\x72\\xb2\\x42\\x93\\x62\\xb7\\xbb\\xaf\\xfa\\x9e\\x43\\x8f\\x20\\x05\\x9a\\x27\\xbe\\x22\\x31\\x58\\x87\\x40\\x80\\x5f\\xc0\\x4a\\x50\\x2f\\xb6\\xc6\\xc3\\x35\\x3a\\xf2\\x17\\x44\\xda\\xd0\\xc6\\x9a\\x62\\xd3\\x21\\x64\\xde\\x42\\x86\\x77\\x2a\\xd3\\xac\\x94\\x5a\\x5a\\x1d\\x2d\\x99\\x9b\\x0f\\x6c\\xdb\\x70\\x40\\xd9\\x2e\\x15\\xf0\\x66\\x42\\x50\\x91\\x86\\x14\\xf5\\xee\\x3e\\x9f\\x11\\xab\\xc4\\xf5\\x6e\\xb5\\x39\\x21\\x80\\x62\\x7b\\xf3\\x9c\\x72\\x4b\\x11\\xf6\\xb3\\x47\\x6c\\xeb\\x9f\\x90\\x67\\x4f\\xb7\\xe1\\x45\\xd9\\x50\\x58\\x7b\\x0f\\x96\\xdd\\xbf\\x97\\x2b\\xd4\\x26\\xdb\\x6a\\x1d\\x9e\\xbe\\x37\\xbb\\x10\\x6a\\x75\\xa0\\x82\\xea\\xc1\\x57\\x28\\xd3\\x06\\x67\\x6c\\xc0\\xeb\\xfa\\xb8\\x22\\x0b\\xa4\\x6f\\xa6\\x55\\xde\\x65\\x39\\x4a\\x2f\\x5d\\x81\\x0a\\x58\\x91\\xf9\\x17\\x4c\\x83\\x07\\x85\\x67\\x7b\\xcd\\xb8\\x0f\\xef\\x39\\x2e\\x6a\\x3e\\xd7\\x0a\\x3b\\x8c\\x9d\\x3a\\xdc\\x25\\x59\\xef\\x00\\xa6\\x0b\\x97\\x3e\\x16\\x4a\\xdc\\xc9\\xb5\\xea\\xec\\x2d\\xc9\\xcd\\x60\\x33\\xc4\\x06\\x60\\x3b\\x67\\x5a\\xc7\\x39\\xee\\xbf\\x3c\\x20\\x9f\\x53\\x43\\xb4\\x4b\\x40\\xed\\xb2\\xbd\\x87\\x79\\xde\\x4a\\x7d\\xef\\x86\\x0b\\x63\\x70\\x7a\\xa7\\x9f\\x66\\x85\\x3e\\x52\\x4f\\x7b\\x8c\\x07\\x2c\\x35\\x81\\x66\\x8f\\xcf\\x01\\x0b\\x8d\\xb5\\x3f\\x2b\\xab\\xe4\\x43\\x42\\xcf\\xa7\\xe6\\x8c\\x84\\x5f\\x62\\xcb\\x86\\xfb\\x19\\x9a\\xca\\x7c\\x4d\\xd7\\x68\\x98\\xf0\\x9c\\xd4\\x74\\x10\\x66\\xbc\\x27\\x97\\x28\\xda\\x54\\x9c\\x8d\\x66\\x24\\x8d\\x4e\\x18\\x1c\\x76\\x29\\xb5\\x56\\x36\\x97\\x27\\x25\\x0d\\x73\\x28\\x90\\xc4\\x68\\x78\\xfb\\x76\\x3b\\xb9\\x90\\xcf\\x23\\x5b\\x62\\xa4\\x35\\xc4\\xf7\\xb5\\x12\\x89\\x5c\\x42\\xdc\\x94\\xd8\\x05\\x7a\\xa5\\x01\\x4c\\x83\\xf4\\x76\\xe2\\xb7\\x59\\xb6\\xef\\x58\\x17\\x01\\xfb\\xd3\\xb9\\x87\\x0d\\x00\\x13\\xed\\xa8\\x12\\xbf\\x27\\x1b\\x81\\x51\\x69\\x61\\xa0\\xa8\\x7e\\xa7\\x15\\xa3\\x00\\xb9\\xd3\\xe2\\xaa\\x55\\x42\\xa9\\x2a\\xb0\\x65\\x72\\xa7\\x54\\xcf\\x57\\xa1\\xb7\\x78\\x33\\xa2\\xe4\\x6c\\x73\\x49\\x28\\xbd\\x46\\x82\\x0d\\x45\\x66\\x7b\\x1b\\xe4\\x5e\\x20\\xa0\\xac\\x4a\\x93\\x98\\xee\\x01\\x44\\xca\\xef\\x06\\x03\\x12\\x73\\x10\\xb4\\x05\\xe7\\x5b\\x8f\\xbf\\xbe\\xfe\\xb1\\x84\\x0a\\x23\\x96\\x71\\x0a\\x88\\x25\\xb6\\x5f\\xa9\\xa2\\x50\\xa1\\xc7\\x18\\x1c\\xe7\\xc2\\xc0\\x6e\\x05\\xbc\\x51\\x8d\\x91\\xad\\x36\\x68\\x53\\x46\\x49\\x9a\\xe3\\x63\\xa6\\xee\\xe5\\xdc\\xac\\xce\\x9b\\x48\\xf4\\x6f\\xf4\\xff\\x62\\x3c\\x42\\x52\\x81\\x57\\x8d\\x14\\xcf\\x8a\\x14\\xe6\\xa7\\xa6\\xf3\\x7d\\x38\\x86\\x77\\x17\\xd3\\x7d\\xd4\\x47\\x74\\xfe\\x78\\x33\\x94\\x1f\\xc3\\x9e\\xf4\\xf8\\x20\\xdb\\xb4\\xcd\\xb3\\x67\\x48\\xd5\\xd2\\x6e\\x55\\xea\\xd2\\x2b\\xf5\\x38\\x39\\xd5\\x49\\xee\\x9f\\xe7\\x4c\\xa3\\xc8\\xf6\\x1b\\x6b\\x2e\\x4c\\x94\\x32\\xde\\xe5\\x4c\\xa4\\x39\\x4c\\x44\\x7d\\xd8\\x13\\xc0\\xee\\xde\\x40\\x10\\x23\\xfa\\x4c\\xec\\xea\\x8c\\xbd\\xab\\x73\\xac\\xce\\x03\\xb2\\xdb\\x4d\\x5d\\x30\\xab\\x78\\x2f\\xd3\\x59\\xa6\\x41\\x61\\x28\\xf0\\xb6\\xbc\\x11\\xe1\\xcd\\x0e\\x25\\x56\\x2b\\x74\\x23\\xf6\\x90\\x68\\xd1\\x81\\xcb\\xb3\\x23\\x94\\x28\\xfc\\x0c\\x1c\\x4c\\x51\\x9a\\x84\\x84\\x08\\x65\\xa7\\xdf\\x40\\x16\\x1c\\xd7\\x39\\xba\\xae\\xc8\\x55\\x89\\xff\\xac\\x2d\\xcd\\xca\\xbd\\xfd\\xf0\\x06\\xea\\xd9\\xf6\\x8d\\xf0\\x15\\x55\\x88\\x57\\xba\\x10\\x68\\x57\\x9c\\x9f\\xd7\\xe8\\x67\\xc6\\x90\\x21\\x22\\x20\\x57\\x09\\x42\\x1d\\xc3\\x25\\x60\\x19\\x58\\xec\\x50\\xaa\\x8b\\x5c\\x25\\xd9\\xc7\\xe1\\x8a\\xc0\\xb1\\x10\\xe8\\xac\\x0b\\xf9\\xe7\\xcc\\xa8\\x7a\\x55\\xc3\\x46\\xba\\xb5\\x9a\\x10\\x2b\\x0f\\x20\\xf3\\xc5\\x03\\x7a\\x72\\x3e\\xbb\\x48\\xb8\\xa8\\xcf\\x2b\\x60\\x42\\x33\\x45\\x55\\x1b\\xde\\x2c\\x4e\\xf7\\x8e\\x05\\xa2\\x72\\x93\\x6f\\xa5\\xed\\x3b\\x5f\\xe3\\x40\\x31\\xdc\\xa9\\x0a\\xbd\\xca\\x98\\x35\\x51\\xf2\\xdb\\x37\\xd7\\x9a\\x08\\xd7\\x07\\xa0\\x65\\xdf\\xf3\\x02\\x18\\xc6\\xdd\\x25\\x8c\\xb2\\x57\\x40\\xd2\\x40\\xe3\\x62\\x2a\\x47\\xf4\\xcb\\x8c\\x16\\x13\\xb2\\x06\\xd9\\x49\\xe8\\xdd\\x0c\\xc7\\xb7\\x51\\xe6\\x5a\\x03\\xd2\\x66\\xec\\x0f\\xd3\\x16\\x6f\\xc1\\xb7\\x9f\\x8a\\x03\\x25\\x36\\xef\\xe1\\x2b\\xad\\x68\\x10\\x27\\x7e\\xc8\\xec\\xc6\\x6d\\x8c\\xce\\x4d\\x17\\xd6\\x1c\\xc3\\x79\\x9c\\x6a\\x2c\\x44\\x90\\xda\\x8d\\xa2\\xcb\\xa8\\xe5\\x30\\x87\\x07\\x50\\xaf\\x5c\\xb9\\xb5\\x46\\x74\\x32\\xa2\\x0a\\xdc\\x4e\\xf6\\x5d\\x58\\x77\\x3c\\x2f\\xf0\\xa0\\x8c\\xbb\\xb6\\xe7\\x85\\x6e\\xaa\\x72\\x6f\\x89\\xd7\\x41\\x77\\x88\\x83\\x77\\xfb\\x68\\x8f\\x36\\x69\\x85\\x48\\xef\\xe0\\x8f\\x1e\\x6c\\x27\\x4d\\x02\\xb6\\x28\\x37\\xb5\\x70\\x97\\x2d\\x21\\xe2\\xce\\xdb\\xc3\\xc9\\xf3\\x96\\xe7\\x65\\x3e\\x17\\xb7\\x4a\\x05\\xe9\\x8e\\xfb\\x68\\xaa\\x7d\\x2e\\x51\\xa4\\x5d\\x50\\x26\\x66\\x37\\x1d\\x3c\\x17\\x28\\x0e\\xe3\\x44\\x6b\\xe4\\x86\\x10\\x97\\xac\\xbe\\x38\\xf7\\x75\\x1c\\x30\\xf9\\x80\\xd2\\x93\\xa2\\x0a\\xd2\\x2e\\xf1\\x05\\x4d\\xaa\\x4d\\xe8\\x7d\\x65\\x3a\\x24\\x6f\\xf6\\x0a\\xd3\\x7d\\xbd\\xbd\\xcf\\x6e\\x4b\\x6c\\x7c\\xa1\\xd6\\x27\\x3d\\x9e\\x38\\x7a\\x82\\x1b\\xaf\\xfa\\x94\\xae\\x09\\x42\\xe5\\x27\\x25\\x3c\\xba\\xd3\\x84\\x37\\x1a\\xe6\\xba\\x20\\xe1\\xa3\\x06\\x67\\xec\\xc7\\xe5\\xa9\\x42\\x7c\\x6e\\x84\\x4c\\x27\\x12\\xd6\\xb9\\xb1\\x57\\xae\\x9d\\x3b\\x57\\xb5\\x0d\\x84\\x9c\\x48\\x9a\\x74\\x69\\x14\\x65\\x1d\\x5f\\x65\\x3c\\xc7\\xfd\\x3c\\x03\\x45\\xaf\\x7d\\xf9\\xb5\\x6a\\x43\\xdf\\x21\\x39\\xd6\\x92\\x72\\xaa\\x54\\x57\\x1d\\xa8\\x96\\x1a\\xe9\\x32\\x73\\x99\\x75\\xda\\x9f\\x3b\\x81\\xeb\\x71\\x52\\x90\\x6d\\x89\\xe1\\x2d\\xf6\\x97\\x68\\x87\\x88\\x58\\xff\\x5c\\xfb\\x8b\\xc5\\x66\\xb9\\x4e\\x06\\x04\\xa6\\x83\\x64\\x43\\xa8\\xe0\\x2e\\x04\\x64\\xa0\\x97\\x18\\xd9\\x60\\x92\\x1e\\xd8\\x2b\\x4b\\x7d\\x2e\\x75\\x3a\\x2b\\xf0\\x60\\x1a\\x07\\xe3\\x2c\\x86\\xf3\\xc3\\x1c\\x09\\x2d\\x32\\xfc\\xa6\\xd2\\x8e\\x6e\\xeb\\x1f\\x6f\\xee\\x40\\xb0\\x18\\x50\\x92\\x8e\\xb5\\x7b\\xb3\\x59\\x8a\\x48\\x6c\\xaa\\x38\\xdc\\x19\\x0f\\x60\\xc5\\xef\\xa6\\xf8\\xe3\\x0a\\x80\\xcf\\x5f\\xbe\\x5c\\x45\\x81\\xe7\\xa5\\x95\\x76\\x38\\x6b\\xe9\\x7c\\x2e\\xfd\\xfd\\x79\\x34\\xd2\\x38\\x57\\xf5\\x75\\x6f\\x53\\x82\\x33\\xe5\\xae\\x35\\x28\\xb5\\xc9\\xcf\\x41\\x7e\\x19\\xcd\\x86\\x90\\x79\\x61\\x06\\x33\\x1f\\xee\\xef\\x91\\x10\\x2a\\x28\\x23\\xad\\xd5\\x33\\x87\\xa7\\x82\\xc8\\xcc\\xb7\\x2e\\x7b\\x18\\x99\\x96\\xd5\\xeb\\xb5\\x68\\xfc\\xc7\\x5b\\xd1\\xa5\\xa3\\x41\\xbe\\x82\\xb6\\xd6\\x79\\xdf\\x1f\\xac\\xae\\xc7\\x5e\\xfd\\xd2\\xb3\\x14\\x00\\x9d\\x09\\x4e\\xd6\\x20\\xda\\xc6\\x17\\xc3\\xbc\\xa5\\xfa\\x47\\x6b\\xb7\\xc6\\x76\\xa9\\x40\\x45\\xfa\\x06\\x33\\x88\\x06\\xb8\\x95\\x5c\\x88\\xbc\\x83\\x49\\x5a\\x68\\x72\\x0c\\xdc\\xe9\\x9f\\x73\\x56\\x0a\\x6a\\x9a\\xf7\\x80\\xcd\\x4a\\xed\\x93\\xd9\\x1e\\x90\\x34\\xa2\\x3a\\x61\\x5f\\x55\\x90\\x53\\xd4\\xd0\\xa6\\x16\\x07\\x44\\xe6\\xc7\\xd7\\x13\\x03\\x47\\x43\\xce\\x3c\\xc6\\x5e\\xda\\x9b\\x04\\x1c\\xa7\\xc5\\x0d\\x8b\\x33\\xa5\\x0b\\x17\\xad\\x86\\x50\\x9b\\x3e\\x11\\xd5\\x25\\x7b\\x8d\\xd9\\x0b\\xc8\\xf2\\x15\\x79\\xf7\\x68\\xbc\\xf5\\xb0\\x78\\x26\\x16\\xc7\\x30\\xef\\xf9\\x1b\\x47\\xa3\\x2a\\xfc\\xd0\\x20\\x41\\xe7\\x14\\x50\\x8f\\xf7\\xba\\x28\\x40\\x07\\x9e\\xa5\\xc2\\x8e\\x82\\x31\\x7c\\x7d\\x63\\x96\\x1f\\xe9\\xf4\\x39\\xfa\\x9e\\x61\\x18\\x46\\xab\\x1f\\x5a\\xb5\\x21\\x19\\x03\\x0a\\x8b\\xf3\\x78\\x33\\x00\\x91\\x46\\x84\\x71\\xaf\\xb3\\x5c\\xcf\\x78\\x36\\x32\\x5b\\x49\\x23\\x48\\x46\\x48\\x13\\x7f\\xd6\\x14\\xde\\x1e\\x4d\\x90\\xb8\\x60\\x8a\\x0d\\xa2\\xe4\\xe6\\x07\\xd3\\x26\\xf9\\x7a\\x22\\xd2\\xc4\\xe9\\x9f\\xc3\\xbb\\x5d\\x8c\\xe7\\x7b\\x90\\x1c\\x8a\\x97\\x62\\x02\\x63\\x26\\x2c\\x60\\x56\\x60\\x0b\\x95\\x6d\\x9a\\x08\\x17\\xe4\\x89\\xd6\\x17\\x59\\x0b\\x0c\\xd0\\x4a\\xbd\\x2e\\x21\\x35\\x47\\x14\\x5a\\x52\\xdc\\x65\\x38\\xd1\\x8a\\x24\\x3a\\x02\\x5a\\x63\\x1b\\xa8\\x3f\\x4b\\xf9\\x47\\x89\\xbd\\x4f\\xf6\\x1e\\x97\\x9b\\x02\\x8d\\xde\\x91\\x21\\xa0\\x30\\x45\\xf4\\x06\\x44\\x5e\\xb0\\xca\\x78\\x7b\\x5a\\x98\\xfd\\xa4\\xe2\\x17\\x86\\xec\\x99\\x0a\\xd5\\xe2\\x6a\\x09\\x7b\\x16\\x1a\\x5f\\xa6\\x0c\\x23\\xbd\\xc0\\x99\\xe8\\xa7\\x3a\\x04\\xcc\\x06\\xdb\\xf5\\xa2\\x40\\x67\\x38\\xdd\\xb1\\x8e\\xba\\xf4\\x6e\\xde\\xa7\\xc9\\xf7\\x86\\x88\\x2e\\x94\\x65\\xfa\\x91\\x1e\\xd2\\x17\\x1b\\x29\\x1e\\xa8\\xe8\\xce\\x25\\x93\\x64\\x59\\x0d\\x7b\\xbd\\x19\\x1e\\x9c\\xa0\\x73\\x53\\xa4\\xe0\\x74\\x0b\\x36\\x0d\\x32\\x2f\\xc0\\xbc\\x1e\\x0d\\xd5\\x7d\\x32\\x9b\\xd0\\x64\\xd2\\x7b\\x30\\x36\\x9a\\xa9\\x29\\x99\\x95\\x31\\x04\\x16\\x04\\x09\\xef\\x40\\x10\\x32\\x3b\\x02\\x2a\\x11\\xae\\xb4\\x10\\xe5\\xdb\\xed\\xa6\\xd9\\xef\\x21\\x7f\\x31\\x55\\xd6\\xf5\\x78\\x4f\\xfb\\xf3\\xe0\\x3c\\xb4\\x2e\\xf6\\xb9\\xa9\\x36\\xb4\\xa9\\x36\\x7d\\xaf\\xcc\\xe7\\x75\\xaf\\x8b\\xfc\\x35\\x65\\x51\\x80\\xca\\xdf\\x64\\x8d\\xc1\\xba\\xe5\\xf6\\xf6\\x53\\x79\\xbc\\xee\\xac\\xdf\\x98\\x46\\x40\\xfd\\x45\\x20\\x51\\x77\\xe6\\x3f\\xb5\\x38\\xb2\\x0c\\xf3\\x62\\x44\\x5c\\x70\\x86\\x02\\x25\\xe8\\x7c\\x47\\x13\\x9a\\xea\\x65\\x3b\\xec\\x0e\\x14\\x49\\x86\\x08\\xd6\\x1f\\x32\\xc3\\xd4\\x29\\x5f\\x66\\x62\\x5b\\xe2\\x3e\\xea\\x63\\x64\\x5b\\x22\\x1f\\xee\\x42\\xc4\\x78\\x0b\\x89\\xf7\\x31\\x61\\xcf\\xf3\\x62\\x3a\\x3f\\xc6\\x5b\\xad\\xa1\\x4d\\xf9\\x06\\x1e\\xb6\\xf9\\x60\\x58\\xa8\\xaf\\x08\\x79\\xf7\\xdd\\x14\\x6f\\x4d\\x88\\xc0\\x8d\\x8b\\xa8\\x5d\\x8d\\xae\\x3e\\x99\\x09\\x7d\\x75\\x32\\xf4\\x2a\\x62\\x80\\x02\\xe6\\x5b\\x06\\xd0\\x39\\x5e\\x50\\x74\\x0f\\xc7\\x7e\\x37\\xf5\\x56\\x1f\\xf5\\x3f\\xbf\\xff\\xea\\x10\\xe6\\xa8\\xf3\\x3b\\x8b\\xc2\\xb1\\xa0\\x7b\\x6c\\xc9\\x30\\x2c\\x87\\xcb\\x16\\xc7\\xbb\\x59\\x10\\xc0\\xb4\\x69\\xc7\\x42\\xd5\\xc2\\xba\\x3f\\xcd\\xb1\\xde\\xb8\\xb7\\x5e\\x4a\\x02\\x0c\\xb1\\x8c\\x78\\x15\\x79\\xd0\\xe1\\x9f\\x56\\x7d\\x21\\x94\\xdd\\xe2\\xc6\\x17\\xf4\\x36\\x1a\\xc7\\xdd\\x04\\x75\\x8d\\xf4\\x25\\x01\\x88\\xde\\x30\\xa3\\xd0\\x39\\x9f\\x4b\\x73\\x5c\\xe4\\x8b\\xa2\\x35\\x89\\x6f\\xbd\\x09\\xcf\\x4f\\xf1\\x85\\x71\\xd1\\xc1\\xb2\\xed\\x76\\xb3\\xdd\\x4e\\x82\\xd5\\x47\\x82\\x35\\x4c\\x84\\x3f\\x4c\\xdf\\xef\\xfa\\xd6\\xc6\\x7e\\x3e\\x82\\xb7\\x80\\x11\\x65\\x76\\x74\\xe0\\x91\\xf9\\xf5\\xc9\\x4d\\xa1\\xf9\\x40\\xb1\\x8e\\xe0\\x2b\\xa2\\x3b\\x1f\\x44\\x73\\x38\\x44\\xaf\\x42\\x89\\x7d\\x95\\xe5\\xf8\\xc2\\xb0\\x5d\\xad\\x27\\xcd\\xe1\\x32\\x00\\xcc\\x7f\\x94\\xd8\\xe2\\xbc\\x8b\\x08\\x7b\\xc0\\x01\\xa7\\xb5\\x15\\x90\\x9d\\x89\\x7d\\x11\\xae\\x36\\xf9\\x51\\xf0\\xbb\\xd6\\xa4\\xc7\\xeb\\xd8\\xe7\\xb7\\x04\\x83\\x56\\x93\\x31\\xb6\\xaa\\x90\\x6f\\x0a\\x54\\x6f\\x6a\\xd0\\x80\\x22\\x7d\\x68\\x10\\x3c\\x4e\\x5c\\x7f\\xa8\\x43\\x7d\\x52\\xd4\\xbb\\x3f\\x76\\x57\\xe0\\xe6\\x8f\\x74\\xa4\\xeb\\xe1\\x79\\x11\\x14\\xe9\\xbb\\x4c\\xc5\\x11\\x18\\x46\\xe5\\x55\\xfe\\x08\\x57\\x2b\\x8d\\x84\\x83\\xba\\xc7\\x32\\xb2\\x57\\xba\\xaf\\xf2\\x67\\xdf\\x9e\\x52\\xcf\\xb3\\xdf\\xcd\\x71\\x93\\x7c\\x92\\x8d\\x65\\x66\\x4c\\xe8\\xbb\\x2e\\x7e\\xb3\\xdd\\xac\\x67\\xe2\\xb7\\x7f\\x9d\\x0f\\x75\\x32\\x8c\\xc4\\x49\\x2d\\xd7\\x7b\\x7d\\x24\\x3e\\x04\\xfd\\x6a\\x07\\xe3\\x4e\\x49\\xf9\\x59\\x41\\x95\\x04\\xc6\\x55\\x7d\\x9d\\x2b\\xcf\\xba\\x6e\\x27\\xf5\\xfc\\x94\\x7b\\xdd\\x8f\\xc3\\x5b\\xdb\\x76\\x9a\\x63\\xa1\\x26\\x82\\x99\\xb0\\x5b\\x4f\\xcc\\x9b\\x3f\\x17\\x40\\x65\\x1b\\xda\\xde\\x2e\\xa4\\xff\\x09\\x57\\x68\\x73\\xbe\\x8f\\x0b\\xeb\\x89\\xaf\\xf9\\x55\\x0d\\xe9\\xce\\xc7\\xe5\\x33\\xf3\\x8d\\x71\\xfc\\x77\\x0c\\xee\\xce\\xf2\\xbc\\x3c\\x68\\x71\\xc1\\xea\\xa2\\xef\\x80\\x56\\xae\\xf7\\x0d\\xe0\\xe0\\xc0\\x1b\\x5e\\xed\\xc6\\x49\\x03\\x1f\\xf9\\x51\\x17\\x06\\x66\\x5e\\x7c\\xab\\xcf\\x2c\\x24\\xd9\\x17\\x5c\\x47\\x13\\x60\\xcb\\xaf\\xcd\\x73\\xf9\\x77\\x49\\x81\\x83\\xa2\\x0c\\xbe\\xeb\\x79\\x96\\xfb\\x6d\\xfb\\xcf\\xdd\\x2a\\x1e\\x9b\\x05\\x1e\\x9c\\xcd\\x2f\\x7c\\x85\\x14\\x96\\x3d\\xa1\\x58\\xcf\\x44\\x0b\\x12\\x1a\\x6f\\xfe\\x3a\\xa2\\x26\\x86\\xc8\\x4f\\x98\\x28\\x37\\xb5\\x3f\\xeb\\xa2\\xce\\x56\\x07\\xdf\\xe9\\x22\\x3f\\x26\\x90\\xfa\\xbc\\xe5\\x2b\\xd6\\xcb\\xed\\xa4\\x4e\\xcc\\x28\\x6e\\xeb\\xa2\\xd8\\xe3\\xa4\\xb9\\xff\\x73\\x83\\xe2\\xbc\\x2c\\xd7\\x61\\xe2\\xe0\\x8b\\x7e\\xab\\xdf\\xd7\\x56\\x85\\x8d\\x56\\x86\\xb3\\x10\\x11\\xde\\xd6\\x8a\\x40\\x3d\\xea\\xae\\xbc\\xd0\\x58\\x25\\x94\\x10\\xf9\\xb0\\xc4\\xfe\\x34\\x4b\\xab\\xc4\\x50\\x65\\xd2\\x60\\x27\\xf3\\xbf\\xe9\\xe4\\x14\\x78\\x4b\\x02\\x6c\\x60\\x34\\x06\\xc5\\x8a\\x2b\\xfd\\x30\\xbf\\xa4\\xd7\\xc7\\x7a\\x6e\\x8e\\xf9\\x4b\\x7a\\xb7\\x9c\\x96\\x88\\xcc\\xaf\\xe5\\x38\\x26\\x0f\\x83\\x33\\xfd\\x4b\\x31\\xe3\\x63\\x5d\\x6b\\xca\\xfe\\x9a\\xf5\\x61\\xf1\\xaa\\x60\\xcf\\xbf\\x14\\xc3\\x59\\x51\\xb8\\xce\\x5f\\x4d\\xb0\\x8c\\xd8\\xf3\\x94\\xf8\\x7f\\x6d\\xa6\\x7f\\xdb\\xfc\\xdb\\xe6\\xff\\xc3\\xe6\\x01\\x15\\x0b\\x50\\x75\\x81\\xb1\\x89\\x3d\\xd2\\xfe\\xe4\\xda\\xae\\x67\\x58\\x0a\\xfe\\x0a\\x25\\xe9\\x3f\\x7e\\xfb\\xb7\\x3f\\xfe\\xf1\\xcf\\x7f\\xfc\\x7b\\xb2\\xe4\\x71\\x96\\x2e\\x7b\\x9f\\xfc\\x67\\x57\\x03\\x5d\\xfd\\x7b\\x92\\x17\\xe3\\x92\\xff\\x77\\x3a\\x0e\\x5b\\x3e\\x6c\\xbf\\xff\\x06\\xfe\\x17\\x04\\xc5\\xd0\\x6f\\x7f\\x4c\\x71\\x96\\xd5\\x43\\xf9\\x3b\\xf4\\x2f\\xf8\\x74\\xfd\\x91\\x8e\\xdd\\xb8\\xfc\\xfe\\xaf\\x69\\x9a\\xfe\\xf1\\xcf\\xff\\x09\\x00\\x00\\xff\\xff\\xaf\\xa5\\x1a\\xb1\\x3d\\x07\\x02\\x00\")\n\nfunc cmdInternalPagesAssetsStylesContainersCssBytes() ([]byte, error) {\n\treturn bindataRead(\n\t\t_cmdInternalPagesAssetsStylesContainersCss,\n\t\t\"cmd/internal/pages/assets/styles/containers.css\",\n\t)\n}\n\nfunc cmdInternalPagesAssetsStylesContainersCss() (*asset, error) {\n\tbytes, err := cmdInternalPagesAssetsStylesContainersCssBytes()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tinfo := bindataFileInfo{name: \"cmd/internal/pages/assets/styles/containers.css\", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)}\n\ta := &asset{bytes: bytes, info: info, digest: [32]uint8{0xd3, 0x13, 0xf3, 0xbc, 0xc8, 0x9f, 0x4b, 0x4, 0x81, 0x1c, 0xf9, 0x9c, 0x51, 0x4d, 0xa2, 0x2f, 0x8d, 0x89, 0x5a, 0xfd, 0xd6, 0x57, 0x22, 0xa, 0xa3, 0x25, 0xa3, 0x40, 0x28, 0x64, 0xd2, 0xf}}\n\treturn a, nil\n}\n\n// Asset loads and returns the asset for the given name.\n// It returns an error if the asset could not be found or\n// could not be loaded.\nfunc Asset(name string) ([]byte, error) {\n\tcanonicalName := strings.Replace(name, \"\\\\\", \"/\", -1)\n\tif f, ok := _bindata[canonicalName]; ok {\n\t\ta, err := f()\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"Asset %s can't read by error: %v\", name, err)\n\t\t}\n\t\treturn a.bytes, nil\n\t}\n\treturn nil, fmt.Errorf(\"Asset %s not found\", name)\n}\n\n// AssetString returns the asset contents as a string (instead of a []byte).\nfunc AssetString(name string) (string, error) {\n\tdata, err := Asset(name)\n\treturn string(data), err\n}\n\n// MustAsset is like Asset but panics when Asset would return an error.\n// It simplifies safe initialization of global variables.\nfunc MustAsset(name string) []byte {\n\ta, err := Asset(name)\n\tif err != nil {\n\t\tpanic(\"asset: Asset(\" + name + \"): \" + err.Error())\n\t}\n\n\treturn a\n}\n\n// MustAssetString is like AssetString but panics when Asset would return an\n// error. It simplifies safe initialization of global variables.\nfunc MustAssetString(name string) string {\n\treturn string(MustAsset(name))\n}\n\n// AssetInfo loads and returns the asset info for the given name.\n// It returns an error if the asset could not be found or\n// could not be loaded.\nfunc AssetInfo(name string) (os.FileInfo, error) {\n\tcanonicalName := strings.Replace(name, \"\\\\\", \"/\", -1)\n\tif f, ok := _bindata[canonicalName]; ok {\n\t\ta, err := f()\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"AssetInfo %s can't read by error: %v\", name, err)\n\t\t}\n\t\treturn a.info, nil\n\t}\n\treturn nil, fmt.Errorf(\"AssetInfo %s not found\", name)\n}\n\n// AssetDigest returns the digest of the file with the given name. It returns an\n// error if the asset could not be found or the digest could not be loaded.\nfunc AssetDigest(name string) ([sha256.Size]byte, error) {\n\tcanonicalName := strings.Replace(name, \"\\\\\", \"/\", -1)\n\tif f, ok := _bindata[canonicalName]; ok {\n\t\ta, err := f()\n\t\tif err != nil {\n\t\t\treturn [sha256.Size]byte{}, fmt.Errorf(\"AssetDigest %s can't read by error: %v\", name, err)\n\t\t}\n\t\treturn a.digest, nil\n\t}\n\treturn [sha256.Size]byte{}, fmt.Errorf(\"AssetDigest %s not found\", name)\n}\n\n// Digests returns a map of all known files and their checksums.\nfunc Digests() (map[string][sha256.Size]byte, error) {\n\tmp := make(map[string][sha256.Size]byte, len(_bindata))\n\tfor name := range _bindata {\n\t\ta, err := _bindata[name]()\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tmp[name] = a.digest\n\t}\n\treturn mp, nil\n}\n\n// AssetNames returns the names of the assets.\nfunc AssetNames() []string {\n\tnames := make([]string, 0, len(_bindata))\n\tfor name := range _bindata {\n\t\tnames = append(names, name)\n\t}\n\treturn names\n}\n\n// _bindata is a table, holding each asset generator, mapped to its name.\nvar _bindata = map[string]func() (*asset, error){\n\t\"cmd/internal/pages/assets/js/bootstrap-4.0.0-beta.2.min.js\":      cmdInternalPagesAssetsJsBootstrap400Beta2MinJs,\n\t\"cmd/internal/pages/assets/js/containers.js\":                      cmdInternalPagesAssetsJsContainersJs,\n\t\"cmd/internal/pages/assets/js/jquery-3.5.1.min.js\":                cmdInternalPagesAssetsJsJquery351MinJs,\n\t\"cmd/internal/pages/assets/js/loader.js\":                          cmdInternalPagesAssetsJsLoaderJs,\n\t\"cmd/internal/pages/assets/js/popper.min.js\":                      cmdInternalPagesAssetsJsPopperMinJs,\n\t\"cmd/internal/pages/assets/styles/bootstrap-4.0.0-beta.2.min.css\": cmdInternalPagesAssetsStylesBootstrap400Beta2MinCss,\n\t\"cmd/internal/pages/assets/styles/bootstrap-theme-3.1.1.min.css\":  cmdInternalPagesAssetsStylesBootstrapTheme311MinCss,\n\t\"cmd/internal/pages/assets/styles/containers.css\":                 cmdInternalPagesAssetsStylesContainersCss,\n}\n\n// AssetDebug is true if the assets were built with the debug flag enabled.\nconst AssetDebug = false\n\n// AssetDir returns the file names below a certain\n// directory embedded in the file by go-bindata.\n// For example if you run go-bindata on data/... and data contains the\n// following hierarchy:\n//\n//\tdata/\n//\t  foo.txt\n//\t  img/\n//\t    a.png\n//\t    b.png\n//\n// then AssetDir(\"data\") would return []string{\"foo.txt\", \"img\"},\n// AssetDir(\"data/img\") would return []string{\"a.png\", \"b.png\"},\n// AssetDir(\"foo.txt\") and AssetDir(\"notexist\") would return an error, and\n// AssetDir(\"\") will return []string{\"data\"}.\nfunc AssetDir(name string) ([]string, error) {\n\tnode := _bintree\n\tif len(name) != 0 {\n\t\tcanonicalName := strings.Replace(name, \"\\\\\", \"/\", -1)\n\t\tpathList := strings.Split(canonicalName, \"/\")\n\t\tfor _, p := range pathList {\n\t\t\tnode = node.Children[p]\n\t\t\tif node == nil {\n\t\t\t\treturn nil, fmt.Errorf(\"Asset %s not found\", name)\n\t\t\t}\n\t\t}\n\t}\n\tif node.Func != nil {\n\t\treturn nil, fmt.Errorf(\"Asset %s not found\", name)\n\t}\n\trv := make([]string, 0, len(node.Children))\n\tfor childName := range node.Children {\n\t\trv = append(rv, childName)\n\t}\n\treturn rv, nil\n}\n\ntype bintree struct {\n\tFunc     func() (*asset, error)\n\tChildren map[string]*bintree\n}\n\nvar _bintree = &bintree{nil, map[string]*bintree{\n\t\"cmd\": {nil, map[string]*bintree{\n\t\t\"internal\": {nil, map[string]*bintree{\n\t\t\t\"pages\": {nil, map[string]*bintree{\n\t\t\t\t\"assets\": {nil, map[string]*bintree{\n\t\t\t\t\t\"js\": {nil, map[string]*bintree{\n\t\t\t\t\t\t\"bootstrap-4.0.0-beta.2.min.js\": {cmdInternalPagesAssetsJsBootstrap400Beta2MinJs, map[string]*bintree{}},\n\t\t\t\t\t\t\"containers.js\":                 {cmdInternalPagesAssetsJsContainersJs, map[string]*bintree{}},\n\t\t\t\t\t\t\"jquery-3.5.1.min.js\":           {cmdInternalPagesAssetsJsJquery351MinJs, map[string]*bintree{}},\n\t\t\t\t\t\t\"loader.js\":                     {cmdInternalPagesAssetsJsLoaderJs, map[string]*bintree{}},\n\t\t\t\t\t\t\"popper.min.js\":                 {cmdInternalPagesAssetsJsPopperMinJs, map[string]*bintree{}},\n\t\t\t\t\t}},\n\t\t\t\t\t\"styles\": {nil, map[string]*bintree{\n\t\t\t\t\t\t\"bootstrap-4.0.0-beta.2.min.css\": {cmdInternalPagesAssetsStylesBootstrap400Beta2MinCss, map[string]*bintree{}},\n\t\t\t\t\t\t\"bootstrap-theme-3.1.1.min.css\":  {cmdInternalPagesAssetsStylesBootstrapTheme311MinCss, map[string]*bintree{}},\n\t\t\t\t\t\t\"containers.css\":                 {cmdInternalPagesAssetsStylesContainersCss, map[string]*bintree{}},\n\t\t\t\t\t}},\n\t\t\t\t}},\n\t\t\t}},\n\t\t}},\n\t}},\n}}\n\n// RestoreAsset restores an asset under the given directory.\nfunc RestoreAsset(dir, name string) error {\n\tdata, err := Asset(name)\n\tif err != nil {\n\t\treturn err\n\t}\n\tinfo, err := AssetInfo(name)\n\tif err != nil {\n\t\treturn err\n\t}\n\terr = os.MkdirAll(_filePath(dir, filepath.Dir(name)), os.FileMode(0755))\n\tif err != nil {\n\t\treturn err\n\t}\n\terr = os.WriteFile(_filePath(dir, name), data, info.Mode())\n\tif err != nil {\n\t\treturn err\n\t}\n\treturn os.Chtimes(_filePath(dir, name), info.ModTime(), info.ModTime())\n}\n\n// RestoreAssets restores an asset under the given directory recursively.\nfunc RestoreAssets(dir, name string) error {\n\tchildren, err := AssetDir(name)\n\t// File\n\tif err != nil {\n\t\treturn RestoreAsset(dir, name)\n\t}\n\t// Dir\n\tfor _, child := range children {\n\t\terr = RestoreAssets(dir, filepath.Join(name, child))\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc _filePath(dir, name string) string {\n\tcanonicalName := strings.Replace(name, \"\\\\\", \"/\", -1)\n\treturn filepath.Join(append([]string{dir}, strings.Split(canonicalName, \"/\")...)...)\n}\n"
  },
  {
    "path": "cmd/internal/pages/static/static.go",
    "content": "// Copyright 2014 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n// Handler for /static content.\n\npackage static\n\nimport (\n\t\"fmt\"\n\t\"mime\"\n\t\"net/http\"\n\t\"net/url\"\n\t\"path\"\n\n\t\"k8s.io/klog/v2\"\n)\n\nconst StaticResource = \"/static/\"\n\nvar popper, _ = Asset(\"cmd/internal/pages/assets/js/popper.min.js\")\nvar bootstrapJS, _ = Asset(\"cmd/internal/pages/assets/js/bootstrap-4.0.0-beta.2.min.js\")\nvar containersJS, _ = Asset(\"cmd/internal/pages/assets/js/containers.js\")\nvar loaderJS, _ = Asset(\"cmd/internal/pages/assets/js/loader.js\")\nvar jqueryJS, _ = Asset(\"cmd/internal/pages/assets/js/jquery-3.5.1.min.js\")\n\nvar bootstrapCSS, _ = Asset(\"cmd/internal/pages/assets/styles/bootstrap-4.0.0-beta.2.min.css\")\nvar bootstrapThemeCSS, _ = Asset(\"cmd/internal/pages/assets/styles/bootstrap-theme-3.1.1.min.css\")\nvar containersCSS, _ = Asset(\"cmd/internal/pages/assets/styles/containers.css\")\n\nvar staticFiles = map[string][]byte{\n\t\"popper.min.js\":                  popper,\n\t\"bootstrap-4.0.0-beta.2.min.css\": bootstrapCSS,\n\t\"bootstrap-4.0.0-beta.2.min.js\":  bootstrapJS,\n\t\"bootstrap-theme-3.1.1.min.css\":  bootstrapThemeCSS,\n\t\"containers.css\":                 containersCSS,\n\t\"containers.js\":                  containersJS,\n\t\"loader.js\":                      loaderJS,\n\t\"jquery-3.5.1.min.js\":            jqueryJS,\n}\n\nfunc HandleRequest(w http.ResponseWriter, u *url.URL) {\n\tif len(u.Path) <= len(StaticResource) {\n\t\thttp.Error(w, fmt.Sprintf(\"unknown static resource %q\", u.Path), http.StatusNotFound)\n\t\treturn\n\t}\n\n\t// Get the static content if it exists.\n\tresource := u.Path[len(StaticResource):]\n\tcontent, ok := staticFiles[resource]\n\tif !ok {\n\t\thttp.Error(w, fmt.Sprintf(\"unknown static resource %q\", u.Path), http.StatusNotFound)\n\t\treturn\n\t}\n\n\t// Set Content-Type if we were able to detect it.\n\tcontentType := mime.TypeByExtension(path.Ext(resource))\n\tif contentType != \"\" {\n\t\tw.Header().Set(\"Content-Type\", contentType)\n\t}\n\n\tif _, err := w.Write(content); err != nil {\n\t\tklog.Errorf(\"Failed to write response: %v\", err)\n\t}\n}\n"
  },
  {
    "path": "cmd/internal/pages/templates.go",
    "content": "// Copyright 2023 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n// generated by build/assets.sh; DO NOT EDIT\n\n// Code generated by go-bindata. DO NOT EDIT.\n// sources:\n// cmd/internal/pages/assets/html/containers.html (9.64kB)\n\npackage pages\n\nimport (\n\t\"bytes\"\n\t\"compress/gzip\"\n\t\"crypto/sha256\"\n\t\"fmt\"\n\t\"io\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"strings\"\n\t\"time\"\n)\n\nfunc bindataRead(data []byte, name string) ([]byte, error) {\n\tgz, err := gzip.NewReader(bytes.NewBuffer(data))\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"read %q: %w\", name, err)\n\t}\n\n\tvar buf bytes.Buffer\n\t_, err = io.Copy(&buf, gz)\n\tclErr := gz.Close()\n\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"read %q: %w\", name, err)\n\t}\n\tif clErr != nil {\n\t\treturn nil, err\n\t}\n\n\treturn buf.Bytes(), nil\n}\n\ntype asset struct {\n\tbytes  []byte\n\tinfo   os.FileInfo\n\tdigest [sha256.Size]byte\n}\n\ntype bindataFileInfo struct {\n\tname    string\n\tsize    int64\n\tmode    os.FileMode\n\tmodTime time.Time\n}\n\nfunc (fi bindataFileInfo) Name() string {\n\treturn fi.name\n}\nfunc (fi bindataFileInfo) Size() int64 {\n\treturn fi.size\n}\nfunc (fi bindataFileInfo) Mode() os.FileMode {\n\treturn fi.mode\n}\nfunc (fi bindataFileInfo) ModTime() time.Time {\n\treturn fi.modTime\n}\nfunc (fi bindataFileInfo) IsDir() bool {\n\treturn false\n}\nfunc (fi bindataFileInfo) Sys() interface{} {\n\treturn nil\n}\n\nvar _cmdInternalPagesAssetsHtmlContainersHtml = []byte(\"\\x1f\\x8b\\x08\\x00\\x00\\x00\\x00\\x00\\x00\\xff\\xcc\\x5a\\x5f\\x73\\xe2\\x38\\x12\\x7f\\x86\\x4f\\xd1\\xeb\\xba\\x87\\xd9\\xaa\\xb1\\x49\\x26\\xb9\\x87\\x9b\\x23\\x54\\xb1\\xcc\\xcc\\x2d\\xb7\\x99\\x24\\x15\\x92\\xdd\\xda\\x47\\xd9\\x6e\\x6c\\x4d\\x84\\xa5\\x95\\x64\\x08\\x97\\xca\\x77\\xbf\\x92\\x64\\x83\\xff\\x01\\xf9\\x57\\x33\\xcb\\x0b\\x20\\xa9\\xbb\\x7f\\xfd\\x53\\xb7\\xd4\\xb2\\x3c\\xfc\\xc9\\xf7\\xfb\\x00\\x13\\x2e\\xd6\\x92\\x26\\xa9\\x86\\x0f\\x47\\xc7\\xa7\\xf0\\x1f\\xce\\x13\\x86\\x30\\xcd\\xa2\\x00\\xc6\\x8c\\xc1\\xb5\\xe9\\x52\\x70\\x8d\\x0a\\xe5\\x12\\xe3\\xa0\\xdf\\x07\\x38\\xa7\\x11\\x66\\x0a\\x63\\xc8\\xb3\\x18\\x25\\xe8\\x14\\x61\\x2c\\x48\\x94\\x62\\xd9\\xf3\\x1e\\x7e\\x47\\xa9\\x28\\xcf\\xe0\\x43\\x70\\x04\\xef\\xcc\\x00\\xaf\\xe8\\xf2\\x7e\\xfe\\x77\\x1f\\x60\\xcd\\x73\\x58\\x90\\x35\\x64\\x5c\\x43\\xae\\x10\\x74\\x4a\\x15\\xcc\\x29\\x43\\xc0\\xfb\\x08\\x85\\x06\\x9a\\x41\\xc4\\x17\\x82\\x51\\x92\\x45\\x08\\x2b\\xaa\\x53\\x6b\\xa6\\x50\\x12\\xf4\\x01\\xfe\\x2c\\x54\\xf0\\x50\\x13\\x9a\\x01\\x81\\x88\\x8b\\x35\\xf0\\x79\\x75\\x1c\\x10\\x6d\\xf0\\x9a\\x4f\\xaa\\xb5\\xf8\\x38\\x18\\xac\\x56\\xab\\x80\\x58\\xac\\x01\\x97\\xc9\\x80\\xb9\\x71\\x6a\\x70\\x3e\\x9d\\x7c\\xbe\\x98\\x7d\\xf6\\x3f\\x04\\x47\\x46\\xe2\\x36\\x63\\xa8\\x14\\x48\\xfc\\x2b\\xa7\\x12\\x63\\x08\\xd7\\x40\\x84\\x60\\x34\\x22\\x21\\x43\\x60\\x64\\x05\\x5c\\x02\\x49\\x24\\x62\\x0c\\x9a\\x1b\\xb4\\x2b\\x49\\x35\\xcd\\x92\\xf7\\xa0\\xf8\\x5c\\xaf\\x88\\xc4\\x3e\\x40\\x4c\\x95\\x96\\x34\\xcc\\x75\\x8d\\xaa\\x12\\x1b\\x55\\xb5\\x01\\x3c\\x03\\x92\\x81\\x37\\x9e\\xc1\\x74\\xe6\\xc1\\x2f\\xe3\\xd9\\x74\\xf6\\xbe\\x0f\\xf0\\xc7\\xf4\\xe6\\xd7\\xcb\\xdb\\x1b\\xf8\\x63\\x7c\\x7d\\x3d\\xbe\\xb8\\x99\\x7e\\x9e\\xc1\\xe5\\x35\\x4c\\x2e\\x2f\\x3e\\x4d\\x6f\\xa6\\x97\\x17\\x33\\xb8\\xfc\\x02\\xe3\\x8b\\x3f\\xe1\\xb7\\xe9\\xc5\\xa7\\xf7\\x80\\x54\\xa7\\x28\\x01\\xef\\x85\\x34\\xf8\\xb9\\x04\\x6a\\x48\\x34\\xf3\\x06\\x30\\x43\\xac\\x01\\x98\\x73\\x07\\x48\\x09\\x8c\\xe8\\x9c\\x46\\xc0\\x48\\x96\\xe4\\x24\\x41\\x48\\xf8\\x12\\x65\\x46\\xb3\\x04\\x04\\xca\\x05\\x55\\x66\\x2a\\x15\\x90\\x2c\\xee\\x03\\x30\\xba\\xa0\\x9a\\x68\\xdb\\xd2\\x72\\x2a\\xe8\\xfb\\xfe\\xa8\\xdf\\x1f\\xa6\\x7a\\xc1\\x46\\x7d\\x80\\x61\\x8a\\x24\\x1e\\xd9\\x29\\x18\\x6a\\xaa\\x19\\x8e\\xa2\\x71\\xbc\\xa4\\x8a\\x4b\\xf0\\xe1\\xe1\\x21\\xf8\\x44\\x95\\x60\\x64\\x7d\\x41\\x16\\xf8\\xf8\\x38\\x1c\\xb8\\x21\\x6e\\xb8\\x8a\\x24\\x15\\x1a\\x94\\x8c\\xce\\xbc\\x87\\x87\\xe0\\x9a\\x73\\xfd\\xf8\\xa8\\x8c\\xe5\\x68\\x20\\xb8\\x10\\x28\\x83\\x05\\xcd\\x82\\x6f\\xca\\x1b\\x0d\\x07\\x6e\\x70\\x21\\xf9\\x93\\xef\\xc3\\x39\\xd1\\xa8\\xb4\\x8d\\x21\\xca\\x30\\x36\\xd8\\x61\\x41\\x33\\x3a\\xa7\\x18\\xc3\\x64\\x36\\x03\\x83\\xd3\\x8e\\x66\\x34\\xbb\\x03\\x89\\xec\\xcc\\x53\\x7a\\xcd\\x50\\xa5\\x88\\xda\\x83\\x54\\xe2\\xbc\\x6d\\x37\\xe4\\x5c\\x2b\\x2d\\x89\\xf0\\x4f\\x83\\xa3\\xe0\\xc8\\x0f\\x51\\x93\\xe0\\x83\\xc5\\x11\\x29\\xe5\\x8d\\xfa\\x5b\\x00\\x97\\xc2\\x50\\x44\\x98\\x61\\x67\\x81\\xaf\\x35\\x67\\x95\\xf8\\x27\\xc1\\x71\\x70\\xdc\\xb2\\xf6\\x1c\\x8d\\x11\\xcf\\x4c\\xb6\\xa0\\x54\\x2d\\xc0\\x7b\\x19\\xfb\\x2f\\x59\\x92\\x99\\x9b\\x90\\x8d\\x27\\xfb\\x26\\xe8\\xdb\\x5f\\x39\\xca\\xb5\\x7f\\x12\\xfc\\xb3\\x00\\xdc\\x31\\x4d\\xfb\\xe4\\xf7\\x10\\xdd\\xd6\\xb4\\xd5\\xa5\\xd7\\x02\\xcf\\x3c\\x8d\\xf7\\x7a\\xf0\\x8d\\x2c\\x89\\x6b\\xf5\\xba\\x4d\\x30\\x4e\\x62\\x94\\x7b\\x80\\x3d\\x47\\x59\\x85\\xd7\\xa6\\xc2\\xe1\\xa0\\xcc\\x81\\x61\\xc8\\xe3\\x75\\x61\\x23\\xa6\\x4b\\x88\\x18\\x51\\xea\\xcc\\xdb\\xc8\\xba\\x50\\xf1\\x55\\xca\\x57\\x11\\x51\\xe8\\xc1\\xc6\\x3d\\xd2\\x9c\\x4e\\x6f\\x2b\\xcc\\x7c\\xb5\\xf0\\x8f\\x3f\\x78\\x40\\xe3\\x33\\x8f\\xf1\\x84\\x7b\\x1b\\xb1\\x01\\xd9\\xfc\\xac\\xd9\\x2b\\x45\\x46\\xfd\\x5e\\xb5\\x43\\x90\\x04\\x7d\\x03\\x16\\xa5\\xe9\\x32\\xd9\\x7b\\x3c\\x6a\\x27\\x69\\x7a\\x6c\\xe4\\x06\\x31\\x5d\\x9a\\x6f\\xce\\x4a\\xf1\\x50\\x22\\x89\\x23\\x99\\x2f\\x42\\x27\\xfd\\xf0\\x20\\x49\\x96\\x20\\xfc\\x43\\x10\\x89\\x99\\x9e\\x6c\\xdc\\xfc\\x78\\x06\\xc1\\x55\\xbd\\x4d\\x3d\\x3e\\x5a\\x83\\x8c\\x8e\\x2a\\xce\\x36\\x25\\x83\\x73\\x9a\\xdd\\x3d\\x3e\\x7a\\xa3\\x8e\\xae\\x1b\\xbc\\xd7\\x06\\x1d\\x19\\x0d\\x07\\x8c\\x16\\x00\\x30\\x8b\\x8d\\xe2\\xe1\\x80\\xb3\\x2d\\x29\\x16\\xb8\\xfb\\xf3\\xf0\\x40\\xe7\\x10\\x4c\\x95\\x23\\xf5\\x00\\x57\\x50\\x7c\\x86\\xe9\\xe9\\x16\\x64\\x10\\x0c\\x62\\x1e\\xdd\\x19\\xc6\\x3e\\xd9\\x6f\\xd8\\xfa\\xe4\\xc0\\xa4\\xa7\\x9d\\xa6\\x0f\\x59\\x69\\xdb\\x11\\x3c\\x5e\\x90\\xcc\\x1b\\x5d\\xd9\\xef\\xa7\\xda\\x29\\x49\\xa8\\x3a\\x3c\\xcb\\xc3\\xa8\\xca\\xfc\\xeb\\x62\\xe4\\x64\\x54\\xd3\\x37\\x1c\\xa4\\x27\\xd5\\x00\\xa9\\x08\\x33\\xaa\\xb4\\x9f\\x48\\x9e\\x8b\\x46\\x84\\xa8\\x8a\\x02\\x1b\\x1e\\x4d\\x84\\xbd\\x5a\\x12\\xd4\\xc6\\x97\\x41\\xd1\\x36\\xe2\\x53\\x8d\\x0b\\x1b\\x2c\\xb5\\xf1\\xdb\\x48\\x69\\x04\\x49\\x75\\x76\\x76\\x52\\xe8\\x18\\x74\\x73\\x3d\\xd3\\x44\\xe7\\x6f\\x41\\xe0\\x27\\x49\\x97\\x28\\xc1\\xe9\\x6b\\x12\\x98\\xb3\\x83\\xfc\\xb9\\x10\\x54\\x56\\xdc\\xf2\\xd7\\xc0\\xe7\\x52\\xcb\\xa9\\x81\\x0e\\x8a\\x86\\x4a\\x90\\xac\\xb4\\x62\\xd4\\xf8\\x8c\\x84\\xc8\\x2c\\x77\\x55\\xdd\\xc1\\x6f\\xb8\\x36\\xd4\\x99\\xe1\\x23\\x68\\x76\\xfe\\x4e\\x58\\x6e\\x57\\x88\\x66\\xfe\\xd5\\x59\\x73\\xce\\x6e\\xb1\\xf5\\x5e\\x06\\x6d\\xa6\\xb9\\x24\\x09\\x0e\\x43\\x39\\x2a\\x00\\x19\\x55\\xbb\\xc8\\xea\\x6d\\xb9\\xb2\\xe6\\x5b\\x5c\\xed\\x46\\xf5\\x5c\\xbe\\x2a\\xfa\\xdb\\x7c\\x55\\x3b\\xeb\\x7c\\xf5\\x36\\x74\\xf5\\x86\\x83\\x9c\\x59\\x6f\\x4a\\x26\\x8b\\x86\\x5d\\xd1\\xda\\x95\\xe3\\xce\\xab\\xe9\\x82\\x24\\x78\\x38\\x42\\x2b\\x8b\\xce\\xce\\x50\\x05\\xa8\\x2e\\x4d\\x27\\x23\\xa7\\xda\\x05\\x6b\\xa5\\xa7\\x8a\\xcb\\x69\\x33\\xfb\\x92\\x8b\\x13\\x9f\\x5a\\x19\\xb3\\x3f\\xd6\\x46\\x99\\x29\\x0c\\xe5\\xf6\\xff\\x21\\xdf\\xae\\x51\\xf1\\x5c\\x46\\xa8\\xc6\\x4b\\x42\\x99\\x29\\xc9\\xdf\\x20\\x07\\xa7\\x8a\\x33\\x5b\\xd6\\x36\\xf2\\xcf\\x99\\x9c\\x88\\xbc\\x6a\\x6c\\x67\\xa0\\x55\\x98\\xd8\\x19\\x3f\\x40\\x22\\x4d\\x97\\xe6\\x00\\x50\\x58\\xf4\\x6d\\xdd\\x0b\\x82\\x64\\xc8\\xdc\\x6f\\x6f\\x34\\xb9\\xba\\x75\\xd3\\xbf\\xd5\\x58\\x2c\\xde\\x02\\x23\\x03\\x27\\x38\\x37\\x85\\xf8\\xc6\\xf1\\xfd\\x26\\xf7\\xe5\\x51\\x4a\\xa4\\x99\\xc7\\x32\\x46\\x85\\xa4\\x99\\x76\\x8d\\x6d\\x63\\x50\\x53\\x93\\x67\\x74\\xa3\\x46\\x55\\xd5\\xb4\\x91\\x57\\x27\\xb1\\xc3\\x97\\xaf\\xe4\\xfe\\x8d\\xdc\\xf9\\x4a\\xee\\xc1\\xaa\\x6a\\x78\\x34\\xe1\\x75\\x87\\xb6\\x16\\x77\\xfb\\x14\\xf1\\x57\\xb9\\xa4\\xee\\x5e\\xef\\xce\\x98\\x31\\xbe\\x32\\x47\\x16\\xde\\x9e\\x24\\x63\\xa1\\x61\\x10\\x82\\xaf\\x24\\x4a\\x69\\x86\\xd3\\x6c\\xce\\x83\\x8b\\x7c\\x61\\xe5\\xca\\x35\\xa6\\x8d\\xbe\\x5c\\x6a\\x36\\xff\\x9d\\x13\\x5f\\x71\\xc1\\xe5\\xfa\\xfb\\x06\\xbc\\xb3\\xb9\\x27\\xe6\\xdd\\x80\\xc0\\x3d\\x89\\xb0\\x6a\\x5e\\x4f\\x6f\\x45\\x59\\x33\\x03\\xe8\\xff\\x70\\x8f\\xe1\\xdd\\x41\\x53\\xc8\\xdf\\x66\\x54\\xef\\x91\\x7f\\x49\\x54\\x15\\x7a\\xde\\x28\\x51\\xba\\x92\\xa4\\xed\\xf4\\xc1\\x1c\\xd9\\xe9\\x6e\\x21\\xf9\\x0a\\x47\\x67\\x2b\\x22\\xde\\x6a\\x91\\x5b\\x11\\xd1\\xb9\\x2c\\xb4\\x3d\\xae\\x58\\x7d\\x81\\xd7\\x15\\xe9\\x03\\x9e\\x37\\x53\\xaf\\xf0\\xee\\x29\\x67\\x84\\xc3\\x9b\\xd9\\xad\\x32\\xa5\\xd1\\xee\\x4a\\xdc\\x66\\x5e\\x91\\x7f\\x42\\xd2\\x05\\x91\\xeb\\x3d\\x65\\x80\\x19\\x65\\x2c\\xd0\\x2c\\x69\\x17\\x02\\xf5\\x61\\x45\\x32\\x5f\\x2e\\x51\\x2e\\x29\\xae\\xf6\\x97\\x07\\xd5\\x0a\\x21\\x37\\x88\\xfd\\x84\\xe4\\x09\\x7a\\x75\\x95\\xe6\\xd4\\xbc\\x29\\x19\\x7e\\x88\\x37\\x57\\x92\\x47\\xa8\\xd4\\xa1\\x6a\\xa7\\xea\\x8e\\x28\\x45\\x7c\\xcd\\xc5\\x93\\x1c\\xda\\x51\\x67\\x7c\\x47\\x37\\x6d\\xc9\\xf1\\x14\\x07\\x3b\\xbc\\x69\\x18\\x38\\x1d\\xdd\\x70\\x4d\\x18\\x94\\x71\\x78\\x6a\\x23\\xb3\\xc2\\x4f\\x24\\x72\\x5f\\x9b\\x21\\xbe\\x9b\\xf8\\x28\\x25\\x52\\x6f\\x49\\x81\\xf2\\xa9\\x94\\x51\\x35\\xb9\\xba\\x85\\x73\\x4e\\x62\\x18\\x2f\\x51\\xee\\xd1\\xc7\\x38\\x89\\xeb\\x8a\\x36\\x0f\\xab\\xaa\\xc8\\x2c\\x26\\x10\\xf6\\xa8\\x2e\\x77\\x2a\\x13\\x28\\x7d\\xb3\\xff\\x77\\xe2\\xeb\\x56\\xf9\\x8b\\x44\\x72\\x17\\xf3\\x55\\xb6\\x4b\\xa7\\x53\\x15\\x96\\xc3\\x76\\x2a\\x6d\\x87\\xc6\\xc1\\xdd\\xf9\\x3b\\x86\\x49\\xb9\\x51\\x7f\\xa7\\x48\\x59\\x58\\x73\\x87\\xa7\\x21\\x94\\x83\\x46\\x4b\\x05\\x80\\xe4\\x2b\\xe8\\x3e\\xf0\\xec\\x9d\\xc2\\xc6\\xb0\\xf6\\x72\\xfc\\x2f\\x7b\\xb6\\xac\\xb9\\x2a\\x79\\x22\\xd1\\x3e\\x5b\\x85\\xd6\\xa7\\x6b\\xa0\\x1f\\x12\\x09\\xd5\\x3f\\x7e\\x6c\\x0e\\xaa\\xd2\\x2b\\xd7\\x11\\xd7\\x91\\x72\\xed\\x3b\\x2a\\x3a\\x35\\x43\\x7d\\xaf\\x52\\xd2\\xe7\\x19\\x5b\\x7b\\xa3\\x5f\\xb9\\x86\\x72\\xc2\\xdc\\x21\\xb9\\x43\\xb2\\xcd\\xe6\\x73\\xe0\\xd2\\x6c\\xce\\x1b\\x60\\x23\\xce\\xe2\\x97\\xa0\\x9d\\x70\\x16\\x3f\\x15\\x6e\\xaf\\xd7\\x89\\xbb\\xbb\\xb1\\x3d\\x73\\x27\\x5e\\x35\\xba\\x34\\xde\\x37\\x57\\x9f\\x67\\x26\\xe5\\x05\\xea\\x15\\x97\\x77\\xcf\\xcc\\xca\\xde\\xeb\\xd3\\xb1\\x30\\x5c\\x6c\\xf6\\xcf\\x49\\xc4\\x5e\\xb3\\x37\\x96\\x5c\\x98\\xe0\\x6f\\x27\\x48\\x98\\x6b\\xcd\\x37\\xf3\\x15\\xea\\x0c\\x42\\x9d\\xf9\\x31\\xce\\x49\\xce\\x34\\x94\\x72\\xbe\\xe6\\x49\\xc2\\xd0\\x2b\\x1e\\x9d\\x3b\\x21\\xc7\\x73\\xe6\\x50\\xfa\\x0a\\x19\\x46\\xf6\\x08\\xb0\\x31\\x06\\x31\\xd1\\xa4\\x10\\xad\\x60\\x00\\x22\\x29\\xf1\\x53\\xa2\\x04\\x17\\xb9\\x38\\xf3\\xb4\\xcc\\xb1\\x68\\xc4\\x7b\\x41\\xb2\\x18\\xe3\\x33\\x6f\\x4e\\x98\\xc2\\x8e\\x10\\x73\\xe1\\xd5\\x6d\\xb8\\x9c\\xeb\\xee\\xf8\\xaa\\x05\\x66\\x44\\x24\\x56\\xc6\\xf6\\xca\\x48\\x70\\x9e\\xb5\\x58\\xca\\x59\\xb7\\x49\\xaf\\x49\\xb0\\xbf\\xc0\\x2c\\xf7\\x40\\x72\\xe3\\xb1\\xfb\\x6d\\x1d\\xb3\\xd5\\x25\\xc3\\x38\\x5c\\xef\\x65\\xac\\x1d\\xf3\\xc5\\xe3\\xa1\\x3d\\x61\\xfb\\x9c\\x05\\x39\\x95\\x3c\\x4f\\x52\\x91\\xeb\\xf6\\x2a\\xb8\\x59\\x96\\x4b\\x78\\xe1\\x5a\\xa3\\x6a\\x6f\\xdf\\x2f\\x30\\xfb\\x59\\x4a\\x6e\\x1f\\x1f\\xb7\\xb6\\x80\\xd2\\x16\\xda\\x11\\xbb\\x8d\\x35\\x9c\\x6f\\x64\\xe8\\x17\\xf5\\xc3\\xb6\\xcc\\x2f\\x94\\xa1\\x5a\\x2b\\x8d\\x8b\\xa7\\x57\\x90\\xf3\\x8d\\x8c\\xdb\\xfb\\x3a\\x8b\\xc8\\xdd\\x9a\\x76\\x2c\\x53\\x93\\x5c\\x69\\xbe\\xf8\\x8a\\x5a\\xd2\\xe8\\xb9\\x7c\\x1c\\x58\\xac\\x7a\\xfb\\x18\\x18\\xbb\\xdb\\x73\\x13\\xc7\\x50\\x58\\x6f\\xae\\x58\\xfb\\x62\\xa5\\x51\\x4b\\x59\\x27\\xfc\\x85\\xd3\\x73\\x30\\x1e\\x7a\\xcd\\xc3\\x66\\xc7\\x2d\\xc8\\x0f\\x0b\\x8d\\x8e\\xbb\\x93\\x43\\xd1\\xf1\\xb4\\xa2\\x4a\\x80\\xa9\\x9b\\x6d\\x59\\xf3\\xb1\\xb9\\x5e\\xd0\\x4c\\xe4\\xba\\x56\\xea\\x56\\x6f\\x48\\xfc\\xd8\\x5d\\xf8\\xf9\\x11\\xcf\\x33\\xed\\x75\\xee\\xdf\\x9b\\xad\\xbb\\x4b\\xce\\xaa\\xdf\\x21\\xb7\\x24\\x2c\\xc7\\xb3\\xe3\\xa3\\x06\\xe4\\xdd\\x0b\\x4d\\x27\\xc2\\x5a\\x35\\xd8\\xd0\\xd4\\xbd\\x00\\xbe\\x90\\x43\\x57\\x8c\\x1c\\xa4\\xb1\\x28\\x23\\xfe\\x9e\\x4c\\xd6\\x4a\\x2d\\x67\\x45\\x72\\xc6\\x2a\\x66\\x42\\xc6\\xa3\\x3b\\xaf\\xab\\x7e\\xde\\xe7\\xdc\\xcb\\x27\\x61\\xc7\\x42\\xdd\\xd1\\x59\\xed\\xaa\\x74\\xec\\xbf\\xa3\\x2f\\x85\\x13\\xfb\\x2e\\x53\\x60\\x11\\xaa\\x40\\xa1\\xbe\\xcc\\xcc\\x39\\x72\\x42\\x18\\x0b\\x49\\x74\\xf7\\x4e\\x69\\x22\\xf5\\x15\\x49\\xf0\\xdd\\xc3\\x43\\xb0\\xb9\\x4f\\x75\\xf7\\xdc\\xef\\xc1\\xb4\\xd5\\x4e\\xe3\\xb6\\xa9\\x75\\xf8\\xb2\\xad\\xee\\x02\\xd9\\xfe\\x2c\\x6f\\x93\\x7f\\xb6\\x2f\\x3a\\x99\\x4f\\x2c\\xc9\\xca\\xdd\\x96\\x18\\x3b\\xf5\\x8b\\x99\\x62\\x50\\xfd\\x85\\x01\\xf7\\x9e\\xc0\\x70\\xe0\\xde\\xa2\\xf9\\x7f\\x00\\x00\\x00\\xff\\xff\\x19\\x81\\xf2\\xde\\xa8\\x25\\x00\\x00\")\n\nfunc cmdInternalPagesAssetsHtmlContainersHtmlBytes() ([]byte, error) {\n\treturn bindataRead(\n\t\t_cmdInternalPagesAssetsHtmlContainersHtml,\n\t\t\"cmd/internal/pages/assets/html/containers.html\",\n\t)\n}\n\nfunc cmdInternalPagesAssetsHtmlContainersHtml() (*asset, error) {\n\tbytes, err := cmdInternalPagesAssetsHtmlContainersHtmlBytes()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tinfo := bindataFileInfo{name: \"cmd/internal/pages/assets/html/containers.html\", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)}\n\ta := &asset{bytes: bytes, info: info, digest: [32]uint8{0x3b, 0xb9, 0x8c, 0xe6, 0xbf, 0xf1, 0x9d, 0x7, 0xe7, 0xbc, 0xd5, 0xf1, 0xb1, 0xc2, 0x47, 0xe5, 0x2e, 0x76, 0xdf, 0x59, 0x12, 0x64, 0x50, 0x9d, 0x91, 0xb3, 0xaf, 0xb3, 0x1, 0x60, 0xd, 0x6c}}\n\treturn a, nil\n}\n\n// Asset loads and returns the asset for the given name.\n// It returns an error if the asset could not be found or\n// could not be loaded.\nfunc Asset(name string) ([]byte, error) {\n\tcanonicalName := strings.Replace(name, \"\\\\\", \"/\", -1)\n\tif f, ok := _bindata[canonicalName]; ok {\n\t\ta, err := f()\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"Asset %s can't read by error: %v\", name, err)\n\t\t}\n\t\treturn a.bytes, nil\n\t}\n\treturn nil, fmt.Errorf(\"Asset %s not found\", name)\n}\n\n// AssetString returns the asset contents as a string (instead of a []byte).\nfunc AssetString(name string) (string, error) {\n\tdata, err := Asset(name)\n\treturn string(data), err\n}\n\n// MustAsset is like Asset but panics when Asset would return an error.\n// It simplifies safe initialization of global variables.\nfunc MustAsset(name string) []byte {\n\ta, err := Asset(name)\n\tif err != nil {\n\t\tpanic(\"asset: Asset(\" + name + \"): \" + err.Error())\n\t}\n\n\treturn a\n}\n\n// MustAssetString is like AssetString but panics when Asset would return an\n// error. It simplifies safe initialization of global variables.\nfunc MustAssetString(name string) string {\n\treturn string(MustAsset(name))\n}\n\n// AssetInfo loads and returns the asset info for the given name.\n// It returns an error if the asset could not be found or\n// could not be loaded.\nfunc AssetInfo(name string) (os.FileInfo, error) {\n\tcanonicalName := strings.Replace(name, \"\\\\\", \"/\", -1)\n\tif f, ok := _bindata[canonicalName]; ok {\n\t\ta, err := f()\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"AssetInfo %s can't read by error: %v\", name, err)\n\t\t}\n\t\treturn a.info, nil\n\t}\n\treturn nil, fmt.Errorf(\"AssetInfo %s not found\", name)\n}\n\n// AssetDigest returns the digest of the file with the given name. It returns an\n// error if the asset could not be found or the digest could not be loaded.\nfunc AssetDigest(name string) ([sha256.Size]byte, error) {\n\tcanonicalName := strings.Replace(name, \"\\\\\", \"/\", -1)\n\tif f, ok := _bindata[canonicalName]; ok {\n\t\ta, err := f()\n\t\tif err != nil {\n\t\t\treturn [sha256.Size]byte{}, fmt.Errorf(\"AssetDigest %s can't read by error: %v\", name, err)\n\t\t}\n\t\treturn a.digest, nil\n\t}\n\treturn [sha256.Size]byte{}, fmt.Errorf(\"AssetDigest %s not found\", name)\n}\n\n// Digests returns a map of all known files and their checksums.\nfunc Digests() (map[string][sha256.Size]byte, error) {\n\tmp := make(map[string][sha256.Size]byte, len(_bindata))\n\tfor name := range _bindata {\n\t\ta, err := _bindata[name]()\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tmp[name] = a.digest\n\t}\n\treturn mp, nil\n}\n\n// AssetNames returns the names of the assets.\nfunc AssetNames() []string {\n\tnames := make([]string, 0, len(_bindata))\n\tfor name := range _bindata {\n\t\tnames = append(names, name)\n\t}\n\treturn names\n}\n\n// _bindata is a table, holding each asset generator, mapped to its name.\nvar _bindata = map[string]func() (*asset, error){\n\t\"cmd/internal/pages/assets/html/containers.html\": cmdInternalPagesAssetsHtmlContainersHtml,\n}\n\n// AssetDebug is true if the assets were built with the debug flag enabled.\nconst AssetDebug = false\n\n// AssetDir returns the file names below a certain\n// directory embedded in the file by go-bindata.\n// For example if you run go-bindata on data/... and data contains the\n// following hierarchy:\n//\n//\tdata/\n//\t  foo.txt\n//\t  img/\n//\t    a.png\n//\t    b.png\n//\n// then AssetDir(\"data\") would return []string{\"foo.txt\", \"img\"},\n// AssetDir(\"data/img\") would return []string{\"a.png\", \"b.png\"},\n// AssetDir(\"foo.txt\") and AssetDir(\"notexist\") would return an error, and\n// AssetDir(\"\") will return []string{\"data\"}.\nfunc AssetDir(name string) ([]string, error) {\n\tnode := _bintree\n\tif len(name) != 0 {\n\t\tcanonicalName := strings.Replace(name, \"\\\\\", \"/\", -1)\n\t\tpathList := strings.Split(canonicalName, \"/\")\n\t\tfor _, p := range pathList {\n\t\t\tnode = node.Children[p]\n\t\t\tif node == nil {\n\t\t\t\treturn nil, fmt.Errorf(\"Asset %s not found\", name)\n\t\t\t}\n\t\t}\n\t}\n\tif node.Func != nil {\n\t\treturn nil, fmt.Errorf(\"Asset %s not found\", name)\n\t}\n\trv := make([]string, 0, len(node.Children))\n\tfor childName := range node.Children {\n\t\trv = append(rv, childName)\n\t}\n\treturn rv, nil\n}\n\ntype bintree struct {\n\tFunc     func() (*asset, error)\n\tChildren map[string]*bintree\n}\n\nvar _bintree = &bintree{nil, map[string]*bintree{\n\t\"cmd\": {nil, map[string]*bintree{\n\t\t\"internal\": {nil, map[string]*bintree{\n\t\t\t\"pages\": {nil, map[string]*bintree{\n\t\t\t\t\"assets\": {nil, map[string]*bintree{\n\t\t\t\t\t\"html\": {nil, map[string]*bintree{\n\t\t\t\t\t\t\"containers.html\": {cmdInternalPagesAssetsHtmlContainersHtml, map[string]*bintree{}},\n\t\t\t\t\t}},\n\t\t\t\t}},\n\t\t\t}},\n\t\t}},\n\t}},\n}}\n\n// RestoreAsset restores an asset under the given directory.\nfunc RestoreAsset(dir, name string) error {\n\tdata, err := Asset(name)\n\tif err != nil {\n\t\treturn err\n\t}\n\tinfo, err := AssetInfo(name)\n\tif err != nil {\n\t\treturn err\n\t}\n\terr = os.MkdirAll(_filePath(dir, filepath.Dir(name)), os.FileMode(0755))\n\tif err != nil {\n\t\treturn err\n\t}\n\terr = os.WriteFile(_filePath(dir, name), data, info.Mode())\n\tif err != nil {\n\t\treturn err\n\t}\n\treturn os.Chtimes(_filePath(dir, name), info.ModTime(), info.ModTime())\n}\n\n// RestoreAssets restores an asset under the given directory recursively.\nfunc RestoreAssets(dir, name string) error {\n\tchildren, err := AssetDir(name)\n\t// File\n\tif err != nil {\n\t\treturn RestoreAsset(dir, name)\n\t}\n\t// Dir\n\tfor _, child := range children {\n\t\terr = RestoreAssets(dir, filepath.Join(name, child))\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc _filePath(dir, name string) string {\n\tcanonicalName := strings.Replace(name, \"\\\\\", \"/\", -1)\n\treturn filepath.Join(append([]string{dir}, strings.Split(canonicalName, \"/\")...)...)\n}\n"
  },
  {
    "path": "cmd/internal/storage/bigquery/README.md",
    "content": "BigQuery Storage Driver\n=======\n\n[EXPERIMENTAL] Support for BigQuery backend as cAdvisor storage driver.\nThe current implementation takes bunch of BigQuery specific flags for authentication.\nThese will be merged into a single backend config.\n\nTo run the current version, following flags need to be specified:\n```\n # Storage driver to use.\n -storage_driver=bigquery\n \n # Information about server-to-server Oauth token.\n # These can be obtained by creating a Service Account client id under `Google Developer API`\n \n # service client id\n -bq_id=\"XYZ.apps.googleusercontent.com\"\n \n # service email address\n -bq_account=\"ABC@developer.gserviceaccount.com\"\n \n # path to pem key (converted from p12 file)\n -bq_credentials_file=\"/path/to/key.pem\"\n \n # project id to use for storing datasets.\n -bq_project_id=\"awesome_project\"\n```\n\nSee [Service account Authentication](https://developers.google.com/accounts/docs/OAuth2) for Oauth related details.\n"
  },
  {
    "path": "cmd/internal/storage/bigquery/bigquery.go",
    "content": "// Copyright 2014 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage bigquery\n\nimport (\n\t\"os\"\n\n\t\"github.com/google/cadvisor/cmd/internal/storage/bigquery/client\"\n\tinfo \"github.com/google/cadvisor/info/v1\"\n\t\"github.com/google/cadvisor/storage\"\n\n\tbigquery \"google.golang.org/api/bigquery/v2\"\n)\n\nfunc init() {\n\tstorage.RegisterStorageDriver(\"bigquery\", new)\n}\n\ntype bigqueryStorage struct {\n\tclient      *client.Client\n\tmachineName string\n}\n\nconst (\n\t// Bigquery schema types\n\ttypeTimestamp string = \"TIMESTAMP\"\n\ttypeString    string = \"STRING\"\n\ttypeInteger   string = \"INTEGER\"\n\n\tcolTimestamp          string = \"timestamp\"\n\tcolMachineName        string = \"machine\"\n\tcolContainerName      string = \"container_name\"\n\tcolCPUCumulativeUsage string = \"cpu_cumulative_usage\"\n\t// Cumulative CPU usage in system and user mode\n\tcolCPUCumulativeUsageSystem string = \"cpu_cumulative_usage_system\"\n\tcolCPUCumulativeUsageUser   string = \"cpu_cumulative_usage_user\"\n\t// Memory usage\n\tcolMemoryUsage string = \"memory_usage\"\n\t// Working set size\n\tcolMemoryWorkingSet string = \"memory_working_set\"\n\t// Total active file size\n\tcolMemoryTotalActiveFile string = \"memory_total_active_file\"\n\t// Total inactive file size\n\tcolMemoryTotalInactiveFile string = \"memory_total_inactive_file\"\n\t// Container page fault\n\tcolMemoryContainerPgfault string = \"memory_container_pgfault\"\n\t// Constainer major page fault\n\tcolMemoryContainerPgmajfault string = \"memory_container_pgmajfault\"\n\t// Hierarchical page fault\n\tcolMemoryHierarchicalPgfault string = \"memory_hierarchical_pgfault\"\n\t// Hierarchical major page fault\n\tcolMemoryHierarchicalPgmajfault string = \"memory_hierarchical_pgmajfault\"\n\t// Cumulative count of bytes received.\n\tcolRxBytes string = \"rx_bytes\"\n\t// Cumulative count of receive errors encountered.\n\tcolRxErrors string = \"rx_errors\"\n\t// Cumulative count of bytes transmitted.\n\tcolTxBytes string = \"tx_bytes\"\n\t// Cumulative count of transmit errors encountered.\n\tcolTxErrors string = \"tx_errors\"\n\t// Filesystem device.\n\tcolFsDevice = \"fs_device\"\n\t// Filesystem limit.\n\tcolFsLimit = \"fs_limit\"\n\t// Filesystem available space.\n\tcolFsUsage = \"fs_usage\"\n)\n\nfunc new() (storage.StorageDriver, error) {\n\thostname, err := os.Hostname()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn newStorage(\n\t\thostname,\n\t\t*storage.ArgDbTable,\n\t\t*storage.ArgDbName,\n\t)\n}\n\n// TODO(jnagal): Infer schema through reflection. (See bigquery/client/example)\nfunc (s *bigqueryStorage) GetSchema() *bigquery.TableSchema {\n\tfields := make([]*bigquery.TableFieldSchema, 19)\n\ti := 0\n\tfields[i] = &bigquery.TableFieldSchema{\n\t\tType: typeTimestamp,\n\t\tName: colTimestamp,\n\t\tMode: \"REQUIRED\",\n\t}\n\ti++\n\tfields[i] = &bigquery.TableFieldSchema{\n\t\tType: typeString,\n\t\tName: colMachineName,\n\t\tMode: \"REQUIRED\",\n\t}\n\ti++\n\tfields[i] = &bigquery.TableFieldSchema{\n\t\tType: typeString,\n\t\tName: colContainerName,\n\t\tMode: \"REQUIRED\",\n\t}\n\ti++\n\tfields[i] = &bigquery.TableFieldSchema{\n\t\tType: typeInteger,\n\t\tName: colCPUCumulativeUsage,\n\t}\n\ti++\n\tfields[i] = &bigquery.TableFieldSchema{\n\t\tType: typeInteger,\n\t\tName: colCPUCumulativeUsageSystem,\n\t}\n\ti++\n\tfields[i] = &bigquery.TableFieldSchema{\n\t\tType: typeInteger,\n\t\tName: colCPUCumulativeUsageUser,\n\t}\n\ti++\n\tfields[i] = &bigquery.TableFieldSchema{\n\t\tType: typeInteger,\n\t\tName: colMemoryUsage,\n\t}\n\ti++\n\tfields[i] = &bigquery.TableFieldSchema{\n\t\tType: typeInteger,\n\t\tName: colMemoryWorkingSet,\n\t}\n\ti++\n\tfields[i] = &bigquery.TableFieldSchema{\n\t\tType: typeInteger,\n\t\tName: colMemoryTotalActiveFile,\n\t}\n\ti++\n\tfields[i] = &bigquery.TableFieldSchema{\n\t\tType: typeInteger,\n\t\tName: colMemoryTotalInactiveFile,\n\t}\n\ti++\n\tfields[i] = &bigquery.TableFieldSchema{\n\t\tType: typeInteger,\n\t\tName: colMemoryContainerPgfault,\n\t}\n\ti++\n\tfields[i] = &bigquery.TableFieldSchema{\n\t\tType: typeInteger,\n\t\tName: colMemoryContainerPgmajfault,\n\t}\n\ti++\n\tfields[i] = &bigquery.TableFieldSchema{\n\t\tType: typeInteger,\n\t\tName: colMemoryHierarchicalPgfault,\n\t}\n\ti++\n\tfields[i] = &bigquery.TableFieldSchema{\n\t\tType: typeInteger,\n\t\tName: colMemoryHierarchicalPgmajfault,\n\t}\n\ti++\n\tfields[i] = &bigquery.TableFieldSchema{\n\t\tType: typeInteger,\n\t\tName: colRxBytes,\n\t}\n\ti++\n\tfields[i] = &bigquery.TableFieldSchema{\n\t\tType: typeInteger,\n\t\tName: colRxErrors,\n\t}\n\ti++\n\tfields[i] = &bigquery.TableFieldSchema{\n\t\tType: typeInteger,\n\t\tName: colTxBytes,\n\t}\n\ti++\n\tfields[i] = &bigquery.TableFieldSchema{\n\t\tType: typeInteger,\n\t\tName: colTxErrors,\n\t}\n\ti++\n\tfields[i] = &bigquery.TableFieldSchema{\n\t\tType: typeString,\n\t\tName: colFsDevice,\n\t}\n\ti++\n\tfields[i] = &bigquery.TableFieldSchema{\n\t\tType: typeInteger,\n\t\tName: colFsLimit,\n\t}\n\ti++\n\tfields[i] = &bigquery.TableFieldSchema{\n\t\tType: typeInteger,\n\t\tName: colFsUsage,\n\t}\n\treturn &bigquery.TableSchema{\n\t\tFields: fields,\n\t}\n}\n\nfunc (s *bigqueryStorage) containerStatsToRows(\n\tcInfo *info.ContainerInfo,\n\tstats *info.ContainerStats,\n) (row map[string]interface{}) {\n\trow = make(map[string]interface{})\n\n\t// Timestamp\n\trow[colTimestamp] = stats.Timestamp\n\n\t// Machine name\n\trow[colMachineName] = s.machineName\n\n\t// Container name\n\tname := cInfo.ContainerReference.Name\n\tif len(cInfo.ContainerReference.Aliases) > 0 {\n\t\tname = cInfo.ContainerReference.Aliases[0]\n\t}\n\trow[colContainerName] = name\n\n\t// Cumulative Cpu Usage\n\trow[colCPUCumulativeUsage] = stats.Cpu.Usage.Total\n\n\t// Cumulative Cpu Usage in system mode\n\trow[colCPUCumulativeUsageSystem] = stats.Cpu.Usage.System\n\n\t// Cumulative Cpu Usage in user mode\n\trow[colCPUCumulativeUsageUser] = stats.Cpu.Usage.User\n\n\t// Memory Usage\n\trow[colMemoryUsage] = stats.Memory.Usage\n\n\t// Working set size\n\trow[colMemoryWorkingSet] = stats.Memory.WorkingSet\n\n\t// Total active file size\n\trow[colMemoryTotalActiveFile] = stats.Memory.TotalActiveFile\n\n\t// Total inactive file size\n\trow[colMemoryTotalInactiveFile] = stats.Memory.TotalInactiveFile\n\n\t// container page fault\n\trow[colMemoryContainerPgfault] = stats.Memory.ContainerData.Pgfault\n\n\t// container major page fault\n\trow[colMemoryContainerPgmajfault] = stats.Memory.ContainerData.Pgmajfault\n\n\t// hierarchical page fault\n\trow[colMemoryHierarchicalPgfault] = stats.Memory.HierarchicalData.Pgfault\n\n\t// hierarchical major page fault\n\trow[colMemoryHierarchicalPgmajfault] = stats.Memory.HierarchicalData.Pgmajfault\n\n\t// Network stats.\n\trow[colRxBytes] = stats.Network.RxBytes\n\trow[colRxErrors] = stats.Network.RxErrors\n\trow[colTxBytes] = stats.Network.TxBytes\n\trow[colTxErrors] = stats.Network.TxErrors\n\n\t// TODO(jnagal): Handle per-cpu stats.\n\n\treturn\n}\n\nfunc (s *bigqueryStorage) containerFilesystemStatsToRows(\n\tcInfo *info.ContainerInfo,\n\tstats *info.ContainerStats,\n) (rows []map[string]interface{}) {\n\tfor _, fsStat := range stats.Filesystem {\n\t\trow := make(map[string]interface{})\n\t\trow[colFsDevice] = fsStat.Device\n\t\trow[colFsLimit] = fsStat.Limit\n\t\trow[colFsUsage] = fsStat.Usage\n\t\trows = append(rows, row)\n\t}\n\treturn rows\n}\n\nfunc (s *bigqueryStorage) AddStats(cInfo *info.ContainerInfo, stats *info.ContainerStats) error {\n\tif stats == nil {\n\t\treturn nil\n\t}\n\trows := make([]map[string]interface{}, 0)\n\trows = append(rows, s.containerStatsToRows(cInfo, stats))\n\trows = append(rows, s.containerFilesystemStatsToRows(cInfo, stats)...)\n\tfor _, row := range rows {\n\t\terr := s.client.InsertRow(row)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc (s *bigqueryStorage) Close() error {\n\ts.client.Close()\n\ts.client = nil\n\treturn nil\n}\n\n// Create a new bigquery storage driver.\n// machineName: A unique identifier to identify the host that current cAdvisor\n// instance is running on.\n// tableName: BigQuery table used for storing stats.\nfunc newStorage(machineName, datasetID, tableName string) (storage.StorageDriver, error) {\n\tbqClient, err := client.NewClient()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\terr = bqClient.CreateDataset(datasetID)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tret := &bigqueryStorage{\n\t\tclient:      bqClient,\n\t\tmachineName: machineName,\n\t}\n\tschema := ret.GetSchema()\n\terr = bqClient.CreateTable(tableName, schema)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn ret, nil\n}\n"
  },
  {
    "path": "cmd/internal/storage/bigquery/client/client.go",
    "content": "// Copyright 2014 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage client\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"flag\"\n\t\"fmt\"\n\t\"os\"\n\t\"strings\"\n\n\t\"golang.org/x/oauth2\"\n\t\"golang.org/x/oauth2/jwt\"\n\tbigquery \"google.golang.org/api/bigquery/v2\"\n\t\"google.golang.org/api/option\"\n)\n\nvar (\n\t// TODO(jnagal): Condense all flags to an identity file and a pem key file.\n\tclientID       = flag.String(\"bq_id\", \"\", \"Client ID\")\n\tclientSecret   = flag.String(\"bq_secret\", \"notasecret\", \"Client Secret\")\n\tprojectID      = flag.String(\"bq_project_id\", \"\", \"Bigquery project ID\")\n\tserviceAccount = flag.String(\"bq_account\", \"\", \"Service account email\")\n\tpemFile        = flag.String(\"bq_credentials_file\", \"\", \"Credential Key file (pem)\")\n)\n\nconst (\n\terrAlreadyExists string = \"Error 409: Already Exists\"\n)\n\ntype Client struct {\n\tservice   *bigquery.Service\n\ttoken     *oauth2.Token\n\tdatasetID string\n\ttableID   string\n}\n\n// Helper method to create an authenticated connection.\nfunc connect() (*oauth2.Token, *bigquery.Service, error) {\n\tif *clientID == \"\" {\n\t\treturn nil, nil, fmt.Errorf(\"no client id specified\")\n\t}\n\tif *serviceAccount == \"\" {\n\t\treturn nil, nil, fmt.Errorf(\"no service account specified\")\n\t}\n\tif *projectID == \"\" {\n\t\treturn nil, nil, fmt.Errorf(\"no project id specified\")\n\t}\n\tauthScope := bigquery.BigqueryScope\n\tif *pemFile == \"\" {\n\t\treturn nil, nil, fmt.Errorf(\"no credentials specified\")\n\t}\n\tpemBytes, err := os.ReadFile(*pemFile)\n\tif err != nil {\n\t\treturn nil, nil, fmt.Errorf(\"could not access credential file %v - %v\", pemFile, err)\n\t}\n\n\tjwtConfig := &jwt.Config{\n\t\tEmail:      *serviceAccount,\n\t\tScopes:     []string{authScope},\n\t\tPrivateKey: pemBytes,\n\t\tTokenURL:   \"https://accounts.google.com/o/oauth2/token\",\n\t}\n\ttoken, err := jwtConfig.TokenSource(context.Background()).Token()\n\tif err != nil {\n\t\treturn nil, nil, err\n\t}\n\tif !token.Valid() {\n\t\treturn nil, nil, fmt.Errorf(\"invalid token for BigQuery oauth\")\n\t}\n\n\tconfig := &oauth2.Config{\n\t\tClientID:     *clientID,\n\t\tClientSecret: *clientSecret,\n\t\tScopes:       []string{authScope},\n\t\tEndpoint: oauth2.Endpoint{\n\t\t\tAuthURL:  \"https://accounts.google.com/o/oauth2/auth\",\n\t\t\tTokenURL: \"https://accounts.google.com/o/oauth2/token\",\n\t\t},\n\t}\n\tclient := config.Client(context.Background(), token)\n\n\tservice, err := bigquery.NewService(context.Background(), option.WithHTTPClient(client))\n\tif err != nil {\n\t\tfmt.Printf(\"Failed to create new service: %v\\n\", err)\n\t\treturn nil, nil, err\n\t}\n\n\treturn token, service, nil\n}\n\n// Creates a new client instance with an authenticated connection to bigquery.\nfunc NewClient() (*Client, error) {\n\ttoken, service, err := connect()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tc := &Client{\n\t\ttoken:   token,\n\t\tservice: service,\n\t}\n\treturn c, nil\n}\n\nfunc (c *Client) Close() error {\n\tc.service = nil\n\treturn nil\n}\n\n// Helper method to return the bigquery service connection.\n// Expired connection is refreshed.\nfunc (c *Client) getService() (*bigquery.Service, error) {\n\tif c.token == nil || c.service == nil {\n\t\treturn nil, fmt.Errorf(\"service not initialized\")\n\t}\n\n\t// Refresh expired token.\n\tif !c.token.Valid() {\n\t\ttoken, service, err := connect()\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tc.token = token\n\t\tc.service = service\n\t\treturn service, nil\n\t}\n\treturn c.service, nil\n}\n\nfunc (c *Client) PrintDatasets() error {\n\tdatasetList, err := c.service.Datasets.List(*projectID).Do()\n\tif err != nil {\n\t\tfmt.Printf(\"Failed to get list of datasets\\n\")\n\t\treturn err\n\t}\n\tfmt.Printf(\"Successfully retrieved datasets. Retrieved: %d\\n\", len(datasetList.Datasets))\n\n\tfor _, d := range datasetList.Datasets {\n\t\tfmt.Printf(\"%s %s\\n\", d.Id, d.FriendlyName)\n\t}\n\treturn nil\n}\n\nfunc (c *Client) CreateDataset(datasetID string) error {\n\tif c.service == nil {\n\t\treturn fmt.Errorf(\"no service created\")\n\t}\n\t_, err := c.service.Datasets.Insert(*projectID, &bigquery.Dataset{\n\t\tDatasetReference: &bigquery.DatasetReference{\n\t\t\tDatasetId: datasetID,\n\t\t\tProjectId: *projectID,\n\t\t},\n\t}).Do()\n\t// TODO(jnagal): Do a Get() to verify dataset already exists.\n\tif err != nil && !strings.Contains(err.Error(), errAlreadyExists) {\n\t\treturn err\n\t}\n\tc.datasetID = datasetID\n\treturn nil\n}\n\n// Create a table with provided table ID and schema.\n// Schema is currently not updated if the table already exists.\nfunc (c *Client) CreateTable(tableID string, schema *bigquery.TableSchema) error {\n\tif c.service == nil || c.datasetID == \"\" {\n\t\treturn fmt.Errorf(\"no dataset created\")\n\t}\n\t_, err := c.service.Tables.Get(*projectID, c.datasetID, tableID).Do()\n\tif err != nil {\n\t\t// Create a new table.\n\t\t_, err := c.service.Tables.Insert(*projectID, c.datasetID, &bigquery.Table{\n\t\t\tSchema: schema,\n\t\t\tTableReference: &bigquery.TableReference{\n\t\t\t\tDatasetId: c.datasetID,\n\t\t\t\tProjectId: *projectID,\n\t\t\t\tTableId:   tableID,\n\t\t\t},\n\t\t}).Do()\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\t// TODO(jnagal): Update schema if it has changed. We can only extend existing schema.\n\tc.tableID = tableID\n\treturn nil\n}\n\n// Add a row to the connected table.\nfunc (c *Client) InsertRow(rowData map[string]interface{}) error {\n\tservice, _ := c.getService()\n\tif service == nil || c.datasetID == \"\" || c.tableID == \"\" {\n\t\treturn fmt.Errorf(\"table not setup to add rows\")\n\t}\n\tjsonRows := make(map[string]bigquery.JsonValue)\n\tfor key, value := range rowData {\n\t\tjsonRows[key] = bigquery.JsonValue(value)\n\t}\n\trows := []*bigquery.TableDataInsertAllRequestRows{\n\t\t{\n\t\t\tJson: jsonRows,\n\t\t},\n\t}\n\n\t// TODO(jnagal): Batch insert requests.\n\tinsertRequest := &bigquery.TableDataInsertAllRequest{Rows: rows}\n\n\tresult, err := service.Tabledata.InsertAll(*projectID, c.datasetID, c.tableID, insertRequest).Do()\n\tif err != nil {\n\t\treturn fmt.Errorf(\"error inserting row: %v\", err)\n\t}\n\n\tif len(result.InsertErrors) > 0 {\n\t\terrstr := fmt.Sprintf(\"Insertion for %d rows failed\\n\", len(result.InsertErrors))\n\t\tfor _, errors := range result.InsertErrors {\n\t\t\tfor _, errorproto := range errors.Errors {\n\t\t\t\terrstr += fmt.Sprintf(\"Error inserting row %d: %+v\\n\", errors.Index, errorproto)\n\t\t\t}\n\t\t}\n\t\treturn errors.New(errstr)\n\t}\n\treturn nil\n}\n"
  },
  {
    "path": "cmd/internal/storage/bigquery/client/example/example.go",
    "content": "// Copyright 2014 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage main\n\nimport (\n\t\"flag\"\n\t\"fmt\"\n\t\"time\"\n\n\t\"github.com/SeanDolphin/bqschema\"\n\n\t\"github.com/google/cadvisor/cmd/internal/storage/bigquery/client\"\n)\n\ntype container struct {\n\tName         string    `json:\"name\"`\n\tCpuUsage     uint64    `json:\"cpuusage,omitempty\"`\n\tMemoryUsage  uint64    `json:\"memoryusage,omitempty\"`\n\tNetworkUsage uint64    `json:\"networkusage,omitempty\"`\n\tTimestamp    time.Time `json:\"timestamp\"`\n}\n\nfunc main() {\n\tflag.Parse()\n\tc, err := client.NewClient()\n\tif err != nil {\n\t\tfmt.Printf(\"Failed to connect to bigquery\\n\")\n\t\tpanic(err)\n\t}\n\n\terr = c.PrintDatasets()\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\n\t// Create a new dataset.\n\terr = c.CreateDataset(\"sampledataset\")\n\tif err != nil {\n\t\tfmt.Printf(\"Failed to create dataset %v\\n\", err)\n\t\tpanic(err)\n\t}\n\n\t// Create a new table\n\tcontainerData := container{\n\t\tName:         \"test_container\",\n\t\tCpuUsage:     123456,\n\t\tMemoryUsage:  1024,\n\t\tNetworkUsage: 9046,\n\t\tTimestamp:    time.Now(),\n\t}\n\tschema, err := bqschema.ToSchema(containerData)\n\tif err != nil {\n\t\tfmt.Printf(\"Failed to create schema\")\n\t\tpanic(err)\n\t}\n\n\terr = c.CreateTable(\"sampletable\", schema)\n\tif err != nil {\n\t\tfmt.Printf(\"Failed to create table\")\n\t\tpanic(err)\n\t}\n\n\t// Add Data\n\tm := make(map[string]interface{})\n\tt := time.Now()\n\tfor i := 0; i < 10; i++ {\n\t\tm[\"Name\"] = containerData.Name\n\t\tm[\"CpuUsage\"] = containerData.CpuUsage + uint64(i*100)\n\t\tm[\"MemoryUsage\"] = containerData.MemoryUsage - uint64(i*10)\n\t\tm[\"NetworkUsage\"] = containerData.NetworkUsage + uint64(i*10)\n\t\tm[\"Timestamp\"] = t.Add(time.Duration(i) * time.Second)\n\n\t\terr = c.InsertRow(m)\n\t\tif err != nil {\n\t\t\tfmt.Printf(\"Failed to insert row\")\n\t\t\tpanic(err)\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "cmd/internal/storage/elasticsearch/elasticsearch.go",
    "content": "// Copyright 2015 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage elasticsearch\n\nimport (\n\t\"flag\"\n\t\"fmt\"\n\t\"os\"\n\t\"sync\"\n\t\"time\"\n\n\tinfo \"github.com/google/cadvisor/info/v1\"\n\tstorage \"github.com/google/cadvisor/storage\"\n\n\t\"gopkg.in/olivere/elastic.v2\"\n)\n\nfunc init() {\n\tstorage.RegisterStorageDriver(\"elasticsearch\", new)\n}\n\ntype elasticStorage struct {\n\tclient      *elastic.Client\n\tmachineName string\n\tindexName   string\n\ttypeName    string\n\tlock        sync.Mutex\n}\n\ntype detailSpec struct {\n\tTimestamp      int64                `json:\"timestamp\"`\n\tMachineName    string               `json:\"machine_name,omitempty\"`\n\tContainerName  string               `json:\"container_Name,omitempty\"`\n\tContainerStats *info.ContainerStats `json:\"container_stats,omitempty\"`\n}\n\nvar (\n\targElasticHost   = flag.String(\"storage_driver_es_host\", \"http://localhost:9200\", \"ElasticSearch host:port\")\n\targIndexName     = flag.String(\"storage_driver_es_index\", \"cadvisor\", \"ElasticSearch index name\")\n\targTypeName      = flag.String(\"storage_driver_es_type\", \"stats\", \"ElasticSearch type name\")\n\targEnableSniffer = flag.Bool(\"storage_driver_es_enable_sniffer\", false, \"ElasticSearch uses a sniffing process to find all nodes of your cluster by default, automatically\")\n)\n\nfunc new() (storage.StorageDriver, error) {\n\thostname, err := os.Hostname()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn newStorage(\n\t\thostname,\n\t\t*argIndexName,\n\t\t*argTypeName,\n\t\t*argElasticHost,\n\t\t*argEnableSniffer,\n\t)\n}\n\nfunc (s *elasticStorage) containerStatsAndDefaultValues(\n\tcInfo *info.ContainerInfo, stats *info.ContainerStats) *detailSpec {\n\ttimestamp := stats.Timestamp.UnixNano() / 1e3\n\tvar containerName string\n\tif len(cInfo.ContainerReference.Aliases) > 0 {\n\t\tcontainerName = cInfo.ContainerReference.Aliases[0]\n\t} else {\n\t\tcontainerName = cInfo.ContainerReference.Name\n\t}\n\tdetail := &detailSpec{\n\t\tTimestamp:      timestamp,\n\t\tMachineName:    s.machineName,\n\t\tContainerName:  containerName,\n\t\tContainerStats: stats,\n\t}\n\treturn detail\n}\n\nfunc (s *elasticStorage) AddStats(cInfo *info.ContainerInfo, stats *info.ContainerStats) error {\n\tif stats == nil {\n\t\treturn nil\n\t}\n\tfunc() {\n\t\t// AddStats will be invoked simultaneously from multiple threads and only one of them will perform a write.\n\t\ts.lock.Lock()\n\t\tdefer s.lock.Unlock()\n\t\t// Add some default params based on ContainerStats\n\t\tdetail := s.containerStatsAndDefaultValues(cInfo, stats)\n\t\t// Index a cadvisor (using JSON serialization)\n\t\t_, err := s.client.Index().\n\t\t\tIndex(s.indexName).\n\t\t\tType(s.typeName).\n\t\t\tBodyJson(detail).\n\t\t\tDo()\n\t\tif err != nil {\n\t\t\t// Handle error\n\t\t\tfmt.Printf(\"failed to write stats to ElasticSearch - %s\", err)\n\t\t\treturn\n\t\t}\n\t}()\n\treturn nil\n}\n\nfunc (s *elasticStorage) Close() error {\n\ts.client = nil\n\treturn nil\n}\n\n// machineName: A unique identifier to identify the host that current cAdvisor\n// instance is running on.\n// ElasticHost: The host which runs ElasticSearch.\nfunc newStorage(\n\tmachineName,\n\tindexName,\n\ttypeName,\n\telasticHost string,\n\tenableSniffer bool,\n) (storage.StorageDriver, error) {\n\t// Obtain a client and connect to the default Elasticsearch installation\n\t// on 127.0.0.1:9200. Of course you can configure your client to connect\n\t// to other hosts and configure it in various other ways.\n\tclient, err := elastic.NewClient(\n\t\telastic.SetHealthcheck(true),\n\t\telastic.SetSniff(enableSniffer),\n\t\telastic.SetHealthcheckInterval(30*time.Second),\n\t\telastic.SetURL(elasticHost),\n\t)\n\tif err != nil {\n\t\t// Handle error\n\t\treturn nil, fmt.Errorf(\"failed to create the elasticsearch client - %s\", err)\n\t}\n\n\t// Ping the Elasticsearch server to get e.g. the version number\n\tinfo, code, err := client.Ping().URL(elasticHost).Do()\n\tif err != nil {\n\t\t// Handle error\n\t\treturn nil, fmt.Errorf(\"failed to ping the elasticsearch - %s\", err)\n\n\t}\n\tfmt.Printf(\"Elasticsearch returned with code %d and version %s\", code, info.Version.Number)\n\n\tret := &elasticStorage{\n\t\tclient:      client,\n\t\tmachineName: machineName,\n\t\tindexName:   indexName,\n\t\ttypeName:    typeName,\n\t}\n\treturn ret, nil\n}\n"
  },
  {
    "path": "cmd/internal/storage/influxdb/influxdb.go",
    "content": "// Copyright 2014 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage influxdb\n\nimport (\n\t\"flag\"\n\t\"fmt\"\n\t\"net/url\"\n\t\"os\"\n\t\"sync\"\n\t\"time\"\n\n\tinfo \"github.com/google/cadvisor/info/v1\"\n\t\"github.com/google/cadvisor/storage\"\n\t\"github.com/google/cadvisor/version\"\n\n\tinfluxdb \"github.com/influxdb/influxdb/client\"\n)\n\nfunc init() {\n\tstorage.RegisterStorageDriver(\"influxdb\", new)\n}\n\nvar argDbRetentionPolicy = flag.String(\"storage_driver_influxdb_retention_policy\", \"\", \"retention policy\")\n\ntype influxdbStorage struct {\n\tclient          *influxdb.Client\n\tmachineName     string\n\tdatabase        string\n\tretentionPolicy string\n\tbufferDuration  time.Duration\n\tlastWrite       time.Time\n\tpoints          []*influxdb.Point\n\tlock            sync.Mutex\n\treadyToFlush    func() bool\n}\n\n// Series names\nconst (\n\t// Cumulative CPU usage\n\tserCPUUsageTotal  string = \"cpu_usage_total\"\n\tserCPUUsageSystem string = \"cpu_usage_system\"\n\tserCPUUsageUser   string = \"cpu_usage_user\"\n\tserCPUUsagePerCPU string = \"cpu_usage_per_cpu\"\n\t// Smoothed average of number of runnable threads x 1000.\n\tserLoadAverage string = \"load_average\"\n\t// Memory Usage\n\tserMemoryUsage string = \"memory_usage\"\n\t// Maximum memory usage recorded\n\tserMemoryMaxUsage string = \"memory_max_usage\"\n\t// //Number of bytes of page cache memory\n\tserMemoryCache string = \"memory_cache\"\n\t// Size of RSS\n\tserMemoryRss string = \"memory_rss\"\n\t// Container swap usage\n\tserMemorySwap string = \"memory_swap\"\n\t// Size of memory mapped files in bytes\n\tserMemoryMappedFile string = \"memory_mapped_file\"\n\t// Working set size\n\tserMemoryWorkingSet string = \"memory_working_set\"\n\t// Total active file size\n\tserMemoryTotalActiveFile string = \"memory_total_active_file\"\n\t// Total inactive file size\n\tserMemoryTotalInactiveFile string = \"memory_total_inactive_file\"\n\t// Number of memory usage hits limits\n\tserMemoryFailcnt string = \"memory_failcnt\"\n\t// Cumulative count of memory allocation failures\n\tserMemoryFailure string = \"memory_failure\"\n\t// Cumulative count of bytes received.\n\tserRxBytes string = \"rx_bytes\"\n\t// Cumulative count of receive errors encountered.\n\tserRxErrors string = \"rx_errors\"\n\t// Cumulative count of bytes transmitted.\n\tserTxBytes string = \"tx_bytes\"\n\t// Cumulative count of transmit errors encountered.\n\tserTxErrors string = \"tx_errors\"\n\t// Filesystem limit.\n\tserFsLimit string = \"fs_limit\"\n\t// Filesystem usage.\n\tserFsUsage string = \"fs_usage\"\n\t// Hugetlb stat - current res_counter usage for hugetlb\n\tsetHugetlbUsage = \"hugetlb_usage\"\n\t// Hugetlb stat - maximum usage ever recorded\n\tsetHugetlbMaxUsage = \"hugetlb_max_usage\"\n\t// Hugetlb stat - number of times hugetlb usage allocation failure\n\tsetHugetlbFailcnt = \"hugetlb_failcnt\"\n\t// Perf statistics\n\tserPerfStat = \"perf_stat\"\n\t// Referenced memory\n\tserReferencedMemory = \"referenced_memory\"\n\t// Resctrl - Total memory bandwidth\n\tserResctrlMemoryBandwidthTotal = \"resctrl_memory_bandwidth_total\"\n\t// Resctrl - Local memory bandwidth\n\tserResctrlMemoryBandwidthLocal = \"resctrl_memory_bandwidth_local\"\n\t// Resctrl - Last level cache usage\n\tserResctrlLLCOccupancy = \"resctrl_llc_occupancy\"\n)\n\nfunc new() (storage.StorageDriver, error) {\n\thostname, err := os.Hostname()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn newStorage(\n\t\thostname,\n\t\t*storage.ArgDbTable,\n\t\t*storage.ArgDbName,\n\t\t*argDbRetentionPolicy,\n\t\t*storage.ArgDbUsername,\n\t\t*storage.ArgDbPassword,\n\t\t*storage.ArgDbHost,\n\t\t*storage.ArgDbIsSecure,\n\t\t*storage.ArgDbBufferDuration,\n\t)\n}\n\n// Field names\nconst (\n\tfieldValue  string = \"value\"\n\tfieldType   string = \"type\"\n\tfieldDevice string = \"device\"\n)\n\n// Tag names\nconst (\n\ttagMachineName   string = \"machine\"\n\ttagContainerName string = \"container_name\"\n)\n\nfunc (s *influxdbStorage) containerFilesystemStatsToPoints(\n\tcInfo *info.ContainerInfo,\n\tstats *info.ContainerStats) (points []*influxdb.Point) {\n\tif len(stats.Filesystem) == 0 {\n\t\treturn points\n\t}\n\tfor _, fsStat := range stats.Filesystem {\n\t\ttagsFsUsage := map[string]string{\n\t\t\tfieldDevice: fsStat.Device,\n\t\t\tfieldType:   \"usage\",\n\t\t}\n\t\tfieldsFsUsage := map[string]interface{}{\n\t\t\tfieldValue: int64(fsStat.Usage),\n\t\t}\n\t\tpointFsUsage := &influxdb.Point{\n\t\t\tMeasurement: serFsUsage,\n\t\t\tTags:        tagsFsUsage,\n\t\t\tFields:      fieldsFsUsage,\n\t\t}\n\n\t\ttagsFsLimit := map[string]string{\n\t\t\tfieldDevice: fsStat.Device,\n\t\t\tfieldType:   \"limit\",\n\t\t}\n\t\tfieldsFsLimit := map[string]interface{}{\n\t\t\tfieldValue: int64(fsStat.Limit),\n\t\t}\n\t\tpointFsLimit := &influxdb.Point{\n\t\t\tMeasurement: serFsLimit,\n\t\t\tTags:        tagsFsLimit,\n\t\t\tFields:      fieldsFsLimit,\n\t\t}\n\n\t\tpoints = append(points, pointFsUsage, pointFsLimit)\n\t}\n\n\ts.tagPoints(cInfo, stats, points)\n\n\treturn points\n}\n\n// Set tags and timestamp for all points of the batch.\n// Points should inherit the tags that are set for BatchPoints, but that does not seem to work.\nfunc (s *influxdbStorage) tagPoints(cInfo *info.ContainerInfo, stats *info.ContainerStats, points []*influxdb.Point) {\n\t// Use container alias if possible\n\tvar containerName string\n\tif len(cInfo.ContainerReference.Aliases) > 0 {\n\t\tcontainerName = cInfo.ContainerReference.Aliases[0]\n\t} else {\n\t\tcontainerName = cInfo.ContainerReference.Name\n\t}\n\n\tcommonTags := map[string]string{\n\t\ttagMachineName:   s.machineName,\n\t\ttagContainerName: containerName,\n\t}\n\tfor i := 0; i < len(points); i++ {\n\t\t// merge with existing tags if any\n\t\taddTagsToPoint(points[i], commonTags)\n\t\taddTagsToPoint(points[i], cInfo.Spec.Labels)\n\t\tpoints[i].Time = stats.Timestamp\n\t}\n}\n\nfunc (s *influxdbStorage) containerStatsToPoints(\n\tcInfo *info.ContainerInfo,\n\tstats *info.ContainerStats,\n) (points []*influxdb.Point) {\n\t// CPU usage: Total usage in nanoseconds\n\tpoints = append(points, makePoint(serCPUUsageTotal, stats.Cpu.Usage.Total))\n\n\t// CPU usage: Time spend in system space (in nanoseconds)\n\tpoints = append(points, makePoint(serCPUUsageSystem, stats.Cpu.Usage.System))\n\n\t// CPU usage: Time spent in user space (in nanoseconds)\n\tpoints = append(points, makePoint(serCPUUsageUser, stats.Cpu.Usage.User))\n\n\t// CPU usage per CPU\n\tfor i := 0; i < len(stats.Cpu.Usage.PerCpu); i++ {\n\t\tpoint := makePoint(serCPUUsagePerCPU, stats.Cpu.Usage.PerCpu[i])\n\t\ttags := map[string]string{\"instance\": fmt.Sprintf(\"%v\", i)}\n\t\taddTagsToPoint(point, tags)\n\n\t\tpoints = append(points, point)\n\t}\n\n\t// Load Average\n\tpoints = append(points, makePoint(serLoadAverage, stats.Cpu.LoadAverage))\n\n\t// Network Stats\n\tpoints = append(points, makePoint(serRxBytes, stats.Network.RxBytes))\n\tpoints = append(points, makePoint(serRxErrors, stats.Network.RxErrors))\n\tpoints = append(points, makePoint(serTxBytes, stats.Network.TxBytes))\n\tpoints = append(points, makePoint(serTxErrors, stats.Network.TxErrors))\n\n\t// Referenced Memory\n\tpoints = append(points, makePoint(serReferencedMemory, stats.ReferencedMemory))\n\n\ts.tagPoints(cInfo, stats, points)\n\n\treturn points\n}\n\nfunc (s *influxdbStorage) memoryStatsToPoints(\n\tcInfo *info.ContainerInfo,\n\tstats *info.ContainerStats,\n) (points []*influxdb.Point) {\n\t// Memory Usage\n\tpoints = append(points, makePoint(serMemoryUsage, stats.Memory.Usage))\n\t// Maximum memory usage recorded\n\tpoints = append(points, makePoint(serMemoryMaxUsage, stats.Memory.MaxUsage))\n\t//Number of bytes of page cache memory\n\tpoints = append(points, makePoint(serMemoryCache, stats.Memory.Cache))\n\t// Size of RSS\n\tpoints = append(points, makePoint(serMemoryRss, stats.Memory.RSS))\n\t// Container swap usage\n\tpoints = append(points, makePoint(serMemorySwap, stats.Memory.Swap))\n\t// Size of memory mapped files in bytes\n\tpoints = append(points, makePoint(serMemoryMappedFile, stats.Memory.MappedFile))\n\t// Working Set Size\n\tpoints = append(points, makePoint(serMemoryWorkingSet, stats.Memory.WorkingSet))\n\t// Total Active File Size\n\tpoints = append(points, makePoint(serMemoryTotalActiveFile, stats.Memory.TotalActiveFile))\n\t// Total Inactive File Size\n\tpoints = append(points, makePoint(serMemoryTotalInactiveFile, stats.Memory.TotalInactiveFile))\n\t// Number of memory usage hits limits\n\tpoints = append(points, makePoint(serMemoryFailcnt, stats.Memory.Failcnt))\n\n\t// Cumulative count of memory allocation failures\n\tmemoryFailuresTags := map[string]string{\n\t\t\"failure_type\": \"pgfault\",\n\t\t\"scope\":        \"container\",\n\t}\n\tmemoryFailurePoint := makePoint(serMemoryFailure, stats.Memory.ContainerData.Pgfault)\n\taddTagsToPoint(memoryFailurePoint, memoryFailuresTags)\n\tpoints = append(points, memoryFailurePoint)\n\n\tmemoryFailuresTags[\"failure_type\"] = \"pgmajfault\"\n\tmemoryFailurePoint = makePoint(serMemoryFailure, stats.Memory.ContainerData.Pgmajfault)\n\taddTagsToPoint(memoryFailurePoint, memoryFailuresTags)\n\tpoints = append(points, memoryFailurePoint)\n\n\tmemoryFailuresTags[\"failure_type\"] = \"pgfault\"\n\tmemoryFailuresTags[\"scope\"] = \"hierarchical\"\n\tmemoryFailurePoint = makePoint(serMemoryFailure, stats.Memory.HierarchicalData.Pgfault)\n\taddTagsToPoint(memoryFailurePoint, memoryFailuresTags)\n\tpoints = append(points, memoryFailurePoint)\n\n\tmemoryFailuresTags[\"failure_type\"] = \"pgmajfault\"\n\tmemoryFailurePoint = makePoint(serMemoryFailure, stats.Memory.HierarchicalData.Pgmajfault)\n\taddTagsToPoint(memoryFailurePoint, memoryFailuresTags)\n\tpoints = append(points, memoryFailurePoint)\n\n\ts.tagPoints(cInfo, stats, points)\n\n\treturn points\n}\n\nfunc (s *influxdbStorage) hugetlbStatsToPoints(\n\tcInfo *info.ContainerInfo,\n\tstats *info.ContainerStats,\n) (points []*influxdb.Point) {\n\n\tfor pageSize, hugetlbStat := range stats.Hugetlb {\n\t\ttags := map[string]string{\n\t\t\t\"page_size\": pageSize,\n\t\t}\n\n\t\t// Hugepage usage\n\t\tpoint := makePoint(setHugetlbUsage, hugetlbStat.Usage)\n\t\taddTagsToPoint(point, tags)\n\t\tpoints = append(points, point)\n\n\t\t//Maximum hugepage usage recorded\n\t\tpoint = makePoint(setHugetlbMaxUsage, hugetlbStat.MaxUsage)\n\t\taddTagsToPoint(point, tags)\n\t\tpoints = append(points, point)\n\n\t\t// Number of hugepage usage hits limits\n\t\tpoint = makePoint(setHugetlbFailcnt, hugetlbStat.Failcnt)\n\t\taddTagsToPoint(point, tags)\n\t\tpoints = append(points, point)\n\t}\n\n\ts.tagPoints(cInfo, stats, points)\n\n\treturn points\n}\n\nfunc (s *influxdbStorage) perfStatsToPoints(\n\tcInfo *info.ContainerInfo,\n\tstats *info.ContainerStats,\n) (points []*influxdb.Point) {\n\n\tfor _, perfStat := range stats.PerfStats {\n\t\tpoint := makePoint(serPerfStat, perfStat.Value)\n\t\ttags := map[string]string{\n\t\t\t\"cpu\":           fmt.Sprintf(\"%v\", perfStat.Cpu),\n\t\t\t\"name\":          perfStat.Name,\n\t\t\t\"scaling_ratio\": fmt.Sprintf(\"%v\", perfStat.ScalingRatio),\n\t\t}\n\t\taddTagsToPoint(point, tags)\n\t\tpoints = append(points, point)\n\t}\n\n\ts.tagPoints(cInfo, stats, points)\n\n\treturn points\n}\n\nfunc (s *influxdbStorage) resctrlStatsToPoints(\n\tcInfo *info.ContainerInfo,\n\tstats *info.ContainerStats,\n) (points []*influxdb.Point) {\n\n\t// Memory bandwidth\n\tfor nodeID, rdtMemoryBandwidth := range stats.Resctrl.MemoryBandwidth {\n\t\ttags := map[string]string{\n\t\t\t\"node_id\": fmt.Sprintf(\"%v\", nodeID),\n\t\t}\n\t\tpoint := makePoint(serResctrlMemoryBandwidthTotal, rdtMemoryBandwidth.TotalBytes)\n\t\taddTagsToPoint(point, tags)\n\t\tpoints = append(points, point)\n\n\t\tpoint = makePoint(serResctrlMemoryBandwidthLocal, rdtMemoryBandwidth.LocalBytes)\n\t\taddTagsToPoint(point, tags)\n\t\tpoints = append(points, point)\n\t}\n\n\t// Cache\n\tfor nodeID, rdtCache := range stats.Resctrl.Cache {\n\t\ttags := map[string]string{\n\t\t\t\"node_id\": fmt.Sprintf(\"%v\", nodeID),\n\t\t}\n\t\tpoint := makePoint(serResctrlLLCOccupancy, rdtCache.LLCOccupancy)\n\t\taddTagsToPoint(point, tags)\n\t\tpoints = append(points, point)\n\t}\n\n\ts.tagPoints(cInfo, stats, points)\n\n\treturn points\n}\n\nfunc (s *influxdbStorage) OverrideReadyToFlush(readyToFlush func() bool) {\n\ts.readyToFlush = readyToFlush\n}\n\nfunc (s *influxdbStorage) defaultReadyToFlush() bool {\n\treturn time.Since(s.lastWrite) >= s.bufferDuration\n}\n\nfunc (s *influxdbStorage) AddStats(cInfo *info.ContainerInfo, stats *info.ContainerStats) error {\n\tif stats == nil {\n\t\treturn nil\n\t}\n\tvar pointsToFlush []*influxdb.Point\n\tfunc() {\n\t\t// AddStats will be invoked simultaneously from multiple threads and only one of them will perform a write.\n\t\ts.lock.Lock()\n\t\tdefer s.lock.Unlock()\n\n\t\ts.points = append(s.points, s.containerStatsToPoints(cInfo, stats)...)\n\t\ts.points = append(s.points, s.memoryStatsToPoints(cInfo, stats)...)\n\t\ts.points = append(s.points, s.hugetlbStatsToPoints(cInfo, stats)...)\n\t\ts.points = append(s.points, s.perfStatsToPoints(cInfo, stats)...)\n\t\ts.points = append(s.points, s.resctrlStatsToPoints(cInfo, stats)...)\n\t\ts.points = append(s.points, s.containerFilesystemStatsToPoints(cInfo, stats)...)\n\t\tif s.readyToFlush() {\n\t\t\tpointsToFlush = s.points\n\t\t\ts.points = make([]*influxdb.Point, 0)\n\t\t\ts.lastWrite = time.Now()\n\t\t}\n\t}()\n\tif len(pointsToFlush) > 0 {\n\t\tpoints := make([]influxdb.Point, len(pointsToFlush))\n\t\tfor i, p := range pointsToFlush {\n\t\t\tpoints[i] = *p\n\t\t}\n\n\t\tbatchTags := map[string]string{tagMachineName: s.machineName}\n\t\tbp := influxdb.BatchPoints{\n\t\t\tPoints:          points,\n\t\t\tDatabase:        s.database,\n\t\t\tRetentionPolicy: s.retentionPolicy,\n\t\t\tTags:            batchTags,\n\t\t\tTime:            stats.Timestamp,\n\t\t}\n\t\tresponse, err := s.client.Write(bp)\n\t\tif err != nil || checkResponseForErrors(response) != nil {\n\t\t\treturn fmt.Errorf(\"failed to write stats to influxDb - %s\", err)\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc (s *influxdbStorage) Close() error {\n\ts.client = nil\n\treturn nil\n}\n\n// machineName: A unique identifier to identify the host that current cAdvisor\n// instance is running on.\n// influxdbHost: The host which runs influxdb (host:port)\nfunc newStorage(\n\tmachineName,\n\ttablename,\n\tdatabase,\n\tretentionPolicy,\n\tusername,\n\tpassword,\n\tinfluxdbHost string,\n\tisSecure bool,\n\tbufferDuration time.Duration,\n) (*influxdbStorage, error) {\n\turl := &url.URL{\n\t\tScheme: \"http\",\n\t\tHost:   influxdbHost,\n\t}\n\tif isSecure {\n\t\turl.Scheme = \"https\"\n\t}\n\n\tconfig := &influxdb.Config{\n\t\tURL:       *url,\n\t\tUsername:  username,\n\t\tPassword:  password,\n\t\tUserAgent: fmt.Sprintf(\"%v/%v\", \"cAdvisor\", version.Info[\"version\"]),\n\t}\n\tclient, err := influxdb.NewClient(*config)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tret := &influxdbStorage{\n\t\tclient:          client,\n\t\tmachineName:     machineName,\n\t\tdatabase:        database,\n\t\tretentionPolicy: retentionPolicy,\n\t\tbufferDuration:  bufferDuration,\n\t\tlastWrite:       time.Now(),\n\t\tpoints:          make([]*influxdb.Point, 0),\n\t}\n\tret.readyToFlush = ret.defaultReadyToFlush\n\treturn ret, nil\n}\n\n// Creates a measurement point with a single value field\nfunc makePoint(name string, value interface{}) *influxdb.Point {\n\tfields := map[string]interface{}{\n\t\tfieldValue: toSignedIfUnsigned(value),\n\t}\n\n\treturn &influxdb.Point{\n\t\tMeasurement: name,\n\t\tFields:      fields,\n\t}\n}\n\n// Adds additional tags to the existing tags of a point\nfunc addTagsToPoint(point *influxdb.Point, tags map[string]string) {\n\tif point.Tags == nil {\n\t\tpoint.Tags = tags\n\t} else {\n\t\tfor k, v := range tags {\n\t\t\tpoint.Tags[k] = v\n\t\t}\n\t}\n}\n\n// Checks response for possible errors\nfunc checkResponseForErrors(response *influxdb.Response) error {\n\tconst msg = \"failed to write stats to influxDb - %s\"\n\n\tif response != nil && response.Err != nil {\n\t\treturn fmt.Errorf(msg, response.Err)\n\t}\n\tif response != nil && response.Results != nil {\n\t\tfor _, result := range response.Results {\n\t\t\tif result.Err != nil {\n\t\t\t\treturn fmt.Errorf(msg, result.Err)\n\t\t\t}\n\t\t}\n\t}\n\treturn nil\n}\n\n// Some stats have type unsigned integer, but the InfluxDB client accepts only signed integers.\nfunc toSignedIfUnsigned(value interface{}) interface{} {\n\tswitch v := value.(type) {\n\tcase uint64:\n\t\treturn int64(v)\n\tcase uint32:\n\t\treturn int32(v)\n\tcase uint16:\n\t\treturn int16(v)\n\tcase uint8:\n\t\treturn int8(v)\n\tcase uint:\n\t\treturn int(v)\n\t}\n\treturn value\n}\n"
  },
  {
    "path": "cmd/internal/storage/influxdb/influxdb_test.go",
    "content": "// Copyright 2014 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n//go:build influxdb_test\n\n// To run unit test: go test -tags influxdb_test\n\npackage influxdb\n\nimport (\n\t\"fmt\"\n\t\"math/rand\"\n\t\"net/url\"\n\t\"reflect\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/google/cadvisor/cmd/internal/storage/test\"\n\tinfo \"github.com/google/cadvisor/info/v1\"\n\t\"github.com/google/cadvisor/storage\"\n\n\tinfluxdb \"github.com/influxdb/influxdb/client\"\n\t\"github.com/stretchr/testify/assert\"\n\t\"github.com/stretchr/testify/require\"\n)\n\n// The duration in seconds for which stats will be buffered in the influxdb driver.\nconst kCacheDuration = 1\n\ntype influxDbTestStorageDriver struct {\n\tcount  int\n\tbuffer int\n\tbase   storage.StorageDriver\n}\n\nfunc (self *influxDbTestStorageDriver) readyToFlush() bool {\n\treturn self.count >= self.buffer\n}\n\nfunc (self *influxDbTestStorageDriver) AddStats(cInfo *info.ContainerInfo, stats *info.ContainerStats) error {\n\tself.count++\n\treturn self.base.AddStats(cInfo, stats)\n}\n\nfunc (self *influxDbTestStorageDriver) Close() error {\n\treturn self.base.Close()\n}\n\nfunc (self *influxDbTestStorageDriver) StatsEq(a, b *info.ContainerStats) bool {\n\tif !test.TimeEq(a.Timestamp, b.Timestamp, 10*time.Millisecond) {\n\t\treturn false\n\t}\n\t// Check only the stats populated in influxdb.\n\tif !reflect.DeepEqual(a.Cpu.Usage, b.Cpu.Usage) {\n\t\treturn false\n\t}\n\n\tif a.Memory.Usage != b.Memory.Usage {\n\t\treturn false\n\t}\n\n\tif a.Memory.WorkingSet != b.Memory.WorkingSet {\n\t\treturn false\n\t}\n\n\tif a.Memory.TotalActiveFile != b.Memory.TotalActiveFile {\n\t\treturn false\n\t}\n\n\tif a.Memory.TotalInactiveFile != b.Memory.TotalInactiveFile {\n\t\treturn false\n\t}\n\n\tif !reflect.DeepEqual(a.Network, b.Network) {\n\t\treturn false\n\t}\n\n\tif !reflect.DeepEqual(a.Filesystem, b.Filesystem) {\n\t\treturn false\n\t}\n\treturn true\n}\n\nfunc runStorageTest(f func(test.TestStorageDriver, *testing.T), t *testing.T, bufferCount int) {\n\tmachineName := \"machineA\"\n\ttable := \"cadvisor_table\"\n\tdatabase := \"cadvisor_test\"\n\tusername := \"root\"\n\tpassword := \"root\"\n\thostname := \"localhost:8086\"\n\tretentionPolicy := \"cadvisor_test_rp\"\n\t// percentilesDuration := 10 * time.Minute\n\n\tconfig := influxdb.Config{\n\t\tURL:      url.URL{Scheme: \"http\", Host: hostname},\n\t\tUsername: username,\n\t\tPassword: password,\n\t}\n\tclient, err := influxdb.NewClient(config)\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\n\t// Re-create the database first.\n\tif err := prepareDatabase(client, database, retentionPolicy); err != nil {\n\t\tt.Fatal(err)\n\t}\n\n\t// Delete all data by the end of the call.\n\t// defer client.Query(influxdb.Query{Command: fmt.Sprintf(\"drop database \\\"%v\\\"\", database)})\n\n\tdriver, err := newStorage(machineName,\n\t\ttable,\n\t\tdatabase,\n\t\tretentionPolicy,\n\t\tusername,\n\t\tpassword,\n\t\thostname,\n\t\tfalse,\n\t\ttime.Duration(bufferCount))\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\tdefer driver.Close()\n\ttestDriver := &influxDbTestStorageDriver{buffer: bufferCount}\n\tdriver.OverrideReadyToFlush(testDriver.readyToFlush)\n\ttestDriver.base = driver\n\n\t// Generate another container's data on same machine.\n\ttest.StorageDriverFillRandomStatsFunc(\"containerOnSameMachine\", 100, testDriver, t)\n\n\t// Generate another container's data on another machine.\n\tdriverForAnotherMachine, err := newStorage(\"machineB\",\n\t\ttable,\n\t\tdatabase,\n\t\tretentionPolicy,\n\t\tusername,\n\t\tpassword,\n\t\thostname,\n\t\tfalse,\n\t\ttime.Duration(bufferCount))\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\tdefer driverForAnotherMachine.Close()\n\ttestDriverOtherMachine := &influxDbTestStorageDriver{buffer: bufferCount}\n\tdriverForAnotherMachine.OverrideReadyToFlush(testDriverOtherMachine.readyToFlush)\n\ttestDriverOtherMachine.base = driverForAnotherMachine\n\n\ttest.StorageDriverFillRandomStatsFunc(\"containerOnAnotherMachine\", 100, testDriverOtherMachine, t)\n\tf(testDriver, t)\n}\n\nfunc prepareDatabase(client *influxdb.Client, database string, retentionPolicy string) error {\n\tdropDbQuery := influxdb.Query{\n\t\tCommand: fmt.Sprintf(\"drop database \\\"%v\\\"\", database),\n\t}\n\tcreateDbQuery := influxdb.Query{\n\t\tCommand: fmt.Sprintf(\"create database \\\"%v\\\"\", database),\n\t}\n\t// A default retention policy must always be present.\n\t// Depending on the InfluxDB configuration it may be created automatically with the database or not.\n\t// TODO create ret. policy only if not present\n\tcreatePolicyQuery := influxdb.Query{\n\t\tCommand: fmt.Sprintf(\"create retention policy \\\"%v\\\" on \\\"%v\\\" duration 1h replication 1 default\", retentionPolicy, database),\n\t}\n\t_, err := client.Query(dropDbQuery)\n\tif err != nil {\n\t\treturn err\n\t}\n\t_, err = client.Query(createDbQuery)\n\tif err != nil {\n\t\treturn err\n\t}\n\t_, err = client.Query(createPolicyQuery)\n\treturn err\n}\n\nfunc TestContainerFileSystemStatsToPoints(t *testing.T) {\n\tassert := assert.New(t)\n\n\tmachineName := \"testMachine\"\n\ttable := \"cadvisor_table\"\n\tdatabase := \"cadvisor_test\"\n\tretentionPolicy := \"cadvisor_test_rp\"\n\tusername := \"root\"\n\tpassword := \"root\"\n\tinfluxdbHost := \"localhost:8086\"\n\n\tstorage, err := newStorage(machineName,\n\t\ttable,\n\t\tdatabase,\n\t\tretentionPolicy,\n\t\tusername,\n\t\tpassword,\n\t\tinfluxdbHost,\n\t\tfalse, 2*time.Minute)\n\tassert.Nil(err)\n\n\tcInfo := &info.ContainerInfo{\n\t\tContainerReference: info.ContainerReference{\n\t\t\tName: \"containerName\",\n\t\t},\n\t}\n\n\tstats := &info.ContainerStats{}\n\tpoints := storage.containerFilesystemStatsToPoints(cInfo, stats)\n\n\t// stats.Filesystem is always nil, not sure why\n\tassert.Nil(points)\n}\n\nfunc TestContainerStatsToPoints(t *testing.T) {\n\t// Given\n\tstorage, err := createTestStorage()\n\trequire.Nil(t, err)\n\trequire.NotNil(t, storage)\n\n\tcInfo, stats := createTestStats()\n\trequire.Nil(t, err)\n\trequire.NotNil(t, stats)\n\n\t// When\n\tpoints := storage.containerStatsToPoints(cInfo, stats)\n\tpoints = append(points, storage.memoryStatsToPoints(cInfo, stats)...)\n\tpoints = append(points, storage.hugetlbStatsToPoints(cInfo, stats)...)\n\tpoints = append(points, storage.perfStatsToPoints(cInfo, stats)...)\n\tpoints = append(points, storage.resctrlStatsToPoints(cInfo, stats)...)\n\n\t// Then\n\tassert.NotEmpty(t, points)\n\tassert.Len(t, points, 34+len(stats.Cpu.Usage.PerCpu))\n\n\t// CPU stats\n\tassertContainsPointWithValue(t, points, serCpuUsageTotal, stats.Cpu.Usage.Total)\n\tassertContainsPointWithValue(t, points, serCpuUsageSystem, stats.Cpu.Usage.System)\n\tassertContainsPointWithValue(t, points, serCpuUsageUser, stats.Cpu.Usage.User)\n\tassertContainsPointWithValue(t, points, serLoadAverage, stats.Cpu.LoadAverage)\n\tfor _, cpu_usage := range stats.Cpu.Usage.PerCpu {\n\t\tassertContainsPointWithValue(t, points, serCpuUsagePerCpu, cpu_usage)\n\t}\n\n\t// Memory stats\n\tassertContainsPointWithValue(t, points, serMemoryUsage, stats.Memory.Usage)\n\tassertContainsPointWithValue(t, points, serMemoryMaxUsage, stats.Memory.MaxUsage)\n\tassertContainsPointWithValue(t, points, serMemoryCache, stats.Memory.Cache)\n\tassertContainsPointWithValue(t, points, serMemoryRss, stats.Memory.RSS)\n\tassertContainsPointWithValue(t, points, serMemorySwap, stats.Memory.Swap)\n\tassertContainsPointWithValue(t, points, serMemoryMappedFile, stats.Memory.MappedFile)\n\tassertContainsPointWithValue(t, points, serMemoryUsage, stats.Memory.Usage)\n\tassertContainsPointWithValue(t, points, serMemoryWorkingSet, stats.Memory.WorkingSet)\n\tassertContainsPointWithValue(t, points, serMemoryTotalActiveFile, stats.Memory.TotalActiveFile)\n\tassertContainsPointWithValue(t, points, serMemoryTotalInactiveFile, stats.Memory.TotalInactiveFile)\n\tassertContainsPointWithValue(t, points, serMemoryFailcnt, stats.Memory.Failcnt)\n\tassertContainsPointWithValue(t, points, serMemoryFailure, stats.Memory.ContainerData.Pgfault)\n\tassertContainsPointWithValue(t, points, serMemoryFailure, stats.Memory.ContainerData.Pgmajfault)\n\tassertContainsPointWithValue(t, points, serMemoryFailure, stats.Memory.HierarchicalData.Pgfault)\n\tassertContainsPointWithValue(t, points, serMemoryFailure, stats.Memory.HierarchicalData.Pgmajfault)\n\n\t// Hugetlb stats\n\tfor _, hugetlbStat := range stats.Hugetlb {\n\t\tassertContainsPointWithValue(t, points, setHugetlbUsage, hugetlbStat.Usage)\n\t\tassertContainsPointWithValue(t, points, setHugetlbMaxUsage, hugetlbStat.MaxUsage)\n\t\tassertContainsPointWithValue(t, points, setHugetlbFailcnt, hugetlbStat.Failcnt)\n\t}\n\n\t// Network stats\n\tassertContainsPointWithValue(t, points, serRxBytes, stats.Network.RxBytes)\n\tassertContainsPointWithValue(t, points, serRxErrors, stats.Network.RxErrors)\n\tassertContainsPointWithValue(t, points, serTxBytes, stats.Network.TxBytes)\n\tassertContainsPointWithValue(t, points, serTxBytes, stats.Network.TxErrors)\n\n\t// Perf stats\n\tfor _, perfStat := range stats.PerfStats {\n\t\tassertContainsPointWithValue(t, points, serPerfStat, perfStat.Value)\n\t}\n\n\t// Reference memory\n\tassertContainsPointWithValue(t, points, serReferencedMemory, stats.ReferencedMemory)\n\n\t// Resource Control stats - memory bandwidth\n\tfor _, rdtMemoryBandwidth := range stats.Resctrl.MemoryBandwidth {\n\t\tassertContainsPointWithValue(t, points, serResctrlMemoryBandwidthTotal, rdtMemoryBandwidth.TotalBytes)\n\t\tassertContainsPointWithValue(t, points, serResctrlMemoryBandwidthLocal, rdtMemoryBandwidth.LocalBytes)\n\t}\n\n\t// Resource Control stats - cache\n\tfor _, rdtCache := range stats.Resctrl.Cache {\n\t\tassertContainsPointWithValue(t, points, serResctrlLLCOccupancy, rdtCache.LLCOccupancy)\n\t}\n}\n\nfunc assertContainsPointWithValue(t *testing.T, points []*influxdb.Point, name string, value interface{}) bool {\n\tfound := false\n\tfor _, point := range points {\n\t\tif point.Measurement == name && point.Fields[fieldValue] == toSignedIfUnsigned(value) {\n\t\t\tfound = true\n\t\t\tbreak\n\t\t}\n\t}\n\treturn assert.True(t, found, \"no point found with name='%v' and value=%v\", name, value)\n}\n\nfunc createTestStorage() (*influxdbStorage, error) {\n\tmachineName := \"testMachine\"\n\ttable := \"cadvisor_table\"\n\tdatabase := \"cadvisor_test\"\n\tretentionPolicy := \"cadvisor_test_rp\"\n\tusername := \"root\"\n\tpassword := \"root\"\n\tinfluxdbHost := \"localhost:8086\"\n\n\tstorage, err := newStorage(machineName,\n\t\ttable,\n\t\tdatabase,\n\t\tretentionPolicy,\n\t\tusername,\n\t\tpassword,\n\t\tinfluxdbHost,\n\t\tfalse, 2*time.Minute)\n\n\treturn storage, err\n}\n\nfunc createTestStats() (*info.ContainerInfo, *info.ContainerStats) {\n\tcInfo := &info.ContainerInfo{\n\t\tContainerReference: info.ContainerReference{\n\t\t\tName:    \"testContainername\",\n\t\t\tAliases: []string{\"testContainerAlias1\", \"testContainerAlias2\"},\n\t\t},\n\t}\n\n\tcpuUsage := info.CpuUsage{\n\t\tTotal:  uint64(rand.Intn(10000)),\n\t\tPerCpu: []uint64{uint64(rand.Intn(1000)), uint64(rand.Intn(1000)), uint64(rand.Intn(1000))},\n\t\tUser:   uint64(rand.Intn(10000)),\n\t\tSystem: uint64(rand.Intn(10000)),\n\t}\n\n\tstats := &info.ContainerStats{\n\t\tTimestamp: time.Now(),\n\t\tCpu: info.CpuStats{\n\t\t\tUsage:       cpuUsage,\n\t\t\tLoadAverage: int32(rand.Intn(1000)),\n\t\t},\n\t\tMemory: info.MemoryStats{\n\t\t\tUsage:             26767396864,\n\t\t\tMaxUsage:          30429605888,\n\t\t\tCache:             7837376512,\n\t\t\tRSS:               18930020352,\n\t\t\tSwap:              1024,\n\t\t\tMappedFile:        1025327104,\n\t\t\tWorkingSet:        23630012416,\n\t\t\tTotalActiveFile:   29459246253,\n\t\t\tTotalInactiveFile: 28364536434,\n\t\t\tFailcnt:           1,\n\t\t\tContainerData:     info.MemoryStatsMemoryData{Pgfault: 100328455, Pgmajfault: 97},\n\t\t\tHierarchicalData:  info.MemoryStatsMemoryData{Pgfault: 100328454, Pgmajfault: 96},\n\t\t},\n\t\tHugetlb: map[string]info.HugetlbStats{\n\t\t\t\"1GB\": {Usage: 1234, MaxUsage: 5678, Failcnt: 9},\n\t\t\t\"2GB\": {Usage: 9876, MaxUsage: 5432, Failcnt: 1},\n\t\t},\n\t\tReferencedMemory: 12345,\n\t\tPerfStats:        []info.PerfStat{{Cpu: 1, PerfValue: info.PerfValue{Name: \"cycles\", ScalingRatio: 1.5, Value: 4589}}},\n\t\tResctrl: info.ResctrlStats{\n\t\t\tMemoryBandwidth: []info.MemoryBandwidthStats{\n\t\t\t\t{TotalBytes: 11234, LocalBytes: 4567},\n\t\t\t\t{TotalBytes: 55678, LocalBytes: 9876},\n\t\t\t},\n\t\t\tCache: []info.CacheStats{\n\t\t\t\t{LLCOccupancy: 3},\n\t\t\t\t{LLCOccupancy: 5},\n\t\t\t},\n\t\t},\n\t}\n\treturn cInfo, stats\n}\n"
  },
  {
    "path": "cmd/internal/storage/kafka/kafka.go",
    "content": "// Copyright 2016 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage kafka\n\nimport (\n\t\"crypto/tls\"\n\t\"crypto/x509\"\n\t\"encoding/json\"\n\t\"flag\"\n\t\"log\"\n\t\"os\"\n\t\"strings\"\n\t\"time\"\n\n\tinfo \"github.com/google/cadvisor/info/v1\"\n\t\"github.com/google/cadvisor/storage\"\n\t\"github.com/google/cadvisor/utils/container\"\n\n\tkafka \"github.com/Shopify/sarama\"\n\t\"k8s.io/klog/v2\"\n)\n\nfunc init() {\n\tstorage.RegisterStorageDriver(\"kafka\", new)\n\tkafka.Logger = log.New(os.Stderr, \"[kafka]\", log.LstdFlags)\n}\n\nvar (\n\tbrokers   = flag.String(\"storage_driver_kafka_broker_list\", \"localhost:9092\", \"kafka broker(s) csv\")\n\ttopic     = flag.String(\"storage_driver_kafka_topic\", \"stats\", \"kafka topic\")\n\tcertFile  = flag.String(\"storage_driver_kafka_ssl_cert\", \"\", \"optional certificate file for TLS client authentication\")\n\tkeyFile   = flag.String(\"storage_driver_kafka_ssl_key\", \"\", \"optional key file for TLS client authentication\")\n\tcaFile    = flag.String(\"storage_driver_kafka_ssl_ca\", \"\", \"optional certificate authority file for TLS client authentication\")\n\tverifySSL = flag.Bool(\"storage_driver_kafka_ssl_verify\", true, \"verify ssl certificate chain\")\n)\n\ntype kafkaStorage struct {\n\tproducer    kafka.AsyncProducer\n\ttopic       string\n\tmachineName string\n}\n\ntype detailSpec struct {\n\tTimestamp       time.Time            `json:\"timestamp\"`\n\tMachineName     string               `json:\"machine_name,omitempty\"`\n\tContainerName   string               `json:\"container_Name,omitempty\"`\n\tContainerID     string               `json:\"container_Id,omitempty\"`\n\tContainerLabels map[string]string    `json:\"container_labels,omitempty\"`\n\tContainerStats  *info.ContainerStats `json:\"container_stats,omitempty\"`\n}\n\nfunc (s *kafkaStorage) infoToDetailSpec(cInfo *info.ContainerInfo, stats *info.ContainerStats) *detailSpec {\n\ttimestamp := time.Now()\n\tcontainerID := cInfo.ContainerReference.Id\n\tcontainerLabels := cInfo.Spec.Labels\n\tcontainerName := container.GetPreferredName(cInfo.ContainerReference)\n\n\tdetail := &detailSpec{\n\t\tTimestamp:       timestamp,\n\t\tMachineName:     s.machineName,\n\t\tContainerName:   containerName,\n\t\tContainerID:     containerID,\n\t\tContainerLabels: containerLabels,\n\t\tContainerStats:  stats,\n\t}\n\treturn detail\n}\n\nfunc (s *kafkaStorage) AddStats(cInfo *info.ContainerInfo, stats *info.ContainerStats) error {\n\tdetail := s.infoToDetailSpec(cInfo, stats)\n\tb, err := json.Marshal(detail)\n\n\ts.producer.Input() <- &kafka.ProducerMessage{\n\t\tTopic: s.topic,\n\t\tValue: kafka.StringEncoder(b),\n\t}\n\n\treturn err\n}\n\nfunc (s *kafkaStorage) Close() error {\n\treturn s.producer.Close()\n}\n\nfunc new() (storage.StorageDriver, error) {\n\tmachineName, err := os.Hostname()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn newStorage(machineName)\n}\n\nfunc generateTLSConfig() (*tls.Config, error) {\n\tif *certFile != \"\" && *keyFile != \"\" && *caFile != \"\" {\n\t\tcert, err := tls.LoadX509KeyPair(*certFile, *keyFile)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\tcaCert, err := os.ReadFile(*caFile)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tcaCertPool := x509.NewCertPool()\n\t\tcaCertPool.AppendCertsFromPEM(caCert)\n\n\t\treturn &tls.Config{\n\t\t\tCertificates:       []tls.Certificate{cert},\n\t\t\tRootCAs:            caCertPool,\n\t\t\tInsecureSkipVerify: *verifySSL,\n\t\t}, nil\n\t}\n\n\treturn nil, nil\n}\n\nfunc newStorage(machineName string) (storage.StorageDriver, error) {\n\tconfig := kafka.NewConfig()\n\n\ttlsConfig, err := generateTLSConfig()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tif tlsConfig != nil {\n\t\tconfig.Net.TLS.Enable = true\n\t\tconfig.Net.TLS.Config = tlsConfig\n\t}\n\n\tconfig.Producer.RequiredAcks = kafka.WaitForAll\n\n\tbrokerList := strings.Split(*brokers, \",\")\n\tklog.V(4).Infof(\"Kafka brokers:%q\", *brokers)\n\n\tproducer, err := kafka.NewAsyncProducer(brokerList, config)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tret := &kafkaStorage{\n\t\tproducer:    producer,\n\t\ttopic:       *topic,\n\t\tmachineName: machineName,\n\t}\n\treturn ret, nil\n}\n"
  },
  {
    "path": "cmd/internal/storage/redis/redis.go",
    "content": "// Copyright 2015 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage redis\n\nimport (\n\t\"encoding/json\"\n\t\"os\"\n\t\"sync\"\n\t\"time\"\n\n\tinfo \"github.com/google/cadvisor/info/v1\"\n\tstorage \"github.com/google/cadvisor/storage\"\n\n\tredis \"github.com/gomodule/redigo/redis\"\n)\n\nfunc init() {\n\tstorage.RegisterStorageDriver(\"redis\", new)\n}\n\ntype redisStorage struct {\n\tconn           redis.Conn\n\tmachineName    string\n\tredisKey       string\n\tbufferDuration time.Duration\n\tlastWrite      time.Time\n\tlock           sync.Mutex\n\treadyToFlush   func() bool\n}\n\ntype detailSpec struct {\n\tTimestamp      int64                `json:\"timestamp\"`\n\tMachineName    string               `json:\"machine_name,omitempty\"`\n\tContainerName  string               `json:\"container_Name,omitempty\"`\n\tContainerStats *info.ContainerStats `json:\"container_stats,omitempty\"`\n}\n\nfunc new() (storage.StorageDriver, error) {\n\thostname, err := os.Hostname()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn newStorage(\n\t\thostname,\n\t\t*storage.ArgDbName,\n\t\t*storage.ArgDbHost,\n\t\t*storage.ArgDbBufferDuration,\n\t)\n}\n\nfunc (s *redisStorage) defaultReadyToFlush() bool {\n\treturn time.Since(s.lastWrite) >= s.bufferDuration\n}\n\n// We must add some default params (for example: MachineName,ContainerName...)because containerStats do not include them\nfunc (s *redisStorage) containerStatsAndDefaultValues(cInfo *info.ContainerInfo, stats *info.ContainerStats) *detailSpec {\n\ttimestamp := stats.Timestamp.UnixNano() / 1e3\n\tvar containerName string\n\tif len(cInfo.ContainerReference.Aliases) > 0 {\n\t\tcontainerName = cInfo.ContainerReference.Aliases[0]\n\t} else {\n\t\tcontainerName = cInfo.ContainerReference.Name\n\t}\n\tdetail := &detailSpec{\n\t\tTimestamp:      timestamp,\n\t\tMachineName:    s.machineName,\n\t\tContainerName:  containerName,\n\t\tContainerStats: stats,\n\t}\n\treturn detail\n}\n\n// Push the data into redis\nfunc (s *redisStorage) AddStats(cInfo *info.ContainerInfo, stats *info.ContainerStats) error {\n\tif stats == nil {\n\t\treturn nil\n\t}\n\tvar seriesToFlush []byte\n\tfunc() {\n\t\t// AddStats will be invoked simultaneously from multiple threads and only one of them will perform a write.\n\t\ts.lock.Lock()\n\t\tdefer s.lock.Unlock()\n\t\t// Add some default params based on containerStats\n\t\tdetail := s.containerStatsAndDefaultValues(cInfo, stats)\n\t\t// To json\n\t\tb, _ := json.Marshal(detail)\n\t\tif s.readyToFlush() {\n\t\t\tseriesToFlush = b\n\t\t\ts.lastWrite = time.Now()\n\t\t}\n\t}()\n\tif len(seriesToFlush) == 0 {\n\t\treturn nil\n\t}\n\t// We use redis's \"LPUSH\" to push the data to the redis\n\treturn s.conn.Send(\"LPUSH\", s.redisKey, seriesToFlush)\n}\n\nfunc (s *redisStorage) Close() error {\n\treturn s.conn.Close()\n}\n\n// Create a new redis storage driver.\n// machineName: A unique identifier to identify the host that runs the current cAdvisor\n// instance is running on.\n// redisHost: The host which runs redis.\n// redisKey: The key for the Data that stored in the redis\nfunc newStorage(\n\tmachineName,\n\tredisKey,\n\tredisHost string,\n\tbufferDuration time.Duration,\n) (storage.StorageDriver, error) {\n\tconn, err := redis.Dial(\"tcp\", redisHost)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tret := &redisStorage{\n\t\tconn:           conn,\n\t\tmachineName:    machineName,\n\t\tredisKey:       redisKey,\n\t\tbufferDuration: bufferDuration,\n\t\tlastWrite:      time.Now(),\n\t}\n\tret.readyToFlush = ret.defaultReadyToFlush\n\treturn ret, nil\n}\n"
  },
  {
    "path": "cmd/internal/storage/statsd/client/client.go",
    "content": "// Copyright 2015 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage client\n\nimport (\n\t\"fmt\"\n\t\"net\"\n\n\t\"k8s.io/klog/v2\"\n)\n\ntype Client struct {\n\tHostPort  string\n\tNamespace string\n\tconn      net.Conn\n}\n\nfunc (c *Client) Open() error {\n\tconn, err := net.Dial(\"udp\", c.HostPort)\n\tif err != nil {\n\t\tklog.Errorf(\"failed to open udp connection to %q: %v\", c.HostPort, err)\n\t\treturn err\n\t}\n\tc.conn = conn\n\treturn nil\n}\n\nfunc (c *Client) Close() error {\n\tc.conn.Close()\n\tc.conn = nil\n\treturn nil\n}\n\n// Simple send to statsd daemon without sampling.\nfunc (c *Client) Send(namespace, containerName, key string, value uint64) error {\n\t// only send counter value\n\tformatted := fmt.Sprintf(\"%s.%s.%s:%d|g\", namespace, containerName, key, value)\n\t_, err := fmt.Fprint(c.conn, formatted)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to send data %q: %v\", formatted, err)\n\t}\n\treturn nil\n}\n\nfunc New(hostPort string) (*Client, error) {\n\tClient := Client{HostPort: hostPort}\n\tif err := Client.Open(); err != nil {\n\t\treturn nil, err\n\t}\n\treturn &Client, nil\n}\n"
  },
  {
    "path": "cmd/internal/storage/statsd/statsd.go",
    "content": "// Copyright 2015 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage statsd\n\nimport (\n\t\"strconv\"\n\n\tclient \"github.com/google/cadvisor/cmd/internal/storage/statsd/client\"\n\tinfo \"github.com/google/cadvisor/info/v1\"\n\t\"github.com/google/cadvisor/storage\"\n)\n\nfunc init() {\n\tstorage.RegisterStorageDriver(\"statsd\", new)\n}\n\ntype statsdStorage struct {\n\tclient    *client.Client\n\tNamespace string\n}\n\nconst (\n\t// Cumulative CPU usage\n\t// To be deprecated in 0.39\n\t// https://github.com/google/cadvisor/issues/2637\n\tcolCPUCumulativeUsage string = \"cpu_cumulative_usage\"\n\t// Cumulative CPU usage\n\tserCPUUsageTotal  string = \"cpu_usage_total\"\n\tserCPUUsageSystem string = \"cpu_usage_system\"\n\tserCPUUsageUser   string = \"cpu_usage_user\"\n\tserCPUUsagePerCPU string = \"cpu_usage_per_cpu\"\n\t// Smoothed average of number of runnable threads x 1000.\n\tserLoadAverage string = \"cpu_load_average\"\n\t// Memory Usage\n\tserMemoryUsage string = \"memory_usage\"\n\t// Maximum memory usage recorded\n\tserMemoryMaxUsage string = \"memory_max_usage\"\n\t// Number of bytes of page cache memory\n\tserMemoryCache string = \"memory_cache\"\n\t// Size of RSS\n\tserMemoryRss string = \"memory_rss\"\n\t// Container swap usage\n\tserMemorySwap string = \"memory_swap\"\n\t// Size of memory mapped files in bytes\n\tserMemoryMappedFile string = \"memory_mapped_file\"\n\t// Working set size\n\tserMemoryWorkingSet string = \"memory_working_set\"\n\t// Total active file size\n\tserMemoryTotalActiveFile string = \"memory_total_active_file\"\n\t// Total inactive file size\n\tserMemoryTotalInactiveFile string = \"memory_total_inactive_file\"\n\t// Number of memory usage hits limits\n\tserMemoryFailcnt string = \"memory_failcnt\"\n\t// Cumulative count of memory allocation failures\n\tserMemoryFailure string = \"memory_failure\"\n\t// Cumulative count of bytes received.\n\tserRxBytes string = \"rx_bytes\"\n\t// Cumulative count of receive errors encountered.\n\tserRxErrors string = \"rx_errors\"\n\t// Cumulative count of bytes transmitted.\n\tserTxBytes string = \"tx_bytes\"\n\t// Cumulative count of transmit errors encountered.\n\tserTxErrors string = \"tx_errors\"\n\t// Filesystem summary\n\tserFsSummary string = \"fs_summary\"\n\t// Filesystem limit.\n\tserFsLimit string = \"fs_limit\"\n\t// Filesystem usage.\n\tserFsUsage string = \"fs_usage\"\n\t// Hugetlb stat - current res_counter usage for hugetlb\n\tsetHugetlbUsage string = \"hugetlb_usage\"\n\t// Hugetlb stat - maximum usage ever recorded\n\tsetHugetlbMaxUsage string = \"hugetlb_max_usage\"\n\t// Hugetlb stat - number of times hugetlb usage allocation failure\n\tsetHugetlbFailcnt string = \"hugetlb_failcnt\"\n\t// Perf statistics\n\tserPerfStat string = \"perf_stat\"\n\t// Referenced memory\n\tserReferencedMemory string = \"referenced_memory\"\n\t// Resctrl - Total memory bandwidth\n\tserResctrlMemoryBandwidthTotal string = \"resctrl_memory_bandwidth_total\"\n\t// Resctrl - Local memory bandwidth\n\tserResctrlMemoryBandwidthLocal string = \"resctrl_memory_bandwidth_local\"\n\t// Resctrl - Last level cache usage\n\tserResctrlLLCOccupancy string = \"resctrl_llc_occupancy\"\n)\n\nfunc new() (storage.StorageDriver, error) {\n\treturn newStorage(*storage.ArgDbName, *storage.ArgDbHost)\n}\n\nfunc (s *statsdStorage) containerStatsToValues(stats *info.ContainerStats) (series map[string]uint64) {\n\tseries = make(map[string]uint64)\n\n\t// Total usage in nanoseconds\n\tseries[serCPUUsageTotal] = stats.Cpu.Usage.Total\n\n\t// To be deprecated in 0.39\n\tseries[colCPUCumulativeUsage] = series[serCPUUsageTotal]\n\n\t// CPU usage: Time spend in system space (in nanoseconds)\n\tseries[serCPUUsageSystem] = stats.Cpu.Usage.System\n\n\t// CPU usage: Time spent in user space (in nanoseconds)\n\tseries[serCPUUsageUser] = stats.Cpu.Usage.User\n\n\t// CPU usage per CPU\n\tfor i := 0; i < len(stats.Cpu.Usage.PerCpu); i++ {\n\t\tseries[serCPUUsagePerCPU+\".\"+strconv.Itoa(i)] = stats.Cpu.Usage.PerCpu[i]\n\t}\n\n\t// Load Average\n\tseries[serLoadAverage] = uint64(stats.Cpu.LoadAverage)\n\n\t// Network stats.\n\tseries[serRxBytes] = stats.Network.RxBytes\n\tseries[serRxErrors] = stats.Network.RxErrors\n\tseries[serTxBytes] = stats.Network.TxBytes\n\tseries[serTxErrors] = stats.Network.TxErrors\n\n\t// Referenced Memory\n\tseries[serReferencedMemory] = stats.ReferencedMemory\n\n\treturn series\n}\n\nfunc (s *statsdStorage) containerFsStatsToValues(series *map[string]uint64, stats *info.ContainerStats) {\n\tfor _, fsStat := range stats.Filesystem {\n\t\t// Summary stats.\n\t\t(*series)[serFsSummary+\".\"+serFsLimit] += fsStat.Limit\n\t\t(*series)[serFsSummary+\".\"+serFsUsage] += fsStat.Usage\n\n\t\t// Per device stats.\n\t\t(*series)[fsStat.Device+\".\"+serFsLimit] = fsStat.Limit\n\t\t(*series)[fsStat.Device+\".\"+serFsUsage] = fsStat.Usage\n\t}\n}\n\nfunc (s *statsdStorage) memoryStatsToValues(series *map[string]uint64, stats *info.ContainerStats) {\n\t// Memory Usage\n\t(*series)[serMemoryUsage] = stats.Memory.Usage\n\t// Maximum memory usage recorded\n\t(*series)[serMemoryMaxUsage] = stats.Memory.MaxUsage\n\t//Number of bytes of page cache memory\n\t(*series)[serMemoryCache] = stats.Memory.Cache\n\t// Size of RSS\n\t(*series)[serMemoryRss] = stats.Memory.RSS\n\t// Container swap usage\n\t(*series)[serMemorySwap] = stats.Memory.Swap\n\t// Size of memory mapped files in bytes\n\t(*series)[serMemoryMappedFile] = stats.Memory.MappedFile\n\t// Working Set Size\n\t(*series)[serMemoryWorkingSet] = stats.Memory.WorkingSet\n\t// Total Active File Size\n\t(*series)[serMemoryTotalActiveFile] = stats.Memory.TotalActiveFile\n\t// Total Inactive File Size\n\t(*series)[serMemoryTotalInactiveFile] = stats.Memory.TotalInactiveFile\n\t// Number of memory usage hits limits\n\t(*series)[serMemoryFailcnt] = stats.Memory.Failcnt\n\n\t// Cumulative count of memory allocation failures\n\t(*series)[serMemoryFailure+\".container.pgfault\"] = stats.Memory.ContainerData.Pgfault\n\t(*series)[serMemoryFailure+\".container.pgmajfault\"] = stats.Memory.ContainerData.Pgmajfault\n\t(*series)[serMemoryFailure+\".hierarchical.pgfault\"] = stats.Memory.HierarchicalData.Pgfault\n\t(*series)[serMemoryFailure+\".hierarchical.pgmajfault\"] = stats.Memory.HierarchicalData.Pgmajfault\n}\n\nfunc (s *statsdStorage) hugetlbStatsToValues(series *map[string]uint64, stats *info.ContainerStats) {\n\tfor pageSize, hugetlbStat := range stats.Hugetlb {\n\t\t(*series)[setHugetlbUsage+\".\"+pageSize] = hugetlbStat.Usage\n\t\t(*series)[setHugetlbMaxUsage+\".\"+pageSize] = hugetlbStat.MaxUsage\n\t\t(*series)[setHugetlbFailcnt+\".\"+pageSize] = hugetlbStat.Failcnt\n\t}\n}\n\nfunc (s *statsdStorage) perfStatsToValues(series *map[string]uint64, stats *info.ContainerStats) {\n\tfor _, perfStat := range stats.PerfStats {\n\t\t(*series)[serPerfStat+\".\"+perfStat.Name+\".\"+strconv.Itoa(perfStat.Cpu)] = perfStat.Value\n\t}\n}\n\nfunc (s *statsdStorage) resctrlStatsToValues(series *map[string]uint64, stats *info.ContainerStats) {\n\tfor nodeID, rdtMemoryBandwidth := range stats.Resctrl.MemoryBandwidth {\n\t\t(*series)[serResctrlMemoryBandwidthTotal+\".\"+strconv.Itoa(nodeID)] = rdtMemoryBandwidth.TotalBytes\n\t\t(*series)[serResctrlMemoryBandwidthLocal+\".\"+strconv.Itoa(nodeID)] = rdtMemoryBandwidth.LocalBytes\n\t}\n\tfor nodeID, rdtCache := range stats.Resctrl.Cache {\n\t\t(*series)[serResctrlLLCOccupancy+\".\"+strconv.Itoa(nodeID)] = rdtCache.LLCOccupancy\n\t}\n\n}\n\n// Push the data via the statsd client\nfunc (s *statsdStorage) AddStats(cInfo *info.ContainerInfo, stats *info.ContainerStats) error {\n\tif stats == nil {\n\t\treturn nil\n\t}\n\n\tseries := s.containerStatsToValues(stats)\n\ts.containerFsStatsToValues(&series, stats)\n\ts.memoryStatsToValues(&series, stats)\n\ts.hugetlbStatsToValues(&series, stats)\n\ts.perfStatsToValues(&series, stats)\n\ts.resctrlStatsToValues(&series, stats)\n\n\tvar containerName string\n\tif len(cInfo.ContainerReference.Aliases) > 0 {\n\t\tcontainerName = cInfo.ContainerReference.Aliases[0]\n\t} else {\n\t\tcontainerName = cInfo.ContainerReference.Name\n\t}\n\n\tfor key, value := range series {\n\t\terr := s.client.Send(s.Namespace, containerName, key, value)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc (s *statsdStorage) Close() error {\n\ts.client.Close()\n\ts.client = nil\n\treturn nil\n}\n\nfunc newStorage(namespace, hostPort string) (*statsdStorage, error) {\n\tstatsdClient, err := client.New(hostPort)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tstatsdStorage := &statsdStorage{\n\t\tclient:    statsdClient,\n\t\tNamespace: namespace,\n\t}\n\treturn statsdStorage, nil\n}\n"
  },
  {
    "path": "cmd/internal/storage/stdout/stdout.go",
    "content": "// Copyright 2015 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage stdout\n\nimport (\n\t\"bytes\"\n\t\"fmt\"\n\t\"strconv\"\n\t\"time\"\n\n\tinfo \"github.com/google/cadvisor/info/v1\"\n\t\"github.com/google/cadvisor/storage\"\n)\n\nfunc init() {\n\tstorage.RegisterStorageDriver(\"stdout\", new)\n}\n\ntype stdoutStorage struct {\n\tNamespace string\n}\n\nconst (\n\tserTimestamp string = \"timestamp\"\n\t// Cumulative CPU usage\n\t// To be deprecated in 0.39\n\t// https://github.com/google/cadvisor/issues/2637\n\tcolCPUCumulativeUsage string = \"cpu_cumulative_usage\"\n\t// Cumulative CPU usage\n\tserCPUUsageTotal  string = \"cpu_usage_total\"\n\tserCPUUsageSystem string = \"cpu_usage_system\"\n\tserCPUUsageUser   string = \"cpu_usage_user\"\n\tserCPUUsagePerCPU string = \"cpu_usage_per_cpu\"\n\t// Smoothed average of number of runnable threads x 1000.\n\tserLoadAverage string = \"load_average\"\n\t// Memory Usage\n\tserMemoryUsage string = \"memory_usage\"\n\t// Maximum memory usage recorded\n\tserMemoryMaxUsage string = \"memory_max_usage\"\n\t// Number of bytes of page cache memory\n\tserMemoryCache string = \"memory_cache\"\n\t// Size of RSS\n\tserMemoryRss string = \"memory_rss\"\n\t// Container swap usage\n\tserMemorySwap string = \"memory_swap\"\n\t// Size of memory mapped files in bytes\n\tserMemoryMappedFile string = \"memory_mapped_file\"\n\t// Working set size\n\tserMemoryWorkingSet string = \"memory_working_set\"\n\t// Total active file\n\tserMemoryTotalActiveFile string = \"memory_total_active_file\"\n\t// Total inactive file\n\tserMemoryTotalInactiveFile string = \"memory_total_inactive_file\"\n\t// Number of memory usage hits limits\n\tserMemoryFailcnt string = \"memory_failcnt\"\n\t// Cumulative count of memory allocation failures\n\tserMemoryFailure string = \"memory_failure\"\n\t// Cumulative count of bytes received.\n\tserRxBytes string = \"rx_bytes\"\n\t// Cumulative count of receive errors encountered.\n\tserRxErrors string = \"rx_errors\"\n\t// Cumulative count of bytes transmitted.\n\tserTxBytes string = \"tx_bytes\"\n\t// Cumulative count of transmit errors encountered.\n\tserTxErrors string = \"tx_errors\"\n\t// Filesystem summary\n\tserFsSummary string = \"fs_summary\"\n\t// Filesystem limit.\n\tserFsLimit string = \"fs_limit\"\n\t// Filesystem usage.\n\tserFsUsage string = \"fs_usage\"\n\t// Hugetlb stat - current res_counter usage for hugetlb\n\tsetHugetlbUsage string = \"hugetlb_usage\"\n\t// Hugetlb stat - maximum usage ever recorded\n\tsetHugetlbMaxUsage string = \"hugetlb_max_usage\"\n\t// Hugetlb stat - number of times hugetlb usage allocation failure\n\tsetHugetlbFailcnt string = \"hugetlb_failcnt\"\n\t// Perf statistics\n\tserPerfStat string = \"perf_stat\"\n\t// Referenced memory\n\tserReferencedMemory string = \"referenced_memory\"\n\t// Resctrl - Total memory bandwidth\n\tserResctrlMemoryBandwidthTotal string = \"resctrl_memory_bandwidth_total\"\n\t// Resctrl - Local memory bandwidth\n\tserResctrlMemoryBandwidthLocal string = \"resctrl_memory_bandwidth_local\"\n\t// Resctrl - Last level cache usage\n\tserResctrlLLCOccupancy string = \"resctrl_llc_occupancy\"\n)\n\nfunc new() (storage.StorageDriver, error) {\n\treturn newStorage(*storage.ArgDbHost)\n}\n\nfunc (driver *stdoutStorage) containerStatsToValues(stats *info.ContainerStats) (series map[string]uint64) {\n\tseries = make(map[string]uint64)\n\n\t// Unix Timestamp\n\tseries[serTimestamp] = uint64(time.Now().UnixNano())\n\n\t// Total usage in nanoseconds\n\tseries[serCPUUsageTotal] = stats.Cpu.Usage.Total\n\n\t// To be deprecated in 0.39\n\tseries[colCPUCumulativeUsage] = series[serCPUUsageTotal]\n\n\t// CPU usage: Time spend in system space (in nanoseconds)\n\tseries[serCPUUsageSystem] = stats.Cpu.Usage.System\n\n\t// CPU usage: Time spent in user space (in nanoseconds)\n\tseries[serCPUUsageUser] = stats.Cpu.Usage.User\n\n\t// CPU usage per CPU\n\tfor i := 0; i < len(stats.Cpu.Usage.PerCpu); i++ {\n\t\tseries[serCPUUsagePerCPU+\".\"+strconv.Itoa(i)] = stats.Cpu.Usage.PerCpu[i]\n\t}\n\n\t// Load Average\n\tseries[serLoadAverage] = uint64(stats.Cpu.LoadAverage)\n\n\t// Network stats.\n\tseries[serRxBytes] = stats.Network.RxBytes\n\tseries[serRxErrors] = stats.Network.RxErrors\n\tseries[serTxBytes] = stats.Network.TxBytes\n\tseries[serTxErrors] = stats.Network.TxErrors\n\n\t// Referenced Memory\n\tseries[serReferencedMemory] = stats.ReferencedMemory\n\n\treturn series\n}\n\nfunc (driver *stdoutStorage) containerFsStatsToValues(series *map[string]uint64, stats *info.ContainerStats) {\n\tfor _, fsStat := range stats.Filesystem {\n\t\t// Summary stats.\n\t\t(*series)[serFsSummary+\".\"+serFsLimit] += fsStat.Limit\n\t\t(*series)[serFsSummary+\".\"+serFsUsage] += fsStat.Usage\n\n\t\t// Per device stats.\n\t\t(*series)[fsStat.Device+\".\"+serFsLimit] = fsStat.Limit\n\t\t(*series)[fsStat.Device+\".\"+serFsUsage] = fsStat.Usage\n\t}\n}\n\nfunc (driver *stdoutStorage) memoryStatsToValues(series *map[string]uint64, stats *info.ContainerStats) {\n\t// Memory Usage\n\t(*series)[serMemoryUsage] = stats.Memory.Usage\n\t// Maximum memory usage recorded\n\t(*series)[serMemoryMaxUsage] = stats.Memory.MaxUsage\n\t//Number of bytes of page cache memory\n\t(*series)[serMemoryCache] = stats.Memory.Cache\n\t// Size of RSS\n\t(*series)[serMemoryRss] = stats.Memory.RSS\n\t// Container swap usage\n\t(*series)[serMemorySwap] = stats.Memory.Swap\n\t// Size of memory mapped files in bytes\n\t(*series)[serMemoryMappedFile] = stats.Memory.MappedFile\n\t// Working Set Size\n\t(*series)[serMemoryWorkingSet] = stats.Memory.WorkingSet\n\t// Total Active File\n\t(*series)[serMemoryTotalActiveFile] = stats.Memory.TotalActiveFile\n\t// Total Inactive File\n\t(*series)[serMemoryTotalInactiveFile] = stats.Memory.TotalInactiveFile\n\t// Number of memory usage hits limits\n\t(*series)[serMemoryFailcnt] = stats.Memory.Failcnt\n\n\t// Cumulative count of memory allocation failures\n\t(*series)[serMemoryFailure+\".container.pgfault\"] = stats.Memory.ContainerData.Pgfault\n\t(*series)[serMemoryFailure+\".container.pgmajfault\"] = stats.Memory.ContainerData.Pgmajfault\n\t(*series)[serMemoryFailure+\".hierarchical.pgfault\"] = stats.Memory.HierarchicalData.Pgfault\n\t(*series)[serMemoryFailure+\".hierarchical.pgmajfault\"] = stats.Memory.HierarchicalData.Pgmajfault\n}\n\nfunc (driver *stdoutStorage) hugetlbStatsToValues(series *map[string]uint64, stats *info.ContainerStats) {\n\tfor pageSize, hugetlbStat := range stats.Hugetlb {\n\t\t(*series)[setHugetlbUsage+\".\"+pageSize] = hugetlbStat.Usage\n\t\t(*series)[setHugetlbMaxUsage+\".\"+pageSize] = hugetlbStat.MaxUsage\n\t\t(*series)[setHugetlbFailcnt+\".\"+pageSize] = hugetlbStat.Failcnt\n\t}\n}\n\nfunc (driver *stdoutStorage) perfStatsToValues(series *map[string]uint64, stats *info.ContainerStats) {\n\tfor _, perfStat := range stats.PerfStats {\n\t\t(*series)[serPerfStat+\".\"+perfStat.Name+\".\"+strconv.Itoa(perfStat.Cpu)] = perfStat.Value\n\t}\n}\n\nfunc (driver *stdoutStorage) resctrlStatsToValues(series *map[string]uint64, stats *info.ContainerStats) {\n\tfor nodeID, rdtMemoryBandwidth := range stats.Resctrl.MemoryBandwidth {\n\t\t(*series)[serResctrlMemoryBandwidthTotal+\".\"+strconv.Itoa(nodeID)] = rdtMemoryBandwidth.TotalBytes\n\t\t(*series)[serResctrlMemoryBandwidthLocal+\".\"+strconv.Itoa(nodeID)] = rdtMemoryBandwidth.LocalBytes\n\t}\n\tfor nodeID, rdtCache := range stats.Resctrl.Cache {\n\t\t(*series)[serResctrlLLCOccupancy+\".\"+strconv.Itoa(nodeID)] = rdtCache.LLCOccupancy\n\t}\n\n}\n\nfunc (driver *stdoutStorage) AddStats(cInfo *info.ContainerInfo, stats *info.ContainerStats) error {\n\tif stats == nil {\n\t\treturn nil\n\t}\n\n\tcontainerName := cInfo.ContainerReference.Name\n\tif len(cInfo.ContainerReference.Aliases) > 0 {\n\t\tcontainerName = cInfo.ContainerReference.Aliases[0]\n\t}\n\n\tvar buffer bytes.Buffer\n\tbuffer.WriteString(fmt.Sprintf(\"cName=%s host=%s\", containerName, driver.Namespace))\n\n\tseries := driver.containerStatsToValues(stats)\n\tdriver.containerFsStatsToValues(&series, stats)\n\tdriver.memoryStatsToValues(&series, stats)\n\tdriver.hugetlbStatsToValues(&series, stats)\n\tdriver.perfStatsToValues(&series, stats)\n\tdriver.resctrlStatsToValues(&series, stats)\n\tfor key, value := range series {\n\t\tbuffer.WriteString(fmt.Sprintf(\" %s=%v\", key, value))\n\t}\n\n\t_, err := fmt.Println(buffer.String())\n\n\treturn err\n}\n\nfunc (driver *stdoutStorage) Close() error {\n\treturn nil\n}\n\nfunc newStorage(namespace string) (*stdoutStorage, error) {\n\tstdoutStorage := &stdoutStorage{\n\t\tNamespace: namespace,\n\t}\n\treturn stdoutStorage, nil\n}\n"
  },
  {
    "path": "cmd/internal/storage/test/mock.go",
    "content": "// Copyright 2014 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage test\n\nimport (\n\tinfo \"github.com/google/cadvisor/info/v1\"\n\n\t\"github.com/stretchr/testify/mock\"\n)\n\ntype MockStorageDriver struct {\n\tmock.Mock\n\tMockCloseMethod bool\n}\n\nfunc (d *MockStorageDriver) AddStats(cInfo *info.ContainerInfo, stats *info.ContainerStats) error {\n\targs := d.Called(cInfo.ContainerReference, stats)\n\treturn args.Error(0)\n}\n\nfunc (d *MockStorageDriver) Close() error {\n\tif d.MockCloseMethod {\n\t\targs := d.Called()\n\t\treturn args.Error(0)\n\t}\n\treturn nil\n}\n"
  },
  {
    "path": "cmd/internal/storage/test/storagetests.go",
    "content": "// Copyright 2014 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage test\n\nimport (\n\t\"math/rand\"\n\t\"testing\"\n\t\"time\"\n\n\tinfo \"github.com/google/cadvisor/info/v1\"\n\t\"github.com/google/cadvisor/storage\"\n)\n\ntype TestStorageDriver interface {\n\tStatsEq(a *info.ContainerStats, b *info.ContainerStats) bool\n\tstorage.StorageDriver\n}\n\nfunc buildTrace(cpu, mem []uint64, duration time.Duration) []*info.ContainerStats {\n\tif len(cpu) != len(mem) {\n\t\tpanic(\"len(cpu) != len(mem)\")\n\t}\n\n\tret := make([]*info.ContainerStats, len(cpu))\n\tcurrentTime := time.Now()\n\n\tvar cpuTotalUsage uint64 = 0\n\tfor i, cpuUsage := range cpu {\n\t\tcpuTotalUsage += cpuUsage\n\t\tstats := new(info.ContainerStats)\n\t\tstats.Timestamp = currentTime\n\t\tcurrentTime = currentTime.Add(duration)\n\n\t\tstats.Cpu.Usage.Total = cpuTotalUsage\n\t\tstats.Cpu.Usage.User = stats.Cpu.Usage.Total\n\t\tstats.Cpu.Usage.System = 0\n\t\tstats.Cpu.Usage.PerCpu = []uint64{cpuTotalUsage}\n\n\t\tstats.Memory.Usage = mem[i]\n\n\t\tstats.Network.RxBytes = uint64(rand.Intn(10000))\n\t\tstats.Network.RxErrors = uint64(rand.Intn(1000))\n\t\tstats.Network.TxBytes = uint64(rand.Intn(100000))\n\t\tstats.Network.TxErrors = uint64(rand.Intn(1000))\n\n\t\tstats.Filesystem = make([]info.FsStats, 1)\n\t\tstats.Filesystem[0].Device = \"/dev/sda1\"\n\t\tstats.Filesystem[0].Limit = 1024000000\n\t\tstats.Filesystem[0].Usage = 1024000\n\t\tret[i] = stats\n\t}\n\treturn ret\n}\n\nfunc TimeEq(t1, t2 time.Time, tolerance time.Duration) bool {\n\t// t1 should not be later than t2\n\tif t1.After(t2) {\n\t\tt1, t2 = t2, t1\n\t}\n\tdiff := t2.Sub(t1)\n\n\treturn diff <= tolerance\n}\n\n// This function will generate random stats and write\n// them into the storage. The function will not close the driver\nfunc StorageDriverFillRandomStatsFunc(\n\tcontainerName string,\n\tN int,\n\tdriver TestStorageDriver,\n\tt *testing.T,\n) {\n\tcpuTrace := make([]uint64, 0, N)\n\tmemTrace := make([]uint64, 0, N)\n\n\t// We need N+1 observations to get N samples\n\tfor i := 0; i < N+1; i++ {\n\t\tcpuTrace = append(cpuTrace, uint64(rand.Intn(1000)))\n\t\tmemTrace = append(memTrace, uint64(rand.Intn(1000)))\n\t}\n\n\tsamplePeriod := 1 * time.Second\n\n\tcInfo := info.ContainerInfo{\n\t\tContainerReference: info.ContainerReference{\n\t\t\tName: containerName,\n\t\t},\n\t}\n\n\ttrace := buildTrace(cpuTrace, memTrace, samplePeriod)\n\n\tfor _, stats := range trace {\n\t\terr := driver.AddStats(&cInfo, stats)\n\t\tif err != nil {\n\t\t\tt.Fatalf(\"unable to add stats: %v\", err)\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "cmd/storagedriver.go",
    "content": "// Copyright 2014 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage main\n\nimport (\n\t\"flag\"\n\t\"fmt\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/google/cadvisor/cache/memory\"\n\t_ \"github.com/google/cadvisor/cmd/internal/storage/bigquery\"\n\t_ \"github.com/google/cadvisor/cmd/internal/storage/elasticsearch\"\n\t_ \"github.com/google/cadvisor/cmd/internal/storage/influxdb\"\n\t_ \"github.com/google/cadvisor/cmd/internal/storage/kafka\"\n\t_ \"github.com/google/cadvisor/cmd/internal/storage/redis\"\n\t_ \"github.com/google/cadvisor/cmd/internal/storage/statsd\"\n\t_ \"github.com/google/cadvisor/cmd/internal/storage/stdout\"\n\t\"github.com/google/cadvisor/storage\"\n\n\t\"k8s.io/klog/v2\"\n)\n\nvar (\n\tstorageDriver   = flag.String(\"storage_driver\", \"\", fmt.Sprintf(\"Storage `driver` to use. Data is always cached shortly in memory, this controls where data is pushed besides the local cache. Empty means none, multiple separated by commas. Options are: <empty>, %s\", strings.Join(storage.ListDrivers(), \", \")))\n\tstorageDuration = flag.Duration(\"storage_duration\", 2*time.Minute, \"How long to keep data stored (Default: 2min).\")\n)\n\n// NewMemoryStorage creates a memory storage with an optional backend storage option.\nfunc NewMemoryStorage() (*memory.InMemoryCache, error) {\n\tbackendStorages := []storage.StorageDriver{}\n\tfor _, driver := range strings.Split(*storageDriver, \",\") {\n\t\tif driver == \"\" {\n\t\t\tcontinue\n\t\t}\n\t\tstorage, err := storage.New(driver)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tbackendStorages = append(backendStorages, storage)\n\t\tklog.V(1).Infof(\"Using backend storage type %q\", driver)\n\t}\n\tklog.V(1).Infof(\"Caching stats in memory for %v\", *storageDuration)\n\treturn memory.New(*storageDuration, backendStorages), nil\n}\n"
  },
  {
    "path": "collector/collector_manager.go",
    "content": "// Copyright 2015 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage collector\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n\t\"time\"\n\n\tv1 \"github.com/google/cadvisor/info/v1\"\n)\n\nconst metricLabelPrefix = \"io.cadvisor.metric.\"\n\ntype GenericCollectorManager struct {\n\tCollectors         []*collectorData\n\tNextCollectionTime time.Time\n}\n\ntype collectorData struct {\n\tcollector          Collector\n\tnextCollectionTime time.Time\n}\n\n// Returns a new CollectorManager that is thread-compatible.\nfunc NewCollectorManager() (CollectorManager, error) {\n\treturn &GenericCollectorManager{\n\t\tCollectors:         []*collectorData{},\n\t\tNextCollectionTime: time.Now(),\n\t}, nil\n}\n\nfunc GetCollectorConfigs(labels map[string]string) map[string]string {\n\tconfigs := map[string]string{}\n\tfor k, v := range labels {\n\t\tif strings.HasPrefix(k, metricLabelPrefix) {\n\t\t\tname := strings.TrimPrefix(k, metricLabelPrefix)\n\t\t\tconfigs[name] = v\n\t\t}\n\t}\n\treturn configs\n}\n\nfunc (cm *GenericCollectorManager) RegisterCollector(collector Collector) error {\n\tcm.Collectors = append(cm.Collectors, &collectorData{\n\t\tcollector:          collector,\n\t\tnextCollectionTime: time.Now(),\n\t})\n\treturn nil\n}\n\nfunc (cm *GenericCollectorManager) GetSpec() ([]v1.MetricSpec, error) {\n\tmetricSpec := []v1.MetricSpec{}\n\tfor _, c := range cm.Collectors {\n\t\tspecs := c.collector.GetSpec()\n\t\tmetricSpec = append(metricSpec, specs...)\n\t}\n\n\treturn metricSpec, nil\n}\n\nfunc (cm *GenericCollectorManager) Collect() (time.Time, map[string][]v1.MetricVal, error) {\n\tvar errors []error\n\n\t// Collect from all collectors that are ready.\n\tvar next time.Time\n\tmetrics := map[string][]v1.MetricVal{}\n\tfor _, c := range cm.Collectors {\n\t\tif c.nextCollectionTime.Before(time.Now()) {\n\t\t\tvar err error\n\t\t\tc.nextCollectionTime, metrics, err = c.collector.Collect(metrics)\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\n\t\t// Keep track of the next collector that will be ready.\n\t\tif next.IsZero() || next.After(c.nextCollectionTime) {\n\t\t\tnext = c.nextCollectionTime\n\t\t}\n\t}\n\tcm.NextCollectionTime = next\n\treturn next, metrics, compileErrors(errors)\n}\n\n// Make an error slice into a single error.\nfunc compileErrors(errors []error) error {\n\tif len(errors) == 0 {\n\t\treturn nil\n\t}\n\n\tres := make([]string, len(errors))\n\tfor i := range errors {\n\t\tres[i] = fmt.Sprintf(\"Error %d: %v\", i, errors[i].Error())\n\t}\n\treturn fmt.Errorf(\"%s\", strings.Join(res, \",\"))\n}\n"
  },
  {
    "path": "collector/collector_manager_test.go",
    "content": "// Copyright 2015 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage collector\n\nimport (\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/stretchr/testify/assert\"\n\n\tv1 \"github.com/google/cadvisor/info/v1\"\n)\n\ntype fakeCollector struct {\n\tnextCollectionTime time.Time\n\terr                error\n\tcollectedFrom      int\n}\n\nfunc (fc *fakeCollector) Collect(metric map[string][]v1.MetricVal) (time.Time, map[string][]v1.MetricVal, error) {\n\tfc.collectedFrom++\n\treturn fc.nextCollectionTime, metric, fc.err\n}\n\nfunc (fc *fakeCollector) Name() string {\n\treturn \"fake-collector\"\n}\n\nfunc (fc *fakeCollector) GetSpec() []v1.MetricSpec {\n\treturn []v1.MetricSpec{}\n}\n\nfunc TestCollect(t *testing.T) {\n\tcm := &GenericCollectorManager{}\n\n\tfirstTime := time.Now().Add(-time.Hour)\n\tsecondTime := time.Now().Add(time.Hour)\n\tf1 := &fakeCollector{\n\t\tnextCollectionTime: firstTime,\n\t}\n\tf2 := &fakeCollector{\n\t\tnextCollectionTime: secondTime,\n\t}\n\n\tassert := assert.New(t)\n\tassert.NoError(cm.RegisterCollector(f1))\n\tassert.NoError(cm.RegisterCollector(f2))\n\n\t// First collection, everyone gets collected from.\n\tnextTime, _, err := cm.Collect()\n\tassert.Equal(firstTime, nextTime)\n\tassert.NoError(err)\n\tassert.Equal(1, f1.collectedFrom)\n\tassert.Equal(1, f2.collectedFrom)\n\n\tf1.nextCollectionTime = time.Now().Add(2 * time.Hour)\n\n\t// Second collection, only the one that is ready gets collected from.\n\tnextTime, _, err = cm.Collect()\n\tassert.Equal(secondTime, nextTime)\n\tassert.NoError(err)\n\tassert.Equal(2, f1.collectedFrom)\n\tassert.Equal(1, f2.collectedFrom)\n}\n"
  },
  {
    "path": "collector/config/sample_config.json",
    "content": "{\n\t\"endpoint\" : \"http://localhost:8000/nginx_status\",\n\t\"metrics_config\"  : [\n\t\t{ \"name\" : \"activeConnections\",  \n\t\t  \"metric_type\" : \"gauge\",\n\t\t  \"units\" : \"number of active connections\",\n\t\t  \"data_type\" : \"int\",\n\t\t  \"polling_frequency\" : 10,\n\t\t  \"regex\" : \"Active connections: ([0-9]+)\"\t\t\t\n\t\t},\n\t\t{ \"name\" : \"reading\",\n\t\t  \"metric_type\" : \"gauge\", \n\t\t  \"units\" : \"number of reading connections\",\n\t\t  \"data_type\" : \"int\",\n\t\t  \"polling_frequency\" : 10,\n\t\t  \"regex\" : \"Reading: ([0-9]+) .*\"\t\n\t\t},\n\t\t{ \"name\" : \"writing\",\n                  \"metric_type\" : \"gauge\",\n                  \"data_type\" : \"int\",\n\t\t  \"units\" : \"number of writing connections\",\n                  \"polling_frequency\" : 10,\n                  \"regex\" : \".*Writing: ([0-9]+).*\"\n                },\n\t\t{ \"name\" : \"waiting\",\n                  \"metric_type\" : \"gauge\",\n                  \"units\" : \"number of waiting connections\",\n\t\t  \"data_type\" : \"int\",\n                  \"polling_frequency\" : 10,\n                  \"regex\" : \".*Waiting: ([0-9]+)\"\n                }\n\t] \t\n\t\n}\n"
  },
  {
    "path": "collector/config/sample_config_endpoint_config.json",
    "content": "{\n  \"endpoint\" : {\n    \"protocol\": \"https\",\n    \"port\": 8000,\n    \"path\": \"/nginx_status\"\n  },\n  \"metrics_config\"  : [\n    { \"name\" : \"activeConnections\",\n      \"metric_type\" : \"gauge\",\n      \"units\" : \"number of active connections\",\n      \"data_type\" : \"int\",\n      \"polling_frequency\" : 10,\n      \"regex\" : \"Active connections: ([0-9]+)\"\n    },\n    { \"name\" : \"reading\",\n      \"metric_type\" : \"gauge\",\n      \"units\" : \"number of reading connections\",\n      \"data_type\" : \"int\",\n      \"polling_frequency\" : 10,\n      \"regex\" : \"Reading: ([0-9]+) .*\"\n    },\n    { \"name\" : \"writing\",\n      \"metric_type\" : \"gauge\",\n      \"data_type\" : \"int\",\n      \"units\" : \"number of writing connections\",\n      \"polling_frequency\" : 10,\n      \"regex\" : \".*Writing: ([0-9]+).*\"\n    },\n    { \"name\" : \"waiting\",\n      \"metric_type\" : \"gauge\",\n      \"units\" : \"number of waiting connections\",\n      \"data_type\" : \"int\",\n      \"polling_frequency\" : 10,\n      \"regex\" : \".*Waiting: ([0-9]+)\"\n    }\n  ]\n\n}\n"
  },
  {
    "path": "collector/config/sample_config_prometheus.json",
    "content": "{\n        \"endpoint\" : \"http://localhost:8080/metrics\",\n\t\"polling_frequency\" : 10, \n        \"metrics_config\" : [\n        ]\n}\n"
  },
  {
    "path": "collector/config/sample_config_prometheus_endpoint_config.json",
    "content": "{\n  \"endpoint\" : {\n    \"protocol\": \"http\",\n    \"port\": 8081,\n    \"path\": \"/METRICS\"\n  },\n  \"polling_frequency\" : 10,\n  \"metrics_config\" : [\n  ]\n}"
  },
  {
    "path": "collector/config/sample_config_prometheus_filtered.json",
    "content": "{\n        \"endpoint\" : \"http://localhost:8080/metrics\",\n        \"polling_frequency\" : 10,\n        \"metrics_config\" : [\n            \"go_goroutines\",\n            \"qps\"\n        ]\n}\n\n"
  },
  {
    "path": "collector/config.go",
    "content": "// Copyright 2015 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage collector\n\nimport (\n\t\"time\"\n\n\t\"encoding/json\"\n\n\tv1 \"github.com/google/cadvisor/info/v1\"\n)\n\ntype Config struct {\n\t// the endpoint to hit to scrape metrics\n\tEndpoint EndpointConfig `json:\"endpoint\"`\n\n\t// holds information about different metrics that can be collected\n\tMetricsConfig []MetricConfig `json:\"metrics_config\"`\n}\n\n// metricConfig holds information extracted from the config file about a metric\ntype MetricConfig struct {\n\t// the name of the metric\n\tName string `json:\"name\"`\n\n\t// enum type for the metric type\n\tMetricType v1.MetricType `json:\"metric_type\"`\n\n\t// metric units to display on UI and in storage (eg: MB, cores)\n\t// this is only used for display.\n\tUnits string `json:\"units\"`\n\n\t// data type of the metric (eg: int, float)\n\tDataType v1.DataType `json:\"data_type\"`\n\n\t// the frequency at which the metric should be collected\n\tPollingFrequency time.Duration `json:\"polling_frequency\"`\n\n\t// the regular expression that can be used to extract the metric\n\tRegex string `json:\"regex\"`\n}\n\ntype Prometheus struct {\n\t// the endpoint to hit to scrape metrics\n\tEndpoint EndpointConfig `json:\"endpoint\"`\n\n\t// the frequency at which metrics should be collected\n\tPollingFrequency time.Duration `json:\"polling_frequency\"`\n\n\t// holds names of different metrics that can be collected\n\tMetricsConfig []string `json:\"metrics_config\"`\n}\n\ntype EndpointConfig struct {\n\t// The full URL of the endpoint to reach\n\tURL string\n\t// A configuration in which an actual URL is constructed from, using the container's ip address\n\tURLConfig URLConfig\n}\n\ntype URLConfig struct {\n\t// the protocol to use for connecting to the endpoint. Eg 'http' or 'https'\n\tProtocol string `json:\"protocol\"`\n\n\t// the port to use for connecting to the endpoint. Eg '8778'\n\tPort json.Number `json:\"port\"`\n\n\t// the path to use for the endpoint. Eg '/metrics'\n\tPath string `json:\"path\"`\n}\n\nfunc (ec *EndpointConfig) UnmarshalJSON(b []byte) error {\n\turl := \"\"\n\tconfig := URLConfig{\n\t\tProtocol: \"http\",\n\t\tPort:     \"8000\",\n\t}\n\n\tif err := json.Unmarshal(b, &url); err == nil {\n\t\tec.URL = url\n\t\treturn nil\n\t}\n\terr := json.Unmarshal(b, &config)\n\tif err == nil {\n\t\tec.URLConfig = config\n\t\treturn nil\n\t}\n\treturn err\n}\n"
  },
  {
    "path": "collector/fakes.go",
    "content": "// Copyright 2015 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage collector\n\nimport (\n\t\"time\"\n\n\tv1 \"github.com/google/cadvisor/info/v1\"\n)\n\ntype FakeCollectorManager struct {\n}\n\nfunc (fkm *FakeCollectorManager) RegisterCollector(collector Collector) error {\n\treturn nil\n}\n\nfunc (fkm *FakeCollectorManager) GetSpec() ([]v1.MetricSpec, error) {\n\treturn []v1.MetricSpec{}, nil\n}\n\nfunc (fkm *FakeCollectorManager) Collect(metric map[string][]v1.MetricVal) (time.Time, map[string][]v1.MetricVal, error) {\n\tvar zero time.Time\n\treturn zero, metric, nil\n}\n"
  },
  {
    "path": "collector/generic_collector.go",
    "content": "// Copyright 2015 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage collector\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"regexp\"\n\t\"strconv\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/google/cadvisor/container\"\n\tv1 \"github.com/google/cadvisor/info/v1\"\n)\n\ntype GenericCollector struct {\n\t// name of the collector\n\tname string\n\n\t// holds information extracted from the config file for a collector\n\tconfigFile Config\n\n\t// holds information necessary to extract metrics\n\tinfo *collectorInfo\n\n\t// The Http client to use when connecting to metric endpoints\n\thttpClient *http.Client\n}\n\ntype collectorInfo struct {\n\t// minimum polling frequency among all metrics\n\tminPollingFrequency time.Duration\n\n\t// regular expresssions for all metrics\n\tregexps []*regexp.Regexp\n\n\t// Limit for the number of srcaped metrics. If the count is higher,\n\t// no metrics will be returned.\n\tmetricCountLimit int\n}\n\n// Returns a new collector using the information extracted from the configfile\nfunc NewCollector(collectorName string, configFile []byte, metricCountLimit int, containerHandler container.ContainerHandler, httpClient *http.Client) (*GenericCollector, error) {\n\tvar configInJSON Config\n\terr := json.Unmarshal(configFile, &configInJSON)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tconfigInJSON.Endpoint.configure(containerHandler)\n\n\t// TODO : Add checks for validity of config file (eg : Accurate JSON fields)\n\n\tif len(configInJSON.MetricsConfig) == 0 {\n\t\treturn nil, fmt.Errorf(\"no metrics provided in config\")\n\t}\n\n\tminPollFrequency := time.Duration(0)\n\tregexprs := make([]*regexp.Regexp, len(configInJSON.MetricsConfig))\n\n\tfor ind, metricConfig := range configInJSON.MetricsConfig {\n\t\t// Find the minimum specified polling frequency in metric config.\n\t\tif metricConfig.PollingFrequency != 0 {\n\t\t\tif minPollFrequency == 0 || metricConfig.PollingFrequency < minPollFrequency {\n\t\t\t\tminPollFrequency = metricConfig.PollingFrequency\n\t\t\t}\n\t\t}\n\n\t\tregexprs[ind], err = regexp.Compile(metricConfig.Regex)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"invalid regexp %v for metric %v\", metricConfig.Regex, metricConfig.Name)\n\t\t}\n\t}\n\n\t// Minimum supported polling frequency is 1s.\n\tminSupportedFrequency := 1 * time.Second\n\tif minPollFrequency < minSupportedFrequency {\n\t\tminPollFrequency = minSupportedFrequency\n\t}\n\n\tif len(configInJSON.MetricsConfig) > metricCountLimit {\n\t\treturn nil, fmt.Errorf(\"too many metrics defined: %d limit: %d\", len(configInJSON.MetricsConfig), metricCountLimit)\n\t}\n\n\treturn &GenericCollector{\n\t\tname:       collectorName,\n\t\tconfigFile: configInJSON,\n\t\tinfo: &collectorInfo{\n\t\t\tminPollingFrequency: minPollFrequency,\n\t\t\tregexps:             regexprs,\n\t\t\tmetricCountLimit:    metricCountLimit,\n\t\t},\n\t\thttpClient: httpClient,\n\t}, nil\n}\n\n// Returns name of the collector\nfunc (collector *GenericCollector) Name() string {\n\treturn collector.name\n}\n\nfunc (collector *GenericCollector) configToSpec(config MetricConfig) v1.MetricSpec {\n\treturn v1.MetricSpec{\n\t\tName:   config.Name,\n\t\tType:   config.MetricType,\n\t\tFormat: config.DataType,\n\t\tUnits:  config.Units,\n\t}\n}\n\nfunc (collector *GenericCollector) GetSpec() []v1.MetricSpec {\n\tspecs := []v1.MetricSpec{}\n\tfor _, metricConfig := range collector.configFile.MetricsConfig {\n\t\tspec := collector.configToSpec(metricConfig)\n\t\tspecs = append(specs, spec)\n\t}\n\treturn specs\n}\n\n// Returns collected metrics and the next collection time of the collector\nfunc (collector *GenericCollector) Collect(metrics map[string][]v1.MetricVal) (time.Time, map[string][]v1.MetricVal, error) {\n\tcurrentTime := time.Now()\n\tnextCollectionTime := currentTime.Add(time.Duration(collector.info.minPollingFrequency))\n\n\turi := collector.configFile.Endpoint.URL\n\tresponse, err := collector.httpClient.Get(uri)\n\tif err != nil {\n\t\treturn nextCollectionTime, nil, err\n\t}\n\n\tdefer response.Body.Close()\n\n\tpageContent, err := io.ReadAll(response.Body)\n\tif err != nil {\n\t\treturn nextCollectionTime, nil, err\n\t}\n\n\tvar errorSlice []error\n\n\tfor ind, metricConfig := range collector.configFile.MetricsConfig {\n\t\tmatchString := collector.info.regexps[ind].FindStringSubmatch(string(pageContent))\n\t\tif matchString != nil {\n\t\t\tif metricConfig.DataType == v1.FloatType {\n\t\t\t\tregVal, err := strconv.ParseFloat(strings.TrimSpace(matchString[1]), 64)\n\t\t\t\tif err != nil {\n\t\t\t\t\terrorSlice = append(errorSlice, err)\n\t\t\t\t}\n\t\t\t\tmetrics[metricConfig.Name] = []v1.MetricVal{\n\t\t\t\t\t{FloatValue: regVal, Timestamp: currentTime},\n\t\t\t\t}\n\t\t\t} else if metricConfig.DataType == v1.IntType {\n\t\t\t\tregVal, err := strconv.ParseInt(strings.TrimSpace(matchString[1]), 10, 64)\n\t\t\t\tif err != nil {\n\t\t\t\t\terrorSlice = append(errorSlice, err)\n\t\t\t\t}\n\t\t\t\tmetrics[metricConfig.Name] = []v1.MetricVal{\n\t\t\t\t\t{IntValue: regVal, Timestamp: currentTime},\n\t\t\t\t}\n\n\t\t\t} else {\n\t\t\t\terrorSlice = append(errorSlice, fmt.Errorf(\"unexpected value of 'data_type' for metric '%v' in config \", metricConfig.Name))\n\t\t\t}\n\t\t} else {\n\t\t\terrorSlice = append(errorSlice, fmt.Errorf(\"no match found for regexp: %v for metric '%v' in config\", metricConfig.Regex, metricConfig.Name))\n\t\t}\n\t}\n\treturn nextCollectionTime, metrics, compileErrors(errorSlice)\n}\n"
  },
  {
    "path": "collector/generic_collector_test.go",
    "content": "// Copyright 2015 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage collector\n\nimport (\n\t\"fmt\"\n\t\"net/http\"\n\t\"net/http/httptest\"\n\t\"os\"\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/assert\"\n\n\tcontainertest \"github.com/google/cadvisor/container/testing\"\n\tv1 \"github.com/google/cadvisor/info/v1\"\n)\n\nfunc TestEmptyConfig(t *testing.T) {\n\tassert := assert.New(t)\n\n\temptyConfig := `\n        {\n                \"endpoint\" : \"http://localhost:8000/nginx_status\",\n                \"metrics_config\"  : [\n                ]\n        }\n        `\n\n\t// Create a temporary config file 'temp.json' with invalid json format\n\tassert.NoError(os.WriteFile(\"temp.json\", []byte(emptyConfig), 0777))\n\n\tconfigFile, err := os.ReadFile(\"temp.json\")\n\tassert.NoError(err)\n\n\tcontainerHandler := containertest.NewMockContainerHandler(\"mockContainer\")\n\t_, err = NewCollector(\"tempCollector\", configFile, 100, containerHandler, http.DefaultClient)\n\tassert.Error(err)\n\n\tassert.NoError(os.Remove(\"temp.json\"))\n}\n\nfunc TestConfigWithErrors(t *testing.T) {\n\tassert := assert.New(t)\n\n\t// Syntax error: Missed '\"' after activeConnections\n\tinvalid := `\n\t{\n\t\t\"endpoint\" : \"http://localhost:8000/nginx_status\",\n\t\t\"metrics_config\"  : [\n\t\t\t{\n\t\t\t\t \"name\" : \"activeConnections,  \n\t\t  \t\t \"metric_type\" : \"gauge\",\n\t\t \t \t \"data_type\" : \"int\",\n\t\t  \t\t \"polling_frequency\" : 10,\n\t\t    \t\t \"regex\" : \"Active connections: ([0-9]+)\"\t\t\t\n\t\t\t}\n\t\t]\n\t}\n\t`\n\n\t// Create a temporary config file 'temp.json' with invalid json format\n\tassert.NoError(os.WriteFile(\"temp.json\", []byte(invalid), 0777))\n\tconfigFile, err := os.ReadFile(\"temp.json\")\n\tassert.NoError(err)\n\n\tcontainerHandler := containertest.NewMockContainerHandler(\"mockContainer\")\n\t_, err = NewCollector(\"tempCollector\", configFile, 100, containerHandler, http.DefaultClient)\n\tassert.Error(err)\n\n\tassert.NoError(os.Remove(\"temp.json\"))\n}\n\nfunc TestConfigWithRegexErrors(t *testing.T) {\n\tassert := assert.New(t)\n\n\t// Error: Missed operand for '+' in activeConnections regex\n\tinvalid := `\n        {\n                \"endpoint\" : \"host:port/nginx_status\",\n                \"metrics_config\"  : [\n                        {\n                                 \"name\" : \"activeConnections\",\n                                 \"metric_type\" : \"gauge\",\n                                 \"data_type\" : \"int\",\n                                 \"polling_frequency\" : 10,\n                                 \"regex\" : \"Active connections: (+)\"\n                        },\n                        {\n                                 \"name\" : \"reading\",\n                                 \"metric_type\" : \"gauge\",\n                                 \"data_type\" : \"int\",\n                                 \"polling_frequency\" : 10,\n                                 \"regex\" : \"Reading: ([0-9]+) .*\"\n                        }\n                ]\n        }\n        `\n\n\t// Create a temporary config file 'temp.json'\n\tassert.NoError(os.WriteFile(\"temp.json\", []byte(invalid), 0777))\n\n\tconfigFile, err := os.ReadFile(\"temp.json\")\n\tassert.NoError(err)\n\n\tcontainerHandler := containertest.NewMockContainerHandler(\"mockContainer\")\n\t_, err = NewCollector(\"tempCollector\", configFile, 100, containerHandler, http.DefaultClient)\n\tassert.Error(err)\n\n\tassert.NoError(os.Remove(\"temp.json\"))\n}\n\nfunc TestConfig(t *testing.T) {\n\tassert := assert.New(t)\n\n\t// Create an nginx collector using the config file 'sample_config.json'\n\tconfigFile, err := os.ReadFile(\"config/sample_config.json\")\n\tassert.NoError(err)\n\n\tcontainerHandler := containertest.NewMockContainerHandler(\"mockContainer\")\n\tcollector, err := NewCollector(\"nginx\", configFile, 100, containerHandler, http.DefaultClient)\n\tassert.NoError(err)\n\tassert.Equal(collector.name, \"nginx\")\n\tassert.Equal(collector.configFile.Endpoint.URL, \"http://localhost:8000/nginx_status\")\n\tassert.Equal(collector.configFile.MetricsConfig[0].Name, \"activeConnections\")\n}\n\nfunc TestEndpointConfig(t *testing.T) {\n\tassert := assert.New(t)\n\tconfigFile, err := os.ReadFile(\"config/sample_config_endpoint_config.json\")\n\tassert.NoError(err)\n\n\tcontainerHandler := containertest.NewMockContainerHandler(\"mockContainer\")\n\tcontainerHandler.On(\"GetContainerIPAddress\").Return(\n\t\t\"111.111.111.111\",\n\t)\n\n\tcollector, err := NewCollector(\"nginx\", configFile, 100, containerHandler, http.DefaultClient)\n\tassert.NoError(err)\n\tassert.Equal(collector.name, \"nginx\")\n\tassert.Equal(collector.configFile.Endpoint.URL, \"https://111.111.111.111:8000/nginx_status\")\n\tassert.Equal(collector.configFile.MetricsConfig[0].Name, \"activeConnections\")\n}\n\nfunc TestMetricCollection(t *testing.T) {\n\tassert := assert.New(t)\n\n\t// Collect nginx metrics from a fake nginx endpoint\n\tconfigFile, err := os.ReadFile(\"config/sample_config.json\")\n\tassert.NoError(err)\n\n\tcontainerHandler := containertest.NewMockContainerHandler(\"mockContainer\")\n\tfakeCollector, err := NewCollector(\"nginx\", configFile, 100, containerHandler, http.DefaultClient)\n\tassert.NoError(err)\n\n\ttempServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {\n\t\tfmt.Fprintln(w, \"Active connections: 3\\nserver accepts handled requests\")\n\t\tfmt.Fprintln(w, \"5 5 32\\nReading: 0 Writing: 1 Waiting: 2\")\n\t}))\n\tdefer tempServer.Close()\n\tfakeCollector.configFile.Endpoint.URL = tempServer.URL\n\n\tmetrics := map[string][]v1.MetricVal{}\n\t_, metrics, errMetric := fakeCollector.Collect(metrics)\n\tassert.NoError(errMetric)\n\tmetricNames := []string{\"activeConnections\", \"reading\", \"writing\", \"waiting\"}\n\t// activeConnections = 3\n\tassert.Equal(metrics[metricNames[0]][0].IntValue, int64(3))\n\tassert.Equal(metrics[metricNames[0]][0].FloatValue, float64(0))\n\t// reading = 0\n\tassert.Equal(metrics[metricNames[1]][0].IntValue, int64(0))\n\tassert.Equal(metrics[metricNames[1]][0].FloatValue, float64(0))\n\t// writing = 1\n\tassert.Equal(metrics[metricNames[2]][0].IntValue, int64(1))\n\tassert.Equal(metrics[metricNames[2]][0].FloatValue, float64(0))\n\t// waiting = 2\n\tassert.Equal(metrics[metricNames[3]][0].IntValue, int64(2))\n\tassert.Equal(metrics[metricNames[3]][0].FloatValue, float64(0))\n}\n\nfunc TestMetricCollectionLimit(t *testing.T) {\n\tassert := assert.New(t)\n\n\t// Collect nginx metrics from a fake nginx endpoint\n\tconfigFile, err := os.ReadFile(\"config/sample_config.json\")\n\tassert.NoError(err)\n\n\tcontainerHandler := containertest.NewMockContainerHandler(\"mockContainer\")\n\t_, err = NewCollector(\"nginx\", configFile, 1, containerHandler, http.DefaultClient)\n\tassert.Error(err)\n}\n"
  },
  {
    "path": "collector/prometheus_collector.go",
    "content": "// Copyright 2015 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage collector\n\nimport (\n\t\"bytes\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"sort\"\n\t\"time\"\n\n\trawmodel \"github.com/prometheus/client_model/go\"\n\t\"github.com/prometheus/common/expfmt\"\n\t\"github.com/prometheus/common/model\"\n\n\t\"github.com/google/cadvisor/container\"\n\tv1 \"github.com/google/cadvisor/info/v1\"\n)\n\ntype PrometheusCollector struct {\n\t// name of the collector\n\tname string\n\n\t// rate at which metrics are collected\n\tpollingFrequency time.Duration\n\n\t// holds information extracted from the config file for a collector\n\tconfigFile Prometheus\n\n\t// the metrics to gather (uses a map as a set)\n\tmetricsSet map[string]bool\n\n\t// Limit for the number of scaped metrics. If the count is higher,\n\t// no metrics will be returned.\n\tmetricCountLimit int\n\n\t// The Http client to use when connecting to metric endpoints\n\thttpClient *http.Client\n}\n\n// Returns a new collector using the information extracted from the configfile\nfunc NewPrometheusCollector(collectorName string, configFile []byte, metricCountLimit int, containerHandler container.ContainerHandler, httpClient *http.Client) (*PrometheusCollector, error) {\n\tvar configInJSON Prometheus\n\terr := json.Unmarshal(configFile, &configInJSON)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tconfigInJSON.Endpoint.configure(containerHandler)\n\n\tminPollingFrequency := configInJSON.PollingFrequency\n\n\t// Minimum supported frequency is 1s\n\tminSupportedFrequency := 1 * time.Second\n\n\tif minPollingFrequency < minSupportedFrequency {\n\t\tminPollingFrequency = minSupportedFrequency\n\t}\n\n\tif metricCountLimit < 0 {\n\t\treturn nil, fmt.Errorf(\"metric count limit must be greater than or equal to 0\")\n\t}\n\n\tvar metricsSet map[string]bool\n\tif len(configInJSON.MetricsConfig) > 0 {\n\t\tmetricsSet = make(map[string]bool, len(configInJSON.MetricsConfig))\n\t\tfor _, name := range configInJSON.MetricsConfig {\n\t\t\tmetricsSet[name] = true\n\t\t}\n\t}\n\n\tif len(configInJSON.MetricsConfig) > metricCountLimit {\n\t\treturn nil, fmt.Errorf(\"too many metrics defined: %d limit %d\", len(configInJSON.MetricsConfig), metricCountLimit)\n\t}\n\n\t// TODO : Add checks for validity of config file (eg : Accurate JSON fields)\n\treturn &PrometheusCollector{\n\t\tname:             collectorName,\n\t\tpollingFrequency: minPollingFrequency,\n\t\tconfigFile:       configInJSON,\n\t\tmetricsSet:       metricsSet,\n\t\tmetricCountLimit: metricCountLimit,\n\t\thttpClient:       httpClient,\n\t}, nil\n}\n\n// Returns name of the collector\nfunc (collector *PrometheusCollector) Name() string {\n\treturn collector.name\n}\n\nfunc (collector *PrometheusCollector) GetSpec() []v1.MetricSpec {\n\n\tresponse, err := collector.httpClient.Get(collector.configFile.Endpoint.URL)\n\tif err != nil {\n\t\treturn nil\n\t}\n\tdefer response.Body.Close()\n\n\tif response.StatusCode != http.StatusOK {\n\t\treturn nil\n\t}\n\n\tdec := expfmt.NewDecoder(response.Body, expfmt.ResponseFormat(response.Header))\n\n\tvar specs []v1.MetricSpec\n\n\tfor {\n\t\td := rawmodel.MetricFamily{}\n\t\tif err = dec.Decode(&d); err != nil {\n\t\t\tbreak\n\t\t}\n\t\tname := d.GetName()\n\t\tif len(name) == 0 {\n\t\t\tcontinue\n\t\t}\n\t\t// If metrics to collect is specified, skip any metrics not in the list to collect.\n\t\tif _, ok := collector.metricsSet[name]; collector.metricsSet != nil && !ok {\n\t\t\tcontinue\n\t\t}\n\n\t\tspec := v1.MetricSpec{\n\t\t\tName:   name,\n\t\t\tType:   metricType(d.GetType()),\n\t\t\tFormat: v1.FloatType,\n\t\t}\n\t\tspecs = append(specs, spec)\n\t}\n\n\tif err != nil && err != io.EOF {\n\t\treturn nil\n\t}\n\n\treturn specs\n}\n\n// metricType converts Prometheus metric type to cadvisor metric type.\n// If there is no mapping then just return the name of the Prometheus metric type.\nfunc metricType(t rawmodel.MetricType) v1.MetricType {\n\tswitch t {\n\tcase rawmodel.MetricType_COUNTER:\n\t\treturn v1.MetricCumulative\n\tcase rawmodel.MetricType_GAUGE:\n\t\treturn v1.MetricGauge\n\tdefault:\n\t\treturn v1.MetricType(t.String())\n\t}\n}\n\ntype prometheusLabels []*rawmodel.LabelPair\n\nfunc labelSetToLabelPairs(labels model.Metric) prometheusLabels {\n\tvar promLabels prometheusLabels\n\tfor k, v := range labels {\n\t\tname := string(k)\n\t\tvalue := string(v)\n\t\tpromLabels = append(promLabels, &rawmodel.LabelPair{Name: &name, Value: &value})\n\t}\n\treturn promLabels\n}\n\nfunc (s prometheusLabels) Len() int      { return len(s) }\nfunc (s prometheusLabels) Swap(i, j int) { s[i], s[j] = s[j], s[i] }\n\n// ByName implements sort.Interface by providing Less and using the Len and\n// Swap methods of the embedded PrometheusLabels value.\ntype byName struct{ prometheusLabels }\n\nfunc (s byName) Less(i, j int) bool {\n\treturn s.prometheusLabels[i].GetName() < s.prometheusLabels[j].GetName()\n}\n\nfunc prometheusLabelSetToCadvisorLabels(promLabels model.Metric) map[string]string {\n\tlabels := make(map[string]string)\n\tfor k, v := range promLabels {\n\t\tif string(k) == \"__name__\" {\n\t\t\tcontinue\n\t\t}\n\t\tlabels[string(k)] = string(v)\n\t}\n\treturn labels\n}\n\nfunc prometheusLabelSetToCadvisorLabel(promLabels model.Metric) string {\n\tlabels := labelSetToLabelPairs(promLabels)\n\tsort.Sort(byName{labels})\n\tvar b bytes.Buffer\n\n\tfor i, l := range labels {\n\t\tif i > 0 {\n\t\t\tb.WriteString(\"\\xff\")\n\t\t}\n\t\tb.WriteString(l.GetName())\n\t\tb.WriteString(\"=\")\n\t\tb.WriteString(l.GetValue())\n\t}\n\n\treturn b.String()\n}\n\n// Returns collected metrics and the next collection time of the collector\nfunc (collector *PrometheusCollector) Collect(metrics map[string][]v1.MetricVal) (time.Time, map[string][]v1.MetricVal, error) {\n\tcurrentTime := time.Now()\n\tnextCollectionTime := currentTime.Add(time.Duration(collector.pollingFrequency))\n\n\turi := collector.configFile.Endpoint.URL\n\tresponse, err := collector.httpClient.Get(uri)\n\tif err != nil {\n\t\treturn nextCollectionTime, nil, err\n\t}\n\tdefer response.Body.Close()\n\n\tif response.StatusCode != http.StatusOK {\n\t\treturn nextCollectionTime, nil, fmt.Errorf(\"server returned HTTP status %s\", response.Status)\n\t}\n\n\tsdec := expfmt.SampleDecoder{\n\t\tDec: expfmt.NewDecoder(response.Body, expfmt.ResponseFormat(response.Header)),\n\t\tOpts: &expfmt.DecodeOptions{\n\t\t\tTimestamp: model.TimeFromUnixNano(currentTime.UnixNano()),\n\t\t},\n\t}\n\n\tvar (\n\t\t// 50 is chosen as a reasonable guesstimate at a number of metrics we can\n\t\t// expect from virtually any endpoint to try to save allocations.\n\t\tdecSamples = make(model.Vector, 0, 50)\n\t\tnewMetrics = make(map[string][]v1.MetricVal)\n\t)\n\tfor {\n\t\tif err = sdec.Decode(&decSamples); err != nil {\n\t\t\tbreak\n\t\t}\n\n\t\tfor _, sample := range decSamples {\n\t\t\tmetName := string(sample.Metric[model.MetricNameLabel])\n\t\t\tif len(metName) == 0 {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\t// If metrics to collect is specified, skip any metrics not in the list to collect.\n\t\t\tif _, ok := collector.metricsSet[metName]; collector.metricsSet != nil && !ok {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\t// TODO Handle multiple labels nicer. Prometheus metrics can have multiple\n\t\t\t// labels, cadvisor only accepts a single string for the metric label.\n\t\t\tlabel := prometheusLabelSetToCadvisorLabel(sample.Metric)\n\t\t\tlabels := prometheusLabelSetToCadvisorLabels(sample.Metric)\n\n\t\t\tmetric := v1.MetricVal{\n\t\t\t\tFloatValue: float64(sample.Value),\n\t\t\t\tTimestamp:  sample.Timestamp.Time(),\n\t\t\t\tLabel:      label,\n\t\t\t\tLabels:     labels,\n\t\t\t}\n\t\t\tnewMetrics[metName] = append(newMetrics[metName], metric)\n\t\t\tif len(newMetrics) > collector.metricCountLimit {\n\t\t\t\treturn nextCollectionTime, nil, fmt.Errorf(\"too many metrics to collect\")\n\t\t\t}\n\t\t}\n\t\tdecSamples = decSamples[:0]\n\t}\n\n\tif err != nil && err != io.EOF {\n\t\treturn nextCollectionTime, nil, err\n\t}\n\n\tfor key, val := range newMetrics {\n\t\tmetrics[key] = append(metrics[key], val...)\n\t}\n\n\treturn nextCollectionTime, metrics, nil\n}\n"
  },
  {
    "path": "collector/prometheus_collector_test.go",
    "content": "// Copyright 2015 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage collector\n\nimport (\n\t\"fmt\"\n\t\"net/http\"\n\t\"net/http/httptest\"\n\t\"os\"\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/assert\"\n\t\"github.com/stretchr/testify/require\"\n\n\tcontainertest \"github.com/google/cadvisor/container/testing\"\n\tv1 \"github.com/google/cadvisor/info/v1\"\n)\n\nfunc TestPrometheus(t *testing.T) {\n\tassert := assert.New(t)\n\n\t// Create a prometheus collector using the config file 'sample_config_prometheus.json'\n\tconfigFile, err := os.ReadFile(\"config/sample_config_prometheus.json\")\n\tassert.NoError(err)\n\tcontainerHandler := containertest.NewMockContainerHandler(\"mockContainer\")\n\tcollector, err := NewPrometheusCollector(\"Prometheus\", configFile, 100, containerHandler, http.DefaultClient)\n\tassert.NoError(err)\n\tassert.Equal(\"Prometheus\", collector.name)\n\tassert.Equal(\"http://localhost:8080/metrics\", collector.configFile.Endpoint.URL)\n\n\ttempServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {\n\n\t\ttext := `# HELP go_gc_duration_seconds A summary of the GC invocation durations.\n# TYPE go_gc_duration_seconds summary\ngo_gc_duration_seconds{quantile=\"0\"} 5.8348000000000004e-05\ngo_gc_duration_seconds{quantile=\"1\"} 0.000499764\ngo_gc_duration_seconds_sum 1.7560473e+07\ngo_gc_duration_seconds_count 2693\n# HELP go_goroutines Number of goroutines that currently exist.\n# TYPE go_goroutines gauge\ngo_goroutines 16\n# HELP empty_metric A metric without any values\n# TYPE empty_metric counter\n# HELP metric_with_spaces_in_label A metric with spaces in a label.\n# TYPE metric_with_spaces_in_label gauge\nmetric_with_spaces_in_label{name=\"Network Agent\"} 72\n# HELP metric_with_multiple_labels A metric with multiple labels.\n# TYPE metric_with_multiple_labels gauge\nmetric_with_multiple_labels{label1=\"One\", label2=\"Two\", label3=\"Three\"} 81\n`\n\t\tfmt.Fprintln(w, text)\n\t}))\n\n\tdefer tempServer.Close()\n\n\tcollector.configFile.Endpoint.URL = tempServer.URL\n\n\tvar spec []v1.MetricSpec\n\trequire.NotPanics(t, func() { spec = collector.GetSpec() })\n\tassert.Len(spec, 4)\n\tspecNames := make(map[string]struct{}, 3)\n\tfor _, s := range spec {\n\t\tspecNames[s.Name] = struct{}{}\n\t}\n\texpectedSpecNames := map[string]struct{}{\n\t\t\"go_gc_duration_seconds\":      {},\n\t\t\"go_goroutines\":               {},\n\t\t\"metric_with_spaces_in_label\": {},\n\t\t\"metric_with_multiple_labels\": {},\n\t}\n\tassert.Equal(expectedSpecNames, specNames)\n\n\tmetrics := map[string][]v1.MetricVal{}\n\t_, metrics, errMetric := collector.Collect(metrics)\n\n\tassert.NoError(errMetric)\n\n\tgcDuration := metrics[\"go_gc_duration_seconds\"]\n\tassert.Equal(5.8348000000000004e-05, gcDuration[0].FloatValue)\n\tassert.Equal(\"__name__=go_gc_duration_seconds\\xffquantile=0\", gcDuration[0].Label)\n\tassert.Equal(0.000499764, gcDuration[1].FloatValue)\n\tassert.Equal(\"__name__=go_gc_duration_seconds\\xffquantile=1\", gcDuration[1].Label)\n\tgcDurationSum := metrics[\"go_gc_duration_seconds_sum\"]\n\tassert.Equal(1.7560473e+07, gcDurationSum[0].FloatValue)\n\tassert.Equal(\"__name__=go_gc_duration_seconds_sum\", gcDurationSum[0].Label)\n\tgcDurationCount := metrics[\"go_gc_duration_seconds_count\"]\n\tassert.Equal(float64(2693), gcDurationCount[0].FloatValue)\n\tassert.Equal(\"__name__=go_gc_duration_seconds_count\", gcDurationCount[0].Label)\n\n\tgoRoutines := metrics[\"go_goroutines\"]\n\tassert.Equal(float64(16), goRoutines[0].FloatValue)\n\tassert.Equal(\"__name__=go_goroutines\", goRoutines[0].Label)\n\n\tmetricWithSpaces := metrics[\"metric_with_spaces_in_label\"]\n\tassert.Equal(float64(72), metricWithSpaces[0].FloatValue)\n\tassert.Equal(\"__name__=metric_with_spaces_in_label\\xffname=Network Agent\", metricWithSpaces[0].Label)\n\n\tmetricWithMultipleLabels := metrics[\"metric_with_multiple_labels\"]\n\tassert.Equal(float64(81), metricWithMultipleLabels[0].FloatValue)\n\tassert.Equal(\"__name__=metric_with_multiple_labels\\xfflabel1=One\\xfflabel2=Two\\xfflabel3=Three\", metricWithMultipleLabels[0].Label)\n}\n\nfunc TestPrometheusEndpointConfig(t *testing.T) {\n\tassert := assert.New(t)\n\n\t//Create a prometheus collector using the config file 'sample_config_prometheus.json'\n\tconfigFile, err := os.ReadFile(\"config/sample_config_prometheus_endpoint_config.json\")\n\tassert.NoError(err)\n\tcontainerHandler := containertest.NewMockContainerHandler(\"mockContainer\")\n\tcontainerHandler.On(\"GetContainerIPAddress\").Return(\n\t\t\"222.222.222.222\",\n\t)\n\n\tcollector, err := NewPrometheusCollector(\"Prometheus\", configFile, 100, containerHandler, http.DefaultClient)\n\tassert.NoError(err)\n\tassert.Equal(collector.name, \"Prometheus\")\n\tassert.Equal(collector.configFile.Endpoint.URL, \"http://222.222.222.222:8081/METRICS\")\n}\n\nfunc TestPrometheusShortResponse(t *testing.T) {\n\tassert := assert.New(t)\n\n\t// Create a prometheus collector using the config file 'sample_config_prometheus.json'\n\tconfigFile, err := os.ReadFile(\"config/sample_config_prometheus.json\")\n\tassert.NoError(err)\n\tcontainerHandler := containertest.NewMockContainerHandler(\"mockContainer\")\n\tcollector, err := NewPrometheusCollector(\"Prometheus\", configFile, 100, containerHandler, http.DefaultClient)\n\tassert.NoError(err)\n\tassert.Equal(collector.name, \"Prometheus\")\n\tassert.Equal(collector.configFile.Endpoint.URL, \"http://localhost:8080/metrics\")\n\n\ttempServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {\n\t\ttext := \"# HELP empty_metric A metric without any values\"\n\t\tfmt.Fprint(w, text)\n\t}))\n\n\tdefer tempServer.Close()\n\n\tcollector.configFile.Endpoint.URL = tempServer.URL\n\n\tassert.NotPanics(func() { collector.GetSpec() })\n}\n\nfunc TestPrometheusMetricCountLimit(t *testing.T) {\n\tassert := assert.New(t)\n\n\t// Create a prometheus collector using the config file 'sample_config_prometheus.json'\n\tconfigFile, err := os.ReadFile(\"config/sample_config_prometheus.json\")\n\tassert.NoError(err)\n\tcontainerHandler := containertest.NewMockContainerHandler(\"mockContainer\")\n\tcollector, err := NewPrometheusCollector(\"Prometheus\", configFile, 10, containerHandler, http.DefaultClient)\n\tassert.NoError(err)\n\tassert.Equal(collector.name, \"Prometheus\")\n\tassert.Equal(collector.configFile.Endpoint.URL, \"http://localhost:8080/metrics\")\n\n\ttempServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {\n\t\tfor i := 0; i < 30; i++ {\n\t\t\tfmt.Fprintf(w, \"# HELP m%d Number of goroutines that currently exist.\\n\", i)\n\t\t\tfmt.Fprintf(w, \"# TYPE m%d gauge\\n\", i)\n\t\t\tfmt.Fprintf(w, \"m%d %d\", i, i)\n\t\t}\n\t}))\n\tdefer tempServer.Close()\n\n\tcollector.configFile.Endpoint.URL = tempServer.URL\n\tmetrics := map[string][]v1.MetricVal{}\n\t_, result, errMetric := collector.Collect(metrics)\n\n\tassert.Error(errMetric)\n\tassert.Equal(len(metrics), 0)\n\tassert.Nil(result)\n}\n\nfunc TestPrometheusFiltersMetrics(t *testing.T) {\n\tassert := assert.New(t)\n\n\t// Create a prometheus collector using the config file 'sample_config_prometheus_filtered.json'\n\tconfigFile, err := os.ReadFile(\"config/sample_config_prometheus_filtered.json\")\n\tassert.NoError(err)\n\tcontainerHandler := containertest.NewMockContainerHandler(\"mockContainer\")\n\tcollector, err := NewPrometheusCollector(\"Prometheus\", configFile, 100, containerHandler, http.DefaultClient)\n\tassert.NoError(err)\n\tassert.Equal(collector.name, \"Prometheus\")\n\tassert.Equal(collector.configFile.Endpoint.URL, \"http://localhost:8080/metrics\")\n\n\ttempServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {\n\n\t\ttext := `# HELP go_gc_duration_seconds A summary of the GC invocation durations.\n# TYPE go_gc_duration_seconds summary\ngo_gc_duration_seconds{quantile=\"0\"} 5.8348000000000004e-05\ngo_gc_duration_seconds{quantile=\"1\"} 0.000499764\ngo_gc_duration_seconds_sum 1.7560473e+07\ngo_gc_duration_seconds_count 2693\n# HELP go_goroutines Number of goroutines that currently exist.\n# TYPE go_goroutines gauge\ngo_goroutines 16\n`\n\t\tfmt.Fprintln(w, text)\n\t}))\n\n\tdefer tempServer.Close()\n\n\tcollector.configFile.Endpoint.URL = tempServer.URL\n\tmetrics := map[string][]v1.MetricVal{}\n\t_, metrics, errMetric := collector.Collect(metrics)\n\n\tassert.NoError(errMetric)\n\tassert.Len(metrics, 1)\n\n\tgoRoutines := metrics[\"go_goroutines\"]\n\tassert.Equal(goRoutines[0].FloatValue, float64(16))\n}\n\nfunc TestPrometheusFiltersMetricsCountLimit(t *testing.T) {\n\tassert := assert.New(t)\n\n\t// Create a prometheus collector using the config file 'sample_config_prometheus_filtered.json'\n\tconfigFile, err := os.ReadFile(\"config/sample_config_prometheus_filtered.json\")\n\tassert.NoError(err)\n\tcontainerHandler := containertest.NewMockContainerHandler(\"mockContainer\")\n\t_, err = NewPrometheusCollector(\"Prometheus\", configFile, 1, containerHandler, http.DefaultClient)\n\tassert.Error(err)\n}\n"
  },
  {
    "path": "collector/types.go",
    "content": "// Copyright 2015 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage collector\n\nimport (\n\t\"time\"\n\n\tv1 \"github.com/google/cadvisor/info/v1\"\n)\n\n// TODO(vmarmol): Export to a custom metrics type when that is available.\n\n// Metric collector.\ntype Collector interface {\n\t// Collect metrics from this collector.\n\t// Returns the next time this collector should be collected from.\n\t// Next collection time is always returned, even when an error occurs.\n\t// A collection time of zero means no more collection.\n\tCollect(map[string][]v1.MetricVal) (time.Time, map[string][]v1.MetricVal, error)\n\n\t// Return spec for all metrics associated with this collector\n\tGetSpec() []v1.MetricSpec\n\n\t// Name of this collector.\n\tName() string\n}\n\n// Manages and runs collectors.\ntype CollectorManager interface {\n\t// Register a collector.\n\tRegisterCollector(collector Collector) error\n\n\t// Collect from collectors that are ready and return the next time\n\t// at which a collector will be ready to collect from.\n\t// Next collection time is always returned, even when an error occurs.\n\t// A collection time of zero means no more collection.\n\tCollect() (time.Time, map[string][]v1.MetricVal, error)\n\n\t// Get metric spec from all registered collectors.\n\tGetSpec() ([]v1.MetricSpec, error)\n}\n"
  },
  {
    "path": "collector/util.go",
    "content": "// Copyright 2016 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage collector\n\nimport \"github.com/google/cadvisor/container\"\n\nfunc (ec *EndpointConfig) configure(containerHandler container.ContainerHandler) {\n\t// If the exact URL was not specified, generate it based on the ip address of the container.\n\tif ec.URL == \"\" {\n\t\tipAddress := containerHandler.GetContainerIPAddress()\n\t\tec.URL = ec.URLConfig.Protocol + \"://\" + ipAddress + \":\" + ec.URLConfig.Port.String() + ec.URLConfig.Path\n\t}\n}\n"
  },
  {
    "path": "container/common/container_hints.go",
    "content": "// Copyright 2014 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n//go:build linux\n\n// Unmarshal's a Containers description json file. The json file contains\n// an array of ContainerHint structs, each with a container's id and networkInterface\n// This allows collecting stats about network interfaces configured outside docker\n// and lxc\npackage common\n\nimport (\n\t\"encoding/json\"\n\t\"flag\"\n\t\"os\"\n)\n\nvar ArgContainerHints = flag.String(\"container_hints\", \"/etc/cadvisor/container_hints.json\", \"location of the container hints file\")\n\ntype ContainerHints struct {\n\tAllHosts []containerHint `json:\"all_hosts,omitempty\"`\n}\n\ntype containerHint struct {\n\tFullName         string            `json:\"full_path,omitempty\"`\n\tNetworkInterface *networkInterface `json:\"network_interface,omitempty\"`\n\tMounts           []Mount           `json:\"mounts,omitempty\"`\n}\n\ntype Mount struct {\n\tHostDir      string `json:\"host_dir,omitempty\"`\n\tContainerDir string `json:\"container_dir,omitempty\"`\n}\n\ntype networkInterface struct {\n\tVethHost  string `json:\"veth_host,omitempty\"`\n\tVethChild string `json:\"veth_child,omitempty\"`\n}\n\nfunc GetContainerHintsFromFile(containerHintsFile string) (ContainerHints, error) {\n\tdat, err := os.ReadFile(containerHintsFile)\n\tif os.IsNotExist(err) {\n\t\treturn ContainerHints{}, nil\n\t}\n\tvar cHints ContainerHints\n\tif err == nil {\n\t\terr = json.Unmarshal(dat, &cHints)\n\t}\n\n\treturn cHints, err\n}\n"
  },
  {
    "path": "container/common/container_hints_test.go",
    "content": "// Copyright 2014 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n//go:build linux\n\npackage common\n\nimport (\n\t\"testing\"\n)\n\nfunc TestGetContainerHintsFromFile(t *testing.T) {\n\tcHints, err := GetContainerHintsFromFile(\"test_resources/container_hints.json\")\n\n\tif err != nil {\n\t\tt.Fatalf(\"Error in unmarshalling: %s\", err)\n\t}\n\n\tif cHints.AllHosts[0].NetworkInterface.VethHost != \"veth24031eth1\" &&\n\t\tcHints.AllHosts[0].NetworkInterface.VethChild != \"eth1\" {\n\t\tt.Errorf(\"Cannot find network interface in %+v\", cHints)\n\t}\n\n\tcorrectMountDirs := [...]string{\n\t\t\"/var/run/nm-sdc1\",\n\t\t\"/var/run/nm-sdb3\",\n\t\t\"/var/run/nm-sda3\",\n\t\t\"/var/run/netns/root\",\n\t\t\"/var/run/openvswitch/db.sock\",\n\t}\n\n\tif len(cHints.AllHosts[0].Mounts) == 0 {\n\t\tt.Errorf(\"Cannot find any mounts\")\n\t}\n\n\tfor i, mountDir := range cHints.AllHosts[0].Mounts {\n\t\tif correctMountDirs[i] != mountDir.HostDir {\n\t\t\tt.Errorf(\"Cannot find mount %s in %+v\", mountDir.HostDir, cHints)\n\t\t}\n\t}\n}\n\nfunc TestFileNotExist(t *testing.T) {\n\t_, err := GetContainerHintsFromFile(\"/file_does_not_exist.json\")\n\tif err != nil {\n\t\tt.Fatalf(\"GetContainerHintsFromFile must not error for blank file: %s\", err)\n\t}\n}\n"
  },
  {
    "path": "container/common/fsHandler.go",
    "content": "// Copyright 2015 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n//go:build linux\n\n// Handler for Docker containers.\npackage common\n\nimport (\n\t\"fmt\"\n\t\"sync\"\n\t\"time\"\n\n\t\"github.com/google/cadvisor/fs\"\n\n\t\"k8s.io/klog/v2\"\n)\n\ntype FsHandler interface {\n\tStart()\n\tUsage() FsUsage\n\tStop()\n}\n\ntype FsUsage struct {\n\tBaseUsageBytes  uint64\n\tTotalUsageBytes uint64\n\tInodeUsage      uint64\n}\n\ntype realFsHandler struct {\n\tsync.RWMutex\n\tlastUpdate time.Time\n\tusage      FsUsage\n\tperiod     time.Duration\n\tminPeriod  time.Duration\n\trootfs     string\n\textraDir   string\n\tfsInfo     fs.FsInfo\n\t// Tells the container to stop.\n\tstopChan chan struct{}\n}\n\nconst (\n\tmaxBackoffFactor = 20\n)\n\nconst DefaultPeriod = time.Minute\n\nvar _ FsHandler = &realFsHandler{}\n\nfunc NewFsHandler(period time.Duration, rootfs, extraDir string, fsInfo fs.FsInfo) FsHandler {\n\treturn &realFsHandler{\n\t\tlastUpdate: time.Time{},\n\t\tusage:      FsUsage{},\n\t\tperiod:     period,\n\t\tminPeriod:  period,\n\t\trootfs:     rootfs,\n\t\textraDir:   extraDir,\n\t\tfsInfo:     fsInfo,\n\t\tstopChan:   make(chan struct{}, 1),\n\t}\n}\n\nfunc (fh *realFsHandler) update() error {\n\tvar (\n\t\trootUsage, extraUsage fs.UsageInfo\n\t\trootErr, extraErr     error\n\t)\n\t// TODO(vishh): Add support for external mounts.\n\tif fh.rootfs != \"\" {\n\t\trootUsage, rootErr = fh.fsInfo.GetDirUsage(fh.rootfs)\n\t}\n\n\tif fh.extraDir != \"\" {\n\t\textraUsage, extraErr = fh.fsInfo.GetDirUsage(fh.extraDir)\n\t}\n\n\t// Wait to handle errors until after all operartions are run.\n\t// An error in one will not cause an early return, skipping others\n\tfh.Lock()\n\tdefer fh.Unlock()\n\tfh.lastUpdate = time.Now()\n\tif fh.rootfs != \"\" && rootErr == nil {\n\t\tfh.usage.InodeUsage = rootUsage.Inodes\n\t\tfh.usage.BaseUsageBytes = rootUsage.Bytes\n\t\tfh.usage.TotalUsageBytes = rootUsage.Bytes\n\t}\n\tif fh.extraDir != \"\" && extraErr == nil {\n\t\tif fh.rootfs != \"\" {\n\t\t\tfh.usage.TotalUsageBytes += extraUsage.Bytes\n\t\t} else {\n\t\t\t// rootfs is empty, totalUsageBytes use extra usage bytes\n\t\t\tfh.usage.TotalUsageBytes = extraUsage.Bytes\n\t\t}\n\t}\n\n\t// Combine errors into a single error to return\n\tif rootErr != nil || extraErr != nil {\n\t\treturn fmt.Errorf(\"rootDiskErr: %v, extraDiskErr: %v\", rootErr, extraErr)\n\t}\n\treturn nil\n}\n\nfunc (fh *realFsHandler) trackUsage() {\n\tlongOp := time.Second\n\tfor {\n\t\tstart := time.Now()\n\t\tif err := fh.update(); err != nil {\n\t\t\tklog.Errorf(\"failed to collect filesystem stats - %v\", err)\n\t\t\tfh.period = fh.period * 2\n\t\t\tif fh.period > maxBackoffFactor*fh.minPeriod {\n\t\t\t\tfh.period = maxBackoffFactor * fh.minPeriod\n\t\t\t}\n\t\t} else {\n\t\t\tfh.period = fh.minPeriod\n\t\t}\n\t\tduration := time.Since(start)\n\t\tif duration > longOp {\n\t\t\t// adapt longOp time so that message doesn't continue to print\n\t\t\t// if the long duration is persistent either because of slow\n\t\t\t// disk or lots of containers.\n\t\t\tlongOp = longOp + time.Second\n\t\t\tklog.V(2).Infof(\"fs: disk usage and inodes count on following dirs took %v: %v; will not log again for this container unless duration exceeds %v\", duration, []string{fh.rootfs, fh.extraDir}, longOp)\n\t\t}\n\t\tselect {\n\t\tcase <-fh.stopChan:\n\t\t\treturn\n\t\tcase <-time.After(fh.period):\n\t\t}\n\t}\n}\n\nfunc (fh *realFsHandler) Start() {\n\tgo fh.trackUsage()\n}\n\nfunc (fh *realFsHandler) Stop() {\n\tclose(fh.stopChan)\n}\n\nfunc (fh *realFsHandler) Usage() FsUsage {\n\tfh.RLock()\n\tdefer fh.RUnlock()\n\treturn fh.usage\n}\n"
  },
  {
    "path": "container/common/helpers.go",
    "content": "// Copyright 2016 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n//go:build linux\n\npackage common\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"io/fs\"\n\t\"math\"\n\t\"os\"\n\t\"path\"\n\t\"strconv\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/opencontainers/cgroups\"\n\t\"golang.org/x/sys/unix\"\n\n\t\"github.com/google/cadvisor/container\"\n\tinfo \"github.com/google/cadvisor/info/v1\"\n\t\"github.com/google/cadvisor/utils\"\n\n\t\"k8s.io/klog/v2\"\n)\n\nfunc DebugInfo(watches map[string][]string) map[string][]string {\n\tout := make(map[string][]string)\n\n\tlines := make([]string, 0, len(watches))\n\tfor containerName, cgroupWatches := range watches {\n\t\tlines = append(lines, fmt.Sprintf(\"%s:\", containerName))\n\t\tfor _, cg := range cgroupWatches {\n\t\t\tlines = append(lines, fmt.Sprintf(\"\\t%s\", cg))\n\t\t}\n\t}\n\tout[\"Inotify watches\"] = lines\n\n\treturn out\n}\n\nvar bootTime = func() time.Time {\n\tnow := time.Now()\n\tvar sysinfo unix.Sysinfo_t\n\tif err := unix.Sysinfo(&sysinfo); err != nil {\n\t\treturn now\n\t}\n\tsinceBoot := time.Duration(sysinfo.Uptime) * time.Second\n\treturn now.Add(-1 * sinceBoot).Truncate(time.Minute)\n}()\n\nfunc GetSpec(cgroupPaths map[string]string, machineInfoFactory info.MachineInfoFactory, hasNetwork, hasFilesystem bool) (info.ContainerSpec, error) {\n\treturn getSpecInternal(cgroupPaths, machineInfoFactory, hasNetwork, hasFilesystem, cgroups.IsCgroup2UnifiedMode())\n}\n\nfunc getSpecInternal(cgroupPaths map[string]string, machineInfoFactory info.MachineInfoFactory, hasNetwork, hasFilesystem, cgroup2UnifiedMode bool) (info.ContainerSpec, error) {\n\tvar spec info.ContainerSpec\n\n\t// Assume unified hierarchy containers.\n\t// Get the lowest creation time from all hierarchies as the container creation time.\n\tnow := time.Now()\n\tlowestTime := now\n\tfor _, cgroupPathDir := range cgroupPaths {\n\t\tdir, err := os.Stat(cgroupPathDir)\n\t\tif err == nil && dir.ModTime().Before(lowestTime) {\n\t\t\tlowestTime = dir.ModTime()\n\t\t} else if os.IsNotExist(err) {\n\t\t\t// Directory does not exist, skip checking for files within.\n\t\t\tcontinue\n\t\t}\n\n\t\t// The modified time of the cgroup directory sometimes changes whenever a subcontainer is created.\n\t\t// eg. /docker will have creation time matching the creation of latest docker container.\n\t\t// Use clone_children/events as a workaround as it isn't usually modified. It is only likely changed\n\t\t// immediately after creating a container. If the directory modified time is lower, we use that.\n\t\tcgroupPathFile := path.Join(cgroupPathDir, \"cgroup.clone_children\")\n\t\tif cgroup2UnifiedMode {\n\t\t\tcgroupPathFile = path.Join(cgroupPathDir, \"cgroup.events\")\n\t\t}\n\t\tfi, err := os.Stat(cgroupPathFile)\n\t\tif err == nil && fi.ModTime().Before(lowestTime) {\n\t\t\tlowestTime = fi.ModTime()\n\t\t}\n\t}\n\tif lowestTime.Before(bootTime) {\n\t\tlowestTime = bootTime\n\t}\n\n\tif lowestTime != now {\n\t\tspec.CreationTime = lowestTime\n\t}\n\n\t// Get machine info.\n\tmi, err := machineInfoFactory.GetMachineInfo()\n\tif err != nil {\n\t\treturn spec, err\n\t}\n\n\t// CPU.\n\tcpuRoot, ok := GetControllerPath(cgroupPaths, \"cpu\", cgroup2UnifiedMode)\n\tif ok {\n\t\tif utils.FileExists(cpuRoot) {\n\t\t\tif cgroup2UnifiedMode {\n\t\t\t\tspec.HasCpu = true\n\n\t\t\t\tweight := readUInt64(cpuRoot, \"cpu.weight\")\n\t\t\t\tif weight > 0 {\n\t\t\t\t\tlimit, err := convertCPUWeightToCPULimit(weight)\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\tklog.Errorf(\"GetSpec: Failed to read CPULimit from %q: %s\", path.Join(cpuRoot, \"cpu.weight\"), err)\n\t\t\t\t\t} else {\n\t\t\t\t\t\tspec.Cpu.Limit = limit\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tmax := readString(cpuRoot, \"cpu.max\")\n\t\t\t\tif max != \"\" {\n\t\t\t\t\tsplits := strings.SplitN(max, \" \", 2)\n\t\t\t\t\tif len(splits) != 2 {\n\t\t\t\t\t\tklog.Errorf(\"GetSpec: Failed to parse CPUmax from %q\", path.Join(cpuRoot, \"cpu.max\"))\n\t\t\t\t\t} else {\n\t\t\t\t\t\tif splits[0] != \"max\" {\n\t\t\t\t\t\t\tspec.Cpu.Quota = parseUint64String(splits[0])\n\t\t\t\t\t\t}\n\t\t\t\t\t\tspec.Cpu.Period = parseUint64String(splits[1])\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tspec.HasCpu = true\n\t\t\t\tspec.Cpu.Limit = readUInt64(cpuRoot, \"cpu.shares\")\n\t\t\t\tspec.Cpu.Period = readUInt64(cpuRoot, \"cpu.cfs_period_us\")\n\t\t\t\tquota := readString(cpuRoot, \"cpu.cfs_quota_us\")\n\n\t\t\t\tif quota != \"\" && quota != \"-1\" {\n\t\t\t\t\tval, err := strconv.ParseUint(quota, 10, 64)\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\tklog.Errorf(\"GetSpec: Failed to parse CPUQuota from %q: %s\", path.Join(cpuRoot, \"cpu.cfs_quota_us\"), err)\n\t\t\t\t\t} else {\n\t\t\t\t\t\tspec.Cpu.Quota = val\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// Cpu Mask.\n\t// This will fail for non-unified hierarchies. We'll return the whole machine mask in that case.\n\tcpusetRoot, ok := GetControllerPath(cgroupPaths, \"cpuset\", cgroup2UnifiedMode)\n\tif ok {\n\t\tif utils.FileExists(cpusetRoot) {\n\t\t\tspec.HasCpu = true\n\t\t\tmask := \"\"\n\t\t\tif cgroup2UnifiedMode {\n\t\t\t\tmask = readString(cpusetRoot, \"cpuset.cpus.effective\")\n\t\t\t} else {\n\t\t\t\tmask = readString(cpusetRoot, \"cpuset.cpus\")\n\t\t\t}\n\t\t\tspec.Cpu.Mask = utils.FixCpuMask(mask, mi.NumCores)\n\t\t}\n\t}\n\n\t// Memory\n\tmemoryRoot, ok := GetControllerPath(cgroupPaths, \"memory\", cgroup2UnifiedMode)\n\tif ok {\n\t\tif cgroup2UnifiedMode {\n\t\t\tif utils.FileExists(path.Join(memoryRoot, \"memory.max\")) {\n\t\t\t\tspec.HasMemory = true\n\t\t\t\tspec.Memory.Reservation = readUInt64(memoryRoot, \"memory.min\")\n\t\t\t\tspec.Memory.Limit = readUInt64(memoryRoot, \"memory.max\")\n\t\t\t\tspec.Memory.SwapLimit = readUInt64(memoryRoot, \"memory.swap.max\")\n\t\t\t}\n\t\t} else {\n\t\t\tif utils.FileExists(memoryRoot) {\n\t\t\t\tspec.HasMemory = true\n\t\t\t\tspec.Memory.Limit = readUInt64(memoryRoot, \"memory.limit_in_bytes\")\n\t\t\t\tspec.Memory.SwapLimit = readUInt64(memoryRoot, \"memory.memsw.limit_in_bytes\")\n\t\t\t\tspec.Memory.Reservation = readUInt64(memoryRoot, \"memory.soft_limit_in_bytes\")\n\t\t\t}\n\t\t}\n\t}\n\n\t// Hugepage\n\thugepageRoot, ok := cgroupPaths[\"hugetlb\"]\n\tif ok {\n\t\tif utils.FileExists(hugepageRoot) {\n\t\t\tspec.HasHugetlb = true\n\t\t}\n\t}\n\n\t// Processes, read it's value from pids path directly\n\tpidsRoot, ok := GetControllerPath(cgroupPaths, \"pids\", cgroup2UnifiedMode)\n\tif ok {\n\t\tif utils.FileExists(pidsRoot) {\n\t\t\tspec.HasProcesses = true\n\t\t\tspec.Processes.Limit = readUInt64(pidsRoot, \"pids.max\")\n\t\t}\n\t}\n\n\tspec.HasNetwork = hasNetwork\n\tspec.HasFilesystem = hasFilesystem\n\n\tioControllerName := \"blkio\"\n\tif cgroup2UnifiedMode {\n\t\tioControllerName = \"io\"\n\t}\n\n\tif blkioRoot, ok := GetControllerPath(cgroupPaths, ioControllerName, cgroup2UnifiedMode); ok && utils.FileExists(blkioRoot) {\n\t\tspec.HasDiskIo = true\n\t}\n\n\treturn spec, nil\n}\n\nfunc GetControllerPath(cgroupPaths map[string]string, controllerName string, cgroup2UnifiedMode bool) (string, bool) {\n\n\tok := false\n\tpath := \"\"\n\n\tif cgroup2UnifiedMode {\n\t\tpath, ok = cgroupPaths[\"\"]\n\t} else {\n\t\tpath, ok = cgroupPaths[controllerName]\n\t}\n\treturn path, ok\n}\n\nfunc readString(dirpath string, file string) string {\n\tcgroupFile := path.Join(dirpath, file)\n\n\t// Read\n\tout, err := os.ReadFile(cgroupFile)\n\tif err != nil {\n\t\t// Ignore non-existent files\n\t\tif !os.IsNotExist(err) {\n\t\t\tklog.Warningf(\"readString: Failed to read %q: %s\", cgroupFile, err)\n\t\t}\n\t\treturn \"\"\n\t}\n\treturn strings.TrimSpace(string(out))\n}\n\n// Convert from [1-10000] to [2-262144]\nfunc convertCPUWeightToCPULimit(weight uint64) (uint64, error) {\n\tconst (\n\t\t// minWeight is the lowest value possible for cpu.weight\n\t\tminWeight = 1\n\t\t// maxWeight is the highest value possible for cpu.weight\n\t\tmaxWeight = 10000\n\t)\n\tif weight < minWeight || weight > maxWeight {\n\t\treturn 0, fmt.Errorf(\"convertCPUWeightToCPULimit: invalid cpu weight: %v\", weight)\n\t}\n\treturn 2 + ((weight-1)*262142)/9999, nil\n}\n\nfunc parseUint64String(strValue string) uint64 {\n\tif strValue == \"max\" {\n\t\treturn math.MaxUint64\n\t}\n\tif strValue == \"\" {\n\t\treturn 0\n\t}\n\n\tval, err := strconv.ParseUint(strValue, 10, 64)\n\tif err != nil {\n\t\tklog.Errorf(\"parseUint64String: Failed to parse int %q: %s\", strValue, err)\n\t\treturn 0\n\t}\n\n\treturn val\n}\n\nfunc readUInt64(dirpath string, file string) uint64 {\n\tout := readString(dirpath, file)\n\tif out == \"max\" {\n\t\treturn math.MaxUint64\n\t}\n\tif out == \"\" {\n\t\treturn 0\n\t}\n\n\tval, err := strconv.ParseUint(out, 10, 64)\n\tif err != nil {\n\t\tklog.Errorf(\"readUInt64: Failed to parse int %q from file %q: %s\", out, path.Join(dirpath, file), err)\n\t\treturn 0\n\t}\n\n\treturn val\n}\n\n// Lists all directories under \"path\" and outputs the results as children of \"parent\".\nfunc ListDirectories(dirpath string, parent string, recursive bool, output map[string]struct{}) error {\n\tdirents, err := os.ReadDir(dirpath)\n\tif err != nil {\n\t\t// Ignore if this hierarchy does not exist.\n\t\tif errors.Is(err, fs.ErrNotExist) {\n\t\t\treturn nil\n\t\t}\n\t\treturn err\n\t}\n\tfor _, dirent := range dirents {\n\t\t// We only grab directories.\n\t\tif !dirent.IsDir() {\n\t\t\tcontinue\n\t\t}\n\t\tdirname := dirent.Name()\n\n\t\tname := path.Join(parent, dirname)\n\t\toutput[name] = struct{}{}\n\n\t\t// List subcontainers if asked to.\n\t\tif recursive {\n\t\t\tif err := ListDirectories(path.Join(dirpath, dirname), name, true, output); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc MakeCgroupPaths(mountPoints map[string]string, name string) map[string]string {\n\tcgroupPaths := make(map[string]string, len(mountPoints))\n\tfor key, val := range mountPoints {\n\t\tcgroupPaths[key] = path.Join(val, name)\n\t}\n\n\treturn cgroupPaths\n}\n\nfunc CgroupExists(cgroupPaths map[string]string) bool {\n\t// If any cgroup exists, the container is still alive.\n\tfor _, cgroupPath := range cgroupPaths {\n\t\tif utils.FileExists(cgroupPath) {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\nfunc ListContainers(name string, cgroupPaths map[string]string, listType container.ListType) ([]info.ContainerReference, error) {\n\tcontainers := make(map[string]struct{})\n\tfor _, cgroupPath := range cgroupPaths {\n\t\terr := ListDirectories(cgroupPath, name, listType == container.ListRecursive, containers)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\n\t// Make into container references.\n\tret := make([]info.ContainerReference, 0, len(containers))\n\tfor cont := range containers {\n\t\tret = append(ret, info.ContainerReference{\n\t\t\tName: cont,\n\t\t})\n\t}\n\n\treturn ret, nil\n}\n\n// AssignDeviceNamesToDiskStats assigns the Device field on the provided DiskIoStats by looking up\n// the device major and minor identifiers in the provided device namer.\nfunc AssignDeviceNamesToDiskStats(namer DeviceNamer, stats *info.DiskIoStats) {\n\tassignDeviceNamesToPerDiskStats(\n\t\tnamer,\n\t\tstats.IoMerged,\n\t\tstats.IoQueued,\n\t\tstats.IoServiceBytes,\n\t\tstats.IoServiceTime,\n\t\tstats.IoServiced,\n\t\tstats.IoTime,\n\t\tstats.IoWaitTime,\n\t\tstats.Sectors,\n\t\tstats.IoCostUsage,\n\t\tstats.IoCostWait,\n\t\tstats.IoCostIndebt,\n\t\tstats.IoCostIndelay,\n\t)\n}\n\n// assignDeviceNamesToPerDiskStats looks up device names for the provided stats, caching names\n// if necessary.\nfunc assignDeviceNamesToPerDiskStats(namer DeviceNamer, diskStats ...[]info.PerDiskStats) {\n\tdevices := make(deviceIdentifierMap)\n\tfor _, stats := range diskStats {\n\t\tfor i, stat := range stats {\n\t\t\tstats[i].Device = devices.Find(stat.Major, stat.Minor, namer)\n\t\t}\n\t}\n}\n\n// DeviceNamer returns string names for devices by their major and minor id.\ntype DeviceNamer interface {\n\t// DeviceName returns the name of the device by its major and minor ids, or false if no\n\t// such device is recognized.\n\tDeviceName(major, minor uint64) (string, bool)\n}\n\ntype MachineInfoNamer info.MachineInfo\n\nfunc (n *MachineInfoNamer) DeviceName(major, minor uint64) (string, bool) {\n\tfor _, info := range n.DiskMap {\n\t\tif info.Major == major && info.Minor == minor {\n\t\t\treturn \"/dev/\" + info.Name, true\n\t\t}\n\t}\n\tfor _, info := range n.Filesystems {\n\t\tif info.DeviceMajor == major && info.DeviceMinor == minor {\n\t\t\treturn info.Device, true\n\t\t}\n\t}\n\treturn \"\", false\n}\n\ntype deviceIdentifier struct {\n\tmajor uint64\n\tminor uint64\n}\n\ntype deviceIdentifierMap map[deviceIdentifier]string\n\n// Find locates the device name by device identifier out of from, caching the result as necessary.\nfunc (m deviceIdentifierMap) Find(major, minor uint64, namer DeviceNamer) string {\n\td := deviceIdentifier{major, minor}\n\tif s, ok := m[d]; ok {\n\t\treturn s\n\t}\n\ts, _ := namer.DeviceName(major, minor)\n\tm[d] = s\n\treturn s\n}\n\n// RemoveNetMetrics is used to remove any network metrics from the given MetricSet.\n// It returns the original set as is if remove is false, or if there are no metrics\n// to remove.\nfunc RemoveNetMetrics(metrics container.MetricSet, remove bool) container.MetricSet {\n\tif !remove {\n\t\treturn metrics\n\t}\n\n\t// Check if there is anything we can remove, to avoid useless copying.\n\tif !metrics.HasAny(container.AllNetworkMetrics) {\n\t\treturn metrics\n\t}\n\n\t// A copy of all metrics except for network ones.\n\treturn metrics.Difference(container.AllNetworkMetrics)\n}\n"
  },
  {
    "path": "container/common/helpers_test.go",
    "content": "// Copyright 2018 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n//go:build linux\n\npackage common\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"math\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"reflect\"\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/assert\"\n\n\t\"github.com/google/cadvisor/container\"\n\tinfo \"github.com/google/cadvisor/info/v1\"\n\tv2 \"github.com/google/cadvisor/info/v2\"\n)\n\nfunc BenchmarkListDirectories(b *testing.B) {\n\tfor i := 0; i < b.N; i++ {\n\t\toutput := make(map[string]struct{})\n\t\tif err := ListDirectories(\"/sys/fs/cgroup\", \"\", true, output); err != nil {\n\t\t\tb.Fatal(err)\n\t\t}\n\t}\n}\n\nfunc TestConvertCpuWeightToCpuLimit(t *testing.T) {\n\tlimit, err := convertCPUWeightToCPULimit(1)\n\tif err != nil {\n\t\tt.Fatalf(\"Error in convertCPUWeightToCPULimit: %s\", err)\n\t}\n\tif limit != 2 {\n\t\tt.Fatalf(\"convertCPUWeightToCPULimit(1) != 2\")\n\t}\n\tlimit, err = convertCPUWeightToCPULimit(10000)\n\tif err != nil {\n\t\tt.Fatalf(\"Error in convertCPUWeightToCPULimit: %s\", err)\n\t}\n\tif limit != 262144 {\n\t\tt.Fatalf(\"convertCPUWeightToCPULimit(10000) != 262144\")\n\t}\n\t_, err = convertCPUWeightToCPULimit(0)\n\tif err == nil {\n\t\tt.Fatalf(\"convertCPUWeightToCPULimit(0) must raise an error\")\n\t}\n\t_, err = convertCPUWeightToCPULimit(10001)\n\tif err == nil {\n\t\tt.Fatalf(\"convertCPUWeightToCPULimit(10001) must raise an error\")\n\t}\n}\n\nfunc TestParseUint64String(t *testing.T) {\n\tif parseUint64String(\"1000\") != 1000 {\n\t\tt.Fatalf(\"parseUint64String(\\\"1000\\\") != 1000\")\n\t}\n\tif parseUint64String(\"-1\") != 0 {\n\t\tt.Fatalf(\"parseUint64String(\\\"-1\\\") != 0\")\n\t}\n\tif parseUint64String(\"0\") != 0 {\n\t\tt.Fatalf(\"parseUint64String(\\\"0\\\") != 0\")\n\t}\n\tif parseUint64String(\"not-a-number\") != 0 {\n\t\tt.Fatalf(\"parseUint64String(\\\"not-a-number\\\") != 0\")\n\t}\n\tif parseUint64String(\" 1000 \") != 0 {\n\t\tt.Fatalf(\"parseUint64String(\\\" 1000 \\\") != 0\")\n\t}\n\tif parseUint64String(\"18446744073709551615\") != 18446744073709551615 {\n\t\tt.Fatalf(\"parseUint64String(\\\"18446744073709551615\\\") != 18446744073709551615\")\n\t}\n}\n\ntype mockInfoProvider struct {\n\toptions v2.RequestOptions\n}\n\nfunc (m *mockInfoProvider) GetRequestedContainersInfo(containerName string, options v2.RequestOptions) (map[string]*info.ContainerInfo, error) {\n\tm.options = options\n\treturn map[string]*info.ContainerInfo{}, nil\n}\n\nfunc (m *mockInfoProvider) GetVersionInfo() (*info.VersionInfo, error) {\n\treturn nil, errors.New(\"not supported\")\n}\n\nfunc (m *mockInfoProvider) GetMachineInfo() (*info.MachineInfo, error) {\n\treturn &info.MachineInfo{\n\t\tNumCores: 7,\n\t}, nil\n}\n\nfunc TestGetSpecCgroupV1(t *testing.T) {\n\troot, err := os.Getwd()\n\tif err != nil {\n\t\tt.Fatalf(\"getwd: %s\", err)\n\t}\n\n\tcgroupPaths := map[string]string{\n\t\t\"memory\": filepath.Join(root, \"test_resources/cgroup_v1/test1/memory\"),\n\t\t\"cpu\":    filepath.Join(root, \"test_resources/cgroup_v1/test1/cpu\"),\n\t\t\"cpuset\": filepath.Join(root, \"test_resources/cgroup_v1/test1/cpuset\"),\n\t\t\"pids\":   filepath.Join(root, \"test_resources/cgroup_v1/test1/pids\"),\n\t}\n\n\tspec, err := getSpecInternal(cgroupPaths, &mockInfoProvider{}, false, false, false)\n\tassert.Nil(t, err)\n\n\tassert.True(t, spec.HasMemory)\n\tassert.EqualValues(t, spec.Memory.Limit, 123456789)\n\tassert.EqualValues(t, spec.Memory.SwapLimit, 13579)\n\tassert.EqualValues(t, spec.Memory.Reservation, 24680)\n\n\tassert.True(t, spec.HasCpu)\n\tassert.EqualValues(t, spec.Cpu.Limit, 1025)\n\tassert.EqualValues(t, spec.Cpu.Period, 100010)\n\tassert.EqualValues(t, spec.Cpu.Quota, 20000)\n\n\tassert.EqualValues(t, spec.Cpu.Mask, \"0-5\")\n\n\tassert.True(t, spec.HasProcesses)\n\tassert.EqualValues(t, spec.Processes.Limit, 1027)\n\n\tassert.False(t, spec.HasHugetlb)\n\tassert.False(t, spec.HasDiskIo)\n}\n\nfunc TestGetSpecCgroupV2(t *testing.T) {\n\troot, err := os.Getwd()\n\tif err != nil {\n\t\tt.Fatalf(\"getwd: %s\", err)\n\t}\n\n\tcgroupPaths := map[string]string{\n\t\t\"\": filepath.Join(root, \"test_resources/cgroup_v2/test1\"),\n\t}\n\n\tspec, err := getSpecInternal(cgroupPaths, &mockInfoProvider{}, false, false, true)\n\tassert.Nil(t, err)\n\n\tassert.True(t, spec.HasMemory)\n\tassert.EqualValues(t, spec.Memory.Limit, 123456789)\n\tassert.EqualValues(t, spec.Memory.SwapLimit, 13579)\n\tassert.EqualValues(t, spec.Memory.Reservation, 24680)\n\n\tassert.True(t, spec.HasCpu)\n\tassert.EqualValues(t, spec.Cpu.Limit, 1286)\n\tassert.EqualValues(t, spec.Cpu.Period, 100010)\n\tassert.EqualValues(t, spec.Cpu.Quota, 20000)\n\n\tassert.EqualValues(t, spec.Cpu.Mask, \"0-5\")\n\n\tassert.True(t, spec.HasProcesses)\n\tassert.EqualValues(t, spec.Processes.Limit, 1027)\n\n\tassert.False(t, spec.HasHugetlb)\n\tassert.True(t, spec.HasDiskIo)\n}\n\nfunc TestGetSpecCgroupV2Max(t *testing.T) {\n\troot, err := os.Getwd()\n\tassert.Nil(t, err)\n\n\tcgroupPaths := map[string]string{\n\t\t\"\": filepath.Join(root, \"test_resources/cgroup_v2/test2\"),\n\t}\n\n\tspec, err := getSpecInternal(cgroupPaths, &mockInfoProvider{}, false, false, true)\n\tassert.Nil(t, err)\n\n\tmax := uint64(math.MaxUint64)\n\n\tassert.True(t, spec.HasMemory)\n\tassert.EqualValues(t, spec.Memory.Limit, max)\n\tassert.EqualValues(t, spec.Memory.SwapLimit, max)\n\tassert.EqualValues(t, spec.Memory.Reservation, max)\n\n\tassert.True(t, spec.HasCpu)\n\tassert.EqualValues(t, spec.Cpu.Limit, 1286)\n\tassert.EqualValues(t, spec.Cpu.Period, 100010)\n\tassert.EqualValues(t, spec.Cpu.Quota, 0)\n\n\tassert.EqualValues(t, spec.Processes.Limit, max)\n}\n\nfunc TestRemoveNetMetrics(t *testing.T) {\n\tfor _, ts := range []struct {\n\t\tdesc    string\n\t\tin, out container.MetricSet\n\t}{\n\t\t{\n\t\t\tdesc: \"nil set\",\n\t\t\tin:   nil,\n\t\t},\n\t\t{\n\t\t\tdesc: \"empty set\",\n\t\t\tin:   container.MetricSet{},\n\t\t},\n\t\t{\n\t\t\tdesc: \"nothing to remove\",\n\t\t\tin:   container.MetricSet{container.MemoryUsageMetrics: struct{}{}, container.PerfMetrics: struct{}{}},\n\t\t},\n\t\t{\n\t\t\tdesc: \"also nothing to remove\",\n\t\t\tin:   container.AllMetrics.Difference(container.AllNetworkMetrics),\n\t\t},\n\t\t{\n\t\t\tdesc: \"remove net from all\",\n\t\t\tin:   container.AllMetrics,\n\t\t\tout:  container.AllMetrics.Difference(container.AllNetworkMetrics),\n\t\t},\n\t\t{\n\t\t\tdesc: \"remove net from some\",\n\t\t\tin:   container.MetricSet{container.MemoryUsageMetrics: struct{}{}, container.NetworkTcpUsageMetrics: struct{}{}},\n\t\t\tout:  container.MetricSet{container.MemoryUsageMetrics: struct{}{}},\n\t\t},\n\t} {\n\t\tfor _, remove := range []bool{true, false} {\n\t\t\tts, remove := ts, remove\n\t\t\tdesc := fmt.Sprintf(\"%s, remove: %v\", ts.desc, remove)\n\t\t\tt.Run(desc, func(t *testing.T) {\n\t\t\t\tout := RemoveNetMetrics(ts.in, remove)\n\t\t\t\tif !remove || ts.out == nil {\n\t\t\t\t\t// Compare the actual underlying pointers. Can't use assert.Same\n\t\t\t\t\t// because it checks for pointer type, and these are maps.\n\t\t\t\t\tif reflect.ValueOf(ts.in) != reflect.ValueOf(out) {\n\t\t\t\t\t\tt.Errorf(\"expected original map %p, got %p\", ts.in, out)\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tassert.Equal(t, ts.out, out)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t}\n}\n\nfunc BenchmarkGetSpecCgroupV2(b *testing.B) {\n\troot, err := os.Getwd()\n\tif err != nil {\n\t\tb.Fatalf(\"getwd: %s\", err)\n\t}\n\n\tcgroupPaths := map[string]string{\n\t\t\"\": filepath.Join(root, \"test_resources/cgroup_v2/test1\"),\n\t}\n\n\tfor i := 0; i < b.N; i++ {\n\t\t_, err := getSpecInternal(cgroupPaths, &mockInfoProvider{}, false, false, true)\n\t\tassert.Nil(b, err)\n\t}\n\n}\n\nfunc BenchmarkGetSpecCgroupV1(b *testing.B) {\n\troot, err := os.Getwd()\n\tif err != nil {\n\t\tb.Fatalf(\"getwd: %s\", err)\n\t}\n\n\tcgroupPaths := map[string]string{\n\t\t\"memory\": filepath.Join(root, \"test_resources/cgroup_v1/test1/memory\"),\n\t\t\"cpu\":    filepath.Join(root, \"test_resources/cgroup_v1/test1/cpu\"),\n\t\t\"cpuset\": filepath.Join(root, \"test_resources/cgroup_v1/test1/cpuset\"),\n\t\t\"pids\":   filepath.Join(root, \"test_resources/cgroup_v1/test1/pids\"),\n\t}\n\n\tfor i := 0; i < b.N; i++ {\n\t\t_, err := getSpecInternal(cgroupPaths, &mockInfoProvider{}, false, false, false)\n\t\tassert.Nil(b, err)\n\t}\n\n}\n"
  },
  {
    "path": "container/common/inotify_watcher.go",
    "content": "// Copyright 2015 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n//go:build linux\n\npackage common\n\nimport (\n\t\"sync\"\n\n\tinotify \"k8s.io/utils/inotify\"\n)\n\n// Watcher for container-related inotify events in the cgroup hierarchy.\n//\n// Implementation is thread-safe.\ntype InotifyWatcher struct {\n\t// Underlying inotify watcher.\n\twatcher *inotify.Watcher\n\n\t// Map of containers being watched to cgroup paths watched for that container.\n\tcontainersWatched map[string]map[string]bool\n\n\t// Lock for all datastructure access.\n\tlock sync.Mutex\n}\n\nfunc NewInotifyWatcher() (*InotifyWatcher, error) {\n\tw, err := inotify.NewWatcher()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn &InotifyWatcher{\n\t\twatcher:           w,\n\t\tcontainersWatched: make(map[string]map[string]bool),\n\t}, nil\n}\n\n// Add a watch to the specified directory. Returns if the container was already being watched.\nfunc (iw *InotifyWatcher) AddWatch(containerName, dir string) (bool, error) {\n\tiw.lock.Lock()\n\tdefer iw.lock.Unlock()\n\n\tcgroupsWatched, alreadyWatched := iw.containersWatched[containerName]\n\n\t// Register an inotify notification.\n\tif !cgroupsWatched[dir] {\n\t\terr := iw.watcher.AddWatch(dir, inotify.InCreate|inotify.InDelete|inotify.InMove)\n\t\tif err != nil {\n\t\t\treturn alreadyWatched, err\n\t\t}\n\n\t\tif cgroupsWatched == nil {\n\t\t\tcgroupsWatched = make(map[string]bool)\n\t\t}\n\t\tcgroupsWatched[dir] = true\n\t}\n\n\t// Record our watching of the container.\n\tif !alreadyWatched {\n\t\tiw.containersWatched[containerName] = cgroupsWatched\n\t}\n\treturn alreadyWatched, nil\n}\n\n// Remove watch from the specified directory. Returns if this was the last watch on the specified container.\nfunc (iw *InotifyWatcher) RemoveWatch(containerName, dir string) (bool, error) {\n\tiw.lock.Lock()\n\tdefer iw.lock.Unlock()\n\n\t// If we don't have a watch registered for this, just return.\n\tcgroupsWatched, ok := iw.containersWatched[containerName]\n\tif !ok {\n\t\treturn false, nil\n\t}\n\n\t// Remove the inotify watch if it exists.\n\tif cgroupsWatched[dir] {\n\t\terr := iw.watcher.RemoveWatch(dir)\n\t\tif err != nil {\n\t\t\treturn false, nil\n\t\t}\n\t\tdelete(cgroupsWatched, dir)\n\t}\n\n\t// Remove the record if this is the last watch.\n\tif len(cgroupsWatched) == 0 {\n\t\tdelete(iw.containersWatched, containerName)\n\t\treturn true, nil\n\t}\n\n\treturn false, nil\n}\n\n// Errors are returned on this channel.\nfunc (iw *InotifyWatcher) Error() chan error {\n\treturn iw.watcher.Error\n}\n\n// Events are returned on this channel.\nfunc (iw *InotifyWatcher) Event() chan *inotify.Event {\n\treturn iw.watcher.Event\n}\n\n// Closes the inotify watcher.\nfunc (iw *InotifyWatcher) Close() error {\n\treturn iw.watcher.Close()\n}\n\n// Returns a map of containers to the cgroup paths being watched.\nfunc (iw *InotifyWatcher) GetWatches() map[string][]string {\n\tout := make(map[string][]string, len(iw.containersWatched))\n\tfor k, v := range iw.containersWatched {\n\t\tout[k] = mapToSlice(v)\n\t}\n\treturn out\n}\n\nfunc mapToSlice(m map[string]bool) []string {\n\tout := make([]string, 0, len(m))\n\tfor k := range m {\n\t\tout = append(out, k)\n\t}\n\treturn out\n}\n"
  },
  {
    "path": "container/common/test_resources/cgroup_v1/test1/cpu/cpu.cfs_period_us",
    "content": "100010\n"
  },
  {
    "path": "container/common/test_resources/cgroup_v1/test1/cpu/cpu.cfs_quota_us",
    "content": "20000\n"
  },
  {
    "path": "container/common/test_resources/cgroup_v1/test1/cpu/cpu.shares",
    "content": "1025\n"
  },
  {
    "path": "container/common/test_resources/cgroup_v1/test1/cpuset/cpuset.cpus",
    "content": "0-5\n"
  },
  {
    "path": "container/common/test_resources/cgroup_v1/test1/memory/memory.limit_in_bytes",
    "content": "123456789\n"
  },
  {
    "path": "container/common/test_resources/cgroup_v1/test1/memory/memory.memsw.limit_in_bytes",
    "content": "13579\n"
  },
  {
    "path": "container/common/test_resources/cgroup_v1/test1/memory/memory.soft_limit_in_bytes",
    "content": "24680\n"
  },
  {
    "path": "container/common/test_resources/cgroup_v1/test1/pids/pids.max",
    "content": "1027\n"
  },
  {
    "path": "container/common/test_resources/cgroup_v2/test1/cpu.max",
    "content": "20000 100010\n"
  },
  {
    "path": "container/common/test_resources/cgroup_v2/test1/cpu.weight",
    "content": "50\n"
  },
  {
    "path": "container/common/test_resources/cgroup_v2/test1/cpuset.cpus.effective",
    "content": "0-5\n"
  },
  {
    "path": "container/common/test_resources/cgroup_v2/test1/memory.max",
    "content": "123456789\n"
  },
  {
    "path": "container/common/test_resources/cgroup_v2/test1/memory.min",
    "content": "24680\n"
  },
  {
    "path": "container/common/test_resources/cgroup_v2/test1/memory.swap.max",
    "content": "13579\n"
  },
  {
    "path": "container/common/test_resources/cgroup_v2/test1/pids.max",
    "content": "1027\n"
  },
  {
    "path": "container/common/test_resources/cgroup_v2/test2/cpu.max",
    "content": "max 100010\n"
  },
  {
    "path": "container/common/test_resources/cgroup_v2/test2/cpu.weight",
    "content": "50\n"
  },
  {
    "path": "container/common/test_resources/cgroup_v2/test2/memory.max",
    "content": "max\n"
  },
  {
    "path": "container/common/test_resources/cgroup_v2/test2/memory.min",
    "content": "max\n"
  },
  {
    "path": "container/common/test_resources/cgroup_v2/test2/memory.swap.max",
    "content": "max\n"
  },
  {
    "path": "container/common/test_resources/cgroup_v2/test2/pids.max",
    "content": "max\n"
  },
  {
    "path": "container/common/test_resources/container_hints.json",
    "content": "{\n  \"name\": \"Container Hints\",\n  \"description\": \"Container hints file\",\n  \"all_hosts\": [\n    {\n      \"network_interface\": {\n        \"veth_child\": \"eth1\",\n        \"veth_host\": \"veth24031eth1\"\n      },\n      \"mounts\": [\n        {\n          \"host_dir\": \"/var/run/nm-sdc1\",\n          \"container_dir\": \"/var/run/nm-sdc1\",\n          \"permission\": \"rw\"\n        },\n        {\n          \"host_dir\": \"/var/run/nm-sdb3\",\n          \"container_dir\": \"/var/run/nm-sdb3\",\n          \"permission\": \"rw\"\n        },\n        {\n          \"host_dir\": \"/var/run/nm-sda3\",\n          \"container_dir\": \"/var/run/nm-sda3\",\n          \"permission\": \"rw\"\n        },\n        {\n          \"host_dir\": \"/var/run/netns/root\",\n          \"container_dir\": \"/var/run/netns/root\",\n          \"permission\": \"ro\"\n        },\n        {\n          \"host_dir\": \"/var/run/openvswitch/db.sock\",\n          \"container_dir\": \"/var/run/openvswitch/db.sock\",\n          \"permission\": \"rw\"\n        }\n      ],\n      \"full_path\": \"18a4585950db428e4d5a65c216a5d708d241254709626f4cb300ee963fb4b144\"\n    }\n  ]\n}\n"
  },
  {
    "path": "container/container.go",
    "content": "// Copyright 2014 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n// Package container defines types for sub-container events and also\n// defines an interface for container operation handlers.\npackage container\n\nimport info \"github.com/google/cadvisor/info/v1\"\n\n// ListType describes whether listing should be just for a\n// specific container or performed recursively.\ntype ListType int\n\nconst (\n\tListSelf ListType = iota\n\tListRecursive\n)\n\ntype ContainerType int\n\nconst (\n\tContainerTypeRaw ContainerType = iota\n\tContainerTypeDocker\n\tContainerTypeCrio\n\tContainerTypeContainerd\n\tContainerTypePodman\n)\n\n// Interface for container operation handlers.\ntype ContainerHandler interface {\n\t// Returns the ContainerReference\n\tContainerReference() (info.ContainerReference, error)\n\n\t// Returns container's isolation spec.\n\tGetSpec() (info.ContainerSpec, error)\n\n\t// Returns the current stats values of the container.\n\tGetStats() (*info.ContainerStats, error)\n\n\t// Returns the subcontainers of this container.\n\tListContainers(listType ListType) ([]info.ContainerReference, error)\n\n\t// Returns the processes inside this container.\n\tListProcesses(listType ListType) ([]int, error)\n\n\t// Returns absolute cgroup path for the requested resource.\n\tGetCgroupPath(resource string) (string, error)\n\n\t// Returns container labels, if available.\n\tGetContainerLabels() map[string]string\n\n\t// Returns the container's ip address, if available\n\tGetContainerIPAddress() string\n\n\t// GetExitCode returns the container's exit code if available.\n\t// Returns an error if the container has not exited, exit codes are not supported\n\t// for this handler type, or the container information is unavailable.\n\tGetExitCode() (int, error)\n\n\t// Returns whether the container still exists.\n\tExists() bool\n\n\t// Cleanup frees up any resources being held like fds or go routines, etc.\n\tCleanup()\n\n\t// Start starts any necessary background goroutines - must be cleaned up in Cleanup().\n\t// It is expected that most implementations will be a no-op.\n\tStart()\n\n\t// Type of handler\n\tType() ContainerType\n}\n"
  },
  {
    "path": "container/containerd/client.go",
    "content": "// Copyright 2017 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage containerd\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"fmt\"\n\t\"net\"\n\t\"sync\"\n\t\"time\"\n\n\tcontainersapi \"github.com/containerd/containerd/api/services/containers/v1\"\n\ttasksapi \"github.com/containerd/containerd/api/services/tasks/v1\"\n\tversionapi \"github.com/containerd/containerd/api/services/version/v1\"\n\ttasktypes \"github.com/containerd/containerd/api/types/task\"\n\t\"github.com/containerd/errdefs/pkg/errgrpc\"\n\t\"google.golang.org/grpc\"\n\t\"google.golang.org/grpc/backoff\"\n\t\"google.golang.org/grpc/credentials/insecure\"\n\temptypb \"google.golang.org/protobuf/types/known/emptypb\"\n\n\t\"github.com/google/cadvisor/container/containerd/containers\"\n\t\"github.com/google/cadvisor/container/containerd/pkg/dialer\"\n)\n\ntype client struct {\n\tcontainerService containersapi.ContainersClient\n\ttaskService      tasksapi.TasksClient\n\tversionService   versionapi.VersionClient\n}\n\ntype ContainerdClient interface {\n\tLoadContainer(ctx context.Context, id string) (*containers.Container, error)\n\tTaskPid(ctx context.Context, id string) (uint32, error)\n\tLoadTaskProcess(ctx context.Context, id string) (*tasktypes.Process, error)\n\tTaskExitStatus(ctx context.Context, id string) (uint32, error)\n\tVersion(ctx context.Context) (string, error)\n}\n\nvar (\n\tErrTaskIsInUnknownState = errors.New(\"containerd task is in unknown state\") // used when process reported in containerd task is in Unknown State\n)\n\nvar once sync.Once\nvar ctrdClient ContainerdClient = nil\nvar ctrdClientErr error = nil\n\nconst (\n\tmaxBackoffDelay   = 3 * time.Second\n\tbaseBackoffDelay  = 100 * time.Millisecond\n\tconnectionTimeout = 2 * time.Second\n\tmaxMsgSize        = 16 * 1024 * 1024 // 16MB\n)\n\n// Client creates a containerd client\nfunc Client(address, namespace string) (ContainerdClient, error) {\n\tonce.Do(func() {\n\t\ttryConn, err := net.DialTimeout(\"unix\", address, connectionTimeout)\n\t\tif err != nil {\n\t\t\tctrdClientErr = fmt.Errorf(\"containerd: cannot unix dial containerd api service: %v\", err)\n\t\t\treturn\n\t\t}\n\t\ttryConn.Close()\n\n\t\tconnParams := grpc.ConnectParams{\n\t\t\tBackoff: backoff.DefaultConfig,\n\t\t}\n\t\tconnParams.Backoff.BaseDelay = baseBackoffDelay\n\t\tconnParams.Backoff.MaxDelay = maxBackoffDelay\n\t\t//nolint:staticcheck // SA1019\n\t\tgopts := []grpc.DialOption{\n\t\t\tgrpc.WithTransportCredentials(insecure.NewCredentials()),\n\t\t\tgrpc.WithContextDialer(dialer.ContextDialer),\n\t\t\tgrpc.WithBlock(),\n\t\t\tgrpc.WithConnectParams(connParams),\n\t\t\tgrpc.WithDefaultCallOptions(grpc.MaxCallRecvMsgSize(maxMsgSize)),\n\t\t}\n\t\tunary, stream := newNSInterceptors(namespace)\n\t\tgopts = append(gopts,\n\t\t\tgrpc.WithUnaryInterceptor(unary),\n\t\t\tgrpc.WithStreamInterceptor(stream),\n\t\t)\n\n\t\tctx, cancel := context.WithTimeout(context.Background(), connectionTimeout)\n\t\tdefer cancel()\n\t\t//nolint:staticcheck // SA1019\n\t\tconn, err := grpc.DialContext(ctx, dialer.DialAddress(address), gopts...)\n\t\tif err != nil {\n\t\t\tctrdClientErr = err\n\t\t\treturn\n\t\t}\n\t\tctrdClient = &client{\n\t\t\tcontainerService: containersapi.NewContainersClient(conn),\n\t\t\ttaskService:      tasksapi.NewTasksClient(conn),\n\t\t\tversionService:   versionapi.NewVersionClient(conn),\n\t\t}\n\t})\n\treturn ctrdClient, ctrdClientErr\n}\n\nfunc (c *client) LoadContainer(ctx context.Context, id string) (*containers.Container, error) {\n\tr, err := c.containerService.Get(ctx, &containersapi.GetContainerRequest{\n\t\tID: id,\n\t})\n\tif err != nil {\n\t\treturn nil, errgrpc.ToNative(err)\n\t}\n\treturn containerFromProto(r.Container), nil\n}\n\nfunc (c *client) TaskPid(ctx context.Context, id string) (uint32, error) {\n\tresponse, err := c.taskService.Get(ctx, &tasksapi.GetRequest{\n\t\tContainerID: id,\n\t})\n\tif err != nil {\n\t\treturn 0, errgrpc.ToNative(err)\n\t}\n\tif response.Process.Status == tasktypes.Status_UNKNOWN {\n\t\treturn 0, ErrTaskIsInUnknownState\n\t}\n\treturn response.Process.Pid, nil\n}\n\nfunc (c *client) LoadTaskProcess(ctx context.Context, id string) (*tasktypes.Process, error) {\n\tresponse, err := c.taskService.Get(ctx, &tasksapi.GetRequest{\n\t\tContainerID: id,\n\t})\n\tif err != nil {\n\t\treturn nil, errgrpc.ToNative(err)\n\t}\n\n\treturn response.Process, nil\n}\n\nfunc (c *client) TaskExitStatus(ctx context.Context, id string) (uint32, error) {\n\tresponse, err := c.taskService.Get(ctx, &tasksapi.GetRequest{\n\t\tContainerID: id,\n\t})\n\tif err != nil {\n\t\treturn 0, errgrpc.ToNative(err)\n\t}\n\tif response.Process.Status != tasktypes.Status_STOPPED {\n\t\treturn 0, fmt.Errorf(\"container %s has not exited (status: %v)\", id, response.Process.Status)\n\t}\n\treturn response.Process.ExitStatus, nil\n}\n\nfunc (c *client) Version(ctx context.Context) (string, error) {\n\tresponse, err := c.versionService.Version(ctx, &emptypb.Empty{})\n\tif err != nil {\n\t\treturn \"\", errgrpc.ToNative(err)\n\t}\n\treturn response.Version, nil\n}\n\nfunc containerFromProto(containerpb *containersapi.Container) *containers.Container {\n\tvar runtime containers.RuntimeInfo\n\tvar createdAt time.Time\n\t// TODO: is nil check required for containerpb\n\tif containerpb.Runtime != nil {\n\t\truntime = containers.RuntimeInfo{\n\t\t\tName:    containerpb.Runtime.Name,\n\t\t\tOptions: containerpb.Runtime.Options,\n\t\t}\n\t}\n\tif containerpb.GetCreatedAt() != nil {\n\t\tcreatedAt = containerpb.GetCreatedAt().AsTime()\n\t}\n\treturn &containers.Container{\n\t\tID:          containerpb.ID,\n\t\tLabels:      containerpb.Labels,\n\t\tImage:       containerpb.Image,\n\t\tRuntime:     runtime,\n\t\tSpec:        containerpb.Spec,\n\t\tSnapshotter: containerpb.Snapshotter,\n\t\tSnapshotKey: containerpb.SnapshotKey,\n\t\tExtensions:  containerpb.Extensions,\n\t\tCreatedAt:   createdAt,\n\t}\n}\n"
  },
  {
    "path": "container/containerd/client_test.go",
    "content": "// Copyright 2017 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage containerd\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\t\"github.com/containerd/containerd/api/types/task\"\n\n\t\"github.com/google/cadvisor/container/containerd/containers\"\n)\n\ntype containerdClientMock struct {\n\tcntrs      map[string]*containers.Container\n\treturnErr  error\n\ttasks      map[string]*task.Process\n\texitStatus uint32\n}\n\nfunc (c *containerdClientMock) LoadContainer(ctx context.Context, id string) (*containers.Container, error) {\n\tif c.returnErr != nil {\n\t\treturn nil, c.returnErr\n\t}\n\tcntr, ok := c.cntrs[id]\n\tif !ok {\n\t\treturn nil, fmt.Errorf(\"unable to find container %q\", id)\n\t}\n\treturn cntr, nil\n}\n\nfunc (c *containerdClientMock) Version(ctx context.Context) (string, error) {\n\treturn \"test-v0.0.0\", nil\n}\n\nfunc (c *containerdClientMock) TaskPid(ctx context.Context, id string) (uint32, error) {\n\treturn 2389, nil\n}\n\nfunc (c *containerdClientMock) LoadTaskProcess(ctx context.Context, id string) (*task.Process, error) {\n\tif c.returnErr != nil {\n\t\treturn nil, c.returnErr\n\t}\n\ttask, ok := c.tasks[id]\n\tif !ok {\n\t\treturn nil, fmt.Errorf(\"unable to find task for container %q\", id)\n\t}\n\treturn task, nil\n}\n\nfunc (c *containerdClientMock) TaskExitStatus(ctx context.Context, id string) (uint32, error) {\n\tif c.returnErr != nil {\n\t\treturn 0, c.returnErr\n\t}\n\treturn c.exitStatus, nil\n}\n\nfunc mockcontainerdClient(cntrs map[string]*containers.Container, returnErr error) ContainerdClient {\n\ttasks := make(map[string]*task.Process)\n\n\tfor _, cntr := range cntrs {\n\t\ttasks[cntr.ID] = &task.Process{}\n\t}\n\n\treturn &containerdClientMock{\n\t\tcntrs:     cntrs,\n\t\treturnErr: returnErr,\n\t\ttasks:     tasks,\n\t}\n}\n"
  },
  {
    "path": "container/containerd/containers/containers.go",
    "content": "// Copyright 2017 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n/*\n   Copyright The containerd Authors.\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n*/\n\npackage containers\n\nimport (\n\t\"context\"\n\t\"time\"\n\n\t\"google.golang.org/protobuf/types/known/anypb\"\n)\n\n// Container represents the set of data pinned by a container. Unless otherwise\n// noted, the resources here are considered in use by the container.\n//\n// The resources specified in this object are used to create tasks from the container.\ntype Container struct {\n\t// ID uniquely identifies the container in a namespace.\n\t//\n\t// This property is required and cannot be changed after creation.\n\tID string\n\n\t// Labels provide metadata extension for a container.\n\t//\n\t// These are optional and fully mutable.\n\tLabels map[string]string\n\n\t// Image specifies the image reference used for a container.\n\t//\n\t// This property is optional and mutable.\n\tImage string\n\n\t// Runtime specifies which runtime should be used when launching container\n\t// tasks.\n\t//\n\t// This property is required and immutable.\n\tRuntime RuntimeInfo\n\n\t// Spec should carry the runtime specification used to implement the\n\t// container.\n\t//\n\t// This field is required but mutable.\n\tSpec *anypb.Any\n\n\t// SnapshotKey specifies the snapshot key to use for the container's root\n\t// filesystem. When starting a task from this container, a caller should\n\t// look up the mounts from the snapshot service and include those on the\n\t// task create request.\n\t//\n\t// This field is not required but mutable.\n\tSnapshotKey string\n\n\t// Snapshotter specifies the snapshotter name used for rootfs\n\t//\n\t// This field is not required but immutable.\n\tSnapshotter string\n\n\t// CreatedAt is the time at which the container was created.\n\tCreatedAt time.Time\n\n\t// UpdatedAt is the time at which the container was updated.\n\tUpdatedAt time.Time\n\n\t// Extensions stores client-specified metadata\n\tExtensions map[string]*anypb.Any\n}\n\n// RuntimeInfo holds runtime specific information\ntype RuntimeInfo struct {\n\tName    string\n\tOptions *anypb.Any\n}\n\n// Store interacts with the underlying container storage\ntype Store interface {\n\t// Get a container using the id.\n\t//\n\t// Container object is returned on success. If the id is not known to the\n\t// store, an error will be returned.\n\tGet(ctx context.Context, id string) (Container, error)\n\n\t// List returns containers that match one or more of the provided filters.\n\tList(ctx context.Context, filters ...string) ([]Container, error)\n\n\t// Create a container in the store from the provided container.\n\tCreate(ctx context.Context, container Container) (Container, error)\n\n\t// Update the container with the provided container object. ID must be set.\n\t//\n\t// If one or more fieldpaths are provided, only the field corresponding to\n\t// the fieldpaths will be mutated.\n\tUpdate(ctx context.Context, container Container, fieldpaths ...string) (Container, error)\n\n\t// Delete a container using the id.\n\t//\n\t// nil will be returned on success. If the container is not known to the\n\t// store, ErrNotFound will be returned.\n\tDelete(ctx context.Context, id string) error\n}\n"
  },
  {
    "path": "container/containerd/factory.go",
    "content": "// Copyright 2017 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n//go:build linux\n\npackage containerd\n\nimport (\n\t\"context\"\n\t\"flag\"\n\t\"fmt\"\n\t\"path\"\n\t\"regexp\"\n\t\"strings\"\n\n\t\"k8s.io/klog/v2\"\n\n\t\"github.com/google/cadvisor/container\"\n\t\"github.com/google/cadvisor/container/libcontainer\"\n\t\"github.com/google/cadvisor/fs\"\n\tinfo \"github.com/google/cadvisor/info/v1\"\n\t\"github.com/google/cadvisor/watcher\"\n)\n\nvar ArgContainerdEndpoint = flag.String(\"containerd\", \"/run/containerd/containerd.sock\", \"containerd endpoint\")\nvar ArgContainerdNamespace = flag.String(\"containerd-namespace\", \"k8s.io\", \"containerd namespace\")\n\nvar containerdEnvMetadataWhiteList = flag.String(\"containerd_env_metadata_whitelist\", \"\", \"DEPRECATED: this flag will be removed, please use `env_metadata_whitelist`. A comma-separated list of environment variable keys matched with specified prefix that needs to be collected for containerd containers\")\n\n// The namespace under which containerd aliases are unique.\nconst k8sContainerdNamespace = \"containerd\"\n\n// Regexp that identifies containerd cgroups, containers started with\n// --cgroup-parent have another prefix than 'containerd'\nvar containerdCgroupRegexp = regexp.MustCompile(`([a-z0-9]{64})`)\n\ntype containerdFactory struct {\n\tmachineInfoFactory info.MachineInfoFactory\n\tclient             ContainerdClient\n\tversion            string\n\t// Information about the mounted cgroup subsystems.\n\tcgroupSubsystems map[string]string\n\t// Information about mounted filesystems.\n\tfsInfo          fs.FsInfo\n\tincludedMetrics container.MetricSet\n}\n\nfunc (f *containerdFactory) String() string {\n\treturn k8sContainerdNamespace\n}\n\nfunc (f *containerdFactory) NewContainerHandler(name string, metadataEnvAllowList []string, inHostNamespace bool) (handler container.ContainerHandler, err error) {\n\tclient, err := Client(*ArgContainerdEndpoint, *ArgContainerdNamespace)\n\tif err != nil {\n\t\treturn\n\t}\n\n\tcontainerdMetadataEnvAllowList := strings.Split(*containerdEnvMetadataWhiteList, \",\")\n\n\t// prefer using the unified metadataEnvAllowList\n\tif len(metadataEnvAllowList) != 0 {\n\t\tcontainerdMetadataEnvAllowList = metadataEnvAllowList\n\t}\n\n\treturn newContainerdContainerHandler(\n\t\tclient,\n\t\tname,\n\t\tf.machineInfoFactory,\n\t\tf.fsInfo,\n\t\tf.cgroupSubsystems,\n\t\tinHostNamespace,\n\t\tcontainerdMetadataEnvAllowList,\n\t\tf.includedMetrics,\n\t)\n}\n\n// Returns the containerd ID from the full container name.\nfunc ContainerNameToContainerdID(name string) string {\n\tid := path.Base(name)\n\tif matches := containerdCgroupRegexp.FindStringSubmatch(id); matches != nil {\n\t\treturn matches[1]\n\t}\n\treturn id\n}\n\n// isContainerName returns true if the cgroup with associated name\n// corresponds to a containerd container.\nfunc isContainerName(name string) bool {\n\t// TODO: May be check with HasPrefix ContainerdNamespace\n\tif strings.HasSuffix(name, \".mount\") {\n\t\treturn false\n\t}\n\treturn containerdCgroupRegexp.MatchString(path.Base(name))\n}\n\n// Containerd can handle and accept all containerd created containers\nfunc (f *containerdFactory) CanHandleAndAccept(name string) (bool, bool, error) {\n\t// if the container is not associated with containerd, we can't handle it or accept it.\n\tif !isContainerName(name) {\n\t\treturn false, false, nil\n\t}\n\t// Check if the container is known to containerd and it is running.\n\tid := ContainerNameToContainerdID(name)\n\t// If container and task lookup in containerd fails then we assume\n\t// that the container state is not known to containerd\n\tctx, cancel := context.WithTimeout(context.Background(), connectionTimeout)\n\tdefer cancel()\n\t_, err := f.client.LoadContainer(ctx, id)\n\tif err != nil {\n\t\treturn false, false, fmt.Errorf(\"failed to load container: %v\", err)\n\t}\n\n\treturn true, true, nil\n}\n\nfunc (f *containerdFactory) DebugInfo() map[string][]string {\n\treturn map[string][]string{}\n}\n\n// Register root container before running this function!\nfunc Register(factory info.MachineInfoFactory, fsInfo fs.FsInfo, includedMetrics container.MetricSet) error {\n\tclient, err := Client(*ArgContainerdEndpoint, *ArgContainerdNamespace)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"unable to create containerd client: %v\", err)\n\t}\n\n\tcontainerdVersion, err := client.Version(context.Background())\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to fetch containerd client version: %v\", err)\n\t}\n\n\tcgroupSubsystems, err := libcontainer.GetCgroupSubsystems(includedMetrics)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to get cgroup subsystems: %v\", err)\n\t}\n\n\tklog.V(1).Infof(\"Registering containerd factory\")\n\tf := &containerdFactory{\n\t\tcgroupSubsystems:   cgroupSubsystems,\n\t\tclient:             client,\n\t\tfsInfo:             fsInfo,\n\t\tmachineInfoFactory: factory,\n\t\tversion:            containerdVersion,\n\t\tincludedMetrics:    includedMetrics,\n\t}\n\n\tcontainer.RegisterContainerHandlerFactory(f, []watcher.ContainerWatchSource{watcher.Raw})\n\treturn nil\n}\n"
  },
  {
    "path": "container/containerd/factory_test.go",
    "content": "// Copyright 2017 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n//go:build linux\n\npackage containerd\n\nimport (\n\t\"testing\"\n\n\t\"github.com/containerd/typeurl/v2\"\n\tspecs \"github.com/opencontainers/runtime-spec/specs-go\"\n\t\"github.com/stretchr/testify/assert\"\n\n\t\"github.com/google/cadvisor/container/containerd/containers\"\n)\n\nfunc TestIsContainerName(t *testing.T) {\n\ttests := []struct {\n\t\tname     string\n\t\texpected bool\n\t}{\n\t\t{\n\t\t\tname:     \"/system.slice/run-containerd-io.containerd.runtime.v1.linux-k8s.io-14ae50f1d3ada102aec3ab00168fdafb2dc0986d79ca9e8d5b75581fa89e9fea-rootfs.mount\",\n\t\t\texpected: false,\n\t\t},\n\t\t{\n\t\t\tname:     \"/kubepods/besteffort/podd76e26fba3bf2bfd215eb29011d55250/40af7cdcbe507acad47a5a62025743ad3ddc6ab93b77b21363aa1c1d641047c9\",\n\t\t\texpected: true,\n\t\t},\n\t}\n\tfor _, test := range tests {\n\t\tif actual := isContainerName(test.name); actual != test.expected {\n\t\t\tt.Errorf(\"%s: expected: %v, actual: %v\", test.name, test.expected, actual)\n\t\t}\n\t}\n}\n\nfunc TestCanHandleAndAccept(t *testing.T) {\n\tas := assert.New(t)\n\ttestContainers := make(map[string]*containers.Container)\n\ttestContainer := &containers.Container{\n\t\tID:     \"40af7cdcbe507acad47a5a62025743ad3ddc6ab93b77b21363aa1c1d641047c9\",\n\t\tLabels: map[string]string{\"io.cri-containerd.kind\": \"sandbox\"},\n\t}\n\tspec := &specs.Spec{Root: &specs.Root{Path: \"/test/\"}, Process: &specs.Process{}}\n\ttestContainer.Spec, _ = typeurl.MarshalAnyToProto(spec)\n\ttestContainers[\"40af7cdcbe507acad47a5a62025743ad3ddc6ab93b77b21363aa1c1d641047c9\"] = testContainer\n\n\tf := &containerdFactory{\n\t\tclient:             mockcontainerdClient(testContainers, nil),\n\t\tcgroupSubsystems:   nil,\n\t\tfsInfo:             nil,\n\t\tmachineInfoFactory: nil,\n\t\tincludedMetrics:    nil,\n\t}\n\tfor k, v := range map[string]bool{\n\t\t\"/kubepods/besteffort/podd76e26fba3bf2bfd215eb29011d55250/40af7cdcbe507acad47a5a62025743ad3ddc6ab93b77b21363aa1c1d641047c9\":                        true,\n\t\t\"/system.slice/run-containerd-io.containerd.runtime.v1.linux-k8s.io-14ae50f1d3ada102aec3ab00168fdafb2dc0986d79ca9e8d5b75581fa89e9fea-rootfs.mount\": false,\n\t} {\n\t\tb1, b2, err := f.CanHandleAndAccept(k)\n\t\tas.Nil(err)\n\t\tas.Equal(b1, v)\n\t\tas.Equal(b2, v)\n\t}\n}\n"
  },
  {
    "path": "container/containerd/grpc.go",
    "content": "// Copyright 2017 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n// This code has been taken from containerd repo to avoid large library import\npackage containerd\n\nimport (\n\t\"context\"\n\n\t\"google.golang.org/grpc\"\n\n\t\"github.com/google/cadvisor/container/containerd/namespaces\"\n)\n\ntype namespaceInterceptor struct {\n\tnamespace string\n}\n\nfunc (ni namespaceInterceptor) unary(ctx context.Context, method string, req, reply interface{}, cc *grpc.ClientConn, invoker grpc.UnaryInvoker, opts ...grpc.CallOption) error {\n\t_, ok := namespaces.Namespace(ctx)\n\tif !ok {\n\t\tctx = namespaces.WithNamespace(ctx, ni.namespace)\n\t}\n\treturn invoker(ctx, method, req, reply, cc, opts...)\n}\n\nfunc (ni namespaceInterceptor) stream(ctx context.Context, desc *grpc.StreamDesc, cc *grpc.ClientConn, method string, streamer grpc.Streamer, opts ...grpc.CallOption) (grpc.ClientStream, error) {\n\t_, ok := namespaces.Namespace(ctx)\n\tif !ok {\n\t\tctx = namespaces.WithNamespace(ctx, ni.namespace)\n\t}\n\treturn streamer(ctx, desc, cc, method, opts...)\n}\n\nfunc newNSInterceptors(ns string) (grpc.UnaryClientInterceptor, grpc.StreamClientInterceptor) {\n\tni := namespaceInterceptor{\n\t\tnamespace: ns,\n\t}\n\treturn grpc.UnaryClientInterceptor(ni.unary), grpc.StreamClientInterceptor(ni.stream)\n}\n"
  },
  {
    "path": "container/containerd/handler.go",
    "content": "// Copyright 2017 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n//go:build linux\n\n// Handler for containerd containers.\npackage containerd\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"errors\"\n\t\"fmt\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/containerd/errdefs\"\n\t\"github.com/opencontainers/cgroups\"\n\tspecs \"github.com/opencontainers/runtime-spec/specs-go\"\n\n\t\"github.com/google/cadvisor/container\"\n\t\"github.com/google/cadvisor/container/common\"\n\tcontainerlibcontainer \"github.com/google/cadvisor/container/libcontainer\"\n\t\"github.com/google/cadvisor/fs\"\n\tinfo \"github.com/google/cadvisor/info/v1\"\n)\n\ntype containerdContainerHandler struct {\n\tmachineInfoFactory info.MachineInfoFactory\n\t// Absolute path to the cgroup hierarchies of this container.\n\t// (e.g.: \"cpu\" -> \"/sys/fs/cgroup/cpu/test\")\n\tcgroupPaths map[string]string\n\tfsInfo      fs.FsInfo\n\t// Metadata associated with the container.\n\treference info.ContainerReference\n\tenvs      map[string]string\n\tlabels    map[string]string\n\t// Time at which this container was created.\n\tcreationTime time.Time\n\t// Image name used for this container.\n\timage string\n\t// Filesystem handler.\n\tincludedMetrics container.MetricSet\n\n\tlibcontainerHandler *containerlibcontainer.Handler\n\tclient              ContainerdClient\n}\n\nvar _ container.ContainerHandler = &containerdContainerHandler{}\n\n// newContainerdContainerHandler returns a new container.ContainerHandler\nfunc newContainerdContainerHandler(\n\tclient ContainerdClient,\n\tname string,\n\tmachineInfoFactory info.MachineInfoFactory,\n\tfsInfo fs.FsInfo,\n\tcgroupSubsystems map[string]string,\n\tinHostNamespace bool,\n\tmetadataEnvAllowList []string,\n\tincludedMetrics container.MetricSet,\n) (container.ContainerHandler, error) {\n\t// Create the cgroup paths.\n\tcgroupPaths := common.MakeCgroupPaths(cgroupSubsystems, name)\n\n\t// Generate the equivalent cgroup manager for this container.\n\tcgroupManager, err := containerlibcontainer.NewCgroupManager(name, cgroupPaths)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tid := ContainerNameToContainerdID(name)\n\t// We assume that if load fails then the container is not known to containerd.\n\tctx := context.Background()\n\tcntr, err := client.LoadContainer(ctx, id)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tvar spec specs.Spec\n\tif err := json.Unmarshal(cntr.Spec.Value, &spec); err != nil {\n\t\treturn nil, err\n\t}\n\n\t// Cgroup is created during task creation. When cadvisor sees the cgroup,\n\t// task may not be fully created yet. Use a retry+backoff to tolerant the\n\t// race condition.\n\t// TODO(random-liu): Use cri-containerd client to talk with cri-containerd\n\t// instead. cri-containerd has some internal synchronization to make sure\n\t// `ContainerStatus` only returns result after `StartContainer` finishes.\n\tvar taskPid uint32\n\tbackoff := 100 * time.Millisecond\n\tretry := 5\n\tfor {\n\t\ttaskPid, err = client.TaskPid(ctx, id)\n\t\tif err == nil {\n\t\t\tbreak\n\t\t}\n\n\t\t// Retry when task is not created yet or task is in unknown state (likely in process of initializing)\n\t\tisRetriableError := errdefs.IsNotFound(err) || errors.Is(err, ErrTaskIsInUnknownState)\n\t\tif !isRetriableError || retry == 0 {\n\t\t\treturn nil, err\n\t\t}\n\n\t\tretry--\n\t\ttime.Sleep(backoff)\n\t\tbackoff *= 2\n\t}\n\n\trootfs := \"/\"\n\tif !inHostNamespace {\n\t\trootfs = \"/rootfs\"\n\t}\n\n\tcontainerReference := info.ContainerReference{\n\t\tId:        id,\n\t\tName:      name,\n\t\tNamespace: k8sContainerdNamespace,\n\t\tAliases:   []string{id, name},\n\t}\n\n\t// Containers that don't have their own network -- this includes\n\t// containers running in Kubernetes pods that use the network of the\n\t// infrastructure container -- does not need their stats to be\n\t// reported. This stops metrics being reported multiple times for each\n\t// container in a pod.\n\tmetrics := common.RemoveNetMetrics(includedMetrics, cntr.Labels[\"io.cri-containerd.kind\"] != \"sandbox\")\n\n\tlibcontainerHandler := containerlibcontainer.NewHandler(cgroupManager, rootfs, int(taskPid), metrics)\n\n\thandler := &containerdContainerHandler{\n\t\tmachineInfoFactory:  machineInfoFactory,\n\t\tcgroupPaths:         cgroupPaths,\n\t\tfsInfo:              fsInfo,\n\t\tenvs:                make(map[string]string),\n\t\tlabels:              cntr.Labels,\n\t\tincludedMetrics:     metrics,\n\t\treference:           containerReference,\n\t\tlibcontainerHandler: libcontainerHandler,\n\t\tclient:              client,\n\t}\n\tif !cntr.CreatedAt.IsZero() && !cntr.CreatedAt.Before(time.Unix(0, 0)) {\n\t\thandler.creationTime = cntr.CreatedAt\n\t}\n\t// Add the name and bare ID as aliases of the container.\n\thandler.image = cntr.Image\n\n\tfor _, exposedEnv := range metadataEnvAllowList {\n\t\tif exposedEnv == \"\" {\n\t\t\t// if no containerdEnvWhitelist provided, len(metadataEnvAllowList) == 1, metadataEnvAllowList[0] == \"\"\n\t\t\tcontinue\n\t\t}\n\n\t\tfor _, envVar := range spec.Process.Env {\n\t\t\tif envVar != \"\" {\n\t\t\t\tsplits := strings.SplitN(envVar, \"=\", 2)\n\t\t\t\tif len(splits) == 2 && strings.HasPrefix(splits[0], exposedEnv) {\n\t\t\t\t\thandler.envs[splits[0]] = splits[1]\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn handler, nil\n}\n\nfunc (h *containerdContainerHandler) ContainerReference() (info.ContainerReference, error) {\n\treturn h.reference, nil\n}\n\nfunc (h *containerdContainerHandler) GetSpec() (info.ContainerSpec, error) {\n\t// TODO: Since we dont collect disk usage stats for containerd, we set hasFilesystem\n\t// to false. Revisit when we support disk usage stats for containerd\n\thasFilesystem := false\n\thasNet := h.includedMetrics.Has(container.NetworkUsageMetrics)\n\tspec, err := common.GetSpec(h.cgroupPaths, h.machineInfoFactory, hasNet, hasFilesystem)\n\tspec.Labels = h.labels\n\tspec.Envs = h.envs\n\tspec.Image = h.image\n\tstartTime := spec.CreationTime\n\tif !h.creationTime.IsZero() {\n\t\tspec.CreationTime = h.creationTime\n\t}\n\tif !startTime.IsZero() {\n\t\tspec.StartTime = startTime\n\t}\n\n\treturn spec, err\n}\n\nfunc (h *containerdContainerHandler) getFsStats(stats *info.ContainerStats) error {\n\tmi, err := h.machineInfoFactory.GetMachineInfo()\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tif h.includedMetrics.Has(container.DiskIOMetrics) {\n\t\tcommon.AssignDeviceNamesToDiskStats((*common.MachineInfoNamer)(mi), &stats.DiskIo)\n\t}\n\treturn nil\n}\n\nfunc (h *containerdContainerHandler) GetStats() (*info.ContainerStats, error) {\n\tstats, err := h.libcontainerHandler.GetStats()\n\tif err != nil {\n\t\treturn stats, err\n\t}\n\n\t// Get filesystem stats.\n\terr = h.getFsStats(stats)\n\treturn stats, err\n}\n\nfunc (h *containerdContainerHandler) ListContainers(listType container.ListType) ([]info.ContainerReference, error) {\n\treturn []info.ContainerReference{}, nil\n}\n\nfunc (h *containerdContainerHandler) GetCgroupPath(resource string) (string, error) {\n\tvar res string\n\tif !cgroups.IsCgroup2UnifiedMode() {\n\t\tres = resource\n\t}\n\tpath, ok := h.cgroupPaths[res]\n\tif !ok {\n\t\treturn \"\", fmt.Errorf(\"could not find path for resource %q for container %q\", resource, h.reference.Name)\n\t}\n\treturn path, nil\n}\n\nfunc (h *containerdContainerHandler) GetContainerLabels() map[string]string {\n\treturn h.labels\n}\n\nfunc (h *containerdContainerHandler) ListProcesses(listType container.ListType) ([]int, error) {\n\treturn h.libcontainerHandler.GetProcesses()\n}\n\nfunc (h *containerdContainerHandler) Exists() bool {\n\treturn common.CgroupExists(h.cgroupPaths)\n}\n\nfunc (h *containerdContainerHandler) Type() container.ContainerType {\n\treturn container.ContainerTypeContainerd\n}\n\nfunc (h *containerdContainerHandler) Start() {\n}\n\nfunc (h *containerdContainerHandler) Cleanup() {\n}\n\nfunc (h *containerdContainerHandler) GetContainerIPAddress() string {\n\t// containerd doesnt take care of networking.So it doesnt maintain networking states\n\treturn \"\"\n}\n\nfunc (h *containerdContainerHandler) GetExitCode() (int, error) {\n\tctx := context.Background()\n\texitStatus, err := h.client.TaskExitStatus(ctx, h.reference.Id)\n\tif err != nil {\n\t\treturn -1, err\n\t}\n\treturn int(exitStatus), nil\n}\n"
  },
  {
    "path": "container/containerd/handler_test.go",
    "content": "// Copyright 2017 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n//go:build linux\n\n// Handler for containerd containers.\npackage containerd\n\nimport (\n\t\"testing\"\n\n\t\"github.com/containerd/typeurl/v2\"\n\tspecs \"github.com/opencontainers/runtime-spec/specs-go\"\n\t\"github.com/stretchr/testify/assert\"\n\n\t\"github.com/google/cadvisor/container\"\n\t\"github.com/google/cadvisor/container/containerd/containers\"\n\t\"github.com/google/cadvisor/fs\"\n\tinfo \"github.com/google/cadvisor/info/v1\"\n)\n\nfunc init() {\n\ttypeurl.Register(&specs.Spec{}, \"types.contianerd.io/opencontainers/runtime-spec\", \"v1\", \"Spec\")\n}\n\ntype mockedMachineInfo struct{}\n\nfunc (m *mockedMachineInfo) GetMachineInfo() (*info.MachineInfo, error) {\n\treturn &info.MachineInfo{}, nil\n}\n\nfunc (m *mockedMachineInfo) GetVersionInfo() (*info.VersionInfo, error) {\n\treturn &info.VersionInfo{}, nil\n}\n\nfunc TestHandler(t *testing.T) {\n\tas := assert.New(t)\n\ttype testCase struct {\n\t\tclient               ContainerdClient\n\t\tname                 string\n\t\tmachineInfoFactory   info.MachineInfoFactory\n\t\tfsInfo               fs.FsInfo\n\t\tcgroupSubsystems     map[string]string\n\t\tinHostNamespace      bool\n\t\tmetadataEnvAllowList []string\n\t\tincludedMetrics      container.MetricSet\n\n\t\thasErr         bool\n\t\terrContains    string\n\t\tcheckReference *info.ContainerReference\n\t\tcheckEnvVars   map[string]string\n\t}\n\ttestContainers := make(map[string]*containers.Container)\n\ttestContainer := &containers.Container{\n\t\tID:     \"40af7cdcbe507acad47a5a62025743ad3ddc6ab93b77b21363aa1c1d641047c9\",\n\t\tLabels: map[string]string{\"io.cri-containerd.kind\": \"sandbox\"},\n\t}\n\tspec := &specs.Spec{Root: &specs.Root{Path: \"/test/\"}, Process: &specs.Process{Env: []string{\"TEST_REGION=FRA\", \"TEST_ZONE=A\", \"HELLO=WORLD\"}}}\n\ttestContainer.Spec, _ = typeurl.MarshalAnyToProto(spec)\n\ttestContainers[\"40af7cdcbe507acad47a5a62025743ad3ddc6ab93b77b21363aa1c1d641047c9\"] = testContainer\n\tfor _, ts := range []testCase{\n\t\t{\n\t\t\tmockcontainerdClient(nil, nil),\n\t\t\t\"/kubepods/pod068e8fa0-9213-11e7-a01f-507b9d4141fa/40af7cdcbe507acad47a5a62025743ad3ddc6ab93b77b21363aa1c1d641047c9\",\n\t\t\tnil,\n\t\t\tnil,\n\t\t\tnil,\n\t\t\tfalse,\n\t\t\tnil,\n\t\t\tnil,\n\t\t\ttrue,\n\t\t\t\"unable to find container \\\"40af7cdcbe507acad47a5a62025743ad3ddc6ab93b77b21363aa1c1d641047c9\\\"\",\n\t\t\tnil,\n\t\t\tnil,\n\t\t},\n\t\t{\n\t\t\tmockcontainerdClient(testContainers, nil),\n\t\t\t\"/kubepods/pod068e8fa0-9213-11e7-a01f-507b9d4141fa/40af7cdcbe507acad47a5a62025743ad3ddc6ab93b77b21363aa1c1d641047c9\",\n\t\t\t&mockedMachineInfo{},\n\t\t\tnil,\n\t\t\tnil,\n\t\t\tfalse,\n\t\t\tnil,\n\t\t\tnil,\n\t\t\tfalse,\n\t\t\t\"\",\n\t\t\t&info.ContainerReference{\n\t\t\t\tId:        \"40af7cdcbe507acad47a5a62025743ad3ddc6ab93b77b21363aa1c1d641047c9\",\n\t\t\t\tName:      \"/kubepods/pod068e8fa0-9213-11e7-a01f-507b9d4141fa/40af7cdcbe507acad47a5a62025743ad3ddc6ab93b77b21363aa1c1d641047c9\",\n\t\t\t\tAliases:   []string{\"40af7cdcbe507acad47a5a62025743ad3ddc6ab93b77b21363aa1c1d641047c9\", \"/kubepods/pod068e8fa0-9213-11e7-a01f-507b9d4141fa/40af7cdcbe507acad47a5a62025743ad3ddc6ab93b77b21363aa1c1d641047c9\"},\n\t\t\t\tNamespace: k8sContainerdNamespace,\n\t\t\t},\n\t\t\tmap[string]string{},\n\t\t},\n\t\t{\n\t\t\tmockcontainerdClient(testContainers, nil),\n\t\t\t\"/kubepods/pod068e8fa0-9213-11e7-a01f-507b9d4141fa/40af7cdcbe507acad47a5a62025743ad3ddc6ab93b77b21363aa1c1d641047c9\",\n\t\t\t&mockedMachineInfo{},\n\t\t\tnil,\n\t\t\tnil,\n\t\t\tfalse,\n\t\t\t[]string{\"TEST\"},\n\t\t\tnil,\n\t\t\tfalse,\n\t\t\t\"\",\n\t\t\t&info.ContainerReference{\n\t\t\t\tId:        \"40af7cdcbe507acad47a5a62025743ad3ddc6ab93b77b21363aa1c1d641047c9\",\n\t\t\t\tName:      \"/kubepods/pod068e8fa0-9213-11e7-a01f-507b9d4141fa/40af7cdcbe507acad47a5a62025743ad3ddc6ab93b77b21363aa1c1d641047c9\",\n\t\t\t\tAliases:   []string{\"40af7cdcbe507acad47a5a62025743ad3ddc6ab93b77b21363aa1c1d641047c9\", \"/kubepods/pod068e8fa0-9213-11e7-a01f-507b9d4141fa/40af7cdcbe507acad47a5a62025743ad3ddc6ab93b77b21363aa1c1d641047c9\"},\n\t\t\t\tNamespace: k8sContainerdNamespace,\n\t\t\t},\n\t\t\tmap[string]string{\"TEST_REGION\": \"FRA\", \"TEST_ZONE\": \"A\"},\n\t\t},\n\t} {\n\t\thandler, err := newContainerdContainerHandler(ts.client, ts.name, ts.machineInfoFactory, ts.fsInfo, ts.cgroupSubsystems, ts.inHostNamespace, ts.metadataEnvAllowList, ts.includedMetrics)\n\t\tif ts.hasErr {\n\t\t\tas.NotNil(err)\n\t\t\tif ts.errContains != \"\" {\n\t\t\t\tas.Contains(err.Error(), ts.errContains)\n\t\t\t}\n\t\t}\n\t\tif ts.checkReference != nil {\n\t\t\tcr, err := handler.ContainerReference()\n\t\t\tas.Nil(err)\n\t\t\tas.Equal(*ts.checkReference, cr)\n\t\t}\n\t\tif ts.checkEnvVars != nil {\n\t\t\tsp, err := handler.GetSpec()\n\t\t\tas.Nil(err)\n\t\t\tas.Equal(ts.checkEnvVars, sp.Envs)\n\t\t}\n\t}\n}\n\nfunc TestGetExitCode(t *testing.T) {\n\ttests := []struct {\n\t\tname         string\n\t\texitStatus   uint32\n\t\treturnErr    error\n\t\texpectErr    bool\n\t\terrContains  string\n\t\texpectedCode int\n\t}{\n\t\t{\n\t\t\tname:         \"successful exit code 0\",\n\t\t\texitStatus:   0,\n\t\t\treturnErr:    nil,\n\t\t\texpectErr:    false,\n\t\t\texpectedCode: 0,\n\t\t},\n\t\t{\n\t\t\tname:         \"successful exit code 1\",\n\t\t\texitStatus:   1,\n\t\t\treturnErr:    nil,\n\t\t\texpectErr:    false,\n\t\t\texpectedCode: 1,\n\t\t},\n\t\t{\n\t\t\tname:         \"task not stopped\",\n\t\t\texitStatus:   0,\n\t\t\treturnErr:    assert.AnError,\n\t\t\texpectErr:    true,\n\t\t\texpectedCode: -1,\n\t\t},\n\t}\n\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tas := assert.New(t)\n\n\t\t\tmockClient := &containerdClientMock{\n\t\t\t\treturnErr:  tt.returnErr,\n\t\t\t\texitStatus: tt.exitStatus,\n\t\t\t}\n\n\t\t\th := &containerdContainerHandler{\n\t\t\t\tclient: mockClient,\n\t\t\t\treference: info.ContainerReference{\n\t\t\t\t\tId: \"test-container-id\",\n\t\t\t\t},\n\t\t\t}\n\n\t\t\tcode, err := h.GetExitCode()\n\n\t\t\tif tt.expectErr {\n\t\t\t\tas.Error(err)\n\t\t\t\tas.Equal(tt.expectedCode, code)\n\t\t\t} else {\n\t\t\t\tas.NoError(err)\n\t\t\t\tas.Equal(tt.expectedCode, code)\n\t\t\t}\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "container/containerd/identifiers/validate.go",
    "content": "// Copyright 2017 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n/*\n   Copyright The containerd Authors.\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n*/\n\n// Package identifiers provides common validation for identifiers and keys\n// across containerd.\n//\n// Identifiers in containerd must be a alphanumeric, allowing limited\n// underscores, dashes and dots.\n//\n// While the character set may be expanded in the future, identifiers\n// are guaranteed to be safely used as filesystem path components.\npackage identifiers\n\nimport (\n\t\"fmt\"\n\t\"regexp\"\n\n\t\"github.com/containerd/errdefs\"\n)\n\nconst (\n\tmaxLength  = 76\n\talphanum   = `[A-Za-z0-9]+`\n\tseparators = `[._-]`\n)\n\nvar (\n\t// identifierRe defines the pattern for valid identifiers.\n\tidentifierRe = regexp.MustCompile(reAnchor(alphanum + reGroup(separators+reGroup(alphanum)) + \"*\"))\n)\n\n// Validate returns nil if the string s is a valid identifier.\n//\n// identifiers are similar to the domain name rules according to RFC 1035, section 2.3.1. However\n// rules in this package are relaxed to allow numerals to follow period (\".\") and mixed case is\n// allowed.\n//\n// In general identifiers that pass this validation should be safe for use as filesystem path components.\nfunc Validate(s string) error {\n\tif len(s) == 0 {\n\t\treturn fmt.Errorf(\"identifier must not be empty: %w\", errdefs.ErrInvalidArgument)\n\t}\n\n\tif len(s) > maxLength {\n\t\treturn fmt.Errorf(\"identifier %q greater than maximum length (%d characters): %w\", s, maxLength, errdefs.ErrInvalidArgument)\n\t}\n\n\tif !identifierRe.MatchString(s) {\n\t\treturn fmt.Errorf(\"identifier %q must match %v: %w\", s, identifierRe, errdefs.ErrInvalidArgument)\n\t}\n\treturn nil\n}\n\nfunc reGroup(s string) string {\n\treturn `(?:` + s + `)`\n}\n\nfunc reAnchor(s string) string {\n\treturn `^` + s + `$`\n}\n"
  },
  {
    "path": "container/containerd/identifiers/validate_test.go",
    "content": "// Copyright 2017 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n/*\n   Copyright The containerd Authors.\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n*/\n\npackage identifiers\n\nimport (\n\t\"strings\"\n\t\"testing\"\n\n\t\"github.com/containerd/errdefs\"\n)\n\nfunc TestValidIdentifiers(t *testing.T) {\n\tfor _, input := range []string{\n\t\t\"default\",\n\t\t\"Default\",\n\t\tt.Name(),\n\t\t\"default-default\",\n\t\t\"containerd.io\",\n\t\t\"foo.boo\",\n\t\t\"swarmkit.docker.io\",\n\t\t\"0912341234\",\n\t\t\"task.0.0123456789\",\n\t\t\"container.system-75-f19a.00\",\n\t\t\"underscores_are_allowed\",\n\t\tstrings.Repeat(\"a\", maxLength),\n\t} {\n\t\tt.Run(input, func(t *testing.T) {\n\t\t\tif err := Validate(input); err != nil {\n\t\t\t\tt.Fatalf(\"unexpected error: %v != nil\", err)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestInvalidIdentifiers(t *testing.T) {\n\tfor _, input := range []string{\n\t\t\"\",\n\t\t\".foo..foo\",\n\t\t\"foo/foo\",\n\t\t\"foo/..\",\n\t\t\"foo..foo\",\n\t\t\"foo.-boo\",\n\t\t\"-foo.boo\",\n\t\t\"foo.boo-\",\n\t\t\"but__only_tasteful_underscores\",\n\t\t\"zn--e9.org\", // or something like it!\n\t\t\"default--default\",\n\t\tstrings.Repeat(\"a\", maxLength+1),\n\t} {\n\n\t\tt.Run(input, func(t *testing.T) {\n\t\t\tif err := Validate(input); err == nil {\n\t\t\t\tt.Fatal(\"expected invalid error\")\n\t\t\t} else if !errdefs.IsInvalidArgument(err) {\n\t\t\t\tt.Fatal(\"error should be an invalid identifier error\")\n\t\t\t}\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "container/containerd/install/install.go",
    "content": "// Copyright 2019 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n//go:build linux\n\n// The install package registers containerd.NewPlugin() as the \"containerd\" container provider when imported\npackage install\n\nimport (\n\t\"k8s.io/klog/v2\"\n\n\t\"github.com/google/cadvisor/container\"\n\t\"github.com/google/cadvisor/container/containerd\"\n)\n\nfunc init() {\n\terr := container.RegisterPlugin(\"containerd\", containerd.NewPlugin())\n\tif err != nil {\n\t\tklog.Fatalf(\"Failed to register containerd plugin: %v\", err)\n\t}\n}\n"
  },
  {
    "path": "container/containerd/namespaces/context.go",
    "content": "// Copyright 2017 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n/*\n   Copyright The containerd Authors.\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n*/\n\npackage namespaces\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"os\"\n\n\t\"github.com/containerd/errdefs\"\n\n\t\"github.com/google/cadvisor/container/containerd/identifiers\"\n)\n\nconst (\n\t// NamespaceEnvVar is the environment variable key name\n\tNamespaceEnvVar = \"CONTAINERD_NAMESPACE\"\n\t// Default is the name of the default namespace\n\tDefault = \"default\"\n)\n\ntype namespaceKey struct{}\n\n// WithNamespace sets a given namespace on the context\nfunc WithNamespace(ctx context.Context, namespace string) context.Context {\n\tctx = context.WithValue(ctx, namespaceKey{}, namespace) // set our key for namespace\n\t// also store on the grpc and ttrpc headers so it gets picked up by any clients that\n\t// are using this.\n\treturn withTTRPCNamespaceHeader(withGRPCNamespaceHeader(ctx, namespace), namespace)\n}\n\n// NamespaceFromEnv uses the namespace defined in CONTAINERD_NAMESPACE or\n// default\nfunc NamespaceFromEnv(ctx context.Context) context.Context {\n\tnamespace := os.Getenv(NamespaceEnvVar)\n\tif namespace == \"\" {\n\t\tnamespace = Default\n\t}\n\treturn WithNamespace(ctx, namespace)\n}\n\n// Namespace returns the namespace from the context.\n//\n// The namespace is not guaranteed to be valid.\nfunc Namespace(ctx context.Context) (string, bool) {\n\tnamespace, ok := ctx.Value(namespaceKey{}).(string)\n\tif !ok {\n\t\tif namespace, ok = fromGRPCHeader(ctx); !ok {\n\t\t\treturn fromTTRPCHeader(ctx)\n\t\t}\n\t}\n\treturn namespace, ok\n}\n\n// NamespaceRequired returns the valid namespace from the context or an error.\nfunc NamespaceRequired(ctx context.Context) (string, error) {\n\tnamespace, ok := Namespace(ctx)\n\tif !ok || namespace == \"\" {\n\t\treturn \"\", fmt.Errorf(\"namespace is required: %w\", errdefs.ErrFailedPrecondition)\n\t}\n\tif err := identifiers.Validate(namespace); err != nil {\n\t\treturn \"\", fmt.Errorf(\"namespace validation: %w\", err)\n\t}\n\treturn namespace, nil\n}\n"
  },
  {
    "path": "container/containerd/namespaces/context_test.go",
    "content": "// Copyright 2017 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n/*\n   Copyright The containerd Authors.\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n*/\n\npackage namespaces\n\nimport (\n\t\"context\"\n\t\"os\"\n\t\"testing\"\n)\n\nfunc TestContext(t *testing.T) {\n\tctx := context.Background()\n\tnamespace, ok := Namespace(ctx)\n\tif ok {\n\t\tt.Fatal(\"namespace should not be present\")\n\t}\n\n\tif namespace != \"\" {\n\t\tt.Fatalf(\"namespace should not be defined: got %q\", namespace)\n\t}\n\n\texpected := \"test\"\n\tnctx := WithNamespace(ctx, expected)\n\n\tnamespace, ok = Namespace(nctx)\n\tif !ok {\n\t\tt.Fatal(\"expected to find a namespace\")\n\t}\n\n\tif namespace != expected {\n\t\tt.Fatalf(\"unexpected namespace: %q != %q\", namespace, expected)\n\t}\n}\n\nfunc TestNamespaceFromEnv(t *testing.T) {\n\toldenv := os.Getenv(NamespaceEnvVar)\n\tdefer os.Setenv(NamespaceEnvVar, oldenv) // restore old env var\n\n\tctx := context.Background()\n\tnamespace, ok := Namespace(ctx)\n\tif ok {\n\t\tt.Fatal(\"namespace should not be present\")\n\t}\n\n\tif namespace != \"\" {\n\t\tt.Fatalf(\"namespace should not be defined: got %q\", namespace)\n\t}\n\n\texpected := \"test-namespace\"\n\tos.Setenv(NamespaceEnvVar, expected)\n\tnctx := NamespaceFromEnv(ctx)\n\n\tnamespace, ok = Namespace(nctx)\n\tif !ok {\n\t\tt.Fatal(\"expected to find a namespace\")\n\t}\n\n\tif namespace != expected {\n\t\tt.Fatalf(\"unexpected namespace: %q != %q\", namespace, expected)\n\t}\n}\n"
  },
  {
    "path": "container/containerd/namespaces/grpc.go",
    "content": "// Copyright 2017 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n/*\n   Copyright The containerd Authors.\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n*/\n\npackage namespaces\n\nimport (\n\t\"context\"\n\n\t\"google.golang.org/grpc/metadata\"\n)\n\nconst (\n\t// GRPCHeader defines the header name for specifying a containerd namespace.\n\tGRPCHeader = \"containerd-namespace\"\n)\n\n// NOTE(stevvooe): We can stub this file out if we don't want a grpc dependency here.\n\nfunc withGRPCNamespaceHeader(ctx context.Context, namespace string) context.Context {\n\t// also store on the grpc headers so it gets picked up by any clients that\n\t// are using this.\n\tnsheader := metadata.Pairs(GRPCHeader, namespace)\n\tmd, ok := metadata.FromOutgoingContext(ctx) // merge with outgoing context.\n\tif !ok {\n\t\tmd = nsheader\n\t} else {\n\t\t// order ensures the latest is first in this list.\n\t\tmd = metadata.Join(nsheader, md)\n\t}\n\n\treturn metadata.NewOutgoingContext(ctx, md)\n}\n\nfunc fromGRPCHeader(ctx context.Context) (string, bool) {\n\t// try to extract for use in grpc servers.\n\tmd, ok := metadata.FromIncomingContext(ctx)\n\tif !ok {\n\t\t// TODO(stevvooe): Check outgoing context?\n\t\treturn \"\", false\n\t}\n\n\tvalues := md[GRPCHeader]\n\tif len(values) == 0 {\n\t\treturn \"\", false\n\t}\n\n\treturn values[0], true\n}\n"
  },
  {
    "path": "container/containerd/namespaces/store.go",
    "content": "// Copyright 2017 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n/*\n   Copyright The containerd Authors.\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n*/\n\npackage namespaces\n\nimport \"context\"\n\n// Store provides introspection about namespaces.\n//\n// Note that these are slightly different than other objects, which are record\n// oriented. A namespace is really just a name and a set of labels. Objects\n// that belong to a namespace are returned when the namespace is assigned to a\n// given context.\ntype Store interface {\n\tCreate(ctx context.Context, namespace string, labels map[string]string) error\n\tLabels(ctx context.Context, namespace string) (map[string]string, error)\n\tSetLabel(ctx context.Context, namespace, key, value string) error\n\tList(ctx context.Context) ([]string, error)\n\n\t// Delete removes the namespace. The namespace must be empty to be deleted.\n\tDelete(ctx context.Context, namespace string, opts ...DeleteOpts) error\n}\n\n// DeleteInfo specifies information for the deletion of a namespace\ntype DeleteInfo struct {\n\t// Name of the namespace\n\tName string\n}\n\n// DeleteOpts allows the caller to set options for namespace deletion\ntype DeleteOpts func(context.Context, *DeleteInfo) error\n"
  },
  {
    "path": "container/containerd/namespaces/ttrpc.go",
    "content": "// Copyright 2017 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n/*\n   Copyright The containerd Authors.\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n*/\n\npackage namespaces\n\nimport (\n\t\"context\"\n\n\t\"github.com/containerd/ttrpc\"\n)\n\nconst (\n\t// TTRPCHeader defines the header name for specifying a containerd namespace\n\tTTRPCHeader = \"containerd-namespace-ttrpc\"\n)\n\nfunc copyMetadata(src ttrpc.MD) ttrpc.MD {\n\tmd := ttrpc.MD{}\n\tfor k, v := range src {\n\t\tmd[k] = append(md[k], v...)\n\t}\n\treturn md\n}\n\nfunc withTTRPCNamespaceHeader(ctx context.Context, namespace string) context.Context {\n\tmd, ok := ttrpc.GetMetadata(ctx)\n\tif !ok {\n\t\tmd = ttrpc.MD{}\n\t} else {\n\t\tmd = copyMetadata(md)\n\t}\n\tmd.Set(TTRPCHeader, namespace)\n\treturn ttrpc.WithMetadata(ctx, md)\n}\n\nfunc fromTTRPCHeader(ctx context.Context) (string, bool) {\n\treturn ttrpc.GetMetadataValue(ctx, TTRPCHeader)\n}\n"
  },
  {
    "path": "container/containerd/namespaces/ttrpc_test.go",
    "content": "// Copyright 2017 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n/*\n   Copyright The containerd Authors.\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n*/\n\npackage namespaces\n\nimport (\n\t\"context\"\n\t\"reflect\"\n\t\"testing\"\n\n\t\"github.com/containerd/ttrpc\"\n)\n\nfunc TestCopyTTRPCMetadata(t *testing.T) {\n\tsrc := ttrpc.MD{}\n\tsrc.Set(\"key\", \"a\", \"b\", \"c\", \"d\")\n\tmd := copyMetadata(src)\n\n\tif !reflect.DeepEqual(src, md) {\n\t\tt.Fatalf(\"metadata is copied incorrectly\")\n\t}\n\n\tslice, _ := src.Get(\"key\")\n\tslice[0] = \"z\"\n\tif reflect.DeepEqual(src, md) {\n\t\tt.Fatalf(\"metadata is copied incorrectly\")\n\t}\n}\n\nfunc TestTTRPCNamespaceHeader(t *testing.T) {\n\tctx := context.Background()\n\tnamespace := \"test-namespace\"\n\tctx = withTTRPCNamespaceHeader(ctx, namespace)\n\n\theader, ok := fromTTRPCHeader(ctx)\n\tif !ok || header != namespace {\n\t\tt.Fatalf(\"ttrp namespace header is set incorrectly\")\n\t}\n}\n"
  },
  {
    "path": "container/containerd/pkg/dialer/dialer.go",
    "content": "// Copyright 2017 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n/*\n   Copyright The containerd Authors.\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n*/\n\npackage dialer\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"net\"\n\t\"time\"\n)\n\ntype dialResult struct {\n\tc   net.Conn\n\terr error\n}\n\n// ContextDialer returns a GRPC net.Conn connected to the provided address\nfunc ContextDialer(ctx context.Context, address string) (net.Conn, error) {\n\tif deadline, ok := ctx.Deadline(); ok {\n\t\treturn timeoutDialer(address, time.Until(deadline))\n\t}\n\treturn timeoutDialer(address, 0)\n}\n\n// Dialer returns a GRPC net.Conn connected to the provided address\n// Deprecated: use ContextDialer and grpc.WithContextDialer.\nvar Dialer = timeoutDialer\n\nfunc timeoutDialer(address string, timeout time.Duration) (net.Conn, error) {\n\tvar (\n\t\tstopC = make(chan struct{})\n\t\tsynC  = make(chan *dialResult)\n\t)\n\tgo func() {\n\t\tdefer close(synC)\n\t\tfor {\n\t\t\tselect {\n\t\t\tcase <-stopC:\n\t\t\t\treturn\n\t\t\tdefault:\n\t\t\t\tc, err := dialer(address, timeout)\n\t\t\t\tif isNoent(err) {\n\t\t\t\t\t<-time.After(10 * time.Millisecond)\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tsynC <- &dialResult{c, err}\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\t}()\n\tselect {\n\tcase dr := <-synC:\n\t\treturn dr.c, dr.err\n\tcase <-time.After(timeout):\n\t\tclose(stopC)\n\t\tgo func() {\n\t\t\tdr := <-synC\n\t\t\tif dr != nil && dr.c != nil {\n\t\t\t\tdr.c.Close()\n\t\t\t}\n\t\t}()\n\t\treturn nil, fmt.Errorf(\"dial %s: timeout\", address)\n\t}\n}\n"
  },
  {
    "path": "container/containerd/pkg/dialer/dialer_unix.go",
    "content": "// Copyright 2017 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//go:build !windows\n\n/*\n   Copyright The containerd Authors.\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n*/\n\npackage dialer\n\nimport (\n\t\"fmt\"\n\t\"net\"\n\t\"os\"\n\t\"strings\"\n\t\"syscall\"\n\t\"time\"\n)\n\n// DialAddress returns the address with unix:// prepended to the\n// provided address\nfunc DialAddress(address string) string {\n\treturn fmt.Sprintf(\"unix://%s\", address)\n}\n\nfunc isNoent(err error) bool {\n\tif err != nil {\n\t\tif nerr, ok := err.(*net.OpError); ok {\n\t\t\tif serr, ok := nerr.Err.(*os.SyscallError); ok {\n\t\t\t\tif serr.Err == syscall.ENOENT {\n\t\t\t\t\treturn true\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn false\n}\n\nfunc dialer(address string, timeout time.Duration) (net.Conn, error) {\n\taddress = strings.TrimPrefix(address, \"unix://\")\n\treturn net.DialTimeout(\"unix\", address, timeout)\n}\n"
  },
  {
    "path": "container/containerd/pkg/dialer/dialer_windows.go",
    "content": "// Copyright 2017 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n/*\n   Copyright The containerd Authors.\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n*/\n\npackage dialer\n\nimport (\n\t\"net\"\n\t\"os\"\n\t\"time\"\n\n\twinio \"github.com/Microsoft/go-winio\"\n)\n\nfunc isNoent(err error) bool {\n\treturn os.IsNotExist(err)\n}\n\nfunc dialer(address string, timeout time.Duration) (net.Conn, error) {\n\treturn winio.DialPipe(address, &timeout)\n}\n\n// DialAddress returns the dial address\nfunc DialAddress(address string) string {\n\treturn address\n}\n"
  },
  {
    "path": "container/containerd/plugin.go",
    "content": "// Copyright 2019 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n//go:build linux\n\npackage containerd\n\nimport (\n\t\"github.com/google/cadvisor/container\"\n\t\"github.com/google/cadvisor/fs\"\n\tinfo \"github.com/google/cadvisor/info/v1\"\n\t\"github.com/google/cadvisor/watcher\"\n)\n\n// NewPlugin returns an implementation of container.Plugin suitable for passing to container.RegisterPlugin()\nfunc NewPlugin() container.Plugin {\n\treturn &plugin{}\n}\n\ntype plugin struct{}\n\nfunc (p *plugin) InitializeFSContext(context *fs.Context) error {\n\treturn nil\n}\n\nfunc (p *plugin) Register(factory info.MachineInfoFactory, fsInfo fs.FsInfo, includedMetrics container.MetricSet) (watcher.ContainerWatcher, error) {\n\terr := Register(factory, fsInfo, includedMetrics)\n\treturn nil, err\n}\n"
  },
  {
    "path": "container/crio/client.go",
    "content": "// Copyright 2017 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage crio\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"flag\"\n\t\"fmt\"\n\t\"io\"\n\t\"net\"\n\t\"net/http\"\n\t\"sync\"\n\t\"syscall\"\n\t\"time\"\n)\n\nvar crioClientTimeout = flag.Duration(\"crio_client_timeout\", time.Duration(0), \"CRI-O client timeout. Default is no timeout.\")\n\nconst (\n\tCrioSocket            = \"/var/run/crio/crio.sock\"\n\tmaxUnixSocketPathSize = len(syscall.RawSockaddrUnix{}.Path)\n)\n\nvar (\n\ttheClient      CrioClient\n\tclientErr      error\n\tcrioClientOnce sync.Once\n)\n\n// Info represents CRI-O information as sent by the CRI-O server\ntype Info struct {\n\tStorageDriver string `json:\"storage_driver\"`\n\tStorageRoot   string `json:\"storage_root\"`\n\tStorageImage  string `json:\"storage_image\"`\n\tCgroupDriver  string `json:\"cgroup_driver\"`\n}\n\n// ContainerInfo represents a given container information\ntype ContainerInfo struct {\n\tName        string            `json:\"name\"`\n\tPid         int               `json:\"pid\"`\n\tImage       string            `json:\"image\"`\n\tCreatedTime int64             `json:\"created_time\"`\n\tLabels      map[string]string `json:\"labels\"`\n\tAnnotations map[string]string `json:\"annotations\"`\n\tLogPath     string            `json:\"log_path\"`\n\tRoot        string            `json:\"root\"`\n\tIP          string            `json:\"ip_address\"`\n\tIPs         []string          `json:\"ip_addresses\"`\n}\n\ntype CrioClient interface {\n\tInfo() (Info, error)\n\tContainerInfo(string) (*ContainerInfo, error)\n}\n\ntype crioClientImpl struct {\n\tclient *http.Client\n}\n\nfunc configureUnixTransport(tr *http.Transport, proto, addr string) error {\n\tif len(addr) > maxUnixSocketPathSize {\n\t\treturn fmt.Errorf(\"unix socket path %q is too long\", addr)\n\t}\n\t// No need for compression in local communications.\n\ttr.DisableCompression = true\n\ttr.DialContext = func(_ context.Context, _, _ string) (net.Conn, error) {\n\t\treturn net.DialTimeout(proto, addr, 32*time.Second)\n\t}\n\treturn nil\n}\n\n// Client returns a new configured CRI-O client\nfunc Client() (CrioClient, error) {\n\tcrioClientOnce.Do(func() {\n\t\ttr := new(http.Transport)\n\t\ttheClient = nil\n\t\tif clientErr = configureUnixTransport(tr, \"unix\", CrioSocket); clientErr != nil {\n\t\t\treturn\n\t\t}\n\t\ttheClient = &crioClientImpl{\n\t\t\tclient: &http.Client{\n\t\t\t\tTransport: tr,\n\t\t\t\tTimeout:   *crioClientTimeout,\n\t\t\t},\n\t\t}\n\t})\n\treturn theClient, clientErr\n}\n\nfunc getRequest(path string) (*http.Request, error) {\n\treq, err := http.NewRequest(\"GET\", path, nil)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\t// For local communications over a unix socket, it doesn't matter what\n\t// the host is. We just need a valid and meaningful host name.\n\treq.Host = \"crio\"\n\treq.URL.Host = CrioSocket\n\treq.URL.Scheme = \"http\"\n\treturn req, nil\n}\n\n// Info returns generic info from the CRI-O server\nfunc (c *crioClientImpl) Info() (Info, error) {\n\tinfo := Info{}\n\treq, err := getRequest(\"/info\")\n\tif err != nil {\n\t\treturn info, err\n\t}\n\tresp, err := c.client.Do(req)\n\tif err != nil {\n\t\treturn info, err\n\t}\n\tdefer resp.Body.Close()\n\tif err := json.NewDecoder(resp.Body).Decode(&info); err != nil {\n\t\treturn info, err\n\t}\n\treturn info, nil\n}\n\n// ContainerInfo returns information about a given container\nfunc (c *crioClientImpl) ContainerInfo(id string) (*ContainerInfo, error) {\n\treq, err := getRequest(\"/containers/\" + id)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tcInfo := ContainerInfo{}\n\tresp, err := c.client.Do(req)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tdefer resp.Body.Close()\n\n\t// golang's http.Do doesn't return an error if non 200 response code is returned\n\t// handle this case here, rather than failing to decode the body\n\tif resp.StatusCode != http.StatusOK {\n\t\trespBody, err := io.ReadAll(resp.Body)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"error finding container %s: status %d\", id, resp.StatusCode)\n\t\t}\n\t\treturn nil, fmt.Errorf(\"error finding container %s: status %d returned error %s\", id, resp.StatusCode, string(respBody))\n\t}\n\n\tif err := json.NewDecoder(resp.Body).Decode(&cInfo); err != nil {\n\t\treturn nil, err\n\t}\n\tif len(cInfo.IP) > 0 {\n\t\treturn &cInfo, nil\n\t}\n\tif len(cInfo.IPs) > 0 {\n\t\tcInfo.IP = cInfo.IPs[0]\n\t}\n\treturn &cInfo, nil\n}\n"
  },
  {
    "path": "container/crio/client_test.go",
    "content": "// Copyright 2017 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage crio\n\nimport \"fmt\"\n\ntype crioClientMock struct {\n\tinfo           Info\n\tcontainersInfo map[string]*ContainerInfo\n\terr            error\n}\n\nfunc (c *crioClientMock) Info() (Info, error) {\n\tif c.err != nil {\n\t\treturn Info{}, c.err\n\t}\n\treturn c.info, nil\n}\n\nfunc (c *crioClientMock) ContainerInfo(id string) (*ContainerInfo, error) {\n\tif c.err != nil {\n\t\treturn nil, c.err\n\t}\n\tcInfo, ok := c.containersInfo[id]\n\tif !ok {\n\t\treturn nil, fmt.Errorf(\"no container with id %s\", id)\n\t}\n\treturn cInfo, nil\n}\n\nfunc mockCrioClient(info Info, containersInfo map[string]*ContainerInfo, err error) CrioClient {\n\treturn &crioClientMock{\n\t\terr:            err,\n\t\tinfo:           info,\n\t\tcontainersInfo: containersInfo,\n\t}\n}\n"
  },
  {
    "path": "container/crio/factory.go",
    "content": "// Copyright 2017 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n//go:build linux\n\npackage crio\n\nimport (\n\t\"fmt\"\n\t\"path\"\n\t\"regexp\"\n\t\"strings\"\n\n\t\"github.com/google/cadvisor/container\"\n\t\"github.com/google/cadvisor/container/libcontainer\"\n\t\"github.com/google/cadvisor/fs\"\n\tinfo \"github.com/google/cadvisor/info/v1\"\n\t\"github.com/google/cadvisor/watcher\"\n\n\t\"k8s.io/klog/v2\"\n)\n\n// The namespace under which crio aliases are unique.\nconst CrioNamespace = \"crio\"\n\n// The namespace suffix under which crio aliases are unique when using systemd.\nconst CrioNamespaceSuffix = \".scope\"\n\n// The namespace systemd runs components under.\nconst SystemdNamespace = \"system-systemd\"\n\n// Regexp that identifies CRI-O cgroups\nvar crioCgroupRegexp = regexp.MustCompile(`([a-z0-9]{64})`)\n\ntype storageDriver string\n\nconst (\n\t// TODO add full set of supported drivers in future..\n\toverlayStorageDriver  storageDriver = \"overlay\"\n\toverlay2StorageDriver storageDriver = \"overlay2\"\n)\n\ntype crioFactory struct {\n\tmachineInfoFactory info.MachineInfoFactory\n\n\tstorageDriver storageDriver\n\tstorageDir    string\n\n\t// Information about the mounted cgroup subsystems.\n\tcgroupSubsystems map[string]string\n\n\t// Information about mounted filesystems.\n\tfsInfo fs.FsInfo\n\n\tincludedMetrics container.MetricSet\n\n\tclient CrioClient\n\n\tcgroupDriver string\n}\n\nfunc (f *crioFactory) String() string {\n\treturn CrioNamespace\n}\n\nfunc (f *crioFactory) NewContainerHandler(name string, metadataEnvAllowList []string, inHostNamespace bool) (handler container.ContainerHandler, err error) {\n\tclient, err := Client()\n\tif err != nil {\n\t\treturn\n\t}\n\thandler, err = newCrioContainerHandler(\n\t\tclient,\n\t\tname,\n\t\tf.machineInfoFactory,\n\t\tf.fsInfo,\n\t\tf.storageDriver,\n\t\tf.storageDir,\n\t\tf.cgroupSubsystems,\n\t\tinHostNamespace,\n\t\tmetadataEnvAllowList,\n\t\tf.includedMetrics,\n\t)\n\treturn\n}\n\n// Returns the CRIO ID from the full container name.\nfunc ContainerNameToCrioId(name string) string {\n\tid := path.Base(name)\n\n\tif matches := crioCgroupRegexp.FindStringSubmatch(id); matches != nil {\n\t\treturn matches[1]\n\t}\n\n\treturn id\n}\n\n// isContainerName returns true if the cgroup with associated name\n// corresponds to a crio container.\nfunc isContainerName(name string) bool {\n\t// always ignore .mount cgroup even if associated with crio and delegate to systemd\n\tif strings.HasSuffix(name, \".mount\") {\n\t\treturn false\n\t}\n\treturn crioCgroupRegexp.MatchString(path.Base(name))\n}\n\n// crio handles all containers under /crio\nfunc (f *crioFactory) CanHandleAndAccept(name string) (bool, bool, error) {\n\tif strings.HasPrefix(path.Base(name), \"crio-conmon\") {\n\t\t// TODO(runcom): should we include crio-conmon cgroups?\n\t\treturn false, false, nil\n\t}\n\tif strings.HasPrefix(path.Base(name), SystemdNamespace) {\n\t\treturn true, false, nil\n\t}\n\tif !strings.HasPrefix(path.Base(name), CrioNamespace) {\n\t\treturn false, false, nil\n\t}\n\t// if the container is not associated with CRI-O, we can't handle it or accept it.\n\tif !isContainerName(name) {\n\t\treturn false, false, nil\n\t}\n\n\t// When using systemd as the cgroup driver, sandbox containers don't have\n\t// the .scope suffix. Filter them out to prevent cadvisor from trying to\n\t// query cri-o for containers that don't exist in the runtime, which causes\n\t// 404 errors and can lead to deadlocks during kubelet restart.\n\t// See: https://github.com/cri-o/cri-o/issues/8748\n\t// See: https://github.com/google/cadvisor/pull/3457\n\tif f.cgroupDriver == \"systemd\" {\n\t\tif !strings.HasSuffix(path.Base(name), CrioNamespaceSuffix) {\n\t\t\t// This is a sandbox container when using systemd\n\t\t\treturn true, false, nil\n\t\t}\n\t}\n\treturn true, true, nil\n}\n\nfunc (f *crioFactory) DebugInfo() map[string][]string {\n\treturn map[string][]string{}\n}\n\n// Register root container before running this function!\nfunc Register(factory info.MachineInfoFactory, fsInfo fs.FsInfo, includedMetrics container.MetricSet) error {\n\tclient, err := Client()\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tinfo, err := client.Info()\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t// TODO determine crio version so we can work differently w/ future versions if needed\n\n\tcgroupSubsystems, err := libcontainer.GetCgroupSubsystems(includedMetrics)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to get cgroup subsystems: %v\", err)\n\t}\n\n\tklog.V(1).Infof(\"Registering CRI-O factory\")\n\tf := &crioFactory{\n\t\tclient:             client,\n\t\tcgroupSubsystems:   cgroupSubsystems,\n\t\tfsInfo:             fsInfo,\n\t\tmachineInfoFactory: factory,\n\t\tstorageDriver:      storageDriver(info.StorageDriver),\n\t\tstorageDir:         info.StorageRoot,\n\t\tincludedMetrics:    includedMetrics,\n\t\tcgroupDriver:       info.CgroupDriver,\n\t}\n\n\tcontainer.RegisterContainerHandlerFactory(f, []watcher.ContainerWatchSource{watcher.Raw})\n\treturn nil\n}\n"
  },
  {
    "path": "container/crio/factory_test.go",
    "content": "// Copyright 2017 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n//go:build linux\n\npackage crio\n\nimport (\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/assert\"\n)\n\nfunc TestCanHandleAndAccept(t *testing.T) {\n\ttests := []struct {\n\t\tname          string\n\t\tcgroupDriver  string\n\t\tpath          string\n\t\twantCanHandle bool\n\t\twantCanAccept bool\n\t}{\n\t\t// Systemd behavior - sandbox containers (without .scope) are filtered\n\t\t{\n\t\t\tname:          \"systemd: sandbox container without .scope\",\n\t\t\tcgroupDriver:  \"systemd\",\n\t\t\tpath:          \"/kubepods/pod068e8fa0-9213-11e7-a01f-507b9d4141fa/crio-81e5c2990803c383229c9680ce964738d5e566d97f5bd436ac34808d2ec75d5f\",\n\t\t\twantCanHandle: true,\n\t\t\twantCanAccept: false,\n\t\t},\n\t\t{\n\t\t\tname:          \"systemd: regular container with .scope\",\n\t\t\tcgroupDriver:  \"systemd\",\n\t\t\tpath:          \"/kubepods/pod068e8fa0-9213-11e7-a01f-507b9d4141fa/crio-81e5c2990803c383229c9680ce964738d5e566d97f5bd436ac34808d2ec75d5f.scope\",\n\t\t\twantCanHandle: true,\n\t\t\twantCanAccept: true,\n\t\t},\n\t\t// Non-systemd (cgroupfs) behavior - all valid containers accepted\n\t\t{\n\t\t\tname:          \"cgroupfs: container without .scope\",\n\t\t\tcgroupDriver:  \"cgroupfs\",\n\t\t\tpath:          \"/kubepods/pod068e8fa0-9213-11e7-a01f-507b9d4141fa/crio-81e5c2990803c383229c9680ce964738d5e566d97f5bd436ac34808d2ec75d5f\",\n\t\t\twantCanHandle: true,\n\t\t\twantCanAccept: true,\n\t\t},\n\t\t{\n\t\t\tname:          \"cgroupfs: container with .scope\",\n\t\t\tcgroupDriver:  \"cgroupfs\",\n\t\t\tpath:          \"/kubepods/pod068e8fa0-9213-11e7-a01f-507b9d4141fa/crio-81e5c2990803c383229c9680ce964738d5e566d97f5bd436ac34808d2ec75d5f.scope\",\n\t\t\twantCanHandle: true,\n\t\t\twantCanAccept: true,\n\t\t},\n\t\t// Common cases (same behavior for both systemd and cgroupfs)\n\t\t{\n\t\t\tname:          \"system-systemd component\",\n\t\t\tcgroupDriver:  \"systemd\",\n\t\t\tpath:          \"/system.slice/system-systemd\\\\x2dcoredump.slice\",\n\t\t\twantCanHandle: true,\n\t\t\twantCanAccept: false,\n\t\t},\n\t\t{\n\t\t\tname:          \"mount cgroup\",\n\t\t\tcgroupDriver:  \"systemd\",\n\t\t\tpath:          \"/kubepods/pod068e8fa0-9213-11e7-a01f-507b9d4141fa/crio-81e5c2990803c383229c9680ce964738d5e566d97f5bd436ac34808d2ec75d5f.mount\",\n\t\t\twantCanHandle: false,\n\t\t\twantCanAccept: false,\n\t\t},\n\t\t{\n\t\t\tname:          \"crio-conmon container\",\n\t\t\tcgroupDriver:  \"systemd\",\n\t\t\tpath:          \"/kubepods/pod068e8fa0-9213-11e7-a01f-507b9d4141fa/crio-conmon-81e5c2990803c383229c9680ce964738d5e566d97f5bd436ac34808d2ec75d5f\",\n\t\t\twantCanHandle: false,\n\t\t\twantCanAccept: false,\n\t\t},\n\t\t{\n\t\t\tname:          \"invalid container ID\",\n\t\t\tcgroupDriver:  \"systemd\",\n\t\t\tpath:          \"/kubepods/pod068e8fa0-9213-11e7-a01f-507b9d4141fa/crio-990803c383229c9680ce964738d5e566d97f5bd436ac34808d2ec75\",\n\t\t\twantCanHandle: false,\n\t\t\twantCanAccept: false,\n\t\t},\n\t}\n\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tf := &crioFactory{\n\t\t\t\tcgroupDriver: tt.cgroupDriver,\n\t\t\t}\n\n\t\t\tcanHandle, canAccept, err := f.CanHandleAndAccept(tt.path)\n\t\t\tassert.NoError(t, err)\n\t\t\tassert.Equal(t, tt.wantCanHandle, canHandle, \"canHandle mismatch\")\n\t\t\tassert.Equal(t, tt.wantCanAccept, canAccept, \"canAccept mismatch\")\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "container/crio/handler.go",
    "content": "// Copyright 2017 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n//go:build linux\n\n// Handler for CRI-O containers.\npackage crio\n\nimport (\n\t\"fmt\"\n\t\"path/filepath\"\n\t\"strconv\"\n\t\"strings\"\n\n\t\"github.com/opencontainers/cgroups\"\n\n\t\"github.com/google/cadvisor/container\"\n\t\"github.com/google/cadvisor/container/common\"\n\tcontainerlibcontainer \"github.com/google/cadvisor/container/libcontainer\"\n\t\"github.com/google/cadvisor/fs\"\n\tinfo \"github.com/google/cadvisor/info/v1\"\n)\n\ntype crioContainerHandler struct {\n\tclient CrioClient\n\tname   string\n\n\tmachineInfoFactory info.MachineInfoFactory\n\n\t// Absolute path to the cgroup hierarchies of this container.\n\t// (e.g.: \"cpu\" -> \"/sys/fs/cgroup/cpu/test\")\n\tcgroupPaths map[string]string\n\n\t// the CRI-O storage driver\n\tstorageDriver    storageDriver\n\tfsInfo           fs.FsInfo\n\trootfsStorageDir string\n\n\t// Metadata associated with the container.\n\tenvs   map[string]string\n\tlabels map[string]string\n\n\t// TODO\n\t// crio version handling...\n\n\t// Image name used for this container.\n\timage string\n\n\t// The network mode of the container\n\t// TODO\n\n\t// Filesystem handler.\n\tfsHandler common.FsHandler\n\n\t// The IP address of the container\n\tipAddress string\n\n\tincludedMetrics container.MetricSet\n\n\treference info.ContainerReference\n\n\tlibcontainerHandler *containerlibcontainer.Handler\n\tcgroupManager       cgroups.Manager\n\trootFs              string\n\tpidKnown            bool\n}\n\nvar _ container.ContainerHandler = &crioContainerHandler{}\n\n// newCrioContainerHandler returns a new container.ContainerHandler\nfunc newCrioContainerHandler(\n\tclient CrioClient,\n\tname string,\n\tmachineInfoFactory info.MachineInfoFactory,\n\tfsInfo fs.FsInfo,\n\tstorageDriver storageDriver,\n\tstorageDir string,\n\tcgroupSubsystems map[string]string,\n\tinHostNamespace bool,\n\tmetadataEnvAllowList []string,\n\tincludedMetrics container.MetricSet,\n) (container.ContainerHandler, error) {\n\t// Create the cgroup paths.\n\tcgroupPaths := common.MakeCgroupPaths(cgroupSubsystems, name)\n\n\t// Generate the equivalent cgroup manager for this container.\n\tcgroupManager, err := containerlibcontainer.NewCgroupManager(name, cgroupPaths)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\trootFs := \"/\"\n\tif !inHostNamespace {\n\t\trootFs = \"/rootfs\"\n\t}\n\n\tid := ContainerNameToCrioId(name)\n\tpidKnown := true\n\n\tcInfo, err := client.ContainerInfo(id)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif cInfo.Pid == 0 {\n\t\t// If pid is not known yet, network related stats can not be retrieved by the\n\t\t// libcontainer handler GetStats().  In this case, the crio handler GetStats()\n\t\t// will reattempt to get the pid and, if now known, will construct the libcontainer\n\t\t// handler.  This libcontainer handler is then cached and reused without additional\n\t\t// calls to crio.\n\t\tpidKnown = false\n\t}\n\n\t// passed to fs handler below ...\n\t// XXX: this is using the full container logpath, as constructed by the CRI\n\t// /var/log/pods/<pod_uuid>/container_instance.log\n\t// It's not actually a log dir, as the CRI doesn't have per-container dirs\n\t// under /var/log/pods/<pod_uuid>/\n\t// We can't use /var/log/pods/<pod_uuid>/ to count per-container log usage.\n\t// We use the container log file directly.\n\tstorageLogDir := cInfo.LogPath\n\n\t// Determine the rootfs storage dir\n\trootfsStorageDir := cInfo.Root\n\t// TODO(runcom): CRI-O doesn't strip /merged but we need to in order to\n\t// get device ID from root, otherwise, it's going to error out as overlay\n\t// mounts doesn't have fixed dev ids.\n\trootfsStorageDir = strings.TrimSuffix(rootfsStorageDir, \"/merged\")\n\tswitch storageDriver {\n\tcase overlayStorageDriver, overlay2StorageDriver:\n\t\t// overlay and overlay2 driver are the same \"overlay2\" driver so treat\n\t\t// them the same.\n\t\trootfsStorageDir = filepath.Join(rootfsStorageDir, \"diff\")\n\t}\n\n\tcontainerReference := info.ContainerReference{\n\t\tId:        id,\n\t\tName:      name,\n\t\tAliases:   []string{cInfo.Name, id},\n\t\tNamespace: CrioNamespace,\n\t}\n\n\t// Find out if we need network metrics reported for this container.\n\t// Containers that don't have their own network -- this includes\n\t// containers running in Kubernetes pods that use the network of the\n\t// infrastructure container -- does not need their stats to be\n\t// reported. This stops metrics being reported multiple times for each\n\t// container in a pod.\n\tmetrics := common.RemoveNetMetrics(includedMetrics, cInfo.Labels[\"io.kubernetes.container.name\"] != \"POD\")\n\n\tlibcontainerHandler := containerlibcontainer.NewHandler(cgroupManager, rootFs, cInfo.Pid, metrics)\n\n\t// TODO: extract object mother method\n\thandler := &crioContainerHandler{\n\t\tclient:              client,\n\t\tname:                name,\n\t\tmachineInfoFactory:  machineInfoFactory,\n\t\tcgroupPaths:         cgroupPaths,\n\t\tstorageDriver:       storageDriver,\n\t\tfsInfo:              fsInfo,\n\t\trootfsStorageDir:    rootfsStorageDir,\n\t\tenvs:                make(map[string]string),\n\t\tlabels:              cInfo.Labels,\n\t\tincludedMetrics:     metrics,\n\t\treference:           containerReference,\n\t\tlibcontainerHandler: libcontainerHandler,\n\t\tcgroupManager:       cgroupManager,\n\t\trootFs:              rootFs,\n\t\tpidKnown:            pidKnown,\n\t}\n\n\thandler.image = cInfo.Image\n\t// TODO: we wantd to know graph driver DeviceId (dont think this is needed now)\n\n\t// ignore err and get zero as default, this happens with sandboxes, not sure why...\n\t// kube isn't sending restart count in labels for sandboxes.\n\trestartCount, _ := strconv.Atoi(cInfo.Annotations[\"io.kubernetes.container.restartCount\"])\n\t// Only adds restartcount label if it's greater than 0\n\tif restartCount > 0 {\n\t\thandler.labels[\"restartcount\"] = strconv.Itoa(restartCount)\n\t}\n\n\thandler.ipAddress = cInfo.IP\n\n\t// we optionally collect disk usage metrics\n\tif includedMetrics.Has(container.DiskUsageMetrics) {\n\t\thandler.fsHandler = common.NewFsHandler(common.DefaultPeriod, rootfsStorageDir, storageLogDir, fsInfo)\n\t}\n\t// TODO for env vars we wanted to show from container.Config.Env from whitelist\n\t//for _, exposedEnv := range metadataEnvAllowList {\n\t//klog.V(4).Infof(\"TODO env whitelist: %v\", exposedEnv)\n\t//}\n\n\treturn handler, nil\n}\n\nfunc (h *crioContainerHandler) Start() {\n\tif h.fsHandler != nil {\n\t\th.fsHandler.Start()\n\t}\n}\n\nfunc (h *crioContainerHandler) Cleanup() {\n\tif h.fsHandler != nil {\n\t\th.fsHandler.Stop()\n\t}\n}\n\nfunc (h *crioContainerHandler) ContainerReference() (info.ContainerReference, error) {\n\treturn h.reference, nil\n}\n\nfunc (h *crioContainerHandler) GetSpec() (info.ContainerSpec, error) {\n\thasFilesystem := h.includedMetrics.Has(container.DiskUsageMetrics)\n\thasNet := h.includedMetrics.Has(container.NetworkUsageMetrics)\n\tspec, err := common.GetSpec(h.cgroupPaths, h.machineInfoFactory, hasNet, hasFilesystem)\n\n\tspec.Labels = h.labels\n\tspec.Envs = h.envs\n\tspec.Image = h.image\n\n\treturn spec, err\n}\n\nfunc (h *crioContainerHandler) getFsStats(stats *info.ContainerStats) error {\n\tmi, err := h.machineInfoFactory.GetMachineInfo()\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tif h.includedMetrics.Has(container.DiskIOMetrics) {\n\t\tcommon.AssignDeviceNamesToDiskStats((*common.MachineInfoNamer)(mi), &stats.DiskIo)\n\t}\n\n\tif !h.includedMetrics.Has(container.DiskUsageMetrics) {\n\t\treturn nil\n\t}\n\tvar device string\n\tswitch h.storageDriver {\n\tcase overlay2StorageDriver, overlayStorageDriver:\n\t\tdeviceInfo, err := h.fsInfo.GetDirFsDevice(h.rootfsStorageDir)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"unable to determine device info for dir: %v: %v\", h.rootfsStorageDir, err)\n\t\t}\n\t\tdevice = deviceInfo.Device\n\tdefault:\n\t\treturn nil\n\t}\n\n\tvar (\n\t\tlimit  uint64\n\t\tfsType string\n\t)\n\n\t// crio does not impose any filesystem limits for containers. So use capacity as limit.\n\tfor _, fs := range mi.Filesystems {\n\t\tif fs.Device == device {\n\t\t\tlimit = fs.Capacity\n\t\t\tfsType = fs.Type\n\t\t\tbreak\n\t\t}\n\t}\n\n\tif fsType == \"\" {\n\t\treturn fmt.Errorf(\"unable to determine fs type for device: %v\", device)\n\t}\n\tfsStat := info.FsStats{Device: device, Type: fsType, Limit: limit}\n\tusage := h.fsHandler.Usage()\n\tfsStat.BaseUsage = usage.BaseUsageBytes\n\tfsStat.Usage = usage.TotalUsageBytes\n\tfsStat.Inodes = usage.InodeUsage\n\n\tstats.Filesystem = append(stats.Filesystem, fsStat)\n\n\treturn nil\n}\n\nfunc (h *crioContainerHandler) getLibcontainerHandler() *containerlibcontainer.Handler {\n\tif h.pidKnown {\n\t\treturn h.libcontainerHandler\n\t}\n\n\tid := ContainerNameToCrioId(h.name)\n\n\tcInfo, err := h.client.ContainerInfo(id)\n\tif err != nil || cInfo.Pid == 0 {\n\t\treturn h.libcontainerHandler\n\t}\n\n\th.pidKnown = true\n\th.libcontainerHandler = containerlibcontainer.NewHandler(h.cgroupManager, h.rootFs, cInfo.Pid, h.includedMetrics)\n\n\treturn h.libcontainerHandler\n}\n\nfunc (h *crioContainerHandler) GetStats() (*info.ContainerStats, error) {\n\tlibcontainerHandler := h.getLibcontainerHandler()\n\tstats, err := libcontainerHandler.GetStats()\n\tif err != nil {\n\t\treturn stats, err\n\t}\n\n\tif h.includedMetrics.Has(container.NetworkUsageMetrics) && len(stats.Network.Interfaces) == 0 {\n\t\t// No network related information indicates that the pid of the\n\t\t// container is not longer valid and we need to ask crio to\n\t\t// provide the pid of another container from that pod\n\t\th.pidKnown = false\n\t\treturn stats, nil\n\t}\n\t// Get filesystem stats.\n\terr = h.getFsStats(stats)\n\tif err != nil {\n\t\treturn stats, err\n\t}\n\n\treturn stats, nil\n}\n\nfunc (h *crioContainerHandler) ListContainers(listType container.ListType) ([]info.ContainerReference, error) {\n\t// No-op for Docker driver.\n\treturn []info.ContainerReference{}, nil\n}\n\nfunc (h *crioContainerHandler) GetCgroupPath(resource string) (string, error) {\n\tvar res string\n\tif !cgroups.IsCgroup2UnifiedMode() {\n\t\tres = resource\n\t}\n\tpath, ok := h.cgroupPaths[res]\n\tif !ok {\n\t\treturn \"\", fmt.Errorf(\"could not find path for resource %q for container %q\", resource, h.reference.Name)\n\t}\n\treturn path, nil\n}\n\nfunc (h *crioContainerHandler) GetContainerLabels() map[string]string {\n\treturn h.labels\n}\n\nfunc (h *crioContainerHandler) GetContainerIPAddress() string {\n\treturn h.ipAddress\n}\n\nfunc (h *crioContainerHandler) ListProcesses(listType container.ListType) ([]int, error) {\n\treturn h.libcontainerHandler.GetProcesses()\n}\n\nfunc (h *crioContainerHandler) Exists() bool {\n\treturn common.CgroupExists(h.cgroupPaths)\n}\n\nfunc (h *crioContainerHandler) Type() container.ContainerType {\n\treturn container.ContainerTypeCrio\n}\n\nfunc (h *crioContainerHandler) GetExitCode() (int, error) {\n\treturn -1, fmt.Errorf(\"exit code not available from CRI-O API\")\n}\n"
  },
  {
    "path": "container/crio/handler_test.go",
    "content": "// Copyright 2017 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n//go:build linux\n\npackage crio\n\nimport (\n\t\"fmt\"\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/assert\"\n\n\t\"github.com/google/cadvisor/container\"\n\t\"github.com/google/cadvisor/fs\"\n\tinfo \"github.com/google/cadvisor/info/v1\"\n)\n\nfunc TestHandler(t *testing.T) {\n\tas := assert.New(t)\n\ttype testCase struct {\n\t\tclient               CrioClient\n\t\tname                 string\n\t\tmachineInfoFactory   info.MachineInfoFactory\n\t\tfsInfo               fs.FsInfo\n\t\tstorageDriver        storageDriver\n\t\tstorageDir           string\n\t\tcgroupSubsystems     map[string]string\n\t\tinHostNamespace      bool\n\t\tmetadataEnvAllowList []string\n\t\tincludedMetrics      container.MetricSet\n\n\t\thasErr         bool\n\t\terrContains    string\n\t\tcheckReference *info.ContainerReference\n\t}\n\tfor _, ts := range []testCase{\n\t\t{\n\t\t\tmockCrioClient(Info{}, nil, fmt.Errorf(\"no client returned\")),\n\t\t\t\"/kubepods/pod068e8fa0-9213-11e7-a01f-507b9d4141fa/crio-81e5c2990803c383229c9680ce964738d5e566d97f5bd436ac34808d2ec75d5f\",\n\t\t\tnil,\n\t\t\tnil,\n\t\t\t\"\",\n\t\t\t\"\",\n\t\t\tnil,\n\t\t\tfalse,\n\t\t\tnil,\n\t\t\tnil,\n\n\t\t\ttrue,\n\t\t\t\"no client returned\",\n\t\t\tnil,\n\t\t},\n\t\t{\n\t\t\tmockCrioClient(Info{}, nil, nil),\n\t\t\t\"/kubepods/pod068e8fa0-9213-11e7-a01f-507b9d4141fa/crio-81e5c2990803c383229c9680ce964738d5e566d97f5bd436ac34808d2ec75d5f\",\n\t\t\tnil,\n\t\t\tnil,\n\t\t\t\"\",\n\t\t\t\"\",\n\t\t\tnil,\n\t\t\tfalse,\n\t\t\tnil,\n\t\t\tnil,\n\n\t\t\ttrue,\n\t\t\t\"no container with id 81e5c2990803c383229c9680ce964738d5e566d97f5bd436ac34808d2ec75d5f\",\n\t\t\tnil,\n\t\t},\n\t\t{\n\t\t\tmockCrioClient(\n\t\t\t\tInfo{},\n\t\t\t\tmap[string]*ContainerInfo{\"81e5c2990803c383229c9680ce964738d5e566d97f5bd436ac34808d2ec75d5f\": {Name: \"test\", Labels: map[string]string{\"io.kubernetes.container.name\": \"POD\"}}},\n\t\t\t\tnil,\n\t\t\t),\n\t\t\t\"/kubepods/pod068e8fa0-9213-11e7-a01f-507b9d4141fa/crio-81e5c2990803c383229c9680ce964738d5e566d97f5bd436ac34808d2ec75d5f\",\n\t\t\tnil,\n\t\t\tnil,\n\t\t\t\"\",\n\t\t\t\"\",\n\t\t\tnil,\n\t\t\tfalse,\n\t\t\tnil,\n\t\t\tnil,\n\n\t\t\tfalse,\n\t\t\t\"\",\n\t\t\t&info.ContainerReference{\n\t\t\t\tId:        \"81e5c2990803c383229c9680ce964738d5e566d97f5bd436ac34808d2ec75d5f\",\n\t\t\t\tName:      \"/kubepods/pod068e8fa0-9213-11e7-a01f-507b9d4141fa/crio-81e5c2990803c383229c9680ce964738d5e566d97f5bd436ac34808d2ec75d5f\",\n\t\t\t\tAliases:   []string{\"test\", \"81e5c2990803c383229c9680ce964738d5e566d97f5bd436ac34808d2ec75d5f\"},\n\t\t\t\tNamespace: CrioNamespace,\n\t\t\t},\n\t\t},\n\t} {\n\t\thandler, err := newCrioContainerHandler(ts.client, ts.name, ts.machineInfoFactory, ts.fsInfo, ts.storageDriver, ts.storageDir, ts.cgroupSubsystems, ts.inHostNamespace, ts.metadataEnvAllowList, ts.includedMetrics)\n\t\tif ts.hasErr {\n\t\t\tas.NotNil(err)\n\t\t\tif ts.errContains != \"\" {\n\t\t\t\tas.Contains(err.Error(), ts.errContains)\n\t\t\t}\n\t\t}\n\t\tif ts.checkReference != nil {\n\t\t\tcr, err := handler.ContainerReference()\n\t\t\tas.Nil(err)\n\t\t\tas.Equal(*ts.checkReference, cr)\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "container/crio/install/install.go",
    "content": "// Copyright 2019 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n//go:build linux\n\n// The install package registers crio.NewPlugin() as the \"crio\" container provider when imported\npackage install\n\nimport (\n\t\"k8s.io/klog/v2\"\n\n\t\"github.com/google/cadvisor/container\"\n\t\"github.com/google/cadvisor/container/crio\"\n)\n\nfunc init() {\n\terr := container.RegisterPlugin(\"crio\", crio.NewPlugin())\n\tif err != nil {\n\t\tklog.Fatalf(\"Failed to register crio plugin: %v\", err)\n\t}\n}\n"
  },
  {
    "path": "container/crio/plugin.go",
    "content": "// Copyright 2019 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n//go:build linux\n\npackage crio\n\nimport (\n\t\"k8s.io/klog/v2\"\n\n\t\"github.com/google/cadvisor/container\"\n\t\"github.com/google/cadvisor/fs\"\n\tinfo \"github.com/google/cadvisor/info/v1\"\n\t\"github.com/google/cadvisor/watcher\"\n)\n\n// NewPlugin returns an implementation of container.Plugin suitable for passing to container.RegisterPlugin()\nfunc NewPlugin() container.Plugin {\n\treturn &plugin{}\n}\n\ntype plugin struct{}\n\nfunc (p *plugin) InitializeFSContext(context *fs.Context) error {\n\tcrioClient, err := Client()\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tcrioInfo, err := crioClient.Info()\n\tif err != nil {\n\t\tklog.V(5).Infof(\"CRI-O not connected: %v\", err)\n\t} else {\n\t\tcontext.Crio = fs.CrioContext{Root: crioInfo.StorageRoot, ImageStore: crioInfo.StorageImage, Driver: crioInfo.StorageDriver}\n\t}\n\treturn nil\n}\n\nfunc (p *plugin) Register(factory info.MachineInfoFactory, fsInfo fs.FsInfo, includedMetrics container.MetricSet) (watcher.ContainerWatcher, error) {\n\terr := Register(factory, fsInfo, includedMetrics)\n\treturn nil, err\n}\n"
  },
  {
    "path": "container/docker/client.go",
    "content": "// Copyright 2015 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n//go:build linux\n\n// Handler for /validate content.\n// Validates cadvisor dependencies - kernel, os, docker setup.\n\npackage docker\n\nimport (\n\t\"net/http\"\n\t\"sync\"\n\n\t\"github.com/docker/go-connections/tlsconfig\"\n\tdclient \"github.com/moby/moby/client\"\n)\n\nvar (\n\tdockerClient     *dclient.Client\n\tdockerClientErr  error\n\tdockerClientOnce sync.Once\n)\n\n// Client creates a Docker API client based on the given Docker flags\nfunc Client() (*dclient.Client, error) {\n\tdockerClientOnce.Do(func() {\n\t\tvar client *http.Client\n\t\tif *ArgDockerTLS {\n\t\t\tclient = &http.Client{}\n\t\t\toptions := tlsconfig.Options{\n\t\t\t\tCAFile:             *ArgDockerCA,\n\t\t\t\tCertFile:           *ArgDockerCert,\n\t\t\t\tKeyFile:            *ArgDockerKey,\n\t\t\t\tInsecureSkipVerify: false,\n\t\t\t}\n\t\t\ttlsc, err := tlsconfig.Client(options)\n\t\t\tif err != nil {\n\t\t\t\tdockerClientErr = err\n\t\t\t\treturn\n\t\t\t}\n\t\t\tclient.Transport = &http.Transport{\n\t\t\t\tTLSClientConfig: tlsc,\n\t\t\t}\n\t\t}\n\t\tdockerClient, dockerClientErr = dclient.New(\n\t\t\tdclient.WithHost(*ArgDockerEndpoint),\n\t\t\tdclient.WithHTTPClient(client),\n\t\t)\n\t})\n\treturn dockerClient, dockerClientErr\n}\n"
  },
  {
    "path": "container/docker/docker.go",
    "content": "// Copyright 2016 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n//go:build linux\n\n// Provides global docker information.\npackage docker\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"regexp\"\n\t\"strconv\"\n\t\"time\"\n\n\tdockersystem \"github.com/moby/moby/api/types/system\"\n\tdclient \"github.com/moby/moby/client\"\n\n\t\"github.com/google/cadvisor/container/docker/utils\"\n\tv1 \"github.com/google/cadvisor/info/v1\"\n\t\"github.com/google/cadvisor/machine\"\n)\n\nvar dockerTimeout = 10 * time.Second\n\nfunc SetTimeout(timeout time.Duration) {\n\tdockerTimeout = timeout\n}\n\nfunc Status() (v1.DockerStatus, error) {\n\tctx, cancel := context.WithTimeout(context.Background(), dockerTimeout)\n\tdefer cancel()\n\treturn StatusWithContext(ctx)\n}\n\nfunc StatusWithContext(ctx context.Context) (v1.DockerStatus, error) {\n\tclient, err := Client()\n\tif err != nil {\n\t\treturn v1.DockerStatus{}, fmt.Errorf(\"unable to communicate with docker daemon: %v\", err)\n\t}\n\tres, err := client.Info(ctx, dclient.InfoOptions{})\n\tif err != nil {\n\t\treturn v1.DockerStatus{}, err\n\t}\n\treturn StatusFromDockerInfo(res.Info)\n}\n\nfunc StatusFromDockerInfo(dockerInfo dockersystem.Info) (v1.DockerStatus, error) {\n\tout := v1.DockerStatus{}\n\tout.KernelVersion = machine.KernelVersion()\n\tout.OS = dockerInfo.OperatingSystem\n\tout.Hostname = dockerInfo.Name\n\tout.RootDir = dockerInfo.DockerRootDir\n\tout.Driver = dockerInfo.Driver\n\tout.NumImages = dockerInfo.Images\n\tout.NumContainers = dockerInfo.Containers\n\tout.DriverStatus = make(map[string]string, len(dockerInfo.DriverStatus))\n\tfor _, v := range dockerInfo.DriverStatus {\n\t\tout.DriverStatus[v[0]] = v[1]\n\t}\n\tvar err error\n\tver, err := VersionString()\n\tif err != nil {\n\t\treturn out, err\n\t}\n\tout.Version = ver\n\tver, err = APIVersionString()\n\tif err != nil {\n\t\treturn out, err\n\t}\n\tout.APIVersion = ver\n\treturn out, nil\n}\n\nfunc Images() ([]v1.DockerImage, error) {\n\tclient, err := Client()\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"unable to communicate with docker daemon: %v\", err)\n\t}\n\tctx, cancel := context.WithTimeout(context.Background(), dockerTimeout)\n\tdefer cancel()\n\tsummaries, err := client.ImageList(ctx, dclient.ImageListOptions{All: false})\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn utils.SummariesToImages(summaries.Items)\n}\n\n// ValidateInfo checks whether the dockerInfo reflects a valid docker setup, and returns it if it does, or an\n// error otherwise.\nfunc ValidateInfo(GetInfo func() (*dockersystem.Info, error), ServerVersion func() (string, error)) (*dockersystem.Info, error) {\n\tinfo, err := GetInfo()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\t// Fall back to version API if ServerVersion is not set in info.\n\tif info.ServerVersion == \"\" {\n\t\tvar err error\n\t\tinfo.ServerVersion, err = ServerVersion()\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"unable to get runtime version: %v\", err)\n\t\t}\n\t}\n\n\tversion, err := ParseVersion(info.ServerVersion, VersionRe, 3)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tif version[0] < 1 {\n\t\treturn nil, fmt.Errorf(\"cAdvisor requires runtime version %v or above but we have found version %v reported as %q\", []int{1, 0, 0}, version, info.ServerVersion)\n\t}\n\n\tif info.Driver == \"\" {\n\t\treturn nil, fmt.Errorf(\"failed to find runtime storage driver\")\n\t}\n\n\treturn info, nil\n}\n\nfunc Info() (*dockersystem.Info, error) {\n\tclient, err := Client()\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"unable to communicate with docker daemon: %v\", err)\n\t}\n\n\tctx, cancel := context.WithTimeout(context.Background(), dockerTimeout)\n\tdefer cancel()\n\tres, err := client.Info(ctx, dclient.InfoOptions{})\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to detect Docker info: %v\", err)\n\t}\n\n\treturn &res.Info, nil\n}\n\nfunc APIVersion() ([]int, error) {\n\tver, err := APIVersionString()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn ParseVersion(ver, apiVersionRe, 2)\n}\n\nfunc VersionString() (string, error) {\n\tdockerVersion := \"Unknown\"\n\tclient, err := Client()\n\tif err == nil {\n\t\tctx, cancel := context.WithTimeout(context.Background(), dockerTimeout)\n\t\tdefer cancel()\n\t\tversion, err := client.ServerVersion(ctx, dclient.ServerVersionOptions{})\n\t\tif err == nil {\n\t\t\tdockerVersion = version.Version\n\t\t}\n\t}\n\treturn dockerVersion, err\n}\n\nfunc APIVersionString() (string, error) {\n\tapiVersion := \"Unknown\"\n\tclient, err := Client()\n\tif err == nil {\n\t\tctx, cancel := context.WithTimeout(context.Background(), dockerTimeout)\n\t\tdefer cancel()\n\t\tversion, err := client.Ping(ctx, dclient.PingOptions{NegotiateAPIVersion: true})\n\t\tif err == nil {\n\t\t\tapiVersion = version.APIVersion\n\t\t}\n\t}\n\treturn apiVersion, err\n}\n\nfunc ParseVersion(versionString string, regex *regexp.Regexp, length int) ([]int, error) {\n\tmatches := regex.FindAllStringSubmatch(versionString, -1)\n\tif len(matches) != 1 {\n\t\treturn nil, fmt.Errorf(\"version string \\\"%v\\\" doesn't match expected regular expression: \\\"%v\\\"\", versionString, regex.String())\n\t}\n\tversionStringArray := matches[0][1:]\n\tversionArray := make([]int, length)\n\tfor index, versionStr := range versionStringArray {\n\t\tversion, err := strconv.Atoi(versionStr)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"error while parsing \\\"%v\\\" in \\\"%v\\\"\", versionStr, versionString)\n\t\t}\n\t\tversionArray[index] = version\n\t}\n\treturn versionArray, nil\n}\n"
  },
  {
    "path": "container/docker/docker_test.go",
    "content": "// Copyright 2017 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n//go:build linux\n\npackage docker\n\nimport (\n\t\"reflect\"\n\t\"regexp\"\n\t\"testing\"\n)\n\nfunc TestParseDockerAPIVersion(t *testing.T) {\n\ttests := []struct {\n\t\tversion       string\n\t\tregex         *regexp.Regexp\n\t\tlength        int\n\t\texpected      []int\n\t\texpectedError string\n\t}{\n\t\t{\"17.03.0\", VersionRe, 3, []int{17, 03, 0}, \"\"},\n\t\t{\"17.a3.0\", VersionRe, 3, []int{}, `version string \"17.a3.0\" doesn't match expected regular expression: \"(\\d+)\\.(\\d+)\\.(\\d+)\"`},\n\t\t{\"1.20\", apiVersionRe, 2, []int{1, 20}, \"\"},\n\t\t{\"1.a\", apiVersionRe, 2, []int{}, `version string \"1.a\" doesn't match expected regular expression: \"(\\d+)\\.(\\d+)\"`},\n\t}\n\n\tfor _, test := range tests {\n\t\tactual, err := ParseVersion(test.version, test.regex, test.length)\n\t\tif err != nil {\n\t\t\tif len(test.expectedError) == 0 {\n\t\t\t\tt.Errorf(\"%s: expected no error, got %v\", test.version, err)\n\t\t\t} else if err.Error() != test.expectedError {\n\t\t\t\tt.Errorf(\"%s: expected error %v, got %v\", test.version, test.expectedError, err)\n\t\t\t}\n\t\t} else {\n\t\t\tif !reflect.DeepEqual(actual, test.expected) {\n\t\t\t\tt.Errorf(\"%s: expected array %v, got %v\", test.version, test.expected, actual)\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "container/docker/factory.go",
    "content": "// Copyright 2014 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n//go:build linux\n\npackage docker\n\nimport (\n\t\"context\"\n\t\"flag\"\n\t\"fmt\"\n\t\"regexp\"\n\t\"strconv\"\n\t\"strings\"\n\t\"sync\"\n\t\"time\"\n\n\t\"github.com/blang/semver/v4\"\n\tdockersystem \"github.com/moby/moby/api/types/system\"\n\tdclient \"github.com/moby/moby/client\"\n\t\"k8s.io/klog/v2\"\n\n\t\"github.com/google/cadvisor/container\"\n\t\"github.com/google/cadvisor/container/containerd\"\n\tdockerutil \"github.com/google/cadvisor/container/docker/utils\"\n\t\"github.com/google/cadvisor/container/libcontainer\"\n\t\"github.com/google/cadvisor/devicemapper\"\n\t\"github.com/google/cadvisor/fs\"\n\tinfo \"github.com/google/cadvisor/info/v1\"\n\t\"github.com/google/cadvisor/machine\"\n\t\"github.com/google/cadvisor/watcher\"\n\t\"github.com/google/cadvisor/zfs\"\n)\n\nvar ArgDockerEndpoint = flag.String(\"docker\", \"unix:///var/run/docker.sock\", \"docker endpoint\")\nvar ArgDockerTLS = flag.Bool(\"docker-tls\", false, \"use TLS to connect to docker\")\nvar ArgDockerCert = flag.String(\"docker-tls-cert\", \"cert.pem\", \"path to client certificate\")\nvar ArgDockerKey = flag.String(\"docker-tls-key\", \"key.pem\", \"path to private key\")\nvar ArgDockerCA = flag.String(\"docker-tls-ca\", \"ca.pem\", \"path to trusted CA\")\n\nvar dockerEnvMetadataWhiteList = flag.String(\"docker_env_metadata_whitelist\", \"\", \"DEPRECATED: this flag will be removed, please use `env_metadata_whitelist`. A comma-separated list of environment variable keys matched with specified prefix that needs to be collected for docker containers\")\n\n// The namespace under which Docker aliases are unique.\nconst DockerNamespace = \"docker\"\n\n// The retry times for getting docker root dir\nconst rootDirRetries = 5\n\n// The retry period for getting docker root dir, Millisecond\nconst rootDirRetryPeriod time.Duration = 1000 * time.Millisecond\n\nvar (\n\t// Basepath to all container specific information that libcontainer stores.\n\tdockerRootDir string\n\n\tdockerRootDirFlag = flag.String(\"docker_root\", \"/var/lib/docker\", \"DEPRECATED: docker root is read from docker info (this is a fallback, default: /var/lib/docker)\")\n\n\tdockerRootDirOnce sync.Once\n\n\t// flag that controls globally disabling thin_ls pending future enhancements.\n\t// in production, it has been found that thin_ls makes excessive use of iops.\n\t// in an iops restricted environment, usage of thin_ls must be controlled via blkio.\n\t// pending that enhancement, disable its usage.\n\tdisableThinLs = true\n)\n\nfunc RootDir() string {\n\tdockerRootDirOnce.Do(func() {\n\t\tfor i := 0; i < rootDirRetries; i++ {\n\t\t\tstatus, err := Status()\n\t\t\tif err == nil && status.RootDir != \"\" {\n\t\t\t\tdockerRootDir = status.RootDir\n\t\t\t\tbreak\n\t\t\t} else {\n\t\t\t\ttime.Sleep(rootDirRetryPeriod)\n\t\t\t}\n\t\t}\n\t\tif dockerRootDir == \"\" {\n\t\t\tdockerRootDir = *dockerRootDirFlag\n\t\t}\n\t})\n\treturn dockerRootDir\n}\n\ntype StorageDriver string\n\nconst (\n\tDevicemapperStorageDriver          StorageDriver = \"devicemapper\"\n\tAufsStorageDriver                  StorageDriver = \"aufs\"\n\tOverlayStorageDriver               StorageDriver = \"overlay\"\n\tOverlay2StorageDriver              StorageDriver = \"overlay2\"\n\tContainerdSnapshotterStorageDriver StorageDriver = \"overlayfs\"\n\tZfsStorageDriver                   StorageDriver = \"zfs\"\n\tVfsStorageDriver                   StorageDriver = \"vfs\"\n)\n\ntype dockerFactory struct {\n\tmachineInfoFactory info.MachineInfoFactory\n\n\tstorageDriver StorageDriver\n\tstorageDir    string\n\n\tclient           *dclient.Client\n\tcontainerdClient containerd.ContainerdClient\n\n\t// Information about the mounted cgroup subsystems.\n\tcgroupSubsystems map[string]string\n\n\t// Information about mounted filesystems.\n\tfsInfo fs.FsInfo\n\n\tdockerVersion []int\n\n\tdockerAPIVersion []int\n\n\tincludedMetrics container.MetricSet\n\n\tthinPoolName    string\n\tthinPoolWatcher *devicemapper.ThinPoolWatcher\n\n\tzfsWatcher *zfs.ZfsWatcher\n}\n\nfunc (f *dockerFactory) String() string {\n\treturn DockerNamespace\n}\n\nfunc (f *dockerFactory) NewContainerHandler(name string, metadataEnvAllowList []string, inHostNamespace bool) (handler container.ContainerHandler, err error) {\n\tclient, err := Client()\n\tif err != nil {\n\t\treturn\n\t}\n\n\tdockerMetadataEnvAllowList := strings.Split(*dockerEnvMetadataWhiteList, \",\")\n\n\t// prefer using the unified metadataEnvAllowList\n\tif len(metadataEnvAllowList) != 0 {\n\t\tdockerMetadataEnvAllowList = metadataEnvAllowList\n\t}\n\n\thandler, err = newContainerHandler(\n\t\tclient,\n\t\tf.containerdClient,\n\t\tname,\n\t\tf.machineInfoFactory,\n\t\tf.fsInfo,\n\t\tf.storageDriver,\n\t\tf.storageDir,\n\t\tf.cgroupSubsystems,\n\t\tinHostNamespace,\n\t\tdockerMetadataEnvAllowList,\n\t\tf.dockerVersion,\n\t\tf.includedMetrics,\n\t\tf.thinPoolName,\n\t\tf.thinPoolWatcher,\n\t\tf.zfsWatcher,\n\t)\n\treturn\n}\n\n// Docker handles all containers under /docker\nfunc (f *dockerFactory) CanHandleAndAccept(name string) (bool, bool, error) {\n\t// if the container is not associated with docker, we can't handle it or accept it.\n\tif !dockerutil.IsContainerName(name) {\n\t\treturn false, false, nil\n\t}\n\n\t// Check if the container is known to docker and it is active.\n\tid := dockerutil.ContainerNameToId(name)\n\n\t// We assume that if Inspect fails then the container is not known to docker.\n\tres, err := f.client.ContainerInspect(context.Background(), id, dclient.ContainerInspectOptions{})\n\tif err != nil || !res.Container.State.Running {\n\t\treturn false, true, fmt.Errorf(\"error inspecting container: %v\", err)\n\t}\n\n\treturn true, true, nil\n}\n\nfunc (f *dockerFactory) DebugInfo() map[string][]string {\n\treturn map[string][]string{}\n}\n\nvar (\n\tversionRegexpString    = `(\\d+)\\.(\\d+)\\.(\\d+)`\n\tVersionRe              = regexp.MustCompile(versionRegexpString)\n\tapiVersionRegexpString = `(\\d+)\\.(\\d+)`\n\tapiVersionRe           = regexp.MustCompile(apiVersionRegexpString)\n)\n\nfunc StartThinPoolWatcher(dockerInfo *dockersystem.Info) (*devicemapper.ThinPoolWatcher, error) {\n\t_, err := devicemapper.ThinLsBinaryPresent()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tif err := ensureThinLsKernelVersion(machine.KernelVersion()); err != nil {\n\t\treturn nil, err\n\t}\n\n\tif disableThinLs {\n\t\treturn nil, fmt.Errorf(\"usage of thin_ls is disabled to preserve iops\")\n\t}\n\n\tdockerThinPoolName, err := dockerutil.DockerThinPoolName(*dockerInfo)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tdockerMetadataDevice, err := dockerutil.DockerMetadataDevice(*dockerInfo)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tthinPoolWatcher, err := devicemapper.NewThinPoolWatcher(dockerThinPoolName, dockerMetadataDevice)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tgo thinPoolWatcher.Start()\n\treturn thinPoolWatcher, nil\n}\n\nfunc StartZfsWatcher(dockerInfo *dockersystem.Info) (*zfs.ZfsWatcher, error) {\n\tfilesystem, err := dockerutil.DockerZfsFilesystem(*dockerInfo)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tzfsWatcher, err := zfs.NewZfsWatcher(filesystem)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tgo zfsWatcher.Start()\n\treturn zfsWatcher, nil\n}\n\nfunc ensureThinLsKernelVersion(kernelVersion string) error {\n\t// kernel 4.4.0 has the proper bug fixes to allow thin_ls to work without corrupting the thin pool\n\tminKernelVersion := semver.MustParse(\"4.4.0\")\n\t// RHEL 7 kernel 3.10.0 release >= 366 has the proper bug fixes backported from 4.4.0 to allow\n\t// thin_ls to work without corrupting the thin pool\n\tminRhel7KernelVersion := semver.MustParse(\"3.10.0\")\n\n\tmatches := VersionRe.FindStringSubmatch(kernelVersion)\n\tif len(matches) < 4 {\n\t\treturn fmt.Errorf(\"error parsing kernel version: %q is not a semver\", kernelVersion)\n\t}\n\n\tsem, err := semver.Make(matches[0])\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tif sem.GTE(minKernelVersion) {\n\t\t// kernel 4.4+ - good\n\t\treturn nil\n\t}\n\n\t// Certain RHEL/Centos 7.x kernels have a backport to fix the corruption bug\n\tif !strings.Contains(kernelVersion, \".el7\") {\n\t\t// not a RHEL 7.x kernel - won't work\n\t\treturn fmt.Errorf(\"kernel version 4.4.0 or later is required to use thin_ls - you have %q\", kernelVersion)\n\t}\n\n\t// RHEL/Centos 7.x from here on\n\tif sem.Major != 3 {\n\t\t// only 3.x kernels *may* work correctly\n\t\treturn fmt.Errorf(\"RHEL/Centos 7.x kernel version 3.10.0-366 or later is required to use thin_ls - you have %q\", kernelVersion)\n\t}\n\n\tif sem.GT(minRhel7KernelVersion) {\n\t\t// 3.10.1+ - good\n\t\treturn nil\n\t}\n\n\tif sem.EQ(minRhel7KernelVersion) {\n\t\t// need to check release\n\t\treleaseRE := regexp.MustCompile(`^[^-]+-([0-9]+)\\.`)\n\t\treleaseMatches := releaseRE.FindStringSubmatch(kernelVersion)\n\t\tif len(releaseMatches) != 2 {\n\t\t\treturn fmt.Errorf(\"unable to determine RHEL/Centos 7.x kernel release from %q\", kernelVersion)\n\t\t}\n\n\t\trelease, err := strconv.Atoi(releaseMatches[1])\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"error parsing release %q: %v\", releaseMatches[1], err)\n\t\t}\n\n\t\tif release >= 366 {\n\t\t\treturn nil\n\t\t}\n\t}\n\n\treturn fmt.Errorf(\"RHEL/Centos 7.x kernel version 3.10.0-366 or later is required to use thin_ls - you have %q\", kernelVersion)\n}\n\n// Register root container before running this function!\nfunc Register(factory info.MachineInfoFactory, fsInfo fs.FsInfo, includedMetrics container.MetricSet) error {\n\tclient, err := Client()\n\tif err != nil {\n\t\treturn fmt.Errorf(\"unable to communicate with docker daemon: %v\", err)\n\t}\n\n\tdockerInfo, err := ValidateInfo(Info, VersionString)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to validate Docker info: %v\", err)\n\t}\n\n\t// Version already validated above, assume no error here.\n\tdockerVersion, _ := ParseVersion(dockerInfo.ServerVersion, VersionRe, 3)\n\n\tdockerAPIVersion, _ := APIVersion()\n\n\tcgroupSubsystems, err := libcontainer.GetCgroupSubsystems(includedMetrics)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to get cgroup subsystems: %v\", err)\n\t}\n\n\tvar (\n\t\tthinPoolWatcher  *devicemapper.ThinPoolWatcher\n\t\tthinPoolName     string\n\t\tzfsWatcher       *zfs.ZfsWatcher\n\t\tcontainerdClient containerd.ContainerdClient\n\t)\n\tif includedMetrics.Has(container.DiskUsageMetrics) {\n\t\tif StorageDriver(dockerInfo.Driver) == DevicemapperStorageDriver {\n\t\t\tthinPoolWatcher, err = StartThinPoolWatcher(dockerInfo)\n\t\t\tif err != nil {\n\t\t\t\tklog.Errorf(\"devicemapper filesystem stats will not be reported: %v\", err)\n\t\t\t}\n\n\t\t\t// Safe to ignore error - driver status should always be populated.\n\t\t\tstatus, _ := StatusFromDockerInfo(*dockerInfo)\n\t\t\tthinPoolName = status.DriverStatus[dockerutil.DriverStatusPoolName]\n\t\t}\n\n\t\tif StorageDriver(dockerInfo.Driver) == ZfsStorageDriver {\n\t\t\tzfsWatcher, err = StartZfsWatcher(dockerInfo)\n\t\t\tif err != nil {\n\t\t\t\tklog.Errorf(\"zfs filesystem stats will not be reported: %v\", err)\n\t\t\t}\n\t\t}\n\t}\n\n\tif StorageDriver(dockerInfo.Driver) == ContainerdSnapshotterStorageDriver {\n\t\tcontainerdClient, err = containerd.Client(*containerd.ArgContainerdEndpoint, \"moby\")\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"unable to create containerd client: %v\", err)\n\t\t}\n\t}\n\n\tklog.V(1).Infof(\"Registering Docker factory\")\n\tf := &dockerFactory{\n\t\tcgroupSubsystems:   cgroupSubsystems,\n\t\tclient:             client,\n\t\tcontainerdClient:   containerdClient,\n\t\tdockerVersion:      dockerVersion,\n\t\tdockerAPIVersion:   dockerAPIVersion,\n\t\tfsInfo:             fsInfo,\n\t\tmachineInfoFactory: factory,\n\t\tstorageDriver:      StorageDriver(dockerInfo.Driver),\n\t\tstorageDir:         RootDir(),\n\t\tincludedMetrics:    includedMetrics,\n\t\tthinPoolName:       thinPoolName,\n\t\tthinPoolWatcher:    thinPoolWatcher,\n\t\tzfsWatcher:         zfsWatcher,\n\t}\n\n\tcontainer.RegisterContainerHandlerFactory(f, []watcher.ContainerWatchSource{watcher.Raw})\n\treturn nil\n}\n"
  },
  {
    "path": "container/docker/factory_test.go",
    "content": "// Copyright 2016 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n//go:build linux\n\npackage docker\n\nimport \"testing\"\n\nfunc TestEnsureThinLsKernelVersion(t *testing.T) {\n\ttests := []struct {\n\t\tversion       string\n\t\texpectedError string\n\t}{\n\t\t{\"4.4.0-31-generic\", \"\"},\n\t\t{\"4.4.1\", \"\"},\n\t\t{\"4.6.4-301.fc24.x86_64\", \"\"},\n\t\t{\"3.10.0-327.22.2.el7.x86_64\", `RHEL/Centos 7.x kernel version 3.10.0-366 or later is required to use thin_ls - you have \"3.10.0-327.22.2.el7.x86_64\"`},\n\t\t{\"3.10.0-366.el7.x86_64\", \"\"},\n\t\t{\"3.10.0-366.el7_3.x86_64\", \"\"},\n\t\t{\"3.10.0.el7.abc\", `unable to determine RHEL/Centos 7.x kernel release from \"3.10.0.el7.abc\"`},\n\t\t{\"3.10.0-abc.el7.blarg\", `unable to determine RHEL/Centos 7.x kernel release from \"3.10.0-abc.el7.blarg\"`},\n\t\t{\"3.10.0-367.el7.x86_64\", \"\"},\n\t\t{\"3.10.0-366.x86_64\", `kernel version 4.4.0 or later is required to use thin_ls - you have \"3.10.0-366.x86_64\"`},\n\t\t{\"3.10.1-1.el7.x86_64\", \"\"},\n\t\t{\"2.0.36\", `kernel version 4.4.0 or later is required to use thin_ls - you have \"2.0.36\"`},\n\t\t{\"2.1\", `error parsing kernel version: \"2.1\" is not a semver`},\n\t}\n\n\tfor _, test := range tests {\n\t\terr := ensureThinLsKernelVersion(test.version)\n\t\tif err != nil {\n\t\t\tif len(test.expectedError) == 0 {\n\t\t\t\tt.Errorf(\"%s: expected no error, got %v\", test.version, err)\n\t\t\t} else if err.Error() != test.expectedError {\n\t\t\t\tt.Errorf(\"%s: expected error %v, got %v\", test.version, test.expectedError, err)\n\t\t\t}\n\t\t} else if err == nil && len(test.expectedError) > 0 {\n\t\t\tt.Errorf(\"%s: expected error %v\", test.version, test.expectedError)\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "container/docker/fs.go",
    "content": "// Copyright 2022 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n//go:build linux\n\npackage docker\n\nimport (\n\t\"fmt\"\n\n\t\"k8s.io/klog/v2\"\n\n\t\"github.com/google/cadvisor/container\"\n\t\"github.com/google/cadvisor/container/common\"\n\t\"github.com/google/cadvisor/devicemapper\"\n\t\"github.com/google/cadvisor/fs\"\n\tinfo \"github.com/google/cadvisor/info/v1\"\n\t\"github.com/google/cadvisor/zfs\"\n)\n\nfunc FsStats(\n\tstats *info.ContainerStats,\n\tmachineInfoFactory info.MachineInfoFactory,\n\tmetrics container.MetricSet,\n\tstorageDriver StorageDriver,\n\tfsHandler common.FsHandler,\n\tglobalFsInfo fs.FsInfo,\n\tpoolName string,\n\trootfsStorageDir string,\n\tzfsParent string,\n) error {\n\tmi, err := machineInfoFactory.GetMachineInfo()\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tif metrics.Has(container.DiskIOMetrics) {\n\t\tcommon.AssignDeviceNamesToDiskStats((*common.MachineInfoNamer)(mi), &stats.DiskIo)\n\t}\n\n\tif metrics.Has(container.DiskUsageMetrics) {\n\t\tvar device string\n\t\tswitch storageDriver {\n\t\tcase DevicemapperStorageDriver:\n\t\t\tdevice = poolName\n\t\tcase AufsStorageDriver, OverlayStorageDriver, Overlay2StorageDriver, VfsStorageDriver:\n\t\t\tdeviceInfo, err := globalFsInfo.GetDirFsDevice(rootfsStorageDir)\n\t\t\tif err != nil {\n\t\t\t\treturn fmt.Errorf(\"unable to determine device info for dir: %v: %v\", rootfsStorageDir, err)\n\t\t\t}\n\t\t\tdevice = deviceInfo.Device\n\t\tcase ZfsStorageDriver:\n\t\t\tdevice = zfsParent\n\t\tdefault:\n\t\t\treturn nil\n\t\t}\n\n\t\tfor _, fs := range mi.Filesystems {\n\t\t\tif fs.Device == device {\n\t\t\t\tusage := fsHandler.Usage()\n\t\t\t\tfsStat := info.FsStats{\n\t\t\t\t\tDevice:    device,\n\t\t\t\t\tType:      fs.Type,\n\t\t\t\t\tLimit:     fs.Capacity,\n\t\t\t\t\tBaseUsage: usage.BaseUsageBytes,\n\t\t\t\t\tUsage:     usage.TotalUsageBytes,\n\t\t\t\t\tInodes:    usage.InodeUsage,\n\t\t\t\t}\n\t\t\t\tfileSystems, err := globalFsInfo.GetGlobalFsInfo()\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn fmt.Errorf(\"unable to obtain diskstats for filesystem %s: %v\", fsStat.Device, err)\n\t\t\t\t}\n\t\t\t\taddDiskStats(fileSystems, &fs, &fsStat)\n\t\t\t\tstats.Filesystem = append(stats.Filesystem, fsStat)\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t}\n\n\treturn nil\n}\n\nfunc addDiskStats(fileSystems []fs.Fs, fsInfo *info.FsInfo, fsStats *info.FsStats) {\n\tif fsInfo == nil {\n\t\treturn\n\t}\n\n\tfor _, fileSys := range fileSystems {\n\t\tif fsInfo.DeviceMajor == fileSys.DiskStats.Major &&\n\t\t\tfsInfo.DeviceMinor == fileSys.DiskStats.Minor {\n\t\t\tfsStats.ReadsCompleted = fileSys.DiskStats.ReadsCompleted\n\t\t\tfsStats.ReadsMerged = fileSys.DiskStats.ReadsMerged\n\t\t\tfsStats.SectorsRead = fileSys.DiskStats.SectorsRead\n\t\t\tfsStats.ReadTime = fileSys.DiskStats.ReadTime\n\t\t\tfsStats.WritesCompleted = fileSys.DiskStats.WritesCompleted\n\t\t\tfsStats.WritesMerged = fileSys.DiskStats.WritesMerged\n\t\t\tfsStats.SectorsWritten = fileSys.DiskStats.SectorsWritten\n\t\t\tfsStats.WriteTime = fileSys.DiskStats.WriteTime\n\t\t\tfsStats.IoInProgress = fileSys.DiskStats.IoInProgress\n\t\t\tfsStats.IoTime = fileSys.DiskStats.IoTime\n\t\t\tfsStats.WeightedIoTime = fileSys.DiskStats.WeightedIoTime\n\t\t\tbreak\n\t\t}\n\t}\n}\n\n// FsHandler is a composite FsHandler implementation the incorporates\n// the common fs handler, a devicemapper ThinPoolWatcher, and a zfsWatcher\ntype FsHandler struct {\n\tFsHandler common.FsHandler\n\n\t// thinPoolWatcher is the devicemapper thin pool watcher\n\tThinPoolWatcher *devicemapper.ThinPoolWatcher\n\t// deviceID is the id of the container's fs device\n\tDeviceID string\n\n\t// zfsWatcher is the zfs filesystem watcher\n\tZfsWatcher *zfs.ZfsWatcher\n\t// zfsFilesystem is the docker zfs filesystem\n\tZfsFilesystem string\n}\n\nvar _ common.FsHandler = &FsHandler{}\n\nfunc (h *FsHandler) Start() {\n\th.FsHandler.Start()\n}\n\nfunc (h *FsHandler) Stop() {\n\th.FsHandler.Stop()\n}\n\nfunc (h *FsHandler) Usage() common.FsUsage {\n\tusage := h.FsHandler.Usage()\n\n\t// When devicemapper is the storage driver, the base usage of the container comes from the thin pool.\n\t// We still need the result of the fsHandler for any extra storage associated with the container.\n\t// To correctly factor in the thin pool usage, we should:\n\t// * Usage the thin pool usage as the base usage\n\t// * Calculate the overall usage by adding the overall usage from the fs handler to the thin pool usage\n\tif h.ThinPoolWatcher != nil {\n\t\tthinPoolUsage, err := h.ThinPoolWatcher.GetUsage(h.DeviceID)\n\t\tif err != nil {\n\t\t\t// TODO: ideally we should keep track of how many times we failed to get the usage for this\n\t\t\t// device vs how many refreshes of the cache there have been, and display an error e.g. if we've\n\t\t\t// had at least 1 refresh and we still can't find the device.\n\t\t\tklog.V(5).Infof(\"unable to get fs usage from thin pool for device %s: %v\", h.DeviceID, err)\n\t\t} else {\n\t\t\tusage.BaseUsageBytes = thinPoolUsage\n\t\t\tusage.TotalUsageBytes += thinPoolUsage\n\t\t}\n\t}\n\n\tif h.ZfsWatcher != nil {\n\t\tzfsUsage, err := h.ZfsWatcher.GetUsage(h.ZfsFilesystem)\n\t\tif err != nil {\n\t\t\tklog.V(5).Infof(\"unable to get fs usage from zfs for filesystem %s: %v\", h.ZfsFilesystem, err)\n\t\t} else {\n\t\t\tusage.BaseUsageBytes = zfsUsage\n\t\t\tusage.TotalUsageBytes += zfsUsage\n\t\t}\n\t}\n\treturn usage\n}\n"
  },
  {
    "path": "container/docker/handler.go",
    "content": "// Copyright 2014 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n//go:build linux\n\n// Package docker implements a handler for Docker containers.\npackage docker\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"os\"\n\t\"path\"\n\t\"strconv\"\n\t\"strings\"\n\t\"time\"\n\n\tdclient \"github.com/moby/moby/client\"\n\t\"github.com/opencontainers/cgroups\"\n\t\"github.com/opencontainers/runtime-spec/specs-go\"\n\n\t\"github.com/google/cadvisor/container\"\n\t\"github.com/google/cadvisor/container/common\"\n\t\"github.com/google/cadvisor/container/containerd\"\n\t\"github.com/google/cadvisor/container/containerd/namespaces\"\n\tdockerutil \"github.com/google/cadvisor/container/docker/utils\"\n\tcontainerlibcontainer \"github.com/google/cadvisor/container/libcontainer\"\n\t\"github.com/google/cadvisor/devicemapper\"\n\t\"github.com/google/cadvisor/fs\"\n\tinfo \"github.com/google/cadvisor/info/v1\"\n\t\"github.com/google/cadvisor/zfs\"\n\n\t\"k8s.io/klog/v2\"\n)\n\nconst (\n\t// The read write layers exist here.\n\taufsRWLayer     = \"diff\"\n\toverlayRWLayer  = \"upper\"\n\toverlay2RWLayer = \"diff\"\n\n\t// Path to the directory where docker stores log files if the json logging driver is enabled.\n\tpathToContainersDir = \"containers\"\n)\n\ntype containerHandler struct {\n\t// machineInfoFactory provides info.MachineInfo\n\tmachineInfoFactory info.MachineInfoFactory\n\n\t// Absolute path to the cgroup hierarchies of this container.\n\t// (e.g.: \"cpu\" -> \"/sys/fs/cgroup/cpu/test\")\n\tcgroupPaths map[string]string\n\n\t// the docker storage driver\n\tstorageDriver    StorageDriver\n\tfsInfo           fs.FsInfo\n\trootfsStorageDir string\n\n\t// Time at which this container was created.\n\tcreationTime time.Time\n\n\t// Time at which this container was started.\n\tstartTime time.Time\n\n\t// Metadata associated with the container.\n\tenvs   map[string]string\n\tlabels map[string]string\n\n\t// Image name used for this container.\n\timage string\n\n\t// Filesystem handler.\n\tfsHandler common.FsHandler\n\n\t// The IP address of the container\n\tipAddress string\n\n\tmetrics container.MetricSet\n\n\t// the devicemapper poolname\n\tthinPoolName string\n\n\t// zfsParent is the parent for docker zfs\n\tzfsParent string\n\n\t// Reference to the container\n\treference info.ContainerReference\n\n\tlibcontainerHandler *containerlibcontainer.Handler\n\n\t// the docker client is needed to inspect the container and get the health status\n\tclient dclient.APIClient\n}\n\nvar _ container.ContainerHandler = &containerHandler{}\n\nfunc getRwLayerID(containerID, storageDir string, sd StorageDriver, dockerVersion []int) (string, error) {\n\tconst (\n\t\t// Docker version >=1.10.0 have a randomized ID for the root fs of a container.\n\t\trandomizedRWLayerMinorVersion = 10\n\t\trwLayerIDFile                 = \"mount-id\"\n\t)\n\tif (dockerVersion[0] <= 1) && (dockerVersion[1] < randomizedRWLayerMinorVersion) {\n\t\treturn containerID, nil\n\t}\n\n\tbytes, err := os.ReadFile(path.Join(storageDir, \"image\", string(sd), \"layerdb\", \"mounts\", containerID, rwLayerIDFile))\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"failed to identify the read-write layer ID for container %q. - %v\", containerID, err)\n\t}\n\treturn string(bytes), err\n}\n\n// newContainerHandler returns a new container.ContainerHandler\nfunc newContainerHandler(\n\tclient *dclient.Client,\n\tcontainerdClient containerd.ContainerdClient,\n\tname string,\n\tmachineInfoFactory info.MachineInfoFactory,\n\tfsInfo fs.FsInfo,\n\tstorageDriver StorageDriver,\n\tstorageDir string,\n\tcgroupSubsystems map[string]string,\n\tinHostNamespace bool,\n\tmetadataEnvAllowList []string,\n\tdockerVersion []int,\n\tmetrics container.MetricSet,\n\tthinPoolName string,\n\tthinPoolWatcher *devicemapper.ThinPoolWatcher,\n\tzfsWatcher *zfs.ZfsWatcher,\n) (container.ContainerHandler, error) {\n\t// Create the cgroup paths.\n\tcgroupPaths := common.MakeCgroupPaths(cgroupSubsystems, name)\n\n\t// Generate the equivalent cgroup manager for this container.\n\tcgroupManager, err := containerlibcontainer.NewCgroupManager(name, cgroupPaths)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\trootFs := \"/\"\n\tif !inHostNamespace {\n\t\trootFs = \"/rootfs\"\n\t\tstorageDir = path.Join(rootFs, storageDir)\n\t}\n\n\tid := dockerutil.ContainerNameToId(name)\n\n\t// Add the Containers dir where the log files are stored.\n\t// FIXME: Give `otherStorageDir` a more descriptive name.\n\totherStorageDir := path.Join(storageDir, pathToContainersDir, id)\n\n\tvar rootfsStorageDir, zfsFilesystem, zfsParent string\n\tif storageDriver == ContainerdSnapshotterStorageDriver {\n\t\tctx := namespaces.WithNamespace(context.Background(), \"moby\")\n\t\tcntr, err := containerdClient.LoadContainer(ctx, id)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\tvar spec specs.Spec\n\t\tif err := json.Unmarshal(cntr.Spec.Value, &spec); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\trootfsStorageDir = spec.Root.Path\n\t} else {\n\t\trwLayerID, err := getRwLayerID(id, storageDir, storageDriver, dockerVersion)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\t// Determine the rootfs storage dir OR the pool name to determine the device.\n\t\t// For devicemapper, we only need the thin pool name, and that is passed in to this call\n\t\trootfsStorageDir, zfsFilesystem, zfsParent, err = DetermineDeviceStorage(storageDriver, storageDir, rwLayerID)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"unable to determine device storage: %v\", err)\n\t\t}\n\t}\n\n\t// We assume that if Inspect fails then the container is not known to docker.\n\tres, err := client.ContainerInspect(context.Background(), id, dclient.ContainerInspectOptions{})\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to inspect container %q: %v\", id, err)\n\t}\n\tctnr := res.Container\n\n\t// Obtain the IP address for the container.\n\tvar ipAddress string\n\tif ctnr.NetworkSettings != nil && ctnr.HostConfig != nil {\n\t\tc := ctnr\n\t\tif ctnr.HostConfig.NetworkMode.IsContainer() {\n\t\t\t// If the NetworkMode starts with 'container:' then we need to use the IP address of the container specified.\n\t\t\t// This happens in cases such as kubernetes where the containers doesn't have an IP address itself and we need to use the pod's address\n\t\t\tcontainerID := ctnr.HostConfig.NetworkMode.ConnectedContainer()\n\t\t\tres, err := client.ContainerInspect(context.Background(), containerID, dclient.ContainerInspectOptions{})\n\t\t\tif err != nil {\n\t\t\t\treturn nil, fmt.Errorf(\"failed to inspect container %q: %v\", containerID, err)\n\t\t\t}\n\t\t\tc = res.Container\n\t\t}\n\t\tif nw, ok := c.NetworkSettings.Networks[c.HostConfig.NetworkMode.NetworkName()]; ok {\n\t\t\tif nw.IPAddress.IsValid() {\n\t\t\t\tipAddress = nw.IPAddress.String()\n\t\t\t}\n\t\t}\n\t}\n\n\t// Do not report network metrics for containers that share netns with another container.\n\tincludedMetrics := common.RemoveNetMetrics(metrics, ctnr.HostConfig.NetworkMode.IsContainer())\n\n\thandler := &containerHandler{\n\t\tmachineInfoFactory: machineInfoFactory,\n\t\tcgroupPaths:        cgroupPaths,\n\t\tstorageDriver:      storageDriver,\n\t\tfsInfo:             fsInfo,\n\t\trootfsStorageDir:   rootfsStorageDir,\n\t\tipAddress:          ipAddress,\n\t\tenvs:               make(map[string]string),\n\t\tlabels:             ctnr.Config.Labels,\n\t\timage:              ctnr.Config.Image,\n\t\tmetrics:            includedMetrics,\n\t\tthinPoolName:       thinPoolName,\n\t\tzfsParent:          zfsParent,\n\t\tclient:             client,\n\t\treference: info.ContainerReference{\n\t\t\t// Add the name and bare ID as aliases of the container.\n\t\t\tId:        id,\n\t\t\tName:      name,\n\t\t\tAliases:   []string{strings.TrimPrefix(ctnr.Name, \"/\"), id},\n\t\t\tNamespace: DockerNamespace,\n\t\t},\n\t\tlibcontainerHandler: containerlibcontainer.NewHandler(cgroupManager, rootFs, ctnr.State.Pid, metrics),\n\t}\n\n\t// Timestamp returned by Docker is in time.RFC3339Nano format.\n\thandler.creationTime, err = time.Parse(time.RFC3339Nano, ctnr.Created)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to parse the create timestamp %q for container %q: %v\", ctnr.Created, id, err)\n\t}\n\n\t// StartedAt may be unset for containers that never started.\n\tif startedAt := ctnr.State.StartedAt; startedAt != \"\" {\n\t\tif t, err := time.Parse(time.RFC3339Nano, startedAt); err == nil && !t.Before(time.Unix(0, 0)) {\n\t\t\thandler.startTime = t\n\t\t}\n\t}\n\n\tif ctnr.RestartCount > 0 {\n\t\thandler.labels[\"restartcount\"] = strconv.Itoa(ctnr.RestartCount)\n\t}\n\n\tif includedMetrics.Has(container.DiskUsageMetrics) {\n\t\tvar deviceID string\n\t\tif ctnr.GraphDriver != nil {\n\t\t\tdeviceID = ctnr.GraphDriver.Data[\"DeviceId\"]\n\t\t} else {\n\t\t\tklog.V(4).Infof(\"GraphDriver not found for container %q\", id)\n\t\t}\n\t\thandler.fsHandler = &FsHandler{\n\t\t\tFsHandler:       common.NewFsHandler(common.DefaultPeriod, rootfsStorageDir, otherStorageDir, fsInfo),\n\t\t\tThinPoolWatcher: thinPoolWatcher,\n\t\t\tZfsWatcher:      zfsWatcher,\n\t\t\tDeviceID:        deviceID,\n\t\t\tZfsFilesystem:   zfsFilesystem,\n\t\t}\n\t}\n\n\t// Split env vars to get metadata map.\n\tfor _, exposedEnv := range metadataEnvAllowList {\n\t\tif exposedEnv == \"\" {\n\t\t\t// if no dockerEnvWhitelist provided, len(metadataEnvAllowList) == 1, metadataEnvAllowList[0] == \"\"\n\t\t\tcontinue\n\t\t}\n\n\t\tfor _, envVar := range ctnr.Config.Env {\n\t\t\tif envVar != \"\" {\n\t\t\t\tsplits := strings.SplitN(envVar, \"=\", 2)\n\t\t\t\tif len(splits) == 2 && strings.HasPrefix(splits[0], exposedEnv) {\n\t\t\t\t\thandler.envs[strings.ToLower(splits[0])] = splits[1]\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn handler, nil\n}\n\nfunc DetermineDeviceStorage(storageDriver StorageDriver, storageDir string, rwLayerID string) (\n\trootfsStorageDir string, zfsFilesystem string, zfsParent string, err error) {\n\tswitch storageDriver {\n\tcase AufsStorageDriver:\n\t\trootfsStorageDir = path.Join(storageDir, string(AufsStorageDriver), aufsRWLayer, rwLayerID)\n\tcase OverlayStorageDriver:\n\t\trootfsStorageDir = path.Join(storageDir, string(storageDriver), rwLayerID, overlayRWLayer)\n\tcase Overlay2StorageDriver:\n\t\trootfsStorageDir = path.Join(storageDir, string(storageDriver), rwLayerID, overlay2RWLayer)\n\tcase VfsStorageDriver:\n\t\trootfsStorageDir = path.Join(storageDir)\n\tcase ZfsStorageDriver:\n\t\tvar status info.DockerStatus\n\t\tstatus, err = Status()\n\t\tif err != nil {\n\t\t\treturn\n\t\t}\n\t\tzfsParent = status.DriverStatus[dockerutil.DriverStatusParentDataset]\n\t\tzfsFilesystem = path.Join(zfsParent, rwLayerID)\n\t}\n\treturn\n}\n\nfunc (h *containerHandler) ContainerReference() (info.ContainerReference, error) {\n\treturn h.reference, nil\n}\n\nfunc (h *containerHandler) GetSpec() (info.ContainerSpec, error) {\n\thasFilesystem := h.metrics.Has(container.DiskUsageMetrics)\n\thasNetwork := h.metrics.Has(container.NetworkUsageMetrics)\n\tspec, err := common.GetSpec(h.cgroupPaths, h.machineInfoFactory, hasNetwork, hasFilesystem)\n\tif err != nil {\n\t\treturn info.ContainerSpec{}, err\n\t}\n\n\tspec.Labels = h.labels\n\tspec.Envs = h.envs\n\tspec.Image = h.image\n\tspec.CreationTime = h.creationTime\n\tspec.StartTime = h.startTime\n\n\treturn spec, nil\n}\n\nfunc (h *containerHandler) GetStats() (*info.ContainerStats, error) {\n\t// TODO(vmarmol): Get from libcontainer API instead of cgroup manager when we don't have to support older Dockers.\n\tstats, err := h.libcontainerHandler.GetStats()\n\tif err != nil {\n\t\treturn stats, err\n\t}\n\n\t// We assume that if Inspect fails then the container is not known to docker.\n\tres, err := h.client.ContainerInspect(context.Background(), h.reference.Id, dclient.ContainerInspectOptions{})\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to inspect container %q: %v\", h.reference.Id, err)\n\t}\n\tctnr := res.Container\n\n\tif ctnr.State.Health != nil {\n\t\tstats.Health.Status = string(ctnr.State.Health.Status)\n\t}\n\n\t// Get filesystem stats.\n\terr = FsStats(stats, h.machineInfoFactory, h.metrics, h.storageDriver,\n\t\th.fsHandler, h.fsInfo, h.thinPoolName, h.rootfsStorageDir, h.zfsParent)\n\tif err != nil {\n\t\treturn stats, err\n\t}\n\n\treturn stats, nil\n}\n\nfunc (h *containerHandler) ListContainers(container.ListType) ([]info.ContainerReference, error) {\n\treturn []info.ContainerReference{}, nil\n}\n\nfunc (h *containerHandler) ListProcesses(container.ListType) ([]int, error) {\n\treturn h.libcontainerHandler.GetProcesses()\n}\n\nfunc (h *containerHandler) GetCgroupPath(resource string) (string, error) {\n\tvar res string\n\tif !cgroups.IsCgroup2UnifiedMode() {\n\t\tres = resource\n\t}\n\tcgroupPath, ok := h.cgroupPaths[res]\n\tif !ok {\n\t\treturn \"\", fmt.Errorf(\"could not find path for resource %q for container %q\", resource, h.reference.Name)\n\t}\n\treturn cgroupPath, nil\n}\n\nfunc (h *containerHandler) GetContainerLabels() map[string]string {\n\treturn h.labels\n}\n\nfunc (h *containerHandler) GetContainerIPAddress() string {\n\treturn h.ipAddress\n}\n\nfunc (h *containerHandler) Exists() bool {\n\treturn common.CgroupExists(h.cgroupPaths)\n}\n\nfunc (h *containerHandler) Cleanup() {\n\tif h.fsHandler != nil {\n\t\th.fsHandler.Stop()\n\t}\n}\n\nfunc (h *containerHandler) Start() {\n\tif h.fsHandler != nil {\n\t\th.fsHandler.Start()\n\t}\n}\n\nfunc (h *containerHandler) Type() container.ContainerType {\n\treturn container.ContainerTypeDocker\n}\n\nfunc (h *containerHandler) GetExitCode() (int, error) {\n\tres, err := h.client.ContainerInspect(context.Background(), h.reference.Id, dclient.ContainerInspectOptions{})\n\tif err != nil {\n\t\treturn -1, fmt.Errorf(\"failed to inspect container %s: %w\", h.reference.Id, err)\n\t}\n\tctnr := res.Container\n\n\tif ctnr.State.Running {\n\t\treturn -1, fmt.Errorf(\"container %s is still running\", h.reference.Id)\n\t}\n\n\treturn ctnr.State.ExitCode, nil\n}\n"
  },
  {
    "path": "container/docker/handler_test.go",
    "content": "// Copyright 2014 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n//go:build linux\n\n// Handler for Docker containers.\npackage docker\n\nimport (\n\t\"context\"\n\t\"os\"\n\t\"path\"\n\t\"strings\"\n\t\"testing\"\n\n\t\"github.com/moby/moby/api/types/container\"\n\tdclient \"github.com/moby/moby/client\"\n\t\"github.com/stretchr/testify/assert\"\n\n\t\"github.com/google/cadvisor/fs\"\n\tinfo \"github.com/google/cadvisor/info/v1\"\n)\n\ntype mockDockerClientForExitCode struct {\n\tdclient.APIClient\n\tinspectResp dclient.ContainerInspectResult\n\tinspectErr  error\n}\n\nfunc (m *mockDockerClientForExitCode) ContainerInspect(ctx context.Context, containerID string, options dclient.ContainerInspectOptions) (dclient.ContainerInspectResult, error) {\n\treturn m.inspectResp, m.inspectErr\n}\n\nfunc TestStorageDirDetectionWithOldVersions(t *testing.T) {\n\tas := assert.New(t)\n\trwLayer, err := getRwLayerID(\"abcd\", \"/\", AufsStorageDriver, []int{1, 9, 0})\n\tas.Nil(err)\n\tas.Equal(rwLayer, \"abcd\")\n}\n\nfunc TestStorageDirDetectionWithNewVersions(t *testing.T) {\n\tas := assert.New(t)\n\ttestDir := t.TempDir()\n\tcontainerID := \"abcd\"\n\trandomizedID := \"xyz\"\n\trandomIDPath := path.Join(testDir, \"image/aufs/layerdb/mounts/\", containerID)\n\tas.Nil(os.MkdirAll(randomIDPath, os.ModePerm))\n\tas.Nil(os.WriteFile(path.Join(randomIDPath, \"mount-id\"), []byte(randomizedID), os.ModePerm))\n\trwLayer, err := getRwLayerID(containerID, testDir, \"aufs\", []int{1, 10, 0})\n\tas.Nil(err)\n\tas.Equal(rwLayer, randomizedID)\n\trwLayer, err = getRwLayerID(containerID, testDir, \"aufs\", []int{1, 10, 0})\n\tas.Nil(err)\n\tas.Equal(rwLayer, randomizedID)\n\n}\n\nfunc rawMetadataEnvMatch(dockerEnvWhiteList string, cntConfig container.Config) map[string]string {\n\tmetadataEnvAllowList := strings.Split(dockerEnvWhiteList, \",\")\n\thandlerEnvs := make(map[string]string)\n\n\t// split env vars to get metadata map.\n\tfor _, exposedEnv := range metadataEnvAllowList {\n\t\tfor _, envVar := range cntConfig.Env {\n\t\t\tif envVar != \"\" {\n\t\t\t\tsplits := strings.SplitN(envVar, \"=\", 2)\n\t\t\t\tif len(splits) == 2 && splits[0] == exposedEnv {\n\t\t\t\t\thandlerEnvs[strings.ToLower(exposedEnv)] = splits[1]\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn handlerEnvs\n}\n\nfunc newMetadataEnvMatch(dockerEnvWhiteList string, cntConfig container.Config) map[string]string {\n\tmetadataEnvAllowList := strings.Split(dockerEnvWhiteList, \",\")\n\thandlerEnvs := make(map[string]string)\n\n\t// split env vars to get metadata map.\n\tfor _, exposedEnv := range metadataEnvAllowList {\n\t\tif exposedEnv == \"\" {\n\t\t\t// if no dockerEnvWhitelist provided, len(metadataEnvAllowList) == 1, metadataEnvAllowList[0] == \"\"\n\t\t\tcontinue\n\t\t}\n\n\t\tfor _, envVar := range cntConfig.Env {\n\t\t\tif envVar != \"\" {\n\t\t\t\tsplits := strings.SplitN(envVar, \"=\", 2)\n\t\t\t\tif len(splits) == 2 && strings.HasPrefix(splits[0], exposedEnv) {\n\t\t\t\t\thandlerEnvs[strings.ToLower(splits[0])] = splits[1]\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn handlerEnvs\n}\n\nfunc TestDockerEnvWhitelist(t *testing.T) {\n\tas := assert.New(t)\n\n\tenvTotalMatch := \"TEST_REGION,TEST_ZONE\"\n\tenvMatchWithPrefix := \"TEST_\"\n\tenvMatchWithPrefixEmpty := \"\"\n\n\trawCntConfig := container.Config{Env: []string{\"TEST_REGION=FRA\", \"TEST_ZONE=A\", \"HELLO=WORLD\"}}\n\tnewCntConfig := container.Config{Env: []string{\"TEST_REGION=FRA\", \"TEST_ZONE=A\", \"TEST_POOL=TOOLING\", \"HELLO=WORLD\"}}\n\n\trawExpected := map[string]string{\n\t\t\"test_region\": \"FRA\",\n\t\t\"test_zone\":   \"A\",\n\t}\n\tnewExpected := map[string]string{\n\t\t\"test_region\": \"FRA\",\n\t\t\"test_zone\":   \"A\",\n\t\t\"test_pool\":   \"TOOLING\",\n\t}\n\temptyExpected := map[string]string{}\n\n\trawEnvsTotalMatch := rawMetadataEnvMatch(envTotalMatch, rawCntConfig)\n\tnewEnvsTotalMatch := newMetadataEnvMatch(envTotalMatch, rawCntConfig)\n\n\t// make sure total match does not change\n\tas.Equal(rawEnvsTotalMatch, newEnvsTotalMatch)\n\tas.Equal(rawEnvsTotalMatch, rawExpected)\n\n\trawEnvsTotalMatch2 := rawMetadataEnvMatch(envTotalMatch, newCntConfig)\n\tnewEnvsTotalMatch2 := newMetadataEnvMatch(envTotalMatch, newCntConfig)\n\n\t// make sure total match does not change with more envs exposed\n\tas.Equal(rawEnvsTotalMatch2, newEnvsTotalMatch2)\n\tas.Equal(rawEnvsTotalMatch2, rawExpected)\n\n\tnewEnvsMatchWithPrefix := newMetadataEnvMatch(envMatchWithPrefix, rawCntConfig)\n\tnewEnvsMatchWithPrefix2 := newMetadataEnvMatch(envMatchWithPrefix, newCntConfig)\n\n\t// make sure new method can return envs with prefix specified\n\tas.Equal(newEnvsMatchWithPrefix, rawExpected)\n\tas.Equal(newEnvsMatchWithPrefix2, newExpected)\n\n\tnewEnvsMatchWithEmptyPrefix := newMetadataEnvMatch(envMatchWithPrefixEmpty, newCntConfig)\n\trawEnvsMatchWithEmptyWhitelist := rawMetadataEnvMatch(envMatchWithPrefixEmpty, newCntConfig)\n\n\t// make sure empty whitelist returns nothing\n\tas.Equal(newEnvsMatchWithEmptyPrefix, emptyExpected)\n\tas.Equal(rawEnvsMatchWithEmptyWhitelist, emptyExpected)\n\n}\n\nfunc TestAddDiskStatsCheck(t *testing.T) {\n\tvar readsCompleted, readsMerged, sectorsRead, readTime, writesCompleted, writesMerged, sectorsWritten,\n\t\twriteTime, ioInProgress, ioTime, weightedIoTime uint64 = 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11\n\n\tfileSystem := fs.Fs{\n\t\tDiskStats: fs.DiskStats{\n\t\t\tReadsCompleted:  readsCompleted,\n\t\t\tReadsMerged:     readsMerged,\n\t\t\tSectorsRead:     sectorsRead,\n\t\t\tReadTime:        readTime,\n\t\t\tWritesCompleted: writesCompleted,\n\t\t\tWritesMerged:    writesMerged,\n\t\t\tSectorsWritten:  sectorsWritten,\n\t\t\tWriteTime:       writeTime,\n\t\t\tIoInProgress:    ioInProgress,\n\t\t\tIoTime:          ioTime,\n\t\t\tWeightedIoTime:  weightedIoTime,\n\t\t},\n\t}\n\n\tfileSystems := []fs.Fs{fileSystem}\n\n\tvar fsStats info.FsStats\n\taddDiskStats(fileSystems, nil, &fsStats)\n}\n\nfunc TestAddDiskStats(t *testing.T) {\n\t// Arrange\n\tas := assert.New(t)\n\tvar readsCompleted, readsMerged, sectorsRead, readTime, writesCompleted, writesMerged, sectorsWritten,\n\t\twriteTime, ioInProgress, ioTime, weightedIoTime uint64 = 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11\n\tvar fsStats info.FsStats\n\n\tfsInfo := info.FsInfo{\n\t\tDeviceMajor: 4,\n\t\tDeviceMinor: 64,\n\t}\n\n\tfileSystem := fs.Fs{\n\t\tDiskStats: fs.DiskStats{\n\t\t\tReadsCompleted:  readsCompleted,\n\t\t\tReadsMerged:     readsMerged,\n\t\t\tSectorsRead:     sectorsRead,\n\t\t\tReadTime:        readTime,\n\t\t\tWritesCompleted: writesCompleted,\n\t\t\tWritesMerged:    writesMerged,\n\t\t\tSectorsWritten:  sectorsWritten,\n\t\t\tWriteTime:       writeTime,\n\t\t\tIoInProgress:    ioInProgress,\n\t\t\tIoTime:          ioTime,\n\t\t\tWeightedIoTime:  weightedIoTime,\n\t\t},\n\t}\n\n\tfileSystems := []fs.Fs{fileSystem}\n\n\t// Act\n\taddDiskStats(fileSystems, &fsInfo, &fsStats)\n\n\t// Assert\n\tas.Equal(readsCompleted, fileSystem.DiskStats.ReadsCompleted, \"ReadsCompleted metric should be %d but was %d\", readsCompleted, fileSystem.DiskStats.ReadsCompleted)\n\tas.Equal(readsMerged, fileSystem.DiskStats.ReadsMerged, \"ReadsMerged metric should be %d but was %d\", readsMerged, fileSystem.DiskStats.ReadsMerged)\n\tas.Equal(sectorsRead, fileSystem.DiskStats.SectorsRead, \"SectorsRead metric should be %d but was %d\", sectorsRead, fileSystem.DiskStats.SectorsRead)\n\tas.Equal(readTime, fileSystem.DiskStats.ReadTime, \"ReadTime metric should be %d but was %d\", readTime, fileSystem.DiskStats.ReadTime)\n\tas.Equal(writesCompleted, fileSystem.DiskStats.WritesCompleted, \"WritesCompleted metric should be %d but was %d\", writesCompleted, fileSystem.DiskStats.WritesCompleted)\n\tas.Equal(writesMerged, fileSystem.DiskStats.WritesMerged, \"WritesMerged metric should be %d but was %d\", writesMerged, fileSystem.DiskStats.WritesMerged)\n\tas.Equal(sectorsWritten, fileSystem.DiskStats.SectorsWritten, \"SectorsWritten metric should be %d but was %d\", sectorsWritten, fileSystem.DiskStats.SectorsWritten)\n\tas.Equal(writeTime, fileSystem.DiskStats.WriteTime, \"WriteTime metric should be %d but was %d\", writeTime, fileSystem.DiskStats.WriteTime)\n\tas.Equal(ioInProgress, fileSystem.DiskStats.IoInProgress, \"IoInProgress metric should be %d but was %d\", ioInProgress, fileSystem.DiskStats.IoInProgress)\n\tas.Equal(ioTime, fileSystem.DiskStats.IoTime, \"IoTime metric should be %d but was %d\", ioTime, fileSystem.DiskStats.IoTime)\n\tas.Equal(weightedIoTime, fileSystem.DiskStats.WeightedIoTime, \"WeightedIoTime metric should be %d but was %d\", weightedIoTime, fileSystem.DiskStats.WeightedIoTime)\n}\n\nfunc TestGetExitCode(t *testing.T) {\n\ttests := []struct {\n\t\tname         string\n\t\trunning      bool\n\t\texitCode     int\n\t\tinspectErr   error\n\t\texpectErr    bool\n\t\terrContains  string\n\t\texpectedCode int\n\t}{\n\t\t{\n\t\t\tname:         \"successful exit code 0\",\n\t\t\trunning:      false,\n\t\t\texitCode:     0,\n\t\t\tinspectErr:   nil,\n\t\t\texpectErr:    false,\n\t\t\texpectedCode: 0,\n\t\t},\n\t\t{\n\t\t\tname:         \"successful exit code 1\",\n\t\t\trunning:      false,\n\t\t\texitCode:     1,\n\t\t\tinspectErr:   nil,\n\t\t\texpectErr:    false,\n\t\t\texpectedCode: 1,\n\t\t},\n\t\t{\n\t\t\tname:         \"container still running\",\n\t\t\trunning:      true,\n\t\t\texitCode:     0,\n\t\t\tinspectErr:   nil,\n\t\t\texpectErr:    true,\n\t\t\terrContains:  \"still running\",\n\t\t\texpectedCode: -1,\n\t\t},\n\t\t{\n\t\t\tname:         \"inspect fails\",\n\t\t\trunning:      false,\n\t\t\texitCode:     0,\n\t\t\tinspectErr:   assert.AnError,\n\t\t\texpectErr:    true,\n\t\t\terrContains:  \"failed to inspect\",\n\t\t\texpectedCode: -1,\n\t\t},\n\t}\n\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tas := assert.New(t)\n\n\t\t\tmockClient := &mockDockerClientForExitCode{\n\t\t\t\tinspectResp: dclient.ContainerInspectResult{\n\t\t\t\t\tContainer: container.InspectResponse{\n\t\t\t\t\t\tState: &container.State{\n\t\t\t\t\t\t\tRunning:  tt.running,\n\t\t\t\t\t\t\tExitCode: tt.exitCode,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tinspectErr: tt.inspectErr,\n\t\t\t}\n\n\t\t\th := &containerHandler{\n\t\t\t\tclient: mockClient,\n\t\t\t\treference: info.ContainerReference{\n\t\t\t\t\tId: \"test-container-id\",\n\t\t\t\t},\n\t\t\t}\n\n\t\t\tcode, err := h.GetExitCode()\n\n\t\t\tif tt.expectErr {\n\t\t\t\tas.Error(err)\n\t\t\t\tif tt.errContains != \"\" {\n\t\t\t\t\tas.Contains(err.Error(), tt.errContains)\n\t\t\t\t}\n\t\t\t\tas.Equal(tt.expectedCode, code)\n\t\t\t} else {\n\t\t\t\tas.NoError(err)\n\t\t\t\tas.Equal(tt.expectedCode, code)\n\t\t\t}\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "container/docker/install/install.go",
    "content": "// Copyright 2019 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n//go:build linux\n\n// The install package registers docker.NewPlugin() as the \"docker\" container provider when imported\npackage install\n\nimport (\n\t\"k8s.io/klog/v2\"\n\n\t\"github.com/google/cadvisor/container\"\n\t\"github.com/google/cadvisor/container/docker\"\n)\n\nfunc init() {\n\terr := container.RegisterPlugin(\"docker\", docker.NewPlugin())\n\tif err != nil {\n\t\tklog.Fatalf(\"Failed to register docker plugin: %v\", err)\n\t}\n}\n"
  },
  {
    "path": "container/docker/plugin.go",
    "content": "// Copyright 2019 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n//go:build linux\n\npackage docker\n\nimport (\n\t\"context\"\n\t\"time\"\n\n\t\"k8s.io/klog/v2\"\n\n\t\"github.com/google/cadvisor/container\"\n\t\"github.com/google/cadvisor/fs\"\n\tinfo \"github.com/google/cadvisor/info/v1\"\n\t\"github.com/google/cadvisor/watcher\"\n)\n\nconst dockerClientTimeout = 10 * time.Second\n\n// NewPlugin returns an implementation of container.Plugin suitable for passing to container.RegisterPlugin()\nfunc NewPlugin() container.Plugin {\n\treturn &plugin{}\n}\n\ntype plugin struct{}\n\nfunc (p *plugin) InitializeFSContext(context *fs.Context) error {\n\tSetTimeout(dockerClientTimeout)\n\t// Try to connect to docker indefinitely on startup.\n\tdockerStatus := retryDockerStatus()\n\tcontext.Docker = fs.DockerContext{\n\t\tRoot:         RootDir(),\n\t\tDriver:       dockerStatus.Driver,\n\t\tDriverStatus: dockerStatus.DriverStatus,\n\t}\n\treturn nil\n}\n\nfunc (p *plugin) Register(factory info.MachineInfoFactory, fsInfo fs.FsInfo, includedMetrics container.MetricSet) (watcher.ContainerWatcher, error) {\n\terr := Register(factory, fsInfo, includedMetrics)\n\treturn nil, err\n}\n\nfunc retryDockerStatus() info.DockerStatus {\n\tstartupTimeout := dockerClientTimeout\n\tmaxTimeout := 4 * startupTimeout\n\tfor {\n\t\tctx, cancel := context.WithTimeout(context.Background(), startupTimeout)\n\t\tdefer cancel()\n\t\tdockerStatus, err := StatusWithContext(ctx)\n\t\tif err == nil {\n\t\t\treturn dockerStatus\n\t\t}\n\n\t\tswitch err {\n\t\tcase context.DeadlineExceeded:\n\t\t\tklog.Warningf(\"Timeout trying to communicate with docker during initialization, will retry\")\n\t\tdefault:\n\t\t\tklog.V(5).Infof(\"Docker not connected: %v\", err)\n\t\t\treturn info.DockerStatus{}\n\t\t}\n\n\t\tstartupTimeout = 2 * startupTimeout\n\t\tif startupTimeout > maxTimeout {\n\t\t\tstartupTimeout = maxTimeout\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "container/docker/utils/docker.go",
    "content": "// Copyright 2016 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage utils\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\t\"path\"\n\t\"regexp\"\n\t\"strings\"\n\n\tdockerimage \"github.com/moby/moby/api/types/image\"\n\tdockersystem \"github.com/moby/moby/api/types/system\"\n\n\tv1 \"github.com/google/cadvisor/info/v1\"\n)\n\nconst (\n\tDriverStatusPoolName      = \"Pool Name\"\n\tDriverStatusMetadataFile  = \"Metadata file\"\n\tDriverStatusParentDataset = \"Parent Dataset\"\n)\n\n// Regexp that identifies docker cgroups, containers started with\n// --cgroup-parent have another prefix than 'docker'\nvar cgroupRegexp = regexp.MustCompile(`([a-z0-9]{64})`)\n\nfunc DriverStatusValue(status [][2]string, target string) string {\n\tfor _, v := range status {\n\t\tif strings.EqualFold(v[0], target) {\n\t\t\treturn v[1]\n\t\t}\n\t}\n\n\treturn \"\"\n}\n\nfunc DockerThinPoolName(info dockersystem.Info) (string, error) {\n\tpoolName := DriverStatusValue(info.DriverStatus, DriverStatusPoolName)\n\tif len(poolName) == 0 {\n\t\treturn \"\", fmt.Errorf(\"could not get devicemapper pool name\")\n\t}\n\n\treturn poolName, nil\n}\n\nfunc DockerMetadataDevice(info dockersystem.Info) (string, error) {\n\tmetadataDevice := DriverStatusValue(info.DriverStatus, DriverStatusMetadataFile)\n\tif len(metadataDevice) != 0 {\n\t\treturn metadataDevice, nil\n\t}\n\n\tpoolName, err := DockerThinPoolName(info)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\n\tmetadataDevice = fmt.Sprintf(\"/dev/mapper/%s_tmeta\", poolName)\n\n\tif _, err := os.Stat(metadataDevice); err != nil {\n\t\treturn \"\", err\n\t}\n\n\treturn metadataDevice, nil\n}\n\nfunc DockerZfsFilesystem(info dockersystem.Info) (string, error) {\n\tfilesystem := DriverStatusValue(info.DriverStatus, DriverStatusParentDataset)\n\tif len(filesystem) == 0 {\n\t\treturn \"\", fmt.Errorf(\"could not get zfs filesystem\")\n\t}\n\n\treturn filesystem, nil\n}\n\nfunc SummariesToImages(summaries []dockerimage.Summary) ([]v1.DockerImage, error) {\n\tvar out []v1.DockerImage\n\tconst unknownTag = \"<none>:<none>\"\n\tfor _, summary := range summaries {\n\t\tif len(summary.RepoTags) == 1 && summary.RepoTags[0] == unknownTag {\n\t\t\t// images with repo or tags are uninteresting.\n\t\t\tcontinue\n\t\t}\n\t\tdi := v1.DockerImage{\n\t\t\tID:          summary.ID,\n\t\t\tRepoTags:    summary.RepoTags,\n\t\t\tCreated:     summary.Created,\n\t\t\tVirtualSize: summary.Size,\n\t\t\tSize:        summary.Size,\n\t\t}\n\t\tout = append(out, di)\n\t}\n\treturn out, nil\n}\n\n// ContainerNameToId returns the ID from the full container name.\nfunc ContainerNameToId(name string) string {\n\tid := path.Base(name)\n\n\tif matches := cgroupRegexp.FindStringSubmatch(id); matches != nil {\n\t\treturn matches[1]\n\t}\n\n\treturn id\n}\n\n// IsContainerName returns true if the cgroup with associated name\n// corresponds to a container.\nfunc IsContainerName(name string) bool {\n\t// always ignore .mount cgroup even if associated with docker and delegate to systemd\n\tif strings.HasSuffix(name, \".mount\") {\n\t\treturn false\n\t}\n\treturn cgroupRegexp.MatchString(path.Base(name))\n}\n"
  },
  {
    "path": "container/docker/utils/docker_test.go",
    "content": "// Copyright 2022 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage utils\n\nimport \"testing\"\n\nfunc TestIsContainerName(t *testing.T) {\n\ttests := []struct {\n\t\tname     string\n\t\texpected bool\n\t}{\n\t\t{\n\t\t\tname:     \"/system.slice/var-lib-docker-overlay-9f086b233ab7c786bf8b40b164680b658a8f00e94323868e288d6ce20bc92193-merged.mount\",\n\t\t\texpected: false,\n\t\t},\n\t\t{\n\t\t\tname:     \"/system.slice/docker-72e5a5ff5eef3c4222a6551b992b9360a99122f77d2229783f0ee0946dfd800e.scope\",\n\t\t\texpected: true,\n\t\t},\n\t}\n\tfor _, test := range tests {\n\t\tif actual := IsContainerName(test.name); actual != test.expected {\n\t\t\tt.Errorf(\"%s: expected: %v, actual: %v\", test.name, test.expected, actual)\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "container/factory.go",
    "content": "// Copyright 2014 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage container\n\nimport (\n\t\"fmt\"\n\t\"sort\"\n\t\"strings\"\n\t\"sync\"\n\n\t\"github.com/google/cadvisor/fs\"\n\tinfo \"github.com/google/cadvisor/info/v1\"\n\t\"github.com/google/cadvisor/watcher\"\n\n\t\"k8s.io/klog/v2\"\n)\n\ntype ContainerHandlerFactory interface {\n\t// Create a new ContainerHandler using this factory. CanHandleAndAccept() must have returned true.\n\tNewContainerHandler(name string, metadataEnvAllowList []string, inHostNamespace bool) (c ContainerHandler, err error)\n\n\t// Returns whether this factory can handle and accept the specified container.\n\tCanHandleAndAccept(name string) (handle bool, accept bool, err error)\n\n\t// Name of the factory.\n\tString() string\n\n\t// Returns debugging information. Map of lines per category.\n\tDebugInfo() map[string][]string\n}\n\n// MetricKind represents the kind of metrics that cAdvisor exposes.\ntype MetricKind string\n\nconst (\n\tCpuUsageMetrics                MetricKind = \"cpu\"\n\tProcessSchedulerMetrics        MetricKind = \"sched\"\n\tPerCpuUsageMetrics             MetricKind = \"percpu\"\n\tMemoryUsageMetrics             MetricKind = \"memory\"\n\tMemoryNumaMetrics              MetricKind = \"memory_numa\"\n\tCpuLoadMetrics                 MetricKind = \"cpuLoad\"\n\tDiskIOMetrics                  MetricKind = \"diskIO\"\n\tDiskUsageMetrics               MetricKind = \"disk\"\n\tNetworkUsageMetrics            MetricKind = \"network\"\n\tNetworkTcpUsageMetrics         MetricKind = \"tcp\"\n\tNetworkAdvancedTcpUsageMetrics MetricKind = \"advtcp\"\n\tNetworkUdpUsageMetrics         MetricKind = \"udp\"\n\tAppMetrics                     MetricKind = \"app\"\n\tProcessMetrics                 MetricKind = \"process\"\n\tHugetlbUsageMetrics            MetricKind = \"hugetlb\"\n\tPerfMetrics                    MetricKind = \"perf_event\"\n\tReferencedMemoryMetrics        MetricKind = \"referenced_memory\"\n\tCPUTopologyMetrics             MetricKind = \"cpu_topology\"\n\tResctrlMetrics                 MetricKind = \"resctrl\"\n\tCPUSetMetrics                  MetricKind = \"cpuset\"\n\tOOMMetrics                     MetricKind = \"oom_event\"\n\tPressureMetrics                MetricKind = \"pressure\"\n)\n\n// AllMetrics represents all kinds of metrics that cAdvisor supported.\nvar AllMetrics = MetricSet{\n\tCpuUsageMetrics:                struct{}{},\n\tProcessSchedulerMetrics:        struct{}{},\n\tPerCpuUsageMetrics:             struct{}{},\n\tMemoryUsageMetrics:             struct{}{},\n\tMemoryNumaMetrics:              struct{}{},\n\tCpuLoadMetrics:                 struct{}{},\n\tDiskIOMetrics:                  struct{}{},\n\tDiskUsageMetrics:               struct{}{},\n\tNetworkUsageMetrics:            struct{}{},\n\tNetworkTcpUsageMetrics:         struct{}{},\n\tNetworkAdvancedTcpUsageMetrics: struct{}{},\n\tNetworkUdpUsageMetrics:         struct{}{},\n\tProcessMetrics:                 struct{}{},\n\tAppMetrics:                     struct{}{},\n\tHugetlbUsageMetrics:            struct{}{},\n\tPerfMetrics:                    struct{}{},\n\tReferencedMemoryMetrics:        struct{}{},\n\tCPUTopologyMetrics:             struct{}{},\n\tResctrlMetrics:                 struct{}{},\n\tCPUSetMetrics:                  struct{}{},\n\tOOMMetrics:                     struct{}{},\n\tPressureMetrics:                struct{}{},\n}\n\n// AllNetworkMetrics represents all network metrics that cAdvisor supports.\nvar AllNetworkMetrics = MetricSet{\n\tNetworkUsageMetrics:            struct{}{},\n\tNetworkTcpUsageMetrics:         struct{}{},\n\tNetworkAdvancedTcpUsageMetrics: struct{}{},\n\tNetworkUdpUsageMetrics:         struct{}{},\n}\n\nfunc (mk MetricKind) String() string {\n\treturn string(mk)\n}\n\ntype MetricSet map[MetricKind]struct{}\n\nfunc (ms MetricSet) Has(mk MetricKind) bool {\n\t_, exists := ms[mk]\n\treturn exists\n}\n\nfunc (ms MetricSet) HasAny(ms1 MetricSet) bool {\n\tfor m := range ms1 {\n\t\tif _, ok := ms[m]; ok {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\nfunc (ms MetricSet) add(mk MetricKind) {\n\tms[mk] = struct{}{}\n}\n\nfunc (ms MetricSet) String() string {\n\tvalues := make([]string, 0, len(ms))\n\tfor metric := range ms {\n\t\tvalues = append(values, string(metric))\n\t}\n\tsort.Strings(values)\n\treturn strings.Join(values, \",\")\n}\n\n// Not thread-safe, exported only for https://pkg.go.dev/flag#Value\nfunc (ms *MetricSet) Set(value string) error {\n\t*ms = MetricSet{}\n\tif value == \"\" {\n\t\treturn nil\n\t}\n\tfor _, metric := range strings.Split(value, \",\") {\n\t\tif AllMetrics.Has(MetricKind(metric)) {\n\t\t\t(*ms).add(MetricKind(metric))\n\t\t} else {\n\t\t\treturn fmt.Errorf(\"unsupported metric %q specified\", metric)\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc (ms MetricSet) Difference(ms1 MetricSet) MetricSet {\n\tresult := MetricSet{}\n\tfor kind := range ms {\n\t\tif !ms1.Has(kind) {\n\t\t\tresult.add(kind)\n\t\t}\n\t}\n\treturn result\n}\n\nfunc (ms MetricSet) Append(ms1 MetricSet) MetricSet {\n\tresult := ms\n\tfor kind := range ms1 {\n\t\tif !ms.Has(kind) {\n\t\t\tresult.add(kind)\n\t\t}\n\t}\n\treturn result\n}\n\n// All registered auth provider plugins.\nvar pluginsLock sync.Mutex\nvar plugins = make(map[string]Plugin)\n\ntype Plugin interface {\n\t// InitializeFSContext is invoked when populating an fs.Context object for a new manager.\n\t// A returned error here is fatal.\n\tInitializeFSContext(context *fs.Context) error\n\n\t// Register is invoked when starting a manager. It can optionally return a container watcher.\n\t// A returned error is logged, but is not fatal.\n\tRegister(factory info.MachineInfoFactory, fsInfo fs.FsInfo, includedMetrics MetricSet) (watcher.ContainerWatcher, error)\n}\n\nfunc RegisterPlugin(name string, plugin Plugin) error {\n\tpluginsLock.Lock()\n\tdefer pluginsLock.Unlock()\n\tif _, found := plugins[name]; found {\n\t\treturn fmt.Errorf(\"Plugin %q was registered twice\", name)\n\t}\n\tplugins[name] = plugin\n\treturn nil\n}\n\nfunc InitializeFSContext(context *fs.Context) error {\n\tpluginsLock.Lock()\n\tdefer pluginsLock.Unlock()\n\tfor name, plugin := range plugins {\n\t\terr := plugin.InitializeFSContext(context)\n\t\tif err != nil {\n\t\t\tklog.V(5).Infof(\"Initialization of the %s context failed: %v\", name, err)\n\t\t\treturn err\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc InitializePlugins(factory info.MachineInfoFactory, fsInfo fs.FsInfo, includedMetrics MetricSet) []watcher.ContainerWatcher {\n\tpluginsLock.Lock()\n\tdefer pluginsLock.Unlock()\n\n\tcontainerWatchers := []watcher.ContainerWatcher{}\n\tfor name, plugin := range plugins {\n\t\twatcher, err := plugin.Register(factory, fsInfo, includedMetrics)\n\t\tif err != nil {\n\t\t\tklog.Infof(\"Registration of the %s container factory failed: %v\", name, err)\n\t\t} else {\n\t\t\tklog.Infof(\"Registration of the %s container factory successfully\", name)\n\t\t}\n\t\tif watcher != nil {\n\t\t\tcontainerWatchers = append(containerWatchers, watcher)\n\t\t}\n\t}\n\treturn containerWatchers\n}\n\n// TODO(vmarmol): Consider not making this global.\n// Global list of factories.\nvar (\n\tfactories     = map[watcher.ContainerWatchSource][]ContainerHandlerFactory{}\n\tfactoriesLock sync.RWMutex\n)\n\n// Register a ContainerHandlerFactory. These should be registered from least general to most general\n// as they will be asked in order whether they can handle a particular container.\nfunc RegisterContainerHandlerFactory(factory ContainerHandlerFactory, watchTypes []watcher.ContainerWatchSource) {\n\tfactoriesLock.Lock()\n\tdefer factoriesLock.Unlock()\n\n\tfor _, watchType := range watchTypes {\n\t\tfactories[watchType] = append(factories[watchType], factory)\n\t}\n}\n\n// Returns whether there are any container handler factories registered.\nfunc HasFactories() bool {\n\tfactoriesLock.Lock()\n\tdefer factoriesLock.Unlock()\n\n\treturn len(factories) != 0\n}\n\n// Create a new ContainerHandler for the specified container.\nfunc NewContainerHandler(name string, watchType watcher.ContainerWatchSource, metadataEnvAllowList []string, inHostNamespace bool) (ContainerHandler, bool, error) {\n\tfactoriesLock.RLock()\n\tdefer factoriesLock.RUnlock()\n\n\t// Create the ContainerHandler with the first factory that supports it.\n\t// Note that since RawContainerHandler can support a wide range of paths,\n\t// it's evaluated last just to make sure if any other ContainerHandler\n\t// can support it.\n\tfor _, factory := range GetReorderedFactoryList(watchType) {\n\t\tcanHandle, canAccept, err := factory.CanHandleAndAccept(name)\n\t\tif err != nil {\n\t\t\tklog.V(4).Infof(\"Error trying to work out if we can handle %s: %v\", name, err)\n\t\t}\n\t\tif canHandle {\n\t\t\tif !canAccept {\n\t\t\t\tklog.V(3).Infof(\"Factory %q can handle container %q, but ignoring.\", factory, name)\n\t\t\t\treturn nil, false, nil\n\t\t\t}\n\t\t\tklog.V(3).Infof(\"Using factory %q for container %q\", factory, name)\n\t\t\thandle, err := factory.NewContainerHandler(name, metadataEnvAllowList, inHostNamespace)\n\t\t\treturn handle, canAccept, err\n\t\t}\n\t\tklog.V(4).Infof(\"Factory %q was unable to handle container %q\", factory, name)\n\t}\n\n\treturn nil, false, fmt.Errorf(\"no known factory can handle creation of container\")\n}\n\n// Clear the known factories.\nfunc ClearContainerHandlerFactories() {\n\tfactoriesLock.Lock()\n\tdefer factoriesLock.Unlock()\n\n\tfactories = map[watcher.ContainerWatchSource][]ContainerHandlerFactory{}\n}\n\nfunc DebugInfo() map[string][]string {\n\tfactoriesLock.RLock()\n\tdefer factoriesLock.RUnlock()\n\n\t// Get debug information for all factories.\n\tout := make(map[string][]string)\n\tfor _, factoriesSlice := range factories {\n\t\tfor _, factory := range factoriesSlice {\n\t\t\tfor k, v := range factory.DebugInfo() {\n\t\t\t\tout[k] = v\n\t\t\t}\n\t\t}\n\t}\n\treturn out\n}\n\n// GetReorderedFactoryList returns the list of ContainerHandlerFactory where the\n// RawContainerHandler is always the last element.\nfunc GetReorderedFactoryList(watchType watcher.ContainerWatchSource) []ContainerHandlerFactory {\n\tContainerHandlerFactoryList := make([]ContainerHandlerFactory, 0, len(factories))\n\n\tvar rawFactory ContainerHandlerFactory\n\tfor _, v := range factories[watchType] {\n\t\tif v != nil {\n\t\t\tif v.String() == \"raw\" {\n\t\t\t\trawFactory = v\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tContainerHandlerFactoryList = append(ContainerHandlerFactoryList, v)\n\t\t}\n\t}\n\n\tif rawFactory != nil {\n\t\tContainerHandlerFactoryList = append(ContainerHandlerFactoryList, rawFactory)\n\t}\n\n\treturn ContainerHandlerFactoryList\n}\n"
  },
  {
    "path": "container/factory_test.go",
    "content": "// Copyright 2014 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage container_test\n\nimport (\n\t\"testing\"\n\n\t\"github.com/google/cadvisor/container\"\n\tcontainertest \"github.com/google/cadvisor/container/testing\"\n\t\"github.com/google/cadvisor/watcher\"\n\n\t\"github.com/stretchr/testify/mock\"\n)\n\ntype mockContainerHandlerFactory struct {\n\tmock.Mock\n\tName           string\n\tCanHandleValue bool\n\tCanAcceptValue bool\n}\n\nfunc (f *mockContainerHandlerFactory) String() string {\n\treturn f.Name\n}\n\nfunc (f *mockContainerHandlerFactory) DebugInfo() map[string][]string {\n\treturn map[string][]string{}\n}\n\nfunc (f *mockContainerHandlerFactory) CanHandleAndAccept(name string) (bool, bool, error) {\n\treturn f.CanHandleValue, f.CanAcceptValue, nil\n}\n\nfunc (f *mockContainerHandlerFactory) NewContainerHandler(name string, metadataEnvAllowList []string, isHostNamespace bool) (container.ContainerHandler, error) {\n\targs := f.Called(name)\n\treturn args.Get(0).(container.ContainerHandler), args.Error(1)\n}\n\nconst testContainerName = \"/test\"\n\nvar testMetadataEnvAllowList = []string{}\n\nvar mockFactory containertest.FactoryForMockContainerHandler\n\nfunc TestNewContainerHandler_FirstMatches(t *testing.T) {\n\tcontainer.ClearContainerHandlerFactories()\n\n\t// Register one allways yes factory.\n\tallwaysYes := &mockContainerHandlerFactory{\n\t\tName:           \"yes\",\n\t\tCanHandleValue: true,\n\t\tCanAcceptValue: true,\n\t}\n\tcontainer.RegisterContainerHandlerFactory(allwaysYes, []watcher.ContainerWatchSource{watcher.Raw})\n\n\t// The yes factory should be asked to create the ContainerHandler.\n\tmockContainer, err := mockFactory.NewContainerHandler(testContainerName, testMetadataEnvAllowList, true)\n\tif err != nil {\n\t\tt.Error(err)\n\t}\n\tallwaysYes.On(\"NewContainerHandler\", testContainerName).Return(mockContainer, nil)\n\n\tcont, _, err := container.NewContainerHandler(testContainerName, watcher.Raw, testMetadataEnvAllowList, true)\n\tif err != nil {\n\t\tt.Error(err)\n\t}\n\tif cont == nil {\n\t\tt.Error(\"Expected container to not be nil\")\n\t}\n}\n\nfunc TestNewContainerHandler_SecondMatches(t *testing.T) {\n\tcontainer.ClearContainerHandlerFactories()\n\n\t// Register one allways no and one always yes factory.\n\tallwaysNo := &mockContainerHandlerFactory{\n\t\tName:           \"no\",\n\t\tCanHandleValue: false,\n\t\tCanAcceptValue: true,\n\t}\n\tcontainer.RegisterContainerHandlerFactory(allwaysNo, []watcher.ContainerWatchSource{watcher.Raw})\n\tallwaysYes := &mockContainerHandlerFactory{\n\t\tName:           \"yes\",\n\t\tCanHandleValue: true,\n\t\tCanAcceptValue: true,\n\t}\n\tcontainer.RegisterContainerHandlerFactory(allwaysYes, []watcher.ContainerWatchSource{watcher.Raw})\n\n\t// The yes factory should be asked to create the ContainerHandler.\n\tmockContainer, err := mockFactory.NewContainerHandler(testContainerName, testMetadataEnvAllowList, true)\n\tif err != nil {\n\t\tt.Error(err)\n\t}\n\tallwaysYes.On(\"NewContainerHandler\", testContainerName).Return(mockContainer, nil)\n\n\tcont, _, err := container.NewContainerHandler(testContainerName, watcher.Raw, testMetadataEnvAllowList, true)\n\tif err != nil {\n\t\tt.Error(err)\n\t}\n\tif cont == nil {\n\t\tt.Error(\"Expected container to not be nil\")\n\t}\n}\n\nfunc TestNewContainerHandler_NoneMatch(t *testing.T) {\n\tcontainer.ClearContainerHandlerFactories()\n\n\t// Register two allways no factories.\n\tallwaysNo1 := &mockContainerHandlerFactory{\n\t\tName:           \"no\",\n\t\tCanHandleValue: false,\n\t\tCanAcceptValue: true,\n\t}\n\tcontainer.RegisterContainerHandlerFactory(allwaysNo1, []watcher.ContainerWatchSource{watcher.Raw})\n\tallwaysNo2 := &mockContainerHandlerFactory{\n\t\tName:           \"no\",\n\t\tCanHandleValue: false,\n\t\tCanAcceptValue: true,\n\t}\n\tcontainer.RegisterContainerHandlerFactory(allwaysNo2, []watcher.ContainerWatchSource{watcher.Raw})\n\n\t_, _, err := container.NewContainerHandler(testContainerName, watcher.Raw, testMetadataEnvAllowList, true)\n\tif err == nil {\n\t\tt.Error(\"Expected NewContainerHandler to fail\")\n\t}\n}\n\nfunc TestNewContainerHandler_Accept(t *testing.T) {\n\tcontainer.ClearContainerHandlerFactories()\n\n\t// Register handler that can handle the container, but can't accept it.\n\tcannotHandle := &mockContainerHandlerFactory{\n\t\tName:           \"no\",\n\t\tCanHandleValue: false,\n\t\tCanAcceptValue: true,\n\t}\n\tcontainer.RegisterContainerHandlerFactory(cannotHandle, []watcher.ContainerWatchSource{watcher.Raw})\n\tcannotAccept := &mockContainerHandlerFactory{\n\t\tName:           \"no\",\n\t\tCanHandleValue: true,\n\t\tCanAcceptValue: false,\n\t}\n\tcontainer.RegisterContainerHandlerFactory(cannotAccept, []watcher.ContainerWatchSource{watcher.Raw})\n\n\t_, accept, err := container.NewContainerHandler(testContainerName, watcher.Raw, testMetadataEnvAllowList, true)\n\tif err != nil {\n\t\tt.Error(\"Expected NewContainerHandler to succeed\")\n\t}\n\tif accept == true {\n\t\tt.Error(\"Expected NewContainerHandler to ignore the container.\")\n\t}\n}\n\nfunc TestRawContainerHandler_Last(t *testing.T) {\n\tchf1 := &mockContainerHandlerFactory{\n\t\tName: \"raw\",\n\t}\n\tcontainer.RegisterContainerHandlerFactory(chf1, []watcher.ContainerWatchSource{watcher.Raw})\n\tcfh2 := &mockContainerHandlerFactory{\n\t\tName: \"crio\",\n\t}\n\tcontainer.RegisterContainerHandlerFactory(cfh2, []watcher.ContainerWatchSource{watcher.Raw})\n\n\tcfh3 := &mockContainerHandlerFactory{\n\t\tName: \"containerd\",\n\t}\n\tcontainer.RegisterContainerHandlerFactory(cfh3, []watcher.ContainerWatchSource{watcher.Raw})\n\n\tlist := container.GetReorderedFactoryList(watcher.Raw)\n\n\tif list[len(list)-1].String() != \"raw\" {\n\t\tt.Error(\"Expected raw container handler to be last in the list.\")\n\t}\n}\n"
  },
  {
    "path": "container/libcontainer/handler.go",
    "content": "// Copyright 2018 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n//go:build linux\n\npackage libcontainer\n\nimport (\n\t\"bufio\"\n\t\"bytes\"\n\t\"encoding/json\"\n\t\"flag\"\n\t\"fmt\"\n\t\"io\"\n\t\"os\"\n\t\"path\"\n\t\"regexp\"\n\t\"strconv\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/opencontainers/cgroups\"\n\t\"github.com/opencontainers/cgroups/fs2\"\n\t\"k8s.io/klog/v2\"\n\n\t\"github.com/google/cadvisor/container\"\n\t\"github.com/google/cadvisor/container/common\"\n\tinfo \"github.com/google/cadvisor/info/v1\"\n)\n\nvar (\n\treferencedResetInterval = flag.Uint64(\"referenced_reset_interval\", 0,\n\t\t\"Reset interval for referenced bytes (container_referenced_bytes metric), number of measurement cycles after which referenced bytes are cleared, if set to 0 referenced bytes are never cleared (default: 0)\")\n\n\tsmapsFilePathPattern     = \"/proc/%d/smaps\"\n\tclearRefsFilePathPattern = \"/proc/%d/clear_refs\"\n\n\treferencedRegexp = regexp.MustCompile(`Referenced:\\s*([0-9]+)\\s*kB`)\n)\n\ntype Handler struct {\n\tcgroupManager   cgroups.Manager\n\trootFs          string\n\tpid             int\n\tincludedMetrics container.MetricSet\n\t// pidMetricsCache holds CPU scheduler stats for existing processes (map key is PID) between calls to schedulerStatsFromProcs.\n\tpidMetricsCache map[int]*info.CpuSchedstat\n\t// pidMetricsSaved holds accumulated CPU scheduler stats for processes that no longer exist.\n\tpidMetricsSaved info.CpuSchedstat\n\tcycles          uint64\n}\n\nfunc NewHandler(cgroupManager cgroups.Manager, rootFs string, pid int, includedMetrics container.MetricSet) *Handler {\n\treturn &Handler{\n\t\tcgroupManager:   cgroupManager,\n\t\trootFs:          rootFs,\n\t\tpid:             pid,\n\t\tincludedMetrics: includedMetrics,\n\t\tpidMetricsCache: make(map[int]*info.CpuSchedstat),\n\t}\n}\n\n// Get cgroup and networking stats of the specified container\nfunc (h *Handler) GetStats() (*info.ContainerStats, error) {\n\tignoreStatsError := false\n\tif cgroups.IsCgroup2UnifiedMode() {\n\t\t// On cgroup v2 the root cgroup stats have been introduced in recent kernel versions,\n\t\t// so not all kernel versions have all the data. This means that stat fetching can fail\n\t\t// due to lacking cgroup stat files, but that some data is provided.\n\t\tif h.cgroupManager.Path(\"\") == fs2.UnifiedMountpoint {\n\t\t\tignoreStatsError = true\n\t\t}\n\t}\n\n\tcgroupStats, err := h.cgroupManager.GetStats()\n\tif err != nil {\n\t\tif !ignoreStatsError {\n\t\t\treturn nil, err\n\t\t}\n\t\tklog.V(4).Infof(\"Ignoring errors when gathering stats for root cgroup since some controllers don't have stats on the root cgroup: %v\", err)\n\t}\n\tstats := newContainerStats(cgroupStats, h.includedMetrics)\n\n\tif h.includedMetrics.Has(container.ProcessSchedulerMetrics) {\n\t\tstats.Cpu.Schedstat, err = h.schedulerStatsFromProcs()\n\t\tif err != nil {\n\t\t\tklog.V(4).Infof(\"Unable to get Process Scheduler Stats: %v\", err)\n\t\t}\n\t}\n\n\tif h.includedMetrics.Has(container.ReferencedMemoryMetrics) {\n\t\th.cycles++\n\t\tpids, err := h.cgroupManager.GetPids()\n\t\tif err != nil {\n\t\t\tklog.V(4).Infof(\"Could not get PIDs for container %d: %v\", h.pid, err)\n\t\t} else {\n\t\t\tstats.ReferencedMemory, err = referencedBytesStat(pids, h.cycles, *referencedResetInterval)\n\t\t\tif err != nil {\n\t\t\t\tklog.V(4).Infof(\"Unable to get referenced bytes: %v\", err)\n\t\t\t}\n\t\t}\n\t}\n\n\t// If we know the pid then get network stats from /proc/<pid>/net/dev\n\tif h.pid > 0 {\n\t\tif h.includedMetrics.Has(container.NetworkUsageMetrics) {\n\t\t\tnetStats, err := networkStatsFromProc(h.rootFs, h.pid)\n\t\t\tif err != nil {\n\t\t\t\tklog.V(4).Infof(\"Unable to get network stats from pid %d: %v\", h.pid, err)\n\t\t\t} else {\n\t\t\t\tstats.Network.Interfaces = append(stats.Network.Interfaces, netStats...)\n\t\t\t}\n\t\t}\n\t\tif h.includedMetrics.Has(container.NetworkTcpUsageMetrics) {\n\t\t\tt, err := tcpStatsFromProc(h.rootFs, h.pid, \"net/tcp\")\n\t\t\tif err != nil {\n\t\t\t\tklog.V(4).Infof(\"Unable to get tcp stats from pid %d: %v\", h.pid, err)\n\t\t\t} else {\n\t\t\t\tstats.Network.Tcp = t\n\t\t\t}\n\n\t\t\tt6, err := tcpStatsFromProc(h.rootFs, h.pid, \"net/tcp6\")\n\t\t\tif err != nil {\n\t\t\t\tklog.V(4).Infof(\"Unable to get tcp6 stats from pid %d: %v\", h.pid, err)\n\t\t\t} else {\n\t\t\t\tstats.Network.Tcp6 = t6\n\t\t\t}\n\n\t\t}\n\t\tif h.includedMetrics.Has(container.NetworkAdvancedTcpUsageMetrics) {\n\t\t\tta, err := advancedTCPStatsFromProc(h.rootFs, h.pid, \"net/netstat\", \"net/snmp\")\n\t\t\tif err != nil {\n\t\t\t\tklog.V(4).Infof(\"Unable to get advanced tcp stats from pid %d: %v\", h.pid, err)\n\t\t\t} else {\n\t\t\t\tstats.Network.TcpAdvanced = ta\n\t\t\t}\n\t\t}\n\t\tif h.includedMetrics.Has(container.NetworkUdpUsageMetrics) {\n\t\t\tu, err := udpStatsFromProc(h.rootFs, h.pid, \"net/udp\")\n\t\t\tif err != nil {\n\t\t\t\tklog.V(4).Infof(\"Unable to get udp stats from pid %d: %v\", h.pid, err)\n\t\t\t} else {\n\t\t\t\tstats.Network.Udp = u\n\t\t\t}\n\n\t\t\tu6, err := udpStatsFromProc(h.rootFs, h.pid, \"net/udp6\")\n\t\t\tif err != nil {\n\t\t\t\tklog.V(4).Infof(\"Unable to get udp6 stats from pid %d: %v\", h.pid, err)\n\t\t\t} else {\n\t\t\t\tstats.Network.Udp6 = u6\n\t\t\t}\n\t\t}\n\t}\n\t// some process metrics are per container ( number of processes, number of\n\t// file descriptors etc.) and not required a proper container's\n\t// root PID (systemd services don't have the root PID atm)\n\tif h.includedMetrics.Has(container.ProcessMetrics) {\n\t\tpath, ok := common.GetControllerPath(h.cgroupManager.GetPaths(), \"cpu\", cgroups.IsCgroup2UnifiedMode())\n\t\tif !ok {\n\t\t\tklog.V(4).Infof(\"Could not find cgroups CPU for container %d\", h.pid)\n\t\t} else {\n\t\t\tstats.Processes, err = processStatsFromProcs(h.rootFs, path, h.pid)\n\t\t\tif err != nil {\n\t\t\t\tklog.V(4).Infof(\"Unable to get Process Stats: %v\", err)\n\t\t\t}\n\t\t}\n\n\t\t// if include processes metrics, just set threads metrics if exist, and has no relationship with cpu path\n\t\tsetThreadsStats(cgroupStats, stats)\n\t}\n\n\t// For backwards compatibility.\n\tif len(stats.Network.Interfaces) > 0 {\n\t\tstats.Network.InterfaceStats = stats.Network.Interfaces[0]\n\t}\n\n\treturn stats, nil\n}\n\nfunc parseUlimit(value string) (int64, error) {\n\tnum, err := strconv.ParseInt(value, 10, 64)\n\tif err != nil {\n\t\tif strings.EqualFold(value, \"unlimited\") {\n\t\t\t// -1 implies unlimited except for priority and nice; man limits.conf\n\t\t\tnum = -1\n\t\t} else {\n\t\t\t// Value is not a number or \"unlimited\"; return an error\n\t\t\treturn 0, fmt.Errorf(\"unable to parse limit: %s\", value)\n\t\t}\n\t}\n\treturn num, nil\n}\n\nfunc processLimitsFile(fileData string) []info.UlimitSpec {\n\tconst maxOpenFilesLinePrefix = \"Max open files\"\n\n\tlimits := strings.Split(fileData, \"\\n\")\n\tulimits := make([]info.UlimitSpec, 0, len(limits))\n\tfor _, lim := range limits {\n\t\t// Skip any headers/footers\n\t\tif strings.HasPrefix(lim, \"Max open files\") {\n\t\t\t// Remove line prefix\n\t\t\tulimit, err := processMaxOpenFileLimitLine(\n\t\t\t\t\"max_open_files\",\n\t\t\t\tlim[len(maxOpenFilesLinePrefix):],\n\t\t\t)\n\t\t\tif err == nil {\n\t\t\t\tulimits = append(ulimits, ulimit)\n\t\t\t}\n\t\t}\n\t}\n\treturn ulimits\n}\n\n// Any caller of processMaxOpenFileLimitLine must ensure that the name prefix is already removed from the limit line.\n// with the \"Max open files\" prefix.\nfunc processMaxOpenFileLimitLine(name, line string) (info.UlimitSpec, error) {\n\t// Remove any leading whitespace\n\tline = strings.TrimSpace(line)\n\t// Split on whitespace\n\tfields := strings.Fields(line)\n\tif len(fields) != 3 {\n\t\treturn info.UlimitSpec{}, fmt.Errorf(\"unable to parse max open files line: %s\", line)\n\t}\n\t// The first field is the soft limit, the second is the hard limit\n\tsoft, err := parseUlimit(fields[0])\n\tif err != nil {\n\t\treturn info.UlimitSpec{}, err\n\t}\n\thard, err := parseUlimit(fields[1])\n\tif err != nil {\n\t\treturn info.UlimitSpec{}, err\n\t}\n\treturn info.UlimitSpec{\n\t\tName:      name,\n\t\tSoftLimit: soft,\n\t\tHardLimit: hard,\n\t}, nil\n}\n\nfunc processRootProcUlimits(rootFs string, rootPid int) []info.UlimitSpec {\n\tfilePath := path.Join(rootFs, \"/proc\", strconv.Itoa(rootPid), \"limits\")\n\tout, err := os.ReadFile(filePath)\n\tif err != nil {\n\t\tklog.V(4).Infof(\"error while listing directory %q to read ulimits: %v\", filePath, err)\n\t\treturn []info.UlimitSpec{}\n\t}\n\treturn processLimitsFile(string(out))\n}\n\nfunc processStatsFromProcs(rootFs string, cgroupPath string, rootPid int) (info.ProcessStats, error) {\n\tvar fdCount, socketCount uint64\n\tfilePath := path.Join(cgroupPath, \"cgroup.procs\")\n\tout, err := os.ReadFile(filePath)\n\tif err != nil {\n\t\treturn info.ProcessStats{}, fmt.Errorf(\"couldn't open cpu cgroup procs file %v : %v\", filePath, err)\n\t}\n\n\tpids := strings.Split(string(out), \"\\n\")\n\n\t// EOL is also treated as a new line while reading \"cgroup.procs\" file with os.ReadFile.\n\t// The last value is an empty string \"\". Ex: pids = [\"22\", \"1223\", \"\"]\n\t// Trim the last value\n\tif len(pids) != 0 && pids[len(pids)-1] == \"\" {\n\t\tpids = pids[:len(pids)-1]\n\t}\n\n\tfor _, pid := range pids {\n\t\tdirPath := path.Join(rootFs, \"/proc\", pid, \"fd\")\n\t\tfds, err := os.ReadDir(dirPath)\n\t\tif err != nil {\n\t\t\tklog.V(4).Infof(\"error while listing directory %q to measure fd count: %v\", dirPath, err)\n\t\t\tcontinue\n\t\t}\n\t\tfdCount += uint64(len(fds))\n\t\tfor _, fd := range fds {\n\t\t\tfdPath := path.Join(dirPath, fd.Name())\n\t\t\tlinkName, err := os.Readlink(fdPath)\n\t\t\tif err != nil {\n\t\t\t\tklog.V(4).Infof(\"error while reading %q link: %v\", fdPath, err)\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif strings.HasPrefix(linkName, \"socket\") {\n\t\t\t\tsocketCount++\n\t\t\t}\n\t\t}\n\t}\n\n\tprocessStats := info.ProcessStats{\n\t\tProcessCount: uint64(len(pids)),\n\t\tFdCount:      fdCount,\n\t\tSocketCount:  socketCount,\n\t}\n\n\tif rootPid > 0 {\n\t\tprocessStats.Ulimits = processRootProcUlimits(rootFs, rootPid)\n\t}\n\n\treturn processStats, nil\n}\n\nfunc (h *Handler) schedulerStatsFromProcs() (info.CpuSchedstat, error) {\n\tpids, err := h.cgroupManager.GetAllPids()\n\tif err != nil {\n\t\treturn info.CpuSchedstat{}, fmt.Errorf(\"could not get PIDs for container %d: %w\", h.pid, err)\n\t}\n\talivePids := make(map[int]struct{}, len(pids))\n\tfor _, pid := range pids {\n\t\tf, err := os.Open(path.Join(h.rootFs, \"proc\", strconv.Itoa(pid), \"schedstat\"))\n\t\tif err != nil {\n\t\t\treturn info.CpuSchedstat{}, fmt.Errorf(\"couldn't open scheduler statistics for process %d: %v\", pid, err)\n\t\t}\n\t\tdefer f.Close()\n\t\tcontents, err := io.ReadAll(f)\n\t\tif err != nil {\n\t\t\treturn info.CpuSchedstat{}, fmt.Errorf(\"couldn't read scheduler statistics for process %d: %v\", pid, err)\n\t\t}\n\t\talivePids[pid] = struct{}{}\n\t\trawMetrics := bytes.Split(bytes.TrimRight(contents, \"\\n\"), []byte(\" \"))\n\t\tif len(rawMetrics) != 3 {\n\t\t\treturn info.CpuSchedstat{}, fmt.Errorf(\"unexpected number of metrics in schedstat file for process %d\", pid)\n\t\t}\n\t\tcacheEntry, ok := h.pidMetricsCache[pid]\n\t\tif !ok {\n\t\t\tcacheEntry = &info.CpuSchedstat{}\n\t\t\th.pidMetricsCache[pid] = cacheEntry\n\t\t}\n\t\tfor i, rawMetric := range rawMetrics {\n\t\t\tmetric, err := strconv.ParseUint(string(rawMetric), 10, 64)\n\t\t\tif err != nil {\n\t\t\t\treturn info.CpuSchedstat{}, fmt.Errorf(\"parsing error while reading scheduler statistics for process: %d: %v\", pid, err)\n\t\t\t}\n\t\t\tswitch i {\n\t\t\tcase 0:\n\t\t\t\tcacheEntry.RunTime = metric\n\t\t\tcase 1:\n\t\t\t\tcacheEntry.RunqueueTime = metric\n\t\t\tcase 2:\n\t\t\t\tcacheEntry.RunPeriods = metric\n\t\t\t}\n\t\t}\n\t}\n\tschedstats := h.pidMetricsSaved // copy\n\tfor p, v := range h.pidMetricsCache {\n\t\tschedstats.RunPeriods += v.RunPeriods\n\t\tschedstats.RunqueueTime += v.RunqueueTime\n\t\tschedstats.RunTime += v.RunTime\n\t\tif _, alive := alivePids[p]; !alive {\n\t\t\t// PID p is gone: accumulate its stats ...\n\t\t\th.pidMetricsSaved.RunPeriods += v.RunPeriods\n\t\t\th.pidMetricsSaved.RunqueueTime += v.RunqueueTime\n\t\t\th.pidMetricsSaved.RunTime += v.RunTime\n\t\t\t// ... and remove its cache entry, to prevent\n\t\t\t// pidMetricsCache from growing.\n\t\t\tdelete(h.pidMetricsCache, p)\n\t\t}\n\t}\n\treturn schedstats, nil\n}\n\n// referencedBytesStat gets and clears referenced bytes\n// see: https://github.com/brendangregg/wss#wsspl-referenced-page-flag\nfunc referencedBytesStat(pids []int, cycles uint64, resetInterval uint64) (uint64, error) {\n\treferencedKBytes, err := getReferencedKBytes(pids)\n\tif err != nil {\n\t\treturn uint64(0), err\n\t}\n\n\terr = clearReferencedBytes(pids, cycles, resetInterval)\n\tif err != nil {\n\t\treturn uint64(0), err\n\t}\n\treturn referencedKBytes * 1024, nil\n}\n\nfunc getReferencedKBytes(pids []int) (uint64, error) {\n\treferencedKBytes := uint64(0)\n\treadSmapsContent := false\n\tfoundMatch := false\n\tfor _, pid := range pids {\n\t\tsmapsFilePath := fmt.Sprintf(smapsFilePathPattern, pid)\n\t\tsmapsContent, err := os.ReadFile(smapsFilePath)\n\t\tif err != nil {\n\t\t\tklog.V(5).Infof(\"Cannot read %s file, err: %s\", smapsFilePath, err)\n\t\t\tif os.IsNotExist(err) {\n\t\t\t\tcontinue // smaps file does not exists for all PIDs\n\t\t\t}\n\t\t\treturn 0, err\n\t\t}\n\t\treadSmapsContent = true\n\n\t\tallMatches := referencedRegexp.FindAllSubmatch(smapsContent, -1)\n\t\tif len(allMatches) == 0 {\n\t\t\tklog.V(5).Infof(\"Not found any information about referenced bytes in %s file\", smapsFilePath)\n\t\t\tcontinue // referenced bytes may not exist in smaps file\n\t\t}\n\n\t\tfor _, matches := range allMatches {\n\t\t\tif len(matches) != 2 {\n\t\t\t\treturn 0, fmt.Errorf(\"failed to match regexp in output: %s\", string(smapsContent))\n\t\t\t}\n\t\t\tfoundMatch = true\n\t\t\treferenced, err := strconv.ParseUint(string(matches[1]), 10, 64)\n\t\t\tif err != nil {\n\t\t\t\treturn 0, err\n\t\t\t}\n\t\t\treferencedKBytes += referenced\n\t\t}\n\t}\n\n\tif len(pids) != 0 {\n\t\tif !readSmapsContent {\n\t\t\tklog.Warningf(\"Cannot read smaps files for any PID from %s\", \"CONTAINER\")\n\t\t} else if !foundMatch {\n\t\t\tklog.Warningf(\"Not found any information about referenced bytes in smaps files for any PID from %s\", \"CONTAINER\")\n\t\t}\n\t}\n\treturn referencedKBytes, nil\n}\n\nfunc clearReferencedBytes(pids []int, cycles uint64, resetInterval uint64) error {\n\tif resetInterval == 0 {\n\t\treturn nil\n\t}\n\n\tif cycles%resetInterval == 0 {\n\t\tfor _, pid := range pids {\n\t\t\tclearRefsFilePath := fmt.Sprintf(clearRefsFilePathPattern, pid)\n\t\t\tclerRefsFile, err := os.OpenFile(clearRefsFilePath, os.O_WRONLY, 0o644)\n\t\t\tif err != nil {\n\t\t\t\t// clear_refs file may not exist for all PIDs\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\t_, err = clerRefsFile.WriteString(\"1\\n\")\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\terr = clerRefsFile.Close()\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc networkStatsFromProc(rootFs string, pid int) ([]info.InterfaceStats, error) {\n\tnetStatsFile := path.Join(rootFs, \"proc\", strconv.Itoa(pid), \"/net/dev\")\n\n\tifaceStats, err := scanInterfaceStats(netStatsFile)\n\tif err != nil {\n\t\treturn []info.InterfaceStats{}, fmt.Errorf(\"couldn't read network stats: %v\", err)\n\t}\n\n\treturn ifaceStats, nil\n}\n\nvar ignoredDevicePrefixes = []string{\"lo\", \"veth\", \"docker\", \"nerdctl\"}\n\nfunc isIgnoredDevice(ifName string) bool {\n\tfor _, prefix := range ignoredDevicePrefixes {\n\t\tif strings.HasPrefix(strings.ToLower(ifName), prefix) {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\nfunc scanInterfaceStats(netStatsFile string) ([]info.InterfaceStats, error) {\n\tfile, err := os.Open(netStatsFile)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failure opening %s: %v\", netStatsFile, err)\n\t}\n\tdefer file.Close()\n\n\tscanner := bufio.NewScanner(file)\n\n\t// Discard header lines\n\tfor i := 0; i < 2; i++ {\n\t\tif b := scanner.Scan(); !b {\n\t\t\treturn nil, scanner.Err()\n\t\t}\n\t}\n\n\tstats := []info.InterfaceStats{}\n\tfor scanner.Scan() {\n\t\tline := scanner.Text()\n\t\tline = strings.Replace(line, \":\", \"\", -1)\n\n\t\tfields := strings.Fields(line)\n\t\t// If the format of the  line is invalid then don't trust any of the stats\n\t\t// in this file.\n\t\tif len(fields) != 17 {\n\t\t\treturn nil, fmt.Errorf(\"invalid interface stats line: %v\", line)\n\t\t}\n\n\t\tdevName := fields[0]\n\t\tif isIgnoredDevice(devName) {\n\t\t\tcontinue\n\t\t}\n\n\t\ti := info.InterfaceStats{\n\t\t\tName: devName,\n\t\t}\n\n\t\tstatFields := append(fields[1:5], fields[9:13]...)\n\t\tstatPointers := []*uint64{\n\t\t\t&i.RxBytes, &i.RxPackets, &i.RxErrors, &i.RxDropped,\n\t\t\t&i.TxBytes, &i.TxPackets, &i.TxErrors, &i.TxDropped,\n\t\t}\n\n\t\terr := setInterfaceStatValues(statFields, statPointers)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"cannot parse interface stats (%v): %v\", err, line)\n\t\t}\n\n\t\tstats = append(stats, i)\n\t}\n\n\treturn stats, nil\n}\n\nfunc setInterfaceStatValues(fields []string, pointers []*uint64) error {\n\tfor i, v := range fields {\n\t\tval, err := strconv.ParseUint(v, 10, 64)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\t*pointers[i] = val\n\t}\n\treturn nil\n}\n\nfunc tcpStatsFromProc(rootFs string, pid int, file string) (info.TcpStat, error) {\n\ttcpStatsFile := path.Join(rootFs, \"proc\", strconv.Itoa(pid), file)\n\n\ttcpStats, err := scanTCPStats(tcpStatsFile)\n\tif err != nil {\n\t\treturn tcpStats, fmt.Errorf(\"couldn't read tcp stats: %v\", err)\n\t}\n\n\treturn tcpStats, nil\n}\n\nfunc advancedTCPStatsFromProc(rootFs string, pid int, file1, file2 string) (info.TcpAdvancedStat, error) {\n\tvar advancedStats info.TcpAdvancedStat\n\tvar err error\n\n\tnetstatFile := path.Join(rootFs, \"proc\", strconv.Itoa(pid), file1)\n\terr = scanAdvancedTCPStats(&advancedStats, netstatFile)\n\tif err != nil {\n\t\treturn advancedStats, err\n\t}\n\n\tsnmpFile := path.Join(rootFs, \"proc\", strconv.Itoa(pid), file2)\n\terr = scanAdvancedTCPStats(&advancedStats, snmpFile)\n\tif err != nil {\n\t\treturn advancedStats, err\n\t}\n\n\treturn advancedStats, nil\n}\n\nfunc scanAdvancedTCPStats(advancedStats *info.TcpAdvancedStat, advancedTCPStatsFile string) error {\n\tdata, err := os.ReadFile(advancedTCPStatsFile)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failure opening %s: %v\", advancedTCPStatsFile, err)\n\t}\n\n\treader := strings.NewReader(string(data))\n\tscanner := bufio.NewScanner(reader)\n\tscanner.Split(bufio.ScanLines)\n\n\tadvancedTCPStats := make(map[string]interface{})\n\tfor scanner.Scan() {\n\t\tnameParts := strings.Split(scanner.Text(), \" \")\n\t\tscanner.Scan()\n\t\tvalueParts := strings.Split(scanner.Text(), \" \")\n\t\t// Remove trailing :. and ignore non-tcp\n\t\tprotocol := nameParts[0][:len(nameParts[0])-1]\n\t\tif protocol != \"TcpExt\" && protocol != \"Tcp\" {\n\t\t\tcontinue\n\t\t}\n\t\tif len(nameParts) != len(valueParts) {\n\t\t\treturn fmt.Errorf(\"mismatch field count mismatch in %s: %s\",\n\t\t\t\tadvancedTCPStatsFile, protocol)\n\t\t}\n\t\tfor i := 1; i < len(nameParts); i++ {\n\t\t\tif strings.Contains(valueParts[i], \"-\") {\n\t\t\t\tvInt64, err := strconv.ParseInt(valueParts[i], 10, 64)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn fmt.Errorf(\"decode value: %s to int64 error: %s\", valueParts[i], err)\n\t\t\t\t}\n\t\t\t\tadvancedTCPStats[nameParts[i]] = vInt64\n\t\t\t} else {\n\t\t\t\tvUint64, err := strconv.ParseUint(valueParts[i], 10, 64)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn fmt.Errorf(\"decode value: %s to uint64 error: %s\", valueParts[i], err)\n\t\t\t\t}\n\t\t\t\tadvancedTCPStats[nameParts[i]] = vUint64\n\t\t\t}\n\t\t}\n\t}\n\n\tb, err := json.Marshal(advancedTCPStats)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\terr = json.Unmarshal(b, advancedStats)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\treturn scanner.Err()\n}\n\nfunc scanTCPStats(tcpStatsFile string) (info.TcpStat, error) {\n\tvar stats info.TcpStat\n\n\tdata, err := os.ReadFile(tcpStatsFile)\n\tif err != nil {\n\t\treturn stats, fmt.Errorf(\"failure opening %s: %v\", tcpStatsFile, err)\n\t}\n\n\ttcpStateMap := map[string]uint64{\n\t\t\"01\": 0, // ESTABLISHED\n\t\t\"02\": 0, // SYN_SENT\n\t\t\"03\": 0, // SYN_RECV\n\t\t\"04\": 0, // FIN_WAIT1\n\t\t\"05\": 0, // FIN_WAIT2\n\t\t\"06\": 0, // TIME_WAIT\n\t\t\"07\": 0, // CLOSE\n\t\t\"08\": 0, // CLOSE_WAIT\n\t\t\"09\": 0, // LAST_ACK\n\t\t\"0A\": 0, // LISTEN\n\t\t\"0B\": 0, // CLOSING\n\t}\n\n\treader := strings.NewReader(string(data))\n\tscanner := bufio.NewScanner(reader)\n\n\tscanner.Split(bufio.ScanLines)\n\n\t// Discard header line\n\tif b := scanner.Scan(); !b {\n\t\treturn stats, scanner.Err()\n\t}\n\n\tfor scanner.Scan() {\n\t\tline := scanner.Text()\n\n\t\tstate := strings.Fields(line)\n\t\t// TCP state is the 4th field.\n\t\t// Format: sl local_address rem_address st tx_queue rx_queue tr tm->when retrnsmt  uid timeout inode\n\t\ttcpState := state[3]\n\t\t_, ok := tcpStateMap[tcpState]\n\t\tif !ok {\n\t\t\treturn stats, fmt.Errorf(\"invalid TCP stats line: %v\", line)\n\t\t}\n\t\ttcpStateMap[tcpState]++\n\t}\n\n\tstats = info.TcpStat{\n\t\tEstablished: tcpStateMap[\"01\"],\n\t\tSynSent:     tcpStateMap[\"02\"],\n\t\tSynRecv:     tcpStateMap[\"03\"],\n\t\tFinWait1:    tcpStateMap[\"04\"],\n\t\tFinWait2:    tcpStateMap[\"05\"],\n\t\tTimeWait:    tcpStateMap[\"06\"],\n\t\tClose:       tcpStateMap[\"07\"],\n\t\tCloseWait:   tcpStateMap[\"08\"],\n\t\tLastAck:     tcpStateMap[\"09\"],\n\t\tListen:      tcpStateMap[\"0A\"],\n\t\tClosing:     tcpStateMap[\"0B\"],\n\t}\n\n\treturn stats, nil\n}\n\nfunc udpStatsFromProc(rootFs string, pid int, file string) (info.UdpStat, error) {\n\tvar err error\n\tvar udpStats info.UdpStat\n\n\tudpStatsFile := path.Join(rootFs, \"proc\", strconv.Itoa(pid), file)\n\n\tr, err := os.Open(udpStatsFile)\n\tif err != nil {\n\t\treturn udpStats, fmt.Errorf(\"failure opening %s: %v\", udpStatsFile, err)\n\t}\n\n\tudpStats, err = scanUDPStats(r)\n\tif err != nil {\n\t\treturn udpStats, fmt.Errorf(\"couldn't read udp stats: %v\", err)\n\t}\n\n\treturn udpStats, nil\n}\n\nfunc scanUDPStats(r io.Reader) (info.UdpStat, error) {\n\tvar stats info.UdpStat\n\n\tscanner := bufio.NewScanner(r)\n\tscanner.Split(bufio.ScanLines)\n\n\t// Discard header line\n\tif b := scanner.Scan(); !b {\n\t\treturn stats, scanner.Err()\n\t}\n\n\tvar listening, dropped, rxQueued, txQueued uint64\n\n\tfor scanner.Scan() {\n\t\tline := scanner.Text()\n\t\t// Format: sl local_address rem_address st tx_queue rx_queue tr tm->when retrnsmt  uid timeout inode ref pointer drops\n\n\t\tlistening++\n\n\t\tfs := strings.Fields(line)\n\t\tif len(fs) != 13 {\n\t\t\tcontinue\n\t\t}\n\n\t\tvar rx, tx uint64\n\t\t_, err := fmt.Sscanf(fs[4], \"%X:%X\", &rx, &tx)\n\t\tif err != nil {\n\t\t\tcontinue\n\t\t}\n\t\trxQueued += rx\n\t\ttxQueued += tx\n\n\t\td, err := strconv.Atoi(string(fs[12]))\n\t\tif err != nil {\n\t\t\tcontinue\n\t\t}\n\t\tdropped += uint64(d)\n\t}\n\n\tstats = info.UdpStat{\n\t\tListen:   listening,\n\t\tDropped:  dropped,\n\t\tRxQueued: rxQueued,\n\t\tTxQueued: txQueued,\n\t}\n\n\treturn stats, nil\n}\n\nfunc (h *Handler) GetProcesses() ([]int, error) {\n\tpids, err := h.cgroupManager.GetPids()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn pids, nil\n}\n\n// Convert libcontainer stats to info.ContainerStats.\nfunc setCPUStats(s *cgroups.Stats, ret *info.ContainerStats, withPerCPU bool) {\n\tret.Cpu.Usage.User = s.CpuStats.CpuUsage.UsageInUsermode\n\tret.Cpu.Usage.System = s.CpuStats.CpuUsage.UsageInKernelmode\n\tret.Cpu.Usage.Total = s.CpuStats.CpuUsage.TotalUsage\n\tret.Cpu.CFS.Periods = s.CpuStats.ThrottlingData.Periods\n\tret.Cpu.CFS.ThrottledPeriods = s.CpuStats.ThrottlingData.ThrottledPeriods\n\tret.Cpu.CFS.ThrottledTime = s.CpuStats.ThrottlingData.ThrottledTime\n\tret.Cpu.CFS.BurstsPeriods = s.CpuStats.BurstData.BurstsPeriods\n\tret.Cpu.CFS.BurstTime = s.CpuStats.BurstData.BurstTime\n\tsetPSIStats(s.CpuStats.PSI, &ret.Cpu.PSI)\n\n\tif !withPerCPU {\n\t\treturn\n\t}\n\tif len(s.CpuStats.CpuUsage.PercpuUsage) == 0 {\n\t\t// libcontainer's 'GetStats' can leave 'PercpuUsage' nil if it skipped the\n\t\t// cpuacct subsystem.\n\t\treturn\n\t}\n\tret.Cpu.Usage.PerCpu = s.CpuStats.CpuUsage.PercpuUsage\n}\n\nfunc setDiskIoStats(s *cgroups.Stats, ret *info.ContainerStats) {\n\tret.DiskIo.IoServiceBytes = diskStatsCopy(s.BlkioStats.IoServiceBytesRecursive)\n\tret.DiskIo.IoServiced = diskStatsCopy(s.BlkioStats.IoServicedRecursive)\n\tret.DiskIo.IoQueued = diskStatsCopy(s.BlkioStats.IoQueuedRecursive)\n\tret.DiskIo.Sectors = diskStatsCopy(s.BlkioStats.SectorsRecursive)\n\tret.DiskIo.IoServiceTime = diskStatsCopy(s.BlkioStats.IoServiceTimeRecursive)\n\tret.DiskIo.IoWaitTime = diskStatsCopy(s.BlkioStats.IoWaitTimeRecursive)\n\tret.DiskIo.IoMerged = diskStatsCopy(s.BlkioStats.IoMergedRecursive)\n\tret.DiskIo.IoTime = diskStatsCopy(s.BlkioStats.IoTimeRecursive)\n\tret.DiskIo.IoCostUsage = diskStatsCopy(s.BlkioStats.IoCostUsage)\n\tret.DiskIo.IoCostWait = diskStatsCopy(s.BlkioStats.IoCostWait)\n\tret.DiskIo.IoCostIndebt = diskStatsCopy(s.BlkioStats.IoCostIndebt)\n\tret.DiskIo.IoCostIndelay = diskStatsCopy(s.BlkioStats.IoCostIndelay)\n\tsetPSIStats(s.BlkioStats.PSI, &ret.DiskIo.PSI)\n}\n\nfunc setMemoryStats(s *cgroups.Stats, ret *info.ContainerStats) {\n\tret.Memory.Usage = s.MemoryStats.Usage.Usage\n\tret.Memory.MaxUsage = s.MemoryStats.Usage.MaxUsage\n\tret.Memory.Failcnt = s.MemoryStats.Usage.Failcnt\n\tret.Memory.KernelUsage = s.MemoryStats.KernelUsage.Usage\n\tsetPSIStats(s.MemoryStats.PSI, &ret.Memory.PSI)\n\n\tif cgroups.IsCgroup2UnifiedMode() {\n\t\tret.Memory.Cache = s.MemoryStats.Stats[\"file\"]\n\t\tret.Memory.RSS = s.MemoryStats.Stats[\"anon\"]\n\t\tret.Memory.Swap = s.MemoryStats.SwapUsage.Usage - s.MemoryStats.Usage.Usage\n\t\tret.Memory.MappedFile = s.MemoryStats.Stats[\"file_mapped\"]\n\t} else if s.MemoryStats.UseHierarchy {\n\t\tret.Memory.Cache = s.MemoryStats.Stats[\"total_cache\"]\n\t\tret.Memory.RSS = s.MemoryStats.Stats[\"total_rss\"]\n\t\tret.Memory.Swap = s.MemoryStats.Stats[\"total_swap\"]\n\t\tret.Memory.MappedFile = s.MemoryStats.Stats[\"total_mapped_file\"]\n\t} else {\n\t\tret.Memory.Cache = s.MemoryStats.Stats[\"cache\"]\n\t\tret.Memory.RSS = s.MemoryStats.Stats[\"rss\"]\n\t\tret.Memory.Swap = s.MemoryStats.Stats[\"swap\"]\n\t\tret.Memory.MappedFile = s.MemoryStats.Stats[\"mapped_file\"]\n\t}\n\tif v, ok := s.MemoryStats.Stats[\"pgfault\"]; ok {\n\t\tret.Memory.ContainerData.Pgfault = v\n\t\tret.Memory.HierarchicalData.Pgfault = v\n\t}\n\tif v, ok := s.MemoryStats.Stats[\"pgmajfault\"]; ok {\n\t\tret.Memory.ContainerData.Pgmajfault = v\n\t\tret.Memory.HierarchicalData.Pgmajfault = v\n\t}\n\n\tinactiveFileKeyName := \"total_inactive_file\"\n\tif cgroups.IsCgroup2UnifiedMode() {\n\t\tinactiveFileKeyName = \"inactive_file\"\n\t}\n\n\tactiveFileKeyName := \"total_active_file\"\n\tif cgroups.IsCgroup2UnifiedMode() {\n\t\tactiveFileKeyName = \"active_file\"\n\t}\n\n\tif v, ok := s.MemoryStats.Stats[activeFileKeyName]; ok {\n\t\tret.Memory.TotalActiveFile = v\n\t}\n\n\tworkingSet := ret.Memory.Usage\n\tif v, ok := s.MemoryStats.Stats[inactiveFileKeyName]; ok {\n\t\tret.Memory.TotalInactiveFile = v\n\t\tif workingSet < v {\n\t\t\tworkingSet = 0\n\t\t} else {\n\t\t\tworkingSet -= v\n\t\t}\n\t}\n\tret.Memory.WorkingSet = workingSet\n}\n\nfunc setCPUSetStats(s *cgroups.Stats, ret *info.ContainerStats) {\n\tret.CpuSet.MemoryMigrate = s.CPUSetStats.MemoryMigrate\n}\n\nfunc getNumaStats(memoryStats map[uint8]uint64) map[uint8]uint64 {\n\tstats := make(map[uint8]uint64, len(memoryStats))\n\tfor node, usage := range memoryStats {\n\t\tstats[node] = usage\n\t}\n\treturn stats\n}\n\nfunc setMemoryNumaStats(s *cgroups.Stats, ret *info.ContainerStats) {\n\tret.Memory.ContainerData.NumaStats.File = getNumaStats(s.MemoryStats.PageUsageByNUMA.File.Nodes)\n\tret.Memory.ContainerData.NumaStats.Anon = getNumaStats(s.MemoryStats.PageUsageByNUMA.Anon.Nodes)\n\tret.Memory.ContainerData.NumaStats.Unevictable = getNumaStats(s.MemoryStats.PageUsageByNUMA.Unevictable.Nodes)\n\n\tret.Memory.HierarchicalData.NumaStats.File = getNumaStats(s.MemoryStats.PageUsageByNUMA.Hierarchical.File.Nodes)\n\tret.Memory.HierarchicalData.NumaStats.Anon = getNumaStats(s.MemoryStats.PageUsageByNUMA.Hierarchical.Anon.Nodes)\n\tret.Memory.HierarchicalData.NumaStats.Unevictable = getNumaStats(s.MemoryStats.PageUsageByNUMA.Hierarchical.Unevictable.Nodes)\n}\n\nfunc setHugepageStats(s *cgroups.Stats, ret *info.ContainerStats) {\n\tret.Hugetlb = make(map[string]info.HugetlbStats)\n\tfor k, v := range s.HugetlbStats {\n\t\tret.Hugetlb[k] = info.HugetlbStats{\n\t\t\tUsage:    v.Usage,\n\t\t\tMaxUsage: v.MaxUsage,\n\t\t\tFailcnt:  v.Failcnt,\n\t\t}\n\t}\n}\n\nfunc setPSIData(d *cgroups.PSIData, ret *info.PSIData) {\n\tif d != nil {\n\t\tret.Total = d.Total\n\t\tret.Avg10 = d.Avg10\n\t\tret.Avg60 = d.Avg60\n\t\tret.Avg300 = d.Avg300\n\t}\n}\n\nfunc setPSIStats(s *cgroups.PSIStats, ret *info.PSIStats) {\n\tif s != nil {\n\t\tsetPSIData(&s.Full, &ret.Full)\n\t\tsetPSIData(&s.Some, &ret.Some)\n\t}\n}\n\n// read from pids path not cpu\nfunc setThreadsStats(s *cgroups.Stats, ret *info.ContainerStats) {\n\tif s != nil {\n\t\tret.Processes.ThreadsCurrent = s.PidsStats.Current\n\t\tret.Processes.ThreadsMax = s.PidsStats.Limit\n\t}\n}\n\nfunc newContainerStats(cgroupStats *cgroups.Stats, includedMetrics container.MetricSet) *info.ContainerStats {\n\tret := &info.ContainerStats{\n\t\tTimestamp: time.Now(),\n\t}\n\n\tif s := cgroupStats; s != nil {\n\t\tsetCPUStats(s, ret, includedMetrics.Has(container.PerCpuUsageMetrics))\n\t\tif includedMetrics.Has(container.DiskIOMetrics) {\n\t\t\tsetDiskIoStats(s, ret)\n\t\t}\n\t\tsetMemoryStats(s, ret)\n\t\tif includedMetrics.Has(container.MemoryNumaMetrics) {\n\t\t\tsetMemoryNumaStats(s, ret)\n\t\t}\n\t\tif includedMetrics.Has(container.HugetlbUsageMetrics) {\n\t\t\tsetHugepageStats(s, ret)\n\t\t}\n\t\tif includedMetrics.Has(container.CPUSetMetrics) {\n\t\t\tsetCPUSetStats(s, ret)\n\t\t}\n\t}\n\treturn ret\n}\n"
  },
  {
    "path": "container/libcontainer/handler_test.go",
    "content": "// Copyright 2018 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n//go:build linux\n\npackage libcontainer\n\nimport (\n\t\"os\"\n\t\"reflect\"\n\t\"testing\"\n\n\t\"github.com/opencontainers/cgroups\"\n\t\"github.com/stretchr/testify/assert\"\n\n\tinfo \"github.com/google/cadvisor/info/v1\"\n)\n\nfunc TestScanInterfaceStats(t *testing.T) {\n\tstats, err := scanInterfaceStats(\"testdata/procnetdev\")\n\tif err != nil {\n\t\tt.Error(err)\n\t}\n\n\tnetdevstats := []info.InterfaceStats{\n\t\t{\n\t\t\tName:      \"wlp4s0\",\n\t\t\tRxBytes:   1,\n\t\t\tRxPackets: 2,\n\t\t\tRxErrors:  3,\n\t\t\tRxDropped: 4,\n\t\t\tTxBytes:   9,\n\t\t\tTxPackets: 10,\n\t\t\tTxErrors:  11,\n\t\t\tTxDropped: 12,\n\t\t},\n\t\t{\n\t\t\tName:      \"em1\",\n\t\t\tRxBytes:   315849,\n\t\t\tRxPackets: 1172,\n\t\t\tRxErrors:  0,\n\t\t\tRxDropped: 0,\n\t\t\tTxBytes:   315850,\n\t\t\tTxPackets: 1173,\n\t\t\tTxErrors:  0,\n\t\t\tTxDropped: 0,\n\t\t},\n\t}\n\n\tif len(stats) != len(netdevstats) {\n\t\tt.Errorf(\"Expected 2 net stats, got %d\", len(stats))\n\t}\n\n\tfor i, v := range netdevstats {\n\t\tif v != stats[i] {\n\t\t\tt.Errorf(\"Expected %#v, got %#v\", v, stats[i])\n\t\t}\n\t}\n}\n\nfunc TestScanUDPStats(t *testing.T) {\n\tudpStatsFile := \"testdata/procnetudp\"\n\tr, err := os.Open(udpStatsFile)\n\tif err != nil {\n\t\tt.Errorf(\"failure opening %s: %v\", udpStatsFile, err)\n\t}\n\n\tstats, err := scanUDPStats(r)\n\tif err != nil {\n\t\tt.Error(err)\n\t}\n\n\tudpstats := info.UdpStat{\n\t\tListen:   2,\n\t\tDropped:  4,\n\t\tRxQueued: 10,\n\t\tTxQueued: 11,\n\t}\n\n\tif stats != udpstats {\n\t\tt.Errorf(\"Expected %#v, got %#v\", udpstats, stats)\n\t}\n}\n\n// https://github.com/docker/libcontainer/blob/v2.2.1/cgroups/fs/cpuacct.go#L19\nconst nanosecondsInSeconds = 1000000000\n\n// https://github.com/containerd/cgroups/pull/12\nconst clockTicks = 100\n\nfunc TestSetCPUStats(t *testing.T) {\n\tperCPUUsage := make([]uint64, 31)\n\tfor i := uint32(0); i < 31; i++ {\n\t\tperCPUUsage[i] = 8562955455524\n\t}\n\ts := &cgroups.Stats{\n\t\tCpuStats: cgroups.CpuStats{\n\t\t\tCpuUsage: cgroups.CpuUsage{\n\t\t\t\tPercpuUsage:       perCPUUsage,\n\t\t\t\tTotalUsage:        33802947350272,\n\t\t\t\tUsageInKernelmode: 734746 * nanosecondsInSeconds / clockTicks,\n\t\t\t\tUsageInUsermode:   2767637 * nanosecondsInSeconds / clockTicks,\n\t\t\t},\n\t\t\tPSI: &cgroups.PSIStats{\n\t\t\t\tFull: cgroups.PSIData{\n\t\t\t\t\tAvg10:  0.3,\n\t\t\t\t\tAvg60:  0.2,\n\t\t\t\t\tAvg300: 0.1,\n\t\t\t\t\tTotal:  100,\n\t\t\t\t},\n\t\t\t\tSome: cgroups.PSIData{\n\t\t\t\t\tAvg10:  0.6,\n\t\t\t\t\tAvg60:  0.4,\n\t\t\t\t\tAvg300: 0.2,\n\t\t\t\t\tTotal:  200,\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\tvar ret info.ContainerStats\n\tsetCPUStats(s, &ret, true)\n\n\texpected := info.ContainerStats{\n\t\tCpu: info.CpuStats{\n\t\t\tUsage: info.CpuUsage{\n\t\t\t\tPerCpu: perCPUUsage,\n\t\t\t\tUser:   s.CpuStats.CpuUsage.UsageInUsermode,\n\t\t\t\tSystem: s.CpuStats.CpuUsage.UsageInKernelmode,\n\t\t\t\tTotal:  33802947350272,\n\t\t\t},\n\t\t\tPSI: info.PSIStats{\n\t\t\t\tFull: info.PSIData{\n\t\t\t\t\tAvg10:  0.3,\n\t\t\t\t\tAvg60:  0.2,\n\t\t\t\t\tAvg300: 0.1,\n\t\t\t\t\tTotal:  100,\n\t\t\t\t},\n\t\t\t\tSome: info.PSIData{\n\t\t\t\t\tAvg10:  0.6,\n\t\t\t\t\tAvg60:  0.4,\n\t\t\t\t\tAvg300: 0.2,\n\t\t\t\t\tTotal:  200,\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\n\tif !ret.Eq(&expected) {\n\t\tt.Fatalf(\"expected %+v == %+v\", ret, expected)\n\t}\n}\n\nfunc TestSetProcessesStats(t *testing.T) {\n\tret := info.ContainerStats{\n\t\tProcesses: info.ProcessStats{\n\t\t\tProcessCount: 1,\n\t\t\tFdCount:      2,\n\t\t},\n\t}\n\ts := &cgroups.Stats{\n\t\tPidsStats: cgroups.PidsStats{\n\t\t\tCurrent: 5,\n\t\t\tLimit:   100,\n\t\t},\n\t}\n\tsetThreadsStats(s, &ret)\n\n\texpected := info.ContainerStats{\n\n\t\tProcesses: info.ProcessStats{\n\t\t\tProcessCount:   1,\n\t\t\tFdCount:        2,\n\t\t\tThreadsCurrent: s.PidsStats.Current,\n\t\t\tThreadsMax:     s.PidsStats.Limit,\n\t\t},\n\t}\n\n\tif expected.Processes.ProcessCount != ret.Processes.ProcessCount {\n\t\tt.Fatalf(\"expected ProcessCount: %d == %d\", ret.Processes.ProcessCount, expected.Processes.ProcessCount)\n\t}\n\tif expected.Processes.FdCount != ret.Processes.FdCount {\n\t\tt.Fatalf(\"expected FdCount: %d == %d\", ret.Processes.FdCount, expected.Processes.FdCount)\n\t}\n\n\tif expected.Processes.ThreadsCurrent != ret.Processes.ThreadsCurrent {\n\t\tt.Fatalf(\"expected current threads: %d == %d\", ret.Processes.ThreadsCurrent, expected.Processes.ThreadsCurrent)\n\t}\n\tif expected.Processes.ThreadsMax != ret.Processes.ThreadsMax {\n\t\tt.Fatalf(\"expected max threads: %d == %d\", ret.Processes.ThreadsMax, expected.Processes.ThreadsMax)\n\t}\n}\n\nfunc TestParseLimitsFile(t *testing.T) {\n\ttestData := []struct {\n\t\tlimitLine string\n\t\texpected  []info.UlimitSpec\n\t}{\n\t\t{\n\t\t\t\"Limit                     Soft Limit           Hard Limit           Units   \\n\",\n\t\t\t[]info.UlimitSpec{},\n\t\t},\n\t\t{\n\t\t\t\"Max open files            8192                 8192                 files   \\n\",\n\t\t\t[]info.UlimitSpec{{Name: \"max_open_files\", SoftLimit: 8192, HardLimit: 8192}},\n\t\t},\n\t\t{\n\t\t\t\"Max open files            85899345920          85899345920          files   \\n\",\n\t\t\t[]info.UlimitSpec{{Name: \"max_open_files\", SoftLimit: 85899345920, HardLimit: 85899345920}},\n\t\t},\n\t\t{\n\t\t\t\"Max open files            gibberish1           8192                 files   \\n\",\n\t\t\t[]info.UlimitSpec{},\n\t\t},\n\t\t{\n\t\t\t\"Max open files            8192                 0xbaddata            files   \\n\",\n\t\t\t[]info.UlimitSpec{},\n\t\t},\n\t\t{\n\t\t\t\"Max stack size            8192                 8192                 files   \\n\",\n\t\t\t[]info.UlimitSpec{},\n\t\t},\n\t}\n\n\tfor _, testItem := range testData {\n\t\tactual := processLimitsFile(testItem.limitLine)\n\t\tif reflect.DeepEqual(actual, testItem.expected) == false {\n\t\t\tt.Fatalf(\"Parsed ulimit doesn't match expected values for line: %s\", testItem.limitLine)\n\t\t}\n\t}\n}\n\nfunc TestReferencedBytesStat(t *testing.T) {\n\t// overwrite package variables\n\tsmapsFilePathPattern = \"testdata/smaps%d\"\n\tclearRefsFilePathPattern = \"testdata/clear_refs%d\"\n\n\tpids := []int{4, 6, 8}\n\tstat, err := referencedBytesStat(pids, 1, 3)\n\tassert.Nil(t, err)\n\tassert.Equal(t, uint64(416*1024), stat)\n\n\tclearRefsFiles := []string{\n\t\t\"testdata/clear_refs4\",\n\t\t\"testdata/clear_refs6\",\n\t\t\"testdata/clear_refs8\",\n\t}\n\n\t// check if clear_refs files have proper values\n\tassert.Equal(t, \"0\\n\", getFileContent(t, clearRefsFiles[0]))\n\tassert.Equal(t, \"0\\n\", getFileContent(t, clearRefsFiles[1]))\n\tassert.Equal(t, \"0\\n\", getFileContent(t, clearRefsFiles[2]))\n}\n\nfunc TestReferencedBytesStatWhenNeverCleared(t *testing.T) {\n\t// overwrite package variables\n\tsmapsFilePathPattern = \"testdata/smaps%d\"\n\tclearRefsFilePathPattern = \"testdata/clear_refs%d\"\n\n\tpids := []int{4, 6, 8}\n\tstat, err := referencedBytesStat(pids, 1, 0)\n\tassert.Nil(t, err)\n\tassert.Equal(t, uint64(416*1024), stat)\n\n\tclearRefsFiles := []string{\n\t\t\"testdata/clear_refs4\",\n\t\t\"testdata/clear_refs6\",\n\t\t\"testdata/clear_refs8\",\n\t}\n\n\t// check if clear_refs files have proper values\n\tassert.Equal(t, \"0\\n\", getFileContent(t, clearRefsFiles[0]))\n\tassert.Equal(t, \"0\\n\", getFileContent(t, clearRefsFiles[1]))\n\tassert.Equal(t, \"0\\n\", getFileContent(t, clearRefsFiles[2]))\n}\n\nfunc TestReferencedBytesStatWhenResetIsNeeded(t *testing.T) {\n\t// overwrite package variables\n\tsmapsFilePathPattern = \"testdata/smaps%d\"\n\tclearRefsFilePathPattern = \"testdata/clear_refs%d\"\n\n\tpids := []int{4, 6, 8}\n\tstat, err := referencedBytesStat(pids, 1, 1)\n\tassert.Nil(t, err)\n\tassert.Equal(t, uint64(416*1024), stat)\n\n\tclearRefsFiles := []string{\n\t\t\"testdata/clear_refs4\",\n\t\t\"testdata/clear_refs6\",\n\t\t\"testdata/clear_refs8\",\n\t}\n\n\t// check if clear_refs files have proper values\n\tassert.Equal(t, \"1\\n\", getFileContent(t, clearRefsFiles[0]))\n\tassert.Equal(t, \"1\\n\", getFileContent(t, clearRefsFiles[1]))\n\tassert.Equal(t, \"1\\n\", getFileContent(t, clearRefsFiles[2]))\n\n\tclearTestData(t, clearRefsFiles)\n}\n\nfunc TestGetReferencedKBytesWhenSmapsMissing(t *testing.T) {\n\t// overwrite package variable\n\tsmapsFilePathPattern = \"testdata/smaps%d\"\n\n\tpids := []int{10}\n\treferenced, err := getReferencedKBytes(pids)\n\tassert.Nil(t, err)\n\tassert.Equal(t, uint64(0), referenced)\n}\n\nfunc TestClearReferencedBytesWhenClearRefsMissing(t *testing.T) {\n\t// overwrite package variable\n\tclearRefsFilePathPattern = \"testdata/clear_refs%d\"\n\n\tpids := []int{10}\n\terr := clearReferencedBytes(pids, 0, 1)\n\tassert.Nil(t, err)\n}\n\nvar ulimits []info.UlimitSpec\n\nfunc BenchmarkProcessLimitsFile(b *testing.B) {\n\tcontent, err := os.ReadFile(\"testdata/limits\")\n\tassert.Nil(b, err)\n\n\tb.ResetTimer()\n\tfor i := 0; i < b.N; i++ {\n\t\tulimits = processLimitsFile(string(content))\n\t}\n\n\t// Ensure the compiler doesn't optimize away the benchmark\n\t_ = ulimits\n}\n\nfunc TestProcessMaxOpenFileLimitLine(t *testing.T) {\n\tline := \"            1073741816           1073741816           files     \"\n\n\tulimit, err := processMaxOpenFileLimitLine(\"max_open_files\", line)\n\tassert.Nil(t, err)\n\tassert.Equal(t, \"max_open_files\", ulimit.Name)\n\tassert.Equal(t, int64(1073741816), ulimit.SoftLimit)\n\tassert.Equal(t, int64(1073741816), ulimit.HardLimit)\n}\n"
  },
  {
    "path": "container/libcontainer/helpers.go",
    "content": "// Copyright 2014 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n//go:build linux\n\npackage libcontainer\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/google/cadvisor/container\"\n\tinfo \"github.com/google/cadvisor/info/v1\"\n\n\t\"github.com/opencontainers/cgroups\"\n\tfs \"github.com/opencontainers/cgroups/fs\"\n\tfs2 \"github.com/opencontainers/cgroups/fs2\"\n\t\"k8s.io/klog/v2\"\n)\n\n// GetCgroupSubsystems returns information about the cgroup subsystems that are\n// of interest as a map of cgroup controllers to their mount points.\n// For example, \"cpu\" -> \"/sys/fs/cgroup/cpu\".\n//\n// The incudeMetrics arguments specifies which metrics are requested,\n// and is used to filter out some cgroups and their mounts. If nil,\n// all supported cgroup subsystems are included.\n//\n// For cgroup v2, includedMetrics argument is unused, the only map key is \"\"\n// (empty string), and the value is the unified cgroup mount point.\nfunc GetCgroupSubsystems(includedMetrics container.MetricSet) (map[string]string, error) {\n\tif cgroups.IsCgroup2UnifiedMode() {\n\t\treturn map[string]string{\"\": fs2.UnifiedMountpoint}, nil\n\t}\n\t// Get all cgroup mounts.\n\tallCgroups, err := cgroups.GetCgroupMounts(true)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn getCgroupSubsystemsHelper(allCgroups, includedMetrics)\n}\n\nfunc getCgroupSubsystemsHelper(allCgroups []cgroups.Mount, includedMetrics container.MetricSet) (map[string]string, error) {\n\tif len(allCgroups) == 0 {\n\t\treturn nil, fmt.Errorf(\"failed to find cgroup mounts\")\n\t}\n\n\t// Trim the mounts to only the subsystems we care about.\n\tmountPoints := make(map[string]string, len(allCgroups))\n\tfor _, mount := range allCgroups {\n\t\tfor _, subsystem := range mount.Subsystems {\n\t\t\tif !needSubsys(subsystem, includedMetrics) {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif _, ok := mountPoints[subsystem]; ok {\n\t\t\t\t// duplicate mount for this subsystem; use the first one we saw\n\t\t\t\tklog.V(5).Infof(\"skipping %s, already using mount at %s\", mount.Mountpoint, mountPoints[subsystem])\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tmountPoints[subsystem] = mount.Mountpoint\n\t\t}\n\t}\n\n\treturn mountPoints, nil\n}\n\n// A map of cgroup subsystems we support listing (should be the minimal set\n// we need stats from) to a respective MetricKind.\nvar supportedSubsystems = map[string]container.MetricKind{\n\t\"cpu\":        container.CpuUsageMetrics,\n\t\"cpuacct\":    container.CpuUsageMetrics,\n\t\"memory\":     container.MemoryUsageMetrics,\n\t\"hugetlb\":    container.HugetlbUsageMetrics,\n\t\"pids\":       container.ProcessMetrics,\n\t\"cpuset\":     container.CPUSetMetrics,\n\t\"blkio\":      container.DiskIOMetrics,\n\t\"io\":         container.DiskIOMetrics,\n\t\"devices\":    \"\",\n\t\"perf_event\": container.PerfMetrics,\n}\n\n// Check if this cgroup subsystem/controller is of use.\nfunc needSubsys(name string, metrics container.MetricSet) bool {\n\t// Check if supported.\n\tmetric, supported := supportedSubsystems[name]\n\tif !supported {\n\t\treturn false\n\t}\n\t// Check if needed.\n\tif metrics == nil || metric == \"\" {\n\t\treturn true\n\t}\n\n\treturn metrics.Has(metric)\n}\n\nfunc diskStatsCopy0(major, minor uint64) *info.PerDiskStats {\n\tdisk := info.PerDiskStats{\n\t\tMajor: major,\n\t\tMinor: minor,\n\t}\n\tdisk.Stats = make(map[string]uint64)\n\treturn &disk\n}\n\ntype diskKey struct {\n\tMajor uint64\n\tMinor uint64\n}\n\nfunc diskStatsCopy1(diskStat map[diskKey]*info.PerDiskStats) []info.PerDiskStats {\n\ti := 0\n\tstat := make([]info.PerDiskStats, len(diskStat))\n\tfor _, disk := range diskStat {\n\t\tstat[i] = *disk\n\t\ti++\n\t}\n\treturn stat\n}\n\nfunc diskStatsCopy(blkioStats []cgroups.BlkioStatEntry) (stat []info.PerDiskStats) {\n\tif len(blkioStats) == 0 {\n\t\treturn\n\t}\n\tdiskStat := make(map[diskKey]*info.PerDiskStats)\n\tfor i := range blkioStats {\n\t\tmajor := blkioStats[i].Major\n\t\tminor := blkioStats[i].Minor\n\t\tkey := diskKey{\n\t\t\tMajor: major,\n\t\t\tMinor: minor,\n\t\t}\n\t\tdiskp, ok := diskStat[key]\n\t\tif !ok {\n\t\t\tdiskp = diskStatsCopy0(major, minor)\n\t\t\tdiskStat[key] = diskp\n\t\t}\n\t\top := blkioStats[i].Op\n\t\tif op == \"\" {\n\t\t\top = \"Count\"\n\t\t}\n\t\tdiskp.Stats[op] = blkioStats[i].Value\n\t}\n\treturn diskStatsCopy1(diskStat)\n}\n\nfunc NewCgroupManager(name string, paths map[string]string) (cgroups.Manager, error) {\n\tconfig := &cgroups.Cgroup{\n\t\tName:      name,\n\t\tResources: &cgroups.Resources{},\n\t}\n\tif cgroups.IsCgroup2UnifiedMode() {\n\t\tpath := paths[\"\"]\n\t\treturn fs2.NewManager(config, path)\n\t}\n\n\treturn fs.NewManager(config, paths)\n}\n"
  },
  {
    "path": "container/libcontainer/helpers_test.go",
    "content": "// Copyright 2014 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n//go:build linux\n\npackage libcontainer\n\nimport (\n\t\"os\"\n\t\"path/filepath\"\n\t\"reflect\"\n\t\"strings\"\n\t\"testing\"\n\n\t\"github.com/opencontainers/cgroups\"\n\t\"github.com/stretchr/testify/assert\"\n)\n\nvar defaultCgroupSubsystems = []string{\n\t\"systemd\", \"freezer\", \"memory\", \"blkio\", \"hugetlb\", \"net_cls,net_prio\", \"pids\", \"cpu,cpuacct\", \"devices\", \"cpuset\", \"perf_events\",\n}\n\nfunc cgroupMountsAt(path string, subsystems []string) []cgroups.Mount {\n\tres := []cgroups.Mount{}\n\tfor _, subsystem := range subsystems {\n\t\tres = append(res, cgroups.Mount{\n\t\t\tRoot:       \"/\",\n\t\t\tSubsystems: strings.Split(subsystem, \",\"),\n\t\t\tMountpoint: filepath.Join(path, subsystem),\n\t\t})\n\t}\n\treturn res\n}\n\nfunc TestGetCgroupSubsystems(t *testing.T) {\n\ttestCases := []struct {\n\t\tmounts   []cgroups.Mount\n\t\texpected map[string]string\n\t\terr      bool\n\t}{\n\t\t{\n\t\t\tmounts: []cgroups.Mount{},\n\t\t\terr:    true,\n\t\t},\n\t\t{\n\t\t\t// normal case\n\t\t\tmounts: cgroupMountsAt(\"/sys/fs/cgroup\", defaultCgroupSubsystems),\n\t\t\texpected: map[string]string{\n\t\t\t\t\"blkio\":   \"/sys/fs/cgroup/blkio\",\n\t\t\t\t\"cpu\":     \"/sys/fs/cgroup/cpu,cpuacct\",\n\t\t\t\t\"cpuacct\": \"/sys/fs/cgroup/cpu,cpuacct\",\n\t\t\t\t\"cpuset\":  \"/sys/fs/cgroup/cpuset\",\n\t\t\t\t\"devices\": \"/sys/fs/cgroup/devices\",\n\t\t\t\t\"memory\":  \"/sys/fs/cgroup/memory\",\n\t\t\t\t\"hugetlb\": \"/sys/fs/cgroup/hugetlb\",\n\t\t\t\t\"pids\":    \"/sys/fs/cgroup/pids\",\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\t// multiple croup subsystems, should ignore second one\n\t\t\tmounts: append(cgroupMountsAt(\"/sys/fs/cgroup\", defaultCgroupSubsystems),\n\t\t\t\tcgroupMountsAt(\"/var/lib/rkt/pods/run/ccdd4e36-2d4c-49fd-8b94-4fb06133913d/stage1/rootfs/opt/stage2/flannel/rootfs/sys/fs/cgroup\", defaultCgroupSubsystems)...),\n\t\t\texpected: map[string]string{\n\t\t\t\t\"blkio\":   \"/sys/fs/cgroup/blkio\",\n\t\t\t\t\"cpu\":     \"/sys/fs/cgroup/cpu,cpuacct\",\n\t\t\t\t\"cpuacct\": \"/sys/fs/cgroup/cpu,cpuacct\",\n\t\t\t\t\"cpuset\":  \"/sys/fs/cgroup/cpuset\",\n\t\t\t\t\"devices\": \"/sys/fs/cgroup/devices\",\n\t\t\t\t\"memory\":  \"/sys/fs/cgroup/memory\",\n\t\t\t\t\"hugetlb\": \"/sys/fs/cgroup/hugetlb\",\n\t\t\t\t\"pids\":    \"/sys/fs/cgroup/pids\",\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\t// most subsystems not mounted\n\t\t\tmounts: cgroupMountsAt(\"/sys/fs/cgroup\", []string{\"cpu\"}),\n\t\t\texpected: map[string]string{\n\t\t\t\t\"cpu\": \"/sys/fs/cgroup/cpu\",\n\t\t\t},\n\t\t},\n\t}\n\n\tfor i, testCase := range testCases {\n\t\tsubSystems, err := getCgroupSubsystemsHelper(testCase.mounts, nil)\n\t\tif testCase.err {\n\t\t\tif err == nil {\n\t\t\t\tt.Fatalf(\"[case %d] Expected error but didn't get one\", i)\n\t\t\t}\n\t\t\tcontinue\n\t\t}\n\t\tif err != nil {\n\t\t\tt.Fatalf(\"[case %d] Expected no error, but got %v\", i, err)\n\t\t}\n\t\tif !reflect.DeepEqual(testCase.expected, subSystems) {\n\t\t\tt.Fatalf(\"[case %d] Expected %v == %v\", i, testCase.expected, subSystems)\n\t\t}\n\t}\n}\n\nfunc getFileContent(t *testing.T, filePath string) string {\n\tfileContent, err := os.ReadFile(filePath)\n\tassert.Nil(t, err)\n\treturn string(fileContent)\n}\n\nfunc clearTestData(t *testing.T, clearRefsPaths []string) {\n\tfor _, clearRefsPath := range clearRefsPaths {\n\t\terr := os.WriteFile(clearRefsPath, []byte(\"0\\n\"), 0o644)\n\t\tassert.Nil(t, err)\n\t}\n}\n"
  },
  {
    "path": "container/libcontainer/testdata/clear_refs4",
    "content": "0\n"
  },
  {
    "path": "container/libcontainer/testdata/clear_refs6",
    "content": "0\n"
  },
  {
    "path": "container/libcontainer/testdata/clear_refs8",
    "content": "0\n"
  },
  {
    "path": "container/libcontainer/testdata/docker-v1.8.3/execdriver/native/1/state.json",
    "content": "{\"id\":\"1\",\"init_process_pid\":66241,\"init_process_start\":\"4507843\",\"cgroup_paths\":{\"blkio\":\"/sys/fs/cgroup/blkio/docker/1\",\"cpu\":\"/sys/fs/cgroup/cpu/docker/1\",\"cpuacct\":\"/sys/fs/cgroup/cpuacct/docker/1\",\"cpuset\":\"/sys/fs/cgroup/cpuset/docker/1\",\"devices\":\"/sys/fs/cgroup/devices/docker/1\",\"freezer\":\"/sys/fs/cgroup/freezer/docker/1\",\"hugetlb\":\"/sys/fs/cgroup/hugetlb/docker/1\",\"memory\":\"/sys/fs/cgroup/memory/docker/1\",\"net_cls\":\"/sys/fs/cgroup/net_cls/docker/1\",\"net_prio\":\"/sys/fs/cgroup/net_prio/docker/1\",\"perf_event\":\"/sys/fs/cgroup/perf_event/docker/1\"},\"namespace_paths\":{\"NEWIPC\":\"/proc/66241/ns/ipc\",\"NEWNET\":\"/var/run/docker/netns/e05ddb1777f3\",\"NEWNS\":\"/proc/66241/ns/mnt\",\"NEWPID\":\"/proc/66241/ns/pid\",\"NEWUSER\":\"/proc/66241/ns/user\",\"NEWUTS\":\"/proc/66241/ns/uts\"},\"config\":{\"no_pivot_root\":false,\"parent_death_signal\":0,\"pivot_dir\":\"\",\"rootfs\":\"/var/lib/docker/devicemapper/mnt/1/rootfs\",\"readonlyfs\":false,\"privatefs\":true,\"mounts\":[{\"source\":\"proc\",\"destination\":\"/proc\",\"device\":\"proc\",\"flags\":14,\"data\":\"\",\"relabel\":\"\",\"premount_cmds\":null,\"postmount_cmds\":null},{\"source\":\"tmpfs\",\"destination\":\"/dev\",\"device\":\"tmpfs\",\"flags\":16777218,\"data\":\"mode=755\",\"relabel\":\"\",\"premount_cmds\":null,\"postmount_cmds\":null},{\"source\":\"devpts\",\"destination\":\"/dev/pts\",\"device\":\"devpts\",\"flags\":10,\"data\":\"newinstance,ptmxmode=0666,mode=0620,gid=5\",\"relabel\":\"\",\"premount_cmds\":null,\"postmount_cmds\":null},{\"source\":\"shm\",\"destination\":\"/dev/shm\",\"device\":\"tmpfs\",\"flags\":14,\"data\":\"mode=1777,size=65536k\",\"relabel\":\"\",\"premount_cmds\":null,\"postmount_cmds\":null},{\"source\":\"mqueue\",\"destination\":\"/dev/mqueue\",\"device\":\"mqueue\",\"flags\":14,\"data\":\"\",\"relabel\":\"\",\"premount_cmds\":null,\"postmount_cmds\":null},{\"source\":\"sysfs\",\"destination\":\"/sys\",\"device\":\"sysfs\",\"flags\":15,\"data\":\"\",\"relabel\":\"\",\"premount_cmds\":null,\"postmount_cmds\":null},{\"source\":\"cgroup\",\"destination\":\"/sys/fs/cgroup\",\"device\":\"cgroup\",\"flags\":15,\"data\":\"\",\"relabel\":\"\",\"premount_cmds\":null,\"postmount_cmds\":null},{\"source\":\"/var/lib/docker/containers/1/resolv.conf\",\"destination\":\"/etc/resolv.conf\",\"device\":\"bind\",\"flags\":20480,\"data\":\"\",\"relabel\":\"\",\"premount_cmds\":null,\"postmount_cmds\":null},{\"source\":\"/var/lib/docker/containers/1/hostname\",\"destination\":\"/etc/hostname\",\"device\":\"bind\",\"flags\":20480,\"data\":\"\",\"relabel\":\"\",\"premount_cmds\":null,\"postmount_cmds\":null},{\"source\":\"/var/lib/docker/containers/1/hosts\",\"destination\":\"/etc/hosts\",\"device\":\"bind\",\"flags\":20480,\"data\":\"\",\"relabel\":\"\",\"premount_cmds\":null,\"postmount_cmds\":null}],\"devices\":[{\"type\":99,\"path\":\"/dev/fuse\",\"major\":10,\"minor\":229,\"permissions\":\"rwm\",\"file_mode\":0,\"uid\":0,\"gid\":0},{\"type\":99,\"path\":\"/dev/null\",\"major\":1,\"minor\":3,\"permissions\":\"rwm\",\"file_mode\":438,\"uid\":0,\"gid\":0},{\"type\":99,\"path\":\"/dev/zero\",\"major\":1,\"minor\":5,\"permissions\":\"rwm\",\"file_mode\":438,\"uid\":0,\"gid\":0},{\"type\":99,\"path\":\"/dev/full\",\"major\":1,\"minor\":7,\"permissions\":\"rwm\",\"file_mode\":438,\"uid\":0,\"gid\":0},{\"type\":99,\"path\":\"/dev/tty\",\"major\":5,\"minor\":0,\"permissions\":\"rwm\",\"file_mode\":438,\"uid\":0,\"gid\":0},{\"type\":99,\"path\":\"/dev/urandom\",\"major\":1,\"minor\":9,\"permissions\":\"rwm\",\"file_mode\":438,\"uid\":0,\"gid\":0},{\"type\":99,\"path\":\"/dev/random\",\"major\":1,\"minor\":8,\"permissions\":\"rwm\",\"file_mode\":438,\"uid\":0,\"gid\":0}],\"mount_label\":\"\",\"hostname\":\"1\",\"namespaces\":[{\"type\":\"NEWNS\",\"path\":\"\"},{\"type\":\"NEWUTS\",\"path\":\"\"},{\"type\":\"NEWIPC\",\"path\":\"\"},{\"type\":\"NEWPID\",\"path\":\"\"},{\"type\":\"NEWNET\",\"path\":\"/var/run/docker/netns/e05ddb1777f3\"}],\"capabilities\":[\"CHOWN\",\"DAC_OVERRIDE\",\"FSETID\",\"FOWNER\",\"MKNOD\",\"NET_RAW\",\"SETGID\",\"SETUID\",\"SETFCAP\",\"SETPCAP\",\"NET_BIND_SERVICE\",\"SYS_CHROOT\",\"KILL\",\"AUDIT_WRITE\"],\"networks\":null,\"routes\":null,\"cgroups\":{\"name\":\"1\",\"parent\":\"docker\",\"allow_all_devices\":false,\"allowed_devices\":[{\"type\":99,\"path\":\"\",\"major\":-1,\"minor\":-1,\"permissions\":\"m\",\"file_mode\":0,\"uid\":0,\"gid\":0},{\"type\":98,\"path\":\"\",\"major\":-1,\"minor\":-1,\"permissions\":\"m\",\"file_mode\":0,\"uid\":0,\"gid\":0},{\"type\":99,\"path\":\"/dev/console\",\"major\":5,\"minor\":1,\"permissions\":\"rwm\",\"file_mode\":0,\"uid\":0,\"gid\":0},{\"type\":99,\"path\":\"/dev/tty0\",\"major\":4,\"minor\":0,\"permissions\":\"rwm\",\"file_mode\":0,\"uid\":0,\"gid\":0},{\"type\":99,\"path\":\"/dev/tty1\",\"major\":4,\"minor\":1,\"permissions\":\"rwm\",\"file_mode\":0,\"uid\":0,\"gid\":0},{\"type\":99,\"path\":\"\",\"major\":136,\"minor\":-1,\"permissions\":\"rwm\",\"file_mode\":0,\"uid\":0,\"gid\":0},{\"type\":99,\"path\":\"\",\"major\":5,\"minor\":2,\"permissions\":\"rwm\",\"file_mode\":0,\"uid\":0,\"gid\":0},{\"type\":99,\"path\":\"\",\"major\":10,\"minor\":200,\"permissions\":\"rwm\",\"file_mode\":0,\"uid\":0,\"gid\":0},{\"type\":99,\"path\":\"/dev/null\",\"major\":1,\"minor\":3,\"permissions\":\"rwm\",\"file_mode\":438,\"uid\":0,\"gid\":0},{\"type\":99,\"path\":\"/dev/zero\",\"major\":1,\"minor\":5,\"permissions\":\"rwm\",\"file_mode\":438,\"uid\":0,\"gid\":0},{\"type\":99,\"path\":\"/dev/full\",\"major\":1,\"minor\":7,\"permissions\":\"rwm\",\"file_mode\":438,\"uid\":0,\"gid\":0},{\"type\":99,\"path\":\"/dev/tty\",\"major\":5,\"minor\":0,\"permissions\":\"rwm\",\"file_mode\":438,\"uid\":0,\"gid\":0},{\"type\":99,\"path\":\"/dev/urandom\",\"major\":1,\"minor\":9,\"permissions\":\"rwm\",\"file_mode\":438,\"uid\":0,\"gid\":0},{\"type\":99,\"path\":\"/dev/random\",\"major\":1,\"minor\":8,\"permissions\":\"rwm\",\"file_mode\":438,\"uid\":0,\"gid\":0}],\"denied_devices\":null,\"memory\":0,\"memory_reservation\":0,\"memory_swap\":0,\"kernel_memory\":0,\"cpu_shares\":0,\"cpuset_cpus\":\"\",\"cpuset_mems\":\"\",\"blkio_throttle_read_bps_device\":\"\",\"blkio_throttle_write_bps_device\":\"\",\"blkio_throttle_read_iops_device\":\"\",\"blkio_throttle_write_iops_device\":\"\",\"blkio_weight\":0,\"blkio_weight_device\":\"\",\"freezer\":\"\",\"hugetlb_limit\":null,\"slice\":\"\",\"oom_kill_disable\":false,\"memory_swappiness\":-1,\"net_prio_ifpriomap\":null,\"net_cls_classid\":\"\"},\"apparmor_profile\":\"docker-default\",\"process_label\":\"\",\"rlimits\":null,\"additional_groups\":null,\"uid_mappings\":null,\"gid_mappings\":null,\"mask_paths\":[\"/proc/kcore\",\"/proc/latency_stats\",\"/proc/timer_stats\"],\"readonly_paths\":[\"/proc/asound\",\"/proc/bus\",\"/proc/fs\",\"/proc/irq\",\"/proc/sys\",\"/proc/sysrq-trigger\"],\"sysctl\":null,\"seccomp\":null},\"external_descriptors\":[\"/dev/null\",\"/dev/null\",\"/dev/null\"]}\n"
  },
  {
    "path": "container/libcontainer/testdata/docker-v1.9.1/execdriver/native/1/state.json",
    "content": "{\"id\":\"1\",\"init_process_pid\":64076,\"init_process_start\":\"3211353\",\"cgroup_paths\":{\"blkio\":\"/sys/fs/cgroup/blkio/docker/1\",\"cpu\":\"/sys/fs/cgroup/cpu/docker/1\",\"cpuacct\":\"/sys/fs/cgroup/cpuacct/docker/1\",\"cpuset\":\"/sys/fs/cgroup/cpuset/docker/1\",\"devices\":\"/sys/fs/cgroup/devices/docker/1\",\"freezer\":\"/sys/fs/cgroup/freezer/docker/1\",\"hugetlb\":\"/sys/fs/cgroup/hugetlb/docker/1\",\"memory\":\"/sys/fs/cgroup/memory/docker/1\",\"net_cls\":\"/sys/fs/cgroup/net_cls/docker/1\",\"net_prio\":\"/sys/fs/cgroup/net_prio/docker/1\",\"perf_event\":\"/sys/fs/cgroup/perf_event/docker/1\"},\"namespace_paths\":{\"NEWIPC\":\"/proc/64076/ns/ipc\",\"NEWNET\":\"/proc/64076/ns/net\",\"NEWNS\":\"/proc/64076/ns/mnt\",\"NEWPID\":\"/proc/64076/ns/pid\",\"NEWUSER\":\"/proc/64076/ns/user\",\"NEWUTS\":\"/proc/64076/ns/uts\"},\"config\":{\"no_pivot_root\":false,\"parent_death_signal\":0,\"pivot_dir\":\"\",\"rootfs\":\"/var/lib/docker/devicemapper/mnt/1/rootfs\",\"readonlyfs\":false,\"rootPropagation\":278528,\"mounts\":[{\"source\":\"proc\",\"destination\":\"/proc\",\"device\":\"proc\",\"flags\":14,\"propagation_flags\":null,\"data\":\"\",\"relabel\":\"\",\"premount_cmds\":null,\"postmount_cmds\":null},{\"source\":\"tmpfs\",\"destination\":\"/dev\",\"device\":\"tmpfs\",\"flags\":16777218,\"propagation_flags\":null,\"data\":\"mode=755\",\"relabel\":\"\",\"premount_cmds\":null,\"postmount_cmds\":null},{\"source\":\"devpts\",\"destination\":\"/dev/pts\",\"device\":\"devpts\",\"flags\":10,\"propagation_flags\":null,\"data\":\"newinstance,ptmxmode=0666,mode=0620,gid=5\",\"relabel\":\"\",\"premount_cmds\":null,\"postmount_cmds\":null},{\"source\":\"sysfs\",\"destination\":\"/sys\",\"device\":\"sysfs\",\"flags\":15,\"propagation_flags\":null,\"data\":\"\",\"relabel\":\"\",\"premount_cmds\":null,\"postmount_cmds\":null},{\"source\":\"cgroup\",\"destination\":\"/sys/fs/cgroup\",\"device\":\"cgroup\",\"flags\":15,\"propagation_flags\":null,\"data\":\"\",\"relabel\":\"\",\"premount_cmds\":null,\"postmount_cmds\":null},{\"source\":\"/var/lib/docker/containers/1/resolv.conf\",\"destination\":\"/etc/resolv.conf\",\"device\":\"bind\",\"flags\":20480,\"propagation_flags\":null,\"data\":\"\",\"relabel\":\"\",\"premount_cmds\":null,\"postmount_cmds\":null},{\"source\":\"/var/lib/docker/containers/1/hostname\",\"destination\":\"/etc/hostname\",\"device\":\"bind\",\"flags\":20480,\"propagation_flags\":null,\"data\":\"\",\"relabel\":\"\",\"premount_cmds\":null,\"postmount_cmds\":null},{\"source\":\"/var/lib/docker/containers/1/hosts\",\"destination\":\"/etc/hosts\",\"device\":\"bind\",\"flags\":20480,\"propagation_flags\":null,\"data\":\"\",\"relabel\":\"\",\"premount_cmds\":null,\"postmount_cmds\":null},{\"source\":\"/var/lib/docker/containers/1/shm\",\"destination\":\"/dev/shm\",\"device\":\"bind\",\"flags\":20480,\"propagation_flags\":null,\"data\":\"\",\"relabel\":\"\",\"premount_cmds\":null,\"postmount_cmds\":null},{\"source\":\"/var/lib/docker/containers/1/mqueue\",\"destination\":\"/dev/mqueue\",\"device\":\"bind\",\"flags\":20480,\"propagation_flags\":null,\"data\":\"\",\"relabel\":\"\",\"premount_cmds\":null,\"postmount_cmds\":null}],\"devices\":[{\"type\":99,\"path\":\"/dev/fuse\",\"major\":10,\"minor\":229,\"permissions\":\"rwm\",\"file_mode\":0,\"uid\":0,\"gid\":0},{\"type\":99,\"path\":\"/dev/null\",\"major\":1,\"minor\":3,\"permissions\":\"rwm\",\"file_mode\":438,\"uid\":0,\"gid\":0},{\"type\":99,\"path\":\"/dev/zero\",\"major\":1,\"minor\":5,\"permissions\":\"rwm\",\"file_mode\":438,\"uid\":0,\"gid\":0},{\"type\":99,\"path\":\"/dev/full\",\"major\":1,\"minor\":7,\"permissions\":\"rwm\",\"file_mode\":438,\"uid\":0,\"gid\":0},{\"type\":99,\"path\":\"/dev/tty\",\"major\":5,\"minor\":0,\"permissions\":\"rwm\",\"file_mode\":438,\"uid\":0,\"gid\":0},{\"type\":99,\"path\":\"/dev/urandom\",\"major\":1,\"minor\":9,\"permissions\":\"rwm\",\"file_mode\":438,\"uid\":0,\"gid\":0},{\"type\":99,\"path\":\"/dev/random\",\"major\":1,\"minor\":8,\"permissions\":\"rwm\",\"file_mode\":438,\"uid\":0,\"gid\":0}],\"mount_label\":\"\",\"hostname\":\"1\",\"namespaces\":[{\"type\":\"NEWNS\",\"path\":\"\"},{\"type\":\"NEWUTS\",\"path\":\"\"},{\"type\":\"NEWIPC\",\"path\":\"\"},{\"type\":\"NEWPID\",\"path\":\"\"},{\"type\":\"NEWNET\",\"path\":\"\"}],\"capabilities\":[\"CAP_CHOWN\",\"CAP_DAC_OVERRIDE\",\"CAP_FSETID\",\"CAP_FOWNER\",\"CAP_MKNOD\",\"CAP_NET_RAW\",\"CAP_SETGID\",\"CAP_SETUID\",\"CAP_SETFCAP\",\"CAP_SETPCAP\",\"CAP_NET_BIND_SERVICE\",\"CAP_SYS_CHROOT\",\"CAP_KILL\",\"CAP_AUDIT_WRITE\"],\"networks\":null,\"routes\":null,\"cgroups\":{\"name\":\"1\",\"parent\":\"docker\",\"allow_all_devices\":false,\"allowed_devices\":[{\"type\":99,\"path\":\"\",\"major\":-1,\"minor\":-1,\"permissions\":\"m\",\"file_mode\":0,\"uid\":0,\"gid\":0},{\"type\":98,\"path\":\"\",\"major\":-1,\"minor\":-1,\"permissions\":\"m\",\"file_mode\":0,\"uid\":0,\"gid\":0},{\"type\":99,\"path\":\"/dev/console\",\"major\":5,\"minor\":1,\"permissions\":\"rwm\",\"file_mode\":0,\"uid\":0,\"gid\":0},{\"type\":99,\"path\":\"/dev/tty0\",\"major\":4,\"minor\":0,\"permissions\":\"rwm\",\"file_mode\":0,\"uid\":0,\"gid\":0},{\"type\":99,\"path\":\"/dev/tty1\",\"major\":4,\"minor\":1,\"permissions\":\"rwm\",\"file_mode\":0,\"uid\":0,\"gid\":0},{\"type\":99,\"path\":\"\",\"major\":136,\"minor\":-1,\"permissions\":\"rwm\",\"file_mode\":0,\"uid\":0,\"gid\":0},{\"type\":99,\"path\":\"\",\"major\":5,\"minor\":2,\"permissions\":\"rwm\",\"file_mode\":0,\"uid\":0,\"gid\":0},{\"type\":99,\"path\":\"\",\"major\":10,\"minor\":200,\"permissions\":\"rwm\",\"file_mode\":0,\"uid\":0,\"gid\":0},{\"type\":99,\"path\":\"/dev/null\",\"major\":1,\"minor\":3,\"permissions\":\"rwm\",\"file_mode\":438,\"uid\":0,\"gid\":0},{\"type\":99,\"path\":\"/dev/zero\",\"major\":1,\"minor\":5,\"permissions\":\"rwm\",\"file_mode\":438,\"uid\":0,\"gid\":0},{\"type\":99,\"path\":\"/dev/full\",\"major\":1,\"minor\":7,\"permissions\":\"rwm\",\"file_mode\":438,\"uid\":0,\"gid\":0},{\"type\":99,\"path\":\"/dev/tty\",\"major\":5,\"minor\":0,\"permissions\":\"rwm\",\"file_mode\":438,\"uid\":0,\"gid\":0},{\"type\":99,\"path\":\"/dev/urandom\",\"major\":1,\"minor\":9,\"permissions\":\"rwm\",\"file_mode\":438,\"uid\":0,\"gid\":0},{\"type\":99,\"path\":\"/dev/random\",\"major\":1,\"minor\":8,\"permissions\":\"rwm\",\"file_mode\":438,\"uid\":0,\"gid\":0}],\"denied_devices\":null,\"memory\":0,\"memory_reservation\":0,\"memory_swap\":0,\"kernel_memory\":0,\"cpu_shares\":0,\"cpuset_cpus\":\"\",\"cpuset_mems\":\"\",\"blkio_weight\":0,\"blkio_leaf_weight\":0,\"blkio_weight_device\":null,\"blkio_throttle_read_bps_device\":null,\"blkio_throttle_write_bps_device\":null,\"blkio_throttle_read_iops_device\":null,\"blkio_throttle_write_iops_device\":null,\"freezer\":\"\",\"hugetlb_limit\":null,\"slice\":\"\",\"oom_kill_disable\":false,\"memory_swappiness\":-1,\"net_prio_ifpriomap\":null,\"net_cls_classid\":\"\"},\"apparmor_profile\":\"docker-default\",\"process_label\":\"\",\"rlimits\":null,\"oom_score_adj\":0,\"additional_groups\":null,\"uid_mappings\":null,\"gid_mappings\":null,\"mask_paths\":[\"/proc/kcore\",\"/proc/latency_stats\",\"/proc/timer_stats\"],\"readonly_paths\":[\"/proc/asound\",\"/proc/bus\",\"/proc/fs\",\"/proc/irq\",\"/proc/sys\",\"/proc/sysrq-trigger\"],\"sysctl\":null,\"seccomp\":null,\"version\":\"\"},\"external_descriptors\":[\"/dev/null\",\"/dev/null\",\"/dev/null\"]}\n"
  },
  {
    "path": "container/libcontainer/testdata/limits",
    "content": "Limit                     Soft Limit           Hard Limit           Units     \nMax cpu time              unlimited            unlimited            seconds   \nMax file size             unlimited            unlimited            bytes     \nMax data size             unlimited            unlimited            bytes     \nMax stack size            8388608              unlimited            bytes     \nMax core file size        unlimited            unlimited            bytes     \nMax resident set          unlimited            unlimited            bytes     \nMax processes             119958               119958               processes \nMax open files            1073741816           1073741816           files     \nMax locked memory         3932852224           3932852224           bytes     \nMax address space         unlimited            unlimited            bytes     \nMax file locks            unlimited            unlimited            locks     \nMax pending signals       119958               119958               signals   \nMax msgqueue size         819200               819200               bytes     \nMax nice priority         0                    0                    \nMax realtime priority     0                    0                    \nMax realtime timeout      unlimited            unlimited            us        \n"
  },
  {
    "path": "container/libcontainer/testdata/procnetdev",
    "content": "Inter-|   Receive                                                |  Transmit\n face |bytes    packets errs drop fifo frame compressed multicast|bytes    packets errs drop fifo colls carrier compressed\nwlp4s0:       1       2    3    4    5     6          7         8        9       10    11    12    13     14       15          0\ndocker0:       0       0    0    0    0     0          0         0        0       0    0    0    0     0       0          0\n    lo:  0    0    0    0    0     0          0         0   0    0    0    0    0     0       0          0\n   em1:  315849    1172    0    0    0     0          0         0   315850    1173    0    0    0     0       0          0"
  },
  {
    "path": "container/libcontainer/testdata/procnetudp",
    "content": "  sl  local_address rem_address   st tx_queue rx_queue tr tm->when retrnsmt   uid  timeout inode ref pointer drops             \n  1: 00000000:07D3 00000000:0000 07 00000000:00000000 00:00000000 00000000     0        0 16583 2 ffff8800b4549400 0         \n  21: 00000000:A841 00000000:0000 07 0000000A:0000000B 00:00000000 00000000  1000        0 114299623 2 ffff880338477800 4     \n"
  },
  {
    "path": "container/libcontainer/testdata/smaps4",
    "content": "55f523c9f000-55f523cc1000 r-xp 00000000 08:02 5505067                    /sbin/cgmanager\nSize:                136 kB\nKernelPageSize:        4 kB\nMMUPageSize:           4 kB\nRss:                 132 kB\nPss:                 132 kB\nShared_Clean:          0 kB\nShared_Dirty:          0 kB\nPrivate_Clean:       132 kB\nPrivate_Dirty:         0 kB\nReferenced:          132 kB\nAnonymous:             0 kB\nLazyFree:              0 kB\nAnonHugePages:         0 kB\nShmemPmdMapped:        0 kB\nShared_Hugetlb:        0 kB\nPrivate_Hugetlb:       0 kB\nSwap:                  0 kB\nSwapPss:               0 kB\nLocked:                0 kB\nVmFlags: rd ex mr mw me dw sd \n55f523ec0000-55f523ec2000 r--p 00021000 08:02 5505067                    /sbin/cgmanager\nSize:                  8 kB\nKernelPageSize:        4 kB\nMMUPageSize:           4 kB\nRss:                   8 kB\nPss:                   8 kB\nShared_Clean:          0 kB\nShared_Dirty:          0 kB\nPrivate_Clean:         0 kB\nPrivate_Dirty:         8 kB\nReferenced:            4 kB\nAnonymous:             8 kB\nLazyFree:              0 kB\nAnonHugePages:         0 kB\nShmemPmdMapped:        0 kB\nShared_Hugetlb:        0 kB\nPrivate_Hugetlb:       0 kB\nSwap:                  0 kB\nSwapPss:               0 kB\nLocked:                0 kB\nVmFlags: rd mr mw me dw ac sd \n55f523ec2000-55f523ec3000 rw-p 00023000 08:02 5505067                    /sbin/cgmanager\nSize:                  4 kB\nKernelPageSize:        4 kB\nMMUPageSize:           4 kB\nRss:                   4 kB\nPss:                   4 kB\nShared_Clean:          0 kB\nShared_Dirty:          0 kB\nPrivate_Clean:         0 kB\nPrivate_Dirty:         4 kB\nReferenced:            0 kB\nAnonymous:             4 kB\nLazyFree:              0 kB\nAnonHugePages:         0 kB\nShmemPmdMapped:        0 kB\nShared_Hugetlb:        0 kB\nPrivate_Hugetlb:       0 kB\nSwap:                  0 kB\nSwapPss:               0 kB\nLocked:                0 kB\nVmFlags: rd wr mr mw me dw ac sd \n55f52478d000-55f5247ae000 rw-p 00000000 00:00 0                          [heap]\nSize:                132 kB\nKernelPageSize:        4 kB\nMMUPageSize:           4 kB\nRss:                  16 kB\nPss:                  16 kB\nShared_Clean:          0 kB\nShared_Dirty:          0 kB\nPrivate_Clean:         0 kB\nPrivate_Dirty:        16 kB\nReferenced:           16 kB\nAnonymous:            16 kB\nLazyFree:              0 kB\nAnonHugePages:         0 kB\nShmemPmdMapped:        0 kB\nShared_Hugetlb:        0 kB\nPrivate_Hugetlb:       0 kB\nSwap:                  0 kB\nSwapPss:               0 kB\nLocked:                0 kB\nVmFlags: rd wr mr mw me ac sd \n"
  },
  {
    "path": "container/libcontainer/testdata/smaps6",
    "content": "55f523c9f000-55f523cc1000 r-xp 00000000 08:02 5505067                    /sbin/cgmanager\nSize:                136 kB\nKernelPageSize:        4 kB\nMMUPageSize:           4 kB\nRss:                 132 kB\nPss:                 132 kB\nShared_Clean:          0 kB\nShared_Dirty:          0 kB\nPrivate_Clean:       132 kB\nPrivate_Dirty:         0 kB\nReferenced:          132 kB\nAnonymous:             0 kB\nLazyFree:              0 kB\nAnonHugePages:         0 kB\nShmemPmdMapped:        0 kB\nShared_Hugetlb:        0 kB\nPrivate_Hugetlb:       0 kB\nSwap:                  0 kB\nSwapPss:               0 kB\nLocked:                0 kB\nVmFlags: rd ex mr mw me dw sd \n"
  },
  {
    "path": "container/libcontainer/testdata/smaps8",
    "content": "55f523c9f000-55f523cc1000 r-xp 00000000 08:02 5505067                    /sbin/cgmanager\nSize:                136 kB\nKernelPageSize:        4 kB\nMMUPageSize:           4 kB\nRss:                 132 kB\nPss:                 132 kB\nShared_Clean:          0 kB\nShared_Dirty:          0 kB\nPrivate_Clean:       132 kB\nPrivate_Dirty:         0 kB\nReferenced:          132 kB\nAnonymous:             0 kB\nLazyFree:              0 kB\nAnonHugePages:         0 kB\nShmemPmdMapped:        0 kB\nShared_Hugetlb:        0 kB\nPrivate_Hugetlb:       0 kB\nSwap:                  0 kB\nSwapPss:               0 kB\nLocked:                0 kB\nVmFlags: rd ex mr mw me dw sd \n"
  },
  {
    "path": "container/podman/client.go",
    "content": "// Copyright 2021 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n//go:build linux\n\npackage podman\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"net\"\n\t\"net/http\"\n\turllib \"net/url\"\n)\n\ntype clientKey struct{}\n\nfunc (c clientKey) String() string {\n\treturn \"client\"\n}\n\ntype Connection struct {\n\tURI    *urllib.URL\n\tClient *http.Client\n}\n\nfunc client(ctx *context.Context) (*Connection, error) {\n\turl, err := urllib.Parse(*endpointFlag)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tswitch url.Scheme {\n\tcase \"unix\":\n\t\tconnection := Connection{URI: url}\n\t\tconnection.Client = &http.Client{\n\t\t\tTransport: &http.Transport{\n\t\t\t\tDialContext: func(ctx context.Context, _, _ string) (net.Conn, error) {\n\t\t\t\t\treturn (&net.Dialer{}).DialContext(ctx, \"unix\", url.Path)\n\t\t\t\t},\n\t\t\t\tDisableCompression: true,\n\t\t\t},\n\t\t}\n\t\t*ctx = context.WithValue(*ctx, clientKey{}, &connection)\n\t\treturn &connection, nil\n\t}\n\n\treturn nil, fmt.Errorf(\"couldn't get podman client\")\n}\n"
  },
  {
    "path": "container/podman/factory.go",
    "content": "// Copyright 2021 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n//go:build linux\n\npackage podman\n\nimport (\n\t\"flag\"\n\t\"fmt\"\n\t\"path\"\n\t\"sync\"\n\t\"time\"\n\n\t\"github.com/google/cadvisor/container\"\n\t\"github.com/google/cadvisor/container/docker\"\n\tdockerutil \"github.com/google/cadvisor/container/docker/utils\"\n\t\"github.com/google/cadvisor/devicemapper\"\n\t\"github.com/google/cadvisor/fs\"\n\tinfo \"github.com/google/cadvisor/info/v1\"\n\t\"github.com/google/cadvisor/zfs\"\n)\n\nconst (\n\trootDirRetries     = 5\n\trootDirRetryPeriod = time.Second\n\tcontainerBaseName  = \"container\"\n)\n\nvar (\n\tendpointFlag = flag.String(\"podman\", \"unix:///var/run/podman/podman.sock\", \"podman endpoint\")\n)\n\nvar (\n\trootDir     string\n\trootDirOnce sync.Once\n)\n\nfunc RootDir() string {\n\trootDirOnce.Do(func() {\n\t\tfor i := 0; i < rootDirRetries; i++ {\n\t\t\tstatus, err := Status()\n\t\t\tif err == nil && status.RootDir != \"\" {\n\t\t\t\trootDir = status.RootDir\n\t\t\t\tbreak\n\t\t\t} else {\n\t\t\t\ttime.Sleep(rootDirRetryPeriod)\n\t\t\t}\n\t\t}\n\t})\n\treturn rootDir\n}\n\ntype podmanFactory struct {\n\t// Information about the mounted cgroup subsystems.\n\tmachineInfoFactory info.MachineInfoFactory\n\n\tstorageDriver docker.StorageDriver\n\tstorageDir    string\n\n\tcgroupSubsystem map[string]string\n\n\tfsInfo fs.FsInfo\n\n\tmetrics container.MetricSet\n\n\tthinPoolName    string\n\tthinPoolWatcher *devicemapper.ThinPoolWatcher\n\n\tzfsWatcher *zfs.ZfsWatcher\n}\n\nfunc (f *podmanFactory) CanHandleAndAccept(name string) (handle bool, accept bool, err error) {\n\t// Rootless\n\tif path.Base(name) == containerBaseName {\n\t\tname, _ = path.Split(name)\n\t}\n\tif !dockerutil.IsContainerName(name) {\n\t\treturn false, false, nil\n\t}\n\n\tid := dockerutil.ContainerNameToId(name)\n\n\tctnr, err := InspectContainer(id)\n\tif err != nil {\n\t\treturn false, true, fmt.Errorf(\"error inspecting container: %v\", err)\n\t}\n\tif ctnr.State == nil || !ctnr.State.Running {\n\t\treturn false, true, fmt.Errorf(\"container not running\")\n\t}\n\treturn true, true, nil\n}\n\nfunc (f *podmanFactory) DebugInfo() map[string][]string {\n\treturn map[string][]string{}\n}\n\nfunc (f *podmanFactory) String() string {\n\treturn \"podman\"\n}\n\nfunc (f *podmanFactory) NewContainerHandler(name string, metadataEnvAllowList []string, inHostNamespace bool) (handler container.ContainerHandler, err error) {\n\treturn newContainerHandler(name, f.machineInfoFactory, f.fsInfo,\n\t\tf.storageDriver, f.storageDir, f.cgroupSubsystem, inHostNamespace,\n\t\tmetadataEnvAllowList, f.metrics, f.thinPoolName, f.thinPoolWatcher, f.zfsWatcher)\n}\n"
  },
  {
    "path": "container/podman/fs.go",
    "content": "// Copyright 2022 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n//go:build linux\n\npackage podman\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"os\"\n\t\"path/filepath\"\n\n\t\"github.com/google/cadvisor/container/docker\"\n)\n\nvar containersJsonFilnames = []string{\n\t\"containers.json\",\n\t\"volatile-containers.json\",\n}\n\ntype containersJSON struct {\n\tID    string `json:\"id\"`\n\tLayer string `json:\"layer\"`\n\t// rest in unnecessary\n}\n\nfunc rwLayerID(storageDriver docker.StorageDriver, storageDir string, containerID string) (string, error) {\n\tvar containers []containersJSON\n\tfileExists := false\n\n\tfor _, filename := range containersJsonFilnames {\n\t\tdata, err := os.ReadFile(filepath.Join(storageDir, string(storageDriver)+\"-containers\", filename))\n\t\tif err != nil && !os.IsNotExist(err) {\n\t\t\treturn \"\", err\n\t\t}\n\n\t\tif data != nil {\n\t\t\tfileExists = true\n\t\t\tvar buffer []containersJSON\n\t\t\terr = json.Unmarshal(data, &buffer)\n\t\t\tif err != nil {\n\t\t\t\treturn \"\", err\n\t\t\t}\n\t\t\tcontainers = append(containers, buffer...)\n\t\t}\n\t}\n\n\tif !fileExists {\n\t\treturn \"\", os.ErrNotExist\n\t}\n\n\tfor _, c := range containers {\n\t\tif c.ID == containerID {\n\t\t\treturn c.Layer, nil\n\t\t}\n\t}\n\n\treturn \"\", fmt.Errorf(\"unable to determine %v rw layer id\", containerID)\n}\n"
  },
  {
    "path": "container/podman/handler.go",
    "content": "// Copyright 2021 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n//go:build linux\n\n// Package podman implements a handler for Podman containers.\npackage podman\n\nimport (\n\t\"fmt\"\n\t\"path\"\n\t\"path/filepath\"\n\t\"strconv\"\n\t\"strings\"\n\t\"time\"\n\n\tdockercontainer \"github.com/moby/moby/api/types/container\"\n\t\"github.com/opencontainers/cgroups\"\n\n\t\"github.com/google/cadvisor/container\"\n\t\"github.com/google/cadvisor/container/common\"\n\t\"github.com/google/cadvisor/container/docker\"\n\tdockerutil \"github.com/google/cadvisor/container/docker/utils\"\n\tcontainerlibcontainer \"github.com/google/cadvisor/container/libcontainer\"\n\t\"github.com/google/cadvisor/devicemapper\"\n\t\"github.com/google/cadvisor/fs\"\n\tinfo \"github.com/google/cadvisor/info/v1\"\n\t\"github.com/google/cadvisor/zfs\"\n)\n\ntype containerHandler struct {\n\t// machineInfoFactory provides info.MachineInfo\n\tmachineInfoFactory info.MachineInfoFactory\n\n\t// Absolute path to the cgroup hierarchies of this container.\n\t// (e.g.: \"cpu\" -> \"/sys/fs/cgroup/cpu/test\")\n\tcgroupPaths map[string]string\n\n\t// the docker storage driver\n\tstorageDriver    docker.StorageDriver\n\tfsInfo           fs.FsInfo\n\trootfsStorageDir string\n\n\t// Time at which this container was created.\n\tcreationTime time.Time\n\n\t// Time at which this container was started.\n\tstartTime time.Time\n\n\t// Metadata associated with the container.\n\tenvs   map[string]string\n\tlabels map[string]string\n\n\t// Image name used for this container.\n\timage string\n\n\tnetworkMode dockercontainer.NetworkMode\n\n\t// Filesystem handler.\n\tfsHandler common.FsHandler\n\n\t// The IP address of the container\n\tipAddress string\n\n\tmetrics container.MetricSet\n\n\t// the devicemapper poolname\n\tthinPoolName string\n\n\t// zfsParent is the parent for docker zfs\n\tzfsParent string\n\n\t// Reference to the container\n\treference info.ContainerReference\n\n\tlibcontainerHandler *containerlibcontainer.Handler\n}\n\nfunc newContainerHandler(\n\tname string,\n\tmachineInfoFactory info.MachineInfoFactory,\n\tfsInfo fs.FsInfo,\n\tstorageDriver docker.StorageDriver,\n\tstorageDir string,\n\tcgroupSubsystems map[string]string,\n\tinHostNamespace bool,\n\tmetadataEnvAllowList []string,\n\tmetrics container.MetricSet,\n\tthinPoolName string,\n\tthinPoolWatcher *devicemapper.ThinPoolWatcher,\n\tzfsWatcher *zfs.ZfsWatcher,\n) (container.ContainerHandler, error) {\n\t// Create the cgroup paths.\n\tcgroupPaths := common.MakeCgroupPaths(cgroupSubsystems, name)\n\n\t// Generate the equivalent cgroup manager for this container.\n\tcgroupManager, err := containerlibcontainer.NewCgroupManager(name, cgroupPaths)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\trootFs := \"/\"\n\tif !inHostNamespace {\n\t\trootFs = \"/rootfs\"\n\t\tstorageDir = path.Join(rootFs, storageDir)\n\t}\n\n\trootless := path.Base(name) == containerBaseName\n\tif rootless {\n\t\tname, _ = path.Split(name)\n\t}\n\n\tid := dockerutil.ContainerNameToId(name)\n\n\t// We assume that if Inspect fails then the container is not known to Podman.\n\tctnr, err := InspectContainer(id)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\t// Obtain the IP address for the container.\n\tvar ipAddress string\n\tif ctnr.NetworkSettings != nil && ctnr.HostConfig != nil {\n\t\tc := ctnr\n\t\tif ctnr.HostConfig.NetworkMode.IsContainer() {\n\t\t\t// If the NetworkMode starts with 'container:' then we need to use the IP address of the container specified.\n\t\t\t// This happens in cases such as kubernetes where the containers doesn't have an IP address itself and we need to use the pod's address\n\t\t\tcontainerID := ctnr.HostConfig.NetworkMode.ConnectedContainer()\n\t\t\tc, err = InspectContainer(containerID)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, fmt.Errorf(\"failed to inspect container %q: %v\", containerID, err)\n\t\t\t}\n\t\t}\n\t\tif nw, ok := c.NetworkSettings.Networks[c.HostConfig.NetworkMode.NetworkName()]; ok {\n\t\t\tif nw.IPAddress.IsValid() {\n\t\t\t\tipAddress = nw.IPAddress.String()\n\t\t\t}\n\t\t}\n\t}\n\n\tlayerID, err := rwLayerID(storageDriver, storageDir, id)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\t// Determine the rootfs storage dir OR the pool name to determine the device.\n\t// For devicemapper, we only need the thin pool name, and that is passed in to this call\n\trootfsStorageDir, zfsFilesystem, zfsParent, err := determineDeviceStorage(storageDriver, storageDir, layerID)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\totherStorageDir := filepath.Join(storageDir, string(storageDriver)+\"-containers\", id)\n\n\thandler := &containerHandler{\n\t\tmachineInfoFactory: machineInfoFactory,\n\t\tcgroupPaths:        cgroupPaths,\n\t\tstorageDriver:      storageDriver,\n\t\tfsInfo:             fsInfo,\n\t\trootfsStorageDir:   rootfsStorageDir,\n\t\tipAddress:          ipAddress,\n\t\tenvs:               make(map[string]string),\n\t\tlabels:             ctnr.Config.Labels,\n\t\timage:              ctnr.Config.Image,\n\t\tnetworkMode:        ctnr.HostConfig.NetworkMode,\n\t\tfsHandler:          common.NewFsHandler(common.DefaultPeriod, rootfsStorageDir, otherStorageDir, fsInfo),\n\t\tmetrics:            metrics,\n\t\tthinPoolName:       thinPoolName,\n\t\tzfsParent:          zfsParent,\n\t\treference: info.ContainerReference{\n\t\t\t// Add the name and bare ID as aliases of the container.\n\t\t\tId:        id,\n\t\t\tName:      name,\n\t\t\tAliases:   []string{strings.TrimPrefix(ctnr.Name, \"/\"), id},\n\t\t\tNamespace: Namespace,\n\t\t},\n\t\tlibcontainerHandler: containerlibcontainer.NewHandler(cgroupManager, rootFs, ctnr.State.Pid, metrics),\n\t}\n\n\thandler.creationTime, err = time.Parse(time.RFC3339, ctnr.Created)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to parse the create timestamp %q for container %q: %v\", ctnr.Created, id, err)\n\t}\n\n\t// StartedAt may be unset for containers that never started.\n\tif startedAt := ctnr.State.StartedAt; startedAt != \"\" {\n\t\tif t, err := time.Parse(time.RFC3339Nano, startedAt); err == nil && !t.Before(time.Unix(0, 0)) {\n\t\t\thandler.startTime = t\n\t\t} else if t, err := time.Parse(time.RFC3339, startedAt); err == nil && !t.Before(time.Unix(0, 0)) {\n\t\t\thandler.startTime = t\n\t\t}\n\t}\n\n\tif ctnr.RestartCount > 0 {\n\t\thandler.labels[\"restartcount\"] = strconv.Itoa(ctnr.RestartCount)\n\t}\n\n\tif metrics.Has(container.DiskUsageMetrics) {\n\t\thandler.fsHandler = &docker.FsHandler{\n\t\t\tFsHandler:       common.NewFsHandler(common.DefaultPeriod, rootfsStorageDir, otherStorageDir, fsInfo),\n\t\t\tThinPoolWatcher: thinPoolWatcher,\n\t\t\tZfsWatcher:      zfsWatcher,\n\t\t\tDeviceID:        ctnr.GraphDriver.Data[\"DeviceId\"],\n\t\t\tZfsFilesystem:   zfsFilesystem,\n\t\t}\n\t}\n\n\t// Split env vars to get metadata map.\n\tfor _, exposedEnv := range metadataEnvAllowList {\n\t\tif exposedEnv == \"\" {\n\t\t\tcontinue\n\t\t}\n\n\t\tfor _, envVar := range ctnr.Config.Env {\n\t\t\tif envVar != \"\" {\n\t\t\t\tsplits := strings.SplitN(envVar, \"=\", 2)\n\t\t\t\tif len(splits) == 2 && strings.HasPrefix(splits[0], exposedEnv) {\n\t\t\t\t\thandler.envs[strings.ToLower(splits[0])] = splits[1]\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn handler, nil\n}\n\nfunc determineDeviceStorage(storageDriver docker.StorageDriver, storageDir string, rwLayerID string) (\n\trootfsStorageDir string, zfsFilesystem string, zfsParent string, err error) {\n\tswitch storageDriver {\n\t// Podman aliased the driver names together.\n\tcase docker.OverlayStorageDriver, docker.Overlay2StorageDriver:\n\t\trootfsStorageDir = path.Join(storageDir, \"overlay\", rwLayerID, \"diff\")\n\t\treturn\n\tdefault:\n\t\treturn docker.DetermineDeviceStorage(storageDriver, storageDir, rwLayerID)\n\t}\n}\n\nfunc (h *containerHandler) ContainerReference() (info.ContainerReference, error) {\n\treturn h.reference, nil\n}\n\nfunc (h *containerHandler) needNet() bool {\n\tif h.metrics.Has(container.NetworkUsageMetrics) {\n\t\th.networkMode.IsContainer()\n\t\treturn !h.networkMode.IsContainer()\n\t}\n\treturn false\n}\n\nfunc (h *containerHandler) GetSpec() (info.ContainerSpec, error) {\n\thasFilesystem := h.metrics.Has(container.DiskUsageMetrics)\n\n\tspec, err := common.GetSpec(h.cgroupPaths, h.machineInfoFactory, h.needNet(), hasFilesystem)\n\tif err != nil {\n\t\treturn info.ContainerSpec{}, err\n\t}\n\n\tspec.Labels = h.labels\n\tspec.Envs = h.envs\n\tspec.Image = h.image\n\tspec.CreationTime = h.creationTime\n\tspec.StartTime = h.startTime\n\n\treturn spec, nil\n}\n\nfunc (h *containerHandler) GetStats() (*info.ContainerStats, error) {\n\tstats, err := h.libcontainerHandler.GetStats()\n\tif err != nil {\n\t\treturn stats, err\n\t}\n\n\tif !h.needNet() {\n\t\tstats.Network = info.NetworkStats{}\n\t}\n\n\t// Get filesystem stats.\n\terr = docker.FsStats(stats, h.machineInfoFactory, h.metrics, h.storageDriver,\n\t\th.fsHandler, h.fsInfo, h.thinPoolName, h.rootfsStorageDir, h.zfsParent)\n\tif err != nil {\n\t\treturn stats, err\n\t}\n\n\treturn stats, nil\n}\n\nfunc (h *containerHandler) ListContainers(container.ListType) ([]info.ContainerReference, error) {\n\treturn []info.ContainerReference{}, nil\n}\n\nfunc (h *containerHandler) ListProcesses(container.ListType) ([]int, error) {\n\treturn h.libcontainerHandler.GetProcesses()\n}\n\nfunc (h *containerHandler) GetCgroupPath(resource string) (string, error) {\n\tvar res string\n\tif !cgroups.IsCgroup2UnifiedMode() {\n\t\tres = resource\n\t}\n\tcgroupPath, ok := h.cgroupPaths[res]\n\tif !ok {\n\t\treturn \"\", fmt.Errorf(\"could not find path for resource %q for container %q\", resource, h.reference.Name)\n\t}\n\n\treturn cgroupPath, nil\n}\n\nfunc (h *containerHandler) GetContainerLabels() map[string]string {\n\treturn h.labels\n}\n\nfunc (h *containerHandler) GetContainerIPAddress() string {\n\treturn h.ipAddress\n}\n\nfunc (h *containerHandler) Exists() bool {\n\treturn common.CgroupExists(h.cgroupPaths)\n}\n\nfunc (h *containerHandler) Cleanup() {\n\tif h.fsHandler != nil {\n\t\th.fsHandler.Stop()\n\t}\n}\n\nfunc (h *containerHandler) Start() {\n\tif h.fsHandler != nil {\n\t\th.fsHandler.Start()\n\t}\n}\n\nfunc (h *containerHandler) Type() container.ContainerType {\n\treturn container.ContainerTypePodman\n}\n\nfunc (h *containerHandler) GetExitCode() (int, error) {\n\tctnr, err := InspectContainer(h.reference.Id)\n\tif err != nil {\n\t\treturn -1, fmt.Errorf(\"failed to inspect container %s: %w\", h.reference.Id, err)\n\t}\n\n\tif ctnr.State == nil {\n\t\treturn -1, fmt.Errorf(\"container state not available for %s\", h.reference.Id)\n\t}\n\n\tif ctnr.State.Running {\n\t\treturn -1, fmt.Errorf(\"container %s is still running\", h.reference.Id)\n\t}\n\n\treturn ctnr.State.ExitCode, nil\n}\n"
  },
  {
    "path": "container/podman/install/install.go",
    "content": "// Copyright 2021 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n//go:build linux\n\npackage install\n\nimport (\n\t\"k8s.io/klog/v2\"\n\n\t\"github.com/google/cadvisor/container\"\n\t\"github.com/google/cadvisor/container/podman\"\n)\n\nfunc init() {\n\terr := container.RegisterPlugin(\"podman\", podman.NewPlugin())\n\tif err != nil {\n\t\tklog.Fatalf(\"Failed to register podman plugin: %v\", err)\n\t}\n}\n"
  },
  {
    "path": "container/podman/plugin.go",
    "content": "// Copyright 2021 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n//go:build linux\n\npackage podman\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/opencontainers/cgroups\"\n\t\"k8s.io/klog/v2\"\n\n\t\"github.com/google/cadvisor/container\"\n\t\"github.com/google/cadvisor/container/docker\"\n\tdockerutil \"github.com/google/cadvisor/container/docker/utils\"\n\t\"github.com/google/cadvisor/container/libcontainer\"\n\t\"github.com/google/cadvisor/devicemapper\"\n\t\"github.com/google/cadvisor/fs\"\n\tinfo \"github.com/google/cadvisor/info/v1\"\n\t\"github.com/google/cadvisor/watcher\"\n\t\"github.com/google/cadvisor/zfs\"\n)\n\nfunc NewPlugin() container.Plugin {\n\treturn &plugin{}\n}\n\ntype plugin struct{}\n\nfunc (p *plugin) InitializeFSContext(context *fs.Context) error {\n\tcontext.Podman = fs.PodmanContext{\n\t\tRoot:         \"\",\n\t\tDriver:       \"\",\n\t\tDriverStatus: map[string]string{},\n\t}\n\n\treturn nil\n}\n\nfunc (p *plugin) Register(factory info.MachineInfoFactory, fsInfo fs.FsInfo, includedMetrics container.MetricSet) (watcher.ContainerWatcher, error) {\n\treturn Register(factory, fsInfo, includedMetrics)\n}\n\nfunc Register(factory info.MachineInfoFactory, fsInfo fs.FsInfo, metrics container.MetricSet) (watcher.ContainerWatcher, error) {\n\tcgroupSubsystem, err := libcontainer.GetCgroupSubsystems(metrics)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to get cgroup subsystems: %v\", err)\n\t}\n\n\tvalidatedInfo, err := docker.ValidateInfo(GetInfo, VersionString)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to validate Podman info: %v\", err)\n\t}\n\n\tvar (\n\t\tthinPoolName    string\n\t\tthinPoolWatcher *devicemapper.ThinPoolWatcher\n\t\tzfsWatcher      *zfs.ZfsWatcher\n\t)\n\tif metrics.Has(container.DiskUsageMetrics) {\n\t\tswitch docker.StorageDriver(validatedInfo.Driver) {\n\t\tcase docker.DevicemapperStorageDriver:\n\t\t\tthinPoolWatcher, err = docker.StartThinPoolWatcher(validatedInfo)\n\t\t\tif err != nil {\n\t\t\t\tklog.Errorf(\"devicemapper filesystem stats will not be reported: %v\", err)\n\t\t\t}\n\n\t\t\tstatus, _ := docker.StatusFromDockerInfo(*validatedInfo)\n\t\t\tthinPoolName = status.DriverStatus[dockerutil.DriverStatusPoolName]\n\t\tcase docker.ZfsStorageDriver:\n\t\t\tzfsWatcher, err = docker.StartZfsWatcher(validatedInfo)\n\t\t\tif err != nil {\n\t\t\t\tklog.Errorf(\"zfs filesystem stats will not be reported: %v\", err)\n\t\t\t}\n\t\t}\n\t}\n\n\t// Register Podman container handler factory.\n\tklog.V(1).Info(\"Registering Podman factory\")\n\tf := &podmanFactory{\n\t\tmachineInfoFactory: factory,\n\t\tstorageDriver:      docker.StorageDriver(validatedInfo.Driver),\n\t\tstorageDir:         RootDir(),\n\t\tcgroupSubsystem:    cgroupSubsystem,\n\t\tfsInfo:             fsInfo,\n\t\tmetrics:            metrics,\n\t\tthinPoolName:       thinPoolName,\n\t\tthinPoolWatcher:    thinPoolWatcher,\n\t\tzfsWatcher:         zfsWatcher,\n\t}\n\n\tcontainer.RegisterContainerHandlerFactory(f, []watcher.ContainerWatchSource{watcher.Raw})\n\n\tif !cgroups.IsCgroup2UnifiedMode() {\n\t\tklog.Warning(\"Podman rootless containers not working with cgroups v1!\")\n\t}\n\n\treturn nil, nil\n}\n"
  },
  {
    "path": "container/podman/podman.go",
    "content": "// Copyright 2021 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n//go:build linux\n\npackage podman\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"time\"\n\n\tdockercontainer \"github.com/moby/moby/api/types/container\"\n\tdockerimage \"github.com/moby/moby/api/types/image\"\n\tdockersystem \"github.com/moby/moby/api/types/system\"\n\n\t\"github.com/google/cadvisor/container/docker\"\n\t\"github.com/google/cadvisor/container/docker/utils\"\n\tv1 \"github.com/google/cadvisor/info/v1\"\n)\n\nconst (\n\tNamespace = \"podman\"\n)\n\nvar timeout = 10 * time.Second\n\nfunc validateResponse(gotError error, response *http.Response) error {\n\tvar err error\n\tswitch {\n\tcase response == nil:\n\t\terr = fmt.Errorf(\"response not present\")\n\tcase response.StatusCode == http.StatusNotFound:\n\t\terr = fmt.Errorf(\"item not found\")\n\tcase response.StatusCode == http.StatusNotImplemented:\n\t\terr = fmt.Errorf(\"query not implemented\")\n\tdefault:\n\t\treturn gotError\n\t}\n\n\tif gotError != nil {\n\t\terr = fmt.Errorf(\"%s: %w\", err.Error(), gotError)\n\t}\n\n\treturn err\n}\n\nfunc apiGetRequest(url string, item interface{}) error {\n\tctx, cancel := context.WithTimeout(context.Background(), timeout)\n\tdefer cancel()\n\n\tconn, err := client(&ctx)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\treq, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tresp, err := conn.Client.Do(req)\n\terr = validateResponse(err, resp)\n\tif err != nil {\n\t\treturn err\n\t}\n\tdefer resp.Body.Close()\n\n\tdata, err := io.ReadAll(resp.Body)\n\tif err != nil {\n\t\treturn err\n\n\t}\n\n\terr = json.Unmarshal(data, item)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\treturn ctx.Err()\n}\n\nfunc Images() ([]v1.DockerImage, error) {\n\tvar summaries []dockerimage.Summary\n\terr := apiGetRequest(\"http://d/v1.0.0/images/json\", &summaries)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn utils.SummariesToImages(summaries)\n}\n\nfunc Status() (v1.DockerStatus, error) {\n\tpodmanInfo, err := GetInfo()\n\tif err != nil {\n\t\treturn v1.DockerStatus{}, err\n\t}\n\n\tstatus, err := docker.StatusFromDockerInfo(*podmanInfo)\n\tif err != nil {\n\t\treturn v1.DockerStatus{}, err\n\t}\n\n\tpodmanVersion, err := VersionString()\n\tif err != nil {\n\t\t// status.Version will be \"Unknown\"\n\t\treturn status, err\n\t}\n\tstatus.Version = podmanVersion\n\n\tpodmanAPIVersion, err := APIVersionString()\n\tif err != nil {\n\t\t// status.APIVersion will be \"Unknown\"\n\t\treturn status, err\n\t}\n\tstatus.APIVersion = podmanAPIVersion\n\n\treturn status, nil\n}\n\nfunc GetInfo() (*dockersystem.Info, error) {\n\tvar info dockersystem.Info\n\terr := apiGetRequest(\"http://d/v1.0.0/info\", &info)\n\treturn &info, err\n}\n\nfunc VersionString() (string, error) {\n\tvar version dockersystem.VersionResponse\n\terr := apiGetRequest(\"http://d/v1.0.0/version\", &version)\n\tif err != nil {\n\t\treturn \"Unknown\", err\n\t}\n\n\treturn version.Version, nil\n}\n\nfunc APIVersionString() (string, error) {\n\tvar version dockersystem.VersionResponse\n\terr := apiGetRequest(\"http://d/v1.0.0/version\", &version)\n\tif err != nil {\n\t\treturn \"Unknown\", err\n\t}\n\n\treturn version.APIVersion, nil\n}\n\nfunc InspectContainer(id string) (dockercontainer.InspectResponse, error) {\n\tvar data dockercontainer.InspectResponse\n\terr := apiGetRequest(fmt.Sprintf(\"http://d/v1.0.0/containers/%s/json\", id), &data)\n\treturn data, err\n}\n"
  },
  {
    "path": "container/podman/podman_test.go",
    "content": "// Copyright 2022 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n//go:build linux\n\npackage podman\n\nimport (\n\t\"errors\"\n\t\"net/http\"\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/assert\"\n)\n\nfunc TestValidateResponse(t *testing.T) {\n\tfor _, tc := range []struct {\n\t\tresponse *http.Response\n\t\terr      error\n\t\texpected string\n\t}{\n\t\t{\n\t\t\tresponse: nil,\n\t\t\terr:      nil,\n\t\t\texpected: \"response not present\",\n\t\t},\n\t\t{\n\t\t\tresponse: &http.Response{\n\t\t\t\tStatusCode: http.StatusNotFound,\n\t\t\t},\n\t\t\terr:      errors.New(\"some error\"),\n\t\t\texpected: \"item not found: some error\",\n\t\t},\n\t\t{\n\t\t\tresponse: &http.Response{\n\t\t\t\tStatusCode: http.StatusNotImplemented,\n\t\t\t},\n\t\t\terr:      errors.New(\"some error\"),\n\t\t\texpected: \"query not implemented: some error\",\n\t\t},\n\t\t{\n\t\t\tresponse: &http.Response{\n\t\t\t\tStatusCode: http.StatusOK,\n\t\t\t},\n\t\t\terr:      errors.New(\"some error\"),\n\t\t\texpected: \"some error\",\n\t\t},\n\t\t{\n\t\t\tresponse: &http.Response{\n\t\t\t\tStatusCode: http.StatusOK,\n\t\t\t},\n\t\t\terr:      nil,\n\t\t\texpected: \"\",\n\t\t},\n\t} {\n\t\terr := validateResponse(tc.err, tc.response)\n\t\tif tc.expected != \"\" {\n\t\t\tassert.EqualError(t, err, tc.expected)\n\t\t} else {\n\t\t\tassert.NoError(t, err)\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "container/raw/factory.go",
    "content": "// Copyright 2014 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n//go:build linux\n\npackage raw\n\nimport (\n\t\"flag\"\n\t\"fmt\"\n\t\"strings\"\n\n\t\"github.com/google/cadvisor/container\"\n\t\"github.com/google/cadvisor/container/common\"\n\t\"github.com/google/cadvisor/container/libcontainer\"\n\t\"github.com/google/cadvisor/fs\"\n\tinfo \"github.com/google/cadvisor/info/v1\"\n\twatch \"github.com/google/cadvisor/watcher\"\n\n\t\"k8s.io/klog/v2\"\n)\n\nvar (\n\tDockerOnly             = flag.Bool(\"docker_only\", false, \"Only report docker containers in addition to root stats\")\n\tdisableRootCgroupStats = flag.Bool(\"disable_root_cgroup_stats\", false, \"Disable collecting root Cgroup stats\")\n)\n\ntype rawFactory struct {\n\t// Factory for machine information.\n\tmachineInfoFactory info.MachineInfoFactory\n\n\t// Information about the cgroup subsystems.\n\tcgroupSubsystems map[string]string\n\n\t// Information about mounted filesystems.\n\tfsInfo fs.FsInfo\n\n\t// Watcher for inotify events.\n\twatcher *common.InotifyWatcher\n\n\t// List of metrics to be included.\n\tincludedMetrics map[container.MetricKind]struct{}\n\n\t// List of raw container cgroup path prefix whitelist.\n\trawPrefixWhiteList []string\n}\n\nfunc (f *rawFactory) String() string {\n\treturn \"raw\"\n}\n\nfunc (f *rawFactory) NewContainerHandler(name string, metadataEnvAllowList []string, inHostNamespace bool) (container.ContainerHandler, error) {\n\trootFs := \"/\"\n\tif !inHostNamespace {\n\t\trootFs = \"/rootfs\"\n\t}\n\treturn newRawContainerHandler(name, f.cgroupSubsystems, f.machineInfoFactory, f.fsInfo, f.watcher, rootFs, f.includedMetrics)\n}\n\n// The raw factory can handle any container. If --docker_only is set to true, non-docker containers are ignored except for \"/\" and those whitelisted by raw_cgroup_prefix_whitelist flag.\nfunc (f *rawFactory) CanHandleAndAccept(name string) (bool, bool, error) {\n\tif name == \"/\" {\n\t\treturn true, true, nil\n\t}\n\tif *DockerOnly && f.rawPrefixWhiteList[0] == \"\" {\n\t\treturn true, false, nil\n\t}\n\tfor _, prefix := range f.rawPrefixWhiteList {\n\t\tif strings.HasPrefix(name, prefix) {\n\t\t\treturn true, true, nil\n\t\t}\n\t}\n\treturn true, false, nil\n}\n\nfunc (f *rawFactory) DebugInfo() map[string][]string {\n\treturn common.DebugInfo(f.watcher.GetWatches())\n}\n\nfunc Register(machineInfoFactory info.MachineInfoFactory, fsInfo fs.FsInfo, includedMetrics map[container.MetricKind]struct{}, rawPrefixWhiteList []string) error {\n\tcgroupSubsystems, err := libcontainer.GetCgroupSubsystems(includedMetrics)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to get cgroup subsystems: %v\", err)\n\t}\n\tif len(cgroupSubsystems) == 0 {\n\t\treturn fmt.Errorf(\"failed to find supported cgroup mounts for the raw factory\")\n\t}\n\n\twatcher, err := common.NewInotifyWatcher()\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tklog.V(1).Infof(\"Registering Raw factory\")\n\tfactory := &rawFactory{\n\t\tmachineInfoFactory: machineInfoFactory,\n\t\tfsInfo:             fsInfo,\n\t\tcgroupSubsystems:   cgroupSubsystems,\n\t\twatcher:            watcher,\n\t\tincludedMetrics:    includedMetrics,\n\t\trawPrefixWhiteList: rawPrefixWhiteList,\n\t}\n\tcontainer.RegisterContainerHandlerFactory(factory, []watch.ContainerWatchSource{watch.Raw})\n\treturn nil\n}\n"
  },
  {
    "path": "container/raw/handler.go",
    "content": "// Copyright 2014 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n//go:build linux\n\n// Handler for \"raw\" containers.\npackage raw\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/google/cadvisor/container\"\n\t\"github.com/google/cadvisor/container/common\"\n\t\"github.com/google/cadvisor/container/libcontainer\"\n\t\"github.com/google/cadvisor/fs\"\n\tinfo \"github.com/google/cadvisor/info/v1\"\n\t\"github.com/google/cadvisor/machine\"\n\n\t\"github.com/opencontainers/cgroups\"\n\t\"k8s.io/klog/v2\"\n)\n\ntype rawContainerHandler struct {\n\t// Name of the container for this handler.\n\tname               string\n\tmachineInfoFactory info.MachineInfoFactory\n\n\t// Absolute path to the cgroup hierarchies of this container.\n\t// (e.g.: \"cpu\" -> \"/sys/fs/cgroup/cpu/test\")\n\tcgroupPaths map[string]string\n\n\tfsInfo          fs.FsInfo\n\texternalMounts  []common.Mount\n\tincludedMetrics container.MetricSet\n\n\tlibcontainerHandler *libcontainer.Handler\n}\n\nfunc isRootCgroup(name string) bool {\n\treturn name == \"/\"\n}\n\nfunc newRawContainerHandler(name string, cgroupSubsystems map[string]string, machineInfoFactory info.MachineInfoFactory, fsInfo fs.FsInfo, watcher *common.InotifyWatcher, rootFs string, includedMetrics container.MetricSet) (container.ContainerHandler, error) {\n\tcHints, err := common.GetContainerHintsFromFile(*common.ArgContainerHints)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tcgroupPaths := common.MakeCgroupPaths(cgroupSubsystems, name)\n\n\tcgroupManager, err := libcontainer.NewCgroupManager(name, cgroupPaths)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tvar externalMounts []common.Mount\n\tfor _, container := range cHints.AllHosts {\n\t\tif name == container.FullName {\n\t\t\texternalMounts = container.Mounts\n\t\t\tbreak\n\t\t}\n\t}\n\n\tpid := 0\n\tif isRootCgroup(name) {\n\t\tpid = 1\n\n\t\t// delete pids from cgroup paths because /sys/fs/cgroup/pids/pids.current not exist\n\t\tdelete(cgroupPaths, \"pids\")\n\t}\n\n\thandler := libcontainer.NewHandler(cgroupManager, rootFs, pid, includedMetrics)\n\n\treturn &rawContainerHandler{\n\t\tname:                name,\n\t\tmachineInfoFactory:  machineInfoFactory,\n\t\tcgroupPaths:         cgroupPaths,\n\t\tfsInfo:              fsInfo,\n\t\texternalMounts:      externalMounts,\n\t\tincludedMetrics:     includedMetrics,\n\t\tlibcontainerHandler: handler,\n\t}, nil\n}\n\nfunc (h *rawContainerHandler) ContainerReference() (info.ContainerReference, error) {\n\t// We only know the container by its one name.\n\treturn info.ContainerReference{\n\t\tName: h.name,\n\t}, nil\n}\n\nfunc (h *rawContainerHandler) GetRootNetworkDevices() ([]info.NetInfo, error) {\n\tnd := []info.NetInfo{}\n\tif isRootCgroup(h.name) {\n\t\tmi, err := h.machineInfoFactory.GetMachineInfo()\n\t\tif err != nil {\n\t\t\treturn nd, err\n\t\t}\n\t\treturn mi.NetworkDevices, nil\n\t}\n\treturn nd, nil\n}\n\n// Nothing to start up.\nfunc (h *rawContainerHandler) Start() {}\n\n// Nothing to clean up.\nfunc (h *rawContainerHandler) Cleanup() {}\n\nfunc (h *rawContainerHandler) GetSpec() (info.ContainerSpec, error) {\n\tconst hasNetwork = false\n\thasFilesystem := isRootCgroup(h.name) || len(h.externalMounts) > 0\n\tspec, err := common.GetSpec(h.cgroupPaths, h.machineInfoFactory, hasNetwork, hasFilesystem)\n\tif err != nil {\n\t\treturn spec, err\n\t}\n\n\tif isRootCgroup(h.name) {\n\t\t// Check physical network devices for root container.\n\t\tnd, err := h.GetRootNetworkDevices()\n\t\tif err != nil {\n\t\t\treturn spec, err\n\t\t}\n\t\tspec.HasNetwork = spec.HasNetwork || len(nd) != 0\n\n\t\t// Get memory and swap limits of the running machine\n\t\tmemLimit, err := machine.GetMachineMemoryCapacity()\n\t\tif err != nil {\n\t\t\tklog.Warningf(\"failed to obtain memory limit for machine container\")\n\t\t\tspec.HasMemory = false\n\t\t} else {\n\t\t\tspec.Memory.Limit = uint64(memLimit)\n\t\t\t// Spec is marked to have memory only if the memory limit is set\n\t\t\tspec.HasMemory = true\n\t\t}\n\n\t\tswapLimit, err := machine.GetMachineSwapCapacity()\n\t\tif err != nil {\n\t\t\tklog.Warningf(\"failed to obtain swap limit for machine container\")\n\t\t} else {\n\t\t\tspec.Memory.SwapLimit = uint64(swapLimit)\n\t\t}\n\t}\n\n\treturn spec, nil\n}\n\nfunc fsToFsStats(fs *fs.Fs) info.FsStats {\n\tinodes := uint64(0)\n\tinodesFree := uint64(0)\n\thasInodes := fs.InodesFree != nil\n\tif hasInodes {\n\t\tinodes = *fs.Inodes\n\t\tinodesFree = *fs.InodesFree\n\t}\n\treturn info.FsStats{\n\t\tDevice:          fs.Device,\n\t\tType:            fs.Type.String(),\n\t\tLimit:           fs.Capacity,\n\t\tUsage:           fs.Capacity - fs.Free,\n\t\tHasInodes:       hasInodes,\n\t\tInodes:          inodes,\n\t\tInodesFree:      inodesFree,\n\t\tAvailable:       fs.Available,\n\t\tReadsCompleted:  fs.DiskStats.ReadsCompleted,\n\t\tReadsMerged:     fs.DiskStats.ReadsMerged,\n\t\tSectorsRead:     fs.DiskStats.SectorsRead,\n\t\tReadTime:        fs.DiskStats.ReadTime,\n\t\tWritesCompleted: fs.DiskStats.WritesCompleted,\n\t\tWritesMerged:    fs.DiskStats.WritesMerged,\n\t\tSectorsWritten:  fs.DiskStats.SectorsWritten,\n\t\tWriteTime:       fs.DiskStats.WriteTime,\n\t\tIoInProgress:    fs.DiskStats.IoInProgress,\n\t\tIoTime:          fs.DiskStats.IoTime,\n\t\tWeightedIoTime:  fs.DiskStats.WeightedIoTime,\n\t}\n}\n\nfunc (h *rawContainerHandler) getFsStats(stats *info.ContainerStats) error {\n\tvar filesystems []fs.Fs\n\tvar err error\n\t// Early exist if no disk metrics are to be collected.\n\tif !h.includedMetrics.Has(container.DiskUsageMetrics) && !h.includedMetrics.Has(container.DiskIOMetrics) {\n\t\treturn nil\n\t}\n\n\t// Get Filesystem information only for the root cgroup.\n\tif isRootCgroup(h.name) {\n\t\tfilesystems, err = h.fsInfo.GetGlobalFsInfo()\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t} else {\n\t\tif len(h.externalMounts) > 0 {\n\t\t\tmountSet := make(map[string]struct{})\n\t\t\tfor _, mount := range h.externalMounts {\n\t\t\t\tmountSet[mount.HostDir] = struct{}{}\n\t\t\t}\n\t\t\tfilesystems, err = h.fsInfo.GetFsInfoForPath(mountSet)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\t}\n\n\tif h.includedMetrics.Has(container.DiskUsageMetrics) {\n\t\tfor i := range filesystems {\n\t\t\tfs := filesystems[i]\n\t\t\tstats.Filesystem = append(stats.Filesystem, fsToFsStats(&fs))\n\t\t}\n\t}\n\n\tif h.includedMetrics.Has(container.DiskIOMetrics) {\n\t\tcommon.AssignDeviceNamesToDiskStats(&fsNamer{fs: filesystems, factory: h.machineInfoFactory}, &stats.DiskIo)\n\n\t}\n\treturn nil\n}\n\nfunc (h *rawContainerHandler) GetStats() (*info.ContainerStats, error) {\n\tif *disableRootCgroupStats && isRootCgroup(h.name) {\n\t\treturn nil, nil\n\t}\n\tstats, err := h.libcontainerHandler.GetStats()\n\tif err != nil {\n\t\treturn stats, err\n\t}\n\n\t// Get filesystem stats.\n\terr = h.getFsStats(stats)\n\tif err != nil {\n\t\treturn stats, err\n\t}\n\n\treturn stats, nil\n}\n\nfunc (h *rawContainerHandler) GetCgroupPath(resource string) (string, error) {\n\tvar res string\n\tif !cgroups.IsCgroup2UnifiedMode() {\n\t\tres = resource\n\t}\n\tpath, ok := h.cgroupPaths[res]\n\tif !ok {\n\t\treturn \"\", fmt.Errorf(\"could not find path for resource %q for container %q\", resource, h.name)\n\t}\n\treturn path, nil\n}\n\nfunc (h *rawContainerHandler) GetContainerLabels() map[string]string {\n\treturn map[string]string{}\n}\n\nfunc (h *rawContainerHandler) GetContainerIPAddress() string {\n\t// the IP address for the raw container corresponds to the system ip address.\n\treturn \"127.0.0.1\"\n}\n\nfunc (h *rawContainerHandler) ListContainers(listType container.ListType) ([]info.ContainerReference, error) {\n\treturn common.ListContainers(h.name, h.cgroupPaths, listType)\n}\n\nfunc (h *rawContainerHandler) ListProcesses(listType container.ListType) ([]int, error) {\n\treturn h.libcontainerHandler.GetProcesses()\n}\n\nfunc (h *rawContainerHandler) Exists() bool {\n\treturn common.CgroupExists(h.cgroupPaths)\n}\n\nfunc (h *rawContainerHandler) Type() container.ContainerType {\n\treturn container.ContainerTypeRaw\n}\n\nfunc (h *rawContainerHandler) GetExitCode() (int, error) {\n\treturn -1, fmt.Errorf(\"exit codes not applicable for raw cgroup containers\")\n}\n\ntype fsNamer struct {\n\tfs      []fs.Fs\n\tfactory info.MachineInfoFactory\n\tinfo    common.DeviceNamer\n}\n\nfunc (n *fsNamer) DeviceName(major, minor uint64) (string, bool) {\n\tfor _, info := range n.fs {\n\t\tif uint64(info.Major) == major && uint64(info.Minor) == minor {\n\t\t\treturn info.Device, true\n\t\t}\n\t}\n\tif n.info == nil {\n\t\tmi, err := n.factory.GetMachineInfo()\n\t\tif err != nil {\n\t\t\treturn \"\", false\n\t\t}\n\t\tn.info = (*common.MachineInfoNamer)(mi)\n\t}\n\treturn n.info.DeviceName(major, minor)\n}\n"
  },
  {
    "path": "container/raw/handler_test.go",
    "content": "// Copyright 2016 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n//go:build linux\n\n// Handler for \"raw\" containers.\npackage raw\n\nimport (\n\t\"reflect\"\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/assert\"\n\n\t\"github.com/google/cadvisor/container\"\n\t\"github.com/google/cadvisor/container/common\"\n\t\"github.com/google/cadvisor/fs\"\n\tinfo \"github.com/google/cadvisor/info/v1\"\n)\n\nfunc TestFsToFsStats(t *testing.T) {\n\tinodes := uint64(100)\n\tinodesFree := uint64(50)\n\ttestCases := map[string]struct {\n\t\tfs       *fs.Fs\n\t\texpected info.FsStats\n\t}{\n\t\t\"has_inodes\": {\n\t\t\tfs: &fs.Fs{\n\t\t\t\tDeviceInfo: fs.DeviceInfo{Device: \"123\"},\n\t\t\t\tType:       fs.VFS,\n\t\t\t\tCapacity:   uint64(1024 * 1024),\n\t\t\t\tFree:       uint64(1024),\n\t\t\t\tAvailable:  uint64(1024),\n\t\t\t\tInodes:     &inodes,\n\t\t\t\tInodesFree: &inodesFree,\n\t\t\t\tDiskStats: fs.DiskStats{\n\t\t\t\t\tReadsCompleted:  uint64(100),\n\t\t\t\t\tReadsMerged:     uint64(100),\n\t\t\t\t\tSectorsRead:     uint64(100),\n\t\t\t\t\tReadTime:        uint64(100),\n\t\t\t\t\tWritesCompleted: uint64(100),\n\t\t\t\t\tWritesMerged:    uint64(100),\n\t\t\t\t\tSectorsWritten:  uint64(100),\n\t\t\t\t\tWriteTime:       uint64(100),\n\t\t\t\t\tIoInProgress:    uint64(100),\n\t\t\t\t\tIoTime:          uint64(100),\n\t\t\t\t\tWeightedIoTime:  uint64(100),\n\t\t\t\t},\n\t\t\t},\n\t\t\texpected: info.FsStats{\n\t\t\t\tDevice:          \"123\",\n\t\t\t\tType:            fs.VFS.String(),\n\t\t\t\tLimit:           uint64(1024 * 1024),\n\t\t\t\tUsage:           uint64(1024*1024) - uint64(1024),\n\t\t\t\tHasInodes:       true,\n\t\t\t\tInodes:          inodes,\n\t\t\t\tInodesFree:      inodesFree,\n\t\t\t\tAvailable:       uint64(1024),\n\t\t\t\tReadsCompleted:  uint64(100),\n\t\t\t\tReadsMerged:     uint64(100),\n\t\t\t\tSectorsRead:     uint64(100),\n\t\t\t\tReadTime:        uint64(100),\n\t\t\t\tWritesCompleted: uint64(100),\n\t\t\t\tWritesMerged:    uint64(100),\n\t\t\t\tSectorsWritten:  uint64(100),\n\t\t\t\tWriteTime:       uint64(100),\n\t\t\t\tIoInProgress:    uint64(100),\n\t\t\t\tIoTime:          uint64(100),\n\t\t\t\tWeightedIoTime:  uint64(100),\n\t\t\t},\n\t\t},\n\t\t\"has_no_inodes\": {\n\t\t\tfs: &fs.Fs{\n\t\t\t\tDeviceInfo: fs.DeviceInfo{Device: \"123\"},\n\t\t\t\tType:       fs.DeviceMapper,\n\t\t\t\tCapacity:   uint64(1024 * 1024),\n\t\t\t\tFree:       uint64(1024),\n\t\t\t\tAvailable:  uint64(1024),\n\t\t\t\tDiskStats: fs.DiskStats{\n\t\t\t\t\tReadsCompleted:  uint64(100),\n\t\t\t\t\tReadsMerged:     uint64(100),\n\t\t\t\t\tSectorsRead:     uint64(100),\n\t\t\t\t\tReadTime:        uint64(100),\n\t\t\t\t\tWritesCompleted: uint64(100),\n\t\t\t\t\tWritesMerged:    uint64(100),\n\t\t\t\t\tSectorsWritten:  uint64(100),\n\t\t\t\t\tWriteTime:       uint64(100),\n\t\t\t\t\tIoInProgress:    uint64(100),\n\t\t\t\t\tIoTime:          uint64(100),\n\t\t\t\t\tWeightedIoTime:  uint64(100),\n\t\t\t\t},\n\t\t\t},\n\t\t\texpected: info.FsStats{\n\t\t\t\tDevice:          \"123\",\n\t\t\t\tType:            fs.DeviceMapper.String(),\n\t\t\t\tLimit:           uint64(1024 * 1024),\n\t\t\t\tUsage:           uint64(1024*1024) - uint64(1024),\n\t\t\t\tHasInodes:       false,\n\t\t\t\tAvailable:       uint64(1024),\n\t\t\t\tReadsCompleted:  uint64(100),\n\t\t\t\tReadsMerged:     uint64(100),\n\t\t\t\tSectorsRead:     uint64(100),\n\t\t\t\tReadTime:        uint64(100),\n\t\t\t\tWritesCompleted: uint64(100),\n\t\t\t\tWritesMerged:    uint64(100),\n\t\t\t\tSectorsWritten:  uint64(100),\n\t\t\t\tWriteTime:       uint64(100),\n\t\t\t\tIoInProgress:    uint64(100),\n\t\t\t\tIoTime:          uint64(100),\n\t\t\t\tWeightedIoTime:  uint64(100),\n\t\t\t},\n\t\t},\n\t}\n\tfor testName, testCase := range testCases {\n\t\tactual := fsToFsStats(testCase.fs)\n\t\tif !reflect.DeepEqual(testCase.expected, actual) {\n\t\t\tt.Errorf(\"test case=%v, expected=%v, actual=%v\", testName, testCase.expected, actual)\n\t\t}\n\t}\n}\n\nfunc TestGetFsStats(t *testing.T) {\n\tinodes := uint64(2000)\n\tinodesFree := uint64(1000)\n\n\tcases := map[string]struct {\n\t\tname                string\n\t\tincludedMetrics     container.MetricSet\n\t\texternalMounts      []common.Mount\n\t\tglobalFsInfo        func() ([]fs.Fs, error)\n\t\tgetFsInfoForPath    func(mountSet map[string]struct{}) ([]fs.Fs, error)\n\t\tdiskIO              info.DiskIoStats\n\t\texpectedFilesystems []info.FsStats\n\t\texpectedDiskIO      info.DiskIoStats\n\t}{\n\t\t\"root with disk metrics enabled\": {\n\t\t\tname:            \"/\",\n\t\t\tincludedMetrics: container.MetricSet{container.DiskUsageMetrics: struct{}{}, container.DiskIOMetrics: struct{}{}},\n\t\t\texternalMounts:  []common.Mount{},\n\t\t\tglobalFsInfo: func() ([]fs.Fs, error) {\n\t\t\t\treturn []fs.Fs{{\n\t\t\t\t\tDeviceInfo: fs.DeviceInfo{\n\t\t\t\t\t\tDevice: \"123\",\n\t\t\t\t\t\tMajor:  1,\n\t\t\t\t\t\tMinor:  2,\n\t\t\t\t\t},\n\t\t\t\t\tType:       \"devicemapper\",\n\t\t\t\t\tCapacity:   1000,\n\t\t\t\t\tFree:       500,\n\t\t\t\t\tAvailable:  450,\n\t\t\t\t\tInodes:     &inodes,\n\t\t\t\t\tInodesFree: &inodesFree,\n\t\t\t\t\tDiskStats: fs.DiskStats{\n\t\t\t\t\t\tReadsCompleted:  1,\n\t\t\t\t\t\tReadsMerged:     2,\n\t\t\t\t\t\tSectorsRead:     3,\n\t\t\t\t\t\tReadTime:        3,\n\t\t\t\t\t\tWritesCompleted: 4,\n\t\t\t\t\t\tWritesMerged:    6,\n\t\t\t\t\t\tSectorsWritten:  7,\n\t\t\t\t\t\tWriteTime:       8,\n\t\t\t\t\t\tIoInProgress:    9,\n\t\t\t\t\t\tIoTime:          10,\n\t\t\t\t\t\tWeightedIoTime:  11,\n\t\t\t\t\t},\n\t\t\t\t}}, nil\n\t\t\t},\n\t\t\texpectedFilesystems: []info.FsStats{\n\t\t\t\t{\n\t\t\t\t\tDevice:          \"123\",\n\t\t\t\t\tType:            \"devicemapper\",\n\t\t\t\t\tLimit:           1000,\n\t\t\t\t\tUsage:           500,\n\t\t\t\t\tBaseUsage:       0,\n\t\t\t\t\tAvailable:       450,\n\t\t\t\t\tHasInodes:       true,\n\t\t\t\t\tInodes:          2000,\n\t\t\t\t\tInodesFree:      1000,\n\t\t\t\t\tReadsCompleted:  1,\n\t\t\t\t\tReadsMerged:     2,\n\t\t\t\t\tSectorsRead:     3,\n\t\t\t\t\tReadTime:        3,\n\t\t\t\t\tWritesCompleted: 4,\n\t\t\t\t\tWritesMerged:    6,\n\t\t\t\t\tSectorsWritten:  7,\n\t\t\t\t\tWriteTime:       8,\n\t\t\t\t\tIoInProgress:    9,\n\t\t\t\t\tIoTime:          10,\n\t\t\t\t\tWeightedIoTime:  11,\n\t\t\t\t},\n\t\t\t},\n\t\t\texpectedDiskIO: info.DiskIoStats{\n\t\t\t\tIoServiceBytes: []info.PerDiskStats{\n\t\t\t\t\t{\n\t\t\t\t\t\tDevice: \"123\",\n\t\t\t\t\t\tMajor:  1,\n\t\t\t\t\t\tMinor:  2,\n\t\t\t\t\t\tStats:  map[string]uint64{\"a\": 1},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\tdiskIO: info.DiskIoStats{\n\t\t\t\tIoServiceBytes: []info.PerDiskStats{\n\t\t\t\t\t{\n\t\t\t\t\t\tDevice: \"\",\n\t\t\t\t\t\tMajor:  1,\n\t\t\t\t\t\tMinor:  2,\n\t\t\t\t\t\tStats:  map[string]uint64{\"a\": 1},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t\"root with disk usage metrics enabled\": {\n\t\t\tname:            \"/\",\n\t\t\tincludedMetrics: container.MetricSet{container.DiskUsageMetrics: struct{}{}},\n\t\t\texternalMounts:  []common.Mount{},\n\t\t\tglobalFsInfo: func() ([]fs.Fs, error) {\n\t\t\t\treturn []fs.Fs{{\n\t\t\t\t\tDeviceInfo: fs.DeviceInfo{\n\t\t\t\t\t\tDevice: \"123\",\n\t\t\t\t\t\tMajor:  1,\n\t\t\t\t\t\tMinor:  2,\n\t\t\t\t\t},\n\t\t\t\t\tType:       \"devicemapper\",\n\t\t\t\t\tCapacity:   1000,\n\t\t\t\t\tFree:       500,\n\t\t\t\t\tAvailable:  450,\n\t\t\t\t\tInodes:     &inodes,\n\t\t\t\t\tInodesFree: &inodesFree,\n\t\t\t\t\tDiskStats: fs.DiskStats{\n\t\t\t\t\t\tReadsCompleted:  1,\n\t\t\t\t\t\tReadsMerged:     2,\n\t\t\t\t\t\tSectorsRead:     3,\n\t\t\t\t\t\tReadTime:        3,\n\t\t\t\t\t\tWritesCompleted: 4,\n\t\t\t\t\t\tWritesMerged:    6,\n\t\t\t\t\t\tSectorsWritten:  7,\n\t\t\t\t\t\tWriteTime:       8,\n\t\t\t\t\t\tIoInProgress:    9,\n\t\t\t\t\t\tIoTime:          10,\n\t\t\t\t\t\tWeightedIoTime:  11,\n\t\t\t\t\t},\n\t\t\t\t}}, nil\n\t\t\t},\n\t\t\texpectedFilesystems: []info.FsStats{\n\t\t\t\t{\n\t\t\t\t\tDevice:          \"123\",\n\t\t\t\t\tType:            \"devicemapper\",\n\t\t\t\t\tLimit:           1000,\n\t\t\t\t\tUsage:           500,\n\t\t\t\t\tBaseUsage:       0,\n\t\t\t\t\tAvailable:       450,\n\t\t\t\t\tHasInodes:       true,\n\t\t\t\t\tInodes:          2000,\n\t\t\t\t\tInodesFree:      1000,\n\t\t\t\t\tReadsCompleted:  1,\n\t\t\t\t\tReadsMerged:     2,\n\t\t\t\t\tSectorsRead:     3,\n\t\t\t\t\tReadTime:        3,\n\t\t\t\t\tWritesCompleted: 4,\n\t\t\t\t\tWritesMerged:    6,\n\t\t\t\t\tSectorsWritten:  7,\n\t\t\t\t\tWriteTime:       8,\n\t\t\t\t\tIoInProgress:    9,\n\t\t\t\t\tIoTime:          10,\n\t\t\t\t\tWeightedIoTime:  11,\n\t\t\t\t},\n\t\t\t},\n\t\t\t// DiskIoStats must not be enriched with device name.\n\t\t\t// This is imperfect check but I can't find any other.\n\t\t\texpectedDiskIO: info.DiskIoStats{\n\t\t\t\tIoServiceBytes: []info.PerDiskStats{\n\t\t\t\t\t{\n\t\t\t\t\t\tDevice: \"\",\n\t\t\t\t\t\tMajor:  1,\n\t\t\t\t\t\tMinor:  2,\n\t\t\t\t\t\tStats:  map[string]uint64{\"a\": 1},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\tdiskIO: info.DiskIoStats{\n\t\t\t\tIoServiceBytes: []info.PerDiskStats{\n\t\t\t\t\t{\n\t\t\t\t\t\tDevice: \"\",\n\t\t\t\t\t\tMajor:  1,\n\t\t\t\t\t\tMinor:  2,\n\t\t\t\t\t\tStats:  map[string]uint64{\"a\": 1},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t\"root with disk I/O metrics enabled\": {\n\t\t\tname:            \"/\",\n\t\t\tincludedMetrics: container.MetricSet{container.DiskIOMetrics: struct{}{}},\n\t\t\texternalMounts:  []common.Mount{},\n\t\t\tglobalFsInfo: func() ([]fs.Fs, error) {\n\t\t\t\treturn []fs.Fs{{\n\t\t\t\t\tDeviceInfo: fs.DeviceInfo{\n\t\t\t\t\t\tDevice: \"123\",\n\t\t\t\t\t\tMajor:  1,\n\t\t\t\t\t\tMinor:  2,\n\t\t\t\t\t},\n\t\t\t\t\tType:       \"devicemapper\",\n\t\t\t\t\tCapacity:   1000,\n\t\t\t\t\tFree:       500,\n\t\t\t\t\tAvailable:  450,\n\t\t\t\t\tInodes:     &inodes,\n\t\t\t\t\tInodesFree: &inodesFree,\n\t\t\t\t\tDiskStats: fs.DiskStats{\n\t\t\t\t\t\tReadsCompleted:  1,\n\t\t\t\t\t\tReadsMerged:     2,\n\t\t\t\t\t\tSectorsRead:     3,\n\t\t\t\t\t\tReadTime:        3,\n\t\t\t\t\t\tWritesCompleted: 4,\n\t\t\t\t\t\tWritesMerged:    6,\n\t\t\t\t\t\tSectorsWritten:  7,\n\t\t\t\t\t\tWriteTime:       8,\n\t\t\t\t\t\tIoInProgress:    9,\n\t\t\t\t\t\tIoTime:          10,\n\t\t\t\t\t\tWeightedIoTime:  11,\n\t\t\t\t\t},\n\t\t\t\t}}, nil\n\t\t\t},\n\t\t\texpectedDiskIO: info.DiskIoStats{\n\t\t\t\tIoServiceBytes: []info.PerDiskStats{\n\t\t\t\t\t{\n\t\t\t\t\t\tDevice: \"123\",\n\t\t\t\t\t\tMajor:  1,\n\t\t\t\t\t\tMinor:  2,\n\t\t\t\t\t\tStats:  map[string]uint64{\"a\": 1},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\tdiskIO: info.DiskIoStats{\n\t\t\t\tIoServiceBytes: []info.PerDiskStats{\n\t\t\t\t\t{\n\t\t\t\t\t\tDevice: \"\",\n\t\t\t\t\t\tMajor:  1,\n\t\t\t\t\t\tMinor:  2,\n\t\t\t\t\t\tStats:  map[string]uint64{\"a\": 1},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t\"root with disk metrics disabled\": {\n\t\t\tname:            \"/\",\n\t\t\tincludedMetrics: container.MetricSet{},\n\t\t\texternalMounts:  []common.Mount{},\n\t\t\t// DiskIoStats must not be enriched with device name.\n\t\t\t// This is imperfect check but I can't find any other.\n\t\t\texpectedDiskIO: info.DiskIoStats{\n\t\t\t\tIoServiceBytes: []info.PerDiskStats{\n\t\t\t\t\t{\n\t\t\t\t\t\tDevice: \"\",\n\t\t\t\t\t\tMajor:  1,\n\t\t\t\t\t\tMinor:  2,\n\t\t\t\t\t\tStats:  map[string]uint64{\"a\": 1},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\tdiskIO: info.DiskIoStats{\n\t\t\t\tIoServiceBytes: []info.PerDiskStats{\n\t\t\t\t\t{\n\t\t\t\t\t\tDevice: \"\",\n\t\t\t\t\t\tMajor:  1,\n\t\t\t\t\t\tMinor:  2,\n\t\t\t\t\t\tStats:  map[string]uint64{\"a\": 1},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t\"random container with disk metrics enabled\": {\n\t\t\tname:            \"/random/container\",\n\t\t\tincludedMetrics: container.MetricSet{container.DiskUsageMetrics: struct{}{}, container.DiskIOMetrics: struct{}{}},\n\t\t\texternalMounts: []common.Mount{\n\t\t\t\t{HostDir: \"/\", ContainerDir: \"/\"},\n\t\t\t\t{HostDir: \"/random\", ContainerDir: \"/completely/random\"},\n\t\t\t},\n\t\t\tgetFsInfoForPath: func(mountSet map[string]struct{}) ([]fs.Fs, error) {\n\t\t\t\treturn []fs.Fs{\n\t\t\t\t\t{\n\t\t\t\t\t\tDeviceInfo: fs.DeviceInfo{\n\t\t\t\t\t\t\tDevice: \"123\",\n\t\t\t\t\t\t\tMajor:  1,\n\t\t\t\t\t\t\tMinor:  2,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tType:       \"devicemapper\",\n\t\t\t\t\t\tCapacity:   1000,\n\t\t\t\t\t\tFree:       500,\n\t\t\t\t\t\tAvailable:  450,\n\t\t\t\t\t\tInodes:     &inodes,\n\t\t\t\t\t\tInodesFree: &inodesFree,\n\t\t\t\t\t\tDiskStats: fs.DiskStats{\n\t\t\t\t\t\t\tReadsCompleted:  1,\n\t\t\t\t\t\t\tReadsMerged:     2,\n\t\t\t\t\t\t\tSectorsRead:     3,\n\t\t\t\t\t\t\tReadTime:        3,\n\t\t\t\t\t\t\tWritesCompleted: 4,\n\t\t\t\t\t\t\tWritesMerged:    6,\n\t\t\t\t\t\t\tSectorsWritten:  7,\n\t\t\t\t\t\t\tWriteTime:       8,\n\t\t\t\t\t\t\tIoInProgress:    9,\n\t\t\t\t\t\t\tIoTime:          10,\n\t\t\t\t\t\t\tWeightedIoTime:  11,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tDeviceInfo: fs.DeviceInfo{\n\t\t\t\t\t\t\tDevice: \"246\",\n\t\t\t\t\t\t\tMajor:  3,\n\t\t\t\t\t\t\tMinor:  4,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tType:       \"devicemapper\",\n\t\t\t\t\t\tCapacity:   2000,\n\t\t\t\t\t\tFree:       1000,\n\t\t\t\t\t\tAvailable:  900,\n\t\t\t\t\t\tInodes:     &inodes,\n\t\t\t\t\t\tInodesFree: &inodesFree,\n\t\t\t\t\t\tDiskStats: fs.DiskStats{\n\t\t\t\t\t\t\tReadsCompleted:  10,\n\t\t\t\t\t\t\tReadsMerged:     20,\n\t\t\t\t\t\t\tSectorsRead:     25,\n\t\t\t\t\t\t\tReadTime:        30,\n\t\t\t\t\t\t\tWritesCompleted: 40,\n\t\t\t\t\t\t\tWritesMerged:    60,\n\t\t\t\t\t\t\tSectorsWritten:  70,\n\t\t\t\t\t\t\tWriteTime:       80,\n\t\t\t\t\t\t\tIoInProgress:    90,\n\t\t\t\t\t\t\tIoTime:          100,\n\t\t\t\t\t\t\tWeightedIoTime:  110,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t}, nil\n\t\t\t},\n\t\t\texpectedFilesystems: []info.FsStats{\n\t\t\t\t{\n\t\t\t\t\tDevice:          \"123\",\n\t\t\t\t\tType:            \"devicemapper\",\n\t\t\t\t\tLimit:           1000,\n\t\t\t\t\tUsage:           500,\n\t\t\t\t\tBaseUsage:       0,\n\t\t\t\t\tAvailable:       450,\n\t\t\t\t\tHasInodes:       true,\n\t\t\t\t\tInodes:          2000,\n\t\t\t\t\tInodesFree:      1000,\n\t\t\t\t\tReadsCompleted:  1,\n\t\t\t\t\tReadsMerged:     2,\n\t\t\t\t\tSectorsRead:     3,\n\t\t\t\t\tReadTime:        3,\n\t\t\t\t\tWritesCompleted: 4,\n\t\t\t\t\tWritesMerged:    6,\n\t\t\t\t\tSectorsWritten:  7,\n\t\t\t\t\tWriteTime:       8,\n\t\t\t\t\tIoInProgress:    9,\n\t\t\t\t\tIoTime:          10,\n\t\t\t\t\tWeightedIoTime:  11,\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tDevice:          \"246\",\n\t\t\t\t\tType:            \"devicemapper\",\n\t\t\t\t\tLimit:           2000,\n\t\t\t\t\tUsage:           1000,\n\t\t\t\t\tBaseUsage:       0,\n\t\t\t\t\tAvailable:       900,\n\t\t\t\t\tHasInodes:       true,\n\t\t\t\t\tInodes:          2000,\n\t\t\t\t\tInodesFree:      1000,\n\t\t\t\t\tReadsCompleted:  10,\n\t\t\t\t\tReadsMerged:     20,\n\t\t\t\t\tSectorsRead:     25,\n\t\t\t\t\tReadTime:        30,\n\t\t\t\t\tWritesCompleted: 40,\n\t\t\t\t\tWritesMerged:    60,\n\t\t\t\t\tSectorsWritten:  70,\n\t\t\t\t\tWriteTime:       80,\n\t\t\t\t\tIoInProgress:    90,\n\t\t\t\t\tIoTime:          100,\n\t\t\t\t\tWeightedIoTime:  110,\n\t\t\t\t},\n\t\t\t},\n\t\t\texpectedDiskIO: info.DiskIoStats{\n\t\t\t\tIoServiceBytes: []info.PerDiskStats{\n\t\t\t\t\t{\n\t\t\t\t\t\tDevice: \"123\",\n\t\t\t\t\t\tMajor:  1,\n\t\t\t\t\t\tMinor:  2,\n\t\t\t\t\t\tStats:  map[string]uint64{\"a\": 1},\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tDevice: \"246\",\n\t\t\t\t\t\tMajor:  3,\n\t\t\t\t\t\tMinor:  4,\n\t\t\t\t\t\tStats:  map[string]uint64{\"b\": 2},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\tdiskIO: info.DiskIoStats{\n\t\t\t\tIoServiceBytes: []info.PerDiskStats{\n\t\t\t\t\t{\n\t\t\t\t\t\tDevice: \"\",\n\t\t\t\t\t\tMajor:  1,\n\t\t\t\t\t\tMinor:  2,\n\t\t\t\t\t\tStats:  map[string]uint64{\"a\": 1},\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tDevice: \"\",\n\t\t\t\t\t\tMajor:  3,\n\t\t\t\t\t\tMinor:  4,\n\t\t\t\t\t\tStats:  map[string]uint64{\"b\": 2},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\n\tfor name, c := range cases {\n\t\tt.Run(name, func(t *testing.T) {\n\t\t\thandler := rawContainerHandler{\n\t\t\t\tname:               c.name,\n\t\t\t\tincludedMetrics:    c.includedMetrics,\n\t\t\t\tfsInfo:             fsInfo{c.globalFsInfo, c.getFsInfoForPath},\n\t\t\t\texternalMounts:     c.externalMounts,\n\t\t\t\tmachineInfoFactory: machineInfo{},\n\t\t\t}\n\t\t\tstats := &info.ContainerStats{DiskIo: c.diskIO}\n\t\t\terr := handler.getFsStats(stats)\n\n\t\t\tassert.NoError(t, err)\n\t\t\tassert.Len(t, stats.Filesystem, len(c.expectedFilesystems))\n\t\t\tassert.Equal(t, c.expectedFilesystems, stats.Filesystem)\n\t\t\tassert.Equal(t, c.expectedDiskIO, stats.DiskIo)\n\t\t})\n\t}\n}\n\ntype fsInfo struct {\n\tglobalFsInfo     func() ([]fs.Fs, error)\n\tgetFsInfoForPath func(mountSet map[string]struct{}) ([]fs.Fs, error)\n}\n\nfunc (f fsInfo) GetGlobalFsInfo() ([]fs.Fs, error) {\n\treturn f.globalFsInfo()\n}\n\nfunc (f fsInfo) GetFsInfoForPath(mountSet map[string]struct{}) ([]fs.Fs, error) {\n\treturn f.getFsInfoForPath(mountSet)\n}\n\nfunc (f fsInfo) GetDirUsage(_ string) (fs.UsageInfo, error) {\n\tpanic(\"unsupported\")\n}\n\nfunc (f fsInfo) GetDeviceInfoByFsUUID(_ string) (*fs.DeviceInfo, error) {\n\tpanic(\"unsupported\")\n}\n\nfunc (f fsInfo) GetDirFsDevice(_ string) (*fs.DeviceInfo, error) {\n\tpanic(\"unsupported\")\n}\n\nfunc (f fsInfo) GetDeviceForLabel(_ string) (string, error) {\n\tpanic(\"unsupported\")\n}\n\nfunc (f fsInfo) GetLabelsForDevice(_ string) ([]string, error) {\n\tpanic(\"unsupported\")\n}\n\nfunc (f fsInfo) GetMountpointForDevice(_ string) (string, error) {\n\tpanic(\"unsupported\")\n}\n\ntype machineInfo struct{}\n\nfunc (m machineInfo) GetMachineInfo() (*info.MachineInfo, error) {\n\treturn &info.MachineInfo{\n\t\tDiskMap: map[string]info.DiskInfo{\n\t\t\t\"1:2\": {\n\t\t\t\tName:      \"sda\",\n\t\t\t\tSize:      1234,\n\t\t\t\tScheduler: \"none\",\n\t\t\t},\n\t\t\t\"3:4\": {\n\t\t\t\tName:      \"sdb\",\n\t\t\t\tSize:      5678,\n\t\t\t\tScheduler: \"none\",\n\t\t\t},\n\t\t},\n\t}, nil\n}\n\nfunc (m machineInfo) GetVersionInfo() (*info.VersionInfo, error) {\n\tpanic(\"unsupported\")\n}\n"
  },
  {
    "path": "container/raw/watcher.go",
    "content": "// Copyright 2014 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n//go:build linux\n\n// Package container defines types for sub-container events and also\n// defines an interface for container operation handlers.\npackage raw\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\t\"path\"\n\t\"strings\"\n\n\tinotify \"k8s.io/utils/inotify\"\n\n\t\"github.com/google/cadvisor/container\"\n\t\"github.com/google/cadvisor/container/common\"\n\t\"github.com/google/cadvisor/container/libcontainer\"\n\t\"github.com/google/cadvisor/watcher\"\n\n\t\"k8s.io/klog/v2\"\n)\n\ntype rawContainerWatcher struct {\n\t// Absolute path to the root of the cgroup hierarchies\n\tcgroupPaths map[string]string\n\n\t// Inotify event watcher.\n\twatcher *common.InotifyWatcher\n\n\t// Signal for watcher thread to stop.\n\tstopWatcher chan error\n}\n\nfunc NewRawContainerWatcher(includedMetrics container.MetricSet) (watcher.ContainerWatcher, error) {\n\tcgroupSubsystems, err := libcontainer.GetCgroupSubsystems(includedMetrics)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to get cgroup subsystems: %v\", err)\n\t}\n\tif len(cgroupSubsystems) == 0 {\n\t\treturn nil, fmt.Errorf(\"failed to find supported cgroup mounts for the raw factory\")\n\t}\n\n\twatcher, err := common.NewInotifyWatcher()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\trawWatcher := &rawContainerWatcher{\n\t\tcgroupPaths: cgroupSubsystems,\n\t\twatcher:     watcher,\n\t\tstopWatcher: make(chan error),\n\t}\n\n\treturn rawWatcher, nil\n}\n\nfunc (w *rawContainerWatcher) Start(events chan watcher.ContainerEvent) error {\n\t// Watch this container (all its cgroups) and all subdirectories.\n\twatched := make([]string, 0)\n\tfor _, cgroupPath := range w.cgroupPaths {\n\t\t_, err := w.watchDirectory(events, cgroupPath, \"/\")\n\t\tif err != nil {\n\t\t\tfor _, watchedCgroupPath := range watched {\n\t\t\t\t_, removeErr := w.watcher.RemoveWatch(\"/\", watchedCgroupPath)\n\t\t\t\tif removeErr != nil {\n\t\t\t\t\tklog.Warningf(\"Failed to remove inotify watch for %q with error: %v\", watchedCgroupPath, removeErr)\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn err\n\t\t}\n\t\twatched = append(watched, cgroupPath)\n\t}\n\n\t// Process the events received from the kernel.\n\tgo func() {\n\t\tfor {\n\t\t\tselect {\n\t\t\tcase event := <-w.watcher.Event():\n\t\t\t\terr := w.processEvent(event, events)\n\t\t\t\tif err != nil {\n\t\t\t\t\tklog.Warningf(\"Error while processing event (%+v): %v\", event, err)\n\t\t\t\t}\n\t\t\tcase err := <-w.watcher.Error():\n\t\t\t\tklog.Warningf(\"Error while watching %q: %v\", \"/\", err)\n\t\t\tcase <-w.stopWatcher:\n\t\t\t\terr := w.watcher.Close()\n\t\t\t\tif err == nil {\n\t\t\t\t\tw.stopWatcher <- err\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}()\n\n\treturn nil\n}\n\nfunc (w *rawContainerWatcher) Stop() error {\n\t// Rendezvous with the watcher thread.\n\tw.stopWatcher <- nil\n\treturn <-w.stopWatcher\n}\n\n// Watches the specified directory and all subdirectories. Returns whether the path was\n// already being watched and an error (if any).\nfunc (w *rawContainerWatcher) watchDirectory(events chan watcher.ContainerEvent, dir string, containerName string) (bool, error) {\n\t// Don't watch .mount cgroups because they never have containers as sub-cgroups.  A single container\n\t// can have many .mount cgroups associated with it which can quickly exhaust the inotify watches on a node.\n\tif strings.HasSuffix(containerName, \".mount\") {\n\t\treturn false, nil\n\t}\n\talreadyWatching, err := w.watcher.AddWatch(containerName, dir)\n\tif err != nil {\n\t\treturn alreadyWatching, err\n\t}\n\n\t// Remove the watch if further operations failed.\n\tcleanup := true\n\tdefer func() {\n\t\tif cleanup {\n\t\t\t_, err := w.watcher.RemoveWatch(containerName, dir)\n\t\t\tif err != nil {\n\t\t\t\tklog.Warningf(\"Failed to remove inotify watch for %q: %v\", dir, err)\n\t\t\t}\n\t\t}\n\t}()\n\n\t// TODO(vmarmol): We should re-do this once we're done to ensure directories were not added in the meantime.\n\t// Watch subdirectories as well.\n\tentries, err := os.ReadDir(dir)\n\tif err != nil {\n\t\treturn alreadyWatching, err\n\t}\n\tfor _, entry := range entries {\n\t\tif entry.IsDir() {\n\t\t\tentryPath := path.Join(dir, entry.Name())\n\t\t\tsubcontainerName := path.Join(containerName, entry.Name())\n\t\t\talreadyWatchingSubDir, err := w.watchDirectory(events, entryPath, subcontainerName)\n\t\t\tif err != nil {\n\t\t\t\tklog.Errorf(\"Failed to watch directory %q: %v\", entryPath, err)\n\t\t\t\tif os.IsNotExist(err) {\n\t\t\t\t\t// The directory may have been removed before watching. Try to watch the other\n\t\t\t\t\t// subdirectories. (https://github.com/kubernetes/kubernetes/issues/28997)\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\treturn alreadyWatching, err\n\t\t\t}\n\t\t\t// since we already missed the creation event for this directory, publish an event here.\n\t\t\tif !alreadyWatchingSubDir {\n\t\t\t\tgo func() {\n\t\t\t\t\tevents <- watcher.ContainerEvent{\n\t\t\t\t\t\tEventType:   watcher.ContainerAdd,\n\t\t\t\t\t\tName:        subcontainerName,\n\t\t\t\t\t\tWatchSource: watcher.Raw,\n\t\t\t\t\t}\n\t\t\t\t}()\n\t\t\t}\n\t\t}\n\t}\n\n\tcleanup = false\n\treturn alreadyWatching, nil\n}\n\nfunc (w *rawContainerWatcher) processEvent(event *inotify.Event, events chan watcher.ContainerEvent) error {\n\t// Convert the inotify event type to a container create or delete.\n\tvar eventType watcher.ContainerEventType\n\tswitch {\n\tcase (event.Mask & inotify.InCreate) > 0:\n\t\teventType = watcher.ContainerAdd\n\tcase (event.Mask & inotify.InDelete) > 0:\n\t\teventType = watcher.ContainerDelete\n\tcase (event.Mask & inotify.InMovedFrom) > 0:\n\t\teventType = watcher.ContainerDelete\n\tcase (event.Mask & inotify.InMovedTo) > 0:\n\t\teventType = watcher.ContainerAdd\n\tdefault:\n\t\t// Ignore other events.\n\t\treturn nil\n\t}\n\n\t// Derive the container name from the path name.\n\tvar containerName string\n\tfor _, mount := range w.cgroupPaths {\n\t\tmountLocation := path.Clean(mount) + \"/\"\n\t\tif strings.HasPrefix(event.Name, mountLocation) {\n\t\t\tcontainerName = event.Name[len(mountLocation)-1:]\n\t\t\tbreak\n\t\t}\n\t}\n\tif containerName == \"\" {\n\t\treturn fmt.Errorf(\"unable to detect container from watch event on directory %q\", event.Name)\n\t}\n\n\t// Maintain the watch for the new or deleted container.\n\tswitch eventType {\n\tcase watcher.ContainerAdd:\n\t\t// New container was created, watch it.\n\t\talreadyWatched, err := w.watchDirectory(events, event.Name, containerName)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\t// Only report container creation once.\n\t\tif alreadyWatched {\n\t\t\treturn nil\n\t\t}\n\tcase watcher.ContainerDelete:\n\t\t// Container was deleted, stop watching for it.\n\t\tlastWatched, err := w.watcher.RemoveWatch(containerName, event.Name)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\t// Only report container deletion once.\n\t\tif !lastWatched {\n\t\t\treturn nil\n\t\t}\n\tdefault:\n\t\treturn fmt.Errorf(\"unknown event type %v\", eventType)\n\t}\n\n\t// Deliver the event.\n\tevents <- watcher.ContainerEvent{\n\t\tEventType:   eventType,\n\t\tName:        containerName,\n\t\tWatchSource: watcher.Raw,\n\t}\n\n\treturn nil\n}\n"
  },
  {
    "path": "container/systemd/factory.go",
    "content": "// Copyright 2016 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage systemd\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n\n\t\"github.com/google/cadvisor/container\"\n\t\"github.com/google/cadvisor/fs\"\n\tinfo \"github.com/google/cadvisor/info/v1\"\n\t\"github.com/google/cadvisor/watcher\"\n\n\t\"k8s.io/klog/v2\"\n)\n\ntype systemdFactory struct{}\n\nfunc (f *systemdFactory) String() string {\n\treturn \"systemd\"\n}\n\nfunc (f *systemdFactory) NewContainerHandler(name string, metadataEnvAllowList []string, inHostNamespace bool) (container.ContainerHandler, error) {\n\treturn nil, fmt.Errorf(\"not yet supported\")\n}\n\nfunc (f *systemdFactory) CanHandleAndAccept(name string) (bool, bool, error) {\n\t// on systemd using devicemapper each mount into the container has an associated cgroup that we ignore.\n\t// for details on .mount units: http://man7.org/linux/man-pages/man5/systemd.mount.5.html\n\tif strings.HasSuffix(name, \".mount\") {\n\t\treturn true, false, nil\n\t}\n\tklog.V(5).Infof(\"%s not handled by systemd handler\", name)\n\treturn false, false, nil\n}\n\nfunc (f *systemdFactory) DebugInfo() map[string][]string {\n\treturn map[string][]string{}\n}\n\n// Register registers the systemd container factory.\nfunc Register(machineInfoFactory info.MachineInfoFactory, fsInfo fs.FsInfo, includedMetrics container.MetricSet) error {\n\tklog.V(1).Infof(\"Registering systemd factory\")\n\tfactory := &systemdFactory{}\n\tcontainer.RegisterContainerHandlerFactory(factory, []watcher.ContainerWatchSource{watcher.Raw})\n\treturn nil\n}\n"
  },
  {
    "path": "container/systemd/install/install.go",
    "content": "// Copyright 2019 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n// The install package registers systemd.NewPlugin() as the \"systemd\" container provider when imported\npackage install\n\nimport (\n\t\"k8s.io/klog/v2\"\n\n\t\"github.com/google/cadvisor/container\"\n\t\"github.com/google/cadvisor/container/systemd\"\n)\n\nfunc init() {\n\terr := container.RegisterPlugin(\"systemd\", systemd.NewPlugin())\n\tif err != nil {\n\t\tklog.Fatalf(\"Failed to register systemd plugin: %v\", err)\n\t}\n}\n"
  },
  {
    "path": "container/systemd/plugin.go",
    "content": "// Copyright 2019 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage systemd\n\nimport (\n\t\"github.com/google/cadvisor/container\"\n\t\"github.com/google/cadvisor/fs\"\n\tinfo \"github.com/google/cadvisor/info/v1\"\n\t\"github.com/google/cadvisor/watcher\"\n)\n\n// NewPlugin returns an implementation of container.Plugin suitable for passing to container.RegisterPlugin()\nfunc NewPlugin() container.Plugin {\n\treturn &plugin{}\n}\n\ntype plugin struct{}\n\nfunc (p *plugin) InitializeFSContext(context *fs.Context) error {\n\treturn nil\n}\n\nfunc (p *plugin) Register(factory info.MachineInfoFactory, fsInfo fs.FsInfo, includedMetrics container.MetricSet) (watcher.ContainerWatcher, error) {\n\terr := Register(factory, fsInfo, includedMetrics)\n\treturn nil, err\n}\n"
  },
  {
    "path": "container/testing/mock_handler.go",
    "content": "// Copyright 2014 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage testing\n\nimport (\n\t\"github.com/google/cadvisor/container\"\n\tinfo \"github.com/google/cadvisor/info/v1\"\n\n\t\"github.com/stretchr/testify/mock\"\n)\n\n// This struct mocks a container handler.\ntype MockContainerHandler struct {\n\tmock.Mock\n\tName    string\n\tAliases []string\n}\n\nfunc NewMockContainerHandler(containerName string) *MockContainerHandler {\n\treturn &MockContainerHandler{\n\t\tName: containerName,\n\t}\n}\n\n// If self.Name is not empty, then ContainerReference() will return self.Name and self.Aliases.\n// Otherwise, it will use the value provided by .On().Return().\nfunc (h *MockContainerHandler) ContainerReference() (info.ContainerReference, error) {\n\tif len(h.Name) > 0 {\n\t\tvar aliases []string\n\t\tif len(h.Aliases) > 0 {\n\t\t\taliases = make([]string, len(h.Aliases))\n\t\t\tcopy(aliases, h.Aliases)\n\t\t}\n\t\treturn info.ContainerReference{\n\t\t\tName:    h.Name,\n\t\t\tAliases: aliases,\n\t\t}, nil\n\t}\n\targs := h.Called()\n\treturn args.Get(0).(info.ContainerReference), args.Error(1)\n}\n\nfunc (h *MockContainerHandler) Start() {}\n\nfunc (h *MockContainerHandler) Cleanup() {}\n\nfunc (h *MockContainerHandler) GetSpec() (info.ContainerSpec, error) {\n\targs := h.Called()\n\treturn args.Get(0).(info.ContainerSpec), args.Error(1)\n}\n\nfunc (h *MockContainerHandler) GetStats() (*info.ContainerStats, error) {\n\targs := h.Called()\n\treturn args.Get(0).(*info.ContainerStats), args.Error(1)\n}\n\nfunc (h *MockContainerHandler) ListContainers(listType container.ListType) ([]info.ContainerReference, error) {\n\targs := h.Called(listType)\n\treturn args.Get(0).([]info.ContainerReference), args.Error(1)\n}\n\nfunc (h *MockContainerHandler) ListProcesses(listType container.ListType) ([]int, error) {\n\targs := h.Called(listType)\n\treturn args.Get(0).([]int), args.Error(1)\n}\n\nfunc (h *MockContainerHandler) Exists() bool {\n\targs := h.Called()\n\treturn args.Get(0).(bool)\n}\n\nfunc (h *MockContainerHandler) GetCgroupPath(path string) (string, error) {\n\targs := h.Called(path)\n\treturn args.Get(0).(string), args.Error(1)\n}\n\nfunc (h *MockContainerHandler) GetContainerLabels() map[string]string {\n\targs := h.Called()\n\treturn args.Get(0).(map[string]string)\n}\n\nfunc (h *MockContainerHandler) Type() container.ContainerType {\n\targs := h.Called()\n\treturn args.Get(0).(container.ContainerType)\n}\n\nfunc (h *MockContainerHandler) GetContainerIPAddress() string {\n\targs := h.Called()\n\treturn args.Get(0).(string)\n}\n\nfunc (h *MockContainerHandler) GetExitCode() (int, error) {\n\targs := h.Called()\n\treturn args.Int(0), args.Error(1)\n}\n\ntype FactoryForMockContainerHandler struct {\n\tName                        string\n\tPrepareContainerHandlerFunc func(name string, handler *MockContainerHandler)\n}\n\nfunc (h *FactoryForMockContainerHandler) String() string {\n\treturn h.Name\n}\n\nfunc (h *FactoryForMockContainerHandler) NewContainerHandler(name string, metadataEnvAllowList []string, inHostNamespace bool) (container.ContainerHandler, error) {\n\thandler := &MockContainerHandler{}\n\tif h.PrepareContainerHandlerFunc != nil {\n\t\th.PrepareContainerHandlerFunc(name, handler)\n\t}\n\treturn handler, nil\n}\n\nfunc (h *FactoryForMockContainerHandler) CanHandle(name string) bool {\n\treturn true\n}\n"
  },
  {
    "path": "deploy/Dockerfile",
    "content": "FROM registry.hub.docker.com/library/golang:1.25-alpine3.22 AS build\n\n# Install build depdencies for all supported arches\nRUN apk --no-cache add bash build-base cmake device-mapper findutils git \\\n                       libc6-compat linux-headers ndctl-dev pkgconfig python3 thin-provisioning-tools wget zfs && \\\n    echo 'hosts: files mdns4_minimal [NOTFOUND=return] dns mdns4' >> /etc/nsswitch.conf && \\\n    rm -rf /var/cache/apk/*\n\nRUN wget https://sourceforge.net/projects/perfmon2/files/libpfm4/libpfm-4.11.0.tar.gz && \\\n  echo \"112bced9a67d565ff0ce6c2bb90452516d1183e5  libpfm-4.11.0.tar.gz\" | sha1sum -c  && \\\n  tar -xzf libpfm-4.11.0.tar.gz && \\\n  rm libpfm-4.11.0.tar.gz\n\nRUN export DBG=\"-g -Wall\" && \\\n  make -e -C libpfm-4.11.0 && \\\n  make install -C libpfm-4.11.0\n\n# ipmctl only supports Intel x86_64 processors.\n# https://github.com/intel/ipmctl/issues/163\n\n# Disable libipmctl due to https://github.com/google/cadvisor/issues/3482\n#RUN if [ \"$(uname --machine)\" = \"x86_64\" ]; then \\\n    #git clone -b v02.00.00.3885 https://github.com/intel/ipmctl/ && \\\n    #cd ipmctl && \\\n    #mkdir output && \\\n    #cd output && \\\n    #cmake -DRELEASE=ON -DCMAKE_INSTALL_PREFIX=/ -DCMAKE_INSTALL_LIBDIR=/usr/local/lib .. && \\\n    #make -j all && \\\n    #make install; fi\n\nWORKDIR /go/src/github.com/google/cadvisor\n\n# Cache Golang Dependencies for faster incremental builds\nADD go.mod go.sum ./\nRUN go mod download\nADD cmd/go.mod cmd/go.sum ./cmd/\nRUN cd cmd && go mod download\n\nADD . .\n\nARG VERSION\n\n# libipmctl only works on x86_64 CPUs.\nRUN export GO_TAGS=\"libpfm,netgo\"; \\\n    if [ \"$(uname --machine)\" = \"x86_64\" ]; then \\\n          # Disable libipmctl due to https://github.com/google/cadvisor/issues/3482\n          #export GO_TAGS=\"$GO_TAGS,libipmctl\"; \\\n          export GO_TAGS=\"$GO_TAGS\"; \\\n    fi; \\\n    GO_FLAGS=\"-tags=$GO_TAGS\" ./build/build.sh\n\nFROM mirror.gcr.io/library/alpine:3.22\nMAINTAINER dengnan@google.com vmarmol@google.com vishnuk@google.com jimmidyson@gmail.com stclair@google.com\n\nRUN apk --no-cache add libc6-compat device-mapper findutils ndctl thin-provisioning-tools zfs && \\\n    echo 'hosts: files mdns4_minimal [NOTFOUND=return] dns mdns4' >> /etc/nsswitch.conf && \\\n    rm -rf /var/cache/apk/*\n\n# Grab cadvisor,libpfm4 and libipmctl from \"build\" container if they exist (libipmctl only works on amd64/x86_64).\nCOPY --from=build /usr/local/lib/libpfm.so* /usr/local/lib/\n# Disable libipmctl due to https://github.com/google/cadvisor/issues/3482\n#COPY --from=build /usr/local/lib/libipmctl.so* /usr/local/lib/\nCOPY --from=build /go/src/github.com/google/cadvisor/_output/cadvisor /usr/bin/cadvisor\n\nCOPY deploy/entrypoint.sh /usr/bin/entrypoint.sh\nRUN chmod +x /usr/bin/entrypoint.sh\n\nCOPY deploy/healthcheck.sh /usr/bin/healthcheck.sh\nRUN chmod +x /usr/bin/healthcheck.sh\n\n# Default port is 8080, but can be changed with -port flag\n# Users should expose their custom port with: docker run -p <custom>:<custom>\nEXPOSE 8080\n\nHEALTHCHECK --interval=30s --timeout=3s --start-period=5s \\\n  CMD /usr/bin/healthcheck.sh\n\n# Use entrypoint wrapper\nENTRYPOINT [\"/usr/bin/entrypoint.sh\"]\n\n"
  },
  {
    "path": "deploy/Dockerfile.ppc64le",
    "content": "FROM ppc64le/alpine:3.15\nMAINTAINER dashpole@google.com lysannef@us.ibm.com\n# Deprecated: the Dockerfile in this directory should support ppc64le\n# Simply build using: docker buildx build --platform linux/ppc64le -f Dockerfile .\n\nRUN apk --no-cache add libc6-compat device-mapper findutils zfs && \\\n    apk --no-cache add thin-provisioning-tools --repository http://dl-3.alpinelinux.org/alpine/edge/main/ && \\\n    echo 'hosts: files mdns4_minimal [NOTFOUND=return] dns mdns4' >> /etc/nsswitch.conf && \\\n    rm -rf /var/cache/apk/*\n\n# Grab cadvisor from the staging directory.\nADD cadvisor /usr/bin/cadvisor\n\nEXPOSE 8080\n\nHEALTHCHECK --interval=30s --timeout=3s \\\n  CMD wget --quiet --tries=1 --spider http://localhost:8080/healthz || exit 1\n\nENTRYPOINT [\"/usr/bin/cadvisor\", \"-logtostderr\"]\n\n"
  },
  {
    "path": "deploy/build.sh",
    "content": "#!/bin/bash\n\n# Copyright 2015 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\nset -e\nset -x\n\nmake build\n\ndocker build -t google/cadvisor:beta -f $(dirname $0)/Dockerfile .\n"
  },
  {
    "path": "deploy/canary/Dockerfile",
    "content": "FROM golang:1.25\nMAINTAINER dashpole@google.com\n\nRUN apt-get update && apt-get install -y git dmsetup && apt-get clean\nRUN git clone https://github.com/google/cadvisor.git /go/src/github.com/google/cadvisor\nRUN cd /go/src/github.com/google/cadvisor && make\n\nENTRYPOINT [\"/go/src/github.com/google/cadvisor/cadvisor\"]\n\n"
  },
  {
    "path": "deploy/entrypoint.sh",
    "content": "#!/bin/sh\n\n# Copyright 2025 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\nset -e\n\n# Execute cadvisor with all provided arguments\nexec /usr/bin/cadvisor -logtostderr \"$@\"\n"
  },
  {
    "path": "deploy/healthcheck.sh",
    "content": "#!/bin/sh\n\n# Copyright 2025 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\n# Default port\nPORT=8080\n\n# Extract port from the cadvisor process command line\nif [ -f /proc/1/cmdline ]; then\n    CMDLINE=$(tr '\\0' ' ' < /proc/1/cmdline)\n\n    # Look for -port=XXXX or --port=XXXX\n    for arg in $CMDLINE; do\n        case \"$arg\" in\n            -port=*)\n                PORT=\"${arg#-port=}\"\n                ;;\n            --port=*)\n                PORT=\"${arg#--port=}\"\n                ;;\n        esac\n    done\nfi\n\nwget --quiet --tries=1 --spider \"http://localhost:${PORT}/healthz\" || exit 1\n"
  },
  {
    "path": "deploy/kubernetes/README.md",
    "content": "# cAdvisor Kubernetes Daemonset\n\ncAdvisor uses [Kustomize](https://github.com/kubernetes-sigs/kustomize) to manage Kubernetes manifests. See the [Install Kustomize](https://kubectl.docs.kubernetes.io/installation/kustomize/) for installation instructions, and for a description of how it works.\n\n## Deploy\n\nPick a [cAdvisor release](https://github.com/google/cadvisor/releases)\n```\nVERSION=v0.42.0\n```\n\nDeploy to Kubernetes cluster with [remote build](https://github.com/kubernetes-sigs/kustomize/blob/master/examples/remoteBuild.md):\n```\nkustomize build \"https://github.com/google/cadvisor/deploy/kubernetes/base?ref=${VERSION}\" | kubectl apply -f -\n```\n\n## Usage\n\nTo update the image version([reference](https://github.com/kubernetes-sigs/kustomize/blob/master/examples/image.md)):\n```\ncd deploy/kubernetes/base && kustomize edit set image ghcr.io/google/cadvisor:${VERSION} && cd ../../..\n```\n\nTo generate the base daemonset:\n```\nkubectl kustomize deploy/kubernetes/base\n```\n\nTo apply the base daemonset to your cluster:\n```\nkubectl kustomize deploy/kubernetes/base | kubectl apply -f -\n```\n\nTo generate the daemonset with example patches applied:\n```\nkubectl kustomize deploy/kubernetes/overlays/examples\n```\n\nTo apply the daemonset to your cluster with example patches applied:\n```\nkubectl kustomize deploy/kubernetes/overlays/examples | kubectl apply -f -\n```\n\n### cAdvisor with perf support on Kubernetes\n\nExample of modifications needed to deploy cAdvisor with perf support is provided in [overlays/examples_perf](overlays/examples_perf) directory (modification to daemonset and configmap with perf events configuration).\n\nTo generate and apply the daemonset with patches for cAdvisor with perf support:\n```\nkubectl kustomize deploy/kubernetes/overlays/examples_perf | kubectl apply -f -\n```\n\n## Kustomization\n\nOn your own fork of cAdvisor, create your own overlay directory with your patches.  Copy patches from the example folder if you intend to use them, but don't modify the originals.  Commit your changes in your local branch, and use git to manage them the same way you would any other piece of code.\n\nTo run the daemonset with your patches applied:\n```\nkubectl kustomize deploy/kubernetes/overlays/<my_custom_overlays> | kubectl apply -f -\n```\n\nTo get changes made to the upstream cAdvisor daemonset, simply rebase your fork of cAdvisor on top of upstream.  Since you didn't make changes to the originals, you won't have any conflicts.\n"
  },
  {
    "path": "deploy/kubernetes/base/daemonset.yaml",
    "content": "apiVersion: apps/v1 # for Kubernetes versions before 1.9.0 use apps/v1beta2\nkind: DaemonSet\nmetadata:\n  name: cadvisor\n  namespace: cadvisor\n  annotations:\n      seccomp.security.alpha.kubernetes.io/pod: 'docker/default'\nspec:\n  selector:\n    matchLabels:\n      name: cadvisor\n  template:\n    metadata:\n      labels:\n        name: cadvisor\n    spec:\n      serviceAccountName: cadvisor\n      containers:\n      - name: cadvisor\n        image: ghcr.io/google/cadvisor:0.54.0\n        resources:\n          requests:\n            memory: 400Mi\n            cpu: 400m\n          limits:\n            memory: 2000Mi\n            cpu: 800m\n        volumeMounts:\n        - name: rootfs\n          mountPath: /rootfs\n          readOnly: true\n        - name: var-run\n          mountPath: /var/run\n          readOnly: true\n        - name: sys\n          mountPath: /sys\n          readOnly: true\n        - name: docker\n          mountPath: /var/lib/docker\n          readOnly: true\n        - name: disk\n          mountPath: /dev/disk\n          readOnly: true\n        ports:\n          - name: http\n            containerPort: 8080\n            protocol: TCP\n      automountServiceAccountToken: false\n      terminationGracePeriodSeconds: 30\n      volumes:\n      - name: rootfs\n        hostPath:\n          path: /\n      - name: var-run\n        hostPath:\n          path: /var/run\n      - name: sys\n        hostPath:\n          path: /sys\n      - name: docker\n        hostPath:\n          path: /var/lib/docker\n      - name: disk\n        hostPath:\n          path: /dev/disk\n"
  },
  {
    "path": "deploy/kubernetes/base/kustomization.yaml",
    "content": "apiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\nnamespace: cadvisor\ncommonLabels:\n  app: cadvisor\nresources:\n- daemonset.yaml\n- namespace.yaml\n- serviceaccount.yaml\n"
  },
  {
    "path": "deploy/kubernetes/base/namespace.yaml",
    "content": "apiVersion: v1\nkind: Namespace\nmetadata:\n  name: cadvisor\n"
  },
  {
    "path": "deploy/kubernetes/base/serviceaccount.yaml",
    "content": "apiVersion: v1\nkind: ServiceAccount\nmetadata:\n  name: cadvisor\n  namespace: cadvisor\n"
  },
  {
    "path": "deploy/kubernetes/overlays/examples/cadvisor-args.yaml",
    "content": "# This patch is an example of setting arguments for the cAdvisor container.\n# This set of arguments mirrors what the kubelet currently uses for cAdvisor, \n# enables only cpu, memory, diskIO, disk and network metrics, and shows only\n# container metrics.\napiVersion: apps/v1 # for Kubernetes versions before 1.9.0 use apps/v1beta2\nkind: DaemonSet\nmetadata:\n  name: cadvisor\n  namespace: cadvisor\nspec:\n  template:\n    spec:\n      containers:\n      - name: cadvisor\n        args:\n          - --housekeeping_interval=10s                           # kubernetes default args\n          - --max_housekeeping_interval=15s\n          - --event_storage_event_limit=default=0\n          - --event_storage_age_limit=default=0\n          - --enable_metrics=app,cpu,disk,diskIO,memory,network,process\n          - --docker_only                                         # only show stats for docker containers\n          - --store_container_labels=false\n          - --whitelisted_container_labels=io.kubernetes.container.name, io.kubernetes.pod.name,io.kubernetes.pod.namespace\n"
  },
  {
    "path": "deploy/kubernetes/overlays/examples/critical-priority.yaml",
    "content": "# This patch sets the priorityClass to system-node-critical, the highest priority available.\napiVersion: apps/v1 # for Kubernetes versions before 1.9.0 use apps/v1beta2\nkind: DaemonSet\nmetadata:\n  name: cadvisor\n  namespace: cadvisor\nspec:\n  template:\n    metadata:\n      annotations:\n        scheduler.alpha.kubernetes.io/critical-pod: ''\n    spec:\n      priorityClassName: system-node-critical\n      tolerations:\n        - key: \"CriticalAddonsOnly\"\n          operator: \"Exists\"\n"
  },
  {
    "path": "deploy/kubernetes/overlays/examples/kustomization.yaml",
    "content": "bases:\n- ../../base\npatches:\n- stackdriver-sidecar.yaml\n- critical-priority.yaml\n- cadvisor-args.yaml\n- gpu-privilages.yaml\n"
  },
  {
    "path": "deploy/kubernetes/overlays/examples/stackdriver-sidecar.yaml",
    "content": "# This patch adds a sidecar which pushes all metrics to stackdriver\napiVersion: apps/v1 # for Kubernetes versions before 1.9.0 use apps/v1beta2\nkind: DaemonSet\nmetadata:\n  name: cadvisor\n  namespace: cadvisor\nspec:\n  template:\n    spec:\n      containers:\n      - name: prometheus-to-sd\n        image: gcr.io/google-containers/prometheus-to-sd:v0.2.6\n        ports:\n          - name: profiler\n            containerPort: 6061\n        command:\n          - /monitor\n          - --stackdriver-prefix=custom.googleapis.com\n          - --source=cadvisor:http://localhost:8080\n          - --pod-id=$(POD_NAME)\n          - --namespace-id=$(POD_NAMESPACE)\n        env:\n          - name: POD_NAME\n            valueFrom:\n              fieldRef:\n                fieldPath: metadata.name\n          - name: POD_NAMESPACE\n            valueFrom:\n              fieldRef:\n                fieldPath: metadata.namespace\n        securityContext:\n          runAsNonRoot: true\n          readOnlyRootFilesystem: true\n          allowPrivilegeEscalation: false\n"
  },
  {
    "path": "deploy/kubernetes/overlays/examples_perf/cadvisor-perf.yaml",
    "content": "# This patch is an example of setting arguments for the cAdvisor container to collect perf metrics \napiVersion: apps/v1 # for Kubernetes versions before 1.9.0 use apps/v1beta2\nkind: DaemonSet\nmetadata:\n  name: cadvisor\n  namespace: cadvisor\nspec:\n  template:\n    spec:\n      containers:\n      - name: cadvisor\n        args:\n          - --perf_events_config=/etc/config/perf-non-hardware.json\n        securityContext:\n          privileged: true\n        volumeMounts:\n        - name: perf-volume\n          mountPath: /etc/config/\n      volumes:\n        - name: perf-volume\n          configMap:\n            name: perf-config\n"
  },
  {
    "path": "deploy/kubernetes/overlays/examples_perf/configmap.yaml",
    "content": "apiVersion: v1\nkind: ConfigMap\nmetadata:\n  name: perf-config\n  namespace: cadvisor\ndata:\n  perf-non-hardware.json: |\n    {\n      \"core\": {\n        \"events\": [\n          \"context-switches\",\n          \"cpu-migrations-custom\"\n        ],\n        \"custom_events\": [\n          {\n            \"type\": 1,\n            \"config\": [\n              \"0x4\"\n            ],\n            \"name\": \"cpu-migrations-custom\"\n          }\n        ]\n      }\n    }\n\n"
  },
  {
    "path": "deploy/kubernetes/overlays/examples_perf/kustomization.yaml",
    "content": "bases:\n- ../../base\nresources:\n- configmap.yaml\npatches:\n- cadvisor-perf.yaml\n"
  },
  {
    "path": "deploy/snap/snapcraft.yaml",
    "content": "name: cadvisor\nsummary:  Container Advisor.\ndescription:| Analyzes resource usage and performance characteristics of running containers.\n  \nadopt-info: cadvisor\n\ngrade: stable\nconfinement: classic\n\narchitectures:\n  - build-on: i386\n  - build-on: amd64\n  - build-on: armhf\n  - build-on: arm64\n\napps:\n  cadvisor:\n    command: bin/cadvisor\n    plugs:\n      - home\n      - network\n      - docker\n      - removable-media\n\nparts:\n  cadvisor:\n  plugin: nil \n    source: https://github.com/google/cadvisor.git\n    source-type: git\n    override-pull: |\n      git clone https://github.com/google/cadvisor.git src/github.com/google/cadvisor\n       cd src/github.com/google/cadvisor\n      last_committed_tag=\"$(git describe --tags --abbrev=0)\"\n      last_committed_tag_ver=\"$(echo ${last_committed_tag} | sed 's/v//')\"\n      last_released_tag=\"$(snap info $SNAPCRAFT_PROJECT_NAME | awk '$1 == \"beta:\" { print $2 }')\"\n      # If the latest tag from the upstream project has not been released to\n      # beta, build that tag instead of master.\n      if [ \"${last_committed_tag_ver}\" != \"${last_released_tag}\" ]; then\n        git fetch\n        git checkout \"${last_committed_tag}\"\n      fi\n      snapcraftctl set-version \"$(git describe --tags | sed 's/v//')\"\n      override-build: |\n      export GOPATH=$PWD\n      cd src/github.com/google/cadvisor\n      env CGO_ENABLED=0 GOOS=linux \\\n      go build --ldflags \"-s -w \\\n        -X 'github.com/google/cadvisor/version.GitCommit=$(git rev-list -1 HEAD)' \\\n        -X 'github.com/google/cadvisor/version.Version=$(git describe --tags --abbrev=0)'\" \\\n        -a -installsuffix cgo -o $SNAPCRAFT_PART_INSTALL/bin/cadvisor\n    build-snaps:\n      - go\n    build-packages:\n      - git\n      - sed\n"
  },
  {
    "path": "devicemapper/dmsetup_client.go",
    "content": "// Copyright 2016 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage devicemapper\n\nimport (\n\t\"os/exec\"\n\t\"strconv\"\n\t\"strings\"\n\n\t\"k8s.io/klog/v2\"\n)\n\n// DmsetupClient is a low-level client for interacting with device mapper via\n// the `dmsetup` utility, which is provided by the `device-mapper` package.\ntype DmsetupClient interface {\n\t// Table runs `dmsetup table` on the given device name and returns the\n\t// output or an error.\n\tTable(deviceName string) ([]byte, error)\n\t// Message runs `dmsetup message` on the given device, passing the given\n\t// message to the given sector, and returns the output or an error.\n\tMessage(deviceName string, sector int, message string) ([]byte, error)\n\t// Status runs `dmsetup status` on the given device and returns the output\n\t// or an error.\n\tStatus(deviceName string) ([]byte, error)\n}\n\n// NewDmSetupClient returns a new DmsetupClient.\nfunc NewDmsetupClient() DmsetupClient {\n\treturn &defaultDmsetupClient{}\n}\n\n// defaultDmsetupClient is a functional DmsetupClient\ntype defaultDmsetupClient struct{}\n\nvar _ DmsetupClient = &defaultDmsetupClient{}\n\nfunc (c *defaultDmsetupClient) Table(deviceName string) ([]byte, error) {\n\treturn c.dmsetup(\"table\", deviceName)\n}\n\nfunc (c *defaultDmsetupClient) Message(deviceName string, sector int, message string) ([]byte, error) {\n\treturn c.dmsetup(\"message\", deviceName, strconv.Itoa(sector), message)\n}\n\nfunc (c *defaultDmsetupClient) Status(deviceName string) ([]byte, error) {\n\treturn c.dmsetup(\"status\", deviceName)\n}\n\nfunc (*defaultDmsetupClient) dmsetup(args ...string) ([]byte, error) {\n\tklog.V(5).Infof(\"running dmsetup %v\", strings.Join(args, \" \"))\n\treturn exec.Command(\"dmsetup\", args...).Output()\n}\n"
  },
  {
    "path": "devicemapper/doc.go",
    "content": "// Copyright 2016 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n// Package devicemapper contains code for working with devicemapper\npackage devicemapper\n"
  },
  {
    "path": "devicemapper/fake/dmsetup_client_fake.go",
    "content": "// Copyright 2016 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage fake\n\nimport (\n\t\"testing\"\n)\n\ntype DmsetupCommand struct {\n\tName   string\n\tResult string\n\tErr    error\n}\n\n// NewFakeDmsetupClient returns a new fake DmsetupClient.\nfunc NewFakeDmsetupClient(t *testing.T, commands ...DmsetupCommand) *FakeDmsetupClient {\n\tif len(commands) == 0 {\n\t\tcommands = make([]DmsetupCommand, 0)\n\t}\n\treturn &FakeDmsetupClient{t: t, commands: commands}\n}\n\n// FakeDmsetupClient is a thread-unsafe fake implementation of the\n// DmsetupClient interface\ntype FakeDmsetupClient struct {\n\tt        *testing.T\n\tcommands []DmsetupCommand\n}\n\nfunc (c *FakeDmsetupClient) Table(deviceName string) ([]byte, error) {\n\treturn c.dmsetup(\"table\")\n}\n\nfunc (c *FakeDmsetupClient) Message(deviceName string, sector int, message string) ([]byte, error) {\n\treturn c.dmsetup(\"message\")\n}\n\nfunc (c *FakeDmsetupClient) Status(deviceName string) ([]byte, error) {\n\treturn c.dmsetup(\"status\")\n}\n\nfunc (c *FakeDmsetupClient) AddCommand(name string, result string, err error) {\n\tc.commands = append(c.commands, DmsetupCommand{name, result, err})\n}\n\nfunc (c *FakeDmsetupClient) dmsetup(inputCommand string) ([]byte, error) {\n\tvar nextCommand DmsetupCommand\n\tnextCommand, c.commands = c.commands[0], c.commands[1:]\n\tif nextCommand.Name != inputCommand {\n\t\tc.t.Fatalf(\"unexpected dmsetup command; expected: %q, got %q\", nextCommand.Name, inputCommand)\n\t\t// should be unreachable in a test context.\n\t}\n\n\treturn []byte(nextCommand.Result), nextCommand.Err\n}\n"
  },
  {
    "path": "devicemapper/fake/thin_ls_client_fake.go",
    "content": "// Copyright 2016 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage fake\n\ntype FakeThinLsClient struct {\n\tresult map[string]uint64\n\terr    error\n}\n\n// NewFakeThinLsClient returns a new fake ThinLsClient.\nfunc NewFakeThinLsClient(result map[string]uint64, err error) *FakeThinLsClient {\n\treturn &FakeThinLsClient{result, err}\n}\n\nfunc (c *FakeThinLsClient) ThinLs(deviceName string) (map[string]uint64, error) {\n\treturn c.result, c.err\n}\n"
  },
  {
    "path": "devicemapper/thin_ls_client.go",
    "content": "// Copyright 2016 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage devicemapper\n\nimport (\n\t\"bufio\"\n\t\"bytes\"\n\t\"fmt\"\n\t\"os/exec\"\n\t\"strconv\"\n\t\"strings\"\n\n\t\"k8s.io/klog/v2\"\n)\n\n// thinLsClient knows how to run a thin_ls very specific to CoW usage for\n// containers.\ntype thinLsClient interface {\n\t// ThinLs runs a thin ls on the given device, which is expected to be a\n\t// metadata device. The caller must hold the metadata snapshot for the\n\t// device.\n\tThinLs(deviceName string) (map[string]uint64, error)\n}\n\n// newThinLsClient returns a thinLsClient or an error if the thin_ls binary\n// couldn't be located.\nfunc newThinLsClient() (thinLsClient, error) {\n\tthinLsPath, err := ThinLsBinaryPresent()\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"error creating thin_ls client: %v\", err)\n\t}\n\n\treturn &defaultThinLsClient{thinLsPath}, nil\n}\n\n// defaultThinLsClient is a functional thinLsClient\ntype defaultThinLsClient struct {\n\tthinLsPath string\n}\n\nvar _ thinLsClient = &defaultThinLsClient{}\n\nfunc (c *defaultThinLsClient) ThinLs(deviceName string) (map[string]uint64, error) {\n\targs := []string{\"--no-headers\", \"-m\", \"-o\", \"DEV,EXCLUSIVE_BYTES\", deviceName}\n\tklog.V(4).Infof(\"running command: thin_ls %v\", strings.Join(args, \" \"))\n\n\toutput, err := exec.Command(c.thinLsPath, args...).Output()\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"error running command `thin_ls %v`: %v\\noutput:\\n\\n%v\", strings.Join(args, \" \"), err, string(output))\n\t}\n\n\treturn parseThinLsOutput(output), nil\n}\n\n// parseThinLsOutput parses the output returned by thin_ls to build a map of\n// device id -> usage.\nfunc parseThinLsOutput(output []byte) map[string]uint64 {\n\tcache := map[string]uint64{}\n\n\t// parse output\n\tscanner := bufio.NewScanner(bytes.NewReader(output))\n\tfor scanner.Scan() {\n\t\toutput := scanner.Text()\n\t\tfields := strings.Fields(output)\n\t\tif len(fields) != 2 {\n\t\t\tcontinue\n\t\t}\n\n\t\tdeviceID := fields[0]\n\t\tusage, err := strconv.ParseUint(fields[1], 10, 64)\n\t\tif err != nil {\n\t\t\tklog.Warningf(\"unexpected error parsing thin_ls output: %v\", err)\n\t\t\tcontinue\n\t\t}\n\n\t\tcache[deviceID] = usage\n\t}\n\n\treturn cache\n\n}\n"
  },
  {
    "path": "devicemapper/thin_ls_client_test.go",
    "content": "// Copyright 2016 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage devicemapper\n\nimport (\n\t\"reflect\"\n\t\"testing\"\n)\n\nfunc TestParseThinLsOutput(t *testing.T) {\n\tcases := []struct {\n\t\tname           string\n\t\tinput          string\n\t\texpectedResult map[string]uint64\n\t}{\n\t\t{\n\t\t\tname: \"ok\",\n\t\t\tinput: `\n  1         2293760\n  2         2097152\n  3          131072\n  4         2031616`,\n\t\t\texpectedResult: map[string]uint64{\n\t\t\t\t\"1\": 2293760,\n\t\t\t\t\"2\": 2097152,\n\t\t\t\t\"3\": 131072,\n\t\t\t\t\"4\": 2031616,\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"skip bad rows\",\n\t\t\tinput: `\n  1         2293760\n  2         2097152\n  3          131072ads\n  4d dsrv         2031616`,\n\t\t\texpectedResult: map[string]uint64{\n\t\t\t\t\"1\": 2293760,\n\t\t\t\t\"2\": 2097152,\n\t\t\t},\n\t\t},\n\t}\n\n\tfor _, tc := range cases {\n\t\tactualResult := parseThinLsOutput([]byte(tc.input))\n\t\tif e, a := tc.expectedResult, actualResult; !reflect.DeepEqual(e, a) {\n\t\t\tt.Errorf(\"%v: unexpected result: expected %+v got %+v\", tc.name, e, a)\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "devicemapper/thin_pool_watcher.go",
    "content": "// Copyright 2016 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage devicemapper\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n\t\"sync/atomic\"\n\t\"time\"\n\n\t\"k8s.io/klog/v2\"\n)\n\n// usageCache is a typed wrapper around atomic.Value that eliminates the need\n// for type assertions at every call site. It stores device ID strings mapped\n// to usage values (uint64).\ntype usageCache struct {\n\tv atomic.Value\n}\n\n// Load retrieves the current cache map.\nfunc (c *usageCache) Load() map[string]uint64 {\n\treturn c.v.Load().(map[string]uint64)\n}\n\n// Store saves a new cache map.\nfunc (c *usageCache) Store(m map[string]uint64) {\n\tc.v.Store(m)\n}\n\n// ThinPoolWatcher maintains a cache of device name -> usage stats for a\n// devicemapper thin-pool using thin_ls.\ntype ThinPoolWatcher struct {\n\tpoolName       string\n\tmetadataDevice string\n\tcache          usageCache\n\tperiod         time.Duration\n\tstopChan       chan struct{}\n\tdmsetup        DmsetupClient\n\tthinLsClient   thinLsClient\n}\n\n// NewThinPoolWatcher returns a new ThinPoolWatcher for the given devicemapper\n// thin pool name and metadata device or an error.\nfunc NewThinPoolWatcher(poolName, metadataDevice string) (*ThinPoolWatcher, error) {\n\tthinLsClient, err := newThinLsClient()\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"encountered error creating thin_ls client: %v\", err)\n\t}\n\n\tw := &ThinPoolWatcher{\n\t\tpoolName:       poolName,\n\t\tmetadataDevice: metadataDevice,\n\t\tperiod:         15 * time.Second,\n\t\tstopChan:       make(chan struct{}),\n\t\tdmsetup:        NewDmsetupClient(),\n\t\tthinLsClient:   thinLsClient,\n\t}\n\tw.cache.Store(map[string]uint64{})\n\treturn w, nil\n}\n\n// Start starts the ThinPoolWatcher.\nfunc (w *ThinPoolWatcher) Start() {\n\terr := w.Refresh()\n\tif err != nil {\n\t\tklog.Errorf(\"encountered error refreshing thin pool watcher: %v\", err)\n\t}\n\n\tfor {\n\t\tselect {\n\t\tcase <-w.stopChan:\n\t\t\treturn\n\t\tcase <-time.After(w.period):\n\t\t\tstart := time.Now()\n\t\t\terr = w.Refresh()\n\t\t\tif err != nil {\n\t\t\t\tklog.Errorf(\"encountered error refreshing thin pool watcher: %v\", err)\n\t\t\t}\n\n\t\t\t// print latency for refresh\n\t\t\tduration := time.Since(start)\n\t\t\tklog.V(5).Infof(\"thin_ls(%d) took %s\", start.Unix(), duration)\n\t\t}\n\t}\n}\n\n// Stop stops the ThinPoolWatcher.\nfunc (w *ThinPoolWatcher) Stop() {\n\tclose(w.stopChan)\n}\n\n// GetUsage gets the cached usage value of the given device.\nfunc (w *ThinPoolWatcher) GetUsage(deviceID string) (uint64, error) {\n\tcache := w.cache.Load()\n\tv, ok := cache[deviceID]\n\tif !ok {\n\t\treturn 0, fmt.Errorf(\"no cached value for usage of device %v\", deviceID)\n\t}\n\treturn v, nil\n}\n\nconst (\n\treserveMetadataMessage = \"reserve_metadata_snap\"\n\treleaseMetadataMessage = \"release_metadata_snap\"\n)\n\n// Refresh performs a `thin_ls` of the pool being watched and refreshes the\n// cached data with the result.\nfunc (w *ThinPoolWatcher) Refresh() error {\n\tcurrentlyReserved, err := w.checkReservation(w.poolName)\n\tif err != nil {\n\t\terr = fmt.Errorf(\"error determining whether snapshot is reserved: %v\", err)\n\t\treturn err\n\t}\n\n\tif currentlyReserved {\n\t\tklog.V(5).Infof(\"metadata for %v is currently reserved; releasing\", w.poolName)\n\t\t_, err = w.dmsetup.Message(w.poolName, 0, releaseMetadataMessage)\n\t\tif err != nil {\n\t\t\terr = fmt.Errorf(\"error releasing metadata snapshot for %v: %v\", w.poolName, err)\n\t\t\treturn err\n\t\t}\n\t}\n\n\tklog.V(5).Infof(\"reserving metadata snapshot for thin-pool %v\", w.poolName)\n\t// NOTE: \"0\" in the call below is for the 'sector' argument to 'dmsetup\n\t// message'.  It's not needed for thin pools.\n\tif output, err := w.dmsetup.Message(w.poolName, 0, reserveMetadataMessage); err != nil {\n\t\terr = fmt.Errorf(\"error reserving metadata for thin-pool %v: %v output: %v\", w.poolName, err, string(output))\n\t\treturn err\n\t}\n\tklog.V(5).Infof(\"reserved metadata snapshot for thin-pool %v\", w.poolName)\n\n\tdefer func() {\n\t\tklog.V(5).Infof(\"releasing metadata snapshot for thin-pool %v\", w.poolName)\n\t\t_, err := w.dmsetup.Message(w.poolName, 0, releaseMetadataMessage)\n\t\tif err != nil {\n\t\t\tklog.Warningf(\"Unable to release metadata snapshot for thin-pool %v: %s\", w.poolName, err)\n\t\t}\n\t}()\n\n\tklog.V(5).Infof(\"running thin_ls on metadata device %v\", w.metadataDevice)\n\tnewCache, err := w.thinLsClient.ThinLs(w.metadataDevice)\n\tif err != nil {\n\t\terr = fmt.Errorf(\"error performing thin_ls on metadata device %v: %v\", w.metadataDevice, err)\n\t\treturn err\n\t}\n\n\tw.cache.Store(newCache)\n\treturn nil\n}\n\nconst (\n\tthinPoolDmsetupStatusHeldMetadataRoot = 6\n\tthinPoolDmsetupStatusMinFields        = thinPoolDmsetupStatusHeldMetadataRoot + 1\n)\n\n// checkReservation checks to see whether the thin device is currently holding\n// userspace metadata.\nfunc (w *ThinPoolWatcher) checkReservation(poolName string) (bool, error) {\n\tklog.V(5).Infof(\"checking whether the thin-pool is holding a metadata snapshot\")\n\toutput, err := w.dmsetup.Status(poolName)\n\tif err != nil {\n\t\treturn false, err\n\t}\n\n\t// we care about the field at fields[thinPoolDmsetupStatusHeldMetadataRoot],\n\t// so make sure we get enough fields\n\tfields := strings.Fields(string(output))\n\tif len(fields) < thinPoolDmsetupStatusMinFields {\n\t\treturn false, fmt.Errorf(\"unexpected output of dmsetup status command; expected at least %d fields, got %v; output: %v\", thinPoolDmsetupStatusMinFields, len(fields), string(output))\n\t}\n\n\theldMetadataRoot := fields[thinPoolDmsetupStatusHeldMetadataRoot]\n\tcurrentlyReserved := heldMetadataRoot != \"-\"\n\treturn currentlyReserved, nil\n}\n"
  },
  {
    "path": "devicemapper/thin_pool_watcher_test.go",
    "content": "// Copyright 2016 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage devicemapper\n\nimport (\n\t\"fmt\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/google/cadvisor/devicemapper/fake\"\n)\n\nfunc TestRefresh(t *testing.T) {\n\tusage := map[string]uint64{\n\t\t\"1\": 12345,\n\t\t\"2\": 23456,\n\t\t\"3\": 34567,\n\t}\n\n\tcases := []struct {\n\t\tname            string\n\t\tdmsetupCommands []fake.DmsetupCommand\n\t\tthinLsOutput    map[string]uint64\n\t\tthinLsErr       error\n\t\texpectedError   bool\n\t\tdeviceID        string\n\t\texpectedUsage   uint64\n\t}{\n\t\t{\n\t\t\tname: \"check reservation fails\",\n\t\t\tdmsetupCommands: []fake.DmsetupCommand{\n\t\t\t\t{Name: \"status\", Result: \"\", Err: fmt.Errorf(\"not gonna work\")},\n\t\t\t},\n\t\t\texpectedError: true,\n\t\t},\n\t\t{\n\t\t\tname: \"no existing reservation - ok with minimum # of fields\",\n\t\t\tdmsetupCommands: []fake.DmsetupCommand{\n\t\t\t\t{Name: \"status\", Result: \"0 75497472 thin-pool 65 327/524288 14092/589824 -\", Err: nil}, // status check\n\t\t\t\t{Name: \"message\", Result: \"\", Err: nil},                                                 // make reservation\n\t\t\t\t{Name: \"message\", Result: \"\", Err: nil},                                                 // release reservation\n\t\t\t},\n\t\t\tthinLsOutput:  usage,\n\t\t\texpectedError: false,\n\t\t\tdeviceID:      \"2\",\n\t\t\texpectedUsage: 23456,\n\t\t},\n\t\t{\n\t\t\tname: \"no existing reservation - ok\",\n\t\t\tdmsetupCommands: []fake.DmsetupCommand{\n\t\t\t\t{Name: \"status\", Result: \"0 75497472 thin-pool 65 327/524288 14092/589824 - rw no_discard_passdown error_if_no_space - \", Err: nil}, // status check\n\t\t\t\t{Name: \"message\", Result: \"\", Err: nil}, // make reservation\n\t\t\t\t{Name: \"message\", Result: \"\", Err: nil}, // release reservation\n\t\t\t},\n\t\t\tthinLsOutput:  usage,\n\t\t\texpectedError: false,\n\t\t\tdeviceID:      \"2\",\n\t\t\texpectedUsage: 23456,\n\t\t},\n\t\t{\n\t\t\tname: \"existing reservation - ok\",\n\t\t\tdmsetupCommands: []fake.DmsetupCommand{\n\t\t\t\t// status check\n\t\t\t\t{Name: \"status\", Result: \"0 75497472 thin-pool 65 327/524288 14092/589824 39 rw no_discard_passdown error_if_no_space - \", Err: nil},\n\t\t\t\t// release reservation\n\t\t\t\t{Name: \"message\", Result: \"\", Err: nil},\n\t\t\t\t// make reservation\n\t\t\t\t{Name: \"message\", Result: \"\", Err: nil},\n\t\t\t\t// release reservation\n\t\t\t\t{Name: \"message\", Result: \"\", Err: nil},\n\t\t\t},\n\t\t\tthinLsOutput:  usage,\n\t\t\texpectedError: false,\n\t\t\tdeviceID:      \"3\",\n\t\t\texpectedUsage: 34567,\n\t\t},\n\t\t{\n\t\t\tname: \"failure releasing existing reservation\",\n\t\t\tdmsetupCommands: []fake.DmsetupCommand{\n\t\t\t\t// status check\n\t\t\t\t{Name: \"status\", Result: \"0 75497472 thin-pool 65 327/524288 14092/589824 39 rw no_discard_passdown error_if_no_space - \", Err: nil},\n\t\t\t\t// release reservation\n\t\t\t\t{Name: \"message\", Result: \"\", Err: fmt.Errorf(\"not gonna work\")},\n\t\t\t},\n\t\t\texpectedError: true,\n\t\t},\n\t\t{\n\t\t\tname: \"failure making reservation\",\n\t\t\tdmsetupCommands: []fake.DmsetupCommand{\n\t\t\t\t// status check\n\t\t\t\t{Name: \"status\", Result: \"0 75497472 thin-pool 65 327/524288 14092/589824 39 rw no_discard_passdown error_if_no_space - \", Err: nil},\n\t\t\t\t// release reservation\n\t\t\t\t{Name: \"message\", Result: \"\", Err: nil},\n\t\t\t\t// make reservation\n\t\t\t\t{Name: \"message\", Result: \"\", Err: fmt.Errorf(\"not gonna work\")},\n\t\t\t},\n\t\t\texpectedError: true,\n\t\t},\n\t\t{\n\t\t\tname: \"failure running thin_ls\",\n\t\t\tdmsetupCommands: []fake.DmsetupCommand{\n\t\t\t\t// status check\n\t\t\t\t{Name: \"status\", Result: \"0 75497472 thin-pool 65 327/524288 14092/589824 39 rw no_discard_passdown error_if_no_space - \", Err: nil},\n\t\t\t\t// release reservation\n\t\t\t\t{Name: \"message\", Result: \"\", Err: nil},\n\t\t\t\t// make reservation\n\t\t\t\t{Name: \"message\", Result: \"\", Err: nil},\n\t\t\t\t// release reservation\n\t\t\t\t{Name: \"message\", Result: \"\", Err: nil},\n\t\t\t},\n\t\t\tthinLsErr:     fmt.Errorf(\"not gonna work\"),\n\t\t\texpectedError: true,\n\t\t},\n\t}\n\n\tfor _, tc := range cases {\n\t\tdmsetup := fake.NewFakeDmsetupClient(t, tc.dmsetupCommands...)\n\t\tthinLsClient := fake.NewFakeThinLsClient(tc.thinLsOutput, tc.thinLsErr)\n\t\twatcher := &ThinPoolWatcher{\n\t\t\tpoolName:       \"test pool name\",\n\t\t\tmetadataDevice: \"/dev/mapper/metadata-device\",\n\t\t\tperiod:         15 * time.Second,\n\t\t\tstopChan:       make(chan struct{}),\n\t\t\tdmsetup:        dmsetup,\n\t\t\tthinLsClient:   thinLsClient,\n\t\t}\n\n\t\terr := watcher.Refresh()\n\t\tif err != nil {\n\t\t\tif !tc.expectedError {\n\t\t\t\tt.Errorf(\"%v: unexpected error: %v\", tc.name, err)\n\t\t\t}\n\t\t\tcontinue\n\t\t} else if tc.expectedError {\n\t\t\tt.Errorf(\"%v: unexpected success\", tc.name)\n\t\t\tcontinue\n\t\t}\n\n\t\tactualUsage, err := watcher.GetUsage(tc.deviceID)\n\t\tif err != nil {\n\t\t\tt.Errorf(\"%v: device ID not found: %v\", tc.deviceID, err)\n\t\t\tcontinue\n\t\t}\n\n\t\tif e, a := tc.expectedUsage, actualUsage; e != a {\n\t\t\tt.Errorf(\"%v: actual usage did not match expected usage: expected: %v got: %v\", tc.name, e, a)\n\t\t}\n\t}\n}\n\nfunc TestCheckReservation(t *testing.T) {\n\tcases := []struct {\n\t\tname           string\n\t\tstatusResult   string\n\t\tstatusErr      error\n\t\texpectedResult bool\n\t\texpectedErr    error\n\t}{\n\t\t{\n\t\t\tname:           \"existing reservation 1\",\n\t\t\tstatusResult:   \"0 75497472 thin-pool 65 327/524288 14092/589824 36 rw no_discard_passdown queue_if_no_space - \",\n\t\t\texpectedResult: true,\n\t\t},\n\t\t{\n\t\t\tname:           \"existing reservation 2\",\n\t\t\tstatusResult:   \"0 12345 thin-pool 65 327/45678 14092/45678 36 rw discard_passdown error_if_no_space needs_check \",\n\t\t\texpectedResult: true,\n\t\t},\n\t\t{\n\t\t\tname:           \"no reservation 1\",\n\t\t\tstatusResult:   \"0 75497472 thin-pool 65 327/524288 14092/589824 - rw no_discard_passdown error_if_no_space - \",\n\t\t\texpectedResult: false,\n\t\t},\n\t\t{\n\t\t\tname:           \"no reservation 2\",\n\t\t\tstatusResult:   \"0 75 thin-pool 65 327/12345 14092/589824 - rw no_discard_passdown queue_if_no_space - \",\n\t\t\texpectedResult: false,\n\t\t},\n\t\t{\n\t\t\tname:           \"no reservation 2\",\n\t\t\tstatusResult:   \"0 75 thin-pool 65 327/12345 14092/589824 - rw no_discard_passdown queue_if_no_space - \",\n\t\t\texpectedResult: false,\n\t\t},\n\t}\n\n\tfor _, tc := range cases {\n\t\tfakeDmsetupClient := fake.NewFakeDmsetupClient(t)\n\t\tfakeDmsetupClient.AddCommand(\"status\", tc.statusResult, tc.statusErr)\n\t\twatcher := &ThinPoolWatcher{dmsetup: fakeDmsetupClient}\n\t\tactualResult, err := watcher.checkReservation(\"test pool\")\n\t\tif err != nil {\n\t\t\tif tc.expectedErr == nil {\n\t\t\t\tt.Errorf(\"%v: unexpected error running checkReservation: %v\", tc.name, err)\n\t\t\t}\n\t\t} else if tc.expectedErr != nil {\n\t\t\tt.Errorf(\"%v: unexpected success running checkReservation\", tc.name)\n\t\t}\n\n\t\tif e, a := tc.expectedResult, actualResult; e != a {\n\t\t\tt.Errorf(\"%v: unexpected result from checkReservation: expected: %v got: %v\", tc.name, e, a)\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "devicemapper/util.go",
    "content": "// Copyright 2016 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage devicemapper\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\t\"path/filepath\"\n)\n\n// ThinLsBinaryPresent returns the location of the thin_ls binary in the mount\n// namespace cadvisor is running in or an error.  The locations checked are:\n//\n// - /sbin/\n// - /bin/\n// - /usr/sbin/\n// - /usr/bin/\n//\n// The thin_ls binary is provided by the device-mapper-persistent-data\n// package.\nfunc ThinLsBinaryPresent() (string, error) {\n\tvar (\n\t\tthinLsPath string\n\t\terr        error\n\t)\n\n\tfor _, path := range []string{\"/sbin\", \"/bin\", \"/usr/sbin/\", \"/usr/bin\"} {\n\t\t// try paths for non-containerized operation\n\t\t// note: thin_ls is most likely a symlink to pdata_tools\n\t\tthinLsPath = filepath.Join(path, \"thin_ls\")\n\t\t_, err = os.Stat(thinLsPath)\n\t\tif err == nil {\n\t\t\treturn thinLsPath, nil\n\t\t}\n\t}\n\n\treturn \"\", fmt.Errorf(\"unable to find thin_ls binary\")\n}\n"
  },
  {
    "path": "doc.go",
    "content": "// Copyright 2020 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage cadvisor\n"
  },
  {
    "path": "docs/api.md",
    "content": "# cAdvisor Remote REST API\n\ncAdvisor exposes its raw and processed stats via a versioned remote REST API:\n\n`http://<hostname>:<port>/api/<version>/<request>`\n\nThe current version of the API is `v1.3`.\n\nThere is a beta release of the `v2.0` API [available](api_v2.md).\n\n## Version 1.3\n\nThis version exposes the same endpoints as `v1.2` with one additional read-only endpoint.\n\n### Events\n\nThe resource name for Docker container information is as follows:\n\n`/api/v1.3/events/<absolute container name>`\n\nQuerying the endpoint receives a list of events which are a serialized `Event` JSON objects (found in [info/v1/container.go](../info/v1/container.go)).\n\nThe endpoint accepts a certain number of query parameters:\n\n| Parameter         | Description                                                                    | Default           |\n|-------------------|--------------------------------------------------------------------------------|-------------------|\n| `start_time`      | Start time of events to query (for stream=false)                               | Beginning of time |\n| `end_time`        | End time of events to query (for stream=false)                                 | Now               |\n| `stream`          | Whether to stream new events as they occur. If false returns historical events | false             |\n| `subcontainers`   | Whether to also return events for all subcontainers                            | false             |\n| `max_events`      | The max number of events to return (for stream=false)                          | 10                |\n| `all_events`      | Whether to include all supported event types                                   | false             |\n| `oom_events`      | Whether to include OOM events                                                  | false             |\n| `oom_kill_events` | Whether to include OOM kill events                                             | false             |\n| `creation_events` | Whether to include container creation events                                   | false             |\n| `deletion_events` | Whether to include container deletion events                                   | false             |\n\n## Version 1.2\n\nThis version exposes the same endpoints as `v1.1` with one additional read-only endpoint.\n\n### Docker Container Information\n\nThe resource name for Docker container information is as follows:\n\n`/api/v1.2/docker/<Docker container name or blank for all Docker containers>`\n\nThe Docker name can be either the UUID or the short name of the container. It returns the information of the specified container(s). The information is returned as a list of serialized `ContainerInfo` JSON objects (found in [info/v1/container.go](../info/v1/container.go)).\n\n## Version 1.1\n\nThis version exposes the same endpoints as `v1.0` with one additional read-only endpoint.\n\n### Subcontainer Information\n\nThe resource name for subcontainer information is as follows:\n\n`/api/v1.1/subcontainers/<absolute container name>`\n\nWhere the absolute container name follows the lmctfy naming convention (described bellow). It returns the information of the specified container and all subcontainers (recursively). The information is returned as a list of serialized `ContainerInfo` JSON objects (found in [info/v1/container.go](../info/v1/container.go)).\n\n## Version 1.0\n\nThis version exposes two main endpoints, one for container information and the other for machine information. Both endpoints are read-only in v1.0.\n\n### Container Information\n\nThe resource name for container information is as follows:\n\n`/api/v1.0/containers/<absolute container name>`\n\nWhere the absolute container name follows the lmctfy naming convention. For example:\n\n| Container Name       | Resource Name                             |\n|----------------------|-------------------------------------------|\n| /                    | /api/v1.0/containers/                     |\n| /foo                 | /api/v1.0/containers/foo                  |\n| /docker/2c4dee605d22 | /api/v1.0/containers/docker/2c4dee605d22  |\n\nNote that the root container (`/`) contains usage for the entire machine. All Docker containers are listed under `/docker`.\n\nThe container information is returned as a JSON object containing:\n\n- Absolute container name\n- List of subcontainers\n- ContainerSpec which describes the resource isolation enabled in the container\n- Detailed resource usage statistics of the container for the last `N` seconds (`N` is globally configurable in cAdvisor)\n- Histogram of resource usage from the creation of the container\n\nThe actual object is the marshalled JSON of the `ContainerInfo` struct found in [info/v1/container.go](../info/v1/container.go)\n\n### Machine Information\n\nThe resource name for machine information is as follows:\n\n`/api/vX.Y/machine`\n\nThis resource is read-only. The machine information is returned as a JSON object containing:\n\n- Number of schedulable logical CPU cores\n- Memory capacity (in bytes)\n- Maximum supported CPU frequency (in kHz)\n- Available filesystems: major, minor numbers and capacity (in bytes)\n- Network devices: mac addresses, MTU, and speed (if available)\n- Machine topology: Nodes, cores, threads, per-node memory, and caches\n\nThe actual object is the marshalled JSON of the `MachineInfo` struct found in [info/v1/machine.go](../info/v1/machine.go)\n"
  },
  {
    "path": "docs/api_v2.md",
    "content": "# cAdvisor Remote REST API\n\ncAdvisor exposes its raw and processed stats via a versioned remote REST API:\n\n`http://<hostname>:<port>/api/<version>/<request>`\n\nThis document covers the detail of version 2.0. All resources covered in this version are read-only.\n\nNOTE: v2.0 is still a work in progress.\n\n## Version information\n\nSoftware version for cAdvisor can be obtained from version endpoint as follows:\n`/api/v2.0/version`\n\n## Machine Information\n\nThe resource name for machine information is as follows:\n\n`/api/v2.0/machine`\n\nThe machine information is returned as a JSON object of the `MachineInfo` struct found in [info/v1/machine.go](../info/v1/machine.go)\n\n## Attributes\n\nAttributes endpoint provides hardware and software attributes of the running machine.\nThe resource name for attributes is:\n`/api/v2.0/attributes`\n\nHardware information includes all information covered by machine endpoint. Software information include version of cAdvisor, kernel, docker, and underlying OS.\n\nThe actual object is the marshalled JSON of the `Attributes` struct found in [info/v2/machine.go](../info/v2/machine.go)\n\n## Container Stats\nThe resource name for container stats information is:\n`/api/v2.0/stats/<container identifier>`\n\n### Stats request options\n\nStats support following options in the request:\n- `type`: describes the type of identifier. Supported values are `name`(default) and `docker`. `name` implies that the identifier is an absolute container name. `docker` implies that the identifier is a docker id.\n- `recursive`: Option to specify if stats for subcontainers of the requested containers should also be reported. Default is false.\n- `count`: Number of stats samples to be reported. Default is 64.\n\n### Container name\n\nWhen container identifier is of type `name`, the identifier is interpreted as the absolute container name. Naming follows the lmctfy convention. For example:\n\n| Container Name       | Resource Name                             |\n|----------------------|-------------------------------------------|\n| /                    | /api/v2.0/containers/                     |\n| /foo                 | /api/v2.0/containers/foo                  |\n| /docker/2c4dee605d22 | /api/v2.0/containers/docker/2c4dee605d22  |\n\nNote that the root container (`/`) contains usage for the entire machine. All Docker containers are listed under `/docker`. Also, `type=name` is not required in the examples above as `name` is the default type.\n\n### Docker Containers\n\nWhen container identifier is of type `docker`, the identifier is interpreted as docker id. For example:\n\n\n| Docker container     | Resource Name                             |\n|----------------------|-------------------------------------------|\n| All docker containers| /api/v2.0/stats?type=docker&recursive=true|\n| clever_colden        | /api/v2.0/stats/clever_colden?type=docker |\n| 2c4dee605d22         | /api/v2.0/stats/2c4dee605d22?type=docker  |\n\nThe Docker name can be either the UUID or the short name of the container. It returns the information of the specified container(s).\n\nNote that `recursive` is only valid when docker root is specified. It is used to get stats for all docker containers.\n\n### Returned stats\n\nThe stats information is returned  as a JSON object containing a map from container name to list of stat objects. Stat object is the marshalled JSON of the `ContainerStats` struct found in [info/v2/container.go](../info/v2/container.go)\n\n## Container Stats Summary\nInstead of a list of periodically collected detailed samples, cAdvisor can also provide a summary of stats for a container. It provides the latest collected stats and percentiles (max, average, and 90%ile) values for usage in last minute and hour. (Usage summary for last day exists, but is not currently used.)\n\nUnlike the regular stats API, only selected resources are captured by `summary`. Currently it is limited to cpu and memory usage.\n\nThe resource name for container summary information is:\n`/api/v2.0/summary/<container identifier>`\n\nAdditionally, `type` and `recursive` options can be used to describe the identifier type and ask for summary of all subcontainers respectively. The semantics are same as described for container stats above.\n\nThe returned summary information is a JSON object containing a map from container name to list of summary objects. Summary object is the marshalled JSON of the `DerivedStats` struct found in [info/v2/container.go](../info/v2/container.go)\n\n## Container Spec\n\nThe resource name for container stats information is:\n`/api/v2.0/spec/<container identifier>`\n\nAdditionally, `type` and `recursive` options can be used to describe the identifier type and ask for spec of all subcontainers respectively. The semantics are same as described for container stats above.\n\nThe spec information is returned as a JSON object containing a map from container name to list of spec objects. Spec object is the marshalled JSON of the `ContainerSpec` struct found in [info/v2/container.go](../info/v2/container.go)\n\n"
  },
  {
    "path": "docs/application_metrics.md",
    "content": "# Collecting Application Metrics with cAdvisor\n\n**Note** Application metrics support is in Alpha. We are still making a bunch of interface changes.\n\n## Introduction\nIn addition to usage metrics, cAdvisor can also be configured to collect application metrics. A container can expose application metrics through multiple ways - on a status page, through structured info like prometheus, or have a separate API for fetching stats. cAdvisor provides a generic way to collect these metrics. Additional templates are provided to automate some well-known collection profiles.\n\n## Specifying application metrics\n\nApplication metrics specification consists of two steps:\n* Creating a configuration\n* Passing the configuration location to cadvisor\n\n## Creating a configuration\nAn application metric configuration tells cAdvisor where to look for application metrics and specifies other parameters about how to export the metrics from cAdvisor to UI and backends. The metric config includes:\n* Endpoint (Location to collect metrics from)\n* Name of metric\n* Type (Counter, Gauge, ...)\n* Data Type (int, float)\n* Units (kbps, seconds, count)\n* Polling Frequency\n* Regexps (Regular expressions to specify which metrics to collect and how to parse them)\n\nHere is an example of a very generic metric collector that assumes no structured information:\n\n```\n{\n  \"endpoint\" : \"http://localhost:8000/nginx_status\",\n  \"metrics_config\" : [\n    {\n      \"name\" : \"activeConnections\",\n      \"metric_type\" : \"gauge\",\n      \"units\" : \"number of active connections\",\n      \"data_type\" : \"int\",\n      \"polling_frequency\" : 10,\n      \"regex\" : \"Active connections: ([0-9]+)\"\n    },\n    {\n      \"name\" : \"reading\",\n      \"metric_type\" : \"gauge\",\n      \"units\" : \"number of reading connections\",\n      \"data_type\" : \"int\",\n      \"polling_frequency\" : 10,\n      \"regex\" : \"Reading: ([0-9]+) .*\"\n    }\n  ]\n} \n```\n\nFor structured metrics export, eg. Prometheus, the config can shrink down to just the endpoint, as other information can be gleaned from the structure. Here is a sample prometheus config that collects all metrics from an endpoint.\n\n```\n{\n  \"endpoint\" : \"http://localhost:9100/metrics\"\n}\n```\n\nAnother sample config that collects only selected metrics:\n\n```\n{\n  \"endpoint\" : \"http://localhost:8000/metrics\",\n  \"metrics_config\" : [\n    \"scheduler_binding_latency\",\n    \"scheduler_e2e_scheduling_latency\",\n    \"scheduling_algorithm_latency\"\n  ]\n}\n```\n\n## Passing the configuration to cAdvisor\n\ncAdvisor can discover any configurations for a container using Docker container labels. Any label starting with ```io.cadvisor.metric``` is parsed as a cadvisor application-metric label.\ncAdvisor uses the value as an indicator of where the configuration can be found.  Labels of the form ```io.cadvisor.metric.prometheus-xyz``` indicate that the configuration points to a\nPrometheus metrics endpoint.\n\nThe configuration file can either be part of the container image or can be added on at runtime with a volume. This makes sure that there is no connection between the host where the container is running and the application metrics configuration. A container is self-contained for its metric information.\n\nSo a sample configuration for redis would look like:\n\nDockerfile (or runtime):\n```\n FROM redis\n ADD redis_config.json /var/cadvisor/redis_config.json\n LABEL io.cadvisor.metric.redis=\"/var/cadvisor/redis_config.json\"\n```\n\ncAdvisor will then reach into the container image at runtime, process the config, and start collecting and exposing application metrics.\n\nNote that cAdvisor specifically looks at the container labels to extract this information.  In Docker 1.8, containers don't inherit labels\nfrom their images, and thus you must specify the label at runtime.\n\n## API access to application-specific metrics\n\nA new endpoint is added for collecting application-specific metrics for a particular container:\n\n```\nhttp://localhost:8080/api/v2.0/appmetrics/containerName\n```\n\nThe set of application-metrics being collected can be discovered from the container spec:\n\n```\nhttp://localhost:8080/api/v2.0/spec/containerName\n```\n\nRegular stats API also has application-metrics appended to it:\n\n```\nhttp://localhost:8080/api/v2.0/stats/containerName\n```\n\n## UI changes\nApplication-metrics show up on the container page after the resource metrics.\n\n## Ongoing work\n\n### Templates\nNext step for application-metrics is to add templates for well-known containers that have stable stats API. These would be specified by a new label ```io.cadvisor.metric.type```. If the label value is a known type, cAdvisor would start collecting stats automatically without needing any further config. Config can still be used to override any specific parameters - like set of metrics to collect. \n\n### UI enhancements\nThere are a bunch of UI enhancements under way:\n* Better handling/display of metrics - eg. allowing overlaying metrics on the same graphs, handling metric types like percentiles.\n* Moving application metrics to separate tab.\n* Adding control to show only selected metrics on UI while still exporting everything through the API.\n"
  },
  {
    "path": "docs/clients.md",
    "content": "# cAdvisor API Clients\n\nThere is an official Go client implementation in the [client](../client/) directory. You can use it on your own Go project by including it like this:\n\n```go\nimport \"github.com/google/cadvisor/client\"\n\nclient, err = client.NewClient(\"http://localhost:8080/\")\nmInfo, err := client.MachineInfo()\n```\n\nDo you know of another cAdvisor client? Maybe in another language? Please let us know! We'd be happy to add a note on this page.\n"
  },
  {
    "path": "docs/deploy.md",
    "content": "# Building and Deploying the cAdvisor Docker Container\n\n## Building\n\nBuilding the cAdvisor Docker container is simple, just run:\n\n```\n$ ./deploy/build.sh\n```\n\nWhich will statically build the cAdvisor binary and then build the Docker image. The resulting Docker image will be called `google/cadvisor:beta`. This image is very bare, containing the cAdvisor binary and nothing else.\n\n## Deploying\n\nAll cAdvisor releases are tagged and correspond to a Docker image. The latest supported release uses the `latest` tag. We have a `beta` and `canary` tag for pre-release versions with newer features. You can see more details about this in the cAdvisor [Google Container Registry](https://gcr.io/cadvisor/cadvisor) page.\n"
  },
  {
    "path": "docs/development/README.md",
    "content": "The [development](./) directory holds documentation for cAdvisor developers and contributors. If you\nare looking for development using cAdvisor (as opposed to development of cAdvisor), then these\ndocuments probably don't apply to you.\n"
  },
  {
    "path": "docs/development/build.md",
    "content": "# Building and Testing cAdvisor\n\n**Note**: cAdvisor only builds on Linux since it uses Linux-only APIs.\n\n## Installing Dependencies\n\ncAdvisor is written in the [Go](http://golang.org) programming language. If you haven't set up a Go development environment, please follow [these instructions](http://golang.org/doc/code.html) to install go tool and set up GOPATH. Note that the version of Go in package repositories of some operating systems is outdated, so please [download](https://golang.org/dl/) the latest version.\n\n**Note**: cAdvisor requires Go 1.14 to build.\n\nAfter setting up Go, you should be able to `go get` cAdvisor as expected (we use `-d` to only download):\n\n```\n$ go get -d github.com/google/cadvisor\n```\n\n## Building from Source\n\nAt this point you can build cAdvisor from the source folder:\n\n```\n$GOPATH/src/github.com/google/cadvisor $ make build\n```\n\nor run only unit tests:\n\n```\n$GOPATH/src/github.com/google/cadvisor $ make test\n```\n\nFor integration tests, see the [integration testing](integration_testing.md) page.\n\n### Non-volatile Memory Support\n\ncAdvisor can be linked against [libipmctl](https://github.com/intel/ipmctl) library that allows to gather information about Intel® Optane™ DC Persistent memory. If you want to build cAdvisor with libipmctl support you must meet following requirements:\n* `libipmctl-devel` must be installed on build system.\n* `libipmctl` must be installed on all systems where cAdvisor is running.\n\nDetailed information about building `libipmctl` can be found in the project's [README](https://github.com/intel/ipmctl#build). Make sure to use the most up to date released version. Functionality that relies on `libipmctl` was tested against version 02.00.00.3820 of the library.\n\nTo enable `libipmctl` support `GO_FLAGS` variable must be set:\n\n```\n$GOPATH/src/github.com/google/cadvisor $ GO_FLAGS=\"-tags=libipmctl,netgo\" make build\n```\n\n### Perf Support\n\ncAdvisor can be linked against [libpfm4](http://perfmon2.sourceforge.net/) library that allows to gather information about performance monitoring events.\nIf you want to build cAdvisor with libpfm4 support you must meet following requirements:\n* `libpfm4-dev` must be installed on build system.\n* `libpfm4` must be installed on all systems where cAdvisor is running.\n\nlibpfm4 packages are available in Debian- and RHEL-derivatives distributions.\n\nlibpfm4 can be installed using apt package manager:\n```\napt-get install libpfm4 libpfm4-dev\n```\nor yum package manager:\n```\nyum install libpfm libpfm-devel\n```\n\nTo enable `libpfm4` support `GO_FLAGS` variable must be set:\n\n```\n$GOPATH/src/github.com/google/cadvisor $ GO_FLAGS=\"-tags=libpfm,netgo\" make build\n```\n\n## Running Built Binary\n\nNow you can run the built binary:\n\n```\n$GOPATH/src/github.com/google/cadvisor $ sudo ./cadvisor\n```\n\n### Perf Support\n\nIt is required to include perf config (examplary config is available [here](../../perf/testing/perf-non-hardware.json)) to run cAdvisor with performance monitoring events:\n```\n$GOPATH/src/github.com/google/cadvisor $ sudo ./cadvisor -perf_events_config=perf/testing/perf-non-hardware.json\n\n```\n"
  },
  {
    "path": "docs/development/integration_testing.md",
    "content": "# Integration Testing cAdvisor \n\n## Docker-based tests\n\nThe cAdvisor integration tests are run per-pr using [Github Actions](https://help.github.com/en/actions). Workflow configuration can be found at [.github/workflows/test.yml](.github/workflows/test.yml). Tests are executed in Docker containers run on MS Azure virtual machines.\n\nTo run them locally Docker must be installed on your machine. Following command allows you to execute default suite of integration tests:\n\n```\nmake docker-test-integration\n```\n\nBuild scripts take care of building cAdvisor and integration tests, and executing them against running cAdvisor process.\n\nIn order to run non-default tests suites (e.g. such that rely on third-party C libraries) you must source one of the files available at [build/config](build/config), e.g.:\n\n```\nsource build/config/libpfm4.sh && make docker-test-integration\n```\n\nAll the necessary packages will be installed, build flags will be applied and additional parameters will be passed to cAdvisor automatically. Configuration is performed using shell environment variables.\n\n## VM-base tests (legacy)\n\nThe cAdvisor integration tests are run per-pr using the [kubernetes node-e2e testing framework](https://github.com/kubernetes/community/blob/master/contributors/devel/e2e-node-tests.md) on GCE instances.  To make use of this framework, complete the setup of GCP described in the node-e2e testing framework, clone `k8s.io/kubernetes`, and from that repository run:\n```\n$ make test-e2e-node TEST_SUITE=cadvisor REMOTE=true\n```\nThis will create a VM, build cadvisor, run integration tests on that VM, retrieve logs, and will clean up the test afterwards.  See the [node-e2e testing documentation](https://github.com/kubernetes/community/blob/master/contributors/devel/e2e-node-tests.md) for more running options.\n\nTo simply run the tests against an existing cAdvisor:\n\n```\n$ go test github.com/google/cadvisor/integration/tests/... -host=HOST -port=PORT\n```\n\nNote that `HOST` and `PORT` default to `localhost` and `8080` respectively.\nToday We only support remote execution in Google Compute Engine since that is where we run our continuous builds.\n"
  },
  {
    "path": "docs/development/issues.md",
    "content": "# GitHub Issue tracking cAdvisor\n\nThis document outlines the process around GitHub issue tracking for cAdvisor at https://github.com/google/cadvisor/issues\n\n## Labels\n\nA brief explanation of what issue labels mean. Most labels also apply to pull requests, but for pull\nrequests which reference an issue, it is not necessary to copy the same labels to the PR.\n\n- `area/API` - For issues related to the API.\n- `area/UI` - For issues related to the web UI.\n- `area/documentation` - For issues related to the documentation (inline comments or markdown).\n- `area/performance` - For issues related to cAdvisor performance (speed, memory, etc.).\n- `area/storage` - For issues related to cAdvisor storage plugins.\n- `area/testing` - For issues related to testing (integration tests, unit tests, jenkins, etc.)\n- `closed/duplicate` - For issues which have been closed as duplicates of another issue. The final\n  comment on the issue should hold a reference the duplicate issue.\n- `closed/infeasible` - For issues which cannot be resolved (e.g. a request for a feature we cannot\n  or do not want to add).\n- `community-assigned` - For issues which are being worked on by a community member (when github won't let us assign the issue to them).\n- `kind/bug` - For issues referring to a bug in the existing implementation.\n- `kind/enhancement` - For issues proposing an enhancement or new feature.\n- `kind/support` - For issues which might just be user confusion / environment setup. If support\n  issue ends up requiring a PR, it should probably be relabeled (for example, to `bug`). Many\n  support issues may indicate a shortcoming of the documentation.\n- `help wanted` - For issues which have been highlighted as a good place to contribute to\n  cAdvisor. `help wanted` issues could be enhancements that the core team is unlikely to get to in\n  the near future, or small projects which might be a good starting point. Lack of a `help wanted`\n  label does not mean we won't accept contributions, it only means it was not identified as a\n  candidate project for community contributions.\n"
  },
  {
    "path": "docs/development/releasing.md",
    "content": "# cAdvisor Release Instructions\n\n## 1. Send Release PR\n\nExample: https://github.com/google/cadvisor/pull/1281\n\nAdd release notes to [CHANGELOG.md](../../CHANGELOG.md)\n\n- Tip: Use a github PR search to find changes since the last release\n  `is:pr is:merged merged:>2016-04-21`\n\n## 2. Create the release tag\n\n### 2.a Create the release branch (only for major/minor releases)\n\nSkip this step for patch releases.\n\n```\n# Example version\nVERSION=v0.23\nPATCH_VERSION=$VERSION.0\n# Sync to HEAD, or the commit to branch at\ngit fetch upstream && git checkout upstream/master\n# Create the branch\ngit branch release-$VERSION\n# Push it to upstream\ngit push git@github.com:google/cadvisor.git release-$VERSION\n```\n\n### 2.b Tag the release (for all releases)\n\n```\n# Example patch version\nVERSION=v0.23\nPATCH_VERSION=$VERSION.0\n# Checkout the release branch\ngit fetch upstream && git checkout upstream/release-$VERSION\n# Tag the release commit. If you aren't signing, ommit the -s\ngit tag -s -a $PATCH_VERSION\n# Push it to upstream\ngit push git@github.com:google/cadvisor.git $PATCH_VERSION\n```\n\n## 3. Build release artifacts\n\nCommand: `make release`\n\n- Make sure your git client is synced to the release cut point\n- Use the same go version as kubernetes: [dependencies.yaml](https://github.com/kubernetes/kubernetes/blob/master/build/dependencies.yaml#L101)\n- Tip: use https://github.com/moovweb/gvm to manage multiple go versions.\n- Try to build it from the release branch, since we include that in the binary version\n- Verify the ldflags output, in particular check the Version, BuildUser, and GoVersion are expected\n\nOnce the build is complete, copy the output after `Release info...` and save it to use in step 5\n\nExample:\n\n```\nMulti Arch Container:\ngcr.io/cadvisor/cadvisor:v0.44.1-test-8\n\nArchitecture Specific Containers:\ngcr.io/cadvisor/cadvisor-arm:v0.44.1-test-8\ngcr.io/cadvisor/cadvisor-arm64:v0.44.1-test-8\ngcr.io/cadvisor/cadvisor-amd64:v0.44.1-test-8\n\nBinaries:\nSHA256 (cadvisor-v0.44.1-test-8-linux-arm64) = e5e3f9e72208bc6a5ef8b837473f6c12877ace946e6f180bce8d81edadf66767\nSHA256 (cadvisor-v0.44.1-test-8-linux-arm) = 7d714e495a4f50d9cc374bd5e6b5c6922ffa40ff1cc7244f2308f7d351c4ccea\nSHA256 (cadvisor-v0.44.1-test-8-linux-amd64) = ea95c5a6db8eecb47379715c0ca260a8a8d1522971fd3736f80006c7f6cc9466\n```\n\n## 4. Check that the Containers for the release work\n\nThe only argument to the script is the tag of the Multi Arch Container from step\n3. To verify that the container images for the release were built successfully,\nuse the check_container.sh script. The script will start each cadvisor image and\ncurl the `/healthz` endpoint to confirm that it is working.\n\nRunning this script requires that you have installed `qemu-user-static` and\nconfigured qemu as a binary interpreter.\n\n```\n$ sudo apt install qemu-user-static\n$ docker run --rm --privileged multiarch/qemu-user-static --reset -p yes\n```\n\nThe only argument to the script is the tag of the Multi Arch Container from step\n3.\n\n```sh\nbuild/check_container.sh gcr.io/tstapler-gke-dev/cadvisor:v0.44.1-test-8\n```\n\n## 5. Cut the release\n\nGo to https://github.com/google/cadvisor/releases and click \"Draft a new\nrelease\"\n\n- \"Tag version\" and \"Release title\" should be preceded by 'v' and then the\n  version. Select the tag pushed in step 2.b\n- Copy an old release as a template (e.g.\n  github.com/google/cadvisor/releases/tag/v0.23.1)\n- Body should start with release notes (from CHANGELOG.md)\n- Next are the docker images and binary hashes you copied (from step 3).\n- Upload the binaries build in step 3, they are located in the `_output`\n  directory.\n- If this is a minor version release, mark the release as a \"pre-release\"\n- Click publish when done"
  },
  {
    "path": "docs/roadmap.md",
    "content": "# cAdvisor project roadmap\n\nLast updated: Jan 2026.\nStatus: proposed by SIG Node.\n\nNext steps:\n\n- Otel community agreement\n- detailed plans\n\n## Motivation\n\nThe motivation for this document is a set of new requests for cAdvisor standalone mode. These requests is a reminder that we need to define a cAdvisor roadmap in light of a current developments in K8s project and a modern landscape of tools and projects.\n\n## Background\n\nCAdvisor consists of two parts that are interleaved and interconnected:\n\n- a library linked into kubelet used to provide information about resource usage that K8s project depends on.\n- standalone binary for users to monitor containerized workloads. This includes, but not limited to kubernetes. Outside of kubernetes it is docker containers, Mesos, etc. and provide support for dedicated hardware such as Intel PMU perf metrics.\n\nThe project was originated when the industry looked very differently and not well aligned with modern landscape of tools and projects.\n\nAlso, since cAdvisor is a Google project, rather than a kubernetes project, results in a few issues:\n\n- Google outsized ownership and responsibility for this project with limited OSS governance model.\n- K8s contributors that currently maintains it has little vested interest in owning the standalone mode scenarios.\n- Every release of kubernetes requires cAdvisor to be vendored into k8s tree, which can cause significant “dependency hell” and limits what standalone mode cAdvisor can do.\n\nThere is ongoing work to deprecate the cAdvisor as a vendored library for k8s. The work consist of multiple stages. First stage is tracked as part of this enhancement:  [cAdvisor-less, CRI-full Container and Pod Stats](https://github.com/kubernetes/enhancements/issues/2371). There will be more work needed after the KEP above is merged to transition machine-wide metrics to containerd.\n\nOnce the transition of metrics to container runtime complete, the cAdvisor project will not be in scope of k8s contributors and will be more aligned with the OpenTelemetry project.\n\nAlso unless SIG instrumentation will take it as their scope, we will deprecate the cAdvisor endpoint and not accept requests like this: [Configurable cAdvisor Metrics Collection](https://github.com/kubernetes/enhancements/pull/5776) as those are also more aligned with the telemetry scenarios rather than orchestration.\n\n## cAdvisor roadmap\n\n### K8s side\n\n#### 2026\n\n- finish transition of Pod merics to K8s: [cAdvisor-less, CRI-full Container and Pod Stats](https://github.com/kubernetes/enhancements/issues/2371)\n- start transition of machine-level metrics to Container Runtime (KEP: TBD).  \n- Decide on the future of `cadvisor` endpoint - likely deprecation of the `cadvisor` endpoint of kubelet\n\n#### 2027\n\n- Stop vendoring cAdvisor to K8s.\n\n#### 2027+ (maybe way passed it)\n\n- Remove the `cadvisor` endpoint of kubelet\n\n### cAdvisor standalone\n\nThe proposal is to move cAdvisor standalone scenarios to Otel collector. New [receivers](https://opentelemetry.io/docs/collector/components/receiver/) will collect similar information to what cAdvisor collects today and Otel collector can be configured to export as Prometheus endpoint or [any other supported exporter](https://opentelemetry.io/docs/collector/components/exporter/). So there will be a transition path from cAdvisor standalone to Otel collector.\n\nThe same time cAdvisor project will be placed in maintenance mode and eventually closed.\n\nIf there will be interest from any project or 3rd party to pick up the project and transfer it to CNCF or other project - there will be an open discussion on this.\n\n## Notes on transition to Otel Collector\n\nThis is not a detailed spec on transition to Otel Collector. The intent of this section is to highlight the tension points that needs to be clarified as the transition specs are written.\n\n### Distribution model\n\ncAdvisor is a specialized software for containers metrics collection. It is easier to configure and likely more lightweight. Otel collector will need to be compiled with the right set of receivers and exporters and configured appropriately.\n\nThe benefit of using Otel Collector for these scenarios is its flexibility in collecting telemetry for more scenarios and a well-known config as oppose to a custom cAdvisor configuration.\n\nThe believe of this roadmap is that benefits of cAdvisor's distribution model will not be significant enough to prefer it over the Otel collector.\n\n### Supported metrics\n\nThe proposal is to transition all metrics to Otel collector to make sure a smooth transition for time-proof set of metrics. However the detailed plan is needed to make a final decision.\n\nThe design may split metrics into multiple receivers if this will be more convenient.\n\n### Supported endpoints\n\nBeyond prometheus metrics, cAdvisor supports a few more endpoint. The list is here: https://github.com/google/cadvisor/blob/master/docs/api.md\n\n### prometheus\n\nPrometheus endpoints may expose metrics in a format different as Otel collector prefer dots in names to underscores. Also other renames may potentially be needed as metric names will be aligned with Otel Semantic Convention.\n\nOtel collector will expose the single prometheus endpoint with all metrics for all containers and will not support [container-specific endpoints](https://github.com/google/cadvisor/blob/master/docs/application_metrics.md#api-access-to-application-specific-metrics).\n\n### events\n\nThe proposal is to collect events as Otel events.\n\nThere is no analogous of events endpoint in Otel collector. So transition to Otel events will require to change design of consumers from pull model to push model for events.\n\n#### docker\n\nNot supported. No alternatives offered.\n\n#### subcontainers\n\nNot supported. No alternatives offered.\n\n#### containers\n\nNot supported. No alternatives offered.\n\n#### machine\n\nNot supported, use [Node Feature Discovery](https://github.com/kubernetes-sigs/node-feature-discovery).\n\n### Supported runtimes\n\nThe proposal is to transition container-based metrics collection to Otel collector so all advanced metrics and non-Kubernetes environments monitoring is supported by Otel collector. This way Otel collector will support the same set of environments and runtimes as cAdvisor does today. This may be done by copying code from cAdvisor.\n\nHowever, as a more lightweight implementation, Otel collector may also implement receivers that are based on CRI-exposed metrics based on KEP [cAdvisor-less, CRI-full Container and Pod Stats](https://github.com/kubernetes/enhancements/issues/2371). These receivers will be less flexible and limited to Kubernetes scenarios. However these receivers will be more reliable.\n\nThe proposal is to design for the full set of scenarios, but not limiting to it and allow for CRI-based metrics receivers.\n\n### Supported OSes\n\ncAdvisor does NOT support Windows containers monitoring while Otel collector does. There is a potential for Otel collector to implement this scenario, but it will be outside of a scope of this roadmap document.\n"
  },
  {
    "path": "docs/running.md",
    "content": "# Running cAdvisor\n\n## With Docker\n\nWe have a Docker image that includes everything you need to get started. Simply run:\n\n```\nVERSION=v0.35.0 # use the latest release version from https://github.com/google/cadvisor/releases\nsudo docker run \\\n  --volume=/:/rootfs:ro \\\n  --volume=/var/run:/var/run:rw \\\n  --volume=/sys:/sys:ro \\\n  --volume=/var/lib/docker/:/var/lib/docker:ro \\\n  --publish=8080:8080 \\\n  --detach=true \\\n  --name=cadvisor \\\n  ghcr.io/google/cadvisor:$VERSION # for versions prior to v0.53.0, use gcr.io/cadvisor/cadvisor instead\n```\n\ncAdvisor is now running (in the background) on `http://localhost:8080/`. The setup includes directories with Docker state cAdvisor needs to observe.\n\n**Note**:\n- If docker daemon is running with [user namespace enabled](https://docs.docker.com/reference/cli/dockerd/#daemon-user-namespace-options),\nyou need to add `--userns=host` option in order for cAdvisor to monitor Docker containers,\notherwise cAdvisor can not connect to docker daemon.\n- If cadvisor scrapes `process` metrics due to `--disable_metrics` or `--enable_metrics` options, you need to add `--pid=host` and `--privileged` for `docker run` to get `/proc/pid/fd` path in host.\n- If cAdvisor needs to be run in Docker container without `--privileged` option it is possible to add host devices to container using `--dev` and\n  specify security options using `--security-opt` with secure computing mode (seccomp).\n  For details related to seccomp please [see](https://docs.docker.com/engine/security/seccomp/), the default Docker profile can be found [here](https://github.com/moby/moby/blob/master/profiles/seccomp/default.json).\n\n  For example to run cAdvisor with perf support in Docker container without `--privileged` option it is required to:\n  - Set perf_event_paranoid using `sudo sysctl kernel.perf_event_paranoid=-1`, see [documentation](https://www.kernel.org/doc/Documentation/sysctl/kernel.txt)\n  - Add \"perf_event_open\" syscall into syscalls array with the action: \"SCMP_ACT_ALLOW\" in [default Docker profile](https://github.com/moby/moby/blob/master/profiles/seccomp/default.json)\n  - Run Docker container with following options:\n  ```\n  docker run \\\n  --volume=/:/rootfs:ro \\\n  --volume=/var/run:/var/run:ro \\\n  --volume=/sys:/sys:ro \\\n  --volume=/var/lib/docker/:/var/lib/docker:ro \\\n  --volume=/dev/disk/:/dev/disk:ro \\\n  --volume=$GOPATH/src/github.com/google/cadvisor/perf/testing:/etc/configs/perf \\\n  --publish=8080:8080 \\\n  --device=/dev/kmsg \\\n  --security-opt seccomp=default.json \\\n  --name=cadvisor \\\n  ghcr.io/google/cadvisor:<tag> -perf_events_config=/etc/configs/perf/perf.json\n  ```\n\n## With Boot2Docker\n\nAfter booting up a boot2docker instance, run cAdvisor image with the same docker command mentioned above. cAdvisor can now be accessed at port 8080 of your boot2docker instance. The host IP can be found through DOCKER_HOST environment variable setup by boot2docker:\n\n```\n$ echo $DOCKER_HOST\ntcp://192.168.59.103:2376\n```\n\nIn this case, cAdvisor UI should be accessible on `http://192.168.59.103:8080`\n\n## Other Configurations\n\n### CentOS, Fedora, and RHEL\n\nYou may need to run the container with `--privileged=true` and `--volume=/cgroup:/cgroup:ro \\` in order for cAdvisor to monitor Docker containers.\n\nRHEL and CentOS lock down their containers a bit more. cAdvisor needs access to the Docker daemon through its socket. This requires `--privileged=true` in RHEL and CentOS.\n\nOn some versions of RHEL and CentOS the cgroup hierarchies are mounted in `/cgroup` so run cAdvisor with an additional Docker option of `--volume=/cgroup:/cgroup:ro \\`.\n\n**Note**: For a RedHat 7 docker host the default run commands from above throw oci errors. Please use the command below if the host is RedHat 7:\n```\ndocker run\n--volume=/:/rootfs:ro\n--volume=/var/run:/var/run:rw\n--volume=/sys/fs/cgroup/cpu,cpuacct:/sys/fs/cgroup/cpuacct,cpu\n--volume=/var/lib/docker/:/var/lib/docker:ro\n--publish=8080:8080\n--detach=true\n--name=cadvisor\n--privileged=true\ngoogle/cadvisor:latest\n```\n\n\n### Debian\n\nBy default, Debian disables the memory cgroup which does not allow cAdvisor to gather memory stats. To enable the memory cgroup take a look at [these instructions](https://github.com/google/cadvisor/issues/432).\n\n### LXC Docker exec driver\n\nIf you are using Docker with the LXC exec driver, then you need to manually specify all cgroup mounts by adding the:\n\n```\n  --volume=/cgroup/cpu:/cgroup/cpu \\\n  --volume=/cgroup/cpuacct:/cgroup/cpuacct \\\n  --volume=/cgroup/cpuset:/cgroup/cpuset \\\n  --volume=/cgroup/memory:/cgroup/memory \\\n  --volume=/cgroup/blkio:/cgroup/blkio \\\n```\n\n### Invalid Bindmount `/`\n\nThis is a problem seen in older versions of Docker. To fix, start cAdvisor without the `--volume=/:/rootfs:ro` mount. cAdvisor will degrade gracefully by dropping stats that depend on access to the machine root.\n\n## Standalone\n\ncAdvisor is a static Go binary with no external dependencies. To run it standalone all you should need to do is run it! Note that some data sources may require root privileges. cAdvisor will gracefully degrade its features to those it can expose with the access given.\n\n```\n$ sudo cadvisor\n```\n\ncAdvisor is now running (in the foreground) on `http://localhost:8080/`.\n\n## Runtime Options\n\ncAdvisor has a series of flags that can be used to configure its runtime behavior. More details can be found in runtime [options](runtime_options.md).\n"
  },
  {
    "path": "docs/runtime_options.md",
    "content": "# cAdvisor Runtime Options\n\nThis document describes a set of runtime flags available in cAdvisor.\n\n## Container labels\n* `--store_container_labels=false` - do not convert container labels and environment variables into labels on prometheus metrics for each container.\n* `--whitelisted_container_labels` - comma separated list of container labels to be converted to labels on prometheus metrics for each container. `store_container_labels` must be set to false for this to take effect.\n\n## Container envs\n\n* `--env_metadata_whitelist`: a comma-separated list of environment variable keys that needs to be collected for containers, only support containerd and docker runtime for now.\n\n## Limiting which containers are monitored\n* `--docker_only=false` - do not report raw cgroup metrics, except the root cgroup.\n* `--raw_cgroup_prefix_whitelist` - a comma-separated list of cgroup path prefix that needs to be collected even when `--docker_only` is specified\n* `--disable_root_cgroup_stats=false` - disable collecting root Cgroup stats.\n\n## Container Hints\n\nContainer hints are a way to pass extra information about a container to cAdvisor. In this way cAdvisor can augment the stats it gathers. For more information on the container hints format see its [definition](../container/common/container_hints.go). Note that container hints are only used by the raw container driver today.\n\n```\n--container_hints=\"/etc/cadvisor/container_hints.json\": location of the container hints file\n```\n\n## CPU\n\n```\n--enable_load_reader=false: Whether to enable cpu load reader\n--max_procs=0: max number of CPUs that can be used simultaneously. Less than 1 for default (number of cores).\n```\n\n## Debugging and Logging\n\ncAdvisor-native flags that help in debugging:\n\n```\n--log_backtrace_at=\"\": when logging hits line file:N, emit a stack trace\n--log_cadvisor_usage=false: Whether to log the usage of the cAdvisor container\n--version=false: print cAdvisor version and exit\n--profiling=false: Enable profiling via web interface host:port/debug/pprof/\n```\n\nFrom [glog](https://github.com/golang/glog) here are some flags we find useful:\n\n```\n--log_dir=\"\": If non-empty, write log files in this directory\n--logtostderr=false: log to standard error instead of files\n--alsologtostderr=false: log to standard error as well as files\n--stderrthreshold=0: logs at or above this threshold go to stderr\n--v=0: log level for V logs\n--vmodule=: comma-separated list of pattern=N settings for file-filtered logging\n```\n\n## Docker\n\n```\n--docker=\"unix:///var/run/docker.sock\": docker endpoint (default \"unix:///var/run/docker.sock\")\n--docker_root=\"/var/lib/docker\": DEPRECATED: docker root is read from docker info (this is a fallback, default: /var/lib/docker) (default \"/var/lib/docker\")\n--docker-tls: use TLS to connect to docker\n--docker-tls-cert=\"cert.pem\": client certificate for TLS-connection with docker\n--docker-tls-key=\"key.pem\": private key for TLS-connection with docker\n--docker-tls-ca=\"ca.pem\": trusted CA for TLS-connection with docker\n```\n\n## Podman\n\n```bash\n--podman=\"unix:///var/run/podman/podman.sock\": podman endpoint (default \"unix:///var/run/podman/podman.sock\")\n```\n\n## Housekeeping\n\nHousekeeping is the periodic actions cAdvisor takes. During these actions, cAdvisor will gather container stats. These flags control how and when cAdvisor performs housekeeping.\n\n#### Dynamic Housekeeping\n\nDynamic housekeeping intervals let cAdvisor vary how often it gathers stats.\nIt does this depending on how active the container is. Turning this off\nprovides predictable housekeeping intervals, but increases the resource usage\nof cAdvisor.\n\n```\n--allow_dynamic_housekeeping=true: Whether to allow the housekeeping interval to be dynamic\n```\n\n#### Housekeeping Intervals\n\nIntervals for housekeeping. cAdvisor has two housekeepings: global and per-container.\n\nGlobal housekeeping is a singular housekeeping done once in cAdvisor. This typically does detection of new containers. Today, cAdvisor discovers new containers with kernel events so this global housekeeping is mostly used as backup in the case that there are any missed events.\n\nPer-container housekeeping is run once on each container cAdvisor tracks. This typically gets container stats.\n\n```\n--global_housekeeping_interval=1m0s: Interval between global housekeepings\n--housekeeping_interval=1s: Interval between container housekeepings\n--max_housekeeping_interval=1m0s: Largest interval to allow between container housekeepings (default 1m0s)\n```\n\n## HTTP\n\nSpecify where cAdvisor listens.\n\n```\n--http_auth_file=\"\": HTTP auth file for the web UI\n--http_auth_realm=\"localhost\": HTTP auth realm for the web UI (default \"localhost\")\n--http_digest_file=\"\": HTTP digest file for the web UI\n--http_digest_realm=\"localhost\": HTTP digest file for the web UI (default \"localhost\")\n--listen_ip=\"\": IP to listen on, defaults to all IPs\n--port=8080: port to listen (default 8080)\n--url_base_prefix=/: optional path prefix aded to all resource URLs; useful when running cAdvisor behind a proxy. (default /)\n```\n\n## Local Storage Duration\n\ncAdvisor stores the latest historical data in memory. How long of a history it stores can be configured with the `--storage_duration` flag.\n\n```\n--storage_duration=2m0s: How long to store data.\n```\n\n## Machine\n\n```\n--boot_id_file=\"/proc/sys/kernel/random/boot_id\": Comma-separated list of files to check for boot-id. Use the first one that exists. (default \"/proc/sys/kernel/random/boot_id\")\n--machine_id_file=\"/etc/machine-id,/var/lib/dbus/machine-id\": Comma-separated list of files to check for machine-id. Use the first one that exists. (default \"/etc/machine-id,/var/lib/dbus/machine-id\")\n--update_machine_info_interval=5m: Interval between machine info updates. (default 5m)\n```\n\n## Metrics\n\n```\n--application_metrics_count_limit=100: Max number of application metrics to store (per container) (default 100)\n--collector_cert=\"\": Collector's certificate, exposed to endpoints for certificate based authentication.\n--collector_key=\"\": Key for the collector's certificate\n--disable_metrics=<metrics>: comma-separated list of metrics to be disabled. Options are advtcp,app,cpu,cpuLoad,cpu_topology,cpuset,disk,diskIO,hugetlb,memory,memory_numa,network,oom_event,percpu,perf_event,process,referenced_memory,resctrl,sched,tcp,udp. (default advtcp,cpu_topology,cpuset,hugetlb,memory_numa,process,referenced_memory,resctrl,sched,tcp,udp)\n--enable_metrics=<metrics>: comma-separated list of metrics to be enabled. If set, overrides 'disable_metrics'. Options are advtcp,app,cpu,cpuLoad,cpu_topology,cpuset,disk,diskIO,hugetlb,memory,memory_numa,network,oom_event,percpu,perf_event,process,referenced_memory,resctrl,sched,tcp,udp.\n--prometheus_endpoint=\"/metrics\": Endpoint to expose Prometheus metrics on (default \"/metrics\")\n--disable_root_cgroup_stats=false: Disable collecting root Cgroup stats\n```\n\n## Storage Drivers\n\n```\n--storage_driver=\"\": Storage driver to use. Data is always cached shortly in memory, this controls where data is pushed besides the local cache. Empty means none. Options are: <empty>, bigquery, elasticsearch, influxdb, kafka, redis, statsd, stdout\n--storage_driver_buffer_duration=\"1m0s\": Writes in the storage driver will be buffered for this duration, and committed to the non memory backends as a single transaction (default 1m0s)\n--storage_driver_db=\"cadvisor\": database name (default \"cadvisor\")\n--storage_driver_host=\"localhost:8086\": database host:port (default \"localhost:8086\")\n--storage_driver_password=\"root\": database password (default \"root\")\n--storage_driver_secure=false: use secure connection with database\n--storage_driver_table=\"stats\": table name (default \"stats\")\n--storage_driver_user=\"root\": database username (default \"root\")\n```\n\n## Perf Events\n\n```\n--perf_events_config=\"\" Path to a JSON file containing configuration of perf events to measure. Empty value disables perf events measuring.\n```\n\nCore perf events can be exposed on Prometheus endpoint per CPU or aggregated by event. It is controlled through `--disable_metrics` and `--enable_metrics` parameters with option `percpu`, e.g.:\n- `--disable_metrics=\"percpu\"` - core perf events are aggregated\n- `--disable_metrics=\"\"` - core perf events are exposed per CPU.\n\nIt's possible to get \"too many opened files\" error when a lot of perf events are exposed per CPU. This happens because of passing system limits.\nTry to increase max number of file desctriptors with `ulimit -n <value>`.\n\nAggregated form of core perf events significantly decrease volume of data. For aggregated form of core perf events scaling ratio (`container_perf_metric_scaling ratio`) indicates the lowest value of scaling ratio for specific event to show the worst precision.\n\n### Perf subsystem introduction\n\nOne of the goals of kernel perf subsystem is to instrument CPU performance counters that allow to profile applications.\nProfiling is performed by setting up performance counters that count hardware events (e.g. number of retired\ninstructions, number of cache misses). The counters are CPU hardware registers and amount of them is limited.\n\nOther goals of perf subsystem (such as tracing) are beyond the scope of this documentation and you can follow Further\nReading section below to learn more about them.\n\nFamiliarize yourself with following perf-event-related terms:\n* `multiplexing` - 2nd Generation Intel® Xeon® Scalable Processors provides 4 counters per each hyper thread. If number\nof configured events is greater than number of available counters then Linux will multiplex counting and some (or even\nall) of the events will not be accounted for all the time. In such situation information about amount of time that event\nwas accounted for and amount of time when event was enabled is provided. Counter value that cAdvisor exposes is scaled\nautomatically.\n* `grouping` - in scenario when accounted for events are used to calculate derivative metrics, it is reasonable to\nmeasure them in transactional manner: all the events in a group must be accounted for in the same period of time. Keep\nin mind that it is impossible to group more events that there are counters available.\n* `uncore events` - events which can be counted by PMUs outside core.\n* `PMU` - Performance Monitoring Unit\n\n#### Getting config values\nUsing perf tools:\n* Identify the event in `perf list` output.\n* Execute command: `perf stat -I 5000 -vvv -e EVENT_NAME`\n* Find `perf_event_attr` section on `perf stat` output, copy config and type field to configuration file.\n\n```\n------------------------------------------------------------\nperf_event_attr:\n  type                             18\n  size                             112\n  config                           0x304\n  sample_type                      IDENTIFIER\n  read_format                      TOTAL_TIME_ENABLED|TOTAL_TIME_RUNNING\n  disabled                         1\n  inherit                          1\n  exclude_guest                    1\n------------------------------------------------------------\n```\n* Configuration file should look like:\n```json\n{\n  \"core\": {\n    \"events\": [\n      \"event_name\"\n    ],\n    \"custom_events\": [\n      {\n        \"type\": 18,\n        \"config\": [\n          \"0x304\"\n        ],\n        \"name\": \"event_name\"\n      }\n    ]\n  },\n  \"uncore\": {\n    \"events\": [\n      \"event_name\"\n    ],\n    \"custom_events\": [\n      {\n        \"type\": 18,\n        \"config\": [\n          \"0x304\"\n        ],\n        \"name\": \"event_name\"\n      }\n    ]\n  }\n}\n```\n\nConfig values can be also obtain from:\n* [Intel® 64 and IA32 Architectures Performance Monitoring Events](https://software.intel.com/content/www/us/en/develop/download/intel-64-and-ia32-architectures-performance-monitoring-events.html)\n\n\n##### Uncore Events configuration\nUncore Event name should be in form `PMU_PREFIX/event_name` where **PMU_PREFIX** mean\nthat statistics would be counted on all PMUs with that prefix in name.\n\nLet's explain this by example:\n\n```json\n{\n  \"uncore\": {\n    \"events\": [\n      \"uncore_imc/cas_count_read\",\n      \"uncore_imc_0/cas_count_write\",\n      \"cas_count_all\"\n    ],\n    \"custom_events\": [\n      {\n        \"config\": [\n          \"0x304\"\n        ],\n        \"name\": \"uncore_imc_0/cas_count_write\"\n      },\n      {\n        \"type\": 19,\n        \"config\": [\n          \"0x304\"\n        ],\n        \"name\": \"cas_count_all\"\n      }\n    ]\n  }\n}\n```\n\n- `uncore_imc/cas_count_read` - because of `uncore_imc` type and no entry in custom events,\n    it would be counted by **all** Integrated Memory Controller PMUs with config provided from libpfm package.\n    (using this function: https://man7.org/linux/man-pages/man3/pfm_get_os_event_encoding.3.html)\n\n- `uncore_imc_0/cas_count_write` - because of `uncore_imc_0` type and entry in custom events it would be counted by `uncore_imc_0` PMU with provided config.\n\n- `uncore_imc_1/cas_count_all` - because of entry in custom events with type field, event would be counted by PMU with **19** type and provided config.\n\n#### Configuring perf events by name\n\nIt is possible to configure perf events by names using events supported in [libpfm4](http://perfmon2.sourceforge.net/), for detailed information please see [libpfm4 documentation](http://perfmon2.sourceforge.net/docs_v4.html).\n\nDiscovery of perf events supported on platform can be made using python script - [pmu.py](https://sourceforge.net/p/perfmon2/libpfm4/ci/master/tree/python/src/pmu.py) provided with libpfm4, please see [script reqirements](https://sourceforge.net/p/perfmon2/libpfm4/ci/master/tree/python/README).\n\n##### Example configuration of perf events using event names supported in libpfm4\n\nExample output of `pmu.py`:\n```\n$ python pmu.py\nINSTRUCTIONS 1\n\t\t u 0\n\t\t k 1\n\t\t period 3\n\t\t freq 4\n\t\t precise 5\n\t\t excl 6\n\t\t mg 7\n\t\t mh 8\n\t\t cpu 9\n\t\t pinned 10\nINSTRUCTION_RETIRED 192\n\t\t e 2\n\t\t i 3\n\t\t c 4\n\t\t t 5\n\t\t intx 7\n\t\t intxcp 8\n\t\t u 0\n\t\t k 1\n\t\t period 3\n\t\t freq 4\n\t\t excl 6\n\t\t mg 7\n\t\t mh 8\n\t\t cpu 9\n\t\t pinned 10\nUNC_M_CAS_COUNT 4\n\t\t RD 3\n\t\t WR 12\n\t\t e 0\n\t\t i 1\n\t\t t 2\n\t\t period 3\n\t\t freq 4\n\t\t excl 6\n\t\t cpu 9\n\t\t pinned 10\n```\nand perf events configuration for listed events:\n```json\n{\n  \"core\": {\n    \"events\": [\n      \"instructions\",\n      \"instruction_retired\"\n    ]\n  },\n  \"uncore\": {\n    \"events\": [\n      \"uncore_imc/unc_m_cas_count:rd\",\n      \"uncore_imc/unc_m_cas_count:wr\"\n    ]\n  }\n}\n```\n\nNotice: PMU_PREFIX is provided in the same way as for configuration with config values.\n\n#### Grouping\n\n```json\n{\n  \"core\": {\n    \"events\": [\n      [\"instructions\", \"instruction_retired\"]\n    ]\n  },\n  \"uncore\": {\n    \"events\": [\n      [\"uncore_imc_0/unc_m_cas_count:rd\", \"uncore_imc_0/unc_m_cas_count:wr\"],\n      [\"uncore_imc_1/unc_m_cas_count:rd\", \"uncore_imc_1/unc_m_cas_count:wr\"]\n    ]\n  }\n}\n```\n\n\n### Further reading\n\n* [perf Examples](http://www.brendangregg.com/perf.html) on Brendan Gregg's blog\n* [Kernel Perf Wiki](https://perf.wiki.kernel.org/index.php/Main_Page)\n* `man perf_event_open`\n* [perf subsystem](https://github.com/torvalds/linux/tree/v5.6/kernel/events) in Linux kernel\n* [Uncore Performance Monitoring Reference Manuals](https://software.intel.com/content/www/us/en/develop/articles/intel-sdm.html#uncore)\n\nSee example configuration below:\n```json\n{\n  \"core\": {\n    \"events\": [\n      \"instructions\",\n      \"instructions_retired\"\n    ],\n    \"custom_events\": [\n      {\n        \"type\": 4,\n        \"config\": [\n          \"0x5300c0\"\n        ],\n        \"name\": \"instructions_retired\"\n      }\n    ]\n  },\n  \"uncore\": {\n    \"events\": [\n      \"uncore_imc/cas_count_read\"\n    ],\n    \"custom_events\": [\n      {\n        \"config\": [\n          \"0xc04\"\n        ],\n        \"name\": \"uncore_imc/cas_count_read\"\n      }\n    ]\n  }\n}\n```\n\nIn the example above:\n* `instructions` will be measured as a non-grouped event and is specified using human friendly interface that can be\nobtained by calling `perf list`. You can use any name that appears in the output of `perf list` command. This is\ninterface that majority of users will rely on.\n* `instructions_retired` will be measured as non-grouped event and is specified using an advanced API that allows\nto specify any perf event available (some of them are not named and can't be specified with plain string). Event name\nshould be a human readable string that will become a metric name.\n* `cas_count_read` will be measured as uncore non-grouped event on all Integrated Memory Controllers Performance Monitoring Units because of unset `type` field and\n`uncore_imc` prefix.\n\n## Resctrl\nTo gain metrics, cAdvisor creates own monitoring groups with `cadvisor` prefix.\n\nResctrl file system is not hierarchical like cgroups, so users should set `--docker_only` flag to avoid race conditions and unexpected behaviours.\n\n```\n--resctrl_interval=0: Resctrl mon groups updating interval. Zero value disables updating mon groups.\n```\n\n## Storage driver specific instructions:\n\n* [InfluxDB instructions](storage/influxdb.md).\n* [ElasticSearch instructions](storage/elasticsearch.md).\n* [Kafka instructions](storage/kafka.md).\n* [Prometheus instructions](storage/prometheus.md).\n"
  },
  {
    "path": "docs/storage/README.md",
    "content": "# cAdvisor Storage Plugins\n\ncAdvisor supports exporting stats to various storage driver plugins. To enable a storage driver, set the `-storage_driver` flag.\n\n## Storage drivers\n\n- [BigQuery](https://cloud.google.com/bigquery/). See the [documentation](../../storage/bigquery/README.md) for usage.\n- [ElasticSearch](https://www.elastic.co/). See the [documentation](elasticsearch.md) for usage and examples.\n- [InfluxDB](https://influxdb.com/). See the [documentation](influxdb.md) for usage and examples.\n- [Kafka](http://kafka.apache.org/). See the [documentation](kafka.md) for usage.\n- [Prometheus](https://prometheus.io). See the [documentation](prometheus.md) for usage and examples.\n- [Redis](http://redis.io/)\n- [StatsD](https://github.com/etsy/statsd). See the [documentation](statsd.md) for usage and examples.\n- `stdout` - write stats to standard output.\n"
  },
  {
    "path": "docs/storage/elasticsearch.md",
    "content": "# Exporting cAdvisor Stats to ElasticSearch\n\ncAdvisor supports exporting stats to [ElasticSearch](https://www.elastic.co/). To use ES, you need to provide the additional flags to cAdvisor:\n\nSet the storage driver as ES:\n\n```\n -storage_driver=elasticsearch\n```\n\nSpecify ES host address:\n\n```\n -storage_driver_es_host=\"http://elasticsearch:9200\"\n```\n\nThere are also optional flags:\n\n```\n # ElasticSearch type name. By default it's \"stats\".\n -storage_driver_es_type=\"stats\"\n # ElasticSearch can use a sniffing process to find all nodes of your cluster automatically. False by default.\n -storage_driver_es_enable_sniffer=false\n```\n\n# Examples\n\nFor a detailed tutorial, see [docker-elk-cadvisor-dashboards](https://github.com/gregbkr/docker-elk-cadvisor-dashboards)\n"
  },
  {
    "path": "docs/storage/influxdb.md",
    "content": "# Exporting cAdvisor Stats to InfluxDB\n\ncAdvisor supports exporting stats to [InfluxDB](http://influxdb.com). To use InfluxDB, you need to pass some additional flags to cAdvisor telling it where the InfluxDB instance is located:\n\nSet the storage driver as InfluxDB.\n\n```\n -storage_driver=influxdb\n```\n\nSpecify what InfluxDB instance to push data to:\n\n```\n # The *ip:port* of the database. Default is 'localhost:8086'\n -storage_driver_host=ip:port\n # database name. Uses db 'cadvisor' by default\n -storage_driver_db\n # database username. Default is 'root'\n -storage_driver_user\n # database password. Default is 'root'\n -storage_driver_password\n # Use secure connection with database. False by default\n -storage_driver_secure\n # Writes will be buffered for this duration, and committed to the non memory backends as a single transaction. Default is '60s'\n -storage_driver_buffer_duration\n # retention policy. Default is '' which corresponds to the default retention policy of the influxdb database\n-storage_driver_influxdb_retention_policy\n```\n\n# Examples\n\n[Brian Christner](https://www.brianchristner.io) wrote a detailed post on [setting up Docker monitoring](https://www.brianchristner.io/how-to-setup-docker-monitoring) with cAdvisor and Influxdb.  A docker compose configuration for setting up cadvisor-influxdb-grafana can be found [here](https://github.com/dalekurt/docker-monitoring/blob/master/docker-compose.yml).\n"
  },
  {
    "path": "docs/storage/kafka.md",
    "content": "# Exporting cAdvisor Stats to Kafka\n\ncAdvisor supports exporting stats to [Kafka](http://kafka.apache.org/). To use Kafka, you need to provide the additional flags to cAdvisor:\n\nSet the storage driver as Kafka:\n\n```\n -storage_driver=kafka\n```\n\nIf no broker are provided it will default to a broker listening at localhost:9092, with 'stats' as the default topic.\n\n\nSpecify a Kafka broker address:\n\n```\n-storage_driver_kafka_broker_list=localhost:9092\n\n```\n\nSpecify a Kafka topic:\n\n```\n-storage_driver_kafka_topic=myTopic\n```\n\nAs of version 9.0. Kafka supports TLS client auth:\n\n```\n # To enable TLS client auth support you need to provide the following:\n\n # Location to Certificate Authority certificate\n  -storage_driver_kafka_ssl_ca=/path/to/ca.pem\n\n # Location to client certificate certificate\n  -storage_driver_kafka_ssl_cert=/path/to/client_cert.pem\n\n # Location to client certificate key\n  -storage_driver_kafka_ssl_key=/path/to/client_key.pem\n\n # Verify SSL certificate chain (default: true)\n  -storage_driver_kafka_ssl_verify=false\n```\n"
  },
  {
    "path": "docs/storage/prometheus.md",
    "content": "# Monitoring cAdvisor with Prometheus\n\ncAdvisor exposes container and hardware statistics as [Prometheus](https://prometheus.io) metrics out of the box. By default, these metrics are served under the `/metrics` HTTP endpoint. This endpoint may be customized by setting the `-prometheus_endpoint` and `-disable_metrics` or `-enable_metrics` command-line flags.\n\nTo collect some of metrics it is required to build cAdvisor with additional flags, for details see [build instructions](../development/build.md), additional flags are indicated in \"additional build flag\" column in table below.\n\nTo monitor cAdvisor with Prometheus, simply configure one or more jobs in Prometheus which scrape the relevant cAdvisor processes at that metrics endpoint. For details, see Prometheus's [Configuration](https://prometheus.io/docs/operating/configuration/) documentation, as well as the [Getting started](https://prometheus.io/docs/introduction/getting_started/) guide.\n\n# Examples\n\n* [CenturyLink Labs](https://labs.ctl.io/) did an excellent write up on [Monitoring Docker services with Prometheus +cAdvisor](https://www.ctl.io/developers/blog/post/monitoring-docker-services-with-prometheus/), while it is great to get a better overview of cAdvisor integration with Prometheus, the PromDash GUI part is outdated as it has been deprecated for Grafana.\n\n* [vegasbrianc](https://github.com/vegasbrianc) provides a [starter project](https://github.com/vegasbrianc/prometheus) for cAdvisor and Prometheus monitoring, alongide a ready-to-use [Grafana dashboard](https://github.com/vegasbrianc/grafana_dashboard).\n\n## Prometheus container metrics\n\nThe table below lists the Prometheus container metrics exposed by cAdvisor (in alphabetical order by metric name) and corresponding `-disable_metrics` / `-enable_metrics` option parameter:\n\nMetric name | Type | Description | Unit (where applicable) | option parameter | additional build flag |\n:-----------|:-----|:------------|:------------------------|:---------------------------|:----------------------\n`container_blkio_device_usage_total` | Counter | Blkio device bytes usage | bytes | diskIO | \n`container_cpu_cfs_periods_total` | Counter | Number of elapsed enforcement period intervals | | cpu |\n`container_cpu_cfs_throttled_periods_total` | Counter | Number of throttled period intervals | | cpu |\n`container_cpu_cfs_throttled_seconds_total` | Counter | Total time duration the container has been throttled | seconds | cpu |\n`container_cpu_load_average_10s` | Gauge | Value of container cpu load average over the last 10 seconds | | cpuLoad |\n`container_cpu_schedstat_run_periods_total` | Counter | Number of times processes of the cgroup have run on the cpu | | sched |\n`container_cpu_schedstat_runqueue_seconds_total` | Counter | Time duration processes of the container have been waiting on a runqueue | seconds | sched |\n`container_cpu_schedstat_run_seconds_total` | Counter | Time duration the processes of the container have run on the CPU | seconds | sched |\n`container_cpu_system_seconds_total` | Counter | Cumulative system cpu time consumed | seconds | cpu |\n`container_cpu_usage_seconds_total` | Counter | Cumulative cpu time consumed | seconds | cpu |\n`container_cpu_user_seconds_total` | Counter | Cumulative user cpu time consumed | seconds | cpu |\n`container_file_descriptors` | Gauge | Number of open file descriptors for the container | | process |\n`container_fs_inodes_free` | Gauge | Number of available Inodes | | disk |\n`container_fs_inodes_total` | Gauge | Total number of Inodes | | disk |\n`container_fs_io_current` | Gauge | Number of I/Os currently in progress | | diskIO |\n`container_fs_io_time_seconds_total` | Counter | Cumulative count of seconds spent doing I/Os | seconds | diskIO |\n`container_fs_io_time_weighted_seconds_total` | Counter | Cumulative weighted I/O time | seconds | diskIO |\n`container_fs_limit_bytes` | Gauge | Number of bytes that can be consumed by the container on this filesystem | bytes | disk |\n`container_fs_reads_bytes_total` | Counter | Cumulative count of bytes read | bytes | diskIO |\n`container_fs_read_seconds_total` | Counter | Cumulative count of seconds spent reading | | diskIO |\n`container_fs_reads_merged_total` | Counter | Cumulative count of reads merged | | diskIO |\n`container_fs_reads_total` | Counter | Cumulative count of reads completed | | diskIO |\n`container_fs_sector_reads_total` | Counter | Cumulative count of sector reads completed | | diskIO |\n`container_fs_sector_writes_total` | Counter | Cumulative count of sector writes completed | | diskIO |\n`container_fs_usage_bytes` | Gauge | Number of bytes that are consumed by the container on this filesystem | bytes | disk |\n`container_fs_writes_bytes_total` | Counter | Cumulative count of bytes written | bytes | diskIO |\n`container_fs_write_seconds_total` | Counter | Cumulative count of seconds spent writing | seconds | diskIO |\n`container_fs_writes_merged_total` | Counter | Cumulative count of writes merged | | diskIO |\n`container_fs_writes_total` | Counter | Cumulative count of writes completed | | diskIO |\n`container_health_state` | Gauge | State of the health check probe | | - |\n`container_hugetlb_failcnt` | Counter | Number of hugepage usage hits limits | | hugetlb |\n`container_hugetlb_max_usage_bytes` | Gauge | Maximum hugepage usages recorded | bytes | hugetlb |\n`container_hugetlb_usage_bytes` | Gauge | Current hugepage usage | bytes | hugetlb |\n`container_last_seen` | Gauge | Last time a container was seen by the exporter | timestamp | - |\n`container_llc_occupancy_bytes` | Gauge | Last level cache usage statistics for container counted with RDT Memory Bandwidth Monitoring (MBM). | bytes | resctrl |\n`container_memory_bandwidth_bytes` | Gauge | Total memory bandwidth usage statistics for container counted with RDT Memory Bandwidth Monitoring (MBM). | bytes | resctrl |\n`container_memory_bandwidth_local_bytes` | Gauge | Local memory bandwidth usage statistics for container counted with RDT Memory Bandwidth Monitoring (MBM). | bytes | resctrl |\n`container_memory_cache` | Gauge | Total page cache memory | bytes | memory |\n`container_memory_failcnt` | Counter | Number of memory usage hits limits | | memory |\n`container_memory_failures_total` | Counter | Cumulative count of memory allocation failures | | memory |\n`container_memory_mapped_file` | Gauge | Size of memory mapped files | bytes | memory |\n`container_memory_max_usage_bytes` | Gauge | Maximum memory usage recorded | bytes | memory |\n`container_memory_migrate` | Gauge | Memory migrate status | | cpuset |\n`container_memory_numa_pages` | Gauge | Number of used pages per NUMA node | | memory_numa |\n`container_memory_rss` | Gauge | Size of RSS | bytes | memory |\n`container_memory_swap` | Gauge | Container swap usage | bytes | memory |\n`container_memory_usage_bytes` | Gauge | Current memory usage, including all memory regardless of when it was accessed | bytes | memory |\n`container_memory_working_set_bytes` | Gauge | Current working set | bytes | memory |\n`container_network_advance_tcp_stats_total` | Gauge | advanced tcp connections statistic for container | | advtcp |\n`container_network_receive_bytes_total` | Counter | Cumulative count of bytes received | bytes | network |\n`container_network_receive_errors_total` | Counter | Cumulative count of errors encountered while receiving | | network |\n`container_network_receive_packets_dropped_total` | Counter | Cumulative count of packets dropped while receiving | | network |\n`container_network_receive_packets_total` | Counter | Cumulative count of packets received | | network |\n`container_network_tcp6_usage_total` | Gauge | tcp6 connection usage statistic for container | | tcp |\n`container_network_tcp_usage_total` | Gauge | tcp connection usage statistic for container | | tcp |\n`container_network_transmit_bytes_total` | Counter | Cumulative count of bytes transmitted | bytes | network |\n`container_network_transmit_errors_total` | Counter | Cumulative count of errors encountered while transmitting | | network |\n`container_network_transmit_packets_dropped_total` | Counter | Cumulative count of packets dropped while transmitting | | network |\n`container_network_transmit_packets_total` | Counter | Cumulative count of packets transmitted | | network |\n`container_network_udp6_usage_total` | Gauge | udp6 connection usage statistic for container | | udp |\n`container_network_udp_usage_total` | Gauge | udp connection usage statistic for container | | udp |\n`container_oom_events_total` | Counter | Count of out of memory events observed for the container | | oom_event |\n`container_perf_events_scaling_ratio` | Gauge | Scaling ratio for perf event counter (event can be identified by `event` label and `cpu` indicates the core for which event was measured). See [perf event configuration](../runtime_options.md#perf-events). | | perf_event | libpfm\n`container_perf_events_total` | Counter | Scaled counter of perf core event (event can be identified by `event` label and `cpu` indicates the core for which event was measured). See [perf event configuration](../runtime_options.md#perf-events). | | perf_event | libpfm\n`container_perf_uncore_events_scaling_ratio` | Gauge | Scaling ratio for perf uncore event counter (event can be identified by `event` label, `pmu` and `socket` lables indicate the PMU and the CPU socket for which event was measured). See [perf event configuration](../runtime_options.md#perf-events). Metric exists only for main cgroup (id=\"/\"). | | perf_event | libpfm\n`container_perf_uncore_events_total` | Counter | Scaled counter of perf uncore event (event can be identified by `event` label, `pmu` and `socket` lables indicate the PMU and the CPU socket for which event was measured). See [perf event configuration](../runtime_options.md#perf-events)). Metric exists only for main cgroup (id=\"/\").| | perf_event | libpfm\n`container_processes` | Gauge | Number of processes running inside the container | | process |\n`container_referenced_bytes` | Gauge |  Container referenced bytes during last measurements cycle based on Referenced field in /proc/smaps file, with /proc/PIDs/clear_refs set to 1 after defined number of cycles configured through `referenced_reset_interval` cAdvisor parameter.</br>Warning: this is intrusive collection because can influence kernel page reclaim policy and add latency. Refer to https://github.com/brendangregg/wss#wsspl-referenced-page-flag for more details. | bytes | referenced_memory |\n`container_sockets` | Gauge | Number of open sockets for the container | | process |\n`container_spec_cpu_period` | Gauge | CPU period of the container | | - |\n`container_spec_cpu_quota` | Gauge | CPU quota of the container | | - |\n`container_spec_cpu_shares` | Gauge | CPU share of the container | | - |\n`container_spec_memory_limit_bytes` | Gauge | Memory limit for the container | bytes | - |\n`container_spec_memory_reservation_limit_bytes` | Gauge | Memory reservation limit for the container | bytes | |\n`container_spec_memory_swap_limit_bytes` | Gauge | Memory swap limit for the container | bytes | |\n`container_start_time_seconds` | Gauge | Start time of the container since unix epoch | seconds | |\n`container_tasks_state` | Gauge | Number of tasks in given state (`sleeping`, `running`, `stopped`, `uninterruptible`, or `ioawaiting`) | | cpuLoad |\n`container_threads` | Gauge | Number of threads running inside the container | | process |\n`container_threads_max` | Gauge | Maximum number of threads allowed inside the container | | process |\n`container_ulimits_soft` | Gauge | Soft ulimit values for the container root process. Unlimited if -1, except priority and nice | | process |\n\n## Prometheus hardware metrics\n\nThe table below lists the Prometheus hardware metrics exposed by cAdvisor (in alphabetical order by metric name) and corresponding `-disable_metrics` / `-enable_metrics` option parameter:\n\nMetric name | Type | Description | Unit (where applicable) | option parameter | additional build flag |\n:-----------|:-----|:------------|:------------------------|:---------------------------|:--------------------\n`machine_cpu_cache_capacity_bytes` | Gauge |  Cache size in bytes assigned to NUMA node and CPU core | bytes | cpu_topology |\n`machine_cpu_cores` | Gauge | Number of logical CPU cores | | |\n`machine_cpu_physical_cores` | Gauge | Number of physical CPU cores | | |\n`machine_cpu_sockets` | Gauge | Number of CPU sockets | | |\n`machine_dimm_capacity_bytes` | Gauge | Total RAM DIMM capacity (all types memory modules) value labeled by dimm type,<br>information is retrieved from sysfs edac per-DIMM API (/sys/devices/system/edac/mc/) introduced in kernel 3.6 | bytes | | |\n`machine_dimm_count` | Gauge | Number of RAM DIMM (all types memory modules) value labeled by dimm type,<br>information is retrieved from sysfs edac per-DIMM API (/sys/devices/system/edac/mc/) introduced in kernel 3.6 | | |\n`machine_memory_bytes` | Gauge | Amount of memory installed on the machine | bytes | |\n`machine_swap_bytes` | Gauge | Amount of swap memory available on the machine | bytes | |\n`machine_node_distance` | Gauge | Distance between NUMA node and target NUMA node | | cpu_topology |\n`machine_node_hugepages_count` | Gauge |  Numer of hugepages assigned to NUMA node | | cpu_topology |\n`machine_node_memory_capacity_bytes` | Gauge |  Amount of memory assigned to NUMA node | bytes | cpu_topology |\n`machine_nvm_avg_power_budget_watts` | Gauge |  NVM power budget | watts | | libipmctl\n`machine_nvm_capacity` | Gauge | NVM capacity value labeled by NVM mode (memory mode or app direct mode) | bytes | | libipmctl\n`machine_thread_siblings_count` | Gauge | Number of CPU thread siblings | | cpu_topology |\n"
  },
  {
    "path": "docs/storage/statsd.md",
    "content": "# Exporting cAdvisor Stats to statsd\n\ncAdvisor supports exporting stats to [statsd](https://github.com/etsy/statsd). To use statsd, you need to pass some additional flags to cAdvisor telling it where to find statsd:\n\nSet the storage driver as statsd.\n\n```\n -storage_driver=statsd\n```\n\nSpecify what statsd instance to push data to:\n\n```\n # The *ip:port* of the instance. Default is 'localhost:8086'\n -storage_driver_host=ip:port\n```\n\n# Examples\n\nThe easiest way to get up an running is to start the cadvisor binary with the `--storage_driver` and `--storage_driver_host` flags.\n\n```\ncadvisor --storage_driver=\"statsd\" --storage_driver_host=\"localhost:8125\"\n```\n\nThe default port for statsd is 8125, so this wil start pumping metrics directly to it."
  },
  {
    "path": "docs/web.md",
    "content": "# cAdvisor Web UI\n\ncAdvisor exposes a web UI at its port:\n\n`http://<hostname>:<port>/`\n\nThis UI has one primary resource at `/containers` which exports live information about all containers on the machine.\n\n## Web UI authentication\n\nYou can add authentication to the web UI by either HTTP basic or HTTP digest authentication. \n\nNOTE: The Web UI authentication only protects the `/containers` endpoint, and not the other cAdvisor HTTP endpoints such as `/api/...` and `/metrics`. Some of these endpoints can expose sensitive information, so it is not advised to expose these endpoints publicly.\n\n### HTTP basic authentication\n\nYou will need to add a *http_auth_file* parameter with a HTTP basic auth file generated using htpasswd to enable HTTP basic auth. By default the auth realm is set as localhost.\n\n`./cadvisor --http_auth_file test.htpasswd --http_auth_realm localhost`\n\nThe [test.htpasswd](../test.htpasswd) file provided has a username and password already added (`admin:password1`) for testing purposes.\n\n### HTTP Digest authentication\n\nYou will need to add a *http_digest_file* parameter with a HTTP digest auth file generated using htdigest to enable HTTP Digest auth. By default the auth realm is set as localhost.\n\n`./cadvisor --http_digest_file test.htdigest --http_digest_realm localhost`\n\nThe [test.htdigest](../test.htdigest) file provided has a username and password already added (`admin:password1`) for testing purposes.\n\n**Note** : You can use either type of authentication, in case you decide to use both files in the arguments only HTTP basic auth will be enabled. \n"
  },
  {
    "path": "events/handler.go",
    "content": "// Copyright 2015 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage events\n\nimport (\n\t\"errors\"\n\t\"sort\"\n\t\"strings\"\n\t\"sync\"\n\t\"time\"\n\n\tinfo \"github.com/google/cadvisor/info/v1\"\n\t\"github.com/google/cadvisor/utils\"\n\n\t\"k8s.io/klog/v2\"\n)\n\ntype byTimestamp []*info.Event\n\n// functions necessary to implement the sort interface on the Events struct\nfunc (e byTimestamp) Len() int {\n\treturn len(e)\n}\n\nfunc (e byTimestamp) Swap(i, j int) {\n\te[i], e[j] = e[j], e[i]\n}\n\nfunc (e byTimestamp) Less(i, j int) bool {\n\treturn e[i].Timestamp.Before(e[j].Timestamp)\n}\n\ntype EventChannel struct {\n\t// Watch ID. Can be used by the caller to request cancellation of watch events.\n\twatchID int\n\t// Channel on which the caller can receive watch events.\n\tchannel chan *info.Event\n}\n\n// Request holds a set of parameters by which Event objects may be screened.\n// The caller may want events that occurred within a specific timeframe\n// or of a certain type, which may be specified in the *Request object\n// they pass to an EventManager function\ntype Request struct {\n\t// events falling before StartTime do not satisfy the request. StartTime\n\t// must be left blank in calls to WatchEvents\n\tStartTime time.Time\n\t// events falling after EndTime do not satisfy the request. EndTime\n\t// must be left blank in calls to WatchEvents\n\tEndTime time.Time\n\t// EventType is a map that specifies the type(s) of events wanted\n\tEventType map[info.EventType]bool\n\t// allows the caller to put a limit on how many\n\t// events to receive. If there are more events than MaxEventsReturned\n\t// then the most chronologically recent events in the time period\n\t// specified are returned. Must be >= 1\n\tMaxEventsReturned int\n\t// the absolute container name for which the event occurred\n\tContainerName string\n\t// if IncludeSubcontainers is false, only events occurring in the specific\n\t// container, and not the subcontainers, will be returned\n\tIncludeSubcontainers bool\n}\n\n// EventManager is implemented by Events. It provides two ways to monitor\n// events and one way to add events\ntype EventManager interface {\n\t// WatchEvents() allows a caller to register for receiving events based on the specified request.\n\t// On successful registration, an EventChannel object is returned.\n\tWatchEvents(request *Request) (*EventChannel, error)\n\t// GetEvents() returns all detected events based on the filters specified in request.\n\tGetEvents(request *Request) ([]*info.Event, error)\n\t// AddEvent allows the caller to add an event to an EventManager\n\t// object\n\tAddEvent(event *info.Event) error\n\t// Cancels a previously requested watch event.\n\tStopWatch(watchID int)\n}\n\n// events provides an implementation for the EventManager interface.\ntype events struct {\n\t// eventStore holds the events by event type.\n\teventStore map[info.EventType]*utils.TimedStore\n\t// map of registered watchers keyed by watch id.\n\twatchers map[int]*watch\n\t// lock guarding the eventStore.\n\teventsLock sync.RWMutex\n\t// lock guarding watchers.\n\twatcherLock sync.RWMutex\n\t// last allocated watch id.\n\tlastID int\n\t// Event storage policy.\n\tstoragePolicy StoragePolicy\n}\n\n// initialized by a call to WatchEvents(), a watch struct will then be added\n// to the events slice of *watch objects. When AddEvent() finds an event that\n// satisfies the request parameter of a watch object in events.watchers,\n// it will send that event out over the watch object's channel. The caller that\n// called WatchEvents will receive the event over the channel provided to\n// WatchEvents\ntype watch struct {\n\t// request parameters passed in by the caller of WatchEvents()\n\trequest *Request\n\t// a channel used to send event back to the caller.\n\teventChannel *EventChannel\n}\n\nfunc NewEventChannel(watchID int) *EventChannel {\n\treturn &EventChannel{\n\t\twatchID: watchID,\n\t\tchannel: make(chan *info.Event, 10),\n\t}\n}\n\n// Policy specifying how many events to store.\n// MaxAge is the max duration for which to keep events.\n// MaxNumEvents is the max number of events to keep (-1 for no limit).\ntype StoragePolicy struct {\n\t// Defaults limites, used if a per-event limit is not set.\n\tDefaultMaxAge       time.Duration\n\tDefaultMaxNumEvents int\n\n\t// Per-event type limits.\n\tPerTypeMaxAge       map[info.EventType]time.Duration\n\tPerTypeMaxNumEvents map[info.EventType]int\n}\n\nfunc DefaultStoragePolicy() StoragePolicy {\n\treturn StoragePolicy{\n\t\tDefaultMaxAge:       24 * time.Hour,\n\t\tDefaultMaxNumEvents: 100000,\n\t\tPerTypeMaxAge:       make(map[info.EventType]time.Duration),\n\t\tPerTypeMaxNumEvents: make(map[info.EventType]int),\n\t}\n}\n\n// returns a pointer to an initialized Events object.\nfunc NewEventManager(storagePolicy StoragePolicy) EventManager {\n\treturn &events{\n\t\teventStore:    make(map[info.EventType]*utils.TimedStore),\n\t\twatchers:      make(map[int]*watch),\n\t\tstoragePolicy: storagePolicy,\n\t}\n}\n\n// returns a pointer to an initialized Request object\nfunc NewRequest() *Request {\n\treturn &Request{\n\t\tEventType:            map[info.EventType]bool{},\n\t\tIncludeSubcontainers: false,\n\t\tMaxEventsReturned:    10,\n\t}\n}\n\n// returns a pointer to an initialized watch object\nfunc newWatch(request *Request, eventChannel *EventChannel) *watch {\n\treturn &watch{\n\t\trequest:      request,\n\t\teventChannel: eventChannel,\n\t}\n}\n\nfunc (ch *EventChannel) GetChannel() chan *info.Event {\n\treturn ch.channel\n}\n\nfunc (ch *EventChannel) GetWatchId() int {\n\treturn ch.watchID\n}\n\n// sorts and returns up to the last MaxEventsReturned chronological elements\nfunc getMaxEventsReturned(request *Request, eSlice []*info.Event) []*info.Event {\n\tsort.Sort(byTimestamp(eSlice))\n\tn := request.MaxEventsReturned\n\tif n >= len(eSlice) || n <= 0 {\n\t\treturn eSlice\n\t}\n\treturn eSlice[len(eSlice)-n:]\n}\n\n// If the request wants all subcontainers, this returns if the request's\n// container path is a prefix of the event container path.  Otherwise,\n// it checks that the container paths of the event and request are\n// equivalent\nfunc isSubcontainer(request *Request, event *info.Event) bool {\n\tif request.IncludeSubcontainers {\n\t\treturn request.ContainerName == \"/\" || strings.HasPrefix(event.ContainerName+\"/\", request.ContainerName+\"/\")\n\t}\n\treturn event.ContainerName == request.ContainerName\n}\n\n// determines if an event occurs within the time set in the request object and is the right type\nfunc checkIfEventSatisfiesRequest(request *Request, event *info.Event) bool {\n\tstartTime := request.StartTime\n\tendTime := request.EndTime\n\teventTime := event.Timestamp\n\tif !startTime.IsZero() {\n\t\tif startTime.After(eventTime) {\n\t\t\treturn false\n\t\t}\n\t}\n\tif !endTime.IsZero() {\n\t\tif endTime.Before(eventTime) {\n\t\t\treturn false\n\t\t}\n\t}\n\tif !request.EventType[event.EventType] {\n\t\treturn false\n\t}\n\tif request.ContainerName != \"\" {\n\t\treturn isSubcontainer(request, event)\n\t}\n\treturn true\n}\n\n// method of Events object that screens Event objects found in the eventStore\n// attribute and if they fit the parameters passed by the Request object,\n// adds it to a slice of *Event objects that is returned. If both MaxEventsReturned\n// and StartTime/EndTime are specified in the request object, then only\n// up to the most recent MaxEventsReturned events in that time range are returned.\nfunc (e *events) GetEvents(request *Request) ([]*info.Event, error) {\n\treturnEventList := []*info.Event{}\n\te.eventsLock.RLock()\n\tdefer e.eventsLock.RUnlock()\n\tfor eventType, fetch := range request.EventType {\n\t\tif !fetch {\n\t\t\tcontinue\n\t\t}\n\t\tevs, ok := e.eventStore[eventType]\n\t\tif !ok {\n\t\t\tcontinue\n\t\t}\n\n\t\tres := evs.InTimeRange(request.StartTime, request.EndTime, request.MaxEventsReturned)\n\t\tfor _, in := range res {\n\t\t\te := in.(*info.Event)\n\t\t\tif checkIfEventSatisfiesRequest(request, e) {\n\t\t\t\treturnEventList = append(returnEventList, e)\n\t\t\t}\n\t\t}\n\t}\n\treturnEventList = getMaxEventsReturned(request, returnEventList)\n\treturn returnEventList, nil\n}\n\n// method of Events object that maintains an *Event channel passed by the user.\n// When an event is added by AddEvents that satisfies the parameters in the passed\n// Request object it is fed to the channel. The StartTime and EndTime of the watch\n// request should be uninitialized because the purpose is to watch indefinitely\n// for events that will happen in the future\nfunc (e *events) WatchEvents(request *Request) (*EventChannel, error) {\n\tif !request.StartTime.IsZero() || !request.EndTime.IsZero() {\n\t\treturn nil, errors.New(\n\t\t\t\"for a call to watch, request.StartTime and request.EndTime must be uninitialized\")\n\t}\n\te.watcherLock.Lock()\n\tdefer e.watcherLock.Unlock()\n\tnewID := e.lastID + 1\n\treturnEventChannel := NewEventChannel(newID)\n\tnewWatcher := newWatch(request, returnEventChannel)\n\te.watchers[newID] = newWatcher\n\te.lastID = newID\n\treturn returnEventChannel, nil\n}\n\n// helper function to update the event manager's eventStore\nfunc (e *events) updateEventStore(event *info.Event) {\n\te.eventsLock.Lock()\n\tdefer e.eventsLock.Unlock()\n\tif _, ok := e.eventStore[event.EventType]; !ok {\n\t\tmaxNumEvents := e.storagePolicy.DefaultMaxNumEvents\n\t\tif numEvents, ok := e.storagePolicy.PerTypeMaxNumEvents[event.EventType]; ok {\n\t\t\tmaxNumEvents = numEvents\n\t\t}\n\t\tif maxNumEvents == 0 {\n\t\t\t// Event storage is disabled for event.EventType\n\t\t\treturn\n\t\t}\n\n\t\tmaxAge := e.storagePolicy.DefaultMaxAge\n\t\tif age, ok := e.storagePolicy.PerTypeMaxAge[event.EventType]; ok {\n\t\t\tmaxAge = age\n\t\t}\n\n\t\te.eventStore[event.EventType] = utils.NewTimedStore(maxAge, maxNumEvents)\n\t}\n\te.eventStore[event.EventType].Add(event.Timestamp, event)\n}\n\nfunc (e *events) findValidWatchers(event *info.Event) []*watch {\n\twatchesToSend := make([]*watch, 0)\n\tfor _, watcher := range e.watchers {\n\t\twatchRequest := watcher.request\n\t\tif checkIfEventSatisfiesRequest(watchRequest, event) {\n\t\t\twatchesToSend = append(watchesToSend, watcher)\n\t\t}\n\t}\n\treturn watchesToSend\n}\n\n// method of Events object that adds the argument Event object to the\n// eventStore. It also feeds the event to a set of watch channels\n// held by the manager if it satisfies the request keys of the channels\nfunc (e *events) AddEvent(event *info.Event) error {\n\te.updateEventStore(event)\n\te.watcherLock.RLock()\n\tdefer e.watcherLock.RUnlock()\n\twatchesToSend := e.findValidWatchers(event)\n\tfor _, watchObject := range watchesToSend {\n\t\twatchObject.eventChannel.GetChannel() <- event\n\t}\n\tklog.V(4).Infof(\"Added event %v\", event)\n\treturn nil\n}\n\n// Removes a watch instance from the EventManager's watchers map\nfunc (e *events) StopWatch(watchID int) {\n\te.watcherLock.Lock()\n\tdefer e.watcherLock.Unlock()\n\t_, ok := e.watchers[watchID]\n\tif !ok {\n\t\tklog.Errorf(\"Could not find watcher instance %v\", watchID)\n\t}\n\tclose(e.watchers[watchID].eventChannel.GetChannel())\n\tdelete(e.watchers, watchID)\n}\n"
  },
  {
    "path": "events/handler_test.go",
    "content": "// Copyright 2015 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage events\n\nimport (\n\t\"testing\"\n\t\"time\"\n\n\tinfo \"github.com/google/cadvisor/info/v1\"\n\n\t\"github.com/stretchr/testify/assert\"\n)\n\nfunc createOldTime(t *testing.T) time.Time {\n\tconst longForm = \"Jan 2, 2006 at 3:04pm (MST)\"\n\tlinetime, err := time.Parse(longForm, \"Feb 3, 2013 at 7:54pm (PST)\")\n\tif err != nil {\n\t\tt.Fatalf(\"could not format time.Time object\")\n\t} else {\n\t\treturn linetime\n\t}\n\treturn time.Now()\n}\n\n// used to convert an OomInstance to an Event object\nfunc makeEvent(inTime time.Time, containerName string) *info.Event {\n\treturn &info.Event{\n\t\tContainerName: containerName,\n\t\tTimestamp:     inTime,\n\t\tEventType:     info.EventOom,\n\t}\n}\n\n// returns EventManager and Request to use in tests\nfunc initializeScenario(t *testing.T) (EventManager, *Request, *info.Event, *info.Event) {\n\tfakeEvent := makeEvent(createOldTime(t), \"/\")\n\tfakeEvent2 := makeEvent(time.Now(), \"/\")\n\n\tmanager := NewEventManager(DefaultStoragePolicy())\n\treturn manager, NewRequest(), fakeEvent, fakeEvent2\n}\n\nfunc TestIsSubcontainer(t *testing.T) {\n\tmyRequest := NewRequest()\n\tmyRequest.ContainerName = \"/root\"\n\trootRequest := NewRequest()\n\trootRequest.ContainerName = \"/\"\n\n\tsameContainerEvent := &info.Event{\n\t\tContainerName: \"/root\",\n\t}\n\tsubContainerEvent := &info.Event{\n\t\tContainerName: \"/root/subdir\",\n\t}\n\tdifferentContainerEvent := &info.Event{\n\t\tContainerName: \"/root-completely-different-container\",\n\t}\n\n\tif isSubcontainer(rootRequest, sameContainerEvent) {\n\t\tt.Errorf(\"should not have found %v to be a subcontainer of %v\",\n\t\t\tsameContainerEvent, rootRequest)\n\t}\n\tif !isSubcontainer(myRequest, sameContainerEvent) {\n\t\tt.Errorf(\"should have found %v and %v had the same container name\",\n\t\t\tmyRequest, sameContainerEvent)\n\t}\n\tif isSubcontainer(myRequest, subContainerEvent) {\n\t\tt.Errorf(\"should have found %v and %v had different containers\",\n\t\t\tmyRequest, subContainerEvent)\n\t}\n\n\trootRequest.IncludeSubcontainers = true\n\tmyRequest.IncludeSubcontainers = true\n\n\tif !isSubcontainer(rootRequest, sameContainerEvent) {\n\t\tt.Errorf(\"should have found %v to be a subcontainer of %v\",\n\t\t\tsameContainerEvent.ContainerName, rootRequest.ContainerName)\n\t}\n\tif !isSubcontainer(myRequest, sameContainerEvent) {\n\t\tt.Errorf(\"should have found %v and %v had the same container\",\n\t\t\tmyRequest.ContainerName, sameContainerEvent.ContainerName)\n\t}\n\tif !isSubcontainer(myRequest, subContainerEvent) {\n\t\tt.Errorf(\"should have found %v was a subcontainer of %v\",\n\t\t\tsubContainerEvent.ContainerName, myRequest.ContainerName)\n\t}\n\tif isSubcontainer(myRequest, differentContainerEvent) {\n\t\tt.Errorf(\"should have found %v and %v had different containers\",\n\t\t\tmyRequest.ContainerName, differentContainerEvent.ContainerName)\n\t}\n}\n\nfunc TestWatchEventsDetectsNewEvents(t *testing.T) {\n\tmyEventHolder, myRequest, fakeEvent, fakeEvent2 := initializeScenario(t)\n\tmyRequest.EventType[info.EventOom] = true\n\treturnEventChannel, err := myEventHolder.WatchEvents(myRequest)\n\tassert.NoError(t, err)\n\n\terr = myEventHolder.AddEvent(fakeEvent)\n\tassert.NoError(t, err)\n\terr = myEventHolder.AddEvent(fakeEvent2)\n\tassert.NoError(t, err)\n\n\tstartTime := time.Now()\n\tgo func() {\n\t\ttime.Sleep(5 * time.Second)\n\t\tif time.Since(startTime) > (5 * time.Second) {\n\t\t\tt.Errorf(\"Took too long to receive all the events\")\n\t\t}\n\t}()\n\n\teventsFound := 0\n\tgo func() {\n\t\tfor event := range returnEventChannel.GetChannel() {\n\t\t\teventsFound++\n\t\t\tif eventsFound == 1 {\n\t\t\t\tassert.Equal(t, fakeEvent, event)\n\t\t\t} else if eventsFound == 2 {\n\t\t\t\tassert.Equal(t, fakeEvent2, event)\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t}()\n}\n\nfunc TestAddEventAddsEventsToEventManager(t *testing.T) {\n\tmyEventHolder, _, fakeEvent, _ := initializeScenario(t)\n\n\terr := myEventHolder.AddEvent(fakeEvent)\n\tassert.NoError(t, err)\n\n\tevents, err := myEventHolder.GetEvents(&Request{\n\t\tEventType:         map[info.EventType]bool{info.EventOom: true},\n\t\tMaxEventsReturned: -1,\n\t})\n\n\tassert.NoError(t, err)\n\tassert.Len(t, events, 1)\n\tassert.Equal(t, fakeEvent, events[0])\n}\n\nfunc TestGetEventsForOneEvent(t *testing.T) {\n\tmyEventHolder, myRequest, fakeEvent, fakeEvent2 := initializeScenario(t)\n\tmyRequest.MaxEventsReturned = 1\n\tmyRequest.EventType[info.EventOom] = true\n\n\terr := myEventHolder.AddEvent(fakeEvent)\n\tassert.NoError(t, err)\n\terr = myEventHolder.AddEvent(fakeEvent2)\n\tassert.NoError(t, err)\n\n\treceivedEvents, err := myEventHolder.GetEvents(myRequest)\n\tassert.NoError(t, err)\n\tassert.Len(t, receivedEvents, 1)\n\tassert.Equal(t, fakeEvent2, receivedEvents[0])\n}\n\nfunc TestGetEventsForTimePeriod(t *testing.T) {\n\tmyEventHolder, myRequest, fakeEvent, fakeEvent2 := initializeScenario(t)\n\tmyRequest.StartTime = time.Now().Add(-1 * time.Second * 10)\n\tmyRequest.EndTime = time.Now().Add(time.Second * 10)\n\tmyRequest.EventType[info.EventOom] = true\n\n\terr := myEventHolder.AddEvent(fakeEvent)\n\tassert.NoError(t, err)\n\terr = myEventHolder.AddEvent(fakeEvent2)\n\tassert.NoError(t, err)\n\n\treceivedEvents, err := myEventHolder.GetEvents(myRequest)\n\tassert.NoError(t, err)\n\tassert.Len(t, receivedEvents, 1)\n\tassert.Equal(t, fakeEvent2, receivedEvents[0])\n}\n\nfunc TestGetEventsForNoTypeRequested(t *testing.T) {\n\tmyEventHolder, myRequest, fakeEvent, fakeEvent2 := initializeScenario(t)\n\n\terr := myEventHolder.AddEvent(fakeEvent)\n\tassert.NoError(t, err)\n\terr = myEventHolder.AddEvent(fakeEvent2)\n\tassert.NoError(t, err)\n\n\treceivedEvents, err := myEventHolder.GetEvents(myRequest)\n\tassert.NoError(t, err)\n\tassert.Len(t, receivedEvents, 0)\n}\n"
  },
  {
    "path": "fs/btrfs/install/install.go",
    "content": "// Copyright 2014 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n//go:build linux\n\npackage install\n\nimport (\n\t\"github.com/google/cadvisor/fs\"\n\t\"github.com/google/cadvisor/fs/btrfs\"\n\n\t\"k8s.io/klog/v2\"\n)\n\nfunc init() {\n\terr := fs.RegisterPlugin(\"btrfs\", btrfs.NewPlugin())\n\tif err != nil {\n\t\tklog.Fatalf(\"Failed to register btrfs fs plugin: %v\", err)\n\t}\n}\n"
  },
  {
    "path": "fs/btrfs/mount.go",
    "content": "// Copyright 2014 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n//go:build linux\n\npackage btrfs\n\nimport (\n\t\"fmt\"\n\t\"syscall\"\n\n\tmount \"github.com/moby/sys/mountinfo\"\n\t\"k8s.io/klog/v2\"\n)\n\n// major extracts the major device number from a device number.\nfunc major(devNumber uint64) uint {\n\treturn uint((devNumber >> 8) & 0xfff)\n}\n\n// minor extracts the minor device number from a device number.\nfunc minor(devNumber uint64) uint {\n\treturn uint((devNumber & 0xff) | ((devNumber >> 12) & 0xfff00))\n}\n\n// GetBtrfsMajorMinorIds gets the major and minor device IDs for a btrfs mount point.\n// This is a workaround for wrong btrfs Major and Minor Ids reported in /proc/self/mountinfo.\n// Instead of using values from /proc/self/mountinfo we use stat to get Ids from btrfs mount point.\nfunc GetBtrfsMajorMinorIds(mnt *mount.Info) (int, int, error) {\n\tbuf := new(syscall.Stat_t)\n\terr := syscall.Stat(mnt.Source, buf)\n\tif err != nil {\n\t\terr = fmt.Errorf(\"stat failed on %s with error: %s\", mnt.Source, err)\n\t\treturn 0, 0, err\n\t}\n\n\tklog.V(4).Infof(\"btrfs mount %#v\", mnt)\n\tif buf.Mode&syscall.S_IFMT == syscall.S_IFBLK {\n\t\terr := syscall.Stat(mnt.Mountpoint, buf)\n\t\tif err != nil {\n\t\t\terr = fmt.Errorf(\"stat failed on %s with error: %s\", mnt.Mountpoint, err)\n\t\t\treturn 0, 0, err\n\t\t}\n\n\t\t// The type Dev and Rdev in Stat_t are 32bit on mips.\n\t\tklog.V(4).Infof(\"btrfs dev major:minor %d:%d\\n\", int(major(uint64(buf.Dev))), int(minor(uint64(buf.Dev))))    // nolint: unconvert\n\t\tklog.V(4).Infof(\"btrfs rdev major:minor %d:%d\\n\", int(major(uint64(buf.Rdev))), int(minor(uint64(buf.Rdev)))) // nolint: unconvert\n\n\t\treturn int(major(uint64(buf.Dev))), int(minor(uint64(buf.Dev))), nil // nolint: unconvert\n\t}\n\treturn 0, 0, fmt.Errorf(\"%s is not a block device\", mnt.Source)\n}\n"
  },
  {
    "path": "fs/btrfs/plugin.go",
    "content": "// Copyright 2014 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n//go:build linux\n\npackage btrfs\n\nimport (\n\t\"strings\"\n\n\t\"github.com/google/cadvisor/fs\"\n\t\"github.com/google/cadvisor/fs/vfs\"\n\n\tmount \"github.com/moby/sys/mountinfo\"\n\t\"k8s.io/klog/v2\"\n)\n\ntype btrfsPlugin struct{}\n\n// NewPlugin creates a new Btrfs filesystem plugin.\nfunc NewPlugin() fs.FsPlugin {\n\treturn &btrfsPlugin{}\n}\n\nfunc (p *btrfsPlugin) Name() string {\n\treturn \"btrfs\"\n}\n\n// CanHandle returns true if the filesystem type is btrfs.\nfunc (p *btrfsPlugin) CanHandle(fsType string) bool {\n\treturn fsType == \"btrfs\"\n}\n\n// Priority returns 100 - Btrfs has higher priority than VFS.\nfunc (p *btrfsPlugin) Priority() int {\n\treturn 100\n}\n\n// GetStats returns filesystem statistics for Btrfs.\n// Btrfs delegates to VFS for stats collection.\nfunc (p *btrfsPlugin) GetStats(device string, partition fs.PartitionInfo) (*fs.FsStats, error) {\n\t// Btrfs uses VFS stats\n\tcapacity, free, avail, inodes, inodesFree, err := vfs.GetVfsStats(partition.Mountpoint)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn &fs.FsStats{\n\t\tCapacity:   capacity,\n\t\tFree:       free,\n\t\tAvailable:  avail,\n\t\tInodes:     &inodes,\n\t\tInodesFree: &inodesFree,\n\t\tType:       fs.VFS,\n\t}, nil\n}\n\n// ProcessMount handles Btrfs mount processing.\n// Btrfs fix: following workaround fixes wrong btrfs Major and Minor Ids reported in /proc/self/mountinfo.\n// Instead of using values from /proc/self/mountinfo we use stat to get Ids from btrfs mount point.\nfunc (p *btrfsPlugin) ProcessMount(mnt *mount.Info) (bool, *mount.Info, error) {\n\t// Only apply fix if Major is 0 and Source starts with /dev/\n\tif mnt.Major == 0 && strings.HasPrefix(mnt.Source, \"/dev/\") {\n\t\tmajor, minor, err := GetBtrfsMajorMinorIds(mnt)\n\t\tif err != nil {\n\t\t\tklog.Warningf(\"%s\", err)\n\t\t} else {\n\t\t\t// Create a copy with corrected values\n\t\t\tcorrectedMnt := *mnt\n\t\t\tcorrectedMnt.Major = major\n\t\t\tcorrectedMnt.Minor = minor\n\t\t\treturn true, &correctedMnt, nil\n\t\t}\n\t}\n\treturn true, mnt, nil\n}\n"
  },
  {
    "path": "fs/devicemapper/install/install.go",
    "content": "// Copyright 2014 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage install\n\nimport (\n\t\"github.com/google/cadvisor/fs\"\n\t\"github.com/google/cadvisor/fs/devicemapper\"\n\n\t\"k8s.io/klog/v2\"\n)\n\nfunc init() {\n\terr := fs.RegisterPlugin(\"devicemapper\", devicemapper.NewPlugin())\n\tif err != nil {\n\t\tklog.Fatalf(\"Failed to register devicemapper fs plugin: %v\", err)\n\t}\n}\n"
  },
  {
    "path": "fs/devicemapper/plugin.go",
    "content": "// Copyright 2014 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage devicemapper\n\nimport (\n\t\"github.com/google/cadvisor/fs\"\n\n\tmount \"github.com/moby/sys/mountinfo\"\n\t\"k8s.io/klog/v2\"\n)\n\ntype dmPlugin struct{}\n\n// NewPlugin creates a new DeviceMapper filesystem plugin.\nfunc NewPlugin() fs.FsPlugin {\n\treturn &dmPlugin{}\n}\n\nfunc (p *dmPlugin) Name() string {\n\treturn \"devicemapper\"\n}\n\n// CanHandle returns true if the filesystem type is devicemapper.\nfunc (p *dmPlugin) CanHandle(fsType string) bool {\n\treturn fsType == \"devicemapper\"\n}\n\n// Priority returns 100 - DeviceMapper has higher priority than VFS.\nfunc (p *dmPlugin) Priority() int {\n\treturn 100\n}\n\n// GetStats returns filesystem statistics for DeviceMapper thin provisioning.\nfunc (p *dmPlugin) GetStats(device string, partition fs.PartitionInfo) (*fs.FsStats, error) {\n\tcapacity, free, avail, err := GetDMStats(device, partition.BlockSize)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tklog.V(5).Infof(\"got devicemapper fs capacity stats: capacity: %v free: %v available: %v\", capacity, free, avail)\n\n\treturn &fs.FsStats{\n\t\tCapacity:  capacity,\n\t\tFree:      free,\n\t\tAvailable: avail,\n\t\tType:      fs.DeviceMapper,\n\t}, nil\n}\n\n// ProcessMount handles DeviceMapper mount processing.\n// For DeviceMapper, no special processing is needed.\nfunc (p *dmPlugin) ProcessMount(mnt *mount.Info) (bool, *mount.Info, error) {\n\treturn true, mnt, nil\n}\n"
  },
  {
    "path": "fs/devicemapper/stats.go",
    "content": "// Copyright 2014 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage devicemapper\n\nimport (\n\t\"fmt\"\n\t\"os/exec\"\n\t\"strconv\"\n\t\"strings\"\n\n\tdm \"github.com/google/cadvisor/devicemapper\"\n)\n\n// GetDMStats returns devicemapper thin provisioning stats.\nfunc GetDMStats(poolName string, dataBlkSize uint) (uint64, uint64, uint64, error) {\n\tout, err := exec.Command(\"dmsetup\", \"status\", poolName).Output()\n\tif err != nil {\n\t\treturn 0, 0, 0, err\n\t}\n\n\tused, total, err := parseDMStatus(string(out))\n\tif err != nil {\n\t\treturn 0, 0, 0, err\n\t}\n\n\tused *= 512 * uint64(dataBlkSize)\n\ttotal *= 512 * uint64(dataBlkSize)\n\tfree := total - used\n\n\treturn total, free, free, nil\n}\n\n// parseDMStatus parses the output of `dmsetup status`.\nfunc parseDMStatus(dmStatus string) (uint64, uint64, error) {\n\tdmStatus = strings.Replace(dmStatus, \"/\", \" \", -1)\n\tdmFields := strings.Fields(dmStatus)\n\n\tif len(dmFields) < 8 {\n\t\treturn 0, 0, fmt.Errorf(\"invalid dmsetup status output: %s\", dmStatus)\n\t}\n\n\tused, err := strconv.ParseUint(dmFields[6], 10, 64)\n\tif err != nil {\n\t\treturn 0, 0, err\n\t}\n\ttotal, err := strconv.ParseUint(dmFields[7], 10, 64)\n\tif err != nil {\n\t\treturn 0, 0, err\n\t}\n\n\treturn used, total, nil\n}\n\n// parseDMTable parses a single line of `dmsetup table` output and returns the\n// major device, minor device, block size, and an error.\nfunc ParseDMTable(dmTable string) (uint, uint, uint, error) {\n\tdmTable = strings.Replace(dmTable, \":\", \" \", -1)\n\tdmFields := strings.Fields(dmTable)\n\n\tif len(dmFields) < 8 {\n\t\treturn 0, 0, 0, fmt.Errorf(\"invalid dmsetup status output: %s\", dmTable)\n\t}\n\n\tmajor, err := strconv.ParseUint(dmFields[5], 10, 32)\n\tif err != nil {\n\t\treturn 0, 0, 0, err\n\t}\n\tminor, err := strconv.ParseUint(dmFields[6], 10, 32)\n\tif err != nil {\n\t\treturn 0, 0, 0, err\n\t}\n\tdataBlkSize, err := strconv.ParseUint(dmFields[7], 10, 32)\n\tif err != nil {\n\t\treturn 0, 0, 0, err\n\t}\n\n\treturn uint(major), uint(minor), uint(dataBlkSize), nil\n}\n\n// DockerDMDevice returns information about the devicemapper device and \"partition\" if\n// docker is using devicemapper for its storage driver.\nfunc DockerDMDevice(driverStatus map[string]string, dmsetup dm.DmsetupClient) (string, uint, uint, uint, error) {\n\tconst driverStatusPoolName = \"Pool Name\"\n\n\tpoolName, ok := driverStatus[driverStatusPoolName]\n\tif !ok || len(poolName) == 0 {\n\t\treturn \"\", 0, 0, 0, fmt.Errorf(\"could not get dm pool name\")\n\t}\n\n\tout, err := dmsetup.Table(poolName)\n\tif err != nil {\n\t\treturn \"\", 0, 0, 0, err\n\t}\n\n\tmajor, minor, dataBlkSize, err := ParseDMTable(string(out))\n\tif err != nil {\n\t\treturn \"\", 0, 0, 0, err\n\t}\n\n\treturn poolName, major, minor, dataBlkSize, nil\n}\n"
  },
  {
    "path": "fs/devicemapper/stats_test.go",
    "content": "// Copyright 2014 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage devicemapper\n\nimport (\n\t\"testing\"\n)\n\nvar dmStatusTests = []struct {\n\tdmStatus    string\n\tused        uint64\n\ttotal       uint64\n\terrExpected bool\n}{\n\t{`0 409534464 thin-pool 64085 3705/4161600 88106/3199488 - rw no_discard_passdown queue_if_no_space -`, 88106, 3199488, false},\n\t{`0 209715200 thin-pool 707 1215/524288 30282/1638400 - rw discard_passdown`, 30282, 1638400, false},\n\t{`Invalid status line`, 0, 0, false},\n}\n\nfunc TestParseDMStatus(t *testing.T) {\n\tfor _, tt := range dmStatusTests {\n\t\tused, total, err := parseDMStatus(tt.dmStatus)\n\t\tif tt.errExpected && err != nil {\n\t\t\tt.Errorf(\"parseDMStatus(%q) expected error\", tt.dmStatus)\n\t\t}\n\t\tif used != tt.used {\n\t\t\tt.Errorf(\"parseDMStatus(%q) wrong used value => %q, want %q\", tt.dmStatus, used, tt.used)\n\t\t}\n\t\tif total != tt.total {\n\t\t\tt.Errorf(\"parseDMStatus(%q) wrong total value => %q, want %q\", tt.dmStatus, total, tt.total)\n\t\t}\n\t}\n}\n\nvar dmTableTests = []struct {\n\tdmTable     string\n\tmajor       uint\n\tminor       uint\n\tdataBlkSize uint\n\terrExpected bool\n}{\n\t{`0 409534464 thin-pool 253:6 253:7 128 32768 1 skip_block_zeroing`, 253, 7, 128, false},\n\t{`0 409534464 thin-pool 253:6 258:9 512 32768 1 skip_block_zeroing otherstuff`, 258, 9, 512, false},\n\t{`Invalid status line`, 0, 0, 0, false},\n}\n\nfunc TestParseDMTable(t *testing.T) {\n\tfor _, tt := range dmTableTests {\n\t\tmajor, minor, dataBlkSize, err := ParseDMTable(tt.dmTable)\n\t\tif tt.errExpected && err != nil {\n\t\t\tt.Errorf(\"ParseDMTable(%q) expected error\", tt.dmTable)\n\t\t}\n\t\tif major != tt.major {\n\t\t\tt.Errorf(\"ParseDMTable(%q) wrong major value => %q, want %q\", tt.dmTable, major, tt.major)\n\t\t}\n\t\tif minor != tt.minor {\n\t\t\tt.Errorf(\"ParseDMTable(%q) wrong minor value => %q, want %q\", tt.dmTable, minor, tt.minor)\n\t\t}\n\t\tif dataBlkSize != tt.dataBlkSize {\n\t\t\tt.Errorf(\"ParseDMTable(%q) wrong dataBlkSize value => %q, want %q\", tt.dmTable, dataBlkSize, tt.dataBlkSize)\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "fs/fs.go",
    "content": "// Copyright 2014 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n//go:build linux\n\n// Provides Filesystem Stats\npackage fs\n\nimport (\n\t\"bufio\"\n\t\"errors\"\n\t\"fmt\"\n\t\"os\"\n\t\"path\"\n\t\"path/filepath\"\n\t\"regexp\"\n\t\"strconv\"\n\t\"strings\"\n\t\"syscall\"\n\n\tmount \"github.com/moby/sys/mountinfo\"\n\n\t\"github.com/google/cadvisor/devicemapper\"\n\n\t\"k8s.io/klog/v2\"\n)\n\nconst (\n\tLabelSystemRoot          = \"root\"\n\tLabelDockerImages        = \"docker-images\"\n\tLabelCrioImages          = \"crio-images\"\n\tLabelCrioContainers      = \"crio-containers\"\n\tDriverStatusPoolName     = \"Pool Name\"\n\tDriverStatusDataLoopFile = \"Data loop file\"\n)\n\nconst (\n\t// The block size in bytes.\n\tstatBlockSize uint64 = 512\n\t// The maximum number of `disk usage` tasks that can be running at once.\n\tmaxConcurrentOps = 20\n)\n\n// A pool for restricting the number of consecutive `du` and `find` tasks running.\nvar pool = make(chan struct{}, maxConcurrentOps)\n\nfunc init() {\n\tfor i := 0; i < maxConcurrentOps; i++ {\n\t\treleaseToken()\n\t}\n}\n\nfunc claimToken() {\n\t<-pool\n}\n\nfunc releaseToken() {\n\tpool <- struct{}{}\n}\n\ntype partition struct {\n\tmountpoint string\n\tmajor      uint\n\tminor      uint\n\tfsType     string\n\tblockSize  uint\n}\n\ntype RealFsInfo struct {\n\t// Map from block device path to partition information.\n\tpartitions map[string]partition\n\t// Map from label to block device path.\n\t// Labels are intent-specific tags that are auto-detected.\n\tlabels map[string]string\n\t// Map from mountpoint to mount information.\n\tmounts map[string]mount.Info\n\t// devicemapper client\n\tdmsetup devicemapper.DmsetupClient\n\t// fsUUIDToDeviceName is a map from the filesystem UUID to its device name.\n\tfsUUIDToDeviceName map[string]string\n}\n\nfunc NewFsInfo(context Context) (FsInfo, error) {\n\tfileReader, err := os.Open(\"/proc/self/mountinfo\")\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tmounts, err := mount.GetMountsFromReader(fileReader, nil)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tfsUUIDToDeviceName, err := getFsUUIDToDeviceNameMap()\n\tif err != nil {\n\t\t// UUID is not always available across different OS distributions.\n\t\t// Do not fail if there is an error.\n\t\tklog.Warningf(\"Failed to get disk UUID mapping, getting disk info by uuid will not work: %v\", err)\n\t}\n\n\t// Avoid devicemapper container mounts - these are tracked by the ThinPoolWatcher\n\texcluded := []string{fmt.Sprintf(\"%s/devicemapper/mnt\", context.Docker.Root)}\n\tfsInfo := &RealFsInfo{\n\t\tpartitions:         processMounts(mounts, excluded),\n\t\tlabels:             make(map[string]string),\n\t\tmounts:             make(map[string]mount.Info),\n\t\tdmsetup:            devicemapper.NewDmsetupClient(),\n\t\tfsUUIDToDeviceName: fsUUIDToDeviceName,\n\t}\n\n\tfor _, mnt := range mounts {\n\t\tfsInfo.mounts[mnt.Mountpoint] = *mnt\n\t}\n\n\t// need to call this before the log line below printing out the partitions, as this function may\n\t// add a \"partition\" for devicemapper to fsInfo.partitions\n\tfsInfo.addDockerImagesLabel(context, mounts)\n\tfsInfo.addCrioImagesLabel(context, mounts)\n\n\tklog.V(1).Infof(\"Filesystem UUIDs: %+v\", fsInfo.fsUUIDToDeviceName)\n\tklog.V(1).Infof(\"Filesystem partitions: %+v\", fsInfo.partitions)\n\tfsInfo.addSystemRootLabel(mounts)\n\treturn fsInfo, nil\n}\n\n// getFsUUIDToDeviceNameMap creates the filesystem uuid to device name map\n// using the information in /dev/disk/by-uuid. If the directory does not exist,\n// this function will return an empty map.\nfunc getFsUUIDToDeviceNameMap() (map[string]string, error) {\n\tconst dir = \"/dev/disk/by-uuid\"\n\n\tif _, err := os.Stat(dir); os.IsNotExist(err) {\n\t\treturn make(map[string]string), nil\n\t}\n\n\tfiles, err := os.ReadDir(dir)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tfsUUIDToDeviceName := make(map[string]string)\n\tfor _, file := range files {\n\t\tfpath := filepath.Join(dir, file.Name())\n\t\ttarget, err := os.Readlink(fpath)\n\t\tif err != nil {\n\t\t\tklog.Warningf(\"Failed to resolve symlink for %q\", fpath)\n\t\t\tcontinue\n\t\t}\n\t\tdevice, err := filepath.Abs(filepath.Join(dir, target))\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"failed to resolve the absolute path of %q\", filepath.Join(dir, target))\n\t\t}\n\t\tfsUUIDToDeviceName[file.Name()] = device\n\t}\n\treturn fsUUIDToDeviceName, nil\n}\n\nfunc processMounts(mounts []*mount.Info, excludedMountpointPrefixes []string) map[string]partition {\n\tpartitions := make(map[string]partition)\n\n\tfor _, mnt := range mounts {\n\t\t// Use plugin system to determine if filesystem is supported\n\t\tplugin := GetPluginForFsType(mnt.FSType)\n\t\tif plugin == nil {\n\t\t\tcontinue\n\t\t}\n\n\t\t// Avoid bind mounts, but allow tmpfs duplicates (handled by plugin's ProcessMount)\n\t\tif _, ok := partitions[mnt.Source]; ok {\n\t\t\tif mnt.FSType != \"tmpfs\" {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t}\n\n\t\t// Check for excluded mountpoint prefixes\n\t\thasPrefix := false\n\t\tfor _, prefix := range excludedMountpointPrefixes {\n\t\t\tif strings.HasPrefix(mnt.Mountpoint, prefix) {\n\t\t\t\thasPrefix = true\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t\tif hasPrefix {\n\t\t\tcontinue\n\t\t}\n\n\t\t// Let plugin process the mount (handles filesystem-specific modifications)\n\t\tinclude, processedMnt, err := plugin.ProcessMount(mnt)\n\t\tif err != nil {\n\t\t\tklog.Warningf(\"error processing mount for %s: %v\", mnt.FSType, err)\n\t\t\tcontinue\n\t\t}\n\t\tif !include {\n\t\t\tcontinue\n\t\t}\n\n\t\tpartitions[processedMnt.Source] = partition{\n\t\t\tfsType:     processedMnt.FSType,\n\t\t\tmountpoint: processedMnt.Mountpoint,\n\t\t\tmajor:      uint(processedMnt.Major),\n\t\t\tminor:      uint(processedMnt.Minor),\n\t\t}\n\t}\n\n\treturn partitions\n}\n\n// getDockerDeviceMapperInfo returns information about the devicemapper device and \"partition\" if\n// docker is using devicemapper for its storage driver. If a loopback device is being used, don't\n// return any information or error, as we want to report based on the actual partition where the\n// loopback file resides, inside of the loopback file itself.\nfunc (i *RealFsInfo) getDockerDeviceMapperInfo(context DockerContext) (string, *partition, error) {\n\tif context.Driver != DeviceMapper.String() {\n\t\treturn \"\", nil, nil\n\t}\n\n\tdataLoopFile := context.DriverStatus[DriverStatusDataLoopFile]\n\tif len(dataLoopFile) > 0 {\n\t\treturn \"\", nil, nil\n\t}\n\n\tdev, major, minor, blockSize, err := dockerDMDevice(context.DriverStatus, i.dmsetup)\n\tif err != nil {\n\t\treturn \"\", nil, err\n\t}\n\n\treturn dev, &partition{\n\t\tfsType:    DeviceMapper.String(),\n\t\tmajor:     major,\n\t\tminor:     minor,\n\t\tblockSize: blockSize,\n\t}, nil\n}\n\n// addSystemRootLabel attempts to determine which device contains the mount for /.\nfunc (i *RealFsInfo) addSystemRootLabel(mounts []*mount.Info) {\n\tfor _, m := range mounts {\n\t\tif m.Mountpoint == \"/\" {\n\t\t\ti.partitions[m.Source] = partition{\n\t\t\t\tfsType:     m.FSType,\n\t\t\t\tmountpoint: m.Mountpoint,\n\t\t\t\tmajor:      uint(m.Major),\n\t\t\t\tminor:      uint(m.Minor),\n\t\t\t}\n\t\t\ti.labels[LabelSystemRoot] = m.Source\n\t\t\treturn\n\t\t}\n\t}\n}\n\n// addDockerImagesLabel attempts to determine which device contains the mount for docker images.\nfunc (i *RealFsInfo) addDockerImagesLabel(context Context, mounts []*mount.Info) {\n\tif context.Docker.Driver != \"\" {\n\t\tdockerDev, dockerPartition, err := i.getDockerDeviceMapperInfo(context.Docker)\n\t\tif err != nil {\n\t\t\tklog.Warningf(\"Could not get Docker devicemapper device: %v\", err)\n\t\t}\n\t\tif len(dockerDev) > 0 && dockerPartition != nil {\n\t\t\ti.partitions[dockerDev] = *dockerPartition\n\t\t\ti.labels[LabelDockerImages] = dockerDev\n\t\t} else {\n\t\t\ti.updateContainerImagesPath(LabelDockerImages, mounts, getDockerImagePaths(context))\n\t\t}\n\t}\n}\n\nfunc (i *RealFsInfo) addCrioImagesLabel(context Context, mounts []*mount.Info) {\n\tlabelCrioImageOrContainers := LabelCrioContainers\n\t// If imagestore is not specified, let's fall back to the original case.\n\t// Everything will be stored in crio-images\n\tif context.Crio.ImageStore == \"\" {\n\t\tlabelCrioImageOrContainers = LabelCrioImages\n\t}\n\tif context.Crio.Root != \"\" {\n\t\tcrioPath := context.Crio.Root\n\t\tcrioImagePaths := map[string]struct{}{\n\t\t\t\"/\": {},\n\t\t}\n\t\timageOrContainerPath := context.Crio.Driver + \"-containers\"\n\t\tif context.Crio.ImageStore == \"\" {\n\t\t\t// If ImageStore is not specified then we will assume ImageFs is complete separate.\n\t\t\t// No need to split the image store.\n\t\t\timageOrContainerPath = context.Crio.Driver + \"-images\"\n\n\t\t}\n\t\tcrioImagePaths[path.Join(crioPath, imageOrContainerPath)] = struct{}{}\n\t\tfor crioPath != \"/\" && crioPath != \".\" {\n\t\t\tcrioImagePaths[crioPath] = struct{}{}\n\t\t\tcrioPath = filepath.Dir(crioPath)\n\t\t}\n\t\ti.updateContainerImagesPath(labelCrioImageOrContainers, mounts, crioImagePaths)\n\t}\n\tif context.Crio.ImageStore != \"\" {\n\t\tcrioPath := context.Crio.ImageStore\n\t\tcrioImagePaths := map[string]struct{}{\n\t\t\t\"/\": {},\n\t\t}\n\t\tcrioImagePaths[path.Join(crioPath, context.Crio.Driver+\"-images\")] = struct{}{}\n\t\tfor crioPath != \"/\" && crioPath != \".\" {\n\t\t\tcrioImagePaths[crioPath] = struct{}{}\n\t\t\tcrioPath = filepath.Dir(crioPath)\n\t\t}\n\t\ti.updateContainerImagesPath(LabelCrioImages, mounts, crioImagePaths)\n\t}\n}\n\n// Generate a list of possible mount points for docker image management from the docker root directory.\n// Right now, we look for each type of supported graph driver directories, but we can do better by parsing\n// some of the context from `docker info`.\nfunc getDockerImagePaths(context Context) map[string]struct{} {\n\tdockerImagePaths := map[string]struct{}{\n\t\t\"/\": {},\n\t}\n\n\t// TODO(rjnagal): Detect docker root and graphdriver directories from docker info.\n\tdockerRoot := context.Docker.Root\n\tfor _, dir := range []string{\"devicemapper\", \"btrfs\", \"aufs\", \"overlay\", \"overlay2\", \"zfs\"} {\n\t\tdockerImagePaths[path.Join(dockerRoot, dir)] = struct{}{}\n\t}\n\tfor dockerRoot != \"/\" && dockerRoot != \".\" {\n\t\tdockerImagePaths[dockerRoot] = struct{}{}\n\t\tdockerRoot = filepath.Dir(dockerRoot)\n\t}\n\treturn dockerImagePaths\n}\n\n// This method compares the mountpoints with possible container image mount points. If a match is found,\n// the label is added to the partition.\nfunc (i *RealFsInfo) updateContainerImagesPath(label string, mounts []*mount.Info, containerImagePaths map[string]struct{}) {\n\tvar useMount *mount.Info\n\tfor _, m := range mounts {\n\t\tif _, ok := containerImagePaths[m.Mountpoint]; ok {\n\t\t\tif useMount == nil || (len(useMount.Mountpoint) < len(m.Mountpoint)) {\n\t\t\t\tuseMount = m\n\t\t\t}\n\t\t}\n\t}\n\tif useMount != nil {\n\t\ti.partitions[useMount.Source] = partition{\n\t\t\tfsType:     useMount.FSType,\n\t\t\tmountpoint: useMount.Mountpoint,\n\t\t\tmajor:      uint(useMount.Major),\n\t\t\tminor:      uint(useMount.Minor),\n\t\t}\n\t\ti.labels[label] = useMount.Source\n\t}\n}\n\nfunc (i *RealFsInfo) GetDeviceForLabel(label string) (string, error) {\n\tdev, ok := i.labels[label]\n\tif !ok {\n\t\treturn \"\", fmt.Errorf(\"non-existent label %q\", label)\n\t}\n\treturn dev, nil\n}\n\nfunc (i *RealFsInfo) GetLabelsForDevice(device string) ([]string, error) {\n\tvar labels []string\n\tfor label, dev := range i.labels {\n\t\tif dev == device {\n\t\t\tlabels = append(labels, label)\n\t\t}\n\t}\n\treturn labels, nil\n}\n\nfunc (i *RealFsInfo) GetMountpointForDevice(dev string) (string, error) {\n\tp, ok := i.partitions[dev]\n\tif !ok {\n\t\treturn \"\", fmt.Errorf(\"no partition info for device %q\", dev)\n\t}\n\treturn p.mountpoint, nil\n}\n\nfunc (i *RealFsInfo) GetFsInfoForPath(mountSet map[string]struct{}) ([]Fs, error) {\n\tfilesystems := make([]Fs, 0)\n\tdeviceSet := make(map[string]struct{})\n\tdiskStatsMap, err := getDiskStatsMap(\"/proc/diskstats\")\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\t// statsCache stores cached filesystem stats by cache key for plugins that implement FsCachingPlugin\n\tstatsCache := make(map[string]Fs)\n\tfor device, partition := range i.partitions {\n\t\t_, hasMount := mountSet[partition.mountpoint]\n\t\t_, hasDevice := deviceSet[device]\n\t\tif mountSet == nil || (hasMount && !hasDevice) {\n\t\t\tvar (\n\t\t\t\tstatsErr error\n\t\t\t\tfs       Fs\n\t\t\t)\n\n\t\t\t// Use plugin system to get filesystem stats\n\t\t\tplugin := GetPluginForFsType(partition.fsType)\n\t\t\tif plugin == nil {\n\t\t\t\tklog.V(4).Infof(\"no plugin found for filesystem type: %v\", partition.fsType)\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tpartInfo := PartitionInfo{\n\t\t\t\tMountpoint: partition.mountpoint,\n\t\t\t\tMajor:      partition.major,\n\t\t\t\tMinor:      partition.minor,\n\t\t\t\tFsType:     partition.fsType,\n\t\t\t\tBlockSize:  partition.blockSize,\n\t\t\t}\n\n\t\t\t// Check if plugin supports caching and if we have a cached value\n\t\t\tvar cacheKey string\n\t\t\tif cachingPlugin, ok := plugin.(FsCachingPlugin); ok {\n\t\t\t\tcacheKey = cachingPlugin.CacheKey(partInfo)\n\t\t\t\tif cacheKey != \"\" {\n\t\t\t\t\tif cachedFs, found := statsCache[cacheKey]; found {\n\t\t\t\t\t\tfs = cachedFs\n\t\t\t\t\t\t// Skip stats fetching, use cached value\n\t\t\t\t\t\tdeviceSet[device] = struct{}{}\n\t\t\t\t\t\tfs.DeviceInfo = DeviceInfo{\n\t\t\t\t\t\t\tDevice: device,\n\t\t\t\t\t\t\tMajor:  uint(partition.major),\n\t\t\t\t\t\t\tMinor:  uint(partition.minor),\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif val, ok := diskStatsMap[device]; ok {\n\t\t\t\t\t\t\tfs.DiskStats = val\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tfor k, v := range diskStatsMap {\n\t\t\t\t\t\t\t\tif v.MajorNum == uint64(partition.major) && v.MinorNum == uint64(partition.minor) {\n\t\t\t\t\t\t\t\t\tfs.DiskStats = diskStatsMap[k]\n\t\t\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tfilesystems = append(filesystems, fs)\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tstats, statsErr := plugin.GetStats(device, partInfo)\n\t\t\tif statsErr != nil {\n\t\t\t\t// Handle fallback to VFS for plugins that request it\n\t\t\t\tif errors.Is(statsErr, ErrFallbackToVFS) {\n\t\t\t\t\tvfsPlugin := GetPluginForFsType(\"ext4\") // VFS handles ext*\n\t\t\t\t\tif vfsPlugin != nil {\n\t\t\t\t\t\tstats, statsErr = vfsPlugin.GetStats(device, partInfo)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif statsErr != nil {\n\t\t\t\t\tklog.V(4).Infof(\"Stat fs failed for %s. Error: %v\", partition.fsType, statsErr)\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif stats == nil {\n\t\t\t\tklog.V(4).Infof(\"no stats returned for %s at %s\", partition.fsType, partition.mountpoint)\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tfs.Capacity = stats.Capacity\n\t\t\tfs.Free = stats.Free\n\t\t\tfs.Available = stats.Available\n\t\t\tfs.Inodes = stats.Inodes\n\t\t\tfs.InodesFree = stats.InodesFree\n\t\t\tfs.Type = stats.Type\n\n\t\t\t// Store in cache if plugin supports caching\n\t\t\tif cacheKey != \"\" {\n\t\t\t\tstatsCache[cacheKey] = fs\n\t\t\t}\n\n\t\t\tdeviceSet[device] = struct{}{}\n\t\t\tfs.DeviceInfo = DeviceInfo{\n\t\t\t\tDevice: device,\n\t\t\t\tMajor:  uint(partition.major),\n\t\t\t\tMinor:  uint(partition.minor),\n\t\t\t}\n\n\t\t\tif val, ok := diskStatsMap[device]; ok {\n\t\t\t\tfs.DiskStats = val\n\t\t\t} else {\n\t\t\t\tfor k, v := range diskStatsMap {\n\t\t\t\t\tif v.MajorNum == uint64(partition.major) && v.MinorNum == uint64(partition.minor) {\n\t\t\t\t\t\tfs.DiskStats = diskStatsMap[k]\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tfilesystems = append(filesystems, fs)\n\t\t}\n\t}\n\treturn filesystems, nil\n}\n\nvar partitionRegex = regexp.MustCompile(`^(?:(?:s|v|xv)d[a-z]+\\d*|dm-\\d+)$`)\n\nfunc getDiskStatsMap(diskStatsFile string) (map[string]DiskStats, error) {\n\tdiskStatsMap := make(map[string]DiskStats)\n\tfile, err := os.Open(diskStatsFile)\n\tif err != nil {\n\t\tif os.IsNotExist(err) {\n\t\t\tklog.Warningf(\"Not collecting filesystem statistics because file %q was not found\", diskStatsFile)\n\t\t\treturn diskStatsMap, nil\n\t\t}\n\t\treturn nil, err\n\t}\n\n\tdefer file.Close()\n\tscanner := bufio.NewScanner(file)\n\n\tfor scanner.Scan() {\n\t\tline := scanner.Text()\n\t\twords := strings.Fields(line)\n\t\tif !partitionRegex.MatchString(words[2]) {\n\t\t\tcontinue\n\t\t}\n\t\t// 8      50 sdd2 40 0 280 223 7 0 22 108 0 330 330\n\t\tdeviceName := path.Join(\"/dev\", words[2])\n\n\t\tvar err error\n\t\tdevInfo := make([]uint64, 2)\n\t\tfor i := 0; i < len(devInfo); i++ {\n\t\t\tdevInfo[i], err = strconv.ParseUint(words[i], 10, 64)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t}\n\n\t\twordLength := len(words)\n\t\toffset := 3\n\t\tvar stats = make([]uint64, wordLength-offset)\n\t\tif len(stats) < 11 {\n\t\t\treturn nil, fmt.Errorf(\"could not parse all 11 columns of /proc/diskstats\")\n\t\t}\n\t\tfor i := offset; i < wordLength; i++ {\n\t\t\tstats[i-offset], err = strconv.ParseUint(words[i], 10, 64)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t}\n\n\t\tmajor64, err := strconv.ParseUint(words[0], 10, 64)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\tminor64, err := strconv.ParseUint(words[1], 10, 64)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\tdiskStats := DiskStats{\n\t\t\tMajorNum:        devInfo[0],\n\t\t\tMinorNum:        devInfo[1],\n\t\t\tReadsCompleted:  stats[0],\n\t\t\tReadsMerged:     stats[1],\n\t\t\tSectorsRead:     stats[2],\n\t\t\tReadTime:        stats[3],\n\t\t\tWritesCompleted: stats[4],\n\t\t\tWritesMerged:    stats[5],\n\t\t\tSectorsWritten:  stats[6],\n\t\t\tWriteTime:       stats[7],\n\t\t\tIoInProgress:    stats[8],\n\t\t\tIoTime:          stats[9],\n\t\t\tWeightedIoTime:  stats[10],\n\t\t\tMajor:           major64,\n\t\t\tMinor:           minor64,\n\t\t}\n\t\tdiskStatsMap[deviceName] = diskStats\n\t}\n\treturn diskStatsMap, nil\n}\n\nfunc (i *RealFsInfo) GetGlobalFsInfo() ([]Fs, error) {\n\treturn i.GetFsInfoForPath(nil)\n}\n\nfunc major(devNumber uint64) uint {\n\treturn uint((devNumber >> 8) & 0xfff)\n}\n\nfunc minor(devNumber uint64) uint {\n\treturn uint((devNumber & 0xff) | ((devNumber >> 12) & 0xfff00))\n}\n\nfunc (i *RealFsInfo) GetDeviceInfoByFsUUID(uuid string) (*DeviceInfo, error) {\n\tdeviceName, found := i.fsUUIDToDeviceName[uuid]\n\tif !found {\n\t\treturn nil, ErrNoSuchDevice\n\t}\n\tp, found := i.partitions[deviceName]\n\tif !found {\n\t\treturn nil, fmt.Errorf(\"cannot find device %q in partitions\", deviceName)\n\t}\n\treturn &DeviceInfo{deviceName, p.major, p.minor}, nil\n}\n\nfunc (i *RealFsInfo) mountInfoFromDir(dir string) (*mount.Info, bool) {\n\tmnt, found := i.mounts[dir]\n\t// try the parent dir if not found until we reach the root dir\n\t// this is an issue on btrfs systems where the directory is not\n\t// the subvolume\n\tfor !found {\n\t\tpathdir, _ := filepath.Split(dir)\n\t\t// break when we reach root\n\t\tif pathdir == \"/\" {\n\t\t\tmnt, found = i.mounts[\"/\"]\n\t\t\tbreak\n\t\t}\n\t\t// trim \"/\" from the new parent path otherwise the next possible\n\t\t// filepath.Split in the loop will not split the string any further\n\t\tdir = strings.TrimSuffix(pathdir, \"/\")\n\t\tmnt, found = i.mounts[dir]\n\t}\n\treturn &mnt, found\n}\n\nfunc (i *RealFsInfo) GetDirFsDevice(dir string) (*DeviceInfo, error) {\n\tbuf := new(syscall.Stat_t)\n\terr := syscall.Stat(dir, buf)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"stat failed on %s with error: %s\", dir, err)\n\t}\n\n\t// The type Dev in Stat_t is 32bit on mips.\n\tmajor := major(uint64(buf.Dev)) // nolint: unconvert\n\tminor := minor(uint64(buf.Dev)) // nolint: unconvert\n\tfor device, partition := range i.partitions {\n\t\tif partition.major == major && partition.minor == minor {\n\t\t\treturn &DeviceInfo{device, major, minor}, nil\n\t\t}\n\t}\n\n\tmnt, found := i.mountInfoFromDir(dir)\n\tif found && strings.HasPrefix(mnt.Source, \"/dev/\") {\n\t\tmajor, minor := mnt.Major, mnt.Minor\n\n\t\tif mnt.FSType == \"btrfs\" && major == 0 {\n\t\t\tmajor, minor, err = getBtrfsMajorMinorIds(mnt)\n\t\t\tif err != nil {\n\t\t\t\tklog.Warningf(\"Unable to get btrfs mountpoint IDs: %v\", err)\n\t\t\t}\n\t\t}\n\n\t\treturn &DeviceInfo{mnt.Source, uint(major), uint(minor)}, nil\n\t}\n\n\treturn nil, fmt.Errorf(\"with major: %d, minor: %d: %w\", major, minor, ErrDeviceNotInPartitionsMap)\n}\n\nfunc GetDirUsage(dir string) (UsageInfo, error) {\n\tvar usage UsageInfo\n\n\tif dir == \"\" {\n\t\treturn usage, fmt.Errorf(\"invalid directory\")\n\t}\n\n\trootInfo, err := os.Stat(dir)\n\tif err != nil {\n\t\treturn usage, fmt.Errorf(\"could not stat %q to get inode usage: %v\", dir, err)\n\t}\n\n\trootStat, ok := rootInfo.Sys().(*syscall.Stat_t)\n\tif !ok {\n\t\treturn usage, fmt.Errorf(\"unsupported fileinfo for getting inode usage of %q\", dir)\n\t}\n\n\trootDevID := rootStat.Dev\n\n\t// dedupedInode stores inodes that could be duplicates (nlink > 1)\n\tdedupedInodes := make(map[uint64]struct{})\n\n\terr = filepath.Walk(dir, func(path string, info os.FileInfo, err error) error {\n\t\tif os.IsNotExist(err) {\n\t\t\t// expected if files appear/vanish\n\t\t\treturn nil\n\t\t}\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"unable to count inodes for part of dir %s: %s\", dir, err)\n\t\t}\n\n\t\t// according to the docs, Sys can be nil\n\t\tif info.Sys() == nil {\n\t\t\treturn fmt.Errorf(\"fileinfo Sys is nil\")\n\t\t}\n\n\t\ts, ok := info.Sys().(*syscall.Stat_t)\n\t\tif !ok {\n\t\t\treturn fmt.Errorf(\"unsupported fileinfo; could not convert to stat_t\")\n\t\t}\n\n\t\tif s.Dev != rootDevID {\n\t\t\t// don't descend into directories on other devices\n\t\t\treturn filepath.SkipDir\n\t\t}\n\t\tif s.Nlink > 1 {\n\t\t\tif _, ok := dedupedInodes[s.Ino]; !ok {\n\t\t\t\t// Dedupe things that could be hardlinks\n\t\t\t\tdedupedInodes[s.Ino] = struct{}{}\n\n\t\t\t\tusage.Bytes += uint64(s.Blocks) * statBlockSize\n\t\t\t\tusage.Inodes++\n\t\t\t}\n\t\t} else {\n\t\t\tusage.Bytes += uint64(s.Blocks) * statBlockSize\n\t\t\tusage.Inodes++\n\t\t}\n\t\treturn nil\n\t})\n\n\treturn usage, err\n}\n\nfunc (i *RealFsInfo) GetDirUsage(dir string) (UsageInfo, error) {\n\tclaimToken()\n\tdefer releaseToken()\n\treturn GetDirUsage(dir)\n}\n\n// Devicemapper thin provisioning is detailed at\n// https://www.kernel.org/doc/Documentation/device-mapper/thin-provisioning.txt\nfunc dockerDMDevice(driverStatus map[string]string, dmsetup devicemapper.DmsetupClient) (string, uint, uint, uint, error) {\n\tpoolName, ok := driverStatus[DriverStatusPoolName]\n\tif !ok || len(poolName) == 0 {\n\t\treturn \"\", 0, 0, 0, fmt.Errorf(\"could not get dm pool name\")\n\t}\n\n\tout, err := dmsetup.Table(poolName)\n\tif err != nil {\n\t\treturn \"\", 0, 0, 0, err\n\t}\n\n\tmajor, minor, dataBlkSize, err := parseDMTable(string(out))\n\tif err != nil {\n\t\treturn \"\", 0, 0, 0, err\n\t}\n\n\treturn poolName, major, minor, dataBlkSize, nil\n}\n\n// parseDMTable parses a single line of `dmsetup table` output and returns the\n// major device, minor device, block size, and an error.\nfunc parseDMTable(dmTable string) (uint, uint, uint, error) {\n\tdmTable = strings.Replace(dmTable, \":\", \" \", -1)\n\tdmFields := strings.Fields(dmTable)\n\n\tif len(dmFields) < 8 {\n\t\treturn 0, 0, 0, fmt.Errorf(\"invalid dmsetup status output: %s\", dmTable)\n\t}\n\n\tmajor, err := strconv.ParseUint(dmFields[5], 10, 32)\n\tif err != nil {\n\t\treturn 0, 0, 0, err\n\t}\n\tminor, err := strconv.ParseUint(dmFields[6], 10, 32)\n\tif err != nil {\n\t\treturn 0, 0, 0, err\n\t}\n\tdataBlkSize, err := strconv.ParseUint(dmFields[7], 10, 32)\n\tif err != nil {\n\t\treturn 0, 0, 0, err\n\t}\n\n\treturn uint(major), uint(minor), uint(dataBlkSize), nil\n}\n\n// Get major and minor Ids for a mount point using btrfs as filesystem.\nfunc getBtrfsMajorMinorIds(mount *mount.Info) (int, int, error) {\n\t// btrfs fix: following workaround fixes wrong btrfs Major and Minor Ids reported in /proc/self/mountinfo.\n\t// instead of using values from /proc/self/mountinfo we use stat to get Ids from btrfs mount point\n\n\tbuf := new(syscall.Stat_t)\n\terr := syscall.Stat(mount.Source, buf)\n\tif err != nil {\n\t\terr = fmt.Errorf(\"stat failed on %s with error: %s\", mount.Source, err)\n\t\treturn 0, 0, err\n\t}\n\n\tklog.V(4).Infof(\"btrfs mount %#v\", mount)\n\tif buf.Mode&syscall.S_IFMT == syscall.S_IFBLK {\n\t\terr := syscall.Stat(mount.Mountpoint, buf)\n\t\tif err != nil {\n\t\t\terr = fmt.Errorf(\"stat failed on %s with error: %s\", mount.Mountpoint, err)\n\t\t\treturn 0, 0, err\n\t\t}\n\n\t\t// The type Dev and Rdev in Stat_t are 32bit on mips.\n\t\tklog.V(4).Infof(\"btrfs dev major:minor %d:%d\\n\", int(major(uint64(buf.Dev))), int(minor(uint64(buf.Dev))))    // nolint: unconvert\n\t\tklog.V(4).Infof(\"btrfs rdev major:minor %d:%d\\n\", int(major(uint64(buf.Rdev))), int(minor(uint64(buf.Rdev)))) // nolint: unconvert\n\n\t\treturn int(major(uint64(buf.Dev))), int(minor(uint64(buf.Dev))), nil // nolint: unconvert\n\t}\n\treturn 0, 0, fmt.Errorf(\"%s is not a block device\", mount.Source)\n}\n"
  },
  {
    "path": "fs/fs_test.go",
    "content": "// Copyright 2014 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n//go:build linux\n\npackage fs\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"os\"\n\t\"reflect\"\n\t\"strings\"\n\t\"testing\"\n\n\tmount \"github.com/moby/sys/mountinfo\"\n\t\"github.com/stretchr/testify/assert\"\n\t\"github.com/stretchr/testify/require\"\n)\n\n// testPlugin is a minimal plugin implementation for testing processMounts.\ntype testPlugin struct {\n\tname             string\n\tcanHandle        func(string) bool\n\tpriority         int\n\tprocessMountFunc func(*mount.Info) (bool, *mount.Info, error)\n}\n\nfunc (p *testPlugin) Name() string                 { return p.name }\nfunc (p *testPlugin) CanHandle(fsType string) bool { return p.canHandle(fsType) }\nfunc (p *testPlugin) Priority() int                { return p.priority }\nfunc (p *testPlugin) GetStats(device string, partition PartitionInfo) (*FsStats, error) {\n\treturn nil, nil\n}\nfunc (p *testPlugin) ProcessMount(mnt *mount.Info) (bool, *mount.Info, error) {\n\tif p.processMountFunc != nil {\n\t\treturn p.processMountFunc(mnt)\n\t}\n\treturn true, mnt, nil\n}\n\nfunc init() {\n\t// Register test plugins for processMounts tests\n\n\t// VFS plugin - handles ext*, xfs\n\tRegisterPlugin(\"test-vfs\", &testPlugin{\n\t\tname: \"test-vfs\",\n\t\tcanHandle: func(fsType string) bool {\n\t\t\tif strings.HasPrefix(fsType, \"ext\") {\n\t\t\t\treturn true\n\t\t\t}\n\t\t\treturn fsType == \"xfs\"\n\t\t},\n\t\tpriority: 0,\n\t})\n\n\t// ZFS plugin\n\tRegisterPlugin(\"test-zfs\", &testPlugin{\n\t\tname:      \"test-zfs\",\n\t\tcanHandle: func(fsType string) bool { return fsType == \"zfs\" },\n\t\tpriority:  100,\n\t})\n\n\t// Btrfs plugin\n\tRegisterPlugin(\"test-btrfs\", &testPlugin{\n\t\tname:      \"test-btrfs\",\n\t\tcanHandle: func(fsType string) bool { return fsType == \"btrfs\" },\n\t\tpriority:  100,\n\t})\n\n\t// Overlay plugin - makes source unique with major/minor\n\tRegisterPlugin(\"test-overlay\", &testPlugin{\n\t\tname:      \"test-overlay\",\n\t\tcanHandle: func(fsType string) bool { return fsType == \"overlay\" },\n\t\tpriority:  100,\n\t\tprocessMountFunc: func(mnt *mount.Info) (bool, *mount.Info, error) {\n\t\t\tcorrectedMnt := *mnt\n\t\t\tcorrectedMnt.Source = fmt.Sprintf(\"%s_%d-%d\", mnt.Source, mnt.Major, mnt.Minor)\n\t\t\treturn true, &correctedMnt, nil\n\t\t},\n\t})\n\n\t// NFS plugin\n\tRegisterPlugin(\"test-nfs\", &testPlugin{\n\t\tname:      \"test-nfs\",\n\t\tcanHandle: func(fsType string) bool { return strings.HasPrefix(fsType, \"nfs\") },\n\t\tpriority:  50,\n\t})\n\n\t// tmpfs plugin - uses mountpoint as source\n\tRegisterPlugin(\"test-tmpfs\", &testPlugin{\n\t\tname:      \"test-tmpfs\",\n\t\tcanHandle: func(fsType string) bool { return fsType == \"tmpfs\" },\n\t\tpriority:  100,\n\t\tprocessMountFunc: func(mnt *mount.Info) (bool, *mount.Info, error) {\n\t\t\tcorrectedMnt := *mnt\n\t\t\tcorrectedMnt.Source = mnt.Mountpoint\n\t\t\treturn true, &correctedMnt, nil\n\t\t},\n\t})\n}\n\nfunc TestMountInfoFromDir(t *testing.T) {\n\tas := assert.New(t)\n\tfsInfo := &RealFsInfo{\n\t\tmounts: map[string]mount.Info{\n\t\t\t\"/\": {},\n\t\t},\n\t}\n\ttestDirs := []string{\"/var/lib/kubelet\", \"/var/lib/rancher\"}\n\tfor _, testDir := range testDirs {\n\t\t_, found := fsInfo.mountInfoFromDir(testDir)\n\t\tas.True(found, \"failed to find MountInfo %s from FsInfo %s\", testDir, fsInfo)\n\t}\n}\n\nfunc TestGetDiskStatsMap(t *testing.T) {\n\tdiskStatsMap, err := getDiskStatsMap(\"test_resources/diskstats\")\n\tif err != nil {\n\t\tt.Errorf(\"Error calling getDiskStatsMap %s\", err)\n\t}\n\tif len(diskStatsMap) != 30 {\n\t\tt.Errorf(\"diskStatsMap %+v not valid\", diskStatsMap)\n\t}\n\tkeySet := map[string]string{\n\t\t\"/dev/sda\":  \"/dev/sda\",\n\t\t\"/dev/sdb\":  \"/dev/sdb\",\n\t\t\"/dev/sdc\":  \"/dev/sdc\",\n\t\t\"/dev/sdd\":  \"/dev/sdd\",\n\t\t\"/dev/sde\":  \"/dev/sde\",\n\t\t\"/dev/sdf\":  \"/dev/sdf\",\n\t\t\"/dev/sdg\":  \"/dev/sdg\",\n\t\t\"/dev/sdh\":  \"/dev/sdh\",\n\t\t\"/dev/sdb1\": \"/dev/sdb1\",\n\t\t\"/dev/sdb2\": \"/dev/sdb2\",\n\t\t\"/dev/sda1\": \"/dev/sda1\",\n\t\t\"/dev/sda2\": \"/dev/sda2\",\n\t\t\"/dev/sdc1\": \"/dev/sdc1\",\n\t\t\"/dev/sdc2\": \"/dev/sdc2\",\n\t\t\"/dev/sdc3\": \"/dev/sdc3\",\n\t\t\"/dev/sdc4\": \"/dev/sdc4\",\n\t\t\"/dev/sdd1\": \"/dev/sdd1\",\n\t\t\"/dev/sdd2\": \"/dev/sdd2\",\n\t\t\"/dev/sdd3\": \"/dev/sdd3\",\n\t\t\"/dev/sdd4\": \"/dev/sdd4\",\n\t\t\"/dev/sde1\": \"/dev/sde1\",\n\t\t\"/dev/sde2\": \"/dev/sde2\",\n\t\t\"/dev/sdf1\": \"/dev/sdf1\",\n\t\t\"/dev/sdf2\": \"/dev/sdf2\",\n\t\t\"/dev/sdg1\": \"/dev/sdg1\",\n\t\t\"/dev/sdg2\": \"/dev/sdg2\",\n\t\t\"/dev/sdh1\": \"/dev/sdh1\",\n\t\t\"/dev/sdh2\": \"/dev/sdh2\",\n\t\t\"/dev/dm-0\": \"/dev/dm-0\",\n\t\t\"/dev/dm-1\": \"/dev/dm-1\",\n\t}\n\n\tfor device := range diskStatsMap {\n\t\tif _, ok := keySet[device]; !ok {\n\t\t\tt.Errorf(\"Cannot find device %s\", device)\n\t\t}\n\t\tdelete(keySet, device)\n\t}\n\tif len(keySet) != 0 {\n\t\tt.Errorf(\"diskStatsMap %+v contains illegal keys %+v\", diskStatsMap, keySet)\n\t}\n}\n\nfunc TestGetDiskStatsMapMajorMinorNum(t *testing.T) {\n\tdiskStatsMap, err := getDiskStatsMap(\"test_resources/diskstats\")\n\tif err != nil {\n\t\tt.Errorf(\"Error calling getDiskStatsMap %s\", err)\n\t}\n\tif len(diskStatsMap) != 30 {\n\t\tt.Errorf(\"diskStatsMap %+v not valid\", diskStatsMap)\n\t}\n\n\tif stat, ok := diskStatsMap[\"/dev/dm-0\"]; ok {\n\t\tif stat.MajorNum != 252 && stat.MinorNum != 1 {\n\t\t\tt.Fatalf(\"getDiskStatsMap did not return correct major (%d) and minor (%d) numbers\", stat.MajorNum, stat.MinorNum)\n\t\t}\n\t}\n}\n\nfunc TestFileNotExist(t *testing.T) {\n\t_, err := getDiskStatsMap(\"/file_does_not_exist\")\n\tif err != nil {\n\t\tt.Fatalf(\"getDiskStatsMap must not error for absent file: %s\", err)\n\t}\n}\n\nfunc TestDirDiskUsage(t *testing.T) {\n\tas := assert.New(t)\n\tfsInfo, err := NewFsInfo(Context{})\n\tas.NoError(err)\n\tdir := t.TempDir()\n\tas.NoError(err)\n\tdefer os.RemoveAll(dir)\n\tdataSize := 1024 * 100 //100 KB\n\tb := make([]byte, dataSize)\n\tf, err := os.CreateTemp(dir, \"\")\n\tas.NoError(err)\n\tas.NoError(os.WriteFile(f.Name(), b, 0700))\n\tfi, err := f.Stat()\n\tas.NoError(err)\n\texpectedSize := uint64(fi.Size())\n\tusage, err := fsInfo.GetDirUsage(dir)\n\tas.NoError(err)\n\tas.True(expectedSize <= usage.Bytes, \"expected dir size to be at-least %d; got size: %d\", expectedSize, usage.Bytes)\n}\n\nfunc TestDirInodeUsage(t *testing.T) {\n\tas := assert.New(t)\n\tfsInfo, err := NewFsInfo(Context{})\n\tas.NoError(err)\n\tdir := t.TempDir()\n\tdefer os.RemoveAll(dir)\n\tnumFiles := 1000\n\tfor i := 0; i < numFiles; i++ {\n\t\t_, err := os.MkdirTemp(dir, \"\")\n\t\trequire.NoError(t, err)\n\t}\n\tusage, err := fsInfo.GetDirUsage(dir)\n\tas.NoError(err)\n\t// We should get numFiles+1 inodes, since we get 1 inode for each file, plus 1 for the directory\n\tas.True(uint64(numFiles+1) == usage.Inodes, \"expected inodes in dir to be %d; got inodes: %d\", numFiles+1, usage.Inodes)\n}\n\nfunc TestAddSystemRootLabel(t *testing.T) {\n\ttests := []struct {\n\t\tmounts   []*mount.Info\n\t\texpected string\n\t}{\n\t\t{\n\t\t\tmounts: []*mount.Info{\n\t\t\t\t{Source: \"/dev/sda1\", Mountpoint: \"/foo\"},\n\t\t\t\t{Source: \"/dev/sdb1\", Mountpoint: \"/\"},\n\t\t\t},\n\t\t\texpected: \"/dev/sdb1\",\n\t\t},\n\t}\n\n\tfor i, tt := range tests {\n\t\tfsInfo := &RealFsInfo{\n\t\t\tlabels:     map[string]string{},\n\t\t\tpartitions: map[string]partition{},\n\t\t}\n\t\tfsInfo.addSystemRootLabel(tt.mounts)\n\n\t\tif source, ok := fsInfo.labels[LabelSystemRoot]; !ok || source != tt.expected {\n\t\t\tt.Errorf(\"case %d: expected mount source '%s', got '%s'\", i, tt.expected, source)\n\t\t}\n\t}\n}\n\ntype testDmsetup struct {\n\tdata []byte\n\terr  error\n}\n\nfunc (*testDmsetup) Message(deviceName string, sector int, message string) ([]byte, error) {\n\treturn nil, nil\n}\n\nfunc (*testDmsetup) Status(deviceName string) ([]byte, error) {\n\treturn nil, nil\n}\n\nfunc (t *testDmsetup) Table(poolName string) ([]byte, error) {\n\treturn t.data, t.err\n}\n\nfunc TestGetDockerDeviceMapperInfo(t *testing.T) {\n\ttests := []struct {\n\t\tname              string\n\t\tdriver            string\n\t\tdriverStatus      map[string]string\n\t\tdmsetupTable      string\n\t\tdmsetupTableError error\n\t\texpectedDevice    string\n\t\texpectedPartition *partition\n\t\texpectedError     bool\n\t}{\n\t\t{\n\t\t\tname:              \"not devicemapper\",\n\t\t\tdriver:            \"btrfs\",\n\t\t\texpectedDevice:    \"\",\n\t\t\texpectedPartition: nil,\n\t\t\texpectedError:     false,\n\t\t},\n\t\t{\n\t\t\tname:              \"nil driver status\",\n\t\t\tdriver:            \"devicemapper\",\n\t\t\tdriverStatus:      nil,\n\t\t\texpectedDevice:    \"\",\n\t\t\texpectedPartition: nil,\n\t\t\texpectedError:     true,\n\t\t},\n\t\t{\n\t\t\tname:              \"loopback\",\n\t\t\tdriver:            \"devicemapper\",\n\t\t\tdriverStatus:      map[string]string{\"Data loop file\": \"/var/lib/docker/devicemapper/devicemapper/data\"},\n\t\t\texpectedDevice:    \"\",\n\t\t\texpectedPartition: nil,\n\t\t\texpectedError:     false,\n\t\t},\n\t\t{\n\t\t\tname:              \"missing pool name\",\n\t\t\tdriver:            \"devicemapper\",\n\t\t\tdriverStatus:      map[string]string{},\n\t\t\texpectedDevice:    \"\",\n\t\t\texpectedPartition: nil,\n\t\t\texpectedError:     true,\n\t\t},\n\t\t{\n\t\t\tname:              \"error invoking dmsetup\",\n\t\t\tdriver:            \"devicemapper\",\n\t\t\tdriverStatus:      map[string]string{\"Pool Name\": \"vg_vagrant-docker--pool\"},\n\t\t\tdmsetupTableError: errors.New(\"foo\"),\n\t\t\texpectedDevice:    \"\",\n\t\t\texpectedPartition: nil,\n\t\t\texpectedError:     true,\n\t\t},\n\t\t{\n\t\t\tname:              \"unable to parse dmsetup table\",\n\t\t\tdriver:            \"devicemapper\",\n\t\t\tdriverStatus:      map[string]string{\"Pool Name\": \"vg_vagrant-docker--pool\"},\n\t\t\tdmsetupTable:      \"no data here!\",\n\t\t\texpectedDevice:    \"\",\n\t\t\texpectedPartition: nil,\n\t\t\texpectedError:     true,\n\t\t},\n\t\t{\n\t\t\tname:           \"happy path\",\n\t\t\tdriver:         \"devicemapper\",\n\t\t\tdriverStatus:   map[string]string{\"Pool Name\": \"vg_vagrant-docker--pool\"},\n\t\t\tdmsetupTable:   \"0 53870592 thin-pool 253:2 253:3 1024 0 1 skip_block_zeroing\",\n\t\t\texpectedDevice: \"vg_vagrant-docker--pool\",\n\t\t\texpectedPartition: &partition{\n\t\t\t\tfsType:    \"devicemapper\",\n\t\t\t\tmajor:     253,\n\t\t\t\tminor:     3,\n\t\t\t\tblockSize: 1024,\n\t\t\t},\n\t\t\texpectedError: false,\n\t\t},\n\t}\n\n\tfor _, tt := range tests {\n\t\tfsInfo := &RealFsInfo{\n\t\t\tdmsetup: &testDmsetup{\n\t\t\t\tdata: []byte(tt.dmsetupTable),\n\t\t\t},\n\t\t}\n\n\t\tdockerCtx := DockerContext{\n\t\t\tDriver:       tt.driver,\n\t\t\tDriverStatus: tt.driverStatus,\n\t\t}\n\n\t\tdevice, partition, err := fsInfo.getDockerDeviceMapperInfo(dockerCtx)\n\n\t\tif tt.expectedError && err == nil {\n\t\t\tt.Errorf(\"%s: expected error but got nil\", tt.name)\n\t\t\tcontinue\n\t\t}\n\t\tif !tt.expectedError && err != nil {\n\t\t\tt.Errorf(\"%s: unexpected error: %v\", tt.name, err)\n\t\t\tcontinue\n\t\t}\n\n\t\tif e, a := tt.expectedDevice, device; e != a {\n\t\t\tt.Errorf(\"%s: device: expected %q, got %q\", tt.name, e, a)\n\t\t}\n\n\t\tif e, a := tt.expectedPartition, partition; !reflect.DeepEqual(e, a) {\n\t\t\tt.Errorf(\"%s: partition: expected %#v, got %#v\", tt.name, e, a)\n\t\t}\n\t}\n}\n\nfunc TestAddDockerImagesLabel(t *testing.T) {\n\ttests := []struct {\n\t\tname                           string\n\t\tdriver                         string\n\t\tdriverStatus                   map[string]string\n\t\tdmsetupTable                   string\n\t\tgetDockerDeviceMapperInfoError error\n\t\tmounts                         []*mount.Info\n\t\texpectedDockerDevice           string\n\t\texpectedPartition              *partition\n\t}{\n\t\t{\n\t\t\tname:   \"single partition, no dedicated image fs\",\n\t\t\tdriver: \"overlay2\",\n\t\t\tmounts: []*mount.Info{\n\t\t\t\t{\n\t\t\t\t\tSource:     \"/dev/root\",\n\t\t\t\t\tMountpoint: \"/\",\n\t\t\t\t\tFSType:     \"ext4\",\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tSource:     \"/sys/fs/cgroup\",\n\t\t\t\t\tMountpoint: \"/sys/fs/cgroup\",\n\t\t\t\t\tFSType:     \"tmpfs\",\n\t\t\t\t},\n\t\t\t},\n\t\t\texpectedDockerDevice: \"/dev/root\",\n\t\t},\n\t\t{\n\t\t\tname:         \"devicemapper, not loopback\",\n\t\t\tdriver:       \"devicemapper\",\n\t\t\tdriverStatus: map[string]string{\"Pool Name\": \"vg_vagrant-docker--pool\"},\n\t\t\tdmsetupTable: \"0 53870592 thin-pool 253:2 253:3 1024 0 1 skip_block_zeroing\",\n\t\t\tmounts: []*mount.Info{\n\t\t\t\t{\n\t\t\t\t\tSource:     \"/dev/mapper/vg_vagrant-lv_root\",\n\t\t\t\t\tMountpoint: \"/\",\n\t\t\t\t\tFSType:     \"devicemapper\",\n\t\t\t\t},\n\t\t\t},\n\t\t\texpectedDockerDevice: \"vg_vagrant-docker--pool\",\n\t\t\texpectedPartition: &partition{\n\t\t\t\tfsType:    \"devicemapper\",\n\t\t\t\tmajor:     253,\n\t\t\t\tminor:     3,\n\t\t\t\tblockSize: 1024,\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname:         \"devicemapper, loopback on non-root partition\",\n\t\t\tdriver:       \"devicemapper\",\n\t\t\tdriverStatus: map[string]string{\"Data loop file\": \"/var/lib/docker/devicemapper/devicemapper/data\"},\n\t\t\tmounts: []*mount.Info{\n\t\t\t\t{\n\t\t\t\t\tSource:     \"/dev/mapper/vg_vagrant-lv_root\",\n\t\t\t\t\tMountpoint: \"/\",\n\t\t\t\t\tFSType:     \"devicemapper\",\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tSource:     \"/dev/sdb1\",\n\t\t\t\t\tMountpoint: \"/var/lib/docker/devicemapper\",\n\t\t\t\t},\n\t\t\t},\n\t\t\texpectedDockerDevice: \"/dev/sdb1\",\n\t\t},\n\t\t{\n\t\t\tname:   \"multiple mounts - innermost check\",\n\t\t\tdriver: \"overlay2\",\n\t\t\tmounts: []*mount.Info{\n\t\t\t\t{\n\t\t\t\t\tSource:     \"/dev/sda1\",\n\t\t\t\t\tMountpoint: \"/\",\n\t\t\t\t\tFSType:     \"ext4\",\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tSource:     \"/dev/sdb1\",\n\t\t\t\t\tMountpoint: \"/var/lib/docker\",\n\t\t\t\t\tFSType:     \"ext4\",\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tSource:     \"/dev/sdb2\",\n\t\t\t\t\tMountpoint: \"/var/lib/docker/btrfs\",\n\t\t\t\t\tFSType:     \"btrfs\",\n\t\t\t\t},\n\t\t\t},\n\t\t\texpectedDockerDevice: \"/dev/sdb2\",\n\t\t},\n\t\t{\n\t\t\tname:   \"root fs inside container, docker-images bindmount\",\n\t\t\tdriver: \"overlay2\",\n\t\t\tmounts: []*mount.Info{\n\t\t\t\t{\n\t\t\t\t\tSource:     \"overlay\",\n\t\t\t\t\tMountpoint: \"/\",\n\t\t\t\t\tFSType:     \"overlay\",\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tSource:     \"/dev/sda1\",\n\t\t\t\t\tMountpoint: \"/var/lib/docker\",\n\t\t\t\t\tFSType:     \"ext4\",\n\t\t\t\t},\n\t\t\t},\n\t\t\texpectedDockerDevice: \"/dev/sda1\",\n\t\t},\n\t\t{\n\t\t\tname:   \"[overlay2] root fs inside container - /var/lib/docker bindmount\",\n\t\t\tdriver: \"overlay2\",\n\t\t\tmounts: []*mount.Info{\n\t\t\t\t{\n\t\t\t\t\tSource:     \"overlay\",\n\t\t\t\t\tMountpoint: \"/\",\n\t\t\t\t\tFSType:     \"overlay\",\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tSource:     \"/dev/sdb1\",\n\t\t\t\t\tMountpoint: \"/var/lib/docker\",\n\t\t\t\t\tFSType:     \"ext4\",\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tSource:     \"/dev/sdb2\",\n\t\t\t\t\tMountpoint: \"/var/lib/docker/overlay2\",\n\t\t\t\t\tFSType:     \"ext4\",\n\t\t\t\t},\n\t\t\t},\n\t\t\texpectedDockerDevice: \"/dev/sdb2\",\n\t\t},\n\t}\n\n\tfor _, tt := range tests {\n\t\tfsInfo := &RealFsInfo{\n\t\t\tlabels:     map[string]string{},\n\t\t\tpartitions: map[string]partition{},\n\t\t\tdmsetup: &testDmsetup{\n\t\t\t\tdata: []byte(tt.dmsetupTable),\n\t\t\t},\n\t\t}\n\n\t\tcontext := Context{\n\t\t\tDocker: DockerContext{\n\t\t\t\tRoot:         \"/var/lib/docker\",\n\t\t\t\tDriver:       tt.driver,\n\t\t\t\tDriverStatus: tt.driverStatus,\n\t\t\t},\n\t\t}\n\n\t\tfsInfo.addDockerImagesLabel(context, tt.mounts)\n\n\t\tif e, a := tt.expectedDockerDevice, fsInfo.labels[LabelDockerImages]; e != a {\n\t\t\tt.Errorf(\"%s: docker device: expected %q, got %q\", tt.name, e, a)\n\t\t}\n\n\t\tif tt.expectedPartition == nil {\n\t\t\tcontinue\n\t\t}\n\t\tif e, a := *tt.expectedPartition, fsInfo.partitions[tt.expectedDockerDevice]; !reflect.DeepEqual(e, a) {\n\t\t\tt.Errorf(\"%s: docker partition: expected %#v, got %#v\", tt.name, e, a)\n\t\t}\n\t}\n}\n\nfunc TestAddCrioImagesLabel(t *testing.T) {\n\ttests := []struct {\n\t\tname                   string\n\t\tdriver                 string\n\t\tdriverStatus           map[string]string\n\t\tdmsetupTable           string\n\t\tmounts                 []*mount.Info\n\t\timageStore             string\n\t\texpectedCrioImages     string\n\t\texpectedCrioContainers string\n\t\texpectedPartition      *partition\n\t}{\n\t\t{\n\t\t\tname:   \"single partition, no dedicated image fs\",\n\t\t\tdriver: \"overlay2\",\n\t\t\tmounts: []*mount.Info{\n\t\t\t\t{\n\t\t\t\t\tSource:     \"/dev/root\",\n\t\t\t\t\tMountpoint: \"/\",\n\t\t\t\t\tFSType:     \"ext4\",\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tSource:     \"/sys/fs/cgroup\",\n\t\t\t\t\tMountpoint: \"/sys/fs/cgroup\",\n\t\t\t\t\tFSType:     \"tmpfs\",\n\t\t\t\t},\n\t\t\t},\n\t\t\texpectedCrioImages:     \"/dev/root\",\n\t\t\texpectedCrioContainers: \"\",\n\t\t},\n\t\t{\n\t\t\tname:   \"root fs inside container, docker-images bindmount\",\n\t\t\tdriver: \"overlay2\",\n\t\t\tmounts: []*mount.Info{\n\t\t\t\t{\n\t\t\t\t\tSource:     \"overlay\",\n\t\t\t\t\tMountpoint: \"/\",\n\t\t\t\t\tFSType:     \"overlay\",\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tSource:     \"/dev/sda1\",\n\t\t\t\t\tMountpoint: \"/var/lib/container\",\n\t\t\t\t\tFSType:     \"ext4\",\n\t\t\t\t},\n\t\t\t},\n\t\t\texpectedCrioImages: \"/dev/sda1\",\n\t\t},\n\t\t{\n\t\t\tname:   \"[overlay2] image and container separate\",\n\t\t\tdriver: \"overlay2\",\n\t\t\tmounts: []*mount.Info{\n\t\t\t\t{\n\t\t\t\t\tSource:     \"/dev/sdb1\",\n\t\t\t\t\tMountpoint: \"/imagestore\",\n\t\t\t\t\tFSType:     \"ext4\",\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tSource:     \"/dev/sdb2\",\n\t\t\t\t\tMountpoint: \"/var/lib/container\",\n\t\t\t\t\tFSType:     \"ext4\",\n\t\t\t\t},\n\t\t\t},\n\t\t\texpectedCrioImages:     \"/dev/sdb1\",\n\t\t\texpectedCrioContainers: \"/dev/sdb2\",\n\t\t\timageStore:             \"/imagestore\",\n\t\t},\n\t}\n\n\tfor _, tt := range tests {\n\t\tfsInfo := &RealFsInfo{\n\t\t\tlabels:     map[string]string{},\n\t\t\tpartitions: map[string]partition{},\n\t\t\tdmsetup: &testDmsetup{\n\t\t\t\tdata: []byte(tt.dmsetupTable),\n\t\t\t},\n\t\t}\n\n\t\tcontext := Context{\n\t\t\tCrio: CrioContext{\n\t\t\t\tRoot:       \"/var/lib/container\",\n\t\t\t\tImageStore: tt.imageStore,\n\t\t\t\tDriver:     \"overlay\",\n\t\t\t},\n\t\t}\n\n\t\tfsInfo.addCrioImagesLabel(context, tt.mounts)\n\n\t\tif tt.imageStore != \"\" {\n\t\t\tif e, a := tt.expectedCrioImages, fsInfo.labels[LabelCrioImages]; e != a {\n\t\t\t\tt.Errorf(\"%s: docker device: expected %q, got %q\", tt.name, e, a)\n\t\t\t}\n\n\t\t\tif e, a := tt.expectedCrioContainers, fsInfo.labels[LabelCrioContainers]; e != a {\n\t\t\t\tt.Errorf(\"%s: docker device: expected %q, got %q\", tt.name, e, a)\n\t\t\t}\n\n\t\t}\n\t\tif tt.imageStore == \"\" {\n\t\t\tif e, a := tt.expectedCrioImages, fsInfo.labels[LabelCrioImages]; e != a {\n\t\t\t\tt.Errorf(\"%s: docker device: expected %q, got %q\", tt.name, e, a)\n\t\t\t}\n\n\t\t}\n\n\t\tif tt.expectedPartition == nil {\n\t\t\tcontinue\n\t\t}\n\t}\n}\n\nfunc TestProcessMounts(t *testing.T) {\n\ttests := []struct {\n\t\tname             string\n\t\tmounts           []*mount.Info\n\t\texcludedPrefixes []string\n\t\texpected         map[string]partition\n\t}{\n\t\t{\n\t\t\tname: \"unsupported fs types\",\n\t\t\tmounts: []*mount.Info{\n\t\t\t\t{FSType: \"somethingelse\"},\n\t\t\t},\n\t\t\texpected: map[string]partition{},\n\t\t},\n\t\t{\n\t\t\tname: \"avoid bind mounts\",\n\t\t\tmounts: []*mount.Info{\n\t\t\t\t{Root: \"/\", Mountpoint: \"/\", Source: \"/dev/sda1\", FSType: \"xfs\", Major: 253, Minor: 0},\n\t\t\t\t{Root: \"/foo\", Mountpoint: \"/bar\", Source: \"/dev/sda1\", FSType: \"xfs\", Major: 253, Minor: 0},\n\t\t\t},\n\t\t\texpected: map[string]partition{\n\t\t\t\t\"/dev/sda1\": {fsType: \"xfs\", mountpoint: \"/\", major: 253, minor: 0},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"exclude prefixes\",\n\t\t\tmounts: []*mount.Info{\n\t\t\t\t{Root: \"/\", Mountpoint: \"/someother\", Source: \"/dev/sda1\", FSType: \"xfs\", Major: 253, Minor: 2},\n\t\t\t\t{Root: \"/\", Mountpoint: \"/\", Source: \"/dev/sda2\", FSType: \"xfs\", Major: 253, Minor: 0},\n\t\t\t\t{Root: \"/\", Mountpoint: \"/excludeme\", Source: \"/dev/sda3\", FSType: \"xfs\", Major: 253, Minor: 1},\n\t\t\t},\n\t\t\texcludedPrefixes: []string{\"/exclude\", \"/some\"},\n\t\t\texpected: map[string]partition{\n\t\t\t\t\"/dev/sda2\": {fsType: \"xfs\", mountpoint: \"/\", major: 253, minor: 0},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"supported fs types\",\n\t\t\tmounts: []*mount.Info{\n\t\t\t\t{Root: \"/\", Mountpoint: \"/a\", Source: \"/dev/sda\", FSType: \"ext3\", Major: 253, Minor: 0},\n\t\t\t\t{Root: \"/\", Mountpoint: \"/b\", Source: \"/dev/sdb\", FSType: \"ext4\", Major: 253, Minor: 1},\n\t\t\t\t{Root: \"/\", Mountpoint: \"/c\", Source: \"/dev/sdc\", FSType: \"btrfs\", Major: 253, Minor: 2},\n\t\t\t\t{Root: \"/\", Mountpoint: \"/d\", Source: \"/dev/sdd\", FSType: \"xfs\", Major: 253, Minor: 3},\n\t\t\t\t{Root: \"/\", Mountpoint: \"/e\", Source: \"/dev/sde\", FSType: \"zfs\", Major: 253, Minor: 4},\n\t\t\t\t{Root: \"/\", Mountpoint: \"/f\", Source: \"overlay\", FSType: \"overlay\", Major: 253, Minor: 5},\n\t\t\t\t{Root: \"/\", Mountpoint: \"/g\", Source: \"127.0.0.1:/nfs\", FSType: \"nfs4\", Major: 253, Minor: 6},\n\t\t\t\t{Root: \"/\", Mountpoint: \"/test1\", Source: \"tmpfs\", FSType: \"tmpfs\", Major: 253, Minor: 4},\n\t\t\t\t{Root: \"/\", Mountpoint: \"/test2\", Source: \"tmpfs\", FSType: \"tmpfs\", Major: 253, Minor: 4},\n\t\t\t},\n\t\t\texpected: map[string]partition{\n\t\t\t\t\"/dev/sda\":       {fsType: \"ext3\", mountpoint: \"/a\", major: 253, minor: 0},\n\t\t\t\t\"/dev/sdb\":       {fsType: \"ext4\", mountpoint: \"/b\", major: 253, minor: 1},\n\t\t\t\t\"/dev/sdc\":       {fsType: \"btrfs\", mountpoint: \"/c\", major: 253, minor: 2},\n\t\t\t\t\"/dev/sdd\":       {fsType: \"xfs\", mountpoint: \"/d\", major: 253, minor: 3},\n\t\t\t\t\"/dev/sde\":       {fsType: \"zfs\", mountpoint: \"/e\", major: 253, minor: 4},\n\t\t\t\t\"overlay_253-5\":  {fsType: \"overlay\", mountpoint: \"/f\", major: 253, minor: 5},\n\t\t\t\t\"127.0.0.1:/nfs\": {fsType: \"nfs4\", mountpoint: \"/g\", major: 253, minor: 6},\n\t\t\t\t\"/test1\":         {fsType: \"tmpfs\", mountpoint: \"/test1\", major: 253, minor: 4},\n\t\t\t\t\"/test2\":         {fsType: \"tmpfs\", mountpoint: \"/test2\", major: 253, minor: 4},\n\t\t\t},\n\t\t},\n\t}\n\n\tfor _, test := range tests {\n\t\tactual := processMounts(test.mounts, test.excludedPrefixes)\n\t\tif !reflect.DeepEqual(test.expected, actual) {\n\t\t\tt.Errorf(\"%s: expected %#v, got %#v\", test.name, test.expected, actual)\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "fs/nfs/install/install.go",
    "content": "// Copyright 2014 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n//go:build linux\n\npackage install\n\nimport (\n\t\"github.com/google/cadvisor/fs\"\n\t\"github.com/google/cadvisor/fs/nfs\"\n\n\t\"k8s.io/klog/v2\"\n)\n\nfunc init() {\n\terr := fs.RegisterPlugin(\"nfs\", nfs.NewPlugin())\n\tif err != nil {\n\t\tklog.Fatalf(\"Failed to register nfs fs plugin: %v\", err)\n\t}\n}\n"
  },
  {
    "path": "fs/nfs/plugin.go",
    "content": "// Copyright 2014 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n//go:build linux\n\npackage nfs\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n\n\t\"github.com/google/cadvisor/fs\"\n\t\"github.com/google/cadvisor/fs/vfs\"\n\n\tmount \"github.com/moby/sys/mountinfo\"\n\t\"k8s.io/klog/v2\"\n)\n\ntype nfsPlugin struct{}\n\n// Ensure nfsPlugin implements FsCachingPlugin\nvar _ fs.FsCachingPlugin = &nfsPlugin{}\n\n// NewPlugin creates a new NFS filesystem plugin.\nfunc NewPlugin() fs.FsPlugin {\n\treturn &nfsPlugin{}\n}\n\nfunc (p *nfsPlugin) Name() string {\n\treturn \"nfs\"\n}\n\n// CanHandle returns true if the filesystem type is NFS (nfs, nfs3, nfs4, etc.).\nfunc (p *nfsPlugin) CanHandle(fsType string) bool {\n\treturn strings.HasPrefix(fsType, \"nfs\")\n}\n\n// Priority returns 50 - NFS has medium priority (higher than VFS but lower than specific plugins).\nfunc (p *nfsPlugin) Priority() int {\n\treturn 50\n}\n\n// GetStats returns filesystem statistics for NFS.\n// NFS uses VFS stats.\nfunc (p *nfsPlugin) GetStats(device string, partition fs.PartitionInfo) (*fs.FsStats, error) {\n\tcapacity, free, avail, inodes, inodesFree, err := vfs.GetVfsStats(partition.Mountpoint)\n\tif err != nil {\n\t\tklog.V(4).Infof(\"the file system type is %s, partition mountpoint does not exist: %v, error: %v\",\n\t\t\tpartition.FsType, partition.Mountpoint, err)\n\t\treturn nil, err\n\t}\n\n\treturn &fs.FsStats{\n\t\tCapacity:   capacity,\n\t\tFree:       free,\n\t\tAvailable:  avail,\n\t\tInodes:     &inodes,\n\t\tInodesFree: &inodesFree,\n\t\tType:       fs.VFS,\n\t}, nil\n}\n\n// ProcessMount handles NFS mount processing.\n// For NFS, no special processing is needed.\nfunc (p *nfsPlugin) ProcessMount(mnt *mount.Info) (bool, *mount.Info, error) {\n\treturn true, mnt, nil\n}\n\n// CacheKey returns a cache key based on device ID (major:minor).\n// NFS mounts with the same device ID share the same underlying filesystem,\n// so we can cache stats to avoid redundant statfs calls.\nfunc (p *nfsPlugin) CacheKey(partition fs.PartitionInfo) string {\n\treturn fmt.Sprintf(\"%d:%d\", partition.Major, partition.Minor)\n}\n"
  },
  {
    "path": "fs/overlay/install/install.go",
    "content": "// Copyright 2014 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n//go:build linux\n\npackage install\n\nimport (\n\t\"github.com/google/cadvisor/fs\"\n\t\"github.com/google/cadvisor/fs/overlay\"\n\n\t\"k8s.io/klog/v2\"\n)\n\nfunc init() {\n\terr := fs.RegisterPlugin(\"overlay\", overlay.NewPlugin())\n\tif err != nil {\n\t\tklog.Fatalf(\"Failed to register overlay fs plugin: %v\", err)\n\t}\n}\n"
  },
  {
    "path": "fs/overlay/plugin.go",
    "content": "// Copyright 2014 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n//go:build linux\n\npackage overlay\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/google/cadvisor/fs\"\n\t\"github.com/google/cadvisor/fs/vfs\"\n\n\tmount \"github.com/moby/sys/mountinfo\"\n)\n\ntype overlayPlugin struct{}\n\n// NewPlugin creates a new Overlay filesystem plugin.\nfunc NewPlugin() fs.FsPlugin {\n\treturn &overlayPlugin{}\n}\n\nfunc (p *overlayPlugin) Name() string {\n\treturn \"overlay\"\n}\n\n// CanHandle returns true if the filesystem type is overlay or overlay2.\nfunc (p *overlayPlugin) CanHandle(fsType string) bool {\n\treturn fsType == \"overlay\"\n}\n\n// Priority returns 100 - Overlay has higher priority than VFS.\nfunc (p *overlayPlugin) Priority() int {\n\treturn 100\n}\n\n// GetStats returns filesystem statistics for Overlay.\n// Overlay delegates to VFS for stats collection.\nfunc (p *overlayPlugin) GetStats(device string, partition fs.PartitionInfo) (*fs.FsStats, error) {\n\t// Overlay uses VFS stats\n\tcapacity, free, avail, inodes, inodesFree, err := vfs.GetVfsStats(partition.Mountpoint)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn &fs.FsStats{\n\t\tCapacity:   capacity,\n\t\tFree:       free,\n\t\tAvailable:  avail,\n\t\tInodes:     &inodes,\n\t\tInodesFree: &inodesFree,\n\t\tType:       fs.VFS,\n\t}, nil\n}\n\n// ProcessMount handles Overlay mount processing.\n// Overlay fix: Making mount source unique for all overlay mounts, using the mount's major and minor ids.\n// This is needed because multiple overlay mounts can have the same source.\nfunc (p *overlayPlugin) ProcessMount(mnt *mount.Info) (bool, *mount.Info, error) {\n\t// Create a copy with unique source\n\tcorrectedMnt := *mnt\n\tcorrectedMnt.Source = fmt.Sprintf(\"%s_%d-%d\", mnt.Source, mnt.Major, mnt.Minor)\n\treturn true, &correctedMnt, nil\n}\n"
  },
  {
    "path": "fs/plugin.go",
    "content": "// Copyright 2014 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage fs\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"sync\"\n\n\tmount \"github.com/moby/sys/mountinfo\"\n\t\"k8s.io/klog/v2\"\n)\n\n// FsPlugin provides filesystem-specific statistics collection.\ntype FsPlugin interface {\n\t// Name returns the plugin identifier (e.g., \"zfs\", \"devicemapper\", \"vfs\").\n\tName() string\n\n\t// CanHandle returns true if this plugin handles the given filesystem type.\n\tCanHandle(fsType string) bool\n\n\t// Priority returns the plugin priority (higher = checked first).\n\t// Allows specific plugins (zfs, btrfs) to override generic (vfs).\n\tPriority() int\n\n\t// GetStats returns filesystem statistics for a partition.\n\tGetStats(device string, partition PartitionInfo) (*FsStats, error)\n\n\t// ProcessMount optionally modifies mount info during processing.\n\t// Returns (shouldInclude bool, modifiedMount *mount.Info, error).\n\tProcessMount(mnt *mount.Info) (bool, *mount.Info, error)\n}\n\n// FsCachingPlugin is an optional interface for plugins that want to cache\n// stats by a key (e.g., device ID) to avoid redundant stat calls.\n// This is useful for network filesystems like NFS where multiple mounts\n// may point to the same underlying device.\ntype FsCachingPlugin interface {\n\tFsPlugin\n\n\t// CacheKey returns a cache key for the given partition.\n\t// Stats will be cached by this key and reused for partitions with the same key.\n\t// Return empty string to disable caching for a specific partition.\n\tCacheKey(partition PartitionInfo) string\n}\n\n// FsWatcherPlugin is an optional interface for plugins that provide\n// background monitoring (e.g., ZFS watcher, ThinPool watcher).\ntype FsWatcherPlugin interface {\n\tFsPlugin\n\n\t// StartWatcher starts background monitoring.\n\t// Returns a Watcher that can be used to get container-level usage.\n\tStartWatcher() (FsWatcher, error)\n}\n\n// FsWatcher provides container-level filesystem usage from background monitoring.\ntype FsWatcher interface {\n\t// GetUsage returns filesystem usage for a specific container/path.\n\tGetUsage(containerID string, deviceID string) (uint64, error)\n\n\t// Stop stops the background monitoring.\n\tStop()\n}\n\n// PartitionInfo contains information needed for stats collection.\ntype PartitionInfo struct {\n\tMountpoint string\n\tMajor      uint\n\tMinor      uint\n\tFsType     string\n\tBlockSize  uint\n}\n\n// FsStats contains filesystem statistics returned by plugins.\ntype FsStats struct {\n\tCapacity   uint64\n\tFree       uint64\n\tAvailable  uint64\n\tInodes     *uint64\n\tInodesFree *uint64\n\tType       FsType\n}\n\n// ErrFallbackToVFS signals that a specialized plugin cannot handle\n// this filesystem and VFS should be used instead.\nvar ErrFallbackToVFS = errors.New(\"fallback to VFS\")\n\n// Plugin registry (init-time registration only).\nvar (\n\tpluginsLock sync.RWMutex\n\tplugins     = make(map[string]FsPlugin)\n)\n\n// RegisterPlugin registers a filesystem plugin.\n// This should be called from init() functions.\nfunc RegisterPlugin(name string, plugin FsPlugin) error {\n\tpluginsLock.Lock()\n\tdefer pluginsLock.Unlock()\n\tif _, found := plugins[name]; found {\n\t\treturn fmt.Errorf(\"FsPlugin %q was registered twice\", name)\n\t}\n\tklog.V(4).Infof(\"Registered FsPlugin %q\", name)\n\tplugins[name] = plugin\n\treturn nil\n}\n\n// GetPluginForFsType returns the appropriate plugin for the filesystem type.\n// Returns nil if no plugin can handle the filesystem type.\nfunc GetPluginForFsType(fsType string) FsPlugin {\n\tpluginsLock.RLock()\n\tdefer pluginsLock.RUnlock()\n\n\tvar best FsPlugin\n\tfor _, p := range plugins {\n\t\tif p.CanHandle(fsType) {\n\t\t\tif best == nil || p.Priority() > best.Priority() {\n\t\t\t\tbest = p\n\t\t\t}\n\t\t}\n\t}\n\treturn best\n}\n\n// GetAllPlugins returns all registered plugins.\nfunc GetAllPlugins() []FsPlugin {\n\tpluginsLock.RLock()\n\tdefer pluginsLock.RUnlock()\n\n\tresult := make([]FsPlugin, 0, len(plugins))\n\tfor _, p := range plugins {\n\t\tresult = append(result, p)\n\t}\n\treturn result\n}\n\n// InitializeWatchers starts all plugin watchers and returns them.\nfunc InitializeWatchers() map[string]FsWatcher {\n\tpluginsLock.RLock()\n\tdefer pluginsLock.RUnlock()\n\n\twatchers := make(map[string]FsWatcher)\n\tfor name, plugin := range plugins {\n\t\tif wp, ok := plugin.(FsWatcherPlugin); ok {\n\t\t\twatcher, err := wp.StartWatcher()\n\t\t\tif err != nil {\n\t\t\t\tklog.V(4).Infof(\"Failed to start watcher for plugin %s: %v\", name, err)\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif watcher != nil {\n\t\t\t\twatchers[name] = watcher\n\t\t\t\tklog.V(4).Infof(\"Started watcher for FsPlugin %q\", name)\n\t\t\t}\n\t\t}\n\t}\n\treturn watchers\n}\n\n// StopWatchers stops all provided watchers.\nfunc StopWatchers(watchers map[string]FsWatcher) {\n\tfor name, watcher := range watchers {\n\t\tif watcher != nil {\n\t\t\twatcher.Stop()\n\t\t\tklog.V(4).Infof(\"Stopped watcher for FsPlugin %q\", name)\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "fs/test_resources/diskstats",
    "content": "   1       0 ram0 0 0 0 0 0 0 0 0 0 0 0\n   1       1 ram1 0 0 0 0 0 0 0 0 0 0 0\n   1       2 ram2 0 0 0 0 0 0 0 0 0 0 0\n   1       3 ram3 0 0 0 0 0 0 0 0 0 0 0\n   1       4 ram4 0 0 0 0 0 0 0 0 0 0 0\n   1       5 ram5 0 0 0 0 0 0 0 0 0 0 0\n   1       6 ram6 0 0 0 0 0 0 0 0 0 0 0\n   1       7 ram7 0 0 0 0 0 0 0 0 0 0 0\n   1       8 ram8 0 0 0 0 0 0 0 0 0 0 0\n   1       9 ram9 0 0 0 0 0 0 0 0 0 0 0\n   1      10 ram10 0 0 0 0 0 0 0 0 0 0 0\n   1      11 ram11 0 0 0 0 0 0 0 0 0 0 0\n   1      12 ram12 0 0 0 0 0 0 0 0 0 0 0\n   1      13 ram13 0 0 0 0 0 0 0 0 0 0 0\n   1      14 ram14 0 0 0 0 0 0 0 0 0 0 0\n   1      15 ram15 0 0 0 0 0 0 0 0 0 0 0\n   7       0 loop0 0 0 0 0 0 0 0 0 0 0 0\n   7       1 loop1 0 0 0 0 0 0 0 0 0 0 0\n   7       2 loop2 0 0 0 0 0 0 0 0 0 0 0\n   7       3 loop3 0 0 0 0 0 0 0 0 0 0 0\n   7       4 loop4 0 0 0 0 0 0 0 0 0 0 0\n   7       5 loop5 0 0 0 0 0 0 0 0 0 0 0\n   7       6 loop6 0 0 0 0 0 0 0 0 0 0 0\n   7       7 loop7 0 0 0 0 0 0 0 0 0 0 0\n   8      16 sdb 931 1157 7601 960 2 0 16 0 0 919 960\n   8      17 sdb1 477 1147 3895 271 1 0 8 0 0 271 271\n   8      18 sdb2 395 0 3154 326 1 0 8 0 0 326 326\n   8       0 sda 931 1157 7601 1065 2 0 16 0 0 873 1065\n   8       1 sda1 477 1147 3895 419 1 0 8 0 0 419 419\n   8       2 sda2 395 0 3154 328 1 0 8 0 0 328 328\n   8      32 sdc 12390 470 457965 36363 72184 244851 9824537 5359169 0 607738 5437210\n   8      33 sdc1 10907 221 446193 34366 72173 244851 9824499 5359063 0 606972 5435214\n   8      34 sdc2 650 249 5120 901 7 0 22 93 0 956 994\n   8      35 sdc3 264 0 2106 380 1 0 8 0 0 380 380\n   8      36 sdc4 392 0 3130 476 1 0 8 0 0 475 475\n   8      48 sdd 3371 134 58909 18327 73997 243043 9824537 4532714 0 594248 4602162\n   8      49 sdd1 2498 134 51977 17192 73986 243043 9824499 4532600 0 593618 4600885\n   8      50 sdd2 40 0 280 223 7 0 22 108 0 330 330\n   8      51 sdd3 264 0 2106 328 1 0 8 0 0 328 328\n   8      52 sdd4 392 0 3130 373 1 0 8 1 0 374 374\n   8      64 sde 931 1157 7601 768 2 0 16 0 0 632 768\n   8      65 sde1 477 1147 3895 252 1 0 8 0 0 252 252\n   8      66 sde2 395 0 3154 281 1 0 8 0 0 281 281\n   8      80 sdf 931 1157 7601 936 2 0 16 0 0 717 936\n   8      81 sdf1 477 1147 3895 382 1 0 8 0 0 382 382\n   8      82 sdf2 395 0 3154 321 1 0 8 0 0 321 321\n   8      96 sdg 931 1157 7601 858 2 0 16 0 0 804 858\n   8      97 sdg1 477 1147 3895 244 1 0 8 0 0 244 244\n   8      98 sdg2 395 0 3154 299 1 0 8 0 0 299 299\n   8     112 sdh 931 1157 7601 895 2 0 16 0 0 841 895\n   8     113 sdh1 477 1147 3895 264 1 0 8 0 0 264 264\n   8     114 sdh2 395 0 3154 311 1 0 8 0 0 311 311\n 252       0 dm-0 1251094 0 108121362 21287644 111848 0 52908472 22236936 0 4838500 43524784\n 252       1 dm-1 58415638 0 2682446960 1719953592 20048040 0 543988240 1975572544 0 262085340 3695556828\n"
  },
  {
    "path": "fs/tmpfs/install/install.go",
    "content": "// Copyright 2014 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n//go:build linux\n\npackage install\n\nimport (\n\t\"github.com/google/cadvisor/fs\"\n\t\"github.com/google/cadvisor/fs/tmpfs\"\n\n\t\"k8s.io/klog/v2\"\n)\n\nfunc init() {\n\terr := fs.RegisterPlugin(\"tmpfs\", tmpfs.NewPlugin())\n\tif err != nil {\n\t\tklog.Fatalf(\"Failed to register tmpfs fs plugin: %v\", err)\n\t}\n}\n"
  },
  {
    "path": "fs/tmpfs/plugin.go",
    "content": "// Copyright 2014 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n//go:build linux\n\npackage tmpfs\n\nimport (\n\t\"github.com/google/cadvisor/fs\"\n\t\"github.com/google/cadvisor/fs/vfs\"\n\n\tmount \"github.com/moby/sys/mountinfo\"\n)\n\ntype tmpfsPlugin struct{}\n\n// NewPlugin creates a new tmpfs filesystem plugin.\nfunc NewPlugin() fs.FsPlugin {\n\treturn &tmpfsPlugin{}\n}\n\nfunc (p *tmpfsPlugin) Name() string {\n\treturn \"tmpfs\"\n}\n\n// CanHandle returns true if the filesystem type is tmpfs.\nfunc (p *tmpfsPlugin) CanHandle(fsType string) bool {\n\treturn fsType == \"tmpfs\"\n}\n\n// Priority returns 100 - tmpfs has higher priority than VFS.\nfunc (p *tmpfsPlugin) Priority() int {\n\treturn 100\n}\n\n// GetStats returns filesystem statistics for tmpfs.\n// tmpfs delegates to VFS for stats collection.\nfunc (p *tmpfsPlugin) GetStats(device string, partition fs.PartitionInfo) (*fs.FsStats, error) {\n\t// tmpfs uses VFS stats\n\tcapacity, free, avail, inodes, inodesFree, err := vfs.GetVfsStats(partition.Mountpoint)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn &fs.FsStats{\n\t\tCapacity:   capacity,\n\t\tFree:       free,\n\t\tAvailable:  avail,\n\t\tInodes:     &inodes,\n\t\tInodesFree: &inodesFree,\n\t\tType:       fs.VFS,\n\t}, nil\n}\n\n// ProcessMount handles tmpfs mount processing.\n// For tmpfs, we use the mountpoint as the source to make each mount unique.\n// This allows multiple tmpfs mounts with the same \"tmpfs\" source to coexist.\nfunc (p *tmpfsPlugin) ProcessMount(mnt *mount.Info) (bool, *mount.Info, error) {\n\t// Use mountpoint as source to make each tmpfs mount unique\n\tcorrectedMnt := *mnt\n\tcorrectedMnt.Source = mnt.Mountpoint\n\treturn true, &correctedMnt, nil\n}\n\n// AllowDuplicateSource returns true for tmpfs since multiple tmpfs mounts\n// should be tracked separately even if they appear to have the same source.\nfunc (p *tmpfsPlugin) AllowDuplicateSource() bool {\n\treturn true\n}\n"
  },
  {
    "path": "fs/types.go",
    "content": "// Copyright 2014 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage fs\n\nimport (\n\t\"errors\"\n)\n\ntype Context struct {\n\t// docker root directory.\n\tDocker DockerContext\n\tCrio   CrioContext\n\tPodman PodmanContext\n}\n\ntype DockerContext struct {\n\tRoot         string\n\tDriver       string\n\tDriverStatus map[string]string\n}\n\ntype PodmanContext struct {\n\tRoot         string\n\tDriver       string\n\tDriverStatus map[string]string\n}\n\ntype CrioContext struct {\n\tRoot       string\n\tImageStore string\n\tDriver     string\n}\n\ntype DeviceInfo struct {\n\tDevice string\n\tMajor  uint\n\tMinor  uint\n}\n\ntype FsType string\n\nfunc (ft FsType) String() string {\n\treturn string(ft)\n}\n\nconst (\n\tZFS          FsType = \"zfs\"\n\tDeviceMapper FsType = \"devicemapper\"\n\tVFS          FsType = \"vfs\"\n\tNFS          FsType = \"nfs\"\n)\n\ntype Fs struct {\n\tDeviceInfo\n\tType       FsType\n\tCapacity   uint64\n\tFree       uint64\n\tAvailable  uint64\n\tInodes     *uint64\n\tInodesFree *uint64\n\tDiskStats  DiskStats\n}\n\ntype DiskStats struct {\n\tMajorNum        uint64\n\tMinorNum        uint64\n\tReadsCompleted  uint64\n\tReadsMerged     uint64\n\tSectorsRead     uint64\n\tReadTime        uint64\n\tWritesCompleted uint64\n\tWritesMerged    uint64\n\tSectorsWritten  uint64\n\tWriteTime       uint64\n\tIoInProgress    uint64\n\tIoTime          uint64\n\tWeightedIoTime  uint64\n\tMajor           uint64\n\tMinor           uint64\n}\n\ntype UsageInfo struct {\n\tBytes  uint64\n\tInodes uint64\n}\n\nvar (\n\t// ErrNoSuchDevice is the error indicating the requested device does not exist.\n\tErrNoSuchDevice = errors.New(\"cadvisor: no such device\")\n\n\t// ErrDeviceNotInPartitionsMap is the error resulting if a device could not be found in the partitions map.\n\tErrDeviceNotInPartitionsMap = errors.New(\"could not find device in cached partitions map\")\n)\n\ntype FsInfo interface {\n\t// Returns capacity and free space, in bytes, of all the ext2, ext3, ext4 filesystems on the host.\n\tGetGlobalFsInfo() ([]Fs, error)\n\n\t// Returns capacity and free space, in bytes, of the set of mounts passed.\n\tGetFsInfoForPath(mountSet map[string]struct{}) ([]Fs, error)\n\n\t// GetDirUsage returns a usage information for 'dir'.\n\tGetDirUsage(dir string) (UsageInfo, error)\n\n\t// GetDeviceInfoByFsUUID returns the information of the device with the\n\t// specified filesystem uuid. If no such device exists, this function will\n\t// return the ErrNoSuchDevice error.\n\tGetDeviceInfoByFsUUID(uuid string) (*DeviceInfo, error)\n\n\t// Returns the block device info of the filesystem on which 'dir' resides.\n\tGetDirFsDevice(dir string) (*DeviceInfo, error)\n\n\t// Returns the device name associated with a particular label.\n\tGetDeviceForLabel(label string) (string, error)\n\n\t// Returns all labels associated with a particular device name.\n\tGetLabelsForDevice(device string) ([]string, error)\n\n\t// Returns the mountpoint associated with a particular device.\n\tGetMountpointForDevice(device string) (string, error)\n}\n"
  },
  {
    "path": "fs/vfs/install/install.go",
    "content": "// Copyright 2014 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n//go:build linux\n\npackage install\n\nimport (\n\t\"github.com/google/cadvisor/fs\"\n\t\"github.com/google/cadvisor/fs/vfs\"\n\n\t\"k8s.io/klog/v2\"\n)\n\nfunc init() {\n\terr := fs.RegisterPlugin(\"vfs\", vfs.NewPlugin())\n\tif err != nil {\n\t\tklog.Fatalf(\"Failed to register vfs fs plugin: %v\", err)\n\t}\n}\n"
  },
  {
    "path": "fs/vfs/plugin.go",
    "content": "// Copyright 2014 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n//go:build linux\n\npackage vfs\n\nimport (\n\t\"strings\"\n\n\t\"github.com/google/cadvisor/fs\"\n\t\"github.com/google/cadvisor/utils\"\n\n\tmount \"github.com/moby/sys/mountinfo\"\n\t\"k8s.io/klog/v2\"\n)\n\ntype vfsPlugin struct{}\n\n// NewPlugin creates a new VFS filesystem plugin.\nfunc NewPlugin() fs.FsPlugin {\n\treturn &vfsPlugin{}\n}\n\nfunc (p *vfsPlugin) Name() string {\n\treturn \"vfs\"\n}\n\n// CanHandle returns true for standard filesystems that use VFS stats.\n// This includes ext2/3/4, xfs, and similar block-based filesystems.\n// Virtual/pseudo filesystems (proc, sysfs, cgroup, etc.) are excluded.\nfunc (p *vfsPlugin) CanHandle(fsType string) bool {\n\t// Exclude virtual/pseudo filesystems that don't have real disk backing\n\tswitch fsType {\n\tcase \"cgroup\", \"cgroup2\", \"cpuset\", \"mqueue\", \"proc\", \"sysfs\",\n\t\t\"devtmpfs\", \"devpts\", \"securityfs\", \"debugfs\", \"tracefs\",\n\t\t\"pstore\", \"configfs\", \"fusectl\", \"hugetlbfs\", \"autofs\",\n\t\t\"binfmt_misc\", \"efivarfs\", \"rpc_pipefs\", \"nsfs\":\n\t\treturn false\n\t}\n\n\t// VFS can handle most standard Linux filesystems\n\tif strings.HasPrefix(fsType, \"ext\") {\n\t\treturn true\n\t}\n\tswitch fsType {\n\tcase \"xfs\", \"squashfs\", \"f2fs\", \"jfs\", \"reiserfs\", \"hfs\", \"hfsplus\",\n\t\t\"ntfs\", \"vfat\", \"fat\", \"msdos\", \"exfat\", \"udf\", \"iso9660\":\n\t\treturn true\n\t}\n\t// Don't act as a general fallback - only handle known filesystem types\n\treturn false\n}\n\n// Priority returns 0 - VFS is the lowest priority fallback plugin.\nfunc (p *vfsPlugin) Priority() int {\n\treturn 0\n}\n\n// GetStats returns filesystem statistics using the statfs syscall.\nfunc (p *vfsPlugin) GetStats(device string, partition fs.PartitionInfo) (*fs.FsStats, error) {\n\tif !utils.FileExists(partition.Mountpoint) {\n\t\tklog.V(4).Infof(\"VFS: mountpoint does not exist: %v\", partition.Mountpoint)\n\t\treturn nil, nil\n\t}\n\n\tcapacity, free, avail, inodes, inodesFree, err := GetVfsStats(partition.Mountpoint)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn &fs.FsStats{\n\t\tCapacity:   capacity,\n\t\tFree:       free,\n\t\tAvailable:  avail,\n\t\tInodes:     &inodes,\n\t\tInodesFree: &inodesFree,\n\t\tType:       fs.VFS,\n\t}, nil\n}\n\n// ProcessMount handles standard mount processing.\n// For VFS, no special processing is needed.\nfunc (p *vfsPlugin) ProcessMount(mnt *mount.Info) (bool, *mount.Info, error) {\n\treturn true, mnt, nil\n}\n"
  },
  {
    "path": "fs/vfs/stats.go",
    "content": "// Copyright 2014 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n//go:build linux\n\npackage vfs\n\nimport (\n\t\"context\"\n\t\"syscall\"\n\t\"time\"\n)\n\n// GetVfsStats returns filesystem statistics using the statfs syscall.\n// It has a timeout to prevent hanging on unresponsive filesystems.\nfunc GetVfsStats(path string) (total uint64, free uint64, avail uint64, inodes uint64, inodesFree uint64, err error) {\n\t// timeout the context with, default is 2sec\n\ttimeout := 2\n\tctx, cancel := context.WithTimeout(context.Background(), time.Duration(timeout)*time.Second)\n\tdefer cancel()\n\n\ttype result struct {\n\t\ttotal      uint64\n\t\tfree       uint64\n\t\tavail      uint64\n\t\tinodes     uint64\n\t\tinodesFree uint64\n\t\terr        error\n\t}\n\n\tresultChan := make(chan result, 1)\n\n\tgo func() {\n\t\tvar s syscall.Statfs_t\n\t\tif err = syscall.Statfs(path, &s); err != nil {\n\t\t\ttotal, free, avail, inodes, inodesFree = 0, 0, 0, 0, 0\n\t\t}\n\t\ttotal = uint64(s.Frsize) * s.Blocks\n\t\tfree = uint64(s.Frsize) * s.Bfree\n\t\tavail = uint64(s.Frsize) * s.Bavail\n\t\tinodes = uint64(s.Files)\n\t\tinodesFree = uint64(s.Ffree)\n\t\tresultChan <- result{total: total, free: free, avail: avail, inodes: inodes, inodesFree: inodesFree, err: err}\n\t}()\n\n\tselect {\n\tcase <-ctx.Done():\n\t\treturn 0, 0, 0, 0, 0, ctx.Err()\n\tcase res := <-resultChan:\n\t\treturn res.total, res.free, res.avail, res.inodes, res.inodesFree, res.err\n\t}\n}\n"
  },
  {
    "path": "fs/zfs/install/install.go",
    "content": "// Copyright 2014 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage install\n\nimport (\n\t\"github.com/google/cadvisor/fs\"\n\t\"github.com/google/cadvisor/fs/zfs\"\n\n\t\"k8s.io/klog/v2\"\n)\n\nfunc init() {\n\terr := fs.RegisterPlugin(\"zfs\", zfs.NewPlugin())\n\tif err != nil {\n\t\tklog.Fatalf(\"Failed to register zfs fs plugin: %v\", err)\n\t}\n}\n"
  },
  {
    "path": "fs/zfs/plugin.go",
    "content": "// Copyright 2014 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage zfs\n\nimport (\n\t\"os\"\n\n\t\"github.com/google/cadvisor/fs\"\n\n\tmount \"github.com/moby/sys/mountinfo\"\n)\n\ntype zfsPlugin struct{}\n\n// NewPlugin creates a new ZFS filesystem plugin.\nfunc NewPlugin() fs.FsPlugin {\n\treturn &zfsPlugin{}\n}\n\nfunc (p *zfsPlugin) Name() string {\n\treturn \"zfs\"\n}\n\n// CanHandle returns true if the filesystem type is zfs.\nfunc (p *zfsPlugin) CanHandle(fsType string) bool {\n\treturn fsType == \"zfs\"\n}\n\n// Priority returns 100 - ZFS has higher priority than VFS.\nfunc (p *zfsPlugin) Priority() int {\n\treturn 100\n}\n\n// GetStats returns filesystem statistics for ZFS.\nfunc (p *zfsPlugin) GetStats(device string, partition fs.PartitionInfo) (*fs.FsStats, error) {\n\t// Check if ZFS is available - if /dev/zfs doesn't exist, fall back to VFS\n\tif _, err := os.Stat(\"/dev/zfs\"); os.IsNotExist(err) {\n\t\treturn nil, fs.ErrFallbackToVFS\n\t}\n\n\tcapacity, free, avail, err := GetZfsStats(device)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn &fs.FsStats{\n\t\tCapacity:  capacity,\n\t\tFree:      free,\n\t\tAvailable: avail,\n\t\tType:      fs.ZFS,\n\t}, nil\n}\n\n// ProcessMount handles ZFS mount processing.\n// For ZFS, no special processing is needed.\nfunc (p *zfsPlugin) ProcessMount(mnt *mount.Info) (bool, *mount.Info, error) {\n\treturn true, mnt, nil\n}\n"
  },
  {
    "path": "fs/zfs/stats.go",
    "content": "// Copyright 2014 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage zfs\n\nimport (\n\tzfslib \"github.com/mistifyio/go-zfs\"\n)\n\n// GetZfsStats returns ZFS mount stats using zfsutils.\nfunc GetZfsStats(poolName string) (uint64, uint64, uint64, error) {\n\tdataset, err := zfslib.GetDataset(poolName)\n\tif err != nil {\n\t\treturn 0, 0, 0, err\n\t}\n\n\ttotal := dataset.Used + dataset.Avail + dataset.Usedbydataset\n\n\treturn total, dataset.Avail, dataset.Avail, nil\n}\n"
  },
  {
    "path": "fs/zfs/watcher.go",
    "content": "// Copyright 2016 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage zfs\n\nimport (\n\t\"fmt\"\n\t\"sync/atomic\"\n\t\"time\"\n\n\tzfslib \"github.com/mistifyio/go-zfs\"\n\t\"k8s.io/klog/v2\"\n)\n\n// usageCache is a typed wrapper around atomic.Value that eliminates the need\n// for type assertions at every call site. It stores filesystem name strings\n// mapped to usage values (uint64).\ntype usageCache struct {\n\tv atomic.Value\n}\n\n// Load retrieves the current cache map.\nfunc (c *usageCache) Load() map[string]uint64 {\n\treturn c.v.Load().(map[string]uint64)\n}\n\n// Store saves a new cache map.\nfunc (c *usageCache) Store(m map[string]uint64) {\n\tc.v.Store(m)\n}\n\n// ZfsWatcher maintains a cache of filesystem -> usage stats for a\n// zfs filesystem\ntype ZfsWatcher struct {\n\tfilesystem string\n\tcache      usageCache\n\tperiod     time.Duration\n\tstopChan   chan struct{}\n}\n\n// NewZfsWatcher returns a new ZfsWatcher for the given zfs filesystem.\nfunc NewZfsWatcher(filesystem string) (*ZfsWatcher, error) {\n\tw := &ZfsWatcher{\n\t\tfilesystem: filesystem,\n\t\tperiod:     15 * time.Second,\n\t\tstopChan:   make(chan struct{}),\n\t}\n\tw.cache.Store(map[string]uint64{})\n\treturn w, nil\n}\n\n// Start starts the ZfsWatcher.\nfunc (w *ZfsWatcher) Start() {\n\terr := w.Refresh()\n\tif err != nil {\n\t\tklog.Errorf(\"encountered error refreshing zfs watcher: %v\", err)\n\t}\n\n\tfor {\n\t\tselect {\n\t\tcase <-w.stopChan:\n\t\t\treturn\n\t\tcase <-time.After(w.period):\n\t\t\tstart := time.Now()\n\t\t\terr = w.Refresh()\n\t\t\tif err != nil {\n\t\t\t\tklog.Errorf(\"encountered error refreshing zfs watcher: %v\", err)\n\t\t\t}\n\n\t\t\t// print latency for refresh\n\t\t\tduration := time.Since(start)\n\t\t\tklog.V(5).Infof(\"zfs(%d) took %s\", start.Unix(), duration)\n\t\t}\n\t}\n}\n\n// Stop stops the ZfsWatcher.\nfunc (w *ZfsWatcher) Stop() {\n\tclose(w.stopChan)\n}\n\n// GetUsage gets the cached usage value of the given filesystem.\nfunc (w *ZfsWatcher) GetUsage(filesystem string) (uint64, error) {\n\tcache := w.cache.Load()\n\tv, ok := cache[filesystem]\n\tif !ok {\n\t\treturn 0, fmt.Errorf(\"no cached value for usage of filesystem %v\", filesystem)\n\t}\n\treturn v, nil\n}\n\n// Refresh performs a zfs get\nfunc (w *ZfsWatcher) Refresh() error {\n\tparent, err := zfslib.GetDataset(w.filesystem)\n\tif err != nil {\n\t\tklog.Errorf(\"encountered error getting zfs filesystem: %s: %v\", w.filesystem, err)\n\t\treturn err\n\t}\n\tchildren, err := parent.Children(0)\n\tif err != nil {\n\t\tklog.Errorf(\"encountered error getting children of zfs filesystem: %s: %v\", w.filesystem, err)\n\t\treturn err\n\t}\n\n\tnewCache := make(map[string]uint64)\n\tfor _, ds := range children {\n\t\tnewCache[ds.Name] = ds.Used\n\t}\n\n\tw.cache.Store(newCache)\n\treturn nil\n}\n"
  },
  {
    "path": "go.mod",
    "content": "module github.com/google/cadvisor\n\ngo 1.24.0\n\nrequire (\n\tcloud.google.com/go/compute/metadata v0.7.0\n\tgithub.com/Microsoft/go-winio v0.6.2\n\tgithub.com/aws/aws-sdk-go-v2/config v1.29.14\n\tgithub.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.30\n\tgithub.com/blang/semver/v4 v4.0.0\n\tgithub.com/containerd/containerd/api v1.10.0\n\tgithub.com/containerd/errdefs v1.0.0\n\tgithub.com/containerd/errdefs/pkg v0.3.0\n\tgithub.com/containerd/ttrpc v1.2.7\n\tgithub.com/containerd/typeurl/v2 v2.2.3\n\tgithub.com/docker/go-connections v0.6.0\n\tgithub.com/docker/go-units v0.5.0\n\tgithub.com/euank/go-kmsg-parser v2.0.0+incompatible\n\tgithub.com/mistifyio/go-zfs v2.1.1+incompatible\n\tgithub.com/moby/moby/api v1.52.0\n\tgithub.com/moby/moby/client v0.2.1\n\tgithub.com/moby/sys/mountinfo v0.7.2\n\tgithub.com/opencontainers/cgroups v0.0.6\n\tgithub.com/opencontainers/runc v1.4.0\n\tgithub.com/opencontainers/runtime-spec v1.3.0\n\tgithub.com/prometheus/client_golang v1.22.0\n\tgithub.com/prometheus/client_model v0.6.2\n\tgithub.com/prometheus/common v0.64.0\n\tgithub.com/stretchr/testify v1.11.1\n\tgolang.org/x/sys v0.37.0\n\tgoogle.golang.org/grpc v1.72.2\n\tgoogle.golang.org/protobuf v1.36.8\n\tk8s.io/klog/v2 v2.130.1\n\tk8s.io/utils v0.0.0-20250502105355-0f33e8f1c979\n)\n\nrequire (\n\tgithub.com/aws/aws-sdk-go-v2 v1.36.3 // indirect\n\tgithub.com/aws/aws-sdk-go-v2/credentials v1.17.67 // indirect\n\tgithub.com/aws/aws-sdk-go-v2/internal/configsources v1.3.34 // indirect\n\tgithub.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.34 // indirect\n\tgithub.com/aws/aws-sdk-go-v2/internal/ini v1.8.3 // indirect\n\tgithub.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.3 // indirect\n\tgithub.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.15 // indirect\n\tgithub.com/aws/aws-sdk-go-v2/service/sso v1.25.3 // indirect\n\tgithub.com/aws/aws-sdk-go-v2/service/ssooidc v1.30.1 // indirect\n\tgithub.com/aws/aws-sdk-go-v2/service/sts v1.33.19 // indirect\n\tgithub.com/aws/smithy-go v1.22.3 // indirect\n\tgithub.com/beorn7/perks v1.0.1 // indirect\n\tgithub.com/cespare/xxhash/v2 v2.3.0 // indirect\n\tgithub.com/containerd/log v0.1.0 // indirect\n\tgithub.com/coreos/go-systemd/v22 v22.6.0 // indirect\n\tgithub.com/cyphar/filepath-securejoin v0.6.1 // indirect\n\tgithub.com/davecgh/go-spew v1.1.1 // indirect\n\tgithub.com/distribution/reference v0.6.0 // indirect\n\tgithub.com/felixge/httpsnoop v1.0.4 // indirect\n\tgithub.com/go-logr/logr v1.4.3 // indirect\n\tgithub.com/go-logr/stdr v1.2.2 // indirect\n\tgithub.com/godbus/dbus/v5 v5.1.0 // indirect\n\tgithub.com/gogo/protobuf v1.3.2 // indirect\n\tgithub.com/kylelemons/godebug v1.1.0 // indirect\n\tgithub.com/moby/docker-image-spec v1.3.1 // indirect\n\tgithub.com/moby/sys/userns v0.1.0 // indirect\n\tgithub.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect\n\tgithub.com/opencontainers/go-digest v1.0.0 // indirect\n\tgithub.com/opencontainers/image-spec v1.1.1 // indirect\n\tgithub.com/pmezard/go-difflib v1.0.0 // indirect\n\tgithub.com/prometheus/procfs v0.16.1 // indirect\n\tgithub.com/sirupsen/logrus v1.9.3 // indirect\n\tgithub.com/stretchr/objx v0.5.2 // indirect\n\tgo.opentelemetry.io/auto/sdk v1.1.0 // indirect\n\tgo.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 // indirect\n\tgo.opentelemetry.io/otel v1.36.0 // indirect\n\tgo.opentelemetry.io/otel/metric v1.36.0 // indirect\n\tgo.opentelemetry.io/otel/trace v1.36.0 // indirect\n\tgolang.org/x/net v0.43.0 // indirect\n\tgolang.org/x/text v0.28.0 // indirect\n\tgoogle.golang.org/genproto/googleapis/rpc v0.0.0-20250528174236-200df99c418a // indirect\n\tgopkg.in/yaml.v3 v3.0.1 // indirect\n)\n"
  },
  {
    "path": "go.sum",
    "content": "cloud.google.com/go/compute/metadata v0.7.0 h1:PBWF+iiAerVNe8UCHxdOt6eHLVc3ydFeOCw78U8ytSU=\ncloud.google.com/go/compute/metadata v0.7.0/go.mod h1:j5MvL9PprKL39t166CoB1uVHfQMs4tFQZZcKwksXUjo=\ngithub.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY=\ngithub.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU=\ngithub.com/aws/aws-sdk-go-v2 v1.36.3 h1:mJoei2CxPutQVxaATCzDUjcZEjVRdpsiiXi2o38yqWM=\ngithub.com/aws/aws-sdk-go-v2 v1.36.3/go.mod h1:LLXuLpgzEbD766Z5ECcRmi8AzSwfZItDtmABVkRLGzg=\ngithub.com/aws/aws-sdk-go-v2/config v1.29.14 h1:f+eEi/2cKCg9pqKBoAIwRGzVb70MRKqWX4dg1BDcSJM=\ngithub.com/aws/aws-sdk-go-v2/config v1.29.14/go.mod h1:wVPHWcIFv3WO89w0rE10gzf17ZYy+UVS1Geq8Iei34g=\ngithub.com/aws/aws-sdk-go-v2/credentials v1.17.67 h1:9KxtdcIA/5xPNQyZRgUSpYOE6j9Bc4+D7nZua0KGYOM=\ngithub.com/aws/aws-sdk-go-v2/credentials v1.17.67/go.mod h1:p3C44m+cfnbv763s52gCqrjaqyPikj9Sg47kUVaNZQQ=\ngithub.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.30 h1:x793wxmUWVDhshP8WW2mlnXuFrO4cOd3HLBroh1paFw=\ngithub.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.30/go.mod h1:Jpne2tDnYiFascUEs2AWHJL9Yp7A5ZVy3TNyxaAjD6M=\ngithub.com/aws/aws-sdk-go-v2/internal/configsources v1.3.34 h1:ZK5jHhnrioRkUNOc+hOgQKlUL5JeC3S6JgLxtQ+Rm0Q=\ngithub.com/aws/aws-sdk-go-v2/internal/configsources v1.3.34/go.mod h1:p4VfIceZokChbA9FzMbRGz5OV+lekcVtHlPKEO0gSZY=\ngithub.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.34 h1:SZwFm17ZUNNg5Np0ioo/gq8Mn6u9w19Mri8DnJ15Jf0=\ngithub.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.34/go.mod h1:dFZsC0BLo346mvKQLWmoJxT+Sjp+qcVR1tRVHQGOH9Q=\ngithub.com/aws/aws-sdk-go-v2/internal/ini v1.8.3 h1:bIqFDwgGXXN1Kpp99pDOdKMTTb5d2KyU5X/BZxjOkRo=\ngithub.com/aws/aws-sdk-go-v2/internal/ini v1.8.3/go.mod h1:H5O/EsxDWyU+LP/V8i5sm8cxoZgc2fdNR9bxlOFrQTo=\ngithub.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.3 h1:eAh2A4b5IzM/lum78bZ590jy36+d/aFLgKF/4Vd1xPE=\ngithub.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.3/go.mod h1:0yKJC/kb8sAnmlYa6Zs3QVYqaC8ug2AbnNChv5Ox3uA=\ngithub.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.15 h1:dM9/92u2F1JbDaGooxTq18wmmFzbJRfXfVfy96/1CXM=\ngithub.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.15/go.mod h1:SwFBy2vjtA0vZbjjaFtfN045boopadnoVPhu4Fv66vY=\ngithub.com/aws/aws-sdk-go-v2/service/sso v1.25.3 h1:1Gw+9ajCV1jogloEv1RRnvfRFia2cL6c9cuKV2Ps+G8=\ngithub.com/aws/aws-sdk-go-v2/service/sso v1.25.3/go.mod h1:qs4a9T5EMLl/Cajiw2TcbNt2UNo/Hqlyp+GiuG4CFDI=\ngithub.com/aws/aws-sdk-go-v2/service/ssooidc v1.30.1 h1:hXmVKytPfTy5axZ+fYbR5d0cFmC3JvwLm5kM83luako=\ngithub.com/aws/aws-sdk-go-v2/service/ssooidc v1.30.1/go.mod h1:MlYRNmYu/fGPoxBQVvBYr9nyr948aY/WLUvwBMBJubs=\ngithub.com/aws/aws-sdk-go-v2/service/sts v1.33.19 h1:1XuUZ8mYJw9B6lzAkXhqHlJd/XvaX32evhproijJEZY=\ngithub.com/aws/aws-sdk-go-v2/service/sts v1.33.19/go.mod h1:cQnB8CUnxbMU82JvlqjKR2HBOm3fe9pWorWBza6MBJ4=\ngithub.com/aws/smithy-go v1.22.3 h1:Z//5NuZCSW6R4PhQ93hShNbyBbn8BWCmCVCt+Q8Io5k=\ngithub.com/aws/smithy-go v1.22.3/go.mod h1:t1ufH5HMublsJYulve2RKmHDC15xu1f26kHCp/HgceI=\ngithub.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=\ngithub.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=\ngithub.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM=\ngithub.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ=\ngithub.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=\ngithub.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=\ngithub.com/containerd/containerd/api v1.10.0 h1:5n0oHYVBwN4VhoX9fFykCV9dF1/BvAXeg2F8W6UYq1o=\ngithub.com/containerd/containerd/api v1.10.0/go.mod h1:NBm1OAk8ZL+LG8R0ceObGxT5hbUYj7CzTmR3xh0DlMM=\ngithub.com/containerd/errdefs v1.0.0 h1:tg5yIfIlQIrxYtu9ajqY42W3lpS19XqdxRQeEwYG8PI=\ngithub.com/containerd/errdefs v1.0.0/go.mod h1:+YBYIdtsnF4Iw6nWZhJcqGSg/dwvV7tyJ/kCkyJ2k+M=\ngithub.com/containerd/errdefs/pkg v0.3.0 h1:9IKJ06FvyNlexW690DXuQNx2KA2cUJXx151Xdx3ZPPE=\ngithub.com/containerd/errdefs/pkg v0.3.0/go.mod h1:NJw6s9HwNuRhnjJhM7pylWwMyAkmCQvQ4GpJHEqRLVk=\ngithub.com/containerd/log v0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I=\ngithub.com/containerd/log v0.1.0/go.mod h1:VRRf09a7mHDIRezVKTRCrOq78v577GXq3bSa3EhrzVo=\ngithub.com/containerd/ttrpc v1.2.7 h1:qIrroQvuOL9HQ1X6KHe2ohc7p+HP/0VE6XPU7elJRqQ=\ngithub.com/containerd/ttrpc v1.2.7/go.mod h1:YCXHsb32f+Sq5/72xHubdiJRQY9inL4a4ZQrAbN1q9o=\ngithub.com/containerd/typeurl/v2 v2.2.3 h1:yNA/94zxWdvYACdYO8zofhrTVuQY73fFU1y++dYSw40=\ngithub.com/containerd/typeurl/v2 v2.2.3/go.mod h1:95ljDnPfD3bAbDJRugOiShd/DlAAsxGtUBhJxIn7SCk=\ngithub.com/coreos/go-systemd/v22 v22.6.0 h1:aGVa/v8B7hpb0TKl0MWoAavPDmHvobFe5R5zn0bCJWo=\ngithub.com/coreos/go-systemd/v22 v22.6.0/go.mod h1:iG+pp635Fo7ZmV/j14KUcmEyWF+0X7Lua8rrTWzYgWU=\ngithub.com/cyphar/filepath-securejoin v0.6.1 h1:5CeZ1jPXEiYt3+Z6zqprSAgSWiggmpVyciv8syjIpVE=\ngithub.com/cyphar/filepath-securejoin v0.6.1/go.mod h1:A8hd4EnAeyujCJRrICiOWqjS1AX0a9kM5XL+NwKoYSc=\ngithub.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=\ngithub.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=\ngithub.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=\ngithub.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk=\ngithub.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E=\ngithub.com/docker/go-connections v0.6.0 h1:LlMG9azAe1TqfR7sO+NJttz1gy6KO7VJBh+pMmjSD94=\ngithub.com/docker/go-connections v0.6.0/go.mod h1:AahvXYshr6JgfUJGdDCs2b5EZG/vmaMAntpSFH5BFKE=\ngithub.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4=\ngithub.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=\ngithub.com/euank/go-kmsg-parser v2.0.0+incompatible h1:cHD53+PLQuuQyLZeriD1V/esuG4MuU0Pjs5y6iknohY=\ngithub.com/euank/go-kmsg-parser v2.0.0+incompatible/go.mod h1:MhmAMZ8V4CYH4ybgdRwPr2TU5ThnS43puaKEMpja1uw=\ngithub.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg=\ngithub.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=\ngithub.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=\ngithub.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI=\ngithub.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=\ngithub.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=\ngithub.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=\ngithub.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk=\ngithub.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=\ngithub.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=\ngithub.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=\ngithub.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=\ngithub.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=\ngithub.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=\ngithub.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=\ngithub.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=\ngithub.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=\ngithub.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=\ngithub.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=\ngithub.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=\ngithub.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=\ngithub.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=\ngithub.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=\ngithub.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=\ngithub.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=\ngithub.com/mistifyio/go-zfs v2.1.1+incompatible h1:gAMO1HM9xBRONLHHYnu5iFsOJUiJdNZo6oqSENd4eW8=\ngithub.com/mistifyio/go-zfs v2.1.1+incompatible/go.mod h1:8AuVvqP/mXw1px98n46wfvcGfQ4ci2FwoAjKYxuo3Z4=\ngithub.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3Nl2EsFP0=\ngithub.com/moby/docker-image-spec v1.3.1/go.mod h1:eKmb5VW8vQEh/BAr2yvVNvuiJuY6UIocYsFu/DxxRpo=\ngithub.com/moby/moby/api v1.52.0 h1:00BtlJY4MXkkt84WhUZPRqt5TvPbgig2FZvTbe3igYg=\ngithub.com/moby/moby/api v1.52.0/go.mod h1:8mb+ReTlisw4pS6BRzCMts5M49W5M7bKt1cJy/YbAqc=\ngithub.com/moby/moby/client v0.2.1 h1:1Grh1552mvv6i+sYOdY+xKKVTvzJegcVMhuXocyDz/k=\ngithub.com/moby/moby/client v0.2.1/go.mod h1:O+/tw5d4a1Ha/ZA/tPxIZJapJRUS6LNZ1wiVRxYHyUE=\ngithub.com/moby/sys/mountinfo v0.7.2 h1:1shs6aH5s4o5H2zQLn796ADW1wMrIwHsyJ2v9KouLrg=\ngithub.com/moby/sys/mountinfo v0.7.2/go.mod h1:1YOa8w8Ih7uW0wALDUgT1dTTSBrZ+HiBLGws92L2RU4=\ngithub.com/moby/sys/userns v0.1.0 h1:tVLXkFOxVu9A64/yh59slHVv9ahO9UIev4JZusOLG/g=\ngithub.com/moby/sys/userns v0.1.0/go.mod h1:IHUYgu/kao6N8YZlp9Cf444ySSvCmDlmzUcYfDHOl28=\ngithub.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=\ngithub.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=\ngithub.com/opencontainers/cgroups v0.0.6 h1:tfZFWTIIGaUUFImTyuTg+Mr5x8XRiSdZESgEBW7UxuI=\ngithub.com/opencontainers/cgroups v0.0.6/go.mod h1:oWVzJsKK0gG9SCRBfTpnn16WcGEqDI8PAcpMGbqWxcs=\ngithub.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=\ngithub.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=\ngithub.com/opencontainers/image-spec v1.1.1 h1:y0fUlFfIZhPF1W537XOLg0/fcx6zcHCJwooC2xJA040=\ngithub.com/opencontainers/image-spec v1.1.1/go.mod h1:qpqAh3Dmcf36wStyyWU+kCeDgrGnAve2nCC8+7h8Q0M=\ngithub.com/opencontainers/runc v1.4.0 h1:FG1Hw0GBYPsNki+mBz1QOrSzbwbAcerhrAD2r097QCc=\ngithub.com/opencontainers/runc v1.4.0/go.mod h1:sch3Bh3c1NlyAkALoAUz5Br9ubMLZzFcxuovZbnkErk=\ngithub.com/opencontainers/runtime-spec v1.3.0 h1:YZupQUdctfhpZy3TM39nN9Ika5CBWT5diQ8ibYCRkxg=\ngithub.com/opencontainers/runtime-spec v1.3.0/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=\ngithub.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=\ngithub.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=\ngithub.com/prometheus/client_golang v1.22.0 h1:rb93p9lokFEsctTys46VnV1kLCDpVZ0a/Y92Vm0Zc6Q=\ngithub.com/prometheus/client_golang v1.22.0/go.mod h1:R7ljNsLXhuQXYZYtw6GAE9AZg8Y7vEW5scdCXrWRXC0=\ngithub.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNwqPLxwZyk=\ngithub.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE=\ngithub.com/prometheus/common v0.64.0 h1:pdZeA+g617P7oGv1CzdTzyeShxAGrTBsolKNOLQPGO4=\ngithub.com/prometheus/common v0.64.0/go.mod h1:0gZns+BLRQ3V6NdaerOhMbwwRbNh9hkGINtQAsP5GS8=\ngithub.com/prometheus/procfs v0.16.1 h1:hZ15bTNuirocR6u0JZ6BAHHmwS1p8B4P6MRqxtzMyRg=\ngithub.com/prometheus/procfs v0.16.1/go.mod h1:teAbpZRB1iIAJYREa1LsoWUXykVXA1KlTmWl8x/U+Is=\ngithub.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII=\ngithub.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o=\ngithub.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=\ngithub.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=\ngithub.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=\ngithub.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY=\ngithub.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=\ngithub.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=\ngithub.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=\ngithub.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=\ngithub.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=\ngithub.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=\ngo.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA=\ngo.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A=\ngo.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 h1:F7Jx+6hwnZ41NSFTO5q4LYDtJRXBf2PD0rNBkeB/lus=\ngo.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0/go.mod h1:UHB22Z8QsdRDrnAtX4PntOl36ajSxcdUMt1sF7Y6E7Q=\ngo.opentelemetry.io/otel v1.36.0 h1:UumtzIklRBY6cI/lllNZlALOF5nNIzJVb16APdvgTXg=\ngo.opentelemetry.io/otel v1.36.0/go.mod h1:/TcFMXYjyRNh8khOAO9ybYkqaDBb/70aVwkNML4pP8E=\ngo.opentelemetry.io/otel/metric v1.36.0 h1:MoWPKVhQvJ+eeXWHFBOPoBOi20jh6Iq2CcCREuTYufE=\ngo.opentelemetry.io/otel/metric v1.36.0/go.mod h1:zC7Ks+yeyJt4xig9DEw9kuUFe5C3zLbVjV2PzT6qzbs=\ngo.opentelemetry.io/otel/sdk v1.36.0 h1:b6SYIuLRs88ztox4EyrvRti80uXIFy+Sqzoh9kFULbs=\ngo.opentelemetry.io/otel/sdk v1.36.0/go.mod h1:+lC+mTgD+MUWfjJubi2vvXWcVxyr9rmlshZni72pXeY=\ngo.opentelemetry.io/otel/sdk/metric v1.36.0 h1:r0ntwwGosWGaa0CrSt8cuNuTcccMXERFwHX4dThiPis=\ngo.opentelemetry.io/otel/sdk/metric v1.36.0/go.mod h1:qTNOhFDfKRwX0yXOqJYegL5WRaW376QbB7P4Pb0qva4=\ngo.opentelemetry.io/otel/trace v1.36.0 h1:ahxWNuqZjpdiFAyrIoQ4GIiAIhxAunQR6MUoKrsNd4w=\ngo.opentelemetry.io/otel/trace v1.36.0/go.mod h1:gQ+OnDZzrybY4k4seLzPAWNwVBBVlF2szhehOBB/tGA=\ngolang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=\ngolang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=\ngolang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=\ngolang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=\ngolang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=\ngolang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=\ngolang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=\ngolang.org/x/net v0.43.0 h1:lat02VYK2j4aLzMzecihNvTlJNQUq316m2Mr9rnM6YE=\ngolang.org/x/net v0.43.0/go.mod h1:vhO1fvI4dGsIjh73sWfUVjj3N7CA9WkKJNQm2svM6Jg=\ngolang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=\ngolang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.37.0 h1:fdNQudmxPjkdUTPnLn5mdQv7Zwvbvpaxqs831goi9kQ=\ngolang.org/x/sys v0.37.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=\ngolang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=\ngolang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=\ngolang.org/x/text v0.28.0 h1:rhazDwis8INMIwQ4tpjLDzUhx6RlXqZNPEM0huQojng=\ngolang.org/x/text v0.28.0/go.mod h1:U8nCwOR8jO/marOQ0QbDiOngZVEBB7MAiitBuMjXiNU=\ngolang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=\ngolang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=\ngolang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=\ngolang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=\ngolang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=\ngolang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=\ngolang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=\ngolang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=\ngoogle.golang.org/genproto/googleapis/rpc v0.0.0-20250528174236-200df99c418a h1:v2PbRU4K3llS09c7zodFpNePeamkAwG3mPrAery9VeE=\ngoogle.golang.org/genproto/googleapis/rpc v0.0.0-20250528174236-200df99c418a/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A=\ngoogle.golang.org/grpc v1.72.2 h1:TdbGzwb82ty4OusHWepvFWGLgIbNo1/SUynEN0ssqv8=\ngoogle.golang.org/grpc v1.72.2/go.mod h1:wH5Aktxcg25y1I3w7H69nHfXdOG3UiadoBtjh3izSDM=\ngoogle.golang.org/protobuf v1.36.8 h1:xHScyCOEuuwZEc6UtSOvPbAT4zRh0xcNRYekJwfqyMc=\ngoogle.golang.org/protobuf v1.36.8/go.mod h1:fuxRtAxBytpl4zzqUh6/eyUujkJdNiuEkXntxiD/uRU=\ngopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=\ngopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=\ngopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=\ngopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=\ngopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=\ngopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=\ngotest.tools/v3 v3.5.2 h1:7koQfIKdy+I8UTetycgUqXWSDwpgv193Ka+qRsmBY8Q=\ngotest.tools/v3 v3.5.2/go.mod h1:LtdLGcnqToBH83WByAAi/wiwSFCArdFIUV/xxN4pcjA=\nk8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk=\nk8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE=\nk8s.io/utils v0.0.0-20250502105355-0f33e8f1c979 h1:jgJW5IePPXLGB8e/1wvd0Ich9QE97RvvF3a8J3fP/Lg=\nk8s.io/utils v0.0.0-20250502105355-0f33e8f1c979/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=\npgregory.net/rapid v1.2.0 h1:keKAYRcjm+e1F0oAuU5F5+YPAWcyxNNRK2wud503Gnk=\npgregory.net/rapid v1.2.0/go.mod h1:PY5XlDGj0+V1FCq0o192FdRhpKHGTRIWBgqjDBTrq04=\n"
  },
  {
    "path": "info/v1/container.go",
    "content": "// Copyright 2014 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage v1\n\nimport (\n\t\"reflect\"\n\t\"time\"\n)\n\ntype CpuSpec struct {\n\tLimit    uint64 `json:\"limit\"`\n\tMaxLimit uint64 `json:\"max_limit\"`\n\tMask     string `json:\"mask,omitempty\"`\n\tQuota    uint64 `json:\"quota,omitempty\"`\n\tPeriod   uint64 `json:\"period,omitempty\"`\n}\n\ntype MemorySpec struct {\n\t// The amount of memory requested. Default is unlimited (-1).\n\t// Units: bytes.\n\tLimit uint64 `json:\"limit,omitempty\"`\n\n\t// The amount of guaranteed memory.  Default is 0.\n\t// Units: bytes.\n\tReservation uint64 `json:\"reservation,omitempty\"`\n\n\t// The amount of swap space requested. Default is unlimited (-1).\n\t// Units: bytes.\n\tSwapLimit uint64 `json:\"swap_limit,omitempty\"`\n}\n\ntype ProcessSpec struct {\n\tLimit uint64 `json:\"limit,omitempty\"`\n}\n\ntype ContainerSpec struct {\n\t// Time at which the container was created.\n\tCreationTime time.Time `json:\"creation_time,omitempty\"`\n\n\t// Time at which the container was started.\n\t// This may be unset if the runtime does not provide it.\n\tStartTime time.Time `json:\"start_time,omitempty\"`\n\n\t// Metadata labels associated with this container.\n\tLabels map[string]string `json:\"labels,omitempty\"`\n\t// Metadata envs associated with this container. Only whitelisted envs are added.\n\tEnvs map[string]string `json:\"envs,omitempty\"`\n\n\tHasCpu bool    `json:\"has_cpu\"`\n\tCpu    CpuSpec `json:\"cpu,omitempty\"`\n\n\tHasMemory bool       `json:\"has_memory\"`\n\tMemory    MemorySpec `json:\"memory,omitempty\"`\n\n\tHasHugetlb bool `json:\"has_hugetlb\"`\n\n\tHasNetwork bool `json:\"has_network\"`\n\n\tHasProcesses bool        `json:\"has_processes\"`\n\tProcesses    ProcessSpec `json:\"processes,omitempty\"`\n\n\tHasFilesystem bool `json:\"has_filesystem\"`\n\n\t// HasDiskIo when true, indicates that DiskIo stats will be available.\n\tHasDiskIo bool `json:\"has_diskio\"`\n\n\tHasCustomMetrics bool         `json:\"has_custom_metrics\"`\n\tCustomMetrics    []MetricSpec `json:\"custom_metrics,omitempty\"`\n\n\t// Image name used for this container.\n\tImage string `json:\"image,omitempty\"`\n}\n\n// Container reference contains enough information to uniquely identify a container\ntype ContainerReference struct {\n\t// The container id\n\tId string `json:\"id,omitempty\"`\n\n\t// The absolute name of the container. This is unique on the machine.\n\tName string `json:\"name\"`\n\n\t// Other names by which the container is known within a certain namespace.\n\t// This is unique within that namespace.\n\tAliases []string `json:\"aliases,omitempty\"`\n\n\t// Namespace under which the aliases of a container are unique.\n\t// An example of a namespace is \"docker\" for Docker containers.\n\tNamespace string `json:\"namespace,omitempty\"`\n}\n\n// Sorts by container name.\ntype ContainerReferenceSlice []ContainerReference\n\nfunc (s ContainerReferenceSlice) Len() int           { return len(s) }\nfunc (s ContainerReferenceSlice) Swap(i, j int)      { s[i], s[j] = s[j], s[i] }\nfunc (s ContainerReferenceSlice) Less(i, j int) bool { return s[i].Name < s[j].Name }\n\n// ContainerInfoRequest is used when users check a container info from the REST API.\n// It specifies how much data users want to get about a container\ntype ContainerInfoRequest struct {\n\t// Max number of stats to return. Specify -1 for all stats currently available.\n\t// Default: 60\n\tNumStats int `json:\"num_stats,omitempty\"`\n\n\t// Start time for which to query information.\n\t// If omitted, the beginning of time is assumed.\n\tStart time.Time `json:\"start,omitempty\"`\n\n\t// End time for which to query information.\n\t// If omitted, current time is assumed.\n\tEnd time.Time `json:\"end,omitempty\"`\n}\n\n// Returns a ContainerInfoRequest with all default values specified.\nfunc DefaultContainerInfoRequest() ContainerInfoRequest {\n\treturn ContainerInfoRequest{\n\t\tNumStats: 60,\n\t}\n}\n\nfunc (r *ContainerInfoRequest) Equals(other ContainerInfoRequest) bool {\n\treturn r.NumStats == other.NumStats &&\n\t\tr.Start.Equal(other.Start) &&\n\t\tr.End.Equal(other.End)\n}\n\ntype ContainerInfo struct {\n\tContainerReference\n\n\t// The direct subcontainers of the current container.\n\tSubcontainers []ContainerReference `json:\"subcontainers,omitempty\"`\n\n\t// The isolation used in the container.\n\tSpec ContainerSpec `json:\"spec,omitempty\"`\n\n\t// Historical statistics gathered from the container.\n\tStats []*ContainerStats `json:\"stats,omitempty\"`\n}\n\n// TODO(vmarmol): Refactor to not need this equality comparison.\n// ContainerInfo may be (un)marshaled by json or other en/decoder. In that\n// case, the Timestamp field in each stats/sample may not be precisely\n// en/decoded.  This will lead to small but acceptable differences between a\n// ContainerInfo and its encode-then-decode version.  Eq() is used to compare\n// two ContainerInfo accepting small difference (<10ms) of Time fields.\nfunc (ci *ContainerInfo) Eq(b *ContainerInfo) bool {\n\n\t// If both ci and b are nil, then Eq() returns true\n\tif ci == nil {\n\t\treturn b == nil\n\t}\n\tif b == nil {\n\t\treturn ci == nil\n\t}\n\n\t// For fields other than time.Time, we will compare them precisely.\n\t// This would require that any slice should have same order.\n\tif !reflect.DeepEqual(ci.ContainerReference, b.ContainerReference) {\n\t\treturn false\n\t}\n\tif !reflect.DeepEqual(ci.Subcontainers, b.Subcontainers) {\n\t\treturn false\n\t}\n\tif !ci.Spec.Eq(&b.Spec) {\n\t\treturn false\n\t}\n\n\tfor i, expectedStats := range b.Stats {\n\t\tselfStats := ci.Stats[i]\n\t\tif !expectedStats.Eq(selfStats) {\n\t\t\treturn false\n\t\t}\n\t}\n\n\treturn true\n}\n\nfunc (s *ContainerSpec) Eq(b *ContainerSpec) bool {\n\t// Creation within 1s of each other.\n\tdiff := s.CreationTime.Sub(b.CreationTime)\n\tif (diff > time.Second) || (diff < -time.Second) {\n\t\treturn false\n\t}\n\n\t// Start time within 1s of each other.\n\tstartDiff := s.StartTime.Sub(b.StartTime)\n\tif (startDiff > time.Second) || (startDiff < -time.Second) {\n\t\treturn false\n\t}\n\n\tif s.HasCpu != b.HasCpu {\n\t\treturn false\n\t}\n\tif !reflect.DeepEqual(s.Cpu, b.Cpu) {\n\t\treturn false\n\t}\n\tif s.HasMemory != b.HasMemory {\n\t\treturn false\n\t}\n\tif !reflect.DeepEqual(s.Memory, b.Memory) {\n\t\treturn false\n\t}\n\tif s.HasHugetlb != b.HasHugetlb {\n\t\treturn false\n\t}\n\tif s.HasNetwork != b.HasNetwork {\n\t\treturn false\n\t}\n\tif s.HasProcesses != b.HasProcesses {\n\t\treturn false\n\t}\n\tif s.HasFilesystem != b.HasFilesystem {\n\t\treturn false\n\t}\n\tif s.HasDiskIo != b.HasDiskIo {\n\t\treturn false\n\t}\n\tif s.HasCustomMetrics != b.HasCustomMetrics {\n\t\treturn false\n\t}\n\tif s.Image != b.Image {\n\t\treturn false\n\t}\n\treturn true\n}\n\nfunc (ci *ContainerInfo) StatsAfter(ref time.Time) []*ContainerStats {\n\tn := len(ci.Stats) + 1\n\tfor i, s := range ci.Stats {\n\t\tif s.Timestamp.After(ref) {\n\t\t\tn = i\n\t\t\tbreak\n\t\t}\n\t}\n\tif n > len(ci.Stats) {\n\t\treturn nil\n\t}\n\treturn ci.Stats[n:]\n}\n\nfunc (ci *ContainerInfo) StatsStartTime() time.Time {\n\tvar ret time.Time\n\tfor _, s := range ci.Stats {\n\t\tif s.Timestamp.Before(ret) || ret.IsZero() {\n\t\t\tret = s.Timestamp\n\t\t}\n\t}\n\treturn ret\n}\n\nfunc (ci *ContainerInfo) StatsEndTime() time.Time {\n\tvar ret time.Time\n\tfor i := len(ci.Stats) - 1; i >= 0; i-- {\n\t\ts := ci.Stats[i]\n\t\tif s.Timestamp.After(ret) {\n\t\t\tret = s.Timestamp\n\t\t}\n\t}\n\treturn ret\n}\n\n// PSI statistics for an individual resource.\ntype PSIStats struct {\n\t// PSI data for all tasks of in the cgroup.\n\tFull PSIData `json:\"full,omitempty\"`\n\t// PSI data for some tasks in the cgroup.\n\tSome PSIData `json:\"some,omitempty\"`\n}\n\ntype PSIData struct {\n\t// Total time duration for tasks in the cgroup have waited due to congestion.\n\t// Unit: nanoseconds.\n\tTotal uint64 `json:\"total\"`\n\t// The average (in %) tasks have waited due to congestion over a 10 second window.\n\tAvg10 float64 `json:\"avg10\"`\n\t// The average (in %) tasks have waited due to congestion over a 60 second window.\n\tAvg60 float64 `json:\"avg60\"`\n\t// The average (in %) tasks have waited due to congestion over a 300 second window.\n\tAvg300 float64 `json:\"avg300\"`\n}\n\n// This mirrors kernel internal structure.\ntype LoadStats struct {\n\t// Number of sleeping tasks.\n\tNrSleeping uint64 `json:\"nr_sleeping\"`\n\n\t// Number of running tasks.\n\tNrRunning uint64 `json:\"nr_running\"`\n\n\t// Number of tasks in stopped state\n\tNrStopped uint64 `json:\"nr_stopped\"`\n\n\t// Number of tasks in uninterruptible state\n\tNrUninterruptible uint64 `json:\"nr_uninterruptible\"`\n\n\t// Number of tasks waiting on IO\n\tNrIoWait uint64 `json:\"nr_io_wait\"`\n}\n\n// CPU usage time statistics.\ntype CpuUsage struct {\n\t// Total CPU usage.\n\t// Unit: nanoseconds.\n\tTotal uint64 `json:\"total\"`\n\n\t// Per CPU/core usage of the container.\n\t// Unit: nanoseconds.\n\tPerCpu []uint64 `json:\"per_cpu_usage,omitempty\"`\n\n\t// Time spent in user space.\n\t// Unit: nanoseconds.\n\tUser uint64 `json:\"user\"`\n\n\t// Time spent in kernel space.\n\t// Unit: nanoseconds.\n\tSystem uint64 `json:\"system\"`\n}\n\n// Cpu Completely Fair Scheduler statistics.\ntype CpuCFS struct {\n\t// Total number of elapsed enforcement intervals.\n\tPeriods uint64 `json:\"periods\"`\n\n\t// Total number of times tasks in the cgroup have been throttled.\n\tThrottledPeriods uint64 `json:\"throttled_periods\"`\n\n\t// Total time duration for which tasks in the cgroup have been throttled.\n\t// Unit: nanoseconds.\n\tThrottledTime uint64 `json:\"throttled_time\"`\n\n\t// Total number of periods when CPU burst occurs.\n\tBurstsPeriods uint64 `json:\"bursts_periods\"`\n\n\t// Total time duration when CPU burst occurs.\n\t// Unit: nanoseconds.\n\tBurstTime uint64 `json:\"burst_time\"`\n}\n\n// Cpu Aggregated scheduler statistics\ntype CpuSchedstat struct {\n\t// https://www.kernel.org/doc/Documentation/scheduler/sched-stats.txt\n\n\t// time spent on the cpu\n\tRunTime uint64 `json:\"run_time\"`\n\t// time spent waiting on a runqueue\n\tRunqueueTime uint64 `json:\"runqueue_time\"`\n\t// # of timeslices run on this cpu\n\tRunPeriods uint64 `json:\"run_periods\"`\n}\n\n// All CPU usage metrics are cumulative from the creation of the container\ntype CpuStats struct {\n\tUsage     CpuUsage     `json:\"usage\"`\n\tCFS       CpuCFS       `json:\"cfs\"`\n\tSchedstat CpuSchedstat `json:\"schedstat\"`\n\t// Smoothed average of number of runnable threads x 1000.\n\t// We multiply by thousand to avoid using floats, but preserving precision.\n\t// Load is smoothed over the last 10 seconds. Instantaneous value can be read\n\t// from LoadStats.NrRunning.\n\tLoadAverage int32 `json:\"load_average\"`\n\t// from LoadStats.NrUninterruptible\n\tLoadDAverage int32    `json:\"load_d_average\"`\n\tPSI          PSIStats `json:\"psi\"`\n}\n\ntype PerDiskStats struct {\n\tDevice string            `json:\"device\"`\n\tMajor  uint64            `json:\"major\"`\n\tMinor  uint64            `json:\"minor\"`\n\tStats  map[string]uint64 `json:\"stats\"`\n}\n\ntype DiskIoStats struct {\n\tIoServiceBytes []PerDiskStats `json:\"io_service_bytes,omitempty\"`\n\tIoServiced     []PerDiskStats `json:\"io_serviced,omitempty\"`\n\tIoQueued       []PerDiskStats `json:\"io_queued,omitempty\"`\n\tSectors        []PerDiskStats `json:\"sectors,omitempty\"`\n\tIoServiceTime  []PerDiskStats `json:\"io_service_time,omitempty\"`\n\tIoWaitTime     []PerDiskStats `json:\"io_wait_time,omitempty\"`\n\tIoMerged       []PerDiskStats `json:\"io_merged,omitempty\"`\n\tIoTime         []PerDiskStats `json:\"io_time,omitempty\"`\n\tIoCostUsage    []PerDiskStats `json:\"io_cost_usage,omitempty\"`\n\tIoCostWait     []PerDiskStats `json:\"io_cost_wait,omitempty\"`\n\tIoCostIndebt   []PerDiskStats `json:\"io_cost_indebt,omitempty\"`\n\tIoCostIndelay  []PerDiskStats `json:\"io_cost_indelay,omitempty\"`\n\tPSI            PSIStats       `json:\"psi\"`\n}\n\ntype HugetlbStats struct {\n\t// current res_counter usage for hugetlb\n\tUsage uint64 `json:\"usage,omitempty\"`\n\t// maximum usage ever recorded.\n\tMaxUsage uint64 `json:\"max_usage,omitempty\"`\n\t// number of times hugetlb usage allocation failure.\n\tFailcnt uint64 `json:\"failcnt\"`\n}\n\ntype MemoryStats struct {\n\t// Current memory usage, this includes all memory regardless of when it was\n\t// accessed.\n\t// Units: Bytes.\n\tUsage uint64 `json:\"usage\"`\n\n\t// Maximum memory usage recorded.\n\t// Units: Bytes.\n\tMaxUsage uint64 `json:\"max_usage\"`\n\n\t// Number of bytes of page cache memory.\n\t// Units: Bytes.\n\tCache uint64 `json:\"cache\"`\n\n\t// The amount of anonymous and swap cache memory (includes transparent\n\t// hugepages).\n\t// Units: Bytes.\n\tRSS uint64 `json:\"rss\"`\n\n\t// The amount of swap currently used by the processes in this cgroup\n\t// Units: Bytes.\n\tSwap uint64 `json:\"swap\"`\n\n\t// The amount of memory used for mapped files (includes tmpfs/shmem)\n\tMappedFile uint64 `json:\"mapped_file\"`\n\n\t// The amount of working set memory, this includes recently accessed memory,\n\t// dirty memory, and kernel memory. Working set is <= \"usage\".\n\t// Units: Bytes.\n\tWorkingSet uint64 `json:\"working_set\"`\n\n\t// The total amount of active file memory.\n\t// Units: Bytes.\n\tTotalActiveFile uint64 `json:\"total_active_file\"`\n\n\t// The total amount of inactive file memory.\n\t// Units: Bytes.\n\tTotalInactiveFile uint64 `json:\"total_inactive_file\"`\n\n\tFailcnt uint64 `json:\"failcnt\"`\n\n\t// Size of kernel memory allocated in bytes.\n\t// Units: Bytes.\n\tKernelUsage uint64 `json:\"kernel\"`\n\n\tContainerData    MemoryStatsMemoryData `json:\"container_data,omitempty\"`\n\tHierarchicalData MemoryStatsMemoryData `json:\"hierarchical_data,omitempty\"`\n\n\tPSI PSIStats `json:\"psi\"`\n}\n\ntype CPUSetStats struct {\n\tMemoryMigrate uint64 `json:\"memory_migrate\"`\n}\n\ntype MemoryNumaStats struct {\n\tFile        map[uint8]uint64 `json:\"file,omitempty\"`\n\tAnon        map[uint8]uint64 `json:\"anon,omitempty\"`\n\tUnevictable map[uint8]uint64 `json:\"unevictable,omitempty\"`\n}\n\ntype MemoryStatsMemoryData struct {\n\tPgfault    uint64          `json:\"pgfault\"`\n\tPgmajfault uint64          `json:\"pgmajfault\"`\n\tNumaStats  MemoryNumaStats `json:\"numa_stats,omitempty\"`\n}\n\ntype InterfaceStats struct {\n\t// The name of the interface.\n\tName string `json:\"name\"`\n\t// Cumulative count of bytes received.\n\tRxBytes uint64 `json:\"rx_bytes\"`\n\t// Cumulative count of packets received.\n\tRxPackets uint64 `json:\"rx_packets\"`\n\t// Cumulative count of receive errors encountered.\n\tRxErrors uint64 `json:\"rx_errors\"`\n\t// Cumulative count of packets dropped while receiving.\n\tRxDropped uint64 `json:\"rx_dropped\"`\n\t// Cumulative count of bytes transmitted.\n\tTxBytes uint64 `json:\"tx_bytes\"`\n\t// Cumulative count of packets transmitted.\n\tTxPackets uint64 `json:\"tx_packets\"`\n\t// Cumulative count of transmit errors encountered.\n\tTxErrors uint64 `json:\"tx_errors\"`\n\t// Cumulative count of packets dropped while transmitting.\n\tTxDropped uint64 `json:\"tx_dropped\"`\n}\n\ntype NetworkStats struct {\n\tInterfaceStats `json:\",inline\"`\n\tInterfaces     []InterfaceStats `json:\"interfaces,omitempty\"`\n\t// TCP connection stats (Established, Listen...)\n\tTcp TcpStat `json:\"tcp\"`\n\t// TCP6 connection stats (Established, Listen...)\n\tTcp6 TcpStat `json:\"tcp6\"`\n\t// UDP connection stats\n\tUdp UdpStat `json:\"udp\"`\n\t// UDP6 connection stats\n\tUdp6 UdpStat `json:\"udp6\"`\n\t// TCP advanced stats\n\tTcpAdvanced TcpAdvancedStat `json:\"tcp_advanced\"`\n}\n\ntype TcpStat struct {\n\t// Count of TCP connections in state \"Established\"\n\tEstablished uint64\n\t// Count of TCP connections in state \"Syn_Sent\"\n\tSynSent uint64\n\t// Count of TCP connections in state \"Syn_Recv\"\n\tSynRecv uint64\n\t// Count of TCP connections in state \"Fin_Wait1\"\n\tFinWait1 uint64\n\t// Count of TCP connections in state \"Fin_Wait2\"\n\tFinWait2 uint64\n\t// Count of TCP connections in state \"Time_Wait\n\tTimeWait uint64\n\t// Count of TCP connections in state \"Close\"\n\tClose uint64\n\t// Count of TCP connections in state \"Close_Wait\"\n\tCloseWait uint64\n\t// Count of TCP connections in state \"Listen_Ack\"\n\tLastAck uint64\n\t// Count of TCP connections in state \"Listen\"\n\tListen uint64\n\t// Count of TCP connections in state \"Closing\"\n\tClosing uint64\n}\n\ntype TcpAdvancedStat struct {\n\t// The algorithm used to determine the timeout value used for\n\t// retransmitting unacknowledged octets, ref: RFC2698, default 1\n\tRtoAlgorithm uint64\n\t// The minimum value permitted by a TCP implementation for the\n\t// retransmission timeout, measured in milliseconds, default 200ms\n\tRtoMin uint64\n\t// The maximum value permitted by a TCP implementation for the\n\t// retransmission timeout, measured in milliseconds, default 120s\n\tRtoMax uint64\n\t// The limit on the total number of TCP connections the entity\n\t// can support., default -1, i.e. infinity\n\tMaxConn int64\n\n\t// The number of times TCP connections have made a direct\n\t// transition to the SYN-SENT state from the CLOSED state.\n\tActiveOpens uint64\n\t// The number of times TCP connections have made a direct\n\t// transition to the SYN-RCVD state from the LISTEN state.\n\tPassiveOpens uint64\n\t// The number of times TCP connections have made a direct\n\t// transition to the CLOSED state from either the SYN-SENT\n\t// state or the SYN-RCVD state, plus the number of times TCP\n\t// connections have made a direct transition to the LISTEN\n\t// state from the SYN-RCVD state.\n\tAttemptFails uint64\n\t// The number of times TCP connections have made a direct\n\t// transition to the CLOSED state from either the ESTABLISHED\n\t// state or the CLOSE-WAIT state.\n\tEstabResets uint64\n\t// The number of TCP connections for which the current state\n\t// is either ESTABLISHED or CLOSE- WAIT.\n\tCurrEstab uint64\n\n\t// The total number of segments received, including those\n\t// received in error.\n\tInSegs uint64\n\t// The total number of segments sent, including those on\n\t// current connections but excluding those containing only\n\t// retransmitted octets.\n\tOutSegs uint64\n\t// The total number of segments retransmitted - that is, the\n\t// number of TCP segments transmitted containing one or more\n\t// previously transmitted octets.\n\tRetransSegs uint64\n\t// The total number of segments received in error (e.g., bad\n\t// TCP checksums).\n\tInErrs uint64\n\t// The number of TCP segments sent containing the RST flag.\n\tOutRsts uint64\n\t// The number of IP Packets with checksum errors\n\tInCsumErrors uint64\n\t// The number of resets received for embryonic SYN_RECV sockets\n\tEmbryonicRsts uint64\n\n\t// The number of SYN cookies sent\n\tSyncookiesSent uint64\n\t// The number of SYN cookies received\n\tSyncookiesRecv uint64\n\t// The number of invalid SYN cookies received\n\tSyncookiesFailed uint64\n\n\t// The number of packets pruned from receive queue because of socket buffer overrun\n\tPruneCalled uint64\n\t// The number of packets pruned from receive queue\n\tRcvPruned uint64\n\t// The number of packets dropped from out-of-order queue because of socket buffer overrun\n\tOfoPruned uint64\n\t// The number of ICMP packets dropped because they were out-of-window\n\tOutOfWindowIcmps uint64\n\t// The number of ICMP packets dropped because socket was locked\n\tLockDroppedIcmps uint64\n\n\t// The number of TCP sockets finished time wait in fast timer\n\tTW uint64\n\t// The number of time wait sockets recycled by time stamp\n\tTWRecycled uint64\n\t// The number of TCP sockets finished time wait in slow timer\n\tTWKilled uint64\n\t// counter, if no more mem for TIME-WAIT struct, +1\n\tTCPTimeWaitOverflow uint64\n\n\t// The number of RTO timer first timeout times\n\tTCPTimeouts uint64\n\t// The number of fake timeouts detected by F-RTO\n\tTCPSpuriousRTOs uint64\n\t// The number of send Tail Loss Probe (TLP) times by Probe Timeout(PTO)\n\tTCPLossProbes uint64\n\t// The number of recovery times by TLP\n\tTCPLossProbeRecovery uint64\n\t// The number of RTO failed times when in Recovery state, and remote end has no sack\n\tTCPRenoRecoveryFail uint64\n\t// The number of RTO failed times when in Recovery state, and remote end has sack\n\tTCPSackRecoveryFail uint64\n\t// The number of RTO failed times when in TCP_CA_Disorder state, and remote end has no sack\n\tTCPRenoFailures uint64\n\t// The number of RTO failed times when in TCP_CA_Disorder state, and remote end has sack\n\tTCPSackFailures uint64\n\t// The number of RTO failed times when in TCP_CA_Loss state,\n\tTCPLossFailures uint64\n\n\t// The number of delayed acks sent\n\tDelayedACKs uint64\n\t// The number of delayed acks further delayed because of locked socket\n\tDelayedACKLocked uint64\n\t// The number of quick ack mode was activated times\n\tDelayedACKLost uint64\n\t// The number of times the listen queue of a socket overflowed\n\tListenOverflows uint64\n\t// The number of SYNs to LISTEN sockets dropped\n\tListenDrops uint64\n\t// The number of packet headers predicted\n\tTCPHPHits uint64\n\t// The number of acknowledgments not containing data payload received\n\tTCPPureAcks uint64\n\t// The number of predicted acknowledgments\n\tTCPHPAcks uint64\n\t// The number of times recovered from packet loss due to fast retransmit\n\tTCPRenoRecovery uint64\n\t// The number of SACK retransmits failed\n\tTCPSackRecovery uint64\n\t// The number of bad SACK blocks received\n\tTCPSACKReneging uint64\n\t// The number of detected reordering times using FACK\n\tTCPFACKReorder uint64\n\t// The number of detected reordering times using SACK\n\tTCPSACKReorder uint64\n\t// The number of detected reordering times using Reno\n\tTCPRenoReorder uint64\n\t// The number of detected reordering times using time stamp\n\tTCPTSReorder uint64\n\t// The number of congestion windows fully recovered without slow start\n\tTCPFullUndo uint64\n\t// The number of congestion windows partially recovered using Hoe heuristic\n\tTCPPartialUndo uint64\n\t// The number of congestion windows recovered without slow start by DSACK\n\tTCPDSACKUndo uint64\n\t// The number of congestion windows recovered without slow start after partial ack\n\tTCPLossUndo uint64\n\n\t// The number of fast retransmits\n\tTCPFastRetrans uint64\n\t// The number of retransmits in slow start\n\tTCPSlowStartRetrans uint64\n\t// The number of retransmits lost\n\tTCPLostRetransmit uint64\n\t// The number of retransmits failed, including FastRetrans, SlowStartRetrans\n\tTCPRetransFail uint64\n\n\t// The number of packets collapsed in receive queue due to low socket buffer\n\tTCPRcvCollapsed uint64\n\t// The number of DSACKs sent for old packets\n\tTCPDSACKOldSent uint64\n\t// The number of DSACKs sent for out of order packets\n\tTCPDSACKOfoSent uint64\n\t// The number of DSACKs received\n\tTCPDSACKRecv uint64\n\t// The number of DSACKs for out of order packets received\n\tTCPDSACKOfoRecv uint64\n\t// The number of connections reset due to unexpected data\n\tTCPAbortOnData uint64\n\t// The number of connections reset due to early user close\n\tTCPAbortOnClose uint64\n\t// The number of connections aborted due to memory pressure\n\tTCPAbortOnMemory uint64\n\t// The number of connections aborted due to timeout\n\tTCPAbortOnTimeout uint64\n\t// The number of connections aborted after user close in linger timeout\n\tTCPAbortOnLinger uint64\n\t// The number of times unable to send RST due to no memory\n\tTCPAbortFailed uint64\n\t// The number of TCP ran low on memory times\n\tTCPMemoryPressures uint64\n\t// The number of TCP cumulative duration of\n\t// memory pressure events, by ms\n\tTCPMemoryPressuresChrono uint64\n\t// The number of SACKs discard\n\tTCPSACKDiscard uint64\n\t// The number of DSACKs ignore old\n\tTCPDSACKIgnoredOld uint64\n\t// The number of DSACKs ignore no undo\n\tTCPDSACKIgnoredNoUndo uint64\n\n\t// The number of MD5 not found\n\tTCPMD5NotFound uint64\n\t// The number of MD5 unexpected\n\tTCPMD5Unexpected uint64\n\t// The number of MD5 failed\n\tTCPMD5Failure uint64\n\t// The number of Sack shifted\n\tTCPSackShifted uint64\n\t// The number of Sack merged\n\tTCPSackMerged uint64\n\t// The number of Sack shift fall back\n\tTCPSackShiftFallback uint64\n\t// The number of Backlog drop\n\tTCPBacklogDrop uint64\n\t// The number of PFmemalloc drop\n\tPFMemallocDrop uint64\n\t// The number of memalloc drop\n\tTCPMinTTLDrop uint64\n\t// The number of DeferAccept drop\n\tTCPDeferAcceptDrop uint64\n\t// The number of IP reverse path filter\n\tIPReversePathFilter uint64\n\n\t// The number of request full do cookies\n\tTCPReqQFullDoCookies uint64\n\t// The number of request full drop\n\tTCPReqQFullDrop uint64\n\n\t// number of successful outbound TFO connections\n\tTCPFastOpenActive uint64\n\t// number of SYN-ACK packets received that did not acknowledge data\n\t// sent in the SYN packet and caused a retransmissions without SYN data.\n\tTCPFastOpenActiveFail uint64\n\t// number of successful inbound TFO connections\n\tTCPFastOpenPassive uint64\n\t// number of inbound SYN packets with TFO cookie that was invalid\n\tTCPFastOpenPassiveFail uint64\n\t// number of inbound SYN packets that will have TFO disabled because\n\t// the socket has exceeded the max queue length\n\tTCPFastOpenListenOverflow uint64\n\t// number of inbound SYN packets requesting TFO with TFO set but no cookie\n\tTCPFastOpenCookieReqd uint64\n\n\t// number of SYN and SYN/ACK retransmits to break down retransmissions\n\t// into SYN, fast-retransmits, timeout retransmits, etc.\n\tTCPSynRetrans uint64\n\t// number of outgoing packets with original data\n\t// (excluding retransmission but including data-in-SYN).\n\tTCPOrigDataSent uint64\n\n\t// The number of active connections rejected because of time stamp\n\tPAWSActive uint64\n\t// The number of packetes rejected in established connections because of timestamp\n\tPAWSEstab uint64\n}\n\ntype UdpStat struct {\n\t// Count of UDP sockets in state \"Listen\"\n\tListen uint64\n\n\t// Count of UDP packets dropped by the IP stack\n\tDropped uint64\n\n\t// Count of packets Queued for Receieve\n\tRxQueued uint64\n\n\t// Count of packets Queued for Transmit\n\tTxQueued uint64\n}\n\ntype FsStats struct {\n\t// The block device name associated with the filesystem.\n\tDevice string `json:\"device,omitempty\"`\n\n\t// Type of the filesytem.\n\tType string `json:\"type\"`\n\n\t// Number of bytes that can be consumed by the container on this filesystem.\n\tLimit uint64 `json:\"capacity\"`\n\n\t// Number of bytes that is consumed by the container on this filesystem.\n\tUsage uint64 `json:\"usage\"`\n\n\t// Base Usage that is consumed by the container's writable layer.\n\t// This field is only applicable for docker container's as of now.\n\tBaseUsage uint64 `json:\"base_usage\"`\n\n\t// Number of bytes available for non-root user.\n\tAvailable uint64 `json:\"available\"`\n\n\t// HasInodes when true, indicates that Inodes info will be available.\n\tHasInodes bool `json:\"has_inodes\"`\n\n\t// Number of Inodes\n\tInodes uint64 `json:\"inodes\"`\n\n\t// Number of available Inodes\n\tInodesFree uint64 `json:\"inodes_free\"`\n\n\t// Number of reads completed\n\t// This is the total number of reads completed successfully.\n\tReadsCompleted uint64 `json:\"reads_completed\"`\n\n\t// Number of reads merged\n\t// Reads and writes which are adjacent to each other may be merged for\n\t// efficiency.  Thus two 4K reads may become one 8K read before it is\n\t// ultimately handed to the disk, and so it will be counted (and queued)\n\t// as only one I/O.  This field lets you know how often this was done.\n\tReadsMerged uint64 `json:\"reads_merged\"`\n\n\t// Number of sectors read\n\t// This is the total number of sectors read successfully.\n\tSectorsRead uint64 `json:\"sectors_read\"`\n\n\t// Number of milliseconds spent reading\n\t// This is the total number of milliseconds spent by all reads (as\n\t// measured from __make_request() to end_that_request_last()).\n\tReadTime uint64 `json:\"read_time\"`\n\n\t// Number of writes completed\n\t// This is the total number of writes completed successfully.\n\tWritesCompleted uint64 `json:\"writes_completed\"`\n\n\t// Number of writes merged\n\t// See the description of reads merged.\n\tWritesMerged uint64 `json:\"writes_merged\"`\n\n\t// Number of sectors written\n\t// This is the total number of sectors written successfully.\n\tSectorsWritten uint64 `json:\"sectors_written\"`\n\n\t// Number of milliseconds spent writing\n\t// This is the total number of milliseconds spent by all writes (as\n\t// measured from __make_request() to end_that_request_last()).\n\tWriteTime uint64 `json:\"write_time\"`\n\n\t// Number of I/Os currently in progress\n\t// The only field that should go to zero. Incremented as requests are\n\t// given to appropriate struct request_queue and decremented as they finish.\n\tIoInProgress uint64 `json:\"io_in_progress\"`\n\n\t// Number of milliseconds spent doing I/Os\n\t// This field increases so long as field 9 is nonzero.\n\tIoTime uint64 `json:\"io_time\"`\n\n\t// weighted number of milliseconds spent doing I/Os\n\t// This field is incremented at each I/O start, I/O completion, I/O\n\t// merge, or read of these stats by the number of I/Os in progress\n\t// (field 9) times the number of milliseconds spent doing I/O since the\n\t// last update of this field.  This can provide an easy measure of both\n\t// I/O completion time and the backlog that may be accumulating.\n\tWeightedIoTime uint64 `json:\"weighted_io_time\"`\n}\n\ntype AcceleratorStats struct {\n\t// Make of the accelerator (nvidia, amd, google etc.)\n\tMake string `json:\"make\"`\n\n\t// Model of the accelerator (tesla-p100, tesla-k80 etc.)\n\tModel string `json:\"model\"`\n\n\t// ID of the accelerator.\n\tID string `json:\"id\"`\n\n\t// Total accelerator memory.\n\t// unit: bytes\n\tMemoryTotal uint64 `json:\"memory_total\"`\n\n\t// Total accelerator memory allocated.\n\t// unit: bytes\n\tMemoryUsed uint64 `json:\"memory_used\"`\n\n\t// Percent of time over the past sample period during which\n\t// the accelerator was actively processing.\n\tDutyCycle uint64 `json:\"duty_cycle\"`\n}\n\n// PerfStat represents value of a single monitored perf event.\ntype PerfStat struct {\n\tPerfValue\n\n\t// CPU that perf event was measured on.\n\tCpu int `json:\"cpu\"`\n}\n\ntype PerfValue struct {\n\t// Indicates scaling ratio for an event: time_running/time_enabled\n\t// (amount of time that event was being measured divided by\n\t// amount of time that event was enabled for).\n\t// value 1.0 indicates that no multiplexing occurred. Value close\n\t// to 0 indicates that event was measured for short time and event's\n\t// value might be inaccurate.\n\t// See: https://lwn.net/Articles/324756/\n\tScalingRatio float64 `json:\"scaling_ratio\"`\n\n\t// Value represents value of perf event retrieved from OS. It is\n\t// normalized against ScalingRatio and takes multiplexing into\n\t// consideration.\n\tValue uint64 `json:\"value\"`\n\n\t// Name is human readable name of an event.\n\tName string `json:\"name\"`\n}\n\n// MemoryBandwidthStats corresponds to MBM (Memory Bandwidth Monitoring).\n// See: https://01.org/cache-monitoring-technology\n// See: https://www.kernel.org/doc/Documentation/x86/intel_rdt_ui.txt\ntype MemoryBandwidthStats struct {\n\t// The 'mbm_total_bytes'.\n\tTotalBytes uint64 `json:\"mbm_total_bytes,omitempty\"`\n\n\t// The 'mbm_local_bytes'.\n\tLocalBytes uint64 `json:\"mbm_local_bytes,omitempty\"`\n}\n\n// CacheStats corresponds to CMT (Cache Monitoring Technology).\n// See: https://01.org/cache-monitoring-technology\n// See: https://www.kernel.org/doc/Documentation/x86/intel_rdt_ui.txt\ntype CacheStats struct {\n\t// The 'llc_occupancy'.\n\tLLCOccupancy uint64 `json:\"llc_occupancy,omitempty\"`\n}\n\n// ResctrlStats corresponds to statistics from Resource Control.\ntype ResctrlStats struct {\n\t// Each NUMA Node statistics corresponds to one element in the array.\n\tMemoryBandwidth []MemoryBandwidthStats `json:\"memory_bandwidth,omitempty\"`\n\tCache           []CacheStats           `json:\"cache,omitempty\"`\n}\n\n// PerfUncoreStat represents value of a single monitored perf uncore event.\ntype PerfUncoreStat struct {\n\tPerfValue\n\n\t// Socket that perf event was measured on.\n\tSocket int `json:\"socket\"`\n\n\t// PMU is Performance Monitoring Unit which collected these stats.\n\tPMU string `json:\"pmu\"`\n}\n\ntype UlimitSpec struct {\n\tName      string `json:\"name\"`\n\tSoftLimit int64  `json:\"soft_limit\"`\n\tHardLimit int64  `json:\"hard_limit\"`\n}\n\ntype ProcessStats struct {\n\t// Number of processes\n\tProcessCount uint64 `json:\"process_count\"`\n\n\t// Number of open file descriptors\n\tFdCount uint64 `json:\"fd_count\"`\n\n\t// Number of sockets\n\tSocketCount uint64 `json:\"socket_count\"`\n\n\t// Number of threads currently in container\n\tThreadsCurrent uint64 `json:\"threads_current,omitempty\"`\n\n\t// Maxium number of threads allowed in container\n\tThreadsMax uint64 `json:\"threads_max,omitempty\"`\n\n\t// Ulimits for the top-level container process\n\tUlimits []UlimitSpec `json:\"ulimits,omitempty\"`\n}\n\ntype Health struct {\n\t// Health status of the container\n\tStatus string `json:\"status\"`\n}\n\ntype ContainerStats struct {\n\t// The time of this stat point.\n\tTimestamp time.Time               `json:\"timestamp\"`\n\tCpu       CpuStats                `json:\"cpu,omitempty\"`\n\tDiskIo    DiskIoStats             `json:\"diskio,omitempty\"`\n\tMemory    MemoryStats             `json:\"memory,omitempty\"`\n\tHugetlb   map[string]HugetlbStats `json:\"hugetlb,omitempty\"`\n\tNetwork   NetworkStats            `json:\"network,omitempty\"`\n\t// Filesystem statistics\n\tFilesystem []FsStats `json:\"filesystem,omitempty\"`\n\n\t// Task load stats\n\tTaskStats LoadStats `json:\"task_stats,omitempty\"`\n\n\t// Metrics for Accelerators. Each Accelerator corresponds to one element in the array.\n\tAccelerators []AcceleratorStats `json:\"accelerators,omitempty\"`\n\n\t// ProcessStats for Containers\n\tProcesses ProcessStats `json:\"processes,omitempty\"`\n\n\t// Custom metrics from all collectors\n\tCustomMetrics map[string][]MetricVal `json:\"custom_metrics,omitempty\"`\n\n\t// Statistics originating from perf events\n\tPerfStats []PerfStat `json:\"perf_stats,omitempty\"`\n\n\t// Statistics originating from perf uncore events.\n\t// Applies only for root container.\n\tPerfUncoreStats []PerfUncoreStat `json:\"perf_uncore_stats,omitempty\"`\n\n\t// Referenced memory\n\tReferencedMemory uint64 `json:\"referenced_memory,omitempty\"`\n\n\t// Resource Control (resctrl) statistics\n\tResctrl ResctrlStats `json:\"resctrl,omitempty\"`\n\n\tCpuSet CPUSetStats `json:\"cpuset,omitempty\"`\n\n\tOOMEvents uint64 `json:\"oom_events,omitempty\"`\n\n\tHealth Health `json:\"health,omitempty\"`\n}\n\nfunc timeEq(t1, t2 time.Time, tolerance time.Duration) bool {\n\t// t1 should not be later than t2\n\tif t1.After(t2) {\n\t\tt1, t2 = t2, t1\n\t}\n\tdiff := t2.Sub(t1)\n\treturn diff <= tolerance\n}\n\nconst (\n\t// 10ms, i.e. 0.01s\n\ttimePrecision time.Duration = 10 * time.Millisecond\n)\n\n// This function is useful because we do not require precise time\n// representation.\nfunc (a *ContainerStats) Eq(b *ContainerStats) bool {\n\tif !timeEq(a.Timestamp, b.Timestamp, timePrecision) {\n\t\treturn false\n\t}\n\treturn a.StatsEq(b)\n}\n\n// Checks equality of the stats values.\nfunc (a *ContainerStats) StatsEq(b *ContainerStats) bool {\n\t// TODO(vmarmol): Consider using this through reflection.\n\tif !reflect.DeepEqual(a.Cpu, b.Cpu) {\n\t\treturn false\n\t}\n\tif !reflect.DeepEqual(a.Memory, b.Memory) {\n\t\treturn false\n\t}\n\tif !reflect.DeepEqual(a.Hugetlb, b.Hugetlb) {\n\t\treturn false\n\t}\n\tif !reflect.DeepEqual(a.DiskIo, b.DiskIo) {\n\t\treturn false\n\t}\n\tif !reflect.DeepEqual(a.Network, b.Network) {\n\t\treturn false\n\t}\n\tif !reflect.DeepEqual(a.Processes, b.Processes) {\n\t\treturn false\n\t}\n\tif !reflect.DeepEqual(a.Filesystem, b.Filesystem) {\n\t\treturn false\n\t}\n\tif !reflect.DeepEqual(a.TaskStats, b.TaskStats) {\n\t\treturn false\n\t}\n\tif !reflect.DeepEqual(a.Accelerators, b.Accelerators) {\n\t\treturn false\n\t}\n\tif !reflect.DeepEqual(a.CustomMetrics, b.CustomMetrics) {\n\t\treturn false\n\t}\n\treturn true\n}\n\n// Event contains information general to events such as the time at which they\n// occurred, their specific type, and the actual event. Event types are\n// differentiated by the EventType field of Event.\ntype Event struct {\n\t// the absolute container name for which the event occurred\n\tContainerName string `json:\"container_name\"`\n\n\t// the time at which the event occurred\n\tTimestamp time.Time `json:\"timestamp\"`\n\n\t// the type of event. EventType is an enumerated type\n\tEventType EventType `json:\"event_type\"`\n\n\t// the original event object and all of its extraneous data, ex. an\n\t// OomInstance\n\tEventData EventData `json:\"event_data,omitempty\"`\n}\n\n// EventType is an enumerated type which lists the categories under which\n// events may fall. The Event field EventType is populated by this enum.\ntype EventType string\n\nconst (\n\tEventOom               EventType = \"oom\"\n\tEventOomKill           EventType = \"oomKill\"\n\tEventContainerCreation EventType = \"containerCreation\"\n\tEventContainerDeletion EventType = \"containerDeletion\"\n)\n\n// Extra information about an event. Only one type will be set.\ntype EventData struct {\n\t// Information about an OOM kill event.\n\tOomKill *OomKillEventData `json:\"oom,omitempty\"`\n\n\t// Information about a container deletion event.\n\tContainerDeletion *ContainerDeletionEventData `json:\"container_deletion,omitempty\"`\n}\n\n// Information related to an OOM kill instance\ntype OomKillEventData struct {\n\t// process id of the killed process\n\tPid int `json:\"pid\"`\n\n\t// The name of the killed process\n\tProcessName string `json:\"process_name\"`\n}\n\n// Information related to a container deletion event\ntype ContainerDeletionEventData struct {\n\t// ExitCode is the exit code of the container.\n\t// A value of -1 indicates the exit code was not available or not applicable.\n\tExitCode int `json:\"exit_code\"`\n}\n"
  },
  {
    "path": "info/v1/container_test.go",
    "content": "// Copyright 2014 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage v1\n\nimport (\n\t\"testing\"\n\t\"time\"\n)\n\nfunc TestStatsStartTime(t *testing.T) {\n\tN := 10\n\tstats := make([]*ContainerStats, 0, N)\n\tct := time.Now()\n\tfor i := 0; i < N; i++ {\n\t\ts := &ContainerStats{\n\t\t\tTimestamp: ct.Add(time.Duration(i) * time.Second),\n\t\t}\n\t\tstats = append(stats, s)\n\t}\n\tcinfo := &ContainerInfo{\n\t\tContainerReference: ContainerReference{\n\t\t\tName: \"/some/container\",\n\t\t},\n\t\tStats: stats,\n\t}\n\tref := ct.Add(time.Duration(N-1) * time.Second)\n\tend := cinfo.StatsEndTime()\n\n\tif !ref.Equal(end) {\n\t\tt.Errorf(\"end time is %v; should be %v\", end, ref)\n\t}\n}\n\nfunc TestStatsEndTime(t *testing.T) {\n\tN := 10\n\tstats := make([]*ContainerStats, 0, N)\n\tct := time.Now()\n\tfor i := 0; i < N; i++ {\n\t\ts := &ContainerStats{\n\t\t\tTimestamp: ct.Add(time.Duration(i) * time.Second),\n\t\t}\n\t\tstats = append(stats, s)\n\t}\n\tcinfo := &ContainerInfo{\n\t\tContainerReference: ContainerReference{\n\t\t\tName: \"/some/container\",\n\t\t},\n\t\tStats: stats,\n\t}\n\tref := ct\n\tstart := cinfo.StatsStartTime()\n\n\tif !ref.Equal(start) {\n\t\tt.Errorf(\"start time is %v; should be %v\", start, ref)\n\t}\n}\n"
  },
  {
    "path": "info/v1/docker.go",
    "content": "// Copyright 2016 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n// Types used for docker containers.\npackage v1\n\ntype DockerStatus struct {\n\tVersion       string            `json:\"version\"`\n\tAPIVersion    string            `json:\"api_version\"`\n\tKernelVersion string            `json:\"kernel_version\"`\n\tOS            string            `json:\"os\"`\n\tHostname      string            `json:\"hostname\"`\n\tRootDir       string            `json:\"root_dir\"`\n\tDriver        string            `json:\"driver\"`\n\tDriverStatus  map[string]string `json:\"driver_status\"`\n\tExecDriver    string            `json:\"exec_driver\"`\n\tNumImages     int               `json:\"num_images\"`\n\tNumContainers int               `json:\"num_containers\"`\n}\n\ntype DockerImage struct {\n\tID          string   `json:\"id\"`\n\tRepoTags    []string `json:\"repo_tags\"` // repository name and tags.\n\tCreated     int64    `json:\"created\"`   // unix time since creation.\n\tVirtualSize int64    `json:\"virtual_size\"`\n\tSize        int64    `json:\"size\"`\n}\n"
  },
  {
    "path": "info/v1/machine.go",
    "content": "// Copyright 2014 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage v1\n\nimport \"time\"\n\ntype FsInfo struct {\n\t// Block device associated with the filesystem.\n\tDevice string `json:\"device\"`\n\t// DeviceMajor is the major identifier of the device, used for correlation with blkio stats\n\tDeviceMajor uint64 `json:\"-\"`\n\t// DeviceMinor is the minor identifier of the device, used for correlation with blkio stats\n\tDeviceMinor uint64 `json:\"-\"`\n\n\t// Total number of bytes available on the filesystem.\n\tCapacity uint64 `json:\"capacity\"`\n\n\t// Type of device.\n\tType string `json:\"type\"`\n\n\t// Total number of inodes available on the filesystem.\n\tInodes uint64 `json:\"inodes\"`\n\n\t// HasInodes when true, indicates that Inodes info will be available.\n\tHasInodes bool `json:\"has_inodes\"`\n}\n\ntype Node struct {\n\tId int `json:\"node_id\"`\n\t// Per-node memory\n\tMemory    uint64          `json:\"memory\"`\n\tHugePages []HugePagesInfo `json:\"hugepages\"`\n\tCores     []Core          `json:\"cores\"`\n\tCaches    []Cache         `json:\"caches\"`\n\tDistances []uint64        `json:\"distances\"`\n}\n\ntype Core struct {\n\tId           int     `json:\"core_id\"`\n\tThreads      []int   `json:\"thread_ids\"`\n\tCaches       []Cache `json:\"caches\"`\n\tUncoreCaches []Cache `json:\"uncore_caches\"`\n\tSocketID     int     `json:\"socket_id\"`\n\tBookID       string  `json:\"book_id,omitempty\"`\n\tDrawerID     string  `json:\"drawer_id,omitempty\"`\n}\n\ntype Cache struct {\n\t// Id of memory cache\n\tId int `json:\"id\"`\n\t// Size of memory cache in bytes.\n\tSize uint64 `json:\"size\"`\n\t// Type of memory cache: data, instruction, or unified.\n\tType string `json:\"type\"`\n\t// Level (distance from cpus) in a multi-level cache hierarchy.\n\tLevel int `json:\"level\"`\n}\n\nfunc (n *Node) FindCore(id int) (bool, int) {\n\tfor i, n := range n.Cores {\n\t\tif n.Id == id {\n\t\t\treturn true, i\n\t\t}\n\t}\n\treturn false, -1\n}\n\n// FindCoreByThread returns bool if found Core with same thread as provided and it's index in Node Core array.\n// If it's not found, returns false and -1.\nfunc (n *Node) FindCoreByThread(thread int) (bool, int) {\n\tfor i, n := range n.Cores {\n\t\tfor _, t := range n.Threads {\n\t\t\tif t == thread {\n\t\t\t\treturn true, i\n\t\t\t}\n\t\t}\n\t}\n\treturn false, -1\n}\n\nfunc (n *Node) AddThread(thread int, core int) {\n\tvar coreIdx int\n\tif core == -1 {\n\t\t// Assume one hyperthread per core when topology data is missing.\n\t\tcore = thread\n\t}\n\tok, coreIdx := n.FindCore(core)\n\n\tif !ok {\n\t\t// New core\n\t\tcore := Core{Id: core}\n\t\tn.Cores = append(n.Cores, core)\n\t\tcoreIdx = len(n.Cores) - 1\n\t}\n\tn.Cores[coreIdx].Threads = append(n.Cores[coreIdx].Threads, thread)\n}\n\nfunc (n *Node) AddNodeCache(c Cache) {\n\tn.Caches = append(n.Caches, c)\n}\n\nfunc (n *Node) AddPerCoreCache(c Cache) {\n\tfor idx := range n.Cores {\n\t\tn.Cores[idx].Caches = append(n.Cores[idx].Caches, c)\n\t}\n}\n\ntype HugePagesInfo struct {\n\t// huge page size (in kB)\n\tPageSize uint64 `json:\"page_size\"`\n\n\t// number of huge pages\n\tNumPages uint64 `json:\"num_pages\"`\n}\n\ntype DiskInfo struct {\n\t// device name\n\tName string `json:\"name\"`\n\n\t// Major number\n\tMajor uint64 `json:\"major\"`\n\n\t// Minor number\n\tMinor uint64 `json:\"minor\"`\n\n\t// Size in bytes\n\tSize uint64 `json:\"size\"`\n\n\t// I/O Scheduler - one of \"none\", \"noop\", \"cfq\", \"deadline\"\n\tScheduler string `json:\"scheduler\"`\n}\n\ntype NetInfo struct {\n\t// Device name\n\tName string `json:\"name\"`\n\n\t// Mac Address\n\tMacAddress string `json:\"mac_address\"`\n\n\t// Speed in MBits/s\n\tSpeed int64 `json:\"speed\"`\n\n\t// Maximum Transmission Unit\n\tMtu int64 `json:\"mtu\"`\n}\n\ntype CloudProvider string\n\nconst (\n\tGCE             CloudProvider = \"GCE\"\n\tAWS             CloudProvider = \"AWS\"\n\tAzure           CloudProvider = \"Azure\"\n\tUnknownProvider CloudProvider = \"Unknown\"\n)\n\ntype InstanceType string\n\nconst (\n\tUnknownInstance = \"Unknown\"\n)\n\ntype InstanceID string\n\nconst (\n\tUnNamedInstance InstanceID = \"None\"\n)\n\ntype MachineInfo struct {\n\t// The time of this information point.\n\tTimestamp time.Time `json:\"timestamp\"`\n\n\t// Vendor id of CPU.\n\tCPUVendorID string `json:\"vendor_id\"`\n\n\t// The number of cores in this machine.\n\tNumCores int `json:\"num_cores\"`\n\n\t// The number of physical cores in this machine.\n\tNumPhysicalCores int `json:\"num_physical_cores\"`\n\n\t// The number of cpu sockets in this machine.\n\tNumSockets int `json:\"num_sockets\"`\n\n\t// The number of cpu books in this machine.\n\tNumBooks int `json:\"num_books,omitempty\"`\n\n\t// The number of cpu drawers in this machine.\n\tNumDrawers int `json:\"num_drawers,omitempty\"`\n\n\t// Maximum clock speed for the cores, in KHz.\n\tCpuFrequency uint64 `json:\"cpu_frequency_khz\"`\n\n\t// The amount of memory (in bytes) in this machine\n\tMemoryCapacity uint64 `json:\"memory_capacity\"`\n\n\t// The amount of swap (in bytes) in this machine\n\tSwapCapacity uint64 `json:\"swap_capacity\"`\n\n\t// Memory capacity and number of DIMMs by memory type\n\tMemoryByType map[string]*MemoryInfo `json:\"memory_by_type\"`\n\n\tNVMInfo NVMInfo `json:\"nvm\"`\n\n\t// HugePages on this machine.\n\tHugePages []HugePagesInfo `json:\"hugepages\"`\n\n\t// The machine id\n\tMachineID string `json:\"machine_id\"`\n\n\t// The system uuid\n\tSystemUUID string `json:\"system_uuid\"`\n\n\t// The boot id\n\tBootID string `json:\"boot_id\"`\n\n\t// Filesystems on this machine.\n\tFilesystems []FsInfo `json:\"filesystems\"`\n\n\t// Disk map\n\tDiskMap map[string]DiskInfo `json:\"disk_map\"`\n\n\t// Network devices\n\tNetworkDevices []NetInfo `json:\"network_devices\"`\n\n\t// Machine Topology\n\t// Describes cpu/memory layout and hierarchy.\n\tTopology []Node `json:\"topology\"`\n\n\t// Cloud provider the machine belongs to.\n\tCloudProvider CloudProvider `json:\"cloud_provider\"`\n\n\t// Type of cloud instance (e.g. GCE standard) the machine is.\n\tInstanceType InstanceType `json:\"instance_type\"`\n\n\t// ID of cloud instance (e.g. instance-1) given to it by the cloud provider.\n\tInstanceID InstanceID `json:\"instance_id\"`\n}\n\nfunc (m *MachineInfo) Clone() *MachineInfo {\n\tmemoryByType := m.MemoryByType\n\tif len(m.MemoryByType) > 0 {\n\t\tmemoryByType = make(map[string]*MemoryInfo)\n\t\tfor memoryType, memoryInfo := range m.MemoryByType {\n\t\t\tmemoryByType[memoryType] = memoryInfo\n\t\t}\n\t}\n\tdiskMap := m.DiskMap\n\tif len(m.DiskMap) > 0 {\n\t\tdiskMap = make(map[string]DiskInfo)\n\t\tfor k, info := range m.DiskMap {\n\t\t\tdiskMap[k] = info\n\t\t}\n\t}\n\tcopy := MachineInfo{\n\t\tCPUVendorID:      m.CPUVendorID,\n\t\tTimestamp:        m.Timestamp,\n\t\tNumCores:         m.NumCores,\n\t\tNumPhysicalCores: m.NumPhysicalCores,\n\t\tNumSockets:       m.NumSockets,\n\t\tNumBooks:         m.NumBooks,\n\t\tNumDrawers:       m.NumDrawers,\n\t\tCpuFrequency:     m.CpuFrequency,\n\t\tMemoryCapacity:   m.MemoryCapacity,\n\t\tSwapCapacity:     m.SwapCapacity,\n\t\tMemoryByType:     memoryByType,\n\t\tNVMInfo:          m.NVMInfo,\n\t\tHugePages:        m.HugePages,\n\t\tMachineID:        m.MachineID,\n\t\tSystemUUID:       m.SystemUUID,\n\t\tBootID:           m.BootID,\n\t\tFilesystems:      m.Filesystems,\n\t\tDiskMap:          diskMap,\n\t\tNetworkDevices:   m.NetworkDevices,\n\t\tTopology:         m.Topology,\n\t\tCloudProvider:    m.CloudProvider,\n\t\tInstanceType:     m.InstanceType,\n\t\tInstanceID:       m.InstanceID,\n\t}\n\treturn &copy\n}\n\ntype MemoryInfo struct {\n\t// The amount of memory (in bytes).\n\tCapacity uint64 `json:\"capacity\"`\n\n\t// Number of memory DIMMs.\n\tDimmCount uint `json:\"dimm_count\"`\n}\n\ntype NVMInfo struct {\n\t// The total NVM capacity in bytes for memory mode.\n\tMemoryModeCapacity uint64 `json:\"memory_mode_capacity\"`\n\n\t//The total NVM capacity in bytes for app direct mode.\n\tAppDirectModeCapacity uint64 `json:\"app direct_mode_capacity\"`\n\n\t// Average power budget in watts for NVM devices configured in BIOS.\n\tAvgPowerBudget uint `json:\"avg_power_budget\"`\n}\n\ntype VersionInfo struct {\n\t// Kernel version.\n\tKernelVersion string `json:\"kernel_version\"`\n\n\t// OS image being used for cadvisor container, or host image if running on host directly.\n\tContainerOsVersion string `json:\"container_os_version\"`\n\n\t// Docker version.\n\tDockerVersion string `json:\"docker_version\"`\n\n\t// Docker API Version\n\tDockerAPIVersion string `json:\"docker_api_version\"`\n\n\t// cAdvisor version.\n\tCadvisorVersion string `json:\"cadvisor_version\"`\n\t// cAdvisor git revision.\n\tCadvisorRevision string `json:\"cadvisor_revision\"`\n}\n\ntype MachineInfoFactory interface {\n\tGetMachineInfo() (*MachineInfo, error)\n\tGetVersionInfo() (*VersionInfo, error)\n}\n"
  },
  {
    "path": "info/v1/machine_test.go",
    "content": "// Copyright 2023 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage v1\n\nimport (\n\t\"reflect\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/stretchr/testify/assert\"\n)\n\nfunc TestMachineInfoClone(t *testing.T) {\n\tmachineInfo := getFakeMachineInfo()\n\n\t// Make sure all fields are populated\n\tmachineInfoReflection := reflect.ValueOf(machineInfo)\n\tfor i := 0; i < machineInfoReflection.NumField(); i++ {\n\t\tassert.Falsef(t, machineInfoReflection.Field(i).IsZero(), \"field %s is not populated\", machineInfoReflection.Type().Field(i).Name)\n\t}\n\n\tclonedMachineInfo := *machineInfo.Clone()\n\tassert.Equal(t, machineInfo, clonedMachineInfo, \"cloned machine info should be equal to the original\")\n}\n\nfunc getFakeMachineInfo() MachineInfo {\n\treturn MachineInfo{\n\t\tTimestamp:        time.Now(),\n\t\tCPUVendorID:      \"fake-id\",\n\t\tNumCores:         1,\n\t\tNumPhysicalCores: 2,\n\t\tNumSockets:       3,\n\t\tNumBooks:         1,\n\t\tNumDrawers:       1,\n\t\tCpuFrequency:     4,\n\t\tMemoryCapacity:   5,\n\t\tSwapCapacity:     6,\n\t\tMemoryByType: map[string]*MemoryInfo{\n\t\t\t\"fake\": {Capacity: 2, DimmCount: 3},\n\t\t},\n\t\tNVMInfo: NVMInfo{\n\t\t\tMemoryModeCapacity:    2,\n\t\t\tAppDirectModeCapacity: 6,\n\t\t\tAvgPowerBudget:        3,\n\t\t},\n\t\tHugePages: []HugePagesInfo{{\n\t\t\tPageSize: 512,\n\t\t\tNumPages: 343,\n\t\t}},\n\t\tMachineID:  \"fake-machine-id\",\n\t\tSystemUUID: \"fake-uuid\",\n\t\tBootID:     \"fake-boot-id\",\n\t\tFilesystems: []FsInfo{{\n\t\t\tDevice:      \"dev\",\n\t\t\tDeviceMajor: 1,\n\t\t\tDeviceMinor: 2,\n\t\t\tCapacity:    3,\n\t\t\tType:        \"fake-type\",\n\t\t\tInodes:      4,\n\t\t\tHasInodes:   true,\n\t\t}},\n\t\tDiskMap: map[string]DiskInfo{\"fake-disk\": {\n\t\t\tName:      \"fake\",\n\t\t\tMajor:     1,\n\t\t\tMinor:     2,\n\t\t\tSize:      3,\n\t\t\tScheduler: \"sched\",\n\t\t}},\n\t\tNetworkDevices: []NetInfo{{\n\t\t\tName:       \"fake-net-info\",\n\t\t\tMacAddress: \"123\",\n\t\t\tSpeed:      2,\n\t\t\tMtu:        3,\n\t\t}},\n\t\tTopology: []Node{{\n\t\t\tId:     1,\n\t\t\tMemory: 2,\n\t\t}},\n\t\tCloudProvider: \"fake-provider\",\n\t\tInstanceType:  \"fake-instance-type\",\n\t\tInstanceID:    \"fake-instance-id\",\n\t}\n}\n"
  },
  {
    "path": "info/v1/metric.go",
    "content": "// Copyright 2015 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage v1\n\nimport (\n\t\"time\"\n)\n\n// Type of metric being exported.\ntype MetricType string\n\nconst (\n\t// Instantaneous value. May increase or decrease.\n\tMetricGauge MetricType = \"gauge\"\n\n\t// A counter-like value that is only expected to increase.\n\tMetricCumulative MetricType = \"cumulative\"\n)\n\n// DataType for metric being exported.\ntype DataType string\n\nconst (\n\tIntType   DataType = \"int\"\n\tFloatType DataType = \"float\"\n)\n\n// Spec for custom metric.\ntype MetricSpec struct {\n\t// The name of the metric.\n\tName string `json:\"name\"`\n\n\t// Type of the metric.\n\tType MetricType `json:\"type\"`\n\n\t// Data Type for the stats.\n\tFormat DataType `json:\"format\"`\n\n\t// Display Units for the stats.\n\tUnits string `json:\"units\"`\n}\n\n// An exported metric.\ntype MetricValBasic struct {\n\t// Time at which the metric was queried\n\tTimestamp time.Time `json:\"timestamp\"`\n\n\t// The value of the metric at this point.\n\tIntValue   int64   `json:\"int_value,omitempty\"`\n\tFloatValue float64 `json:\"float_value,omitempty\"`\n}\n\n// An exported metric.\ntype MetricVal struct {\n\t// Label associated with a metric\n\tLabel  string            `json:\"label,omitempty\"`\n\tLabels map[string]string `json:\"labels,omitempty\"`\n\n\t// Time at which the metric was queried\n\tTimestamp time.Time `json:\"timestamp\"`\n\n\t// The value of the metric at this point.\n\tIntValue   int64   `json:\"int_value,omitempty\"`\n\tFloatValue float64 `json:\"float_value,omitempty\"`\n}\n"
  },
  {
    "path": "info/v1/test/datagen.go",
    "content": "// Copyright 2014 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage test\n\nimport (\n\t\"fmt\"\n\t\"math/rand\"\n\t\"time\"\n\n\tinfo \"github.com/google/cadvisor/info/v1\"\n)\n\nfunc GenerateRandomStats(numStats, numCores int, duration time.Duration) []*info.ContainerStats {\n\tret := make([]*info.ContainerStats, numStats)\n\tperCoreUsages := make([]uint64, numCores)\n\tcurrentTime := time.Now()\n\tfor i := range perCoreUsages {\n\t\tperCoreUsages[i] = uint64(rand.Int63n(1000))\n\t}\n\tfor i := 0; i < numStats; i++ {\n\t\tstats := new(info.ContainerStats)\n\t\tstats.Timestamp = currentTime\n\t\tcurrentTime = currentTime.Add(duration)\n\n\t\tpercore := make([]uint64, numCores)\n\t\tfor i := range perCoreUsages {\n\t\t\tperCoreUsages[i] += uint64(rand.Int63n(1000))\n\t\t\tpercore[i] = perCoreUsages[i]\n\t\t\tstats.Cpu.Usage.Total += percore[i]\n\t\t}\n\t\tstats.Cpu.Usage.PerCpu = percore\n\t\tstats.Cpu.Usage.User = stats.Cpu.Usage.Total\n\t\tstats.Cpu.Usage.System = 0\n\t\tstats.Memory.Usage = uint64(rand.Int63n(4096))\n\t\tstats.Memory.Cache = uint64(rand.Int63n(4096))\n\t\tstats.Memory.RSS = uint64(rand.Int63n(4096))\n\t\tstats.Memory.MappedFile = uint64(rand.Int63n(4096))\n\t\tstats.Memory.KernelUsage = uint64(rand.Int63n(4096))\n\t\tstats.ReferencedMemory = uint64(rand.Int63n(1000))\n\t\tret[i] = stats\n\t}\n\treturn ret\n}\n\nfunc GenerateRandomContainerSpec(numCores int) info.ContainerSpec {\n\tret := info.ContainerSpec{\n\t\tCreationTime: time.Now(),\n\t\tHasCpu:       true,\n\t\tCpu:          info.CpuSpec{},\n\t\tHasMemory:    true,\n\t\tMemory:       info.MemorySpec{},\n\t}\n\tret.Cpu.Limit = uint64(1000 + rand.Int63n(2000))\n\tret.Cpu.MaxLimit = uint64(1000 + rand.Int63n(2000))\n\tret.Cpu.Mask = fmt.Sprintf(\"0-%d\", numCores-1)\n\tret.Memory.Limit = uint64(4096 + rand.Int63n(4096))\n\treturn ret\n}\n\nfunc GenerateRandomContainerInfo(containerName string, numCores int, query *info.ContainerInfoRequest, duration time.Duration) *info.ContainerInfo {\n\tstats := GenerateRandomStats(query.NumStats, numCores, duration)\n\tspec := GenerateRandomContainerSpec(numCores)\n\n\tret := &info.ContainerInfo{\n\t\tContainerReference: info.ContainerReference{\n\t\t\tName: containerName,\n\t\t},\n\t\tSpec:  spec,\n\t\tStats: stats,\n\t}\n\treturn ret\n}\n"
  },
  {
    "path": "info/v2/container.go",
    "content": "// Copyright 2015 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage v2\n\nimport (\n\t\"time\"\n\n\t// TODO(rjnagal): Remove dependency after moving all stats structs from v1.\n\t// using v1 now for easy conversion.\n\tv1 \"github.com/google/cadvisor/info/v1\"\n)\n\nconst (\n\tTypeName   = \"name\"\n\tTypeDocker = \"docker\"\n\tTypePodman = \"podman\"\n)\n\ntype CpuSpec struct {\n\t// Requested cpu shares. Default is 1024.\n\tLimit uint64 `json:\"limit\"`\n\t// Requested cpu hard limit. Default is unlimited (0).\n\t// Units: milli-cpus.\n\tMaxLimit uint64 `json:\"max_limit\"`\n\t// Cpu affinity mask.\n\t// TODO(rjnagal): Add a library to convert mask string to set of cpu bitmask.\n\tMask string `json:\"mask,omitempty\"`\n\t// CPUQuota Default is disabled\n\tQuota uint64 `json:\"quota,omitempty\"`\n\t// Period is the CPU reference time in ns e.g the quota is compared against this.\n\tPeriod uint64 `json:\"period,omitempty\"`\n}\n\ntype MemorySpec struct {\n\t// The amount of memory requested. Default is unlimited (-1).\n\t// Units: bytes.\n\tLimit uint64 `json:\"limit,omitempty\"`\n\n\t// The amount of guaranteed memory.  Default is 0.\n\t// Units: bytes.\n\tReservation uint64 `json:\"reservation,omitempty\"`\n\n\t// The amount of swap space requested. Default is unlimited (-1).\n\t// Units: bytes.\n\tSwapLimit uint64 `json:\"swap_limit,omitempty\"`\n}\n\ntype ContainerInfo struct {\n\t// Describes the container.\n\tSpec ContainerSpec `json:\"spec,omitempty\"`\n\n\t// Historical statistics gathered from the container.\n\tStats []*ContainerStats `json:\"stats,omitempty\"`\n}\n\ntype ContainerSpec struct {\n\t// Time at which the container was created.\n\tCreationTime time.Time `json:\"creation_time,omitempty\"`\n\n\t// Time at which the container was started.\n\t// This may be unset if the runtime does not provide it.\n\tStartTime time.Time `json:\"start_time,omitempty\"`\n\n\t// Other names by which the container is known within a certain namespace.\n\t// This is unique within that namespace.\n\tAliases []string `json:\"aliases,omitempty\"`\n\n\t// Namespace under which the aliases of a container are unique.\n\t// An example of a namespace is \"docker\" for Docker containers.\n\tNamespace string `json:\"namespace,omitempty\"`\n\n\t// Metadata labels associated with this container.\n\tLabels map[string]string `json:\"labels,omitempty\"`\n\t// Metadata envs associated with this container. Only whitelisted envs are added.\n\tEnvs map[string]string `json:\"envs,omitempty\"`\n\n\tHasCpu bool    `json:\"has_cpu\"`\n\tCpu    CpuSpec `json:\"cpu,omitempty\"`\n\n\tHasMemory bool       `json:\"has_memory\"`\n\tMemory    MemorySpec `json:\"memory,omitempty\"`\n\n\tHasHugetlb bool `json:\"has_hugetlb\"`\n\n\tHasCustomMetrics bool            `json:\"has_custom_metrics\"`\n\tCustomMetrics    []v1.MetricSpec `json:\"custom_metrics,omitempty\"`\n\n\tHasProcesses bool           `json:\"has_processes\"`\n\tProcesses    v1.ProcessSpec `json:\"processes,omitempty\"`\n\n\t// Following resources have no associated spec, but are being isolated.\n\tHasNetwork    bool `json:\"has_network\"`\n\tHasFilesystem bool `json:\"has_filesystem\"`\n\tHasDiskIo     bool `json:\"has_diskio\"`\n\n\t// Image name used for this container.\n\tImage string `json:\"image,omitempty\"`\n}\n\ntype DeprecatedContainerStats struct {\n\t// The time of this stat point.\n\tTimestamp time.Time `json:\"timestamp\"`\n\t// CPU statistics\n\tHasCpu bool `json:\"has_cpu\"`\n\t// In nanoseconds (aggregated)\n\tCpu v1.CpuStats `json:\"cpu,omitempty\"`\n\t// In nanocores per second (instantaneous)\n\tCpuInst *CpuInstStats `json:\"cpu_inst,omitempty\"`\n\t// Disk IO statistics\n\tHasDiskIo bool           `json:\"has_diskio\"`\n\tDiskIo    v1.DiskIoStats `json:\"diskio,omitempty\"`\n\t// Memory statistics\n\tHasMemory bool           `json:\"has_memory\"`\n\tMemory    v1.MemoryStats `json:\"memory,omitempty\"`\n\t// Hugepage statistics\n\tHasHugetlb bool                       `json:\"has_hugetlb\"`\n\tHugetlb    map[string]v1.HugetlbStats `json:\"hugetlb,omitempty\"`\n\t// Network statistics\n\tHasNetwork bool         `json:\"has_network\"`\n\tNetwork    NetworkStats `json:\"network,omitempty\"`\n\t// Processes statistics\n\tHasProcesses bool            `json:\"has_processes\"`\n\tProcesses    v1.ProcessStats `json:\"processes,omitempty\"`\n\t// Filesystem statistics\n\tHasFilesystem bool         `json:\"has_filesystem\"`\n\tFilesystem    []v1.FsStats `json:\"filesystem,omitempty\"`\n\t// Task load statistics\n\tHasLoad bool         `json:\"has_load\"`\n\tLoad    v1.LoadStats `json:\"load_stats,omitempty\"`\n\t// Custom Metrics\n\tHasCustomMetrics bool                      `json:\"has_custom_metrics\"`\n\tCustomMetrics    map[string][]v1.MetricVal `json:\"custom_metrics,omitempty\"`\n\t// Perf events counters\n\tPerfStats []v1.PerfStat `json:\"perf_stats,omitempty\"`\n\t// Statistics originating from perf uncore events.\n\t// Applies only for root container.\n\tPerfUncoreStats []v1.PerfUncoreStat `json:\"perf_uncore_stats,omitempty\"`\n\t// Referenced memory\n\tReferencedMemory uint64 `json:\"referenced_memory,omitempty\"`\n\t// Resource Control (resctrl) statistics\n\tResctrl v1.ResctrlStats `json:\"resctrl,omitempty\"`\n}\n\ntype ContainerStats struct {\n\t// The time of this stat point.\n\tTimestamp time.Time `json:\"timestamp\"`\n\t// CPU statistics\n\t// In nanoseconds (aggregated)\n\tCpu *v1.CpuStats `json:\"cpu,omitempty\"`\n\t// In nanocores per second (instantaneous)\n\tCpuInst *CpuInstStats `json:\"cpu_inst,omitempty\"`\n\t// Disk IO statistics\n\tDiskIo *v1.DiskIoStats `json:\"diskio,omitempty\"`\n\t// Memory statistics\n\tMemory *v1.MemoryStats `json:\"memory,omitempty\"`\n\t// Hugepage statistics\n\tHugetlb *map[string]v1.HugetlbStats `json:\"hugetlb,omitempty\"`\n\t// Network statistics\n\tNetwork *NetworkStats `json:\"network,omitempty\"`\n\t// Processes statistics\n\tProcesses *v1.ProcessStats `json:\"processes,omitempty\"`\n\t// Filesystem statistics\n\tFilesystem *FilesystemStats `json:\"filesystem,omitempty\"`\n\t// Task load statistics\n\tLoad *v1.LoadStats `json:\"load_stats,omitempty\"`\n\t// Metrics for Accelerators. Each Accelerator corresponds to one element in the array.\n\tAccelerators []v1.AcceleratorStats `json:\"accelerators,omitempty\"`\n\t// Custom Metrics\n\tCustomMetrics map[string][]v1.MetricVal `json:\"custom_metrics,omitempty\"`\n\t// Perf events counters\n\tPerfStats []v1.PerfStat `json:\"perf_stats,omitempty\"`\n\t// Statistics originating from perf uncore events.\n\t// Applies only for root container.\n\tPerfUncoreStats []v1.PerfUncoreStat `json:\"perf_uncore_stats,omitempty\"`\n\t// Referenced memory\n\tReferencedMemory uint64 `json:\"referenced_memory,omitempty\"`\n\t// Resource Control (resctrl) statistics\n\tResctrl v1.ResctrlStats `json:\"resctrl,omitempty\"`\n}\n\ntype Percentiles struct {\n\t// Indicates whether the stats are present or not.\n\t// If true, values below do not have any data.\n\tPresent bool `json:\"present\"`\n\t// Average over the collected sample.\n\tMean uint64 `json:\"mean\"`\n\t// Standard deviation of the collected sample.\n\tStd uint64 `json:\"std\"`\n\t// Max seen over the collected sample.\n\tMax uint64 `json:\"max\"`\n\t// 50th percentile over the collected sample.\n\tFifty uint64 `json:\"fifty\"`\n\t// 90th percentile over the collected sample.\n\tNinety uint64 `json:\"ninety\"`\n\t// 95th percentile over the collected sample.\n\tNinetyFive uint64 `json:\"ninetyfive\"`\n\t// Number of samples used to calculate these percentiles.\n\tCount uint64 `json:\"count\"`\n}\n\ntype Usage struct {\n\t// Indicates amount of data available [0-100].\n\t// If we have data for half a day, we'll still process DayUsage,\n\t// but set PercentComplete to 50.\n\tPercentComplete int32 `json:\"percent_complete\"`\n\t// Mean, Max, and 90p cpu rate value in milliCpus/seconds. Converted to milliCpus to avoid floats.\n\tCpu Percentiles `json:\"cpu\"`\n\t// Mean, Max, and 90p memory size in bytes.\n\tMemory Percentiles `json:\"memory\"`\n}\n\n// latest sample collected for a container.\ntype InstantUsage struct {\n\t// cpu rate in cpu milliseconds/second.\n\tCpu uint64 `json:\"cpu\"`\n\t// Memory usage in bytes.\n\tMemory uint64 `json:\"memory\"`\n}\n\ntype DerivedStats struct {\n\t// Time of generation of these stats.\n\tTimestamp time.Time `json:\"timestamp\"`\n\t// Latest instantaneous sample.\n\tLatestUsage InstantUsage `json:\"latest_usage\"`\n\t// Percentiles in last observed minute.\n\tMinuteUsage Usage `json:\"minute_usage\"`\n\t// Percentile in last hour.\n\tHourUsage Usage `json:\"hour_usage\"`\n\t// Percentile in last day.\n\tDayUsage Usage `json:\"day_usage\"`\n}\n\ntype FsInfo struct {\n\t// Time of generation of these stats.\n\tTimestamp time.Time `json:\"timestamp\"`\n\n\t// The block device name associated with the filesystem.\n\tDevice string `json:\"device\"`\n\n\t// Path where the filesystem is mounted.\n\tMountpoint string `json:\"mountpoint\"`\n\n\t// Filesystem usage in bytes.\n\tCapacity uint64 `json:\"capacity\"`\n\n\t// Bytes available for non-root use.\n\tAvailable uint64 `json:\"available\"`\n\n\t// Number of bytes used on this filesystem.\n\tUsage uint64 `json:\"usage\"`\n\n\t// Labels associated with this filesystem.\n\tLabels []string `json:\"labels\"`\n\n\t// Number of Inodes.\n\tInodes *uint64 `json:\"inodes,omitempty\"`\n\n\t// Number of available Inodes (if known)\n\tInodesFree *uint64 `json:\"inodes_free,omitempty\"`\n}\n\ntype RequestOptions struct {\n\t// Type of container identifier specified - TypeName (default) or TypeDocker\n\tIdType string `json:\"type\"`\n\t// Number of stats to return, -1 means no limit.\n\tCount int `json:\"count\"`\n\t// Whether to include stats for child subcontainers.\n\tRecursive bool `json:\"recursive\"`\n\t// Update stats if they are older than MaxAge\n\t// nil indicates no update, and 0 will always trigger an update.\n\tMaxAge *time.Duration `json:\"max_age\"`\n}\n\ntype ProcessInfo struct {\n\tUser          string  `json:\"user\"`\n\tPid           int     `json:\"pid\"`\n\tPpid          int     `json:\"parent_pid\"`\n\tStartTime     string  `json:\"start_time\"`\n\tPercentCpu    float32 `json:\"percent_cpu\"`\n\tPercentMemory float32 `json:\"percent_mem\"`\n\tRSS           uint64  `json:\"rss\"`\n\tVirtualSize   uint64  `json:\"virtual_size\"`\n\tStatus        string  `json:\"status\"`\n\tRunningTime   string  `json:\"running_time\"`\n\tCgroupPath    string  `json:\"cgroup_path\"`\n\tCmd           string  `json:\"cmd\"`\n\tFdCount       int     `json:\"fd_count\"`\n\tPsr           int     `json:\"psr\"`\n}\n\ntype TcpStat struct {\n\tEstablished uint64\n\tSynSent     uint64\n\tSynRecv     uint64\n\tFinWait1    uint64\n\tFinWait2    uint64\n\tTimeWait    uint64\n\tClose       uint64\n\tCloseWait   uint64\n\tLastAck     uint64\n\tListen      uint64\n\tClosing     uint64\n}\n\ntype NetworkStats struct {\n\t// Network stats by interface.\n\tInterfaces []v1.InterfaceStats `json:\"interfaces,omitempty\"`\n\t// TCP connection stats (Established, Listen...)\n\tTcp TcpStat `json:\"tcp\"`\n\t// TCP6 connection stats (Established, Listen...)\n\tTcp6 TcpStat `json:\"tcp6\"`\n\t// UDP connection stats\n\tUdp v1.UdpStat `json:\"udp\"`\n\t// UDP6 connection stats\n\tUdp6 v1.UdpStat `json:\"udp6\"`\n\t// TCP advanced stats\n\tTcpAdvanced v1.TcpAdvancedStat `json:\"tcp_advanced\"`\n}\n\n// Instantaneous CPU stats\ntype CpuInstStats struct {\n\tUsage CpuInstUsage `json:\"usage\"`\n}\n\n// CPU usage time statistics.\ntype CpuInstUsage struct {\n\t// Total CPU usage.\n\t// Units: nanocores per second\n\tTotal uint64 `json:\"total\"`\n\n\t// Per CPU/core usage of the container.\n\t// Unit: nanocores per second\n\tPerCpu []uint64 `json:\"per_cpu_usage,omitempty\"`\n\n\t// Time spent in user space.\n\t// Unit: nanocores per second\n\tUser uint64 `json:\"user\"`\n\n\t// Time spent in kernel space.\n\t// Unit: nanocores per second\n\tSystem uint64 `json:\"system\"`\n}\n\n// Filesystem usage statistics.\ntype FilesystemStats struct {\n\t// Total Number of bytes consumed by container.\n\tTotalUsageBytes *uint64 `json:\"totalUsageBytes,omitempty\"`\n\t// Number of bytes consumed by a container through its root filesystem.\n\tBaseUsageBytes *uint64 `json:\"baseUsageBytes,omitempty\"`\n\t// Number of inodes used within the container's root filesystem.\n\t// This only accounts for inodes that are shared across containers,\n\t// and does not include inodes used in mounted directories.\n\tInodeUsage *uint64 `json:\"containter_inode_usage,omitempty\"`\n}\n"
  },
  {
    "path": "info/v2/conversion.go",
    "content": "// Copyright 2015 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage v2\n\nimport (\n\t\"fmt\"\n\t\"time\"\n\n\t\"k8s.io/klog/v2\"\n\n\tv1 \"github.com/google/cadvisor/info/v1\"\n)\n\nfunc machineFsStatsFromV1(fsStats []v1.FsStats) []MachineFsStats {\n\tvar result []MachineFsStats\n\tfor i := range fsStats {\n\t\tstat := fsStats[i]\n\t\treadDuration := time.Millisecond * time.Duration(stat.ReadTime)\n\t\twriteDuration := time.Millisecond * time.Duration(stat.WriteTime)\n\t\tioDuration := time.Millisecond * time.Duration(stat.IoTime)\n\t\tweightedDuration := time.Millisecond * time.Duration(stat.WeightedIoTime)\n\t\tmachineFsStat := MachineFsStats{\n\t\t\tDevice:    stat.Device,\n\t\t\tType:      stat.Type,\n\t\t\tCapacity:  &stat.Limit,\n\t\t\tUsage:     &stat.Usage,\n\t\t\tAvailable: &stat.Available,\n\t\t\tDiskStats: DiskStats{\n\t\t\t\tReadsCompleted:     &stat.ReadsCompleted,\n\t\t\t\tReadsMerged:        &stat.ReadsMerged,\n\t\t\t\tSectorsRead:        &stat.SectorsRead,\n\t\t\t\tReadDuration:       &readDuration,\n\t\t\t\tWritesCompleted:    &stat.WritesCompleted,\n\t\t\t\tWritesMerged:       &stat.WritesMerged,\n\t\t\t\tSectorsWritten:     &stat.SectorsWritten,\n\t\t\t\tWriteDuration:      &writeDuration,\n\t\t\t\tIoInProgress:       &stat.IoInProgress,\n\t\t\t\tIoDuration:         &ioDuration,\n\t\t\t\tWeightedIoDuration: &weightedDuration,\n\t\t\t},\n\t\t}\n\t\tif stat.HasInodes {\n\t\t\tmachineFsStat.InodesFree = &stat.InodesFree\n\t\t}\n\t\tresult = append(result, machineFsStat)\n\t}\n\treturn result\n}\n\nfunc MachineStatsFromV1(cont *v1.ContainerInfo) []MachineStats {\n\tvar stats []MachineStats\n\tvar last *v1.ContainerStats\n\tfor i := range cont.Stats {\n\t\tval := cont.Stats[i]\n\t\tstat := MachineStats{\n\t\t\tTimestamp: val.Timestamp,\n\t\t}\n\t\tif cont.Spec.HasCpu {\n\t\t\tstat.Cpu = &val.Cpu\n\t\t\tcpuInst, err := InstCpuStats(last, val)\n\t\t\tif err != nil {\n\t\t\t\tklog.Warningf(\"Could not get instant cpu stats: %v\", err)\n\t\t\t} else {\n\t\t\t\tstat.CpuInst = cpuInst\n\t\t\t}\n\t\t\tlast = val\n\t\t}\n\t\tif cont.Spec.HasMemory {\n\t\t\tstat.Memory = &val.Memory\n\t\t}\n\t\tif cont.Spec.HasNetwork {\n\t\t\tstat.Network = &NetworkStats{\n\t\t\t\t// FIXME: Use reflection instead.\n\t\t\t\tTcp:        TcpStat(val.Network.Tcp),\n\t\t\t\tTcp6:       TcpStat(val.Network.Tcp6),\n\t\t\t\tInterfaces: val.Network.Interfaces,\n\t\t\t}\n\t\t}\n\t\tif cont.Spec.HasFilesystem {\n\t\t\tstat.Filesystem = machineFsStatsFromV1(val.Filesystem)\n\t\t}\n\t\t// TODO(rjnagal): Handle load stats.\n\t\tstats = append(stats, stat)\n\t}\n\treturn stats\n}\n\nfunc ContainerStatsFromV1(containerName string, spec *v1.ContainerSpec, stats []*v1.ContainerStats) []*ContainerStats {\n\tnewStats := make([]*ContainerStats, 0, len(stats))\n\tvar last *v1.ContainerStats\n\tfor _, val := range stats {\n\t\tstat := &ContainerStats{\n\t\t\tTimestamp:        val.Timestamp,\n\t\t\tReferencedMemory: val.ReferencedMemory,\n\t\t}\n\t\tif spec.HasCpu {\n\t\t\tstat.Cpu = &val.Cpu\n\t\t\tcpuInst, err := InstCpuStats(last, val)\n\t\t\tif err != nil {\n\t\t\t\tklog.Warningf(\"Could not get instant cpu stats: %v\", err)\n\t\t\t} else {\n\t\t\t\tstat.CpuInst = cpuInst\n\t\t\t}\n\t\t\tlast = val\n\t\t}\n\t\tif spec.HasMemory {\n\t\t\tstat.Memory = &val.Memory\n\t\t}\n\t\tif spec.HasHugetlb {\n\t\t\tstat.Hugetlb = &val.Hugetlb\n\t\t}\n\t\tif spec.HasNetwork {\n\t\t\t// TODO: Handle TcpStats\n\t\t\tstat.Network = &NetworkStats{\n\t\t\t\tTcp:        TcpStat(val.Network.Tcp),\n\t\t\t\tTcp6:       TcpStat(val.Network.Tcp6),\n\t\t\t\tInterfaces: val.Network.Interfaces,\n\t\t\t}\n\t\t}\n\t\tif spec.HasProcesses {\n\t\t\tstat.Processes = &val.Processes\n\t\t}\n\t\tif spec.HasFilesystem {\n\t\t\tif len(val.Filesystem) == 1 {\n\t\t\t\tstat.Filesystem = &FilesystemStats{\n\t\t\t\t\tTotalUsageBytes: &val.Filesystem[0].Usage,\n\t\t\t\t\tBaseUsageBytes:  &val.Filesystem[0].BaseUsage,\n\t\t\t\t\tInodeUsage:      &val.Filesystem[0].Inodes,\n\t\t\t\t}\n\t\t\t} else if len(val.Filesystem) > 1 && containerName != \"/\" {\n\t\t\t\t// Cannot handle multiple devices per container.\n\t\t\t\tklog.V(4).Infof(\"failed to handle multiple devices for container %s. Skipping Filesystem stats\", containerName)\n\t\t\t}\n\t\t}\n\t\tif spec.HasDiskIo {\n\t\t\tstat.DiskIo = &val.DiskIo\n\t\t}\n\t\tif spec.HasCustomMetrics {\n\t\t\tstat.CustomMetrics = val.CustomMetrics\n\t\t}\n\t\tif len(val.Accelerators) > 0 {\n\t\t\tstat.Accelerators = val.Accelerators\n\t\t}\n\t\tif len(val.PerfStats) > 0 {\n\t\t\tstat.PerfStats = val.PerfStats\n\t\t}\n\t\tif len(val.PerfUncoreStats) > 0 {\n\t\t\tstat.PerfUncoreStats = val.PerfUncoreStats\n\t\t}\n\t\tif len(val.Resctrl.MemoryBandwidth) > 0 || len(val.Resctrl.Cache) > 0 {\n\t\t\tstat.Resctrl = val.Resctrl\n\t\t}\n\t\t// TODO(rjnagal): Handle load stats.\n\t\tnewStats = append(newStats, stat)\n\t}\n\treturn newStats\n}\n\nfunc DeprecatedStatsFromV1(cont *v1.ContainerInfo) []DeprecatedContainerStats {\n\tstats := make([]DeprecatedContainerStats, 0, len(cont.Stats))\n\tvar last *v1.ContainerStats\n\tfor _, val := range cont.Stats {\n\t\tstat := DeprecatedContainerStats{\n\t\t\tTimestamp:        val.Timestamp,\n\t\t\tHasCpu:           cont.Spec.HasCpu,\n\t\t\tHasMemory:        cont.Spec.HasMemory,\n\t\t\tHasHugetlb:       cont.Spec.HasHugetlb,\n\t\t\tHasNetwork:       cont.Spec.HasNetwork,\n\t\t\tHasFilesystem:    cont.Spec.HasFilesystem,\n\t\t\tHasDiskIo:        cont.Spec.HasDiskIo,\n\t\t\tHasCustomMetrics: cont.Spec.HasCustomMetrics,\n\t\t\tReferencedMemory: val.ReferencedMemory,\n\t\t}\n\t\tif stat.HasCpu {\n\t\t\tstat.Cpu = val.Cpu\n\t\t\tcpuInst, err := InstCpuStats(last, val)\n\t\t\tif err != nil {\n\t\t\t\tklog.Warningf(\"Could not get instant cpu stats: %v\", err)\n\t\t\t} else {\n\t\t\t\tstat.CpuInst = cpuInst\n\t\t\t}\n\t\t\tlast = val\n\t\t}\n\t\tif stat.HasMemory {\n\t\t\tstat.Memory = val.Memory\n\t\t}\n\t\tif stat.HasHugetlb {\n\t\t\tstat.Hugetlb = val.Hugetlb\n\t\t}\n\t\tif stat.HasNetwork {\n\t\t\tstat.Network.Interfaces = val.Network.Interfaces\n\t\t}\n\t\tif stat.HasProcesses {\n\t\t\tstat.Processes = val.Processes\n\t\t}\n\t\tif stat.HasFilesystem {\n\t\t\tstat.Filesystem = val.Filesystem\n\t\t}\n\t\tif stat.HasDiskIo {\n\t\t\tstat.DiskIo = val.DiskIo\n\t\t}\n\t\tif stat.HasCustomMetrics {\n\t\t\tstat.CustomMetrics = val.CustomMetrics\n\t\t}\n\t\tif len(val.PerfStats) > 0 {\n\t\t\tstat.PerfStats = val.PerfStats\n\t\t}\n\t\tif len(val.PerfUncoreStats) > 0 {\n\t\t\tstat.PerfUncoreStats = val.PerfUncoreStats\n\t\t}\n\t\tif len(val.Resctrl.MemoryBandwidth) > 0 || len(val.Resctrl.Cache) > 0 {\n\t\t\tstat.Resctrl = val.Resctrl\n\t\t}\n\t\t// TODO(rjnagal): Handle load stats.\n\t\tstats = append(stats, stat)\n\t}\n\treturn stats\n}\n\nfunc InstCpuStats(last, cur *v1.ContainerStats) (*CpuInstStats, error) {\n\tif last == nil {\n\t\treturn nil, nil\n\t}\n\tif !cur.Timestamp.After(last.Timestamp) {\n\t\treturn nil, fmt.Errorf(\"container stats move backwards in time\")\n\t}\n\tif len(last.Cpu.Usage.PerCpu) != len(cur.Cpu.Usage.PerCpu) {\n\t\treturn nil, fmt.Errorf(\"different number of cpus\")\n\t}\n\ttimeDelta := cur.Timestamp.Sub(last.Timestamp)\n\t// Nanoseconds to gain precision and avoid having zero seconds if the\n\t// difference between the timestamps is just under a second\n\ttimeDeltaNs := uint64(timeDelta.Nanoseconds())\n\tconvertToRate := func(lastValue, curValue uint64) (uint64, error) {\n\t\tif curValue < lastValue {\n\t\t\treturn 0, fmt.Errorf(\"cumulative stats decrease\")\n\t\t}\n\t\tvalueDelta := curValue - lastValue\n\t\t// Use float64 to keep precision\n\t\treturn uint64(float64(valueDelta) / float64(timeDeltaNs) * 1e9), nil\n\t}\n\ttotal, err := convertToRate(last.Cpu.Usage.Total, cur.Cpu.Usage.Total)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tpercpu := make([]uint64, len(last.Cpu.Usage.PerCpu))\n\tfor i := range percpu {\n\t\tvar err error\n\t\tpercpu[i], err = convertToRate(last.Cpu.Usage.PerCpu[i], cur.Cpu.Usage.PerCpu[i])\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\tuser, err := convertToRate(last.Cpu.Usage.User, cur.Cpu.Usage.User)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tsystem, err := convertToRate(last.Cpu.Usage.System, cur.Cpu.Usage.System)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn &CpuInstStats{\n\t\tUsage: CpuInstUsage{\n\t\t\tTotal:  total,\n\t\t\tPerCpu: percpu,\n\t\t\tUser:   user,\n\t\t\tSystem: system,\n\t\t},\n\t}, nil\n}\n\n// Get V2 container spec from v1 container info.\nfunc ContainerSpecFromV1(specV1 *v1.ContainerSpec, aliases []string, namespace string) ContainerSpec {\n\tspecV2 := ContainerSpec{\n\t\tCreationTime:     specV1.CreationTime,\n\t\tStartTime:        specV1.StartTime,\n\t\tHasCpu:           specV1.HasCpu,\n\t\tHasMemory:        specV1.HasMemory,\n\t\tHasHugetlb:       specV1.HasHugetlb,\n\t\tHasFilesystem:    specV1.HasFilesystem,\n\t\tHasNetwork:       specV1.HasNetwork,\n\t\tHasProcesses:     specV1.HasProcesses,\n\t\tHasDiskIo:        specV1.HasDiskIo,\n\t\tHasCustomMetrics: specV1.HasCustomMetrics,\n\t\tImage:            specV1.Image,\n\t\tLabels:           specV1.Labels,\n\t\tEnvs:             specV1.Envs,\n\t}\n\tif specV1.HasCpu {\n\t\tspecV2.Cpu.Limit = specV1.Cpu.Limit\n\t\tspecV2.Cpu.MaxLimit = specV1.Cpu.MaxLimit\n\t\tspecV2.Cpu.Mask = specV1.Cpu.Mask\n\t}\n\tif specV1.HasMemory {\n\t\tspecV2.Memory.Limit = specV1.Memory.Limit\n\t\tspecV2.Memory.Reservation = specV1.Memory.Reservation\n\t\tspecV2.Memory.SwapLimit = specV1.Memory.SwapLimit\n\t}\n\tif specV1.HasCustomMetrics {\n\t\tspecV2.CustomMetrics = specV1.CustomMetrics\n\t}\n\tspecV2.Aliases = aliases\n\tspecV2.Namespace = namespace\n\treturn specV2\n}\n"
  },
  {
    "path": "info/v2/conversion_test.go",
    "content": "// Copyright 2016 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage v2\n\nimport (\n\t\"reflect\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/stretchr/testify/assert\"\n\n\tv1 \"github.com/google/cadvisor/info/v1\"\n)\n\nvar (\n\ttimestamp = time.Date(1987, time.August, 10, 0, 0, 0, 0, time.UTC)\n\tlabels    = map[string]string{\"foo\": \"bar\"}\n\tenvs      = map[string]string{\"foo\": \"bar\"}\n)\n\nfunc TestContainerSpecFromV1(t *testing.T) {\n\tstartTime := timestamp.Add(1 * time.Hour)\n\tv1Spec := v1.ContainerSpec{\n\t\tCreationTime: timestamp,\n\t\tStartTime:    startTime,\n\t\tLabels:       labels,\n\t\tEnvs:         envs,\n\t\tHasCpu:       true,\n\t\tCpu: v1.CpuSpec{\n\t\t\tLimit:    2048,\n\t\t\tMaxLimit: 4096,\n\t\t\tMask:     \"cpu_mask\",\n\t\t},\n\t\tHasMemory: true,\n\t\tMemory: v1.MemorySpec{\n\t\t\tLimit:       2048,\n\t\t\tReservation: 1024,\n\t\t\tSwapLimit:   8192,\n\t\t},\n\t\tHasHugetlb:       true,\n\t\tHasNetwork:       true,\n\t\tHasProcesses:     true,\n\t\tHasFilesystem:    true,\n\t\tHasDiskIo:        true,\n\t\tHasCustomMetrics: true,\n\t\tCustomMetrics: []v1.MetricSpec{{\n\t\t\tName:   \"foo\",\n\t\t\tType:   v1.MetricGauge,\n\t\t\tFormat: v1.IntType,\n\t\t\tUnits:  \"bars\",\n\t\t}},\n\t\tImage: \"gcr.io/kubernetes/kubernetes:v1\",\n\t}\n\n\taliases := []string{\"baz\", \"oof\"}\n\tnamespace := \"foo_bar_baz\"\n\n\texpectedV2Spec := ContainerSpec{\n\t\tCreationTime: timestamp,\n\t\tStartTime:    startTime,\n\t\tLabels:       labels,\n\t\tEnvs:         envs,\n\t\tHasCpu:       true,\n\t\tCpu: CpuSpec{\n\t\t\tLimit:    2048,\n\t\t\tMaxLimit: 4096,\n\t\t\tMask:     \"cpu_mask\",\n\t\t},\n\t\tHasMemory: true,\n\t\tMemory: MemorySpec{\n\t\t\tLimit:       2048,\n\t\t\tReservation: 1024,\n\t\t\tSwapLimit:   8192,\n\t\t},\n\t\tHasHugetlb:       true,\n\t\tHasNetwork:       true,\n\t\tHasProcesses:     true,\n\t\tHasFilesystem:    true,\n\t\tHasDiskIo:        true,\n\t\tHasCustomMetrics: true,\n\t\tCustomMetrics: []v1.MetricSpec{{\n\t\t\tName:   \"foo\",\n\t\t\tType:   v1.MetricGauge,\n\t\t\tFormat: v1.IntType,\n\t\t\tUnits:  \"bars\",\n\t\t}},\n\t\tImage:     \"gcr.io/kubernetes/kubernetes:v1\",\n\t\tAliases:   aliases,\n\t\tNamespace: namespace,\n\t}\n\n\tv2Spec := ContainerSpecFromV1(&v1Spec, aliases, namespace)\n\tif !reflect.DeepEqual(v2Spec, expectedV2Spec) {\n\t\tt.Errorf(\"Converted spec differs from expectation!\\nExpected: %+v\\n Got: %+v\\n\", expectedV2Spec, v2Spec)\n\t}\n}\n\nfunc TestContainerStatsFromV1(t *testing.T) {\n\tv1Spec := v1.ContainerSpec{\n\t\tCreationTime: timestamp,\n\t\tLabels:       labels,\n\t\tHasCpu:       true,\n\t\tCpu: v1.CpuSpec{\n\t\t\tLimit:    2048,\n\t\t\tMaxLimit: 4096,\n\t\t\tMask:     \"cpu_mask\",\n\t\t},\n\t\tHasMemory: true,\n\t\tMemory: v1.MemorySpec{\n\t\t\tLimit:       2048,\n\t\t\tReservation: 1024,\n\t\t\tSwapLimit:   8192,\n\t\t},\n\t\tHasHugetlb:       true,\n\t\tHasNetwork:       true,\n\t\tHasProcesses:     true,\n\t\tHasFilesystem:    true,\n\t\tHasDiskIo:        true,\n\t\tHasCustomMetrics: true,\n\t\tCustomMetrics: []v1.MetricSpec{{\n\t\t\tName:   \"foo\",\n\t\t\tType:   v1.MetricGauge,\n\t\t\tFormat: v1.IntType,\n\t\t\tUnits:  \"bars\",\n\t\t}},\n\t\tImage: \"gcr.io/kubernetes/kubernetes:v1\",\n\t}\n\tv1Stats := v1.ContainerStats{\n\t\tTimestamp: timestamp,\n\t\tMemory: v1.MemoryStats{\n\t\t\tUsage:             1,\n\t\t\tCache:             2,\n\t\t\tRSS:               3,\n\t\t\tWorkingSet:        4,\n\t\t\tFailcnt:           5,\n\t\t\tTotalActiveFile:   6,\n\t\t\tTotalInactiveFile: 7,\n\t\t\tContainerData: v1.MemoryStatsMemoryData{\n\t\t\t\tPgfault:    1,\n\t\t\t\tPgmajfault: 2,\n\t\t\t},\n\t\t\tHierarchicalData: v1.MemoryStatsMemoryData{\n\t\t\t\tPgfault:    10,\n\t\t\t\tPgmajfault: 20,\n\t\t\t},\n\t\t},\n\t\tNetwork: v1.NetworkStats{\n\t\t\tInterfaceStats: v1.InterfaceStats{\n\t\t\t\tName:      \"\",\n\t\t\t\tRxBytes:   1,\n\t\t\t\tRxPackets: 2,\n\t\t\t\tRxErrors:  3,\n\t\t\t\tRxDropped: 4,\n\t\t\t\tTxBytes:   5,\n\t\t\t\tTxPackets: 6,\n\t\t\t\tTxErrors:  7,\n\t\t\t\tTxDropped: 8,\n\t\t\t},\n\t\t\tInterfaces: []v1.InterfaceStats{{\n\t\t\t\tName:      \"eth0\",\n\t\t\t\tRxBytes:   10,\n\t\t\t\tRxPackets: 20,\n\t\t\t\tRxErrors:  30,\n\t\t\t\tRxDropped: 40,\n\t\t\t\tTxBytes:   50,\n\t\t\t\tTxPackets: 60,\n\t\t\t\tTxErrors:  70,\n\t\t\t\tTxDropped: 80,\n\t\t\t}},\n\t\t},\n\t\tProcesses: v1.ProcessStats{\n\t\t\tProcessCount:   5,\n\t\t\tFdCount:        1,\n\t\t\tThreadsCurrent: 66,\n\t\t\tThreadsMax:     6000,\n\t\t},\n\t\tFilesystem: []v1.FsStats{{\n\t\t\tDevice:     \"dev0\",\n\t\t\tLimit:      500,\n\t\t\tUsage:      100,\n\t\t\tBaseUsage:  50,\n\t\t\tAvailable:  300,\n\t\t\tInodesFree: 100,\n\t\t}},\n\t\tAccelerators: []v1.AcceleratorStats{{\n\t\t\tMake:        \"nvidia\",\n\t\t\tModel:       \"tesla-p100\",\n\t\t\tID:          \"GPU-deadbeef-1234-5678-90ab-feedfacecafe\",\n\t\t\tMemoryTotal: 20304050607,\n\t\t\tMemoryUsed:  2030405060,\n\t\t\tDutyCycle:   12,\n\t\t}},\n\t\tPerfStats: []v1.PerfStat{\n\t\t\t{\n\t\t\t\tPerfValue: v1.PerfValue{\n\t\t\t\t\tScalingRatio: 1,\n\t\t\t\t\tValue:        123,\n\t\t\t\t\tName:         \"instructions\",\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tPerfValue: v1.PerfValue{\n\t\t\t\t\tScalingRatio: 0.3333333,\n\t\t\t\t\tValue:        123456,\n\t\t\t\t\tName:         \"cycles\",\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\tPerfUncoreStats: []v1.PerfUncoreStat{\n\t\t\t{\n\t\t\t\tPerfValue: v1.PerfValue{\n\t\t\t\t\tScalingRatio: 1.0,\n\t\t\t\t\tValue:        123456,\n\t\t\t\t\tName:         \"uncore_imc_0/cas_count_write\",\n\t\t\t\t},\n\t\t\t\tSocket: 0,\n\t\t\t\tPMU:    \"17\",\n\t\t\t},\n\t\t\t{\n\t\t\t\tPerfValue: v1.PerfValue{\n\t\t\t\t\tScalingRatio: 1.0,\n\t\t\t\t\tValue:        654321,\n\t\t\t\t\tName:         \"uncore_imc_0/cas_count_write\",\n\t\t\t\t},\n\t\t\t\tSocket: 1,\n\t\t\t\tPMU:    \"17\",\n\t\t\t},\n\t\t},\n\t\tReferencedMemory: uint64(1234),\n\t\tResctrl: v1.ResctrlStats{\n\t\t\tMemoryBandwidth: []v1.MemoryBandwidthStats{\n\t\t\t\t{\n\t\t\t\t\tTotalBytes: 72312331,\n\t\t\t\t\tLocalBytes: 1233311,\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tTotalBytes: 32312331,\n\t\t\t\t\tLocalBytes: 2233311,\n\t\t\t\t},\n\t\t\t},\n\t\t\tCache: []v1.CacheStats{\n\t\t\t\t{\n\t\t\t\t\tLLCOccupancy: 123123441,\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tLLCOccupancy: 123313111,\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\texpectedV2Stats := ContainerStats{\n\t\tTimestamp: timestamp,\n\t\tCpu:       &v1Stats.Cpu,\n\t\tDiskIo:    &v1Stats.DiskIo,\n\t\tMemory:    &v1Stats.Memory,\n\t\tHugetlb:   &v1Stats.Hugetlb,\n\t\tProcesses: &v1Stats.Processes,\n\t\tNetwork: &NetworkStats{\n\t\t\tInterfaces: v1Stats.Network.Interfaces,\n\t\t},\n\t\tFilesystem: &FilesystemStats{\n\t\t\tTotalUsageBytes: &v1Stats.Filesystem[0].Usage,\n\t\t\tBaseUsageBytes:  &v1Stats.Filesystem[0].BaseUsage,\n\t\t\tInodeUsage:      &v1Stats.Filesystem[0].Inodes,\n\t\t},\n\t\tAccelerators:     v1Stats.Accelerators,\n\t\tPerfStats:        v1Stats.PerfStats,\n\t\tPerfUncoreStats:  v1Stats.PerfUncoreStats,\n\t\tReferencedMemory: v1Stats.ReferencedMemory,\n\t\tResctrl:          v1Stats.Resctrl,\n\t}\n\n\tv2Stats := ContainerStatsFromV1(\"test\", &v1Spec, []*v1.ContainerStats{&v1Stats})\n\tactualV2Stats := *v2Stats[0]\n\n\tif !reflect.DeepEqual(expectedV2Stats, actualV2Stats) {\n\t\tt.Errorf(\"Converted stats differs from expectation!\\nExpected: %+v\\n Got: %+v\\n\", expectedV2Stats, actualV2Stats)\n\t}\n}\n\nfunc TestInstCpuStats(t *testing.T) {\n\ttests := []struct {\n\t\tlast *v1.ContainerStats\n\t\tcur  *v1.ContainerStats\n\t\twant *CpuInstStats\n\t}{\n\t\t// Last is missing\n\t\t{\n\t\t\tnil,\n\t\t\t&v1.ContainerStats{},\n\t\t\tnil,\n\t\t},\n\t\t// Goes back in time\n\t\t{\n\t\t\t&v1.ContainerStats{\n\t\t\t\tTimestamp: time.Unix(100, 0).Add(time.Second),\n\t\t\t},\n\t\t\t&v1.ContainerStats{\n\t\t\t\tTimestamp: time.Unix(100, 0),\n\t\t\t},\n\t\t\tnil,\n\t\t},\n\t\t// Zero time delta\n\t\t{\n\t\t\t&v1.ContainerStats{\n\t\t\t\tTimestamp: time.Unix(100, 0),\n\t\t\t},\n\t\t\t&v1.ContainerStats{\n\t\t\t\tTimestamp: time.Unix(100, 0),\n\t\t\t},\n\t\t\tnil,\n\t\t},\n\t\t// Different number of cpus\n\t\t{\n\t\t\t&v1.ContainerStats{\n\t\t\t\tTimestamp: time.Unix(100, 0),\n\t\t\t\tCpu: v1.CpuStats{\n\t\t\t\t\tUsage: v1.CpuUsage{\n\t\t\t\t\t\tPerCpu: []uint64{100, 200},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\t&v1.ContainerStats{\n\t\t\t\tTimestamp: time.Unix(100, 0).Add(time.Second),\n\t\t\t\tCpu: v1.CpuStats{\n\t\t\t\t\tUsage: v1.CpuUsage{\n\t\t\t\t\t\tPerCpu: []uint64{100, 200, 300},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\tnil,\n\t\t},\n\t\t// Stat numbers decrease\n\t\t{\n\t\t\t&v1.ContainerStats{\n\t\t\t\tTimestamp: time.Unix(100, 0),\n\t\t\t\tCpu: v1.CpuStats{\n\t\t\t\t\tUsage: v1.CpuUsage{\n\t\t\t\t\t\tTotal:  300,\n\t\t\t\t\t\tPerCpu: []uint64{100, 200},\n\t\t\t\t\t\tUser:   250,\n\t\t\t\t\t\tSystem: 50,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\t&v1.ContainerStats{\n\t\t\t\tTimestamp: time.Unix(100, 0).Add(time.Second),\n\t\t\t\tCpu: v1.CpuStats{\n\t\t\t\t\tUsage: v1.CpuUsage{\n\t\t\t\t\t\tTotal:  200,\n\t\t\t\t\t\tPerCpu: []uint64{100, 100},\n\t\t\t\t\t\tUser:   150,\n\t\t\t\t\t\tSystem: 50,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\tnil,\n\t\t},\n\t\t// One second elapsed\n\t\t{\n\t\t\t&v1.ContainerStats{\n\t\t\t\tTimestamp: time.Unix(100, 0),\n\t\t\t\tCpu: v1.CpuStats{\n\t\t\t\t\tUsage: v1.CpuUsage{\n\t\t\t\t\t\tTotal:  300,\n\t\t\t\t\t\tPerCpu: []uint64{100, 200},\n\t\t\t\t\t\tUser:   250,\n\t\t\t\t\t\tSystem: 50,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\t&v1.ContainerStats{\n\t\t\t\tTimestamp: time.Unix(100, 0).Add(time.Second),\n\t\t\t\tCpu: v1.CpuStats{\n\t\t\t\t\tUsage: v1.CpuUsage{\n\t\t\t\t\t\tTotal:  500,\n\t\t\t\t\t\tPerCpu: []uint64{200, 300},\n\t\t\t\t\t\tUser:   400,\n\t\t\t\t\t\tSystem: 100,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\t&CpuInstStats{\n\t\t\t\tUsage: CpuInstUsage{\n\t\t\t\t\tTotal:  200,\n\t\t\t\t\tPerCpu: []uint64{100, 100},\n\t\t\t\t\tUser:   150,\n\t\t\t\t\tSystem: 50,\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t// Two seconds elapsed\n\t\t{\n\t\t\t&v1.ContainerStats{\n\t\t\t\tTimestamp: time.Unix(100, 0),\n\t\t\t\tCpu: v1.CpuStats{\n\t\t\t\t\tUsage: v1.CpuUsage{\n\t\t\t\t\t\tTotal:  300,\n\t\t\t\t\t\tPerCpu: []uint64{100, 200},\n\t\t\t\t\t\tUser:   250,\n\t\t\t\t\t\tSystem: 50,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\t&v1.ContainerStats{\n\t\t\t\tTimestamp: time.Unix(100, 0).Add(2 * time.Second),\n\t\t\t\tCpu: v1.CpuStats{\n\t\t\t\t\tUsage: v1.CpuUsage{\n\t\t\t\t\t\tTotal:  500,\n\t\t\t\t\t\tPerCpu: []uint64{200, 300},\n\t\t\t\t\t\tUser:   400,\n\t\t\t\t\t\tSystem: 100,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\t&CpuInstStats{\n\t\t\t\tUsage: CpuInstUsage{\n\t\t\t\t\tTotal:  100,\n\t\t\t\t\tPerCpu: []uint64{50, 50},\n\t\t\t\t\tUser:   75,\n\t\t\t\t\tSystem: 25,\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\tfor _, c := range tests {\n\t\tgot, err := InstCpuStats(c.last, c.cur)\n\t\tif err != nil {\n\t\t\tif c.want == nil {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tt.Errorf(\"Unexpected error: %v\", err)\n\t\t}\n\t\tassert.Equal(t, c.want, got)\n\t}\n}\n"
  },
  {
    "path": "info/v2/machine.go",
    "content": "// Copyright 2015 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage v2\n\nimport (\n\t// TODO(rjnagal): Move structs from v1.\n\t\"time\"\n\n\tv1 \"github.com/google/cadvisor/info/v1\"\n)\n\ntype Attributes struct {\n\t// Kernel version.\n\tKernelVersion string `json:\"kernel_version\"`\n\n\t// OS image being used for cadvisor container, or host image if running on host directly.\n\tContainerOsVersion string `json:\"container_os_version\"`\n\n\t// Docker version.\n\tDockerVersion string `json:\"docker_version\"`\n\n\t// Docker API version.\n\tDockerAPIVersion string `json:\"docker_api_version\"`\n\n\t// cAdvisor version.\n\tCadvisorVersion string `json:\"cadvisor_version\"`\n\n\t// The number of cores in this machine.\n\tNumCores int `json:\"num_cores\"`\n\n\t// Maximum clock speed for the cores, in KHz.\n\tCpuFrequency uint64 `json:\"cpu_frequency_khz\"`\n\n\t// The amount of memory (in bytes) in this machine\n\tMemoryCapacity uint64 `json:\"memory_capacity\"`\n\n\t// The machine id\n\tMachineID string `json:\"machine_id\"`\n\n\t// The system uuid\n\tSystemUUID string `json:\"system_uuid\"`\n\n\t// HugePages on this machine.\n\tHugePages []v1.HugePagesInfo `json:\"hugepages\"`\n\n\t// Filesystems on this machine.\n\tFilesystems []v1.FsInfo `json:\"filesystems\"`\n\n\t// Disk map\n\tDiskMap map[string]v1.DiskInfo `json:\"disk_map\"`\n\n\t// Network devices\n\tNetworkDevices []v1.NetInfo `json:\"network_devices\"`\n\n\t// Machine Topology\n\t// Describes cpu/memory layout and hierarchy.\n\tTopology []v1.Node `json:\"topology\"`\n\n\t// Cloud provider the machine belongs to\n\tCloudProvider v1.CloudProvider `json:\"cloud_provider\"`\n\n\t// Type of cloud instance (e.g. GCE standard) the machine is.\n\tInstanceType v1.InstanceType `json:\"instance_type\"`\n}\n\nfunc GetAttributes(mi *v1.MachineInfo, vi *v1.VersionInfo) Attributes {\n\treturn Attributes{\n\t\tKernelVersion:      vi.KernelVersion,\n\t\tContainerOsVersion: vi.ContainerOsVersion,\n\t\tDockerVersion:      vi.DockerVersion,\n\t\tDockerAPIVersion:   vi.DockerAPIVersion,\n\t\tCadvisorVersion:    vi.CadvisorVersion,\n\t\tNumCores:           mi.NumCores,\n\t\tCpuFrequency:       mi.CpuFrequency,\n\t\tMemoryCapacity:     mi.MemoryCapacity,\n\t\tMachineID:          mi.MachineID,\n\t\tSystemUUID:         mi.SystemUUID,\n\t\tHugePages:          mi.HugePages,\n\t\tFilesystems:        mi.Filesystems,\n\t\tDiskMap:            mi.DiskMap,\n\t\tNetworkDevices:     mi.NetworkDevices,\n\t\tTopology:           mi.Topology,\n\t\tCloudProvider:      mi.CloudProvider,\n\t\tInstanceType:       mi.InstanceType,\n\t}\n}\n\n// MachineStats contains usage statistics for the entire machine.\ntype MachineStats struct {\n\t// The time of this stat point.\n\tTimestamp time.Time `json:\"timestamp\"`\n\t// In nanoseconds (aggregated)\n\tCpu *v1.CpuStats `json:\"cpu,omitempty\"`\n\t// In nanocores per second (instantaneous)\n\tCpuInst *CpuInstStats `json:\"cpu_inst,omitempty\"`\n\t// Memory statistics\n\tMemory *v1.MemoryStats `json:\"memory,omitempty\"`\n\t// Network statistics\n\tNetwork *NetworkStats `json:\"network,omitempty\"`\n\t// Filesystem statistics\n\tFilesystem []MachineFsStats `json:\"filesystem,omitempty\"`\n\t// Task load statistics\n\tLoad *v1.LoadStats `json:\"load_stats,omitempty\"`\n}\n\n// MachineFsStats contains per filesystem capacity and usage information.\ntype MachineFsStats struct {\n\t// The block device name associated with the filesystem.\n\tDevice string `json:\"device\"`\n\n\t// Type of filesystem.\n\tType string `json:\"type\"`\n\n\t// Number of bytes that can be consumed on this filesystem.\n\tCapacity *uint64 `json:\"capacity,omitempty\"`\n\n\t// Number of bytes that is currently consumed on this filesystem.\n\tUsage *uint64 `json:\"usage,omitempty\"`\n\n\t// Number of bytes available for non-root user on this filesystem.\n\tAvailable *uint64 `json:\"available,omitempty\"`\n\n\t// Number of inodes that are available on this filesystem.\n\tInodesFree *uint64 `json:\"inodes_free,omitempty\"`\n\n\t// DiskStats for this device.\n\tDiskStats `json:\"inline\"`\n}\n\n// DiskStats contains per partition usage information.\n// This information is only available at the machine level.\ntype DiskStats struct {\n\t// Number of reads completed\n\t// This is the total number of reads completed successfully.\n\tReadsCompleted *uint64 `json:\"reads_completed,omitempty\"`\n\n\t// Number of reads merged\n\t// Reads and writes which are adjacent to each other may be merged for\n\t// efficiency.  Thus two 4K reads may become one 8K read before it is\n\t// ultimately handed to the disk, and so it will be counted (and queued)\n\t// as only one I/O.  This field lets you know how often this was done.\n\tReadsMerged *uint64 `json:\"reads_merged,omitempty\"`\n\n\t// Number of sectors read\n\t// This is the total number of sectors read successfully.\n\tSectorsRead *uint64 `json:\"sectors_read,omitempty\"`\n\n\t// Time spent reading\n\t// This is the total number of milliseconds spent by all reads (as\n\t// measured from __make_request() to end_that_request_last()).\n\tReadDuration *time.Duration `json:\"read_duration,omitempty\"`\n\n\t// Number of writes completed\n\t// This is the total number of writes completed successfully.\n\tWritesCompleted *uint64 `json:\"writes_completed,omitempty\"`\n\n\t// Number of writes merged\n\t// See the description of reads merged.\n\tWritesMerged *uint64 `json:\"writes_merged,omitempty\"`\n\n\t// Number of sectors written\n\t// This is the total number of sectors written successfully.\n\tSectorsWritten *uint64 `json:\"sectors_written,omitempty\"`\n\n\t// Time spent writing\n\t// This is the total number of milliseconds spent by all writes (as\n\t// measured from __make_request() to end_that_request_last()).\n\tWriteDuration *time.Duration `json:\"write_duration,omitempty\"`\n\n\t// Number of I/Os currently in progress\n\t// The only field that should go to zero. Incremented as requests are\n\t// given to appropriate struct request_queue and decremented as they finish.\n\tIoInProgress *uint64 `json:\"io_in_progress,omitempty\"`\n\n\t// Time spent doing I/Os\n\t// This field increases so long as field 9 is nonzero.\n\tIoDuration *time.Duration `json:\"io_duration,omitempty\"`\n\n\t// weighted time spent doing I/Os\n\t// This field is incremented at each I/O start, I/O completion, I/O\n\t// merge, or read of these stats by the number of I/Os in progress\n\t// (field 9) times the number of milliseconds spent doing I/O since the\n\t// last update of this field.  This can provide an easy measure of both\n\t// I/O completion time and the backlog that may be accumulating.\n\tWeightedIoDuration *time.Duration `json:\"weighted_io_duration,omitempty\"`\n}\n"
  },
  {
    "path": "integration/framework/framework.go",
    "content": "// Copyright 2014 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage framework\n\nimport (\n\t\"bytes\"\n\t\"encoding/json\"\n\t\"flag\"\n\t\"fmt\"\n\t\"os\"\n\t\"os/exec\"\n\t\"path/filepath\"\n\t\"strings\"\n\t\"testing\"\n\t\"time\"\n\n\t\"k8s.io/klog/v2\"\n\n\t\"github.com/google/cadvisor/client\"\n\tv2 \"github.com/google/cadvisor/client/v2\"\n)\n\nvar host = flag.String(\"host\", \"localhost\", \"Address of the host being tested\")\nvar port = flag.Int(\"port\", 8080, \"Port of the application on the host being tested\")\nvar sshOptions = flag.String(\"ssh-options\", \"\", \"Command line options for ssh\")\n\n// Integration test framework.\ntype Framework interface {\n\t// Clean the framework state.\n\tCleanup()\n\n\t// The testing.T used by the framework and the current test.\n\tT() *testing.T\n\n\t// Returns the hostname being tested.\n\tHostname() HostnameInfo\n\n\t// Returns the Docker actions for the test framework.\n\tDocker() DockerActions\n\n\t// Returns the CRI-O actions for the test framework.\n\tCrio() CrioActions\n\n\t// Returns the containerd actions for the test framework.\n\tContainerd() ContainerdActions\n\n\t// Returns the shell actions for the test framework.\n\tShell() ShellActions\n\n\t// Returns the cAdvisor actions for the test framework.\n\tCadvisor() CadvisorActions\n}\n\n// Instantiates a Framework. Cleanup *must* be called. Class is thread-compatible.\n// All framework actions report fatal errors on the t specified at creation time.\n//\n// Typical use:\n//\n//\tfunc TestFoo(t *testing.T) {\n//\t\tfm := framework.New(t)\n//\t\tdefer fm.Cleanup()\n//\t     ... actual test ...\n//\t}\nfunc New(t *testing.T) Framework {\n\t// All integration tests are large.\n\tif testing.Short() {\n\t\tt.Skip(\"Skipping framework test in short mode\")\n\t}\n\n\t// Try to see if non-localhost hosts are GCE instances.\n\tfm := &realFramework{\n\t\thostname: HostnameInfo{\n\t\t\tHost: *host,\n\t\t\tPort: *port,\n\t\t},\n\t\tt:        t,\n\t\tcleanups: make([]func(), 0),\n\t}\n\tfm.shellActions = shellActions{\n\t\tfm: fm,\n\t}\n\tfm.dockerActions = dockerActions{\n\t\tfm: fm,\n\t}\n\tfm.crioActions = crioActions{\n\t\tfm:        fm,\n\t\tpodSeqNum: 0,\n\t}\n\tfm.containerdActions = containerdActions{\n\t\tfm:          fm,\n\t\tseqNum:      0,\n\t\tnamespace:   \"k8s.io\",\n\t\tsocket:      getContainerdSocket(),\n\t\tsnapshotter: \"native\",\n\t}\n\n\treturn fm\n}\n\n// getContainerdSocket returns the containerd socket path from CONTAINERD_SOCK env var.\nfunc getContainerdSocket() string {\n\tif sock := os.Getenv(\"CONTAINERD_SOCK\"); sock != \"\" {\n\t\treturn sock\n\t}\n\treturn \"/run/containerd/containerd.sock\"\n}\n\nconst (\n\tAufs         string = \"aufs\"\n\tOverlay      string = \"overlay\"\n\tOverlay2     string = \"overlay2\"\n\tDeviceMapper string = \"devicemapper\"\n\tUnknown      string = \"\"\n)\n\ntype DockerActions interface {\n\t// Run the no-op pause Docker container and return its ID.\n\tRunPause() string\n\n\t// Run the specified command in a Docker busybox container and return its ID.\n\tRunBusybox(cmd ...string) string\n\n\t// Runs a Docker container in the background. Uses the specified DockerRunArgs and command.\n\t// Returns the ID of the new container.\n\t//\n\t// e.g.:\n\t// Run(DockerRunArgs{Image: \"busybox\"}, \"ping\", \"www.google.com\")\n\t//   -> docker run busybox ping www.google.com\n\tRun(args DockerRunArgs, cmd ...string) string\n\tRunStress(args DockerRunArgs, cmd ...string) string\n\n\tVersion() []string\n\tStorageDriver() string\n}\n\n// CrioActions provides methods for managing CRI-O containers in tests.\n// CRI-O containers run inside pod sandboxes, so each container requires\n// a pod to be created first.\ntype CrioActions interface {\n\t// Run the no-op pause CRI-O container and return its ID.\n\tRunPause() string\n\n\t// Run the specified command in a CRI-O busybox container and return its ID.\n\tRunBusybox(cmd ...string) string\n\n\t// Runs a CRI-O container in the background. Uses the specified CrioRunArgs and command.\n\t// Returns the ID of the new container.\n\tRun(args CrioRunArgs, cmd ...string) string\n}\n\n// CrioRunArgs contains arguments for running a CRI-O container.\ntype CrioRunArgs struct {\n\t// Image to use.\n\tImage string\n\n\t// Container name (optional, auto-generated if empty).\n\tName string\n}\n\n// ContainerdActions provides methods for managing containerd containers in tests.\n// Containerd containers are created directly using the ctr CLI tool.\ntype ContainerdActions interface {\n\t// Run the no-op pause containerd container and return its ID.\n\tRunPause() string\n\n\t// Run the specified command in a containerd busybox container and return its ID.\n\tRunBusybox(cmd ...string) string\n\n\t// Runs a containerd container in the background. Uses the specified ContainerdRunArgs and command.\n\t// Returns the ID of the new container.\n\tRun(args ContainerdRunArgs, cmd ...string) string\n}\n\n// ContainerdRunArgs contains arguments for running a containerd container.\ntype ContainerdRunArgs struct {\n\t// Image to use.\n\tImage string\n\n\t// Container name (optional, auto-generated if empty).\n\tName string\n\n\t// Labels to add to the container.\n\tLabels map[string]string\n}\n\ntype ShellActions interface {\n\t// Runs a specified command and arguments. Returns the stdout and stderr.\n\tRun(cmd string, args ...string) (string, string)\n\tRunStress(cmd string, args ...string) (string, string)\n}\n\ntype CadvisorActions interface {\n\t// Returns a cAdvisor client to the machine being tested.\n\tClient() *client.Client\n\tClientV2() *v2.Client\n}\n\ntype realFramework struct {\n\thostname         HostnameInfo\n\tt                *testing.T\n\tcadvisorClient   *client.Client\n\tcadvisorClientV2 *v2.Client\n\n\tshellActions      shellActions\n\tdockerActions     dockerActions\n\tcrioActions       crioActions\n\tcontainerdActions containerdActions\n\n\t// Cleanup functions to call on Cleanup()\n\tcleanups []func()\n}\n\ntype shellActions struct {\n\tfm *realFramework\n}\n\ntype dockerActions struct {\n\tfm *realFramework\n}\n\ntype crioActions struct {\n\tfm        *realFramework\n\tpodSeqNum int // For generating unique pod names\n}\n\ntype containerdActions struct {\n\tfm          *realFramework\n\tseqNum      int    // For generating unique container names\n\tnamespace   string // containerd namespace (default: k8s.io)\n\tsocket      string // containerd socket path\n\tsnapshotter string // containerd snapshotter (default: native)\n}\n\ntype HostnameInfo struct {\n\tHost string\n\tPort int\n}\n\n// Returns: http://<host>:<port>/\nfunc (h HostnameInfo) FullHostname() string {\n\treturn fmt.Sprintf(\"http://%s:%d/\", h.Host, h.Port)\n}\n\nfunc (f *realFramework) T() *testing.T {\n\treturn f.t\n}\n\nfunc (f *realFramework) Hostname() HostnameInfo {\n\treturn f.hostname\n}\n\nfunc (f *realFramework) Shell() ShellActions {\n\treturn f.shellActions\n}\n\nfunc (f *realFramework) Docker() DockerActions {\n\treturn f.dockerActions\n}\n\nfunc (f *realFramework) Crio() CrioActions {\n\treturn &f.crioActions\n}\n\nfunc (f *realFramework) Containerd() ContainerdActions {\n\treturn &f.containerdActions\n}\n\nfunc (f *realFramework) Cadvisor() CadvisorActions {\n\treturn f\n}\n\n// Call all cleanup functions.\nfunc (f *realFramework) Cleanup() {\n\tfor _, cleanupFunc := range f.cleanups {\n\t\tcleanupFunc()\n\t}\n}\n\n// Gets a client to the cAdvisor being tested.\nfunc (f *realFramework) Client() *client.Client {\n\tif f.cadvisorClient == nil {\n\t\tcadvisorClient, err := client.NewClient(f.Hostname().FullHostname())\n\t\tif err != nil {\n\t\t\tf.t.Fatalf(\"Failed to instantiate the cAdvisor client: %v\", err)\n\t\t}\n\t\tf.cadvisorClient = cadvisorClient\n\t}\n\treturn f.cadvisorClient\n}\n\n// Gets a v2 client to the cAdvisor being tested.\nfunc (f *realFramework) ClientV2() *v2.Client {\n\tif f.cadvisorClientV2 == nil {\n\t\tcadvisorClientV2, err := v2.NewClient(f.Hostname().FullHostname())\n\t\tif err != nil {\n\t\t\tf.t.Fatalf(\"Failed to instantiate the cAdvisor client: %v\", err)\n\t\t}\n\t\tf.cadvisorClientV2 = cadvisorClientV2\n\t}\n\treturn f.cadvisorClientV2\n}\n\nfunc (a dockerActions) RunPause() string {\n\treturn a.Run(DockerRunArgs{\n\t\tImage: \"registry.k8s.io/pause\",\n\t})\n}\n\n// Run the specified command in a Docker busybox container.\nfunc (a dockerActions) RunBusybox(cmd ...string) string {\n\treturn a.Run(DockerRunArgs{\n\t\tImage: \"registry.k8s.io/busybox:1.27\",\n\t}, cmd...)\n}\n\ntype DockerRunArgs struct {\n\t// Image to use.\n\tImage string\n\n\t// Arguments to the Docker CLI.\n\tArgs []string\n\n\tInnerArgs []string\n}\n\n// TODO(vmarmol): Use the Docker remote API.\n// TODO(vmarmol): Refactor a set of \"RunCommand\" actions.\n// Runs a Docker container in the background. Uses the specified DockerRunArgs and command.\n//\n// e.g.:\n// RunDockerContainer(DockerRunArgs{Image: \"busybox\"}, \"ping\", \"www.google.com\")\n//\n//\t-> docker run busybox ping www.google.com\nfunc (a dockerActions) Run(args DockerRunArgs, cmd ...string) string {\n\tdockerCommand := append(append([]string{\"docker\", \"run\", \"-d\"}, args.Args...), args.Image)\n\tdockerCommand = append(dockerCommand, cmd...)\n\toutput, _ := a.fm.Shell().Run(\"sudo\", dockerCommand...)\n\n\t// The last line is the container ID.\n\telements := strings.Fields(output)\n\tcontainerID := elements[len(elements)-1]\n\n\ta.fm.cleanups = append(a.fm.cleanups, func() {\n\t\ta.fm.Shell().Run(\"sudo\", \"docker\", \"rm\", \"-f\", containerID)\n\t})\n\treturn containerID\n}\nfunc (a dockerActions) Version() []string {\n\tdockerCommand := []string{\"docker\", \"version\", \"-f\", \"'{{.Server.Version}}'\"}\n\toutput, _ := a.fm.Shell().Run(\"sudo\", dockerCommand...)\n\toutput = strings.TrimSpace(output)\n\tret := strings.Split(output, \".\")\n\tif len(ret) != 3 {\n\t\ta.fm.T().Fatalf(\"invalid version %v\", output)\n\t}\n\treturn ret\n}\n\nfunc (a dockerActions) StorageDriver() string {\n\tdockerCommand := []string{\"docker\", \"info\"}\n\toutput, _ := a.fm.Shell().Run(\"sudo\", dockerCommand...)\n\tif len(output) < 1 {\n\t\ta.fm.T().Fatalf(\"failed to find docker storage driver - %v\", output)\n\t}\n\tfor _, line := range strings.Split(output, \"\\n\") {\n\t\tline = strings.TrimSpace(line)\n\t\tif strings.HasPrefix(line, \"Storage Driver: \") {\n\t\t\tidx := strings.LastIndex(line, \": \") + 2\n\t\t\tdriver := line[idx:]\n\t\t\tswitch driver {\n\t\t\tcase Aufs, Overlay, Overlay2, DeviceMapper:\n\t\t\t\treturn driver\n\t\t\tdefault:\n\t\t\t\treturn Unknown\n\t\t\t}\n\t\t}\n\t}\n\ta.fm.T().Fatalf(\"failed to find docker storage driver from info - %v\", output)\n\treturn Unknown\n}\n\nfunc (a dockerActions) RunStress(args DockerRunArgs, cmd ...string) string {\n\tdockerCommand := append(append(append(append([]string{\"docker\", \"run\", \"-m=4M\", \"-d\", \"-t\", \"-i\"}, args.Args...), args.Image), args.InnerArgs...), cmd...)\n\n\toutput, _ := a.fm.Shell().RunStress(\"sudo\", dockerCommand...)\n\n\t// The last line is the container ID.\n\tif len(output) < 1 {\n\t\ta.fm.T().Fatalf(\"need 1 arguments in output %v to get the name but have %v\", output, len(output))\n\t}\n\telements := strings.Fields(output)\n\tcontainerID := elements[len(elements)-1]\n\n\ta.fm.cleanups = append(a.fm.cleanups, func() {\n\t\ta.fm.Shell().Run(\"sudo\", \"docker\", \"rm\", \"-f\", containerID)\n\t})\n\treturn containerID\n}\n\nfunc (a shellActions) wrapSSH(command string, args ...string) *exec.Cmd {\n\tcmd := []string{a.fm.Hostname().Host, \"--\", \"sh\", \"-c\", \"\\\"\", command}\n\tcmd = append(cmd, args...)\n\tcmd = append(cmd, \"\\\"\")\n\tif *sshOptions != \"\" {\n\t\tcmd = append(strings.Split(*sshOptions, \" \"), cmd...)\n\t}\n\treturn exec.Command(\"ssh\", cmd...)\n}\n\nfunc (a shellActions) Run(command string, args ...string) (string, string) {\n\tvar cmd *exec.Cmd\n\tif a.fm.Hostname().Host == \"localhost\" {\n\t\t// Just run locally.\n\t\tcmd = exec.Command(command, args...)\n\t} else {\n\t\t// We must SSH to the remote machine and run the command.\n\t\tcmd = a.wrapSSH(command, args...)\n\t}\n\tvar stdout bytes.Buffer\n\tvar stderr bytes.Buffer\n\tcmd.Stdout = &stdout\n\tcmd.Stderr = &stderr\n\tklog.Infof(\"About to run - %v\", cmd.Args)\n\terr := cmd.Run()\n\tif err != nil {\n\t\ta.fm.T().Fatalf(\"Failed to run %q %v in %q with error: %q. Stdout: %q, Stderr: %s\", command, args, a.fm.Hostname().Host, err, stdout.String(), stderr.String())\n\t\treturn \"\", \"\"\n\t}\n\treturn stdout.String(), stderr.String()\n}\n\nfunc (a shellActions) RunStress(command string, args ...string) (string, string) {\n\tvar cmd *exec.Cmd\n\tif a.fm.Hostname().Host == \"localhost\" {\n\t\t// Just run locally.\n\t\tcmd = exec.Command(command, args...)\n\t} else {\n\t\t// We must SSH to the remote machine and run the command.\n\t\tcmd = a.wrapSSH(command, args...)\n\t}\n\tvar stdout bytes.Buffer\n\tvar stderr bytes.Buffer\n\tcmd.Stdout = &stdout\n\tcmd.Stderr = &stderr\n\terr := cmd.Run()\n\tif err != nil {\n\t\ta.fm.T().Logf(\"Ran %q %v in %q and received error: %q. Stdout: %q, Stderr: %s\", command, args, a.fm.Hostname().Host, err, stdout.String(), stderr.String())\n\t\treturn stdout.String(), stderr.String()\n\t}\n\treturn stdout.String(), stderr.String()\n}\n\n// Runs retryFunc until no error is returned. After dur time the last error is returned.\n// Note that the function does not timeout the execution of retryFunc when the limit is reached.\nfunc RetryForDuration(retryFunc func() error, dur time.Duration) error {\n\twaitUntil := time.Now().Add(dur)\n\tvar err error\n\tfor time.Now().Before(waitUntil) {\n\t\terr = retryFunc()\n\t\tif err == nil {\n\t\t\treturn nil\n\t\t}\n\t}\n\treturn err\n}\n\n// CRI-O pod sandbox configuration for crictl\ntype crioPodConfig struct {\n\tMetadata struct {\n\t\tName      string `json:\"name\"`\n\t\tNamespace string `json:\"namespace\"`\n\t\tUID       string `json:\"uid\"`\n\t} `json:\"metadata\"`\n\tLinux struct{} `json:\"linux\"`\n}\n\n// CRI-O container configuration for crictl\ntype crioContainerConfig struct {\n\tMetadata struct {\n\t\tName string `json:\"name\"`\n\t} `json:\"metadata\"`\n\tImage struct {\n\t\tImage string `json:\"image\"`\n\t} `json:\"image\"`\n\tCommand []string `json:\"command,omitempty\"`\n\tArgs    []string `json:\"args,omitempty\"`\n\tLinux   struct{} `json:\"linux\"`\n}\n\nfunc (a *crioActions) RunPause() string {\n\treturn a.Run(CrioRunArgs{\n\t\tImage: \"registry.k8s.io/pause:3.9\",\n\t})\n}\n\nfunc (a *crioActions) RunBusybox(cmd ...string) string {\n\treturn a.Run(CrioRunArgs{\n\t\tImage: \"registry.k8s.io/busybox:1.27\",\n\t}, cmd...)\n}\n\nfunc (a *crioActions) Run(args CrioRunArgs, cmd ...string) string {\n\t// Generate unique names for pod and container\n\ta.podSeqNum++\n\tpodName := fmt.Sprintf(\"test-pod-%d-%d\", os.Getpid(), a.podSeqNum)\n\tcontainerName := args.Name\n\tif containerName == \"\" {\n\t\tcontainerName = fmt.Sprintf(\"test-container-%d-%d\", os.Getpid(), a.podSeqNum)\n\t}\n\n\t// Create temporary directory for config files\n\ttmpDir, err := os.MkdirTemp(\"\", \"crio-test-\")\n\tif err != nil {\n\t\ta.fm.T().Fatalf(\"Failed to create temp directory: %v\", err)\n\t}\n\n\t// Create pod config JSON\n\tpodConfig := crioPodConfig{}\n\tpodConfig.Metadata.Name = podName\n\tpodConfig.Metadata.Namespace = \"default\"\n\tpodConfig.Metadata.UID = fmt.Sprintf(\"uid-%d-%d\", os.Getpid(), a.podSeqNum)\n\n\tpodConfigPath := filepath.Join(tmpDir, \"pod-config.json\")\n\tpodConfigData, err := json.Marshal(podConfig)\n\tif err != nil {\n\t\ta.fm.T().Fatalf(\"Failed to marshal pod config: %v\", err)\n\t}\n\tif err := os.WriteFile(podConfigPath, podConfigData, 0644); err != nil {\n\t\ta.fm.T().Fatalf(\"Failed to write pod config: %v\", err)\n\t}\n\n\t// Create container config JSON\n\tcontainerConfig := crioContainerConfig{}\n\tcontainerConfig.Metadata.Name = containerName\n\tcontainerConfig.Image.Image = args.Image\n\tif len(cmd) > 0 {\n\t\tcontainerConfig.Command = cmd[:1]\n\t\tif len(cmd) > 1 {\n\t\t\tcontainerConfig.Args = cmd[1:]\n\t\t}\n\t}\n\n\tcontainerConfigPath := filepath.Join(tmpDir, \"container-config.json\")\n\tcontainerConfigData, err := json.Marshal(containerConfig)\n\tif err != nil {\n\t\ta.fm.T().Fatalf(\"Failed to marshal container config: %v\", err)\n\t}\n\tif err := os.WriteFile(containerConfigPath, containerConfigData, 0644); err != nil {\n\t\ta.fm.T().Fatalf(\"Failed to write container config: %v\", err)\n\t}\n\n\t// Pull the image first\n\tklog.Infof(\"Pulling image %s\", args.Image)\n\ta.fm.Shell().Run(\"sudo\", \"crictl\", \"pull\", args.Image)\n\n\t// Create pod sandbox\n\tklog.Infof(\"Creating pod sandbox %s\", podName)\n\tpodOutput, _ := a.fm.Shell().Run(\"sudo\", \"crictl\", \"runp\", podConfigPath)\n\tpodID := strings.TrimSpace(podOutput)\n\tif podID == \"\" {\n\t\ta.fm.T().Fatalf(\"Failed to create pod sandbox, got empty pod ID\")\n\t}\n\tklog.Infof(\"Created pod sandbox with ID: %s\", podID)\n\n\t// Create container\n\tklog.Infof(\"Creating container %s in pod %s\", containerName, podID)\n\tcontainerOutput, _ := a.fm.Shell().Run(\"sudo\", \"crictl\", \"create\", podID, containerConfigPath, podConfigPath)\n\tcontainerID := strings.TrimSpace(containerOutput)\n\tif containerID == \"\" {\n\t\ta.fm.T().Fatalf(\"Failed to create container, got empty container ID\")\n\t}\n\tklog.Infof(\"Created container with ID: %s\", containerID)\n\n\t// Start container\n\tklog.Infof(\"Starting container %s\", containerID)\n\ta.fm.Shell().Run(\"sudo\", \"crictl\", \"start\", containerID)\n\n\t// Register cleanup function (in reverse order: container first, then pod)\n\ta.fm.cleanups = append(a.fm.cleanups, func() {\n\t\tklog.Infof(\"Cleaning up container %s and pod %s\", containerID, podID)\n\t\t// Stop and remove container\n\t\ta.fm.Shell().Run(\"sudo\", \"crictl\", \"stop\", containerID)\n\t\ta.fm.Shell().Run(\"sudo\", \"crictl\", \"rm\", containerID)\n\t\t// Stop and remove pod\n\t\ta.fm.Shell().Run(\"sudo\", \"crictl\", \"stopp\", podID)\n\t\ta.fm.Shell().Run(\"sudo\", \"crictl\", \"rmp\", podID)\n\t\t// Clean up temp directory\n\t\tos.RemoveAll(tmpDir)\n\t})\n\n\treturn containerID\n}\n\n// Containerd actions implementation\n\nfunc (a *containerdActions) RunPause() string {\n\treturn a.Run(ContainerdRunArgs{\n\t\tImage: \"registry.k8s.io/pause:3.9\",\n\t})\n}\n\nfunc (a *containerdActions) RunBusybox(cmd ...string) string {\n\treturn a.Run(ContainerdRunArgs{\n\t\tImage: \"registry.k8s.io/busybox:1.27\",\n\t}, cmd...)\n}\n\n// Run creates and starts a containerd container using the ctr CLI.\n// It uses the configured namespace (default \"moby\" for Docker-in-Docker environments).\nfunc (a *containerdActions) Run(args ContainerdRunArgs, cmd ...string) string {\n\ta.seqNum++\n\tcontainerName := args.Name\n\tif containerName == \"\" {\n\t\t// Generate a unique 64-char hex container ID\n\t\t// cAdvisor's containerd handler expects container IDs to match this format\n\t\t// Use timestamp in nanoseconds to ensure uniqueness across test runs\n\t\tcontainerName = fmt.Sprintf(\"%016x%016x%016x%016x\", os.Getpid(), a.seqNum, time.Now().UnixNano(), time.Now().UnixNano()%1000000)\n\t}\n\n\t// Build the ctr command\n\t// ctr -a <socket> -n <namespace> run -d <image> <container-id> [cmd...]\n\tctrArgs := []string{\n\t\t\"ctr\",\n\t\t\"--address\", a.socket,\n\t\t\"--namespace\", a.namespace,\n\t}\n\n\t// Pull the image first\n\tklog.Infof(\"Pulling containerd image %s\", args.Image)\n\tpullArgs := append(ctrArgs, \"image\", \"pull\", args.Image)\n\ta.fm.Shell().Run(\"sudo\", pullArgs...)\n\n\t// Build the run command\n\t// Use the configured snapshotter (from CONTAINERD_SNAPSHOTTER env var, default overlayfs)\n\trunArgs := append(ctrArgs, \"run\", \"-d\", \"--snapshotter\", a.snapshotter)\n\n\t// Add labels if specified\n\tfor key, value := range args.Labels {\n\t\trunArgs = append(runArgs, \"--label\", fmt.Sprintf(\"%s=%s\", key, value))\n\t}\n\n\t// Add the image and container name\n\trunArgs = append(runArgs, args.Image, containerName)\n\n\t// Add the command if specified\n\tif len(cmd) > 0 {\n\t\trunArgs = append(runArgs, cmd...)\n\t}\n\n\tklog.Infof(\"Creating containerd container %s\", containerName)\n\ta.fm.Shell().Run(\"sudo\", runArgs...)\n\n\t// ctr run returns the container ID (which is the same as the name we provided)\n\tcontainerID := containerName\n\n\tklog.Infof(\"Created containerd container with ID: %s\", containerID)\n\n\t// Register cleanup function\n\t// Use RunStress for cleanup commands to avoid test failures when containers have already exited\n\ta.fm.cleanups = append(a.fm.cleanups, func() {\n\t\tklog.Infof(\"Cleaning up containerd container %s\", containerID)\n\t\t// Kill the task with SIGKILL to ensure it stops immediately\n\t\t// Use RunStress so we don't fail if the task has already exited\n\t\tkillArgs := append([]string{\"ctr\", \"--address\", a.socket, \"--namespace\", a.namespace},\n\t\t\t\"task\", \"kill\", \"--signal\", \"SIGKILL\", containerID)\n\t\ta.fm.Shell().RunStress(\"sudo\", killArgs...)\n\t\t// Wait a moment for the task to stop\n\t\ttime.Sleep(500 * time.Millisecond)\n\t\t// Delete the task (with force flag)\n\t\tdeleteTaskArgs := append([]string{\"ctr\", \"--address\", a.socket, \"--namespace\", a.namespace},\n\t\t\t\"task\", \"delete\", \"-f\", containerID)\n\t\ta.fm.Shell().RunStress(\"sudo\", deleteTaskArgs...)\n\t\t// Delete the container\n\t\tdeleteArgs := append([]string{\"ctr\", \"--address\", a.socket, \"--namespace\", a.namespace},\n\t\t\t\"container\", \"delete\", containerID)\n\t\ta.fm.Shell().RunStress(\"sudo\", deleteArgs...)\n\t})\n\n\treturn containerID\n}\n"
  },
  {
    "path": "integration/framework/metrics.go",
    "content": "// Copyright 2024 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage framework\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"strings\"\n\t\"time\"\n\n\tdto \"github.com/prometheus/client_model/go\"\n\t\"github.com/prometheus/common/expfmt\"\n)\n\n// MetricsClient provides methods for fetching and parsing Prometheus metrics\n// from cAdvisor's /metrics endpoint.\ntype MetricsClient struct {\n\tbaseURL    string\n\thttpClient *http.Client\n}\n\n// NewMetricsClient creates a new client for the /metrics endpoint.\nfunc NewMetricsClient(hostname HostnameInfo) *MetricsClient {\n\treturn &MetricsClient{\n\t\tbaseURL: hostname.FullHostname(),\n\t\thttpClient: &http.Client{\n\t\t\tTimeout: 30 * time.Second,\n\t\t},\n\t}\n}\n\n// Fetch retrieves raw metrics text from the /metrics endpoint.\nfunc (m *MetricsClient) Fetch() (string, error) {\n\treturn m.FetchWithParams(\"\")\n}\n\n// FetchWithParams retrieves metrics with optional query parameters.\n// Parameters can be \"type=docker\" or \"type=name\" to filter containers.\nfunc (m *MetricsClient) FetchWithParams(params string) (string, error) {\n\turl := m.baseURL + \"metrics\"\n\tif params != \"\" {\n\t\turl += \"?\" + params\n\t}\n\n\tresp, err := m.httpClient.Get(url)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"failed to fetch metrics: %w\", err)\n\t}\n\tdefer resp.Body.Close()\n\n\tif resp.StatusCode != http.StatusOK {\n\t\tbody, _ := io.ReadAll(resp.Body)\n\t\treturn \"\", fmt.Errorf(\"metrics endpoint returned %d: %s\", resp.StatusCode, string(body))\n\t}\n\n\tbody, err := io.ReadAll(resp.Body)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"failed to read response: %w\", err)\n\t}\n\n\treturn string(body), nil\n}\n\n// Parse converts Prometheus text format to metric families.\nfunc (m *MetricsClient) Parse(metricsText string) (map[string]*dto.MetricFamily, error) {\n\tparser := expfmt.TextParser{}\n\treturn parser.TextToMetricFamilies(strings.NewReader(metricsText))\n}\n\n// FetchAndParse combines Fetch and Parse into one call.\nfunc (m *MetricsClient) FetchAndParse() (map[string]*dto.MetricFamily, error) {\n\ttext, err := m.Fetch()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn m.Parse(text)\n}\n\n// HasMetric checks if a metric family exists by name.\nfunc HasMetric(families map[string]*dto.MetricFamily, name string) bool {\n\t_, ok := families[name]\n\treturn ok\n}\n\n// GetMetricFamily returns a specific metric family by name.\nfunc GetMetricFamily(families map[string]*dto.MetricFamily, name string) (*dto.MetricFamily, bool) {\n\tmf, ok := families[name]\n\treturn mf, ok\n}\n\n// FindMetricWithLabels finds a metric matching all specified labels.\n// Returns nil if no matching metric is found.\nfunc FindMetricWithLabels(mf *dto.MetricFamily, labels map[string]string) *dto.Metric {\n\tif mf == nil {\n\t\treturn nil\n\t}\n\tfor _, metric := range mf.GetMetric() {\n\t\tif matchesLabels(metric, labels) {\n\t\t\treturn metric\n\t\t}\n\t}\n\treturn nil\n}\n\n// FindMetricsWithLabelSubstring finds all metrics where the specified label\n// contains the given substring.\nfunc FindMetricsWithLabelSubstring(mf *dto.MetricFamily, labelName, substring string) []*dto.Metric {\n\tif mf == nil {\n\t\treturn nil\n\t}\n\tvar result []*dto.Metric\n\tfor _, metric := range mf.GetMetric() {\n\t\tfor _, lp := range metric.GetLabel() {\n\t\t\tif lp.GetName() == labelName && strings.Contains(lp.GetValue(), substring) {\n\t\t\t\tresult = append(result, metric)\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t}\n\treturn result\n}\n\n// GetGaugeValue extracts the value from a gauge metric.\nfunc GetGaugeValue(metric *dto.Metric) float64 {\n\tif metric == nil || metric.GetGauge() == nil {\n\t\treturn 0\n\t}\n\treturn metric.GetGauge().GetValue()\n}\n\n// GetCounterValue extracts the value from a counter metric.\nfunc GetCounterValue(metric *dto.Metric) float64 {\n\tif metric == nil || metric.GetCounter() == nil {\n\t\treturn 0\n\t}\n\treturn metric.GetCounter().GetValue()\n}\n\n// GetLabelValue returns the value of a specific label from a metric.\n// Returns empty string if label is not found.\nfunc GetLabelValue(metric *dto.Metric, labelName string) string {\n\tif metric == nil {\n\t\treturn \"\"\n\t}\n\tfor _, lp := range metric.GetLabel() {\n\t\tif lp.GetName() == labelName {\n\t\t\treturn lp.GetValue()\n\t\t}\n\t}\n\treturn \"\"\n}\n\n// ContainsLabelValue checks if any metric in the family has the label\n// containing the given substring.\nfunc ContainsLabelValue(mf *dto.MetricFamily, labelName, substring string) bool {\n\tif mf == nil {\n\t\treturn false\n\t}\n\tfor _, metric := range mf.GetMetric() {\n\t\tfor _, lp := range metric.GetLabel() {\n\t\t\tif lp.GetName() == labelName && strings.Contains(lp.GetValue(), substring) {\n\t\t\t\treturn true\n\t\t\t}\n\t\t}\n\t}\n\treturn false\n}\n\n// GetMetricType returns the type of a metric family as a string.\nfunc GetMetricType(mf *dto.MetricFamily) string {\n\tif mf == nil {\n\t\treturn \"unknown\"\n\t}\n\treturn mf.GetType().String()\n}\n\n// matchesLabels checks if a metric has all the specified labels with exact values.\nfunc matchesLabels(metric *dto.Metric, targetLabels map[string]string) bool {\n\tif metric == nil {\n\t\treturn false\n\t}\n\tlabelMap := make(map[string]string)\n\tfor _, lp := range metric.GetLabel() {\n\t\tlabelMap[lp.GetName()] = lp.GetValue()\n\t}\n\tfor k, v := range targetLabels {\n\t\tif labelMap[k] != v {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}\n\n// CountMetrics returns the number of metric samples in a metric family.\nfunc CountMetrics(mf *dto.MetricFamily) int {\n\tif mf == nil {\n\t\treturn 0\n\t}\n\treturn len(mf.GetMetric())\n}\n\n// GetAllLabelValues returns all unique values for a given label name across\n// all metrics in the family.\nfunc GetAllLabelValues(mf *dto.MetricFamily, labelName string) []string {\n\tif mf == nil {\n\t\treturn nil\n\t}\n\tseen := make(map[string]bool)\n\tvar values []string\n\tfor _, metric := range mf.GetMetric() {\n\t\tfor _, lp := range metric.GetLabel() {\n\t\t\tif lp.GetName() == labelName {\n\t\t\t\tval := lp.GetValue()\n\t\t\t\tif !seen[val] {\n\t\t\t\t\tseen[val] = true\n\t\t\t\t\tvalues = append(values, val)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn values\n}\n"
  },
  {
    "path": "integration/runner/retrywhitelist.txt",
    "content": "Network tx and rx bytes should not be equal\nNetwork tx and rx packets should not be equal"
  },
  {
    "path": "integration/runner/run.sh",
    "content": "#!/bin/bash\n\n# Copyright 2015 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\nset -e\nset -x\n\n# Check usage.\nif [ $# == 0 ]; then\n  echo \"USAGE: run.sh <hosts to run tests on>\"\n  exit 1\nfi\n\n# Don't run on trivial changes.\nif ! git diff --name-only origin/master | grep -c -E \"*.go|*.sh\" &> /dev/null; then\n  echo \"This PR does not touch files that require integration testing. Skipping integration tests.\"\n  exit 0\nfi\n\n# Build the runner.\ngo build github.com/google/cadvisor/integration/runner\n\n# Run it.\nHOSTS=$@\n./runner --logtostderr $HOSTS\n"
  },
  {
    "path": "integration/runner/runner.go",
    "content": "// Copyright 2015 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage main\n\nimport (\n\t\"bufio\"\n\t\"bytes\"\n\t\"encoding/json\"\n\t\"errors\"\n\t\"flag\"\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"os/exec\"\n\t\"path\"\n\t\"regexp\"\n\t\"strconv\"\n\t\"strings\"\n\t\"sync\"\n\t\"time\"\n\n\t\"k8s.io/klog/v2\"\n\n\tcadvisorApi \"github.com/google/cadvisor/info/v2\"\n)\n\n// must be able to ssh into hosts without password\n// go run ./integration/runner/runner.go --logtostderr --v 2 --ssh-config <.ssh/config file> <list of hosts>\n\nconst (\n\tcadvisorBinary = \"cadvisor\"\n\ttestTimeout    = 15 * time.Minute\n)\n\nvar cadvisorTimeout = flag.Duration(\"cadvisor_timeout\", 15*time.Second, \"Time to wait for cAdvisor to come up on the remote host\")\nvar port = flag.Int(\"port\", 8080, \"Port in which to start cAdvisor in the remote host\")\nvar testRetryCount = flag.Int(\"test-retry-count\", 3, \"Number of times to retry failed tests before failing.\")\nvar testRetryWhitelist = flag.String(\"test-retry-whitelist\", \"\", \"Path to newline separated list of regexexp for test failures that should be retried.  If empty, no tests are retried.\")\nvar sshOptions = flag.String(\"ssh-options\", \"\", \"Commandline options passed to ssh.\")\nvar retryRegex *regexp.Regexp\n\nfunc getAttributes(ipAddress, portStr string) (*cadvisorApi.Attributes, error) {\n\t// Get host attributes and log attributes if the tests fail.\n\tvar attributes cadvisorApi.Attributes\n\tresp, err := http.Get(fmt.Sprintf(\"http://%s:%s/api/v2.1/attributes\", ipAddress, portStr))\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to get attributes - %v\", err)\n\t}\n\tif resp.StatusCode != http.StatusOK {\n\t\treturn nil, fmt.Errorf(\"failed to get attributes. Status code - %v\", resp.StatusCode)\n\t}\n\tdefer resp.Body.Close()\n\tbody, err := io.ReadAll(resp.Body)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"unable to read attributes response body - %v\", err)\n\t}\n\tif err := json.Unmarshal(body, &attributes); err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to unmarshal attributes - %v\", err)\n\t}\n\treturn &attributes, nil\n}\n\nfunc RunCommand(cmd string, args ...string) error {\n\toutput, err := exec.Command(cmd, args...).CombinedOutput()\n\tif err != nil {\n\t\treturn fmt.Errorf(\"command %q %q failed with error: %v and output: %s\", cmd, args, err, output)\n\t}\n\n\treturn nil\n}\n\nfunc RunSshCommand(cmd string, args ...string) error {\n\tif *sshOptions != \"\" {\n\t\targs = append(strings.Split(*sshOptions, \" \"), args...)\n\t}\n\treturn RunCommand(cmd, args...)\n}\n\nfunc PushAndRunTests(host, testDir string) (result error) {\n\t// Push binary.\n\tklog.Infof(\"Pushing cAdvisor binary to %q...\", host)\n\n\terr := RunSshCommand(\"ssh\", host, \"--\", \"mkdir\", \"-p\", testDir)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to make remote testing directory: %v\", err)\n\t}\n\tdefer func() {\n\t\terr = RunSshCommand(\"ssh\", host, \"--\", \"rm\", \"-rf\", testDir)\n\t\tif err != nil {\n\t\t\tklog.Errorf(\"Failed to cleanup test directory: %v\", err)\n\t\t}\n\t}()\n\n\terr = RunSshCommand(\"scp\", \"-r\", cadvisorBinary, fmt.Sprintf(\"%s:%s\", host, testDir))\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to copy binary: %v\", err)\n\t}\n\n\t// Start cAdvisor.\n\tklog.Infof(\"Running cAdvisor on %q...\", host)\n\tportStr := strconv.Itoa(*port)\n\terrChan := make(chan error, 1)\n\tgo func() {\n\t\terr = RunSshCommand(\"ssh\", host, \"--\", fmt.Sprintf(\"sudo GORACE='halt_on_error=1' %s --port %s --logtostderr --env_metadata_whitelist=TEST_VAR  &> %s/log.txt\", path.Join(testDir, cadvisorBinary), portStr, testDir))\n\t\tif err != nil {\n\t\t\terrChan <- fmt.Errorf(\"error running cAdvisor: %v\", err)\n\t\t}\n\t}()\n\tdefer func() {\n\t\terr = RunSshCommand(\"ssh\", host, \"--\", \"sudo\", \"pkill\", cadvisorBinary)\n\t\tif err != nil {\n\t\t\tklog.Errorf(\"Failed to cleanup: %v\", err)\n\t\t}\n\t}()\n\tdefer func() {\n\t\tif result != nil {\n\t\t\t// Copy logs from the host\n\t\t\terr := RunSshCommand(\"scp\", fmt.Sprintf(\"%s:%s/log.txt\", host, testDir), \"./\")\n\t\t\tif err != nil {\n\t\t\t\tresult = fmt.Errorf(\"error fetching logs: %v for %v\", err, result)\n\t\t\t\treturn\n\t\t\t}\n\t\t\tdefer os.Remove(\"./log.txt\")\n\t\t\tlogs, err := os.ReadFile(\"./log.txt\")\n\t\t\tif err != nil {\n\t\t\t\tresult = fmt.Errorf(\"error reading local log file: %v for %v\", err, result)\n\t\t\t\treturn\n\t\t\t}\n\t\t\tklog.Errorf(\"----------------------\\nLogs from Host: %q\\n%v\\n\", host, string(logs))\n\n\t\t\t// Get attributes for debugging purposes.\n\t\t\tattributes, err := getAttributes(host, portStr)\n\t\t\tif err != nil {\n\t\t\t\tklog.Errorf(\"Failed to read host attributes: %v\", err)\n\t\t\t}\n\t\t\tresult = fmt.Errorf(\"error on host %s: %v\\n%+v\", host, result, attributes)\n\t\t}\n\t}()\n\n\t// Wait for cAdvisor to come up.\n\tendTime := time.Now().Add(*cadvisorTimeout)\n\tdone := false\n\tfor endTime.After(time.Now()) && !done {\n\t\tselect {\n\t\tcase err := <-errChan:\n\t\t\t// Quit early if there was an error.\n\t\t\treturn err\n\t\tcase <-time.After(500 * time.Millisecond):\n\t\t\t// Stop waiting when cAdvisor is healthy..\n\t\t\tresp, err := http.Get(fmt.Sprintf(\"http://%s:%s/healthz\", host, portStr))\n\t\t\tif err == nil && resp.StatusCode == http.StatusOK {\n\t\t\t\tdone = true\n\t\t\t}\n\t\t}\n\t}\n\tif !done {\n\t\treturn fmt.Errorf(\"timed out waiting for cAdvisor to come up at host %q\", host)\n\t}\n\n\t// Run the tests in a retry loop.\n\tklog.Infof(\"Running integration tests targeting %q...\", host)\n\tfor i := 0; i <= *testRetryCount; i++ {\n\t\t// Check if this is a retry\n\t\tif i > 0 {\n\t\t\ttime.Sleep(time.Second * 15) // Wait 15 seconds before retrying\n\t\t\tklog.Warningf(\"Retrying (%d of %d) tests on host %s due to error %v\", i, *testRetryCount, host, err)\n\t\t}\n\t\t// Run the command\n\n\t\terr = RunCommand(\"go\", \"test\", \"--timeout\", testTimeout.String(), \"github.com/google/cadvisor/integration/tests/...\", \"--host\", host, \"--port\", portStr, \"--ssh-options\", *sshOptions)\n\t\tif err == nil {\n\t\t\t// On success, break out of retry loop\n\t\t\tbreak\n\t\t}\n\n\t\t// Only retry on test failures caused by these known flaky failure conditions\n\t\tif retryRegex == nil || !retryRegex.Match([]byte(err.Error())) {\n\t\t\tklog.Warningf(\"Skipping retry for tests on host %s because error is not whitelisted\", host)\n\t\t\tbreak\n\t\t}\n\t}\n\treturn err\n}\n\nfunc Run() error {\n\tstart := time.Now()\n\tdefer func() {\n\t\tklog.Infof(\"Execution time %v\", time.Since(start))\n\t}()\n\tdefer klog.Flush()\n\n\thosts := flag.Args()\n\ttestDir := fmt.Sprintf(\"/tmp/cadvisor-%d\", os.Getpid())\n\tklog.Infof(\"Running integration tests on host(s) %q\", strings.Join(hosts, \",\"))\n\n\t// Build cAdvisor.\n\tklog.Infof(\"Building cAdvisor...\")\n\terr := RunCommand(\"build/build.sh\")\n\tif err != nil {\n\t\treturn err\n\t}\n\tdefer func() {\n\t\terr := RunCommand(\"rm\", cadvisorBinary)\n\t\tif err != nil {\n\t\t\tklog.Error(err)\n\t\t}\n\t}()\n\n\t// Run test on all hosts in parallel.\n\tvar wg sync.WaitGroup\n\tallErrors := make([]error, 0)\n\tvar allErrorsLock sync.Mutex\n\tfor _, host := range hosts {\n\t\twg.Add(1)\n\t\tgo func(host string) {\n\t\t\tdefer wg.Done()\n\t\t\terr := PushAndRunTests(host, testDir)\n\t\t\tif err != nil {\n\t\t\t\tfunc() {\n\t\t\t\t\tallErrorsLock.Lock()\n\t\t\t\t\tdefer allErrorsLock.Unlock()\n\t\t\t\t\tallErrors = append(allErrors, err)\n\t\t\t\t}()\n\t\t\t}\n\t\t}(host)\n\t}\n\twg.Wait()\n\n\tif len(allErrors) != 0 {\n\t\tvar buffer bytes.Buffer\n\t\tfor i, err := range allErrors {\n\t\t\tbuffer.WriteString(fmt.Sprintf(\"Error %d: \", i))\n\t\t\tbuffer.WriteString(err.Error())\n\t\t\tbuffer.WriteString(\"\\n\")\n\t\t}\n\t\treturn errors.New(buffer.String())\n\t}\n\n\tklog.Infof(\"All tests pass!\")\n\treturn nil\n}\n\n// initRetryWhitelist initializes the whitelist of test failures that can be retried.\nfunc initRetryWhitelist() {\n\tif *testRetryWhitelist == \"\" {\n\t\treturn\n\t}\n\n\tfile, err := os.Open(*testRetryWhitelist)\n\tif err != nil {\n\t\tklog.Fatal(err)\n\t}\n\tdefer file.Close()\n\n\tretryStrings := []string{}\n\tscanner := bufio.NewScanner(file)\n\tfor scanner.Scan() {\n\t\ttext := scanner.Text()\n\t\tif text != \"\" {\n\t\t\tretryStrings = append(retryStrings, text)\n\t\t}\n\t}\n\tif err := scanner.Err(); err != nil {\n\t\tklog.Fatal(err)\n\t}\n\tretryRegex = regexp.MustCompile(strings.Join(retryStrings, \"|\"))\n}\n\nfunc main() {\n\tklog.InitFlags(nil)\n\tflag.Parse()\n\n\t// Check usage.\n\tif len(flag.Args()) == 0 {\n\t\tklog.Fatalf(\"USAGE: runner <hosts to test>\")\n\t}\n\tinitRetryWhitelist()\n\n\t// Run the tests.\n\terr := Run()\n\tif err != nil {\n\t\tklog.Fatal(err)\n\t}\n}\n"
  },
  {
    "path": "integration/tests/TODO.md",
    "content": "Tests to Write:\n- UI comes up\n-- / -> /containers\n-- /containers\n-- /docker\n- API tests\n-- /containers\n-- /subcontainers\n"
  },
  {
    "path": "integration/tests/api/containerd_test.go",
    "content": "// Copyright 2014 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n//go:build linux\n\npackage api\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\t\"testing\"\n\t\"time\"\n\n\tinfo \"github.com/google/cadvisor/info/v1\"\n\t\"github.com/google/cadvisor/integration/framework\"\n\n\t\"github.com/stretchr/testify/assert\"\n\t\"github.com/stretchr/testify/require\"\n)\n\n// Waits up to 10s for a containerd container with the specified ID to appear in cAdvisor.\nfunc waitForContainerdContainer(containerID string, fm framework.Framework) {\n\terr := framework.RetryForDuration(func() error {\n\t\t// Query all containers via SubcontainersInfo - containerd containers are in \"containerd\" namespace\n\t\tallInfo, err := fm.Cadvisor().Client().SubcontainersInfo(\"/\", &info.ContainerInfoRequest{\n\t\t\tNumStats: 1,\n\t\t})\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\t// Look for container by ID\n\t\tfor _, container := range allInfo {\n\t\t\tfor _, alias := range container.Aliases {\n\t\t\t\tif alias == containerID {\n\t\t\t\t\treturn nil\n\t\t\t\t}\n\t\t\t}\n\t\t\t// Also check if the container name contains the ID\n\t\t\tif len(container.Name) > 0 && containsString(container.Name, containerID) {\n\t\t\t\treturn nil\n\t\t\t}\n\t\t}\n\t\treturn fmt.Errorf(\"container %q not found in cAdvisor\", containerID)\n\t}, 10*time.Second)\n\trequire.NoError(fm.T(), err, \"Timed out waiting for containerd container %q to be available in cAdvisor\", containerID)\n}\n\nfunc containsString(s, substr string) bool {\n\tfor i := 0; i <= len(s)-len(substr); i++ {\n\t\tif s[i:i+len(substr)] == substr {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\n// Sanity check the container by:\n// - Checking that the specified ID is a valid alias for this container.\n// - Verifying that stats are not empty.\nfunc sanityCheckContainerd(containerID string, containerInfo info.ContainerInfo, t *testing.T) {\n\tassert.Contains(t, containerInfo.Aliases, containerID, \"Alias %q should be in list of aliases %v\", containerID, containerInfo.Aliases)\n\tassert.NotEmpty(t, containerInfo.Stats, \"Expected container to have stats\")\n}\n\n// findContainerdContainer finds a container by ID in the list of containers.\nfunc findContainerdContainer(containerID string, containers []info.ContainerInfo) *info.ContainerInfo {\n\tfor i, container := range containers {\n\t\tfor _, alias := range container.Aliases {\n\t\t\tif alias == containerID {\n\t\t\t\treturn &containers[i]\n\t\t\t}\n\t\t}\n\t\t// Also check if the container name contains the ID\n\t\tif containsString(container.Name, containerID) {\n\t\t\treturn &containers[i]\n\t\t}\n\t}\n\treturn nil\n}\n\n// TestContainerdContainerById tests that cAdvisor can find a containerd container by its ID.\nfunc TestContainerdContainerById(t *testing.T) {\n\tfm := framework.New(t)\n\tdefer fm.Cleanup()\n\n\tcontainerID := fm.Containerd().RunPause()\n\n\t// Wait for the container to show up in cAdvisor\n\twaitForContainerdContainer(containerID, fm)\n\n\t// Query all containers via SubcontainersInfo\n\tallInfo, err := fm.Cadvisor().Client().SubcontainersInfo(\"/\", &info.ContainerInfoRequest{\n\t\tNumStats: 1,\n\t})\n\trequire.NoError(t, err)\n\n\t// Find our container\n\tcontainerInfo := findContainerdContainer(containerID, allInfo)\n\trequire.NotNil(t, containerInfo, \"Container %q should be found in cAdvisor\", containerID)\n\tsanityCheckContainerd(containerID, *containerInfo, t)\n}\n\n// TestContainerdContainerByName tests that cAdvisor can find a containerd container by a custom hex ID.\n// Note: cAdvisor's containerd handler expects 64-char hex container IDs, which is the standard format\n// used by Kubernetes/CRI. Custom human-readable names are not supported.\nfunc TestContainerdContainerByName(t *testing.T) {\n\tfm := framework.New(t)\n\tdefer fm.Cleanup()\n\n\t// Generate a 64-char hex ID (this is what Kubernetes/CRI uses)\n\tcontainerID := fmt.Sprintf(\"%032x%032x\", os.Getpid(), 999999)\n\t_ = fm.Containerd().Run(framework.ContainerdRunArgs{\n\t\tImage: \"registry.k8s.io/pause:3.9\",\n\t\tName:  containerID, // Using hex ID as the name\n\t})\n\n\t// Wait for the container to show up\n\twaitForContainerdContainer(containerID, fm)\n\n\t// Query all containers via SubcontainersInfo\n\tallInfo, err := fm.Cadvisor().Client().SubcontainersInfo(\"/\", &info.ContainerInfoRequest{\n\t\tNumStats: 1,\n\t})\n\trequire.NoError(t, err)\n\n\t// Find our container by ID\n\tcontainerInfo := findContainerdContainer(containerID, allInfo)\n\trequire.NotNil(t, containerInfo, \"Container with ID %q should be found in cAdvisor\", containerID)\n\tsanityCheckContainerd(containerID, *containerInfo, t)\n}\n\n// TestGetAllContainerdContainers tests that cAdvisor can find multiple containerd containers.\nfunc TestGetAllContainerdContainers(t *testing.T) {\n\tfm := framework.New(t)\n\tdefer fm.Cleanup()\n\n\t// Start two containers\n\tcontainerID1 := fm.Containerd().RunPause()\n\tcontainerID2 := fm.Containerd().RunPause()\n\n\t// Wait for both containers to show up\n\twaitForContainerdContainer(containerID1, fm)\n\twaitForContainerdContainer(containerID2, fm)\n\n\t// Query all containers via SubcontainersInfo\n\tallInfo, err := fm.Cadvisor().Client().SubcontainersInfo(\"/\", &info.ContainerInfoRequest{\n\t\tNumStats: 1,\n\t})\n\trequire.NoError(t, err)\n\n\t// Find both containers\n\tcontainerInfo1 := findContainerdContainer(containerID1, allInfo)\n\tcontainerInfo2 := findContainerdContainer(containerID2, allInfo)\n\n\trequire.NotNil(t, containerInfo1, \"Container %q should be found in cAdvisor\", containerID1)\n\trequire.NotNil(t, containerInfo2, \"Container %q should be found in cAdvisor\", containerID2)\n\n\tsanityCheckContainerd(containerID1, *containerInfo1, t)\n\tsanityCheckContainerd(containerID2, *containerInfo2, t)\n}\n\n// TestBasicContainerdContainer tests basic container properties.\nfunc TestBasicContainerdContainer(t *testing.T) {\n\tfm := framework.New(t)\n\tdefer fm.Cleanup()\n\n\tcontainerID := fm.Containerd().RunPause()\n\n\t// Wait for the container to show up\n\twaitForContainerdContainer(containerID, fm)\n\n\t// Query all containers via SubcontainersInfo\n\tallInfo, err := fm.Cadvisor().Client().SubcontainersInfo(\"/\", &info.ContainerInfoRequest{\n\t\tNumStats: 1,\n\t})\n\trequire.NoError(t, err)\n\n\t// Find our container\n\tcontainerInfo := findContainerdContainer(containerID, allInfo)\n\trequire.NotNil(t, containerInfo, \"Container %q should be found\", containerID)\n\tassert.NotEmpty(t, containerInfo.Stats, \"Should have at least one stat\")\n}\n\n// TestContainerdContainerCpuStats tests CPU statistics collection for containerd containers.\nfunc TestContainerdContainerCpuStats(t *testing.T) {\n\tfm := framework.New(t)\n\tdefer fm.Cleanup()\n\n\t// Run a busybox container that does some work\n\tcontainerID := fm.Containerd().RunBusybox(\"sh\", \"-c\", \"while true; do echo hello; sleep 1; done\")\n\n\t// Wait for the container to show up\n\twaitForContainerdContainer(containerID, fm)\n\n\t// Give the container some time to generate CPU usage\n\ttime.Sleep(2 * time.Second)\n\n\t// Query all containers via SubcontainersInfo\n\tallInfo, err := fm.Cadvisor().Client().SubcontainersInfo(\"/\", &info.ContainerInfoRequest{\n\t\tNumStats: 1,\n\t})\n\trequire.NoError(t, err)\n\n\t// Find our container\n\tcontainerInfo := findContainerdContainer(containerID, allInfo)\n\trequire.NotNil(t, containerInfo, \"Container %q should be found\", containerID)\n\trequire.NotEmpty(t, containerInfo.Stats, \"Should have stats\")\n\n\t// Check CPU stats\n\tstat := containerInfo.Stats[0]\n\tcheckCPUStats(t, stat.Cpu)\n}\n\n// TestContainerdContainerMemoryStats tests memory statistics collection for containerd containers.\nfunc TestContainerdContainerMemoryStats(t *testing.T) {\n\tfm := framework.New(t)\n\tdefer fm.Cleanup()\n\n\t// Run a busybox container\n\tcontainerID := fm.Containerd().RunBusybox(\"sh\", \"-c\", \"while true; do echo hello; sleep 1; done\")\n\n\t// Wait for the container to show up\n\twaitForContainerdContainer(containerID, fm)\n\n\t// Give the container some time to use memory\n\ttime.Sleep(2 * time.Second)\n\n\t// Query all containers via SubcontainersInfo\n\tallInfo, err := fm.Cadvisor().Client().SubcontainersInfo(\"/\", &info.ContainerInfoRequest{\n\t\tNumStats: 1,\n\t})\n\trequire.NoError(t, err)\n\n\t// Find our container\n\tcontainerInfo := findContainerdContainer(containerID, allInfo)\n\trequire.NotNil(t, containerInfo, \"Container %q should be found\", containerID)\n\trequire.NotEmpty(t, containerInfo.Stats, \"Should have stats\")\n\n\t// Check memory stats\n\tstat := containerInfo.Stats[0]\n\tcheckMemoryStats(t, stat.Memory)\n}\n\n// TestContainerdContainerSpec tests that container spec is correctly populated for containerd containers.\nfunc TestContainerdContainerSpec(t *testing.T) {\n\tfm := framework.New(t)\n\tdefer fm.Cleanup()\n\n\tcontainerID := fm.Containerd().RunPause()\n\n\t// Wait for the container to show up\n\twaitForContainerdContainer(containerID, fm)\n\n\t// Query all containers via SubcontainersInfo\n\tallInfo, err := fm.Cadvisor().Client().SubcontainersInfo(\"/\", &info.ContainerInfoRequest{\n\t\tNumStats: 1,\n\t})\n\trequire.NoError(t, err)\n\n\t// Find our container\n\tcontainerInfo := findContainerdContainer(containerID, allInfo)\n\trequire.NotNil(t, containerInfo, \"Container %q should be found\", containerID)\n\n\t// Check that spec has basic properties\n\tassert.True(t, containerInfo.Spec.HasCpu, \"CPU should be isolated\")\n\tassert.True(t, containerInfo.Spec.HasMemory, \"Memory should be isolated\")\n}\n\n// TestContainerdContainerLabels tests that container labels are correctly captured.\nfunc TestContainerdContainerLabels(t *testing.T) {\n\tfm := framework.New(t)\n\tdefer fm.Cleanup()\n\n\t// Use auto-generated 64-char hex ID (required by cAdvisor's containerd handler)\n\tcontainerID := fm.Containerd().Run(framework.ContainerdRunArgs{\n\t\tImage: \"registry.k8s.io/pause:3.9\",\n\t\tLabels: map[string]string{\n\t\t\t\"test.label.key\": \"test-value\",\n\t\t},\n\t})\n\n\t// Wait for the container to show up\n\twaitForContainerdContainer(containerID, fm)\n\n\t// Query all containers via SubcontainersInfo\n\tallInfo, err := fm.Cadvisor().Client().SubcontainersInfo(\"/\", &info.ContainerInfoRequest{\n\t\tNumStats: 1,\n\t})\n\trequire.NoError(t, err)\n\n\t// Find our container\n\tcontainerInfo := findContainerdContainer(containerID, allInfo)\n\trequire.NotNil(t, containerInfo, \"Container %q should be found\", containerID)\n\n\t// Check that labels are captured\n\tassert.Contains(t, containerInfo.Spec.Labels, \"test.label.key\", \"Labels should contain test.label.key\")\n\tassert.Equal(t, \"test-value\", containerInfo.Spec.Labels[\"test.label.key\"], \"Label value should match\")\n}\n\n// TestContainerdContainerCreationTime tests that container creation time is valid.\nfunc TestContainerdContainerCreationTime(t *testing.T) {\n\tfm := framework.New(t)\n\tdefer fm.Cleanup()\n\n\tbeforeCreation := time.Now().Add(-1 * time.Second)\n\n\tcontainerID := fm.Containerd().RunPause()\n\twaitForContainerdContainer(containerID, fm)\n\n\tafterCreation := time.Now().Add(1 * time.Second)\n\n\t// Query all containers\n\tallInfo, err := fm.Cadvisor().Client().SubcontainersInfo(\"/\", &info.ContainerInfoRequest{\n\t\tNumStats: 1,\n\t})\n\trequire.NoError(t, err)\n\n\tcontainerInfo := findContainerdContainer(containerID, allInfo)\n\trequire.NotNil(t, containerInfo, \"Container %q should be found\", containerID)\n\n\t// Check creation time is within expected range\n\tcreationTime := containerInfo.Spec.CreationTime\n\tassert.True(t, creationTime.After(beforeCreation), \"Creation time %v should be after %v\", creationTime, beforeCreation)\n\tassert.True(t, creationTime.Before(afterCreation), \"Creation time %v should be before %v\", creationTime, afterCreation)\n}\n\n// TestContainerdContainerDiskIoStats tests DiskIO statistics for containerd containers.\nfunc TestContainerdContainerDiskIoStats(t *testing.T) {\n\tfm := framework.New(t)\n\tdefer fm.Cleanup()\n\n\t// Run a container that does disk I/O and stays running\n\tcontainerID := fm.Containerd().RunBusybox(\"sh\", \"-c\", \"dd if=/dev/zero of=/tmp/testfile bs=1024 count=1000 && sync && sleep 30\")\n\n\t// Wait for the container to show up and do some I/O\n\twaitForContainerdContainer(containerID, fm)\n\ttime.Sleep(3 * time.Second)\n\n\tallInfo, err := fm.Cadvisor().Client().SubcontainersInfo(\"/\", &info.ContainerInfoRequest{\n\t\tNumStats: 1,\n\t})\n\trequire.NoError(t, err)\n\n\tcontainerInfo := findContainerdContainer(containerID, allInfo)\n\trequire.NotNil(t, containerInfo, \"Container %q should be found\", containerID)\n\n\t// Check that DiskIo stats are present\n\tassert.True(t, containerInfo.Spec.HasDiskIo, \"Container should have DiskIo isolation\")\n}\n\n// TestContainerdContainerImageInfo tests that container image information is captured.\nfunc TestContainerdContainerImageInfo(t *testing.T) {\n\tfm := framework.New(t)\n\tdefer fm.Cleanup()\n\n\texpectedImage := \"registry.k8s.io/pause:3.9\"\n\tcontainerID := fm.Containerd().Run(framework.ContainerdRunArgs{\n\t\tImage: expectedImage,\n\t})\n\n\twaitForContainerdContainer(containerID, fm)\n\n\tallInfo, err := fm.Cadvisor().Client().SubcontainersInfo(\"/\", &info.ContainerInfoRequest{\n\t\tNumStats: 1,\n\t})\n\trequire.NoError(t, err)\n\n\tcontainerInfo := findContainerdContainer(containerID, allInfo)\n\trequire.NotNil(t, containerInfo, \"Container %q should be found\", containerID)\n\n\t// Check image name is captured\n\tassert.Contains(t, containerInfo.Spec.Image, \"pause\", \"Container image should contain 'pause'\")\n}\n"
  },
  {
    "path": "integration/tests/api/docker_test.go",
    "content": "// Copyright 2014 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n//go:build linux\n\npackage api\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\t\"strconv\"\n\t\"testing\"\n\t\"time\"\n\n\tinfo \"github.com/google/cadvisor/info/v1\"\n\tv2 \"github.com/google/cadvisor/info/v2\"\n\t\"github.com/google/cadvisor/integration/framework\"\n\n\t\"github.com/opencontainers/cgroups\"\n\t\"github.com/stretchr/testify/assert\"\n\t\"github.com/stretchr/testify/require\"\n)\n\n// Sanity check the container by:\n// - Checking that the specified alias is a valid one for this container.\n// - Verifying that stats are not empty.\nfunc sanityCheck(alias string, containerInfo info.ContainerInfo, t *testing.T) {\n\tassert.Contains(t, containerInfo.Aliases, alias, \"Alias %q should be in list of aliases %v\", alias, containerInfo.Aliases)\n\tassert.NotEmpty(t, containerInfo.Stats, \"Expected container to have stats\")\n}\n\n// Sanity check the container by:\n// - Checking that the specified alias is a valid one for this container.\n// - Verifying that stats are not empty.\nfunc sanityCheckV2(alias string, info v2.ContainerInfo, t *testing.T) {\n\tassert.Contains(t, info.Spec.Aliases, alias, \"Alias %q should be in list of aliases %v\", alias, info.Spec.Aliases)\n\tassert.NotEmpty(t, info.Stats, \"Expected container to have stats\")\n}\n\n// Waits up to 5s for a container with the specified alias to appear.\nfunc waitForContainer(alias string, fm framework.Framework) {\n\terr := framework.RetryForDuration(func() error {\n\t\tret, err := fm.Cadvisor().Client().DockerContainer(alias, &info.ContainerInfoRequest{\n\t\t\tNumStats: 1,\n\t\t})\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif len(ret.Stats) != 1 {\n\t\t\treturn fmt.Errorf(\"no stats returned for container %q\", alias)\n\t\t}\n\n\t\treturn nil\n\t}, 5*time.Second)\n\trequire.NoError(fm.T(), err, \"Timed out waiting for container %q to be available in cAdvisor: %v\", alias, err)\n}\n\n// A Docker container in /docker/<ID>\nfunc TestDockerContainerById(t *testing.T) {\n\tfm := framework.New(t)\n\tdefer fm.Cleanup()\n\n\tcontainerID := fm.Docker().RunPause()\n\n\t// Wait for the container to show up.\n\twaitForContainer(containerID, fm)\n\n\trequest := &info.ContainerInfoRequest{\n\t\tNumStats: 1,\n\t}\n\tcontainerInfo, err := fm.Cadvisor().Client().DockerContainer(containerID, request)\n\trequire.NoError(t, err)\n\n\tsanityCheck(containerID, containerInfo, t)\n}\n\n// A Docker container in /docker/<name>\nfunc TestDockerContainerByName(t *testing.T) {\n\tfm := framework.New(t)\n\tdefer fm.Cleanup()\n\n\tcontainerName := fmt.Sprintf(\"test-docker-container-by-name-%d\", os.Getpid())\n\tfm.Docker().Run(framework.DockerRunArgs{\n\t\tImage: \"registry.k8s.io/pause\",\n\t\tArgs:  []string{\"--name\", containerName},\n\t})\n\n\t// Wait for the container to show up.\n\twaitForContainer(containerName, fm)\n\n\trequest := &info.ContainerInfoRequest{\n\t\tNumStats: 1,\n\t}\n\tcontainerInfo, err := fm.Cadvisor().Client().DockerContainer(containerName, request)\n\trequire.NoError(t, err)\n\n\tsanityCheck(containerName, containerInfo, t)\n}\n\n// Find the first container with the specified alias in containers.\nfunc findContainer(alias string, containers []info.ContainerInfo, t *testing.T) info.ContainerInfo {\n\tfor _, cont := range containers {\n\t\tfor _, a := range cont.Aliases {\n\t\t\tif alias == a {\n\t\t\t\treturn cont\n\t\t\t}\n\t\t}\n\t}\n\tt.Fatalf(\"Failed to find container %q in %+v\", alias, containers)\n\treturn info.ContainerInfo{}\n}\n\n// All Docker containers through /docker\nfunc TestGetAllDockerContainers(t *testing.T) {\n\tfm := framework.New(t)\n\tdefer fm.Cleanup()\n\n\t// Wait for the containers to show up.\n\tcontainerID1 := fm.Docker().RunPause()\n\tcontainerID2 := fm.Docker().RunPause()\n\twaitForContainer(containerID1, fm)\n\twaitForContainer(containerID2, fm)\n\n\trequest := &info.ContainerInfoRequest{\n\t\tNumStats: 1,\n\t}\n\tcontainersInfo, err := fm.Cadvisor().Client().AllDockerContainers(request)\n\trequire.NoError(t, err)\n\n\tif len(containersInfo) < 2 {\n\t\tt.Fatalf(\"At least 2 Docker containers should exist, received %d: %+v\", len(containersInfo), containersInfo)\n\t}\n\tsanityCheck(containerID1, findContainer(containerID1, containersInfo, t), t)\n\tsanityCheck(containerID2, findContainer(containerID2, containersInfo, t), t)\n}\n\n// Check expected properties of a Docker container.\nfunc TestBasicDockerContainer(t *testing.T) {\n\tfm := framework.New(t)\n\tdefer fm.Cleanup()\n\n\tcontainerName := fmt.Sprintf(\"test-basic-docker-container-%d\", os.Getpid())\n\tcontainerID := fm.Docker().Run(framework.DockerRunArgs{\n\t\tImage: \"registry.k8s.io/pause\",\n\t\tArgs: []string{\n\t\t\t\"--name\", containerName,\n\t\t},\n\t})\n\n\t// Wait for the container to show up.\n\twaitForContainer(containerID, fm)\n\n\trequest := &info.ContainerInfoRequest{\n\t\tNumStats: 1,\n\t}\n\tcontainerInfo, err := fm.Cadvisor().Client().DockerContainer(containerID, request)\n\trequire.NoError(t, err)\n\n\t// Check that the container is known by both its name and ID.\n\tsanityCheck(containerID, containerInfo, t)\n\tsanityCheck(containerName, containerInfo, t)\n\n\tassert.Empty(t, containerInfo.Subcontainers, \"Should not have subcontainers\")\n\tassert.Len(t, containerInfo.Stats, 1, \"Should have exactly one stat\")\n}\n\n// TODO(vmarmol): Handle if CPU or memory is not isolated on this system.\n// Check the ContainerSpec.\nfunc TestDockerContainerSpec(t *testing.T) {\n\tfm := framework.New(t)\n\tdefer fm.Cleanup()\n\n\tvar (\n\t\tcpuShares   = uint64(2048)\n\t\tcpuMask     = \"0\"\n\t\tmemoryLimit = uint64(1 << 30) // 1GB\n\t\timage       = \"registry.k8s.io/pause\"\n\t\tenv         = map[string]string{\"test_var\": \"FOO\"}\n\t\tlabels      = map[string]string{\"bar\": \"baz\"}\n\t)\n\n\tcontainerID := fm.Docker().Run(framework.DockerRunArgs{\n\t\tImage: image,\n\t\tArgs: []string{\n\t\t\t\"--cpu-shares\", strconv.FormatUint(cpuShares, 10),\n\t\t\t\"--cpuset-cpus\", cpuMask,\n\t\t\t\"--memory\", strconv.FormatUint(memoryLimit, 10),\n\t\t\t\"--env\", \"TEST_VAR=FOO\",\n\t\t\t\"--label\", \"bar=baz\",\n\t\t},\n\t})\n\n\t// Wait for the container to show up.\n\twaitForContainer(containerID, fm)\n\n\trequest := &info.ContainerInfoRequest{\n\t\tNumStats: 1,\n\t}\n\tcontainerInfo, err := fm.Cadvisor().Client().DockerContainer(containerID, request)\n\trequire.NoError(t, err)\n\tsanityCheck(containerID, containerInfo, t)\n\n\tassert := assert.New(t)\n\n\tassert.True(containerInfo.Spec.HasCpu, \"CPU should be isolated\")\n\tif cgroups.IsCgroup2UnifiedMode() {\n\t\t// cpu shares are rounded slightly on cgroupv2 due to conversion between cgroupv1 (cpu.shares) and cgroupv2 (cpu.weight)\n\t\t// When container is created via docker, runc will convert cpu shares to cpu.weight https://github.com/opencontainers/runc/blob/d11f4d756e85ece5cdba8bb69f8bd4db3cdcbeab/libcontainer/cgroups/utils.go#L423-L428\n\t\t// And cAdvisor will convert cpu.weight back to cpu shares in https://github.com/google/cadvisor/blob/24e7a9883d12f944fd4403861707f4bafcaf4f3d/container/common/helpers.go#L249-L260\n\t\t// Worked example:\n\t\t// cpuShares = 2048 (input to docker --cpu-shares)\n\t\t// cpuWeight = int((1 + ((cpuShares-2)*9999)/262142))=79 (conversion done by runc)\n\t\t// cpuWeight back to cpuShares = int(2 + ((cpuWeight-1)*262142)/9999)= 2046\n\t\tvar cgroupV2Shares uint64 = 2046\n\t\tassert.Equal(cgroupV2Shares, containerInfo.Spec.Cpu.Limit, \"Container should have %d shares, has %d\", cgroupV2Shares, containerInfo.Spec.Cpu.Limit)\n\t} else {\n\t\tassert.Equal(cpuShares, containerInfo.Spec.Cpu.Limit, \"Container should have %d shares, has %d\", cpuShares, containerInfo.Spec.Cpu.Limit)\n\t}\n\n\tassert.Equal(cpuMask, containerInfo.Spec.Cpu.Mask, \"Cpu mask should be %q, but is %q\", cpuMask, containerInfo.Spec.Cpu.Mask)\n\tassert.True(containerInfo.Spec.HasMemory, \"Memory should be isolated\")\n\tassert.Equal(memoryLimit, containerInfo.Spec.Memory.Limit, \"Container should have memory limit of %d, has %d\", memoryLimit, containerInfo.Spec.Memory.Limit)\n\tassert.True(containerInfo.Spec.HasNetwork, \"Network should be isolated\")\n\tassert.True(containerInfo.Spec.HasDiskIo, \"Blkio should be isolated\")\n\n\tassert.Equal(image, containerInfo.Spec.Image, \"Spec should include container image\")\n\tassert.Equal(env, containerInfo.Spec.Envs, \"Spec should include environment variables\")\n\tassert.Equal(labels, containerInfo.Spec.Labels, \"Spec should include labels\")\n}\n\n// Check the CPU ContainerStats.\nfunc TestDockerContainerCpuStats(t *testing.T) {\n\tfm := framework.New(t)\n\tdefer fm.Cleanup()\n\n\t// Wait for the container to show up.\n\tcontainerID := fm.Docker().RunBusybox(\"ping\", \"www.google.com\")\n\twaitForContainer(containerID, fm)\n\n\trequest := &info.ContainerInfoRequest{\n\t\tNumStats: 1,\n\t}\n\tcontainerInfo, err := fm.Cadvisor().Client().DockerContainer(containerID, request)\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\tsanityCheck(containerID, containerInfo, t)\n\n\t// Checks for CpuStats.\n\tcheckCPUStats(t, containerInfo.Stats[0].Cpu)\n}\n\n// Check the memory ContainerStats.\nfunc TestDockerContainerMemoryStats(t *testing.T) {\n\tfm := framework.New(t)\n\tdefer fm.Cleanup()\n\n\t// Wait for the container to show up.\n\tcontainerID := fm.Docker().RunBusybox(\"ping\", \"www.google.com\")\n\twaitForContainer(containerID, fm)\n\n\trequest := &info.ContainerInfoRequest{\n\t\tNumStats: 1,\n\t}\n\tcontainerInfo, err := fm.Cadvisor().Client().DockerContainer(containerID, request)\n\trequire.NoError(t, err)\n\tsanityCheck(containerID, containerInfo, t)\n\n\t// Checks for MemoryStats.\n\tcheckMemoryStats(t, containerInfo.Stats[0].Memory)\n}\n\n// Check the network ContainerStats.\nfunc TestDockerContainerNetworkStats(t *testing.T) {\n\tfm := framework.New(t)\n\tdefer fm.Cleanup()\n\n\t// Wait for the container to show up.\n\tcontainerID := fm.Docker().RunBusybox(\"watch\", \"-n1\", \"wget\", \"http://www.google.com/\")\n\twaitForContainer(containerID, fm)\n\n\t// Wait for at least one additional housekeeping interval\n\ttime.Sleep(20 * time.Second)\n\trequest := &info.ContainerInfoRequest{\n\t\tNumStats: 1,\n\t}\n\tcontainerInfo, err := fm.Cadvisor().Client().DockerContainer(containerID, request)\n\trequire.NoError(t, err)\n\tsanityCheck(containerID, containerInfo, t)\n\n\tstat := containerInfo.Stats[0]\n\tifaceStats := stat.Network.InterfaceStats\n\t// macOS we have more than one interface, since traffic is\n\t// only on eth0 we need to pick that one\n\tif len(stat.Network.Interfaces) > 0 {\n\t\tfor _, iface := range stat.Network.Interfaces {\n\t\t\tif iface.Name == \"eth0\" {\n\t\t\t\tifaceStats = iface\n\t\t\t}\n\t\t}\n\t}\n\n\t// Checks for NetworkStats.\n\tassert := assert.New(t)\n\tassert.NotEqual(0, ifaceStats.TxBytes, \"Network tx bytes should not be zero\")\n\tassert.NotEqual(0, ifaceStats.TxPackets, \"Network tx packets should not be zero\")\n\tassert.NotEqual(0, ifaceStats.RxBytes, \"Network rx bytes should not be zero\")\n\tassert.NotEqual(0, ifaceStats.RxPackets, \"Network rx packets should not be zero\")\n\tassert.NotEqual(ifaceStats.RxBytes, ifaceStats.TxBytes, fmt.Sprintf(\"Network tx (%d) and rx (%d) bytes should not be equal\", ifaceStats.TxBytes, ifaceStats.RxBytes))\n\tassert.NotEqual(ifaceStats.RxPackets, ifaceStats.TxPackets, fmt.Sprintf(\"Network tx (%d) and rx (%d) packets should not be equal\", ifaceStats.TxPackets, ifaceStats.RxPackets))\n}\n\nfunc TestDockerFilesystemStats(t *testing.T) {\n\tfm := framework.New(t)\n\tdefer fm.Cleanup()\n\n\tstorageDriver := fm.Docker().StorageDriver()\n\tif storageDriver == framework.DeviceMapper {\n\t\t// Filesystem stats not supported with devicemapper, yet\n\t\treturn\n\t}\n\n\tconst (\n\t\tddUsage       = uint64(1 << 3) // 1 KB\n\t\tsleepDuration = 10 * time.Second\n\t)\n\t// Wait for the container to show up.\n\t// FIXME: Tests should be bundled and run on the remote host instead of being run over ssh.\n\t// Escaping bash over ssh is ugly.\n\t// Once github issue 1130 is fixed, this logic can be removed.\n\tdockerCmd := fmt.Sprintf(\"dd if=/dev/zero of=/file count=2 bs=%d & ping google.com\", ddUsage)\n\tif fm.Hostname().Host != \"localhost\" {\n\t\tdockerCmd = fmt.Sprintf(\"'%s'\", dockerCmd)\n\t}\n\tcontainerID := fm.Docker().RunBusybox(\"/bin/sh\", \"-c\", dockerCmd)\n\twaitForContainer(containerID, fm)\n\trequest := &v2.RequestOptions{\n\t\tIdType: v2.TypeDocker,\n\t\tCount:  1,\n\t}\n\tneedsBaseUsageCheck := false\n\tswitch storageDriver {\n\tcase framework.Aufs, framework.Overlay, framework.Overlay2, framework.DeviceMapper:\n\t\tneedsBaseUsageCheck = true\n\t}\n\tpass := false\n\t// We need to wait for the `dd` operation to complete.\n\tfor i := 0; i < 10; i++ {\n\t\tcontainerInfo, err := fm.Cadvisor().ClientV2().Stats(containerID, request)\n\t\tif err != nil {\n\t\t\tt.Logf(\"%v stats unavailable - %v\", time.Now().String(), err)\n\t\t\tt.Logf(\"retrying after %s...\", sleepDuration.String())\n\t\t\ttime.Sleep(sleepDuration)\n\n\t\t\tcontinue\n\t\t}\n\t\trequire.Equal(t, len(containerInfo), 1)\n\t\tvar info v2.ContainerInfo\n\t\t// There is only one container in containerInfo. Since it is a map with unknown key,\n\t\t// use the value blindly.\n\t\tfor _, cInfo := range containerInfo {\n\t\t\tinfo = cInfo\n\t\t}\n\t\tsanityCheckV2(containerID, info, t)\n\n\t\trequire.NotNil(t, info.Stats[0], \"got info: %+v\", info)\n\t\trequire.NotNil(t, info.Stats[0].Filesystem, \"got info: %+v\", info)\n\t\trequire.NotNil(t, info.Stats[0].Filesystem.TotalUsageBytes, \"got info: %+v\", info.Stats[0].Filesystem)\n\t\tif *info.Stats[0].Filesystem.TotalUsageBytes >= ddUsage {\n\t\t\tif !needsBaseUsageCheck {\n\t\t\t\tpass = true\n\t\t\t\tbreak\n\t\t\t}\n\t\t\trequire.NotNil(t, info.Stats[0].Filesystem.BaseUsageBytes)\n\t\t\tif *info.Stats[0].Filesystem.BaseUsageBytes >= ddUsage {\n\t\t\t\tpass = true\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t\tt.Logf(\"expected total usage %d bytes to be greater than %d bytes\", *info.Stats[0].Filesystem.TotalUsageBytes, ddUsage)\n\t\tif needsBaseUsageCheck {\n\t\t\tt.Logf(\"expected base %d bytes to be greater than %d bytes\", *info.Stats[0].Filesystem.BaseUsageBytes, ddUsage)\n\t\t}\n\t\tt.Logf(\"retrying after %s...\", sleepDuration.String())\n\t\ttime.Sleep(sleepDuration)\n\t}\n\n\tif !pass {\n\t\tt.Fail()\n\t}\n}\n\nfunc TestDockerHealthState(t *testing.T) {\n\tfm := framework.New(t)\n\tdefer fm.Cleanup()\n\n\tcontainerID := fm.Docker().Run(framework.DockerRunArgs{\n\t\tImage: \"registry.k8s.io/busybox:1.27\",\n\t\tArgs: []string{\n\t\t\t\"--health-cmd\", \"exit 0\",\n\t\t\t\"--health-interval\", \"1s\",\n\t\t},\n\t}, \"sh\", \"-c\", \"sleep 10\")\n\n\t// Wait for the container to show up.\n\twaitForContainer(containerID, fm)\n\n\tgetHealth := func() string {\n\t\tcontainerInfo, err := fm.Cadvisor().Client().DockerContainer(containerID, &info.ContainerInfoRequest{NumStats: 1})\n\t\trequire.NoError(t, err)\n\t\trequire.Len(t, containerInfo.Stats, 1)\n\t\treturn containerInfo.Stats[0].Health.Status\n\t}\n\n\t// Initially the container is in starting state.\n\trequire.Equal(t, \"starting\", getHealth())\n\n\t// Eventually the container should be in healthy state.\n\trequire.Eventually(t, func() bool {\n\t\treturn getHealth() == \"healthy\"\n\t}, 10*time.Second, 100*time.Millisecond)\n}\n\n// Check that restart count is captured in labels.\nfunc TestDockerContainerRestartCount(t *testing.T) {\n\tfm := framework.New(t)\n\tdefer fm.Cleanup()\n\n\tcontainerName := fmt.Sprintf(\"test-restart-count-%d\", os.Getpid())\n\t// Run a container that runs briefly then exits with failure, with restart policy\n\t// The sleep gives cAdvisor time to detect the container between restarts\n\tfm.Docker().Run(framework.DockerRunArgs{\n\t\tImage: \"registry.k8s.io/busybox:1.27\",\n\t\tArgs: []string{\n\t\t\t\"--name\", containerName,\n\t\t\t\"--restart\", \"on-failure:5\",\n\t\t},\n\t}, \"sh\", \"-c\", \"sleep 3 && exit 1\")\n\n\t// Wait for container to show up initially\n\twaitForContainer(containerName, fm)\n\n\t// Wait for at least one restart to occur\n\ttime.Sleep(5 * time.Second)\n\n\trequest := &info.ContainerInfoRequest{\n\t\tNumStats: 1,\n\t}\n\n\t// Query the container - it should still be running or restarting\n\tcontainerInfo, err := fm.Cadvisor().Client().DockerContainer(containerName, request)\n\trequire.NoError(t, err, \"Container should still be available during restart cycle\")\n\tsanityCheck(containerName, containerInfo, t)\n\n\t// Check that restart count label is present and greater than 0\n\trestartCount, ok := containerInfo.Spec.Labels[\"restartcount\"]\n\trequire.True(t, ok, \"restartcount label should be present\")\n\tcount, err := strconv.Atoi(restartCount)\n\trequire.NoError(t, err)\n\tassert.GreaterOrEqual(t, count, 1, \"Restart count should be at least 1\")\n}\n\n// Check the DiskIo ContainerStats.\nfunc TestDockerContainerDiskIoStats(t *testing.T) {\n\tfm := framework.New(t)\n\tdefer fm.Cleanup()\n\n\t// Run a container that does disk I/O and stays running\n\tcontainerID := fm.Docker().RunBusybox(\"sh\", \"-c\", \"dd if=/dev/zero of=/tmp/testfile bs=1024 count=1000 && sync && sleep 30\")\n\n\t// Wait for the container to show up and do some I/O\n\twaitForContainer(containerID, fm)\n\ttime.Sleep(3 * time.Second)\n\n\trequest := &info.ContainerInfoRequest{\n\t\tNumStats: 1,\n\t}\n\tcontainerInfo, err := fm.Cadvisor().Client().DockerContainer(containerID, request)\n\trequire.NoError(t, err)\n\tsanityCheck(containerID, containerInfo, t)\n\n\t// Check that DiskIo stats are present\n\tassert.True(t, containerInfo.Spec.HasDiskIo, \"Container should have DiskIo isolation\")\n}\n\n// Check container with --network none.\nfunc TestDockerContainerNetworkNone(t *testing.T) {\n\tfm := framework.New(t)\n\tdefer fm.Cleanup()\n\n\tcontainerName := fmt.Sprintf(\"test-network-none-%d\", os.Getpid())\n\tcontainerID := fm.Docker().Run(framework.DockerRunArgs{\n\t\tImage: \"registry.k8s.io/pause\",\n\t\tArgs: []string{\n\t\t\t\"--name\", containerName,\n\t\t\t\"--network\", \"none\",\n\t\t},\n\t})\n\n\t// Wait for the container to show up\n\twaitForContainer(containerID, fm)\n\n\trequest := &info.ContainerInfoRequest{\n\t\tNumStats: 1,\n\t}\n\tcontainerInfo, err := fm.Cadvisor().Client().DockerContainer(containerID, request)\n\trequire.NoError(t, err)\n\tsanityCheck(containerID, containerInfo, t)\n\n\t// Container with network none should still be monitored\n\tassert.NotEmpty(t, containerInfo.Stats, \"Container should have stats even with --network none\")\n}\n\n// Check container with --network host.\nfunc TestDockerContainerNetworkHost(t *testing.T) {\n\tfm := framework.New(t)\n\tdefer fm.Cleanup()\n\n\tcontainerName := fmt.Sprintf(\"test-network-host-%d\", os.Getpid())\n\tcontainerID := fm.Docker().Run(framework.DockerRunArgs{\n\t\tImage: \"registry.k8s.io/pause\",\n\t\tArgs: []string{\n\t\t\t\"--name\", containerName,\n\t\t\t\"--network\", \"host\",\n\t\t},\n\t})\n\n\t// Wait for the container to show up\n\twaitForContainer(containerID, fm)\n\n\trequest := &info.ContainerInfoRequest{\n\t\tNumStats: 1,\n\t}\n\tcontainerInfo, err := fm.Cadvisor().Client().DockerContainer(containerID, request)\n\trequire.NoError(t, err)\n\tsanityCheck(containerID, containerInfo, t)\n\n\t// Container with host network should be monitored\n\tassert.NotEmpty(t, containerInfo.Stats, \"Container should have stats with --network host\")\n}\n\n// Check container with shared network namespace (--network container:X).\n// This exercises the code path where we need to inspect another container for IP address.\nfunc TestDockerContainerSharedNetwork(t *testing.T) {\n\tfm := framework.New(t)\n\tdefer fm.Cleanup()\n\n\t// First, create a container that will share its network namespace\n\tnetworkContainerName := fmt.Sprintf(\"test-network-provider-%d\", os.Getpid())\n\tnetworkContainerID := fm.Docker().Run(framework.DockerRunArgs{\n\t\tImage: \"registry.k8s.io/pause\",\n\t\tArgs: []string{\n\t\t\t\"--name\", networkContainerName,\n\t\t},\n\t})\n\twaitForContainer(networkContainerID, fm)\n\n\t// Now create a container that shares the network namespace of the first container\n\tsharedNetworkContainerName := fmt.Sprintf(\"test-network-consumer-%d\", os.Getpid())\n\tsharedNetworkContainerID := fm.Docker().Run(framework.DockerRunArgs{\n\t\tImage: \"registry.k8s.io/pause\",\n\t\tArgs: []string{\n\t\t\t\"--name\", sharedNetworkContainerName,\n\t\t\t\"--network\", fmt.Sprintf(\"container:%s\", networkContainerName),\n\t\t},\n\t})\n\twaitForContainer(sharedNetworkContainerID, fm)\n\n\trequest := &info.ContainerInfoRequest{\n\t\tNumStats: 1,\n\t}\n\n\t// Both containers should be accessible\n\tcontainerInfo1, err := fm.Cadvisor().Client().DockerContainer(networkContainerID, request)\n\trequire.NoError(t, err)\n\tsanityCheck(networkContainerID, containerInfo1, t)\n\n\tcontainerInfo2, err := fm.Cadvisor().Client().DockerContainer(sharedNetworkContainerID, request)\n\trequire.NoError(t, err)\n\tsanityCheck(sharedNetworkContainerID, containerInfo2, t)\n\n\t// The container with shared network should have stats\n\tassert.NotEmpty(t, containerInfo2.Stats, \"Container with shared network should have stats\")\n}\n\n// Check that container image information is captured.\nfunc TestDockerContainerImageInfo(t *testing.T) {\n\tfm := framework.New(t)\n\tdefer fm.Cleanup()\n\n\texpectedImage := \"registry.k8s.io/pause\"\n\tcontainerID := fm.Docker().Run(framework.DockerRunArgs{\n\t\tImage: expectedImage,\n\t})\n\n\twaitForContainer(containerID, fm)\n\n\trequest := &info.ContainerInfoRequest{\n\t\tNumStats: 1,\n\t}\n\tcontainerInfo, err := fm.Cadvisor().Client().DockerContainer(containerID, request)\n\trequire.NoError(t, err)\n\tsanityCheck(containerID, containerInfo, t)\n\n\t// Check image name is captured\n\tassert.Contains(t, containerInfo.Spec.Image, \"pause\", \"Container image should contain 'pause'\")\n}\n\n// Check that container creation time is valid.\nfunc TestDockerContainerCreationTime(t *testing.T) {\n\tfm := framework.New(t)\n\tdefer fm.Cleanup()\n\n\tbeforeCreation := time.Now().Add(-1 * time.Second)\n\n\tcontainerID := fm.Docker().RunPause()\n\twaitForContainer(containerID, fm)\n\n\tafterCreation := time.Now().Add(1 * time.Second)\n\n\trequest := &info.ContainerInfoRequest{\n\t\tNumStats: 1,\n\t}\n\tcontainerInfo, err := fm.Cadvisor().Client().DockerContainer(containerID, request)\n\trequire.NoError(t, err)\n\tsanityCheck(containerID, containerInfo, t)\n\n\t// Check creation time is within expected range\n\tcreationTime := containerInfo.Spec.CreationTime\n\tassert.True(t, creationTime.After(beforeCreation), \"Creation time %v should be after %v\", creationTime, beforeCreation)\n\tassert.True(t, creationTime.Before(afterCreation), \"Creation time %v should be before %v\", creationTime, afterCreation)\n}\n"
  },
  {
    "path": "integration/tests/api/event_test.go",
    "content": "// Copyright 2015 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage api\n\nimport (\n\t\"fmt\"\n\t\"strconv\"\n\t\"strings\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/stretchr/testify/require\"\n\n\tinfo \"github.com/google/cadvisor/info/v1\"\n\t\"github.com/google/cadvisor/integration/framework\"\n)\n\nfunc TestStreamingEventInformationIsReturned(t *testing.T) {\n\t// TODO(vmarmol): De-flake and re-enable.\n\tt.Skip()\n\n\tfm := framework.New(t)\n\tdefer fm.Cleanup()\n\n\t// Watch for container deletions\n\teinfo := make(chan *info.Event)\n\tgo func() {\n\t\terr := fm.Cadvisor().Client().EventStreamingInfo(\"?deletion_events=true&stream=true&subcontainers=true\", einfo)\n\t\trequire.NoError(t, err)\n\t}()\n\n\t// Create a short-lived container.\n\tcontainerID := fm.Docker().RunBusybox(\"sleep\", \"2\")\n\n\t// Wait for the deletion event.\n\ttimeout := time.After(30 * time.Second)\n\tdone := false\n\tfor !done {\n\t\tselect {\n\t\tcase ev := <-einfo:\n\t\t\tif ev.EventType == info.EventContainerDeletion {\n\t\t\t\tif strings.Contains(ev.ContainerName, containerID) {\n\t\t\t\t\tdone = true\n\t\t\t\t}\n\t\t\t}\n\t\tcase <-timeout:\n\t\t\tt.Errorf(\n\t\t\t\t\"timeout happened before destruction event was detected for container %q\", containerID)\n\t\t\tdone = true\n\t\t}\n\t}\n\n\t// We should have already received a creation event.\n\twaitForStaticEvent(containerID, \"?creation_events=true&subcontainers=true\", t, fm, info.EventContainerCreation)\n}\n\nfunc waitForStaticEvent(containerID string, urlRequest string, t *testing.T, fm framework.Framework, typeEvent info.EventType) {\n\teinfo, err := fm.Cadvisor().Client().EventStaticInfo(urlRequest)\n\trequire.NoError(t, err)\n\tfound := false\n\tfor _, ev := range einfo {\n\t\tif ev.EventType == typeEvent {\n\t\t\tif strings.Contains(ev.ContainerName, containerID) {\n\t\t\t\tfound = true\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t}\n\trequire.True(t, found)\n}\n\nfunc TestContainerDeletionExitCode(t *testing.T) {\n\ttests := []struct {\n\t\tname     string\n\t\texitCode int\n\t}{\n\t\t{\n\t\t\tname:     \"successful exit\",\n\t\t\texitCode: 0,\n\t\t},\n\t\t{\n\t\t\tname:     \"error exit\",\n\t\t\texitCode: 1,\n\t\t},\n\t}\n\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tfm := framework.New(t)\n\t\t\tdefer fm.Cleanup()\n\n\t\t\tcontainerID := fm.Docker().RunBusybox(\"sh\", \"-c\", \"exit \"+strconv.Itoa(tt.exitCode))\n\n\t\t\terr := framework.RetryForDuration(func() error {\n\t\t\t\tevents, err := fm.Cadvisor().Client().EventStaticInfo(\"?deletion_events=true&subcontainers=true\")\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn err\n\t\t\t\t}\n\n\t\t\t\tfor _, ev := range events {\n\t\t\t\t\tif ev.EventType == info.EventContainerDeletion &&\n\t\t\t\t\t\tstrings.Contains(ev.ContainerName, containerID) {\n\t\t\t\t\t\tif ev.EventData.ContainerDeletion == nil {\n\t\t\t\t\t\t\treturn fmt.Errorf(\"deletion event data is nil\")\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ev.EventData.ContainerDeletion.ExitCode != tt.exitCode {\n\t\t\t\t\t\t\tt.Errorf(\"expected exit code %d, got %d\",\n\t\t\t\t\t\t\t\ttt.exitCode, ev.EventData.ContainerDeletion.ExitCode)\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn nil\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn fmt.Errorf(\"deletion event not found for container %s\", containerID)\n\t\t\t}, 30*time.Second)\n\n\t\t\trequire.NoError(t, err)\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "integration/tests/api/perf_test.go",
    "content": "//go:build libpfm && cgo\n\n// Copyright 2020 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage api\n\nimport (\n\t\"testing\"\n\t\"time\"\n\n\tv1 \"github.com/google/cadvisor/info/v1\"\n\t\"github.com/google/cadvisor/integration/framework\"\n\n\t\"github.com/stretchr/testify/assert\"\n)\n\nfunc TestPerfEvents(t *testing.T) {\n\tfm := framework.New(t)\n\tdefer fm.Cleanup()\n\n\tcontainerID := fm.Docker().RunPause()\n\twaitForContainerInfo(fm, containerID)\n\n\tinfo, err := fm.Cadvisor().Client().DockerContainer(containerID, &v1.ContainerInfoRequest{\n\t\tNumStats: 1,\n\t})\n\n\tassert.Nil(t, err)\n\tassert.Len(t, info.Stats, 1)\n\tassert.Greater(t, len(info.Stats[0].PerfStats), 0, \"Length of info.Stats[0].PerfStats is not greater than zero\")\n\tfor k, stat := range info.Stats[0].PerfStats {\n\t\t//Everything beyond name is non-deterministic unfortunately.\n\t\tassert.Contains(t, []string{\"context-switches\", \"cpu-migrations-custom\"}, stat.Name, \"Wrong metric name for key %d: %#v\", k, stat)\n\t}\n}\n\nfunc waitForContainerInfo(fm framework.Framework, containerID string) {\n\terr := framework.RetryForDuration(func() error {\n\t\t_, err := fm.Cadvisor().Client().DockerContainer(containerID, &v1.ContainerInfoRequest{NumStats: 1})\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\treturn nil\n\t}, 5*time.Second)\n\tassert.NoError(fm.T(), err)\n}\n"
  },
  {
    "path": "integration/tests/api/test_utils.go",
    "content": "// Copyright 2014 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n//go:build linux\n\npackage api\n\nimport (\n\t\"testing\"\n\t\"time\"\n\n\tinfo \"github.com/google/cadvisor/info/v1\"\n\n\t\"github.com/opencontainers/cgroups\"\n\t\"github.com/stretchr/testify/assert\"\n\t\"k8s.io/klog/v2\"\n)\n\nfunc init() {\n\tklog.InitFlags(nil)\n}\n\n// Checks that expected and actual are within delta of each other.\nfunc inDelta(t *testing.T, expected, actual, delta uint64, description string) {\n\tvar diff uint64\n\tif expected > actual {\n\t\tdiff = expected - actual\n\t} else {\n\t\tdiff = actual - expected\n\t}\n\tif diff > delta {\n\t\tt.Errorf(\"%s (%d and %d) are not within %d of each other\", description, expected, actual, delta)\n\t}\n}\n\n// Checks that CPU stats are valid.\nfunc checkCPUStats(t *testing.T, stat info.CpuStats) {\n\tassert := assert.New(t)\n\n\tassert.NotEqual(0, stat.Usage.Total, \"Total CPU usage should not be zero\")\n\n\t// PerCPU CPU usage is not supported in cgroupv2 (cpuacct.usage_percpu)\n\t// https://github.com/google/cadvisor/issues/3065\n\tif !cgroups.IsCgroup2UnifiedMode() {\n\t\tassert.NotEmpty(stat.Usage.PerCpu, \"Per-core usage should not be empty\")\n\n\t\ttotalUsage := uint64(0)\n\t\tfor _, usage := range stat.Usage.PerCpu {\n\t\t\ttotalUsage += usage\n\t\t}\n\t\tinDelta(t, stat.Usage.Total, totalUsage, uint64((5 * time.Millisecond).Nanoseconds()), \"Per-core CPU usage\")\n\t}\n\n\tinDelta(t, stat.Usage.Total, stat.Usage.User+stat.Usage.System, uint64((500 * time.Millisecond).Nanoseconds()), \"User + system CPU usage\")\n\t// TODO(rjnagal): Add verification for cpu load.\n}\n\nfunc checkMemoryStats(t *testing.T, stat info.MemoryStats) {\n\tassert := assert.New(t)\n\n\tassert.NotEqual(0, stat.Usage, \"Memory usage should not be zero\")\n\tassert.NotEqual(0, stat.WorkingSet, \"Memory working set should not be zero\")\n\tassert.NotEqual(0, stat.TotalActiveFile, \"Memory total active file should not be zero\")\n\tassert.NotEqual(0, stat.TotalInactiveFile, \"Memory total inactive file should not be zero\")\n\tif stat.WorkingSet > stat.Usage {\n\t\tt.Errorf(\"Memory working set (%d) should be at most equal to memory usage (%d)\", stat.WorkingSet, stat.Usage)\n\t}\n\t// TODO(vmarmol): Add checks for ContainerData and HierarchicalData\n}\n"
  },
  {
    "path": "integration/tests/common/attributes_test.go",
    "content": "// Copyright 2015 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage common\n\nimport (\n\t\"testing\"\n\n\t\"github.com/google/cadvisor/integration/framework\"\n\n\t\"github.com/stretchr/testify/assert\"\n)\n\nfunc TestAttributeInformationIsReturned(t *testing.T) {\n\tfm := framework.New(t)\n\tdefer fm.Cleanup()\n\n\tattributes, err := fm.Cadvisor().ClientV2().Attributes()\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\n\tvp := `\\d+\\.\\d+\\.\\d+`\n\tassert.True(t, assert.Regexp(t, vp, attributes.KernelVersion),\n\t\t\"Expected %s to match %s\", attributes.KernelVersion, vp)\n}\n"
  },
  {
    "path": "integration/tests/common/healthz_test.go",
    "content": "// Copyright 2014 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage common\n\nimport (\n\t\"io\"\n\t\"net/http\"\n\t\"testing\"\n\n\t\"github.com/google/cadvisor/integration/framework\"\n)\n\nfunc TestHealthzOk(t *testing.T) {\n\tfm := framework.New(t)\n\tdefer fm.Cleanup()\n\n\t// Ensure that /healthz returns \"ok\"\n\tresp, err := http.Get(fm.Hostname().FullHostname() + \"healthz\")\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\tdefer resp.Body.Close()\n\tbody, err := io.ReadAll(resp.Body)\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\n\tif string(body) != \"ok\" {\n\t\tt.Fatalf(\"cAdvisor returned unexpected healthz status of %q\", body)\n\t}\n}\n"
  },
  {
    "path": "integration/tests/common/machine_test.go",
    "content": "// Copyright 2014 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n// Package common contains integration tests that are runtime-independent.\n// These tests work with any container runtime (Docker, CRI-O, containerd, etc.)\n// and test cAdvisor's core functionality like machine info, attributes, and health.\npackage common\n\nimport (\n\t\"testing\"\n\n\t\"github.com/google/cadvisor/integration/framework\"\n)\n\nfunc TestMachineInformationIsReturned(t *testing.T) {\n\tfm := framework.New(t)\n\tdefer fm.Cleanup()\n\n\tmachineInfo, err := fm.Cadvisor().Client().MachineInfo()\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\n\t// Check for \"sane\" values. Note these can change with time.\n\tif machineInfo.NumCores <= 0 || machineInfo.NumCores >= 1000000 {\n\t\tt.Errorf(\"Machine info has unexpected number of cores: %v\", machineInfo.NumCores)\n\t}\n\tif machineInfo.MemoryCapacity == 0 || machineInfo.MemoryCapacity >= (1<<50 /* 1PB */) {\n\t\tt.Errorf(\"Machine info has unexpected amount of memory: %v\", machineInfo.MemoryCapacity)\n\t}\n\tif len(machineInfo.Filesystems) == 0 {\n\t\tt.Errorf(\"Expected to have some filesystems, found none\")\n\t}\n\tfor _, fs := range machineInfo.Filesystems {\n\t\tif fs.Device == \"\" {\n\t\t\tt.Errorf(\"Expected a non-empty device name in: %+v\", fs)\n\t\t}\n\t\tif fs.Capacity >= (1 << 60 /* 1 EB*/) {\n\t\t\tt.Errorf(\"Unexpected capacity in device %q: %v\", fs.Device, fs.Capacity)\n\t\t}\n\t\tif fs.Type == \"\" {\n\t\t\tt.Errorf(\"Filesystem type is not set\")\n\t\t} else if fs.Type == \"vfs\" && fs.Inodes == 0 {\n\t\t\tif fs.Device != \"devpts\" {\n\t\t\t\tt.Errorf(\"Inodes not available for device %q\", fs.Device)\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "integration/tests/common/machinestats_test.go",
    "content": "// Copyright 2015 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n//go:build linux\n\npackage common\n\nimport (\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/stretchr/testify/assert\"\n\t\"github.com/stretchr/testify/require\"\n\n\t\"github.com/opencontainers/cgroups\"\n\n\t\"github.com/google/cadvisor/integration/framework\"\n)\n\nfunc TestMachineStatsIsReturned(t *testing.T) {\n\tfm := framework.New(t)\n\tdefer fm.Cleanup()\n\n\tmachineStats, err := fm.Cadvisor().ClientV2().MachineStats()\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\n\tas := assert.New(t)\n\tfor _, stat := range machineStats {\n\t\tas.NotEqual(stat.Timestamp, time.Time{})\n\t\tas.True(stat.Cpu.Usage.Total > 0)\n\t\t// PerCPU CPU usage is not supported in cgroupv2 (cpuacct.usage_percpu)\n\t\t// https://github.com/google/cadvisor/issues/3065\n\t\tif !cgroups.IsCgroup2UnifiedMode() {\n\t\t\tas.True(len(stat.Cpu.Usage.PerCpu) > 0)\n\t\t}\n\t\tif stat.CpuInst != nil {\n\t\t\tas.True(stat.CpuInst.Usage.Total > 0)\n\t\t}\n\t\tas.True(stat.Memory.Usage > 0)\n\t\tfor _, nStat := range stat.Network.Interfaces {\n\t\t\tas.NotEqual(nStat.Name, \"\")\n\t\t\tas.NotEqual(nStat.RxBytes, 0)\n\t\t}\n\t\tfor _, fsStat := range stat.Filesystem {\n\t\t\tas.NotEqual(fsStat.Device, \"\")\n\t\t\tas.NotNil(fsStat.Capacity)\n\t\t\tas.NotNil(fsStat.Usage)\n\t\t\tas.NotNil(fsStat.ReadsCompleted)\n\t\t\trequire.NotEmpty(t, fsStat.Type)\n\t\t\tif fsStat.Type == \"vfs\" {\n\t\t\t\tas.NotNil(fsStat.InodesFree)\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "integration/tests/crio/crio_test.go",
    "content": "// Copyright 2024 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n//go:build linux\n\npackage crio\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\t\"testing\"\n\t\"time\"\n\n\tinfo \"github.com/google/cadvisor/info/v1\"\n\tv2 \"github.com/google/cadvisor/info/v2\"\n\t\"github.com/google/cadvisor/integration/framework\"\n\n\t\"github.com/stretchr/testify/assert\"\n\t\"github.com/stretchr/testify/require\"\n)\n\n// Waits up to 10s for a CRI-O container with the specified ID to appear in cAdvisor.\n// CRI-O containers may take longer to appear due to the pod sandbox model.\nfunc waitForCrioContainer(containerID string, fm framework.Framework) {\n\terr := framework.RetryForDuration(func() error {\n\t\t// Query all containers via SubcontainersInfo - CRI-O containers are in \"crio\" namespace,\n\t\t// not \"docker\" namespace, so AllDockerContainers won't find them.\n\t\tallInfo, err := fm.Cadvisor().Client().SubcontainersInfo(\"/\", &info.ContainerInfoRequest{\n\t\t\tNumStats: 1,\n\t\t})\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\t// Look for container by ID (CRI-O containers appear with crio- prefix in cgroup)\n\t\tfor _, container := range allInfo {\n\t\t\tfor _, alias := range container.Aliases {\n\t\t\t\tif alias == containerID {\n\t\t\t\t\treturn nil\n\t\t\t\t}\n\t\t\t}\n\t\t\t// Also check if the container name contains the ID\n\t\t\tif len(container.Name) > 0 && contains(container.Name, containerID) {\n\t\t\t\treturn nil\n\t\t\t}\n\t\t}\n\t\treturn fmt.Errorf(\"container %q not found in cAdvisor\", containerID)\n\t}, 10*time.Second)\n\trequire.NoError(fm.T(), err, \"Timed out waiting for CRI-O container %q to be available in cAdvisor\", containerID)\n}\n\nfunc contains(s, substr string) bool {\n\treturn len(s) >= len(substr) && (s == substr || len(s) > len(substr) && (s[:len(substr)] == substr || s[len(s)-len(substr):] == substr || findSubstring(s, substr)))\n}\n\nfunc findSubstring(s, substr string) bool {\n\tfor i := 0; i <= len(s)-len(substr); i++ {\n\t\tif s[i:i+len(substr)] == substr {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\n// Sanity check the container by:\n// - Checking that the specified ID is a valid alias for this container.\n// - Verifying that stats are not empty.\nfunc sanityCheck(containerID string, containerInfo info.ContainerInfo, t *testing.T) {\n\tassert.Contains(t, containerInfo.Aliases, containerID, \"Alias %q should be in list of aliases %v\", containerID, containerInfo.Aliases)\n\tassert.NotEmpty(t, containerInfo.Stats, \"Expected container to have stats\")\n}\n\n// TestCrioContainerById tests that cAdvisor can find a CRI-O container by its ID.\nfunc TestCrioContainerById(t *testing.T) {\n\tfm := framework.New(t)\n\tdefer fm.Cleanup()\n\n\tcontainerID := fm.Crio().RunPause()\n\n\t// Wait for the container to show up in cAdvisor\n\twaitForCrioContainer(containerID, fm)\n\n\t// Query all containers via SubcontainersInfo - CRI-O containers are in \"crio\" namespace\n\tallInfo, err := fm.Cadvisor().Client().SubcontainersInfo(\"/\", &info.ContainerInfoRequest{\n\t\tNumStats: 1,\n\t})\n\trequire.NoError(t, err)\n\n\t// Find our container\n\tvar found bool\n\tfor _, container := range allInfo {\n\t\tfor _, alias := range container.Aliases {\n\t\t\tif alias == containerID {\n\t\t\t\tsanityCheck(containerID, container, t)\n\t\t\t\tfound = true\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t\tif found {\n\t\t\tbreak\n\t\t}\n\t}\n\tassert.True(t, found, \"Container %q should be found in cAdvisor\", containerID)\n}\n\n// TestCrioContainerByName tests that cAdvisor can find a CRI-O container by a custom name.\nfunc TestCrioContainerByName(t *testing.T) {\n\tfm := framework.New(t)\n\tdefer fm.Cleanup()\n\n\tcontainerName := fmt.Sprintf(\"test-crio-container-by-name-%d\", os.Getpid())\n\tcontainerID := fm.Crio().Run(framework.CrioRunArgs{\n\t\tImage: \"registry.k8s.io/pause:3.9\",\n\t\tName:  containerName,\n\t})\n\n\t// Wait for the container to show up\n\twaitForCrioContainer(containerID, fm)\n\n\t// Query all containers via SubcontainersInfo - CRI-O containers are in \"crio\" namespace\n\tallInfo, err := fm.Cadvisor().Client().SubcontainersInfo(\"/\", &info.ContainerInfoRequest{\n\t\tNumStats: 1,\n\t})\n\trequire.NoError(t, err)\n\n\t// Find our container by ID\n\tvar found bool\n\tfor _, container := range allInfo {\n\t\tfor _, alias := range container.Aliases {\n\t\t\tif alias == containerID {\n\t\t\t\tsanityCheck(containerID, container, t)\n\t\t\t\tfound = true\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t\tif found {\n\t\t\tbreak\n\t\t}\n\t}\n\tassert.True(t, found, \"Container with ID %q should be found in cAdvisor\", containerID)\n}\n\n// TestGetAllCrioContainers tests that cAdvisor can find multiple CRI-O containers.\nfunc TestGetAllCrioContainers(t *testing.T) {\n\tfm := framework.New(t)\n\tdefer fm.Cleanup()\n\n\t// Start two containers\n\tcontainerID1 := fm.Crio().RunPause()\n\tcontainerID2 := fm.Crio().RunPause()\n\n\t// Wait for both containers to show up\n\twaitForCrioContainer(containerID1, fm)\n\twaitForCrioContainer(containerID2, fm)\n\n\t// Query all containers via SubcontainersInfo\n\tallInfo, err := fm.Cadvisor().Client().SubcontainersInfo(\"/\", &info.ContainerInfoRequest{\n\t\tNumStats: 1,\n\t})\n\trequire.NoError(t, err)\n\n\t// Find both containers\n\tvar found1, found2 bool\n\tfor _, container := range allInfo {\n\t\tfor _, alias := range container.Aliases {\n\t\t\tif alias == containerID1 {\n\t\t\t\tsanityCheck(containerID1, container, t)\n\t\t\t\tfound1 = true\n\t\t\t}\n\t\t\tif alias == containerID2 {\n\t\t\t\tsanityCheck(containerID2, container, t)\n\t\t\t\tfound2 = true\n\t\t\t}\n\t\t}\n\t}\n\tassert.True(t, found1, \"Container %q should be found in cAdvisor\", containerID1)\n\tassert.True(t, found2, \"Container %q should be found in cAdvisor\", containerID2)\n}\n\n// TestBasicCrioContainer tests basic container properties.\nfunc TestBasicCrioContainer(t *testing.T) {\n\tfm := framework.New(t)\n\tdefer fm.Cleanup()\n\n\tcontainerID := fm.Crio().RunPause()\n\n\t// Wait for the container to show up\n\twaitForCrioContainer(containerID, fm)\n\n\t// Query all containers via SubcontainersInfo - CRI-O containers are in \"crio\" namespace\n\tallInfo, err := fm.Cadvisor().Client().SubcontainersInfo(\"/\", &info.ContainerInfoRequest{\n\t\tNumStats: 1,\n\t})\n\trequire.NoError(t, err)\n\n\t// Find our container\n\tvar containerInfo *info.ContainerInfo\n\tfor i, container := range allInfo {\n\t\tfor _, alias := range container.Aliases {\n\t\t\tif alias == containerID {\n\t\t\t\tcontainerInfo = &allInfo[i]\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t\tif containerInfo != nil {\n\t\t\tbreak\n\t\t}\n\t}\n\n\trequire.NotNil(t, containerInfo, \"Container %q should be found\", containerID)\n\tassert.NotEmpty(t, containerInfo.Stats, \"Should have at least one stat\")\n}\n\n// TestCrioContainerCpuStats tests CPU statistics collection for CRI-O containers.\nfunc TestCrioContainerCpuStats(t *testing.T) {\n\tfm := framework.New(t)\n\tdefer fm.Cleanup()\n\n\t// Run a busybox container that does some work\n\tcontainerID := fm.Crio().RunBusybox(\"sh\", \"-c\", \"while true; do echo hello; sleep 1; done\")\n\n\t// Wait for the container to show up\n\twaitForCrioContainer(containerID, fm)\n\n\t// Give the container some time to generate CPU usage\n\ttime.Sleep(2 * time.Second)\n\n\t// Query all containers via SubcontainersInfo - CRI-O containers are in \"crio\" namespace\n\tallInfo, err := fm.Cadvisor().Client().SubcontainersInfo(\"/\", &info.ContainerInfoRequest{\n\t\tNumStats: 1,\n\t})\n\trequire.NoError(t, err)\n\n\t// Find our container\n\tvar containerInfo *info.ContainerInfo\n\tfor i, container := range allInfo {\n\t\tfor _, alias := range container.Aliases {\n\t\t\tif alias == containerID {\n\t\t\t\tcontainerInfo = &allInfo[i]\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t\tif containerInfo != nil {\n\t\t\tbreak\n\t\t}\n\t}\n\n\trequire.NotNil(t, containerInfo, \"Container %q should be found\", containerID)\n\trequire.NotEmpty(t, containerInfo.Stats, \"Should have stats\")\n\n\t// Check CPU stats\n\tstat := containerInfo.Stats[0]\n\tcheckCPUStats(t, stat.Cpu)\n}\n\n// TestCrioContainerMemoryStats tests memory statistics collection for CRI-O containers.\nfunc TestCrioContainerMemoryStats(t *testing.T) {\n\tfm := framework.New(t)\n\tdefer fm.Cleanup()\n\n\t// Run a busybox container\n\tcontainerID := fm.Crio().RunBusybox(\"sh\", \"-c\", \"while true; do echo hello; sleep 1; done\")\n\n\t// Wait for the container to show up\n\twaitForCrioContainer(containerID, fm)\n\n\t// Give the container some time to use memory\n\ttime.Sleep(2 * time.Second)\n\n\t// Query all containers via SubcontainersInfo - CRI-O containers are in \"crio\" namespace\n\tallInfo, err := fm.Cadvisor().Client().SubcontainersInfo(\"/\", &info.ContainerInfoRequest{\n\t\tNumStats: 1,\n\t})\n\trequire.NoError(t, err)\n\n\t// Find our container\n\tvar containerInfo *info.ContainerInfo\n\tfor i, container := range allInfo {\n\t\tfor _, alias := range container.Aliases {\n\t\t\tif alias == containerID {\n\t\t\t\tcontainerInfo = &allInfo[i]\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t\tif containerInfo != nil {\n\t\t\tbreak\n\t\t}\n\t}\n\n\trequire.NotNil(t, containerInfo, \"Container %q should be found\", containerID)\n\trequire.NotEmpty(t, containerInfo.Stats, \"Should have stats\")\n\n\t// Check memory stats\n\tstat := containerInfo.Stats[0]\n\tcheckMemoryStats(t, stat.Memory)\n}\n\n// TestCrioContainerNetworkStats tests network statistics collection for CRI-O containers.\n// TODO: Skip this test until network stats collection works reliably for CRI-O containers.\n// In the CI environment, network stats (TxBytes, RxBytes, etc.) are reported as zero,\n// possibly due to CNI network namespace issues in the Docker-in-Docker environment.\nfunc TestCrioContainerNetworkStats(t *testing.T) {\n\tt.Skip(\"Skipping: network stats are not reliably collected for CRI-O containers in CI\")\n\n\tfm := framework.New(t)\n\tdefer fm.Cleanup()\n\n\t// Run a busybox container that generates network traffic\n\tcontainerID := fm.Crio().RunBusybox(\"sh\", \"-c\", \"while true; do wget -q -O /dev/null http://www.google.com/ 2>/dev/null || true; sleep 1; done\")\n\n\t// Wait for the container to show up\n\twaitForCrioContainer(containerID, fm)\n\n\t// Wait for at least one additional housekeeping interval for network stats\n\ttime.Sleep(20 * time.Second)\n\n\t// Query all containers via SubcontainersInfo - CRI-O containers are in \"crio\" namespace\n\tallInfo, err := fm.Cadvisor().Client().SubcontainersInfo(\"/\", &info.ContainerInfoRequest{\n\t\tNumStats: 1,\n\t})\n\trequire.NoError(t, err)\n\n\t// Find our container\n\tvar containerInfo *info.ContainerInfo\n\tfor i, container := range allInfo {\n\t\tfor _, alias := range container.Aliases {\n\t\t\tif alias == containerID {\n\t\t\t\tcontainerInfo = &allInfo[i]\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t\tif containerInfo != nil {\n\t\t\tbreak\n\t\t}\n\t}\n\n\trequire.NotNil(t, containerInfo, \"Container %q should be found\", containerID)\n\trequire.NotEmpty(t, containerInfo.Stats, \"Should have stats\")\n\n\tstat := containerInfo.Stats[0]\n\tifaceStats := stat.Network.InterfaceStats\n\t// Pick eth0 if multiple interfaces exist\n\tif len(stat.Network.Interfaces) > 0 {\n\t\tfor _, iface := range stat.Network.Interfaces {\n\t\t\tif iface.Name == \"eth0\" {\n\t\t\t\tifaceStats = iface\n\t\t\t}\n\t\t}\n\t}\n\n\t// Checks for NetworkStats\n\tassert.NotEqual(t, uint64(0), ifaceStats.TxBytes, \"Network tx bytes should not be zero\")\n\tassert.NotEqual(t, uint64(0), ifaceStats.TxPackets, \"Network tx packets should not be zero\")\n\tassert.NotEqual(t, uint64(0), ifaceStats.RxBytes, \"Network rx bytes should not be zero\")\n\tassert.NotEqual(t, uint64(0), ifaceStats.RxPackets, \"Network rx packets should not be zero\")\n}\n\n// TestCrioContainerSpec tests that container spec is correctly populated for CRI-O containers.\nfunc TestCrioContainerSpec(t *testing.T) {\n\tfm := framework.New(t)\n\tdefer fm.Cleanup()\n\n\tcontainerID := fm.Crio().RunPause()\n\n\t// Wait for the container to show up\n\twaitForCrioContainer(containerID, fm)\n\n\t// Query all containers via SubcontainersInfo - CRI-O containers are in \"crio\" namespace\n\tallInfo, err := fm.Cadvisor().Client().SubcontainersInfo(\"/\", &info.ContainerInfoRequest{\n\t\tNumStats: 1,\n\t})\n\trequire.NoError(t, err)\n\n\t// Find our container\n\tvar containerInfo *info.ContainerInfo\n\tfor i, container := range allInfo {\n\t\tfor _, alias := range container.Aliases {\n\t\t\tif alias == containerID {\n\t\t\t\tcontainerInfo = &allInfo[i]\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t\tif containerInfo != nil {\n\t\t\tbreak\n\t\t}\n\t}\n\n\trequire.NotNil(t, containerInfo, \"Container %q should be found\", containerID)\n\n\t// Check that spec has basic properties\n\tassert.True(t, containerInfo.Spec.HasCpu, \"CPU should be isolated\")\n\tassert.True(t, containerInfo.Spec.HasMemory, \"Memory should be isolated\")\n\t// CRI-O containers may or may not have network depending on pod config\n}\n\n// TestCrioContainerDeletionExitCode tests that container deletion events include exit codes.\n// TODO: Skip this test until cAdvisor properly reports exit codes for CRI-O containers.\n// Currently cAdvisor reports exit code -1 for CRI-O containers even when the container\n// exits with a specific code. This appears to be a timing/integration issue.\nfunc TestCrioContainerDeletionExitCode(t *testing.T) {\n\tt.Skip(\"Skipping: cAdvisor currently reports exit code -1 for CRI-O containers\")\n\n\ttests := []struct {\n\t\tname     string\n\t\texitCode int\n\t}{\n\t\t{\n\t\t\tname:     \"successful exit\",\n\t\t\texitCode: 0,\n\t\t},\n\t\t{\n\t\t\tname:     \"error exit\",\n\t\t\texitCode: 1,\n\t\t},\n\t}\n\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tfm := framework.New(t)\n\t\t\tdefer fm.Cleanup()\n\n\t\t\tcontainerID := fm.Crio().RunBusybox(\"sh\", \"-c\", fmt.Sprintf(\"exit %d\", tt.exitCode))\n\n\t\t\terr := framework.RetryForDuration(func() error {\n\t\t\t\tevents, err := fm.Cadvisor().Client().EventStaticInfo(\"?deletion_events=true&subcontainers=true\")\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn err\n\t\t\t\t}\n\n\t\t\t\tfor _, ev := range events {\n\t\t\t\t\tif ev.EventType == info.EventContainerDeletion {\n\t\t\t\t\t\t// Check if this event is for our container (CRI-O container names contain the ID)\n\t\t\t\t\t\tif contains(ev.ContainerName, containerID) {\n\t\t\t\t\t\t\tif ev.EventData.ContainerDeletion == nil {\n\t\t\t\t\t\t\t\treturn fmt.Errorf(\"deletion event data is nil\")\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif ev.EventData.ContainerDeletion.ExitCode != tt.exitCode {\n\t\t\t\t\t\t\t\tt.Errorf(\"expected exit code %d, got %d\",\n\t\t\t\t\t\t\t\t\ttt.exitCode, ev.EventData.ContainerDeletion.ExitCode)\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treturn nil\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn fmt.Errorf(\"deletion event not found for container %s\", containerID)\n\t\t\t}, 30*time.Second)\n\n\t\t\trequire.NoError(t, err)\n\t\t})\n\t}\n}\n\n// TestCrioHealthState tests health state reporting for CRI-O containers.\n// Docker-style health checks (HEALTHCHECK instruction) are not supported by CRI-O.\n// CRI-O containers rely on Kubernetes liveness/readiness probes instead,\n// which are managed by the kubelet, not the container runtime.\nfunc TestCrioHealthState(t *testing.T) {\n\tt.Skip(\"Skipping: Docker-style health checks are not supported by CRI-O (use Kubernetes probes instead)\")\n}\n\n// TestCrioFilesystemStats tests filesystem statistics collection for CRI-O containers.\nfunc TestCrioFilesystemStats(t *testing.T) {\n\tfm := framework.New(t)\n\tdefer fm.Cleanup()\n\n\tconst (\n\t\tddUsage       = uint64(1 << 3) // 1 KB\n\t\tsleepDuration = 10 * time.Second\n\t)\n\n\t// Run a busybox container that creates a file and stays running\n\tcontainerID := fm.Crio().RunBusybox(\"/bin/sh\", \"-c\", \"dd if=/dev/zero of=/file count=2 bs=1024 && while true; do sleep 1; done\")\n\n\t// Wait for the container to show up\n\twaitForCrioContainer(containerID, fm)\n\n\trequest := &v2.RequestOptions{\n\t\tIdType: v2.TypeName,\n\t\tCount:  1,\n\t}\n\n\tpass := false\n\t// We need to wait for the `dd` operation to complete.\n\tfor i := 0; i < 10; i++ {\n\t\t// Query all containers and find ours\n\t\tallInfo, err := fm.Cadvisor().Client().SubcontainersInfo(\"/\", &info.ContainerInfoRequest{\n\t\t\tNumStats: 1,\n\t\t})\n\t\tif err != nil {\n\t\t\tt.Logf(\"%v stats unavailable - %v\", time.Now().String(), err)\n\t\t\tt.Logf(\"retrying after %s...\", sleepDuration.String())\n\t\t\ttime.Sleep(sleepDuration)\n\t\t\tcontinue\n\t\t}\n\n\t\t// Find our container\n\t\tvar containerName string\n\t\tfor _, container := range allInfo {\n\t\t\tfor _, alias := range container.Aliases {\n\t\t\t\tif alias == containerID {\n\t\t\t\t\tcontainerName = container.Name\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t\tif containerName != \"\" {\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\n\t\tif containerName == \"\" {\n\t\t\tt.Logf(\"Container %q not found, retrying...\", containerID)\n\t\t\ttime.Sleep(sleepDuration)\n\t\t\tcontinue\n\t\t}\n\n\t\t// Get stats using v2 API\n\t\tcontainerInfo, err := fm.Cadvisor().ClientV2().Stats(containerName, request)\n\t\tif err != nil {\n\t\t\tt.Logf(\"%v stats unavailable - %v\", time.Now().String(), err)\n\t\t\tt.Logf(\"retrying after %s...\", sleepDuration.String())\n\t\t\ttime.Sleep(sleepDuration)\n\t\t\tcontinue\n\t\t}\n\n\t\tif len(containerInfo) == 0 {\n\t\t\tt.Logf(\"No container info returned, retrying...\")\n\t\t\ttime.Sleep(sleepDuration)\n\t\t\tcontinue\n\t\t}\n\n\t\t// Get the first (and only) container info\n\t\tvar cInfo v2.ContainerInfo\n\t\tfor _, ci := range containerInfo {\n\t\t\tcInfo = ci\n\t\t\tbreak\n\t\t}\n\n\t\tif len(cInfo.Stats) == 0 || cInfo.Stats[0].Filesystem == nil {\n\t\t\tt.Logf(\"No filesystem stats available yet, retrying...\")\n\t\t\ttime.Sleep(sleepDuration)\n\t\t\tcontinue\n\t\t}\n\n\t\tif cInfo.Stats[0].Filesystem.TotalUsageBytes != nil && *cInfo.Stats[0].Filesystem.TotalUsageBytes >= ddUsage {\n\t\t\tpass = true\n\t\t\tbreak\n\t\t}\n\n\t\tt.Logf(\"expected total usage to be greater than %d bytes, retrying...\", ddUsage)\n\t\ttime.Sleep(sleepDuration)\n\t}\n\n\tif !pass {\n\t\tt.Fail()\n\t}\n}\n"
  },
  {
    "path": "integration/tests/crio/test_utils.go",
    "content": "// Copyright 2024 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n//go:build linux\n\npackage crio\n\nimport (\n\t\"testing\"\n\t\"time\"\n\n\tinfo \"github.com/google/cadvisor/info/v1\"\n\n\t\"github.com/opencontainers/cgroups\"\n\t\"github.com/stretchr/testify/assert\"\n\t\"k8s.io/klog/v2\"\n)\n\nfunc init() {\n\tklog.InitFlags(nil)\n}\n\n// Checks that expected and actual are within delta of each other.\nfunc inDelta(t *testing.T, expected, actual, delta uint64, description string) {\n\tvar diff uint64\n\tif expected > actual {\n\t\tdiff = expected - actual\n\t} else {\n\t\tdiff = actual - expected\n\t}\n\tif diff > delta {\n\t\tt.Errorf(\"%s (%d and %d) are not within %d of each other\", description, expected, actual, delta)\n\t}\n}\n\n// Checks that CPU stats are valid.\nfunc checkCPUStats(t *testing.T, stat info.CpuStats) {\n\tassert := assert.New(t)\n\n\tassert.NotEqual(0, stat.Usage.Total, \"Total CPU usage should not be zero\")\n\n\t// PerCPU CPU usage is not supported in cgroupv2 (cpuacct.usage_percpu)\n\t// https://github.com/google/cadvisor/issues/3065\n\tif !cgroups.IsCgroup2UnifiedMode() {\n\t\tassert.NotEmpty(stat.Usage.PerCpu, \"Per-core usage should not be empty\")\n\n\t\ttotalUsage := uint64(0)\n\t\tfor _, usage := range stat.Usage.PerCpu {\n\t\t\ttotalUsage += usage\n\t\t}\n\t\tinDelta(t, stat.Usage.Total, totalUsage, uint64((5 * time.Millisecond).Nanoseconds()), \"Per-core CPU usage\")\n\t}\n\n\tinDelta(t, stat.Usage.Total, stat.Usage.User+stat.Usage.System, uint64((500 * time.Millisecond).Nanoseconds()), \"User + system CPU usage\")\n}\n\nfunc checkMemoryStats(t *testing.T, stat info.MemoryStats) {\n\tassert := assert.New(t)\n\n\tassert.NotEqual(0, stat.Usage, \"Memory usage should not be zero\")\n\tassert.NotEqual(0, stat.WorkingSet, \"Memory working set should not be zero\")\n\tif stat.WorkingSet > stat.Usage {\n\t\tt.Errorf(\"Memory working set (%d) should be at most equal to memory usage (%d)\", stat.WorkingSet, stat.Usage)\n\t}\n}\n"
  },
  {
    "path": "integration/tests/healthz/doc.go",
    "content": "// Copyright 2024 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n// Package healthz contains healthz endpoint integration tests.\n//\n// Deprecated: This package is deprecated. Use integration/tests/common instead,\n// which contains the same healthz tests along with other runtime-independent tests.\npackage healthz\n"
  },
  {
    "path": "integration/tests/healthz/healthz_test.go",
    "content": "// Copyright 2014 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage healthz\n\nimport (\n\t\"io\"\n\t\"net/http\"\n\t\"testing\"\n\n\t\"github.com/google/cadvisor/integration/framework\"\n)\n\nfunc TestHealthzOk(t *testing.T) {\n\tfm := framework.New(t)\n\tdefer fm.Cleanup()\n\n\t// Ensure that /heathz returns \"ok\"\n\tresp, err := http.Get(fm.Hostname().FullHostname() + \"healthz\")\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\tdefer resp.Body.Close()\n\tbody, err := io.ReadAll(resp.Body)\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\n\tif string(body) != \"ok\" {\n\t\tt.Fatalf(\"cAdvisor returned unexpected healthz status of %q\", body)\n\t}\n}\n"
  },
  {
    "path": "integration/tests/healthz/test_utils.go",
    "content": "// Copyright 2014 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage healthz\n\nimport \"k8s.io/klog/v2\"\n\nfunc init() {\n\tklog.InitFlags(nil)\n}\n"
  },
  {
    "path": "integration/tests/metrics/containerd_metrics_test.go",
    "content": "//go:build linux\n\n// Copyright 2024 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage metrics\n\nimport (\n\t\"strings\"\n\t\"testing\"\n\t\"time\"\n\n\tinfo \"github.com/google/cadvisor/info/v1\"\n\t\"github.com/google/cadvisor/integration/framework\"\n\t\"github.com/stretchr/testify/assert\"\n\t\"github.com/stretchr/testify/require\"\n)\n\n// waitForContainerdContainerViaAPI waits for a containerd container to appear in cAdvisor\n// using the API client, which is more reliable than searching metrics labels.\nfunc waitForContainerdContainerViaAPI(containerID string, fm framework.Framework, timeout time.Duration) bool {\n\tdeadline := time.Now().Add(timeout)\n\tfor time.Now().Before(deadline) {\n\t\tallInfo, err := fm.Cadvisor().Client().SubcontainersInfo(\"/\", &info.ContainerInfoRequest{\n\t\t\tNumStats: 1,\n\t\t})\n\t\tif err != nil {\n\t\t\ttime.Sleep(500 * time.Millisecond)\n\t\t\tcontinue\n\t\t}\n\n\t\t// Look for container by ID in aliases or name\n\t\tfor _, container := range allInfo {\n\t\t\tfor _, alias := range container.Aliases {\n\t\t\t\tif alias == containerID {\n\t\t\t\t\treturn true\n\t\t\t\t}\n\t\t\t}\n\t\t\tif strings.Contains(container.Name, containerID) {\n\t\t\t\treturn true\n\t\t\t}\n\t\t}\n\t\ttime.Sleep(500 * time.Millisecond)\n\t}\n\treturn false\n}\n\n// getContainerdContainerMetricID finds the 'id' label value used for a containerd container\n// in Prometheus metrics by searching all metrics for one containing the container ID.\nfunc getContainerdContainerMetricID(fm framework.Framework, containerID string) string {\n\tclient := framework.NewMetricsClient(fm.Hostname())\n\tfamilies, err := client.FetchAndParse()\n\tif err != nil {\n\t\treturn \"\"\n\t}\n\n\t// Search in CPU metrics for the container\n\tcpuMetric, ok := framework.GetMetricFamily(families, \"container_cpu_usage_seconds_total\")\n\tif !ok {\n\t\treturn \"\"\n\t}\n\n\t// Look for any metric where the 'id' label contains our container ID\n\tfor _, metric := range cpuMetric.GetMetric() {\n\t\tid := framework.GetLabelValue(metric, \"id\")\n\t\tif strings.Contains(id, containerID) {\n\t\t\treturn id\n\t\t}\n\t}\n\n\treturn \"\"\n}\n\n// TestContainerdContainerAppearsInMetrics verifies a containerd container's metrics are exposed.\nfunc TestContainerdContainerAppearsInMetrics(t *testing.T) {\n\tfm := framework.New(t)\n\tdefer fm.Cleanup()\n\n\t// Start a containerd container\n\tcontainerID := fm.Containerd().RunPause()\n\n\t// Wait for container to appear via API first (more reliable)\n\tfound := waitForContainerdContainerViaAPI(containerID, fm, 15*time.Second)\n\trequire.True(t, found, \"Containerd container %s should appear in cAdvisor API within 15 seconds\", containerID)\n\n\t// Now verify it appears in Prometheus metrics\n\tmetricID := getContainerdContainerMetricID(fm, containerID)\n\trequire.NotEmpty(t, metricID, \"Containerd container %s should appear in Prometheus metrics\", containerID)\n}\n\n// TestContainerdContainerCPUMetrics verifies CPU metrics for containerd containers.\nfunc TestContainerdContainerCPUMetrics(t *testing.T) {\n\tfm := framework.New(t)\n\tdefer fm.Cleanup()\n\n\t// Start a container that does some CPU work\n\tcontainerID := fm.Containerd().RunBusybox(\"sh\", \"-c\", \"while true; do :; done\")\n\n\tfound := waitForContainerdContainerViaAPI(containerID, fm, 15*time.Second)\n\trequire.True(t, found, \"Container should appear in cAdvisor\")\n\n\t// Wait for CPU stats to accumulate\n\ttime.Sleep(2 * time.Second)\n\n\tclient := framework.NewMetricsClient(fm.Hostname())\n\tfamilies, err := client.FetchAndParse()\n\trequire.NoError(t, err)\n\n\tcpuMetric, ok := framework.GetMetricFamily(families, \"container_cpu_usage_seconds_total\")\n\trequire.True(t, ok)\n\n\t// Find metrics for our container (search for container ID substring)\n\tmetrics := framework.FindMetricsWithLabelSubstring(cpuMetric, \"id\", containerID)\n\trequire.NotEmpty(t, metrics, \"Should find CPU metrics for containerd container\")\n\n\t// Active container should have some CPU usage\n\thasPositiveValue := false\n\tfor _, m := range metrics {\n\t\tif framework.GetCounterValue(m) > 0 {\n\t\t\thasPositiveValue = true\n\t\t\tbreak\n\t\t}\n\t}\n\tassert.True(t, hasPositiveValue, \"Active containerd container should have positive CPU usage\")\n}\n\n// TestContainerdContainerMemoryMetrics verifies memory metrics for containerd containers.\nfunc TestContainerdContainerMemoryMetrics(t *testing.T) {\n\tfm := framework.New(t)\n\tdefer fm.Cleanup()\n\n\tcontainerID := fm.Containerd().RunPause()\n\n\tfound := waitForContainerdContainerViaAPI(containerID, fm, 15*time.Second)\n\trequire.True(t, found)\n\n\tclient := framework.NewMetricsClient(fm.Hostname())\n\tfamilies, err := client.FetchAndParse()\n\trequire.NoError(t, err)\n\n\t// Check container_memory_usage_bytes\n\tmemUsage, ok := framework.GetMetricFamily(families, \"container_memory_usage_bytes\")\n\trequire.True(t, ok)\n\n\tmetrics := framework.FindMetricsWithLabelSubstring(memUsage, \"id\", containerID)\n\trequire.NotEmpty(t, metrics, \"Should find memory usage metrics for containerd container\")\n\n\t// Memory usage should be non-negative\n\tfor _, m := range metrics {\n\t\tusage := framework.GetGaugeValue(m)\n\t\tassert.GreaterOrEqual(t, usage, float64(0), \"Memory usage should be >= 0\")\n\t}\n\n\t// Check container_memory_working_set_bytes\n\tworkingSet, ok := framework.GetMetricFamily(families, \"container_memory_working_set_bytes\")\n\trequire.True(t, ok)\n\n\twsMetrics := framework.FindMetricsWithLabelSubstring(workingSet, \"id\", containerID)\n\trequire.NotEmpty(t, wsMetrics, \"Should find working set metrics for containerd container\")\n}\n\n// TestContainerdContainerLabelsInMetrics verifies container labels appear in metrics.\nfunc TestContainerdContainerLabelsInMetrics(t *testing.T) {\n\tfm := framework.New(t)\n\tdefer fm.Cleanup()\n\n\t// Start a container with custom labels\n\tcontainerID := fm.Containerd().Run(framework.ContainerdRunArgs{\n\t\tImage: \"registry.k8s.io/pause:3.9\",\n\t\tLabels: map[string]string{\n\t\t\t\"io.kubernetes.pod.name\": \"test-pod\",\n\t\t},\n\t})\n\n\tfound := waitForContainerdContainerViaAPI(containerID, fm, 15*time.Second)\n\trequire.True(t, found)\n\n\tclient := framework.NewMetricsClient(fm.Hostname())\n\tfamilies, err := client.FetchAndParse()\n\trequire.NoError(t, err)\n\n\tcpuMetric, ok := framework.GetMetricFamily(families, \"container_cpu_usage_seconds_total\")\n\trequire.True(t, ok)\n\n\tmetrics := framework.FindMetricsWithLabelSubstring(cpuMetric, \"id\", containerID)\n\trequire.NotEmpty(t, metrics)\n\n\t// Check if label appears (labels are prefixed with 'container_label_')\n\t// Note: dots in label names are converted to underscores\n\tmetric := metrics[0]\n\tlabelValue := framework.GetLabelValue(metric, \"container_label_io_kubernetes_pod_name\")\n\tassert.Equal(t, \"test-pod\", labelValue, \"Container label should appear in metrics\")\n}\n\n// TestContainerdContainerImageInMetrics verifies container image name appears in metrics.\nfunc TestContainerdContainerImageInMetrics(t *testing.T) {\n\tfm := framework.New(t)\n\tdefer fm.Cleanup()\n\n\tcontainerID := fm.Containerd().Run(framework.ContainerdRunArgs{\n\t\tImage: \"registry.k8s.io/pause:3.9\",\n\t})\n\n\tfound := waitForContainerdContainerViaAPI(containerID, fm, 15*time.Second)\n\trequire.True(t, found)\n\n\tclient := framework.NewMetricsClient(fm.Hostname())\n\tfamilies, err := client.FetchAndParse()\n\trequire.NoError(t, err)\n\n\tcpuMetric, ok := framework.GetMetricFamily(families, \"container_cpu_usage_seconds_total\")\n\trequire.True(t, ok)\n\n\tmetrics := framework.FindMetricsWithLabelSubstring(cpuMetric, \"id\", containerID)\n\trequire.NotEmpty(t, metrics)\n\n\t// Check image label\n\timage := framework.GetLabelValue(metrics[0], \"image\")\n\tassert.Contains(t, image, \"pause\", \"Image label should contain 'pause'\")\n}\n\n// TestContainerdContainerStartTimeMetric verifies container start time is recorded.\nfunc TestContainerdContainerStartTimeMetric(t *testing.T) {\n\tfm := framework.New(t)\n\tdefer fm.Cleanup()\n\n\tbeforeCreate := time.Now().Unix()\n\tcontainerID := fm.Containerd().RunPause()\n\tafterCreate := time.Now().Unix()\n\n\tfound := waitForContainerdContainerViaAPI(containerID, fm, 15*time.Second)\n\trequire.True(t, found)\n\n\tclient := framework.NewMetricsClient(fm.Hostname())\n\tfamilies, err := client.FetchAndParse()\n\trequire.NoError(t, err)\n\n\tstartTime, ok := framework.GetMetricFamily(families, \"container_start_time_seconds\")\n\trequire.True(t, ok)\n\n\tmetrics := framework.FindMetricsWithLabelSubstring(startTime, \"id\", containerID)\n\trequire.NotEmpty(t, metrics)\n\n\t// Start time should be between beforeCreate and afterCreate (with tolerance)\n\tstartTs := framework.GetGaugeValue(metrics[0])\n\tassert.GreaterOrEqual(t, startTs, float64(beforeCreate-5), \"Start time should be recent\")\n\tassert.LessOrEqual(t, startTs, float64(afterCreate+10), \"Start time should not be far in the future\")\n}\n\n// TestMultipleContainerdContainersInMetrics verifies multiple containers appear correctly.\nfunc TestMultipleContainerdContainersInMetrics(t *testing.T) {\n\tfm := framework.New(t)\n\tdefer fm.Cleanup()\n\n\t// Start multiple containers\n\tcontainer1 := fm.Containerd().RunPause()\n\tcontainer2 := fm.Containerd().RunPause()\n\n\t// Wait for both containers to appear\n\tfound1 := waitForContainerdContainerViaAPI(container1, fm, 15*time.Second)\n\tfound2 := waitForContainerdContainerViaAPI(container2, fm, 15*time.Second)\n\n\trequire.True(t, found1, \"First container should appear in cAdvisor\")\n\trequire.True(t, found2, \"Second container should appear in cAdvisor\")\n\n\tclient := framework.NewMetricsClient(fm.Hostname())\n\tfamilies, err := client.FetchAndParse()\n\trequire.NoError(t, err)\n\n\tcpuMetric, ok := framework.GetMetricFamily(families, \"container_cpu_usage_seconds_total\")\n\trequire.True(t, ok)\n\n\t// Both containers should have distinct metrics\n\tmetrics1 := framework.FindMetricsWithLabelSubstring(cpuMetric, \"id\", container1)\n\tmetrics2 := framework.FindMetricsWithLabelSubstring(cpuMetric, \"id\", container2)\n\n\tassert.NotEmpty(t, metrics1, \"First containerd container should have metrics\")\n\tassert.NotEmpty(t, metrics2, \"Second containerd container should have metrics\")\n\n\t// IDs should be different\n\tid1 := framework.GetLabelValue(metrics1[0], \"id\")\n\tid2 := framework.GetLabelValue(metrics2[0], \"id\")\n\tassert.NotEqual(t, id1, id2, \"Container IDs should be different\")\n}\n\n// TestContainerdContainerDiskIOMetrics verifies disk I/O metrics for containerd containers.\nfunc TestContainerdContainerDiskIOMetrics(t *testing.T) {\n\tfm := framework.New(t)\n\tdefer fm.Cleanup()\n\n\t// Start a container that does some disk I/O\n\tcontainerID := fm.Containerd().RunBusybox(\"sh\", \"-c\", \"dd if=/dev/zero of=/tmp/test bs=1M count=10 2>/dev/null; sleep infinity\")\n\n\tfound := waitForContainerdContainerViaAPI(containerID, fm, 15*time.Second)\n\trequire.True(t, found)\n\n\t// Wait for disk I/O to be recorded\n\ttime.Sleep(3 * time.Second)\n\n\tclient := framework.NewMetricsClient(fm.Hostname())\n\tfamilies, err := client.FetchAndParse()\n\trequire.NoError(t, err)\n\n\t// Check for disk I/O write metrics\n\tfsWrites, ok := framework.GetMetricFamily(families, \"container_fs_writes_bytes_total\")\n\tif ok {\n\t\tmetrics := framework.FindMetricsWithLabelSubstring(fsWrites, \"id\", containerID)\n\t\tif len(metrics) > 0 {\n\t\t\twrites := framework.GetCounterValue(metrics[0])\n\t\t\t// The container wrote at least 10MB\n\t\t\tassert.GreaterOrEqual(t, writes, float64(0), \"Write bytes should be >= 0\")\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "integration/tests/metrics/docker_metrics_test.go",
    "content": "//go:build linux\n\n// Copyright 2024 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage metrics\n\nimport (\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/google/cadvisor/integration/framework\"\n\t\"github.com/stretchr/testify/assert\"\n\t\"github.com/stretchr/testify/require\"\n)\n\n// waitForContainerInMetrics waits for a container to appear in the metrics endpoint.\nfunc waitForContainerInMetrics(_ *testing.T, client *framework.MetricsClient, containerID string, timeout time.Duration) bool {\n\tdeadline := time.Now().Add(timeout)\n\tfor time.Now().Before(deadline) {\n\t\tfamilies, err := client.FetchAndParse()\n\t\tif err != nil {\n\t\t\ttime.Sleep(500 * time.Millisecond)\n\t\t\tcontinue\n\t\t}\n\n\t\tcpuMetric, ok := framework.GetMetricFamily(families, \"container_cpu_usage_seconds_total\")\n\t\tif !ok {\n\t\t\ttime.Sleep(500 * time.Millisecond)\n\t\t\tcontinue\n\t\t}\n\n\t\t// Check if container appears (using first 12 chars of ID)\n\t\tif framework.ContainsLabelValue(cpuMetric, \"id\", containerID[:12]) {\n\t\t\treturn true\n\t\t}\n\t\ttime.Sleep(500 * time.Millisecond)\n\t}\n\treturn false\n}\n\n// TestDockerContainerAppearsInMetrics verifies a Docker container's metrics are exposed.\nfunc TestDockerContainerAppearsInMetrics(t *testing.T) {\n\tfm := framework.New(t)\n\tdefer fm.Cleanup()\n\n\t// Start a Docker container\n\tcontainerID := fm.Docker().RunPause()\n\n\tclient := framework.NewMetricsClient(fm.Hostname())\n\n\t// Wait for container to appear in metrics\n\tfound := waitForContainerInMetrics(t, client, containerID, 10*time.Second)\n\trequire.True(t, found, \"Container %s should appear in metrics within 10 seconds\", containerID[:12])\n}\n\n// TestDockerContainerCPUMetrics verifies CPU metrics are collected for Docker containers.\nfunc TestDockerContainerCPUMetrics(t *testing.T) {\n\tfm := framework.New(t)\n\tdefer fm.Cleanup()\n\n\t// Start a container that does some CPU work\n\tcontainerID := fm.Docker().RunBusybox(\"sh\", \"-c\", \"while true; do :; done\")\n\n\tclient := framework.NewMetricsClient(fm.Hostname())\n\n\t// Wait for container and let it accumulate some CPU time\n\tfound := waitForContainerInMetrics(t, client, containerID, 10*time.Second)\n\trequire.True(t, found, \"Container should appear in metrics\")\n\n\t// Wait a bit more for CPU stats to accumulate\n\ttime.Sleep(2 * time.Second)\n\n\tfamilies, err := client.FetchAndParse()\n\trequire.NoError(t, err)\n\n\t// Check container_cpu_usage_seconds_total\n\tcpuMetric, ok := framework.GetMetricFamily(families, \"container_cpu_usage_seconds_total\")\n\trequire.True(t, ok)\n\n\t// Find metrics for our container\n\tmetrics := framework.FindMetricsWithLabelSubstring(cpuMetric, \"id\", containerID[:12])\n\trequire.NotEmpty(t, metrics, \"Should find CPU metrics for container %s\", containerID[:12])\n\n\t// At least one metric should have a positive value (the container is doing CPU work)\n\thasPositiveValue := false\n\tfor _, m := range metrics {\n\t\tif framework.GetCounterValue(m) > 0 {\n\t\t\thasPositiveValue = true\n\t\t\tbreak\n\t\t}\n\t}\n\tassert.True(t, hasPositiveValue, \"Active container should have positive CPU usage\")\n\n\t// Check container_cpu_user_seconds_total exists for this container\n\tuserCPU, ok := framework.GetMetricFamily(families, \"container_cpu_user_seconds_total\")\n\tif ok {\n\t\tuserMetrics := framework.FindMetricsWithLabelSubstring(userCPU, \"id\", containerID[:12])\n\t\tassert.NotEmpty(t, userMetrics, \"Should have user CPU metrics\")\n\t}\n}\n\n// TestDockerContainerMemoryMetrics verifies memory metrics are collected for Docker containers.\nfunc TestDockerContainerMemoryMetrics(t *testing.T) {\n\tfm := framework.New(t)\n\tdefer fm.Cleanup()\n\n\t// Start a container with a memory limit\n\tcontainerID := fm.Docker().Run(framework.DockerRunArgs{\n\t\tImage: \"registry.k8s.io/pause\",\n\t\tArgs:  []string{\"--memory=128m\"},\n\t})\n\n\tclient := framework.NewMetricsClient(fm.Hostname())\n\n\tfound := waitForContainerInMetrics(t, client, containerID, 10*time.Second)\n\trequire.True(t, found)\n\n\tfamilies, err := client.FetchAndParse()\n\trequire.NoError(t, err)\n\n\t// Check container_memory_usage_bytes\n\tmemUsage, ok := framework.GetMetricFamily(families, \"container_memory_usage_bytes\")\n\trequire.True(t, ok)\n\n\tmetrics := framework.FindMetricsWithLabelSubstring(memUsage, \"id\", containerID[:12])\n\trequire.NotEmpty(t, metrics, \"Should find memory usage metrics\")\n\n\t// Memory usage should be non-negative\n\tfor _, m := range metrics {\n\t\tusage := framework.GetGaugeValue(m)\n\t\tassert.GreaterOrEqual(t, usage, float64(0), \"Memory usage should be >= 0\")\n\t}\n\n\t// Check container_memory_working_set_bytes\n\tworkingSet, ok := framework.GetMetricFamily(families, \"container_memory_working_set_bytes\")\n\trequire.True(t, ok)\n\n\twsMetrics := framework.FindMetricsWithLabelSubstring(workingSet, \"id\", containerID[:12])\n\trequire.NotEmpty(t, wsMetrics, \"Should find working set metrics\")\n\n\t// Check container_spec_memory_limit_bytes shows our limit\n\tmemLimit, ok := framework.GetMetricFamily(families, \"container_spec_memory_limit_bytes\")\n\tif ok {\n\t\tlimitMetrics := framework.FindMetricsWithLabelSubstring(memLimit, \"id\", containerID[:12])\n\t\tif len(limitMetrics) > 0 {\n\t\t\tlimit := framework.GetGaugeValue(limitMetrics[0])\n\t\t\t// 128MB = 134217728 bytes\n\t\t\texpectedLimit := float64(128 * 1024 * 1024)\n\t\t\tassert.Equal(t, expectedLimit, limit, \"Memory limit should be 128MB\")\n\t\t}\n\t}\n}\n\n// TestDockerContainerNetworkMetrics verifies network metrics are collected for Docker containers.\nfunc TestDockerContainerNetworkMetrics(t *testing.T) {\n\tfm := framework.New(t)\n\tdefer fm.Cleanup()\n\n\t// Start a basic container - pause container has minimal network activity\n\tcontainerID := fm.Docker().RunPause()\n\n\tclient := framework.NewMetricsClient(fm.Hostname())\n\n\tfound := waitForContainerInMetrics(t, client, containerID, 10*time.Second)\n\trequire.True(t, found)\n\n\tfamilies, err := client.FetchAndParse()\n\trequire.NoError(t, err)\n\n\t// Check network receive metrics exist\n\trxBytes, ok := framework.GetMetricFamily(families, \"container_network_receive_bytes_total\")\n\trequire.True(t, ok)\n\n\trxMetrics := framework.FindMetricsWithLabelSubstring(rxBytes, \"id\", containerID[:12])\n\t// Network metrics may or may not be present depending on network mode\n\t// Just verify the metric family exists and has proper structure\n\tif len(rxMetrics) > 0 {\n\t\t// Should have 'interface' label\n\t\tiface := framework.GetLabelValue(rxMetrics[0], \"interface\")\n\t\tassert.NotEmpty(t, iface, \"Network metric should have 'interface' label\")\n\t}\n\n\t// Check network transmit metrics exist\n\ttxBytes, ok := framework.GetMetricFamily(families, \"container_network_transmit_bytes_total\")\n\trequire.True(t, ok)\n\n\ttxMetrics := framework.FindMetricsWithLabelSubstring(txBytes, \"id\", containerID[:12])\n\tif len(txMetrics) > 0 {\n\t\tiface := framework.GetLabelValue(txMetrics[0], \"interface\")\n\t\tassert.NotEmpty(t, iface, \"Network metric should have 'interface' label\")\n\t}\n}\n\n// TestDockerContainerLabelsInMetrics verifies container labels appear in metrics.\nfunc TestDockerContainerLabelsInMetrics(t *testing.T) {\n\tfm := framework.New(t)\n\tdefer fm.Cleanup()\n\n\t// Start a container with custom labels\n\tcontainerID := fm.Docker().Run(framework.DockerRunArgs{\n\t\tImage: \"registry.k8s.io/pause\",\n\t\tArgs:  []string{\"--label\", \"test.label=test-value\"},\n\t})\n\n\tclient := framework.NewMetricsClient(fm.Hostname())\n\n\tfound := waitForContainerInMetrics(t, client, containerID, 10*time.Second)\n\trequire.True(t, found)\n\n\tfamilies, err := client.FetchAndParse()\n\trequire.NoError(t, err)\n\n\t// Find our container's metrics\n\tcpuMetric, ok := framework.GetMetricFamily(families, \"container_cpu_usage_seconds_total\")\n\trequire.True(t, ok)\n\n\tmetrics := framework.FindMetricsWithLabelSubstring(cpuMetric, \"id\", containerID[:12])\n\trequire.NotEmpty(t, metrics)\n\n\t// Check if our label appears (labels are prefixed with 'container_label_')\n\t// Note: label dots are converted to underscores\n\tmetric := metrics[0]\n\tlabelValue := framework.GetLabelValue(metric, \"container_label_test_label\")\n\tassert.Equal(t, \"test-value\", labelValue, \"Container label should appear in metrics\")\n}\n\n// TestDockerContainerImageInMetrics verifies container image name appears in metrics.\nfunc TestDockerContainerImageInMetrics(t *testing.T) {\n\tfm := framework.New(t)\n\tdefer fm.Cleanup()\n\n\tcontainerID := fm.Docker().Run(framework.DockerRunArgs{\n\t\tImage: \"registry.k8s.io/pause\",\n\t})\n\n\tclient := framework.NewMetricsClient(fm.Hostname())\n\n\tfound := waitForContainerInMetrics(t, client, containerID, 10*time.Second)\n\trequire.True(t, found)\n\n\tfamilies, err := client.FetchAndParse()\n\trequire.NoError(t, err)\n\n\tcpuMetric, ok := framework.GetMetricFamily(families, \"container_cpu_usage_seconds_total\")\n\trequire.True(t, ok)\n\n\tmetrics := framework.FindMetricsWithLabelSubstring(cpuMetric, \"id\", containerID[:12])\n\trequire.NotEmpty(t, metrics)\n\n\t// Check image label\n\timage := framework.GetLabelValue(metrics[0], \"image\")\n\tassert.Contains(t, image, \"pause\", \"Image label should contain 'pause'\")\n}\n\n// TestDockerContainerStartTimeMetric verifies container start time is recorded.\nfunc TestDockerContainerStartTimeMetric(t *testing.T) {\n\tfm := framework.New(t)\n\tdefer fm.Cleanup()\n\n\tbeforeCreate := time.Now().Unix()\n\tcontainerID := fm.Docker().RunPause()\n\tafterCreate := time.Now().Unix()\n\n\tclient := framework.NewMetricsClient(fm.Hostname())\n\n\tfound := waitForContainerInMetrics(t, client, containerID, 10*time.Second)\n\trequire.True(t, found)\n\n\tfamilies, err := client.FetchAndParse()\n\trequire.NoError(t, err)\n\n\tstartTime, ok := framework.GetMetricFamily(families, \"container_start_time_seconds\")\n\trequire.True(t, ok)\n\n\tmetrics := framework.FindMetricsWithLabelSubstring(startTime, \"id\", containerID[:12])\n\trequire.NotEmpty(t, metrics)\n\n\t// Start time should be between beforeCreate and afterCreate (with some tolerance)\n\tstartTs := framework.GetGaugeValue(metrics[0])\n\tassert.GreaterOrEqual(t, startTs, float64(beforeCreate-5), \"Start time should be recent\")\n\tassert.LessOrEqual(t, startTs, float64(afterCreate+5), \"Start time should not be in the future\")\n}\n\n// TestMultipleDockerContainersInMetrics verifies multiple containers appear correctly.\nfunc TestMultipleDockerContainersInMetrics(t *testing.T) {\n\tfm := framework.New(t)\n\tdefer fm.Cleanup()\n\n\t// Start multiple containers\n\tcontainer1 := fm.Docker().RunPause()\n\tcontainer2 := fm.Docker().RunPause()\n\n\tclient := framework.NewMetricsClient(fm.Hostname())\n\n\t// Wait for both containers to appear\n\tfound1 := waitForContainerInMetrics(t, client, container1, 10*time.Second)\n\tfound2 := waitForContainerInMetrics(t, client, container2, 10*time.Second)\n\n\trequire.True(t, found1, \"First container should appear in metrics\")\n\trequire.True(t, found2, \"Second container should appear in metrics\")\n\n\tfamilies, err := client.FetchAndParse()\n\trequire.NoError(t, err)\n\n\tcpuMetric, ok := framework.GetMetricFamily(families, \"container_cpu_usage_seconds_total\")\n\trequire.True(t, ok)\n\n\t// Both containers should have distinct metrics\n\tmetrics1 := framework.FindMetricsWithLabelSubstring(cpuMetric, \"id\", container1[:12])\n\tmetrics2 := framework.FindMetricsWithLabelSubstring(cpuMetric, \"id\", container2[:12])\n\n\tassert.NotEmpty(t, metrics1, \"First container should have metrics\")\n\tassert.NotEmpty(t, metrics2, \"Second container should have metrics\")\n\n\t// IDs should be different\n\tid1 := framework.GetLabelValue(metrics1[0], \"id\")\n\tid2 := framework.GetLabelValue(metrics2[0], \"id\")\n\tassert.NotEqual(t, id1, id2, \"Container IDs should be different\")\n}\n\n// TestDockerContainerFilesystemMetrics verifies filesystem metrics for Docker containers.\nfunc TestDockerContainerFilesystemMetrics(t *testing.T) {\n\tfm := framework.New(t)\n\tdefer fm.Cleanup()\n\n\tcontainerID := fm.Docker().RunPause()\n\n\tclient := framework.NewMetricsClient(fm.Hostname())\n\n\tfound := waitForContainerInMetrics(t, client, containerID, 10*time.Second)\n\trequire.True(t, found)\n\n\tfamilies, err := client.FetchAndParse()\n\trequire.NoError(t, err)\n\n\t// Check filesystem usage metric\n\tfsUsage, ok := framework.GetMetricFamily(families, \"container_fs_usage_bytes\")\n\tif ok {\n\t\tmetrics := framework.FindMetricsWithLabelSubstring(fsUsage, \"id\", containerID[:12])\n\t\t// Filesystem metrics may not always be available for all containers\n\t\tif len(metrics) > 0 {\n\t\t\tusage := framework.GetGaugeValue(metrics[0])\n\t\t\tassert.GreaterOrEqual(t, usage, float64(0), \"Filesystem usage should be >= 0\")\n\n\t\t\t// Should have 'device' label\n\t\t\tdevice := framework.GetLabelValue(metrics[0], \"device\")\n\t\t\tassert.NotEmpty(t, device, \"Filesystem metric should have 'device' label\")\n\t\t}\n\t}\n}\n\n// TestDockerContainerMemoryFailcnt verifies memory failcnt metric exists.\nfunc TestDockerContainerMemoryFailcnt(t *testing.T) {\n\tfm := framework.New(t)\n\tdefer fm.Cleanup()\n\n\tcontainerID := fm.Docker().Run(framework.DockerRunArgs{\n\t\tImage: \"registry.k8s.io/pause\",\n\t\tArgs:  []string{\"--memory=64m\"},\n\t})\n\n\tclient := framework.NewMetricsClient(fm.Hostname())\n\n\tfound := waitForContainerInMetrics(t, client, containerID, 10*time.Second)\n\trequire.True(t, found)\n\n\tfamilies, err := client.FetchAndParse()\n\trequire.NoError(t, err)\n\n\t// container_memory_failcnt should exist (may be 0 for healthy containers)\n\tfailcnt, ok := framework.GetMetricFamily(families, \"container_memory_failcnt\")\n\tif ok {\n\t\tmetrics := framework.FindMetricsWithLabelSubstring(failcnt, \"id\", containerID[:12])\n\t\tif len(metrics) > 0 {\n\t\t\tcount := framework.GetCounterValue(metrics[0])\n\t\t\tassert.GreaterOrEqual(t, count, float64(0), \"Failcnt should be >= 0\")\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "integration/tests/metrics/prometheus_test.go",
    "content": "//go:build linux\n\n// Copyright 2024 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n// Package metrics provides integration tests for cAdvisor's Prometheus /metrics endpoint.\npackage metrics\n\nimport (\n\t\"strings\"\n\t\"testing\"\n\n\t\"github.com/google/cadvisor/integration/framework\"\n\t\"github.com/stretchr/testify/assert\"\n\t\"github.com/stretchr/testify/require\"\n)\n\n// TestMetricsEndpointReturns200 verifies the /metrics endpoint is accessible\n// and returns a 200 status code.\nfunc TestMetricsEndpointReturns200(t *testing.T) {\n\tfm := framework.New(t)\n\tdefer fm.Cleanup()\n\n\tclient := framework.NewMetricsClient(fm.Hostname())\n\ttext, err := client.Fetch()\n\trequire.NoError(t, err, \"Failed to fetch /metrics\")\n\trequire.NotEmpty(t, text, \"/metrics returned empty response\")\n}\n\n// TestMetricsEndpointReturnsValidPrometheusFormat verifies the response\n// can be parsed as valid Prometheus text format.\nfunc TestMetricsEndpointReturnsValidPrometheusFormat(t *testing.T) {\n\tfm := framework.New(t)\n\tdefer fm.Cleanup()\n\n\tclient := framework.NewMetricsClient(fm.Hostname())\n\tfamilies, err := client.FetchAndParse()\n\trequire.NoError(t, err, \"Failed to parse Prometheus metrics\")\n\trequire.NotEmpty(t, families, \"No metric families found\")\n}\n\n// TestCadvisorVersionInfoExists verifies the cadvisor_version_info metric is present\n// and has expected labels.\nfunc TestCadvisorVersionInfoExists(t *testing.T) {\n\tfm := framework.New(t)\n\tdefer fm.Cleanup()\n\n\tclient := framework.NewMetricsClient(fm.Hostname())\n\tfamilies, err := client.FetchAndParse()\n\trequire.NoError(t, err)\n\n\tversionInfo, ok := framework.GetMetricFamily(families, \"cadvisor_version_info\")\n\trequire.True(t, ok, \"cadvisor_version_info metric should exist\")\n\trequire.NotEmpty(t, versionInfo.GetMetric(), \"cadvisor_version_info should have at least one sample\")\n\n\t// Check that expected labels are present\n\tmetric := versionInfo.GetMetric()[0]\n\tlabels := make(map[string]bool)\n\tfor _, lp := range metric.GetLabel() {\n\t\tlabels[lp.GetName()] = true\n\t}\n\n\tassert.True(t, labels[\"cadvisorVersion\"], \"Should have cadvisorVersion label\")\n\tassert.True(t, labels[\"kernelVersion\"], \"Should have kernelVersion label\")\n\tassert.True(t, labels[\"osVersion\"], \"Should have osVersion label\")\n}\n\n// TestCoreCPUMetricsExist verifies essential CPU metrics are present.\nfunc TestCoreCPUMetricsExist(t *testing.T) {\n\tfm := framework.New(t)\n\tdefer fm.Cleanup()\n\n\tclient := framework.NewMetricsClient(fm.Hostname())\n\tfamilies, err := client.FetchAndParse()\n\trequire.NoError(t, err)\n\n\tcpuMetrics := []string{\n\t\t\"container_cpu_usage_seconds_total\",\n\t\t\"container_cpu_user_seconds_total\",\n\t\t\"container_cpu_system_seconds_total\",\n\t}\n\n\tfor _, name := range cpuMetrics {\n\t\tassert.True(t, framework.HasMetric(families, name),\n\t\t\t\"CPU metric %q should exist\", name)\n\t}\n\n\t// Verify container_cpu_usage_seconds_total is a counter\n\tcpuUsage, ok := framework.GetMetricFamily(families, \"container_cpu_usage_seconds_total\")\n\trequire.True(t, ok)\n\tassert.Equal(t, \"COUNTER\", framework.GetMetricType(cpuUsage),\n\t\t\"container_cpu_usage_seconds_total should be a counter\")\n}\n\n// TestCoreMemoryMetricsExist verifies essential memory metrics are present.\nfunc TestCoreMemoryMetricsExist(t *testing.T) {\n\tfm := framework.New(t)\n\tdefer fm.Cleanup()\n\n\tclient := framework.NewMetricsClient(fm.Hostname())\n\tfamilies, err := client.FetchAndParse()\n\trequire.NoError(t, err)\n\n\tmemoryMetrics := []string{\n\t\t\"container_memory_usage_bytes\",\n\t\t\"container_memory_working_set_bytes\",\n\t\t\"container_memory_cache\",\n\t\t\"container_memory_rss\",\n\t}\n\n\tfor _, name := range memoryMetrics {\n\t\tassert.True(t, framework.HasMetric(families, name),\n\t\t\t\"Memory metric %q should exist\", name)\n\t}\n\n\t// Verify container_memory_usage_bytes is a gauge\n\tmemUsage, ok := framework.GetMetricFamily(families, \"container_memory_usage_bytes\")\n\trequire.True(t, ok)\n\tassert.Equal(t, \"GAUGE\", framework.GetMetricType(memUsage),\n\t\t\"container_memory_usage_bytes should be a gauge\")\n}\n\n// TestCoreNetworkMetricsExist verifies essential network metrics are present.\nfunc TestCoreNetworkMetricsExist(t *testing.T) {\n\tfm := framework.New(t)\n\tdefer fm.Cleanup()\n\n\tclient := framework.NewMetricsClient(fm.Hostname())\n\tfamilies, err := client.FetchAndParse()\n\trequire.NoError(t, err)\n\n\tnetworkMetrics := []string{\n\t\t\"container_network_receive_bytes_total\",\n\t\t\"container_network_transmit_bytes_total\",\n\t\t\"container_network_receive_packets_total\",\n\t\t\"container_network_transmit_packets_total\",\n\t}\n\n\tfor _, name := range networkMetrics {\n\t\tassert.True(t, framework.HasMetric(families, name),\n\t\t\t\"Network metric %q should exist\", name)\n\t}\n}\n\n// TestCoreFilesystemMetricsExist verifies essential filesystem metrics are present.\nfunc TestCoreFilesystemMetricsExist(t *testing.T) {\n\tfm := framework.New(t)\n\tdefer fm.Cleanup()\n\n\tclient := framework.NewMetricsClient(fm.Hostname())\n\tfamilies, err := client.FetchAndParse()\n\trequire.NoError(t, err)\n\n\tfsMetrics := []string{\n\t\t\"container_fs_usage_bytes\",\n\t\t\"container_fs_limit_bytes\",\n\t}\n\n\tfor _, name := range fsMetrics {\n\t\tassert.True(t, framework.HasMetric(families, name),\n\t\t\t\"Filesystem metric %q should exist\", name)\n\t}\n}\n\n// TestContainerSpecMetricsExist verifies container specification metrics are present.\nfunc TestContainerSpecMetricsExist(t *testing.T) {\n\tfm := framework.New(t)\n\tdefer fm.Cleanup()\n\n\tclient := framework.NewMetricsClient(fm.Hostname())\n\tfamilies, err := client.FetchAndParse()\n\trequire.NoError(t, err)\n\n\tspecMetrics := []string{\n\t\t\"container_start_time_seconds\",\n\t\t\"container_spec_memory_limit_bytes\",\n\t}\n\n\tfor _, name := range specMetrics {\n\t\tassert.True(t, framework.HasMetric(families, name),\n\t\t\t\"Spec metric %q should exist\", name)\n\t}\n}\n\n// TestMachineMetricsExist verifies machine-level metrics are present with reasonable values.\nfunc TestMachineMetricsExist(t *testing.T) {\n\tfm := framework.New(t)\n\tdefer fm.Cleanup()\n\n\tclient := framework.NewMetricsClient(fm.Hostname())\n\tfamilies, err := client.FetchAndParse()\n\trequire.NoError(t, err)\n\n\tmachineMetrics := []string{\n\t\t\"machine_cpu_cores\",\n\t\t\"machine_cpu_physical_cores\",\n\t\t\"machine_memory_bytes\",\n\t}\n\n\tfor _, name := range machineMetrics {\n\t\tassert.True(t, framework.HasMetric(families, name),\n\t\t\t\"Machine metric %q should exist\", name)\n\t}\n\n\t// Verify machine_cpu_cores has a reasonable value (1 to 1024 cores)\n\tcpuCores, ok := framework.GetMetricFamily(families, \"machine_cpu_cores\")\n\trequire.True(t, ok)\n\trequire.NotEmpty(t, cpuCores.GetMetric())\n\n\tcores := framework.GetGaugeValue(cpuCores.GetMetric()[0])\n\tassert.GreaterOrEqual(t, cores, float64(1), \"Should have at least 1 CPU core\")\n\tassert.LessOrEqual(t, cores, float64(1024), \"CPU core count seems unreasonably high\")\n\n\t// Verify machine_memory_bytes has a reasonable value (100MB to 100TB)\n\tmemBytes, ok := framework.GetMetricFamily(families, \"machine_memory_bytes\")\n\trequire.True(t, ok)\n\trequire.NotEmpty(t, memBytes.GetMetric())\n\n\tmem := framework.GetGaugeValue(memBytes.GetMetric()[0])\n\tassert.GreaterOrEqual(t, mem, float64(100*1024*1024), \"Machine memory should be at least 100MB\")\n\tassert.LessOrEqual(t, mem, float64(100*1024*1024*1024*1024), \"Machine memory seems unreasonably high\")\n}\n\n// TestMetricsHaveCorrectTypes verifies that metric types are correct.\nfunc TestMetricsHaveCorrectTypes(t *testing.T) {\n\tfm := framework.New(t)\n\tdefer fm.Cleanup()\n\n\tclient := framework.NewMetricsClient(fm.Hostname())\n\tfamilies, err := client.FetchAndParse()\n\trequire.NoError(t, err)\n\n\t// Counters should be COUNTER type\n\tcounterMetrics := []string{\n\t\t\"container_cpu_usage_seconds_total\",\n\t\t\"container_cpu_user_seconds_total\",\n\t\t\"container_cpu_system_seconds_total\",\n\t\t\"container_network_receive_bytes_total\",\n\t\t\"container_network_transmit_bytes_total\",\n\t}\n\tfor _, name := range counterMetrics {\n\t\tif mf, ok := families[name]; ok {\n\t\t\tassert.Equal(t, \"COUNTER\", framework.GetMetricType(mf),\n\t\t\t\t\"%s should be a counter\", name)\n\t\t}\n\t}\n\n\t// Gauges should be GAUGE type\n\tgaugeMetrics := []string{\n\t\t\"container_memory_usage_bytes\",\n\t\t\"container_memory_working_set_bytes\",\n\t\t\"machine_cpu_cores\",\n\t\t\"machine_memory_bytes\",\n\t}\n\tfor _, name := range gaugeMetrics {\n\t\tif mf, ok := families[name]; ok {\n\t\t\tassert.Equal(t, \"GAUGE\", framework.GetMetricType(mf),\n\t\t\t\t\"%s should be a gauge\", name)\n\t\t}\n\t}\n}\n\n// TestMetricsHaveHelpText verifies metrics have help descriptions.\nfunc TestMetricsHaveHelpText(t *testing.T) {\n\tfm := framework.New(t)\n\tdefer fm.Cleanup()\n\n\tclient := framework.NewMetricsClient(fm.Hostname())\n\tfamilies, err := client.FetchAndParse()\n\trequire.NoError(t, err)\n\n\t// Check a few key metrics have non-empty help text\n\tmetricsToCheck := []string{\n\t\t\"container_cpu_usage_seconds_total\",\n\t\t\"container_memory_usage_bytes\",\n\t\t\"machine_memory_bytes\",\n\t}\n\n\tfor _, name := range metricsToCheck {\n\t\tif mf, ok := families[name]; ok {\n\t\t\thelp := mf.GetHelp()\n\t\t\tassert.NotEmpty(t, help, \"Metric %s should have help text\", name)\n\t\t}\n\t}\n}\n\n// TestContainerLastSeenExists verifies the container_last_seen metric is present.\nfunc TestContainerLastSeenExists(t *testing.T) {\n\tfm := framework.New(t)\n\tdefer fm.Cleanup()\n\n\tclient := framework.NewMetricsClient(fm.Hostname())\n\tfamilies, err := client.FetchAndParse()\n\trequire.NoError(t, err)\n\n\tassert.True(t, framework.HasMetric(families, \"container_last_seen\"),\n\t\t\"container_last_seen metric should exist\")\n}\n\n// TestRootContainerMetricsExist verifies the root container (/) has metrics.\nfunc TestRootContainerMetricsExist(t *testing.T) {\n\tfm := framework.New(t)\n\tdefer fm.Cleanup()\n\n\tclient := framework.NewMetricsClient(fm.Hostname())\n\tfamilies, err := client.FetchAndParse()\n\trequire.NoError(t, err)\n\n\t// The root container should appear in CPU metrics with id=\"/\"\n\tcpuMetric, ok := framework.GetMetricFamily(families, \"container_cpu_usage_seconds_total\")\n\trequire.True(t, ok)\n\n\t// Look for root container\n\tfound := false\n\tfor _, metric := range cpuMetric.GetMetric() {\n\t\tid := framework.GetLabelValue(metric, \"id\")\n\t\tif id == \"/\" {\n\t\t\tfound = true\n\t\t\t// Root container should have positive CPU usage\n\t\t\tvalue := framework.GetCounterValue(metric)\n\t\t\tassert.GreaterOrEqual(t, value, float64(0), \"Root container CPU should be >= 0\")\n\t\t\tbreak\n\t\t}\n\t}\n\tassert.True(t, found, \"Root container (/) should appear in CPU metrics\")\n}\n\n// TestGoRuntimeMetricsExist verifies Go runtime metrics are exposed.\nfunc TestGoRuntimeMetricsExist(t *testing.T) {\n\tfm := framework.New(t)\n\tdefer fm.Cleanup()\n\n\tclient := framework.NewMetricsClient(fm.Hostname())\n\tfamilies, err := client.FetchAndParse()\n\trequire.NoError(t, err)\n\n\t// Check for at least some Go runtime metrics\n\tgoMetrics := []string{\n\t\t\"go_goroutines\",\n\t\t\"go_memstats_alloc_bytes\",\n\t}\n\n\tfoundCount := 0\n\tfor _, name := range goMetrics {\n\t\tif framework.HasMetric(families, name) {\n\t\t\tfoundCount++\n\t\t}\n\t}\n\n\tassert.GreaterOrEqual(t, foundCount, 1, \"Should have at least one Go runtime metric\")\n}\n\n// TestProcessMetricsExist verifies process-level metrics are exposed.\nfunc TestProcessMetricsExist(t *testing.T) {\n\tfm := framework.New(t)\n\tdefer fm.Cleanup()\n\n\tclient := framework.NewMetricsClient(fm.Hostname())\n\tfamilies, err := client.FetchAndParse()\n\trequire.NoError(t, err)\n\n\t// These are process collector metrics for the cAdvisor process itself\n\tprocessMetrics := []string{\n\t\t\"process_cpu_seconds_total\",\n\t\t\"process_resident_memory_bytes\",\n\t}\n\n\tfoundCount := 0\n\tfor _, name := range processMetrics {\n\t\tif framework.HasMetric(families, name) {\n\t\t\tfoundCount++\n\t\t}\n\t}\n\n\tassert.GreaterOrEqual(t, foundCount, 1, \"Should have at least one process metric\")\n}\n\n// TestMetricsContainExpectedLabels verifies container metrics have the 'id' label.\nfunc TestMetricsContainExpectedLabels(t *testing.T) {\n\tfm := framework.New(t)\n\tdefer fm.Cleanup()\n\n\tclient := framework.NewMetricsClient(fm.Hostname())\n\tfamilies, err := client.FetchAndParse()\n\trequire.NoError(t, err)\n\n\t// Container metrics should have 'id' label\n\tcontainerMetrics := []string{\n\t\t\"container_cpu_usage_seconds_total\",\n\t\t\"container_memory_usage_bytes\",\n\t}\n\n\tfor _, name := range containerMetrics {\n\t\tmf, ok := families[name]\n\t\tif !ok {\n\t\t\tcontinue\n\t\t}\n\t\tif len(mf.GetMetric()) == 0 {\n\t\t\tcontinue\n\t\t}\n\n\t\t// Check first metric has 'id' label\n\t\tmetric := mf.GetMetric()[0]\n\t\tid := framework.GetLabelValue(metric, \"id\")\n\t\tassert.NotEmpty(t, id, \"Metric %s should have 'id' label\", name)\n\t}\n}\n\n// TestDiskIOMetricsExist verifies disk I/O metrics are present.\nfunc TestDiskIOMetricsExist(t *testing.T) {\n\tfm := framework.New(t)\n\tdefer fm.Cleanup()\n\n\tclient := framework.NewMetricsClient(fm.Hostname())\n\tfamilies, err := client.FetchAndParse()\n\trequire.NoError(t, err)\n\n\t// At least some disk I/O metrics should exist\n\tdiskIOMetrics := []string{\n\t\t\"container_fs_reads_bytes_total\",\n\t\t\"container_fs_writes_bytes_total\",\n\t\t\"container_fs_reads_total\",\n\t\t\"container_fs_writes_total\",\n\t}\n\n\tfoundCount := 0\n\tfor _, name := range diskIOMetrics {\n\t\tif framework.HasMetric(families, name) {\n\t\t\tfoundCount++\n\t\t}\n\t}\n\n\t// Some environments may not have all disk I/O metrics\n\t// but we should have at least one\n\tassert.GreaterOrEqual(t, foundCount, 1, \"Should have at least one disk I/O metric\")\n}\n\n// TestMetricsResponseContainsComments verifies the response contains # HELP and # TYPE.\nfunc TestMetricsResponseContainsComments(t *testing.T) {\n\tfm := framework.New(t)\n\tdefer fm.Cleanup()\n\n\tclient := framework.NewMetricsClient(fm.Hostname())\n\ttext, err := client.Fetch()\n\trequire.NoError(t, err)\n\n\tassert.True(t, strings.Contains(text, \"# HELP\"),\n\t\t\"Metrics response should contain # HELP comments\")\n\tassert.True(t, strings.Contains(text, \"# TYPE\"),\n\t\t\"Metrics response should contain # TYPE comments\")\n}\n"
  },
  {
    "path": "machine/info.go",
    "content": "// Copyright 2014 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n//go:build linux\n\npackage machine\n\nimport (\n\t\"flag\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"strings\"\n\t\"time\"\n\n\t\"golang.org/x/sys/unix\"\n\n\t\"github.com/google/cadvisor/fs\"\n\tinfo \"github.com/google/cadvisor/info/v1\"\n\t\"github.com/google/cadvisor/nvm\"\n\t\"github.com/google/cadvisor/utils/cloudinfo\"\n\t\"github.com/google/cadvisor/utils/sysfs\"\n\t\"github.com/google/cadvisor/utils/sysinfo\"\n\n\t\"k8s.io/klog/v2\"\n)\n\nconst hugepagesDirectory = \"/sys/kernel/mm/hugepages/\"\nconst memoryControllerPath = \"/sys/devices/system/edac/mc/\"\n\nvar machineIDFilePath = flag.String(\"machine_id_file\", \"/etc/machine-id,/var/lib/dbus/machine-id\", \"Comma-separated list of files to check for machine-id. Use the first one that exists.\")\nvar bootIDFilePath = flag.String(\"boot_id_file\", \"/proc/sys/kernel/random/boot_id\", \"Comma-separated list of files to check for boot-id. Use the first one that exists.\")\n\nfunc getInfoFromFiles(filePaths string) string {\n\tif len(filePaths) == 0 {\n\t\treturn \"\"\n\t}\n\tfor _, file := range strings.Split(filePaths, \",\") {\n\t\tid, err := os.ReadFile(file)\n\t\tif err == nil {\n\t\t\treturn strings.TrimSpace(string(id))\n\t\t}\n\t}\n\tklog.Warningf(\"Couldn't collect info from any of the files in %q\", filePaths)\n\treturn \"\"\n}\n\nfunc Info(sysFs sysfs.SysFs, fsInfo fs.FsInfo, inHostNamespace bool) (*info.MachineInfo, error) {\n\trootFs := \"/\"\n\tif !inHostNamespace {\n\t\trootFs = \"/rootfs\"\n\t}\n\n\tcpuinfo, err := os.ReadFile(filepath.Join(rootFs, \"/proc/cpuinfo\"))\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tclockSpeed, err := GetClockSpeed(cpuinfo)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tmemoryCapacity, err := GetMachineMemoryCapacity()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tmemoryByType, err := GetMachineMemoryByType(memoryControllerPath)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tswapCapacity, err := GetMachineSwapCapacity()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tnvmInfo, err := nvm.GetInfo()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\thugePagesInfo, err := sysinfo.GetHugePagesInfo(sysFs, hugepagesDirectory)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tfilesystems, err := fsInfo.GetGlobalFsInfo()\n\tif err != nil {\n\t\tklog.Errorf(\"Failed to get global filesystem information: %v\", err)\n\t}\n\n\tdiskMap, err := sysinfo.GetBlockDeviceInfo(sysFs)\n\tif err != nil {\n\t\tklog.Errorf(\"Failed to get disk map: %v\", err)\n\t}\n\n\tnetDevices, err := sysinfo.GetNetworkDevices(sysFs)\n\tif err != nil {\n\t\tklog.Errorf(\"Failed to get network devices: %v\", err)\n\t}\n\n\ttopology, numCores, err := GetTopology(sysFs)\n\tif err != nil {\n\t\tklog.Errorf(\"Failed to get topology information: %v\", err)\n\t}\n\n\tsystemUUID, err := sysinfo.GetSystemUUID(sysFs)\n\tif err != nil {\n\t\tklog.Errorf(\"Failed to get system UUID: %v\", err)\n\t}\n\n\trealCloudInfo := cloudinfo.NewRealCloudInfo()\n\tcloudProvider := realCloudInfo.GetCloudProvider()\n\tinstanceType := realCloudInfo.GetInstanceType()\n\tinstanceID := realCloudInfo.GetInstanceID()\n\n\tmachineInfo := &info.MachineInfo{\n\t\tTimestamp:        time.Now(),\n\t\tCPUVendorID:      GetCPUVendorID(cpuinfo),\n\t\tNumCores:         numCores,\n\t\tNumPhysicalCores: GetPhysicalCores(cpuinfo),\n\t\tNumSockets:       GetSockets(cpuinfo),\n\t\tNumBooks:         GetBooks(cpuinfo),\n\t\tNumDrawers:       GetDrawers(cpuinfo),\n\t\tCpuFrequency:     clockSpeed,\n\t\tMemoryCapacity:   memoryCapacity,\n\t\tMemoryByType:     memoryByType,\n\t\tSwapCapacity:     swapCapacity,\n\t\tNVMInfo:          nvmInfo,\n\t\tHugePages:        hugePagesInfo,\n\t\tDiskMap:          diskMap,\n\t\tNetworkDevices:   netDevices,\n\t\tTopology:         topology,\n\t\tMachineID:        getInfoFromFiles(filepath.Join(rootFs, *machineIDFilePath)),\n\t\tSystemUUID:       systemUUID,\n\t\tBootID:           getInfoFromFiles(filepath.Join(rootFs, *bootIDFilePath)),\n\t\tCloudProvider:    cloudProvider,\n\t\tInstanceType:     instanceType,\n\t\tInstanceID:       instanceID,\n\t}\n\n\tfor i := range filesystems {\n\t\tfs := filesystems[i]\n\t\tinodes := uint64(0)\n\t\tif fs.Inodes != nil {\n\t\t\tinodes = *fs.Inodes\n\t\t}\n\t\tmachineInfo.Filesystems = append(machineInfo.Filesystems, info.FsInfo{Device: fs.Device, DeviceMajor: uint64(fs.Major), DeviceMinor: uint64(fs.Minor), Type: fs.Type.String(), Capacity: fs.Capacity, Inodes: inodes, HasInodes: fs.Inodes != nil})\n\t}\n\n\treturn machineInfo, nil\n}\n\nfunc ContainerOsVersion() string {\n\tos, err := getOperatingSystem()\n\tif err != nil {\n\t\tos = \"Unknown\"\n\t}\n\treturn os\n}\n\nfunc KernelVersion() string {\n\tuname := &unix.Utsname{}\n\tif err := unix.Uname(uname); err != nil {\n\t\treturn \"Unknown\"\n\t}\n\treturn unix.ByteSliceToString(uname.Release[:])\n}\n"
  },
  {
    "path": "machine/machine.go",
    "content": "// Copyright 2015 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n//go:build linux\n\n// The machine package contains functions that extract machine-level specs.\npackage machine\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\t\"path\"\n\t\"regexp\"\n\t\"runtime\"\n\n\t\"strconv\"\n\t\"strings\"\n\n\tinfo \"github.com/google/cadvisor/info/v1\"\n\t\"github.com/google/cadvisor/utils\"\n\t\"github.com/google/cadvisor/utils/sysfs\"\n\t\"github.com/google/cadvisor/utils/sysinfo\"\n\n\t\"k8s.io/klog/v2\"\n\n\t\"golang.org/x/sys/unix\"\n)\n\nvar (\n\tcoreRegExp   = regexp.MustCompile(`(?m)^core id\\s*:\\s*([0-9]+)$`)\n\tnodeRegExp   = regexp.MustCompile(`(?m)^physical id\\s*:\\s*([0-9]+)$`)\n\tbookRegExp   = regexp.MustCompile(`(?m)^book id\\s*:\\s*([0-9]+)$`)\n\tdrawerRegExp = regexp.MustCompile(`(?m)^drawer id\\s*:\\s*([0-9]+)$`)\n\t// Power systems have a different format so cater for both\n\tcpuClockSpeedMHz     = regexp.MustCompile(`(?:cpu MHz|CPU MHz|clock)\\s*:\\s*([0-9]+\\.[0-9]+)(?:MHz)?`)\n\tmemoryCapacityRegexp = regexp.MustCompile(`MemTotal:\\s*([0-9]+) kB`)\n\tswapCapacityRegexp   = regexp.MustCompile(`SwapTotal:\\s*([0-9]+) kB`)\n\tvendorIDRegexp       = regexp.MustCompile(`vendor_id\\s*:\\s*(\\w+)`)\n\n\tcpuAttributesPath  = \"/sys/devices/system/cpu/\"\n\tisMemoryController = regexp.MustCompile(\"mc[0-9]+\")\n\tisDimm             = regexp.MustCompile(\"dimm[0-9]+\")\n\tmachineArch        = getMachineArch()\n\tmaxFreqFile        = \"/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq\"\n)\n\nconst memTypeFileName = \"dimm_mem_type\"\nconst sizeFileName = \"size\"\n\n// GetCPUVendorID returns \"vendor_id\" reading /proc/cpuinfo file.\nfunc GetCPUVendorID(procInfo []byte) string {\n\tvendorID := \"\"\n\n\tmatches := vendorIDRegexp.FindSubmatch(procInfo)\n\tif len(matches) != 2 {\n\t\tklog.V(4).Info(\"Cannot read vendor id correctly, set empty.\")\n\t\treturn vendorID\n\t}\n\n\tvendorID = string(matches[1])\n\n\treturn vendorID\n}\n\n// GetPhysicalCores returns number of CPU cores reading /proc/cpuinfo file or if needed information from sysfs cpu path\nfunc GetPhysicalCores(procInfo []byte) int {\n\tnumCores := getUniqueMatchesCount(string(procInfo), coreRegExp)\n\tif numCores == 0 {\n\t\t// read number of cores from /sys/bus/cpu/devices/cpu*/topology/core_id to deal with processors\n\t\t// for which 'core id' is not available in /proc/cpuinfo\n\t\tnumCores = sysfs.GetUniqueCPUPropertyCount(cpuAttributesPath, sysfs.CPUCoreID)\n\t}\n\tif numCores == 0 {\n\t\tklog.Errorf(\"Cannot read number of physical cores correctly, number of cores set to %d\", numCores)\n\t}\n\treturn numCores\n}\n\n// GetSockets returns number of CPU sockets reading /proc/cpuinfo file or if needed information from sysfs cpu path\nfunc GetSockets(procInfo []byte) int {\n\tnumSocket := getUniqueMatchesCount(string(procInfo), nodeRegExp)\n\tif numSocket == 0 {\n\t\t// read number of sockets from /sys/bus/cpu/devices/cpu*/topology/physical_package_id to deal with processors\n\t\t// for which 'physical id' is not available in /proc/cpuinfo\n\t\tnumSocket = sysfs.GetUniqueCPUPropertyCount(cpuAttributesPath, sysfs.CPUPhysicalPackageID)\n\t}\n\tif numSocket == 0 {\n\t\tklog.Errorf(\"Cannot read number of sockets correctly, number of sockets set to %d\", numSocket)\n\t}\n\treturn numSocket\n}\n\n// GetBooks returns number of CPU books reading from sysfs cpu path\nfunc GetBooks(procInfo []byte) int {\n\tif runtime.GOARCH != \"s390x\" {\n\t\treturn 0\n\t}\n\tnumBook := getUniqueMatchesCount(string(procInfo), bookRegExp)\n\tif numBook == 0 {\n\t\t// read number of books from /sys/bus/cpu/devices/cpu*/topology/book_id to deal with processors\n\t\t// for which 'book id' is not available in /proc/cpuinfo\n\t\tnumBook = sysfs.GetUniqueCPUPropertyCount(cpuAttributesPath, sysfs.CPUBookID)\n\t}\n\tif numBook == 0 {\n\t\tklog.Errorf(\"Cannot read number of books correctly, number of books set to %d\", numBook)\n\t}\n\treturn numBook\n}\n\n// GetDrawer returns number of CPU drawerss reading from sysfs cpu path\nfunc GetDrawers(procInfo []byte) int {\n\tif runtime.GOARCH != \"s390x\" {\n\t\treturn 0\n\t}\n\tnumDrawer := getUniqueMatchesCount(string(procInfo), drawerRegExp)\n\tif numDrawer == 0 {\n\t\t// read number of books from /sys/bus/cpu/devices/cpu*/topology/book_id to deal with processors\n\t\t// read number of drawers from /sys/bus/cpu/devices/cpu*/topology/drawer_id to deal with processors\n\t\t// for which 'drawer id' is not available in /proc/cpuinfo\n\t\tnumDrawer = sysfs.GetUniqueCPUPropertyCount(cpuAttributesPath, sysfs.CPUDrawerID)\n\t}\n\tif numDrawer == 0 {\n\t\tklog.Errorf(\"Cannot read number of drawers correctly, number of drawers set to %d\", numDrawer)\n\t}\n\treturn numDrawer\n}\n\n// GetClockSpeed returns the CPU clock speed, given a []byte formatted as the /proc/cpuinfo file.\nfunc GetClockSpeed(procInfo []byte) (uint64, error) {\n\t// First look through sys to find a max supported cpu frequency.\n\tif utils.FileExists(maxFreqFile) {\n\t\tval, err := os.ReadFile(maxFreqFile)\n\t\tif err != nil {\n\t\t\treturn 0, err\n\t\t}\n\t\tvar maxFreq uint64\n\t\tn, err := fmt.Sscanf(string(val), \"%d\", &maxFreq)\n\t\tif err != nil || n != 1 {\n\t\t\treturn 0, fmt.Errorf(\"could not parse frequency %q\", val)\n\t\t}\n\t\treturn maxFreq, nil\n\t}\n\t// s390/s390x, mips64, riscv64, aarch64 and arm32 changes\n\tif isMips64() || isSystemZ() || isAArch64() || isArm32() || isRiscv64() {\n\t\treturn 0, nil\n\t}\n\n\t// Fall back to /proc/cpuinfo\n\tmatches := cpuClockSpeedMHz.FindSubmatch(procInfo)\n\tif len(matches) != 2 {\n\t\treturn 0, fmt.Errorf(\"could not detect clock speed from output: %q\", string(procInfo))\n\t}\n\n\tspeed, err := strconv.ParseFloat(string(matches[1]), 64)\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\t// Convert to kHz\n\treturn uint64(speed * 1000), nil\n}\n\n// GetMachineMemoryCapacity returns the machine's total memory from /proc/meminfo.\n// Returns the total memory capacity as an uint64 (number of bytes).\nfunc GetMachineMemoryCapacity() (uint64, error) {\n\tout, err := os.ReadFile(\"/proc/meminfo\")\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\n\tmemoryCapacity, err := parseCapacity(out, memoryCapacityRegexp)\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\treturn memoryCapacity, err\n}\n\n// GetMachineMemoryByType returns information about memory capacity and number of DIMMs.\n// Information is retrieved from sysfs edac per-DIMM API (/sys/devices/system/edac/mc/)\n// introduced in kernel 3.6. Documentation can be found at\n// https://www.kernel.org/doc/Documentation/admin-guide/ras.rst.\n// Full list of memory types can be found in edac_mc.c\n// (https://github.com/torvalds/linux/blob/v5.5/drivers/edac/edac_mc.c#L198)\nfunc GetMachineMemoryByType(edacPath string) (map[string]*info.MemoryInfo, error) {\n\tmemory := map[string]*info.MemoryInfo{}\n\tnames, err := os.ReadDir(edacPath)\n\t// On some architectures (such as ARM) memory controller device may not exist.\n\t// If this is the case then we ignore error and return empty slice.\n\t_, ok := err.(*os.PathError)\n\tif err != nil && ok {\n\t\treturn memory, nil\n\t} else if err != nil {\n\t\treturn memory, err\n\t}\n\tfor _, controllerDir := range names {\n\t\tcontroller := controllerDir.Name()\n\t\tif !isMemoryController.MatchString(controller) {\n\t\t\tcontinue\n\t\t}\n\t\tdimms, err := os.ReadDir(path.Join(edacPath, controllerDir.Name()))\n\t\tif err != nil {\n\t\t\treturn map[string]*info.MemoryInfo{}, err\n\t\t}\n\t\tfor _, dimmDir := range dimms {\n\t\t\tdimm := dimmDir.Name()\n\t\t\tif !isDimm.MatchString(dimm) {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tmemType, err := os.ReadFile(path.Join(edacPath, controller, dimm, memTypeFileName))\n\t\t\tif err != nil {\n\t\t\t\treturn map[string]*info.MemoryInfo{}, err\n\t\t\t}\n\t\t\treadableMemType := strings.TrimSpace(string(memType))\n\t\t\tif _, exists := memory[readableMemType]; !exists {\n\t\t\t\tmemory[readableMemType] = &info.MemoryInfo{}\n\t\t\t}\n\t\t\tsize, err := os.ReadFile(path.Join(edacPath, controller, dimm, sizeFileName))\n\t\t\tif err != nil {\n\t\t\t\treturn map[string]*info.MemoryInfo{}, err\n\t\t\t}\n\t\t\tcapacity, err := strconv.Atoi(strings.TrimSpace(string(size)))\n\t\t\tif err != nil {\n\t\t\t\treturn map[string]*info.MemoryInfo{}, err\n\t\t\t}\n\t\t\tmemory[readableMemType].Capacity += uint64(mbToBytes(capacity))\n\t\t\tmemory[readableMemType].DimmCount++\n\t\t}\n\t}\n\n\treturn memory, nil\n}\n\nfunc mbToBytes(megabytes int) int {\n\treturn megabytes * 1024 * 1024\n}\n\n// GetMachineSwapCapacity returns the machine's total swap from /proc/meminfo.\n// Returns the total swap capacity as an uint64 (number of bytes).\nfunc GetMachineSwapCapacity() (uint64, error) {\n\tout, err := os.ReadFile(\"/proc/meminfo\")\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\n\tswapCapacity, err := parseCapacity(out, swapCapacityRegexp)\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\treturn swapCapacity, err\n}\n\n// GetTopology returns CPU topology reading information from sysfs\nfunc GetTopology(sysFs sysfs.SysFs) ([]info.Node, int, error) {\n\treturn sysinfo.GetNodesInfo(sysFs)\n}\n\n// parseCapacity matches a Regexp in a []byte, returning the resulting value in bytes.\n// Assumes that the value matched by the Regexp is in KB.\nfunc parseCapacity(b []byte, r *regexp.Regexp) (uint64, error) {\n\tmatches := r.FindSubmatch(b)\n\tif len(matches) != 2 {\n\t\treturn 0, fmt.Errorf(\"failed to match regexp in output: %q\", string(b))\n\t}\n\tm, err := strconv.ParseUint(string(matches[1]), 10, 64)\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\n\t// Convert to bytes.\n\treturn m * 1024, err\n}\n\n// getUniqueMatchesCount returns number of unique matches in given argument using provided regular expression\nfunc getUniqueMatchesCount(s string, r *regexp.Regexp) int {\n\tmatches := r.FindAllString(s, -1)\n\tuniques := make(map[string]bool)\n\tfor _, match := range matches {\n\t\tuniques[match] = true\n\t}\n\treturn len(uniques)\n}\n\nfunc getMachineArch() string {\n\tuname := unix.Utsname{}\n\terr := unix.Uname(&uname)\n\tif err != nil {\n\t\tklog.Errorf(\"Cannot get machine architecture, err: %v\", err)\n\t\treturn \"\"\n\t}\n\treturn unix.ByteSliceToString(uname.Machine[:])\n}\n\n// arm32 changes\nfunc isArm32() bool {\n\treturn strings.Contains(machineArch, \"arm\")\n}\n\n// aarch64 changes\nfunc isAArch64() bool {\n\treturn strings.Contains(machineArch, \"aarch64\")\n}\n\n// s390/s390x changes\nfunc isSystemZ() bool {\n\treturn strings.Contains(machineArch, \"390\")\n}\n\n// riscv64 changes\nfunc isRiscv64() bool {\n\treturn strings.Contains(machineArch, \"riscv64\")\n}\n\n// mips64 changes\nfunc isMips64() bool {\n\treturn strings.Contains(machineArch, \"mips64\")\n}\n"
  },
  {
    "path": "machine/operatingsystem_unix.go",
    "content": "// Copyright 2020 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n//go:build freebsd || darwin || linux\n\npackage machine\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\t\"regexp\"\n\t\"runtime\"\n\t\"strings\"\n\n\t\"golang.org/x/sys/unix\"\n)\n\nvar rex = regexp.MustCompile(\"(PRETTY_NAME)=(.*)\")\n\n// getOperatingSystem gets the name of the current operating system.\nfunc getOperatingSystem() (string, error) {\n\tif runtime.GOOS == \"darwin\" || runtime.GOOS == \"freebsd\" {\n\t\tuname := unix.Utsname{}\n\t\terr := unix.Uname(&uname)\n\t\tif err != nil {\n\t\t\treturn \"\", err\n\t\t}\n\t\treturn unix.ByteSliceToString(uname.Sysname[:]), nil\n\t}\n\tbytes, err := os.ReadFile(\"/etc/os-release\")\n\tif err != nil && os.IsNotExist(err) {\n\t\t// /usr/lib/os-release in stateless systems like Clear Linux\n\t\tbytes, err = os.ReadFile(\"/usr/lib/os-release\")\n\t}\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"error opening file : %v\", err)\n\t}\n\tline := rex.FindAllStringSubmatch(string(bytes), -1)\n\tif len(line) > 0 {\n\t\treturn strings.Trim(line[0][2], \"\\\"\"), nil\n\t}\n\treturn \"Linux\", nil\n}\n"
  },
  {
    "path": "machine/operatingsystem_windows.go",
    "content": "// Copyright 2020 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage machine\n\nimport (\n\t\"fmt\"\n\n\t\"golang.org/x/sys/windows/registry\"\n)\n\nfunc getOperatingSystem() (string, error) {\n\tsystem := \"Windows\"\n\tk, err := registry.OpenKey(registry.LOCAL_MACHINE, `SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion`, registry.QUERY_VALUE)\n\tif err != nil {\n\t\treturn system, err\n\t}\n\tdefer k.Close()\n\n\tproductName, _, err := k.GetStringValue(\"ProductName\")\n\tif err != nil {\n\t\treturn system, nil\n\t}\n\n\treleaseId, _, err := k.GetStringValue(\"ReleaseId\")\n\tif err != nil {\n\t\treturn system, err\n\t}\n\n\tcurrentBuildNumber, _, err := k.GetStringValue(\"CurrentBuildNumber\")\n\tif err != nil {\n\t\treturn system, err\n\t}\n\trevision, _, err := k.GetIntegerValue(\"UBR\")\n\tif err != nil {\n\t\treturn system, err\n\t}\n\n\tsystem = fmt.Sprintf(\"%s Version %s (OS Build %s.%d)\",\n\t\tproductName, releaseId, currentBuildNumber, revision)\n\n\treturn system, nil\n}\n"
  },
  {
    "path": "machine/testdata/cpu9999/online",
    "content": "1\n"
  },
  {
    "path": "machine/testdata/cpu9999/topology/core_id",
    "content": "8888\n"
  },
  {
    "path": "machine/testdata/cpu9999/topology/physical_package_id",
    "content": "0\n"
  },
  {
    "path": "machine/testdata/cpuinfo",
    "content": "processor\t: 0\ncpu family\t: 6\nstepping\t: 2\nmicrocode\t: 0x10\ncpu MHz\t\t: 1596.000\ncache size\t: 12288 KB\nphysical id\t: 0\nsiblings\t: 6\ncore id\t\t: 0\ncpu cores\t: 6\napicid\t\t: 0\ninitial apicid\t: 0\nfpu\t\t: yes\nfpu_exception\t: yes\ncpuid level\t: 11\nwp\t\t: yes\nbogomips\t: 5333.60\nclflush size\t: 64\ncache_alignment\t: 64\naddress sizes\t: 40 bits physical, 48 bits virtual\n\nprocessor\t: 1\ncpu family\t: 6\nstepping\t: 2\nmicrocode\t: 0x10\ncpu MHz\t\t: 1596.000\ncache size\t: 12288 KB\nphysical id\t: 0\nsiblings\t: 6\ncore id\t\t: 1\ncpu cores\t: 6\napicid\t\t: 2\ninitial apicid\t: 2\nfpu\t\t: yes\nfpu_exception\t: yes\ncpuid level\t: 11\nwp\t\t: yes\nbogomips\t: 5333.60\nclflush size\t: 64\ncache_alignment\t: 64\naddress sizes\t: 40 bits physical, 48 bits virtual\n\nprocessor\t: 2\ncpu family\t: 6\nstepping\t: 2\nmicrocode\t: 0x10\ncpu MHz\t\t: 1596.000\ncache size\t: 12288 KB\nphysical id\t: 0\nsiblings\t: 6\ncore id\t\t: 2\ncpu cores\t: 6\napicid\t\t: 4\ninitial apicid\t: 4\nfpu\t\t: yes\nfpu_exception\t: yes\ncpuid level\t: 11\nwp\t\t: yes\nbogomips\t: 5333.60\nclflush size\t: 64\ncache_alignment\t: 64\naddress sizes\t: 40 bits physical, 48 bits virtual\n\nprocessor\t: 3\ncpu family\t: 6\nstepping\t: 2\nmicrocode\t: 0x10\ncpu MHz\t\t: 1596.000\ncache size\t: 12288 KB\nphysical id\t: 1\nsiblings\t: 6\ncore id\t\t: 3\ncpu cores\t: 6\napicid\t\t: 16\ninitial apicid\t: 16\nfpu\t\t: yes\nfpu_exception\t: yes\ncpuid level\t: 11\nwp\t\t: yes\nbogomips\t: 5333.60\nclflush size\t: 64\ncache_alignment\t: 64\naddress sizes\t: 40 bits physical, 48 bits virtual\n\nprocessor\t: 4\ncpu family\t: 6\nstepping\t: 2\nmicrocode\t: 0x10\ncpu MHz\t\t: 1596.000\ncache size\t: 12288 KB\nphysical id\t: 1\nsiblings\t: 6\ncore id\t\t: 4\ncpu cores\t: 6\napicid\t\t: 18\ninitial apicid\t: 18\nfpu\t\t: yes\nfpu_exception\t: yes\ncpuid level\t: 11\nwp\t\t: yes\nbogomips\t: 5333.60\nclflush size\t: 64\ncache_alignment\t: 64\naddress sizes\t: 40 bits physical, 48 bits virtual\n\nprocessor\t: 5\ncpu family\t: 6\nstepping\t: 2\nmicrocode\t: 0x10\ncpu MHz\t\t: 1596.000\ncache size\t: 12288 KB\nphysical id\t: 1\nsiblings\t: 6\ncore id\t\t: 5\ncpu cores\t: 6\napicid\t\t: 20\ninitial apicid\t: 20\nfpu\t\t: yes\nfpu_exception\t: yes\ncpuid level\t: 11\nwp\t\t: yes\nbogomips\t: 5333.60\nclflush size\t: 64\ncache_alignment\t: 64\naddress sizes\t: 40 bits physical, 48 bits virtual\n\nprocessor\t: 6\ncpu family\t: 6\nstepping\t: 2\nmicrocode\t: 0x10\ncpu MHz\t\t: 2661.000\ncache size\t: 12288 KB\nphysical id\t: 0\nsiblings\t: 6\ncore id\t\t: 0\ncpu cores\t: 6\napicid\t\t: 1\ninitial apicid\t: 1\nfpu\t\t: yes\nfpu_exception\t: yes\ncpuid level\t: 11\nwp\t\t: yes\nbogomips\t: 5333.60\nclflush size\t: 64\ncache_alignment\t: 64\naddress sizes\t: 40 bits physical, 48 bits virtual\n\nprocessor\t: 7\ncpu family\t: 6\nstepping\t: 2\nmicrocode\t: 0x10\ncpu MHz\t\t: 2661.000\ncache size\t: 12288 KB\nphysical id\t: 0\nsiblings\t: 6\ncore id\t\t: 1\ncpu cores\t: 6\napicid\t\t: 3\ninitial apicid\t: 3\nfpu\t\t: yes\nfpu_exception\t: yes\ncpuid level\t: 11\nwp\t\t: yes\nbogomips\t: 5333.60\nclflush size\t: 64\ncache_alignment\t: 64\naddress sizes\t: 40 bits physical, 48 bits virtual\n\nprocessor\t: 8\ncpu family\t: 6\nstepping\t: 2\nmicrocode\t: 0x10\ncpu MHz\t\t: 1596.000\ncache size\t: 12288 KB\nphysical id\t: 0\nsiblings\t: 6\ncore id\t\t: 2\ncpu cores\t: 6\napicid\t\t: 5\ninitial apicid\t: 5\nfpu\t\t: yes\nfpu_exception\t: yes\ncpuid level\t: 11\nwp\t\t: yes\nbogomips\t: 5333.60\nclflush size\t: 64\ncache_alignment\t: 64\naddress sizes\t: 40 bits physical, 48 bits virtual\n\nprocessor\t: 9\ncpu family\t: 6\nstepping\t: 2\nmicrocode\t: 0x10\ncpu MHz\t\t: 2661.000\ncache size\t: 12288 KB\nphysical id\t: 1\nsiblings\t: 6\ncore id\t\t: 3\ncpu cores\t: 6\napicid\t\t: 17\ninitial apicid\t: 17\nfpu\t\t: yes\nfpu_exception\t: yes\ncpuid level\t: 11\nwp\t\t: yes\nbogomips\t: 5333.60\nclflush size\t: 64\ncache_alignment\t: 64\naddress sizes\t: 40 bits physical, 48 bits virtual\n\nprocessor\t: 10\ncpu family\t: 6\nstepping\t: 2\nmicrocode\t: 0x10\ncpu MHz\t\t: 1596.000\ncache size\t: 12288 KB\nphysical id\t: 1\nsiblings\t: 6\ncore id\t\t: 4\ncpu cores\t: 6\napicid\t\t: 19\ninitial apicid\t: 19\nfpu\t\t: yes\nfpu_exception\t: yes\ncpuid level\t: 11\nwp\t\t: yes\nbogomips\t: 5333.60\nclflush size\t: 64\ncache_alignment\t: 64\naddress sizes\t: 40 bits physical, 48 bits virtual\nprocessor\t: 11\ncpu family\t: 6\nstepping\t: 2\nmicrocode\t: 0x10\ncpu MHz\t\t: 2661.000\ncache size\t: 12288 KB\nphysical id\t: 1\nsiblings\t: 6\ncore id\t\t: 5\ncpu cores\t: 6\napicid\t\t: 21\ninitial apicid\t: 21\nfpu\t\t: yes\nfpu_exception\t: yes\ncpuid level\t: 11\nwp\t\t: yes\nbogomips\t: 5333.60\nclflush size\t: 64\ncache_alignment\t: 64\naddress sizes\t: 40 bits physical, 48 bits virtual\n\n"
  },
  {
    "path": "machine/testdata/cpuinfo_arm",
    "content": "processor    : 0\nmodel name    : ARMv7 Processor rev 4 (v7l)\nBogoMIPS    : 76.80\nFeatures    : half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt vfpd32 lpae evtstrm crc32\nCPU implementer    : 0x41\nCPU architecture: 7\nCPU variant    : 0x0\nCPU part    : 0xd03\nCPU revision    : 4\n\nprocessor    : 1\nmodel name    : ARMv7 Processor rev 4 (v7l)\nBogoMIPS    : 76.80\nFeatures    : half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt vfpd32 lpae evtstrm crc32\nCPU implementer    : 0x41\nCPU architecture: 7\nCPU variant    : 0x0\nCPU part    : 0xd03\nCPU revision    : 4\n\nprocessor    : 2\nmodel name    : ARMv7 Processor rev 4 (v7l)\nBogoMIPS    : 76.80\nFeatures    : half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt vfpd32 lpae evtstrm crc32\nCPU implementer    : 0x41\nCPU architecture: 7\nCPU variant    : 0x0\nCPU part    : 0xd03\nCPU revision    : 4\n\nprocessor    : 3\nmodel name    : ARMv7 Processor rev 4 (v7l)\nBogoMIPS    : 76.80\nFeatures    : half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt vfpd32 lpae evtstrm crc32\nCPU implementer    : 0x41\nCPU architecture: 7\nCPU variant    : 0x0\nCPU part    : 0xd03\nCPU revision    : 4\n\nHardware    : BCM2835\nRevision    : 0000\nSerial        : 00000000d0a71bfd\n"
  },
  {
    "path": "machine/testdata/cpuinfo_lower_case",
    "content": "processor       : 0\ncpu model       : ICT Loongson-3 V0.13  FPU V0.1\nmodel name      : ICT Loongson-3A R3 (Loongson-3B3000) @ 1450MHz\nBogoMIPS        : 2887.52\ncpu MHz         : 1450.00\nwait instruction    : yes\nmicrosecond timers  : yes\ntlb_entries     : 1088\nextra interrupt vector  : no\nhardware watchpoint : yes, count: 0, address/irw mask: []\nisa         : mips1 mips2 mips3 mips4 mips5 mips32r1 mips32r2 mips64r1 mips64r2\nASEs implemented    : vz\nshadow register sets    : 1\nkscratch registers  : 6\npackage         : 0\ncore            : 0\nVCED exceptions     : not available\nVCEI exceptions     : not available\n\nprocessor       : 1\ncpu model       : ICT Loongson-3 V0.13  FPU V0.1\nmodel name      : ICT Loongson-3A R3 (Loongson-3B3000) @ 1450MHz\nBogoMIPS        : 2902.61\ncpu MHz         : 1450.00\nwait instruction    : yes\nmicrosecond timers  : yes\ntlb_entries     : 1088\nextra interrupt vector  : no\nhardware watchpoint : yes, count: 0, address/irw mask: []\nisa         : mips1 mips2 mips3 mips4 mips5 mips32r1 mips32r2 mips64r1 mips64r2\nASEs implemented    : vz\nshadow register sets    : 1\nkscratch registers  : 6\npackage         : 0\ncore            : 1\nVCED exceptions     : not available\nVCEI exceptions     : not available\n\nprocessor       : 2\ncpu model       : ICT Loongson-3 V0.13  FPU V0.1\nmodel name      : ICT Loongson-3A R3 (Loongson-3B3000) @ 1450MHz\nBogoMIPS        : 2902.61\ncpu MHz         : 1450.00\nwait instruction    : yes\nmicrosecond timers  : yes\ntlb_entries     : 1088\nextra interrupt vector  : no\nhardware watchpoint : yes, count: 0, address/irw mask: []\nisa         : mips1 mips2 mips3 mips4 mips5 mips32r1 mips32r2 mips64r1 mips64r2\nASEs implemented    : vz\nshadow register sets    : 1\nkscratch registers  : 6\npackage         : 0\ncore            : 2\nVCED exceptions     : not available\nVCEI exceptions     : not available\n\nprocessor       : 3\ncpu model       : ICT Loongson-3 V0.13  FPU V0.1\nmodel name      : ICT Loongson-3A R3 (Loongson-3B3000) @ 1450MHz\nBogoMIPS        : 2902.61\ncpu MHz         : 1450.00\nwait instruction    : yes\nmicrosecond timers  : yes\ntlb_entries     : 1088\nextra interrupt vector  : no\nhardware watchpoint : yes, count: 0, address/irw mask: []\nisa         : mips1 mips2 mips3 mips4 mips5 mips32r1 mips32r2 mips64r1 mips64r2\nASEs implemented    : vz\nshadow register sets    : 1\nkscratch registers  : 6\npackage         : 0\ncore            : 3\nVCED exceptions     : not available\nVCEI exceptions     : not available\n\nprocessor       : 4\ncpu model       : ICT Loongson-3 V0.13  FPU V0.1\nmodel name      : ICT Loongson-3A R3 (Loongson-3B3000) @ 1450MHz\nBogoMIPS        : 2887.52\ncpu MHz         : 1450.00\nwait instruction    : yes\nmicrosecond timers  : yes\ntlb_entries     : 1088\nextra interrupt vector  : no\nhardware watchpoint : yes, count: 0, address/irw mask: []\nisa         : mips1 mips2 mips3 mips4 mips5 mips32r1 mips32r2 mips64r1 mips64r2\nASEs implemented    : vz\nshadow register sets    : 1\nkscratch registers  : 6\npackage         : 1\ncore            : 0\nVCED exceptions     : not available\nVCEI exceptions     : not available\n\nprocessor       : 5\ncpu model       : ICT Loongson-3 V0.13  FPU V0.1\nmodel name      : ICT Loongson-3A R3 (Loongson-3B3000) @ 1450MHz\nBogoMIPS        : 2887.52\ncpu MHz         : 1450.00\nwait instruction    : yes\nmicrosecond timers  : yes\ntlb_entries     : 1088\nextra interrupt vector  : no\nhardware watchpoint : yes, count: 0, address/irw mask: []\nisa         : mips1 mips2 mips3 mips4 mips5 mips32r1 mips32r2 mips64r1 mips64r2\nASEs implemented    : vz\nshadow register sets    : 1\nkscratch registers  : 6\npackage         : 1\ncore            : 1\nVCED exceptions     : not available\nVCEI exceptions     : not available\n\nprocessor       : 6\ncpu model       : ICT Loongson-3 V0.13  FPU V0.1\nmodel name      : ICT Loongson-3A R3 (Loongson-3B3000) @ 1450MHz\nBogoMIPS        : 2887.52\ncpu MHz         : 1450.00\nwait instruction    : yes\nmicrosecond timers  : yes\ntlb_entries     : 1088\nextra interrupt vector  : no\nhardware watchpoint : yes, count: 0, address/irw mask: []\nisa         : mips1 mips2 mips3 mips4 mips5 mips32r1 mips32r2 mips64r1 mips64r2\nASEs implemented    : vz\nshadow register sets    : 1\nkscratch registers  : 6\npackage         : 1\ncore            : 2\nVCED exceptions     : not available\nVCEI exceptions     : not available\n\nprocessor       : 7\ncpu model       : ICT Loongson-3 V0.13  FPU V0.1\nmodel name      : ICT Loongson-3A R3 (Loongson-3B3000) @ 1450MHz\nBogoMIPS        : 2887.52\ncpu MHz         : 1450.00\nwait instruction    : yes\nmicrosecond timers  : yes\ntlb_entries     : 1088\nextra interrupt vector  : no\nhardware watchpoint : yes, count: 0, address/irw mask: []\nisa         : mips1 mips2 mips3 mips4 mips5 mips32r1 mips32r2 mips64r1 mips64r2\nASEs implemented    : vz\nshadow register sets    : 1\nkscratch registers  : 6\npackage         : 1\ncore            : 3\nVCED exceptions     : not available\nVCEI exceptions     : not available\n\n"
  },
  {
    "path": "machine/testdata/cpuinfo_onesocket_many_NUMAs",
    "content": "processor : 0\nvendor_id : GenuineIntel\ncpu family : 6\nmodel : 85\nmodel name : Intel(R) Xeon(R) Gold 5218R CPU @ 2.10GHz\nstepping : 7\nmicrocode : 0x1\ncpu MHz : 2095.082\ncache size : 16384 KB\nphysical id : 0\nsiblings : 2\ncore id : 0\ncpu cores : 1\napicid : 0\ninitial apicid : 0\nfpu : yes\nfpu_exception : yes\ncpuid level : 13\nwp : yes\nflags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ss ht syscall nx pdpe1gb rdtscp lm constant_tsc arch_perfmon rep_good nopl xtopology cpuid tsc_known_freq pni pclmulqdq vmx ssse3 fma cx16 pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand hypervisor lahf_lm abm 3dnowprefetch cpuid_fault invpcid_single ssbd ibrs ibpb ibrs_enhanced tpr_shadow vnmi flexpriority ept vpid fsgsbase tsc_adjust bmi1 avx2 smep bmi2 erms invpcid mpx avx512f avx512dq rdseed adx smap clflushopt clwb avx512cd avx512bw avx512vl xsaveopt xsavec xgetbv1 xsaves arat pku ospke avx512_vnni md_clear arch_capabilities\nbugs : spectre_v1 spectre_v2 spec_store_bypass swapgs\nbogomips : 4190.16\nclflush size : 64\ncache_alignment : 64\naddress sizes : 40 bits physical, 48 bits virtual\npower management:\n\nprocessor : 1\nvendor_id : GenuineIntel\ncpu family : 6\nmodel : 85\nmodel name : Intel(R) Xeon(R) Gold 5218R CPU @ 2.10GHz\nstepping : 7\nmicrocode : 0x1\ncpu MHz : 2095.082\ncache size : 16384 KB\nphysical id : 0\nsiblings : 2\ncore id : 0\ncpu cores : 1\napicid : 1\ninitial apicid : 1\nfpu : yes\nfpu_exception : yes\ncpuid level : 13\nwp : yes\nflags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ss ht syscall nx pdpe1gb rdtscp lm constant_tsc arch_perfmon rep_good nopl xtopology cpuid tsc_known_freq pni pclmulqdq vmx ssse3 fma cx16 pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand hypervisor lahf_lm abm 3dnowprefetch cpuid_fault invpcid_single ssbd ibrs ibpb ibrs_enhanced tpr_shadow vnmi flexpriority ept vpid fsgsbase tsc_adjust bmi1 avx2 smep bmi2 erms invpcid mpx avx512f avx512dq rdseed adx smap clflushopt clwb avx512cd avx512bw avx512vl xsaveopt xsavec xgetbv1 xsaves arat pku ospke avx512_vnni md_clear arch_capabilities\nbugs : spectre_v1 spectre_v2 spec_store_bypass swapgs\nbogomips : 4190.16\nclflush size : 64\ncache_alignment : 64\naddress sizes : 40 bits physical, 48 bits virtual\npower management:\n\nprocessor : 2\nvendor_id : GenuineIntel\ncpu family : 6\nmodel : 85\nmodel name : Intel(R) Xeon(R) Gold 5218R CPU @ 2.10GHz\nstepping : 7\nmicrocode : 0x1\ncpu MHz : 2095.082\ncache size : 16384 KB\nphysical id : 1\nsiblings : 2\ncore id : 0\ncpu cores : 1\napicid : 2\ninitial apicid : 2\nfpu : yes\nfpu_exception : yes\ncpuid level : 13\nwp : yes\nflags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ss ht syscall nx pdpe1gb rdtscp lm constant_tsc arch_perfmon rep_good nopl xtopology cpuid tsc_known_freq pni pclmulqdq vmx ssse3 fma cx16 pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand hypervisor lahf_lm abm 3dnowprefetch cpuid_fault invpcid_single ssbd ibrs ibpb ibrs_enhanced tpr_shadow vnmi flexpriority ept vpid fsgsbase tsc_adjust bmi1 avx2 smep bmi2 erms invpcid mpx avx512f avx512dq rdseed adx smap clflushopt clwb avx512cd avx512bw avx512vl xsaveopt xsavec xgetbv1 xsaves arat pku ospke avx512_vnni md_clear arch_capabilities\nbugs : spectre_v1 spectre_v2 spec_store_bypass swapgs\nbogomips : 4190.16\nclflush size : 64\ncache_alignment : 64\naddress sizes : 40 bits physical, 48 bits virtual\npower management:\n\nprocessor : 3\nvendor_id : GenuineIntel\ncpu family : 6\nmodel : 85\nmodel name : Intel(R) Xeon(R) Gold 5218R CPU @ 2.10GHz\nstepping : 7\nmicrocode : 0x1\ncpu MHz : 2095.082\ncache size : 16384 KB\nphysical id : 1\nsiblings : 2\ncore id : 0\ncpu cores : 1\napicid : 3\ninitial apicid : 3\nfpu : yes\nfpu_exception : yes\ncpuid level : 13\nwp : yes\nflags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ss ht syscall nx pdpe1gb rdtscp lm constant_tsc arch_perfmon rep_good nopl xtopology cpuid tsc_known_freq pni pclmulqdq vmx ssse3 fma cx16 pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand hypervisor lahf_lm abm 3dnowprefetch cpuid_fault invpcid_single ssbd ibrs ibpb ibrs_enhanced tpr_shadow vnmi flexpriority ept vpid fsgsbase tsc_adjust bmi1 avx2 smep bmi2 erms invpcid mpx avx512f avx512dq rdseed adx smap clflushopt clwb avx512cd avx512bw avx512vl xsaveopt xsavec xgetbv1 xsaves arat pku ospke avx512_vnni md_clear arch_capabilities\nbugs : spectre_v1 spectre_v2 spec_store_bypass swapgs\nbogomips : 4190.16\nclflush size : 64\ncache_alignment : 64\naddress sizes : 40 bits physical, 48 bits virtual\npower management:\n\nprocessor : 4\nvendor_id : GenuineIntel\ncpu family : 6\nmodel : 85\nmodel name : Intel(R) Xeon(R) Gold 5218R CPU @ 2.10GHz\nstepping : 7\nmicrocode : 0x1\ncpu MHz : 2095.082\ncache size : 16384 KB\nphysical id : 2\nsiblings : 2\ncore id : 0\ncpu cores : 1\napicid : 4\ninitial apicid : 4\nfpu : yes\nfpu_exception : yes\ncpuid level : 13\nwp : yes\nflags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ss ht syscall nx pdpe1gb rdtscp lm constant_tsc arch_perfmon rep_good nopl xtopology cpuid tsc_known_freq pni pclmulqdq vmx ssse3 fma cx16 pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand hypervisor lahf_lm abm 3dnowprefetch cpuid_fault invpcid_single ssbd ibrs ibpb ibrs_enhanced tpr_shadow vnmi flexpriority ept vpid fsgsbase tsc_adjust bmi1 avx2 smep bmi2 erms invpcid mpx avx512f avx512dq rdseed adx smap clflushopt clwb avx512cd avx512bw avx512vl xsaveopt xsavec xgetbv1 xsaves arat pku ospke avx512_vnni md_clear arch_capabilities\nbugs : spectre_v1 spectre_v2 spec_store_bypass swapgs\nbogomips : 4190.16\nclflush size : 64\ncache_alignment : 64\naddress sizes : 40 bits physical, 48 bits virtual\npower management:\n\nprocessor : 5\nvendor_id : GenuineIntel\ncpu family : 6\nmodel : 85\nmodel name : Intel(R) Xeon(R) Gold 5218R CPU @ 2.10GHz\nstepping : 7\nmicrocode : 0x1\ncpu MHz : 2095.082\ncache size : 16384 KB\nphysical id : 2\nsiblings : 2\ncore id : 0\ncpu cores : 1\napicid : 5\ninitial apicid : 5\nfpu : yes\nfpu_exception : yes\ncpuid level : 13\nwp : yes\nflags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ss ht syscall nx pdpe1gb rdtscp lm constant_tsc arch_perfmon rep_good nopl xtopology cpuid tsc_known_freq pni pclmulqdq vmx ssse3 fma cx16 pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand hypervisor lahf_lm abm 3dnowprefetch cpuid_fault invpcid_single ssbd ibrs ibpb ibrs_enhanced tpr_shadow vnmi flexpriority ept vpid fsgsbase tsc_adjust bmi1 avx2 smep bmi2 erms invpcid mpx avx512f avx512dq rdseed adx smap clflushopt clwb avx512cd avx512bw avx512vl xsaveopt xsavec xgetbv1 xsaves arat pku ospke avx512_vnni md_clear arch_capabilities\nbugs : spectre_v1 spectre_v2 spec_store_bypass swapgs\nbogomips : 4190.16\nclflush size : 64\ncache_alignment : 64\naddress sizes : 40 bits physical, 48 bits virtual\npower management:\n\nprocessor : 6\nvendor_id : GenuineIntel\ncpu family : 6\nmodel : 85\nmodel name : Intel(R) Xeon(R) Gold 5218R CPU @ 2.10GHz\nstepping : 7\nmicrocode : 0x1\ncpu MHz : 2095.082\ncache size : 16384 KB\nphysical id : 3\nsiblings : 2\ncore id : 0\ncpu cores : 1\napicid : 6\ninitial apicid : 6\nfpu : yes\nfpu_exception : yes\ncpuid level : 13\nwp : yes\nflags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ss ht syscall nx pdpe1gb rdtscp lm constant_tsc arch_perfmon rep_good nopl xtopology cpuid tsc_known_freq pni pclmulqdq vmx ssse3 fma cx16 pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand hypervisor lahf_lm abm 3dnowprefetch cpuid_fault invpcid_single ssbd ibrs ibpb ibrs_enhanced tpr_shadow vnmi flexpriority ept vpid fsgsbase tsc_adjust bmi1 avx2 smep bmi2 erms invpcid mpx avx512f avx512dq rdseed adx smap clflushopt clwb avx512cd avx512bw avx512vl xsaveopt xsavec xgetbv1 xsaves arat pku ospke avx512_vnni md_clear arch_capabilities\nbugs : spectre_v1 spectre_v2 spec_store_bypass swapgs\nbogomips : 4190.16\nclflush size : 64\ncache_alignment : 64\naddress sizes : 40 bits physical, 48 bits virtual\npower management:\n\nprocessor : 7\nvendor_id : GenuineIntel\ncpu family : 6\nmodel : 85\nmodel name : Intel(R) Xeon(R) Gold 5218R CPU @ 2.10GHz\nstepping : 7\nmicrocode : 0x1\ncpu MHz : 2095.082\ncache size : 16384 KB\nphysical id : 3\nsiblings : 2\ncore id : 0\ncpu cores : 1\napicid : 7\ninitial apicid : 7\nfpu : yes\nfpu_exception : yes\ncpuid level : 13\nwp : yes\nflags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ss ht syscall nx pdpe1gb rdtscp lm constant_tsc arch_perfmon rep_good nopl xtopology cpuid tsc_known_freq pni pclmulqdq vmx ssse3 fma cx16 pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand hypervisor lahf_lm abm 3dnowprefetch cpuid_fault invpcid_single ssbd ibrs ibpb ibrs_enhanced tpr_shadow vnmi flexpriority ept vpid fsgsbase tsc_adjust bmi1 avx2 smep bmi2 erms invpcid mpx avx512f avx512dq rdseed adx smap clflushopt clwb avx512cd avx512bw avx512vl xsaveopt xsavec xgetbv1 xsaves arat pku ospke avx512_vnni md_clear arch_capabilities\nbugs : spectre_v1 spectre_v2 spec_store_bypass swapgs\nbogomips : 4190.16\nclflush size : 64\ncache_alignment : 64\naddress sizes : 40 bits physical, 48 bits virtual\npower management:\n\nprocessor : 8\nvendor_id : GenuineIntel\ncpu family : 6\nmodel : 85\nmodel name : Intel(R) Xeon(R) Gold 5218R CPU @ 2.10GHz\nstepping : 7\nmicrocode : 0x1\ncpu MHz : 2095.082\ncache size : 16384 KB\nphysical id : 4\nsiblings : 2\ncore id : 0\ncpu cores : 1\napicid : 8\ninitial apicid : 8\nfpu : yes\nfpu_exception : yes\ncpuid level : 13\nwp : yes\nflags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ss ht syscall nx pdpe1gb rdtscp lm constant_tsc arch_perfmon rep_good nopl xtopology cpuid tsc_known_freq pni pclmulqdq vmx ssse3 fma cx16 pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand hypervisor lahf_lm abm 3dnowprefetch cpuid_fault invpcid_single ssbd ibrs ibpb ibrs_enhanced tpr_shadow vnmi flexpriority ept vpid fsgsbase tsc_adjust bmi1 avx2 smep bmi2 erms invpcid mpx avx512f avx512dq rdseed adx smap clflushopt clwb avx512cd avx512bw avx512vl xsaveopt xsavec xgetbv1 xsaves arat pku ospke avx512_vnni md_clear arch_capabilities\nbugs : spectre_v1 spectre_v2 spec_store_bypass swapgs\nbogomips : 4190.16\nclflush size : 64\ncache_alignment : 64\naddress sizes : 40 bits physical, 48 bits virtual\npower management:\n\nprocessor : 9\nvendor_id : GenuineIntel\ncpu family : 6\nmodel : 85\nmodel name : Intel(R) Xeon(R) Gold 5218R CPU @ 2.10GHz\nstepping : 7\nmicrocode : 0x1\ncpu MHz : 2095.082\ncache size : 16384 KB\nphysical id : 4\nsiblings : 2\ncore id : 0\ncpu cores : 1\napicid : 9\ninitial apicid : 9\nfpu : yes\nfpu_exception : yes\ncpuid level : 13\nwp : yes\nflags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ss ht syscall nx pdpe1gb rdtscp lm constant_tsc arch_perfmon rep_good nopl xtopology cpuid tsc_known_freq pni pclmulqdq vmx ssse3 fma cx16 pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand hypervisor lahf_lm abm 3dnowprefetch cpuid_fault invpcid_single ssbd ibrs ibpb ibrs_enhanced tpr_shadow vnmi flexpriority ept vpid fsgsbase tsc_adjust bmi1 avx2 smep bmi2 erms invpcid mpx avx512f avx512dq rdseed adx smap clflushopt clwb avx512cd avx512bw avx512vl xsaveopt xsavec xgetbv1 xsaves arat pku ospke avx512_vnni md_clear arch_capabilities\nbugs : spectre_v1 spectre_v2 spec_store_bypass swapgs\nbogomips : 4190.16\nclflush size : 64\ncache_alignment : 64\naddress sizes : 40 bits physical, 48 bits virtual\npower management:\n\nprocessor : 10\nvendor_id : GenuineIntel\ncpu family : 6\nmodel : 85\nmodel name : Intel(R) Xeon(R) Gold 5218R CPU @ 2.10GHz\nstepping : 7\nmicrocode : 0x1\ncpu MHz : 2095.082\ncache size : 16384 KB\nphysical id : 5\nsiblings : 2\ncore id : 0\ncpu cores : 1\napicid : 10\ninitial apicid : 10\nfpu : yes\nfpu_exception : yes\ncpuid level : 13\nwp : yes\nflags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ss ht syscall nx pdpe1gb rdtscp lm constant_tsc arch_perfmon rep_good nopl xtopology cpuid tsc_known_freq pni pclmulqdq vmx ssse3 fma cx16 pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand hypervisor lahf_lm abm 3dnowprefetch cpuid_fault invpcid_single ssbd ibrs ibpb ibrs_enhanced tpr_shadow vnmi flexpriority ept vpid fsgsbase tsc_adjust bmi1 avx2 smep bmi2 erms invpcid mpx avx512f avx512dq rdseed adx smap clflushopt clwb avx512cd avx512bw avx512vl xsaveopt xsavec xgetbv1 xsaves arat pku ospke avx512_vnni md_clear arch_capabilities\nbugs : spectre_v1 spectre_v2 spec_store_bypass swapgs\nbogomips : 4190.16\nclflush size : 64\ncache_alignment : 64\naddress sizes : 40 bits physical, 48 bits virtual\npower management:\n\nprocessor : 11\nvendor_id : GenuineIntel\ncpu family : 6\nmodel : 85\nmodel name : Intel(R) Xeon(R) Gold 5218R CPU @ 2.10GHz\nstepping : 7\nmicrocode : 0x1\ncpu MHz : 2095.082\ncache size : 16384 KB\nphysical id : 5\nsiblings : 2\ncore id : 0\ncpu cores : 1\napicid : 11\ninitial apicid : 11\nfpu : yes\nfpu_exception : yes\ncpuid level : 13\nwp : yes\nflags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ss ht syscall nx pdpe1gb rdtscp lm constant_tsc arch_perfmon rep_good nopl xtopology cpuid tsc_known_freq pni pclmulqdq vmx ssse3 fma cx16 pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand hypervisor lahf_lm abm 3dnowprefetch cpuid_fault invpcid_single ssbd ibrs ibpb ibrs_enhanced tpr_shadow vnmi flexpriority ept vpid fsgsbase tsc_adjust bmi1 avx2 smep bmi2 erms invpcid mpx avx512f avx512dq rdseed adx smap clflushopt clwb avx512cd avx512bw avx512vl xsaveopt xsavec xgetbv1 xsaves arat pku ospke avx512_vnni md_clear arch_capabilities\nbugs : spectre_v1 spectre_v2 spec_store_bypass swapgs\nbogomips : 4190.16\nclflush size : 64\ncache_alignment : 64\naddress sizes : 40 bits physical, 48 bits virtual\npower management:\n\nprocessor : 12\nvendor_id : GenuineIntel\ncpu family : 6\nmodel : 85\nmodel name : Intel(R) Xeon(R) Gold 5218R CPU @ 2.10GHz\nstepping : 7\nmicrocode : 0x1\ncpu MHz : 2095.082\ncache size : 16384 KB\nphysical id : 6\nsiblings : 2\ncore id : 0\ncpu cores : 1\napicid : 12\ninitial apicid : 12\nfpu : yes\nfpu_exception : yes\ncpuid level : 13\nwp : yes\nflags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ss ht syscall nx pdpe1gb rdtscp lm constant_tsc arch_perfmon rep_good nopl xtopology cpuid tsc_known_freq pni pclmulqdq vmx ssse3 fma cx16 pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand hypervisor lahf_lm abm 3dnowprefetch cpuid_fault invpcid_single ssbd ibrs ibpb ibrs_enhanced tpr_shadow vnmi flexpriority ept vpid fsgsbase tsc_adjust bmi1 avx2 smep bmi2 erms invpcid mpx avx512f avx512dq rdseed adx smap clflushopt clwb avx512cd avx512bw avx512vl xsaveopt xsavec xgetbv1 xsaves arat pku ospke avx512_vnni md_clear arch_capabilities\nbugs : spectre_v1 spectre_v2 spec_store_bypass swapgs\nbogomips : 4190.16\nclflush size : 64\ncache_alignment : 64\naddress sizes : 40 bits physical, 48 bits virtual\npower management:\n\nprocessor : 13\nvendor_id : GenuineIntel\ncpu family : 6\nmodel : 85\nmodel name : Intel(R) Xeon(R) Gold 5218R CPU @ 2.10GHz\nstepping : 7\nmicrocode : 0x1\ncpu MHz : 2095.082\ncache size : 16384 KB\nphysical id : 6\nsiblings : 2\ncore id : 0\ncpu cores : 1\napicid : 13\ninitial apicid : 13\nfpu : yes\nfpu_exception : yes\ncpuid level : 13\nwp : yes\nflags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ss ht syscall nx pdpe1gb rdtscp lm constant_tsc arch_perfmon rep_good nopl xtopology cpuid tsc_known_freq pni pclmulqdq vmx ssse3 fma cx16 pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand hypervisor lahf_lm abm 3dnowprefetch cpuid_fault invpcid_single ssbd ibrs ibpb ibrs_enhanced tpr_shadow vnmi flexpriority ept vpid fsgsbase tsc_adjust bmi1 avx2 smep bmi2 erms invpcid mpx avx512f avx512dq rdseed adx smap clflushopt clwb avx512cd avx512bw avx512vl xsaveopt xsavec xgetbv1 xsaves arat pku ospke avx512_vnni md_clear arch_capabilities\nbugs : spectre_v1 spectre_v2 spec_store_bypass swapgs\nbogomips : 4190.16\nclflush size : 64\ncache_alignment : 64\naddress sizes : 40 bits physical, 48 bits virtual\npower management:\n\nprocessor : 14\nvendor_id : GenuineIntel\ncpu family : 6\nmodel : 85\nmodel name : Intel(R) Xeon(R) Gold 5218R CPU @ 2.10GHz\nstepping : 7\nmicrocode : 0x1\ncpu MHz : 2095.082\ncache size : 16384 KB\nphysical id : 7\nsiblings : 2\ncore id : 0\ncpu cores : 1\napicid : 14\ninitial apicid : 14\nfpu : yes\nfpu_exception : yes\ncpuid level : 13\nwp : yes\nflags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ss ht syscall nx pdpe1gb rdtscp lm constant_tsc arch_perfmon rep_good nopl xtopology cpuid tsc_known_freq pni pclmulqdq vmx ssse3 fma cx16 pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand hypervisor lahf_lm abm 3dnowprefetch cpuid_fault invpcid_single ssbd ibrs ibpb ibrs_enhanced tpr_shadow vnmi flexpriority ept vpid fsgsbase tsc_adjust bmi1 avx2 smep bmi2 erms invpcid mpx avx512f avx512dq rdseed adx smap clflushopt clwb avx512cd avx512bw avx512vl xsaveopt xsavec xgetbv1 xsaves arat pku ospke avx512_vnni md_clear arch_capabilities\nbugs : spectre_v1 spectre_v2 spec_store_bypass swapgs\nbogomips : 4190.16\nclflush size : 64\ncache_alignment : 64\naddress sizes : 40 bits physical, 48 bits virtual\npower management:\n\nprocessor : 15\nvendor_id : GenuineIntel\ncpu family : 6\nmodel : 85\nmodel name : Intel(R) Xeon(R) Gold 5218R CPU @ 2.10GHz\nstepping : 7\nmicrocode : 0x1\ncpu MHz : 2095.082\ncache size : 16384 KB\nphysical id : 7\nsiblings : 2\ncore id : 0\ncpu cores : 1\napicid : 15\ninitial apicid : 15\nfpu : yes\nfpu_exception : yes\ncpuid level : 13\nwp : yes\nflags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ss ht syscall nx pdpe1gb rdtscp lm constant_tsc arch_perfmon rep_good nopl xtopology cpuid tsc_known_freq pni pclmulqdq vmx ssse3 fma cx16 pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand hypervisor lahf_lm abm 3dnowprefetch cpuid_fault invpcid_single ssbd ibrs ibpb ibrs_enhanced tpr_shadow vnmi flexpriority ept vpid fsgsbase tsc_adjust bmi1 avx2 smep bmi2 erms invpcid mpx avx512f avx512dq rdseed adx smap clflushopt clwb avx512cd avx512bw avx512vl xsaveopt xsavec xgetbv1 xsaves arat pku ospke avx512_vnni md_clear arch_capabilities\nbugs : spectre_v1 spectre_v2 spec_store_bypass swapgs\nbogomips : 4190.16\nclflush size : 64\ncache_alignment : 64\naddress sizes : 40 bits physical, 48 bits virtual\npower management:\n\nprocessor : 16\nvendor_id : GenuineIntel\ncpu family : 6\nmodel : 85\nmodel name : Intel(R) Xeon(R) Gold 5218R CPU @ 2.10GHz\nstepping : 7\nmicrocode : 0x1\ncpu MHz : 2095.082\ncache size : 16384 KB\nphysical id : 8\nsiblings : 2\ncore id : 0\ncpu cores : 1\napicid : 16\ninitial apicid : 16\nfpu : yes\nfpu_exception : yes\ncpuid level : 13\nwp : yes\nflags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ss ht syscall nx pdpe1gb rdtscp lm constant_tsc arch_perfmon rep_good nopl xtopology cpuid tsc_known_freq pni pclmulqdq vmx ssse3 fma cx16 pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand hypervisor lahf_lm abm 3dnowprefetch cpuid_fault invpcid_single ssbd ibrs ibpb ibrs_enhanced tpr_shadow vnmi flexpriority ept vpid fsgsbase tsc_adjust bmi1 avx2 smep bmi2 erms invpcid mpx avx512f avx512dq rdseed adx smap clflushopt clwb avx512cd avx512bw avx512vl xsaveopt xsavec xgetbv1 xsaves arat pku ospke avx512_vnni md_clear arch_capabilities\nbugs : spectre_v1 spectre_v2 spec_store_bypass swapgs\nbogomips : 4190.16\nclflush size : 64\ncache_alignment : 64\naddress sizes : 40 bits physical, 48 bits virtual\npower management:\n\nprocessor : 17\nvendor_id : GenuineIntel\ncpu family : 6\nmodel : 85\nmodel name : Intel(R) Xeon(R) Gold 5218R CPU @ 2.10GHz\nstepping : 7\nmicrocode : 0x1\ncpu MHz : 2095.082\ncache size : 16384 KB\nphysical id : 8\nsiblings : 2\ncore id : 0\ncpu cores : 1\napicid : 17\ninitial apicid : 17\nfpu : yes\nfpu_exception : yes\ncpuid level : 13\nwp : yes\nflags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ss ht syscall nx pdpe1gb rdtscp lm constant_tsc arch_perfmon rep_good nopl xtopology cpuid tsc_known_freq pni pclmulqdq vmx ssse3 fma cx16 pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand hypervisor lahf_lm abm 3dnowprefetch cpuid_fault invpcid_single ssbd ibrs ibpb ibrs_enhanced tpr_shadow vnmi flexpriority ept vpid fsgsbase tsc_adjust bmi1 avx2 smep bmi2 erms invpcid mpx avx512f avx512dq rdseed adx smap clflushopt clwb avx512cd avx512bw avx512vl xsaveopt xsavec xgetbv1 xsaves arat pku ospke avx512_vnni md_clear arch_capabilities\nbugs : spectre_v1 spectre_v2 spec_store_bypass swapgs\nbogomips : 4190.16\nclflush size : 64\ncache_alignment : 64\naddress sizes : 40 bits physical, 48 bits virtual\npower management:\n\nprocessor : 18\nvendor_id : GenuineIntel\ncpu family : 6\nmodel : 85\nmodel name : Intel(R) Xeon(R) Gold 5218R CPU @ 2.10GHz\nstepping : 7\nmicrocode : 0x1\ncpu MHz : 2095.082\ncache size : 16384 KB\nphysical id : 9\nsiblings : 2\ncore id : 0\ncpu cores : 1\napicid : 18\ninitial apicid : 18\nfpu : yes\nfpu_exception : yes\ncpuid level : 13\nwp : yes\nflags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ss ht syscall nx pdpe1gb rdtscp lm constant_tsc arch_perfmon rep_good nopl xtopology cpuid tsc_known_freq pni pclmulqdq vmx ssse3 fma cx16 pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand hypervisor lahf_lm abm 3dnowprefetch cpuid_fault invpcid_single ssbd ibrs ibpb ibrs_enhanced tpr_shadow vnmi flexpriority ept vpid fsgsbase tsc_adjust bmi1 avx2 smep bmi2 erms invpcid mpx avx512f avx512dq rdseed adx smap clflushopt clwb avx512cd avx512bw avx512vl xsaveopt xsavec xgetbv1 xsaves arat pku ospke avx512_vnni md_clear arch_capabilities\nbugs : spectre_v1 spectre_v2 spec_store_bypass swapgs\nbogomips : 4190.16\nclflush size : 64\ncache_alignment : 64\naddress sizes : 40 bits physical, 48 bits virtual\npower management:\n\nprocessor : 19\nvendor_id : GenuineIntel\ncpu family : 6\nmodel : 85\nmodel name : Intel(R) Xeon(R) Gold 5218R CPU @ 2.10GHz\nstepping : 7\nmicrocode : 0x1\ncpu MHz : 2095.082\ncache size : 16384 KB\nphysical id : 9\nsiblings : 2\ncore id : 0\ncpu cores : 1\napicid : 19\ninitial apicid : 19\nfpu : yes\nfpu_exception : yes\ncpuid level : 13\nwp : yes\nflags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ss ht syscall nx pdpe1gb rdtscp lm constant_tsc arch_perfmon rep_good nopl xtopology cpuid tsc_known_freq pni pclmulqdq vmx ssse3 fma cx16 pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand hypervisor lahf_lm abm 3dnowprefetch cpuid_fault invpcid_single ssbd ibrs ibpb ibrs_enhanced tpr_shadow vnmi flexpriority ept vpid fsgsbase tsc_adjust bmi1 avx2 smep bmi2 erms invpcid mpx avx512f avx512dq rdseed adx smap clflushopt clwb avx512cd avx512bw avx512vl xsaveopt xsavec xgetbv1 xsaves arat pku ospke avx512_vnni md_clear arch_capabilities\nbugs : spectre_v1 spectre_v2 spec_store_bypass swapgs\nbogomips : 4190.16\nclflush size : 64\ncache_alignment : 64\naddress sizes : 40 bits physical, 48 bits virtual\npower management:\n\nprocessor : 20\nvendor_id : GenuineIntel\ncpu family : 6\nmodel : 85\nmodel name : Intel(R) Xeon(R) Gold 5218R CPU @ 2.10GHz\nstepping : 7\nmicrocode : 0x1\ncpu MHz : 2095.082\ncache size : 16384 KB\nphysical id : 10\nsiblings : 2\ncore id : 0\ncpu cores : 1\napicid : 20\ninitial apicid : 20\nfpu : yes\nfpu_exception : yes\ncpuid level : 13\nwp : yes\nflags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ss ht syscall nx pdpe1gb rdtscp lm constant_tsc arch_perfmon rep_good nopl xtopology cpuid tsc_known_freq pni pclmulqdq vmx ssse3 fma cx16 pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand hypervisor lahf_lm abm 3dnowprefetch cpuid_fault invpcid_single ssbd ibrs ibpb ibrs_enhanced tpr_shadow vnmi flexpriority ept vpid fsgsbase tsc_adjust bmi1 avx2 smep bmi2 erms invpcid mpx avx512f avx512dq rdseed adx smap clflushopt clwb avx512cd avx512bw avx512vl xsaveopt xsavec xgetbv1 xsaves arat pku ospke avx512_vnni md_clear arch_capabilities\nbugs : spectre_v1 spectre_v2 spec_store_bypass swapgs\nbogomips : 4190.16\nclflush size : 64\ncache_alignment : 64\naddress sizes : 40 bits physical, 48 bits virtual\npower management:\n\nprocessor : 21\nvendor_id : GenuineIntel\ncpu family : 6\nmodel : 85\nmodel name : Intel(R) Xeon(R) Gold 5218R CPU @ 2.10GHz\nstepping : 7\nmicrocode : 0x1\ncpu MHz : 2095.082\ncache size : 16384 KB\nphysical id : 10\nsiblings : 2\ncore id : 0\ncpu cores : 1\napicid : 21\ninitial apicid : 21\nfpu : yes\nfpu_exception : yes\ncpuid level : 13\nwp : yes\nflags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ss ht syscall nx pdpe1gb rdtscp lm constant_tsc arch_perfmon rep_good nopl xtopology cpuid tsc_known_freq pni pclmulqdq vmx ssse3 fma cx16 pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand hypervisor lahf_lm abm 3dnowprefetch cpuid_fault invpcid_single ssbd ibrs ibpb ibrs_enhanced tpr_shadow vnmi flexpriority ept vpid fsgsbase tsc_adjust bmi1 avx2 smep bmi2 erms invpcid mpx avx512f avx512dq rdseed adx smap clflushopt clwb avx512cd avx512bw avx512vl xsaveopt xsavec xgetbv1 xsaves arat pku ospke avx512_vnni md_clear arch_capabilities\nbugs : spectre_v1 spectre_v2 spec_store_bypass swapgs\nbogomips : 4190.16\nclflush size : 64\ncache_alignment : 64\naddress sizes : 40 bits physical, 48 bits virtual\npower management:\n\nprocessor : 22\nvendor_id : GenuineIntel\ncpu family : 6\nmodel : 85\nmodel name : Intel(R) Xeon(R) Gold 5218R CPU @ 2.10GHz\nstepping : 7\nmicrocode : 0x1\ncpu MHz : 2095.082\ncache size : 16384 KB\nphysical id : 11\nsiblings : 2\ncore id : 0\ncpu cores : 1\napicid : 22\ninitial apicid : 22\nfpu : yes\nfpu_exception : yes\ncpuid level : 13\nwp : yes\nflags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ss ht syscall nx pdpe1gb rdtscp lm constant_tsc arch_perfmon rep_good nopl xtopology cpuid tsc_known_freq pni pclmulqdq vmx ssse3 fma cx16 pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand hypervisor lahf_lm abm 3dnowprefetch cpuid_fault invpcid_single ssbd ibrs ibpb ibrs_enhanced tpr_shadow vnmi flexpriority ept vpid fsgsbase tsc_adjust bmi1 avx2 smep bmi2 erms invpcid mpx avx512f avx512dq rdseed adx smap clflushopt clwb avx512cd avx512bw avx512vl xsaveopt xsavec xgetbv1 xsaves arat pku ospke avx512_vnni md_clear arch_capabilities\nbugs : spectre_v1 spectre_v2 spec_store_bypass swapgs\nbogomips : 4190.16\nclflush size : 64\ncache_alignment : 64\naddress sizes : 40 bits physical, 48 bits virtual\npower management:\n\nprocessor : 23\nvendor_id : GenuineIntel\ncpu family : 6\nmodel : 85\nmodel name : Intel(R) Xeon(R) Gold 5218R CPU @ 2.10GHz\nstepping : 7\nmicrocode : 0x1\ncpu MHz : 2095.082\ncache size : 16384 KB\nphysical id : 11\nsiblings : 2\ncore id : 0\ncpu cores : 1\napicid : 23\ninitial apicid : 23\nfpu : yes\nfpu_exception : yes\ncpuid level : 13\nwp : yes\nflags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ss ht syscall nx pdpe1gb rdtscp lm constant_tsc arch_perfmon rep_good nopl xtopology cpuid tsc_known_freq pni pclmulqdq vmx ssse3 fma cx16 pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand hypervisor lahf_lm abm 3dnowprefetch cpuid_fault invpcid_single ssbd ibrs ibpb ibrs_enhanced tpr_shadow vnmi flexpriority ept vpid fsgsbase tsc_adjust bmi1 avx2 smep bmi2 erms invpcid mpx avx512f avx512dq rdseed adx smap clflushopt clwb avx512cd avx512bw avx512vl xsaveopt xsavec xgetbv1 xsaves arat pku ospke avx512_vnni md_clear arch_capabilities\nbugs : spectre_v1 spectre_v2 spec_store_bypass swapgs\nbogomips : 4190.16\nclflush size : 64\ncache_alignment : 64\naddress sizes : 40 bits physical, 48 bits virtual\npower management:\n\nprocessor : 24\nvendor_id : GenuineIntel\ncpu family : 6\nmodel : 85\nmodel name : Intel(R) Xeon(R) Gold 5218R CPU @ 2.10GHz\nstepping : 7\nmicrocode : 0x1\ncpu MHz : 2095.082\ncache size : 16384 KB\nphysical id : 12\nsiblings : 2\ncore id : 0\ncpu cores : 1\napicid : 24\ninitial apicid : 24\nfpu : yes\nfpu_exception : yes\ncpuid level : 13\nwp : yes\nflags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ss ht syscall nx pdpe1gb rdtscp lm constant_tsc arch_perfmon rep_good nopl xtopology cpuid tsc_known_freq pni pclmulqdq vmx ssse3 fma cx16 pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand hypervisor lahf_lm abm 3dnowprefetch cpuid_fault invpcid_single ssbd ibrs ibpb ibrs_enhanced tpr_shadow vnmi flexpriority ept vpid fsgsbase tsc_adjust bmi1 avx2 smep bmi2 erms invpcid mpx avx512f avx512dq rdseed adx smap clflushopt clwb avx512cd avx512bw avx512vl xsaveopt xsavec xgetbv1 xsaves arat pku ospke avx512_vnni md_clear arch_capabilities\nbugs : spectre_v1 spectre_v2 spec_store_bypass swapgs\nbogomips : 4190.16\nclflush size : 64\ncache_alignment : 64\naddress sizes : 40 bits physical, 48 bits virtual\npower management:\n\nprocessor : 25\nvendor_id : GenuineIntel\ncpu family : 6\nmodel : 85\nmodel name : Intel(R) Xeon(R) Gold 5218R CPU @ 2.10GHz\nstepping : 7\nmicrocode : 0x1\ncpu MHz : 2095.082\ncache size : 16384 KB\nphysical id : 12\nsiblings : 2\ncore id : 0\ncpu cores : 1\napicid : 25\ninitial apicid : 25\nfpu : yes\nfpu_exception : yes\ncpuid level : 13\nwp : yes\nflags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ss ht syscall nx pdpe1gb rdtscp lm constant_tsc arch_perfmon rep_good nopl xtopology cpuid tsc_known_freq pni pclmulqdq vmx ssse3 fma cx16 pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand hypervisor lahf_lm abm 3dnowprefetch cpuid_fault invpcid_single ssbd ibrs ibpb ibrs_enhanced tpr_shadow vnmi flexpriority ept vpid fsgsbase tsc_adjust bmi1 avx2 smep bmi2 erms invpcid mpx avx512f avx512dq rdseed adx smap clflushopt clwb avx512cd avx512bw avx512vl xsaveopt xsavec xgetbv1 xsaves arat pku ospke avx512_vnni md_clear arch_capabilities\nbugs : spectre_v1 spectre_v2 spec_store_bypass swapgs\nbogomips : 4190.16\nclflush size : 64\ncache_alignment : 64\naddress sizes : 40 bits physical, 48 bits virtual\npower management:\n\nprocessor : 26\nvendor_id : GenuineIntel\ncpu family : 6\nmodel : 85\nmodel name : Intel(R) Xeon(R) Gold 5218R CPU @ 2.10GHz\nstepping : 7\nmicrocode : 0x1\ncpu MHz : 2095.082\ncache size : 16384 KB\nphysical id : 13\nsiblings : 2\ncore id : 0\ncpu cores : 1\napicid : 26\ninitial apicid : 26\nfpu : yes\nfpu_exception : yes\ncpuid level : 13\nwp : yes\nflags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ss ht syscall nx pdpe1gb rdtscp lm constant_tsc arch_perfmon rep_good nopl xtopology cpuid tsc_known_freq pni pclmulqdq vmx ssse3 fma cx16 pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand hypervisor lahf_lm abm 3dnowprefetch cpuid_fault invpcid_single ssbd ibrs ibpb ibrs_enhanced tpr_shadow vnmi flexpriority ept vpid fsgsbase tsc_adjust bmi1 avx2 smep bmi2 erms invpcid mpx avx512f avx512dq rdseed adx smap clflushopt clwb avx512cd avx512bw avx512vl xsaveopt xsavec xgetbv1 xsaves arat pku ospke avx512_vnni md_clear arch_capabilities\nbugs : spectre_v1 spectre_v2 spec_store_bypass swapgs\nbogomips : 4190.16\nclflush size : 64\ncache_alignment : 64\naddress sizes : 40 bits physical, 48 bits virtual\npower management:\n\nprocessor : 27\nvendor_id : GenuineIntel\ncpu family : 6\nmodel : 85\nmodel name : Intel(R) Xeon(R) Gold 5218R CPU @ 2.10GHz\nstepping : 7\nmicrocode : 0x1\ncpu MHz : 2095.082\ncache size : 16384 KB\nphysical id : 13\nsiblings : 2\ncore id : 0\ncpu cores : 1\napicid : 27\ninitial apicid : 27\nfpu : yes\nfpu_exception : yes\ncpuid level : 13\nwp : yes\nflags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ss ht syscall nx pdpe1gb rdtscp lm constant_tsc arch_perfmon rep_good nopl xtopology cpuid tsc_known_freq pni pclmulqdq vmx ssse3 fma cx16 pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand hypervisor lahf_lm abm 3dnowprefetch cpuid_fault invpcid_single ssbd ibrs ibpb ibrs_enhanced tpr_shadow vnmi flexpriority ept vpid fsgsbase tsc_adjust bmi1 avx2 smep bmi2 erms invpcid mpx avx512f avx512dq rdseed adx smap clflushopt clwb avx512cd avx512bw avx512vl xsaveopt xsavec xgetbv1 xsaves arat pku ospke avx512_vnni md_clear arch_capabilities\nbugs : spectre_v1 spectre_v2 spec_store_bypass swapgs\nbogomips : 4190.16\nclflush size : 64\ncache_alignment : 64\naddress sizes : 40 bits physical, 48 bits virtual\npower management:\n\nprocessor : 28\nvendor_id : GenuineIntel\ncpu family : 6\nmodel : 85\nmodel name : Intel(R) Xeon(R) Gold 5218R CPU @ 2.10GHz\nstepping : 7\nmicrocode : 0x1\ncpu MHz : 2095.082\ncache size : 16384 KB\nphysical id : 14\nsiblings : 2\ncore id : 0\ncpu cores : 1\napicid : 28\ninitial apicid : 28\nfpu : yes\nfpu_exception : yes\ncpuid level : 13\nwp : yes\nflags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ss ht syscall nx pdpe1gb rdtscp lm constant_tsc arch_perfmon rep_good nopl xtopology cpuid tsc_known_freq pni pclmulqdq vmx ssse3 fma cx16 pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand hypervisor lahf_lm abm 3dnowprefetch cpuid_fault invpcid_single ssbd ibrs ibpb ibrs_enhanced tpr_shadow vnmi flexpriority ept vpid fsgsbase tsc_adjust bmi1 avx2 smep bmi2 erms invpcid mpx avx512f avx512dq rdseed adx smap clflushopt clwb avx512cd avx512bw avx512vl xsaveopt xsavec xgetbv1 xsaves arat pku ospke avx512_vnni md_clear arch_capabilities\nbugs : spectre_v1 spectre_v2 spec_store_bypass swapgs\nbogomips : 4190.16\nclflush size : 64\ncache_alignment : 64\naddress sizes : 40 bits physical, 48 bits virtual\npower management:\n\nprocessor : 29\nvendor_id : GenuineIntel\ncpu family : 6\nmodel : 85\nmodel name : Intel(R) Xeon(R) Gold 5218R CPU @ 2.10GHz\nstepping : 7\nmicrocode : 0x1\ncpu MHz : 2095.082\ncache size : 16384 KB\nphysical id : 14\nsiblings : 2\ncore id : 0\ncpu cores : 1\napicid : 29\ninitial apicid : 29\nfpu : yes\nfpu_exception : yes\ncpuid level : 13\nwp : yes\nflags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ss ht syscall nx pdpe1gb rdtscp lm constant_tsc arch_perfmon rep_good nopl xtopology cpuid tsc_known_freq pni pclmulqdq vmx ssse3 fma cx16 pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand hypervisor lahf_lm abm 3dnowprefetch cpuid_fault invpcid_single ssbd ibrs ibpb ibrs_enhanced tpr_shadow vnmi flexpriority ept vpid fsgsbase tsc_adjust bmi1 avx2 smep bmi2 erms invpcid mpx avx512f avx512dq rdseed adx smap clflushopt clwb avx512cd avx512bw avx512vl xsaveopt xsavec xgetbv1 xsaves arat pku ospke avx512_vnni md_clear arch_capabilities\nbugs : spectre_v1 spectre_v2 spec_store_bypass swapgs\nbogomips : 4190.16\nclflush size : 64\ncache_alignment : 64\naddress sizes : 40 bits physical, 48 bits virtual\npower management:\n\nprocessor : 30\nvendor_id : GenuineIntel\ncpu family : 6\nmodel : 85\nmodel name : Intel(R) Xeon(R) Gold 5218R CPU @ 2.10GHz\nstepping : 7\nmicrocode : 0x1\ncpu MHz : 2095.082\ncache size : 16384 KB\nphysical id : 15\nsiblings : 2\ncore id : 0\ncpu cores : 1\napicid : 30\ninitial apicid : 30\nfpu : yes\nfpu_exception : yes\ncpuid level : 13\nwp : yes\nflags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ss ht syscall nx pdpe1gb rdtscp lm constant_tsc arch_perfmon rep_good nopl xtopology cpuid tsc_known_freq pni pclmulqdq vmx ssse3 fma cx16 pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand hypervisor lahf_lm abm 3dnowprefetch cpuid_fault invpcid_single ssbd ibrs ibpb ibrs_enhanced tpr_shadow vnmi flexpriority ept vpid fsgsbase tsc_adjust bmi1 avx2 smep bmi2 erms invpcid mpx avx512f avx512dq rdseed adx smap clflushopt clwb avx512cd avx512bw avx512vl xsaveopt xsavec xgetbv1 xsaves arat pku ospke avx512_vnni md_clear arch_capabilities\nbugs : spectre_v1 spectre_v2 spec_store_bypass swapgs\nbogomips : 4190.16\nclflush size : 64\ncache_alignment : 64\naddress sizes : 40 bits physical, 48 bits virtual\npower management:\n\nprocessor : 31\nvendor_id : GenuineIntel\ncpu family : 6\nmodel : 85\nmodel name : Intel(R) Xeon(R) Gold 5218R CPU @ 2.10GHz\nstepping : 7\nmicrocode : 0x1\ncpu MHz : 2095.082\ncache size : 16384 KB\nphysical id : 15\nsiblings : 2\ncore id : 0\ncpu cores : 1\napicid : 31\ninitial apicid : 31\nfpu : yes\nfpu_exception : yes\ncpuid level : 13\nwp : yes\nflags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ss ht syscall nx pdpe1gb rdtscp lm constant_tsc arch_perfmon rep_good nopl xtopology cpuid tsc_known_freq pni pclmulqdq vmx ssse3 fma cx16 pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand hypervisor lahf_lm abm 3dnowprefetch cpuid_fault invpcid_single ssbd ibrs ibpb ibrs_enhanced tpr_shadow vnmi flexpriority ept vpid fsgsbase tsc_adjust bmi1 avx2 smep bmi2 erms invpcid mpx avx512f avx512dq rdseed adx smap clflushopt clwb avx512cd avx512bw avx512vl xsaveopt xsavec xgetbv1 xsaves arat pku ospke avx512_vnni md_clear arch_capabilities\nbugs : spectre_v1 spectre_v2 spec_store_bypass swapgs\nbogomips : 4190.16\nclflush size : 64\ncache_alignment : 64\naddress sizes : 40 bits physical, 48 bits virtual\npower management:\n"
  },
  {
    "path": "machine/testdata/cpuinfo_rpi4",
    "content": "processor       : 0\nBogoMIPS        : 108.00\nFeatures        : fp asimd evtstrm crc32 cpuid\nCPU implementer : 0x41\nCPU architecture: 8\nCPU variant     : 0x0\nCPU part        : 0xd08\nCPU revision    : 3\n\nprocessor       : 1\nBogoMIPS        : 108.00\nFeatures        : fp asimd evtstrm crc32 cpuid\nCPU implementer : 0x41\nCPU architecture: 8\nCPU variant     : 0x0\nCPU part        : 0xd08\nCPU revision    : 3\n\nprocessor       : 2\nBogoMIPS        : 108.00\nFeatures        : fp asimd evtstrm crc32 cpuid\nCPU implementer : 0x41\nCPU architecture: 8\nCPU variant     : 0x0\nCPU part        : 0xd08\nCPU revision    : 3\n\nprocessor       : 3\nBogoMIPS        : 108.00\nFeatures        : fp asimd evtstrm crc32 cpuid\nCPU implementer : 0x41\nCPU architecture: 8\nCPU variant     : 0x0\nCPU part        : 0xd08\nCPU revision    : 3\n\nHardware        : BCM2835\nRevision        : c03111\nSerial          : 10000000bb9410ef\nModel           : Raspberry Pi 4 Model B Rev 1.1\n"
  },
  {
    "path": "machine/testdata/cpuinfo_upper_case",
    "content": "processor       : 0\ncpu model       : ICT Loongson-3 V0.4  FPU V0.1\nmodel name      : Loongson-3A R4 (Loongson-3B4000)\nCPU MHz         : 1800.00\nBogoMIPS        : 12730.64\nwait instruction    : yes\nmicrosecond timers  : yes\ntlb_entries     : 2112\nextra interrupt vector  : yes\nhardware watchpoint : yes, count: 0, address/irw mask: []\nisa         : mips1 mips2 mips3 mips4 mips5 mips32r1 mips32r2 mips64r1 mips64r2\nASEs implemented    : vz msa\nLoongson Features   : csr lasx lamo cam vz gft lft msi256 extioi csripi\nshadow register sets    : 1\nkscratch registers  : 6\npackage         : 0\ncore            : 0\nVCED exceptions     : not available\nVCEI exceptions     : not available\n\nprocessor       : 1\ncpu model       : ICT Loongson-3 V0.4  FPU V0.1\nmodel name      : Loongson-3A R4 (Loongson-3B4000)\nCPU MHz         : 1800.00\nBogoMIPS        : 12711.24\nwait instruction    : yes\nmicrosecond timers  : yes\ntlb_entries     : 2112\nextra interrupt vector  : yes\nhardware watchpoint : yes, count: 0, address/irw mask: []\nisa         : mips1 mips2 mips3 mips4 mips5 mips32r1 mips32r2 mips64r1 mips64r2\nASEs implemented    : vz msa\nLoongson Features   : csr lasx lamo cam vz gft lft msi256 extioi csripi\nshadow register sets    : 1\nkscratch registers  : 6\npackage         : 0\ncore            : 1\nVCED exceptions     : not available\nVCEI exceptions     : not available\n\nprocessor       : 2\ncpu model       : ICT Loongson-3 V0.4  FPU V0.1\nmodel name      : Loongson-3A R4 (Loongson-3B4000)\nCPU MHz         : 1800.00\nBogoMIPS        : 12730.64\nwait instruction    : yes\nmicrosecond timers  : yes\ntlb_entries     : 2112\nextra interrupt vector  : yes\nhardware watchpoint : yes, count: 0, address/irw mask: []\nisa         : mips1 mips2 mips3 mips4 mips5 mips32r1 mips32r2 mips64r1 mips64r2\nASEs implemented    : vz msa\nLoongson Features   : csr lasx lamo cam vz gft lft msi256 extioi csripi\nshadow register sets    : 1\nkscratch registers  : 6\npackage         : 0\ncore            : 2\nVCED exceptions     : not available\nVCEI exceptions     : not available\n\nprocessor       : 3\ncpu model       : ICT Loongson-3 V0.4  FPU V0.1\nmodel name      : Loongson-3A R4 (Loongson-3B4000)\nCPU MHz         : 1800.00\nBogoMIPS        : 12730.64\nwait instruction    : yes\nmicrosecond timers  : yes\ntlb_entries     : 2112\nextra interrupt vector  : yes\nhardware watchpoint : yes, count: 0, address/irw mask: []\nisa         : mips1 mips2 mips3 mips4 mips5 mips32r1 mips32r2 mips64r1 mips64r2\nASEs implemented    : vz msa\nLoongson Features   : csr lasx lamo cam vz gft lft msi256 extioi csripi\nshadow register sets    : 1\nkscratch registers  : 6\npackage         : 0\ncore            : 3\nVCED exceptions     : not available\nVCEI exceptions     : not available\n\nprocessor       : 4\ncpu model       : ICT Loongson-3 V0.4  FPU V0.1\nmodel name      : Loongson-3A R4 (Loongson-3B4000)\nCPU MHz         : 1800.00\nBogoMIPS        : 12730.64\nwait instruction    : yes\nmicrosecond timers  : yes\ntlb_entries     : 2112\nextra interrupt vector  : yes\nhardware watchpoint : yes, count: 0, address/irw mask: []\nisa         : mips1 mips2 mips3 mips4 mips5 mips32r1 mips32r2 mips64r1 mips64r2\nASEs implemented    : vz msa\nLoongson Features   : csr lasx lamo cam vz gft lft msi256 extioi csripi\nshadow register sets    : 1\nkscratch registers  : 6\npackage         : 1\ncore            : 0\nVCED exceptions     : not available\nVCEI exceptions     : not available\n\nprocessor       : 5\ncpu model       : ICT Loongson-3 V0.4  FPU V0.1\nmodel name      : Loongson-3A R4 (Loongson-3B4000)\nCPU MHz         : 1800.00\nBogoMIPS        : 12730.64\nwait instruction    : yes\nmicrosecond timers  : yes\ntlb_entries     : 2112\nextra interrupt vector  : yes\nhardware watchpoint : yes, count: 0, address/irw mask: []\nisa         : mips1 mips2 mips3 mips4 mips5 mips32r1 mips32r2 mips64r1 mips64r2\nASEs implemented    : vz msa\nLoongson Features   : csr lasx lamo cam vz gft lft msi256 extioi csripi\nshadow register sets    : 1\nkscratch registers  : 6\npackage         : 1\ncore            : 1\nVCED exceptions     : not available\nVCEI exceptions     : not available\n\nprocessor       : 6\ncpu model       : ICT Loongson-3 V0.4  FPU V0.1\nmodel name      : Loongson-3A R4 (Loongson-3B4000)\nCPU MHz         : 1800.00\nBogoMIPS        : 12730.64\nwait instruction    : yes\nmicrosecond timers  : yes\ntlb_entries     : 2112\nextra interrupt vector  : yes\nhardware watchpoint : yes, count: 0, address/irw mask: []\nisa         : mips1 mips2 mips3 mips4 mips5 mips32r1 mips32r2 mips64r1 mips64r2\nASEs implemented    : vz msa\nLoongson Features   : csr lasx lamo cam vz gft lft msi256 extioi csripi\nshadow register sets    : 1\nkscratch registers  : 6\npackage         : 1\ncore            : 2\nVCED exceptions     : not available\nVCEI exceptions     : not available\n\nprocessor       : 7\ncpu model       : ICT Loongson-3 V0.4  FPU V0.1\nmodel name      : Loongson-3A R4 (Loongson-3B4000)\nCPU MHz         : 1800.00\nBogoMIPS        : 12730.64\nwait instruction    : yes\nmicrosecond timers  : yes\ntlb_entries     : 2112\nextra interrupt vector  : yes\nhardware watchpoint : yes, count: 0, address/irw mask: []\nisa         : mips1 mips2 mips3 mips4 mips5 mips32r1 mips32r2 mips64r1 mips64r2\nASEs implemented    : vz msa\nLoongson Features   : csr lasx lamo cam vz gft lft msi256 extioi csripi\nshadow register sets    : 1\nkscratch registers  : 6\npackage         : 1\ncore            : 3\nVCED exceptions     : not available\nVCEI exceptions     : not available\n\n"
  },
  {
    "path": "machine/testdata/edac/mc/mc0/dimm0/dimm_mem_type",
    "content": "Unbuffered-DDR4\n"
  },
  {
    "path": "machine/testdata/edac/mc/mc0/dimm0/size",
    "content": "789\n"
  },
  {
    "path": "machine/testdata/edac/mc/mc0/dimm1/dimm_mem_type",
    "content": "Non-volatile-RAM\n"
  },
  {
    "path": "machine/testdata/edac/mc/mc0/dimm1/size",
    "content": "456\n"
  },
  {
    "path": "machine/testdata/edac/mc/mc0/dimm_is_fake/dimm_mem_type",
    "content": "Unbuffered-DDR4"
  },
  {
    "path": "machine/testdata/edac/mc/mc0/dimm_is_fake/size",
    "content": "321"
  },
  {
    "path": "machine/testdata/edac/mc/mc1/dimm0/dimm_mem_type",
    "content": "Non-volatile-RAM"
  },
  {
    "path": "machine/testdata/edac/mc/mc1/dimm0/size",
    "content": "123"
  },
  {
    "path": "machine/testdata/edac/mc/mc_fake/dimm0/dimm0/dimm_mem_type",
    "content": "Unbuffered-DDR4"
  },
  {
    "path": "machine/testdata/edac/mc/mc_fake/dimm0/dimm0/size",
    "content": "789"
  },
  {
    "path": "machine/testdata/edac/mc/mc_fake/dimm0/dimm1/dimm_mem_type",
    "content": "Non-volatile-RAM"
  },
  {
    "path": "machine/testdata/edac/mc/mc_fake/dimm0/dimm1/size",
    "content": "456"
  },
  {
    "path": "machine/testdata/edac/mc/mc_fake/dimm0/dimm_mem_type",
    "content": "Unbuffered-DDR4"
  },
  {
    "path": "machine/testdata/edac/mc/mc_fake/dimm0/size",
    "content": "789"
  },
  {
    "path": "machine/testdata/edac/mc/mc_fake/dimm1/dimm_mem_type",
    "content": "Non-volatile-RAM"
  },
  {
    "path": "machine/testdata/edac/mc/mc_fake/dimm1/size",
    "content": "456"
  },
  {
    "path": "machine/testdata/sysfs_cpus/cpu0/topology/core_id",
    "content": "0\n"
  },
  {
    "path": "machine/testdata/sysfs_cpus/cpu0/topology/physical_package_id",
    "content": "0\n"
  },
  {
    "path": "machine/testdata/sysfs_cpus/cpu1/.gitkeep",
    "content": ""
  },
  {
    "path": "machine/testdata/wrong_sysfs/cpu0/.gitkeep",
    "content": ""
  },
  {
    "path": "machine/testdata_rpi4/cpu0/hotplug/fail",
    "content": "-1\n"
  },
  {
    "path": "machine/testdata_rpi4/cpu0/hotplug/state",
    "content": "206\n"
  },
  {
    "path": "machine/testdata_rpi4/cpu0/hotplug/target",
    "content": "0\n"
  },
  {
    "path": "machine/testdata_rpi4/cpu0/topology/core_cpus",
    "content": "1\n"
  },
  {
    "path": "machine/testdata_rpi4/cpu0/topology/core_cpus_list",
    "content": "0\n"
  },
  {
    "path": "machine/testdata_rpi4/cpu0/topology/core_id",
    "content": "0\n"
  },
  {
    "path": "machine/testdata_rpi4/cpu0/topology/core_siblings",
    "content": "f\n"
  },
  {
    "path": "machine/testdata_rpi4/cpu0/topology/core_siblings_list",
    "content": "0-3\n"
  },
  {
    "path": "machine/testdata_rpi4/cpu0/topology/die_cpus",
    "content": "1\n"
  },
  {
    "path": "machine/testdata_rpi4/cpu0/topology/die_cpus_list",
    "content": "1\n"
  },
  {
    "path": "machine/testdata_rpi4/cpu0/topology/die_id",
    "content": "-1\n"
  },
  {
    "path": "machine/testdata_rpi4/cpu0/topology/package_cpus",
    "content": "f\n"
  },
  {
    "path": "machine/testdata_rpi4/cpu0/topology/package_cpus_list",
    "content": "0-3\n"
  },
  {
    "path": "machine/testdata_rpi4/cpu0/topology/physical_package_id",
    "content": "0\n"
  },
  {
    "path": "machine/testdata_rpi4/cpu0/topology/thread_siblings",
    "content": "1\n"
  },
  {
    "path": "machine/testdata_rpi4/cpu0/topology/thread_siblings_list",
    "content": "0\n"
  },
  {
    "path": "machine/testdata_rpi4/cpu1/cpu_capacity",
    "content": "1024\n"
  },
  {
    "path": "machine/testdata_rpi4/cpu1/hotplug/fail",
    "content": "-1\n"
  },
  {
    "path": "machine/testdata_rpi4/cpu1/hotplug/state",
    "content": "206\n"
  },
  {
    "path": "machine/testdata_rpi4/cpu1/hotplug/target",
    "content": "0\n"
  },
  {
    "path": "machine/testdata_rpi4/cpu1/topology/core_cpus",
    "content": "2\n"
  },
  {
    "path": "machine/testdata_rpi4/cpu1/topology/core_cpus_list",
    "content": "1\n"
  },
  {
    "path": "machine/testdata_rpi4/cpu1/topology/core_id",
    "content": "1\n"
  },
  {
    "path": "machine/testdata_rpi4/cpu1/topology/core_siblings",
    "content": "f\n"
  },
  {
    "path": "machine/testdata_rpi4/cpu1/topology/core_siblings_list",
    "content": "0-3\n"
  },
  {
    "path": "machine/testdata_rpi4/cpu1/topology/die_cpus",
    "content": "2\n"
  },
  {
    "path": "machine/testdata_rpi4/cpu1/topology/die_cpus_list",
    "content": "1\n"
  },
  {
    "path": "machine/testdata_rpi4/cpu1/topology/die_id",
    "content": "-1\n"
  },
  {
    "path": "machine/testdata_rpi4/cpu1/topology/package_cpus",
    "content": "f\n"
  },
  {
    "path": "machine/testdata_rpi4/cpu1/topology/package_cpus_list",
    "content": "0-3\n"
  },
  {
    "path": "machine/testdata_rpi4/cpu1/topology/physical_package_id",
    "content": "0\n"
  },
  {
    "path": "machine/testdata_rpi4/cpu1/topology/thread_siblings",
    "content": "2\n"
  },
  {
    "path": "machine/testdata_rpi4/cpu1/topology/thread_siblings_list",
    "content": "1\n"
  },
  {
    "path": "machine/testdata_rpi4/cpu1/uevent",
    "content": "OF_NAME=cpu\nOF_FULLNAME=/cpus/cpu@1\nOF_TYPE=cpu\nOF_COMPATIBLE_0=arm,cortex-a72\nOF_COMPATIBLE_N=1\nMODALIAS=cpu:type:aarch64:feature:,0000,0001,0002,0007,000B\n\n"
  },
  {
    "path": "machine/testdata_rpi4/cpu2/hotplug/fail",
    "content": "-1\n"
  },
  {
    "path": "machine/testdata_rpi4/cpu2/hotplug/state",
    "content": "206\n"
  },
  {
    "path": "machine/testdata_rpi4/cpu2/hotplug/target",
    "content": "0\n"
  },
  {
    "path": "machine/testdata_rpi4/cpu2/topology/core_cpus",
    "content": "4\n"
  },
  {
    "path": "machine/testdata_rpi4/cpu2/topology/core_cpus_list",
    "content": "2\n"
  },
  {
    "path": "machine/testdata_rpi4/cpu2/topology/core_id",
    "content": "2\n"
  },
  {
    "path": "machine/testdata_rpi4/cpu2/topology/core_siblings",
    "content": "f\n"
  },
  {
    "path": "machine/testdata_rpi4/cpu2/topology/core_siblings_list",
    "content": "0-3\n"
  },
  {
    "path": "machine/testdata_rpi4/cpu2/topology/die_cpus",
    "content": "4\n"
  },
  {
    "path": "machine/testdata_rpi4/cpu2/topology/die_cpus_list",
    "content": "2\n"
  },
  {
    "path": "machine/testdata_rpi4/cpu2/topology/die_id",
    "content": "-1\n"
  },
  {
    "path": "machine/testdata_rpi4/cpu2/topology/package_cpus",
    "content": "f\n"
  },
  {
    "path": "machine/testdata_rpi4/cpu2/topology/package_cpus_list",
    "content": "0-3\n"
  },
  {
    "path": "machine/testdata_rpi4/cpu2/topology/physical_package_id",
    "content": "0\n"
  },
  {
    "path": "machine/testdata_rpi4/cpu2/topology/thread_siblings",
    "content": "4\n"
  },
  {
    "path": "machine/testdata_rpi4/cpu2/topology/thread_siblings_list",
    "content": "2\n"
  },
  {
    "path": "machine/testdata_rpi4/cpu3/hotplug/fail",
    "content": "-1\n"
  },
  {
    "path": "machine/testdata_rpi4/cpu3/hotplug/state",
    "content": "206\n"
  },
  {
    "path": "machine/testdata_rpi4/cpu3/hotplug/target",
    "content": "0\n"
  },
  {
    "path": "machine/testdata_rpi4/cpu3/topology/core_cpus",
    "content": "8\n"
  },
  {
    "path": "machine/testdata_rpi4/cpu3/topology/core_cpus_list",
    "content": "3\n"
  },
  {
    "path": "machine/testdata_rpi4/cpu3/topology/core_id",
    "content": "3\n"
  },
  {
    "path": "machine/testdata_rpi4/cpu3/topology/core_siblings",
    "content": "f\n"
  },
  {
    "path": "machine/testdata_rpi4/cpu3/topology/core_siblings_list",
    "content": "0-3\n"
  },
  {
    "path": "machine/testdata_rpi4/cpu3/topology/die_cpus",
    "content": "8\n"
  },
  {
    "path": "machine/testdata_rpi4/cpu3/topology/die_cpus_list",
    "content": "3\n"
  },
  {
    "path": "machine/testdata_rpi4/cpu3/topology/die_id",
    "content": "-1\n"
  },
  {
    "path": "machine/testdata_rpi4/cpu3/topology/package_cpus",
    "content": "f\n"
  },
  {
    "path": "machine/testdata_rpi4/cpu3/topology/package_cpus_list",
    "content": "0-3\n"
  },
  {
    "path": "machine/testdata_rpi4/cpu3/topology/physical_package_id",
    "content": "0\n"
  },
  {
    "path": "machine/testdata_rpi4/cpu3/topology/thread_siblings",
    "content": "8\n"
  },
  {
    "path": "machine/testdata_rpi4/cpu3/topology/thread_siblings_list",
    "content": "3\n"
  },
  {
    "path": "machine/testdata_rpi4/hotplug/states",
    "content": " 24: fs/buffer:dead                                                                                                   [0/1911]\n 25: printk:dead\n 26: mm/memctrl:dead\n 27: lib/percpu_cnt:dead\n 28: lib/radix:dead\n 29: mm/page_alloc:dead\n 30: net/dev:dead\n 35: padata:dead\n 36: workqueue:prepare\n 38: hrtimers:prepare\n 41: smpcfd:prepare\n 42: relay:prepare\n 43: slab:prepare\n 44: md/raid5:prepare\n 45: RCU/tree:prepare\n 54: base/topology:prepare\n 57: trace/RB:preapre\n 58: mm/zsmalloc:prepare\n 59: mm/zswap:prepare\n 60: mm/zswap_pool:prepare\n 63: timers:prepare\n 65: fork:vm_stack_cache\n 86: cpu:bringup\n 87: idle:dead\n 88: ap:offline\n 89: sched:starting\n 90: RCU/tree:dying\n 91: irqchip/arm/gic:starting\n107: arm64/debug_monitors:starting\n108: perf/arm64/hw_breakpoint:starting\n110: perf/arm/pmu:starting\n113: clockevents/arm/arch_timer:starting\n125: kvm/cpu:starting\n126: kvm/arm/vgic:starting\n128: kvm/arm/timer:starting\n129: clockevents/dummy_timer:starting\n132: arm64/isndep:starting\n133: smpcfd:dying\n136: ap:online\n137: cpu:teardown\n139: smpboot/threads:online\n141: irq/affinity:online\n144: perf:online\n155: perf/arm/ccn:online\n168: lockup_detector:online\n169: workqueue:online\n170: RCU/tree:online\n172: mm/writeback:online\n173: mm/vmstat:online\n174: mm/compaction:online\n175: arm64/cpuinfo:online\n176: padata:online\n177: mm/vmscan:online\n178: lib/percpu_cnt:online\n179: cpufreq:online\n180: leds/trigger:starting\n181: printk:online\n205: sched:active\n206: online\n"
  },
  {
    "path": "machine/topology_test.go",
    "content": "// Copyright 2014 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n//go:build linux\n\npackage machine\n\nimport (\n\t\"encoding/json\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"reflect\"\n\t\"runtime\"\n\t\"sort\"\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/assert\"\n\n\tinfo \"github.com/google/cadvisor/info/v1\"\n\t\"github.com/google/cadvisor/utils/sysfs\"\n\t\"github.com/google/cadvisor/utils/sysfs/fakesysfs\"\n)\n\nfunc TestPhysicalCores(t *testing.T) {\n\ttestfile := \"./testdata/cpuinfo\"\n\n\ttestcpuinfo, err := os.ReadFile(testfile)\n\tassert.Nil(t, err)\n\tassert.NotNil(t, testcpuinfo)\n\n\tnumPhysicalCores := GetPhysicalCores(testcpuinfo)\n\tassert.Equal(t, 6, numPhysicalCores)\n}\n\nfunc TestPhysicalCoresReadingFromCpuBus(t *testing.T) {\n\torigCPUAttributesPath := cpuAttributesPath\n\tdefer func() {\n\t\tcpuAttributesPath = origCPUAttributesPath\n\t}()\n\tcpuAttributesPath = \"./testdata/sysfs_cpus/\" // overwriting package variable to mock sysfs\n\ttestfile := \"./testdata/cpuinfo_arm\"         // mock cpuinfo without core id\n\n\ttestcpuinfo, err := os.ReadFile(testfile)\n\tassert.Nil(t, err)\n\tassert.NotNil(t, testcpuinfo)\n\n\tnumPhysicalCores := GetPhysicalCores(testcpuinfo)\n\tassert.Equal(t, 1, numPhysicalCores)\n}\n\nfunc TestPhysicalCoresFromWrongSysFs(t *testing.T) {\n\torigCPUAttributesPath := cpuAttributesPath\n\tdefer func() {\n\t\tcpuAttributesPath = origCPUAttributesPath\n\t}()\n\tcpuAttributesPath = \"./testdata/wrongsysfs\" // overwriting package variable to mock sysfs\n\ttestfile := \"./testdata/cpuinfo_arm\"        // mock cpuinfo without core id\n\n\ttestcpuinfo, err := os.ReadFile(testfile)\n\tassert.Nil(t, err)\n\tassert.NotNil(t, testcpuinfo)\n\n\tnumPhysicalCores := GetPhysicalCores(testcpuinfo)\n\tassert.Equal(t, 0, numPhysicalCores)\n}\n\nfunc TestSockets(t *testing.T) {\n\ttestfile := \"./testdata/cpuinfo\"\n\n\ttestcpuinfo, err := os.ReadFile(testfile)\n\tassert.Nil(t, err)\n\tassert.NotNil(t, testcpuinfo)\n\n\tnumSockets := GetSockets(testcpuinfo)\n\tassert.Equal(t, 2, numSockets)\n}\n\nfunc TestSocketsReadingFromCpuBus(t *testing.T) {\n\torigCPUAttributesPath := cpuAttributesPath\n\tdefer func() {\n\t\tcpuAttributesPath = origCPUAttributesPath\n\t}()\n\tcpuAttributesPath = \"./testdata/wrongsysfs\" // overwriting package variable to mock sysfs\n\ttestfile := \"./testdata/cpuinfo_arm\"        // mock cpuinfo without physical id\n\n\ttestcpuinfo, err := os.ReadFile(testfile)\n\tassert.Nil(t, err)\n\tassert.NotNil(t, testcpuinfo)\n\n\tnumSockets := GetSockets(testcpuinfo)\n\tassert.Equal(t, 0, numSockets)\n}\n\nfunc TestSocketsReadingFromWrongSysFs(t *testing.T) {\n\tpath, err := filepath.Abs(\"./testdata/sysfs_cpus/\")\n\tassert.NoError(t, err)\n\n\torigCPUAttributesPath := cpuAttributesPath\n\tdefer func() {\n\t\tcpuAttributesPath = origCPUAttributesPath\n\t}()\n\tcpuAttributesPath = path             // overwriting package variable to mock sysfs\n\ttestfile := \"./testdata/cpuinfo_arm\" // mock cpuinfo without physical id\n\n\ttestcpuinfo, err := os.ReadFile(testfile)\n\tassert.Nil(t, err)\n\tassert.NotNil(t, testcpuinfo)\n\n\tnumSockets := GetSockets(testcpuinfo)\n\tassert.Equal(t, 1, numSockets)\n}\n\nfunc TestTopology(t *testing.T) {\n\tmachineArch = \"\" // overwrite package variable\n\tsysFs := &fakesysfs.FakeSysFs{}\n\tc := sysfs.CacheInfo{\n\t\tSize:  32 * 1024,\n\t\tType:  \"unified\",\n\t\tLevel: 1,\n\t\tCpus:  2,\n\t}\n\tsysFs.SetCacheInfo(c)\n\n\tnodesPaths := []string{\n\t\t\"/fakeSysfs/devices/system/node/node0\",\n\t\t\"/fakeSysfs/devices/system/node/node1\",\n\t}\n\tsysFs.SetNodesPaths(nodesPaths, nil)\n\n\tcpusPaths := map[string][]string{\n\t\t\"/fakeSysfs/devices/system/node/node0\": {\n\t\t\t\"/fakeSysfs/devices/system/node/node0/cpu0\",\n\t\t\t\"/fakeSysfs/devices/system/node/node0/cpu1\",\n\t\t\t\"/fakeSysfs/devices/system/node/node0/cpu2\",\n\t\t\t\"/fakeSysfs/devices/system/node/node0/cpu6\",\n\t\t\t\"/fakeSysfs/devices/system/node/node0/cpu7\",\n\t\t\t\"/fakeSysfs/devices/system/node/node0/cpu8\",\n\t\t},\n\t\t\"/fakeSysfs/devices/system/node/node1\": {\n\t\t\t\"/fakeSysfs/devices/system/node/node0/cpu3\",\n\t\t\t\"/fakeSysfs/devices/system/node/node0/cpu4\",\n\t\t\t\"/fakeSysfs/devices/system/node/node0/cpu5\",\n\t\t\t\"/fakeSysfs/devices/system/node/node0/cpu9\",\n\t\t\t\"/fakeSysfs/devices/system/node/node0/cpu10\",\n\t\t\t\"/fakeSysfs/devices/system/node/node0/cpu11\",\n\t\t},\n\t}\n\tsysFs.SetCPUsPaths(cpusPaths, nil)\n\n\tcoreThread := map[string]string{\n\t\t\"/fakeSysfs/devices/system/node/node0/cpu0\":  \"0\",\n\t\t\"/fakeSysfs/devices/system/node/node0/cpu1\":  \"1\",\n\t\t\"/fakeSysfs/devices/system/node/node0/cpu2\":  \"2\",\n\t\t\"/fakeSysfs/devices/system/node/node0/cpu3\":  \"3\",\n\t\t\"/fakeSysfs/devices/system/node/node0/cpu4\":  \"4\",\n\t\t\"/fakeSysfs/devices/system/node/node0/cpu5\":  \"5\",\n\t\t\"/fakeSysfs/devices/system/node/node0/cpu6\":  \"0\",\n\t\t\"/fakeSysfs/devices/system/node/node0/cpu7\":  \"1\",\n\t\t\"/fakeSysfs/devices/system/node/node0/cpu8\":  \"2\",\n\t\t\"/fakeSysfs/devices/system/node/node0/cpu9\":  \"3\",\n\t\t\"/fakeSysfs/devices/system/node/node0/cpu10\": \"4\",\n\t\t\"/fakeSysfs/devices/system/node/node0/cpu11\": \"5\",\n\t}\n\tsysFs.SetCoreThreads(coreThread, nil)\n\n\tmemTotal := \"MemTotal:       32817192 kB\"\n\tsysFs.SetMemory(memTotal, nil)\n\n\thugePages := []os.FileInfo{\n\t\t&fakesysfs.FileInfo{EntryName: \"hugepages-2048kB\"},\n\t\t&fakesysfs.FileInfo{EntryName: \"hugepages-1048576kB\"},\n\t}\n\tsysFs.SetHugePages(hugePages, nil)\n\n\thugePageNr := map[string]string{\n\t\t\"/fakeSysfs/devices/system/node/node0/hugepages/hugepages-2048kB/nr_hugepages\":    \"1\",\n\t\t\"/fakeSysfs/devices/system/node/node0/hugepages/hugepages-1048576kB/nr_hugepages\": \"1\",\n\t\t\"/fakeSysfs/devices/system/node/node1/hugepages/hugepages-2048kB/nr_hugepages\":    \"1\",\n\t\t\"/fakeSysfs/devices/system/node/node1/hugepages/hugepages-1048576kB/nr_hugepages\": \"1\",\n\t}\n\tsysFs.SetHugePagesNr(hugePageNr, nil)\n\n\tphysicalPackageIDs := map[string]string{\n\t\t\"/fakeSysfs/devices/system/node/node0/cpu0\":  \"0\",\n\t\t\"/fakeSysfs/devices/system/node/node0/cpu1\":  \"0\",\n\t\t\"/fakeSysfs/devices/system/node/node0/cpu2\":  \"0\",\n\t\t\"/fakeSysfs/devices/system/node/node0/cpu3\":  \"0\",\n\t\t\"/fakeSysfs/devices/system/node/node0/cpu4\":  \"0\",\n\t\t\"/fakeSysfs/devices/system/node/node0/cpu5\":  \"0\",\n\t\t\"/fakeSysfs/devices/system/node/node0/cpu6\":  \"1\",\n\t\t\"/fakeSysfs/devices/system/node/node0/cpu7\":  \"1\",\n\t\t\"/fakeSysfs/devices/system/node/node0/cpu8\":  \"1\",\n\t\t\"/fakeSysfs/devices/system/node/node0/cpu9\":  \"1\",\n\t\t\"/fakeSysfs/devices/system/node/node0/cpu10\": \"1\",\n\t\t\"/fakeSysfs/devices/system/node/node0/cpu11\": \"1\",\n\t}\n\tsysFs.SetPhysicalPackageIDs(physicalPackageIDs, nil)\n\n\tsysFs.SetDistances(\"/fakeSysfs/devices/system/node/node0\", \"10 11\", nil)\n\tsysFs.SetDistances(\"/fakeSysfs/devices/system/node/node1\", \"11 10\", nil)\n\n\ttopology, numCores, err := GetTopology(sysFs)\n\tassert.Nil(t, err)\n\tassert.Equal(t, 12, numCores)\n\n\texpectedTopology := []info.Node{}\n\tnumNodes := 2\n\tnumCoresPerNode := 3\n\tnumThreads := 2\n\tcache := info.Cache{\n\t\tSize:  32 * 1024,\n\t\tType:  \"unified\",\n\t\tLevel: 1,\n\t}\n\tdistances := [][]uint64{\n\t\t{10, 11},\n\t\t{11, 10},\n\t}\n\tfor i := 0; i < numNodes; i++ {\n\t\tnode := info.Node{Id: i}\n\t\t// Copy over Memory from result. TODO(rjnagal): Use memory from fake.\n\t\tnode.Memory = topology[i].Memory\n\t\t// Copy over HugePagesInfo from result. TODO(ohsewon): Use HugePagesInfo from fake.\n\t\tnode.HugePages = topology[i].HugePages\n\t\tnode.Distances = distances[i]\n\t\tfor j := 0; j < numCoresPerNode; j++ {\n\t\t\tcore := info.Core{Id: i*numCoresPerNode + j}\n\t\t\tcore.Caches = append(core.Caches, cache)\n\t\t\tfor k := 0; k < numThreads; k++ {\n\t\t\t\tcore.Threads = append(core.Threads, k*numCoresPerNode*numNodes+core.Id)\n\t\t\t}\n\t\t\tnode.Cores = append(node.Cores, core)\n\t\t}\n\t\texpectedTopology = append(expectedTopology, node)\n\t}\n\n\tassert.NotNil(t, reflect.DeepEqual(topology, expectedTopology))\n}\n\nfunc TestTopologyEmptySysFs(t *testing.T) {\n\tmachineArch = \"\" // overwrite package variable\n\t_, _, err := GetTopology(&fakesysfs.FakeSysFs{})\n\tassert.NotNil(t, err)\n}\n\nfunc TestTopologyWithoutNodes(t *testing.T) {\n\tmachineArch = \"\" // overwrite package variable\n\tsysFs := &fakesysfs.FakeSysFs{}\n\n\tc := sysfs.CacheInfo{\n\t\tId:    0,\n\t\tSize:  32 * 1024,\n\t\tType:  \"unified\",\n\t\tLevel: 0,\n\t\tCpus:  2,\n\t}\n\tsysFs.SetCacheInfo(c)\n\n\tnodesPaths := []string{}\n\tsysFs.SetNodesPaths(nodesPaths, nil)\n\n\tcpusPaths := map[string][]string{\n\t\t\"/sys/devices/system/cpu\": {\n\t\t\t\"/sys/devices/system/cpu/cpu0\",\n\t\t\t\"/sys/devices/system/cpu/cpu1\",\n\t\t\t\"/sys/devices/system/cpu/cpu2\",\n\t\t\t\"/sys/devices/system/cpu/cpu3\",\n\t\t},\n\t}\n\tsysFs.SetCPUsPaths(cpusPaths, nil)\n\n\tcoreThread := map[string]string{\n\t\t\"/sys/devices/system/cpu/cpu0\": \"0\",\n\t\t\"/sys/devices/system/cpu/cpu1\": \"1\",\n\t\t\"/sys/devices/system/cpu/cpu2\": \"0\",\n\t\t\"/sys/devices/system/cpu/cpu3\": \"1\",\n\t}\n\tsysFs.SetCoreThreads(coreThread, nil)\n\n\tphysicalPackageIDs := map[string]string{\n\t\t\"/sys/devices/system/cpu/cpu0\": \"0\",\n\t\t\"/sys/devices/system/cpu/cpu1\": \"1\",\n\t\t\"/sys/devices/system/cpu/cpu2\": \"0\",\n\t\t\"/sys/devices/system/cpu/cpu3\": \"1\",\n\t}\n\tsysFs.SetPhysicalPackageIDs(physicalPackageIDs, nil)\n\n\ttopology, numCores, err := GetTopology(sysFs)\n\tsort.SliceStable(topology, func(i, j int) bool {\n\t\treturn topology[i].Id < topology[j].Id\n\t})\n\tassert.Nil(t, err)\n\tassert.Equal(t, 2, len(topology))\n\tassert.Equal(t, 4, numCores)\n\n\ttopologyJSON1, err := json.Marshal(topology[0])\n\tassert.Nil(t, err)\n\ttopologyJSON2, err := json.Marshal(topology[1])\n\tassert.Nil(t, err)\n\n\texpectedTopology1 := `{\"node_id\":0,\"memory\":0,\"hugepages\":null,\"distances\":null,\"cores\":[{\"core_id\":0,\"thread_ids\":[0,2],\"caches\":[{\"id\":0, \"size\":32768,\"type\":\"unified\",\"level\":0}], \"socket_id\": 0, \"uncore_caches\":null}],\"caches\":null}`\n\texpectedTopology2 := `\n\t\t{\n\t\t\t\"node_id\":1,\n\t\t\t\"memory\":0,\n\t\t\t\"hugepages\":null,\n            \"distances\": null,\n\t\t\t\"cores\":[\n\t\t\t\t{\n\t\t\t\t\t\"core_id\":1,\n\t\t\t\t\t\"thread_ids\":[\n\t\t\t\t\t1,\n\t\t\t\t\t3\n\t\t\t\t\t],\n\t\t\t\t\t\"caches\":[\n\t\t\t\t\t{\n\t\t\t\t\t\t\"id\": 0,\n\t\t\t\t\t\t\"size\":32768,\n\t\t\t\t\t\t\"type\":\"unified\",\n\t\t\t\t\t\t\"level\":0\n\t\t\t\t\t}\n\t\t\t\t\t],\n\t\t\t\t\t\"socket_id\": 1,\n\t\t\t\t\t\"uncore_caches\": null\n\t\t\t\t}\n\t\t\t],\n\t\t\t\"caches\":null\n\t\t}`\n\n\tjson1 := string(topologyJSON1)\n\tjson2 := string(topologyJSON2)\n\n\tassert.JSONEq(t, expectedTopology1, json1)\n\tassert.JSONEq(t, expectedTopology2, json2)\n}\n\nfunc TestTopologyWithNodesWithoutCPU(t *testing.T) {\n\tmachineArch = \"\" // overwrite package variable\n\tsysFs := &fakesysfs.FakeSysFs{}\n\tnodesPaths := []string{\n\t\t\"/fakeSysfs/devices/system/node/node0\",\n\t\t\"/fakeSysfs/devices/system/node/node1\",\n\t}\n\tsysFs.SetNodesPaths(nodesPaths, nil)\n\n\tmemTotal := \"MemTotal:       32817192 kB\"\n\tsysFs.SetMemory(memTotal, nil)\n\n\thugePages := []os.FileInfo{\n\t\t&fakesysfs.FileInfo{EntryName: \"hugepages-2048kB\"},\n\t\t&fakesysfs.FileInfo{EntryName: \"hugepages-1048576kB\"},\n\t}\n\tsysFs.SetHugePages(hugePages, nil)\n\n\thugePageNr := map[string]string{\n\t\t\"/fakeSysfs/devices/system/node/node0/hugepages/hugepages-2048kB/nr_hugepages\":    \"1\",\n\t\t\"/fakeSysfs/devices/system/node/node0/hugepages/hugepages-1048576kB/nr_hugepages\": \"1\",\n\t\t\"/fakeSysfs/devices/system/node/node1/hugepages/hugepages-2048kB/nr_hugepages\":    \"1\",\n\t\t\"/fakeSysfs/devices/system/node/node1/hugepages/hugepages-1048576kB/nr_hugepages\": \"1\",\n\t}\n\tsysFs.SetHugePagesNr(hugePageNr, nil)\n\n\tsysFs.SetDistances(\"/fakeSysfs/devices/system/node/node0\", \"10 11\", nil)\n\tsysFs.SetDistances(\"/fakeSysfs/devices/system/node/node1\", \"11 10\", nil)\n\n\ttopology, numCores, err := GetTopology(sysFs)\n\n\tassert.Nil(t, err)\n\tassert.Equal(t, 0, numCores)\n\n\ttopologyJSON, err := json.Marshal(topology)\n\tassert.Nil(t, err)\n\n\texpectedTopology := `[\n     {\n      \"caches\": null,\n      \"cores\": null,\n      \"hugepages\": [\n       {\n        \"num_pages\": 1,\n        \"page_size\": 2048\n       },\n       {\n        \"num_pages\": 1,\n        \"page_size\": 1048576\n       }\n      ],\n      \"distances\": [\n        10,\n        11\n      ],\n      \"memory\": 33604804608,\n      \"node_id\": 0\n     },\n     {\n      \"caches\": null,\n      \"cores\": null,\n      \"hugepages\": [\n       {\n        \"num_pages\": 1,\n        \"page_size\": 2048\n       },\n       {\n        \"num_pages\": 1,\n        \"page_size\": 1048576\n       }\n      ],\n      \"distances\": [\n        11,\n        10\n      ],\n      \"memory\": 33604804608,\n      \"node_id\": 1\n     }\n    ]\n    `\n\tassert.JSONEq(t, expectedTopology, string(topologyJSON))\n}\n\nfunc TestTopologyOnSystemZ(t *testing.T) {\n\tif runtime.GOARCH != \"s390x\" {\n\t\tt.Skip(\"skipping TestTopologyOnSystemZ due to wrong architecture\")\n\t} else {\n\t\tmachineArch = \"s390\" // overwrite package variable\n\t\tsysFs := &fakesysfs.FakeSysFs{}\n\n\t\tc := sysfs.CacheInfo{\n\t\t\tId:    0,\n\t\t\tSize:  128 * 1024,\n\t\t\tType:  \"Data\",\n\t\t\tLevel: 0,\n\t\t\tCpus:  2,\n\t\t}\n\t\tsysFs.SetCacheInfo(c)\n\n\t\tnodesPaths := []string{}\n\t\tsysFs.SetNodesPaths(nodesPaths, nil)\n\n\t\tcpusPaths := map[string][]string{\n\t\t\t\"/sys/devices/system/cpu\": {\n\t\t\t\t\"/sys/devices/system/cpu/cpu0\",\n\t\t\t\t\"/sys/devices/system/cpu/cpu1\",\n\t\t\t\t\"/sys/devices/system/cpu/cpu2\",\n\t\t\t\t\"/sys/devices/system/cpu/cpu3\",\n\t\t\t},\n\t\t}\n\t\tsysFs.SetCPUsPaths(cpusPaths, nil)\n\n\t\tcoreThread := map[string]string{\n\t\t\t\"/sys/devices/system/cpu/cpu0\": \"0\",\n\t\t\t\"/sys/devices/system/cpu/cpu1\": \"1\",\n\t\t\t\"/sys/devices/system/cpu/cpu2\": \"0\",\n\t\t\t\"/sys/devices/system/cpu/cpu3\": \"1\",\n\t\t}\n\t\tsysFs.SetCoreThreads(coreThread, nil)\n\n\t\tphysicalPackageIDs := map[string]string{\n\t\t\t\"/sys/devices/system/cpu/cpu0\": \"0\",\n\t\t\t\"/sys/devices/system/cpu/cpu1\": \"1\",\n\t\t\t\"/sys/devices/system/cpu/cpu2\": \"0\",\n\t\t\t\"/sys/devices/system/cpu/cpu3\": \"1\",\n\t\t}\n\t\tsysFs.SetPhysicalPackageIDs(physicalPackageIDs, nil)\n\n\t\tbookIDs := map[string]string{\n\t\t\t\"/sys/devices/system/cpu/cpu0\": \"1\",\n\t\t\t\"/sys/devices/system/cpu/cpu1\": \"1\",\n\t\t\t\"/sys/devices/system/cpu/cpu2\": \"1\",\n\t\t\t\"/sys/devices/system/cpu/cpu3\": \"1\",\n\t\t}\n\t\tsysFs.SetBookIDs(bookIDs, nil)\n\n\t\tdrawerIDs := map[string]string{\n\t\t\t\"/sys/devices/system/cpu/cpu0\": \"0\",\n\t\t\t\"/sys/devices/system/cpu/cpu1\": \"0\",\n\t\t\t\"/sys/devices/system/cpu/cpu2\": \"0\",\n\t\t\t\"/sys/devices/system/cpu/cpu3\": \"0\",\n\t\t}\n\t\tsysFs.SetDrawerIDs(drawerIDs, nil)\n\n\t\ttopology, numCores, err := GetTopology(sysFs)\n\t\tassert.Nil(t, err)\n\t\tassert.Equal(t, 2, len(topology))\n\t\tassert.Equal(t, 4, numCores)\n\n\t\ttopologyJSON1, err := json.Marshal(topology[0])\n\t\tassert.Nil(t, err)\n\t\ttopologyJSON2, err := json.Marshal(topology[1])\n\t\tassert.Nil(t, err)\n\n\t\texpectedTopology1 := `{\"node_id\":0,\"memory\":0,\"hugepages\":null,\"distances\":null,\"cores\":[{\"core_id\":0,\"thread_ids\":[0,2],\"caches\":[{\"id\":0, \"size\":131072,\"type\":\"Data\",\"level\":0}], \"socket_id\": 0, \"book_id\":\"1\", \"drawer_id\":\"0\", \"uncore_caches\":null}],\"caches\":null}`\n\t\texpectedTopology2 := `\n\t\t{\n\t\t\t\"node_id\":1,\n\t\t\t\"memory\":0,\n\t\t\t\"hugepages\":null,\n            \"distances\": null,\n\t\t\t\"cores\":[\n\t\t\t\t{\n\t\t\t\t\t\"core_id\":1,\n\t\t\t\t\t\"thread_ids\":[\n\t\t\t\t\t1,\n\t\t\t\t\t3\n\t\t\t\t\t],\n\t\t\t\t\t\"caches\":[\n\t\t\t\t\t{\n\t\t\t\t\t\t\"id\": 0,\n\t\t\t\t\t\t\"size\":131072,\n\t\t\t\t\t\t\"type\":\"Data\",\n\t\t\t\t\t\t\"level\":0\n\t\t\t\t\t}\n\t\t\t\t\t],\n\t\t\t\t\t\"socket_id\": 1,\n\t\t\t\t\t\"book_id\": \"1\",\n\t\t\t\t\t\"drawer_id\": \"0\",\n\t\t\t\t\t\"uncore_caches\": null\n\t\t\t\t}\n\t\t\t],\n\t\t\t\"caches\":null\n\t\t}`\n\n\t\tjson1 := string(topologyJSON1)\n\t\tjson2 := string(topologyJSON2)\n\n\t\tassert.JSONEq(t, expectedTopology1, json1)\n\t\tassert.JSONEq(t, expectedTopology2, json2)\n\t}\n}\n\nfunc TestMemoryInfo(t *testing.T) {\n\ttestPath := \"./testdata/edac/mc\"\n\tmemory, err := GetMachineMemoryByType(testPath)\n\n\tassert.Nil(t, err)\n\tassert.Len(t, memory, 2)\n\tassert.Equal(t, uint64(789*1024*1024), memory[\"Unbuffered-DDR4\"].Capacity)\n\tassert.Equal(t, uint64(579*1024*1024), memory[\"Non-volatile-RAM\"].Capacity)\n\tassert.Equal(t, uint(1), memory[\"Unbuffered-DDR4\"].DimmCount)\n\tassert.Equal(t, uint(2), memory[\"Non-volatile-RAM\"].DimmCount)\n}\n\nfunc TestMemoryInfoOnArchThatDoNotExposeMemoryController(t *testing.T) {\n\ttestPath := \"./there/is/no/spoon\"\n\tmemory, err := GetMachineMemoryByType(testPath)\n\n\tassert.Nil(t, err)\n\tassert.Len(t, memory, 0)\n}\n\nfunc TestClockSpeedOnCpuUpperCase(t *testing.T) {\n\tmaxFreqFile = \"\"                            // do not read the system max frequency\n\tmachineArch = \"\"                            // overwrite package variable\n\ttestfile := \"./testdata/cpuinfo_upper_case\" // mock cpuinfo with CPU MHz\n\n\ttestcpuinfo, err := os.ReadFile(testfile)\n\tassert.Nil(t, err)\n\tassert.NotNil(t, testcpuinfo)\n\n\tclockSpeed, err := GetClockSpeed(testcpuinfo)\n\tassert.Nil(t, err)\n\tassert.NotNil(t, clockSpeed)\n\tassert.Equal(t, uint64(1800*1000), clockSpeed)\n}\n\nfunc TestClockSpeedOnCpuLowerCase(t *testing.T) {\n\tmaxFreqFile = \"\"                            // do not read the system max frequency\n\tmachineArch = \"\"                            // overwrite package variable\n\ttestfile := \"./testdata/cpuinfo_lower_case\" // mock cpuinfo with cpu MHz\n\n\ttestcpuinfo, err := os.ReadFile(testfile)\n\tassert.Nil(t, err)\n\tassert.NotNil(t, testcpuinfo)\n\n\tclockSpeed, err := GetClockSpeed(testcpuinfo)\n\tassert.Nil(t, err)\n\tassert.NotNil(t, clockSpeed)\n\tassert.Equal(t, uint64(1450*1000), clockSpeed)\n}\n\nfunc TestGetCPUVendorID(t *testing.T) {\n\tvar testCases = []struct {\n\t\tfile     string\n\t\texpected string\n\t}{\n\t\t{\n\t\t\t\"./testdata/cpuinfo_onesocket_many_NUMAs\",\n\t\t\t\"GenuineIntel\",\n\t\t},\n\t\t{\n\t\t\t\"./testdata/cpuinfo_arm\",\n\t\t\t\"\",\n\t\t},\n\t}\n\n\tfor _, test := range testCases {\n\t\ttestcpuinfo, err := os.ReadFile(test.file)\n\t\tassert.Nil(t, err)\n\t\tassert.NotNil(t, testcpuinfo)\n\t\tcpuVendorID := GetCPUVendorID(testcpuinfo)\n\t\tassert.Equal(t, test.expected, cpuVendorID)\n\t}\n}\n"
  },
  {
    "path": "manager/container.go",
    "content": "// Copyright 2014 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n//go:build linux\n\npackage manager\n\nimport (\n\t\"flag\"\n\t\"fmt\"\n\t\"math\"\n\t\"math/rand\"\n\t\"os\"\n\t\"os/exec\"\n\t\"path\"\n\t\"regexp\"\n\t\"sort\"\n\t\"strconv\"\n\t\"strings\"\n\t\"sync\"\n\t\"sync/atomic\"\n\t\"time\"\n\n\t\"github.com/google/cadvisor/cache/memory\"\n\t\"github.com/google/cadvisor/collector\"\n\t\"github.com/google/cadvisor/container\"\n\tinfo \"github.com/google/cadvisor/info/v1\"\n\tv2 \"github.com/google/cadvisor/info/v2\"\n\t\"github.com/google/cadvisor/stats\"\n\t\"github.com/google/cadvisor/summary\"\n\t\"github.com/google/cadvisor/utils/cpuload\"\n\n\t\"github.com/docker/go-units\"\n\n\t\"k8s.io/klog/v2\"\n\t\"k8s.io/utils/clock\"\n)\n\n// Housekeeping interval.\nvar enableLoadReader = flag.Bool(\"enable_load_reader\", false, \"Whether to enable cpu load reader\")\nvar HousekeepingInterval = flag.Duration(\"housekeeping_interval\", 1*time.Second, \"Interval between container housekeepings\")\n\n// TODO: replace regular expressions with something simpler, such as strings.Split().\n// cgroup type chosen to fetch the cgroup path of a process.\n// Memory has been chosen, as it is one of the default cgroups that is enabled for most containers...\nvar cgroupMemoryPathRegExp = regexp.MustCompile(`memory[^:]*:(.*?)[,;$]`)\n\n// ... but there are systems (e.g. Raspberry Pi 4) where memory cgroup controller is disabled by default.\n// We should check cpu cgroup then.\nvar cgroupCPUPathRegExp = regexp.MustCompile(`cpu[^:]*:(.*?)[,;$]`)\n\ntype containerInfo struct {\n\tinfo.ContainerReference\n\tSubcontainers []info.ContainerReference\n\tSpec          info.ContainerSpec\n}\n\n// atomicTime is a lock-free wrapper for storing and retrieving time values.\n// It stores time as Unix nanoseconds in an atomic.Int64, enabling concurrent\n// reads and writes without mutex contention.\ntype atomicTime struct {\n\tatomic.Int64\n}\n\n// Time returns the stored time value as a time.Time.\nfunc (t *atomicTime) Time() time.Time {\n\treturn time.Unix(0, t.Load())\n}\n\ntype containerData struct {\n\toomEvents                uint64\n\thandler                  container.ContainerHandler\n\tinfo                     containerInfo\n\tmemoryCache              *memory.InMemoryCache\n\tlock                     sync.Mutex\n\tloadReader               cpuload.CpuLoadReader\n\tsummaryReader            *summary.StatsSummary\n\tloadAvg                  float64 // smoothed load average seen so far.\n\tloadDAvg                 float64 // smoothed load.d average seen so far.\n\thousekeepingInterval     time.Duration\n\tmaxHousekeepingInterval  time.Duration\n\tallowDynamicHousekeeping bool\n\tinfoLastUpdatedTime      atomicTime // Unix nano\n\tstatsLastUpdatedTime     atomicTime // Unix nano\n\tlastErrorTime            time.Time\n\t//  used to track time\n\tclock clock.Clock\n\n\t// Decay value used for load average smoothing. Interval length of 10 seconds is used.\n\tloadDecay float64\n\n\t// Whether to log the usage of this container when it is updated.\n\tlogUsage bool\n\n\t// Tells the container to stop.\n\tstop     chan struct{}\n\tstopOnce sync.Once\n\n\t// Tells the container to immediately collect stats\n\tonDemandChan chan chan struct{}\n\n\t// Runs custom metric collectors.\n\tcollectorManager collector.CollectorManager\n\n\t// perfCollector updates stats for perf_event cgroup controller.\n\tperfCollector stats.Collector\n\n\t// resctrlCollector updates stats for resctrl controller.\n\tresctrlCollector stats.Collector\n}\n\n// jitter returns a time.Duration between duration and duration + maxFactor * duration,\n// to allow clients to avoid converging on periodic behavior.  If maxFactor is 0.0, a\n// suggested default value will be chosen.\nfunc jitter(duration time.Duration, maxFactor float64) time.Duration {\n\tif maxFactor <= 0.0 {\n\t\tmaxFactor = 1.0\n\t}\n\twait := duration + time.Duration(rand.Float64()*maxFactor*float64(duration))\n\treturn wait\n}\n\nfunc (cd *containerData) Start() error {\n\tgo cd.housekeeping()\n\treturn nil\n}\n\nfunc (cd *containerData) Stop() error {\n\terr := cd.memoryCache.RemoveContainer(cd.info.Name)\n\tif err != nil {\n\t\treturn err\n\t}\n\t// Use sync.Once to ensure the channel is only closed once, preventing\n\t// panic from concurrent calls to Stop() when multiple goroutines try\n\t// to destroy the same container simultaneously.\n\tcd.stopOnce.Do(func() {\n\t\tclose(cd.stop)\n\t})\n\tcd.perfCollector.Destroy()\n\tcd.resctrlCollector.Destroy()\n\treturn nil\n}\n\nfunc (cd *containerData) allowErrorLogging() bool {\n\tif cd.clock.Since(cd.lastErrorTime) > time.Minute {\n\t\tcd.lastErrorTime = cd.clock.Now()\n\t\treturn true\n\t}\n\treturn false\n}\n\n// OnDemandHousekeeping performs housekeeping on the container and blocks until it has completed.\n// It is designed to be used in conjunction with periodic housekeeping, and will cause the timer for\n// periodic housekeeping to reset.  This should be used sparingly, as calling OnDemandHousekeeping frequently\n// can have serious performance costs.\nfunc (cd *containerData) OnDemandHousekeeping(maxAge time.Duration) {\n\ttimeSinceStatsLastUpdate := cd.clock.Since(cd.statsLastUpdatedTime.Time())\n\tif timeSinceStatsLastUpdate > maxAge {\n\t\thousekeepingFinishedChan := make(chan struct{})\n\t\tcd.onDemandChan <- housekeepingFinishedChan\n\t\tselect {\n\t\tcase <-cd.stop:\n\t\tcase <-housekeepingFinishedChan:\n\t\t}\n\t}\n}\n\n// notifyOnDemand notifies all calls to OnDemandHousekeeping that housekeeping is finished\nfunc (cd *containerData) notifyOnDemand() {\n\tfor {\n\t\tselect {\n\t\tcase finishedChan := <-cd.onDemandChan:\n\t\t\tclose(finishedChan)\n\t\tdefault:\n\t\t\treturn\n\t\t}\n\t}\n}\n\nfunc (cd *containerData) GetInfo(shouldUpdateSubcontainers bool) (*containerInfo, error) {\n\t// Get spec and subcontainers.\n\tif cd.clock.Since(cd.infoLastUpdatedTime.Time()) > 5*time.Second || shouldUpdateSubcontainers {\n\t\terr := cd.updateSpec()\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tif shouldUpdateSubcontainers {\n\t\t\terr = cd.updateSubcontainers()\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t}\n\t\tcd.infoLastUpdatedTime.Store(cd.clock.Now().UnixNano())\n\t}\n\tcd.lock.Lock()\n\tdefer cd.lock.Unlock()\n\tcInfo := containerInfo{\n\t\tSubcontainers: cd.info.Subcontainers,\n\t\tSpec:          cd.info.Spec,\n\t}\n\tcInfo.Id = cd.info.Id\n\tcInfo.Name = cd.info.Name\n\tcInfo.Aliases = cd.info.Aliases\n\tcInfo.Namespace = cd.info.Namespace\n\treturn &cInfo, nil\n}\n\nfunc (cd *containerData) DerivedStats() (v2.DerivedStats, error) {\n\tif cd.summaryReader == nil {\n\t\treturn v2.DerivedStats{}, fmt.Errorf(\"derived stats not enabled for container %q\", cd.info.Name)\n\t}\n\treturn cd.summaryReader.DerivedStats()\n}\n\nfunc (cd *containerData) getCgroupPath(cgroups string) string {\n\tif cgroups == \"-\" {\n\t\treturn \"/\"\n\t}\n\tif strings.HasPrefix(cgroups, \"0::\") {\n\t\treturn cgroups[3:]\n\t}\n\tmatches := cgroupMemoryPathRegExp.FindSubmatch([]byte(cgroups))\n\tif len(matches) != 2 {\n\t\tklog.V(3).Infof(\n\t\t\t\"failed to get memory cgroup path from %q, will try to get cpu cgroup path\",\n\t\t\tcgroups,\n\t\t)\n\t\t// On some systems (e.g. Raspberry PI 4) cgroup memory controlled is disabled by default.\n\t\tmatches = cgroupCPUPathRegExp.FindSubmatch([]byte(cgroups))\n\t\tif len(matches) != 2 {\n\t\t\tklog.V(3).Infof(\"failed to get cpu cgroup path from %q; assuming root cgroup\", cgroups)\n\t\t\t// return root in case of failures - memory hierarchy might not be enabled.\n\t\t\treturn \"/\"\n\t\t}\n\t}\n\treturn string(matches[1])\n}\n\n// Returns contents of a file inside the container root.\n// Takes in a path relative to container root.\nfunc (cd *containerData) ReadFile(filepath string, inHostNamespace bool) ([]byte, error) {\n\tpids, err := cd.getContainerPids(inHostNamespace)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\t// TODO(rjnagal): Optimize by just reading container's cgroup.proc file when in host namespace.\n\trootfs := \"/\"\n\tif !inHostNamespace {\n\t\trootfs = \"/rootfs\"\n\t}\n\tfor _, pid := range pids {\n\t\tfilePath := path.Join(rootfs, \"/proc\", pid, \"/root\", filepath)\n\t\tklog.V(3).Infof(\"Trying path %q\", filePath)\n\t\tdata, err := os.ReadFile(filePath)\n\t\tif err == nil {\n\t\t\treturn data, err\n\t\t}\n\t}\n\t// No process paths could be found. Declare config non-existent.\n\treturn nil, fmt.Errorf(\"file %q does not exist\", filepath)\n}\n\n// Return output for ps command in host /proc with specified format\nfunc (cd *containerData) getPsOutput(inHostNamespace bool, format string) ([]byte, error) {\n\targs := []string{}\n\tcommand := \"ps\"\n\tif !inHostNamespace {\n\t\tcommand = \"/usr/sbin/chroot\"\n\t\targs = append(args, \"/rootfs\", \"ps\")\n\t}\n\targs = append(args, \"-e\", \"-o\", format)\n\tout, err := exec.Command(command, args...).Output()\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to execute %q command: %v\", command, err)\n\t}\n\treturn out, err\n}\n\n// Get pids of processes in this container.\n// A slightly lighterweight call than GetProcessList if other details are not required.\nfunc (cd *containerData) getContainerPids(inHostNamespace bool) ([]string, error) {\n\tformat := \"pid,cgroup\"\n\tout, err := cd.getPsOutput(inHostNamespace, format)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\texpectedFields := 2\n\tlines := strings.Split(string(out), \"\\n\")\n\tpids := []string{}\n\tfor _, line := range lines[1:] {\n\t\tif len(line) == 0 {\n\t\t\tcontinue\n\t\t}\n\t\tfields := strings.Fields(line)\n\t\tif len(fields) < expectedFields {\n\t\t\treturn nil, fmt.Errorf(\"expected at least %d fields, found %d: output: %q\", expectedFields, len(fields), line)\n\t\t}\n\t\tpid := fields[0]\n\t\tcgroup := cd.getCgroupPath(fields[1])\n\t\tif cd.info.Name == cgroup {\n\t\t\tpids = append(pids, pid)\n\t\t}\n\t}\n\treturn pids, nil\n}\n\nfunc (cd *containerData) GetProcessList(cadvisorContainer string, inHostNamespace bool) ([]v2.ProcessInfo, error) {\n\tformat := \"user,pid,ppid,stime,pcpu,pmem,rss,vsz,stat,time,comm,psr,cgroup\"\n\tout, err := cd.getPsOutput(inHostNamespace, format)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn cd.parseProcessList(cadvisorContainer, inHostNamespace, out)\n}\n\nfunc (cd *containerData) parseProcessList(cadvisorContainer string, inHostNamespace bool, out []byte) ([]v2.ProcessInfo, error) {\n\trootfs := \"/\"\n\tif !inHostNamespace {\n\t\trootfs = \"/rootfs\"\n\t}\n\tprocesses := []v2.ProcessInfo{}\n\tlines := strings.Split(string(out), \"\\n\")\n\tfor _, line := range lines[1:] {\n\t\tprocessInfo, err := cd.parsePsLine(line, cadvisorContainer, inHostNamespace)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"could not parse line %s: %v\", line, err)\n\t\t}\n\t\tif processInfo == nil {\n\t\t\tcontinue\n\t\t}\n\n\t\tvar fdCount int\n\t\tdirPath := path.Join(rootfs, \"/proc\", strconv.Itoa(processInfo.Pid), \"fd\")\n\t\tfds, err := os.ReadDir(dirPath)\n\t\tif err != nil {\n\t\t\tklog.V(4).Infof(\"error while listing directory %q to measure fd count: %v\", dirPath, err)\n\t\t\tcontinue\n\t\t}\n\t\tfdCount = len(fds)\n\t\tprocessInfo.FdCount = fdCount\n\n\t\tprocesses = append(processes, *processInfo)\n\t}\n\treturn processes, nil\n}\n\nfunc (cd *containerData) isRoot() bool {\n\treturn cd.info.Name == \"/\"\n}\n\nfunc (cd *containerData) parsePsLine(line, cadvisorContainer string, inHostNamespace bool) (*v2.ProcessInfo, error) {\n\tconst expectedFields = 13\n\tif len(line) == 0 {\n\t\treturn nil, nil\n\t}\n\n\tinfo := v2.ProcessInfo{}\n\tvar err error\n\n\tfields := strings.Fields(line)\n\tif len(fields) < expectedFields {\n\t\treturn nil, fmt.Errorf(\"expected at least %d fields, found %d: output: %q\", expectedFields, len(fields), line)\n\t}\n\tinfo.User = fields[0]\n\tinfo.StartTime = fields[3]\n\tinfo.Status = fields[8]\n\tinfo.RunningTime = fields[9]\n\n\tinfo.Pid, err = strconv.Atoi(fields[1])\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"invalid pid %q: %v\", fields[1], err)\n\t}\n\tinfo.Ppid, err = strconv.Atoi(fields[2])\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"invalid ppid %q: %v\", fields[2], err)\n\t}\n\n\tpercentCPU, err := strconv.ParseFloat(fields[4], 32)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"invalid cpu percent %q: %v\", fields[4], err)\n\t}\n\tinfo.PercentCpu = float32(percentCPU)\n\tpercentMem, err := strconv.ParseFloat(fields[5], 32)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"invalid memory percent %q: %v\", fields[5], err)\n\t}\n\tinfo.PercentMemory = float32(percentMem)\n\n\tinfo.RSS, err = strconv.ParseUint(fields[6], 0, 64)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"invalid rss %q: %v\", fields[6], err)\n\t}\n\tinfo.VirtualSize, err = strconv.ParseUint(fields[7], 0, 64)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"invalid virtual size %q: %v\", fields[7], err)\n\t}\n\t// convert to bytes\n\tinfo.RSS *= 1024\n\tinfo.VirtualSize *= 1024\n\n\t// According to `man ps`: The following user-defined format specifiers may contain spaces: args, cmd, comm, command,\n\t// fname, ucmd, ucomm, lstart, bsdstart, start.\n\t// Therefore we need to be able to parse comm that consists of multiple space-separated parts.\n\tinfo.Cmd = strings.Join(fields[10:len(fields)-2], \" \")\n\n\t// These are last two parts of the line. We create a subslice of `fields` to handle comm that includes spaces.\n\tlastTwoFields := fields[len(fields)-2:]\n\tinfo.Psr, err = strconv.Atoi(lastTwoFields[0])\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"invalid psr %q: %v\", lastTwoFields[0], err)\n\t}\n\tinfo.CgroupPath = cd.getCgroupPath(lastTwoFields[1])\n\n\t// Remove the ps command we just ran from cadvisor container.\n\t// Not necessary, but makes the cadvisor page look cleaner.\n\tif !inHostNamespace && cadvisorContainer == info.CgroupPath && info.Cmd == \"ps\" {\n\t\treturn nil, nil\n\t}\n\n\t// Do not report processes from other containers when non-root container requested.\n\tif !cd.isRoot() && info.CgroupPath != cd.info.Name {\n\t\treturn nil, nil\n\t}\n\n\t// Remove cgroup information when non-root container requested.\n\tif !cd.isRoot() {\n\t\tinfo.CgroupPath = \"\"\n\t}\n\treturn &info, nil\n}\n\nfunc newContainerData(containerName string, memoryCache *memory.InMemoryCache, handler container.ContainerHandler, logUsage bool, collectorManager collector.CollectorManager, maxHousekeepingInterval time.Duration, allowDynamicHousekeeping bool, clock clock.Clock) (*containerData, error) {\n\tif memoryCache == nil {\n\t\treturn nil, fmt.Errorf(\"nil memory storage\")\n\t}\n\tif handler == nil {\n\t\treturn nil, fmt.Errorf(\"nil container handler\")\n\t}\n\tref, err := handler.ContainerReference()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tcont := &containerData{\n\t\thandler:                  handler,\n\t\tmemoryCache:              memoryCache,\n\t\thousekeepingInterval:     *HousekeepingInterval,\n\t\tmaxHousekeepingInterval:  maxHousekeepingInterval,\n\t\tallowDynamicHousekeeping: allowDynamicHousekeeping,\n\t\tlogUsage:                 logUsage,\n\t\tloadAvg:                  -1.0, // negative value indicates uninitialized.\n\t\tloadDAvg:                 -1.0, // negative value indicates uninitialized.\n\t\tstop:                     make(chan struct{}),\n\t\tcollectorManager:         collectorManager,\n\t\tonDemandChan:             make(chan chan struct{}, 100),\n\t\tclock:                    clock,\n\t\tperfCollector:            &stats.NoopCollector{},\n\t\tresctrlCollector:         &stats.NoopCollector{},\n\t}\n\tcont.info.ContainerReference = ref\n\n\tcont.loadDecay = math.Exp(float64(-cont.housekeepingInterval.Seconds() / 10))\n\n\tif *enableLoadReader {\n\t\t// Create cpu load reader.\n\t\tloadReader, err := cpuload.New()\n\t\tif err != nil {\n\t\t\tklog.Warningf(\"Could not initialize cpu load reader for %q: %s\", ref.Name, err)\n\t\t} else {\n\t\t\tcont.loadReader = loadReader\n\t\t}\n\t}\n\n\terr = cont.updateSpec()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tcont.summaryReader, err = summary.New(cont.info.Spec)\n\tif err != nil {\n\t\tcont.summaryReader = nil\n\t\tklog.V(5).Infof(\"Failed to create summary reader for %q: %v\", ref.Name, err)\n\t}\n\n\treturn cont, nil\n}\n\n// Determine when the next housekeeping should occur.\nfunc (cd *containerData) nextHousekeepingInterval() time.Duration {\n\tif cd.allowDynamicHousekeeping {\n\t\tvar empty time.Time\n\t\tstats, err := cd.memoryCache.RecentStats(cd.info.Name, empty, empty, 2)\n\t\tif err != nil {\n\t\t\tif cd.allowErrorLogging() {\n\t\t\t\tklog.V(4).Infof(\"Failed to get RecentStats(%q) while determining the next housekeeping: %v\", cd.info.Name, err)\n\t\t\t}\n\t\t} else if len(stats) == 2 {\n\t\t\t// TODO(vishnuk): Use no processes as a signal.\n\t\t\t// Raise the interval if usage hasn't changed in the last housekeeping.\n\t\t\tif stats[0].StatsEq(stats[1]) && (cd.housekeepingInterval < cd.maxHousekeepingInterval) {\n\t\t\t\tcd.housekeepingInterval *= 2\n\t\t\t\tif cd.housekeepingInterval > cd.maxHousekeepingInterval {\n\t\t\t\t\tcd.housekeepingInterval = cd.maxHousekeepingInterval\n\t\t\t\t}\n\t\t\t} else if cd.housekeepingInterval != *HousekeepingInterval {\n\t\t\t\t// Lower interval back to the baseline.\n\t\t\t\tcd.housekeepingInterval = *HousekeepingInterval\n\t\t\t}\n\t\t}\n\t}\n\n\treturn jitter(cd.housekeepingInterval, 1.0)\n}\n\n// TODO(vmarmol): Implement stats collecting as a custom collector.\nfunc (cd *containerData) housekeeping() {\n\t// Start any background goroutines - must be cleaned up in cd.handler.Cleanup().\n\tcd.handler.Start()\n\tdefer cd.handler.Cleanup()\n\n\t// Initialize cpuload reader - must be cleaned up in cd.loadReader.Stop()\n\tif cd.loadReader != nil {\n\t\terr := cd.loadReader.Start()\n\t\tif err != nil {\n\t\t\tklog.Warningf(\"Could not start cpu load stat collector for %q: %s\", cd.info.Name, err)\n\t\t}\n\t\tdefer cd.loadReader.Stop()\n\t}\n\n\t// Long housekeeping is either 100ms or half of the housekeeping interval.\n\tlongHousekeeping := 100 * time.Millisecond\n\tif *HousekeepingInterval/2 < longHousekeeping {\n\t\tlongHousekeeping = *HousekeepingInterval / 2\n\t}\n\n\t// Housekeep every second.\n\tklog.V(3).Infof(\"Start housekeeping for container %q\\n\", cd.info.Name)\n\thouseKeepingTimer := cd.clock.NewTimer(0 * time.Second)\n\tdefer houseKeepingTimer.Stop()\n\tfor {\n\t\tif !cd.housekeepingTick(houseKeepingTimer.C(), longHousekeeping) {\n\t\t\treturn\n\t\t}\n\t\t// Stop and drain the timer so that it is safe to reset it\n\t\tif !houseKeepingTimer.Stop() {\n\t\t\tselect {\n\t\t\tcase <-houseKeepingTimer.C():\n\t\t\tdefault:\n\t\t\t}\n\t\t}\n\t\t// Log usage if asked to do so.\n\t\tif cd.logUsage {\n\t\t\tconst numSamples = 60\n\t\t\tvar empty time.Time\n\t\t\tstats, err := cd.memoryCache.RecentStats(cd.info.Name, empty, empty, numSamples)\n\t\t\tif err != nil {\n\t\t\t\tif cd.allowErrorLogging() {\n\t\t\t\t\tklog.Warningf(\"[%s] Failed to get recent stats for logging usage: %v\", cd.info.Name, err)\n\t\t\t\t}\n\t\t\t} else if len(stats) < numSamples {\n\t\t\t\t// Ignore, not enough stats yet.\n\t\t\t} else {\n\t\t\t\tusageCPUNs := uint64(0)\n\t\t\t\tfor i := range stats {\n\t\t\t\t\tif i > 0 {\n\t\t\t\t\t\tusageCPUNs += stats[i].Cpu.Usage.Total - stats[i-1].Cpu.Usage.Total\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tusageMemory := stats[numSamples-1].Memory.Usage\n\n\t\t\t\tinstantUsageInCores := float64(stats[numSamples-1].Cpu.Usage.Total-stats[numSamples-2].Cpu.Usage.Total) / float64(stats[numSamples-1].Timestamp.Sub(stats[numSamples-2].Timestamp).Nanoseconds())\n\t\t\t\tusageInCores := float64(usageCPUNs) / float64(stats[numSamples-1].Timestamp.Sub(stats[0].Timestamp).Nanoseconds())\n\t\t\t\tusageInHuman := units.HumanSize(float64(usageMemory))\n\t\t\t\t// Don't set verbosity since this is already protected by the logUsage flag.\n\t\t\t\tklog.Infof(\"[%s] %.3f cores (average: %.3f cores), %s of memory\", cd.info.Name, instantUsageInCores, usageInCores, usageInHuman)\n\t\t\t}\n\t\t}\n\t\thouseKeepingTimer.Reset(cd.nextHousekeepingInterval())\n\t}\n}\n\nfunc (cd *containerData) housekeepingTick(timer <-chan time.Time, longHousekeeping time.Duration) bool {\n\tselect {\n\tcase <-cd.stop:\n\t\t// Stop housekeeping when signaled.\n\t\treturn false\n\tcase finishedChan := <-cd.onDemandChan:\n\t\t// notify the calling function once housekeeping has completed\n\t\tdefer close(finishedChan)\n\tcase <-timer:\n\t}\n\tstart := cd.clock.Now()\n\terr := cd.updateStats()\n\tif err != nil {\n\t\tif cd.allowErrorLogging() {\n\t\t\tklog.Warningf(\"Failed to update stats for container \\\"%s\\\": %s\", cd.info.Name, err)\n\t\t}\n\t}\n\t// Log if housekeeping took too long.\n\tduration := cd.clock.Since(start)\n\tif duration >= longHousekeeping {\n\t\tklog.V(3).Infof(\"[%s] Housekeeping took %s\", cd.info.Name, duration)\n\t}\n\tcd.notifyOnDemand()\n\tcd.statsLastUpdatedTime.Store(cd.clock.Now().UnixNano())\n\treturn true\n}\n\nfunc (cd *containerData) updateSpec() error {\n\tspec, err := cd.handler.GetSpec()\n\tif err != nil {\n\t\t// Ignore errors if the container is dead.\n\t\tif !cd.handler.Exists() {\n\t\t\treturn nil\n\t\t}\n\t\treturn err\n\t}\n\n\tcustomMetrics, err := cd.collectorManager.GetSpec()\n\tif err != nil {\n\t\treturn err\n\t}\n\tif len(customMetrics) > 0 {\n\t\tspec.HasCustomMetrics = true\n\t\tspec.CustomMetrics = customMetrics\n\t}\n\tcd.lock.Lock()\n\tdefer cd.lock.Unlock()\n\tcd.info.Spec = spec\n\treturn nil\n}\n\n// Calculate new smoothed load average using the new sample of runnable threads.\n// The decay used ensures that the load will stabilize on a new constant value within\n// 10 seconds.\nfunc (cd *containerData) updateLoad(newLoad uint64) {\n\tif cd.loadAvg < 0 {\n\t\tcd.loadAvg = float64(newLoad) // initialize to the first seen sample for faster stabilization.\n\t} else {\n\t\tcd.loadAvg = cd.loadAvg*cd.loadDecay + float64(newLoad)*(1.0-cd.loadDecay)\n\t}\n}\n\nfunc (cd *containerData) updateLoadD(newLoad uint64) {\n\tif cd.loadDAvg < 0 {\n\t\tcd.loadDAvg = float64(newLoad) // initialize to the first seen sample for faster stabilization.\n\t} else {\n\t\tcd.loadDAvg = cd.loadDAvg*cd.loadDecay + float64(newLoad)*(1.0-cd.loadDecay)\n\t}\n}\n\nfunc (cd *containerData) updateStats() error {\n\tstats, statsErr := cd.handler.GetStats()\n\tif statsErr != nil {\n\t\t// Ignore errors if the container is dead.\n\t\tif !cd.handler.Exists() {\n\t\t\treturn nil\n\t\t}\n\n\t\t// Stats may be partially populated, push those before we return an error.\n\t\tstatsErr = fmt.Errorf(\"%v, continuing to push stats\", statsErr)\n\t}\n\tif stats == nil {\n\t\treturn statsErr\n\t}\n\tif cd.loadReader != nil {\n\t\t// TODO(vmarmol): Cache this path.\n\t\tpath, err := cd.handler.GetCgroupPath(\"cpu\")\n\t\tif err == nil {\n\t\t\tloadStats, err := cd.loadReader.GetCpuLoad(cd.info.Name, path)\n\t\t\tif err != nil {\n\t\t\t\treturn fmt.Errorf(\"failed to get load stat for %q - path %q, error %s\", cd.info.Name, path, err)\n\t\t\t}\n\t\t\tstats.TaskStats = loadStats\n\t\t\tcd.updateLoad(loadStats.NrRunning)\n\t\t\t// convert to 'milliLoad' to avoid floats and preserve precision.\n\t\t\tstats.Cpu.LoadAverage = int32(cd.loadAvg * 1000)\n\n\t\t\tcd.updateLoadD(loadStats.NrUninterruptible)\n\t\t\t// convert to 'milliLoad' to avoid floats and preserve precision.\n\t\t\tstats.Cpu.LoadDAverage = int32(cd.loadDAvg * 1000)\n\t\t}\n\t}\n\tif cd.summaryReader != nil {\n\t\terr := cd.summaryReader.AddSample(*stats)\n\t\tif err != nil {\n\t\t\t// Ignore summary errors for now.\n\t\t\tklog.V(2).Infof(\"Failed to add summary stats for %q: %v\", cd.info.Name, err)\n\t\t}\n\t}\n\n\tstats.OOMEvents = atomic.LoadUint64(&cd.oomEvents)\n\n\tvar customStatsErr error\n\tcm := cd.collectorManager.(*collector.GenericCollectorManager)\n\tif len(cm.Collectors) > 0 {\n\t\tif cm.NextCollectionTime.Before(cd.clock.Now()) {\n\t\t\tcustomStats, err := cd.updateCustomStats()\n\t\t\tif customStats != nil {\n\t\t\t\tstats.CustomMetrics = customStats\n\t\t\t}\n\t\t\tif err != nil {\n\t\t\t\tcustomStatsErr = err\n\t\t\t}\n\t\t}\n\t}\n\n\tperfStatsErr := cd.perfCollector.UpdateStats(stats)\n\n\tresctrlStatsErr := cd.resctrlCollector.UpdateStats(stats)\n\n\tref, err := cd.handler.ContainerReference()\n\tif err != nil {\n\t\t// Ignore errors if the container is dead.\n\t\tif !cd.handler.Exists() {\n\t\t\treturn nil\n\t\t}\n\t\treturn err\n\t}\n\n\tcInfo := info.ContainerInfo{\n\t\tContainerReference: ref,\n\t}\n\n\terr = cd.memoryCache.AddStats(&cInfo, stats)\n\tif err != nil {\n\t\treturn err\n\t}\n\tif statsErr != nil {\n\t\treturn statsErr\n\t}\n\tif perfStatsErr != nil {\n\t\tklog.Errorf(\"error occurred while collecting perf stats for container %s: %s\", cInfo.Name, perfStatsErr)\n\t\treturn perfStatsErr\n\t}\n\tif resctrlStatsErr != nil {\n\t\tklog.Errorf(\"error occurred while collecting resctrl stats for container %s: %s\", cInfo.Name, resctrlStatsErr)\n\t\treturn resctrlStatsErr\n\t}\n\treturn customStatsErr\n}\n\nfunc (cd *containerData) updateCustomStats() (map[string][]info.MetricVal, error) {\n\t_, customStats, customStatsErr := cd.collectorManager.Collect()\n\tif customStatsErr != nil {\n\t\tif !cd.handler.Exists() {\n\t\t\treturn customStats, nil\n\t\t}\n\t\tcustomStatsErr = fmt.Errorf(\"%v, continuing to push custom stats\", customStatsErr)\n\t}\n\treturn customStats, customStatsErr\n}\n\nfunc (cd *containerData) updateSubcontainers() error {\n\tvar subcontainers info.ContainerReferenceSlice\n\tsubcontainers, err := cd.handler.ListContainers(container.ListSelf)\n\tif err != nil {\n\t\t// Ignore errors if the container is dead.\n\t\tif !cd.handler.Exists() {\n\t\t\treturn nil\n\t\t}\n\t\treturn err\n\t}\n\tsort.Sort(subcontainers)\n\tcd.lock.Lock()\n\tdefer cd.lock.Unlock()\n\tcd.info.Subcontainers = subcontainers\n\treturn nil\n}\n"
  },
  {
    "path": "manager/container_test.go",
    "content": "// Copyright 2014 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n//go:build linux\n\n// Per-container manager.\n\npackage manager\n\nimport (\n\t\"fmt\"\n\t\"reflect\"\n\t\"sync\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/google/cadvisor/cache/memory\"\n\t\"github.com/google/cadvisor/collector\"\n\t\"github.com/google/cadvisor/container\"\n\tcontainertest \"github.com/google/cadvisor/container/testing\"\n\tinfo \"github.com/google/cadvisor/info/v1\"\n\titest \"github.com/google/cadvisor/info/v1/test\"\n\tv2 \"github.com/google/cadvisor/info/v2\"\n\n\t\"github.com/stretchr/testify/assert\"\n\t\"github.com/stretchr/testify/require\"\n\n\tclock \"k8s.io/utils/clock/testing\"\n)\n\nconst (\n\tcontainerName        = \"/container\"\n\ttestLongHousekeeping = time.Second\n)\n\n// Create a containerData instance for a test.\nfunc setupContainerData(t *testing.T, spec info.ContainerSpec) (*containerData, *containertest.MockContainerHandler, *memory.InMemoryCache, *clock.FakeClock) {\n\tmockHandler := containertest.NewMockContainerHandler(containerName)\n\tmockHandler.On(\"GetSpec\").Return(\n\t\tspec,\n\t\tnil,\n\t)\n\tmemoryCache := memory.New(60, nil)\n\tfakeClock := clock.NewFakeClock(time.Now())\n\tret, err := newContainerData(containerName, memoryCache, mockHandler, false, &collector.GenericCollectorManager{}, 60*time.Second, true, fakeClock)\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\treturn ret, mockHandler, memoryCache, fakeClock\n}\n\n// Create a containerData instance for a test and add a default GetSpec mock.\nfunc newTestContainerData(t *testing.T) (*containerData, *containertest.MockContainerHandler, *memory.InMemoryCache, *clock.FakeClock) {\n\treturn setupContainerData(t, itest.GenerateRandomContainerSpec(4))\n}\n\nfunc TestUpdateSubcontainers(t *testing.T) {\n\tsubcontainers := []info.ContainerReference{\n\t\t{Name: \"/container/ee0103\"},\n\t\t{Name: \"/container/abcd\"},\n\t\t{Name: \"/container/something\"},\n\t}\n\tcd, mockHandler, _, _ := newTestContainerData(t)\n\tmockHandler.On(\"ListContainers\", container.ListSelf).Return(\n\t\tsubcontainers,\n\t\tnil,\n\t)\n\n\terr := cd.updateSubcontainers()\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\n\tif len(cd.info.Subcontainers) != len(subcontainers) {\n\t\tt.Errorf(\"Received %v subcontainers, should be %v\", len(cd.info.Subcontainers), len(subcontainers))\n\t}\n\n\tfor _, sub := range cd.info.Subcontainers {\n\t\tfound := false\n\t\tfor _, sub2 := range subcontainers {\n\t\t\tif sub.Name == sub2.Name {\n\t\t\t\tfound = true\n\t\t\t}\n\t\t}\n\t\tif !found {\n\t\t\tt.Errorf(\"Received unknown sub container %v\", sub)\n\t\t}\n\t}\n\n\tmockHandler.AssertExpectations(t)\n}\n\nfunc TestUpdateSubcontainersWithError(t *testing.T) {\n\tcd, mockHandler, _, _ := newTestContainerData(t)\n\tmockHandler.On(\"ListContainers\", container.ListSelf).Return(\n\t\t[]info.ContainerReference{},\n\t\tfmt.Errorf(\"some error\"),\n\t)\n\tmockHandler.On(\"Exists\").Return(true)\n\n\tassert.NotNil(t, cd.updateSubcontainers())\n\tassert.Empty(t, cd.info.Subcontainers, \"subcontainers should not be populated on failure\")\n\tmockHandler.AssertExpectations(t)\n}\n\nfunc TestUpdateSubcontainersWithErrorOnDeadContainer(t *testing.T) {\n\tcd, mockHandler, _, _ := newTestContainerData(t)\n\tmockHandler.On(\"ListContainers\", container.ListSelf).Return(\n\t\t[]info.ContainerReference{},\n\t\tfmt.Errorf(\"some error\"),\n\t)\n\tmockHandler.On(\"Exists\").Return(false)\n\n\tassert.Nil(t, cd.updateSubcontainers())\n\tmockHandler.AssertExpectations(t)\n}\n\nfunc checkNumStats(t *testing.T, memoryCache *memory.InMemoryCache, numStats int) {\n\tvar empty time.Time\n\tstats, err := memoryCache.RecentStats(containerName, empty, empty, -1)\n\trequire.Nil(t, err)\n\tassert.Len(t, stats, numStats)\n}\n\nfunc TestUpdateStats(t *testing.T) {\n\tstatsList := itest.GenerateRandomStats(1, 4, 1*time.Second)\n\tstats := statsList[0]\n\n\tcd, mockHandler, memoryCache, _ := newTestContainerData(t)\n\tmockHandler.On(\"GetStats\").Return(\n\t\tstats,\n\t\tnil,\n\t)\n\n\terr := cd.updateStats()\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\n\tcheckNumStats(t, memoryCache, 1)\n\tmockHandler.AssertExpectations(t)\n}\n\nfunc TestUpdateSpec(t *testing.T) {\n\tspec := itest.GenerateRandomContainerSpec(4)\n\tcd, mockHandler, _, _ := newTestContainerData(t)\n\tmockHandler.On(\"GetSpec\").Return(\n\t\tspec,\n\t\tnil,\n\t)\n\n\terr := cd.updateSpec()\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\n\tmockHandler.AssertExpectations(t)\n}\n\nfunc TestGetInfo(t *testing.T) {\n\tspec := itest.GenerateRandomContainerSpec(4)\n\tsubcontainers := []info.ContainerReference{\n\t\t{Name: \"/container/ee0103\"},\n\t\t{Name: \"/container/abcd\"},\n\t\t{Name: \"/container/something\"},\n\t}\n\tcd, mockHandler, _, _ := setupContainerData(t, spec)\n\tmockHandler.On(\"ListContainers\", container.ListSelf).Return(\n\t\tsubcontainers,\n\t\tnil,\n\t)\n\tmockHandler.Aliases = []string{\"a1\", \"a2\"}\n\n\tinfo, err := cd.GetInfo(true)\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\n\tmockHandler.AssertExpectations(t)\n\n\tif len(info.Subcontainers) != len(subcontainers) {\n\t\tt.Errorf(\"Received %v subcontainers, should be %v\", len(info.Subcontainers), len(subcontainers))\n\t}\n\n\tfor _, sub := range info.Subcontainers {\n\t\tfound := false\n\t\tfor _, sub2 := range subcontainers {\n\t\t\tif sub.Name == sub2.Name {\n\t\t\t\tfound = true\n\t\t\t}\n\t\t}\n\t\tif !found {\n\t\t\tt.Errorf(\"Received unknown sub container %v\", sub)\n\t\t}\n\t}\n\n\tif !reflect.DeepEqual(spec, info.Spec) {\n\t\tt.Errorf(\"received wrong container spec\")\n\t}\n\n\tif info.Name != mockHandler.Name {\n\t\tt.Errorf(\"received wrong container name: received %v; should be %v\", info.Name, mockHandler.Name)\n\t}\n}\n\nfunc TestOnDemandHousekeeping(t *testing.T) {\n\tstatsList := itest.GenerateRandomStats(1, 4, 1*time.Second)\n\tstats := statsList[0]\n\n\tcd, mockHandler, memoryCache, fakeClock := newTestContainerData(t)\n\tmockHandler.On(\"GetStats\").Return(stats, nil)\n\tdefer func() {\n\t\terr := cd.Stop()\n\t\tassert.NoError(t, err)\n\t}()\n\n\t// 0 seconds should always trigger an update\n\tgo cd.OnDemandHousekeeping(0 * time.Second)\n\tcd.housekeepingTick(fakeClock.NewTimer(time.Minute).C(), testLongHousekeeping)\n\n\tfakeClock.Step(2 * time.Second)\n\n\t// This should return without requiring a housekeepingTick because stats have been updated recently enough\n\tcd.OnDemandHousekeeping(3 * time.Second)\n\n\tgo cd.OnDemandHousekeeping(1 * time.Second)\n\tcd.housekeepingTick(fakeClock.NewTimer(time.Minute).C(), testLongHousekeeping)\n\n\tcheckNumStats(t, memoryCache, 2)\n\tmockHandler.AssertExpectations(t)\n}\n\nfunc TestConcurrentOnDemandHousekeeping(t *testing.T) {\n\tstatsList := itest.GenerateRandomStats(1, 4, 1*time.Second)\n\tstats := statsList[0]\n\n\tcd, mockHandler, memoryCache, fakeClock := newTestContainerData(t)\n\tmockHandler.On(\"GetStats\").Return(stats, nil)\n\tdefer func() {\n\t\terr := cd.Stop()\n\t\tassert.NoError(t, err)\n\t}()\n\n\tnumConcurrentCalls := 5\n\tvar waitForHousekeeping sync.WaitGroup\n\twaitForHousekeeping.Add(numConcurrentCalls)\n\tonDemandCache := []chan struct{}{}\n\tfor i := 0; i < numConcurrentCalls; i++ {\n\t\tgo func() {\n\t\t\tcd.OnDemandHousekeeping(0 * time.Second)\n\t\t\twaitForHousekeeping.Done()\n\t\t}()\n\t\t// Wait for work to be queued\n\t\tonDemandCache = append(onDemandCache, <-cd.onDemandChan)\n\t}\n\t// Requeue work:\n\tfor _, ch := range onDemandCache {\n\t\tcd.onDemandChan <- ch\n\t}\n\n\tgo cd.housekeepingTick(fakeClock.NewTimer(time.Minute).C(), testLongHousekeeping)\n\t// Ensure that all queued calls return with only a single call to housekeepingTick\n\twaitForHousekeeping.Wait()\n\n\tcheckNumStats(t, memoryCache, 1)\n\tmockHandler.AssertExpectations(t)\n}\n\nfunc TestOnDemandHousekeepingReturnsAfterStopped(t *testing.T) {\n\tstatsList := itest.GenerateRandomStats(1, 4, 1*time.Second)\n\tstats := statsList[0]\n\n\tcd, mockHandler, memoryCache, fakeClock := newTestContainerData(t)\n\tmockHandler.On(\"GetStats\").Return(stats, nil)\n\n\t// trigger housekeeping update\n\tgo cd.OnDemandHousekeeping(0 * time.Second)\n\tcd.housekeepingTick(fakeClock.NewTimer(time.Minute).C(), testLongHousekeeping)\n\n\tcheckNumStats(t, memoryCache, 1)\n\n\tfakeClock.Step(2 * time.Second)\n\n\terr := cd.Stop()\n\tassert.NoError(t, err)\n\t// housekeeping tick should detect stop and not store any more metrics\n\tassert.False(t, cd.housekeepingTick(fakeClock.NewTimer(time.Minute).C(), testLongHousekeeping))\n\tfakeClock.Step(1 * time.Second)\n\t// on demand housekeeping should not block and return\n\tcd.OnDemandHousekeeping(-1 * time.Second)\n\n\tmockHandler.AssertExpectations(t)\n}\n\nfunc TestOnDemandHousekeepingRace(t *testing.T) {\n\tstatsList := itest.GenerateRandomStats(1, 4, 1*time.Second)\n\tstats := statsList[0]\n\n\tcd, mockHandler, _, _ := newTestContainerData(t)\n\tmockHandler.On(\"GetStats\").Return(stats, nil)\n\n\twg := sync.WaitGroup{}\n\twg.Add(1002)\n\n\tgo func() {\n\t\ttime.Sleep(10 * time.Millisecond)\n\t\terr := cd.Start()\n\t\tassert.NoError(t, err)\n\t\twg.Done()\n\t}()\n\n\tgo func() {\n\t\tt.Log(\"starting on demand goroutine\")\n\t\tfor i := 0; i < 1000; i++ {\n\t\t\tgo func() {\n\t\t\t\ttime.Sleep(1 * time.Microsecond)\n\t\t\t\tcd.OnDemandHousekeeping(0 * time.Millisecond)\n\t\t\t\twg.Done()\n\t\t\t}()\n\t\t}\n\t\twg.Done()\n\t}()\n\twg.Wait()\n}\n\nvar psOutput = [][]byte{\n\t[]byte(\"root       15886       2 23:51  0.1  0.0     0      0 I    00:00:00 kworker/u8:3-ev   3 -\\nroot       15887       2 23:51  0.0  0.0     0      0 I<   00:00:00 kworker/1:2H      1 -\\nubuntu     15888    1804 23:51  0.0  0.0  2832  10176 R+   00:00:00 ps                1 8:devices:/user.slice,6:pids:/user.slice/user-1000.slice/session-3.scope,5:blkio:/user.slice,2:cpu,cpuacct:/user.slice,1:na\"),\n\t[]byte(\"root         104       2 21:34  0.0  0.0     0      0 I<   00:00:00 kthrotld          3 -\\nroot         105       2 21:34  0.0  0.0     0      0 S    00:00:00 irq/41-aerdrv     0 -\\nroot         107       2 21:34  0.0  0.0     0      0 I<   00:00:00 DWC Notificatio   3 -\\nroot         109       2 21:34  0.0  0.0     0      0 S<   00:00:00 vchiq-slot/0      1 -\\nroot         110       2 21:34  0.0  0.0     0      0 S<   00:00:00 vchiq-recy/0      3 -\"),\n}\n\nfunc TestParseProcessList(t *testing.T) {\n\tfor i, ps := range psOutput {\n\t\tt.Run(fmt.Sprintf(\"iteration %d\", i), func(tt *testing.T) {\n\t\t\tcd := &containerData{}\n\t\t\t_, err := cd.parseProcessList(\"/\", true, ps)\n\t\t\t// checking *only* parsing errors - otherwise /proc would have to be emulated.\n\t\t\tassert.NoError(tt, err)\n\t\t})\n\t}\n}\n\nvar psLine = []struct {\n\tname              string\n\tline              string\n\tcadvisorContainer string\n\tisHostNamespace   bool\n\tprocess           *v2.ProcessInfo\n\terr               error\n\tcd                *containerData\n}{\n\t{\n\t\tname:              \"plain process with cgroup\",\n\t\tline:              \"ubuntu     15888    1804 23:51  0.1  0.0  2832  10176 R+   00:10:00 cadvisor            1 10:cpuset:/docker/dd479c33249f6c3f0f1189aa88f07dad3eeb3e6fedfc71385c27ddd699994831,9:devices:/docker/dd479c33249f6c3f0f1189aa88f07dad3eeb3e6fedfc71385c27ddd699994831,8:pids:/docker/dd479c33249f6c3f0f1189aa88f07dad3eeb3e6fedfc71385c27ddd699994831,7:memory:/docker/dd479c33249f6c3f0f1189aa88f07dad3eeb3e6fedfc71385c27ddd699994831,6:freezer:/docker/dd479c33249f6c3f0f1189aa88f07dad3eeb3e6fedfc71385c27ddd699994831,5:perf_event:/docker/dd479c33249f6c3f0f1189aa88f07dad3eeb3e6fedfc71385c27ddd699994831,4:blkio:/docker/dd479c33249f6c3f0f1189aa88f07dad3eeb3e6fedfc71385c27ddd699994831,3:cpu,cpuacct:/docker/dd479c33249f6c3f0f1189aa88f07dad3eeb3e6fedfc71385c27ddd699994831,2:net_cls,net_prio:/docker/dd479c33249f6c3f0f1189aa88f07dad3eeb3e6fedfc71385c27ddd699994831,1:name=systemd:/docker/dd479c33249f6c3f0f1189aa88f07dad3eeb3e6fedfc71385c27ddd699994831\",\n\t\tcadvisorContainer: \"/docker/cadvisor\",\n\t\tisHostNamespace:   true,\n\t\tprocess: &v2.ProcessInfo{\n\t\t\tUser:          \"ubuntu\",\n\t\t\tPid:           15888,\n\t\t\tPpid:          1804,\n\t\t\tStartTime:     \"23:51\",\n\t\t\tPercentCpu:    0.1,\n\t\t\tPercentMemory: 0.0,\n\t\t\tRSS:           2899968,\n\t\t\tVirtualSize:   10420224,\n\t\t\tStatus:        \"R+\",\n\t\t\tRunningTime:   \"00:10:00\",\n\t\t\tCgroupPath:    \"/docker/dd479c33249f6c3f0f1189aa88f07dad3eeb3e6fedfc71385c27ddd699994831\",\n\t\t\tCmd:           \"cadvisor\",\n\t\t\tPsr:           1,\n\t\t},\n\t\tcd: &containerData{\n\t\t\tinfo: containerInfo{ContainerReference: info.ContainerReference{Name: \"/\"}},\n\t\t},\n\t},\n\t{\n\t\tname:              \"process with space in name and no cgroup\",\n\t\tline:              \"root         107       2 21:34  0.0  0.1     3      4 I<   00:20:00 DWC Notificatio   3 -\",\n\t\tcadvisorContainer: \"/docker/cadvisor\",\n\t\tprocess: &v2.ProcessInfo{\n\t\t\tUser:          \"root\",\n\t\t\tPid:           107,\n\t\t\tPpid:          2,\n\t\t\tStartTime:     \"21:34\",\n\t\t\tPercentCpu:    0.0,\n\t\t\tPercentMemory: 0.1,\n\t\t\tRSS:           3072,\n\t\t\tVirtualSize:   4096,\n\t\t\tStatus:        \"I<\",\n\t\t\tRunningTime:   \"00:20:00\",\n\t\t\tCgroupPath:    \"/\",\n\t\t\tCmd:           \"DWC Notificatio\",\n\t\t\tPsr:           3,\n\t\t},\n\t\tcd: &containerData{\n\t\t\tinfo: containerInfo{ContainerReference: info.ContainerReference{Name: \"/\"}},\n\t\t},\n\t},\n\t{\n\t\tname:              \"process with highly unusual name (one 2 three 4 five 6 eleven), cgroup to be ignored\",\n\t\tline:              \"root         107       2 21:34  0.0  0.1     3      4 I<   00:20:00 one 2 three 4 five 6 eleven   3 10:cpuset:/docker/dd479c33249f6c3f0f1189aa88f07dad3eeb3e6fedfc71385c27ddd699994831,9:devices:/docker/dd479c33249f6c3f0f1189aa88f07dad3eeb3e6fedfc71385c27ddd699994831,8:pids:/docker/dd479c33249f6c3f0f1189aa88f07dad3eeb3e6fedfc71385c27ddd699994831,7:memory:/docker/dd479c33249f6c3f0f1189aa88f07dad3eeb3e6fedfc71385c27ddd699994831,6:freezer:/docker/dd479c33249f6c3f0f1189aa88f07dad3eeb3e6fedfc71385c27ddd699994831,5:perf_event:/docker/dd479c33249f6c3f0f1189aa88f07dad3eeb3e6fedfc71385c27ddd699994831,4:blkio:/docker/dd479c33249f6c3f0f1189aa88f07dad3eeb3e6fedfc71385c27ddd699994831,3:cpu,cpuacct:/docker/dd479c33249f6c3f0f1189aa88f07dad3eeb3e6fedfc71385c27ddd699994831,2:net_cls,net_prio:/docker/dd479c33249f6c3f0f1189aa88f07dad3eeb3e6fedfc71385c27ddd699994831,1:name=systemd:/docker/dd479c33249f6c3f0f1189aa88f07dad3eeb3e6fedfc71385c27ddd699994831\",\n\t\tcadvisorContainer: \"/docker/cadvisor\",\n\t\tisHostNamespace:   true,\n\t\tprocess: &v2.ProcessInfo{\n\t\t\tUser:          \"root\",\n\t\t\tPid:           107,\n\t\t\tPpid:          2,\n\t\t\tStartTime:     \"21:34\",\n\t\t\tPercentCpu:    0.0,\n\t\t\tPercentMemory: 0.1,\n\t\t\tRSS:           3072,\n\t\t\tVirtualSize:   4096,\n\t\t\tStatus:        \"I<\",\n\t\t\tRunningTime:   \"00:20:00\",\n\t\t\tCmd:           \"one 2 three 4 five 6 eleven\",\n\t\t\tPsr:           3,\n\t\t\tCgroupPath:    \"/docker/dd479c33249f6c3f0f1189aa88f07dad3eeb3e6fedfc71385c27ddd699994831\",\n\t\t},\n\t\tcd: &containerData{\n\t\t\tinfo: containerInfo{ContainerReference: info.ContainerReference{Name: \"/\"}},\n\t\t},\n\t},\n\t{\n\t\tname:              \"wrong field count\",\n\t\tline:              \"ps output it is not\",\n\t\tcadvisorContainer: \"/docker/cadvisor\",\n\t\terr:               fmt.Errorf(\"expected at least 13 fields, found 5: output: \\\"ps output it is not\\\"\"),\n\t\tcd:                &containerData{},\n\t},\n\t{\n\t\tname:              \"ps running in cadvisor container should be ignored\",\n\t\tline:              \"root         107       2 21:34  0.0  0.1     3      4 I<   00:20:00 ps   3 10:cpuset:/docker/dd479c33249f6c3f0f1189aa88f07dad3eeb3e6fedfc71385c27ddd699994831,9:devices:/docker/dd479c33249f6c3f0f1189aa88f07dad3eeb3e6fedfc71385c27ddd699994831,8:pids:/docker/dd479c33249f6c3f0f1189aa88f07dad3eeb3e6fedfc71385c27ddd699994831,7:memory:/docker/dd479c33249f6c3f0f1189aa88f07dad3eeb3e6fedfc71385c27ddd699994831,6:freezer:/docker/dd479c33249f6c3f0f1189aa88f07dad3eeb3e6fedfc71385c27ddd699994831,5:perf_event:/docker/dd479c33249f6c3f0f1189aa88f07dad3eeb3e6fedfc71385c27ddd699994831,4:blkio:/docker/dd479c33249f6c3f0f1189aa88f07dad3eeb3e6fedfc71385c27ddd699994831,3:cpu,cpuacct:/docker/dd479c33249f6c3f0f1189aa88f07dad3eeb3e6fedfc71385c27ddd699994831,2:net_cls,net_prio:/docker/dd479c33249f6c3f0f1189aa88f07dad3eeb3e6fedfc71385c27ddd699994831,1:name=systemd:/docker/dd479c33249f6c3f0f1189aa88f07dad3eeb3e6fedfc71385c27ddd699994831\",\n\t\tcadvisorContainer: \"/docker/dd479c33249f6c3f0f1189aa88f07dad3eeb3e6fedfc71385c27ddd699994831\",\n\t\tcd: &containerData{\n\t\t\tinfo: containerInfo{ContainerReference: info.ContainerReference{Name: \"/\"}},\n\t\t},\n\t},\n\t{\n\t\tname: \"non-root container but process belongs to the container\",\n\t\tline: \"root         107       2 21:34  0.0  0.1     3      4 I<   00:20:00 sleep inf   3 10:cpuset:/docker/some-random-container,9:devices:/docker/some-random-container,8:pids:/docker/some-random-container,7:memory:/docker/some-random-container,6:freezer:/docker/some-random-container,5:perf_event:/docker/some-random-container,4:blkio:/docker/some-random-container,3:cpu,cpuacct:/docker/some-random-container,2:net_cls,net_prio:/docker/some-random-container,1:name=systemd:/docker/some-random-container\",\n\t\tprocess: &v2.ProcessInfo{\n\t\t\tUser:          \"root\",\n\t\t\tPid:           107,\n\t\t\tPpid:          2,\n\t\t\tStartTime:     \"21:34\",\n\t\t\tPercentCpu:    0.0,\n\t\t\tPercentMemory: 0.1,\n\t\t\tRSS:           3072,\n\t\t\tVirtualSize:   4096,\n\t\t\tStatus:        \"I<\",\n\t\t\tRunningTime:   \"00:20:00\",\n\t\t\tCmd:           \"sleep inf\",\n\t\t\tPsr:           3,\n\t\t},\n\t\tcadvisorContainer: \"/docker/dd479c33249f6c3f0f1189aa88f07dad3eeb3e6fedfc71385c27ddd699994831\",\n\t\tcd: &containerData{\n\t\t\tinfo: containerInfo{ContainerReference: info.ContainerReference{Name: \"/docker/some-random-container\"}},\n\t\t},\n\t},\n\t{\n\t\tname:              \"non-root container and process belonging to another container\",\n\t\tline:              \"root         107       2 21:34  0.0  0.1     3      4 I<   00:20:00 sleep inf   3 10:cpuset:/docker/some-random-container,9:devices:/docker/some-random-container,8:pids:/docker/some-random-container,7:memory:/docker/some-random-container,6:freezer:/docker/some-random-container,5:perf_event:/docker/some-random-container,4:blkio:/docker/some-random-container,3:cpu,cpuacct:/docker/some-random-container,2:net_cls,net_prio:/docker/some-random-container,1:name=systemd:/docker/some-random-container\",\n\t\tcadvisorContainer: \"/docker/dd479c33249f6c3f0f1189aa88f07dad3eeb3e6fedfc71385c27ddd699994831\",\n\t\tcd: &containerData{\n\t\t\tinfo: containerInfo{ContainerReference: info.ContainerReference{Name: \"/docker/some-other-container\"}},\n\t\t},\n\t},\n}\n\nfunc TestParsePsLine(t *testing.T) {\n\tfor _, ps := range psLine {\n\t\tt.Run(ps.name, func(tt *testing.T) {\n\t\t\tprocess, err := ps.cd.parsePsLine(ps.line, ps.cadvisorContainer, ps.isHostNamespace)\n\t\t\tassert.Equal(tt, ps.err, err)\n\t\t\tassert.EqualValues(tt, ps.process, process)\n\t\t})\n\t}\n}\n\nvar cgroupCases = []struct {\n\tname    string\n\tcgroups string\n\tpath    string\n}{\n\t{\n\t\tname:    \"no cgroup\",\n\t\tcgroups: \"-\",\n\t\tpath:    \"/\",\n\t},\n\t{\n\t\tname:    \"random and meaningless string\",\n\t\tcgroups: \"/this/is/a/path/to/some.file\",\n\t\tpath:    \"/\",\n\t},\n\t{\n\t\tname:    \"0::-type cgroup\",\n\t\tcgroups: \"0::/docker/some-cgroup\",\n\t\tpath:    \"/docker/some-cgroup\",\n\t},\n\t{\n\t\tname:    \"memory cgroup\",\n\t\tcgroups: \"4:memory:/docker/09c89cd48b3597db904ab8e6920fef2cbf93588d037d9613ce362e25188f8ec6,2:net_cls:/docker/09c89cd48b3597db904ab8e6920fef2cbf93588d037d9613ce362e25188f8ec6\",\n\t\tpath:    \"/docker/09c89cd48b3597db904ab8e6920fef2cbf93588d037d9613ce362e25188f8ec6\",\n\t},\n\t{\n\t\tname:    \"cpu,cpuacct cgroup\",\n\t\tcgroups: \"4:cpu,cpuacct:/docker/09c89cd48b3597db904ab8e6920fef2cbf93588d037d9613ce362e25188f8ec6,2:net_cls:/docker/09c89cd48b3597db904ab8e6920fef2cbf93588d037d9613ce362e25188f8ec6\",\n\t\tpath:    \"/docker/09c89cd48b3597db904ab8e6920fef2cbf93588d037d9613ce362e25188f8ec6\",\n\t},\n\t{\n\t\tname:    \"cpu cgroup\",\n\t\tcgroups: \"4:cpu:/docker/09c89cd48b3597db904ab8e6920fef2cbf93588d037d9613ce362e25188f8ec6,2:net_cls:/docker/09c89cd48b3597db904ab8e6920fef2cbf93588d037d9613ce362e25188f8ec6\",\n\t\tpath:    \"/docker/09c89cd48b3597db904ab8e6920fef2cbf93588d037d9613ce362e25188f8ec6\",\n\t},\n\t{\n\t\tname:    \"cpuacct cgroup\",\n\t\tcgroups: \"4:cpuacct:/docker/09c89cd48b3597db904ab8e6920fef2cbf93588d037d9613ce362e25188f8ec6,2:net_cls:/docker/09c89cd48b3597db904ab8e6920fef2cbf93588d037d9613ce362e25188f8ec6\",\n\t\tpath:    \"/docker/09c89cd48b3597db904ab8e6920fef2cbf93588d037d9613ce362e25188f8ec6\",\n\t},\n}\n\nfunc TestGetCgroupPath(t *testing.T) {\n\tfor _, cgroup := range cgroupCases {\n\t\tt.Run(cgroup.name, func(tt *testing.T) {\n\t\t\tcd := &containerData{}\n\t\t\tpath := cd.getCgroupPath(cgroup.cgroups)\n\t\t\tassert.Equal(t, cgroup.path, path)\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "manager/manager.go",
    "content": "// Copyright 2014 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n//go:build linux\n\n// Manager of cAdvisor-monitored containers.\npackage manager\n\nimport (\n\t\"flag\"\n\t\"fmt\"\n\t\"net/http\"\n\t\"os\"\n\t\"path\"\n\t\"strconv\"\n\t\"strings\"\n\t\"sync\"\n\t\"sync/atomic\"\n\t\"time\"\n\n\t\"github.com/google/cadvisor/cache/memory\"\n\t\"github.com/google/cadvisor/collector\"\n\t\"github.com/google/cadvisor/container\"\n\t\"github.com/google/cadvisor/container/raw\"\n\t\"github.com/google/cadvisor/events\"\n\t\"github.com/google/cadvisor/fs\"\n\tinfo \"github.com/google/cadvisor/info/v1\"\n\tv2 \"github.com/google/cadvisor/info/v2\"\n\t\"github.com/google/cadvisor/machine\"\n\t\"github.com/google/cadvisor/nvm\"\n\t\"github.com/google/cadvisor/perf\"\n\t\"github.com/google/cadvisor/resctrl\"\n\t\"github.com/google/cadvisor/stats\"\n\t\"github.com/google/cadvisor/utils/oomparser\"\n\t\"github.com/google/cadvisor/utils/sysfs\"\n\t\"github.com/google/cadvisor/version\"\n\t\"github.com/google/cadvisor/watcher\"\n\n\t\"github.com/opencontainers/cgroups\"\n\n\t\"k8s.io/klog/v2\"\n\t\"k8s.io/utils/clock\"\n)\n\nvar globalHousekeepingInterval = flag.Duration(\"global_housekeeping_interval\", 1*time.Minute, \"Interval between global housekeepings\")\nvar updateMachineInfoInterval = flag.Duration(\"update_machine_info_interval\", 5*time.Minute, \"Interval between machine info updates.\")\nvar logCadvisorUsage = flag.Bool(\"log_cadvisor_usage\", false, \"Whether to log the usage of the cAdvisor container\")\nvar eventStorageAgeLimit = flag.String(\"event_storage_age_limit\", \"default=24h\", \"Max length of time for which to store events (per type). Value is a comma separated list of key values, where the keys are event types (e.g.: creation, oom) or \\\"default\\\" and the value is a duration. Default is applied to all non-specified event types\")\nvar eventStorageEventLimit = flag.String(\"event_storage_event_limit\", \"default=100000\", \"Max number of events to store (per type). Value is a comma separated list of key values, where the keys are event types (e.g.: creation, oom) or \\\"default\\\" and the value is an integer. Default is applied to all non-specified event types\")\nvar applicationMetricsCountLimit = flag.Int(\"application_metrics_count_limit\", 100, \"Max number of application metrics to store (per container)\")\n\n// The namespace under which aliases are unique.\nconst (\n\tDockerNamespace = \"docker\"\n\tPodmanNamespace = \"podman\"\n)\n\nvar HousekeepingConfigFlags = HousekeepingConfig{\n\tflag.Duration(\"max_housekeeping_interval\", 60*time.Second, \"Largest interval to allow between container housekeepings\"),\n\tflag.Bool(\"allow_dynamic_housekeeping\", true, \"Whether to allow the housekeeping interval to be dynamic\"),\n}\n\n// The Manager interface defines operations for starting a manager and getting\n// container and machine information.\ntype Manager interface {\n\t// Start the manager. Calling other manager methods before this returns\n\t// may produce undefined behavior.\n\tStart() error\n\n\t// Stops the manager.\n\tStop() error\n\n\t//  information about a container.\n\tGetContainerInfo(containerName string, query *info.ContainerInfoRequest) (*info.ContainerInfo, error)\n\n\t// Get V2 information about a container.\n\t// Recursive (subcontainer) requests are best-effort, and may return a partial result alongside an\n\t// error in the partial failure case.\n\tGetContainerInfoV2(containerName string, options v2.RequestOptions) (map[string]v2.ContainerInfo, error)\n\n\t// Get information about all subcontainers of the specified container (includes self).\n\tSubcontainersInfo(containerName string, query *info.ContainerInfoRequest) ([]*info.ContainerInfo, error)\n\n\t// Gets all the Docker containers. Return is a map from full container name to ContainerInfo.\n\tAllDockerContainers(query *info.ContainerInfoRequest) (map[string]info.ContainerInfo, error)\n\n\t// Gets information about a specific Docker container. The specified name is within the Docker namespace.\n\tDockerContainer(dockerName string, query *info.ContainerInfoRequest) (info.ContainerInfo, error)\n\n\t// Gets spec for all containers based on request options.\n\tGetContainerSpec(containerName string, options v2.RequestOptions) (map[string]v2.ContainerSpec, error)\n\n\t// Gets summary stats for all containers based on request options.\n\tGetDerivedStats(containerName string, options v2.RequestOptions) (map[string]v2.DerivedStats, error)\n\n\t// Get info for all requested containers based on the request options.\n\tGetRequestedContainersInfo(containerName string, options v2.RequestOptions) (map[string]*info.ContainerInfo, error)\n\n\t// Returns true if the named container exists.\n\tExists(containerName string) bool\n\n\t// Get information about the machine.\n\tGetMachineInfo() (*info.MachineInfo, error)\n\n\t// Get version information about different components we depend on.\n\tGetVersionInfo() (*info.VersionInfo, error)\n\n\t// GetFsInfoByFsUUID returns the information of the device having the\n\t// specified filesystem uuid. If no such device with the UUID exists, this\n\t// function will return the fs.ErrNoSuchDevice error.\n\tGetFsInfoByFsUUID(uuid string) (v2.FsInfo, error)\n\n\t// Get filesystem information for the filesystem that contains the given directory\n\tGetDirFsInfo(dir string) (v2.FsInfo, error)\n\n\t// Get filesystem information for a given label.\n\t// Returns information for all global filesystems if label is empty.\n\tGetFsInfo(label string) ([]v2.FsInfo, error)\n\n\t// Get ps output for a container.\n\tGetProcessList(containerName string, options v2.RequestOptions) ([]v2.ProcessInfo, error)\n\n\t// Get events streamed through passedChannel that fit the request.\n\tWatchForEvents(request *events.Request) (*events.EventChannel, error)\n\n\t// Get past events that have been detected and that fit the request.\n\tGetPastEvents(request *events.Request) ([]*info.Event, error)\n\n\tCloseEventChannel(watchID int)\n\n\t// Returns debugging information. Map of lines per category.\n\tDebugInfo() map[string][]string\n\n\tAllPodmanContainers(c *info.ContainerInfoRequest) (map[string]info.ContainerInfo, error)\n\n\tPodmanContainer(containerName string, query *info.ContainerInfoRequest) (info.ContainerInfo, error)\n}\n\n// Housekeeping configuration for the manager\ntype HousekeepingConfig = struct {\n\tInterval     *time.Duration\n\tAllowDynamic *bool\n}\n\n// New takes a memory storage and returns a new manager.\nfunc New(memoryCache *memory.InMemoryCache, sysfs sysfs.SysFs, HousekeepingConfig HousekeepingConfig, includedMetricsSet container.MetricSet, collectorHTTPClient *http.Client, rawContainerCgroupPathPrefixWhiteList, containerEnvMetadataWhiteList []string, perfEventsFile string, resctrlInterval time.Duration) (Manager, error) {\n\tif memoryCache == nil {\n\t\treturn nil, fmt.Errorf(\"manager requires memory storage\")\n\t}\n\n\t// Detect the container we are running on.\n\tselfContainer := \"/\"\n\tvar err error\n\t// Avoid using GetOwnCgroupPath on cgroup v2 as it is not supported by libcontainer\n\tif !cgroups.IsCgroup2UnifiedMode() {\n\t\tselfContainer, err = cgroups.GetOwnCgroup(\"cpu\")\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tklog.V(2).Infof(\"cAdvisor running in container: %q\", selfContainer)\n\t}\n\n\tcontext := fs.Context{}\n\n\tif err := container.InitializeFSContext(&context); err != nil {\n\t\treturn nil, err\n\t}\n\n\tfsInfo, err := fs.NewFsInfo(context)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\t// If cAdvisor was started with host's rootfs mounted, assume that its running\n\t// in its own namespaces.\n\tinHostNamespace := false\n\tif _, err := os.Stat(\"/rootfs/proc\"); os.IsNotExist(err) {\n\t\tinHostNamespace = true\n\t}\n\n\t// Register for new subcontainers.\n\teventsChannel := make(chan watcher.ContainerEvent, 16)\n\n\tnewManager := &manager{\n\t\tquitChannels:                          make([]chan error, 0, 2),\n\t\tmemoryCache:                           memoryCache,\n\t\tfsInfo:                                fsInfo,\n\t\tsysFs:                                 sysfs,\n\t\tcadvisorContainer:                     selfContainer,\n\t\tinHostNamespace:                       inHostNamespace,\n\t\tstartupTime:                           time.Now(),\n\t\tmaxHousekeepingInterval:               *HousekeepingConfig.Interval,\n\t\tallowDynamicHousekeeping:              *HousekeepingConfig.AllowDynamic,\n\t\tincludedMetrics:                       includedMetricsSet,\n\t\tcontainerWatchers:                     []watcher.ContainerWatcher{},\n\t\teventsChannel:                         eventsChannel,\n\t\tcollectorHTTPClient:                   collectorHTTPClient,\n\t\trawContainerCgroupPathPrefixWhiteList: rawContainerCgroupPathPrefixWhiteList,\n\t\tcontainerEnvMetadataWhiteList:         containerEnvMetadataWhiteList,\n\t}\n\n\tmachineInfo, err := machine.Info(sysfs, fsInfo, inHostNamespace)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tnewManager.machineInfo = *machineInfo\n\tklog.V(1).Infof(\"Machine: %+v\", newManager.machineInfo)\n\n\tnewManager.perfManager, err = perf.NewManager(perfEventsFile, machineInfo.Topology)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tnewManager.resctrlManager, err = resctrl.NewManager(resctrlInterval, machineInfo.CPUVendorID, inHostNamespace)\n\tif err != nil {\n\t\tklog.V(4).Infof(\"Cannot gather resctrl metrics: %v\", err)\n\t}\n\n\tversionInfo, err := getVersionInfo()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tklog.V(1).Infof(\"Version: %+v\", *versionInfo)\n\n\tnewManager.eventHandler = events.NewEventManager(parseEventsStoragePolicy())\n\treturn newManager, nil\n}\n\n// A namespaced container name.\ntype namespacedContainerName struct {\n\t// The namespace of the container. Can be empty for the root namespace.\n\tNamespace string\n\n\t// The name of the container in this namespace.\n\tName string\n}\n\n// containerMap is a type-safe wrapper around sync.Map for storing containerData\n// keyed by namespacedContainerName.\ntype containerMap struct {\n\tm sync.Map\n}\n\n// Load returns the containerData for the given name, or nil if not found.\nfunc (c *containerMap) Load(name namespacedContainerName) (*containerData, bool) {\n\tv, ok := c.m.Load(name)\n\tif !ok {\n\t\treturn nil, false\n\t}\n\treturn v.(*containerData), true\n}\n\n// Store stores the containerData for the given name.\nfunc (c *containerMap) Store(name namespacedContainerName, data *containerData) {\n\tc.m.Store(name, data)\n}\n\n// Delete removes the containerData for the given name.\nfunc (c *containerMap) Delete(name namespacedContainerName) {\n\tc.m.Delete(name)\n}\n\n// Range calls f for each container in the map. If f returns false, iteration stops.\nfunc (c *containerMap) Range(f func(name namespacedContainerName, data *containerData) bool) {\n\tc.m.Range(func(key, value any) bool {\n\t\treturn f(key.(namespacedContainerName), value.(*containerData))\n\t})\n}\n\ntype manager struct {\n\tcontainers               containerMap\n\tmemoryCache              *memory.InMemoryCache\n\tfsInfo                   fs.FsInfo\n\tsysFs                    sysfs.SysFs\n\tmachineMu                sync.RWMutex // protects machineInfo\n\tmachineInfo              info.MachineInfo\n\tquitChannels             []chan error\n\tcadvisorContainer        string\n\tinHostNamespace          bool\n\teventHandler             events.EventManager\n\tstartupTime              time.Time\n\tmaxHousekeepingInterval  time.Duration\n\tallowDynamicHousekeeping bool\n\tincludedMetrics          container.MetricSet\n\tcontainerWatchers        []watcher.ContainerWatcher\n\teventsChannel            chan watcher.ContainerEvent\n\tcollectorHTTPClient      *http.Client\n\tperfManager              stats.Manager\n\tresctrlManager           resctrl.ResControlManager\n\t// List of raw container cgroup path prefix whitelist.\n\trawContainerCgroupPathPrefixWhiteList []string\n\t// List of container env prefix whitelist, the matched container envs would be collected into metrics as extra labels.\n\tcontainerEnvMetadataWhiteList []string\n}\n\nfunc (m *manager) PodmanContainer(containerName string, query *info.ContainerInfoRequest) (info.ContainerInfo, error) {\n\tcontainer, err := m.namespacedContainer(containerName, PodmanNamespace)\n\tif err != nil {\n\t\treturn info.ContainerInfo{}, err\n\t}\n\n\tinf, err := m.containerDataToContainerInfo(container, query)\n\tif err != nil {\n\t\treturn info.ContainerInfo{}, err\n\t}\n\treturn *inf, nil\n}\n\n// Start the container manager.\nfunc (m *manager) Start() error {\n\tm.containerWatchers = container.InitializePlugins(m, m.fsInfo, m.includedMetrics)\n\n\terr := raw.Register(m, m.fsInfo, m.includedMetrics, m.rawContainerCgroupPathPrefixWhiteList)\n\tif err != nil {\n\t\tklog.Errorf(\"Registration of the raw container factory failed: %v\", err)\n\t}\n\n\trawWatcher, err := raw.NewRawContainerWatcher(m.includedMetrics)\n\tif err != nil {\n\t\treturn err\n\t}\n\tm.containerWatchers = append(m.containerWatchers, rawWatcher)\n\n\t// Watch for OOMs.\n\terr = m.watchForNewOoms()\n\tif err != nil {\n\t\tklog.Warningf(\"Could not configure a source for OOM detection, disabling OOM events: %v\", err)\n\t}\n\n\t// If there are no factories, don't start any housekeeping and serve the information we do have.\n\tif !container.HasFactories() {\n\t\treturn nil\n\t}\n\n\t// Create root and then recover all containers.\n\terr = m.createContainer(\"/\", watcher.Raw)\n\tif err != nil {\n\t\treturn err\n\t}\n\tklog.V(2).Infof(\"Starting recovery of all containers\")\n\terr = m.detectSubcontainers(\"/\")\n\tif err != nil {\n\t\treturn err\n\t}\n\tklog.V(2).Infof(\"Recovery completed\")\n\n\t// Watch for new container.\n\tquitWatcher := make(chan error)\n\terr = m.watchForNewContainers(quitWatcher)\n\tif err != nil {\n\t\treturn err\n\t}\n\tm.quitChannels = append(m.quitChannels, quitWatcher)\n\n\t// Look for new containers in the main housekeeping thread.\n\tquitGlobalHousekeeping := make(chan error)\n\tm.quitChannels = append(m.quitChannels, quitGlobalHousekeeping)\n\tgo m.globalHousekeeping(quitGlobalHousekeeping)\n\n\tquitUpdateMachineInfo := make(chan error)\n\tm.quitChannels = append(m.quitChannels, quitUpdateMachineInfo)\n\tgo m.updateMachineInfo(quitUpdateMachineInfo)\n\n\treturn nil\n}\n\nfunc (m *manager) Stop() error {\n\tdefer m.destroyCollectors()\n\t// Stop and wait on all quit channels.\n\tfor i, c := range m.quitChannels {\n\t\t// Send the exit signal and wait on the thread to exit (by closing the channel).\n\t\tc <- nil\n\t\terr := <-c\n\t\tif err != nil {\n\t\t\t// Remove the channels that quit successfully.\n\t\t\tm.quitChannels = m.quitChannels[i:]\n\t\t\treturn err\n\t\t}\n\t}\n\tm.quitChannels = make([]chan error, 0, 2)\n\tnvm.Finalize()\n\tperf.Finalize()\n\treturn nil\n}\n\nfunc (m *manager) destroyCollectors() {\n\tm.containers.Range(func(_ namespacedContainerName, container *containerData) bool {\n\t\tif container == nil {\n\t\t\treturn true\n\t\t}\n\t\tcontainer.perfCollector.Destroy()\n\t\tcontainer.resctrlCollector.Destroy()\n\t\treturn true\n\t})\n}\n\nfunc (m *manager) updateMachineInfo(quit chan error) {\n\tticker := time.NewTicker(*updateMachineInfoInterval)\n\tfor {\n\t\tselect {\n\t\tcase <-ticker.C:\n\t\t\tinfo, err := machine.Info(m.sysFs, m.fsInfo, m.inHostNamespace)\n\t\t\tif err != nil {\n\t\t\t\tklog.Errorf(\"Could not get machine info: %v\", err)\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tm.machineMu.Lock()\n\t\t\tm.machineInfo = *info\n\t\t\tm.machineMu.Unlock()\n\t\t\tklog.V(5).Infof(\"Update machine info: %+v\", *info)\n\t\tcase <-quit:\n\t\t\tticker.Stop()\n\t\t\tquit <- nil\n\t\t\treturn\n\t\t}\n\t}\n}\n\nfunc (m *manager) globalHousekeeping(quit chan error) {\n\t// Long housekeeping is either 100ms or half of the housekeeping interval.\n\tlongHousekeeping := 100 * time.Millisecond\n\tif *globalHousekeepingInterval/2 < longHousekeeping {\n\t\tlongHousekeeping = *globalHousekeepingInterval / 2\n\t}\n\n\tticker := time.NewTicker(*globalHousekeepingInterval)\n\tfor {\n\t\tselect {\n\t\tcase t := <-ticker.C:\n\t\t\tstart := time.Now()\n\n\t\t\t// Check for new containers.\n\t\t\terr := m.detectSubcontainers(\"/\")\n\t\t\tif err != nil {\n\t\t\t\tklog.Errorf(\"Failed to detect containers: %s\", err)\n\t\t\t}\n\n\t\t\t// Log if housekeeping took too long.\n\t\t\tduration := time.Since(start)\n\t\t\tif duration >= longHousekeeping {\n\t\t\t\tklog.V(3).Infof(\"Global Housekeeping(%d) took %s\", t.Unix(), duration)\n\t\t\t}\n\t\tcase <-quit:\n\t\t\t// Quit if asked to do so.\n\t\t\tquit <- nil\n\t\t\tklog.Infof(\"Exiting global housekeeping thread\")\n\t\t\treturn\n\t\t}\n\t}\n}\n\nfunc (m *manager) getContainerData(containerName string) (*containerData, error) {\n\t// Ensure we have the container.\n\tcont, ok := m.containers.Load(namespacedContainerName{Name: containerName})\n\tif !ok {\n\t\treturn nil, fmt.Errorf(\"unknown container %q\", containerName)\n\t}\n\treturn cont, nil\n}\n\nfunc (m *manager) GetDerivedStats(containerName string, options v2.RequestOptions) (map[string]v2.DerivedStats, error) {\n\tconts, err := m.getRequestedContainers(containerName, options)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tvar errs partialFailure\n\tstats := make(map[string]v2.DerivedStats)\n\tfor name, cont := range conts {\n\t\td, err := cont.DerivedStats()\n\t\tif err != nil {\n\t\t\terrs.append(name, \"DerivedStats\", err)\n\t\t}\n\t\tstats[name] = d\n\t}\n\treturn stats, errs.OrNil()\n}\n\nfunc (m *manager) GetContainerSpec(containerName string, options v2.RequestOptions) (map[string]v2.ContainerSpec, error) {\n\tconts, err := m.getRequestedContainers(containerName, options)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tvar errs partialFailure\n\tspecs := make(map[string]v2.ContainerSpec)\n\tfor name, cont := range conts {\n\t\tcinfo, err := cont.GetInfo(false)\n\t\tif err != nil {\n\t\t\terrs.append(name, \"GetInfo\", err)\n\t\t}\n\t\tspec := m.getV2Spec(cinfo)\n\t\tspecs[name] = spec\n\t}\n\treturn specs, errs.OrNil()\n}\n\n// Get V2 container spec from v1 container info.\nfunc (m *manager) getV2Spec(cinfo *containerInfo) v2.ContainerSpec {\n\tspec := m.getAdjustedSpec(cinfo)\n\treturn v2.ContainerSpecFromV1(&spec, cinfo.Aliases, cinfo.Namespace)\n}\n\nfunc (m *manager) getAdjustedSpec(cinfo *containerInfo) info.ContainerSpec {\n\tspec := cinfo.Spec\n\n\t// Set default value to an actual value\n\tif spec.HasMemory {\n\t\t// Memory.Limit is 0 means there's no limit\n\t\tif spec.Memory.Limit == 0 {\n\t\t\tm.machineMu.RLock()\n\t\t\tspec.Memory.Limit = uint64(m.machineInfo.MemoryCapacity)\n\t\t\tm.machineMu.RUnlock()\n\t\t}\n\t}\n\treturn spec\n}\n\nfunc (m *manager) GetContainerInfo(containerName string, query *info.ContainerInfoRequest) (*info.ContainerInfo, error) {\n\tcont, err := m.getContainerData(containerName)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn m.containerDataToContainerInfo(cont, query)\n}\n\nfunc (m *manager) GetContainerInfoV2(containerName string, options v2.RequestOptions) (map[string]v2.ContainerInfo, error) {\n\tcontainers, err := m.getRequestedContainers(containerName, options)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tvar errs partialFailure\n\tvar nilTime time.Time // Ignored.\n\n\tinfos := make(map[string]v2.ContainerInfo, len(containers))\n\tfor name, container := range containers {\n\t\tresult := v2.ContainerInfo{}\n\t\tcinfo, err := container.GetInfo(false)\n\t\tif err != nil {\n\t\t\terrs.append(name, \"GetInfo\", err)\n\t\t\tinfos[name] = result\n\t\t\tcontinue\n\t\t}\n\t\tresult.Spec = m.getV2Spec(cinfo)\n\n\t\tstats, err := m.memoryCache.RecentStats(name, nilTime, nilTime, options.Count)\n\t\tif err != nil {\n\t\t\terrs.append(name, \"RecentStats\", err)\n\t\t\tinfos[name] = result\n\t\t\tcontinue\n\t\t}\n\n\t\tresult.Stats = v2.ContainerStatsFromV1(containerName, &cinfo.Spec, stats)\n\t\tinfos[name] = result\n\t}\n\n\treturn infos, errs.OrNil()\n}\n\nfunc (m *manager) containerDataToContainerInfo(cont *containerData, query *info.ContainerInfoRequest) (*info.ContainerInfo, error) {\n\t// Get the info from the container.\n\tcinfo, err := cont.GetInfo(true)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tstats, err := m.memoryCache.RecentStats(cinfo.Name, query.Start, query.End, query.NumStats)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\t// Make a copy of the info for the user.\n\tret := &info.ContainerInfo{\n\t\tContainerReference: cinfo.ContainerReference,\n\t\tSubcontainers:      cinfo.Subcontainers,\n\t\tSpec:               m.getAdjustedSpec(cinfo),\n\t\tStats:              stats,\n\t}\n\treturn ret, nil\n}\n\nfunc (m *manager) getContainer(containerName string) (*containerData, error) {\n\tcont, ok := m.containers.Load(namespacedContainerName{Name: containerName})\n\tif !ok {\n\t\treturn nil, fmt.Errorf(\"unknown container %q\", containerName)\n\t}\n\treturn cont, nil\n}\n\nfunc (m *manager) getSubcontainers(containerName string) map[string]*containerData {\n\tmatchedName := path.Join(containerName, \"/\")\n\tcontainersMap := make(map[string]*containerData)\n\n\t// Get all the unique subcontainers of the specified container\n\tm.containers.Range(func(_ namespacedContainerName, cont *containerData) bool {\n\t\tif cont == nil {\n\t\t\treturn true\n\t\t}\n\t\tname := cont.info.Name\n\t\tif name == containerName || strings.HasPrefix(name, matchedName) {\n\t\t\tcontainersMap[name] = cont\n\t\t}\n\t\treturn true\n\t})\n\treturn containersMap\n}\n\nfunc (m *manager) SubcontainersInfo(containerName string, query *info.ContainerInfoRequest) ([]*info.ContainerInfo, error) {\n\tcontainersMap := m.getSubcontainers(containerName)\n\n\tcontainers := make([]*containerData, 0, len(containersMap))\n\tfor _, cont := range containersMap {\n\t\tcontainers = append(containers, cont)\n\t}\n\treturn m.containerDataSliceToContainerInfoSlice(containers, query)\n}\n\nfunc (m *manager) getAllNamespacedContainers(ns string) map[string]*containerData {\n\tcontainers := make(map[string]*containerData)\n\n\t// Get containers in a namespace.\n\tm.containers.Range(func(name namespacedContainerName, cont *containerData) bool {\n\t\tif cont == nil {\n\t\t\treturn true\n\t\t}\n\t\tif name.Namespace == ns {\n\t\t\tcontainers[cont.info.Name] = cont\n\t\t}\n\t\treturn true\n\t})\n\treturn containers\n}\n\nfunc (m *manager) AllDockerContainers(query *info.ContainerInfoRequest) (map[string]info.ContainerInfo, error) {\n\tcontainers := m.getAllNamespacedContainers(DockerNamespace)\n\treturn m.containersInfo(containers, query)\n}\n\nfunc (m *manager) namespacedContainer(containerName string, ns string) (*containerData, error) {\n\t// Check for the container in the namespace.\n\tif cont, ok := m.containers.Load(namespacedContainerName{Namespace: ns, Name: containerName}); ok {\n\t\treturn cont, nil\n\t}\n\n\t// Look for container by short prefix name if no exact match found.\n\tvar cont *containerData\n\tvar err error\n\tm.containers.Range(func(name namespacedContainerName, c *containerData) bool {\n\t\tif name.Namespace == ns && strings.HasPrefix(name.Name, containerName) {\n\t\t\tif cont == nil {\n\t\t\t\tcont = c\n\t\t\t} else {\n\t\t\t\terr = fmt.Errorf(\"unable to find container in %q namespace. Container %q is not unique\", ns, containerName)\n\t\t\t\treturn false // stop iteration\n\t\t\t}\n\t\t}\n\t\treturn true\n\t})\n\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tif cont == nil {\n\t\treturn nil, fmt.Errorf(\"unable to find container %q in %q namespace\", containerName, ns)\n\t}\n\n\treturn cont, nil\n}\n\nfunc (m *manager) DockerContainer(containerName string, query *info.ContainerInfoRequest) (info.ContainerInfo, error) {\n\tcontainer, err := m.namespacedContainer(containerName, DockerNamespace)\n\tif err != nil {\n\t\treturn info.ContainerInfo{}, err\n\t}\n\n\tinf, err := m.containerDataToContainerInfo(container, query)\n\tif err != nil {\n\t\treturn info.ContainerInfo{}, err\n\t}\n\treturn *inf, nil\n}\n\nfunc (m *manager) containerDataSliceToContainerInfoSlice(containers []*containerData, query *info.ContainerInfoRequest) ([]*info.ContainerInfo, error) {\n\tif len(containers) == 0 {\n\t\treturn nil, fmt.Errorf(\"no containers found\")\n\t}\n\n\t// Get the info for each container.\n\toutput := make([]*info.ContainerInfo, 0, len(containers))\n\tfor i := range containers {\n\t\tcinfo, err := m.containerDataToContainerInfo(containers[i], query)\n\t\tif err != nil {\n\t\t\t// Skip containers with errors, we try to degrade gracefully.\n\t\t\tklog.V(4).Infof(\"convert container data to container info failed with error %s\", err.Error())\n\t\t\tcontinue\n\t\t}\n\t\toutput = append(output, cinfo)\n\t}\n\n\treturn output, nil\n}\n\nfunc (m *manager) GetRequestedContainersInfo(containerName string, options v2.RequestOptions) (map[string]*info.ContainerInfo, error) {\n\tcontainers, err := m.getRequestedContainers(containerName, options)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tvar errs partialFailure\n\tcontainersMap := make(map[string]*info.ContainerInfo)\n\tquery := info.ContainerInfoRequest{\n\t\tNumStats: options.Count,\n\t}\n\tfor name, data := range containers {\n\t\tinfo, err := m.containerDataToContainerInfo(data, &query)\n\t\tif err != nil {\n\t\t\tif err == memory.ErrDataNotFound {\n\t\t\t\tklog.V(4).Infof(\"Error getting data for container %s because of race condition\", name)\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\terrs.append(name, \"containerDataToContainerInfo\", err)\n\t\t}\n\t\tcontainersMap[name] = info\n\t}\n\treturn containersMap, errs.OrNil()\n}\n\nfunc (m *manager) getRequestedContainers(containerName string, options v2.RequestOptions) (map[string]*containerData, error) {\n\tcontainersMap := make(map[string]*containerData)\n\tswitch options.IdType {\n\tcase v2.TypeName:\n\t\tif !options.Recursive {\n\t\t\tcont, err := m.getContainer(containerName)\n\t\t\tif err != nil {\n\t\t\t\treturn containersMap, err\n\t\t\t}\n\t\t\tcontainersMap[cont.info.Name] = cont\n\t\t} else {\n\t\t\tcontainersMap = m.getSubcontainers(containerName)\n\t\t\tif len(containersMap) == 0 {\n\t\t\t\treturn containersMap, fmt.Errorf(\"unknown container: %q\", containerName)\n\t\t\t}\n\t\t}\n\tcase v2.TypeDocker, v2.TypePodman:\n\t\tnamespace := map[string]string{\n\t\t\tv2.TypeDocker: DockerNamespace,\n\t\t\tv2.TypePodman: PodmanNamespace,\n\t\t}[options.IdType]\n\t\tif !options.Recursive {\n\t\t\tcontainerName = strings.TrimPrefix(containerName, \"/\")\n\t\t\tcont, err := m.namespacedContainer(containerName, namespace)\n\t\t\tif err != nil {\n\t\t\t\treturn containersMap, err\n\t\t\t}\n\t\t\tcontainersMap[cont.info.Name] = cont\n\t\t} else {\n\t\t\tif containerName != \"/\" {\n\t\t\t\treturn containersMap, fmt.Errorf(\"invalid request for %s container %q with subcontainers\", options.IdType, containerName)\n\t\t\t}\n\t\t\tcontainersMap = m.getAllNamespacedContainers(namespace)\n\t\t}\n\tdefault:\n\t\treturn containersMap, fmt.Errorf(\"invalid request type %q\", options.IdType)\n\t}\n\tif options.MaxAge != nil {\n\t\t// update stats for all containers in containersMap\n\t\tvar waitGroup sync.WaitGroup\n\t\twaitGroup.Add(len(containersMap))\n\t\tfor _, container := range containersMap {\n\t\t\tgo func(cont *containerData) {\n\t\t\t\tcont.OnDemandHousekeeping(*options.MaxAge)\n\t\t\t\twaitGroup.Done()\n\t\t\t}(container)\n\t\t}\n\t\twaitGroup.Wait()\n\t}\n\treturn containersMap, nil\n}\n\nfunc (m *manager) GetDirFsInfo(dir string) (v2.FsInfo, error) {\n\tdevice, err := m.fsInfo.GetDirFsDevice(dir)\n\tif err != nil {\n\t\treturn v2.FsInfo{}, fmt.Errorf(\"failed to get device for dir %q: %v\", dir, err)\n\t}\n\treturn m.getFsInfoByDeviceName(device.Device)\n}\n\nfunc (m *manager) GetFsInfoByFsUUID(uuid string) (v2.FsInfo, error) {\n\tdevice, err := m.fsInfo.GetDeviceInfoByFsUUID(uuid)\n\tif err != nil {\n\t\treturn v2.FsInfo{}, err\n\t}\n\treturn m.getFsInfoByDeviceName(device.Device)\n}\n\nfunc (m *manager) GetFsInfo(label string) ([]v2.FsInfo, error) {\n\tvar empty time.Time\n\t// Get latest data from filesystems hanging off root container.\n\tstats, err := m.memoryCache.RecentStats(\"/\", empty, empty, 1)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tdev := \"\"\n\tif len(label) != 0 {\n\t\tdev, err = m.fsInfo.GetDeviceForLabel(label)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\tfsInfo := []v2.FsInfo{}\n\tfor i := range stats[0].Filesystem {\n\t\tfs := stats[0].Filesystem[i]\n\t\tif len(label) != 0 && fs.Device != dev {\n\t\t\tcontinue\n\t\t}\n\t\tmountpoint, err := m.fsInfo.GetMountpointForDevice(fs.Device)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tlabels, err := m.fsInfo.GetLabelsForDevice(fs.Device)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\tfi := v2.FsInfo{\n\t\t\tTimestamp:  stats[0].Timestamp,\n\t\t\tDevice:     fs.Device,\n\t\t\tMountpoint: mountpoint,\n\t\t\tCapacity:   fs.Limit,\n\t\t\tUsage:      fs.Usage,\n\t\t\tAvailable:  fs.Available,\n\t\t\tLabels:     labels,\n\t\t}\n\t\tif fs.HasInodes {\n\t\t\tfi.Inodes = &fs.Inodes\n\t\t\tfi.InodesFree = &fs.InodesFree\n\t\t}\n\t\tfsInfo = append(fsInfo, fi)\n\t}\n\treturn fsInfo, nil\n}\n\nfunc (m *manager) GetMachineInfo() (*info.MachineInfo, error) {\n\tm.machineMu.RLock()\n\tdefer m.machineMu.RUnlock()\n\treturn m.machineInfo.Clone(), nil\n}\n\nfunc (m *manager) GetVersionInfo() (*info.VersionInfo, error) {\n\t// TODO: Consider caching this and periodically updating.  The VersionInfo may change if\n\t// the docker daemon is started after the cAdvisor client is created.  Caching the value\n\t// would be helpful so we would be able to return the last known docker version if\n\t// docker was down at the time of a query.\n\treturn getVersionInfo()\n}\n\nfunc (m *manager) Exists(containerName string) bool {\n\t_, ok := m.containers.Load(namespacedContainerName{Name: containerName})\n\treturn ok\n}\n\nfunc (m *manager) GetProcessList(containerName string, options v2.RequestOptions) ([]v2.ProcessInfo, error) {\n\t// override recursive. Only support single container listing.\n\toptions.Recursive = false\n\t// override MaxAge.  ProcessList does not require updated stats.\n\toptions.MaxAge = nil\n\tconts, err := m.getRequestedContainers(containerName, options)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif len(conts) != 1 {\n\t\treturn nil, fmt.Errorf(\"expected the request to match only one container\")\n\t}\n\t// TODO(rjnagal): handle count? Only if we can do count by type (eg. top 5 cpu users)\n\tps := []v2.ProcessInfo{}\n\tfor _, cont := range conts {\n\t\tps, err = cont.GetProcessList(m.cadvisorContainer, m.inHostNamespace)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\treturn ps, nil\n}\n\nfunc (m *manager) registerCollectors(collectorConfigs map[string]string, cont *containerData) error {\n\tfor k, v := range collectorConfigs {\n\t\tconfigFile, err := cont.ReadFile(v, m.inHostNamespace)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"failed to read config file %q for config %q, container %q: %v\", k, v, cont.info.Name, err)\n\t\t}\n\t\tklog.V(4).Infof(\"Got config from %q: %q\", v, configFile)\n\n\t\tif strings.HasPrefix(k, \"prometheus\") || strings.HasPrefix(k, \"Prometheus\") {\n\t\t\tnewCollector, err := collector.NewPrometheusCollector(k, configFile, *applicationMetricsCountLimit, cont.handler, m.collectorHTTPClient)\n\t\t\tif err != nil {\n\t\t\t\treturn fmt.Errorf(\"failed to create collector for container %q, config %q: %v\", cont.info.Name, k, err)\n\t\t\t}\n\t\t\terr = cont.collectorManager.RegisterCollector(newCollector)\n\t\t\tif err != nil {\n\t\t\t\treturn fmt.Errorf(\"failed to register collector for container %q, config %q: %v\", cont.info.Name, k, err)\n\t\t\t}\n\t\t} else {\n\t\t\tnewCollector, err := collector.NewCollector(k, configFile, *applicationMetricsCountLimit, cont.handler, m.collectorHTTPClient)\n\t\t\tif err != nil {\n\t\t\t\treturn fmt.Errorf(\"failed to create collector for container %q, config %q: %v\", cont.info.Name, k, err)\n\t\t\t}\n\t\t\terr = cont.collectorManager.RegisterCollector(newCollector)\n\t\t\tif err != nil {\n\t\t\t\treturn fmt.Errorf(\"failed to register collector for container %q, config %q: %v\", cont.info.Name, k, err)\n\t\t\t}\n\t\t}\n\t}\n\treturn nil\n}\n\n// Create a container.\nfunc (m *manager) createContainer(containerName string, watchSource watcher.ContainerWatchSource) error {\n\tnamespacedName := namespacedContainerName{\n\t\tName: containerName,\n\t}\n\n\t// Check that the container didn't already exist.\n\tif _, ok := m.containers.Load(namespacedName); ok {\n\t\treturn nil\n\t}\n\n\thandler, accept, err := container.NewContainerHandler(containerName, watchSource, m.containerEnvMetadataWhiteList, m.inHostNamespace)\n\tif err != nil {\n\t\treturn err\n\t}\n\tif !accept {\n\t\t// ignoring this container.\n\t\tklog.V(4).Infof(\"ignoring container %q\", containerName)\n\t\treturn nil\n\t}\n\tcollectorManager, err := collector.NewCollectorManager()\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tlogUsage := *logCadvisorUsage && containerName == m.cadvisorContainer\n\tcont, err := newContainerData(containerName, m.memoryCache, handler, logUsage, collectorManager, m.maxHousekeepingInterval, m.allowDynamicHousekeeping, clock.RealClock{})\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tif m.includedMetrics.Has(container.PerfMetrics) {\n\t\tperfCgroupPath, err := handler.GetCgroupPath(\"perf_event\")\n\t\tif err != nil {\n\t\t\tklog.Warningf(\"Error getting perf_event cgroup path: %q\", err)\n\t\t} else {\n\t\t\tcont.perfCollector, err = m.perfManager.GetCollector(perfCgroupPath)\n\t\t\tif err != nil {\n\t\t\t\tklog.Errorf(\"Perf event metrics will not be available for container %q: %v\", containerName, err)\n\t\t\t}\n\t\t}\n\t}\n\n\tif m.includedMetrics.Has(container.ResctrlMetrics) {\n\t\tm.machineMu.Lock()\n\t\tnoOfNUMA := len(m.machineInfo.Topology)\n\t\tm.machineMu.Unlock()\n\t\tcont.resctrlCollector, err = m.resctrlManager.GetCollector(containerName, func() ([]string, error) {\n\t\t\treturn cont.getContainerPids(m.inHostNamespace)\n\t\t}, noOfNUMA)\n\t\tif err != nil {\n\t\t\tklog.V(4).Infof(\"resctrl metrics will not be available for container %s: %s\", cont.info.Name, err)\n\t\t}\n\t}\n\n\t// Add collectors\n\tlabels := handler.GetContainerLabels()\n\tcollectorConfigs := collector.GetCollectorConfigs(labels)\n\terr = m.registerCollectors(collectorConfigs, cont)\n\tif err != nil {\n\t\tklog.Warningf(\"Failed to register collectors for %q: %v\", containerName, err)\n\t}\n\n\t// Add the container name and all its aliases. The aliases must be within the namespace of the factory.\n\tm.containers.Store(namespacedName, cont)\n\tfor _, alias := range cont.info.Aliases {\n\t\tm.containers.Store(namespacedContainerName{\n\t\t\tNamespace: cont.info.Namespace,\n\t\t\tName:      alias,\n\t\t}, cont)\n\t}\n\n\tklog.V(3).Infof(\"Added container: %q (aliases: %v, namespace: %q)\", containerName, cont.info.Aliases, cont.info.Namespace)\n\n\tcontSpec, err := cont.handler.GetSpec()\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tcontRef, err := cont.handler.ContainerReference()\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tnewEvent := &info.Event{\n\t\tContainerName: contRef.Name,\n\t\tTimestamp:     contSpec.CreationTime,\n\t\tEventType:     info.EventContainerCreation,\n\t}\n\terr = m.eventHandler.AddEvent(newEvent)\n\tif err != nil {\n\t\treturn err\n\t}\n\t// Start the container's housekeeping.\n\treturn cont.Start()\n}\n\nfunc (m *manager) destroyContainer(containerName string) error {\n\tnamespacedName := namespacedContainerName{\n\t\tName: containerName,\n\t}\n\tcont, ok := m.containers.Load(namespacedName)\n\tif !ok {\n\t\t// Already destroyed, done.\n\t\treturn nil\n\t}\n\n\texitCode, err := cont.handler.GetExitCode()\n\tif err != nil {\n\t\tklog.V(4).Infof(\"Could not retrieve exit code for container %q: %v (using -1)\", containerName, err)\n\t\texitCode = -1\n\t}\n\n\terr = cont.Stop()\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t// Remove the container from our records (and all its aliases).\n\tm.containers.Delete(namespacedName)\n\tfor _, alias := range cont.info.Aliases {\n\t\tm.containers.Delete(namespacedContainerName{\n\t\t\tNamespace: cont.info.Namespace,\n\t\t\tName:      alias,\n\t\t})\n\t}\n\tklog.V(3).Infof(\"Destroyed container: %q (aliases: %v, namespace: %q, exit_code: %d)\", containerName, cont.info.Aliases, cont.info.Namespace, exitCode)\n\n\tcontRef, err := cont.handler.ContainerReference()\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tnewEvent := &info.Event{\n\t\tContainerName: contRef.Name,\n\t\tTimestamp:     time.Now(),\n\t\tEventType:     info.EventContainerDeletion,\n\t\tEventData: info.EventData{\n\t\t\tContainerDeletion: &info.ContainerDeletionEventData{\n\t\t\t\tExitCode: exitCode,\n\t\t\t},\n\t\t},\n\t}\n\terr = m.eventHandler.AddEvent(newEvent)\n\tif err != nil {\n\t\treturn err\n\t}\n\treturn nil\n}\n\n// Detect all containers that have been added or deleted from the specified container.\nfunc (m *manager) getContainersDiff(containerName string) (added []info.ContainerReference, removed []info.ContainerReference, err error) {\n\t// Get all subcontainers recursively.\n\tcont, ok := m.containers.Load(namespacedContainerName{Name: containerName})\n\tif !ok {\n\t\treturn nil, nil, fmt.Errorf(\"failed to find container %q while checking for new containers\", containerName)\n\t}\n\tallContainers, err := cont.handler.ListContainers(container.ListRecursive)\n\n\tif err != nil {\n\t\treturn nil, nil, err\n\t}\n\tallContainers = append(allContainers, info.ContainerReference{Name: containerName})\n\n\t// Determine which were added and which were removed.\n\tallContainersSet := make(map[string]*containerData)\n\tm.containers.Range(func(name namespacedContainerName, cont *containerData) bool {\n\t\tif cont == nil {\n\t\t\treturn true\n\t\t}\n\t\t// Only add the canonical name.\n\t\tif cont.info.Name == name.Name {\n\t\t\tallContainersSet[name.Name] = cont\n\t\t}\n\t\treturn true\n\t})\n\n\t// Added containers\n\tfor _, c := range allContainers {\n\t\tdelete(allContainersSet, c.Name)\n\t\t_, ok := m.containers.Load(namespacedContainerName{Name: c.Name})\n\t\tif !ok {\n\t\t\tadded = append(added, c)\n\t\t}\n\t}\n\n\t// Removed ones are no longer in the container listing.\n\tfor _, d := range allContainersSet {\n\t\tremoved = append(removed, d.info.ContainerReference)\n\t}\n\n\treturn\n}\n\n// Detect the existing subcontainers and reflect the setup here.\nfunc (m *manager) detectSubcontainers(containerName string) error {\n\tadded, removed, err := m.getContainersDiff(containerName)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t// Add the new containers.\n\tfor _, cont := range added {\n\t\terr = m.createContainer(cont.Name, watcher.Raw)\n\t\tif err != nil {\n\t\t\tklog.Errorf(\"Failed to create existing container: %s: %s\", cont.Name, err)\n\t\t}\n\t}\n\n\t// Remove the old containers.\n\tfor _, cont := range removed {\n\t\terr = m.destroyContainer(cont.Name)\n\t\tif err != nil {\n\t\t\tklog.Errorf(\"Failed to destroy existing container: %s: %s\", cont.Name, err)\n\t\t}\n\t}\n\n\treturn nil\n}\n\n// Watches for new containers started in the system. Runs forever unless there is a setup error.\nfunc (m *manager) watchForNewContainers(quit chan error) error {\n\twatched := make([]watcher.ContainerWatcher, 0)\n\tfor _, watcher := range m.containerWatchers {\n\t\terr := watcher.Start(m.eventsChannel)\n\t\tif err != nil {\n\t\t\tfor _, w := range watched {\n\t\t\t\tstopErr := w.Stop()\n\t\t\t\tif stopErr != nil {\n\t\t\t\t\tklog.Warningf(\"Failed to stop wacher %v with error: %v\", w, stopErr)\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn err\n\t\t}\n\t\twatched = append(watched, watcher)\n\t}\n\n\t// There is a race between starting the watch and new container creation so we do a detection before we read new containers.\n\terr := m.detectSubcontainers(\"/\")\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t// Listen to events from the container handler.\n\tgo func() {\n\t\tfor {\n\t\t\tselect {\n\t\t\tcase event := <-m.eventsChannel:\n\t\t\t\tswitch {\n\t\t\t\tcase event.EventType == watcher.ContainerAdd:\n\t\t\t\t\tswitch event.WatchSource {\n\t\t\t\t\tdefault:\n\t\t\t\t\t\terr = m.createContainer(event.Name, event.WatchSource)\n\t\t\t\t\t}\n\t\t\t\tcase event.EventType == watcher.ContainerDelete:\n\t\t\t\t\terr = m.destroyContainer(event.Name)\n\t\t\t\t}\n\t\t\t\tif err != nil {\n\t\t\t\t\tklog.Warningf(\"Failed to process watch event %+v: %v\", event, err)\n\t\t\t\t}\n\t\t\tcase <-quit:\n\t\t\t\tvar errs partialFailure\n\n\t\t\t\t// Stop processing events if asked to quit.\n\t\t\t\tfor i, watcher := range m.containerWatchers {\n\t\t\t\t\terr := watcher.Stop()\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\terrs.append(fmt.Sprintf(\"watcher %d\", i), \"Stop\", err)\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif len(errs) > 0 {\n\t\t\t\t\tquit <- errs\n\t\t\t\t} else {\n\t\t\t\t\tquit <- nil\n\t\t\t\t\tklog.Infof(\"Exiting thread watching subcontainers\")\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}()\n\treturn nil\n}\n\nfunc (m *manager) watchForNewOoms() error {\n\tklog.V(2).Infof(\"Started watching for new ooms in manager\")\n\toutStream := make(chan *oomparser.OomInstance, 10)\n\toomLog, err := oomparser.New()\n\tif err != nil {\n\t\treturn err\n\t}\n\tgo oomLog.StreamOoms(outStream)\n\n\tgo func() {\n\t\tfor oomInstance := range outStream {\n\t\t\t// Surface OOM and OOM kill events.\n\t\t\tnewEvent := &info.Event{\n\t\t\t\tContainerName: oomInstance.ContainerName,\n\t\t\t\tTimestamp:     oomInstance.TimeOfDeath,\n\t\t\t\tEventType:     info.EventOom,\n\t\t\t}\n\t\t\terr := m.eventHandler.AddEvent(newEvent)\n\t\t\tif err != nil {\n\t\t\t\tklog.Errorf(\"failed to add OOM event for %q: %v\", oomInstance.ContainerName, err)\n\t\t\t}\n\t\t\tklog.V(3).Infof(\"Created an OOM event in container %q at %v\", oomInstance.ContainerName, oomInstance.TimeOfDeath)\n\n\t\t\tnewEvent = &info.Event{\n\t\t\t\tContainerName: oomInstance.VictimContainerName,\n\t\t\t\tTimestamp:     oomInstance.TimeOfDeath,\n\t\t\t\tEventType:     info.EventOomKill,\n\t\t\t\tEventData: info.EventData{\n\t\t\t\t\tOomKill: &info.OomKillEventData{\n\t\t\t\t\t\tPid:         oomInstance.Pid,\n\t\t\t\t\t\tProcessName: oomInstance.ProcessName,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t}\n\t\t\terr = m.eventHandler.AddEvent(newEvent)\n\t\t\tif err != nil {\n\t\t\t\tklog.Errorf(\"failed to add OOM kill event for %q: %v\", oomInstance.ContainerName, err)\n\t\t\t}\n\n\t\t\t// Count OOM events for later collection by prometheus\n\t\t\trequest := v2.RequestOptions{\n\t\t\t\tIdType: v2.TypeName,\n\t\t\t\tCount:  1,\n\t\t\t}\n\t\t\tconts, err := m.getRequestedContainers(oomInstance.ContainerName, request)\n\t\t\tif err != nil {\n\t\t\t\tklog.V(2).Infof(\"failed getting container info for %q: %v\", oomInstance.ContainerName, err)\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif len(conts) != 1 {\n\t\t\t\tklog.V(2).Info(\"Expected the request to match only one container\")\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tfor _, cont := range conts {\n\t\t\t\tatomic.AddUint64(&cont.oomEvents, 1)\n\t\t\t}\n\t\t}\n\t}()\n\treturn nil\n}\n\n// can be called by the api which will take events returned on the channel\nfunc (m *manager) WatchForEvents(request *events.Request) (*events.EventChannel, error) {\n\treturn m.eventHandler.WatchEvents(request)\n}\n\n// can be called by the api which will return all events satisfying the request\nfunc (m *manager) GetPastEvents(request *events.Request) ([]*info.Event, error) {\n\treturn m.eventHandler.GetEvents(request)\n}\n\n// called by the api when a client is no longer listening to the channel\nfunc (m *manager) CloseEventChannel(watchID int) {\n\tm.eventHandler.StopWatch(watchID)\n}\n\n// Parses the events StoragePolicy from the flags.\nfunc parseEventsStoragePolicy() events.StoragePolicy {\n\tpolicy := events.DefaultStoragePolicy()\n\n\t// Parse max age.\n\tparts := strings.Split(*eventStorageAgeLimit, \",\")\n\tfor _, part := range parts {\n\t\titems := strings.Split(part, \"=\")\n\t\tif len(items) != 2 {\n\t\t\tklog.Warningf(\"Unknown event storage policy %q when parsing max age\", part)\n\t\t\tcontinue\n\t\t}\n\t\tdur, err := time.ParseDuration(items[1])\n\t\tif err != nil {\n\t\t\tklog.Warningf(\"Unable to parse event max age duration %q: %v\", items[1], err)\n\t\t\tcontinue\n\t\t}\n\t\tif items[0] == \"default\" {\n\t\t\tpolicy.DefaultMaxAge = dur\n\t\t\tcontinue\n\t\t}\n\t\tpolicy.PerTypeMaxAge[info.EventType(items[0])] = dur\n\t}\n\n\t// Parse max number.\n\tparts = strings.Split(*eventStorageEventLimit, \",\")\n\tfor _, part := range parts {\n\t\titems := strings.Split(part, \"=\")\n\t\tif len(items) != 2 {\n\t\t\tklog.Warningf(\"Unknown event storage policy %q when parsing max event limit\", part)\n\t\t\tcontinue\n\t\t}\n\t\tval, err := strconv.Atoi(items[1])\n\t\tif err != nil {\n\t\t\tklog.Warningf(\"Unable to parse integer from %q: %v\", items[1], err)\n\t\t\tcontinue\n\t\t}\n\t\tif items[0] == \"default\" {\n\t\t\tpolicy.DefaultMaxNumEvents = val\n\t\t\tcontinue\n\t\t}\n\t\tpolicy.PerTypeMaxNumEvents[info.EventType(items[0])] = val\n\t}\n\n\treturn policy\n}\n\nfunc (m *manager) DebugInfo() map[string][]string {\n\tdebugInfo := container.DebugInfo()\n\n\t// Get unique containers.\n\tconts := make(map[*containerData]struct{})\n\tm.containers.Range(func(_ namespacedContainerName, cont *containerData) bool {\n\t\tif cont != nil {\n\t\t\tconts[cont] = struct{}{}\n\t\t}\n\t\treturn true\n\t})\n\n\t// List containers.\n\tlines := make([]string, 0, len(conts))\n\tfor cont := range conts {\n\t\tlines = append(lines, cont.info.Name)\n\t\tif cont.info.Namespace != \"\" {\n\t\t\tlines = append(lines, fmt.Sprintf(\"\\tNamespace: %s\", cont.info.Namespace))\n\t\t}\n\n\t\tif len(cont.info.Aliases) != 0 {\n\t\t\tlines = append(lines, \"\\tAliases:\")\n\t\t\tfor _, alias := range cont.info.Aliases {\n\t\t\t\tlines = append(lines, fmt.Sprintf(\"\\t\\t%s\", alias))\n\t\t\t}\n\t\t}\n\t}\n\n\tdebugInfo[\"Managed containers\"] = lines\n\treturn debugInfo\n}\n\nfunc (m *manager) getFsInfoByDeviceName(deviceName string) (v2.FsInfo, error) {\n\tmountPoint, err := m.fsInfo.GetMountpointForDevice(deviceName)\n\tif err != nil {\n\t\treturn v2.FsInfo{}, fmt.Errorf(\"failed to get mount point for device %q: %v\", deviceName, err)\n\t}\n\tinfos, err := m.GetFsInfo(\"\")\n\tif err != nil {\n\t\treturn v2.FsInfo{}, err\n\t}\n\tfor _, info := range infos {\n\t\tif info.Mountpoint == mountPoint {\n\t\t\treturn info, nil\n\t\t}\n\t}\n\treturn v2.FsInfo{}, fmt.Errorf(\"cannot find filesystem info for device %q\", deviceName)\n}\n\nfunc (m *manager) containersInfo(containers map[string]*containerData, query *info.ContainerInfoRequest) (map[string]info.ContainerInfo, error) {\n\toutput := make(map[string]info.ContainerInfo, len(containers))\n\tfor name, cont := range containers {\n\t\tinf, err := m.containerDataToContainerInfo(cont, query)\n\t\tif err != nil {\n\t\t\t// Ignore the error because of race condition and return best-effort result.\n\t\t\tif err == memory.ErrDataNotFound {\n\t\t\t\tklog.V(4).Infof(\"Error getting data for container %s because of race condition\", name)\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\treturn nil, err\n\t\t}\n\t\toutput[name] = *inf\n\t}\n\treturn output, nil\n}\n\nfunc (m *manager) AllPodmanContainers(query *info.ContainerInfoRequest) (map[string]info.ContainerInfo, error) {\n\tcontainers := m.getAllNamespacedContainers(PodmanNamespace)\n\treturn m.containersInfo(containers, query)\n}\n\nfunc getVersionInfo() (*info.VersionInfo, error) {\n\n\tkernelVersion := machine.KernelVersion()\n\tosVersion := machine.ContainerOsVersion()\n\n\treturn &info.VersionInfo{\n\t\tKernelVersion:      kernelVersion,\n\t\tContainerOsVersion: osVersion,\n\t\tCadvisorVersion:    version.Info[\"version\"],\n\t\tCadvisorRevision:   version.Info[\"revision\"],\n\t}, nil\n}\n\n// Helper for accumulating partial failures.\ntype partialFailure []string\n\nfunc (f *partialFailure) append(id, operation string, err error) {\n\t*f = append(*f, fmt.Sprintf(\"[%q: %s: %s]\", id, operation, err))\n}\n\nfunc (f partialFailure) Error() string {\n\treturn fmt.Sprintf(\"partial failures: %s\", strings.Join(f, \", \"))\n}\n\nfunc (f partialFailure) OrNil() error {\n\tif len(f) == 0 {\n\t\treturn nil\n\t}\n\treturn f\n}\n"
  },
  {
    "path": "manager/manager_bench_test.go",
    "content": "// Copyright 2025 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n//go:build linux\n\npackage manager\n\nimport (\n\t\"fmt\"\n\t\"sync\"\n\t\"testing\"\n)\n\n// Benchmark concurrent reads on sync.Map\nfunc BenchmarkSyncMapConcurrentReads(b *testing.B) {\n\tvar m sync.Map\n\n\tfor i := 0; i < 1000; i++ {\n\t\tkey := namespacedContainerName{Name: fmt.Sprintf(\"/container/%d\", i)}\n\t\tm.Store(key, &containerData{})\n\t}\n\n\tb.ResetTimer()\n\tb.RunParallel(func(pb *testing.PB) {\n\t\ti := 0\n\t\tfor pb.Next() {\n\t\t\tkey := namespacedContainerName{Name: fmt.Sprintf(\"/container/%d\", i%1000)}\n\t\t\tm.Load(key)\n\t\t\ti++\n\t\t}\n\t})\n}\n\n// Benchmark concurrent reads on RWMutex and map\nfunc BenchmarkRWMutexMapConcurrentReads(b *testing.B) {\n\tvar mu sync.RWMutex\n\tm := make(map[namespacedContainerName]*containerData)\n\n\tfor i := 0; i < 1000; i++ {\n\t\tkey := namespacedContainerName{Name: fmt.Sprintf(\"/container/%d\", i)}\n\t\tm[key] = &containerData{}\n\t}\n\n\tb.ResetTimer()\n\tb.RunParallel(func(pb *testing.PB) {\n\t\ti := 0\n\t\tfor pb.Next() {\n\t\t\tkey := namespacedContainerName{Name: fmt.Sprintf(\"/container/%d\", i%1000)}\n\t\t\tmu.RLock()\n\t\t\t_ = m[key]\n\t\t\tmu.RUnlock()\n\t\t\ti++\n\t\t}\n\t})\n}\n\n// Benchmark iteration with sync.Map\nfunc BenchmarkSyncMapIteration(b *testing.B) {\n\tvar m sync.Map\n\n\tfor i := 0; i < 1000; i++ {\n\t\tkey := namespacedContainerName{Name: fmt.Sprintf(\"/container/%d\", i)}\n\t\tm.Store(key, &containerData{})\n\t}\n\n\tb.ResetTimer()\n\tfor i := 0; i < b.N; i++ {\n\t\tcount := 0\n\t\tm.Range(func(_, _ any) bool {\n\t\t\tcount++\n\t\t\treturn true\n\t\t})\n\t}\n}\n\n// Benchmark iteration with RWMutex and map\nfunc BenchmarkRWMutexMapIteration(b *testing.B) {\n\tvar mu sync.RWMutex\n\tm := make(map[namespacedContainerName]*containerData)\n\n\tfor i := 0; i < 1000; i++ {\n\t\tkey := namespacedContainerName{Name: fmt.Sprintf(\"/container/%d\", i)}\n\t\tm[key] = &containerData{}\n\t}\n\n\tb.ResetTimer()\n\tfor i := 0; i < b.N; i++ {\n\t\tmu.RLock()\n\t\tcount := 0\n\t\tfor range m {\n\t\t\tcount++\n\t\t}\n\t\tmu.RUnlock()\n\t}\n}\n\n// Benchmark mixed read/write with sync.Map\nfunc BenchmarkSyncMapMixedReadWrite(b *testing.B) {\n\tvar m sync.Map\n\n\tfor i := 0; i < 1000; i++ {\n\t\tkey := namespacedContainerName{Name: fmt.Sprintf(\"/container/%d\", i)}\n\t\tm.Store(key, &containerData{})\n\t}\n\n\tb.ResetTimer()\n\tb.RunParallel(func(pb *testing.PB) {\n\t\ti := 0\n\t\tfor pb.Next() {\n\t\t\tif i%100 == 0 {\n\t\t\t\t// 1% writes\n\t\t\t\tkey := namespacedContainerName{Name: fmt.Sprintf(\"/container/new/%d\", i)}\n\t\t\t\tm.Store(key, &containerData{})\n\t\t\t} else {\n\t\t\t\t// 99% reads\n\t\t\t\tkey := namespacedContainerName{Name: fmt.Sprintf(\"/container/%d\", i%1000)}\n\t\t\t\tm.Load(key)\n\t\t\t}\n\t\t\ti++\n\t\t}\n\t})\n}\n\n// Benchmark mixed read/write with RWMutex and map\nfunc BenchmarkRWMutexMapMixedReadWrite(b *testing.B) {\n\tvar mu sync.RWMutex\n\tm := make(map[namespacedContainerName]*containerData)\n\n\tfor i := 0; i < 1000; i++ {\n\t\tkey := namespacedContainerName{Name: fmt.Sprintf(\"/container/%d\", i)}\n\t\tm[key] = &containerData{}\n\t}\n\n\tb.ResetTimer()\n\tb.RunParallel(func(pb *testing.PB) {\n\t\ti := 0\n\t\tfor pb.Next() {\n\t\t\tif i%100 == 0 {\n\t\t\t\t// 1% writes\n\t\t\t\tkey := namespacedContainerName{Name: fmt.Sprintf(\"/container/new/%d\", i)}\n\t\t\t\tmu.Lock()\n\t\t\t\tm[key] = &containerData{}\n\t\t\t\tmu.Unlock()\n\t\t\t} else {\n\t\t\t\t// 99% reads\n\t\t\t\tkey := namespacedContainerName{Name: fmt.Sprintf(\"/container/%d\", i%1000)}\n\t\t\t\tmu.RLock()\n\t\t\t\t_ = m[key]\n\t\t\t\tmu.RUnlock()\n\t\t\t}\n\t\t\ti++\n\t\t}\n\t})\n}\n"
  },
  {
    "path": "manager/manager_test.go",
    "content": "// Copyright 2014 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n//go:build linux\n\n// Per-container manager.\n\npackage manager\n\nimport (\n\t\"fmt\"\n\t\"reflect\"\n\t\"strings\"\n\t\"sync\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/google/cadvisor/cache/memory\"\n\t\"github.com/google/cadvisor/collector\"\n\t\"github.com/google/cadvisor/container\"\n\tcontainertest \"github.com/google/cadvisor/container/testing\"\n\t\"github.com/google/cadvisor/events\"\n\tinfo \"github.com/google/cadvisor/info/v1\"\n\titest \"github.com/google/cadvisor/info/v1/test\"\n\tv2 \"github.com/google/cadvisor/info/v2\"\n\t\"github.com/google/cadvisor/stats\"\n\t\"github.com/google/cadvisor/utils/sysfs/fakesysfs\"\n\n\t\"github.com/stretchr/testify/assert\"\n\tclock \"k8s.io/utils/clock/testing\"\n\n\t// install all the container runtimes included in the library version for testing.\n\t// as these are moved to cmd/internal/container, remove them from here.\n\t_ \"github.com/google/cadvisor/container/containerd/install\"\n\t_ \"github.com/google/cadvisor/container/crio/install\"\n\t_ \"github.com/google/cadvisor/container/docker/install\"\n\t_ \"github.com/google/cadvisor/container/systemd/install\"\n)\n\n// TODO(vmarmol): Refactor these tests.\n\nfunc createManagerAndAddContainers(\n\tmemoryCache *memory.InMemoryCache,\n\tsysfs *fakesysfs.FakeSysFs,\n\tcontainers []string,\n\tf func(*containertest.MockContainerHandler),\n\tt *testing.T,\n) *manager {\n\tcontainer.ClearContainerHandlerFactories()\n\tmif := &manager{\n\t\tquitChannels: make([]chan error, 0, 2),\n\t\tmemoryCache:  memoryCache,\n\t}\n\tfor _, name := range containers {\n\t\tmockHandler := containertest.NewMockContainerHandler(name)\n\t\tspec := itest.GenerateRandomContainerSpec(4)\n\t\tmockHandler.On(\"GetSpec\").Return(\n\t\t\tspec,\n\t\t\tnil,\n\t\t).Once()\n\t\tcont, err := newContainerData(name, memoryCache, mockHandler, false, &collector.GenericCollectorManager{}, 60*time.Second, true, clock.NewFakeClock(time.Now()))\n\t\tif err != nil {\n\t\t\tt.Fatal(err)\n\t\t}\n\t\tmif.containers.Store(namespacedContainerName{\n\t\t\tName: name,\n\t\t}, cont)\n\t\t// Add Docker containers under their namespace.\n\t\tif strings.HasPrefix(name, \"/docker\") {\n\t\t\tmif.containers.Store(namespacedContainerName{\n\t\t\t\tNamespace: DockerNamespace,\n\t\t\t\tName:      strings.TrimPrefix(name, \"/docker/\"),\n\t\t\t}, cont)\n\t\t}\n\t\tf(mockHandler)\n\t}\n\treturn mif\n}\n\nfunc createManagerAndAddSubContainers(\n\tmemoryCache *memory.InMemoryCache,\n\tsysfs *fakesysfs.FakeSysFs,\n\tcontainers []string,\n\tf func(*containertest.MockContainerHandler),\n\tt *testing.T,\n) *manager {\n\tcontainer.ClearContainerHandlerFactories()\n\tmif := &manager{\n\t\tquitChannels: make([]chan error, 0, 2),\n\t\tmemoryCache:  memoryCache,\n\t}\n\n\tsubcontainers1 := []info.ContainerReference{\n\t\t{Name: \"/kubepods/besteffort\"},\n\t\t{Name: \"/kubepods/burstable\"},\n\t}\n\tsubcontainers2 := []info.ContainerReference(nil)\n\tsubcontainers3 := []info.ContainerReference{\n\t\t{Name: \"/kubepods/burstable/pod01042b28-179d-446a-954a-7266557e12cd\"},\n\t\t{Name: \"/kubepods/burstable/pod01042b28-179d-446a-954a-7266557e12ce\"},\n\t}\n\tsubcontainers4 := []info.ContainerReference{\n\t\t{Name: \"/kubepods/burstable/pod01042b28-179d-446a-954a-7266557e12cd/22f44d2a517778590e2d8bcafafe501f79e8a509e5b6de70b7700c4d37722bce\"},\n\t\t{Name: \"/kubepods/burstable/pod01042b28-179d-446a-954a-7266557e12cd/ae9465f98d275998e148b6fc12f5f92e5d4a64fca0d255f6dc3a13cc6f93a10f\"},\n\t}\n\n\tsubcontainers5 := []info.ContainerReference(nil)\n\tsubcontainers6 := []info.ContainerReference(nil)\n\n\tsubcontainerList := [][]info.ContainerReference{subcontainers1, subcontainers2, subcontainers3, subcontainers4, subcontainers5, subcontainers6}\n\n\tfor idx, name := range containers {\n\t\tmockHandler := containertest.NewMockContainerHandler(name)\n\t\tspec := itest.GenerateRandomContainerSpec(4)\n\t\tmockHandler.On(\"GetSpec\").Return(\n\t\t\tspec,\n\t\t\tnil,\n\t\t).Once()\n\t\tmockHandler.On(\"ListContainers\", container.ListSelf).Return(\n\t\t\tsubcontainerList[idx],\n\t\t\tnil,\n\t\t)\n\t\tcont, err := newContainerData(name, memoryCache, mockHandler, false, &collector.GenericCollectorManager{}, 60*time.Second, true, clock.NewFakeClock(time.Now()))\n\t\tif err != nil {\n\t\t\tt.Fatal(err)\n\t\t}\n\t\tmif.containers.Store(namespacedContainerName{\n\t\t\tName: name,\n\t\t}, cont)\n\t\t// Add Docker containers under their namespace.\n\t\tif strings.HasPrefix(name, \"/docker\") {\n\t\t\tmif.containers.Store(namespacedContainerName{\n\t\t\t\tNamespace: DockerNamespace,\n\t\t\t\tName:      strings.TrimPrefix(name, \"/docker/\"),\n\t\t\t}, cont)\n\t\t}\n\t\tf(mockHandler)\n\t}\n\treturn mif\n}\n\n// Expect a manager with the specified containers and query. Returns the manager, map of ContainerInfo objects,\n// and map of MockContainerHandler objects.}\nfunc expectManagerWithContainers(containers []string, query *info.ContainerInfoRequest, t *testing.T) (*manager, map[string]*info.ContainerInfo, map[string]*containertest.MockContainerHandler) {\n\tinfosMap := make(map[string]*info.ContainerInfo, len(containers))\n\thandlerMap := make(map[string]*containertest.MockContainerHandler, len(containers))\n\n\tfor _, container := range containers {\n\t\tinfosMap[container] = itest.GenerateRandomContainerInfo(container, 4, query, 1*time.Second)\n\t}\n\n\tmemoryCache := memory.New(time.Duration(query.NumStats)*time.Second, nil)\n\tsysfs := &fakesysfs.FakeSysFs{}\n\tm := createManagerAndAddContainers(\n\t\tmemoryCache,\n\t\tsysfs,\n\t\tcontainers,\n\t\tfunc(h *containertest.MockContainerHandler) {\n\t\t\tcinfo := infosMap[h.Name]\n\t\t\tref, err := h.ContainerReference()\n\t\t\tif err != nil {\n\t\t\t\tt.Error(err)\n\t\t\t}\n\n\t\t\tcInfo := info.ContainerInfo{\n\t\t\t\tContainerReference: ref,\n\t\t\t}\n\t\t\tfor _, stat := range cinfo.Stats {\n\t\t\t\terr = memoryCache.AddStats(&cInfo, stat)\n\t\t\t\tif err != nil {\n\t\t\t\t\tt.Error(err)\n\t\t\t\t}\n\t\t\t}\n\t\t\tspec := cinfo.Spec\n\n\t\t\th.On(\"ListContainers\", container.ListSelf).Return(\n\t\t\t\t[]info.ContainerReference(nil),\n\t\t\t\tnil,\n\t\t\t)\n\t\t\th.On(\"GetSpec\").Return(\n\t\t\t\tspec,\n\t\t\t\tnil,\n\t\t\t).Once()\n\t\t\thandlerMap[h.Name] = h\n\t\t},\n\t\tt,\n\t)\n\n\treturn m, infosMap, handlerMap\n}\n\n// Expect a manager with the specified containers and query. Returns the manager, map of ContainerInfo objects,\n// and map of MockContainerHandler objects.}\nfunc expectManagerWithSubContainers(containers []string, query *info.ContainerInfoRequest, t *testing.T) (*manager, map[string]*info.ContainerInfo, map[string]*containertest.MockContainerHandler) {\n\tinfosMap := make(map[string]*info.ContainerInfo, len(containers))\n\thandlerMap := make(map[string]*containertest.MockContainerHandler, len(containers))\n\n\tfor _, container := range containers {\n\t\tinfosMap[container] = itest.GenerateRandomContainerInfo(container, 4, query, 1*time.Second)\n\t}\n\n\tmemoryCache := memory.New(time.Duration(query.NumStats)*time.Second, nil)\n\tsysfs := &fakesysfs.FakeSysFs{}\n\tm := createManagerAndAddSubContainers(\n\t\tmemoryCache,\n\t\tsysfs,\n\t\tcontainers,\n\t\tfunc(h *containertest.MockContainerHandler) {\n\t\t\tcinfo := infosMap[h.Name]\n\t\t\tref, err := h.ContainerReference()\n\t\t\tif err != nil {\n\t\t\t\tt.Error(err)\n\t\t\t}\n\n\t\t\tcInfo := info.ContainerInfo{\n\t\t\t\tContainerReference: ref,\n\t\t\t}\n\t\t\tfor _, stat := range cinfo.Stats {\n\t\t\t\terr = memoryCache.AddStats(&cInfo, stat)\n\t\t\t\tif err != nil {\n\t\t\t\t\tt.Error(err)\n\t\t\t\t}\n\t\t\t}\n\t\t\tspec := cinfo.Spec\n\t\t\th.On(\"GetSpec\").Return(\n\t\t\t\tspec,\n\t\t\t\tnil,\n\t\t\t).Once()\n\t\t\thandlerMap[h.Name] = h\n\t\t},\n\t\tt,\n\t)\n\n\treturn m, infosMap, handlerMap\n}\n\n// Expect a manager with the specified containers and query. Returns the manager, map of ContainerInfo objects,\n// and map of MockContainerHandler objects.}\nfunc expectManagerWithContainersV2(containers []string, query *info.ContainerInfoRequest, t *testing.T) (*manager, map[string]*info.ContainerInfo, map[string]*containertest.MockContainerHandler) {\n\tinfosMap := make(map[string]*info.ContainerInfo, len(containers))\n\thandlerMap := make(map[string]*containertest.MockContainerHandler, len(containers))\n\n\tfor _, container := range containers {\n\t\tinfosMap[container] = itest.GenerateRandomContainerInfo(container, 4, query, 1*time.Second)\n\t}\n\n\tmemoryCache := memory.New(time.Duration(query.NumStats)*time.Second, nil)\n\tsysfs := &fakesysfs.FakeSysFs{}\n\tm := createManagerAndAddContainers(\n\t\tmemoryCache,\n\t\tsysfs,\n\t\tcontainers,\n\t\tfunc(h *containertest.MockContainerHandler) {\n\t\t\tcinfo := infosMap[h.Name]\n\t\t\tref, err := h.ContainerReference()\n\t\t\tif err != nil {\n\t\t\t\tt.Error(err)\n\t\t\t}\n\n\t\t\tcInfo := info.ContainerInfo{\n\t\t\t\tContainerReference: ref,\n\t\t\t}\n\n\t\t\tfor _, stat := range cinfo.Stats {\n\t\t\t\terr = memoryCache.AddStats(&cInfo, stat)\n\t\t\t\tif err != nil {\n\t\t\t\t\tt.Error(err)\n\t\t\t\t}\n\t\t\t}\n\t\t\tspec := cinfo.Spec\n\n\t\t\th.On(\"GetSpec\").Return(\n\t\t\t\tspec,\n\t\t\t\tnil,\n\t\t\t).Once()\n\t\t\thandlerMap[h.Name] = h\n\t\t},\n\t\tt,\n\t)\n\n\treturn m, infosMap, handlerMap\n}\n\nfunc TestGetContainerInfo(t *testing.T) {\n\tcontainers := []string{\n\t\t\"/c1\",\n\t\t\"/c2\",\n\t}\n\n\tquery := &info.ContainerInfoRequest{\n\t\tNumStats: 256,\n\t}\n\n\tm, infosMap, handlerMap := expectManagerWithContainers(containers, query, t)\n\n\treturnedInfos := make(map[string]*info.ContainerInfo, len(containers))\n\n\tfor _, container := range containers {\n\t\tcinfo, err := m.GetContainerInfo(container, query)\n\t\tif err != nil {\n\t\t\tt.Fatalf(\"Unable to get info for container %v: %v\", container, err)\n\t\t}\n\t\treturnedInfos[container] = cinfo\n\t}\n\n\tfor container, handler := range handlerMap {\n\t\thandler.AssertExpectations(t)\n\t\treturned := returnedInfos[container]\n\t\texpected := infosMap[container]\n\t\tif !reflect.DeepEqual(returned, expected) {\n\t\t\tt.Errorf(\"returned unexpected info for container %v; returned %+v; expected %+v\", container, returned, expected)\n\t\t}\n\t}\n}\n\nfunc TestGetContainerInfoV2(t *testing.T) {\n\tcontainers := []string{\n\t\t\"/\",\n\t\t\"/c1\",\n\t\t\"/c2\",\n\t}\n\n\toptions := v2.RequestOptions{\n\t\tIdType:    v2.TypeName,\n\t\tCount:     1,\n\t\tRecursive: true,\n\t}\n\tquery := &info.ContainerInfoRequest{\n\t\tNumStats: 2,\n\t}\n\n\tm, _, handlerMap := expectManagerWithContainersV2(containers, query, t)\n\n\tinfos, err := m.GetContainerInfoV2(\"/\", options)\n\tif err != nil {\n\t\tt.Fatalf(\"GetContainerInfoV2 failed: %v\", err)\n\t}\n\n\tfor container, handler := range handlerMap {\n\t\thandler.AssertExpectations(t)\n\t\tinfo, ok := infos[container]\n\t\tassert.True(t, ok, \"Missing info for container %q\", container)\n\t\tassert.NotEqual(t, v2.ContainerSpec{}, info.Spec, \"Empty spec for container %q\", container)\n\t\tassert.NotEmpty(t, info.Stats, \"Missing stats for container %q\", container)\n\t}\n}\n\nfunc TestGetContainerInfoV2Failure(t *testing.T) {\n\tsuccessful := \"/\"\n\tstatless := \"/c1\"\n\tfailing := \"/c2\"\n\tcontainers := []string{\n\t\tsuccessful, statless, failing,\n\t}\n\n\toptions := v2.RequestOptions{\n\t\tIdType:    v2.TypeName,\n\t\tCount:     1,\n\t\tRecursive: true,\n\t}\n\tquery := &info.ContainerInfoRequest{\n\t\tNumStats: 2,\n\t}\n\n\tm, _, handlerMap := expectManagerWithContainers(containers, query, t)\n\n\t// Remove /c1 stats\n\terr := m.memoryCache.RemoveContainer(statless)\n\tif err != nil {\n\t\tt.Fatalf(\"RemoveContainer failed: %v\", err)\n\t}\n\n\t// Make GetSpec fail on /c2\n\tmockErr := fmt.Errorf(\"intentional GetSpec failure\")\n\t_, err = handlerMap[failing].GetSpec()\n\tassert.NoError(t, err) // Use up default GetSpec call, and replace below\n\thandlerMap[failing].On(\"GetSpec\").Return(info.ContainerSpec{}, mockErr)\n\thandlerMap[failing].On(\"Exists\").Return(true)\n\t// Force GetSpec by resetting infoLastUpdatedTime to zero.\n\tif cont, ok := m.containers.Load(namespacedContainerName{Name: failing}); ok {\n\t\tcont.infoLastUpdatedTime.Store(0)\n\t}\n\n\tinfos, err := m.GetContainerInfoV2(\"/\", options)\n\tif err == nil {\n\t\tt.Error(\"Expected error calling GetContainerInfoV2\")\n\t}\n\n\t// Successful containers still successful.\n\tinfo, ok := infos[successful]\n\tassert.True(t, ok, \"Missing info for container %q\", successful)\n\tassert.NotEqual(t, v2.ContainerSpec{}, info.Spec, \"Empty spec for container %q\", successful)\n\tassert.NotEmpty(t, info.Stats, \"Missing stats for container %q\", successful)\n\n\t// \"/c1\" present with spec.\n\tinfo, ok = infos[statless]\n\tassert.True(t, ok, \"Missing info for container %q\", statless)\n\tassert.NotEqual(t, v2.ContainerSpec{}, info.Spec, \"Empty spec for container %q\", statless)\n\tassert.Empty(t, info.Stats, \"Missing stats for container %q\", successful)\n\n\t// \"/c2\" should be present but empty.\n\tinfo, ok = infos[failing]\n\tassert.True(t, ok, \"Missing info for failed container\")\n\tassert.Equal(t, v2.ContainerInfo{}, info, \"Empty spec for failed container\")\n\tassert.Empty(t, info.Stats, \"Missing stats for failed container\")\n}\n\nfunc TestSubcontainersInfo(t *testing.T) {\n\tcontainers := []string{\n\t\t\"/c1\",\n\t\t\"/c2\",\n\t}\n\n\tquery := &info.ContainerInfoRequest{\n\t\tNumStats: 64,\n\t}\n\n\tm, _, _ := expectManagerWithContainers(containers, query, t)\n\n\tresult, err := m.SubcontainersInfo(\"/\", query)\n\tif err != nil {\n\t\tt.Fatalf(\"expected to succeed: %s\", err)\n\t}\n\tif len(result) != len(containers) {\n\t\tt.Errorf(\"expected to received containers: %v, but received: %v\", containers, result)\n\t}\n\tfor _, res := range result {\n\t\tfound := false\n\t\tfor _, name := range containers {\n\t\t\tif res.Name == name {\n\t\t\t\tfound = true\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t\tif !found {\n\t\t\tt.Errorf(\"unexpected container %q in result, expected one of %v\", res.Name, containers)\n\t\t}\n\t}\n}\n\nfunc TestSubcontainersInfoError(t *testing.T) {\n\tcontainers := []string{\n\t\t\"/kubepods\",\n\t\t\"/kubepods/besteffort\",\n\t\t\"/kubepods/burstable\",\n\t\t\"/kubepods/burstable/pod01042b28-179d-446a-954a-7266557e12cd\",\n\t\t\"/kubepods/burstable/pod01042b28-179d-446a-954a-7266557e12cd/22f44d2a517778590e2d8bcafafe501f79e8a509e5b6de70b7700c4d37722bce\",\n\t\t\"/kubepods/burstable/pod01042b28-179d-446a-954a-7266557e12cd/ae9465f98d275998e148b6fc12f5f92e5d4a64fca0d255f6dc3a13cc6f93a10f\",\n\t}\n\tquery := &info.ContainerInfoRequest{\n\t\tNumStats: 1,\n\t}\n\n\tm, _, _ := expectManagerWithSubContainers(containers, query, t)\n\tresult, err := m.SubcontainersInfo(\"/kubepods\", query)\n\tif err != nil {\n\t\tt.Fatalf(\"expected to succeed: %s\", err)\n\t}\n\n\tif len(result) != len(containers) {\n\t\tt.Errorf(\"expected to received containers: %v, but received: %v\", containers, result)\n\t}\n\n\ttotalBurstable := 0\n\tburstableCount := 0\n\ttotalBesteffort := 0\n\tbesteffortCount := 0\n\n\tfor _, res := range result {\n\t\tfound := false\n\t\tif res.Name == \"/kubepods/burstable\" {\n\t\t\ttotalBurstable = len(res.Subcontainers)\n\t\t} else if res.Name == \"/kubepods/besteffort\" {\n\t\t\ttotalBesteffort = len(res.Subcontainers)\n\t\t} else if strings.HasPrefix(res.Name, \"/kubepods/burstable\") && len(res.Name) == len(\"/kubepods/burstable/pod01042b28-179d-446a-954a-7266557e12cd\") {\n\t\t\tburstableCount++\n\t\t} else if strings.HasPrefix(res.Name, \"/kubepods/besteffort\") && len(res.Name) == len(\"/kubepods/besteffort/pod01042b28-179d-446a-954a-7266557e12cd\") {\n\t\t\tbesteffortCount++\n\t\t}\n\t\tfor _, name := range containers {\n\t\t\tif res.Name == name {\n\t\t\t\tfound = true\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t\tif !found {\n\t\t\tt.Errorf(\"unexpected container %q in result, expected one of %v\", res.Name, containers)\n\t\t}\n\t}\n\n\tassert.NotEqual(t, totalBurstable, burstableCount)\n\tassert.Equal(t, totalBesteffort, besteffortCount)\n}\n\nfunc TestDockerContainersInfo(t *testing.T) {\n\tcontainers := []string{\n\t\t\"/docker/c1a\",\n\t\t\"/docker/c2a\",\n\t}\n\n\tquery := &info.ContainerInfoRequest{\n\t\tNumStats: 2,\n\t}\n\n\tm, _, _ := expectManagerWithContainers(containers, query, t)\n\n\tresult, err := m.DockerContainer(\"c1a\", query)\n\tif err != nil {\n\t\tt.Fatalf(\"expected to succeed: %s\", err)\n\t}\n\tif result.Name != containers[0] {\n\t\tt.Errorf(\"Unexpected container %q in result. Expected container %q\", result.Name, containers[0])\n\t}\n\n\tresult, err = m.DockerContainer(\"c2\", query)\n\tif err != nil {\n\t\tt.Fatalf(\"expected to succeed: %s\", err)\n\t}\n\tif result.Name != containers[1] {\n\t\tt.Errorf(\"Unexpected container %q in result. Expected container %q\", result.Name, containers[1])\n\t}\n\n\tresult, err = m.DockerContainer(\"c\", query)\n\texpectedError := \"unable to find container. Container \\\"c\\\" is not unique\"\n\tif err == nil {\n\t\tt.Errorf(\"expected error %q but received %q\", expectedError, err)\n\t}\n}\n\nfunc TestDestroyContainerWithExitCode(t *testing.T) {\n\tmockHandler := containertest.NewMockContainerHandler(\"/test\")\n\tmockHandler.On(\"GetExitCode\").Return(42, nil)\n\n\tmemoryCache := memory.New(60*time.Second, nil)\n\tm := &manager{\n\t\tquitChannels: make([]chan error, 0, 2),\n\t\tmemoryCache:  memoryCache,\n\t}\n\n\tcont := &containerData{\n\t\thandler:          mockHandler,\n\t\tmemoryCache:      memoryCache,\n\t\tperfCollector:    &stats.NoopCollector{},\n\t\tresctrlCollector: &stats.NoopCollector{},\n\t\tinfo: containerInfo{\n\t\t\tContainerReference: info.ContainerReference{\n\t\t\t\tName: \"/test\",\n\t\t\t},\n\t\t},\n\t\tstop: make(chan struct{}),\n\t}\n\n\tm.containers.Store(namespacedContainerName{Name: \"/test\"}, cont)\n\n\tmockEventHandler := &mockEventHandler{\n\t\tevents: make([]*info.Event, 0),\n\t}\n\tm.eventHandler = mockEventHandler\n\n\terr := m.destroyContainer(\"/test\")\n\tif err != nil {\n\t\tt.Logf(\"destroyContainer error: %v\", err)\n\t}\n\tassert.Nil(t, err)\n\n\tassert.Len(t, mockEventHandler.events, 1)\n\tevent := mockEventHandler.events[0]\n\tassert.Equal(t, info.EventContainerDeletion, event.EventType)\n\tassert.NotNil(t, event.EventData.ContainerDeletion)\n\tassert.Equal(t, 42, event.EventData.ContainerDeletion.ExitCode)\n\n\tmockHandler.AssertExpectations(t)\n}\n\nfunc TestDestroyContainerExitCodeUnavailable(t *testing.T) {\n\tmockHandler := containertest.NewMockContainerHandler(\"/test\")\n\tmockHandler.On(\"GetExitCode\").Return(-1, fmt.Errorf(\"container not found\"))\n\n\tmemoryCache := memory.New(60*time.Second, nil)\n\tm := &manager{\n\t\tquitChannels: make([]chan error, 0, 2),\n\t\tmemoryCache:  memoryCache,\n\t}\n\n\tcont := &containerData{\n\t\thandler:          mockHandler,\n\t\tmemoryCache:      memoryCache,\n\t\tperfCollector:    &stats.NoopCollector{},\n\t\tresctrlCollector: &stats.NoopCollector{},\n\t\tinfo: containerInfo{\n\t\t\tContainerReference: info.ContainerReference{\n\t\t\t\tName: \"/test\",\n\t\t\t},\n\t\t},\n\t\tstop: make(chan struct{}),\n\t}\n\n\tm.containers.Store(namespacedContainerName{Name: \"/test\"}, cont)\n\n\tmockEventHandler := &mockEventHandler{\n\t\tevents: make([]*info.Event, 0),\n\t}\n\tm.eventHandler = mockEventHandler\n\n\terr := m.destroyContainer(\"/test\")\n\tif err != nil {\n\t\tt.Logf(\"destroyContainer error: %v\", err)\n\t}\n\tassert.Nil(t, err)\n\n\tassert.Len(t, mockEventHandler.events, 1)\n\tevent := mockEventHandler.events[0]\n\tassert.Equal(t, info.EventContainerDeletion, event.EventType)\n\tassert.NotNil(t, event.EventData.ContainerDeletion)\n\tassert.Equal(t, -1, event.EventData.ContainerDeletion.ExitCode)\n\n\tmockHandler.AssertExpectations(t)\n}\n\ntype mockEventHandler struct {\n\tevents []*info.Event\n}\n\nfunc (m *mockEventHandler) AddEvent(e *info.Event) error {\n\tm.events = append(m.events, e)\n\treturn nil\n}\n\nfunc (m *mockEventHandler) WatchEvents(request *events.Request) (*events.EventChannel, error) {\n\treturn nil, fmt.Errorf(\"not implemented\")\n}\n\nfunc (m *mockEventHandler) GetEvents(request *events.Request) ([]*info.Event, error) {\n\treturn nil, fmt.Errorf(\"not implemented\")\n}\n\nfunc (m *mockEventHandler) StopWatch(watchID int) {\n}\n\n// threadSafeEventHandler is a thread-safe version of mockEventHandler for concurrent tests.\ntype threadSafeEventHandler struct {\n\tmu     sync.Mutex\n\tevents []*info.Event\n}\n\nfunc (m *threadSafeEventHandler) AddEvent(e *info.Event) error {\n\tm.mu.Lock()\n\tdefer m.mu.Unlock()\n\tm.events = append(m.events, e)\n\treturn nil\n}\n\nfunc (m *threadSafeEventHandler) WatchEvents(request *events.Request) (*events.EventChannel, error) {\n\treturn nil, fmt.Errorf(\"not implemented\")\n}\n\nfunc (m *threadSafeEventHandler) GetEvents(request *events.Request) ([]*info.Event, error) {\n\treturn nil, fmt.Errorf(\"not implemented\")\n}\n\nfunc (m *threadSafeEventHandler) StopWatch(watchID int) {\n}\n\n// TestContainerDataStopConcurrent verifies that concurrent calls to Stop()\n// do not cause a panic. This is a regression test for a race condition where\n// multiple goroutines could call Stop() on the same containerData, causing a\n// \"close of closed channel\" panic.\nfunc TestContainerDataStopConcurrent(t *testing.T) {\n\tmemoryCache := memory.New(60*time.Second, nil)\n\n\t// Create a minimal containerData with the fields needed for Stop()\n\tcd := &containerData{\n\t\tinfo: containerInfo{\n\t\t\tContainerReference: info.ContainerReference{\n\t\t\t\tName: \"/test-concurrent\",\n\t\t\t},\n\t\t},\n\t\tmemoryCache:      memoryCache,\n\t\tstop:             make(chan struct{}),\n\t\tperfCollector:    &stats.NoopCollector{},\n\t\tresctrlCollector: &stats.NoopCollector{},\n\t}\n\n\t// Launch multiple goroutines that all try to call Stop() simultaneously\n\tconst numGoroutines = 10\n\tvar wg sync.WaitGroup\n\twg.Add(numGoroutines)\n\n\t// Use a channel to synchronize goroutines to start at the same time\n\tstart := make(chan struct{})\n\n\tfor i := 0; i < numGoroutines; i++ {\n\t\tgo func() {\n\t\t\tdefer wg.Done()\n\t\t\t<-start // Wait for signal to start\n\t\t\t// This should not panic even if called multiple times concurrently\n\t\t\t_ = cd.Stop()\n\t\t}()\n\t}\n\n\t// Signal all goroutines to start simultaneously\n\tclose(start)\n\n\t// Wait for all goroutines to complete - if there's a panic, the test will fail\n\twg.Wait()\n}\n\n// TestDestroyContainerConcurrent verifies that concurrent calls to destroyContainer\n// for the same container do not cause a panic.\nfunc TestDestroyContainerConcurrent(t *testing.T) {\n\tmemoryCache := memory.New(60*time.Second, nil)\n\tm := &manager{\n\t\tquitChannels: make([]chan error, 0, 2),\n\t\tmemoryCache:  memoryCache,\n\t}\n\n\tmockEventHandler := &threadSafeEventHandler{}\n\tmockHandler := containertest.NewMockContainerHandler(\"/test-concurrent\")\n\tmockHandler.On(\"Start\").Return(nil)\n\tmockHandler.On(\"Cleanup\").Return()\n\tmockHandler.On(\"Stop\").Return()\n\t// GetExitCode may be called multiple times due to concurrent access\n\tmockHandler.On(\"GetExitCode\").Return(-1, nil).Maybe()\n\n\t// Create the container\n\tcd := &containerData{\n\t\thandler: mockHandler,\n\t\tinfo: containerInfo{\n\t\t\tContainerReference: info.ContainerReference{\n\t\t\t\tName: \"/test-concurrent\",\n\t\t\t},\n\t\t},\n\t\tmemoryCache:      memoryCache,\n\t\tstop:             make(chan struct{}),\n\t\tperfCollector:    &stats.NoopCollector{},\n\t\tresctrlCollector: &stats.NoopCollector{},\n\t}\n\n\t// Add to manager's container map\n\tm.containers.Store(namespacedContainerName{Name: \"/test-concurrent\"}, cd)\n\n\t// Register event handler\n\tm.eventHandler = mockEventHandler\n\n\t// Launch multiple goroutines that all try to destroy the same container\n\tconst numGoroutines = 10\n\tvar wg sync.WaitGroup\n\twg.Add(numGoroutines)\n\n\tstart := make(chan struct{})\n\n\tfor i := 0; i < numGoroutines; i++ {\n\t\tgo func() {\n\t\t\tdefer wg.Done()\n\t\t\t<-start\n\t\t\t_ = m.destroyContainer(\"/test-concurrent\")\n\t\t}()\n\t}\n\n\tclose(start)\n\twg.Wait()\n\n\t// With sync.Once protecting only the channel close, multiple goroutines\n\t// can still process the container and add events. The key assertion is\n\t// that no panic occurred (test would fail otherwise).\n\t// At least one event should be recorded.\n\tassert.GreaterOrEqual(t, len(mockEventHandler.events), 1, \"at least one destruction event should be recorded\")\n}\n"
  },
  {
    "path": "metrics/metrics.go",
    "content": "// Copyright 2020 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage metrics\n\nimport (\n\t\"time\"\n\n\tinfo \"github.com/google/cadvisor/info/v1\"\n\tv2 \"github.com/google/cadvisor/info/v2\"\n)\n\n// metricValue describes a single metric value for a given set of label values\n// within a parent containerMetric.\ntype metricValue struct {\n\tvalue     float64\n\tlabels    []string\n\ttimestamp time.Time\n}\n\ntype metricValues []metricValue\n\n// infoProvider will usually be manager.Manager, but can be swapped out for testing.\ntype infoProvider interface {\n\t// GetRequestedContainersInfo gets info for all requested containers based on the request options.\n\tGetRequestedContainersInfo(containerName string, options v2.RequestOptions) (map[string]*info.ContainerInfo, error)\n\t// GetVersionInfo provides information about the version.\n\tGetVersionInfo() (*info.VersionInfo, error)\n\t// GetMachineInfo provides information about the machine.\n\tGetMachineInfo() (*info.MachineInfo, error)\n}\n"
  },
  {
    "path": "metrics/prometheus.go",
    "content": "// Copyright 2014 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage metrics\n\nimport (\n\t\"fmt\"\n\t\"regexp\"\n\t\"strconv\"\n\t\"time\"\n\n\t\"github.com/google/cadvisor/container\"\n\tinfo \"github.com/google/cadvisor/info/v1\"\n\tv2 \"github.com/google/cadvisor/info/v2\"\n\n\t\"github.com/prometheus/client_golang/prometheus\"\n\n\t\"k8s.io/klog/v2\"\n\t\"k8s.io/utils/clock\"\n)\n\n// asFloat64 converts a uint64 into a float64.\nfunc asFloat64(v uint64) float64 { return float64(v) }\n\n// asMicrosecondsToSeconds converts nanoseconds into a float64 representing seconds.\nfunc asMicrosecondsToSeconds(v uint64) float64 {\n\treturn float64(v) / 1e6\n}\n\n// asNanosecondsToSeconds converts nanoseconds into a float64 representing seconds.\nfunc asNanosecondsToSeconds(v uint64) float64 {\n\treturn float64(v) / 1e9\n}\n\n// fsValues is a helper method for assembling per-filesystem stats.\nfunc fsValues(fsStats []info.FsStats, valueFn func(*info.FsStats) float64, timestamp time.Time) metricValues {\n\tvalues := make(metricValues, 0, len(fsStats))\n\tfor _, stat := range fsStats {\n\t\tvalues = append(values, metricValue{\n\t\t\tvalue:     valueFn(&stat),\n\t\t\tlabels:    []string{stat.Device},\n\t\t\ttimestamp: timestamp,\n\t\t})\n\t}\n\treturn values\n}\n\n// ioValues is a helper method for assembling per-disk and per-filesystem stats.\nfunc ioValues(ioStats []info.PerDiskStats, ioType string, ioValueFn func(uint64) float64,\n\tfsStats []info.FsStats, valueFn func(*info.FsStats) float64, timestamp time.Time) metricValues {\n\n\tvalues := make(metricValues, 0, len(ioStats)+len(fsStats))\n\tfor _, stat := range ioStats {\n\t\tvalues = append(values, metricValue{\n\t\t\tvalue:     ioValueFn(stat.Stats[ioType]),\n\t\t\tlabels:    []string{stat.Device},\n\t\t\ttimestamp: timestamp,\n\t\t})\n\t}\n\tfor _, stat := range fsStats {\n\t\tvalues = append(values, metricValue{\n\t\t\tvalue:     valueFn(&stat),\n\t\t\tlabels:    []string{stat.Device},\n\t\t\ttimestamp: timestamp,\n\t\t})\n\t}\n\treturn values\n}\n\n// containerMetric describes a multi-dimensional metric used for exposing a\n// certain type of container statistic.\ntype containerMetric struct {\n\tname        string\n\thelp        string\n\tvalueType   prometheus.ValueType\n\textraLabels []string\n\tcondition   func(s info.ContainerSpec) bool\n\tgetValues   func(s *info.ContainerStats) metricValues\n}\n\nfunc (cm *containerMetric) desc(baseLabels []string) *prometheus.Desc {\n\treturn prometheus.NewDesc(cm.name, cm.help, append(baseLabels, cm.extraLabels...), nil)\n}\n\n// ContainerLabelsFunc defines all base labels and their values attached to\n// each metric exported by cAdvisor.\ntype ContainerLabelsFunc func(*info.ContainerInfo) map[string]string\n\n// PrometheusCollector implements prometheus.Collector.\ntype PrometheusCollector struct {\n\tinfoProvider        infoProvider\n\terrors              prometheus.Gauge\n\tcontainerMetrics    []containerMetric\n\tcontainerLabelsFunc ContainerLabelsFunc\n\tincludedMetrics     container.MetricSet\n\topts                v2.RequestOptions\n}\n\n// NewPrometheusCollector returns a new PrometheusCollector. The passed\n// ContainerLabelsFunc specifies which base labels will be attached to all\n// exported metrics. If left to nil, the DefaultContainerLabels function\n// will be used instead.\nfunc NewPrometheusCollector(i infoProvider, f ContainerLabelsFunc, includedMetrics container.MetricSet, now clock.Clock, opts v2.RequestOptions) *PrometheusCollector {\n\tif f == nil {\n\t\tf = DefaultContainerLabels\n\t}\n\tc := &PrometheusCollector{\n\t\tinfoProvider:        i,\n\t\tcontainerLabelsFunc: f,\n\t\terrors: prometheus.NewGauge(prometheus.GaugeOpts{\n\t\t\tNamespace: \"container\",\n\t\t\tName:      \"scrape_error\",\n\t\t\tHelp:      \"1 if there was an error while getting container metrics, 0 otherwise\",\n\t\t}),\n\t\tcontainerMetrics: []containerMetric{\n\t\t\t{\n\t\t\t\tname:      \"container_last_seen\",\n\t\t\t\thelp:      \"Last time a container was seen by the exporter\",\n\t\t\t\tvalueType: prometheus.GaugeValue,\n\t\t\t\tgetValues: func(s *info.ContainerStats) metricValues {\n\t\t\t\t\treturn metricValues{{\n\t\t\t\t\t\tvalue:     float64(now.Now().Unix()),\n\t\t\t\t\t\ttimestamp: now.Now(),\n\t\t\t\t\t}}\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:      \"container_health_state\",\n\t\t\t\thelp:      \"The result of the container's health check\",\n\t\t\t\tvalueType: prometheus.GaugeValue,\n\t\t\t\tgetValues: getContainerHealthState,\n\t\t\t},\n\t\t},\n\t\tincludedMetrics: includedMetrics,\n\t\topts:            opts,\n\t}\n\tif includedMetrics.Has(container.CpuUsageMetrics) {\n\t\tc.containerMetrics = append(c.containerMetrics, []containerMetric{\n\t\t\t{\n\t\t\t\tname:      \"container_cpu_user_seconds_total\",\n\t\t\t\thelp:      \"Cumulative user cpu time consumed in seconds.\",\n\t\t\t\tvalueType: prometheus.CounterValue,\n\t\t\t\tgetValues: func(s *info.ContainerStats) metricValues {\n\t\t\t\t\treturn metricValues{\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tvalue:     float64(s.Cpu.Usage.User) / float64(time.Second),\n\t\t\t\t\t\t\ttimestamp: s.Timestamp,\n\t\t\t\t\t\t},\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t}, {\n\t\t\t\tname:      \"container_cpu_system_seconds_total\",\n\t\t\t\thelp:      \"Cumulative system cpu time consumed in seconds.\",\n\t\t\t\tvalueType: prometheus.CounterValue,\n\t\t\t\tgetValues: func(s *info.ContainerStats) metricValues {\n\t\t\t\t\treturn metricValues{\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tvalue:     float64(s.Cpu.Usage.System) / float64(time.Second),\n\t\t\t\t\t\t\ttimestamp: s.Timestamp,\n\t\t\t\t\t\t},\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t}, {\n\t\t\t\tname:        \"container_cpu_usage_seconds_total\",\n\t\t\t\thelp:        \"Cumulative cpu time consumed in seconds.\",\n\t\t\t\tvalueType:   prometheus.CounterValue,\n\t\t\t\textraLabels: []string{\"cpu\"},\n\t\t\t\tgetValues: func(s *info.ContainerStats) metricValues {\n\t\t\t\t\tif len(s.Cpu.Usage.PerCpu) == 0 {\n\t\t\t\t\t\tif s.Cpu.Usage.Total > 0 {\n\t\t\t\t\t\t\treturn metricValues{{\n\t\t\t\t\t\t\t\tvalue:     float64(s.Cpu.Usage.Total) / float64(time.Second),\n\t\t\t\t\t\t\t\tlabels:    []string{\"total\"},\n\t\t\t\t\t\t\t\ttimestamp: s.Timestamp,\n\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tvalues := make(metricValues, 0, len(s.Cpu.Usage.PerCpu))\n\t\t\t\t\tfor i, value := range s.Cpu.Usage.PerCpu {\n\t\t\t\t\t\tif value > 0 {\n\t\t\t\t\t\t\tvalues = append(values, metricValue{\n\t\t\t\t\t\t\t\tvalue:     float64(value) / float64(time.Second),\n\t\t\t\t\t\t\t\tlabels:    []string{fmt.Sprintf(\"cpu%02d\", i)},\n\t\t\t\t\t\t\t\ttimestamp: s.Timestamp,\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treturn values\n\t\t\t\t},\n\t\t\t}, {\n\t\t\t\tname:      \"container_cpu_cfs_periods_total\",\n\t\t\t\thelp:      \"Number of elapsed enforcement period intervals.\",\n\t\t\t\tvalueType: prometheus.CounterValue,\n\t\t\t\tcondition: func(s info.ContainerSpec) bool { return s.Cpu.Quota != 0 },\n\t\t\t\tgetValues: func(s *info.ContainerStats) metricValues {\n\t\t\t\t\treturn metricValues{\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tvalue:     float64(s.Cpu.CFS.Periods),\n\t\t\t\t\t\t\ttimestamp: s.Timestamp,\n\t\t\t\t\t\t}}\n\t\t\t\t},\n\t\t\t}, {\n\t\t\t\tname:      \"container_cpu_cfs_throttled_periods_total\",\n\t\t\t\thelp:      \"Number of throttled period intervals.\",\n\t\t\t\tvalueType: prometheus.CounterValue,\n\t\t\t\tcondition: func(s info.ContainerSpec) bool { return s.Cpu.Quota != 0 },\n\t\t\t\tgetValues: func(s *info.ContainerStats) metricValues {\n\t\t\t\t\treturn metricValues{\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tvalue:     float64(s.Cpu.CFS.ThrottledPeriods),\n\t\t\t\t\t\t\ttimestamp: s.Timestamp,\n\t\t\t\t\t\t}}\n\t\t\t\t},\n\t\t\t}, {\n\t\t\t\tname:      \"container_cpu_cfs_throttled_seconds_total\",\n\t\t\t\thelp:      \"Total time duration the container has been throttled.\",\n\t\t\t\tvalueType: prometheus.CounterValue,\n\t\t\t\tcondition: func(s info.ContainerSpec) bool { return s.Cpu.Quota != 0 },\n\t\t\t\tgetValues: func(s *info.ContainerStats) metricValues {\n\t\t\t\t\treturn metricValues{\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tvalue:     float64(s.Cpu.CFS.ThrottledTime) / float64(time.Second),\n\t\t\t\t\t\t\ttimestamp: s.Timestamp,\n\t\t\t\t\t\t}}\n\t\t\t\t},\n\t\t\t}, {\n\t\t\t\tname:      \"container_cpu_cfs_burst_periods_total\",\n\t\t\t\thelp:      \"Number of periods when burst occurs.\",\n\t\t\t\tvalueType: prometheus.CounterValue,\n\t\t\t\tcondition: func(s info.ContainerSpec) bool { return s.Cpu.Quota != 0 },\n\t\t\t\tgetValues: func(s *info.ContainerStats) metricValues {\n\t\t\t\t\treturn metricValues{\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tvalue:     float64(s.Cpu.CFS.BurstsPeriods),\n\t\t\t\t\t\t\ttimestamp: s.Timestamp,\n\t\t\t\t\t\t}}\n\t\t\t\t},\n\t\t\t}, {\n\t\t\t\tname:      \"container_cpu_cfs_burst_seconds_total\",\n\t\t\t\thelp:      \"Total time duration the container has been bursted.\",\n\t\t\t\tvalueType: prometheus.CounterValue,\n\t\t\t\tcondition: func(s info.ContainerSpec) bool { return s.Cpu.Quota != 0 },\n\t\t\t\tgetValues: func(s *info.ContainerStats) metricValues {\n\t\t\t\t\treturn metricValues{\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tvalue:     float64(s.Cpu.CFS.BurstTime) / float64(time.Second),\n\t\t\t\t\t\t\ttimestamp: s.Timestamp,\n\t\t\t\t\t\t}}\n\t\t\t\t},\n\t\t\t},\n\t\t}...)\n\t}\n\tif includedMetrics.Has(container.ProcessSchedulerMetrics) {\n\t\tc.containerMetrics = append(c.containerMetrics, []containerMetric{\n\t\t\t{\n\t\t\t\tname:      \"container_cpu_schedstat_run_seconds_total\",\n\t\t\t\thelp:      \"Time duration the processes of the container have run on the CPU.\",\n\t\t\t\tvalueType: prometheus.CounterValue,\n\t\t\t\tgetValues: func(s *info.ContainerStats) metricValues {\n\t\t\t\t\treturn metricValues{{\n\t\t\t\t\t\tvalue:     float64(s.Cpu.Schedstat.RunTime) / float64(time.Second),\n\t\t\t\t\t\ttimestamp: s.Timestamp,\n\t\t\t\t\t}}\n\t\t\t\t},\n\t\t\t}, {\n\t\t\t\tname:      \"container_cpu_schedstat_runqueue_seconds_total\",\n\t\t\t\thelp:      \"Time duration processes of the container have been waiting on a runqueue.\",\n\t\t\t\tvalueType: prometheus.CounterValue,\n\t\t\t\tgetValues: func(s *info.ContainerStats) metricValues {\n\t\t\t\t\treturn metricValues{{\n\t\t\t\t\t\tvalue:     float64(s.Cpu.Schedstat.RunqueueTime) / float64(time.Second),\n\t\t\t\t\t\ttimestamp: s.Timestamp,\n\t\t\t\t\t}}\n\t\t\t\t},\n\t\t\t}, {\n\t\t\t\tname:      \"container_cpu_schedstat_run_periods_total\",\n\t\t\t\thelp:      \"Number of times processes of the cgroup have run on the cpu\",\n\t\t\t\tvalueType: prometheus.CounterValue,\n\t\t\t\tgetValues: func(s *info.ContainerStats) metricValues {\n\t\t\t\t\treturn metricValues{{\n\t\t\t\t\t\tvalue:     float64(s.Cpu.Schedstat.RunPeriods),\n\t\t\t\t\t\ttimestamp: s.Timestamp,\n\t\t\t\t\t}}\n\t\t\t\t},\n\t\t\t},\n\t\t}...)\n\t}\n\tif includedMetrics.Has(container.CpuLoadMetrics) {\n\t\tc.containerMetrics = append(c.containerMetrics, []containerMetric{\n\t\t\t{\n\t\t\t\tname:      \"container_cpu_load_average_10s\",\n\t\t\t\thelp:      \"Value of container cpu load average over the last 10 seconds.\",\n\t\t\t\tvalueType: prometheus.GaugeValue,\n\t\t\t\tgetValues: func(s *info.ContainerStats) metricValues {\n\t\t\t\t\treturn metricValues{{value: float64(s.Cpu.LoadAverage), timestamp: s.Timestamp}}\n\t\t\t\t},\n\t\t\t}, {\n\t\t\t\tname:      \"container_cpu_load_d_average_10s\",\n\t\t\t\thelp:      \"Value of container cpu load.d average over the last 10 seconds.\",\n\t\t\t\tvalueType: prometheus.GaugeValue,\n\t\t\t\tgetValues: func(s *info.ContainerStats) metricValues {\n\t\t\t\t\treturn metricValues{{value: float64(s.Cpu.LoadDAverage), timestamp: s.Timestamp}}\n\t\t\t\t},\n\t\t\t}, {\n\t\t\t\tname:        \"container_tasks_state\",\n\t\t\t\thelp:        \"Number of tasks in given state\",\n\t\t\t\textraLabels: []string{\"state\"},\n\t\t\t\tvalueType:   prometheus.GaugeValue,\n\t\t\t\tgetValues: func(s *info.ContainerStats) metricValues {\n\t\t\t\t\treturn metricValues{\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tvalue:     float64(s.TaskStats.NrSleeping),\n\t\t\t\t\t\t\tlabels:    []string{\"sleeping\"},\n\t\t\t\t\t\t\ttimestamp: s.Timestamp,\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tvalue:     float64(s.TaskStats.NrRunning),\n\t\t\t\t\t\t\tlabels:    []string{\"running\"},\n\t\t\t\t\t\t\ttimestamp: s.Timestamp,\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tvalue:     float64(s.TaskStats.NrStopped),\n\t\t\t\t\t\t\tlabels:    []string{\"stopped\"},\n\t\t\t\t\t\t\ttimestamp: s.Timestamp,\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tvalue:     float64(s.TaskStats.NrUninterruptible),\n\t\t\t\t\t\t\tlabels:    []string{\"uninterruptible\"},\n\t\t\t\t\t\t\ttimestamp: s.Timestamp,\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tvalue:     float64(s.TaskStats.NrIoWait),\n\t\t\t\t\t\t\tlabels:    []string{\"iowaiting\"},\n\t\t\t\t\t\t\ttimestamp: s.Timestamp,\n\t\t\t\t\t\t},\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t},\n\t\t}...)\n\t}\n\tif includedMetrics.Has(container.HugetlbUsageMetrics) {\n\t\tc.containerMetrics = append(c.containerMetrics, []containerMetric{\n\t\t\t{\n\t\t\t\tname:        \"container_hugetlb_failcnt\",\n\t\t\t\thelp:        \"Number of hugepage usage hits limits\",\n\t\t\t\tvalueType:   prometheus.CounterValue,\n\t\t\t\textraLabels: []string{\"pagesize\"},\n\t\t\t\tgetValues: func(s *info.ContainerStats) metricValues {\n\t\t\t\t\tvalues := make(metricValues, 0, len(s.Hugetlb))\n\t\t\t\t\tfor k, v := range s.Hugetlb {\n\t\t\t\t\t\tvalues = append(values, metricValue{\n\t\t\t\t\t\t\tvalue:     float64(v.Failcnt),\n\t\t\t\t\t\t\tlabels:    []string{k},\n\t\t\t\t\t\t\ttimestamp: s.Timestamp,\n\t\t\t\t\t\t})\n\t\t\t\t\t}\n\t\t\t\t\treturn values\n\t\t\t\t},\n\t\t\t}, {\n\t\t\t\tname:        \"container_hugetlb_usage_bytes\",\n\t\t\t\thelp:        \"Current hugepage usage in bytes\",\n\t\t\t\tvalueType:   prometheus.GaugeValue,\n\t\t\t\textraLabels: []string{\"pagesize\"},\n\t\t\t\tgetValues: func(s *info.ContainerStats) metricValues {\n\t\t\t\t\tvalues := make(metricValues, 0, len(s.Hugetlb))\n\t\t\t\t\tfor k, v := range s.Hugetlb {\n\t\t\t\t\t\tvalues = append(values, metricValue{\n\t\t\t\t\t\t\tvalue:     float64(v.Usage),\n\t\t\t\t\t\t\tlabels:    []string{k},\n\t\t\t\t\t\t\ttimestamp: s.Timestamp,\n\t\t\t\t\t\t})\n\t\t\t\t\t}\n\t\t\t\t\treturn values\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:        \"container_hugetlb_max_usage_bytes\",\n\t\t\t\thelp:        \"Maximum hugepage usage recorded in bytes\",\n\t\t\t\tvalueType:   prometheus.GaugeValue,\n\t\t\t\textraLabels: []string{\"pagesize\"},\n\t\t\t\tgetValues: func(s *info.ContainerStats) metricValues {\n\t\t\t\t\tvalues := make(metricValues, 0, len(s.Hugetlb))\n\t\t\t\t\tfor k, v := range s.Hugetlb {\n\t\t\t\t\t\tvalues = append(values, metricValue{\n\t\t\t\t\t\t\tvalue:     float64(v.MaxUsage),\n\t\t\t\t\t\t\tlabels:    []string{k},\n\t\t\t\t\t\t\ttimestamp: s.Timestamp,\n\t\t\t\t\t\t})\n\t\t\t\t\t}\n\t\t\t\t\treturn values\n\t\t\t\t},\n\t\t\t},\n\t\t}...)\n\t}\n\tif includedMetrics.Has(container.MemoryUsageMetrics) {\n\t\tc.containerMetrics = append(c.containerMetrics, []containerMetric{\n\t\t\t{\n\t\t\t\tname:      \"container_memory_cache\",\n\t\t\t\thelp:      \"Number of bytes of page cache memory.\",\n\t\t\t\tvalueType: prometheus.GaugeValue,\n\t\t\t\tgetValues: func(s *info.ContainerStats) metricValues {\n\t\t\t\t\treturn metricValues{{value: float64(s.Memory.Cache), timestamp: s.Timestamp}}\n\t\t\t\t},\n\t\t\t}, {\n\t\t\t\tname:      \"container_memory_rss\",\n\t\t\t\thelp:      \"Size of RSS in bytes.\",\n\t\t\t\tvalueType: prometheus.GaugeValue,\n\t\t\t\tgetValues: func(s *info.ContainerStats) metricValues {\n\t\t\t\t\treturn metricValues{{value: float64(s.Memory.RSS), timestamp: s.Timestamp}}\n\t\t\t\t},\n\t\t\t}, {\n\t\t\t\tname:      \"container_memory_kernel_usage\",\n\t\t\t\thelp:      \"Size of kernel memory allocated in bytes.\",\n\t\t\t\tvalueType: prometheus.GaugeValue,\n\t\t\t\tgetValues: func(s *info.ContainerStats) metricValues {\n\t\t\t\t\treturn metricValues{{value: float64(s.Memory.KernelUsage), timestamp: s.Timestamp}}\n\t\t\t\t},\n\t\t\t}, {\n\t\t\t\tname:      \"container_memory_mapped_file\",\n\t\t\t\thelp:      \"Size of memory mapped files in bytes.\",\n\t\t\t\tvalueType: prometheus.GaugeValue,\n\t\t\t\tgetValues: func(s *info.ContainerStats) metricValues {\n\t\t\t\t\treturn metricValues{{value: float64(s.Memory.MappedFile), timestamp: s.Timestamp}}\n\t\t\t\t},\n\t\t\t}, {\n\t\t\t\tname:      \"container_memory_swap\",\n\t\t\t\thelp:      \"Container swap usage in bytes.\",\n\t\t\t\tvalueType: prometheus.GaugeValue,\n\t\t\t\tgetValues: func(s *info.ContainerStats) metricValues {\n\t\t\t\t\treturn metricValues{{value: float64(s.Memory.Swap), timestamp: s.Timestamp}}\n\t\t\t\t},\n\t\t\t}, {\n\t\t\t\tname:      \"container_memory_failcnt\",\n\t\t\t\thelp:      \"Number of memory usage hits limits\",\n\t\t\t\tvalueType: prometheus.CounterValue,\n\t\t\t\tgetValues: func(s *info.ContainerStats) metricValues {\n\t\t\t\t\treturn metricValues{{\n\t\t\t\t\t\tvalue:     float64(s.Memory.Failcnt),\n\t\t\t\t\t\ttimestamp: s.Timestamp,\n\t\t\t\t\t}}\n\t\t\t\t},\n\t\t\t}, {\n\t\t\t\tname:      \"container_memory_usage_bytes\",\n\t\t\t\thelp:      \"Current memory usage in bytes, including all memory regardless of when it was accessed\",\n\t\t\t\tvalueType: prometheus.GaugeValue,\n\t\t\t\tgetValues: func(s *info.ContainerStats) metricValues {\n\t\t\t\t\treturn metricValues{{value: float64(s.Memory.Usage), timestamp: s.Timestamp}}\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:      \"container_memory_max_usage_bytes\",\n\t\t\t\thelp:      \"Maximum memory usage recorded in bytes\",\n\t\t\t\tvalueType: prometheus.GaugeValue,\n\t\t\t\tgetValues: func(s *info.ContainerStats) metricValues {\n\t\t\t\t\treturn metricValues{{value: float64(s.Memory.MaxUsage), timestamp: s.Timestamp}}\n\t\t\t\t},\n\t\t\t}, {\n\t\t\t\tname:      \"container_memory_working_set_bytes\",\n\t\t\t\thelp:      \"Current working set in bytes.\",\n\t\t\t\tvalueType: prometheus.GaugeValue,\n\t\t\t\tgetValues: func(s *info.ContainerStats) metricValues {\n\t\t\t\t\treturn metricValues{{value: float64(s.Memory.WorkingSet), timestamp: s.Timestamp}}\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:      \"container_memory_total_active_file_bytes\",\n\t\t\t\thelp:      \"Current total active file in bytes.\",\n\t\t\t\tvalueType: prometheus.GaugeValue,\n\t\t\t\tgetValues: func(s *info.ContainerStats) metricValues {\n\t\t\t\t\treturn metricValues{{value: float64(s.Memory.TotalActiveFile), timestamp: s.Timestamp}}\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:      \"container_memory_total_inactive_file_bytes\",\n\t\t\t\thelp:      \"Current total inactive file in bytes.\",\n\t\t\t\tvalueType: prometheus.GaugeValue,\n\t\t\t\tgetValues: func(s *info.ContainerStats) metricValues {\n\t\t\t\t\treturn metricValues{{value: float64(s.Memory.TotalInactiveFile), timestamp: s.Timestamp}}\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:        \"container_memory_failures_total\",\n\t\t\t\thelp:        \"Cumulative count of memory allocation failures.\",\n\t\t\t\tvalueType:   prometheus.CounterValue,\n\t\t\t\textraLabels: []string{\"failure_type\", \"scope\"},\n\t\t\t\tgetValues: func(s *info.ContainerStats) metricValues {\n\t\t\t\t\treturn metricValues{\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tvalue:     float64(s.Memory.ContainerData.Pgfault),\n\t\t\t\t\t\t\tlabels:    []string{\"pgfault\", \"container\"},\n\t\t\t\t\t\t\ttimestamp: s.Timestamp,\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tvalue:     float64(s.Memory.ContainerData.Pgmajfault),\n\t\t\t\t\t\t\tlabels:    []string{\"pgmajfault\", \"container\"},\n\t\t\t\t\t\t\ttimestamp: s.Timestamp,\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tvalue:     float64(s.Memory.HierarchicalData.Pgfault),\n\t\t\t\t\t\t\tlabels:    []string{\"pgfault\", \"hierarchy\"},\n\t\t\t\t\t\t\ttimestamp: s.Timestamp,\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tvalue:     float64(s.Memory.HierarchicalData.Pgmajfault),\n\t\t\t\t\t\t\tlabels:    []string{\"pgmajfault\", \"hierarchy\"},\n\t\t\t\t\t\t\ttimestamp: s.Timestamp,\n\t\t\t\t\t\t},\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t},\n\t\t}...)\n\t}\n\tif includedMetrics.Has(container.CPUSetMetrics) {\n\t\tc.containerMetrics = append(c.containerMetrics, containerMetric{\n\t\t\tname:      \"container_memory_migrate\",\n\t\t\thelp:      \"Memory migrate status.\",\n\t\t\tvalueType: prometheus.GaugeValue,\n\t\t\tgetValues: func(s *info.ContainerStats) metricValues {\n\t\t\t\treturn metricValues{{value: float64(s.CpuSet.MemoryMigrate), timestamp: s.Timestamp}}\n\t\t\t},\n\t\t})\n\t}\n\tif includedMetrics.Has(container.MemoryNumaMetrics) {\n\t\tc.containerMetrics = append(c.containerMetrics, []containerMetric{\n\t\t\t{\n\t\t\t\tname:        \"container_memory_numa_pages\",\n\t\t\t\thelp:        \"Number of used pages per NUMA node\",\n\t\t\t\tvalueType:   prometheus.GaugeValue,\n\t\t\t\textraLabels: []string{\"type\", \"scope\", \"node\"},\n\t\t\t\tgetValues: func(s *info.ContainerStats) metricValues {\n\t\t\t\t\tvalues := make(metricValues, 0)\n\t\t\t\t\tvalues = append(values, getNumaStatsPerNode(s.Memory.ContainerData.NumaStats.File,\n\t\t\t\t\t\t[]string{\"file\", \"container\"}, s.Timestamp)...)\n\t\t\t\t\tvalues = append(values, getNumaStatsPerNode(s.Memory.ContainerData.NumaStats.Anon,\n\t\t\t\t\t\t[]string{\"anon\", \"container\"}, s.Timestamp)...)\n\t\t\t\t\tvalues = append(values, getNumaStatsPerNode(s.Memory.ContainerData.NumaStats.Unevictable,\n\t\t\t\t\t\t[]string{\"unevictable\", \"container\"}, s.Timestamp)...)\n\n\t\t\t\t\tvalues = append(values, getNumaStatsPerNode(s.Memory.HierarchicalData.NumaStats.File,\n\t\t\t\t\t\t[]string{\"file\", \"hierarchy\"}, s.Timestamp)...)\n\t\t\t\t\tvalues = append(values, getNumaStatsPerNode(s.Memory.HierarchicalData.NumaStats.Anon,\n\t\t\t\t\t\t[]string{\"anon\", \"hierarchy\"}, s.Timestamp)...)\n\t\t\t\t\tvalues = append(values, getNumaStatsPerNode(s.Memory.HierarchicalData.NumaStats.Unevictable,\n\t\t\t\t\t\t[]string{\"unevictable\", \"hierarchy\"}, s.Timestamp)...)\n\t\t\t\t\treturn values\n\t\t\t\t},\n\t\t\t},\n\t\t}...)\n\t}\n\tif includedMetrics.Has(container.DiskUsageMetrics) {\n\t\tc.containerMetrics = append(c.containerMetrics, []containerMetric{\n\t\t\t{\n\t\t\t\tname:        \"container_fs_inodes_free\",\n\t\t\t\thelp:        \"Number of available Inodes\",\n\t\t\t\tvalueType:   prometheus.GaugeValue,\n\t\t\t\textraLabels: []string{\"device\"},\n\t\t\t\tgetValues: func(s *info.ContainerStats) metricValues {\n\t\t\t\t\treturn fsValues(s.Filesystem, func(fs *info.FsStats) float64 {\n\t\t\t\t\t\treturn float64(fs.InodesFree)\n\t\t\t\t\t}, s.Timestamp)\n\t\t\t\t},\n\t\t\t}, {\n\t\t\t\tname:        \"container_fs_inodes_total\",\n\t\t\t\thelp:        \"Number of Inodes\",\n\t\t\t\tvalueType:   prometheus.GaugeValue,\n\t\t\t\textraLabels: []string{\"device\"},\n\t\t\t\tgetValues: func(s *info.ContainerStats) metricValues {\n\t\t\t\t\treturn fsValues(s.Filesystem, func(fs *info.FsStats) float64 {\n\t\t\t\t\t\treturn float64(fs.Inodes)\n\t\t\t\t\t}, s.Timestamp)\n\t\t\t\t},\n\t\t\t}, {\n\t\t\t\tname:        \"container_fs_limit_bytes\",\n\t\t\t\thelp:        \"Number of bytes that can be consumed by the container on this filesystem.\",\n\t\t\t\tvalueType:   prometheus.GaugeValue,\n\t\t\t\textraLabels: []string{\"device\"},\n\t\t\t\tgetValues: func(s *info.ContainerStats) metricValues {\n\t\t\t\t\treturn fsValues(s.Filesystem, func(fs *info.FsStats) float64 {\n\t\t\t\t\t\treturn float64(fs.Limit)\n\t\t\t\t\t}, s.Timestamp)\n\t\t\t\t},\n\t\t\t}, {\n\t\t\t\tname:        \"container_fs_usage_bytes\",\n\t\t\t\thelp:        \"Number of bytes that are consumed by the container on this filesystem.\",\n\t\t\t\tvalueType:   prometheus.GaugeValue,\n\t\t\t\textraLabels: []string{\"device\"},\n\t\t\t\tgetValues: func(s *info.ContainerStats) metricValues {\n\t\t\t\t\treturn fsValues(s.Filesystem, func(fs *info.FsStats) float64 {\n\t\t\t\t\t\treturn float64(fs.Usage)\n\t\t\t\t\t}, s.Timestamp)\n\t\t\t\t},\n\t\t\t},\n\t\t}...)\n\t}\n\tif includedMetrics.Has(container.DiskIOMetrics) {\n\t\tc.containerMetrics = append(c.containerMetrics, []containerMetric{\n\t\t\t{\n\t\t\t\tname:        \"container_fs_reads_bytes_total\",\n\t\t\t\thelp:        \"Cumulative count of bytes read\",\n\t\t\t\tvalueType:   prometheus.CounterValue,\n\t\t\t\textraLabels: []string{\"device\"},\n\t\t\t\tgetValues: func(s *info.ContainerStats) metricValues {\n\t\t\t\t\treturn ioValues(\n\t\t\t\t\t\ts.DiskIo.IoServiceBytes, \"Read\", asFloat64,\n\t\t\t\t\t\tnil, nil,\n\t\t\t\t\t\ts.Timestamp,\n\t\t\t\t\t)\n\t\t\t\t},\n\t\t\t}, {\n\t\t\t\tname:        \"container_fs_reads_total\",\n\t\t\t\thelp:        \"Cumulative count of reads completed\",\n\t\t\t\tvalueType:   prometheus.CounterValue,\n\t\t\t\textraLabels: []string{\"device\"},\n\t\t\t\tgetValues: func(s *info.ContainerStats) metricValues {\n\t\t\t\t\treturn ioValues(\n\t\t\t\t\t\ts.DiskIo.IoServiced, \"Read\", asFloat64,\n\t\t\t\t\t\ts.Filesystem, func(fs *info.FsStats) float64 {\n\t\t\t\t\t\t\treturn float64(fs.ReadsCompleted)\n\t\t\t\t\t\t},\n\t\t\t\t\t\ts.Timestamp,\n\t\t\t\t\t)\n\t\t\t\t},\n\t\t\t}, {\n\t\t\t\tname:        \"container_fs_sector_reads_total\",\n\t\t\t\thelp:        \"Cumulative count of sector reads completed\",\n\t\t\t\tvalueType:   prometheus.CounterValue,\n\t\t\t\textraLabels: []string{\"device\"},\n\t\t\t\tgetValues: func(s *info.ContainerStats) metricValues {\n\t\t\t\t\treturn ioValues(\n\t\t\t\t\t\ts.DiskIo.Sectors, \"Read\", asFloat64,\n\t\t\t\t\t\ts.Filesystem, func(fs *info.FsStats) float64 {\n\t\t\t\t\t\t\treturn float64(fs.SectorsRead)\n\t\t\t\t\t\t},\n\t\t\t\t\t\ts.Timestamp,\n\t\t\t\t\t)\n\t\t\t\t},\n\t\t\t}, {\n\t\t\t\tname:        \"container_fs_reads_merged_total\",\n\t\t\t\thelp:        \"Cumulative count of reads merged\",\n\t\t\t\tvalueType:   prometheus.CounterValue,\n\t\t\t\textraLabels: []string{\"device\"},\n\t\t\t\tgetValues: func(s *info.ContainerStats) metricValues {\n\t\t\t\t\treturn ioValues(\n\t\t\t\t\t\ts.DiskIo.IoMerged, \"Read\", asFloat64,\n\t\t\t\t\t\ts.Filesystem, func(fs *info.FsStats) float64 {\n\t\t\t\t\t\t\treturn float64(fs.ReadsMerged)\n\t\t\t\t\t\t},\n\t\t\t\t\t\ts.Timestamp,\n\t\t\t\t\t)\n\t\t\t\t},\n\t\t\t}, {\n\t\t\t\tname:        \"container_fs_read_seconds_total\",\n\t\t\t\thelp:        \"Cumulative count of seconds spent reading\",\n\t\t\t\tvalueType:   prometheus.CounterValue,\n\t\t\t\textraLabels: []string{\"device\"},\n\t\t\t\tgetValues: func(s *info.ContainerStats) metricValues {\n\t\t\t\t\treturn ioValues(\n\t\t\t\t\t\ts.DiskIo.IoServiceTime, \"Read\", asNanosecondsToSeconds,\n\t\t\t\t\t\ts.Filesystem, func(fs *info.FsStats) float64 {\n\t\t\t\t\t\t\treturn float64(fs.ReadTime) / float64(time.Second)\n\t\t\t\t\t\t},\n\t\t\t\t\t\ts.Timestamp,\n\t\t\t\t\t)\n\t\t\t\t},\n\t\t\t}, {\n\t\t\t\tname:        \"container_fs_writes_bytes_total\",\n\t\t\t\thelp:        \"Cumulative count of bytes written\",\n\t\t\t\tvalueType:   prometheus.CounterValue,\n\t\t\t\textraLabels: []string{\"device\"},\n\t\t\t\tgetValues: func(s *info.ContainerStats) metricValues {\n\t\t\t\t\treturn ioValues(\n\t\t\t\t\t\ts.DiskIo.IoServiceBytes, \"Write\", asFloat64,\n\t\t\t\t\t\tnil, nil,\n\t\t\t\t\t\ts.Timestamp,\n\t\t\t\t\t)\n\t\t\t\t},\n\t\t\t}, {\n\t\t\t\tname:        \"container_fs_writes_total\",\n\t\t\t\thelp:        \"Cumulative count of writes completed\",\n\t\t\t\tvalueType:   prometheus.CounterValue,\n\t\t\t\textraLabels: []string{\"device\"},\n\t\t\t\tgetValues: func(s *info.ContainerStats) metricValues {\n\t\t\t\t\treturn ioValues(\n\t\t\t\t\t\ts.DiskIo.IoServiced, \"Write\", asFloat64,\n\t\t\t\t\t\ts.Filesystem, func(fs *info.FsStats) float64 {\n\t\t\t\t\t\t\treturn float64(fs.WritesCompleted)\n\t\t\t\t\t\t},\n\t\t\t\t\t\ts.Timestamp,\n\t\t\t\t\t)\n\t\t\t\t},\n\t\t\t}, {\n\t\t\t\tname:        \"container_fs_sector_writes_total\",\n\t\t\t\thelp:        \"Cumulative count of sector writes completed\",\n\t\t\t\tvalueType:   prometheus.CounterValue,\n\t\t\t\textraLabels: []string{\"device\"},\n\t\t\t\tgetValues: func(s *info.ContainerStats) metricValues {\n\t\t\t\t\treturn ioValues(\n\t\t\t\t\t\ts.DiskIo.Sectors, \"Write\", asFloat64,\n\t\t\t\t\t\ts.Filesystem, func(fs *info.FsStats) float64 {\n\t\t\t\t\t\t\treturn float64(fs.SectorsWritten)\n\t\t\t\t\t\t},\n\t\t\t\t\t\ts.Timestamp,\n\t\t\t\t\t)\n\t\t\t\t},\n\t\t\t}, {\n\t\t\t\tname:        \"container_fs_writes_merged_total\",\n\t\t\t\thelp:        \"Cumulative count of writes merged\",\n\t\t\t\tvalueType:   prometheus.CounterValue,\n\t\t\t\textraLabels: []string{\"device\"},\n\t\t\t\tgetValues: func(s *info.ContainerStats) metricValues {\n\t\t\t\t\treturn ioValues(\n\t\t\t\t\t\ts.DiskIo.IoMerged, \"Write\", asFloat64,\n\t\t\t\t\t\ts.Filesystem, func(fs *info.FsStats) float64 {\n\t\t\t\t\t\t\treturn float64(fs.WritesMerged)\n\t\t\t\t\t\t},\n\t\t\t\t\t\ts.Timestamp,\n\t\t\t\t\t)\n\t\t\t\t},\n\t\t\t}, {\n\t\t\t\tname:        \"container_fs_write_seconds_total\",\n\t\t\t\thelp:        \"Cumulative count of seconds spent writing\",\n\t\t\t\tvalueType:   prometheus.CounterValue,\n\t\t\t\textraLabels: []string{\"device\"},\n\t\t\t\tgetValues: func(s *info.ContainerStats) metricValues {\n\t\t\t\t\treturn ioValues(\n\t\t\t\t\t\ts.DiskIo.IoServiceTime, \"Write\", asNanosecondsToSeconds,\n\t\t\t\t\t\ts.Filesystem, func(fs *info.FsStats) float64 {\n\t\t\t\t\t\t\treturn float64(fs.WriteTime) / float64(time.Second)\n\t\t\t\t\t\t},\n\t\t\t\t\t\ts.Timestamp,\n\t\t\t\t\t)\n\t\t\t\t},\n\t\t\t}, {\n\t\t\t\tname:        \"container_fs_io_current\",\n\t\t\t\thelp:        \"Number of I/Os currently in progress\",\n\t\t\t\tvalueType:   prometheus.GaugeValue,\n\t\t\t\textraLabels: []string{\"device\"},\n\t\t\t\tgetValues: func(s *info.ContainerStats) metricValues {\n\t\t\t\t\treturn ioValues(\n\t\t\t\t\t\ts.DiskIo.IoQueued, \"Total\", asFloat64,\n\t\t\t\t\t\ts.Filesystem, func(fs *info.FsStats) float64 {\n\t\t\t\t\t\t\treturn float64(fs.IoInProgress)\n\t\t\t\t\t\t},\n\t\t\t\t\t\ts.Timestamp,\n\t\t\t\t\t)\n\t\t\t\t},\n\t\t\t}, {\n\t\t\t\tname:        \"container_fs_io_time_seconds_total\",\n\t\t\t\thelp:        \"Cumulative count of seconds spent doing I/Os\",\n\t\t\t\tvalueType:   prometheus.CounterValue,\n\t\t\t\textraLabels: []string{\"device\"},\n\t\t\t\tgetValues: func(s *info.ContainerStats) metricValues {\n\t\t\t\t\treturn ioValues(\n\t\t\t\t\t\ts.DiskIo.IoServiceTime, \"Total\", asNanosecondsToSeconds,\n\t\t\t\t\t\ts.Filesystem, func(fs *info.FsStats) float64 {\n\t\t\t\t\t\t\treturn float64(float64(fs.IoTime) / float64(time.Second))\n\t\t\t\t\t\t},\n\t\t\t\t\t\ts.Timestamp,\n\t\t\t\t\t)\n\t\t\t\t},\n\t\t\t}, {\n\t\t\t\tname:        \"container_fs_io_time_weighted_seconds_total\",\n\t\t\t\thelp:        \"Cumulative weighted I/O time in seconds\",\n\t\t\t\tvalueType:   prometheus.CounterValue,\n\t\t\t\textraLabels: []string{\"device\"},\n\t\t\t\tgetValues: func(s *info.ContainerStats) metricValues {\n\t\t\t\t\treturn fsValues(s.Filesystem, func(fs *info.FsStats) float64 {\n\t\t\t\t\t\treturn float64(fs.WeightedIoTime) / float64(time.Second)\n\t\t\t\t\t}, s.Timestamp)\n\t\t\t\t},\n\t\t\t}, {\n\t\t\t\tname:        \"container_fs_io_cost_usage_seconds_total\",\n\t\t\t\thelp:        \"Cumulative IOCost usage in seconds\",\n\t\t\t\tvalueType:   prometheus.CounterValue,\n\t\t\t\textraLabels: []string{\"device\"},\n\t\t\t\tgetValues: func(s *info.ContainerStats) metricValues {\n\t\t\t\t\treturn ioValues(\n\t\t\t\t\t\ts.DiskIo.IoCostUsage, \"Count\", asMicrosecondsToSeconds,\n\t\t\t\t\t\t[]info.FsStats{}, nil,\n\t\t\t\t\t\ts.Timestamp,\n\t\t\t\t\t)\n\t\t\t\t},\n\t\t\t}, {\n\t\t\t\tname:        \"container_fs_io_cost_wait_seconds_total\",\n\t\t\t\thelp:        \"Cumulative IOCost wait in seconds\",\n\t\t\t\tvalueType:   prometheus.CounterValue,\n\t\t\t\textraLabels: []string{\"device\"},\n\t\t\t\tgetValues: func(s *info.ContainerStats) metricValues {\n\t\t\t\t\treturn ioValues(\n\t\t\t\t\t\ts.DiskIo.IoCostWait, \"Count\", asMicrosecondsToSeconds,\n\t\t\t\t\t\t[]info.FsStats{}, nil,\n\t\t\t\t\t\ts.Timestamp,\n\t\t\t\t\t)\n\t\t\t\t},\n\t\t\t}, {\n\t\t\t\tname:        \"container_fs_io_cost_indebt_seconds_total\",\n\t\t\t\thelp:        \"Cumulative IOCost debt in seconds\",\n\t\t\t\tvalueType:   prometheus.CounterValue,\n\t\t\t\textraLabels: []string{\"device\"},\n\t\t\t\tgetValues: func(s *info.ContainerStats) metricValues {\n\t\t\t\t\treturn ioValues(\n\t\t\t\t\t\ts.DiskIo.IoCostIndebt, \"Count\", asMicrosecondsToSeconds,\n\t\t\t\t\t\t[]info.FsStats{}, nil,\n\t\t\t\t\t\ts.Timestamp,\n\t\t\t\t\t)\n\t\t\t\t},\n\t\t\t}, {\n\t\t\t\tname:        \"container_fs_io_cost_indelay_seconds_total\",\n\t\t\t\thelp:        \"Cumulative IOCost delay in seconds\",\n\t\t\t\tvalueType:   prometheus.CounterValue,\n\t\t\t\textraLabels: []string{\"device\"},\n\t\t\t\tgetValues: func(s *info.ContainerStats) metricValues {\n\t\t\t\t\treturn ioValues(\n\t\t\t\t\t\ts.DiskIo.IoCostIndelay, \"Count\", asMicrosecondsToSeconds,\n\t\t\t\t\t\t[]info.FsStats{}, nil,\n\t\t\t\t\t\ts.Timestamp,\n\t\t\t\t\t)\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:        \"container_blkio_device_usage_total\",\n\t\t\t\thelp:        \"Blkio Device bytes usage\",\n\t\t\t\tvalueType:   prometheus.CounterValue,\n\t\t\t\textraLabels: []string{\"device\", \"major\", \"minor\", \"operation\"},\n\t\t\t\tgetValues: func(s *info.ContainerStats) metricValues {\n\t\t\t\t\tvar values metricValues\n\t\t\t\t\tfor _, diskStat := range s.DiskIo.IoServiceBytes {\n\t\t\t\t\t\tfor operation, value := range diskStat.Stats {\n\t\t\t\t\t\t\tvalues = append(values, metricValue{\n\t\t\t\t\t\t\t\tvalue: float64(value),\n\t\t\t\t\t\t\t\tlabels: []string{diskStat.Device,\n\t\t\t\t\t\t\t\t\tstrconv.Itoa(int(diskStat.Major)),\n\t\t\t\t\t\t\t\t\tstrconv.Itoa(int(diskStat.Minor)),\n\t\t\t\t\t\t\t\t\toperation},\n\t\t\t\t\t\t\t\ttimestamp: s.Timestamp,\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treturn values\n\t\t\t\t},\n\t\t\t},\n\t\t}...)\n\t}\n\tif includedMetrics.Has(container.NetworkUsageMetrics) {\n\t\tc.containerMetrics = append(c.containerMetrics, []containerMetric{\n\t\t\t{\n\t\t\t\tname:        \"container_network_receive_bytes_total\",\n\t\t\t\thelp:        \"Cumulative count of bytes received\",\n\t\t\t\tvalueType:   prometheus.CounterValue,\n\t\t\t\textraLabels: []string{\"interface\"},\n\t\t\t\tgetValues: func(s *info.ContainerStats) metricValues {\n\t\t\t\t\tvalues := make(metricValues, 0, len(s.Network.Interfaces))\n\t\t\t\t\tfor _, value := range s.Network.Interfaces {\n\t\t\t\t\t\tvalues = append(values, metricValue{\n\t\t\t\t\t\t\tvalue:     float64(value.RxBytes),\n\t\t\t\t\t\t\tlabels:    []string{value.Name},\n\t\t\t\t\t\t\ttimestamp: s.Timestamp,\n\t\t\t\t\t\t})\n\t\t\t\t\t}\n\t\t\t\t\treturn values\n\t\t\t\t},\n\t\t\t}, {\n\t\t\t\tname:        \"container_network_receive_packets_total\",\n\t\t\t\thelp:        \"Cumulative count of packets received\",\n\t\t\t\tvalueType:   prometheus.CounterValue,\n\t\t\t\textraLabels: []string{\"interface\"},\n\t\t\t\tgetValues: func(s *info.ContainerStats) metricValues {\n\t\t\t\t\tvalues := make(metricValues, 0, len(s.Network.Interfaces))\n\t\t\t\t\tfor _, value := range s.Network.Interfaces {\n\t\t\t\t\t\tvalues = append(values, metricValue{\n\t\t\t\t\t\t\tvalue:     float64(value.RxPackets),\n\t\t\t\t\t\t\tlabels:    []string{value.Name},\n\t\t\t\t\t\t\ttimestamp: s.Timestamp,\n\t\t\t\t\t\t})\n\t\t\t\t\t}\n\t\t\t\t\treturn values\n\t\t\t\t},\n\t\t\t}, {\n\t\t\t\tname:        \"container_network_receive_packets_dropped_total\",\n\t\t\t\thelp:        \"Cumulative count of packets dropped while receiving\",\n\t\t\t\tvalueType:   prometheus.CounterValue,\n\t\t\t\textraLabels: []string{\"interface\"},\n\t\t\t\tgetValues: func(s *info.ContainerStats) metricValues {\n\t\t\t\t\tvalues := make(metricValues, 0, len(s.Network.Interfaces))\n\t\t\t\t\tfor _, value := range s.Network.Interfaces {\n\t\t\t\t\t\tvalues = append(values, metricValue{\n\t\t\t\t\t\t\tvalue:     float64(value.RxDropped),\n\t\t\t\t\t\t\tlabels:    []string{value.Name},\n\t\t\t\t\t\t\ttimestamp: s.Timestamp,\n\t\t\t\t\t\t})\n\t\t\t\t\t}\n\t\t\t\t\treturn values\n\t\t\t\t},\n\t\t\t}, {\n\t\t\t\tname:        \"container_network_receive_errors_total\",\n\t\t\t\thelp:        \"Cumulative count of errors encountered while receiving\",\n\t\t\t\tvalueType:   prometheus.CounterValue,\n\t\t\t\textraLabels: []string{\"interface\"},\n\t\t\t\tgetValues: func(s *info.ContainerStats) metricValues {\n\t\t\t\t\tvalues := make(metricValues, 0, len(s.Network.Interfaces))\n\t\t\t\t\tfor _, value := range s.Network.Interfaces {\n\t\t\t\t\t\tvalues = append(values, metricValue{\n\t\t\t\t\t\t\tvalue:     float64(value.RxErrors),\n\t\t\t\t\t\t\tlabels:    []string{value.Name},\n\t\t\t\t\t\t\ttimestamp: s.Timestamp,\n\t\t\t\t\t\t})\n\t\t\t\t\t}\n\t\t\t\t\treturn values\n\t\t\t\t},\n\t\t\t}, {\n\t\t\t\tname:        \"container_network_transmit_bytes_total\",\n\t\t\t\thelp:        \"Cumulative count of bytes transmitted\",\n\t\t\t\tvalueType:   prometheus.CounterValue,\n\t\t\t\textraLabels: []string{\"interface\"},\n\t\t\t\tgetValues: func(s *info.ContainerStats) metricValues {\n\t\t\t\t\tvalues := make(metricValues, 0, len(s.Network.Interfaces))\n\t\t\t\t\tfor _, value := range s.Network.Interfaces {\n\t\t\t\t\t\tvalues = append(values, metricValue{\n\t\t\t\t\t\t\tvalue:     float64(value.TxBytes),\n\t\t\t\t\t\t\tlabels:    []string{value.Name},\n\t\t\t\t\t\t\ttimestamp: s.Timestamp,\n\t\t\t\t\t\t})\n\t\t\t\t\t}\n\t\t\t\t\treturn values\n\t\t\t\t},\n\t\t\t}, {\n\t\t\t\tname:        \"container_network_transmit_packets_total\",\n\t\t\t\thelp:        \"Cumulative count of packets transmitted\",\n\t\t\t\tvalueType:   prometheus.CounterValue,\n\t\t\t\textraLabels: []string{\"interface\"},\n\t\t\t\tgetValues: func(s *info.ContainerStats) metricValues {\n\t\t\t\t\tvalues := make(metricValues, 0, len(s.Network.Interfaces))\n\t\t\t\t\tfor _, value := range s.Network.Interfaces {\n\t\t\t\t\t\tvalues = append(values, metricValue{\n\t\t\t\t\t\t\tvalue:     float64(value.TxPackets),\n\t\t\t\t\t\t\tlabels:    []string{value.Name},\n\t\t\t\t\t\t\ttimestamp: s.Timestamp,\n\t\t\t\t\t\t})\n\t\t\t\t\t}\n\t\t\t\t\treturn values\n\t\t\t\t},\n\t\t\t}, {\n\t\t\t\tname:        \"container_network_transmit_packets_dropped_total\",\n\t\t\t\thelp:        \"Cumulative count of packets dropped while transmitting\",\n\t\t\t\tvalueType:   prometheus.CounterValue,\n\t\t\t\textraLabels: []string{\"interface\"},\n\t\t\t\tgetValues: func(s *info.ContainerStats) metricValues {\n\t\t\t\t\tvalues := make(metricValues, 0, len(s.Network.Interfaces))\n\t\t\t\t\tfor _, value := range s.Network.Interfaces {\n\t\t\t\t\t\tvalues = append(values, metricValue{\n\t\t\t\t\t\t\tvalue:     float64(value.TxDropped),\n\t\t\t\t\t\t\tlabels:    []string{value.Name},\n\t\t\t\t\t\t\ttimestamp: s.Timestamp,\n\t\t\t\t\t\t})\n\t\t\t\t\t}\n\t\t\t\t\treturn values\n\t\t\t\t},\n\t\t\t}, {\n\t\t\t\tname:        \"container_network_transmit_errors_total\",\n\t\t\t\thelp:        \"Cumulative count of errors encountered while transmitting\",\n\t\t\t\tvalueType:   prometheus.CounterValue,\n\t\t\t\textraLabels: []string{\"interface\"},\n\t\t\t\tgetValues: func(s *info.ContainerStats) metricValues {\n\t\t\t\t\tvalues := make(metricValues, 0, len(s.Network.Interfaces))\n\t\t\t\t\tfor _, value := range s.Network.Interfaces {\n\t\t\t\t\t\tvalues = append(values, metricValue{\n\t\t\t\t\t\t\tvalue:     float64(value.TxErrors),\n\t\t\t\t\t\t\tlabels:    []string{value.Name},\n\t\t\t\t\t\t\ttimestamp: s.Timestamp,\n\t\t\t\t\t\t})\n\t\t\t\t\t}\n\t\t\t\t\treturn values\n\t\t\t\t},\n\t\t\t},\n\t\t}...)\n\t}\n\tif includedMetrics.Has(container.NetworkTcpUsageMetrics) {\n\t\tc.containerMetrics = append(c.containerMetrics, []containerMetric{\n\t\t\t{\n\t\t\t\tname:        \"container_network_tcp_usage_total\",\n\t\t\t\thelp:        \"tcp connection usage statistic for container\",\n\t\t\t\tvalueType:   prometheus.GaugeValue,\n\t\t\t\textraLabels: []string{\"tcp_state\"},\n\t\t\t\tgetValues: func(s *info.ContainerStats) metricValues {\n\t\t\t\t\treturn metricValues{\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tvalue:     float64(s.Network.Tcp.Established),\n\t\t\t\t\t\t\tlabels:    []string{\"established\"},\n\t\t\t\t\t\t\ttimestamp: s.Timestamp,\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tvalue:     float64(s.Network.Tcp.SynSent),\n\t\t\t\t\t\t\tlabels:    []string{\"synsent\"},\n\t\t\t\t\t\t\ttimestamp: s.Timestamp,\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tvalue:     float64(s.Network.Tcp.SynRecv),\n\t\t\t\t\t\t\tlabels:    []string{\"synrecv\"},\n\t\t\t\t\t\t\ttimestamp: s.Timestamp,\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tvalue:     float64(s.Network.Tcp.FinWait1),\n\t\t\t\t\t\t\tlabels:    []string{\"finwait1\"},\n\t\t\t\t\t\t\ttimestamp: s.Timestamp,\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tvalue:     float64(s.Network.Tcp.FinWait2),\n\t\t\t\t\t\t\tlabels:    []string{\"finwait2\"},\n\t\t\t\t\t\t\ttimestamp: s.Timestamp,\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tvalue:     float64(s.Network.Tcp.TimeWait),\n\t\t\t\t\t\t\tlabels:    []string{\"timewait\"},\n\t\t\t\t\t\t\ttimestamp: s.Timestamp,\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tvalue:     float64(s.Network.Tcp.Close),\n\t\t\t\t\t\t\tlabels:    []string{\"close\"},\n\t\t\t\t\t\t\ttimestamp: s.Timestamp,\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tvalue:     float64(s.Network.Tcp.CloseWait),\n\t\t\t\t\t\t\tlabels:    []string{\"closewait\"},\n\t\t\t\t\t\t\ttimestamp: s.Timestamp,\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tvalue:     float64(s.Network.Tcp.LastAck),\n\t\t\t\t\t\t\tlabels:    []string{\"lastack\"},\n\t\t\t\t\t\t\ttimestamp: s.Timestamp,\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tvalue:     float64(s.Network.Tcp.Listen),\n\t\t\t\t\t\t\tlabels:    []string{\"listen\"},\n\t\t\t\t\t\t\ttimestamp: s.Timestamp,\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tvalue:     float64(s.Network.Tcp.Closing),\n\t\t\t\t\t\t\tlabels:    []string{\"closing\"},\n\t\t\t\t\t\t\ttimestamp: s.Timestamp,\n\t\t\t\t\t\t},\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t},\n\t\t}...)\n\t\tc.containerMetrics = append(c.containerMetrics, []containerMetric{\n\t\t\t{\n\t\t\t\tname:        \"container_network_tcp6_usage_total\",\n\t\t\t\thelp:        \"tcp6 connection usage statistic for container\",\n\t\t\t\tvalueType:   prometheus.GaugeValue,\n\t\t\t\textraLabels: []string{\"tcp_state\"},\n\t\t\t\tgetValues: func(s *info.ContainerStats) metricValues {\n\t\t\t\t\treturn metricValues{\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tvalue:     float64(s.Network.Tcp6.Established),\n\t\t\t\t\t\t\tlabels:    []string{\"established\"},\n\t\t\t\t\t\t\ttimestamp: s.Timestamp,\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tvalue:     float64(s.Network.Tcp6.SynSent),\n\t\t\t\t\t\t\tlabels:    []string{\"synsent\"},\n\t\t\t\t\t\t\ttimestamp: s.Timestamp,\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tvalue:     float64(s.Network.Tcp6.SynRecv),\n\t\t\t\t\t\t\tlabels:    []string{\"synrecv\"},\n\t\t\t\t\t\t\ttimestamp: s.Timestamp,\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tvalue:     float64(s.Network.Tcp6.FinWait1),\n\t\t\t\t\t\t\tlabels:    []string{\"finwait1\"},\n\t\t\t\t\t\t\ttimestamp: s.Timestamp,\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tvalue:     float64(s.Network.Tcp6.FinWait2),\n\t\t\t\t\t\t\tlabels:    []string{\"finwait2\"},\n\t\t\t\t\t\t\ttimestamp: s.Timestamp,\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tvalue:     float64(s.Network.Tcp6.TimeWait),\n\t\t\t\t\t\t\tlabels:    []string{\"timewait\"},\n\t\t\t\t\t\t\ttimestamp: s.Timestamp,\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tvalue:     float64(s.Network.Tcp6.Close),\n\t\t\t\t\t\t\tlabels:    []string{\"close\"},\n\t\t\t\t\t\t\ttimestamp: s.Timestamp,\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tvalue:     float64(s.Network.Tcp6.CloseWait),\n\t\t\t\t\t\t\tlabels:    []string{\"closewait\"},\n\t\t\t\t\t\t\ttimestamp: s.Timestamp,\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tvalue:     float64(s.Network.Tcp6.LastAck),\n\t\t\t\t\t\t\tlabels:    []string{\"lastack\"},\n\t\t\t\t\t\t\ttimestamp: s.Timestamp,\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tvalue:     float64(s.Network.Tcp6.Listen),\n\t\t\t\t\t\t\tlabels:    []string{\"listen\"},\n\t\t\t\t\t\t\ttimestamp: s.Timestamp,\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tvalue:     float64(s.Network.Tcp6.Closing),\n\t\t\t\t\t\t\tlabels:    []string{\"closing\"},\n\t\t\t\t\t\t\ttimestamp: s.Timestamp,\n\t\t\t\t\t\t},\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t},\n\t\t}...)\n\t}\n\tif includedMetrics.Has(container.NetworkAdvancedTcpUsageMetrics) {\n\t\tc.containerMetrics = append(c.containerMetrics, []containerMetric{\n\t\t\t{\n\t\t\t\tname:        \"container_network_advance_tcp_stats_total\",\n\t\t\t\thelp:        \"advance tcp connections statistic for container\",\n\t\t\t\tvalueType:   prometheus.GaugeValue,\n\t\t\t\textraLabels: []string{\"tcp_state\"},\n\t\t\t\tgetValues: func(s *info.ContainerStats) metricValues {\n\t\t\t\t\treturn metricValues{\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tvalue:     float64(s.Network.TcpAdvanced.RtoAlgorithm),\n\t\t\t\t\t\t\tlabels:    []string{\"rtoalgorithm\"},\n\t\t\t\t\t\t\ttimestamp: s.Timestamp,\n\t\t\t\t\t\t}, {\n\t\t\t\t\t\t\tvalue:     float64(s.Network.TcpAdvanced.RtoMin),\n\t\t\t\t\t\t\tlabels:    []string{\"rtomin\"},\n\t\t\t\t\t\t\ttimestamp: s.Timestamp,\n\t\t\t\t\t\t}, {\n\t\t\t\t\t\t\tvalue:     float64(s.Network.TcpAdvanced.RtoMax),\n\t\t\t\t\t\t\tlabels:    []string{\"rtomax\"},\n\t\t\t\t\t\t\ttimestamp: s.Timestamp,\n\t\t\t\t\t\t}, {\n\t\t\t\t\t\t\tvalue:     float64(s.Network.TcpAdvanced.MaxConn),\n\t\t\t\t\t\t\tlabels:    []string{\"maxconn\"},\n\t\t\t\t\t\t\ttimestamp: s.Timestamp,\n\t\t\t\t\t\t}, {\n\t\t\t\t\t\t\tvalue:     float64(s.Network.TcpAdvanced.ActiveOpens),\n\t\t\t\t\t\t\tlabels:    []string{\"activeopens\"},\n\t\t\t\t\t\t\ttimestamp: s.Timestamp,\n\t\t\t\t\t\t}, {\n\t\t\t\t\t\t\tvalue:     float64(s.Network.TcpAdvanced.PassiveOpens),\n\t\t\t\t\t\t\tlabels:    []string{\"passiveopens\"},\n\t\t\t\t\t\t\ttimestamp: s.Timestamp,\n\t\t\t\t\t\t}, {\n\t\t\t\t\t\t\tvalue:     float64(s.Network.TcpAdvanced.AttemptFails),\n\t\t\t\t\t\t\tlabels:    []string{\"attemptfails\"},\n\t\t\t\t\t\t\ttimestamp: s.Timestamp,\n\t\t\t\t\t\t}, {\n\t\t\t\t\t\t\tvalue:     float64(s.Network.TcpAdvanced.EstabResets),\n\t\t\t\t\t\t\tlabels:    []string{\"estabresets\"},\n\t\t\t\t\t\t\ttimestamp: s.Timestamp,\n\t\t\t\t\t\t}, {\n\t\t\t\t\t\t\tvalue:     float64(s.Network.TcpAdvanced.CurrEstab),\n\t\t\t\t\t\t\tlabels:    []string{\"currestab\"},\n\t\t\t\t\t\t\ttimestamp: s.Timestamp,\n\t\t\t\t\t\t}, {\n\t\t\t\t\t\t\tvalue:     float64(s.Network.TcpAdvanced.InSegs),\n\t\t\t\t\t\t\tlabels:    []string{\"insegs\"},\n\t\t\t\t\t\t\ttimestamp: s.Timestamp,\n\t\t\t\t\t\t}, {\n\t\t\t\t\t\t\tvalue:     float64(s.Network.TcpAdvanced.OutSegs),\n\t\t\t\t\t\t\tlabels:    []string{\"outsegs\"},\n\t\t\t\t\t\t\ttimestamp: s.Timestamp,\n\t\t\t\t\t\t}, {\n\t\t\t\t\t\t\tvalue:     float64(s.Network.TcpAdvanced.RetransSegs),\n\t\t\t\t\t\t\tlabels:    []string{\"retranssegs\"},\n\t\t\t\t\t\t\ttimestamp: s.Timestamp,\n\t\t\t\t\t\t}, {\n\t\t\t\t\t\t\tvalue:     float64(s.Network.TcpAdvanced.InErrs),\n\t\t\t\t\t\t\tlabels:    []string{\"inerrs\"},\n\t\t\t\t\t\t\ttimestamp: s.Timestamp,\n\t\t\t\t\t\t}, {\n\t\t\t\t\t\t\tvalue:     float64(s.Network.TcpAdvanced.OutRsts),\n\t\t\t\t\t\t\tlabels:    []string{\"outrsts\"},\n\t\t\t\t\t\t\ttimestamp: s.Timestamp,\n\t\t\t\t\t\t}, {\n\t\t\t\t\t\t\tvalue:     float64(s.Network.TcpAdvanced.InCsumErrors),\n\t\t\t\t\t\t\tlabels:    []string{\"incsumerrors\"},\n\t\t\t\t\t\t\ttimestamp: s.Timestamp,\n\t\t\t\t\t\t}, {\n\t\t\t\t\t\t\tvalue:     float64(s.Network.TcpAdvanced.EmbryonicRsts),\n\t\t\t\t\t\t\tlabels:    []string{\"embryonicrsts\"},\n\t\t\t\t\t\t\ttimestamp: s.Timestamp,\n\t\t\t\t\t\t}, {\n\t\t\t\t\t\t\tvalue:     float64(s.Network.TcpAdvanced.SyncookiesSent),\n\t\t\t\t\t\t\tlabels:    []string{\"syncookiessent\"},\n\t\t\t\t\t\t\ttimestamp: s.Timestamp,\n\t\t\t\t\t\t}, {\n\t\t\t\t\t\t\tvalue:     float64(s.Network.TcpAdvanced.SyncookiesRecv),\n\t\t\t\t\t\t\tlabels:    []string{\"syncookiesrecv\"},\n\t\t\t\t\t\t\ttimestamp: s.Timestamp,\n\t\t\t\t\t\t}, {\n\t\t\t\t\t\t\tvalue:     float64(s.Network.TcpAdvanced.SyncookiesFailed),\n\t\t\t\t\t\t\tlabels:    []string{\"syncookiesfailed\"},\n\t\t\t\t\t\t\ttimestamp: s.Timestamp,\n\t\t\t\t\t\t}, {\n\t\t\t\t\t\t\tvalue:     float64(s.Network.TcpAdvanced.PruneCalled),\n\t\t\t\t\t\t\tlabels:    []string{\"prunecalled\"},\n\t\t\t\t\t\t\ttimestamp: s.Timestamp,\n\t\t\t\t\t\t}, {\n\t\t\t\t\t\t\tvalue:     float64(s.Network.TcpAdvanced.RcvPruned),\n\t\t\t\t\t\t\tlabels:    []string{\"rcvpruned\"},\n\t\t\t\t\t\t\ttimestamp: s.Timestamp,\n\t\t\t\t\t\t}, {\n\t\t\t\t\t\t\tvalue:     float64(s.Network.TcpAdvanced.OfoPruned),\n\t\t\t\t\t\t\tlabels:    []string{\"ofopruned\"},\n\t\t\t\t\t\t\ttimestamp: s.Timestamp,\n\t\t\t\t\t\t}, {\n\t\t\t\t\t\t\tvalue:     float64(s.Network.TcpAdvanced.OutOfWindowIcmps),\n\t\t\t\t\t\t\tlabels:    []string{\"outofwindowicmps\"},\n\t\t\t\t\t\t\ttimestamp: s.Timestamp,\n\t\t\t\t\t\t}, {\n\t\t\t\t\t\t\tvalue:     float64(s.Network.TcpAdvanced.LockDroppedIcmps),\n\t\t\t\t\t\t\tlabels:    []string{\"lockdroppedicmps\"},\n\t\t\t\t\t\t\ttimestamp: s.Timestamp,\n\t\t\t\t\t\t}, {\n\t\t\t\t\t\t\tvalue:     float64(s.Network.TcpAdvanced.TW),\n\t\t\t\t\t\t\tlabels:    []string{\"tw\"},\n\t\t\t\t\t\t\ttimestamp: s.Timestamp,\n\t\t\t\t\t\t}, {\n\t\t\t\t\t\t\tvalue:     float64(s.Network.TcpAdvanced.TWRecycled),\n\t\t\t\t\t\t\tlabels:    []string{\"twrecycled\"},\n\t\t\t\t\t\t\ttimestamp: s.Timestamp,\n\t\t\t\t\t\t}, {\n\t\t\t\t\t\t\tvalue:     float64(s.Network.TcpAdvanced.TWKilled),\n\t\t\t\t\t\t\tlabels:    []string{\"twkilled\"},\n\t\t\t\t\t\t\ttimestamp: s.Timestamp,\n\t\t\t\t\t\t}, {\n\t\t\t\t\t\t\tvalue:     float64(s.Network.TcpAdvanced.TCPTimeWaitOverflow),\n\t\t\t\t\t\t\tlabels:    []string{\"tcptimewaitoverflow\"},\n\t\t\t\t\t\t\ttimestamp: s.Timestamp,\n\t\t\t\t\t\t}, {\n\t\t\t\t\t\t\tvalue:     float64(s.Network.TcpAdvanced.TCPTimeouts),\n\t\t\t\t\t\t\tlabels:    []string{\"tcptimeouts\"},\n\t\t\t\t\t\t\ttimestamp: s.Timestamp,\n\t\t\t\t\t\t}, {\n\t\t\t\t\t\t\tvalue:     float64(s.Network.TcpAdvanced.TCPSpuriousRTOs),\n\t\t\t\t\t\t\tlabels:    []string{\"tcpspuriousrtos\"},\n\t\t\t\t\t\t\ttimestamp: s.Timestamp,\n\t\t\t\t\t\t}, {\n\t\t\t\t\t\t\tvalue:     float64(s.Network.TcpAdvanced.TCPLossProbes),\n\t\t\t\t\t\t\tlabels:    []string{\"tcplossprobes\"},\n\t\t\t\t\t\t\ttimestamp: s.Timestamp,\n\t\t\t\t\t\t}, {\n\t\t\t\t\t\t\tvalue:     float64(s.Network.TcpAdvanced.TCPLossProbeRecovery),\n\t\t\t\t\t\t\tlabels:    []string{\"tcplossproberecovery\"},\n\t\t\t\t\t\t\ttimestamp: s.Timestamp,\n\t\t\t\t\t\t}, {\n\t\t\t\t\t\t\tvalue:     float64(s.Network.TcpAdvanced.TCPRenoRecoveryFail),\n\t\t\t\t\t\t\tlabels:    []string{\"tcprenorecoveryfail\"},\n\t\t\t\t\t\t\ttimestamp: s.Timestamp,\n\t\t\t\t\t\t}, {\n\t\t\t\t\t\t\tvalue:     float64(s.Network.TcpAdvanced.TCPSackRecoveryFail),\n\t\t\t\t\t\t\tlabels:    []string{\"tcpsackrecoveryfail\"},\n\t\t\t\t\t\t\ttimestamp: s.Timestamp,\n\t\t\t\t\t\t}, {\n\t\t\t\t\t\t\tvalue:     float64(s.Network.TcpAdvanced.TCPRenoFailures),\n\t\t\t\t\t\t\tlabels:    []string{\"tcprenofailures\"},\n\t\t\t\t\t\t\ttimestamp: s.Timestamp,\n\t\t\t\t\t\t}, {\n\t\t\t\t\t\t\tvalue:     float64(s.Network.TcpAdvanced.TCPSackFailures),\n\t\t\t\t\t\t\tlabels:    []string{\"tcpsackfailures\"},\n\t\t\t\t\t\t\ttimestamp: s.Timestamp,\n\t\t\t\t\t\t}, {\n\t\t\t\t\t\t\tvalue:     float64(s.Network.TcpAdvanced.TCPLossFailures),\n\t\t\t\t\t\t\tlabels:    []string{\"tcplossfailures\"},\n\t\t\t\t\t\t\ttimestamp: s.Timestamp,\n\t\t\t\t\t\t}, {\n\t\t\t\t\t\t\tvalue:     float64(s.Network.TcpAdvanced.DelayedACKs),\n\t\t\t\t\t\t\tlabels:    []string{\"delayedacks\"},\n\t\t\t\t\t\t\ttimestamp: s.Timestamp,\n\t\t\t\t\t\t}, {\n\t\t\t\t\t\t\tvalue:     float64(s.Network.TcpAdvanced.DelayedACKLocked),\n\t\t\t\t\t\t\tlabels:    []string{\"delayedacklocked\"},\n\t\t\t\t\t\t\ttimestamp: s.Timestamp,\n\t\t\t\t\t\t}, {\n\t\t\t\t\t\t\tvalue:     float64(s.Network.TcpAdvanced.DelayedACKLost),\n\t\t\t\t\t\t\tlabels:    []string{\"delayedacklost\"},\n\t\t\t\t\t\t\ttimestamp: s.Timestamp,\n\t\t\t\t\t\t}, {\n\t\t\t\t\t\t\tvalue:     float64(s.Network.TcpAdvanced.ListenOverflows),\n\t\t\t\t\t\t\tlabels:    []string{\"listenoverflows\"},\n\t\t\t\t\t\t\ttimestamp: s.Timestamp,\n\t\t\t\t\t\t}, {\n\t\t\t\t\t\t\tvalue:     float64(s.Network.TcpAdvanced.ListenDrops),\n\t\t\t\t\t\t\tlabels:    []string{\"listendrops\"},\n\t\t\t\t\t\t\ttimestamp: s.Timestamp,\n\t\t\t\t\t\t}, {\n\t\t\t\t\t\t\tvalue:     float64(s.Network.TcpAdvanced.TCPHPHits),\n\t\t\t\t\t\t\tlabels:    []string{\"tcphphits\"},\n\t\t\t\t\t\t\ttimestamp: s.Timestamp,\n\t\t\t\t\t\t}, {\n\t\t\t\t\t\t\tvalue:     float64(s.Network.TcpAdvanced.TCPPureAcks),\n\t\t\t\t\t\t\tlabels:    []string{\"tcppureacks\"},\n\t\t\t\t\t\t\ttimestamp: s.Timestamp,\n\t\t\t\t\t\t}, {\n\t\t\t\t\t\t\tvalue:     float64(s.Network.TcpAdvanced.TCPHPAcks),\n\t\t\t\t\t\t\tlabels:    []string{\"tcphpacks\"},\n\t\t\t\t\t\t\ttimestamp: s.Timestamp,\n\t\t\t\t\t\t}, {\n\t\t\t\t\t\t\tvalue:     float64(s.Network.TcpAdvanced.TCPRenoRecovery),\n\t\t\t\t\t\t\tlabels:    []string{\"tcprenorecovery\"},\n\t\t\t\t\t\t\ttimestamp: s.Timestamp,\n\t\t\t\t\t\t}, {\n\t\t\t\t\t\t\tvalue:     float64(s.Network.TcpAdvanced.TCPSackRecovery),\n\t\t\t\t\t\t\tlabels:    []string{\"tcpsackrecovery\"},\n\t\t\t\t\t\t\ttimestamp: s.Timestamp,\n\t\t\t\t\t\t}, {\n\t\t\t\t\t\t\tvalue:     float64(s.Network.TcpAdvanced.TCPSACKReneging),\n\t\t\t\t\t\t\tlabels:    []string{\"tcpsackreneging\"},\n\t\t\t\t\t\t\ttimestamp: s.Timestamp,\n\t\t\t\t\t\t}, {\n\t\t\t\t\t\t\tvalue:     float64(s.Network.TcpAdvanced.TCPFACKReorder),\n\t\t\t\t\t\t\tlabels:    []string{\"tcpfackreorder\"},\n\t\t\t\t\t\t\ttimestamp: s.Timestamp,\n\t\t\t\t\t\t}, {\n\t\t\t\t\t\t\tvalue:     float64(s.Network.TcpAdvanced.TCPSACKReorder),\n\t\t\t\t\t\t\tlabels:    []string{\"tcpsackreorder\"},\n\t\t\t\t\t\t\ttimestamp: s.Timestamp,\n\t\t\t\t\t\t}, {\n\t\t\t\t\t\t\tvalue:     float64(s.Network.TcpAdvanced.TCPRenoReorder),\n\t\t\t\t\t\t\tlabels:    []string{\"tcprenoreorder\"},\n\t\t\t\t\t\t\ttimestamp: s.Timestamp,\n\t\t\t\t\t\t}, {\n\t\t\t\t\t\t\tvalue:     float64(s.Network.TcpAdvanced.TCPTSReorder),\n\t\t\t\t\t\t\tlabels:    []string{\"tcptsreorder\"},\n\t\t\t\t\t\t\ttimestamp: s.Timestamp,\n\t\t\t\t\t\t}, {\n\t\t\t\t\t\t\tvalue:     float64(s.Network.TcpAdvanced.TCPFullUndo),\n\t\t\t\t\t\t\tlabels:    []string{\"tcpfullundo\"},\n\t\t\t\t\t\t\ttimestamp: s.Timestamp,\n\t\t\t\t\t\t}, {\n\t\t\t\t\t\t\tvalue:     float64(s.Network.TcpAdvanced.TCPPartialUndo),\n\t\t\t\t\t\t\tlabels:    []string{\"tcppartialundo\"},\n\t\t\t\t\t\t\ttimestamp: s.Timestamp,\n\t\t\t\t\t\t}, {\n\t\t\t\t\t\t\tvalue:     float64(s.Network.TcpAdvanced.TCPDSACKUndo),\n\t\t\t\t\t\t\tlabels:    []string{\"tcpdsackundo\"},\n\t\t\t\t\t\t\ttimestamp: s.Timestamp,\n\t\t\t\t\t\t}, {\n\t\t\t\t\t\t\tvalue:     float64(s.Network.TcpAdvanced.TCPLossUndo),\n\t\t\t\t\t\t\tlabels:    []string{\"tcplossundo\"},\n\t\t\t\t\t\t\ttimestamp: s.Timestamp,\n\t\t\t\t\t\t}, {\n\t\t\t\t\t\t\tvalue:     float64(s.Network.TcpAdvanced.TCPFastRetrans),\n\t\t\t\t\t\t\tlabels:    []string{\"tcpfastretrans\"},\n\t\t\t\t\t\t\ttimestamp: s.Timestamp,\n\t\t\t\t\t\t}, {\n\t\t\t\t\t\t\tvalue:     float64(s.Network.TcpAdvanced.TCPSlowStartRetrans),\n\t\t\t\t\t\t\tlabels:    []string{\"tcpslowstartretrans\"},\n\t\t\t\t\t\t\ttimestamp: s.Timestamp,\n\t\t\t\t\t\t}, {\n\t\t\t\t\t\t\tvalue:     float64(s.Network.TcpAdvanced.TCPLostRetransmit),\n\t\t\t\t\t\t\tlabels:    []string{\"tcplostretransmit\"},\n\t\t\t\t\t\t\ttimestamp: s.Timestamp,\n\t\t\t\t\t\t}, {\n\t\t\t\t\t\t\tvalue:     float64(s.Network.TcpAdvanced.TCPRetransFail),\n\t\t\t\t\t\t\tlabels:    []string{\"tcpretransfail\"},\n\t\t\t\t\t\t\ttimestamp: s.Timestamp,\n\t\t\t\t\t\t}, {\n\t\t\t\t\t\t\tvalue:     float64(s.Network.TcpAdvanced.TCPRcvCollapsed),\n\t\t\t\t\t\t\tlabels:    []string{\"tcprcvcollapsed\"},\n\t\t\t\t\t\t\ttimestamp: s.Timestamp,\n\t\t\t\t\t\t}, {\n\t\t\t\t\t\t\tvalue:     float64(s.Network.TcpAdvanced.TCPDSACKOldSent),\n\t\t\t\t\t\t\tlabels:    []string{\"tcpdsackoldsent\"},\n\t\t\t\t\t\t\ttimestamp: s.Timestamp,\n\t\t\t\t\t\t}, {\n\t\t\t\t\t\t\tvalue:     float64(s.Network.TcpAdvanced.TCPDSACKOfoSent),\n\t\t\t\t\t\t\tlabels:    []string{\"tcpdsackofosent\"},\n\t\t\t\t\t\t\ttimestamp: s.Timestamp,\n\t\t\t\t\t\t}, {\n\t\t\t\t\t\t\tvalue:     float64(s.Network.TcpAdvanced.TCPDSACKRecv),\n\t\t\t\t\t\t\tlabels:    []string{\"tcpdsackrecv\"},\n\t\t\t\t\t\t\ttimestamp: s.Timestamp,\n\t\t\t\t\t\t}, {\n\t\t\t\t\t\t\tvalue:     float64(s.Network.TcpAdvanced.TCPDSACKOfoRecv),\n\t\t\t\t\t\t\tlabels:    []string{\"tcpdsackoforecv\"},\n\t\t\t\t\t\t\ttimestamp: s.Timestamp,\n\t\t\t\t\t\t}, {\n\t\t\t\t\t\t\tvalue:     float64(s.Network.TcpAdvanced.TCPAbortOnData),\n\t\t\t\t\t\t\tlabels:    []string{\"tcpabortondata\"},\n\t\t\t\t\t\t\ttimestamp: s.Timestamp,\n\t\t\t\t\t\t}, {\n\t\t\t\t\t\t\tvalue:     float64(s.Network.TcpAdvanced.TCPAbortOnClose),\n\t\t\t\t\t\t\tlabels:    []string{\"tcpabortonclose\"},\n\t\t\t\t\t\t\ttimestamp: s.Timestamp,\n\t\t\t\t\t\t}, {\n\t\t\t\t\t\t\tvalue:     float64(s.Network.TcpAdvanced.TCPAbortOnMemory),\n\t\t\t\t\t\t\tlabels:    []string{\"tcpabortonmemory\"},\n\t\t\t\t\t\t\ttimestamp: s.Timestamp,\n\t\t\t\t\t\t}, {\n\t\t\t\t\t\t\tvalue:     float64(s.Network.TcpAdvanced.TCPAbortOnTimeout),\n\t\t\t\t\t\t\tlabels:    []string{\"tcpabortontimeout\"},\n\t\t\t\t\t\t\ttimestamp: s.Timestamp,\n\t\t\t\t\t\t}, {\n\t\t\t\t\t\t\tvalue:     float64(s.Network.TcpAdvanced.TCPAbortOnLinger),\n\t\t\t\t\t\t\tlabels:    []string{\"tcpabortonlinger\"},\n\t\t\t\t\t\t\ttimestamp: s.Timestamp,\n\t\t\t\t\t\t}, {\n\t\t\t\t\t\t\tvalue:     float64(s.Network.TcpAdvanced.TCPAbortFailed),\n\t\t\t\t\t\t\tlabels:    []string{\"tcpabortfailed\"},\n\t\t\t\t\t\t\ttimestamp: s.Timestamp,\n\t\t\t\t\t\t}, {\n\t\t\t\t\t\t\tvalue:     float64(s.Network.TcpAdvanced.TCPMemoryPressures),\n\t\t\t\t\t\t\tlabels:    []string{\"tcpmemorypressures\"},\n\t\t\t\t\t\t\ttimestamp: s.Timestamp,\n\t\t\t\t\t\t}, {\n\t\t\t\t\t\t\tvalue:     float64(s.Network.TcpAdvanced.TCPMemoryPressuresChrono),\n\t\t\t\t\t\t\tlabels:    []string{\"tcpmemorypressureschrono\"},\n\t\t\t\t\t\t\ttimestamp: s.Timestamp,\n\t\t\t\t\t\t}, {\n\t\t\t\t\t\t\tvalue:     float64(s.Network.TcpAdvanced.TCPSACKDiscard),\n\t\t\t\t\t\t\tlabels:    []string{\"tcpsackdiscard\"},\n\t\t\t\t\t\t\ttimestamp: s.Timestamp,\n\t\t\t\t\t\t}, {\n\t\t\t\t\t\t\tvalue:     float64(s.Network.TcpAdvanced.TCPDSACKIgnoredOld),\n\t\t\t\t\t\t\tlabels:    []string{\"tcpdsackignoredold\"},\n\t\t\t\t\t\t\ttimestamp: s.Timestamp,\n\t\t\t\t\t\t}, {\n\t\t\t\t\t\t\tvalue:     float64(s.Network.TcpAdvanced.TCPDSACKIgnoredNoUndo),\n\t\t\t\t\t\t\tlabels:    []string{\"tcpdsackignorednoundo\"},\n\t\t\t\t\t\t\ttimestamp: s.Timestamp,\n\t\t\t\t\t\t}, {\n\t\t\t\t\t\t\tvalue:     float64(s.Network.TcpAdvanced.TCPMD5NotFound),\n\t\t\t\t\t\t\tlabels:    []string{\"tcpmd5notfound\"},\n\t\t\t\t\t\t\ttimestamp: s.Timestamp,\n\t\t\t\t\t\t}, {\n\t\t\t\t\t\t\tvalue:     float64(s.Network.TcpAdvanced.TCPMD5Unexpected),\n\t\t\t\t\t\t\tlabels:    []string{\"tcpmd5unexpected\"},\n\t\t\t\t\t\t\ttimestamp: s.Timestamp,\n\t\t\t\t\t\t}, {\n\t\t\t\t\t\t\tvalue:     float64(s.Network.TcpAdvanced.TCPMD5Failure),\n\t\t\t\t\t\t\tlabels:    []string{\"tcpmd5failure\"},\n\t\t\t\t\t\t\ttimestamp: s.Timestamp,\n\t\t\t\t\t\t}, {\n\t\t\t\t\t\t\tvalue:     float64(s.Network.TcpAdvanced.TCPSackShifted),\n\t\t\t\t\t\t\tlabels:    []string{\"tcpsackshifted\"},\n\t\t\t\t\t\t\ttimestamp: s.Timestamp,\n\t\t\t\t\t\t}, {\n\t\t\t\t\t\t\tvalue:     float64(s.Network.TcpAdvanced.TCPSackMerged),\n\t\t\t\t\t\t\tlabels:    []string{\"tcpsackmerged\"},\n\t\t\t\t\t\t\ttimestamp: s.Timestamp,\n\t\t\t\t\t\t}, {\n\t\t\t\t\t\t\tvalue:     float64(s.Network.TcpAdvanced.TCPSackShiftFallback),\n\t\t\t\t\t\t\tlabels:    []string{\"tcpsackshiftfallback\"},\n\t\t\t\t\t\t\ttimestamp: s.Timestamp,\n\t\t\t\t\t\t}, {\n\t\t\t\t\t\t\tvalue:     float64(s.Network.TcpAdvanced.TCPBacklogDrop),\n\t\t\t\t\t\t\tlabels:    []string{\"tcpbacklogdrop\"},\n\t\t\t\t\t\t\ttimestamp: s.Timestamp,\n\t\t\t\t\t\t}, {\n\t\t\t\t\t\t\tvalue:     float64(s.Network.TcpAdvanced.PFMemallocDrop),\n\t\t\t\t\t\t\tlabels:    []string{\"pfmemallocdrop\"},\n\t\t\t\t\t\t\ttimestamp: s.Timestamp,\n\t\t\t\t\t\t}, {\n\t\t\t\t\t\t\tvalue:     float64(s.Network.TcpAdvanced.TCPMinTTLDrop),\n\t\t\t\t\t\t\tlabels:    []string{\"tcpminttldrop\"},\n\t\t\t\t\t\t\ttimestamp: s.Timestamp,\n\t\t\t\t\t\t}, {\n\t\t\t\t\t\t\tvalue:     float64(s.Network.TcpAdvanced.TCPDeferAcceptDrop),\n\t\t\t\t\t\t\tlabels:    []string{\"tcpdeferacceptdrop\"},\n\t\t\t\t\t\t\ttimestamp: s.Timestamp,\n\t\t\t\t\t\t}, {\n\t\t\t\t\t\t\tvalue:     float64(s.Network.TcpAdvanced.IPReversePathFilter),\n\t\t\t\t\t\t\tlabels:    []string{\"ipreversepathfilter\"},\n\t\t\t\t\t\t\ttimestamp: s.Timestamp,\n\t\t\t\t\t\t}, {\n\t\t\t\t\t\t\tvalue:     float64(s.Network.TcpAdvanced.TCPReqQFullDoCookies),\n\t\t\t\t\t\t\tlabels:    []string{\"tcpreqqfulldocookies\"},\n\t\t\t\t\t\t\ttimestamp: s.Timestamp,\n\t\t\t\t\t\t}, {\n\t\t\t\t\t\t\tvalue:     float64(s.Network.TcpAdvanced.TCPReqQFullDrop),\n\t\t\t\t\t\t\tlabels:    []string{\"tcpreqqfulldrop\"},\n\t\t\t\t\t\t\ttimestamp: s.Timestamp,\n\t\t\t\t\t\t}, {\n\t\t\t\t\t\t\tvalue:     float64(s.Network.TcpAdvanced.TCPFastOpenActive),\n\t\t\t\t\t\t\tlabels:    []string{\"tcpfastopenactive\"},\n\t\t\t\t\t\t\ttimestamp: s.Timestamp,\n\t\t\t\t\t\t}, {\n\t\t\t\t\t\t\tvalue:     float64(s.Network.TcpAdvanced.TCPFastOpenActiveFail),\n\t\t\t\t\t\t\tlabels:    []string{\"tcpfastopenactivefail\"},\n\t\t\t\t\t\t\ttimestamp: s.Timestamp,\n\t\t\t\t\t\t}, {\n\t\t\t\t\t\t\tvalue:     float64(s.Network.TcpAdvanced.TCPFastOpenPassive),\n\t\t\t\t\t\t\tlabels:    []string{\"tcpfastopenpassive\"},\n\t\t\t\t\t\t\ttimestamp: s.Timestamp,\n\t\t\t\t\t\t}, {\n\t\t\t\t\t\t\tvalue:     float64(s.Network.TcpAdvanced.TCPFastOpenPassiveFail),\n\t\t\t\t\t\t\tlabels:    []string{\"tcpfastopenpassivefail\"},\n\t\t\t\t\t\t\ttimestamp: s.Timestamp,\n\t\t\t\t\t\t}, {\n\t\t\t\t\t\t\tvalue:     float64(s.Network.TcpAdvanced.TCPFastOpenListenOverflow),\n\t\t\t\t\t\t\tlabels:    []string{\"tcpfastopenlistenoverflow\"},\n\t\t\t\t\t\t\ttimestamp: s.Timestamp,\n\t\t\t\t\t\t}, {\n\t\t\t\t\t\t\tvalue:     float64(s.Network.TcpAdvanced.TCPFastOpenCookieReqd),\n\t\t\t\t\t\t\tlabels:    []string{\"tcpfastopencookiereqd\"},\n\t\t\t\t\t\t\ttimestamp: s.Timestamp,\n\t\t\t\t\t\t}, {\n\t\t\t\t\t\t\tvalue:     float64(s.Network.TcpAdvanced.TCPSynRetrans),\n\t\t\t\t\t\t\tlabels:    []string{\"tcpsynretrans\"},\n\t\t\t\t\t\t\ttimestamp: s.Timestamp,\n\t\t\t\t\t\t}, {\n\t\t\t\t\t\t\tvalue:     float64(s.Network.TcpAdvanced.TCPOrigDataSent),\n\t\t\t\t\t\t\tlabels:    []string{\"tcporigdatasent\"},\n\t\t\t\t\t\t\ttimestamp: s.Timestamp,\n\t\t\t\t\t\t}, {\n\t\t\t\t\t\t\tvalue:     float64(s.Network.TcpAdvanced.PAWSActive),\n\t\t\t\t\t\t\tlabels:    []string{\"pawsactive\"},\n\t\t\t\t\t\t\ttimestamp: s.Timestamp,\n\t\t\t\t\t\t}, {\n\t\t\t\t\t\t\tvalue:     float64(s.Network.TcpAdvanced.PAWSEstab),\n\t\t\t\t\t\t\tlabels:    []string{\"pawsestab\"},\n\t\t\t\t\t\t\ttimestamp: s.Timestamp,\n\t\t\t\t\t\t},\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t},\n\t\t}...)\n\t}\n\tif includedMetrics.Has(container.NetworkUdpUsageMetrics) {\n\t\tc.containerMetrics = append(c.containerMetrics, []containerMetric{\n\t\t\t{\n\t\t\t\tname:        \"container_network_udp6_usage_total\",\n\t\t\t\thelp:        \"udp6 connection usage statistic for container\",\n\t\t\t\tvalueType:   prometheus.GaugeValue,\n\t\t\t\textraLabels: []string{\"udp_state\"},\n\t\t\t\tgetValues: func(s *info.ContainerStats) metricValues {\n\t\t\t\t\treturn metricValues{\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tvalue:     float64(s.Network.Udp6.Listen),\n\t\t\t\t\t\t\tlabels:    []string{\"listen\"},\n\t\t\t\t\t\t\ttimestamp: s.Timestamp,\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tvalue:     float64(s.Network.Udp6.Dropped),\n\t\t\t\t\t\t\tlabels:    []string{\"dropped\"},\n\t\t\t\t\t\t\ttimestamp: s.Timestamp,\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tvalue:     float64(s.Network.Udp6.RxQueued),\n\t\t\t\t\t\t\tlabels:    []string{\"rxqueued\"},\n\t\t\t\t\t\t\ttimestamp: s.Timestamp,\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tvalue:     float64(s.Network.Udp6.TxQueued),\n\t\t\t\t\t\t\tlabels:    []string{\"txqueued\"},\n\t\t\t\t\t\t\ttimestamp: s.Timestamp,\n\t\t\t\t\t\t},\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t},\n\t\t}...)\n\t\tc.containerMetrics = append(c.containerMetrics, []containerMetric{\n\t\t\t{\n\t\t\t\tname:        \"container_network_udp_usage_total\",\n\t\t\t\thelp:        \"udp connection usage statistic for container\",\n\t\t\t\tvalueType:   prometheus.GaugeValue,\n\t\t\t\textraLabels: []string{\"udp_state\"},\n\t\t\t\tgetValues: func(s *info.ContainerStats) metricValues {\n\t\t\t\t\treturn metricValues{\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tvalue:     float64(s.Network.Udp.Listen),\n\t\t\t\t\t\t\tlabels:    []string{\"listen\"},\n\t\t\t\t\t\t\ttimestamp: s.Timestamp,\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tvalue:     float64(s.Network.Udp.Dropped),\n\t\t\t\t\t\t\tlabels:    []string{\"dropped\"},\n\t\t\t\t\t\t\ttimestamp: s.Timestamp,\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tvalue:     float64(s.Network.Udp.RxQueued),\n\t\t\t\t\t\t\tlabels:    []string{\"rxqueued\"},\n\t\t\t\t\t\t\ttimestamp: s.Timestamp,\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tvalue:     float64(s.Network.Udp.TxQueued),\n\t\t\t\t\t\t\tlabels:    []string{\"txqueued\"},\n\t\t\t\t\t\t\ttimestamp: s.Timestamp,\n\t\t\t\t\t\t},\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t},\n\t\t}...)\n\t}\n\tif includedMetrics.Has(container.ProcessMetrics) {\n\t\tc.containerMetrics = append(c.containerMetrics, []containerMetric{\n\t\t\t{\n\t\t\t\tname:      \"container_processes\",\n\t\t\t\thelp:      \"Number of processes running inside the container.\",\n\t\t\t\tvalueType: prometheus.GaugeValue,\n\t\t\t\tgetValues: func(s *info.ContainerStats) metricValues {\n\t\t\t\t\treturn metricValues{{value: float64(s.Processes.ProcessCount), timestamp: s.Timestamp}}\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:      \"container_file_descriptors\",\n\t\t\t\thelp:      \"Number of open file descriptors for the container.\",\n\t\t\t\tvalueType: prometheus.GaugeValue,\n\t\t\t\tgetValues: func(s *info.ContainerStats) metricValues {\n\t\t\t\t\treturn metricValues{{value: float64(s.Processes.FdCount), timestamp: s.Timestamp}}\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:      \"container_sockets\",\n\t\t\t\thelp:      \"Number of open sockets for the container.\",\n\t\t\t\tvalueType: prometheus.GaugeValue,\n\t\t\t\tgetValues: func(s *info.ContainerStats) metricValues {\n\t\t\t\t\treturn metricValues{{value: float64(s.Processes.SocketCount), timestamp: s.Timestamp}}\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:      \"container_threads_max\",\n\t\t\t\thelp:      \"Maximum number of threads allowed inside the container, infinity if value is zero\",\n\t\t\t\tvalueType: prometheus.GaugeValue,\n\t\t\t\tgetValues: func(s *info.ContainerStats) metricValues {\n\t\t\t\t\treturn metricValues{\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tvalue:     float64(s.Processes.ThreadsMax),\n\t\t\t\t\t\t\ttimestamp: s.Timestamp,\n\t\t\t\t\t\t},\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:      \"container_threads\",\n\t\t\t\thelp:      \"Number of threads running inside the container\",\n\t\t\t\tvalueType: prometheus.GaugeValue,\n\t\t\t\tgetValues: func(s *info.ContainerStats) metricValues {\n\t\t\t\t\treturn metricValues{\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tvalue:     float64(s.Processes.ThreadsCurrent),\n\t\t\t\t\t\t\ttimestamp: s.Timestamp,\n\t\t\t\t\t\t},\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:        \"container_ulimits_soft\",\n\t\t\t\thelp:        \"Soft ulimit values for the container root process. Unlimited if -1, except priority and nice\",\n\t\t\t\tvalueType:   prometheus.GaugeValue,\n\t\t\t\textraLabels: []string{\"ulimit\"},\n\t\t\t\tgetValues: func(s *info.ContainerStats) metricValues {\n\t\t\t\t\tvalues := make(metricValues, 0, len(s.Processes.Ulimits))\n\t\t\t\t\tfor _, ulimit := range s.Processes.Ulimits {\n\t\t\t\t\t\tvalues = append(values, metricValue{\n\t\t\t\t\t\t\tvalue:     float64(ulimit.SoftLimit),\n\t\t\t\t\t\t\tlabels:    []string{ulimit.Name},\n\t\t\t\t\t\t\ttimestamp: s.Timestamp,\n\t\t\t\t\t\t})\n\t\t\t\t\t}\n\t\t\t\t\treturn values\n\t\t\t\t},\n\t\t\t},\n\t\t}...)\n\t}\n\tif includedMetrics.Has(container.PerfMetrics) {\n\t\tif includedMetrics.Has(container.PerCpuUsageMetrics) {\n\t\t\tc.containerMetrics = append(c.containerMetrics, []containerMetric{\n\t\t\t\t{\n\t\t\t\t\tname:        \"container_perf_events_total\",\n\t\t\t\t\thelp:        \"Perf event metric.\",\n\t\t\t\t\tvalueType:   prometheus.CounterValue,\n\t\t\t\t\textraLabels: []string{\"cpu\", \"event\"},\n\t\t\t\t\tgetValues: func(s *info.ContainerStats) metricValues {\n\t\t\t\t\t\treturn getPerCPUCorePerfEvents(s)\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tname:        \"container_perf_events_scaling_ratio\",\n\t\t\t\t\thelp:        \"Perf event metric scaling ratio.\",\n\t\t\t\t\tvalueType:   prometheus.GaugeValue,\n\t\t\t\t\textraLabels: []string{\"cpu\", \"event\"},\n\t\t\t\t\tgetValues: func(s *info.ContainerStats) metricValues {\n\t\t\t\t\t\treturn getPerCPUCoreScalingRatio(s)\n\t\t\t\t\t},\n\t\t\t\t}}...)\n\t\t} else {\n\t\t\tc.containerMetrics = append(c.containerMetrics, []containerMetric{\n\t\t\t\t{\n\t\t\t\t\tname:        \"container_perf_events_total\",\n\t\t\t\t\thelp:        \"Perf event metric.\",\n\t\t\t\t\tvalueType:   prometheus.CounterValue,\n\t\t\t\t\textraLabels: []string{\"cpu\", \"event\"},\n\t\t\t\t\tgetValues: func(s *info.ContainerStats) metricValues {\n\t\t\t\t\t\treturn getAggregatedCorePerfEvents(s)\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tname:        \"container_perf_events_scaling_ratio\",\n\t\t\t\t\thelp:        \"Perf event metric scaling ratio.\",\n\t\t\t\t\tvalueType:   prometheus.GaugeValue,\n\t\t\t\t\textraLabels: []string{\"cpu\", \"event\"},\n\t\t\t\t\tgetValues: func(s *info.ContainerStats) metricValues {\n\t\t\t\t\t\treturn getMinCoreScalingRatio(s)\n\t\t\t\t\t},\n\t\t\t\t}}...)\n\t\t}\n\t\tc.containerMetrics = append(c.containerMetrics, []containerMetric{\n\t\t\t{\n\t\t\t\tname:        \"container_perf_uncore_events_total\",\n\t\t\t\thelp:        \"Perf uncore event metric.\",\n\t\t\t\tvalueType:   prometheus.CounterValue,\n\t\t\t\textraLabels: []string{\"socket\", \"event\", \"pmu\"},\n\t\t\t\tgetValues: func(s *info.ContainerStats) metricValues {\n\t\t\t\t\tvalues := make(metricValues, 0, len(s.PerfUncoreStats))\n\t\t\t\t\tfor _, metric := range s.PerfUncoreStats {\n\t\t\t\t\t\tvalues = append(values, metricValue{\n\t\t\t\t\t\t\tvalue:     float64(metric.Value),\n\t\t\t\t\t\t\tlabels:    []string{strconv.Itoa(metric.Socket), metric.Name, metric.PMU},\n\t\t\t\t\t\t\ttimestamp: s.Timestamp,\n\t\t\t\t\t\t})\n\t\t\t\t\t}\n\t\t\t\t\treturn values\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:        \"container_perf_uncore_events_scaling_ratio\",\n\t\t\t\thelp:        \"Perf uncore event metric scaling ratio.\",\n\t\t\t\tvalueType:   prometheus.GaugeValue,\n\t\t\t\textraLabels: []string{\"socket\", \"event\", \"pmu\"},\n\t\t\t\tgetValues: func(s *info.ContainerStats) metricValues {\n\t\t\t\t\tvalues := make(metricValues, 0, len(s.PerfUncoreStats))\n\t\t\t\t\tfor _, metric := range s.PerfUncoreStats {\n\t\t\t\t\t\tvalues = append(values, metricValue{\n\t\t\t\t\t\t\tvalue:     metric.ScalingRatio,\n\t\t\t\t\t\t\tlabels:    []string{strconv.Itoa(metric.Socket), metric.Name, metric.PMU},\n\t\t\t\t\t\t\ttimestamp: s.Timestamp,\n\t\t\t\t\t\t})\n\t\t\t\t\t}\n\t\t\t\t\treturn values\n\t\t\t\t},\n\t\t\t},\n\t\t}...)\n\t}\n\tif includedMetrics.Has(container.ReferencedMemoryMetrics) {\n\t\tc.containerMetrics = append(c.containerMetrics, []containerMetric{\n\t\t\t{\n\t\t\t\tname:      \"container_referenced_bytes\",\n\t\t\t\thelp:      \"Container referenced bytes during last measurements cycle\",\n\t\t\t\tvalueType: prometheus.GaugeValue,\n\t\t\t\tgetValues: func(s *info.ContainerStats) metricValues {\n\t\t\t\t\treturn metricValues{{value: float64(s.ReferencedMemory), timestamp: s.Timestamp}}\n\t\t\t\t},\n\t\t\t},\n\t\t}...)\n\t}\n\tif includedMetrics.Has(container.ResctrlMetrics) {\n\t\tc.containerMetrics = append(c.containerMetrics, []containerMetric{\n\t\t\t{\n\t\t\t\tname:        \"container_memory_bandwidth_bytes\",\n\t\t\t\thelp:        \"Total memory bandwidth usage statistics for container counted with RDT Memory Bandwidth Monitoring (MBM).\",\n\t\t\t\tvalueType:   prometheus.GaugeValue,\n\t\t\t\textraLabels: []string{prometheusNodeLabelName},\n\t\t\t\tgetValues: func(s *info.ContainerStats) metricValues {\n\t\t\t\t\tnumberOfNUMANodes := len(s.Resctrl.MemoryBandwidth)\n\t\t\t\t\tmetrics := make(metricValues, numberOfNUMANodes)\n\t\t\t\t\tfor numaNode, stats := range s.Resctrl.MemoryBandwidth {\n\t\t\t\t\t\tmetrics[numaNode] = metricValue{\n\t\t\t\t\t\t\tvalue:     float64(stats.TotalBytes),\n\t\t\t\t\t\t\ttimestamp: s.Timestamp,\n\t\t\t\t\t\t\tlabels:    []string{strconv.Itoa(numaNode)},\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treturn metrics\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:        \"container_memory_bandwidth_local_bytes\",\n\t\t\t\thelp:        \"Local memory bandwidth usage statistics for container counted with RDT Memory Bandwidth Monitoring (MBM).\",\n\t\t\t\tvalueType:   prometheus.GaugeValue,\n\t\t\t\textraLabels: []string{prometheusNodeLabelName},\n\t\t\t\tgetValues: func(s *info.ContainerStats) metricValues {\n\t\t\t\t\tnumberOfNUMANodes := len(s.Resctrl.MemoryBandwidth)\n\t\t\t\t\tmetrics := make(metricValues, numberOfNUMANodes)\n\t\t\t\t\tfor numaNode, stats := range s.Resctrl.MemoryBandwidth {\n\t\t\t\t\t\tmetrics[numaNode] = metricValue{\n\t\t\t\t\t\t\tvalue:     float64(stats.LocalBytes),\n\t\t\t\t\t\t\ttimestamp: s.Timestamp,\n\t\t\t\t\t\t\tlabels:    []string{strconv.Itoa(numaNode)},\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treturn metrics\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:        \"container_llc_occupancy_bytes\",\n\t\t\t\thelp:        \"Last level cache usage statistics for container counted with RDT Memory Bandwidth Monitoring (MBM).\",\n\t\t\t\tvalueType:   prometheus.GaugeValue,\n\t\t\t\textraLabels: []string{prometheusNodeLabelName},\n\t\t\t\tgetValues: func(s *info.ContainerStats) metricValues {\n\t\t\t\t\tnumberOfNUMANodes := len(s.Resctrl.Cache)\n\t\t\t\t\tmetrics := make(metricValues, numberOfNUMANodes)\n\t\t\t\t\tfor numaNode, stats := range s.Resctrl.Cache {\n\t\t\t\t\t\tmetrics[numaNode] = metricValue{\n\t\t\t\t\t\t\tvalue:     float64(stats.LLCOccupancy),\n\t\t\t\t\t\t\ttimestamp: s.Timestamp,\n\t\t\t\t\t\t\tlabels:    []string{strconv.Itoa(numaNode)},\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treturn metrics\n\t\t\t\t},\n\t\t\t},\n\t\t}...)\n\t}\n\tif includedMetrics.Has(container.OOMMetrics) {\n\t\tc.containerMetrics = append(c.containerMetrics, containerMetric{\n\t\t\tname:      \"container_oom_events_total\",\n\t\t\thelp:      \"Count of out of memory events observed for the container\",\n\t\t\tvalueType: prometheus.CounterValue,\n\t\t\tgetValues: func(s *info.ContainerStats) metricValues {\n\t\t\t\treturn metricValues{{value: float64(s.OOMEvents), timestamp: s.Timestamp}}\n\t\t\t},\n\t\t})\n\t}\n\n\tif includedMetrics.Has(container.PressureMetrics) {\n\t\tc.containerMetrics = append(c.containerMetrics, []containerMetric{\n\t\t\t{\n\t\t\t\tname:      \"container_pressure_cpu_stalled_seconds_total\",\n\t\t\t\thelp:      \"Total time duration no tasks in the container could make progress due to CPU congestion.\",\n\t\t\t\tvalueType: prometheus.CounterValue,\n\t\t\t\tgetValues: func(s *info.ContainerStats) metricValues {\n\t\t\t\t\treturn metricValues{{value: asMicrosecondsToSeconds(s.Cpu.PSI.Full.Total), timestamp: s.Timestamp}}\n\t\t\t\t},\n\t\t\t}, {\n\t\t\t\tname:      \"container_pressure_cpu_waiting_seconds_total\",\n\t\t\t\thelp:      \"Total time duration tasks in the container have waited due to CPU congestion.\",\n\t\t\t\tvalueType: prometheus.CounterValue,\n\t\t\t\tgetValues: func(s *info.ContainerStats) metricValues {\n\t\t\t\t\treturn metricValues{{value: asMicrosecondsToSeconds(s.Cpu.PSI.Some.Total), timestamp: s.Timestamp}}\n\t\t\t\t},\n\t\t\t}, {\n\t\t\t\tname:      \"container_pressure_memory_stalled_seconds_total\",\n\t\t\t\thelp:      \"Total time duration no tasks in the container could make progress due to memory congestion.\",\n\t\t\t\tvalueType: prometheus.CounterValue,\n\t\t\t\tgetValues: func(s *info.ContainerStats) metricValues {\n\t\t\t\t\treturn metricValues{{value: asMicrosecondsToSeconds(s.Memory.PSI.Full.Total), timestamp: s.Timestamp}}\n\t\t\t\t},\n\t\t\t}, {\n\t\t\t\tname:      \"container_pressure_memory_waiting_seconds_total\",\n\t\t\t\thelp:      \"Total time duration tasks in the container have waited due to memory congestion.\",\n\t\t\t\tvalueType: prometheus.CounterValue,\n\t\t\t\tgetValues: func(s *info.ContainerStats) metricValues {\n\t\t\t\t\treturn metricValues{{value: asMicrosecondsToSeconds(s.Memory.PSI.Some.Total), timestamp: s.Timestamp}}\n\t\t\t\t},\n\t\t\t}, {\n\t\t\t\tname:      \"container_pressure_io_stalled_seconds_total\",\n\t\t\t\thelp:      \"Total time duration no tasks in the container could make progress due to IO congestion.\",\n\t\t\t\tvalueType: prometheus.CounterValue,\n\t\t\t\tgetValues: func(s *info.ContainerStats) metricValues {\n\t\t\t\t\treturn metricValues{{value: asMicrosecondsToSeconds(s.DiskIo.PSI.Full.Total), timestamp: s.Timestamp}}\n\t\t\t\t},\n\t\t\t}, {\n\t\t\t\tname:      \"container_pressure_io_waiting_seconds_total\",\n\t\t\t\thelp:      \"Total time duration tasks in the container have waited due to IO congestion.\",\n\t\t\t\tvalueType: prometheus.CounterValue,\n\t\t\t\tgetValues: func(s *info.ContainerStats) metricValues {\n\t\t\t\t\treturn metricValues{{value: asMicrosecondsToSeconds(s.DiskIo.PSI.Some.Total), timestamp: s.Timestamp}}\n\t\t\t\t},\n\t\t\t},\n\t\t}...)\n\t}\n\n\treturn c\n}\n\nvar (\n\tversionInfoDesc  = prometheus.NewDesc(\"cadvisor_version_info\", \"A metric with a constant '1' value labeled by kernel version, OS version, docker version, cadvisor version & cadvisor revision.\", []string{\"kernelVersion\", \"osVersion\", \"dockerVersion\", \"cadvisorVersion\", \"cadvisorRevision\"}, nil)\n\tcreationTimeDesc = prometheus.NewDesc(\"container_creation_time_seconds\", \"Container creation time since unix epoch in seconds.\", nil, nil)\n\tstartTimeDesc    = prometheus.NewDesc(\"container_start_time_seconds\", \"Start time of the container since unix epoch in seconds.\", nil, nil)\n\tcpuPeriodDesc    = prometheus.NewDesc(\"container_spec_cpu_period\", \"CPU period of the container.\", nil, nil)\n\tcpuQuotaDesc     = prometheus.NewDesc(\"container_spec_cpu_quota\", \"CPU quota of the container.\", nil, nil)\n\tcpuSharesDesc    = prometheus.NewDesc(\"container_spec_cpu_shares\", \"CPU share of the container.\", nil, nil)\n)\n\n// Describe describes all the metrics ever exported by cadvisor. It\n// implements prometheus.PrometheusCollector.\nfunc (c *PrometheusCollector) Describe(ch chan<- *prometheus.Desc) {\n\tc.errors.Describe(ch)\n\tfor _, cm := range c.containerMetrics {\n\t\tch <- cm.desc([]string{})\n\t}\n\tch <- creationTimeDesc\n\tch <- startTimeDesc\n\tch <- cpuPeriodDesc\n\tch <- cpuQuotaDesc\n\tch <- cpuSharesDesc\n\tch <- versionInfoDesc\n}\n\n// Collect fetches the stats from all containers and delivers them as\n// Prometheus metrics. It implements prometheus.PrometheusCollector.\nfunc (c *PrometheusCollector) Collect(ch chan<- prometheus.Metric) {\n\tc.errors.Set(0)\n\tc.collectVersionInfo(ch)\n\tc.collectContainersInfo(ch)\n\tc.errors.Collect(ch)\n}\n\nconst (\n\t// ContainerLabelPrefix is the prefix added to all container labels.\n\tContainerLabelPrefix = \"container_label_\"\n\t// ContainerEnvPrefix is the prefix added to all env variable labels.\n\tContainerEnvPrefix = \"container_env_\"\n\t// LabelID is the name of the id label.\n\tLabelID = \"id\"\n\t// LabelName is the name of the name label.\n\tLabelName = \"name\"\n\t// LabelImage is the name of the image label.\n\tLabelImage = \"image\"\n)\n\n// DefaultContainerLabels implements ContainerLabelsFunc. It exports the\n// container name, first alias, image name as well as all its env and label\n// values.\nfunc DefaultContainerLabels(container *info.ContainerInfo) map[string]string {\n\tset := map[string]string{LabelID: container.Name}\n\tif len(container.Aliases) > 0 {\n\t\tset[LabelName] = container.Aliases[0]\n\t}\n\tif image := container.Spec.Image; len(image) > 0 {\n\t\tset[LabelImage] = image\n\t}\n\tfor k, v := range container.Spec.Labels {\n\t\tset[ContainerLabelPrefix+k] = v\n\t}\n\tfor k, v := range container.Spec.Envs {\n\t\tset[ContainerEnvPrefix+k] = v\n\t}\n\treturn set\n}\n\n// BaseContainerLabels returns a ContainerLabelsFunc that exports the container\n// name, first alias, image name as well as all its white listed env and label values.\nfunc BaseContainerLabels(whiteList []string) func(container *info.ContainerInfo) map[string]string {\n\twhiteListMap := make(map[string]struct{}, len(whiteList))\n\tfor _, k := range whiteList {\n\t\twhiteListMap[k] = struct{}{}\n\t}\n\n\treturn func(container *info.ContainerInfo) map[string]string {\n\t\tset := map[string]string{LabelID: container.Name}\n\t\tif len(container.Aliases) > 0 {\n\t\t\tset[LabelName] = container.Aliases[0]\n\t\t}\n\t\tif image := container.Spec.Image; len(image) > 0 {\n\t\t\tset[LabelImage] = image\n\t\t}\n\t\tfor k, v := range container.Spec.Labels {\n\t\t\tif _, ok := whiteListMap[k]; ok {\n\t\t\t\tset[ContainerLabelPrefix+k] = v\n\t\t\t}\n\t\t}\n\t\tfor k, v := range container.Spec.Envs {\n\t\t\tset[ContainerEnvPrefix+k] = v\n\t\t}\n\t\treturn set\n\t}\n}\n\nfunc (c *PrometheusCollector) collectContainersInfo(ch chan<- prometheus.Metric) {\n\tcontainers, err := c.infoProvider.GetRequestedContainersInfo(\"/\", c.opts)\n\tif err != nil {\n\t\tc.errors.Set(1)\n\t\tklog.Warningf(\"Couldn't get containers: %s\", err)\n\t\treturn\n\t}\n\trawLabels := map[string]struct{}{}\n\tfor _, container := range containers {\n\t\tfor l := range c.containerLabelsFunc(container) {\n\t\t\trawLabels[l] = struct{}{}\n\t\t}\n\t}\n\n\tfor _, cont := range containers {\n\t\tvalues := make([]string, 0, len(rawLabels))\n\t\tlabels := make([]string, 0, len(rawLabels))\n\t\tcontainerLabels := c.containerLabelsFunc(cont)\n\t\tfor l := range rawLabels {\n\t\t\tduplicate := false\n\t\t\tsl := sanitizeLabelName(l)\n\t\t\tfor _, x := range labels {\n\t\t\t\tif sl == x {\n\t\t\t\t\tduplicate = true\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t\tif !duplicate {\n\t\t\t\tlabels = append(labels, sl)\n\t\t\t\tvalues = append(values, containerLabels[l])\n\t\t\t}\n\t\t}\n\n\t\t// Container spec\n\t\tdesc := prometheus.NewDesc(\"container_creation_time_seconds\", \"Container creation time since unix epoch in seconds.\", labels, nil)\n\t\tch <- prometheus.MustNewConstMetric(desc, prometheus.GaugeValue, float64(cont.Spec.CreationTime.Unix()), values...)\n\n\t\tdesc = prometheus.NewDesc(\"container_start_time_seconds\", \"Start time of the container since unix epoch in seconds.\", labels, nil)\n\t\tstartTime := cont.Spec.CreationTime\n\t\tif !cont.Spec.StartTime.IsZero() {\n\t\t\tstartTime = cont.Spec.StartTime\n\t\t}\n\t\tch <- prometheus.MustNewConstMetric(desc, prometheus.GaugeValue, float64(startTime.Unix()), values...)\n\n\t\tif cont.Spec.HasCpu {\n\t\t\tdesc = prometheus.NewDesc(\"container_spec_cpu_period\", \"CPU period of the container.\", labels, nil)\n\t\t\tch <- prometheus.MustNewConstMetric(desc, prometheus.GaugeValue, float64(cont.Spec.Cpu.Period), values...)\n\t\t\tif cont.Spec.Cpu.Quota != 0 {\n\t\t\t\tdesc = prometheus.NewDesc(\"container_spec_cpu_quota\", \"CPU quota of the container.\", labels, nil)\n\t\t\t\tch <- prometheus.MustNewConstMetric(desc, prometheus.GaugeValue, float64(cont.Spec.Cpu.Quota), values...)\n\t\t\t}\n\t\t\tdesc := prometheus.NewDesc(\"container_spec_cpu_shares\", \"CPU share of the container.\", labels, nil)\n\t\t\tch <- prometheus.MustNewConstMetric(desc, prometheus.GaugeValue, float64(cont.Spec.Cpu.Limit), values...)\n\n\t\t}\n\t\tif cont.Spec.HasMemory {\n\t\t\tdesc := prometheus.NewDesc(\"container_spec_memory_limit_bytes\", \"Memory limit for the container.\", labels, nil)\n\t\t\tch <- prometheus.MustNewConstMetric(desc, prometheus.GaugeValue, specMemoryValue(cont.Spec.Memory.Limit), values...)\n\t\t\tdesc = prometheus.NewDesc(\"container_spec_memory_swap_limit_bytes\", \"Memory swap limit for the container.\", labels, nil)\n\t\t\tch <- prometheus.MustNewConstMetric(desc, prometheus.GaugeValue, specMemoryValue(cont.Spec.Memory.SwapLimit), values...)\n\t\t\tdesc = prometheus.NewDesc(\"container_spec_memory_reservation_limit_bytes\", \"Memory reservation limit for the container.\", labels, nil)\n\t\t\tch <- prometheus.MustNewConstMetric(desc, prometheus.GaugeValue, specMemoryValue(cont.Spec.Memory.Reservation), values...)\n\t\t}\n\n\t\t// Now for the actual metrics\n\t\tif len(cont.Stats) == 0 {\n\t\t\tcontinue\n\t\t}\n\t\tstats := cont.Stats[0]\n\t\tfor _, cm := range c.containerMetrics {\n\t\t\tif cm.condition != nil && !cm.condition(cont.Spec) {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tdesc := cm.desc(labels)\n\t\t\tfor _, metricValue := range cm.getValues(stats) {\n\t\t\t\tch <- prometheus.NewMetricWithTimestamp(\n\t\t\t\t\tmetricValue.timestamp,\n\t\t\t\t\tprometheus.MustNewConstMetric(desc, cm.valueType, float64(metricValue.value), append(values, metricValue.labels...)...),\n\t\t\t\t)\n\t\t\t}\n\t\t}\n\t\tif c.includedMetrics.Has(container.AppMetrics) {\n\t\t\tfor metricLabel, v := range stats.CustomMetrics {\n\t\t\t\tfor _, metric := range v {\n\t\t\t\t\tclabels := make([]string, len(rawLabels), len(rawLabels)+len(metric.Labels))\n\t\t\t\t\tcvalues := make([]string, len(rawLabels), len(rawLabels)+len(metric.Labels))\n\t\t\t\t\tcopy(clabels, labels)\n\t\t\t\t\tcopy(cvalues, values)\n\t\t\t\t\tfor label, value := range metric.Labels {\n\t\t\t\t\t\tclabels = append(clabels, sanitizeLabelName(\"app_\"+label))\n\t\t\t\t\t\tcvalues = append(cvalues, value)\n\t\t\t\t\t}\n\t\t\t\t\tdesc := prometheus.NewDesc(metricLabel, \"Custom application metric.\", clabels, nil)\n\t\t\t\t\tch <- prometheus.MustNewConstMetric(desc, prometheus.GaugeValue, float64(metric.FloatValue), cvalues...)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunc (c *PrometheusCollector) collectVersionInfo(ch chan<- prometheus.Metric) {\n\tversionInfo, err := c.infoProvider.GetVersionInfo()\n\tif err != nil {\n\t\tc.errors.Set(1)\n\t\tklog.Warningf(\"Couldn't get version info: %s\", err)\n\t\treturn\n\t}\n\tch <- prometheus.MustNewConstMetric(versionInfoDesc, prometheus.GaugeValue, 1, []string{versionInfo.KernelVersion, versionInfo.ContainerOsVersion, versionInfo.DockerVersion, versionInfo.CadvisorVersion, versionInfo.CadvisorRevision}...)\n}\n\n// Size after which we consider memory to be \"unlimited\". This is not\n// MaxInt64 due to rounding by the kernel.\nconst maxMemorySize = uint64(1 << 62)\n\nfunc specMemoryValue(v uint64) float64 {\n\tif v > maxMemorySize {\n\t\treturn 0\n\t}\n\treturn float64(v)\n}\n\nvar invalidNameCharRE = regexp.MustCompile(`[^a-zA-Z0-9_]`)\n\n// sanitizeLabelName replaces anything that doesn't match\n// client_label.LabelNameRE with an underscore.\nfunc sanitizeLabelName(name string) string {\n\treturn invalidNameCharRE.ReplaceAllString(name, \"_\")\n}\n\nfunc getNumaStatsPerNode(nodeStats map[uint8]uint64, labels []string, timestamp time.Time) metricValues {\n\tmValues := make(metricValues, 0, len(nodeStats))\n\tfor node, stat := range nodeStats {\n\t\tnodeLabels := append(labels, strconv.FormatUint(uint64(node), 10))\n\t\tmValues = append(mValues, metricValue{value: float64(stat), labels: nodeLabels, timestamp: timestamp})\n\t}\n\treturn mValues\n}\n\nfunc getPerCPUCorePerfEvents(s *info.ContainerStats) metricValues {\n\tvalues := make(metricValues, 0, len(s.PerfStats))\n\tfor _, metric := range s.PerfStats {\n\t\tvalues = append(values, metricValue{\n\t\t\tvalue:     float64(metric.Value),\n\t\t\tlabels:    []string{strconv.Itoa(metric.Cpu), metric.Name},\n\t\t\ttimestamp: s.Timestamp,\n\t\t})\n\t}\n\treturn values\n}\n\nfunc getPerCPUCoreScalingRatio(s *info.ContainerStats) metricValues {\n\tvalues := make(metricValues, 0, len(s.PerfStats))\n\tfor _, metric := range s.PerfStats {\n\t\tvalues = append(values, metricValue{\n\t\t\tvalue:     metric.ScalingRatio,\n\t\t\tlabels:    []string{strconv.Itoa(metric.Cpu), metric.Name},\n\t\t\ttimestamp: s.Timestamp,\n\t\t})\n\t}\n\treturn values\n}\n\nfunc getAggregatedCorePerfEvents(s *info.ContainerStats) metricValues {\n\tvalues := make(metricValues, 0)\n\n\tperfEventStatAgg := make(map[string]uint64)\n\t// aggregate by event\n\tfor _, perfStat := range s.PerfStats {\n\t\tperfEventStatAgg[perfStat.Name] += perfStat.Value\n\t}\n\t// create aggregated metrics\n\tfor perfEvent, perfValue := range perfEventStatAgg {\n\t\tvalues = append(values, metricValue{\n\t\t\tvalue:     float64(perfValue),\n\t\t\tlabels:    []string{\"\", perfEvent},\n\t\t\ttimestamp: s.Timestamp,\n\t\t})\n\t}\n\treturn values\n}\n\nfunc getMinCoreScalingRatio(s *info.ContainerStats) metricValues {\n\tvalues := make(metricValues, 0)\n\tperfEventStatMin := make(map[string]float64)\n\t// search for minimal value of scalin ratio for specific event\n\tfor _, perfStat := range s.PerfStats {\n\t\tif _, ok := perfEventStatMin[perfStat.Name]; !ok {\n\t\t\t// found a new event\n\t\t\tperfEventStatMin[perfStat.Name] = perfStat.ScalingRatio\n\t\t} else if perfStat.ScalingRatio < perfEventStatMin[perfStat.Name] {\n\t\t\t// found a lower value of scaling ration so replace the minimal value\n\t\t\tperfEventStatMin[perfStat.Name] = perfStat.ScalingRatio\n\t\t}\n\t}\n\n\tfor perfEvent, perfScalingRatio := range perfEventStatMin {\n\t\tvalues = append(values, metricValue{\n\t\t\tvalue:     perfScalingRatio,\n\t\t\tlabels:    []string{\"\", perfEvent},\n\t\t\ttimestamp: s.Timestamp,\n\t\t})\n\t}\n\treturn values\n}\n\nfunc getContainerHealthState(s *info.ContainerStats) metricValues {\n\tvalue := float64(0)\n\tswitch s.Health.Status {\n\tcase \"healthy\":\n\t\tvalue = 1\n\tcase \"\": // if container has no health check defined\n\t\tvalue = -1\n\tdefault: // starting or unhealthy\n\t}\n\treturn metricValues{{\n\t\tvalue:     value,\n\t\ttimestamp: s.Timestamp,\n\t}}\n}\n"
  },
  {
    "path": "metrics/prometheus_fake.go",
    "content": "// Copyright 2020 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage metrics\n\nimport (\n\t\"errors\"\n\t\"time\"\n\n\tinfo \"github.com/google/cadvisor/info/v1\"\n\tv2 \"github.com/google/cadvisor/info/v2\"\n)\n\ntype testSubcontainersInfoProvider struct{}\n\nfunc (p testSubcontainersInfoProvider) GetVersionInfo() (*info.VersionInfo, error) {\n\treturn &info.VersionInfo{\n\t\tKernelVersion:      \"4.1.6-200.fc22.x86_64\",\n\t\tContainerOsVersion: \"Fedora 22 (Twenty Two)\",\n\t\tDockerVersion:      \"1.8.1\",\n\t\tCadvisorVersion:    \"0.16.0\",\n\t\tCadvisorRevision:   \"abcdef\",\n\t}, nil\n}\n\nfunc (p testSubcontainersInfoProvider) GetMachineInfo() (*info.MachineInfo, error) {\n\treturn &info.MachineInfo{\n\t\tTimestamp:        time.Unix(1395066363, 0),\n\t\tNumCores:         4,\n\t\tNumPhysicalCores: 1,\n\t\tNumSockets:       1,\n\t\tMemoryCapacity:   1024,\n\t\tMemoryByType: map[string]*info.MemoryInfo{\n\t\t\t\"Non-volatile-RAM\": {Capacity: 2168421613568, DimmCount: 8},\n\t\t\t\"Unbuffered-DDR4\":  {Capacity: 412316860416, DimmCount: 12},\n\t\t},\n\t\tNVMInfo: info.NVMInfo{\n\t\t\tMemoryModeCapacity:    429496729600,\n\t\t\tAppDirectModeCapacity: 1735166787584,\n\t\t},\n\t\tMachineID:  \"machine-id-test\",\n\t\tSystemUUID: \"system-uuid-test\",\n\t\tBootID:     \"boot-id-test\",\n\t\tTopology: []info.Node{\n\t\t\t{\n\t\t\t\tId:     0,\n\t\t\t\tMemory: 33604804608,\n\t\t\t\tHugePages: []info.HugePagesInfo{\n\t\t\t\t\t{\n\t\t\t\t\t\tPageSize: uint64(1048576),\n\t\t\t\t\t\tNumPages: uint64(0),\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tPageSize: uint64(2048),\n\t\t\t\t\t\tNumPages: uint64(0),\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tCores: []info.Core{\n\t\t\t\t\t{\n\t\t\t\t\t\tId:      0,\n\t\t\t\t\t\tThreads: []int{0, 1},\n\t\t\t\t\t\tCaches: []info.Cache{\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tSize:  32768,\n\t\t\t\t\t\t\t\tType:  \"Data\",\n\t\t\t\t\t\t\t\tLevel: 1,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tSize:  32768,\n\t\t\t\t\t\t\t\tType:  \"Instruction\",\n\t\t\t\t\t\t\t\tLevel: 1,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tSize:  262144,\n\t\t\t\t\t\t\t\tType:  \"Unified\",\n\t\t\t\t\t\t\t\tLevel: 2,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tId:      1,\n\t\t\t\t\t\tThreads: []int{2, 3},\n\t\t\t\t\t\tCaches: []info.Cache{\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tSize:  32764,\n\t\t\t\t\t\t\t\tType:  \"Data\",\n\t\t\t\t\t\t\t\tLevel: 1,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tSize:  32764,\n\t\t\t\t\t\t\t\tType:  \"Instruction\",\n\t\t\t\t\t\t\t\tLevel: 1,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tSize:  262148,\n\t\t\t\t\t\t\t\tType:  \"Unified\",\n\t\t\t\t\t\t\t\tLevel: 2,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\n\t\t\t\t\t{\n\t\t\t\t\t\tId:      2,\n\t\t\t\t\t\tThreads: []int{4, 5},\n\t\t\t\t\t\tCaches: []info.Cache{\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tSize:  32768,\n\t\t\t\t\t\t\t\tType:  \"Data\",\n\t\t\t\t\t\t\t\tLevel: 1,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tSize:  32768,\n\t\t\t\t\t\t\t\tType:  \"Instruction\",\n\t\t\t\t\t\t\t\tLevel: 1,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tSize:  262144,\n\t\t\t\t\t\t\t\tType:  \"Unified\",\n\t\t\t\t\t\t\t\tLevel: 2,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tId:      3,\n\t\t\t\t\t\tThreads: []int{6, 7},\n\t\t\t\t\t\tCaches: []info.Cache{\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tSize:  32764,\n\t\t\t\t\t\t\t\tType:  \"Data\",\n\t\t\t\t\t\t\t\tLevel: 1,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tSize:  32764,\n\t\t\t\t\t\t\t\tType:  \"Instruction\",\n\t\t\t\t\t\t\t\tLevel: 1,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tSize:  262148,\n\t\t\t\t\t\t\t\tType:  \"Unified\",\n\t\t\t\t\t\t\t\tLevel: 2,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tDistances: []uint64{\n\t\t\t\t\t10,\n\t\t\t\t\t12,\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tId:     1,\n\t\t\t\tMemory: 33604804606,\n\t\t\t\tHugePages: []info.HugePagesInfo{\n\t\t\t\t\t{\n\t\t\t\t\t\tPageSize: uint64(1048576),\n\t\t\t\t\t\tNumPages: uint64(2),\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tPageSize: uint64(2048),\n\t\t\t\t\t\tNumPages: uint64(4),\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tCores: []info.Core{\n\t\t\t\t\t{\n\t\t\t\t\t\tId:      4,\n\t\t\t\t\t\tThreads: []int{8, 9},\n\t\t\t\t\t\tCaches: []info.Cache{\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tSize:  32768,\n\t\t\t\t\t\t\t\tType:  \"Data\",\n\t\t\t\t\t\t\t\tLevel: 1,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tSize:  32768,\n\t\t\t\t\t\t\t\tType:  \"Instruction\",\n\t\t\t\t\t\t\t\tLevel: 1,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tSize:  262144,\n\t\t\t\t\t\t\t\tType:  \"Unified\",\n\t\t\t\t\t\t\t\tLevel: 2,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tId:      5,\n\t\t\t\t\t\tThreads: []int{10, 11},\n\t\t\t\t\t\tCaches: []info.Cache{\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tSize:  32764,\n\t\t\t\t\t\t\t\tType:  \"Data\",\n\t\t\t\t\t\t\t\tLevel: 1,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tSize:  32764,\n\t\t\t\t\t\t\t\tType:  \"Instruction\",\n\t\t\t\t\t\t\t\tLevel: 1,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tSize:  262148,\n\t\t\t\t\t\t\t\tType:  \"Unified\",\n\t\t\t\t\t\t\t\tLevel: 2,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tId:      6,\n\t\t\t\t\t\tThreads: []int{12, 13},\n\t\t\t\t\t\tCaches: []info.Cache{\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tSize:  32768,\n\t\t\t\t\t\t\t\tType:  \"Data\",\n\t\t\t\t\t\t\t\tLevel: 1,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tSize:  32768,\n\t\t\t\t\t\t\t\tType:  \"Instruction\",\n\t\t\t\t\t\t\t\tLevel: 1,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tSize:  262144,\n\t\t\t\t\t\t\t\tType:  \"Unified\",\n\t\t\t\t\t\t\t\tLevel: 2,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tId:      7,\n\t\t\t\t\t\tThreads: []int{14, 15},\n\t\t\t\t\t\tCaches: []info.Cache{\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tSize:  32764,\n\t\t\t\t\t\t\t\tType:  \"Data\",\n\t\t\t\t\t\t\t\tLevel: 1,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tSize:  32764,\n\t\t\t\t\t\t\t\tType:  \"Instruction\",\n\t\t\t\t\t\t\t\tLevel: 1,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tSize:  262148,\n\t\t\t\t\t\t\t\tType:  \"Unified\",\n\t\t\t\t\t\t\t\tLevel: 2,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tCaches: []info.Cache{\n\t\t\t\t\t{\n\t\t\t\t\t\tSize:  8388608,\n\t\t\t\t\t\tType:  \"Unified\",\n\t\t\t\t\t\tLevel: 3,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tDistances: []uint64{\n\t\t\t\t\t12,\n\t\t\t\t\t10,\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}, nil\n}\n\nfunc (p testSubcontainersInfoProvider) GetRequestedContainersInfo(string, v2.RequestOptions) (map[string]*info.ContainerInfo, error) {\n\treturn map[string]*info.ContainerInfo{\n\t\t\"testcontainer\": {\n\t\t\tContainerReference: info.ContainerReference{\n\t\t\t\tName:    \"testcontainer\",\n\t\t\t\tAliases: []string{\"testcontaineralias\"},\n\t\t\t},\n\t\t\tSpec: info.ContainerSpec{\n\t\t\t\tImage:  \"test\",\n\t\t\t\tHasCpu: true,\n\t\t\t\tCpu: info.CpuSpec{\n\t\t\t\t\tLimit:  1000,\n\t\t\t\t\tPeriod: 100000,\n\t\t\t\t\tQuota:  10000,\n\t\t\t\t},\n\t\t\t\tMemory: info.MemorySpec{\n\t\t\t\t\tLimit:       2048,\n\t\t\t\t\tReservation: 1024,\n\t\t\t\t\tSwapLimit:   4096,\n\t\t\t\t},\n\t\t\t\tHasHugetlb:   true,\n\t\t\t\tHasProcesses: true,\n\t\t\t\tProcesses: info.ProcessSpec{\n\t\t\t\t\tLimit: 100,\n\t\t\t\t},\n\t\t\t\tCreationTime: time.Unix(1257894000, 0),\n\t\t\t\tStartTime:    time.Unix(1257895000, 0),\n\t\t\t\tLabels: map[string]string{\n\t\t\t\t\t\"foo.label\": \"bar\",\n\t\t\t\t},\n\t\t\t\tEnvs: map[string]string{\n\t\t\t\t\t\"foo+env\": \"prod\",\n\t\t\t\t},\n\t\t\t},\n\t\t\tStats: []*info.ContainerStats{\n\t\t\t\t{\n\t\t\t\t\tTimestamp: time.Unix(1395066363, 0),\n\t\t\t\t\tCpu: info.CpuStats{\n\t\t\t\t\t\tUsage: info.CpuUsage{\n\t\t\t\t\t\t\tTotal:  1,\n\t\t\t\t\t\t\tPerCpu: []uint64{2, 3, 4, 5},\n\t\t\t\t\t\t\tUser:   6,\n\t\t\t\t\t\t\tSystem: 7,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tCFS: info.CpuCFS{\n\t\t\t\t\t\t\tPeriods:          723,\n\t\t\t\t\t\t\tThrottledPeriods: 18,\n\t\t\t\t\t\t\tThrottledTime:    1724314000,\n\t\t\t\t\t\t\tBurstsPeriods:    25,\n\t\t\t\t\t\t\tBurstTime:        500000000,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tSchedstat: info.CpuSchedstat{\n\t\t\t\t\t\t\tRunTime:      53643567,\n\t\t\t\t\t\t\tRunqueueTime: 479424566378,\n\t\t\t\t\t\t\tRunPeriods:   984285,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tLoadAverage:  2,\n\t\t\t\t\t\tLoadDAverage: 2,\n\t\t\t\t\t\tPSI: info.PSIStats{\n\t\t\t\t\t\t\tFull: info.PSIData{\n\t\t\t\t\t\t\t\tAvg10:  0.3,\n\t\t\t\t\t\t\t\tAvg60:  0.2,\n\t\t\t\t\t\t\t\tAvg300: 0.1,\n\t\t\t\t\t\t\t\tTotal:  100,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tSome: info.PSIData{\n\t\t\t\t\t\t\t\tAvg10:  0.6,\n\t\t\t\t\t\t\t\tAvg60:  0.4,\n\t\t\t\t\t\t\t\tAvg300: 0.2,\n\t\t\t\t\t\t\t\tTotal:  200,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\tMemory: info.MemoryStats{\n\t\t\t\t\t\tUsage:             8,\n\t\t\t\t\t\tMaxUsage:          8,\n\t\t\t\t\t\tWorkingSet:        9,\n\t\t\t\t\t\tTotalActiveFile:   7,\n\t\t\t\t\t\tTotalInactiveFile: 6,\n\t\t\t\t\t\tContainerData: info.MemoryStatsMemoryData{\n\t\t\t\t\t\t\tPgfault:    10,\n\t\t\t\t\t\t\tPgmajfault: 11,\n\t\t\t\t\t\t\tNumaStats: info.MemoryNumaStats{\n\t\t\t\t\t\t\t\tFile:        map[uint8]uint64{0: 16649, 1: 10000},\n\t\t\t\t\t\t\t\tAnon:        map[uint8]uint64{0: 10000, 1: 7109},\n\t\t\t\t\t\t\t\tUnevictable: map[uint8]uint64{0: 8900, 1: 10000},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tHierarchicalData: info.MemoryStatsMemoryData{\n\t\t\t\t\t\t\tPgfault:    12,\n\t\t\t\t\t\t\tPgmajfault: 13,\n\t\t\t\t\t\t\tNumaStats: info.MemoryNumaStats{\n\t\t\t\t\t\t\t\tFile:        map[uint8]uint64{0: 36649, 1: 10000},\n\t\t\t\t\t\t\t\tAnon:        map[uint8]uint64{0: 20000, 1: 7109},\n\t\t\t\t\t\t\t\tUnevictable: map[uint8]uint64{0: 8900, 1: 20000},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tCache:       14,\n\t\t\t\t\t\tRSS:         15,\n\t\t\t\t\t\tMappedFile:  16,\n\t\t\t\t\t\tKernelUsage: 17,\n\t\t\t\t\t\tSwap:        8192,\n\t\t\t\t\t\tPSI: info.PSIStats{\n\t\t\t\t\t\t\tFull: info.PSIData{\n\t\t\t\t\t\t\t\tAvg10:  0.3,\n\t\t\t\t\t\t\t\tAvg60:  0.2,\n\t\t\t\t\t\t\t\tAvg300: 0.1,\n\t\t\t\t\t\t\t\tTotal:  1000,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tSome: info.PSIData{\n\t\t\t\t\t\t\t\tAvg10:  0.6,\n\t\t\t\t\t\t\t\tAvg60:  0.4,\n\t\t\t\t\t\t\t\tAvg300: 0.2,\n\t\t\t\t\t\t\t\tTotal:  2000,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\tHugetlb: map[string]info.HugetlbStats{\n\t\t\t\t\t\t\"2Mi\": {\n\t\t\t\t\t\t\tUsage:    4,\n\t\t\t\t\t\t\tMaxUsage: 10,\n\t\t\t\t\t\t\tFailcnt:  1,\n\t\t\t\t\t\t},\n\t\t\t\t\t\t\"1Gi\": {\n\t\t\t\t\t\t\tUsage:    0,\n\t\t\t\t\t\t\tMaxUsage: 0,\n\t\t\t\t\t\t\tFailcnt:  0,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\tNetwork: info.NetworkStats{\n\t\t\t\t\t\tInterfaceStats: info.InterfaceStats{\n\t\t\t\t\t\t\tName:      \"eth0\",\n\t\t\t\t\t\t\tRxBytes:   14,\n\t\t\t\t\t\t\tRxPackets: 15,\n\t\t\t\t\t\t\tRxErrors:  16,\n\t\t\t\t\t\t\tRxDropped: 17,\n\t\t\t\t\t\t\tTxBytes:   18,\n\t\t\t\t\t\t\tTxPackets: 19,\n\t\t\t\t\t\t\tTxErrors:  20,\n\t\t\t\t\t\t\tTxDropped: 21,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tInterfaces: []info.InterfaceStats{\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tName:      \"eth0\",\n\t\t\t\t\t\t\t\tRxBytes:   14,\n\t\t\t\t\t\t\t\tRxPackets: 15,\n\t\t\t\t\t\t\t\tRxErrors:  16,\n\t\t\t\t\t\t\t\tRxDropped: 17,\n\t\t\t\t\t\t\t\tTxBytes:   18,\n\t\t\t\t\t\t\t\tTxPackets: 19,\n\t\t\t\t\t\t\t\tTxErrors:  20,\n\t\t\t\t\t\t\t\tTxDropped: 21,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tTcp: info.TcpStat{\n\t\t\t\t\t\t\tEstablished: 13,\n\t\t\t\t\t\t\tSynSent:     0,\n\t\t\t\t\t\t\tSynRecv:     0,\n\t\t\t\t\t\t\tFinWait1:    0,\n\t\t\t\t\t\t\tFinWait2:    0,\n\t\t\t\t\t\t\tTimeWait:    0,\n\t\t\t\t\t\t\tClose:       0,\n\t\t\t\t\t\t\tCloseWait:   0,\n\t\t\t\t\t\t\tLastAck:     0,\n\t\t\t\t\t\t\tListen:      3,\n\t\t\t\t\t\t\tClosing:     0,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tTcp6: info.TcpStat{\n\t\t\t\t\t\t\tEstablished: 11,\n\t\t\t\t\t\t\tSynSent:     0,\n\t\t\t\t\t\t\tSynRecv:     0,\n\t\t\t\t\t\t\tFinWait1:    0,\n\t\t\t\t\t\t\tFinWait2:    0,\n\t\t\t\t\t\t\tTimeWait:    0,\n\t\t\t\t\t\t\tClose:       0,\n\t\t\t\t\t\t\tCloseWait:   0,\n\t\t\t\t\t\t\tLastAck:     0,\n\t\t\t\t\t\t\tListen:      3,\n\t\t\t\t\t\t\tClosing:     0,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tTcpAdvanced: info.TcpAdvancedStat{\n\t\t\t\t\t\t\tTCPFullUndo:               2361,\n\t\t\t\t\t\t\tTCPMD5NotFound:            0,\n\t\t\t\t\t\t\tTCPDSACKRecv:              83680,\n\t\t\t\t\t\t\tTCPSackShifted:            2,\n\t\t\t\t\t\t\tTCPSackShiftFallback:      298,\n\t\t\t\t\t\t\tPFMemallocDrop:            0,\n\t\t\t\t\t\t\tEstabResets:               37,\n\t\t\t\t\t\t\tInSegs:                    140370590,\n\t\t\t\t\t\t\tTCPPureAcks:               24251339,\n\t\t\t\t\t\t\tTCPDSACKOldSent:           15633,\n\t\t\t\t\t\t\tIPReversePathFilter:       0,\n\t\t\t\t\t\t\tTCPFastOpenPassiveFail:    0,\n\t\t\t\t\t\t\tInCsumErrors:              0,\n\t\t\t\t\t\t\tTCPRenoFailures:           43414,\n\t\t\t\t\t\t\tTCPMemoryPressuresChrono:  0,\n\t\t\t\t\t\t\tTCPDeferAcceptDrop:        0,\n\t\t\t\t\t\t\tTW:                        10436427,\n\t\t\t\t\t\t\tTCPSpuriousRTOs:           0,\n\t\t\t\t\t\t\tTCPDSACKIgnoredNoUndo:     71885,\n\t\t\t\t\t\t\tRtoMax:                    120000,\n\t\t\t\t\t\t\tActiveOpens:               11038621,\n\t\t\t\t\t\t\tEmbryonicRsts:             0,\n\t\t\t\t\t\t\tRcvPruned:                 0,\n\t\t\t\t\t\t\tTCPLossProbeRecovery:      401,\n\t\t\t\t\t\t\tTCPHPHits:                 56096478,\n\t\t\t\t\t\t\tTCPPartialUndo:            3,\n\t\t\t\t\t\t\tTCPAbortOnMemory:          0,\n\t\t\t\t\t\t\tAttemptFails:              48997,\n\t\t\t\t\t\t\tRetransSegs:               462961,\n\t\t\t\t\t\t\tSyncookiesFailed:          0,\n\t\t\t\t\t\t\tOfoPruned:                 0,\n\t\t\t\t\t\t\tTCPAbortOnLinger:          0,\n\t\t\t\t\t\t\tTCPAbortFailed:            0,\n\t\t\t\t\t\t\tTCPRenoReorder:            839,\n\t\t\t\t\t\t\tTCPRcvCollapsed:           0,\n\t\t\t\t\t\t\tTCPDSACKIgnoredOld:        0,\n\t\t\t\t\t\t\tTCPReqQFullDrop:           0,\n\t\t\t\t\t\t\tOutOfWindowIcmps:          0,\n\t\t\t\t\t\t\tTWKilled:                  0,\n\t\t\t\t\t\t\tTCPLossProbes:             88648,\n\t\t\t\t\t\t\tTCPRenoRecoveryFail:       394,\n\t\t\t\t\t\t\tTCPFastOpenCookieReqd:     0,\n\t\t\t\t\t\t\tTCPHPAcks:                 21490641,\n\t\t\t\t\t\t\tTCPSACKReneging:           0,\n\t\t\t\t\t\t\tTCPTSReorder:              3,\n\t\t\t\t\t\t\tTCPSlowStartRetrans:       290832,\n\t\t\t\t\t\t\tMaxConn:                   -1,\n\t\t\t\t\t\t\tSyncookiesRecv:            0,\n\t\t\t\t\t\t\tTCPSackFailures:           60,\n\t\t\t\t\t\t\tDelayedACKLocked:          90,\n\t\t\t\t\t\t\tTCPDSACKOfoSent:           1,\n\t\t\t\t\t\t\tTCPSynRetrans:             988,\n\t\t\t\t\t\t\tTCPDSACKOfoRecv:           10,\n\t\t\t\t\t\t\tTCPSACKDiscard:            0,\n\t\t\t\t\t\t\tTCPMD5Unexpected:          0,\n\t\t\t\t\t\t\tTCPSackMerged:             6,\n\t\t\t\t\t\t\tRtoMin:                    200,\n\t\t\t\t\t\t\tCurrEstab:                 22,\n\t\t\t\t\t\t\tTCPTimeWaitOverflow:       0,\n\t\t\t\t\t\t\tListenOverflows:           0,\n\t\t\t\t\t\t\tDelayedACKs:               503975,\n\t\t\t\t\t\t\tTCPLossUndo:               61374,\n\t\t\t\t\t\t\tTCPOrigDataSent:           130698387,\n\t\t\t\t\t\t\tTCPBacklogDrop:            0,\n\t\t\t\t\t\t\tTCPReqQFullDoCookies:      0,\n\t\t\t\t\t\t\tTCPFastOpenPassive:        0,\n\t\t\t\t\t\t\tPAWSActive:                0,\n\t\t\t\t\t\t\tOutRsts:                   91699,\n\t\t\t\t\t\t\tTCPSackRecoveryFail:       2,\n\t\t\t\t\t\t\tDelayedACKLost:            18843,\n\t\t\t\t\t\t\tTCPAbortOnData:            8,\n\t\t\t\t\t\t\tTCPMinTTLDrop:             0,\n\t\t\t\t\t\t\tPruneCalled:               0,\n\t\t\t\t\t\t\tTWRecycled:                0,\n\t\t\t\t\t\t\tListenDrops:               0,\n\t\t\t\t\t\t\tTCPAbortOnTimeout:         0,\n\t\t\t\t\t\t\tSyncookiesSent:            0,\n\t\t\t\t\t\t\tTCPSACKReorder:            11,\n\t\t\t\t\t\t\tTCPDSACKUndo:              33,\n\t\t\t\t\t\t\tTCPMD5Failure:             0,\n\t\t\t\t\t\t\tTCPLostRetransmit:         0,\n\t\t\t\t\t\t\tTCPAbortOnClose:           7,\n\t\t\t\t\t\t\tTCPFastOpenListenOverflow: 0,\n\t\t\t\t\t\t\tOutSegs:                   211580512,\n\t\t\t\t\t\t\tInErrs:                    31,\n\t\t\t\t\t\t\tTCPTimeouts:               27422,\n\t\t\t\t\t\t\tTCPLossFailures:           729,\n\t\t\t\t\t\t\tTCPSackRecovery:           159,\n\t\t\t\t\t\t\tRtoAlgorithm:              1,\n\t\t\t\t\t\t\tPassiveOpens:              59,\n\t\t\t\t\t\t\tLockDroppedIcmps:          0,\n\t\t\t\t\t\t\tTCPRenoRecovery:           3519,\n\t\t\t\t\t\t\tTCPFACKReorder:            0,\n\t\t\t\t\t\t\tTCPFastRetrans:            11794,\n\t\t\t\t\t\t\tTCPRetransFail:            0,\n\t\t\t\t\t\t\tTCPMemoryPressures:        0,\n\t\t\t\t\t\t\tTCPFastOpenActive:         0,\n\t\t\t\t\t\t\tTCPFastOpenActiveFail:     0,\n\t\t\t\t\t\t\tPAWSEstab:                 0,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tUdp: info.UdpStat{\n\t\t\t\t\t\t\tListen:   0,\n\t\t\t\t\t\t\tDropped:  0,\n\t\t\t\t\t\t\tRxQueued: 0,\n\t\t\t\t\t\t\tTxQueued: 0,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tUdp6: info.UdpStat{\n\t\t\t\t\t\t\tListen:   0,\n\t\t\t\t\t\t\tDropped:  0,\n\t\t\t\t\t\t\tRxQueued: 0,\n\t\t\t\t\t\t\tTxQueued: 0,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\tDiskIo: info.DiskIoStats{\n\t\t\t\t\t\tIoServiceBytes: []info.PerDiskStats{{\n\t\t\t\t\t\t\tDevice: \"/dev/sdb\",\n\t\t\t\t\t\t\tMajor:  8,\n\t\t\t\t\t\t\tMinor:  0,\n\t\t\t\t\t\t\tStats: map[string]uint64{\n\t\t\t\t\t\t\t\t\"Async\":   1,\n\t\t\t\t\t\t\t\t\"Discard\": 2,\n\t\t\t\t\t\t\t\t\"Read\":    3,\n\t\t\t\t\t\t\t\t\"Sync\":    4,\n\t\t\t\t\t\t\t\t\"Total\":   5,\n\t\t\t\t\t\t\t\t\"Write\":   6,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t}},\n\t\t\t\t\t\tIoCostUsage: []info.PerDiskStats{{\n\t\t\t\t\t\t\tDevice: \"sda1\",\n\t\t\t\t\t\t\tMajor:  8,\n\t\t\t\t\t\t\tMinor:  1,\n\t\t\t\t\t\t\tStats:  map[string]uint64{\"Count\": 1500000},\n\t\t\t\t\t\t}},\n\t\t\t\t\t\tIoCostWait: []info.PerDiskStats{{\n\t\t\t\t\t\t\tDevice: \"sda1\",\n\t\t\t\t\t\t\tMajor:  8,\n\t\t\t\t\t\t\tMinor:  1,\n\t\t\t\t\t\t\tStats:  map[string]uint64{\"Count\": 2500000},\n\t\t\t\t\t\t}},\n\t\t\t\t\t\tIoCostIndebt: []info.PerDiskStats{{\n\t\t\t\t\t\t\tDevice: \"sda1\",\n\t\t\t\t\t\t\tMajor:  8,\n\t\t\t\t\t\t\tMinor:  1,\n\t\t\t\t\t\t\tStats:  map[string]uint64{\"Count\": 500000},\n\t\t\t\t\t\t}},\n\t\t\t\t\t\tIoCostIndelay: []info.PerDiskStats{{\n\t\t\t\t\t\t\tDevice: \"sda1\",\n\t\t\t\t\t\t\tMajor:  8,\n\t\t\t\t\t\t\tMinor:  1,\n\t\t\t\t\t\t\tStats:  map[string]uint64{\"Count\": 750000},\n\t\t\t\t\t\t}},\n\t\t\t\t\t\tPSI: info.PSIStats{\n\t\t\t\t\t\t\tFull: info.PSIData{\n\t\t\t\t\t\t\t\tAvg10:  0.3,\n\t\t\t\t\t\t\t\tAvg60:  0.2,\n\t\t\t\t\t\t\t\tAvg300: 0.1,\n\t\t\t\t\t\t\t\tTotal:  1100,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tSome: info.PSIData{\n\t\t\t\t\t\t\t\tAvg10:  0.6,\n\t\t\t\t\t\t\t\tAvg60:  0.4,\n\t\t\t\t\t\t\t\tAvg300: 0.2,\n\t\t\t\t\t\t\t\tTotal:  2200,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\tFilesystem: []info.FsStats{\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tDevice:          \"sda1\",\n\t\t\t\t\t\t\tInodesFree:      524288,\n\t\t\t\t\t\t\tInodes:          2097152,\n\t\t\t\t\t\t\tLimit:           22,\n\t\t\t\t\t\t\tUsage:           23,\n\t\t\t\t\t\t\tReadsCompleted:  24,\n\t\t\t\t\t\t\tReadsMerged:     25,\n\t\t\t\t\t\t\tSectorsRead:     26,\n\t\t\t\t\t\t\tReadTime:        27,\n\t\t\t\t\t\t\tWritesCompleted: 28,\n\t\t\t\t\t\t\tWritesMerged:    39,\n\t\t\t\t\t\t\tSectorsWritten:  40,\n\t\t\t\t\t\t\tWriteTime:       41,\n\t\t\t\t\t\t\tIoInProgress:    42,\n\t\t\t\t\t\t\tIoTime:          43,\n\t\t\t\t\t\t\tWeightedIoTime:  44,\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tDevice:          \"sda2\",\n\t\t\t\t\t\t\tInodesFree:      262144,\n\t\t\t\t\t\t\tInodes:          2097152,\n\t\t\t\t\t\t\tLimit:           37,\n\t\t\t\t\t\t\tUsage:           38,\n\t\t\t\t\t\t\tReadsCompleted:  39,\n\t\t\t\t\t\t\tReadsMerged:     40,\n\t\t\t\t\t\t\tSectorsRead:     41,\n\t\t\t\t\t\t\tReadTime:        42,\n\t\t\t\t\t\t\tWritesCompleted: 43,\n\t\t\t\t\t\t\tWritesMerged:    44,\n\t\t\t\t\t\t\tSectorsWritten:  45,\n\t\t\t\t\t\t\tWriteTime:       46,\n\t\t\t\t\t\t\tIoInProgress:    47,\n\t\t\t\t\t\t\tIoTime:          48,\n\t\t\t\t\t\t\tWeightedIoTime:  49,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\tAccelerators: []info.AcceleratorStats{\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tMake:        \"nvidia\",\n\t\t\t\t\t\t\tModel:       \"tesla-p100\",\n\t\t\t\t\t\t\tID:          \"GPU-deadbeef-1234-5678-90ab-feedfacecafe\",\n\t\t\t\t\t\t\tMemoryTotal: 20304050607,\n\t\t\t\t\t\t\tMemoryUsed:  2030405060,\n\t\t\t\t\t\t\tDutyCycle:   12,\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tMake:        \"nvidia\",\n\t\t\t\t\t\t\tModel:       \"tesla-k80\",\n\t\t\t\t\t\t\tID:          \"GPU-deadbeef-0123-4567-89ab-feedfacecafe\",\n\t\t\t\t\t\t\tMemoryTotal: 10203040506,\n\t\t\t\t\t\t\tMemoryUsed:  1020304050,\n\t\t\t\t\t\t\tDutyCycle:   6,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\tProcesses: info.ProcessStats{\n\t\t\t\t\t\tProcessCount:   1,\n\t\t\t\t\t\tFdCount:        5,\n\t\t\t\t\t\tSocketCount:    3,\n\t\t\t\t\t\tThreadsCurrent: 5,\n\t\t\t\t\t\tThreadsMax:     100,\n\t\t\t\t\t\tUlimits: []info.UlimitSpec{\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tName:      \"max_open_files\",\n\t\t\t\t\t\t\t\tSoftLimit: 16384,\n\t\t\t\t\t\t\t\tHardLimit: 16384,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\tTaskStats: info.LoadStats{\n\t\t\t\t\t\tNrSleeping:        50,\n\t\t\t\t\t\tNrRunning:         51,\n\t\t\t\t\t\tNrStopped:         52,\n\t\t\t\t\t\tNrUninterruptible: 53,\n\t\t\t\t\t\tNrIoWait:          54,\n\t\t\t\t\t},\n\t\t\t\t\tCustomMetrics: map[string][]info.MetricVal{\n\t\t\t\t\t\t\"container_custom_app_metric_1\": {\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tFloatValue: float64(1.1),\n\t\t\t\t\t\t\t\tTimestamp:  time.Now(),\n\t\t\t\t\t\t\t\tLabel:      \"testlabel_1_1_1\",\n\t\t\t\t\t\t\t\tLabels:     map[string]string{\"test_label\": \"1_1\", \"test_label_2\": \"2_1\"},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tFloatValue: float64(1.2),\n\t\t\t\t\t\t\t\tTimestamp:  time.Now(),\n\t\t\t\t\t\t\t\tLabel:      \"testlabel_1_1_2\",\n\t\t\t\t\t\t\t\tLabels:     map[string]string{\"test_label\": \"1_2\", \"test_label_2\": \"2_2\"},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\t\"container_custom_app_metric_2\": {\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tFloatValue: float64(2),\n\t\t\t\t\t\t\t\tTimestamp:  time.Now(),\n\t\t\t\t\t\t\t\tLabel:      \"testlabel2\",\n\t\t\t\t\t\t\t\tLabels:     map[string]string{\"test_label\": \"test_value\"},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\t\"container_custom_app_metric_3\": {\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tFloatValue: float64(3),\n\t\t\t\t\t\t\t\tTimestamp:  time.Now(),\n\t\t\t\t\t\t\t\tLabel:      \"testlabel3\",\n\t\t\t\t\t\t\t\tLabels:     map[string]string{\"test_label\": \"test_value\"},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\tPerfStats: []info.PerfStat{\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tPerfValue: info.PerfValue{\n\t\t\t\t\t\t\t\tScalingRatio: 1.0,\n\t\t\t\t\t\t\t\tValue:        123,\n\t\t\t\t\t\t\t\tName:         \"instructions\",\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tCpu: 0,\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tPerfValue: info.PerfValue{\n\t\t\t\t\t\t\t\tScalingRatio: 0.5,\n\t\t\t\t\t\t\t\tValue:        456,\n\t\t\t\t\t\t\t\tName:         \"instructions\",\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tCpu: 1,\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tPerfValue: info.PerfValue{\n\t\t\t\t\t\t\t\tScalingRatio: 0.66666666666,\n\t\t\t\t\t\t\t\tValue:        321,\n\t\t\t\t\t\t\t\tName:         \"instructions_retired\",\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tCpu: 0,\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tPerfValue: info.PerfValue{\n\t\t\t\t\t\t\t\tScalingRatio: 0.33333333333,\n\t\t\t\t\t\t\t\tValue:        789,\n\t\t\t\t\t\t\t\tName:         \"instructions_retired\",\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tCpu: 1,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\tPerfUncoreStats: []info.PerfUncoreStat{\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tPerfValue: info.PerfValue{\n\t\t\t\t\t\t\t\tScalingRatio: 1.0,\n\t\t\t\t\t\t\t\tValue:        1231231512.0,\n\t\t\t\t\t\t\t\tName:         \"cas_count_read\",\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tSocket: 0,\n\t\t\t\t\t\t\tPMU:    \"uncore_imc_0\",\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tPerfValue: info.PerfValue{\n\t\t\t\t\t\t\t\tScalingRatio: 1.0,\n\t\t\t\t\t\t\t\tValue:        1111231331.0,\n\t\t\t\t\t\t\t\tName:         \"cas_count_read\",\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tSocket: 1,\n\t\t\t\t\t\t\tPMU:    \"uncore_imc_0\",\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\tReferencedMemory: 1234,\n\t\t\t\t\tResctrl: info.ResctrlStats{\n\t\t\t\t\t\tMemoryBandwidth: []info.MemoryBandwidthStats{\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tTotalBytes: 4512312,\n\t\t\t\t\t\t\t\tLocalBytes: 2390393,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tTotalBytes: 2173713,\n\t\t\t\t\t\t\t\tLocalBytes: 1231233,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tCache: []info.CacheStats{\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tLLCOccupancy: 162626,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tLLCOccupancy: 213777,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\tCpuSet: info.CPUSetStats{MemoryMigrate: 1},\n\t\t\t\t\tHealth: info.Health{Status: \"healthy\"},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}, nil\n}\n\ntype erroringSubcontainersInfoProvider struct {\n\tsuccessfulProvider testSubcontainersInfoProvider\n\tshouldFail         bool\n}\n\nfunc (p *erroringSubcontainersInfoProvider) GetVersionInfo() (*info.VersionInfo, error) {\n\tif p.shouldFail {\n\t\treturn nil, errors.New(\"oops 1\")\n\t}\n\treturn p.successfulProvider.GetVersionInfo()\n}\n\nfunc (p *erroringSubcontainersInfoProvider) GetMachineInfo() (*info.MachineInfo, error) {\n\tif p.shouldFail {\n\t\treturn nil, errors.New(\"oops 2\")\n\t}\n\treturn p.successfulProvider.GetMachineInfo()\n}\n\nfunc (p *erroringSubcontainersInfoProvider) GetRequestedContainersInfo(\n\ta string, opt v2.RequestOptions) (map[string]*info.ContainerInfo, error) {\n\tif p.shouldFail {\n\t\treturn map[string]*info.ContainerInfo{}, errors.New(\"oops 3\")\n\t}\n\treturn p.successfulProvider.GetRequestedContainersInfo(a, opt)\n}\n"
  },
  {
    "path": "metrics/prometheus_machine.go",
    "content": "// Copyright 2020 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage metrics\n\nimport (\n\t\"strconv\"\n\n\t\"github.com/prometheus/client_golang/prometheus\"\n\n\t\"github.com/google/cadvisor/container\"\n\tinfo \"github.com/google/cadvisor/info/v1\"\n\n\t\"k8s.io/klog/v2\"\n)\n\nvar baseLabelsNames = []string{\"machine_id\", \"system_uuid\", \"boot_id\"}\n\nconst (\n\tprometheusModeLabelName       = \"mode\"\n\tprometheusTypeLabelName       = \"type\"\n\tprometheusLevelLabelName      = \"level\"\n\tprometheusNodeLabelName       = \"node_id\"\n\tprometheusCoreLabelName       = \"core_id\"\n\tprometheusThreadLabelName     = \"thread_id\"\n\tprometheusPageSizeLabelName   = \"page_size\"\n\tprometheusTargetNodeLabelName = \"target_node_id\"\n\n\tnvmMemoryMode    = \"memory_mode\"\n\tnvmAppDirectMode = \"app_direct_mode\"\n\n\tmemoryByTypeDimmCountKey    = \"DimmCount\"\n\tmemoryByTypeDimmCapacityKey = \"Capacity\"\n\n\temptyLabelValue = \"\"\n)\n\n// machineMetric describes a multi-dimensional metric used for exposing a\n// certain type of machine statistic.\ntype machineMetric struct {\n\tname        string\n\thelp        string\n\tvalueType   prometheus.ValueType\n\textraLabels []string\n\tcondition   func(machineInfo *info.MachineInfo) bool\n\tgetValues   func(machineInfo *info.MachineInfo) metricValues\n}\n\nfunc (metric *machineMetric) desc(baseLabels []string) *prometheus.Desc {\n\treturn prometheus.NewDesc(metric.name, metric.help, append(baseLabels, metric.extraLabels...), nil)\n}\n\n// PrometheusMachineCollector implements prometheus.Collector.\ntype PrometheusMachineCollector struct {\n\tinfoProvider   infoProvider\n\terrors         prometheus.Gauge\n\tmachineMetrics []machineMetric\n}\n\n// NewPrometheusMachineCollector returns a new PrometheusCollector.\nfunc NewPrometheusMachineCollector(i infoProvider, includedMetrics container.MetricSet) *PrometheusMachineCollector {\n\tc := &PrometheusMachineCollector{\n\n\t\tinfoProvider: i,\n\t\terrors: prometheus.NewGauge(prometheus.GaugeOpts{\n\t\t\tNamespace: \"machine\",\n\t\t\tName:      \"scrape_error\",\n\t\t\tHelp:      \"1 if there was an error while getting machine metrics, 0 otherwise.\",\n\t\t}),\n\t\tmachineMetrics: []machineMetric{\n\t\t\t{\n\t\t\t\tname:      \"machine_cpu_physical_cores\",\n\t\t\t\thelp:      \"Number of physical CPU cores.\",\n\t\t\t\tvalueType: prometheus.GaugeValue,\n\t\t\t\tgetValues: func(machineInfo *info.MachineInfo) metricValues {\n\t\t\t\t\treturn metricValues{{value: float64(machineInfo.NumPhysicalCores), timestamp: machineInfo.Timestamp}}\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:      \"machine_cpu_cores\",\n\t\t\t\thelp:      \"Number of logical CPU cores.\",\n\t\t\t\tvalueType: prometheus.GaugeValue,\n\t\t\t\tgetValues: func(machineInfo *info.MachineInfo) metricValues {\n\t\t\t\t\treturn metricValues{{value: float64(machineInfo.NumCores), timestamp: machineInfo.Timestamp}}\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:      \"machine_cpu_sockets\",\n\t\t\t\thelp:      \"Number of CPU sockets.\",\n\t\t\t\tvalueType: prometheus.GaugeValue,\n\t\t\t\tgetValues: func(machineInfo *info.MachineInfo) metricValues {\n\t\t\t\t\treturn metricValues{{value: float64(machineInfo.NumSockets), timestamp: machineInfo.Timestamp}}\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:      \"machine_cpu_books\",\n\t\t\t\thelp:      \"Number of CPU books.\",\n\t\t\t\tvalueType: prometheus.GaugeValue,\n\t\t\t\tgetValues: func(machineInfo *info.MachineInfo) metricValues {\n\t\t\t\t\treturn metricValues{{value: float64(machineInfo.NumBooks), timestamp: machineInfo.Timestamp}}\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:      \"machine_cpu_drawers\",\n\t\t\t\thelp:      \"Number of CPU drawers.\",\n\t\t\t\tvalueType: prometheus.GaugeValue,\n\t\t\t\tgetValues: func(machineInfo *info.MachineInfo) metricValues {\n\t\t\t\t\treturn metricValues{{value: float64(machineInfo.NumDrawers), timestamp: machineInfo.Timestamp}}\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:      \"machine_memory_bytes\",\n\t\t\t\thelp:      \"Amount of memory installed on the machine.\",\n\t\t\t\tvalueType: prometheus.GaugeValue,\n\t\t\t\tgetValues: func(machineInfo *info.MachineInfo) metricValues {\n\t\t\t\t\treturn metricValues{{value: float64(machineInfo.MemoryCapacity), timestamp: machineInfo.Timestamp}}\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:      \"machine_swap_bytes\",\n\t\t\t\thelp:      \"Amount of swap memory available on the machine.\",\n\t\t\t\tvalueType: prometheus.GaugeValue,\n\t\t\t\tgetValues: func(machineInfo *info.MachineInfo) metricValues {\n\t\t\t\t\treturn metricValues{{value: float64(machineInfo.SwapCapacity), timestamp: machineInfo.Timestamp}}\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:        \"machine_dimm_count\",\n\t\t\t\thelp:        \"Number of RAM DIMM (all types memory modules) value labeled by dimm type.\",\n\t\t\t\tvalueType:   prometheus.GaugeValue,\n\t\t\t\textraLabels: []string{prometheusTypeLabelName},\n\t\t\t\tcondition:   func(machineInfo *info.MachineInfo) bool { return len(machineInfo.MemoryByType) != 0 },\n\t\t\t\tgetValues: func(machineInfo *info.MachineInfo) metricValues {\n\t\t\t\t\treturn getMemoryByType(machineInfo, memoryByTypeDimmCountKey)\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:        \"machine_dimm_capacity_bytes\",\n\t\t\t\thelp:        \"Total RAM DIMM capacity (all types memory modules) value labeled by dimm type.\",\n\t\t\t\tvalueType:   prometheus.GaugeValue,\n\t\t\t\textraLabels: []string{prometheusTypeLabelName},\n\t\t\t\tcondition:   func(machineInfo *info.MachineInfo) bool { return len(machineInfo.MemoryByType) != 0 },\n\t\t\t\tgetValues: func(machineInfo *info.MachineInfo) metricValues {\n\t\t\t\t\treturn getMemoryByType(machineInfo, memoryByTypeDimmCapacityKey)\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:        \"machine_nvm_capacity\",\n\t\t\t\thelp:        \"NVM capacity value labeled by NVM mode (memory mode or app direct mode).\",\n\t\t\t\tvalueType:   prometheus.GaugeValue,\n\t\t\t\textraLabels: []string{prometheusModeLabelName},\n\t\t\t\tgetValues: func(machineInfo *info.MachineInfo) metricValues {\n\t\t\t\t\treturn metricValues{\n\t\t\t\t\t\t{value: float64(machineInfo.NVMInfo.MemoryModeCapacity), labels: []string{nvmMemoryMode}, timestamp: machineInfo.Timestamp},\n\t\t\t\t\t\t{value: float64(machineInfo.NVMInfo.AppDirectModeCapacity), labels: []string{nvmAppDirectMode}, timestamp: machineInfo.Timestamp},\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:      \"machine_nvm_avg_power_budget_watts\",\n\t\t\t\thelp:      \"NVM power budget.\",\n\t\t\t\tvalueType: prometheus.GaugeValue,\n\t\t\t\tgetValues: func(machineInfo *info.MachineInfo) metricValues {\n\t\t\t\t\treturn metricValues{{value: float64(machineInfo.NVMInfo.AvgPowerBudget), timestamp: machineInfo.Timestamp}}\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\n\tif includedMetrics.Has(container.CPUTopologyMetrics) {\n\t\tc.machineMetrics = append(c.machineMetrics, []machineMetric{\n\t\t\t{\n\t\t\t\tname:        \"machine_cpu_cache_capacity_bytes\",\n\t\t\t\thelp:        \"Cache size in bytes assigned to NUMA node and CPU core.\",\n\t\t\t\tvalueType:   prometheus.GaugeValue,\n\t\t\t\textraLabels: []string{prometheusNodeLabelName, prometheusCoreLabelName, prometheusTypeLabelName, prometheusLevelLabelName},\n\t\t\t\tgetValues: func(machineInfo *info.MachineInfo) metricValues {\n\t\t\t\t\treturn getCaches(machineInfo)\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:        \"machine_thread_siblings_count\",\n\t\t\t\thelp:        \"Number of CPU thread siblings.\",\n\t\t\t\tvalueType:   prometheus.GaugeValue,\n\t\t\t\textraLabels: []string{prometheusNodeLabelName, prometheusCoreLabelName, prometheusThreadLabelName},\n\t\t\t\tgetValues: func(machineInfo *info.MachineInfo) metricValues {\n\t\t\t\t\treturn getThreadsSiblingsCount(machineInfo)\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:        \"machine_node_memory_capacity_bytes\",\n\t\t\t\thelp:        \"Amount of memory assigned to NUMA node.\",\n\t\t\t\tvalueType:   prometheus.GaugeValue,\n\t\t\t\textraLabels: []string{prometheusNodeLabelName},\n\t\t\t\tgetValues: func(machineInfo *info.MachineInfo) metricValues {\n\t\t\t\t\treturn getNodeMemory(machineInfo)\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:        \"machine_node_hugepages_count\",\n\t\t\t\thelp:        \"Numer of hugepages assigned to NUMA node.\",\n\t\t\t\tvalueType:   prometheus.GaugeValue,\n\t\t\t\textraLabels: []string{prometheusNodeLabelName, prometheusPageSizeLabelName},\n\t\t\t\tgetValues: func(machineInfo *info.MachineInfo) metricValues {\n\t\t\t\t\treturn getHugePagesCount(machineInfo)\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:        \"machine_node_distance\",\n\t\t\t\thelp:        \"Distance between NUMA node and target NUMA node.\",\n\t\t\t\tvalueType:   prometheus.GaugeValue,\n\t\t\t\textraLabels: []string{prometheusNodeLabelName, prometheusTargetNodeLabelName},\n\t\t\t\tgetValues: func(machineInfo *info.MachineInfo) metricValues {\n\t\t\t\t\treturn getDistance(machineInfo)\n\t\t\t\t},\n\t\t\t},\n\t\t}...)\n\t}\n\treturn c\n}\n\n// Describe describes all the machine metrics ever exported by cadvisor. It\n// implements prometheus.PrometheusCollector.\nfunc (collector *PrometheusMachineCollector) Describe(ch chan<- *prometheus.Desc) {\n\tcollector.errors.Describe(ch)\n\tfor _, metric := range collector.machineMetrics {\n\t\tch <- metric.desc([]string{})\n\t}\n}\n\n// Collect fetches information about machine and delivers them as\n// Prometheus metrics. It implements prometheus.PrometheusCollector.\nfunc (collector *PrometheusMachineCollector) Collect(ch chan<- prometheus.Metric) {\n\tcollector.errors.Set(0)\n\tcollector.collectMachineInfo(ch)\n\tcollector.errors.Collect(ch)\n}\n\nfunc (collector *PrometheusMachineCollector) collectMachineInfo(ch chan<- prometheus.Metric) {\n\tmachineInfo, err := collector.infoProvider.GetMachineInfo()\n\tif err != nil {\n\t\tcollector.errors.Set(1)\n\t\tklog.Warningf(\"Couldn't get machine info: %s\", err)\n\t\treturn\n\t}\n\n\tbaseLabelsValues := []string{machineInfo.MachineID, machineInfo.SystemUUID, machineInfo.BootID}\n\n\tfor _, metric := range collector.machineMetrics {\n\t\tif metric.condition != nil && !metric.condition(machineInfo) {\n\t\t\tcontinue\n\t\t}\n\n\t\tfor _, metricValue := range metric.getValues(machineInfo) {\n\t\t\tlabelValues := make([]string, len(baseLabelsValues))\n\t\t\tcopy(labelValues, baseLabelsValues)\n\t\t\tif len(metric.extraLabels) != 0 {\n\t\t\t\tlabelValues = append(labelValues, metricValue.labels...)\n\t\t\t}\n\n\t\t\tprometheusMetric := prometheus.MustNewConstMetric(metric.desc(baseLabelsNames),\n\t\t\t\tmetric.valueType, metricValue.value, labelValues...)\n\n\t\t\tif metricValue.timestamp.IsZero() {\n\t\t\t\tch <- prometheusMetric\n\t\t\t} else {\n\t\t\t\tch <- prometheus.NewMetricWithTimestamp(metricValue.timestamp, prometheusMetric)\n\t\t\t}\n\t\t}\n\n\t}\n}\n\nfunc getMemoryByType(machineInfo *info.MachineInfo, property string) metricValues {\n\tmValues := make(metricValues, 0, len(machineInfo.MemoryByType))\n\tfor memoryType, memoryInfo := range machineInfo.MemoryByType {\n\t\tpropertyValue := 0.0\n\t\tswitch property {\n\t\tcase memoryByTypeDimmCapacityKey:\n\t\t\tpropertyValue = float64(memoryInfo.Capacity)\n\t\tcase memoryByTypeDimmCountKey:\n\t\t\tpropertyValue = float64(memoryInfo.DimmCount)\n\t\tdefault:\n\t\t\tklog.Warningf(\"Incorrect propery name for MemoryByType, property %s\", property)\n\t\t\treturn metricValues{}\n\t\t}\n\t\tmValues = append(mValues, metricValue{value: propertyValue, labels: []string{memoryType}, timestamp: machineInfo.Timestamp})\n\t}\n\treturn mValues\n}\n\nfunc getThreadsSiblingsCount(machineInfo *info.MachineInfo) metricValues {\n\tmValues := make(metricValues, 0, machineInfo.NumCores)\n\tfor _, node := range machineInfo.Topology {\n\t\tnodeID := strconv.Itoa(node.Id)\n\n\t\tfor _, core := range node.Cores {\n\t\t\tcoreID := strconv.Itoa(core.Id)\n\t\t\tsiblingsCount := len(core.Threads)\n\n\t\t\tfor _, thread := range core.Threads {\n\t\t\t\tmValues = append(mValues,\n\t\t\t\t\tmetricValue{\n\t\t\t\t\t\tvalue:     float64(siblingsCount),\n\t\t\t\t\t\tlabels:    []string{nodeID, coreID, strconv.Itoa(thread)},\n\t\t\t\t\t\ttimestamp: machineInfo.Timestamp,\n\t\t\t\t\t})\n\t\t\t}\n\t\t}\n\t}\n\treturn mValues\n}\n\nfunc getNodeMemory(machineInfo *info.MachineInfo) metricValues {\n\tmValues := make(metricValues, 0, len(machineInfo.Topology))\n\tfor _, node := range machineInfo.Topology {\n\t\tnodeID := strconv.Itoa(node.Id)\n\t\tmValues = append(mValues,\n\t\t\tmetricValue{\n\t\t\t\tvalue:     float64(node.Memory),\n\t\t\t\tlabels:    []string{nodeID},\n\t\t\t\ttimestamp: machineInfo.Timestamp,\n\t\t\t})\n\t}\n\treturn mValues\n}\n\nfunc getHugePagesCount(machineInfo *info.MachineInfo) metricValues {\n\tmValues := make(metricValues, 0)\n\tfor _, node := range machineInfo.Topology {\n\t\tnodeID := strconv.Itoa(node.Id)\n\n\t\tfor _, hugePage := range node.HugePages {\n\t\t\tmValues = append(mValues,\n\t\t\t\tmetricValue{\n\t\t\t\t\tvalue:     float64(hugePage.NumPages),\n\t\t\t\t\tlabels:    []string{nodeID, strconv.FormatUint(hugePage.PageSize, 10)},\n\t\t\t\t\ttimestamp: machineInfo.Timestamp,\n\t\t\t\t})\n\t\t}\n\t}\n\treturn mValues\n}\n\nfunc getCaches(machineInfo *info.MachineInfo) metricValues {\n\tmValues := make(metricValues, 0)\n\tfor _, node := range machineInfo.Topology {\n\t\tnodeID := strconv.Itoa(node.Id)\n\n\t\tfor _, core := range node.Cores {\n\t\t\tcoreID := strconv.Itoa(core.Id)\n\n\t\t\tfor _, cache := range core.Caches {\n\t\t\t\tmValues = append(mValues,\n\t\t\t\t\tmetricValue{\n\t\t\t\t\t\tvalue:     float64(cache.Size),\n\t\t\t\t\t\tlabels:    []string{nodeID, coreID, cache.Type, strconv.Itoa(cache.Level)},\n\t\t\t\t\t\ttimestamp: machineInfo.Timestamp,\n\t\t\t\t\t})\n\t\t\t}\n\t\t\tfor _, cache := range core.UncoreCaches {\n\t\t\t\tmValues = append(mValues,\n\t\t\t\t\tmetricValue{\n\t\t\t\t\t\tvalue:     float64(cache.Size),\n\t\t\t\t\t\tlabels:    []string{nodeID, coreID, cache.Type, strconv.Itoa(cache.Level)},\n\t\t\t\t\t\ttimestamp: machineInfo.Timestamp,\n\t\t\t\t\t})\n\t\t\t}\n\t\t}\n\n\t\tfor _, cache := range node.Caches {\n\t\t\tmValues = append(mValues,\n\t\t\t\tmetricValue{\n\t\t\t\t\tvalue:     float64(cache.Size),\n\t\t\t\t\tlabels:    []string{nodeID, emptyLabelValue, cache.Type, strconv.Itoa(cache.Level)},\n\t\t\t\t\ttimestamp: machineInfo.Timestamp,\n\t\t\t\t})\n\t\t}\n\t}\n\treturn mValues\n}\n\nfunc getDistance(machineInfo *info.MachineInfo) metricValues {\n\tmValues := make(metricValues, 0, len(machineInfo.Topology)^2)\n\tfor _, node := range machineInfo.Topology {\n\t\tnodeID := strconv.Itoa(node.Id)\n\t\tfor i, target := range node.Distances {\n\t\t\tmValues = append(mValues,\n\t\t\t\tmetricValue{\n\t\t\t\t\tvalue:     float64(target),\n\t\t\t\t\tlabels:    []string{nodeID, strconv.Itoa(i)},\n\t\t\t\t\ttimestamp: machineInfo.Timestamp,\n\t\t\t\t})\n\t\t}\n\t}\n\treturn mValues\n}\n"
  },
  {
    "path": "metrics/prometheus_machine_test.go",
    "content": "// Copyright 2020 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage metrics\n\nimport (\n\t\"bytes\"\n\t\"os\"\n\t\"reflect\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/prometheus/client_golang/prometheus\"\n\t\"github.com/prometheus/common/expfmt\"\n\t\"github.com/stretchr/testify/assert\"\n\n\t\"github.com/google/cadvisor/container\"\n)\n\nconst machineMetricsFile = \"testdata/prometheus_machine_metrics\"\nconst machineMetricsFailureFile = \"testdata/prometheus_machine_metrics_failure\"\n\nfunc TestPrometheusMachineCollector(t *testing.T) {\n\tcollector := NewPrometheusMachineCollector(testSubcontainersInfoProvider{}, container.AllMetrics)\n\tregistry := prometheus.NewRegistry()\n\tregistry.MustRegister(collector)\n\n\tmetricsFamily, err := registry.Gather()\n\tassert.Nil(t, err)\n\n\tvar metricBuffer bytes.Buffer\n\tfor _, metricFamily := range metricsFamily {\n\t\t_, err := expfmt.MetricFamilyToText(&metricBuffer, metricFamily)\n\t\tassert.Nil(t, err)\n\t}\n\tcollectedMetrics := metricBuffer.String()\n\n\texpectedMetrics, err := os.ReadFile(machineMetricsFile)\n\tassert.Nil(t, err)\n\tassert.Equal(t, string(expectedMetrics), collectedMetrics)\n}\n\nfunc TestPrometheusMachineCollectorWithFailure(t *testing.T) {\n\tprovider := &erroringSubcontainersInfoProvider{\n\t\tsuccessfulProvider: testSubcontainersInfoProvider{},\n\t\tshouldFail:         true,\n\t}\n\tcollector := NewPrometheusMachineCollector(provider, container.AllMetrics)\n\tregistry := prometheus.NewRegistry()\n\tregistry.MustRegister(collector)\n\n\tmetricsFamily, err := registry.Gather()\n\tassert.Nil(t, err)\n\n\tvar metricBuffer bytes.Buffer\n\tfor _, metricFamily := range metricsFamily {\n\t\t_, err := expfmt.MetricFamilyToText(&metricBuffer, metricFamily)\n\t\tassert.Nil(t, err)\n\t}\n\tcollectedMetrics := metricBuffer.String()\n\texpectedMetrics, err := os.ReadFile(machineMetricsFailureFile)\n\tassert.Nil(t, err)\n\tassert.Equal(t, string(expectedMetrics), collectedMetrics)\n}\n\nfunc TestGetMemoryByType(t *testing.T) {\n\tmachineInfo, err := testSubcontainersInfoProvider{}.GetMachineInfo()\n\tassert.Nil(t, err)\n\n\tcapacityMetrics := getMemoryByType(machineInfo, memoryByTypeDimmCapacityKey)\n\tassert.Equal(t, 2, len(capacityMetrics))\n\n\tcountMetrics := getMemoryByType(machineInfo, memoryByTypeDimmCountKey)\n\tassert.Equal(t, 2, len(countMetrics))\n}\n\nfunc TestGetMemoryByTypeWithWrongProperty(t *testing.T) {\n\tmachineInfo, err := testSubcontainersInfoProvider{}.GetMachineInfo()\n\tassert.Nil(t, err)\n\n\tmetricVals := getMemoryByType(machineInfo, \"wrong_property_name\")\n\tassert.Equal(t, 0, len(metricVals))\n}\n\nfunc TestGetCaches(t *testing.T) {\n\tmachineInfo, err := testSubcontainersInfoProvider{}.GetMachineInfo()\n\tassert.Nil(t, err)\n\n\tmetricVals := getCaches(machineInfo)\n\n\tassert.Equal(t, 25, len(metricVals))\n\texpectedMetricVals := []metricValue{\n\t\t{value: 32768, labels: []string{\"0\", \"0\", \"Data\", \"1\"}, timestamp: time.Unix(1395066363, 0)},\n\t\t{value: 32768, labels: []string{\"0\", \"0\", \"Instruction\", \"1\"}, timestamp: time.Unix(1395066363, 0)},\n\t\t{value: 262144, labels: []string{\"0\", \"0\", \"Unified\", \"2\"}, timestamp: time.Unix(1395066363, 0)},\n\t\t{value: 32764, labels: []string{\"0\", \"1\", \"Data\", \"1\"}, timestamp: time.Unix(1395066363, 0)},\n\t\t{value: 32764, labels: []string{\"0\", \"1\", \"Instruction\", \"1\"}, timestamp: time.Unix(1395066363, 0)},\n\t\t{value: 262148, labels: []string{\"0\", \"1\", \"Unified\", \"2\"}, timestamp: time.Unix(1395066363, 0)},\n\t\t{value: 32768, labels: []string{\"0\", \"2\", \"Data\", \"1\"}, timestamp: time.Unix(1395066363, 0)},\n\t\t{value: 32768, labels: []string{\"0\", \"2\", \"Instruction\", \"1\"}, timestamp: time.Unix(1395066363, 0)},\n\t\t{value: 262144, labels: []string{\"0\", \"2\", \"Unified\", \"2\"}, timestamp: time.Unix(1395066363, 0)},\n\t\t{value: 32764, labels: []string{\"0\", \"3\", \"Data\", \"1\"}, timestamp: time.Unix(1395066363, 0)},\n\t\t{value: 32764, labels: []string{\"0\", \"3\", \"Instruction\", \"1\"}, timestamp: time.Unix(1395066363, 0)},\n\t\t{value: 262148, labels: []string{\"0\", \"3\", \"Unified\", \"2\"}, timestamp: time.Unix(1395066363, 0)},\n\t\t{value: 32768, labels: []string{\"1\", \"4\", \"Data\", \"1\"}, timestamp: time.Unix(1395066363, 0)},\n\t\t{value: 32768, labels: []string{\"1\", \"4\", \"Instruction\", \"1\"}, timestamp: time.Unix(1395066363, 0)},\n\t\t{value: 262144, labels: []string{\"1\", \"4\", \"Unified\", \"2\"}, timestamp: time.Unix(1395066363, 0)},\n\t\t{value: 32764, labels: []string{\"1\", \"5\", \"Data\", \"1\"}, timestamp: time.Unix(1395066363, 0)},\n\t\t{value: 32764, labels: []string{\"1\", \"5\", \"Instruction\", \"1\"}, timestamp: time.Unix(1395066363, 0)},\n\t\t{value: 262148, labels: []string{\"1\", \"5\", \"Unified\", \"2\"}, timestamp: time.Unix(1395066363, 0)},\n\t\t{value: 32768, labels: []string{\"1\", \"6\", \"Data\", \"1\"}, timestamp: time.Unix(1395066363, 0)},\n\t\t{value: 32768, labels: []string{\"1\", \"6\", \"Instruction\", \"1\"}, timestamp: time.Unix(1395066363, 0)},\n\t\t{value: 262144, labels: []string{\"1\", \"6\", \"Unified\", \"2\"}, timestamp: time.Unix(1395066363, 0)},\n\t\t{value: 32764, labels: []string{\"1\", \"7\", \"Data\", \"1\"}, timestamp: time.Unix(1395066363, 0)},\n\t\t{value: 32764, labels: []string{\"1\", \"7\", \"Instruction\", \"1\"}, timestamp: time.Unix(1395066363, 0)},\n\t\t{value: 262148, labels: []string{\"1\", \"7\", \"Unified\", \"2\"}, timestamp: time.Unix(1395066363, 0)},\n\t\t{value: 8388608, labels: []string{\"1\", \"\", \"Unified\", \"3\"}, timestamp: time.Unix(1395066363, 0)},\n\t}\n\tassertMetricValues(t, expectedMetricVals, metricVals, \"Unexpected information about Node memory\")\n}\n\nfunc TestGetThreadsSiblingsCount(t *testing.T) {\n\tmachineInfo, err := testSubcontainersInfoProvider{}.GetMachineInfo()\n\tassert.Nil(t, err)\n\n\tmetricVals := getThreadsSiblingsCount(machineInfo)\n\n\tassert.Equal(t, 16, len(metricVals))\n\texpectedMetricVals := []metricValue{\n\t\t{value: 2, labels: []string{\"0\", \"0\", \"0\"}, timestamp: time.Unix(1395066363, 0)},\n\t\t{value: 2, labels: []string{\"0\", \"0\", \"1\"}, timestamp: time.Unix(1395066363, 0)},\n\t\t{value: 2, labels: []string{\"0\", \"1\", \"2\"}, timestamp: time.Unix(1395066363, 0)},\n\t\t{value: 2, labels: []string{\"0\", \"1\", \"3\"}, timestamp: time.Unix(1395066363, 0)},\n\t\t{value: 2, labels: []string{\"0\", \"2\", \"4\"}, timestamp: time.Unix(1395066363, 0)},\n\t\t{value: 2, labels: []string{\"0\", \"2\", \"5\"}, timestamp: time.Unix(1395066363, 0)},\n\t\t{value: 2, labels: []string{\"0\", \"3\", \"6\"}, timestamp: time.Unix(1395066363, 0)},\n\t\t{value: 2, labels: []string{\"0\", \"3\", \"7\"}, timestamp: time.Unix(1395066363, 0)},\n\t\t{value: 2, labels: []string{\"1\", \"4\", \"8\"}, timestamp: time.Unix(1395066363, 0)},\n\t\t{value: 2, labels: []string{\"1\", \"4\", \"9\"}, timestamp: time.Unix(1395066363, 0)},\n\t\t{value: 2, labels: []string{\"1\", \"5\", \"10\"}, timestamp: time.Unix(1395066363, 0)},\n\t\t{value: 2, labels: []string{\"1\", \"5\", \"11\"}, timestamp: time.Unix(1395066363, 0)},\n\t\t{value: 2, labels: []string{\"1\", \"6\", \"12\"}, timestamp: time.Unix(1395066363, 0)},\n\t\t{value: 2, labels: []string{\"1\", \"6\", \"13\"}, timestamp: time.Unix(1395066363, 0)},\n\t\t{value: 2, labels: []string{\"1\", \"7\", \"14\"}, timestamp: time.Unix(1395066363, 0)},\n\t\t{value: 2, labels: []string{\"1\", \"7\", \"15\"}, timestamp: time.Unix(1395066363, 0)},\n\t}\n\tassertMetricValues(t, expectedMetricVals, metricVals, \"Unexpected information about CPU threads\")\n}\n\nfunc TestGetNodeMemory(t *testing.T) {\n\tmachineInfo, err := testSubcontainersInfoProvider{}.GetMachineInfo()\n\tassert.Nil(t, err)\n\n\tmetricVals := getNodeMemory(machineInfo)\n\n\tassert.Equal(t, 2, len(metricVals))\n\texpectedMetricVals := []metricValue{\n\t\t{value: 33604804608, labels: []string{\"0\"}, timestamp: time.Unix(1395066363, 0)},\n\t\t{value: 33604804606, labels: []string{\"1\"}, timestamp: time.Unix(1395066363, 0)},\n\t}\n\tassertMetricValues(t, expectedMetricVals, metricVals, \"Unexpected information about Node memory\")\n}\n\nfunc TestGetHugePagesCount(t *testing.T) {\n\tmachineInfo, err := testSubcontainersInfoProvider{}.GetMachineInfo()\n\tassert.Nil(t, err)\n\n\tmetricVals := getHugePagesCount(machineInfo)\n\n\tassert.Equal(t, 4, len(metricVals))\n\texpectedMetricVals := []metricValue{\n\t\t{value: 0, labels: []string{\"0\", \"1048576\"}, timestamp: time.Unix(1395066363, 0)},\n\t\t{value: 0, labels: []string{\"0\", \"2048\"}, timestamp: time.Unix(1395066363, 0)},\n\t\t{value: 2, labels: []string{\"1\", \"1048576\"}, timestamp: time.Unix(1395066363, 0)},\n\t\t{value: 4, labels: []string{\"1\", \"2048\"}, timestamp: time.Unix(1395066363, 0)},\n\t}\n\tassertMetricValues(t, expectedMetricVals, metricVals, \"Unexpected information about Node memory\")\n}\n\nfunc TestGetDistance(t *testing.T) {\n\tmachineInfo, err := testSubcontainersInfoProvider{}.GetMachineInfo()\n\tassert.Nil(t, err)\n\n\tmetricVals := getDistance(machineInfo)\n\n\tassert.Equal(t, 4, len(metricVals))\n\texpectedMetricVals := []metricValue{\n\t\t{value: 10, labels: []string{\"0\", \"0\"}, timestamp: time.Unix(1395066363, 0)},\n\t\t{value: 12, labels: []string{\"0\", \"1\"}, timestamp: time.Unix(1395066363, 0)},\n\t\t{value: 12, labels: []string{\"1\", \"0\"}, timestamp: time.Unix(1395066363, 0)},\n\t\t{value: 10, labels: []string{\"1\", \"1\"}, timestamp: time.Unix(1395066363, 0)},\n\t}\n\tassertMetricValues(t, expectedMetricVals, metricVals, \"Unexpected information about Node memory\")\n}\n\nfunc assertMetricValues(t *testing.T, expected metricValues, actual metricValues, message string) {\n\tfor i := range actual {\n\t\tassert.Truef(t, reflect.DeepEqual(expected[i], actual[i]),\n\t\t\t\"%s expected %#v but found %#v\\n\", message, expected[i], actual[i])\n\t}\n}\n"
  },
  {
    "path": "metrics/prometheus_test.go",
    "content": "// Copyright 2014 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage metrics\n\nimport (\n\t\"errors\"\n\t\"os\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/google/cadvisor/container\"\n\tinfo \"github.com/google/cadvisor/info/v1\"\n\tv2 \"github.com/google/cadvisor/info/v2\"\n\n\t\"github.com/prometheus/client_golang/prometheus\"\n\t\"github.com/prometheus/client_golang/prometheus/testutil\"\n\t\"github.com/stretchr/testify/assert\"\n\tclock \"k8s.io/utils/clock/testing\"\n)\n\nvar now = clock.NewFakeClock(time.Unix(1395066363, 0))\n\nfunc TestPrometheusCollector(t *testing.T) {\n\tc := NewPrometheusCollector(testSubcontainersInfoProvider{}, func(container *info.ContainerInfo) map[string]string {\n\t\ts := DefaultContainerLabels(container)\n\t\ts[\"zone.name\"] = \"hello\"\n\t\treturn s\n\t}, container.AllMetrics, now, v2.RequestOptions{})\n\treg := prometheus.NewRegistry()\n\treg.MustRegister(c)\n\n\ttestPrometheusCollector(t, reg, \"testdata/prometheus_metrics\")\n}\n\nfunc TestPrometheusCollectorWithWhiteList(t *testing.T) {\n\tc := NewPrometheusCollector(testSubcontainersInfoProvider{}, func(container *info.ContainerInfo) map[string]string {\n\t\twhitelistedLabels := []string{\n\t\t\t\"no_one_match\",\n\t\t}\n\t\tcontainerLabelFunc := BaseContainerLabels(whitelistedLabels)\n\t\ts := containerLabelFunc(container)\n\t\ts[\"zone.name\"] = \"hello\"\n\t\treturn s\n\t}, container.AllMetrics, now, v2.RequestOptions{})\n\treg := prometheus.NewRegistry()\n\treg.MustRegister(c)\n\n\ttestPrometheusCollector(t, reg, \"testdata/prometheus_metrics_whitelist_filtered\")\n}\n\nfunc TestPrometheusCollectorWithPerfAggregated(t *testing.T) {\n\tmetrics := container.MetricSet{\n\t\tcontainer.PerfMetrics: struct{}{},\n\t}\n\tc := NewPrometheusCollector(testSubcontainersInfoProvider{}, func(container *info.ContainerInfo) map[string]string {\n\t\ts := DefaultContainerLabels(container)\n\t\ts[\"zone.name\"] = \"hello\"\n\t\treturn s\n\t}, metrics, now, v2.RequestOptions{})\n\treg := prometheus.NewRegistry()\n\treg.MustRegister(c)\n\n\ttestPrometheusCollector(t, reg, \"testdata/prometheus_metrics_perf_aggregated\")\n}\n\nfunc testPrometheusCollector(t *testing.T, gatherer prometheus.Gatherer, metricsFile string) {\n\twantMetrics, err := os.Open(metricsFile)\n\tif err != nil {\n\t\tt.Fatalf(\"unable to read input test file %s\", metricsFile)\n\t}\n\n\terr = testutil.GatherAndCompare(gatherer, wantMetrics)\n\tif err != nil {\n\t\tt.Fatalf(\"Metric comparison failed: %s\", err)\n\t}\n}\n\nfunc TestPrometheusCollector_scrapeFailure(t *testing.T) {\n\tprovider := &erroringSubcontainersInfoProvider{\n\t\tsuccessfulProvider: testSubcontainersInfoProvider{},\n\t\tshouldFail:         true,\n\t}\n\n\tc := NewPrometheusCollector(provider, func(container *info.ContainerInfo) map[string]string {\n\t\ts := DefaultContainerLabels(container)\n\t\ts[\"zone.name\"] = \"hello\"\n\t\treturn s\n\t}, container.AllMetrics, now, v2.RequestOptions{})\n\treg := prometheus.NewRegistry()\n\treg.MustRegister(c)\n\n\ttestPrometheusCollector(t, reg, \"testdata/prometheus_metrics_failure\")\n\n\tprovider.shouldFail = false\n\n\ttestPrometheusCollector(t, reg, \"testdata/prometheus_metrics\")\n}\n\nfunc TestNewPrometheusCollectorWithPerf(t *testing.T) {\n\tc := NewPrometheusCollector(&mockInfoProvider{}, mockLabelFunc, container.MetricSet{container.PerfMetrics: struct{}{}}, now, v2.RequestOptions{})\n\tassert.Len(t, c.containerMetrics, 6)\n\tnames := []string{}\n\tfor _, m := range c.containerMetrics {\n\t\tnames = append(names, m.name)\n\t}\n\tassert.Contains(t, names, \"container_last_seen\")\n\tassert.Contains(t, names, \"container_health_state\")\n\tassert.Contains(t, names, \"container_perf_events_total\")\n\tassert.Contains(t, names, \"container_perf_events_scaling_ratio\")\n\tassert.Contains(t, names, \"container_perf_uncore_events_total\")\n\tassert.Contains(t, names, \"container_perf_uncore_events_scaling_ratio\")\n}\n\nfunc TestNewPrometheusCollectorWithRequestOptions(t *testing.T) {\n\tp := mockInfoProvider{}\n\topts := v2.RequestOptions{\n\t\tIdType: \"docker\",\n\t}\n\tc := NewPrometheusCollector(&p, mockLabelFunc, container.AllMetrics, now, opts)\n\tch := make(chan prometheus.Metric, 10)\n\tc.Collect(ch)\n\tassert.Equal(t, p.options, opts)\n}\n\ntype mockInfoProvider struct {\n\toptions v2.RequestOptions\n}\n\nfunc (m *mockInfoProvider) GetRequestedContainersInfo(containerName string, options v2.RequestOptions) (map[string]*info.ContainerInfo, error) {\n\tm.options = options\n\treturn map[string]*info.ContainerInfo{}, nil\n}\n\nfunc (m *mockInfoProvider) GetVersionInfo() (*info.VersionInfo, error) {\n\treturn nil, errors.New(\"not supported\")\n}\n\nfunc (m *mockInfoProvider) GetMachineInfo() (*info.MachineInfo, error) {\n\treturn nil, errors.New(\"not supported\")\n}\n\nfunc mockLabelFunc(*info.ContainerInfo) map[string]string {\n\treturn map[string]string{}\n}\n\nfunc TestGetPerCpuCorePerfEvents(t *testing.T) {\n\tcontainerStats := &info.ContainerStats{\n\t\tTimestamp: time.Unix(1395066367, 0),\n\t\tPerfStats: []info.PerfStat{\n\t\t\t{\n\t\t\t\tPerfValue: info.PerfValue{\n\t\t\t\t\tScalingRatio: 1.0,\n\t\t\t\t\tValue:        123,\n\t\t\t\t\tName:         \"instructions\",\n\t\t\t\t},\n\t\t\t\tCpu: 0,\n\t\t\t},\n\t\t\t{\n\t\t\t\tPerfValue: info.PerfValue{\n\t\t\t\t\tScalingRatio: 0.5,\n\t\t\t\t\tValue:        456,\n\t\t\t\t\tName:         \"instructions\",\n\t\t\t\t},\n\t\t\t\tCpu: 1,\n\t\t\t},\n\t\t\t{\n\t\t\t\tPerfValue: info.PerfValue{\n\t\t\t\t\tScalingRatio: 0.7,\n\t\t\t\t\tValue:        321,\n\t\t\t\t\tName:         \"instructions_retired\"},\n\t\t\t\tCpu: 0,\n\t\t\t},\n\t\t\t{\n\t\t\t\tPerfValue: info.PerfValue{\n\t\t\t\t\tScalingRatio: 0.3,\n\t\t\t\t\tValue:        789,\n\t\t\t\t\tName:         \"instructions_retired\"},\n\t\t\t\tCpu: 1,\n\t\t\t},\n\t\t},\n\t}\n\tmetricVals := getPerCPUCorePerfEvents(containerStats)\n\tassert.Equal(t, 4, len(metricVals))\n\tvalues := []float64{}\n\tfor _, metric := range metricVals {\n\t\tvalues = append(values, metric.value)\n\t}\n\tassert.Contains(t, values, 123.0)\n\tassert.Contains(t, values, 456.0)\n\tassert.Contains(t, values, 321.0)\n\tassert.Contains(t, values, 789.0)\n}\n\nfunc TestGetPerCpuCoreScalingRatio(t *testing.T) {\n\tcontainerStats := &info.ContainerStats{\n\t\tTimestamp: time.Unix(1395066367, 0),\n\t\tPerfStats: []info.PerfStat{\n\t\t\t{\n\t\t\t\tPerfValue: info.PerfValue{\n\t\t\t\t\tScalingRatio: 1.0,\n\t\t\t\t\tValue:        123,\n\t\t\t\t\tName:         \"instructions\"},\n\t\t\t\tCpu: 0,\n\t\t\t},\n\t\t\t{\n\t\t\t\tPerfValue: info.PerfValue{\n\t\t\t\t\tScalingRatio: 0.5,\n\t\t\t\t\tValue:        456,\n\t\t\t\t\tName:         \"instructions\"},\n\t\t\t\tCpu: 1,\n\t\t\t},\n\t\t\t{\n\t\t\t\tPerfValue: info.PerfValue{\n\t\t\t\t\tScalingRatio: 0.7,\n\t\t\t\t\tValue:        321,\n\t\t\t\t\tName:         \"instructions_retired\"},\n\t\t\t\tCpu: 0,\n\t\t\t},\n\t\t\t{\n\t\t\t\tPerfValue: info.PerfValue{\n\t\t\t\t\tScalingRatio: 0.3,\n\t\t\t\t\tValue:        789,\n\t\t\t\t\tName:         \"instructions_retired\"},\n\t\t\t\tCpu: 1,\n\t\t\t},\n\t\t},\n\t}\n\tmetricVals := getPerCPUCoreScalingRatio(containerStats)\n\tassert.Equal(t, 4, len(metricVals))\n\tvalues := []float64{}\n\tfor _, metric := range metricVals {\n\t\tvalues = append(values, metric.value)\n\t}\n\tassert.Contains(t, values, 1.0)\n\tassert.Contains(t, values, 0.5)\n\tassert.Contains(t, values, 0.7)\n\tassert.Contains(t, values, 0.3)\n}\n\nfunc TestGetAggCorePerfEvents(t *testing.T) {\n\tcontainerStats := &info.ContainerStats{\n\t\tTimestamp: time.Unix(1395066367, 0),\n\t\tPerfStats: []info.PerfStat{\n\t\t\t{\n\t\t\t\tPerfValue: info.PerfValue{\n\t\t\t\t\tScalingRatio: 1.0,\n\t\t\t\t\tValue:        123,\n\t\t\t\t\tName:         \"instructions\"},\n\t\t\t\tCpu: 0,\n\t\t\t},\n\t\t\t{\n\t\t\t\tPerfValue: info.PerfValue{\n\t\t\t\t\tScalingRatio: 0.5,\n\t\t\t\t\tValue:        456,\n\t\t\t\t\tName:         \"instructions\"},\n\t\t\t\tCpu: 1,\n\t\t\t},\n\t\t\t{\n\t\t\t\tPerfValue: info.PerfValue{\n\t\t\t\t\tScalingRatio: 0.7,\n\t\t\t\t\tValue:        321,\n\t\t\t\t\tName:         \"instructions_retired\"},\n\t\t\t\tCpu: 0,\n\t\t\t},\n\t\t\t{\n\t\t\t\tPerfValue: info.PerfValue{\n\t\t\t\t\tScalingRatio: 0.3,\n\t\t\t\t\tValue:        789,\n\t\t\t\t\tName:         \"instructions_retired\"},\n\t\t\t\tCpu: 1,\n\t\t\t},\n\t\t},\n\t}\n\tmetricVals := getAggregatedCorePerfEvents(containerStats)\n\tassert.Equal(t, 2, len(metricVals))\n\tvalues := []float64{}\n\tfor _, metric := range metricVals {\n\t\tvalues = append(values, metric.value)\n\t}\n\tassert.Contains(t, values, 579.0)\n\tassert.Contains(t, values, 1110.0)\n}\n\nfunc TestGetMinCoreScalingRatio(t *testing.T) {\n\tcontainerStats := &info.ContainerStats{\n\t\tTimestamp: time.Unix(1395066367, 0),\n\t\tPerfStats: []info.PerfStat{\n\t\t\t{\n\t\t\t\tPerfValue: info.PerfValue{\n\t\t\t\t\tScalingRatio: 1.0,\n\t\t\t\t\tValue:        123,\n\t\t\t\t\tName:         \"instructions\"},\n\t\t\t\tCpu: 0,\n\t\t\t},\n\t\t\t{\n\t\t\t\tPerfValue: info.PerfValue{\n\t\t\t\t\tScalingRatio: 0.5,\n\t\t\t\t\tValue:        456,\n\t\t\t\t\tName:         \"instructions\"},\n\t\t\t\tCpu: 1,\n\t\t\t},\n\t\t\t{\n\t\t\t\tPerfValue: info.PerfValue{\n\t\t\t\t\tScalingRatio: 0.7,\n\t\t\t\t\tValue:        321,\n\t\t\t\t\tName:         \"instructions_retired\"},\n\t\t\t\tCpu: 0,\n\t\t\t},\n\t\t\t{\n\t\t\t\tPerfValue: info.PerfValue{\n\t\t\t\t\tScalingRatio: 0.3,\n\t\t\t\t\tValue:        789,\n\t\t\t\t\tName:         \"instructions_retired\"},\n\t\t\t\tCpu: 1,\n\t\t\t},\n\t\t},\n\t}\n\tmetricVals := getMinCoreScalingRatio(containerStats)\n\tassert.Equal(t, 2, len(metricVals))\n\tvalues := []float64{}\n\tfor _, metric := range metricVals {\n\t\tvalues = append(values, metric.value)\n\t}\n\tassert.Contains(t, values, 0.5)\n\tassert.Contains(t, values, 0.3)\n}\n\nfunc TestGetContainerHealthState(t *testing.T) {\n\ttestCases := []struct {\n\t\tname           string\n\t\tcontainerStats *info.ContainerStats\n\t\texpectedValue  float64\n\t}{\n\t\t{name: \"healthy\", expectedValue: 1.0, containerStats: &info.ContainerStats{Health: info.Health{Status: \"healthy\"}}},\n\t\t{name: \"unhealthy\", expectedValue: 0.0, containerStats: &info.ContainerStats{Health: info.Health{Status: \"unhealthy\"}}},\n\t\t{name: \"starting\", expectedValue: 0.0, containerStats: &info.ContainerStats{Health: info.Health{Status: \"unknown\"}}},\n\t\t{name: \"empty\", expectedValue: -1.0, containerStats: &info.ContainerStats{}},\n\t}\n\tfor _, tc := range testCases {\n\t\tt.Run(tc.name, func(t *testing.T) {\n\t\t\tmetricVals := getContainerHealthState(tc.containerStats)\n\t\t\tassert.Equal(t, 1, len(metricVals))\n\t\t\tassert.Equal(t, tc.expectedValue, metricVals[0].value)\n\t\t})\n\t}\n}\n\nfunc TestIOCostMetrics(t *testing.T) {\n\tcontainerStats := &info.ContainerStats{\n\t\tTimestamp: time.Unix(1395066363, 0),\n\t\tDiskIo: info.DiskIoStats{\n\t\t\tIoCostUsage: []info.PerDiskStats{{\n\t\t\t\tDevice: \"sda1\",\n\t\t\t\tMajor:  8,\n\t\t\t\tMinor:  1,\n\t\t\t\tStats:  map[string]uint64{\"Count\": 1500000},\n\t\t\t}},\n\t\t\tIoCostWait: []info.PerDiskStats{{\n\t\t\t\tDevice: \"sda1\",\n\t\t\t\tMajor:  8,\n\t\t\t\tMinor:  1,\n\t\t\t\tStats:  map[string]uint64{\"Count\": 2500000},\n\t\t\t}},\n\t\t\tIoCostIndebt: []info.PerDiskStats{{\n\t\t\t\tDevice: \"sda1\",\n\t\t\t\tMajor:  8,\n\t\t\t\tMinor:  1,\n\t\t\t\tStats:  map[string]uint64{\"Count\": 500000},\n\t\t\t}},\n\t\t\tIoCostIndelay: []info.PerDiskStats{{\n\t\t\t\tDevice: \"sda1\",\n\t\t\t\tMajor:  8,\n\t\t\t\tMinor:  1,\n\t\t\t\tStats:  map[string]uint64{\"Count\": 750000},\n\t\t\t}},\n\t\t},\n\t}\n\n\ttestCases := []struct {\n\t\tname          string\n\t\tstats         []info.PerDiskStats\n\t\texpectedValue float64\n\t}{\n\t\t{\n\t\t\tname:          \"IoCostUsage\",\n\t\t\tstats:         containerStats.DiskIo.IoCostUsage,\n\t\t\texpectedValue: 1.5,\n\t\t},\n\t\t{\n\t\t\tname:          \"IoCostWait\",\n\t\t\tstats:         containerStats.DiskIo.IoCostWait,\n\t\t\texpectedValue: 2.5,\n\t\t},\n\t\t{\n\t\t\tname:          \"IoCostIndebt\",\n\t\t\tstats:         containerStats.DiskIo.IoCostIndebt,\n\t\t\texpectedValue: 0.5,\n\t\t},\n\t\t{\n\t\t\tname:          \"IoCostIndelay\",\n\t\t\tstats:         containerStats.DiskIo.IoCostIndelay,\n\t\t\texpectedValue: 0.75,\n\t\t},\n\t}\n\n\tfor _, tc := range testCases {\n\t\tt.Run(tc.name, func(t *testing.T) {\n\t\t\tvalues := ioValues(\n\t\t\t\ttc.stats, \"Count\", asMicrosecondsToSeconds,\n\t\t\t\t[]info.FsStats{}, nil,\n\t\t\t\tcontainerStats.Timestamp,\n\t\t\t)\n\t\t\tassert.Equal(t, 1, len(values))\n\t\t\tassert.Equal(t, tc.expectedValue, values[0].value)\n\t\t\tassert.Equal(t, []string{\"sda1\"}, values[0].labels)\n\t\t})\n\t}\n}\n\nfunc TestCPUBurstMetrics(t *testing.T) {\n\tcontainerStats := &info.ContainerStats{\n\t\tTimestamp: time.Unix(1395066363, 0),\n\t\tCpu: info.CpuStats{\n\t\t\tCFS: info.CpuCFS{\n\t\t\t\tBurstsPeriods: 25,\n\t\t\t\tBurstTime:     500000000,\n\t\t\t},\n\t\t},\n\t}\n\n\ttestCases := []struct {\n\t\tname          string\n\t\tgetValue      func() float64\n\t\texpectedValue float64\n\t}{\n\t\t{\n\t\t\tname:          \"BurstsPeriods\",\n\t\t\tgetValue:      func() float64 { return float64(containerStats.Cpu.CFS.BurstsPeriods) },\n\t\t\texpectedValue: 25.0,\n\t\t},\n\t\t{\n\t\t\tname:          \"BurstTime\",\n\t\t\tgetValue:      func() float64 { return float64(containerStats.Cpu.CFS.BurstTime) / float64(time.Second) },\n\t\t\texpectedValue: 0.5,\n\t\t},\n\t}\n\n\tfor _, tc := range testCases {\n\t\tt.Run(tc.name, func(t *testing.T) {\n\t\t\tresult := tc.getValue()\n\t\t\tassert.Equal(t, tc.expectedValue, result)\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "metrics/testdata/prometheus_machine_metrics",
    "content": "# HELP machine_cpu_books Number of CPU books.\n# TYPE machine_cpu_books gauge\nmachine_cpu_books{boot_id=\"boot-id-test\",machine_id=\"machine-id-test\",system_uuid=\"system-uuid-test\"} 0 1395066363000\n# HELP machine_cpu_cache_capacity_bytes Cache size in bytes assigned to NUMA node and CPU core.\n# TYPE machine_cpu_cache_capacity_bytes gauge\nmachine_cpu_cache_capacity_bytes{boot_id=\"boot-id-test\",core_id=\"\",level=\"3\",machine_id=\"machine-id-test\",node_id=\"1\",system_uuid=\"system-uuid-test\",type=\"Unified\"} 8.388608e+06 1395066363000\nmachine_cpu_cache_capacity_bytes{boot_id=\"boot-id-test\",core_id=\"0\",level=\"1\",machine_id=\"machine-id-test\",node_id=\"0\",system_uuid=\"system-uuid-test\",type=\"Data\"} 32768 1395066363000\nmachine_cpu_cache_capacity_bytes{boot_id=\"boot-id-test\",core_id=\"0\",level=\"1\",machine_id=\"machine-id-test\",node_id=\"0\",system_uuid=\"system-uuid-test\",type=\"Instruction\"} 32768 1395066363000\nmachine_cpu_cache_capacity_bytes{boot_id=\"boot-id-test\",core_id=\"0\",level=\"2\",machine_id=\"machine-id-test\",node_id=\"0\",system_uuid=\"system-uuid-test\",type=\"Unified\"} 262144 1395066363000\nmachine_cpu_cache_capacity_bytes{boot_id=\"boot-id-test\",core_id=\"1\",level=\"1\",machine_id=\"machine-id-test\",node_id=\"0\",system_uuid=\"system-uuid-test\",type=\"Data\"} 32764 1395066363000\nmachine_cpu_cache_capacity_bytes{boot_id=\"boot-id-test\",core_id=\"1\",level=\"1\",machine_id=\"machine-id-test\",node_id=\"0\",system_uuid=\"system-uuid-test\",type=\"Instruction\"} 32764 1395066363000\nmachine_cpu_cache_capacity_bytes{boot_id=\"boot-id-test\",core_id=\"1\",level=\"2\",machine_id=\"machine-id-test\",node_id=\"0\",system_uuid=\"system-uuid-test\",type=\"Unified\"} 262148 1395066363000\nmachine_cpu_cache_capacity_bytes{boot_id=\"boot-id-test\",core_id=\"2\",level=\"1\",machine_id=\"machine-id-test\",node_id=\"0\",system_uuid=\"system-uuid-test\",type=\"Data\"} 32768 1395066363000\nmachine_cpu_cache_capacity_bytes{boot_id=\"boot-id-test\",core_id=\"2\",level=\"1\",machine_id=\"machine-id-test\",node_id=\"0\",system_uuid=\"system-uuid-test\",type=\"Instruction\"} 32768 1395066363000\nmachine_cpu_cache_capacity_bytes{boot_id=\"boot-id-test\",core_id=\"2\",level=\"2\",machine_id=\"machine-id-test\",node_id=\"0\",system_uuid=\"system-uuid-test\",type=\"Unified\"} 262144 1395066363000\nmachine_cpu_cache_capacity_bytes{boot_id=\"boot-id-test\",core_id=\"3\",level=\"1\",machine_id=\"machine-id-test\",node_id=\"0\",system_uuid=\"system-uuid-test\",type=\"Data\"} 32764 1395066363000\nmachine_cpu_cache_capacity_bytes{boot_id=\"boot-id-test\",core_id=\"3\",level=\"1\",machine_id=\"machine-id-test\",node_id=\"0\",system_uuid=\"system-uuid-test\",type=\"Instruction\"} 32764 1395066363000\nmachine_cpu_cache_capacity_bytes{boot_id=\"boot-id-test\",core_id=\"3\",level=\"2\",machine_id=\"machine-id-test\",node_id=\"0\",system_uuid=\"system-uuid-test\",type=\"Unified\"} 262148 1395066363000\nmachine_cpu_cache_capacity_bytes{boot_id=\"boot-id-test\",core_id=\"4\",level=\"1\",machine_id=\"machine-id-test\",node_id=\"1\",system_uuid=\"system-uuid-test\",type=\"Data\"} 32768 1395066363000\nmachine_cpu_cache_capacity_bytes{boot_id=\"boot-id-test\",core_id=\"4\",level=\"1\",machine_id=\"machine-id-test\",node_id=\"1\",system_uuid=\"system-uuid-test\",type=\"Instruction\"} 32768 1395066363000\nmachine_cpu_cache_capacity_bytes{boot_id=\"boot-id-test\",core_id=\"4\",level=\"2\",machine_id=\"machine-id-test\",node_id=\"1\",system_uuid=\"system-uuid-test\",type=\"Unified\"} 262144 1395066363000\nmachine_cpu_cache_capacity_bytes{boot_id=\"boot-id-test\",core_id=\"5\",level=\"1\",machine_id=\"machine-id-test\",node_id=\"1\",system_uuid=\"system-uuid-test\",type=\"Data\"} 32764 1395066363000\nmachine_cpu_cache_capacity_bytes{boot_id=\"boot-id-test\",core_id=\"5\",level=\"1\",machine_id=\"machine-id-test\",node_id=\"1\",system_uuid=\"system-uuid-test\",type=\"Instruction\"} 32764 1395066363000\nmachine_cpu_cache_capacity_bytes{boot_id=\"boot-id-test\",core_id=\"5\",level=\"2\",machine_id=\"machine-id-test\",node_id=\"1\",system_uuid=\"system-uuid-test\",type=\"Unified\"} 262148 1395066363000\nmachine_cpu_cache_capacity_bytes{boot_id=\"boot-id-test\",core_id=\"6\",level=\"1\",machine_id=\"machine-id-test\",node_id=\"1\",system_uuid=\"system-uuid-test\",type=\"Data\"} 32768 1395066363000\nmachine_cpu_cache_capacity_bytes{boot_id=\"boot-id-test\",core_id=\"6\",level=\"1\",machine_id=\"machine-id-test\",node_id=\"1\",system_uuid=\"system-uuid-test\",type=\"Instruction\"} 32768 1395066363000\nmachine_cpu_cache_capacity_bytes{boot_id=\"boot-id-test\",core_id=\"6\",level=\"2\",machine_id=\"machine-id-test\",node_id=\"1\",system_uuid=\"system-uuid-test\",type=\"Unified\"} 262144 1395066363000\nmachine_cpu_cache_capacity_bytes{boot_id=\"boot-id-test\",core_id=\"7\",level=\"1\",machine_id=\"machine-id-test\",node_id=\"1\",system_uuid=\"system-uuid-test\",type=\"Data\"} 32764 1395066363000\nmachine_cpu_cache_capacity_bytes{boot_id=\"boot-id-test\",core_id=\"7\",level=\"1\",machine_id=\"machine-id-test\",node_id=\"1\",system_uuid=\"system-uuid-test\",type=\"Instruction\"} 32764 1395066363000\nmachine_cpu_cache_capacity_bytes{boot_id=\"boot-id-test\",core_id=\"7\",level=\"2\",machine_id=\"machine-id-test\",node_id=\"1\",system_uuid=\"system-uuid-test\",type=\"Unified\"} 262148 1395066363000\n# HELP machine_cpu_cores Number of logical CPU cores.\n# TYPE machine_cpu_cores gauge\nmachine_cpu_cores{boot_id=\"boot-id-test\",machine_id=\"machine-id-test\",system_uuid=\"system-uuid-test\"} 4 1395066363000\n# HELP machine_cpu_drawers Number of CPU drawers.\n# TYPE machine_cpu_drawers gauge\nmachine_cpu_drawers{boot_id=\"boot-id-test\",machine_id=\"machine-id-test\",system_uuid=\"system-uuid-test\"} 0 1395066363000\n# HELP machine_cpu_physical_cores Number of physical CPU cores.\n# TYPE machine_cpu_physical_cores gauge\nmachine_cpu_physical_cores{boot_id=\"boot-id-test\",machine_id=\"machine-id-test\",system_uuid=\"system-uuid-test\"} 1 1395066363000\n# HELP machine_cpu_sockets Number of CPU sockets.\n# TYPE machine_cpu_sockets gauge\nmachine_cpu_sockets{boot_id=\"boot-id-test\",machine_id=\"machine-id-test\",system_uuid=\"system-uuid-test\"} 1 1395066363000\n# HELP machine_dimm_capacity_bytes Total RAM DIMM capacity (all types memory modules) value labeled by dimm type.\n# TYPE machine_dimm_capacity_bytes gauge\nmachine_dimm_capacity_bytes{boot_id=\"boot-id-test\",machine_id=\"machine-id-test\",system_uuid=\"system-uuid-test\",type=\"Non-volatile-RAM\"} 2.168421613568e+12 1395066363000\nmachine_dimm_capacity_bytes{boot_id=\"boot-id-test\",machine_id=\"machine-id-test\",system_uuid=\"system-uuid-test\",type=\"Unbuffered-DDR4\"} 4.12316860416e+11 1395066363000\n# HELP machine_dimm_count Number of RAM DIMM (all types memory modules) value labeled by dimm type.\n# TYPE machine_dimm_count gauge\nmachine_dimm_count{boot_id=\"boot-id-test\",machine_id=\"machine-id-test\",system_uuid=\"system-uuid-test\",type=\"Non-volatile-RAM\"} 8 1395066363000\nmachine_dimm_count{boot_id=\"boot-id-test\",machine_id=\"machine-id-test\",system_uuid=\"system-uuid-test\",type=\"Unbuffered-DDR4\"} 12 1395066363000\n# HELP machine_memory_bytes Amount of memory installed on the machine.\n# TYPE machine_memory_bytes gauge\nmachine_memory_bytes{boot_id=\"boot-id-test\",machine_id=\"machine-id-test\",system_uuid=\"system-uuid-test\"} 1024 1395066363000\n# HELP machine_node_distance Distance between NUMA node and target NUMA node.\n# TYPE machine_node_distance gauge\nmachine_node_distance{boot_id=\"boot-id-test\",machine_id=\"machine-id-test\",node_id=\"0\",system_uuid=\"system-uuid-test\",target_node_id=\"0\"} 10 1395066363000\nmachine_node_distance{boot_id=\"boot-id-test\",machine_id=\"machine-id-test\",node_id=\"0\",system_uuid=\"system-uuid-test\",target_node_id=\"1\"} 12 1395066363000\nmachine_node_distance{boot_id=\"boot-id-test\",machine_id=\"machine-id-test\",node_id=\"1\",system_uuid=\"system-uuid-test\",target_node_id=\"0\"} 12 1395066363000\nmachine_node_distance{boot_id=\"boot-id-test\",machine_id=\"machine-id-test\",node_id=\"1\",system_uuid=\"system-uuid-test\",target_node_id=\"1\"} 10 1395066363000\n# HELP machine_node_hugepages_count Numer of hugepages assigned to NUMA node.\n# TYPE machine_node_hugepages_count gauge\nmachine_node_hugepages_count{boot_id=\"boot-id-test\",machine_id=\"machine-id-test\",node_id=\"0\",page_size=\"1048576\",system_uuid=\"system-uuid-test\"} 0 1395066363000\nmachine_node_hugepages_count{boot_id=\"boot-id-test\",machine_id=\"machine-id-test\",node_id=\"0\",page_size=\"2048\",system_uuid=\"system-uuid-test\"} 0 1395066363000\nmachine_node_hugepages_count{boot_id=\"boot-id-test\",machine_id=\"machine-id-test\",node_id=\"1\",page_size=\"1048576\",system_uuid=\"system-uuid-test\"} 2 1395066363000\nmachine_node_hugepages_count{boot_id=\"boot-id-test\",machine_id=\"machine-id-test\",node_id=\"1\",page_size=\"2048\",system_uuid=\"system-uuid-test\"} 4 1395066363000\n# HELP machine_node_memory_capacity_bytes Amount of memory assigned to NUMA node.\n# TYPE machine_node_memory_capacity_bytes gauge\nmachine_node_memory_capacity_bytes{boot_id=\"boot-id-test\",machine_id=\"machine-id-test\",node_id=\"0\",system_uuid=\"system-uuid-test\"} 3.3604804608e+10 1395066363000\nmachine_node_memory_capacity_bytes{boot_id=\"boot-id-test\",machine_id=\"machine-id-test\",node_id=\"1\",system_uuid=\"system-uuid-test\"} 3.3604804606e+10 1395066363000\n# HELP machine_nvm_avg_power_budget_watts NVM power budget.\n# TYPE machine_nvm_avg_power_budget_watts gauge\nmachine_nvm_avg_power_budget_watts{boot_id=\"boot-id-test\",machine_id=\"machine-id-test\",system_uuid=\"system-uuid-test\"} 0 1395066363000\n# HELP machine_nvm_capacity NVM capacity value labeled by NVM mode (memory mode or app direct mode).\n# TYPE machine_nvm_capacity gauge\nmachine_nvm_capacity{boot_id=\"boot-id-test\",machine_id=\"machine-id-test\",mode=\"app_direct_mode\",system_uuid=\"system-uuid-test\"} 1.735166787584e+12 1395066363000\nmachine_nvm_capacity{boot_id=\"boot-id-test\",machine_id=\"machine-id-test\",mode=\"memory_mode\",system_uuid=\"system-uuid-test\"} 4.294967296e+11 1395066363000\n# HELP machine_scrape_error 1 if there was an error while getting machine metrics, 0 otherwise.\n# TYPE machine_scrape_error gauge\nmachine_scrape_error 0\n# HELP machine_swap_bytes Amount of swap memory available on the machine.\n# TYPE machine_swap_bytes gauge\nmachine_swap_bytes{boot_id=\"boot-id-test\",machine_id=\"machine-id-test\",system_uuid=\"system-uuid-test\"} 0 1395066363000\n# HELP machine_thread_siblings_count Number of CPU thread siblings.\n# TYPE machine_thread_siblings_count gauge\nmachine_thread_siblings_count{boot_id=\"boot-id-test\",core_id=\"0\",machine_id=\"machine-id-test\",node_id=\"0\",system_uuid=\"system-uuid-test\",thread_id=\"0\"} 2 1395066363000\nmachine_thread_siblings_count{boot_id=\"boot-id-test\",core_id=\"0\",machine_id=\"machine-id-test\",node_id=\"0\",system_uuid=\"system-uuid-test\",thread_id=\"1\"} 2 1395066363000\nmachine_thread_siblings_count{boot_id=\"boot-id-test\",core_id=\"1\",machine_id=\"machine-id-test\",node_id=\"0\",system_uuid=\"system-uuid-test\",thread_id=\"2\"} 2 1395066363000\nmachine_thread_siblings_count{boot_id=\"boot-id-test\",core_id=\"1\",machine_id=\"machine-id-test\",node_id=\"0\",system_uuid=\"system-uuid-test\",thread_id=\"3\"} 2 1395066363000\nmachine_thread_siblings_count{boot_id=\"boot-id-test\",core_id=\"2\",machine_id=\"machine-id-test\",node_id=\"0\",system_uuid=\"system-uuid-test\",thread_id=\"4\"} 2 1395066363000\nmachine_thread_siblings_count{boot_id=\"boot-id-test\",core_id=\"2\",machine_id=\"machine-id-test\",node_id=\"0\",system_uuid=\"system-uuid-test\",thread_id=\"5\"} 2 1395066363000\nmachine_thread_siblings_count{boot_id=\"boot-id-test\",core_id=\"3\",machine_id=\"machine-id-test\",node_id=\"0\",system_uuid=\"system-uuid-test\",thread_id=\"6\"} 2 1395066363000\nmachine_thread_siblings_count{boot_id=\"boot-id-test\",core_id=\"3\",machine_id=\"machine-id-test\",node_id=\"0\",system_uuid=\"system-uuid-test\",thread_id=\"7\"} 2 1395066363000\nmachine_thread_siblings_count{boot_id=\"boot-id-test\",core_id=\"4\",machine_id=\"machine-id-test\",node_id=\"1\",system_uuid=\"system-uuid-test\",thread_id=\"8\"} 2 1395066363000\nmachine_thread_siblings_count{boot_id=\"boot-id-test\",core_id=\"4\",machine_id=\"machine-id-test\",node_id=\"1\",system_uuid=\"system-uuid-test\",thread_id=\"9\"} 2 1395066363000\nmachine_thread_siblings_count{boot_id=\"boot-id-test\",core_id=\"5\",machine_id=\"machine-id-test\",node_id=\"1\",system_uuid=\"system-uuid-test\",thread_id=\"10\"} 2 1395066363000\nmachine_thread_siblings_count{boot_id=\"boot-id-test\",core_id=\"5\",machine_id=\"machine-id-test\",node_id=\"1\",system_uuid=\"system-uuid-test\",thread_id=\"11\"} 2 1395066363000\nmachine_thread_siblings_count{boot_id=\"boot-id-test\",core_id=\"6\",machine_id=\"machine-id-test\",node_id=\"1\",system_uuid=\"system-uuid-test\",thread_id=\"12\"} 2 1395066363000\nmachine_thread_siblings_count{boot_id=\"boot-id-test\",core_id=\"6\",machine_id=\"machine-id-test\",node_id=\"1\",system_uuid=\"system-uuid-test\",thread_id=\"13\"} 2 1395066363000\nmachine_thread_siblings_count{boot_id=\"boot-id-test\",core_id=\"7\",machine_id=\"machine-id-test\",node_id=\"1\",system_uuid=\"system-uuid-test\",thread_id=\"14\"} 2 1395066363000\nmachine_thread_siblings_count{boot_id=\"boot-id-test\",core_id=\"7\",machine_id=\"machine-id-test\",node_id=\"1\",system_uuid=\"system-uuid-test\",thread_id=\"15\"} 2 1395066363000\n"
  },
  {
    "path": "metrics/testdata/prometheus_machine_metrics_failure",
    "content": "# HELP machine_scrape_error 1 if there was an error while getting machine metrics, 0 otherwise.\n# TYPE machine_scrape_error gauge\nmachine_scrape_error 1\n"
  },
  {
    "path": "metrics/testdata/prometheus_metrics",
    "content": "# HELP cadvisor_version_info A metric with a constant '1' value labeled by kernel version, OS version, docker version, cadvisor version & cadvisor revision.\n# TYPE cadvisor_version_info gauge\ncadvisor_version_info{cadvisorRevision=\"abcdef\",cadvisorVersion=\"0.16.0\",dockerVersion=\"1.8.1\",kernelVersion=\"4.1.6-200.fc22.x86_64\",osVersion=\"Fedora 22 (Twenty Two)\"} 1\n# HELP container_blkio_device_usage_total Blkio Device bytes usage\n# TYPE container_blkio_device_usage_total counter\ncontainer_blkio_device_usage_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",device=\"/dev/sdb\",id=\"testcontainer\",image=\"test\",major=\"8\",minor=\"0\",name=\"testcontaineralias\",operation=\"Async\",zone_name=\"hello\"} 1 1395066363000\ncontainer_blkio_device_usage_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",device=\"/dev/sdb\",id=\"testcontainer\",image=\"test\",major=\"8\",minor=\"0\",name=\"testcontaineralias\",operation=\"Discard\",zone_name=\"hello\"} 2 1395066363000\ncontainer_blkio_device_usage_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",device=\"/dev/sdb\",id=\"testcontainer\",image=\"test\",major=\"8\",minor=\"0\",name=\"testcontaineralias\",operation=\"Read\",zone_name=\"hello\"} 3 1395066363000\ncontainer_blkio_device_usage_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",device=\"/dev/sdb\",id=\"testcontainer\",image=\"test\",major=\"8\",minor=\"0\",name=\"testcontaineralias\",operation=\"Sync\",zone_name=\"hello\"} 4 1395066363000\ncontainer_blkio_device_usage_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",device=\"/dev/sdb\",id=\"testcontainer\",image=\"test\",major=\"8\",minor=\"0\",name=\"testcontaineralias\",operation=\"Total\",zone_name=\"hello\"} 5 1395066363000\ncontainer_blkio_device_usage_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",device=\"/dev/sdb\",id=\"testcontainer\",image=\"test\",major=\"8\",minor=\"0\",name=\"testcontaineralias\",operation=\"Write\",zone_name=\"hello\"} 6 1395066363000\n# HELP container_cpu_cfs_periods_total Number of elapsed enforcement period intervals.\n# TYPE container_cpu_cfs_periods_total counter\ncontainer_cpu_cfs_periods_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 723 1395066363000\n# HELP container_cpu_cfs_throttled_periods_total Number of throttled period intervals.\n# TYPE container_cpu_cfs_throttled_periods_total counter\ncontainer_cpu_cfs_throttled_periods_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 18 1395066363000\n# HELP container_cpu_cfs_throttled_seconds_total Total time duration the container has been throttled.\n# TYPE container_cpu_cfs_throttled_seconds_total counter\ncontainer_cpu_cfs_throttled_seconds_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 1.724314 1395066363000\n# HELP container_cpu_cfs_burst_periods_total Number of periods when burst occurs.\n# TYPE container_cpu_cfs_burst_periods_total counter\ncontainer_cpu_cfs_burst_periods_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 25 1395066363000\n# HELP container_cpu_cfs_burst_seconds_total Total time duration the container has been bursted.\n# TYPE container_cpu_cfs_burst_seconds_total counter\ncontainer_cpu_cfs_burst_seconds_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 0.5 1395066363000\n# HELP container_cpu_load_average_10s Value of container cpu load average over the last 10 seconds.\n# TYPE container_cpu_load_average_10s gauge\ncontainer_cpu_load_average_10s{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 2 1395066363000\n# HELP container_cpu_load_d_average_10s Value of container cpu load.d average over the last 10 seconds.\n# TYPE container_cpu_load_d_average_10s gauge\ncontainer_cpu_load_d_average_10s{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 2 1395066363000\n# HELP container_cpu_schedstat_run_periods_total Number of times processes of the cgroup have run on the cpu\n# TYPE container_cpu_schedstat_run_periods_total counter\ncontainer_cpu_schedstat_run_periods_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 984285 1395066363000\n# HELP container_cpu_schedstat_run_seconds_total Time duration the processes of the container have run on the CPU.\n# TYPE container_cpu_schedstat_run_seconds_total counter\ncontainer_cpu_schedstat_run_seconds_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 0.053643567 1395066363000\n# HELP container_cpu_schedstat_runqueue_seconds_total Time duration processes of the container have been waiting on a runqueue.\n# TYPE container_cpu_schedstat_runqueue_seconds_total counter\ncontainer_cpu_schedstat_runqueue_seconds_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 479.424566378 1395066363000\n# HELP container_cpu_system_seconds_total Cumulative system cpu time consumed in seconds.\n# TYPE container_cpu_system_seconds_total counter\ncontainer_cpu_system_seconds_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 7e-09 1395066363000\n# HELP container_cpu_usage_seconds_total Cumulative cpu time consumed in seconds.\n# TYPE container_cpu_usage_seconds_total counter\ncontainer_cpu_usage_seconds_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",cpu=\"cpu00\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 2e-09 1395066363000\ncontainer_cpu_usage_seconds_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",cpu=\"cpu01\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 3e-09 1395066363000\ncontainer_cpu_usage_seconds_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",cpu=\"cpu02\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 4e-09 1395066363000\ncontainer_cpu_usage_seconds_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",cpu=\"cpu03\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 5e-09 1395066363000\n# HELP container_cpu_user_seconds_total Cumulative user cpu time consumed in seconds.\n# TYPE container_cpu_user_seconds_total counter\ncontainer_cpu_user_seconds_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 6e-09 1395066363000\n# HELP container_custom_app_metric_1 Custom application metric.\n# TYPE container_custom_app_metric_1 gauge\ncontainer_custom_app_metric_1{app_test_label=\"1_1\",app_test_label_2=\"2_1\",container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 1.1\ncontainer_custom_app_metric_1{app_test_label=\"1_2\",app_test_label_2=\"2_2\",container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 1.2\n# HELP container_custom_app_metric_2 Custom application metric.\n# TYPE container_custom_app_metric_2 gauge\ncontainer_custom_app_metric_2{app_test_label=\"test_value\",container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 2\n# HELP container_custom_app_metric_3 Custom application metric.\n# TYPE container_custom_app_metric_3 gauge\ncontainer_custom_app_metric_3{app_test_label=\"test_value\",container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 3\n# HELP container_file_descriptors Number of open file descriptors for the container.\n# TYPE container_file_descriptors gauge\ncontainer_file_descriptors{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 5 1395066363000\n# HELP container_fs_inodes_free Number of available Inodes\n# TYPE container_fs_inodes_free gauge\ncontainer_fs_inodes_free{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",device=\"sda1\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 524288 1395066363000\ncontainer_fs_inodes_free{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",device=\"sda2\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 262144 1395066363000\n# HELP container_fs_inodes_total Number of Inodes\n# TYPE container_fs_inodes_total gauge\ncontainer_fs_inodes_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",device=\"sda1\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 2.097152e+06 1395066363000\ncontainer_fs_inodes_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",device=\"sda2\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 2.097152e+06 1395066363000\n# HELP container_fs_io_current Number of I/Os currently in progress\n# TYPE container_fs_io_current gauge\ncontainer_fs_io_current{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",device=\"sda1\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 42 1395066363000\ncontainer_fs_io_current{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",device=\"sda2\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 47 1395066363000\n# HELP container_fs_io_time_seconds_total Cumulative count of seconds spent doing I/Os\n# TYPE container_fs_io_time_seconds_total counter\ncontainer_fs_io_time_seconds_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",device=\"sda1\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 4.3e-08 1395066363000\ncontainer_fs_io_time_seconds_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",device=\"sda2\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 4.8e-08 1395066363000\n# HELP container_fs_io_time_weighted_seconds_total Cumulative weighted I/O time in seconds\n# TYPE container_fs_io_time_weighted_seconds_total counter\ncontainer_fs_io_time_weighted_seconds_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",device=\"sda1\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 4.4e-08 1395066363000\ncontainer_fs_io_time_weighted_seconds_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",device=\"sda2\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 4.9e-08 1395066363000\n# HELP container_fs_io_cost_usage_seconds_total Cumulative IOCost usage in seconds\n# TYPE container_fs_io_cost_usage_seconds_total counter\ncontainer_fs_io_cost_usage_seconds_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",device=\"sda1\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 1.5 1395066363000\n# HELP container_fs_io_cost_wait_seconds_total Cumulative IOCost wait in seconds\n# TYPE container_fs_io_cost_wait_seconds_total counter\ncontainer_fs_io_cost_wait_seconds_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",device=\"sda1\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 2.5 1395066363000\n# HELP container_fs_io_cost_indebt_seconds_total Cumulative IOCost debt in seconds\n# TYPE container_fs_io_cost_indebt_seconds_total counter\ncontainer_fs_io_cost_indebt_seconds_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",device=\"sda1\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 0.5 1395066363000\n# HELP container_fs_io_cost_indelay_seconds_total Cumulative IOCost delay in seconds\n# TYPE container_fs_io_cost_indelay_seconds_total counter\ncontainer_fs_io_cost_indelay_seconds_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",device=\"sda1\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 0.75 1395066363000\n# HELP container_fs_limit_bytes Number of bytes that can be consumed by the container on this filesystem.\n# TYPE container_fs_limit_bytes gauge\ncontainer_fs_limit_bytes{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",device=\"sda1\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 22 1395066363000\ncontainer_fs_limit_bytes{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",device=\"sda2\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 37 1395066363000\n# HELP container_fs_read_seconds_total Cumulative count of seconds spent reading\n# TYPE container_fs_read_seconds_total counter\ncontainer_fs_read_seconds_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",device=\"sda1\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 2.7e-08 1395066363000\ncontainer_fs_read_seconds_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",device=\"sda2\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 4.2e-08 1395066363000\n# HELP container_fs_reads_bytes_total Cumulative count of bytes read\n# TYPE container_fs_reads_bytes_total counter\ncontainer_fs_reads_bytes_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",device=\"/dev/sdb\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 3 1395066363000\n# HELP container_fs_reads_merged_total Cumulative count of reads merged\n# TYPE container_fs_reads_merged_total counter\ncontainer_fs_reads_merged_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",device=\"sda1\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 25 1395066363000\ncontainer_fs_reads_merged_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",device=\"sda2\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 40 1395066363000\n# HELP container_fs_reads_total Cumulative count of reads completed\n# TYPE container_fs_reads_total counter\ncontainer_fs_reads_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",device=\"sda1\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 24 1395066363000\ncontainer_fs_reads_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",device=\"sda2\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 39 1395066363000\n# HELP container_fs_sector_reads_total Cumulative count of sector reads completed\n# TYPE container_fs_sector_reads_total counter\ncontainer_fs_sector_reads_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",device=\"sda1\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 26 1395066363000\ncontainer_fs_sector_reads_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",device=\"sda2\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 41 1395066363000\n# HELP container_fs_sector_writes_total Cumulative count of sector writes completed\n# TYPE container_fs_sector_writes_total counter\ncontainer_fs_sector_writes_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",device=\"sda1\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 40 1395066363000\ncontainer_fs_sector_writes_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",device=\"sda2\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 45 1395066363000\n# HELP container_fs_usage_bytes Number of bytes that are consumed by the container on this filesystem.\n# TYPE container_fs_usage_bytes gauge\ncontainer_fs_usage_bytes{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",device=\"sda1\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 23 1395066363000\ncontainer_fs_usage_bytes{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",device=\"sda2\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 38 1395066363000\n# HELP container_fs_write_seconds_total Cumulative count of seconds spent writing\n# TYPE container_fs_write_seconds_total counter\ncontainer_fs_write_seconds_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",device=\"sda1\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 4.1e-08 1395066363000\ncontainer_fs_write_seconds_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",device=\"sda2\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 4.6e-08 1395066363000\n# HELP container_fs_writes_bytes_total Cumulative count of bytes written\n# TYPE container_fs_writes_bytes_total counter\ncontainer_fs_writes_bytes_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",device=\"/dev/sdb\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 6 1395066363000\n# HELP container_fs_writes_merged_total Cumulative count of writes merged\n# TYPE container_fs_writes_merged_total counter\ncontainer_fs_writes_merged_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",device=\"sda1\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 39 1395066363000\ncontainer_fs_writes_merged_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",device=\"sda2\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 44 1395066363000\n# HELP container_fs_writes_total Cumulative count of writes completed\n# TYPE container_fs_writes_total counter\ncontainer_fs_writes_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",device=\"sda1\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 28 1395066363000\ncontainer_fs_writes_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",device=\"sda2\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 43 1395066363000\n# HELP container_health_state The result of the container's health check\n# TYPE container_health_state gauge\ncontainer_health_state{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 1 1395066363000\n# HELP container_hugetlb_failcnt Number of hugepage usage hits limits\n# TYPE container_hugetlb_failcnt counter\ncontainer_hugetlb_failcnt{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",pagesize=\"1Gi\",zone_name=\"hello\"} 0 1395066363000\ncontainer_hugetlb_failcnt{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",pagesize=\"2Mi\",zone_name=\"hello\"} 1 1395066363000\n# HELP container_hugetlb_max_usage_bytes Maximum hugepage usage recorded in bytes\n# TYPE container_hugetlb_max_usage_bytes gauge\ncontainer_hugetlb_max_usage_bytes{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",pagesize=\"1Gi\",zone_name=\"hello\"} 0 1395066363000\ncontainer_hugetlb_max_usage_bytes{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",pagesize=\"2Mi\",zone_name=\"hello\"} 10 1395066363000\n# HELP container_hugetlb_usage_bytes Current hugepage usage in bytes\n# TYPE container_hugetlb_usage_bytes gauge\ncontainer_hugetlb_usage_bytes{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",pagesize=\"1Gi\",zone_name=\"hello\"} 0 1395066363000\ncontainer_hugetlb_usage_bytes{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",pagesize=\"2Mi\",zone_name=\"hello\"} 4 1395066363000\n# HELP container_last_seen Last time a container was seen by the exporter\n# TYPE container_last_seen gauge\ncontainer_last_seen{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 1.395066363e+09 1395066363000\n# HELP container_memory_cache Number of bytes of page cache memory.\n# TYPE container_memory_cache gauge\ncontainer_memory_cache{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 14 1395066363000\n# HELP container_memory_failcnt Number of memory usage hits limits\n# TYPE container_memory_failcnt counter\ncontainer_memory_failcnt{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 0 1395066363000\n# HELP container_memory_failures_total Cumulative count of memory allocation failures.\n# TYPE container_memory_failures_total counter\ncontainer_memory_failures_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",failure_type=\"pgfault\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",scope=\"container\",zone_name=\"hello\"} 10 1395066363000\ncontainer_memory_failures_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",failure_type=\"pgfault\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",scope=\"hierarchy\",zone_name=\"hello\"} 12 1395066363000\ncontainer_memory_failures_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",failure_type=\"pgmajfault\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",scope=\"container\",zone_name=\"hello\"} 11 1395066363000\ncontainer_memory_failures_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",failure_type=\"pgmajfault\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",scope=\"hierarchy\",zone_name=\"hello\"} 13 1395066363000\n# HELP container_memory_kernel_usage Size of kernel memory allocated in bytes.\n# TYPE container_memory_kernel_usage gauge\ncontainer_memory_kernel_usage{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 17 1395066363000\n# HELP container_memory_mapped_file Size of memory mapped files in bytes.\n# TYPE container_memory_mapped_file gauge\ncontainer_memory_mapped_file{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 16 1395066363000\n# HELP container_memory_max_usage_bytes Maximum memory usage recorded in bytes\n# TYPE container_memory_max_usage_bytes gauge\ncontainer_memory_max_usage_bytes{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 8 1395066363000\n# HELP container_memory_migrate Memory migrate status.\n# TYPE container_memory_migrate gauge\ncontainer_memory_migrate{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 1 1395066363000\n# HELP container_memory_numa_pages Number of used pages per NUMA node\n# TYPE container_memory_numa_pages gauge\ncontainer_memory_numa_pages{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",node=\"0\",scope=\"container\",type=\"anon\",zone_name=\"hello\"} 10000 1395066363000\ncontainer_memory_numa_pages{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",node=\"0\",scope=\"container\",type=\"file\",zone_name=\"hello\"} 16649 1395066363000\ncontainer_memory_numa_pages{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",node=\"0\",scope=\"container\",type=\"unevictable\",zone_name=\"hello\"} 8900 1395066363000\ncontainer_memory_numa_pages{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",node=\"0\",scope=\"hierarchy\",type=\"anon\",zone_name=\"hello\"} 20000 1395066363000\ncontainer_memory_numa_pages{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",node=\"0\",scope=\"hierarchy\",type=\"file\",zone_name=\"hello\"} 36649 1395066363000\ncontainer_memory_numa_pages{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",node=\"0\",scope=\"hierarchy\",type=\"unevictable\",zone_name=\"hello\"} 8900 1395066363000\ncontainer_memory_numa_pages{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",node=\"1\",scope=\"container\",type=\"anon\",zone_name=\"hello\"} 7109 1395066363000\ncontainer_memory_numa_pages{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",node=\"1\",scope=\"container\",type=\"file\",zone_name=\"hello\"} 10000 1395066363000\ncontainer_memory_numa_pages{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",node=\"1\",scope=\"container\",type=\"unevictable\",zone_name=\"hello\"} 10000 1395066363000\ncontainer_memory_numa_pages{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",node=\"1\",scope=\"hierarchy\",type=\"anon\",zone_name=\"hello\"} 7109 1395066363000\ncontainer_memory_numa_pages{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",node=\"1\",scope=\"hierarchy\",type=\"file\",zone_name=\"hello\"} 10000 1395066363000\ncontainer_memory_numa_pages{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",node=\"1\",scope=\"hierarchy\",type=\"unevictable\",zone_name=\"hello\"} 20000 1395066363000\n# HELP container_memory_rss Size of RSS in bytes.\n# TYPE container_memory_rss gauge\ncontainer_memory_rss{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 15 1395066363000\n# HELP container_memory_swap Container swap usage in bytes.\n# TYPE container_memory_swap gauge\ncontainer_memory_swap{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 8192 1395066363000\n# HELP container_memory_total_active_file_bytes Current total active file in bytes.\n# TYPE container_memory_total_active_file_bytes gauge\ncontainer_memory_total_active_file_bytes{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 7 1395066363000\n# HELP container_memory_total_inactive_file_bytes Current total inactive file in bytes.\n# TYPE container_memory_total_inactive_file_bytes gauge\ncontainer_memory_total_inactive_file_bytes{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 6 1395066363000\n# HELP container_memory_usage_bytes Current memory usage in bytes, including all memory regardless of when it was accessed\n# TYPE container_memory_usage_bytes gauge\ncontainer_memory_usage_bytes{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 8 1395066363000\n# HELP container_memory_working_set_bytes Current working set in bytes.\n# TYPE container_memory_working_set_bytes gauge\ncontainer_memory_working_set_bytes{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 9 1395066363000\n# HELP container_network_advance_tcp_stats_total advance tcp connections statistic for container\n# TYPE container_network_advance_tcp_stats_total gauge\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"activeopens\",zone_name=\"hello\"} 1.1038621e+07 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"attemptfails\",zone_name=\"hello\"} 48997 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"currestab\",zone_name=\"hello\"} 22 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"delayedacklocked\",zone_name=\"hello\"} 90 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"delayedacklost\",zone_name=\"hello\"} 18843 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"delayedacks\",zone_name=\"hello\"} 503975 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"embryonicrsts\",zone_name=\"hello\"} 0 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"estabresets\",zone_name=\"hello\"} 37 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"incsumerrors\",zone_name=\"hello\"} 0 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"inerrs\",zone_name=\"hello\"} 31 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"insegs\",zone_name=\"hello\"} 1.4037059e+08 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"ipreversepathfilter\",zone_name=\"hello\"} 0 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"listendrops\",zone_name=\"hello\"} 0 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"listenoverflows\",zone_name=\"hello\"} 0 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"lockdroppedicmps\",zone_name=\"hello\"} 0 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"maxconn\",zone_name=\"hello\"} -1 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"ofopruned\",zone_name=\"hello\"} 0 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"outofwindowicmps\",zone_name=\"hello\"} 0 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"outrsts\",zone_name=\"hello\"} 91699 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"outsegs\",zone_name=\"hello\"} 2.11580512e+08 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"passiveopens\",zone_name=\"hello\"} 59 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"pawsactive\",zone_name=\"hello\"} 0 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"pawsestab\",zone_name=\"hello\"} 0 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"pfmemallocdrop\",zone_name=\"hello\"} 0 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"prunecalled\",zone_name=\"hello\"} 0 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"rcvpruned\",zone_name=\"hello\"} 0 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"retranssegs\",zone_name=\"hello\"} 462961 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"rtoalgorithm\",zone_name=\"hello\"} 1 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"rtomax\",zone_name=\"hello\"} 120000 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"rtomin\",zone_name=\"hello\"} 200 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"syncookiesfailed\",zone_name=\"hello\"} 0 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"syncookiesrecv\",zone_name=\"hello\"} 0 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"syncookiessent\",zone_name=\"hello\"} 0 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"tcpabortfailed\",zone_name=\"hello\"} 0 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"tcpabortonclose\",zone_name=\"hello\"} 7 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"tcpabortondata\",zone_name=\"hello\"} 8 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"tcpabortonlinger\",zone_name=\"hello\"} 0 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"tcpabortonmemory\",zone_name=\"hello\"} 0 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"tcpabortontimeout\",zone_name=\"hello\"} 0 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"tcpbacklogdrop\",zone_name=\"hello\"} 0 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"tcpdeferacceptdrop\",zone_name=\"hello\"} 0 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"tcpdsackignorednoundo\",zone_name=\"hello\"} 71885 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"tcpdsackignoredold\",zone_name=\"hello\"} 0 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"tcpdsackoforecv\",zone_name=\"hello\"} 10 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"tcpdsackofosent\",zone_name=\"hello\"} 1 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"tcpdsackoldsent\",zone_name=\"hello\"} 15633 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"tcpdsackrecv\",zone_name=\"hello\"} 83680 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"tcpdsackundo\",zone_name=\"hello\"} 33 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"tcpfackreorder\",zone_name=\"hello\"} 0 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"tcpfastopenactive\",zone_name=\"hello\"} 0 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"tcpfastopenactivefail\",zone_name=\"hello\"} 0 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"tcpfastopencookiereqd\",zone_name=\"hello\"} 0 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"tcpfastopenlistenoverflow\",zone_name=\"hello\"} 0 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"tcpfastopenpassive\",zone_name=\"hello\"} 0 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"tcpfastopenpassivefail\",zone_name=\"hello\"} 0 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"tcpfastretrans\",zone_name=\"hello\"} 11794 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"tcpfullundo\",zone_name=\"hello\"} 2361 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"tcphpacks\",zone_name=\"hello\"} 2.1490641e+07 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"tcphphits\",zone_name=\"hello\"} 5.6096478e+07 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"tcplossfailures\",zone_name=\"hello\"} 729 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"tcplossproberecovery\",zone_name=\"hello\"} 401 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"tcplossprobes\",zone_name=\"hello\"} 88648 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"tcplossundo\",zone_name=\"hello\"} 61374 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"tcplostretransmit\",zone_name=\"hello\"} 0 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"tcpmd5failure\",zone_name=\"hello\"} 0 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"tcpmd5notfound\",zone_name=\"hello\"} 0 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"tcpmd5unexpected\",zone_name=\"hello\"} 0 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"tcpmemorypressures\",zone_name=\"hello\"} 0 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"tcpmemorypressureschrono\",zone_name=\"hello\"} 0 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"tcpminttldrop\",zone_name=\"hello\"} 0 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"tcporigdatasent\",zone_name=\"hello\"} 1.30698387e+08 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"tcppartialundo\",zone_name=\"hello\"} 3 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"tcppureacks\",zone_name=\"hello\"} 2.4251339e+07 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"tcprcvcollapsed\",zone_name=\"hello\"} 0 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"tcprenofailures\",zone_name=\"hello\"} 43414 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"tcprenorecovery\",zone_name=\"hello\"} 3519 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"tcprenorecoveryfail\",zone_name=\"hello\"} 394 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"tcprenoreorder\",zone_name=\"hello\"} 839 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"tcpreqqfulldocookies\",zone_name=\"hello\"} 0 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"tcpreqqfulldrop\",zone_name=\"hello\"} 0 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"tcpretransfail\",zone_name=\"hello\"} 0 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"tcpsackdiscard\",zone_name=\"hello\"} 0 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"tcpsackfailures\",zone_name=\"hello\"} 60 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"tcpsackmerged\",zone_name=\"hello\"} 6 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"tcpsackrecovery\",zone_name=\"hello\"} 159 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"tcpsackrecoveryfail\",zone_name=\"hello\"} 2 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"tcpsackreneging\",zone_name=\"hello\"} 0 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"tcpsackreorder\",zone_name=\"hello\"} 11 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"tcpsackshifted\",zone_name=\"hello\"} 2 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"tcpsackshiftfallback\",zone_name=\"hello\"} 298 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"tcpslowstartretrans\",zone_name=\"hello\"} 290832 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"tcpspuriousrtos\",zone_name=\"hello\"} 0 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"tcpsynretrans\",zone_name=\"hello\"} 988 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"tcptimeouts\",zone_name=\"hello\"} 27422 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"tcptimewaitoverflow\",zone_name=\"hello\"} 0 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"tcptsreorder\",zone_name=\"hello\"} 3 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"tw\",zone_name=\"hello\"} 1.0436427e+07 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"twkilled\",zone_name=\"hello\"} 0 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"twrecycled\",zone_name=\"hello\"} 0 1395066363000\n# HELP container_network_receive_bytes_total Cumulative count of bytes received\n# TYPE container_network_receive_bytes_total counter\ncontainer_network_receive_bytes_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",interface=\"eth0\",name=\"testcontaineralias\",zone_name=\"hello\"} 14 1395066363000\n# HELP container_network_receive_errors_total Cumulative count of errors encountered while receiving\n# TYPE container_network_receive_errors_total counter\ncontainer_network_receive_errors_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",interface=\"eth0\",name=\"testcontaineralias\",zone_name=\"hello\"} 16 1395066363000\n# HELP container_network_receive_packets_dropped_total Cumulative count of packets dropped while receiving\n# TYPE container_network_receive_packets_dropped_total counter\ncontainer_network_receive_packets_dropped_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",interface=\"eth0\",name=\"testcontaineralias\",zone_name=\"hello\"} 17 1395066363000\n# HELP container_network_receive_packets_total Cumulative count of packets received\n# TYPE container_network_receive_packets_total counter\ncontainer_network_receive_packets_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",interface=\"eth0\",name=\"testcontaineralias\",zone_name=\"hello\"} 15 1395066363000\n# HELP container_network_tcp6_usage_total tcp6 connection usage statistic for container\n# TYPE container_network_tcp6_usage_total gauge\ncontainer_network_tcp6_usage_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"close\",zone_name=\"hello\"} 0 1395066363000\ncontainer_network_tcp6_usage_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"closewait\",zone_name=\"hello\"} 0 1395066363000\ncontainer_network_tcp6_usage_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"closing\",zone_name=\"hello\"} 0 1395066363000\ncontainer_network_tcp6_usage_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"established\",zone_name=\"hello\"} 11 1395066363000\ncontainer_network_tcp6_usage_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"finwait1\",zone_name=\"hello\"} 0 1395066363000\ncontainer_network_tcp6_usage_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"finwait2\",zone_name=\"hello\"} 0 1395066363000\ncontainer_network_tcp6_usage_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"lastack\",zone_name=\"hello\"} 0 1395066363000\ncontainer_network_tcp6_usage_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"listen\",zone_name=\"hello\"} 3 1395066363000\ncontainer_network_tcp6_usage_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"synrecv\",zone_name=\"hello\"} 0 1395066363000\ncontainer_network_tcp6_usage_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"synsent\",zone_name=\"hello\"} 0 1395066363000\ncontainer_network_tcp6_usage_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"timewait\",zone_name=\"hello\"} 0 1395066363000\n# HELP container_network_tcp_usage_total tcp connection usage statistic for container\n# TYPE container_network_tcp_usage_total gauge\ncontainer_network_tcp_usage_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"close\",zone_name=\"hello\"} 0 1395066363000\ncontainer_network_tcp_usage_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"closewait\",zone_name=\"hello\"} 0 1395066363000\ncontainer_network_tcp_usage_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"closing\",zone_name=\"hello\"} 0 1395066363000\ncontainer_network_tcp_usage_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"established\",zone_name=\"hello\"} 13 1395066363000\ncontainer_network_tcp_usage_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"finwait1\",zone_name=\"hello\"} 0 1395066363000\ncontainer_network_tcp_usage_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"finwait2\",zone_name=\"hello\"} 0 1395066363000\ncontainer_network_tcp_usage_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"lastack\",zone_name=\"hello\"} 0 1395066363000\ncontainer_network_tcp_usage_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"listen\",zone_name=\"hello\"} 3 1395066363000\ncontainer_network_tcp_usage_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"synrecv\",zone_name=\"hello\"} 0 1395066363000\ncontainer_network_tcp_usage_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"synsent\",zone_name=\"hello\"} 0 1395066363000\ncontainer_network_tcp_usage_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"timewait\",zone_name=\"hello\"} 0 1395066363000\n# HELP container_network_transmit_bytes_total Cumulative count of bytes transmitted\n# TYPE container_network_transmit_bytes_total counter\ncontainer_network_transmit_bytes_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",interface=\"eth0\",name=\"testcontaineralias\",zone_name=\"hello\"} 18 1395066363000\n# HELP container_network_transmit_errors_total Cumulative count of errors encountered while transmitting\n# TYPE container_network_transmit_errors_total counter\ncontainer_network_transmit_errors_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",interface=\"eth0\",name=\"testcontaineralias\",zone_name=\"hello\"} 20 1395066363000\n# HELP container_network_transmit_packets_dropped_total Cumulative count of packets dropped while transmitting\n# TYPE container_network_transmit_packets_dropped_total counter\ncontainer_network_transmit_packets_dropped_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",interface=\"eth0\",name=\"testcontaineralias\",zone_name=\"hello\"} 21 1395066363000\n# HELP container_network_transmit_packets_total Cumulative count of packets transmitted\n# TYPE container_network_transmit_packets_total counter\ncontainer_network_transmit_packets_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",interface=\"eth0\",name=\"testcontaineralias\",zone_name=\"hello\"} 19 1395066363000\n# HELP container_network_udp6_usage_total udp6 connection usage statistic for container\n# TYPE container_network_udp6_usage_total gauge\ncontainer_network_udp6_usage_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",udp_state=\"dropped\",zone_name=\"hello\"} 0 1395066363000\ncontainer_network_udp6_usage_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",udp_state=\"listen\",zone_name=\"hello\"} 0 1395066363000\ncontainer_network_udp6_usage_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",udp_state=\"rxqueued\",zone_name=\"hello\"} 0 1395066363000\ncontainer_network_udp6_usage_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",udp_state=\"txqueued\",zone_name=\"hello\"} 0 1395066363000\n# HELP container_network_udp_usage_total udp connection usage statistic for container\n# TYPE container_network_udp_usage_total gauge\ncontainer_network_udp_usage_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",udp_state=\"dropped\",zone_name=\"hello\"} 0 1395066363000\ncontainer_network_udp_usage_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",udp_state=\"listen\",zone_name=\"hello\"} 0 1395066363000\ncontainer_network_udp_usage_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",udp_state=\"rxqueued\",zone_name=\"hello\"} 0 1395066363000\ncontainer_network_udp_usage_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",udp_state=\"txqueued\",zone_name=\"hello\"} 0 1395066363000\n# HELP container_oom_events_total Count of out of memory events observed for the container\n# TYPE container_oom_events_total counter\ncontainer_oom_events_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 0 1395066363000\n# HELP container_perf_events_total Perf event metric.\n# TYPE container_perf_events_total counter\ncontainer_perf_events_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",cpu=\"0\",event=\"instructions\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 123 1395066363000\ncontainer_perf_events_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",cpu=\"0\",event=\"instructions_retired\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 321 1395066363000\ncontainer_perf_events_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",cpu=\"1\",event=\"instructions\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 456 1395066363000\ncontainer_perf_events_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",cpu=\"1\",event=\"instructions_retired\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 789 1395066363000\n# HELP container_perf_events_scaling_ratio Perf event metric scaling ratio.\n# TYPE container_perf_events_scaling_ratio gauge\ncontainer_perf_events_scaling_ratio{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",cpu=\"0\",event=\"instructions\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 1 1395066363000\ncontainer_perf_events_scaling_ratio{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",cpu=\"0\",event=\"instructions_retired\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 0.66666666666 1395066363000\ncontainer_perf_events_scaling_ratio{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",cpu=\"1\",event=\"instructions\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 0.5 1395066363000\ncontainer_perf_events_scaling_ratio{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",cpu=\"1\",event=\"instructions_retired\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 0.33333333333 1395066363000\n# HELP container_perf_uncore_events_total Perf uncore event metric.\n# TYPE container_perf_uncore_events_total counter\ncontainer_perf_uncore_events_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",event=\"cas_count_read\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",pmu=\"uncore_imc_0\",socket=\"0\",zone_name=\"hello\"} 1.231231512e+09 1395066363000\ncontainer_perf_uncore_events_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",event=\"cas_count_read\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",pmu=\"uncore_imc_0\",socket=\"1\",zone_name=\"hello\"} 1.111231331e+09 1395066363000\n# HELP container_perf_uncore_events_scaling_ratio Perf uncore event metric scaling ratio.\n# TYPE container_perf_uncore_events_scaling_ratio gauge\ncontainer_perf_uncore_events_scaling_ratio{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",event=\"cas_count_read\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",pmu=\"uncore_imc_0\",socket=\"0\",zone_name=\"hello\"} 1 1395066363000\ncontainer_perf_uncore_events_scaling_ratio{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",event=\"cas_count_read\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",pmu=\"uncore_imc_0\",socket=\"1\",zone_name=\"hello\"} 1 1395066363000\n# HELP container_pressure_cpu_stalled_seconds_total Total time duration no tasks in the container could make progress due to CPU congestion.\n# TYPE container_pressure_cpu_stalled_seconds_total counter\ncontainer_pressure_cpu_stalled_seconds_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 0.0001 1395066363000\n# HELP container_pressure_cpu_waiting_seconds_total Total time duration tasks in the container have waited due to CPU congestion.\n# TYPE container_pressure_cpu_waiting_seconds_total counter\ncontainer_pressure_cpu_waiting_seconds_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 0.0002 1395066363000\n# HELP container_pressure_io_stalled_seconds_total Total time duration no tasks in the container could make progress due to IO congestion.\n# TYPE container_pressure_io_stalled_seconds_total counter\ncontainer_pressure_io_stalled_seconds_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 0.0011 1395066363000\n# HELP container_pressure_io_waiting_seconds_total Total time duration tasks in the container have waited due to IO congestion.\n# TYPE container_pressure_io_waiting_seconds_total counter\ncontainer_pressure_io_waiting_seconds_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 0.0022 1395066363000\n# HELP container_pressure_memory_stalled_seconds_total Total time duration no tasks in the container could make progress due to memory congestion.\n# TYPE container_pressure_memory_stalled_seconds_total counter\ncontainer_pressure_memory_stalled_seconds_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 0.001 1395066363000\n# HELP container_pressure_memory_waiting_seconds_total Total time duration tasks in the container have waited due to memory congestion.\n# TYPE container_pressure_memory_waiting_seconds_total counter\ncontainer_pressure_memory_waiting_seconds_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 0.002 1395066363000\n# HELP container_processes Number of processes running inside the container.\n# TYPE container_processes gauge\ncontainer_processes{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 1 1395066363000\n# HELP container_referenced_bytes Container referenced bytes during last measurements cycle\n# TYPE container_referenced_bytes gauge\ncontainer_referenced_bytes{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 1234 1395066363000\n# HELP container_scrape_error 1 if there was an error while getting container metrics, 0 otherwise\n# TYPE container_scrape_error gauge\ncontainer_scrape_error 0\n# HELP container_sockets Number of open sockets for the container.\n# TYPE container_sockets gauge\ncontainer_sockets{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 3 1395066363000\n# HELP container_spec_cpu_period CPU period of the container.\n# TYPE container_spec_cpu_period gauge\ncontainer_spec_cpu_period{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 100000\n# HELP container_spec_cpu_quota CPU quota of the container.\n# TYPE container_spec_cpu_quota gauge\ncontainer_spec_cpu_quota{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 10000\n# HELP container_spec_cpu_shares CPU share of the container.\n# TYPE container_spec_cpu_shares gauge\ncontainer_spec_cpu_shares{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 1000\n# HELP container_creation_time_seconds Container creation time since unix epoch in seconds.\n# TYPE container_creation_time_seconds gauge\ncontainer_creation_time_seconds{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 1.257894e+09\n# HELP container_start_time_seconds Start time of the container since unix epoch in seconds.\n# TYPE container_start_time_seconds gauge\ncontainer_start_time_seconds{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 1.257895e+09\n# HELP container_tasks_state Number of tasks in given state\n# TYPE container_tasks_state gauge\ncontainer_tasks_state{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",state=\"iowaiting\",zone_name=\"hello\"} 54 1395066363000\ncontainer_tasks_state{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",state=\"running\",zone_name=\"hello\"} 51 1395066363000\ncontainer_tasks_state{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",state=\"sleeping\",zone_name=\"hello\"} 50 1395066363000\ncontainer_tasks_state{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",state=\"stopped\",zone_name=\"hello\"} 52 1395066363000\ncontainer_tasks_state{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",state=\"uninterruptible\",zone_name=\"hello\"} 53 1395066363000\n# HELP container_threads Number of threads running inside the container\n# TYPE container_threads gauge\ncontainer_threads{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 5 1395066363000\n# HELP container_threads_max Maximum number of threads allowed inside the container, infinity if value is zero\n# TYPE container_threads_max gauge\ncontainer_threads_max{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 100 1395066363000\n# HELP container_ulimits_soft Soft ulimit values for the container root process. Unlimited if -1, except priority and nice\n# TYPE container_ulimits_soft gauge\ncontainer_ulimits_soft{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",ulimit=\"max_open_files\",zone_name=\"hello\"} 16384 1395066363000\n# HELP container_llc_occupancy_bytes Last level cache usage statistics for container counted with RDT Memory Bandwidth Monitoring (MBM).\n# TYPE container_llc_occupancy_bytes gauge\ncontainer_llc_occupancy_bytes{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",node_id=\"0\",zone_name=\"hello\"} 162626 1395066363000\ncontainer_llc_occupancy_bytes{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",node_id=\"1\",zone_name=\"hello\"} 213777 1395066363000\n# HELP container_memory_bandwidth_bytes Total memory bandwidth usage statistics for container counted with RDT Memory Bandwidth Monitoring (MBM).\n# TYPE container_memory_bandwidth_bytes gauge\ncontainer_memory_bandwidth_bytes{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",node_id=\"0\",zone_name=\"hello\"} 4.512312e+06 1395066363000\ncontainer_memory_bandwidth_bytes{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",node_id=\"1\",zone_name=\"hello\"} 2.173713e+06 1395066363000\n# HELP container_memory_bandwidth_local_bytes Local memory bandwidth usage statistics for container counted with RDT Memory Bandwidth Monitoring (MBM).\n# TYPE container_memory_bandwidth_local_bytes gauge\ncontainer_memory_bandwidth_local_bytes{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",node_id=\"0\",zone_name=\"hello\"} 2.390393e+06 1395066363000\ncontainer_memory_bandwidth_local_bytes{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",node_id=\"1\",zone_name=\"hello\"} 1.231233e+06 1395066363000\n"
  },
  {
    "path": "metrics/testdata/prometheus_metrics_failure",
    "content": "# HELP container_scrape_error 1 if there was an error while getting container metrics, 0 otherwise\n# TYPE container_scrape_error gauge\ncontainer_scrape_error 1\n"
  },
  {
    "path": "metrics/testdata/prometheus_metrics_perf_aggregated",
    "content": "# HELP cadvisor_version_info A metric with a constant '1' value labeled by kernel version, OS version, docker version, cadvisor version & cadvisor revision.\n# TYPE cadvisor_version_info gauge\ncadvisor_version_info{cadvisorRevision=\"abcdef\",cadvisorVersion=\"0.16.0\",dockerVersion=\"1.8.1\",kernelVersion=\"4.1.6-200.fc22.x86_64\",osVersion=\"Fedora 22 (Twenty Two)\"} 1\n# HELP container_health_state The result of the container's health check\n# TYPE container_health_state gauge\ncontainer_health_state{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 1 1395066363000\n# HELP container_last_seen Last time a container was seen by the exporter\n# TYPE container_last_seen gauge\ncontainer_last_seen{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 1.395066363e+09 1395066363000\n# HELP container_perf_events_scaling_ratio Perf event metric scaling ratio.\n# TYPE container_perf_events_scaling_ratio gauge\ncontainer_perf_events_scaling_ratio{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",cpu=\"\",event=\"instructions\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 0.5 1395066363000\ncontainer_perf_events_scaling_ratio{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",cpu=\"\",event=\"instructions_retired\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 0.33333333333 1395066363000\n# HELP container_perf_events_total Perf event metric.\n# TYPE container_perf_events_total counter\ncontainer_perf_events_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",cpu=\"\",event=\"instructions\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 579 1395066363000\ncontainer_perf_events_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",cpu=\"\",event=\"instructions_retired\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 1110 1395066363000\n# HELP container_perf_uncore_events_scaling_ratio Perf uncore event metric scaling ratio.\n# TYPE container_perf_uncore_events_scaling_ratio gauge\ncontainer_perf_uncore_events_scaling_ratio{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",event=\"cas_count_read\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",pmu=\"uncore_imc_0\",socket=\"0\",zone_name=\"hello\"} 1 1395066363000\ncontainer_perf_uncore_events_scaling_ratio{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",event=\"cas_count_read\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",pmu=\"uncore_imc_0\",socket=\"1\",zone_name=\"hello\"} 1 1395066363000\n# HELP container_perf_uncore_events_total Perf uncore event metric.\n# TYPE container_perf_uncore_events_total counter\ncontainer_perf_uncore_events_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",event=\"cas_count_read\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",pmu=\"uncore_imc_0\",socket=\"0\",zone_name=\"hello\"} 1.231231512e+09 1395066363000\ncontainer_perf_uncore_events_total{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",event=\"cas_count_read\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",pmu=\"uncore_imc_0\",socket=\"1\",zone_name=\"hello\"} 1.111231331e+09 1395066363000\n# HELP container_scrape_error 1 if there was an error while getting container metrics, 0 otherwise\n# TYPE container_scrape_error gauge\ncontainer_scrape_error 0\n# HELP container_spec_cpu_period CPU period of the container.\n# TYPE container_spec_cpu_period gauge\ncontainer_spec_cpu_period{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 100000\n# HELP container_spec_cpu_quota CPU quota of the container.\n# TYPE container_spec_cpu_quota gauge\ncontainer_spec_cpu_quota{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 10000\n# HELP container_spec_cpu_shares CPU share of the container.\n# TYPE container_spec_cpu_shares gauge\ncontainer_spec_cpu_shares{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 1000\n# HELP container_creation_time_seconds Container creation time since unix epoch in seconds.\n# TYPE container_creation_time_seconds gauge\ncontainer_creation_time_seconds{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 1.257894e+09\n# HELP container_start_time_seconds Start time of the container since unix epoch in seconds.\n# TYPE container_start_time_seconds gauge\ncontainer_start_time_seconds{container_env_foo_env=\"prod\",container_label_foo_label=\"bar\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 1.257895e+09\n"
  },
  {
    "path": "metrics/testdata/prometheus_metrics_whitelist_filtered",
    "content": "# HELP cadvisor_version_info A metric with a constant '1' value labeled by kernel version, OS version, docker version, cadvisor version & cadvisor revision.\n# TYPE cadvisor_version_info gauge\ncadvisor_version_info{cadvisorRevision=\"abcdef\",cadvisorVersion=\"0.16.0\",dockerVersion=\"1.8.1\",kernelVersion=\"4.1.6-200.fc22.x86_64\",osVersion=\"Fedora 22 (Twenty Two)\"} 1\n# HELP container_blkio_device_usage_total Blkio Device bytes usage\n# TYPE container_blkio_device_usage_total counter\ncontainer_blkio_device_usage_total{container_env_foo_env=\"prod\",device=\"/dev/sdb\",id=\"testcontainer\",image=\"test\",major=\"8\",minor=\"0\",name=\"testcontaineralias\",operation=\"Async\",zone_name=\"hello\"} 1 1395066363000\ncontainer_blkio_device_usage_total{container_env_foo_env=\"prod\",device=\"/dev/sdb\",id=\"testcontainer\",image=\"test\",major=\"8\",minor=\"0\",name=\"testcontaineralias\",operation=\"Discard\",zone_name=\"hello\"} 2 1395066363000\ncontainer_blkio_device_usage_total{container_env_foo_env=\"prod\",device=\"/dev/sdb\",id=\"testcontainer\",image=\"test\",major=\"8\",minor=\"0\",name=\"testcontaineralias\",operation=\"Read\",zone_name=\"hello\"} 3 1395066363000\ncontainer_blkio_device_usage_total{container_env_foo_env=\"prod\",device=\"/dev/sdb\",id=\"testcontainer\",image=\"test\",major=\"8\",minor=\"0\",name=\"testcontaineralias\",operation=\"Sync\",zone_name=\"hello\"} 4 1395066363000\ncontainer_blkio_device_usage_total{container_env_foo_env=\"prod\",device=\"/dev/sdb\",id=\"testcontainer\",image=\"test\",major=\"8\",minor=\"0\",name=\"testcontaineralias\",operation=\"Total\",zone_name=\"hello\"} 5 1395066363000\ncontainer_blkio_device_usage_total{container_env_foo_env=\"prod\",device=\"/dev/sdb\",id=\"testcontainer\",image=\"test\",major=\"8\",minor=\"0\",name=\"testcontaineralias\",operation=\"Write\",zone_name=\"hello\"} 6 1395066363000\n# HELP container_cpu_cfs_periods_total Number of elapsed enforcement period intervals.\n# TYPE container_cpu_cfs_periods_total counter\ncontainer_cpu_cfs_periods_total{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 723 1395066363000\n# HELP container_cpu_cfs_throttled_periods_total Number of throttled period intervals.\n# TYPE container_cpu_cfs_throttled_periods_total counter\ncontainer_cpu_cfs_throttled_periods_total{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 18 1395066363000\n# HELP container_cpu_cfs_throttled_seconds_total Total time duration the container has been throttled.\n# TYPE container_cpu_cfs_throttled_seconds_total counter\ncontainer_cpu_cfs_throttled_seconds_total{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 1.724314 1395066363000\n# HELP container_cpu_cfs_burst_periods_total Number of periods when burst occurs.\n# TYPE container_cpu_cfs_burst_periods_total counter\ncontainer_cpu_cfs_burst_periods_total{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 25 1395066363000\n# HELP container_cpu_cfs_burst_seconds_total Total time duration the container has been bursted.\n# TYPE container_cpu_cfs_burst_seconds_total counter\ncontainer_cpu_cfs_burst_seconds_total{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 0.5 1395066363000\n# HELP container_cpu_load_average_10s Value of container cpu load average over the last 10 seconds.\n# TYPE container_cpu_load_average_10s gauge\ncontainer_cpu_load_average_10s{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 2 1395066363000\n# HELP container_cpu_load_d_average_10s Value of container cpu load.d average over the last 10 seconds.\n# TYPE container_cpu_load_d_average_10s gauge\ncontainer_cpu_load_d_average_10s{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 2 1395066363000\n# HELP container_cpu_schedstat_run_periods_total Number of times processes of the cgroup have run on the cpu\n# TYPE container_cpu_schedstat_run_periods_total counter\ncontainer_cpu_schedstat_run_periods_total{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 984285 1395066363000\n# HELP container_cpu_schedstat_run_seconds_total Time duration the processes of the container have run on the CPU.\n# TYPE container_cpu_schedstat_run_seconds_total counter\ncontainer_cpu_schedstat_run_seconds_total{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 0.053643567 1395066363000\n# HELP container_cpu_schedstat_runqueue_seconds_total Time duration processes of the container have been waiting on a runqueue.\n# TYPE container_cpu_schedstat_runqueue_seconds_total counter\ncontainer_cpu_schedstat_runqueue_seconds_total{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 479.424566378 1395066363000\n# HELP container_cpu_system_seconds_total Cumulative system cpu time consumed in seconds.\n# TYPE container_cpu_system_seconds_total counter\ncontainer_cpu_system_seconds_total{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 7e-09 1395066363000\n# HELP container_cpu_usage_seconds_total Cumulative cpu time consumed in seconds.\n# TYPE container_cpu_usage_seconds_total counter\ncontainer_cpu_usage_seconds_total{container_env_foo_env=\"prod\",cpu=\"cpu00\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 2e-09 1395066363000\ncontainer_cpu_usage_seconds_total{container_env_foo_env=\"prod\",cpu=\"cpu01\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 3e-09 1395066363000\ncontainer_cpu_usage_seconds_total{container_env_foo_env=\"prod\",cpu=\"cpu02\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 4e-09 1395066363000\ncontainer_cpu_usage_seconds_total{container_env_foo_env=\"prod\",cpu=\"cpu03\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 5e-09 1395066363000\n# HELP container_cpu_user_seconds_total Cumulative user cpu time consumed in seconds.\n# TYPE container_cpu_user_seconds_total counter\ncontainer_cpu_user_seconds_total{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 6e-09 1395066363000\n# HELP container_custom_app_metric_1 Custom application metric.\n# TYPE container_custom_app_metric_1 gauge\ncontainer_custom_app_metric_1{app_test_label=\"1_1\",app_test_label_2=\"2_1\",container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 1.1\ncontainer_custom_app_metric_1{app_test_label=\"1_2\",app_test_label_2=\"2_2\",container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 1.2\n# HELP container_custom_app_metric_2 Custom application metric.\n# TYPE container_custom_app_metric_2 gauge\ncontainer_custom_app_metric_2{app_test_label=\"test_value\",container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 2\n# HELP container_custom_app_metric_3 Custom application metric.\n# TYPE container_custom_app_metric_3 gauge\ncontainer_custom_app_metric_3{app_test_label=\"test_value\",container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 3\n# HELP container_file_descriptors Number of open file descriptors for the container.\n# TYPE container_file_descriptors gauge\ncontainer_file_descriptors{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 5 1395066363000\n# HELP container_fs_inodes_free Number of available Inodes\n# TYPE container_fs_inodes_free gauge\ncontainer_fs_inodes_free{container_env_foo_env=\"prod\",device=\"sda1\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 524288 1395066363000\ncontainer_fs_inodes_free{container_env_foo_env=\"prod\",device=\"sda2\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 262144 1395066363000\n# HELP container_fs_inodes_total Number of Inodes\n# TYPE container_fs_inodes_total gauge\ncontainer_fs_inodes_total{container_env_foo_env=\"prod\",device=\"sda1\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 2.097152e+06 1395066363000\ncontainer_fs_inodes_total{container_env_foo_env=\"prod\",device=\"sda2\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 2.097152e+06 1395066363000\n# HELP container_fs_io_current Number of I/Os currently in progress\n# TYPE container_fs_io_current gauge\ncontainer_fs_io_current{container_env_foo_env=\"prod\",device=\"sda1\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 42 1395066363000\ncontainer_fs_io_current{container_env_foo_env=\"prod\",device=\"sda2\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 47 1395066363000\n# HELP container_fs_io_time_seconds_total Cumulative count of seconds spent doing I/Os\n# TYPE container_fs_io_time_seconds_total counter\ncontainer_fs_io_time_seconds_total{container_env_foo_env=\"prod\",device=\"sda1\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 4.3e-08 1395066363000\ncontainer_fs_io_time_seconds_total{container_env_foo_env=\"prod\",device=\"sda2\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 4.8e-08 1395066363000\n# HELP container_fs_io_time_weighted_seconds_total Cumulative weighted I/O time in seconds\n# TYPE container_fs_io_time_weighted_seconds_total counter\ncontainer_fs_io_time_weighted_seconds_total{container_env_foo_env=\"prod\",device=\"sda1\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 4.4e-08 1395066363000\ncontainer_fs_io_time_weighted_seconds_total{container_env_foo_env=\"prod\",device=\"sda2\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 4.9e-08 1395066363000\n# HELP container_fs_io_cost_usage_seconds_total Cumulative IOCost usage in seconds\n# TYPE container_fs_io_cost_usage_seconds_total counter\ncontainer_fs_io_cost_usage_seconds_total{container_env_foo_env=\"prod\",device=\"sda1\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 1.5 1395066363000\n# HELP container_fs_io_cost_wait_seconds_total Cumulative IOCost wait in seconds\n# TYPE container_fs_io_cost_wait_seconds_total counter\ncontainer_fs_io_cost_wait_seconds_total{container_env_foo_env=\"prod\",device=\"sda1\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 2.5 1395066363000\n# HELP container_fs_io_cost_indebt_seconds_total Cumulative IOCost debt in seconds\n# TYPE container_fs_io_cost_indebt_seconds_total counter\ncontainer_fs_io_cost_indebt_seconds_total{container_env_foo_env=\"prod\",device=\"sda1\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 0.5 1395066363000\n# HELP container_fs_io_cost_indelay_seconds_total Cumulative IOCost delay in seconds\n# TYPE container_fs_io_cost_indelay_seconds_total counter\ncontainer_fs_io_cost_indelay_seconds_total{container_env_foo_env=\"prod\",device=\"sda1\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 0.75 1395066363000\n# HELP container_fs_limit_bytes Number of bytes that can be consumed by the container on this filesystem.\n# TYPE container_fs_limit_bytes gauge\ncontainer_fs_limit_bytes{container_env_foo_env=\"prod\",device=\"sda1\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 22 1395066363000\ncontainer_fs_limit_bytes{container_env_foo_env=\"prod\",device=\"sda2\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 37 1395066363000\n# HELP container_fs_read_seconds_total Cumulative count of seconds spent reading\n# TYPE container_fs_read_seconds_total counter\ncontainer_fs_read_seconds_total{container_env_foo_env=\"prod\",device=\"sda1\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 2.7e-08 1395066363000\ncontainer_fs_read_seconds_total{container_env_foo_env=\"prod\",device=\"sda2\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 4.2e-08 1395066363000\n# HELP container_fs_reads_bytes_total Cumulative count of bytes read\n# TYPE container_fs_reads_bytes_total counter\ncontainer_fs_reads_bytes_total{container_env_foo_env=\"prod\",device=\"/dev/sdb\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 3 1395066363000\n# HELP container_fs_reads_merged_total Cumulative count of reads merged\n# TYPE container_fs_reads_merged_total counter\ncontainer_fs_reads_merged_total{container_env_foo_env=\"prod\",device=\"sda1\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 25 1395066363000\ncontainer_fs_reads_merged_total{container_env_foo_env=\"prod\",device=\"sda2\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 40 1395066363000\n# HELP container_fs_reads_total Cumulative count of reads completed\n# TYPE container_fs_reads_total counter\ncontainer_fs_reads_total{container_env_foo_env=\"prod\",device=\"sda1\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 24 1395066363000\ncontainer_fs_reads_total{container_env_foo_env=\"prod\",device=\"sda2\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 39 1395066363000\n# HELP container_fs_sector_reads_total Cumulative count of sector reads completed\n# TYPE container_fs_sector_reads_total counter\ncontainer_fs_sector_reads_total{container_env_foo_env=\"prod\",device=\"sda1\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 26 1395066363000\ncontainer_fs_sector_reads_total{container_env_foo_env=\"prod\",device=\"sda2\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 41 1395066363000\n# HELP container_fs_sector_writes_total Cumulative count of sector writes completed\n# TYPE container_fs_sector_writes_total counter\ncontainer_fs_sector_writes_total{container_env_foo_env=\"prod\",device=\"sda1\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 40 1395066363000\ncontainer_fs_sector_writes_total{container_env_foo_env=\"prod\",device=\"sda2\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 45 1395066363000\n# HELP container_fs_usage_bytes Number of bytes that are consumed by the container on this filesystem.\n# TYPE container_fs_usage_bytes gauge\ncontainer_fs_usage_bytes{container_env_foo_env=\"prod\",device=\"sda1\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 23 1395066363000\ncontainer_fs_usage_bytes{container_env_foo_env=\"prod\",device=\"sda2\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 38 1395066363000\n# HELP container_fs_write_seconds_total Cumulative count of seconds spent writing\n# TYPE container_fs_write_seconds_total counter\ncontainer_fs_write_seconds_total{container_env_foo_env=\"prod\",device=\"sda1\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 4.1e-08 1395066363000\ncontainer_fs_write_seconds_total{container_env_foo_env=\"prod\",device=\"sda2\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 4.6e-08 1395066363000\n# HELP container_fs_writes_bytes_total Cumulative count of bytes written\n# TYPE container_fs_writes_bytes_total counter\ncontainer_fs_writes_bytes_total{container_env_foo_env=\"prod\",device=\"/dev/sdb\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 6 1395066363000\n# HELP container_fs_writes_merged_total Cumulative count of writes merged\n# TYPE container_fs_writes_merged_total counter\ncontainer_fs_writes_merged_total{container_env_foo_env=\"prod\",device=\"sda1\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 39 1395066363000\ncontainer_fs_writes_merged_total{container_env_foo_env=\"prod\",device=\"sda2\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 44 1395066363000\n# HELP container_fs_writes_total Cumulative count of writes completed\n# TYPE container_fs_writes_total counter\ncontainer_fs_writes_total{container_env_foo_env=\"prod\",device=\"sda1\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 28 1395066363000\ncontainer_fs_writes_total{container_env_foo_env=\"prod\",device=\"sda2\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 43 1395066363000\n# HELP container_health_state The result of the container's health check\n# TYPE container_health_state gauge\ncontainer_health_state{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 1 1395066363000\n# HELP container_hugetlb_failcnt Number of hugepage usage hits limits\n# TYPE container_hugetlb_failcnt counter\ncontainer_hugetlb_failcnt{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",pagesize=\"1Gi\",zone_name=\"hello\"} 0 1395066363000\ncontainer_hugetlb_failcnt{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",pagesize=\"2Mi\",zone_name=\"hello\"} 1 1395066363000\n# HELP container_hugetlb_max_usage_bytes Maximum hugepage usage recorded in bytes\n# TYPE container_hugetlb_max_usage_bytes gauge\ncontainer_hugetlb_max_usage_bytes{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",pagesize=\"1Gi\",zone_name=\"hello\"} 0 1395066363000\ncontainer_hugetlb_max_usage_bytes{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",pagesize=\"2Mi\",zone_name=\"hello\"} 10 1395066363000\n# HELP container_hugetlb_usage_bytes Current hugepage usage in bytes\n# TYPE container_hugetlb_usage_bytes gauge\ncontainer_hugetlb_usage_bytes{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",pagesize=\"1Gi\",zone_name=\"hello\"} 0 1395066363000\ncontainer_hugetlb_usage_bytes{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",pagesize=\"2Mi\",zone_name=\"hello\"} 4 1395066363000\n# HELP container_last_seen Last time a container was seen by the exporter\n# TYPE container_last_seen gauge\ncontainer_last_seen{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 1.395066363e+09 1395066363000\n# HELP container_memory_cache Number of bytes of page cache memory.\n# TYPE container_memory_cache gauge\ncontainer_memory_cache{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 14 1395066363000\n# HELP container_memory_failcnt Number of memory usage hits limits\n# TYPE container_memory_failcnt counter\ncontainer_memory_failcnt{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 0 1395066363000\n# HELP container_memory_failures_total Cumulative count of memory allocation failures.\n# TYPE container_memory_failures_total counter\ncontainer_memory_failures_total{container_env_foo_env=\"prod\",failure_type=\"pgfault\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",scope=\"container\",zone_name=\"hello\"} 10 1395066363000\ncontainer_memory_failures_total{container_env_foo_env=\"prod\",failure_type=\"pgfault\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",scope=\"hierarchy\",zone_name=\"hello\"} 12 1395066363000\ncontainer_memory_failures_total{container_env_foo_env=\"prod\",failure_type=\"pgmajfault\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",scope=\"container\",zone_name=\"hello\"} 11 1395066363000\ncontainer_memory_failures_total{container_env_foo_env=\"prod\",failure_type=\"pgmajfault\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",scope=\"hierarchy\",zone_name=\"hello\"} 13 1395066363000\n# HELP container_memory_kernel_usage Size of kernel memory allocated in bytes.\n# TYPE container_memory_kernel_usage gauge\ncontainer_memory_kernel_usage{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 17 1395066363000\n# HELP container_memory_mapped_file Size of memory mapped files in bytes.\n# TYPE container_memory_mapped_file gauge\ncontainer_memory_mapped_file{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 16 1395066363000\n# HELP container_memory_max_usage_bytes Maximum memory usage recorded in bytes\n# TYPE container_memory_max_usage_bytes gauge\ncontainer_memory_max_usage_bytes{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 8 1395066363000\n# HELP container_memory_migrate Memory migrate status.\n# TYPE container_memory_migrate gauge\ncontainer_memory_migrate{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 1 1395066363000\n# HELP container_memory_numa_pages Number of used pages per NUMA node\n# TYPE container_memory_numa_pages gauge\ncontainer_memory_numa_pages{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",node=\"0\",scope=\"container\",type=\"anon\",zone_name=\"hello\"} 10000 1395066363000\ncontainer_memory_numa_pages{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",node=\"0\",scope=\"container\",type=\"file\",zone_name=\"hello\"} 16649 1395066363000\ncontainer_memory_numa_pages{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",node=\"0\",scope=\"container\",type=\"unevictable\",zone_name=\"hello\"} 8900 1395066363000\ncontainer_memory_numa_pages{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",node=\"0\",scope=\"hierarchy\",type=\"anon\",zone_name=\"hello\"} 20000 1395066363000\ncontainer_memory_numa_pages{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",node=\"0\",scope=\"hierarchy\",type=\"file\",zone_name=\"hello\"} 36649 1395066363000\ncontainer_memory_numa_pages{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",node=\"0\",scope=\"hierarchy\",type=\"unevictable\",zone_name=\"hello\"} 8900 1395066363000\ncontainer_memory_numa_pages{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",node=\"1\",scope=\"container\",type=\"anon\",zone_name=\"hello\"} 7109 1395066363000\ncontainer_memory_numa_pages{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",node=\"1\",scope=\"container\",type=\"file\",zone_name=\"hello\"} 10000 1395066363000\ncontainer_memory_numa_pages{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",node=\"1\",scope=\"container\",type=\"unevictable\",zone_name=\"hello\"} 10000 1395066363000\ncontainer_memory_numa_pages{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",node=\"1\",scope=\"hierarchy\",type=\"anon\",zone_name=\"hello\"} 7109 1395066363000\ncontainer_memory_numa_pages{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",node=\"1\",scope=\"hierarchy\",type=\"file\",zone_name=\"hello\"} 10000 1395066363000\ncontainer_memory_numa_pages{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",node=\"1\",scope=\"hierarchy\",type=\"unevictable\",zone_name=\"hello\"} 20000 1395066363000\n# HELP container_memory_rss Size of RSS in bytes.\n# TYPE container_memory_rss gauge\ncontainer_memory_rss{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 15 1395066363000\n# HELP container_memory_swap Container swap usage in bytes.\n# TYPE container_memory_swap gauge\ncontainer_memory_swap{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 8192 1395066363000\n# HELP container_memory_total_active_file_bytes Current total active file in bytes.\n# TYPE container_memory_total_active_file_bytes gauge\ncontainer_memory_total_active_file_bytes{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 7 1395066363000\n# HELP container_memory_total_inactive_file_bytes Current total inactive file in bytes.\n# TYPE container_memory_total_inactive_file_bytes gauge\ncontainer_memory_total_inactive_file_bytes{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 6 1395066363000\n# HELP container_memory_usage_bytes Current memory usage in bytes, including all memory regardless of when it was accessed\n# TYPE container_memory_usage_bytes gauge\ncontainer_memory_usage_bytes{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 8 1395066363000\n# HELP container_memory_working_set_bytes Current working set in bytes.\n# TYPE container_memory_working_set_bytes gauge\ncontainer_memory_working_set_bytes{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 9 1395066363000\n# HELP container_network_advance_tcp_stats_total advance tcp connections statistic for container\n# TYPE container_network_advance_tcp_stats_total gauge\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"activeopens\",zone_name=\"hello\"} 1.1038621e+07 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"attemptfails\",zone_name=\"hello\"} 48997 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"currestab\",zone_name=\"hello\"} 22 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"delayedacklocked\",zone_name=\"hello\"} 90 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"delayedacklost\",zone_name=\"hello\"} 18843 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"delayedacks\",zone_name=\"hello\"} 503975 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"embryonicrsts\",zone_name=\"hello\"} 0 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"estabresets\",zone_name=\"hello\"} 37 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"incsumerrors\",zone_name=\"hello\"} 0 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"inerrs\",zone_name=\"hello\"} 31 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"insegs\",zone_name=\"hello\"} 1.4037059e+08 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"ipreversepathfilter\",zone_name=\"hello\"} 0 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"listendrops\",zone_name=\"hello\"} 0 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"listenoverflows\",zone_name=\"hello\"} 0 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"lockdroppedicmps\",zone_name=\"hello\"} 0 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"maxconn\",zone_name=\"hello\"} -1 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"ofopruned\",zone_name=\"hello\"} 0 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"outofwindowicmps\",zone_name=\"hello\"} 0 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"outrsts\",zone_name=\"hello\"} 91699 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"outsegs\",zone_name=\"hello\"} 2.11580512e+08 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"passiveopens\",zone_name=\"hello\"} 59 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"pawsactive\",zone_name=\"hello\"} 0 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"pawsestab\",zone_name=\"hello\"} 0 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"pfmemallocdrop\",zone_name=\"hello\"} 0 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"prunecalled\",zone_name=\"hello\"} 0 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"rcvpruned\",zone_name=\"hello\"} 0 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"retranssegs\",zone_name=\"hello\"} 462961 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"rtoalgorithm\",zone_name=\"hello\"} 1 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"rtomax\",zone_name=\"hello\"} 120000 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"rtomin\",zone_name=\"hello\"} 200 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"syncookiesfailed\",zone_name=\"hello\"} 0 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"syncookiesrecv\",zone_name=\"hello\"} 0 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"syncookiessent\",zone_name=\"hello\"} 0 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"tcpabortfailed\",zone_name=\"hello\"} 0 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"tcpabortonclose\",zone_name=\"hello\"} 7 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"tcpabortondata\",zone_name=\"hello\"} 8 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"tcpabortonlinger\",zone_name=\"hello\"} 0 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"tcpabortonmemory\",zone_name=\"hello\"} 0 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"tcpabortontimeout\",zone_name=\"hello\"} 0 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"tcpbacklogdrop\",zone_name=\"hello\"} 0 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"tcpdeferacceptdrop\",zone_name=\"hello\"} 0 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"tcpdsackignorednoundo\",zone_name=\"hello\"} 71885 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"tcpdsackignoredold\",zone_name=\"hello\"} 0 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"tcpdsackoforecv\",zone_name=\"hello\"} 10 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"tcpdsackofosent\",zone_name=\"hello\"} 1 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"tcpdsackoldsent\",zone_name=\"hello\"} 15633 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"tcpdsackrecv\",zone_name=\"hello\"} 83680 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"tcpdsackundo\",zone_name=\"hello\"} 33 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"tcpfackreorder\",zone_name=\"hello\"} 0 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"tcpfastopenactive\",zone_name=\"hello\"} 0 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"tcpfastopenactivefail\",zone_name=\"hello\"} 0 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"tcpfastopencookiereqd\",zone_name=\"hello\"} 0 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"tcpfastopenlistenoverflow\",zone_name=\"hello\"} 0 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"tcpfastopenpassive\",zone_name=\"hello\"} 0 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"tcpfastopenpassivefail\",zone_name=\"hello\"} 0 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"tcpfastretrans\",zone_name=\"hello\"} 11794 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"tcpfullundo\",zone_name=\"hello\"} 2361 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"tcphpacks\",zone_name=\"hello\"} 2.1490641e+07 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"tcphphits\",zone_name=\"hello\"} 5.6096478e+07 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"tcplossfailures\",zone_name=\"hello\"} 729 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"tcplossproberecovery\",zone_name=\"hello\"} 401 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"tcplossprobes\",zone_name=\"hello\"} 88648 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"tcplossundo\",zone_name=\"hello\"} 61374 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"tcplostretransmit\",zone_name=\"hello\"} 0 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"tcpmd5failure\",zone_name=\"hello\"} 0 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"tcpmd5notfound\",zone_name=\"hello\"} 0 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"tcpmd5unexpected\",zone_name=\"hello\"} 0 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"tcpmemorypressures\",zone_name=\"hello\"} 0 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"tcpmemorypressureschrono\",zone_name=\"hello\"} 0 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"tcpminttldrop\",zone_name=\"hello\"} 0 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"tcporigdatasent\",zone_name=\"hello\"} 1.30698387e+08 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"tcppartialundo\",zone_name=\"hello\"} 3 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"tcppureacks\",zone_name=\"hello\"} 2.4251339e+07 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"tcprcvcollapsed\",zone_name=\"hello\"} 0 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"tcprenofailures\",zone_name=\"hello\"} 43414 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"tcprenorecovery\",zone_name=\"hello\"} 3519 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"tcprenorecoveryfail\",zone_name=\"hello\"} 394 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"tcprenoreorder\",zone_name=\"hello\"} 839 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"tcpreqqfulldocookies\",zone_name=\"hello\"} 0 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"tcpreqqfulldrop\",zone_name=\"hello\"} 0 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"tcpretransfail\",zone_name=\"hello\"} 0 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"tcpsackdiscard\",zone_name=\"hello\"} 0 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"tcpsackfailures\",zone_name=\"hello\"} 60 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"tcpsackmerged\",zone_name=\"hello\"} 6 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"tcpsackrecovery\",zone_name=\"hello\"} 159 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"tcpsackrecoveryfail\",zone_name=\"hello\"} 2 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"tcpsackreneging\",zone_name=\"hello\"} 0 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"tcpsackreorder\",zone_name=\"hello\"} 11 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"tcpsackshifted\",zone_name=\"hello\"} 2 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"tcpsackshiftfallback\",zone_name=\"hello\"} 298 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"tcpslowstartretrans\",zone_name=\"hello\"} 290832 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"tcpspuriousrtos\",zone_name=\"hello\"} 0 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"tcpsynretrans\",zone_name=\"hello\"} 988 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"tcptimeouts\",zone_name=\"hello\"} 27422 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"tcptimewaitoverflow\",zone_name=\"hello\"} 0 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"tcptsreorder\",zone_name=\"hello\"} 3 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"tw\",zone_name=\"hello\"} 1.0436427e+07 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"twkilled\",zone_name=\"hello\"} 0 1395066363000\ncontainer_network_advance_tcp_stats_total{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"twrecycled\",zone_name=\"hello\"} 0 1395066363000\n# HELP container_network_receive_bytes_total Cumulative count of bytes received\n# TYPE container_network_receive_bytes_total counter\ncontainer_network_receive_bytes_total{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",interface=\"eth0\",name=\"testcontaineralias\",zone_name=\"hello\"} 14 1395066363000\n# HELP container_network_receive_errors_total Cumulative count of errors encountered while receiving\n# TYPE container_network_receive_errors_total counter\ncontainer_network_receive_errors_total{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",interface=\"eth0\",name=\"testcontaineralias\",zone_name=\"hello\"} 16 1395066363000\n# HELP container_network_receive_packets_dropped_total Cumulative count of packets dropped while receiving\n# TYPE container_network_receive_packets_dropped_total counter\ncontainer_network_receive_packets_dropped_total{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",interface=\"eth0\",name=\"testcontaineralias\",zone_name=\"hello\"} 17 1395066363000\n# HELP container_network_receive_packets_total Cumulative count of packets received\n# TYPE container_network_receive_packets_total counter\ncontainer_network_receive_packets_total{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",interface=\"eth0\",name=\"testcontaineralias\",zone_name=\"hello\"} 15 1395066363000\n# HELP container_network_tcp6_usage_total tcp6 connection usage statistic for container\n# TYPE container_network_tcp6_usage_total gauge\ncontainer_network_tcp6_usage_total{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"close\",zone_name=\"hello\"} 0 1395066363000\ncontainer_network_tcp6_usage_total{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"closewait\",zone_name=\"hello\"} 0 1395066363000\ncontainer_network_tcp6_usage_total{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"closing\",zone_name=\"hello\"} 0 1395066363000\ncontainer_network_tcp6_usage_total{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"established\",zone_name=\"hello\"} 11 1395066363000\ncontainer_network_tcp6_usage_total{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"finwait1\",zone_name=\"hello\"} 0 1395066363000\ncontainer_network_tcp6_usage_total{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"finwait2\",zone_name=\"hello\"} 0 1395066363000\ncontainer_network_tcp6_usage_total{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"lastack\",zone_name=\"hello\"} 0 1395066363000\ncontainer_network_tcp6_usage_total{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"listen\",zone_name=\"hello\"} 3 1395066363000\ncontainer_network_tcp6_usage_total{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"synrecv\",zone_name=\"hello\"} 0 1395066363000\ncontainer_network_tcp6_usage_total{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"synsent\",zone_name=\"hello\"} 0 1395066363000\ncontainer_network_tcp6_usage_total{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"timewait\",zone_name=\"hello\"} 0 1395066363000\n# HELP container_network_tcp_usage_total tcp connection usage statistic for container\n# TYPE container_network_tcp_usage_total gauge\ncontainer_network_tcp_usage_total{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"close\",zone_name=\"hello\"} 0 1395066363000\ncontainer_network_tcp_usage_total{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"closewait\",zone_name=\"hello\"} 0 1395066363000\ncontainer_network_tcp_usage_total{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"closing\",zone_name=\"hello\"} 0 1395066363000\ncontainer_network_tcp_usage_total{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"established\",zone_name=\"hello\"} 13 1395066363000\ncontainer_network_tcp_usage_total{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"finwait1\",zone_name=\"hello\"} 0 1395066363000\ncontainer_network_tcp_usage_total{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"finwait2\",zone_name=\"hello\"} 0 1395066363000\ncontainer_network_tcp_usage_total{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"lastack\",zone_name=\"hello\"} 0 1395066363000\ncontainer_network_tcp_usage_total{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"listen\",zone_name=\"hello\"} 3 1395066363000\ncontainer_network_tcp_usage_total{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"synrecv\",zone_name=\"hello\"} 0 1395066363000\ncontainer_network_tcp_usage_total{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"synsent\",zone_name=\"hello\"} 0 1395066363000\ncontainer_network_tcp_usage_total{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",tcp_state=\"timewait\",zone_name=\"hello\"} 0 1395066363000\n# HELP container_network_transmit_bytes_total Cumulative count of bytes transmitted\n# TYPE container_network_transmit_bytes_total counter\ncontainer_network_transmit_bytes_total{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",interface=\"eth0\",name=\"testcontaineralias\",zone_name=\"hello\"} 18 1395066363000\n# HELP container_network_transmit_errors_total Cumulative count of errors encountered while transmitting\n# TYPE container_network_transmit_errors_total counter\ncontainer_network_transmit_errors_total{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",interface=\"eth0\",name=\"testcontaineralias\",zone_name=\"hello\"} 20 1395066363000\n# HELP container_network_transmit_packets_dropped_total Cumulative count of packets dropped while transmitting\n# TYPE container_network_transmit_packets_dropped_total counter\ncontainer_network_transmit_packets_dropped_total{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",interface=\"eth0\",name=\"testcontaineralias\",zone_name=\"hello\"} 21 1395066363000\n# HELP container_network_transmit_packets_total Cumulative count of packets transmitted\n# TYPE container_network_transmit_packets_total counter\ncontainer_network_transmit_packets_total{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",interface=\"eth0\",name=\"testcontaineralias\",zone_name=\"hello\"} 19 1395066363000\n# HELP container_network_udp6_usage_total udp6 connection usage statistic for container\n# TYPE container_network_udp6_usage_total gauge\ncontainer_network_udp6_usage_total{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",udp_state=\"dropped\",zone_name=\"hello\"} 0 1395066363000\ncontainer_network_udp6_usage_total{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",udp_state=\"listen\",zone_name=\"hello\"} 0 1395066363000\ncontainer_network_udp6_usage_total{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",udp_state=\"rxqueued\",zone_name=\"hello\"} 0 1395066363000\ncontainer_network_udp6_usage_total{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",udp_state=\"txqueued\",zone_name=\"hello\"} 0 1395066363000\n# HELP container_network_udp_usage_total udp connection usage statistic for container\n# TYPE container_network_udp_usage_total gauge\ncontainer_network_udp_usage_total{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",udp_state=\"dropped\",zone_name=\"hello\"} 0 1395066363000\ncontainer_network_udp_usage_total{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",udp_state=\"listen\",zone_name=\"hello\"} 0 1395066363000\ncontainer_network_udp_usage_total{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",udp_state=\"rxqueued\",zone_name=\"hello\"} 0 1395066363000\ncontainer_network_udp_usage_total{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",udp_state=\"txqueued\",zone_name=\"hello\"} 0 1395066363000\n# HELP container_oom_events_total Count of out of memory events observed for the container\n# TYPE container_oom_events_total counter\ncontainer_oom_events_total{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 0 1395066363000\n# HELP container_perf_events_total Perf event metric.\n# TYPE container_perf_events_total counter\ncontainer_perf_events_total{container_env_foo_env=\"prod\",cpu=\"0\",event=\"instructions\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 123 1395066363000\ncontainer_perf_events_total{container_env_foo_env=\"prod\",cpu=\"0\",event=\"instructions_retired\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 321 1395066363000\ncontainer_perf_events_total{container_env_foo_env=\"prod\",cpu=\"1\",event=\"instructions\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 456 1395066363000\ncontainer_perf_events_total{container_env_foo_env=\"prod\",cpu=\"1\",event=\"instructions_retired\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 789 1395066363000\n# HELP container_perf_events_scaling_ratio Perf event metric scaling ratio.\n# TYPE container_perf_events_scaling_ratio gauge\ncontainer_perf_events_scaling_ratio{container_env_foo_env=\"prod\",cpu=\"0\",event=\"instructions\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 1 1395066363000\ncontainer_perf_events_scaling_ratio{container_env_foo_env=\"prod\",cpu=\"0\",event=\"instructions_retired\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 0.66666666666 1395066363000\ncontainer_perf_events_scaling_ratio{container_env_foo_env=\"prod\",cpu=\"1\",event=\"instructions\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 0.5 1395066363000\ncontainer_perf_events_scaling_ratio{container_env_foo_env=\"prod\",cpu=\"1\",event=\"instructions_retired\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 0.33333333333 1395066363000\n# HELP container_perf_uncore_events_total Perf uncore event metric.\n# TYPE container_perf_uncore_events_total counter\ncontainer_perf_uncore_events_total{container_env_foo_env=\"prod\",event=\"cas_count_read\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",pmu=\"uncore_imc_0\",socket=\"0\",zone_name=\"hello\"} 1.231231512e+09 1395066363000\ncontainer_perf_uncore_events_total{container_env_foo_env=\"prod\",event=\"cas_count_read\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",pmu=\"uncore_imc_0\",socket=\"1\",zone_name=\"hello\"} 1.111231331e+09 1395066363000\n# HELP container_perf_uncore_events_scaling_ratio Perf uncore event metric scaling ratio.\n# TYPE container_perf_uncore_events_scaling_ratio gauge\ncontainer_perf_uncore_events_scaling_ratio{container_env_foo_env=\"prod\",event=\"cas_count_read\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",pmu=\"uncore_imc_0\",socket=\"0\",zone_name=\"hello\"} 1 1395066363000\ncontainer_perf_uncore_events_scaling_ratio{container_env_foo_env=\"prod\",event=\"cas_count_read\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",pmu=\"uncore_imc_0\",socket=\"1\",zone_name=\"hello\"} 1 1395066363000\n# HELP container_pressure_cpu_stalled_seconds_total Total time duration no tasks in the container could make progress due to CPU congestion.\n# TYPE container_pressure_cpu_stalled_seconds_total counter\ncontainer_pressure_cpu_stalled_seconds_total{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 0.0001 1395066363000\n# HELP container_pressure_cpu_waiting_seconds_total Total time duration tasks in the container have waited due to CPU congestion.\n# TYPE container_pressure_cpu_waiting_seconds_total counter\ncontainer_pressure_cpu_waiting_seconds_total{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 0.0002 1395066363000\n# HELP container_pressure_io_stalled_seconds_total Total time duration no tasks in the container could make progress due to IO congestion.\n# TYPE container_pressure_io_stalled_seconds_total counter\ncontainer_pressure_io_stalled_seconds_total{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 0.0011 1395066363000\n# HELP container_pressure_io_waiting_seconds_total Total time duration tasks in the container have waited due to IO congestion.\n# TYPE container_pressure_io_waiting_seconds_total counter\ncontainer_pressure_io_waiting_seconds_total{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 0.0022 1395066363000\n# HELP container_pressure_memory_stalled_seconds_total Total time duration no tasks in the container could make progress due to memory congestion.\n# TYPE container_pressure_memory_stalled_seconds_total counter\ncontainer_pressure_memory_stalled_seconds_total{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 0.001 1395066363000\n# HELP container_pressure_memory_waiting_seconds_total Total time duration tasks in the container have waited due to memory congestion.\n# TYPE container_pressure_memory_waiting_seconds_total counter\ncontainer_pressure_memory_waiting_seconds_total{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 0.002 1395066363000\n# HELP container_processes Number of processes running inside the container.\n# TYPE container_processes gauge\ncontainer_processes{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 1 1395066363000\n# HELP container_referenced_bytes Container referenced bytes during last measurements cycle\n# TYPE container_referenced_bytes gauge\ncontainer_referenced_bytes{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 1234 1395066363000\n# HELP container_scrape_error 1 if there was an error while getting container metrics, 0 otherwise\n# TYPE container_scrape_error gauge\ncontainer_scrape_error 0\n# HELP container_sockets Number of open sockets for the container.\n# TYPE container_sockets gauge\ncontainer_sockets{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 3 1395066363000\n# HELP container_spec_cpu_period CPU period of the container.\n# TYPE container_spec_cpu_period gauge\ncontainer_spec_cpu_period{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 100000\n# HELP container_spec_cpu_quota CPU quota of the container.\n# TYPE container_spec_cpu_quota gauge\ncontainer_spec_cpu_quota{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 10000\n# HELP container_spec_cpu_shares CPU share of the container.\n# TYPE container_spec_cpu_shares gauge\ncontainer_spec_cpu_shares{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 1000\n# HELP container_creation_time_seconds Container creation time since unix epoch in seconds.\n# TYPE container_creation_time_seconds gauge\ncontainer_creation_time_seconds{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 1.257894e+09\n# HELP container_start_time_seconds Start time of the container since unix epoch in seconds.\n# TYPE container_start_time_seconds gauge\ncontainer_start_time_seconds{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 1.257895e+09\n# HELP container_tasks_state Number of tasks in given state\n# TYPE container_tasks_state gauge\ncontainer_tasks_state{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",state=\"iowaiting\",zone_name=\"hello\"} 54 1395066363000\ncontainer_tasks_state{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",state=\"running\",zone_name=\"hello\"} 51 1395066363000\ncontainer_tasks_state{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",state=\"sleeping\",zone_name=\"hello\"} 50 1395066363000\ncontainer_tasks_state{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",state=\"stopped\",zone_name=\"hello\"} 52 1395066363000\ncontainer_tasks_state{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",state=\"uninterruptible\",zone_name=\"hello\"} 53 1395066363000\n# HELP container_threads Number of threads running inside the container\n# TYPE container_threads gauge\ncontainer_threads{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 5 1395066363000\n# HELP container_threads_max Maximum number of threads allowed inside the container, infinity if value is zero\n# TYPE container_threads_max gauge\ncontainer_threads_max{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",zone_name=\"hello\"} 100 1395066363000\n# HELP container_ulimits_soft Soft ulimit values for the container root process. Unlimited if -1, except priority and nice\n# TYPE container_ulimits_soft gauge\ncontainer_ulimits_soft{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",ulimit=\"max_open_files\",zone_name=\"hello\"} 16384 1395066363000\n# HELP container_llc_occupancy_bytes Last level cache usage statistics for container counted with RDT Memory Bandwidth Monitoring (MBM).\n# TYPE container_llc_occupancy_bytes gauge\ncontainer_llc_occupancy_bytes{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",node_id=\"0\",zone_name=\"hello\"} 162626 1395066363000\ncontainer_llc_occupancy_bytes{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",node_id=\"1\",zone_name=\"hello\"} 213777 1395066363000\n# HELP container_memory_bandwidth_bytes Total memory bandwidth usage statistics for container counted with RDT Memory Bandwidth Monitoring (MBM).\n# TYPE container_memory_bandwidth_bytes gauge\ncontainer_memory_bandwidth_bytes{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",node_id=\"0\",zone_name=\"hello\"} 4.512312e+06 1395066363000\ncontainer_memory_bandwidth_bytes{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",node_id=\"1\",zone_name=\"hello\"} 2.173713e+06 1395066363000\n# HELP container_memory_bandwidth_local_bytes Local memory bandwidth usage statistics for container counted with RDT Memory Bandwidth Monitoring (MBM).\n# TYPE container_memory_bandwidth_local_bytes gauge\ncontainer_memory_bandwidth_local_bytes{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",node_id=\"0\",zone_name=\"hello\"} 2.390393e+06 1395066363000\ncontainer_memory_bandwidth_local_bytes{container_env_foo_env=\"prod\",id=\"testcontainer\",image=\"test\",name=\"testcontaineralias\",node_id=\"1\",zone_name=\"hello\"} 1.231233e+06 1395066363000\n"
  },
  {
    "path": "nvm/machine_libipmctl.go",
    "content": "//go:build libipmctl && cgo\n\n// Copyright 2020 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage nvm\n\n// #cgo pkg-config: libipmctl\n// #include <nvm_management.h>\nimport \"C\"\nimport (\n\t\"fmt\"\n\t\"sync\"\n\n\tinfo \"github.com/google/cadvisor/info/v1\"\n\n\t\"k8s.io/klog/v2\"\n)\n\nvar (\n\tisNVMLibInitialized = false\n\tnvmLibMutex         = sync.Mutex{}\n)\n\nfunc init() {\n\tnvmLibMutex.Lock()\n\tdefer nvmLibMutex.Unlock()\n\tcErr := C.nvm_init()\n\tif cErr != C.NVM_SUCCESS {\n\t\t// Unfortunately klog does not seem to work here. I believe it's better to\n\t\t// output information using fmt rather then let it disappear silently.\n\t\tfmt.Printf(\"libipmctl initialization failed with status %d\", cErr)\n\t\treturn\n\t}\n\tisNVMLibInitialized = true\n}\n\n// getAvgPowerBudget retrieves configured power budget\n// (in watts) for NVM devices. When libipmctl is not available\n// zero is returned.\nfunc getAvgPowerBudget() (uint, error) {\n\t// Get number of devices on the platform\n\t// see: https://github.com/intel/ipmctl/blob/v01.00.00.3497/src/os/nvm_api/nvm_management.h#L1478\n\tcount := C.uint(0)\n\terr := C.nvm_get_number_of_devices(&count)\n\tif err != C.NVM_SUCCESS {\n\t\tklog.Warningf(\"Unable to get number of NVM devices. Status code: %d\", err)\n\t\treturn uint(0), fmt.Errorf(\"Unable to get number of NVM devices. Status code: %d\", err)\n\t}\n\n\tif count == 0 {\n\t\tklog.V(4).Infof(\"There are no NVM devices.\")\n\t\treturn uint(0), nil\n\t}\n\n\t// Load basic device information for all the devices\n\t// to obtain UID of the first one.\n\tdevices := make([]C.struct_device_discovery, count)\n\terr = C.nvm_get_devices(&devices[0], C.uchar(count))\n\tif err != C.NVM_SUCCESS {\n\t\tklog.Warningf(\"Unable to get all NVM devices. Status code: %d\", err)\n\t\treturn uint(0), fmt.Errorf(\"Unable to get all NVM devices. Status code: %d\", err)\n\t}\n\n\t// Power budget is same for all the devices\n\t// so we can rely on any of them.\n\tdevice := C.struct_device_details{}\n\terr = C.nvm_get_device_details(&devices[0].uid[0], &device)\n\tif err != C.NVM_SUCCESS {\n\t\tuid := C.GoString(&devices[0].uid[0])\n\t\tklog.Warningf(\"Unable to get details of NVM device %q. Status code: %d\", uid, err)\n\t\treturn uint(0), fmt.Errorf(\"Unable to get details of NVM device %q. Status code: %d\", uid, err)\n\t}\n\n\treturn uint(device.avg_power_budget / 1000), nil\n}\n\n// getCapacities retrieves the total NVM capacity in bytes for memory mode and app direct mode\nfunc getCapacities() (uint64, uint64, error) {\n\tcaps := C.struct_device_capacities{}\n\terr := C.nvm_get_nvm_capacities(&caps)\n\tif err != C.NVM_SUCCESS {\n\t\tklog.Warningf(\"Unable to get NVM capacity. Status code: %d\", err)\n\t\treturn uint64(0), uint64(0), fmt.Errorf(\"Unable to get NVM capacity. Status code: %d\", err)\n\t}\n\treturn uint64(caps.memory_capacity), uint64(caps.app_direct_capacity), nil\n}\n\n// GetInfo returns information specific for non-volatile memory modules\nfunc GetInfo() (info.NVMInfo, error) {\n\tnvmLibMutex.Lock()\n\tdefer nvmLibMutex.Unlock()\n\n\tnvmInfo := info.NVMInfo{}\n\tif !isNVMLibInitialized {\n\t\tklog.V(1).Info(\"libipmctl has not been initialized. NVM information will not be available\")\n\t\treturn nvmInfo, nil\n\t}\n\n\tvar err error\n\tnvmInfo.MemoryModeCapacity, nvmInfo.AppDirectModeCapacity, err = getCapacities()\n\tif err != nil {\n\t\treturn info.NVMInfo{}, fmt.Errorf(\"Unable to get NVM capacities, err: %s\", err)\n\t}\n\n\tnvmInfo.AvgPowerBudget, err = getAvgPowerBudget()\n\tif err != nil {\n\t\treturn info.NVMInfo{}, fmt.Errorf(\"Unable to get NVM average power budget, err: %s\", err)\n\t}\n\treturn nvmInfo, nil\n}\n\n// Finalize un-initializes libipmctl. See https://github.com/google/cadvisor/issues/2457.\nfunc Finalize() {\n\tnvmLibMutex.Lock()\n\tdefer nvmLibMutex.Unlock()\n\n\tklog.V(1).Info(\"Attempting to un-initialize libipmctl\")\n\tif !isNVMLibInitialized {\n\t\tklog.V(1).Info(\"libipmctl has not been initialized; not un-initializing.\")\n\t\treturn\n\t}\n\n\tC.nvm_uninit()\n\tisNVMLibInitialized = false\n}\n"
  },
  {
    "path": "nvm/machine_no_libipmctl.go",
    "content": "//go:build !libipmctl || !cgo\n\n// Copyright 2020 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage nvm\n\nimport (\n\t\"k8s.io/klog/v2\"\n\n\tinfo \"github.com/google/cadvisor/info/v1\"\n)\n\n// GetInfo returns information specific for non-volatile memory modules.\n// When libipmctl is not available zero value is returned.\nfunc GetInfo() (info.NVMInfo, error) {\n\treturn info.NVMInfo{}, nil\n}\n\n// Finalize un-initializes libipmctl. See https://github.com/google/cadvisor/issues/2457.\n// When libipmctl is not available it just logs that it's being called.\nfunc Finalize() {\n\tklog.V(4).Info(\"libipmctl not available, doing nothing.\")\n}\n"
  },
  {
    "path": "perf/collector_libpfm.go",
    "content": "//go:build libpfm && cgo\n\n// Copyright 2020 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n// Collector of perf events for a container.\npackage perf\n\n// #cgo CFLAGS: -I/usr/include\n// #cgo LDFLAGS: -lpfm\n// #include <perfmon/pfmlib.h>\n// #include <stdlib.h>\n// #include <string.h>\nimport \"C\"\n\nimport (\n\t\"bytes\"\n\t\"encoding/binary\"\n\t\"fmt\"\n\t\"os\"\n\t\"sync\"\n\t\"unsafe\"\n\n\t\"golang.org/x/sys/unix\"\n\t\"k8s.io/klog/v2\"\n\n\tinfo \"github.com/google/cadvisor/info/v1\"\n\t\"github.com/google/cadvisor/stats\"\n)\n\ntype collector struct {\n\tcgroupPath         string\n\tevents             PerfEvents\n\tcpuFiles           map[int]group\n\tcpuFilesLock       sync.Mutex\n\tonlineCPUs         []int\n\teventToCustomEvent map[Event]*CustomEvent\n\tuncore             stats.Collector\n\n\t// Handle for mocking purposes.\n\tperfEventOpen func(attr *unix.PerfEventAttr, pid int, cpu int, groupFd int, flags int) (fd int, err error)\n\tioctlSetInt   func(fd int, req uint, value int) error\n}\n\ntype group struct {\n\tcpuFiles   map[string]map[int]readerCloser\n\tnames      []string\n\tleaderName string\n}\n\nvar (\n\tisLibpfmInitialized = false\n\tlibpfmMutex         = sync.Mutex{}\n)\n\nconst (\n\tgroupLeaderFileDescriptor = -1\n)\n\nfunc init() {\n\tlibpfmMutex.Lock()\n\tdefer libpfmMutex.Unlock()\n\tpErr := C.pfm_initialize()\n\tif pErr != C.PFM_SUCCESS {\n\t\tklog.Errorf(\"unable to initialize libpfm: %d\", int(pErr))\n\t\treturn\n\t}\n\tisLibpfmInitialized = true\n}\n\nfunc newCollector(cgroupPath string, events PerfEvents, onlineCPUs []int, cpuToSocket map[int]int) *collector {\n\tcollector := &collector{cgroupPath: cgroupPath, events: events, onlineCPUs: onlineCPUs, cpuFiles: map[int]group{}, uncore: NewUncoreCollector(cgroupPath, events, cpuToSocket), perfEventOpen: unix.PerfEventOpen, ioctlSetInt: unix.IoctlSetInt}\n\tmapEventsToCustomEvents(collector)\n\treturn collector\n}\n\nfunc (c *collector) UpdateStats(stats *info.ContainerStats) error {\n\terr := c.uncore.UpdateStats(stats)\n\tif err != nil {\n\t\tklog.Errorf(\"Failed to get uncore perf event stats: %v\", err)\n\t}\n\n\tc.cpuFilesLock.Lock()\n\tdefer c.cpuFilesLock.Unlock()\n\n\tstats.PerfStats = []info.PerfStat{}\n\tklog.V(5).Infof(\"Attempting to update perf_event stats from cgroup %q\", c.cgroupPath)\n\n\tfor _, group := range c.cpuFiles {\n\t\tfor cpu, file := range group.cpuFiles[group.leaderName] {\n\t\t\tstat, err := readGroupPerfStat(file, group, cpu, c.cgroupPath)\n\t\t\tif err != nil {\n\t\t\t\tklog.Warningf(\"Unable to read from perf_event_file (event: %q, CPU: %d) for %q: %q\", group.leaderName, cpu, c.cgroupPath, err.Error())\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tstats.PerfStats = append(stats.PerfStats, stat...)\n\t\t}\n\t}\n\n\treturn nil\n}\n\nfunc readGroupPerfStat(file readerCloser, group group, cpu int, cgroupPath string) ([]info.PerfStat, error) {\n\tvalues, err := getPerfValues(file, group)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tperfStats := make([]info.PerfStat, len(values))\n\tfor i, value := range values {\n\t\tklog.V(5).Infof(\"Read metric for event %q for cpu %d from cgroup %q: %d\", value.Name, cpu, cgroupPath, value.Value)\n\t\tperfStats[i] = info.PerfStat{\n\t\t\tPerfValue: value,\n\t\t\tCpu:       cpu,\n\t\t}\n\t}\n\n\treturn perfStats, nil\n}\n\nfunc getPerfValues(file readerCloser, group group) ([]info.PerfValue, error) {\n\t// 24 bytes of GroupReadFormat struct.\n\t// 16 bytes of Values struct for each element in group.\n\t// See https://man7.org/linux/man-pages/man2/perf_event_open.2.html section \"Reading results\" with PERF_FORMAT_GROUP specified.\n\tbuf := make([]byte, 24+16*len(group.names))\n\t_, err := file.Read(buf)\n\tif err != nil {\n\t\treturn []info.PerfValue{}, fmt.Errorf(\"unable to read perf event group ( leader = %s ): %w\", group.leaderName, err)\n\t}\n\tperfData := &GroupReadFormat{}\n\treader := bytes.NewReader(buf[:24])\n\terr = binary.Read(reader, binary.LittleEndian, perfData)\n\tif err != nil {\n\t\treturn []info.PerfValue{}, fmt.Errorf(\"unable to decode perf event group ( leader = %s ): %w\", group.leaderName, err)\n\t}\n\tvalues := make([]Values, perfData.Nr)\n\treader = bytes.NewReader(buf[24:])\n\terr = binary.Read(reader, binary.LittleEndian, values)\n\tif err != nil {\n\t\treturn []info.PerfValue{}, fmt.Errorf(\"unable to decode perf event group values ( leader = %s ): %w\", group.leaderName, err)\n\t}\n\n\tscalingRatio := 1.0\n\tif perfData.TimeRunning != 0 && perfData.TimeEnabled != 0 {\n\t\tscalingRatio = float64(perfData.TimeRunning) / float64(perfData.TimeEnabled)\n\t}\n\n\tperfValues := make([]info.PerfValue, perfData.Nr)\n\tif scalingRatio != float64(0) {\n\t\tfor i, name := range group.names {\n\t\t\tperfValues[i] = info.PerfValue{\n\t\t\t\tScalingRatio: scalingRatio,\n\t\t\t\tValue:        uint64(float64(values[i].Value) / scalingRatio),\n\t\t\t\tName:         name,\n\t\t\t}\n\t\t}\n\t} else {\n\t\tfor i, name := range group.names {\n\t\t\tperfValues[i] = info.PerfValue{\n\t\t\t\tScalingRatio: scalingRatio,\n\t\t\t\tValue:        values[i].Value,\n\t\t\t\tName:         name,\n\t\t\t}\n\t\t}\n\t}\n\n\treturn perfValues, nil\n}\n\nfunc (c *collector) setup() error {\n\tcgroup, err := os.Open(c.cgroupPath)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"unable to open cgroup directory %s: %s\", c.cgroupPath, err)\n\t}\n\tdefer cgroup.Close()\n\n\tc.cpuFilesLock.Lock()\n\tdefer c.cpuFilesLock.Unlock()\n\tcgroupFd := int(cgroup.Fd())\n\tgroupIndex := 0\n\tfor _, group := range c.events.Core.Events {\n\t\t// CPUs file descriptors of group leader needed for perf_event_open.\n\t\tleaderFileDescriptors := make(map[int]int, len(c.onlineCPUs))\n\t\tfor _, cpu := range c.onlineCPUs {\n\t\t\tleaderFileDescriptors[cpu] = groupLeaderFileDescriptor\n\t\t}\n\n\t\tleaderFileDescriptors, err := c.createLeaderFileDescriptors(group.events, cgroupFd, groupIndex, leaderFileDescriptors)\n\t\tif err != nil {\n\t\t\tklog.Errorf(\"Cannot count perf event group %v: %v\", group.events, err)\n\t\t\tc.deleteGroup(groupIndex)\n\t\t\tcontinue\n\t\t} else {\n\t\t\tgroupIndex++\n\t\t}\n\n\t\t// Group is prepared so we should reset and enable counting.\n\t\tfor _, fd := range leaderFileDescriptors {\n\t\t\terr = c.ioctlSetInt(fd, unix.PERF_EVENT_IOC_RESET, 0)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\terr = c.ioctlSetInt(fd, unix.PERF_EVENT_IOC_ENABLE, 0)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\t}\n\n\treturn nil\n}\n\nfunc (c *collector) createLeaderFileDescriptors(events []Event, cgroupFd int, groupIndex int, leaderFileDescriptors map[int]int) (map[int]int, error) {\n\tfor j, event := range events {\n\t\t// First element is group leader.\n\t\tisGroupLeader := j == 0\n\t\tcustomEvent, ok := c.eventToCustomEvent[event]\n\t\tvar err error\n\t\tif ok {\n\t\t\tconfig := c.createConfigFromRawEvent(customEvent)\n\t\t\tleaderFileDescriptors, err = c.registerEvent(eventInfo{string(customEvent.Name), config, cgroupFd, groupIndex, isGroupLeader}, leaderFileDescriptors)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, fmt.Errorf(\"cannot register perf event: %v\", err)\n\t\t\t}\n\t\t} else {\n\t\t\tconfig, err := c.createConfigFromEvent(event)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, fmt.Errorf(\"cannot create config from perf event: %v\", err)\n\n\t\t\t}\n\t\t\tleaderFileDescriptors, err = c.registerEvent(eventInfo{string(event), config, cgroupFd, groupIndex, isGroupLeader}, leaderFileDescriptors)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, fmt.Errorf(\"cannot register perf event: %v\", err)\n\t\t\t}\n\t\t\t// Clean memory allocated by C code.\n\t\t\tC.free(unsafe.Pointer(config))\n\t\t}\n\t}\n\treturn leaderFileDescriptors, nil\n}\n\nfunc readPerfEventAttr(name string, pfmGetOsEventEncoding func(string, unsafe.Pointer) error) (*unix.PerfEventAttr, error) {\n\tperfEventAttrMemory := C.malloc(C.size_t(unsafe.Sizeof(unix.PerfEventAttr{})))\n\t// Fill memory with 0 values.\n\tC.memset(perfEventAttrMemory, 0, C.size_t(unsafe.Sizeof(unix.PerfEventAttr{})))\n\terr := pfmGetOsEventEncoding(name, unsafe.Pointer(perfEventAttrMemory))\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn (*unix.PerfEventAttr)(perfEventAttrMemory), nil\n}\n\nfunc pfmGetOsEventEncoding(name string, perfEventAttrMemory unsafe.Pointer) error {\n\tevent := pfmPerfEncodeArgT{}\n\tfstr := C.CString(\"\")\n\tdefer C.free(unsafe.Pointer(fstr))\n\tevent.fstr = unsafe.Pointer(fstr)\n\tevent.attr = perfEventAttrMemory\n\tevent.size = C.size_t(unsafe.Sizeof(event))\n\tcSafeName := C.CString(name)\n\tdefer C.free(unsafe.Pointer(cSafeName))\n\tpErr := C.pfm_get_os_event_encoding(cSafeName, C.PFM_PLM0|C.PFM_PLM3, C.PFM_OS_PERF_EVENT, unsafe.Pointer(&event))\n\tif pErr != C.PFM_SUCCESS {\n\t\treturn fmt.Errorf(\"unable to transform event name %s to perf_event_attr: %d\", name, int(pErr))\n\t}\n\treturn nil\n}\n\ntype eventInfo struct {\n\tname          string\n\tconfig        *unix.PerfEventAttr\n\tpid           int\n\tgroupIndex    int\n\tisGroupLeader bool\n}\n\nfunc (c *collector) registerEvent(event eventInfo, leaderFileDescriptors map[int]int) (map[int]int, error) {\n\tnewLeaderFileDescriptors := make(map[int]int, len(c.onlineCPUs))\n\tvar pid, flags int\n\tif event.isGroupLeader {\n\t\tpid = event.pid\n\t\tflags = unix.PERF_FLAG_FD_CLOEXEC | unix.PERF_FLAG_PID_CGROUP\n\t} else {\n\t\tpid = -1\n\t\tflags = unix.PERF_FLAG_FD_CLOEXEC\n\t}\n\n\tsetAttributes(event.config, event.isGroupLeader)\n\n\tfor _, cpu := range c.onlineCPUs {\n\t\tfd, err := c.perfEventOpen(event.config, pid, cpu, leaderFileDescriptors[cpu], flags)\n\t\tif err != nil {\n\t\t\treturn leaderFileDescriptors, fmt.Errorf(\"setting up perf event %#v failed: %q\", event.config, err)\n\t\t}\n\t\tperfFile := os.NewFile(uintptr(fd), event.name)\n\t\tif perfFile == nil {\n\t\t\treturn leaderFileDescriptors, fmt.Errorf(\"unable to create os.File from file descriptor %#v\", fd)\n\t\t}\n\n\t\tc.addEventFile(event.groupIndex, event.name, cpu, perfFile)\n\n\t\t// If group leader, save fd for others.\n\t\tif event.isGroupLeader {\n\t\t\tnewLeaderFileDescriptors[cpu] = fd\n\t\t}\n\t}\n\n\tif event.isGroupLeader {\n\t\treturn newLeaderFileDescriptors, nil\n\t}\n\treturn leaderFileDescriptors, nil\n}\n\nfunc (c *collector) addEventFile(index int, name string, cpu int, perfFile *os.File) {\n\t_, ok := c.cpuFiles[index]\n\tif !ok {\n\t\tc.cpuFiles[index] = group{\n\t\t\tleaderName: name,\n\t\t\tcpuFiles:   map[string]map[int]readerCloser{},\n\t\t}\n\t}\n\n\t_, ok = c.cpuFiles[index].cpuFiles[name]\n\tif !ok {\n\t\tc.cpuFiles[index].cpuFiles[name] = map[int]readerCloser{}\n\t}\n\n\tc.cpuFiles[index].cpuFiles[name][cpu] = perfFile\n\n\t// Check if name is already stored.\n\tfor _, have := range c.cpuFiles[index].names {\n\t\tif name == have {\n\t\t\treturn\n\t\t}\n\t}\n\n\t// Otherwise save it.\n\tc.cpuFiles[index] = group{\n\t\tcpuFiles:   c.cpuFiles[index].cpuFiles,\n\t\tnames:      append(c.cpuFiles[index].names, name),\n\t\tleaderName: c.cpuFiles[index].leaderName,\n\t}\n}\n\nfunc (c *collector) deleteGroup(index int) {\n\tfor name, files := range c.cpuFiles[index].cpuFiles {\n\t\tfor cpu, file := range files {\n\t\t\tklog.V(5).Infof(\"Closing perf event file descriptor for cgroup %q, event %q and CPU %d\", c.cgroupPath, name, cpu)\n\t\t\terr := file.Close()\n\t\t\tif err != nil {\n\t\t\t\tklog.Warningf(\"Unable to close perf event file descriptor for cgroup %q, event %q and CPU %d\", c.cgroupPath, name, cpu)\n\t\t\t}\n\t\t}\n\t}\n\tdelete(c.cpuFiles, index)\n}\n\nfunc createPerfEventAttr(event CustomEvent) *unix.PerfEventAttr {\n\tlength := len(event.Config)\n\n\tconfig := &unix.PerfEventAttr{\n\t\tType:   event.Type,\n\t\tConfig: event.Config[0],\n\t}\n\tif length >= 2 {\n\t\tconfig.Ext1 = event.Config[1]\n\t}\n\tif length == 3 {\n\t\tconfig.Ext2 = event.Config[2]\n\t}\n\n\tklog.V(5).Infof(\"perf_event_attr struct prepared: %#v\", config)\n\treturn config\n}\n\nfunc setAttributes(config *unix.PerfEventAttr, leader bool) {\n\tconfig.Sample_type = unix.PERF_SAMPLE_IDENTIFIER\n\tconfig.Read_format = unix.PERF_FORMAT_TOTAL_TIME_ENABLED | unix.PERF_FORMAT_TOTAL_TIME_RUNNING | unix.PERF_FORMAT_GROUP | unix.PERF_FORMAT_ID\n\tconfig.Bits = unix.PerfBitInherit\n\n\t// Group leader should have this flag set to disable counting until all group would be prepared.\n\tif leader {\n\t\tconfig.Bits |= unix.PerfBitDisabled\n\t}\n\n\tconfig.Size = uint32(unsafe.Sizeof(unix.PerfEventAttr{}))\n}\n\nfunc (c *collector) Destroy() {\n\tc.uncore.Destroy()\n\tc.cpuFilesLock.Lock()\n\tdefer c.cpuFilesLock.Unlock()\n\n\tfor i := range c.cpuFiles {\n\t\tc.deleteGroup(i)\n\t}\n}\n\n// Finalize terminates libpfm4 to free resources.\nfunc Finalize() {\n\tlibpfmMutex.Lock()\n\tdefer libpfmMutex.Unlock()\n\n\tklog.V(1).Info(\"Attempting to terminate libpfm4\")\n\tif !isLibpfmInitialized {\n\t\tklog.V(1).Info(\"libpfm4 has not been initialized; not terminating.\")\n\t\treturn\n\t}\n\n\tC.pfm_terminate()\n\tisLibpfmInitialized = false\n}\n\nfunc mapEventsToCustomEvents(collector *collector) {\n\tcollector.eventToCustomEvent = map[Event]*CustomEvent{}\n\tfor key, event := range collector.events.Core.CustomEvents {\n\t\tcollector.eventToCustomEvent[event.Name] = &collector.events.Core.CustomEvents[key]\n\t}\n}\n\nfunc (c *collector) createConfigFromRawEvent(event *CustomEvent) *unix.PerfEventAttr {\n\tklog.V(5).Infof(\"Setting up raw perf event %#v\", event)\n\n\tconfig := createPerfEventAttr(*event)\n\n\tklog.V(5).Infof(\"perf_event_attr: %#v\", config)\n\n\treturn config\n}\n\nfunc (c *collector) createConfigFromEvent(event Event) (*unix.PerfEventAttr, error) {\n\tklog.V(5).Infof(\"Setting up perf event %s\", string(event))\n\n\tconfig, err := readPerfEventAttr(string(event), pfmGetOsEventEncoding)\n\tif err != nil {\n\t\tC.free((unsafe.Pointer)(config))\n\t\treturn nil, err\n\t}\n\n\tklog.V(5).Infof(\"perf_event_attr: %#v\", config)\n\n\treturn config, nil\n}\n"
  },
  {
    "path": "perf/collector_libpfm_test.go",
    "content": "//go:build libpfm && cgo\n\n// Copyright 2020 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n// Collector of perf events for a container.\npackage perf\n\nimport (\n\t\"bytes\"\n\t\"encoding/binary\"\n\t\"os\"\n\t\"testing\"\n\t\"unsafe\"\n\n\t\"golang.org/x/sys/unix\"\n\n\t\"github.com/stretchr/testify/assert\"\n\n\tinfo \"github.com/google/cadvisor/info/v1\"\n\t\"github.com/google/cadvisor/stats\"\n)\n\ntype buffer struct {\n\t*bytes.Buffer\n}\n\nfunc (b buffer) Close() error {\n\treturn nil\n}\n\nfunc TestCollector_UpdateStats(t *testing.T) {\n\tcollector := collector{uncore: &stats.NoopCollector{}}\n\tnotScaledBuffer := buffer{bytes.NewBuffer([]byte{})}\n\tscaledBuffer := buffer{bytes.NewBuffer([]byte{})}\n\tgroupedBuffer := buffer{bytes.NewBuffer([]byte{})}\n\terr := binary.Write(notScaledBuffer, binary.LittleEndian, GroupReadFormat{\n\t\tNr:          1,\n\t\tTimeEnabled: 100,\n\t\tTimeRunning: 100,\n\t})\n\tassert.NoError(t, err)\n\terr = binary.Write(notScaledBuffer, binary.LittleEndian, Values{\n\t\tValue: 123456789,\n\t\tID:    0,\n\t})\n\tassert.NoError(t, err)\n\terr = binary.Write(scaledBuffer, binary.LittleEndian, GroupReadFormat{\n\t\tNr:          1,\n\t\tTimeEnabled: 3,\n\t\tTimeRunning: 1,\n\t})\n\tassert.NoError(t, err)\n\terr = binary.Write(scaledBuffer, binary.LittleEndian, Values{\n\t\tValue: 333333333,\n\t\tID:    2,\n\t})\n\tassert.NoError(t, err)\n\terr = binary.Write(groupedBuffer, binary.LittleEndian, GroupReadFormat{\n\t\tNr:          2,\n\t\tTimeEnabled: 100,\n\t\tTimeRunning: 100,\n\t})\n\tassert.NoError(t, err)\n\terr = binary.Write(groupedBuffer, binary.LittleEndian, Values{\n\t\tValue: 123456,\n\t\tID:    0,\n\t})\n\tassert.NoError(t, err)\n\terr = binary.Write(groupedBuffer, binary.LittleEndian, Values{\n\t\tValue: 654321,\n\t\tID:    1,\n\t})\n\tassert.NoError(t, err)\n\n\tcollector.cpuFiles = map[int]group{\n\t\t1: {\n\t\t\tcpuFiles: map[string]map[int]readerCloser{\n\t\t\t\t\"instructions\": {0: notScaledBuffer},\n\t\t\t},\n\t\t\tnames:      []string{\"instructions\"},\n\t\t\tleaderName: \"instructions\",\n\t\t},\n\t\t2: {\n\t\t\tcpuFiles: map[string]map[int]readerCloser{\n\t\t\t\t\"cycles\": {11: scaledBuffer},\n\t\t\t},\n\t\t\tnames:      []string{\"cycles\"},\n\t\t\tleaderName: \"cycles\",\n\t\t},\n\t\t3: {\n\t\t\tcpuFiles: map[string]map[int]readerCloser{\n\t\t\t\t\"cache-misses\": {\n\t\t\t\t\t0: groupedBuffer,\n\t\t\t\t},\n\t\t\t},\n\t\t\tnames:      []string{\"cache-misses\", \"cache-references\"},\n\t\t\tleaderName: \"cache-misses\",\n\t\t},\n\t}\n\n\tstats := &info.ContainerStats{}\n\terr = collector.UpdateStats(stats)\n\n\tassert.NoError(t, err)\n\tassert.Len(t, stats.PerfStats, 4)\n\n\tassert.Contains(t, stats.PerfStats, info.PerfStat{\n\t\tPerfValue: info.PerfValue{\n\t\t\tScalingRatio: 0.3333333333333333,\n\t\t\tValue:        999999999,\n\t\t\tName:         \"cycles\",\n\t\t},\n\t\tCpu: 11,\n\t})\n\tassert.Contains(t, stats.PerfStats, info.PerfStat{\n\t\tPerfValue: info.PerfValue{\n\t\t\tScalingRatio: 1,\n\t\t\tValue:        123456789,\n\t\t\tName:         \"instructions\",\n\t\t},\n\t\tCpu: 0,\n\t})\n\tassert.Contains(t, stats.PerfStats, info.PerfStat{\n\t\tPerfValue: info.PerfValue{\n\t\t\tScalingRatio: 1.0,\n\t\t\tValue:        123456,\n\t\t\tName:         \"cache-misses\",\n\t\t},\n\t\tCpu: 0,\n\t})\n\tassert.Contains(t, stats.PerfStats, info.PerfStat{\n\t\tPerfValue: info.PerfValue{\n\t\t\tScalingRatio: 1.0,\n\t\t\tValue:        654321,\n\t\t\tName:         \"cache-references\",\n\t\t},\n\t\tCpu: 0,\n\t})\n}\n\nfunc TestCreatePerfEventAttr(t *testing.T) {\n\tevent := CustomEvent{\n\t\tType:   0x1,\n\t\tConfig: Config{uint64(0x2), uint64(0x3), uint64(0x4)},\n\t\tName:   \"fake_event\",\n\t}\n\n\tattributes := createPerfEventAttr(event)\n\n\tassert.Equal(t, uint32(1), attributes.Type)\n\tassert.Equal(t, uint64(2), attributes.Config)\n\tassert.Equal(t, uint64(3), attributes.Ext1)\n\tassert.Equal(t, uint64(4), attributes.Ext2)\n}\n\nfunc TestSetGroupAttributes(t *testing.T) {\n\tevent := CustomEvent{\n\t\tType:   0x1,\n\t\tConfig: Config{uint64(0x2), uint64(0x3), uint64(0x4)},\n\t\tName:   \"fake_event\",\n\t}\n\n\tattributes := createPerfEventAttr(event)\n\tsetAttributes(attributes, true)\n\tassert.Equal(t, uint64(65536), attributes.Sample_type)\n\tassert.Equal(t, uint64(0xf), attributes.Read_format)\n\tassert.Equal(t, uint64(0x3), attributes.Bits)\n\n\tattributes = createPerfEventAttr(event)\n\tsetAttributes(attributes, false)\n\tassert.Equal(t, uint64(65536), attributes.Sample_type)\n\tassert.Equal(t, uint64(0xf), attributes.Read_format)\n\tassert.Equal(t, uint64(0x2), attributes.Bits)\n}\n\nfunc TestNewCollector(t *testing.T) {\n\tperfCollector := newCollector(\"cgroup\", PerfEvents{\n\t\tCore: Events{\n\t\t\tEvents: []Group{{[]Event{\"event_1\"}, false}, {[]Event{\"event_2\"}, false}},\n\t\t\tCustomEvents: []CustomEvent{{\n\t\t\t\tType:   0,\n\t\t\t\tConfig: []uint64{1, 2, 3},\n\t\t\t\tName:   \"event_2\",\n\t\t\t}},\n\t\t},\n\t}, []int{0, 1, 2, 3}, map[int]int{})\n\tassert.Len(t, perfCollector.eventToCustomEvent, 1)\n\tassert.Nil(t, perfCollector.eventToCustomEvent[Event(\"event_1\")])\n\tassert.Same(t, &perfCollector.events.Core.CustomEvents[0], perfCollector.eventToCustomEvent[Event(\"event_2\")])\n}\n\nfunc TestCollectorSetup(t *testing.T) {\n\tpath, err := os.MkdirTemp(\"\", \"cgroup\")\n\tassert.Nil(t, err)\n\tdefer func() {\n\t\terr := os.RemoveAll(path)\n\t\tassert.Nil(t, err)\n\t}()\n\tevents := PerfEvents{\n\t\tCore: Events{\n\t\t\tEvents: []Group{\n\t\t\t\t{[]Event{\"cache-misses\"}, false},\n\t\t\t\t{[]Event{\"non-existing-event\"}, false},\n\t\t\t},\n\t\t},\n\t}\n\tc := newCollector(path, events, []int{0}, map[int]int{0: 0})\n\tc.perfEventOpen = func(attr *unix.PerfEventAttr, pid int, cpu int, groupFd int, flags int) (fd int, err error) {\n\t\treturn int(attr.Config), nil\n\t}\n\tc.ioctlSetInt = func(fd int, req uint, value int) error {\n\t\treturn nil\n\t}\n\terr = c.setup()\n\tassert.Nil(t, err)\n\tassert.Equal(t, 1, len(c.cpuFiles))\n\tassert.Equal(t, []string{\"cache-misses\"}, c.cpuFiles[0].names)\n}\n\nvar readGroupPerfStatCases = []struct {\n\ttest       string\n\tfile       GroupReadFormat\n\tvaluesFile Values\n\tname       string\n\tcpu        int\n\tperfStat   []info.PerfStat\n\terr        error\n}{\n\t{\n\t\ttest: \"no scaling\",\n\t\tfile: GroupReadFormat{\n\t\t\tTimeEnabled: 0,\n\t\t\tTimeRunning: 0,\n\t\t\tNr:          1,\n\t\t},\n\t\tvaluesFile: Values{\n\t\t\tValue: 5,\n\t\t\tID:    0,\n\t\t},\n\t\tname: \"some metric\",\n\t\tcpu:  1,\n\t\tperfStat: []info.PerfStat{{\n\t\t\tPerfValue: info.PerfValue{\n\t\t\t\tScalingRatio: 1,\n\t\t\t\tValue:        5,\n\t\t\t\tName:         \"some metric\",\n\t\t\t},\n\t\t\tCpu: 1,\n\t\t}},\n\t\terr: nil,\n\t},\n\t{\n\t\ttest: \"no scaling - TimeEnabled = 0\",\n\t\tfile: GroupReadFormat{\n\t\t\tTimeEnabled: 0,\n\t\t\tTimeRunning: 1,\n\t\t\tNr:          1,\n\t\t},\n\t\tvaluesFile: Values{\n\t\t\tValue: 5,\n\t\t\tID:    0,\n\t\t},\n\t\tname: \"some metric\",\n\t\tcpu:  1,\n\t\tperfStat: []info.PerfStat{{\n\t\t\tPerfValue: info.PerfValue{\n\t\t\t\tScalingRatio: 1,\n\t\t\t\tValue:        5,\n\t\t\t\tName:         \"some metric\",\n\t\t\t},\n\t\t\tCpu: 1,\n\t\t}},\n\t\terr: nil,\n\t},\n\t{\n\t\ttest: \"scaling - 0.5\",\n\t\tfile: GroupReadFormat{\n\t\t\tTimeEnabled: 4,\n\t\t\tTimeRunning: 2,\n\t\t\tNr:          1,\n\t\t},\n\t\tvaluesFile: Values{\n\t\t\tValue: 4,\n\t\t\tID:    0,\n\t\t},\n\t\tname: \"some metric\",\n\t\tcpu:  2,\n\t\tperfStat: []info.PerfStat{{\n\t\t\tPerfValue: info.PerfValue{\n\t\t\t\tScalingRatio: 0.5,\n\t\t\t\tValue:        8,\n\t\t\t\tName:         \"some metric\",\n\t\t\t},\n\t\t\tCpu: 2,\n\t\t}},\n\t\terr: nil,\n\t},\n\t{\n\t\ttest: \"scaling - 0 (TimeEnabled = 1, TimeRunning = 0)\",\n\t\tfile: GroupReadFormat{\n\t\t\tTimeEnabled: 1,\n\t\t\tTimeRunning: 0,\n\t\t\tNr:          1,\n\t\t},\n\t\tvaluesFile: Values{\n\t\t\tValue: 4,\n\t\t\tID:    0,\n\t\t},\n\t\tname: \"some metric\",\n\t\tcpu:  3,\n\t\tperfStat: []info.PerfStat{{\n\t\t\tPerfValue: info.PerfValue{\n\t\t\t\tScalingRatio: 1.0,\n\t\t\t\tValue:        4,\n\t\t\t\tName:         \"some metric\",\n\t\t\t},\n\t\t\tCpu: 3,\n\t\t}},\n\t\terr: nil,\n\t},\n\t{\n\t\ttest: \"scaling - 0 (TimeEnabled = 0, TimeRunning = 1)\",\n\t\tfile: GroupReadFormat{\n\t\t\tTimeEnabled: 0,\n\t\t\tTimeRunning: 1,\n\t\t\tNr:          1,\n\t\t},\n\t\tvaluesFile: Values{\n\t\t\tValue: 4,\n\t\t\tID:    0,\n\t\t},\n\t\tname: \"some metric\",\n\t\tcpu:  3,\n\t\tperfStat: []info.PerfStat{{\n\t\t\tPerfValue: info.PerfValue{\n\t\t\t\tScalingRatio: 1.0,\n\t\t\t\tValue:        4,\n\t\t\t\tName:         \"some metric\",\n\t\t\t},\n\t\t\tCpu: 3,\n\t\t}},\n\t\terr: nil,\n\t},\n\t{\n\t\ttest: \"zeros, zeros everywhere\",\n\t\tfile: GroupReadFormat{\n\t\t\tTimeEnabled: 0,\n\t\t\tTimeRunning: 0,\n\t\t\tNr:          1,\n\t\t},\n\t\tvaluesFile: Values{\n\t\t\tValue: 0,\n\t\t\tID:    0,\n\t\t},\n\t\tname: \"some metric\",\n\t\tcpu:  4,\n\t\tperfStat: []info.PerfStat{{\n\t\t\tPerfValue: info.PerfValue{\n\t\t\t\tScalingRatio: 1.0,\n\t\t\t\tValue:        0,\n\t\t\t\tName:         \"some metric\",\n\t\t\t},\n\t\t\tCpu: 4,\n\t\t}},\n\t\terr: nil,\n\t},\n\t{\n\t\ttest: \"non-zero TimeRunning\",\n\t\tfile: GroupReadFormat{\n\t\t\tTimeEnabled: 0,\n\t\t\tTimeRunning: 3,\n\t\t\tNr:          1,\n\t\t},\n\t\tvaluesFile: Values{\n\t\t\tValue: 0,\n\t\t\tID:    0,\n\t\t},\n\t\tname: \"some metric\",\n\t\tcpu:  4,\n\t\tperfStat: []info.PerfStat{{\n\t\t\tPerfValue: info.PerfValue{\n\t\t\t\tScalingRatio: 1.0,\n\t\t\t\tValue:        0,\n\t\t\t\tName:         \"some metric\",\n\t\t\t},\n\t\t\tCpu: 4,\n\t\t}},\n\t\terr: nil,\n\t},\n}\n\nfunc TestReadPerfStat(t *testing.T) {\n\tfor _, test := range readGroupPerfStatCases {\n\t\tt.Run(test.test, func(tt *testing.T) {\n\t\t\tbuf := &buffer{bytes.NewBuffer([]byte{})}\n\t\t\terr := binary.Write(buf, binary.LittleEndian, test.file)\n\t\t\tassert.NoError(tt, err)\n\t\t\terr = binary.Write(buf, binary.LittleEndian, test.valuesFile)\n\t\t\tassert.NoError(tt, err)\n\t\t\tstat, err := readGroupPerfStat(buf, group{\n\t\t\t\tcpuFiles:   nil,\n\t\t\t\tnames:      []string{test.name},\n\t\t\t\tleaderName: test.name,\n\t\t\t}, test.cpu, \"/\")\n\t\t\tassert.Equal(tt, test.perfStat, stat)\n\t\t\tassert.Equal(tt, test.err, err)\n\t\t})\n\t}\n}\n\nfunc TestReadPerfEventAttr(t *testing.T) {\n\tvar testCases = []struct {\n\t\texpected      *unix.PerfEventAttr\n\t\tpfmMockedFunc func(string, unsafe.Pointer) error\n\t}{\n\t\t{\n\t\t\t&unix.PerfEventAttr{\n\t\t\t\tType:               0,\n\t\t\t\tSize:               0,\n\t\t\t\tConfig:             0,\n\t\t\t\tSample:             0,\n\t\t\t\tSample_type:        0,\n\t\t\t\tRead_format:        0,\n\t\t\t\tBits:               0,\n\t\t\t\tWakeup:             0,\n\t\t\t\tBp_type:            0,\n\t\t\t\tExt1:               0,\n\t\t\t\tExt2:               0,\n\t\t\t\tBranch_sample_type: 0,\n\t\t\t\tSample_regs_user:   0,\n\t\t\t\tSample_stack_user:  0,\n\t\t\t\tClockid:            0,\n\t\t\t\tSample_regs_intr:   0,\n\t\t\t\tAux_watermark:      0,\n\t\t\t\tSample_max_stack:   0,\n\t\t\t},\n\t\t\tfunc(s string, pointer unsafe.Pointer) error {\n\t\t\t\treturn nil\n\t\t\t},\n\t\t},\n\t}\n\n\tfor _, test := range testCases {\n\t\tgot, err := readPerfEventAttr(\"event_name\", test.pfmMockedFunc)\n\t\tassert.NoError(t, err)\n\t\tassert.Equal(t, test.expected, got)\n\t}\n}\n"
  },
  {
    "path": "perf/collector_no_libpfm.go",
    "content": "//go:build !libpfm || !cgo\n\n// Copyright 2020 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n// Collector of perf events for a container.\npackage perf\n\nimport (\n\t\"github.com/google/cadvisor/stats\"\n\n\t\"k8s.io/klog/v2\"\n)\n\nfunc NewCollector(cgroupPath string, events Events, numCores int) stats.Collector {\n\treturn &stats.NoopCollector{}\n}\n\n// Finalize terminates libpfm4 to free resources.\nfunc Finalize() {\n\tklog.V(1).Info(\"cAdvisor is build without cgo and/or libpfm support. Nothing to be finalized\")\n}\n"
  },
  {
    "path": "perf/config.go",
    "content": "// Copyright 2020 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n// Configuration for perf event manager.\npackage perf\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"os\"\n\t\"strconv\"\n\n\t\"k8s.io/klog/v2\"\n)\n\ntype PerfEvents struct {\n\t// Core perf events to be measured.\n\tCore Events `json:\"core,omitempty\"`\n\n\t// Uncore perf events to be measured.\n\tUncore Events `json:\"uncore,omitempty\"`\n}\n\ntype Events struct {\n\t// List of perf events' names to be measured.\n\tEvents []Group `json:\"events\"`\n\n\t// List of custom perf events' to be measured. It is impossible to\n\t// specify some events using their names and in such case you have\n\t// to provide lower level configuration.\n\tCustomEvents []CustomEvent `json:\"custom_events\"`\n}\n\ntype Event string\n\ntype CustomEvent struct {\n\t// Type of the event. See perf_event_attr documentation\n\t// at man perf_event_open.\n\tType uint32 `json:\"type,omitempty\"`\n\n\t// Symbolically formed event like:\n\t// pmu/config=PerfEvent.Config[0],config1=PerfEvent.Config[1],config2=PerfEvent.Config[2]\n\t// as described in man perf-stat.\n\tConfig Config `json:\"config\"`\n\n\t// Human readable name of metric that will be created from the event.\n\tName Event `json:\"name\"`\n}\n\ntype Config []uint64\n\nfunc (c *Config) UnmarshalJSON(b []byte) error {\n\tconfig := []string{}\n\terr := json.Unmarshal(b, &config)\n\tif err != nil {\n\t\tklog.Errorf(\"Unmarshalling %s into slice of strings failed: %q\", b, err)\n\t\treturn fmt.Errorf(\"unmarshalling %s into slice of strings failed: %q\", b, err)\n\t}\n\tintermediate := []uint64{}\n\tfor _, v := range config {\n\t\tuintValue, err := strconv.ParseUint(v, 0, 64)\n\t\tif err != nil {\n\t\t\tklog.Errorf(\"Parsing %#v into uint64 failed: %q\", v, err)\n\t\t\treturn fmt.Errorf(\"parsing %#v into uint64 failed: %q\", v, err)\n\t\t}\n\t\tintermediate = append(intermediate, uintValue)\n\t}\n\t*c = intermediate\n\treturn nil\n}\n\nfunc parseConfig(file *os.File) (events PerfEvents, err error) {\n\tdecoder := json.NewDecoder(file)\n\terr = decoder.Decode(&events)\n\tif err != nil {\n\t\terr = fmt.Errorf(\"unable to load perf events configuration from %q: %q\", file.Name(), err)\n\t\treturn\n\t}\n\treturn\n}\n\ntype Group struct {\n\tevents []Event\n\tarray  bool\n}\n\nfunc (g *Group) UnmarshalJSON(b []byte) error {\n\tvar jsonObj interface{}\n\terr := json.Unmarshal(b, &jsonObj)\n\tif err != nil {\n\t\treturn err\n\t}\n\tswitch obj := jsonObj.(type) {\n\tcase string:\n\t\t*g = Group{\n\t\t\tevents: []Event{Event(obj)},\n\t\t\tarray:  false,\n\t\t}\n\t\treturn nil\n\tcase []interface{}:\n\t\tgroup := Group{\n\t\t\tevents: make([]Event, 0, len(obj)),\n\t\t\tarray:  true,\n\t\t}\n\t\tfor _, v := range obj {\n\t\t\tvalue, ok := v.(string)\n\t\t\tif !ok {\n\t\t\t\treturn fmt.Errorf(\"cannot unmarshal %v\", value)\n\t\t\t}\n\t\t\tgroup.events = append(group.events, Event(value))\n\t\t}\n\t\t*g = group\n\t\treturn nil\n\t}\n\treturn fmt.Errorf(\"unsupported type\")\n}\n"
  },
  {
    "path": "perf/config_test.go",
    "content": "// Copyright 2020 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage perf\n\nimport (\n\t\"os\"\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/assert\"\n)\n\nfunc TestConfigParsing(t *testing.T) {\n\tfile, err := os.Open(\"testing/perf.json\")\n\tassert.Nil(t, err)\n\tdefer file.Close()\n\n\tevents, err := parseConfig(file)\n\n\tassert.Nil(t, err)\n\tassert.Len(t, events.Core.Events, 2)\n\tassert.Len(t, events.Core.Events[0].events, 2)\n\tassert.Equal(t, true, events.Core.Events[0].array)\n\tassert.Equal(t, Event(\"instructions\"), events.Core.Events[0].events[0])\n\tassert.Equal(t, Event(\"instructions_retired\"), events.Core.Events[0].events[1])\n\tassert.Len(t, events.Core.Events[1].events, 1)\n\tassert.Equal(t, false, events.Core.Events[1].array)\n\tassert.Equal(t, Event(\"cycles\"), events.Core.Events[1].events[0])\n\n\tassert.Len(t, events.Uncore.Events, 3)\n\tassert.Equal(t, Event(\"cas_count_write\"), events.Uncore.Events[0].events[0])\n\tassert.Equal(t, Event(\"uncore_imc_0/UNC_M_CAS_COUNT:RD\"), events.Uncore.Events[1].events[0])\n\tassert.Equal(t, Event(\"uncore_ubox/UNC_U_EVENT_MSG\"), events.Uncore.Events[2].events[0])\n\n\tassert.Len(t, events.Uncore.CustomEvents, 1)\n\tassert.Equal(t, Config{0x5300}, events.Uncore.CustomEvents[0].Config)\n\tassert.Equal(t, uint32(0x12), events.Uncore.CustomEvents[0].Type)\n\tassert.Equal(t, Event(\"cas_count_write\"), events.Uncore.CustomEvents[0].Name)\n\n}\n"
  },
  {
    "path": "perf/manager_libpfm.go",
    "content": "//go:build libpfm && cgo\n\n// Copyright 2020 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n// Manager of perf events for containers.\npackage perf\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\n\tinfo \"github.com/google/cadvisor/info/v1\"\n\t\"github.com/google/cadvisor/stats\"\n\t\"github.com/google/cadvisor/utils/sysinfo\"\n)\n\ntype manager struct {\n\tevents      PerfEvents\n\tonlineCPUs  []int\n\tcpuToSocket map[int]int\n\tstats.NoopDestroy\n}\n\nfunc NewManager(configFile string, topology []info.Node) (stats.Manager, error) {\n\tif configFile == \"\" {\n\t\treturn &stats.NoopManager{}, nil\n\t}\n\n\tfile, err := os.Open(configFile)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"unable to read configuration file %q: %w\", configFile, err)\n\t}\n\n\tconfig, err := parseConfig(file)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"unable to parse configuration file %q: %w\", configFile, err)\n\t}\n\n\tif len(config.Core.Events) == 0 && len(config.Uncore.Events) == 0 {\n\t\treturn nil, fmt.Errorf(\"there is no events in config file %q\", configFile)\n\t}\n\n\tonlineCPUs := sysinfo.GetOnlineCPUs(topology)\n\n\tcpuToSocket := make(map[int]int)\n\n\tfor _, cpu := range onlineCPUs {\n\t\tcpuToSocket[cpu] = sysinfo.GetSocketFromCPU(topology, cpu)\n\t}\n\n\treturn &manager{events: config, onlineCPUs: onlineCPUs, cpuToSocket: cpuToSocket}, nil\n}\n\nfunc (m *manager) GetCollector(cgroupPath string) (stats.Collector, error) {\n\tcollector := newCollector(cgroupPath, m.events, m.onlineCPUs, m.cpuToSocket)\n\terr := collector.setup()\n\tif err != nil {\n\t\tcollector.Destroy()\n\t\treturn &stats.NoopCollector{}, err\n\t}\n\treturn collector, nil\n}\n"
  },
  {
    "path": "perf/manager_libpfm_test.go",
    "content": "//go:build libpfm && cgo\n\n// Copyright 2020 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n// Manager of perf events for containers.\npackage perf\n\nimport (\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/assert\"\n\n\tinfo \"github.com/google/cadvisor/info/v1\"\n\t\"github.com/google/cadvisor/stats\"\n)\n\nfunc TestEmptyConfigPassed(t *testing.T) {\n\tmanager, err := NewManager(\"testing/perf-no-events.json\", []info.Node{})\n\n\tassert.NotNil(t, err)\n\tassert.Nil(t, manager)\n}\n\nfunc TestNoConfigFilePassed(t *testing.T) {\n\tmanager, err := NewManager(\"\", []info.Node{})\n\n\tassert.Nil(t, err)\n\t_, ok := manager.(*stats.NoopManager)\n\tassert.True(t, ok)\n}\n\nfunc TestNonExistentFile(t *testing.T) {\n\tmanager, err := NewManager(\"this-file-is-so-non-existent\", []info.Node{})\n\n\tassert.NotNil(t, err)\n\tassert.Nil(t, manager)\n}\n\nfunc TestMalformedJsonFile(t *testing.T) {\n\tmanager, err := NewManager(\"testing/this-is-some-random.json\", []info.Node{})\n\n\tassert.NotNil(t, err)\n\tassert.Nil(t, manager)\n}\n\nfunc TestNewManager(t *testing.T) {\n\tmanagerInstance, err := NewManager(\"testing/perf.json\", []info.Node{})\n\n\tassert.Nil(t, err)\n\t_, ok := managerInstance.(*manager)\n\tassert.True(t, ok)\n}\n"
  },
  {
    "path": "perf/manager_no_libpfm.go",
    "content": "//go:build !libpfm || !cgo\n\n// Copyright 2020 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n// Manager of perf events for containers.\npackage perf\n\nimport (\n\tinfo \"github.com/google/cadvisor/info/v1\"\n\t\"github.com/google/cadvisor/stats\"\n\n\t\"k8s.io/klog/v2\"\n)\n\nfunc NewManager(configFile string, topology []info.Node) (stats.Manager, error) {\n\tklog.V(1).Info(\"cAdvisor is build without cgo and/or libpfm support. Perf event counters are not available.\")\n\treturn &stats.NoopManager{}, nil\n}\n"
  },
  {
    "path": "perf/testing/perf-no-events.json",
    "content": "{\n  \"core\": {\n    \"events\": [],\n    \"custom_events\": []\n  },\n  \"uncore\": {\n    \"events\": [],\n    \"custom_events\": []\n  }\n}\n\n"
  },
  {
    "path": "perf/testing/perf-non-hardware.json",
    "content": "{\n  \"core\": {\n    \"events\": [\n      \"context-switches\",\n      \"cpu-migrations-custom\"\n    ],\n    \"custom_events\": [\n      {\n        \"type\": 1,\n        \"config\": [\n          \"0x4\"\n        ],\n        \"name\": \"cpu-migrations-custom\"\n      }\n    ]\n  }\n}\n"
  },
  {
    "path": "perf/testing/perf.json",
    "content": "{\n  \"core\": {\n    \"events\": [\n      [\"instructions\", \"instructions_retired\"],\n      \"cycles\"\n    ],\n    \"custom_events\": [\n      {\n        \"type\": 4,\n        \"config\": [\n          \"0x5300c0\"\n        ],\n        \"name\": \"instructions_retired\"\n      }\n    ]\n  },\n  \"uncore\": {\n    \"events\": [\n      \"cas_count_write\",\n      \"uncore_imc_0/UNC_M_CAS_COUNT:RD\",\n      \"uncore_ubox/UNC_U_EVENT_MSG\"\n    ],\n    \"custom_events\": [\n      {\n        \"type\": 18,\n        \"config\": [\n          \"0x5300\"\n        ],\n        \"name\": \"cas_count_write\"\n      }\n    ]\n  }\n}\n"
  },
  {
    "path": "perf/testing/this-is-some-random.json",
    "content": "[]"
  },
  {
    "path": "perf/types_libpfm.go",
    "content": "//go:build libpfm && cgo\n\n// Copyright 2020 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n// Types related to handling perf events that are missing from unix package.\npackage perf\n\nimport \"C\"\nimport (\n\t\"io\"\n\t\"unsafe\"\n)\n\n// GroupReadFormat allows to read perf event's values for grouped events.\n// See https://man7.org/linux/man-pages/man2/perf_event_open.2.html section \"Reading results\" with PERF_FORMAT_GROUP specified.\ntype GroupReadFormat struct {\n\tNr          uint64 /* The number of events */\n\tTimeEnabled uint64 /* if PERF_FORMAT_TOTAL_TIME_ENABLED */\n\tTimeRunning uint64 /* if PERF_FORMAT_TOTAL_TIME_RUNNING */\n}\n\ntype Values struct {\n\tValue uint64 /* The value of the event */\n\tID    uint64 /* if PERF_FORMAT_ID */\n}\n\n// pfmPerfEncodeArgT represents structure that is used to parse perf event nam\n// into perf_event_attr using libpfm.\ntype pfmPerfEncodeArgT struct {\n\tattr unsafe.Pointer\n\tfstr unsafe.Pointer\n\tsize C.size_t\n\t_    C.int // idx\n\t_    C.int // cpu\n\t_    C.int // flags\n}\n\ntype readerCloser interface {\n\tio.Reader\n\tio.Closer\n}\n"
  },
  {
    "path": "perf/uncore_libpfm.go",
    "content": "//go:build libpfm && cgo\n\n// Copyright 2020 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n// Uncore perf events logic.\npackage perf\n\n// #cgo CFLAGS: -I/usr/include\n// #cgo LDFLAGS: -lpfm\n// #include <perfmon/pfmlib.h>\n// #include <stdlib.h>\nimport \"C\"\nimport (\n\t\"fmt\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"reflect\"\n\t\"regexp\"\n\t\"strconv\"\n\t\"strings\"\n\t\"sync\"\n\t\"unsafe\"\n\n\t\"golang.org/x/sys/unix\"\n\t\"k8s.io/klog/v2\"\n\n\tinfo \"github.com/google/cadvisor/info/v1\"\n\t\"github.com/google/cadvisor/stats\"\n)\n\ntype pmu struct {\n\tname   string\n\ttypeOf uint32\n\tcpus   []uint32\n}\n\nconst (\n\tuncorePMUPrefix    = \"uncore\"\n\tpmuTypeFilename    = \"type\"\n\tpmuCpumaskFilename = \"cpumask\"\n\tsystemDevicesPath  = \"/sys/devices\"\n\trootPerfEventPath  = \"/sys/fs/cgroup/perf_event\"\n\tuncorePID          = -1\n)\n\nfunc getPMU(pmus uncorePMUs, gotType uint32) (*pmu, error) {\n\tfor _, pmu := range pmus {\n\t\tif pmu.typeOf == gotType {\n\t\t\treturn &pmu, nil\n\t\t}\n\t}\n\n\treturn nil, fmt.Errorf(\"there is no pmu with event type: %#v\", gotType)\n}\n\ntype uncorePMUs map[string]pmu\n\nfunc readUncorePMU(path string, name string, cpumaskRegexp *regexp.Regexp) (*pmu, error) {\n\tbuf, err := os.ReadFile(filepath.Join(path, pmuTypeFilename))\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\ttypeString := strings.TrimSpace(string(buf))\n\teventType, err := strconv.ParseUint(typeString, 0, 32)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tbuf, err = os.ReadFile(filepath.Join(path, pmuCpumaskFilename))\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tvar cpus []uint32\n\tcpumask := strings.TrimSpace(string(buf))\n\tfor _, cpu := range cpumaskRegexp.Split(cpumask, -1) {\n\t\tparsedCPU, err := strconv.ParseUint(cpu, 0, 32)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tcpus = append(cpus, uint32(parsedCPU))\n\t}\n\n\treturn &pmu{name: name, typeOf: uint32(eventType), cpus: cpus}, nil\n}\n\nfunc getUncorePMUs(devicesPath string) (uncorePMUs, error) {\n\tpmus := make(uncorePMUs)\n\n\t// Depends on platform, cpu mask could be for example in form \"0-1\" or \"0,1\".\n\tcpumaskRegexp := regexp.MustCompile(\"[-,\\n]\")\n\terr := filepath.Walk(devicesPath, func(path string, info os.FileInfo, err error) error {\n\t\t// Skip root path.\n\t\tif path == devicesPath {\n\t\t\treturn nil\n\t\t}\n\t\tif info.IsDir() {\n\t\t\tif strings.HasPrefix(info.Name(), uncorePMUPrefix) {\n\t\t\t\tpmu, err := readUncorePMU(path, info.Name(), cpumaskRegexp)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn err\n\t\t\t\t}\n\t\t\t\tpmus[info.Name()] = *pmu\n\t\t\t}\n\t\t}\n\t\treturn nil\n\t})\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn pmus, nil\n}\n\ntype uncoreCollector struct {\n\tcpuFilesLock       sync.Mutex\n\tcpuFiles           map[int]map[string]group\n\tevents             []Group\n\teventToCustomEvent map[Event]*CustomEvent\n\tcpuToSocket        map[int]int\n\n\t// Handle for mocking purposes.\n\tperfEventOpen func(attr *unix.PerfEventAttr, pid int, cpu int, groupFd int, flags int) (fd int, err error)\n\tioctlSetInt   func(fd int, req uint, value int) error\n}\n\nfunc NewUncoreCollector(cgroupPath string, events PerfEvents, cpuToSocket map[int]int) stats.Collector {\n\n\tif cgroupPath != rootPerfEventPath {\n\t\t// Uncore metric doesn't exists for cgroups, only for entire platform.\n\t\treturn &stats.NoopCollector{}\n\t}\n\n\tcollector := &uncoreCollector{\n\t\tcpuToSocket:   cpuToSocket,\n\t\tperfEventOpen: unix.PerfEventOpen,\n\t\tioctlSetInt:   unix.IoctlSetInt,\n\t}\n\n\terr := collector.setup(events, systemDevicesPath)\n\tif err != nil {\n\t\tklog.Errorf(\"Perf uncore metrics will not be available: unable to setup uncore perf event collector: %v\", err)\n\t\treturn &stats.NoopCollector{}\n\t}\n\n\treturn collector\n}\n\nfunc (c *uncoreCollector) createLeaderFileDescriptors(events []Event, groupIndex int, groupPMUs map[Event]uncorePMUs,\n\tleaderFileDescriptors map[string]map[uint32]int) (map[string]map[uint32]int, error) {\n\tvar err error\n\tfor _, event := range events {\n\t\teventName, _ := parseEventName(string(event))\n\t\tcustomEvent, ok := c.eventToCustomEvent[event]\n\t\tif ok {\n\t\t\terr = c.setupRawEvent(customEvent, groupPMUs[event], groupIndex, leaderFileDescriptors)\n\t\t} else {\n\t\t\terr = c.setupEvent(eventName, groupPMUs[event], groupIndex, leaderFileDescriptors)\n\t\t}\n\t\tif err != nil {\n\t\t\tbreak\n\t\t}\n\t}\n\tif err != nil {\n\t\tc.deleteGroup(groupIndex)\n\t\treturn nil, fmt.Errorf(\"cannot create config from perf event: %v\", err)\n\t}\n\treturn leaderFileDescriptors, nil\n}\n\nfunc (c *uncoreCollector) setup(events PerfEvents, devicesPath string) error {\n\treadUncorePMUs, err := getUncorePMUs(devicesPath)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tc.cpuFiles = make(map[int]map[string]group)\n\tc.events = events.Uncore.Events\n\tc.eventToCustomEvent = parseUncoreEvents(events.Uncore)\n\tc.cpuFilesLock.Lock()\n\tdefer c.cpuFilesLock.Unlock()\n\n\tfor i, group := range c.events {\n\t\t// Check what PMUs are needed.\n\t\tgroupPMUs, err := parsePMUs(group, readUncorePMUs, c.eventToCustomEvent)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\terr = checkGroup(group, groupPMUs)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\t// CPUs file descriptors of group leader needed for perf_event_open.\n\t\tleaderFileDescriptors := make(map[string]map[uint32]int)\n\t\tfor _, pmu := range readUncorePMUs {\n\t\t\tleaderFileDescriptors[pmu.name] = make(map[uint32]int)\n\t\t\tfor _, cpu := range pmu.cpus {\n\t\t\t\tleaderFileDescriptors[pmu.name][cpu] = groupLeaderFileDescriptor\n\t\t\t}\n\t\t}\n\t\tleaderFileDescriptors, err = c.createLeaderFileDescriptors(group.events, i, groupPMUs, leaderFileDescriptors)\n\t\tif err != nil {\n\t\t\tklog.Error(err)\n\t\t\tcontinue\n\t\t}\n\t\t// Group is prepared so we should reset and enable counting.\n\t\tfor _, pmuCPUs := range leaderFileDescriptors {\n\t\t\tfor _, fd := range pmuCPUs {\n\t\t\t\t// Call only for used PMUs.\n\t\t\t\tif fd != groupLeaderFileDescriptor {\n\t\t\t\t\terr = c.ioctlSetInt(fd, unix.PERF_EVENT_IOC_RESET, 0)\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\treturn err\n\t\t\t\t\t}\n\t\t\t\t\terr = c.ioctlSetInt(fd, unix.PERF_EVENT_IOC_ENABLE, 0)\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\treturn err\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn nil\n}\n\nfunc checkGroup(group Group, eventPMUs map[Event]uncorePMUs) error {\n\tif group.array {\n\t\tvar pmu uncorePMUs\n\t\tfor _, event := range group.events {\n\t\t\tif len(eventPMUs[event]) > 1 {\n\t\t\t\treturn fmt.Errorf(\"the events in group usually have to be from single PMU, try reorganizing the \\\"%v\\\" group\", group.events)\n\t\t\t}\n\t\t\tif len(eventPMUs[event]) == 1 {\n\t\t\t\tif pmu == nil {\n\t\t\t\t\tpmu = eventPMUs[event]\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\n\t\t\t\teq := reflect.DeepEqual(pmu, eventPMUs[event])\n\t\t\t\tif !eq {\n\t\t\t\t\treturn fmt.Errorf(\"the events in group usually have to be from the same PMU, try reorganizing the \\\"%v\\\" group\", group.events)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn nil\n\t}\n\tif len(eventPMUs[group.events[0]]) < 1 {\n\t\treturn fmt.Errorf(\"the event %q don't have any PMU to count with\", group.events[0])\n\t}\n\treturn nil\n}\n\nfunc parseEventName(eventName string) (string, string) {\n\t// First \"/\" separate pmu prefix and event name\n\t// ex. \"uncore_imc_0/cas_count_read\" -> uncore_imc_0 and cas_count_read.\n\tsplittedEvent := strings.SplitN(eventName, \"/\", 2)\n\tvar pmuPrefix = \"\"\n\tif len(splittedEvent) == 2 {\n\t\tpmuPrefix = splittedEvent[0]\n\t\teventName = splittedEvent[1]\n\t}\n\treturn eventName, pmuPrefix\n}\n\nfunc parsePMUs(group Group, pmus uncorePMUs, customEvents map[Event]*CustomEvent) (map[Event]uncorePMUs, error) {\n\teventPMUs := make(map[Event]uncorePMUs)\n\tfor _, event := range group.events {\n\t\t_, prefix := parseEventName(string(event))\n\t\tcustom, ok := customEvents[event]\n\t\tif ok {\n\t\t\tif custom.Type != 0 {\n\t\t\t\tpmu, err := getPMU(pmus, custom.Type)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn nil, err\n\t\t\t\t}\n\t\t\t\teventPMUs[event] = uncorePMUs{pmu.name: *pmu}\n\t\t\t\tcontinue\n\t\t\t}\n\t\t}\n\t\teventPMUs[event] = obtainPMUs(prefix, pmus)\n\t}\n\n\treturn eventPMUs, nil\n}\n\nfunc obtainPMUs(want string, gotPMUs uncorePMUs) uncorePMUs {\n\tpmus := make(uncorePMUs)\n\tif want == \"\" {\n\t\treturn pmus\n\t}\n\tfor _, pmu := range gotPMUs {\n\t\tif strings.HasPrefix(pmu.name, want) {\n\t\t\tpmus[pmu.name] = pmu\n\t\t}\n\t}\n\n\treturn pmus\n}\n\nfunc parseUncoreEvents(events Events) map[Event]*CustomEvent {\n\teventToCustomEvent := map[Event]*CustomEvent{}\n\tfor _, group := range events.Events {\n\t\tfor _, uncoreEvent := range group.events {\n\t\t\tfor _, customEvent := range events.CustomEvents {\n\t\t\t\tif uncoreEvent == customEvent.Name {\n\t\t\t\t\teventToCustomEvent[customEvent.Name] = &customEvent\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn eventToCustomEvent\n}\n\nfunc (c *uncoreCollector) Destroy() {\n\tc.cpuFilesLock.Lock()\n\tdefer c.cpuFilesLock.Unlock()\n\n\tfor groupIndex := range c.cpuFiles {\n\t\tc.deleteGroup(groupIndex)\n\t\tdelete(c.cpuFiles, groupIndex)\n\t}\n}\n\nfunc (c *uncoreCollector) UpdateStats(stats *info.ContainerStats) error {\n\tklog.V(5).Info(\"Attempting to update uncore perf_event stats\")\n\n\tfor _, groupPMUs := range c.cpuFiles {\n\t\tfor pmu, group := range groupPMUs {\n\t\t\tfor cpu, file := range group.cpuFiles[group.leaderName] {\n\t\t\t\tstat, err := readPerfUncoreStat(file, group, cpu, pmu, c.cpuToSocket)\n\t\t\t\tif err != nil {\n\t\t\t\t\tklog.Warningf(\"Unable to read from perf_event_file (event: %q, CPU: %d) for %q: %q\", group.leaderName, cpu, pmu, err.Error())\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\n\t\t\t\tstats.PerfUncoreStats = append(stats.PerfUncoreStats, stat...)\n\t\t\t}\n\t\t}\n\t}\n\n\treturn nil\n}\n\nfunc (c *uncoreCollector) setupEvent(name string, pmus uncorePMUs, groupIndex int, leaderFileDescriptors map[string]map[uint32]int) error {\n\tif !isLibpfmInitialized {\n\t\treturn fmt.Errorf(\"libpfm4 is not initialized, cannot proceed with setting perf events up\")\n\t}\n\n\tklog.V(5).Infof(\"Setting up uncore perf event %s\", name)\n\n\tconfig, err := readPerfEventAttr(name, pfmGetOsEventEncoding)\n\tif err != nil {\n\t\tC.free((unsafe.Pointer)(config))\n\t\treturn err\n\t}\n\n\t// Register event for all memory controllers.\n\tfor _, pmu := range pmus {\n\t\tconfig.Type = pmu.typeOf\n\t\tisGroupLeader := leaderFileDescriptors[pmu.name][pmu.cpus[0]] == groupLeaderFileDescriptor\n\t\tsetAttributes(config, isGroupLeader)\n\t\tleaderFileDescriptors[pmu.name], err = c.registerEvent(eventInfo{name, config, uncorePID, groupIndex, isGroupLeader}, pmu, leaderFileDescriptors[pmu.name])\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\n\t// Clean memory allocated by C code.\n\tC.free(unsafe.Pointer(config))\n\n\treturn nil\n}\n\nfunc (c *uncoreCollector) registerEvent(eventInfo eventInfo, pmu pmu, leaderFileDescriptors map[uint32]int) (map[uint32]int, error) {\n\tnewLeaderFileDescriptors := make(map[uint32]int)\n\tisGroupLeader := false\n\tfor _, cpu := range pmu.cpus {\n\t\tgroupFd, flags := leaderFileDescriptors[cpu], 0\n\t\tfd, err := c.perfEventOpen(eventInfo.config, eventInfo.pid, int(cpu), groupFd, flags)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"setting up perf event %#v failed: %q | (pmu: %q, groupFd: %d, cpu: %d)\", eventInfo.config, err, pmu, groupFd, cpu)\n\t\t}\n\t\tperfFile := os.NewFile(uintptr(fd), eventInfo.name)\n\t\tif perfFile == nil {\n\t\t\treturn nil, fmt.Errorf(\"unable to create os.File from file descriptor %#v\", fd)\n\t\t}\n\n\t\tc.addEventFile(eventInfo.groupIndex, eventInfo.name, pmu.name, int(cpu), perfFile)\n\n\t\t// If group leader, save fd for others.\n\t\tif leaderFileDescriptors[cpu] == groupLeaderFileDescriptor {\n\t\t\tnewLeaderFileDescriptors[cpu] = fd\n\t\t\tisGroupLeader = true\n\t\t}\n\t}\n\n\tif isGroupLeader {\n\t\treturn newLeaderFileDescriptors, nil\n\t}\n\treturn leaderFileDescriptors, nil\n}\n\nfunc (c *uncoreCollector) addEventFile(index int, name string, pmu string, cpu int, perfFile *os.File) {\n\t_, ok := c.cpuFiles[index]\n\tif !ok {\n\t\tc.cpuFiles[index] = map[string]group{}\n\t}\n\n\t_, ok = c.cpuFiles[index][pmu]\n\tif !ok {\n\t\tc.cpuFiles[index][pmu] = group{\n\t\t\tcpuFiles:   map[string]map[int]readerCloser{},\n\t\t\tleaderName: name,\n\t\t}\n\t}\n\n\t_, ok = c.cpuFiles[index][pmu].cpuFiles[name]\n\tif !ok {\n\t\tc.cpuFiles[index][pmu].cpuFiles[name] = map[int]readerCloser{}\n\t}\n\n\tc.cpuFiles[index][pmu].cpuFiles[name][cpu] = perfFile\n\n\t// Check if name is already stored.\n\tfor _, have := range c.cpuFiles[index][pmu].names {\n\t\tif name == have {\n\t\t\treturn\n\t\t}\n\t}\n\n\t// Otherwise save it.\n\tc.cpuFiles[index][pmu] = group{\n\t\tcpuFiles:   c.cpuFiles[index][pmu].cpuFiles,\n\t\tnames:      append(c.cpuFiles[index][pmu].names, name),\n\t\tleaderName: c.cpuFiles[index][pmu].leaderName,\n\t}\n}\n\nfunc (c *uncoreCollector) setupRawEvent(event *CustomEvent, pmus uncorePMUs, groupIndex int, leaderFileDescriptors map[string]map[uint32]int) error {\n\tklog.V(5).Infof(\"Setting up raw perf uncore event %#v\", event)\n\n\tfor _, pmu := range pmus {\n\t\tnewEvent := CustomEvent{\n\t\t\tType:   pmu.typeOf,\n\t\t\tConfig: event.Config,\n\t\t\tName:   event.Name,\n\t\t}\n\t\tconfig := createPerfEventAttr(newEvent)\n\t\tisGroupLeader := leaderFileDescriptors[pmu.name][pmu.cpus[0]] == groupLeaderFileDescriptor\n\t\tsetAttributes(config, isGroupLeader)\n\t\tvar err error\n\t\tleaderFileDescriptors[pmu.name], err = c.registerEvent(eventInfo{string(newEvent.Name), config, uncorePID, groupIndex, isGroupLeader}, pmu, leaderFileDescriptors[pmu.name])\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\n\treturn nil\n}\n\nfunc (c *uncoreCollector) deleteGroup(groupIndex int) {\n\tgroupPMUs := c.cpuFiles[groupIndex]\n\tfor pmu, group := range groupPMUs {\n\t\tfor name, cpus := range group.cpuFiles {\n\t\t\tfor cpu, file := range cpus {\n\t\t\t\tklog.V(5).Infof(\"Closing uncore perf event file descriptor for event %q, PMU %s and CPU %d\", name, pmu, cpu)\n\t\t\t\terr := file.Close()\n\t\t\t\tif err != nil {\n\t\t\t\t\tklog.Warningf(\"Unable to close perf event file descriptor for event %q, PMU %s and CPU %d\", name, pmu, cpu)\n\t\t\t\t}\n\t\t\t}\n\t\t\tdelete(group.cpuFiles, name)\n\t\t}\n\t\tdelete(groupPMUs, pmu)\n\t}\n\tdelete(c.cpuFiles, groupIndex)\n}\n\nfunc readPerfUncoreStat(file readerCloser, group group, cpu int, pmu string, cpuToSocket map[int]int) ([]info.PerfUncoreStat, error) {\n\tvalues, err := getPerfValues(file, group)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tsocket, ok := cpuToSocket[cpu]\n\tif !ok {\n\t\t// Socket is unknown.\n\t\tsocket = -1\n\t}\n\n\tperfUncoreStats := make([]info.PerfUncoreStat, len(values))\n\tfor i, value := range values {\n\t\tklog.V(5).Infof(\"Read metric for event %q for cpu %d from pmu %q: %d\", value.Name, cpu, pmu, value.Value)\n\t\tperfUncoreStats[i] = info.PerfUncoreStat{\n\t\t\tPerfValue: value,\n\t\t\tSocket:    socket,\n\t\t\tPMU:       pmu,\n\t\t}\n\t}\n\n\treturn perfUncoreStats, nil\n}\n"
  },
  {
    "path": "perf/uncore_libpfm_test.go",
    "content": "//go:build libpfm && cgo\n\n// Copyright 2020 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n// Uncore perf events logic tests.\npackage perf\n\nimport (\n\t\"bytes\"\n\t\"encoding/binary\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"testing\"\n\n\t\"golang.org/x/sys/unix\"\n\n\t\"github.com/stretchr/testify/assert\"\n\n\tv1 \"github.com/google/cadvisor/info/v1\"\n)\n\nfunc mockSystemDevices() (string, error) {\n\ttestDir, err := os.MkdirTemp(\"\", \"uncore_imc_test\")\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\n\t// First Uncore IMC PMU.\n\tfirstPMUPath := filepath.Join(testDir, \"uncore_imc_0\")\n\terr = os.MkdirAll(firstPMUPath, os.ModePerm)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\terr = os.WriteFile(filepath.Join(firstPMUPath, \"cpumask\"), []byte(\"0-1\"), 0777)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\terr = os.WriteFile(filepath.Join(firstPMUPath, \"type\"), []byte(\"18\"), 0777)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\n\t// Second Uncore IMC PMU.\n\tsecondPMUPath := filepath.Join(testDir, \"uncore_imc_1\")\n\terr = os.MkdirAll(secondPMUPath, os.ModePerm)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\terr = os.WriteFile(filepath.Join(secondPMUPath, \"cpumask\"), []byte(\"0,1\"), 0777)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\terr = os.WriteFile(filepath.Join(secondPMUPath, \"type\"), []byte(\"19\"), 0777)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\n\treturn testDir, nil\n}\n\nfunc TestUncore(t *testing.T) {\n\tpath, err := mockSystemDevices()\n\tassert.Nil(t, err)\n\tdefer func() {\n\t\terr := os.RemoveAll(path)\n\t\tassert.Nil(t, err)\n\t}()\n\n\tactual, err := getUncorePMUs(path)\n\tassert.Nil(t, err)\n\texpected := uncorePMUs{\n\t\t\"uncore_imc_0\": {name: \"uncore_imc_0\", typeOf: 18, cpus: []uint32{0, 1}},\n\t\t\"uncore_imc_1\": {name: \"uncore_imc_1\", typeOf: 19, cpus: []uint32{0, 1}},\n\t}\n\tassert.Equal(t, expected, actual)\n\n\tpmuSet := uncorePMUs{\n\t\t\"uncore_imc_0\": actual[\"uncore_imc_0\"],\n\t\t\"uncore_imc_1\": actual[\"uncore_imc_1\"],\n\t}\n\n\tactualPMU, err := getPMU(pmuSet, expected[\"uncore_imc_0\"].typeOf)\n\tassert.Nil(t, err)\n\tassert.Equal(t, expected[\"uncore_imc_0\"], *actualPMU)\n}\n\nfunc TestUncoreCollectorSetup(t *testing.T) {\n\tpath, err := mockSystemDevices()\n\tassert.Nil(t, err)\n\tdefer func() {\n\t\terr := os.RemoveAll(path)\n\t\tassert.Nil(t, err)\n\t}()\n\n\tevents := PerfEvents{\n\t\tCore: Events{\n\t\t\tEvents: []Group{\n\t\t\t\t{[]Event{\"cache-misses\"}, false},\n\t\t\t},\n\t\t},\n\t\tUncore: Events{\n\t\t\tEvents: []Group{\n\t\t\t\t{[]Event{\"uncore_imc_1/cas_count_read\"}, false},\n\t\t\t\t{[]Event{\"uncore_imc_1/non_existing_event\"}, false},\n\t\t\t\t{[]Event{\"uncore_imc_0/cas_count_write\", \"uncore_imc_0/cas_count_read\"}, true},\n\t\t\t},\n\t\t\tCustomEvents: []CustomEvent{\n\t\t\t\t{19, Config{0x01, 0x02}, \"uncore_imc_1/cas_count_read\"},\n\t\t\t\t{0, Config{0x02, 0x03}, \"uncore_imc_0/cas_count_write\"},\n\t\t\t\t{18, Config{0x01, 0x02}, \"uncore_imc_0/cas_count_read\"},\n\t\t\t},\n\t\t},\n\t}\n\n\tcollector := &uncoreCollector{}\n\tcollector.perfEventOpen = func(attr *unix.PerfEventAttr, pid int, cpu int, groupFd int, flags int) (fd int, err error) {\n\t\treturn int(attr.Config), nil\n\t}\n\tcollector.ioctlSetInt = func(fd int, req uint, value int) error {\n\t\treturn nil\n\t}\n\n\terr = collector.setup(events, path)\n\tassert.Equal(t, []string{\"uncore_imc_1/cas_count_read\"},\n\t\tgetMapKeys(collector.cpuFiles[0][\"uncore_imc_1\"].cpuFiles))\n\tassert.ElementsMatch(t, []string{\"uncore_imc_0/cas_count_write\", \"uncore_imc_0/cas_count_read\"},\n\t\tgetMapKeys(collector.cpuFiles[2][\"uncore_imc_0\"].cpuFiles))\n\n\t// There are no errors.\n\tassert.Nil(t, err)\n}\n\nfunc TestParseUncoreEvents(t *testing.T) {\n\tevents := PerfEvents{\n\t\tUncore: Events{\n\t\t\tEvents: []Group{\n\t\t\t\t{[]Event{\"cas_count_read\"}, false},\n\t\t\t\t{[]Event{\"cas_count_write\"}, false},\n\t\t\t},\n\t\t\tCustomEvents: []CustomEvent{\n\t\t\t\t{\n\t\t\t\t\tType:   17,\n\t\t\t\t\tConfig: Config{0x50, 0x60},\n\t\t\t\t\tName:   \"cas_count_read\",\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\teventToCustomEvent := parseUncoreEvents(events.Uncore)\n\tassert.Len(t, eventToCustomEvent, 1)\n\tassert.Equal(t, eventToCustomEvent[\"cas_count_read\"].Name, Event(\"cas_count_read\"))\n\tassert.Equal(t, eventToCustomEvent[\"cas_count_read\"].Type, uint32(17))\n\tassert.Equal(t, eventToCustomEvent[\"cas_count_read\"].Config, Config{0x50, 0x60})\n}\n\nfunc TestObtainPMUs(t *testing.T) {\n\tgot := uncorePMUs{\n\t\t\"uncore_imc_0\": {name: \"uncore_imc_0\", typeOf: 18, cpus: []uint32{0, 1}},\n\t\t\"uncore_imc_1\": {name: \"uncore_imc_1\", typeOf: 19, cpus: []uint32{0, 1}},\n\t}\n\n\tactual := obtainPMUs(\"uncore_imc_0\", got)\n\tassert.Equal(t, uncorePMUs{\"uncore_imc_0\": got[\"uncore_imc_0\"]}, actual)\n\n\tactual = obtainPMUs(\"uncore_imc_1\", got)\n\tassert.Equal(t, uncorePMUs{\"uncore_imc_1\": got[\"uncore_imc_1\"]}, actual)\n\n\tactual = obtainPMUs(\"\", got)\n\tassert.Equal(t, uncorePMUs{}, actual)\n}\n\nfunc TestUncoreParseEventName(t *testing.T) {\n\teventName, pmuPrefix := parseEventName(\"some_event\")\n\tassert.Equal(t, \"some_event\", eventName)\n\tassert.Empty(t, pmuPrefix)\n\n\teventName, pmuPrefix = parseEventName(\"some_pmu/some_event\")\n\tassert.Equal(t, \"some_pmu\", pmuPrefix)\n\tassert.Equal(t, \"some_event\", eventName)\n\n\teventName, pmuPrefix = parseEventName(\"some_pmu/some_event/first_slash/second_slash\")\n\tassert.Equal(t, \"some_pmu\", pmuPrefix)\n\tassert.Equal(t, \"some_event/first_slash/second_slash\", eventName)\n}\n\nfunc TestCheckGroup(t *testing.T) {\n\tvar testCases = []struct {\n\t\tgroup          Group\n\t\teventPMUs      map[Event]uncorePMUs\n\t\texpectedOutput string\n\t}{\n\t\t{\n\t\t\tGroup{[]Event{\"uncore_imc/cas_count_write\"}, false},\n\t\t\tmap[Event]uncorePMUs{},\n\t\t\t\"the event \\\"uncore_imc/cas_count_write\\\" don't have any PMU to count with\",\n\t\t},\n\t\t{\n\t\t\tGroup{[]Event{\"uncore_imc/cas_count_write\", \"uncore_imc/cas_count_read\"}, true},\n\t\t\tmap[Event]uncorePMUs{\"uncore_imc/cas_count_write\": {\n\t\t\t\t\"uncore_imc_0\": {name: \"uncore_imc_0\", typeOf: 18, cpus: []uint32{0, 1}},\n\t\t\t\t\"uncore_imc_1\": {name: \"uncore_imc_1\", typeOf: 19, cpus: []uint32{0, 1}},\n\t\t\t},\n\t\t\t\t\"uncore_imc/cas_count_read\": {\n\t\t\t\t\t\"uncore_imc_0\": {name: \"uncore_imc_0\", typeOf: 18, cpus: []uint32{0, 1}},\n\t\t\t\t\t\"uncore_imc_1\": {name: \"uncore_imc_1\", typeOf: 19, cpus: []uint32{0, 1}},\n\t\t\t\t},\n\t\t\t},\n\t\t\t\"the events in group usually have to be from single PMU, try reorganizing the \\\"[uncore_imc/cas_count_write uncore_imc/cas_count_read]\\\" group\",\n\t\t},\n\t\t{\n\t\t\tGroup{[]Event{\"uncore_imc_0/cas_count_write\", \"uncore_imc_1/cas_count_read\"}, true},\n\t\t\tmap[Event]uncorePMUs{\"uncore_imc_0/cas_count_write\": {\n\t\t\t\t\"uncore_imc_0\": {name: \"uncore_imc_0\", typeOf: 18, cpus: []uint32{0, 1}},\n\t\t\t},\n\t\t\t\t\"uncore_imc_1/cas_count_read\": {\n\t\t\t\t\t\"uncore_imc_1\": {name: \"uncore_imc_1\", typeOf: 19, cpus: []uint32{0, 1}},\n\t\t\t\t},\n\t\t\t},\n\t\t\t\"the events in group usually have to be from the same PMU, try reorganizing the \\\"[uncore_imc_0/cas_count_write uncore_imc_1/cas_count_read]\\\" group\",\n\t\t},\n\t\t{\n\t\t\tGroup{[]Event{\"uncore_imc/cas_count_write\"}, false},\n\t\t\tmap[Event]uncorePMUs{\"uncore_imc/cas_count_write\": {\n\t\t\t\t\"uncore_imc_0\": {name: \"uncore_imc_0\", typeOf: 18, cpus: []uint32{0, 1}},\n\t\t\t\t\"uncore_imc_1\": {name: \"uncore_imc_1\", typeOf: 19, cpus: []uint32{0, 1}},\n\t\t\t}},\n\t\t\t\"\",\n\t\t},\n\t\t{\n\t\t\tGroup{[]Event{\"uncore_imc_0/cas_count_write\", \"uncore_imc_0/cas_count_read\"}, true},\n\t\t\tmap[Event]uncorePMUs{\"uncore_imc_0/cas_count_write\": {\n\t\t\t\t\"uncore_imc_0\": {name: \"uncore_imc_0\", typeOf: 18, cpus: []uint32{0, 1}},\n\t\t\t},\n\t\t\t\t\"uncore_imc_0/cas_count_read\": {\n\t\t\t\t\t\"uncore_imc_0\": {name: \"uncore_imc_0\", typeOf: 18, cpus: []uint32{0, 1}},\n\t\t\t\t}},\n\t\t\t\"\",\n\t\t},\n\t}\n\n\tfor _, tc := range testCases {\n\t\terr := checkGroup(tc.group, tc.eventPMUs)\n\t\tif tc.expectedOutput == \"\" {\n\t\t\tassert.Nil(t, err)\n\t\t} else {\n\t\t\tassert.EqualError(t, err, tc.expectedOutput)\n\t\t}\n\t}\n}\n\nfunc TestReadPerfUncoreStat(t *testing.T) {\n\tfile := GroupReadFormat{\n\t\tTimeEnabled: 0,\n\t\tTimeRunning: 1,\n\t\tNr:          1,\n\t}\n\n\tvaluesFile := Values{\n\t\tValue: 4,\n\t\tID:    0,\n\t}\n\n\texpectedStat := []v1.PerfUncoreStat{{\n\t\tPerfValue: v1.PerfValue{\n\t\t\tScalingRatio: 1,\n\t\t\tValue:        4,\n\t\t\tName:         \"foo\",\n\t\t},\n\t\tSocket: 0,\n\t\tPMU:    \"bar\",\n\t}}\n\tcpuToSocket := map[int]int{\n\t\t1: 0,\n\t\t2: 0,\n\t}\n\n\tbuf := &buffer{bytes.NewBuffer([]byte{})}\n\terr := binary.Write(buf, binary.LittleEndian, file)\n\tassert.NoError(t, err)\n\terr = binary.Write(buf, binary.LittleEndian, valuesFile)\n\tassert.NoError(t, err)\n\n\tstat, err := readPerfUncoreStat(buf, group{\n\t\tcpuFiles:   nil,\n\t\tnames:      []string{\"foo\"},\n\t\tleaderName: \"foo\",\n\t}, 1, \"bar\", cpuToSocket)\n\tassert.NoError(t, err)\n\tassert.Equal(t, expectedStat, stat)\n}\n\nfunc getMapKeys(someMap map[string]map[int]readerCloser) []string {\n\tvar keys []string\n\tfor key := range someMap {\n\t\tkeys = append(keys, key)\n\t}\n\treturn keys\n}\n"
  },
  {
    "path": "resctrl/factory.go",
    "content": "// Copyright 2025 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage resctrl\n\nimport (\n\t\"fmt\"\n\t\"sync\"\n\t\"time\"\n\n\t\"github.com/google/cadvisor/stats\"\n\n\t\"k8s.io/klog/v2\"\n)\n\ntype ResControlManager interface {\n\tDestroy()\n\tGetCollector(containerName string, getContainerPids func() ([]string, error), numberOfNUMANodes int) (stats.Collector, error)\n}\n\n// All registered auth provider plugins.\nvar pluginsLock sync.Mutex\nvar plugins = make(map[string]ResControlManagerPlugin)\n\ntype ResControlManagerPlugin interface {\n\tNewManager(interval time.Duration, vendorID string, inHostNamespace bool) (ResControlManager, error)\n}\n\nfunc RegisterPlugin(name string, plugin ResControlManagerPlugin) error {\n\tpluginsLock.Lock()\n\tdefer pluginsLock.Unlock()\n\tif _, found := plugins[name]; found {\n\t\treturn fmt.Errorf(\"ResControlManagerPlugin %q was registered twice\", name)\n\t}\n\tklog.V(4).Infof(\"Registered ResControlManagerPlugin %q\", name)\n\tplugins[name] = plugin\n\treturn nil\n}\n\nfunc NewManager(interval time.Duration, vendorID string, inHostNamespace bool) (ResControlManager, error) {\n\tpluginsLock.Lock()\n\tdefer pluginsLock.Unlock()\n\tfor _, plugin := range plugins {\n\t\treturn plugin.NewManager(interval, vendorID, inHostNamespace)\n\t}\n\treturn nil, fmt.Errorf(\"unable to find plugins for resctrl manager\")\n}\n"
  },
  {
    "path": "resctrl/intel/collector.go",
    "content": "//go:build linux\n\n// Copyright 2021 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n// Collector of resctrl for a container.\npackage intel\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"strings\"\n\t\"sync\"\n\t\"time\"\n\n\t\"k8s.io/klog/v2\"\n\n\tinfo \"github.com/google/cadvisor/info/v1\"\n)\n\nconst noInterval = 0\n\ntype collector struct {\n\tid                string\n\tinterval          time.Duration\n\tgetContainerPids  func() ([]string, error)\n\tresctrlPath       string\n\trunning           bool\n\tdestroyed         bool\n\tnumberOfNUMANodes int\n\tvendorID          string\n\tmu                sync.Mutex\n\tinHostNamespace   bool\n}\n\nfunc newCollector(id string, getContainerPids func() ([]string, error), interval time.Duration, numberOfNUMANodes int, vendorID string, inHostNamespace bool) *collector {\n\treturn &collector{id: id, interval: interval, getContainerPids: getContainerPids, numberOfNUMANodes: numberOfNUMANodes,\n\t\tvendorID: vendorID, mu: sync.Mutex{}, inHostNamespace: inHostNamespace}\n}\n\nfunc (c *collector) setup() error {\n\tvar err error\n\tc.resctrlPath, err = prepareMonitoringGroup(c.id, c.getContainerPids, c.inHostNamespace)\n\n\tif c.interval != noInterval {\n\t\tif err != nil {\n\t\t\tklog.Errorf(\"Failed to setup container %q resctrl collector: %s \\n Trying again in next intervals.\", c.id, err)\n\t\t} else {\n\t\t\tc.running = true\n\t\t}\n\t\tgo func() {\n\t\t\tfor {\n\t\t\t\ttime.Sleep(c.interval)\n\t\t\t\tc.mu.Lock()\n\t\t\t\tif c.destroyed {\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tklog.V(5).Infof(\"Trying to check %q containers control group.\", c.id)\n\t\t\t\tif c.running {\n\t\t\t\t\terr = c.checkMonitoringGroup()\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\tc.running = false\n\t\t\t\t\t\tklog.Errorf(\"Failed to check %q resctrl collector control group: %s \\n Trying again in next intervals.\", c.id, err)\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tc.resctrlPath, err = prepareMonitoringGroup(c.id, c.getContainerPids, c.inHostNamespace)\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\tc.running = false\n\t\t\t\t\t\tklog.Errorf(\"Failed to setup container %q resctrl collector: %s \\n Trying again in next intervals.\", c.id, err)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tc.mu.Unlock()\n\t\t\t}\n\t\t}()\n\t} else {\n\t\t// There is no interval set, if setup fail, stop.\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"failed to setup container %q resctrl collector: %w\", c.id, err)\n\t\t}\n\t\tc.running = true\n\t}\n\n\treturn nil\n}\n\nfunc (c *collector) checkMonitoringGroup() error {\n\tnewPath, err := prepareMonitoringGroup(c.id, c.getContainerPids, c.inHostNamespace)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"couldn't obtain mon_group path: %v\", err)\n\t}\n\n\t// Check if container moved between control groups.\n\tif newPath != c.resctrlPath {\n\t\terr = c.clear()\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"couldn't clear previous monitoring group: %w\", err)\n\t\t}\n\t\tc.resctrlPath = newPath\n\t}\n\n\treturn nil\n}\n\nfunc (c *collector) UpdateStats(stats *info.ContainerStats) error {\n\tc.mu.Lock()\n\tdefer c.mu.Unlock()\n\tif c.running {\n\t\tstats.Resctrl = info.ResctrlStats{}\n\n\t\tresctrlStats, err := getIntelRDTStatsFrom(c.resctrlPath, c.vendorID)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\tstats.Resctrl.MemoryBandwidth = make([]info.MemoryBandwidthStats, 0, c.numberOfNUMANodes)\n\t\tstats.Resctrl.Cache = make([]info.CacheStats, 0, c.numberOfNUMANodes)\n\n\t\tfor _, numaNodeStats := range *resctrlStats.MBMStats {\n\t\t\tstats.Resctrl.MemoryBandwidth = append(stats.Resctrl.MemoryBandwidth,\n\t\t\t\tinfo.MemoryBandwidthStats{\n\t\t\t\t\tTotalBytes: numaNodeStats.MBMTotalBytes,\n\t\t\t\t\tLocalBytes: numaNodeStats.MBMLocalBytes,\n\t\t\t\t})\n\t\t}\n\n\t\tfor _, numaNodeStats := range *resctrlStats.CMTStats {\n\t\t\tstats.Resctrl.Cache = append(stats.Resctrl.Cache,\n\t\t\t\tinfo.CacheStats{LLCOccupancy: numaNodeStats.LLCOccupancy})\n\t\t}\n\t}\n\n\treturn nil\n}\n\nfunc (c *collector) Destroy() {\n\tc.mu.Lock()\n\tdefer c.mu.Unlock()\n\tc.running = false\n\terr := c.clear()\n\tif err != nil {\n\t\tklog.Errorf(\"trying to destroy %q resctrl collector but: %v\", c.id, err)\n\t}\n\tc.destroyed = true\n}\n\nfunc (c *collector) clear() error {\n\t// Not allowed to remove root or undefined resctrl directory.\n\tif c.id != rootContainer && c.resctrlPath != \"\" {\n\t\t// Remove only own prepared mon group.\n\t\tif strings.HasPrefix(filepath.Base(c.resctrlPath), monGroupPrefix) {\n\t\t\terr := os.RemoveAll(c.resctrlPath)\n\t\t\tif err != nil {\n\t\t\t\treturn fmt.Errorf(\"couldn't clear mon_group: %v\", err)\n\t\t\t}\n\t\t}\n\t}\n\treturn nil\n}\n"
  },
  {
    "path": "resctrl/intel/collector_test.go",
    "content": "//go:build linux\n\n// Copyright 2021 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n// Collector tests.\npackage intel\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/assert\"\n\n\tinfo \"github.com/google/cadvisor/info/v1\"\n)\n\nfunc TestNewCollectorWithSetup(t *testing.T) {\n\trootResctrl = mockResctrl()\n\tdefer os.RemoveAll(rootResctrl)\n\n\tpidsPath = mockContainersPids()\n\tdefer os.RemoveAll(pidsPath)\n\n\tprocessPath = mockProcFs()\n\tdefer os.RemoveAll(processPath)\n\n\texpectedID := \"container\"\n\texpectedResctrlPath := filepath.Join(rootResctrl, monGroupsDirName, fmt.Sprintf(\"%s-%s\", monGroupPrefix, expectedID))\n\n\tcollector := newCollector(expectedID, mockGetContainerPids, 0, 2, \"\", true)\n\terr := collector.setup()\n\n\tassert.NoError(t, err)\n\tassert.Equal(t, collector.id, expectedID)\n\tassert.Equal(t, collector.resctrlPath, expectedResctrlPath)\n}\n\nfunc TestUpdateStats(t *testing.T) {\n\trootResctrl = mockResctrl()\n\tdefer os.RemoveAll(rootResctrl)\n\n\tpidsPath = mockContainersPids()\n\tdefer os.RemoveAll(pidsPath)\n\n\tprocessPath = mockProcFs()\n\tdefer os.RemoveAll(processPath)\n\n\tcollector := newCollector(\"container\", mockGetContainerPids, 0, 2, \"\", true)\n\terr := collector.setup()\n\tassert.NoError(t, err)\n\n\tmockResctrlMonData(collector.resctrlPath)\n\tenabledCMT, enabledMBM = true, true\n\n\tstats := info.ContainerStats{}\n\n\t// Write some dumb data.\n\terr = collector.UpdateStats(&stats)\n\tassert.NoError(t, err)\n\tassert.Equal(t, stats.Resctrl.Cache, []info.CacheStats{\n\t\t{LLCOccupancy: 1111},\n\t\t{LLCOccupancy: 3333},\n\t})\n\tassert.Equal(t, stats.Resctrl.MemoryBandwidth, []info.MemoryBandwidthStats{\n\t\t{\n\t\t\tTotalBytes: 3333,\n\t\t\tLocalBytes: 2222,\n\t\t},\n\t\t{\n\t\t\tTotalBytes: 3333,\n\t\t\tLocalBytes: 1111,\n\t\t},\n\t})\n}\n\nfunc TestDestroy(t *testing.T) {\n\trootResctrl = mockResctrl()\n\tdefer os.RemoveAll(rootResctrl)\n\n\tpidsPath = mockContainersPids()\n\tdefer os.RemoveAll(pidsPath)\n\n\tprocessPath = mockProcFs()\n\tdefer os.RemoveAll(processPath)\n\n\tcollector := newCollector(\"container\", mockGetContainerPids, 0, 2, \"\", true)\n\terr := collector.setup()\n\tif err != nil {\n\t\tt.Fail()\n\t}\n\n\tpath := collector.resctrlPath\n\n\tif stat, err := os.Stat(path); stat == nil && err != nil {\n\t\tt.Fail()\n\t}\n\n\tcollector.Destroy()\n\n\tif stat, err := os.Stat(path); stat != nil && err == nil {\n\t\tt.Fail()\n\t}\n}\n"
  },
  {
    "path": "resctrl/intel/install/install.go",
    "content": "// Copyright 2025 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n//go:build linux\n\npackage install\n\nimport (\n\t\"time\"\n\n\t\"github.com/google/cadvisor/resctrl\"\n\t\"github.com/google/cadvisor/resctrl/intel\"\n\n\t\"k8s.io/klog/v2\"\n)\n\ntype managerplugin struct {\n}\n\nfunc (m *managerplugin) NewManager(interval time.Duration, vendorID string, inHostNamespace bool) (resctrl.ResControlManager, error) {\n\treturn intel.NewManager(interval, intel.Setup, vendorID, inHostNamespace)\n}\n\nfunc init() {\n\terr := resctrl.RegisterPlugin(\"intel\", &managerplugin{})\n\tif err != nil {\n\t\tklog.Fatalf(\"Failed to register intel resctrl plugin: %v\", err)\n\t}\n}\n"
  },
  {
    "path": "resctrl/intel/manager.go",
    "content": "//go:build linux\n\n// Copyright 2021 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n// ResControlManager of resctrl for containers.\npackage intel\n\nimport (\n\t\"errors\"\n\t\"time\"\n\n\t\"k8s.io/klog/v2\"\n\n\t\"github.com/google/cadvisor/container/raw\"\n\t\"github.com/google/cadvisor/resctrl\"\n\t\"github.com/google/cadvisor/stats\"\n)\n\ntype manager struct {\n\tstats.NoopDestroy\n\tinterval        time.Duration\n\tvendorID        string\n\tinHostNamespace bool\n}\n\nfunc (m *manager) GetCollector(containerName string, getContainerPids func() ([]string, error), numberOfNUMANodes int) (stats.Collector, error) {\n\tcollector := newCollector(containerName, getContainerPids, m.interval, numberOfNUMANodes, m.vendorID, m.inHostNamespace)\n\terr := collector.setup()\n\tif err != nil {\n\t\treturn &stats.NoopCollector{}, err\n\t}\n\n\treturn collector, nil\n}\n\nfunc NewManager(interval time.Duration, setup func() error, vendorID string, inHostNamespace bool) (resctrl.ResControlManager, error) {\n\terr := setup()\n\tif err != nil {\n\t\treturn &NoopManager{}, err\n\t}\n\n\tif !isResctrlInitialized {\n\t\treturn &NoopManager{}, errors.New(\"the resctrl isn't initialized\")\n\t}\n\tif !(enabledCMT || enabledMBM) {\n\t\treturn &NoopManager{}, errors.New(\"there are no monitoring features available\")\n\t}\n\n\tif !*raw.DockerOnly {\n\t\tklog.Warning(\"--docker_only should be set when collecting Resctrl metrics! See the runtime docs.\")\n\t}\n\n\treturn &manager{interval: interval, vendorID: vendorID, inHostNamespace: inHostNamespace}, nil\n}\n\ntype NoopManager struct {\n\tstats.NoopDestroy\n}\n\nfunc (np *NoopManager) GetCollector(_ string, _ func() ([]string, error), _ int) (stats.Collector, error) {\n\treturn &stats.NoopCollector{}, nil\n}\n"
  },
  {
    "path": "resctrl/intel/manager_test.go",
    "content": "//go:build linux\n\n// Copyright 2021 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n// ResControlManager tests.\npackage intel\n\nimport (\n\t\"os\"\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/assert\"\n\n\t\"github.com/google/cadvisor/resctrl\"\n)\n\nfunc TestNewManager(t *testing.T) {\n\tvar testCases = []struct {\n\t\tisResctrlInitialized bool\n\t\tenabledCMT           bool\n\t\tenabledMBM           bool\n\t\tinHostNamespace      bool\n\t\terr                  string\n\t\texpected             resctrl.ResControlManager\n\t}{\n\t\t{\n\t\t\ttrue,\n\t\t\ttrue,\n\t\t\tfalse,\n\t\t\ttrue,\n\t\t\t\"\",\n\t\t\t&manager{interval: 0, inHostNamespace: true},\n\t\t},\n\t\t{\n\t\t\ttrue,\n\t\t\tfalse,\n\t\t\ttrue,\n\t\t\ttrue,\n\t\t\t\"\",\n\t\t\t&manager{interval: 0, inHostNamespace: true},\n\t\t},\n\t\t{\n\t\t\ttrue,\n\t\t\ttrue,\n\t\t\ttrue,\n\t\t\tfalse,\n\t\t\t\"\",\n\t\t\t&manager{interval: 0, inHostNamespace: false},\n\t\t},\n\t\t{\n\t\t\tfalse,\n\t\t\ttrue,\n\t\t\tfalse,\n\t\t\tfalse,\n\t\t\t\"the resctrl isn't initialized\",\n\t\t\t&NoopManager{},\n\t\t},\n\t\t{\n\t\t\tfalse,\n\t\t\tfalse,\n\t\t\ttrue,\n\t\t\tfalse,\n\t\t\t\"the resctrl isn't initialized\",\n\t\t\t&NoopManager{},\n\t\t},\n\t\t{\n\t\t\tfalse,\n\t\t\ttrue,\n\t\t\ttrue,\n\t\t\ttrue,\n\t\t\t\"the resctrl isn't initialized\",\n\t\t\t&NoopManager{},\n\t\t},\n\t\t{\n\t\t\tfalse,\n\t\t\tfalse,\n\t\t\tfalse,\n\t\t\ttrue,\n\t\t\t\"the resctrl isn't initialized\",\n\t\t\t&NoopManager{},\n\t\t},\n\t\t{\n\t\t\ttrue,\n\t\t\tfalse,\n\t\t\tfalse,\n\t\t\ttrue,\n\t\t\t\"there are no monitoring features available\",\n\t\t\t&NoopManager{},\n\t\t},\n\t}\n\n\tfor _, test := range testCases {\n\t\tsetup := func() error {\n\t\t\tisResctrlInitialized = test.isResctrlInitialized\n\t\t\tenabledCMT = test.enabledCMT\n\t\t\tenabledMBM = test.enabledMBM\n\t\t\treturn nil\n\t\t}\n\t\tgot, err := NewManager(0, setup, \"\", test.inHostNamespace)\n\t\tassert.Equal(t, got, test.expected)\n\t\tcheckError(t, err, test.err)\n\t}\n}\n\nfunc TestGetCollector(t *testing.T) {\n\trootResctrl = mockResctrl()\n\tdefer os.RemoveAll(rootResctrl)\n\n\tpidsPath = mockContainersPids()\n\tdefer os.RemoveAll(pidsPath)\n\n\tprocessPath = mockProcFs()\n\tdefer os.RemoveAll(processPath)\n\n\texpectedID := \"container\"\n\n\tsetup := func() error {\n\t\tisResctrlInitialized = true\n\t\tenabledCMT = true\n\t\tenabledMBM = true\n\t\treturn nil\n\t}\n\tmanager, err := NewManager(0, setup, \"\", true)\n\tassert.NoError(t, err)\n\n\t_, err = manager.GetCollector(expectedID, mockGetContainerPids, 2)\n\tassert.NoError(t, err)\n}\n"
  },
  {
    "path": "resctrl/intel/testing/tasks_empty",
    "content": ""
  },
  {
    "path": "resctrl/intel/testing/tasks_one",
    "content": "2\n"
  },
  {
    "path": "resctrl/intel/testing/tasks_two",
    "content": "12\n77"
  },
  {
    "path": "resctrl/intel/utils.go",
    "content": "//go:build linux\n\n// Copyright 2021 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n// Utilities.\npackage intel\n\nimport (\n\t\"bufio\"\n\t\"bytes\"\n\t\"errors\"\n\t\"fmt\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"strconv\"\n\t\"strings\"\n\n\t\"github.com/opencontainers/cgroups\"\n\t\"github.com/opencontainers/cgroups/fs2\"\n\t\"github.com/opencontainers/runc/libcontainer/intelrdt\"\n)\n\nconst (\n\tcpuCgroup                = \"cpu\"\n\trootContainer            = \"/\"\n\tmonitoringGroupDir       = \"mon_groups\"\n\tprocessTask              = \"task\"\n\tcpusFileName             = \"cpus\"\n\tcpusListFileName         = \"cpus_list\"\n\tschemataFileName         = \"schemata\"\n\ttasksFileName            = \"tasks\"\n\tmodeFileName             = \"mode\"\n\tsizeFileName             = \"size\"\n\tinfoDirName              = \"info\"\n\tmonDataDirName           = \"mon_data\"\n\tmonGroupsDirName         = \"mon_groups\"\n\tnoPidsPassedError        = \"there are no pids passed\"\n\tnoContainerNameError     = \"there are no container name passed\"\n\tnoControlGroupFoundError = \"couldn't find control group matching container\"\n\tllcOccupancyFileName     = \"llc_occupancy\"\n\tmbmLocalBytesFileName    = \"mbm_local_bytes\"\n\tmbmTotalBytesFileName    = \"mbm_total_bytes\"\n\tcontainerPrefix          = '/'\n\tminContainerNameLen      = 2 // \"/<container_name>\" e.g. \"/a\"\n\tunavailable              = \"Unavailable\"\n\tmonGroupPrefix           = \"cadvisor\"\n)\n\nvar (\n\trootResctrl          = \"\"\n\tpidsPath             = \"\"\n\tprocessPath          = \"/proc\"\n\tenabledMBM           = false\n\tenabledCMT           = false\n\tisResctrlInitialized = false\n\tgroupDirectories     = map[string]struct{}{\n\t\tcpusFileName:     {},\n\t\tcpusListFileName: {},\n\t\tinfoDirName:      {},\n\t\tmonDataDirName:   {},\n\t\tmonGroupsDirName: {},\n\t\tschemataFileName: {},\n\t\ttasksFileName:    {},\n\t\tmodeFileName:     {},\n\t\tsizeFileName:     {},\n\t}\n)\n\nfunc Setup() error {\n\tvar err error\n\trootResctrl, err = intelrdt.Root()\n\tif err != nil {\n\t\treturn fmt.Errorf(\"unable to initialize resctrl: %v\", err)\n\t}\n\n\tif cgroups.IsCgroup2UnifiedMode() {\n\t\tpidsPath = fs2.UnifiedMountpoint\n\t} else {\n\t\tpidsPath = filepath.Join(fs2.UnifiedMountpoint, cpuCgroup)\n\t}\n\n\tenabledMBM = intelrdt.IsMBMEnabled()\n\tenabledCMT = intelrdt.IsCMTEnabled()\n\n\tisResctrlInitialized = true\n\n\treturn nil\n}\n\nfunc prepareMonitoringGroup(containerName string, getContainerPids func() ([]string, error), inHostNamespace bool) (string, error) {\n\tif containerName == rootContainer {\n\t\treturn rootResctrl, nil\n\t}\n\n\tpids, err := getContainerPids()\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\n\tif len(pids) == 0 {\n\t\treturn \"\", fmt.Errorf(\"couldn't obtain %q container pids: there is no pids in cgroup\", containerName)\n\t}\n\n\t// Firstly, find the control group to which the container belongs.\n\t// Consider the root group.\n\tcontrolGroupPath, err := findGroup(rootResctrl, pids, true, false)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"%q %q: %q\", noControlGroupFoundError, containerName, err)\n\t}\n\tif controlGroupPath == \"\" {\n\t\treturn \"\", fmt.Errorf(\"%q %q\", noControlGroupFoundError, containerName)\n\t}\n\n\t// Check if there is any monitoring group.\n\tmonGroupPath, err := findGroup(filepath.Join(controlGroupPath, monGroupsDirName), pids, false, true)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"couldn't find monitoring group matching %q container: %v\", containerName, err)\n\t}\n\n\t// Prepare new one if not exists.\n\tif monGroupPath == \"\" {\n\t\t// Remove leading prefix.\n\t\t// e.g. /my/container -> my/container\n\t\tif len(containerName) >= minContainerNameLen && containerName[0] == containerPrefix {\n\t\t\tcontainerName = containerName[1:]\n\t\t}\n\n\t\t// Add own prefix and use `-` instead `/`.\n\t\t// e.g. my/container -> cadvisor-my-container\n\t\tproperContainerName := fmt.Sprintf(\"%s-%s\", monGroupPrefix, strings.Replace(containerName, \"/\", \"-\", -1))\n\t\tmonGroupPath = filepath.Join(controlGroupPath, monitoringGroupDir, properContainerName)\n\n\t\terr = os.MkdirAll(monGroupPath, os.ModePerm)\n\t\tif err != nil {\n\t\t\treturn \"\", fmt.Errorf(\"couldn't create monitoring group directory for %q container: %w\", containerName, err)\n\t\t}\n\n\t\tif !inHostNamespace {\n\t\t\tprocessPath = \"/rootfs/proc\"\n\t\t}\n\n\t\tfor _, pid := range pids {\n\t\t\tprocessThreads, err := getAllProcessThreads(filepath.Join(processPath, pid, processTask))\n\t\t\tif err != nil {\n\t\t\t\treturn \"\", err\n\t\t\t}\n\t\t\tfor _, thread := range processThreads {\n\t\t\t\terr = intelrdt.WriteIntelRdtTasks(monGroupPath, thread)\n\t\t\t\tif err != nil {\n\t\t\t\t\tsecondError := os.Remove(monGroupPath)\n\t\t\t\t\tif secondError != nil {\n\t\t\t\t\t\treturn \"\", fmt.Errorf(\n\t\t\t\t\t\t\t\"coudn't assign pids to %q container monitoring group: %w \\n couldn't clear %q monitoring group: %v\",\n\t\t\t\t\t\t\tcontainerName, err, containerName, secondError)\n\t\t\t\t\t}\n\t\t\t\t\treturn \"\", fmt.Errorf(\"coudn't assign pids to %q container monitoring group: %w\", containerName, err)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn monGroupPath, nil\n}\n\nfunc getPids(containerName string) ([]int, error) {\n\tif len(containerName) == 0 {\n\t\t// No container name passed.\n\t\treturn nil, errors.New(noContainerNameError)\n\t}\n\tpids, err := cgroups.GetAllPids(filepath.Join(pidsPath, containerName))\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"couldn't obtain pids for %q container: %v\", containerName, err)\n\t}\n\treturn pids, nil\n}\n\n// getAllProcessThreads obtains all available processes from directory.\n// e.g. ls /proc/4215/task/ -> 4215, 4216, 4217, 4218\n// func will return [4215, 4216, 4217, 4218].\nfunc getAllProcessThreads(path string) ([]int, error) {\n\tprocessThreads := make([]int, 0)\n\n\tthreadDirs, err := os.ReadDir(path)\n\tif err != nil {\n\t\treturn processThreads, err\n\t}\n\n\tfor _, dir := range threadDirs {\n\t\tpid, err := strconv.Atoi(dir.Name())\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"couldn't parse %q dir: %v\", dir.Name(), err)\n\t\t}\n\t\tprocessThreads = append(processThreads, pid)\n\t}\n\n\treturn processThreads, nil\n}\n\n// findGroup returns the path of a control/monitoring group in which the pids are.\nfunc findGroup(group string, pids []string, includeGroup bool, exclusive bool) (string, error) {\n\tif len(pids) == 0 {\n\t\treturn \"\", errors.New(noPidsPassedError)\n\t}\n\n\tavailablePaths := make([]string, 0)\n\tif includeGroup {\n\t\tavailablePaths = append(availablePaths, group)\n\t}\n\n\tfiles, err := os.ReadDir(group)\n\tfor _, file := range files {\n\t\tif _, ok := groupDirectories[file.Name()]; !ok {\n\t\t\tavailablePaths = append(availablePaths, filepath.Join(group, file.Name()))\n\t\t}\n\t}\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"couldn't obtain groups paths: %w\", err)\n\t}\n\n\tfor _, path := range availablePaths {\n\t\tgroupFound, err := arePIDsInGroup(path, pids, exclusive)\n\t\tif err != nil {\n\t\t\treturn \"\", err\n\t\t}\n\t\tif groupFound {\n\t\t\treturn path, nil\n\t\t}\n\t}\n\n\treturn \"\", nil\n}\n\n// arePIDsInGroup returns true if all of the pids are within control group.\nfunc arePIDsInGroup(path string, pids []string, exclusive bool) (bool, error) {\n\tif len(pids) == 0 {\n\t\treturn false, fmt.Errorf(\"couldn't obtain pids from %q path: %v\", path, noPidsPassedError)\n\t}\n\n\ttasks, err := readTasksFile(filepath.Join(path, tasksFileName))\n\tif err != nil {\n\t\treturn false, err\n\t}\n\n\tany := false\n\tfor _, pid := range pids {\n\t\t_, ok := tasks[pid]\n\t\tif !ok {\n\t\t\t// There are missing pids within group.\n\t\t\tif any {\n\t\t\t\treturn false, fmt.Errorf(\"there should be all pids in group\")\n\t\t\t}\n\t\t\treturn false, nil\n\t\t}\n\t\tany = true\n\t}\n\n\t// Check if there should be only passed pids in group.\n\tif exclusive {\n\t\tif len(tasks) != len(pids) {\n\t\t\treturn false, fmt.Errorf(\"group should have container pids only\")\n\t\t}\n\t}\n\n\treturn true, nil\n}\n\n// readTasksFile returns pids map from given tasks path.\nfunc readTasksFile(tasksPath string) (map[string]struct{}, error) {\n\ttasks := make(map[string]struct{})\n\n\ttasksFile, err := os.Open(tasksPath)\n\tif err != nil {\n\t\treturn tasks, fmt.Errorf(\"couldn't read tasks file from %q path: %w\", tasksPath, err)\n\t}\n\tdefer tasksFile.Close()\n\n\tscanner := bufio.NewScanner(tasksFile)\n\tfor scanner.Scan() {\n\t\ttasks[scanner.Text()] = struct{}{}\n\t}\n\n\tif err := scanner.Err(); err != nil {\n\t\treturn tasks, fmt.Errorf(\"couldn't obtain pids from %q path: %w\", tasksPath, err)\n\t}\n\n\treturn tasks, nil\n}\n\nfunc readStatFrom(path string, vendorID string) (uint64, error) {\n\tcontext, err := os.ReadFile(path)\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\n\tcontextString := string(bytes.TrimSpace(context))\n\n\tif contextString == unavailable {\n\t\terr := fmt.Errorf(\"\\\"Unavailable\\\" value from file %q\", path)\n\t\tif vendorID == \"AuthenticAMD\" {\n\t\t\tkernelBugzillaLink := \"https://bugzilla.kernel.org/show_bug.cgi?id=213311\"\n\t\t\terr = fmt.Errorf(\"%v, possible bug: %q\", err, kernelBugzillaLink)\n\t\t}\n\t\treturn 0, err\n\t}\n\n\tstat, err := strconv.ParseUint(contextString, 10, 64)\n\tif err != nil {\n\t\treturn stat, fmt.Errorf(\"unable to parse %q as a uint from file %q\", string(context), path)\n\t}\n\n\treturn stat, nil\n}\n\nfunc getIntelRDTStatsFrom(path string, vendorID string) (intelrdt.Stats, error) {\n\tstats := intelrdt.Stats{}\n\n\tstatsDirectories, err := filepath.Glob(filepath.Join(path, monDataDirName, \"*\"))\n\tif err != nil {\n\t\treturn stats, err\n\t}\n\n\tif len(statsDirectories) == 0 {\n\t\treturn stats, fmt.Errorf(\"there is no mon_data stats directories: %q\", path)\n\t}\n\n\tvar cmtStats []intelrdt.CMTNumaNodeStats\n\tvar mbmStats []intelrdt.MBMNumaNodeStats\n\n\tfor _, dir := range statsDirectories {\n\t\tif enabledCMT {\n\t\t\tllcOccupancy, err := readStatFrom(filepath.Join(dir, llcOccupancyFileName), vendorID)\n\t\t\tif err != nil {\n\t\t\t\treturn stats, err\n\t\t\t}\n\t\t\tcmtStats = append(cmtStats, intelrdt.CMTNumaNodeStats{LLCOccupancy: llcOccupancy})\n\t\t}\n\t\tif enabledMBM {\n\t\t\tmbmTotalBytes, err := readStatFrom(filepath.Join(dir, mbmTotalBytesFileName), vendorID)\n\t\t\tif err != nil {\n\t\t\t\treturn stats, err\n\t\t\t}\n\t\t\tmbmLocalBytes, err := readStatFrom(filepath.Join(dir, mbmLocalBytesFileName), vendorID)\n\t\t\tif err != nil {\n\t\t\t\treturn stats, err\n\t\t\t}\n\t\t\tmbmStats = append(mbmStats, intelrdt.MBMNumaNodeStats{\n\t\t\t\tMBMTotalBytes: mbmTotalBytes,\n\t\t\t\tMBMLocalBytes: mbmLocalBytes,\n\t\t\t})\n\t\t}\n\t}\n\n\tstats.CMTStats = &cmtStats\n\tstats.MBMStats = &mbmStats\n\n\treturn stats, nil\n}\n"
  },
  {
    "path": "resctrl/intel/utils_test.go",
    "content": "//go:build linux\n\n// Copyright 2021 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n// Utilities tests.\n//\n// Mocked environment:\n// - \"container\" first container with {1, 2, 3} processes.\n// - \"another\" second container with {5, 6} processes.\npackage intel\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"testing\"\n\n\t\"github.com/opencontainers/cgroups\"\n\t\"github.com/opencontainers/runc/libcontainer/intelrdt\"\n\n\t\"github.com/stretchr/testify/assert\"\n)\n\nfunc init() {\n\t// All the test cases in this file uses \"fake\" cgroups (not the real\n\t// cgroupfs). This setting relaxes filesystem type check in cgroups\n\t// package so it can work with fake cgroups.\n\tcgroups.TestMode = true\n}\n\nfunc mockAllGetContainerPids() ([]string, error) {\n\treturn []string{\"1\", \"2\", \"3\", \"5\", \"6\"}, nil\n}\n\nfunc mockGetContainerPids() ([]string, error) {\n\treturn []string{\"1\", \"2\", \"3\"}, nil\n}\n\nfunc mockAnotherGetContainerPids() ([]string, error) {\n\treturn []string{\"5\", \"6\"}, nil\n}\n\nfunc touch(path string) error {\n\tfile, err := os.OpenFile(path, os.O_CREATE, os.ModePerm)\n\tif err != nil {\n\t\treturn err\n\t}\n\treturn file.Close()\n}\n\nfunc touchDir(path string) error {\n\terr := os.MkdirAll(path, os.ModePerm)\n\tif err != nil {\n\t\treturn err\n\t}\n\treturn nil\n}\n\nfunc fillPids(path string, pids []int) error {\n\tf, err := os.OpenFile(path, os.O_WRONLY, os.ModePerm)\n\tif err != nil {\n\t\treturn err\n\t}\n\tdefer f.Close()\n\tfor _, pid := range pids {\n\t\t_, err := fmt.Fprintln(f, pid)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc mockResctrl() string {\n\tpath, _ := os.MkdirTemp(\"\", \"resctrl\")\n\n\tvar files = []struct {\n\t\tpath  string\n\t\ttouch func(string) error\n\t}{\n\t\t// Mock root files.\n\t\t{\n\t\t\tfilepath.Join(path, cpusFileName),\n\t\t\ttouch,\n\t\t},\n\t\t{\n\t\t\tfilepath.Join(path, cpusListFileName),\n\t\t\ttouch,\n\t\t},\n\t\t{\n\t\t\tfilepath.Join(path, infoDirName),\n\t\t\ttouchDir,\n\t\t},\n\t\t{\n\t\t\tfilepath.Join(path, monDataDirName),\n\t\t\ttouchDir,\n\t\t},\n\t\t{\n\t\t\tfilepath.Join(path, monGroupsDirName),\n\t\t\ttouchDir,\n\t\t},\n\t\t{\n\t\t\tfilepath.Join(path, schemataFileName),\n\t\t\ttouch,\n\t\t},\n\t\t{\n\t\t\tfilepath.Join(path, modeFileName),\n\t\t\ttouch,\n\t\t},\n\t\t{\n\t\t\tfilepath.Join(path, sizeFileName),\n\t\t\ttouch,\n\t\t},\n\t\t{\n\t\t\tfilepath.Join(path, tasksFileName),\n\t\t\ttouch,\n\t\t},\n\t\t// Create custom CLOSID \"m1\".\n\t\t{\n\t\t\tfilepath.Join(path, \"m1\"),\n\t\t\ttouchDir,\n\t\t},\n\t\t{\n\t\t\tfilepath.Join(path, \"m1\", cpusFileName),\n\t\t\ttouch,\n\t\t},\n\t\t{\n\t\t\tfilepath.Join(path, \"m1\", cpusListFileName),\n\t\t\ttouch,\n\t\t},\n\t\t{\n\t\t\tfilepath.Join(path, \"m1\", monDataDirName),\n\t\t\ttouchDir,\n\t\t},\n\t\t{\n\t\t\tfilepath.Join(path, \"m1\", monGroupsDirName),\n\t\t\ttouchDir,\n\t\t},\n\t\t{\n\t\t\tfilepath.Join(path, \"m1\", schemataFileName),\n\t\t\ttouch,\n\t\t},\n\t\t{\n\t\t\tfilepath.Join(path, \"m1\", tasksFileName),\n\t\t\ttouch,\n\t\t},\n\t\t{\n\t\t\tfilepath.Join(path, \"m1\", monGroupsDirName, \"test\"),\n\t\t\ttouchDir,\n\t\t},\n\t\t{\n\t\t\tfilepath.Join(path, \"m1\", monGroupsDirName, \"test\", tasksFileName),\n\t\t\ttouch,\n\t\t},\n\t}\n\tfor _, file := range files {\n\t\terr := file.touch(file.path)\n\t\tif err != nil {\n\t\t\treturn \"\"\n\t\t}\n\t}\n\n\t// Mock root group task file.\n\terr := fillPids(filepath.Join(path, tasksFileName), []int{1, 2, 3, 4})\n\tif err != nil {\n\t\treturn \"\"\n\t}\n\n\t// Mock custom CLOSID \"m1\" task file.\n\terr = fillPids(filepath.Join(path, \"m1\", tasksFileName), []int{5, 6, 7, 8, 9, 10})\n\tif err != nil {\n\t\treturn \"\"\n\t}\n\t// Mock custom mon group \"test\" task file.\n\terr = fillPids(filepath.Join(path, \"m1\", monGroupsDirName, \"test\", tasksFileName), []int{7, 8})\n\tif err != nil {\n\t\treturn \"\"\n\t}\n\n\treturn path\n}\n\nfunc mockResctrlMonData(path string) {\n\n\t_ = touchDir(filepath.Join(path, monDataDirName, \"mon_L3_00\"))\n\t_ = touchDir(filepath.Join(path, monDataDirName, \"mon_L3_01\"))\n\n\tvar files = []struct {\n\t\tpath  string\n\t\tvalue string\n\t}{\n\t\t{\n\t\t\tfilepath.Join(path, monDataDirName, \"mon_L3_00\", llcOccupancyFileName),\n\t\t\t\"1111\",\n\t\t},\n\t\t{\n\t\t\tfilepath.Join(path, monDataDirName, \"mon_L3_00\", mbmLocalBytesFileName),\n\t\t\t\"2222\",\n\t\t},\n\t\t{\n\t\t\tfilepath.Join(path, monDataDirName, \"mon_L3_00\", mbmTotalBytesFileName),\n\t\t\t\"3333\",\n\t\t},\n\t\t{\n\t\t\tfilepath.Join(path, monDataDirName, \"mon_L3_01\", llcOccupancyFileName),\n\t\t\t\"3333\",\n\t\t},\n\t\t{\n\t\t\tfilepath.Join(path, monDataDirName, \"mon_L3_01\", mbmLocalBytesFileName),\n\t\t\t\"1111\",\n\t\t},\n\t\t{\n\t\t\tfilepath.Join(path, monDataDirName, \"mon_L3_01\", mbmTotalBytesFileName),\n\t\t\t\"3333\",\n\t\t},\n\t}\n\n\tfor _, file := range files {\n\t\t_ = touch(file.path)\n\t\t_ = os.WriteFile(file.path, []byte(file.value), os.ModePerm)\n\t}\n}\n\nfunc mockContainersPids() string {\n\tpath, _ := os.MkdirTemp(\"\", \"cgroup\")\n\t// container\n\t_ = touchDir(filepath.Join(path, \"container\"))\n\t_ = touch(filepath.Join(path, \"container\", cgroups.CgroupProcesses))\n\terr := fillPids(filepath.Join(path, \"container\", cgroups.CgroupProcesses), []int{1, 2, 3})\n\tif err != nil {\n\t\treturn \"\"\n\t}\n\t// another\n\t_ = touchDir(filepath.Join(path, \"another\"))\n\t_ = touch(filepath.Join(path, \"another\", cgroups.CgroupProcesses))\n\terr = fillPids(filepath.Join(path, \"another\", cgroups.CgroupProcesses), []int{5})\n\tif err != nil {\n\t\treturn \"\"\n\t}\n\n\treturn path\n}\n\nfunc mockProcFs() string {\n\tpath, _ := os.MkdirTemp(\"\", \"proc\")\n\n\tvar files = []struct {\n\t\tpath  string\n\t\ttouch func(string) error\n\t}{\n\t\t// container\n\t\t{\n\t\t\tfilepath.Join(path, \"1\", processTask, \"1\"),\n\t\t\ttouchDir,\n\t\t},\n\t\t{\n\t\t\tfilepath.Join(path, \"2\", processTask, \"2\"),\n\t\t\ttouchDir,\n\t\t},\n\t\t{\n\t\t\tfilepath.Join(path, \"3\", processTask, \"3\"),\n\t\t\ttouchDir,\n\t\t},\n\t\t{\n\t\t\tfilepath.Join(path, \"4\", processTask, \"4\"),\n\t\t\ttouchDir,\n\t\t},\n\t\t// another\n\t\t{\n\t\t\tfilepath.Join(path, \"5\", processTask, \"5\"),\n\t\t\ttouchDir,\n\t\t},\n\t\t{\n\t\t\tfilepath.Join(path, \"6\", processTask, \"6\"),\n\t\t\ttouchDir,\n\t\t},\n\t}\n\n\tfor _, file := range files {\n\t\t_ = file.touch(file.path)\n\t}\n\n\treturn path\n}\n\nfunc checkError(t *testing.T, err error, expected string) {\n\tif expected != \"\" {\n\t\tassert.EqualError(t, err, expected)\n\t} else {\n\t\tassert.NoError(t, err)\n\t}\n}\n\nfunc TestPrepareMonitoringGroup(t *testing.T) {\n\trootResctrl = mockResctrl()\n\tdefer os.RemoveAll(rootResctrl)\n\n\tpidsPath = mockContainersPids()\n\tdefer os.RemoveAll(pidsPath)\n\n\tprocessPath = mockProcFs()\n\tdefer os.RemoveAll(processPath)\n\n\tvar testCases = []struct {\n\t\tcontainer        string\n\t\tgetContainerPids func() ([]string, error)\n\t\texpected         string\n\t\terr              string\n\t}{\n\t\t{\n\t\t\t\"container\",\n\t\t\tmockGetContainerPids,\n\t\t\tfilepath.Join(rootResctrl, monGroupsDirName, \"cadvisor-container\"),\n\t\t\t\"\",\n\t\t},\n\t\t{\n\t\t\t\"another\",\n\t\t\tmockAnotherGetContainerPids,\n\t\t\tfilepath.Join(rootResctrl, \"m1\", monGroupsDirName, \"cadvisor-another\"),\n\t\t\t\"\",\n\t\t},\n\t\t{\n\t\t\t\"/\",\n\t\t\tmockAllGetContainerPids,\n\t\t\trootResctrl,\n\t\t\t\"\",\n\t\t},\n\t}\n\n\tfor _, test := range testCases {\n\t\tactual, err := prepareMonitoringGroup(test.container, test.getContainerPids, true)\n\t\tassert.Equal(t, test.expected, actual)\n\t\tcheckError(t, err, test.err)\n\t}\n}\n\nfunc TestGetPids(t *testing.T) {\n\tpidsPath = mockContainersPids()\n\tdefer os.RemoveAll(pidsPath)\n\n\tvar testCases = []struct {\n\t\tcontainer string\n\t\texpected  []int\n\t\terr       string\n\t}{\n\t\t{\n\t\t\t\"\",\n\t\t\tnil,\n\t\t\tnoContainerNameError,\n\t\t},\n\t\t{\n\t\t\t\"container\",\n\t\t\t[]int{1, 2, 3},\n\t\t\t\"\",\n\t\t},\n\t\t{\n\t\t\t\"no_container\",\n\t\t\tnil,\n\t\t\tfmt.Sprintf(\"couldn't obtain pids for \\\"no_container\\\" container: lstat %v: no such file or directory\", filepath.Join(pidsPath, \"no_container\")),\n\t\t},\n\t}\n\n\tfor _, test := range testCases {\n\t\tactual, err := getPids(test.container)\n\t\tassert.Equal(t, test.expected, actual)\n\t\tcheckError(t, err, test.err)\n\t}\n}\n\nfunc TestGetAllProcessThreads(t *testing.T) {\n\tmockProcFs := func() string {\n\t\tpath, _ := os.MkdirTemp(\"\", \"proc\")\n\n\t\tvar files = []struct {\n\t\t\tpath  string\n\t\t\ttouch func(string) error\n\t\t}{\n\t\t\t// correct\n\t\t\t{\n\t\t\t\tfilepath.Join(path, \"4215\", processTask, \"4215\"),\n\t\t\t\ttouchDir,\n\t\t\t},\n\t\t\t{\n\t\t\t\tfilepath.Join(path, \"4215\", processTask, \"4216\"),\n\t\t\t\ttouchDir,\n\t\t\t},\n\t\t\t{\n\t\t\t\tfilepath.Join(path, \"4215\", processTask, \"4217\"),\n\t\t\t\ttouchDir,\n\t\t\t},\n\t\t\t{\n\t\t\t\tfilepath.Join(path, \"4215\", processTask, \"4218\"),\n\t\t\t\ttouchDir,\n\t\t\t},\n\t\t\t// invalid\n\t\t\t{\n\t\t\t\tfilepath.Join(path, \"301\", processTask, \"301\"),\n\t\t\t\ttouchDir,\n\t\t\t},\n\t\t\t{\n\t\t\t\tfilepath.Join(path, \"301\", processTask, \"incorrect\"),\n\t\t\t\ttouchDir,\n\t\t\t},\n\t\t}\n\n\t\tfor _, file := range files {\n\t\t\t_ = file.touch(file.path)\n\t\t}\n\n\t\treturn path\n\t}\n\n\tmockedProcFs := mockProcFs()\n\tdefer os.RemoveAll(mockedProcFs)\n\n\tvar testCases = []struct {\n\t\tpath     string\n\t\texpected []int\n\t\terr      string\n\t}{\n\t\t{\n\t\t\tfilepath.Join(mockedProcFs, \"4215\", processTask),\n\t\t\t[]int{4215, 4216, 4217, 4218},\n\t\t\t\"\",\n\t\t},\n\t\t{\n\t\t\tfilepath.Join(mockedProcFs, \"301\", processTask),\n\t\t\tnil,\n\t\t\t\"couldn't parse \\\"incorrect\\\" dir: strconv.Atoi: parsing \\\"incorrect\\\": invalid syntax\",\n\t\t},\n\t}\n\n\tfor _, test := range testCases {\n\t\tactual, err := getAllProcessThreads(test.path)\n\t\tassert.Equal(t, test.expected, actual)\n\t\tcheckError(t, err, test.err)\n\t}\n}\n\nfunc TestFindGroup(t *testing.T) {\n\trootResctrl = mockResctrl()\n\tdefer os.RemoveAll(rootResctrl)\n\n\tvar testCases = []struct {\n\t\tpath         string\n\t\tpids         []string\n\t\tincludeGroup bool\n\t\texclusive    bool\n\t\texpected     string\n\t\terr          string\n\t}{\n\t\t{\n\t\t\trootResctrl,\n\t\t\t[]string{\"1\", \"2\", \"3\", \"4\"},\n\t\t\ttrue,\n\t\t\tfalse,\n\t\t\trootResctrl,\n\t\t\t\"\",\n\t\t},\n\t\t{\n\t\t\trootResctrl,\n\t\t\t[]string{},\n\t\t\ttrue,\n\t\t\tfalse,\n\t\t\t\"\",\n\t\t\t\"there are no pids passed\",\n\t\t},\n\t\t{\n\t\t\trootResctrl,\n\t\t\t[]string{\"5\", \"6\"},\n\t\t\ttrue,\n\t\t\tfalse,\n\t\t\tfilepath.Join(rootResctrl, \"m1\"),\n\t\t\t\"\",\n\t\t},\n\t\t{\n\t\t\trootResctrl,\n\t\t\t[]string{\"11\", \"12\"},\n\t\t\ttrue,\n\t\t\tfalse,\n\t\t\t\"\",\n\t\t\t\"\",\n\t\t},\n\t\t{\n\t\t\tfilepath.Join(rootResctrl, \"m1\", monGroupsDirName),\n\t\t\t[]string{\"5\", \"6\"},\n\t\t\tfalse,\n\t\t\ttrue,\n\t\t\t\"\",\n\t\t\t\"\",\n\t\t},\n\t\t{\n\t\t\tfilepath.Join(rootResctrl, \"m1\", monGroupsDirName),\n\t\t\t[]string{\"7\", \"8\"},\n\t\t\tfalse,\n\t\t\ttrue,\n\t\t\tfilepath.Join(rootResctrl, \"m1\", monGroupsDirName, \"test\"),\n\t\t\t\"\",\n\t\t},\n\t\t{\n\t\t\tfilepath.Join(rootResctrl, \"m1\", monGroupsDirName),\n\t\t\t[]string{\"7\"},\n\t\t\tfalse,\n\t\t\ttrue,\n\t\t\t\"\",\n\t\t\t\"group should have container pids only\",\n\t\t},\n\t}\n\tfor _, test := range testCases {\n\t\tactual, err := findGroup(test.path, test.pids, test.includeGroup, test.exclusive)\n\t\tassert.Equal(t, test.expected, actual)\n\t\tcheckError(t, err, test.err)\n\t}\n}\n\nfunc TestArePIDsInGroup(t *testing.T) {\n\trootResctrl = mockResctrl()\n\tdefer os.RemoveAll(rootResctrl)\n\n\tvar testCases = []struct {\n\t\texpected  bool\n\t\terr       string\n\t\tpath      string\n\t\tpids      []string\n\t\texclusive bool\n\t}{\n\t\t{\n\t\t\ttrue,\n\t\t\t\"\",\n\t\t\trootResctrl,\n\t\t\t[]string{\"1\", \"2\"},\n\t\t\tfalse,\n\t\t},\n\t\t{\n\t\t\tfalse,\n\t\t\t\"there should be all pids in group\",\n\t\t\trootResctrl,\n\t\t\t[]string{\"4\", \"5\"},\n\t\t\tfalse,\n\t\t},\n\t\t{\n\t\t\tfalse,\n\t\t\t\"\",\n\t\t\tfilepath.Join(rootResctrl, \"m1\"),\n\t\t\t[]string{\"1\"},\n\t\t\tfalse,\n\t\t},\n\t\t{\n\t\t\tfalse,\n\t\t\tfmt.Sprintf(\"couldn't read tasks file from %q path: open %s: no such file or directory\", filepath.Join(rootResctrl, monitoringGroupDir, tasksFileName), filepath.Join(rootResctrl, monitoringGroupDir, tasksFileName)),\n\t\t\tfilepath.Join(rootResctrl, monitoringGroupDir),\n\t\t\t[]string{\"1\", \"2\"},\n\t\t\tfalse,\n\t\t},\n\t\t{\n\t\t\tfalse,\n\t\t\tfmt.Sprintf(\"couldn't obtain pids from %q path: %v\", rootResctrl, noPidsPassedError),\n\t\t\trootResctrl,\n\t\t\tnil,\n\t\t\tfalse,\n\t\t},\n\t}\n\n\tfor _, test := range testCases {\n\t\tactual, err := arePIDsInGroup(test.path, test.pids, test.exclusive)\n\t\tassert.Equal(t, test.expected, actual)\n\t\tcheckError(t, err, test.err)\n\t}\n}\n\nfunc TestGetStats(t *testing.T) {\n\trootResctrl = mockResctrl()\n\tdefer os.RemoveAll(rootResctrl)\n\n\tpidsPath = mockContainersPids()\n\tdefer os.RemoveAll(pidsPath)\n\n\tprocessPath = mockProcFs()\n\tdefer os.RemoveAll(processPath)\n\n\tenabledCMT, enabledMBM = true, true\n\n\tvar testCases = []struct {\n\t\tcontainer string\n\t\texpected  intelrdt.Stats\n\t\terr       string\n\t}{\n\t\t{\n\t\t\t\"container\",\n\t\t\tintelrdt.Stats{\n\t\t\t\tMBMStats: &[]intelrdt.MBMNumaNodeStats{\n\t\t\t\t\t{\n\t\t\t\t\t\tMBMTotalBytes: 3333,\n\t\t\t\t\t\tMBMLocalBytes: 2222,\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tMBMTotalBytes: 3333,\n\t\t\t\t\t\tMBMLocalBytes: 1111,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tCMTStats: &[]intelrdt.CMTNumaNodeStats{\n\t\t\t\t\t{\n\t\t\t\t\t\tLLCOccupancy: 1111,\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tLLCOccupancy: 3333,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\t\"\",\n\t\t},\n\t\t{\n\t\t\t\"another\",\n\t\t\tintelrdt.Stats{\n\t\t\t\tMBMStats: &[]intelrdt.MBMNumaNodeStats{\n\t\t\t\t\t{\n\t\t\t\t\t\tMBMTotalBytes: 3333,\n\t\t\t\t\t\tMBMLocalBytes: 2222,\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tMBMTotalBytes: 3333,\n\t\t\t\t\t\tMBMLocalBytes: 1111,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tCMTStats: &[]intelrdt.CMTNumaNodeStats{\n\t\t\t\t\t{\n\t\t\t\t\t\tLLCOccupancy: 1111,\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tLLCOccupancy: 3333,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\t\"\",\n\t\t},\n\t\t{\n\t\t\t\"/\",\n\t\t\tintelrdt.Stats{\n\t\t\t\tMBMStats: &[]intelrdt.MBMNumaNodeStats{\n\t\t\t\t\t{\n\t\t\t\t\t\tMBMTotalBytes: 3333,\n\t\t\t\t\t\tMBMLocalBytes: 2222,\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tMBMTotalBytes: 3333,\n\t\t\t\t\t\tMBMLocalBytes: 1111,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tCMTStats: &[]intelrdt.CMTNumaNodeStats{\n\t\t\t\t\t{\n\t\t\t\t\t\tLLCOccupancy: 1111,\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tLLCOccupancy: 3333,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\t\"\",\n\t\t},\n\t}\n\n\tfor _, test := range testCases {\n\t\tcontainerPath, _ := prepareMonitoringGroup(test.container, mockGetContainerPids, true)\n\t\tmockResctrlMonData(containerPath)\n\t\tactual, err := getIntelRDTStatsFrom(containerPath, \"\")\n\t\tcheckError(t, err, test.err)\n\t\tassert.Equal(t, test.expected.CMTStats, actual.CMTStats)\n\t\tassert.Equal(t, test.expected.MBMStats, actual.MBMStats)\n\t}\n}\n\nfunc TestReadTasksFile(t *testing.T) {\n\tvar testCases = []struct {\n\t\ttasksFile string\n\t\texpected  map[string]struct{}\n\t\terr       string\n\t}{\n\t\t{\"testing/tasks_two\",\n\t\t\tmap[string]struct{}{\n\t\t\t\t\"12\": {},\n\t\t\t\t\"77\": {},\n\t\t\t},\n\t\t\t\"\",\n\t\t},\n\t\t{\"testing/tasks_one\",\n\t\t\tmap[string]struct{}{\n\t\t\t\t\"2\": {},\n\t\t\t},\n\t\t\t\"\",\n\t\t},\n\t\t{\"testing/tasks_empty\",\n\t\t\tmap[string]struct{}{},\n\t\t\t\"\",\n\t\t},\n\t}\n\n\tfor _, test := range testCases {\n\t\tactual, err := readTasksFile(test.tasksFile)\n\t\tassert.Equal(t, test.expected, actual)\n\t\tcheckError(t, err, test.err)\n\t}\n}\n"
  },
  {
    "path": "stats/noop.go",
    "content": "// Copyright 2020 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n// Noop perf Manager and Collector.\npackage stats\n\nimport (\n\t\"k8s.io/klog/v2\"\n\n\tv1 \"github.com/google/cadvisor/info/v1\"\n)\n\ntype NoopManager struct {\n\tNoopDestroy\n}\n\ntype NoopDestroy struct{}\n\nfunc (nsd NoopDestroy) Destroy() {\n\tklog.V(5).Info(\"No-op Destroy function called\")\n}\n\nfunc (m *NoopManager) GetCollector(cgroup string) (Collector, error) {\n\treturn &NoopCollector{}, nil\n}\n\ntype NoopCollector struct {\n\tNoopDestroy\n}\n\nfunc (c *NoopCollector) UpdateStats(stats *v1.ContainerStats) error {\n\treturn nil\n}\n"
  },
  {
    "path": "stats/types.go",
    "content": "// Copyright 2020 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n// Handling statistics that are fully controlled in cAdvisor\npackage stats\n\nimport info \"github.com/google/cadvisor/info/v1\"\n\n// This is supposed to store global state about an cAdvisor metrics collector.\n// cAdvisor manager will call Destroy() when it stops.\n// For each container detected by the cAdvisor manager, it will call\n// GetCollector() with the devices cgroup path for that container.\n// GetCollector() is supposed to return an object that can update\n// external stats for that container.\ntype Manager interface {\n\tDestroy()\n\tGetCollector(deviceCgroup string) (Collector, error)\n}\n\n// Collector can update ContainerStats by adding more metrics.\ntype Collector interface {\n\tDestroy()\n\tUpdateStats(*info.ContainerStats) error\n}\n"
  },
  {
    "path": "storage/common_flags.go",
    "content": "// Copyright 2015 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage storage\n\nimport (\n\t\"flag\"\n\t\"time\"\n)\n\nvar ArgDbUsername = flag.String(\"storage_driver_user\", \"root\", \"database username\")\nvar ArgDbPassword = flag.String(\"storage_driver_password\", \"root\", \"database password\")\nvar ArgDbHost = flag.String(\"storage_driver_host\", \"localhost:8086\", \"database host:port\")\nvar ArgDbName = flag.String(\"storage_driver_db\", \"cadvisor\", \"database name\")\nvar ArgDbTable = flag.String(\"storage_driver_table\", \"stats\", \"table name\")\nvar ArgDbIsSecure = flag.Bool(\"storage_driver_secure\", false, \"use secure connection with database\")\nvar ArgDbBufferDuration = flag.Duration(\"storage_driver_buffer_duration\", 60*time.Second, \"Writes in the storage driver will be buffered for this duration, and committed to the non memory backends as a single transaction\")\n"
  },
  {
    "path": "storage/storage.go",
    "content": "// Copyright 2014 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage storage\n\nimport (\n\t\"fmt\"\n\t\"sort\"\n\n\tinfo \"github.com/google/cadvisor/info/v1\"\n)\n\ntype StorageDriver interface {\n\tAddStats(cInfo *info.ContainerInfo, stats *info.ContainerStats) error\n\n\t// Close will clear the state of the storage driver. The elements\n\t// stored in the underlying storage may or may not be deleted depending\n\t// on the implementation of the storage driver.\n\tClose() error\n}\n\ntype StorageDriverFunc func() (StorageDriver, error)\n\nvar registeredPlugins = map[string](StorageDriverFunc){}\n\nfunc RegisterStorageDriver(name string, f StorageDriverFunc) {\n\tregisteredPlugins[name] = f\n}\n\nfunc New(name string) (StorageDriver, error) {\n\tif name == \"\" {\n\t\treturn nil, nil\n\t}\n\tf, ok := registeredPlugins[name]\n\tif !ok {\n\t\treturn nil, fmt.Errorf(\"unknown backend storage driver: %s\", name)\n\t}\n\treturn f()\n}\n\nfunc ListDrivers() []string {\n\tdrivers := make([]string, 0, len(registeredPlugins))\n\tfor name := range registeredPlugins {\n\t\tdrivers = append(drivers, name)\n\t}\n\tsort.Strings(drivers)\n\treturn drivers\n}\n"
  },
  {
    "path": "summary/buffer.go",
    "content": "// Copyright 2015 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage summary\n\nimport (\n\tinfo \"github.com/google/cadvisor/info/v2\"\n)\n\n// Manages a buffer of usage samples.\n// This is similar to stats buffer in cache/memory.\n// The main difference is that we do not pre-allocate the buffer as most containers\n// won't live that long.\ntype SamplesBuffer struct {\n\t// list of collected samples.\n\tsamples []info.Usage\n\t// maximum size this buffer can grow to.\n\tmaxSize int\n\t// index for the latest sample.\n\tindex int\n}\n\n// Initializes an empty buffer.\nfunc NewSamplesBuffer(size int) *SamplesBuffer {\n\treturn &SamplesBuffer{\n\t\tindex:   -1,\n\t\tmaxSize: size,\n\t}\n}\n\n// Returns the current number of samples in the buffer.\nfunc (s *SamplesBuffer) Size() int {\n\treturn len(s.samples)\n}\n\n// Add an element to the buffer. Oldest one is overwritten if required.\nfunc (s *SamplesBuffer) Add(stat info.Usage) {\n\tif len(s.samples) < s.maxSize {\n\t\ts.samples = append(s.samples, stat)\n\t\ts.index++\n\t\treturn\n\t}\n\ts.index = (s.index + 1) % s.maxSize\n\ts.samples[s.index] = stat\n}\n\n// Returns pointers to the last 'n' stats.\nfunc (s *SamplesBuffer) RecentStats(n int) []*info.Usage {\n\tif n > len(s.samples) {\n\t\tn = len(s.samples)\n\t}\n\tstart := s.index - (n - 1)\n\tif start < 0 {\n\t\tstart += len(s.samples)\n\t}\n\n\tout := make([]*info.Usage, n)\n\tfor i := 0; i < n; i++ {\n\t\tindex := (start + i) % len(s.samples)\n\t\tout[i] = &s.samples[index]\n\t}\n\treturn out\n}\n"
  },
  {
    "path": "summary/buffer_test.go",
    "content": "// Copyright 2015 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage summary\n\nimport (\n\t\"reflect\"\n\t\"testing\"\n\n\tinfo \"github.com/google/cadvisor/info/v2\"\n)\n\nfunc createSample(i uint64) info.Usage {\n\tusage := info.Usage{}\n\tusage.PercentComplete = 100\n\tusage.Cpu = info.Percentiles{\n\t\tPresent: true,\n\t\tMean:    i * 50,\n\t\tMax:     i * 100,\n\t\tNinety:  i * 90,\n\t}\n\tusage.Memory = info.Percentiles{\n\t\tPresent: true,\n\t\tMean:    i * 50 * 1024,\n\t\tMax:     i * 100 * 1024,\n\t\tNinety:  i * 90 * 1024,\n\t}\n\treturn usage\n}\n\nfunc expectSize(t *testing.T, b *SamplesBuffer, expectedSize int) {\n\tif b.Size() != expectedSize {\n\t\tt.Errorf(\"Expected size %d, got %d\", expectedSize, b.Size())\n\t}\n}\n\nfunc expectElements(t *testing.T, b *SamplesBuffer, expected []info.Usage) {\n\n\tout := b.RecentStats(b.Size())\n\tif len(out) != len(expected) {\n\t\tt.Errorf(\"Expected %d elements, got %d\", len(expected), len(out))\n\t}\n\tfor i, el := range out {\n\t\tif !reflect.DeepEqual(*el, expected[i]) {\n\t\t\tt.Errorf(\"Expected elements %v, got %v\", expected[i], *el)\n\t\t}\n\t}\n}\n\nfunc TestEmpty(t *testing.T) {\n\tb := NewSamplesBuffer(5)\n\texpectSize(t, b, 0)\n\texpectElements(t, b, []info.Usage{})\n}\n\nfunc TestAddSingleSample(t *testing.T) {\n\tb := NewSamplesBuffer(5)\n\n\tsample := createSample(1)\n\tb.Add(sample)\n\texpectSize(t, b, 1)\n\texpectElements(t, b, []info.Usage{sample})\n}\n\nfunc TestFullBuffer(t *testing.T) {\n\tmaxSize := 5\n\tb := NewSamplesBuffer(maxSize)\n\tsamples := []info.Usage{}\n\tfor i := 0; i < maxSize; i++ {\n\t\tsample := createSample(uint64(i))\n\t\tsamples = append(samples, sample)\n\t\tb.Add(sample)\n\t}\n\texpectSize(t, b, maxSize)\n\texpectElements(t, b, samples)\n}\n\nfunc TestOverflow(t *testing.T) {\n\tmaxSize := 5\n\toverflow := 2\n\tb := NewSamplesBuffer(maxSize)\n\tsamples := []info.Usage{}\n\tfor i := 0; i < maxSize+overflow; i++ {\n\t\tsample := createSample(uint64(i))\n\t\tif i >= overflow {\n\t\t\tsamples = append(samples, sample)\n\t\t}\n\t\tb.Add(sample)\n\t}\n\texpectSize(t, b, maxSize)\n\texpectElements(t, b, samples)\n}\n\nfunc TestReplaceAll(t *testing.T) {\n\tmaxSize := 5\n\tb := NewSamplesBuffer(maxSize)\n\tsamples := []info.Usage{}\n\tfor i := 0; i < maxSize*2; i++ {\n\t\tsample := createSample(uint64(i))\n\t\tif i >= maxSize {\n\t\t\tsamples = append(samples, sample)\n\t\t}\n\t\tb.Add(sample)\n\t}\n\texpectSize(t, b, maxSize)\n\texpectElements(t, b, samples)\n}\n"
  },
  {
    "path": "summary/percentiles.go",
    "content": "// Copyright 2015 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n// Utility methods to calculate percentiles.\n\npackage summary\n\nimport (\n\t\"fmt\"\n\t\"math\"\n\t\"sort\"\n\n\tinfo \"github.com/google/cadvisor/info/v2\"\n)\n\nconst secondsToMilliSeconds = 1000\nconst milliSecondsToNanoSeconds = 1000000\nconst secondsToNanoSeconds = secondsToMilliSeconds * milliSecondsToNanoSeconds\n\ntype Uint64Slice []uint64\n\nfunc (s Uint64Slice) Len() int           { return len(s) }\nfunc (s Uint64Slice) Swap(i, j int)      { s[i], s[j] = s[j], s[i] }\nfunc (s Uint64Slice) Less(i, j int) bool { return s[i] < s[j] }\n\n// Get percentile of the provided samples. Round to integer.\nfunc (s Uint64Slice) GetPercentile(d float64) uint64 {\n\tif d < 0.0 || d > 1.0 {\n\t\treturn 0\n\t}\n\tcount := s.Len()\n\tif count == 0 {\n\t\treturn 0\n\t}\n\tsort.Sort(s)\n\tn := float64(d * (float64(count) + 1))\n\tidx, frac := math.Modf(n)\n\tindex := int(idx)\n\tpercentile := float64(s[index-1])\n\tif index > 1 && index < count {\n\t\tpercentile += frac * float64(s[index]-s[index-1])\n\t}\n\treturn uint64(percentile)\n}\n\ntype mean struct {\n\t// current count.\n\tcount uint64\n\t// current mean.\n\tMean float64\n}\n\nfunc (m *mean) Add(value uint64) {\n\tm.count++\n\tif m.count == 1 {\n\t\tm.Mean = float64(value)\n\t\treturn\n\t}\n\tc := float64(m.count)\n\tv := float64(value)\n\tm.Mean = (m.Mean*(c-1) + v) / c\n}\n\ntype Percentile interface {\n\tAdd(info.Percentiles)\n\tAddSample(uint64)\n\tGetAllPercentiles() info.Percentiles\n}\n\ntype resource struct {\n\t// list of samples being tracked.\n\tsamples Uint64Slice\n\t// average from existing samples.\n\tmean mean\n\t// maximum value seen so far in the added samples.\n\tmax uint64\n}\n\n// Adds a new percentile sample.\nfunc (r *resource) Add(p info.Percentiles) {\n\tif !p.Present {\n\t\treturn\n\t}\n\tif p.Max > r.max {\n\t\tr.max = p.Max\n\t}\n\tr.mean.Add(p.Mean)\n\t// Selecting 90p of 90p :(\n\tr.samples = append(r.samples, p.Ninety)\n}\n\n// Add a single sample. Internally, we convert it to a fake percentile sample.\nfunc (r *resource) AddSample(val uint64) {\n\tsample := info.Percentiles{\n\t\tPresent:    true,\n\t\tMean:       val,\n\t\tStd:        0,\n\t\tMax:        val,\n\t\tFifty:      val,\n\t\tNinety:     val,\n\t\tNinetyFive: val,\n\t\tCount:      1,\n\t}\n\tr.Add(sample)\n}\n\n// Get max, average, and 90p from existing samples.\nfunc (r *resource) GetAllPercentiles() info.Percentiles {\n\tp := info.Percentiles{}\n\tp.Mean = uint64(r.mean.Mean)\n\tp.Std = uint64(r.samples.getStandardDeviation(r.mean.Mean))\n\tp.Max = r.max\n\tp.Fifty = r.samples.GetPercentile(0.5)\n\tp.Ninety = r.samples.GetPercentile(0.9)\n\tp.NinetyFive = r.samples.GetPercentile(0.95)\n\t// len(samples) is equal to count stored in mean.\n\tp.Count = r.mean.count\n\tp.Present = true\n\treturn p\n}\n\nfunc NewResource(size int) Percentile {\n\treturn &resource{\n\t\tsamples: make(Uint64Slice, 0, size),\n\t\tmean:    mean{count: 0, Mean: 0},\n\t}\n}\n\n// Return aggregated percentiles from the provided percentile samples.\nfunc GetDerivedPercentiles(stats []*info.Usage) info.Usage {\n\tcpu := NewResource(len(stats))\n\tmemory := NewResource(len(stats))\n\tfor _, stat := range stats {\n\t\tcpu.Add(stat.Cpu)\n\t\tmemory.Add(stat.Memory)\n\t}\n\tusage := info.Usage{}\n\tusage.Cpu = cpu.GetAllPercentiles()\n\tusage.Memory = memory.GetAllPercentiles()\n\treturn usage\n}\n\n// Calculate part of a minute this sample set represent.\nfunc getPercentComplete(stats []*secondSample) (percent int32) {\n\tnumSamples := len(stats)\n\tif numSamples > 1 {\n\t\tpercent = 100\n\t\ttimeRange := stats[numSamples-1].Timestamp.Sub(stats[0].Timestamp).Nanoseconds()\n\t\t// allow some slack\n\t\tif timeRange < 58*secondsToNanoSeconds {\n\t\t\tpercent = int32((timeRange * 100) / 60 * secondsToNanoSeconds)\n\t\t}\n\t}\n\treturn\n}\n\nfunc (s Uint64Slice) getStandardDeviation(mean float64) float64 {\n\tn := len(s)\n\tif n <= 1 {\n\t\treturn 0\n\t}\n\tvar ss float64\n\tfor _, v := range s {\n\t\td := float64(v) - mean\n\t\tss += d * d\n\t}\n\t// Use Bessel's correction (n-1) to calculate sample standard deviation.\n\t// This provides an unbiased estimate of population variance from sample data.\n\treturn math.Sqrt(ss / float64(n-1))\n}\n\n// Calculate cpurate from two consecutive total cpu usage samples.\nfunc getCPURate(latest, previous secondSample) (uint64, error) {\n\telapsed := latest.Timestamp.Sub(previous.Timestamp).Nanoseconds()\n\tif elapsed < 10*milliSecondsToNanoSeconds {\n\t\treturn 0, fmt.Errorf(\"elapsed time too small: %d ns: time now %s last %s\", elapsed, latest.Timestamp.String(), previous.Timestamp.String())\n\t}\n\tif latest.Cpu < previous.Cpu {\n\t\treturn 0, fmt.Errorf(\"bad sample: cumulative cpu usage dropped from %d to %d\", latest.Cpu, previous.Cpu)\n\t}\n\t// Cpurate is calculated in cpu-milliseconds per second.\n\tcpuRate := (latest.Cpu - previous.Cpu) * secondsToMilliSeconds / uint64(elapsed)\n\treturn cpuRate, nil\n}\n\n// Returns a percentile sample for a minute by aggregating seconds samples.\nfunc GetMinutePercentiles(stats []*secondSample) info.Usage {\n\tlastSample := secondSample{}\n\tcpu := NewResource(len(stats))\n\tmemory := NewResource(len(stats))\n\tfor _, stat := range stats {\n\t\tif !lastSample.Timestamp.IsZero() {\n\t\t\tcpuRate, err := getCPURate(*stat, lastSample)\n\t\t\tif err != nil {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tcpu.AddSample(cpuRate)\n\t\t\tmemory.AddSample(stat.Memory)\n\t\t} else {\n\t\t\tmemory.AddSample(stat.Memory)\n\t\t}\n\t\tlastSample = *stat\n\t}\n\tpercent := getPercentComplete(stats)\n\treturn info.Usage{\n\t\tPercentComplete: percent,\n\t\tCpu:             cpu.GetAllPercentiles(),\n\t\tMemory:          memory.GetAllPercentiles(),\n\t}\n}\n"
  },
  {
    "path": "summary/percentiles_test.go",
    "content": "// Copyright 2015 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage summary\n\nimport (\n\t\"math\"\n\t\"testing\"\n\t\"time\"\n\n\tinfo \"github.com/google/cadvisor/info/v2\"\n)\n\nconst (\n\tNanosecond = 1000000000\n\tN          = 100\n\t// Standard deviation of the sequence [1..99] using sample standard deviation formula.\n\t// N = 100 in every test\n\t// This is sqrt(Σ(i - 50)² / 98) where i ∈ [1,99], mean = 50, n = 99.\n\tStdDevFactor = 28.722813232\n)\n\nfunc assertPercentile(t *testing.T, s Uint64Slice, f float64, want uint64) {\n\tif got := s.GetPercentile(f); got != want {\n\t\tt.Errorf(\"GetPercentile(%f) is %d, should be %d.\", f, got, want)\n\t}\n}\n\nfunc TestPercentile(t *testing.T) {\n\ts := make(Uint64Slice, 0, N)\n\tfor i := N; i > 0; i-- {\n\t\ts = append(s, uint64(i))\n\t}\n\tassertPercentile(t, s, 0.2, 20)\n\tassertPercentile(t, s, 0.7, 70)\n\tassertPercentile(t, s, 0.9, 90)\n\tfor i := 101; i <= N+5; i++ {\n\t\ts = append(s, uint64(i))\n\t}\n\t// 90p should be between 94 and 95. Promoted to 95.\n\tassertPercentile(t, s, 0.2, 21)\n\tassertPercentile(t, s, 0.7, 74)\n\tassertPercentile(t, s, 0.9, 95)\n}\n\nfunc TestMean(t *testing.T) {\n\tvar i uint64\n\tmean := mean{count: 0, Mean: 0}\n\tfor i = 1; i < N; i++ {\n\t\tmean.Add(i)\n\t}\n\tif mean.Mean != 50.0 {\n\t\tt.Errorf(\"Mean is %f, should be 50.0\", mean.Mean)\n\t}\n}\n\nfunc TestAggregates(t *testing.T) {\n\tvar i uint64\n\tct := time.Now()\n\tstats := make([]*secondSample, 0, N)\n\tfor i = 1; i < N; i++ {\n\t\ts := &secondSample{\n\t\t\tTimestamp: ct.Add(time.Duration(i) * time.Second),\n\t\t\t// cpu rate is 1 s/s\n\t\t\tCpu: i * Nanosecond,\n\t\t\t// Memory grows by a KB every second.\n\t\t\tMemory: i * 1024,\n\t\t}\n\t\tstats = append(stats, s)\n\t}\n\tusage := GetMinutePercentiles(stats)\n\t// Cpu mean, max, and 90p should all be 1000 ms/s.\n\tcpuExpected := info.Percentiles{\n\t\tPresent:    true,\n\t\tMean:       1000,\n\t\tStd:        0,\n\t\tMax:        1000,\n\t\tFifty:      1000,\n\t\tNinety:     1000,\n\t\tNinetyFive: 1000,\n\t\t// Since cpu is calculated between samples, we lose 1 sample.\n\t\tCount: N - 2,\n\t}\n\tif usage.Cpu != cpuExpected {\n\t\tt.Errorf(\"cpu stats are %+v. Expected %+v\", usage.Cpu, cpuExpected)\n\t}\n\tmemExpected := info.Percentiles{\n\t\tPresent:    true,\n\t\tMean:       50 * 1024,\n\t\tStd:        uint64(math.Round(StdDevFactor * 1024)),\n\t\tMax:        99 * 1024,\n\t\tFifty:      50 * 1024,\n\t\tNinety:     90 * 1024,\n\t\tNinetyFive: 95 * 1024,\n\t\tCount:      N - 1,\n\t}\n\tif usage.Memory != memExpected {\n\t\tt.Errorf(\"memory stats are mean %+v. Expected %+v\", usage.Memory, memExpected)\n\t}\n}\nfunc TestSamplesCloseInTimeIgnored(t *testing.T) {\n\tvar i uint64\n\tct := time.Now()\n\tstats := make([]*secondSample, 0, N*2)\n\tfor i = 1; i < N; i++ {\n\t\ts1 := &secondSample{\n\t\t\tTimestamp: ct.Add(time.Duration(i) * time.Second),\n\t\t\t// cpu rate is 1 s/s\n\t\t\tCpu: i * Nanosecond,\n\t\t\t// Memory grows by a KB every second.\n\t\t\tMemory: i * 1024,\n\t\t}\n\t\tstats = append(stats, s1)\n\n\t\t// Add another dummy sample too close in time to the last one.\n\t\ts2 := &secondSample{\n\t\t\t// Add extra millisecond.\n\t\t\tTimestamp: ct.Add(time.Duration(i) * time.Second).Add(time.Duration(1) * time.Millisecond),\n\t\t\tCpu:       i * 100 * Nanosecond,\n\t\t\tMemory:    i * 1024 * 1024,\n\t\t}\n\t\tstats = append(stats, s2)\n\t}\n\tusage := GetMinutePercentiles(stats)\n\t// Cpu mean, max, and 90p should all be 1000 ms/s. All high-value samples are discarded.\n\tcpuExpected := info.Percentiles{\n\t\tPresent:    true,\n\t\tMean:       1000,\n\t\tStd:        0,\n\t\tMax:        1000,\n\t\tFifty:      1000,\n\t\tNinety:     1000,\n\t\tNinetyFive: 1000,\n\t\t// Since cpu is calculated between samples, we lose 1 sample.\n\t\tCount: N - 2,\n\t}\n\tif usage.Cpu != cpuExpected {\n\t\tt.Errorf(\"cpu stats are %+v. Expected %+v\", usage.Cpu, cpuExpected)\n\t}\n\tmemExpected := info.Percentiles{\n\t\tPresent:    true,\n\t\tMean:       50 * 1024,\n\t\tStd:        uint64(math.Round(StdDevFactor * 1024)),\n\t\tMax:        99 * 1024,\n\t\tFifty:      50 * 1024,\n\t\tNinety:     90 * 1024,\n\t\tNinetyFive: 95 * 1024,\n\t\tCount:      N - 1,\n\t}\n\tif usage.Memory != memExpected {\n\t\tt.Errorf(\"memory stats are mean %+v. Expected %+v\", usage.Memory, memExpected)\n\t}\n}\n\nfunc TestDerivedStats(t *testing.T) {\n\tvar i uint64\n\tstats := make([]*info.Usage, 0, N)\n\tfor i = 1; i < N; i++ {\n\t\ts := &info.Usage{\n\t\t\tPercentComplete: 100,\n\t\t\tCpu: info.Percentiles{\n\t\t\t\tPresent:    true,\n\t\t\t\tMean:       i * Nanosecond,\n\t\t\t\tMax:        i * Nanosecond,\n\t\t\t\tFifty:      i * Nanosecond,\n\t\t\t\tNinety:     i * Nanosecond,\n\t\t\t\tNinetyFive: i * Nanosecond,\n\t\t\t},\n\t\t\tMemory: info.Percentiles{\n\t\t\t\tPresent:    true,\n\t\t\t\tMean:       i * 1024,\n\t\t\t\tMax:        i * 1024,\n\t\t\t\tFifty:      i * 1024,\n\t\t\t\tNinety:     i * 1024,\n\t\t\t\tNinetyFive: i * 1024,\n\t\t\t},\n\t\t}\n\t\tstats = append(stats, s)\n\t}\n\tusage := GetDerivedPercentiles(stats)\n\tcpuExpected := info.Percentiles{\n\t\tPresent:    true,\n\t\tMean:       50 * Nanosecond,\n\t\tStd:        uint64(math.Round(StdDevFactor * Nanosecond)),\n\t\tMax:        99 * Nanosecond,\n\t\tFifty:      50 * Nanosecond,\n\t\tNinety:     90 * Nanosecond,\n\t\tNinetyFive: 95 * Nanosecond,\n\t\t// GetDerivedPercentiles calculates directly from samples, hence we don't lose any samples.\n\t\tCount: N - 1,\n\t}\n\tif usage.Cpu != cpuExpected {\n\t\tt.Errorf(\"cpu stats are %+v. Expected %+v\", usage.Cpu, cpuExpected)\n\t}\n\tmemExpected := info.Percentiles{\n\t\tPresent:    true,\n\t\tMean:       50 * 1024,\n\t\tStd:        uint64(math.Round(StdDevFactor * 1024)),\n\t\tMax:        99 * 1024,\n\t\tFifty:      50 * 1024,\n\t\tNinety:     90 * 1024,\n\t\tNinetyFive: 95 * 1024,\n\t\tCount:      N - 1,\n\t}\n\tif usage.Memory != memExpected {\n\t\tt.Errorf(\"memory stats are mean %+v. Expected %+v\", usage.Memory, memExpected)\n\t}\n}\n"
  },
  {
    "path": "summary/summary.go",
    "content": "// Copyright 2015 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n// Maintains the summary of aggregated minute, hour, and day stats.\n// For a container running for more than a day, amount of tracked data can go up to\n// 40 KB when cpu and memory are tracked. We'll start by enabling collection for the\n// node, followed by docker, and then all containers as we understand the usage pattern\n// better\n// TODO(rjnagal): Optimize the size if we start running it for every container.\npackage summary\n\nimport (\n\t\"fmt\"\n\t\"sync\"\n\t\"time\"\n\n\tv1 \"github.com/google/cadvisor/info/v1\"\n\tinfo \"github.com/google/cadvisor/info/v2\"\n)\n\n// Usage fields we track for generating percentiles.\ntype secondSample struct {\n\tTimestamp time.Time // time when the sample was recorded.\n\tCpu       uint64    // cpu usage\n\tMemory    uint64    // memory usage\n}\n\ntype availableResources struct {\n\tCpu    bool\n\tMemory bool\n}\n\ntype StatsSummary struct {\n\t// Resources being tracked for this container.\n\tavailable availableResources\n\t// list of second samples. The list is cleared when a new minute samples is generated.\n\tsecondSamples []*secondSample\n\t// minute percentiles. We track 24 * 60 maximum samples.\n\tminuteSamples *SamplesBuffer\n\t// latest derived instant, minute, hour, and day stats. Instant sample updated every second.\n\t// Others updated every minute.\n\tderivedStats info.DerivedStats // Guarded by dataLock.\n\tdataLock     sync.RWMutex\n}\n\n// Adds a new seconds sample.\n// If enough seconds samples are collected, a minute sample is generated and derived\n// stats are updated.\nfunc (s *StatsSummary) AddSample(stat v1.ContainerStats) error {\n\tsample := secondSample{}\n\tsample.Timestamp = stat.Timestamp\n\tif s.available.Cpu {\n\t\tsample.Cpu = stat.Cpu.Usage.Total\n\t}\n\tif s.available.Memory {\n\t\tsample.Memory = stat.Memory.WorkingSet\n\t}\n\ts.secondSamples = append(s.secondSamples, &sample)\n\ts.updateLatestUsage()\n\t// TODO(jnagal): Use 'available' to avoid unnecessary computation.\n\tnumSamples := len(s.secondSamples)\n\telapsed := time.Nanosecond\n\tif numSamples > 1 {\n\t\tstart := s.secondSamples[0].Timestamp\n\t\tend := s.secondSamples[numSamples-1].Timestamp\n\t\telapsed = end.Sub(start)\n\t}\n\tif elapsed > 60*time.Second {\n\t\t// Make a minute sample. This works with dynamic housekeeping as long\n\t\t// as we keep max dynamic housekeeping period close to a minute.\n\t\tminuteSample := GetMinutePercentiles(s.secondSamples)\n\t\t// Clear seconds samples. Keep the latest sample for continuity.\n\t\t// Copying and resizing helps avoid slice re-allocation.\n\t\ts.secondSamples[0] = s.secondSamples[numSamples-1]\n\t\ts.secondSamples = s.secondSamples[:1]\n\t\ts.minuteSamples.Add(minuteSample)\n\t\terr := s.updateDerivedStats()\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc (s *StatsSummary) updateLatestUsage() {\n\tusage := info.InstantUsage{}\n\tnumStats := len(s.secondSamples)\n\tif numStats < 1 {\n\t\treturn\n\t}\n\tlatest := s.secondSamples[numStats-1]\n\tusage.Memory = latest.Memory\n\tif numStats > 1 {\n\t\tprevious := s.secondSamples[numStats-2]\n\t\tcpu, err := getCPURate(*latest, *previous)\n\t\tif err == nil {\n\t\t\tusage.Cpu = cpu\n\t\t}\n\t}\n\n\ts.dataLock.Lock()\n\tdefer s.dataLock.Unlock()\n\ts.derivedStats.LatestUsage = usage\n\ts.derivedStats.Timestamp = latest.Timestamp\n}\n\n// Generate new derived stats based on current minute stats samples.\nfunc (s *StatsSummary) updateDerivedStats() error {\n\tderived := info.DerivedStats{}\n\tderived.Timestamp = time.Now()\n\tminuteSamples := s.minuteSamples.RecentStats(1)\n\tif len(minuteSamples) != 1 {\n\t\treturn fmt.Errorf(\"failed to retrieve minute stats\")\n\t}\n\tderived.MinuteUsage = *minuteSamples[0]\n\thourUsage, err := s.getDerivedUsage(60)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to compute hour stats: %v\", err)\n\t}\n\tdayUsage, err := s.getDerivedUsage(60 * 24)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to compute day usage: %v\", err)\n\t}\n\tderived.HourUsage = hourUsage\n\tderived.DayUsage = dayUsage\n\n\ts.dataLock.Lock()\n\tdefer s.dataLock.Unlock()\n\tderived.LatestUsage = s.derivedStats.LatestUsage\n\ts.derivedStats = derived\n\n\treturn nil\n}\n\n// helper method to get hour and daily derived stats\nfunc (s *StatsSummary) getDerivedUsage(n int) (info.Usage, error) {\n\tif n < 1 {\n\t\treturn info.Usage{}, fmt.Errorf(\"invalid number of samples requested: %d\", n)\n\t}\n\tsamples := s.minuteSamples.RecentStats(n)\n\tnumSamples := len(samples)\n\tif numSamples < 1 {\n\t\treturn info.Usage{}, fmt.Errorf(\"failed to retrieve any minute stats\")\n\t}\n\t// We generate derived stats even with partial data.\n\tusage := GetDerivedPercentiles(samples)\n\t// Assumes we have equally placed minute samples.\n\tusage.PercentComplete = int32(numSamples * 100 / n)\n\treturn usage, nil\n}\n\n// Return the latest calculated derived stats.\nfunc (s *StatsSummary) DerivedStats() (info.DerivedStats, error) {\n\ts.dataLock.RLock()\n\tdefer s.dataLock.RUnlock()\n\n\treturn s.derivedStats, nil\n}\n\nfunc New(spec v1.ContainerSpec) (*StatsSummary, error) {\n\tsummary := StatsSummary{}\n\tif spec.HasCpu {\n\t\tsummary.available.Cpu = true\n\t}\n\tif spec.HasMemory {\n\t\tsummary.available.Memory = true\n\t}\n\tif !summary.available.Cpu && !summary.available.Memory {\n\t\treturn nil, fmt.Errorf(\"none of the resources are being tracked\")\n\t}\n\tsummary.minuteSamples = NewSamplesBuffer(60 /* one hour */)\n\treturn &summary, nil\n}\n"
  },
  {
    "path": "test.htdigest",
    "content": "admin:localhost:70f2631dded4ce5ad0ebbea5faa6ad6e\n"
  },
  {
    "path": "test.htpasswd",
    "content": "admin:$apr1$WVO0Bsre$VrmWGDbcBV1fdAkvgQwdk0\n"
  },
  {
    "path": "utils/cloudinfo/aws/aws.go",
    "content": "// Copyright 2015 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage cloudinfo\n\nimport (\n\t\"context\"\n\t\"io\"\n\t\"os\"\n\t\"strings\"\n\n\t\"github.com/aws/aws-sdk-go-v2/config\"\n\t\"github.com/aws/aws-sdk-go-v2/feature/ec2/imds\"\n\n\tinfo \"github.com/google/cadvisor/info/v1\"\n\t\"github.com/google/cadvisor/utils/cloudinfo\"\n)\n\nconst (\n\tproductVerFileName       = \"/sys/class/dmi/id/product_version\"\n\tbiosVerFileName          = \"/sys/class/dmi/id/bios_vendor\"\n\tsystemdOSReleaseFileName = \"/etc/os-release\"\n\tamazon                   = \"amazon\"\n)\n\nfunc init() {\n\tcloudinfo.RegisterCloudProvider(info.AWS, &provider{})\n}\n\ntype provider struct{}\n\nvar _ cloudinfo.CloudProvider = provider{}\n\nfunc (provider) IsActiveProvider() bool {\n\treturn fileContainsAmazonIdentifier(productVerFileName) ||\n\t\tfileContainsAmazonIdentifier(biosVerFileName) ||\n\t\tfileContainsAmazonIdentifier(systemdOSReleaseFileName)\n}\n\nfunc fileContainsAmazonIdentifier(filename string) bool {\n\tfileContent, err := os.ReadFile(filename)\n\tif err != nil {\n\t\treturn false\n\t}\n\n\treturn strings.Contains(string(fileContent), amazon)\n}\n\nfunc getAwsMetadata(name string) string {\n\tcfg, err := config.LoadDefaultConfig(context.TODO())\n\tif err != nil {\n\t\treturn info.UnknownInstance\n\t}\n\n\tclient := imds.NewFromConfig(cfg)\n\tdata, err := client.GetMetadata(context.TODO(), &imds.GetMetadataInput{\n\t\tPath: name,\n\t})\n\tif err != nil {\n\t\treturn info.UnknownInstance\n\t}\n\n\traw, err := io.ReadAll(data.Content)\n\tif err != nil {\n\t\treturn info.UnknownInstance\n\t}\n\n\treturn string(raw)\n}\n\nfunc (provider) GetInstanceType() info.InstanceType {\n\treturn info.InstanceType(getAwsMetadata(\"instance-type\"))\n}\n\nfunc (provider) GetInstanceID() info.InstanceID {\n\treturn info.InstanceID(getAwsMetadata(\"instance-id\"))\n}\n"
  },
  {
    "path": "utils/cloudinfo/azure/azure.go",
    "content": "// Copyright 2015 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage cloudinfo\n\nimport (\n\t\"os\"\n\t\"strings\"\n\n\tinfo \"github.com/google/cadvisor/info/v1\"\n\t\"github.com/google/cadvisor/utils/cloudinfo\"\n)\n\nconst (\n\tsysVendorFileName    = \"/sys/class/dmi/id/sys_vendor\"\n\tbiosUUIDFileName     = \"/sys/class/dmi/id/product_uuid\"\n\tmicrosoftCorporation = \"Microsoft Corporation\"\n)\n\nfunc init() {\n\tcloudinfo.RegisterCloudProvider(info.Azure, &provider{})\n}\n\ntype provider struct{}\n\nvar _ cloudinfo.CloudProvider = provider{}\n\nfunc (provider) IsActiveProvider() bool {\n\tdata, err := os.ReadFile(sysVendorFileName)\n\tif err != nil {\n\t\treturn false\n\t}\n\treturn strings.Contains(string(data), microsoftCorporation)\n}\n\n// TODO: Implement method.\nfunc (provider) GetInstanceType() info.InstanceType {\n\treturn info.UnknownInstance\n}\n\nfunc (provider) GetInstanceID() info.InstanceID {\n\tdata, err := os.ReadFile(biosUUIDFileName)\n\tif err != nil {\n\t\treturn info.UnNamedInstance\n\t}\n\treturn info.InstanceID(strings.TrimSuffix(string(data), \"\\n\"))\n}\n"
  },
  {
    "path": "utils/cloudinfo/cloudinfo.go",
    "content": "// Copyright 2015 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n// Get information about the cloud provider (if any) cAdvisor is running on.\n\npackage cloudinfo\n\nimport (\n\t\"k8s.io/klog/v2\"\n\n\tinfo \"github.com/google/cadvisor/info/v1\"\n)\n\ntype CloudInfo interface {\n\tGetCloudProvider() info.CloudProvider\n\tGetInstanceType() info.InstanceType\n\tGetInstanceID() info.InstanceID\n}\n\n// CloudProvider is an abstraction for providing cloud-specific information.\ntype CloudProvider interface {\n\t// IsActiveProvider determines whether this is the cloud provider operating\n\t// this instance.\n\tIsActiveProvider() bool\n\t// GetInstanceType gets the type of instance this process is running on.\n\t// The behavior is undefined if this is not the active provider.\n\tGetInstanceType() info.InstanceType\n\t// GetInstanceType gets the ID of the instance this process is running on.\n\t// The behavior is undefined if this is not the active provider.\n\tGetInstanceID() info.InstanceID\n}\n\nvar providers = map[info.CloudProvider]CloudProvider{}\n\n// RegisterCloudProvider registers the given cloud provider\nfunc RegisterCloudProvider(name info.CloudProvider, provider CloudProvider) {\n\tif _, alreadyRegistered := providers[name]; alreadyRegistered {\n\t\tklog.Warningf(\"Duplicate registration of CloudProvider %s\", name)\n\t}\n\tproviders[name] = provider\n}\n\ntype realCloudInfo struct {\n\tcloudProvider info.CloudProvider\n\tinstanceType  info.InstanceType\n\tinstanceID    info.InstanceID\n}\n\nfunc NewRealCloudInfo() CloudInfo {\n\tfor name, provider := range providers {\n\t\tif provider.IsActiveProvider() {\n\t\t\treturn &realCloudInfo{\n\t\t\t\tcloudProvider: name,\n\t\t\t\tinstanceType:  provider.GetInstanceType(),\n\t\t\t\tinstanceID:    provider.GetInstanceID(),\n\t\t\t}\n\t\t}\n\t}\n\n\t// No registered active provider.\n\treturn &realCloudInfo{\n\t\tcloudProvider: info.UnknownProvider,\n\t\tinstanceType:  info.UnknownInstance,\n\t\tinstanceID:    info.UnNamedInstance,\n\t}\n}\n\nfunc (i *realCloudInfo) GetCloudProvider() info.CloudProvider {\n\treturn i.cloudProvider\n}\n\nfunc (i *realCloudInfo) GetInstanceType() info.InstanceType {\n\treturn i.instanceType\n}\n\nfunc (i *realCloudInfo) GetInstanceID() info.InstanceID {\n\treturn i.instanceID\n}\n"
  },
  {
    "path": "utils/cloudinfo/gce/gce.go",
    "content": "// Copyright 2015 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage gce\n\nimport (\n\t\"context\"\n\t\"os\"\n\t\"strings\"\n\n\tinfo \"github.com/google/cadvisor/info/v1\"\n\t\"github.com/google/cadvisor/utils/cloudinfo\"\n\n\t\"cloud.google.com/go/compute/metadata\"\n)\n\nconst (\n\tgceProductName = \"/sys/class/dmi/id/product_name\"\n\tgoogle         = \"Google\"\n)\n\nfunc init() {\n\tcloudinfo.RegisterCloudProvider(info.GCE, &provider{})\n}\n\ntype provider struct{}\n\nvar _ cloudinfo.CloudProvider = provider{}\n\nfunc (provider) IsActiveProvider() bool {\n\tdata, err := os.ReadFile(gceProductName)\n\tif err != nil {\n\t\treturn false\n\t}\n\treturn strings.Contains(string(data), google)\n}\n\nfunc (provider) GetInstanceType() info.InstanceType {\n\tmachineType, err := metadata.GetWithContext(context.TODO(), \"instance/machine-type\")\n\tif err != nil {\n\t\treturn info.UnknownInstance\n\t}\n\n\tresponseParts := strings.Split(machineType, \"/\") // Extract the instance name from the machine type.\n\treturn info.InstanceType(responseParts[len(responseParts)-1])\n}\n\nfunc (provider) GetInstanceID() info.InstanceID {\n\tinstanceID, err := metadata.GetWithContext(context.TODO(), \"instance/id\")\n\tif err != nil {\n\t\treturn info.UnknownInstance\n\t}\n\treturn info.InstanceID(info.InstanceType(instanceID))\n}\n"
  },
  {
    "path": "utils/container/container.go",
    "content": "// Copyright 2016 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage container\n\nimport (\n\tinfo \"github.com/google/cadvisor/info/v1\"\n)\n\n// Returns the alias a container is known by within a certain namespace,\n// if available. Otherwise returns the absolute name of the container.\nfunc GetPreferredName(ref info.ContainerReference) string {\n\tvar containerName string\n\tif len(ref.Aliases) > 0 {\n\t\tcontainerName = ref.Aliases[0]\n\t} else {\n\t\tcontainerName = ref.Name\n\t}\n\treturn containerName\n}\n"
  },
  {
    "path": "utils/cpuload/cpuload.go",
    "content": "// Copyright 2015 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n//go:build linux\n\npackage cpuload\n\nimport (\n\t\"fmt\"\n\n\tinfo \"github.com/google/cadvisor/info/v1\"\n\n\t\"k8s.io/klog/v2\"\n\n\t\"github.com/google/cadvisor/utils/cpuload/netlink\"\n)\n\ntype CpuLoadReader interface {\n\t// Start the reader.\n\tStart() error\n\n\t// Stop the reader and clean up internal state.\n\tStop()\n\n\t// Retrieve Cpu load for a given group.\n\t// name is the full hierarchical name of the container.\n\t// Path is an absolute filesystem path for a container under CPU cgroup hierarchy.\n\tGetCpuLoad(name string, path string) (info.LoadStats, error)\n}\n\nfunc New() (CpuLoadReader, error) {\n\treader, err := netlink.New()\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to create a netlink based cpuload reader: %v\", err)\n\t}\n\tklog.V(4).Info(\"Using a netlink-based load reader\")\n\treturn reader, nil\n}\n"
  },
  {
    "path": "utils/cpuload/cpuload_unsupported.go",
    "content": "// Copyright 2015 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n//go:build !linux\n\npackage cpuload\n\nimport (\n\t\"fmt\"\n\n\tinfo \"github.com/google/cadvisor/info/v1\"\n)\n\ntype CpuLoadReader interface {\n\t// Start the reader.\n\tStart() error\n\n\t// Stop the reader and clean up internal state.\n\tStop()\n\n\t// Retrieve Cpu load for a given group.\n\t// name is the full hierarchical name of the container.\n\t// Path is an absolute filesystem path for a container under CPU cgroup hierarchy.\n\tGetCpuLoad(name string, path string) (info.LoadStats, error)\n}\n\nfunc New() (CpuLoadReader, error) {\n\treturn nil, fmt.Errorf(\"cpuload is not supported on this platform\")\n}\n"
  },
  {
    "path": "utils/cpuload/netlink/conn.go",
    "content": "// Copyright 2015 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n//go:build linux\n\npackage netlink\n\nimport (\n\t\"bufio\"\n\t\"bytes\"\n\t\"encoding/binary\"\n\t\"os\"\n\t\"syscall\"\n)\n\ntype Connection struct {\n\t// netlink socket\n\tfd int\n\t// cache pid to use in every netlink request.\n\tpid uint32\n\t// sequence number for netlink messages.\n\tseq  uint32\n\taddr syscall.SockaddrNetlink\n\trbuf *bufio.Reader\n}\n\n// Create and bind a new netlink socket.\nfunc newConnection() (*Connection, error) {\n\n\tfd, err := syscall.Socket(syscall.AF_NETLINK, syscall.SOCK_DGRAM, syscall.NETLINK_GENERIC)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tconn := new(Connection)\n\tconn.fd = fd\n\tconn.seq = 0\n\tconn.pid = uint32(os.Getpid())\n\tconn.addr.Family = syscall.AF_NETLINK\n\tconn.rbuf = bufio.NewReader(conn)\n\terr = syscall.Bind(fd, &conn.addr)\n\tif err != nil {\n\t\tsyscall.Close(fd)\n\t\treturn nil, err\n\t}\n\treturn conn, err\n}\n\nfunc (c *Connection) Read(b []byte) (n int, err error) {\n\tn, _, err = syscall.Recvfrom(c.fd, b, 0)\n\treturn n, err\n}\n\nfunc (c *Connection) Write(b []byte) (n int, err error) {\n\terr = syscall.Sendto(c.fd, b, 0, &c.addr)\n\treturn len(b), err\n}\n\nfunc (c *Connection) Close() error {\n\treturn syscall.Close(c.fd)\n}\n\nfunc (c *Connection) WriteMessage(msg syscall.NetlinkMessage) error {\n\tw := bytes.NewBuffer(nil)\n\tmsg.Header.Len = uint32(syscall.NLMSG_HDRLEN + len(msg.Data))\n\tmsg.Header.Seq = c.seq\n\tc.seq++\n\tmsg.Header.Pid = c.pid\n\terr := binary.Write(w, binary.LittleEndian, msg.Header)\n\tif err != nil {\n\t\treturn err\n\t}\n\t_, err = w.Write(msg.Data)\n\tif err != nil {\n\t\treturn err\n\t}\n\t_, err = c.Write(w.Bytes())\n\treturn err\n}\n\nfunc (c *Connection) ReadMessage() (msg syscall.NetlinkMessage, err error) {\n\terr = binary.Read(c.rbuf, binary.LittleEndian, &msg.Header)\n\tif err != nil {\n\t\treturn msg, err\n\t}\n\tmsg.Data = make([]byte, msg.Header.Len-syscall.NLMSG_HDRLEN)\n\t_, err = c.rbuf.Read(msg.Data)\n\treturn msg, err\n}\n"
  },
  {
    "path": "utils/cpuload/netlink/example/example.go",
    "content": "// Copyright 2015 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n//go:build linux\n\npackage main\n\nimport (\n\t\"log\"\n\n\t\"github.com/google/cadvisor/utils/cpuload/netlink\"\n)\n\nfunc main() {\n\tn, err := netlink.New()\n\tif err != nil {\n\t\tlog.Printf(\"Failed to create cpu load util: %s\", err)\n\t\treturn\n\t}\n\tdefer n.Stop()\n\n\tpaths := []string{\"/sys/fs/cgroup/cpu\", \"/sys/fs/cgroup/cpu/docker\"}\n\tnames := []string{\"/\", \"/docker\"}\n\tfor i, path := range paths {\n\t\tstats, err := n.GetCpuLoad(names[i], path)\n\t\tif err != nil {\n\t\t\tlog.Printf(\"Error getting cpu load for %q: %s\", path, err)\n\t\t}\n\t\tlog.Printf(\"Task load for %s: %+v\", path, stats)\n\t}\n}\n"
  },
  {
    "path": "utils/cpuload/netlink/netlink.go",
    "content": "// Copyright 2015 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n//go:build linux\n\npackage netlink\n\nimport (\n\t\"bytes\"\n\t\"encoding/binary\"\n\t\"fmt\"\n\t\"os\"\n\t\"syscall\"\n\n\t\"golang.org/x/sys/unix\"\n\n\tinfo \"github.com/google/cadvisor/info/v1\"\n)\n\nvar (\n\t// TODO(rjnagal): Verify and fix for other architectures.\n\n\tEndian = binary.LittleEndian\n)\n\ntype genMsghdr struct {\n\tCommand  uint8\n\tVersion  uint8\n\tReserved uint16\n}\n\ntype netlinkMessage struct {\n\tHeader    syscall.NlMsghdr\n\tGenHeader genMsghdr\n\tData      []byte\n}\n\nfunc (m netlinkMessage) toRawMsg() (rawmsg syscall.NetlinkMessage) {\n\trawmsg.Header = m.Header\n\tw := bytes.NewBuffer([]byte{})\n\t_ = binary.Write(w, Endian, m.GenHeader)\n\tw.Write(m.Data)\n\trawmsg.Data = w.Bytes()\n\treturn rawmsg\n}\n\ntype loadStatsResp struct {\n\tHeader    syscall.NlMsghdr\n\tGenHeader genMsghdr\n\tStats     info.LoadStats\n}\n\n// Return required padding to align 'size' to 'alignment'.\nfunc padding(size int, alignment int) int {\n\tunalignedPart := size % alignment\n\treturn (alignment - unalignedPart) % alignment\n}\n\n// Get family id for taskstats subsystem.\nfunc getFamilyID(conn *Connection) (uint16, error) {\n\tmsg := prepareFamilyMessage()\n\terr := conn.WriteMessage(msg.toRawMsg())\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\n\tresp, err := conn.ReadMessage()\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\tid, err := parseFamilyResp(resp)\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\treturn id, nil\n}\n\n// Append an attribute to the message.\n// Adds attribute info (length and type), followed by the data and necessary padding.\n// Can be called multiple times to add attributes. Only fixed size and string type\n// attributes are handled. We don't need nested attributes for task stats.\nfunc addAttribute(buf *bytes.Buffer, attrType uint16, data interface{}, dataSize int) {\n\tattr := syscall.RtAttr{\n\t\tLen:  syscall.SizeofRtAttr,\n\t\tType: attrType,\n\t}\n\tattr.Len += uint16(dataSize)\n\t_ = binary.Write(buf, Endian, attr)\n\tswitch data := data.(type) {\n\tcase string:\n\t\t_ = binary.Write(buf, Endian, []byte(data))\n\t\tbuf.WriteByte(0) // terminate\n\tdefault:\n\t\t_ = binary.Write(buf, Endian, data)\n\t}\n\tfor i := 0; i < padding(int(attr.Len), syscall.NLMSG_ALIGNTO); i++ {\n\t\tbuf.WriteByte(0)\n\t}\n}\n\n// Prepares the message and generic headers and appends attributes as data.\nfunc prepareMessage(headerType uint16, cmd uint8, attributes []byte) (msg netlinkMessage) {\n\tmsg.Header.Type = headerType\n\tmsg.Header.Flags = syscall.NLM_F_REQUEST\n\tmsg.GenHeader.Command = cmd\n\tmsg.GenHeader.Version = 0x1\n\tmsg.Data = attributes\n\treturn msg\n}\n\n// Prepares message to query family id for task stats.\nfunc prepareFamilyMessage() (msg netlinkMessage) {\n\tbuf := bytes.NewBuffer([]byte{})\n\taddAttribute(buf, unix.CTRL_ATTR_FAMILY_NAME, unix.TASKSTATS_GENL_NAME, len(unix.TASKSTATS_GENL_NAME)+1)\n\treturn prepareMessage(unix.GENL_ID_CTRL, unix.CTRL_CMD_GETFAMILY, buf.Bytes())\n}\n\n// Prepares message to query task stats for a task group.\nfunc prepareCmdMessage(id uint16, cfd uintptr) (msg netlinkMessage) {\n\tbuf := bytes.NewBuffer([]byte{})\n\taddAttribute(buf, unix.CGROUPSTATS_CMD_ATTR_FD, uint32(cfd), 4)\n\treturn prepareMessage(id, unix.CGROUPSTATS_CMD_GET, buf.Bytes())\n}\n\n// Extracts returned family id from the response.\nfunc parseFamilyResp(msg syscall.NetlinkMessage) (uint16, error) {\n\tm := new(netlinkMessage)\n\tm.Header = msg.Header\n\terr := verifyHeader(msg)\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\tbuf := bytes.NewBuffer(msg.Data)\n\t// extract generic header from data.\n\terr = binary.Read(buf, Endian, &m.GenHeader)\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\tid := uint16(0)\n\t// Extract attributes. kernel reports family name, id, version, etc.\n\t// Scan till we find id.\n\tfor buf.Len() > syscall.SizeofRtAttr {\n\t\tvar attr syscall.RtAttr\n\t\terr = binary.Read(buf, Endian, &attr)\n\t\tif err != nil {\n\t\t\treturn 0, err\n\t\t}\n\t\tif attr.Type == unix.CTRL_ATTR_FAMILY_ID {\n\t\t\terr = binary.Read(buf, Endian, &id)\n\t\t\tif err != nil {\n\t\t\t\treturn 0, err\n\t\t\t}\n\t\t\treturn id, nil\n\t\t}\n\t\tpayload := int(attr.Len) - syscall.SizeofRtAttr\n\t\tskipLen := payload + padding(payload, syscall.SizeofRtAttr)\n\t\tname := make([]byte, skipLen)\n\t\terr = binary.Read(buf, Endian, name)\n\t\tif err != nil {\n\t\t\treturn 0, err\n\t\t}\n\t}\n\treturn 0, fmt.Errorf(\"family id not found in the response\")\n}\n\n// Extract task stats from response returned by kernel.\nfunc parseLoadStatsResp(msg syscall.NetlinkMessage) (*loadStatsResp, error) {\n\tm := new(loadStatsResp)\n\tm.Header = msg.Header\n\terr := verifyHeader(msg)\n\tif err != nil {\n\t\treturn m, err\n\t}\n\tbuf := bytes.NewBuffer(msg.Data)\n\t// Scan the general header.\n\terr = binary.Read(buf, Endian, &m.GenHeader)\n\tif err != nil {\n\t\treturn m, err\n\t}\n\t// cgroup stats response should have just one attribute.\n\t// Read it directly into the stats structure.\n\tvar attr syscall.RtAttr\n\terr = binary.Read(buf, Endian, &attr)\n\tif err != nil {\n\t\treturn m, err\n\t}\n\terr = binary.Read(buf, Endian, &m.Stats)\n\tif err != nil {\n\t\treturn m, err\n\t}\n\treturn m, err\n}\n\n// Verify and return any error reported by kernel.\nfunc verifyHeader(msg syscall.NetlinkMessage) error {\n\tswitch msg.Header.Type {\n\tcase syscall.NLMSG_DONE:\n\t\treturn fmt.Errorf(\"expected a response, got nil\")\n\tcase syscall.NLMSG_ERROR:\n\t\tbuf := bytes.NewBuffer(msg.Data)\n\t\tvar errno int32\n\t\terr := binary.Read(buf, Endian, errno)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\treturn fmt.Errorf(\"netlink request failed with error %s\", syscall.Errno(-errno))\n\t}\n\treturn nil\n}\n\n// Get load stats for a task group.\n// id: family id for taskstats.\n// cfd: open file to path to the cgroup directory under cpu hierarchy.\n// conn: open netlink connection used to communicate with kernel.\nfunc getLoadStats(id uint16, cfd *os.File, conn *Connection) (info.LoadStats, error) {\n\tmsg := prepareCmdMessage(id, cfd.Fd())\n\terr := conn.WriteMessage(msg.toRawMsg())\n\tif err != nil {\n\t\treturn info.LoadStats{}, err\n\t}\n\n\tresp, err := conn.ReadMessage()\n\tif err != nil {\n\t\treturn info.LoadStats{}, err\n\t}\n\n\tparsedmsg, err := parseLoadStatsResp(resp)\n\tif err != nil {\n\t\treturn info.LoadStats{}, err\n\t}\n\treturn parsedmsg.Stats, nil\n}\n"
  },
  {
    "path": "utils/cpuload/netlink/reader.go",
    "content": "// Copyright 2015 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n//go:build linux\n\npackage netlink\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\n\tinfo \"github.com/google/cadvisor/info/v1\"\n\n\t\"k8s.io/klog/v2\"\n)\n\ntype NetlinkReader struct {\n\tfamilyID uint16\n\tconn     *Connection\n}\n\nfunc New() (*NetlinkReader, error) {\n\tconn, err := newConnection()\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to create a new connection: %s\", err)\n\t}\n\n\tid, err := getFamilyID(conn)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to get netlink family id for task stats: %s\", err)\n\t}\n\tklog.V(4).Infof(\"Family id for taskstats: %d\", id)\n\treturn &NetlinkReader{\n\t\tfamilyID: id,\n\t\tconn:     conn,\n\t}, nil\n}\n\nfunc (r *NetlinkReader) Stop() {\n\tif r.conn != nil {\n\t\tr.conn.Close()\n\t}\n}\n\nfunc (r *NetlinkReader) Start() error {\n\t// We do the start setup for netlink in New(). Nothing to do here.\n\treturn nil\n}\n\n// Returns instantaneous number of running tasks in a group.\n// Caller can use historical data to calculate cpu load.\n// path is an absolute filesystem path for a container under the CPU cgroup hierarchy.\n// NOTE: non-hierarchical load is returned. It does not include load for subcontainers.\nfunc (r *NetlinkReader) GetCpuLoad(name string, path string) (info.LoadStats, error) {\n\tif len(path) == 0 {\n\t\treturn info.LoadStats{}, fmt.Errorf(\"cgroup path can not be empty\")\n\t}\n\n\tcfd, err := os.Open(path)\n\tif err != nil {\n\t\treturn info.LoadStats{}, fmt.Errorf(\"failed to open cgroup path %s: %q\", path, err)\n\t}\n\tdefer cfd.Close()\n\n\tstats, err := getLoadStats(r.familyID, cfd, r.conn)\n\tif err != nil {\n\t\treturn info.LoadStats{}, err\n\t}\n\tklog.V(4).Infof(\"Task stats for %q: %+v\", path, stats)\n\treturn stats, nil\n}\n"
  },
  {
    "path": "utils/oomparser/oomexample/main.go",
    "content": "// Copyright 2014 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n//go:build linux\n\npackage main\n\nimport (\n\t\"flag\"\n\n\t\"k8s.io/klog/v2\"\n\n\t\"github.com/google/cadvisor/utils/oomparser\"\n)\n\n// demonstrates how to run oomparser.OomParser to get OomInstance information\nfunc main() {\n\tklog.InitFlags(nil)\n\tflag.Parse()\n\t// out is a user-provided channel from which the user can read incoming\n\t// OomInstance objects\n\toutStream := make(chan *oomparser.OomInstance)\n\toomLog, err := oomparser.New()\n\tif err != nil {\n\t\tklog.Infof(\"Couldn't make a new oomparser. %v\", err)\n\t} else {\n\t\tgo oomLog.StreamOoms(outStream)\n\t\t// demonstration of how to get oomLog's list of oomInstances or access\n\t\t// the user-declared oomInstance channel, here called outStream\n\t\tfor oomInstance := range outStream {\n\t\t\tklog.Infof(\"Reading the buffer. Output is %v\", oomInstance)\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "utils/oomparser/oomparser.go",
    "content": "// Copyright 2014 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n//go:build linux\n\npackage oomparser\n\nimport (\n\t\"path\"\n\t\"regexp\"\n\t\"strconv\"\n\t\"time\"\n\n\t\"github.com/euank/go-kmsg-parser/kmsgparser\"\n\n\t\"k8s.io/klog/v2\"\n)\n\nvar (\n\tlegacyContainerRegexp = regexp.MustCompile(`Task in (.*) killed as a result of limit of (.*)`)\n\t// Starting in 5.0 linux kernels, the OOM message changed\n\tcontainerRegexp = regexp.MustCompile(`oom-kill:constraint=(.*),nodemask=(.*),cpuset=(.*),mems_allowed=(.*),oom_memcg=(.*),task_memcg=(.*),task=(.*),pid=(.*),uid=(.*)`)\n\tlastLineRegexp  = regexp.MustCompile(`Killed process ([0-9]+) \\((.+)\\)`)\n\tfirstLineRegexp = regexp.MustCompile(`invoked oom-killer:`)\n)\n\n// OomParser wraps a kmsgparser in order to extract OOM events from the\n// individual kernel ring buffer messages.\ntype OomParser struct {\n\tparser kmsgparser.Parser\n}\n\n// struct that contains information related to an OOM kill instance\ntype OomInstance struct {\n\t// process id of the killed process\n\tPid int\n\t// the name of the killed process\n\tProcessName string\n\t// the time that the process was reported to be killed,\n\t// accurate to the minute\n\tTimeOfDeath time.Time\n\t// the absolute name of the container that OOMed\n\tContainerName string\n\t// the absolute name of the container that was killed\n\t// due to the OOM.\n\tVictimContainerName string\n\t// the constraint that triggered the OOM.  One of CONSTRAINT_NONE,\n\t// CONSTRAINT_CPUSET, CONSTRAINT_MEMORY_POLICY, CONSTRAINT_MEMCG\n\tConstraint string\n}\n\n// gets the container name from a line and adds it to the oomInstance.\nfunc getLegacyContainerName(line string, currentOomInstance *OomInstance) error {\n\tparsedLine := legacyContainerRegexp.FindStringSubmatch(line)\n\tif parsedLine == nil {\n\t\treturn nil\n\t}\n\tcurrentOomInstance.ContainerName = path.Join(\"/\", parsedLine[1])\n\tcurrentOomInstance.VictimContainerName = path.Join(\"/\", parsedLine[2])\n\treturn nil\n}\n\n// gets the container name from a line and adds it to the oomInstance.\nfunc getContainerName(line string, currentOomInstance *OomInstance) (bool, error) {\n\tparsedLine := containerRegexp.FindStringSubmatch(line)\n\tif parsedLine == nil {\n\t\t// Fall back to the legacy format if it isn't found here.\n\t\treturn false, getLegacyContainerName(line, currentOomInstance)\n\t}\n\tcurrentOomInstance.ContainerName = parsedLine[6]\n\tcurrentOomInstance.VictimContainerName = parsedLine[5]\n\tcurrentOomInstance.Constraint = parsedLine[1]\n\tpid, err := strconv.Atoi(parsedLine[8])\n\tif err != nil {\n\t\treturn false, err\n\t}\n\tcurrentOomInstance.Pid = pid\n\tcurrentOomInstance.ProcessName = parsedLine[7]\n\treturn true, nil\n}\n\n// gets the pid, name, and date from a line and adds it to oomInstance\nfunc getProcessNamePid(line string, currentOomInstance *OomInstance) (bool, error) {\n\treList := lastLineRegexp.FindStringSubmatch(line)\n\n\tif reList == nil {\n\t\treturn false, nil\n\t}\n\n\tpid, err := strconv.Atoi(reList[1])\n\tif err != nil {\n\t\treturn false, err\n\t}\n\tcurrentOomInstance.Pid = pid\n\tcurrentOomInstance.ProcessName = reList[2]\n\treturn true, nil\n}\n\n// uses regex to see if line is the start of a kernel oom log\nfunc checkIfStartOfOomMessages(line string) bool {\n\tpotentialOomStart := firstLineRegexp.MatchString(line)\n\treturn potentialOomStart\n}\n\n// StreamOoms writes to a provided a stream of OomInstance objects representing\n// OOM events that are found in the logs.\n// It will block and should be called from a goroutine.\nfunc (p *OomParser) StreamOoms(outStream chan<- *OomInstance) {\n\tkmsgEntries := p.parser.Parse()\n\tdefer p.parser.Close()\n\n\tfor msg := range kmsgEntries {\n\t\tisOomMessage := checkIfStartOfOomMessages(msg.Message)\n\t\tif isOomMessage {\n\t\t\toomCurrentInstance := &OomInstance{\n\t\t\t\tContainerName:       \"/\",\n\t\t\t\tVictimContainerName: \"/\",\n\t\t\t\tTimeOfDeath:         msg.Timestamp,\n\t\t\t}\n\t\t\tfor msg := range kmsgEntries {\n\t\t\t\tfinished, err := getContainerName(msg.Message, oomCurrentInstance)\n\t\t\t\tif err != nil {\n\t\t\t\t\tklog.Errorf(\"%v\", err)\n\t\t\t\t}\n\t\t\t\tif !finished {\n\t\t\t\t\tfinished, err = getProcessNamePid(msg.Message, oomCurrentInstance)\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\tklog.Errorf(\"%v\", err)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif finished {\n\t\t\t\t\toomCurrentInstance.TimeOfDeath = msg.Timestamp\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t\toutStream <- oomCurrentInstance\n\t\t}\n\t}\n\t// Should not happen\n\tklog.Errorf(\"exiting analyzeLines. OOM events will not be reported.\")\n}\n\n// initializes an OomParser object. Returns an OomParser object and an error.\nfunc New() (*OomParser, error) {\n\tparser, err := kmsgparser.NewParser()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tparser.SetLogger(glogAdapter{})\n\treturn &OomParser{parser: parser}, nil\n}\n\ntype glogAdapter struct{}\n\nvar _ kmsgparser.Logger = glogAdapter{}\n\nfunc (glogAdapter) Infof(format string, args ...interface{}) {\n\tklog.V(4).Infof(format, args...)\n}\nfunc (glogAdapter) Warningf(format string, args ...interface{}) {\n\tklog.V(2).Infof(format, args...)\n}\nfunc (glogAdapter) Errorf(format string, args ...interface{}) {\n\tklog.Warningf(format, args...)\n}\n"
  },
  {
    "path": "utils/oomparser/oomparser_test.go",
    "content": "// Copyright 2015 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n//go:build linux\n\npackage oomparser\n\nimport (\n\t\"fmt\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/euank/go-kmsg-parser/kmsgparser\"\n\t\"github.com/stretchr/testify/assert\"\n)\n\nconst (\n\tstartLine           = \"ruby invoked oom-killer: gfp_mask=0x201da, order=0, oom_score_adj=0\"\n\tendLine             = \"Killed process 19667 (evil-program2) total-vm:1460016kB, anon-rss:1414008kB, file-rss:4kB\"\n\tlegacyContainerLine = \"Task in /mem2 killed as a result of limit of /mem3\"\n\tcontainerLine       = \"oom-kill:constraint=CONSTRAINT_MEMCG,nodemask=(null),cpuset=ef807430361e6e82b45db92e2e9b6fbec98f419b12c591e655c1a725565e73a8,mems_allowed=0,oom_memcg=/kubepods/burstable/podfbdfe8e3-1c87-4ff2-907c-b2ec8e25d012,task_memcg=/kubepods/burstable/podfbdfe8e3-1c87-4ff2-907c-b2ec8e25d012/ef807430361e6e82b45db92e2e9b6fbec98f419b12c591e655c1a725565e73a8,task=manager,pid=966,uid=0\"\n)\n\nfunc TestGetLegacyContainerName(t *testing.T) {\n\tcurrentOomInstance := new(OomInstance)\n\tfinished, err := getContainerName(startLine, currentOomInstance)\n\tif err != nil {\n\t\tt.Errorf(\"bad line fed to getContainerName should yield no error, but had error %v\", err)\n\t}\n\tif finished {\n\t\tt.Errorf(\"bad line fed to getContainerName should not result in a finished oom log, but it did\")\n\t}\n\tif currentOomInstance.ContainerName != \"\" {\n\t\tt.Errorf(\"bad line fed to getContainerName yielded no container name but set it to %s\", currentOomInstance.ContainerName)\n\t}\n\tfinished, err = getContainerName(legacyContainerLine, currentOomInstance)\n\tif err != nil {\n\t\tt.Errorf(\"container line fed to getContainerName should yield no error, but had error %v\", err)\n\t}\n\tif finished {\n\t\tt.Errorf(\"getContainerName with the legacy log line should not result in a finished oom log, but it did\")\n\n\t}\n\tif currentOomInstance.ContainerName != \"/mem2\" {\n\t\tt.Errorf(\"getContainerName should have set containerName to /mem2, not %s\", currentOomInstance.ContainerName)\n\t}\n\tif currentOomInstance.VictimContainerName != \"/mem3\" {\n\t\tt.Errorf(\"getContainerName should have set victimContainerName to /mem3, not %s\", currentOomInstance.VictimContainerName)\n\t}\n}\n\nfunc TestGetContainerName(t *testing.T) {\n\tcurrentOomInstance := new(OomInstance)\n\tfinished, err := getContainerName(startLine, currentOomInstance)\n\tif err != nil {\n\t\tt.Errorf(\"bad line fed to getContainerName should yield no error, but had error %v\", err)\n\t}\n\tif finished {\n\t\tt.Errorf(\"bad line fed to getContainerName should not result in a finished oom log, but it did\")\n\t}\n\tif currentOomInstance.ContainerName != \"\" {\n\t\tt.Errorf(\"bad line fed to getContainerName yielded no container name but set it to %s\", currentOomInstance.ContainerName)\n\t}\n\tfinished, err = getContainerName(containerLine, currentOomInstance)\n\tif err != nil {\n\t\tt.Errorf(\"container line fed to getContainerName should yield no error, but had error %v\", err)\n\t}\n\tif !finished {\n\t\tt.Errorf(\"getContainerName with the complete log line should result in a finished oom log, but it did not\")\n\n\t}\n\tif currentOomInstance.ContainerName != \"/kubepods/burstable/podfbdfe8e3-1c87-4ff2-907c-b2ec8e25d012/ef807430361e6e82b45db92e2e9b6fbec98f419b12c591e655c1a725565e73a8\" {\n\t\tt.Errorf(\"getContainerName should have set containerName to /kubepods/burstable/podfbdfe8e3-1c87-4ff2-907c-b2ec8e25d012/ef807430361e6e82b45db92e2e9b6fbec98f419b12c591e655c1a725565e73a8, not %s\", currentOomInstance.ContainerName)\n\t}\n\tif currentOomInstance.VictimContainerName != \"/kubepods/burstable/podfbdfe8e3-1c87-4ff2-907c-b2ec8e25d012\" {\n\t\tt.Errorf(\"getContainerName should have set victimContainerName to /kubepods/burstable/podfbdfe8e3-1c87-4ff2-907c-b2ec8e25d012, not %s\", currentOomInstance.VictimContainerName)\n\t}\n\tif currentOomInstance.Pid != 966 {\n\t\tt.Errorf(\"getContainerName should have set Pid to 966, not %d\", currentOomInstance.Pid)\n\t}\n\tif currentOomInstance.ProcessName != \"manager\" {\n\t\tt.Errorf(\"getContainerName should have set ProcessName to manager, not %s\", currentOomInstance.ProcessName)\n\t}\n\tif currentOomInstance.Constraint != \"CONSTRAINT_MEMCG\" {\n\t\tt.Errorf(\"getContainerName should have set ProcessName to CONSTRAINT_MEMCG, not %s\", currentOomInstance.Constraint)\n\t}\n}\n\nfunc TestGetProcessNamePid(t *testing.T) {\n\tcurrentOomInstance := new(OomInstance)\n\tcouldParseLine, err := getProcessNamePid(startLine, currentOomInstance)\n\tif err != nil {\n\t\tt.Errorf(\"bad line fed to getProcessNamePid should yield no error, but had error %v\", err)\n\t}\n\tif couldParseLine {\n\t\tt.Errorf(\"bad line fed to getProcessNamePid should return false but returned %v\", couldParseLine)\n\t}\n\n\tcouldParseLine, err = getProcessNamePid(endLine, currentOomInstance)\n\tif err != nil {\n\t\tt.Errorf(\"good line fed to getProcessNamePid should yield no error, but had error %v\", err)\n\t}\n\tif !couldParseLine {\n\t\tt.Errorf(\"good line fed to getProcessNamePid should return true but returned %v\", couldParseLine)\n\t}\n\tif currentOomInstance.ProcessName != \"evil-program2\" {\n\t\tt.Errorf(\"getProcessNamePid should have set processName to evil-program2, not %s\", currentOomInstance.ProcessName)\n\t}\n\tif currentOomInstance.Pid != 19667 {\n\t\tt.Errorf(\"getProcessNamePid should have set PID to 19667, not %d\", currentOomInstance.Pid)\n\t}\n}\n\nfunc TestCheckIfStartOfMessages(t *testing.T) {\n\tcouldParseLine := checkIfStartOfOomMessages(endLine)\n\tif couldParseLine {\n\t\tt.Errorf(\"bad line fed to checkIfStartOfMessages should return false but returned %v\", couldParseLine)\n\t}\n\tcouldParseLine = checkIfStartOfOomMessages(startLine)\n\tif !couldParseLine {\n\t\tt.Errorf(\"start line fed to checkIfStartOfMessages should return true but returned %v\", couldParseLine)\n\t}\n}\n\nfunc TestLastLineRegex(t *testing.T) {\n\tprocessNames := []string{\"foo\", \"python3.4\", \"foo-bar\", \"Plex Media Server\", \"x86_64-pc-linux-gnu-c++-5.4.0\", \"[\", \"()\", `\"with quotes\"`}\n\tfor _, name := range processNames {\n\t\tline := fmt.Sprintf(\"Jan 21 22:01:49 localhost kernel: [62279.421192] Killed process 1234 (%s) total-vm:1460016kB, anon-rss:1414008kB, file-rss:4kB\", name)\n\t\toomInfo := &OomInstance{}\n\t\tisPid, err := getProcessNamePid(line, oomInfo)\n\t\tassert.True(t, isPid)\n\t\tassert.NoError(t, err)\n\t\tassert.Equal(t, 1234, oomInfo.Pid)\n\t\tassert.Equal(t, name, oomInfo.ProcessName)\n\t}\n}\n\nfunc TestStreamOOMs(t *testing.T) {\n\tmockMsgs := make(chan kmsgparser.Message)\n\tp := &OomParser{\n\t\tparser: &mockKmsgParser{\n\t\t\tmessages: mockMsgs,\n\t\t},\n\t}\n\n\toomsOut := make(chan *OomInstance)\n\n\tgo func() {\n\t\tp.StreamOoms(oomsOut)\n\t}()\n\n\twriteAll := func(m []string, t time.Time) {\n\t\tfor _, msg := range m {\n\t\t\tmockMsgs <- kmsgparser.Message{\n\t\t\t\tMessage:   msg,\n\t\t\t\tTimestamp: t,\n\t\t\t}\n\t\t}\n\t}\n\n\ttype in struct {\n\t\tmsgs []string\n\t\ttime time.Time\n\t}\n\n\ttestTime := time.Unix(0xf331f4ee, 0)\n\ttestTime2 := time.Unix(0xfa51f001, 0)\n\ttestPairs := []struct {\n\t\tin  []in\n\t\tout []*OomInstance\n\t}{\n\t\t{\n\t\t\tin: []in{{\n\t\t\t\ttime: testTime,\n\t\t\t\tmsgs: []string{\n\t\t\t\t\t\"memorymonster invoked oom-killer: gfp_mask=0xd0, order=0, oom_score_adj=0\",\n\t\t\t\t\t\"memorymonster cpuset=/ mems_allowed=0\",\n\t\t\t\t\t\"CPU: 5 PID: 13536 Comm: memorymonster Tainted: P           OX 3.13.0-43-generic #72-Ubuntu\",\n\t\t\t\t\t\"Hardware name: Hewlett-Packard HP Z420 Workstation/1589, BIOS J61 v03.65 12/19/2013\",\n\t\t\t\t\t\" ffff88072ae10800 ffff8807a4835c48 ffffffff81720bf6 ffff8807a8e86000\",\n\t\t\t\t\t\" ffff8807a4835cd0 ffffffff8171b4b1 0000000000000246 ffff88072ae10800\",\n\t\t\t\t\t\" ffff8807a4835c90 ffff8807a4835ca0 ffffffff811522a7 0000000000000001\",\n\t\t\t\t\t\"Call Trace:\",\n\t\t\t\t\t\" [<ffffffff81720bf6>] dump_stack+0x45/0x56\",\n\t\t\t\t\t\" [<ffffffff8171b4b1>] dump_header+0x7f/0x1f1\",\n\t\t\t\t\t\" [<ffffffff811522a7>] ? find_lock_task_mm+0x27/0x70\",\n\t\t\t\t\t\" [<ffffffff811526de>] oom_kill_process+0x1ce/0x330\",\n\t\t\t\t\t\" [<ffffffff812d6ce5>] ? security_capable_noaudit+0x15/0x20\",\n\t\t\t\t\t\" [<ffffffff811b491c>] mem_cgroup_oom_synchronize+0x51c/0x560\",\n\t\t\t\t\t\" [<ffffffff811b3e50>] ? mem_cgroup_charge_common+0xa0/0xa0\",\n\t\t\t\t\t\" [<ffffffff81152e64>] pagefault_out_of_memory+0x14/0x80\",\n\t\t\t\t\t\" [<ffffffff81719aa1>] mm_fault_error+0x8e/0x180\",\n\t\t\t\t\t\" [<ffffffff8172cf31>] __do_page_fault+0x4a1/0x560\",\n\t\t\t\t\t\" [<ffffffff810a0255>] ? set_next_entity+0x95/0xb0\",\n\t\t\t\t\t\" [<ffffffff81012609>] ? __switch_to+0x169/0x4c0\",\n\t\t\t\t\t\" [<ffffffff8172d00a>] do_page_fault+0x1a/0x70\",\n\t\t\t\t\t\" [<ffffffff81729468>] page_fault+0x28/0x30\",\n\t\t\t\t\t\"Task in /mem2 killed as a result of limit of /mem2\",\n\t\t\t\t\t\"memory: usage 980kB, limit 980kB, failcnt 4152239\",\n\t\t\t\t\t\"memory+swap: usage 0kB, limit 18014398509481983kB, failcnt 0\",\n\t\t\t\t\t\"kmem: usage 0kB, limit 18014398509481983kB, failcnt 0\",\n\t\t\t\t\t\"Memory cgroup stats for /mem2: cache:0KB rss:980KB rss_huge:0KB mapped_file:0KB writeback:20KB inactive_anon:560KB active_anon:420KB inactive_file:0KB active_file:0KB unevictable:0KB\",\n\t\t\t\t\t\"[ pid ]   uid  tgid total_vm      rss nr_ptes swapents oom_score_adj name\",\n\t\t\t\t\t\"[13536] 275858 13536  8389663      343   16267  8324326             0 memorymonster\",\n\t\t\t\t\t\"Memory cgroup out of memory: Kill process 13536 (memorymonster) score 996 or sacrifice child\",\n\t\t\t\t\t\"Killed process 13536 (memorymonster) total-vm:33558652kB, anon-rss:920kB, file-rss:452kB\",\n\t\t\t\t},\n\t\t\t}},\n\t\t\tout: []*OomInstance{{\n\t\t\t\tTimeOfDeath:         testTime,\n\t\t\t\tContainerName:       \"/mem2\",\n\t\t\t\tProcessName:         \"memorymonster\",\n\t\t\t\tPid:                 13536,\n\t\t\t\tVictimContainerName: \"/mem2\",\n\t\t\t}},\n\t\t},\n\t\t{\n\t\t\tin: []in{{\n\t\t\t\ttime: testTime,\n\t\t\t\tmsgs: []string{\n\t\t\t\t\t\"badsysprogram invoked oom-killer: gfp_mask=0x280da, order=0, oom_score_adj=0\",\n\t\t\t\t\t\"badsysprogram cpuset=/ mems_allowed=0\",\n\t\t\t\t\t\"CPU: 0 PID: 1532 Comm: badsysprogram Not tainted 3.13.0-27-generic #50-Ubuntu\",\n\t\t\t\t\t\"Hardware name: Google Google, BIOS Google 01/01/2011\",\n\t\t\t\t\t\" 0000000000000000 ffff880069715a90 ffffffff817199c4 ffff8800680d8000\",\n\t\t\t\t\t\" ffff880069715b18 ffffffff817142ff 0000000000000000 0000000000000000\",\n\t\t\t\t\t\" 0000000000000000 0000000000000000 0000000000000000 0000000000000000\",\n\t\t\t\t\t\"Call Trace:\",\n\t\t\t\t\t\" [<ffffffff817199c4>] dump_stack+0x45/0x56\",\n\t\t\t\t\t\" [<ffffffff817142ff>] dump_header+0x7f/0x1f1\",\n\t\t\t\t\t\" [<ffffffff8115196e>] oom_kill_process+0x1ce/0x330\",\n\t\t\t\t\t\" [<ffffffff812d3395>] ? security_capable_noaudit+0x15/0x20\",\n\t\t\t\t\t\" [<ffffffff811520a4>] out_of_memory+0x414/0x450\",\n\t\t\t\t\t\" [<ffffffff81158377>] __alloc_pages_nodemask+0xa87/0xb20\",\n\t\t\t\t\t\" [<ffffffff811985da>] alloc_pages_vma+0x9a/0x140\",\n\t\t\t\t\t\" [<ffffffff8117909b>] handle_mm_fault+0xb2b/0xf10\",\n\t\t\t\t\t\" [<ffffffff81725924>] __do_page_fault+0x184/0x560\",\n\t\t\t\t\t\" [<ffffffff8101b7d9>] ? sched_clock+0x9/0x10\",\n\t\t\t\t\t\" [<ffffffff8109d13d>] ? sched_clock_local+0x1d/0x80\",\n\t\t\t\t\t\" [<ffffffff811112ec>] ? acct_account_cputime+0x1c/0x20\",\n\t\t\t\t\t\" [<ffffffff8109d76b>] ? account_user_time+0x8b/0xa0\",\n\t\t\t\t\t\" [<ffffffff8109dd84>] ? vtime_account_user+0x54/0x60\",\n\t\t\t\t\t\" [<ffffffff81725d1a>] do_page_fault+0x1a/0x70\",\n\t\t\t\t\t\" [<ffffffff81722188>] page_fault+0x28/0x30\",\n\t\t\t\t\t\"Mem-Info:\",\n\t\t\t\t\t\"Node 0 DMA per-cpu:\",\n\t\t\t\t\t\"CPU    0: hi:    0, btch:   1 usd:   0\",\n\t\t\t\t\t\"Node 0 DMA32 per-cpu:\",\n\t\t\t\t\t\"CPU    0: hi:  186, btch:  31 usd:  86\",\n\t\t\t\t\t\"active_anon:405991 inactive_anon:57 isolated_anon:0\",\n\t\t\t\t\t\" active_file:35 inactive_file:69 isolated_file:0\",\n\t\t\t\t\t\" unevictable:0 dirty:0 writeback:0 unstable:0\",\n\t\t\t\t\t\" free:12929 slab_reclaimable:1635 slab_unreclaimable:1919\",\n\t\t\t\t\t\" mapped:34 shmem:70 pagetables:1423 bounce:0\",\n\t\t\t\t\t\" free_cma:0\",\n\t\t\t\t\t\"Node 0 DMA free:7124kB min:412kB low:512kB high:616kB active_anon:8508kB inactive_anon:4kB active_file:0kB inactive_file:0kB unevictable:0kB isolated(anon):0kB isolated(file):0kB present:15992kB managed:15908kB mlocked:0kB dirty:0kB writeback:0kB mapped:0kB shmem:4kB slab_reclaimable:16kB slab_unreclaimable:16kB kernel_stack:0kB pagetables:12kB unstable:0kB bounce:0kB free_cma:0kB writeback_tmp:0kB pages_scanned:0 all_unreclaimable? yes\",\n\t\t\t\t\t\"lowmem_reserve[]: 0 1679 1679 1679\",\n\t\t\t\t\t\"Node 0 DMA32 free:44592kB min:44640kB low:55800kB high:66960kB active_anon:1615456kB inactive_anon:224kB active_file:140kB inactive_file:276kB unevictable:0kB isolated(anon):0kB isolated(file):0kB present:1765368kB managed:1722912kB mlocked:0kB dirty:0kB writeback:0kB mapped:136kB shmem:276kB slab_reclaimable:6524kB slab_unreclaimable:7660kB kernel_stack:592kB pagetables:5680kB unstable:0kB bounce:0kB free_cma:0kB writeback_tmp:0kB pages_scanned:819 all_unreclaimable? yes\",\n\t\t\t\t\t\"lowmem_reserve[]: 0 0 0 0\",\n\t\t\t\t\t\"Node 0 DMA: 5*4kB (UM) 6*8kB (UEM) 7*16kB (UEM) 1*32kB (M) 2*64kB (UE) 3*128kB (UEM) 1*256kB (E) 2*512kB (EM) 3*1024kB (UEM) 1*2048kB (R) 0*4096kB = 7124kB\",\n\t\t\t\t\t\"Node 0 DMA32: 74*4kB (UEM) 125*8kB (UEM) 78*16kB (UEM) 26*32kB (UE) 12*64kB (UEM) 4*128kB (UE) 4*256kB (UE) 2*512kB (E) 11*1024kB (UE) 7*2048kB (UE) 3*4096kB (UR) = 44592kB\",\n\t\t\t\t\t\"Node 0 hugepages_total=0 hugepages_free=0 hugepages_surp=0 hugepages_size=2048kB\",\n\t\t\t\t\t\"204 total pagecache pages\",\n\t\t\t\t\t\"0 pages in swap cache\",\n\t\t\t\t\t\"Swap cache stats: add 0, delete 0, find 0/0\",\n\t\t\t\t\t\"Free swap  = 0kB\",\n\t\t\t\t\t\"Total swap = 0kB\",\n\t\t\t\t\t\"445340 pages RAM\",\n\t\t\t\t\t\"0 pages HighMem/MovableOnly\",\n\t\t\t\t\t\"10614 pages reserved\",\n\t\t\t\t\t\"[ pid ]   uid  tgid total_vm      rss nr_ptes swapents oom_score_adj name\",\n\t\t\t\t\t\"[  273]     0   273     4869       50      13        0             0 upstart-udev-br\",\n\t\t\t\t\t\"[  293]     0   293    12802      154      28        0         -1000 systemd-udevd\",\n\t\t\t\t\t\"[  321]     0   321     3819       54      12        0             0 upstart-file-br\",\n\t\t\t\t\t\"[  326]   102   326     9805      109      24        0             0 dbus-daemon\",\n\t\t\t\t\t\"[  334]   101   334    63960       94      26        0             0 rsyslogd\",\n\t\t\t\t\t\"[  343]     0   343    10863      102      26        0             0 systemd-logind\",\n\t\t\t\t\t\"[  546]     0   546     3815       60      13        0             0 upstart-socket-\",\n\t\t\t\t\t\"[  710]     0   710     2556      587       8        0             0 dhclient\",\n\t\t\t\t\t\"[  863]     0   863     3955       48      13        0             0 getty\",\n\t\t\t\t\t\"[  865]     0   865     3955       50      13        0             0 getty\",\n\t\t\t\t\t\"[  867]     0   867     3955       51      13        0             0 getty\",\n\t\t\t\t\t\"[  868]     0   868     3955       51      12        0             0 getty\",\n\t\t\t\t\t\"[  870]     0   870     3955       49      13        0             0 getty\",\n\t\t\t\t\t\"[  915]     0   915     5914       61      16        0             0 cron\",\n\t\t\t\t\t\"[ 1015]     0  1015    10885     1524      25        0             0 manage_addresse\",\n\t\t\t\t\t\"[ 1028]     0  1028     3955       49      13        0             0 getty\",\n\t\t\t\t\t\"[ 1033]     0  1033     3197       48      12        0             0 getty\",\n\t\t\t\t\t\"[ 1264]     0  1264    11031     1635      26        0             0 manage_accounts\",\n\t\t\t\t\t\"[ 1268]     0  1268    15341      180      33        0         -1000 sshd\",\n\t\t\t\t\t\"[ 1313]   104  1313     6804      154      17        0             0 ntpd\",\n\t\t\t\t\t\"[ 1389]     0  1389    25889      255      55        0             0 sshd\",\n\t\t\t\t\t\"[ 1407]  1020  1407    25889      255      52        0             0 sshd\",\n\t\t\t\t\t\"[ 1408]  1020  1408     5711      581      17        0             0 bash\",\n\t\t\t\t\t\"[ 1425]     0  1425    25889      256      53        0             0 sshd\",\n\t\t\t\t\t\"[ 1443]  1020  1443    25889      257      52        0             0 sshd\",\n\t\t\t\t\t\"[ 1444]  1020  1444     5711      581      16        0             0 bash\",\n\t\t\t\t\t\"[ 1476]  1020  1476     1809       25       9        0             0 tail\",\n\t\t\t\t\t\"[ 1532]  1020  1532   410347   398810     788        0             0 badsysprogram\",\n\t\t\t\t\t\"Out of memory: Kill process 1532 (badsysprogram) score 919 or sacrifice child\",\n\t\t\t\t\t\"Killed process 1532 (badsysprogram) total-vm:1641388kB, anon-rss:1595164kB, file-rss:76kB\",\n\t\t\t\t},\n\t\t\t}},\n\t\t\tout: []*OomInstance{{\n\t\t\t\tPid:                 1532,\n\t\t\t\tProcessName:         \"badsysprogram\",\n\t\t\t\tTimeOfDeath:         testTime,\n\t\t\t\tContainerName:       \"/\",\n\t\t\t\tVictimContainerName: \"/\",\n\t\t\t}},\n\t\t},\n\t\t{ // Multiple OOMs\n\t\t\t// These were generated via `docker run -m 20M euank/gunpowder-memhog 2G; docker run -m 300M euank/gunpowder-memhog 800M`\n\t\t\t// followed by nabbing output from `/dev/kmsg` and stripping the syslog-ish prefixes `kmsgparser` will handle anyways.\n\t\t\tin: []in{\n\t\t\t\t{\n\t\t\t\t\ttime: testTime,\n\t\t\t\t\tmsgs: []string{\n\t\t\t\t\t\t\"docker0: port 2(veth380a1cd) entered disabled state\",\n\t\t\t\t\t\t\"device veth380a1cd left promiscuous mode\",\n\t\t\t\t\t\t\"docker0: port 2(veth380a1cd) entered disabled state\",\n\t\t\t\t\t\t\"docker0: port 2(vethcd0dbfb) entered blocking state\",\n\t\t\t\t\t\t\"docker0: port 2(vethcd0dbfb) entered disabled state\",\n\t\t\t\t\t\t\"device vethcd0dbfb entered promiscuous mode\",\n\t\t\t\t\t\t\"IPv6: ADDRCONF(NETDEV_UP): vethcd0dbfb: link is not ready\",\n\t\t\t\t\t\t\"IPv6: ADDRCONF(NETDEV_CHANGE): vethcd0dbfb: link becomes ready\",\n\t\t\t\t\t\t\"docker0: port 2(vethcd0dbfb) entered blocking state\",\n\t\t\t\t\t\t\"docker0: port 2(vethcd0dbfb) entered forwarding state\",\n\t\t\t\t\t\t\"docker0: port 2(vethcd0dbfb) entered disabled state\",\n\t\t\t\t\t\t\"eth0: renamed from vethbcd01c4\",\n\t\t\t\t\t\t\"docker0: port 2(vethcd0dbfb) entered blocking state\",\n\t\t\t\t\t\t\"docker0: port 2(vethcd0dbfb) entered forwarding state\",\n\t\t\t\t\t\t\"gunpowder-memho invoked oom-killer: gfp_mask=0x24000c0(GFP_KERNEL), order=0, oom_score_adj=0\",\n\t\t\t\t\t\t\"gunpowder-memho cpuset=2e088fe462e25e60be1dafafe2c05c47bda1a97978648d10ad2b7484fc0b8f50 mems_allowed=0\",\n\t\t\t\t\t\t\"CPU: 0 PID: 1381 Comm: gunpowder-memho Tainted: G           O    4.8.0-gentoo #2\",\n\t\t\t\t\t\t\"Hardware name: LENOVO 20BSCTO1WW/20BSCTO1WW, BIOS N14ET32W (1.10 ) 08/13/2015\",\n\t\t\t\t\t\t\" 0000000000000000 ffff8800968e3ca0 ffffffff8137ad47 ffff8800968e3d68\",\n\t\t\t\t\t\t\" ffff8800b74ee540 ffff8800968e3d00 ffffffff811261dd 0000000000000003\",\n\t\t\t\t\t\t\" 0000000000000000 0000000000000001 0000000000000246 0000000000000202\",\n\t\t\t\t\t\t\"Call Trace:\",\n\t\t\t\t\t\t\" [<ffffffff8137ad47>] dump_stack+0x4d/0x63\",\n\t\t\t\t\t\t\" [<ffffffff811261dd>] dump_header+0x58/0x1c8\",\n\t\t\t\t\t\t\" [<ffffffff810e85fe>] oom_kill_process+0x7e/0x362\",\n\t\t\t\t\t\t\" [<ffffffff811221a8>] ? mem_cgroup_iter+0x109/0x23e\",\n\t\t\t\t\t\t\" [<ffffffff811239dc>] mem_cgroup_out_of_memory+0x241/0x299\",\n\t\t\t\t\t\t\" [<ffffffff81124447>] mem_cgroup_oom_synchronize+0x273/0x28c\",\n\t\t\t\t\t\t\" [<ffffffff81120839>] ? __mem_cgroup_insert_exceeded+0x76/0x76\",\n\t\t\t\t\t\t\" [<ffffffff810e8b46>] pagefault_out_of_memory+0x1f/0x76\",\n\t\t\t\t\t\t\" [<ffffffff81038f38>] mm_fault_error+0x56/0x108\",\n\t\t\t\t\t\t\" [<ffffffff81039355>] __do_page_fault+0x36b/0x3ee\",\n\t\t\t\t\t\t\" [<ffffffff81039405>] do_page_fault+0xc/0xe\",\n\t\t\t\t\t\t\" [<ffffffff81560082>] page_fault+0x22/0x30\",\n\t\t\t\t\t\t\"Task in /docker/2e088fe462e25e60be1dafafe2c05c47bda1a97978648d10ad2b7484fc0b8f50 killed as a result of limit of /docker/2e088fe462e25e60be1dafafe2c05c47bda1a97978648d10ad2b7484fc0b8f50\",\n\t\t\t\t\t\t\"memory: usage 20480kB, limit 20480kB, failcnt 1204\",\n\t\t\t\t\t\t\"memory+swap: usage 40940kB, limit 40960kB, failcnt 6\",\n\t\t\t\t\t\t\"kmem: usage 220kB, limit 9007199254740988kB, failcnt 0\",\n\t\t\t\t\t\t\"Memory cgroup stats for /docker/2e088fe462e25e60be1dafafe2c05c47bda1a97978648d10ad2b7484fc0b8f50: cache:0KB rss:20260KB rss_huge:0KB mapped_file:0KB dirty:0KB writeback:1016KB swap:20460KB inactive_anon:10232KB active_anon:10028KB inactive_file:0KB active_file:0KB unevictable:0KB\",\n\t\t\t\t\t\t\"[ pid ]   uid  tgid total_vm      rss nr_ptes nr_pmds swapents oom_score_adj name\",\n\t\t\t\t\t\t\"[ 1381]     0  1381   530382     5191      34       4     5489             0 gunpowder-memho\",\n\t\t\t\t\t\t\"Memory cgroup out of memory: Kill process 1381 (gunpowder-memho) score 1046 or sacrifice child\",\n\t\t\t\t\t\t\"Killed process 1381 (gunpowder-memho) total-vm:2121528kB, anon-rss:18624kB, file-rss:2140kB, shmem-rss:0kB\",\n\t\t\t\t\t\t\"oom_reaper: reaped process 1381 (gunpowder-memho), now anon-rss:0kB, file-rss:0kB, shmem-rss:0kB\",\n\t\t\t\t\t\t\"docker0: port 2(vethcd0dbfb) entered disabled state\",\n\t\t\t\t\t\t\"vethbcd01c4: renamed from eth0\",\n\t\t\t\t\t\t\"docker0: port 2(vethcd0dbfb) entered disabled state\",\n\t\t\t\t\t\t\"device vethcd0dbfb left promiscuous mode\",\n\t\t\t\t\t\t\"docker0: port 2(vethcd0dbfb) entered disabled state\",\n\t\t\t\t\t\t\"docker0: port 2(veth4cb51e1) entered blocking state\",\n\t\t\t\t\t\t\"docker0: port 2(veth4cb51e1) entered disabled state\",\n\t\t\t\t\t\t\"device veth4cb51e1 entered promiscuous mode\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\ttime: testTime2,\n\t\t\t\t\tmsgs: []string{\n\t\t\t\t\t\t\"IPv6: ADDRCONF(NETDEV_UP): veth4cb51e1: link is not ready\",\n\t\t\t\t\t\t\"docker0: port 2(veth4cb51e1) entered blocking state\",\n\t\t\t\t\t\t\"docker0: port 2(veth4cb51e1) entered forwarding state\",\n\t\t\t\t\t\t\"IPv6: ADDRCONF(NETDEV_CHANGE): veth4cb51e1: link becomes ready\",\n\t\t\t\t\t\t\"docker0: port 2(veth4cb51e1) entered disabled state\",\n\t\t\t\t\t\t\"eth0: renamed from veth4b89c12\",\n\t\t\t\t\t\t\"docker0: port 2(veth4cb51e1) entered blocking state\",\n\t\t\t\t\t\t\"docker0: port 2(veth4cb51e1) entered forwarding state\",\n\t\t\t\t\t\t\"gunpowder-memho invoked oom-killer: gfp_mask=0x24000c0(GFP_KERNEL), order=0, oom_score_adj=0\",\n\t\t\t\t\t\t\"gunpowder-memho cpuset=6c6fcab8562fd3150854986b78552c732f234fd405b624207b8843528a145e70 mems_allowed=0\",\n\t\t\t\t\t\t\"CPU: 0 PID: 1667 Comm: gunpowder-memho Tainted: G           O    4.8.0-gentoo #2\",\n\t\t\t\t\t\t\"Hardware name: LENOVO 20BSCTO1WW/20BSCTO1WW, BIOS N14ET32W (1.10 ) 08/13/2015\",\n\t\t\t\t\t\t\" 0000000000000000 ffff88008137fca0 ffffffff8137ad47 ffff88008137fd68\",\n\t\t\t\t\t\t\" ffff8801c75b0c40 ffff88008137fd00 ffffffff811261dd 0000000000000003\",\n\t\t\t\t\t\t\" 0000000000000000 0000000000000001 0000000000000246 0000000000000202\",\n\t\t\t\t\t\t\"Call Trace:\",\n\t\t\t\t\t\t\" [<ffffffff8137ad47>] dump_stack+0x4d/0x63\",\n\t\t\t\t\t\t\" [<ffffffff811261dd>] dump_header+0x58/0x1c8\",\n\t\t\t\t\t\t\" [<ffffffff810e85fe>] oom_kill_process+0x7e/0x362\",\n\t\t\t\t\t\t\" [<ffffffff811221a8>] ? mem_cgroup_iter+0x109/0x23e\",\n\t\t\t\t\t\t\" [<ffffffff811239dc>] mem_cgroup_out_of_memory+0x241/0x299\",\n\t\t\t\t\t\t\" [<ffffffff81124447>] mem_cgroup_oom_synchronize+0x273/0x28c\",\n\t\t\t\t\t\t\" [<ffffffff81120839>] ? __mem_cgroup_insert_exceeded+0x76/0x76\",\n\t\t\t\t\t\t\" [<ffffffff810e8b46>] pagefault_out_of_memory+0x1f/0x76\",\n\t\t\t\t\t\t\" [<ffffffff81038f38>] mm_fault_error+0x56/0x108\",\n\t\t\t\t\t\t\" [<ffffffff81039355>] __do_page_fault+0x36b/0x3ee\",\n\t\t\t\t\t\t\" [<ffffffff81039405>] do_page_fault+0xc/0xe\",\n\t\t\t\t\t\t\" [<ffffffff81560082>] page_fault+0x22/0x30\",\n\t\t\t\t\t\t\"Task in /docker/6c6fcab8562fd3150854986b78552c732f234fd405b624207b8843528a145e70 killed as a result of limit of /docker/6c6fcab8562fd3150854986b78552c732f234fd405b624207b8843528a145e70\",\n\t\t\t\t\t\t\"memory: usage 307112kB, limit 307200kB, failcnt 35982\",\n\t\t\t\t\t\t\"memory+swap: usage 614400kB, limit 614400kB, failcnt 11\",\n\t\t\t\t\t\t\"kmem: usage 1308kB, limit 9007199254740988kB, failcnt 0\",\n\t\t\t\t\t\t\"Memory cgroup stats for /docker/6c6fcab8562fd3150854986b78552c732f234fd405b624207b8843528a145e70: cache:0KB rss:305804KB rss_huge:0KB mapped_file:0KB dirty:0KB writeback:55884KB swap:307288KB inactive_anon:152940KB active_anon:152832KB inactive_file:0KB active_file:0KB unevictable:0KB\",\n\t\t\t\t\t\t\"[ pid ]   uid  tgid total_vm      rss nr_ptes nr_pmds swapents oom_score_adj name\",\n\t\t\t\t\t\t\"[ 1667]     0  1667   210894    62557     315       4    91187             0 gunpowder-memho\",\n\t\t\t\t\t\t\"Memory cgroup out of memory: Kill process 1667 (gunpowder-memho) score 1003 or sacrifice child\",\n\t\t\t\t\t\t\"Killed process 1667 (gunpowder-memho) total-vm:843576kB, anon-rss:248180kB, file-rss:2048kB, shmem-rss:0kB\",\n\t\t\t\t\t\t\"oom_reaper: reaped process 1667 (gunpowder-memho), now anon-rss:0kB, file-rss:0kB, shmem-rss:0kB\",\n\t\t\t\t\t\t\"docker0: port 2(veth4cb51e1) entered disabled state\",\n\t\t\t\t\t\t\"veth4b89c12: renamed from eth0\",\n\t\t\t\t\t\t\"docker0: port 2(veth4cb51e1) entered blocking state\",\n\t\t\t\t\t\t\"docker0: port 2(veth4cb51e1) entered forwarding state\",\n\t\t\t\t\t\t\"docker0: port 2(veth4cb51e1) entered disabled state\",\n\t\t\t\t\t\t\"device veth4cb51e1 left promiscuous mode\",\n\t\t\t\t\t\t\"docker0: port 2(veth4cb51e1) entered disabled state\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\tout: []*OomInstance{\n\t\t\t\t{\n\t\t\t\t\tPid:                 1381,\n\t\t\t\t\tProcessName:         \"gunpowder-memho\",\n\t\t\t\t\tTimeOfDeath:         testTime,\n\t\t\t\t\tContainerName:       \"/docker/2e088fe462e25e60be1dafafe2c05c47bda1a97978648d10ad2b7484fc0b8f50\",\n\t\t\t\t\tVictimContainerName: \"/docker/2e088fe462e25e60be1dafafe2c05c47bda1a97978648d10ad2b7484fc0b8f50\",\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tPid:                 1667,\n\t\t\t\t\tProcessName:         \"gunpowder-memho\",\n\t\t\t\t\tTimeOfDeath:         testTime2,\n\t\t\t\t\tContainerName:       \"/docker/6c6fcab8562fd3150854986b78552c732f234fd405b624207b8843528a145e70\",\n\t\t\t\t\tVictimContainerName: \"/docker/6c6fcab8562fd3150854986b78552c732f234fd405b624207b8843528a145e70\",\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\n\tfor _, pair := range testPairs {\n\t\tpair := pair\n\t\tgo func() {\n\t\t\tfor _, x := range pair.in {\n\t\t\t\twriteAll(x.msgs, x.time)\n\t\t\t}\n\t\t}()\n\t\tfor _, expected := range pair.out {\n\t\t\toom := <-oomsOut\n\t\t\tassert.Equal(t, expected, oom)\n\t\t}\n\n\t\tselect {\n\t\tcase oom := <-oomsOut:\n\t\t\tt.Errorf(\"did not expect any remaining OOMs, got %+v\", oom)\n\t\tdefault:\n\t\t}\n\n\t}\n}\n\ntype mockKmsgParser struct {\n\tmessages chan kmsgparser.Message\n}\n\nfunc (m *mockKmsgParser) SeekEnd() error {\n\treturn nil\n}\n\nfunc (m *mockKmsgParser) Parse() <-chan kmsgparser.Message {\n\treturn m.messages\n}\n\nfunc (m *mockKmsgParser) SetLogger(kmsgparser.Logger) {}\nfunc (m *mockKmsgParser) Close() error {\n\tclose(m.messages)\n\treturn nil\n}\n"
  },
  {
    "path": "utils/path.go",
    "content": "// Copyright 2014 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage utils\n\nimport \"os\"\n\nfunc FileExists(file string) bool {\n\tif _, err := os.Stat(file); err != nil {\n\t\treturn false\n\t}\n\treturn true\n}\n"
  },
  {
    "path": "utils/sysfs/fakesysfs/fake.go",
    "content": "// Copyright 2014 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage fakesysfs\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\t\"time\"\n\n\t\"github.com/google/cadvisor/utils/sysfs\"\n)\n\n// If we extend sysfs to support more interfaces, it might be worth making this a mock instead of a fake.\ntype FileInfo struct {\n\tEntryName string\n}\n\nfunc (i *FileInfo) Name() string {\n\treturn i.EntryName\n}\n\nfunc (i *FileInfo) Size() int64 {\n\treturn 1234567\n}\n\nfunc (i *FileInfo) Mode() os.FileMode {\n\treturn 0\n}\n\nfunc (i *FileInfo) ModTime() time.Time {\n\treturn time.Time{}\n}\n\nfunc (i *FileInfo) IsDir() bool {\n\treturn true\n}\n\nfunc (i *FileInfo) Sys() interface{} {\n\treturn nil\n}\n\ntype FakeSysFs struct {\n\tinfo  FileInfo\n\tcache sysfs.CacheInfo\n\n\tnodesPaths  []string\n\tnodePathErr error\n\n\tcpusPaths  map[string][]string\n\tcpuPathErr error\n\n\tcoreThread map[string]string\n\tcoreIDErr  map[string]error\n\n\tphysicalPackageIDs   map[string]string\n\tphysicalPackageIDErr map[string]error\n\n\tbookIDs   map[string]string\n\tbookIDErr map[string]error\n\n\tdrawerIDs   map[string]string\n\tdrawerIDErr map[string]error\n\n\tmemTotal string\n\tmemErr   error\n\n\thugePages    []os.FileInfo\n\thugePagesErr error\n\n\thugePagesNr    map[string]string\n\thugePagesNrErr error\n\n\tdistances    map[string]string\n\tdistancesErr error\n\n\tonlineCPUs map[string]interface{}\n}\n\nfunc (fs *FakeSysFs) GetNodesPaths() ([]string, error) {\n\treturn fs.nodesPaths, fs.nodePathErr\n}\n\nfunc (fs *FakeSysFs) GetCPUsPaths(cpusPath string) ([]string, error) {\n\treturn fs.cpusPaths[cpusPath], fs.cpuPathErr\n}\n\nfunc (fs *FakeSysFs) GetCoreID(coreIDPath string) (string, error) {\n\treturn fs.coreThread[coreIDPath], fs.coreIDErr[coreIDPath]\n}\n\nfunc (fs *FakeSysFs) GetCPUPhysicalPackageID(cpuPath string) (string, error) {\n\treturn fs.physicalPackageIDs[cpuPath], fs.physicalPackageIDErr[cpuPath]\n}\n\nfunc (fs *FakeSysFs) GetBookID(coreIDPath string) (string, error) {\n\treturn fs.bookIDs[coreIDPath], fs.bookIDErr[coreIDPath]\n}\n\nfunc (fs *FakeSysFs) GetDrawerID(coreIDPath string) (string, error) {\n\treturn fs.drawerIDs[coreIDPath], fs.drawerIDErr[coreIDPath]\n}\n\nfunc (fs *FakeSysFs) GetMemInfo(nodePath string) (string, error) {\n\treturn fs.memTotal, fs.memErr\n}\n\nfunc (fs *FakeSysFs) GetHugePagesInfo(hugepagesDirectory string) ([]os.FileInfo, error) {\n\treturn fs.hugePages, fs.hugePagesErr\n}\n\nfunc (fs *FakeSysFs) GetHugePagesNr(hugepagesDirectory string, hugePageName string) (string, error) {\n\thugePageFile := fmt.Sprintf(\"%s%s/%s\", hugepagesDirectory, hugePageName, sysfs.HugePagesNrFile)\n\treturn fs.hugePagesNr[hugePageFile], fs.hugePagesNrErr\n}\n\nfunc (fs *FakeSysFs) GetBlockDevices() ([]os.FileInfo, error) {\n\tfs.info.EntryName = \"sda\"\n\treturn []os.FileInfo{&fs.info}, nil\n}\n\nfunc (fs *FakeSysFs) GetBlockDeviceSize(name string) (string, error) {\n\treturn \"1234567\", nil\n}\n\nfunc (fs *FakeSysFs) GetBlockDeviceScheduler(name string) (string, error) {\n\treturn \"noop deadline [cfq]\", nil\n}\n\nfunc (fs *FakeSysFs) GetBlockDeviceNumbers(name string) (string, error) {\n\treturn \"8:0\\n\", nil\n}\n\nfunc (fs *FakeSysFs) IsBlockDeviceHidden(name string) (bool, error) {\n\treturn false, nil\n}\n\nfunc (fs *FakeSysFs) GetNetworkDevices() ([]os.FileInfo, error) {\n\treturn []os.FileInfo{&fs.info}, nil\n}\n\nfunc (fs *FakeSysFs) GetNetworkAddress(name string) (string, error) {\n\treturn \"42:01:02:03:04:f4\\n\", nil\n}\n\nfunc (fs *FakeSysFs) GetNetworkMtu(name string) (string, error) {\n\treturn \"1024\\n\", nil\n}\n\nfunc (fs *FakeSysFs) GetNetworkSpeed(name string) (string, error) {\n\treturn \"1000\\n\", nil\n}\n\nfunc (fs *FakeSysFs) GetNetworkStatValue(name string, stat string) (uint64, error) {\n\treturn 1024, nil\n}\n\nfunc (fs *FakeSysFs) GetCaches(id int) ([]os.FileInfo, error) {\n\tfs.info.EntryName = \"index0\"\n\treturn []os.FileInfo{&fs.info}, nil\n}\n\nfunc (fs *FakeSysFs) GetCacheInfo(cpu int, cache string) (sysfs.CacheInfo, error) {\n\treturn fs.cache, nil\n}\n\nfunc (fs *FakeSysFs) SetCacheInfo(cache sysfs.CacheInfo) {\n\tfs.cache = cache\n}\n\nfunc (fs *FakeSysFs) SetNodesPaths(paths []string, err error) {\n\tfs.nodesPaths = paths\n\tfs.nodePathErr = err\n}\n\nfunc (fs *FakeSysFs) SetCPUsPaths(paths map[string][]string, err error) {\n\tfs.cpusPaths = paths\n\tfs.cpuPathErr = err\n}\n\nfunc (fs *FakeSysFs) SetCoreThreads(coreThread map[string]string, coreThreadErrors map[string]error) {\n\tfs.coreThread = coreThread\n\tfs.coreIDErr = coreThreadErrors\n}\n\nfunc (fs *FakeSysFs) SetPhysicalPackageIDs(physicalPackageIDs map[string]string, physicalPackageIDErrors map[string]error) {\n\tfs.physicalPackageIDs = physicalPackageIDs\n\tfs.physicalPackageIDErr = physicalPackageIDErrors\n}\n\nfunc (fs *FakeSysFs) SetBookIDs(bookIDs map[string]string, bookIDErrors map[string]error) {\n\tfs.bookIDs = bookIDs\n\tfs.bookIDErr = bookIDErrors\n}\n\nfunc (fs *FakeSysFs) SetDrawerIDs(drawerIDs map[string]string, drawerIDErrors map[string]error) {\n\tfs.drawerIDs = drawerIDs\n\tfs.drawerIDErr = drawerIDErrors\n}\n\nfunc (fs *FakeSysFs) SetMemory(memTotal string, err error) {\n\tfs.memTotal = memTotal\n\tfs.memErr = err\n}\n\nfunc (fs *FakeSysFs) SetHugePages(hugePages []os.FileInfo, err error) {\n\tfs.hugePages = hugePages\n\tfs.hugePagesErr = err\n}\n\nfunc (fs *FakeSysFs) SetHugePagesNr(hugePagesNr map[string]string, err error) {\n\tfs.hugePagesNr = hugePagesNr\n\tfs.hugePagesNrErr = err\n}\n\nfunc (fs *FakeSysFs) SetEntryName(name string) {\n\tfs.info.EntryName = name\n}\n\nfunc (fs *FakeSysFs) GetSystemUUID() (string, error) {\n\treturn \"1F862619-BA9F-4526-8F85-ECEAF0C97430\", nil\n}\n\nfunc (fs *FakeSysFs) GetDistances(nodeDir string) (string, error) {\n\tif fs.distancesErr != nil {\n\t\treturn \"\", fs.distancesErr\n\t}\n\n\tif _, ok := fs.distances[nodeDir]; !ok {\n\t\treturn \"\", fmt.Errorf(\"distance not found\")\n\t}\n\n\treturn fs.distances[nodeDir], nil\n}\n\nfunc (fs *FakeSysFs) SetDistances(nodeDir string, distances string, err error) {\n\tif fs.distances == nil {\n\t\tfs.distances = map[string]string{nodeDir: distances}\n\t} else {\n\t\tfs.distances[nodeDir] = distances\n\t}\n\tfs.distancesErr = err\n}\n\nfunc (fs *FakeSysFs) IsCPUOnline(dir string) bool {\n\tif fs.onlineCPUs == nil {\n\t\treturn true\n\t}\n\t_, ok := fs.onlineCPUs[dir]\n\treturn ok\n}\n\nfunc (fs *FakeSysFs) SetOnlineCPUs(online map[string]interface{}) {\n\tfs.onlineCPUs = online\n}\n"
  },
  {
    "path": "utils/sysfs/sysfs.go",
    "content": "// Copyright 2014 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage sysfs\n\nimport (\n\t\"bytes\"\n\t\"fmt\"\n\t\"os\"\n\t\"path\"\n\t\"path/filepath\"\n\t\"regexp\"\n\t\"runtime\"\n\t\"strconv\"\n\t\"strings\"\n\n\t\"k8s.io/klog/v2\"\n)\n\nconst (\n\tblockDir     = \"/sys/block\"\n\tcacheDir     = \"/sys/devices/system/cpu/cpu\"\n\tnetDir       = \"/sys/class/net\"\n\tdmiDir       = \"/sys/class/dmi\"\n\tppcDevTree   = \"/proc/device-tree\"\n\ts390xDevTree = \"/etc\" // s390/s390x changes\n\n\tmeminfoFile = \"meminfo\"\n\n\tdistanceFile = \"distance\"\n\n\tsysFsCPUTopology = \"topology\"\n\n\t// CPUPhysicalPackageID is a physical package id of cpu#. Typically corresponds to a physical socket number,\n\t// but the actual value is architecture and platform dependent.\n\tCPUPhysicalPackageID = \"physical_package_id\"\n\t// CPUCoreID is the CPU core ID of cpu#. Typically it is the hardware platform's identifier\n\t// (rather than the kernel's). The actual value is architecture and platform dependent.\n\tCPUCoreID = \"core_id\"\n\n\t// On some architecture there exists additional level of book and drawer id\n\t// CPUBookID is the book ID of cpu#. Typically corresponds to a physical book number.\n\tCPUBookID = \"book_id\"\n\t// CPUDrawerID is the drawer ID of cpu#. Typically corresponds to a physical drawer number.\n\tCPUDrawerID = \"drawer_id\"\n\n\tcoreIDFilePath    = \"/\" + sysFsCPUTopology + \"/core_id\"\n\tpackageIDFilePath = \"/\" + sysFsCPUTopology + \"/physical_package_id\"\n\tbookIDFilePath    = \"/\" + sysFsCPUTopology + \"/book_id\"\n\tdrawerIDFilePath  = \"/\" + sysFsCPUTopology + \"/drawer_id\"\n\n\t// memory size calculations\n\n\tcpuDirPattern  = \"cpu*[0-9]\"\n\tnodeDirPattern = \"node*[0-9]\"\n\n\t//HugePagesNrFile name of nr_hugepages file in sysfs\n\tHugePagesNrFile = \"nr_hugepages\"\n)\n\nvar (\n\tnodeDir = \"/sys/devices/system/node/\"\n)\n\ntype CacheInfo struct {\n\t// cache id\n\tId int\n\t// size in bytes\n\tSize uint64\n\t// cache type - instruction, data, unified\n\tType string\n\t// distance from cpus in a multi-level hierarchy\n\tLevel int\n\t// number of cpus that can access this cache.\n\tCpus int\n}\n\n// Abstracts the lowest level calls to sysfs.\ntype SysFs interface {\n\t// Get NUMA nodes paths\n\tGetNodesPaths() ([]string, error)\n\t// Get paths to CPUs in provided directory e.g. /sys/devices/system/node/node0 or /sys/devices/system/cpu\n\tGetCPUsPaths(cpusPath string) ([]string, error)\n\t// Get physical core id for specified CPU\n\tGetCoreID(coreIDFilePath string) (string, error)\n\t// Get physical package id for specified CPU\n\tGetCPUPhysicalPackageID(cpuPath string) (string, error)\n\t// Get book id for specified CPU\n\tGetBookID(cpuPath string) (string, error)\n\t// Get drawer id for specified CPU\n\tGetDrawerID(cpuPath string) (string, error)\n\t// Get total memory for specified NUMA node\n\tGetMemInfo(nodeDir string) (string, error)\n\t// Get hugepages from specified directory\n\tGetHugePagesInfo(hugePagesDirectory string) ([]os.FileInfo, error)\n\t// Get hugepage_nr from specified directory\n\tGetHugePagesNr(hugePagesDirectory string, hugePageName string) (string, error)\n\t// Get directory information for available block devices.\n\tGetBlockDevices() ([]os.FileInfo, error)\n\t// Get Size of a given block device.\n\tGetBlockDeviceSize(string) (string, error)\n\t// Get scheduler type for the block device.\n\tGetBlockDeviceScheduler(string) (string, error)\n\t// Get device major:minor number string.\n\tGetBlockDeviceNumbers(string) (string, error)\n\t// Is the device \"hidden\" (meaning will not have a device handle)\n\t// This is the case with native nvme multipathing.\n\tIsBlockDeviceHidden(string) (bool, error)\n\n\tGetNetworkDevices() ([]os.FileInfo, error)\n\tGetNetworkAddress(string) (string, error)\n\tGetNetworkMtu(string) (string, error)\n\tGetNetworkSpeed(string) (string, error)\n\tGetNetworkStatValue(dev string, stat string) (uint64, error)\n\n\t// Get directory information for available caches accessible to given cpu.\n\tGetCaches(id int) ([]os.FileInfo, error)\n\t// Get information for a cache accessible from the given cpu.\n\tGetCacheInfo(cpu int, cache string) (CacheInfo, error)\n\n\tGetSystemUUID() (string, error)\n\n\t// GetDistances returns distance array\n\tGetDistances(string) (string, error)\n\n\t// IsCPUOnline determines if CPU status from kernel hotplug machanism standpoint.\n\t// See: https://www.kernel.org/doc/html/latest/core-api/cpu_hotplug.html\n\tIsCPUOnline(dir string) bool\n}\n\ntype realSysFs struct {\n\tcpuPath string\n}\n\nfunc NewRealSysFs() SysFs {\n\treturn &realSysFs{\n\t\tcpuPath: \"/sys/devices/system/cpu\",\n\t}\n}\n\nfunc (fs *realSysFs) GetNodesPaths() ([]string, error) {\n\tpathPattern := fmt.Sprintf(\"%s%s\", nodeDir, nodeDirPattern)\n\treturn filepath.Glob(pathPattern)\n}\n\nfunc (fs *realSysFs) GetCPUsPaths(cpusPath string) ([]string, error) {\n\tpathPattern := fmt.Sprintf(\"%s/%s\", cpusPath, cpuDirPattern)\n\treturn filepath.Glob(pathPattern)\n}\n\nfunc (fs *realSysFs) GetCoreID(cpuPath string) (string, error) {\n\tcoreIDFilePath := fmt.Sprintf(\"%s%s\", cpuPath, coreIDFilePath)\n\tcoreID, err := os.ReadFile(coreIDFilePath)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\treturn strings.TrimSpace(string(coreID)), err\n}\n\nfunc (fs *realSysFs) GetCPUPhysicalPackageID(cpuPath string) (string, error) {\n\tpackageIDFilePath := fmt.Sprintf(\"%s%s\", cpuPath, packageIDFilePath)\n\tpackageID, err := os.ReadFile(packageIDFilePath)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\treturn strings.TrimSpace(string(packageID)), err\n}\n\nfunc (fs *realSysFs) GetBookID(cpuPath string) (string, error) {\n\tbookIDFilePath := fmt.Sprintf(\"%s%s\", cpuPath, bookIDFilePath)\n\tbookID, err := os.ReadFile(bookIDFilePath)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\treturn strings.TrimSpace(string(bookID)), nil\n}\n\nfunc (fs *realSysFs) GetDrawerID(cpuPath string) (string, error) {\n\tdrawerIDFilePath := fmt.Sprintf(\"%s%s\", cpuPath, drawerIDFilePath)\n\tdrawerID, err := os.ReadFile(drawerIDFilePath)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\treturn strings.TrimSpace(string(drawerID)), nil\n}\n\nfunc (fs *realSysFs) GetMemInfo(nodePath string) (string, error) {\n\tmeminfoPath := fmt.Sprintf(\"%s/%s\", nodePath, meminfoFile)\n\tmeminfo, err := os.ReadFile(meminfoPath)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\treturn strings.TrimSpace(string(meminfo)), err\n}\n\nfunc (fs *realSysFs) GetDistances(nodePath string) (string, error) {\n\tdistancePath := fmt.Sprintf(\"%s/%s\", nodePath, distanceFile)\n\tdistance, err := os.ReadFile(distancePath)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\treturn strings.TrimSpace(string(distance)), err\n}\n\nfunc (fs *realSysFs) GetHugePagesInfo(hugePagesDirectory string) ([]os.FileInfo, error) {\n\tdirs, err := os.ReadDir(hugePagesDirectory)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn toFileInfo(dirs)\n}\n\nfunc (fs *realSysFs) GetHugePagesNr(hugepagesDirectory string, hugePageName string) (string, error) {\n\thugePageFilePath := fmt.Sprintf(\"%s%s/%s\", hugepagesDirectory, hugePageName, HugePagesNrFile)\n\thugePageFile, err := os.ReadFile(hugePageFilePath)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\treturn strings.TrimSpace(string(hugePageFile)), err\n}\n\nfunc (fs *realSysFs) GetBlockDevices() ([]os.FileInfo, error) {\n\tdirs, err := os.ReadDir(blockDir)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn toFileInfo(dirs)\n}\n\nfunc (fs *realSysFs) GetBlockDeviceNumbers(name string) (string, error) {\n\tdev, err := os.ReadFile(path.Join(blockDir, name, \"/dev\"))\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\treturn string(dev), nil\n}\n\nfunc (fs *realSysFs) IsBlockDeviceHidden(name string) (bool, error) {\n\t// See: https://www.kernel.org/doc/Documentation/ABI/stable/sysfs-block\n\t//      https://git.kernel.org/pub/scm/utils/util-linux/util-linux.git\n\t//        - c8487d854ba5 (\"lsblk: Ignore hidden devices\")\n\tdevHiddenPath := path.Join(blockDir, name, \"/hidden\")\n\thidden, err := os.ReadFile(devHiddenPath)\n\tif err != nil && os.IsNotExist(err) {\n\t\t// older OS may not have /hidden sysfs entry, so for sure\n\t\t// it is not a hidden device...\n\t\treturn false, nil\n\t}\n\tif err != nil {\n\t\treturn false, fmt.Errorf(\"failed to read %s: %w\", devHiddenPath, err)\n\t}\n\n\treturn strings.TrimSpace(string(hidden)) == \"1\", nil\n}\n\nfunc (fs *realSysFs) GetBlockDeviceScheduler(name string) (string, error) {\n\tsched, err := os.ReadFile(path.Join(blockDir, name, \"/queue/scheduler\"))\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\treturn string(sched), nil\n}\n\nfunc (fs *realSysFs) GetBlockDeviceSize(name string) (string, error) {\n\tsize, err := os.ReadFile(path.Join(blockDir, name, \"/size\"))\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\treturn string(size), nil\n}\n\nfunc (fs *realSysFs) GetNetworkDevices() ([]os.FileInfo, error) {\n\tdirs, err := os.ReadDir(netDir)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tfiles, err := toFileInfo(dirs)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\t// Filter out non-directory & non-symlink files\n\tfiltered := []os.FileInfo{}\n\tfor _, f := range files {\n\t\tif f.Mode()|os.ModeSymlink != 0 {\n\t\t\tf, err = os.Stat(path.Join(netDir, f.Name()))\n\t\t\tif err != nil {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t}\n\t\tif f.IsDir() {\n\t\t\tfiltered = append(filtered, f)\n\t\t}\n\t}\n\treturn filtered, nil\n}\n\nfunc (fs *realSysFs) GetNetworkAddress(name string) (string, error) {\n\taddress, err := os.ReadFile(path.Join(netDir, name, \"/address\"))\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\treturn string(address), nil\n}\n\nfunc (fs *realSysFs) GetNetworkMtu(name string) (string, error) {\n\tmtu, err := os.ReadFile(path.Join(netDir, name, \"/mtu\"))\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\treturn string(mtu), nil\n}\n\nfunc (fs *realSysFs) GetNetworkSpeed(name string) (string, error) {\n\tspeed, err := os.ReadFile(path.Join(netDir, name, \"/speed\"))\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\treturn string(speed), nil\n}\n\nfunc (fs *realSysFs) GetNetworkStatValue(dev string, stat string) (uint64, error) {\n\tstatPath := path.Join(netDir, dev, \"/statistics\", stat)\n\tout, err := os.ReadFile(statPath)\n\tif err != nil {\n\t\treturn 0, fmt.Errorf(\"failed to read stat from %q for device %q\", statPath, dev)\n\t}\n\tvar s uint64\n\tn, err := fmt.Sscanf(string(out), \"%d\", &s)\n\tif err != nil || n != 1 {\n\t\treturn 0, fmt.Errorf(\"could not parse value from %q for file %s\", string(out), statPath)\n\t}\n\treturn s, nil\n}\n\nfunc (fs *realSysFs) GetCaches(id int) ([]os.FileInfo, error) {\n\tcpuPath := fmt.Sprintf(\"%s%d/cache\", cacheDir, id)\n\tdir, err := os.ReadDir(cpuPath)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn toFileInfo(dir)\n}\n\nfunc toFileInfo(dirs []os.DirEntry) ([]os.FileInfo, error) {\n\tinfo := []os.FileInfo{}\n\tfor _, dir := range dirs {\n\t\tfI, err := dir.Info()\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tinfo = append(info, fI)\n\t}\n\treturn info, nil\n}\n\nfunc bitCount(i uint64) (count int) {\n\tfor i != 0 {\n\t\tif i&1 == 1 {\n\t\t\tcount++\n\t\t}\n\t\ti >>= 1\n\t}\n\treturn\n}\n\nfunc getCPUCount(cache string) (count int, err error) {\n\tout, err := os.ReadFile(path.Join(cache, \"/shared_cpu_map\"))\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\tmasks := strings.Split(string(out), \",\")\n\tfor _, mask := range masks {\n\t\t// convert hex string to uint64\n\t\tm, err := strconv.ParseUint(strings.TrimSpace(mask), 16, 64)\n\t\tif err != nil {\n\t\t\treturn 0, fmt.Errorf(\"failed to parse cpu map %q: %v\", string(out), err)\n\t\t}\n\t\tcount += bitCount(m)\n\t}\n\treturn\n}\n\nfunc (fs *realSysFs) GetCacheInfo(cpu int, name string) (CacheInfo, error) {\n\tcachePath := fmt.Sprintf(\"%s%d/cache/%s\", cacheDir, cpu, name)\n\tvar id int\n\tif runtime.GOARCH != \"s390x\" {\n\t\tout, err := os.ReadFile(path.Join(cachePath, \"/id\"))\n\t\tif err != nil {\n\t\t\treturn CacheInfo{}, err\n\t\t}\n\t\tn, err := fmt.Sscanf(string(out), \"%d\", &id)\n\t\tif err != nil || n != 1 {\n\t\t\treturn CacheInfo{}, err\n\t\t}\n\t}\n\n\tout, err := os.ReadFile(path.Join(cachePath, \"/size\"))\n\tif err != nil {\n\t\treturn CacheInfo{}, err\n\t}\n\tvar size uint64\n\tn, err := fmt.Sscanf(string(out), \"%dK\", &size)\n\tif err != nil || n != 1 {\n\t\treturn CacheInfo{}, err\n\t}\n\t// convert to bytes\n\tsize = size * 1024\n\tout, err = os.ReadFile(path.Join(cachePath, \"/level\"))\n\tif err != nil {\n\t\treturn CacheInfo{}, err\n\t}\n\tvar level int\n\tn, err = fmt.Sscanf(string(out), \"%d\", &level)\n\tif err != nil || n != 1 {\n\t\treturn CacheInfo{}, err\n\t}\n\n\tout, err = os.ReadFile(path.Join(cachePath, \"/type\"))\n\tif err != nil {\n\t\treturn CacheInfo{}, err\n\t}\n\tcacheType := strings.TrimSpace(string(out))\n\tcpuCount, err := getCPUCount(cachePath)\n\tif err != nil {\n\t\treturn CacheInfo{}, err\n\t}\n\treturn CacheInfo{\n\t\tId:    id,\n\t\tSize:  size,\n\t\tLevel: level,\n\t\tType:  cacheType,\n\t\tCpus:  cpuCount,\n\t}, nil\n}\n\nfunc (fs *realSysFs) GetSystemUUID() (string, error) {\n\tif id, err := os.ReadFile(path.Join(dmiDir, \"id\", \"product_uuid\")); err == nil {\n\t\treturn strings.TrimSpace(string(id)), nil\n\t} else if id, err = os.ReadFile(path.Join(ppcDevTree, \"system-id\")); err == nil {\n\t\treturn strings.TrimSpace(strings.TrimRight(string(id), \"\\000\")), nil\n\t} else if id, err = os.ReadFile(path.Join(ppcDevTree, \"vm,uuid\")); err == nil {\n\t\treturn strings.TrimSpace(strings.TrimRight(string(id), \"\\000\")), nil\n\t} else if id, err = os.ReadFile(path.Join(s390xDevTree, \"machine-id\")); err == nil {\n\t\treturn strings.TrimSpace(string(id)), nil\n\t} else {\n\t\treturn \"\", err\n\t}\n}\n\nfunc (fs *realSysFs) IsCPUOnline(cpuPath string) bool {\n\tcpuOnlinePath, err := filepath.Abs(fs.cpuPath + \"/online\")\n\tif err != nil {\n\t\tklog.V(1).Infof(\"Unable to get absolute path for %s\", cpuPath)\n\t\treturn false\n\t}\n\n\t// Quick check to determine if file exists: if it does not then kernel CPU hotplug is disabled and all CPUs are online.\n\t_, err = os.Stat(cpuOnlinePath)\n\tif err != nil && os.IsNotExist(err) {\n\t\treturn true\n\t}\n\tif err != nil {\n\t\tklog.V(1).Infof(\"Unable to stat %s: %s\", cpuOnlinePath, err)\n\t}\n\n\tcpuID, err := getCPUID(cpuPath)\n\tif err != nil {\n\t\tklog.V(1).Infof(\"Unable to get CPU ID from path %s: %s\", cpuPath, err)\n\t\treturn false\n\t}\n\n\tisOnline, err := isCPUOnline(cpuOnlinePath, cpuID)\n\tif err != nil {\n\t\tklog.V(1).Infof(\"Unable to get online CPUs list: %s\", err)\n\t\treturn false\n\t}\n\treturn isOnline\n}\n\nfunc getCPUID(dir string) (uint16, error) {\n\tregex := regexp.MustCompile(\"cpu([0-9]+)\")\n\tmatches := regex.FindStringSubmatch(dir)\n\tif len(matches) == 2 {\n\t\tid, err := strconv.Atoi(matches[1])\n\t\tif err != nil {\n\t\t\treturn 0, err\n\t\t}\n\t\treturn uint16(id), nil\n\t}\n\treturn 0, fmt.Errorf(\"can't get CPU ID from %s\", dir)\n}\n\n// isCPUOnline is copied from github.com/opencontainers/runc/libcontainer/cgroups/fs and modified to suite cAdvisor\n// needs as Apache 2.0 license allows.\n// It parses CPU list (such as: 0,3-5,10) into a struct that allows to determine quickly if CPU or particular ID is online.\n// see: https://github.com/opencontainers/runc/blob/ab27e12cebf148aa5d1ee3ad13d9fc7ae12bf0b6/libcontainer/cgroups/fs/cpuset.go#L45\nfunc isCPUOnline(path string, cpuID uint16) (bool, error) {\n\tfileContent, err := os.ReadFile(path)\n\tif err != nil {\n\t\treturn false, err\n\t}\n\tif len(fileContent) == 0 {\n\t\treturn false, fmt.Errorf(\"%s found to be empty\", path)\n\t}\n\n\tcpuList := strings.TrimSpace(string(fileContent))\n\tfor _, s := range strings.Split(cpuList, \",\") {\n\t\tsplitted := strings.SplitN(s, \"-\", 3)\n\t\tswitch len(splitted) {\n\t\tcase 3:\n\t\t\treturn false, fmt.Errorf(\"invalid values in %s\", path)\n\t\tcase 2:\n\t\t\tmin, err := strconv.ParseUint(splitted[0], 10, 16)\n\t\t\tif err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t\tmax, err := strconv.ParseUint(splitted[1], 10, 16)\n\t\t\tif err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t\tif min > max {\n\t\t\t\treturn false, fmt.Errorf(\"invalid values in %s\", path)\n\t\t\t}\n\t\t\t// Return true, if the CPU under consideration is in the range of online CPUs.\n\t\t\tif cpuID >= uint16(min) && cpuID <= uint16(max) {\n\t\t\t\treturn true, nil\n\t\t\t}\n\t\tcase 1:\n\t\t\tvalue, err := strconv.ParseUint(s, 10, 16)\n\t\t\tif err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t\tif uint16(value) == cpuID {\n\t\t\t\treturn true, nil\n\t\t\t}\n\t\t}\n\t}\n\n\treturn false, nil\n}\n\n// Looks for sysfs cpu path containing given CPU property, e.g. core_id or physical_package_id\n// and returns number of unique values of given property, exemplary usage: getting number of CPU physical cores\nfunc GetUniqueCPUPropertyCount(cpuAttributesPath string, propertyName string) int {\n\tabsCPUAttributesPath, err := filepath.Abs(cpuAttributesPath)\n\tif err != nil {\n\t\tklog.Errorf(\"Cannot make %s absolute\", cpuAttributesPath)\n\t\treturn 0\n\t}\n\tpathPattern := absCPUAttributesPath + \"/cpu*[0-9]\"\n\tsysCPUPaths, err := filepath.Glob(pathPattern)\n\tif err != nil {\n\t\tklog.Errorf(\"Cannot find files matching pattern (pathPattern: %s),  number of unique %s set to 0\", pathPattern, propertyName)\n\t\treturn 0\n\t}\n\tcpuOnlinePath, err := filepath.Abs(cpuAttributesPath + \"/online\")\n\tif err != nil {\n\t\tklog.V(1).Infof(\"Unable to get absolute path for %s\", cpuAttributesPath+\"/../online\")\n\t\treturn 0\n\t}\n\n\tif err != nil {\n\t\tklog.V(1).Infof(\"Unable to get online CPUs list: %s\", err)\n\t\treturn 0\n\t}\n\tuniques := make(map[string]bool)\n\tfor _, sysCPUPath := range sysCPUPaths {\n\t\tcpuID, err := getCPUID(sysCPUPath)\n\t\tif err != nil {\n\t\t\tklog.V(1).Infof(\"Unable to get CPU ID from path %s: %s\", sysCPUPath, err)\n\t\t\treturn 0\n\t\t}\n\t\tisOnline, err := isCPUOnline(cpuOnlinePath, cpuID)\n\t\tif err != nil && !os.IsNotExist(err) {\n\t\t\tklog.V(1).Infof(\"Unable to determine CPU online state: %s\", err)\n\t\t\tcontinue\n\t\t}\n\t\tif !isOnline && !os.IsNotExist(err) {\n\t\t\tcontinue\n\t\t}\n\t\tpropertyPath := filepath.Join(sysCPUPath, sysFsCPUTopology, propertyName)\n\t\tpropertyVal, err := os.ReadFile(propertyPath)\n\t\tif err != nil {\n\t\t\tklog.Warningf(\"Cannot open %s, assuming 0 for %s of CPU %d\", propertyPath, propertyName, cpuID)\n\t\t\tpropertyVal = []byte(\"0\")\n\t\t}\n\t\tpackagePath := filepath.Join(sysCPUPath, sysFsCPUTopology, CPUPhysicalPackageID)\n\t\tpackageVal, err := os.ReadFile(packagePath)\n\t\tif err != nil {\n\t\t\tklog.Warningf(\"Cannot open %s, assuming 0 %s of CPU %d\", packagePath, CPUPhysicalPackageID, cpuID)\n\t\t\tpackageVal = []byte(\"0\")\n\n\t\t}\n\t\tuniques[fmt.Sprintf(\"%s_%s\", bytes.TrimSpace(propertyVal), bytes.TrimSpace(packageVal))] = true\n\t}\n\treturn len(uniques)\n}\n"
  },
  {
    "path": "utils/sysfs/sysfs_notx86.go",
    "content": "//go:build !x86\n\n// Copyright 2021 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage sysfs\n\nvar isX86 = false\n"
  },
  {
    "path": "utils/sysfs/sysfs_test.go",
    "content": "// Copyright 2020 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage sysfs\n\nimport (\n\t\"os\"\n\t\"strconv\"\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/assert\"\n)\n\nfunc TestGetNodes(t *testing.T) {\n\t//overwrite global variable\n\tnodeDir = \"./testdata/\"\n\n\tsysFs := NewRealSysFs()\n\tnodesDirs, err := sysFs.GetNodesPaths()\n\tassert.Nil(t, err)\n\tassert.Equal(t, 2, len(nodesDirs))\n\tassert.Contains(t, nodesDirs, \"testdata/node0\")\n\tassert.Contains(t, nodesDirs, \"testdata/node1\")\n}\n\nfunc TestGetNodesWithNonExistingDir(t *testing.T) {\n\t//overwrite global variable\n\tnodeDir = \"./testdata/NonExistingDir/\"\n\n\tsysFs := NewRealSysFs()\n\tnodesDirs, err := sysFs.GetNodesPaths()\n\tassert.Nil(t, err)\n\tassert.Equal(t, 0, len(nodesDirs))\n}\n\nfunc TestGetCPUsPaths(t *testing.T) {\n\tsysFs := NewRealSysFs()\n\tcpuDirs, err := sysFs.GetCPUsPaths(\"./testdata/node0\")\n\tassert.Nil(t, err)\n\tassert.Equal(t, 2, len(cpuDirs))\n\tassert.Contains(t, cpuDirs, \"testdata/node0/cpu0\")\n\tassert.Contains(t, cpuDirs, \"testdata/node0/cpu1\")\n}\n\nfunc TestGetCPUsPathsFromNodeWithoutCPU(t *testing.T) {\n\tsysFs := NewRealSysFs()\n\tcpuDirs, err := sysFs.GetCPUsPaths(\"./testdata/node1\")\n\tassert.Nil(t, err)\n\tassert.Equal(t, 0, len(cpuDirs))\n}\n\nfunc TestGetCoreID(t *testing.T) {\n\tsysFs := NewRealSysFs()\n\trawCoreID, err := sysFs.GetCoreID(\"./testdata/node0/cpu0\")\n\tassert.Nil(t, err)\n\n\tcoreID, err := strconv.Atoi(rawCoreID)\n\tassert.Nil(t, err)\n\tassert.Equal(t, 0, coreID)\n}\n\nfunc TestGetCoreIDWhenFileIsMissing(t *testing.T) {\n\tsysFs := NewRealSysFs()\n\trawCoreID, err := sysFs.GetCoreID(\"./testdata/node0/cpu1\")\n\tassert.NotNil(t, err)\n\tassert.Equal(t, \"\", rawCoreID)\n}\n\nfunc TestGetMemInfo(t *testing.T) {\n\tsysFs := NewRealSysFs()\n\tmemInfo, err := sysFs.GetMemInfo(\"./testdata/node0\")\n\tassert.Nil(t, err)\n\tassert.Equal(t, \"Node 0 MemTotal:       32817192 kB\", memInfo)\n}\n\nfunc TestGetMemInfoWhenFileIsMissing(t *testing.T) {\n\tsysFs := NewRealSysFs()\n\tmemInfo, err := sysFs.GetMemInfo(\"./testdata/node1\")\n\tassert.NotNil(t, err)\n\tassert.Equal(t, \"\", memInfo)\n}\n\nfunc TestGetHugePagesInfo(t *testing.T) {\n\tsysFs := NewRealSysFs()\n\thugePages, err := sysFs.GetHugePagesInfo(\"./testdata/node0/hugepages\")\n\tassert.Nil(t, err)\n\tassert.Equal(t, 2, len(hugePages))\n\tassert.Equal(t, \"hugepages-1048576kB\", hugePages[0].Name())\n\tassert.Equal(t, \"hugepages-2048kB\", hugePages[1].Name())\n}\n\nfunc TestGetHugePagesInfoWhenDirIsMissing(t *testing.T) {\n\tsysFs := NewRealSysFs()\n\thugePages, err := sysFs.GetHugePagesInfo(\"./testdata/node1/hugepages\")\n\tassert.NotNil(t, err)\n\tassert.Equal(t, []os.FileInfo([]os.FileInfo(nil)), hugePages)\n}\n\nfunc TestGetHugePagesNr(t *testing.T) {\n\tsysFs := NewRealSysFs()\n\trawHugePageNr, err := sysFs.GetHugePagesNr(\"./testdata/node0/hugepages/\", \"hugepages-1048576kB\")\n\tassert.Nil(t, err)\n\n\thugePageNr, err := strconv.Atoi(rawHugePageNr)\n\tassert.Nil(t, err)\n\tassert.Equal(t, 1, hugePageNr)\n}\n\nfunc TestGetHugePagesNrWhenFileIsMissing(t *testing.T) {\n\tsysFs := NewRealSysFs()\n\trawHugePageNr, err := sysFs.GetHugePagesNr(\"./testdata/node1/hugepages/\", \"hugepages-1048576kB\")\n\tassert.NotNil(t, err)\n\tassert.Equal(t, \"\", rawHugePageNr)\n}\n\nfunc TestIsCPUOnline(t *testing.T) {\n\tsysFs := &realSysFs{\n\t\tcpuPath: \"./testdata_epyc7402_nohyperthreading\",\n\t}\n\tonline := sysFs.IsCPUOnline(\"./testdata_epyc7402_nohyperthreading/cpu14\")\n\tassert.True(t, online)\n\n\tonline = sysFs.IsCPUOnline(\"./testdata_epyc7402_nohyperthreading/cpu13\")\n\tassert.False(t, online)\n}\n\nfunc TestIsCPUOnlineNoFileAndCPU0MustBeOnline(t *testing.T) {\n\t// Test on x86.\n\torigIsX86 := isX86\n\tdefer func() {\n\t\tisX86 = origIsX86\n\t}()\n\tisX86 = false\n\n\tsysFs := &realSysFs{\n\t\tcpuPath: \"./testdata/missing_online/node0\",\n\t}\n\tonline := sysFs.IsCPUOnline(\"./testdata/missing_online/node0/cpu33\")\n\tassert.True(t, online)\n}\n\nfunc TestIsCPU0OnlineOnx86(t *testing.T) {\n\t// Test on x86.\n\torigIsX86 := isX86\n\tdefer func() {\n\t\tisX86 = origIsX86\n\t}()\n\tisX86 = true\n\n\tsysFs := NewRealSysFs()\n\tonline := sysFs.IsCPUOnline(\"path/is/irrelevant/it/is/zero/that/matters/cpu0\")\n\tassert.True(t, online)\n}\n\nfunc TestCPU0OfflineOnNotx86(t *testing.T) {\n\t// Test on arch other than x86.\n\torigIsX86 := isX86\n\tdefer func() {\n\t\tisX86 = origIsX86\n\t}()\n\tisX86 = false\n\n\tsysFs := &realSysFs{\n\t\tcpuPath: \"./testdata_graviton2\",\n\t}\n\tonline := sysFs.IsCPUOnline(\"./testdata_graviton2/cpu0\")\n\tassert.False(t, online)\n}\n\nfunc TestIsCpuOnlineRaspberryPi4(t *testing.T) {\n\t// Test on arch other than x86.\n\torigIsX86 := isX86\n\tdefer func() {\n\t\tisX86 = origIsX86\n\t}()\n\tisX86 = false\n\n\tsysFS := &realSysFs{\n\t\tcpuPath: \"./testdata_rpi4\",\n\t}\n\tonline := sysFS.IsCPUOnline(\"./testdata_rpi4/cpu0\")\n\tassert.True(t, online)\n\n\tonline = sysFS.IsCPUOnline(\"./testdata_rpi4/cpu1\")\n\tassert.True(t, online)\n\n\tonline = sysFS.IsCPUOnline(\"./testdata_rpi4/cpu2\")\n\tassert.True(t, online)\n\n\tonline = sysFS.IsCPUOnline(\"./testdata_rpi4/cpu3\")\n\tassert.True(t, online)\n}\n\nfunc TestIsCpuOnlineGraviton2(t *testing.T) {\n\t// Test on arch other than x86.\n\torigIsX86 := isX86\n\tdefer func() {\n\t\tisX86 = origIsX86\n\t}()\n\tisX86 = false\n\n\tsysFS := &realSysFs{\n\t\tcpuPath: \"./testdata_graviton2\",\n\t}\n\tonline := sysFS.IsCPUOnline(\"./testdata_graviton2/cpu0\")\n\tassert.False(t, online)\n\n\tonline = sysFS.IsCPUOnline(\"./testdata_graviton2/cpu1\")\n\tassert.True(t, online)\n\n\tonline = sysFS.IsCPUOnline(\"./testdata_graviton2/cpu2\")\n\tassert.True(t, online)\n\n\tonline = sysFS.IsCPUOnline(\"./testdata_graviton2/cpu3\")\n\tassert.True(t, online)\n}\n\nfunc TestGetUniqueCPUPropertyCountOnRaspberryPi4(t *testing.T) {\n\t// Test on arch other than x86.\n\torigIsX86 := isX86\n\tdefer func() {\n\t\tisX86 = origIsX86\n\t}()\n\tisX86 = false\n\n\tcount := GetUniqueCPUPropertyCount(\"./testdata_rpi4/\", CPUPhysicalPackageID)\n\tassert.Equal(t, 1, count)\n\n\tcount = GetUniqueCPUPropertyCount(\"./testdata_rpi4/\", CPUCoreID)\n\tassert.Equal(t, 4, count)\n}\n\nfunc TestGetUniqueCPUPropertyCountOnEpyc7402(t *testing.T) {\n\t// Test on x86.\n\torigIsX86 := isX86\n\tdefer func() {\n\t\tisX86 = origIsX86\n\t}()\n\tisX86 = true\n\n\tcount := GetUniqueCPUPropertyCount(\"./testdata_epyc7402/\", CPUPhysicalPackageID)\n\tassert.Equal(t, 1, count)\n\n\tcount = GetUniqueCPUPropertyCount(\"./testdata_epyc7402/\", CPUCoreID)\n\tassert.Equal(t, 24, count)\n}\n\nfunc TestGetUniqueCPUPropertyCountOnEpyc7402NoHyperThreading(t *testing.T) {\n\t// Test on x86.\n\torigIsX86 := isX86\n\tdefer func() {\n\t\tisX86 = origIsX86\n\t}()\n\tisX86 = true\n\n\tcount := GetUniqueCPUPropertyCount(\"./testdata_epyc7402_nohyperthreading/\", CPUPhysicalPackageID)\n\tassert.Equal(t, 1, count)\n\n\tcount = GetUniqueCPUPropertyCount(\"./testdata_epyc7402_nohyperthreading/\", CPUCoreID)\n\tassert.Equal(t, 17, count)\n}\n\nfunc TestGetUniqueCPUPropertyCountOnXeon4214(t *testing.T) {\n\t// Test on x86.\n\torigIsX86 := isX86\n\tdefer func() {\n\t\tisX86 = origIsX86\n\t}()\n\tisX86 = true\n\n\tcount := GetUniqueCPUPropertyCount(\"./testdata_xeon4214_2socket/\", CPUPhysicalPackageID)\n\tassert.Equal(t, 2, count)\n\n\tcount = GetUniqueCPUPropertyCount(\"./testdata_xeon4214_2socket/\", CPUCoreID)\n\tassert.Equal(t, 24, count)\n}\n\nfunc TestGetUniqueCPUPropertyCountOnXeon5218NoHyperThreadingNoHotplug(t *testing.T) {\n\t// Test on x86.\n\torigIsX86 := isX86\n\tdefer func() {\n\t\tisX86 = origIsX86\n\t}()\n\tisX86 = true\n\n\tcount := GetUniqueCPUPropertyCount(\"./testdata_xeon5218_nohyperthread_2socket_nohotplug/\", CPUPhysicalPackageID)\n\tassert.Equal(t, 2, count)\n\n\tcount = GetUniqueCPUPropertyCount(\"./testdata_xeon5218_nohyperthread_2socket_nohotplug/\", CPUCoreID)\n\tassert.Equal(t, 32, count)\n}\n\nfunc TestUniqueCPUPropertyOnSingleSocketMultipleNUMAsSystem(t *testing.T) {\n\t// Test on x86.\n\torigIsX86 := isX86\n\tdefer func() {\n\t\tisX86 = origIsX86\n\t}()\n\tisX86 = true\n\n\tcount := GetUniqueCPUPropertyCount(\"./testdata_single_socket_many_NUMAs/\", CPUPhysicalPackageID)\n\tassert.Equal(t, 16, count)\n\n\tcount = GetUniqueCPUPropertyCount(\"./testdata_single_socket_many_NUMAs/\", CPUCoreID)\n\tassert.Equal(t, 16, count)\n}\n\nfunc TestGetDistances(t *testing.T) {\n\tsysFs := NewRealSysFs()\n\tdistances, err := sysFs.GetDistances(\"./testdata/node0\")\n\tassert.Nil(t, err)\n\tassert.Equal(t, \"10 11\", distances)\n}\n\nfunc TestGetDistancesFileIsMissing(t *testing.T) {\n\tsysFs := NewRealSysFs()\n\tdistances, err := sysFs.GetDistances(\"./testdata/node1\")\n\tassert.NotNil(t, err)\n\tassert.Equal(t, \"\", distances)\n}\n"
  },
  {
    "path": "utils/sysfs/sysfs_x86.go",
    "content": "//go:build x86\n\n// Copyright 2021 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage sysfs\n\nvar isX86 = true\n"
  },
  {
    "path": "utils/sysfs/testdata/edac/mc/mc0/dimm0/dimm_mem_type",
    "content": "Unbuffered-DDR4\n"
  },
  {
    "path": "utils/sysfs/testdata/edac/mc/mc0/dimm0/size",
    "content": "789\n"
  },
  {
    "path": "utils/sysfs/testdata/edac/mc/mc0/dimm1/dimm_mem_type",
    "content": "Non-volatile-RAM\n"
  },
  {
    "path": "utils/sysfs/testdata/edac/mc/mc0/dimm1/size",
    "content": "456\n"
  },
  {
    "path": "utils/sysfs/testdata/edac/mc/mc0/dimm_is_fake/dimm_mem_type",
    "content": "Unbuffered-DDR4"
  },
  {
    "path": "utils/sysfs/testdata/edac/mc/mc0/dimm_is_fake/size",
    "content": "321"
  },
  {
    "path": "utils/sysfs/testdata/edac/mc/mc1/dimm0/dimm_mem_type",
    "content": "Non-volatile-RAM"
  },
  {
    "path": "utils/sysfs/testdata/edac/mc/mc1/dimm0/size",
    "content": "123"
  },
  {
    "path": "utils/sysfs/testdata/edac/mc/mc_fake/dimm0/dimm0/dimm_mem_type",
    "content": "Unbuffered-DDR4"
  },
  {
    "path": "utils/sysfs/testdata/edac/mc/mc_fake/dimm0/dimm0/size",
    "content": "789"
  },
  {
    "path": "utils/sysfs/testdata/edac/mc/mc_fake/dimm0/dimm1/dimm_mem_type",
    "content": "Non-volatile-RAM"
  },
  {
    "path": "utils/sysfs/testdata/edac/mc/mc_fake/dimm0/dimm1/size",
    "content": "456"
  },
  {
    "path": "utils/sysfs/testdata/edac/mc/mc_fake/dimm0/dimm_mem_type",
    "content": "Unbuffered-DDR4"
  },
  {
    "path": "utils/sysfs/testdata/edac/mc/mc_fake/dimm0/size",
    "content": "789"
  },
  {
    "path": "utils/sysfs/testdata/edac/mc/mc_fake/dimm1/dimm_mem_type",
    "content": "Non-volatile-RAM"
  },
  {
    "path": "utils/sysfs/testdata/edac/mc/mc_fake/dimm1/size",
    "content": "456"
  },
  {
    "path": "utils/sysfs/testdata/missing_online/node0/cpu0/.gitkeep",
    "content": ""
  },
  {
    "path": "utils/sysfs/testdata/missing_online/node0/cpu33/.gitkeep",
    "content": ""
  },
  {
    "path": "utils/sysfs/testdata/node0/cpu0/topology/core_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata/node0/cpu1/topology/.gitkeep",
    "content": ""
  },
  {
    "path": "utils/sysfs/testdata/node0/distance",
    "content": "10 11\n"
  },
  {
    "path": "utils/sysfs/testdata/node0/hugepages/hugepages-1048576kB/nr_hugepages",
    "content": "1\n"
  },
  {
    "path": "utils/sysfs/testdata/node0/hugepages/hugepages-2048kB/nr_hugepages",
    "content": "2\n"
  },
  {
    "path": "utils/sysfs/testdata/node0/meminfo",
    "content": "Node 0 MemTotal:       32817192 kB\n"
  },
  {
    "path": "utils/sysfs/testdata/node1/.gitkeep",
    "content": ""
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu0/topology/core_cpus",
    "content": "0000,01000001\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu0/topology/core_cpus_list",
    "content": "0,24\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu0/topology/core_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu0/topology/core_siblings",
    "content": "ffff,ffffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu0/topology/core_siblings_list",
    "content": "0-47\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu0/topology/die_cpus",
    "content": "ffff,ffffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu0/topology/die_cpus_list",
    "content": "0-47\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu0/topology/die_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu0/topology/package_cpus",
    "content": "ffff,ffffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu0/topology/package_cpus_list",
    "content": "0-47\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu0/topology/physical_package_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu0/topology/thread_siblings",
    "content": "0000,01000001\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu0/topology/thread_siblings_list",
    "content": "0,24\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu1/topology/core_cpus",
    "content": "0000,02000002\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu1/topology/core_cpus_list",
    "content": "1,25\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu1/topology/core_id",
    "content": "1\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu1/topology/core_siblings",
    "content": "ffff,ffffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu1/topology/core_siblings_list",
    "content": "0-47\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu1/topology/die_cpus",
    "content": "ffff,ffffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu1/topology/die_cpus_list",
    "content": "0-47\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu1/topology/die_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu1/topology/package_cpus",
    "content": "ffff,ffffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu1/topology/package_cpus_list",
    "content": "0-47\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu1/topology/physical_package_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu1/topology/thread_siblings",
    "content": "0000,02000002\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu1/topology/thread_siblings_list",
    "content": "1,25\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu10/topology/core_cpus",
    "content": "0004,00000400\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu10/topology/core_cpus_list",
    "content": "10,34\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu10/topology/core_id",
    "content": "13\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu10/topology/core_siblings",
    "content": "ffff,ffffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu10/topology/core_siblings_list",
    "content": "0-47\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu10/topology/die_cpus",
    "content": "ffff,ffffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu10/topology/die_cpus_list",
    "content": "0-47\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu10/topology/die_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu10/topology/package_cpus",
    "content": "ffff,ffffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu10/topology/package_cpus_list",
    "content": "0-47\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu10/topology/physical_package_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu10/topology/thread_siblings",
    "content": "0004,00000400\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu10/topology/thread_siblings_list",
    "content": "10,34\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu11/topology/core_cpus",
    "content": "0008,00000800\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu11/topology/core_cpus_list",
    "content": "11,35\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu11/topology/core_id",
    "content": "14\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu11/topology/core_siblings",
    "content": "ffff,ffffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu11/topology/core_siblings_list",
    "content": "0-47\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu11/topology/die_cpus",
    "content": "ffff,ffffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu11/topology/die_cpus_list",
    "content": "0-47\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu11/topology/die_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu11/topology/package_cpus",
    "content": "ffff,ffffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu11/topology/package_cpus_list",
    "content": "0-47\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu11/topology/physical_package_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu11/topology/thread_siblings",
    "content": "0008,00000800\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu11/topology/thread_siblings_list",
    "content": "11,35\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu12/topology/core_cpus",
    "content": "0010,00001000\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu12/topology/core_cpus_list",
    "content": "12,36\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu12/topology/core_id",
    "content": "16\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu12/topology/core_siblings",
    "content": "ffff,ffffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu12/topology/core_siblings_list",
    "content": "0-47\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu12/topology/die_cpus",
    "content": "ffff,ffffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu12/topology/die_cpus_list",
    "content": "0-47\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu12/topology/die_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu12/topology/package_cpus",
    "content": "ffff,ffffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu12/topology/package_cpus_list",
    "content": "0-47\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu12/topology/physical_package_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu12/topology/thread_siblings",
    "content": "0010,00001000\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu12/topology/thread_siblings_list",
    "content": "12,36\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu13/topology/core_cpus",
    "content": "0020,00002000\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu13/topology/core_cpus_list",
    "content": "13,37\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu13/topology/core_id",
    "content": "17\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu13/topology/core_siblings",
    "content": "ffff,ffffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu13/topology/core_siblings_list",
    "content": "0-47\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu13/topology/die_cpus",
    "content": "ffff,ffffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu13/topology/die_cpus_list",
    "content": "0-47\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu13/topology/die_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu13/topology/package_cpus",
    "content": "ffff,ffffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu13/topology/package_cpus_list",
    "content": "0-47\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu13/topology/physical_package_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu13/topology/thread_siblings",
    "content": "0020,00002000\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu13/topology/thread_siblings_list",
    "content": "13,37\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu14/topology/core_cpus",
    "content": "0040,00004000\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu14/topology/core_cpus_list",
    "content": "14,38\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu14/topology/core_id",
    "content": "18\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu14/topology/core_siblings",
    "content": "ffff,ffffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu14/topology/core_siblings_list",
    "content": "0-47\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu14/topology/die_cpus",
    "content": "ffff,ffffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu14/topology/die_cpus_list",
    "content": "0-47\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu14/topology/die_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu14/topology/package_cpus",
    "content": "ffff,ffffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu14/topology/package_cpus_list",
    "content": "0-47\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu14/topology/physical_package_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu14/topology/thread_siblings",
    "content": "0040,00004000\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu14/topology/thread_siblings_list",
    "content": "14,38\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu15/topology/core_cpus",
    "content": "0080,00008000\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu15/topology/core_cpus_list",
    "content": "15,39\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu15/topology/core_id",
    "content": "20\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu15/topology/core_siblings",
    "content": "ffff,ffffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu15/topology/core_siblings_list",
    "content": "0-47\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu15/topology/die_cpus",
    "content": "ffff,ffffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu15/topology/die_cpus_list",
    "content": "0-47\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu15/topology/die_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu15/topology/package_cpus",
    "content": "ffff,ffffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu15/topology/package_cpus_list",
    "content": "0-47\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu15/topology/physical_package_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu15/topology/thread_siblings",
    "content": "0080,00008000\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu15/topology/thread_siblings_list",
    "content": "15,39\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu16/topology/core_cpus",
    "content": "0100,00010000\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu16/topology/core_cpus_list",
    "content": "16,40\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu16/topology/core_id",
    "content": "21\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu16/topology/core_siblings",
    "content": "ffff,ffffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu16/topology/core_siblings_list",
    "content": "0-47\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu16/topology/die_cpus",
    "content": "ffff,ffffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu16/topology/die_cpus_list",
    "content": "0-47\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu16/topology/die_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu16/topology/package_cpus",
    "content": "ffff,ffffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu16/topology/package_cpus_list",
    "content": "0-47\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu16/topology/physical_package_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu16/topology/thread_siblings",
    "content": "0100,00010000\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu16/topology/thread_siblings_list",
    "content": "16,40\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu17/topology/core_cpus",
    "content": "0200,00020000\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu17/topology/core_cpus_list",
    "content": "17,41\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu17/topology/core_id",
    "content": "22\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu17/topology/core_siblings",
    "content": "ffff,ffffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu17/topology/core_siblings_list",
    "content": "0-47\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu17/topology/die_cpus",
    "content": "ffff,ffffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu17/topology/die_cpus_list",
    "content": "0-47\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu17/topology/die_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu17/topology/package_cpus",
    "content": "ffff,ffffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu17/topology/package_cpus_list",
    "content": "0-47\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu17/topology/physical_package_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu17/topology/thread_siblings",
    "content": "0200,00020000\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu17/topology/thread_siblings_list",
    "content": "17,41\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu18/topology/core_cpus",
    "content": "0400,00040000\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu18/topology/core_cpus_list",
    "content": "18,42\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu18/topology/core_id",
    "content": "24\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu18/topology/core_siblings",
    "content": "ffff,ffffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu18/topology/core_siblings_list",
    "content": "0-47\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu18/topology/die_cpus",
    "content": "ffff,ffffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu18/topology/die_cpus_list",
    "content": "0-47\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu18/topology/die_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu18/topology/package_cpus",
    "content": "ffff,ffffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu18/topology/package_cpus_list",
    "content": "0-47\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu18/topology/physical_package_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu18/topology/thread_siblings",
    "content": "0400,00040000\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu18/topology/thread_siblings_list",
    "content": "18,42\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu19/topology/core_cpus",
    "content": "0800,00080000\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu19/topology/core_cpus_list",
    "content": "19,43\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu19/topology/core_id",
    "content": "25\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu19/topology/core_siblings",
    "content": "ffff,ffffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu19/topology/core_siblings_list",
    "content": "0-47\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu19/topology/die_cpus",
    "content": "ffff,ffffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu19/topology/die_cpus_list",
    "content": "0-47\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu19/topology/die_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu19/topology/package_cpus",
    "content": "ffff,ffffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu19/topology/package_cpus_list",
    "content": "0-47\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu19/topology/physical_package_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu19/topology/thread_siblings",
    "content": "0800,00080000\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu19/topology/thread_siblings_list",
    "content": "19,43\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu2/topology/core_cpus",
    "content": "0000,04000004\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu2/topology/core_cpus_list",
    "content": "2,26\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu2/topology/core_id",
    "content": "2\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu2/topology/core_siblings",
    "content": "ffff,ffffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu2/topology/core_siblings_list",
    "content": "0-47\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu2/topology/die_cpus",
    "content": "ffff,ffffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu2/topology/die_cpus_list",
    "content": "0-47\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu2/topology/die_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu2/topology/package_cpus",
    "content": "ffff,ffffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu2/topology/package_cpus_list",
    "content": "0-47\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu2/topology/physical_package_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu2/topology/thread_siblings",
    "content": "0000,04000004\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu2/topology/thread_siblings_list",
    "content": "2,26\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu20/topology/core_cpus",
    "content": "1000,00100000\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu20/topology/core_cpus_list",
    "content": "20,44\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu20/topology/core_id",
    "content": "26\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu20/topology/core_siblings",
    "content": "ffff,ffffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu20/topology/core_siblings_list",
    "content": "0-47\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu20/topology/die_cpus",
    "content": "ffff,ffffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu20/topology/die_cpus_list",
    "content": "0-47\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu20/topology/die_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu20/topology/package_cpus",
    "content": "ffff,ffffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu20/topology/package_cpus_list",
    "content": "0-47\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu20/topology/physical_package_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu20/topology/thread_siblings",
    "content": "1000,00100000\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu20/topology/thread_siblings_list",
    "content": "20,44\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu21/topology/core_cpus",
    "content": "2000,00200000\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu21/topology/core_cpus_list",
    "content": "21,45\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu21/topology/core_id",
    "content": "28\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu21/topology/core_siblings",
    "content": "ffff,ffffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu21/topology/core_siblings_list",
    "content": "0-47\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu21/topology/die_cpus",
    "content": "ffff,ffffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu21/topology/die_cpus_list",
    "content": "0-47\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu21/topology/die_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu21/topology/package_cpus",
    "content": "ffff,ffffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu21/topology/package_cpus_list",
    "content": "0-47\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu21/topology/physical_package_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu21/topology/thread_siblings",
    "content": "2000,00200000\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu21/topology/thread_siblings_list",
    "content": "21,45\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu22/topology/core_cpus",
    "content": "4000,00400000\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu22/topology/core_cpus_list",
    "content": "22,46\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu22/topology/core_id",
    "content": "29\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu22/topology/core_siblings",
    "content": "ffff,ffffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu22/topology/core_siblings_list",
    "content": "0-47\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu22/topology/die_cpus",
    "content": "ffff,ffffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu22/topology/die_cpus_list",
    "content": "0-47\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu22/topology/die_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu22/topology/package_cpus",
    "content": "ffff,ffffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu22/topology/package_cpus_list",
    "content": "0-47\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu22/topology/physical_package_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu22/topology/thread_siblings",
    "content": "4000,00400000\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu22/topology/thread_siblings_list",
    "content": "22,46\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu23/topology/core_cpus",
    "content": "8000,00800000\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu23/topology/core_cpus_list",
    "content": "23,47\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu23/topology/core_id",
    "content": "30\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu23/topology/core_siblings",
    "content": "ffff,ffffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu23/topology/core_siblings_list",
    "content": "0-47\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu23/topology/die_cpus",
    "content": "ffff,ffffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu23/topology/die_cpus_list",
    "content": "0-47\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu23/topology/die_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu23/topology/package_cpus",
    "content": "ffff,ffffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu23/topology/package_cpus_list",
    "content": "0-47\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu23/topology/physical_package_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu23/topology/thread_siblings",
    "content": "8000,00800000\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu23/topology/thread_siblings_list",
    "content": "23,47\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu24/topology/core_cpus",
    "content": "0000,01000001\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu24/topology/core_cpus_list",
    "content": "0,24\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu24/topology/core_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu24/topology/core_siblings",
    "content": "ffff,ffffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu24/topology/core_siblings_list",
    "content": "0-47\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu24/topology/die_cpus",
    "content": "ffff,ffffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu24/topology/die_cpus_list",
    "content": "0-47\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu24/topology/die_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu24/topology/package_cpus",
    "content": "ffff,ffffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu24/topology/package_cpus_list",
    "content": "0-47\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu24/topology/physical_package_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu24/topology/thread_siblings",
    "content": "0000,01000001\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu24/topology/thread_siblings_list",
    "content": "0,24\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu25/topology/core_cpus",
    "content": "0000,02000002\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu25/topology/core_cpus_list",
    "content": "1,25\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu25/topology/core_id",
    "content": "1\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu25/topology/core_siblings",
    "content": "ffff,ffffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu25/topology/core_siblings_list",
    "content": "0-47\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu25/topology/die_cpus",
    "content": "ffff,ffffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu25/topology/die_cpus_list",
    "content": "0-47\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu25/topology/die_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu25/topology/package_cpus",
    "content": "ffff,ffffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu25/topology/package_cpus_list",
    "content": "0-47\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu25/topology/physical_package_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu25/topology/thread_siblings",
    "content": "0000,02000002\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu25/topology/thread_siblings_list",
    "content": "1,25\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu26/topology/core_cpus",
    "content": "0000,04000004\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu26/topology/core_cpus_list",
    "content": "2,26\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu26/topology/core_id",
    "content": "2\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu26/topology/core_siblings",
    "content": "ffff,ffffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu26/topology/core_siblings_list",
    "content": "0-47\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu26/topology/die_cpus",
    "content": "ffff,ffffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu26/topology/die_cpus_list",
    "content": "0-47\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu26/topology/die_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu26/topology/package_cpus",
    "content": "ffff,ffffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu26/topology/package_cpus_list",
    "content": "0-47\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu26/topology/physical_package_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu26/topology/thread_siblings",
    "content": "0000,04000004\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu26/topology/thread_siblings_list",
    "content": "2,26\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu27/topology/core_cpus",
    "content": "0000,08000008\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu27/topology/core_cpus_list",
    "content": "3,27\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu27/topology/core_id",
    "content": "4\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu27/topology/core_siblings",
    "content": "ffff,ffffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu27/topology/core_siblings_list",
    "content": "0-47\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu27/topology/die_cpus",
    "content": "ffff,ffffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu27/topology/die_cpus_list",
    "content": "0-47\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu27/topology/die_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu27/topology/package_cpus",
    "content": "ffff,ffffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu27/topology/package_cpus_list",
    "content": "0-47\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu27/topology/physical_package_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu27/topology/thread_siblings",
    "content": "0000,08000008\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu27/topology/thread_siblings_list",
    "content": "3,27\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu28/topology/core_cpus",
    "content": "0000,10000010\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu28/topology/core_cpus_list",
    "content": "4,28\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu28/topology/core_id",
    "content": "5\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu28/topology/core_siblings",
    "content": "ffff,ffffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu28/topology/core_siblings_list",
    "content": "0-47\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu28/topology/die_cpus",
    "content": "ffff,ffffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu28/topology/die_cpus_list",
    "content": "0-47\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu28/topology/die_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu28/topology/package_cpus",
    "content": "ffff,ffffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu28/topology/package_cpus_list",
    "content": "0-47\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu28/topology/physical_package_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu28/topology/thread_siblings",
    "content": "0000,10000010\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu28/topology/thread_siblings_list",
    "content": "4,28\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu29/topology/core_cpus",
    "content": "0000,20000020\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu29/topology/core_cpus_list",
    "content": "5,29\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu29/topology/core_id",
    "content": "6\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu29/topology/core_siblings",
    "content": "ffff,ffffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu29/topology/core_siblings_list",
    "content": "0-47\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu29/topology/die_cpus",
    "content": "ffff,ffffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu29/topology/die_cpus_list",
    "content": "0-47\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu29/topology/die_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu29/topology/package_cpus",
    "content": "ffff,ffffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu29/topology/package_cpus_list",
    "content": "0-47\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu29/topology/physical_package_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu29/topology/thread_siblings",
    "content": "0000,20000020\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu29/topology/thread_siblings_list",
    "content": "5,29\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu3/topology/core_cpus",
    "content": "0000,08000008\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu3/topology/core_cpus_list",
    "content": "3,27\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu3/topology/core_id",
    "content": "4\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu3/topology/core_siblings",
    "content": "ffff,ffffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu3/topology/core_siblings_list",
    "content": "0-47\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu3/topology/die_cpus",
    "content": "ffff,ffffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu3/topology/die_cpus_list",
    "content": "0-47\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu3/topology/die_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu3/topology/package_cpus",
    "content": "ffff,ffffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu3/topology/package_cpus_list",
    "content": "0-47\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu3/topology/physical_package_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu3/topology/thread_siblings",
    "content": "0000,08000008\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu3/topology/thread_siblings_list",
    "content": "3,27\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu30/topology/core_cpus",
    "content": "0000,40000040\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu30/topology/core_cpus_list",
    "content": "6,30\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu30/topology/core_id",
    "content": "8\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu30/topology/core_siblings",
    "content": "ffff,ffffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu30/topology/core_siblings_list",
    "content": "0-47\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu30/topology/die_cpus",
    "content": "ffff,ffffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu30/topology/die_cpus_list",
    "content": "0-47\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu30/topology/die_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu30/topology/package_cpus",
    "content": "ffff,ffffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu30/topology/package_cpus_list",
    "content": "0-47\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu30/topology/physical_package_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu30/topology/thread_siblings",
    "content": "0000,40000040\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu30/topology/thread_siblings_list",
    "content": "6,30\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu31/topology/core_cpus",
    "content": "0000,80000080\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu31/topology/core_cpus_list",
    "content": "7,31\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu31/topology/core_id",
    "content": "9\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu31/topology/core_siblings",
    "content": "ffff,ffffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu31/topology/core_siblings_list",
    "content": "0-47\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu31/topology/die_cpus",
    "content": "ffff,ffffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu31/topology/die_cpus_list",
    "content": "0-47\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu31/topology/die_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu31/topology/package_cpus",
    "content": "ffff,ffffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu31/topology/package_cpus_list",
    "content": "0-47\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu31/topology/physical_package_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu31/topology/thread_siblings",
    "content": "0000,80000080\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu31/topology/thread_siblings_list",
    "content": "7,31\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu32/topology/core_cpus",
    "content": "0001,00000100\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu32/topology/core_cpus_list",
    "content": "8,32\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu32/topology/core_id",
    "content": "10\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu32/topology/core_siblings",
    "content": "ffff,ffffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu32/topology/core_siblings_list",
    "content": "0-47\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu32/topology/die_cpus",
    "content": "ffff,ffffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu32/topology/die_cpus_list",
    "content": "0-47\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu32/topology/die_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu32/topology/package_cpus",
    "content": "ffff,ffffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu32/topology/package_cpus_list",
    "content": "0-47\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu32/topology/physical_package_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu32/topology/thread_siblings",
    "content": "0001,00000100\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu32/topology/thread_siblings_list",
    "content": "8,32\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu33/topology/core_cpus",
    "content": "0002,00000200\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu33/topology/core_cpus_list",
    "content": "9,33\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu33/topology/core_id",
    "content": "12\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu33/topology/core_siblings",
    "content": "ffff,ffffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu33/topology/core_siblings_list",
    "content": "0-47\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu33/topology/die_cpus",
    "content": "ffff,ffffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu33/topology/die_cpus_list",
    "content": "0-47\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu33/topology/die_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu33/topology/package_cpus",
    "content": "ffff,ffffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu33/topology/package_cpus_list",
    "content": "0-47\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu33/topology/physical_package_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu33/topology/thread_siblings",
    "content": "0002,00000200\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu33/topology/thread_siblings_list",
    "content": "9,33\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu34/topology/core_cpus",
    "content": "0004,00000400\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu34/topology/core_cpus_list",
    "content": "10,34\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu34/topology/core_id",
    "content": "13\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu34/topology/core_siblings",
    "content": "ffff,ffffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu34/topology/core_siblings_list",
    "content": "0-47\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu34/topology/die_cpus",
    "content": "ffff,ffffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu34/topology/die_cpus_list",
    "content": "0-47\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu34/topology/die_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu34/topology/package_cpus",
    "content": "ffff,ffffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu34/topology/package_cpus_list",
    "content": "0-47\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu34/topology/physical_package_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu34/topology/thread_siblings",
    "content": "0004,00000400\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu34/topology/thread_siblings_list",
    "content": "10,34\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu35/topology/core_cpus",
    "content": "0008,00000800\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu35/topology/core_cpus_list",
    "content": "11,35\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu35/topology/core_id",
    "content": "14\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu35/topology/core_siblings",
    "content": "ffff,ffffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu35/topology/core_siblings_list",
    "content": "0-47\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu35/topology/die_cpus",
    "content": "ffff,ffffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu35/topology/die_cpus_list",
    "content": "0-47\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu35/topology/die_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu35/topology/package_cpus",
    "content": "ffff,ffffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu35/topology/package_cpus_list",
    "content": "0-47\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu35/topology/physical_package_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu35/topology/thread_siblings",
    "content": "0008,00000800\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu35/topology/thread_siblings_list",
    "content": "11,35\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu36/topology/core_cpus",
    "content": "0010,00001000\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu36/topology/core_cpus_list",
    "content": "12,36\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu36/topology/core_id",
    "content": "16\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu36/topology/core_siblings",
    "content": "ffff,ffffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu36/topology/core_siblings_list",
    "content": "0-47\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu36/topology/die_cpus",
    "content": "ffff,ffffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu36/topology/die_cpus_list",
    "content": "0-47\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu36/topology/die_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu36/topology/package_cpus",
    "content": "ffff,ffffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu36/topology/package_cpus_list",
    "content": "0-47\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu36/topology/physical_package_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu36/topology/thread_siblings",
    "content": "0010,00001000\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu36/topology/thread_siblings_list",
    "content": "12,36\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu37/topology/core_cpus",
    "content": "0020,00002000\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu37/topology/core_cpus_list",
    "content": "13,37\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu37/topology/core_id",
    "content": "17\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu37/topology/core_siblings",
    "content": "ffff,ffffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu37/topology/core_siblings_list",
    "content": "0-47\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu37/topology/die_cpus",
    "content": "ffff,ffffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu37/topology/die_cpus_list",
    "content": "0-47\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu37/topology/die_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu37/topology/package_cpus",
    "content": "ffff,ffffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu37/topology/package_cpus_list",
    "content": "0-47\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu37/topology/physical_package_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu37/topology/thread_siblings",
    "content": "0020,00002000\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu37/topology/thread_siblings_list",
    "content": "13,37\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu38/topology/core_cpus",
    "content": "0040,00004000\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu38/topology/core_cpus_list",
    "content": "14,38\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu38/topology/core_id",
    "content": "18\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu38/topology/core_siblings",
    "content": "ffff,ffffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu38/topology/core_siblings_list",
    "content": "0-47\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu38/topology/die_cpus",
    "content": "ffff,ffffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu38/topology/die_cpus_list",
    "content": "0-47\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu38/topology/die_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu38/topology/package_cpus",
    "content": "ffff,ffffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu38/topology/package_cpus_list",
    "content": "0-47\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu38/topology/physical_package_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu38/topology/thread_siblings",
    "content": "0040,00004000\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu38/topology/thread_siblings_list",
    "content": "14,38\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu39/topology/core_cpus",
    "content": "0080,00008000\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu39/topology/core_cpus_list",
    "content": "15,39\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu39/topology/core_id",
    "content": "20\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu39/topology/core_siblings",
    "content": "ffff,ffffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu39/topology/core_siblings_list",
    "content": "0-47\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu39/topology/die_cpus",
    "content": "ffff,ffffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu39/topology/die_cpus_list",
    "content": "0-47\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu39/topology/die_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu39/topology/package_cpus",
    "content": "ffff,ffffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu39/topology/package_cpus_list",
    "content": "0-47\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu39/topology/physical_package_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu39/topology/thread_siblings",
    "content": "0080,00008000\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu39/topology/thread_siblings_list",
    "content": "15,39\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu4/topology/core_cpus",
    "content": "0000,10000010\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu4/topology/core_cpus_list",
    "content": "4,28\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu4/topology/core_id",
    "content": "5\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu4/topology/core_siblings",
    "content": "ffff,ffffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu4/topology/core_siblings_list",
    "content": "0-47\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu4/topology/die_cpus",
    "content": "ffff,ffffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu4/topology/die_cpus_list",
    "content": "0-47\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu4/topology/die_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu4/topology/package_cpus",
    "content": "ffff,ffffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu4/topology/package_cpus_list",
    "content": "0-47\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu4/topology/physical_package_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu4/topology/thread_siblings",
    "content": "0000,10000010\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu4/topology/thread_siblings_list",
    "content": "4,28\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu40/topology/core_cpus",
    "content": "0100,00010000\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu40/topology/core_cpus_list",
    "content": "16,40\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu40/topology/core_id",
    "content": "21\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu40/topology/core_siblings",
    "content": "ffff,ffffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu40/topology/core_siblings_list",
    "content": "0-47\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu40/topology/die_cpus",
    "content": "ffff,ffffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu40/topology/die_cpus_list",
    "content": "0-47\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu40/topology/die_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu40/topology/package_cpus",
    "content": "ffff,ffffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu40/topology/package_cpus_list",
    "content": "0-47\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu40/topology/physical_package_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu40/topology/thread_siblings",
    "content": "0100,00010000\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu40/topology/thread_siblings_list",
    "content": "16,40\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu41/topology/core_cpus",
    "content": "0200,00020000\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu41/topology/core_cpus_list",
    "content": "17,41\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu41/topology/core_id",
    "content": "22\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu41/topology/core_siblings",
    "content": "ffff,ffffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu41/topology/core_siblings_list",
    "content": "0-47\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu41/topology/die_cpus",
    "content": "ffff,ffffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu41/topology/die_cpus_list",
    "content": "0-47\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu41/topology/die_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu41/topology/package_cpus",
    "content": "ffff,ffffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu41/topology/package_cpus_list",
    "content": "0-47\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu41/topology/physical_package_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu41/topology/thread_siblings",
    "content": "0200,00020000\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu41/topology/thread_siblings_list",
    "content": "17,41\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu42/topology/core_cpus",
    "content": "0400,00040000\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu42/topology/core_cpus_list",
    "content": "18,42\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu42/topology/core_id",
    "content": "24\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu42/topology/core_siblings",
    "content": "ffff,ffffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu42/topology/core_siblings_list",
    "content": "0-47\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu42/topology/die_cpus",
    "content": "ffff,ffffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu42/topology/die_cpus_list",
    "content": "0-47\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu42/topology/die_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu42/topology/package_cpus",
    "content": "ffff,ffffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu42/topology/package_cpus_list",
    "content": "0-47\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu42/topology/physical_package_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu42/topology/thread_siblings",
    "content": "0400,00040000\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu42/topology/thread_siblings_list",
    "content": "18,42\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu43/topology/core_cpus",
    "content": "0800,00080000\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu43/topology/core_cpus_list",
    "content": "19,43\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu43/topology/core_id",
    "content": "25\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu43/topology/core_siblings",
    "content": "ffff,ffffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu43/topology/core_siblings_list",
    "content": "0-47\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu43/topology/die_cpus",
    "content": "ffff,ffffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu43/topology/die_cpus_list",
    "content": "0-47\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu43/topology/die_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu43/topology/package_cpus",
    "content": "ffff,ffffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu43/topology/package_cpus_list",
    "content": "0-47\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu43/topology/physical_package_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu43/topology/thread_siblings",
    "content": "0800,00080000\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu43/topology/thread_siblings_list",
    "content": "19,43\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu44/topology/core_cpus",
    "content": "1000,00100000\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu44/topology/core_cpus_list",
    "content": "20,44\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu44/topology/core_id",
    "content": "26\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu44/topology/core_siblings",
    "content": "ffff,ffffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu44/topology/core_siblings_list",
    "content": "0-47\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu44/topology/die_cpus",
    "content": "ffff,ffffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu44/topology/die_cpus_list",
    "content": "0-47\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu44/topology/die_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu44/topology/package_cpus",
    "content": "ffff,ffffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu44/topology/package_cpus_list",
    "content": "0-47\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu44/topology/physical_package_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu44/topology/thread_siblings",
    "content": "1000,00100000\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu44/topology/thread_siblings_list",
    "content": "20,44\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu45/topology/core_cpus",
    "content": "2000,00200000\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu45/topology/core_cpus_list",
    "content": "21,45\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu45/topology/core_id",
    "content": "28\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu45/topology/core_siblings",
    "content": "ffff,ffffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu45/topology/core_siblings_list",
    "content": "0-47\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu45/topology/die_cpus",
    "content": "ffff,ffffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu45/topology/die_cpus_list",
    "content": "0-47\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu45/topology/die_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu45/topology/package_cpus",
    "content": "ffff,ffffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu45/topology/package_cpus_list",
    "content": "0-47\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu45/topology/physical_package_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu45/topology/thread_siblings",
    "content": "2000,00200000\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu45/topology/thread_siblings_list",
    "content": "21,45\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu46/topology/core_cpus",
    "content": "4000,00400000\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu46/topology/core_cpus_list",
    "content": "22,46\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu46/topology/core_id",
    "content": "29\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu46/topology/core_siblings",
    "content": "ffff,ffffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu46/topology/core_siblings_list",
    "content": "0-47\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu46/topology/die_cpus",
    "content": "ffff,ffffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu46/topology/die_cpus_list",
    "content": "0-47\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu46/topology/die_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu46/topology/package_cpus",
    "content": "ffff,ffffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu46/topology/package_cpus_list",
    "content": "0-47\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu46/topology/physical_package_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu46/topology/thread_siblings",
    "content": "4000,00400000\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu46/topology/thread_siblings_list",
    "content": "22,46\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu47/topology/core_cpus",
    "content": "8000,00800000\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu47/topology/core_cpus_list",
    "content": "23,47\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu47/topology/core_id",
    "content": "30\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu47/topology/core_siblings",
    "content": "ffff,ffffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu47/topology/core_siblings_list",
    "content": "0-47\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu47/topology/die_cpus",
    "content": "ffff,ffffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu47/topology/die_cpus_list",
    "content": "0-47\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu47/topology/die_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu47/topology/package_cpus",
    "content": "ffff,ffffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu47/topology/package_cpus_list",
    "content": "0-47\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu47/topology/physical_package_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu47/topology/thread_siblings",
    "content": "8000,00800000\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu47/topology/thread_siblings_list",
    "content": "23,47\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu5/topology/core_cpus",
    "content": "0000,20000020\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu5/topology/core_cpus_list",
    "content": "5,29\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu5/topology/core_id",
    "content": "6\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu5/topology/core_siblings",
    "content": "ffff,ffffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu5/topology/core_siblings_list",
    "content": "0-47\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu5/topology/die_cpus",
    "content": "ffff,ffffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu5/topology/die_cpus_list",
    "content": "0-47\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu5/topology/die_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu5/topology/package_cpus",
    "content": "ffff,ffffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu5/topology/package_cpus_list",
    "content": "0-47\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu5/topology/physical_package_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu5/topology/thread_siblings",
    "content": "0000,20000020\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu5/topology/thread_siblings_list",
    "content": "5,29\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu6/topology/core_cpus",
    "content": "0000,40000040\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu6/topology/core_cpus_list",
    "content": "6,30\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu6/topology/core_id",
    "content": "8\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu6/topology/core_siblings",
    "content": "ffff,ffffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu6/topology/core_siblings_list",
    "content": "0-47\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu6/topology/die_cpus",
    "content": "ffff,ffffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu6/topology/die_cpus_list",
    "content": "0-47\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu6/topology/die_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu6/topology/package_cpus",
    "content": "ffff,ffffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu6/topology/package_cpus_list",
    "content": "0-47\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu6/topology/physical_package_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu6/topology/thread_siblings",
    "content": "0000,40000040\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu6/topology/thread_siblings_list",
    "content": "6,30\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu7/topology/core_cpus",
    "content": "0000,80000080\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu7/topology/core_cpus_list",
    "content": "7,31\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu7/topology/core_id",
    "content": "9\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu7/topology/core_siblings",
    "content": "ffff,ffffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu7/topology/core_siblings_list",
    "content": "0-47\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu7/topology/die_cpus",
    "content": "ffff,ffffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu7/topology/die_cpus_list",
    "content": "0-47\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu7/topology/die_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu7/topology/package_cpus",
    "content": "ffff,ffffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu7/topology/package_cpus_list",
    "content": "0-47\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu7/topology/physical_package_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu7/topology/thread_siblings",
    "content": "0000,80000080\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu7/topology/thread_siblings_list",
    "content": "7,31\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu8/topology/core_cpus",
    "content": "0001,00000100\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu8/topology/core_cpus_list",
    "content": "8,32\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu8/topology/core_id",
    "content": "10\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu8/topology/core_siblings",
    "content": "ffff,ffffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu8/topology/core_siblings_list",
    "content": "0-47\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu8/topology/die_cpus",
    "content": "ffff,ffffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu8/topology/die_cpus_list",
    "content": "0-47\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu8/topology/die_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu8/topology/package_cpus",
    "content": "ffff,ffffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu8/topology/package_cpus_list",
    "content": "0-47\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu8/topology/physical_package_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu8/topology/thread_siblings",
    "content": "0001,00000100\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu8/topology/thread_siblings_list",
    "content": "8,32\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu9/topology/core_cpus",
    "content": "0002,00000200\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu9/topology/core_cpus_list",
    "content": "9,33\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu9/topology/core_id",
    "content": "12\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu9/topology/core_siblings",
    "content": "ffff,ffffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu9/topology/core_siblings_list",
    "content": "0-47\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu9/topology/die_cpus",
    "content": "ffff,ffffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu9/topology/die_cpus_list",
    "content": "0-47\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu9/topology/die_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu9/topology/package_cpus",
    "content": "ffff,ffffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu9/topology/package_cpus_list",
    "content": "0-47\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu9/topology/physical_package_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu9/topology/thread_siblings",
    "content": "0002,00000200\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/cpu9/topology/thread_siblings_list",
    "content": "9,33\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402/online",
    "content": "0-23,27-40,42,44,46-47"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu0/topology/core_cpus",
    "content": "000001\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu0/topology/core_cpus_list",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu0/topology/core_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu0/topology/core_siblings",
    "content": "ffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu0/topology/core_siblings_list",
    "content": "0-23\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu0/topology/die_cpus",
    "content": "ffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu0/topology/die_cpus_list",
    "content": "0-23\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu0/topology/die_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu0/topology/package_cpus",
    "content": "ffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu0/topology/package_cpus_list",
    "content": "0-23\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu0/topology/physical_package_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu0/topology/thread_siblings",
    "content": "000001\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu0/topology/thread_siblings_list",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu1/topology/core_cpus",
    "content": "000002\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu1/topology/core_cpus_list",
    "content": "1\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu1/topology/core_id",
    "content": "1\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu1/topology/core_siblings",
    "content": "ffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu1/topology/core_siblings_list",
    "content": "0-23\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu1/topology/die_cpus",
    "content": "ffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu1/topology/die_cpus_list",
    "content": "0-23\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu1/topology/die_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu1/topology/package_cpus",
    "content": "ffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu1/topology/package_cpus_list",
    "content": "0-23\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu1/topology/physical_package_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu1/topology/thread_siblings",
    "content": "000002\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu1/topology/thread_siblings_list",
    "content": "1\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu10/topology/core_cpus",
    "content": "000400\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu10/topology/core_cpus_list",
    "content": "10\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu10/topology/core_id",
    "content": "13\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu10/topology/core_siblings",
    "content": "ffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu10/topology/core_siblings_list",
    "content": "0-23\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu10/topology/die_cpus",
    "content": "ffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu10/topology/die_cpus_list",
    "content": "0-23\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu10/topology/die_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu10/topology/package_cpus",
    "content": "ffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu10/topology/package_cpus_list",
    "content": "0-23\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu10/topology/physical_package_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu10/topology/thread_siblings",
    "content": "000400\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu10/topology/thread_siblings_list",
    "content": "10\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu11/topology/core_cpus",
    "content": "000800\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu11/topology/core_cpus_list",
    "content": "11\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu11/topology/core_id",
    "content": "14\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu11/topology/core_siblings",
    "content": "ffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu11/topology/core_siblings_list",
    "content": "0-23\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu11/topology/die_cpus",
    "content": "ffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu11/topology/die_cpus_list",
    "content": "0-23\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu11/topology/die_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu11/topology/package_cpus",
    "content": "ffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu11/topology/package_cpus_list",
    "content": "0-23\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu11/topology/physical_package_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu11/topology/thread_siblings",
    "content": "000800\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu11/topology/thread_siblings_list",
    "content": "11\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu12/topology/core_cpus",
    "content": "001000\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu12/topology/core_cpus_list",
    "content": "12\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu12/topology/core_id",
    "content": "16\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu12/topology/core_siblings",
    "content": "ffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu12/topology/core_siblings_list",
    "content": "0-23\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu12/topology/die_cpus",
    "content": "ffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu12/topology/die_cpus_list",
    "content": "0-23\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu12/topology/die_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu12/topology/package_cpus",
    "content": "ffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu12/topology/package_cpus_list",
    "content": "0-23\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu12/topology/physical_package_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu12/topology/thread_siblings",
    "content": "001000\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu12/topology/thread_siblings_list",
    "content": "12\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu13/topology/core_cpus",
    "content": "002000\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu13/topology/core_cpus_list",
    "content": "13\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu13/topology/core_id",
    "content": "17\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu13/topology/core_siblings",
    "content": "ffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu13/topology/core_siblings_list",
    "content": "0-23\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu13/topology/die_cpus",
    "content": "ffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu13/topology/die_cpus_list",
    "content": "0-23\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu13/topology/die_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu13/topology/package_cpus",
    "content": "ffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu13/topology/package_cpus_list",
    "content": "0-23\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu13/topology/physical_package_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu13/topology/thread_siblings",
    "content": "002000\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu13/topology/thread_siblings_list",
    "content": "13\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu14/topology/core_cpus",
    "content": "004000\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu14/topology/core_cpus_list",
    "content": "14\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu14/topology/core_id",
    "content": "18\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu14/topology/core_siblings",
    "content": "ffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu14/topology/core_siblings_list",
    "content": "0-23\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu14/topology/die_cpus",
    "content": "ffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu14/topology/die_cpus_list",
    "content": "0-23\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu14/topology/die_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu14/topology/package_cpus",
    "content": "ffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu14/topology/package_cpus_list",
    "content": "0-23\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu14/topology/physical_package_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu14/topology/thread_siblings",
    "content": "004000\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu14/topology/thread_siblings_list",
    "content": "14\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu15/topology/core_cpus",
    "content": "008000\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu15/topology/core_cpus_list",
    "content": "15\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu15/topology/core_id",
    "content": "20\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu15/topology/core_siblings",
    "content": "ffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu15/topology/core_siblings_list",
    "content": "0-23\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu15/topology/die_cpus",
    "content": "ffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu15/topology/die_cpus_list",
    "content": "0-23\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu15/topology/die_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu15/topology/package_cpus",
    "content": "ffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu15/topology/package_cpus_list",
    "content": "0-23\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu15/topology/physical_package_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu15/topology/thread_siblings",
    "content": "008000\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu15/topology/thread_siblings_list",
    "content": "15\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu16/topology/core_cpus",
    "content": "010000\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu16/topology/core_cpus_list",
    "content": "16\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu16/topology/core_id",
    "content": "21\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu16/topology/core_siblings",
    "content": "ffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu16/topology/core_siblings_list",
    "content": "0-23\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu16/topology/die_cpus",
    "content": "ffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu16/topology/die_cpus_list",
    "content": "0-23\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu16/topology/die_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu16/topology/package_cpus",
    "content": "ffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu16/topology/package_cpus_list",
    "content": "0-23\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu16/topology/physical_package_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu16/topology/thread_siblings",
    "content": "010000\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu16/topology/thread_siblings_list",
    "content": "16\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu17/topology/core_cpus",
    "content": "020000\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu17/topology/core_cpus_list",
    "content": "17\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu17/topology/core_id",
    "content": "22\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu17/topology/core_siblings",
    "content": "ffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu17/topology/core_siblings_list",
    "content": "0-23\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu17/topology/die_cpus",
    "content": "ffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu17/topology/die_cpus_list",
    "content": "0-23\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu17/topology/die_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu17/topology/package_cpus",
    "content": "ffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu17/topology/package_cpus_list",
    "content": "0-23\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu17/topology/physical_package_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu17/topology/thread_siblings",
    "content": "020000\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu17/topology/thread_siblings_list",
    "content": "17\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu18/topology/core_cpus",
    "content": "040000\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu18/topology/core_cpus_list",
    "content": "18\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu18/topology/core_id",
    "content": "24\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu18/topology/core_siblings",
    "content": "ffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu18/topology/core_siblings_list",
    "content": "0-23\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu18/topology/die_cpus",
    "content": "ffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu18/topology/die_cpus_list",
    "content": "0-23\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu18/topology/die_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu18/topology/package_cpus",
    "content": "ffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu18/topology/package_cpus_list",
    "content": "0-23\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu18/topology/physical_package_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu18/topology/thread_siblings",
    "content": "040000\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu18/topology/thread_siblings_list",
    "content": "18\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu19/topology/core_cpus",
    "content": "080000\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu19/topology/core_cpus_list",
    "content": "19\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu19/topology/core_id",
    "content": "25\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu19/topology/core_siblings",
    "content": "ffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu19/topology/core_siblings_list",
    "content": "0-23\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu19/topology/die_cpus",
    "content": "ffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu19/topology/die_cpus_list",
    "content": "0-23\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu19/topology/die_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu19/topology/package_cpus",
    "content": "ffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu19/topology/package_cpus_list",
    "content": "0-23\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu19/topology/physical_package_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu19/topology/thread_siblings",
    "content": "080000\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu19/topology/thread_siblings_list",
    "content": "19\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu2/topology/core_cpus",
    "content": "000004\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu2/topology/core_cpus_list",
    "content": "2\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu2/topology/core_id",
    "content": "2\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu2/topology/core_siblings",
    "content": "ffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu2/topology/core_siblings_list",
    "content": "0-23\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu2/topology/die_cpus",
    "content": "ffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu2/topology/die_cpus_list",
    "content": "0-23\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu2/topology/die_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu2/topology/package_cpus",
    "content": "ffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu2/topology/package_cpus_list",
    "content": "0-23\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu2/topology/physical_package_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu2/topology/thread_siblings",
    "content": "000004\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu2/topology/thread_siblings_list",
    "content": "2\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu20/topology/core_cpus",
    "content": "100000\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu20/topology/core_cpus_list",
    "content": "20\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu20/topology/core_id",
    "content": "26\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu20/topology/core_siblings",
    "content": "ffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu20/topology/core_siblings_list",
    "content": "0-23\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu20/topology/die_cpus",
    "content": "ffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu20/topology/die_cpus_list",
    "content": "0-23\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu20/topology/die_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu20/topology/package_cpus",
    "content": "ffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu20/topology/package_cpus_list",
    "content": "0-23\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu20/topology/physical_package_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu20/topology/thread_siblings",
    "content": "100000\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu20/topology/thread_siblings_list",
    "content": "20\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu21/topology/core_cpus",
    "content": "200000\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu21/topology/core_cpus_list",
    "content": "21\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu21/topology/core_id",
    "content": "28\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu21/topology/core_siblings",
    "content": "ffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu21/topology/core_siblings_list",
    "content": "0-23\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu21/topology/die_cpus",
    "content": "ffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu21/topology/die_cpus_list",
    "content": "0-23\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu21/topology/die_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu21/topology/package_cpus",
    "content": "ffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu21/topology/package_cpus_list",
    "content": "0-23\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu21/topology/physical_package_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu21/topology/thread_siblings",
    "content": "200000\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu21/topology/thread_siblings_list",
    "content": "21\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu22/topology/core_cpus",
    "content": "400000\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu22/topology/core_cpus_list",
    "content": "22\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu22/topology/core_id",
    "content": "29\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu22/topology/core_siblings",
    "content": "ffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu22/topology/core_siblings_list",
    "content": "0-23\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu22/topology/die_cpus",
    "content": "ffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu22/topology/die_cpus_list",
    "content": "0-23\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu22/topology/die_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu22/topology/package_cpus",
    "content": "ffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu22/topology/package_cpus_list",
    "content": "0-23\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu22/topology/physical_package_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu22/topology/thread_siblings",
    "content": "400000\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu22/topology/thread_siblings_list",
    "content": "22\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu23/topology/core_cpus",
    "content": "800000\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu23/topology/core_cpus_list",
    "content": "23\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu23/topology/core_id",
    "content": "30\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu23/topology/core_siblings",
    "content": "ffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu23/topology/core_siblings_list",
    "content": "0-23\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu23/topology/die_cpus",
    "content": "ffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu23/topology/die_cpus_list",
    "content": "0-23\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu23/topology/die_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu23/topology/package_cpus",
    "content": "ffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu23/topology/package_cpus_list",
    "content": "0-23\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu23/topology/physical_package_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu23/topology/thread_siblings",
    "content": "800000\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu23/topology/thread_siblings_list",
    "content": "23\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu3/topology/core_cpus",
    "content": "000008\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu3/topology/core_cpus_list",
    "content": "3\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu3/topology/core_id",
    "content": "4\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu3/topology/core_siblings",
    "content": "ffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu3/topology/core_siblings_list",
    "content": "0-23\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu3/topology/die_cpus",
    "content": "ffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu3/topology/die_cpus_list",
    "content": "0-23\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu3/topology/die_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu3/topology/package_cpus",
    "content": "ffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu3/topology/package_cpus_list",
    "content": "0-23\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu3/topology/physical_package_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu3/topology/thread_siblings",
    "content": "000008\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu3/topology/thread_siblings_list",
    "content": "3\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu4/topology/core_cpus",
    "content": "000010\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu4/topology/core_cpus_list",
    "content": "4\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu4/topology/core_id",
    "content": "5\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu4/topology/core_siblings",
    "content": "ffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu4/topology/core_siblings_list",
    "content": "0-23\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu4/topology/die_cpus",
    "content": "ffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu4/topology/die_cpus_list",
    "content": "0-23\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu4/topology/die_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu4/topology/package_cpus",
    "content": "ffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu4/topology/package_cpus_list",
    "content": "0-23\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu4/topology/physical_package_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu4/topology/thread_siblings",
    "content": "000010\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu4/topology/thread_siblings_list",
    "content": "4\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu5/topology/core_cpus",
    "content": "000020\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu5/topology/core_cpus_list",
    "content": "5\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu5/topology/core_id",
    "content": "6\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu5/topology/core_siblings",
    "content": "ffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu5/topology/core_siblings_list",
    "content": "0-23\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu5/topology/die_cpus",
    "content": "ffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu5/topology/die_cpus_list",
    "content": "0-23\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu5/topology/die_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu5/topology/package_cpus",
    "content": "ffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu5/topology/package_cpus_list",
    "content": "0-23\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu5/topology/physical_package_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu5/topology/thread_siblings",
    "content": "000020\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu5/topology/thread_siblings_list",
    "content": "5\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu6/topology/core_cpus",
    "content": "000040\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu6/topology/core_cpus_list",
    "content": "6\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu6/topology/core_id",
    "content": "8\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu6/topology/core_siblings",
    "content": "ffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu6/topology/core_siblings_list",
    "content": "0-23\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu6/topology/die_cpus",
    "content": "ffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu6/topology/die_cpus_list",
    "content": "0-23\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu6/topology/die_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu6/topology/package_cpus",
    "content": "ffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu6/topology/package_cpus_list",
    "content": "0-23\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu6/topology/physical_package_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu6/topology/thread_siblings",
    "content": "000040\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu6/topology/thread_siblings_list",
    "content": "6\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu7/topology/core_cpus",
    "content": "000080\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu7/topology/core_cpus_list",
    "content": "7\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu7/topology/core_id",
    "content": "9\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu7/topology/core_siblings",
    "content": "ffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu7/topology/core_siblings_list",
    "content": "0-23\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu7/topology/die_cpus",
    "content": "ffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu7/topology/die_cpus_list",
    "content": "0-23\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu7/topology/die_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu7/topology/package_cpus",
    "content": "ffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu7/topology/package_cpus_list",
    "content": "0-23\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu7/topology/physical_package_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu7/topology/thread_siblings",
    "content": "000080\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu7/topology/thread_siblings_list",
    "content": "7\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu8/topology/core_cpus",
    "content": "000100\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu8/topology/core_cpus_list",
    "content": "8\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu8/topology/core_id",
    "content": "10\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu8/topology/core_siblings",
    "content": "ffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu8/topology/core_siblings_list",
    "content": "0-23\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu8/topology/die_cpus",
    "content": "ffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu8/topology/die_cpus_list",
    "content": "0-23\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu8/topology/die_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu8/topology/package_cpus",
    "content": "ffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu8/topology/package_cpus_list",
    "content": "0-23\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu8/topology/physical_package_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu8/topology/thread_siblings",
    "content": "000100\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu8/topology/thread_siblings_list",
    "content": "8\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu9/topology/core_cpus",
    "content": "000200\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu9/topology/core_cpus_list",
    "content": "9\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu9/topology/core_id",
    "content": "12\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu9/topology/core_siblings",
    "content": "ffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu9/topology/core_siblings_list",
    "content": "0-23\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu9/topology/die_cpus",
    "content": "ffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu9/topology/die_cpus_list",
    "content": "0-23\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu9/topology/die_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu9/topology/package_cpus",
    "content": "ffffff\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu9/topology/package_cpus_list",
    "content": "0-23\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu9/topology/physical_package_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu9/topology/thread_siblings",
    "content": "000200\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/cpu9/topology/thread_siblings_list",
    "content": "9\n"
  },
  {
    "path": "utils/sysfs/testdata_epyc7402_nohyperthreading/online",
    "content": "0-10,12,14,20-23"
  },
  {
    "path": "utils/sysfs/testdata_graviton2/cpu0/online",
    "content": "1\n"
  },
  {
    "path": "utils/sysfs/testdata_graviton2/cpu0/topology/core_cpus",
    "content": "1\n"
  },
  {
    "path": "utils/sysfs/testdata_graviton2/cpu0/topology/core_cpus_list",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_graviton2/cpu0/topology/core_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_graviton2/cpu0/topology/core_siblings",
    "content": "b\n"
  },
  {
    "path": "utils/sysfs/testdata_graviton2/cpu0/topology/core_siblings_list",
    "content": "0-1,3\n"
  },
  {
    "path": "utils/sysfs/testdata_graviton2/cpu0/topology/die_cpus",
    "content": "1\n"
  },
  {
    "path": "utils/sysfs/testdata_graviton2/cpu0/topology/die_cpus_list",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_graviton2/cpu0/topology/die_id",
    "content": "-1\n"
  },
  {
    "path": "utils/sysfs/testdata_graviton2/cpu0/topology/package_cpus",
    "content": "b\n"
  },
  {
    "path": "utils/sysfs/testdata_graviton2/cpu0/topology/package_cpus_list",
    "content": "0-1,3\n"
  },
  {
    "path": "utils/sysfs/testdata_graviton2/cpu0/topology/physical_package_id",
    "content": "60\n"
  },
  {
    "path": "utils/sysfs/testdata_graviton2/cpu0/topology/thread_siblings",
    "content": "1\n"
  },
  {
    "path": "utils/sysfs/testdata_graviton2/cpu0/topology/thread_siblings_list",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_graviton2/cpu1/online",
    "content": "1\n"
  },
  {
    "path": "utils/sysfs/testdata_graviton2/cpu1/topology/core_cpus",
    "content": "2\n"
  },
  {
    "path": "utils/sysfs/testdata_graviton2/cpu1/topology/core_cpus_list",
    "content": "1\n"
  },
  {
    "path": "utils/sysfs/testdata_graviton2/cpu1/topology/core_id",
    "content": "1\n"
  },
  {
    "path": "utils/sysfs/testdata_graviton2/cpu1/topology/core_siblings",
    "content": "b\n"
  },
  {
    "path": "utils/sysfs/testdata_graviton2/cpu1/topology/core_siblings_list",
    "content": "0-1,3\n"
  },
  {
    "path": "utils/sysfs/testdata_graviton2/cpu1/topology/die_cpus",
    "content": "2\n"
  },
  {
    "path": "utils/sysfs/testdata_graviton2/cpu1/topology/die_cpus_list",
    "content": "1\n"
  },
  {
    "path": "utils/sysfs/testdata_graviton2/cpu1/topology/die_id",
    "content": "-1\n"
  },
  {
    "path": "utils/sysfs/testdata_graviton2/cpu1/topology/package_cpus",
    "content": "b\n"
  },
  {
    "path": "utils/sysfs/testdata_graviton2/cpu1/topology/package_cpus_list",
    "content": "0-1,3\n"
  },
  {
    "path": "utils/sysfs/testdata_graviton2/cpu1/topology/physical_package_id",
    "content": "60\n"
  },
  {
    "path": "utils/sysfs/testdata_graviton2/cpu1/topology/thread_siblings",
    "content": "2\n"
  },
  {
    "path": "utils/sysfs/testdata_graviton2/cpu1/topology/thread_siblings_list",
    "content": "1\n"
  },
  {
    "path": "utils/sysfs/testdata_graviton2/cpu2/online",
    "content": "1\n"
  },
  {
    "path": "utils/sysfs/testdata_graviton2/cpu3/online",
    "content": "1\n"
  },
  {
    "path": "utils/sysfs/testdata_graviton2/cpu3/topology/core_cpus",
    "content": "8\n"
  },
  {
    "path": "utils/sysfs/testdata_graviton2/cpu3/topology/core_cpus_list",
    "content": "3\n"
  },
  {
    "path": "utils/sysfs/testdata_graviton2/cpu3/topology/core_id",
    "content": "3\n"
  },
  {
    "path": "utils/sysfs/testdata_graviton2/cpu3/topology/core_siblings",
    "content": "b\n"
  },
  {
    "path": "utils/sysfs/testdata_graviton2/cpu3/topology/core_siblings_list",
    "content": "0-1,3\n"
  },
  {
    "path": "utils/sysfs/testdata_graviton2/cpu3/topology/die_cpus",
    "content": "8\n"
  },
  {
    "path": "utils/sysfs/testdata_graviton2/cpu3/topology/die_cpus_list",
    "content": "3\n"
  },
  {
    "path": "utils/sysfs/testdata_graviton2/cpu3/topology/die_id",
    "content": "-1\n"
  },
  {
    "path": "utils/sysfs/testdata_graviton2/cpu3/topology/package_cpus",
    "content": "b\n"
  },
  {
    "path": "utils/sysfs/testdata_graviton2/cpu3/topology/package_cpus_list",
    "content": "0-1,3\n"
  },
  {
    "path": "utils/sysfs/testdata_graviton2/cpu3/topology/physical_package_id",
    "content": "60\n"
  },
  {
    "path": "utils/sysfs/testdata_graviton2/cpu3/topology/thread_siblings",
    "content": "8\n"
  },
  {
    "path": "utils/sysfs/testdata_graviton2/cpu3/topology/thread_siblings_list",
    "content": "3\n"
  },
  {
    "path": "utils/sysfs/testdata_graviton2/online",
    "content": "1-3\n"
  },
  {
    "path": "utils/sysfs/testdata_rpi4/cpu0/hotplug/state",
    "content": "206\n"
  },
  {
    "path": "utils/sysfs/testdata_rpi4/cpu0/topology/core_cpus",
    "content": "1\n"
  },
  {
    "path": "utils/sysfs/testdata_rpi4/cpu0/topology/core_cpus_list",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_rpi4/cpu0/topology/core_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_rpi4/cpu0/topology/core_siblings",
    "content": "f\n"
  },
  {
    "path": "utils/sysfs/testdata_rpi4/cpu0/topology/core_siblings_list",
    "content": "0-3\n"
  },
  {
    "path": "utils/sysfs/testdata_rpi4/cpu0/topology/die_cpus",
    "content": "1\n"
  },
  {
    "path": "utils/sysfs/testdata_rpi4/cpu0/topology/die_cpus_list",
    "content": "1\n"
  },
  {
    "path": "utils/sysfs/testdata_rpi4/cpu0/topology/die_id",
    "content": "-1\n"
  },
  {
    "path": "utils/sysfs/testdata_rpi4/cpu0/topology/package_cpus",
    "content": "f\n"
  },
  {
    "path": "utils/sysfs/testdata_rpi4/cpu0/topology/package_cpus_list",
    "content": "0-3\n"
  },
  {
    "path": "utils/sysfs/testdata_rpi4/cpu0/topology/physical_package_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_rpi4/cpu0/topology/thread_siblings",
    "content": "1\n"
  },
  {
    "path": "utils/sysfs/testdata_rpi4/cpu0/topology/thread_siblings_list",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_rpi4/cpu1/hotplug/state",
    "content": "206\n"
  },
  {
    "path": "utils/sysfs/testdata_rpi4/cpu1/topology/core_cpus",
    "content": "2\n"
  },
  {
    "path": "utils/sysfs/testdata_rpi4/cpu1/topology/core_cpus_list",
    "content": "1\n"
  },
  {
    "path": "utils/sysfs/testdata_rpi4/cpu1/topology/core_id",
    "content": "1\n"
  },
  {
    "path": "utils/sysfs/testdata_rpi4/cpu1/topology/core_siblings",
    "content": "f\n"
  },
  {
    "path": "utils/sysfs/testdata_rpi4/cpu1/topology/core_siblings_list",
    "content": "0-3\n"
  },
  {
    "path": "utils/sysfs/testdata_rpi4/cpu1/topology/die_cpus",
    "content": "2\n"
  },
  {
    "path": "utils/sysfs/testdata_rpi4/cpu1/topology/die_cpus_list",
    "content": "1\n"
  },
  {
    "path": "utils/sysfs/testdata_rpi4/cpu1/topology/die_id",
    "content": "-1\n"
  },
  {
    "path": "utils/sysfs/testdata_rpi4/cpu1/topology/package_cpus",
    "content": "f\n"
  },
  {
    "path": "utils/sysfs/testdata_rpi4/cpu1/topology/package_cpus_list",
    "content": "0-3\n"
  },
  {
    "path": "utils/sysfs/testdata_rpi4/cpu1/topology/physical_package_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_rpi4/cpu1/topology/thread_siblings",
    "content": "2\n"
  },
  {
    "path": "utils/sysfs/testdata_rpi4/cpu1/topology/thread_siblings_list",
    "content": "1\n"
  },
  {
    "path": "utils/sysfs/testdata_rpi4/cpu2/hotplug/state",
    "content": "206\n"
  },
  {
    "path": "utils/sysfs/testdata_rpi4/cpu2/topology/core_cpus",
    "content": "4\n"
  },
  {
    "path": "utils/sysfs/testdata_rpi4/cpu2/topology/core_cpus_list",
    "content": "2\n"
  },
  {
    "path": "utils/sysfs/testdata_rpi4/cpu2/topology/core_id",
    "content": "2\n"
  },
  {
    "path": "utils/sysfs/testdata_rpi4/cpu2/topology/core_siblings",
    "content": "f\n"
  },
  {
    "path": "utils/sysfs/testdata_rpi4/cpu2/topology/core_siblings_list",
    "content": "0-3\n"
  },
  {
    "path": "utils/sysfs/testdata_rpi4/cpu2/topology/die_cpus",
    "content": "4\n"
  },
  {
    "path": "utils/sysfs/testdata_rpi4/cpu2/topology/die_cpus_list",
    "content": "2\n"
  },
  {
    "path": "utils/sysfs/testdata_rpi4/cpu2/topology/die_id",
    "content": "-1\n"
  },
  {
    "path": "utils/sysfs/testdata_rpi4/cpu2/topology/package_cpus",
    "content": "f\n"
  },
  {
    "path": "utils/sysfs/testdata_rpi4/cpu2/topology/package_cpus_list",
    "content": "0-3\n"
  },
  {
    "path": "utils/sysfs/testdata_rpi4/cpu2/topology/physical_package_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_rpi4/cpu2/topology/thread_siblings",
    "content": "4\n"
  },
  {
    "path": "utils/sysfs/testdata_rpi4/cpu2/topology/thread_siblings_list",
    "content": "2\n"
  },
  {
    "path": "utils/sysfs/testdata_rpi4/cpu3/hotplug/state",
    "content": "206\n"
  },
  {
    "path": "utils/sysfs/testdata_rpi4/cpu3/topology/core_cpus",
    "content": "8\n"
  },
  {
    "path": "utils/sysfs/testdata_rpi4/cpu3/topology/core_cpus_list",
    "content": "3\n"
  },
  {
    "path": "utils/sysfs/testdata_rpi4/cpu3/topology/core_id",
    "content": "3\n"
  },
  {
    "path": "utils/sysfs/testdata_rpi4/cpu3/topology/core_siblings",
    "content": "f\n"
  },
  {
    "path": "utils/sysfs/testdata_rpi4/cpu3/topology/core_siblings_list",
    "content": "0-3\n"
  },
  {
    "path": "utils/sysfs/testdata_rpi4/cpu3/topology/die_cpus",
    "content": "8\n"
  },
  {
    "path": "utils/sysfs/testdata_rpi4/cpu3/topology/die_cpus_list",
    "content": "3\n"
  },
  {
    "path": "utils/sysfs/testdata_rpi4/cpu3/topology/die_id",
    "content": "-1\n"
  },
  {
    "path": "utils/sysfs/testdata_rpi4/cpu3/topology/package_cpus",
    "content": "f\n"
  },
  {
    "path": "utils/sysfs/testdata_rpi4/cpu3/topology/package_cpus_list",
    "content": "0-3\n"
  },
  {
    "path": "utils/sysfs/testdata_rpi4/cpu3/topology/physical_package_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_rpi4/cpu3/topology/thread_siblings",
    "content": "8\n"
  },
  {
    "path": "utils/sysfs/testdata_rpi4/cpu3/topology/thread_siblings_list",
    "content": "3\n"
  },
  {
    "path": "utils/sysfs/testdata_rpi4/hotplug/states",
    "content": " 24: fs/buffer:dead\n 25: printk:dead\n 26: mm/memctrl:dead\n 27: lib/percpu_cnt:dead\n 28: lib/radix:dead\n 29: mm/page_alloc:dead\n 30: net/dev:dead\n 35: padata:dead\n 36: workqueue:prepare\n 38: hrtimers:prepare\n 42: relay:prepare\n 43: slab:prepare\n 44: md/raid5:prepare\n 45: RCU/tree:prepare\n 54: base/topology:prepare\n 57: trace/RB:preapre\n 58: mm/zsmalloc:prepare\n 59: mm/zswap:prepare\n 60: mm/zswap_pool:prepare\n 63: timers:prepare\n 65: fork:vm_stack_cache\n 86: cpu:bringup\n 87: idle:dead\n 88: ap:offline\n 89: sched:starting\n 90: RCU/tree:dying\n 91: irqchip/arm/gic:starting\n107: arm64/debug_monitors:starting\n108: perf/arm64/hw_breakpoint:starting\n110: perf/arm/pmu:starting\n113: clockevents/arm/arch_timer:starting\n125: kvm/cpu:starting\n126: kvm/arm/vgic:starting\n128: kvm/arm/timer:starting\n129: clockevents/dummy_timer:starting\n132: arm64/isndep:starting\n133: smpcfd:dying\n136: ap:online\n137: cpu:teardown\n139: smpboot/threads:online\n141: irq/affinity:online\n144: perf:online\n155: perf/arm/ccn:online\n168: lockup_detector:online\n169: workqueue:online\n170: RCU/tree:online\n172: mm/writeback:online\n173: mm/vmstat:online\n174: mm/compaction:online\n175: arm64/cpuinfo:online\n176: padata:online\n177: mm/vmscan:online\n178: lib/percpu_cnt:online\n179: cpufreq:online\n180: leds/trigger:starting\n181: printk:online\n205: sched:active\n206: online\n 41: smpcfd:prepare\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu0/topology/core_cpus",
    "content": "00000003\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu0/topology/core_cpus_list",
    "content": "0-1\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu0/topology/core_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu0/topology/core_siblings",
    "content": "00000003\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu0/topology/core_siblings_list",
    "content": "0-1\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu0/topology/die_cpus",
    "content": "00000003\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu0/topology/die_cpus_list",
    "content": "0-1\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu0/topology/die_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu0/topology/package_cpus",
    "content": "00000003\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu0/topology/package_cpus_list",
    "content": "0-1\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu0/topology/physical_package_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu0/topology/thread_siblings",
    "content": "00000003\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu0/topology/thread_siblings_list",
    "content": "0-1\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu1/topology/core_cpus",
    "content": "00000003\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu1/topology/core_cpus_list",
    "content": "0-1\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu1/topology/core_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu1/topology/core_siblings",
    "content": "00000003\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu1/topology/core_siblings_list",
    "content": "0-1\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu1/topology/die_cpus",
    "content": "00000003\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu1/topology/die_cpus_list",
    "content": "0-1\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu1/topology/die_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu1/topology/package_cpus",
    "content": "00000003\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu1/topology/package_cpus_list",
    "content": "0-1\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu1/topology/physical_package_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu1/topology/thread_siblings",
    "content": "00000003\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu1/topology/thread_siblings_list",
    "content": "0-1\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu10/topology/core_cpus",
    "content": "00000c00\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu10/topology/core_cpus_list",
    "content": "10-11\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu10/topology/core_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu10/topology/core_siblings",
    "content": "00000c00\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu10/topology/core_siblings_list",
    "content": "10-11\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu10/topology/die_cpus",
    "content": "00000c00\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu10/topology/die_cpus_list",
    "content": "10-11\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu10/topology/die_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu10/topology/package_cpus",
    "content": "00000c00\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu10/topology/package_cpus_list",
    "content": "10-11\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu10/topology/physical_package_id",
    "content": "5\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu10/topology/thread_siblings",
    "content": "00000c00\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu10/topology/thread_siblings_list",
    "content": "10-11\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu11/topology/core_cpus",
    "content": "00000c00\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu11/topology/core_cpus_list",
    "content": "10-11\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu11/topology/core_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu11/topology/core_siblings",
    "content": "00000c00\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu11/topology/core_siblings_list",
    "content": "10-11\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu11/topology/die_cpus",
    "content": "00000c00\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu11/topology/die_cpus_list",
    "content": "10-11\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu11/topology/die_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu11/topology/package_cpus",
    "content": "00000c00\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu11/topology/package_cpus_list",
    "content": "10-11\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu11/topology/physical_package_id",
    "content": "5\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu11/topology/thread_siblings",
    "content": "00000c00\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu11/topology/thread_siblings_list",
    "content": "10-11\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu12/topology/core_cpus",
    "content": "00003000\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu12/topology/core_cpus_list",
    "content": "12-13\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu12/topology/core_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu12/topology/core_siblings",
    "content": "00003000\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu12/topology/core_siblings_list",
    "content": "12-13\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu12/topology/die_cpus",
    "content": "00003000\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu12/topology/die_cpus_list",
    "content": "12-13\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu12/topology/die_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu12/topology/package_cpus",
    "content": "00003000\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu12/topology/package_cpus_list",
    "content": "12-13\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu12/topology/physical_package_id",
    "content": "6\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu12/topology/thread_siblings",
    "content": "00003000\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu12/topology/thread_siblings_list",
    "content": "12-13\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu13/topology/core_cpus",
    "content": "00003000\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu13/topology/core_cpus_list",
    "content": "12-13\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu13/topology/core_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu13/topology/core_siblings",
    "content": "00003000\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu13/topology/core_siblings_list",
    "content": "12-13\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu13/topology/die_cpus",
    "content": "00003000\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu13/topology/die_cpus_list",
    "content": "12-13\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu13/topology/die_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu13/topology/package_cpus",
    "content": "00003000\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu13/topology/package_cpus_list",
    "content": "12-13\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu13/topology/physical_package_id",
    "content": "6\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu13/topology/thread_siblings",
    "content": "00003000\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu13/topology/thread_siblings_list",
    "content": "12-13\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu14/topology/core_cpus",
    "content": "0000c000\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu14/topology/core_cpus_list",
    "content": "14-15\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu14/topology/core_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu14/topology/core_siblings",
    "content": "0000c000\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu14/topology/core_siblings_list",
    "content": "14-15\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu14/topology/die_cpus",
    "content": "0000c000\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu14/topology/die_cpus_list",
    "content": "14-15\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu14/topology/die_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu14/topology/package_cpus",
    "content": "0000c000\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu14/topology/package_cpus_list",
    "content": "14-15\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu14/topology/physical_package_id",
    "content": "7\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu14/topology/thread_siblings",
    "content": "0000c000\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu14/topology/thread_siblings_list",
    "content": "14-15\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu15/topology/core_cpus",
    "content": "0000c000\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu15/topology/core_cpus_list",
    "content": "14-15\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu15/topology/core_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu15/topology/core_siblings",
    "content": "0000c000\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu15/topology/core_siblings_list",
    "content": "14-15\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu15/topology/die_cpus",
    "content": "0000c000\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu15/topology/die_cpus_list",
    "content": "14-15\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu15/topology/die_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu15/topology/package_cpus",
    "content": "0000c000\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu15/topology/package_cpus_list",
    "content": "14-15\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu15/topology/physical_package_id",
    "content": "7\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu15/topology/thread_siblings",
    "content": "0000c000\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu15/topology/thread_siblings_list",
    "content": "14-15\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu16/topology/core_cpus",
    "content": "00030000\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu16/topology/core_cpus_list",
    "content": "16-17\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu16/topology/core_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu16/topology/core_siblings",
    "content": "00030000\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu16/topology/core_siblings_list",
    "content": "16-17\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu16/topology/die_cpus",
    "content": "00030000\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu16/topology/die_cpus_list",
    "content": "16-17\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu16/topology/die_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu16/topology/package_cpus",
    "content": "00030000\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu16/topology/package_cpus_list",
    "content": "16-17\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu16/topology/physical_package_id",
    "content": "8\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu16/topology/thread_siblings",
    "content": "00030000\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu16/topology/thread_siblings_list",
    "content": "16-17\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu17/topology/core_cpus",
    "content": "00030000\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu17/topology/core_cpus_list",
    "content": "16-17\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu17/topology/core_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu17/topology/core_siblings",
    "content": "00030000\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu17/topology/core_siblings_list",
    "content": "16-17\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu17/topology/die_cpus",
    "content": "00030000\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu17/topology/die_cpus_list",
    "content": "16-17\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu17/topology/die_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu17/topology/package_cpus",
    "content": "00030000\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu17/topology/package_cpus_list",
    "content": "16-17\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu17/topology/physical_package_id",
    "content": "8\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu17/topology/thread_siblings",
    "content": "00030000\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu17/topology/thread_siblings_list",
    "content": "16-17\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu18/topology/core_cpus",
    "content": "000c0000\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu18/topology/core_cpus_list",
    "content": "18-19\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu18/topology/core_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu18/topology/core_siblings",
    "content": "000c0000\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu18/topology/core_siblings_list",
    "content": "18-19\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu18/topology/die_cpus",
    "content": "000c0000\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu18/topology/die_cpus_list",
    "content": "18-19\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu18/topology/die_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu18/topology/package_cpus",
    "content": "000c0000\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu18/topology/package_cpus_list",
    "content": "18-19\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu18/topology/physical_package_id",
    "content": "9\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu18/topology/thread_siblings",
    "content": "000c0000\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu18/topology/thread_siblings_list",
    "content": "18-19\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu19/topology/core_cpus",
    "content": "000c0000\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu19/topology/core_cpus_list",
    "content": "18-19\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu19/topology/core_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu19/topology/core_siblings",
    "content": "000c0000\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu19/topology/core_siblings_list",
    "content": "18-19\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu19/topology/die_cpus",
    "content": "000c0000\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu19/topology/die_cpus_list",
    "content": "18-19\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu19/topology/die_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu19/topology/package_cpus",
    "content": "000c0000\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu19/topology/package_cpus_list",
    "content": "18-19\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu19/topology/physical_package_id",
    "content": "9\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu19/topology/thread_siblings",
    "content": "000c0000\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu19/topology/thread_siblings_list",
    "content": "18-19\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu2/topology/core_cpus",
    "content": "0000000c\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu2/topology/core_cpus_list",
    "content": "2-3\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu2/topology/core_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu2/topology/core_siblings",
    "content": "0000000c\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu2/topology/core_siblings_list",
    "content": "2-3\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu2/topology/die_cpus",
    "content": "0000000c\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu2/topology/die_cpus_list",
    "content": "2-3\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu2/topology/die_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu2/topology/package_cpus",
    "content": "0000000c\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu2/topology/package_cpus_list",
    "content": "2-3\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu2/topology/physical_package_id",
    "content": "1\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu2/topology/thread_siblings",
    "content": "0000000c\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu2/topology/thread_siblings_list",
    "content": "2-3\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu20/topology/core_cpus",
    "content": "00300000\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu20/topology/core_cpus_list",
    "content": "20-21\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu20/topology/core_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu20/topology/core_siblings",
    "content": "00300000\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu20/topology/core_siblings_list",
    "content": "20-21\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu20/topology/die_cpus",
    "content": "00300000\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu20/topology/die_cpus_list",
    "content": "20-21\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu20/topology/die_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu20/topology/package_cpus",
    "content": "00300000\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu20/topology/package_cpus_list",
    "content": "20-21\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu20/topology/physical_package_id",
    "content": "10\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu20/topology/thread_siblings",
    "content": "00300000\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu20/topology/thread_siblings_list",
    "content": "20-21\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu21/topology/core_cpus",
    "content": "00300000\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu21/topology/core_cpus_list",
    "content": "20-21\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu21/topology/core_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu21/topology/core_siblings",
    "content": "00300000\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu21/topology/core_siblings_list",
    "content": "20-21\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu21/topology/die_cpus",
    "content": "00300000\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu21/topology/die_cpus_list",
    "content": "20-21\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu21/topology/die_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu21/topology/package_cpus",
    "content": "00300000\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu21/topology/package_cpus_list",
    "content": "20-21\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu21/topology/physical_package_id",
    "content": "10\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu21/topology/thread_siblings",
    "content": "00300000\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu21/topology/thread_siblings_list",
    "content": "20-21\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu22/topology/core_cpus",
    "content": "00c00000\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu22/topology/core_cpus_list",
    "content": "22-23\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu22/topology/core_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu22/topology/core_siblings",
    "content": "00c00000\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu22/topology/core_siblings_list",
    "content": "22-23\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu22/topology/die_cpus",
    "content": "00c00000\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu22/topology/die_cpus_list",
    "content": "22-23\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu22/topology/die_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu22/topology/package_cpus",
    "content": "00c00000\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu22/topology/package_cpus_list",
    "content": "22-23\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu22/topology/physical_package_id",
    "content": "11\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu22/topology/thread_siblings",
    "content": "00c00000\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu22/topology/thread_siblings_list",
    "content": "22-23\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu23/topology/core_cpus",
    "content": "00c00000\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu23/topology/core_cpus_list",
    "content": "22-23\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu23/topology/core_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu23/topology/core_siblings",
    "content": "00c00000\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu23/topology/core_siblings_list",
    "content": "22-23\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu23/topology/die_cpus",
    "content": "00c00000\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu23/topology/die_cpus_list",
    "content": "22-23\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu23/topology/die_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu23/topology/package_cpus",
    "content": "00c00000\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu23/topology/package_cpus_list",
    "content": "22-23\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu23/topology/physical_package_id",
    "content": "11\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu23/topology/thread_siblings",
    "content": "00c00000\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu23/topology/thread_siblings_list",
    "content": "22-23\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu24/topology/core_cpus",
    "content": "03000000\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu24/topology/core_cpus_list",
    "content": "24-25\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu24/topology/core_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu24/topology/core_siblings",
    "content": "03000000\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu24/topology/core_siblings_list",
    "content": "24-25\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu24/topology/die_cpus",
    "content": "03000000\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu24/topology/die_cpus_list",
    "content": "24-25\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu24/topology/die_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu24/topology/package_cpus",
    "content": "03000000\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu24/topology/package_cpus_list",
    "content": "24-25\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu24/topology/physical_package_id",
    "content": "12\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu24/topology/thread_siblings",
    "content": "03000000\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu24/topology/thread_siblings_list",
    "content": "24-25\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu25/topology/core_cpus",
    "content": "03000000\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu25/topology/core_cpus_list",
    "content": "24-25\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu25/topology/core_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu25/topology/core_siblings",
    "content": "03000000\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu25/topology/core_siblings_list",
    "content": "24-25\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu25/topology/die_cpus",
    "content": "03000000\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu25/topology/die_cpus_list",
    "content": "24-25\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu25/topology/die_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu25/topology/package_cpus",
    "content": "03000000\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu25/topology/package_cpus_list",
    "content": "24-25\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu25/topology/physical_package_id",
    "content": "12\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu25/topology/thread_siblings",
    "content": "03000000\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu25/topology/thread_siblings_list",
    "content": "24-25\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu26/topology/core_cpus",
    "content": "0c000000\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu26/topology/core_cpus_list",
    "content": "26-27\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu26/topology/core_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu26/topology/core_siblings",
    "content": "0c000000\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu26/topology/core_siblings_list",
    "content": "26-27\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu26/topology/die_cpus",
    "content": "0c000000\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu26/topology/die_cpus_list",
    "content": "26-27\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu26/topology/die_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu26/topology/package_cpus",
    "content": "0c000000\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu26/topology/package_cpus_list",
    "content": "26-27\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu26/topology/physical_package_id",
    "content": "13\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu26/topology/thread_siblings",
    "content": "0c000000\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu26/topology/thread_siblings_list",
    "content": "26-27\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu27/topology/core_cpus",
    "content": "0c000000\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu27/topology/core_cpus_list",
    "content": "26-27\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu27/topology/core_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu27/topology/core_siblings",
    "content": "0c000000\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu27/topology/core_siblings_list",
    "content": "26-27\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu27/topology/die_cpus",
    "content": "0c000000\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu27/topology/die_cpus_list",
    "content": "26-27\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu27/topology/die_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu27/topology/package_cpus",
    "content": "0c000000\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu27/topology/package_cpus_list",
    "content": "26-27\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu27/topology/physical_package_id",
    "content": "13\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu27/topology/thread_siblings",
    "content": "0c000000\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu27/topology/thread_siblings_list",
    "content": "26-27\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu28/topology/core_cpus",
    "content": "30000000\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu28/topology/core_cpus_list",
    "content": "28-29\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu28/topology/core_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu28/topology/core_siblings",
    "content": "30000000\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu28/topology/core_siblings_list",
    "content": "28-29\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu28/topology/die_cpus",
    "content": "30000000\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu28/topology/die_cpus_list",
    "content": "28-29\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu28/topology/die_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu28/topology/package_cpus",
    "content": "30000000\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu28/topology/package_cpus_list",
    "content": "28-29\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu28/topology/physical_package_id",
    "content": "14\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu28/topology/thread_siblings",
    "content": "30000000\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu28/topology/thread_siblings_list",
    "content": "28-29\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu29/topology/core_cpus",
    "content": "30000000\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu29/topology/core_cpus_list",
    "content": "28-29\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu29/topology/core_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu29/topology/core_siblings",
    "content": "30000000\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu29/topology/core_siblings_list",
    "content": "28-29\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu29/topology/die_cpus",
    "content": "30000000\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu29/topology/die_cpus_list",
    "content": "28-29\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu29/topology/die_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu29/topology/package_cpus",
    "content": "30000000\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu29/topology/package_cpus_list",
    "content": "28-29\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu29/topology/physical_package_id",
    "content": "14\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu29/topology/thread_siblings",
    "content": "30000000\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu29/topology/thread_siblings_list",
    "content": "28-29\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu3/topology/core_cpus",
    "content": "0000000c\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu3/topology/core_cpus_list",
    "content": "2-3\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu3/topology/core_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu3/topology/core_siblings",
    "content": "0000000c\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu3/topology/core_siblings_list",
    "content": "2-3\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu3/topology/die_cpus",
    "content": "0000000c\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu3/topology/die_cpus_list",
    "content": "2-3\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu3/topology/die_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu3/topology/package_cpus",
    "content": "0000000c\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu3/topology/package_cpus_list",
    "content": "2-3\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu3/topology/physical_package_id",
    "content": "1\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu3/topology/thread_siblings",
    "content": "0000000c\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu3/topology/thread_siblings_list",
    "content": "2-3\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu30/topology/core_cpus",
    "content": "c0000000\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu30/topology/core_cpus_list",
    "content": "30-31\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu30/topology/core_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu30/topology/core_siblings",
    "content": "c0000000\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu30/topology/core_siblings_list",
    "content": "30-31\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu30/topology/die_cpus",
    "content": "c0000000\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu30/topology/die_cpus_list",
    "content": "30-31\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu30/topology/die_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu30/topology/package_cpus",
    "content": "c0000000\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu30/topology/package_cpus_list",
    "content": "30-31\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu30/topology/physical_package_id",
    "content": "15\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu30/topology/thread_siblings",
    "content": "c0000000\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu30/topology/thread_siblings_list",
    "content": "30-31\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu31/topology/core_cpus",
    "content": "c0000000\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu31/topology/core_cpus_list",
    "content": "30-31\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu31/topology/core_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu31/topology/core_siblings",
    "content": "c0000000\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu31/topology/core_siblings_list",
    "content": "30-31\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu31/topology/die_cpus",
    "content": "c0000000\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu31/topology/die_cpus_list",
    "content": "30-31\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu31/topology/die_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu31/topology/package_cpus",
    "content": "c0000000\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu31/topology/package_cpus_list",
    "content": "30-31\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu31/topology/physical_package_id",
    "content": "15\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu31/topology/thread_siblings",
    "content": "c0000000\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu31/topology/thread_siblings_list",
    "content": "30-31\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu4/topology/core_cpus",
    "content": "00000030\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu4/topology/core_cpus_list",
    "content": "4-5\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu4/topology/core_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu4/topology/core_siblings",
    "content": "00000030\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu4/topology/core_siblings_list",
    "content": "4-5\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu4/topology/die_cpus",
    "content": "00000030\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu4/topology/die_cpus_list",
    "content": "4-5\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu4/topology/die_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu4/topology/package_cpus",
    "content": "00000030\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu4/topology/package_cpus_list",
    "content": "4-5\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu4/topology/physical_package_id",
    "content": "2\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu4/topology/thread_siblings",
    "content": "00000030\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu4/topology/thread_siblings_list",
    "content": "4-5\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu5/topology/core_cpus",
    "content": "00000030\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu5/topology/core_cpus_list",
    "content": "4-5\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu5/topology/core_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu5/topology/core_siblings",
    "content": "00000030\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu5/topology/core_siblings_list",
    "content": "4-5\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu5/topology/die_cpus",
    "content": "00000030\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu5/topology/die_cpus_list",
    "content": "4-5\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu5/topology/die_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu5/topology/package_cpus",
    "content": "00000030\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu5/topology/package_cpus_list",
    "content": "4-5\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu5/topology/physical_package_id",
    "content": "2\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu5/topology/thread_siblings",
    "content": "00000030\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu5/topology/thread_siblings_list",
    "content": "4-5\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu6/topology/core_cpus",
    "content": "000000c0\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu6/topology/core_cpus_list",
    "content": "6-7\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu6/topology/core_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu6/topology/core_siblings",
    "content": "000000c0\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu6/topology/core_siblings_list",
    "content": "6-7\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu6/topology/die_cpus",
    "content": "000000c0\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu6/topology/die_cpus_list",
    "content": "6-7\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu6/topology/die_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu6/topology/package_cpus",
    "content": "000000c0\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu6/topology/package_cpus_list",
    "content": "6-7\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu6/topology/physical_package_id",
    "content": "3\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu6/topology/thread_siblings",
    "content": "000000c0\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu6/topology/thread_siblings_list",
    "content": "6-7\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu7/topology/core_cpus",
    "content": "000000c0\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu7/topology/core_cpus_list",
    "content": "6-7\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu7/topology/core_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu7/topology/core_siblings",
    "content": "000000c0\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu7/topology/core_siblings_list",
    "content": "6-7\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu7/topology/die_cpus",
    "content": "000000c0\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu7/topology/die_cpus_list",
    "content": "6-7\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu7/topology/die_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu7/topology/package_cpus",
    "content": "000000c0\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu7/topology/package_cpus_list",
    "content": "6-7\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu7/topology/physical_package_id",
    "content": "3\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu7/topology/thread_siblings",
    "content": "000000c0\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu7/topology/thread_siblings_list",
    "content": "6-7\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu8/topology/core_cpus",
    "content": "00000300\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu8/topology/core_cpus_list",
    "content": "8-9\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu8/topology/core_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu8/topology/core_siblings",
    "content": "00000300\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu8/topology/core_siblings_list",
    "content": "8-9\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu8/topology/die_cpus",
    "content": "00000300\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu8/topology/die_cpus_list",
    "content": "8-9\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu8/topology/die_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu8/topology/package_cpus",
    "content": "00000300\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu8/topology/package_cpus_list",
    "content": "8-9\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu8/topology/physical_package_id",
    "content": "4\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu8/topology/thread_siblings",
    "content": "00000300\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu8/topology/thread_siblings_list",
    "content": "8-9\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu9/topology/core_cpus",
    "content": "00000300\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu9/topology/core_cpus_list",
    "content": "8-9\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu9/topology/core_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu9/topology/core_siblings",
    "content": "00000300\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu9/topology/core_siblings_list",
    "content": "8-9\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu9/topology/die_cpus",
    "content": "00000300\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu9/topology/die_cpus_list",
    "content": "8-9\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu9/topology/die_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu9/topology/package_cpus",
    "content": "00000300\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu9/topology/package_cpus_list",
    "content": "8-9\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu9/topology/physical_package_id",
    "content": "4\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu9/topology/thread_siblings",
    "content": "00000300\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/cpu9/topology/thread_siblings_list",
    "content": "8-9\n"
  },
  {
    "path": "utils/sysfs/testdata_single_socket_many_NUMAs/online",
    "content": "0-31\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu0/topology/core_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu0/topology/core_siblings",
    "content": "00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,0000000f,ff000fff\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu0/topology/core_siblings_list",
    "content": "0-11,24-35\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu0/topology/physical_package_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu0/topology/thread_siblings",
    "content": "00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,01000001\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu0/topology/thread_siblings_list",
    "content": "0,24\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu1/topology/core_id",
    "content": "1\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu1/topology/core_siblings",
    "content": "00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,0000000f,ff000fff\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu1/topology/core_siblings_list",
    "content": "0-11,24-35\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu1/topology/physical_package_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu1/topology/thread_siblings",
    "content": "00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,02000002\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu1/topology/thread_siblings_list",
    "content": "1,25\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu10/topology/core_id",
    "content": "12\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu10/topology/core_siblings",
    "content": "00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,0000000f,ff000fff\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu10/topology/core_siblings_list",
    "content": "0-11,24-35\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu10/topology/physical_package_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu10/topology/thread_siblings",
    "content": "00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000004,00000400\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu10/topology/thread_siblings_list",
    "content": "10,34\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu11/topology/core_id",
    "content": "13\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu11/topology/core_siblings",
    "content": "00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,0000000f,ff000fff\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu11/topology/core_siblings_list",
    "content": "0-11,24-35\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu11/topology/physical_package_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu11/topology/thread_siblings",
    "content": "00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000008,00000800\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu11/topology/thread_siblings_list",
    "content": "11,35\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu12/topology/core_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu12/topology/core_siblings",
    "content": "00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,0000fff0,00fff000\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu12/topology/core_siblings_list",
    "content": "12-23,36-47\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu12/topology/physical_package_id",
    "content": "1\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu12/topology/thread_siblings",
    "content": "00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000010,00001000\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu12/topology/thread_siblings_list",
    "content": "12,36\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu13/topology/core_id",
    "content": "1\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu13/topology/core_siblings",
    "content": "00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,0000fff0,00fff000\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu13/topology/core_siblings_list",
    "content": "12-23,36-47\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu13/topology/physical_package_id",
    "content": "1\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu13/topology/thread_siblings",
    "content": "00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000020,00002000\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu13/topology/thread_siblings_list",
    "content": "13,37\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu14/topology/core_id",
    "content": "2\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu14/topology/core_siblings",
    "content": "00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,0000fff0,00fff000\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu14/topology/core_siblings_list",
    "content": "12-23,36-47\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu14/topology/physical_package_id",
    "content": "1\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu14/topology/thread_siblings",
    "content": "00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000040,00004000\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu14/topology/thread_siblings_list",
    "content": "14,38\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu15/topology/core_id",
    "content": "3\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu15/topology/core_siblings",
    "content": "00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,0000fff0,00fff000\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu15/topology/core_siblings_list",
    "content": "12-23,36-47\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu15/topology/physical_package_id",
    "content": "1\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu15/topology/thread_siblings",
    "content": "00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000080,00008000\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu15/topology/thread_siblings_list",
    "content": "15,39\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu16/topology/core_id",
    "content": "4\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu16/topology/core_siblings",
    "content": "00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,0000fff0,00fff000\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu16/topology/core_siblings_list",
    "content": "12-23,36-47\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu16/topology/physical_package_id",
    "content": "1\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu16/topology/thread_siblings",
    "content": "00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000100,00010000\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu16/topology/thread_siblings_list",
    "content": "16,40\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu17/topology/core_id",
    "content": "5\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu17/topology/core_siblings",
    "content": "00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,0000fff0,00fff000\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu17/topology/core_siblings_list",
    "content": "12-23,36-47\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu17/topology/physical_package_id",
    "content": "1\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu17/topology/thread_siblings",
    "content": "00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000200,00020000\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu17/topology/thread_siblings_list",
    "content": "17,41\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu18/topology/core_id",
    "content": "8\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu18/topology/core_siblings",
    "content": "00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,0000fff0,00fff000\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu18/topology/core_siblings_list",
    "content": "12-23,36-47\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu18/topology/physical_package_id",
    "content": "1\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu18/topology/thread_siblings",
    "content": "00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000400,00040000\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu18/topology/thread_siblings_list",
    "content": "18,42\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu19/topology/core_id",
    "content": "9\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu19/topology/core_siblings",
    "content": "00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,0000fff0,00fff000\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu19/topology/core_siblings_list",
    "content": "12-23,36-47\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu19/topology/physical_package_id",
    "content": "1\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu19/topology/thread_siblings",
    "content": "00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000800,00080000\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu19/topology/thread_siblings_list",
    "content": "19,43\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu2/topology/core_id",
    "content": "2\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu2/topology/core_siblings",
    "content": "00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,0000000f,ff000fff\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu2/topology/core_siblings_list",
    "content": "0-11,24-35\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu2/topology/physical_package_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu2/topology/thread_siblings",
    "content": "00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,04000004\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu2/topology/thread_siblings_list",
    "content": "2,26\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu20/topology/core_id",
    "content": "10\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu20/topology/core_siblings",
    "content": "00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,0000fff0,00fff000\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu20/topology/core_siblings_list",
    "content": "12-23,36-47\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu20/topology/physical_package_id",
    "content": "1\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu20/topology/thread_siblings",
    "content": "00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00001000,00100000\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu20/topology/thread_siblings_list",
    "content": "20,44\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu21/topology/core_id",
    "content": "11\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu21/topology/core_siblings",
    "content": "00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,0000fff0,00fff000\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu21/topology/core_siblings_list",
    "content": "12-23,36-47\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu21/topology/physical_package_id",
    "content": "1\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu21/topology/thread_siblings",
    "content": "00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00002000,00200000\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu21/topology/thread_siblings_list",
    "content": "21,45\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu22/topology/core_id",
    "content": "12\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu22/topology/core_siblings",
    "content": "00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,0000fff0,00fff000\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu22/topology/core_siblings_list",
    "content": "12-23,36-47\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu22/topology/physical_package_id",
    "content": "1\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu22/topology/thread_siblings",
    "content": "00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00004000,00400000\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu22/topology/thread_siblings_list",
    "content": "22,46\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu23/topology/core_id",
    "content": "13\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu23/topology/core_siblings",
    "content": "00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,0000fff0,00fff000\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu23/topology/core_siblings_list",
    "content": "12-23,36-47\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu23/topology/physical_package_id",
    "content": "1\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu23/topology/thread_siblings",
    "content": "00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00008000,00800000\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu23/topology/thread_siblings_list",
    "content": "23,47\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu24/topology/core_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu24/topology/core_siblings",
    "content": "00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,0000000f,ff000fff\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu24/topology/core_siblings_list",
    "content": "0-11,24-35\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu24/topology/physical_package_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu24/topology/thread_siblings",
    "content": "00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,01000001\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu24/topology/thread_siblings_list",
    "content": "0,24\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu25/topology/core_id",
    "content": "1\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu25/topology/core_siblings",
    "content": "00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,0000000f,ff000fff\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu25/topology/core_siblings_list",
    "content": "0-11,24-35\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu25/topology/physical_package_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu25/topology/thread_siblings",
    "content": "00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,02000002\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu25/topology/thread_siblings_list",
    "content": "1,25\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu26/topology/core_id",
    "content": "2\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu26/topology/core_siblings",
    "content": "00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,0000000f,ff000fff\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu26/topology/core_siblings_list",
    "content": "0-11,24-35\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu26/topology/physical_package_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu26/topology/thread_siblings",
    "content": "00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,04000004\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu26/topology/thread_siblings_list",
    "content": "2,26\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu27/topology/core_id",
    "content": "3\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu27/topology/core_siblings",
    "content": "00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,0000000f,ff000fff\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu27/topology/core_siblings_list",
    "content": "0-11,24-35\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu27/topology/physical_package_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu27/topology/thread_siblings",
    "content": "00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,08000008\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu27/topology/thread_siblings_list",
    "content": "3,27\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu28/topology/core_id",
    "content": "4\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu28/topology/core_siblings",
    "content": "00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,0000000f,ff000fff\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu28/topology/core_siblings_list",
    "content": "0-11,24-35\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu28/topology/physical_package_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu28/topology/thread_siblings",
    "content": "00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,10000010\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu28/topology/thread_siblings_list",
    "content": "4,28\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu29/topology/core_id",
    "content": "5\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu29/topology/core_siblings",
    "content": "00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,0000000f,ff000fff\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu29/topology/core_siblings_list",
    "content": "0-11,24-35\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu29/topology/physical_package_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu29/topology/thread_siblings",
    "content": "00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,20000020\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu29/topology/thread_siblings_list",
    "content": "5,29\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu3/topology/core_id",
    "content": "3\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu3/topology/core_siblings",
    "content": "00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,0000000f,ff000fff\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu3/topology/core_siblings_list",
    "content": "0-11,24-35\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu3/topology/physical_package_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu3/topology/thread_siblings",
    "content": "00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,08000008\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu3/topology/thread_siblings_list",
    "content": "3,27\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu30/topology/core_id",
    "content": "8\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu30/topology/core_siblings",
    "content": "00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,0000000f,ff000fff\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu30/topology/core_siblings_list",
    "content": "0-11,24-35\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu30/topology/physical_package_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu30/topology/thread_siblings",
    "content": "00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,40000040\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu30/topology/thread_siblings_list",
    "content": "6,30\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu31/topology/core_id",
    "content": "9\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu31/topology/core_siblings",
    "content": "00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,0000000f,ff000fff\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu31/topology/core_siblings_list",
    "content": "0-11,24-35\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu31/topology/physical_package_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu31/topology/thread_siblings",
    "content": "00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,80000080\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu31/topology/thread_siblings_list",
    "content": "7,31\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu32/topology/core_id",
    "content": "10\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu32/topology/core_siblings",
    "content": "00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,0000000f,ff000fff\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu32/topology/core_siblings_list",
    "content": "0-11,24-35\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu32/topology/physical_package_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu32/topology/thread_siblings",
    "content": "00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000001,00000100\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu32/topology/thread_siblings_list",
    "content": "8,32\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu33/topology/core_id",
    "content": "11\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu33/topology/core_siblings",
    "content": "00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,0000000f,ff000fff\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu33/topology/core_siblings_list",
    "content": "0-11,24-35\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu33/topology/physical_package_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu33/topology/thread_siblings",
    "content": "00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000002,00000200\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu33/topology/thread_siblings_list",
    "content": "9,33\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu34/topology/core_id",
    "content": "12\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu34/topology/core_siblings",
    "content": "00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,0000000f,ff000fff\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu34/topology/core_siblings_list",
    "content": "0-11,24-35\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu34/topology/physical_package_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu34/topology/thread_siblings",
    "content": "00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000004,00000400\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu34/topology/thread_siblings_list",
    "content": "10,34\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu35/topology/core_id",
    "content": "13\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu35/topology/core_siblings",
    "content": "00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,0000000f,ff000fff\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu35/topology/core_siblings_list",
    "content": "0-11,24-35\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu35/topology/physical_package_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu35/topology/thread_siblings",
    "content": "00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000008,00000800\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu35/topology/thread_siblings_list",
    "content": "11,35\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu36/topology/core_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu36/topology/core_siblings",
    "content": "00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,0000fff0,00fff000\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu36/topology/core_siblings_list",
    "content": "12-23,36-47\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu36/topology/physical_package_id",
    "content": "1\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu36/topology/thread_siblings",
    "content": "00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000010,00001000\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu36/topology/thread_siblings_list",
    "content": "12,36\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu37/topology/core_id",
    "content": "1\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu37/topology/core_siblings",
    "content": "00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,0000fff0,00fff000\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu37/topology/core_siblings_list",
    "content": "12-23,36-47\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu37/topology/physical_package_id",
    "content": "1\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu37/topology/thread_siblings",
    "content": "00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000020,00002000\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu37/topology/thread_siblings_list",
    "content": "13,37\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu38/topology/core_id",
    "content": "2\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu38/topology/core_siblings",
    "content": "00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,0000fff0,00fff000\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu38/topology/core_siblings_list",
    "content": "12-23,36-47\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu38/topology/physical_package_id",
    "content": "1\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu38/topology/thread_siblings",
    "content": "00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000040,00004000\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu38/topology/thread_siblings_list",
    "content": "14,38\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu39/topology/core_id",
    "content": "3\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu39/topology/core_siblings",
    "content": "00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,0000fff0,00fff000\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu39/topology/core_siblings_list",
    "content": "12-23,36-47\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu39/topology/physical_package_id",
    "content": "1\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu39/topology/thread_siblings",
    "content": "00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000080,00008000\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu39/topology/thread_siblings_list",
    "content": "15,39\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu4/topology/core_id",
    "content": "4\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu4/topology/core_siblings",
    "content": "00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,0000000f,ff000fff\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu4/topology/core_siblings_list",
    "content": "0-11,24-35\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu4/topology/physical_package_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu4/topology/thread_siblings",
    "content": "00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,10000010\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu4/topology/thread_siblings_list",
    "content": "4,28\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu40/topology/core_id",
    "content": "4\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu40/topology/core_siblings",
    "content": "00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,0000fff0,00fff000\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu40/topology/core_siblings_list",
    "content": "12-23,36-47\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu40/topology/physical_package_id",
    "content": "1\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu40/topology/thread_siblings",
    "content": "00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000100,00010000\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu40/topology/thread_siblings_list",
    "content": "16,40\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu41/topology/core_id",
    "content": "5\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu41/topology/core_siblings",
    "content": "00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,0000fff0,00fff000\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu41/topology/core_siblings_list",
    "content": "12-23,36-47\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu41/topology/physical_package_id",
    "content": "1\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu41/topology/thread_siblings",
    "content": "00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000200,00020000\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu41/topology/thread_siblings_list",
    "content": "17,41\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu42/topology/core_id",
    "content": "8\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu42/topology/core_siblings",
    "content": "00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,0000fff0,00fff000\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu42/topology/core_siblings_list",
    "content": "12-23,36-47\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu42/topology/physical_package_id",
    "content": "1\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu42/topology/thread_siblings",
    "content": "00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000400,00040000\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu42/topology/thread_siblings_list",
    "content": "18,42\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu43/topology/core_id",
    "content": "9\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu43/topology/core_siblings",
    "content": "00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,0000fff0,00fff000\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu43/topology/core_siblings_list",
    "content": "12-23,36-47\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu43/topology/physical_package_id",
    "content": "1\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu43/topology/thread_siblings",
    "content": "00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000800,00080000\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu43/topology/thread_siblings_list",
    "content": "19,43\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu44/topology/core_id",
    "content": "10\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu44/topology/core_siblings",
    "content": "00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,0000fff0,00fff000\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu44/topology/core_siblings_list",
    "content": "12-23,36-47\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu44/topology/physical_package_id",
    "content": "1\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu44/topology/thread_siblings",
    "content": "00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00001000,00100000\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu44/topology/thread_siblings_list",
    "content": "20,44\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu45/topology/core_id",
    "content": "11\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu45/topology/core_siblings",
    "content": "00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,0000fff0,00fff000\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu45/topology/core_siblings_list",
    "content": "12-23,36-47\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu45/topology/physical_package_id",
    "content": "1\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu45/topology/thread_siblings",
    "content": "00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00002000,00200000\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu45/topology/thread_siblings_list",
    "content": "21,45\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu46/topology/core_id",
    "content": "12\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu46/topology/core_siblings",
    "content": "00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,0000fff0,00fff000\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu46/topology/core_siblings_list",
    "content": "12-23,36-47\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu46/topology/physical_package_id",
    "content": "1\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu46/topology/thread_siblings",
    "content": "00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00004000,00400000\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu46/topology/thread_siblings_list",
    "content": "22,46\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu47/topology/core_id",
    "content": "13\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu47/topology/core_siblings",
    "content": "00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,0000fff0,00fff000\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu47/topology/core_siblings_list",
    "content": "12-23,36-47\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu47/topology/physical_package_id",
    "content": "1\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu47/topology/thread_siblings",
    "content": "00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00008000,00800000\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu47/topology/thread_siblings_list",
    "content": "23,47\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu5/topology/core_id",
    "content": "5\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu5/topology/core_siblings",
    "content": "00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,0000000f,ff000fff\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu5/topology/core_siblings_list",
    "content": "0-11,24-35\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu5/topology/physical_package_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu5/topology/thread_siblings",
    "content": "00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,20000020\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu5/topology/thread_siblings_list",
    "content": "5,29\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu6/topology/core_id",
    "content": "8\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu6/topology/core_siblings",
    "content": "00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,0000000f,ff000fff\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu6/topology/core_siblings_list",
    "content": "0-11,24-35\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu6/topology/physical_package_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu6/topology/thread_siblings",
    "content": "00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,40000040\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu6/topology/thread_siblings_list",
    "content": "6,30\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu7/topology/core_id",
    "content": "9\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu7/topology/core_siblings",
    "content": "00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,0000000f,ff000fff\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu7/topology/core_siblings_list",
    "content": "0-11,24-35\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu7/topology/physical_package_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu7/topology/thread_siblings",
    "content": "00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,80000080\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu7/topology/thread_siblings_list",
    "content": "7,31\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu8/topology/core_id",
    "content": "10\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu8/topology/core_siblings",
    "content": "00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,0000000f,ff000fff\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu8/topology/core_siblings_list",
    "content": "0-11,24-35\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu8/topology/physical_package_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu8/topology/thread_siblings",
    "content": "00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000001,00000100\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu8/topology/thread_siblings_list",
    "content": "8,32\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu9/topology/core_id",
    "content": "11\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu9/topology/core_siblings",
    "content": "00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,0000000f,ff000fff\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu9/topology/core_siblings_list",
    "content": "0-11,24-35\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu9/topology/physical_package_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu9/topology/thread_siblings",
    "content": "00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000002,00000200\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/cpu9/topology/thread_siblings_list",
    "content": "9,33\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon4214_2socket/online",
    "content": "0-47"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu0/topology/core_cpus",
    "content": "00000001\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu0/topology/core_cpus_list",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu0/topology/core_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu0/topology/core_siblings",
    "content": "55555555\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu0/topology/core_siblings_list",
    "content": "0,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu0/topology/die_cpus",
    "content": "55555555\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu0/topology/die_cpus_list",
    "content": "0,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu0/topology/die_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu0/topology/package_cpus",
    "content": "55555555\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu0/topology/package_cpus_list",
    "content": "0,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu0/topology/physical_package_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu0/topology/thread_siblings",
    "content": "00000001\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu0/topology/thread_siblings_list",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu1/topology/core_cpus",
    "content": "00000002\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu1/topology/core_cpus_list",
    "content": "1\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu1/topology/core_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu1/topology/core_siblings",
    "content": "aaaaaaaa\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu1/topology/core_siblings_list",
    "content": "1,3,5,7,9,11,13,15,17,19,21,23,25,27,29,31\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu1/topology/die_cpus",
    "content": "aaaaaaaa\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu1/topology/die_cpus_list",
    "content": "1,3,5,7,9,11,13,15,17,19,21,23,25,27,29,31\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu1/topology/die_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu1/topology/package_cpus",
    "content": "aaaaaaaa\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu1/topology/package_cpus_list",
    "content": "1,3,5,7,9,11,13,15,17,19,21,23,25,27,29,31\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu1/topology/physical_package_id",
    "content": "1\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu1/topology/thread_siblings",
    "content": "00000002\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu1/topology/thread_siblings_list",
    "content": "1\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu10/topology/core_cpus",
    "content": "00000400\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu10/topology/core_cpus_list",
    "content": "10\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu10/topology/core_id",
    "content": "5\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu10/topology/core_siblings",
    "content": "55555555\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu10/topology/core_siblings_list",
    "content": "0,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu10/topology/die_cpus",
    "content": "55555555\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu10/topology/die_cpus_list",
    "content": "0,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu10/topology/die_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu10/topology/package_cpus",
    "content": "55555555\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu10/topology/package_cpus_list",
    "content": "0,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu10/topology/physical_package_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu10/topology/thread_siblings",
    "content": "00000400\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu10/topology/thread_siblings_list",
    "content": "10\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu11/topology/core_cpus",
    "content": "00000800\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu11/topology/core_cpus_list",
    "content": "11\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu11/topology/core_id",
    "content": "5\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu11/topology/core_siblings",
    "content": "aaaaaaaa\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu11/topology/core_siblings_list",
    "content": "1,3,5,7,9,11,13,15,17,19,21,23,25,27,29,31\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu11/topology/die_cpus",
    "content": "aaaaaaaa\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu11/topology/die_cpus_list",
    "content": "1,3,5,7,9,11,13,15,17,19,21,23,25,27,29,31\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu11/topology/die_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu11/topology/package_cpus",
    "content": "aaaaaaaa\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu11/topology/package_cpus_list",
    "content": "1,3,5,7,9,11,13,15,17,19,21,23,25,27,29,31\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu11/topology/physical_package_id",
    "content": "1\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu11/topology/thread_siblings",
    "content": "00000800\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu11/topology/thread_siblings_list",
    "content": "11\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu12/topology/core_cpus",
    "content": "00001000\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu12/topology/core_cpus_list",
    "content": "12\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu12/topology/core_id",
    "content": "3\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu12/topology/core_siblings",
    "content": "55555555\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu12/topology/core_siblings_list",
    "content": "0,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu12/topology/die_cpus",
    "content": "55555555\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu12/topology/die_cpus_list",
    "content": "0,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu12/topology/die_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu12/topology/package_cpus",
    "content": "55555555\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu12/topology/package_cpus_list",
    "content": "0,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu12/topology/physical_package_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu12/topology/thread_siblings",
    "content": "00001000\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu12/topology/thread_siblings_list",
    "content": "12\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu13/topology/core_cpus",
    "content": "00002000\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu13/topology/core_cpus_list",
    "content": "13\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu13/topology/core_id",
    "content": "3\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu13/topology/core_siblings",
    "content": "aaaaaaaa\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu13/topology/core_siblings_list",
    "content": "1,3,5,7,9,11,13,15,17,19,21,23,25,27,29,31\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu13/topology/die_cpus",
    "content": "aaaaaaaa\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu13/topology/die_cpus_list",
    "content": "1,3,5,7,9,11,13,15,17,19,21,23,25,27,29,31\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu13/topology/die_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu13/topology/package_cpus",
    "content": "aaaaaaaa\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu13/topology/package_cpus_list",
    "content": "1,3,5,7,9,11,13,15,17,19,21,23,25,27,29,31\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu13/topology/physical_package_id",
    "content": "1\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu13/topology/thread_siblings",
    "content": "00002000\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu13/topology/thread_siblings_list",
    "content": "13\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu14/topology/core_cpus",
    "content": "00004000\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu14/topology/core_cpus_list",
    "content": "14\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu14/topology/core_id",
    "content": "4\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu14/topology/core_siblings",
    "content": "55555555\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu14/topology/core_siblings_list",
    "content": "0,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu14/topology/die_cpus",
    "content": "55555555\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu14/topology/die_cpus_list",
    "content": "0,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu14/topology/die_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu14/topology/package_cpus",
    "content": "55555555\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu14/topology/package_cpus_list",
    "content": "0,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu14/topology/physical_package_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu14/topology/thread_siblings",
    "content": "00004000\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu14/topology/thread_siblings_list",
    "content": "14\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu15/topology/core_cpus",
    "content": "00008000\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu15/topology/core_cpus_list",
    "content": "15\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu15/topology/core_id",
    "content": "4\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu15/topology/core_siblings",
    "content": "aaaaaaaa\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu15/topology/core_siblings_list",
    "content": "1,3,5,7,9,11,13,15,17,19,21,23,25,27,29,31\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu15/topology/die_cpus",
    "content": "aaaaaaaa\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu15/topology/die_cpus_list",
    "content": "1,3,5,7,9,11,13,15,17,19,21,23,25,27,29,31\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu15/topology/die_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu15/topology/package_cpus",
    "content": "aaaaaaaa\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu15/topology/package_cpus_list",
    "content": "1,3,5,7,9,11,13,15,17,19,21,23,25,27,29,31\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu15/topology/physical_package_id",
    "content": "1\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu15/topology/thread_siblings",
    "content": "00008000\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu15/topology/thread_siblings_list",
    "content": "15\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu16/topology/core_cpus",
    "content": "00010000\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu16/topology/core_cpus_list",
    "content": "16\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu16/topology/core_id",
    "content": "8\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu16/topology/core_siblings",
    "content": "55555555\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu16/topology/core_siblings_list",
    "content": "0,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu16/topology/die_cpus",
    "content": "55555555\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu16/topology/die_cpus_list",
    "content": "0,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu16/topology/die_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu16/topology/package_cpus",
    "content": "55555555\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu16/topology/package_cpus_list",
    "content": "0,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu16/topology/physical_package_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu16/topology/thread_siblings",
    "content": "00010000\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu16/topology/thread_siblings_list",
    "content": "16\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu17/topology/core_cpus",
    "content": "00020000\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu17/topology/core_cpus_list",
    "content": "17\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu17/topology/core_id",
    "content": "8\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu17/topology/core_siblings",
    "content": "aaaaaaaa\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu17/topology/core_siblings_list",
    "content": "1,3,5,7,9,11,13,15,17,19,21,23,25,27,29,31\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu17/topology/die_cpus",
    "content": "aaaaaaaa\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu17/topology/die_cpus_list",
    "content": "1,3,5,7,9,11,13,15,17,19,21,23,25,27,29,31\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu17/topology/die_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu17/topology/package_cpus",
    "content": "aaaaaaaa\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu17/topology/package_cpus_list",
    "content": "1,3,5,7,9,11,13,15,17,19,21,23,25,27,29,31\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu17/topology/physical_package_id",
    "content": "1\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu17/topology/thread_siblings",
    "content": "00020000\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu17/topology/thread_siblings_list",
    "content": "17\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu18/topology/core_cpus",
    "content": "00040000\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu18/topology/core_cpus_list",
    "content": "18\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu18/topology/core_id",
    "content": "15\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu18/topology/core_siblings",
    "content": "55555555\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu18/topology/core_siblings_list",
    "content": "0,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu18/topology/die_cpus",
    "content": "55555555\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu18/topology/die_cpus_list",
    "content": "0,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu18/topology/die_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu18/topology/package_cpus",
    "content": "55555555\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu18/topology/package_cpus_list",
    "content": "0,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu18/topology/physical_package_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu18/topology/thread_siblings",
    "content": "00040000\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu18/topology/thread_siblings_list",
    "content": "18\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu19/topology/core_cpus",
    "content": "00080000\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu19/topology/core_cpus_list",
    "content": "19\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu19/topology/core_id",
    "content": "15\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu19/topology/core_siblings",
    "content": "aaaaaaaa\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu19/topology/core_siblings_list",
    "content": "1,3,5,7,9,11,13,15,17,19,21,23,25,27,29,31\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu19/topology/die_cpus",
    "content": "aaaaaaaa\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu19/topology/die_cpus_list",
    "content": "1,3,5,7,9,11,13,15,17,19,21,23,25,27,29,31\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu19/topology/die_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu19/topology/package_cpus",
    "content": "aaaaaaaa\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu19/topology/package_cpus_list",
    "content": "1,3,5,7,9,11,13,15,17,19,21,23,25,27,29,31\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu19/topology/physical_package_id",
    "content": "1\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu19/topology/thread_siblings",
    "content": "00080000\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu19/topology/thread_siblings_list",
    "content": "19\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu2/topology/core_cpus",
    "content": "00000004\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu2/topology/core_cpus_list",
    "content": "2\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu2/topology/core_id",
    "content": "7\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu2/topology/core_siblings",
    "content": "55555555\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu2/topology/core_siblings_list",
    "content": "0,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu2/topology/die_cpus",
    "content": "55555555\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu2/topology/die_cpus_list",
    "content": "0,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu2/topology/die_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu2/topology/package_cpus",
    "content": "55555555\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu2/topology/package_cpus_list",
    "content": "0,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu2/topology/physical_package_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu2/topology/thread_siblings",
    "content": "00000004\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu2/topology/thread_siblings_list",
    "content": "2\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu20/topology/core_cpus",
    "content": "00100000\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu20/topology/core_cpus_list",
    "content": "20\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu20/topology/core_id",
    "content": "9\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu20/topology/core_siblings",
    "content": "55555555\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu20/topology/core_siblings_list",
    "content": "0,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu20/topology/die_cpus",
    "content": "55555555\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu20/topology/die_cpus_list",
    "content": "0,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu20/topology/die_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu20/topology/package_cpus",
    "content": "55555555\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu20/topology/package_cpus_list",
    "content": "0,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu20/topology/physical_package_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu20/topology/thread_siblings",
    "content": "00100000\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu20/topology/thread_siblings_list",
    "content": "20\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu21/topology/core_cpus",
    "content": "00200000\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu21/topology/core_cpus_list",
    "content": "21\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu21/topology/core_id",
    "content": "9\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu21/topology/core_siblings",
    "content": "aaaaaaaa\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu21/topology/core_siblings_list",
    "content": "1,3,5,7,9,11,13,15,17,19,21,23,25,27,29,31\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu21/topology/die_cpus",
    "content": "aaaaaaaa\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu21/topology/die_cpus_list",
    "content": "1,3,5,7,9,11,13,15,17,19,21,23,25,27,29,31\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu21/topology/die_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu21/topology/package_cpus",
    "content": "aaaaaaaa\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu21/topology/package_cpus_list",
    "content": "1,3,5,7,9,11,13,15,17,19,21,23,25,27,29,31\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu21/topology/physical_package_id",
    "content": "1\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu21/topology/thread_siblings",
    "content": "00200000\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu21/topology/thread_siblings_list",
    "content": "21\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu22/topology/core_cpus",
    "content": "00400000\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu22/topology/core_cpus_list",
    "content": "22\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu22/topology/core_id",
    "content": "14\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu22/topology/core_siblings",
    "content": "55555555\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu22/topology/core_siblings_list",
    "content": "0,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu22/topology/die_cpus",
    "content": "55555555\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu22/topology/die_cpus_list",
    "content": "0,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu22/topology/die_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu22/topology/package_cpus",
    "content": "55555555\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu22/topology/package_cpus_list",
    "content": "0,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu22/topology/physical_package_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu22/topology/thread_siblings",
    "content": "00400000\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu22/topology/thread_siblings_list",
    "content": "22\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu23/topology/core_cpus",
    "content": "00800000\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu23/topology/core_cpus_list",
    "content": "23\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu23/topology/core_id",
    "content": "14\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu23/topology/core_siblings",
    "content": "aaaaaaaa\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu23/topology/core_siblings_list",
    "content": "1,3,5,7,9,11,13,15,17,19,21,23,25,27,29,31\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu23/topology/die_cpus",
    "content": "aaaaaaaa\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu23/topology/die_cpus_list",
    "content": "1,3,5,7,9,11,13,15,17,19,21,23,25,27,29,31\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu23/topology/die_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu23/topology/package_cpus",
    "content": "aaaaaaaa\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu23/topology/package_cpus_list",
    "content": "1,3,5,7,9,11,13,15,17,19,21,23,25,27,29,31\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu23/topology/physical_package_id",
    "content": "1\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu23/topology/thread_siblings",
    "content": "00800000\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu23/topology/thread_siblings_list",
    "content": "23\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu24/topology/core_cpus",
    "content": "01000000\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu24/topology/core_cpus_list",
    "content": "24\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu24/topology/core_id",
    "content": "10\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu24/topology/core_siblings",
    "content": "55555555\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu24/topology/core_siblings_list",
    "content": "0,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu24/topology/die_cpus",
    "content": "55555555\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu24/topology/die_cpus_list",
    "content": "0,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu24/topology/die_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu24/topology/package_cpus",
    "content": "55555555\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu24/topology/package_cpus_list",
    "content": "0,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu24/topology/physical_package_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu24/topology/thread_siblings",
    "content": "01000000\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu24/topology/thread_siblings_list",
    "content": "24\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu25/topology/core_cpus",
    "content": "02000000\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu25/topology/core_cpus_list",
    "content": "25\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu25/topology/core_id",
    "content": "10\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu25/topology/core_siblings",
    "content": "aaaaaaaa\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu25/topology/core_siblings_list",
    "content": "1,3,5,7,9,11,13,15,17,19,21,23,25,27,29,31\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu25/topology/die_cpus",
    "content": "aaaaaaaa\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu25/topology/die_cpus_list",
    "content": "1,3,5,7,9,11,13,15,17,19,21,23,25,27,29,31\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu25/topology/die_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu25/topology/package_cpus",
    "content": "aaaaaaaa\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu25/topology/package_cpus_list",
    "content": "1,3,5,7,9,11,13,15,17,19,21,23,25,27,29,31\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu25/topology/physical_package_id",
    "content": "1\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu25/topology/thread_siblings",
    "content": "02000000\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu25/topology/thread_siblings_list",
    "content": "25\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu26/topology/core_cpus",
    "content": "04000000\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu26/topology/core_cpus_list",
    "content": "26\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu26/topology/core_id",
    "content": "13\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu26/topology/core_siblings",
    "content": "55555555\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu26/topology/core_siblings_list",
    "content": "0,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu26/topology/die_cpus",
    "content": "55555555\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu26/topology/die_cpus_list",
    "content": "0,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu26/topology/die_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu26/topology/package_cpus",
    "content": "55555555\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu26/topology/package_cpus_list",
    "content": "0,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu26/topology/physical_package_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu26/topology/thread_siblings",
    "content": "04000000\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu26/topology/thread_siblings_list",
    "content": "26\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu27/topology/core_cpus",
    "content": "08000000\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu27/topology/core_cpus_list",
    "content": "27\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu27/topology/core_id",
    "content": "13\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu27/topology/core_siblings",
    "content": "aaaaaaaa\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu27/topology/core_siblings_list",
    "content": "1,3,5,7,9,11,13,15,17,19,21,23,25,27,29,31\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu27/topology/die_cpus",
    "content": "aaaaaaaa\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu27/topology/die_cpus_list",
    "content": "1,3,5,7,9,11,13,15,17,19,21,23,25,27,29,31\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu27/topology/die_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu27/topology/package_cpus",
    "content": "aaaaaaaa\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu27/topology/package_cpus_list",
    "content": "1,3,5,7,9,11,13,15,17,19,21,23,25,27,29,31\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu27/topology/physical_package_id",
    "content": "1\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu27/topology/thread_siblings",
    "content": "08000000\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu27/topology/thread_siblings_list",
    "content": "27\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu28/topology/core_cpus",
    "content": "10000000\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu28/topology/core_cpus_list",
    "content": "28\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu28/topology/core_id",
    "content": "11\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu28/topology/core_siblings",
    "content": "55555555\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu28/topology/core_siblings_list",
    "content": "0,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu28/topology/die_cpus",
    "content": "55555555\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu28/topology/die_cpus_list",
    "content": "0,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu28/topology/die_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu28/topology/package_cpus",
    "content": "55555555\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu28/topology/package_cpus_list",
    "content": "0,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu28/topology/physical_package_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu28/topology/thread_siblings",
    "content": "10000000\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu28/topology/thread_siblings_list",
    "content": "28\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu29/topology/core_cpus",
    "content": "20000000\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu29/topology/core_cpus_list",
    "content": "29\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu29/topology/core_id",
    "content": "11\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu29/topology/core_siblings",
    "content": "aaaaaaaa\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu29/topology/core_siblings_list",
    "content": "1,3,5,7,9,11,13,15,17,19,21,23,25,27,29,31\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu29/topology/die_cpus",
    "content": "aaaaaaaa\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu29/topology/die_cpus_list",
    "content": "1,3,5,7,9,11,13,15,17,19,21,23,25,27,29,31\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu29/topology/die_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu29/topology/package_cpus",
    "content": "aaaaaaaa\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu29/topology/package_cpus_list",
    "content": "1,3,5,7,9,11,13,15,17,19,21,23,25,27,29,31\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu29/topology/physical_package_id",
    "content": "1\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu29/topology/thread_siblings",
    "content": "20000000\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu29/topology/thread_siblings_list",
    "content": "29\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu3/topology/core_cpus",
    "content": "00000008\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu3/topology/core_cpus_list",
    "content": "3\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu3/topology/core_id",
    "content": "7\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu3/topology/core_siblings",
    "content": "aaaaaaaa\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu3/topology/core_siblings_list",
    "content": "1,3,5,7,9,11,13,15,17,19,21,23,25,27,29,31\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu3/topology/die_cpus",
    "content": "aaaaaaaa\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu3/topology/die_cpus_list",
    "content": "1,3,5,7,9,11,13,15,17,19,21,23,25,27,29,31\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu3/topology/die_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu3/topology/package_cpus",
    "content": "aaaaaaaa\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu3/topology/package_cpus_list",
    "content": "1,3,5,7,9,11,13,15,17,19,21,23,25,27,29,31\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu3/topology/physical_package_id",
    "content": "1\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu3/topology/thread_siblings",
    "content": "00000008\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu3/topology/thread_siblings_list",
    "content": "3\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu30/topology/core_cpus",
    "content": "40000000\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu30/topology/core_cpus_list",
    "content": "30\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu30/topology/core_id",
    "content": "12\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu30/topology/core_siblings",
    "content": "55555555\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu30/topology/core_siblings_list",
    "content": "0,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu30/topology/die_cpus",
    "content": "55555555\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu30/topology/die_cpus_list",
    "content": "0,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu30/topology/die_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu30/topology/package_cpus",
    "content": "55555555\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu30/topology/package_cpus_list",
    "content": "0,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu30/topology/physical_package_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu30/topology/thread_siblings",
    "content": "40000000\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu30/topology/thread_siblings_list",
    "content": "30\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu31/topology/core_cpus",
    "content": "80000000\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu31/topology/core_cpus_list",
    "content": "31\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu31/topology/core_id",
    "content": "12\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu31/topology/core_siblings",
    "content": "aaaaaaaa\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu31/topology/core_siblings_list",
    "content": "1,3,5,7,9,11,13,15,17,19,21,23,25,27,29,31\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu31/topology/die_cpus",
    "content": "aaaaaaaa\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu31/topology/die_cpus_list",
    "content": "1,3,5,7,9,11,13,15,17,19,21,23,25,27,29,31\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu31/topology/die_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu31/topology/package_cpus",
    "content": "aaaaaaaa\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu31/topology/package_cpus_list",
    "content": "1,3,5,7,9,11,13,15,17,19,21,23,25,27,29,31\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu31/topology/physical_package_id",
    "content": "1\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu31/topology/thread_siblings",
    "content": "80000000\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu31/topology/thread_siblings_list",
    "content": "31\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu4/topology/core_cpus",
    "content": "00000010\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu4/topology/core_cpus_list",
    "content": "4\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu4/topology/core_id",
    "content": "1\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu4/topology/core_siblings",
    "content": "55555555\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu4/topology/core_siblings_list",
    "content": "0,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu4/topology/die_cpus",
    "content": "55555555\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu4/topology/die_cpus_list",
    "content": "0,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu4/topology/die_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu4/topology/package_cpus",
    "content": "55555555\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu4/topology/package_cpus_list",
    "content": "0,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu4/topology/physical_package_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu4/topology/thread_siblings",
    "content": "00000010\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu4/topology/thread_siblings_list",
    "content": "4\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu5/topology/core_cpus",
    "content": "00000020\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu5/topology/core_cpus_list",
    "content": "5\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu5/topology/core_id",
    "content": "1\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu5/topology/core_siblings",
    "content": "aaaaaaaa\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu5/topology/core_siblings_list",
    "content": "1,3,5,7,9,11,13,15,17,19,21,23,25,27,29,31\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu5/topology/die_cpus",
    "content": "aaaaaaaa\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu5/topology/die_cpus_list",
    "content": "1,3,5,7,9,11,13,15,17,19,21,23,25,27,29,31\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu5/topology/die_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu5/topology/package_cpus",
    "content": "aaaaaaaa\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu5/topology/package_cpus_list",
    "content": "1,3,5,7,9,11,13,15,17,19,21,23,25,27,29,31\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu5/topology/physical_package_id",
    "content": "1\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu5/topology/thread_siblings",
    "content": "00000020\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu5/topology/thread_siblings_list",
    "content": "5\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu6/topology/core_cpus",
    "content": "00000040\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu6/topology/core_cpus_list",
    "content": "6\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu6/topology/core_id",
    "content": "6\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu6/topology/core_siblings",
    "content": "55555555\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu6/topology/core_siblings_list",
    "content": "0,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu6/topology/die_cpus",
    "content": "55555555\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu6/topology/die_cpus_list",
    "content": "0,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu6/topology/die_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu6/topology/package_cpus",
    "content": "55555555\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu6/topology/package_cpus_list",
    "content": "0,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu6/topology/physical_package_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu6/topology/thread_siblings",
    "content": "00000040\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu6/topology/thread_siblings_list",
    "content": "6\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu7/topology/core_cpus",
    "content": "00000080\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu7/topology/core_cpus_list",
    "content": "7\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu7/topology/core_id",
    "content": "6\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu7/topology/core_siblings",
    "content": "aaaaaaaa\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu7/topology/core_siblings_list",
    "content": "1,3,5,7,9,11,13,15,17,19,21,23,25,27,29,31\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu7/topology/die_cpus",
    "content": "aaaaaaaa\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu7/topology/die_cpus_list",
    "content": "1,3,5,7,9,11,13,15,17,19,21,23,25,27,29,31\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu7/topology/die_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu7/topology/package_cpus",
    "content": "aaaaaaaa\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu7/topology/package_cpus_list",
    "content": "1,3,5,7,9,11,13,15,17,19,21,23,25,27,29,31\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu7/topology/physical_package_id",
    "content": "1\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu7/topology/thread_siblings",
    "content": "00000080\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu7/topology/thread_siblings_list",
    "content": "7\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu8/topology/core_cpus",
    "content": "00000100\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu8/topology/core_cpus_list",
    "content": "8\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu8/topology/core_id",
    "content": "2\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu8/topology/core_siblings",
    "content": "55555555\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu8/topology/core_siblings_list",
    "content": "0,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu8/topology/die_cpus",
    "content": "55555555\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu8/topology/die_cpus_list",
    "content": "0,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu8/topology/die_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu8/topology/package_cpus",
    "content": "55555555\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu8/topology/package_cpus_list",
    "content": "0,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu8/topology/physical_package_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu8/topology/thread_siblings",
    "content": "00000100\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu8/topology/thread_siblings_list",
    "content": "8\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu9/topology/core_cpus",
    "content": "00000200\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu9/topology/core_cpus_list",
    "content": "9\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu9/topology/core_id",
    "content": "2\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu9/topology/core_siblings",
    "content": "aaaaaaaa\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu9/topology/core_siblings_list",
    "content": "1,3,5,7,9,11,13,15,17,19,21,23,25,27,29,31\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu9/topology/die_cpus",
    "content": "aaaaaaaa\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu9/topology/die_cpus_list",
    "content": "1,3,5,7,9,11,13,15,17,19,21,23,25,27,29,31\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu9/topology/die_id",
    "content": "0\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu9/topology/package_cpus",
    "content": "aaaaaaaa\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu9/topology/package_cpus_list",
    "content": "1,3,5,7,9,11,13,15,17,19,21,23,25,27,29,31\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu9/topology/physical_package_id",
    "content": "1\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu9/topology/thread_siblings",
    "content": "00000200\n"
  },
  {
    "path": "utils/sysfs/testdata_xeon5218_nohyperthread_2socket_nohotplug/cpu9/topology/thread_siblings_list",
    "content": "9\n"
  },
  {
    "path": "utils/sysinfo/sysinfo.go",
    "content": "// Copyright 2014 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage sysinfo\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\t\"regexp\"\n\t\"runtime\"\n\t\"strconv\"\n\t\"strings\"\n\n\tinfo \"github.com/google/cadvisor/info/v1\"\n\t\"github.com/google/cadvisor/utils/sysfs\"\n\n\t\"k8s.io/klog/v2\"\n)\n\nvar (\n\tschedulerRegExp      = regexp.MustCompile(`.*\\[(.*)\\].*`)\n\tnodeDirRegExp        = regexp.MustCompile(`node/node(\\d*)`)\n\tcpuDirRegExp         = regexp.MustCompile(`/cpu(\\d+)`)\n\tmemoryCapacityRegexp = regexp.MustCompile(`MemTotal:\\s*([0-9]+) kB`)\n\n\tcpusPath = \"/sys/devices/system/cpu\"\n)\n\nconst (\n\tcacheLevel2  = 2\n\thugepagesDir = \"hugepages/\"\n)\n\n// Get information about block devices present on the system.\n// Uses the passed in system interface to retrieve the low level OS information.\nfunc GetBlockDeviceInfo(sysfs sysfs.SysFs) (map[string]info.DiskInfo, error) {\n\tdisks, err := sysfs.GetBlockDevices()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tdiskMap := make(map[string]info.DiskInfo)\n\tfor _, disk := range disks {\n\t\tname := disk.Name()\n\t\t// Ignore non-disk devices.\n\t\t// TODO(rjnagal): Maybe just match hd, sd, and dm prefixes.\n\t\tif strings.HasPrefix(name, \"loop\") || strings.HasPrefix(name, \"ram\") || strings.HasPrefix(name, \"sr\") {\n\t\t\tcontinue\n\t\t}\n\t\t// Ignore \"hidden\" devices (i.e. nvme path device sysfs entries).\n\t\t// These devices are in the form of /dev/nvme$Xc$Yn$Z and will\n\t\t// not have a device handle (i.e. \"hidden\")\n\t\tisHidden, err := sysfs.IsBlockDeviceHidden(name)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tif isHidden {\n\t\t\tcontinue\n\t\t}\n\t\tdiskInfo := info.DiskInfo{\n\t\t\tName: name,\n\t\t}\n\t\tdev, err := sysfs.GetBlockDeviceNumbers(name)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tn, err := fmt.Sscanf(dev, \"%d:%d\", &diskInfo.Major, &diskInfo.Minor)\n\t\tif err != nil || n != 2 {\n\t\t\treturn nil, fmt.Errorf(\"could not parse device numbers from %s for device %s\", dev, name)\n\t\t}\n\t\tout, err := sysfs.GetBlockDeviceSize(name)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\t// Remove trailing newline before conversion.\n\t\tsize, err := strconv.ParseUint(strings.TrimSpace(out), 10, 64)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\t// size is in 512 bytes blocks.\n\t\tdiskInfo.Size = size * 512\n\n\t\tdiskInfo.Scheduler = \"none\"\n\t\tblkSched, err := sysfs.GetBlockDeviceScheduler(name)\n\t\tif err == nil {\n\t\t\tmatches := schedulerRegExp.FindSubmatch([]byte(blkSched))\n\t\t\tif len(matches) >= 2 {\n\t\t\t\tdiskInfo.Scheduler = string(matches[1])\n\t\t\t}\n\t\t}\n\t\tdevice := fmt.Sprintf(\"%d:%d\", diskInfo.Major, diskInfo.Minor)\n\t\tdiskMap[device] = diskInfo\n\t}\n\treturn diskMap, nil\n}\n\n// Get information about network devices present on the system.\nfunc GetNetworkDevices(sysfs sysfs.SysFs) ([]info.NetInfo, error) {\n\tdevs, err := sysfs.GetNetworkDevices()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tnetDevices := []info.NetInfo{}\n\tfor _, dev := range devs {\n\t\tname := dev.Name()\n\t\t// Ignore docker, loopback, and veth devices.\n\t\tignoredDevices := []string{\"lo\", \"veth\", \"docker\", \"nerdctl\"}\n\t\tignored := false\n\t\tfor _, prefix := range ignoredDevices {\n\t\t\tif strings.HasPrefix(name, prefix) {\n\t\t\t\tignored = true\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t\tif ignored {\n\t\t\tcontinue\n\t\t}\n\t\taddress, err := sysfs.GetNetworkAddress(name)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tmtuStr, err := sysfs.GetNetworkMtu(name)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tvar mtu int64\n\t\tn, err := fmt.Sscanf(mtuStr, \"%d\", &mtu)\n\t\tif err != nil || n != 1 {\n\t\t\treturn nil, fmt.Errorf(\"could not parse mtu from %s for device %s\", mtuStr, name)\n\t\t}\n\t\tnetInfo := info.NetInfo{\n\t\t\tName:       name,\n\t\t\tMacAddress: strings.TrimSpace(address),\n\t\t\tMtu:        mtu,\n\t\t}\n\t\tspeed, err := sysfs.GetNetworkSpeed(name)\n\t\t// Some devices don't set speed.\n\t\tif err == nil {\n\t\t\tvar s int64\n\t\t\tn, err := fmt.Sscanf(speed, \"%d\", &s)\n\t\t\tif err != nil || n != 1 {\n\t\t\t\treturn nil, fmt.Errorf(\"could not parse speed from %s for device %s\", speed, name)\n\t\t\t}\n\t\t\tnetInfo.Speed = s\n\t\t}\n\t\tnetDevices = append(netDevices, netInfo)\n\t}\n\treturn netDevices, nil\n}\n\n// GetHugePagesInfo returns information about pre-allocated huge pages\n// hugepagesDirectory should be top directory of hugepages\n// Such as: /sys/kernel/mm/hugepages/\nfunc GetHugePagesInfo(sysFs sysfs.SysFs, hugepagesDirectory string) ([]info.HugePagesInfo, error) {\n\tvar hugePagesInfo []info.HugePagesInfo\n\tfiles, err := sysFs.GetHugePagesInfo(hugepagesDirectory)\n\tif err != nil {\n\t\t// treat as non-fatal since kernels and machine can be\n\t\t// configured to disable hugepage support\n\t\treturn hugePagesInfo, nil\n\t}\n\n\tfor _, st := range files {\n\t\tnameArray := strings.Split(st.Name(), \"-\")\n\t\tpageSizeArray := strings.Split(nameArray[1], \"kB\")\n\t\tpageSize, err := strconv.ParseUint(string(pageSizeArray[0]), 10, 64)\n\t\tif err != nil {\n\t\t\treturn hugePagesInfo, err\n\t\t}\n\n\t\tval, err := sysFs.GetHugePagesNr(hugepagesDirectory, st.Name())\n\t\tif err != nil {\n\t\t\treturn hugePagesInfo, err\n\t\t}\n\t\tvar numPages uint64\n\t\t// we use sscanf as the file as a new-line that trips up ParseUint\n\t\t// it returns the number of tokens successfully parsed, so if\n\t\t// n != 1, it means we were unable to parse a number from the file\n\t\tn, err := fmt.Sscanf(string(val), \"%d\", &numPages)\n\t\tif err != nil || n != 1 {\n\t\t\treturn hugePagesInfo, fmt.Errorf(\"could not parse file nr_hugepage for %s, contents %q\", st.Name(), string(val))\n\t\t}\n\n\t\thugePagesInfo = append(hugePagesInfo, info.HugePagesInfo{\n\t\t\tNumPages: numPages,\n\t\t\tPageSize: pageSize,\n\t\t})\n\t}\n\treturn hugePagesInfo, nil\n}\n\n// GetNodesInfo returns information about NUMA nodes and their topology\nfunc GetNodesInfo(sysFs sysfs.SysFs) ([]info.Node, int, error) {\n\tnodes := []info.Node{}\n\tallLogicalCoresCount := 0\n\n\tnodesDirs, err := sysFs.GetNodesPaths()\n\tif err != nil {\n\t\treturn nil, 0, err\n\t}\n\n\tif len(nodesDirs) == 0 {\n\t\tklog.V(4).Info(\"Nodes topology is not available, providing CPU topology\")\n\t\treturn getCPUTopology(sysFs)\n\t}\n\n\tfor _, nodeDir := range nodesDirs {\n\t\tid, err := getMatchedInt(nodeDirRegExp, nodeDir)\n\t\tif err != nil {\n\t\t\treturn nil, 0, err\n\t\t}\n\t\tnode := info.Node{Id: id}\n\n\t\tcpuDirs, err := sysFs.GetCPUsPaths(nodeDir)\n\t\tif len(cpuDirs) == 0 {\n\t\t\tklog.Warningf(\"Found node without any CPU, nodeDir: %s, number of cpuDirs %d, err: %v\", nodeDir, len(cpuDirs), err)\n\t\t} else {\n\t\t\tcores, err := getCoresInfo(sysFs, cpuDirs)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, 0, err\n\t\t\t}\n\t\t\tnode.Cores = cores\n\t\t\tfor _, core := range cores {\n\t\t\t\tallLogicalCoresCount += len(core.Threads)\n\t\t\t}\n\t\t}\n\n\t\t// On some Linux platforms(such as Arm64 guest kernel), cache info may not exist.\n\t\t// So, we should ignore error here.\n\t\terr = addCacheInfo(sysFs, &node)\n\t\tif err != nil {\n\t\t\tklog.V(1).Infof(\"Found node without cache information, nodeDir: %s\", nodeDir)\n\t\t}\n\n\t\tnode.Memory, err = getNodeMemInfo(sysFs, nodeDir)\n\t\tif err != nil {\n\t\t\treturn nil, 0, err\n\t\t}\n\n\t\thugepagesDirectory := fmt.Sprintf(\"%s/%s\", nodeDir, hugepagesDir)\n\t\tnode.HugePages, err = GetHugePagesInfo(sysFs, hugepagesDirectory)\n\t\tif err != nil {\n\t\t\treturn nil, 0, err\n\t\t}\n\n\t\tnode.Distances, err = getDistances(sysFs, nodeDir)\n\t\tif err != nil {\n\t\t\treturn nil, 0, err\n\t\t}\n\n\t\tnodes = append(nodes, node)\n\t}\n\treturn nodes, allLogicalCoresCount, err\n}\n\nfunc getCPUTopology(sysFs sysfs.SysFs) ([]info.Node, int, error) {\n\tnodes := []info.Node{}\n\n\tcpusPaths, err := sysFs.GetCPUsPaths(cpusPath)\n\tif err != nil {\n\t\treturn nil, 0, err\n\t}\n\tcpusCount := len(cpusPaths)\n\n\tif cpusCount == 0 {\n\t\terr = fmt.Errorf(\"no CPU is available, cpusPath: %s\", cpusPath)\n\t\treturn nil, 0, err\n\t}\n\n\tcpusByPhysicalPackageID, err := getCpusByPhysicalPackageID(sysFs, cpusPaths)\n\tif err != nil {\n\t\treturn nil, 0, err\n\t}\n\n\tif len(cpusByPhysicalPackageID) == 0 {\n\t\tklog.Warningf(\"Cannot read any physical package id for any CPU\")\n\t\treturn nil, cpusCount, nil\n\t}\n\n\tfor physicalPackageID, cpus := range cpusByPhysicalPackageID {\n\t\tnode := info.Node{Id: physicalPackageID}\n\n\t\tcores, err := getCoresInfo(sysFs, cpus)\n\t\tif err != nil {\n\t\t\treturn nil, 0, err\n\t\t}\n\t\tnode.Cores = cores\n\n\t\t// On some Linux platforms(such as Arm64 guest kernel), cache info may not exist.\n\t\t// So, we should ignore error here.\n\t\terr = addCacheInfo(sysFs, &node)\n\t\tif err != nil {\n\t\t\tklog.V(1).Infof(\"Found cpu without cache information, cpuPath: %s\", cpus)\n\t\t}\n\t\tnodes = append(nodes, node)\n\t}\n\treturn nodes, cpusCount, nil\n}\n\nfunc getCpusByPhysicalPackageID(sysFs sysfs.SysFs, cpusPaths []string) (map[int][]string, error) {\n\tcpuPathsByPhysicalPackageID := make(map[int][]string)\n\tfor _, cpuPath := range cpusPaths {\n\n\t\trawPhysicalPackageID, err := sysFs.GetCPUPhysicalPackageID(cpuPath)\n\t\tif os.IsNotExist(err) {\n\t\t\tklog.Warningf(\"Cannot read physical package id for %s, physical_package_id file does not exist, err: %s\", cpuPath, err)\n\t\t\tcontinue\n\t\t} else if err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\tphysicalPackageID, err := strconv.Atoi(rawPhysicalPackageID)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\tif _, ok := cpuPathsByPhysicalPackageID[physicalPackageID]; !ok {\n\t\t\tcpuPathsByPhysicalPackageID[physicalPackageID] = make([]string, 0)\n\t\t}\n\n\t\tcpuPathsByPhysicalPackageID[physicalPackageID] = append(cpuPathsByPhysicalPackageID[physicalPackageID], cpuPath)\n\t}\n\treturn cpuPathsByPhysicalPackageID, nil\n}\n\n// addCacheInfo adds information about cache for NUMA node\nfunc addCacheInfo(sysFs sysfs.SysFs, node *info.Node) error {\n\tfor coreID, core := range node.Cores {\n\t\tthreadID := core.Threads[0] //get any thread for core\n\t\tcaches, err := GetCacheInfo(sysFs, threadID)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\tnumThreadsPerCore := len(core.Threads)\n\t\tnumThreadsPerNode := len(node.Cores) * numThreadsPerCore\n\n\t\tfor _, cache := range caches {\n\t\t\tc := info.Cache{\n\t\t\t\tId:    cache.Id,\n\t\t\t\tSize:  cache.Size,\n\t\t\t\tLevel: cache.Level,\n\t\t\t\tType:  cache.Type,\n\t\t\t}\n\t\t\tif cache.Level > cacheLevel2 {\n\t\t\t\tif cache.Cpus == numThreadsPerNode {\n\t\t\t\t\t// Add a node level cache.\n\t\t\t\t\tcacheFound := false\n\t\t\t\t\tfor _, nodeCache := range node.Caches {\n\t\t\t\t\t\tif nodeCache == c {\n\t\t\t\t\t\t\tcacheFound = true\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif !cacheFound {\n\t\t\t\t\t\tnode.Caches = append(node.Caches, c)\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\t// Add uncore cache, for architecture in which l3 cache only shared among some cores.\n\t\t\t\t\tuncoreCacheFound := false\n\t\t\t\t\tfor _, uncoreCache := range node.Cores[coreID].UncoreCaches {\n\t\t\t\t\t\tif uncoreCache == c {\n\t\t\t\t\t\t\tuncoreCacheFound = true\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif !uncoreCacheFound {\n\t\t\t\t\t\tnode.Cores[coreID].UncoreCaches = append(node.Cores[coreID].UncoreCaches, c)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else if cache.Cpus == numThreadsPerCore {\n\t\t\t\t// Add core level cache\n\t\t\t\tnode.Cores[coreID].Caches = append(node.Cores[coreID].Caches, c)\n\t\t\t}\n\t\t\t// Ignore unknown caches.\n\t\t}\n\t}\n\treturn nil\n}\n\n// getNodeMemInfo returns information about total memory for NUMA node\nfunc getNodeMemInfo(sysFs sysfs.SysFs, nodeDir string) (uint64, error) {\n\trawMem, err := sysFs.GetMemInfo(nodeDir)\n\tif err != nil {\n\t\t//Ignore if per-node info is not available.\n\t\tklog.Warningf(\"Found node without memory information, nodeDir: %s\", nodeDir)\n\t\treturn 0, nil\n\t}\n\tmatches := memoryCapacityRegexp.FindStringSubmatch(rawMem)\n\tif len(matches) != 2 {\n\t\treturn 0, fmt.Errorf(\"failed to match regexp in output: %q\", string(rawMem))\n\t}\n\tmemory, err := strconv.ParseUint(matches[1], 10, 64)\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\tmemory = memory * 1024 // Convert to bytes\n\treturn uint64(memory), nil\n}\n\n// getDistances returns information about distances between NUMA nodes\nfunc getDistances(sysFs sysfs.SysFs, nodeDir string) ([]uint64, error) {\n\trawDistance, err := sysFs.GetDistances(nodeDir)\n\tif err != nil {\n\t\t//Ignore if per-node info is not available.\n\t\tklog.Warningf(\"Found node without distance information, nodeDir: %s\", nodeDir)\n\t\treturn nil, nil\n\t}\n\n\tdistances := []uint64{}\n\tfor _, distance := range strings.Split(rawDistance, \" \") {\n\t\tdistanceUint, err := strconv.ParseUint(distance, 10, 64)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"cannot convert %s to int\", distance)\n\t\t}\n\t\tdistances = append(distances, distanceUint)\n\t}\n\n\treturn distances, nil\n}\n\n// getCoresInfo returns information about physical cores\nfunc getCoresInfo(sysFs sysfs.SysFs, cpuDirs []string) ([]info.Core, error) {\n\tcores := make([]info.Core, 0, len(cpuDirs))\n\tfor _, cpuDir := range cpuDirs {\n\t\tcpuID, err := getMatchedInt(cpuDirRegExp, cpuDir)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"unexpected format of CPU directory, cpuDirRegExp %s, cpuDir: %s\", cpuDirRegExp, cpuDir)\n\t\t}\n\t\tif !sysFs.IsCPUOnline(cpuDir) {\n\t\t\tcontinue\n\t\t}\n\n\t\trawPhysicalID, err := sysFs.GetCoreID(cpuDir)\n\t\tif os.IsNotExist(err) {\n\t\t\tklog.Warningf(\"Cannot read core id for %s, core_id file does not exist, err: %s\", cpuDir, err)\n\t\t\tcontinue\n\t\t} else if err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tphysicalID, err := strconv.Atoi(rawPhysicalID)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\trawPhysicalPackageID, err := sysFs.GetCPUPhysicalPackageID(cpuDir)\n\t\tif os.IsNotExist(err) {\n\t\t\tklog.Warningf(\"Cannot read physical package id for %s, physical_package_id file does not exist, err: %s\", cpuDir, err)\n\t\t\tcontinue\n\t\t} else if err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\tphysicalPackageID, err := strconv.Atoi(rawPhysicalPackageID)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\tvar bookID, drawerID string\n\t\t// s390/s390x additional cpu topology levels\n\t\tif runtime.GOARCH == \"s390x\" {\n\t\t\tbookID, err = sysFs.GetBookID(cpuDir)\n\t\t\tif os.IsNotExist(err) {\n\t\t\t\tklog.Warningf(\"Cannot read book id for %s, book_id file does not exist, err: %s\", cpuDir, err)\n\t\t\t\tcontinue\n\t\t\t} else if err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tdrawerID, err = sysFs.GetDrawerID(cpuDir)\n\t\t\tif os.IsNotExist(err) {\n\t\t\t\tklog.Warningf(\"Cannot read drawer id for %s, drawer_id file does not exist, err: %s\", cpuDir, err)\n\t\t\t\tcontinue\n\t\t\t} else if err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t}\n\n\t\tcoreIDx := -1\n\t\tfor id, core := range cores {\n\t\t\tif core.Id == physicalID && core.SocketID == physicalPackageID {\n\t\t\t\t// For s390x, we need to check the BookID and DrawerID match as well.\n\t\t\t\tif runtime.GOARCH != \"s390x\" || (core.BookID == bookID && core.DrawerID == drawerID) {\n\t\t\t\t\tcoreIDx = id\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif coreIDx == -1 {\n\t\t\tcores = append(cores, info.Core{})\n\t\t\tcoreIDx = len(cores) - 1\n\t\t}\n\t\tdesiredCore := &cores[coreIDx]\n\n\t\tdesiredCore.Id = physicalID\n\t\tdesiredCore.SocketID = physicalPackageID\n\t\tdesiredCore.BookID = bookID\n\t\tdesiredCore.DrawerID = drawerID\n\n\t\tif len(desiredCore.Threads) == 0 {\n\t\t\tdesiredCore.Threads = []int{cpuID}\n\t\t} else {\n\t\t\tdesiredCore.Threads = append(desiredCore.Threads, cpuID)\n\t\t}\n\n\t}\n\treturn cores, nil\n}\n\n// GetCacheInfo return information about a cache accessible from the given cpu thread\nfunc GetCacheInfo(sysFs sysfs.SysFs, id int) ([]sysfs.CacheInfo, error) {\n\tcaches, err := sysFs.GetCaches(id)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tinfo := []sysfs.CacheInfo{}\n\tfor _, cache := range caches {\n\t\tif !strings.HasPrefix(cache.Name(), \"index\") {\n\t\t\tcontinue\n\t\t}\n\t\tcacheInfo, err := sysFs.GetCacheInfo(id, cache.Name())\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tinfo = append(info, cacheInfo)\n\t}\n\treturn info, nil\n}\n\nfunc getNetworkStats(name string, sysFs sysfs.SysFs) (info.InterfaceStats, error) {\n\tvar stats info.InterfaceStats\n\tvar err error\n\tstats.Name = name\n\tstats.RxBytes, err = sysFs.GetNetworkStatValue(name, \"rx_bytes\")\n\tif err != nil {\n\t\treturn stats, err\n\t}\n\tstats.RxPackets, err = sysFs.GetNetworkStatValue(name, \"rx_packets\")\n\tif err != nil {\n\t\treturn stats, err\n\t}\n\tstats.RxErrors, err = sysFs.GetNetworkStatValue(name, \"rx_errors\")\n\tif err != nil {\n\t\treturn stats, err\n\t}\n\tstats.RxDropped, err = sysFs.GetNetworkStatValue(name, \"rx_dropped\")\n\tif err != nil {\n\t\treturn stats, err\n\t}\n\tstats.TxBytes, err = sysFs.GetNetworkStatValue(name, \"tx_bytes\")\n\tif err != nil {\n\t\treturn stats, err\n\t}\n\tstats.TxPackets, err = sysFs.GetNetworkStatValue(name, \"tx_packets\")\n\tif err != nil {\n\t\treturn stats, err\n\t}\n\tstats.TxErrors, err = sysFs.GetNetworkStatValue(name, \"tx_errors\")\n\tif err != nil {\n\t\treturn stats, err\n\t}\n\tstats.TxDropped, err = sysFs.GetNetworkStatValue(name, \"tx_dropped\")\n\tif err != nil {\n\t\treturn stats, err\n\t}\n\treturn stats, nil\n}\n\nfunc GetSystemUUID(sysFs sysfs.SysFs) (string, error) {\n\treturn sysFs.GetSystemUUID()\n}\n\nfunc getMatchedInt(rgx *regexp.Regexp, str string) (int, error) {\n\tmatches := rgx.FindStringSubmatch(str)\n\tif len(matches) != 2 {\n\t\treturn 0, fmt.Errorf(\"failed to match regexp, str: %s\", str)\n\t}\n\tvalInt, err := strconv.Atoi(matches[1])\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\treturn valInt, nil\n}\n\n// GetSocketFromCPU returns Socket ID of passed CPU. If is not present, returns -1.\nfunc GetSocketFromCPU(topology []info.Node, cpu int) int {\n\tfor _, node := range topology {\n\t\tfound, coreID := node.FindCoreByThread(cpu)\n\t\tif found {\n\t\t\treturn node.Cores[coreID].SocketID\n\t\t}\n\t}\n\treturn -1\n}\n\n// GetOnlineCPUs returns available cores.\nfunc GetOnlineCPUs(topology []info.Node) []int {\n\tonlineCPUs := make([]int, 0)\n\tfor _, node := range topology {\n\t\tfor _, core := range node.Cores {\n\t\t\tonlineCPUs = append(onlineCPUs, core.Threads...)\n\t\t}\n\t}\n\treturn onlineCPUs\n}\n"
  },
  {
    "path": "utils/sysinfo/sysinfo_test.go",
    "content": "// Copyright 2014 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage sysinfo\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"os\"\n\t\"sort\"\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/assert\"\n\n\tinfo \"github.com/google/cadvisor/info/v1\"\n\t\"github.com/google/cadvisor/utils/sysfs\"\n\t\"github.com/google/cadvisor/utils/sysfs/fakesysfs\"\n)\n\nfunc TestGetHugePagesInfo(t *testing.T) {\n\tfakeSys := fakesysfs.FakeSysFs{}\n\thugePages := []os.FileInfo{\n\t\t&fakesysfs.FileInfo{EntryName: \"hugepages-2048kB\"},\n\t\t&fakesysfs.FileInfo{EntryName: \"hugepages-1048576kB\"},\n\t}\n\tfakeSys.SetHugePages(hugePages, nil)\n\n\thugePageNr := map[string]string{\n\t\t\"/fakeSysfs/devices/system/node/node0/hugepages/hugepages-2048kB/nr_hugepages\":    \"1\",\n\t\t\"/fakeSysfs/devices/system/node/node0/hugepages/hugepages-1048576kB/nr_hugepages\": \"1\",\n\t}\n\tfakeSys.SetHugePagesNr(hugePageNr, nil)\n\n\thugePagesInfo, err := GetHugePagesInfo(&fakeSys, \"/fakeSysfs/devices/system/node/node0/hugepages/\")\n\tassert.Nil(t, err)\n\tassert.Equal(t, 2, len(hugePagesInfo))\n}\n\nfunc TestGetHugePagesInfoWithHugePagesDirectory(t *testing.T) {\n\tfakeSys := fakesysfs.FakeSysFs{}\n\thugePagesInfo, err := GetHugePagesInfo(&fakeSys, \"/fakeSysfs/devices/system/node/node0/hugepages/\")\n\tassert.Nil(t, err)\n\tassert.Equal(t, 0, len(hugePagesInfo))\n}\n\nfunc TestGetHugePagesInfoWithWrongDirName(t *testing.T) {\n\tfakeSys := fakesysfs.FakeSysFs{}\n\thugePages := []os.FileInfo{\n\t\t&fakesysfs.FileInfo{EntryName: \"hugepages-abckB\"},\n\t}\n\tfakeSys.SetHugePages(hugePages, nil)\n\n\thugePagesInfo, err := GetHugePagesInfo(&fakeSys, \"/fakeSysfs/devices/system/node/node0/hugepages/\")\n\tassert.NotNil(t, err)\n\tassert.Equal(t, 0, len(hugePagesInfo))\n}\n\nfunc TestGetHugePagesInfoWithReadingNrHugePagesError(t *testing.T) {\n\tfakeSys := fakesysfs.FakeSysFs{}\n\thugePages := []os.FileInfo{\n\t\t&fakesysfs.FileInfo{EntryName: \"hugepages-2048kB\"},\n\t\t&fakesysfs.FileInfo{EntryName: \"hugepages-1048576kB\"},\n\t}\n\tfakeSys.SetHugePages(hugePages, nil)\n\n\thugePageNr := map[string]string{\n\t\t\"/fakeSysfs/devices/system/node/node0/hugepages/hugepages-2048kB/nr_hugepages\":    \"1\",\n\t\t\"/fakeSysfs/devices/system/node/node0/hugepages/hugepages-1048576kB/nr_hugepages\": \"1\",\n\t}\n\tfakeSys.SetHugePagesNr(hugePageNr, fmt.Errorf(\"Error in reading nr_hugepages\"))\n\n\thugePagesInfo, err := GetHugePagesInfo(&fakeSys, \"/fakeSysfs/devices/system/node/node0/hugepages/\")\n\tassert.NotNil(t, err)\n\tassert.Equal(t, 0, len(hugePagesInfo))\n}\n\nfunc TestGetHugePagesInfoWithWrongNrHugePageValue(t *testing.T) {\n\tfakeSys := fakesysfs.FakeSysFs{}\n\thugePages := []os.FileInfo{\n\t\t&fakesysfs.FileInfo{EntryName: \"hugepages-2048kB\"},\n\t\t&fakesysfs.FileInfo{EntryName: \"hugepages-1048576kB\"},\n\t}\n\tfakeSys.SetHugePages(hugePages, nil)\n\n\thugePageNr := map[string]string{\n\t\t\"/fakeSysfs/devices/system/node/node0/hugepages/hugepages-2048kB/nr_hugepages\":    \"*****\",\n\t\t\"/fakeSysfs/devices/system/node/node0/hugepages/hugepages-1048576kB/nr_hugepages\": \"1\",\n\t}\n\tfakeSys.SetHugePagesNr(hugePageNr, nil)\n\n\thugePagesInfo, err := GetHugePagesInfo(&fakeSys, \"/fakeSysfs/devices/system/node/node0/hugepages/\")\n\tassert.NotNil(t, err)\n\tassert.Equal(t, 0, len(hugePagesInfo))\n}\n\nfunc TestGetNodesInfo(t *testing.T) {\n\ttestCases := []struct {\n\t\tcache              sysfs.CacheInfo\n\t\tnodesPaths         []string\n\t\tcpusPaths          map[string][]string\n\t\tcoresThreads       map[string]string\n\t\tmemTotal           string\n\t\thugePages          []os.FileInfo\n\t\thugePageNr         map[string]string\n\t\tphysicalPackageIDs map[string]string\n\t\tnodes              int\n\t\tcores              int\n\t\tdistances          []string\n\t\texpectedNodes      string\n\t}{\n\t\t{\n\t\t\tsysfs.CacheInfo{\n\t\t\t\tId:    0,\n\t\t\t\tSize:  32 * 1024,\n\t\t\t\tType:  \"unified\",\n\t\t\t\tLevel: 3,\n\t\t\t\tCpus:  2,\n\t\t\t},\n\t\t\t[]string{\n\t\t\t\t\"/fakeSysfs/devices/system/node/node0\",\n\t\t\t\t\"/fakeSysfs/devices/system/node/node1\"},\n\t\t\tmap[string][]string{\n\t\t\t\t\"/fakeSysfs/devices/system/node/node0\": {\n\t\t\t\t\t\"/fakeSysfs/devices/system/node/node0/cpu0\",\n\t\t\t\t\t\"/fakeSysfs/devices/system/node/node0/cpu1\",\n\t\t\t\t},\n\t\t\t\t\"/fakeSysfs/devices/system/node/node1\": {\n\t\t\t\t\t\"/fakeSysfs/devices/system/node/node0/cpu2\",\n\t\t\t\t\t\"/fakeSysfs/devices/system/node/node0/cpu3\",\n\t\t\t\t},\n\t\t\t},\n\t\t\tmap[string]string{\n\t\t\t\t\"/fakeSysfs/devices/system/node/node0/cpu0\": \"0\",\n\t\t\t\t\"/fakeSysfs/devices/system/node/node0/cpu1\": \"0\",\n\t\t\t\t\"/fakeSysfs/devices/system/node/node0/cpu2\": \"1\",\n\t\t\t\t\"/fakeSysfs/devices/system/node/node0/cpu3\": \"1\",\n\t\t\t},\n\t\t\t\"MemTotal:       32817192 kB\",\n\t\t\t[]os.FileInfo{\n\t\t\t\t&fakesysfs.FileInfo{EntryName: \"hugepages-2048kB\"},\n\t\t\t},\n\t\t\tmap[string]string{\n\t\t\t\t\"/fakeSysfs/devices/system/node/node0/hugepages/hugepages-2048kB/nr_hugepages\": \"1\",\n\t\t\t\t\"/fakeSysfs/devices/system/node/node1/hugepages/hugepages-2048kB/nr_hugepages\": \"1\",\n\t\t\t},\n\t\t\tmap[string]string{\n\t\t\t\t\"/fakeSysfs/devices/system/node/node0/cpu0\": \"0\",\n\t\t\t\t\"/fakeSysfs/devices/system/node/node0/cpu1\": \"0\",\n\t\t\t\t\"/fakeSysfs/devices/system/node/node0/cpu2\": \"1\",\n\t\t\t\t\"/fakeSysfs/devices/system/node/node0/cpu3\": \"1\",\n\t\t\t},\n\t\t\t2,\n\t\t\t4,\n\t\t\t[]string{\n\t\t\t\t\"10 11\",\n\t\t\t\t\"11 10\",\n\t\t\t},\n\t\t\t`\n\t[\n      {\n        \"node_id\": 0,\n        \"memory\": 33604804608,\n        \"hugepages\": [\n          {\n            \"page_size\": 2048,\n            \"num_pages\": 1\n          }\n        ],\n        \"distances\": [\n          10,\n          11\n        ],\n        \"cores\": [\n          {\n            \"core_id\": 0,\n            \"thread_ids\": [\n              0,\n              1\n            ],\n            \"caches\": null,\n            \"uncore_caches\": null,\n            \"socket_id\": 0\n          }\n        ],\n        \"caches\": [\n          {\n            \"id\": 0,\n            \"size\": 32768,\n            \"type\": \"unified\",\n            \"level\": 3\n          }\n        ]\n      },\n      {\n        \"node_id\": 1,\n        \"memory\": 33604804608,\n        \"hugepages\": [\n          {\n            \"page_size\": 2048,\n            \"num_pages\": 1\n          }\n        ],\n        \"distances\": [\n          11,\n          10\n        ],\n        \"cores\": [\n          {\n            \"core_id\": 1,\n            \"thread_ids\": [\n              2,\n              3\n            ],\n            \"caches\": null,\n            \"uncore_caches\": null,\n            \"socket_id\": 1\n          }\n        ],\n        \"caches\": [\n          {\n            \"id\": 0,\n            \"size\": 32768,\n            \"type\": \"unified\",\n            \"level\": 3\n          }\n        ]\n      }\n    ]\n    `,\n\t\t},\n\t\t{\n\t\t\tsysfs.CacheInfo{\n\t\t\t\tId:    0,\n\t\t\t\tSize:  32 * 1024,\n\t\t\t\tType:  \"unified\",\n\t\t\t\tLevel: 3,\n\t\t\t\tCpus:  6,\n\t\t\t},\n\t\t\t[]string{\n\t\t\t\t\"/fakeSysfs/devices/system/node/node0\"},\n\t\t\tmap[string][]string{\n\t\t\t\t\"/fakeSysfs/devices/system/node/node0\": {\n\t\t\t\t\t\"/fakeSysfs/devices/system/node/node0/cpu0\",\n\t\t\t\t\t\"/fakeSysfs/devices/system/node/node0/cpu1\",\n\t\t\t\t\t\"/fakeSysfs/devices/system/node/node0/cpu2\",\n\t\t\t\t\t\"/fakeSysfs/devices/system/node/node0/cpu3\",\n\t\t\t\t\t\"/fakeSysfs/devices/system/node/node0/cpu4\",\n\t\t\t\t\t\"/fakeSysfs/devices/system/node/node0/cpu5\",\n\t\t\t\t},\n\t\t\t},\n\t\t\tmap[string]string{\n\t\t\t\t\"/fakeSysfs/devices/system/node/node0/cpu0\": \"0\",\n\t\t\t\t\"/fakeSysfs/devices/system/node/node0/cpu1\": \"0\",\n\t\t\t\t\"/fakeSysfs/devices/system/node/node0/cpu2\": \"1\",\n\t\t\t\t\"/fakeSysfs/devices/system/node/node0/cpu3\": \"1\",\n\t\t\t\t\"/fakeSysfs/devices/system/node/node0/cpu4\": \"2\",\n\t\t\t\t\"/fakeSysfs/devices/system/node/node0/cpu5\": \"2\",\n\t\t\t},\n\t\t\t\"MemTotal:       32817192 kB\",\n\t\t\t[]os.FileInfo{\n\t\t\t\t&fakesysfs.FileInfo{EntryName: \"hugepages-2048kB\"},\n\t\t\t},\n\t\t\tmap[string]string{\n\t\t\t\t\"/fakeSysfs/devices/system/node/node0/hugepages/hugepages-2048kB/nr_hugepages\": \"1\",\n\t\t\t},\n\t\t\tmap[string]string{\n\t\t\t\t\"/fakeSysfs/devices/system/node/node0/cpu0\": \"0\",\n\t\t\t\t\"/fakeSysfs/devices/system/node/node0/cpu1\": \"0\",\n\t\t\t\t\"/fakeSysfs/devices/system/node/node0/cpu2\": \"1\",\n\t\t\t\t\"/fakeSysfs/devices/system/node/node0/cpu3\": \"1\",\n\t\t\t\t\"/fakeSysfs/devices/system/node/node0/cpu4\": \"2\",\n\t\t\t\t\"/fakeSysfs/devices/system/node/node0/cpu5\": \"2\",\n\t\t\t},\n\t\t\t1,\n\t\t\t6,\n\t\t\t[]string{\n\t\t\t\t\"10\",\n\t\t\t},\n\t\t\t`\n\t[\n      {\n        \"node_id\": 0,\n        \"memory\": 33604804608,\n        \"distances\": [\n          10\n        ],\n        \"hugepages\": [\n          {\n            \"page_size\": 2048,\n            \"num_pages\": 1\n          }\n        ],\n        \"cores\": [\n          {\n            \"core_id\": 0,\n            \"thread_ids\": [\n              0,\n              1\n            ],\n            \"caches\": null,\n            \"socket_id\": 0,\n            \"uncore_caches\": null\n          },\n          {\n            \"core_id\": 1,\n            \"thread_ids\": [\n              2,\n              3\n            ],\n            \"caches\": null,\n            \"socket_id\": 1,\n            \"uncore_caches\": null\n          },\n          {\n            \"core_id\": 2,\n            \"thread_ids\": [\n              4,\n              5\n            ],\n            \"caches\": null,\n            \"socket_id\": 2,\n            \"uncore_caches\": null\n          }\n        ],\n        \"caches\": [\n          {\n            \"id\": 0,\n            \"size\": 32768,\n            \"type\": \"unified\",\n            \"level\": 3\n          }\n        ]\n      }\n    ]\n    `,\n\t\t},\n\t}\n\n\tfor _, test := range testCases {\n\t\tfakeSys := &fakesysfs.FakeSysFs{}\n\t\tfakeSys.SetCacheInfo(test.cache)\n\t\tfakeSys.SetNodesPaths(test.nodesPaths, nil)\n\t\tfakeSys.SetCPUsPaths(test.cpusPaths, nil)\n\t\tfakeSys.SetCoreThreads(test.coresThreads, nil)\n\t\tfakeSys.SetMemory(test.memTotal, nil)\n\t\tfakeSys.SetHugePages(test.hugePages, nil)\n\t\tfakeSys.SetHugePagesNr(test.hugePageNr, nil)\n\t\tfakeSys.SetPhysicalPackageIDs(test.physicalPackageIDs, nil)\n\t\tfor i, node := range test.nodesPaths {\n\t\t\tfakeSys.SetDistances(node, test.distances[i], nil)\n\t\t}\n\n\t\tnodes, cores, err := GetNodesInfo(fakeSys)\n\t\tassert.Nil(t, err)\n\t\tassert.Equal(t, test.nodes, len(nodes))\n\t\tassert.Equal(t, test.cores, cores)\n\n\t\tnodesJSON, err := json.Marshal(nodes)\n\t\tassert.Nil(t, err)\n\t\tassert.JSONEq(t, test.expectedNodes, string(nodesJSON))\n\t}\n}\n\nfunc TestGetNodesInfoWithOfflineCPUs(t *testing.T) {\n\tfakeSys := &fakesysfs.FakeSysFs{}\n\tc := sysfs.CacheInfo{\n\t\tId:    0,\n\t\tSize:  32 * 1024,\n\t\tType:  \"unified\",\n\t\tLevel: 3,\n\t\tCpus:  1,\n\t}\n\tfakeSys.SetCacheInfo(c)\n\n\tnodesPaths := []string{\n\t\t\"/fakeSysfs/devices/system/node/node0\",\n\t\t\"/fakeSysfs/devices/system/node/node1\",\n\t}\n\tfakeSys.SetNodesPaths(nodesPaths, nil)\n\n\tcpusPaths := map[string][]string{\n\t\t\"/fakeSysfs/devices/system/node/node0\": {\n\t\t\t\"/fakeSysfs/devices/system/node/node0/cpu0\",\n\t\t\t\"/fakeSysfs/devices/system/node/node0/cpu1\",\n\t\t},\n\t\t\"/fakeSysfs/devices/system/node/node1\": {\n\t\t\t\"/fakeSysfs/devices/system/node/node0/cpu2\",\n\t\t\t\"/fakeSysfs/devices/system/node/node0/cpu3\",\n\t\t},\n\t}\n\tfakeSys.SetCPUsPaths(cpusPaths, nil)\n\n\tcoreThread := map[string]string{\n\t\t\"/fakeSysfs/devices/system/node/node0/cpu0\": \"0\",\n\t\t\"/fakeSysfs/devices/system/node/node0/cpu1\": \"0\",\n\t\t\"/fakeSysfs/devices/system/node/node0/cpu2\": \"1\",\n\t\t\"/fakeSysfs/devices/system/node/node0/cpu3\": \"1\",\n\t}\n\tfakeSys.SetCoreThreads(coreThread, nil)\n\tfakeSys.SetOnlineCPUs(map[string]interface{}{\n\t\t\"/fakeSysfs/devices/system/node/node0/cpu0\": nil,\n\t\t\"/fakeSysfs/devices/system/node/node0/cpu2\": nil,\n\t})\n\n\tmemTotal := \"MemTotal:       32817192 kB\"\n\tfakeSys.SetMemory(memTotal, nil)\n\n\thugePages := []os.FileInfo{\n\t\t&fakesysfs.FileInfo{EntryName: \"hugepages-2048kB\"},\n\t}\n\tfakeSys.SetHugePages(hugePages, nil)\n\n\thugePageNr := map[string]string{\n\t\t\"/fakeSysfs/devices/system/node/node0/hugepages/hugepages-2048kB/nr_hugepages\": \"1\",\n\t\t\"/fakeSysfs/devices/system/node/node1/hugepages/hugepages-2048kB/nr_hugepages\": \"1\",\n\t}\n\tfakeSys.SetHugePagesNr(hugePageNr, nil)\n\n\tphysicalPackageIDs := map[string]string{\n\t\t\"/fakeSysfs/devices/system/node/node0/cpu0\": \"0\",\n\t\t\"/fakeSysfs/devices/system/node/node0/cpu1\": \"0\",\n\t\t\"/fakeSysfs/devices/system/node/node0/cpu2\": \"1\",\n\t\t\"/fakeSysfs/devices/system/node/node0/cpu3\": \"1\",\n\t}\n\tfakeSys.SetPhysicalPackageIDs(physicalPackageIDs, nil)\n\n\tfakeSys.SetDistances(\"/fakeSysfs/devices/system/node/node0\", \"10 11\", nil)\n\tfakeSys.SetDistances(\"/fakeSysfs/devices/system/node/node1\", \"11 10\", nil)\n\n\tnodes, cores, err := GetNodesInfo(fakeSys)\n\tassert.Nil(t, err)\n\tassert.Equal(t, 2, len(nodes))\n\tassert.Equal(t, 2, cores)\n\n\tnodesJSON, err := json.Marshal(nodes)\n\tassert.Nil(t, err)\n\texpectedNodes := `\n\t[\n      {\n        \"node_id\": 0,\n        \"memory\": 33604804608,\n        \"hugepages\": [\n          {\n            \"page_size\": 2048,\n            \"num_pages\": 1\n          }\n        ],\n        \"distances\": [\n          10,\n          11\n        ],\n        \"cores\": [\n          {\n            \"core_id\": 0,\n            \"thread_ids\": [\n              0\n            ],\n            \"caches\": null,\n            \"socket_id\": 0,\n            \"uncore_caches\": null\n          }\n        ],\n        \"caches\": [\n          {\n            \"id\": 0,\n            \"size\": 32768,\n            \"type\": \"unified\",\n            \"level\": 3\n          }\n        ]\n      },\n      {\n        \"node_id\": 1,\n        \"memory\": 33604804608,\n        \"hugepages\": [\n          {\n            \"page_size\": 2048,\n            \"num_pages\": 1\n          }\n        ],\n        \"distances\": [\n          11,\n          10\n        ],\n        \"cores\": [\n          {\n            \"core_id\": 1,\n            \"thread_ids\": [\n              2\n            ],\n            \"caches\": null,\n            \"socket_id\": 1,\n            \"uncore_caches\": null\n          }\n        ],\n        \"caches\": [\n          {\n            \"id\": 0,\n            \"size\": 32768,\n            \"type\": \"unified\",\n            \"level\": 3\n          }\n        ]\n      }\n    ]\n    `\n\tassert.JSONEq(t, expectedNodes, string(nodesJSON))\n}\n\nfunc TestGetNodesWithoutMemoryInfo(t *testing.T) {\n\tfakeSys := &fakesysfs.FakeSysFs{}\n\tc := sysfs.CacheInfo{\n\t\tSize:  32 * 1024,\n\t\tType:  \"unified\",\n\t\tLevel: 3,\n\t\tCpus:  2,\n\t}\n\tfakeSys.SetCacheInfo(c)\n\n\tnodesPaths := []string{\n\t\t\"/fakeSysfs/devices/system/node/node0\",\n\t\t\"/fakeSysfs/devices/system/node/node1\",\n\t}\n\tfakeSys.SetNodesPaths(nodesPaths, nil)\n\n\tcpusPaths := map[string][]string{\n\t\t\"/fakeSysfs/devices/system/node/node0\": {\n\t\t\t\"/fakeSysfs/devices/system/node/node0/cpu0\",\n\t\t\t\"/fakeSysfs/devices/system/node/node0/cpu1\",\n\t\t},\n\t\t\"/fakeSysfs/devices/system/node/node1\": {\n\t\t\t\"/fakeSysfs/devices/system/node/node0/cpu2\",\n\t\t\t\"/fakeSysfs/devices/system/node/node0/cpu3\",\n\t\t},\n\t}\n\tfakeSys.SetCPUsPaths(cpusPaths, nil)\n\n\tcoreThread := map[string]string{\n\t\t\"/fakeSysfs/devices/system/node/node0/cpu0\": \"0\",\n\t\t\"/fakeSysfs/devices/system/node/node0/cpu1\": \"0\",\n\t\t\"/fakeSysfs/devices/system/node/node0/cpu2\": \"1\",\n\t\t\"/fakeSysfs/devices/system/node/node0/cpu3\": \"1\",\n\t}\n\tfakeSys.SetCoreThreads(coreThread, nil)\n\n\thugePages := []os.FileInfo{\n\t\t&fakesysfs.FileInfo{EntryName: \"hugepages-2048kB\"},\n\t}\n\tfakeSys.SetHugePages(hugePages, nil)\n\n\thugePageNr := map[string]string{\n\t\t\"/fakeSysfs/devices/system/node/node0/hugepages/hugepages-2048kB/nr_hugepages\": \"1\",\n\t\t\"/fakeSysfs/devices/system/node/node1/hugepages/hugepages-2048kB/nr_hugepages\": \"1\",\n\t}\n\tfakeSys.SetHugePagesNr(hugePageNr, nil)\n\n\tnodes, cores, err := GetNodesInfo(fakeSys)\n\tassert.NotNil(t, err)\n\tassert.Equal(t, []info.Node([]info.Node(nil)), nodes)\n\tassert.Equal(t, 0, cores)\n}\n\nfunc TestGetNodesInfoWithoutCacheInfo(t *testing.T) {\n\tfakeSys := &fakesysfs.FakeSysFs{}\n\n\tnodesPaths := []string{\n\t\t\"/fakeSysfs/devices/system/node/node0\",\n\t\t\"/fakeSysfs/devices/system/node/node1\",\n\t}\n\tfakeSys.SetNodesPaths(nodesPaths, nil)\n\n\tcpusPaths := map[string][]string{\n\t\t\"/fakeSysfs/devices/system/node/node0\": {\n\t\t\t\"/fakeSysfs/devices/system/node/node0/cpu0\",\n\t\t\t\"/fakeSysfs/devices/system/node/node0/cpu1\",\n\t\t},\n\t\t\"/fakeSysfs/devices/system/node/node1\": {\n\t\t\t\"/fakeSysfs/devices/system/node/node0/cpu2\",\n\t\t\t\"/fakeSysfs/devices/system/node/node0/cpu3\",\n\t\t},\n\t}\n\tfakeSys.SetCPUsPaths(cpusPaths, nil)\n\n\tcoreThread := map[string]string{\n\t\t\"/fakeSysfs/devices/system/node/node0/cpu0\": \"0\",\n\t\t\"/fakeSysfs/devices/system/node/node0/cpu1\": \"0\",\n\t\t\"/fakeSysfs/devices/system/node/node0/cpu2\": \"1\",\n\t\t\"/fakeSysfs/devices/system/node/node0/cpu3\": \"1\",\n\t}\n\tfakeSys.SetCoreThreads(coreThread, nil)\n\n\tmemTotal := \"MemTotal:       32817192 kB\"\n\tfakeSys.SetMemory(memTotal, nil)\n\n\thugePages := []os.FileInfo{\n\t\t&fakesysfs.FileInfo{EntryName: \"hugepages-2048kB\"},\n\t}\n\tfakeSys.SetHugePages(hugePages, nil)\n\n\thugePageNr := map[string]string{\n\t\t\"/fakeSysfs/devices/system/node/node0/hugepages/hugepages-2048kB/nr_hugepages\": \"1\",\n\t\t\"/fakeSysfs/devices/system/node/node1/hugepages/hugepages-2048kB/nr_hugepages\": \"1\",\n\t}\n\tfakeSys.SetHugePagesNr(hugePageNr, nil)\n\n\tphysicalPackageIDs := map[string]string{\n\t\t\"/fakeSysfs/devices/system/node/node0/cpu0\": \"0\",\n\t\t\"/fakeSysfs/devices/system/node/node0/cpu1\": \"0\",\n\t\t\"/fakeSysfs/devices/system/node/node0/cpu2\": \"1\",\n\t\t\"/fakeSysfs/devices/system/node/node0/cpu3\": \"1\",\n\t}\n\tfakeSys.SetPhysicalPackageIDs(physicalPackageIDs, nil)\n\n\tfakeSys.SetDistances(\"/fakeSysfs/devices/system/node/node0\", \"10 11\", nil)\n\tfakeSys.SetDistances(\"/fakeSysfs/devices/system/node/node1\", \"11 10\", nil)\n\n\tnodes, cores, err := GetNodesInfo(fakeSys)\n\tassert.Nil(t, err)\n\tassert.Equal(t, 2, len(nodes))\n\tassert.Equal(t, 4, cores)\n\n\tnodesJSON, err := json.Marshal(nodes)\n\tassert.Nil(t, err)\n\texpectedNodes := `\n\t[\n      {\n        \"node_id\": 0,\n        \"memory\": 33604804608,\n        \"hugepages\": [\n          {\n            \"page_size\": 2048,\n            \"num_pages\": 1\n          }\n        ],\n        \"distances\": [\n          10,\n          11\n        ],\n        \"cores\": [\n\t  {\n            \"core_id\": 0,\n            \"thread_ids\": [\n              0,\n              1\n            ],\n            \"caches\": null,\n            \"uncore_caches\": null,\n            \"socket_id\": 0\n          }\n        ],\n        \"caches\": null\n      },\n      {\n        \"node_id\": 1,\n        \"memory\": 33604804608,\n        \"hugepages\": [\n          {\n            \"page_size\": 2048,\n            \"num_pages\": 1\n          }\n        ],\n        \"distances\": [\n          11,\n          10\n        ],\n        \"cores\": [\n          {\n            \"core_id\": 1,\n            \"thread_ids\": [\n              2,\n              3\n            ],\n            \"caches\": null,\n            \"uncore_caches\": null,\n            \"socket_id\": 1\n          }\n        ],\n        \"caches\": null\n      }\n    ]`\n\tassert.JSONEq(t, expectedNodes, string(nodesJSON))\n}\n\nfunc TestGetNodesInfoWithoutHugePagesInfo(t *testing.T) {\n\tfakeSys := &fakesysfs.FakeSysFs{}\n\tc := sysfs.CacheInfo{\n\t\tId:    0,\n\t\tSize:  32 * 1024,\n\t\tType:  \"unified\",\n\t\tLevel: 2,\n\t\tCpus:  2,\n\t}\n\tfakeSys.SetCacheInfo(c)\n\n\tnodesPaths := []string{\n\t\t\"/fakeSysfs/devices/system/node/node0\",\n\t\t\"/fakeSysfs/devices/system/node/node1\",\n\t}\n\tfakeSys.SetNodesPaths(nodesPaths, nil)\n\n\tcpusPaths := map[string][]string{\n\t\t\"/fakeSysfs/devices/system/node/node0\": {\n\t\t\t\"/fakeSysfs/devices/system/node/node0/cpu0\",\n\t\t\t\"/fakeSysfs/devices/system/node/node0/cpu1\",\n\t\t},\n\t\t\"/fakeSysfs/devices/system/node/node1\": {\n\t\t\t\"/fakeSysfs/devices/system/node/node0/cpu2\",\n\t\t\t\"/fakeSysfs/devices/system/node/node0/cpu3\",\n\t\t},\n\t}\n\tfakeSys.SetCPUsPaths(cpusPaths, nil)\n\n\tcoreThread := map[string]string{\n\t\t\"/fakeSysfs/devices/system/node/node0/cpu0\": \"0\",\n\t\t\"/fakeSysfs/devices/system/node/node0/cpu1\": \"0\",\n\t\t\"/fakeSysfs/devices/system/node/node0/cpu2\": \"1\",\n\t\t\"/fakeSysfs/devices/system/node/node0/cpu3\": \"1\",\n\t}\n\tfakeSys.SetCoreThreads(coreThread, nil)\n\n\tmemTotal := \"MemTotal:       32817192 kB\"\n\tfakeSys.SetMemory(memTotal, nil)\n\n\tphysicalPackageIDs := map[string]string{\n\t\t\"/fakeSysfs/devices/system/node/node0/cpu0\": \"0\",\n\t\t\"/fakeSysfs/devices/system/node/node0/cpu1\": \"0\",\n\t\t\"/fakeSysfs/devices/system/node/node0/cpu2\": \"1\",\n\t\t\"/fakeSysfs/devices/system/node/node0/cpu3\": \"1\",\n\t}\n\tfakeSys.SetPhysicalPackageIDs(physicalPackageIDs, nil)\n\n\tfakeSys.SetDistances(\"/fakeSysfs/devices/system/node/node0\", \"10 11\", nil)\n\tfakeSys.SetDistances(\"/fakeSysfs/devices/system/node/node1\", \"11 10\", nil)\n\n\tnodes, cores, err := GetNodesInfo(fakeSys)\n\tassert.Nil(t, err)\n\tassert.Equal(t, 2, len(nodes))\n\tassert.Equal(t, 4, cores)\n\n\tnodesJSON, err := json.Marshal(nodes)\n\tassert.Nil(t, err)\n\texpectedNodes := `\n\t[\n      {\n        \"node_id\": 0,\n        \"memory\": 33604804608,\n        \"distances\": [\n          10,\n          11\n        ],\n        \"hugepages\": null,\n        \"cores\": [\n          {\n            \"core_id\": 0,\n            \"thread_ids\": [\n              0,\n              1\n            ],\n            \"caches\": [\n              {\n                \"id\": 0,\n                \"size\": 32768,\n                \"type\": \"unified\",\n                \"level\": 2\n              }\n            ],\n            \"uncore_caches\": null,\n            \"socket_id\": 0\n          }\n        ],\n        \"caches\": null\n      },\n      {\n        \"node_id\": 1,\n        \"memory\": 33604804608,\n        \"hugepages\": null,\n        \"distances\": [\n          11,\n          10\n        ],\n        \"cores\": [\n          {\n            \"core_id\": 1,\n            \"thread_ids\": [\n              2,\n              3\n            ],\n            \"caches\": [\n              {\n                \"id\": 0,\n                \"size\": 32768,\n                \"type\": \"unified\",\n                \"level\": 2\n              }\n            ],\n            \"uncore_caches\": null,\n            \"socket_id\": 1\n          }\n        ],\n        \"caches\": null\n      }\n    ]`\n\tassert.JSONEq(t, expectedNodes, string(nodesJSON))\n}\n\nfunc TestGetNodesInfoWithoutNodes(t *testing.T) {\n\tfakeSys := &fakesysfs.FakeSysFs{}\n\n\tc := sysfs.CacheInfo{\n\t\tId:    0,\n\t\tSize:  32 * 1024,\n\t\tType:  \"unified\",\n\t\tLevel: 1,\n\t\tCpus:  2,\n\t}\n\tfakeSys.SetCacheInfo(c)\n\n\tnodesPaths := []string{}\n\tfakeSys.SetNodesPaths(nodesPaths, nil)\n\n\tcpusPaths := map[string][]string{\n\t\tcpusPath: {\n\t\t\tcpusPath + \"/cpu0\",\n\t\t\tcpusPath + \"/cpu1\",\n\t\t\tcpusPath + \"/cpu2\",\n\t\t\tcpusPath + \"/cpu3\",\n\t\t},\n\t}\n\tfakeSys.SetCPUsPaths(cpusPaths, nil)\n\n\tcoreThread := map[string]string{\n\t\tcpusPath + \"/cpu0\": \"0\",\n\t\tcpusPath + \"/cpu1\": \"0\",\n\t\tcpusPath + \"/cpu2\": \"1\",\n\t\tcpusPath + \"/cpu3\": \"1\",\n\t}\n\tfakeSys.SetCoreThreads(coreThread, nil)\n\n\tphysicalPackageIDs := map[string]string{\n\t\t\"/sys/devices/system/cpu/cpu0\": \"0\",\n\t\t\"/sys/devices/system/cpu/cpu1\": \"0\",\n\t\t\"/sys/devices/system/cpu/cpu2\": \"1\",\n\t\t\"/sys/devices/system/cpu/cpu3\": \"1\",\n\t}\n\tfakeSys.SetPhysicalPackageIDs(physicalPackageIDs, nil)\n\n\tnodes, cores, err := GetNodesInfo(fakeSys)\n\tassert.Nil(t, err)\n\tassert.Equal(t, 2, len(nodes))\n\tassert.Equal(t, 4, cores)\n\n\tsort.Slice(nodes, func(i, j int) bool {\n\t\treturn nodes[i].Id < nodes[j].Id\n\t})\n\n\tnodesJSON, err := json.Marshal(nodes)\n\tassert.Nil(t, err)\n\n\texpectedNodes := `[\n\t\t{\n\t\t\t\"node_id\":0,\n\t\t\t\"memory\":0,\n            \"distances\": null,\n\t\t\t\"hugepages\":null,\n\t\t\t\"cores\":[\n\t\t\t   {\n\t\t\t\t  \"core_id\":0,\n\t\t\t\t  \"thread_ids\":[\n\t\t\t\t\t 0,\n\t\t\t\t\t 1\n\t\t\t\t  ],\n\t\t\t\t  \"caches\":[\n\t\t\t\t\t {\n\t\t\t\t\t\t\"id\": 0,\n\t\t\t\t\t\t\"size\":32768,\n\t\t\t\t\t\t\"type\":\"unified\",\n\t\t\t\t\t\t\"level\":1\n\t\t\t\t\t }\n\t\t\t\t  ],\n\t\t\t\t  \"socket_id\": 0,\n\t\t\t\t  \"uncore_caches\": null\n\t\t\t   }\n\t\t\t],\n\t\t\t\"caches\":null\n\t\t },\n\t\t {\n\t\t\t\"node_id\":1,\n\t\t\t\"memory\":0,\n            \"distances\": null,\n\t\t\t\"hugepages\":null,\n\t\t\t\"cores\":[\n\t\t\t   {\n\t\t\t\t  \"core_id\":1,\n\t\t\t\t  \"thread_ids\":[\n\t\t\t\t\t 2,\n\t\t\t\t\t 3\n\t\t\t\t  ],\n\t\t\t\t  \"caches\":[\n\t\t\t\t\t {\n\t\t\t\t\t\t\"id\": 0,\n\t\t\t\t\t\t\"size\":32768,\n\t\t\t\t\t\t\"type\":\"unified\",\n\t\t\t\t\t\t\"level\":1\n\t\t\t\t\t }\n\t\t\t\t  ],\n\t\t\t\t  \"uncore_caches\": null,\n\t\t\t\t  \"socket_id\": 1\n\t\t\t   }\n\t\t\t],\n\t\t\t\"caches\":null\n\t\t }\n\t]`\n\tassert.JSONEq(t, expectedNodes, string(nodesJSON))\n}\n\nfunc TestGetNodesInfoWithoutNodesWhenPhysicalPackageIDMissingForOneCPU(t *testing.T) {\n\tfakeSys := &fakesysfs.FakeSysFs{}\n\n\tnodesPaths := []string{}\n\tfakeSys.SetNodesPaths(nodesPaths, nil)\n\n\tcpusPaths := map[string][]string{\n\t\tcpusPath: {\n\t\t\tcpusPath + \"/cpu0\",\n\t\t\tcpusPath + \"/cpu1\",\n\t\t},\n\t}\n\tfakeSys.SetCPUsPaths(cpusPaths, nil)\n\n\tcoreThread := map[string]string{\n\t\tcpusPath + \"/cpu0\": \"0\",\n\t\tcpusPath + \"/cpu1\": \"0\",\n\t}\n\n\tcoreThreadErrors := map[string]error{\n\t\tcpusPath + \"/cpu0\": nil,\n\t\tcpusPath + \"/cpu1\": nil,\n\t}\n\tfakeSys.SetCoreThreads(coreThread, coreThreadErrors)\n\n\tphysicalPackageIDs := map[string]string{\n\t\tcpusPath + \"/cpu0\": \"0\",\n\t\tcpusPath + \"/cpu1\": \"0\",\n\t}\n\n\tphysicalPackageIDErrors := map[string]error{\n\t\tcpusPath + \"/cpu0\": nil,\n\t\tcpusPath + \"/cpu1\": os.ErrNotExist,\n\t}\n\tfakeSys.SetPhysicalPackageIDs(physicalPackageIDs, physicalPackageIDErrors)\n\n\tnodes, cores, err := GetNodesInfo(fakeSys)\n\tassert.Nil(t, err)\n\tassert.Equal(t, 1, len(nodes))\n\tassert.Equal(t, 2, cores)\n\n\tsort.Slice(nodes, func(i, j int) bool {\n\t\treturn nodes[i].Id < nodes[j].Id\n\t})\n\n\tnodesJSON, err := json.Marshal(nodes)\n\tassert.Nil(t, err)\n\n\tfmt.Println(string(nodesJSON))\n\n\texpectedNodes := `[\n\t\t{\n\t\t\t\"node_id\":0,\n\t\t\t\"memory\":0,\n            \"distances\": null,\n\t\t\t\"hugepages\":null,\n\t\t\t\"cores\":[\n\t\t\t   {\n\t\t\t\t  \"core_id\":0,\n\t\t\t\t  \"thread_ids\":[\n\t\t\t\t\t 0\n\t\t\t\t  ],\n\t\t\t\t  \"caches\": null,\n\t\t\t\t  \"socket_id\": 0,\n\t\t\t\t  \"uncore_caches\": null\n\t\t\t   }\n\t\t\t],\n\t\t\t\"caches\":null\n\t\t}\n\t]`\n\tassert.JSONEq(t, expectedNodes, string(nodesJSON))\n}\n\nfunc TestGetNodesInfoWithoutNodesWhenPhysicalPackageIDMissing(t *testing.T) {\n\tfakeSys := &fakesysfs.FakeSysFs{}\n\n\tnodesPaths := []string{}\n\tfakeSys.SetNodesPaths(nodesPaths, nil)\n\n\tcpusPaths := map[string][]string{\n\t\tcpusPath: {\n\t\t\tcpusPath + \"/cpu0\",\n\t\t\tcpusPath + \"/cpu1\",\n\t\t},\n\t}\n\tfakeSys.SetCPUsPaths(cpusPaths, nil)\n\n\tcoreThread := map[string]string{\n\t\tcpusPath + \"/cpu0\": \"0\",\n\t\tcpusPath + \"/cpu1\": \"0\",\n\t}\n\n\tcoreThreadErrors := map[string]error{\n\t\tcpusPath + \"/cpu0\": nil,\n\t\tcpusPath + \"/cpu1\": nil,\n\t}\n\tfakeSys.SetCoreThreads(coreThread, coreThreadErrors)\n\n\tphysicalPackageIDs := map[string]string{\n\t\tcpusPath + \"/cpu0\": \"0\",\n\t\tcpusPath + \"/cpu1\": \"0\",\n\t}\n\n\tphysicalPackageIDErrors := map[string]error{\n\t\tcpusPath + \"/cpu0\": os.ErrNotExist,\n\t\tcpusPath + \"/cpu1\": os.ErrNotExist,\n\t}\n\tfakeSys.SetPhysicalPackageIDs(physicalPackageIDs, physicalPackageIDErrors)\n\n\tnodes, cores, err := GetNodesInfo(fakeSys)\n\tassert.Nil(t, err)\n\tassert.Equal(t, 0, len(nodes))\n\tassert.Equal(t, 2, cores)\n}\n\nfunc TestGetNodesWhenTopologyDirMissingForOneCPU(t *testing.T) {\n\t/*\n\t\tUnit test for case in which:\n\t\t- there are two cpus (cpu0 and cpu1) in /sys/devices/system/node/node0/ and /sys/devices/system/cpu\n\t\t- topology directory is missing for cpu1 but it exists for cpu0\n\t*/\n\tfakeSys := &fakesysfs.FakeSysFs{}\n\n\tnodesPaths := []string{\n\t\t\"/fakeSysfs/devices/system/node/node0\",\n\t}\n\tfakeSys.SetNodesPaths(nodesPaths, nil)\n\n\tcpusPaths := map[string][]string{\n\t\t\"/fakeSysfs/devices/system/node/node0\": {\n\t\t\t\"/fakeSysfs/devices/system/node/node0/cpu0\",\n\t\t\t\"/fakeSysfs/devices/system/node/node0/cpu1\",\n\t\t},\n\t}\n\tfakeSys.SetCPUsPaths(cpusPaths, nil)\n\n\tcoreThread := map[string]string{\n\t\t\"/fakeSysfs/devices/system/node/node0/cpu0\": \"0\",\n\t\t\"/fakeSysfs/devices/system/node/node0/cpu1\": \"0\",\n\t}\n\n\tcoreThreadErrors := map[string]error{\n\t\t\"/fakeSysfs/devices/system/node/node0/cpu0\": nil,\n\t\t\"/fakeSysfs/devices/system/node/node0/cpu1\": os.ErrNotExist,\n\t}\n\tfakeSys.SetCoreThreads(coreThread, coreThreadErrors)\n\n\tmemTotal := \"MemTotal:       32817192 kB\"\n\tfakeSys.SetMemory(memTotal, nil)\n\n\thugePages := []os.FileInfo{\n\t\t&fakesysfs.FileInfo{EntryName: \"hugepages-2048kB\"},\n\t}\n\tfakeSys.SetHugePages(hugePages, nil)\n\n\thugePageNr := map[string]string{\n\t\t\"/fakeSysfs/devices/system/node/node0/hugepages/hugepages-2048kB/nr_hugepages\": \"1\",\n\t}\n\tfakeSys.SetHugePagesNr(hugePageNr, nil)\n\n\tphysicalPackageIDs := map[string]string{\n\t\t\"/fakeSysfs/devices/system/node/node0/cpu0\": \"0\",\n\t\t\"/fakeSysfs/devices/system/node/node0/cpu1\": \"0\",\n\t}\n\n\tphysicalPackageIDErrors := map[string]error{\n\t\t\"/fakeSysfs/devices/system/node/node0/cpu0\": nil,\n\t\t\"/fakeSysfs/devices/system/node/node0/cpu1\": os.ErrNotExist,\n\t}\n\n\tfakeSys.SetPhysicalPackageIDs(physicalPackageIDs, physicalPackageIDErrors)\n\n\tfakeSys.SetDistances(\"/fakeSysfs/devices/system/node/node0\", \"10\", nil)\n\n\tnodes, cores, err := GetNodesInfo(fakeSys)\n\tassert.Nil(t, err)\n\n\tassert.Equal(t, 1, len(nodes))\n\tassert.Equal(t, 1, cores)\n\n\tsort.Slice(nodes, func(i, j int) bool {\n\t\treturn nodes[i].Id < nodes[j].Id\n\t})\n\n\tnodesJSON, err := json.Marshal(nodes)\n\tassert.Nil(t, err)\n\n\texpectedNodes := `[\n\t\t{\n\t\t   \"node_id\":0,\n\t\t   \"memory\":33604804608,\n           \"distances\" : [\n             10\n           ],\n\t\t   \"hugepages\":[\n\t\t\t  {\n\t\t\t\t \"page_size\":2048,\n\t\t\t\t \"num_pages\":1\n\t\t\t  }\n\t\t   ],\n\t\t   \"cores\":[\n\t\t\t  {\n\t\t\t\t \"core_id\":0,\n\t\t\t\t \"thread_ids\":[\n\t\t\t\t\t0\n\t\t\t\t ],\n\t\t\t\t \"caches\":null,\n\t\t\t\t \"socket_id\":0,\n\t\t\t\t \"uncore_caches\":null\n\t\t\t  }\n\t\t   ],\n\t\t   \"caches\": null\n\t\t}\n\t ]`\n\tassert.JSONEq(t, expectedNodes, string(nodesJSON))\n}\n\nfunc TestGetNodesWhenPhysicalPackageIDMissingForOneCPU(t *testing.T) {\n\tfakeSys := &fakesysfs.FakeSysFs{}\n\n\tnodesPaths := []string{\n\t\t\"/fakeSysfs/devices/system/node/node0\",\n\t}\n\tfakeSys.SetNodesPaths(nodesPaths, nil)\n\n\tcpusPaths := map[string][]string{\n\t\t\"/fakeSysfs/devices/system/node/node0\": {\n\t\t\t\"/fakeSysfs/devices/system/node/node0/cpu0\",\n\t\t\t\"/fakeSysfs/devices/system/node/node0/cpu1\",\n\t\t},\n\t}\n\tfakeSys.SetCPUsPaths(cpusPaths, nil)\n\n\tcoreThread := map[string]string{\n\t\t\"/fakeSysfs/devices/system/node/node0/cpu0\": \"0\",\n\t\t\"/fakeSysfs/devices/system/node/node0/cpu1\": \"0\",\n\t}\n\n\tcoreThreadErrors := map[string]error{\n\t\t\"/fakeSysfs/devices/system/node/node0/cpu0\": nil,\n\t\t\"/fakeSysfs/devices/system/node/node0/cpu1\": nil,\n\t}\n\tfakeSys.SetCoreThreads(coreThread, coreThreadErrors)\n\n\tmemTotal := \"MemTotal:       32817192 kB\"\n\tfakeSys.SetMemory(memTotal, nil)\n\n\thugePages := []os.FileInfo{\n\t\t&fakesysfs.FileInfo{EntryName: \"hugepages-2048kB\"},\n\t}\n\tfakeSys.SetHugePages(hugePages, nil)\n\n\thugePageNr := map[string]string{\n\t\t\"/fakeSysfs/devices/system/node/node0/hugepages/hugepages-2048kB/nr_hugepages\": \"1\",\n\t}\n\tfakeSys.SetHugePagesNr(hugePageNr, nil)\n\n\tphysicalPackageIDs := map[string]string{\n\t\t\"/fakeSysfs/devices/system/node/node0/cpu0\": \"0\",\n\t\t\"/fakeSysfs/devices/system/node/node0/cpu1\": \"0\",\n\t}\n\n\tphysicalPackageIDErrors := map[string]error{\n\t\t\"/fakeSysfs/devices/system/node/node0/cpu0\": nil,\n\t\t\"/fakeSysfs/devices/system/node/node0/cpu1\": os.ErrNotExist,\n\t}\n\n\tfakeSys.SetPhysicalPackageIDs(physicalPackageIDs, physicalPackageIDErrors)\n\n\tfakeSys.SetDistances(\"/fakeSysfs/devices/system/node/node0\", \"10\", nil)\n\n\tnodes, cores, err := GetNodesInfo(fakeSys)\n\tassert.Nil(t, err)\n\n\tassert.Equal(t, 1, len(nodes))\n\tassert.Equal(t, 1, cores)\n\n\tsort.Slice(nodes, func(i, j int) bool {\n\t\treturn nodes[i].Id < nodes[j].Id\n\t})\n\n\tnodesJSON, err := json.Marshal(nodes)\n\tassert.Nil(t, err)\n\n\texpectedNodes := `[\n\t\t{\n\t\t   \"node_id\":0,\n\t\t   \"memory\":33604804608,\n           \"distances\" : [\n             10\n           ],\n\t\t   \"hugepages\":[\n\t\t\t  {\n\t\t\t\t \"page_size\":2048,\n\t\t\t\t \"num_pages\":1\n\t\t\t  }\n\t\t   ],\n\t\t   \"cores\":[\n\t\t\t  {\n\t\t\t\t \"core_id\":0,\n\t\t\t\t \"thread_ids\":[\n\t\t\t\t\t0\n\t\t\t\t ],\n\t\t\t\t \"caches\":null,\n\t\t\t\t \"socket_id\":0,\n\t\t\t\t \"uncore_caches\": null\n\t\t\t  }\n\t\t   ],\n\t\t   \"caches\": null\n\t\t}\n\t ]`\n\tassert.JSONEq(t, expectedNodes, string(nodesJSON))\n}\n\nfunc TestGetNodeMemInfo(t *testing.T) {\n\tfakeSys := &fakesysfs.FakeSysFs{}\n\tmemTotal := \"MemTotal:       32817192 kB\"\n\tfakeSys.SetMemory(memTotal, nil)\n\n\tmem, err := getNodeMemInfo(fakeSys, \"/fakeSysfs/devices/system/node/node0\")\n\tassert.Nil(t, err)\n\tassert.Equal(t, uint64(32817192*1024), mem)\n}\n\nfunc TestGetNodeMemInfoWithMissingMemTotaInMemInfo(t *testing.T) {\n\tfakeSys := &fakesysfs.FakeSysFs{}\n\tmemTotal := \"MemXXX:       32817192 kB\"\n\tfakeSys.SetMemory(memTotal, nil)\n\n\tmem, err := getNodeMemInfo(fakeSys, \"/fakeSysfs/devices/system/node/node0\")\n\tassert.NotNil(t, err)\n\tassert.Equal(t, uint64(0), mem)\n}\n\nfunc TestGetNodeMemInfoWhenMemInfoMissing(t *testing.T) {\n\tfakeSys := &fakesysfs.FakeSysFs{}\n\tmemTotal := \"\"\n\tfakeSys.SetMemory(memTotal, fmt.Errorf(\"Cannot read meminfo file\"))\n\n\tmem, err := getNodeMemInfo(fakeSys, \"/fakeSysfs/devices/system/node/node0\")\n\tassert.Nil(t, err)\n\tassert.Equal(t, uint64(0), mem)\n}\n\nfunc TestGetCoresInfoWhenCoreIDIsNotDigit(t *testing.T) {\n\tsysFs := &fakesysfs.FakeSysFs{}\n\tnodesPaths := []string{\n\t\t\"/fakeSysfs/devices/system/node/node0\",\n\t}\n\tsysFs.SetNodesPaths(nodesPaths, nil)\n\n\tcpusPaths := map[string][]string{\n\t\t\"/fakeSysfs/devices/system/node/node0\": {\n\t\t\t\"/fakeSysfs/devices/system/node/node0/cpu0\",\n\t\t},\n\t}\n\tsysFs.SetCPUsPaths(cpusPaths, nil)\n\n\tcoreThread := map[string]string{\n\t\t\"/fakeSysfs/devices/system/node/node0/cpu0\": \"abc\",\n\t}\n\tsysFs.SetCoreThreads(coreThread, nil)\n\n\tcores, err := getCoresInfo(sysFs, []string{\"/fakeSysfs/devices/system/node/node0/cpu0\"})\n\tassert.NotNil(t, err)\n\tassert.Equal(t, []info.Core(nil), cores)\n}\n\nfunc TestGetCoresInfoWithOnlineOfflineFile(t *testing.T) {\n\tsysFs := &fakesysfs.FakeSysFs{}\n\tnodesPaths := []string{\n\t\t\"/fakeSysfs/devices/system/node/node0\",\n\t}\n\tsysFs.SetNodesPaths(nodesPaths, nil)\n\n\tcpusPaths := map[string][]string{\n\t\t\"/fakeSysfs/devices/system/node/node0\": {\n\t\t\t\"/fakeSysfs/devices/system/node/node0/cpu0\",\n\t\t\t\"/fakeSysfs/devices/system/node/node0/cpu1\",\n\t\t},\n\t}\n\tsysFs.SetCPUsPaths(cpusPaths, nil)\n\n\tcoreThread := map[string]string{\n\t\t\"/fakeSysfs/devices/system/node/node0/cpu0\": \"0\",\n\t\t\"/fakeSysfs/devices/system/node/node0/cpu1\": \"0\",\n\t}\n\tsysFs.SetCoreThreads(coreThread, nil)\n\tsysFs.SetOnlineCPUs(map[string]interface{}{\"/fakeSysfs/devices/system/node/node0/cpu0\": nil})\n\tsysFs.SetPhysicalPackageIDs(map[string]string{\n\t\t\"/fakeSysfs/devices/system/node/node0/cpu0\": \"0\",\n\t\t\"/fakeSysfs/devices/system/node/node0/cpu1\": \"0\",\n\t}, nil)\n\n\tcores, err := getCoresInfo(\n\t\tsysFs,\n\t\t[]string{\"/fakeSysfs/devices/system/node/node0/cpu0\", \"/fakeSysfs/devices/system/node/node0/cpu1\"},\n\t)\n\tassert.NoError(t, err)\n\texpected := []info.Core{\n\t\t{\n\t\t\tId:       0,\n\t\t\tThreads:  []int{0},\n\t\t\tCaches:   nil,\n\t\t\tSocketID: 0,\n\t\t},\n\t}\n\tassert.Equal(t, expected, cores)\n}\n\nfunc TestGetBlockDeviceInfo(t *testing.T) {\n\tfakeSys := fakesysfs.FakeSysFs{}\n\tdisks, err := GetBlockDeviceInfo(&fakeSys)\n\tif err != nil {\n\t\tt.Errorf(\"expected call to GetBlockDeviceInfo() to succeed. Failed with %s\", err)\n\t}\n\tif len(disks) != 1 {\n\t\tt.Errorf(\"expected to get one disk entry. Got %d\", len(disks))\n\t}\n\tkey := \"8:0\"\n\tdisk, ok := disks[key]\n\tif !ok {\n\t\tt.Fatalf(\"expected key 8:0 to exist in the disk map.\")\n\t}\n\tif disk.Name != \"sda\" {\n\t\tt.Errorf(\"expected to get disk named sda. Got %q\", disk.Name)\n\t}\n\tsize := uint64(1234567 * 512)\n\tif disk.Size != size {\n\t\tt.Errorf(\"expected to get disk size of %d. Got %d\", size, disk.Size)\n\t}\n\tif disk.Scheduler != \"cfq\" {\n\t\tt.Errorf(\"expected to get scheduler type of cfq. Got %q\", disk.Scheduler)\n\t}\n}\n\nfunc TestGetNetworkDevices(t *testing.T) {\n\tfakeSys := fakesysfs.FakeSysFs{}\n\tfakeSys.SetEntryName(\"eth0\")\n\tdevs, err := GetNetworkDevices(&fakeSys)\n\tif err != nil {\n\t\tt.Errorf(\"expected call to GetNetworkDevices() to succeed. Failed with %s\", err)\n\t}\n\tif len(devs) != 1 {\n\t\tt.Errorf(\"expected to get one network device. Got %d\", len(devs))\n\t}\n\teth := devs[0]\n\tif eth.Name != \"eth0\" {\n\t\tt.Errorf(\"expected to find device with name eth0. Found name %q\", eth.Name)\n\t}\n\tif eth.Mtu != 1024 {\n\t\tt.Errorf(\"expected mtu to be set to 1024. Found %d\", eth.Mtu)\n\t}\n\tif eth.Speed != 1000 {\n\t\tt.Errorf(\"expected device speed to be set to 1000. Found %d\", eth.Speed)\n\t}\n\tif eth.MacAddress != \"42:01:02:03:04:f4\" {\n\t\tt.Errorf(\"expected mac address to be '42:01:02:03:04:f4'. Found %q\", eth.MacAddress)\n\t}\n}\n\nfunc TestIgnoredNetworkDevices(t *testing.T) {\n\tfakeSys := fakesysfs.FakeSysFs{}\n\tignoredDevices := []string{\"veth1234\", \"lo\", \"docker0\", \"nerdctl0\"}\n\tfor _, name := range ignoredDevices {\n\t\tfakeSys.SetEntryName(name)\n\t\tdevs, err := GetNetworkDevices(&fakeSys)\n\t\tif err != nil {\n\t\t\tt.Errorf(\"expected call to GetNetworkDevices() to succeed. Failed with %s\", err)\n\t\t}\n\t\tif len(devs) != 0 {\n\t\t\tt.Errorf(\"expected dev %s to be ignored, but got info %+v\", name, devs)\n\t\t}\n\t}\n}\n\nfunc TestGetCacheInfo(t *testing.T) {\n\tfakeSys := &fakesysfs.FakeSysFs{}\n\tcacheInfo := sysfs.CacheInfo{\n\t\tId:    0,\n\t\tSize:  1024,\n\t\tType:  \"Data\",\n\t\tLevel: 3,\n\t\tCpus:  16,\n\t}\n\tfakeSys.SetCacheInfo(cacheInfo)\n\tcaches, err := GetCacheInfo(fakeSys, 0)\n\tif err != nil {\n\t\tt.Errorf(\"expected call to GetCacheInfo() to succeed. Failed with %s\", err)\n\t}\n\tif len(caches) != 1 {\n\t\tt.Errorf(\"expected to get one cache. Got %d\", len(caches))\n\t}\n\tif caches[0] != cacheInfo {\n\t\tt.Errorf(\"expected to find cacheinfo %+v. Got %+v\", cacheInfo, caches[0])\n\t}\n}\n\nfunc TestGetNetworkStats(t *testing.T) {\n\texpectedStats := info.InterfaceStats{\n\t\tName:      \"eth0\",\n\t\tRxBytes:   1024,\n\t\tRxPackets: 1024,\n\t\tRxErrors:  1024,\n\t\tRxDropped: 1024,\n\t\tTxBytes:   1024,\n\t\tTxPackets: 1024,\n\t\tTxErrors:  1024,\n\t\tTxDropped: 1024,\n\t}\n\tfakeSys := &fakesysfs.FakeSysFs{}\n\tnetStats, err := getNetworkStats(\"eth0\", fakeSys)\n\tif err != nil {\n\t\tt.Errorf(\"call to getNetworkStats() failed with %s\", err)\n\t}\n\tif expectedStats != netStats {\n\t\tt.Errorf(\"expected to get stats %+v, got %+v\", expectedStats, netStats)\n\t}\n}\n\nfunc TestGetSocketFromCPU(t *testing.T) {\n\ttopology := []info.Node{\n\t\t{\n\t\t\tId:        0,\n\t\t\tMemory:    0,\n\t\t\tHugePages: nil,\n\t\t\tCores: []info.Core{\n\t\t\t\t{\n\t\t\t\t\tId:       0,\n\t\t\t\t\tThreads:  []int{0, 1},\n\t\t\t\t\tCaches:   nil,\n\t\t\t\t\tSocketID: 0,\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tId:       1,\n\t\t\t\t\tThreads:  []int{2, 3},\n\t\t\t\t\tCaches:   nil,\n\t\t\t\t\tSocketID: 0,\n\t\t\t\t},\n\t\t\t},\n\t\t\tCaches: nil,\n\t\t},\n\t\t{\n\t\t\tId:        1,\n\t\t\tMemory:    0,\n\t\t\tHugePages: nil,\n\t\t\tCores: []info.Core{\n\t\t\t\t{\n\t\t\t\t\tId:       0,\n\t\t\t\t\tThreads:  []int{4, 5},\n\t\t\t\t\tCaches:   nil,\n\t\t\t\t\tSocketID: 1,\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tId:       1,\n\t\t\t\t\tThreads:  []int{6, 7},\n\t\t\t\t\tCaches:   nil,\n\t\t\t\t\tSocketID: 1,\n\t\t\t\t},\n\t\t\t},\n\t\t\tCaches: nil,\n\t\t},\n\t}\n\tsocket := GetSocketFromCPU(topology, 6)\n\tassert.Equal(t, socket, 1)\n\n\t// Check if return \"-1\" when there is no data about passed CPU.\n\tsocket = GetSocketFromCPU(topology, 8)\n\tassert.Equal(t, socket, -1)\n}\n\nfunc TestGetOnlineCPUs(t *testing.T) {\n\ttopology := []info.Node{\n\t\t{\n\t\t\tId:        0,\n\t\t\tMemory:    0,\n\t\t\tHugePages: nil,\n\t\t\tCores: []info.Core{\n\t\t\t\t{\n\t\t\t\t\tId:       0,\n\t\t\t\t\tThreads:  []int{0, 1},\n\t\t\t\t\tCaches:   nil,\n\t\t\t\t\tSocketID: 0,\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tId:       1,\n\t\t\t\t\tThreads:  []int{2, 3},\n\t\t\t\t\tCaches:   nil,\n\t\t\t\t\tSocketID: 0,\n\t\t\t\t},\n\t\t\t},\n\t\t\tCaches: nil,\n\t\t},\n\t\t{\n\t\t\tId:        1,\n\t\t\tMemory:    0,\n\t\t\tHugePages: nil,\n\t\t\tCores: []info.Core{\n\t\t\t\t{\n\t\t\t\t\tId:       0,\n\t\t\t\t\tThreads:  []int{4, 5},\n\t\t\t\t\tCaches:   nil,\n\t\t\t\t\tSocketID: 1,\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tId:       1,\n\t\t\t\t\tThreads:  []int{6, 7},\n\t\t\t\t\tCaches:   nil,\n\t\t\t\t\tSocketID: 1,\n\t\t\t\t},\n\t\t\t},\n\t\t\tCaches: nil,\n\t\t},\n\t}\n\tonlineCPUs := GetOnlineCPUs(topology)\n\tassert.Equal(t, onlineCPUs, []int{0, 1, 2, 3, 4, 5, 6, 7})\n}\n\nfunc TestGetNodesInfoWithUncoreCacheInfo(t *testing.T) {\n\tfakeSys := &fakesysfs.FakeSysFs{}\n\tc := sysfs.CacheInfo{\n\t\tId:    0,\n\t\tSize:  32 * 1024,\n\t\tType:  \"unified\",\n\t\tLevel: 3,\n\t\tCpus:  8,\n\t}\n\tfakeSys.SetCacheInfo(c)\n\n\tnodesPaths := []string{\n\t\t\"/fakeSysfs/devices/system/node/node0\",\n\t\t\"/fakeSysfs/devices/system/node/node1\",\n\t}\n\tfakeSys.SetNodesPaths(nodesPaths, nil)\n\n\tmemTotal := \"MemTotal:       32817192 kB\"\n\tfakeSys.SetMemory(memTotal, nil)\n\n\tcpusPaths := map[string][]string{\n\t\t\"/fakeSysfs/devices/system/node/node0\": {\n\t\t\t\"/fakeSysfs/devices/system/node/node0/cpu0\",\n\t\t\t\"/fakeSysfs/devices/system/node/node0/cpu1\",\n\t\t},\n\t\t\"/fakeSysfs/devices/system/node/node1\": {\n\t\t\t\"/fakeSysfs/devices/system/node/node0/cpu2\",\n\t\t\t\"/fakeSysfs/devices/system/node/node0/cpu3\",\n\t\t},\n\t}\n\tfakeSys.SetCPUsPaths(cpusPaths, nil)\n\n\tcoreThread := map[string]string{\n\t\t\"/fakeSysfs/devices/system/node/node0/cpu0\": \"0\",\n\t\t\"/fakeSysfs/devices/system/node/node0/cpu1\": \"0\",\n\t\t\"/fakeSysfs/devices/system/node/node0/cpu2\": \"1\",\n\t\t\"/fakeSysfs/devices/system/node/node0/cpu3\": \"1\",\n\t}\n\tfakeSys.SetCoreThreads(coreThread, nil)\n\tphysicalPackageIDs := map[string]string{\n\t\t\"/fakeSysfs/devices/system/node/node0/cpu0\": \"0\",\n\t\t\"/fakeSysfs/devices/system/node/node0/cpu1\": \"0\",\n\t\t\"/fakeSysfs/devices/system/node/node0/cpu2\": \"1\",\n\t\t\"/fakeSysfs/devices/system/node/node0/cpu3\": \"1\",\n\t}\n\tfakeSys.SetPhysicalPackageIDs(physicalPackageIDs, nil)\n\n\tfakeSys.SetDistances(\"/fakeSysfs/devices/system/node/node0\", \"10 11\", nil)\n\tfakeSys.SetDistances(\"/fakeSysfs/devices/system/node/node1\", \"11 10\", nil)\n\n\tnodes, cores, err := GetNodesInfo(fakeSys)\n\tassert.Nil(t, err)\n\tfmt.Println(err)\n\tassert.Equal(t, 2, len(nodes))\n\tassert.Equal(t, 4, cores)\n\n\tnodesJSON, err := json.Marshal(nodes)\n\tassert.Nil(t, err)\n\texpectedNodes := `\n\t[\n      {\n        \"node_id\": 0,\n        \"memory\": 33604804608,\n        \"distances\" : [\n          10,\n          11\n        ],\n        \"hugepages\": null,\n        \"cores\": [\n          {\n            \"core_id\": 0,\n            \"thread_ids\": [\n              0,\n              1\n            ],\n            \"caches\": null,\n            \"uncore_caches\": [\n                {\n                  \"id\": 0,\n                  \"size\": 32768,\n                  \"type\": \"unified\",\n                  \"level\": 3\n                }\n            ],\n            \"socket_id\": 0\n          }\n        ],\n        \"caches\": null\n      },\n      {\n        \"node_id\": 1,\n        \"memory\": 33604804608,\n        \"distances\" : [\n          11,\n          10\n        ],\n        \"hugepages\": null,\n        \"cores\": [\n          {\n            \"core_id\": 1,\n            \"thread_ids\": [\n              2,\n              3\n            ],\n            \"caches\": null,\n            \"uncore_caches\": [\n                {\n                  \"id\": 0,\n                  \"size\": 32768,\n                  \"type\": \"unified\",\n                  \"level\": 3\n                }\n            ],\n            \"socket_id\": 1\n          }\n        ],\n        \"caches\": null\n      }\n    ]`\n\tassert.JSONEq(t, expectedNodes, string(nodesJSON))\n}\n\nfunc TestGetDistances(t *testing.T) {\n\tfakeSys := &fakesysfs.FakeSysFs{}\n\tnode := \"/fakeSysfs/devices/system/node/node0\"\n\tfakeSys.SetDistances(node, \"10 11\", nil)\n\n\tdistances, err := getDistances(fakeSys, node)\n\tassert.Nil(t, err)\n\tassert.Len(t, distances, 2)\n\tassert.Equal(t, uint64(10), distances[0])\n\tassert.Equal(t, uint64(11), distances[1])\n}\n\nfunc TestGetDistancesMissingDistances(t *testing.T) {\n\tfakeSys := &fakesysfs.FakeSysFs{}\n\tnode := \"/fakeSysfs/devices/system/node/node0\"\n\tfakeSys.SetDistances(node, \"10 11\", fmt.Errorf(\"no distances file\"))\n\n\tdistances, err := getDistances(fakeSys, node)\n\tassert.Nil(t, err)\n\tassert.Len(t, distances, 0)\n}\n"
  },
  {
    "path": "utils/timed_store.go",
    "content": "// Copyright 2014 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage utils\n\nimport (\n\t\"sort\"\n\t\"time\"\n)\n\ntype timedStoreDataSlice []timedStoreData\n\nfunc (t timedStoreDataSlice) Less(i, j int) bool {\n\treturn t[i].timestamp.Before(t[j].timestamp)\n}\n\nfunc (t timedStoreDataSlice) Len() int {\n\treturn len(t)\n}\n\nfunc (t timedStoreDataSlice) Swap(i, j int) {\n\tt[i], t[j] = t[j], t[i]\n}\n\n// A time-based buffer for ContainerStats.\n// Holds information for a specific time period and/or a max number of items.\ntype TimedStore struct {\n\tbuffer   timedStoreDataSlice\n\tage      time.Duration\n\tmaxItems int\n}\n\ntype timedStoreData struct {\n\ttimestamp time.Time\n\tdata      interface{}\n}\n\n// Returns a new thread-compatible TimedStore.\n// A maxItems value of -1 means no limit.\nfunc NewTimedStore(age time.Duration, maxItems int) *TimedStore {\n\treturn &TimedStore{\n\t\tbuffer:   make(timedStoreDataSlice, 0),\n\t\tage:      age,\n\t\tmaxItems: maxItems,\n\t}\n}\n\n// Adds an element to the start of the buffer (removing one from the end if necessary).\nfunc (s *TimedStore) Add(timestamp time.Time, item interface{}) {\n\tdata := timedStoreData{\n\t\ttimestamp: timestamp,\n\t\tdata:      item,\n\t}\n\t// Common case: data is added in order.\n\tif len(s.buffer) == 0 || !timestamp.Before(s.buffer[len(s.buffer)-1].timestamp) {\n\t\ts.buffer = append(s.buffer, data)\n\t} else {\n\t\t// Data is out of order; insert it in the correct position.\n\t\tindex := sort.Search(len(s.buffer), func(index int) bool {\n\t\t\treturn s.buffer[index].timestamp.After(timestamp)\n\t\t})\n\t\ts.buffer = append(s.buffer, timedStoreData{}) // Make room to shift the elements\n\t\tcopy(s.buffer[index+1:], s.buffer[index:])    // Shift the elements over\n\t\ts.buffer[index] = data\n\t}\n\n\t// Remove any elements before eviction time.\n\t// TODO(rjnagal): This is assuming that the added entry has timestamp close to now.\n\tevictTime := timestamp.Add(-s.age)\n\tindex := sort.Search(len(s.buffer), func(index int) bool {\n\t\treturn s.buffer[index].timestamp.After(evictTime)\n\t})\n\tif index < len(s.buffer) {\n\t\ts.buffer = s.buffer[index:]\n\t}\n\n\t// Remove any elements if over our max size.\n\tif s.maxItems >= 0 && len(s.buffer) > s.maxItems {\n\t\tstartIndex := len(s.buffer) - s.maxItems\n\t\ts.buffer = s.buffer[startIndex:]\n\t}\n}\n\n// Returns up to maxResult elements in the specified time period (inclusive).\n// Results are from first to last. maxResults of -1 means no limit.\nfunc (s *TimedStore) InTimeRange(start, end time.Time, maxResults int) []interface{} {\n\t// No stats, return empty.\n\tif len(s.buffer) == 0 {\n\t\treturn []interface{}{}\n\t}\n\n\tvar startIndex int\n\tif start.IsZero() {\n\t\t// None specified, start at the beginning.\n\t\tstartIndex = len(s.buffer) - 1\n\t} else {\n\t\t// Start is the index before the elements smaller than it. We do this by\n\t\t// finding the first element smaller than start and taking the index\n\t\t// before that element\n\t\tstartIndex = sort.Search(len(s.buffer), func(index int) bool {\n\t\t\t// buffer[index] < start\n\t\t\treturn s.getData(index).timestamp.Before(start)\n\t\t}) - 1\n\t\t// Check if start is after all the data we have.\n\t\tif startIndex < 0 {\n\t\t\treturn []interface{}{}\n\t\t}\n\t}\n\n\tvar endIndex int\n\tif end.IsZero() {\n\t\t// None specified, end with the latest stats.\n\t\tendIndex = 0\n\t} else {\n\t\t// End is the first index smaller than or equal to it (so, not larger).\n\t\tendIndex = sort.Search(len(s.buffer), func(index int) bool {\n\t\t\t// buffer[index] <= t -> !(buffer[index] > t)\n\t\t\treturn !s.getData(index).timestamp.After(end)\n\t\t})\n\t\t// Check if end is before all the data we have.\n\t\tif endIndex == len(s.buffer) {\n\t\t\treturn []interface{}{}\n\t\t}\n\t}\n\n\t// Trim to maxResults size.\n\tnumResults := startIndex - endIndex + 1\n\tif maxResults != -1 && numResults > maxResults {\n\t\tstartIndex -= numResults - maxResults\n\t\tnumResults = maxResults\n\t}\n\n\t// Return in sorted timestamp order so from the \"back\" to \"front\".\n\tresult := make([]interface{}, numResults)\n\tfor i := 0; i < numResults; i++ {\n\t\tresult[i] = s.Get(startIndex - i)\n\t}\n\treturn result\n}\n\n// Gets the element at the specified index. Note that elements are output in LIFO order.\nfunc (s *TimedStore) Get(index int) interface{} {\n\treturn s.getData(index).data\n}\n\n// Gets the data at the specified index. Note that elements are output in LIFO order.\nfunc (s *TimedStore) getData(index int) timedStoreData {\n\treturn s.buffer[len(s.buffer)-index-1]\n}\n\nfunc (s *TimedStore) Size() int {\n\treturn len(s.buffer)\n}\n"
  },
  {
    "path": "utils/timed_store_test.go",
    "content": "// Copyright 2014 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage utils\n\nimport (\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/stretchr/testify/assert\"\n)\n\nfunc createTime(id int) time.Time {\n\tvar zero time.Time\n\treturn zero.Add(time.Duration(id+1) * time.Second)\n}\n\nfunc expectSize(t *testing.T, sb *TimedStore, expectedSize int) {\n\tif sb.Size() != expectedSize {\n\t\tt.Errorf(\"Expected size %v, got %v\", expectedSize, sb.Size())\n\t}\n}\n\nfunc expectAllElements(t *testing.T, sb *TimedStore, expected []int) {\n\tsize := sb.Size()\n\tels := make([]interface{}, size)\n\tfor i := 0; i < size; i++ {\n\t\tels[i] = sb.Get(size - i - 1)\n\t}\n\texpectElements(t, []interface{}(els), expected)\n}\n\nfunc expectElements(t *testing.T, actual []interface{}, expected []int) {\n\tif len(actual) != len(expected) {\n\t\tt.Errorf(\"Expected elements %v, got %v\", expected, actual)\n\t\treturn\n\t}\n\tfor i, el := range actual {\n\t\tif el.(int) != expected[i] {\n\t\t\tt.Errorf(\"Expected elements %v, got %v\", expected, actual)\n\t\t\treturn\n\t\t}\n\t}\n}\n\nfunc TestAdd(t *testing.T) {\n\tsb := NewTimedStore(5*time.Second, 100)\n\n\t// Add 1.\n\tsb.Add(createTime(0), 0)\n\texpectSize(t, sb, 1)\n\texpectAllElements(t, sb, []int{0})\n\n\t// Fill the buffer.\n\tfor i := 1; i <= 5; i++ {\n\t\texpectSize(t, sb, i)\n\t\tsb.Add(createTime(i), i)\n\t}\n\texpectSize(t, sb, 5)\n\texpectAllElements(t, sb, []int{1, 2, 3, 4, 5})\n\n\t// Add more than is available in the buffer\n\tsb.Add(createTime(6), 6)\n\texpectSize(t, sb, 5)\n\texpectAllElements(t, sb, []int{2, 3, 4, 5, 6})\n\n\t// Replace all elements.\n\tfor i := 7; i <= 10; i++ {\n\t\tsb.Add(createTime(i), i)\n\t}\n\texpectSize(t, sb, 5)\n\texpectAllElements(t, sb, []int{6, 7, 8, 9, 10})\n}\n\nfunc TestGet(t *testing.T) {\n\tsb := NewTimedStore(5*time.Second, -1)\n\tsb.Add(createTime(1), 1)\n\tsb.Add(createTime(2), 2)\n\tsb.Add(createTime(3), 3)\n\texpectSize(t, sb, 3)\n\n\tassert := assert.New(t)\n\tassert.Equal(sb.Get(0).(int), 3)\n\tassert.Equal(sb.Get(1).(int), 2)\n\tassert.Equal(sb.Get(2).(int), 1)\n}\n\nfunc TestInTimeRange(t *testing.T) {\n\tsb := NewTimedStore(5*time.Second, -1)\n\tassert := assert.New(t)\n\n\tvar empty time.Time\n\n\t// No elements.\n\tassert.Empty(sb.InTimeRange(createTime(0), createTime(5), 10))\n\tassert.Empty(sb.InTimeRange(createTime(0), empty, 10))\n\tassert.Empty(sb.InTimeRange(empty, createTime(5), 10))\n\tassert.Empty(sb.InTimeRange(empty, empty, 10))\n\n\t// One element.\n\tsb.Add(createTime(1), 1)\n\texpectSize(t, sb, 1)\n\texpectElements(t, sb.InTimeRange(createTime(0), createTime(5), 10), []int{1})\n\texpectElements(t, sb.InTimeRange(createTime(1), createTime(5), 10), []int{1})\n\texpectElements(t, sb.InTimeRange(createTime(0), createTime(1), 10), []int{1})\n\texpectElements(t, sb.InTimeRange(createTime(1), createTime(1), 10), []int{1})\n\tassert.Empty(sb.InTimeRange(createTime(2), createTime(5), 10))\n\n\t// Two element.\n\tsb.Add(createTime(2), 2)\n\texpectSize(t, sb, 2)\n\texpectElements(t, sb.InTimeRange(createTime(0), createTime(5), 10), []int{1, 2})\n\texpectElements(t, sb.InTimeRange(createTime(1), createTime(5), 10), []int{1, 2})\n\texpectElements(t, sb.InTimeRange(createTime(0), createTime(2), 10), []int{1, 2})\n\texpectElements(t, sb.InTimeRange(createTime(1), createTime(2), 10), []int{1, 2})\n\texpectElements(t, sb.InTimeRange(createTime(1), createTime(1), 10), []int{1})\n\texpectElements(t, sb.InTimeRange(createTime(2), createTime(2), 10), []int{2})\n\tassert.Empty(sb.InTimeRange(createTime(3), createTime(5), 10))\n\n\t// Many elements.\n\tsb.Add(createTime(3), 3)\n\tsb.Add(createTime(4), 4)\n\texpectSize(t, sb, 4)\n\texpectElements(t, sb.InTimeRange(createTime(0), createTime(5), 10), []int{1, 2, 3, 4})\n\texpectElements(t, sb.InTimeRange(createTime(0), createTime(5), 10), []int{1, 2, 3, 4})\n\texpectElements(t, sb.InTimeRange(createTime(1), createTime(5), 10), []int{1, 2, 3, 4})\n\texpectElements(t, sb.InTimeRange(createTime(0), createTime(4), 10), []int{1, 2, 3, 4})\n\texpectElements(t, sb.InTimeRange(createTime(1), createTime(4), 10), []int{1, 2, 3, 4})\n\texpectElements(t, sb.InTimeRange(createTime(0), createTime(2), 10), []int{1, 2})\n\texpectElements(t, sb.InTimeRange(createTime(1), createTime(2), 10), []int{1, 2})\n\texpectElements(t, sb.InTimeRange(createTime(2), createTime(3), 10), []int{2, 3})\n\texpectElements(t, sb.InTimeRange(createTime(3), createTime(4), 10), []int{3, 4})\n\texpectElements(t, sb.InTimeRange(createTime(3), createTime(5), 10), []int{3, 4})\n\tassert.Empty(sb.InTimeRange(createTime(5), createTime(5), 10))\n\n\t// Start and end time does't ignore maxResults.\n\texpectElements(t, sb.InTimeRange(createTime(1), createTime(5), 1), []int{4})\n\n\t// No start time.\n\texpectElements(t, sb.InTimeRange(empty, createTime(5), 10), []int{1, 2, 3, 4})\n\texpectElements(t, sb.InTimeRange(empty, createTime(4), 10), []int{1, 2, 3, 4})\n\texpectElements(t, sb.InTimeRange(empty, createTime(3), 10), []int{1, 2, 3})\n\texpectElements(t, sb.InTimeRange(empty, createTime(2), 10), []int{1, 2})\n\texpectElements(t, sb.InTimeRange(empty, createTime(1), 10), []int{1})\n\n\t// No end time.\n\texpectElements(t, sb.InTimeRange(createTime(0), empty, 10), []int{1, 2, 3, 4})\n\texpectElements(t, sb.InTimeRange(createTime(1), empty, 10), []int{1, 2, 3, 4})\n\texpectElements(t, sb.InTimeRange(createTime(2), empty, 10), []int{2, 3, 4})\n\texpectElements(t, sb.InTimeRange(createTime(3), empty, 10), []int{3, 4})\n\texpectElements(t, sb.InTimeRange(createTime(4), empty, 10), []int{4})\n\n\t// No start or end time.\n\texpectElements(t, sb.InTimeRange(empty, empty, 10), []int{1, 2, 3, 4})\n\n\t// Start after data.\n\tassert.Empty(sb.InTimeRange(createTime(5), createTime(5), 10))\n\tassert.Empty(sb.InTimeRange(createTime(5), empty, 10))\n\n\t// End before data.\n\tassert.Empty(sb.InTimeRange(createTime(0), createTime(0), 10))\n\tassert.Empty(sb.InTimeRange(empty, createTime(0), 10))\n}\n\nfunc TestInTimeRangeWithLimit(t *testing.T) {\n\tsb := NewTimedStore(5*time.Second, -1)\n\tsb.Add(createTime(1), 1)\n\tsb.Add(createTime(2), 2)\n\tsb.Add(createTime(3), 3)\n\tsb.Add(createTime(4), 4)\n\texpectSize(t, sb, 4)\n\n\tvar empty time.Time\n\n\t// Limit cuts off from latest timestamp.\n\texpectElements(t, sb.InTimeRange(empty, empty, 4), []int{1, 2, 3, 4})\n\texpectElements(t, sb.InTimeRange(empty, empty, 3), []int{2, 3, 4})\n\texpectElements(t, sb.InTimeRange(empty, empty, 2), []int{3, 4})\n\texpectElements(t, sb.InTimeRange(empty, empty, 1), []int{4})\n\tassert.Empty(t, sb.InTimeRange(empty, empty, 0))\n}\n\nfunc TestLimitedSize(t *testing.T) {\n\tsb := NewTimedStore(time.Hour, 5)\n\n\t// Add 1.\n\tsb.Add(createTime(0), 0)\n\texpectSize(t, sb, 1)\n\texpectAllElements(t, sb, []int{0})\n\n\t// Fill the buffer.\n\tfor i := 1; i <= 5; i++ {\n\t\texpectSize(t, sb, i)\n\t\tsb.Add(createTime(i), i)\n\t}\n\texpectSize(t, sb, 5)\n\texpectAllElements(t, sb, []int{1, 2, 3, 4, 5})\n\n\t// Add more than is available in the buffer\n\tsb.Add(createTime(6), 6)\n\texpectSize(t, sb, 5)\n\texpectAllElements(t, sb, []int{2, 3, 4, 5, 6})\n\n\t// Replace all elements.\n\tfor i := 7; i <= 10; i++ {\n\t\tsb.Add(createTime(i), i)\n\t}\n\texpectSize(t, sb, 5)\n\texpectAllElements(t, sb, []int{6, 7, 8, 9, 10})\n}\n"
  },
  {
    "path": "utils/utils.go",
    "content": "// Copyright 2015 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage utils\n\nimport \"fmt\"\n\n// Returns a mask of all cores on the machine if the passed-in mask is empty.\nfunc FixCpuMask(mask string, cores int) string {\n\tif mask == \"\" {\n\t\tif cores > 1 {\n\t\t\tmask = fmt.Sprintf(\"0-%d\", cores-1)\n\t\t} else {\n\t\t\tmask = \"0\"\n\t\t}\n\t}\n\treturn mask\n}\n"
  },
  {
    "path": "validate/validate.go",
    "content": "// Copyright 2014 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n//go:build linux\n\n// Handler for /validate content.\n// Validates cadvisor dependencies - kernel, os, docker setup.\n\npackage validate\n\nimport (\n\t\"fmt\"\n\t\"log\"\n\t\"net/http\"\n\t\"os\"\n\t\"path\"\n\t\"strings\"\n\n\t\"github.com/google/cadvisor/container/docker\"\n\t\"github.com/google/cadvisor/manager\"\n\t\"github.com/google/cadvisor/utils\"\n\n\t\"github.com/opencontainers/cgroups\"\n)\n\nconst (\n\tValidatePage  = \"/validate/\"\n\tSupported     = \"[Supported, but not recommended]\"\n\tUnsupported   = \"[Unsupported]\"\n\tRecommended   = \"[Supported and recommended]\"\n\tUnknown       = \"[Unknown]\"\n\tVersionFormat = \"%d.%d%s\"\n\tOutputFormat  = \"%s: %s\\n\\t%s\\n\\n\"\n)\n\nfunc getMajorMinor(version string) (int, int, error) {\n\tvar major, minor int\n\tvar ign string\n\tn, err := fmt.Sscanf(version, VersionFormat, &major, &minor, &ign)\n\tif n != 3 || err != nil {\n\t\tlog.Printf(\"Failed to parse version for %s\", version)\n\t\treturn -1, -1, err\n\t}\n\treturn major, minor, nil\n}\n\nfunc validateKernelVersion(version string) (string, string) {\n\tdesc := fmt.Sprintf(\"Kernel version is %s. Versions >= 2.6 are supported. 3.0+ are recommended.\\n\", version)\n\tmajor, minor, err := getMajorMinor(version)\n\tif err != nil {\n\t\tdesc = fmt.Sprintf(\"Could not parse kernel version. %s\", desc)\n\t\treturn Unknown, desc\n\t}\n\n\tif major < 2 {\n\t\treturn Unsupported, desc\n\t}\n\n\tif major == 2 && minor < 6 {\n\t\treturn Unsupported, desc\n\t}\n\n\tif major >= 3 {\n\t\treturn Recommended, desc\n\t}\n\n\treturn Supported, desc\n}\n\nfunc validateDockerVersion(version string) (string, string) {\n\tdesc := fmt.Sprintf(\"Docker version is %s. Versions >= 1.0 are supported. 1.2+ are recommended.\\n\", version)\n\tmajor, minor, err := getMajorMinor(version)\n\tif err != nil {\n\t\tdesc = fmt.Sprintf(\"Could not parse docker version. %s\\n\\t\", desc)\n\t\treturn Unknown, desc\n\t}\n\tif major < 1 {\n\t\treturn Unsupported, desc\n\t}\n\n\tif major == 1 && minor < 2 {\n\t\treturn Supported, desc\n\t}\n\n\treturn Recommended, desc\n}\n\nfunc getEnabledCgroups() (map[string]int, error) {\n\tout, err := os.ReadFile(\"/proc/cgroups\")\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tcgroups := make(map[string]int)\n\tfor i, line := range strings.Split(string(out), \"\\n\") {\n\t\tvar cgroup string\n\t\tvar ign, enabled int\n\t\tif i == 0 || line == \"\" {\n\t\t\tcontinue\n\t\t}\n\t\tn, err := fmt.Sscanf(line, \"%s %d %d %d\", &cgroup, &ign, &ign, &enabled)\n\t\tif n != 4 || err != nil {\n\t\t\tif err == nil {\n\t\t\t\terr = fmt.Errorf(\"failed to parse /proc/cgroup entry %s\", line)\n\t\t\t}\n\t\t\treturn nil, err\n\t\t}\n\t\tcgroups[cgroup] = enabled\n\t}\n\treturn cgroups, nil\n}\n\nfunc areCgroupsPresent(available map[string]int, desired []string) (bool, string) {\n\tfor _, cgroup := range desired {\n\t\tenabled, ok := available[cgroup]\n\t\tif !ok {\n\t\t\treason := fmt.Sprintf(\"Missing cgroup %s. Available cgroups: %v\\n\", cgroup, available)\n\t\t\treturn false, reason\n\t\t}\n\t\tif enabled != 1 {\n\t\t\treason := fmt.Sprintf(\"Cgroup %s not enabled. Available cgroups: %v\\n\", cgroup, available)\n\t\t\treturn false, reason\n\t\t}\n\t}\n\treturn true, \"\"\n}\n\nfunc validateCPUCFSBandwidth(availableCgroups map[string]int) string {\n\tok, _ := areCgroupsPresent(availableCgroups, []string{\"cpu\"})\n\tif !ok {\n\t\treturn \"\\tCpu cfs bandwidth status unknown: cpu cgroup not enabled.\\n\"\n\t}\n\tmnt, err := cgroups.FindCgroupMountpoint(\"/\", \"cpu\")\n\tif err != nil {\n\t\treturn \"\\tCpu cfs bandwidth status unknown: cpu cgroup not mounted.\\n\"\n\t}\n\t_, err = os.Stat(path.Join(mnt, \"cpu.cfs_period_us\"))\n\tif os.IsNotExist(err) {\n\t\treturn \"\\tCpu cfs bandwidth is disabled. Recompile kernel with \\\"CONFIG_CFS_BANDWIDTH\\\" enabled.\\n\"\n\t}\n\n\treturn \"\\tCpu cfs bandwidth is enabled.\\n\"\n}\n\nfunc validateMemoryAccounting(availableCgroups map[string]int) string {\n\tok, _ := areCgroupsPresent(availableCgroups, []string{\"memory\"})\n\tif !ok {\n\t\treturn \"\\tHierarchical memory accounting status unknown: memory cgroup not enabled.\\n\"\n\t}\n\tvar enabled int\n\tif cgroups.IsCgroup2UnifiedMode() {\n\t\tenabled = 1\n\t} else {\n\t\tmnt, err := cgroups.FindCgroupMountpoint(\"/\", \"memory\")\n\t\tif err != nil {\n\t\t\treturn \"\\tHierarchical memory accounting status unknown: memory cgroup not mounted.\\n\"\n\t\t}\n\t\thier, err := os.ReadFile(path.Join(mnt, \"memory.use_hierarchy\"))\n\t\tif err != nil {\n\t\t\treturn \"\\tHierarchical memory accounting status unknown: hierarchy interface unavailable.\\n\"\n\t\t}\n\t\tn, err := fmt.Sscanf(string(hier), \"%d\", &enabled)\n\t\tif err != nil || n != 1 {\n\t\t\treturn \"\\tHierarchical memory accounting status unknown: hierarchy interface unreadable.\\n\"\n\t\t}\n\t}\n\tif enabled == 1 {\n\t\treturn \"\\tHierarchical memory accounting enabled. Reported memory usage includes memory used by child containers.\\n\"\n\t}\n\treturn \"\\tHierarchical memory accounting disabled. Memory usage does not include usage from child containers.\\n\"\n\n}\n\nfunc validateCgroups() (string, string) {\n\trequiredCgroups := []string{\"cpu\", \"cpuacct\"}\n\trecommendedCgroups := []string{\"memory\", \"blkio\", \"cpuset\", \"devices\", \"freezer\"}\n\tavailableCgroups, err := getEnabledCgroups()\n\tdesc := fmt.Sprintf(\"\\tFollowing cgroups are required: %v\\n\\tFollowing other cgroups are recommended: %v\\n\", requiredCgroups, recommendedCgroups)\n\tif err != nil {\n\t\tdesc = fmt.Sprintf(\"Could not parse /proc/cgroups.\\n%s\", desc)\n\t\treturn Unknown, desc\n\t}\n\tok, out := areCgroupsPresent(availableCgroups, requiredCgroups)\n\tif !ok {\n\t\tout += desc\n\t\treturn Unsupported, out\n\t}\n\tok, out = areCgroupsPresent(availableCgroups, recommendedCgroups)\n\tif !ok {\n\t\t// supported, but not recommended.\n\t\tout += desc\n\t\treturn Supported, out\n\t}\n\tout = fmt.Sprintf(\"Available cgroups: %v\\n\", availableCgroups)\n\tout += desc\n\tout += validateMemoryAccounting(availableCgroups)\n\tout += validateCPUCFSBandwidth(availableCgroups)\n\treturn Recommended, out\n}\n\nfunc validateDockerInfo() (string, string) {\n\tinfo, err := docker.ValidateInfo(docker.Info, docker.VersionString)\n\tif err != nil {\n\t\treturn Unsupported, fmt.Sprintf(\"Docker setup is invalid: %v\", err)\n\t}\n\n\tdesc := fmt.Sprintf(\"Storage driver is %s.\\n\", info.Driver)\n\treturn Recommended, desc\n}\n\nfunc validateCgroupMounts() (string, string) {\n\tconst recommendedMount = \"/sys/fs/cgroup\"\n\tdesc := fmt.Sprintf(\"\\tAny cgroup mount point that is detectible and accessible is supported. %s is recommended as a standard location.\\n\", recommendedMount)\n\tmnt, err := cgroups.FindCgroupMountpoint(\"/\", \"cpu\")\n\tif err != nil {\n\t\tout := \"Could not locate cgroup mount point.\\n\"\n\t\tout += desc\n\t\treturn Unknown, out\n\t}\n\tmnt = path.Dir(mnt)\n\tif !utils.FileExists(mnt) {\n\t\tout := fmt.Sprintf(\"Cgroup mount directory %s inaccessible.\\n\", mnt)\n\t\tout += desc\n\t\treturn Unsupported, out\n\t}\n\tmounts, err := os.ReadDir(mnt)\n\tif err != nil {\n\t\tout := fmt.Sprintf(\"Could not read cgroup mount directory %s.\\n\", mnt)\n\t\tout += desc\n\t\treturn Unsupported, out\n\t}\n\tmountNames := \"\\tCgroup mount directories: \"\n\tfor _, mount := range mounts {\n\t\tmountNames += mount.Name() + \" \"\n\t}\n\tmountNames += \"\\n\"\n\tout := fmt.Sprintf(\"Cgroups are mounted at %s.\\n\", mnt)\n\tout += mountNames\n\tout += desc\n\tinfo, err := os.ReadFile(\"/proc/mounts\")\n\tif err != nil {\n\t\tout := \"Could not read /proc/mounts.\\n\"\n\t\tout += desc\n\t\treturn Unsupported, out\n\t}\n\tout += \"\\tCgroup mounts:\\n\"\n\tfor _, line := range strings.Split(string(info), \"\\n\") {\n\t\tif strings.Contains(line, \" cgroup \") {\n\t\t\tout += \"\\t\" + line + \"\\n\"\n\t\t}\n\t}\n\tif mnt == recommendedMount {\n\t\treturn Recommended, out\n\t}\n\treturn Supported, out\n}\n\nfunc validateIoScheduler(containerManager manager.Manager) (string, string) {\n\tvar desc string\n\tmi, err := containerManager.GetMachineInfo()\n\tif err != nil {\n\t\treturn Unknown, \"Machine info not available\\n\\t\"\n\t}\n\tcfq := false\n\tfor _, disk := range mi.DiskMap {\n\t\tdesc += fmt.Sprintf(\"\\t Disk %q Scheduler type %q.\\n\", disk.Name, disk.Scheduler)\n\t\tif disk.Scheduler == \"cfq\" {\n\t\t\tcfq = true\n\t\t}\n\t}\n\t// Since we get lot of random block devices, report recommended if\n\t// at least one of them is on cfq. Report Supported otherwise.\n\tif cfq {\n\t\tdesc = \"At least one device supports 'cfq' I/O scheduler. Some disk stats can be reported.\\n\" + desc\n\t\treturn Recommended, desc\n\t}\n\tdesc = \"None of the devices support 'cfq' I/O scheduler. No disk stats can be reported.\\n\" + desc\n\treturn Supported, desc\n}\n\nfunc HandleRequest(w http.ResponseWriter, containerManager manager.Manager) error {\n\t// Get cAdvisor version Info.\n\tversionInfo, err := containerManager.GetVersionInfo()\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tout := fmt.Sprintf(\"cAdvisor version: %s\\n\\n\", versionInfo.CadvisorVersion)\n\n\t// No OS is preferred or unsupported as of now.\n\tout += fmt.Sprintf(\"OS version: %s\\n\\n\", versionInfo.ContainerOsVersion)\n\n\tkernelValidation, desc := validateKernelVersion(versionInfo.KernelVersion)\n\tout += fmt.Sprintf(OutputFormat, \"Kernel version\", kernelValidation, desc)\n\n\tcgroupValidation, desc := validateCgroups()\n\tout += fmt.Sprintf(OutputFormat, \"Cgroup setup\", cgroupValidation, desc)\n\n\tmountsValidation, desc := validateCgroupMounts()\n\tout += fmt.Sprintf(OutputFormat, \"Cgroup mount setup\", mountsValidation, desc)\n\n\tdockerValidation, desc := validateDockerVersion(versionInfo.DockerVersion)\n\tout += fmt.Sprintf(OutputFormat, \"Docker version\", dockerValidation, desc)\n\n\tdockerInfoValidation, desc := validateDockerInfo()\n\tout += fmt.Sprintf(OutputFormat, \"Docker driver setup\", dockerInfoValidation, desc)\n\n\tioSchedulerValidation, desc := validateIoScheduler(containerManager)\n\tout += fmt.Sprintf(OutputFormat, \"Block device setup\", ioSchedulerValidation, desc)\n\n\t// Output debug info.\n\tdebugInfo := containerManager.DebugInfo()\n\tfor category, lines := range debugInfo {\n\t\tout += fmt.Sprintf(OutputFormat, category, \"\", strings.Join(lines, \"\\n\\t\"))\n\t}\n\n\t_, err = w.Write([]byte(out))\n\treturn err\n}\n"
  },
  {
    "path": "validate/validate_test.go",
    "content": "// Copyright 2015 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n//go:build linux\n\npackage validate\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n\t\"testing\"\n)\n\nvar (\n\tstandardDesc       = \"Versions >= %s are supported. %s+ are recommended\"\n\tdockerStandardDesc = fmt.Sprintf(standardDesc, \"1.0\", \"1.2\")\n\tkernelStandardDesc = fmt.Sprintf(standardDesc, \"2.6\", \"3.0\")\n\tdockerErrorDesc    = \"Could not parse docker version\"\n\tkernelErrorDesc    = \"Could not parse kernel version\"\n)\n\nfunc TestGetMajorMinor(t *testing.T) {\n\tcases := []struct {\n\t\tversion string\n\t\tmajor   int\n\t\tminor   int\n\t\terr     error\n\t}{\n\t\t{\"0.1beta\", 0, 1, nil},\n\t\t{\"0.1.2\", 0, 1, nil},\n\t\t{\"-1.-1beta\", -1, -1, nil},\n\t\t{\"0.1\", -1, -1, fmt.Errorf(\"have error\")},\n\t\t{\"0\", -1, -1, fmt.Errorf(\"have error\")},\n\t\t{\"beta\", -1, -1, fmt.Errorf(\"have error\")},\n\t}\n\n\tfor i, c := range cases {\n\t\tma, mi, e := getMajorMinor(c.version)\n\t\tif (e != nil) != (c.err != nil) {\n\t\t\tt.Errorf(\"[%d] Unexpected err, should %v, but got %v\", i, c.err, e)\n\t\t}\n\t\tif ma != c.major {\n\t\t\tt.Errorf(\"[%d] Unexpected major, should %v, but got %v\", i, c.major, ma)\n\t\t}\n\t\tif mi != c.minor {\n\t\t\tt.Errorf(\"[%d] Unexpected minor, should %v, but got %v\", i, c.minor, mi)\n\t\t}\n\t}\n}\n\nfunc TestValidateKernelVersion(t *testing.T) {\n\tcases := []struct {\n\t\tversion string\n\t\tresult  string\n\t\tdesc    string\n\t}{\n\t\t{\"2.6.3\", Supported, kernelStandardDesc},\n\t\t{\"3.6.3\", Recommended, kernelStandardDesc},\n\t\t{\"1.0beta\", Unsupported, kernelStandardDesc},\n\t\t{\"0.1beta\", Unsupported, kernelStandardDesc},\n\t\t{\"0.1\", Unknown, kernelErrorDesc},\n\t\t{\"3.1\", Unknown, kernelErrorDesc},\n\t}\n\n\tfor i, c := range cases {\n\t\tres, desc := validateKernelVersion(c.version)\n\t\tif res != c.result {\n\t\t\tt.Errorf(\"[%d] Unexpected result, should %v, but got %v\", i, c.result, res)\n\t\t}\n\t\tif !strings.Contains(desc, c.desc) {\n\t\t\tt.Errorf(\"[%d] Unexpected description, should %v, but got %v\", i, c.desc, desc)\n\t\t}\n\t}\n}\n\nfunc TestValidateDockerVersion(t *testing.T) {\n\tcases := []struct {\n\t\tversion string\n\t\tresult  string\n\t\tdesc    string\n\t}{\n\t\t{\"1.1.3\", Supported, dockerStandardDesc},\n\t\t{\"1.6.3\", Recommended, dockerStandardDesc},\n\t\t{\"1.0beta\", Supported, dockerStandardDesc},\n\t\t{\"0.1beta\", Unsupported, dockerStandardDesc},\n\t\t{\"0.1\", Unknown, dockerErrorDesc},\n\t\t{\"1.6\", Unknown, dockerErrorDesc},\n\t}\n\n\tfor i, c := range cases {\n\t\tres, desc := validateDockerVersion(c.version)\n\t\tif res != c.result {\n\t\t\tt.Errorf(\"[%d] Unexpected result, should %v, but got %v\", i, c.result, res)\n\t\t}\n\t\tif !strings.Contains(desc, c.desc) {\n\t\t\tt.Errorf(\"[%d] Unexpected description, should %v, but got %v\", i, c.desc, desc)\n\t\t}\n\t}\n}\n\nfunc TestAreCgroupsPresent(t *testing.T) {\n\tcases := []struct {\n\t\tavailable map[string]int\n\t\tdesired   []string\n\t\tresult    bool\n\t\treason    string\n\t}{\n\t\t{map[string]int{\"memory\": 1}, []string{\"memory\"}, true, \"\"},\n\t\t{map[string]int{\"memory\": 2}, []string{\"memory\"}, false, \"memory not enabled. Available cgroups\"},\n\t\t{map[string]int{\"memory\": 0}, []string{\"memory\"}, false, \"memory not enabled. Available cgroups\"},\n\t\t{map[string]int{\"memory\": 1}, []string{\"blkio\"}, false, \"Missing cgroup blkio. Available cgroups\"},\n\t}\n\tfor i, c := range cases {\n\t\tresult, reason := areCgroupsPresent(c.available, c.desired)\n\t\tif result != c.result {\n\t\t\tt.Errorf(\"[%d] Unexpected result, should %v, but got %v\", i, c.result, result)\n\t\t}\n\t\tif (c.reason == \"\" && reason != \"\") || (c.reason != \"\" && !strings.Contains(reason, c.reason)) {\n\t\t\tt.Errorf(\"[%d] Unexpected result, should %v, but got %v\", i, c.reason, reason)\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "version/version.go",
    "content": "// Copyright 2014 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage version\n\n// Build information. Populated at build-time.\nvar (\n\tVersion   string\n\tRevision  string\n\tBranch    string\n\tBuildUser string\n\tBuildDate string\n\tGoVersion string\n)\n\n// Info provides the iterable version information.\nvar Info = map[string]string{\n\t\"version\":   Version,\n\t\"revision\":  Revision,\n\t\"branch\":    Branch,\n\t\"buildUser\": BuildUser,\n\t\"buildDate\": BuildDate,\n\t\"goVersion\": GoVersion,\n}\n"
  },
  {
    "path": "watcher/watcher.go",
    "content": "// Copyright 2016 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n// Package container defines types for sub-container events and also\n// defines an interface for container operation handlers.\npackage watcher\n\n// SubcontainerEventType indicates an addition or deletion event.\ntype ContainerEventType int\n\nconst (\n\tContainerAdd ContainerEventType = iota\n\tContainerDelete\n)\n\ntype ContainerWatchSource int\n\nconst (\n\tRaw ContainerWatchSource = iota\n)\n\n// ContainerEvent represents a\ntype ContainerEvent struct {\n\t// The type of event that occurred.\n\tEventType ContainerEventType\n\n\t// The full container name of the container where the event occurred.\n\tName string\n\n\t// The watcher that detected this change event\n\tWatchSource ContainerWatchSource\n}\n\ntype ContainerWatcher interface {\n\t// Registers a channel to listen for events affecting subcontainers (recursively).\n\tStart(events chan ContainerEvent) error\n\n\t// Stops watching for subcontainer changes.\n\tStop() error\n}\n"
  },
  {
    "path": "zfs/watcher.go",
    "content": "// Copyright 2016 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage zfs\n\nimport (\n\t\"fmt\"\n\t\"sync/atomic\"\n\t\"time\"\n\n\tzfs \"github.com/mistifyio/go-zfs\"\n\t\"k8s.io/klog/v2\"\n)\n\n// usageCache is a typed wrapper around atomic.Value that eliminates the need\n// for type assertions at every call site. It stores filesystem name strings\n// mapped to usage values (uint64).\ntype usageCache struct {\n\tv atomic.Value\n}\n\n// Load retrieves the current cache map.\nfunc (c *usageCache) Load() map[string]uint64 {\n\treturn c.v.Load().(map[string]uint64)\n}\n\n// Store saves a new cache map.\nfunc (c *usageCache) Store(m map[string]uint64) {\n\tc.v.Store(m)\n}\n\n// zfsWatcher maintains a cache of filesystem -> usage stats for a\n// zfs filesystem\ntype ZfsWatcher struct {\n\tfilesystem string\n\tcache      usageCache\n\tperiod     time.Duration\n\tstopChan   chan struct{}\n}\n\n// NewThinPoolWatcher returns a new ThinPoolWatcher for the given devicemapper\n// thin pool name and metadata device or an error.\nfunc NewZfsWatcher(filesystem string) (*ZfsWatcher, error) {\n\tw := &ZfsWatcher{\n\t\tfilesystem: filesystem,\n\t\tperiod:     15 * time.Second,\n\t\tstopChan:   make(chan struct{}),\n\t}\n\tw.cache.Store(map[string]uint64{})\n\treturn w, nil\n}\n\n// Start starts the ZfsWatcher.\nfunc (w *ZfsWatcher) Start() {\n\terr := w.Refresh()\n\tif err != nil {\n\t\tklog.Errorf(\"encountered error refreshing zfs watcher: %v\", err)\n\t}\n\n\tfor {\n\t\tselect {\n\t\tcase <-w.stopChan:\n\t\t\treturn\n\t\tcase <-time.After(w.period):\n\t\t\tstart := time.Now()\n\t\t\terr = w.Refresh()\n\t\t\tif err != nil {\n\t\t\t\tklog.Errorf(\"encountered error refreshing zfs watcher: %v\", err)\n\t\t\t}\n\n\t\t\t// print latency for refresh\n\t\t\tduration := time.Since(start)\n\t\t\tklog.V(5).Infof(\"zfs(%d) took %s\", start.Unix(), duration)\n\t\t}\n\t}\n}\n\n// Stop stops the ZfsWatcher.\nfunc (w *ZfsWatcher) Stop() {\n\tclose(w.stopChan)\n}\n\n// GetUsage gets the cached usage value of the given filesystem.\nfunc (w *ZfsWatcher) GetUsage(filesystem string) (uint64, error) {\n\tcache := w.cache.Load()\n\tv, ok := cache[filesystem]\n\tif !ok {\n\t\treturn 0, fmt.Errorf(\"no cached value for usage of filesystem %v\", filesystem)\n\t}\n\treturn v, nil\n}\n\n// Refresh performs a zfs get\nfunc (w *ZfsWatcher) Refresh() error {\n\tparent, err := zfs.GetDataset(w.filesystem)\n\tif err != nil {\n\t\tklog.Errorf(\"encountered error getting zfs filesystem: %s: %v\", w.filesystem, err)\n\t\treturn err\n\t}\n\tchildren, err := parent.Children(0)\n\tif err != nil {\n\t\tklog.Errorf(\"encountered error getting children of zfs filesystem: %s: %v\", w.filesystem, err)\n\t\treturn err\n\t}\n\n\tnewCache := make(map[string]uint64)\n\tfor _, ds := range children {\n\t\tnewCache[ds.Name] = ds.Used\n\t}\n\n\tw.cache.Store(newCache)\n\treturn nil\n}\n"
  }
]