pax_global_header00006660000000000000000000000064152567306240014524gustar00rootroot0000000000000052 comment=6d3443f2dae8413a1a56640290c09a6f486f30c2 python-msgspec-0.22.0/000077500000000000000000000000001525673062400145655ustar00rootroot00000000000000python-msgspec-0.22.0/.cibuildwheel.toml000066400000000000000000000005471525673062400202060ustar00rootroot00000000000000[tool.cibuildwheel] build = "cp310-* cp311-* cp312-* cp313-* cp314-* cp314t-* cp315-* cp315t*" build-frontend = "build[uv]" test-command = "pytest {project}/tests/unit" test-groups = ["test-unit"] [tool.cibuildwheel.pyodide] build = "cp314-*" # https://cibuildwheel.pypa.io/en/stable/platforms/#pyodide test-command = "python -m pytest {project}/tests/unit" python-msgspec-0.22.0/.codecov.yml000066400000000000000000000001721525673062400170100ustar00rootroot00000000000000comment: false coverage: status: project: default: target: auto threshold: 1% patch: off python-msgspec-0.22.0/.codespellrc000066400000000000000000000000571525673062400170670ustar00rootroot00000000000000[codespell] skip = ./site,./.venv,*.py,*.c,*.h python-msgspec-0.22.0/.coveragerc000066400000000000000000000005021525673062400167030ustar00rootroot00000000000000[run] source_pkgs = msgspec source_dirs = tests/unit omit = src/msgspec/_version.py [paths] msgspec = src/msgspec */msgspec/src/msgspec */msgspec/dev/*/venvs/*/lib*/python*/site-packages/msgspec *\msgspec\dev\*\venvs\*\Lib\site-packages\msgspec tests = tests/unit */msgspec/tests/unit python-msgspec-0.22.0/.devcontainer/000077500000000000000000000000001525673062400173245ustar00rootroot00000000000000python-msgspec-0.22.0/.devcontainer/Dockerfile000066400000000000000000000012121525673062400213120ustar00rootroot00000000000000FROM ghcr.io/astral-sh/uv:latest AS uv FROM buildpack-deps:24.04-curl AS bin COPY --chmod=755 --from=uv /uv /usr/local/bin/uv RUN uv tool install rust-just FROM mcr.microsoft.com/devcontainers/base:ubuntu-24.04 RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \ && apt-get -y install --no-install-recommends \ gdb \ valgrind \ libasan6 \ && apt-get autoremove -y \ && apt-get clean -y \ && rm -rf /var/lib/apt/lists/* WORKDIR /workspaces/msgspec COPY --chmod=755 --from=bin \ /root/.local/bin/just \ /usr/local/bin/ COPY --chmod=755 --from=uv \ /uv \ /uvx \ /usr/local/bin/ python-msgspec-0.22.0/.devcontainer/devcontainer.json000066400000000000000000000032651525673062400227060ustar00rootroot00000000000000{ "name": "msgspec", "build": { "cacheFrom": "ghcr.io/msgspec/msgspec", "dockerfile": "Dockerfile" }, "customizations": { "vscode": { "settings": { "python.defaultInterpreterPath": "/home/vscode/.local/share/msgspec/dev/venvs/test/bin/python", "python.testing.pytestEnabled": true, "[python]": { "editor.codeActionsOnSave": { "source.fixAll.ruff": "explicit", "source.organizeImports.ruff": "explicit" }, "editor.defaultFormatter": "charliermarsh.ruff", "editor.formatOnSave": true }, "ruff.configurationPreference": "filesystemFirst", "ruff.importStrategy": "fromEnvironment", "ruff.interpreter": ["/home/vscode/.local/share/msgspec/dev/venvs/test/bin/python"] }, "extensions": [ "charliermarsh.ruff", "github.vscode-github-actions", "ms-python.python", "ms-vscode.cpptools", "nefrob.vscode-just-syntax", "tamasfe.even-better-toml", "yzhang.markdown-all-in-one" ] } }, "postCreateCommand": { "sync-deps": ["zsh", "-c", "just env-sync test && just env-sync hooks"], "git-safe-directory": ["git", "config", "--global", "--add", "safe.directory", "/workspaces/${localWorkspaceFolderBasename}"] }, "remoteEnv": { "PYTHONUNBUFFERED": "1", "PYTHONDONTWRITEBYTECODE": "1", "UV_MANAGED_PYTHON": "1" }, // Defaults for the base Ubuntu image: // https://github.com/devcontainers/images/blob/main/src/base-ubuntu/.devcontainer/devcontainer.json "features": { "ghcr.io/devcontainers/features/common-utils:2": { "configureZshAsDefaultShell": true } } } python-msgspec-0.22.0/.editorconfig000066400000000000000000000003121525673062400172360ustar00rootroot00000000000000root = true [*.{py,c,h,rst,yml,yaml,toml,md}] trim_trailing_whitespace = true insert_final_newline = true indent_style = space [*.{py,c,h,rst}] indent_size = 4 [*.{yml,yaml,toml,md}] indent_size = 2 python-msgspec-0.22.0/.gitattributes000066400000000000000000000001171525673062400174570ustar00rootroot00000000000000* text=auto eol=lf *.bat text eol=crlf *.ps1 text eol=crlf *.cmd text eol=crlf python-msgspec-0.22.0/.github/000077500000000000000000000000001525673062400161255ustar00rootroot00000000000000python-msgspec-0.22.0/.github/CODE_OF_CONDUCT.md000066400000000000000000000062121525673062400207250ustar00rootroot00000000000000# Code of Conduct ## Our Pledge In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation. ## Our Standards Examples of behavior that contributes to creating a positive environment include: * Using welcoming and inclusive language * Being respectful of differing viewpoints and experiences * Gracefully accepting constructive criticism * Focusing on what is best for the community * Showing empathy towards other community members Examples of unacceptable behavior by participants include: * The use of sexualized language or imagery and unwelcome sexual attention or advances * Trolling, insulting/derogatory comments, and personal or political attacks * Public or private harassment * Publishing others' private information, such as a physical or electronic address, without explicit permission * Other conduct which could reasonably be considered inappropriate in a professional setting ## Our Responsibilities Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior. Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful. ## Scope This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers. ## Enforcement Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at jcristharif@gmail.com. All complaints will be reviewed and investigated and will result in a response that is deemed necessary and appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately. Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership. ## Attribution This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version] [homepage]: http://contributor-covenant.org [version]: http://contributor-covenant.org/version/1/4/ python-msgspec-0.22.0/.github/CONTRIBUTING.md000066400000000000000000000145211525673062400203610ustar00rootroot00000000000000# How to Contribute Thank you for taking the time to contribute to `msgspec`! Here we document some contribution guidelines to help you ensure that your contribution is at its best. ## Setting up your Development Environment > [!TIP] > If you're using VS Code or Cursor, you can develop inside a container using the provided `.devcontainer` configuration. This provides a pre-configured environment with all dependencies installed. Simply open the project in your editor and select "Reopen in Container" when prompted. Before getting started, you will need to already have installed: - [Git](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git) - [uv](https://docs.astral.sh/uv/) - A C compiler (`gcc`, `clang`, and `msvc` are all tested) Once you have those installed, you're ready to clone the repository: ``` git clone https://github.com/msgspec/msgspec.git cd msgspec/ ``` Next, you'll need to install the command runner [`just`](https://just.systems/man/en/): ``` uv tool install rust-just ``` This will output extra information if the installation directory is not already on your `PATH`. If you do not want the `just` binary on your `PATH`, you can use uv to invoke it via a virtual environment: ``` uv run --only-dev just --help ``` At this point you're all set up to start contributing to `msgspec`! If you'd like to install the Git hooks, you can do so by running: ``` just pre-commit install ``` Not installing the Git hooks will mean that the linters will not run automatically when you commit changes and instead must be run [manually](#linting). ## Editing and Rebuilding You now have a "development" build of `msgspec` installed. This means that you can make changes to the `.py` files and test them without requiring a rebuild of msgspec's C extension. Edit away! If you do make changes to a `.c` file, you'll need to recompile. You can do this by running commands with the `rebuild` variable set to `true` or `1`: ``` just rebuild=1 test ``` By default `msgspec` is built in release mode, with optimizations enabled. To build a debug build instead (for use with e.g. `gdb` or `lldb`) set the `debug` variable to `true` or `1` when running the command: ``` just rebuild=1 debug=1 test ``` ## Testing Tests are located in the `tests/` directory. Any code changes should include additional tests to ensure correctness. The tests are broken into various `test_*.py` files specific to the functionality that they're testing. The recipes prefixed with `test-` use `pytest` to run the tests. For example: ``` just test-all ``` All such recipes accept additional arguments that are passed to `pytest`. For example, if you want to run a specific test file: ``` just test tests/unit/test_json.py ``` To invoke `pytest` directly, you can use the `env` recipe with the `test` environment: ``` just env test pytest --help ``` ## Linting We use [`prek`](https://github.com/j178/prek) to automatically run a few code linters before every commit. If you followed the development setup above, you should already have `prek` and all the Git hooks installed. These hooks will run whenever you try to commit changes. ``` git commit # linters will run automatically here ``` If you wish to run the linters manually without committing, you can run: ``` just hooks ``` You may also run the same hooks without applying fixes: ``` just check ``` ## Documentation The source of the documentation can be found under the `docs/` directory. They are built into the `site/` directory using `Sphinx` with the following command: ``` just doc-build ``` The HTML documentation can be viewed locally by running: ``` just doc-serve ``` ## Benchmarking You can run all [benchmarks](https://msgspec.dev/benchmarks.html) with the `bench` recipe, for example: ``` just bench encodings ``` Omit the benchmark name to list all available benchmarks. ## Profiling You can run all performance profiling tests with the `test-perf` recipe, for example: ``` just test-perf basic ``` Omit the profiling test name to list all available profiling tests. ## Python Version Management You can use the `python` variable to specify the version of Python to use for each environment. For example, to run tests with Python 3.12: ``` just python=3.12 test ``` Existing environments will be re-created if they are using a different version of Python. Environments will continue using the same version of Python until an invocation specifies a different version. You can update the Python version for all environments with the `env-sync` recipe: ``` just python=3.12 env-sync all ``` ## Dev Container You can manually use dev containers as long as the official [`devcontainer`](https://github.com/devcontainers/cli) CLI is on PATH. > [!NOTE] > If you need to install the `devcontainer` CLI and don't yet have Node.js installed, the easiest way is to use [`mise`](https://github.com/jdx/mise) (mise-en-place). > > 1. [Install](https://mise.jdx.dev/installing-mise.html) `mise` > 2. Add the [shim directory](https://mise.jdx.dev/dev-tools/shims.html#mise-activate-shims) to your PATH in one of the following ways: > - Manually, by finding the path in the output of `mise doctor` > - Automatically, by configuring your shell with the output of the following command (see the help text for the supported shells): > ``` > mise activate [SHELL] --shims > ``` > 3. Install the `devcontainer` CLI by running: > ``` > mise use -g node@lts > mise use -g npm:@devcontainers/cli > ``` To start the dev container, you can use the `dev-start` recipe: ``` just dev-start ``` To open a shell in the dev container, you can use the `dev-shell` recipe: ``` just shell ``` To run a command in the dev container as if you were in a shell, you can use the `dev` recipe: ``` just run just test ``` To stop the dev container, you can use the `dev-stop` recipe: ``` just dev-stop ``` To remove the dev container, you can use the `dev-remove` recipe: ``` just dev-remove ``` ## Continuous Integration (CI) We use GitHub Actions to provide "continuous integration" testing for all Pull Requests (PRs). When submitting a PR, please check to see that all tests pass, and fix any issues that come up. ## Code of Conduct `msgspec` has a code of conduct that must be followed by all contributors to the project. You may read the code of conduct [here](https://github.com/msgspec/msgspec/blob/main/.github/CODE_OF_CONDUCT.md). python-msgspec-0.22.0/.github/ISSUE_TEMPLATE/000077500000000000000000000000001525673062400203105ustar00rootroot00000000000000python-msgspec-0.22.0/.github/ISSUE_TEMPLATE/bug.yml000066400000000000000000000015231525673062400216110ustar00rootroot00000000000000name: 🪲 Bug Report description: Report a bug or unexpected behavior in msgspec body: - type: markdown attributes: value: Thanks for taking the time to fill out a bug report! - type: textarea id: description attributes: label: Description description: > Describe the bug. What happened? What did you expect to happen? When possible, please also include a [minimal, complete, verifiable example](https://stackoverflow.com/help/minimal-reproducible-example). Ideally this should be code that can be run without modification to demonstrate the problem. When including errors and tracebacks, please include the _full traceback_ as well as the code that generated the error (or at least the line that caused it). validations: required: true python-msgspec-0.22.0/.github/ISSUE_TEMPLATE/config.yml000066400000000000000000000000331525673062400222740ustar00rootroot00000000000000blank_issues_enabled: true python-msgspec-0.22.0/.github/ISSUE_TEMPLATE/feature.yml000066400000000000000000000014041525673062400224650ustar00rootroot00000000000000name: 🙌 Feature Request description: Suggest a new feature or change to msgspec body: - type: markdown attributes: value: Thanks for taking the time to fill out a feature request! - type: textarea id: description attributes: label: Description description: > Describe the feature. What problems does it solve? If the feature is to related to a problem, please describe in detail your use case. What would this new feature help you do that you couldn't do before? Why is this useful? When relevant, please also include example code making use of your proposed feature. How would you use this feature? What would code using it look like? validations: required: true python-msgspec-0.22.0/.github/ISSUE_TEMPLATE/question.yml000066400000000000000000000007031525673062400227020ustar00rootroot00000000000000name: � Question description: Ask a question body: - type: markdown attributes: value: Thanks for taking the time to ask a question! - type: textarea id: description attributes: label: Question description: > Ask your question here. Please search through existing and closed issues first to ensure your question hasn't already been answered elsewhere. validations: required: true python-msgspec-0.22.0/.github/SECURITY.md000066400000000000000000000012331525673062400177150ustar00rootroot00000000000000# Security Policy If you believe you have found a security-related bug with `msgspec`, **do not open a public GitHub issue**. Instead, please email jcristharif@gmail.com. Please include as much detail as you would for a normal issue in your report. In particular, including a minimal reproducible example will help the maintainers diagnose and resolve the issue quickly and efficiently. After the issue is resolved, we will make a release and announce the security fix through our normal communication channels. When it makes sense we may also obtain a CVE ID. If you would like to be credited with the report, please include your name and any links in the email. python-msgspec-0.22.0/.github/actions/000077500000000000000000000000001525673062400175655ustar00rootroot00000000000000python-msgspec-0.22.0/.github/actions/fetch-release-history/000077500000000000000000000000001525673062400237735ustar00rootroot00000000000000python-msgspec-0.22.0/.github/actions/fetch-release-history/action.yml000066400000000000000000000027761525673062400260070ustar00rootroot00000000000000name: Fetch Release History description: Fast, minimal fetch of commits since the latest release for version calculation with Git describe inputs: github-token: description: The GitHub token to use for the API required: true ref: description: The ref to fetch when deepening the checkout required: false default: "" runs: using: composite steps: - name: Fetch release history env: GH_TOKEN: ${{ inputs.github-token }} REPOSITORY: ${{ github.repository }} REF: ${{ inputs.ref || github.ref }} shell: bash run: |- SHA="$(git rev-parse HEAD)" latest_tag=$( gh api "repos/${REPOSITORY}/releases/latest" \ --jq '.tag_name' ) echo "Detected latest release tag: $latest_tag" ahead_by=$( gh api "repos/${REPOSITORY}/compare/${latest_tag}...${SHA}" \ --jq '.ahead_by' ) echo "Commits since last release: $ahead_by" if [ "$ahead_by" -gt 0 ]; then echo "Fetching commits since last release" git -c protocol.version=2 fetch \ --no-tags --no-recurse-submodules --filter=blob:none \ --deepen="$ahead_by" origin \ "${REF}" \ "refs/tags/$latest_tag:refs/tags/$latest_tag" else echo "No commits since last release, fetching release tag only" git -c protocol.version=2 fetch \ --no-tags --no-recurse-submodules --filter=blob:none \ origin \ "refs/tags/$latest_tag:refs/tags/$latest_tag" fi python-msgspec-0.22.0/.github/actions/latest-supported-python/000077500000000000000000000000001525673062400244235ustar00rootroot00000000000000python-msgspec-0.22.0/.github/actions/latest-supported-python/action.yml000066400000000000000000000050641525673062400264300ustar00rootroot00000000000000name: Latest Supported Python description: Fetch the highest minor version of Python with a wheel in the latest release on PyPI inputs: github-token: description: The token to use for the GitHub API required: true outputs: version: description: The highest minor version of Python with a wheel value: ${{ steps.python-version.outputs.version }} runs: using: composite steps: - name: Fetch latest release on GitHub id: latest-release env: GH_TOKEN: ${{ inputs.github-token }} REPOSITORY: ${{ github.repository }} shell: bash run: |- latest_release=$( gh api "repos/${REPOSITORY}/releases/latest" \ --jq '.tag_name' ) echo "Latest release: $latest_release" echo "tag=$latest_release" >> "${GITHUB_OUTPUT}" - name: Fetch latest release on PyPI id: python-version env: LATEST_RELEASE: ${{ steps.latest-release.outputs.tag }} RELEASE_EVENT: ${{ github.event_name == 'release' && github.event.action == 'published' }} shell: bash run: |- set -euo pipefail if [[ "${RELEASE_EVENT}" == 'true' ]]; then echo "Release workflow detected; selecting the latest stable version already available on PyPI." version=$( curl -fsS "https://pypi.org/pypi/msgspec/json" \ | jq -r ' .releases | to_entries | map( select( [ .value[] | select(.packagetype == "bdist_wheel") ] | length > 0 ) ) | map(select(.key | test("(a|b|rc)"; "i") | not)) | map(.key) | .[] ' \ | sort -V \ | tail -n 1 ) if [[ -z "$version" ]]; then echo "Failed to find a stable PyPI release with wheels" >&2 exit 1 fi echo "Selected PyPI release: $version" else version="${LATEST_RELEASE}" echo "Selected GitHub release: $version" fi pypi_url="https://pypi.org/pypi/msgspec/$version/json" python_version=$( curl -fsS "$pypi_url" \ | jq -r ' .urls | [ .[] | select(.packagetype == "bdist_wheel") | .filename | capture("cp(?[0-9]+)").cp | tonumber ] | max | "3.\(tostring | .[1:])" ' ) echo "Python version: $python_version" echo "version=$python_version" >> "${GITHUB_OUTPUT}" python-msgspec-0.22.0/.github/dependabot.yml000066400000000000000000000005141525673062400207550ustar00rootroot00000000000000version: 2 updates: - package-ecosystem: github-actions directory: / schedule: interval: weekly groups: github-actions: patterns: - "*" cooldown: default-days: 7 - package-ecosystem: uv directory: / schedule: interval: weekly cooldown: default-days: 7 python-msgspec-0.22.0/.github/workflows/000077500000000000000000000000001525673062400201625ustar00rootroot00000000000000python-msgspec-0.22.0/.github/workflows/build-wheels.yml000066400000000000000000000066061525673062400233010ustar00rootroot00000000000000name: Build Wheels on: workflow_call: inputs: sdist-name: description: Name of the source distribution file required: true type: string build-all: description: Build all wheels including musllinux type: boolean jobs: build-wheels: name: Build ${{ matrix.wheel.target }} runs-on: "${{ matrix.wheel.os }}" permissions: actions: read contents: read strategy: fail-fast: false matrix: wheel: - target: Linux (aarch64) os: ubuntu-24.04-arm archs: aarch64 - target: Linux (x86_64) os: ubuntu-latest archs: x86_64 - target: Linux (riscv64) os: ubuntu-24.04-riscv archs: riscv64 required-label: build-riscv64 - target: macOS (arm64) os: macos-latest archs: arm64 - target: macOS (x86_64) os: macos-15-intel archs: x86_64 - target: Windows (ARM64) os: windows-11-arm archs: ARM64 - target: Windows (AMD64) os: windows-latest archs: AMD64 - target: Pyodide (wasm32) os: ubuntu-latest archs: wasm32 cibw_platform: pyodide exclude: - wheel: target: Linux (riscv64) os: ubuntu-24.04-riscv archs: riscv64 # Unlabeled PRs match riscv64's required-label; otherwise empty keeps it. required-label: >- ${{ github.event_name == 'pull_request' && !contains(github.event.pull_request.labels.*.name, 'build-riscv64') && 'build-riscv64' || '' }} env: CIBW_ARCHS: "${{ matrix.wheel.archs }}" CIBW_PLATFORM: "${{ matrix.wheel.cibw_platform || 'auto' }}" CIBW_SKIP: "${{ !inputs.build-all && '*-musllinux_*' || '' }}" ARTIFACT_NAME: artifact-wheels-${{ matrix.wheel.cibw_platform || matrix.wheel.os }}-${{ matrix.wheel.archs }} PACKAGE_DIR: dist/${{ inputs.sdist-name }} steps: - name: Checkout code uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: persist-credentials: false - name: Download source distribution uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: name: artifact-sdist path: dist - name: Install uv uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0 with: enable-cache: false # The upstream composite action calls actions/setup-python@v6, which is # incompatible with the repository's full-SHA pinning requirement. - name: Build & Test Wheels if: runner.os != 'Windows' run: >- uvx --from cibuildwheel==4.2.0 cibuildwheel --config-file .cibuildwheel.toml --output-dir wheelhouse "${PACKAGE_DIR}" - name: Build & Test Wheels if: runner.os == 'Windows' run: >- uvx --from cibuildwheel==4.2.0 cibuildwheel --config-file .cibuildwheel.toml --output-dir wheelhouse "$env:PACKAGE_DIR" - name: Upload artifact uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: "${{ env.ARTIFACT_NAME }}" path: wheelhouse/*.whl if-no-files-found: error python-msgspec-0.22.0/.github/workflows/ci-capability-policy.yml000066400000000000000000000135731525673062400247250ustar00rootroot00000000000000name: CI capability policy on: pull_request_target: branches: - main types: - opened - ready_for_review - reopened - synchronize merge_group: types: - checks_requested permissions: {} jobs: policy: name: CI capability policy runs-on: ubuntu-latest timeout-minutes: 5 permissions: contents: read steps: - name: Checkout proposed repository uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: persist-credentials: false # pull_request_target runs this trusted workflow from the default branch. # The proposed merge is checked out only to parse workflow YAML as data. # Do not execute checked-out repository content in this workflow. ref: "${{ github.event_name == 'pull_request_target' && format('refs/pull/{0}/merge', github.event.pull_request.number) || github.sha }}" sparse-checkout: .github allow-unsafe-pr-checkout: true - name: Audit CI definitions env: GH_TOKEN: "${{ github.token }}" run: | set -euo pipefail if grep -R -n -E 'zizmor:[[:space:]]*ignore' .github; then echo "::error::Inline zizmor ignores are not allowed" exit 1 fi policy_root="${RUNNER_TEMP}/zizmor-policy" mkdir -p "${policy_root}" cat > "${policy_root}/zizmor.yml" <<'EOF' rules: dangerous-triggers: ignore: # Trusted policy reads the proposed merge as data without executing it. - ci-capability-policy.yml # Trusted orchestration isolates the untrusted docs build from deployment. - docs-deploy.yml EOF docker run --rm \ --volume "${GITHUB_WORKSPACE}:/workspace:ro" \ --volume "${policy_root}:/policy:ro" \ --workdir /workspace \ --env GH_TOKEN \ ghcr.io/zizmorcore/zizmor:1.25.2@sha256:14ea7f5cc7c67933394a35b5a38a277397818d232602635edb2010b313afb110 \ --config /policy/zizmor.yml \ --strict-collection \ --collect all \ --persona regular \ --format github \ -- \ .github - name: Check CI capabilities env: GH_TOKEN: "${{ github.token }}" run: | set -euo pipefail workflow_root="${WORKFLOW_ROOT:-.github/workflows}" deploy_workflow="${workflow_root}/docs-deploy.yml" scan_root="${RUNNER_TEMP:-${TMPDIR:-/tmp}}/ci-capability-policy" failed=false declare -A scanned=() mkdir -p "${scan_root}" error() { echo "::error::$1" failed=true } scan_external_workflow() { local repository="$1" local path="$2" local ref="$3" local identity="external:${repository}/${path}@${ref}" local file="${scan_root}/${ref}-${repository//\//-}-${path//\//-}" if [ -n "${scanned["${identity}"]:-}" ]; then return fi if ! gh api \ -H "Accept: application/vnd.github.raw+json" \ "repos/${repository}/contents/${path}?ref=${ref}" > "${file}"; then error "Unable to fetch external reusable workflow ${repository}/${path}@${ref}" scanned["${identity}"]=true return fi scan_workflow "${file}" "${identity}" "${repository}" "${ref}" } scan_workflow() { local workflow="$1" local identity="$2" local repository="${3:-}" local ref="${4:-}" if [ -n "${scanned["${identity}"]:-}" ]; then return fi scanned["${identity}"]=true if ! yq -e '.' "${workflow}" > /dev/null 2>&1; then error "Unable to parse workflow: ${identity}" return fi if [ "${identity}" != "local:${deploy_workflow}" ] && yq -e ' explode(.) | .jobs[]? | select(tag == "!!map" and has("environment")) ' "${workflow}" > /dev/null 2>&1; then error "${identity} declares an environment; only local:${deploy_workflow} may access environment capabilities" fi mapfile -t reusable_workflows < <( yq -r ' explode(.) | .jobs[]? | select(tag == "!!map" and has("uses")) | .uses ' "${workflow}" ) for reusable_workflow in "${reusable_workflows[@]}"; do case "${reusable_workflow}" in ./.github/workflows/*.yml | ./.github/workflows/*.yaml) local_path="${reusable_workflow#./}" if [ -n "${repository}" ]; then scan_external_workflow "${repository}" "${local_path}" "${ref}" elif [ -f "${local_path}" ]; then scan_workflow "${local_path}" "local:${local_path}" else error "${identity} calls missing local reusable workflow ${reusable_workflow}" fi ;; *) if [[ "${reusable_workflow}" =~ ^([^/]+/[^/]+)/(\.github/workflows/.+\.ya?ml)@([0-9a-f]{40})$ ]]; then scan_external_workflow \ "${BASH_REMATCH[1]}" \ "${BASH_REMATCH[2]}" \ "${BASH_REMATCH[3]}" else error "${identity} calls external reusable workflow ${reusable_workflow} without a full commit SHA" fi ;; esac done } for workflow in "${workflow_root}"/*.yml "${workflow_root}"/*.yaml; do if [ ! -f "${workflow}" ]; then continue fi scan_workflow "${workflow}" "local:${workflow}" done if [ "${failed}" = true ]; then exit 1 fi echo "CI capability policy passed." python-msgspec-0.22.0/.github/workflows/ci.yml000066400000000000000000000132311525673062400213000ustar00rootroot00000000000000name: Build and Test on: push: branches: - main pull_request: branches: - main types: - opened - synchronize - reopened - labeled - unlabeled paths: # Changes to the package itself - src/msgspec/** - pyproject.toml - setup.py - MANIFEST.in # Changes to CI execution - .github/workflows/* - .cibuildwheel.toml - .justfile - scripts/** # Changes to testing - tests/** - .codecov.yml - .codespellrc - .coveragerc - .pre-commit-config.yaml - .pytest.toml - .ruff.toml release: types: - published schedule: # Weekly full wheel build (build-all), so a musllinux or riscv64 breakage # surfaces before the release run that would otherwise be the first to try it. - cron: '17 4 * * 1' permissions: {} env: UV_NO_EDITABLE: "true" UV_NO_SYNC: "true" jobs: prepare: name: Validate build uses: ./.github/workflows/prepare-build.yml permissions: contents: read with: run-static-analysis: true fetch-latest-python: true test: name: Test Python ${{ matrix.python-version }} on ${{ startsWith(matrix.os, 'macos-') && 'macOS' || startsWith(matrix.os, 'windows-') && 'Windows' || 'Linux' }} needs: - prepare runs-on: "${{ matrix.os }}" permissions: contents: read strategy: fail-fast: false matrix: os: - ubuntu-latest # - windows-latest # - macos-latest python-version: - "3.10" - "3.11" - "3.12" - "3.13" - "3.14" - "3.15-dev" steps: - name: Checkout code uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: persist-credentials: false - name: Install Python uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0 with: python-version: "${{ matrix.python-version }}" - name: Install uv uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0 with: enable-cache: false - name: Install command runner run: uv tool install rust-just - name: Install testing dependencies env: MSGSPEC_SANITIZE: "true" MSGSPEC_COVERAGE: "true" run: just env-sync test - name: Run tests with sanitizers env: PYTHONMALLOC: "malloc" ASAN_OPTIONS: "detect_leaks=0" run: >- LD_PRELOAD=$(gcc -print-file-name=libasan.so) just env-run test coverage run -m pytest tests/unit -s - name: Generate coverage files run: |- just env-run test coverage xml find build/temp*/ -name '*.o' -exec gcov -abcu {} + - name: Upload coverage artifacts uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: coverage-${{ matrix.python-version }}-${{ matrix.os }} path: |- coverage.xml _core.c.gcov atof.h.gcov ryu.h.gcov if-no-files-found: error upload-coverage: name: Upload coverage files to Codecov needs: - test runs-on: ubuntu-latest permissions: actions: read contents: read id-token: write steps: - name: Checkout code uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: persist-credentials: false - name: Download coverage artifacts uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: pattern: coverage-* path: coverage-files - name: See the coverage files run: tree -sh coverage-files - name: Upload Codecov uses: codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f # v7.0.0 with: use_oidc: true directory: coverage-files test-integration: name: Run integration tests needs: - test runs-on: ubuntu-latest permissions: contents: read steps: - name: Checkout code uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: persist-credentials: false - name: Install Python uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0 with: python-version-file: pyproject.toml - name: Install uv uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0 with: enable-cache: false - name: Install command runner run: uv tool install rust-just - name: Install testing dependencies run: just env-sync test - name: Run doctests run: just test-doc - name: Run type checker compatibility tests run: just test-typing build-wheels: name: Build wheels ${{ github.event_name == 'release' && 'for release' || '' }} needs: - test - prepare uses: ./.github/workflows/build-wheels.yml permissions: actions: read contents: read with: sdist-name: "${{ needs.prepare.outputs.sdist-name }}" build-all: ${{ github.event_name == 'release' || github.event_name == 'schedule' }} upload-pypi: name: Upload artifacts to PyPI if: github.event_name == 'release' && github.event.action == 'published' needs: - prepare - build-wheels runs-on: ubuntu-latest permissions: actions: read id-token: write steps: - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: pattern: artifact-* merge-multiple: true path: dist - name: Publish package distributions to PyPI uses: pypa/gh-action-pypi-publish@cef221092ed1bacb1cc03d23a2d87d1d172e277b # v1.14.0 python-msgspec-0.22.0/.github/workflows/codspeed.yml000066400000000000000000000052061525673062400224760ustar00rootroot00000000000000name: CodSpeed on: push: branches: - main pull_request: branches: - main paths: - src/** - tests/prof/** - benchmarks/** - pyproject.toml - uv.lock - MANIFEST.in - setup.py - .pytest.toml - .github/workflows/codspeed.yml workflow_dispatch: permissions: {} env: UV_NO_EDITABLE: "true" # cisable glibc CPU-feature detection (AVX2) so benchmarks use the same # memory routines regardless of which CPU the runner lands on, reducing # cross-run variance. See: # https://codspeed.io/blog/why-glibc-faster-github-actions#how-to-fix-it- GLIBC_TUNABLES: "glibc.cpu.hwcaps=-AVX512F,-AVX512DQ,-AVX512_VBMI2,-AVX2,-AVX,-ERMS,-FSRM" RANDOMLY_SEED: "3485796098" jobs: perf_benchmarks: name: performance benchmarks runs-on: codspeed-macro permissions: contents: read id-token: write steps: - name: Checkout code uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: persist-credentials: false - name: Install Python uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0 with: python-version-file: pyproject.toml - name: Install uv uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0 with: enable-cache: false - name: Build msgspec and install profiling dependencies run: uv sync --group test-prof - name: Run benchmarks uses: CodSpeedHQ/action@a4a36bb07c0638b0b4ca52bf1f3dad1b4289e52f # v4.18.1 with: mode: simulation run: uv run --no-sync pytest tests/prof/perf --codspeed --randomly-seed="$RANDOMLY_SEED" -k arm memory_benchmarks: name: Memory benchmarks runs-on: codspeed-macro permissions: contents: read id-token: write steps: - name: Checkout code uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: persist-credentials: false - name: Install Python uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0 with: python-version-file: pyproject.toml - name: Install uv uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0 with: enable-cache: false - name: Build msgspec and install profiling dependencies run: uv sync --group test-prof - name: Run benchmarks uses: CodSpeedHQ/action@a4a36bb07c0638b0b4ca52bf1f3dad1b4289e52f # v4.18.1 with: mode: memory run: uv run --no-sync pytest tests/prof/perf --randomly-seed="$RANDOMLY_SEED" --codspeed -k amd -m memory python-msgspec-0.22.0/.github/workflows/docs-deploy.yml000066400000000000000000000170131525673062400231310ustar00rootroot00000000000000name: docs deploy on: push: branches: - main pull_request_target: branches: - main types: - opened - reopened - synchronize permissions: {} concurrency: group: docs-deploy-${{ github.event.pull_request.number || github.ref }} # Serialize production runs so each compares against the snapshot published # by the preceding run. Preview runs only need their newest result. cancel-in-progress: ${{ github.event_name == 'pull_request_target' }} jobs: docs: name: Build and check docs if: github.event_name == 'push' uses: ./.github/workflows/docs.yml permissions: actions: read contents: read with: cache-namespace: main ref: "${{ github.sha }}" sha: "${{ github.sha }}" preview: name: Deploy preview if: github.event_name == 'pull_request_target' runs-on: ubuntu-latest timeout-minutes: 20 environment: name: docs-preview url: "${{ steps.deploy.outputs.pages-deployment-alias-url }}" permissions: actions: read contents: read steps: - name: Download docs env: GH_TOKEN: "${{ github.token }}" GH_REPO: "${{ github.repository }}" HEAD_SHA: "${{ github.event.pull_request.head.sha }}" run: | set -euo pipefail run_id="" run_url="" for attempt in {1..60}; do run="$( gh run list \ --workflow docs-pr.yml \ --event pull_request \ --commit "${HEAD_SHA}" \ --limit 1 \ --json databaseId,url \ --jq 'if length == 1 then [.[0].databaseId, .[0].url] | @tsv else empty end' )" if [ -z "${run}" ]; then echo "Waiting for docs pr run at ${HEAD_SHA} (${attempt}/60)." sleep 15 continue fi IFS=$'\t' read -r run_id run_url <<< "${run}" echo "Found docs pr run ${run_url}." break done if [ -z "${run_id}" ]; then echo "::error::Timed out waiting for docs pr run at ${HEAD_SHA}." exit 1 fi gh run watch "${run_id}" --compact --exit-status --interval 15 rm -rf site mkdir -p site gh run download "${run_id}" --name docs-site --dir site - &validate-docs-site name: Validate docs site run: | set -euo pipefail test -f site/index.html symlink="$(find site -type l -print -quit)" if [ -n "${symlink}" ]; then echo "::error::Symbolic links are not allowed in docs artifacts: ${symlink}" exit 1 fi # https://developers.cloudflare.com/pages/get-started/direct-upload/#functions for path in site/_worker.js functions; do if [ -e "${path}" ] || [ -L "${path}" ]; then echo "::error::Pages Functions entrypoint is not allowed: ${path}" exit 1 fi done - name: Deploy id: deploy uses: cloudflare/wrangler-action@ebbaa1584979971c8614a24965b4405ff95890e0 # v4.0.0 with: accountId: "${{ secrets.CF_ACCOUNT_ID }}" apiToken: "${{ secrets.CF_PAGES_TOKEN }}" command: >- pages deploy site --project-name=msgspec --branch=pr-${{ github.event.pull_request.number }} --commit-hash=${{ github.event.pull_request.head.sha }} wranglerVersion: 4.98.0 - name: Summarize preview deployment env: PREVIEW_URL: "${{ steps.deploy.outputs.pages-deployment-alias-url }}" run: echo "Pull request docs deployed to ${PREVIEW_URL}" >> "${GITHUB_STEP_SUMMARY}" production: name: Deploy production needs: docs if: github.event_name == 'push' runs-on: ubuntu-latest timeout-minutes: 20 environment: name: docs-live url: https://msgspec.dev permissions: contents: read outputs: ready: "${{ steps.gate.outputs.ready }}" steps: - name: Checkout production snapshot uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: persist-credentials: false ref: cf-pages path: snapshot - name: Download docs uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: name: docs-site path: site - *validate-docs-site - name: Check production deployment id: gate run: | git -C snapshot --work-tree="${GITHUB_WORKSPACE}/site" add --all --force if git -C snapshot diff --cached --quiet; then echo "ready=false" >> "${GITHUB_OUTPUT}" echo "Built docs are identical to the production snapshot; deployment skipped." >> "${GITHUB_STEP_SUMMARY}" exit 0 fi latest_sha="$(git -C snapshot ls-remote --heads origin refs/heads/main | awk '{ print $1 }')" if [ "${latest_sha}" != "${GITHUB_SHA}" ]; then echo "ready=false" >> "${GITHUB_OUTPUT}" echo "Production deployment skipped because ${GITHUB_SHA} is no longer the main branch tip (${latest_sha})." >> "${GITHUB_STEP_SUMMARY}" exit 0 fi echo "ready=true" >> "${GITHUB_OUTPUT}" echo "Built docs differ from the production snapshot." >> "${GITHUB_STEP_SUMMARY}" git -C snapshot diff --cached --name-status | sed -n '1,100p' - name: Deploy if: steps.gate.outputs.ready == 'true' id: deploy uses: cloudflare/wrangler-action@ebbaa1584979971c8614a24965b4405ff95890e0 # v4.0.0 with: accountId: "${{ secrets.CF_ACCOUNT_ID }}" apiToken: "${{ secrets.CF_PAGES_TOKEN }}" command: >- pages deploy site --project-name=msgspec --branch=cf-pages --commit-hash=${{ github.sha }} wranglerVersion: 4.98.0 - name: Summarize production deployment if: steps.gate.outputs.ready == 'true' env: DEPLOYMENT_URL: "${{ steps.deploy.outputs.deployment-url }}" run: echo "Production docs deployed to ${DEPLOYMENT_URL}" >> "${GITHUB_STEP_SUMMARY}" snapshot: name: Publish production snapshot needs: production if: needs.production.outputs.ready == 'true' runs-on: ubuntu-latest timeout-minutes: 10 permissions: contents: write steps: - name: Checkout production snapshot uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: persist-credentials: false ref: cf-pages path: snapshot - name: Download docs uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: name: docs-site path: site - name: Publish production snapshot env: GH_TOKEN: "${{ github.token }}" run: | git -C snapshot --work-tree="${GITHUB_WORKSPACE}/site" add --all --force if git -C snapshot diff --cached --quiet; then echo "The cf-pages production snapshot is already current." >> "${GITHUB_STEP_SUMMARY}" exit 0 fi # Attribute generated commits to GitHub's built-in Actions bot. # The account ID comes from https://api.github.com/users/github-actions%5Bbot%5D. git -C snapshot config user.name "github-actions[bot]" git -C snapshot config user.email "41898282+github-actions[bot]@users.noreply.github.com" git -C snapshot commit --message "deploy: ${GITHUB_SHA}" gh auth setup-git --hostname github.com git -C snapshot push origin HEAD:cf-pages echo "Updated the cf-pages production snapshot." >> "${GITHUB_STEP_SUMMARY}" python-msgspec-0.22.0/.github/workflows/docs-pr.yml000066400000000000000000000011201525673062400222460ustar00rootroot00000000000000name: docs pr on: pull_request: branches: - main types: - opened - reopened - synchronize permissions: {} concurrency: group: docs-pr-${{ github.event.pull_request.number }} cancel-in-progress: true jobs: docs: name: Build and check docs uses: ./.github/workflows/docs.yml permissions: actions: read contents: read with: cache-namespace: "pr-${{ github.event.pull_request.number }}" ref: "${{ format('refs/pull/{0}/merge', github.event.pull_request.number) }}" sha: "${{ github.event.pull_request.head.sha }}" python-msgspec-0.22.0/.github/workflows/docs.yml000066400000000000000000000056161525673062400216450ustar00rootroot00000000000000name: docs on: workflow_call: inputs: ref: description: Repository ref to build required: true type: string cache-namespace: description: Trusted namespace used to isolate link-check caches required: true type: string sha: description: Source commit used to key caches required: true type: string env: UV_NO_EDITABLE: "true" UV_NO_SYNC: "true" jobs: build: runs-on: ubuntu-latest permissions: contents: read steps: - name: Checkout code uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: persist-credentials: false ref: "${{ inputs.ref }}" - name: Fetch release history uses: ./.github/actions/fetch-release-history with: github-token: "${{ github.token }}" ref: "${{ inputs.ref }}" - name: Install Python uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0 with: python-version-file: pyproject.toml - name: Install uv uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0 with: enable-cache: false - name: Install command runner run: uv tool install rust-just - name: Install dependencies run: just env-sync doc - name: Build docs run: just doc-build - name: Upload docs uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: docs-site path: site if-no-files-found: error include-hidden-files: true retention-days: 1 check: name: Check links needs: build runs-on: ubuntu-latest permissions: actions: read contents: read steps: - name: Checkout code uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: persist-credentials: false ref: "${{ inputs.ref }}" - name: Download docs uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: name: docs-site path: site - name: Restore link check cache uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 with: path: .lycheecache # Caches are immutable. Restore the newest cache in this trusted # namespace, then save updated responses under the current commit. key: cache-lychee-${{ inputs.cache-namespace }}-${{ inputs.sha }} restore-keys: cache-lychee-${{ inputs.cache-namespace }}- - name: Check links uses: lycheeverse/lychee-action@8646ba30535128ac92d33dfc9133794bfdd9b411 # v2.8.0 with: lycheeVersion: v0.21.0 fail: true failIfEmpty: true token: "${{ github.token }}" args: >- --cache --verbose --no-progress README.md site python-msgspec-0.22.0/.github/workflows/manual-profile.yml000066400000000000000000000022241525673062400236200ustar00rootroot00000000000000name: Manual Profile on: workflow_dispatch: inputs: version: description: Version of msgspec to profile from PyPI (leave empty to build from source) type: string python: description: Minor version of Python to use for profiling type: string permissions: {} jobs: prepare: name: Prepare build if: inputs.version == '' uses: ./.github/workflows/prepare-build.yml permissions: contents: read with: run-static-analysis: false fetch-latest-python: false build-wheels: name: Build wheels if: inputs.version == '' needs: - prepare uses: ./.github/workflows/build-wheels.yml permissions: actions: read contents: read with: sdist-name: "${{ needs.prepare.outputs.sdist-name }}" profile: name: Run profiling tests needs: - build-wheels if: always() && (needs.build-wheels.result == 'success' || needs.build-wheels.result == 'skipped') uses: ./.github/workflows/profile.yml permissions: actions: read contents: read with: version: "${{ inputs.version }}" python: "${{ inputs.python }}" python-msgspec-0.22.0/.github/workflows/prepare-build.yml000066400000000000000000000054071525673062400234460ustar00rootroot00000000000000name: Prepare Build on: workflow_call: inputs: run-static-analysis: description: Whether to run static analysis checks type: boolean fetch-latest-python: description: Whether to fetch the latest supported Python version type: boolean outputs: sdist-name: description: Name of the source distribution file value: "${{ jobs.prepare.outputs.sdist-name }}" latest-supported-python: description: Latest supported Python version value: "${{ jobs.prepare.outputs.latest-supported-python }}" jobs: prepare: name: Prepare build ${{ inputs.run-static-analysis && 'with static analysis' || '' }} runs-on: ubuntu-latest permissions: contents: read outputs: sdist-name: "${{ steps.build-sdist.outputs.file-name }}" latest-supported-python: "${{ steps.latest-supported-python.outputs.version }}" env: UV_NO_EDITABLE: "true" UV_NO_SYNC: "true" steps: - name: Checkout code uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: persist-credentials: false - name: Fetch release history uses: ./.github/actions/fetch-release-history with: github-token: "${{ github.token }}" - name: Install Python uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0 with: python-version-file: pyproject.toml - name: Install uv uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0 with: enable-cache: false - name: Install command runner if: inputs.run-static-analysis run: uv tool install rust-just - name: Install static analysis dependencies if: inputs.run-static-analysis run: just env-sync hooks - name: Run hooks if: inputs.run-static-analysis run: just hooks-check - name: Build source distribution id: build-sdist run: |- uv build --sdist shopt -s nullglob sdists=(dist/*.tar.gz) if [ "${#sdists[@]}" -ne 1 ]; then echo "::error::Expected exactly one source distribution, found ${#sdists[@]}" exit 1 fi sdist_name=$(basename -- "${sdists[0]}") echo "file-name=${sdist_name}" >> "${GITHUB_OUTPUT}" - name: Upload artifact uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: artifact-sdist path: dist/${{ steps.build-sdist.outputs.file-name }} if-no-files-found: error - name: Fetch latest supported Python if: inputs.fetch-latest-python id: latest-supported-python uses: ./.github/actions/latest-supported-python with: github-token: "${{ github.token }}" python-msgspec-0.22.0/.github/workflows/profile.yml000066400000000000000000000065251525673062400223550ustar00rootroot00000000000000name: Profile on: workflow_call: inputs: version: description: Version of msgspec to profile from PyPI (leave empty to use artifacts) type: string python: description: Minor version of Python to use for profiling type: string jobs: profile: name: Profile ${{ startsWith(matrix.os, 'macos-') && 'macOS' || startsWith(matrix.os, 'windows-') && 'Windows' || 'Linux' }} (${{ matrix.archs }}) runs-on: "${{ matrix.os }}" permissions: actions: read contents: read strategy: fail-fast: false matrix: include: - os: ubuntu-24.04-arm archs: aarch64 - os: ubuntu-latest archs: x86_64 - os: macos-latest archs: arm64 - os: macos-15-intel archs: x86_64 - os: windows-latest archs: AMD64 env: UV_NO_EDITABLE: "true" UV_NO_SYNC: "true" steps: - name: Checkout code uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: persist-credentials: false - name: Fetch latest supported Python if: inputs.python == '' id: latest-supported-python uses: ./.github/actions/latest-supported-python with: github-token: "${{ github.token }}" - name: Install Python uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0 with: python-version: "${{ inputs.python || steps.latest-supported-python.outputs.version }}" - name: Install uv uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0 with: enable-cache: false - name: Install command runner run: uv tool install rust-just - name: Set profiling environment metadata id: metadata env: PYTHON_VERSION: "${{ inputs.python || steps.latest-supported-python.outputs.version }}" shell: bash run: |- echo "UV_PYTHON=${PYTHON_VERSION}" >> "${GITHUB_ENV}" echo "python-version=${PYTHON_VERSION}" >> "${GITHUB_OUTPUT}" echo "env-path=$(just env-path prof)" >> "${GITHUB_OUTPUT}" - name: Install profiling dependencies env: UV_PROJECT_ENVIRONMENT: "${{ steps.metadata.outputs.env-path }}" run: uv sync --only-group test-prof - name: Download artifacts if: inputs.version == '' uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: # Profiling only downloads native wheels, whose build artifacts use # runner-and-architecture names. name: artifact-wheels-${{ matrix.os }}-${{ matrix.archs }} path: dist merge-multiple: true - name: Install from ${{ inputs.version == '' && 'artifact' || format('PyPI (version {0})', inputs.version) }} env: MSGSPEC_VERSION: "${{ inputs.version }}" VIRTUAL_ENV: "${{ steps.metadata.outputs.env-path }}" shell: bash run: |- if [ -z "${MSGSPEC_VERSION}" ]; then uv pip install --no-index --find-links dist msgspec else uv pip install "msgspec==${MSGSPEC_VERSION}" fi # TODO: set up infra to commit results after each merge and then make tests compare - name: Run profiling tests on Python ${{ steps.metadata.outputs.python-version }} run: just test-perf all --calibrate --rounds 10000 python-msgspec-0.22.0/.github/zizmor.yml000066400000000000000000000003671525673062400202100ustar00rootroot00000000000000rules: dangerous-triggers: ignore: # The trusted default-branch policy reads the proposed merge as data. - ci-capability-policy.yml # Trusted orchestration isolates the untrusted docs build from deployment. - docs-deploy.yml python-msgspec-0.22.0/.gitignore000066400000000000000000000014151525673062400165560ustar00rootroot00000000000000# Editor config folders ## Vscode .settings/ .project .vscode/ .vs/ ## PyCharm/IntelliJ-generated files *.iml .idea/ # Dotenv files meant for local use or those containing secrets .env .env.local .env.*.local # Python cached sources __pycache__/ *.pyc # Virtual environments .venv*/ venv*/ # Version file /src/msgspec/_version.py # uv dependency lock file uv.lock # Pytest and coverage .coverage .pytest/ .pytest_cache/ htmlcov/ # Ruff Cache .ruff_cache/ # Mypy Cache .mypy_cache/ # Docs build site/ /.doctrees/ /.wrangler/ # Docs link check cache /.lycheecache # Benchmark outputs benchmarks/*.html benchmarks/*.json # Setuptools/twine-generated files, compiled sources. build/ dist/ *.egg-info/ pip-wheel-metadata/ *.so *.o *.pyd # Misc *.pem out/ .cache/ .DS_Store python-msgspec-0.22.0/.justfile000066400000000000000000000165201525673062400164170ustar00rootroot00000000000000# Disable showing recipe lines before execution. set quiet # Enable unstable features. set unstable # Configure the shell for Windows. set windows-shell := ["pwsh.exe", "-NoProfile", "-NonInteractive", "-ExecutionPolicy", "Bypass", "-Command"] # Provide a consistent experience across Docker-compatible CLIs. export DOCKER_CLI_HINTS := "0" # We don't want to install any dev dependencies by default. export UV_NO_DEV := "true" # We don't want activated virtual environments to interfere with environment management. unexport VIRTUAL_ENV # We apply a unique label to each dev container that is used to find the container ID. # The devcontainer CLI automatically adds the `devcontainer.local_folder` label but on # Windows the drive letter is lowercased. repo_id := sha256(lowercase(justfile_directory())) # This is the parent directory for virtual environments. env_base := join(data_local_directory(), "msgspec", "dev", repo_id, "venvs") # This determines the version of Python with which to use in environments rather than # the default behavior of using the highest version compatible with the project. python := "" # This determines whether to rebuild the C extension for recipes that depend on the project. rebuild := "false" # This determines whether to build a debug version of the C extension. debug := "false" # List all targets. [private] default: just --list # Invoke the Git hook manager. [group: "Static Analysis"] prek arg="--help" *args: ( env-run "hooks" "prek" arg args ) alias pre-commit := prek # Run the hooks. [group: "Static Analysis"] hooks-fix *args: ( env-run "hooks" "prek run --all-files" args ) alias hooks := hooks-fix # Run the hooks without applying fixes. [group: "Static Analysis"] hooks-check *args: ( env-run "hooks" "prek run --all-files --hook-stage manual" args ) alias check := hooks-check # Run all tests. [group: "Testing"] test-all *args: ( env-run "test" "pytest" args ) ( test-doc args ) # Run unit tests. [group: "Testing"] test-unit *args: ( env-run "test" "pytest -o testpaths=tests/unit" args ) alias test := test-unit # Run type checker compatibility tests. [group: "Testing"] test-typing: ( env-run "test" "mypy tests/typing" ) ( env-run "test" "pyright tests/typing" ) ( env-run "test" "pyrefly check tests/typing" ) ( env-run "test" "python scripts/stubtest.py" ) # Run doctests. [group: "Testing"] test-doc *args: ( env-run "test" "pytest --doctest-modules --pyargs msgspec" args ) # Build the documentation. [group: "Documentation"] doc-build: ( env-run "doc" "sphinx-build -d .doctrees -b html docs site --fail-on-warning" ) # Serve the documentation. [group: "Documentation"] doc-serve: ( env-run "doc" "python -c \"import pathlib,webbrowser;webbrowser.open_new_tab(pathlib.Path('site/index.html').absolute().as_uri())\"" ) # Run performance tests. [group: "Profiling"] test-perf name="" *args: ( env-run "prof" ( if name == "" { "python -c \"import os;print('Available tests:', os.linesep.join(['', *sorted(e[5:].split('.')[0] for e in os.listdir('tests/prof/perf') if e.startswith('test_')), 'all (run everything)']))\"" } else { ( if name =~ "^-" { error( "Invalid test name: " + name ) } else if name == "all" { "pytest -o testpaths=tests/prof/perf" } else { "pytest tests/prof/perf/test_" + name + ".py" } ) + " --benchmark-name short --benchmark-disable-gc" } ) args ) # Run benchmarks. [group: "Benchmarking"] bench-run name="" *args: ( env-run "bench" ( if name == "" { "python -c \"import os;print('Available benchmarks:', os.linesep.join(['', *sorted(e[6:].split('.')[0] for e in os.listdir('benchmarks') if e.startswith('bench_')), 'all (run everything)']))\"" } else { "python -m benchmarks.bench_" + name } ) args ) alias bench := bench-run # Run a command within an environment. [group: "Environment Management"] env-run env +cmd: ( _with_env env "run" "--" cmd ) alias env := env-run # Sync an environment's dependencies. [group: "Environment Management"] env-sync env="test": ( _with_env ( if env == "all" { "none" } else { env } ) ( if env == "all" { "run" } else { "sync" } ) ( if env == "all" { "just _env_sync_all" } else { "" } ) ) alias sync := env-sync # Display the path to an environment. [group: "Environment Management"] env-path env="": echo {{ \ if env == "" { \ quote(env_base) \ } else { \ quote(join(env_base, env)) \ } \ }} # Start the dev container. [group: "Dev Container"] dev-start: devcontainer up --workspace-folder . --id-label repo.id={{ repo_id }} # Run a command within the dev container. [group: "Dev Container"] dev-run +cmd: ( _with_dev_container_id "docker exec --user vscode -it $id zsh -lc " + quote(cmd) ) alias run := dev-run # Open a shell in the dev container. [group: "Dev Container"] dev-shell cmd="zsh -l": ( _with_dev_container_id "docker exec --user vscode -it $id " + cmd ) alias shell := dev-shell # Stop the dev container. [group: "Dev Container"] dev-stop: ( _with_dev_container_id "docker stop $id" ) # Remove the dev container. [group: "Dev Container"] dev-remove: ( _with_dev_container_id "docker rm $id" ) [private] _with_dev_container_id cmd: {{ \ if os() == "windows" { \ "$id = docker ps --all --format '{{.ID}}' --filter 'label=repo.id=" + repo_id + "'; " + \ "if ($id) { " + cmd + " } else { Write-Host 'No devcontainer running' }" \ } else { \ "id=$(docker ps --all --format '{{.ID}}' --filter 'label=repo.id=" + repo_id + "'); " + \ "if [ -n \"$id\" ]; then " + cmd + "; else echo 'No devcontainer running'; fi" \ } \ }} [private] _env_sync_all: ( _with_env "test" "sync" ) ( _with_env "doc" "sync" ) ( _with_env "bench" "sync" ) ( _with_env "prof" "sync" ) [private] [no-exit-message] [no-cd] _with_env env action *args: {{ \ if env == "none" { \ "" \ } else { \ if os() == "windows" { \ "$env:UV_PROJECT_ENVIRONMENT=" + quote(join(env_base, env)) + "; " \ } else { \ "UV_PROJECT_ENVIRONMENT=" + quote(join(env_base, env)) + " " \ } \ } \ }}{{ \ if python == "" { \ "" \ } else { \ if os() == "windows" { \ "$env:UV_PYTHON=" + quote(python) + "; " \ } else { \ "UV_PYTHON=" + quote(python) + " " \ } \ } \ }}{{ \ if debug =~ "^(true|1)$" { \ if os() == "windows" { \ "$env:MSGSPEC_DEBUG='1'; " \ } else { \ "MSGSPEC_DEBUG='1' " \ } \ } else { \ "" \ } \ }}uv {{ \ if action == "run" { \ "run" \ } else if action == "sync" { \ "sync" \ } else { \ error( \ "Unknown action: " + action \ ) \ } \ }}{{ \ if rebuild =~ "^(true|1)$" { \ " --reinstall-package msgspec" \ } else { \ "" \ } \ }} {{ \ if env == "test" { \ "--group test-unit --group test-typing" \ } else if env == "doc" { \ "--group doc" \ } else if env == "prof" { \ "--group test-prof" \ } else if env == "bench" { \ "--group bench" \ } else if env == "hooks" { \ "--only-group hooks" \ } else if env == "none" { \ "--isolated --no-sync --no-config" \ } else { \ error( \ "Unknown environment: " + env \ ) \ } \ }} {{ args }} python-msgspec-0.22.0/.pre-commit-config.yaml000066400000000000000000000017161525673062400210530ustar00rootroot00000000000000local: &local language: system pass_filenames: false local-pre-commit: &local-pre-commit <<: *local require_serial: true stages: [pre-commit] local-manual: &local-manual <<: *local stages: [manual] repos: - repo: local hooks: # These default hooks apply fixes. - id: python-lint name: Lint Python code entry: ruff check --fix <<: *local-pre-commit - id: python-format name: Format Python code entry: ruff format <<: *local-pre-commit # These manual hooks suffixed with `-check` run their equivalently named default hooks without applying fixes. - id: python-lint-check name: Lint Python code (check-only) entry: ruff check <<: *local-manual - id: python-format-check name: Format Python code (check-only) entry: ruff format --diff <<: *local-manual # These hooks never apply fixes and run in all cases. - id: spelling name: Check for spelling errors entry: codespell <<: *local python-msgspec-0.22.0/.pytest.toml000066400000000000000000000004311525673062400170660ustar00rootroot00000000000000[pytest] # This determines which tests are collected when no arguments are passed. # We default to all non-profiling test suites and we run unit tests first. testpaths = [ "tests/unit", ] # Turn all warnings into errors. filterwarnings = [ "error", ] markers = [ "memory", ]python-msgspec-0.22.0/.ruff.toml000066400000000000000000000012611525673062400165020ustar00rootroot00000000000000line-length = 88 output-prefer-rule-codes = true extend-exclude = [ "src/msgspec/_version.py", "tests/typing/basic_typing_examples.py", "tests/unit/test_JSONTestSuite.py", ] [lint] select = [ "E", # PEP8 Errors "F", # Pyflakes "I", # Import sorting "W", # PEP8 Warnings ] ignore = [ "E721", # Comparing types instead of isinstance "E741", # Ambiguous variable names "E501", # Conflicts with ruff format "W191", # Conflicts with ruff format ] [lint.extend-per-file-ignores] "src/msgspec/__init__.py" = ["E402", "F401"] "src/msgspec/__init__.pyi" = ["F401"] "src/msgspec/json.py" = ["F401"] "src/msgspec/msgpack.py" = ["F401"] [lint.isort] combine-as-imports = true python-msgspec-0.22.0/LICENSE000066400000000000000000000027321525673062400155760ustar00rootroot00000000000000Copyright (c) 2021, Jim Crist-Harif All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. python-msgspec-0.22.0/MANIFEST.in000066400000000000000000000002251525673062400163220ustar00rootroot00000000000000prune .devcontainer prune .github prune benchmarks prune docs prune examples prune scripts exclude lychee.toml exclude .* include .cibuildwheel.toml python-msgspec-0.22.0/README.md000066400000000000000000000106151525673062400160470ustar00rootroot00000000000000

msgspec

[![CI](https://github.com/msgspec/msgspec/actions/workflows/ci.yml/badge.svg)](https://github.com/msgspec/msgspec/actions/workflows/ci.yml) [![Documentation](https://img.shields.io/badge/docs-latest-blue.svg)](https://msgspec.dev) [![License](https://img.shields.io/github/license/msgspec/msgspec.svg)](https://github.com/msgspec/msgspec/blob/main/LICENSE) [![PyPI Version](https://img.shields.io/pypi/v/msgspec.svg)](https://pypi.org/project/msgspec/) [![Conda Version](https://img.shields.io/conda/vn/conda-forge/msgspec.svg)](https://anaconda.org/conda-forge/msgspec) [![Code Coverage](https://codecov.io/gh/msgspec/msgspec/branch/main/graph/badge.svg)](https://app.codecov.io/gh/msgspec/msgspec)
`msgspec` is a *fast* serialization and validation library, with builtin support for [JSON](https://json.org), [MessagePack](https://msgpack.org), [YAML](https://yaml.org), and [TOML](https://toml.io/en/). It features: - 🚀 **High performance encoders/decoders** for common protocols. The JSON and MessagePack implementations regularly [benchmark](https://msgspec.dev/benchmarks) as the fastest options for Python. - 🎉 **Support for a wide variety of Python types**. Additional types may be supported through [extensions](https://msgspec.dev/extending). - � **Zero-cost schema validation** using familiar Python type annotations. In [benchmarks](https://msgspec.dev/benchmarks) `msgspec` decodes *and* validates JSON faster than [orjson](https://github.com/ijl/orjson) can decode it alone. - ✨ **A speedy Struct type** for representing structured data. If you already use [dataclasses](https://docs.python.org/3/library/dataclasses.html) or [attrs](https://www.attrs.org/en/stable/), [structs](https://msgspec.dev/structs) should feel familiar. However, they're [5-60x faster](https://msgspec.dev/benchmarks#structs) for common operations. All of this is included in a [lightweight library](https://msgspec.dev/benchmarks#library-size) with no required dependencies. --- `msgspec` may be used for serialization alone, as a faster JSON or MessagePack library. For the greatest benefit though, we recommend using `msgspec` to handle the full serialization & validation workflow: **Define** your message schemas using standard Python type annotations. ```python >>> import msgspec >>> class User(msgspec.Struct): ... """A new type describing a User""" ... name: str ... groups: set[str] = set() ... email: str | None = None ``` **Encode** messages as JSON, or one of the many other supported protocols. ```python >>> alice = User("alice", groups={"admin", "engineering"}) >>> alice User(name='alice', groups={"admin", "engineering"}, email=None) >>> msg = msgspec.json.encode(alice) >>> msg b'{"name":"alice","groups":["admin","engineering"],"email":null}' ``` **Decode** messages back into Python objects, with optional schema validation. ```python >>> msgspec.json.decode(msg, type=User) User(name='alice', groups={"admin", "engineering"}, email=None) >>> msgspec.json.decode(b'{"name":"bob","groups":[123]}', type=User) Traceback (most recent call last): File "", line 1, in msgspec.ValidationError: Expected `str`, got `int` - at `$.groups[0]` ``` `msgspec` is designed to be as performant as possible, while retaining some of the nicities of validation libraries like [pydantic](https://pydantic.dev/docs/validation/latest/get-started/). For supported types, encoding/decoding a message with `msgspec` can be [~10-80x faster than alternative libraries](https://msgspec.dev/benchmarks).

See [the documentation](https://msgspec.dev) for more information. ## LICENSE New BSD. See the [License File](https://github.com/msgspec/msgspec/blob/main/LICENSE). python-msgspec-0.22.0/benchmarks/000077500000000000000000000000001525673062400167025ustar00rootroot00000000000000python-msgspec-0.22.0/benchmarks/__init__.py000066400000000000000000000000001525673062400210010ustar00rootroot00000000000000python-msgspec-0.22.0/benchmarks/bench_encodings.py000066400000000000000000000130351525673062400223660ustar00rootroot00000000000000from __future__ import annotations import dataclasses import importlib.metadata import json import sys import timeit from typing import Any, Callable, Literal import msgspec from .generate_data import make_filesystem_data class File(msgspec.Struct, kw_only=True, omit_defaults=True, tag="file"): name: str created_by: str created_at: str updated_by: str | None = None updated_at: str | None = None nbytes: int permissions: Literal["READ", "WRITE", "READ_WRITE"] class Directory(msgspec.Struct, kw_only=True, omit_defaults=True, tag="directory"): name: str created_by: str created_at: str updated_by: str | None = None updated_at: str | None = None contents: list[File | Directory] @dataclasses.dataclass class Benchmark: label: str version: str encode: Callable decode: Callable schema: Any = None def run(self, data: bytes) -> dict: if self.schema is not None: data = msgspec.convert(data, self.schema) timer = timeit.Timer("func(data)", globals={"func": self.encode, "data": data}) n, t = timer.autorange() encode_time = t / n data = self.encode(data) timer = timeit.Timer("func(data)", globals={"func": self.decode, "data": data}) n, t = timer.autorange() decode_time = t / n return { "label": self.label, "encode": encode_time, "decode": decode_time, } def json_benchmarks(): import orjson import rapidjson import simdjson import ujson simdjson_ver = importlib.metadata.version("pysimdjson") rj_dumps = rapidjson.Encoder() rj_loads = rapidjson.Decoder() def uj_dumps(obj): return ujson.dumps(obj) enc = msgspec.json.Encoder() dec = msgspec.json.Decoder(Directory) dec2 = msgspec.json.Decoder() return [ Benchmark("msgspec structs", None, enc.encode, dec.decode, Directory), Benchmark("msgspec", msgspec.__version__, enc.encode, dec2.decode), Benchmark("json", None, json.dumps, json.loads), Benchmark("orjson", orjson.__version__, orjson.dumps, orjson.loads), Benchmark("ujson", ujson.__version__, uj_dumps, ujson.loads), Benchmark("rapidjson", rapidjson.__version__, rj_dumps, rj_loads), Benchmark("simdjson", simdjson_ver, simdjson.dumps, simdjson.loads), ] def msgpack_benchmarks(): import msgpack import ormsgpack enc = msgspec.msgpack.Encoder() dec = msgspec.msgpack.Decoder(Directory) dec2 = msgspec.msgpack.Decoder() return [ Benchmark("msgspec structs", None, enc.encode, dec.decode, Directory), Benchmark("msgspec", msgspec.__version__, enc.encode, dec2.decode), Benchmark("msgpack", msgpack.__version__, msgpack.dumps, msgpack.loads), Benchmark( "ormsgpack", ormsgpack.__version__, ormsgpack.packb, ormsgpack.unpackb ), ] def main(): import argparse parser = argparse.ArgumentParser( description="Benchmark different python serialization libraries" ) parser.add_argument( "--versions", action="store_true", help="Output library version info, and exit immediately", ) parser.add_argument( "-n", type=int, help="The number of objects in the generated data, defaults to 1000", default=1000, ) parser.add_argument( "-p", "--protocol", choices=["json", "msgpack"], default="json", help="The protocol to benchmark, defaults to JSON", ) parser.add_argument( "--json", action="store_true", help="whether to output the results as json", ) args = parser.parse_args() benchmarks = json_benchmarks() if args.protocol == "json" else msgpack_benchmarks() if args.versions: for bench in benchmarks: if bench.version is not None: print(f"- {bench.label}: {bench.version}") sys.exit(0) data = make_filesystem_data(args.n) results = [benchmark.run(data) for benchmark in benchmarks] if args.json: for line in results: print(json.dumps(line)) else: # Compose the results table results.sort(key=lambda row: row["encode"] + row["decode"]) best_et = results[0]["encode"] best_dt = results[0]["decode"] best_tt = best_et + best_dt columns = ( "", "encode (μs)", "vs.", "decode (μs)", "vs.", "total (μs)", "vs.", ) rows = [ ( r["label"], f"{1_000_000 * r['encode']:.1f}", f"{r['encode'] / best_et:.1f}", f"{1_000_000 * r['decode']:.1f}", f"{r['decode'] / best_dt:.1f}", f"{1_000_000 * (r['encode'] + r['decode']):.1f}", f"{(r['encode'] + r['decode']) / best_tt:.1f}", ) for r in results ] widths = tuple( max(max(map(len, x)), len(c)) for x, c in zip(zip(*rows), columns) ) row_template = ("|" + (" %%-%ds |" * len(columns))) % widths header = row_template % tuple(columns) bar_underline = "+%s+" % "+".join("=" * (w + 2) for w in widths) bar = "+%s+" % "+".join("-" * (w + 2) for w in widths) parts = [bar, header, bar_underline] for r in rows: parts.append(row_template % r) parts.append(bar) print("\n".join(parts)) if __name__ == "__main__": main() python-msgspec-0.22.0/benchmarks/bench_gc.py000066400000000000000000000053751525673062400210160ustar00rootroot00000000000000"""This file benchmarks GC collection time for a large number of tiny dataclass-like instances. For each type, the following is measured: - Time for a single full GC pass over all the data. - Amount of memory used to hold all the data """ import gc import sys import time import msgspec def sizeof(x, _seen=None): """Get the recursive sizeof for an object (memoized). Not generic, works on types used in this benchmark. """ if _seen is None: _seen = set() _id = id(x) if _id in _seen: return 0 _seen.add(_id) size = sys.getsizeof(x) if isinstance(x, dict): for k, v in x.items(): size += sizeof(k, _seen) size += sizeof(v, _seen) if hasattr(x, "__dict__"): size += sizeof(x.__dict__, _seen) if hasattr(x, "__slots__"): for k in x.__slots__: size += sizeof(k, _seen) size += sizeof(getattr(x, k), _seen) return size class Point(msgspec.Struct): x: int y: int z: int class PointGCFalse(msgspec.Struct, gc=False): x: int y: int z: int class PointClass: def __init__(self, x, y, z): self.x = x self.y = y self.z = z class PointClassSlots: __slots__ = ("x", "y", "z") def __init__(self, x, y, z): self.x = x self.y = y self.z = z def bench_gc(cls): # Allocate a dict of structs data = {i: cls(i, i, i) for i in range(1_000_000)} # Run a full collection start = time.perf_counter() gc.collect() stop = time.perf_counter() gc_time = (stop - start) * 1e3 mibytes = sizeof(data) / (2**20) return gc_time, mibytes def format_table(results): columns = ("", "GC time (ms)", "Memory Used (MiB)") rows = [] for name, t, mem in results: rows.append((f"**{name}**", f"{t:.2f}", f"{mem:.2f}")) widths = tuple(max(max(map(len, x)), len(c)) for x, c in zip(zip(*rows), columns)) row_template = ("|" + (" %%-%ds |" * len(columns))) % widths header = row_template % tuple(columns) bar_underline = "+%s+" % "+".join("=" * (w + 2) for w in widths) bar = "+%s+" % "+".join("-" * (w + 2) for w in widths) parts = [bar, header, bar_underline] for r in rows: parts.append(row_template % r) parts.append(bar) return "\n".join(parts) def main(): results = [] for name, cls in [ ("standard class", PointClass), ("standard class with __slots__", PointClassSlots), ("msgspec struct", Point), ("msgspec struct with gc=False", PointGCFalse), ]: print(f"Benchmarking {name}...") gc_time, mibytes = bench_gc(cls) results.append((name, gc_time, mibytes)) print(format_table(results)) if __name__ == "__main__": main() python-msgspec-0.22.0/benchmarks/bench_large_json.py000066400000000000000000000112471525673062400225430ustar00rootroot00000000000000import subprocess import sys import tempfile import requests TEMPLATE = """ import resource import time with open({path!r}, "rb") as f: data = f.read() initial_rss = resource.getrusage(resource.RUSAGE_SELF).ru_maxrss {setup} start = time.perf_counter() for _ in range(5): decode(data) stop = time.perf_counter() max_rss = resource.getrusage(resource.RUSAGE_SELF).ru_maxrss # mem_mib = (max_rss * 1024 - len(data)) / (1024 * 1024) mem_mib = (max_rss - initial_rss) / 1024 time_ms = ((stop - start) / 5) * 1000 print([mem_mib, time_ms]) """ JSON = """ import json decode = json.loads """ UJSON = """ import ujson decode = ujson.loads """ ORJSON = """ import orjson decode = orjson.loads """ RAPIDJSON = """ import rapidjson decode = rapidjson.loads """ SIMDJSON = """ import simdjson decode = simdjson.loads """ MSGSPEC = """ import msgspec decode = msgspec.json.decode """ MSGSPEC_STRUCTS = """ import msgspec from typing import Union class Package(msgspec.Struct, gc=False): build: str build_number: int depends: tuple[str, ...] md5: str name: str sha256: str subdir: str version: str license: str = "" noarch: str | bool | None = None size: int = 0 timestamp: int = 0 class RepoData(msgspec.Struct, gc=False): repodata_version: int info: dict packages: dict[str, Package] removed: tuple[str, ...] decode = msgspec.json.Decoder(RepoData).decode """ def main(): import argparse benchmarks = [ ("json", None, JSON), ("ujson", "ujson", UJSON), ("orjson", "orjson", ORJSON), ("rapidjson", "python-rapidjson", RAPIDJSON), ("simdjson", "pysimdjson", SIMDJSON), ("msgspec", "msgspec", MSGSPEC), ("msgspec structs", None, MSGSPEC_STRUCTS), ] benchmark_names = [bench_data[0] for bench_data in benchmarks] parser = argparse.ArgumentParser( description="Benchmark decoding a large JSON message using various JSON libraries" ) parser.add_argument( "-b", "--bench-name", dest="bench_names", nargs="*", choices=benchmark_names, default=benchmark_names, help="A list of benchmark names to run. Defaults to all.", ) parser.add_argument( "--versions", action="store_true", help="Output library version info, and exit immediately", ) args = parser.parse_args() bench_names = set(args.bench_names) # Used as the baseline for comparisons bench_names.add("msgspec structs") if args.versions: import importlib.metadata for _, lib, _ in benchmarks: if lib is not None: version = importlib.metadata.version(lib) print(f"- {lib}: {version}") sys.exit(0) with tempfile.NamedTemporaryFile() as f: # Download the repodata.json resp = requests.get( "https://conda.anaconda.org/conda-forge/noarch/repodata.json" ) resp.raise_for_status() f.write(resp.content) # Run the benchmark for each library results = {} import ast for name, _, setup in benchmarks: if name not in bench_names: continue script = TEMPLATE.format(path=f.name, setup=setup) # We execute each script in a subprocess to isolate their memory usage output = subprocess.check_output([sys.executable, "-c", script]) results[name] = ast.literal_eval(output.decode()) # Compose the results table best_mem, best_time = results["msgspec structs"] # Avoid division by zero if memory is 0 if not best_mem: best_mem = 1.0 columns = ( "", "memory (MiB)", "vs.", "time (ms)", "vs.", ) rows = [ ( f"**{name}**", f"{mem:.1f}", f"{mem / best_mem:.1f}x", f"{time:.1f}", f"{time / best_time:.1f}x", ) for name, (mem, time) in results.items() ] rows.sort(key=lambda x: float(x[1])) widths = tuple( max(max(map(len, x)), len(c)) for x, c in zip(zip(*rows), columns) ) row_template = ("|" + (" %%-%ds |" * len(columns))) % widths header = row_template % tuple(columns) bar_underline = "+%s+" % "+".join("=" * (w + 2) for w in widths) bar = "+%s+" % "+".join("-" * (w + 2) for w in widths) parts = [bar, header, bar_underline] for r in rows: parts.append(row_template % r) parts.append(bar) print("\n".join(parts)) if __name__ == "__main__": main() python-msgspec-0.22.0/benchmarks/bench_library_size.py000066400000000000000000000064661525673062400231250ustar00rootroot00000000000000""" This benchmark compares the installed library size between msgspec and pydantic in a Python 3.10 x86 environment. """ import io import zipfile import requests def get_latest_noarch_wheel_size(library): """Get the total uncompressed size of the latest noarch wheel""" resp = requests.get(f"https://pypi.org/pypi/{library}/json").json() version = resp["info"]["version"] files = {} for file_info in resp["releases"][version]: name = file_info["filename"] url = file_info["url"] if name.endswith(".whl"): files[name] = url if len(files) != 1: raise ValueError( f"Expected to find only 1 matching file for {library}, got {list(files)}" ) url = list(files.values())[0] resp = requests.get(url) fil = io.BytesIO(resp.content) zfil = zipfile.ZipFile(fil) size = sum(f.file_size for f in zfil.filelist) return version, size def get_latest_manylinux_wheel_size(library): """Get the total uncompressed size of the latest Python 3.10 manylinux x86_64 wheel for the library""" resp = requests.get(f"https://pypi.org/pypi/{library}/json").json() version = resp["info"]["version"] files = {} for file_info in resp["releases"][version]: name = file_info["filename"] url = file_info["url"] if "310" in name and "manylinux_2_17_x86_64" in name and "pp73" not in name: files[name] = url if len(files) != 1: raise ValueError( f"Expected to find only 1 matching file for {library}, got {list(files)}" ) url = list(files.values())[0] resp = requests.get(url) fil = io.BytesIO(resp.content) zfil = zipfile.ZipFile(fil) size = sum(f.file_size for f in zfil.filelist) return version, size def main(): msgspec_version, msgspec_size = get_latest_manylinux_wheel_size("msgspec") pydantic_version, pydantic_size = get_latest_noarch_wheel_size("pydantic") _, pydantic_core_size = get_latest_manylinux_wheel_size("pydantic-core") _, typing_extensions_size = get_latest_noarch_wheel_size("typing-extensions") _, annotated_types_size = get_latest_noarch_wheel_size("annotated-types") data = [ ("msgspec", msgspec_version, msgspec_size), ( "pydantic", pydantic_version, pydantic_size + pydantic_core_size + typing_extensions_size + annotated_types_size, ), ] data.sort(key=lambda x: x[2]) msgspec_size = next(s for l, _, s in data if l == "msgspec") columns = ("", "version", "size (MiB)", "vs. msgspec") rows = [ ( f"**{lib}**", version, f"{size / (1024 * 1024):.2f}", f"{size / msgspec_size:.2f}x", ) for lib, version, size in data ] widths = tuple(max(max(map(len, x)), len(c)) for x, c in zip(zip(*rows), columns)) row_template = ("|" + (" %%-%ds |" * len(columns))) % widths header = row_template % tuple(columns) bar_underline = "+%s+" % "+".join("=" * (w + 2) for w in widths) bar = "+%s+" % "+".join("-" * (w + 2) for w in widths) parts = [bar, header, bar_underline] for r in rows: parts.append(row_template % r) parts.append(bar) print("\n".join(parts)) if __name__ == "__main__": main() python-msgspec-0.22.0/benchmarks/bench_structs.py000066400000000000000000000130461525673062400221260ustar00rootroot00000000000000"""This file benchmarks dataclass-like libraries. It measures the following operations: - Time to import a new class definition - Time to create an instance of that class - Time to compare an instance of that class with another instance. """ from time import perf_counter order_template = """ def __{method}__(self, other): if type(self) is not type(other): return NotImplemented return ( (self.a, self.b, self.c, self.d, self.e) {op} (other.a, other.b, other.c, other.d, other.e) ) """ classes_template = """ import reprlib class C{n}: def __init__(self, a, b, c, d, e): self.a = a self.b = b self.c = c self.d = d self.e = e @reprlib.recursive_repr() def __repr__(self): return ( f"{{type(self).__name__}}(a={{self.a!r}}, b={{self.b!r}}, " f"c={{self.c!r}}, d={{self.d!r}}, e={{self.e!r}})" ) def __eq__(self, other): if type(self) is not type(other): return NotImplemented return ( self.a == other.a and self.b == other.b and self.c == other.c and self.d == other.d and self.e == other.e ) """ + "".join( [ order_template.format(method="lt", op="<"), order_template.format(method="le", op="<="), order_template.format(method="gt", op=">"), order_template.format(method="ge", op=">="), ] ) attrs_template = """ from attr import define @define(order=True) class C{n}: a: int b: int c: int d: int e: int """ dataclasses_template = """ from dataclasses import dataclass @dataclass(order=True) class C{n}: a: int b: int c: int d: int e: int """ pydantic_template = """ from pydantic import BaseModel class C{n}(BaseModel): a: int b: int c: int d: int e: int """ msgspec_template = """ from msgspec import Struct class C{n}(Struct, order=True): a: int b: int c: int d: int e: int """ BENCHMARKS = [ ("msgspec", "msgspec", msgspec_template), ("standard classes", None, classes_template), ("attrs", "attrs", attrs_template), ("dataclasses", None, dataclasses_template), ("pydantic", "pydantic", pydantic_template), ] BENCHMARK_NAMES = [bench_data[0] for bench_data in BENCHMARKS] def bench(name, template): N_classes = 100 source = "\n".join(template.format(n=i) for i in range(N_classes)) code_obj = compile(source, "__main__", "exec") # Benchmark defining new types N = 200 start = perf_counter() for _ in range(N): ns = {} exec(code_obj, ns) end = perf_counter() define_time = ((end - start) / (N * N_classes)) * 1e6 C = ns["C0"] # Benchmark creating new instances N = 1000 M = 1000 start = perf_counter() for _ in range(N): [C(a=i, b=i, c=i, d=i, e=i) for i in range(M)] end = perf_counter() init_time = ((end - start) / (N * M)) * 1e6 # Benchmark equality N = 1000 M = 1000 val = M - 1 needle = C(a=val, b=val, c=val, d=val, e=val) haystack = [C(a=i, b=i, c=i, d=i, e=i) for i in range(M)] start = perf_counter() for _ in range(N): haystack.index(needle) end = perf_counter() equality_time = ((end - start) / (N * M)) * 1e6 # Benchmark order try: needle < needle except TypeError: order_time = None else: start = perf_counter() for _ in range(N): for obj in haystack: if obj >= needle: break end = perf_counter() order_time = ((end - start) / (N * M)) * 1e6 return (name, define_time, init_time, equality_time, order_time) def format_table(results): columns = ( "", "import (μs)", "create (μs)", "equality (μs)", "order (μs)", ) def f(n): return "N/A" if n is None else f"{n:.2f}" rows = [] for name, *times in results: rows.append((f"**{name}**", *(f(t) for t in times))) widths = tuple(max(max(map(len, x)), len(c)) for x, c in zip(zip(*rows), columns)) row_template = ("|" + (" %%-%ds |" * len(columns))) % widths header = row_template % tuple(columns) bar_underline = "+%s+" % "+".join("=" * (w + 2) for w in widths) bar = "+%s+" % "+".join("-" * (w + 2) for w in widths) parts = [bar, header, bar_underline] for r in rows: parts.append(row_template % r) parts.append(bar) return "\n".join(parts) def main(): import argparse parser = argparse.ArgumentParser(description="Benchmark msgspec Struct operations") parser.add_argument( "-b", "--bench-name", dest="bench_names", nargs="*", choices=BENCHMARK_NAMES, default=BENCHMARK_NAMES, help="A list of benchmark names to run. Defaults to all.", ) parser.add_argument( "--versions", action="store_true", help="Output library version info, and exit immediately", ) args = parser.parse_args() if args.versions: import importlib.metadata import sys for _, lib, _ in BENCHMARKS: if lib is not None: version = importlib.metadata.version(lib) print(f"- {lib}: {version}") sys.exit(0) results = [] for name, _, source in BENCHMARKS: if name not in args.bench_names: continue results.append(bench(name, source)) print(format_table(results)) if __name__ == "__main__": main() python-msgspec-0.22.0/benchmarks/bench_validation/000077500000000000000000000000001525673062400221735ustar00rootroot00000000000000python-msgspec-0.22.0/benchmarks/bench_validation/__init__.py000066400000000000000000000000001525673062400242720ustar00rootroot00000000000000python-msgspec-0.22.0/benchmarks/bench_validation/__main__.py000066400000000000000000000100401525673062400242600ustar00rootroot00000000000000import argparse import json import shutil import subprocess import sys import tempfile from ..generate_data import make_filesystem_data LIBRARIES = ["msgspec", "mashumaro", "cattrs", "pydantic"] parser = argparse.ArgumentParser( description="Benchmark different python validation libraries" ) parser.add_argument( "--json", action="store_true", help="Whether to output the results as json", ) parser.add_argument( "--size", "-s", type=int, help="The number of objects in the generated data, defaults to 1000", default=1000, ) parser.add_argument( "--iterations", "-n", type=int, help="The number of iterations to perform for each library, defaults to auto-detection", ) parser.add_argument( "--rounds", "-r", type=int, help="The number of times to repeat the benchmark for each library if --iterations is selected, defaults to 5", default=5, ) parser.add_argument( "--lib", dest="libs", nargs="*", choices=LIBRARIES, default=LIBRARIES, help="A list of libraries to benchmark. Defaults to all.", ) parser.add_argument( "--versions", action="store_true", help="Output library version info, and exit immediately", ) args = parser.parse_args() if args.versions: import importlib.metadata for lib in args.libs: version = importlib.metadata.version(lib) print(f"- {lib}: {version}") sys.exit(0) data = json.dumps(make_filesystem_data(int(args.size))).encode("utf-8") iterations = str(args.iterations or 0) rounds = str(args.rounds or 0) header = "-" * shutil.get_terminal_size().columns results = [] with tempfile.NamedTemporaryFile() as f: f.write(data) f.flush() for lib in args.libs: try: res = subprocess.check_output( [ sys.executable, "-m", "benchmarks.bench_validation.runner", lib, f.name, iterations, rounds, ], stderr=subprocess.STDOUT, ) results.append(json.loads(res)) except subprocess.CalledProcessError as e: if not args.json: print(header, file=sys.stderr) print(f"Warning: {lib} failed to run, skipping...", file=sys.stderr) print(e.output.decode("utf-8", errors="replace"), file=sys.stderr) print(header, file=sys.stderr) if not results: print("Error: All libraries failed to run. No results to display.", file=sys.stderr) sys.exit(1) if args.json: for line in results: print(json.dumps(line)) else: # Compose the results table results.sort(key=lambda row: row["encode"] + row["decode"]) best_et = results[0]["encode"] best_dt = results[0]["decode"] best_tt = best_et + best_dt # Avoid division by zero if memory is 0 best_mem = results[0]["memory"] or 1.0 columns = ( "", "encode (μs)", "vs.", "decode (μs)", "vs.", "total (μs)", "vs.", "memory (MiB)", "vs.", ) rows = [ ( r["label"], f"{1_000_000 * r['encode']:.1f}", f"{r['encode'] / best_et:.1f}", f"{1_000_000 * r['decode']:.1f}", f"{r['decode'] / best_dt:.1f}", f"{1_000_000 * (r['encode'] + r['decode']):.1f}", f"{(r['encode'] + r['decode']) / best_tt:.1f}", f"{r['memory']:.1f}", f"{r['memory'] / best_mem:.1f}", ) for r in results ] widths = tuple(max(max(map(len, x)), len(c)) for x, c in zip(zip(*rows), columns)) row_template = ("|" + (" %%-%ds |" * len(columns))) % widths header = row_template % tuple(columns) bar_underline = "+%s+" % "+".join("=" * (w + 2) for w in widths) bar = "+%s+" % "+".join("-" * (w + 2) for w in widths) parts = [bar, header, bar_underline] for r in rows: parts.append(row_template % r) parts.append(bar) print("\n".join(parts)) python-msgspec-0.22.0/benchmarks/bench_validation/bench_cattrs.py000066400000000000000000000017361525673062400252130ustar00rootroot00000000000000from __future__ import annotations import datetime import enum from typing import Literal import attrs import cattrs.preconf.orjson class Permissions(enum.Enum): READ = "READ" WRITE = "WRITE" READ_WRITE = "READ_WRITE" @attrs.define(kw_only=True) class File: name: str created_by: str created_at: datetime.datetime updated_by: str | None = None updated_at: datetime.datetime | None = None nbytes: int permissions: Permissions type: Literal["file"] = "file" @attrs.define(kw_only=True) class Directory: name: str created_by: str created_at: datetime.datetime updated_by: str | None = None updated_at: datetime.datetime | None = None contents: list[File | Directory] type: Literal["directory"] = "directory" converter = cattrs.preconf.orjson.make_converter(omit_if_default=True) def encode(obj): return converter.dumps(obj) def decode(msg): return converter.loads(msg, Directory) label = "cattrs" python-msgspec-0.22.0/benchmarks/bench_validation/bench_mashumaro.py000066400000000000000000000022041525673062400256760ustar00rootroot00000000000000from __future__ import annotations import dataclasses import datetime import enum from typing import Literal from mashumaro.mixins.orjson import DataClassORJSONMixin class Permissions(enum.Enum): READ = "READ" WRITE = "WRITE" READ_WRITE = "READ_WRITE" @dataclasses.dataclass(kw_only=True) class File(DataClassORJSONMixin): name: str created_by: str created_at: datetime.datetime updated_by: str | None = None updated_at: datetime.datetime | None = None nbytes: int permissions: Permissions type: Literal["file"] = "file" class Config: omit_default = True lazy_compilation = True @dataclasses.dataclass(kw_only=True) class Directory(DataClassORJSONMixin): name: str created_by: str created_at: datetime.datetime updated_by: str | None = None updated_at: datetime.datetime | None = None contents: list[File | Directory] type: Literal["directory"] = "directory" class Config: omit_default = True lazy_compilation = True label = "mashumaro" def encode(x): return x.to_json() def decode(msg): return Directory.from_json(msg) python-msgspec-0.22.0/benchmarks/bench_validation/bench_msgspec.py000066400000000000000000000015241525673062400253470ustar00rootroot00000000000000from __future__ import annotations import datetime import enum import msgspec class Permissions(enum.Enum): READ = "READ" WRITE = "WRITE" READ_WRITE = "READ_WRITE" class File(msgspec.Struct, kw_only=True, omit_defaults=True, tag="file"): name: str created_by: str created_at: datetime.datetime updated_by: str | None = None updated_at: datetime.datetime | None = None nbytes: int permissions: Permissions class Directory(msgspec.Struct, kw_only=True, omit_defaults=True, tag="directory"): name: str created_by: str created_at: datetime.datetime updated_by: str | None = None updated_at: datetime.datetime | None = None contents: list[File | Directory] enc = msgspec.json.Encoder() dec = msgspec.json.Decoder(Directory) label = "msgspec" encode = enc.encode decode = dec.decode python-msgspec-0.22.0/benchmarks/bench_validation/bench_pydantic.py000066400000000000000000000022451525673062400255220ustar00rootroot00000000000000from __future__ import annotations import datetime import enum from typing import Annotated, Literal import pydantic class Permissions(enum.Enum): READ = "READ" WRITE = "WRITE" READ_WRITE = "READ_WRITE" class File(pydantic.BaseModel): type: Literal["file"] = "file" name: str created_by: str created_at: datetime.datetime updated_by: str | None = None updated_at: datetime.datetime | None = None nbytes: int permissions: Permissions class Directory(pydantic.BaseModel): type: Literal["directory"] = "directory" name: str created_by: str created_at: datetime.datetime updated_by: str | None = None updated_at: datetime.datetime | None = None contents: list[Annotated[File | Directory, pydantic.Field(discriminator="type")]] if pydantic.__version__.startswith("2."): label = "pydantic v2" def encode(obj): return obj.model_dump_json(exclude_defaults=True) def decode(msg): return Directory.model_validate_json(msg) else: label = "pydantic v1" def encode(obj): return obj.json(exclude_defaults=True) def decode(msg): return Directory.parse_raw(msg) python-msgspec-0.22.0/benchmarks/bench_validation/runner.py000066400000000000000000000021601525673062400240550ustar00rootroot00000000000000import gc import importlib import json import resource import sys import timeit library, path, runs, repeats = sys.argv[1:5] num_runs = int(runs) num_repeats = int(repeats) if num_runs: def measure(timer): return min(timer.repeat(repeat=num_repeats, number=num_runs)) / num_runs else: def measure(timer): n, t = timer.autorange() return t / n with open(path, "rb") as f: json_data = f.read() initial_rss = resource.getrusage(resource.RUSAGE_SELF).ru_maxrss mod = importlib.import_module(f"benchmarks.bench_validation.bench_{library}") msg = mod.decode(json_data) gc.collect() encode_time = measure( timeit.Timer("func(data)", setup="", globals={"func": mod.encode, "data": msg}) ) del msg gc.collect() decode_time = measure( timeit.Timer( "func(data)", setup="", globals={"func": mod.decode, "data": json_data} ) ) max_rss = resource.getrusage(resource.RUSAGE_SELF).ru_maxrss report = json.dumps( { "label": mod.label, "encode": encode_time, "decode": decode_time, "memory": (max_rss - initial_rss) / 1024, } ) print(report) python-msgspec-0.22.0/benchmarks/generate_data.py000066400000000000000000000067541525673062400220530ustar00rootroot00000000000000import datetime import random import string class Generator: UTC = datetime.timezone.utc DATE_2018 = datetime.datetime(2018, 1, 1, tzinfo=UTC) DATE_2023 = datetime.datetime(2023, 1, 1, tzinfo=UTC) PERMISSIONS = ["READ", "WRITE", "READ_WRITE"] NAMES = [ "alice", "ben", "carol", "daniel", "esther", "franklin", "genevieve", "harold", "ilana", "jerome", "katelyn", "leonard", "monique", "nathan", "ora", "patrick", "quinn", "ronald", "stephanie", "thomas", "uma", "vince", "wendy", "xavier", "yitzchak", "zahra", ] def __init__(self, capacity, seed=42): self.capacity = capacity self.random = random.Random(seed) def randdt(self, min, max): ts = self.random.randint(int(min.timestamp()), int(max.timestamp())) return datetime.datetime.fromtimestamp(ts).replace(tzinfo=self.UTC) def randstr(self, min=None, max=None): if max is not None: min = self.random.randint(min, max) return "".join(self.random.choices(string.ascii_letters, k=min)) def _node_base(self, is_dir): name = self.randstr(4, 30) created_by = self.random.choice(self.NAMES) created_at = self.randdt(self.DATE_2018, self.DATE_2023) d = { "type": "directory" if is_dir else "file", "name": name, "created_by": created_by, "created_at": created_at.isoformat(), } if self.random.random() > 0.75: updated_by = self.random.choice(self.NAMES) updated_at = self.randdt(created_at, self.DATE_2023) d.update(updated_by=updated_by, updated_at=updated_at.isoformat()) if is_dir: d["contents"] = [] else: d["nbytes"] = self.random.randint(0, 1_000_000) d["permissions"] = self.random.choice(self.PERMISSIONS) return d def _draw_children(self): n = min(self.random.randint(0, 30), self.capacity) self.capacity -= n return n def _expand_dir_dfs(self, root): # Stack frames: (parent, total_children, made_so_far) stack = [(root, self._draw_children(), 0)] while stack: parent, total, made = stack.pop() if made == total: continue # Create the next child in-order is_dir = self.random.random() > 0.8 child = self._node_base(is_dir) parent["contents"].append(child) # Resume this parent after handling the child stack.append((parent, total, made + 1)) # Expand child immediately if it's a directory if is_dir: stack.append((child, self._draw_children(), 0)) def make(self, is_dir): if not is_dir: return self._node_base(False) root = self._node_base(True) self._expand_dir_dfs(root) return root def make_node(self): return self.make(self.random.random() > 0.8) def generate(self): self.capacity -= 1 if self.capacity == 0: out = self.make(False) else: out = self.make(True) while self.capacity: self.capacity -= 1 out["contents"].append(self.make_node()) return out def make_filesystem_data(n): return Generator(n).generate() python-msgspec-0.22.0/conftest.py000066400000000000000000000054121525673062400167660ustar00rootroot00000000000000import os import re import sys from pathlib import Path def pytest_addoption(parser): # Only register options for configurable test suites when those suites are selected. # This keeps options for heavy tests like performance profiling out of normal test # runs while still allowing their suites to be selected through `testpaths`. configurable_test_suites = { "tests/prof/perf": add_performance_profiling_options, } cwd = Path.cwd() project_root = Path(__file__).parent for test_suite_relpath, add_options_func in list(configurable_test_suites.items()): test_suite_path = project_root.joinpath(test_suite_relpath) if test_suite_path == cwd or test_suite_path in cwd.parents: add_options_func(parser) configurable_test_suites.pop(test_suite_relpath) break # Always accept forward slashes and the system separator, escaping the latter in case of backslashes (Windows). allowed_separators = {"/", re.escape(os.sep)} separator_pattern = f"[{''.join(sorted(allowed_separators))}]" configurable_test_suites_patterns = { re.compile( rf"\b{test_suite_relpath.replace('/', separator_pattern)}\b" ): add_options_func for test_suite_relpath, add_options_func in configurable_test_suites.items() } for arg in sys.argv: if not configurable_test_suites_patterns: break for pattern, add_options_func in list( configurable_test_suites_patterns.items() ): if arg in {"-h", "--help"} or pattern.search(arg): add_options_func(parser) configurable_test_suites_patterns.pop(pattern) break def add_performance_profiling_options(parser): group = parser.getgroup("performance profiling") group.addoption( "--calibrate", action="store_true", help=( "Override automatic calibration of benchmarks and enable the following options: " "--rounds, --warmup-rounds, --iterations" ), ) group.addoption( "--rounds", type=int, default=1000, metavar="ROUNDS", help="Number of rounds for benchmarks (default: 1000)", ) group.addoption( "--warmup-rounds", type=int, default=50, metavar="WARMUP_ROUNDS", help="Number of warmup rounds for benchmarks (default: 50)", ) group.addoption( "--iterations", type=int, default=10, metavar="ITERATIONS", help="Number of iterations in each round of benchmarks (default: 10)", ) group.addoption( "--size", type=int, default=1000, metavar="SIZE", help="Size of the benchmark data (default: 1000)", ) python-msgspec-0.22.0/docs/000077500000000000000000000000001525673062400155155ustar00rootroot00000000000000python-msgspec-0.22.0/docs/_static/000077500000000000000000000000001525673062400171435ustar00rootroot00000000000000python-msgspec-0.22.0/docs/_static/anywidget.png000066400000000000000000000351361525673062400216540ustar00rootroot00000000000000‰PNG  IHDRôôD´HÝ…iCCPICC profile(‘}‘=HÃP…OSµ";ˆ8d¨NŠqÔ*¡B¨Zu0yé4iHZ\ׂƒ?‹Ug]\AðÄÕÅIÑEJ¼/)´ˆñÂã}œwÏá½û¡QfšÕ4½j¦q1“]¯è�ƒˆ"&3˘“¤$<ëëžz©î"<Ë»ïÏêWs|"ñ,3Ì*ññôfÕà¼ObEY%>'ž0é‚Ä�\W\~ã\pXà™!3�š'‹…V:˜M�xŠ8¬j:å —UÎ[œµr�µîÉ_Ìé+Ë\§5б "ÔPBUDh×I±�¢ó¸‡ÄñKäRÈU#Ç*Ð ;~ð?ø=[+›t“‚q ûŶ?Æ€À.ЬÛö÷±m7Oÿ3p¥·ý•0óIz½­…�€�mà⺭){Àå0üdȦìH~ZB>¼ŸÑ7e�¡[ oÍ�[ë§@šf•¼�ñe¯{¼»·snÿö´æ÷¢rº‚Ð?ÓbKGDÿÿÿ ½§“ pHYs × ×B(›xtIMEç7,N�|ø IDATxÚíÝy@UåÚ÷ñ½Ṵ̀A@%P·Šâ€à„¤ 8¡áÐ)=Ni¢™C¥fNiõj©¥™å�GÓRóxHM͉ÃqÄYAQAQAæ6›÷ŸÓÓc†¨ kø~þ*E¸×µÖú±ö½ÖºneUU• -z”wá Ü„;€pÂ@¸wá Ü€pîÂ@¸wá„;€pîÂ@¸á Ü„;€pîÂwá Ü„;€pÂ@¸wá Ü„;îÂ@¸wá„;€pîÂ@¸w Ü„;€pîÂwá Ü„;€pî@¸DIŸ@,*uº’òòâ²²¢²²Â²²Â²²‚ÒÒÒŠŠ2­¶°¼¼¬²²¸¢"¯¬LWU¥P(òËËK++ÿøÏªTF*•©��R©´044Ö×774472252250014410076V›˜è«T„;P›Ê**rŠŠrŠ‹sŠŠ2 Ò “òócòòöÕÛzu´´lbfÖÄÜÜÆÔÔN­n¬V[™™Y˜˜(•Jö„OYUUEЀŠËÊ2òó3òóSrsïåä\ÍÊÚž—'ØÑº«T}¬­5VVÎö––––&††ìGî�»ÂÒÒ´œœ´¼¼¤œœË~™‘!ö- 65õ±µmkkëjccoiika¡ÒãnwH�®ª*=7÷^ffLzú±””=……ÒÞÞöúú¯5iÒÉÁ¡¥�]SsccŽî�ˆJ�.%++>#ãZZZxJÊéòrÙ–b‚•Õ«NN­ìí]7¶µ°`Ê„;Ä'·¨èNFƵv%$--¥ Oð52éâÒÕÅ¥¥½½¥©)áA_¤ßËȸ’œ|øþýïsr(H ½kkëçâÒÎÑÑÅÖÖ€'/A¸C *´Úøôôó‰‰ÛîÞ�à"ý%´××çâÒÓÍÍÝÑÑÔȈ‚€pG(×jo>xpêÞ½Í÷î]®¨  µÈYOoš‹Ë«®®m��Õ܆áŽz Óé22N%$¬�‹‹’ñÝÑú¡V*?hÚÔÏÍ­C³f¤<wÔ‰Ôœœ¨„„nÝÚ[�/ˆâ÷kù÷]]ûh4­�œôyv„;^^¹V�œ¼çúõeiiT£Áÿ½eKŸ-\mm©w¼à¥úââÖܼÉô‹½kk;ÌÝÝËÕ•ž ÜQ#Z�.:1ñçë×—s©.xÞïµmëߺµ­…ÕᎧ+.+»xïÞÆkܱׄ O5ßÉiX»vÍšéñâ+wü.3?ÿøÍ›ÿïÆ�h­–jˆ×x+«±íÛwqs320  ÜeíAvvxtô¼øø©41y¯S§ž Óñ Üå(%+koLÌ;qq”B’| ßoß¾¯»;Ý( wÂ]F±¾ëÊ•÷(…äµ×ןïáäáÁ;P„;¤,ùÑ£­/.HJ¢r‹ø�;v l׎‰ÂR“UPð˵koÅÆR Ùò14üÈÓ³�»»¡>k&î¿ü’’ÃׯϺv-E§£jnþA—.]›7ç¡IÂbU\VvøÆ�ùW®ÄVVR üÑL;»É]»jš4¡„;ÄD§ÓEݽ»øìYVAB5¾pu×­›�ZM)wˆ@bfæ7gÏ~‘žN)ðL•jy§NýÛ·g"žp‡p––þråÊè˜J�çò†…ÅìîÝ;¸¸P ¢ÕéNÞº5ïüy:8â…­nÑbt×®Vff”‚p‡ ¤de}qâÄšÌLJ�—äi`°¢[·^­[ó, Ꮍ`¯¬qq™öê«&&”‚pÇ ÊÈË›ôèÆìlJA`júeŸ>-i*I¸ãÄ$'O:~œv&µR¹«k× ž¢!ÜQSºªªÃ11ý£¢(n­Fó–��‘�¥ Üñ Åeeßœ81ûÞ=JQ˜fk»8 ÀÚÜœRîøK)YY=º“” *ƒÌÌV÷ëçjkK)wäÑ´)¥ ÜEì^Fư.ólÌÓ¼aa1ÈÍ­ƒ³³›­­dV{ÐUU¥fgßJK;›’²!%…Éú§rÓÓ;пkGGJA¸‹RÒ£G#ý•uòž¸j›Ö´iO—6ŽŽö––ÒÞØ²ŠŠøôôs‰‰[ïÞ=YVÆÞÿ£öúúáºÙÙQ Â]dªªªæ8ðYj*¥P(j¥ò}'§¾-[z4mª66–Ûækuº{—’’~Š�ß_TÄñðX7CßlÚ¸1¥ ÜE¦¸¬lÉ‘#ËÓÒä\„Ù[µêЬ™…‰ ‡D¥NwçáÓwî|Ïó6 …ÂߨxûàÁMè?C¸‹ñƒùŠˆˆù‰‰2lÓ&ÈÝ�¯/ö ïJbâO11_gfʳ œœqA@¸‹OUUÕî F^½*½Mó76žÖ®�›6̪¿¼ø´´Ÿ££e8�§P(¾Öh¦ôêÅú«„»(ýzõê óç%³9¡ææ3¼¼ºº¹ï%RQKÎÊÚóa|¼ÜLßãéùš—á.JÿŽ�õ?uJ±>ÓË«Kóæ|Ž®;yyÿ¼zuêíÛ²Úê½zù¶jÅÞ'ÜEéÜÝ»ƒ#"DÚDìq¬wmÞœåíëGjNÎŽK—ÞOH�ÉöÚ)•ÿîßß�æï„»HE'% =rD\­Ä¼ >ñòêݦ�!“0õ.13só… KRRä°±Ý ÷j'õ˜ wÉŠOOS$K2©•Ê/Û´æéiijÊŽk@±|qúô–Ü\Éoéx+«µ!!&††ìtÂ]¬—ccŒvבÏ\\ÆuíÊŽQ¡Õ‹��é’ä»Ñ­lÞ|¦¿¿’‡gw‘JËÍ}ûÀaö 13û¸gO–Πܢ¢-QQ3¥þfÜþ.]vìÈî&ÜÅ*« `æÁƒÛòò„3$µR¹®]»ÐÎ�ù\,d±ÌÿÏ %¼�W¹¼ ÜE,¯¸xÞo¿­{ôHƒ ³±ùàÕW]mmÙ/ÂWZQ±ÿêÕW®Hu½ ö ʬ á.bE¥¥‹^ùðaŽÁN©ÜÜ¥K�‡‡JO�=""ñééýûß» $¹u“¬­×„„Hf9Â]¦Wa+Ž_Ð@mÇ[Y-ìÝÛ… vq*)/ÿ!*jò­[’ܺ�îîoõìÉ^&ÜE¬¢²ò›ÈÈú¿Q¶ÉÝýÍ®]�¹8¹ØfED.)‘Þ¦] ðdYmÂ]Ô*uºM§NÕÛ%X°©é*?¿Ö¼(¹EE«"#—>x ±íò14ÜJÛwÂ]ܪªªv�?ÿ·k×êúÍstüÀϯ‘™5—�Nwøúõ‘çÎI¬ïØ{ööˤïá.zû¯^\—-$·yx¼Þ¥ §ŠTÝNK›yüø¡âb)mT¸—×OOv.á.zÇnÜ8}ºÖ¿­¯‘Ñ7þþM›RaiË-*Z!¥U|ÕJå…�[5iÂÎ%ÜEïL||Pdd-~¾ždmýi``cæ.å¡¢²ò‡³gß’Ð*`CÍÍ6Œ×ëw)¨Å’Kš5{ÏÏÏÔȈªÊʉ[·†Ÿ<™!•s|sÛ¶ã||Ø­„»Üzð`äáÃÑZíË|“mëÚ•”ä)>=}ò‘#¥¥ÒØœ›ðˆW q Zk'§}ƒõ~Ñ+nµRyÔÇgT÷î$»lµtpØ5dÈX©¼Ç?ï?ÿ)v;UÂ5åbkûãàÁÁÏßQÝ]¥:Ü·m[j(s�-,Ö ü�ƒƒ¶%¼°p÷¥KìÓš`ZF² f<¸½Æ-$»nnnoOéðX…VûÝÉ“ïÆÇK`[˜œáÊ]:lÔê5N°²ªÉ›šþsð`’d ¯?µW¯´k'�mùøäÉR©/ZB¸Ëˆ•™ÙêAƒžùáz¸Z½eÐ 'kk*†'Ïv=½±=z„{y‰}Cvæç¬û¹ wÔ3cã�ƒ‚üõÒñVVëf‰aTcˆ§çþ.]ľÓ¯^}(ƒEe w114œ¸üi}òF[Z®ìßߊŽ1x–�;y+Ý�nCT»²ÜP¥J�nóéÓ“nÞüýOBÍÍ×Dó<ÔÜ©¸8ßÈHQo•ÀÀެÆÇ•»”¨ôôÞêÙóÇöíÿïPsóïHv<§žÍ‘=D½ Ÿœ>Í�U®Ü¥iß•+ë®_ß:h�=«Mâ…‰‰ <{V¼ãÿ——×PFî’TPZª66¦xauÝeºN9ëé]>œ‡þŒiÑ#Ùñ’uìøS‡"|ŠN÷#ï¬îžj¤·÷×�H?ëÎ�{™™ìDÂÀŸ‚@Oo²¯ï'¢}òd}T3Ì„;€§ÐW©fùùMiÜXŒƒ_ž–+¹ÅÁ wµÃÄÐpi¿~/ЂTVGEUÖÆÊ6„; ²67ÿ¦_?7.°1;ûâ½{ìAÂÀÓ¹ÚÙýäç'Æ‘¯<¾âå–-#ÜHY׿ÍîÔItÃÞ]Pu÷.»�pð—^ëÜy¡³³è†ýõåËÚÊJváàéTzzïùù…ˆ­Éèî‚‚Ë÷ï³ûwÉÂÄäË~ýœÅvsuÝ¥K<6C¸¨Ž«­í¦®]Å5æ­¹¹1ÉÉì;Â@uÚµ[Ü´©¸Æ¼ùòe^X%ÜT›JåôW_ímd$¢1�™y35•p€ê423[ùê«âó.Ù¯ M¸x6OW×ïZ·Ñ€—¤¤¤æäî𠣺t ª¶3Çþ°È0áOgflü‰¯¯ˆ¼üæÍ¢ÒRÂ]¦´Zm||<ç-P]\¾jÞ\,£�­¬<—�@¸ËQUUÕ–-[üýýoÊûãPsãzôÑ“3££ur}¡IÖá¾oß¾‰'¦¤¤ 6ìÍB�°01YÚ½»XF»3?_¶ÏDÊ7ÜO�:5dÈ�ÿùøûÖ[o=|ø�Sx¦-Z̰³Í5Ü�„»ŒÄÆÆ†††þñO"""¦N�š#ïg§€¥†žÞt±Œv^bbva!á. ÉÉÉûÛß222žøó={öÌ›7¯¸¸˜³¨Þ+¶¶›ÜÝÅ2Zyö‰”]¸gee½ýöÛÑÑÑOýÛï¾ûîã�?.++ãìª7¢sgoQ u§,Ÿ˜�W¸Ξ=ûСCÕ|Í矾fÍšJúýÕR›˜|ܹ³(†ú}NNÒ£G„»d•——úé§›7o~æWΞ={Ó¦Mt•ªçß¦Í ‘¬æqZ~ËïÉ%Üu:Ý7ß|³lÙ²~ýäÉ“÷ìÙÃÙ TÃÈÀ`Ž··(†úí­[r[;[.á¾cÇŽY³f=×?>|xDD'0P�n-ZL²¶þ8O–•Éí�wY„û¡C‡F�õÿ°OŸ>QQQœÀÀ_QééMöòÅPÿ#³™é‡ûÅ‹û÷ïÿÂÿ<$$„æ@5:4k6Q ïkJ+*w‰ˆ��9räË|‡ŒŒ šÕ…ˆžÞ$1<6WYŸžN¸KAZZÚ¸qã^º-Í €êyº¸L°²þ8Ï%&››;mÚ´Ó§O×Êw‹ˆˆ £9ðWïo‹áâ}Ë�;ZÙ¼Â"Íp/))ùè£�j÷YÆðððyóæq&O¹xå•ájµÀyº¼ü®l>‚K0ܵZíŠ+Ö­[Wëßù»ï¾[²d Í €?SééMjß^øã¼�”D¸‹RUUÕ¦M›.\XGßÿóÏ?_½zµVfoC5Ñ£E OÁw›ùéΙ,ß!µp «Ó1gΚfjdôAÛ¶ä¡ââTyÜ<“T¸GDD<Ñ¥½Ž„……ýóŸÿädžÐ·ukµR)ðAÞLK#ÜÅ$&&æ÷••êÁˆ#hN<¡±…Å<�ò¬<¦Ý%î÷ïßýõ× êó‡Òœø³mÚ|„SSåðªªÂ=33sÒ¤I±±±õÿ£CBBäç‚åîä4ÔÜ\È#LÑéîÿi!6Â]p Þ{ï½£G�6ÈOÏÈÈ>|8Í €ß©ôôÆ ~¾ë2˜vw¸—––Ο?Û¶m 8šOðiÑBà·U�Ê`UU‡»V«]µjÕš5k|$4'þÈÚÜü}''!�pCvv®Ôß6k¸WUUmÙ²å£�>ÈxÂÃÃçÎ�Ksà±~�ÀG˜(õUUÅîû÷ïŸ8q¢°®6løøã�iN(ŠöM›ºé :^â33 wÁ9uêTHHˆöÅ_МP(¦FFÓ\]…< R_uO|á[?¯¡¾š�ùµh!äáý”‘Q.éë0‘…{rròßþö· a?£Js@¡P´vttW©;¼�îAv6á.YYYo¿ývtt´ð‡:bĈcÇŽqzCÎŒ &¼òŠ�GxOÒ÷TEî………³gÏ>tè�XpöìYÎpÈ™�°ûÌ\—ô’ªâ÷òòòO?ýtóæÍâ*î�!ChN9swròÛL< Ü’N§[·nݲeËDWÜÇÍ ^~…n@¤Ô&&Óš4ìð—”äî fÇŽ3gÎi}ccc'L˜@sÈV/aÏÌ<ÌË#ÜÆ¡C‡F�%êGFF†……eKú¾<ðWZ98yx¤Û5DÐá~ñâÅþýûK Êááá~ø!Í CÎ66>††‚Þ=é^u 7ÜãããGŽ)™B?nNPZZÊÙYQéé…6k&Øá]“n�†{ZZÚ¸qã$v+’æ�§ÎŽŽ‚Û¿²²´••„{=ÉÍÍ�6mÚéÓ§¥Wî¹sçnܸQ§ÓqÂC>ZØÛ vl):Ý£ú]žS¾á^RR²`Á‚={öHõ@Ÿ2eŠ„·ø3{KËöúú‚^Zn.á^ç´ZíŠ+Ö®]+íc�æ�•žÞ0ÏÌ<ÌÏ'ÜëVUUÕ÷ß¿páB9î4'€¬tðÌL*á^×ÂÃÃ'Ož,ŸÃ�æ�7[[ÁŽížDßcJ¸GDD¹K{] 9äÃÙÚZ°c» ÑGÝî111C† ‘áÿ¸9Aº¤[Ó …ÂÒÔ´·‘‘0Çv¸¤¤´¢‚p¯}÷ïßýõ× $ú4Ò3EFFNž<™æ�¼Þvv‚[ŽßoàpÏÌÌœ4i’̧ž÷îÝ;wî\š@ÚZÛØvlÙ……„{m*((xï½÷Ž=Êq¿qãÆE‹ÑœÖLÀÓîR|`¦Á½¬¬léÒ¥Û¶mã låÊ•4'€„9XZ vl�˜–©-Z­våÊ•_|ñGüÑœfmf&رe•”îµ ªªjË–-}ô‡ûŸM™2å§Ÿ~¢�µ‰‰F¥æØÒ¹r¯û÷ïŸ8q"Çú_=zô‘#G¨¤–5Je/¡ÎÌ$Jñi½ú÷Ó§O‡„„p W/00ðÌ™3Ô£j¸Ÿ'Ü_Rllìk¯½Æ!^AAA×®]£�g¡†{le¥ôÞcª¿pONN=ztFF‡xMŒ1‚æ�’ƾ§Z(¹‘ë)ܳ²²Þ~ûíË—/s|×\\\Ü›o¾ùàÁJiPî’ ÷ÂÂÂÙ³g:tˆƒûyEEEM�:•æ�H¸ µ½ŒB¡(*+#ÜŸOyyù§Ÿ~ºyófŽì³wïÞY³fɶ÷¤ÄLÀá^R^N¸?�N·nݺeË–qX¿Œ­[·~üñÇ4'€èÃ]ÀÓ2%ÜP}.;vì˜9s&ÇôË[¹råçŸNsˆš©¡!á.…pÿí·ßF�Å][-Z´aÚ@¼ ¼Lv1Ó25tñâÅàà`ŽæÚ5uêTš@Äá®R©•JÂ]Äá~çÎ�‘#Gr(×…Ñ£G>|˜:@¤Ús`ELË}šƒ¸®óýäÉ“:t x1åZ­®ªªþ®¥P§Ý¦çæ6àì--•µ:g¥¬ª½\RR2{öìµk×ræÔ�FsðàÁæÍ›S ¼€Û©©}Láþ¼0îÞ½Ÿ‡Gí~ÏZ›–Ñjµ+V¬ ÙëM\\ܨQ£hN€ÓÊÑñ_þþÔAþÑ®]­'{­…{UUÕ÷ß¿páBöS}¢9^†·›ÛÑ=¨CÃúÜÕut·nuñ�k'ÜÃÃÃ'OžÌ~ª{÷î�1cÍ ðbú¶kîåEÊ{ööïöî­Ò«“§U‹/~Éo1`ÀöSC‰ŽŽ.++ëÕ«—¾€ß�`µrphZZº/3“RÔ³Q––_ôïoZgýv^6ÜcbbúõëW.¹§ˆÄåìÙ³†††=zôP u�J–R©ìàìÜ(?ÿ0ó{õ(ÀØxàAVææu÷#^*܇Ê==!ˆŒŒ´··÷òòR õ @–žRÙ¹iSÝÇ'™ß«î*ÕÎ��¬­ëö×öË< y÷îݲm‚¼xñâÝ»w sÿEEEµjÕªž¨¹¹9“3x1%åå³ýuí£G”¢N©•ÊÓAAM›Öõz© hð‡¬�œœ„» ÕêF�q(C,L —fìÛ÷3×ïué·Þ½ë!Ùõ¼@v­355åXjK#3³µš˜PŠ:²¯K—-[ÖÏÏ"Üü/[ ‹õAAžBmï%j›ÜÝÖcËq‡»±€v©jˆÆÀËs±µý)(ÈYO�RÔ¢Ï\\ÆôèQŸÏ;îžÔªI“pšÔž™vv3ýýõë÷÷%á^W*++9¦!^^nnG}|¨ÃË{ÝÂbq` q½Ït‰;Ü�¼˜zqq1‡5D­oÛ¶4'xI½�Œ¾ ¶hˆ{Ôâwóº|¿ë%rdCìB:uÚäîN^ŒF¥ú>8ØÞÒ²A~º¸ÃÝ‚pêŽR©ۣǪ-(ÅóR+•?÷íëfg×Pw¸›™™ vlùùùß�•žÞÔW_�çèH)žË~_ß.. 8¦eêJ^^Ç7¤ÁP_~¿~ï4nL)jhWÇŽ½Z·nØ1på^WXCRò¸9ÁµšR<ÓZ�f˜·wƒƒ7TëJ\\G9¤„æ5±ÐÙy’¯¯žš³*Eý"eAA�`頻Õêììlz4Bb33_ûõ×Ë”âÏ&ÛØ¬8ÐT�h‹þÊ]-Ôω¹¹¹î�šü•3³ÏMóò�¸÷�J¥ ìð˜v‡$Ñœàϼ ¾ ¶Ò#¢ÿõÛ¦MÁŽíë@¢¼Ü܎ќ࿜õô¶ÖõÊJ² ÷¦õÒöþŤ§§sÜCªúМà¿þéç×Jxïˆ>Ü;¶””Ž{HÍ  Å‘=º6ôštÒ wÁŽíÔ©Sœÿ�°ÇÍ ¾d´Õ�-íÚ´k'̱‰>Ü­¬¬;¶Ý»wÓaÒ¦ÒÓ›Ò«—<›|áê:ª[7Á�p¯[©©©œÿ�¶ÇÍ ¦ÙÚÊj«?pp˜Ö»·JÀ�„Š>Ü­­­Õ~%:))‰“’gbh¸¤_?ù4Ë0ZÿNIDAT'mi¹ _?#a¯4+úp700 ìðnݺř9�Os‚¦¦_  üŸRxͬcÇŽ‚Û‰'8í!¶냂<…}=û’< ¾ ¶p?ZI…»›››`Ƕ{÷î‚‚N{È„‹­íŽ  7‰6'°S*·÷ëç,à'ô¤îŽÂ¾Sÿþ}Îyȇ¦I“]}úHrÓ~ñókãä$–ÑJ!Üííí…<¼ëׯsÂCV¼\]�÷ì)±�úµK—î¢ZnP án#ìOI‡æl‡Üø»»ÿ"¡æß»»÷ïÐA\c–B¸›˜˜Œ3F°ÃÛºukNNg;äfp§NßK¢9Áÿ{å•1=z(°þ†ìÂ]¡PôèÑCÈË��çT‡Ü(•Ê1âoN0ÓÎn†ŸŸJ„·ˆ%î-[¶òð®]»Æ©zÜœ`¾xnB>á ‹Å��Æâ|¸S"áîââ"äáíÙ³GÔË/ÌP_^@€›øl!Úײ”Ò�’’!/–­P(’’’„Üz¨SyÅÅ“÷íÛ™Ÿ/–kTªß rµ³oÍ%rånbb2aÂ!�ðÒ¥Kœá�-KSÓ5ýû û ìwj¥òç¾}E�ìÒ w…BÑMÀ½7ÌÌ@öl-,¾Is‚_}};{¦W^á.äÅT ÅöíÛiÿ ™kÖ¸±ð›üܩӫ­[K ÚÒ ÷æ‚âêòåËœÞ�9�7'X«Ñ “Ê»WÒ w{{û€€!�p÷îݜۀ`›,jÚt’¯¯è^V’~¸+•ÊAƒ y„Û¶mcfP²9Ád›Ùþþ*•dŠ,©ÎœßüáâÅ‹œØ€B`Í †š›djd$¥ K*Ü…?í¾iÓ&­Vˉ >}Û¶•jU¥¶ÔakÁ¿}PPPpöìYÎgàw Òœà '»ýQ£Fï¼óŽÀ¹aÆÊÊJNiàwõÜœ`MË–o »a áþ•I¡PìÝ»÷öíÛœÏÀÕ[s‚ùNN“}}õ¤ò²’ŒÂ½]»vÂ$o«¦iÒäç:nN0ÑÚznŸ>úú’/¦Rz­ +++ýüüNž<)ðq&&&6kÖŒóxBDllŸS§êâ;23Ûbmn.‡2JðÊ]¥R�=Zøãüå—_8��?ówwßëí]ëßÖÓÀ`]P�L’]šWî …âÆ�¢˜œIOO···çdžPUUµåÌ™ñ7nÔÖ7´S*# hãè(ŸêIr«4M71Ü ç…&àéW�Jå˜îÝk±9Á^??Y%»dÃÝÀÀ`üøñÂç‚ rrr8“�§dSí5'8Ø­[·-dW@©nX�=„?È”””cÇŽqOU+Í þѶm�‡‡;JuÃ4�wÜ“©uË–-+((à4žÊÄÐðÓ  1�½àùõÊ+£»wWJý‘vy…»��Áĉ…?ÎË—/ïß¿Ÿsø+j“AA/М`–½ýt??•žž<ë&ͧe»yó¦»`V¨†��Ýõë×m®1 |²³‡íÛU^^ïÃÂâÛ� ÙVLÊ¿Ó4MHHˆðÇ™‘‘±cÇÎ^ NÖÖ?Ö°9�¿±ñ—ÁÁrNv‰_¹+Š_~ùeèС¢jBB‚««+ç0P�k‰‰¾GŽT›Z•ê·Áƒ]eÿQXâ³QïíþGëׯ—ö/ZàåupqÙëãSͨ•ÊÝ$»ôÃÝÞÞ~Μ9¢êòåËcbb8"�êùUÛœà`¯^íiÙ$‡pW(ƒËPW¯^ÍòÙÀ³OêN�¶µoÿç?ßíéÙS£¡>r ÷N�:‰â™…B±yóæˆˆJà™ÞèÒ剿ß´jÚ¹3•‘Q¸›˜˜|ðÁbmXXXFFÇ%ðŒäÒÓ›Ú»÷’ÿÎÀ,jÚtRÏžò|YI¾á®P(úöí+–¡&$$|ûí·ÜYžI_¥zßßš­m˜�Íœ>}ôU*jòGJ™äÈÂ… —.]*–Ñž;w®K—.�À3å+ Ëú]\›+wËÓî�}øá‡4œjÂÒÔ”d—u¸{xx 4H,£�ˆˆØ¹s'G'€¦”ÏôîÁƒ  ¢ߺu«U«V£¸r¯NÏž=ÝÜÜD4à%K–”””pŒ Ü«caa±hÑ" ø§Ÿ~úá‡8F¼¥¬žºËÊÊrww׃ä—/_îÔ©G*®Üÿ’���¸.Þ ŬY³rss9RîÕ2dˆ¸¹jÕªÊÊJV„û_rttüì³ÏÄ5æ¥K—îÛ·�ƒ@Í)eø¦û�;wZ¶l)ºaGGG{Èrw\¹×H‹-.\(ºaϘ1#;;›Cáþ—ÆŒ#º1GDD,Z´¨¬¬Œ£À3©/^,ÃͶ²²255=v옸†}þüùÆ�wíÚ•Ö¦ª§”mwÙ”””¦M›Šqä¿ýö[`` Ç.€jèÉvË���W¯^-Æ‘>üÚµk»¸rºôôt�F#Ææº�æ·ß~suuåÀ•û“¾üòK1Ž<...,,,++‹#áþÆ óôôãÈ><{ölÖô@¸?…¥¥å'Ÿ|"ÒÁoÞ¼yîܹÅÅÅÇž ÓG!ÿÈÅÅåÎ�;ׯ_ãà/\¸ ¯¯ïãã£bu` 몿»|ùrçÎ�Å;þ+VLŸ>]__Ÿ] €+÷ÿåààPYYyâÄ ‘ŽÿÈ‘#ÖÖÖ^^^zzzìM\¹ÿ¯ÄÄDQߟ\½zõ”)S¸~ à†êï\\\Ö­['êM˜>}ú·ß~Kçw„ûÿ:`ÀQo»ï¾ûÕW_UTT°7Q�üü|Š@¸Ëˆ‰‰É’%Kľï¿ÿþÒ¥KKJJØ¡xªcÇŽ&''S iã†êÿѤI1v‹|‰'Š‹‹}|| Ù§ø]eeå¶mÛBCCSRR®_¿`nnNYw¹hÕªÕ�233E½QQQYYY>>>&&&ìS(Šòòòµk׆……=þß„„„;wîôíÛ×ÔÔ”âHÓ2OjܸñªU«$°!6l;vlJJ ûEEEüñ¬Y³þø‡{÷î�:ujNNõáÊ].\]]KJJΜ9#ö ‰‹‹;~üxÏž=íííÙ­²•‘‘1kÖ¬¯¿þúÏuãÆ�ÔÔTccc %1<çþt>|õÕWãââ$°-jµzïÞ½~~~ìVŠ���0aBTTT5_3yòä/¾ø‚ùw‰aZæéìíí¿ùæilKAA�¿¿ÿºuëÊËËÙ³²râÄ ??¿ê“]¡P|÷Ýw~ø!è$†i™¿ôÊ+¯TTTœ:uJ›sðàÁòòrooo>€ËAYYÙæÍ›CCC‹ŠŠjòõçÏŸ×ét={öä gÂ]ú”Jeûöí>üðáCilÑéÓ§ccc»tébmmÍþ•°‡Î�;÷yOíS§NvïÞ�£I0æÜŸùÁ¶W¯^RÚ"µZ½k×®ÀÀ@ºŒIÒ… &Ož|ùòåûçË—/Ÿ5k×ï\¹K_³fÍ,,,Ž9"™-*//ÿñÇ�ŒŒ:vìhddÄ.–ҞݶmÛÀ�ÓÒÒ^ø›;v¬qãÆt•‚*yÕˆ››ÛæÍ›%¹io½õVXXXbb"{YŒ²²²,XPë¯"Oœ8qÇŽ\ü1-#}•••¾?agg^VVÆŽ ­V{üøñöíÛ×é�N©EŠp¹¹¹boø^½1cÆÄÇdz£…/))iÆŒõsT:tˆ‚3ç.‹É÷^½zI»×?þñ�#FÐ,P˜JKK÷ïß?a„ú\2""‚ö̹Kò}ûöíÒÞÆqãÆ 2äÌ™3:�Ž=.¨ÔË—/ÿýï1bD=/öëïï/�>zrÕû‹Ø¼yó„ $¿™ï¼óÎôéÓ[´hÁop©©©›6mZ´hQC @­V?~ÜÛÛ›}A¸KYEEÅܹs¥Ñöý™Ö­[7räH:4”¼¼¼Ý»wOœ8±ÁGbggwìØ1vŠh>ëádggÊä qvvÞ±cG~~>û½žßžû׿þåîî.œ#ÁÍÍ�ßxZFú4�|®<==÷íÛW\\Ì®¯kÅÅÅèÖ­›ww÷;wî°�xZFâ.]ºäåå%«Möõõ�3gNïÞ½ÍÌÌ8j]IIÉ©S§–-[!ØAz{{ïÞ½ÛÅÅ…ýÅ´Œ”>>¢8ºuë–””Ä^cZFÊt:ݦM›äye Ñh¶nÝšššÊað2233·mÛ&º)¾ÀÀÀôôtvá.eK–,‘óç¿ùóç_¸p¡¢¢‚ƒá¹. âââV®\©V«EºßCBB233Ù•„»”M™2EæS|o¼ñÆ‘#Grss9ªWPPpôèÑ×_];ýõ×_gvŽp—¸üüüñãÇsç÷ ùòòrŽŠ'>áݸqcíÚµnnnRÚÝcÆŒá7:á.q�= !Ü øé§ŸîÞ½+óet:]RRÒŽ;üýý¥º¯Ã IAáQÈZ–––öÆoDFFRŠ?Î̾ùæ›ÞÞÞÍš5“Ïâm:�.11ñÒ¥K»wïþùçŸ%¿½³fÍúä“OLLL8à‚p¯}÷ïß ‰ŽŽ¦O1b„§§gË–-¥š¥¥¥÷îÝ»råÊÎ�;÷ïß/«ýûá‡.Z´ˆ…y w)»}ûöàÁƒãââ(ÅS9;;¿ýöÛݺuÓh4NNN*•JÔ›SUU•––vëÖ­3gά_¿^Ú¡«·dÉ’¹sçp�î’uëÖ­��òý™¼½½_Î7oÞ¼I“&†††¢vEEŃ¢££÷îÝËDÜï>ÿüó™3gêëëS Â�|Çÿ°³³{ã�7¼¼¼Z´háììlkk+œ¬¯¨¨ÈÈÈHII¹wï^ttô®]»ØeOµfÍš)S¦ˆýáò½�?¾cÇŽnnnŽŽŽÖÖÖVVVjµZ©TÖõÏ-..ÎÊÊÊÌÌLOOONN¾qãFxx¸œç[ž×† &L˜ Ÿûç„»ݾ}ûµ×^‹��¥µB£Ñøûû7oÞÜÞÞ¾Q£F�5²°°077711100000066600ø«ËF­V«Õju:]iiiIIIIIIqqqqqq^^^fffZZZRRÒ¹sç.\¸@©_Ò?ü0jÔ¨zøM ½!ó}ĈúˆR@8œ��¿ÿþû¾}ûòT áŽWUUuüøñqãÆÑ¥B0|øðeË–¹¹¹Q ±à7°Pë*•}ûö=wîÜĉ©Ö·ß~»uëV’�+wÔ¦’’’­[·†……Q Ô?__ßU«VyyyQ Âuâܹs3fÌˆŠŠ¢¨7Ÿ}öYXXX£F�(áŽ:”——·~ýú9sæP Ô5OOÏ/¿üÒ××—‡ wÔ‡ªªª³gÏΘ1ƒå›Qw,X0}útJA¸£^åææ®_¿~îܹ”µËÛÛ{ÅŠ\°îhàKø¹sçž22rÑ¢Eô-��Aƒ½ÿþû=zôÐ××§„;¤¬°°ðÈ‘# ,ˆ��¥8gΜž={P ÂrQ\\|æÌ™U«V:tˆjHïjýÝwßíÙ³§±±1Õ Ü w9*//¿téÒúõë·nÝJ5$ 44tòäɾ¾¾FFFT„»ÜUVVÆÄÄlß¾}åÊ•TC¤&Ož>þèÑ£«V­JHH  Â1vìØ¿ÿýï]ºt133£ Üñ‚JKK¯_¿~øðáùóçS�dgg7gΜ   Ö­[3µ&++ëâÅ‹;wîdº¦žM™2%44ÔËËË‚j€pG�¨ªªJMM½zõ꯿þúÝwßQ�º<~üøîÝ»;99Q î¨?™™™ÑÑÑG�¥·p-ò÷÷3fL×®][´h¡R©(w4˜ÜÜÜ[·n]ºtiÇŽ§OŸ¦ / àñmR777žUáa©¬¬LNNŽ��=qâĺuë ¨Iõ¦L™èááѬY3®ÓA¸CŠ‹‹ïß¿ëÖ­Ó§Ooܸ‘ ÿ]·nÝFŒѵk×6mÚXYYQî«’’’û÷ïß¾}ûêÕ«;vì�á°îîî£F�òöönÕª•££#é Ü!5Z­öálj‰‰qqq§N�úþû梁¥¡¡¡}úôiÓ¦�«««££#­wA¸CFJKK>|øàÁƒû÷ï_¿~}ïÞ½âm4êãã£Ñh\\\œ��5jÄþá( …N§ËÉÉÉÌÌÌÈÈHMM½sçÎùóç÷ïß/À¡>ÜÓÓó•W^qrrrrr²··§wàù®îóóósss³³³=z”žžžššš””tãÆ�zX644´M›6NNN666ÖÿEÏtî@]©¨¨(ú¯ÒÒÒÒÒÒ’’’âââÇ¢Õj EqqqEEÅSÿ¹¹¹¹‘‘‘©©©©©©¡¡áãÿ677733311155566¦‘ w€€pa„;€pîÂ@¸á Ü„;€pî@¸S Ü„;€pîÂwá Ü„;€pÂ@¸wá Ü„;îÂ@¸wá„;€pîÂ@¸w Ü„;€pîÂwá Ü„;€pî@¸wá Ü„;îÂ@¸wá Ü€pîÂ@¸w Ü„;@Øþ?ódè„6IEND®B`‚python-msgspec-0.22.0/docs/_static/bench-1.png000066400000000000000000000447251525673062400211020ustar00rootroot00000000000000‰PNG  IHDR�FÝ:¯ÿ IDATx^íÝ œ�ÕþÇñ1E‰H.SJQ‰B*)ÎI„ÜMJäÒ�8*¥›['‘Û¸ݤP3ÈTt2#NÊ% ‘KRÒ¿ß:íù�™Ù3{ÏZ{ïgÏþ<¯W¯2ó¬õ<Ï{­ÝþZëyžUè�?7aC@@ @�B鴯 @@À é € €A  ƒâbg@@$}@@ (ÏÈ'Ÿ|Ryä9r¤<øàƒA]”ë�½t.9][jjª\}õÕÒ¢E INNζ˱cÇä’K.‘"EŠÈçŸ.… vMD} € C¹È‹/¾XÖ­[g8N9å)W®œ\ýõ2bÄ9ãŒ3BÊä¥ÐŠsyñÅåþûï— *ÈÖ­[ýZû¬ ?ZvúôéR±bE³Ï¢E‹äÑG•5kÖHñâÅÍÈ–Ž’ùBÛ½÷Þ++W®”Ï>ûÌœÃøñãÍœn:¢Ö©S')Uª”Ìš5Ëüù¶Ûn3Ç8p 9öå—_.3fÌ0L7 £óçÏ7碣¨·Þz«hHÕ²¾ öÚk¯É²eËdêÔ©&(oܸñ„éô… ÊÍ7ß,ç�wž qgžyfÀ­ÿÌ3ϘºtQ¯;·9yòd¹ë®»DG‚?ùä9í´ÓÌq† "O=õ”¹Î÷ßÿ„yê©§Ê;ï¼cÎMC^Æ 3¬4tþüóÏæÏjsÏ=÷È¿ÿýoÑ2Úf£F�2–þÚEÛ¢]»vòí·ßf\obb¢ÜqÇ_?;"€ €@ô  ï¾ûn^,X`¦´5X%$$Èĉ¥wïÞrÕUWÉí·ß.ãÆ�3¿_µj•\zé¥&à|øá‡Rºti3j©aK§e§M›fîÇ«[·®œtÒI¢£œ¿üò‹œuÖYfŠÜ õ~½nݺÉ�?þh¦qÏ=÷\~|ò÷ß7ÇÒà©�KëÐÑR 53OËèùêÈ^íÚµM°Ô5 À}ûöÍb,u­÷…^0!WCßèÑ£Íè[³fͤlÙ²’––&•*U ªèùêˆbåÊ•Í-¹È:Èo¼‘í>ÐÝ»w›©o ½zžz�z¤nmÛ¶•“O>Y^yåS¿Zi@Ô}}ò×_•‹.ºÈ„h�W3 ¤ZöÍ7ßôÛ.;v”˜ÐÚ¾}{N›6m*5jÔÊ€�@@ º �™/±fÍšfQƒŸþ££ƒ`ô~<�âÖ‘9YÓ`â �S¦L‘=zÈþó3"¨å>ýôSópŒ†2ÝWËdÞ|RC‹N÷jð*S¦Œ8p@:dF+5éÏ¿úê+‰��7ASC¡Ž>ꈧ£^½zfXGð²no½õ– M6u$Í7©ÇÑ`©uêæ;±{饗L@Ó}Ï?ÿüluΙ3ÇW7 —LsÚ|!0·©AUÚ†AiõmzO£^ûñãÇeÿþý&´k€Ô ç»gUƒÝ’%KLym‡ÌRG`uÄñ¦›n’·ß~ÛTÛ¨Q#3Ê«Sìƒ òÛ.?ü° >œ)ìèþÜsö €X  u [ƒŽN�jàÒÑ/�Æ<ûì³O˜Îô�‰o„Ñ 5`ê(¥>,¢¡ìoû›…ëܹ³ ‡:ý¬S£9H}úˆ� €Á  u¤PËŽÜmذA|#]¾€£÷ê=Ž::·víZyà�LèÉ+@®X±ÂŒLjÔÀwôèQÙ¾}»¹ç0R§ÑõÞK �5éèh Rî¾zGÙG}dî�ìׯ_pâíH€$¢O&ky :òô»PH‘Ô{ uú\¯EŸ„ÖéÚn¸á„)l#�¾—šëûõ:õ�:ú§÷t» µNß{ õÞJ½m D‰&´åôH}ˆHG{uúÙ÷ĺî«[æHý³NUë°ŽPê“Ù65 ?ôÐCfí¢÷ ê“îbµ½ô)|�jgC@�ØðìJ4±Ó¡¿R}ШhÑ¢&|jdC@l�6zQPVŸr×izÁô÷4z\§ˆ € @z¨1Bq*ú0�¾ÂHïYÔ{VõžS6@@ÀF€i£GY@@ �1Øè\2 € `#@€´Ñ£, € ƒÈlt.@° @ÚèQ@ˆA��H]2¯}ûöf D]%ëöᇚyë (úk]͆ @@ÀÛ! �sçΕÄÄD³â‰.�—5@êÒyºìÞÂ… Í2}l € €Ñ!²ùÝwßI©R¥Ì2ºÜ_Ö9fÌÑRtmi6@@�èY€ôÔªU+ÇÙ½{w©\¹²ù]áÂ…eÔ¨QrÙe—E�gŠ €Ĩ@Ää-·Ü"ÕªU“#FÈúõë¥[·n²råJÓ iii&XfÞÎ9çéСCŒ6—� €xG bòöÛo7¡±qãÆF#>>^¾þúk¿2Ç—�zGŽ3A@røû Yù$=Ó> ýBµÓÅ_,Ë—/Ïñ�gÇ k€÷Üsòꫯš×>üðÃæÕˆ'N”�7ÊêÕ«eçÎ�Ò¹sgyôÑGåÈ‘#Ò³gOùøã�夓N’O>ùÄü¬G�f¿’%KÊŒ3ÌŒïáÇÍ,°ÎüÖ¨Qü-gÕªU&�ÝqÇòå—_šçS¦L™"::™ÓòHWÍȤ+IêA@�pØH��Õ[÷Þ}÷]ø.¹äÙ°aƒL›6M¦OŸnžÑ`yþù盟O�:U¾øâ ó Å£G�JÑ¢Eͳ#úÌI»vídÁ‚2nÜ8óïçŸ^¶lÙ"cÇŽ5³Àúé'™9s¦èlñ€L¨Ô`ºhÑ"d8: Ç@@TÀ&@êH£>h¬ë¦ïÏÖY[ ”Û·o—§Ÿ~Úü¼I“&òòË/›°y×]wÉ5×\“�¯ïÙÞ¼y³)RÄüìÌ3Ï”}ûöI§N�ÌH£o_}¨YG4õg›6m’ÓO?ÝÌë?:¢™ÓÆ$}@�€m€Ô)f��ͼi°Ô8dÈ�ŒùÒK/™Ù«W¯äÙgŸmtñÈ *˜ Ú±cG3Ý­áS· /¼ÐÜ^¨R§¶o¼ñÆ<5�y± € ¼€M€\·n�Ü|óÍòé§ŸJéÒ¥e÷îÝR¾|ysdNRWÔÑC}¦DjÑÑC½?²uëÖSØú»¤¤$=z´ ’ún¡¼è¢‹ä‡~0SØ|ð�yÐYï£Ô¥¨Ë•+ÇdðMO @@ 6R�8~üxÑiôá%|ûí·ýH]Ô7Ú¤§§K\\œ,^¼XŽ;&]ºt‘ýû÷K™2eÌ}’UªT‘ŸþÙüü›o¾‘š5kš©÷:žrÊ)Ò§O"õ˜:é@æ¯OP @ÈUÀ6@z™—éåÖáÜ@@ j�h:^ãã�Fà@@�?�¤ € €%@€ Š‹�@@�ô@@ ÓÓ÷TkBݳòܯoß¾Ò¼ysiÙ²ežû»ƒ®D³|ùr9í´Ó.J€ ˜Š@@�À��[…lO¢ -#€ €@läO1?ëÑ£‡ìܹSJ–,)3fÌ�øøx³¶¶¾ãQWº©Q£†Y÷zÕªUæÝ�ºÍ—_~)… –)S¦˜u²sÚ� A‡¡J@@À&@úÖ¦öÁK/½TÆŒc–¬[·®|ôÑGfÍjýó£�>j–"üâ‹/$11ÑK œ:t�[n¹%c%šqãÆÉ‚ äù矗-[¶Èرceýúõ&$þôÓOf%šƒÊ€L¨ÔzõãHú2 € &›©ApÇŽòøã�›³Õ‘ÁV­ZIµjÕ¤~ýú¢�R7]‚ð±Ç3Ëêå5×\“quU«V5«ÌøÖÂ>óÌ3Í2ˆ�:u2õùöÕ:}�U—CÔ`ªK!ê?:¢I€ S‡á0 € €€M€œ$sûí·KzzºÄÅÅ™mô÷]ºt‘ýû÷K™2edêÔ©R¥JùùçŸÍÏ¿ùæ©Y³¦ ‘z¯ã)§œbêÕ©ÔèhäÀ� �y5´íï�o[f[…)_¸J}'õP  €DNÀ6@FîÌó>2#�y¼Çá§+¼on;¼ËI=T‚ €‘ @FÎ>ãÈÑðH¤: §€ €!`Ò!1Ò!&U!€ €€g�›†é“ª@@À³! �ÉÉÉ¢ï%ÒÇÀý-Э¿ÓetÞyçiذ¡_(¦°=Û‡81@ÈA Ð�%Ï>èÓÕ7ÝtS®¶ú¤õ’%KÌ’†þ¶ 6Hß¾}ÍÓÕ®¶�H}?‘¾E]_`©/»ô u™�Ý»w˰aÃ�µ*ѸêÞÔƒ €@äl䯿þ*Í›77Kæ¶é+}tNßéX äwß}'¥J•2ë5êK0s �º@øÚµkeûöíf±oF ÿ×ôÈÈ}Ø92 €®lä=÷Ü#Ó§O—+®¸Â¼ò‚ .0YiçÎ�æ��3fÌ�³Î:Kš5kf–<<ÿüóEsÕ¬Y³dÚ´iràÀéÞ½» 4H¢jÒ‡_«V­ä÷ßo¦·uxV—ÓÑås�HWZêA@ Ò6R׬ÖH]bP7�±½å–[2V•7nœÉPo½õ–,_¾$I@ˆ&›yèÐ!¹ôÒKͨc¡B…ä¶Ûn“Ö­[gLaO˜0A’’’dþüù&Dêý’ú@ÍèÑ£ÍúÙ:ò¨÷Eê ]Ô�@®Y³F2æó}�€yâÇ�)ìhúßçŠ €@Î6RkìÕ«—yE�†ÂÚµkK—.]dÿþýR¦L™:uªT©REtpNï•ÔÙ]}ŽÞøÇHÙ²eeëÖ­òî»ïFg€tÕ©�t%I= € ÛŽsÌï1BöÈüž�¿rH×¢Ô‡ €¡ @†R7Àº �B± € bF ú7�¼É=�y ñ{@ˆ¤Ò¡>Ò!&U!€ €€g�›†é“ª@@À³H‡MC€tˆIU € àY¤Ã¦!@:Ĥ*@ð¬ÒaÓ bR €xV€é°i�1© @<+@€tØ4H‡˜T… €ž @:l¤CLªB@Ï  6 Ò!&U!€ €€g�›†é“ª@@À³H‡MC€tˆIU € àY¤Ã¦!@:Ĥ*@ð¬ÒaÓ bR €xV€é°i�1© @<+@€tØ4H‡˜T… €ž @:l¤CLªB@Ï  6 Ò!&U!€ €€g�›†é“ª@@À³H‡MC€tˆIU € àY��Èäädiß¾½ìÙ³GN;í´ÒÓÓ¥_¿~ràÀ)W®œ¼þúëR¡B¿PÇ—�zROŒééæáä@@À‘@Èäܹs%11Q¶mÛ&+V¬È —-[&åË——sÏ=WÆŒ#;vì�‘#G ÿ(>x—£æ¥@@À½@Èäwß}'¥J•’ºuëJjjj¶™ùRæÍ›'‹/–^x�I€tßË©@œ „,@úβV­ZyÈ[o½Uzõê%×]w’é´ƒS €¸ˆx€œ2eŠ,]ºT^~ùå\¯Ž{ Ý7>5"€ €ùˆh€\´h‘Œ5JæÏŸ/qqq矖–fF-³nûLŠ+f.ôÔSO•-[¶ø½hdXúA@òy€Ìó Ü� »!€ €! @:æEâ1© @<+@€tØ4H‡˜T… €ž @:l¤CLªB@Ï  6 Ò!&U!€ €€g�›†é“ª@@À³H‡MC€tˆIU € àY¤Ã¦!@:Ĥ*@ð¬ÒaÓ bR €xV€é°i�1© @<+@€tØ4H‡˜T… €ž @:l¤CLªB@Ï  6 Ò!&U!€ €€g�›†é“ª@@À³H‡MC€tˆIU € àY¤Ã¦!@:Ĥ*@ð¬ÒaÓ bR €xV€é°i�1© @<+@€tØ4H‡˜T… €ž @:l¤CLªB@Ï  6 Ò!&U!€ €€g�›†é“ª@@À³H‡MC€tˆIU € àY��Èäädiß¾½ìÙ³GN;í´Ž=*]ºt‘ôôt©X±¢Ì™3GÊ–-ëjøðá2pà@ÏBê‰ =Ý<œ €8Y€œ;w®$&&ʶmÛdÅŠÙ¤þnõêÕòâ‹/Ê´iÓdýúõ2jÔ(äŸÅïrÔ¼Tƒ €¸Y€üî»ï¤T©RR·n]IMMÍ ;uê$={ö”Æ�Ë¡C‡¤^½z²víZd ÈãÛ–9éá…«ÔwR• € €@Î! �¾ÃÕªU+ÇÙ´iS™0a‚T¯^ÝìZµjUÙºu+2†$·ð¿)@¢C b²Y³f2vìØŒyöÙgËÎ�; �HëO·XR €¹ D,@vïÞ]2¦°k×®-7n4'›––fF-³n¡]¡Byûí·¥|ùòH¤õG–iMH €D6@ºòç=�®$½[SØÞmÎ @�Ì!ŸÂvÅM€t%éÝz�ÞmÎ @dˆúÈ?;?J#€ .� F �?.… ×¹�pF #ÂÖƒ ÃÊÍÁ@È·@®RãìÙ³eæÌ™æa—ï¿ÿ^âââä‚ .�›nºIúöí+•*UÊ÷Áƒ)H€ F+:÷%@Fg»qÖ €±'�k€lÔ¨‘|òÉ'¢«Æ\yå•R®\9ùå—_äË/¿”E‹É�dþüùrõÕW‡\Žr∀ñ&à@H ×Ù£G6l˜T¬X1[e¿ÿþ»¼õÖ[R¤Hó^ÇPoÈP G¾~däÛ€3@@ �€î�Ü¿¿”.]ÚÔ·}ûvùöÛo¥^½zR¨P¡@Žád¤FOWB€ôtópr €d ¯¸â éܹ³è”öUW]%¿þú«<øàƒ2räȰQ ÃF± #FÏ�@J  Y¬X1Y¸p¡Œ?Þ,?¨+È̘1CöìÙÔÁlv&@ÚèEGYdt´g‰ €@@òŒ3Î�Ö­[›ÐøÔSO™‘ÈÆ�Ëo¿ý6Adب#v dÄè90 €A  {öì)‰‰‰/Ÿþ¹¼òÊ+2zôhÙ¼ysP³Ù™i£e �ÑÑNœ% €H}âú‹/¾�jÕªI‰%dãÆ�rôèQ¹øâ‹Ã&H€ uÄD€Œ=F@ (�€äĉs¬´W¯^AÌfg¤�^t”%@FG;q– € sz]OñâÅåСCa$@†�:b"@FŒž#€ ”@@2555£R}'ä‹/¾(^x¡Œ3&¨ƒÙìL€´Ñ‹Ž²Èèh'Î@�€dV&]Þð†n�Ÿ~ú)l‚ȰQGì@ȈÑs`@‚(@:4£ÒãÇ�Ë{ï½'»wï–»îºKŽ;&üñ‡dÞ'¨3pgd€PQ¼2Š�SGˆ)�€d Kjˆ åF€ ¥®7ê&@z£8 @ò(@ò¾G}ÅO(7d(u½Q7ÒíÀY € �—@®ò�7Þ�Ûn»Íoß|ó�ìÚµKt­ìPoÈP G¾~däÛ€3@@ �\déÒ¥åœsΑÎ�;Ë•W^)åÊ•“Lj K-Îÿ IDATdþüù2{öl™:uªtìØ1�cYíC€´â‹ŠÂȨh&N@É5@îܹSyäÑ‘È_~ùå®ZµjÉ�!C¤M›6aa$@†…9¢!@F”Ÿƒ#€ °@@÷@9rDÖ¬Y#{öì‘SN9ż²bÅŠÄÅŽHŠÞ®ƒéíöáì@ð  óõ}ûvi×®�ìÝ»Wš6m*‰‰‰’ùin}!yBB‚|÷Ýwæ5@“'O–K.¹Äï¡�ùi…è*C€Œ®öâl@bW d²S§NÒªU+iÛ¶­tíÚÕ„É–-[fH?ûì³R¸pa0`€,^¼X&Mš$³fÍ"@þ)P|ð®˜ì‘Șlv.@ ‚ �G�•"EŠœ0’èïšãããeÓ¦MR´hQY¸p¡$%%Éøñã3v×Gýý¨Q£dΜ9²téRù׿þE€$@ZŒb5€[ÃQ €  ?ÿüséÒ¥‹¬]»V¾úê+³Í?ü ƒ ò{˜J•*ÉŽ;ÌïW¯^mVª™7o^ÆþFõéí}ûö™‘ȹsçÊé§ŸN€$@ØuýïF€´&¤@r(@6hÐÀ„¼ôôtó ŸÏ>ûLî¾ûnóH[ÕªUeëÖ­RŸØNNNÎØ}ÕªUòàƒJ¯^½d„ Ò»woiß¾½ù}ZZ𤦦f«zàÀ�žnN¦`íš?;?J#€ .�€dñâÅeÙ²eÒ¤I3š¸mÛ6iÖ¬™üöÛo~ϳzõêæÉí¸¸83…­ÓÔú �o»õÖ[Ík€ôu@‡’zõê™NÑ„«KDî8ÈÈÙsd@‚(@V©RÅ<3cÆ ™>}º¼øâ‹æéêuëÖù=–Ž(êÓ×úM÷îÝ¥yóæÒ¢E III1ïŽÔék}¸F®+Úhý:UιûàÑ`¬üî[¾DQó;�'~v~”F@ \È)S¦HÏž=Íëvt;餓äµ×^3OVûÛôþÇÖ­[›{5j$Ó¦M3�S_ݳråJÑõµï¼óNÑ{!�;&#FŒ0û…3@NOßëÄ9¡îYH’HˆT� €@ �zzߣ¾nG7�¾Îí��¡8ïPLa CÑRù¯“™;J"€ N�€ä–-[d÷îÝ£�z’ 6 Û¹ ÃF± #FÏ�@J  yÏ=÷È /¼�­bß”vPGÌçÎÈ|ÂEQ1d5§Š ÓÈ%J˜§¥õ5;ú"qߦ¯à ×F€ —täŽC€Œœ=GF@ �€äyç�'O?ýtÆ{ƒ9€«} �®$½[Ò»mÙ!€ �Y  9{öl¹ï¾û¤C‡R²dÉŒòúÇpmÈpIGî8ÈÈÙsd@‚(@Þpà æý�Y7î�üŸ¯ñ ¦Ëùߗ鯑Z@µ@@Rï�ìܹ³ôéÓç„{ /¼ðÂPŸ_FýŒ@†�:b"@ÚÑß¶Ì®‚¿J®RßI=T‚ Pp ��76/×§±#µ #%¾ã í¬ñ³ó£4 €@àH]–pòäÉR³fM)]ºtFí}ôQàG²Ü“i Å @v�„Ÿ�¥@(@VªT)Çu¹ÂpmÈpIGî8 ;{üìü(� ¸@@2ðêB·'2t¶^©™d×øÙùQ@ p�\äòåË¥Zµj²víÚklÒ¤IàG²Ü“i Å @v�„Ÿ�¥@È5@–*UJxàyôÑGs¬‘×øü�%V_ã³pÃ�÷´\ö¼ñÂ3Ìo @vœøÙùQ@ p�\¤¾@¼víÚ²dÉ’k¼ãŽ;?’垌@Z† øôô½Nj�Õî/S%H×¢Ô‡ àO ×yÛm·Iß¾}¥aÆ$@F¼ ²�Ò[mB€ôV{p6 €@AÈ5@*THfΜi^"éMdê�U�œFÒ3íM= ;Nüìü\—&@º¥>@�|�@j€¼ùæ›åâ‹/αü“O>6Ydب>2`ª°ìH€ 3AøS ÏÈÜ”Âý #�Þê³HoµÒ[íÁÙ €Y Ï9jÔ(3 ™Ó¦¯ø ׯd¸¤?2p«pìI€ ‡2Ç@P�<$÷@æÝQbõ)bdÞ}#œ{ éͱ@�ØÈ5@¾÷Þ{ò·¿ýM*T¨q%F #ÞÙN€é­6!@z«=8@  DÕR†Üé­®H€ôV{ ½Õœ  P�B ·oß.íÚµ“½{÷JÓ¦M%11Qô©îÌÛ‡~(ƒ–ãÇ�K¿~ý¤k×®~­�ô^7$@z«M�ÞjÎ(È! ��:u’V­ZIÛ¶mM0Ô0Ù²eË Ë]»v™`¹páB©ZµjžÆÈ<‰Â¾2ìä¹�é­öàl@�‚,²/›6m’¢E‹š�˜””$ãÇ�ϰ3fŒüþûïrÿý÷äK€ ˆ)¬; ÃÊ�çÁ�y± €€#��ÈJ•*ÉŽ;Ìi®^½Z†*óæÍË8íîÝ»KåÊ•%55U .,úº Ë.»Ìïe µ¸Ãj�1TE€t€H € „,@ê´ôÖ­[3ä�!C$999ã¤n¹åÑ÷HŽ1BÖ¯_/ݺu“•+Wšß§¥¥™`™uã!š€Ú4l; ÃFÐ��1± €€��ÈêÕ«Ëš5k$..ÎLaÏ™3Ç@F 3 $=ÓÞü‰4»~v~®K ]‹R €’éüS@€tNjU!ÒŠ� €A0…–¿]cu –é ó8¬‚铪@r @:è H;ÄXõ³SË^šéZ”ú@ü  ô�X @Œ@:è<« @:Ĥ*@F ³ ð�›OÒ�£«Z�®$©@ /F ó à÷Œ@€”Ë.±êg§–½4Òµ(õ!€ø @:è±€�tÐyVA€tˆIU €¹  t¤b¬úÙ©1éÚ�ú@ @nåwÏX @Œ@:è<«`Ò!&U!€0™U€‡hÜ|*�n]ÕB€t%I= €y 0™—P¿g2¤\v‰U?;µì¥ �®E©@ÀŸÒA߈ÕĤƒÎã° ¤CLªBÈU€é ƒ ícÕÏN�H×~Ô‡ ¸2p+¿{ÆjbÒAçqX#�1© @€Ȭ>^6mÚ$E‹•… JRR’Œ?þ„+�={¶¬]»Vt´²G�H¤“OÜŽ1Züì®’Ò €6! �•*U’;v˜s[½zµ :TæÍ›—q®ßÿ½´oß^,X ={ö”;I€´éËe£%1餹©@ ! �U«V•­[·fÈ!C†HrrrÆ%vëÖMú÷ï/—_~¹tïÞ�™©ñ @vŸübÃÏî*³—>¾m™“* W©ï¤*A¼,²Y½zuY³f�ÄÅÅ™)ì9sæ˜it;|ø°T®\YJ”(aþ¼oß>óßo½õ–4hÐ@ÒÒÒ$555›Ñx«+1‚f×øÙù¹.ÍR�®E© ²@ÈdïÞ½ÍÓ×ú�Ž06oÞ\Z´h!)))Ò¦M›L�<±‹1‚f÷‘Ã/6üì®2{i¤kQêC�‚,²©÷?¶nÝÚŒ.6jÔH¦M›&ëÖ­“„„Y¹r%2—^E²ûÈá~vWI€tíG} [! �®y¤kQûú˜‚µ3ÄÏÎÏuiF ]‹Rd¤ƒÖe%;Düð³pSšéÆ‘Z@ 6�Ú™d‡ˆ~vnJ Ý8R ĆÒA;€ìñÃÏNÀMi¤GjA�Ø @:hg�"~øÙ ¸)M€tãH- HíL²CÄ?;7¥ �n©bC€é � @vˆøág'à¦4Ò�#µ €@l ´3È?üìÜ”&@ºq¤ˆ ¤ƒvŽ–´ø³­®V¤éeUM=¼ÇÐŽ?;?×¥ �v¢¿¼x…]•.ÖçS'õP „V€éÀ7ZäßÍrpµ"IÏ´'@:�$@:@tXÒ?;?J#mH-F€´CŒ?»«Ì^šéZÔ®>~v”F ¶�Ú;Z#�ÛaH‡˜ª"@Ú!⇟�¥£M€é Å�vˆÑâgw•Œ@ºös]ÈN?üì(mH--ˆH�í° F b:¨Šd‡ˆ~v”Ž6¤ƒ#@Ú!F‹ŸÝU2éÚÏu} ;Qüð³ t´  ´X´ F 4¶Ã*�tˆé *�"~øÙ P:Ú�ZŒi‡-~vWɤk?×õ€ìDñÃÏN€ÒÑ&@€tÐbÑ€�´kì}~±«à¯Òg–,fþ‹H'œÎ*!ÙQ⇟�¥£M€é Å�vˆøÅ†ŸÝU†¾4ÈÎ?üììJÓÿìüòSš™µ,e@vˆøÅ†ŸÝUf/�úõONªlº©‡/ ;Nüð³°+Mÿ³óËOid~Ô�F Ö¦`¹ÀÁ‡Åa±ÖÿÒ…¤*¾ÀíXñÃÏN ü¥ �ÌA³CÄ/6üì®2{i¤kQ»ú@øÙ Ø•¦ÿÙùå§42?jŒ@2iÑo’ži“~d9%@ºµ«�/püììJÓÿìüòS:drûöíÒ®];Ù»w¯4mÚT¥P¡B瘞ž.ýúõ“H¹råäõ×_— *ø½†áÇKê�Uós�ÙÊÄê8S°vÝ?;?×¥ �®Eíêã ?;»Òô?;¿ü”Y€ìÔ©“´jÕJÚ¶m+]»v5a²eË–ç¸lÙ2)_¾¼œ{î¹2fÌÙ±c‡Œ9’ù§@ñÁ»òÓ–y–!åI”ëøÙù¹.M€t-jW_àøÙ Ø•¦ÿÙùå§tÈd||¼lÚ´IŠ-* .”¤¤$?~|Žç8oÞÙü_àvœøág'þÒ! �•*U2£Šº­^½Z†*sÚn½õVéÕ«—\wÝuH¤õ§ TˆHë¦qZÒŽ?;?×¥ �v¢øÙùå§tÈdÕªUeëÖ­rÈ�!’œœœí§L™"K—.•—_~9×óçÈü4ï‰e@v†øÙù¹.M²ÅÏÎÏui��(~v~ù)²Y½zuY³f�ÄÅÅ™)ì9sæ˜i2o‹-’Q£FÉüùóÍ~¾---MRSS³]Ñ䧉ÿ¿ ¿@B5‚ȱƒÙ‡ŒVö}ñ³ós]šd'ŠŸ�_~J‡,@öîÝÛ<}­ÑtïÞ]š7o.-Z´�””iÓ¦�¬ZµJú÷ï/ ,�’%KæyîŒ@æI”çÈ<‰rÝ?;?×¥ @v¢øÙù-Úø£]•¾¡z)ó_ ;NüìüòS:dRïlݺµìÛ·O5j$Ó¦M“uëÖIBB‚¬\¹Rš4i"Ÿ}ö™+VÌœ÷©§ž*[¶lñ{ Èü4ï‰e@v†øÙù¹.M²Å?;o•&@†¿=B ]_ Ò^”dgˆŸ�ŸëÒ ;Qüð³°+ýκývüUú暥Áu"|%ÈàͲ•`)>;DübÃÏî*³—&ى⇟�€]iúŸ�ŸJ ´È¿Øð³»J$~®ìê#ág'ý¥ �Ú�d‡ˆ_løÙ]%?×võ ñ³ˆþÒHmH²CÄ/6üì®’‰Ÿk»ú�øÙ Di¤ƒ6$Ù!â~/¿÷…Ý…þUº[óKÍñnlj~vv¥év~^(M€tÐ  ;Düð F é™öÈ`Àüì˸"~øÙ Di¤ƒ6$Ù!â‡_0È`´üïK²sÄ?;�è/M€tІ ;Düð F€ŒÒ�VöZ�v²øÙùy¡4ÒA+€ìñÃ/d0ZHŸÀç›÷8�û[µr¦�'~v~^(M€tÐ  ;Düð F V$!ÓK²ïËJRv~®K ]‹†¿>¤s�"~ø#«’L/!@Úi…¾42ôÆ¡>Ò�0È?ü‚ @£•}_üð³pSšéÆ1’µ è€ìñÃ/P0ZHŸ#¸výÆui¤kÑð×G€t`N²CÄ¿`�Áh �výÅWzË·?8©è¼Šg˜z�N8#Z Ò?È?ü‚ @£E€$@ÚõüÜøÄZ�Z•d‡ˆ~Á ƒÑ"@€ìú ~nü b-H­J²CÄ¿`�Áh @vý?7~±¤ƒV%Ù!â‡_0È`´� »þ‚Ÿ¿‚X ÒA«€ìñÃ/d0ZH�]ÁÏ�_A¬…é U @vˆøáŒ2-$È®¿àçÆ¯ ÖB€tЪ ;Düð F€Œ’d×_ðsãWk!@:hU�"~ø#@€ F‹I²ë/ø¹ñ+ˆµ ´*È?ü‚ @£E€$ÙõüÜøÄZB ·oß.íÚµ“½{÷JÓ¦M%11Q *”axôèQéÒ¥‹¤§§KÅŠeΜ9R¶lY¿ÆÃ‡—Ô«:i¾€ìñÃ/?,%—µÿ/ƒ~�¼+�݂އþ4Y�/²Ù©S'iÕª•´mÛVºvíjÂdË–-3@5P®^½Z^|ñE™6mš¬_¿^F�E€üS€ÿØ}îðÃ/FÀƒÑʾ/~ø#«ÁE˾! �ñññ²iÓ&)Z´¨,\¸P’’’düøñ.0{öì)�7–C‡I½zõdíÚµH¤õg‡iGˆ~Á ƒÑ"€ íú‹—J‡,@VªTIvìØa®UG‡*óæÍ˸v�Öž0a‚T¯^Ýü¬jÕª²uëV$ÒúóA²#Ä¿`�Áh �výÅK¥C 3B �C† ‘äääŒkoÖ¬™Œ;6#@ž}öÙ²sçNóû´´4IMM=Á©T©Ròã�?zÉ.¤çÒ°aCiР�³cädê¬rV„Ÿ]£à‡Ÿ�€]iú~vv¥]÷?»³ñné�HY\³f�ÄÅÅ™)l}HFï{ômÝ»w—„„„Œ)ìÚµkËÆ�½+Å™!€ €��ÈÞ½{›§¯õ! ‹Í›7—-ZHJJŠ´iÓFfÍš%ü±yˆæ¥—^’åË—Ëĉi@@� „,@êý�­[·–}ûöI£F�Ì“ÖëÖ­3£Ž+W®”cÇŽ™×ø¬X±B*T¨ o¿ý¶”/_Þã\œ € €@È$´ € €S€Y0Û•«B@B&@€ -#€ €S€Y0Û•«B@B&@€ -#€ €S€Y0Û•«B@B&@€ü‹öòË/—ôôt)\¸pȰ©8x}7¨®@ôðÃ_8 KУ°Ñ8e@ �5ú7ß|#•+WŽÁ.àíK޵I?ôväì@þ'SR_`þä“OʼyóÌÅ?øàƒrå•WÊ­·Þ*•*U}ù¹þÓ©S'9|ø°?~\-Z$%K–”~ýúÉ'Ÿ|"üñ‡Œ9Rn¸á³rŽ.¿¨k}ë:Þ�;w–G}4jûÖ† dàÀ�rÒI'ɦM›ä–[n1×¢«é‹ßß}÷])W®œYYèË/¿”ßÿ]F�-×^{­<ñÄòÆoˆ®i®ë ß|óÍÒ²eK¹âŠ+D×}ÿý÷åÌ3Ï”×_ݼ0^íôåò0õ 4Èë¹çž“ñãÇgý÷×_�1yÇwÈe—]&}úô‰:c½^ýç·ß~3/Ó0`€¹†«¯¾ZZµje®ûƒ>�믿>¦û¡ö5ùè£�¤bÅŠrÛm··Ý»wË„ äºë®3}næÌ™R¨P!ó{í³óçÏ—‡zHJ•*eúã/¿ü"£F�Êq_}RûöŃš~þꫯÊé§Ÿž­Oêgß«~v-ƒ~v±Uš™%@Ž;Ö„—þýû˯¿þ*§œrŠLš4I>ÿüshvíÚ%õë×7J—`œ>}º¤¦¦š°yþù狆°âÅ‹Ge/Òs¯[·® mš/¸àó¥|÷ÝwËSO=%E‹•o¼Q{ì1³¶¹^³K-§¡Hö‘#G¤V­ZòüóÏ›©aQ�´Ü˜1cL0Õå+5 «“†P]7]®+éêDË–-“bÅŠ™ßM™2ÅH µÛ¶m“qãÆE�­ö•®]»š~¢·H\sÍ5&ØÔ«WÏüÅE±/@ûþ"«ýPûËË/¿lþ‚¦!Óþôæ›oJZZšéƒ ,0ýEMÕR?£Ú7´¯êÒ¨êסCóo �Y÷Õϳ¿>Ù¾}{yà�Ì_z†nú·öá¬}²H‘"žíƒøÙ5 ~øÙ ÄVid–¹eË3z¦Ë0ê¨cÙ²eÍÈí·ßn¾øuÓ5½u¤ñ³Ï>“íÛ·ËÓO?m~Þ¤IóåW¥J•¨ìE{ôèa¾¬uÓÑ ÍúåüÖ[o™e'õK\à~Aë(ZÍš5%11ÑŒš=þøã¦œÖ¡£—úå«£Hü4|ê>ººÖóÚk¯™:õç:©£?¯¼òŠ è¾z´.}JNN6#½z~¢m›:uªé'¾ëÒl ':r¦Ëxêui`×Í cµª‡Zi¿ÐÙ‚³Î:Kzöìi–DÕ~§÷)kØÖ¿¬è¿5hþ÷¿ÿ�þ÷¿ÿm utRÿ§2ë¾ú{}R®}]7Álܸ±œ{î¹Ùú¤—û~v­ƒ~v±U:¦äªU«dذaSØ:ò£¡0ó¶6¿N3ê¨Ù¿þõ/Y²d‰Üÿýr×]weÈ›nºÉ|¹}úé§æ‹mÈ�!RG%u 77 2}ûö5S©¾©#€z=ö–/_n¾”uÓ‘ ýr~öÙgMøÓà§#“ºõêÕË„GýGÿ‡¼uëV9ùä“嫯¾’Ž;š�ݶm[SŸŽBÖ¨QÃXê¿NUf �:í­å{÷î�1­M¾‚3ã#FˆŽbi¿òFßõdþs,öÃÌׯŸ1ý³N+ëç¬y󿢷¡è¶víZYû¤Þ2 SØzOô}÷Ýgú±ÞŸ«£çYû¤öM¯nøÙµ ~øÙ ÄVé˜ �Ú´:ê¨÷OiÑQ �ªÎ 5=óÌ3rê©§šBtZU÷Ó€¤£d:¦áHÃŒŽ,ÅZ€Ô/S Œú%ª!R„©V­š™ÒŸ;w®1S£;ï¼ÓHý�ŽØêÔ£Þר¾Ðu*[ï5Õ[4 ë:§�vš¹÷L§|Õ\C¦~�û^ã£Så:::kÖ¬¨û”ê}Ÿ:š¥á[o‰ÐÑGÝüÈXí‡�|�ëCY::«Ñ<òÈ#ò÷¿ÿ]Þyçó—Aý\ë}�úð‹ÈœöÍ©OêC3ß~û­ úú—m' ùzGÖ>©Sé^Ýð³kü𳈭Ò1 ý5oÖ/òØên¯VGnuŠZ¿|õÕHú…̘ý00§ÜöÒð­déxN}2wcüìú ~øÙ DOiäŸm¥ÓÙñññææ}¶àÔO§¦udççŸ}öâÅ‹Íh$�(pOúaàVY÷Ô‡¬täQ7!שm�’Îi£OfWÁ/ÿ}OK⇟�@t–Žù©÷¥éSÃ:•í{š::›2rg}ôèQs_¨¾šG§¥õ©Y}‚]7¾¬kúa`NþöÒWMé»#õ¶ }W¨>üåï‰}údvEüèvv¥év~‘*ó2Rð@ˆVd´¶ç�@Œ °n¸÷;@A^Š”þGÿó¾@hÏ�Z_jG� °nxˆ`V[�$ýÏaG QU¹ÿ…ˆ,¨j �Aq±3xEÀw/£¾ÚIWõÑ¥ Ï9çyûí·Í+yôÞf]£^Wù™1c†yPN°¹øâ‹Í‹ðõ\úª}ÍTAØXË>¼­Hÿ;Ñ›þÞþç…£ ½Ð œ-àû×wŠê*H—^ziÆúõº¶>‰­/­×°¨k¨ë¿5@êŠ3ºÊ”®P£ï5Õ—‹„�µìÃÛŠô¿ìRçÐ7rè_ÚtYЇzHô]Jß­ªïPÕÏêœ9sÌr®úÂ~í· fyÒ#GŽH­ZµÌ_ì| QèªpZn̘1f± }§®>°©+Fé›+ôí ús}uWÖuëõa:}�°>P§ïÖÿ°¹ @º³¤&£€ï \_"þÏþSî¹çó"p}‘½.¿¹yófóBzÝôã:â¨R×µoÖ¬™ù¹ŽJê^AØXË>¼­HÿË uÔ_ß(¡›¾XWoÓ ©Ká®X±ÂI ƒj7`À©Y³¦è;vìÈXÂVëпüi€ô·nýk¯½fêÔPš’’bÞ5¬‹~d^2VÏA§°“““Ík–ôóáïÍ áí9çhȂӖ\ 1%�ùu<{÷î5+Ïè(ÆÒ¥KÍ;HuÄÁ uÔQ¿\4@êzïºB�n4u%¤‚°±–}x[‘þ—=@êgKo)ñHÔϘ†=é÷­O¯³ƒ 2«ºiøÓϦŽLꦫ¾ixÔrZ·^—Ö…*´>…¬Q£†Y%næÌ™Ù֭ש/v׿TöîÝÛS6wHw–Ô„að}�ûÖ»ÖC_tÑEf­{�Ów»ú¦°uɤ¤¤˜�¬eﮃÒÿ‚�ô?wýÏ 5 ½Ð œ-àû¿ï¾ûÌKÄu´Q×ÅÖuÙõ!½jÿþýR¦L³¾z•*Ub>@²–}ÐÝÌoú_ð’þç®ÿy¡&¤Z�s@� XQ&h²€ °–}@L¬²SÐ{Ñÿ‚&‹XdÄè90äW€uÃó+—½kÙoIÿ ÞÌ_ úŸ;Ëp×D€ ·8ÇC+Ö ·âËV˜µìƒó¤ÿç•×Þô¿¼„¼û{¤wÛ†3C@<)@€ôd³pR €U@_/£ï%2dˆøÖÔÖ—aß{ï½òÞ{ïÔËvv]ø9£´ªˆiÅGa@‚È€|kjë{< ��9â˜S¨÷"@†Z˜ú@ø YE—ÏÓw“êµ.·©AÑ·å yä8p ¼ÿþû'º¾´¾çôôÓO7Ëê{N¯ºê*ωâç¹& ù  CNÌ@¼.ào}e½7ñ¹çž3§¯²cÇŽf”Q7]‚O�ŽZê׫WÏNÁìܹ³YZ—Ï\¶lÙ —ï/@vëÖÍ,í§�õ¼óÎ3Ç«_¿¾\z饦ü?ü`–üÓU–¼¶áçµ ýù CoÌ@<, £…9­¯üÊ+¯d<ìâ �™×{Ö0©£‚ºêÑ›o¾iÖdÖ©¼ûî»f$ò×_5�òÊ+¯47oÞœQoæ)ìk®¹FÚ´i#'�t’Œ3ÆH •+V¬ð°ž˜ÑVü<ÝD!99dHX©@ ZtÄoôèÑ2oÞ<3xþù盀—W€¼öÚkM¹ZµjIŸ>}¤X±b&@;vÌƳÎ:KÆ�'çž{n@#�úÍüùóͨãÈ‘#¥AƒRµjU™;w®Ô©SG~úé')Z´¨9Ž—6ü¼Ôá;dø¬9 €€ôùûã�?¤lÙ²²uëV3‚˜W€Ô°7lØ0sä%—\bî‡Ô©[¯^½dõêÕ²|ùòlWœ×C4k×®•víÚIzzº™.×pª¡´xñâæþK ¦^ÚðóRk„ï\�á³æH €1"ð /˜§³ÿùÏÆÈ»½LüÜz†¢6d(T©@ ft´P§œuê9>>>fò{áøåW.¼å�áõæh €X@ßߨïmìÚµ«y[pøçɽ �‘ÔçØ € €@  £°Ñ8e@@ ’ÈHêsl@@ �QØhœ2 € I�ÿ¨;/w–ªIEND®B`‚python-msgspec-0.22.0/docs/_static/bench-1.svg000066400000000000000000000535541525673062400211150ustar00rootroot000000000000000.00.20.40.60.81.01.21.41.6Time (μs)ujsonmsgpackorjsonmsgspecjsonmsgspecmsgpackmsgspecjsonarray-likemsgspecmsgpackarray-likeencodedecodetotalBenchmark - 1 Objectpython-msgspec-0.22.0/docs/_static/bench-validation.svg000066400000000000000000000513741525673062400231050ustar00rootroot00000000000000msgspecmashumarocattrspydantic v2pydantic v102468101214161820222426283032343638404244Time (ms)encodedecodetotalBenchmark - JSON Serialization & Validationpython-msgspec-0.22.0/docs/_static/converters-dark.svg000066400000000000000000000313351525673062400230020ustar00rootroot00000000000000 Point(x=1,y=2)b'{"x":1,"y":2}'{'x':1,'y':2}convertloads{'x':1,'y':2}to_builtinsdumpspython-msgspec-0.22.0/docs/_static/converters-light.svg000066400000000000000000000312651525673062400231720ustar00rootroot00000000000000 Point(x=1,y=2)b'{"x":1,"y":2}'{'x':1,'y':2}convertloads{'x':1,'y':2}to_builtinsdumpspython-msgspec-0.22.0/docs/_static/custom.css000066400000000000000000000004651525673062400211740ustar00rootroot00000000000000body[data-theme]:not([data-theme="dark"]) .highlight .gp, .highlight .gh { color: #808080; font-weight: normal; } body[data-theme]:not([data-theme="dark"]) .highlight .go { color: #203060; } body[data-theme="dark"] .highlight .gh, .highlight .gp { color: #aaaaaa; font-weight: normal; } python-msgspec-0.22.0/docs/_static/django-modern-rest.png000066400000000000000000000361361525673062400233610ustar00rootroot00000000000000‰PNG  IHDRŠm?-*gAMA±� üa cHRMz&€„ú€èu0ê`:˜pœºQ<PeXIfMM*‡i&  Š mœ5“2iTXtXML:com.adobe.xmp 365 394 1 1 Á�¦†9OIDATxí� œÕµÿëV÷ôL¯@CŒËS BfAÀe�23Àf:bŒyf3û¦q�OÑcPQ#f÷ÿÌ{j¢-ĈHžYœˆ0À0|IŒOÿn™î˜™îûÎm@‡aj¦—ªê:U¿ú|øÐ]uï¹ç~OM�®{î¹WÓp€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€˜M`Úü† µógÕš-ò¬'PŸ=ÏúVЂÛènëúc=�¬.n×|â'ñxÜg}khÁ,5ñÆ�I™}¤&>»Î,™�ã pÞ°³i½¬m™u û¸&Ň_–©Ï™&‚,%0)©ÝM�èBfïÑ.Äß¾¥ÄÝ%7‹»ìiioÔÃFJ]=lr‡Ð´›«/˜sø�ïøß¹ÂZúrÒî„ýÖÔ<¿îbçj ÍœFŽÂiq°>a™þ–Ú‰ýTåëÍÜÔï;>:�@í‚sŽ’R^Ý_5²ã¢ºyóF÷?‡Ï `DŽÂˆ ÎD@°éĵ�¤/RÓ>�1ï�Tö½Ï'i>X+1ZúöÞpð9|�Á ÀQ Îg öb©ÉÈ€Óê+Ƽ�â”S*€MºÌ7ÐçK˜½f@§"Gq|Œ@msÓÙt>>صýçjê¶´zˆë¸TýØF­ë𮫷 7ácpÆlp…¨‡�&ä»l#(4íòó6¢Sžó!™º‚Z>À6RbF]sÓ§Œ.â<(p¸†$ÒR—R�²PîbnÌûÆáË¡„T›Ú¹*Ÿ¶¤�‹¦œwÞaù”Eo€£ð¦Ýóêµ ` )¾“Wá}…¾ˆ1ïhYY´Ïw‰À6lpl…¿�mC<¸G�{À�€Ôõ; ØFuhÌ[¨Ƽ�Ùp~ZKÃ9d‚B—êøJݼ٧ؠš`HŽ‚¡ÑìPY°ÉI´Þ–˜^oü·Â롆TL)«‰!Ë'ý”± '_:÷W�£p¿� îa¾lCÁRûƼ éXz!$“WRð×Aj3éÂ…ƒ_ÄY/€£ð²õ úN³e.£Ky° hÚX¿ï�†WqÁÕñ9GÓ �rÅBÞV?{DñPÓ�à(ÜhÕú¤fËM\S‚ˆ\U’ñe‚šRªÔÏŸ€Ð2…°�á“�ë�.â¼7 ÀQxÓîÆ½Îø `ÉRK�/¡l2ñ¼ `Óê°ç™!’–eùÚ´æY“Í�î Gá;šÒ‹ÜrRk6E˜‚1oÓP%èØ††Ê¬Ã&E%cÀ5Vèpò xù+…—­ß¯ïy,÷Яt1æ]¬âŠŽŒèWÒ{ÛñÅÕ6¬uzMKÓù†WqÁSà(\Kœ5‘…‰0�.ʤý Ìì&Ƽó IûzÌ¢•xçäQÔÎ"WÔ�ßhöB„vê�¶ GQ,ÎEÍܯÀTóçôxÎD‘å0p3ˆ™êر_�™úæÆ¼[-Ý_ÁL}­’¥Ø4¤Ãiiïʬž½Ý*�[~på·�%8`¹‡¢úEÎâ‡^OæêË&UŽÂ1E,W%š¾[×ÒÈâ ¨\ˆ8· GÁÙzCè>2¢_éè¶±îGW¦}žó®>¿áƒ°aÙ)µ;ë/®wzLÅøÎÃCp†hø^Ȱ¥dù°ÉQâJ¯&séq'1àù°ÚSÉ 3–áûçëHÍá(i–Ò”Ú¿_çµx*eÖ–m>Kmríš}ñæÃ7âêºøœ˜ŒâÊLŽ¢Ì0»ù²îW`fg¤8×KcÞ¹¶¦q `Y;˜Õ2‹�.â,,®bÀ6êÓ1^óΰ5骱}]øîR?\Œ ‹ó¼ÀQð²—¡¶*€MSKù° {æþ1o‘2° -4Ø©ÉcG†Å¥ƒ]Ã9~à(øÙlP�µ_Á }ÒÕcÞuÍ ç‘ƒo*šŽ³+^{ê‚Y�­"´Ë‡E>”^Æ¡û˜FÍ­cÞ*€-…psà7”íóÝjÚ�Ae#GQ6ôæ4œ–šë×HRcÞn l÷ÉÔ5t¸"€mt7ÓTKQœgAŽ‚…™Œ•j¶ŒëdScÞÉdÐ5cÞûØÚ·�-ë¢+ôC�mÞö„£`l?û˜‰WhÂ5cÞn `aëãF…µo q—NŽÂáR=û Ù…/3ý¶ë8®x]|ö<°å-5qýÔù�ïô"N:ž…ãM4¸‚ûÇ}™/÷0x߆<+µfµÿ÷�e|±ú’ê MfÝ��](å�_h?(´Ê;ƒ…3ìP°Bóý�*í-¸¢ *d5±„ë˜wÇÏ:z¥�u� ï‚Ðί‹7|´ðЍQnpå¶@‘í¯O,™–u¾§Èêܫј·þM®� ?:”ïãª)zK)îνU•"um'Ga;róì˾K+"½mžD>’hÔu\Ǽ×%V¾@¤ïãCÛTMOÒwŽýº©!Ìrp–#¶®�M�>úOZ8ï&ëZp´ä�_×9ZÃ!”Ó+ü×Òå®!Џø’¸~z|öxwÐu]ƒ£`nR9ê 5üô"ón«þÇ÷-«^lõòÕ[÷«Ç^§�ìØÏà*’`´OJ¶‹„WŽjpå nb›*8ªi´j¬G /æ:æí×B·ÒZêÛ¼i:yaMËìzoö�_¯á(øÙì�ÛY±ŒN®:ä‚7N°ónK$º5]»Îf:´—B“K¸:ùC{ãî3p.±¯ºZ‚B^<øŽy·OªûO²X‡­F·ë$}×_öfßyõŽ‚—½ µÝ�x|=y‰_p÷…h_6Ë3°½paVÏ WmZTЭ&µ«çŸû¾‚ê °íà(lGn]ƒ¾¬T¥­kÁÁ’…ö‰ió›>â` U[·lÅSääWp÷…˜Ð}·¸»‹ü{GÁ߆ïö`ݲ•ÛéuþîwOxìCVר&sIéSC‡41Á{­{uQm¼áLïõœO�á(øØ*/M=ߣ‚¯çUØu…ä$±sìW8v«céò¿jRü‚£î&èL¾B,©¯¯÷› ", GaÔrŠ\ýØc]´´el{ó ¥Èoœº`î8޽ïӳדÞïpÔ½d�¥vrrLð‹%Ë�KÀQX‚µ¼B#o§J¿Ð¶”W‹²µ­èíc9æýlbå›Dͳ‰hBŠï!°]¶¿›!†£Ï‹­­­}´”õÕ<µ/]k)´OróGÒwÐ8Ì+¥S`)!¦ë>5tŠÃa|Óê˜D`Çÿüãïã'w‰;Æ$‘œÄД¨9~ìøŸoݺ5ËIñ­›¶ö�;ñø·4¡Í礷‰ºN™0é„';_ø;MÌÀáx£pŠ%¬ÑCÍÏgõ 4 �y§É4y6 j_ºârí66餦„”Ù{âñ8~Ä:È*p2†Ùª´'žØDóóï7[.y´ùMLǼ¥–ÑÔtY¯S·jÉK¼Úy'öŽÂ‰V1Q§ ¡_CâR&Šä$Ší˜wû²'ž¦XË£œ`›ª+¶§ÆƘ*Š&GQ4:Û�w’¦^Ü£ù€�.®ki:ýÀNÿK]ª·ŠN:›¨ëH¿ÔØ6h)¢à(J¡Ç¤nZ¤Õ”Ëט¨k¶š‚† îâ8æÝñÐÊ—HwšêìÕC~¶º¹qšW{ï¤~ÃQ8Éé²%Ñš¤Y@ -ÏA,Û1婢®’ðvr€l�Žº.h_ø… ñœ²n!"a€Bh1.;Q ÝKê?ϸ ¥©ÎtÌû™Wì¢äÉï—ÖyÖµ«kŸ_÷YÖ=p�òp.0b>]H$šr©V—õêAcÞâfŽ�O‹Ð)1äu7Eg!n©¾`Îá¦È‚�¢ÀQ…�g%š.û;š.û$OíMÑú3Óæ7œjŠ$…lI$z¤È^kc“Nkj”èÍxvý2'ŽÂ V°QŸÌª$¼Œ�M:©)=«‹%Û퉕Óáj'Á´SZÖä’šøì:;ÛD[x�…'>­[ú»çhuÙû<ÑÙÁ;Y½UKsó–z&7]–^ =yè‚2¶Ø.�íá(Êý¬­úþï�]eU¢œ�Kù}ŽcÞ´1ÕZÂöH9Ñ•¹íššç×]\f<Ù<…;îW�½N?Ko÷`×ty”¯7sÓ�/œþÂw%é»—“Îfê*„¶¨nÞ¼ÑfÊ„¬á ÀQ ÏÈ•%*Dx‘&µm®ì\�"GùyŽcÞëË_¦¡Ã{òè¢K‹ˆÑÒ·÷—vα݂£p¬i¬U¬-‘è¦àèõÖ¶âhélǼû2š$ßv4]k•ûbMsÃTk›€ôþà(úÓðØçö“ë~I]îðX·ûw·¦nKû§ûŸàðyÓ£�þ“2í½<]Ô'„XB¶¢ÉP8ì Gae§¶±paVÏ 5]Ö³í}ðŽcÞÙ‘¯ÿˆŒö¢g §i3êZ.òpÿmí:…­¸�רºe+ž¢_gO8O3»4â9æÝñ³Ž^úA}•]”œØŽÔÄ¢)ç�w˜us›Npn³hýÉdõ˨Z_UÝRåKµógÕrëLû#+–‘Ϋ¸ém¢¾GTøzš(¢ ÀQ€ñÒ鎥ËÿJ³€~á¥>è«®éú�tŽÝ˜·”ò¤·7·»UFÚWëæÍ>E}Äa8 ëØ²’œò:Rx7+¥ÍUvF]sÓ§Ìi½´ KW>KÓœm}KŽmÁ§ù$Û›ŽÂZÀl~¡>›Xù&m’£68òì!…d9æ­K©’ðÒ^5Ý·§Õ¶4|«ý·£ßpR®inüò´–†s,lÂTÑ‘H÷bòl¯˜*”—°±þžx©¬i´´ÇvÊ«¸››Þæê+n¯ŽŸ=Â\™�v€Å&ÿ?cÞ9ci¹�ïÒ&·rY­´õ¾Ö=R //g­î‚¯póôT¨ý¥_7ù6æ$î‘ ¨áS€£°ªÙëó-¢ÿFÒ/ôɯhé‹Õ9GûÒ�ž8èj‘Ž>é§UJ™¶W?öX-íáå$<ÊAÔ¾>­yÖd‹î O‹…£°Àü5ófÒsæÝÀ(ÍLùÞ̹s£4e…Hšžž[ÎÚ Ù”¿(ý6å\ò/_¾’[‰M—êש—–cÞi‘VK²¼æeà )�x™�}÷™!ÄË2¦Ío˜ „ž �|9PbИžPÅŽ/¼Èbw¹/üã…ñ“Ž;›úwt¾}t]9¡M{ߤã}í…ßàÒ·7_ØÚ3~Òñ]¤ï.:[ g¬B«ô·öG d{F$Þ(J4uV‹iØ©à_,”§p#£)|RÏä’ðh"�g¿N¿N¹õ~¢º—t~ž›Þ&ë{YM|Ö &Ëô”88ŠÌMÙ»êWv¼Hc3{´+Ьk{5Zxn-Mý]j{ÃŽjPžE“еwYz’H$h¹1>÷™E�Bêl—Ž¢Hx“âñ-uQÒÍG[�^ZŸÃg8Gèʱí-™+ªÑÛãbncÞí‰'~G÷ê»ÂÅwâcuñÙóНîíšpEÚ?(“*©é_Ь~ ZЗÍÜtà‹Óÿ_ŸXþ2-<§fwyù˜ʆØ÷éýR2š—·»¥ÕM²wM¾èœ°—oÞbûGQ9µ Ã\SDÕCªPžÂ'ëšk¹àÐU•‚›|Û¡êÙ£–Ð.­nžSê�{tÝßʺÄÊÈÉÿÒÖF�֘Ўªìö_å4µ8èGQ„•dÆÿCªfÖ/šÁ§ñJÂÓ46oAE˜7Ÿ*]Ï”4ì˜O#f—ñüêM¨Ël¹Ìä]Qw~ãñÌt.»ºpš€öU>—’æÎ+°ÚpÅϬ‰7Í®�S®ËQo¨á§�¢OYô�ÚÙµ-MóËÒv‘�®ûÕc¯Ó¦ l~”ÙÍáª²ÈØŽÑ!×á(Ab|âØ††J fª· Ó!å¢êKª+Ll�ÀŽŸuôÒ0ÆÕˆæ%RÊ;¹�yûµÐ­”i¿�hsµ¥©éçpúafnï‹“GQ·ÃÂâ*šjhÕkë bר/ NY‹nXú„š*»ª¬J”»qó¤}¬f["ÑM÷0»åÓÍ65ý0»»zΜ�ÙrÝ*Ž"OËN�ßø~ú%biÞ+®ç´Y޹嬽œ„G#9ârncÞí'ש vGž·¾[‹í«ÌXú÷ì&ppyZÓ¯kK¨¨Õ¿@2`Êlª<»UR± ‰Çד—øuIBøWæ7æ½paVÏŠËù£/­tï^AI³Ç”&ŵá(ò°sMKã¿R±Ùy-¹½µ|³úü†–,È&¾¬T¿ÊÒ65çÈf8Žy¯[¶â)zP®p$Pû” j"ËnYûð¼×Å{,ý4=ÒƒÀΛ) 2⻃*ãÀ“´´ÇvÊ«`7UÔl”Ǽ¥ô©¤QO'áÑÖösëâMMfßn“G1ŒE{³I5÷üÃ3õ29¦4õr†©B-è©ø‰ÝÂ&8ˆf7æÝ±tù_é­âàZ©£ÌÊ»ê/®¯²² î²á(†°à‡ãçKÁʈ(bÕ%òY5ß�þwþ±ú±Çºhº,›· «ˆÒC÷ªiͳ�³J¾r3B^Grß±B6™Bû`*RoW8 ÀQ€Q§}Ò§r&ÊôKCL§· 6‹˜EÞNÿ”üÚ–!pzáR%E‰oçÔÑg+ß$}ÕG^?®©‹Ï±uä€p8 kíßB±Áà²M§å­*ÉϦÆJj¦µµµ�–"a3c«¤ÎUYjsêZm™ø0”…\ GÒwЫë+…ÔqaÙ ”}¬œ¼�6ðÙÙ—¶T"ŽÏ'KúVf�GV´·i‡¹µeÖ#¯æi±¿ÑNx§QácòªàÖBR›vü´ñ?Ûºi+‹@±Òs܉ǿE�¬–$1ÿö'Ž;ñƒí;þçÞ^žf°x£ЍÌ\OãÍïä’í§h•ÚëêæÍm{ÃÅ7¨æçg‹¯î‚š¹1ï «<…ö¥+ GÑîú%uA¾»¸¼Å—ÔÑ+ÃQ ¦²lé5üN—óëȬ¾—Í�m’³‰œìýå挶ÅÕÌÆ¼¥–Ñ<Ð¥µÜŽ—:ãrŽpl!3Ú�锣âBh_å4›¦Bèʱy: �úÌj™Ån/Gm_öÄÓgzÔÑJڣܵ§.˜5Ñž¦x´GÑÏN5Í�Ð×�ö;å”��¬Èª\G[âñN)¥�IŠŽä¢–£¯ižÕèHå ”’ºTo=—½r:”íóÝê•ÎæÓO8Šý”fÎ�¥_îN¾9âÕñY*PÌâèÖ»o!E_c¡¬…JróîxhåK4üBS�½}ƒ–Úxã,oSx¯÷pûYôún �ãßCã¼O>©³IÂÛ’hMÒÒª �GÑ^�8ŽyWôë‰ÒN{I9°5©ý�í}v�£ µÍçN¢ìWx«¤é8­6ÞðñƒN:øËD-t/ͤù‹ƒU´K5VcÞÏ<¸bÅ*Ô¡×�㋈¯{‚ê?…Z&CèKˆE‹"+náò+'‘Hd(V¡V—õúÁnÌ»[ ßE;á½äuÃQœiau|ÎÑ^çàyGQ×ÒpùŠz67‚Ð&Ž ë_ã¢ï†GV®¤7¡'¹èk•žÜƼ·$=š.Õ‚˜^?Bºìóü'žvÓ.lˆIM0|Å–ß©¾`Îá\þ‚}2«’Ï2\ôµLOfcÞ퉕ÓûöjËx°,ÔÅ>ÊF] õ´£�{t5åô}pµZäazoæß­nÄ,ùë–þî9Z]ö>³ä1–sܨ°£’9‡C)õLnº,½zû�RÜ]}I5�ái LåYGQoü�ò‹0µKä—8íÕì øÕ0F—]pœÚ½Á^¯ö_wª~õ¢�©ÖRoéÀóü~’o×l†|Ͷ�W…Ðen®¸ßl 6Ê«Èfù,½îW�½N?K±:'í»î|ì–»Ÿ…®&$ìµñÞvdSôV¼pꂹ㩜ÅJyÒQÐÖ‡Ÿ¡öt‹ÙZ.^eþÖ¶Ì:Ëò†Lj B„ÑLšm&‰ã+Fhçsó^ŸXþ2=$ïá Ü4Í£þ¾Ì"Ó¤1ä9G1=~î(š²ù}F6FUýVmáBvlK$º)8zý0òÄencÞ}™Àwioô·=aœ!;)/¬i™]?d^dñ€1“{Fún&ycÌ”YfYSkÿ²î‚2ë�wóí'×ýRrcÞÜ[ð$}çX6É\›}ôŸ4tx“{͑τ&—x-°í)G1-ÞTM7ûçò¿%¸”·¨Í–Xh»paVÏèjá9ØžŸíèecúIŽzC ?½Øÿœ7?ËIú®#¾ì¥¾{ÇQÐð 9©ÝçBOÐ+3NÚCcHÄë–­xJñÄ�…¼q1ڗͲóîøYG/Åö®ò†i†é¥Ôn¬ž.Ç©õÃtlðËžquϯ¿„Þ&¦ ŽÁg¯¦Õ.�äÒ“LV¿Œte±U¨¥L…ö NcÞí�¬XFM-gMÙ¿ž?(™ËÇfÌ»}éÊå´Øã7-Ý´šŒèºÿ.,Ö?ôÄßé×´š¥†CÓ.®‹ÏžÎÄ夫ãã*6ðé—¹�3mhʾ&\å(öMQ˜AsÐý#?£vó;蔃¿øô\ÞN«h—jBÊì=\ƼÛOl¢$¼ûí‚ãìväg«›]µ\�«…&åt�pöMd»v>]jwÚÞj‘ ¶%þ{'½¾³I,²›ùV›ºUK^’oár—«ú5¤CªÜz8 }]´Ñ“}bòáåG±oÍq~>�ö`™�Ö57�Ë¥ßÝZø.7{‰‹¾–êI�m.cÞm‰Ç;‰…ú±†CÓªkŸ_÷Y·€p…£˜�èWèOÈ(ž`ݘRÈÅ\Ö¤Ù’HôH!®5ê‹ÇγóN‹´Z’å5�Ùhðî Ú'æ‚9®XcÎŽ"¤¥.¥¤Ÿ·Îî'pRúðÐÅ\hlxdÅCäöWsÑ×Z=ùŒyoI´&)ip¡µ<ØH¥÷dod£íвwµ Î9ŠfÊ|gˆ>âÒ~lüÞ̹s£L€H=“KÂ#µ=°󞨅î%‹=ïy«)B~¡&>»Ž; öC5Ç�=ãZª£™»!ìÒßç×oúÛ“kØÌ ;þì™[²ÙÌIvñqr;>¿ïs{rµz;þ8áÜÓ¯Èôöªa(Ï´›cÛ‹l›ÁûuÔ»»÷<¸ó­·š)g€³lÑ�vä’cFŽTë_±8&œ6yÖöí¯ž$aZ­¢"Ð9ü06™ëo¾ñú•Ýén÷™ÕJŽ=æI«Û°Z>û¡§í«7.‹Ä¢›­åù‘Xì�[×lb±P âÝ�Þûpûî¼h,vËŽÖŽ·8܇ã§O¹™œÄ(ºZ­c(þÿÛ×l\hu;VËgï( @4Öä÷ù‘:ÄÝâ¯ðg|ÁÀCqÔ¥ñ3OùV:•f³¸•ð‚¡Ð[�kže1\8±~bU2ÕÅf�1+íFoðZ(uÅ”}W8Šíj댌ˆýÜJ£s—‹Æîåò‹T£õºR]©›¸37Cõ°‰Db Ì�e‡Œ½Ý±zööTÚÑ–ÓÛˆD#ÚötûÓN×3ý\á(TG_kÛüå`0´+ŸN{­LeUewgåHµ‰‹ãÈ=oÿlïÞ½!ÊZ¬d4m}uUû-nÆñ˜1ãý]]»Ï3Es!�@o0TášI6®qt_eÃÑà§)ŸÇ¡`l¡¦–ƒfpL˜>}T*™úU-W‘6}~”ÍÃ&Ý÷ÎÒL&ã¦gJÑ6ŽEGܼµuÓ?‹à°Š®2ê¶U›~KA¿‡1.«:¡Pøõk7.*«4Þ—éZÖ×ÛëÚ� @¡Ec‘ïookc±@â„ÓkÏìÚÝU]HÿÜZ–د¹!€Ýß>®rªcU•UsTà¶'½ú™öÕ¤`ZÕ¸ôÜ5Séas&}­Ô3 ½Ñ¹zóuV¶a¦ì=©®$¦¨iûØlbJùÞ®s¯¬êx-‰ý(_n.GÓ†ŸWoY\úØ›J=”•˜¼¦6áà63Ô&œ>åó©Tj<—ûÌJ=)€ýG·°ûsr�£P�Û±vó׃Á ‹WöþÆ0ó³O÷Éh8ø 3eZ)ëèéSâÉTê8+Ûà";�>õÊšõb¢¯žÚ�º�‰®–ª¹?€Ýbi#eîJG¡XF¡”:_&¬åo–’ë~÷R놿”_“ü4Hv§Bû‰äWØÅ¥ö=lüó¹tqÜ©“—ìÙ³‡Ëúa–bu[»?,×:ŠWWoú=×öï¬W>«�¬`3shü©“oêîF&¯º?cÀæ2[fbý”Ã’Éäç½òw5T?)€½Ãmìþýu­£P�ô…‚s***XL ío”R?G£±ŸpI®Ëeò¦Sß.µÏn¨Ÿ[îaõæë¹ô¥»»ïáÞÞ^öëÅ•Ê{›ML©˜þºÚQ¨‡%—ØlZŒÖQÉu;*G~sày§~§LÞû‘É«åfËÃQ6³eŽ�6é¤Ô�z_Ù© óþÁ�ìþ ]í(TGw´=wy(z³§Ýü9Š]Î%¹n&ï<7Û#ß¾E¢±?m_Õþç|Ë—»Ü;}ò‘L6ëÝ à~Ъ¾½Á /^n{Xݾë…X ] v~qû…wlkÛx—~¦{ßy™¼š¶/€íc“�ýþÓ«›RÉ$v”¤?´X$ü=.1¥Rž žp�«žýc4}¦PN¯«&x£•Ÿvºžô;êŒÚ3ºººj|÷òÿ±HŒM[Ù©+™¼û¿hšúa¶}ís7xáÞõ„£P†ôûbÿª~¹¹Õ¨‘HtÓ¶§7³Ù ¥»k72yéf «åÚžeÀ7}Ê·»ÓéÃÝúw”o¿rìaW,!žOŸ=ã(Ôš9ôVÁfÍ£|Œw ŒîÓe$ýø�ïNÿÂÌÉŸK¥Óœ®§Õú©‡M0Â'€=iÒ¤ 9}×j.äÓª¿µµÃÕ£ýíàG¡:ݹfÓµj‘¼þÜð9‹>þ¿O¯{‘I_ôT²{1]-U“Ûr»¢þÿ×Ó³·ÊR( „«v¯na ªi*zÊQ(jU#BçéÂ=ÝVy"=2üIÓî‹�›~Ê‘É{ €]Áæa3ö¬“�èÚýŽ«sò½õU{çºu»ó-ï†rîybæi�ÎÖ�kéµñ©<‹;¾%×ÝÍå¦Íeòvu±YÍÖJãs[îAìÖ–õa¯ SêôJ»ÿýï9G¡:ß+Âç•=ýApü\ULv¶mú6Ý)“÷!dòj·ý Žš1¥6ÙÕ5ƒË}f•žj$" ³IŠ4“ƒ'…ú‰Eš ²²‚áЕÔ.‹u¹ßêÉ'R&ïÇÊÁÉImî_î�ÕÃfÏž½cùwZhtDôI/°ûÿÝxÒQ(�«7}_-äÕ§ÏáHdÛŽ5›Øì»ÑÝ›E&/Ý`Ü–{˜pZõ'’éÔDNVèº?€íú l#vžu H0˜Ï1°­–O¯ U±I®S™¼´ÊèIF7¡WÎs\î!�Üý#,ÿ®i#¢‘ïr‰Zñ÷äiG±ý™çÖ©×I+ÀZ)“òA6¨ls+Û0S69‰ÿ@&¯ZB<Êj¹‡q3N¹­»{Ï3ï޲h[ÚíÛÚ6{:ÄÓŽBÝ´ÙàáÍ�@`/—XW;×E«ØŒq�Ÿ1õ²t:=† _«ôÌ-÷°f›åÆÔ×GR»“_·Š¹¹öˆˆç§{ÞQ¼ÙÚš G¢×r¹qc±Øoþñ§Ž—8è«2yi¶ÌMtµRÇ\v,ÆÆ¹+¾=o=ØÓÛSa%²£±ÿíÕvûxÞQ(;Ú6ݦ‚ÃýÁ8ñ³Z«ª/8êßœ¨Û`:ý3ªß‹L^5äûý¶?¯_5#'ž;᜺tíNÎv¢nvê  ìd³4Ž•là(öÓ�†‚³ÕšIVÂ.Uv,Y¬Þ€J•cG}•É»{wòv´åä6rìh€Õl™]»’¿Éf2ÂÉ\íÐ-æñvÆpûi¼¼jãsôš¹¢?'}¦äº®ík7_ã$�†ÒEì–Kû2}ž¿¿Ôrÿû‡Žw†bå¤kãgV$Ù•<ÅI:•C—pìþÜ=ÿ‡ÜFUÕî8elïéÎ)ŸÃ±Ðe¤ ‹äº£fN­¡‡ÍL§°+——{ØÓ�zPJG¿X[nNÀ„cžYB< pý(mmݺ'�¨²£ŽH8²uûªM?w”RC(C‹þy>“—ãrN›úõt*uä¦õÄ¥èˆ+w<ݾÆ�ͳ“p@©lgõ`pºl_Õ®‘È…eS À†�š>õ‚d*õ�«¹®8»åêëý©®äÍ®3D�ʰµ «jv±¨âpƒ`‹ÅÂsœئ= Örúu“êNþØë™¼*€ŽV²š-ó¾½;Bo‚áAþŸ?© ³yàŒ›>y2yi:l4r§ö„éÓGQLéb[on6¦¦Èo[³Ùóy?ƒ™Žb0*tnTWvAeUe·Áe[NÇ¢ÑÄKO·;>¿CÁÈeòv¥¾i 7‡:··m¾ÑÁ*¢Zo_×Ò¾Þ^ß!Áiˆ×nÐpCï\½ñ§‘HäC±ìR$^´cyGÚ²LœËäMvÍ5Q$KQ´„8»ý º’饙¬·“ëö°Ãž_Ïi¨?:8Š¡èеh8Öèóùl�X ÿÙ¹v󿣚c.ïÚ™\–ñx&¯zØôŠ« 죧O‰ÓʾÇ;æF*“"`ŽbFÿûôºcÑØÃÃ3ï2í5A3�¾fž@k%å2y“É)Ö¶â|é—{Híéþ±×“ë(€ý*ØÃÿ}ÁQ ÏHÛõɪªªTEK.BCN/½ºjãý% ²Ieò>€‡M˜Ý~fžr-ÿ>Ú¦ÛÄ‘Íì`cÈ)ëÀQäIkmí‹F#_Òè×¾•‡ZŽ: ~ÒÊ6Ì”½?“÷}fÊä&‹c{býÄ*Z°Qí·îéƒØ+ÀÎÈ�“öê3ÏþelÿOžÅ‹*FÎè™ÎÖ�k‹ªl%2y)†¥ö+xjÃjûñßbO:úËÞžžÊâ%ð¯I›•õôhaϯnœ¯%á(ò%EåFŒÎQIpTÉ»¨ÏïËú#|6·wêä{=“—ã~´ùûv'»Zò¾1]Z0�]ƒ ìü� G‘?+Mí,7"} €*yñàö?µuæ]¡Œs™¼Éԧ˨‚#šæ8[†œû£4CÍÓ÷*€Ý¹æÙÛq1QÂÓ7L16ê ŽúŒÚ¢˜ºFuÔžÝUï|ÞèºÓÎ÷fv'z{{üNÓËN}8.÷pÔµg$“]uvrrZ[>Ús> Îwš^N׎¢P Q`;�~Q˜ØVk©%Î U¥ås™¼]©�”£m§´Éu¹‡îTòþlÖÖ” §˜ì]="#b+^}fcÇ»'ð!/pya:¸Ðög:ŒD£Ï|¶¸o”\·‹Ó<îÝÉ”ç3y£#bìö+˜0sòçh©Ž£Š»KÝQ+PØ«�©8ß½±·pEòDc þRÛôVŠD¿Z¤ ¶WS™¼©dÊÓ™¼û–{q[=ÙÕ5Í º”KµÜÍLûA¹Ú/¶Ýît×}Òùu*€ =¿¦U±÷ÏÀzp‰”ð�¶Mý·¡Û¡PèÍÎÕ›¾_B¶VíN¦=�É«6UÁÐÇm…nBcãgL½Œöšc‚(¶""±èr°Í3…y,i)ò�Ëijý`"Õ’¡Hä’Á®9ñeò~–’ëŽv¢nvé‹EŸ ·‰uvµgJ;õõþT²ëFSd1’ `� `C"íGa"L%Ê®jª¨¨è(–ÆK_P3¤žwèwA™¼‹ª›-j©vop4»Ù2ã»wÞ»wïÞ�-�Úm%|52°Í5…¹<µ­oÑ[ÅÝýÅæ’ëBUl~áÐ^žÏä�Fø°Çžuò»»ºØì�ØÿoĬϹöêÍw˜%rö€£°àNèlÛt©ŠGMã¥xyÕÆç|wòÿû2ySlfeYÁ’–{xuû~l½K>Ò—éóìß´Š)UDÂXBÜ‚? ÏÞT°?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~€�‚ƒ„…†‡ˆ‰Š‹Œ�Ž��‘’“”•–—˜™š›œ�žŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþ)QÏXbKGDÿ¥òÅêIDATíÁ œ•UÁðçÎ ƒÊ*ƒŠŠ¨,ù)îkê€d¥Žb"-"¹“[¢‘"QZ.ô‰Kn˜¦¢¤‰Ÿ¹` Šˆà‡Ä¾ ³Þç"wfî}ïyß÷€ç\žÿ""""""""""""""""""""""""""""""""""""""""""""""""""""""""""9coˆØ´ÿs?†ˆEƒ×³#D¬ivù!D¬i5‹äTˆØR:››\ KvŸÏ/õ…ˆ»ÌæfûAÄŠÂç¸Y]1D¬˜Ì¯,‚ˆøś±¡ÇnñOˆXP2—_û;D,Íz�B$¾}7²Þ‰ïqn5 "±•1ňÄöSL�H\$™âˆÄuS= ‘˜vÞÀT¯A$¦r6°"Y´A° l¨Då=ˆ`ﳡ> tv²%‚´H²¡ßB$Hþ<‡ ÝÙÈ» 2”¼AN`c½!’YÑ'ä4éËÆî†Hf’\–@€ÙXå^É$7é�ÝØÄ$ˆd2˜_ºšW³±dDÒK¼Ë/=� ¯²‰ÏÚ@$­ܬº5ŒdS�% ’Î+üÊ Ø­šM] ‘4â ÈÃlªò@ˆ45�[¬.B€ƒëØÔ;Åi¬ÝF~í$¹—iŒ€Hc¿d½¿ Héj6µaOˆ4”÷)ëmh… ƒ™Æ8ˆ4TÆ— Ðlª¢" LfŠ÷Òj›º "©vZÇTG#зֳ‰·!’êÇl`2‚�ͦºC$Åól º3‚ý�M\‘­ÚÖ°¡¿ Xþt6ö'ˆlõ6RÛÁÚ~ÄFfBd«'ØØdÑ} z"õZldcu=�ÅiI6ð©÷6õbYÜÊfA¤ÞÍLc²(~‹©&B¤Þ[Lcy{dѽŠ)®„È×ÚÔ1�û�ÍX¦(ƒÈ×ú1½Èb§Å¬·¢"_»Žé­ìŒ,®`½» RïoÌàíæÖj¿vDê}ÆLîAâÏ@¤^I’]†`}ø•äA©×“™%ÏE ‚¥Üì�Ùj ÔžŽ@æ—þÝ "[] "ÈÜduwˆ¤ø5ÕC€6µäÚ#!’ê� –¼Þæšc!ÒÀýÌfJ 2ÿ~ˆ44•Y½Ý™ô,�H#S™Ýò“!bl* $o)†ˆ¡{hdN/ˆ˜K3.χˆ‰+iêµ^1ð}«]‘¬z0„ÅC ’MaØÑ"Y¼ÄPêîë‘@£ÒÚ‘% pC[<,"å}ÎðfŸ‘Œ~Ã(ž:"t®c5ãÛC$½ÍúQÍ!’NÏZFôÙÙ ˆ¤q#{ãxˆ4µó"F÷|ˆ41�1TÝÚ"�ÝÂ8V^] ‘† f0–ùei¨ÍÇŒçÉ= ÒÀ¡•Œgåyi`(ãz´5DR≠‘¥ËWÍpˆ¤8“ñÝž‘­f|�•@¤^ûåŒïå©w1-˜Ñ ²ƒhtùð«¯> æÐ‚Ç !¹¯×/_ÌÍ®G�>´á/�×û¶…¬w=A.„ä°ÏeªnÔ½ŽT ÉUmG¯`•ö mXÜ’“Z\»š�¼ƒ,z%iÃDH.:ãs6ñ²™F+úBrN§éLã^dsp’6|Ò’c†¬e:7 «giÅHNÙe*Ó»Y�J+V¶‚ä�}ç2ƒ�ȪàsZ1’;ÊV2“#‘ÝM´b]+H®¸‘ˆìö©£Ã!9âÜZfÖþN+æ% 9aH’ºÀÀÚq$ ¨a�N0ЪŠVL€ä€C+h˜x†V,/€x¯tƒ•ÂÄ¥´ã$ˆïò_f{ÁDwÚ1â»_2›`d­˜ ñ\¯Jfs8Œ²z�–¬ƒøê"š[ÚY´¬ %_]ÅBÃhKÄWW2Œa”?—¶Ô@|uÃØx2‚ ¥5_�ÏP*Ê�YëÏiÍ*ˆ¯ÊNåpd4•ö,…øêD†õP;¤w--ZñÕ¾ mÕ•EHãÚôÄW…5 oÁà"4Rx;­zâ­Å’Q»!ÕqïЮo=Ìhj^yX>6+=÷UÚ6 â­k݆·§?ôÐÌϸ L€xëD:é·o¯§‹.‚øk:]4â¯átÑþu£ƒÖçA<ö)Ý3 â³ÛéžÛ >;„î9âµ9tM²=Äk#èš¹¿íUGÇŒ‡xn&óCˆçÊ阎°wÙàËÆŒ;öWCŽÛ+â¦ÂÅtÊÇÈ`§~cg­aŠÕÏ\Ñ⢑tÊD¤³ÿÕ³j˜Æ+ƒ !Î)­¤KÎE-/xƒ}4$qÍdºd4R:j5½Ò â˜ÞtÈ4´ß½•̦b(Ä13èŽÇ‘ªôžZ¨:▓鎱UáðÕ41«Ä1‰ÙtÆ™¨×wM¬¾ âœÒG`‹¶“hä¥= *ø”®Ø_9ë?4‘SqÒ¥tEK|©ã“4²üˆ£Z,§#:(º| �ÌÞ â¬èˆqùÍΞO3Ïî qWû :bm M(„¸ìNúfTâ´}jè—_B\÷ ½2â¼Cè“k!x�þ¸âƒ~ôÆ/$> 'žÊ‡øá úá�O´ÝH|\ ñÆz`ãAKüâ“tÞˆW~G×½SñÊát\E7ˆ_ŸÒm—C|ó:íÕ|ˆoÊè² ] Þ)©¢Ã.‡xèUûb⛕ܞÞ+€xè�4w zžÿbn/ý >:�æ^Ãfû]ül%·ƒ§!^:Ž!�-v>mj·±ên—t�¡}Â$lµË�ž«ã¶4â”7O†™b†°$�T{ŽZÈm¦j/ˆKÊ8¯fjB/4”?ðÜFî†8åYr ̬c?@½ï¯å6�ìqÉ�$k��‘J†ð3¤qÀ´$­{â”qÜäãÖ0PÌ0®AZ‡¿HÛúC\Òl%¿4=ÙudÃ�Áàe´jiÄ%§ñ+7"»F?dÒ~*mºâ”ø•ä`duC¨i‰Ì¾·”öqI³µÜ¢º/²™Êf"Èž¯Ó–eù—ôa½µ‡"Xb)C8�šM¤%“!NÍ­VŠ@Ç2„·ò‘Å%µ´â<ˆS^aŠU‡!ÈŸi®ö(dU^MzA\RRÅTkÊ�Yëµ47¾WÉøÖæC\rªþ12º�æʃ‰“+Û §Œd#ÉÑùHo·546£f¾[øÆ@œ2™M¼Ðiý•ÆžlS?c\ƒ!Ny�M}ÑiüˆÆ¦ÂÜÆtÄ)«™ÎÐØ±45>!$¦1žv—”2½U—• �>ki¨î*„Óê#Ʊ ┣™ÉF´F½’ѵ4Tq:Â:¤’1¼qÊfV5}h§|lÒíºÏijù‘ï2ÆðÄ)ç0XÕ¼×ß^AsŸuGy³Ý NN«æî‰Hºndd?‡8åzÚôFkD4Š‘�qÊïiÑœvˆªd!£:â”ßÓžwCtg3ªÝ!NKkuB ùï3šê<ˆSFÓ–�‡ –³ÍÇ·\O[~„xò0’— nAK@\#Édˆ[.¤KÚ"®ŽIFq#Ä-? g!¾1г n9‚VÌJ ¾ëÅ�·t¢Ç‚ƒAmsˆ[Š“´à°!Ãûâš%´ ?¬xšá=qÍ Æ÷i>¬¸†á�‚¸ævÆ÷+ØqÃëqÍ0Æ×v´ehµ;C\s$c›[1¬· ÎÙ¥–qÝ[žbXã îy‹q�[ncXgBÜsãÚ¶üœau„¸ç4Æ´ÖœÊ�Þ…8h×$ã¹ÖÌ�n†¸hã¹ Öt`H߆¸h ãù¬)a8Ë .:œñ|öÔ0”{!NJ,b,=aÏJ†r ÄMw2–RØó)ÃX] qS_ÆÒö|Ä0î…8*o!ãh{>gGC\õÆQ {–3„WuI2†Rسž!Œ„¸ëÆÐöTÓ\ÝÞwý„1kÚ2„ç k¶”ѕÚCBˆË®gt×Ášrš›ŸqÙ®Œl*¬¹Šæ.„¸í.Fö ¬Oc+[@ÜÖ¥–‘u„-³iì·×M`dCaI›:šªÙâº}ªÕÓ°ä › qßxFU½;ìxЦj»BÜ·G£ +:ÔÐÔ$ˆÆ0ª%%°áfšªÙâƒ�1ª«aA隺 â‡AŒj}gÄ7‘¦Öu€xb&£z!�¸NLÒÔu_ôªfT× ¦‹hjq ˆ7n`TuýKÑ,ñGѿՆCÁƒ4ö<Ä'×0ª eˆ,ÿ¯4VÙâ•ÑŒ¬z"j9�æn€ø¥è5F7¾Qt�KsïC<Ói£{ÿP„–¸`ÍÕ ñΩIFW;¾-Âéõ"øâ¡;ÇŠ;ÃÜžãkÆ›Eý“±¬¸±#Ìt»»Š¡¬Ùâ¥]?f<5Ó~Ð Ù´øáÌ$C:⩞kךû·Gf»�óHCñVÿZÆW÷î½çö.AcÅÿ3ôî9Œâ_Í þ–¤u½<íÎ__<¨|“a—Þ4ñ¹OêÑâÝ!>N×TñÛXº%9â¹Ä�tÊ•ï%~O‡ÜÉ£èŒÿ…ä†IºaR’#ÎØHL*€äŒ£–ñ›7.É!Ýçó›v$·´|Œß¨š !¹&1¼šßœ5ý!9èØOøM™×’“v™ÄoÆ#­ ¹êô/¸ýU^Éa­ÿ”ävöÞA�ÜvünOµc›Ar]ÁE˹ÝÌ9 ²#h}Ënk¯(„ì Úß¼žÛ\ròn�H»Q«¹m=dÓvô2n;/Ù•?Ÿä6ñÊÈŽê€ÛWѶõ÷ô„ìÈšŸñH-š{IKȯù€ûÖÓŠw‘ÍJN7Ÿ1-¾³O!DRì{þ_—0¢ê—Fš€HS]Ͻ{v ÃùÏS×÷Û "™5?ü§c›WM‹fÞzVgˆ)ìúýá·Lyyþ*6U±ð�é÷üâÔo•@$‚D›Î½Ëʾ[^~Î�òò“˾Ý{ïñÓ¬�ÿ¨õäPñIEND®B`‚python-msgspec-0.22.0/docs/_static/litestar.png000066400000000000000000001122721525673062400215050ustar00rootroot00000000000000‰PNG  IHDRôôËÖߊáiCCPsRGB•c``<ÍL ¹y%EAîN ‘Q H 1¹¸€7`d`øv D20\Ö ,aåÇ£à,Z¤?±H:˜ÍÈb'AØ vyIA �­b'�Ø@3ð…9Ù>@¶B:; ‰�’Zœ dçÙñ¿åÏg`°øÂÀÀ<!–4��a{;ƒÄ„˜ÊBþV†m—bŸýÁþe;T’ZQñÓwd(H,JK3ƒ4-��áÓrÞHá \Ñw€k10 I 'BrØ6„£G³ pHYs.#.#x¥?vEiTXtXML:com.adobe.xmpUTF-8XML:com.adobe.xmp8�¥TÍn›@¾û)VêaOx1†Ø rœFm•ô�Xªz\ve½K—¥&~µúH}….`ùP)'˜™o¾™Ùù‰¯›’²g0(ƒm!ü÷õFOð�àÁ}(×°+¾5<¿oØñ™…_§“¸‰š}¹CQ³²ŠšS®2ˆì«&Ø‚4Ï£ÇÛ»ÄJ ÞSF„‡éa>UzKfa×#žçX„S½HCGVŸ,Ãu·P1]”¦Pµ2ÍTmŒ'èD½2FÙÀ.«)í4uë2ejO(¯Èlê¶i!÷øhÅ«Vìƒ<Á¯Nè%Qt‘Jª+ؼ”�àG¨T­à5�¬5P<õ\oãÎcòÎtîð¹1_yÊýÐsó…ï,³¥çøþræd>ÎUΘ·p / ¢Þåœæ.³ªÀ ¼« œù³E,ÝÁ¡3žã7ªf»¶”Ô`oº¾rÒ—Þ? ½ÊàÑ?Yoµåÿ[ÅÙЦ²Ö¢Î؃4m“f§&q™ÂxkÑJ˜óYÊHP¹MpãpÈi- Nï •¡Ýh*y!·ÈA÷j«ìçFÔ€¬ý!ÔáB½§1Eÿ@µåhæÛ©lW¤›Gk°¥ÎO¥–mäÚì”N¿Q¦2´Vy“‘áCyØe½œGCËÑ^XX?´Jo”éšÊß4&ïÕSéUvÝÛßá  IDATxœìÝux×úðïÛÝ$‚ Aƒ»¯ u÷R…*-moÛÛÞÞÞß½½R¡-u£ÔÝqJ)PÜÝÝ]"»;v~ i!Dvwf³»³ïçyú@-™ ³ç�sÎ{Þ—åävá „BHBb}„B±�:!„âÐ !„ €N!„¸tB!Ä( B!.@�Bq è„Bˆ P@'„B\€:!„âÐ !„ €N!„¸tB!Ä( B!.@�Bq è„Bˆ P@'„B\€:!„âÐ !„ €N!„¸tB!Ä( B!.@�Bq è„Bˆ P@'„B\€:!„âÐ !„ €N!„¸tB!Ä( B!.@�Bq è„Bˆ P@'„B\€:!„âÐ !„ €N!„¸tB!Ä( B!.@�Bq è„Bˆ P@'„B\€:!„âÐ !„ €N!„¸tB!Ä( B!.@�Bq è„Bˆ P@'„B\€:!„âÐ !„ €N!„¸tB!ĤX_!„„K`@f†UjTc¨U�!³ Cµ4†j©ª¥ÕRR¼ ¢€?þ’D�šÁ¡€nš9 ýàÈIGó9ŽGò9Ÿ0qø$Ç¡A-Ö?9!e£€N‰KŒ) §–€œZÕÐèÔ¯µ3DÑ ìŒŒ±p¿zHÿç`rÀ4�Ã'9ö6±óÇŽ&¶í7±e¿‰CÇ9 3ÌK Äa,'· �õEB’› é> Y=-ê hQ_@³ºÔ áëÊw¬ÀÄæ½&Öï2±j»�5ÛMÉçÐôX_I&Ð !•N€Œ4†Ö9:5Ñ®±ˆ¦u(rüïPpαû0Ǫí–n2°t³�½G)À“袀N©È­- W+紒д®¯âŽ^ÃäØq€cÉ&¿¯1°r›�“E±¾*â6Ð !QãS€¶�Dôo/¢[s u³XB,¡GçÇ 8–o10s¥�E› 8FÃ0±�:!ÄQŠ´i$àÜÎi%¡v&ƒvÒZò(ðs¬Ûe`ò"3Wé8Vë+"‰Š:!Ä9µw‘qA' u«3I>�ÄÉ"Ž9ktLX¨cÑFºë+"‰„:!$b>0°½„‹ºIhÛHtMR[¬™&Ǿ£éøqž†}Gi˜&£€N [�ª Wõ–qY/ i,‚sà$œsh0o­�Og¨XºÙ§›”�:!$$ŒÍê ¸®ŸŒó;IðÐl¼Ò-ßb`Ü4óÖÑr<9tBH¹´Ê0ì\½[‹E ä±Ä9Ǧ=&¾˜©á—e: ±¾"/( BJ%0 }c·œ« {ž‰yÜÙ}ØÄÇ¿¨˜¸HGQ0ÖWCb�:!ä,-¸k°‚-)�'‚mû ¼7Ùš±ÓR|ò¢€NùC½,†;)´Gž€Lαj›‰×bÉ&꓌( B�æ†�¯àª>2Ҽș¦sü¶RÇãUì‚ûÑ|Ï}­bú2ý�-âÐ IŠ\ß_ÆmÄ~VnrŽÇ8æ­5ðÛJ«¶»·7¸(¹Ùzä‰èÝZB^}>OŒï¿É1a¡ŽW~Rg7—¡€NˆËÕ©Îð×k<èž»½òâ½Ü9ktüºBÇší&üjL.%f€:Y ½[I8¿£„¼†”ÎÜw4ñß/ƒX°!�—CÈ( âbýÚŠxìjjVbòýOrü¾ZÇÄE:Vl5’.ˆ—E¬½÷ó;ÉÔÙj7‹—­ Æñé¯Þ›¬"¨Uú·'£€Nˆ É"pïÅ ®í+Wúþmq­ñæj˜¶LÇÑüJýö ǧÝóD\ÖKF·æ•_™�sŽ%› <óI�Ú´&8 脸LÕTàß·zÑ­yå.±›œcþ:ŸÍаhƒ�Š•……1 ~Ãe½d\ÚSFzJåöÃ'L<ý-Á'2 脸H³ºž¿Ã‹º•X$F38f¯Ò1vª†u;)Š;!=¸ª·ŒkúÊȬRy–ºÁñÊ*>Ÿ¡�Câ¡€Nˆ 0ƒ:KxâZO¥e±5ŽßVè7MÃÆ=È£!Õ \ÚSÆuýdÔΨœÀÎ9ÇÏ t<÷uþ8=ÿOJG��'‰À­ç˸c�R)û¯šÎ1{µ�w'©È+Iª¸ü7 �‘•^9�}ÙO� `ÿ1 ‰‚:! ,Õ üå*†t• Dy�7LŽ¥› ¼3QÅÒ͉ÈTKc8šŸ˜Ã^µTàÆ� ®ê-#Íý ¾ë�‰Gß `½¸% è„$¨Ì* ÿ¹ÍƒÎM¥¨¯mû ¼þ“ŠY«  <¶·l  [ LMì3Z k2Œ¸PÁ€vRÔWe7ñÄØ–oMà?ø$!V˨ûL¬/‚žU^áE»Üès¿Êññ/þïÓ 6ìá ßÜãâî†v•ðõl=Ö—bˉB`ÆrëvšhVO@f•èÕHõ2ôo+aË>;%øàrÐ I0Ù™ ¯ßçEӺѫÇÎ9Çò­ĤE:ÔÄŽ¸÷bš×0��Ç;8q;qL\dýá´j @ŒÒlÝ£0ôo'áÀ1NËïqŒ:! $§Û÷ûP¿†µÄ¨¢ÇKß«xþ<è�.³ pÿÅ(ƒfpü¾Æç­5X¸ÁÀ ZçDo¶.‰ }Úˆ8z’cÝ. êñˆ:! "7›á�û|¨��`Î9Ç¢�î{#€ë ×uãêÕJÄ ÎcÈÎdøæw-¡»º•tð8ÇOótH"Ъ¡QpþCÏV"Žæsª9‡( ’rj1¼z�µ3¢3û ¨ïLRñŸ/T×v>»q ‚õ­m ¯lÜmbë~w½µ¦5[_¼É@‡Æ"ª¦F'¨÷Èq¬€‚z¼¡€N\¡VCa ÖW j0Œ¹Û‡ºYÑ æ»™x|l ŸôVYF]îA•SåTcð* “»$9 „ýÇ8¦,ÖP³CãlçWt�¡{ ‡Or¬§å÷¸›L„8H–€.Q G/G,fêe1¼4܇z5œÿ¨šœã·•:îxÉŸ°çÊCդހšÕÎ j�šˆÈÎŒmoòh:^üýã ^ü.ˆ¢€óoj²Äð—«<ÔÙ…¼E�$¼ÜÚú·“Ш¶»çêé /ÜéEN~® ÆñÆÏ*{?€Ã']:-?M×gw1Kñ2 hý3ü±d˜À¿éxàM?öqþ¥Í#3 " :öe†"�š•¿S§º€NM]°Wà«Y:þþ±³ðŒ1th"âï7x’"7!ÞÐ-' +;“¡Eý3á– dg$Þ²{Ýê ¿Ñ�ìܵ&ÇØ)*F«&Mò[I j†¶ 3¤kb¯ìDjÊ�� àd‘³3õó:J¸õ|ÙѯI*F�$¬~m¥³Ê[J"Cß[vOõÿ¸Ù‹ZV�3LŽ·'¨xk¢æº®áèÖ\ ©jÏ< Yé‰÷"è„9k ŒzÇ�cÎkcŒáö ôm“\+±F�$¬²Ç´‘(C³À€û/UС±sçïLT1vŠæÚÊo¡`z”q\­¤4Ÿ»Ž=†kÙfy/€|¿sŒ"3þEwhÿ&«ª€'¯õÐÒ{Q@' g@ûò+Ö2_4ʧڕâþz�sûæGNšøëÉY®<=ò*~FÊ’L¥`ËÃ9ðÖÓ—ëŽõ>mD\@÷7jèÎ’JÓ.WÀ%Ýe[ T³úX‡¢s3ÿw³vÒ½5øiž†ۜ٘>DA£fŽ¥ ¨Ï|Ķ$«ÍŠ6ök´—ðâ·AÑŠ4ø×gAÔÎÐ:ŒeaŒá¡Ë,ÙdàÐ zn�F�Tš•ÛLd¥ëxô*jT�þâ�GfÚ5ò$§C'LüïË Vnw&˜wh,8V§ÝäV?ó¹k“´\9¼ Ð1Ä—¾ÒTñYü&/¦„È÷O}À{ú�åÀç6«ª€/SðÔ‡A:�á0Zr'•†s`úr·¾èÇüõñ=XÎ[§cØ ~ÌXi82èøàÑ«œ+í:y±ŽÏs¾ ¦th,"Åù}fŒáÂ$-[–]‡8þï3çš¹œÛA¢*rQ@�Tº}G9|3€7Æ¡jñõŠÔ8Æüăo°ÿ˜s×vÅ92šÕuæã¶i��ÿ|Lê’®åébu¸òth"";“Ò·N7g��±Sœéð#‰ ÷_ìAª×‘/GN¡€NbB3€÷'k¸û5?vŠ�ƒÓ;š1Æ�ÑmfR³*ðóG–Ú �� Ðþn9z¶²?»öÈVƒr¦÷§h˜¿Î™Õµ†µ®ëGçþ�D�ÄÔò-&nz¾“i0c4å4MŽñ 4Üô|V:”üvº»†ÊÈp € ç/}ÄvJ‚+S½,†ú5ìßkÆw¦3é%&ðôÇ8fÿsÂÃ�Ô¡ tsùEÀß> â™O‚8QX¹Áêx�•)þÌÇAø�ÿúmr[‰y§ûu…�ŸæÇwîA¬õÈ ­»Z(r³´jHCdIGNÿø4Õ�ýô*) ÷\¤À¡’ I�žV8€ uÜ6ºË·Ž�{-óûqŽe› Ü6ºêQid" VE8E²?Zg¿f­ †.ÍèxUiŠ‚Àÿ¾ " ÚÑìØDDïÖtŸí¢€NâÖ¼uÖ™õ�YŸ¿NÇm£ý˜¿>úÅXÎí ¡y}ûÔ‘“&Æü Â¤¥ö uÏ!8œÅÆu`+ÏÊm&¾™mÿ͘1†»†Ð,Ý.º}$®>Éqä¤3KÍN~­òH"pç`Åö×áœãÝIª£çáÝŠÁJˆ‹†®ÍEÔ¨JY[e;Uud%­y=;Ð,Ý è$®¥z�n-œù�wk!VÊ~è�.Ö´Vl5ñý\ZjE½,†5£3œUIaè×–MYNoŒW9vzç`E¥ˆÑ­#q­Cc™Uœ™e¥3´« �º]’ ;Ï~Ýàxùû £nܬcSžWÆ9çØ°;¼;¸‹LËÁ嘼XÇâMöÖFµœ×�NDŠQ×Bi•ªÊh©:°½ˆÌΧ-ձʡ¦0É gK1äç„s`ô·áÕlâ…o‚Ø}8´%êh-»_ÝG¶]vôD!ÇÇÓ©-j8zäIa�÷Ÿ»ÖšE®Üfbg……êe h—KCfy�àøf–ýç·CcÍêѽÝ1—DèÛ¦üÀË9ÇôeníÇç¿Y¿N_Vñ¬«oÉñ§ÜÚ ]¨ ÷åLµRŽÖ¹…ÀÂ;¡é 7XÉ[AÍ*Ú*Æ€¡ÝhÙ½"Ÿý¦ád‘½gX‘.ïEË!ᢀNâR›FjV+ûñô9žû:ˆ'>âð©xø$Çñü7åW¯ª�! ¥ÃM7.é!ë؛�Í7ñ•³›dR+ƒ¡I�Ðÿ,Wï0p²èÏ¿ŸºX +‘«[ )žp®0ù9ÉñíïöŸãs;ÈȬâÀ% è$. hWúÛ9ç[÷¸m´_ÍÒÏjVb˜À—3­ŠpÛö—Þä…1` ƒËîi>gzgÿ0WDZ.(‰tl"†õ"5oí™G«¶îçX»3ôÓi>†~miæX‘¯gi(ðÛ›¥WM-{ ¥£€Nâc¥ïs&Ç÷stÜü¼÷”?oØmâ¦çüøqž£”‚ÚIŽ%ÝôÌ“P+ÃÞGédw¤„f²éÆ)Î9æ–è‘$Ç]Ô�‚LE瘰ÐÞóÌÃ…Ýéü8èV‘¸Óº¡€ZÕÎ ·GóM<5.€„?Ä]~ø×gA<ýaGóÏ|ÈÎdÈk`ÿñgÌ™~Ò"�º©…ÉçÚ…Ñ]íÀqŽ-ûÏ~œµÊ@¾?ôïÛ±‰ˆìLÊÁ®È׳5Û�[òê ”ºS$îôo'ýÑdƒsŽÅ­%ô©K�°û–s“—è¸}´K6éÌÄ�¡¿Ëyu«3tjj/. Òì<�³Ï~ñ+Ï’MÔRnó¡&Ê…B.èD³ôŠlßÏ1g�½êqÖùº×¡¢€NâŠÀðÇePãxo²†Þ `×!{oú;qÜÿFc§hP5ëkõk+Ânºí%xd{_dþ:[÷Óì<\=òB¯œ½~º‰ 5˜!.»3 î"Q5³ p_ÍRKÝò G¿¶|ö{% è$®4¯/ nÃÞ#&|+€·&8×·<¨YM$z;€}GM4¨) iÒ%‰p¾Íd8Ãä”Ù�YçÏCPy¹µÆn4p(Œ-�œZZG©@‘›,ßjbÃn{%ŒëTgh›K•ãBAO$‰+}Ûˆ˜µJǰüa-ƒ†cþz·¼àÇï«uôiù@Ѩ6Cs›û{[÷™X²™:°„«Zšµ¿ª�»ÍrÏ÷ûƒÀ¯aœI—D†A´\!ݾŸc?9Žîuh( “¸²d“�ÇÇq$?ºKÐGNr<66ˆå["¦Úÿ¹×©I‹tê¨�.ÍD(aluÌ_¯£¢•ßI‹uèFgÒÛÑ™ôPÌX¡ãD¡½Yz¯–"-»‡€:‰+‹6šg�-�ÝoŠì› ¶“ê*ÇÔ%Ôï<á,·sÎ1o]ÅoMkw˜ØVJ|YjTeaU©KVÇ €Ù«í½µVOÐ>Œ ÉŠ:!hP“¡i{Ì ö£d¸p Ð=Œn\ŽslÞ[q æ&,ÔC>“ÎÃЮT 6ê0m&ÇE»õ±P@'$}ÚH¶2ä9ç˜L³óˆ4«ËÂê·r«�¢`hÿí”%ám�ti&†ut.‘1X‰ ²ˆ°»Î-Ýbà€Í—×^-E*2Szå!$vû´�9«) G¢gËð†­’ÕáÊsð¸u&½W«Ð¾Gš�¡_;_ÎŒýŸ¥ XW:õ«(žúU`À#^…Á«X¿úNýê-ñÏ­_¯|æë‘ÉZÉ7MÅ´¥¡ßWM¦/×qãÀÈ7ÂkeÈͰ©‚*‘ÉŒ:!aJõZ½Ú혻FGAÀ¡ J2á¼LùƒKÃÇŠÙ«t\yNä'¼ Ъ¡€¥›iÙ½4Ð Cf«ì§¿ÛlX*@–pf <8}$AýlÿÜÛ--+¢UÛÌú~Œ�úëÔï�Ø-%/ ¯×ùéVï0±ã GN­ä èœsì?Æñä¸Vlu.x.Þd  ò°zØŸŽ1†NMD èe €NHZ5´–ü"ŹsËíŠÜ~�Œv�EkV,iÞ3ƒ®˜ÄD–o1#^"Öt`ê w I¾Rpœ[™þû(Xn¹ÜHT`ùÝÃ( TR‡&"Zs/ �ê#$ mrìíŸ:Á±ã€3³ UÆNÕ°l³�¦u4¯'¢n–€êéR½,©ƒ¹UÎ^âáä%:4=¹ ÿǧ¿jùfÀñ`^¬¼&9¡h^O„LEãJE��0´±Ùakùªƒ îA x{¢†ácüX½Ý¹Ê™Ûi°h£½À±ë ÇŠ­É“¼x²ˆãïñÒ÷*´(þØKlô4Ш6…®ÒÐ]!$D^hl£Ý*`vR–5;L ãÇË?¨(ðSPßyÐÄ®CöîƒÉ�É‹“ãxá–}î~Õ�I•ðónÚcâdQä6’ÈÐ"ŒN{É„î !!ª[�!=%òelÎ9Vo�^2O@>™®á¶Ñ~,Ý”�¨,ó¨WžÙ§Î¤»çÓ—kþJëwUN¢Y@6í±÷çC½ttW QN-’�½»c»GÐܲÏĽ¯ðò÷AÜŒÊÂ9Ç\›ûçş䘿Þ�/GªÎñÖO~ı‚Ê{N8Vm³÷9hZ—6ÑKC��5«g/!nÛ~E•TîUÕ��OÍÖíô|OD…+ÃÝ)ÃèÀæ“sTŽãŽ™ØqÐÄÆÝŠ‚Î\DZŽÇÞ à½ÉZT÷Ë˲f‡½ošS‹Ù®ÖèFtK Q›ûçëw™¨ìùòæ½&FŒñãºþ2î¢ÀáùßD²d“³‰‡‹7Ø{„#»ú©À­%AhÕÞìÜV IDATêm_ü«_ÁS¿?ýßigþ½_=óÿ=ýµ‡Ï¹õý>XÁMçÚ{9çØ°ÛÄãc¶s ìØ°Ç„É9„_�S½ µ3vL¾¨òP@'$ @ƒöÓPzrGƒfý¢aÎO^çEÛFBBW@㜃Ÿ væ©àZü÷œ³îbP�Û_òC`ðÊ,=šY…á™=a5Œ)�É9&/ÒñìAT‡..BGOr<ÎQ;ºî™!;SÀ΃ɵúT è„„ =ÈH‹üÿçœÇ¼KÔ–}w½âÇMeÜ~�Ÿ':A�sÓ ˜&Îú½f”=3-ù÷~­ÄìW‚§f°APµS¿×þü}4–��ˆÍL°UCÿ¼Å‹†5í½LTŽ×~RñÅL ñp²Ñ¯{sÔΈük4¨Á°`½s×äЉ£PéËÊ•!£ Cš/òXàö‹}¹JÝ>˜ªaÎO\ëA›çfë«·;EÅÑU³’®Tgý¾¼6£ÄÂpaW �\é±õÜÀ¾#&žù4€ÅãëÆo?`¢“�¾õm®˜¹Ý⨞-E¤§Äú*œW;C€,E>°É7QG Y6î±öÖ߯:– ß:GÄ�ƒ­6¢v›Ø¶ŸcÏaŽC'8Nþ óPxe`Ôå þvƒ½`Î9Çâ�:î|ÅwÁ°’Dí¨Gý,tGˆ£.î!¡K3÷)Éδ7K:pŒÇ$›¸Ã]ƒ¼ÿ��Êu–§»ÞƒG¯ôØ:uÀ9Çœ5:nyÁ�u•TÂÕ.È·ÑwÀ«©^/ÈèF‘ž‚3öÎݶì^-Í^@?£cO‘Ð «ƒÛ­/Z³u»{ëŒ1´l âƒQ> *Ó2é)õ²ÞéÃ%=d6öËuƒcì ½ÀñJ,ájW@ƒí&-vO¸ tâˆö¹"2«üùáêÝZrMÏbE²*SEÊ49Žæ'Î@[lý.w¼äÇ{“5ø(9ªÈ w ö`ì(Z&ùÞzÏ<cGùЪ¡½ɱO|ÀãÕ„;AÀ9l÷\?}Ì!ЉCœZn/–žtvI¶»G†­œ¿ [{…±Ѐ·&¨ñªk˜­@‹ú"ÞéÈ¡ |.2�ˆ0ì</÷¢zzäÃ/çvþŠ¿.�³ãa°ÛÉ®Z*ôÓQ@'¶¥y�n-Î ÞŒ1 l®HV©ÉH©G@K¼úéVo7q×Ë~¼?Es$Þ«0Ü1HÆ;#}hÛ(9†¡ôàŸ·xpßÅ 5 8瘲DLjWýز/±Ÿ+»=ÍÆÊ™%Ç'‰DU›F"jT=ûƒuNk ² ¶Ò%‘Ùú9Š+¤%:¿ ¼9^ň1~lØåL&|Ë"޸χ{.R�ââÙzãl†·ðáüŽ’­,vUãxåOÄÉ"/0Fìþ )”w èĶíJo+Z½ CûÜÄÄd ¶Z5j:íþk«¶›¸ýe?ÆNQ¡:°òàó0Üv¾Œ÷ò¡uNâ?/% l/âí‘>4·Ù~÷ð ½ÀÇÓµ„Û//‹Ýv°²H3ôÓ¹ïÓC*•W±Î�—Fú·Kü)ºG†­,䀯]3ó�×V1|Œ›ö83[oœ-Ø®ÈOD¸ûBÏó"#ÍÞP»r«�ÛFû1]âî——Æn²¥èŽ]=ÇP@'¶´n(”[‚Ñ ÙîvJp€á®1ø +·™ö¢ŸþªÂ´‘0§éÿý2ˆiKÝq³ª¥£‡{qû²­&çønކ{^ócÏ‘ÄÞ//�Ý6®6?𮓸Ó'S%³ÛKª•Áк‘€e›wŠjwÐpÛì¼$Er³.'5Žg?bÂBwìKäÕðßÛ½¨—eo¾Täxé» ¾Ÿ£»²ƒ!ÛÅ‹š’ž�:‰˜,Y3ðòˆCÿ¶–mŽã¢Ò`6 7ôÚ ÿ»Ý‹Ö9‘-ÃøƒV0Ÿ´8ñƒ9cÀЮ»Úƒ›UßöáøÛ‡¬Üæâ‡ö{×Ó ýLô~C"–W_@�ê?B½[K¶’ÊbÍî˜áÖÙUózÞzÀq0/ r<óIÀÁܧ�\¡àéìóùë Ü>Úïú`ºÍ€n#ÇЕx˜%±jy׺Õš×°j{bPvgØ¢ _›»5ñ¯adV‰ì‡Ë/âxêÃ~_“ø{æ5ª2üë:5µ—Å®ŸÍÐðæxÕU§"Êc÷³ï h*tÆr»(2ôm+aÕöÄ\v7M{£†ä²€~i �^å�W‰,x/àxô=?–&p^Åé2«0´ËµÌOqüï« &»`µ"’Í„YŠçgrÙPC*K‹z¡-·ëÝZLØlwÝî =Aî’$xà½6ò`¾ÿ˜‰{^sO0€M{LlØùϳe¯�cüIÌû'Hh†~&š¡'Qu–mdб‰ÖþUN-w QluW*iÅV£Rö5Ýš¥Gz]‘KìÁ'Õ<}£ÛG>ÝyÐÄÈ7ýØy(�oD)LL^¬…�KÀ9ÇŒ:žý<ˆã…Qº¸8g§G˜îy/tô$`˜À’Mž¾Áƒ®Íí- FJn»Àæ§÷«]¤Š5;*çÓ¬V6®'Âõ,Y´Žv´ük­j ÏÝáE«†BDÏç÷˜xø�öuW0/öër÷\È‘bmqÎ9ÆM³öËÝ| ¢"vwŸ ‰-¹'‰ýÇ8î#€7Ç«&p£�=‡MÜóZoO¬¼ò—ºa/W‘°5í[ç§J²Fö"È9Ǽu†�ñ»6˜À�ã‹6†þ�0Æp¢Ð}Ãå³Y‹Ýîv˜ÛP@O"† ¼?EÃ}¯û±ëPb}L“ã—e†½èÇ’M•›­éÜÖK�"3[ÝÚb�1`HW ¯ßë +WâtœsL_®ã/ï�ï‚F"™°P «½ì ÎRÒF©šbïsQpïKb$’üqJNK7›öB¦.ÑlgpW†|?Çóßñׂ8š_ù׫êöJTzû{…•I‘€/UðÌ�¤ù"p “ã“_5<5.Ðá ŒSs×a=Ÿ�ëhY?¹‡àjiöº“99n�ÜOS;^<ùaÿý*ˆü8ýPpαn§•üÕ,=fË“A¶f貤&Hßæ¬t†—†{qã@%â dÝàxå{¯ü Ú®Všª©ÎM'øUà×å¡gªË"Ã�t/Æ!ÐE=‰™&ðíï:†�ñcÝÎø*ða˜_ÍÒ0|ŒëwÅv{À4íõmfŒ¡zzüô69Þ}Їn-"?gÔ8þõyŸÎÐÏêàúþ2.î.;û…4a¡Ö²{ÿ¶’«ûÀ—‡1«Å²Ç ( ŸŽ:Á†Ý&FŒñãË™*Œ8X‚?šo≱A<ÿµŠÂ@¬¯Ær䤽ûR^GºXc ¸¼—„×îõ¡AÍÈ2ÙàX�‰Gß àçùΟ§®Q•áù;¼xèrË·Ä×ËçéVo7±ý@è/ µ3:7uI¡‚0ù =Õ^e= èg¢€NàùoT<>6€c±›/Þ¨ã–ü˜¾<¾:L9iïžÔʈÏ�ZŠxúz¿&òýrØ}ÈÄݯ0g­óÁ¶{ ãö¡OÇ 8ÖÅxŦ<ÀÄ0ºÆ1Æ0¤kr.»û< é6’âª5n‘?Åç(Cb‚së<íMÏù±l³ÖÒ¡]ªÎñö„ î{=€½qØ÷ùà {×”�3ô&u|ð°u—"Þ/çœcõvw¾âǦ=ÎZEî»HÁË#¼¨�i­,ÚhØnèm“ëa­tuo!!+¶dœV-•ÙÚn( røão¬ˆ% èä,ûŽr ãÇ»“4ÛýŠ+Â9ÇîÃ&î}Í�w&iQI¢r¾£ö‚UýñóQc ¸°›„±£|hR'òBCœs« Êk~<îìsÒ¤ŽuþýÖ ÈÒŸ×7ÏáQ€ã�÷ ïLz•†~m“oÙ½AMf«ÈÕñb¶‡ˆšøeH\1Làí‰*xÃ�݇£³Äiš¿®Ðqë Eq_Û{ßnkÅ¢FUG×R½À×xðÌ�[™÷ºÁñÑ/þ:.àhžƒ,7 �1îaZ5<3Èi:Ç Îôª©À³Ã<;ʇ– œ Ã]v€Á]$Wvå+O›/¹n.T©${„H¸m4qûh?–nv6щsŽ·'ªxblG ýÒQqø$·ÕÒ2³Š½ýB'4«+à�‘>\ÞK²53ò«ÿþ"ˆ1?ªŽ.7ªÍ0æ/ºL�¯”’ ÷˜8l39±Xñ½8¯£Œ¼"ÞéÃíÈð8”@?{µŽ…¡_kë j&ײ{ÃZöÂÏž#ñ= ˆ è¤BGò9ô(4‚:|2qJ_Íç¶Îë{d†z5b3`‹pÅ9ÞéC‹úöjùË7ñðÛü8ϹB�kúÊxÿ¡tm^öËÆÂõ†#ÏË�¬{ѤΟ+>ÃÝ*xã~ZÔ³?,ž,f­ ýI"ÃàÎñ{Ïir³íÝçaœ&HÐI…jVchÝÈÙ=>ƶOœìÞ¢ pÈæì°i�Êÿ¸e¥3<;̃ǯöØ^!ؼ×ÀˆWXàà²w£Ú /ßíÅ#W*¨ZÁ¦¹ëì½D(’Õþõÿn.ý^0ÆÐ>WÄ{ùpÇ û³õpKÁžßIJØšÿáòy€ºÕ#9çØq�–ÜK¢€N*Ô3O´Ý©4‹È¬âø—�»3‚¦u+7ñéœV">xØZVŽ´õk±Ù«uŒãÇæ½ÎÌŠ$Ñ*3vT º·� T°jpø„‰�6zŽ×¨Ê0z¸7Ÿ+CËÿ^>È¡ ޼߇&6^ÂVm3Ãj[/‹¡�Ã/ÎñªFUf«J\P³Ÿ¨êFÐI¹€QšI{ gËÄ™’Ø fÍë •’øäS€Ç¯Vðâ]Þˆ«3MޝfªxìýŽ9”ëмžU‘nÔåJÈ«+·Ÿ9nsªc\�¼Ðsch—+bì(†�'CŠ Î4à—¥¡÷ÌeŒáÂn‰óy°£e{[?ù~ŽýÇh†^tR®Ìt†�£3kH´e÷�»M[™î k Hó9xA¥hÛHÀ'�ùpeïŠg¢ñ9žý"ˆç¾VéåžâF^ªàÃG|hÛ(¼=’‚5Œ—ö”ðæý>ÔËŠl¨Kõ2Üw±‚wGúÐ8;üû9u‰ÖÑÏí%ø’ lë{¡gÛ~3îëÄtR®^-ÅR3Ž�Ò¡Iâ,»ï8hÚ l)fk ·<ŠÜz¾Œ·Gú�SËÞ째6Àˆ1~ü0×~Å>ƬjoŸ<–‚›Ï=ó\y(T�‡Ý2×+�]¥à©ë<¶Ÿ_ÆÚæŠøèÑ ;O†ÆûíÖý&Öî}e'ÕË0 ]â¼äFB`8ëHb¸ìl¿¸ô(Jôc(‘,·sÞyí4/Эyb `ûŽrÛí[;6q~µ#7[Àë÷yqïE ”0ƒeIœs,Ýlà¶Ñ~¬#•%+�áÉk¼r· kF6Ül;`†U=°vÃk÷úpUÅÖ‹MI^…áþK|=ò¤�–+­zÞ&þõY›÷q0¦cñF�\é©ð(tl,!#-èXÒU4­Üfb`‡ÈÿÿV Eø<Ö18;:40ê òêGÞítþ Ç›ãU|1S³}Ö»s3\¢ eûׯ9ÇÜöϸº·Œû..½(�ÓR½ ÷_¢ wk Ï}ÄÆrêØ:Á±pƒŽ�B;'‰Ö¶¦:�¸‡ì®R�,âØEGÖJE3ô(éÓF„$F/C¼2 aæ¬éO×pÏk~lÞg}È8&.ÒqÛè¢�Z]VM:%H ÉUÛ ˜6Z̦ùZ5ŒücWÅ<|…‚×ïóÙÎ.¶÷ˆ‰‡ÞöãÓö‚yv&ÃÿÝìÁk÷xѪ¡3×v¬€cý®òŸ¡4/ðÔuŒº¢r‚y1Æ:4ñîƒ>Ürž\nMø u˜!.»3Æ0¸‹Á¥£s·æö>ëkv˜ÐiŽT.}dbo`{k ´{ )!—ÝS<@ϼò_F7ñÈ»ŒùA-uƹýǽ¯û1nª ­œL_Æ'hã…6f×k¶8açÞ­­Ä¬ëúɶ–,‹qnÍï|Ù�E#!½ pó¹2>ù‹CºHa'½•gõv'‹Êþ÷ j0¼~ŸÛègWš�áþ‹­sëeeÂ/Ü`àP lÖÐÆf&x<ªš äÙ¬›¿bkb®xV÷=1q zºµÏé)@—f‰1û<]¯–"¼JÙäœ5:nzÎ�ß×åfATàÕŸT<ôvŽ•4º4Q5ÕÆW0²}ôC'Lüó³nÙ�Í{à èYé ÏÞâÁ wzÑ ¦3KìºÁñÞd #ß D|ž—1 ;ŸüŇ.QP-Í™k;ÝܵeW‡ëÕʪêÖ:ÇÞj€�—bŒ1´o,âÃGRpó¹òYõü*ðëŠðJÁêœ/¹áè‘'ÙʧàœcY«~ÉŠzôj)Á{ª³c,!—Ýv(ýš*ÇKßñà[�°eÌ[gõYŸµJ/5ã7#-zçÝ�¶dSh½â9ç( p|0UÅÕÏᇹ:´0ª— pQw Ÿ?áÃ�í „§;xÜÄý¯ðÖ5â†3Íê xã^/ž¿Ã‹Fµ�Y^/IÕ8—r\M`ÀmÈ}—ÕÓíeK¯Üfàêჩª#­‚}†.±Î­7ª}æ=™´H‡a„þ=ú·KÌÕ½òômcï3^°–ÜIé/Ò$€�ÎÌ8îÞBDª޶™Œ¦нÄr;ç[ö™øÇ'Áˆ�ŒÉçxø�®é+ãÞ‹ÎÜï,.2óÛÊøû^¸ÁÀˆ¡åÿ7A�câBïNVq ‚p‹úº\Aç¦Î}DMÎ1g��~Ä‘�ßÕ¨ÊpÇ —ö´_¸¦"{�pì8pæu¦§»ÞƒííZ7Neô¿ðMA xí'³VëxòZgÛ[i`Œ¡]ck{äí *¾š¥AÕ�µ;LlÝo†\8+�¡{ Ó—Çÿg"ùìq%\K7TP¦ÐV=ÝjðpºÌ*Öìó÷5‰ñ$vk!"í´™�npŒ_ ãåïƒÈãøMiL|þ›†å[ üãFŸÖñªksi>„uÄ'Öì0q¢�£Z)µ¨U�cö*ïLTÿH GFpÛ ®ê-;º�_ÄñÆø ¾ù]‡ÁûXЏâÃΓQ-­röæ¯×qújx³ºþ5̃ÆÙöfyEAk•éû9gÍY¹Õİý¸÷"Wžcÿþ§x¼LAß6"þ÷µŠÍ{ML\¨ã�KC{a`ŒaHWÙ5½ksUlVJ\°> m]„ºÃº5ÏZ&cŒ¡;)azqBÍ7ñâ·*¦,Ña£êéYÖí4qûK~Œ¼Ôƒ‹º[ËÉYU´Ï�ÿôféçwú3°éÇ‚ Þ›¤bå¶ð#¦"ƒ»H>DA­ ç&ç«¶™ø÷l sï°Z›öm+â®! rk;¿G^Î9æ­³žÆ€ó;JxìêÐŽA–gÏaO}(óÏÈ^øFÅï« ³×8¿“ Ó´*«��¢aÑFáæW1›Š¸÷"m90ƒšu¤pÜT~5ÌëbV2ç�ƒ´Ïlwk WaX¾Õ€G†Qp}{3fÎ9æ¯7ð�O‚8t¢â?¤ùë Ü6ºw Qpù9²í |i>k¶Þ§�„}GM4¨Ú*Cš�¡_[_ÌLì™iª×:¥aÇ–½áU LFÐC4m©Ž|?Ç“×y��þ[»Waåî�ø9Þø9ˆoçè1Ý#êØTDª—á½É*ÆNÑ"Nš •É�I‹u¬Ùiàñ«=è‘'§ ìTÙæ­Õ±t³ŽqÓ4,XÙ¾^Ý,†»‡*ØA²0JÚ~ÀijŸ°tsø«yõ ª Gžõ}ò²¬ÞnÀ§0üçV뙰󢣟þªáí‰á5™9QdÍÖg¯6ðèUäÔ²?[�¤ÞÂ�e|=[·]ð'–zµ”PÍæêÊïkÂaN6,'· Ý¢0Ô¨Êð×k=èÝÚ¹ÌÞ » üß§A¬ßûOì]ƒe,ßjbá†Ê«P$ë<ó’M–m‰ý½¨ˆ( ¢A6ÍÜ4@Á5ýdTñ90 “ㇹÆü¨†�‹�S‹áŽA ´—9çnÇ´¥òˆwI+v²ˆã¿_1u©½-£ô`ÄPWœýdÀ’tƒã¦çüåV£‹w¯ŒðâœÖöæ�7?_Dî €Q®í+ã¾Kì5Ã09Ç·³­Á×n)P§(¢>+O„kˆñÔ1´»+¨Y­ô­;6ï50ú[ 7”_ ¤ìL†ÛΗ1¤«\ní�ÊdrÁæýÙ¶ßİɡ@È`•µ}êz�í�p�›¦âÕã|Ùª õ²¾x"ÅV¿�M\óï"WŽ N¢%÷&ðé ˶xv˜Uì#\Ç L<ûy3VÄ×~q<|`âáœ$0 gK÷\¤ Y]çËŠ‚NSññt-¬%åUn>WÆe=exD%á�sŽõ»Läf aÍúísÎ9~[©ãŸ‘_N•¹°¿.€E \÷Ÿ"ˆ£ù¡ý?u«3\ÓWÆ…ÝdÛç¸ËÃ9Çš&ÆüÄ’MÖó- VA‘hâX³ÃÀÓ°£’ÛjæY³õ™«¬së jFo¶Þ§�„ô”`¹Íj≠W÷‘mß�©KÃ+™œÌ( ; m#ÕÓC{h‹‹Ì¬Ü–˜ .¤tMêvžµ qÎ9Vï01æ‡`ÈGÑÕf¸®Ÿ‚ :IHs8›¾¤ÇM¼?YÅÏ t¨§íóÖÊ`h\'z d¦Éñó£¿ ÆtÕkÞ:Ã^,ÂÝZ{ëÑÈ„·Î¤Køi~bD·– Ûm‘ý*Ç´¥‰ñóÆ èf¤>mD¼þ3¨&± ´l àúþ2úµµŸøS–C'L¼;IÅøzHIo-ê ¸q@t¯©X@åønŽU¼æH)+�šŠQ;çr¼úSßÄÉí“EÀÿNÍÖ»ÊQ²lE.ì–�¸®Ÿý›Å ìŽRa+7¢€n“W±2˜KÚ¶ßÀèïT\ÓG>ëüeÚg ذ;F!‘.ÍÜ4PA—æbÔöN5Ý:Sþîd GBèl×¼ž€»†(è™'B‰ò9rÎ9æ¬5ðúOj¹ç£{æEg¹}ÿ1û0²Â9Ñ6��[^(Â=*¸ÌáÙzûÆ"êTgq_1­qÚÙ /œ[Ï|ÿ¤ñ…ºM­R�b IDATsÔ¨úçÖäV§—¿ ¢ `Õü¾¶¯Œ»/Tþ8ãËÀv"ô#0kuåæs´Î F±êüu:Æü¨VøŒ0X™ô7 ´*»9ÙÐ¥,[öxå{óÖ•_¹+Ѩ´Ä]ºYÇ“ã‚8x<~‡úâÙúo+ �]�áò^2.í!!£Jô«•qnµ^ýj¶ŠOÕÂʰîÙÒ^w­Óø9žÿ&ˆñ âÿ¸¤?ðŸ/UÌXaàñk<¨—e/¾~C»\Ëã´<òƒÛ+E…àçü³Ž5 è6´n( #Íjdòþd­ÂiàŸŸ±h£�G®´jf¿?%¾—Î’ cVMó+zÉÔEBF”{Ÿ,âøf¶†OUq¼°ôÿF�¶¹®ì-£Ok©Òʳ8Æ/Ð0nš†a.o ÌêÚgçÛp<ýQkwÆg Õüõnz®÷_âÁÅÝ¥ˆƒž 0 é"cù–8©}š¼Îí`?¬ÌX¡Çõ–J¼¢€nC^£Þ üÑ·9T“ëX½ÝÀÕ}ìUP"ÎñÈVïé+{ËèÞ"úIe•cÒ"c§ªe&8e¥3ôo'â’2š×«¼¦ÕªÌõÁTÛ#\AʨÂТ¾½—!Î9f­2ðìçAÉwÇà^Ü2xæJ�\y&|¿¶"^ùÁšÉÆ“{/Tlç–¨:Çg3h¢ è6”·°½„&u„J97^ÒÉ"ëø×׳5:á|0hQ_@õôðwÎ9¦,ÑñŸ/c[Â5VNÿ=• ÿäõÔɬøþ¥x¬½ôÏ‹ížDN-†›Ïµß€Ç49Þ™HÛ�vP@'®#‹@§¦w±ÊŸ¦z+'ˆ€arÌ[kà­‰*Öí4¡H@û\½[KèÛVDƒš*ïzŠqα÷Ç—³4ü0W‹j2U¸ËíA�ãÍñÖ±¸P;ǹQñ¹õëþ]„‘—Y{ëåÍÖ³²Ý¿š»Ò·¢ÿMÃôå•ÓµªgËЇ•ƒÇMüýãn �¼XAxös3–øËÕåŸ[oVO@ÓºÖÇ(í*¡»å}U�ã�I´wnt’° hZWÀÀöú´‘S+úÓNÇ9GAX´AÇÚ�&jVexür³£[6EA޹ku|3[Ã’Mf¥Í|3Ò€¼Ž«qα|«‰§? `oìÇ£¹§jÂß{‘‚‹»—ž /‰Ö)�õ»*©:;“á>‡zÝOX¨;–�™Ì( “„âS¬V¥ýÛYA¼aÍÊ;Ÿ]’a…~Žîy´�m¬ ¹ï¨u¾ý§ùv®ü@Ù¥™¹‚QÅ4­m/¯ÂO[¦å:Qüû‹?3áK›­h'á�‰*Š*±ÎŒ(£.WÂΕ(M¾Ÿãƒ©ô 8�:‰{™U€v¹"z·–й©•Ù« ~:Id¨�ûë( r,Xoà‡¹–m1bZl¤GK±Ü[Q€ã¥ïƒø~®·µÈãÑœ5Öl/Â=ypI錚ðuª3th,bÎÚÊ;Â6´«„~6»©ûâ7{â¼{\¢ €NâŽ,�³tj*¢Gžˆ– E¤§T~"Y<ãœcç!މ 5LZ¤cïçŽ�EJ�®ÍÊÞOÝ}Øjyºr-­Fâx!ðŸ/‚˜¹JÇ_®ú³ƒc ƒ»H•Ðs³F]áq¤VÂîC&U…sts @Ý,k–Ñ­…ˆMDd¥3GûH»EaÀJ¾¿@Dz-‚q46«[vwµykuüãÓ`TŽÉ%k¶~óö"Üw±5[†sZIÈH âXAt¿¿Gþy³UÈj7MŽ·&¨a5ü!壀Nb¢Nu†ŽMÄ?þª�Á ‰4 /�ir¬ØjbüB 3Vè8QF—XëÚ\<ë%Ì09>™®á­ ªíÊŠäO' �Äo+t<~�uª èÓFÂ�ó¢{“¹Òƒõ�éq¿pƒ�©Ké¡ptuŠd•6m›+ ]®ˆö¹"jeX?ðÒÇ–ý&¦.ÑñËR»b�à®’çÏó‹8žý"€iKã£<©ÛpX5á¯ÿoF^êÁ Î~š½Ü„‹»K¸´§3!£0`µÃ�Õùy·¢€^‚$†�˜ïG&*¯bu k^O@^- È«/Vj“‘D¥»™˜¾ÌÀ´e‰uŒ'+�¡Y=+ sαuŸ‰¿Ž &ÔÏ�¨òýÀ¿>¢{žˆ”ÿoï®Ã£¸ö7€¿3+Ù¸ w Á]ƒW�ºó«ß•{+Pj·B½”r¡¥¥PJ‘ÒbEƒ»<wOVf~,Y¤ ì¬$›Íûyž}Ò„=3§‘}wΜó=ÎÙ�­mc/Üæ˜ûæ²,ãûõ¶ïäGÕc _'ÈW@»&""E””Ë8“&!5GBQ`ä…†…V øx�"šEŠˆ‰Ñ2JDt„ˆPÿê aеÊõæðÛrÔˆmÇLHJ©¹5ãŽÔ1Z„�Îüb½ñ� o/,Ga=,áZ›v)ÜÆÙZ�Þ}@o�cþ¦“%,ØàB“?Üý:™ù22óMЪMèÔL…1qj´oª‚(i¹2ÎgH–Gv�ŒÂR¹F×Ö$•øzþÞ"ƒD4 Ð(ÔÚQ!"Âxy0¸•*,•qò¢ [�±#Ñ„ä,¹Î/áêÕV½˜»F�ùë Ju^Àô{=ê˜j‡åzo/¬à| 'a WCoö&™°7É­h&¢O;ú´SáÎþxé”ée–ÈÈ+–‘ž'#=OBF®ù¿3ò%äÉ(ºø®ö ì¡1ÿ±zéøy õ ,@¼üQ@x o~ž€Š3Îmf’d\Ê’±ÿ” Û�8z^BN¡ã\à¥sÎP«5´j i¸ˆisË‘pŒÃXîB£^¾Ó]c3 ¾[£ç^çN$4m[ǯ j– ˜ïvŒÛJ…NÑæ’£Um}Ya�Q®7,)ò‹ÍáŸW,#¿XFa™Œ²rsà—êe”–›ßÁV£$C–I¾ü¸üß²l¾r¶g8×´ ½Œ¿S$û?Ox:¸ß¹t /Ì©�uêäz4jàù[´¸µ¯Æ¡·òdYÆš}F¼±€¯Ô:Aõå"5jÑ<̯V™¯ì=/‡½¹�­ÐjÌiÔ×µ©,tSÕ˃ÑT½A†þòÇ P®ÊôæPÎ-–a0Ê0šÌÏ7Jæ‚:õM|¬oÝë˜�0®–™/aÚÜr9W¿©dá©ÞºÇƒ;«þ¦ýðYÿ¢¬NŒˆ¹#:‘ š:ZƒGFy8ü¸%å2¦ÿTŽ¿²\W}â/àƒ‡tè­‚£à.dJxø“2äÖÀŠªš* °á›µÝ "ºÖþÓÂÌÛÐ:ò*J«0´‹‚:#qmp=Ò©™ˆ¯žôDóHLJyf¾„'¾(CF¡j�ÈEí:aBLš„;v;ZAÐ5F…6�UØ—drÛÝÉL%·õUcú}:x;vÂ%äKxnv9N§2Ìk�ÈE™$`{¢m«âøPo&bPG5N¥˜8ÞMx¯MöÀ}û,­RA‰Œ—¾+ÇaÎËp t"f0Û�Ñ!Z…ÁŽ¿ºòó6——5š€Ä ’ÓjÑSÍëÐTć�èУµã'¿æU(ÿù¾»ÿf˜» :‘‹«0ÛMè­BD�ãC]£У• ­¢T8xÆÄ2�uœJ&ÔàÍ»utüï p9Ì(GÂ1N®t% t¢: Ll=jDû¦¢S®ÔÁ\�ph5Òs%œãzõ:©a°€÷ép{ ´çÔ‘()—ñê¼rl;Î0w5 t¢:¢Ül>bD»¦"9öžz%OCº¨Ñ,BÄ‘s'ÌÕ*¸µ�ï=䉘¢ÃkT*.“ñœrì:É0wE\‡NTÇè4À;êп½ÊiÕüdYF~±ŒÏWêñû.#ï­»°VQ"^¼Ý�›9v‰ãõr‹$<ûM9Ž_à=sWÅ@'ªƒÔ*àß“=0&Î9ž*ɲŒCgLøø7=“ùBîJü¼€‡GjqG�C·<­JJ¶„g¾)ùtÆ…+ã�;Q$É@Â14j£�7Ä*æ ÆÆ© âäEÃ×6µ ï¦Æéл­*'o«ü÷%žþº³殎�NTGÉ2°7É„â2 [ •Cw̺žJж± £ãÔ�$àtªo£Ö(Q:5ñúݸgˆ>žÎ rY–±7ɼS_f¾SOEÂ!w"7п½ ¯Mñ@ˆŸs–)]M–e\Ì’1o�빇“ Z5ñÐ-úwpî·J’$ãϽF|°¤‚Ëë:‘›ˆðÞC:Ä4PÕÈùdYƹt?mÔcí#Ê8ïpm‹¸w¨ý;¨áá¤eh×3e|ó‡ 6¸jÃ@'r#ÞÀ¦è0 £ófÀ_O–e$gÉX´Y�U»�¼Çn'AºÅˆ˜2H‹žmT5䀹.ûÛ +°ùï§ÔE t"7£�GFiðà­Ó'L]M–edæËX¾Ã€¥Û�È)äK‹`@G5& Р]±F†Ö¯vü‚ ÿþ¾É™ü¹ÕU t"7Õ·� ¯ßå� _ç¡©Ž,Ë(×›ñÛvƒy›Ö;{ÝÓ4\Àø^ÄǪìW³?+À|¿ü·íF|²¬‚ó!ê8:‘ õðÆ]èÙ¦æ†à¯&Ë2.dÊX½×€5ûŒHÍ‘Y¤€·ÐA� ½ÕèÒ\±GR®–[$áý_*ð×A±»:‘›S«€{kðàH-¼]^�­ÇL�8Â^/0ЉÌ3°Ÿ¿U‹˜µ?iŽlWR.cÁ=~Úh`Õ¾z†�ND*ßK�‡kTû3²Ézåz+vðÝr‹ø²^1ЉètZ`bo î¬AD ƒÝ•Udl8hÄwkô¸Àûäõ�ˆªåãiö;0Ø]�Þ c{¢ s×èqâ"o’�ˆ¬àçŒï¥Á¤„3ØkUY…ŒMGŒX¸É€“ɬ“OW0ЉÈj¾žÀЮjÜÚGƒV�Dˆ ö“W,aí>#~I0àB_¶éŸèD¤˜Ftn®ÂmýÔèÛNí2ÕÐÜ�,Ë8›&aÅN#Vï3 ·¨¶{D®Œ�ND64ßC�øX …r8Þ* 2ޱt»Ϙ``u7²�ˆB­º4Wa\/5wRÃCS· ±Ô6Y–qò¢„U{ŒXÀˆœB¾4“2 t"r8_O`Hs°wi®‚§ý*F“ŒKÙ266bõ^Τñå˜lÇ@'"§ ðâZ«1°£ ±-Uð÷êõdº² §R$l9jĶã&œI“ óU˜€�ND5Æ[thªB¯6*ĵV¡a°/�{‡{åîqϘ°û¤ ‡Ïš�–Ë—]r<:Õ QÂÄ4Ñ1Z…Ñ"¢#Dû ëÐ&1×+)—‘–+áD²„cçM8|VÂùL‰ÛÈéèDä2|<Í{Œ·o*¢C´ -Šáïíz÷àeÙ¼«[Zž„siN¥J8qQÂÙ4óÎo&o£Æ@'"—¥ÍÃôÁ~š„‰ˆ * a°ˆð@aþ"|<�özƒŒÜby2.eKHΔp1Kƹt ùŠËÀð&— ®íUÇ$…¥@a©Œsé&&Ë¿©Uæ}ʽu|ú¾ž|<x{ðÒ™ÿÍ[h5ª‹|IJ+d—Åå2r‹ddÊÈ/6?J*dŒ€ÞN^#—Æ@'¢:Éh2?J+dd0i‰ÄÚîÙ��NDDäèDDDn€�NDDäèDDDn€�NDDäèDDDn€�NDDäèDDDn€�NDDäèDDDn€�NDDäèDDDn€�NDDäèDDDn€�NDDäèDDDn€�NDDäèDDDn€�NDDäèDDDn€�NDDäèDDDn€�NDDäèDDDn€�NDDäèDDDn€�NDDäèDDDn€�NDDäèDDDn€�NDDäèDDDn€�NDDäèDDDn€�NDDäèDDDn€�NDDäèDDDn€�NDDäèDDDn€�NDDäÔµÝ"r.�Fƒ @„…… 22��ðññ†Z­†$I¨¨¨@aa23s�–ž�Üœ<Õv·‰H!—ôž=»áÞ»o·úù………xkÆÇ(++wb¯l£Óyàõÿ<‡«Ûü¸p)vìØ«ø\/½øš6i¤¸�«˜1ó¤¥e(jà�ÿüç9è<<œÔ+û|ñÕÿ�˜˜Tc狊ŠDï^±èÓ'íÚµFxx¼½¼  ۙL&äææãüù‹Ø³÷ ¶nÝ…#GQ^^áÔþ¾<í)4nÔЩçp¦·f|„ŒŒ¬?o“&QxéÅ' àÆ?×êä`úŒ��þ󽑨¨H¼<í)ˆ‚3Œe F”WT ¤¸é™YHKMÇ©Óç�šš�B7{ãêÒ�Õ0£F ¶úù™™Ùxç½Ï]2ÐÕj5 새ˆ0«ÛlÙºÓ¦sõêÙ�;·³©­+˜õé·HSØFçé�aCûÃÇÇÛ)}²×â%+œ~-ê‹I“& [׎ðööR| •J…ÐÐ`„†#6¶3¦>v.^LÁŠ•kðË/+‘ªð�–µúôŽEûö­�rìšðÑÇ_Ã9ß™;f8âG ±¹½É$aÙòÕØ»÷�{¥ŒŸ¯/FŽ•JUcç4MÈËÏÇñãcóæX·~‹â‹WÄ{èDuœJ¥ÂØ1ñbù÷øâówп_O›Â¼êc‹hÚ´žyúüùÇB¼<í)ø9äØd�F�‘#Ùu •JÄèø¡êQÝ¡V«Œ�zãÍ7^Àº5‹ðÙ§o£uë˜Úîš]èDuXÓ&�0Þ§˜õÉt´jÙ¢è¼?i_<úÈÝøã÷1hP§�‡¬Ó"¦™Chð ¾ðòòt@�ê.oó›âeóñöŒ—áççSÛ]² �¨Ž9b–/›‡¾}z85ȯ&4ˆÀœÙâ¹ç¦B¥âKHm‰�â�aꨨHtéÒÞ=ªû´Z-¦LžˆßW.@§Nuï¶%ÿ‰ê {﹟öüýkgø[¥RáÉÇÀÛÓ_†F£©•>ÔgZ­#†tȱAÀØ1Ãr,w 7jˆßŽáú×:QsçãñÆëÏC­®¹IDUwÞ9/½ðx���YÛ6-ѼyS‡oÐÀ>›wá.|}}ðÉGoÕ©ÛKü+$ªCââºâÍ7žw™÷ß? ãÇ�¬í®Ô+cÆ »éD%ÂÂBÐ3®«ÃŽç.¼¼<ñᯣE‹èÚîŠU\ãU�ˆnÊßßïÎ|:�®¶»r µZ…W¦=… "j»+õ‚F£ÁˆáöÍn¯Ê˜ÑÃ~Lwˆwg¾ ­¶¶»rS t¢:⑇ïBÓ¦ö ’$ 99y8w.IIgpæÌydddÁ`0ÚuÜÐÐ`<ñøývƒ¬Óµk4lèø7OƒõqÙ:µ­k׎¸ýö±µÝ�›réÂ2d›Å¿,Ç–-;ì;ˆ<üÐ]Šî«­X¹çÏ]´ï¼rròì>ÆÍȲŒ+×âÂyûûk�óvž'44“'M´i˜Õ`0`ëÖ]øãÏ¿°ÿÀäåæCo0@’$‚�Fo´o× Ã† @ü¨!ðõU¾lgÂøQøêëùHIIWÜvá¢ej‚ùA IDAT QÜîz�>z<=­ÁX¶|5’/\²û¼¹yùvÃZc<Ü^ÉßßýûõÄŸ«78üØŽd2I˜=û¤edVûæë~ˆj‰–­š£e‹fP«m‹’Xm˜W%33Ï¿ð&>øï—�$IQ?G QtüÕ#™õé‹  åad­AûÀ× ‡ÝM&RSÓñÅ—ÿÃð“°eËNE•n¹%Þ ½s:‘‹ @˖͵)..Á³ÿú ‹m:§,ËøvÎ�Xºt•¢vmÛ¶„¯¯¯M礛;f¸¢7v.\BQ‘õ¿Z 6À–®ÕÙ9¹˜úøKضm�â¶ÝºvréÒÇ t"†€eÃí«V­Ç¥¥[Ü\K’$Ìúì;E;R©Õj´lÙÌ®óRÕ¼½¼0xP_«Ÿ/Ë2>ÿb.Ö®Ûlu›úRd¦¼¼ÿ~ý=äç*j§Õjй³ëVÕc ¹¸ÈÈ0ÅÃØ»÷tȹSSÓ±s×~EmE5pȹéZýúÅ)º:,**Á¶í{°ví&EÃËqq]lKë”ääüñç_ŠÚ‚€¶mZ:©Göc ¹8[fœ8nŸç}ûC’$«µUŽÖÝ)-&sðÐQdddaïÞCÈÉɵº�NgÞŠ¸>X»NÙ›À¼½«â,w"'Êßw;râÔÂ…¿aÍê�V?¿ @Ù0&Ý\``úôîaõóeYÆšµ›…Eرs?Æ�µn(]Œ= ´òÀ•�9s¥¥eŠVó¸òè�ÈÅÙ²îµ_ß8‡-¯)--Cii™CŽE¶é߯'üý­ŸlXVV~Í’Ì5k7*Z¿Þ©s;4Šj€‹—R÷µ.)**Vè®\|‡CîD..##Kq›‘#£c‡¶Nè Õ¥ÅdIDZZ†åó;ö)šÜè©ÓaÈÐ~ŠúX�F˜L&EmÔزÖYèD..--%%¥ŠÚxxh1û›еK'õŠjJxx(b{t±úù²,cõu·H ±cç>«�!ÆŽvNE:W¢Õj¡Ö(¨Öë Nê�ýèD..3+l(O†Ÿ~�·gLãÌó:là€ÞðS01Ò`0`ÃÆ„|}ÍeÀÚ¶m…fÍšXýüº(0Ð_q!�#5��NäâL&ÖÿµÕ¦¶Z­wM¹kVÿŒYŸÌ@¿¾qÜ÷º1OPª¨Í‘£'�šúÏzú[v*š ¡Óy`¸›™éÔ±-<<<µÉH¯¾†|mc ÕËW¬Fqq‰ÍíÍuÖGàûùŸaÝšEøô“¸ãöqˆ‰‰†N§ì�jNÆ‘è¢ð¶Éš5›ªüz~~!v)¬)0rä`¨Õ®{ÏØ¢(bâå¥\Ïœ½à„Þ8g¹S½uÏ]·)ª¼e‹ùß/ƹsÉvçüù‹Xòëï¸ÿ¾;íº¯)4ˆÀ¸q7n #ÒÒ2pôØ ìÝ{Áé3çQVæº;JÕ'C÷U4¢"IÖ®«:Ð`õÚ�2ÄúÉn­[Å &&'Ož¶ºM]1dp_ô�$I8z줓zd?:ÕK‚ (za³ÕÚµ›èðùçsѯobb¢r<ÐhÔhܸ!7nˆÑñCa2™�••ƒC‡ŽakÂ.lÙº«Êá[r>Q?jˆ¢6ÇŽ�Ä¥KÕ—üݰ!z½Z­ÆªãiµŒ1Èí½s§v˜ùö+Ð(œWPX„c.èr'ª#òò ð̳ÿAn®óö‹W©TˆˆÃÈ‘ƒ1óíW°ní"ü¸àKŒ;\Ѷ¤d¿Æ�¢S§vŠÚT7Ü^)?¿»v+v1| Õo\�ÎÃ>0ßÏÿ̦1›6nƒ^¯wBσWèDuHâ‰$Üÿ೘;çc§W¬Þ^^èÓ;½{uGFFæ¿ ~ü•…fjÀˆááᡵúù’$cÍ †Û+­Y³ ýûõ´ú¸-Z4G«–Í]z¨¹:¢("<<­[Ç OïXÄ�‚ˆˆ0›o[ý¼x¹ƒ{èX t¢:æèјx˘5kºuíX#k…A@DD¦½ô$~è.|ôñ7Xòër�uT*F)nOLüÉÉ7_Þø×†­xó�¬¾êV©DŒ=Ìe]¥RáǾ„Ñh¬ö9‚h4øøxCu¹Œ½'»vïÇþý‡í:†³qÈ�¨JIMÇ]w?Ž?úZQ0{ ‚€�� ¼3ó|?ïSD5Œ¬±s×'Í¢£}»VŠÚ¬ûk L&é¦ÏËÎΞ}‡{ø°ŠF œI ,,¤ÚGhhü¡V«!‚Ýa®×ðÞû_@á>.5Ž�NTGéõ|õõ|Œ/~^´Ü®emJ ‚€>}z`ñâoѽ[§;o}?Ärei “IÂ:+÷=—eYÑéдi#´oßZQw!Ë2æ|÷#>^Û]¹):Q—œœ‚W_{£ÇÜ�Ï¿øΟ¿¨xKH[5ˆ Ç·³ÿ‹8¥IéÆT*•âÙíIIgpVÁúè ·¡¢ÂúÉ]•;°ÕG7mÃç_Ì­ínX…�Nä&’/¦àãO¾Aü˜»0åîÇ1oÞ"œ¢ìŠÓ�f»[C–elÛ¶Ï¿ð–Óÿ†…“âˆÜLYY9víÚ�]»öC£V#"2 ݺvDϸnèÒµšE7†ZíØ?ýð°|ðÞ¿q×=O ¼¼Â¡Ç®o”î¬f2IX·~‹¢sH’„õë· G¬õ#+‘‘áèÞ­3vìÜ«è\u‘$IX¶ìO¼9ý£½•e/:ÕK²,cóæH½j‹IgH·aëSG2�¸x1/¦bùŠ5Ðh4 AllgôŒëŠîÝ:!:º1DÑþÁº.]:`Êä[ð¿y?; çõ“ ¯lhûì¹ HJ:£ø\6nË/<­ÖúÉncÇ sû@ÏÎÎÅ{ïŽå+V[5ÉЕ0ЩÞú~Á/زegmw£F ¤¤¤!%% Ë—¯†Z­Bƒ‘8 F�ŒØî�Mƺš ˜úؽX´x9שۨKçöˆŠR¶ràì™óèØ¡�âs©Tj¤¥e¢I“(«ÛŒ1¯¿ù�¢áýº¢°°?-\Š9ßý„¼¼üÚîŽMèDõ˜ÑhBrò%ü°` ~X°�5ÀÝw݆ɓ&ÀWÁ–�•BCƒ1bÄ ,[ö§zëþÆŽ®¸Íðá1|ø@Çw¦ ~èׯ'6nÜV#ç«I‡Ã?üªÆ&”:'Å‘ÅÅ‹©x÷½Ï0lÄ�X±r-$Iù�㈠w£Ñh0bÄ Åk¦+×YÛúPz®±cjw¶»,Ë(--CqqÉ J‹õí‡~}ãœÔëšÁ+t"ú‡ŒŒ,<÷üHIIÃÿM½OÑ lw®K·E\�. ©ínÜÔÀ}àãã]k“ÅL&xðÙ›Îxæ™Gpÿ}wZ}\Aðâ �cû޽u¶"¯Ð‰¨J’$á³Ï¿Ã!…5üêúÁäjFÇuÈäDgó÷÷EÿþÖׂw†¢âbäÞð1ûÛÈÉÉUtÜvíZaüøNêµóñ �ÈE©Õj<ÿÜTXõ|I’ðöÛ³PRZê°>TTè±ô·?Ð¥s{«Û˜ë¾‡"++ÛaýpwÞÞ^<¸omwÃ*•EfþüsCmwå†ÒÓ3ñÂ%ø×³�YÝF<ýäÃX»v3JJ÷wTSèD.ªrÏö ö?Ÿ7o’N�uh?Nœ8¥¸��·—CûàîzÆuEHHPmwÃj½{uGPP S·òu„?þŠ;î�† "¬nÓ¸qCÜ}×­˜ýí'öÌ9\|‡¨ž2�(,(TÔ¦s믤­fˬߨÎ�Œ=¬N ·WòóóÅ€Zv·F^^æÌùQÑÌuAðÐCSœ¾=±3Ô�ß ¢zF–e¤¦*+|?rˆÃ·S�‰iª¸M]®¬-þ~unvµ 3Fù»ÚðË’ßqî\²¢6!ÁAxô‘»�Ô#ça ¹°¿VëÛ7]ºtpØùEQT\¹L–edÖr…¼º¤wïXÖv7‹íÞ aµÝ�›*++Ãg_ÌU´SLºsš5kâÄž9°ƒ�B–e«¯ºU*ï¿ûn»ã(®¯ÊðáѧO¬¢6EÅ%ÈÈä„8k)­Ý.I2¾�³ÉÉ)íÇÐ!ýMÌóõõÁ �½ñó¢åí‡3üñÇz<ôÀdtPPQÏÇÇO=ù ž{þÍ:Sl†�NäÂŽ'&!77ÁÁÖO˜Š‰‰Æÿæ~‚§Ÿy ))é6Ÿ»oŸxw櫊KÁ>t¬Î¼Ö¶Ð�`ôìÙMQ›‚‚|úÙ‡o‚sþ|2ì­è^þèÑðhñ —ÿy�&|2k6¾›ó±¢ÿ¿Q£†à‡Kpðà1'öÎq8äNä ±mÛÅíºv逥Kæbò¤‰ðV8ãÜßÏÏ>ó¾�ý!üŸ{ÓæŠÛÔWýúÅ! À_Q›Í[v:eG»}û#+;GQÏ×–Í[vb÷žŠÚxhµxöéGmÞß ¦¹Õº——'î¿ï§nߨ×ëñóÏËQ¡¯ûãRõâGA«–Íkä\ »qâ¤òå_°ø—3f˜â•ððPÌ|ûe<öèÝX½f¶n݉³ç’‘““£ñÊæ�ÁÁ�hÞ¼) ì‹øø!ˆ´ñÞhYY9þ\íÚë“]… =z¨âvkÖltBoƒÁˆ ¶aÊä‰V·ñòòÄ�Áý0ÿûÅNé“#ɲŒ?ú¿,š­èo©OŸèß¿'6mÚîÄÞ9†[º��·¢"¶(,,²å«èuœ ¸ãŽq5v¾¢¢wlô½ûa÷îèÝ[Ù½lÀüÿÙ¤I#L}ì^<öè=×ÔºÖ Ðj´ðñõ†�·||¼íž!ÿûªuÈäýs«„‡…(Ú�Š‹K�°m·“zd~³ $Ð ~Ô,øqI�ØjôàÁ#Xÿ×VŒ1Èê6*•ˆçž} Û·ï�^opbïìÇ!w"g4šðáG_Û=ò$|}}Ž-š¡]ÛVhÑ"‘aðõõ±;Ì ‹ðÅ—óì:F}2hP_øøx+j³eËN”••;©GÀ®Ýû‘—W ¨M§NmѨQC'õȱd˜õéè^�µk× ãÆº~IX:QpðÐ1|«°@FM’e}ü .^tìÌkw%ŠF�¢¸Ýj' ·W2ŒØ°1AQ­V‹ ®xkÛߟƲ嫵ÿzöQxêtNê•c0ЉêˆÏ¿˜‹5k7¹\¨Ë²Œ_—®ÂO «í®Ô‘áˆí®|¸}kÂ.'õè [æ@Ä� u™8_~5EEÅŠÚ4h�˜ä¤9�¨Ž0�xþ…7±aC‚Ë„º,ËX³v^ãƒ:»ådm1b´Z�¢6Û·ïQB¶Ø½ûòòòµi×¶¢ëP–‹S±ðçeŠÛ=òðÝ.]sŸ�NT‡”••㉧^Å –À`0Þ¼��&ü´ð7üë¹7œº²Ä݈‚€Ññ6Ìn_»É ½ù§ÒÒ2lÙªl$@¥R!>^ù-„Úô¿y?#+KÙ2=_<þ÷;§CÀ@'ªcôz=Þ|ëC<ñÔ+H®…{Ö²,#++/¼ø&ÞxóTT0Ì•hÔ¸!:uj«¨�³g·_Ï–¥qñ#‡@¥ª;‘’™™�ùß/V¼qË·�CóæM�×1;Ô�ï>]cýú-?á~Ìút²³skäœ%%¥øñ§¥;þ^¬X¹’äCÿuIü¨!Šk ìÙs¹¹Ê†Áí±k÷ųÝ[´ˆFëV-œÔ#çøiáo¸t)MQoo/<óÔÃNê‘}èDuX~¾¹ èÈøÉ˜>ã#9zÂá÷²eYÆ… —ðåWó?ú.¼þÆÈàæ+6;Vù.ek×ÕìdÈ‚‚BìØ¹WQólÊ6ò©m…˜=g�âïíðÑ­[''õÊv.]X&==›·¸VÉÒÒ2m¸wi2™°k×~Z_æ1-]Ù֙޶cç~øûûZýüœÜ<'öæÆ*Êõض}t:�ZëÃ�¤¥e:õø99y˜71üø+š4i„ý{¡Glg´oß‘‘áŠêW˲Œ¼¼œ8y ûöBBÂn;þw�Zß±c¯¢µÝ¹ 'Ù+88é陊Þ™Œ¦Z)§»dÉïŠËûú*[WÅ%%غuѺ:’IBqq‰âóTgéÒ?н['ÅeŽãâº`ÿþÃë‡#M›ÅrÌŒÈM©Õjøøx#:º1"ÂC??_hµZh5jM&TTèQRRŠœœ\dfåàüù‹–ò°®2›žˆnŽ�NDDäx�ˆˆÈ 0ЉˆˆÜ�ˆˆÈ 0ЉˆˆÜ�ˆˆÈ 0ЉˆˆÜ�ˆˆÈ 0ЉˆˆÜ�ˆˆÈ 0ЉˆˆÜ�ˆˆÈ 0ЉˆˆÜ�ˆˆÈ 0ЉˆˆÜ�ˆˆÈ 0ЉˆˆÜ�ˆˆÈ 0ЉˆˆÜ�ˆˆÈ 0ЉˆˆÜ€º¶;@×Òh4 �`c{½Á€ÌÌlÅíA@DD(T¢ªÚçÈL&#JKËQXXdcmãé©CpP åó”ÔtȲìðóxyy"(0ÀòyaQ ‹í>®J¥Bxx(DÁü“µõçTI«Õ",4ØæöF“ éé™V?_EDD„BDȲ²r ×ë­jëá¡EhÈ•¾æå ¤¤Ôª¶*•ˆˆð0—¿o™Ù0 V÷ûfBCƒÑªesDE5€··ôz=22²pêô9œ?Ñ)¿c¾¾Þð÷ó»ásdYFE……EýÿO�ÁÁæ¿%¥¿ �úJtäæå£´´Ì¡}$Û0Ð]L«VͱøçÙEÛ"ýxbîœô(L&IQ;o,þù[„†Ýðy² ˜L&áàÁ£øcõlذƒÑ¦þZkêc÷áÑGî²|~ÿƒÏb÷î?Ϩ‘ƒñöŒi–Ï·mß‹G}ÞîãÐ Ÿö.ç“pëíÛ|¼ÚàÇ>·¹}jj† »Ýêç«T"¾Ÿ÷¢¢"¯þû=,[ö§UmÇ�‰·ÞxÁòù –àÝ÷¬ë{ûömðóO_C€Š ½¹¹ùV÷»*‚ Ü÷Ý{ºvé//OËÀ¦z½çÎ'cñâøeÉJ‡ÖäIñ¯g½éó$IF…^�óç/"!a~]º /¦Ú}þ~ýâð鬀””tŒ{7**¬{s6rÄ |ôá›–×§ã‰Ixø‘çè.‚�îbDA€‡‡T*Ûî†xhµ6µ`¾’ÒétV=ßÇÇ F`ôè¡HLL´—߯ñÄ¿m:÷Íèt3zè5}»eb¼S]¥R]sž¾}bѼySœ9sÞ®ãN™| <=¯WkãÏ©’( Vÿ¬ªâá¡ìüƒ‡GLL4 OïX«½_Ÿ¸kúÚ¯oO¼ ë½w¯î–ï[bbòó õûzaøà½£OŸŪÿÆA€‡‡­[Åàõÿ<‡û¾ö.vîÚg×¹+©Õj«v^^žìì�.�ÛãÑGîÆœï~¬Oç@’”½a¿š¨-çWò{Ø3®>þèMxzzΞ»€§Ÿ~ÍîŸ 9Ý…I’„£ÇNÂd2YÝæìÙ pÄ(á©ÓçPTôÏ¡f�Z�àà@B«ÕB´k× ú =üöí?lÿɯӵKDG7¾æk#G Æ[Ó?rú•�N§Ãm·ŽÁû|aó1š7k‚^½»;°W×2Œ8q" F¿'YY9ŠÏ“�° ·Þ2‚  g\7‚pÓ!i//OtîÜþš¯µlÙ !!AÈÎνa[@¯žÝ,Ÿoß±×® kÛ¶%æÎùa–¯�F\HNÁ‰Ä$äç@ç©CLó¦hÕ::‚€¦Maþ¼Yxý�ÿbñ/+l>UŠ‹K�têì?¾.¼½¼ ooo¨.‡ðSO>„Æ�£ðü o(…³Gûv­ñÕWïYÂ<55=üRÓ2j¬ts tf4qï½O¢°Š`u¶·¦ˆíÛ÷Vûï‘‘á˜0~$þoê}ðõõ�ŸŸ/þûÁë˜pËý((pìýõ FY†D%I‚(Šðõõư¡ý±båZ‡ž«*ãÆÇW_ϯò Ž5n½u <í¸š¾™ÂÂ"ÜÿÀ3ÈË/pÚ9`ßþÃ(//‡§§'ÂÂBмySœ>}î†mš6m„ ¯ùš(Šè× «þXö¾~¾h×®5ó0x¶Ý6÷½q㆘óíG–07MX»n¾™ýŽÿûoL""Âp×”[pß½wÀ××Z­3¦OCaaV¯Ùhs?®—˜˜„;'?Ví¿{xhÑ­['<ùøèÙÓü&jÜØá8pà~X°Äaý¸‘èèÆøæë÷àÈÎÉÅÃ�>�óç/ÖÈùÉzœåN6IKËÀ×ß|�Ǧ¾ˆ²2óUrÓ¦�pËÄÑ=O€¿ê ÐëõXðã¯�e‚ `â„x‡ž«:‘‘á–>(åãã�qcG8¸Gµ#55gÎ\¨Õ*Ävï|Ó6½zvûÇж èÝ;ö¦m[·ŠAP�y‚bvv.Nž×ÇÇ�:¶`^ñÑ'ßXB¹Aƒ4mÒ¨Ú¶‚ .®«åó„m{lê¯Nç�‡šby“ùûªõøÍÊÉ|•’’Îâý¾°ü�1-.O¬I/¥âСcÌ¿[•ß[gðôÔáÃß@÷Ë£0zL{y¶lÝé´s’ýèd·K—Ò ×›×ÊúøxÃÛA�†^=ÍWxÅÅ%ذ1°råZËÐãøq#:"pµó瓱fÍ&æaÛ;n§¨}ËÍÐ#¶ ?¿?/Zîð>Ö´�ZFHBB‚Ñ¢EõÁÖªesËèÊùó‘x< /’F£FllõCö>>ÞèØ¡-ó¤¿];m›aÞµK´hÑ €9”fÍúÖ¦7U+V®± 3k4Ür‹co-YëÌÙ –ÿuÊ9T*fLŸf¹Íd0ñÖô±ê�¿œr>r:ÙM’$ËÕ‹ °£G³,¯Ú³÷ RSÍ3j7mÞn¹rnÙ²Ú·kå�ó]O–�Ÿ-³¬2?—'YãÎ;ÇC­6êYÿ×dØQHÆU”••cß~ó�«F£¾á}ôÞ½»[F'vï9€ ½[v¨¼�^ýÌÿŽÛÂÛÛ �œ| ’/ÙÔß!CúYÞðmÛ¾Çæã Fü²d¥åó¡CûÛt{]½âÅÖZ7óò´'qËÄx‚“I‡}…E‹;»Ÿœƒ�Nv ‚Nç(/¯@i©uUÀnÄ<émó ç•WÍf/--Ãúõ[˜¯–Æ:qÒÙ±ã'qèðq@ppF�dU;o/Loî¿ÑhÄ¢ÅËa®µW÷%\eàÚ{äW=/�®È²Œ­[Ím¶oßk ¥Øî] ÑT½Ð¦÷UÇݽç eH QѵKËç[¶ì°ë–Ƕí{,ýhØ ‘‘5?7"êòä4vØ©Êc�Þƒ‡œA I2¾þf>æ|÷S�¿UT_0ÐÉn#†´\‰�={¥¥åv³m›hÓÆ|Ï:77[®]²´|åË‹Ìȃœ6ã×h4aÑâå–sMºsTªêËãV3f8Ìå=�=�Ç�Ò¿Ú�°m·åûÑ©S»*¿÷>>ÞèÔÉ|�·¨¸Ä2Ô~êÔ¤].5Œ–—‡Ã¯W9‰M–åkÞ@(áååi™� ‡�Ø÷38w.EEæ‘!�Î�7´ëxJ¾$§ÀþIDATú[nSȲŒcÇO:ôø·Ý:/¾ð¸¥¾À‚—àoQPíà:t&Z·nauÝë¼ü¤¦¦;¹W×jÕª9î½çJ Ñ¿6$Àh´¿ ìÕËßv!/ïÚ«‘Ý» =# ‘ahÐ qq]±iÓv»Ï[•õë·"ó¹l„‡‡¢C‡6èÔ±-¾V«ÁèÑC˜ïϯ\µîÏ1�øóÏ¿ðЃS Š&Žå´@/((Ī?Ö[†"§L¾å†�Þ¹s{´¿\%++k×mvJ¿*ùûûaáO_[ý|Y–ѮÔ•Ù6’"Ë2¶m߃;n•J…=ºü#Я^g¾íª+zغm&Mš`~^¯XÌ›¿øš¶±Ý¯ÌžO:uéY6õS§ÓY†ôËË˲ÉÉÕoš*ÃÕ™ Fh4jtèØ>>Þ(..±üûÕ÷å·Ù¸\ À5uL&“C†Ž¯}rÄêŠV­bðãU”xzê„ÈÈp¨¯ÚÝìàÁ£øú›ïí>7`ž)ÿÅçï\óæDŒ?‡Ç‚uÈy¨f0Ð]˜$Iظq Va;æ¸{j•W˜ÖHOÏÄÛ3gáÏÕrî‰W•z]¿~‹¥ÝõO$!)é,ZµjŽÀ Ô¿ü²²ÊçÚëï¤3Ø»ïúõ�ƒ——'&NŒÇܹ ÿñ¼àà@Œaž8§×ëñË’ß�ÒŸ«UèõØ–°zW öÞصk? 4 Úµm??_Ëʃ€?´mÛ�™™�¿ÿ¾¶Â[~~!ŽMD·®Œ–-›áÀ�+#•KM&vì°=Ð+*ô–å�Z­ö†[[ëê v¬Ý¡ìFüý}ѧO«žk2™°fÍ&üûõ÷¬¾ w3�Æ2r!ù¶oß‹)“'š‡ø_|Ç�ÿ}ÓÛKä:è.Ìh4âùÞ¬•ZîÖ�esç.Ä׳¿wØŒÛàà@ôï߀ùì÷Ôû6�øsõ_–JVÆ�į¿®rÊP¡,ËøyÑrôé Q1ùÎ ˜7oÑ?Î5~ÜHøøxöî;ü�0s†â¢¼øÒt§×r¿Znn>Žÿ�;·GHH0bb¢qàr±¸]-W”û÷©r�„„ÝèÖµ#T*s]÷Ê@´¬ÏË+À±ã¶ïàWQ^�ÒÒ2x{{ÁÓS_oäæÙ÷{Z9r¹¹yvK‰ää¼øÒtìÛØ)¿ßÙ9¹˜ú/áÌ™ ˆ‰iб]àëã�Þÿ&MžŠìœo¤C®��NUzõµw«œŒäíã…9³?´Ü7 rèò™¡Cû[†ÿAÀÛÓ_†$U5YžÐ­[G4i…sç“ÖŸ«mÞ¼©©éˆŠj€èèÆèÝ«;¶m¿r©V«qÇã®Üç\ø›Súá $IÂŽ�ûйs{ˆ¢€^=»Yýêûç[«™¡ž�° Ï>óˆåù_}=Û½³å¾÷�U¿°ViY9²²ràííAмYS$'§Ø|îèø!–¥3‰‰I0`‚U�[o{È2I(&&;´±»/ÕIIIÖ-æ *<=u–šÞ�¢ ?ó½ƒÁ€Å¿¸©Ì«×ˆ u«Äõèõå757Û¿| MÇ‰ŠŠDü(óRJY–ñûªïåî( ^f¹M Š"^zñ §•|½Þ§Ÿ}‡Ý{Ì+L´Z->ü¨¹µ÷¤�lòË/+qöòFj• O?ý0t7iU=­V‹øø¡–ÏW¬\ƒ¬ì\«‰'’°wß!—KÆNeßÿÜMü´p©åªé–‰ñðôÔa„+“á6nÜfw“ºâêÐîÕ«;z÷ê~¹l¨„mÛoè•Ë×óíŠîÝ;[® ·mßã�ef/¥býú+W /½ð¸e�uk©T*L{ñIøûû0¯êX³f£Ý}³FQQ1¾þf>$Éü½èÞ½†X#ç./¯À˯̴ìA†�þûfµåz©ö1ÐÉ&zƒ2Ûò¢Û¡}Œ;ÜæãuîÔÍ›5`®ê¥dg§ÊÊV•}5rð5Ë‹mÇÎ}–73�5@ü¨!˜8!ÞÒ—ŸÜx2ÜõvîÜ£Ñ À¼{Òã-÷Ïovu¯Ä—_Ï·,©‹Šj€YO·lür3¢(â‰ÇïǨËÛôʲŒYŸÍ±¹(�-V¬\‹'¯TÓ{vÝ:PâÂ…Kxã�,5ì{õêŽgŸy´FÎMÊ1ÐÉfk×mÆÁƒæ!WAðÄãÀÏ϶êYãÇ�°ÜÞ³çÒ¨Ù²u—eÙVPP °ÿ@u$I²l…*Š"¦¿õ"š65ïí}úô9ìÚí¸’œ®îBò%$_ÞÁ¬]ÛVˆˆ`.~ru±˜ª FËd,oo/Ëþ烻wï¿QSENŸ>‡Ï>Ÿk™!Þ·o¾ŸÿZ·Ž¹a»  @̘> O?õ°¥HÍæÍ;°téë›5ÊË+ðùçs-µbš7U¼•¯=Ö­ß‚ùß_™ûÈÃwaø°5v~²�lf4ñɬÙ0]~¡lܸ!îšr«âãøùùbÈà~–ÏW^uµm­œœ\l¿jÔĉñŠû¡Ä²åZîÍzyyYfÿ²äw‡”UB£Q£[÷Nˆ‹ëjõ£G�.ÐjíŸlݲƒõ� xø¡»ðëÒUŠJ°öíÓÃR°£¸¸mH°©/+W®Ã˜Ñà ú÷‹CHp�Ó bäææcõê ¸í¶±–¯cåïkoÐÊ9|}}ðí7ÿUÔÆ`0`àà[�–f©Þ„„ݸóŽñ×~ÍÊ!ó£GO /¯��Wö™ßæÀáöJ&“ o¼ù_ãÑGî†(ŠðòòÄøq#1nì ˜LQ€V£ùǪ�í;öâ_ÿz995WLæÚþKøø“ÙXøãWP©TˆˆÃLÂ'³¾­‘ó——WàùßÂòßæ!((¡¡Áøð¿oàž{Ÿª¶’#Õ<^¡“]L& ³>›½Þ¼t,((ÿ7õ>«ÛWî{^y…›�°Ëæ \;wî³LàÑjµ– ^œå§…¿]3’°nÝfd^>MAñpÜLé× ¯§§g")é¬Umssó¯ÙÔ|uïø@Ì[á¾ÿÁ¸ïþ§qâä)ËÏ®²4¬§§:K˜Ë²Œìì\LŸñ1xðde;gŸkíÙs6n³Œ2ÜwïhØ0¢ÆÎñb ^~åmË­‹®]:àåiO:|m<ÙŽWè.&7/K—®‚ 0M5¶–Yo0`Õªõð½|<3Ãú`:z$}ü bb¢˜‡ät:ËzíñðÐ"55K~5×<¯üh‹’ÒR|ñÅ\Ë>ܶ¬G?w>ÙÒ‡›Õ°>zì$¾™ýBB‚óæ-ºáósròðëÒUÌËßì‘��k×÷Êd49dßzÀàó¿_l©¢vDá¾ã?þø«e΄Ñ`ÄÑ£'Ò¯êlÛ¾cÆÞƒ^½ºcø°èÒ¹=¢¢"¡Ñh I²³sqìøßؼy;Ö­ßâ°ºé•Nœpython-msgspec-0.22.0/docs/_static/mosec.png000066400000000000000000001113411525673062400207600ustar00rootroot00000000000000‰PNG  IHDR^^BIàM!zTXtRaw profile type exifxÚµ›iv9r…ÿc^æa9 çx^¾¿‹G±KRµ««mKU$E>f"c¸CÏ�ÿúÏëþƒ?mäîri½ŽZ=òÈ#N¾èþóg¾�Áç÷ñý)çë«ðó÷Ý÷"ŸŸÓç½~>‡ßÿú…ŸÃä«ò‡ õõõûù#>ÇþË…âçSÒŠôõþºÐøºPŠŸ„¯ ÌÏcù:zûã#Øù|þúýOøßéCî?/û·7¢· ÷I1ž’çcJ_ Hú?¹4ù¢ð1¤Á yÑûºò1¦öu1ògqúþ3XÑÕRóŸ¾è§¬|þüûî×låøõ’ôK�ë÷ç?ý¾ å—¤ïûÄ?Þ9÷ï2‰??ìÏŠ~‰¾þ¿w÷ûž™§˜¹êúõP?å}ÅëŒ[èÖݱ´êÿ.ÑÞßÁßNU/Jaûå�¿+ŒÉÄ 9ì0à ç}^a±Ä�‹�/b\1½oöÔâˆ+)YÃ�-�´S'‹ë¥=§ø½–ðn;ürïn�;ïÀKcàb�_ùÛÝßý…{Õ !øþ+Ö£‚Í2”9}äed$ܯ –àý£¼&2XeµÈ °ö¹„•ð$H/щ>z0´ýuBÄ­ ‹ ‰ �µ�J¨Á·[²“ ÉÒcÊÑÈ@(%nsJ•Üô¨[ó+-¼—Æù¶ãû€™(ôW#7#M’•s¡~ZîÔÐ,©äRJ-­ô2ʬ©æZj­­ gK-»VZm­õ6Úì©ç^zí­÷>úq$@³Œ:ÚècŒ9¹çäʓߞ¼`N‹–,[qV­Y·asQ>+¯²êj«¯±æŽ;mðc×ÝvßcÏ¥tò)§žvúg^Jí&wó-·Þvûw~gí+­¿ýýY _Y‹/SzaûÎßmíÇ%‚à¤(g$,ºÈxS (訜ùrŽÊœræð—Jd‘E9ÛA#ƒù„Xnø‘;?UæþWys-ÿ”·øïfÎ)u3s¿çíϲ¶ECëeìÓ… ªOt¯™±ó\õûg÷Ï~ðw?ÿ?\(#$ú,ýR<±vŸ’Ѭ%beêô;¬å{[¡Zîܤp§V²�`ç4Gç“�¾›µS:ýú=›�„Ù×L)æ~¨«´{»ã­¹�@®\Íï2×jcÔíÚª�ð:k$»‡RHy“¥zÉx‹•z÷íëÞ4í–Þ&—±¸sÜ,Ž{ê²f7úá.w—Á]öú·£äþú…g€leçºOj7noyÇvÂ`,ˆGF #³®cÎf“"Ïå–šúœµ]ƒ®|'­Îqx4:»û»ë8c¶Bùö˜‡'Ñ_wh€sVÛɤôê¥ôè�AD+/Ü[ß¹çÌv¸ºÚŽr?ç”ÐËÚ«çR>n4nêÁ�qòå)¨z¥¤^2ÉìñÖ³ù©ç7ûi7Ì=&ÝqC¬VȰ“ã‘åtPB ðºyÉËðÕnT¹cXÏ�®oG0Ô)<é½Áàt*Á°³›žpÙl·ÌÁÊ!˜±‰åËlÃ_°ÄS>»ðì5 а–CEk~Ñç±$®~U¦BQ)#l~*[~”tm$¨ÿž;õ4Éû궦kÐü×(KBB��®Õ˜�ýƒ¨[šQ —|åvh‹�æV‡u*=Ùä†é.€yÕvÀ§à&§*%¹»ÄC'ïÜîê—ìùx YÃ+£R©™¾Ê«¢ŒìØ®´(ŽòY_üÕçRx@z•j4dëQþéÌÐW-Y†ˆ ï›o�÷m‹†O½[®�Ö ñ¨õSA:QŕİF.X/]—'¹ß§ÕlN…Sô}"7Û4ú ‰äRY꿞âêÃoz’ì}ƒÙ ï®ÄŽoPÌSSKT½ŸÉ%V+q»–çY,kÇØ7 ³¡¬�+�'-N÷sËMä�ìTêu÷’‚kàJÆ¢ì¤,¤¸mñÀÁ@ý›s:ÍpTai=Ë·Ny�Mu_E"š=Ü™dæ›Õ\ãõWØÇî¢Ê×åK¸ÁBÙ�oµÂ‘>ça»õ¸hä4Rî:´þŽ j&û™HÛ(CZ5®L1µC¡æií‘c‰�4P…t\Eèv+ˆÉµ­¨mßC'«¸cØêSk�“:mS–ö&Á¤<ø°õJ_† nšÒx]G]\‚œ \ÍSœ½í”ML37eEJó¦i‘¼€�¶�Íð.�vé³BÂÅPÀ°˜Î$_bhî­÷ܯ2Ò�F,ÅQµæ1¸dLÀðg‡½®½…ã¸Xs £1Ò¡@�R©‚®šz¯Žèb&§ÄgEnOMµc@Î?�;È „|:ØÝ‘ùV …>¾(,Œà°Ý¢'ˆ,­|Äý1‰u¶Ú«Pá£Øêî8wAîà-TIq•>æéêžkòh†Íàº@ ŠäÖ>õ£RD‰'&4}mîVh˜MS°ÈŠ~‹0H ˜H·¸TÆ8ž¸�F"ÅNò(â™Ú¤ ‚ þõÀi>÷Ú¹ÈdÓàª}ÝEÚEt‚gᤆôèà q®me]ÜêÜ")Tèy^z˜„š„0-(_éÌÐZµ5yyWbIË<‡Ë¡ÀEv�äXW«Ï\"¬¶ðøP ÑêH¿:^÷Ê%l*Lj»¤{{a1‹xWC±Õ�Dc×�“†§¾yˆÃ«Æ îµgÙW’e�ŸMTÄ èzÄ}½~.Tvª…yA2(u�½…ʘúCW�á %øÁÓJ‘”÷%©o¡Mx«'øîö&¨þBk„šeDýI…nj3@–\¤tìX…”V¶—½® ¹,£Õ�Da_Š�˜Û„בWqÒ’6F1 jBkºIeRŸ¸B4Ï77ø}åˆ�qÁjn§â }Pu loS«Éóh”Å� *·-c/âÕ©qÉz¸�um—b>¬ a°¨ÓHI–XÜOõÀ²”Q†¡Å'Æ@+qöË‚E9 2IeFÔÀ¶A|†··UmºÎCÕÒ:;×W%Ù8 @Ü]rná÷ð'¤‹’õ8‰fœT¸†/\uý’S?ÕCùœ·_xD%L%yç‰Ö¥‡SEéÀ°™èrÖV*Q-ð+äÝ”Y0YÎb*1Fò{êÖŠ ]‘ÿîIâ‚Ò,¨ÖÊÁ•"§D4̈|ÎÃ+·÷Úuõ¸°!niÜd€²ð.M¶H L‹œX½/2KÉmpowÔSÜ'Hu£ï�•únÑTŠûm¬‚Ú¥±Lq1�’J¿Ê†Ü"‰l88HsȘø8j3!ù­I” Üov)ß9y(~w/Š´=FÞ“§DQƒÒ߯�K#Ð_X¿˜ƒ-˜­€U¸†ˆ>¢sŽ´TÆLu‰´‹Á¸×¤‘ ²+ùèF}h((d’ þw ]J¸Õ‡é8:¤Dˆ¤Àø‰Î…¡—˜œ8àÿ@%þÃ9.ÊOƒ‰ã@/­¥týp’¾1.ˆýŠjB Á�T 1¥ù¨R؈þt‡Â�Á4´ýÄj�M2ÑTú8 dr‚Xi¦þt­½pÍcš X®¬”�ÙÖ [Ö&Rzhu§Ž…Ø)G³e  ŽH/±p×7–ŒÚ§+©°ŽsöÆÊlv U…f¢›¼¸Ï.H¹PyŒ´ÁH6ôæï€Y Ä–�2³JYÁF• äO‹²w²dÄ¢²—tÐ�n>qa·rFT(�È @RÈ%Ç%PU‹+§+‰Œ´�‘Á± ^:¡%b,ñ¦r–ìßöxl< N-²—4G†3Ñyl„€lߣt£ìrt"÷©ióçóߌÃ’â{xº !¤ªND2-L…„"€T§ó€²'Ë{ÕŠ¬�-‰^Ñs ¼¬MlÎøØ/"L ;gk’ðP›à(·@Œw¢†òE;ð1Ø!2úBS�0 »’:˜öÄV‚¢i�„rÇ 4Є–·§¤‡T ²)£+'O°uͲú†«E‹WâèL8¤Šô÷C{~‰³Í‹ù¬¦-dŒÅJãäc�週òoÂNKÔ†¤)eü·…º"¿£×ð )Œ…¡t ùJéšJØèJµßt@€pFª¹§jæNÒq› €ƒ&€ÕÄu@(™2™â´ÔЛèòk[R^•�]$4Rç!cˆåàrÈÚ­dO'°ê“TQÙ!,¸hŸpH®ÁU‰ö@ƒ³¬ R5LàiIùà-�Àz¡ñð)4C{ˆéñP²fÆ�RAàÑÞÈé>C%÷�bÊ—‚„Îb#‚ùñ€ä{Ÿ¡Dd ñ?µL�¡*yÜW/€i¢a÷ìÚy@;m—¼J�Öi°JhÌ4ÂÅWh`·4Àé•wi“£Í‹7çºOyÃ~ÅÑdµ߉Ìk[²Ø%™5ØáYÕ"çjà€Î3,xÕ¿7Œ*¸î,o¨òæG“»PïܹÀÙã{–ȉ—ÒI ‰HeÑ„“Us?Wˆjæa1À%:%‰è'òÅ!�€gˆwŽjÈ®÷!Ä›ºXMLÓoC°£iwZ"@u6O¸ÛÔܼFÂÂßøÒ¤â¯†u‘@   �¶Nôc�ü„²˜IP°nC–Æ %Œ¥Àìt ÕV§à¯’Ø'Ôê2L@ÇÅ÷ÁO“SÔ52´ÂýS¹{­Ì5åȾc‰Ït²}”pÀE •H¼®†Ä3¬v ÈEäkÏx£sðaDFýV'ß´-f%ºr%‚^€=ñr…`ååMÏ#Eú¾6Z`’òJR*›Ð̃ßÜ©£ÖЈ–oM°UNw•ü‰_•Õb–OS³Þ¦\f\èH{ÝF-¡�(/€™u¡Ðˆ+½¶¯Éx#<ûÀƒ`¼»v¡0>O„Ò3@0“…_UÜi¶ #o¬á§&4ýºû‡—3›ê¥€tËšqjs‘…hœM°3º{;˜|CT¬Õz°�È‘’ ƒˆ É£6Á[|î ;Ü}>AŠž^ æå¶¸{VÖt@Hçñþ?�À×ÁB b1)‡ æþœ¼ÅDœ©Ó,¸„Ó`iú§EªùWçµIÉà¾wuÔPÂæ¹Ž ØxLàJ‘+(ýWh«éDö/`$B Dã�~ñÃlP÷Þ’»Ú mÉöž°‹¡–C0Ô@C!÷‘IèÖ‹æß¶›4½`pi0=·[=$�±´±Ýš˜¥S…h^H„2i‡µwÚ˜ÀýÑ/Ðã£<ÍôU�v¹:M2à"œ–YÔnÉ”µïAƒÙÆ×45‚Ýzºy y)vpÞT?+ N¿Z .~ÒTtÍUð�@ÔÉ+À�Y,MLœß§ÆcHT‚æeµÛõÞvÂ0¤9 VQ~¬¾,…aÑæ À—˜�¯t,v—ŠVÕ ]‡‰¦Õ_’:x�­ Ï|3�¡CãR>“ ¯Ñ€‰v•o@Ï+áð¸§ý‡3j¡cú(YMpå~w‡.©»óöf)kÈýîŸÕë�Ïî×oüöy¼AòJ“Ó�Q.mk#éŒÊEˆuêc8è1¡çÒòy~YG�—ªÊ<ºLÒ¢!âƒR& Úh bŒ§)ÀTm‹if¥��׉tÒxô„-[`­É#UʥùJ5£²žü,µª=¾ÕJi�˜”Þã×Q@+ƨ�<úL6a5¥€‰ÁŽÁÚ¨i]{0¢:ÇaÑÐf຤ ÎZ‹¢‹ øŽd¡ÕÆDÂÜ,ü–cAO� ¡þj€²EÚH˲”g{¹k°tJ/ Ž R§É?¿†d+zÕ€sbA§èFíâ$$4 �öe€ŽïrË É�,Fçr]JE}Rp8Ñ1ÖÁ”Ä#ð'Ô_]‹F'fƒ2POØ5ILU«$ãNøxÀûiÜM±�“ŽÕQs3Id'û€¹ÓD£¬Ñ;þ3Ï‚¸»—™­Ô%ý*c�ãdF JS:rÀRnþò;8\:Fά’ÈuqËH$tÊ�j»¦<4?V? Ñ�؃·é”ê,�ÚuZ@cÇY `-��jpûÒÎJY§‰9Ä Ù0‹Î‚º�FJ¨T r7D»�šÇQŽù–·OCŸb4N$ƒš£*¦]0iò°Æf.€ÄĵР$mH*´¼ÈËŽSû Ú”ôÀNõÖÞW�"CUÍ;¡üåNpú¾J\´GQT8œ&‹C©ÊKEM%pYh›ßïÿF„î¯w{2¨‰¶Å}Y¤ê˜dk‹/,$hÞx‘ijò ÜKºb)—}{Æãêa~øÙkþ-f?¾%§Ð6E@�q+Ó‚®:ª‚ÁIñÝ+#)ý@Ê;úÏU!]oläJ¦óDúP". y‚͘4j¤€’nóS,žZ¬H£NÔd¼z>D�}ö+Dlp¸!—Ðb5ÊM¦yy ‰0‘Ö ²q îƒì`w°¨.4KL3â5½mÀ÷ðT¨”Œ+ÐT:mO3n¡ÒpÊ…¤~è ¦òÀ&tM‡5âuÛ-Tš]¼ùFj<xÔ£190VÛ™+k؈©Ã ¥¦íצ½ [jר�<~´…¬¨”V…Oµ«£y®ø¡?¨¡ér$êH+I=L5�ïƒÇÕì·j@Ñ?N•*,:ÄVF”Ÿò H·íæðòþ�ÆÀeð ö"´<)CÃyÙ¦º¨›~ *ÙÖA9Œ*}¸6�´àóª™ÑQ,�Ú­ –.¹Œò]dË/¡²Šúy{õ<®vÜ`a4äÊe>›¸U †vŠÈ®·¿µ=œ #±h[ÈßµÖ;}ÐÞn®BðxàëšßTË5mÔÀËp¸MüÒñ#õ²÷öh#лb¤ ç¾�3m‰èBÌÎè4¤£áQY31ñ8}vøœ tøvô Ìz…—§ MÞ –ŒI…¥o Ø¬wG‡‚LE´¼Ž�!lm½ ˜¡�¢*q�$" Z�«,Ô3å$bk•ëÀXt‡�›þx Q|�š/ N.ÑqBüiìñ|‡–´ƒÂŸ(³ŠDˆ†¦�r&üÊ& g‘cB­+L%…Å]5‚Öx¾êŒ QAv<ÛÛ5mosÝá´ ÓkÖk².¡}ñÛ›h#cö,ðê[aÖ©–Ë»¥€:k"+šP"ŽKb i¬5ÿæË.̀°y{¼a0æã¨€´c„L6a!¬Š�æÙj[hÄHÓ&Ìâð@ËÌ…¸ßúNRÖMÅ+` :97 ¥»L5ÒЗg†¹5Ì[·¹¯åJh4®£�Ý‚OA`âÔú;> Ý`[7æù©B9Ëí“L p?n.8'zÌ4©ÃM‚È^ ,#Ä¥ê` ’Gn¿–vf N2Ó‰HÎNÃ-D`|1å:OeÚ>†)!ÚdŽ.$E�× N)·ð]«`ðø6›¦¤51ÒÜQÞ�„›B†mt�(!Cc¾(j @2°ñÑòÑìˤæƒD‰I]nRñèK™2mjëlÖ;a5åhñ¤­°y¢“.xaÀ„$¢�4[F6Rð¶�â#¸H²‰À«:ãƒlÛT‰¨nè:"‘#$·[^Úö>b$œkÖŸœ»ƒ±×è˜ÄyÄÕ"2°R¦ñO„rùT&Ô¡Æ×œ/¦7`'õ—å¼ }Ím…÷¼Äv÷£ýg’³#V«BÅçD;|Äà^ܵ@¦ƒs0+ü­¡U4\$Ê÷¼S ¥“&–§R¦s �Úø�Lƒî~WhÉâ�îÊ&ðÌ@5Ñ£%CZèǃÒ):&Gk’ÚuŠ„î;ñ¾³ ð×í}œ¯ÙÍDŒê€)öïÐÉÛÊöò(ÐêÈ(”RÊ)›¦—£»]É^šý3ÏÔ^ Õ¥£D€AÆÓøZ’©=2¯jíâ…~è=Øœ^|§×젥΋#¥ƒÝ5šÚ »Œ\|û¨‘Î1d$Ä€ Úðˆ@V(†€-ÚèÕíÝÄË WXOÍ›7\‚Â?)Ý„x¦DšÆêh7ÌÑ�ÚŠÃ%em&£ ×AÉ4hx§“dp§a�ᯛ†X¨…±¼’£YG°Ô‚ü—÷ÛÔî´�€ vÐf:‚ä´ô…BH{ñ€F`÷šö?ÀG_kD\ì@n„à,rÊè_b,¨`ÅuisGçÚL�?毣„ù†Ì¼ ~Ô¡¾ %‘‚¨pG8ßnµà½ábö2xwaûê¢ÁæÒö+Eh²8[j�\%¨«Ð$/t„ŽJt8Wë:›Æ#KP¬D^Û4µ­+£¯!Ü¢�;‰¶r>cp cT(_�&GHhéÚ 3¨&Ò>)è8O=7a½ô]mÒJ§¾¶Îsáåû:»:$Ÿºxbʵ{§`zÒ�é¨pÖßèäõy‘£·Iä[×)€Þs')£š«VkÐé„,ØÄíh9B£ãÚ/¥LUËB@tƒéy™!¨¶¡„I9Mí¯ÅL¼ú®‘HvêÇSº˜0^G�&Zbl©“@ëœêv�e¢”¨{�<�ï­0g¡ãÑ~FÔwžèe Ƥ=ñ'"‘¶r�H‡2¯qéTw6ÖY Ö ŽÖªs-^û}G3üC´ «Üñ2ƒ(‘òq´,5ˆ°•Ž¥T;ÂDE?MÔÜ�´l¨C�ÉÑnÿóM.R@&`Š&÷¨y+‡€í, ’‡þèì²&ªöð«S‡<ÅEÓ�Ãø^ €‚å;!c+í¥óËáÊý²\šu‹ö ºå¨&ŸµLèP ?N'¡øIžÙ>çaÚé˜tSÜ©…7Õðo²iã á –"ð#Ï�¦Eù�&!*�uB¿Ž|‡õ¶Ž,¦#c’tÚJ›©xxí3Y×9$ßµXu®šG¡!ªüÞÄ›÷­ÍOÔ•�!�”Êj4Âó:Z­ŽWκ/u‡Ó(ƒNÈe˜ò:ÚX=­O‘Ñ6ŒX–ÒÐÙ5úOx^õ6bäéHÉ=_x¼f˜*^:fh*½ 9}{$á½KíTíLÍ¥ý aj7uøõíž…2a�¡Æ¾Ëw•û¸.ê�<Ø4óÖ[p°Q‡–D“˜åmC§g¡lÌãçÔ�BSGëñd�æC\âDU]_Œ�÷?vÞn*m=�!¿²“ôw¶††ŸÉç:r¶¥iê�¼±ïÐÌQ;¸ ]£Y´íª¼t†m&ÀÉgªf‹Ì"Õ¥Ý2tÈSk˜Õ··KMiCrhð¬-7àèhŠHË4ï5ÍM�j†æ[æB ¸ªó ¶IâV+-TáSoÄ„ i¨‘á–MvYBÃ騼öec†äó;'¤­1ìOÖ•B–~ŧ‚¿‰€ý,Ã}ô>1ƒûaÅð¶¡®NÒ^ lEÏ&õ¨®‚ßÔDaWÔ…¶uÁŠF“ñ¨Ïzyó”¯Ó‹KRBo¶Rù:çé½õ�]Ú»ñÿäÓg ÉcbаUû"y¬wÖ�ƳwòU¯I†ø®S-ÔâHê5$�_¯ÏÑÉwŒH)½Þ]†[DÌ£Ft¢Mg6Â÷tž è$f…1=%3¦æPuïX¦šqs—.Ȫ‚·åäé¬ôv/5ê×¾h.Tvb0³¡ìu?ÿþ Ø„¿~çÞ€ÂéH<•�ë+'@01¹¡(¾S´°$Z] ' ²²„U��ÐËëÖ ©,-TOSd)¿]t€BûNNAï ÌU4Çç1³<à÷ù|ßÓðš¦øp�†Ò™H/½àÒu›ª7 ¶Ð£cD˜\ ÚÀ8|é-ë:$+e©hU›Ù�ÂÍIÎä\÷¤§†î¹ã¨kÖP^‡Ï�Ñd £¤Ð8Ú•Ó‘ƒK[b�ç~{d“›°jjõ˜¹ “Ìr‰1šv¡ªÎ-s[⢽�uÞŽÞ[ºD_/Ò¡3Ãëý"èÑÏÐTï†ù~' ôÞ‰HêÔ7VpÓÞŠ<†Ž{ [„Å:õŸ¦{g˜AÞ«c zˈN5íͤ©w¢ð�-V¡Ò±Ko¤Øé¸cO "«œËkÚ<0ÚªÐë­:ä_êñ7¡ów?1Úß.pƒ„ž}ä 7¾¨õ ¶�Ýý‹!Ü¿úÙýú íüõ 3FR:ò|^CØüá9yž¼tX–ÒÒĘª«êˆžDÓ ÊÁk²ž4�C—оðÖyØ…�úBNm½35¨®4ƒCCZ—W.ÖœXøTÒi:ÑÞ¹J¿Ž¢iºRŒçÕ;ò´±NÖ›/€¶fØS˜U�£knKÀ>ÿâ[Gþô³ûwñÿàB!Äìþo¦ö„™þà„iCCPICC profilexœ}‘=HÃ@Å_[‹"-ÚAD!Cu² *â¨U(B…P+´ê`ré4iHR\ׂƒ‹Ug]\AðÄÕÅIÑEJü_RhãÁq?ÞÝ{ܽüÍ*SÍžq@Õ,#“J ¹üªÐûŠ ¢ˆ Œa‰™úœ(¦á9¾îáãë]‚gyŸûs„•‚ÉŸ@<ËtÃ"Þ žÞ´tÎûÄ1V–âsâ1ƒ.HüÈuÙå7Î%‡ý<3fd3óÄ1b¡ÔÅr³²¡OÇU£|Îe…ógµZgí{ò† ÚÊ2×i!…E,A„uTP……­)&2´Ÿôð:~‘\2¹*`äX@ *$Çþ¿»5‹“nR( _lûcèÝZ Ûþ>¶íÖ x®´Ž¿Öf>Iot´øÙ.®;š¼\îOºdHŽ é/�÷3ú¦<½ú×ÜÞÚû8}²ÔUú88FK”½îñî¾îÞþ=Óîï<1r‘è üØ iTXtXML:com.adobe.xmp Ö)â pHYs  šœtIMEç*×üj! IDATxÚì½w`\iy.~ÚôÑhFS5E²ê¨ØV·×ë²›Ý%Z �ra7¹ %��_7’Ë ! ?BX , !°aY–²k­½¶ªmYeÔ¥Ñôªéå”ûÇgŸ9+Éòhæœ3EçùK’ÇsÚwžï­Ï S  @À+�·@€5 @ Ô @€� Pƒj @€@ ¨A€5 @ Ô @€� PƒÔ @€� Pƒj @€@ ¨A€5 @ Uˆ|>/È‹  � ·à‚¢¨x<‡£Ñh2™L¥RA€BQT*•* •JÕÔÔ¤V«DØ?Ž#`a£8VH§ÓN§Óívg2™b>/‰L&“ÍfS©TÂݨA@}’ÂêêªÛí.í‰ëtº®®®ÆÆFáN Ô  ~܇õõõõõuÚk8Ø·Ä0‚ Y0 [­V»ÝŽa‚*Pƒ€G&“¹yóf$ÙówEõz}SS“J¥R("‘ü� ˆd2 "�@ —Ëíù�r¹|``@0jPÈÅbSSS{^o¥RÙÖÖf2™P½¯¹677Ãá0óï‚ �Fá Ô  ö�F§¦¦p§ÿ"‹ív»Ùl†aøH_ …’É$Ó¹8yò¤Åbî³@ j ‰Dâúõëù|žþ‹^¯?}ú4í8$I:Ž­­-&;  án Ô  6�Ïç¯^½šN§é¿´··www—ÿÍn·{nnŽ^3(Šž;wN©T ÷¼þ T³Ô!nß¾Íä…®®.Vx‚ ³Ù<44Dû#Aܸqãðć�T¼^¯Ïç£miiéèè`ñû C?ÓsY[[n»@ ªA,--Ñ¿ªÕêÞÞ^Ö�bµZ­V+ýëææf*•n¾@ ª;;;t4‚ §N�:j2¢HôööJ¥Rð3I’‚á Pƒ€êEQô¯'NœP( EQ»ÝNÿZ|S†�ð�`0H¿Ÿ(Šž8q‚ÓÙL&:7AQ”Ûí�@ ªÌ—Ól6‹ÅbNÃpKKË�G Pƒ€*B(bRG4™Lt,#‘H>…@ ª‰D‚Djµš‡ƒŠÅbæ�ö´Z¨A@å�ÇéŸÕj5G‰‰ýhjj:ðÔ  *Àì}â³r™y,æ9¨A@U ›ÍÒ?ËårÞŽ+“É<5¨ 0C€|ª01[9j¨'J^µ Ç}>ŸÛíf¦'x 4ì9V&“onn¶X,LkB€@ øC8ÞÙÙñù| ñ† ýõ|¶B2�… H2™\]]][[Ójµ‹Åh4 Zõ5àÉqp»Ý;;;tG“J¥²Ùl‰D‚ÖYáÓ°gK­Vwtt¸\.ŸÏ ƒÁ †aÍÍÍf³Y£ÑÏN ìƒ$I¿ßïr¹‚Á °¤R©Ùl¶Z­ 踽½M˜ÏLóXr¹\«ÕjµZÇ=�ÛíŽD"N§Óét*•Jp¶\×h ¨á¸ ‹¹\.·Û ÔÜ1�f³Y¯×3ý|f'Õîî.o§�FéŸéD&†a6› Ø2ÀÆI$ËËË+++MMM6›Íh4ò PCý ›Íz½Þ��ºŽH¥RY,³Ù| ¾#(sE"‘Èf³‰„들(ŠY¹¿S©Tvwwwuu…Ãa§ÓéóùB¡P(†b Ô àÈŽC0t»Ý>Ÿ¼ç‰Äd2Y­Ö†††Cþ#Š¢���ôîñx¸î¼„ (‰Ð± Ãî5œ†aàhäóy¯×ët:c±˜àhT9ÙØjm{ƒVAè ‘¶÷ææ&-ñ¤T*/\¸Àõ9ߺu‹n¸´X,§N�âíbÔPç`n¤ô[]ÚFšÍf_xáú�sªŸJ¥ÆÇÇéÃ���iµZ~L$5Ô-€—ît:ý~?I’K3©oÞ¼éñxÀÏ …âüùóÜ•ÌÎÎÒú´J¥òüùó%oøVl6[ss³0_S †ã‚d2ér¹\.ðÒaA{ƒÁPþkœH$®\¹B?Ó®®.vå¤iøýþ™™ú×���æææò¿Ä <º… ˆÁ`°ÙlGµGÔP3Ø_ѬP(,‹Åba7•0??ït:ï<]cöM³‚L&såÊz4–Z­>{ö,‹1PÄát:é{µ§ˆC€@ õà8D£Q·Ûív»AM1†aƒÁb±p´æóùññqZÖE,Ÿ={–EýØ|>?11A[þ0 Ÿ;wŽ£äžÒO†ÕjµÙl6›Í÷�å+@ †*XÖN§ ’âsYƒÁééiúÉJ¥ÒÑÑQVDr¹Üôô4³¤Ên··µµÕ½ ¨�}öÃ6›�Ïfĵµµ••úW‘H400 ÓéÊ dÌÎÎ2+£M&Óàà`e�2¡ÑS †jÇžŠ¢z½¾‚!´ëׯG"æ_Nœ8ÑÕÕU‚ÍBQÔöööòò2³ÏR,?ôÐCi¬L&“�ÇårÑYSS“Ùl6™L‚£!PCu9û[!+›xËçó—/_¦#…4¤RiGG‡Åb)þ•öù|«««{tAQö™3gX�q‰°Âá0hôœÀB£§@ •Ä}[!+‹ÅÅÅ­­-­V«Óé–——÷à3ßL’�+„‡d&Ká$$Ã� ĦCÅ"X †##—§^ZÈ^wdgW³[~'¨}Þ/dÓaC�â3Ý’K§¤2qYwY¨Ÿ9¶à¨J '¨ëKÙkŽìôJn݃ç÷-`†ÌZt¨]2Ö-~Õiiƒ ¨á>Øòã_ûiâG3™DºØ@ºL ?<(}ûÃÊnËÑ‚äBÕ­kÛ½âë?K<;™Ž$Š]Àb ¾xRòë+ÚÄ5_„øÌÅžŸI“%� C—NJ?ðf•M�Ý×q¨Ë^�ÕÕU£ÑXÁp`6›]YYéìì”J¥5íh”ÖM�Ÿ{&ö½kéýFn‘í’|ðUv«H ú]…¾ùbòsß�¥sÔ�ï¼Q�5¨L #”ÉQÞ0á�2ˆƒŸ|\ùÄc ×q‡/HXŠD¢‡z¨R×277çr¹š››júf–°yü÷Dúoþc7–:ØRЩP³•‰a ƒ3YÒ¿KºC8qÐgzÛ«”ïyCƒƒ�;5ÄÓäGŸŽ¾8·7…¦oD‘=Ð#hË%{oS&GÍmæ®-eŸ›N{Â{‡¸�tI>ñN�V…Ü�Õ¹.EQW¯^�Çã<ôG¾åŽ��QÙÆ QŒúN6O}â[»ß¿¾·–¼Q�<:,;ß'l«ä{wªN-lå¯;²ÏM§·üøžµ[Eõ¤ÆªÃŽ/5v‰÷üCxÕ�ßs_žx\ùðiY1í?]YÈ|é¹ÄÍ�óï-úÿÿžV-I51§Ó9??/—Ë/\¸PÙ“ ¼L�È*Ľ4ûd º?øçèìÚ+Ö^«{×cÊ׌ʊL¢M¯d¿ü|âåÅWÌ"lj@þþÝÚ^›è8RC`—xòÓAW°°ç«äÈûÞ¨zã99rôEõÜtúo¿³Š¬4¥ÿ­s«:E‚ �Fc±XL&Sýi�â8>>>žÍf‡††ŒFceO†$Éñññjk¬`Ñ: .—+�$™É#O]ïtï+R1ü;¯mxÛC ìè™õ+ ÙO~;Ê|äøóïÕõ·ŠŽ5$Òäo~&´â*Ø §ÛÄŸx—Ƥ)ÝOÇÉ?ýjäÚR�}µŠüŸÿJ¦¿Û\ÇÊå‡cccC£Ñœ={¶ÎÇçóÍÎÎVac‹ÈçóN—÷OžÎ¯ø ¼ÐnÂ>ùdS»©ô½'™¡>þ¯Ñͺà4Jä©èZ •ÙÏ*cþÙ×£L^xè´ôóïÕ–Ã Àû컵¿x¾>%EO½¤U(ê–R©ÔÖÖ ÃÕÓÂ`4u:]>ŸgjLÕD"Ñ·'UL^éùƒºrx‚ …þ‹wjþçÏ–k$A~è‹áL®2v=ú±�}ŒçCþûxòéŸ&™¼ð×O6‰ØÉÂ0t±_êß%–œwxÇ&é’ÔåÍårñx\«ÕV•õ®R©ÂápKK ‹ZµU…ne>õŸ1ú×Áñç~O+— ¬,àÑ. IA3«9šv“äÅ“ÈóíPcÄ/}<@W4õ·Š¾ø~»E£$ ½ïó!:®#Æào~X_)«Œ!Tmòg©e©_þ¸ß½°é±¯þ¡n¢L|ôéè3)š/žú€Žÿ‚(¾ŠÏ}?Nó‚R†|â]M¬“#ô~C£SÝy[r8ÅäøúƒÀ |â+Ï'h^¡ð_¾KÃ:/@ôÇ¿ÚØv×=¡(诿½ËH�WjðFˆg' Q–ßý…‹–“e­Q"ðKÑŽñÛÚÅ  d$Òä¿].øÂïxDÑÃM~Q&†ÿ×[ÕtþwÑ™¿úÊìf½QÃ7~–¤[MÚLد\àÐ}lX6ØQ°Á¾öÓ„°²”‰ï\MÅïÚ¼M È“�sáì?2Xèàøê�uK  =;U({ç£J®Ësžx¬ðä~v+“ÊÖ‰2…Ïçµ75Y]]=D0¦¶ð £êñ×_­”Šaް’6fV³ÞQŸÔ0µœ Çï0®JŽ<6ÌywヽÚaÉä¨Ësõ°@ÓéôÍ›7™£ëª‡cuuuii©îüš_óÜ)jÆPø�ç8¯²·[E§Oܱ|I z~&]ŸÔ0±\Øè”òÐ@ÃÐã#ºîÈÖÁ]ZZ"IÒh4Ö„äT{{;Š¢^¯7×ú�Ÿd,à³=�’�wçñQÙ�oP]QÃìja—{ÀÎS¡Á=…í©u¯ED"ŸÏ‡¢hWWWMœ°T*moo‡ haa¡Ö¥gV o湞 ,àk¹RõÀ«›Ö½…³�vžv¼S'ÄèÝKtñl¾†W'EQÀ2ooo¯!M„¶¶6¹\žH$œNgMSsŸæ«Ê Õ€55ÜYÁ©,åá1ÜÀ5„ã$ÚUHa}#O©x±nnÂhom'HÔîÒt¹\»»»R©ô^RÑÕ Aìv;A+++59$ íÚQm3ñWAǬÖsðz£†ÝdÁ2ªQ>v™­‘D­RA +Án·×\�ÝX±ººZ£÷?•%é¼»RŠì×ák“õF ©lá’äR^‹)ÒÂSôøwkÔãM§Ó(ŠªÕêæææZ<ÿžž±X\»-°¾Pœ±€a~pá}Ifø£† tðür2�¶¶¶úb~õÔ–Ä“R©¼páBíäJ¥ò¡‡ª¬ÒL Èårn·Ûårí2Ô»Eñü¾ðinóD ̾´d†×[›dT:5*D™Llmm Ly®ø¨û£:íµ«È Î¿VN•žšé÷ûÁ”P¥TR‘­{ÏVH�z£5# ì�Åÿy#…ÈÍ¥‡ôŠ;ªp±Xl~~~qq±.UᔆýÓ AÏ»Noøøs¾N�½-‘&•| �`AòSLÁ+5h”ˆJŽÉÝT–òE‰2…[ŠD6OѺ²Ùt¨X¤êïïïíí¥µd½^¯×ëfœgà8îñxŸfhÓ£t5ä†?u‚§ü妯°·µð¨-Àß‘:š1ºèèÆzî5#|Œ�¹¹^¨±é0ºL6™LLúõõõ���ªR �Çãr¹¼ÎÚ®)Šr¹\Z­¶â£€Ô•onn>pšaG³ˆ¦†›ë9~¨aËG…¬¿QƒÖ!5 wJhj¸¶˜å‡˜B½Ã�ñú³²û‹v#¡/ý¨P¦òÈ ìHFŠB¡èìììèè‡Ã.—Ëçó…B¡P(´´´d2™l6›J¥âôv9‚ tzë'Nœp¹\‰Db{{»µµ•kÇ�žfAHZ—KzýYù’süü¯/$í!§yŠþaœi2ðÖ^À«¢tG3öoã)0í/–"åd�³>«ï_O}{¼ ¼ùçïP75ùÎÂ0,—Ë�FcKK‹\.Ïf³étì?^¯Çq…BÁ…�F—––PªËi0 Ëd2�dz»»kµZY¿‡$Iú|>‡Ã±¸¸ …òù¼T*mii9uêT{{{ccciEfÑw®¦€ú{6OåpêÁ^®vòkKÙüï5|ä­j ¿£îx¥¹ î’ Ûwl¤[¹WȸHÕú¢Ä=¡ünPö«¯*KlEÑÆÆF›ÍF`%“Ét: …¶¶¶¢Ñ(‚ …‚EÃxvv6›ÍvttT| wP(»»»ñxÇqƒÁÀ¢ã°¾¾>77çv»S©‚ F£±»»»¯¯O§Ó•ɳ"Æ jrùN4}a;Æ.á" O“ø§p<}g´‹÷Te:QŸyw“ˆ¥ IAÿë_"ÏM¿ÿ&Õ;á*ÏÄÑŠÌçóÉdR­VCõŽ|>_Î�┣1õßû!òî{Óc}á}:{=Wýï»ß|± [ýö‡•x³ŠÿGS™™—ýZ”©À9Ö-ùÛßj*ÿææ ê£OG™¼p¾OòéßÑò� ŽÅb.—ËívçóyèîTn³Ù¬×ëëiftõ`OE3‚ Z­Öb±�Fnøg¿£êõÚDÿnmù¶EAŸþnŒ©~Þß*zê: jÈä¨ßþlèöf¡�°£ûäMå(dx#ć¿¹µQøÎFôËÔs1Aä�MÌï÷»\®`0n¬Pͺ•áõz�Ng,vgìÐþŠf@�Ðþ)te¡P�dnBÿò MkéçI�ÿûéÈUÆwÕè—?¨ã³²òÔ‚¿ùé STK&†ëç~ýÕGžANRÐw®$?÷ý8èÑh”åÿ÷k^=RyUvsf@+$È"ƒÂ‘Hd2™*•Ü¥(êúä�O>£ÜŽÂÛ ÿÆ#Š'o(¡–ï‡ÓéO}'Œ:©È?¿_×Ñ\±¶`¸‚Ò&»Iò}Ÿ3m‚¬:ì]�)_;*+fàNP?¾‘ùÒsqº¸ Íˆ>ñÀ‚‡Μ9SÁü_ñ•6¹\N$gï# Éåò=U‰tífÃ0ϵgò­[·<…H¾ï軾ü é0ƒ}ÇÃÊ7=(/&¸N’ÐK ™§žKìy Lô³¿«m7UR.®¬êQ:G}â[ÑÿžØ+°¯”!HÏõJ†:Äû+=Âqòæzîš#ûãÙttŸ$Ö«NI?övµÃ'&&‰„Z­­¬(C1õ¹×®]£(j``àxºÛÛÛ tcŽãtÅ:ø¨X·X,/¿}ûöÎΆaccc ¥êïÿ+þ�{^#©~è”ô\Ÿd¸S²?;K‘·6r×Ùçg2�ݽ¢„Ã�â¿x§†ç§ª£€g&R÷�S?rM47¡r1 #P*Cy#Óq`B.�ïõª_½¤[o&“™˜˜H¥Rjµzll¬,ùý]=`„ hnnN,_ºt©V¤eØE.—»|ù2Žã===Éd’Ù Yñ>7&¶··Q¥}™Ë·3ù­]zLîÈİY‹Ê%†B©,å�÷’x‹àw=ª|òñ´ Toà*ÑJŒ&ÈüAü¿®¦hqÎ#A Ÿ•½çõ*ƒúï:�¾~ýz&“9yò¤Õj­ZφaŠ¢ÚÛÛËÏð×(2™ÌíÛ·ƒÁà�u ÃUÕO»‡/¿ü2‚ ###MMMÌJe©§ž‹ëÅd:WʆaèU§¤ï“ªE_-\U2ª¾(ñÍ’?˜L3ã1‡£Q�<>"ûµ‡¶{ÜÓd2é÷ûÛÚÚªð} "kkkôTÈŠÄÛ+�ÓaºZétº¾¾¾êt¬Àˆ {5ŒFä¿�'Ÿ¹žr…Š]À )üÈ ì×RtYª«"®B…e’„¦W³×Ù™•ÜšO¤ÉýŽC› ê�œµKÆìâŠd}YÜ-ÇÇÇ ‚hnn…B´îXSS“Íf3 5'µZü ”øp‡îV‚¨Tªååe Ã.^¼(‘HjôÒ( šÛÌ][ÊN-gWÜø~ÿW,‚ÛŒØP‡x¬[r®W"Uㆫ_|='Ãq"‘!oÏÍç³±þnÛ™ÁŽºyCæææ\.—ÉdܯV Rt<4zò†l6ër¹ö§uiýÞééé@ `³Ùúûûëã’W6|W§IXÜr Q)V+}#ŠTývV¯¦Ô™�hj¿víÚn`=�6—¦.³8—Ý÷Äãñ B @¤T«Õ2 {œN§ÓéäÂÑ (*™L‚V1ÇI’„aÃ0©TªP(”J%‹Ëþb0‰Db±Xöƒõôô„B!Ç)Šª†Tnù¥Ü§ÃØ�éëkoiQÔ£Áµ5²åæÍ›�ì±¥}C:�žœœÔëõ½½½ÕpEÉdrww$)öƒ‹r`ǽ^¯ßï‡ÃÀ˜? ÙÔ`0477—cÛ—p étºJ„­¼^ïíÛ·‡††JÎ�¬¯¯///+•JÞDkŽ)5Оù™3gö„ˆ‹D0œ™™!I²£££VæM³ÕD¤q=H‹»D`X¯×···©Ý«J*šË�Ïç»qãEQ===¥Í¥3²£££}¯ƒr�ÞÞ^A‰»;|.—R`n·»|v£(jii ‚ ŽŽŽÚm­j[ŠÁ``kKéïï7™Lù|~rr2‘H°ëþ µµµqªV´¶¶FÿÜÐÐÀÝ8I­VËìûX__çÔpá’x€Å$ŽãSSS‰D¢¡¡att´|¾v:�ñx\.——VU-PûèééAÄår•ïÀ0|úôi½^ŸË妦¦èÆa¶^'NÇ^g2fDÖn·sëîî¦_Ôd2I 4qvë¬ ‚˜žžŽÅb ÉR~'n>Ÿ_]]·½>$6êáärykk+EQ‹‹‹,ÜljjÒ’Ö W'˜V±J¥âºŸG*•6773�^+7 ðB$‘J¥ccc¬ÿ+++¹\N«ÕÖ͘Ò:QÞ]4ee�‚H›Z­Îd27oÞ¬•›àóùèŸùÂd…–Ÿ©~8Žp8,•JÏž=ËJŒ6‘H8�N†Ë©Í¨�`bÂËËËGê8>œt:]­h á8Î,F2™L<T£ÑеÞAp”Ù9Ðz§Õ4K@gg§N§c1§»´´DQTKK wƒ6j(f³¹±±1“Éìï&* "‘htt´Ì‡½µµµ´´tˆb [ØÝÝ¥½‰††Þ4˜Pœ8Ð…B—/_žŸŸ/ùÄbñèè¨BÁŽæ’Ïç ƒt•�@ U:‘¹±±Q%‚\.·²²²¹¹ÉÃ;Ã̧p‘°¼˜…=Éd’‡#²ÌŠÏJ�$I‡ÃAPWWW•¨ Ôpð25›Í$I‚ôrű²²‚ã¸^¯çAᇙLak?,Ì v:‡ìù Ì|qq±âÑ ºŒ�ç¾~�ŽŒîînE}>s®[p:�SSSE.ÇD"±³³Ã0§ Kf¬�ùòðvÙáýý}™¡µµõHU°‡c~~žõÊ‹l6 ¼×žžžúVZoÔ •J�¦Ûââ"»KÇñÕÕÕ`0Äãîûyš‹˜‡ g_ù÷Ä<+à#9�ÅTÁ®¬¬lll¸\.Ö+\ŽãF£±æt�#5@ÔÖÖ&—ËA>‰Å¯Å0 ÔÆøýþû²ƒßï¡)N;,÷¼-ôÏ|6Ú3m(>K}è*XбvˆÁ¿¶¶*ÙØ-š™rAø± j`ã’î>­••vM܆††±±1‘Häóù€xÜ�£(Šÿг•“7Ã~�#ÃópJP{ˆd>HÁ0|êÔ)Ö³¹ ¾ìC5Ô €�G×®²•J522‚a˜Ëå:$ÖÞÞ®Õjù M1}~>4ÌÐ#[zvEB.—�ŒŒ\¸páÀw—ËÞÞ¾¾¾{�ù( *Ÿö^j¨%€ÈÐöö6ë¦Z­FQtgggccã@ÛÞb±Œ��ñšbf%X¿äCÀLšò™¡ÝŠM•P(D+úúúX'hÚ‹1o�j ŸD÷ɲ‹¦¦¦ááaµZ]=ÊLG:�òn‡ÃL‡«Jî†F£1�ÝÝÝêâ—‰õõõl6 2åPý«ãkëêêòx<@!Î`0°¾_555UOÊJ¡PH$®Çq<sÚý �Ëå˜ÅÑ<±ØA¸x:@ß�N‘Ô1�:¾6Ž☎CU]/3…ÆO¤ÇãaözVvbI’Ì1<=°–@U¾@ 5 ÐñB+yrŠ`0¸½½]A…n¦}ëñx8RR¤AQ³â¨²Öu,{é¥—æææ8= °@é^>�jtŸ,[ q‡¼'7oÞ\XXp¹\•ºØ¦¦&º•�$I¶ÚÌî·ÛM§'aj7ðÇÓé4§�u¦ïvÜ©8ÀF£‘ ˆÃkcÊÄüü<¨&¨à¨"†™¹4.²34òù<¨Ý°X,|[âñøìì,°×¸k¬÷èAÇÈq¸H Éår¹8ê€Ìçó´ŒÊžÙ0<Ãb±Ð†EQ·nÝâ¨xy~~žvìQ­`z?•JMMMåóyƒÁœG.&VÐ52 ÎJ †:­äÉQG&(»ÔjµíííEÍÎÎr-”xÏlj Ì ®ñx|aa�õ£lnnz½^ú×ööv>'†2‘Éd&''³Ù¬V«äÎy¤1ë©.�* vâ˜`Š�D:I’³³³Ì„?ŸÐëṏ ËåbZþ¬„˜_¨R©ÚÚÚ*Šׯ_O§Ó�fxxAà<Þ·±¢äG\÷ ËãH ôÔÐ-Çâ7ƒK›Í ~úúú, A333ìÊÕ�þþ~faâÆÆ[-É[[[sssôWa688XÇq ê«V«GGGéªDà<ú|>f"³L€.^0éøPú±�}ì˜\ªJ¥ ƒ@‰ˆ­âŠ¢Òét2™¤W§Á`H¥RR©Ôf³U¤öA½^ït:éw8‹…Ãa�NWr”” ˆÛ·o3 Ãa®TzA‚ r¹ÜØØó¢D"‘R©´Ûíl…E½^ïÆÆ#RÇeÑûQÓ²KGìI’ܳs‚»ZÁš(0¬†_ñ|1 ëììlii9ê>ïõz—––ö+µêt:`ÉWê2÷ßyÖ¿||<�N÷÷÷×ŸŽ“àP¼Âp qìºßûW' Ãä…µµ5À ===Ì!ŽãKKK—/_ÞÜÜ,ÆÞ&Âív_½zõÆ�L^À0ìÔ©Sb±8 Þ¼y³‚» ׬tF¹S*X U�\.wùòeÇGGGëRœgkkkqqˆ—477çr¹¹¹¹ýùT†›šš´Z­J¥R("‘Ã0‚ pO&“ñx<‡B¡ýq™†††ÁÁA…B�Ç'&&òù¼Ùl>uêTý) e2™ññq‚ Μ9ÃΨ¡n±¾¾¾¼¼¬T*ÏŸ?ÏÏ‚Æq|qq±»»›ëº ��ÐŒ¼ÇÞÞÞ._؆ᶶ¶ŽŽÚåŽF£SSS8Ž[­Ö“'Orí;,,,´··ÕÄq¼´Ë­[·Ün·Éd„ŽŽQ’Fcc£ÇãI&“‰¤´(Z2™ÜÝÝ-^žPƒA“ÉÄ](ËívÓ"{š‘­V+I’‰D¢„Í†áæææ���ææf¦ /•J5�×ëÝÝÝÍçóz½ž£Kuè�'‰ïó§R©™™¿ß_BG4]\\Ddxx¸ÎTäj8l¡K¥R¯×�F­Vk ïêÜÜÜêê*†aÌ) ‡@­V�D" ›››¹`ŸÏwëÖ-Š¢º»»œÔŒ¢¨^¯·Ùlb±8—˙ۓJ¥---'Ožÿqÿd2™Z­7“¢(.ú²AY§×ëi‚#Y^+++‰D8MG:â�7²Ùl{{{Ý̰¨¡((•Êh4šH$‚8ê^ …VVV0 ëïï/ÒREQÔd2vˆD"&“‰Ýø­sÝÙÙy¸P-Š¢�¦¥¥Ål6ƒ!W4O‘$‰¢(HþiµZ‹Åb·Ûív»V«=¼ÛZ.—744x½Þp8Œ ˆF£a÷a› ð±±±#Yy(Š¢( www�”Hv¹\N§S*•VªjCˆ5T‰DâÊ•+=øàƒÅËQuõêÕxŸ7™L`»®†[jµZÁ.=??ïñxÊü6ƒÁpéÒ¥ò===(Šz<žûÊð¹‹ÅR÷ún5Ü -ªH…8‚ hµ”¯¡˜L&�H�ÑhäHµdœ8q¢³³¤ü~ÅïA2™¬¿¿ÿÁ<¼y<  úºº c�ㆤ‡'&&P½téÒ}c™L†çA,½×¯_Ïf³oa83øVWW·r¹ÜÄÄD2™s7kB;Ì›Äq|rr2‹òIº‰“Ÿ³{žòòò2Ðw« ßG ^ÑÞÞ.•Jc±Ø…8ǹ!I‡AÿÀÏà8>55•H$èiÝ5qWé)Õôùø±P(4;;K’dkk+Èq‡\.lú/±XlggGHX Ôp0¶¶võêU.DŠ™ �KKKûë…‚˜žžŽÅbr¹|tt´¶º}@{¸^¯§­ž=U[AX­V^N†ƒÁ`0¤³'@¯µµõXé» Ôp˜Íf�F“ËåhÞV./²�ªÐeK LËðB$Å”µ8ä)t:+aîØtÕ(—â{ƂֱX|xï‰@ ǽ½½0 onn‚Í ”BñVŠ�af¶<�¿T*={öl¥4ÝÙb‡¦¦&:ÃBÿAºÈšŸ“¡‹YÖ××AZª««ëxv^f^ u {077çr¹ É'Нw`©T ÄáÀH ¿ß/‹Ïœ9Sæ.ˆG©‹³gÏ‚r¦t:-•Jy®ÚŠD"ׯ_G„$I•JuîܹúS©¬–a·Û1 óûý@…ÿ‡4/€jºá‚0 U©TÉdTyC$“Éø-5�^¯ÕñÀRV¾@ ÷�X,Ý»@0¾R0 ð‘‘‘z �‰D¢ÑÑQ¥R�ǧ§§Ù� r4ƒù.ì�Œ ¨á>‹F«ÕV¤|`aaaggˆQL½P­ ›ÍƒÁÑÑQ¹\¤%9šÊy8¢Ñ¨ßïÂß«««9�j ¹\ÆAä÷ûY‚T$Çöö6àE§§§§¦¦¸®­àíÞNNNÞºu+ �9sF&“Ñz|žEQ‹‹‹À[T«ÕÙl¶øBu�Ž/@]ƒÁ`Ðét´@oXYYÙØØ@dpp°©©©¡¡A¯×çóùÉÉÉJ�Éc 8ŽOOO' …B¡×ëé\l(â™\.×îî®T*mkk³ÛíÐÝyÂâ¨á0;Óår�âe�²Nü}sssmm�®‚^Y/455Ås[Õ»»»@Ìä&ärùØØÏ£np_YY� Èn·£( ÔœH’dw‚®@ uÚÎeüJ¥²¥¥…þ#רÚÚZZZ\`2™ O讑ÉdÀØå…«¶”J%¨ûöù|·oßæ�VWW÷軎JöÂ[ PÃØÙÙv&­/ÚÙÙ)‹Ãáp‘ q嘸€€úúúöK‚¸ƒF£ÙS/T`Vm�øÂž444ŒŒŒ`ær¹æçç9=™T*µ½½½§]B*•y~þ›ëj¨äóy`g±0ðGº¨vqq‘» 6=Zt1øE‡‡‡U*Žãe¡âßdÈf³b±xllì^-•jµÄ\wvv8µÑ€¾›ÕjÝSÞJ7ו/ZW78¦s(öÃáp„Ãa�F³GßM¥RùýþT*…¢(ƒ™£eBQÔh4677×V™˜Áa2™?mFÝÐD†††ö AD$ùý~0±B�l¬†;H$N§†á¾¾¾=ÿDÿq}}½HµòâA‡ß:;;‹™’ ‹�4…©JÆÞÜ÷cZ­vpp†a0é›õ@ÒÂÂp,o5›Í���™LfccCx#j¸ƒ……Š¢ZZZœU£ÑhL&S‘jåGÚÄ@Òè¬ O‚ ƒÁ@KW°ûŠnmm%“I¹\¾g(sˆ�� Ö÷�j@�P,ò~‚‹ ql�–ñûý<× é%•Ï£¥+XuC—±®ï¦V«¹Øj¨IÐë »»û�¶\vƒØl�–ÙÞÞž™™á­" H¬®®ÎÎΖ“k o [£nVVVÀ ïûê»�áCn·»žŠÓj(kkkétZ¥RY,–Ã?y/…¸£‚ÅÑ2�TT;lnn®®®Â0\f‘6¦ÊuCë»c�Éd2z¨áø‚žLÓ××wßWEQPT»G!îH`w´ ­éõzù©º¯ª¶N�:UþÀH¶FÝÐúnEFpÛÛÛ%I4=æ‰ÌcM ô³"õÝš››�BÝuT&š˜˜£eØ9E«KÓES¥›3i’,ƒ[˜U[f³™•7Eݸq#pHÚ Ãèq‡Ç¹#;¶W Á³#�Ÿìíí}ùå—·¶¶¬Vë‘òˆt!£F£aw´ ˜I1==½½½ º?îû_H ZÞÉO­dç6ó[~ÜÄSÙ;¬ Á& ÚjÀúZD#]’Sm"z £Í»Ý~¯ª­ÒÐÝÝM’äæææ�7FFFŽTZ $í)d8V«ÕétÆb±­­­b’Ê5ÔH’[ܽ²Ü‡ìÒ‹eggÇáp ù¿˜£e¸!&YÍÎΆÃa‚ ù~w˜øÏ+ÉL¦½‘ƒ÷ÃlžÚòã[~üòí ÅÈ£C²_::ªÓéŠùüÄÄD"‘P©TœŽ�…B*•ê^ßï _øAüÙ©QR®óÁ>É»_§êk9øË)Šòûýå ?EÍÍ͹Ýn‘H466¦R©Š1ÓÆÇÇ ‚8sæLie¬333~¿ßjµžȨ&–––‚hnn.¹¼Œ;t¹\‡ÏÝŠú/�ÆböüÑÚÚº³³“H$¶¶¶@®ë^¾nÅGËø"ć¿¹¹¾W«J.�앎v‹{m¢¦’ßÙ$Ò9jÛ�¯¸òS+¹—æ3‘ÉŒPüÇ•Ô5GöïlêoåûZ@»:A�@`bbâìÙ³‡Äz"‘ˆ×ë¥Ç•P:¹¹¹¹´´tæÌÁ¡¨s•qE/\¸PÎX‡@ 0==-‰.^¼„Iä… Ž� (jz)òá§sáø+L…vöŽG”�ËdâûXL8A]YÈ~í§‰™ÕW0‹ƒÿô­²ÇF”GŠí±‚bî*EQ×®]ÛÝÝíìì,³=ŸÏ���çr¹¡¡!NÍ¢*Äñ꼤(jff&—Ëutt”ù¤ Åîîn<jq{þˆ„B! RÀÃ|×ýWú�/þïo‰Láýoj@þø-�òVu�­¨¼‚À'ŒØ�vˆç·òÑ$I{(/Ìå2»ÎÑ^-ÏMŠ‚˜L¦h4�Ç�€ÉdÚOO;;;N§S*• ”yz(Š¢(b±˜Íf;VšôÇ+ÖÔÜ€(`ùßB;;;{|Q:/‹�t2ÿWºî%þþGê,^HU\è—þûG ¿pVŽ}yŸµKþõ�õo}•‚~5( þúµ¦—* ¤+A�È]_Ç�œ'Sw£Øl6¥RI�8¨¡A‹µôöö²²h Ekkë…8ºz�¸Àÿ•ÆRäï>”`t¾óQå§»©QQúãcð‡~¹ñÏÞ®Áîš$ä_¢kž ’8pÔ ÐwͲlÅ8@CÇÚÚZmék ÔP,–——óù¼V«eÑie èþB�–k·"Wúg_�ºÃ…²…wÿBÃ{ß bÅ~ÝÙ'ŸÐ wWM&G}øËáL®áªGÝ$“É­­­=únåC«ÕêõzÚ¨¡®@÷Øìk)sû¢Ç.Á-ÃÏÝýx~&ý­‚Áð–KŠß|¼�Åïè´ôOÞZ¨+_óàO=W™´¿F�ºéd«ÕÊ:)ÓÎc} ¨¡ÐL}âÄ ÖU’€Ð ¨ƒ¦GËh4šŠ\f&GýÝ'OˆÿàÙ·\ÞtNþ† ”¯ý4é Tf>-E�F¯]»D"QWWëR(6›�¢¨¥¥%�ê.—+‰Ð¥Jì‚îö�F£´0|¥®ô?¯¦üQ‚Žüù;ÔÊIPýC¿ÜhP߉×äpêK?ªØøZÀìçíííæ’ËGWW—H$ …B¥5z ÔPuÀqôØ€Ø\‚–ýhll¼¯Xw HèéŸ^Ñ_{µ¢ÕÀUÝ�\¿ÿ�{äÙÉ´/Z±&E¹\N÷€ÕYŽ¢`k »5Ô<è‘$Gí±)ôhA"‘H8®Ô•^[ÌÐï§T ¿ýan“#��ÈÚMw¨'OPÏNVlvN.—bP†q:êˆ>¤R)¶”éj¨I®«B‹€îÝb+8¦ /çÏ�Ê4Jn.Co¹TÜ<;U1jX^^…g£££œŽº�aÈù¬®®ò?'Y 6±°°pàHV°g´L[[›L&‹Åb.—‹ÿ+¥(hÂQȺ¿î uV�ÉèXƪ;﯄On8‚ v»�‡Q7ôœäÒä|j¨ ø|¾`0ÈQÈÚçóÍÍÍ‘ÐaE7ó€MŒç‹]÷ât¯Dƒ hópPµ9u¢Ðg5½Z��äžh}7�F3<<Œ ÈÖÖ¨pc ‘¹½½]ë³Ë�)5�$ òL]]]¬‡¬ï5Z´—¬WVÜ…ŠÀ�v1o� Ã�™“å¾ë¦Á Û=¹'­V ôõ¸uA�R©´Z­E9�jëëëétZ©T²«GÝo´ ØRÀ@>¯wËW°S:šùkˆlgk›ßê†CôÝhU^ÖGÝtuua‚Á @ µz=6‚-?Z†ÞRø¬�ÁÇÁx|ªL݇<Á5€¦³Ù|xM:0$»s%@Nº;K †j]åÞÑÑ!•JYÛ“�8Z†®�ÙÞÞæç™’Mi[!“Ù')ù²VޤïÆÖ¨›ý0�Z­¶^™õF [[[ñx\.—"ÙxTУeèÐ÷}ÿ Ýâ j1y¸ð9̈;ðWÆË<Ó¹à”ý »£‹ù/å�º¹ìv;Hdòu¨áh(r òQ}Zz´ H˜ùynò·é !úM™‚-áX6=áOÐM(. üó±XÌ®R©Ìf3I’õ7\»®¨Áápäóy�NÇV�S™£eCíììð0v¹ÍT †ù-þJ�æ6 Çj3rž4-Gª ­133Ãâm{>Ÿ/ ÔP�3¬a«]Œ–I&“`®d ]›@­|�BGèoÓ5Ë><ã#�HRÐärÁ]hç¼4/455•&ÕÕ×××ÜÜ †ƒ°5]B,©Ñ:KdÖ 5ÿ“E±¶FË…8Æ.Ë%pÿÝÑRýh:ÃÃmŸ]ÍÒ±¥ éká–‰D™Ír`˜Å‘FÝe²µµÉd²x<^‘ö�ƒËåŠF£R©”±GË`:8x»üð`!&÷Ý—“#PÃa;<ð?ív{ùRÑ€"‘-TæZ, ÇEÅ.¯•Ñ/çš̳咎ƒÄsÓ…Fì׎q;ƒÇï÷ƒf¹2§Î€7ˆqe2™‰‰‰tš…vòææf�F“Ëå¸èÚ¨¡D¬¬¬€ -õSºó|7‚M‹–z´ 7swt*ôѡ æ»±Ρåð™ÿÚ¥'h¶™°1;‡ã¤I’½L���¬4ËÑžtªüïu™›››¬X"5°æ–/ ªb¸-£V«›››év îðÄã ôš-?þÕsÕ5|ùvæ'Ø?Ö¦ IDAT7 VÉo2ŽË677“ɤR©liiaë;iáïGÝ”•JÕÜÜ\7‰Ìš§},Óÿ¤yÁëõr4Z8;�‡S…¸Žfì�ç Œö…gã³kì'2}âϾ¥=yBü؇Þm¥—6ÙüðHнFÝ”†îînE½^ouj€ Ï€±–……NGËÐÓô¸Nq½÷ ª¦†;�• ¡?üb˜Y•T>âiòýÿŽÞ� �¡ð‡ßÒÈ©Éàp8€¾[É“ÍÁ�£nªÿ) Ôp‚þ'èt,“œN'=L‘£¦â€Æ)GhT þ ý®Fä»?Z÷²ÃÑùž¯¸ »ëï½¾¡Ç&âîrèrv›å˜`Žº�µe>e©T N[ †Ê€n×·Z­enJôhNGHÐÍ \÷ê�v"¿ú`¡µÁ%žüTðåÅr#mkü‰Oo3ÊÏtäß4ÆíÞÈÝl¡=»=ˆ:G" ÇQÎS¦™\§«9ú±�}¬Ï;•Jݺu‹¢¨ÁÁÁrò+++ëëë‚ qa¯î�R© ‡Ã‰D‚¢(ÖGQT p8óóó©?‘Å\»wâÙ<õét2C ´‹EØ‘­’„¾u9ùá/G˜ÍT'šo9½êrmƒa¹\ް-;çv»·¶¶Äbñàà ±¦†aƒÁëõÆãñxïõzÝnw$¡­³ÙlµZiÒù—'>÷ýñJ¹©yͨì‘ÙÉ¢'ßQ´âοx+óƒÉô~ÅÇ7�“ÿñ¯6’$ý~¿Ó餛‹¤R)8‡29beeemmM¥R�;wŽÝÄÄ}£ [a±X×ì97oÞôx>N’äÙ³gùŸ-�F''' ‚°Z­'Ož,íK2™Ìøø8A¹„ãH ‡C.—_¸p¡4ÿÓëõ©ørÈ¥Llnn.--õ*’ɤÇãq¹\ ª†á¦¦&³Ùl2™ý29êŸÿÆ É\¾ÄÇ�ÀÐkFe¿ÿ¦F­ 9œ¶¢Ñ¨Ûív»Ý€¶€o±X´Zmñ‡›��õù|Ür#‘ÈÔÔA­­­%ws-//¯¯¯«Õêx@ n‘ÍfÇÇÇq--ŒçóùnܸFË0GH𠊢®\¹’H$ìv;È„Ç}>ŸÛí¦�v…BÑÜÜl±XŽ‚ ƈ§’üÞµT,u„¼XÿÜ ô��6Iþœs‡Ã(Š^¼x‘E¿£" ‚lEgggi�A\¾|9›Í ”_Å/PÃa¸uë–Ûí6�CCCyØ2$m(CÙí¨–EQW¯^�Çã•ån¶6’���Û·oK¥Ò‹/–ßû'PÃ==Àk×®¡(záÂ…–¡PhzzŒ–9p„ÿ˜žžûÚ=~;A*•Êf³•æ·”Øôáî0O‘YœÂX%GŒj¤Õˆ™µ‹5ŽÅÇG@xX&“]¼xA*_wC»ŸÅØw^øË/¿‹ÅºººXQ à X•ŸNP®‰“é¹°°™Ï*z;-˜XZ­>Z¦"èíí …B.—Ëf³566‚h¿Ëå ƒ€²ÙŠöß 5jPó±•�|*Ð_¦³*N§Óét2³*ù|HiöôôT/@d2™‚¸}û¶ÃáÀ0ì¨AkŠ‚UûÜÖüÆuOÜШ”4*›‹à*õªÑjÈå©—²×ÙÙÕì–ŸÀ÷M7@ȦÆ:Ågº%—NI™:ë÷2ËYIGq‡Ã±±±ÑÐÐÐÔÔäv»A•$‚ ƒÁl6ëõúª:[‘H$€eZ�£� H (?­Ë:Ž”êÆ êúRöš#;½’[÷àûÇsÀ0dÖ¢Cí’±nñ«N—å¯jØòã_ûiâG3™DºØ8™L ?<(}ûÃÊnËÁ…%ñx|bbŒ�¬ª7-›ÍºÝîååeú)€1mµ['Sš£át:}>}š››ÛÚÚ¸hr+ ©D¢îSôFˆ¯ÿ,ñìd:’(v‹1øâIɯ?¬äg¸yíQƒ/B|æ¿bÏϤɒN†¡K'¥x³Ê¦…‹”J¥®_¿žÍf ÃÐÐP•ðI’Á`Ðív3ßEÏœ9Ã]sW•#›ÍNNN2ÅK677³>è¼d¬®®®®®Â0<<<¼§ %š ?÷Lì{×Òx©#¼F»$üE•Ý*¨�Þ7 o¾˜üÜ÷cÎ\‚aȨF�T&†Êä(o˜ðFˆDŒÁO>®|â±à¥f2™ëׯ§Ói­V;22R ¾ë+A­Vk6›777www«!oR±½Áç›��‰Dƒƒƒ~¿ßãñз¨ª|+Pª€ Èðð0�>ÿï‰ôßüÇî½RÂ:jÖ¢21Œap&KúwIw'ú,‚@o{•ò=ohcðq§†xšüèÓÑçöªêÑÇGdôHÚÅrÉÞÛ”ÉQs›¹kKÙç¦Óû‹üFº$Ÿx§F!Î^Ðh4£££•Í�Ø›Óé¤Î÷T4—™|©u�$ùÒK/¥R©¾¾> ãÄD¶x,,,ЭºŠÍ'¾µûýë{ßȣòó}’Áv±J¾wOÊáÔÂVþº#ûÜtz¿š†Ý*ú«'5Vv|©!°K¼ç«îüžûòÄãʇOËŠÙã) º²�ùÒs‰›¯Ð227!OœÛ’AµZ=::Z vi¿ßú|AÆÎf³íw¤AɽÉdñoÑï\)8~Ã�âz¯Žëø#[=E$IŽ��§ÓéŠôƒV±Xìå—_†aøÂ… G "GÃétÒõ×å4zŸüöî¿].ŒÆéÿÝÿl*P8EA_x6þ…gãô_:š±¯þ¡^*®À>Q)—O>ýÓ$“þúÉ&!Y†.öKýQbiçŽ=â (�tq5"!“ÉlooÏÍÍmnn‚£F£éèè©ï£Ì`–J¥^¯7�Úl¶Ú*¹/ 7nÜH§Ómmm&“éHÿÃ0�FÓÚÚªÓéI$©T*loo' ø‹V¾p+ó©ÿ,ÌËìî÷´r ÂÊí’�4s׉$ÈÝ$yñdzÌø¶‚1â—> +šú[E_|¿ŽÝ¢Q‚„Þ÷�!Ú³cð·þDÏ®UÆ©Y;99 …Ê鮸\®¹¹9±X|éÒ¥2cŠeºrÅ#•¥~ùã~º-ͦǾú‡ºý9ˆ2ñ¿ŸŽü÷Dšæ‹§> ã¿ Šojø³¯G¿wíŽÁ¯”!ßøÿô-û{c8N¾í/ô´èK'¥Ÿúmv{<Éĕ+W :þ<ëã0ªtÃòéÓ§YTÙ*!|$üÃ3ñ§ž»cð‹Pø+ ãBP;�£ÞþW�Mß�¼f¯Môô‡ô---à4¶¶¶JP©f„B!ŸÏG�ráJ¥²»»»³³“nl �@@"‘˜L&«Õzß™©k|ÍsÇùÇP˜9[”#Ø­¢S'Ä·6r‘ôüLú�(ë�&– ÅHJyh �aè±Ù—t§™o‘½5ìo +Æb±Tª5†ážžžÉÉɵµ5³ÙÌn˜½‚ (jii ‚ ŽŽþ/ 4k æ°µµµµµußvøIÆ>Û#Ñ(ù0å^3*»u· `b9[ŸÔ0Ë({ÀÎÓš8×#¡©aæ ™ÑûE´Z­Íf;’�É´Z­Á`ðûýËË˧N�ªjØÞÞŽÇãr¹¼RZÞ‰¤µµµµµ•öc±X,s8÷jôœYÍ2×?çùã@7Ör$ ñæ\òG ̉¬í<ç§Nˆ ]A<›§@Íe1Ã]ª===Ànii©)‡*ÔwS©T*•Ên·Óñf¯×ëõz÷Ç›™ ø4_U­¬©žx*Ky"ÉþJRC8NÒ¡]…Ö7òtyblnÂv‚8ðÖœ\#‰?Ü¥â»ëúúúââb-Î2Ø0XCUub‚˜L&“ÉÄlô\_____�ž¦fóN€ Õ6{j« Çï¼Î^oÔÀ…dT£|šê& ¨‚ ¯ÎZ”aÚq(f¸KÅÑÞÞîr¹@�ÏøØE"‘p:� †Rµ')•JÛÛÛÛÛÛi™ÿX,6??óöJž¸sÚJ)R|ª‹•Lÿ\¼®\ÍPC*[¸$¹”WKR!-<ÅXï6rR?Ëá°îîî¹¹¹ååe£ÑX»�KKKEµ¶¶Þ7P%ŽF¿Ýn÷z½.—kÓ“`,`˜ß\x_’™º£&x.Íf­§Ç~ñ¬¶æ^*‹Å²½½½»»»¾¾ÞÕÕU‹¼àóù‚Á ¨×¨¡ÓÆ0ÌjµZ­Vƒ;ý$¾Eñü¾ðinó´�3ûÒ’^om2[8œ¡©V[@«ÕÆÆ-vTC IÒáp@ÔÕÕU£JÙz�¢"[÷ž¬� õF jFØ%øä]ogœF­Zã@Œ€~Çj €Ñ”JeíŠPÈ¥]‰“ÌPÅC`c¤Ÿø)¦à•4J„n\Me)ÿ½G-²‹lž¢ue²éjXÁn·cæóùè¾ãš@6›ÝØØ†OíJW!0dÓÝɘÇj1`õF 1ç,Ï®çø9èÍõy—ßm:¬ú§‰‰D*¦khR©ÃáÀqÜh4VDÄ‘Õ\p…nðµ€7¼x4QÈúyì¡à�†; �k¯ÔÏåL©ÈáN1Tãhkk“Ëå X' r®‚ØíöZ¿ùÌõór%ðP‡©¿0$Agì…;ûÓ›élžó}�¤ ND8è©ù6úµCÕ‹‹‹4£ÕúÍ?èîŸ\ÎÒBAœ‚Ù¬ÌóæÑjè�ÐE�É õƒÉ4×G¿�ñÝ áÈ%ð…~)Tû0�:�Ž®8®f¸\®ÝÝ]PDTw¾Õ€ÑSçbªs„ù­üüVþî®ýÜ�´>©A ×�)4>~åùDÉÓ‹EA´PA� Ê*"ËËzzz`}JU{’8Ž///CÔÝÝ]7ú·¯?[°}þõ…$×iø/þ°ð|ÏtKxk/à› zÛC :¸Ä¿ñB’»c=3‘¢†¡·?¬€ê Hw7W'Ö×׳Ù,ȹÖÍ�Óƒr: K‘ŸÿAŒ»c]_Ê^¾]Èð?ÇwI¯Ô S¡ox À»_øAœ£$�?J|ú»…Çöð€´Ó\W3éAíPˆ«ÂÓún0 ×™(¶L ¿í¡Âó-†Â »H¤ÉÿûÍ(ýë@›øìÿkïÌbâ:¯8~—Yî¬Ì³Á`ÀØÆ0Û`Œí&‘’&ŠÒæ¡J«4m’V�%JÕVMõ!}‰*Ui”*jR5±RµUª<¤ŠšªM«´1Øbjl0»Á˜af`˜f¿K¾ôãzw€YîŒÏ¹sïÜÿýÎùÎùŸCÊR–‚ ¾û�®Lóù›Æ’‹gÑD–We)NxéÝÞòaä÷-µÉôr¹ULOLLð8$rmyæ!�ÃT‚³^œN§N§Ãþ«Ò­ePWXé�v¥œ|é1.Ýò¸çßôg÷ñöËBÿÍvûÚmC!æâÀNãáõÃÇÕâ˜êù_¯f%£“℟þ. Þ°<Ù¨üú½¥9Êw7ÏÌÌ ™ R °þnù¡³AùMQä?áJ=󫕬¬�xíÏá÷D9¸Æjùs�¦Qµ0N;?~¬ì®š�2‡KS‰§_[ÙcÞa1À}çuÿÇ"]°è�÷…‚¢D1›ÍV«•ã8´ °¿Û¾}ûJõ´Çãñ›ü‡í›—có©'_]ÆiïÝ\ç_xËÿ‡mt[ ô/¾mʃ‹ê–`æ%Arš¼§…9?ÇÖ«kü_ú£rÙ´ONí°æ‹ˆ.F^|'0¿,ê¤R³OwÌÉòtA­V—Þɲ²24d¡¼¼œa \¸‘J¥†††xžonn.½¹[Ç-..NLLLLL¬úW[‚7ú`ìóòÿµ˜ðÑ@,ÉÍ5 ½ã›ùãÿÄ~ðÛÀ䆸èÕÔ[ÏlL6Q¨IÙ2ù›Õks·äx�²§î×>خʤß�å„O®ÄÏþcýºçÁ®µÉÞxÖ¬•ÇÒ,aÑŒ3)XÂf‘©©)äSvâĉÂ~®ÑÑQ—Ëe6›�;VJ¢°y( ²–Õ–•¿x6pqì–hÎb ¿qŸöK'Ô™8Añqa4þÎÇë#·ÞV#ýƳæ:›¬€Ÿš,l£N,)¼ò§àæÊH�Šº÷sâ°²­^Q®OÔÖù«³É¾‰Ä'C±Í–X§ïb~ö„7zng$ŸÉè�byš¡á‘ÍÍÍ„Wz£:·J"6¤g9áõÃï}I»�ù…¦ë0sw½Â¾) ¾ã‡g““ÉÅ6w!·íW¼ò¤Ñb(ð —”BßGÑW?‡£['rt*Ên¢UJ’"‰hBX pb§I1j%ùìÃú¯žÑlùìÌäJ)Y9½kЀ)[?fŸò<c“á³äÜHüç³P+I‡Y¦Q’2šˆ$„¥ ·]ÎR!#Ÿº_û­t´ܶI‰´÷×ù7ÿºöa_tw™E|±]õÜ#zkZ»Ýú0?CërÄÀÀ@ ¨««+È–áâââ•+WärùéÓ§‹WgÓ†’P•ùð»hBxûïkï÷DbÉÝ|�I’8Ó̼ðe}“ •„/Ƚ÷iäo—b™·µéÕÔíªÇïÑ8wxN 5ê6wñp__I’ÝÝÝy>~žç{{{c±XSSS1ú8‰Gæ¢ßìz(I`�¿'òÑ@Ô³šéX­$ïkU=~�æ@¥´$•” )σӉ�ÉÄåëÉojsɃJAÖÚdw×+�R?¤�Ó{zÔ‹Gà@ÃétÚíöB-ÎwÇÈȈÛí¶Z­mmmù|ß™™™ééi­V{òäÉ"Zvá$ÔÒÒª(ECIœNç§ 1<—ìO N'®{ØÍ‘²BNÖZe­uŠc•]�J¥$†Héûùü�‹%^ ÔJÒ¨¥r”¡A£¼^/˲AÐ4]QQát:‹Åž(™Löôô°,{ôèÑòòòü¼i<ïííå8îøñã&“©(NT$q»Ýn·•Šá­+‹Å’‹™Z�uÞæ" �å�’4j© MI^BÉ"²ËÇ-//»\.lÁˆ §Ó©R©$~ð³³³SSS>ÀAˆD"‘H$‹±,ËóŸÏãñà+«ÑÙP�I€ —Ë‹Åгµ;É–Nñ<þüùh4ÚØØX]]½Ý²¸¸¸´´ncEÓ´Á`¨¨¨°ÛíÛÝ9Á`°¿¿Ÿ¦éîînÉê¦ ȇÎãñ i†2™Ìb±TVV»]%H|±v€Ïç’Ëå§N�JË¢E£Ñ7nà’éW„$-Kmm­Á`H;3ýýý¡P¨¾¾^šƒgŠQÜAŠ�"ZŽ®¬¬TWW766¢ß¤R©ééi—˵—Ëm±X>ŒW ×®]cæÔ©S’ºÓŠ:$i(bòœÄÚ¸0±««K§Ó-//�ŒŒ ½ú4 …^¯W«Õ …‚¢(AR©T4 ‡Ãñx|Ë(ãСCÕÕÕ,Ëööö&‰#GŽØív‰\šbO$ƒ4”H ‘£­¯¬0>>~óæM³Ùl0fffÒþªR©*++m6Ûm*šc±Z%áÝ~ŒÍfcfnnÎ`0tvvJ$p(�íg�†’"‹3Ù=ªÞÞÞÍ+�FS__o³Ù2/@ðûýׯ_›s���ôq*±¢5�†’e/e¶¹ ¯¯/ ‰ïäýû÷×ÕÕí.êq»Ýãããh¡Žƒ‘3gÎ$ËP’¥î %Î.šsrÁää$š4‰P*•­­­F£q/ÿ3‹ ‰ã‹òòòööö¼Ý�%Ü ÒpQÀï1Ú¿Ä/ÕjõÑ£G³²ÆfYöòåË«««ø7yع,ù¶z�†;”<¯~“Édoo/®eR*•���YÜ´ã8î³Ï>á I’i%9ŠÑJÕŒ¤áN4ò“3öx<ègŠ¢:::²ž)L&“.\À^µY7˜B™]�ǃsŸRÈì‚4¹e»�¶¬”è…Ãá‹/â— 555¹ø~¿ÿÒ¥KøeV ¦Pà€¼fdƒ~¶ÛíGŽÉ0p€VHée¤RÕ)îß¿ÇÛ~¿ßï÷���ÛíöLâmJQUU•‡c®ªªÂÒ€ Æo_O•–g!IÒh4B+$H�Á*Ž$Íf³ÙlfYÖëõ¢,½Ëår¹\·ÏÒ³,+.F²Ùly8Z£ÑÈ0 jÄâ8. m©_hwfs+$T4ƒ4;¿02™Óét:�xo}}}jjjzzz˽ýP(„cC�N—·M>“É„“‘Á`0MÒZ!QM´B‚4Y@«ÕŸonnNìUMMÓmmm9�€4¹%™L¯¬¬¤ýž¢(£Ñh6›õz½F£‘Ëå2™Œã8–e#‘Èúú:2§Û1 ´Zmkk«V«…s Ò=óóóÓÓÓ{´x!I²¦¦¦¾¾ÆÉ€4%µ|˜™™YXX@³äv* V«µ¾¾ @É Ä‚Çã[°Ü†aìv{UUØ´€4wÑhÔï÷‡B¡H$�FQ–�¦iš¦U*•F£Ñëõf³ÜY@6€:6@i¤�@i¤�@i¤�@@i¤�@i¤�@(Bþ Béå6MýpIEND®B`‚python-msgspec-0.22.0/docs/_static/msgspec-logo-dark.svg000066400000000000000000000066501525673062400232110ustar00rootroot00000000000000 msgspecpython-msgspec-0.22.0/docs/_static/msgspec-logo-light.svg000066400000000000000000000066001525673062400233720ustar00rootroot00000000000000 msgspecpython-msgspec-0.22.0/docs/_static/nautilus-trader.png000066400000000000000000004043131525673062400230010ustar00rootroot00000000000000‰PNG  IHDRôxÔú-¶zTXtRaw profile type exifxÚµœi–\7r…ÿc½Ì@,ã9Þ�—ïï"“´¤¦ÜRÛÅ*²˜ùq‡@ ÝùÏÿ¸îÿøGð-z—KëÕjõü—-[ü¡ûÏã} >¿¯?þ‹ßŸþîçîç?D~”øž>ÿÐëç{øñóú~ƒ?•ß\¨¯ï?Ìßÿƒåïíû.ô½QÒˆ4„ý½�}/”âçÂ÷ãóX¾Zo¿}„y>ß÷�íŸßN_l¿—þ¼Èÿž³· ÷I1ž’çkJß$ýN. þøsÏŸòûsâkHá;&äWóôó?cDWCÍ¿|ÑW+üjµ~üÉýqµrü¾$ýa’ëÏï¿ü¹ å׫ò¦þ7wÎýû§øûŸ[ˆýGýnöõûÞÝï{fžbäÊT×ïCýx”÷'^7¹…nÝC«¾ñ»p‰ö~¿:Q½Xµí—ŸüZ�[³\7ä°Ã7œ÷}…Ås<.²V1ÆÓûagí,®ôY?~…[²´Sg-×[öœâϱ„w[ó˽»uî¼/��‹Þò·¹¿û†{• !øþs®WŒ/iƒ¦1é+/cEÂýNjyüã×ÿÓº&V°h–•"ÆÄÎÏ%f ÿ�é-tâ……ïŸt m/ÀqëÂ`È€Xµ�J¨§ØB`"; 4zL9NV ”7ƒŒ9¥ÊÚô¨[ó–ÞKc‰üØñsÀŒ•(©¦ÆÚX,VÎ…øi¹C£¤’K)µ´Ò‹•QS͵ÔZ[(Ž–Zv­´ÚZëÍÚè©ç^zí­÷n}X´h«Ö¬›ÙÜspåÁ»/cÆ™fžÅÍ:ÛìÓæX„ÏÊ«¬ºÚêËÖØq§ ~ìºÛîÛö8áJ'Ÿrêi§;ãj7¹›o¹õ¶Û¯ÝñsÕ¾ËúO¿þƪ…ïªÅ·Rzaû¹jü´µ—‚“¢5cÁ¢Ë�oZ:jÍ|9G­œÖÌ›P®DY´f;hÅXÁ|B,7üX;?+ª•û_­›kùwëÿÝ•sZº¿¹rÿ¼n¿Zµ-ZoÅ>Y¨Iõ‰ìã5#ö!@üÅw÷gÿðw¿ÿ?^¨.‹13á‡eÈk±~žžh%”Õê°J[þŽÜXüÓLÜ´kug³ÅëÝ›e»«N¨5§[{¿¾—±æŒLû,iî°÷±ÚeæÂ!¬oÛ-kÄyÚ�“©.ëÚbñ®ðyÁ­Î¼›](ú,HÉV¸ŒúŽ]ÓÞíì˜N,Ík:jgœ«Àp 1÷•úiq…�Ãi{tŸAÅýª×8ˆ³sCow{ $Ý;Ý é3Ä=Ò=a¤¹*ˆ í÷–Cn‘ÖÅîçbáÎLÄÌ9!ø±{Ü¢ {µ3+Vç- ‰yíµnf”i¶^Ó5ó¤èšP˜ÇÝ®´W®(qyFf&ßX¬¾ö=½ ˰á:·��± ‰¬ÇÄ_ï|«7Xî ˆ°|é7€]—f…KkéJ!†5C¬cÜΜ²Ä_u.Ašb$扒áX»Ò-�AÀõõ3í¼!fÚ*mŒm”–Yð'WçW…+ ˆ* –Ëj·ÍDœÁêG¦`)AÂØB²†rl1s3›‡©:/×.i‡¢f~ƒ�"uH½¹§�-ÖÔ{›¡ÞIœ• n�t&èæ!²Ò2·cË‹ÊùÜ“I�L¼Ÿß¸µ’rá•vR#ò �c¾®õ#áÊ!¸`²°¯››)ûùrƒÈàKÛe.´é´o?»zÒÈ «dôömêÏ~$îAfwJâî¬j;þL&èìÏ�‰¾§ èK GÆ �&F·�O$Ö4=UÍé�ÓEåèrЂ§9•å ăô"üÐ S 0Üï´›B‰ °"ËÀ§*Äu`ä©3^ùÊä¥\…,!·ãæ:Úv|¯˜dÔ]0Á{X¤îëõVÓp�Td‚�Ÿ‹Çƒ§ß¤MЧÕyÜ �Í ¤uÏmF„ÜN·PY R¡»Ú3hNhƒ4Qy`”Þ3—1\êg÷gßÈŠÒ}J©0Õn>)&°i8ø ÌKpÞÉ«OŠ“„Hµ¤µk|+Óö „š˜·íœ–IŸ žØX!‘]C¢+ÉÉP'7à#9ˆ:~i›&;5‘‰'A© °ñ7Tæþ: ’‹Ò7£È RÏIˆ‡ÜêXND Œ�U`>� @‹JÍëYD²dÌ1Öȸ›³û‰ á1àmÐѲp’1ÕÜ�(¾Yµï²SŠ­ÊE'®¡'6è3—!'ø°íŒ©\X®ÚÎw•|SEÖDT�ÓGeƒ_Zøvev¿m1lheðF²üœA„b\èVèxíµ Õ7g·Çhd¾T«±0½£«òŠëuÀHDí Å:l´õfBj ÞGd¦žR`ÈF<Ó9X{âùÐlN·œÅ¤ñÞfùƒ(o°h±Ö0+Sçæ˜¶vÎTÁåî 97cê%óê›@VÓ;$ (#ÎOb£ ¾ef X‘ó?š•wBv ÌMJö¼¿ÿbn™Ad�”OEj¦¼Ò…W‚J^Ã3Ð r�àukA2g @c$„o%#­;‡–Xü•pÎ$ ïè{±\€RÊ<ˆKOÐUæ2›™| Ç6²½Hqõã�hÙ4”z„Ôð‡CÞï;/±g2s0$ü™ ;ä>W/àÈß"ƒ=ÃׄªÕ+ˆë:×[ôÊšÇ#iA<à ¨ DHŽ$ÃøþôKŽÞ,_Úv�ß©%z©› bü~]"|ƒ:£Â¦EÐCU†°×7U Ê»ZÙü7‰[p6@"¬dÊ8zäp2 ×Ãký½9Bõ`½ˆØƒQlf\Ì6ŒIM¤)±ØxÜÉÄôôf'(U3Lïê(¢,ô9‰ð'ƒ�{öº†ˆ�…–œâŸ*…hoJÝœVKRX´UªÃ^ÁS…ùçOšut–âŸÓ�Éì`éñ¢Rìà~mdcÊ\ÒᨴtrÀ.‡”àmM°EÜb’¶kãÙ*2¹ünBk€‘‹/ï±G2ÛNˆg( oå;ã½û´ôÞžMð%/åÁ77À�O(w”j¦µJ�*öyñPRµ÷Ž—:dËÁÜ5ɦfJˆ ĵ–¤™Š‚1 ô³#ÙâR�%¼‚ ‰T‚ ° PÈ_[Ý$â­f¡/q$¡ÌRâ±+K¸ìH*¹¢M!—tâz§¡ï#ZÐy Õ´tì�Ùh ±,E™k`ÕÆcì'¤5äf<˜—tÛgIûm!Ù‰®‘žMn6‘�h è&e–'DªÐˆ)bQ›Ê…ˆ©cRQ(SÃ� ³ G')‘åW‡Œ!MÞ³¼J;wK¦ìÀ×(;Y{ñ®”t/m‚Bäâ�;!&Ü6c±Ž³‰>B17 ¢'ÝXT¾üËï<íÜ(Ö¯vBvÌíVÇùO¢òÔJÞ–©ª-F8JÏJß µñªÎÁ¶ÀûÙxìdiVpŽDN¢cD©Ö%ÎÈÁ·äD²bXÄÄ2ã3Qôhzò= Í ÓRN3;͹Ÿ¬·K'^k‡Æ¶’¼£¦+*ÖfɆBÃZÙÐ@Œ&�ýs�G&=„4&sçç-^Î1. Rd–5¥Žaz=z~+‚TŽH'K\šÜ0g·ý&“‘� È~Í'YÊK+~øÒÁe„þ�.ÊðV\&6ÎxsKð$Ã罩Ë{òsì\k1‚-LiÁ½³)ƒx§‡ç#`ÉÑ#k™•�'œIzaáåõ5„ÿ•òGñ£A7ÏV±|(²Ö¤X`½¢mLmEí©>Â\ôBáœ0Kr½cˆ¤*ûÉݸÿÜÉNün{¼,±b�}¢¦ ”¹|AˆC³,kîÀ#Öù1ÎË·+“ãËi!®¤`µì&:cÒ˃Ó:1ÜÄo x0œbÂx̺|€™ŠX?ô-k«Û«*5A] ÙŠŠ€L³ªŒ‰àZG‘̓1LÇÿëÊq ÿyÙê5;Š&®—´Ð£÷€d/ƒˆy&H*��R߈½â¹mÇ}p™‚Eb/¹P2@o`ç"k)"áY˜o™ih­i ¦…ÊH|sÍÉÀ'‹É¸½ .aoçI0¦Ÿ RÂK(œÅ¬¡~“©Lâ¤ÆYTX2b&¬¡PÖ ÿÆìU Ç%bó7.7C“üÅæ$¸ËÑ*9Š#¨Þáä˜yfÕ xÐMÎ�ú€b‘:Ú²�Ð…7&˜�Ù»Î~Û"@BÂ5™U[d+ 'Ê¬à‚ˆ�Žî*@íÈA È�&Øx€#>·�ÉW(Ö®c‰<2 t…"±8gdjxvba°º>‡wVx–˜�Ô„ûˆïá×û©Ë!†ˆÄ*v ,=¨¯W Ú#ij¥ãx.ìç©7‚T�.Å´÷ Ê[”B8ÜáBD‚šSi|HY†ÔHY„V½iMÈŸ< ·Å¯{^Y/p1aÆñ"{àüË PU«(ï˜*sâ×{0e�v•I¢Û3sT�oDIÀ©è@dKRµÄxȈ'¯/T CRµ•Ù óYÅórRÈ †-D¢«ðâáº0?áƒ�)ÀÁX‚k$ИyÐ’ÕYy½ÀŽGÁ­ŠçihƒŠwt8ioä~Ó¼˜²¦RÞy¥Y¬–fœ@á$"�×bX3Á‹´àyRä3ËÏ7ÚCõ0@?œm=·mkãXZè_G U舔Ëyƒ^WN_a¬Ò ú'¦Ì8«×e§[ @ÉÂÏ�´!ÏÈÂ�.E–’´¤ ‚CB’ˆGiaL_9Y^!- ,âÉ5q,Øÿ0‰\Àø©eì@3W�ÇŠì®û�€”Aì÷ܬN‚¸²bOà,U† ¾Áò³,#Të;øíTXz|.x-U Ön—&'ëû:T4—œeQÁi…¾Ÿ²8« ÓW°ZÏš‰†ºðÀ0y9E‰®d€bDob’ ,½`?gž4Iïk%ã˜;ÍÎGbd  Xô¡Ú©âF‡á»Ð¦£Ç…þ_3óþr¦€ÌÚJ˜°rA�Oä^"¨ôǽ銼„Ѥ4’-s<#€ÌBWGüƒBÚ@>bTI.^í³† ´UVyâÖ„¿vô³¥PÐÈSÅ¡�½�ã;«Šµ„�Á¨Œo@O5p‚Ë‹ PçÚHk`6j #¾¸B8ÌÑœi^%C/á¡=� e �‘+ ›ƒ(€ŠU$Å æøŽÉ8m�5÷.ÇØ¶ä:V´kse\¶èF^mw|–¸ó[ÖJü =Ÿ£Í²ƒ{´¦#M=‚ÿSggš|óªÔ÷_騉-çÂ|¨püéñ`"aUì d(ÍÀJH°c.Ž6 \H›Ú-Y»´Äà¡b©»à]ž‹ûظ€Þž`�šl¤g-û i€k†Š®æ…ë¸Ôë󓦂۬Í]D’J D¹•pŽ ³äÀÉ’�jLÀÖV͸Eø½"߸ÎP¼ÛBÛ,МYr)ðÇ´Î=8¼ÚÍ{'•8ÒⲤþÑn0 Ö@xÆÂ,ÉC…“pÁЇ0¦¸‚ôÒ™y 1žÍ<¼I·¹ØdÙãέâÂñ‰íµk2¥�xPÊY ß$- œøcvX¢)B.ÚÖî5|¶ʪc åÁÙôªt"™ Ó5²S§Ö0Rª{þ² jå,E²Z—ô¥ Ä�ÕDIvª’³Ä/PVtˆ+Ö’€g±ehg"ùθµRUé?¨r"*!› v"ù»G]+¹ÌJD®w'ü­âìðÜÎ3µIÓYê5õº ðIßÄÊW9&¾J°K/"ÐåòµÄøIþ¤€Áj‚¶˜ßÞ 3�±E¿ 4†‘ö¤b#.µ•ŠR‰•+cR‰€†gSk©{bF$¦áqSWØ€Aµo/) ÂÁü=ö$@P¤N—ÉTqA�"=eŃü ,ù0¸½\º¯$Ë\ýǹ?ü ©D3U™'£ç«ùƒ”÷fR‚‡¾ÚbÇö*ZWJ^”0w>Ž…Š‘gèäüq>Y¤=»õ†�.pÓG ¨Ö†¬ÊHfœªªÊaJÀx*„Û‘tq«Çáå6Š¥õqlÌ(46$nT±#ˆ#0AÆ¥"I±º-íœ0ÙŒ�ˆ>­^µ¦ yPe<‘Ù\µ_"®×æ¯霑5ªçv¤Ì 9©æyQMÑ‹T"F«¶~Ôú„¡"Òñy,?`Ñ�Ö'h“ô†_¤—žÃ/ ¶nÚ?ýy0³}y’s»XïŒb¨È2‰&Á„—ú˜ Ç“¼ÄÙžõ6Úœ(ôØeÄ+S]vªˆo|Hɳªr‚™ÉÒ÷¸«"Á”yÉ ¯= ¢i#þë$¤‹6½àI2>ûÈ{1Äîx®"‚&ŒcoïæPÑ\UÅÍ3QÐXÞâb‘ ,íGbh½MÇÉTð”·jÓ|ê� L[^ÕáhW@Ûn`®ÁÐaüämà’nª–® ]åq&dγkݧð-š»?Ôár¡zè$s•$õ —@Kjf’”Y9zy“íËB[‘å‰Àx›•Äy$pVôíö3öö0™—þŠ?h¸ ÄjËTÝ;"»�דÂ/À ~Ý"×è‡/i5ñ¨ƒ¡í‹�k—玪ž¨dã‹:ŽÚ˜6LÛšÑ*BÙ'\÷Û–Aé�Ueò§[ ×I³yO$òAÚ�¥¬E€…�‹beoh,’ê–w: Tæ�×kHg‹Ý�ÊEÈÒ!ý`/} 'F ŽEb€ÇšYÀÎ9Áõ¹�Á¨ËØÎ®V¤OU‹”&$%T‚ªBE[²DÐ!ÛÐba€"¢YLdûv™U@YŽ·iª #µ…~Ì/#>ÂL¯9D,¸¶÷…W“ᄼ—!$$"„5Ú³…-õx™Ò0Æ0„i’ êŠ?[$.Z¨{ø%�µ²ÍÊ,ß'BŽd¹"û„ÄD4�ˆ¹}äËtA‹Ú8Ó¦«i%¬L1JJ”5 ÑIô©°´[B/kW‹@+zñh‹}3“ª,©%¹8?ø³¤¥=@¦Ì±DU™¤l{ëšUªçÄPxQÝdoOãªðpñøRZL¸jç¶É›¨‚æ·æ;ι’ÅÚL;�øpbKôNœ! ÍÊs_ ©'"þÖ¬ ­~ú"² oÃþ‚šJûšŠZb§£tpˆä�ðx_5JÉ¢\,£–׃c&9fß^UÁ¥~ÐA÷V´&ˆ‹ˆa�ìlSYx®Ž¡”HVQÝÝÕ êlÇõxaŽiG“Ì}* ‚Ù¬X]V ï·|ÇútʨÂ8µã.Ùb$�+*>ƨ.ICqxD)NÐ�Úp"À€}° ŽˆGU‰“!•Ÿä |b8‚•¾+!™)¡¡ý!DÖDŸ B¥g¼L˜â"Ħì�jG@ŒîcTž6HË·|·«*sä�ÐY~C\µäªmå㓪·)JÙl, Ú ÐWX?WúmÇ®}•„½êÙŠTf.‰í\�ßKuˆ£$2o}² ·²Äã^¥]U^²WEʱþÍ!z£¡ìgª„�”ï­á/XìJò€M }ÖütÀFèEÅL¬4#¨'ö, I2º¼êKô¼2âT£zu5è¦#o¡’U‰hnÚ8ÀJ`ÑY)íá‰j‘ñ@³�8TžOý#"ïTë@8†V4·ä Vơŀ¢°¥ð?Þ|4¦�L¸ñJ[cÌá ~Á½ÊBê¤È,‡ªag ‡˜!|qçÚIÙy‰³Ôd!I}›‰ÂÕz ";I9¤¡vÑŽ\/\Z 1‚ƒü‰^$eI=…Ù·í^®¥1ãüJ �fÈ´­u^€wgf��¦¢RP�9„=î“%ÕP~$í\ãëÕ€òj€n ]ˆäï|reÞÊör¼Œhà‡ãN÷Ú¨§NˆÇ‘Ä‘Š4@€‰ m’ÞÝ“jDÕ;û9਽JÐ Ìžd* ›lÅ!�e{¦H )i3MÚ§ ¨q¯ýS_ÌGhZ5”ö9k3#&{=Báõõ1ß§Ñ‹:Ž&®…ÁêfµŽ2 }!Ä!k¡N<Ž‹2R¢[û@{&¢�àFñËͨÕ¤²¡täA@”h„ñF£�zGeÉqQE>Äêñ("õÍä‰Z,W-¤Zòü�À”÷ÇÊ{Y É‚P¥Ô%;Q-ÓزtšÁyA¤ äHˆËÕåÙßEFKŒïȱ6ª{O�ÁP… â+îÀ€½' á«qEµÈ{Ïúƒ±�©O οտΠ-·ŠGQ½S@åMÌ.³©¼u:�嵃¡^P¥�æŸï!¦°ÂçÊ•dȃ6ˆïN€ñÌ)8Blî·Ë'{ý*'c¤I?êÈÚ4-¬rËÁˆ¸+Þˆ8Ån¨“«ƒã0˜}nÀ©¨‚ f1çþUhP¤*�ô%íQ~„ÓAe€æc‡ta¡Úª1qr <ð£ÈÃûÀ+r%X¬ð /˜mÈ«'jáâuœ èH `ÃÀû�w?qh[n•üÃgÀ“-”JåâɈRö5>tÿ†Ô±Ë]�yä–SåZȈlUðĉ1Å¹àæ‘u˜FéÉŒ$�b{ÙU¹–†òË,NÒNØÖdc«¢Ä a²Òµ)Ì—ú7rh©(§n!©°¤R£’«gqž†=P8(`Ο¬Š«¿IÂ8�Oƒ\­hÕ1+ò5�B¨1´†4“KòiVæ÷­µ“YÖö�õ_P5PkXÇ'¿¼Z"æ”­…UU3R5‘ˆDä@ðdçßn&'€T3ù§�Ÿ no&ŒU|Ì2zÆ%«´£k(ðt€Ä�Ä”ˆøº§LªzÀÆ* ô·;B”ï­¶2RÖ¯%‘v�ôLà(^pÆL(N ™uª›¯\…³“ ™Hn¨úÑ-!Æx r‚‰%bBUC4íçTäJTïu°y(ƒ‹'D޶z‚Ÿ: Yhª¤OpüGßïÂŒò¾ž¢ò¢‰,±™eí’B{ xªÁ<$+nÕÜÂKY“‰WâÞN NGÝz*2ÿ¾£Àý¢Å ­»?mÓ¯ÕÕ”½P¸×c…³ŽJwðlý ©êsœú?ˆ6CyAL9Ú*ëM5߬¼q5oüÙú6'Èò\mßùìÔ¬z[“JN ¥yªüI)v¸ƒ)²·²þÓ«h{TlêI«¬~ Lsv28�·!ìªWyÎÒLØ­JG†Hí–ên"=‹Ì‡Zä±Á‹þ ©áìb—˜N0¦×ÊÁ^Ú¤xûGE[ø J¥Qä8¨EB!Å¡§¬XÞ¸>Ä–‹¬¸6ÁP2¾fFOü!Ö!¤EçÂÞ8[ü É�[Rõ ¡ÏðDp–½^Uf“Òä™[î{½&UÔý¢ÖPüŸ6múI›òÂ;q*Gè?ÞmŽaŃrdˆ8Ÿ$½»nBˆªê ˜PèIõ5’ ~•Å´¦ˆžfäsÎ'º‰uBÒ`ed´´¡j¢ÎGxbëêè˜WcIÐ9¥Œ&(/<Aõ§®í¡îç!ŽÐyâ}¢°¶×œõ -¦�s*–Ö壂i£7 +!¡ƒÁÓ¾žgB%¥NàÙ+«w΂�ÆC�_¼ôö×G ÎpîöðiÒI^‡ÔbÀš¸(µÓjg±ÂšjÀ!ñKÌÝÐñüÿz 츲ƒå‰Š�À¬WA+Z¿vª¢Äˆ,r¦•îï)Ú_ ÑÒK€Š,uf€s²Eo¼›¶¡*òs7¸Ìa„T¶3°&a¼Þ¹YwLõAK›«—ýlŒ¨îå^†µi{J­ß!Ç¢§¡,53®•º¶÷æû^*ªeâ¿YxØ��‰[ÍJð jÖ¯Hü„…`_êy»Úì^¯ r½>Ó€Gbn@O]ç|´+θA:dÊ"Ê"xéŸÅ–­ÎˆQx!"qt˜Cí¼åÓY§æ"?a ÖW¢×èsÓFfX†Ù ÔŠIÆònÐr9Õ¼’(P�ãž��‹¡&;6}¨{SgfÎÛ§õ¢œK�½,ófJ,µ(±‘1\–¯!.l r…‡Gì\5�1¬zX’: U8†±ñ¦sàJÛ¥¦ÎÿÉäøĨ7«Hû4�KXÚüW7·öEq…;¼ÆÌÖÀ‹¾° L>cFkëPÅUÿöP9R‡[„w¸¶Lz *³ÚPLx¨àÕ�³{õÜ�Ô `Ç…ð�˜\’6ÛTÓPSë�:öÝ`ä;7@|«z‰ec†§Ž9ª\—ï§/AÍ¡Ýicqyõ>òLG^ ä/Zö°Ü„�¶óIù†ÜgÞ Â:ª›á »«ÿt'z¸_nM•ï­[‚jâçÕÈL9.V4YlþCC½¨Ô «¸X ul"†ÀÙñöŠ›]¹<àÚ‡§_´zi!˜¶\Ù•x øÃdÎ%ˆ‘ÍüÖsošñNŠ¿ñ”‚‘¥{Yìò?­c©4•CĹð¨°õÆ‚¾{ÿ¢N–‘78¢Â8�—Œ>}G™ûÛœ %¿o‚Ùp·I{-x>/àXh×>=À†b-¯6'7ÄEþÅFx‘ÁK§W;à*q�ÑÑy\2jØÅAŤ†[µÆÈœ‡žÅyáòûš\ﷲɣ¡ŸFV}ªÂáÕ¡„t:EEÉeH‡wû!˜OyEf<Õž]²Z°"¢Gm\åIÄä†ÅÃ4G\u‹cµY«¶e`±É¥9Ä:ˆ!¨‰ü-�µ”ëm階€ A± :R?™Ê7jx1\´BôãmUkjM8—Š¢@[Ó) #¶7€€qXœA®]ô1„ü¶@Ê4†Ì_ÑÅ[›c¸Í¥.QâK{ R�鎶EœªªéuHmâ×ÀPi£ î¾tN¹(|Ö~fÁ×ÞßÖ‚6îv ²žHÝê=Þs¨­Z¹Äƒ¥I,¨ †MíÓ:T­�O 3Šü¯z¼[ÒQr‰Áк;:jɨ¢¤HTI È­?Y£.œªí®ã™± ö²˜„æÁv/<çø´nú‚<ÆÓ�Àd‹Í@¸j'c¨üN{u‘ia¢C¶¦vŒ=?G£�Ù_K=Ñáz‡�¶4ÅìO 9NñŽ^RchÅ#u¼E4¿5�k –R5ìÒ¡À¥Šrt7ò7ÿÎáбålWb“ ÁrlT' ]G'ÄjS»ÚÉ<éÛc©VŸv]ÇI¨€fƒw2§¦ª ŠòbØë;¡{vyUE+O„�‰óÄàé+Ï žOu+oOµÅud`ü­¼Ã¹'´î¬R>$Ù#ê!ŠÔªŽ¦©]s¯‹åÒ&[@CêãHÓ{T |ŧ�li;¨#±� ÀV� U»Fn H"J;Ê* ‰:¼–Ó& ë…‚Å�Ùk]xg,ÑÂê³i� éup@ oõøõœb} ‚ÚôŽm’k]2 wVàê,!Fó?Ô‰À,« m¾c„jÓœ5¨ó@µ€¢Fb5bEmn§ZK‡€¡‡¦NJ´µÆZ�bʪ“¬)«cQ‡Kgy•¾ïHØ‚ýTEºª¢uTO8(ZÂv¡bS÷% cûÌË^V9èO“%®ÚmVçÊðÁ8×§Š@í«ºözyõ\c (Œ¿�(M¯3¿jÁP/í۠Љ*C¡ä`Ä!ëVe 6›Úš£M…P��X€}ex$O†6Ö ô©fhæ #±À/φ,ů‘ ÜJIy'õÆ–¦ã#ïV‡ÿ¹óê0üVÿêÂ:îô‹£)îOϬ@õ¨5óãE;�JKf—Á‡Ü›6Ðg@Ûj§q5·¤AÑ™M{i[ ¨ÙxÕòŽæ)q¶Á¨å ºS?ĵS]ƉG4Ò|:r!E¶©B? å€¢MÚßΪ «—´ 1ža«à´Ð¬wLJMxª­©ÓÕé(c½¢˜Ž †úÙ‰L—ñ�¡ Âò¿røFçU•õÓF/Ñ�`à]Rσz[±>Êžýô/q¢GUxÆA:êœjæÁ“épðg÷ðV£„úÄÜÐöîÑ~µIâ+é´‡ hê¾å�ƒñ÷5Ä_²8|ÎÔ¼ ù±tú"ÏŸˆÀs¼ÏhAMï­Pñ$ÉR‡7e9úÑ'´O VG×åº4©^;<¡: ÔÕ¡=:hgeh®¢ÛaPèAKôªcãw˧½u ^Õ›˜(40íäÿ*¦Ýº«=ѦwÌ‚>í!OP¥¢º®MÐ#[©“==|�¸\µ@¶ãD�*Ò– êIÜëÃJp#¨Åì=•RέU'ŽªN^n¤Q‰.™¼Ö%�´iòÐ^‡¼¥.UË*�æSõ@O02Ù‡þé Ü•¥Nn7±ð)Xï~ §fµ‘áñE‡ÚUõÛ †ã’‹¨ û4Õ¼@⦊'0Â’Âtþõ÷ l¤¼Ênª‹©Ñý{Pà[º. ‚fIÇ 8�×ÉÚÄúÎÓÕS˜X�n;Í»!C��TÿPŠzœjíEçñUøšä)4.†“,è#ÈÒ«}TUð®Êºô}L�áPµŽc¯ŽYÃ_Ðd ö�ÌÝt6ùò(Ј#V_�J�ª£|>ß´añ"ÉÔ4ý�â¤ß†-DÇ´h7LÝ›ˆ-u‹ŽCd¦&^/ð;�¿dÿtózž…ã¯z`z‹ê>Hß8^ËhÒ‘Er-ªP@vNT­ª ߌÐG¤ôeù|œQêÿƒMqî_šºp¼L,Ï#AÁ�Q«iWjGâTà“ýÂkñÄûiWå™`µtÞòjþñå·‘ *Ï'èL-«Gâbñ²Ködd‚|åf‘Y‹ª�å85¨£”ZU§Ï $:´Y-¥¿�‘L®ê+ÄAî<Á‚„ 8ш«£f–>¿d² ‡KoÝÈtäN©¥öÒ¢îV{¯W§Ê!:�n~ËÈ}ðÀб•¯#ˆµ  ‘ ³©9xL)¢ö "ÁIœHòæÈã…ì,j'ÒYçïë¯ÒÀªg÷·¯ –k×çµß œÆy“§kJNnŒ_;¬¸¶£GVÓ£öûŠ‹UHÉ.Ä#¾Û†Š�`Ý\þ­¶n“ÿ‚yî˵e^]°!K•M[:‚M(O‰Ù®s×_A†p vFDØÔô¦®!í¤:l ŽMrp�P×1Jå1bÖµI'¶oĤ>ê³:òÕ \ŒlV•éL Ò¯}>W„¤àÉôÁGEÖü©zŒ7ˆ ¤×¨ššG¢ó¨WgTÔu×@Km¼�RY*néHÚûx2�(|:‘‚NNãš)ôˆBã]j�À“ì­cˆú\Æ ¡9� =WµÛÛ£vyuޮƒ¥½AøïZW#NFí®MŸI`S�°ˆ´ ê6ú\.]‚C"?soî‹]g6Ö>ß Þ=y¼ßΨî2fFêuõm«?–”rY;ÏG�Œ0—^‹½Å"ì—¶FÓ‡Q¨°X6nK’Aû£CвúMøâƒc}ÛÑÎUA]pD{hD&ŽLje äšg­Ž*Ý€~yE'}¨LÐ ØNn’0’ÀWM.sr{5²1ÿ:ÊR©Ë:¨zd� T?}�õ/Ä,"dòZêêŸ:€x"Q°< ¯NåûwÆM[™Y�zq[— ikòƒÜT§à¬�ÖÑ'¯Í’¨fØ™÷J›ï€ì·ákºëçÈh×)æ¤â*îÙ^nŽÂZƒ� …Ù·º?í€KõÂu~Ú“Õ Ž*„œ›ÊOd;r…¾RûõÔÌcÈYI.™ª·1Õ®úkC@Ö¨û}?¥ øuÕ›UA~uPi§üm@ÌêÜûº€Å§Y±K,ñ©Ó'\žÌ3Ä qIÿûàñÛPÕ‰ùG«áuªQ§,|dÛ?d@hws«�:›>*L VWŸ>e:w²õÉS§±ý]ŸÞ×Íë3)Ží×Ào‚U<Bð_jÔ0Z�ðá›´WŒØ‡VŠ>õ!ç·Õ¨âÙ�U•2R¾¢D(ð­U÷p>„®�.?|OviY}tQù맘Ü_Nµÿë µ{_qÊýÑÎÇO™Ð …iCCPICC profilexœ}‘=HÃP…O[µ*3ˆ:d¨NDEµ E¨j…VL^ú#4iHR\ׂƒ?‹Ug]\AðÄÕÅIÑEJ¼/)´ˆñÂã}œwÏá½û€`­Ä4«m ÐtÛL%âb&»"†_À t¡Cf–1+IIøÖ×=uSÝÅx–ߟգæ,Dâf˜6ñ:ñÔ¦mpÞ'XQV‰Ï‰GMº ñ#×�ß8\òLÁL§æˆb±ÐÂJ ³¢©OGUM§ü`Æc•óg­Ta�{òFrúò×i !�,B‚l 1ÚuR,¤è<îãpý¹rm€‘ceh�]?øüž­•Ÿ÷’"q ýÅq>†�ð.P¯:Î÷±ãÔO€Ð3p¥7ýå0ýIzµ©E�€Þmà⺩){ÀåÐÿdȦìJ!ZÁ|x?£oÊ}·@÷ª7·Æ9N€4Í*y#Ê^óywgëÜþíiÌïƒrÍ.š iTXtXML:com.adobe.xmp 7 ¦öbKGDä¾­êR pHYsÊ&ó?tIMEçóþê IDATxÚì½ytå™ö}ÕÖÕ›¤¶Ûò.ÛxÁ6`³Ç öö˜˜¼,!�dòB ™Ì93’LÈ̲‘™Ì^22CI Ân6Ë,Þ�yѾwK½wmßê§)•ªª«eÙ–Z÷ïœ>jµÖªî®ëº—ç~‚ ‚ ‚ ‚ ‚ ‚ ‚ ‚ ‚ ‚ ‚ ‚ ‚ ‚ ‚ ‚ ‚ ‚ ‚ ‚ ‚ ‚ ‚ ‚ ‚ ‚ ‚ ‚ ‚ ‚ ‚ ‚ ‚ ‚ ‚ ‚ ‚ ‚ ‚ ‚ ‚ ‚ ‚ ‚ ‚ ‚ ‚ ‚ ‚ ‚ ‚ ‚ ‚ ‚ ‚ ‚ ‚ ‚ ‚ ‚ ‚ ‚ ‚ ‚ ‚ ‚ ‚ ‚ ‚ ‚ ‚ ‚ ‚ ‚ ‚ ‚ ‚ ‚ ‚ ‚ ‚ ‚ ‚ ‚ ‚ ‚ ‚ ‚ ‚ ‚ ‚ ‚ ‚ ‚ ‚ ‚ ‚ ‚ ‚ ‚ ‚ ‚ ‚ ‚ ‚ ‚ ‚ ˆr†£S@D¹ …l¯uš¦!“ÉŒ›ÿÓï÷Cû‹5Ç!‘Hôld‚˜t„Ãáa׬L&ÃøX À®ëãýú8¦"Îqxžö˜Ïçf$È8d‚÷øý~މº¦iPUõx\çÆÃµÐãï³…çyH’Tø<›Í’9 @qü�cѺ9Š?Êk×XŠý±¼>cü½ÆX˜Žûø��Q<)‚ „B!.›ÍÂ0 hš6×&¯��ÅÏ�k£1ʯ�Ö£ü]DQ,|Ìd2dÈ1™ œa¥6ÓyeÎãÏ�öçŽeö`¬#ýR¾fŒòg�£øß }étšŒ‚ Ê�`0Èe³Yèº^JÚžá/Eð�6{p<¯‹¥Š¾—ÇŒDÞ«ðÿç<σã8hšF†€ A ŸÏdžEQF{=)Eø¹QüžRþÞX”F{½<–)ûRÄÞðð{K1 %›I’ ( 2AŒÂá0—Éd iš×È~4¹—ǹQ|ýhLñ4£©ñ{Éx5^ÄÚ8ŠÇŽÊ‚@Ù2AoDQäJhÎ�˜z}n ¿6–¦àX]'K5Æ(¾Vª˜—ò=ì~1CàÙ ð<]×É� âXà÷û¹l6;t5v�ð�UôîõãXýÌh�Áñ¼6zíò?VB4�ÖD� @ı@–eNUÕR#|/"9"Ï�ò{½>>Ãâv=«ëäÑ4üy~§¯‹à�ĽÔûNÏ“ÀOI$ÈĤ@nŒß«Øs?ÇÃÇŽ6SP¸ÏqjjjÄ)S¦ápX�e™Ÿ={v°®®.‡%I’„P(ä‹D"¾ššyÊ”)RUU•€K¥R>]×%ŽãDQY–uQuŽãAŽã4Žã PÅH$Z<׉„šH$”D"¡$“I%‘H䳉D"700�Pr¹œžÍfµT*¥Åãq½¿¿_Í�ôõ}—Á[ï{ùÜëÏx2” @„Ç(_Q/³ïKM�s/&ÔÇâ~QC I7}út¡¶¶V˜9s¦TUU%Õ××W644DÂápØï÷Ϙ2eÊôp8…B‘H$,‚ ‚çù°,Ë~I’D]×}džçÅüï8ŽyžxžçAà€áå”üL~ÎÜ/°Ü±¿Äêºnd³Y-—ËåEIêº>˜ËåúEéÒu½_Q”�–––žýû÷·tvvF8ÐûÊ+¯ôôôô(G!îì¦�¸šŽãh 1‚ ò§(J)Í{¥Öë½Þ÷*öN�yþ}K–,ñ�rÊ)•‹/®˜9sfdáÂ…3ý~u8^ …fˆ¢83TUUU…xž8Žxž/ézv´âlýy»çg¬ ÀhuQ×u#ŸmГÉdzpp°GÓ´žT*u$™LîWUµ¿µµµ³©©©óСC‰M›6E÷îÝ›ó øºË}˜sË4Œ0” @“Q9kòKéÄ÷"ü¥Šy±¯¹~ÝçóqsçÎf̘!.]º´vÉ’%ÓçÌ™3{îܹ+�ÀìH$2Ûï÷GDQôW‚šûÖ|”9¦"{¬3¥š‰R�#“ɨªª&Eìïï?”ÉdZ{zzö´µµí;xð`çûï¿ßÚÞÞ®~ôÑGj2™Ô-¢ïôÑj¼”( @€ &�@€³îoïAô½¦öK|¯âîõÜ¢E‹|çŸ~ÕŠ+" §×ÕÕ-¬©©Y …f„B¡ÊP($z¹bß7Qµc¬2^�×ó”Ëå´ÁÁÁÁt:Ý>00ð^4=ÔÞÞ¾¥¥¥¥óOúSÏ믿ž1 ½î�°3N+Z@€ Ê]ôÙlýQŠþÑDöÇäVSS#¬]»6|þùçGæÎ�;êÔ©óC¡ÐÊH$2¯¢¢¢Îï÷WH’$¸Eôn6Öâ~<êô¥DíæÿçXž‡£1Q†a@UUMUÕt2™ìŒF£Íoö÷÷ïëêêúhóæÍ­ÿþïÿžÑ‡^ØN½º�ø—<^˜ @-ÒãÆ(ÒMÍÞíÆ›~†÷ð}…¦¼»ï¾û¤¹sçž:sæÌSª««—TUUÍ ƒ~Q�‹Ð�'!o‚±:—N¿GQ bppPO$IY–ÿû‘GùÎ<�†}ypï€,ËÈf³dŽ!"�‚8>ð<ϱHßáBꥑϫè—zã½<Æq¿páBñ’K.©X±bÅéK—.]5mÚ´³§M›¶P–e7݃ÒuÇnL` Ãð,LnÂg÷5öX)ãX‹êXþM¯Y‚Ñ-§csj|Ôu™L™L†¯ªªªˆD"Ë4Mó¯!&ö¼å#çé{XÞJ� ˆñ Á›_>šh,SúÅDž·ûZ8¯¾úê™—_~ù©'Ÿ|òéõõõ§I’4G–e?[ocvF…ù˜�€“ÀŒ&Îî—"α_Àî˜�ÎéXFûæÇØv¿lO‰\.‡H$‚úúzD£ÑìŽ;t“€EôÍÔ°ùªªÒ„ ALÀ7–(rªª"“ÉŒ…èk±g÷yŽã¸yóæù.ºè¢Ú+¯¼rɼyóÖÔÕÕ­ ‡Ã3|>_PÁI@ÌBâyÛ‰º53àEøŠ‰ödl ·ž›Ñ»çÊî|š3;¡P …ÏUU�¿þúë:Á.¸Ï¿Þ ÓkÛ ç� ALhXšß%zñ"üÅÖÑóEßVä­�‰¢È/\¸ÐwÍ5ל|ñÅbÖ¬Y§F"‘E¡Phª ¼�0؉ƒ]†ÃMä‹Ež$òÇÆ�)°ûÌä�Âã===©l6+˜#zS¤o}=ÔðG€ &"’$qŠ¢8Šàˆ¾×(Ÿ/"ö…Ç+++…믿~æ%—\rîüùó?Q__jUUÕT»a:vé|ëqšž}©BïEø'C£ß±6N¦`4ç[Ó4´´´`×®]˜>}:¦OŸŽ¶¶6¼òÊ+±üëÍn©Ÿ�°þ!2db| ¿ªª`âï únÀÕc "{»�<îôÓO÷_yå•3Ï<ó̵+V¬8//�e¹Z’$¡X„oekdï%Ýlm€Í ž±JoÎçºXêßúœf³YtwwcÇŽ�e©T ÍÍÍIŒLÿ6Ù×?à÷û¹L&Cf€ AŒØ®{E„¿”†>¯Q~1á·»/üýßÿýâ+¯¼rí´iÓΨ¬¬\VUUUiN§¦½Ñ ¾ùçÝ´iü±®wöω—ž f‚;::�Éd ª*º»»cy`]÷Ï;dŠš‚ Aœ0X}ßaËݱHó—"öŽ¢úé§ËŸùÌg¬^½úÜ©S§®Ÿ6mÚÒ@ [kÀnQ¾Yè­¢ï&ÆNb¬ëõdŽO†Àn‰§¢(PU¹\���H&“°1fñçm²Ô@€ ÆgÄ_b}ÿhkúÅ"ûa÷çÍ›']rÉ%S.¿üò5‹-º²®®nY( ­è�WÁ'C0>²Ìär9hšUU�Ç¡( [`]ÿo6Ö×?‰>‚8ñ„B!.™L@©ÿh¢};qwüa·[o½µî†nX;sæÌµµµµgTVV†ÜDßlbØ×Øzn'�´ ýxû£1d JÇj³Ù,r¹\!�_8˜�ZM€Ó*� @'¶!ÿ1~·®};¡!ü‚ ðW]uUÕg>ó™S–,Y²vÖ¬YkÍËõØ,yv³vì—å;Eøå°üÎz<”!(ÝC½#Š¢Ä_Ó4hš†t:³ˆ?ïb8‡÷™2qì ‡Ã\2™D:�ká/¥–ïí ·ÜrKýÍ7ß|~CCÃ_×ÔÔ,’$‰7_”Í“Ùt]/ˆ{œ}tŠòí„¿\´2ÎâÏ2J, ª*›¡%“ɬÍkØi� |2qbàyžK$c!ünÓ÷J}�ã8þ¬³Î nذá´3Î8ã³ ,¸ HvÑ<0¼TÁŸÝÜRû“QðÉŒ ¹\™LfX€çù�d2™+Qü?A€ މðëº>šæ¾R¦ò•峚)Ùe—Õþíßþí+V¬¸jÊ”)óEQ¬âÎ"0ó|}³ð;‰>Ë8¥Á ï†`²›‚l6‹L&ƒl6 EQ�o–�æ3n»Iº¥ÿÉŒ’ ˆcÃQtõ‹øí&ïü‚ðK’$|ç;ßY²~ýú¿ž;wîúp81OæccøÙæ+¥DúVÑw«íS´ëÝXÍS¹Ÿ3ëñ± €¹ iZWÞ8•Àì¢~Z @€ Žldïtõ{Áë$þ‚õóÅ‹û>ÿùÏŸyÉ%—ÜÚÐÐpŠÏç“Í\AFÔõ­ÂïUô½DTvæÀ­a�˜¼ç,“É �Nóï­>]×íÞ€ûî–æ÷¢ÁÎ!eÈĨa ~%Nîó’ê÷¼\ÏNüÏ>ûìÐ7¿ùÍËW®\yÃÔ©S˜·ÖeÂnÞX¨X´4¢ïEàœ&“ãœÙ J$H§Ó…ˆQ,åïé$ø|>·5 2ázÑ*Öà7Ö¿›è ø;î¸cÚ§>õ©+—/_~YUUÕSYYYgÊL:ú5M+QGÔ÷Ë]øÉL̬ŠÝïìëë–Èï ¸‡ÄŸ A—¨ß¥ÉÏkº´�}…ûg�uVè®»îºpÍš5_®®®žiÞ(ż”Ï\ß·vôkš6îkûd&o†Àú;4MC4fš¦uíaÐ3I€ Ž6ê/%Ý_l`�­ð/Z´ÈÏ=÷œ»nݺ¯Ö××/0 ¿ …ýÑ�„ŸEû¬`5$zdÆ:C0Vç+—Ë¡¿¿l­\.A²‰D¢Ýƒˆ$ôd¢´«(rù¥F£�úíÖó‹øG¤úÿ÷¿èÆoü¿³fÍ:˼Ž_E– u~kÄoרG¢G†`¬ÏÙh› ­ß388ˆh4Šd2‰L&UUÁó|[6›M:Dò†Ãcv)@€ †_ƒØ`œ£þR—ô nâÿ¥/}iæ�7ÞxÓ’%K®ƒÁÑ¿µ›ßkªŸD�Î͉8gvç0‹ +èºI’öfLboØ¿áAü d22dˆÉ ›ß_Dø­yË}§?¡ˆøn+W® |ûÛß¾~õêÕ7‡B¡*–Neô°ÿ‘ÕýEQ´þ±¬ñ“èѹ9ç̺,UQttt```ÉdlæF:�Þa|ü¢6,ânx}‚ A€ã8/â_JÔïebßñ衇κüòË¿n®ó³Èž¥òY7¿$IÇ\ø½^ÀIøŠŸ2îçÌîüär9tvvb`` 0ˆã85›Í ço("údÈÄHÂá0—H$Æ¢Öï5Õo'üâW¾ò•Ÿÿüç¿ÐÐÐðW~¿?È¢!ÖàÇ–ô±T¿u»^ë|þÑÕo×N¢‡Ï �G>âœÄãqtww2š¦Áçóu÷ööÆL¢¯Ã¾àd ¨þO€˜ô/HQtÚ¼g¬£~Ljþüùþï~÷»¯^½úK5553ÌëöÝêüãIø½DÁ$ztn¼+]]]èííE</ìÔgÆUU•"¢ï$ø¶ÂÏŒ6A€˜$×—F¿±Šú#~¿ß/~ï{ß[~饗n˜={ö6º— <[�`­ó†UUGÝÜ7ÞD�„�Î�SôŸËåÐÜÜŒþþ~Äãqd³Ypg(ŠÒèýë°ï(Ö$žçÉ� Ê¿ßï´s_©Q¿—õüv7ñꫯŽÜyç�7,[¶ì³Á`°Òá³t?~õOTá/&zì>EÁÎçf2d œÒÿ­­­…º®CÅÁîîîCø¸þ_¬ ›LÍ @L6$IâXqâ_,ê·‹öùüë^ VTTHßûÞ÷ξôÒK¿0mÚ´SX3xsw¿¹Îomî›ÈÂOQðÑŸŸr<7ÖîèééÖ‚ ì‹Çãi“èë6â¯{‰úÍø|>84dˆ2¸À¸uù[Sþ¼ÍýѤû™ø ×^{mí=÷Üó¹E‹}&ØE�¥Ù…�¥ûÍóüÍ¿5Bœ,Q0eÊ÷ÜØEÿº®cÿþý…@EQÀ󼦪j£®ëÜÿ€{’É$eÈeŠÝÖ½^Sþ^›ülÓý>ŸO¼ë®»~á _¸¯¾¾~ «õ‹¢XHë›KìqEQl#þÉ*€Ô8çýÜL´ócýG£Q9r}}}ˆÇã0 ‚ D£Ñ�&ñ×-÷GS Èeù‚Ë�óuˆú‹‰)kúGDüÄE‹ùÿõ_ÿõ†sÎ9ç–`0b;A†5ù±®ÖügM÷;Edh­½—ó3žÍ3¿Vš›› õ–þ°···wÎõÿb&€–ÿ‘ &<Ï—ÒåÏ{0v ~¼EøE‚(Šâ}÷Ý·èšk®ùê¼yóÎâyž³ÖúÙçìhÝ–×k�Ÿ ÁðsAƒ‰&–Y²ÿL&ƒ}ûö¡³³±XŒÍÀгÙì›6Ñ¿×$þdˆÉÇqv)k”oõ—Úäg�üÅÙ³gË÷ßÿúõë×߉D*Ý¢~vË?2ÎÂG{³t¢Œ’Sôßßß�ƒ¢··lNÏó±Xl¿EøíJ^Óÿ#À–×dˆ Œßïç2™Ìh—ø•²i�`ù‹W_}uÍ7¾ñ�»–/_þW‚ ð†ÕôÙÏ|Ñ3‹”ƒi$S`Ÿ! Cpb2æ½-&]r‡­[·¢¥¥===æÎü·Sy¡×`Ÿî÷j† “(Ò 2D9ˆ¿CÔo'þL…­ÂÏadºŸw~Â?þã?.¹ñÆÿiêÔ©sÌÓüœ¢~³ ïe}vir2T28žçÆš˯ñGGGöìÙƒ¶¶6 °÷Ž–H$^5 ¿n1N«€â£� 2ÄDF7ñÍ(_§�>¢å¾8gΜÀÏ~ö³kÏ9眛ƒÁ`$ÿÿ€ã8ר¼¬ç§ �s$L‚csnXIŒ‰?[«ivíÚ…C‡¡³³¹\Ž}ÿž®®®^ŒLÿ;­ÿ·Ë ;ó'Š¢� @LTñwáYj­Ÿƒû¦=¢å£tå•WV|ë[ßú¿K–,¹Üçó €ýò>óŽ}V0ž/öd L4ÆçÆ\÷ge/ý·´´`Û¶m8|ø0b±EUÕW ÃP-ѾS3 ÷M€HìÉåÏóvâ4õ~/Â/xà�×\sÍÝÓ§O_j^Çï”òŸÈSüÈLÎñ¼c}nÌ+_XÄÏnº®ã�wÞÁîÝ»ÑÒÒR¨Ésw¸««k§�øÛ}îe'ÀaYÚˆ 1AÅ¿„á>NõþRÄ_ Κ5Ë÷ãÿø“ŸøÄ'þo(ªbÃRþLü'JÔO†`ôç� �û¹1d«ø+ŠY–±iÓ&lÙ²‡B2™dïqU×õWS©TÃëýNÂïeIà0#@ÏbâáUü�Ö÷—Üá�¡zèÑG½í”SN¹Z–e¿yÛ^¶��]“€cÒáO†`|‹‰ÌǽfñWUµ þ>Ÿû÷ïÇ«¯¾Š¦þå Àö–––÷M¢¯¹DÿnKa'þ Ë2æ…dˆñxMqyÌMüݺü‹Šÿí·ß>ë‹_üâ7,XpÏóœ]Ê¿X£ßd2T2`Çi�üUU…ªª…¿ÎÎN<ýôÓØ½{7’Éda¶ ýÉdò™L&“µÍAü½ ‘~£=È_üÇb°�m­_–eék_ûÚâÛn»í;S§N� ¥üyž/Dìç&þ“YȌ̔ûë€EýÖn&þ¬ùïw¿û¶mÛUU¡( ˤ)ªªþ®½½½Ý"øÅ„¿”�@b"àóù818ˆ)Í~n)ÿa7AÄŸÿüç}ò“Ÿü»ªªª `¨ËYï/&þÅ„`2‰"‚ò6¬4Æ2bº®Ä=›ÍÂ0 ȲŒ�7âÝwß… …ïÁáÏMMMïY"~ÕCÀnIàˆÓÎîP bœ#IÒhÄßËÖ½Žé~âYg�úÖ·¾uÍyç�w«¹ÞÏ:–­)v!gc}K‚É<�†•‡!0ϼày~X³ŸªªH§Ó…Ç~øalÙ²�@ÙlÙlÇiš¦½}ðàÁ¿äß|+¥ Ø vm!@€Ïâï0¢s4âïÔåo6ñì³Ï®øþ÷¿ÇÊ•+?-Š"ÇqdY.D/Çz°Ïdî.§ÁDóuÀÄŸeȬ�þ™LÇa``O>ù$Þ{ï=ÔÖÖBÓ46ñÏH¥R[8𜪪98×ý팀�kÿ�Éd¨@€(ñ7/ósÚÅOð"þ]tQÕøÃX´hÑÙÀÇõ~vsª÷Ë.ÿɾ܌JãûuÀ 1«÷[;ýÓé4$IBGG6n܈ÇcöìÙPUñxš¦»?úè£g5M‹»Dÿ*ܛݦÿ™3´¢LÅß­Ó_„sÍ_ºñÆç}ýë_¿wþüù'Cõ~ëH_ëT¿Ñ¤üÉ�!(‡×�yÏ ö7Í)ÿ\.‡T*…p8ŒÝ»wãÑGE<Çüùó¡( ëú×>Ü´{÷îç Ãè¥ð»�¶Í°<bâŠ?g#þ%×ûHßúÖ·NÞ°aÃ}Ó¦M›ÍÄßm¤ïxìC†€ Áñ~X»üíRþ𦡢¢/½ôžyæø|>ÌŸ?ÙlÉd™LFݳgOËîÝ»_7 £Ã&ò7ó(`/M€®ÝÿªªRøO€O8tû»M÷³[ãïUü%"ÇqÒ�wÞ¹rÆ ÿßôéÓëó&dÄpŸ‰4Ò— ‚cù:`é~s—?ÿ\.‡t: Žã ª*~ó›ßà/ù êëë1mÚ4Äãq$“I¤ÓéÜŽ;:wíÚµÀ>ŠƒèÛ­8ê@b<½8DÑ«ø[…ßm™ŸSÊ_bö³Ÿ]uÕUWÝQYYâ8>ŸŠ¢:ýíFúN´©~dÈŒÅëÀ:Ø'I�Hù‡B!ìß¿O>ù$Ž9‚•+W" ¡»»‰DÑh4ùÒK/µöôôìÐ �7ŠÉØ·�@ÅÆ ådˆq&þ6õ¸RÅßóú~Rmm­üoÿöoׯ_¿þ¦P(`)M¶­°�øŸˆz?‚co&«)(åuÀÞì}ÁRþl²_:�F&“A0Ä[o½…'Ÿ|~¿k×®04ñ/™L­­­±wÞy§»§§§À)“È[Eß©ÐËðkÔ_¸�H$µï´ IDATèÂ{œ¡]ˆ8Ôü�•ø³Èß÷ÔSOÝrþùçN–e‰Eþ¦ýÇGtú; GY¾Q'ù¦6´AÌÇçÁ<ËßÚåoŽúÙãÏ<ó ^xá,^¼Ë–-C2™D{{;âñ¸öÑGõ¾öÚk}¹\îC;M‘@Îr3?¦˜>*p.˜çØe`c Ê'�5ÿbÓýÜÖ÷�0§œrJÕ}÷Ýw˺uë>Ãó<'DQdƒHlÅßù—»@R†€JÖÈŸ‰¿9êÏd2H¥RèîîÆ/~ñ ´¶¶bÍš5˜3gÚÚÚÐÓÓƒÞÞÞÔæÍ›{·oßð>€2¦¨ßîV,ú×]²Ž"OËÿ(@Œ_ñ· ©‘¿µæ/™?Λ7/üàƒ~yÍš5WŠ¢È ‚I’�Íf#/iÿÉ¸É eÊÿÙ`ÖìÇæõ³µýŠ¢  bóæÍxôÑG!Ö®]‹ŠŠ 9rÑhTokk‹¿ôÒK±®®®^ïh5E÷Š%âWl2NÆÀne€Õ –‘ÀÁ`©TŠâD 9–6t·È_°|´ÝÈÇl–-[ùçþç»V¯^½N®Øÿ£éôŸ¬†`²š‚r;fö~�$iØ.~Š¢ —Ë!‘H²f¿ýíoñÒK/áä“OÆi§�†t:�¶¶6ôõõe·nÝÚÿÖ[oe ÃhÏ‹·�ð[ÅÞ-í¯`xÚ_uÉÐF@dˆ ôZðù—Ô쇡Ѿu÷Þ{ï—Ö¬YóIžç�©ø“!  ÁD>n–ò—$©ð~`Q?KùK’„x<އ~ÄÊ•+ÑÐЀÞÞ^ôöö���‰×_=vðàÁ,€#>Ðg#ì^Ŀ؊ÝkôÏó¹\Š¢ •J!�N£¢¢Ï?ÿ<~ýë_#‰`ÕªUÐuÑhÑh4»iÓ¦ž]»vi:1Ôì׉�kûŠCÀjÔü}§Èß: ÈÚñoŽþJÿ“ &¤øÛ øñ,þ<Ï×<óÌ3ß\½zõ9ã%ò'�t?f2ã'ògâŸL&¡i*++ñØc�á÷¿ÿ=æÌ™ƒ†††ÂHßöööÁ—^zi §§G°CKül„_qˆös°d®ù[WØEÿŽ€$I‚¢(dÈeùKCïuiÊÆ�ï¼ôÒK×J’Ä;‰ÿD™îG2ÇKüu]/4û%“ÉÂ{dãÆ�xã�70þ|L�:Ùl‰DBß·o_ÿo¼‘Îf³1 ¥übh‰Ÿ5�ï”æ·kô3´ \l@<¡9“óBÆÙ4Óy§ €£øË²\óãÿøo/»ì² Ý"ÿ‰0Ó¿på²DTÎódŸC`÷\¯ÈßÜéo²Ù,~øa¼÷Þ{X¶l***000€T*¥øá‡Ýï¿ÿ~Ö0Œn uù÷Á¾Žïõ1óD@§� —Èßñ8ií?eˆ‰'þì—úÙŠ?€š_þò—_»òÊ+Ï“e™÷ù|0lG?óv"ˆ?EÍt¼Ç"CÀÞì=ÂÒþ,­/Ë2úûûñ£ýûöíÃÒ¥Káóù�J¥‹Å²[¶lé;pà@ÀGù[ÎC}r._süS¬áϮ럢ÊãâÉvžïïVóµø‹¢X÷/ÿò/_¾âŠ+V˲ÌK’TˆhØÅÎ0ŒÑ9FÍ“AiZáè§š‡ü˜ÅŸíä …ÐÙÙ‰Ÿþô§8pà,XˆÅbˆÅb™ÆÆÆÞ–––.Û´cx£Ÿ ~/âo7÷Äš6þ!@gü~?Ç6ÕqÉqÂï”úwjøTÝsÏ=Ÿ¿æškÖúý~�M/3�÷e°É~Ç#ÅJâxb g`òÖú¥R)ƒAôõõáÁľ}û0þ|ð<�X,†ÞÞÞäÖ­[{;::Ø�¡”¿2Ê›Óæ?vÂï¶é�c´Ïq4M£èŸ q¼p˜òçe¾¿[½_€sÚ?tÏ=÷üÍW¾ò•K+**xI’ IR©”m·¿ÝhßrÊÉfÌϯù˜'k�ù¹6Oø0lC¿ß�®®.<ôÐCسg Ëüºººâï¿ÿ~×ààà»1r _»¨_-"þœ›ý¬óþ­Ûýê6Ñÿ°ƒE6�dˆcE‰âo}îËýì2¡ë®»î²Ûo¿ýꊊ žíUžN§]'üMv¡œ¬‚É´¡“Ýñ›·ô5‹&“ÇqèïïÇ/ùKìܹ³fÍ‚¦iD___êÝwßmËd28 û.ÿÑFývÍ~N~tØ�ö!þùÆ_ŠþÉÇ ‡¦?³ø#'üÛÜgÄùß|óÍ—ß{ï½·ÖÖÖúYC“ÝÆ>£]ç?Ù ÁdÈL–’�uÐ�ªªÈf³H§Ó…2ëöŸ6mTUE2™DOOO|ÇŽ‡3™ÌûÚÈ'W$â·[ÖWJÊßm¼¯ëZËóKâO€8nO®·¦?Åëþ^–û…¯¸âŠ‹î¼óÎ[êêêVñgé^v 𲣂‘ÇiÈÉV2(§cfÛ^³÷ëø7 >Ÿ¿þõ¯±eËD"hš†x<ŽX,–Ú¶mÛ�L&³CSý¼ ¿“è;¥ûU¸ø)&þ#Rÿ6×"‚ 1NÄ¿˜ð[kÿæ†?ÿªU«ÖÜu×]·444„9Žƒßï/D2vC~ŽU00YÖçO¶9åföXÇ?ûßÙZ]× …ðøã�ã¹çžC0ÇqˆÅbHïܹsw&“iÐë1òWá½ÑÏ˦>nâñ§èºméë”ö÷WVVž÷ä“O~åÜsÏ­câŸÍf¡ëú°´?»xŸÈ “¥ÎL£‹Ç÷ÿéóù  ›Í"›Í"•J¡²²Ï?ÿ<6n܈L&ƒ`0ˆx<Žd2™Û¶mÛfEQÄQÚúþbKüìšýJ™îç¸ì/oüIü)@œ`ñ·Ëxíú·¦ÿ™øË<ÏŸöŸÿùŸ·œ{î¹uàóù ‘ÌxÊ”Ù`"¯(ŠñWUµÐøW]]�-[¶à©§žÂàà ***‹Å�H$”#GŽ|¨(Êf ”6ÍÏ‹ø—2ÜdzøçŸ2Äñ‚çyÎAdG+üvküÙçKï¿ÿþ[.¸à‚¹ Ë24Mƒ¦i#Du<Ïö7 G9‹¤] }²• Nôñšëþ¬Ñ/›ÍB–e8p¿úÕ¯ÐÜÜŒ`0ˆ��Äãq­³³óÃh4ú¦CäŸóhF“òw~ÝFô)ò'@œà‹ g3aËMøÝjÿ"œþ|æÞ{⦅»å–[Nöù|\±¿ãycŸÉ˜!˜Hs¹¯u½6›E.—c»âaãÆ�عs'$IB<G"‘0úûûwôôô¼aÿR6ññ"þ:¼�õÕ"~ŠüÉ'I’8›vc~�¢Þ·÷�uùå—î–[n9Óï÷ó,�ÉÖ.O”ÈŸ„²xÄ\î†àx™=ëzEQ éÿp8Œßþö·øàƒ`Òé4‘H$Ú;;;_7‰îÛ÷Ú5þ9¥üU“𗺛EþdˆñD‰â_lįÛr¿ú /¼ðºï|ç;Ÿ¨©©YT“N§Í€²›ëï$“­dPΆÀjöÆòxÍsþÍÛûF"¼üòËøóŸÿŒx<ˆÇãH¥R½ÝÝÝφÑ_BÔï–ú·Kù—Zï\Öú“ø“ N œ‡Ï­)Þ–û™ëÿ®¼÷Þ{Ïkhh±nfóZ§¨Ùz¡ ‘,ã3™2£}nÍsþ™YWÁ`GŽÁ³Ï>‹Ã‡Ã0 Äãq(Š¢$‰¿är¹v±wËxIûÛEþN³ýÍé;ôC€O8Ôý­¿ÝM@isþC‚ ¬}ôÑG/:í´Ó"†-÷3§N½Ž÷�L† \�s2eFcØ´?–ú×4 Š¢€çy¨ªŠßýîwضm[a`.—Ó³Ùì«Ñht¯Eès6‚ïýKû›çú.‘?P¤ÞOëüÉ'—þ¼¦þÝêýæÍ}üÖÝwß}Ÿºøâ‹§±)ªªŽ;�/ELÊM,'Ó¿ÉÞC`w¼v[ü²a?O?ý46mÚ„h4ZØúW×õ�½½½�(¾ÔÏKêÿh:ý=‰~Ù/‰?âxãAüyx_öç4åO°äú믿äoþæoæI’Tèøg}æ ÞX5ü•ëÖÀ“iÆÿd/X§ý©ª EQÐÔÔ„çŸÍÍÍ…À<ÏG£Ñ諊¢¤m¢};ñÏÁ[Ç¿—Nÿ’Å€‘ËåèBL€8ÞØlòù˜/c~�ÿæ-Y²äÚ¯ýë kkk%ÖÉÌÌDZÿb‚rN¥SÉ lޟúþÙ¬Q‘J¥ðÔSOaß¾}H¥RPÇéÙlöÏ=p®û{‰ú•#ëx_ Èpžç¡ë:EýeO§`âáóùŠíðWlà�o]ÿ‘ŠŠŠKþéŸþéÔùóçû9Žƒ,Ë#6ø±éc-&åºÒÀ|\º®6M*Çþªr>NfÌ�º®Ãï÷ãÍ7ßÄ|€îîn(ŠÂŒßŽ=(¾}o±A?NÝþnÛùÚ­ï·QIü)@œHlÒn¥.ùs~sÓßšoûÛ«/¼ðÂHÞx “É"U¯MÇ3º,Ljr²Lð+—ã´nóËÿü~?ÚÚÚðüóÏãСC…÷± ƒƒƒ/麞ƒ{׿×Èß-õ?ê%~ù ¾HüÉ'òúRDü­üØ 1 8ë¶Ûn»ô†n¨gM,R³‹âÆ£�”³!˜,ƒ‰&âqšÿXô/ ÃÀÿøGìÝ»±XŒ‹¡(Ê_zzzº=Dþźþ�Rÿni HÊŸuù³YDù@%€‰ôdñ|±+Ÿ—q¿Å"€“Ö¯_ñí·ß¾  ò,•imú›()Ûr.˜��Jã#ú7×þÙÞ�@Û·oÇ»ï¾‹ŽŽŽ‚‘EqGGÇvOý»5ûi%Š¿Ž‘óümÅ_’$ZâGâDãaÉ_)“þDPï÷û¯þÚ×¾¶bÖ¬Y>Ã0àóù�J¥Žz¹ßxÍ”[ôq÷ÝwÏš;w®ÌÒ˜Ö�Ǻ!˜2å5O† �uR¡]ôo>øà:tÈýkŠ¢¼’ZÏ«À[ƒ_©ã}=‰¿ $þ€ñJ‘�uì:ý9_ògÞío € n»í¶ç�w^%«û[Ç Ÿ¨Õ@åžv¦’Ay§]í:::ðöÛo£««Ë<ò·½¹¹y—Áw‹ú‹M÷³}Ú±Ð4�ÄŸ 0qØéÏ­ó¿Ô €Ày ‹¿øÅ/Nƒ¼ynùDоÊM4ÉL¨÷)DQ,Lý3›÷ÆÆF9r¤ýó<¯©ªú†¦iYŒ¬ó; ¿]ôï–ö׋‰¿ $þ€ñŠÍÄ¿Ñ ü)–ú_ÁqÜê¿û»¿«Ÿ3gŽ�çyȲŒd29¡D¥œçáÓ²Col÷¹U�‹½~FÓìÊRÿvµÿŽŽlÞ¼…Ξçwvvî€óš/ëüí6öñ¼©‰?A`œc3î×-`õüS`Ý'?ùÉê .¸ Âvù²™4HQæ8ÍL¦ �õyäy<Ï«¿[χ—ì�Õ@²ÏYÌm¿ùû|¾‚ÙPUµð¿±è¿¿¿¿Ð(©ëú{©¡uµNµ}/ëü‹­ûwJûdÆ9�@€³4àÛæ—+"þÖÈ?àžçgßyç�õÕÕÕ¢(ŠÐ4­P§,ᤂ‰n&¤lSv¿”óá5Š·ž7»z¾¦iÃ^Gæÿ…½wØÔ¿¾¾>¼ÿþûèìì,4ÓJ’ÔuðàÁFØ/óóÒèç¥á�"‚ À$‰þÝÖÿ»­û_àŒÏþó‘åË—yžG0D</{á$C0>ÅžÝ$I*¾�0›£só}F‘¦YGÌåÙ³ûìkvæCUU¨ª:,SÀfþ9r}}},ú7Ey[UÕJoúÓ„¿X €"‚ @Eÿ^›ÿÜêÿµ.˜7o^ø‹_üâTI’ Ë2Òé´k´D†€ ÁXо9²g tff)w³¸2q·KÇí^ìw³Ÿe³7Ì&ÄlìJ†a@–e´¶¶âƒ>@ggg¡ŸFÅþþþþàÜìçec¯Ñ?¬&@×u‚ ÀxǺöÞ%ú÷*þfàpÇqó¿üå/×Ô××ûDQ„$I(uü'2£‰òEQ„(Š…5óæSlÃ)MÓlëîNÕ­‰ÏÍÔZ{ ò£pG|�=fÎ.Øý^I’�Éd°iÓ&´µµa`` �¡Ð4­±¯¯/Š‘u~ÍAø½¾'ñ·Ë€qF0äØÜ}Ñ©‘¿`€óÎ>ûìÐUW]U#Iü~±’è„Ó=•‹!(7Sp¬ �¹Žo}öwu]‡¢(âiëÿd~ŒýŒ®ë“ ëz¡ Ÿ}]E„B¡‚îfØýL&EQ ÿ;û;,Ca.M˜3’$!�Ncûöí8|ø0²Ù¬yÇ¿äÀÀÀfݰ¯“þ†°,˾±— 0™£kãçÆ?·M*\$BÅ—¾ô¥šp8ÌK’ŽãœF �‰¸”s7>m�<s³«ç[£|6bš½>¬"Ï„\Ó4¨ª:쪬¬,4ªJ’„þþ~ôôô@Qär9D£Qtuu!›Í"—ËAUÕ‚ˆ›Ÿ3s‚uò˲Œºº:ÔÔÔ@–eÌš5 ²,L úc5©T mmmèìì,” ØßÔu}[Ü7ö9Ú¿¶MÙl–¢‚ ÀxÇ¥öo½”6ðGÈGÿ'XtÝu×…Î9çœ*AضŸ'$’¦’ÁÄ4vÇe^Š'IÒ°¡8¬ŽÏnvbÏZQ”B ¢¢’$! ¢¥¥𦡥¥±X ]]]صkz{{‹Å�Éd ëú°eyìÿ°6šÍ»±¿ËÌO¿ß�ŠŠ ÔÔÔ`úôéX¾|9B¡‚Á ü~á÷32™ *++!Ir¹$IÏóz.—{W×uÃÓün¿Ûr?×f?³£¦?‚ ÀÁ! ïý—Rû¯°@àÊ+¯¬ …B<÷{¢&þ‘!˜øf€Eû’$¢}'Ñ· >‹îs¹\!ºf«zzzpèÐ!¼þúë8pàÚÛÛ ß‡1cÆ ,\¸gœqÂá0ªªª‰D … kò³Ù,2™ Òéôˆ[&“A&“A6›&þì¾õg›››qàÀ¼ñÆE~¿•••˜2e êëë±bÅ ,[¶ +V¬(Ìþgÿ«ªª{:töƒ~4Oûøck¨é� 0A/¬.Ñ¿[À) X `Þ…^è_¹re˜]ÄÆÓÄ?2í³H›Eûº®Û.‹c¢ÏVÓ´Bê]–eÄb1¼÷Þ{hjj¶mÛÐßß¿ß�9sæ`áÂ…¸æšk0eÊÌ™3S¦L�$Iº®#›Í"�N#‘H �"‹!‹a``‰D¢ øæ’€uu�ùÿe[a˲Œªªªa�‹¢ˆ`0ˆ™3gâÌ3ÏÄòåˉD ËÓé4B¡Âá0"‘ˆ‹Å6†áu+_¯óý7÷aÙ‹ñ:Ê› @ŒL×9íøgÎx�õomþ›àŒ@ àÛ°aC] àü~ÿˆÚêDΉ.žù¸˜²ˆŸý¿,‚f¢jN³³Ú<›4)‰>Œ÷Þ{o¿ý6’É$jkkqá…âÖ[oÅܹs1eÊÌœ9sØ9ÑuÉdÉdíííèíí5ÚÛÛõžž-�jZ*•B&“áÒé´žJ¥´\.gäEßÐ4�cÿ›éµÏ �zŽãyžãópCð¢(Š<Ïs‚ p²,#ƒm˜‰DPQQ1lh�ßïÇŠ+ÐÙÙ‰x<¾÷È‘#;á}Äo±†?Eºþ)õO�˜`؈?l"þbãíÌ€Àj¯¸âŠà©§žbQ—eµÁ„Ê�”S4m=®ñxL,Íïóù M}†a —Ë"zsÍÒ躮Ãï÷C–eÄãqlÞ¼›6m¾}ûPQQ�•+WâŽ;îÀ¼yó°hÑ¢aev>2™ õîîn½½½]?tè�ÒÞÞ®555©GŽQûûûõX,†d2É%“I#ß\8ê“ÇqœÁL¹(Š,ÀWUUI”)SÄD"Á+Š"Æãq¾··—;çœs‡ ÏÛªU«ÐÚÚjìÚµë•ÁÁÁŠwû«põkÀc×?¥þ 2ŸÏÇY·Þµ1¥Ìü7GÿóœÎqœ¸nݺH(âYôo|2Ñ£érÏœˆcbMu¬á�ý_Vág5ý\.‡L&Ö`šN§ñÎ;ï`Ó¦Mغu+‚Á .ºè"\wÝuX¼x1jjjFlØcâñ¸ÞÖÖ¦îÞ½[Ù¹s§²{÷nu÷îÝÚîÝ» ‡IV!4Žöüç3l �ÖÕÕ¥°o‘eÙ˜7o?gÎ.“ÉC¡�¼råJŸ,Ë<Çq¨¬¬ÄÊ•+;ðƒìEñþ̵~kÀSÊßœ}‹%½Ä䃣S0.ν—M~ìÖ÷³›Ït ¸À©õWþÁ~0§ººš¯­­E2™t\ÿ]NÝëå¶UðñzžÌÝô>Ÿ¯ ŒæÈÞœâgkçC¡$IÂþýûñä“ObÇŽƒX³f Ö¯_�+VÀï÷�È~¥Ói½³³SݹsgîÅ_ÌþÏÿü�Ú××gä_£N‚w¼"];cae}éÒ¥üµ×^+Ÿ~úéú™gži¼õÖ[¹þúë_5 #Àé¦Xn£Ùù¯ðœ㹦G� J2,í_,Ê÷ÙCËþnþÅ/~Qá…N©ªª*ié_¹™‚r49citXsŸ,ËÃjü¹\®°b„ ?ë”×uÕÕÕˆÅbxç�wð§?ý ÍÍÍ8óÌ3ñ©O} +W®DEEň1¿±XLÛ¹sgöå—_ÎnÞ¼YyõÕWu‡5ë^óúõRN”“øö©ø€Wjkk÷¨ªš‹Åb™¼°Û ÎAüÝ–º¥ÿIü‰QC%€qÒE‘³ áqšö甲¬öª¯¯—–/_^)Š"***Jêü·KG—[É \MÉ€ Åa?k³ð›—í±y‘HíííøÃþ€—_~²,ãÓŸþ4Ö­[‡3f }UU�îîn&ú™gŸ}VÙ·oŸazý_kÞüF�5 §YTU‹hÂòÞó7óûIÎßÌßë&þv& ÀþÞÞÞ¬é)á;�ýÕá¾Ë_áüP×?A`b#þÖûn n«æ8wÇwDª««…@ Àö#¡™èu¹Žø-õ¸Xg (¶¦iÈd2ÑWUµ°ÔŽã8ÔÔÔ`Û¶mx衇°}ûv,[¶ ÷ÝwV­ZY–GDú›7oÎüæ7¿I¿ð jGG‡á]³ûZ^0Óâ’yA�ÈXÄ_ƒ·yøvï+óû‹eÐØÔÌJ m›]‰¡ršdy�ZÅXp ÿ¿*°_÷ï¶ЭëßÎt ®‚ ÀÃfòŸÝ… E¢Á&ú÷8@EEE…¸jÕª AƼó¿ÜÖ¸O¦Yl ®ßï‡$IPXSÏü˜ð'“Iˆ¢ˆªª*lß¾>ø vïÞ�µk×â¿øN:é¤Âï€L&cìØ±#ûç?ÿ9õøã�çöîÝë”®6‹ý †Rè½ùû‰¼°FónMqÅRâœÃ}7Øjš €:Õªò×k’S IDATŸ‹¦¿Õ `F¦÷­óÿí‹-ùsœüG�€ ˆeƒÎæ‚d-xþ3 ÀBÜÕW_š>}º,Ë2dYÆàà èQÏD7æt¿ßïÏóÃüÌÂÏ"þH$‚Ý»wã�ü#öìÙƒõë×ãî»ïÆìÙ³‡5 öõõ©o¼ñFú¹çžËüáP{{{íYËGñƒúò·D^ü“(:­{w‹öÝ ç’ ñÔ[þ^<ÿñ�)[É›�)vç3^6ûÍ&?¶Ç•Éd(ú'ÈL4\RñN5s Ómòß 5¸Õ«WWúý~. AQ”* å°LÏ®Ö>‘އ5ù�‚p³t?æÃjüªª¢®®‡Â#�<‚Í›7cÍš5øÑ�~„ "~Ã0pðàÁÜ[o½•~üñdz/¾ø¢f#È †Rã±|„ß›ý,>Ná{YïngìľXôï% `ý›V‘î1ý¯|>[áV÷w[þ§Ûü-7ãCÑ?A`¢â÷û9Ó—óx³š»ô†ÆþJµµµ¾E‹Ù†*'zì¯ÓÀ›‰j&Úñð<Y– Q?€abÏ–óår9°Y�=öž{î9œyæ™øþ÷¿�U«V~6›ÍMMMÙ§žz*õÃþ0›H$ìD?  Céñ~ŒLé.­‚X,à5öZ0\L€uí>u·ÝþFýƒ¢‚ @™á�sE²Å5`(É}ö³Ÿ UUU lÝõÑ4ÿ5 g9‚ñr<æ¥}²,AÓéta6>›•Ïfà766â‰'ž@(Â7¾ñ ¬Y³�@º®#‘H‡Ê=õÔSÉGy$ÛÒÒb­çÇ1”ÖïÈL:ˆ¾[ÍÛë |¯õ®ÄÏ­Ãîÿ¶3*FÖüíÖõõÄ?Y–­eD‚ 0°ãbÀܖ²�Ag�DQäO?ýô°$I¨ªªš0iÂr,œHCÀFø²�s Ã(¬ßguþT*žç …ÐÔÔ„ÿú¯ÿB4ÅM7Ý„µk×¢¦¦¹\===غukú™gžI>þøãÊÀÀ@a†RßÝZó“pßÏÞ*¨£-&ä�"ú‡Cô_, à5ò×à­æo8™:‡™ A`"E‹.Q¿5íï¶PP`&nÙ²e¾3fئ-±NX޳ÿ�§!0Gý<ÏC×õa[àf2¤R)ƒA¤Óiüæ7¿Áo¼�5kÖà†nÀܹs‘ÍfÑÒÒ‚Ý»wg_zé¥ä#�<’íëë3/{ÌGúí¢ªéëQ®Q‚ °3@ñ¦8ã(„Ÿsø]ÖÿÉɸ™'ñ÷’ñ‘í�$ .ãà ‚ ÀxE’$ÎTMäo×ÈšÿB¸3Ï<3XSS#„B!ëÎg4'¿Ì�ÇœògåUU‘J¥ M~©T ¹\ÕÕÕxï½÷ðØc�AQ|õ«_ÅE]8tèššš´W^yeð‰'žÈ4773R1”æ?‚¡Á7 ŒÜÌÆ-½]Ì”Ò7š(¸˜p›ôçÅhð¾Õ¯Ý1£Xf#—ËQôO�˜ˆØÔÿÝÖý»eÌÝÿ•!¿­é¹çžæyUUU#"§=H@'þñpÖôÉvÕcËùX­?™L‚ …z衇ðÎ;ï`íڵذaC¡ëï޽ƞ={’�=öXü£�>bâ¤`¨{ÿ†:àÓB_,õ?Úô?PzÚßKç?ç"þ¥f48Oú+e‹_Ã-³CSÿ2åçb¬¢ïff!¿ô/‰ˆS§N•}>$I*:ü‡ Ay�µÞφú°%~ététÓ¦MÃÖ­[±qãFôõõá«_ý*Ö®]‹ÞÞ^¼øâ‹hjjÊ>ÿüó±×^{MS…¥ú»4èÄÇi~m” TñÇDþ£©ýΫÜ €õq§lˆ×cvì~¿ÿ„¯è!Èc+þ^–ÚEþ<†&ÿ-F~Téå—_¬¬¬�²Ù,JÝ Œ ÁÄ:6ØG–e˜Ç=³4.—C"‘€(ŠˆD"xâ‰'ð»ßýË–-Ãí·ßŽêêj¼þúëhnnÖvîÜ9øûßÿ>ÝÝÝÍRý=ùˆ¿ ¯Ù×Gi¼¿^WW'iš¦õ÷÷k8ºNàN>ù䊓N:©¢¶¶Ö‡EY–ý>ŸÏïóù$]×uEQr™LFI$éh4šíêêÊöôôd<˜Ìd2ê(2^Rþ^3#H&“”þ'ÈLDxžç–ã�¶PÀÐ4²ùìû/^’e™«¬¬“F!;A5÷ñs<¬ÞÏÄ?—ËÖó³F¿ÊÊJôööâþûïÇÁƒq饗âœsÎAoo/¶lÙ‚ÖÖÖÔ‹/¾Û±c§€ýb¨Ã_s}'¡ÓlDÓVøg̘Á_vÙe3׬Y³:�J?ùÉOžÈ;1!ü³fÍW¬XZºtéÜ¥K—Ξ6mÚìiÓ¦-‡Ã‘`0(ƒAIÎòxŸãïÔÌH[û'Tˆˆãwž½¤÷ÅüM2Ý|¦›Œ¡MJ®p.>‰øýë_Ï�={67wî\$‰"få°ÅîxÎpQ áóù`F¡»Ÿ­íg™�gžyO?ý4æÍ›‡3Î8ÐÙÙ‰¾¾¾Ü[o½Õ÷Á躮ç0´œï# MìSa_Ëö’òw‹ú�µk׆>ûÙÏ®\±bŹ3fÌX¨(J¨­­-÷æ›o>úÓŸþôåžž»Q†&hÞtÓMs/¾øâÕK–,9wÊ”)S}>ŸÄ¦ZgG‚P0t¬)Ò!3àã]f­Ívæ×Çq]UÕ˜ªª­†a|ÐÔÔ´eçÎ�û¾ûÝïv>|X�{iÀœ!ÑàqP~I'‚2“À›0ƒ}ÏÊ•+e¿ßσAèº~„«\3ãe²ŸYü �NÖø'“IH’]×ñ«_ý þóŸqê©§bþüùˆÅbèïïG{{{ü�wÞ‰ïß¿_ÇÇ ~íÚ¤G…ønQ¿$I¸øâ‹§mذáü%K–œ^SS3×ÜÜŒ?ü0ñá‡>úÿñ¯Ã_8ÃÖ½ß~ûí ×\sÍU³gÏ>½²²²‚‰6{~A€Ïç+ô@˜•®ë®{a˜�‚$Ià ƒS Œçy.oÔkò·Skkk?wúé§÷^wÝu;c±Ø–ÆÆÆWÿáþáÐÎ�;�Þï†Mƹet]Ïó\0„iü2A�ÏXæÿÛ =à}0oºøLeß¿jÕª  ¨¬¬ø š››±jÕ*ÔÕÕ¡³³‰DBß·o_ô…^H뺞ÁPº?>žÜç”ò/¥»X$ûÝï~wùÙgŸ}~CCÃéUUU2ôööâƒ>@cccöå—_~ÇŽ{ì—çyî _øÂìÏ~ö³WœtÒIç‡B!Ÿù\H’žçÁq\aÊ¡¹ÇÆ«aSUµpŸõÍ0C`6æ×3Ç!°ÿÃ'IÒ I’fTTT\;÷<ÏCEÛóom·×ÛñQ×õBY%™L"‹!�b``H¥RÐ4­°º" ¡¾¾Ó§OǼyó …@”eùQž|òÉë{ì±·ž|òÉÿ¼ï¾ûúMÇÊçÏgºÏ·öa�å Çq|>�&ÈŒG,¹5â·3ÅesÙã’$ñÕÕÕ"‹VJ]þG†`üfìjþ©Tª ü¹\S¦LÁæÍ›ñóŸÿ�@‹/ô÷÷£§§'¹eË–�¦¦¦,†Òý{1Ôé?ZáwîÇ?þñyçœsÎ…³fÍZèóùxöÿ§R)466âµ×^ÃÖ­[3;wîÜ�F_Ј¡žƒÂ úÊW¾ÒpóÍ7ÿŸyóæ�’OµCEˆ¢8,Òçy‚ @ˆ¢žç c�E)ˆ¹õf÷|™?�¢³³­­­hnnFkk+º»»‹Å�N§‘Íf¡ªjáçeYF]]æÎ�›�>}z˪U«ö¯Zµj&“iÝ»wïÁæææ®­[·öíß¿?sèС¬IÜíÄßë Ű¾öò›q’$!?Ã� ÈŒL©IÎC Ø C›ÿLc¿oΜ9b0äC¡Ð¨Öÿ“!Ÿ;ñO&“…È_QLŸ>úÓŸðÈ#� ªª ³fÍ‚¢(H¥RFgggòÅ_Œ¥ÓéAÛ´áãÝêJÛ4ÿÂ… }·ÝvÛ’óÏ?ÿ²ùóç/�3g,Ã»ï¾‹ÆÆFÎï÷.Vì¢W.pÊ5Càt&A�Ç‘Éd0þ|ôööfÞxã�­ýýý¯äÿ`¨”…ºº:á{ßûÞúK/½ôs~¿_b"™L¦Ðè'Š"dY‘ê×4 ªªBQ”¢ÂÏÞš¦!›Í"‹¡³³MMMØ»w/öïß�ææf$“I;á74MËår¹x2™Œ¥Óé”®ë¹ÖÖÖjç¨ÅÐjŠ. 5UÂ|œ6ï};1×M&ÁiK`»fAÃ&è #@�g"fmì7rú\Èû•••¢ \8±þßi‚eƯ!`ê$þªª¢¶¶�=öžxâ Ô××cêÔ©H$H&“zSSStóæÍ†a° C³ûµ"»Î~&Nƺuë*n¿ýöKÎ:묋�€Ïú|°ÍˆªªªÙlVíµ×¶~øá‡Ï`hÛà‚(Ö×× ?ùÉO®=ï¼ó®”$‰cŸJ¥ ©~I’ Q¿ùü1Ñ×4m˜ð;eÀÌþ<Ï#�N£½½›7oÆöíÛÑÔÔ„ÁÁÁ?o†žËå‰D"šL&†a˜Í�”7ãSœ‚¡]Ø à]1ÓûW³ö5ÝrߺQgyŒ+ÅäKƒd2ã0`½ 8 bË�¦›ž7.‰ˆL0’ɤëºgë’2ãï8ÜÄ_×uƒA<öØcxúé§1cÆ D"ÄãqÄãquÿþýýÛ¶mc�~Gðñ4?·5éžFÖ.^¼Xºçž{N?÷Üs¯�:uj�ùµÃ¢v¿ßUUÑÒÒ‚ææfär9½««kë<ðÛ|dÌ^œÜòåË÷ßÿ§W¯^ýI–Ábã‹Y„Í4`¥]סª*TU-|nmð³¾ØÖØ>ŸoXÉ »»o½õ6mÚ„¶¶6¨ª 6HK’$$“Él,K DsCw†CôÎÌU*ùOpNþü³~ ÎFìÍ«,8a×1|e€SFÀö%eóúâDQ„ªªd2'Hðá’(ÖÈæÿO1ÿ¾ºº:‘­gÖ4ÍÕ”‰’!8þ‚¿ß_H�³ýXÍ¿ªªª0ÓêÔ©¨¬¬D<G2™Ô¶oßÞÓÔÔÔà Íò?š-j‡EýçŸþ”ï|ç;ÿgÑ¢E+EQ,¼ÀÌ{ð<�ÇãøÞxã $“I¨ªzàÕW_}J×õ^³ø¾ùÍo^û‰O|b}(âA@2™,̰°6öe2™Bó�—hÿÿgïÍë¬ÏôñûóngßÏÉa•€(‹âFµZQ±.ulÕqtÚËv¦ËÔNçg[ë8c§«¯™oÕÑj§jkÕZ´dZm¡.‚ (KBBö䜜}{×ßçý¼¼y9' ˆVèù\W®„p’œwû<÷s?÷s?V­ÕPP166†Õ«WcݺuH$`¡PÁ`ÇÉc‡N‹E¥BЗPj¡p¥˰žñõsŸÑk†¯˜¾§XÀ±€�‰ ‚¦ÈǽFo{$v»…B¡ ª« > ÀDßÊ8Pª5R±ñz½ ¥J%IG•o­‚¿Lð§Á€1·P(@QÔ××ã‘GÁš5k …àñx�H$�ÉdäöööуîE‰òO£òœúÉ„~ã>†Á÷¿ÿý¥×^{íç‚Á «RàÏd2xùå—ñÔSOaçÎ�´U/�F­ª*Íü‰~œö»ï¾ûcW^yå%n·›È²ŒT*eü^ f�#õzkà¯ø@é¿ËåÃ0Ð4 ét™LÆMÆb1üÇüþøÇ?BE¸\.L›6 �@@{íµ×âù|ÞüŒR@”Ðk úQý{†°’çyÕn·«Ç©8EQˆ$I¬¦iŠ,˲¢(Œ¦iŒé”cÌ€Á‰™%0îÿ …�ORUP]ØÉå8b6ÁÄ€r c6=«0Ïó„Î §Ú‰ '£gþÉh@u¹\Æ`sð�D"X³f Ö¬Ycôž' d³Y¥££c¸§§§À{(QÐò13Ýl“ÆÆFþ‘G¹áŒ3ÎX!OÏ—ÍfƒÓé4ÚÏÆÆÆ°aì^½ííí´î¬æóù§s¹\¿¾ÇÐíú¾pÞ—¿üåË}>Éf³ ÁÖ|_Q&ÀÜ›?Y ›aØív@ɲŒL&ƒ\.Y–ÑÔÔ„ŽŽ|ÿûßÇ–-[ i"‘šššÀ0Lvûöí£ûöí“õMÇ!Ӡߥgùi˜üxž®¸âŠ–óÏ?úܹs›Ünw�Çãñû|>»Íf#„MÓ45ŸÏK©T*)ŠbŸ,ËÝ[·n=ðÆoìÛ¼yóP,Ë€•Ë(&cŽÒ P}@µu° ªëÃÉö'bP!ø[‚% ã{,Ë24Û™ˆ=‘A´ÊœØàÏó<œN§QÆ¡Þþ4øÿþ÷¿ÇO<·Û §Ó‰d2‰l6«ìÝ»··¯¯oJ³ü™ÿ”³~¸á†j¿öµ¯ýÃôéÓg0 Chfíp8 ª*²Ù,$IB&“Á–-[°aÃtuu™»O^‹F£{,ì•óòË/_qÇw¬‡ÃŽL&S¦mÔçÍ�,S1ð¡?ëp8`·Û�Ÿ¥ÁŸã8ÔÕÕaÓ¦M¸ï¾û°sçN0 ƒÚÚZÔÔÔ¨ñx|lÇŽéT*Ee¥úý!”l’Óô|rÇ^|ñÅžk®¹¦uÉ’%g{½ÞV·ÛíÓçT¼y\.Âá°q|§�vš|óÍ7‹™Lf(‹u lÙµk×ÖGy¤{xxXÔ…†f @™Æ&>TN,8$ „âr¹ªÃUP]˜Š pt+ WƆH Q¦š)}´ Žó†ÐëÝn·,Ë�«X,¢X,"ã•W^Á“O> Y–á÷û‘J¥�ÍfÕýû÷÷÷õõ½£q‚Ì*Á4–eq×]w�và 7ü}8®¥ÁÕår�Ÿ2Z’$aï޽ضmºººÌ½úÑh4ú²žIÓû×ÉóüY·ß~ûò––/Yl=ÏVƒž2Šü£˜(šùSÝ„Ù,ÉétÂçóáÍ7ßÄ¿ýÛ¿áСCFð÷ù|rww÷hGGGQþSD‰Úß‹’†¢¨Ÿ;&ð×_}ã�7ÞxîôéÓçû|¾˲ŒÙ*¸œ =³9°,˱,ËÙl¶ÖP(Ô:sæÌË—,Y’ü›¿ù›]===ž}öÙu/¾øb4‘H(S× h¨Üvh¼ÏL&CmË«   ªëC•&š?ÓÿÊ=Ì�Œzé_:€VÁÔ˲p8à¸ÒcHÝæ …B¡Þyçüüç?G*•B(22ÿÞÞÞžÞÞÞ­zÀ¢5èJ¢¿J”?Ì€eY<ú裗\tÑE×¹ÝnC�OíoéRUýýýؽ{7ººº�FéùQ%IZ›N§óúÞ T²:ûßøÆÒ /¼0$Ë2ÒétÅà>Q¿õõ@Ùl6ãÚPí„Ëå‚ÇãÁo¼�;ï¼}}}`Y‘H‚ vïÞ=Ö××'¢$Ö@i2Oj8·ÛÍÝu×]M+W®<·¹¹¹Íår THHŸ7³8ÑìH Çqư"óûVÅ,Ë2�'àr¹V„Ãá³gÏþú¿øÅ—÷îÝûÇŸÿüçolÞ¼9cbÌŒ€V� PM{ÆDe‚ª6  ªë#È€ge !p¹\Ð4 Š¢5Êô£@OU@ð~Ž…J[çr9ƒú8pàž|òID£QÚê§|øù_|ñ·�?þxÌÌåÕ BàŸ”  Ú‡Ã�|>_UP]Ç»*lå‚=&úf&€³ü !„h4MuSª‚Lõ8†� Fð—$ …B¢(Âáp`ll ?ü0:;;á÷û‘Ëå�Éd044Ô×ÓÓ³%AšÕÖW>†ào¬`0(üà?ø›eË–]Ìê©­Ãá€(Š´><î½K’„X,†þþ~ "‘HÙ¿(Н)ŠBp¤ý­Àâ¯~õ«�éÓ§Û¨‘ÑT€ÕT”¹·?—ËÁétÂétbãÆ�øÁ~€ÞÞ^€Ûí†,ËùÎÎÎX¡PÔ3~: :X!K–,±ÿð‡?<ëŒ3Î8Ëëõ:è&:yÑú|™§–»ÌÔ?ýLA:=fÃ#†aŒsÏ0ŒÀóü¯×ÛÖÔÔô™U«Výú¡‡Z½aÆ$Æ· N¦Ú>8îûù|‚ �êÄÁ*¨®&ÒLåû¬usÉd2ÆŽJ)É“-xþ5• ¬™«¹îOmnŸyæìÞ½n·ù|étZK$ÑžžžW5MëÃÊ_žbðÆÓþ4ówýèG?ºá¼óλ€eYB}¨ŸY‰O¿ÎårÅÀÀ¢Ñ¨1F—çù�ƒ2/€¥³fÍò_~ùå>UUɉšUA»&ÌS/©IÏóx÷Ýwqï½÷¢«« `·Û¡(JáÀ�#…BaJã� ú¹`0>ŸßúÖ·®¿þú‹ëëëk(BË2VjŸfñÔ¯€žó3o½¿Ë '¢?C5´ÓBȲŒb±–e Ã0ó<Ï¿ßsÏ=·|îsŸ{øw¿ûÝK«W¯Žãh�J @�€ (Û) Š"h+Cu7¯€êú`W%fÀü5kþ·¦iH&“}>Íö¨tS:è© hæJëȹ\θf>ŸO=õ6lØA IR©Òét¢Bð/&¥ü ¦¦ÆqÏ=÷|úœsÎüóù¼á¿OkÕôXhkÝÈÈFFF�J¥(PÐ$IÚ$Ë2ÍF9§¨¿ýöÛ�¡PˆÏd2'„�¢Ên·�»/h ŽF£xì±ÇÐÑÑa>©»»»¯P(ìEi(’lz–´¹sç2?üá^pÁË}>Ÿ�ã8£Ó|/Z§RÀFƒ¿(Š“vâ” ZK,T Éó<<�Êr¹©©©iõù|÷666~zÉ’%ßöÙgwîØ±£X†5´¶28ÚZØj>t ƒ¿*¨€êú�€Ð�0Ž´@YÀšeœ¬�ôTf¯|†àOED"¼òÊ+X»v-²Ù,A ¢¿\ÿ«’$íÇxÁŸ5ë—1Ê_–öï}ï{7_tÑEçR d€½Î0ÌQ¢RjÚ3::ŠX,f¼ža˜tÿ~©ýטWWWÇ]tÑEnI’ˆ´4ÕL IDATe,öûÊþ­Ô?]¹\�=öþô§?AQ´•Ç( ;QrêÓLÁ�\pÁü�~ô£ó-Z4ßápæAzö;.𗳦SÍÏ]¹{w¢¯+�ñ–$Ép0ôxxX-!,«Ã uÆ€9È›UÔP+aLÍ}°ºª º& êå‚{¹ÿ³ÖúÿÐMIEƒ8Õi¥ã8Ž…A £EQ êßï÷c×®]xüñÇ1<< A�H$�Ë励Xì•\.·GZý*e’àOôûÄûßÿýߟYµjÕy,˪R§ÁœfµåèlQ‘H$‹Å�N§i¹I#„ì-‹š¾ŸØ,`»ñÆ…yóæ9âñ¸1ÜçýžCêío]Š¢àø^x᳿€:::z0—ËíD©ŸŸ12ísŸûœëë_ÿúù³gÏžÎó¼1‹€·9ðÛl6£US–el›ÛËyqL%qžì5tþÇqp¹\H¥R`†ommýL$ùÄ9çœsÿÚµkûÌ3ÏŒa¼Õ°åË“ Q�'PÕ5µåv»I&“9�P.ðåÍ„‹ÅTBˆêt:›ÍfÐÉå6ÉS˜¨Ê�,  C~¨g¥þ�N'òù<ž|òI8pÇÑ,OK§ÓïÄãñ�¦à/™²}ùXƒ?×—¿üå˯ºêªsõº2l6Û¸ÌßìÆg LŠ¢ •J!‘H¥†aäb±¸GªÓ4 ŸúÔ§\²,]PvÔ5:žsh¥þéÚ»w/žxâ ›�¾d2¹ ¥A=fª[»úê«ßùÎw.ihh¨eÆè ï‘RýT°IõTh[®–ÿA³ä´ÃóÞÔÔ¡m�fFD™ v&Fôa>3´4àp8àv»‘H$066ư,{öUW]õB[[Ûÿ{øá‡Ÿxûí· 8RPʰ°° ¦Ð% ßÕ’À)°˜ê)8ñ‹çy2Ål€L ÐELÆêëëƒá‹ECŒô~©y³û°O4(°LJy,4 8�N#¸f³Y£îÿúë¯cÆ H&“­(Jlttôªªæp¤î?QýßZû·.‡ ÿ×ý× kjjl„8�NCíoŒZƒ?p¤,P(�J¥ŒúÕ½ä9�‚È�7ÞÈ{½^Žú™ì›ìºP¶¢Üz饗°iÓ&³» œJ¥¶)ŠR€¥�V„àO~ò“‹š››#´Þor14‚¿ù}Rºß<Џœ‘ѱωX…B¹\>Ÿ---ðz½®yóæ}ë®»îzâÓŸþt£~]Ø2L™rŒ{©îöUP]–€^Fð4ÑðŸJ¯-÷š£\~R©I$x½^ÃFöDû|Ø›Û ÌV³ôqPêŸJýûý~ôõõáùçŸÇáÇ ;VMÓò¹\î’$eptÍ_žhe@€ÀŠ»ï¾{ÅâÅ‹=Ôä‡:Ñ™’r¼4(šÙ Q õ¿¢(tÚ‡ýÏÀòåËm’$1ÅbqJµÿ‰(­ýÓ÷a^]]]X·nFFFèk5I’v§R©1kð÷ù|�µkמ;gΜ€qÁßÜÚGÿ¶9ð«ÇƇh9IQ477£¹¹~¿Ÿmhh8ï _øÂÿÝÿý×¶¶¶ÚÊ�rÁßúïIA9™M<ª« NIJÙld hx¢á?S) ¥äãʲ,“¾¾> œN§A/�~•‚“ |ÐÇAÍ\©áõ�þùçÑÑÑI’h6®‰¢¸9�vO!è[§ûY-~�ROþÂóÏ?ɵ×^1g¸4[¶k�£ì­“Ó:¸Nÿ+Åb1¦½ŸçÍ›'èlÆû¾6ô – öæN ÊDH’T±$GM¥A@$�ßïÇèè¨Íívþ®»î:û¬³Îúò½÷ÞÛcbË]3�§�(ó:ó³RÕTÀ_ߢ™Ç±ìi¨ìþ7Ñ×Ѓ@Þú ¾úê«r¡PÐ"‘¡�¦P(SæNö@z2Ú¯nö�En·½½½xá…Ð××g6nÊ���ýQ–å"޶ø5 ÿ*‰þ¬YZÀÙW]uUhñâÅ.JýSúÞ’Á• (Txñ, ½Nëç‹Å¢ªï#µ:@CCxžçòù|YÚþxXëÊårØ´iúûû ¶KUÕ�ÑÑÑËK] Ã̽ûî»kêêê8Y– QŸYƒî‰Z4ÀÓF:ÈÌ8”3¢?GÙl6hšI’P, 0VnO’ev» ˆD"H$§×ÕÕýjùòå÷Üyç�¯ìÝ»·Òž¤–�2{[TÀ_ÇÒÛa¦è'¢úÉ$_�{¶QšXÖjþæ›o¾©Äb19‰ð<Ï#ŸÏ#—ËA–å�Œ# yƒ=™ú÷�ç8Ìnu43ËårF0]»v-:;;‘Íf�Zº(Š/%“ɸ%ØO6ড়⟠DÇŸÅq\äŸøD@Ãì‡z÷—7Öã Ù*fq©þý\±XTØ„è¯X¸p!I¥RDÅ÷ *eÿ]]]ؾ};L"C-ŸÏwɲ¬˜‚`æ­·ÞZsÖYgÙ�RÝßà?¨V>ÚNH»ÌãƒÍ¢BóA+Ø43 ”ÑÇ!™L€ÌÚíBï9:¹®®555-3fÌø¯%K–ü¿•+Wþ¢££c¢·o8d ú¤¨ºVÀ_Íš$øOöSÍúÍßS$M§±™twwëëëùºº:tuu�ó—ÿK±“Ñr›Ýɬ€€eY¸Ýn#xÒÌ™Ž§Ý´i�@DéÜ…©Õý+Qÿ.EɆ·íæ›ov·µµ9†1\ä&Û›­™1Ã0FÖi^£›¨ƒGÚÚÚØd2IDQ4@ÐñÐr÷¯$Iذaz{{ ŽeÙÑÑÑÑ!Ëyh¬««‹ÜqÇAH6›=Js¬S§ ZhжÛíÆ} ªª¡±v×Xµ(ªª%A ð˜Íf‘Éd088ˆÑÑQˆ¢–ea³ÙŒ¶@—Ëe´�êváH¥RðxvåÊ•n§ÓÉP6¬z?–E]ç(»až„§ÎF‰~�H>Ÿ7¦ o+`9`<7²ê·!Ër_6›-šTÏ%—\Â-\¸P Þ Çs�MEìIõT« išáÇA�Ÿ}êÒé÷û¡( ðÖ[oaë֭ؽ{7‰„‘\˜»ÌÂA³xÐÜ^HÿF*•ÂÐкºº`·Û‰DÐÒÒ‚ `Ö¬Y…B „ •J�²dÚ´i?ðÀÿßW¿úÕí¦ó`ÜV @Ê0PGú“i4yT× a'ú“"ˆÍfcyžŸUWWY¶lÙëo¿ýö¸ç À €Ö?þÜsÏe¿þõ¯»A ÉdÉd™L.—kÜ�—SA¡ÿQ;«ãŸ¢(Èçóàyš¦áÅ_ÄÁƒ‘N§éë5I’Öçr¹l… oü Ê›ü˜ïÀé\Ç1‹-rÑ–Ãã�ÄGÕé”ú7½6Ï $´³[Ø1B��šèÏù´²V𦡧§ƒƒƒ�OA.—ë7ÑÍ.5„rÍ5רX–%T(x¬÷Æde)z>\.—AÙÓ6\sÛ-‡¸\.D" áÅ_ÄÚµk±oß>£-ÓápP7?¸Ýn8�N£”`õk ÀÂÌ,˜K ’$!ŸÏ#�N£§§‡ÂÎ�;1sæL´µµaÞ¼yðz½ô÷Ímjjúß;ï¼ó¶{ï½w»~½¬e¦r‰Ë¤]6›�胢ª« NéÀ?Y}Sáyž‘e™w¹\³¿ò•¯œ~ë­·î´ÐrC(9Íoâ‰'ž�Î;ï¼<ÇqNI’�H$�Çáõzlj‘ÊÙ˜kæs2‚ó¬Â?Z£õz½Ø¶m›A[›TôÝýýý{1¹Ã_Åàït:Q‰,Ë¥6¼éÈüùóù¦¦&;u!4Í¥8®H)r*H£¬‚8|';“ÉÞ4ë¥ÁúX®‰Õ–W–e#û§ :ýŸ4ªzö9sæ�åË—Ûòù<ŠÅâû#–c hÖOÍúi°Eù|²,Ãçó!`×®]øþ÷¿�M›6!•JÓýf̘�úúz£fàp8 Š¢Z(Ô‘‘qllLI&“r:�–2™Œ$˲FMx8Žc9ŽãA`m6ϲ¬€Q…+ H&“A,ÃÈÈvíÚ…Ù³gcÑ¢Ehmm¥ÇP{Úi§=}ÇwüÃO~ò“Wóù¼fbT¬L€5àWd&ðH©®*89×1§’ý[�·ˆÍfcEá!œ9s–{<žÝ4sÔW@\Æ866†×_=×ÖÖæ€d2‰±±1ƒA¸Ýn#“˜L˜uªò>¬c0·i%Õ±X„Ãá@<ÇK/½„Çux†aòù|~½¦iÑþåì}µ#‡CÈ7¿ùÍ�ÿâ¿x³»»[AIùï€ùóç n·›õx<†Šÿý phð§Ÿ9޳qÇëÄ8Õ™L†äóy0 3®„PÎo Òõ(R©†‡‡�Àª¿¿¨(Š’~n<(‰ ±jÕ*¶¦¦†£&A'’éáy.—ËPæÓ¬Ÿ‚�|>�|>�p8 ŸÏ‡·Þz Ï>û,^{í5d2x½^ÌŸ?3fÌÀœ9s°páB´´´€eYeppPÚ±cG±££Cܹs§tèÐ!uppPÕËÊOñÓPˬò<¯z½^âñx …8·Ûms¹\Þ@ àÒ4�C&“Á»ï¾‹ƒbÞ¼yhkkC]]ìv»gÖ¬Y�|ñ‹_¼í¿þë¿^¯ÀLFÿW;ªàÔ^àDÞ ˜2�Ÿp&€�x@7Ï󬪪¬¦iç]vÙeÏ­^½ÚœÆI(u4Zè8òôÓOç¿ñ�oH<Ïóñx±X �@>Ÿï(eòÉJ·”Bl6¼Þ’9£$IÈf³Æ¤¿?þñ�صkFFFÌï¡}hhè0&îùŸ¨ß7ÝtSݲeËÚ~üãoÔÿLý^"uuuv†aàóù`ŽÇ Ìf4&Àåp8létz܉ŒF£( à8ÎðÐÍŽ&̪­÷–õú !‹™g@’¤aMÓhfZGËgœq€¤R©’ýS Gƒ?Õ&(Š‚t:mdü¹\N§---Ø»w/î¹ç¼úê«(‹ˆD"8ýôÓ±`Áœyæ™hkkƒ$IòÎ�; ÷ßaݺur¿ª'åDž“]/FE�Fµh4ª�Þo ÷V0(E�F+NÑ›lÑÚ?L…n´/Ýn·ÛA8ʦoïÞ½ê%—\žç 1œ$Ieý&»· Ä+IˆÅbÆùÕµX,Æõ—8`ƶ¶¶rét’$�P.ø‹EÃu“ �H$ðÄOàW¿úFFF‡±dÉÌ›7K–,Á´iÓÔ¾¾¾âOùÉO.Û±cÇfÓÛÈè…¥8 uuuåùl6k˜‰x½^x<ÐÚ0ÇqýÄOd†}2Ϩt ,ËŽkš¦-ªªÂï÷cÆ رc†‡‡�r Çqcñx|K™ì*Ô¿À9mmm{V®\ùiäàÁƒc(é@éýIJ,ãóùØp8L' ¾¯kaÖØív8ƒ°Ùl¬Ïçóöõõ�ûQ•d2©º\.–ÖéûÝT])­z�B¡€L&c´–é¦;Å|>/¢TúÒ×F"8�Nvppð„ÊžÑàŸÍf�쿾¾¹\ßýîwñ»ßý…B­­­˜;w.fÍš§Ó)nÞ¼9¿aÃQüe ŒU@Iè+›î ºhçMxS131èçìÌL&ƒýû÷¯ãyþ?ëëëæt:—ö÷÷*•J�ÑÔÔTïóùXµjÕmÿ÷ÿ×eæ½lBà$ SuUÀ)E÷OFý[¹yÜ UUíÈår„R°v»��6mÚe^¯÷íT*e¶>€Rß÷81 ¦iÚ¦M›r—]v™K–e6�cdd>Ÿ~¿ßØÄé&kõ"ÿ ³ë“]C@­Wé¤?óì—Ë…¾¾>¼ôÒKèéé1!D•$éõ±’*mª�_3eq§h¾ùæ›3��� dYÖ8�Ñ_�ÞW^¯—‰D"ŒÏçÞ={àr¹Þ×µ0¿ŽªÞéý£[Ýz`±’Õ4 ñx\ …B,=7”"Ÿª!•µD“ÍfQ(Æ�Ð%„ˆº÷¿ºV­ZÅd³Yc"æq?Ð:óa¦ý …²Ù¬1Ç¡¹¹íííøéOŠ 6Àn·cÁ‚˜1c‚Á ²oß¾ì+¯¼RÜ·oŸV&àdP2öÊàȸo Ž* BTBˆfÉðYMÓœš¦9P*Ñó!L(xX €•$iõáLJü_8~ Àâ���[DQ<Ççóý¨­­íïöìÙ“Eeq³VæoïÓáp½³ ºªà”SÉô™ ÁŸ®ÚB¡pZ&“a¨pÊf³!´ÞrË-ç?øàƒ›MÁa @7€6ëC�FÕÎÎÎlss³WEŒŒŒÀétÂãñÀív#  µ%ý°�úÉ hð÷x<´ÙlÖn¢(â™gžA{{»AÁë™d÷ÈÈÈTvøSP¹îp¦ÏçË-_¾üržç™x<® È( á¡Enâ÷û‡�`åp8Žrº›Êµ°fáTìèr¹Œ2€ ðûý”:RÆmþ‡yžç‘Éd�ÉdP(hûà1ß/´½Î˜EQ,êýÿ6=£PšE022B¨ñx(hú7Ün÷8[çL&ƒl6 †aP__�·ß~wÝuzzz …0wî\ÔÖÖj¹\.¿~ýúì®]»Ì�Pу|¥ÑÞIS–¯š€�Æ0ŒÖÜÜlkmmuœ}öÙžéÓ§;ív»Ýëõz�€Ãf³±úûÔE‘s¹\.“É$r¹\rtttð�7ÞȾûî»Â�¼¦{„+“°°(ùGØüÀX4•¢Ñè&¯�{AøÌ²eËþÍf³}gûöíÙ X€ŠHUP ™?ÊPÿåêÿå˜ú3B2™\�Ïç‰,ËàyžR®dÚ´i_°`Á{»wïMÊ~”àN ‡={öä�N§Ãétòñxv»Ý(¸\.ÔÖÖŽ{0?Lp2ü½^/X–…(ŠFð—$ 555X»v-¶oßn|_gqòù|þå\.—¯�ùW²ùÕôg´ @í­·Þšlnnž cccZ&“ÑPR¾Sú^¯W‹D"F[Ú±šð”³È¥ßaÐYÁår©V¯�ÞÞ^iáÂ…Çq$“É �N#›Í:€rGqâ&Ï|ÊRQ¿}DH¦òˆÒé42™ÌQÞûÇrOÑ’‡YíŸJ¥�Ïç�¡;úÓŸð½ï}ÃÃÈD"˜3g¼^¯²wïÞôÆ�ÅL&CÇëŠ(µîFõà_´^o»ÝÎ,X°À¶téRïœ9sÂ3f̈444øÃá°Ãf³q6›�¡ì‰Y›b=}p“zýõ×S©Tª¯¯¯w÷îÝ[¶lI¿úê«î‘‘‘�Îp–rÀWxA�*fóæÍ;�Àö /¼p®Çãq¢Tz,W ÀD  ê X§r🊿?30®v—Íf›s¹¡› ÍD<ÏŒK/½ôã»wï~É ¢( O³<€$—Ë)]]]™™3gú !Ä\Çõx<ðz½ðûý`YÙlÖØ0ÿÒ5»�" `YÖ8o,Ë¢X,í_Š¢ ‰`ýúõX»v-b±TU…ÞÎ¥¨ªúçÁÁÁ^LÜî§•%‘çbB·bÅŠ¹‡ƒ×4 £££š$I%݈q¹\.­®®N;pà€!˜›ˆ8–kA§ º\.£ àr¹øP(d·€Ã‡K‰DB�K¥Rp¹\H&“ðx<à8nÒ÷TnX£‹E÷Ó÷²N IDAT´ èfœQ¡P0Ø«ñT|¨ç�Ùä'›Í"ŸÏÃëõB<ûì³xðÁ‹ÅPWW‡éÓ§@ñ•W^IïÝ»—^¿€�©£Ž�ãÞôéÓíû·ÛpÎ9ç4455ÕÕÔÔØyž't¶ÕêPàc�`e,!�e™Ñ4Í …Ó¦M«]¶l®½öÚüðððÁ½{÷v?ú裻7oÞBI;â6•ÎÓÝs:`Ñhñx\~á…öè÷. þVPI´X¥ý«àÔYz-ëXÁDô¿• ªªò¢(’l6‹@ †a¨Úœ466~ìcûØÛ¯½öZZ¸d{Qr�sY<288Xt¹\yBˆ“ösÓÍ�–(È k´&àd´L‡üäóy#ÃE>Ÿ���øío‹ááa°,kÔþ†ÙÑÛÛ»•ëþ娳êÿtÁÓO?�[¸pa„f£‰Dš¦qú57î»––I&“3Q©ÿx(qšý:Ê�ææfçáÃ‡Ç PE”¼^/—Éd�H$ŒÙTD8UêŸ<šùë&D`†>S‚5Û¤%ƒÉfXïsjylÖNÐv?·Û ›Í†çŸ÷ß?âñ8B¡^}õÕT*•RQªé£äÕQ°^×@ À|ò“Ÿ ^|ñÅÓ-ZÔRWWggY–P‡Ežç Ã.z,T¬KÏE¥Vó4J dôkåðûýó[ZZN[ºti²³³sóš5k6?õÔSEQ¦£d $è @ð”t Ö}Ê|,V0! PÕTÀ_CàX€,ŽÖEQ–QêUŸùX±bÅ›6mú�‰V‹£¤˜o½¦š¦iLû|>»¦i Í(hKW0D]]xž‡ÏçC2™46Ñ�ªz÷Ãf©J`tðŠËåB?{ì1ô÷÷Ãf³!™LB–ep×?<<¼^’$G·ûUšðgS…uf‡¹îºë|n·›¡n±XÔX–µáÈ$>¢+.—ËaddÄpâ;QmXTèv» �Ëå‰Dì Ã䬧«««ØÔÔä „@Äb1øý~CTGý(*Ýgfm ½4øëAŽÓŸ�qJ?QI±XÇ"L•aÆ¡MßC&“1ÀòË/¿Œ‡zcccðx<ˆD"H&“¹­[·fõ�D}8bÕ=NÏ!V®\éûüç?ú‚ =G5>‰¢ˆL&sLÝ9æç�‚:Œ‰‚»ÝŸÏ»ÝN8Žó»Ýî+f̘qÞ…^ø§gžyæëׯ÷jš¶¥AJç¢$0ÞDK¦ó` ‰´G� T«« Nú ?Yð/§(WÂ0 ¡ƒXDQ4ç�ù|ž444,¿âŠ+Þ\»ví ‰:Þ§SzAëÃ'˲ÚÛÛ›jnnöišFY‚Óé46têMNk�eðA´¼^/l6›Ag³YȲŒb±·Û�ááaüìg?þ}ûàñx�J¥¨Z=�F“L&(o÷;™á‹’ÏC°¥¥…[±b…Ÿ¾¯\.–eáõz9+{tøðau``@Íf³ŒÍf3X€÷£†·žZ>¢sü~? ™h4:îféëë“ņ†�eYD£Q£Õétt~9ZÛ:íÎlEL?l¥ƒbaªÿ¥Yù|,ËB’¤qú�É‚¿ÞÞh|O’$Ã?ã­·ÞÂ}÷Ýg½`0ˆt:]غukR–åQ=:Õo½žÚÅ_ìþû¿ÿûçŸþL·ÛÍPgEAP(�J¥Žª“›ëý•<)¬çÉú<СDt8“ËåB  Þ¾sÎ9çoæÌ™óñ•+W>qß}÷=544Ô`9Jz€^M{Œ•˜Èîü¨öÀã� Y]Üb«§àØÏóDP'ÊðI™ ßüoó‡ÀR”Ä\�»ì²ËÂ.—‹PÕ>Çq†Ç¼ªªL8ìÞ½{§.4bô á4æ(Ëá\.§pÇð(Š"nß¾}T’¤zð·Òýš ¸çž{fþË¿ü˧Ÿ~z­Ãá ôzP‰þL»™é0M^Ã0ã>èù)÷½rsE1\].\.}¾ g/_¾|N¡Pøó¾}û¶è�Dg2Ê1TÀx±êDß·V��ªàTÕøÍßúo€%æÀ-{ùå—‡Ýn7ñz½ƒ†êšÖtyžÕÕÕåß|óÍÃúï!zöáGI}T´K§Ó’Ãá!¬¹>L» "‘ˆ±‰PÇ@š=™Ú“ÍÐÇ Êµr.UúS‡?:ÚÕívctt�>ú(öíÛ‡p8 Y–‘J¥�Ë夑‘‘—ÞÃÑ^ÿå\ÿÊ9Â1(YCŸ€½å–[Âmmmš-�ŒŒ`Á‚dppp÷† ô{ˆ@ŠÅ"9í´Ó8Aìf¿êYp¢–(ŠÈårÆy�kooÏ[Ïo<Wëêê–eútl2wKƒW¥ì—²añxt˜�´h4Ú+IR� �P(ÄΛ7ï(@Û^'¢þËÙ' <øàƒX¿~½a-L;;;{ …Â^”„¸Š5P.]ºÔñÈ#�œwÅW´y½^ž3Š´‡êt_£ËÂì·0•vFëõ­t½©@•bˆ€%I"N§³aÑ¢EŸ˜5kÖЦM›ÞVUµˆòˆ0Áç W5øWÀ©˜)PûÌ€Å: ˆÝnç.¿üò°×ë%Á`ÍÍÍFFZ__O�çˆÏçkÉf³ÝÝÝ´5GÕA@3Æ;ƒDÓ4-�N‹‡Ã¦ª*CÇ–RŠÐáp À¼QS&`¢rÀÉ è±Úívƒ6·“Ñ�ššÀ …„Ûn»­¦¦¦†¥ M"‘@[[éîî>´fÍ¿Î÷_KK  ”f¦Êýcí¿ŸèZ«ªjXüŠ¢–e™T*%�ŽŽ*e6}Íï÷ÛÌ‚<èèT½rïÍL{K’„t:�x<ŽL&ƒ|>EQ˜±±±¾l66íe$ŸÏcÉ’%ŽãÏóã0‘%2µúµUUñÜsÏáW¿úÒé4ÍÒÕÞÞÞžl6Û�’ÒßÌàh´ë¯¿Þÿãÿø’yóæÕØl6âõz �(I’Á8P‘ ú<Ï \UU‹Åq.“Äš¿®T˜lQ6ËëõÂívÓ˶††† /^îîî~'‹Ieý±°Gih‰³ºªàTfÈ$�ßZˆÐŸ³ÙlìªU«Â>Ÿ�Ìš5Ë Ñ@U[[ A�N§ùÆÆÆ†Ý»wïL&“T•+é!„ñ³¼�R‡²Ù¬èp8슢ʘ³ÛH$2®Žîp8ŒZíD¢­“ ÐìËçóÉÅbѨåK’d¹ššlÙ²�<ò¢Ñ(¦M›fˆÄ²Ù¬ràÀ�ýýý¯éT°9ð+ǘýÏÑï öºë®ó\pÁ>�ÇChȲ,jkk100ÐÿôÓO+8"dPÄ5559Í €yfÁû þæ \(ŒVH–eIGG‡uŸ‡$I$‹ '“I�™ÈçóÚ²eËœv»}Ð3÷ŠÙ9�Ä®]»ðàƒ¢§§Çx_étúP"‘x¥žxsðWh_þò—ë¾ýío_TSSã¦Á=™Lã é±SF€¶û™ƒ2-÷ÑHz^¬_O&{V5MC±XÇq¨©©¡#�‰×ë�·pṪª¾³o߾ܲëÒ&ú›‡ƒT½ªàTd‚Ìß 8K bbØ+¯¼2 1sæLB�L&‘J¥�ÍfAAMM Ün7²Ù¬¯¡¡�lܸñ .ð#(µïq¤ElÜ®§(Š&Š¢,‚MQbÎp3™ <‚Áà¸lˆR”43™ ø(ƒ*øòz½Fo·ªª†k=ÔM. á7¿ù ~ýë_C–e̘1�Éd�J¥Ä®®®öÞÞÞ?ëa¥À_Nùo]6”Z±!ÌÍ7ßlmmuP!Ä€Éd2ùóŸÿ<£iZÈÌØív¶¥¥Å)áyv»Ýè"9‘c�E1’N�³===b&“QË€9 ÚE!´¬D¯�Ûí†×ë5jßåÄbŠ¢ P( …Bnhhˆ7˜7ožÝëõ2fÄét–eX–-›ýg2<øàƒØºu«¡`We$�nSU5oaoTÚW¾ò•ú¯}ík ê™L&�¡Dæ6\ 8hmž2*´}QUUã³ù£\Ð/Žeɲ I’ ‡Ð\.›ÍÖŸï½wß}7^Žé¨ ¬@à( ü«àTÇüÍ à( óÉO~2‰D0}útƒö¤™:5𩝝‡Ýn'Š¢4ñ<ß³sçΤ‰H¡d"c7mŒ�$IQEáyÞ&Ë2EÑÝšL&a³ÙPSS3nSÔç¸ãÝlþ’`À<ÙMo‹Ã0ÈårTÀg´ø‹Eøý~ˆ¢ˆÇ{ ¿ÿýï ÑÚÚ ÈårˆÇã…öööΞžž�(Õ‚ËþrÔ¿V†*¥3íÏ଩©a¯»îºšp8ÌR@KAÐÙÙYX·n]<—Ë…Ì÷`6›%óæÍs8†þ mÛ£ã}ËeÙÇÊBŒs¥ÓÇÄãñ�ööv+ Q5†a4»Ý.˜Õ›ÐÒ ½>”~7Sñ²,#�NÓr DQD>Ÿ—ûúú$MÓx3ÐmmmåÂá0OY*z³Ž$¦:júc^úÓŸ°zõjŒŽŽÒ×Êétzk.—K– þ×_}Í·¾õ­�…B!eíR©”vÌ-ŒÔ6ÚlZdö-°ûc©ª I’àñx ²Ù,X–�ÔÖÖ.¶ÛíïìÞ½;Q3  ŸOR�(Up*€J.ì$Ù?g¢¤ú&z €¹êª«ÂsæÌ�Ïç�¶f~^蔹iÓ¦AUUÆápL/‹öïߟ×OA:aè£bÍÏ"Š¢¬išÊó¼ gS ÓÛâñ84MCccãQYÕèf,Ç\{ü°�¹šRÎTO[°ôŒÒüªª" bÏž=xà�°k×.,Z´óçÏPòÎnÙ²¥§¿¿ÿ-ý8ºæ_©õ¯\ð§Ïã"è½ÿgœq†såÊ•A—ËE(…O�eYÆÆ�퇆†B8"%Š¢ ®®Nƒœ9ãt»ÝF§‡•’=Öëa¶ó5kIÜn7;::*F£Ñ£Ô^©TJ¶Ûí,˲ýšå:ƒA㞢ŒŒhÒ2@:�6€ªª|oooF’¤q  1 6J·Ó2eAÌ€Ðét †††ððã½½ÝëišÖ5<<|ÀrýTäì³Ï®ÿÏÿüÏ �^¯ªª"‘HƒeÐ(˜·ýãí\9Q‹ .}>|>r¹Î‡ÃoíØ±c¬ 0YЯ8+ ÚP';˜LüW©öÏ™Àb3�\}õÕ‘ÖÖVB0222nã¢ne£££E³fÍ‚(Š¿ß_søðáýÃÃÔ_Kël@&¿xó>^,EQdžçY–™B¡`´xE£Qd2„Ãáq:sYÀn·'2S9ŸÙôÈçó=ý4ðÓ@B7b½þ �ÇEQðì³Ïâ©§ž˲X¹r%,X@'Ýiûöí‹¿ñÆ}###[ÆÑŸ‚ò5ÿ‰zÿ8\ˆ’~ƒ\uÕU¾E‹¹Ì3(péëëÃ{ï½Çö÷÷÷www{L×—@ÓÜÜl§™'UÂO¥ 0U†€Þ‡æ€€ÔÖÖ²Û·o/”ÛØ3™Œd³Ùx,[ôgyž7@½¿Ìf@ªªe*j]­i�F³Édrœ™Ïóhii±sG( BçP@K�a¹ÒÀºuëðÒK/¡4¼à8®�FßEQÂøš?Y°`AÓ�üã%óçÏ÷x½^CCb>G4øÓã0[ësóafQáp8‡‘Éd ªj  -v»ÝoïÚµ+Q�þ?¦ŽÊ:¸ÝnR5 ª€“½@¦Hû›ƒ¿™0D{‚ 0W_}u¸¥¥ à ‹TµqáôMeddÐÒÒ‚l6ëÎwÞyg±X¤bZ>”™; Ó³ª,˲ÍfTUeÌ#OÇÆÆ0<< ŸÏw”.À¼‰Òv%«�êD€‚cÙðè†K'öÑÁG´¶L3HšñÓÚ'�T°mÛ6üô§?ŶmÛpÆgà†nÀܹsQ,166&oÙ²%¶fÍšáL&³ ¥þï©fþ•TÿôÞiD©ýO@nºé¦`]]�ÍårÌ¥Ýß|óMŒŒŒ�x<žÜ³g�ªßGƽ˜Ífµ¹sç:Y–%”ýp»ÝF°;–sZ‰! ,€Y Ë2<Ëó¼´oß¾£ŠùŠ¢h¹\Nr:�vsé‰~ápØx�”*§�R–eär9£P’$äóy¥¿¿_1ßשTJ›5k–Íét2ô~ ,ýÝ´íÓÚ"�FñË_þFí_–åöh4:`¡¿ €úÿ÷Ÿ饗†½^/¡m£æÁEfŸüO¤)Î!Ð÷ÔÖÖ"�NCÓ´P8ž `SWWWÖ’áOÖ¨¡¼yZÕ!° Nž¥ª*ma)XÓgsð/Gÿ›}Y€k®¹&ÜÚÚŠb±ˆD"1Ξ”> Ô$dxxÁ`555DźH$"îܹs@°4”{ð8â+�$I-‹¢Ífã !l±X4qñx½½½†ÞÜ+mvX3«›©VÀœY�¨�Ê€(eLinê6GÛ¾DQ4¦ÑQ�xúQ,A�×ëÅØØþçþk×®…×ëÅm·Ý†o¼3fÌ@.—Cwwwá¹çž‹®Y³fPUÕ·Q²}•&þ*eöìÙl"‘�4MSËlŒfð¸¥Öétr×^{m0 q�555²,£££ÝÝÝH&“Èår\{{û˜,ËfÁ'EQkhh°»\.¶ ð~fX)jš±›ÏëŒ3øx<^ìïï? ʲ¬‰¢( ‚`“e™PíI>Ÿ§ugãú™ôÞ¤ªª2ÝÝÝUU‰ù=úý~¦¶¶V Ço·Û Á' ÎôûæŒôøÖ¯_�¡¡!êB˜O&“Û …BÑríj¯»îºywÜqGm(bEQD2™4Î GôýX'~�ü‰X Ã%Šúúzd2hhhhhÍd2¯õôô1¹AÐ”Þ Ë²ÕÖÀ*øè/BÈD ’p2`±)83Ç‘+¯¼28gÎB{ÑË9™B AÑÐÐàt: !¤Ùëõ¦¶mÛ6¬ÿN: Ä…’I�5û4²³|>_�ã8Ž“eÙltœëÀÀ £ªœ7ͽWs§mPT3@k¡æÍÑü¹Ò‡ù÷R!uTóûýFvkú4S4ÓüºÁ`ù|¿ýíoñøã�#™LâSŸú>ÿùÏcñâŰÛí�eYûóŸÿœùÎw¾“xóÍ7‡lCÉï}¢Ì_µÙlÊ<ÐøOÿôO+V¯^ÝQ(´ ²%ñ_imm.½ôÒ€ßïgÂá0B¡4MC,Ãþýû�F©™ �Fã±XÌ‹¥´ÇãaB¡��i*†£,Àûd-µP¡žªªà8Ž™6mÙ¶m›¨OE´f}ª$I² ‚$I�Ëå�ÍfQ,Ç ³•,ˆ€þ:fttTJ¥RŠå~ƬY³Øl6C Iï#óÈ_Äï~÷;tttЀEQö�ŒŒ¶:CCÜx 2gλ^ŒÌÁÿÃü  ó$†Amm-Õ54×××»ß~ûí7,÷t9p\,SuUÀɦZû·~„| %µ>�> `ÕªUþÓN;�¥Á·R ¥1UUÅÐÐfÍšY–Y·ÛÝÊqÜP{{{œ&^b(Õ™=8z€‘‘år¹"Ã0š ÒÔԻݎd2‰t:�¡¡!ŒŽŽ"�NC–e¶X,æ»»»�²£Îf³ZSS“�eYBÁ"=×VÞ÷½‘è“ú(M/Š"Âá0ߨØ(oݺU)·Á‹¢¨H’$ ‚`“$‰Pj6›5®!í0gÕºòù<�»@$IR{zzDŒ«­M›6Íæp8ÊÑnAŒ–< dYÆúõë±iÓ&ôõõQÃ-�No-ŒG1.m_ÿú׃7Ýt“ŸZE›[Û¬Áÿ#¶‡Óëi[ Ãá@mm-âñ8aY¶múôéÛ7oîÐJçX�e÷Öj„©€SLµ Ðà,™iÎBpÅWøæÏŸÏ™@%+S3Èd2‡Ã­~¿?ñÞ{ïÅô‡TFÉß[ƒ.4+ ŸÏK¢(Š‚ p ðÔ�=‘H �c``íííH$…B†²^Q£-ŒnÐt¤«9 ¢£‰Í4èÓš�™Y½\Ak¿† ,“É‚2Zc¥B+:�fÀÃÃÃxþùçñ³Ÿý ƒƒƒ¸ì²Ëð•¯|W\q‚Á �N«/¿üræöÛoO>ùä“Y”†-½‡R{å„&?—]v™ý¡‡ºòüóÏ¿�ã8G4íúÉO~²U–eµÌù¦÷È4èæ?ÈŠ+묳Âßýîw}Á`�Íf³˜`DøÉ°§M ÄãqØív444 ‘H0‡ã¬3fìxóÍ7&úÇ”Ú ‚@ªCƒ>¼U�øÁ gëd¬J%bAÅD§‰¢(š¹ýi²,‚a¸Ýnd2ô÷÷ãôÓO‡,ËN†a®( xúé§÷ê§`¯žÅ´`¼[à¸V�|>/‹Å„ßïwº\.'!„  bll CCCèîîÆæÍ›±téR,[¶ Ô¹Ð\o§AÛJ÷ÓÀ^é¼Z§šMd‚B_gvK£3|>dYÆ;# 6`×®]°Ûíøô§?��üãhll×Ò¶k×®â<�züñÇ%”†¡t耶Vªe>k´[n¹%ò¥/}éæÖÖÖùô}år¹¸(ŠÚ÷ ÐS§†×ëåY–…ßiƈaBˆÁ„$“I WKK ³ÿþ£þ@OOO¾¾¾Þ€Äãq¸\.øý~£#‚Ráæ±¹ïçÙp¹\…BPUñx’$‘«®ºÊŸÉdâO?ýtÙ›¸X,J###‰H$â ÄãqÜ% Œ��!�N£±±555†ÖÃçó!�#—Ë!³ ,°½ûî»y3˜íîî.Λ7ÏŲ,I§ÓH$H&“ ú‚d2‰îîn PÕ;½o{”#‰ú4Dnºé&[KK‹@»¦:nø£¸¦ÒJ¯íÈÈ1þ| ÷¼yóî¼è¢‹þþ•W^‰ëÏ‹ÊÃƒÔ Ù¿fb…ªA¦Ê|t—ÝnŸÈhª™¿U 8G4¹òÊ+½óçÏçiÖMiËÉ6`AŒ jÞ¼y(‹\}}ýžç£ííí1ýaWŒêŸîB7‡|>/êÚ–ÓiZ‡�ÅbÆþýû±cÇìܹ𦡮®Á`<Ï�s43iš�—û -yôër)V{TúŽãŒ2ÃÁƒñë_ÿ�>ú(6lØ€p8ŒÛn» _ýêW±|ùrCY/Ë2öïß/ÿð‡?LüÃ?üCfÛ¶m2€$€wPRúK¨l𣂠}ó›ß<ý‹_üâWjkkÍså:ôæÏ~ö³Î ÁŸÖÿ—Á4âꫯ466òÓ§O‡nßQÁówÊm¿?æ~—;ã‘,SØÕ=çÉãñøÎ-ßû¼Ïû¼ÏÐÑÑ�îînøý~2,GL$GÒétV Rv� Ãñ‹_8JJJ˜`0¨�…wk°ôN—¾Ì¦Ÿ"H~€§ï|x'ÆOäÚÒ4�`0ˆššÐ4�d2é­©©©8~üøëñx¼˜Èõ‚KÓ³¦€ÿõDBÁO±0#ŒÇãYI’,&“é‚Ú†H†Èó<†‡‡±páBȲÌ\}õÕWÙíöÝ<ðÀ!’x©™m@3G1€¼&‚8::µZ­F‡ÃaÕ�P(„h4Š¡¡!ôööâÈ‘#¨®®ÆÂ… ÑÒÒ‚Y³fÁëõVA+L%)¶胾,Ëš@Òf³addÝÝÝhkkÃáÇáóùàñxðÑ�~—]vêêêòZeYÆéÓ§Å'Ÿ|2ñÇ?þ1Ýß߯¨çf@¯ &êå—Èõõõ†ýèG›×¯_™Ñhdô‹¥,ËJ$‰O’ùSÈÙÿ–éD‹ÅÂ�u$Ñ2Lâœçp8àv»5 ¼¦¦ÆÖÜÜœ:qâ„\x®zzzx¯×kT…"£ŽI{¤ÅbÑtú‰wCÃÒ4 ‡Ã¡¯ê°È~ë[ßr{<žè=÷Ü#N‚Á`ÜétŠv»Ý€V;�Ç1::ŠÑÑQ444`Ö¬Y`±X�ÉdP^^ÎÍ›7ÏÐÞޞјãÇ�óeeeFžç�F1>>·Û­y[H’¤•¶HY†‰F£Q^Wª©`ºóÎ;¹9sæâñ¸fñ;sUÈz½Á^ï&Èq\^€žìÿЗàH©ŒÈÉDŠú×  zzz°páBd³YJ’¤-·Þzë¶ÿøÇ×eý4Š{P“¬3ÚqNoÓàÿBð×?$yOn,$I‚ÑhÌ£g§êÒFÆŽŽŒŒ`É’%`Æxå•W^VZZê¸ï¾ûÞˆF£² <úÕ 7@�ކ>ǽK|“æy>k³ÙŒ6›ÍB€é±O¥RƒèïïÇñãÇñòË/£¬¬ uuu˜?>f̘�úúzX,˜Ífía'õû‰Rò; ö<Ïk 'Nœ@oo/Nœ8�¾¾>¤R)ÔÔÔ`ýúõX½z5fΜyŽ×{:�ÆÉ“'…_|‘â‰'Ò===${WéþY]à?'øS¥Üzë­µ7ÝtÓu3gÎl "&½ó[:�ζµµ�MüiµcyûòQ˲4Ñ,�<¥:˲°Ûíp»ÝÚH^EQè––ëÉ“'ã… y"‘�úúúRõõõbKK œ¬V«f0d2™4%>éšx§™Ã0p8šTµMfï¼óNWIIIì{ßû^v"p‰DR©TJðxÙ«ªª˜oûÛ—\vÙe—»\.‡~Ñ&:::ÒÛ·oá\Á¥~·«,Yüh†a(¢¾Îd2y�†\[—Ë¥�cAÐÐÐ`Y½zuzïÞ½…¶ræÌÞétEQdˆSï @ rˆC&“A2™ÌkÃ{'L™ò‰D�J¥à÷û™o¼Ñi·Ûcßýîw3ñx¼(MLtN§Óìp8¬.—‹v:�p»Ý ¬X2™DII *++áp8�L&áv» kÖ¬¡ßxã�¼hØÛÛË;G"‘ Âá0‚Á JJJ4á*i·%6Ð*[åS�‹P €[¹r%5kÖ,.C’¤)€©Â‘ë o›Õ?zû`½SâDŒ™p�R)û�òéÒ!C—ÔqËE?�ÜßÄdéÒ¥H§Óå—^z黺º~rôèÑB-€¬Kvè-4TR¦Y€ið(: ‰p8,H’¤ Jß_­o/:_6A4¢(btt���0 ´Ñhlúþ÷¿oþùçÿ¾}ûö€úö”šùF4ª”4Sh?%I’b±X*�§­V«Ñb±9Ž3 ‰Á 2„²$ú„��:tH;NBmêk”…™ Ɇ¬V+jjj°iÓ&”––bÆŒ(--EEEEÑ�Ç100 ´¶¶f|ðÁÔþýû%Ýâ“U³ý3êwŸ4ðP®¿þúŠÛo¿ýÊÙ³g7±,KéW¢2g§N�ÂsÏ=Ç÷õõ¥&¸öD+âBN µ�rGy<�’/dÈ"ìñx4'½D"A¯\¹ÒÖÞÞ ‡Ãyç@E¥¯¯/1sæL‡(Š9·ä³!ˆÈx\2°†Æ íg'â1Žã´ »¿¿ŸÞ¼y³Ãáp$¾ùÍo&GGG‹¢YI’äP(”!]SSc™={¶¹ººšnjjÂüùóQQQ¡eñdPP(¢ãñ¸qß¾}¼ZÆ àôéÓ™††�¢(C,Ãèè(\., hšÖ&m ‚@ÌÒáp˜XÞ:‘ëšÁ¦M››ÍÆŽŽŽ¾'ã• ïB±ëÇ g2íga'M± ?Qr@õÏœ¾¤@ÑGLHª§§‹/Æ%—\EQ>õ¹Ï}n÷Ñ£G÷dþŒîySp®HZÏ€*:¶‚’$iš˜ŠMyÿ.Xøb8%IRˆCie+ô˜ ½HX„‘‘̘1n·ÇÕÜvÛmŸœ={öžÇüd("™p@- Ô˜©'“ ô ¥�d2™a†6›ÍœÅb1RÅÑ4Mjœ˜‘>’}è��ô”§ÍfƒÇã�×ëEEEÊËËaµZÉñO8ß]ED"¥¯¯O¦ÂÖÂh4jb»òòrãW¿úUCKK ÿÀ$ý~ÑU?›ÍâÍ7ß”¢Ñh˜çyó–-[l•••L1h·Ûéõë×Û_ýõ¨ y-�555‚Ûíæ†A<G4ÕX§Ó‰ÒÒRH’„h4TÏ™�dÿEÁl6sñx¼h-~ª›Þ2›Ôöhç²ð|Î ;qã$]zú<•Ji×”8r® Ä9M º‚ h@�”qX–E2™ÌcÈõôûýèëëCCC–-[¶Èf³]ûè£�þQç¨/‚_y²µrš˜600‘'öD È©Îó¶3gÎ(‰DBd†%Æ'ï‘H‡MMMèïï§-ËÂêêêú7ÞxcÏO”d2‰òòr¸Ýn%›Í*ÉdR‰Çãr4•Ξ=+··· ;wîÛÛÛ¥D"¡LpM²ºÀ?®£úõ‹SáïòÚµk]_þò—W®\¹r1æzœL}#¢±h4н{÷âСCèêêÂÐÐE!B2ýõÖ;ö3¨Âh¢��,$ ,æI|óIàR½ò™ë®»ÎÙÞÞ&³ìuÁAéïï�ÕÖÖ:�F#—Éd4ª7™L"‰`Íš5¨ªªšðž"Œ�¾þMhjÒá1‘ï=aX–ÕÊ ƒ�Ú²e‹uÉ’%¦={ö$~øáôøøxQ´ÛÞÞ®|á _à›ššÒßùÎwÌW\q…¥²²’%AT’$ø|>0 c^µjUz÷îÝݳ tttÄZZZ<EQÄÙ’€-›Í¦Y.ÇãñqõšxÕò –-[Œ y�{ª›~&ƒÙlÖɽނyÐEO´%¢(Âçó‘²:„H$¢�¶&×@_^ C¥\.–,Y‚’’M�CºBH©¡ð»™Íf°,«™Q–ÁjµÂét¢»»›00Lssóíwß}÷‹wÝuWùõ=@‚i`üŸÝ²… addDáy^&‹<ÉÒÞ5BQÜx<ƒÁ€††ŒŽŽÂd29®½öÚÍ‹-šûÜsÏíyíµ×B:çºQ•&w!× U†œP�9Ð€Ž¢(J2™T’ɤ<00 �…‰Ó¨=é”Ùl¦, eµZi’�¼­/Tà÷ûå��exx<Ï+“00@N[‘P�ݧþ1±JYS÷/X°ÀðÙÏ~vÁÆ�————;ɱr‡d2™7ô…œ×Ó§OkƒzFGGI6†ü:g1ïˆ<?ÕJá8NËì'c8ŽƒËåÒˆªNçî¸ãë¯ýëd¡@’$ÅçóÅËÊÊìÇq$“6¹ÑÑQ\~ùåhhh8§ÎMJzBzÿ�œªœ/Ñ+0 ³Ù ƒÁ �†úúz¦ººÚ¹|ùróŽ;’/¿ürfdd¤èïìì”n»í¶Ä† RwÜqµnÝ:SII‰mdd„>tèFFF¨’’Ã0ã’$Éú2ÈÈÈHЦiK(‚ÑhÔJ¢(j,T6› ©�_kÏ\½z5Ç0 C¼.„î×û�KæUèE}zo ÒÚj±X�Ç1<<Œ¶¶6œ#�;ä LX4ÅáDZjÕ*X,ÏÇ?þñ›üñ_:tHÆÄ­�úgA™8MwL€lÆOajõÿÉÞEÎeÎFžS5ÀívÃçóƒ½+Ô‘Íbll �.— >Ÿ�1›ÍsêêêêV¬Xqè/ùËÑ®®.â¬&¨”yH=Î*ätv’!Mü‹²ÄÝ/�"�cP¤ <‡z¶%«žS?ruþô_ÿodŠÃá o¿ýö†k®¹fm}}})m¡$^üŶT*…@ €X,¦©òiš–3™L犞ô¾ý Œ˜Ô*�FýÇù2!“É�Ç£…x<޹sçZo»í6éç?ÿyZ ZÍ5›ÍJ###q¯×k—e™#Á(‰`tt}}}X½z5.¹ä”——çiKHÀÔƒ’¡’Z6¡¹ív;Òé4‰„ÖbVÈ`F…˜>577æÍ›gزe‹°oß¾ÄSO=•òù|E¯÷®]»Ä]»v¥ÇÞ/~ñ‹¶²²²¹~¿¿Êï÷FFFØòòr«Ïç‹éÁè©S§V«ÕȲ,£( ’É$(ŠÒŽQ’$1™L¦Ô²—Æxy½^Z’$êBÇS Øíö¼™dV…>èËl»ÝŽ’’ð<�`ûöí8zô(B¡�Fë&ŠLç$³  Ó— ÈlR^ {,C8F?ÚÚÚ4âô·aÃÌ�;�V«U»^zVQ-‹Àáp`ppíííX²d ª««?õ£ýhûÕW_}ùæhź&e¦;¦À‡¹0p�ÁÛf@äá¢R©”äzßÉC<ün�P(ƒÁ€úúz$ ƒAãG>ò‘Õ+W®l9zôhÛ+¯¼ÒµwïÞ¨®·:¦fÖ}*+PŽœ“¡ 9±=Að§.àœLL‘äL�FT�’@¾M/0±I™7ožñ“ŸüdÝúõë—͘1£ŒeYš �Éf³ƒÚ‚^˜mɲŒX,†X,¦µíI’†a’¢(Æ0y úÏ£dY–H}—ÔÚÏ·™Íf”””h´o"‘À²eËìßøÆ7”_ÿú×5kÓ@€ ÒÈÈH¬¤¤Äj2™Œ©TŠJ§Ó‡Ã8{ö,öïßO^(--Õ̃Ìf³¸HP#þÿ…÷'±Ü-Ù�»±¬.2™ ÊÊʸk®¹Æ½yófG[[[ìèÑ£™�;wŠ£££…NqÆX,Võ³Ÿýì(˲½µµµ¶’’’ù¡Ph6Çq6›Í–N$Ë–N§¥ÁÁÁ˲®t:M…B!Ð4­e³Ùl$I!§þ׺<¼^/#Š¢Öšw>  ÏàUS(�iÑ�£N§Ó`Y¤ëãøñãØºu+8€ññq�F8�NÌ›7ååå(//GII \.—6r[íãW’ɤÂó<Òé´¢QE-#P‚ Pä§~ü2qY$ÇFÚv_{í5TVVbΜ9hnnFUU\.—ÖÕCw±,« é:}ú4dYƲeËK—.ý”ZBT&(‚€ ׎ã(A¦Y€ið�ú“i&òÈ�ï�sß"õU5°¼÷55ÈÙl6Ìœ9Á`f³ÙZVV¶fÅŠ-o½õVÛ3Ï<Óqâĉ„j7Kæ ŒªÌ€o ¦J‘s4©Ùí{øõÙº ùˆðãêñ�Úþd_û½¬¬Œ½å–[f\qÅËg̘QÎqEÐăŸ€.2Œ‰dUúŒ�´7êÍThš¤R©Ä$%€s&øéÊ" ê$3Ö·�NÔöIÄ`Dé�J¥¨5kÖ8’ÉdäÁ>³ÙlûØÇ>¶víÚµ+ÛÚÚºvíÚu|÷îÝãÑhTB¾z>£ãÓ*àT»®T gPä¡/–Ý“¡< u�ªÙ¾ž9QΓék¯Ó4MÍ�;×|à 74^~ùå-µµµ.’5Ûl6P…X,¦~â—¯£çóÎ1=ŠÇã f€C<Ï‹”ô™¿R�eHË–^iOŽc¢ÞoÈ¿UEaÔÕW_ív¹\Ñ|0‡óÚ¯EQB¡PŠçyÁãñX9Žãˆ8mttÁ`gϞšC‡ðâ‹/¢²²uuuhhh@SS¬V+<�6W�¢(¤Ói„B!„B! c||\ÜC<þÉ´?½Ð‘\¾�™jÖI‰¢Èò<σÁº°9«r],Š,Ëžçûxž¯+ÆD�>}:ÖÐÐÀRÅéK,ËFÕk£µC”––¢²²’M§Óy“)‹‰lIæo³Ù@¦hS%â´¨( ªªª�L&ñÈ#�àé§ŸF €ÓéÄÂ… ±xñb,[¶ ---ðz½Èd2J ßzë-á­·ÞÊ>þøã’Ïç“ßÁÚ£Рp‡’’Æét ƒÉl6s™L†"D2@)```ÕÕÕ¨««ÃŒ3P[[‹òòr8Md�FqàÀŒ��Ùkjj®©©©é’‹”¨àB×Ôém|èÊÅ~—ÕÀ–·H É™LFbY–!Y„^�û~m²,# ‚eY8�Nx½^„B!˜L&æM›­Y³¦ùÖ[o ‰ÁÁA¸\.¬Y³k׮ņ PWWY–•ãÇ� O=õTf÷îÝÂßþö7éÔÃÏLA@ �€HQTÂl636›Íd0, ðP5;à†B!m.C0ÄÌ™3QWW§Ó »Ý›Í†¡¡!tttÀáp\~å•W>òÇ?þqp 8ç;¨£Ø§ÁÁ4ø@yL’�N¤ôÔ=€ŽŽ%d«ªªÌN§S£OÿQôÃ0 œN'\.YÐY§ÓY1oÞ¼Šë®»nm__ßðÁƒOíØ±Ã×ÙÙWûÞQD]?Qö?•ìå|ç<ï}&“‰niiqlÙ²¥~õêÕÍ555åÇѤ´B(óh4ªXbTD&0’þg’é7RÕSÜê{dY–}(.ŒÔ³²ZºÈÛÆÆÆ$Y––e)u"#™¬7eðGŒ‚X–ÕÀÉ’%Kl¿ÿýï™ûï¿?ÑÚÚzι–eY‰Åb™D"‘u8&U,Çê¡ç“É$H›¡ÞÁQ¯@/üIF766¢¬¬LÈC>Sgý,¥R©h$9=44Ôuúôéqõ¾"fU]ÈiOjð¶“"™¬éWKBÐ1RMÅî¹X,–1� ‹Åb×}Ç„üµúÆœ9s³ÙLöÒnÇÁívk÷)§ð<‹Å‚™3gbÏž=xðÁqòäI8�N¬[·6lÀå—_¯×‹@ >öØcé¿üå/Ù½{÷Jdä» òSØ(• Ïó"Ïó Š¢F£‘±Ûí“Éd¥iš‘$ ápú™ ccc‡Ã˜;w®Æ|˜L&ƒA$‰ªŠŠŠOø•n}+d we* wz›d€ÉS‘ßÃ…™`OO"‘ˆX__«ÕŠp8¬)Ì/$¼ÛM’$ º—d˃Áèt:š››g^wÝuüØØX°««kôÍ7ßì;qâÄxFYÕ ×ú.”Æ,ú“¦iÊív3]t‘såÊ•õ«W¯žQYYéu8†a(¢ &sˆý+ üÄ­�ã8­$Bιž}!6Ë4MkÝ D Rõ™`08Z�u«u*º`¥½>00 g³YÙn·3¤0�NÃl6_�„dÙÇ!�#“É`æÌ™æþð‡Ì³Ï>ì±Çä"Š,ˈD"©x<ž±Z­œÙl6 Žž ÿ­PYXž°X,ðz½¨®®ÆÜ¹s±|ùr�‚Ïç“ý~¿044”ôûýB <Ï jù(¥ž'b�ENŒ: fþÕ*�Ó�ÌpR}Ÿ¢²U*PÐß/„B¡1‹Å’PJQJò¸Ö IDATdYæ‘ksÕ¾k}}=k6›'½gÉ$b2”L&µëV]]�H$‚{ï½Ï<ó ²Ù,.ºè"\|ñÅØ²e êëë•ÞÞ^á©§žJ?ÿüóÂÞ½{å)y¥€EÒ/z�=“2EQ%�N ét:b0v»Ýb6›m ð¢(bll ©T ñx\ó˜;w.ŒF£fr‰D�Éd®X±bÅc­­­zwÀÉ´–L&¥ MoÓàOû+¼VL¤×=ÄD¥���ñ¢‹.‚ÇãAoo¯fʲì{:ntª@ ‹i�…ôÅ«ƒY(“Éd-))±Î›7¯þª«®ZžL&3ñx<Ö××çûÛßþæˆG"Ay‚…“©b´ \.×ÐÐ`ÿìg?[[[[[[___a³Ùlf³™&ï!Ù>™!‰DrËjqˆÙ qR#=Özµ; v¤íŽÌ­'YqT£(ª—çùÌy˜òZºð=[·n•~ðƒˆÕÕÕ Ã0À Ãu.´MïÀ§ŠÏ _üâ=6làùË_òÇŽ+\ÔyR,KÓ4M›L&†€–eY Q…ŸœWÒg^^^Ž `ýúõ¨¯¯WdYV|>Ÿà÷û3»wïN9rDfäŒ{�Ç“©T*Ù××—‹$“I>$GGGÓ±XLL¥RR6›•eYV†¡ŒF#e±X§ÓÉ–——[*++­V«Õ>cÆ OEE…Íf³9ív»‘ã8ަim$¯Á`ÐüÚI�ž¸£‘Ú>ÉT "uZBG•º~3 ())ÑFÉ’Yòz?yŠ¢:ÕëQŒ(ÔÄ Ê?T¿244$TWWm6†‡‡5†Ao=|!ùž&“‰|Gª¹¹Ùú«_ýʸk×®Äï~÷»ìÈÈÈ„7�,Ë2Ïó2ÏóEQ”:±�â8ŽQÙšaZm SÈ¢(J‘HDAa†öù|Êàà <>>.uvv*}}}“µ‰‘S9kêL1`­ê(Š¢xEQú%IÀ¹3臑ÙÎF�ï€l8ç8îïv»ýªL&#X,j²gŠâÐZêJKK�ÇñÛßþO<ñ`ÅŠX¹r%™» ÞÿýÉGyD8yòd¡&ˆ”Ëâx»Ã…üb­­ iZ»&&“‰æ8ŽRKyŠZš¢$IâdYfÕïçTÙKc�WÐÿY’$9ljDÒãñ¸¬V«Ý`0ÐDøIÚeËÊÊ4oŠ¢h«Õz-˲ÿ#Š¢4L‹§À‡œ�꟰ï¼Èß‘–6³~ázå•W„o|ãŠÛí¦Ôùòš"|"7²B£ýq¿çT‡¢hm]$ó3�Z¦JTò<ÏS’$L&“ÁívÛ ±±d�J§Ó² ’,˲¢(’,ËŠ,Ë MÓ­n Ã0ƒ�1›ÍyL4¡ä†Ñz®‰X�PüäïIÐ'æ)䜤Ói ¸è[Ò ¯3ÑCèM]‚Á æ  %•Juá\‡Ä‰Ø¢¸º¸ç=�ÇŽˬX±ÂV^^ŽcÇŽ!‹Áívkßñ�\O2é�ŒüUËIìÕW_í\¶lYfÏž=©_þò—B&“¡ÎsÝQeµÿ\œB™f²ÒMákYõœô#WÏ'ã™ó¡´´”½ùæ›g,]º´Æb±8âñ8~øá;wîÑ�sò=D• &Vúk"�ÆÆÆ|&“i·,Ë5[Ö¾ÅbÑžûÂ{‚”•(#íÝÝÝøùÏŽ}ûö¡¬¬ óçÏGKK ššš”“'Oò¿úÕ¯RÇŽ“ ¾w9Ý1'`áv»¹††ûºuë@«‚/Êh42Š¢0ÅŽ[Ïh:Ÿ´¹‘@HŒVH®ŸxFœæÈÔ5rÞ£¢÷a'{1µ5™€F2= 'ôÑ€:q-‰DF&ɤ ·$r5î¼wO?ýtꓟü¤d2™Y–�F‹Åàp8´‰�ït#`‰˜÷‚@Õ××›fÍšeºúꫳ{öìá{ì±lGG5�ò|*®ŒS}¿¤»r¾~õœ¤‹1gEᡇšµbÅŠµn·»Z�túóŸÿ¼ã­·ÞÙ´iSé–-[j<O©Íf3d21�Ž=ztôé§Ÿî‡Ã6äZüÝù—E¡ºÕŒ8Ï;Àh4ê»Îy®ôÏb&“ÁÎ�;ñ‹_ü>Ÿ³gÏFss3fÍš³Ùœ}øá‡“ÿó?ÿC9-qÙL#¿µU»÷ªªªŒ—^z©{åÊ•% žòòòÊòòrƒ~´¯~?_rð¥/} ‘HD£ÁcÇŽ oÛ¶Méîî¶©€€+rçÝËããã©H$2ÀeµZ=¢(2$II$0›Íä^eËË˯FN›AáüZe"6â½°DŸÞ¦Àûü§’õ+ ˜_@»*§OŸÎÖÖÖêêêÐÙÙ™§¸Ð ^¸p½›’Aa`.öÿH’„D"‘÷oˆ© bdÀI1pRìx'ÊÒIÀ'Tw±Q«ä˜ôXô“Ö&k³2 çLÊ ƒ@:4†éO¥RÙ©dR„‚FNšgÀ~àÀéÔ©S©ªª*ÑD£QÍ„ç½0„"Ù+1›’e¥¥¥†ë¯¿Þ°iÓ&áĉ©={ödÛÚÚ”cÇŽMfI¬\Àkú®�€1“É4n±X¡PˆÇÛâ½¢lÁï~÷»úÏ}îs×J’dŒF£èïïüÅ/~ñå�üãææææy.—Ë¢gIhšÆ¦M›2×_ý™ýû÷|ðAóàà §K ù}éŒnmTPDZ8äˆ0\áp™LÃÃÃx饗°uëVD"477£¡¡•••ŠßïçŸzê)þÔ©SÄßb9mCoÏÉû¾555Ìå—_î^¾|yí‚ j+**lV«•!lñL Àx*Ï0i)Vf³™+++«ž?~õÆ�å›o¾9ÑÑÑáÛ¿¿Û¶mæÞÞ^'εúÎc¶$IR<Êd2É TØl6“(ŠˆÅb°Ûíšo‰Ñh\¹`Á×É“'Çu,Àù´ÓÞÓàvÒT{Ö),tº�¨ �QÿA‡ʬY³Æêõz©'Nh}Õ¤ú½ ñß C0Ñû'äwl ÿnª C¿ïsÈ8ŽÓêôY™~R)¡èƒþùŽƒPÿ…@¢³³Á`ñxœÙÈ’$?O¿v!¥+!'b› ]}:‘HàÕW_M|îsŸ³rG���a||.—KkQœˆ–~'LŽ®ÛŠ¢Àãñp6là6lØ „Ãa!CCCâË/¿œy饗Q©óýÂ`ŸT©ý¸ÑhLz½^aãÆ�΋.ºÈ­(ʼ×_½uÛ¶mqL옉›o¾Ù|ÓM7]ÍqœQQ;|Ï=÷üeãÆ�uW^yå•6›Í^ì~Q™ ãâÅ‹›6lØ _qÅ¡[o½•ïììòt2ò­¬‰¦„"÷Œþ| ÈÈÈN�:…ÖÖVœ8qEaÑ¢E¨©©�Édß|óÍøßþö7AÊÝøcÈéÂÿ·ö�«ªªLwÜqGÝÚµkg×ÖÖ–�FŠ€[rŸ¿2l‰´«NîÉNhy¢!ÂWI’h·Ûí¨ªªr¬[·N¹é¦›‚Ç�þîw¿?|ø°§# ]oEQ¨cÇŽ¥ÇÆÆú[ZZ¼‡Ã“Éd‰DàñxàŸ]WW·úäÉ“/�'ø£ „s˜î˜ÿ´-›ÍžOüw!Ù¿~}9u¯QŸ}ìÛ·/së­·Ê¥¥¥ EQš)‹Íf»à‘¤ï5C@Ãbï)Æ œL& ?MÓZ–Otúÿ�dfÄEOßc^l!?_p$-‚úmll ýýýšP¥ÿ‰D¢ó#²ûÕ`ÀèßóÓŸþ4ÛÜÜœbYÖBìšìv»ÆnPõ^n…Â~·Ûmðx<† àŠ+®Pî¾ûn±¯¯/�Fű±1!�Ë‘HDH&“b&“É*Š"(Š’¡(Jä8N´Ùlp¹\”Ãá°VTTT:OYY™=�s>Ÿ�nmm=¶oß¾á‚g”M›6y‚Á`¦­­M¸þúë[,‡úÊøÃ^{íµµ›7oþÇqFýu%÷6¤�•¦izåÊ•¥Ï=÷ÿoÿöo¡gžyF*ô¹·¹BE"‘¼QǤ,344„®®. ¦· Zó/¶ ÌÕ¡l%‘H('OžÌ,\¸Ðìõz1::ª9»½We€÷ Ø©”&úóD Z&“ÑJ0úÿ�ü®úd/–)MUA|é X ôôô`ttT£ÿÕÏl“§æ×ZHq§Õ á.Ì@·nÝš©®®NqgG ДædÆ<‚ÿH�T…@ëYšb[<ÇáÇÑÖÖ†S§N‰½½½/øýþÞnƒÕ”ñE1‡Ã>{öìz¯×ku:� sòäÉî/ùË -‹SŸÍʲŒ³gÏfvïÞzøá‡;öîÝÛ�\�]Sž¯^½Úr×]wÍ^´hÑœÿøÇM===þÞÞ^©  Nœ8!”””hB×T*…H$‚®®.tvv"“É`åÊ•¨©©ÇqèééI>ñıD"E®…1„ º‚–/_n¹ãŽ;–lܸq™²g±XÀ²¬fÞDîORòÒëhtì}Âù@y¿þY ">˜Øl68Êív;f̘Ñ|ýõ×ï½÷Þà½÷ÞËa‚îI’¨ÎÎÎö†††vY–¯R…•e‹¥´ººzMww÷ß&Éü‹±iÀ4øP€L È,€~ÁÛ-a ðÄO¤?ñ‰O(õõõÔñãǵžv»}RÕï?¾6(öçóeèÅ7ýx!uñÉ Y �%‰ §§ããã V­E¥‰D×0Fú×e•ž‹œ]{ïÀÀ€²ÿþÈÒ¥KͤíÐb±Àn·Ãjµj">Âaä?óž˜è<�ŒŒ`ÿþýØ·oNŸ>�D"q¤···O÷LäÕý†ñŠ¢XÒØØhÞ´i;>>.@:�–gñ¶yÑ9ëÂm·ÝV}Çw¬)//·², »ÝŽã4Q)é0Ð×ìIÙK°ˆÁ …÷ôD`[?¡L“G"‘Ѐ€Ùl¦œN§÷'?ù‰ëâ‹/î¿é¦›I’Ø‚ M!ç&YyöìÙÇêëë}<Ï9Ó²,3,ËnfYöEQiL<(«XðŸÓà_ ¸�à_¬$0Ž\[�Iÿ™¯¿þºÐÓÓ“-))1 $ ÄãqÍëýƒ¶ÐÔb©˜¨P¨(Þ�ã×Ï ÐoýýýÐzžÕ`Õ;>>)Bc>ÿùÏ»n¸á†™[¶l9:A©È‡\\]á½õÊ+¯ˆ555I–e­ãããšÓžÉd‚ÅbÑÿ�  Zô�rŠœlËf³èèèÀ®]»ðÖ[oadd†ûûû_WEß O#׆—T×§¦êêjÎãñ°W]u•å¹çžó·´´Xº»»¥ýû÷³ÿøÇõõçìÝwßüío›ýøÇ?Îþæ7¿±/]ºÔâñxI’©¶¼ ÏóÙ³gÏ¿òÊ+'þú׿öýùÏŽ\³s\òNŸ>Í,Z´Çiœ‘‘ȲŒ––\z饨®®ÆÖ­[“÷ÝwßX 8­2:Å,}�ÇÃüøÇ?^rÅWÌ7™L4ñÎàyÑhT üDôG|+ ipRŽ  ¯ð¹˜ \8&V׉DN§“´ÕrŸþô§gÍŸ?ô«_ýêøÞ½{‹Í…¶H’4»¿¿ÿÅY³fe‰Ä×Ðv»}qee¥epp0z`:àO€]öL]¨ÏüÉk)5”é@2™D{{{ꪫ®2Úl6Œ��kÃgôãj?�'f ÁD[1ð�ÚHö_xnyžGkk«VŠ!Ç&Šâ›*ý_4Ò®_¿~öœ9s®Þ¼yó©íÛ·§ŠÜ#•.®B¾â¢(RGމ/\¸Ð”Éd˜±±1M AFæVTT€¦i$ mr¤¾&þ�¶Ž&AÊï÷ãðáÃØ¹s'º»»Áó<(ŠŠ%‰í²,KÏ„ À*äüûã’$• ‚@@KK‹ùÆoµÛí6Q]�@@9pà@Úb±8Òétꡇ >ñÄÒwÜÁ}ûÛßöÖÖÖˆ_Ò ‚@Y,“Åb™UVV6cݺu#¯¾úê¾ßþö·gAзäæM§ ƒŠ Ú´ÇL&ƒ`0›Í†ºº:°,‹}ûöñÿþïÿ>844Ô�"³=t÷�í®»îºxÑ¢EµF£‘"m°¡PHó÷ Ý,úòMã"Š¢ò&¢÷§òÜ\ÈsEf‚˜L&b†E-\¸°ì±Ç3}ë[ß~öÙg™‚l�Ð I’¥¿¿ÿ¥úúzW:�¾™eYWyyù‚ÁÁÁ7'Èø'£ÿ§AÁ{¹ÆMŸ‚w¶ J'D)D¯Ää¢ðÏ…;£ûÉèþlAβ4�"ã8NÞ¼y³%‘HÐ}}}š™‹~þû‡ 1Q(�6â÷_XË>}ú4¶nÝŠS§N!ÍéýX– ÿU–e±•­X­Vú®»îú„Ûínv:�Ùçž{®»àþ ?³*°Þ[~¿_¶Ùl²Ùl6Çb1-À€Ýn‡Ãá€ÃáÐfœ¯Õ²{òn¯¡ŽÓé4|>Þzë-<ûì³Ø¶múûû!hš–³ÙìK###…–½@Î�® 9›Z@•ÙlV.»ì2«Ëåâ^{í5þOú‡S‘HD9|ø°`2™¸ûï¿?¸cÇùÆod?ö±�U)ŠÂò<¯KBw  º!Ò&“É>gΜ¦‹/¾ØÐÞÞ> …d|ÕA§à8ŽYºt©EE$“I„Ãa¤R)Øl6‚€ýû÷Ç¿ô¥/õ ¶#§7�‹³�|ä#žÿüÏÿÜÔØØXf2™(·Û�d2©I–ea0´òÃ0šî…”ý¸+4¯Òw'œOü÷nX3A‹Å@QL&år¹L›7o¶E£ÑÀ¡C‡ô @QË)’$xž?RRR¢Xj0ÒCCC»Î“ K¨ô�šž8 þ9'Ža¨%êDTÖ…²‹ê"hÒvww7®½öZÎívN�:QµA6¤ îƒL?l€€Œ­%³ô‹ß믿Ž`pp�´T)Eí?…âåå3ŸùLÕå—_þq–eMf³¹ôÔ©SGúûûÓEîI½î5E²#: J�‡Íd2œ>ÇC�Ç"$3›ÍìðnÎ?éĈF£èëëC[[öîÝ‹£G�‚çyò™2MÓ�àÜÁXP™¯z•�Ìpµµµ)‰D"ÕØØHUWWŸyæqtt<ÏS‰D‚êïï�vww�ìc }ô£�k4æ& ‰D´aJ²,ƒeY°, ‹Å—˧ÓI555U^wÝuemmm½Fä& `–e©ùóç[Óé4Åó_Š[Sð­o}kÖí·ß¾Öëõšˆ;éå'Y?Ñp�–<ÒíBè~½�Ö?{#Ùh4 Y–IGŠ¡¥¥Å"‚ÿ­·Þ2ü“v©T*•Eñ`UUUKIIIçàààÎß…Põ¡]Ó¦Àÿ®­ØðŠ eŠ•huá«×-B*›ÍÊ—_~¹Éï÷3ããã i‹Ecˆªw*ð‡¼_߃ã8¸\.�¹VçD"¡µ[íØ±û÷ïÇÙ³gõâ¿cÃÃÃGðöDG€À•ÊœN§ïë_ÿúgl6›KžDÅb±ª“'Oî‹D"‚.ð3º2ÓÒÒR˜Â{*�N+ÉdR´X,&Q)(xž‡,Ëp:�p¹\Ú¹!óHi€¸È½“ó§w`$ÕX–¡ÆÑÑÑ�ÖÖVttth*höƒÁmét:Y¸°ÿìg?«úÆ7¾ñÉt:�ݱc‡Mý®YäÚç\äþþþÀk¯½æ”$‰¬[#Ú˜ Ã"�ÇãjmmMíÝ»7½oß¾Tkkkª­­-ÛÙÙ)vuu)===tOOuêÔ)øý~m¤5MÓÄ»žòù|eÑh4ÒÑÑáÖ­�”,˨©©±(ŠÂð™-ÎÉqR6›�­««³e2 Ïót$ÁêÕ«ÑØØˆx<Žááa 0555—°,;ªóTPdYF<EQäÔ–;y``àôÀÀÀ!•ö/œ_OQE}ÿûߟsà 7¬r¹\ŒÝn×X½%/9‡…N•S}†ÿâN}©ÌjµÂçó�ã8x<”••yÿû¿ÿ»ô_þå_|­­­•jIkÞ„îîîøéÓ§ÛQ\üG�'éš.L3€“—/B¡¦¸OU•𖆇‡Å•+WZÒé4‰D´º!sKTëï¦6ø±d §þY–…¢(‡Ã]üüóÏãÍ7ßÄÀÀ€Þp§Íï÷VEÞ(+TRÅ}ýë_o®««³êG ›Í–ûýþýÑhT,r?È4M§~øÃ¶¬Y³†}öÙgI’òî%žçE ˲†l6K¥Óið<�H$‚p8 ¯× §ÓYô<èqÄþ•ôz“�´ÇE"HÓSѤì$^yålß¾]]]y³2DQL„B¡×xžÐdƒÁ€Ç¼ñóŸÿüµV«Õ€!øÀ ɲìRA@@ÛÍ7ßì¹óÎ;/Y·n�’ýýýT˜Ç0 óµ¯}�ùÚ×¾f¾ýöÛ­·Ür‹qóæÍÔ¢E‹hš¦©ÁÁAE’$%“ÉÈ£££ižç3�‡å8Ž�ÇãÚP�‘‘ø|>‚`H§Ó‚ÏçËãÛÍf3'˲Qµÿ=;00ð† Ò‹�ú›ßüfó-·Ü²ÊívsN§ét‰D"/ø“$‚}âÞͳû�bÊô €¦i ÃápÀh4¢´´ÔÛÔÔÔûðÃ�áí!WmÈyœÈ¹ª‘\¬ö/OR˜üÓàƒ³qWLx!¥€‰ÊŒŽ:›©cj(£fÍš%»\.s(‚¢(yí`dÁ~/ÅAÿÇqp»Ýšç?h¹\.œ:u Ï>û,ˆöB]øøT*õR"‘(`cE®•ÍpÉ%—¯½öÚr§ÓIëÀàà ’É¤É`0Dºººúp®.„é›nºÉ³víÚ9k×®UvìØ!$‰¨Ó4ÍŠ¢hŽÅb#�@àY–ãEØ`oºé¦ywÜqÇêÒÒRÖétjb>üõ”¿þZ¼_‚¾÷»d@Ê@###())ÇqTeeeuEEÅέ[·�ëî ŽŒrA¹l¢Ÿ˜Óà»™L&J7”bª™ÿ…èd ȵæ� ƒÁ 544XR©Íó< ƒÖ o |¿”ÿmâ÷O2æT*…D"¡M^{â‰'ÐÚÚ ¿ß¯7Ø94<<|çú9Ô"×ÅAùË_ö\tÑEVý¨Öt:�¡¡!ðb¶oß~òĉF5[�ª¨¨àÖ¯_¿Àl6klX]]�qÙ²etÿÉÁÁÁámÛ¶�Ì›7Ohnn.‰F£T¡®Á`0PMMMÆuëÖ™S©”pèÐ!1‰dW¬Xa6›Í4í …�Ç©þþþ¤(Šš±“$I)EQÆãñ¾"Ï<°ÕÕÕsï¹çžUsçÎ5"œ,ü?Ì¥3})ü~¿m6[ycc㙇zh·z¾†Õu­�˜.L€å6QàÎßx>€BN5¹zh^K`6›lÉd’Êf³%k·Û5€Œþы̇�égdÁ"ngjp† xä‘GpäÈM¼¥îoù|¾SE²7€¥Ø;ï¼Ó¹bÅ »Þ¿�Pñ©TŠÆëõöìÙÓ&Šb³ÊøÄ‘«-Óè�7RsæÌi€êêjã%—\‚—_~9£+¹ú¹œN§³F£‘£išÉd‘H£££èííE__’É$QlkÌ‘ÙlÖtú�èȹèììÄ“O>‰{ï½/¼ðFFF E™J"‘ˆ‡B¡AY–O¨ßC \rÉ%¦ßüæ7W,^¼¸™šàQ;vìè=räÈEÈÕø³Òn·›[³fÍB·ÛÍé)m«ÕjXºt©¹··÷ÌÐÐPôèÑ£ƒ³gÏæhš.Ïd2y#Éær¹è+V˜C¡�ðÆod].—²hÑ"s*•Âøø8‚Á 9gét:MÄ‚¢(m™LæLA Òžu–egßwß}«—.]j!bK]¹¨hÍÿƒhdónñFEee%†¡\.Wi0|þÈ‘#gT&Hš ó—§À4øPm,ËRÁu"}�Œ‚ºz >Á`ååå”Ùl6& r<ykÉîþ™‹Í�ìÖåriêøh4ŠT*EQàõzñÔSOáõ×_‡ÏçÓpŽãüƒƒƒ¯H’$àÜÖ¥…jJKKéï}ï{ån·›±X,p»ÝÚ^RR‚ºº:Ìš5 555X¼xqI&“9ràÀ9È*5ûåÕR@jãÆ�sÍf³™¢(TVV׬YÃ;v,ãóùòî5I’žç³êŒwNm;D4ÅØØÑÙÙ‰ãÇ�£«« ¡PHsu#·™LFË\ûûûÿ?{ß$GY®ÿt÷ôôôôÜww6{ßl6!·MH "1$Ü�ž 7AA-OYu< j•u<”ÇR8–¢€þK��‹\Œ�H$!r¿l’Ífïs¿OO÷ôí÷Çô×ôÎÎì.è9'è~USƒk²™éþú{Ÿ÷yŸ÷yñÎ;ïàé§ŸÆÏ~ö3üüç?ÇöíÛ�F§ô¤«ªª¤R©t>Ÿ�x@–à×]w]ãw¾ó�kçÏŸßát:©z“5M3^~ùå£{öìiÐl–SB~¿¿|Þyçõz½^'™€IQdYFKK‹gãÆ�Ý¿ûÝ£møÃÄ––o>ŸçÊå2|>ߤÌÛ0 pG�sÎ9®D"¡lÙ²¥´jÕ*Öår±‘HÑhététZ*•J$`F¥#¡–Õ3 ã�¸pÓ¦M~Ò’›N§-Oò}«‡V}KgÓ=Ëä{F£Q0 ƒ††8�N_ww·øãÿx?jw<ÍÄuÜçÖø?]N§“²)§+TgþµþÛÞ`ï Pi£aí¿Û0 d³Yµ½½]E‘2mV­¬Ž˜ÂØäÿkºñL$ø†�|>�|>UUÑÜÜŒ7Þx[¶lÁÉ“'Á²,Xr¡Px9UéË«ÎR|ÎÀ}þóŸ÷¯[·ÎëõzÑÜÜ —ËeYÈŠ¢MÓ  …àõz™p8ìxä‘Gö¡"úô™ ¯ pøðaµ¥¥…îíííáy4M#°kÖ¬áÆÇÇå'NLž†a¥RIÑ4Mu:�š¦iÒê—Ëå, pâÄ ¼õÖ[رc¶mÛ†?ýéOغu+^zé%<ûì³øÕ¯~…_ÿú×øýï��;wbhhÅbqJà2³þB"‘H+ŠGEí�`Ð4�{ï½·÷K_úÒ¦¦¦&Ÿªª(•J–q‘ 066†ýû÷ã�ü£¾mÛ¶ƒCCC ¨ˆ)i^Ã0š/¾øb¿Ûívx½^«–ÎqZZZ0oÞ<¶§§Çزe %I’×´Mæ‰U( …,_b´#}öÙgsúÓŸJ‰DBêèè¢Ñ(�F‘J¥P(J¥R©lþc&WËô«åÆo<ÿ‹_üâ<Žã ­ÞxûXäZb¿¿7q-ù¾¢(b||mmmà8Žòx<]Û·ozddD©Æ{`æÀ8³–ü§gI×a¦V—d3 Uý[–PÍív»ÈøP2:Ôçó¡¡¡~¿RÖq¦€€ÿKP@jÚÄ5/ŸÏƒøë{½^är9üô§?ÅÁƒ­C�¦i(ŠòÖààà‘,Ðɲ,óÍo~³¹¡¡�nii�®ë–OUU  `xxØš®æ÷û^ýõÃÃÃ-¨¨ß9Tlq Ùh4šëééYÅqãõzaføÌòåË]¢(–:¤W'EQ4QËæp¡Ý (‹Èf³H$˜˜˜ÀÈÈNŸ>�Ó§OcddÄvD¼jC–e)™Lf‹Å¢„Ê«&pÇqÔý÷ß¿úæ›o¾Øëõrdï‘ v¥R ±X [·nÅË/¿Œ;vàСC8yòä�t:Ýh²×™Ë.»L…Bžçáóùàõz-ãÑÑQÄb1g4-êñxÜðxàyÞž€Í­9ð¸êM²šM7€ý�©S C&·R‹ÅÔ††^Ó4šÐ² ÃÀétZAŽçy0 cæg*øßÄ7¡±±4M[�PQ«çÿ‰'žÀ믿EQ`Sð��ŒŒ¼.IR¹ð8÷•¯|Å·nÝ:OKK Ã@"‘˜r½Ëå2FFFpêÔ)ð<�p8ì`fè™gžI˜´7ƒŠî# €ŠÅbñÎÎNŸÃáh&¶±E�çyzñâÅ.]×Õhæ!<… �$©Ì0 Å0 ]½_í*ÿÙPÓš¦i¥R©”J¥r¹\NÒ4MEŸªß ”èëës=øàƒë/½ôÒ>—ËÅÔ š¦áرcصk8€“'Obll ©Tê�R©äCÅ�2Á„qã�7òK–,aÛÚÚàñx,GÃ#GŽ`ïÞ½H§ÓT8v¼úꫤÓiuÙ²enâ×Á²,@QDQD>Ÿ‡$I`Y–ýË_þRŠÅb#‡£5�“ ²»P(EeŸ¯¬@À²,µ`ÁW86öìÙC ƒ&íEMÓtQ^hš¦)sÍæºéº®Ë²\Îçób&“)‹Å²¦iºÉN  bõZ¦i›6m ?ðÀ–/_Þîp8èz¿S–e9rˆD"Èf³PUUÏçó{Ê岕Þq@cc#ý�o|CèêêrØÍ‡âñ8Ž;†x<I’Àó<­ªª200 I’„––ºµµÕI‚d(‚Ëå‚,ËH§Ó(‹H¥RT&“1vïÞ}Êív ’$y “É<_.—su€=`éç?ÿùÞë®»Î˲,ü~?²Ù쌊Œûõûýðûýðz½–Ð’<§D0Jæ€@›äEôDA˜ª3á™–$É¿]]]`&@QÔö_|1�©:€÷æÖ_yÎ]‚¿ Ú5Pß¾²Þd+;êÕðnß?i‘Qñn+ †Š l?*1&[�±XLây^lllH�!ˆ 8çœs,m˲H&“ Z œ‰Å_ ˆàÏï÷Ãçó�¦iär9är9+øÏ›7o½õž~úiÄãqƒARâÑ“ÉäÛà’êEÆ7SÿøÇ}­­­ŽææfÄãñI#y«mv="‘Þ|óM8�γÎ;ï¼­[·n´g¿¨h?íÚµk0Œ*ŠÒCQV¯^m >Ãá0uíµ×zÛÚÚ�<òHÑ, TïK£\.k©TªDQTÉét:xžw8ÆÆ Pæ–6t]×UUÕ%IRdYVõÉ4†ŽÊÌûÓ´ùóçs_úÒ—–\rÉ%+¼^¯c¦û™ÍfI­¥R årE•›¹¹}óæÍ£yžgHÙ�ŒÆ-‹“�EQ‹-âÿøÇ?– ÃÀÀÀ@éÜsÏuSE•J%Äãqx<Ð4 I’�Ïç111†axŠ¢˜\.÷EQ—S•/•Jr­­d>—‹>üá/¼ãŽ;d_ …i™5b›ëv»-=‚¢(Ö ¥Zì‹}�÷Fû~& À$ûjRf‘ey’ÅðÿZfiŽ*w:�8zô(º»»ÑÞÞî½è¢‹Ö™{f:¦uª¹5Î|<`Û¸ö–õæhxw lõ‹€òNhÖsl†0FGGó‡Ã¡ig Ñ4 ŸÏ‡¥K—ZÀ ©© ù|ÙlÖ:$ª=öÉAs¦2³µ;¥iÇÁï÷Ããñ¨¨ýIðW 8rä{ì1D"466Zf±XüðòI‘RÕŸÝ0 J–eU–eµÎµ3j€.ÊܳETú¹£$¯×KÝ|óÍ›7o>»½½=T«¿¿u‹t:�l6k,¥ÍÞûI,šÓé¤(Š¢²Ù,ÆÆÆ,ï³ bÕ�M ç ‡Ã…h4ª9rD“eYóx<Ã0¬{Î0ŒÕaŽf}>Ÿ'‘Hjnn.†1ªÕ½Gè‡Ã½_þò—CÁ`�&€Â>õ°zÿ‘,ßáp \.[zUU­}6È­ÖغR¬’yw:�p»ÝÖˆf2]�ü{ÿÓ`€øL¸ÝnÄãq¼ùæ›hmm¥ÚÛÛÏðKÔöO™ úsà[¨5u‚?�úÀ´iÀ€„Ê@�.Tjðƒ MÓ´±±±\gggƒ®ë´=ë$õÅÞÞ^ëõûýp:�Èd2(•J5Å^õÃÎDPP �q¯D®iš5žˆÁ`§OŸÆã�?ŽÑÑQ466Z³,Ë‘þþþ·Lº»^ö¿€¢(æÓŸþt°±±‘ƒ0Ûó¬k]}½Hà"n<‡aa9˲‡M5}Gõ6‹F£®'Näiš’Ã~ñâÅÖd;3 8nºé&ßÊ•+K�>úhqÇŽµªI½ìÆìzÒdqTÄ~†aôk¯½¶ñúë¯_´téÒ.RëŸM˘$I+‹�$‰¨æ“¶º®õ—ƒÁ efô�$ ^¯×j±#�OÓ4˜½ÿÔªU«¸—^z©dNÞ+·¶¶:ˆF’$k/,Š"Åó¼'™Lʆa ”Ëå¡:× `ñ¾ð…à’%K\ÇA$“Éš˜ã8¸\.kï‘ïZ„탭jñêëJð‰ÉœXû�eY8�NËð‰Ì{PUÕ²y&,Áÿ þœ ¡¿¿óçÏïúÈG>âÞ¶m›‚ÚeQÌ æÊsàÌ[,ËN€RuÐÖÆ,�€½GE•üQ“žT“$I‰F£Ù††¿ªª4yÈÉœqŠ¢ÐÓÓc4<σã8K_‹ ¨`ÿÖSøþ'2–eáóù,¥x©T²`B‘†B!ŒŒŒà§?ý)0oÞ<Ð4MÊÙ#GŽlËd2¦*þ‰†ã,M7Üp¿nÝ:Áçó!—ËM©û×; ‰È ¨˜Æ0 Ó¹dÉ’Ð�Ž¡¢ùà«ïÁ‘#GD¿ßï¥(ÊAÜ—,Yš¦-±'˲ÔÚµkÝ}}}ÜÞ½{ÅçŸ^~þùçu›> ¨^*ú“¤IõÚÚڨ믿¾éâ‹/^¸páÂVŽã˜Z�Ìîuoß+š¦AE¤R)d2äóyÄ MÓ’˜ª¶G[[­( E<ˆ€”S �-³æçÆÞ½{•sÎ9Çúóår<ÏC×u‹E <&;ô¦(еÒyÀò5kÖ„.¿üré²)‹5Ÿ}<‰X‘ˆíÖ¿v‹h"T¬e^Dþ·ªªöATVG¹Þäû—J¥IâBÒD|BE�(Šóò·ö% `„œ/©T o¿ý6Eñ_{íµK·mÛ¶ õ]TQ§D0üçÀ™¹Êå²Qƒ–¯¦^uÛF¶OŽ«.Ð5‚?y)N ÒrÖ^«ì�ÍfK Ã0~¿ßgûÙ; l€ËåB>Ÿ·Z¿j3 SAufò ÈÁC|ý9޳|ï íJ¾[(ÂÐÐ~ñ‹_`hh­­­E«ëºtôèÑ×"‘HfšƒÇ {éÒ¥ìÍ7ß$"­H$RóZU°ö)ŽÇ!“É€¦iWkkkÇ�˜@Å`Ò¨YMÓôS§NeY–m8vì˜@»»»-U9 ´�‡ùð‡?ì½à‚ ÜŸúÔ§J¯½öšôꫯ'Nœ€,Ëõ«nî³€4˲ٮ®.eÅŠ® /¼°{åÊ•ímmmM‡ƒ©uý ãa*ä�Ô»Iûa:�F¡P Ù¼ª(J “Ûe€joo§�N'E‚¿}¸qÙ#¿ÛWrÝ:¤�š;Âæu´†)Іaœ�J¥r5î9 “çùð—¾ô%¡££ƒ …Bp«¾×„'uzŠ¢àõz!Â$'@‡Ã]×-`*Šâ”`Lž)ro‰Ccµ™’ÉXY €h%$I²„äïÝÏóEÑÅ FÀ^¢ ÂcMÓ011š¦YUUxµÛ*g*Ì�9ð�YFM�Y”ˆ °ZhETœÖ¨Ì ˜b•™J¥Š4MÓ‚ ªªR$;*—Ë(‹Ø´iz{{'"„*ôù|H§ÓVYà½dµJÿ€€~2 Áív¨Xî¦Ói+3"ß§¥¥‡Âc�=†h4Š®®.82@F>vìØ_NŸ>=Žú*d•¶LÏ­·Þê]¸p¡3 “ÉL[F©þÌä`fY–Êív÷Pµ×0Œ#¨ø?U{Šš˜˜(ƒA €‹€šã8fõêÕž5kÖxn¿ýöòÐÐP¹¿¿¿<<<¬Ž��k‘HD-‹¢a%¯×+655•»ºº˜¶¶6®««ë¬ÎÎÎP(ò±,ë¨÷]ª­§ký9ÓKñx‘HÉdÒÒJÐ4�ŠF£ L5ÁB8fˆ¶€düv@;ÑêºN3 Cišf(ŠbóLÚíÀ0 fš pÖ¿øEþª«®òú|>躎D"aeà$F �N# ÂçóAÓ4ÄãqÄãq”J%Œ��cß¾} BD�ÕÔ¼=ð“nAàóù …ÐÕÕ…eË–!`þüùV !qv$“‰Ã#™BÑ �Ù8üµl¤u‘a¤Ói8�NJ–å%EQ†aÔ¢ÿë½Ï­9pf/BC΢  Û(d{ö_- $sâí­�ä¿Oš”äGÌ÷j*×H&“y]× �ÇãÉd29ÈhÒ�7bÅŠ–9ŠýPhnnF¹\¶”ÖvêrÖè§Cð·äp$A”nº®C’$kÚ¡MIO0ÄÿøGlÙ²4M㬳βT亮ËGŽyëè8�Œ8 IDATÑ£'QÛ쇬€Î;î¸Ãý±�}ÌGWµ„`Ó2ÀÉår�¦iȲ Žãæó<ïE1…w�Õ½ûÆÀÀ@Æét6êºî ßY–e,\¸ÐR™ÛâBçõz�}}}Î+V€¡ëºaj X¥(Š¢íæAÕ÷’t{ëY=Ÿ{Rž Yéøø8ÆÇÇ-Ç<¬Á»m¯“ΦÎÎN¶P(XîµjåäšöÇ”Ãá 4M£TU5dYÖA Éž1 Ãz$I"¯^ÔsXÚÑÑáùìg?ôù| ©ç‹¢Ã0P*•‰D011�x<Žd2‰t:m¹Kf³Yk¼²¹Ïêî‹Ùî}r] ðõù|hkkÃâÅ‹±lÙ2,^¼---ðù|ð©·ˆFÈDÞ/@®±½…Ñáp •J!›Í‚¦éž¶¶6vttT™!óŸ þsàƒ³4M«U¨¦tUö_KPp@ *þóLu)À0 ¤Óé¢aðz½^‚ðÉ\÷\.‡H$‚�~ô£Vº8�Nø|>ȲŒB¡€b±h©­ßÏáe$ï Ø3"2¼†P›º®O2xÑ4Íú¬Š¢ @×u<ù䓨¾};Âá0:::P.—Iª:tèÈþýûûÍë¬×Éþ]===ÞÍ›7|>å÷ûëRÿ3±äðeY¢(‚eYOsssppp0�Š m*FCö®J’$ebb"OÓ´Õ2H¨ÿ³Î: ÇÕeclÁ‡ûiïW­LÞnFCþl­àÏ0 �|>2™ ¢Ñ(FFF‰DìÙ¹T*�ÛÎ%�=tvv:dY¶‚Jõg$jw¸L¥?œeyb�ÏMö é@0m´¥:”s'€–Ûn»� ƒŤ~>>>ŽÃ‡ãøñã·†  «Å´:h“š¼ý�”nì‚?"$à�¼ì“IvŸN§144„Ý»wƒã8„B!tww㢋.š5k°`Áø|¾i÷£Çã±ÊQ䳿ŸÁ@vQ"ù~¤ôÃó|Èï÷³£££õ€™�CÃq%Ëò\I`| ʦ÷¨Ò¶ _‹ (xǸŵÀ‡az:�.˜ À#IEliIöàà ®¼òJtvvN¢�íƒLˆñHSSDQ´ÆØ)Ë÷šÑ̤!¨>0I6A2fòwUU�äão?0E˲hkkÃ;#§žz Éd«V­Bww7R©™þ'ïܹóø¾}ûö¡ÒmQ/ø@#MÓóxà�POOëõz'e²ö€8Ó!É0Œ%”²giMMM­ƒƒƒqT†E¥õ“©.D£Ñ"ÇqN‚=X”J%,_¾Üê ¯¾Öï|ÙëÐÕf3öÀ_Í€±,‹¦¦&—¼x<Ž�� "‘HØ÷ÂÉl6›³íoëlZ¼x1ÝÓÓÃŽ��YÙ¿ýÚÚË[¤N˜ûçp:�–8”ÌE  Öì@H×ï>‹yžgÏ=÷Ü@*•¢ˆ™V>ŸÇþýûñú믣¿¿±XÌ$E®˲PµVböCÓ´µ¿4MÓUU54M3ì½ûæse™‡‘R‘ªª³ö‡ˆx‹Å"ŠÅ"FGG±{÷nøý~ôööbýúõ¸ôÒKÑÞÞ>HUß³ZÝA³i½%?#à†|W ¢—0 CƒÍ¨hLꙤ¡F)`®þ?Îìåt:íŠàj1`=€Bm_ÓûШèþ‚Š|+Þí.˜ôLf2™¢ªªj  ˆè¨P( “É`ll 6lÀùçŸ¯× ³} †aX*90ˆp�å�€CTÕvUqµOøtÁÅ."´& ��E¡oíÉu]Gkk+‰~ò“Ÿ`ÇŽhiiÁ�wÞ‰`0ˆÁÁAÒîWÚºuë@ÿ~T —êy�&¼ø _øBhÕªU< l„ú/l¡I‰ö‚¨¿u]‡ÇãéFÅøI0df¡óPeîc†1::šå8Ωë:K˜rÍ,X€†††)‚±Ù» Ïôëþê{ÌqÂá°µoJ¥>Œ“'ObttÔî—o‹ÅC¶¿ÏØÁÎW\AÓ4M“ö=; ‚7I’¬ H~f2rD8G€eYd³Y$“IâùOJ!©êªžÉ®¹?ùÉOºÛÚÚ82 )‰`÷îÝØ¾};NŸ>m=ó4M[5zò2[= º$IeQ•D"¡ #“Éh’$Q²,#ŸÏ„¹ªîž iš2Ë” f(žçi—ËEñ<ïà8Žñù|¬at¹\¦ˆ �€¢X,†T*…#GŽàÙgŸÅyç�‡�}ìcèëë³ÀYõ"m¤K£VI`º¡@ö¶DÂn‹EÐ4Íð<FÅA²–p®0>˜«ª52Šêà_�Ч þÕl@ÀŸ\b ö¥  …‚T.—“ ~–eYI’011aMˆÇ[o½…Ë.» Ë—/GCCƒÕhW6ÚÚÞZDjÎöéƒ$ › +`üÕ‡ ìÅbÑ:ì«3${ ¢iÁ`Š¢àé§ŸÆÖ­[ŸùÌgðápàÀÐ4mÄãñÂ3Ï<=yòäaTÆ×N7€„лqãÆöO~ò“�ÇCù|>D£ÑI‡õl¿/ ʤgÛÌ¡ë:Ünw˜çyG©TRM�·Ï¼¿\u)@Ó4mtt4ÝÞÞÞ iC® ÑÌŸ?MMM–qÎLl öäж~r­IͽV?»9­~¿ðèïïÇž={pôèQd2ûŸ?™L&S¶çƳý‘a\~ù圢(SÔÿ„"'@–0Söl€át:馦&Ê^>J§ÓˆÅbÈf³Ð4 Ã(æàûs0/3—\r‰WE$“I ã�7ÞÀž={�Íf§dÎ���Á (ª,IRyppPŽD"Z"‘0òù<¥ª*eÛ#õ²ÚIÚ 2DÉFw“3óù¡¼^/ AXAX·ÛÍȲL•&“A.—Ãðð0vìØ�U«Vášk®ÁÊ•+-¶È¾GÝn7hš¶feL×T‹% ¥ Þ‰™¢¨ð ôÿ\ðŸ7Ô?5M)`:€®QÐꔢ^Ge MªTÔäs”Ëe5‹e<ǹt]§òùc2.TÜ$¡ë:òùŸ¯ìõz= Ã0d|g.—C,ÃéÓ§ñúë¯cÅŠøÐ‡>„%K– µµuR¦Ej¯ÕÎ^»·×ÿj-Rì.Ø3Íê cPÄæØ0 Äãq¼öÚkøÓŸþ]×qÍ5×`ýúõèììœ4–ubbBúÙÏ~–ûå/™EÅYqïN%«¦üÉ�À²¯|å+­===,ñ~·S¿ä€› ЩVq“ëDjE¹Ü•^FBKk›¥ž¶*pi Òé´HÓ4í÷ûýš¦Q„ ·¿-KÚzCcȵ�ép'ïd´215RU¹\ªªÂï÷#�Nã¹çžÃÎ�;qüøq»…¡ëúÞt:mŸ¶Gh %€«®ºŠÁ‘H$j–1ˆ°Œ(òËå2©ñk|êSŸr’2˲V‚,ËV_¾,˧DQ”m÷¼@ EQÔâÅ‹=###ÔÉ“'ñÎ;ï`ttÔž™ëŠ¢È²,Ë‘H¤\.—ÕÁl6³Bf rÓÑJ5Í�dY6âñ¸@¥(Jòù|¬ËåâœN'KÓ4­iš5ibbÄe—]†�|ä#èè蘴7H™`6 À^γ3IDš õkÿõ\çtsàÌ_…Ba¦žªÊþ«»jͨ'¬~%ì°•5Ž:Ù„žËåJ¢(*�@ÀÍóù$¶nÝŠcÇŽYºYj8=22r¸êÐçPé¹Ç5×\C]}õÕ>Rw¯^ÄÊ— ÁÇq±�éâÅ‹9"d±:It]/���²ÝsÀ"ÎóÏ?ß-Š"{ôèQ:tˆèbtEQÊ¥RIEQVUÕ˜a ªh{“'áUû…TO µû"гÔäGÊ@6›-g³Y…eYÚëõrn·ÛÅ0 ].—‹ÅP(‹Å°oß>\yå•¸à‚ &•xžEQ“hÍ´OÀµ?‡²,£\.1ó´Ô9C 9ð½°ǤL§Fö_«$ W•j��zí�vp�FÅiK5A€«Þ¤ªªšL&ó<ÏË>ŸO ©Q‹¢h1{öìÁóÏ?� `ÕªUX´hZ[[ÑÒÒUU­Ú|-g´é½Ÿ‘écv¹\–˜é­·ÞŸÿügœŸÏ±bÅ ~ÕªUîp8ìnjjæÍ›Ç±,Ësçq¹\œÇãaA m†aºjÅbQÉçór¹\.I’¤���åÇÇǵC‡a×®]l$áL…™ PEK$¢Óé”�ïr¹œŠ¢P‘HÄb÷FGGqÅW`ùòåV71t"gƒ}ßÛé—Ë…R©4¥kÄÜC¦oý›Íp ¹5>Ð,@=1 ]‡¨Z™ÿ­·ÞºòöÛog¿úÕ¯¾µsçNR‡,¡2>XFE(Ô '¡éb±XEQÁ)ï4ç°’º0©ç“RA2™´�Ëå‚ÇãA @SSzzz,ÿ·Û�yóæYckí4.±„-•JE™L–&Á0 ´´´ ££·Ýv-Z„îînT:'¯r¹lÄb1m×®]ÒOO±XD"‘Àøø8âñ8 …4M˲F$‘ Ã@ww76mÚä"m¤8|ø0 …§Z&“ygdd$cûõ &†a¨C‡ÅGFFʺ®× úй¯b¶ O´$Tcc#³dÉ×’%K/^joouuu…ü~?ï÷û]ÇQ ÃPÄ’|7{‡HÕâíe¦r¹l”Ëe£X,*Ñh´800�óÍ73Û·ogß~ûmÎd ªé”Öär¹¬Æãñ‚×ëuú|>Mö9aóù<Ö®]k�t�Ç3­ÿD@Jžò; ÃpÔÈðçZçÀ? €€÷2-�þÕ¯~µû{ßûÞ7{ì±Ö[o½õùÝ»wÐPFÅN¶ `!Leó´…ÊJ}[. 2˲ŸÏçr¹\.†a’Å“ îr¹,ƒb…›ÏçqêÔ)¼ñÆSòµ,\I $jøP(„žž¬]»===èééAcccÍ€O~G6›Õ÷ï߯¼ð ¥G}TJ¥R†­Öš@ÅL'1åo:^¯Wøú׿¾qÆ ín·~¿‰DšDWüß/ý_]'%õq3ÃòÔ+K˜ÁæMó^¶¡Æ *bU.—Õ`0"½ôD?::Š��>|{öìÁ‚ °råJôôôX4>ù¬6ãšI÷�ÐŇÂþðìÞ½‘HÄêñ¯b:�Þ#Ëòp�Ã}Þu×]çûÖ·¾��D"5�•$IH¥RÁéÓ§‹Å I©Q˧OŸ. >ýéO;V®\ét»ÝPU;wîÄØØ˜<³Ùì±ìÇäÚÿ|“bG6›Uìm~æŸ+›A?aþœ¹Ç¬šýæÍ›k×®m]¾|yG{{{¸±±‘�¶Oú#½þÄn›dÇv›àê½Bî ®N§“r»ÝT àÚÚÚ¸¾¾¾ÐÆ��Ûo¿½ðöÛoÇ·lÙ’~á…]×Ô&ÂÆ¹\NEQmll8Žs’¹„ñÉårX¿~½â °uk�g¤Zc 4¦oœËþçÀß P¯0›Ž€j&`RIà‘GÉ|îsŸ{uÁ‚7=ôÐCm¿ùÍožùÞ÷¾³=Lcæ¡5‚Ê$Á¦Tá”Úš¢(j2™,PUt¹\¬ œi8ÆA«ªjyñ»\.K\F;û!@Üü8ŽÏó–aJcc#æÍ›‡P(„p8lµÚk‡5Š‘J¥´��å÷¿ÿ½ôúë¯+ÐLa¹~9üŒ˜,ˆ>Mà·ÄË/¿¼ù3ŸùÌeK–, “Ï‹ÅÀúNvJó¯ñL·;UjºlÕ祪@@À[æè°Õ‚'1ÅbQ’e9 …ǹ(Š¢dYF<G*•Âðð0¼^/öîÝ‹—_~Ù4ÓÚÚ ¿ß�†††I�étˆÇã©S§�F-3({ià rZ±X,d2™£†a U}²÷ßïÝwßÝÄó¼3�BUÕ)€±\.#‘HàôéÓ8qↆ†�ÉdÀ0 Z[[µñññˆ¦i®o¼‘ºûî»}DBzßMwH#�NîÙ³çUY–UÛõ ¢b¦U½dTĵóí÷¡¯¯Ï³~ýú†µk×¶�uÖY :::¼�‡!™½Ý®7•JM2Nz/À±ºb·’&n’~¿Ÿòù|Þžžï† ÔþþþÔ¶mÛ2�=ö=>>.Øžùš@@UU-�æC¡/ŸÍf©ê2ÞE]„ææf°,k�U¶—òÈ~6Y”)ÏŠÍ4Š®“ùÏz6@=‘ñÜšg" `Ô©Íu»JXÇTÕð$Qà÷¿ÿýí_ÿú×/ ‡ÃËn¾ùæ¶ÆÆÆgøÃ˜˜˜ %RO£2`¦ÓV0fbJ¥R¹T*•iš¦œN'ã÷û>Ÿ�Õ4�¥(Ê¡ë:Eï�@O²z¢t'V¾�^¯~¿^¯×¤D Gˆºœd’$étZÓöìÙ#ïÚµKy饗T³Í©ºF^6Ï yÔîïŸ(Š¢6oÞÜyÛm·]ÖÝÝ އ©TjJ𯶾}¯Ã�ìm€Ä´§:SRÅár¹XI’äi@@Üdx“º6j€¨ªªÅãñ”×ëå½^¯�a9ÔI�–08Ä®—Üwûn·Ýµ×‰c£}º¡ªªF$‘âñxA–å*s ”êkáñxØ|på�7ÞØÁ²,�F-¡Ú#‚ˆÓNœ8�“'O"‹�çy,_¾Á`0ºmÛ6™¦i×g?ûYOSS“ÓÎT�Ëx<~zß¾}*•JJÕušG²Û>J â¿�4�€âyž^·n]Ãe—]vÖš5k´··û›ššhâ^IÚm“§ÜûéöEõ³Wï™$í�ù|Þêjðz½p¹\hiiq�poooãE]ê©§bO?ý´;ŸÏ ¨íB˜##™LŠŠ¢h~¿ß“Ïç©h4jéT(ŠÂš5kÐÕÕ·ÛmaSÜi±yU¥ŸIÆQº®k3”fÓ8·æÀ™¿ª½ËëÅØ:%€Zl@€õö Ò'®Оxâ‰ìæÍ›·-]ºôS‚ ®ºêª[/^|äg?ûÙï_xá…¬í�Ê£2NxÀ, tÂf¾2#`>è†$I†$Ij4•Óá÷ûéÖÖV–çyFÆÌ‚hY–)–e)–eQ*•¨\.g±f)ÁàyžÌ'7 ÃP†1hšÖ´Ý»w«Û¶mÓ‰„^HÙƒx À°ü3˜:ͯ®à/ 1ŸÿüçW\}õÕñù|2R8‰Xôk5ío·¿}¯û$ó�Ôû'Zó�6@ S…\öÃ1ƒÊLˆuæÞ¨uï(“æ-åóyÉï÷»Ýn·Çáp8È4;¢E =ýÕ¢Àê F2=;Û¢(j£££â�J###º 8�¡2caÒ}»á†Üÿò/ÿrÑÙgŸÝAìyk1fªªZÀäðáÃ8pà‰V¬X�K/½«W¯.ßwß}#…B¡í{ßû¿nݺI¶v¦†DñҶnݺMUÕbÕ^àQ¬¥™×“ì£IÙþÂ… ]W\qE×úõëW-\¸°ÅëõR>Ÿ^¯×ÈCf Ô îÕËv{åzÁ¿…>åL!8…BÇ!€çy´··Ó‚ 4ÏŸ?¿éšk®ýùÏ>úÜsÏ5šßõ€@.—“5MÓC¡�7ŸÏÓÑhÔbæÈçhooÏóÄÝÏú~vö®Ö #s/ÌÖ€šéLš[sàŒ],ËÖT2OS@�ào§¶{Ì,þE3³ÒèÿùŸÿùÚw¿ûÝ«ý~�¦iª··wÙ¿ýÛ¿u-\¸ðÙ‡zè önó.eÌ{œ6kŸ³SBUU©d2©'“IÙNo3 c¯{2]�d ÃXâBY–¡ª*UlÔð–ŸŽ=) â—?a^›Y~˜?¾ûþûïßxÎ9ç,dY–öûýÐu‘HÄ23ªþõf¦ÏØ•ÒÕô¿Íf—6'Úu¾?MQ” …Ød2°À¹¨L¤ëÝ7Ã0�Édй\®äv»9�Çãæ8Ž“e™"›¢(Ö·ÛmQÌö�L^¯×z™½÷ò®]»Ä?ÿùÏÒàà `CÌ–ìÎX† Ô¿þë¿¶ßqǸ\./Qž× œªªbbb'OžÄÁƒqäÈ‚€Ï|æ3¸úê«ÑÔÔ¤ÿú׿Þ÷â‹/º>ñ‰Op·Ür‹·Ú|*—ËiþóŸ'ž{î¹w Ã( ¶¶"ŽŠPtܤý-°ÕÛÛë¹õÖ[W¬_¿~y8öšõwƒA”J%LLLL@dŸ¡PËV¹Öž¨Zö@_Ë$«–ÏdÌ�FÁq‚Á B¡A 9Žëìêêj:ï¼óN~ûÛß.ȲÜXA&6 IDATÅNÅb±¬ëz.û …�H$¬}@´ ¨zæ­ç…Ì ±gÿæTB}À¹5þ~VÕ|€ZÚtVÁµ^y»|ÀMv¡â¨½úê«…}ûöýqùò囃Á qÊóÜpà Ÿ\¹råºgžyæÅçŸ~\›ìâ‘4êQ•‘ á}õàVQÙÕΈõ‚úl®™tÊ ú13£Ðf¸n“~7Ïóô=÷ܳlÓ¦M577ûB¡�5ê•ô¼“ ˜dõ‚ÿLœý�´ ¥uZ=úÕ¨¬ZºË:Ú0 üä'?Ù800ûÖ·¾u¨X,î0³ÖÅfy¨îýÒu]/ ¥B¡ 9Úãñ°�‡UUÕ©i£( c–¡È¡ošþE©‡C/—Ë’$IÊÞ½{µÁÁAÊD¼,ÆM–‰Ü|ÃårQW]uUó�wÞyîÂ… Ê¢ÐÄ?¢ÖµE###8zô(úûûQ*•°yóflÚ´ mmCÄ^xáà=÷Ü“îëë[þµ¯}ÍßÔÔdXI’Œ;v”î¿ÿþôÎ�;�†1V ¼ciš¦6nܾþúë×ôõõõŽ´«úý~H’„ñññIe ìí/B�kl»/>)¥TgõõÚek•�ª]3«�@$Ïó…Bhoo‡ üµ×^»lÙ²e?üá‡_}õÕ0*þµÎ#”J%%‘Hä†ñåóy:�[€Ì—ðx<Ösb-NJFÄÒÛÖ9�©‘áÏ ÿæÀ?ÔªÅLìlÀA˜ÙÞ…æ¼ @^ÚÞÐÐp±¦ióB¡1r¡—-[ÖÝÔÔtÛ\pð׿þõöýû÷‹¶Œ‹‹¢T}šÍ—•þâz�ø¢åì×C3[ÂÌÔòæ¡­Î�íO þ4MS—\rI讻··w>Ïóbc›N§¡ªê¤ñ±$ó'ÁÿýŠþªqÒWMóêLÉ0 C¯ücµØ ‹–VUÕ½iÓ¦!xß}÷íÈd2o›×f9*�)ÂÀêwUUµL&£g2™¦iÊápP‚ Ð�‡&ô>t*Šbär9-“ÉfÖ[ `e“‘�Ùréóùè+¯¼²õšk®YÜÛÛÛæóùØé€”¢(ˆÇã8uêP(pÁ`Æ hoo˲ÐuÝxýõ×O~ãß8®iÚ’oûÛÁ+V8@–eãÀ�å-[¶}ôÑR*•2™2 µ[@ Û}¡6nÜ8ïæ›o>···w¾ßïç @”D§`÷r ïÄ8‰\7¤I;%ÉŒkM̬ê�ì™À(Rår^¯¡P<ÏÓǵÝÿýž¾¾¾ã?ü°O×õ@�½“ PR©TÁétz …•H$0::Š@ â�AæL�}ML¢dY¶€M7Sœá<¦ï˜+Ì€β™ Ô þT�ìw:@Ge p»yךe�7ž~úéþ�üã*—Ë7Åb1„ÃaÐ4 ŽãÐÜÜÌ ‚°vÑ¢E}ÜÿÔSO½qüøq{=”t”Í û„D|¨¨¤ƒ¨øÑ;fØ?ïwè Éð5ó�(˜Ÿ#c}¹êàÖgø“‚ÿâÅ‹ý÷Þ{ïçž{î2¯×˱,‹`0I’�L&-C"BË:Þ>�h¶uþº¦J(åp8,¦Ä>É0 ­T*ÉÓ°ŠaÖétrùÈG.{衇¾úÕ¯>;66¶ßrKL�Ècf?yÃ;F¹\¦Ê岞N§gs/Éï-£¢”&¥˜¦¦&ç-·ÜÒs饗.éèèhp:�Ôt�MQD"Ë®W×u¬]»ëÖ­CCCƒuÍE1^|ñÅÁOúÓI¥R½�<òHÇW\á.‹ÆîÝ»å_þò—…§žzJ.—Ë*� ‡ÌÏW-µ®+EQ¸æškÚo¾ùæ�uÖY]<Ï3Dÿ iR©Ô¤ÀO<ˆ’çùIô7a¿ì¿ºŽoWÑ×¢ó§ÛGïeïŽ|>oùtø|>ÿm·ÝvöÊ•+�ßqÇcxw¤ø”g3“ÉHN§“â8ΛÏç�Fáñx¬9gTUµ„�dL³�0ýâÓ쫹ìü}-Bõ¾‡Œw¦2&ifé**ðË ÃèüùÏ~øñÇ�E"‘p"‘@SS“%fóz½p8ü…^x^__ß²ƒxñÅ÷îÚµ+[õo¶A1KãæžáMF PõN£bæâ˜ÅƒL2EÕð3æÏòf¶/Ùm} IÍàOÓ4µvíZÿM7Ý´võêÕK}>ŸÀ0 ü~¿5–dýÄÁЮ^&—ý &ïï Øíumtü$šÔ•åŠÄÚþ݈õ«À išæ8Ž5÷uî¹çžûàƒrßüæ7ÿ»¿¿?j^Ó¨¸v˜÷‡FíV¼÷“]æg‰™Æëõââ‹/nذaCϪU«ºÃá°—eÙºˆˆ×ÆÇÇqúôi$ ƒAlܸK—.E ˜dŒ#Š¢þè£�}ÿûßß�J¥ï»ï¾ÞuëÖ¹·lÙRxöÙgÅW^yE1} ʨˆ0ÕüÉz9|ò“Ÿl¾âŠ+Ö.]ºt‘ NBÕû|>¸\.är9ØgØ'a’ÏF,‰F¤z\µýÏ6ËŸ-›d߃3íE¢©…Bhll„×ëe[[[—¾öÚkwÞyçØ‰'Z1µE�ÇK.—‹q:�î|>�X,¯×‹@ —Ë¿ß�\.Gº@&•9Ⱦ6?w¶*ËŸIø7 æÀwU=”Æ{Üе`†™ïp¹í�uX½uëÖŽ�;wž¾úê«›¢Ñ(‰D,r¸•ËeŠã8ïúõë?Ô××·¼¿¿ÿèóÏ?x×®]1S#`¤®«šAšˆ¦hLö$çQ1§¡ë<Üö`.Ù€^‡ÎÇ,J$µþ †Á‡>ô¡æO|â}}}}‹}E�çyx½^ˆ¢ˆl6keýĤ…d{0®ÞÞOÉþíFQ”)YEQJ�ï7ÀRó¾§M±kcš¨… öÝ}÷ÝŽûï¿ÿ—ÙlV6™€*Âí&#à6ÿU§D0PM –§(*ÛÛÛË]{íµg]xá…Ý---aŸÏç¬g+¬ë: …&&&0<<Œ±±1ȲŒÖÖVüó?ÿ3zzz¦Ìt0 §OŸ.?òÈ#Éï~÷»{ ÃPôŒ��1÷ÜsOrûöíªíZåÌà?b~Ö)�Ÿ¦iãŸþ韄[o½õÜùóç¯r»ÝnÒËNÄs†a ™LNé7¯5–ÚÞºXK¤÷~ý{v`:Ý^$Š---‡ÃTSSÓ‚ßüæ7C›7oŽœ8q¢¥Æ³k˜CµŠ�‡u¹\l6›E,Ãèè(ü~?X–%–&ù�½M´-Š¢$ç2ÿ9𳪄€õ‚<5‹Œ¶šØ�Êä¿f{ÅÁ0Œy_ûÚר¥K——.]êill´úÙK¥’•ñ’çr¹üóæÍ;ÿœsÎ9wppðÔ¡C‡>÷Üs#ÄU Ó·ì(¶ÿ]x²1‹÷™À€EËöôôx>ñ‰Ot/[¶lñ‚ z¼^¯ƒ¢(‹ªÔu±XÌ:èí*;å_•±¼çC¸úð%ÿMZ í«ÖAÉ0L¾¤ÍROÀ_ü~²P(ðÄK¨Ô°»»»—Þ{ï½×oÙ²å¿�?^2ÁÖ€(*®ˆAT„ž ¨Ì‰pá]�G-ûXÕü¢É*¤GaéÒ¥®�76¯Zµêìùóçw644pµ®1‘ÉårˆÇã8~ü8FFF Š"Ün7/^Œ‹/¾K—.ÇqS®k4ÕvìØQ¼ë®»R©TŠ0_«øüqÙö9%“ò?e”šYÿºuë¸ÿ÷_½zõê5.—Ë›Ëå¬òÇqù|ñx|’�-¹�¤–ý^úöÿ7W­2B58e¢(bxx---à8Ž:ûì³»ûÛßÒ×]w]äÔ©Sͨ1}°\.냃ƒYŸÏ× Š"•N§�F Áó<šššàt:- IÒ$EQz:�›‹ sàyUwÌêý<‰JOÿǪi»'Nà·¿ýmê«_ýª›çyº­­Í¢µIÀ!­wår²,ƒã8G X´lÙ²7nÌ=zôؾ}ûN½ñÆñ±±1EQÓûw¿W%¯ñË Sþ?·ÛMÏŸ?ßµ~ýúygŸ}ö¢žžžžP(ägY–&T» V Ô0 «��(³I–Ov„ÿÖ1a`ˆ§:¡dEQœÌÌ1VgÏP&àû¨Ëåz§T*y$I²ÙDˆÕÓÓ³|óæÍú“O>ù»Ó§O˶̽`ò ó àLæF¨ÁÞ )ÆÆï÷S›7oî]¹råš Ìkllt;�N€5’п$ˆF£Q abb…B.— �@mmmX³f 6lد×;) ªªŠL&£½óÎ;Òý×åŸ{î¹’aÇPÑ,2Lµþ`Ð9j-°ØÞÞÎ|îsŸë¸ñÆ/èîîžoNÞ›4LJ×u¤R)d2kÔ ¨ÕÙö}àÔ§ Ã@–eœ‹ÅF÷ïß?öÊ+¯ �:u*¯ªªŽ™ûxß °©åË?%øSE5448ûúú—]vY{wwwKCCCK8Øm‡I??q�#ŽãàñxÀó<<\hjjâ\.›Ëå,íq"$à¢T*YŽˆ&£–’eY™æYŸ[sàïo»Û:,@­ ?›¬¨Ôwwš,À¤v½‰‰ Üwß}ÉÇÜ×ÚÚêTÅÊnÜn·Ey“ Iß„B!ëáE‘¡±«««ñœsÎYyà 7(ããã‘H$26111±wïÞt!�—‹Å¢Z£^NÍLùÎ4MS�‡ihhp.[¶Ì·hÑ"ï¼yóš[ZZÚ‚Á`¸µµÕÃ0 mWÕÛkù$ð0 c™×‚` ¹Éf³V9¤å?*õ½¬jc!’qf³Yˆ¢heK•ÎÈ×øNûõt»Ýn’y“îbâ£iÕÞÞ¾äÎ;ïüçG}tK<×l€SŸ¡´Só•Éd´‡~ø˲#áp¸S„•,ËUUeeYfÌ9æ%¢àõzÑÔÔ„@ ŸÏA ·Ûm¸Ýn€><<¬ ë'OžTvîÜ©lݺµÜß߯™ž*Ý P™äÐ�Šþ„tØíž§<# .äïºë®óÖ¬Ys® îH$bÍv( Öó�ljDP,Á0 A°f!àâ÷û,ºÛ®q Ö¼ªªB–e«¥óL( Ì´œN'TUÅáDZtéRø|>¬_¿¾÷»ßýîÑn¸¡hÏIϪ®ëÆððp>K¥EœC¡�5D’$ Øf‹¦é´Ù�Q³Œ7 æÀ?r9  0]VL^o¡"[XýKÞxã ãG?úQtݺuíår™Êçó iÍÍÍhkk³wº.•JÁN�77Wäf–J1 ã\¸paçÂ… ;u]Çå—_.—J%qbb"›Ïç3Ñh4�Fóããã…|>_(•J²$IF©TÒE14M3HÐæ8Žv»Ý”Ûí¦�N§Ãëõz{zz ,ps …BM���^§Ó)¸\.Ö®&'t7a0(ŠB±X´FÈ:ËÉŽd%4MC’$k~¼=ðÏ–ò¿ö¿ÚÕÿ@¥þo².V�8MÓZ©TJÔ(©LªÉ677³.—‹"¢E~<�Õ6—ÏçÑÓӳꦛnJ=ñįؘ€Ùø°Û_Œ @üºEió˜Á7EQEÓ4íp8h‡ÃÁ8Çq´Óé4 …‚¡iš‘N§UUUUMÓtŠ¢èR©dœ:uJ¯c¥™tþ¼;ÉÑ�JKß„Y’ÐgÈÁ`�Ó4�;pà@žã8‡¢(l&“¡¢Ñ(b±"‘R©J¥’uO‰˜�2°ª­­ g�u,X0‰Å©^är9 ÔÒ…œI‹çy(Š‚ƒâì³Ï† ÔÕW_Ý{ÿý÷÷ó›ßä0µ3ÀˆÇãr*•’Ýn·‹ˆj3™ ššš¬gÍÎl™¬Ê°ñÞQјÿ@À˜%®þqìBEÐ5imÙ²¥èt: �@À+IDQD¡PÃ0Öd/ûÒu�ØòZ™«ÏçC8¶À¡öçõz¹p8¬þ&oȲ¬K’¤iš¦™îvEQ”Ãá`\.—ÃívÓ$+®Pí#Q9ŽƒËå²Ôפ��°d � 80i@‹]èWÃvø}Q©Õnµè‡Ãa1d% d2 H’]×áp8Šš¦‰¶€L<&©[ZZœ<Ïç:‚€@ Š¢ÐÔÔ„±±1ŒŒŒ �NSK—.Ýpã�7f~øá¿Øàéùo*3ZÍ÷ Þí °ö¢a†¦i:ј�E²íKŸæ9ȡҾxïz?•–¾é¡ÕïŽÝ»w;wïÞ­˜ÏHqÙ²ežç]’$yóù¼Ó6šÖZŠ¢@E$ C„B!455¡¿¿Ùl^xaÝÕ¤MÐív#—Ë!ŸÏÛ)ð¿šIúŸX„­‘e»víÂyç��Çã¼çž{º^|ñÅ�Ý»w7Wßs]×õ¡¡¡Ü¼yó8Y–©|>o•}J¥Ò¤*¦SC3œuF=Vpü�Yé¹Kð¿·X–¥lYæLµVR£¥ªÞÉ‹©úß4*uÜ0*­b“~_>Ÿ§ Ã�š››Åb‘"b8L«iéZAލ¸óù<Êå²Ug'/A,×3û¨[†a(ŽãhA¯×Ëz½^§ùÎ ‚ÀpGÙ‡£�!3<Ï[5E2œÇ>›œXö2 Žãàv»­Þf2…¦i”Ëe¤Óid2ë " þëC¸Vë¹^v`¶¶aÏž=µÀ MÓÑHdWU¦D£Rû¶:>.½ôRÿüùó9"¨ ‡Ã�$ ù|,ËZYk¡P@¹\¦|>ßš¦Oö÷÷§0Õ¯ÞÔÉÅ>dþ»j�‘žmÙg&œCÅßb*¾J�ÏWoFFõÄG*Y+MÐB âñ¸1>>®Äãñbþÿ³÷æArÜåùøÓÝÓ3ÝsŸ;{º,Ù:­Ë¶lll‚1â2ÅQB1•Tø%ä��¢R©¤Š$Tb*1•T B¸æ`,0>°%ÙÖ-K«cW{Î}}÷ï�éO«§Õ3;+­ ó©šÚC«™žžîÏû¼Ïû¾ÏS­Ö$I4MS ÅP¶‹AÓ4‚€R©„|>�T*…sçÎáÕW_Ã0¸fªÃT9ŽÇqmB@N׊õÿü_‚†aP«Õ0??�D"�h4êÙµk—ôïÿþïM£ÄØ �†‹ÅÜ~¿Ÿ% š~¿�D0haaårº®K Ãü X,¦Ð®BN6è=yzôWüV/Žã(2+¼ Úu%`D.÷V\­›�ååe=�Ò.—‹¯T*�eÙ ´Ä²×š½Z�=ìY-Ñø®Õj¨T*mB)D�ÔP‰[ÚJ¢-NŽ…ØœV«UóùeY6™žç ‰D‹Å‹ÅL?"J²R[·ÛØ®´®1D$i Š¢à…^À™3g°°°€jµJ‚ÁÑb±8kÛèX#›LË{Þóžèàà kݺuH&“æFKšK¥4MÃæÍ›I9À•L&o«T*Ççççëèn9M~W2®+íSk‘�)Æs/Zÿ¢�Þ×Vve?Þ8Ow`˜éLŒº½Òl6ÅZ­V¯ÕjUY–EEQ´ñ ¬ŸW½^G>ŸÇÜÜ^~ùeœ8q¢("™L¶MwØK?Ä*˜°Ýl~ÿ/¹ß …à÷û155å§(*ýë_ÿÚãôÙW«Ue||ÜG\?‰8�¢(&‹R(@QT­Ñh|·V«U�ýJéüÕ>è—~(àZ=ý•šþœè2²Œ�t/lõbUUñÒK/•8EÑ%Ë2Òé4�€ÙjÕ!´zܸªIÙJök•¨J h)Á•Ñc­àª¯CO“ ¾-�£hZ¹:Ü3T§Ÿ5MÓêõºP¯×E†ah·ÛÍrçá8Žw¹\,Š¢ \.£V«!—ËáÕW_ÅÓO?�7½éM¸óÎ;Ûd‹Mú†¦À0Œ Òœ¬�»•–^ @@šHƒÁ 2™ Ž=ŠM›6¹î¸ãŽd$ɋŰýó­T*R©T’ü~¿GEó˜É¸-å Ãäs¹\ =yõ ªmIUõÀëPp®‹õò�Ñš˜46궬giiI=wî\nxxxPEd2ð<ß6o•Ã%�ÌDò”�nãq+i™[72ëÃî‘NÆI™‚è®[é.&�FNÞã7bÞ³V€À*=l]Ùl‹‹‹(‹f˲âòòò’Äájuë­·º#‘3::ŠZ­v ð²¾¶¢(8uê¶mÛF�[Þþö·?xòäÉoÃÙdÈ>TãÚª ÕyÏ�Ÿ3‚®W%¢­Ñ�LŸ|/Ûèún ]þÎþD´@‰XJ'à¸TU՚ͦÔl6%5·Ûíòûý<T—ËeT*,//ãøñãØ¸q#xà<øàƒˆF£ŽÁ•eYSa°W±©×°,‹P(„Z­†l6‹'NÀãñÄÿø�ÿ¸ðÅ/~Q2>ýê¡éúÂÂBuppÐmôö€ã8³g‚°^4M/(-ÔãhÄÔågÇD¨“ÒdõK¿uË@ªN×NÍW4:÷¬ô XëqÕÖ|är99�rš¦±Ö@’Y[ejÉfc ¢önÍØ­þ礊në÷Ö¯äAþ†ÔóIé€Â0Ôëu�f£Z­†z½~�’Éþ�ŽûffN]Ê?ˆÅbm@×u=zG�Åìì¬ÙpIQÔùB¡pÒa#L %€ã€w½ë]¡�;wò6l¸¦ÑŽØÄZAJ[¶lA¡P †ɼôÒK ¨VÇÑ:·Û –e5EQ$´æó+h�¢fÐêÎ_D«~¿düœP4˜Áþj*¿Óëk]ŽË®ŽY0@Ê Z®„´F uK ƒîPŠs*Íe¹^¯ ’$IÆ}cö Ȳ 2áœ?<Ï#™L^\I³ªÕ#àF€éÍ(�±e¢ë iåóù</^L Þ�K¥’¼aÃïàà 388ˆÝ»wchh.\Àìì,²Ù¬NQÔS…Bá¬ýß­Àþ¹›¯ër¹ÖD°«Ïô×o+Ћ�ÓÆyÀ6ì/ i.^¼˜wëºîÊçó¦8a¼^ï5¥ÒioöÖA§ Èž­8e/d##�ù‚ ´•ì_­Ê}VÍõ•2§›•=uÚ„ÉL¹}ÒB’$œ?¹\Î쟠(JWå²a±k~š‘Ѳ0æë7lØÀE"Ó¸ÈƬçƒdž¹\^¯û÷(ì¶mÛÞsÏ=çŸ}öÙ‚C†e¦:*à±Ç»ÿÕW_�ÿ·û·K™L†lÔÝ4€Þô Hó"E& Œ@K±,ˬ”Jœ’Éì½ :Fã¤UÁ0�–40‡–qU­fÙ$®J c…c´Þ?Z£Ñ�†èñxØ@ àå8Ž£iš¶j:”Ëe,,,àÀ�8xð Ö¯_ßv]°,‹h4jޝ¨½þÖŠ! ×­ßïG±XD±X˲�»ï¾ÛáÂW=(tº19Ôðù|nÒàñxÌ\ŸÏ'•J¥ èÍÌ è×ùûàwmÙl�í,+Y¯æQGË.xÀØôÚV¡P�8Ž+ Ä+•ŠéaNsHÃR§ŽekÀ±‚œvÖ Óædï-pÝþj7˵Vû³o„Nµ?÷ìì,fff�Ëå̱9†ajõz}Æ!ˆ2héö3�H$˜ÑÑQO4E½^¿æ½8�†apá„B!ìÞ½‚ ¿ýíoÇ™3g¾Z(” ÀjEåóyÍív{þðÿðÿ»ï¾ûfŽ?þÂã�?~üüùó ¬ÐCóàc�=¶î¡‡zëòò2+Š¢WUU7EQ.š¦M b|ö:Zceù6˜Ë IDATŠ  Y–ËŠ¢dY–òù|}yy9ŸÉdê'Ož¬]¾|¹’Ï纮7Ñš6Ja´Æ­= =3£¢(*¢(V\.W= yyžçhšfdYF&“iëxðÁqÿý÷# µ}&¤L°  @ÐëuN$«ƒÁ ¼^¯)’‹Å¢Ñè\¡P°Ç}~~¾Â²¬``ÀEJŠDš: ¦R©Ôœ:»�ö�@ün,–e¯qõ¾«}t¢DçÐj¼ÓiSK¥RU¯×ë§(Š+•Jðx<àyÞ”l%zÞ’$9ÒlV£«1Š�ï�JÝ6+{п™õϵVû³]b)KÎÉÎ_zé%,--™þƺd4IÙƒ/cd®ìرÃ�Fé`0ØöÿWn·>ŸgÏžÅÞ½{±sçNȲ¼÷ƒüà �=öØ™®=«×:t|óæÍ�ŒŒ¬˜ºí¶Ûî;qâį¿ÿýïŸxá…ê]²ª[öGŽYÞ»wo# n³³P]VÈâ&Ë¥(ЦišV«Õ„jµZ+‹Åååå¹l6››žžÎ?~¼véÒ¥Zª‚ç�ç Ì@Ô+�¥(ŠšÏçkn·[…B^�Çã¡iš®×ë¦éQ¡PÀÌÌ Þóž÷`ttÔdÍhšF(2{Vk@u½×y/×8Ñ­ V¡P€¦i¾­[·rÏ<óŒfc+1==­‚P�Åb!r�kšF`/e³ÙJ—ýJëø;„þº‘ý© ^cÄårQ¶`Ú�.íÖЩ/À:´º«×¡Õ¨Õözº®£^¯ >ŸÏ§ë:M2k¢‰D000�ÇÓ–u÷²ÑØ)zûÃ.¿K~goà[)Ë_ËNýµ~~B» €af¯×‹ååeüà?À«¯¾jº4Ò4­5�'ëõz×NˆøÑšggà£ýhì–[na­.�NL�ýø‰Æ‘AÞ¼y3hšf5MKœ>}ú…b±¨`åq+ýüùóÅ7¿ùÍ{�@ˆ¦i* 7nܸ}ß¾};7oÞÌ\¾|y¹T*‰=€Õk‚Á±cÇÄ'Nœa@UU³¤Û¹¶7”º\.ŠeYÚëõº#‘ˆhh(±iÓ¦ Û·oß¾wïÞÝozÓ›nyë[ß:2>>ÎW«U!›ÍÐêW ý #I"¬ÀJ †RUUk4’(Š’¡ˆèRU�FÕj¹\W®\�×ëmë .ˆ×lOrºNìà@³ß¦ÑhPE¹^}õÕŒ®ë{`jjJyë[ßòûýh6›8qâQ[üÑÅ‹/ Uû'{Ý5ZPUµúàõ³ŒàOuÉ®º5vÒ l�ßú=RYç°‰Qªªjš¦©�‡WU•²yžç166†ááa¸ÝîÎNì™üÍÊrnæ õjžßãñ ‘H˜ž ù|Þ-zúé§ñì³ÏbvvÖcbæJ6›=¢ªªâ��¡%óL²ùÈG"6l 4MëØýßéøI ]ZZ‚ÏçÃää$<Olpp°øóŸÿü²E|ˆ|�2 ´Œƒ4Q±cÇŽH<ßl•6öù|¾±±±-wÜqÇÞ]»v¹jµZzqq±‰•{YÚ®ñ……m~~þb ­Õj1¢Zi�P!vÎDoÂçó�çyÓö™|%¾ÄÌ8ŽcÂáp`hhhèöÛoßüð;zè¡M»wïæyž————Ë’$ÑjbÌ¢ÕìÈ`€îÂjP$05 Q×u•eYEQ´$I¨×ë¨×똛›ƒ$I7MœH¬$I¯9è|)Š2�kµ�t]÷är¹…J¥ÂÙY�¹¹9écûX8 Ñ…BÇŽC±X”Μ9óŸétº‚ö@e w(ô¼nµÂ¿õ¢Ø ØÙ -!—Q´F¢®¢(*,Ë2.—ËcÝxˆRàÐÐ�Ù dÍPÖ"€ÿ6ìµ|~Bý“&/23�Ëåð?ÿó?8}ú4ŠÅ"ùº$IO•J¥¬Ãu 5Ñ1?ü°ÿÀ�¾uëÖ¡X,^W4qjK¥R˜ššB"‘ ‰D¢R©¼|üøñ&ÚG´†Ñ2šš02â&q``€ …Bû�M@€EŽ™¾eûöí[GGG…B!—Ïçe@¡5²ºÅøJÀÆ-ËËË–––äx<Ð4�+‹�eÙœQ‡Ã¦÷<ɰI€²JЊ¢hö¬øý~ø|>sìÕPëc‚6l˜Ú¿ÿmÔDQ¬ …ªá̘15b¡L¯Ä ˆ¢¨‚ »Ýnša—¢(æ1‹EÔëu$“Iøý~³^N›Œ„E1U@‰u5MÓÍÙÙYÕ8ægÚl6©·¾õ­îh4ê¹té‘N^úñ�ü-\�é4ÐSæß}ðº]4MS¶»[`%™à^Æu´:¡ÇÑš×¾&si4’ÇãqSÅZéwUUÛèJ¿ßon¨7cƒ²w®ßL†àf=?±ãÃ0ÁÌþ#‘~üãã¹çžÃåË—Íàír¹ ‡lÒ¿$@òhMtøƒÁ ó‘�|$ºnÝ:W(B©Tº>j¼÷B¡EQ0<<Œh4S¾ò•¯œ²m²"€­hÕǧ &ÂU.—3£££;TUõ…Ãaë¬7É´)¯×X·nÝ®;vÜ s.\È˲lÝØÝîCK½r-íŠA´Cù|Þ»´´T»çž{|¬ËåÂàà ÆÇÇáõzQ*•Ìæ4"öäTŽ’e$'T¶ÁX ›öµsÃ$“Éð®]»6Ýu×]·mß¾=Ȳlcff¦¢iZ­&ªÁp] h¹æ5 ‘¢(Ýív³Š¢PD™²T*¡Z­bppÐleYö·‚°^+Ä.¹R©´±³³³ËªªÚ½Gôp8¬�Ð¥K—�J¥ôr¹üü+¯¼rÄø­%ÍøÞIÞ¹è¯>x}.b•zàzô$c#Ÿ22˜¶×0´þ%ŽãxŠ¢«IŽ,˦�+1œ±ŠîÜ,t§:öZ�í­õóí÷ááax<¨ªŠt: Y–�ÇqåÊ|÷»ßÅ™3g@ðŒìÿ§•J%oÛàÈÁÄÑ’¶uÝwß}žw¼ãáuëÖ™î�×sì$ó•e‹‹‹ÇqT0Œ///¿h°dÉh)ë%Œk‰0Q.—GyŽã"Š¢ ‰˜£Ž¤×À ë©`0Þ¼yóÞ={öŒ¦R©Ùååebt¤ ÕÚM¬Ì7S.—© 6ˆ�>úh`Û¶m4qš;sæ Ž;UUM¡*'%IkSªõ³'†?Õj¢(Âív#›Ù¸ØñññÁ;î¸cËž={†dY®ÎÍÍU5M«¢åTXÁU�¦n£�” Š¢(2ÇqnMÓ(âFÙl6Q.—‘L& Íc&ö¹¿ €HkÀÒl6!IS©Tæ+•Š×œK¥’<88èÏår®z½®,,,|óüùóó6Ћ€“ǃ~³|ô×k…ª©Ê+y´¯† [66ª!8ô¨ªªË²,»Ýn¯¦i”µ!O’$ÄãqƒAÐ4 ¿ßof\Nnz7ëæüm/x<Äãq„B!hš†t: ALÃo|ãxñű¼¼l¾Ã0ó‹‹‹Ï.‰º-û§ÑÒr¡(ŠþèG?Þ¼y³{ttétº§,¿ ]×MâÉÉI°,Ë,ÀÁ⪰¹}DZãããaY–AÓ4¢Ñ(Ün·YÏ6DƒÈëÑ‘Hdhÿþýw¯[·N›™™Y¬V«Š‘MçŒÌß ‡Ù‘#GT�Ç#8pÀ¯( õüóÏã©§žB.—k“…¶{«z¥ÓxªuiˆûÏóä¹èÁÁÁðwܱùž{î‡Ã�óçÏ—E©@ ‰V£&Û@–eMEÙãñ°º®ÓVÍ Aà÷û�F͆@+÷É­F@â­a€OJ–åL*•®N”éô|>¯®[·š¦�ÆòÑ£G¿Y(« þÝ©ú ^¿‹çyʦÞ-دÆ9Щ7Àú»¬‘QÆœžK–eÕh\âE¡¬ú¤i‰ø�L©×zåë•Òï¸ÝnÄãqÄãq@:�F­Vƒ¢(Á¯ýk<ñĘ™™1ÏMÓB­Vûa½ÅIÛéM+ýï»÷Þ{¹÷¿ÿý¡ÑÑQŠØ1_ÏFnÿYEÌÍÍa``¡Pˆ ÉÇš™™QÑ.¼ íÓ$p¹\ú¦M›‚Ç1�ápSSSH&“‡Ã‡Ã¦a¡´†q�ŽŽÞºwïÞ�º®_¹xñbY×u¢8 ›å19†gžyF.‹Í™™™ÀáÇ©‹/;jSÂÙ� ÞmôÔ©tCþ_³ÙD¥R$ svŸ¢(*‰ø·oß¾éÎ;ïS¥8;;[Ñ4­„V��vÇÄk@€Ñ (y½^·uú†ØÕHš¦M{hkŸÇkø¬òߤdA¬« ùíÚÂÂÂþñ�‡·lÙâE6›½á¬�GEQP*•P©T°~ýzªv3ßÿþ÷­~ŠAÓ'¬×m³ÙÔwîÜéàãñ8öí۟χ|>�ååeäóyT*(Š‚p8Œd2i‚žç›7oÞ·nÝ:÷É“'/‹¢˜G«L5Š«eª¶ðèÑ£ª j¹\öåóyÓ§‚ÈG{<žk@€uœt¥); $ò¾’$™M�FG0ôïÚµkÓ–-[|gΜY®Õj‚ÁdÔ  äéto뺎f³)qç¦iš&„€�Ç·ÛmþNûfA+ �‹…B•JÍf²,«KKK/iš6je,kšv(‰Ü™Ïç2;;{Ñ(%u’ÿí…þo+x½Þ¾P¼~—Ïçëd¼R°G‡2@/S”‘iUŒ ÝnïI»är¹hš¦ÝVW½F£MÓÌÑ@ˆáÌ�Ô,_�  þñxÜ nårù|’$™Nh�?þ8Ž=jž#EQàr¹2©Tꊢ¨²­æ¸Ø–-[Ü�>úhdpp�r»ÝfvºKÓ4Ôëu,--! ™LRáp8ð¥/}é7h¨Š Õ©ouÏ£¶lÙBmÚ´)¸oß> ãìÙ³¦³¡5»­×ëh6›&Kb€ ×àààÆ={ölÒ4möÒ¥KsƆŸD»P™yí_¹rERU•£(Š%Ÿ-MÓ¦©´:XZ�€uÊ¥›q•õßɵoí‡1î]:‘H$8°NÓ´üôôtY×õZM·¼› ¦Aòz½š¦iÈÈô�Õ k5 �ky�[íÀ‰Ž†&€Þh4ž«×ëIKB¡8U«ÕN x¯\¹òËb±Xí’ýkè>h7 Ò�rJ¿°^¿Ëð¶ï…èÄ `•¥ë¿×� v†A ‚Ìq Àe5Øi4 ( CCCf}—Ì]ýþm\z=0Äâ7‹a``À÷Ëf³�$ 0<<ŒŸüä'øÙÏ~†F£š¦Éç.•Ëå–Ëå :w6GÜÆ0ŒçŸøDxëÖ­î¡¡!¤Ói33\‹¦E#E>ŸG¹\Æää$Âá°ÿäÉ“ÏNOO‹¶ëi®Ö¹)˜˜˜Ð8Ù·oU©Tpúôið<�™*!øCCCƒh6›Ïó±uëÖ݇ógΜ9g\?I84¬@£Ñý~¿—a†dÏÄ*š€.kS Óµp=×�¢(¨Õj iƒƒƒðx<,Ër7nœJ&“ꫯ¾š–$IDˉèT0À‘âõzY†ahkó"½%Ó ×£�±J–v�ÍfQ.—Í~ I’Ž‹EÚˆà š¦¥t]¿¸°°�×4MAû`¯=ýùÿ>øÝ]=ö8�Õè8±@Ë5�ÇÕîî¶ç6ƒÈó¼GÓ4F’$Óm¯\.Ãårµ�–eá÷ûÍ�r-›—nfSáõ¼¡iãñ8@Ó4J¥²Ù¬9!144„§žz ÿýßÿ�B¡ŽãHÖ«J’ôüüüüÅ.Ô?cÛáw¾ó�ÜûÞ÷¾ððð0¥ª*ªÕêŠ%‰Õ.I’P.—‘Ëå ( †††\¹\îò/~ñ‹Úû&ђ̵¾¦þÉO~2�ÇéÙÙY,..Âï÷›Ù«Óq‘‘¼P(„‘‘¢@éß6>>^={öì)A¼hõ«\xUUÕEQü~¿�€hbMD�†¹)Í©º®CEÔj5D"Äb1Ž™‘‘‘Ñ©©)vvv6U.—´ÊmºqΙY–5EQÔ@ àiWC¡�ÙsóZk¢K@ŽE–eäóyd2Ó‰Óh^mŒ’ë%a°FV{i|îsŸ ò<ïJ¥RH¥Rðûýf=¹.ìšþ†5DQÄÄÄ‚Á dYvÅãñÍ·Þz+îܹ£•J…ÇU„6,Š¢Ê0 ÅqGX«ŒµÏç3Y+í¿V×9~†y<Ôj5*‰$7nÜ›™™™+ ¢%ƒ `�îqQ5—ËEy½^–ÒÜHî§=Öì>"£œ¤ßGQd³Yd2 SH„W …ÂE´úŠ|hÙ0¿‚«5ûÃIp¥ì¿?ÿ߿ӋZ!ð;ùëe¬¿SŒ,% èôüƈ”Äqœ€ÉH’dÖ¢GGGM&€¸ˆqkáM?�7 X¡™GFF ¡ª*2™ J¥È\÷øø8¦§§ñØc�!�N#›sç’$Í]¼xñW¢(J]²À-†ÿüÏÿŸŸ6ö�´¬È/:üNãä{+Ìþ“¯NìNõÀëvuPìDý÷Ð%ðÛÄ3ÝiÛÔ å]×2·LfƒeYÆØØ˜©k´Æâ�hš6›­@àfw0¯åóÊ?‰`ttÇ¡Ùl"“É Z­šÁdd³³³ø§ú'¤R)³<`ÿÜÅ‹V.—k+PšA;ï¼óÎàÇ>ö±H"‘ Ãá02™ÌMa8H€¬×ë(—Ë( $psÅbñäÅ‹Ëh÷œØˆöwêïx‡{Ó¦M¾l6‹……ÓAÎ Vb.Hicjj ÇQn·{tçÎ�Þ .¼’Íf“–×l»7A�‚Á —6^Œ,r $ƒí„^oÓ(a�¢Ñ(†††P©TÀó|tllŒ»téÒ|¹\VÑê»Ñ Fƒ¶ßgº®ë’$iápØÍ²,E¼<ü~¿é(ùZ>bP á÷ûQ¯×‘N§Û¦; Æ ù|þ¼Ár$Ekb¥àïÔø×-ó×­ÇöÛ �Ôýµ–™æJ;ÎJ%�•º  Ên­9ìkF°4MÓA�xžwSÅ�̇Ì7 b,ÓF#’ †¢(“ prú»™€àFž›“¡¡!ÄãqÐ4�J¥bJЊ¢EQ099‰ÙÙY|á _@:�Æèè¨é(IR}ffæÐòòrf…ÍÍ`s$ùë¿þëèÔÔ”{``Ùl–”‹Öü¼Ð4mξ“9ocä“.‹³çÎ�›·]+S6¶“““ú<Êç󘟟¿&kíå3 (Ê4Ë™˜˜@,ƒ×ëØ»w¯ëøñãWr¹\Ít²,kEé�@€'ô9˲ăǵ�®,õz�R…J¥¿ß�ÁÁA”J%x½ÞÄÈÈõòË//J’¤áªÃ`Ø °‹¢¨z½^: ² ÃÀívƒã8x½^³¯á5 ÆëƒA¸\.Ôëu,,,`qq¹\¥R Ífªªž- Óh :ÍX4À€² `ïþ_‰ö×­{Q?jôÀïÔr»Ý«± ¾žþ€nÆæD¡%ûJwÊtšÍ¦èñxXš¦I’LIÚ|>�T*…¡¡!„Ãá¶�‘l$,˶™ Ùk¯ èåùI‹Å022ŸÏEQ�Éd�ËåLð£i&&&pòäI|á _@¡PÀÔÔ”I›J’$OOO?=333Óes#ŸCÀ¶O~ò“‰»ï¾Û—H$L#–›qŽHÇ9Åb¥R år™LÔÏœ9sí¾CÕkw Ð?øÁFt]Çôô´°ì“+�"~S(044„ááajýúõƒ{÷îmüô§?-U«Õ Óµ_¯×¿ßÏz<Öš½ò<ßVC¿Ñ¬q%†€¦i ø|>Œ��¡\.S~¿0�=J¤ž«FI#àtZ*•Š2<<ìaY–fYÖ9"%�×J‡eY“E€Z­†+W®`~~¹\ÎTTåX±X¼d$å.ÁßjÔIüÇz_XÇÿú¿~·—ƒU°SöïàW Ô*~_D«QiÀÌ¿!æ&pMõF£�J¥‚¹¹9$“IÄãñkjŠ<Ï#ƒeYs3î4-ðÅ�:r(Âèè(¢Ñ¨Ù忼¼lRþ¢(‚aŒ��á©§žÂ¿þë¿BUU¬_¿¾-øŸ;wîÈôôôËf׉þwØyàÀ�á�üãÑ`0Hùýþ6êß~ìYêjÏ‘uÌK”Ëe‹E³¬S«ÕÔÙÙÙ— ßukƒâ˜åú �>ô¡=}öìÙ¶æµÕ~ Ã@’$ÌÏÏÃï÷Ãëõbxx8¹uëÖü7¾ñ  ƒÜn£Ñ�£Ñ¨—tÒ)b¯× ¯×Û¦ °V¬�Ó¹g¹\^¯ããã(—ËT<¢(jþìÙ³uã:¨t¹ÇáþB(Òc±˜‡€gd¬ïãfƒcBÿ“ÏPE\¸póóóÈf³& iÚÑR©4g£Ÿn�ªý¯÷ÂôWü./ê:þ½× �• -IS®lÛüšÍ¦èr¹(–eÝD V«¡Z­âòåËÚ›­›‹×ë5;µ­MZ7£Ã}5Á�Ȱ#‘H€eYÔj5¤R) ˆ¢Y–!Š"�‚Á ¾ó�ïà›ßü&¢Ñ(¦¦¦LÚ¿ÑhˆÇŽ;vþüùh•Wºu4S6íß¿ÿ–Ï~ö³‰D‚4©LÖš¶&õrâùN„^ˆ}±(ŠL>Ÿ¡Ñh(¸Z>òâª/i`ßüÉŸø8Žc§§§Íì‘L‡\Ïg¡(Š9Rèóù¨ÉÉÉ����…Ÿþô§®Õ®€,Ë:MÓz0äH)€x0XÁÈ͇²>/Ã0H§ÓÀØØêõº{xx8yîܹóÙlV5²dÙ¸Çû½]«Õ´M›6±LkÁãñ˜eÂfÜLPLدP(d^wõzgÏžÅÜÜœ dYVŒM›6aýúõ¦Ê_¹\n:tèÕùùùXy¤):88¸÷oþæo†§¦¦Üccc( h6›¦±ÍõŽ�u xÖq3ŠÅ"òù¼) \¯×©J¥ò²!sKYÀ&k–e™zä‘G|ƒƒƒî¹¹9(ŠŸÏ×Ö²Úår¹ Ifff�Fá÷ûé­[·FæOœ8áØ¬Z«Õ”H$âq»Ý aœ:é�Ô׺iLûb—ËåÛ±c÷óŸÿ|F­¦@­ܶ÷"Ë2Âá°:99ÉK’d2¤�<ÿÍ:~†a áõzÍß•J%œ:uÊdŒ1`IUÕ'ËårÞ!ëï¤ý¿Ú¹ÿ¶‹žçyØ´Sú«~wÖ �Ô*J½€€NL€Ž–qmd).\u¨k[‚ Èš¦©�ÇMQ¥(Šé»^,1== ·Û�ÁÁA3 #�’lÈDù,‰ ‰ÀëõšÙc¯ÛJ€€4¼¹\.x `xxñx^¯Š¢ X,"�N›�_Q3ëƒÄ/~ñ |ùË_F­VÃ]wÝ…�7BE4›Md³ÙêOúÓ™\.w ­zïJb&n†avÿÃ?üæ­[·r‘HÄÔY AŒÿ¥¯­ yn–eMûÙ™Á IDAT|>ofwD@ųår¹h¹6\h éWJ×uêmo{›kãÆ�üìì¬élw#€ÐТ(âÊ•+ˆD"‡Ã®Ûo¿�ûÊW¾R”eÙm¿Žu]§$IÒxòY[ˤ“~-Ø“^‚¨ H§Ó˜œœD"‘ÀÔÔTœçù¥'Ÿ|’(@ÖÑRгO8@íöÛo÷ IùÌ`CÌkâf?˲ˆD"m=KKK&ÈårÄκV*•~(ŠbÓ�pªý;5®JôGQ”>°FËÕ?¿�Ëív›r²]nÊvÓhÀA¯#ƒN»Å´ú 5®Á¡A°V« ’$)Ñh4Ȳ¬[Qs“(‹X\\ÄK/½„w¿ûݘœœÃ0¦¿8ér&(n·ÑhÑhÔT]SUµZÍ·¡Í*Õ¾é‘шgY.— �@À¤úÉæHô ªÕªéÞGl� Pq»ÝÁüü<¾üå/ãôéÓ¸õÖ[qÏ=÷Àçóayyš¦ésssÅ'žx"-Šâ1´¢VÊüš¦7~ñ‹_ܺwï^>‰Àív#•J™ÇïnÖ:S%Í€V¦Á84˲ ¤vÛ5vñâE•rÌ$Ó¾^ÊÚår! aii Ï=÷îºë.LLLDüñ܇?üaY×u·ýº- b>ŸoºÝn¾^¯£X,"—Ë!·Ë@ø5Ùõj•ôü~?²Ù,Nž<‰mÛ¶�çyæøÀ�ßûÞ÷¾ÿ /+äY[ì ;—Ëé•J¥9<<¨T*f‰M’¤›�Ž5*—ÚîqÔj54 Rû‡Ëå*—Ëå*œõüWëô×)óï7öÀï×’$I§išêÒµìÔ- …O¤[{) `00mü¼Ï +A€$IJ6›-…Ãa?Ïó<ªÙlbqqÑœ/Ÿ™™Á]wÝ…7¾ñ�¦¡P.—CµZ5éxŽãÌ2Qv`v#©aû&×)¸]xk 5êÛæq3TUÕü@Ó4&&&P,ñíoO>ù$X–Ň>ô!ÜsÏ=333�$I}ùå— ?ÿùÏK¢(ž1@“˜]Óù�FÇ?ó™Ïì¿ãŽ;ü¡PÁ`‹‹‹æ&lí�p²„½Q/2H¶LØ›qŽÛtMûu’Íf5]ׇQ(Ö, z<ƒA¤R)<ÿüóرcöîÝ;ö¶·½íò�~ô#·à]\\lD£Q�(Š48*‹fêjË)×{ü,Ë"`nnñx###H&“ƒŸýìg·_ r ð3 ûÙz½Ž\.‡ÙÙY¼øâ‹¸ÿþû±gÏŒŽŽš"4dÜš• àv»Í Eš”œ6A¢ºG@‚(Š&‹Ðh4 Š¢ìíV±$ø±,‹¡¡!ˆ¢ˆ_ýêWøæ7¿‰f³‰|=ô6oÞ ApîÜ9d2á‡?üaùСCU',ÃÙÄD·e·ñ¿ú«¿º÷ oxC‚çy„B!,..BUUSƒ�dÛxèše¨„ á8Î4y²–h Ç;;€šD6 T«UÄb1´&WP�ÞMÓðûýðûýH§Ó8zô(Âá0w÷Ýw~ü㋺®s,€œÍf¯×ë%LS±XD,Ïó×Ýœ¸ÚóO¨{�ǃ—^z ±X ÇÑwÝu×í»wï>ýòË/ËF`WµÌûþ7¿ù�rÿý÷‹Ñh”¯V«h6›fYj5ÝŽß~î].ü~Ûß[�|½^·²“—;ýn¿½½#dcFû«~w˲vÏkÝ¡úèÞ;àTbpúyÖØ¬îµžím@¢Z­6›Í¦ …|<ÏóEQÄL¤\.cyyçÏŸÇøø8î¼óNÜu×]f�”ÈÑ’dhÑ·QûÖÌÕics²{{àw¹\ædÂââ"þë¿þ Ï?ÿ<ªÕ*Þô¦7áá‡ÆÔÔ”Y×®ÕjÚÓO?]yüñdžZÞi)t51W8Žþíßþí[÷ïߟôz½ˆF£X\\4�Ú�Vb­3Tr‰lo6›5Ï�µ ¢ë:ƒk›E;h”$‰j6›æç²0âdËk¥­IGºÕm1‘H ß{ï½gŸ~úi7‚fggÉd’ã8Ž®V«¦ÆQ§\Ëqºn矔ž*• >Œ{î¹áp8ðw÷w»Þò–·¶°ëÐÒ0ïëz½NåóyñÖ[oå‰ö>)XËXkqìäx=Ï5ú µZ étÚì Ñ4 E)�FãL—l¿Ð õ¯[™Ñ~Tè€ß›%˲NQåœÆÈìý7â/Ðie<`;Z^õS)EQÔ|>_õù|R0ô¹\.–dçÅbÑ.\À“O>‰íÛ·ã®»î–-[099 By‹Åk‚·uó²n‚ö�¸S™Àú\‘H¡P¥R —.]ÂsÏ=‡çž{º®ãÞ{ïÅÃ?ŒÍ›7·5´�={V|üñÇ+ÿüÏÿ,HÁ¿Œ•Ç™055ûô§?ýÐÞ½{yžG4%=m,G¯Áÿz3lâžGL{¼^o3B@€ÞzëÔm×–¢(”Úún$0Yß;i‚+•J( àyžÙ³gOìÅ_¬‚r`$ÔL&#¯(ЍV«(—Ë& à<ת“Þ~þ=¼^/fff055…ññqìÛ·oë¡$ w*•2=8œX“^J*Ý!21a_Ç�7m€ÉÃ0§�FsÙ¾æôá�ù;þŽa˜kJaýÕ¿Ëãñ@Å•Jvô¬9y'0°RàwúYp-E³ýhIغþžŒg¡T*Õkµš yŽXžÿFfЫÕ*Òé4¦§§ñ«_ýÊ”áݶmFGG±iÓ&p‡d2i¢ÅoÝè4Mƒ,Ë`YÖÌl u|åÊ\¼x'NœÀìì,êõ:pÇwà oxvî܉p8ÜÖ8X*•´gŸ}¶ñ/ÿò/�§žzJ52¶KhÕ@%8K™šß»\.ú}ï{ßä{ßûÞ7�ŽŽ†�b±®\¹bûˆ¤µÑq-ƒ‘uCµŽÅišI’ ˲ù0Ê#ªc¤ZÞ§É4 ƒÁ®sê×û>(Š‚ÏçƒßïG>ŸGµZÃ0Ô† ¢/¿ür^UÕaûÿi4j¡P�'Š¢ÙÉ.Š"8Ž[Q[­™FñûýH¥Rxå•WpàÀjÿþý·mܸñÜ… 4ƒA*À¼wN�:¥§R)iãÆ�nr “k¾ÓñwbÉV…"åëÊçó¸|ù2r¹êõ:y>]Ó´t]ïì{eVœýC�²¿úà÷o‰¢èT èÖ@ù/Àqo½ @sh�2í°‡.RÅŠ¢(…B¡Æ0L# ò<ÏóV  ª*Ün7(Š2ë�—/_ÆóÏ?¢‹îóù Mê>�bbb­Á˜�sssH§Ó¦´m±X4¨<†‡‡ñæ7¿;wîÄÖ­[MPaÝ8s¹œöÌ3ÏŸÿüçkG�%A¯„–åiWuÍ;Ö-PŸúÔ§v<øàƒ÷w8†ÛíÆåË—Í);íï”ù¯evj¥ÿ-¬Ùd&Š"i¶ÒEiØ‚§ÒM24†a:ög\Ïhš5C%,@¹\&Ú ÃcccWfgghÉ·­³gÏ6GGG9I’Ðl6M{¿ßC½ «ý ˆM1EQ8uꆇ‡1>>>|ß}÷…/\¸P0€d6u@UUõ_|QþÓ?ýS?~Š¢˜%€ë-IØ©ý×ÚÌÎÎbnn¹\ÎìGb¦°´´t¾Cæ¯v+5ýõË}Ð_�J+€ò3Ý¡$Ðkv�Á¬Ó�›ð´šw¡eÃtb說êÅb±^*•^¯×íõz9¶•3�Fº®›F$Ö¦$’Ùg2,--uÔ°‹ÀÄb1ìÚµ ˜˜˜ÀÈȦ¦¦ÚdU-Ù¾>;;+?ñÄ·¿ýmáܹsªñüMã=Îßwm2Ÿîþûï�~à¸gëÖ­›8Ž£Ñl6‘N§Í œdq¤ùŽŒ$ÞÌ`är¹Ú2u�eÙ3�P½Š e8 EÙY*†ÐþÖÑËnÇßëhš5K%ª~n·årªªz&&&"³³³)´< ÚV­V“+•ŠÌó<+‚ÉD"‘ê¤_íg`=öååe<÷Üsعs'sÛm·mð¢qN3¸Ú hÞ7Ï<óŒò™Ï|F¦æçç!I$IêØË°Z@àv»ML ¥�áv»Q«Õpøða,,, T*™Ù?EQÏ ­f€ÕÌûëp.“­üûã}Ð_pì°p'& Ûx =‹ë%óGP0gP˜[Ü‚–pÝ�qÐÉû©×ëb½^].ãõzÝ<ÏsE¹è–«‹¹pgú£a2*H2Z�Ç2R�Ç166†ÁÁA tT‚Óu‚ è‹‹‹êsÏ='>ñÄÂÏ~ö3Å�k%ç®àçÝ L@ç8Žúð‡?¼ùàÁƒoH&“!¯×‹d2‰L&ƒf³i²ÖàOêï׻ѭ&¹\®¶ìŸlúDè…ŒJ¶†7da–ˆ€`0èâyÍf³'°Ú,Õz`HÓ4DQ„×ëcæ7ªª,TÛZZZãñ8KÜ+kµAè© °VŸɲɌ}:�Ɖ'À0̺©©©Wfff´Æ+kƽcžÛçŸ^Ëårêè訋R¢Y GHRž ×A±XD2™Ä¥K—pîÜ9¤Óisüަér£Ñxnšß)èk+ì3ÿ¾ýoô—±8Ž3;q�²k‡ ÝKDqºùVêpú] ÀKhÍ5ïDû¸`×¥(ŠZ©Tš•J¥IÓ4í÷û]Ñh” ¬ñ4ÕZm:öD<ˆ”‰FGG155…D"áô:AÏçóÚÌÌŒräÈùë_ÿºpêÔ)Õac"3Ú3hÙ�v«en¿ývÿ£�>úÀŽ;6²,KÅãq°,‹¹¹9èºn‚bÃKX� þ« F سéÖµ¸¸hÒã¤ÉŒa˜r³Ù”J´í¹©H$Âð<�………®6À7 H_9‡FEdllÌ=;;[A«°mžþâÅ‹Âm·ÝÆ+ŠÂˆ¢ˆz½n–¬@c­û,ìŸ9vŽã�N§ PŠoÙ²%633“BKB7‡«Z ½+Êúõë]/¿ü2E�$Ifàzû+(‰D"fÓ&Qç”e‡ÆÌÌ …‚ù^hš>¹¼¼¼ˆ•ÿ:�äŽã±}Ú¿úk…%‚îr¹(›!†½!«SCàuïe=”¬�Zã‚“#³”ô•2JMÓ´J¥"U*‰¢(Ša„B!* ÒÑh”‰Åb,ÇqÏó´Ïç£%I2G§µ,‚žËåt]×õJ¥¢/..ª‹‹‹êôô´zþüyõäÉ“j.—ÓmÙù^´þ&ÚuËë—^¯—~ôÑGw>ôÐCû#‘ˆÏårall •JÙlÖìº'=$ø:×üof0"³ÿö =›Í 3»Ôu=§(ŠÖ!맬Œ˲4¡jIV½–SV `e‚ŒsEÅãñÄììì’íZ#Y­¦(ŠLQCFéH?H'¯…›á¸G¬<TUE¡P€ßïgãñø0® Hå Ð6b{ìØ1qß¾}œßï7…®È¹vw]Mãéü¯T*E±X gΜÁ+¯¼‚ÅÅE³öïr¹š‚ <…µ«û¯(þCX¥þê€þºšÅ:I;5ZÕµ€•(§ïö8oÒA ŒáÚq­¶²€ý÷º®ëŠ¢ ŸÏ“¬�Ø©‚¦iÝx€aÊÚ|¦ª*eÔÕulWxÏšì—Œc®¢å²P(D¿ë]ïZ÷ö·¿ýž‘‘‘ˆËå¢b±ü~?L/žçÛÔýH½ßü­ ƉF¾‘EéìÍ^D“�Ø“ã‘eyÆ,­{‡ù»d2I‡Ãa†—˵&j…�ÞQ/´Ê%s7À²ì9Y–+pPÕ›ŸŸ&''9UUAÉ4Àjˆ•_&Çβ,J¥4MÇqë æ Æu×ÄÕ†F ¦§§U—Ë…p8Œt:mŽivêcè¦öGÀˆ×ëE8n!^QD¥R1³ÿŸüä'¸téJ¥’õi“J¥®¬�ýë+ G}†aÐl6û¬@ô—}9HßX)+ïøW„F¿‚–`ÎŒQp¸)8÷38#°S=‚§ãÕŒl¿dP¯9´j°öŒÿšà‰D˜7¿ùÍ#ï|ç;÷ �ò<ïòûýˆÅb¨V«˜��57YR¯&ªƒ„Âí…ö_I%oµh0¼†¢'B/dR ÿ•z½žéÖ¼¸jŒP(äòù|Q®´÷¬U@µ–H%�ü,ˆ‚Á “Ïç h[KKK2Çqš(Š4qw$öνÃ�¿Ó±×G‰p8ì)•J²q=–­/öìYµÙlj###t&“1`WÞX�ÕñOÓ4 (Š‚P(„_|'OžÄòò²Yfp¹\•z½þ”Úú…=ó×±:¹ßN‰F[ðï�þõ@­po÷8¨Û‚^§`¹ZªßéÑ©ˆHž¦ÐšuŽ6Ø�ÚG¸(‡÷¬M�P3„’A·fжQº|KÆïz÷»ß½þ-oyËî¡¡¡„Ûí¦=ÆÆÆP*•ÌZ?Ïóf–J2cÒéomâº^:üzèj·Û�X,vÍïgff�ÉdP.—Mº—¦éL­V+tz*+`ܹs§Û tnV@%ìŽËåÇqp»Ýf(EQ¾@ Èçó9ã–B@-//ë4MË>ŸÏCX¾\�ja'Ú½Óñ“éÜn7hšF¥REQžd2.•JY#¨Ñ2KËËËš(Š:1êÀjõ´X–E4…Ïç3ƒ¿ ðz½(•JøÑ�~„K—.Ë_2÷ÿ“t:½Œëwûë 0iÿ~ðï€þZiù|>óFíÔ­�½”zezaôõë×»óù¼j¡uKæ�EËm0ŒVí6n€WMhht¶Cîå85#¸×�̪bÿº-èw|0 ƒÝ»w‡<¸eÛ¶m‰D„eYšçyD"À•+W ˲I÷“ìhñ³6o­ ì!˜2 ƒ`0xMó_£ÑÀ™3g�ËåP©TÌçÐ4mZÙáœS°Õ§'&&�|>o¾†af³Ùì‹X�ÙO·9ÇfcƒAÒû5ÿ>è¯W­VÓ½^/Õh4ì�ωN_‰ XsPðÎw¾3ùþ÷¿÷É“'Ï}éK_Z8{ö¬bŒ3ê– ¥idânãÁ£5 4¾º PÀÛ‚?å°¹ÈFF/ŒÍT°üNí…é ( áp˜¹÷Þ{G<¸ittt" úÈoªMÒ4­Öëõó–ÏÉz€ Z¶ÐæÛsÇãqˆ¢¸fcu�,˶�,C d€ºŸ�"Vº]@@'&@¿ÎlÅ¿{ì±Ç¦ß÷¾÷M>òÈ#ÿïá‡Î\ºtéÌ/ùËé/ùË………{Nèù†AƒRFÀ¡Ñ*°–MÝÚ‰n¥UKfï$6‚N€¦iLMMùöíۗؽ{÷èèèèäÈÈH„dn‘HÄÌ Iw4q{óz½ðù|¤qÉ”ó%ÊmN”ÿZh¸÷²hšF(2»½eY65Nœ8�ùùyÓtÉ ØSù|>ß)‰„¥‘sÇŽl,£�ÍŽú›lì# 6 Ãø†¡TUÍ S[3Â/~ñ õÏþìÏôZ­F‘φº›Õ´ØéØ­Z ²,CUÕ�Ëå¢E! ¶�}Ñ4 õz]#ö2�õØ�®!Ò€˜L&áñx ( B&S¾ó�ïàܹsfo„qíüæÊ•+§ÐnôÓKàª:þõµ0½è¯>ø}]õz]w»Ý”Í/» Ù¨õ•jì×½ J’„Gyä©ï}ï{ÑM›6ݳoß¾¡;vÜýÀ,;vìò‰'–Μ9S~å•WšµZMµ±VUCÅÈŠ€Î’´�ÀˆÃ0÷lÛ¶Í799™˜ššŠF£>ŽãÒÄç÷ûáñxP¯×‘J¥Ìîë@ ŸÏ‡@ ¿ßAP*•L­v+åßËþv=ã�H$Ì^„L&ƒD"�\.‡#GŽ •J™£VEé²,ÑÚ ÌVÀm[·nåˆÂ]'wƵ ¤¤@‚¨ÝÐG×u¯ÛífšÍfÝ`~¬ºúºªªT,S …‚;�N›ìŒS#àZ;°N¬Má@ à)‹‚q­7Ð*‹™‡Ôh44�ǃp8Œb±¸ªë‰¨ýñ<MÓ�ÏçAXÃD"�o}ë[8zô(ªÕ*,’Îéjµú¤a¥v½:ÿu”ýµ‚Æþê€þºþ`«P¯ €Bï޽ܡŒq]Y³ýìÙ³ú_üÅ_|ïñÇ÷ONNîöx<ÜæÍ›×�u·ß~»V(š¥R)�N§s ¹§Ÿ~:wîܹr­VS�@¤¡Ý&µWûâkj�·ÜrKø¾ûîظqc8�F�@, …xž§É¦ìóù�FM?—Ë™ô6Ñ£‡Ãfæ¯( …êõzÝo7ôY+|5�ˆeY$ p]בN§ÍÆ·cÇŽazzÙlÖÌþ†)-,,\èòyû`¨íñà8N›œœD.—3'2^‹Ï‚€2ŠieŒŽ~EQ¬r5´¦QÚÊ/•JE#ÿ5>,Ë"�›‚?ÅbµZ ’$!™Lâĉøßÿý_¤R)óœÐ4­ˆ¢øýl6›±°j½‚€žçü ïõsè¯>è¯.KUÕN ÀžÑÛûºy Çß�8ˆ–Sà"Z3Í <ù䓵¿üË¿üÚ?þã?2ããã;�&&&�Édh·Ûí‹D"ëÆÇÇ×íÚµ >ø Z¯×ål6[n6›•R©Ti4µjµ*ÕëuQEQUUY×uŠÔÙ j”b Ãx<øX,æñz½^�Ç“z½^—Ûí¦†¡È¦Ìó/¾ê÷³Ò¹"ÁŸM+ýo¡Ã]^¯×[,h5|Êh•�L<77§nÛ¶ §OŸnó’Xíç´Z¶†;ñJ°²†–K×u«X–ìÀòiäs%çc¥ãfYÖ4Ï`cI’„H$‚b±ˆ¯}íkæØªÅuôéL&sÖ!Ð÷Òõß‹�¹Œ²Gõ@­p Z)‹ïä‡lÛN¿“Ÿ³hÕðßflÀçÑ2Ï)�¿ýío×(Šúêßÿýß³“““·ò}.— µZ�dÿ©L&ó¤¢(’%ûW:€�nÆ?Ž¥·U0ŠýÕýu=KÓ4�çyÊa¤¦›ÐN§2€jûj§âÉ£àÛþÀFî@ËL' `þ[ßúVizzú«ŸûÜçÞ¿o߾݉DÂÌ®ëõzPUµMð„aÊØ)§ì�|OI½˜(ß‘¿!µzB‡[7f¢ÕN2}ŸÏ×Ö¬E?ÉöÉc% óf7™Ù_Çív#�ÃëõBÓ4,--A’$$ \¹rO>ù$®\¹búJ³Þ¯Ôjµf–‡è7 �3;wîôƒAó³ºÙZúVÝžAåÊ’ñËhõ-×:U(4Žã ÍÆG«ÀZ36vv€\gÇnŽ÷")wXéò�ƽ^/†††àr¹ ‚9éAFþ¾ûÝïâÙgŸ5__PÕl4_m´h¡•¨ ½9êýàßýõ¯f³©ûý~ÊA'  p­Á�uzÀÉIÐþÈø€£%ýË¢¥ü7`騱c•�}ìc³o{ÛÛb{öì™Ü³gn½õVø|>LMM™›±¶+àYÍl�†)èb¥t«Õ*dYF³Ù4n¬ÏeíÆ&cY¡P~¿¿Í%N×uÔëu”Ëe4›ÍkÿjÙ^+@@êþñx¼EËd³h4 iápÿùŸÿ‰sçε5’Ñ4½˜N§O¡{Í6éîàÁƒÜÄÄ„ktt™L¦ë üZ,ò\Dg¡Z­šô?ù 4M£ �\¿uØêèËË˪(ŠúÔÔe¨ðµûÍxÖÀOšI­ÁŸ?MÓVù_b>eÎU…E„ì,‚&“I¸\.H’„T*A I&''ñË_þ?øÁ †A¥R!ŒÈO3™Ì’CÖ¯®º9dZ÷ÝjÖZ£¿ú ¿ŒÕA'ÀçÎ{;°g„vC2b¸à›>`€Ýòo<o&“úêW¿*ž={6èСØÐÐn¿ývlß¾ãããày�@ÀÜœEQ4ƒpµZ5ÍPº ¯XëÆDx…Ô_=�™ée6+�Üh4P­VQ«ÕÌ Ÿtöfâµ òW€�I&“ ( …BÁ”y�˜˜À/ùK<ÿüóX\\´Rÿª(ŠÏ4›MÑá!À ¥Úèr¹\Ôþýûý¡P�ökëféèÿÿí}y�w}ýëîéžé¹gvfwöÖê¶|ɱåÈŽ°�Ø›#IlSPIŠ"!EQ©¢€¤* ÿ$êG™†$€˜W,ÀÈ–OlË6ÖaY²´ºV{hÏ9vî³�ßÓßvOo÷LÏjelø¾ª®™­v{Ží÷>ïsq‡p8 AôY Æ ‹‘lÎð5©TJ­×ë*©y3ù x<}ÈŽñÜ5ÉxBd •þ˜ÏçcŒ[íŠ.†A$�(ЍÕj˜››ÓÉhh¯¿þ:~ô£¡P(Àãñ'@¾0;;{Ð@þVG;à¤ú¿‚ Ðe?TP\N”ËeÒnÓÍØ`s-crŒ¤o^Ë 9öw?€�j‘ãʼ‚,3‡Zž››C$‰;vŒI$Àúõë122‚h4Úr±·‹¶Í-Vƃ �ñx<úl~"È…¸V«é«pkµšžÛ7§ßÿ»¤èoddÇ¡\.#™L¢^¯# !›Íbß¾}˜œœlÉ}3 óÚüüü4ÚWkû4€÷¿ÿýâæÍ›…X,æ¨øo-ÈÔ8�¤vŒÃ–Èa.�´ˆºSóù¼*I’ Ysáåzä|I‘)Ïó-â…Üj-°Œ] €aÕø^Û QÑÛÛ‹Z­¦GþdËßää$¾ýío#•JÁçó¡P(�i„S¥n"{'ÄßÍØß–ÏùKÅ›UU�î€É0¶ ÂB1Àn%4»\>€æ˜ß�$I™žžÎd³Y) õNOO3$o?88ˆ±±1lÚ´ ýýýzôgn�"Uck˜¹`Ì8«¾^¯£\.ëû$ª7Nî#‡S‹­{Þ;�Ñå „à÷û188AP*•0;;«WuÇãq|÷»ßÙ'O~Çqét:ý‚ÍÛø~'øC¡{÷Ýw�"‘ȪŠÿº%S"îÈûGHÕø^+ɧ†fQª`H¨’$©¢(êu"—{Ù@²€‡¸äs¦(ŠlãÒ©—Ë¥Ÿ¨¹�Ðø8q–––P*•P«ÕÐÛÛ‹ÅÅE|ó›ßÄÄÄ¢Ñ(ŠÅ"ªÕ*�Ffvvö'•J¥Ð!ú—àl �£Ü?íÿ§€âw xžgÞèôZù‡izÜ<3ÀjŽqÌ"@pBûžÙ‰ÈçóyY–•p8Wŵ¼¼ŒjµŠB¡€|>�uëÖaxxX/l3.žQUUÏñ“u´†%1 c_É›Æ(ÌxXMY[ 9\N‡Àø\Hµ÷Ðм^/ªÕ*fggQ©T ( 6oÞŒ}ûöá±ÇC¥RÑó®Ç5jµÚÓÚ˜W»èŸÌþÀ}ô£õŽ�� ¤õïrTÐÛÍÑ÷ûý-DgpÚÌEUÕºá³+£u$S,EQTò3»é§wú~Ï� óÚacZ‰Ì‹¨×ë5“ãâ2~~B¡/Ë2�†åÈem|5‚Á R©ŠÅ"jµâñ8�¾ÿýïãüùóˆÇã¨V«d%rvaaá+•JÍÂÉNä/¡s UÔoéXÑþ*(Þd4 +`&~ÆÆº3Ú9Šá‚1àîÑD€å·T*•dY–#‘HÜår¹+• æççÑh4t{žT²“^|bã*Š¢“¹èZ]àÍäo,¼\D}9cäP«Õtòo4èïïÇk¯½†½{÷"•JÁãñ X,;ùðâââtÞÏíïïw½ç=ï úý~‚€ÅÅÅË:ïÀP£ŽãZÖ k„ÙÒ…¡ªª"ËrÙð\H”ªCQÕ,.÷s ù†sh)$%¢SzENƒ7Fv†‡‡…z½ŽJ¥¢ c€ÛíÖÉžlø‹F£ày_ûÚ×pâÄ ýßµâÙÊâââSÙlvÝçý­V› ˆÛÖÐþ*(~‡"Àår1Þ)`× ú �5¸š‹Njî0j¾¸‘ßY­V«Édr¡§§'&‚�ä1Ëå2J¥J¥FGGõ”€ÑÊ%n‰äÛœ¶îË5“ßÎ!Xíïp¹\ðù|A Ð#2å-‘H R©à[ßú¦¦¦tw@s &æçç_ÖHÇ*?k,þÛÀ²¬û3ŸùL`ppÐ544„L&ÓRy9;X–ÕûÖ Öj5ã¸e¹ÑhT VF³@¯A�)•Jz�ˆ±%o­]rî<ÿƶkI’ô¼<™ÉqœÌ0Œm8Ü××§ƒÁ×Ç|®±XLfÕj‘H<Ïã_þå_püøq$ ȲLÄtm~~þ‰d2yÍ4 ‰þœ€N³¬Do5H’d® °³€UاXØ/‘M"à€_¢9-pZ«žõœ³$IR2™LF£QÙãñdYfÈÐ’(‹B?B¡xžo±÷×Ê¿Ü}û«%Ríßßß�@ €r¹ŒÙÙY”J%½è�a<øàƒ8}ú4B¡�.Œ†YÎd2Ï–ËåZ‡ 5£Eÿýïÿû½;vìðƒA}p’“è}-^7"tŒ( -®�ö¼¤Z­V7}^e££ …XY–9£³p9…©]0þžF£�jµªŸ»&ÂkZž%n¼ñFÖçó¹r¹œ^i„ÛíF0Ô[h#‘AÀ×¾ö5?~ƒƒƒzwK­VkÌÏÏžŸŸ?Œæèa#ùɾ�îÇÿÚµ¶DÿÚê_z¦€âw SåñІõÚÜNµæ:£˜ð€Ý®Ò>‡ÆsP0Š¢Èét:j�@ ‡eY¶\.czzù|¹\¹\ªª¢¿¿[·nm‰ ëõºÞþFЬÖÒÒý]9d|$Áðð0xžG±XÄìì¬>�t9|ë[ßÂóÏ?¯Ï€× kétúÑT*•Fûu­@3÷¿u``@üó?ÿóP$ac±æççWõºY=—N žÆü?Ý ªT*º«Á0L±T*•M‚¦å�ïééa8Žc 9›‰t-…I3˜Sdƅѽ`¦ZoÝäÕòÃGGG![*•V.’m�¤•uxx¯½öþó?ÿ§N�Âèè(dYF©TB¹\–¦§§�ÌÌÌ<�æ´DsÔo'œÚåþU+’^}© x €eY#AZ¥ Uß®@¶äß<ªýŽ«5'À<œˆQUUÍçóÅZ­ÖˆD"Qžç=�F©T årY�F7nD8ny^ëÖ­C£Ñ@±XD6›E>ŸGµZ]³%=o¶C@ŠÉúúúÐ××–eQ(033£G“^¯===øÿïÿáÅ_ÔsÀ¥R ªª6Òéô�ù&ƒwÕÊafð _øBtttTˆF£zÛØZ½v�^7²œÉ8§� z*‹z7‡æú” ytKQ#Š"˲,£ Þië\ª (FñÒh4�L&uñR«Õˆ¥Ÿ­Õj’áµoùa·Ýv›‡eY,//·L$¯2år‡Â7¿ùM¤R)ŒŽŽ’U¨T*�©©©ãSSSOÈZ·äïdPÇe@TPüÁó|»‹º� `Vŀƹ¬é~ÀcÚÅå*hæÌNµV«Õ’Éd2‰D<�S.—133ƒR©„l6‹r¹Œ|àØ´iSËXWA�F�FQ¯×±´´„åååâXK’¾\‚€Øà‰D±X ªªbii Éd’´rAE„Ãa|ÿûßÇK/½„H$¯×K&**¹\îèôôôtžØÆ Y…¾ñ¯þê¯Â;vìð’É333-ÏëR_¿N¯›•ý_©T°°°€b±ˆJ¥¢÷ÿ3 “Äʆ–Z“ÞÞ^—ËåbªÕªm+ÝZ 2üǼ³ ›Íê€ØàŠ¢d$IR,®Ï*fýúõnân‘ä5j4X\\ÄÔÔŽ9‚ ŸÏcýúõÆÈ¿199ùúäää³Ðvs´9¬ªþ�´þ9"|ò™¤ €â-€Z­fN¨vdÜÆ0 »ùÆû94‡-¸@ÀÊ Y–åT*•ƒµ@ fY–k4úî€\.‡Ó§OãÎ;ïÄ]wݵÂ2šSdž††�DZ´´¤WJ¯¥XkA`1ýýýE’$aff¹\N_=ìõz�Fñ�ï|O?ý4úúúàóùH+ šJ¥NŽ��ÿVUU�[´X[o»í¶Á�~ô£a·Û���LLL´ìN¸=ÜæT ÙÄhú¼"™L¢P(è­Ž,Ë*õz}Ñôye Â�Ç],ËêDjõ­ÙÖB¼Ôj5¤Ói½†�t4�EÃ{Áj 088ÈŒŒŒ¸!˲>›tBd³Y$“Iœ:u ¯¿þ:†ÁæÍ›Q«ÕtÛÿõ×_?;77÷Í}kGú�ºìòÿŽ¢†aôÁdTP¼µaÎÍÎRÆ �¬É 0;U‡Ð\tVÎ hÙW�Ïç‹•J¥ÚÓÓãyÞ­ª*Êå2¦¦¦�Ëå°°°€£G�â£ý(¶oßnyQw»ÝF"‘ÀÒÒÒé´�]®Á$«„@úûû�FÁ0 òù¼žï'}ð±X >Ÿ_ÿú×ñÒK/é-�ÕjŠ¢¨‹‹‹Ž?þ¼ªªU‘ 7‹mýÌg>ìÀÀæææ IRËJ^s±¥“ uÝ€L64çégfft`°ÐË¥RiÉ$VÉ ‰DBårYÿ¹Ý õéF¸y<ž–ü?Ð,^$¢µR©�J¹\NŸ:½oð=ïyçóùØ3gδt-ȲŒL&ƒ™™œ={ãããH$èïïÇòò2qH¤W_}ub~~þ7æamûwrÚÙÿªG©å=¥½ÿTP¼Å`ª°°qì�U*@†uJ€0`/€wØb¸p¯!�FCZ\\\ ƒ~¿ßbY–•$I�¬2™ Ξ=‹w¾ó�øÐ‡>„þþ~Ë'Åó<‘H$P(�L&‘ÏçÉhÔË: � ày¢("‘H ‰èÛÜôu®¤|hhÙlßøÆ7püøqlذ~¿ŸXãêüüüÌÑ£GŸRUµ„ÎZ�h4zã¿þë¿ ð¨Õjdv@ËܳXZë…@‚ ¬¨ë€ÉÉI,--!—Ëéd¢(Ê|¡P(›>3ä3*Ïól4å�fffZZó¬ÞŸÕ.¢ …B+ÄËüü<’É$r¹œ.^\.W!—ËŒOÍ�€«¯¾š=uêJ¥ü~¿î¾¤Óiœ?ããã( x÷»ß�P(„S§N¡X,"ŸÏW>|aaaá9Sh¶û�nœ€nÉßR ÐÞ*(Þ‚p»Ýæ¥æ‚°n\;'€±9È¿-ø5š{ÞÀoAPä­är¹B©TªF£Ñ°ÛíÉÒ ¹¹9,//#™Lâ·¿ý-vïÞ�»ï¾‘HD¯Â–eYßúG–Ì„ÃaÔëuär9d2}-±9b¹‚ÀXí�Ç�FÁqjµ‘N§õsi4`›6m©S§ðïÿþï¨V«¸òÊ+áv»ÉóSffff_~ùåƒhÖ[8‰Ô¯×{Í?üÃ?lÞºu«;C–e,..¶¬±%ƒ”º8ÝŠ2ÚlÿK’„ññq}Ò�á÷\TZOJEs¥~�»æškøx<Îj"²¥°ÐÉs1 ¶vÏÃív¯8wUU155¥¶Hí‚¢(s’$Ɇ÷à À @E¢(º—––ZÚ ‹Å"NŸ>�©©)¬_¿wÞy'¼^/~þóŸ#—Ë!�Nó›ßL …çÑl¿m88¬ �¶ÿuœþçóùôMˆTP¼… -å`ºH¨è\Àvpd“0 )�cÚí;„í8S#)™L¦ƒÁ Ïï÷Y–åŒi�L&ƒ¹¹99rïÿû±sçNˆ¢¨÷Í3 ƒ`0¿ß¯¯&«t�r¹œ^c@ؼ¾ôR6Ä‘7ñx¡P¢(‚eY=âÏd2úb"ÒÇ …088ˆ‡z?ü0¼^/¶oߎãHN\9}úôÌ¡C‡X@çíÀŠ¢¸þK_úÒíØ±C ˆÇã8wîœ.NÌëw×Òõ°Šþ{zzV<>33ƒééid2½€ÎårÕs¹Ü‹Ï©Ç˜عs§»§§‡ÑöÞ_²ƒc'nHêÂ,0*• Î�;‡L&£¯ºfF­×ëS¦÷$ ¥°yóf—Ïçó)Š¢¿�FçÏŸGµZŇ?üaÜpà ¿úÕ¯077§ÎÍÍ-8p`¾^¯?`R#õº»¿›Ü§è¿E°,‹R©D£*(Þ†0çU;YÿV;Ìõv.¹2ŸF³Ui'€M0år�UU‘ËåJ¥R© …¢(ú†adYF6›E±XD2™Äøø8®ºê*ÜqǸùæ›1<<Œ\.‡T*…ÅÅE}=°ÏçÓ{éãñ8âñ8TUE¥R�$IX^^F£ÑÐç ��níf�–3žçáõzu{[¸Ýný®Eo(•Júˆ[Bü,ËbݺuÈårøò—¿Œ×_cccضm›~^µZ­ñꫯ.>|ø0š3dtÎÍ2�gýW¾ò•Ûn¹å–0$PU<Ïëy2>ùr¦Aˆ}n.äT‡Âüü¼>‚è‚L&“³x~"ù˜m“hh)�'Ѭ\¾NsX“ `œ-.g2™œ(ŠÕ`0äy^ ¶1±]‰x饗ðÎw¾×\s FGG‘ÏçõþlRÀåv»áñxô±±dž{0±‘ ñ˲ŒZ­ÖBŽ„AУ7²Ž�9·b±¨on#¤oX‹x<¯×‹ƒbÏž=¨V«xÇ;Þ� 6èk …Bå•W^I;vì€Y ò·ì÷w»Ýñú§zçÎ�;c‚  ¿¿ÓÓÓ�$Iß· esÝ媋 3í#‘ˆ.:jµÜn7 …Ž;†d2©·‘±,«ÔjµÓ6Q�|v7lØÀ ¸b±˜¾ÃÀÉ‚®/ª.ÂápËì"^^}õU,,,´ˆUU§³ÙlÞð¾Úç\eY–Ùºu«èr¹ô ‚™LÙlï{ßû�H$ô´ÈÉ“'åçž{nî‰'ž˜‘eùíýwRìgç´³þ»*ü£Ñ?o‡„¶a­ 7 SÀ¼/ ÛCBs–ûQÍʾÀz4s»0‰rAUËår­R©¤C¡�WEŸËår‘–©d2‰ååeÌÍÍáàÁƒ¸âŠ+ð§ú§Ø´i6n܈l6‹\.§Oš#0’“æ8®¥vÀ¸¢ÖÜòeD£ÑЋ¾²Ù,$IÒÓ Fb5/*êééA$ÁÙ³g±gÏœ§_;wµR©œTUÕøµÔvìØ!lÚ´I ,›Íbvv7ß|³Nþš³PûḴÿþ ^Ô„3!qBîu 'ÀHüÝTþÛ¥“,Å€¢(”ü© x«CÏÉØYí&âg°rñ°rY�›[ãý9Í ˜p-€^¬\(¤Ÿ£ªªJ6›-‹Åªßï}>ŸŸeY–¬&B`ffGŽÁ† pË-·à†nÀèè(†Ñ§’ª{cîØhëÛ­”5î%0í}o!{ã÷’uƉD>ŸÇ�Ç~ð…w½ë]p»Ý8sæ ŠÅ¢|ôèÑìþýû—3™ÌIÍö­;ˆÐ˜uëÖÅ>ÿùÏ¿ïºë®EdÌo£Ñ€Ûín!«Ú+ üR˲ðûýèëëÐÌ™/.."�#ŸÏãÀ�˜žžn±’%I:V(*UD3—Žã˜�;wzH·G»Æ¥Ly}}}ðz½ú &RWòÒK/abbétZÿýÇ%3™Ì‚I8Çp è»wïöz½^òù<.^¼ˆÍ›7ëc¯5W¡ôå/™�ÿóhù‘±r¦¿“:«@·ýþªù5i�pLAÅÛ V¢@µ¸oV/Û<Î8%§$µ”ÀF4«¥-EI d³ÙR¹\®¯(Š^F»’“(¼P(`~~'Nœ@"‘Àu×]‡;v`ëÖ­X¿~=ªÕ*ŠÅ¢¾[À5ZÄÿÍX0f.3އÈF£(—Ë8uêžyæ>Žd2©?w·Û�›��=g"׈–Po½õV±··×U©T�L&‘N§qï½÷" “É(ßýîw3_ýêW—J¥Òëh¦È –l€Õôü[YÿŽzþAçÿS@ñöBµZ5¯¶KX9$úgmœ¹�ЉüÍn@Àyi4»¶i–o»áîL£Ñh¤R©¼ å`0èu»Ýn–e9©´lœœœÄo~óD£QŒŽŽâª«®Â¦M›°~ýzÄb10 £�äµ";òµ,Ëút¿lÄ5`d IDAT6‹J¥‚'NàôéÓxñÅõ-{W^y%î»ï>Ü|óÍÑ‹�†zîܹú±ùÎ;ï¼+�ŠÄq˜šš²$2sàrŽüÕ"yôöö‚a,//#›Í‚aD£Q<üðÃ8uêR©”‘t Édò¤ Éè‘t<箹æO<G&“YóF–e!Š"†††t»{qq’$¡¯¯SSS8pàfffÈÐ0 £J’ôr¹\®¢u�F€+‹áÖ[oõdnn7ÝtFFFpþüùú<�~à�æ0 †•³ûÍä/u°ü;Mû³Z÷kKþÄ¥  €âíæù«ª•PmˆŸ@± ~íW w}jÿwY‹€fÑÜ,8ŠÖùïŒÕïª×ë�T*•w¹\œßïEQô¸´¤7©¼'ƒW�æççqñâEûÅ/~1{üøñ’fùP¶ ~+û_j#Ú ü±k÷S:Yÿ´êŸ Šß#àóù‹Â)§"À®¥�kcí«mÈ]1=fgUfµ åš�М®æê$´(X.‹r±X¬2 øÝnÞï÷»ëõ:_¯×¹z½ÎV«U† "·ä¾ úTÁP(„¾¾>ŒŒŒ`Ë–-ˆÅb-Q¾$I¨V«ê‚râĉÆþýû«{öì©§¨h¶o]ÐŽŠÍEY?8Žc>ð� ¿ï}ï»mÆ ýÇ!‘HÀåra||\'0�Ç£GÕ²,ëu ÝVü·#P+1@~ÿðð0¢Ñ(dYÆÜÜœ=���áܹsøÉO~‚ééiˆ¢ˆF£ŽãTY–›J¥’°_c<À³{÷n÷;Þño?’ÉäªHÉêù�z"àˆp!{#ü~?X–Ń>ˆññqð<�jµª/ý¹páÂ3&²VŒÝrË-¸ûî»cêÂÂBùСCKÏ=÷œ¤ªjÀÓšøkÀ¾Z_j#:Eþ�*þ;’?˲´êŸ Šß'”J¥KqŒ5N¬¥‹Ç! kŸm£8`3š[ƒBÀªÕjµ^­Vë Ã0Ç1�‡ .ŸÏÇÞãñp�‡E‘u»Ý ù|étóóó¸pá‚rúôiuݺujoo¯’N§åÙÙYùرcÒ‰'¤#GŽ(KKKæe6 šk’Ï£µÐO†Í\ÿ�7ú?ùÉOîܱcÇ5�Çåóù000€ÅÅEäóy½‘Ì©'Ó/•ü�:,ËÂçóappP·Î/^¼ˆl6‹F£�X,†R©„|§OŸ†(Šz]Ïóó333Gaßâè0 Š"÷±�}, …ÐÓÓƒ'N\òs1N(Y)<77‡R©„z½–e144„={öàèÑ£ày^ßÚȲ¬œÏç÷ …¢‰pYÍþgÿþïÿ>àr¹˜^xáâ¯ýëj2™TМ{qÍ9íˆßªÀÎ pZø§ÀyÅ?øCuZV±*h¿@ˆkõ“[— é+6/Îð˜ oLC{U ÍH ¹u�é$Œi­õO)‹’�m* CŠÉü|­^@­×몶Lˆ±¨®7_8%�ø§ÑœêV7½&+R*6lðÞwß}Û¯¿þúkC¡�OEôööB–eÝþ&© óhßZ­¦O)tjá¯,Ë"`dd¡Põz/^Ô‡-ø|>|ë[ß‘#Gô= Õj.—«4;;»¿ÑhH6äO¢ÿàßþíßú¯¸â a``—\ùOÆ@ ‰hNå›››CµZE½^Ã0Þ={°oß>}m²6ZZ•$éå .œ³ ìuúûûÕW^y¥¼wïÞìÉ“'4+û« Ø’Åç\ràÈ6¤ßMäoþÌÙõþSò§€â÷Ù dg³/&1`,D!`'¬.Bæ‹–ËBp¦ïá �IhæOgѬ0€æìu­õ mÅ€…0`V>«m¯£ÙÖ8§ÝV-^ý–aŒŽŽz>ö±�]uã�7n‹D"=n·›‰F£ðûýH¥R( ú"²tÈœï¯×ë-rkYèG B¡FGG!Š"ªÕªž7׊ã‡ñƒüÐG/kÖ-“É<›Ífíšøí=\·k×.Ïí·ßîïééÑ ØüœŒÏ­“`q»ÝˆF£ˆÇãz*"™L¶li€±±1ìÛ·¿üå/õ.�l6K–ñ‰‰‰,Ø…f�Š{~~^ùçþçšöÞ.häNVb·“h'V3èÇvè�×ëµ*¦ €â÷ ZU `nd¦ÌÄǵqÌ€b.Ã}’­hZ€˜æôiDâÁÊ‚vuLbïÔ)k¢dÍâŬv~mS![¶l ~øÃÞºuëÖ-ÃÃÃ1—Ë…žž�\I{ŸÏçƒ(Š+ÆúÉ¿]Ѷ¹mÎ)yIÔãñ ··}}}Ùl :ù ‚€ÑÑQüâ¿À#�<I’‹ÅÈ "5ŸÏš˜˜˜°‰@‰Û´nll,ô©O}*ÔÛÛËöööâÌ™3Ÿ›Õó! ›B¡b±‚Á >:•JéÅ~’$Áçó¡··?ü0yä}¸S6›%û¦§§T*•ª ¯Ó>{ä9UÐÜ‚ù²æI¦Ï²â0 w } íkhœtåxžG¹\¦Ñ?TX:FtJ �ƒ…}¾_±!yQïK¦[Ît1�×ìv7š]14§ öhAоŸ±j²7¾F$z+¡Ù¶˜Ò~µÃk¢öôô°·ß~{ï®]»®YÜ‚ 0}}}ƒH&“˜žžÖÛëDQÔÛ�ûˆåßí »9ùVb€a}åñÀÀ|>dYÆüü<–––P«Õô…Ccccø¿ÿû?üà?ô÷÷“½j±X?sæÌkh3à@œa˜‘O~ò“Á 6‰Dóóó]Õ3�)�Ä© »†A±XD:�nÙ !Ë2B¡AÀ·¿ým¼üòËèïï‡ËåB.—#u‹SSSû²ÙlÖÂŽ Ù®ÊiÎÏ šUþZÔ/[ˆÛN‡ÔÅã�–ûX¦šŒ¯™ÖÝ@ÉŸ Š?DÀóú¨> Pk%C6›�;|øðsÕæðËUÆÚ±ñÎ;ïú³?û³H<g"‘Μ9ÓrníÒ¤ö �ë~…B™LfźfI’à÷û‹Åpøðaü÷ÿ7‚Á þø�ÿårY_U*• ÇŽ{6›Í^Ð>Gf@>OO¢Y˜šCk[ Sò_Íã—LþÚ$FJþTPPÐPÝn7S«Õ¬ÈÌnq��Àš.:œMjÀÜ% ›Ä€9ú7?k!Ø6·ähhö,‹7rÏÆûŒÅ}«Í‡oüº\Ì»ßýn÷UW]åݺukØårõ�ÑP(Ô#ÏqCzÏIŽ?•Jabb¢ÅÂ'Ã|H;Y9Lú§-orAï†ì�«�EQÔÇ"G£Qð<EQP©T°¼¼Œt:ÝBü ÀŒ!~à�ðì³Ï"‹é‹têõºº¼¼œyå•W^,—Ë9´¯<ï»þúë7~⟈õöö²===¸pá‚ný³,kÛÀ²,B¡úûû 47øe2äóy],‘×�eY$ T*|÷»ßÅÑ£Gqíµ×bÓ¦MX\\ÄÒÒ$IRÓétöðáÃ'³Ùì)ù[­Ù}o¬çUl¢óN¤®tqß*çß®àÏ’üµ×”’?M¬@Æ� ¢µUPµø7ÖtŸ5=n¼U,Ü£åï2E÷’M ÀN0B€µ ÿNB·ÛíömÞ¼Ù½k×®¾[o½5¾yóæ±@ t»Ý|¥RÁÒÒ’nÑ{½^x<d2?~Üj[£NX„Ü�Ú÷æ-…Æœ>icdYV/Œóù|p¹\úDQõÁFÕjKKKX^^F¥RÑω·Û�ÑÑQLLLà?þã?pöìYlذýýýúsH¥R™^xáP±X\² ã}‘çù«?ýéOŽŒŒðëÖ­C:�nymÈkhNQ¸Ýn ¡··ªª"ŸÏcii •J¥…ôÉA\�G}ûöíC4ŧ>õ) à•W^!» ”ÉÉÉä /¼0Ñh4^6Øùí¦ïIm¬ùÕ{»ïéTìç(ò§äÿû†¾k –e›ü²UÌØVäj>ÌÄmõµÓÇÌ [`u®ÌîÝ»×]{íµq¯×ë�D"}�@ âñxñxÜë÷ûY¯×Ë„B!ôööê-ÄŠÅ"&''õÕë�ÖI; [Ìq\Ë~£#@¯×Ûr^ä{Hj¡Z­¢Z­¶´ÅÇ�‚  §§,Ëâ±ÇÃÏ~ö3¸\.\}õÕèëëC½^G.—SΞ=›yüñÇ�Öjµ ´ÖP˜#T~ýúõ7üã?þãu›7ov���ayy©Tªíëáv»188زu�$šIz{{ár¹pôèQ<ôÐCðx<øÈG>‚[n¹…BÀ¹sçÔ¥¥¥ÊÁƒ“gΜ™QUõE¼ÑÉÑIÈÖ¿2ïÙÛÙýíFimªýiäO ŠŽPEõx<ŒE”j—0[ÿ¬áÅÂY·¹¸±hm4»�¢ývö'°B Ôjµ Ïó£‰Dâ¿ßáyžÓЧ ( jµ*• 2™ <�>¤‡L¾“e¹\N�L­Þüµ‘èƒÁ xžG$Ñ£x+‘ÑÉ5 ûP*•ôuÉÕjµ%Å@­‚,Ë¢¯¯¡P¯¾ú*öìÙƒsçÎaË–-رcúûûIq záÂ…ô£�>zN–å)�í¢&�¯ÿ¾°mÓ¦Mî¡¡!T*•¶äϲ,zzzô�ƒD,”Ëe½¢Ÿ¸,Ë¢··>Ÿ¯¼ò ~ö³Ÿ!›Íâž{îÁ‡>ô!ô÷÷cjj Ï=÷fgg•ÉÉÉågžy¦°¸¸8à%4;;œ.ßéÆèDì�¢}s-`=Þ4ò§ÅåüŒuëtrì"w§ßî±väÏ·³sÜn7õÕW¯½IÅ ǹyž×IŸ´ì‘]d-¯‘ÔÉzYóAŸô£‡Ãa}=‰ÔÉœÿR©ÔRµOˆÚH€$‚'ßG¾ÇLîÆ'?‹Üçy½½½8rä~üããÌ™3èëëÃwÜ�w¿û݈F£˜ŸŸÇ©S§äýèGé}ûöM8‰7Ú!­¢†çù±o|ã·_}õÕ�ááa¸\.œ?ÞVÀx<¬[·===¨T*˜ŸŸ×çö#~¯×‹X,xæ™gð“Ÿü²,ã#ùî¾ûnŒŒŒ@’$œ;w‡VÏ�;W}ì±ÇÒ/¾øbÍÁMÏ¡YÌgù;]Àã$ÂïDòíHßÉ�ŸäO·ûQ@Añf§€•Åt¶v{‡ˆÝ)±¯FtrHç€�a˜P$Ùà÷û¯d¦Ÿã87˲ ‰RÉa´è�ÛƒÁ B¡"‘B¡‚Á �±uëVôõõé/®$IXXXÐçÔ ­Vûš�+b·š`̯Çb1Äb1d³YûÙÏföïß?©‘¥ ù# õ~ík_»ûÊ+¯ Âívëí�VûÂá06mÚA°´´„ÅÅEÝÍ µ ñx===˜ššÂ£�>Šgžy Ãà/ÿò/qç�w"‹�aT«Uœ:u ãããÒSO=•ýÅ/~Q^\\”ÑœÕÿ¢‰ü­neÃ×N{ó�»vY«ÁZ”ü)¨ xs˜B¡ÐésèÄ 0;L¶|»\þZ<ƈ 9L(Šf�wÍ�B>4g¸5AÀ0 Ãð<Ïû|>ŸÇãñsÇÛýM’<>>ŸO'ÿ`0ˆ¾¾>lÙ²;wîÔ·Ô)Š‚\.‡l6‹|>oÛ `GìVÂÀØRG E£Q=•qôèQ<ûì³8~ü88ŽÃm·Ý†÷½ï}¸âŠ+à÷ûõŸU©TÔ'Ÿ|²ü7ó7¹‹/N£Ù_kGþ›7oŽéK_ºçÊ+¯ R?zô(Ì-¨dÁÈÈúûûÁ0L ù“º‡žžäóy<ûì³øÕ¯~…ÙÙY\wÝuøà?ˆ�;w"ëÏ;—ËáøñãÒ� {÷î-�:uJÑœŠãhöð—Ú¿QX¥‡Àito×Ú׎üW¼étÈ¿K7€WÀLü œõ±�òuÀ{ÑäÅÊ"B[±Ã²,ëñxÜ�GÁËqÏØô晋úH*Áï÷£§§cccX·n6n܈H$‚ÞÞ^„B!o 2þèjµªçôÉ{c¬ø'5d~€ÇãA2™D2™Äòò2Ο?�Ó§OãìÙ³à8×^{-ÞûÞ÷bãÆ�ú "£+qæÌ™Æý×¾ýíoWJ¥Ò€q¬Üy`,LÃ=÷Ü3ðñ�|÷¶mÛbÃÃÃp»Ý·ö#†‡‡188¨?ÏjµªGý3338þ<>Œ—^z ¡Pïz×»pË-·`tt´E¨È²ŒÉÉIiÿþýÅGy¤üôÓOË’$ÉhŽl~ À¤vîv¤ï$ÿo�Fô¶‹ôÛ®‰vJþ‚ е¾TPP¼éŸ='i+!À:pºq ºœæ ¸ÀV-úçÚ<'ËdžaAàEQ=��ã8Á(HYîCfü“•¾†õ³AO�¹öcccz­� úæBAÀ²¬^/@~^­VCµZÕg,//cyyõz¢(b``÷Üs¶mÛ†M›6!¯°ãUUÅÑ£Gë{÷î-}ï{ß«---U\@sŽ„6ƒhî¿ÿþ�Ï}îsï_¿~½7C–eœ8qÅbq…sAJoo/‚Á Þ¥pêÔ)œ?Ï=÷&''!îºë.ìÞ½W]u�ÀŠâ… ê=ôPá{ßû^õܹsäü*h.èy ͉Ž�QÿjÚÿÌE}jk¿Ýê쮊ý(ùÓ‹0Å›—ËÅ´™Eߎ,í꬀�C°ZqÐN�[AKŒ¸R~ÃïéJ ¸\.—Ûí<�Èó¼›eYÏóŒÇã�ñ<ÏëõÆ¢¾F£¡‹’û6§Ì‹~ˆËàr¹àñx‡122‚õë×cppÛ¶mC8F,k)Z4¢P((GŽ©ý⿨üô§?­ÏÎÎëü5óhÝ=ßr\qÅÜW¿úÕkî¸ãŽ›½^¯‡a¤ÓiLMMÁ˜N’eÕjù|…BA?H‹ßÒÒòù<¢Ñ(n¿ývÜrË-ºP!µÆó=qâDuß¾}¥½{÷Ö Ä/¡9²÷8š›$«°/ô³*ü3§œäýU“èdë·‹ø‘?èJ_*((Þ‚n€�è¶V �K°`¾o>|h¦®°E,ì§vL‚À{<Þëõº=� Š¢Ëív³D�Èž|Íó¼Þ-@û˜ç]Rc@Æãö÷÷ƒ¬&©»É�ªª¢V«©'Ož¬Ÿ8q¢öøã�×~øa©R©‚Êhô¼¹óýÜÏ~ö³Û¶mÛv Ïó\¥RÁÂÂP¯×4[3™ �J¥�J¥°¼¼ŒL&ƒB¡Žã088ˆÛo¿ôG„‘‘ôööêÝ¡Ž��×:Tyâ‰'jÿû¿ÿ+Õj5cäœpÍ%=‹ÈÞ‰�l@7y~;’7F÷J‹Ÿ’?o=‚À� {!Щ> “èÆ%p*¸6€ü›€æfÁ1  ¹u�Y­Ð"u†çyÎçó¹‚Á àv»]¢(ºAà<çv»žçBðFA`¼n·»¥-ÑëõÂçóéë„É÷“]÷ÇAQ¥Ñh(årYÊårÒ±cÇ?ýéOë'OžTL„ÒÐHôšË–l Ó>ò‘�Äÿú¯ÿú×]wÝFEQP.—õ>I’�Ïç1;;‹ .`ffF_¾#b±nºé&lÞ¼£££X·nÜn÷ŠT½^W§§§ë§OŸ®=ôÐCÕÿøÇ CŸ;9—’vΧᬽÏÊòoùËpVÙ¿š‚>Gc}:à‡ Š·Ú ¡}Þ.=°‡`-€ùÑì Ø†fš ˆfŠ€ƒý¢$Ç¢@ÛÀÖívs^¯—óx<ú­Ëåbxžg4×€á8Žá8¦CÕZU–eUŽãÍ)P(ÅbQ*—ËòÒÒ’<;;«LLL(…BÁÜ2F,ì,šÅrdÀ�¥U‡¹ûï¿ówÜñÎx<$ËŒ$IB¹\F:�Æ™3gpæÌÌÏσeYÄb1lذW_}5®ºê*Œ��飊ÍÎD¹\Vãããõ§žzªúÈ#�4Ο?¯h§LÎ[ÖˆA#þE´.ó±"x Φþ9Íû«#8üÚ–ü9Žƒ,Ë”ü©  x }0†iÓ~ìÄèÆ!èTL¸ÖÀ¸”È«9ƒš;G³‹@pJømní#Œqè�q�ªª�eYÕ U­(�Qż¹Ñî~@ Í9a]å¯7n |ö³Ÿ½eË–-W»Ýn€ÞÆ833ƒ×^{ gΜA:�F8Æðð0FGGqÓM7a×®]z¯¾’$© Òääd]#ýÚ¯~õ+9ŸÏ[‘£„fQßyM¨äÑlK”a]Åßp ÌÄßÎú·Ê÷w“×·"ù¶–¿ÏçC©T¢äOÅ[6aCrv_w# º—*̯¹}š è×Ä�o,4rê Ø �KýÛo—ìœ 7IDAT;Vд÷ShZý)� ÍD¦““Ïçcï½÷ÞÍ»wï~O<‘-‚ét§OŸÆÉ“'qþüy”J%ƒA !‘H`hhÛ¶mÃöíÛA¦6 %›ÍJsss�ñññúã�?^æ™góóóæ(×x¾Khæ÷—-H»ÝÑpð=ÝÚþ—ZÐ×6ê§Ã}(¨ xÛ C·€S"즥ðRF¯ÕÁðh‚ W14‹íß­Ö _N Z|­ i‘д˧ñF¡\[»öÚkÅ�}ìc·mÛ¶ízEQ\…B 8{ö,Î�;‡ÙÙYÔj5ð<�¾¾>$ }Òàðð°:00 x<©V«Õ'&&ê'Ož¬:tH>vì˜b“F"¿»Žæ¼þ¤v¾iC´o<¤€Œöv;ò7GÿNz÷»!~Pò§ €â÷<Ï3æ©o…€•èät›hç�qÀ�Ò�D„[sBšj·^4» ŒbÄ)é3« |I‹”I®œDÎ5'äÅó<óáxÛŽ;î!’N§177‡™™LOO#ŸÏëdåõz�FåžžÉï÷˵Z­èv»Õd2Ù8r䈔Édœ\ÃHJ"‡f ß,šÝ5XÏÜ—ºtÚåúÛ ûQº þvQ}Gâ×þ~Ðh4(ùSP@ñᬕèF\J:ÀÕAD˜×» NA@d1�f±¡­S �Ï‹3½.„ Œ6tM[¿¢EöYíë¢FªJ7Qk0tíÞ½û]ƒƒƒÛ2™Œ¸¸¸È-..byyY%Ãgä&$I’êÇ5TUUÊ岪­èeº¸~Ò'ufÒW`½}O¶‰æÛ »\7Ý;À‰˜£  €âí ¿ßÏ�ívk(œ,#ZmM€'À)ùÛ�1f,þ� Í´� ­Û ÝÚ×54íqÅDnV9jÀYÿ¹™¨8ŽãFdYÞ�f[¤ÓÔ„÷BÖÄɲFú‹š¨Ãz ŽÝÚ]É¡Љô;åü»‰üWCúp¹\�$‰’?Ю@7bÀJ°EÀZ²n@»•ÅŒ‰Øíj›çÝ.ZT»Ó¨5ŠfëãVÍ•èæºdõ!üš‡)-Ê/„ŒÕ||sôoR—·íZü.…üíˆß)¡Sâ§ €‚Š�.Å@§®�NÅ�\Ž@7‘¿SÀ)ù3mHÃJØõš+hß’& 9üèz4 ™U�?)Þ“´È~Íúƒe4Ó²ÍyšE@'ë_nCêv…}’ÅÏq²ÐÇ ñ;Žö ¼^/Êå2% *(¨ sïütrºq8t—°v‘¿òg»$ÿÕ µM”p3šc�ù× BšÐH=¯=F¬ü”öxÍ@øVço&Ê*€kßi®ß®Úßîõì*â'‹ŸªÕ*%~ ç×GúPü>ØÿôûýL¹\Ö·ÆÙ�c¸el.¾Š ©š/èœÅ}Î""emîËm€1×ßnš!L÷Û‰€vä¬nÚ\X‹ú—Ñl·“`¿ÈfÍ"CR|X"o£éç¶/vsò•.€{[_²ù�fú;]Ïk÷:¶ª&m#$!|EQP­Vé<u((œ@E¦V«Ù¹Ýt \ê"¡N9þN?Ó|€uÀÉß½Ú†T;=fuŸt# _í D:Íl€òï&ú·#r¹ÃãÊ*ˆ_q@ü–?Ã0µZ�FøTPP¬|>Ÿî Øü}8™$ØÍfA®Ë¯�¿Õ9ÁFŸc»é~ínÕâè¾¾‚éð½íγ›è_±!r»û V·ÁÏIÔoKü´ŠŸ‚ Š7ã�Ázÿ@·ÄÅ¢û5ÃÝDùíŠýØDÚ�hGNNÚѺYå ±Òn¢¡�#¡Â~™N'ÀÉ­‚µ[âc'¤èÄ>Š7´€‚‚\‰›\«¼¸‘$Û&´ ¾™¨Ø6D¥¾‡é@üÌ’»hº“ Ð)êG҇è¿Sä�¯©ÐNØ‘¼lóóœŽóíõÓ‰}TPP¼…´�‰Ð�ˆÖtk'‡Q~»ê~côÜÎö_Í §ÿf':­kî$œˆ;òWamÉwN�v¤¯˜¡#òE•J…’?Å›š  0Àãñ06ÕÔÝXÚ�F ·«Ú_Kâo·1щèYMÔ�._'àÒç˜ ÿìVê*«+^?–e¡( % *((ÞâÝ®vz°«øw§Ñs7«€�DüªÃ×m-òþNuj‡hÞN(t²øW3 ©´ÊŸ‚ Š·º\=ìtŸÀjÅA·Qs7¹ÿN]N]‚ÕÀ™õï$ú‡M4Þ.Ð)ªïDú«žäG«ü)¨  x{ÿ�8! d× Á¯&rfVù÷ÞMäßéu¸T×b5@' vqß ñÓ¨Ÿ‚ Šß'´) „C²í$œ8€³JùN¢äRó¿1D‘SÔ�Xi·¡Ð©à„è�n:ìHü4×OAÅÛ,Ë2 9!åNïœÞ·Šš»%Ônœ'×’n…M;£ù;q”.ÿ pVÑ�NÄOí~ *((~�àv»™z½Ž×õNmx�}5ÿÖMô¿VÀéóêFÐXý\µƒàD\J¤ßõ¶>·ÛMç÷SP@Añû —ËÅȲܭèDœ—rÛé÷¼דKq2¬~^»QÄ«@÷“úÚ-@j�Çã¡«y)¨  øC‚ƒî�v$×éþj{³þÖ;¥Úõù;MW8]Pä”àÛ¥:ýΕ/µú)¨   ši‚F£�5N½ÛïcÞÄ¿ñn\ŒÕ*¢� :¼ßÉÒïvÙ‘—Ë�ǃb±HÉŸ‚ ŠVˆ¢¨‹‚ [BwJ —ëï}µ]N¢þÕºÝ< ,Ë‚çyšß§ €‚‚¢{¸\.F’¤µˆ¶Wû÷Ì8‰p/A|t3˜¨[Ð ù·#uÇy}†aàr¹è¦> *(((Ö,Ë2ªª¢ËT2ó&ÿ}w;&ÙéýÕ €n Ý�>Ã0´Ÿ‚ Š7n·›€Z­v¹ÿþÕ.¯ ÝÖ+\jqb»ÑÄ�¿Ý÷X½æÔÞ§ €‚‚â­ Q™z½ÞÊzªê´øp-¯!ÝÔ*\*ùwÚSÐÕCŽã Ë2%| *(((þ°áõz�e¹çáÍìFP»VÏår™’>í  §a×—Õ^sV³™°%Âç8õz�>Åjàóù†aÖz­ñš‚ Ðà†‚‚:—�‡QUõr)Ú‚çyptä.…ÿsWÑŽgÆŽIEND®B`‚python-msgspec-0.22.0/docs/_static/pioreactor.png000066400000000000000000000535221525673062400220270ustar00rootroot00000000000000‰PNG  IHDRóó4ôKgAMA±� üa cHRMz&€„ú€èu0ê`:˜pœºQ<leXIfMM*>F‡iNHH ó ócС£ pHYs  šœ”iTXtXML:com.adobe.xmp 72 72 1 498 1 499 5 ç@IDATxí½œ]Wy¯ý?ýœéš¢)êÝ–-Ùr¶qÁØØØtLKÀÔH!¸)$—|á¦ønH#¡¸¹˜jl `ll㊋\%˲%Y²ÊH3šÞO?w­±…mq$M9míóìŸæ7š}ö^ë]Ï»ÎþïwUß5›̉€ g ø�µÃ!@˜&€˜S @Ž@Ìw æC€sê @Àqˆ¹ãÄ|@€bN€ 8N1wÜ�˜@@Ì©€ Ç æŽ;ó!@ˆ9u€ à8ÄÜqb> @1§@€'€˜;î@̇  æÔ@€€ãsLjù€ Äœ:@pœbî¸1€ €˜S @Ž@Ìw æC€sê @Àqˆ¹ãÄ|@€bN€ 8N1wÜ�˜@@Ì©€ Ç æŽ;ó!@ˆ9u€ à8ÄÜqb> @1§@€'€˜;î@̇  æÔ@€€ãsLjù€ Äœ:@pœbî¸1€ €˜S @Ž@Ìw æC€sê @Àqˆ¹ãÄ|@€bN€ 8N1wÜ�˜@@Ì©€ Ç æŽ;ó!@ˆ9u€ à8ÄÜqb> @1§@€'€˜;î@̇  æÔ@€€ãsLjù€ Äœ:@pœbî¸1€ €˜S @Ž@Ìw æC€sê @Àqˆ¹ãÄ|@€bN€ 8N1wÜ�˜@@Ì©€ Ç æŽ;ó!@ˆ9u€ à8ÄÜqb> @1§@€'€˜;î@̇  æÔ@€€ãsLjù€ Äœ:@pœbî¸1€ €˜S @Ž@Ìw æC€sê @Àqˆ¹ãÄ|@€bN€ 8N1wÜ�˜@@Ì©€ Ç æŽ;ó!@ˆ9u€ à8ÄÜqb> @1§@€'€˜;î@̇  æÔ@€€ãsLjù€ Äœ:@pœbî¸1€ €˜S @Ž@Ìw æC€sê @Àqˆ¹ãÄ|@€bN€ 8N1wÜ�˜@@Ì©€ Ç æŽ;ó!@ˆ9u€ à8ÄÜqb> @1§@€'€˜;î@̇  æÔ@€€ãsLjù€ Äœ:@pœbî¸1€ €˜S @Ž@Ìw æC€sê @Àqˆ¹ãÄ|@€bN€ 8N1wÜ�˜@@Ì©€ Ç æŽ;ó!@ˆ9u€ à8ÄÜqb> @1§@€'€˜;î@̇  æÔ@€€ãsLjù€ Äœ:@pœbî¸1€ €˜S @Ž@Ìw æC€sê @Àqˆ¹ãÄ|@€bN€ 8N1wÜ�˜@@Ì©€ Ç æŽ;ó!@ˆ9u€ à8ÄÜqb> @1§@€'€˜;î@̇  æÔ@€€ã‚ŽÛ�ù€€ãAŸbµ~EkŠÕýP8âS:•ÓÔDVSSÅ'2æwvúw*™s¼Ô˜�Â@Ì Ë“Ô �ç ø|RSKH]Ë£Z´ýògÃK9Ñ�àYÇP°“@ÌOŠˆ P¶y;k½èjnóIK«6Ätù›Ûô²K›§G¡—§Ô•‘k0ä3] uÓ?ïþÃŒ¾gH·^߯m÷�Égžš4ÃW†Ÿ°âˆù ,<÷¿È‚¬¢-9…b¦ÏÓüøLg6!¥ÍObاø€_™¸çŠí©™±fE;ìËBÎÔ…ó_Û¨7¼«K«O¯c XÚ5u]ôêV]xe«zº§ôÓëzõ³ÿÓ¯L��sypqªLó2�/d¶ö¡ ›þä5æçÔŒ¬Í¨¶+«@ä$¹˜û¬¨�ìõkä速ôk²Ï¯\1ä$&ññ rƱ62/t+»­/™©œ6]Z¯·þö"�zf‘æ Ø�û?�w.ŽéŸ\®×þf‡nøÆaýü›ýRؼ(—q€âq 惪"€˜»ìî”´`CVç§ÕvfZA}Ïê0§È‚œ.ÈháY™éúè>¿z·Õû`@‰AsA¡•dVV÷ÅFs ÞgžšÈiÝ9µzûïv錗5)èÀt²J¬í‹£úðŸ­ÐLÿúõÿyX·}{@þ(¢^‰¾ª›s=�5Mãͧeµú­IÕ/ËN7Ÿ¢6b«_šUÃò¤–¿Z:xgHn *9â#ò(àÙ¦ñ|d>ÛÛò]ŸœÌiéÚ¨ñNm¾¤E‘¡d>N³:g#õ¥1}ä®ÔßÛ©ïù�îøÞ µFÔy žJ.ž?Ä|þ K–BÖDâõ‹³Zõ¶”šOÉÈ*NÖ¶™=hH+^›Rçyií¿5¤Ã÷”ž"R/ñü©ÚùÎ6:ŸÏ‘Iç õî¿l×+_Ó®j˜Ò7^s¹× ÷b³\íÇþz•õýŸÏÔý7 «¦…¦¹ðäž¹@ÌçÆ­¤wوٟ”Ný`R›Ó ˜>ºRVÔ#Í9­ý�¤º^î×®†4øˆEÇ3ªø§Ç.Ì'À‹eµé²z]û±%Z»¡¾$6Ws&¶ß|ùšZ}âó«õË«ûõÅ�T&šaJ[5WŠ–1/!ì¹d•3�#‘œ6þYâ¹&õ2©µ¡Î´l|B»ZÃ:|{PY;z>J3UvOÆÌù6³.µ�+® ¿Þû—]ºâ��jXÀ×|ÖçqƒÝDæ²×·O,üÚgèÞ ©¦µ _Üy”�[Ý#À·¼‚}f§‘5­Êêô�$¦§˜•ÓÔéÖ3Àç”·´¾ï'A¥ÆèK/¦O¬(ÏVÊcf,Å™µzß'kã¹MÅ4�´OB Ëô§ÿñgWéåWèßL”ž šV5ž„Ï•b>WrE¾/3júá^�ÖjÓ?ª-@çi�ìÍå|ZqUJ±–¬ž¹!¬ÉƒFЩE¢û¢dŒËí†&3sÛ%’”ÞòÇízí;ºÔÒ^¢¾˜™Ì�€Ý£ýW/Ô)ô�ÏÐ�ßTMQú¯“âÌ| ðž/Á"ÜŸ—º.3BþÖÊò£Eµñ:7g”Ë$õÌ�aM6‚îþžG‹W¿íà7»µèLÄšT´¾r…ühY³iÓä~YJ—f巪óé(šyÿÎÚ9æ'‰Ì§†³Z·©VÿÂJ�uþ‚yçIÅ'`ûÌO;«IÿãuZaF¾ÇÍ‚b^Š…HÃj÷€´ñOŠµÎ¢³´yÏ5 +Þ¦­º2©¶‹M³»‰Ö9 CÀ¶tLÏ8NrãÝY]üæ&}ô3+´ŽigÇ¡T¹§—¬¨Ñ_|y�^ù–V�î³SC8 0?ˆùüøìîT¯´æwSj0SÀ\ZçÙŠNÈ´",½ÐØ~ºYIÜtpÌŸ@ÎDåy#só5¶+«k>Þ¦÷ÿñ -YY3ÿÌH¡,šÍ4ÏßþÓeúÐçkäQóÝ¡e«,~ðJ¦ˆyxÒ6¯×tä¦×XDÝûFÛ¾ÝfEºæõfs;ˆÚ½"T@-x© v$»�Ì_Ügnö£�åô�/tê\ª¶NF¬¿”š{Õ5õºßèÒ§o]¥ÄNŸñ9_÷¼X#æà‡ôŸV¿/©�rG¿Ë¶ÿ¼ë¬”êÍÆ/v~<ÇüØ>óç�y>S/†Ëêý_j׫ßÔ¥ú&&¢Ì�påÜŽúõ²‹[ô×·¯ÒäV?‚^9®qÊļÌî²Ó¼7eÔbDÐïp 5½JœÙ¤¥ÅlÁjȱ�ê<ëÕtŸù‹†N !×?.dE·yr­ÔÛƒ!Ÿ6˜�qÿëÞ•šØj"tã{̆b>ZE¸6½Ã§Uצt8*?Še::?7­†3Œ˜›�Ý8æNÀö™Û{ oÍèÍŸiÑÕoéRs›Ão|sÇQwZAßxÎ}殕{œâªpz ‰˜æl“Ê™¾æ† 2j\f¢ò"í€6[›æs½�&cmY5-{.:wµË`> u¯�Ì2¦~ («W¼Yo|ç"µ/Š*yÒ©P¡°Ogn6‚þ‹•AÐ+ÔK•ib^F¿d†ÌÂ+—™]•<lå²>5¯Ì(¶ÌDLU›sí²}æ‰DVW_Û¤·~`±™-69ªƒ@(âצó›õW·®ÔÐãŒr¯¯Ï¿”ˆùüÎ9…¬Y×¼í+æî|;¶ðvvÓêŒj–1gšÚ±xfüwÄ Š:ó¬f}øSË´l ÓÏf Î#†� Ÿór#è?3‚nÆKØ™ 8ÄüDtŠø™mb¯??«p�ù–zÉ ¶8¦¥¡Öì¬l0yÍ©ÕÔtÞeÍZ¾¶vN÷s“ûì ݹ5ëOo\¦žÇ̃' à%9A1+ï£ì”™›mF±û=8ÃÈî¬V»0£ÈB�³¸UåU>,r†€Ýum³™¶öžÿÕ¡áí|™œq\ EÌËÝf™1SÒÖ˜�oºz,zµájÛs ·1' (S #[¯h\Ò›?Щ3^[¯ø(sÖ¼â×B—1/4Ѧ—ëó)Öa–nõâv•æå$Ò”U°ÞÀ ˜˜a�à2Ÿ@k»ÙBõ³Ë ÉnyË�c æÇ)áß±V³\§›ÙMðiÊM¯ÙnfVq@ е´Vñ£åx´x¡ç ê­$ó2øÓ~C¦zº‰½ ù—"KŸYT<2e´óçyð”9yxœ€]TfÝé�úß^ª^ÄyÜÛ³/b>{fó¿Ãˆ[  ¶Ÿ¶­^ly˜ Ì�@¬6  _Õª·ýy;[§Î ¡gïBÌËáZ+æfÛP/¶õÁoÆø<°²�—ýDÙÜ#ÐØÒ;>Ò©®•1¥âÞ~ޏç�òYŒ˜—‹½×†Ù½;ís†>órÕ0òõ0�æV3 ¨g‡y� çöôÌ‹†˜ÏœUá®4B—}ñNÕ…KºRR²¥³«Á15­R<‚^"`ûÏW®«×»?Ý¡‘=^� ¼ä¹â•1/Ûã¦l‡¥zÍÇ£¶…díe’æ?t»O{:aöef³•rÔ0ò¬-¦¹ý�¾³D‡Ÿ :¯—·˜ˆùqÑ÷»ŒëD�;®�æ3µ*>äWÊt%0š½¸õˆÔ«›@جß~ÚY�zýïµhâTª¹6 æeò¾ß¬[>yÈoÖ.÷^ô´˜ú”5p½¸Â]™ê ÙB �-a½ó»”íö›q*mêËWpν„bþ¥ûÃovzÒ|ù<اìóç4ÞãWâ‘yéj9U3�…1ý�inïÝJs{µÖļLž÷EŒ˜?`Ä܃-cv€ßD¿_I+æÔ°2Õ0²­&1³»Ú¹—4é”ój™{^MŽQYyÔ¾F)ÿkE.±ÛoúÍMS»‡úͧËeúË'�˜g“†¨÷zJYMÈ 3&PßÖ»ÿ²ó¹¹ç3¾‹ ½B1/£'«sê¹70=êÛ+¢gw�xÚˆù³&*7­€@iDì`¸³´é’:%§è;/ õÊÉ1/£/üµRïOžÑî7ýå#šÚoÄœÁoe¬]d]�CzןwèðSô�W›ÿó2zÜ6I§Ì\óÃ÷•‰»ßm§Û îhx§é:°��ûE*cí kÌž@8âשg6hó•õJN�Ïž »wxp7m·œh“ö|%¤ösÓŠ9ß,�ÓáÇCÛîgƒ·ªá¬­M&²:Ò�PïÁ„ÆGӊdzŠOd4e~Òfz”•X, H�_Q38«¡)¨Î¥Qµ¶‡ò–7k೸¡Áô�_û'�ú½Kwjù&ñ³@çô¥xºÌî³Ñ¹ÿvà¶ V¾6­`�y›vð…ÚFå}�4´Ý7m¾ÑÎá “ãíÞ>®mŽiÏŽ Ú×@oRv¹ÞÙøÙ¶Ö„#>µu†µhyL+××hù Z±®F#ü…! û´æ´:½üu ÚóÔ¸"u4À†le§‚˜W€‚MÒþ¯†ÔuqZuQc�kBhìÍ¥sêÝÒ„ib÷Ù2p8M ûÙ)Ýwë�¹gX{wLÉFâöÅóÅÇl„ÜÞg¯O%s:´/1ý³åÎa}ë_©¦. UFØÏ¾¸I›ÍôªŽ%T sžËÿmtþ®OtèCïÔÊMÇ8n. rOÅ@Ì+ÁEV [¤goiݵ)…ê܊Φº7¨áÇÌCƒýË+¡FÍɆ‘Á”ºkX·ÿ°OO=2a6¤!ò>VÈç”Až›ü&�ødFÛÓ[ÆôÍ<¨SήÕeohÓ¦ šTošç9fOÀFç+O©Ó9תçH\á˜kÂìË\íwðM©�0#Û»T㚬º.L+àHÿ¹m^1óåÜ2ËÓúäWP̘1�#‡âúÙ÷zuó747uÏôi—c&‚�Ü3Ùœ¶o×ÖûÆÔØÒ•ooÕåo\hšæùB̘zñ/ŒÕõšßjÕçß½_ 7Ñ�Q|âåÍ1//ÿ—äê�žú\DÑöœZNÉÈ e%6Z‹øôÌÏÃÙê—Ÿçm%»ë×l;Ò×MFÄo¹î¯”ÁiÖ;°î»_<¬Ÿ}«_W¼­UW¼Ùˆz•ì×yœ5µm¾ÔôáéÀôJ“¶„ûpo%ùÖD&þE9=ñבé•á*z œí0Û›>ó³°~iúɉÈ+©&�Ð;âüæë{ôGoÜ¡¿Ú«D:S±#Ì­¨OŒ§õýÿ8¬O¾s‡yùèQbʃk ŸÐcsÿ°¦6¤×ýq‹&ÙQmî¹1¯0GÙh7kšÜ·þCDSfç±J=ü¾Ü´�÷Þašïl ^åšZ©Ëb×®ícúìÇwêŸ?±_q3=rÃqÖαá”þã/öëï?ñ´žÞ:V~®eZWÔ•ïhѡü¹æ»ÙÚ‹˜Ï–X ®·{€ÇÇ|zø¯¢Ýo`© ï¡í×´k®?õ½ˆüwГ»¾•ÀÅ%Ï"iæ�ß|ÃaýÉvêñ_Ž)Ú䆈¿”19XãÓcw�éÓïÝ¥ë�Ò)çq¾¤PÅýöl,ZV£Í°KqI—?uļü>Èk�ôĤô?�ª›YòÕ4i—û8ÚG¾ý¿":x“r»b¤ƒšPnŽ¥Î|4£}§[_xÏ©>+Àm§Yû“¹Œ¾ú©n}÷?÷ij¼‚ÞvKíÜä7=î·[5¼N3Àåì%ˆy»ÎŠg.&=ö™ˆöÿ"¨tÜ[¦ç°Œ7üŒ_[¿Ñ³9Œ�¶ÄQù†úRºþëûõåß;¤Ø*3J½Lõ§Ð¤l9 Ò·ÿ¶Oÿõï{eËÉ‘ŸÀô@¸Ëe†ÔVT+_~k9;W�õ�üô\oæ¾ÒðAx8 ±ƒ~Õ/ÍMÏC/ÙCÙ<4m³ú~³BÝ®ï„5yÀ v³}äe8Æ{²:ÿ Z}j½Âf‡(Žè9×·¿|@?ø»~Õ¯2~óˆ�-õ´ ›ïÆö;'5�kÙªZ楅sÌoÓ�¡Ñ©„v?<©p­Ç*Â1e­Ö?y":ây+èCf“L³û“_kÊì^ÔÑîæûnûêí&0üML»��'‡MdG�q¢ÆìÛ5©¯~þYýôßT·ÜÛN‹6ûtû7‡ô•ÏíÑî'Íb7¿F  ê‚«5ÔMSû¯Áñȉ ŸÉìÊ…*†X;¬×ì³âÚâ«ÓZzyJ‘ÆÂêßÐÞ›ÂÛýü[/ì#{ü²?/9Œ€O¯™nNÛÁlEíkIÆüQ*Y³é–ûúôÝ�÷kÁ™e¡XªÂž$ŸšN¿~þï#êXzXo}÷2Æy<Ï+f–wÝtaƒú•UÛôJO'ÉÇN8æ©ï”í;SFèm4žM˜ ß½>S+¸®ˆ}p@ßüL¯jN3ã*ª¼�Å–?Ø’ÓO¾2¨;o>RDên%=Ýrg¶F}Ù¹uJ%x¸å½“[‹˜ŸœW@ ¢ ì}zB?¹îˆú{’ š~c3È,ÿ:ؓҭ7˜í\cé×£u"lšÚÏsƒ&÷3ªý(¯üF̽âIÊQ•ƆÓúå}ºã_GU»�¯ó‹+A¤Á¬ xã¸~qK�FM?‡b±€Î¹Ô4µ�™{­:ðí÷šG)OUxè¾~]÷û}j:ƒ¯r>Ç×tùu‹é?¿ý¦Ãù>®ºsAÓb±dE�:2Ë1#è^ª<¼äMÊRU¶?2¢¿Ü'ÿ23%‘or^ßÛEŽ²Ñ¬nûÞ�¼s0ï5Õv2ôkÓµµJ�{Êõ<<åN S-2f@ãÞgFõÈ Š˜éXÇ'Šú´ëæ)=½cø¹]þŽiU|bÅ|í¦Mí'2÷’Ãs/y“²T �Ý;Æt÷�GÕ¸!Ÿ‰Ó£Ë|zäŽ =öàðL.÷ô5áˆ_k6Ôj,�˜{Éш¹—¼IYª†À¾}czà¿Æià+<§‡b>=õÓ)í|1·b¾b]LŒñŸIÍqçžîø K!0M`ÏSºÿæÕ,fNùŒ«„�{Þ.=~ϸž|‹D:}IT™ÑùŒëP…_ˆ˜W¸ƒ0Ç8°Twÿë˜b-|}�es¢¿íR¯ÛLtþÔ“C'º¬*> üZE ƒà<ämžr&Eñ>�ƒf“Œ-wŒÉoV8c;ÚÙù{ze¼XNO<8®=;ª{«ÔPȯug™ApϙϮUîÕˆyåúË ðkö?;¢»ì1‹øökpfpÂ.$óØM“zr[uGçv%¸Õ§×˜~sÄ|ÕÆ‰Ks'Ü„‘�ú'õøcšœÈ˜]ðó¹Ô Ûš�gôäcã:´/>—$8©mwOªf5B>‡}zæÑ„öîŸO2Îß ™Ap«bJ3EÍy_Ú æžp#…¨£c =óÓ„ì"(s'`7a9üxRýýÓqéÜrüN¿ß§ECʰƒšãž|Î|ÄÜn¤^'�4Ü#‡šP†�oót¶ɪ¯'¡ÄTõ¶1LWMûòˆÒ“óÊíA1¯7`NLàHw\Ï<1¥Ú6¢ò“šÙ§áŸîNêÀžêU2™/\Rª¿z_hfV[ܸ 1wÃOXYåúÚóXB‘ļU!“íLª§»zÅ<ô©mQX‰D!ˆ’F¹ æåöùC`lùþòb>\'½dºß|kJýÕ;¢=`6\Y¸(bF´™Ÿ´Â8pb0±º $¦²ê5ÍìqúË Vl¿yb2kÆ!®Ù‚¥ëRBvoóÖŽ�Æs—Üv\[óã¢áT;ðmÏ“qÕ.$*/¤G"füA·í7ß[�£Úí M]cPQ3©)Gp^ȪU–´ó²`'SÌœÀ@_\{�+ÒŒ˜ÏœÚɯ ÖHÝ;S²ó÷«õðE_^V6ƒš»^s×=ˆýž'06žÔÞ[’ Ò_^P_ûͰÞ'SªÎÈÜ´#Ú».›ÝÓ Š–ÄÊ@1/t²„Àl$i�(ÍüòÙ@›Áµ¶™yêpVSñô ®öæ%VÌÛ–›…câDæ®{1w݃Øïiv±˜‘Á´B¢‰½Žö×IcÃ3®:ÅÌgÞhbµ~e«÷}¦Õª,i"æeÁN¦˜�‰Ñ´†ûÓ Ïìr®š%�`ƒó¡ŒF†“³¼Ó;—Gbfbî¼Csç]H¼L`b<­¡¾Œ‚,S7ûÍ8„ñ¡¬‰Î«SÍldnÅ<[½ï2E©WåH1/uò„À Ä'3íK+hšƒ9 OÀoš<ÆMd>nZ@ªñ°ã¢VÌé3wÞýˆ¹ó.¤^&�Ng§7ñ¼\Êò•ÍŠ™—�JUçÂ1¶ü‘˜OÙê��W¾ÊWàœó%9’@ÆÌÿMƳò™®8 OÀgž€édÎìé]­bîS8júÌ �–KL1/1p²ƒÀlX1O™&P+:E `Þ‘žóê”3[¯l3{¦hI²´xD”–7¹A`VìÊ\ˆù¬�ÍêbÛÌœ6ƒ¿2é*s  (Kl>«zS‰#æ•èl‚Àó2YÓÌ>e"sZÙ‹S'¬˜›>óL¦:›ÙÍš1ӣى̋S½J™*b^JÚä@ ‚Ø—ÄpÔG3{ùd®¦ æs%Ç}(�€ �Âf´1»Z ¶i]·kÞÕù(´� 3+¯:K_¤:U¦dña™À“-fBÀoF±‡L䔫ÎVà™ š×5ö%)hæș̌+ÕxØz•0³%˜ùè¾÷s÷}H mËD|ZÌOˆ‰ P�5ØÇ`",+2v…®Ã�‹R!¬˜…MŸy(T��B[þä”�Ì9\'t½ØÿRf“¾”šÃ#ZTShLQÜü¤Ì6«d.¨D.¬‰T�úÓMêK6k©Î>×ҫ¼¿¢55´•7¶5Wž}®[d7©[P]Cu> sFÍmŸ¹ŸNs׫²ª³;ï¶—À¼\ki´Gkcûµ²æ€…�(è›ÙÆVà‡2 Ú7Õ¥ÝSKµsr…÷èK3௲¨­ jA[@éãå¥e3ógÍóº~Õ7Uç£ÐFæ ™×zÖÅUS°ê¬Áp¯�¤k“Ú\¿CçÔoׂЈ9ce}v‡m`k ŒkcÝN�Q÷´R¹€vM.×}£›´/Þ®Œù›£|jMÄØÔ;TÇéQ©ÞDæ�MÕ¹cütdnÅÜt5p¸M1w̶ݯ”.i|B6=¢ÚÀDÁJ`Óú²:µv�Ö×îÔÓ“«uÇàù:�l1¯ |Ù z ÙþÜÆæ ñøì_Ôf‘MÕ^š5ÝõMEjª³~OGæ“&4UmðLÁsG\iåö‹wvÃ]Öô�é *ªå9Ó³¶fïôÏãã§êΡ—éHª¡¨y’x~‘HP�Ævä5®äg4—³öûëô+­ÞÇ e·‘yõ"˜KÕ©È{paEºå¥Fer~5‡tmû/Ô=P‘§ÏE+gÖíÐiµOêÖ�+ôÀØj3ˆ.DœþRõ¯úº°V\Öáý …ÌÈvŽÂÈšÍUÚׇռ V˜LÅ6³� ¤å¯Î^=v|“™‘p|6ñIÒôY¯ªÙ§ßYôcuE÷—PÈ_(þsÍï~½¦í§º²y‹êqF¿¿€§èÿki‹j妨ƒ¶}†£PÒ“Ò¢µ!u.®)T’Î¥“5ùôìJ)`æÚs¸M1¯`ÿMeº¤éq½«ý5šif¦‘µ¬ÖfÌ”¶ ›îÓ5m·ª#4ªl®¼ö”F 3_ØÑÊõQMAÌ ‰=Ñ—Ó¢Õa-YQ½‘yÖDæNšål I–´ÊA1/õä9•õéíwêŠæ{ÌñÉŠ€–6‚~jín½½ãZë7:G± Db~µ/Š*jVÐf�öÂж}Å‘¿v®µÕûL§²Úg†WÚ=8Ü&P½µ¸‚ý6ž ê�­èŒÚí ù*oR’�®ÖÔ«ZnÖR³8Mš½èµ©¡>¢Õ¯Ž(eæEsÌŸ@&•SçÆ�Z[ªwM…ŒY"xðHR±2·øÍß›¤` æVâ¦iýå�ÛuNÊøƺÊ|cΘ•äVDéÂ÷kahœ&÷"×£–VÓÔ~fD »x Ǽ ¤§¤®µau,ªÞþò´y¡é;œëÅÌ»:UDˆyE¸á9#ÒfÔú²X·®j~P5þñŠiZ?¢T.¢³êÓy�OšlâoïñÊáÂù…¦™}Õé1M˜~^ŽùHöä´Øö—¯¬^1ϘÑüGº¦û¦2†ù{¹ºR@Ì+Äßv0Y̬Äö ï1£Å‡œÆT¶F/oú…Y…ÎŒ´7KÈ"5Å©Pvñ;®–~óy¶ýåÑF¿Ú:"Ó›ØÌ;AGÈd²ê;”R¨1wÔ…/11 Žòý1júɯi}ÐÌ'?bŒpçËeÅÛlíb¢ó_hud”þó"V!Ûo¾êjÓoç•i>˜§ûËÏ«µµzG±[~vZZïþ¤B¬5ŸêT1÷"æà Û¼~Jì€V˜ŸÐ 7H©³eBÖ ˆ[ÒššÝª§¹ýW\ ý;zÃE5šÜ�˜Ï‡mr$§U›"Z±¦n>É8¯×»×LK‹º<8½ˆ@Ì‹w¦I�gý¦Ÿ|«™‚6âLóú±eKg£ÚT¿VEÆMt~ì§ü]m�a�ñ²zÕÔ”5bŽÙ°Sû¢Ñ€ÖŸY§®eÕ;’Ý’³‘ùžÛã ²úÛì+RÞ�˜—Ù)v…·sëv©3rhz““2›3çìíîk Á)­«}B-Á Vˆ›3É߸ty£.þHƒ&ºó“Êÿib4§3¯ªÑú ò_P%gíKÍèPJ˜cî�#æevå„�sù‚ífðÛ˜³QùQ„é\TgÔoÑ �8¥RØß‹WDuî+ê•0Þ²bϬàÚ�ošòéôÍuZyjuOÈJ$²Ú½}RÍ�Ï™•³«ðbļŒN·}åëkº§w@ó{`¸]Ã=ÈhqͳÓQ:Û¦§r-YÚ ‹>R¯©Ô|6„“ã9m¸:¦SÖWwTn™¥’íÞ6©Ú$`6u¨’¯Å“eôΔósÍÞáaÿ„óQùQŒvýö•ѧÔŒ�…Ràß+O©ÕyW6jòàsÛâ8yo&g¢òt¯tÆ…uZV½7Ë8‹R¥ÓY=õÀ„¢­ ~›¶Š¾1/“{l‹_6—1û…÷˜ìv¥7ove¸E‘ýjÙõäé×-–W—-«×Ë®­Sb”è|&ŒSS9�b¢òµëšfr¹ç¯±sÌ·Þ4© #Ù=ãkļL®´{”¯Žö*äŸ2�ÓÞz;öû‚j6‹ß$<ÓâP¦jrÜlWŸZ¯‹^× ‘=¼0Ò‹>ˆïËé¬WÔêÌ͈¹� a×dï“ÙÇxQ-qû¿¸²LþKY17QyÀg—AõÖ‘Í…´0bÆ’¦õÁ[e«”ÒBÒŠU :ëMµJ˜¾`Žã°‹ì¬¹2¦u§6ÉÏVŸJþjð�ÿã×÷>Á›eòYÒ<™…V‚Ó»¢y+2Ï™%G›C}f™4SÔŠX¿N;«Qoü`›²û|fÎp3r8i;âß÷ë²·.ÐæKš.IáLO&³Ú¹uJ5 ½õÜ)!7SBÌËä·”iZo �›ÈçüVýæ?µiøqÔ<ÁÉCY]ñáF½òªÎ|Wå9;øíéû'aMvOù1/“;ʨ10e–ZñÞCØNI«5»¾ÕøS†.MÀŬbõMA]ðŠ6½Â.$sÄ{ui>ìì1g¿±N—^Ñ¡ÆfÚ×�²ŒO¥ußíã 1øí(OüFÌËàF+vuf sA÷êa›Úíྠ[*Íg+ÖÕê5¿¹P­a¥mÿ ‡ìf*Í!]þ¦6�r&SÑŽV‰øTVOl7»ï™§­ìG±xâ7b^7ÚÇmÌgÚ½IùŒ�§Œ¤g‰ÍKPÇ6mnÑ;?Õ®ÉíÌ=·+½¥Í y¯ù­f]råÂÐw'‹„‰Ê¸uD�Kyô»ãµ™YŠGgÆ© WåÌÞåaÚìjeÝ«¯Ç¾éýÍýž.cA«Å¼³£´Ï=¿Moû\«†ón‹ÏL MÎêU¶ŸüÊNùx½Y2�Ñ]_Q´É«Ï�—·ªþ ª—ÁÝ>#p)³ÁŠŒ¨{·O9g¦¥Ù¸ÜËe,Cå9A–-í!]|E›Î½¶^ña/·ú‚]²õôWÕêWu¨Õì2Çñ�”ézØ·kJƒv~y1�Œ7þ‡˜—Á�ökφl¯Ur/U–9³œkÈüPÅJEÜæ³vC½Þÿñ¥:í‚:ÅGªKГ9­ÛÓµ]¢�ç6”»yÅ'3zø#jnôòsÇ WÅHž´EÁz²DsšÌÚ¨ÁDç=ìx€t.2-æ<:Jëäuëõ»ÿs…Î]£&zªCÐmKÄ9WÔéC¶R77–¸#¹%“iýò£ªYÄcß—ÍÊL¼:+\…¹ØŠÛ”Ù�d"}¾º0éVJ*fsNÅMù&§ËG+‡_–­©Ñþx¹®þp‹ÆŸõ¶ Çszå;è·>¾R«×W÷֦ǫkvñœáÁ”~tB¡¯×Çãäòyž´eòž�Ëû“u&rõÞüWŸ/«‘T³&3~3�ž£\:–Dõ®ßY¦ßøôB�í2³ <6kÍ–'9(½þ÷Zô¾ß_¡®eÑr¡®ø|§Lû£÷Œª•odÅûj®ò¬�+¹yÞ6ƒàz“�Ï‹¹·ž²v!œ¡”‰³AóèðVÙæéö’ß¾ -¤kÞ»Tü—.M=cö±óˆ;l92£Ò;þ´M×~x…l99ŽO OëßTÃ:ùǧäö'x¶Lþ ™èõ™x»ó¨ç†ÁùÌüò¾Ô"�dÂ,LQ¦úõâlëzýÛécßX"�™W-³k–ˇµ?ì èŸY¤·½™bu<ÆNäOË«·;®{oS¸†&ö±rù3ïµñ:â� ‰ÌŸšê˜ó禧yçKæWR‰N�f"fˆŸÛÂáHu:©™á¨_W¾©S+×Öéº9¨-7�¹7רT¥´Ù—ü¬Ëëõöß^,;Ð�ãäÆÇÒºõûýjoõî€Û“Sðþ¼Ò–ÉÇv�XÒ Ûo3sνÓDè7Ë·ö&Ûu$U?=ϼLxÉö8ÖœV¯O~n­>úK §—==Î¥uÚ.ÏZßÒ‡þz©þÇ?¬CÈgá�©©”nüÌ j»¼0Ì¢øUs)‘y]]ãÏê‘ñåZÛ§P`ÔÈ»û_¶€RÚ;µV½©¨Ùލ¼ŒÕë¸YÇjºòšm:¯I7}¯W·\7 IÓ§V^ýˤsj0"~ÅÛZuÅ›ª­+rÜrñÁ¯°s˹wD‰é…bxÜÿ:!ïœÁ»eô¥í7t|™^ÛÜ #æ^8²FÌN­Ö`:fÖfGÌ+Ù§ Eõž?X¦«ÞÖ®ŸQ¿ù›•#êVÄ›Cºòí­ºü�FÄ;ñ¹Ô¥É‰´~úµ5¯¥‰}.ü\º1/£·lS»_!Ý3rŠ®hRÌ?áttô%õÄø™Ú“h2m ¶1/cõšqÖ »¢z÷Ç–é ×vé¡»†uûûôÔ#².,åÎZv„zÐ,3zÊÙµºì mÚtA“iZç5cGs¡øv¤'®;:ªµ›¼Ó•wL1ùóy|SÊ\¢þŒn]¯Í »‰L8ÛÐn_LR¹Œv1?œª#*/s½šKö6¾ì�mÓ?ÝÏNé¾[‡ôÈ=ÃÚ»cJÉ„Ye¿#l²f1“šº€V­¯ÑÙ7ió%M²óã9æOÀ|»íúu,(‚ãæo)˜b^` ³MÎöR†Í˜ïÛ†N×›ÚÌ •À˜“ÑyЗЖÑs´;Þd:[*¢òÙÖ…Jº~Ñò˜Þò[ö§K“ãíÞ>®mŽiÏŽ Ú×@oR»ñß,ºÙmä6«�µ™ Plú+�€o0k¨¯XW£HŒfàBûr2¥þÕ€ê6"æ…f[‰é!æà•ˆ~ÿØZ]ظSÑè„Ù:Ô-!´QùD&¨§Ç7¨?]«�cöW@¨hlä¼ñe�Ó?G µ‘ú‘î„z&4>šV<žU|"£)ó“¶óÀ#~ÅŒ@GjüŠÖÌ ¶ :—FÕÚn^]+p ÝÑryå÷„‰ÊïüïA3I4cvHãEÉ+~=Q9óÑ)ágµþœn<[èP}`Щè<äŸ4ýþ¯ÒÎDƒi^/!4²*+Ö‹WƦÊf—ÀèhR_ÿP�š‰Ê�ËÈkÐþR! š‘í¦:uóà9fƒ’:ÓPíFtn›×;SެÓTÆ®fç†ÝâvÌ€@Á بüŽ *ξåg[É "æä;ÓõÈØiJdíTœÊÆ€/­}‰.Ý3|¾™W^ï\÷@¹S P0#à }ýwkQyÁ˜º�b^a^ª÷§õ½þóôÌÔ*³xåöuùMKÂP:ª;_¥g�Œ^¯°z„9ÕIÀŽ_¸í†A³Úƒí+§Ï«šjb^�Þ®5ßÁo¹D݉å¹ß¹mJŸÊútëÀkõäd‹‹ÏT�‘‘„¾ñ±5•W‚;Jjb^RÜ3ËÌŠe Ö]¥mã§›ùÛ•3NÑ®½ÞŸ®Ó÷zߦ‡Ç›>rªÐ̼ÊU(.�±»¡Ê€ ˆÊ‹Kº2SçI\™~™Hfwÿ¯ÞWꎡ—)n6e)÷ಠÙÚt÷ä}§ç‘w{hÆ«ÐêƒYUH`xÈDåd¢ò3h+«B÷«rB¾j¤?ƒ2GMßô-Cçª'µ@ol¹[õÁasWéE4`–j}À, sÛÐf §kÌkFeΛZ.�€gŒ &õ½/Vh¡Y"Ú_úçƒg@:\ÄÜçÙEevŒ¯ÔÁx«^Õü°6Ö=¥°×RˆzÀäÝ�lÕ]ƒ/7Ñø’é&„Ü�Jƒ‰UC •ÌééícúîgûµxQyÕ8þ˜‚"æÇ©Ô?íªp™z]䕺{dƒ®jÞ¢Õ±=fy¦(&ÛÑêƒfºÙ=Ãç™mZWOO•³Íü¼ó7‰B`Îûãú‡¨ã4zMç Ñ7"æŽ91`Dv Ù¢¯~�óº¸éQ­Ší7¢nÊ.ÀaE|ÀˆøÃcg˜µÖO×øó Á”»¿¾E# xŽÀØHJ?¹®W=;âZp&Q¹ç<‹!æ³€UI—†LD¾/Þ¥oô,R£ÙœeCÝ3ZW³WK¢=¦ >5+S}&êH6iO|‘¶��b‚é0Íé�é(ŸJ.†@ÉdÌøû÷LèKŸèÑ"„¼dÜ+5#ļR=3C»lÿõX¦N¿9C÷Žœi69IiQäˆFÔ҂И¢þ„ùIšAkY%³!³ùBHc© ¤›ÔŸj2}ñ�fP[ÝKÑiNŸ¡¸ e"0ԟпýÉA-\kö)ä [&/TN¶ˆyåøbÞ–Ø(:mæ¤ÛˆÝþp@Þ$0a¶¥½ë¦m»e\ ôæM'ϲTŒ˜˜%0.‡ PN¹¬Ô½o\ÿò¾nµ2§¼œ®¨¨¼óŠrÆ@81�ÞÃSúû>«úSe攟øZ>­T…êñ5%…'0ÔŸÔ×>{ÐDæq…¢t”;î΂š�˜'‰A(»Oùí?îÓMÿ4 ºvÝÅ¡ìnªÔw}‡å€@•°«¼mlDÿøþjcZ•x}vÅDÌgÇ‹«!””@ÎlƒpàÙqýïU릡•¾C™!æ9 S!�ê#Ð×3¥ÏÿÞ>ùÖfÒO^}5`f%FÌgƉ« ”œÀð@Rßü§nízdB‘Z„¼äp(CÄÜ!gajõØõĸžÝ5Q½ª°ä#C)}ûß»õ“ÿݯ†¥<ª«° ̪ÈÔ�Yáâb”‡@oï„nüZ�í�—Çr-)�Q#äßÿJ·¾û©^5­g•’Âw43ÄÜQÇavu†üúáßê—wÑäXq¶½­.¢•[ÚÑá´nøÆaýßOö¨™¥Z+×Qfb^aÁ�@óJ¿¾ôž^=ü@¿Ì2ü$06’Ö_wH_ÿÃCjAÈ=èáâ 1/[R†@A øMkkxUVÿùém{d¨ i“Xù Œ�¦uÓwëËAÈËï ÷,@ÌÝóW1�P�O‡÷Äuã×{µo×d“ðVÑíên·ü WÿúۉȽåÚ’•1/j2‚@aÔuøuÇ¿ ë–«¿'Y˜DI¥lFSúÖ¿ÔǬ]©ËæÇ3¦æ8î@̯N LêwþÄô�û|zÓ»«µ#\� /uow\ÿòÏêáÛGÔx*£ÖwgYÍGÌËŠŸÌ!0wMgøõÝ?ë“ÝßúM×.V['‚>wš¥½Óúl÷ScúÛßÚ£�á„jši$-­¼—5È{>¥DUD ñt¿¾÷—}ºþÔw(QE%w·¨©DV[îÐ'.Û©á‰[™ºëÊŠ²1¯(w` fO q½_׺Oß7‚~AŸ=ÀÞa׸ùú^}êÏ(Б•?À­%Äïé¬hf÷´{)\µh4«„ýà3ýÊšæÛ·¼w‰ÚEª¥èΔsàHBßþ·nýè GÔÀrgü抡ˆ¹+žÂNœ„@㺀~úåõ<›Ò{þp‰V¯¯;É|\ v/òm ëŸ?¾_ƒ# Õ¯` [)¸W[4³W›Ç)¯§ ÄÌ@ªm÷�é¯Þ·KwßÒ§Lš¥âÊép�åïžÕ§Þ²S£SI…"4«—Ó^Î1÷²w)[U†}šL¤õÙ÷îÕ·¿¼_Cý©ªäPÎBÛAnÝ5¨?zýÝü�>Õ˜µÌ,B�ÍìECKÂ(ŸyM�tøtÝßõh÷ÖI]ûûK´òTšÝKᑾÛ7~P7}¥_5í~‰ÆK�½êó@Ì«¾ ÀËb-~=zטönÛ­÷ÿÅ"]ðÊVC„ˆÅðùÔDFübP_ÿ›n �&§£ñbäCšÈG1ÏG…sðŽM¤ôù�îÕ]¯ÐÛ>¸Hk7Ô{¨„å-J|*«GîÒuÿxHûwO)lÖÏ·](%ļ”´É e"`ûkCu¾é(ý±ÛŸÖå¿Ù¬×¿«S]Kce²Èýlñ¬¶>0¬ëþé°voW¤Î?-äî—Œ¸H1wÑkØ �9°}é çtó·úuÏ�†õæ·ë²×µ«±…GÁL‘&Íà¶í�êº/të©GŸq+ä('¾Áå¤OÞ(�€é7�'3úÆßwëÖ÷ßéÔy—6+ZÃèã¹$ašÓ·nÑ�_ëÑÖ{F©÷OGãÇ»žó(%ļ”´É F óM/û�ÿc¯Ú—të¯kÕ+^ÓªÎeÑ ³´<æd³9Þ×m7ôéîŸ ªÏl9kûí�s@ ’ æ•ä l�@™X�èMéû_:¬¾Ò£�Ô몷/Ôéç4*«>áIé�Û‡uÛ�}zê¡qì€6ó��meª d{RˆùIqª‡€íSÏ*§Ç~9ª‡ïQDzˆ.}C«.¹ºE틽­Û¾ðÝONèÖë�èþ[†Od¦7B 0O¼z¾—1wØy˜�b°Ñhß᤾óÅCºÞDìËÖÅ´ñ¼Fmº A«N­u¾=“É©÷`B�ß7bF¥�h‡Ì62˜V øÜ´2v4+fí"íB@Ì M”ô à1vZ[ÆôïÙ19ýóƒ¯Rm]Pk7ÖqoЙç7jñŠØ¯D°R‹Ÿ3ËÔö%µíÁQ=~ÿˆž|xLG&e‚D¤IDAT=Ž ùÑ¿ù W æ®x ;!P!ü~Ÿ¦&3F­(Žêÿÿµv„µöô:-]›<·hET‹#ª1¢_Ž#Ϩç@BÝ{ã:´/®îgãÚûÔ„YÔ%nšÎ_°èÅBþÂYþ÷”ç›æ',†ŽCÀŠûà‘”î¿}húçèe6¢ol i‘éwïZS—!ßiþ¿ 5¬˜T1ÓàŽþ^ˆŽ�ÞŸï·]n§ˆÙ—‰©É¬âf Õ±‘ô´pÚ;¥n+ÜæÇæËšfôc77y±�çKŸsp•bîªç°NÀ6k›ÛìÏö‡Ç�o­Ññ�iê¶sÜ£5~Åžÿm_~%ÜÏ ¸Ý�̦;“ãX!ŸÉ=\W æ®z»!àFœSÉœùIklØ+…¢(-�ê›@ZZ¾ä@(:ļèˆÉ€ P\ˆyqù’: @ èó¢#&@€@q æÅåKê€ �¢@Ì‹Ž˜ @Å%€˜—/©C€ŠN1/:b2€ —b^\¾¤@(:V€+:âRg�Ó¢ö~-jëS{Ë€Úš‡U‰+MÈïÏ*™ )‘ kx¬NG›ÕÓߢ}‡»4>éí½ªKíòƒ PJˆy)i!¯lΧXdJç¬ß©�kwiÝŠýª‹MüÚ'Ê:›õé`o»žÜ³\[¶Ÿ®‡ÛÌ–—/ÚZêD7ó ”�b^vÌÍ€TÚ¯å]‡tÕE[´é”§ 'æ–�¹ËïÏiigÏôÏÕÝ«= õ‹-çëþ­§jr*j^ f¸³Åœ-àF@˜Ä|>ôÊpo&ãWsÃ�Þrå½&Bá�ñ™m9s³&"_´p@ïyÝ�zåæ{õÓ{.×CO¬T2šU´?“¼¸€ C1/ Ç¢§b›ÂcáI½þŠôŠsšnZ7»5›| 'ä/.D&TWÛ�>ü–ëôô9Ëôßw]®'v/šn~/NŽ/Î�ÿC€Àl 泡U¦kÉ€N[½GzËÍjnì5Vøôœ�ß t&¤UKé¯ý’~~ß«ôã;7kd¬fºi¾ø¹“ Ì„b>Je¼fb2 ×^²Eo¾ü.ÕÆÆ”3ÞÊqd³Q½úå?WkS�¾ëUf�\£úÒËá ò„ p,ÄüX"òwÎèd<žÓ‡ßv‹Î?ãaEÌ·r ùQ$©tTg­ßaZôÝŸ_£mO·A?ú)¿!@ \X4¦\äO�¯íøTZþ¡ê³0Bž4W—'"?ÖÌL&¨e]ýúà›¿¢ ÎÚ¯l†èüXFü @ ÔóRŸA~ÃC>ýÁ{nÕÚe; dgpGi/ÉfýZPŸÖ›.ý®Î\߯Tª2^4JK�Ü Tļr|1mÉÈHPï¹æ^m\³]á`ºÂ¬{Á»¨Lg먮zùkÍòa¥Óú tø �Ò@ÌKËû„¹Mźô¼'tùËÌÔ³èdÉF¬ŸÐ¨|˜Î„uúª]zÕy÷¨½uÜL[CÐO€‹� �b^4´³K8mVt[Ò~Hï|ÍÝf9Ö¡²v›©õÉt�.:ë.]zîöé5àË=Ho¦vs /@Ì+Ä›ý}~½ïM÷«¾æˆ‰ÈÝrK&[«‹Ïþ©6œ2b6r© ˜@ Š¸¥uL"Ð+/zJ‹;(¬¼o'Ã>= ®!¡ «�nn·«Õq@€@é æ¥c}ÜœF‡rzËe�ª&:ìLóú±…I™æöó6Ü¡ÓÖŒšÁpÇ~Ê߀ PLˆy1éÎ íÉ© ^åãfßñC ˜ÝË\=l_y,ê7£ðï×âÎQe2Dç®ú»!÷ æeô™]åmj4¥×\ò„ÂQg£ò£Ó™¨Î=í^­_=lÄÜÝ“£åá7 W æeôTÒl rÑù{Ì ·ù=ÈÚè< jEçSjk™}çe¬\d TļŒîñë³w)w>*?Š1“‰iíòǵ¤kŠ…dŽBá7 �"@Ì‹ øxÉÛ(Öç‹ë”å½ ‡¼3ŸË® ·´}ŸÙ }Ì=s¼âs€ H1/ ÌÙ$•2‹Äœ½Áz›œÍmN\›ÍÅÔÖx@ ã4µ;á1Œ„\'€˜—Ƀ‰¸O§¯í6©17Qº—Ž\.¢Î¶gÕ² iÄÜK%£,€*“b^&¿Ä§|ZÒ1döOVüì³E”ÍÕÖÔ£¦†4ëµÏ×C˜Ä|Ð qËÔˆO¦_9ðÞ +Ùœ_Í�GT_›1û�‚i@€À‰ æ'¢S¤ÏìüòX]R 5qù^(æxxìྚè”jc¶|´³�ç!Šb^(’³H''ŸÌà0ŸÏ{QùQ 9 ÄMËCÆL»;z–߀ P ˆy1¨ž$M+n55v:š—£V¿ò¤ùAÉORø€À¼ æóF8‡L3t$l;“½,t>ÓÄž~¾Á[£õçàqn� PTˆyQñæOÜçË)žš½Œ?gF²‡žÍîå—–ü>æ, �R𲚔’ãìò2�êäTØÄå^ÆŸU:6®x¹Œ³s;WC(ž´Å"{‚t}FƇ#¦•=p‚«ÜþÈg–rM¥#æÇoú¹]¬‡ Péó2xÈŠ[*Òðx�Y!Í{.°ÝãSuš˜Šš‘ìÞ+_ª YB8!ž´'ÄS¼cõRO�iŠö^tî÷e58Ҧщ€Yá®x I€ž#€˜—©&DkrÚ×ÝbĪ—GÜJ1 � 'ÀÓ¶Œª¯Ïꮇ×(™ª7Ó·¼ÑÔðOééýgèÀ¡˜‚Ao”©ŒU„¬!̈b>#LŹ(l–t½oËr3E­ÅLQ+N¥Lõ¹•írzöðZõÅhb/%|ò‚ªšb^f÷7,ðëÆ[ÏÐd¼Éùè<œÒƒO\¢'w5(b¥˜2W-²‡ªˆb^fgG£Ý|Çi:Ô·È,}ê®Ú¹å£ãmÝ}¶©WÀƒû´—¹ª�= �ã@Ì�‹¦t4µHßùÙÙšˆ7›èÜÍöö`pB÷m½LÛw5š¨¼tìÈ €¼½m—3þµ}ç÷?´Z»,7k™ÛÝÔÜ:üþŒzš´í™ ª¥¯Ü-÷a- àDæâÄÖ…}õ{hx¬ÓXäÖ(pŸ&tçïÑO5(vËö q?f@˜Ä|^ø ws �ÕðD‹¾|ý¥›lq¦¹=Óm^¥;¶¬QÊlyê•)v…ó,)A(>ļøŒgœCÄ4·?¶cµn¼ý|³ãXåÏ=ãÚòÄÙºõ�³5 ™½Ï{:õ©/¼KW\𘮾ø—j¨1¶_Õ}¾´{j½~|×¥fÀ[ëtžL?«ˆj�€~E1ÿŠÊþÏ´€ú‚ºù—çš9ݧëõ—> K7?¤šè¤r¹Â‹z0�ÒŽ=Ë�ˆ_®Ït)› T6 ¬ƒ PÅsÇœï7˜¤2Q}÷æKuÛýgèòóÕùgnUcÝØ¼ãtûJ�Éå´óÙ¥ºýÁ ´mçr%R¡’7ë;æÌ… Pv¾k6=ȼ¢²»aîí•ݱìô5ÏêôÕ»tÚê½ZØw§-k8ìS0쯪 ;F"•Ì*™à«:ß:Äýð*ÄÜcžÍf}jªWGË€:¨¥iØ4Å'‹Ä§>‘ +žkd¢VGú›u¸¿ÕôÇ7+�¡ÝcU�â@UD€fv�9Û6Ã�¡¶?;÷/õXé( ä#À¢1ù¨p€ àÄÜ!ga* @ Ä<ÎA€"€˜;ä,L… ä#€˜ç£Â9@€€Cs‡œ…©€ �|ó|T8@pˆbî�³0€ ��bž� ç @@Ìr¦B€ò@ÌóQá @À!ˆ¹CÎÂT@€@>ˆy>*œƒ 8D1wÈY˜ @ÈG1ÏG…s€ ‡ æ9 S!@ù æù¨p€ àÄÜ!ga* @ Ä<ÎA€"€˜;ä,L… ä#€˜ç£Â9@€€Cs‡œ…©€ �|ó|T8@pˆbî�³0€ ��bž� ç @@Ìr¦B€ò@ÌóQá @À!ˆ¹CÎÂT@€@>ˆy>*œƒ 8D1wÈY˜ @ÈG1ÏG…s€ ‡ æ9 S!@ù æù¨p€ àÄÜ!ga* @ Ä<ÎA€"€˜;ä,L… ä#€˜ç£Â9@€€Cs‡œ…©€ �|ó|T8@pˆbî�³0€ ��bž� ç @@Ìr¦B€ò@ÌóQá @À!ˆ¹CÎÂT@€@>ˆy>*œƒ 8D1wÈY˜ @ÈG1ÏG…s€ ‡ æ9 S!@ù æù¨p€ àÄÜ!ga* @ Ä<ÎA€"€˜;ä,L… ä#€˜ç£Â9@€€Cs‡œ…©€ �|ó|T8@pˆbî�³0€ ��bž� ç @@Ìr¦B€ò@ÌóQá @À!ˆ¹CÎÂT@€@>ˆy>*œƒ 8D1wÈY˜ @ÈG1ÏG…s€ ‡ æ9 S!@ù æù¨p€ àÄÜ!ga* @ Ä<ÎA€"€˜;ä,L… ä#€˜ç£Â9@€€Cs‡œ…©€ �|ó|T8@pˆbî�³0€ ��bž� ç @@Ìr¦B€ò@ÌóQá @À!ˆ¹CÎÂT@€@>ˆy>*œƒ 8D1wÈY˜ @ÈG1ÏG…s€ ‡ æ9 S!@ù æù¨p€ àÄÜ!ga* @ Ä<ÎA€"€˜;ä,L… ä#€˜ç£Â9@€€Cs‡œ…©€ �|ó|T8@pˆbî�³0€ ��bž� ç @@Ìr¦B€ò@ÌóQá @À!ˆ¹CÎÂT@€@>ˆy>*œƒ 8D1wÈY˜ @ÈG1ÏG…s€ ‡ æ9 S!@ù æù¨p€ àÄÜ!ga* @ Ä<ÎA€"€˜;ä,L… ä#€˜ç£Â9@€€Cs‡œ…©€ �|ó|T8@pˆ@Ðç×g²S!@8†ÀÿB·ø¾ rtIEND®B`‚python-msgspec-0.22.0/docs/_static/ravyn.png000066400000000000000000000303741525673062400210170ustar00rootroot00000000000000‰PNG  IHDRßßvù, pHYs““L¦âtEXtSoftwarewww.inkscape.org›î< IDATxœí�y¸Uµ¾ßs2AÂ$$aÈ J˜”Ñ( L2„A”‹€ ‚ˆ¨ èÅ”‹ˆ^Åõ¢L‚Š "ˆþP@æ9Œ ! !Óù~|Ýœ>�®êªîÚUÕ}ú}žý$眮®ÝÕµjï½öZßê“D�=ògdÑè1„ÑÀ`u`Õº6ô#€+Ç,^©ùw10§òï‹À ài`zåç%¡g|ù3x °)°>°^¥­ LÄÆŠ×°>ƒ òà^ànàlÀ=r¢¯7í ÊrÀ6À¶ÀæØàÞD9z €û°1ÞÜܼZd§º™žñeËÀŽÀàíÀ”ÓÐ’²áõÀ À�xjÛ#zÆ×#�í€÷{[}…ö(,K€;�k�ßã‘q Ðu0=ãKϲØÐÞì¬\lw ep96Äk�…Åv§³è_2Æ`C;ØX¡Øî”’ÙÀŸ€ßWÒ3ĦôŒ/ž7ŽV+¸/�ÄKÀ%À�°'µGzÆ·4ËS��»Ü—nà_ÀYÀ/�y÷¥TôŒo�µ€Oc£Wp_º‘—�_ßž(¸/¥ g|Þ;8Up_†À¥ÀIx_qØ2œ�o{àd`×¢;2LÀžÒoâ½ÄaÇp4¾·_ö,º#=^ç¯øAxCÑÉ“ád|›§ûÒÝá�ÌeÀ ÀÃEw$†ƒñ­Œ×GÑÙ¡^Ã…EÀ¹À—�ç îKPºÙøFÁ£Ý îK�ô¼| 8}wÝj|ï~ŠSwzt.K€ÏàÍú®#dîX¬|¸Žžáu:ÿÁ™!]ixÐ]k ½€ŸkÝ‘m188•.�íã[ 88¸èŽôh›k€O�Ý‘<ètãÛ¸Ë1ôè\^¾ü èJ'D#:uÍ7oÜHÏð:�K°´ÆY #ÃÎùÖÁ_Ø6Ew¤G[<†§˜×Ý‘¢è´‘oGàVz†×É,~€Ú‡­áAç_p,ð,RÔ£3¹o Ì-¸/…Ó ÓÎåpØ{‹îH�–™|ïÁö´A+”Ýø&À™=:“?GÓ îGé(ó´sàfz†×©LÇú7{Ñ3¼†”ÕøvÆÛ“ŠîH�Ô àmƒ�ñr¡Geœv¾‹íô$:�ÛðöÁ¿‹îH'P¶‘ï`àWô ¯Ó˜�³¶§gx‰)ÓÈ÷qàÇ”ï�Ð#ž+q¢òSEw¤Ó(Ë�~ÎH(Kz4çQ\£b*=Ãk‰2ÜìÇß¡§«Ò),Äê›.¸/­2øJÑ�(zÚùa,У3¸ø$�­·¹.ì²>Ö‹9­¨Ž9ò}8»à>ôHÆ àCÀNt¶á-‹×¨ÕL˜oâõj!uãïƒ÷€FtþÉX|§ü\@g§üôçã*Áµüø`þÝ)F@ik¬±26ï÷HÅßðzüÞ¢;’§_ŠøÛbì8º*¿îäo|ëâ�±ñyž´G*žŽ~StG2äcÀÿ5yÍ+¸œ÷=á»cò4¾qÈØ¦y�°G*áíž/s îK–€$I–8Ïàié3A{T!¯5ßH,Þ3¼rògì~?–î2¼}�_“Ü·°&ð;ì˜ N^Æw:ðîœÎÕ#9Ó€ýñfùCÅv%svÁ#^ÚPÅm€s²ïÎÒä1í<?}z”‡W�oc9öù÷%Sðh¾\ïq,–»Fhã› ÜB{¡Gv `©Å±c¥Ù Ë�´[]xÖ º¹íEÒøÆá“ C� Ç?źÇÐvsÖÁ;ð&zVe½ŸÆÉÜ33z¿!„\ó�IÏðòâìInÄCx]÷.ºÛðvÁûtYÀZ8·4ˆ�„2¾ƒ�C½w�¡<„·v¬ûý‹xÝ2Ç2v3S±ÖOˆåÍ.8W1sBL;×îÂE){„å,Å÷?X†QqÉ âulÈìØ úŸ,ß4kã�Ã’Þ™å›öhÈ<<•ìÃN�~¼Þùä¬2p8®ï�GŒð�x>³ÊIYO;?KÏðò`N¿§dÍöÃÓ¯ábx_ÆY1yço|=Ë7Ìrä[˽€é°ÌÁr|7à'ÿ9ÀG�ŸÙ©‰«QÀ¹—àÊX·gñfY_ÞÔÜ5‹7ëÉl`<Íœ€3nv§³Ó}’²øÞÎùUQ�Ê‘ÉXv¾,%¿çbEõ'Ûy“,F¾Sè^HnıŠUÃû6¼ß0< oà&ÊcxàéoÛqŸíŽ|[â5GO‡% —‡¯U~Þ ¸x+tSúO=#°wñK”WÙn௭Ü®ñýØ¡�7èÉéøÆ¨üüìÔÞoêy‡F¬‚GõÝ‹îHîıŸÍ^؈vF¬é^bÖ ~©[Wàmœ£ènÃÛä—ÝðÀßËa­ÜêÈ7 ;ÞØê‰{4d&.ú�šßMÆ «b¥­Oçß­Ü8W8ꤽâéÀF´Pi·Õ‘ï#ô /kîÆÓÉZÃÛ¸ÞÅ ð-#q¤Î…t–á�÷[[ú^ZùÆà¦2yŸ:�+q&H­elx+ÿN%øÂ¼kš„šê®�=·õY�Ä,`=¬€–˜VF¾�Ñ3¼¬ÞªÙ—¡†·žjNþ‰§¢yÞHœñþ]<µ Áì-ïdÃ;ˆR/Òß2ØУ}æïÃ;j½eïÄîëÕðh³¤Î“·àh’QØðgeüþ}8×ðo8aµ8X)Íi�ïH,¯Ö£=îÃût¿«ûý8{E¬,¶;NŠÍ‹Àç�?âmŽ“hÑ�Ãjxš}ÝUu%àè4¤Yó�d°ÈD�Öø-vXÕo�g&ŒÆ›è;ÓføRJ6ÎÉ£ãXÒ¬™‚£ÓŒv÷`©÷åñ þì€Z­òïªX=Õ¨ˆç�I$T„KS"l?z†×Kðêt†B÷á©çI•ÿß�#'žÍ©_ýÀ§p6ü•~,Éø}Àðú6Í=÷s¼–Jr3¯„ËTÛ†8k rÁņCH˜Þ•fäû–,葞ðhrMÝïGá}­Ã*?ßìF µ¬¬‡ó'ã0¶Å.WÃÕ�öLqÌàd»:x3^K„Gß�á�÷beöæ†%)IÛ^=ZåfI“´ô5'é/5¯»UÒ* ^¢õIú„¤9’þ&iÍ@ç™"é©”×ëNIüìëHº2eŸÒ²[’¾$}¤ZHö\vêdüÄ}¢îo“ðLbçÊÏÿÀù�Y{±6á~ˆ§À»�}a�>쿎äë;Uú´a¥ëŸÄ{¦ßxŽÏ&yQ’iç*øËY¦Ý #ÃÓ¸FjÇ;`§Ë*?_ƒÓfòØN8»œ�×&QZŸí°:VOK3Í|;¡® П(ú�Gñú0k€ L‹ì@3¥gxi8/òÞ'°”yÕðÎ#Ÿ}¼‰øÆ>¸;"BÞ^Xf!�á]ƒƒ©ó4<°�„ºîý$ ¸N07½;ðü¸[xQÒûÕøŽ’ô“š×H:I^{…^ßRéÛ|IG:ÇXI?®|®¤,�t|N× Q#éµýMË4Iýq}hÖÁž£%×HZK�¯áš’n¬yíBI‡E¼6˶º¤ßUÎyŸ¤Í�g+I¤¼^÷Jzk× ®íŸ²Ï­°k\šM;Íb îb^ÆQ?»Ñ¸êÏθ>”Êϯà©Ùy�ûu ޜޗCÞŠŒÕ–qÐʼnXâáM �ÀkηQ|݈ãs8Çá±�±Ì’fäðtèT.“4Q�¯]¿¤/KZ\óú§nô©¶ íž“45ÐyÖÓÐÑ< Ó$íøó'mSSö½UæIZ.ªqÜ9§v3½¶Cž~þ¥î˜dÃyC&iVå|WÈÓÎPç™�òš�#iÅÀŸ?i!é?)ûßï‹êKÜ´ó¿²�»‚Kp4È%ÖõعæwgU~•–3‹*�‹½ÒŸÁ)JYGɬ„Ëe�‹¿“0O}?BÊ\·€œˆ#Pòâ}‘‰°Ê‘’žÏñéPvQ|ÔÂÊ’.¨;fžìi õï—t´¤W*çû§ÂE†ì*é™”×ì"Ioøù[iÛIZ”òs´ËIË6êOT'wʹƒeež¼v[FÑ_èû$M¯;î…]ßm(éúʹI:Y~`f}že$�¡t[ÏJÚ/àgoµ­ éÑŸ#KöoÔ§¨içaFàŽâR�{ ƒº™µ¬‰‹N^‚SZª\Nï" æÛÝ…ÃÖ­üû5Ζ%UMÖcI¦›)<%Ý„òã�§ÌEéMmøÛF)鮂žeà>I»(ú :RÒ1’^®;îIGÆ×nÛT¾®ò3IË8ÏHI_‘÷#“2M ƒ‰ j?LñYBð´ô«QG'*Ý4£[˜+G�ŒQô—ø.5~0Ý,OCÜ8£$� ÁhŒ™ 7­{‹†x3$ýŸ<¥+ÚÀ¢ÚçR|ž�l¢ÆwDaÝ+†Å’ÎRüVÀº’~ÛàØ²aŒˆ9¶�¶µ†ºÅÿ(i|€óôË¡^óS\·‡$½3ÐçΪ*iIŠÏ’Ï*�ñ]TX÷òç ùiõå­(éTI¯68övI›ÇÛN[VÒéܤŸ'é“ ¹�Òm˜/®ô­¡¯Dí•Çð$é*%0¾§ ë^~Ü"iEq£$}JžâÕ3[Ò§n´ÛMö–V¹MÒ›œ§OÞª˜›âºýG�‹6¬fí(•oé4O¾¯"�oÝâú– Ó$}Hñ#ÈTyJÕˆ?HZ;æØvÚ’~¡Á›f‰¤ïKà\ëhé(œ8J:Mñëá²´£U>법bŒïà;’™²‡2îFÞIÒMÇ?&i�˜cÛi}’>ªÁÐ0ÉûQS�ïp¥ »Mö´mTIÚWR|®"8F1Æ÷£;‚9’¾¡ø¸Âm$]qü\I_U¸õÍ&rÜg•ÙùÂ{8A¹“òª¤/(Ìæ}Öm„¤3S|¶¢ø•bŒïßv,KæKú®âÛ6“tyÄñK$�­è¬…vÛ²’N‘½¥Už”´{ ó$é…¤OŽž )b”e[FÒ¥)>[‘LS„ñ�ÖЛ¡Y(ï;E%¶"ßT¿V´'ì…ób"ÇI>\s¾I?—Õ̲>×j’.Nzñ$½$«šÅf`—¨­¬Á0»Náõ­¢Ú²y¡]j�%òM·Ñ½¶l˜Q�µ(>U¨Ý¶JåüµÎ€g%íè|{*]0ôÿÐ*[›(Ë v¯g·×ÆvNÎ'Ì-S\†xÄ¥ËꙀ%éÁ–ꓟÃÕ^ãR…Ú¡¿rÞ‡+ÿVã$Ïű£Wd|¾•°ˆÓqºQ3Ç‚GSiœ�_FÞÜ‚¿÷Nãu;«½;íƒüøo\B¸Õ²MŸVhð÷¹À™¸@¨\³-€Û×ünV1»<ÀùvÎ&Y ·Å¸o'ÒBUÕÙK/–¡6C+lòúÿ48Œ_Uè`œœ›%½[ÑÓ‘åå�¯—"Ž_ OÿÖˆy�vÛ8y�®VFBòÔ8„*õØÊù’îoýKÒÛ~þPí#Jð]FnQåóÔ~°Ç‹ìQþ%¯cânÀ/(Ú«·Xö`†Ú$GÞ³;DKç÷=#i¯@çÜAÉóÔ^’ÃÔ:Å¡Rmýò&70G• �ꇩü3|“r¿•uÃŒ’ô1Å;®Qxñ¢ %ý¹Á¹/–´j€ó-#ß�õ£k�æP©ýœ¿Jø;…ñª1¾7Ü™Fà‹x¦[ *öVùV/ À…x¤Šª=>—+Þ1âï³€oáMôDu°Ûà@üp¨ßC›|’0¢AoÁÒò['xí%Xì(”>hh–Åå”.º#9°& ߪ9Ÿüj\<ñΈ¿¿�0Q*j¯âißé¸^BH&?ÞÕào¿Ä7ü‹Ÿ³|ƒæåÙ¦áÑîO÷!OÖÄ‘JI2ÝÀ*Àë—ksZhÞ§øÈýµ%ýFћŠåRT¡¥×‘´’¬YÙȹñ¤â÷ÛiIeÉr‘µ:¤m+Ǹ'�½�¡µëgK:Nuiô5mŒ¤/)ZÒ`‰¼×³AÄñY¶~9’⹈~üHaòíúdéŠyq²ÂÍ ›y‘Wû Ò‰6u Ï«ÆøÒJ�'e@–Fˆ©Þ£ømƒ¿JÚ2æø,ÛÖ²ìz#î—ôŽ@ç�TùœÍxQÞûì´•ú6RÒÿ&ø¼ÝÊbIýÕ‹‘äi›–»$½]Ñ_Àºr™­(U„Ìv€¶†œS×(Ço¡œøJ¿äH5—u�CãVËéz„¾Ö×5ù¼Ã�•ª$iˆRªb;Q›ä}òÓ{NÄñUñÚ¸úYµQ’ŽÕÒêÓUîP¸äñŠÎ¤¯å.…ÓsÉ»m¥îÝ8OËxdý‹¬ø‡¤7+úâO�teıÕ)jQØFmª¢CÓ^UX1Ü÷«¹¬Cõ!B½¬ˆö1u¾RB–¬ƒ¬'Ò.¯ÈZ‰qk‘Ã=ÂÜ©üô 7U¼lÞÕ’ÖtîÚ:éqüZáôcòncå‡j�¡l„ìRo‡ëåõ[Ü wEı d¹·(/h–m5I?Qôû9Y^<Ôùß§Æ"¼µ< ø"-¡[ÖŽœ7ª3¥ò`Óªq´B’:Û+ZûV9x6ô 5JÖÉ�J®­:3B$¹Ryßf)1ó$�¨âDi«×è�Ênš»—†j‘öÊVÈòzi¹[ÒŠ¿øG«ñ¾œôj=U<ó9î—´cÀóï­æÈWHZ/‡kÕÞ-;uNQ63�‘r}‹²ªF—…·!K¤álŋȎÕÒ%’«Ü¯¥’´Í-„+9÷î$…iÆI:'æü’•B)—%ikÉÑD�);oêDIoò¹{˜M‘]úI˜'éÊ¿ø“]Xó"…)æXC�«øê4×IÚ8`v•ÃÏ¢X çä•g7ZžyÌ‘ôSe­³‹GõhÌFÈ‹ìfܯæë³Éj¼¾[ Wõ yC­ O›â‚^�ÃÆB”ÙB~°üXñÓ­¿*¬á7k;ËßåªÑ�l³��ge*ÇÕ Lª^À8E¨ËÔüé8E�×OÉN—P7ÓHYayFLÿ—È%”Cè¨T[3£gåìû¢Œ®:ŬªcÇÕ®HÓÖPºjG=™P½ˆ�öß$}]ÍÝÏSÕ¸xä ›}°·œ%Ç¿UÑËÔ–•kBD=õÉ™YÝìiÛ( N1Ÿ’ãh³zï�4ü²²dåê…|¬îså}©f_ÀÕ8åæZ…©=€¤·ªy ÔË [À9&NÄè&5÷‡lÕ)¦äuðJ½o¿¼-ÒnHâ}*¯b^h–HQ½ ·Õüái%KWù€—(Œq}y¿,nm1 éB… Q#»Ò£n¾çå’ġ֖ÍZuŠ)ydÚ;Ã÷ž Ë0¶Ã¢W+¾ätȶ¢¤okh†ÈùÊöAÔ'¯³£¦ØIx@áœNk©»ö§(…ñý¶îàWßÞ£hu°z—ô_Êg¿l_5v£?«JQ‹Z¿œý_[ëïIe_qh¢ÚÛ»["+‘ÅeºdÑÚuü”‰‰Jh|£´ôÂ;ítggYß% ³å­ƒ<¦wcÕØ«¶XÒ.J§YÛVCRrBÖajû«¹W9Ž�rŠõíÂ6úY&櫲žäCoSwðl%÷`í!醄�Z$Ë<¬žð½Ûm›«±“çVW2y‚ìì¨ÝS{DÙ,§ö\ù¯IúšòͼÿYý-w¨ò™F6Ñ”ذîç[€…1¯ïöþ×\HÂUÀñÀ½ _ß}À1¸ÀJm„—��Ÿâ".y2×|ø °Båw¸Fĉ¸6EVl…kLlÔâñ×á2hfÕ¡„ŒÈù|¡¸»úŸ$Æ·VÝÏwE¼n®0óE`ㄹÝU _ß.«çâúoµü²Ò�9õ£–½€ï2ÔîŽnÎð<ýÀp}ÃQ-? _£ó[û0ŠÕ 8gRß躟Ÿ©ûyà#ÀçI^çïYàdà`qÂcÚe'\’lÍšß=\›SjÙø°gÍï߯òZ†çZ¸€èRk͸8˜™Y�Ò3¡ÀsgÉëu“_=Õ§æÊxúñi`|Âcgã²^g�íT*Žx:÷e§.ó�Sñ�¾ §~TY±Ò—cú`» ?Äþ�ñù~Œ¿¯´<Šk^“i�ÒÓ¼¹à>dEª‘ï…ºŸßLŽdp}ÒŒ¸Üó©d_Ë.޵ð”r‡šß]�o¨Çrìx­ùaà› }X-À@Oex¾Uð5?¨…cáB ß |ÑÑ$¼WîtfàY�Ìøž«ûyß'ÀÓ�¯]}6Sñú®Zøóy\pòœû° vžl[÷ûâµ]ÖŽ¦Ý�³:ÅNÊ͸ÄöÝÍ^˜#� “v"7ÕþÐõªþFkS³+�-€ÃÈ×ðÆàiíåØðœ�§-yÞš•sßÂPÛ��SÈÖðÆ?þé o6^ÿ¾ƒr ]w2ÿò“’í±¤ÑÚ¿NÅUÕÙPCÃÖ–EaóîDzrðl£\Ä¿+L¨Ú¶Š¯sÅ€¼·˜W�š´mŒÚË®(Ûªæ³%½Õ¼†ÜmŠ/ùºªÁ/i¡œc:䩾õÉáhO4¸>/Kú¸²—% ]µûx«ŠMNÒöoás•‘yª NIsWãlæ9o«(Í’å@ã*7É•ˆòîÇÖŠ¡»LarÿÞ¬ÖbŸ“3Æ;¡ÂíŸ[ø|eäoªûli/Äñ1oþ˜¤ïÉÊÅyÕ”›¢AåµÙr}ˆ¼o¨5åiy£Ót%S�KÛúä úF’�q,’ô}e§dºm î©ùð%µi|ÈÙÅÍæàsä:t•oά¿”Qòh[Uû] óĵeåòf�ÖuÕÊGY UÛºj.�؈¿*ŸªPY¶µð9ËÊ–ÊÀø�ë®ýQÉŸJwÈbHÛªý‘i# Füß«ü³ÊûdÙÄFë:)œ“§O^3¦u>KsCÌ�G…ýåèú¤çê—…pçʺ‡ÇȪbyÞÛÈkÊF,’tºÂ8yÖVúµÏ|ÙSTA–vÛÅ)?o™9O >cVj´œ³÷%Ób©2_–Fø°âsÕÞ"ßô‹d9‰¼µ1ãÖu’eéßèÜqå´£¸LÅÖük·í¨îYëIN f|õm=¹Fû•НTË«²"ؾtØ,+ç�½&äÈÛ‹9VÖ›ŒÒ}UNü 1O¬\¿4ܧbÅ�²h+héò�Ì|E ,y\Ì1²ôtY,)ÉíI?”4MΖÞ7‡~Ö¶êº.NÆðZÙâü‡(]Iåéòz0ïixˆÖ-I³U.SÄg-ââN�t˜ì¡Lâ*¿VaK7×·í½®“\ÛýH…Ù×\£r]’2Gž„.:šW;0Ågï"KÃõIEäE¾ÎX`œù¾70.æµ7_ñ¦!Øg]€3ñ;àSÀôçÿ/—™$it1ðsœYDp¶ÁYòËÜ�,yX˜Ûð¯QVY@#»Äÿ øòS7*[µêUe­É8Ù¼é ç®_CK«ÃÅq�Љà ÙÖTãªÆ�ÎÅŠùÜE_ô¨6IÒÉ’fF|¨y.ݨâMÒ6V®3·M²Dö®†R1û�¼m’„›”ŸRXžm‚âëv2û(æ³}ᛵ1ò ­¿P—J»_ø~Ù™Ç] t×pñ³}IDATìµØúä�»$ûvÏɱª!KŸÙÖ‘¿·nå5¹EiÛh9²%j:úky UÜÖrTy3.—oŠ}_WÉ”¡çÊq«+êGÚvªÄÝm,‘C0c¯CRoç‰8ËùÅšöBÍÿ_æTþ�[Óª¿ÏZ¡l¬–öY`ùº¿ÍªüþXÂð$à@¢=˜Oa!¨ßgÜO°ZÀQX»¥¾¯µÌÇš¡ßbiéŽnâƒÀY ÕLí6þìÚìEI�o0�¥e“2c#}‹Ê+�Úào÷`éˆ8±ÕÅÀ±ÆLcwp{lˆ·vˆyÍ|àÿ°Ñu˶A#ÆàÐg‹îHìO‚yš}¾_à§VLÇz·bMÍ[‰WÉ~ð’ë†RyÏOw´ÖÅXFâ›ìd¢÷­^Ã#Ài„Ù7,oÁ*r[Ý‘x?ô›«ž7›—Ö´·å8g®ç¹ô{�¨»¼¤3¿G(ÙÙ2évKÅ—?{M�Ë;ÿ°ˆÖ'Çø¦Múíd>®„×'m„Ëu´®zœ3±$à™x­VÏÛ�ß°´Ì½€_áµbˆ‘fY�s�%à)èiÀÓÎ_6¶ÂSúíŠîHŽ<L"¡ÖiéÀZNIÝ�ìY8x¯•Ö©ûûMÀÛ€¿×ý¾¸‘0†÷.,~KÞB<%Þ‡¦u»á½øÖ$N†‹ ·Ûy°}Úƒ2ø_<¢Ì«ùýHìŒùLÍï€÷ãÍ,X©rŽ#XÚ›º�Ч’¿`p,�%ð�Ç×e¸1+kÏJ|DÒùiMÛ3·Ùs:Uãì‡#å}—*sÕ@O£…v€\¹¶žù’~,‡È½æÊ£�•…µžop-†')åµk5«áV`ëV Ì®1p"C÷ÅÊÑÕiöSÀæÀK-œc"Î>Ø¿î÷³qA’ïÓÝûtU–> |‰ä…rº•YxÔ›�æ ´k¾*_jñ¸ÐTkÐ]ÃÐÔœj‰«*kc#ICð1,ï^kx3pMÂupAÐ< ¯x7þâób\ei¾†ÃÝðÀËžT†­­ùªü?¼¿VVÂC¦ÕüîWÀj~ÞøC‚÷Ú;j7ËÅ£ìyd[K/ [ÂQçãâšKŸsÞ»<‚øH�áÆL`}Z ÒH;O­i›kèZªŒ<­¡BB«ÉêiUP|àò(9íh~Í17Êû�y‹ó®& åÞ)¯[OU>â·[IºPÝ#ã—5‰÷õê[»_L­L{YyXC‹€P÷÷£Ôø³m#§IÞ¸¿Xu….rhceÅëK%-�sÿ¾.iõÀç-ËÄÉiôðƒp„Z¼ÎíÊHLÀÕVËÌ?ñ”±¢öW¼V;_ÞÈ ƒfy¼Ÿù),p6^ÛLË©¯Ë`i�q�Áå*çþ^¥/ó"�lŸñx]û º§ sHÞ…OZ£U«­iŸ þ|Ɇïh°Ï;Ôýí Êï÷�“lï–GÄ8-Ñ,Ûê²véÅšYƒ¬ùR•¬OÒN²øñ‚ÄW³ÇoÕæµÏB@i‚žÜîFÀNÀõ•Ÿ¯e°âéÍXÀéT씹¾þàŒéÃN“½*mk=ϯVúp&pgÀ>¬ŽËT‰J=’3ßïÓÚy“¬ÔËvĪbq9seàNs¸bU MÀ„­Ó¾öNî…+­N¬ûû½À98*¦•ýÇ$ô»`ƒÛ—ÖSĪ_ÓqEÛúxÚnåx¼½ÐYJž…7]ËÎáx{à>œþŽË<=ãs­Ïàè¶#Îi«å%àוþÜ–ñ¹kÙ§ƒ}o´Ëý¸Ï¿ž©ün/;…î’ÿ«çv³ÚöÖN–Æ7'°–ýéw°~jžAƒûÛa4öÀÓØ�¼f 8×�µG¸2ÖýÙÄâÎ.Ây�ÿŒyÝÆøsuãTv1^"d²ÈZ4wOà�Y¾a vÃ0{;«™ëÐ8M)޵°±í�§t+D¼î!¼!þ Âe6ŒÁ�ÄžÒú‘6-‹p0Å/€+qZT&à5u£‡O'sFw…P¬>/äËÌùÀa•ÿÿ�RàióÏ›;˜Â ÁmóÚW€Kð:î-öµ£°ÑìG6ÿÆ÷+œ£Ö kà® 2èO¸ Ø–ä ¦„0¾±4Cžñ†i™…G½EØàΪüþRà} ^?‡Òí��&q²ö8—ðÜÊû½šM—‡0ïS¼Ç[¶Ë½¸¿—à©ylŽ=É�¾œ�—$÷eù¦¡j5l‹k+Œ ñæQÝ ]x¼ò»—± ¾�n»c£ÛŒæžÜixD=¿æý²d,ž.”Ij:4ãß8·ñR,‚#q\l's4ÎXÉ”�…R¾„÷ÍÊʉ öïA÷ᬇ¨µ[-¯â›÷\lÈÍEsÒ±:6´}ðˆÛî"ì,¹´ÒB<$Q;µï4®Ä×?sC i|ýÀÕÀΡNÐ&W✟wtŠcoÆw1-¤’Ä0{&ß�×qÛÒzÚW•—°ŽäU•öl›ï× c™�2Ï„ñ–$iuÝK#¡Ÿ¬Àé;·³´ÎJزæÿI\ÇÏ`‡RVS´‘x-ñ.lpShtÀÓɪ±ÝBøt£f<€õv>Up?Ò°¯ÿƒ„ùªl�õʦP,u2o€_×à5¯á=«óñ(ÞîM¼<ͦTÚö$›Þ6ã1ìY¼÷sfï™5«c-›v·?òâã :â‚�Wq̲.º'c/ßz †– ฺ.j'Ôk"Þt¯Ûæ´?ÛÀ}¾Üõ F™”�‹ðÆÙ9' %ÏÊ´?¤|ÓŽ÷ÆÑ UÕ©YÀª-¼×rx}°5®²º-Ù„r=��í?X9îFÂÅ~†æxï°ÌÜ‚—ÁÕ B®ùêù aöÊñœÍ¨î�½‚§¡}$Ó]l‚ mÛÊ¿›_¢³°�Ý Ü�÷Úî![‡NÑÄ…¥•�ÇpÀy.² yßà <]*‹fÿÊ•—0h|µ›â}xÛa¼×·žª¾™ôž»%Ø{öxƒö(ÃCñ¬Ì‚Á³ðÀ�Ûz9Oã‹Ìì�‡ö2`×fàW]ú«Wà°¨õHæ(š‹½¡3+m:ö’=ƒ�kv6,Ê¢ÓLY�- p¤P¨@ƒ†äm|àrw‚•E”F;T£VjG±;±£eEURe_ÂSÓ°‘Í$…Dø0gËæ/É�ç[_^ 8E8Šd¬¥R¤þKÕÛTë`¹o-ôÈž#‹î@Âz5qòv£'Úáv¼¸-rÔ¨_­ðëƒEtd°'�‹˜Éq¸V¤ñ�7¶ßKþ¢³Uªk° k~—뼘°%ÎØ/“ÌÈW±"\am|à¨}“zÓŒ—+ÿVëNT7°{dÇ;qbm™ä%¿Qi…Rã‡EíMXMÊFT7«§Tþ½“4%žzÄÑ|u—¥d˜°VÏW‹îäá’„wâô“¸dÕ,©µœ‰7È¿�‹;ÎÕ˜nÃÓÐR]¤`¬îÕ®&N– Ç /¯UÊ2òU¹qy¥½<‡ó䪑)Wã€Ú»�“±Wöyà÷8Bç­´ÅÒíì‚5|þN¹ o1V­+�áAùF¾*ëâµà›ž£šÕpp6ÄI jtŒÂBD'0T‰k6ƒÍ7âô�¢Fe`–³øñz6E1sÿ©èŽÔSVãoÀ_A¸ÔÏâ0±çpËÉÀI ^×�åŽÁ�Øõ³……Øo©´›H¯€Öi,ƒ%Åkõ²¥‹Uy÷;Òˆ2øK= �@YsõΣÝ$šÇWn…§0qN„g±è5í‰6û[4ëàÀˆ=±:ÁrÅv§)ÿÁ†WÚaÙ�¯Ê Xo%Ë5êpíæ •LÂrø�ð‰ÊñI˜…�ð^¬øü^S–1ñu$~ß¾ÒÞN6éQyq%pÎV)-�b|`½• ÈÎz.‡ÞnU…x2þ¢¦5¹ŒY8ªæ1<:>Yù÷ œ0§Å~%aU,p»ž‚o‚õVÞLy§’q à¥Ã)t€‡º“Œ\ûàbìul—§pºÐïZc½UúpÖú!ÀûÉFKìÌy{]ŸÃ�¯T~?;¢²%–ÅÁáã°„ÅX¼•2]'X³ðµ¿ªèŽ$¥ÓŒ|Ã|OùÚe1Þj¸‹l³ÃGc‡Ä>xÝ1>þå=Úä_ø�——b&”mŸ/ ¯ŸÄ’/7ym3ÎÆR€‡‘]ìáB,ðQ`M,+q aëí Gp¡›·Óa†�9òÕ²6ÖÏlEt¨žŽeûþ„· >Ž 2kã­‹q@A'92ÊÄ3¸ÓµEw¤U:ÝøÀ£Õ±À7I·†©ß×› ü?MO¾C†E1b˜Ä !¾;?Êý_F~‹—/Ý‘vè㫲1fÝ!ÁkÆÑõ‘)»â/vEì�9ËÈ-Ì®›MYØ´Ò¿-ðVÆdì0É›¹øZ=Š�4o/ µLÇ‘4¿+¸™ÐMÆ1ŽÀ뀕c^· ΢oÄføË]¿òóÀwqɬvט­Ò�׎“°®Ì$‚7 kጫ´±ÇG1 �/3°¡UÛC �±ý%ÞN)áÒm_ ¸ï sºÍøªŒÇQõ ñncâ3ÖÇagÌ5¿›‡å~гðËÈ( ±QŽðÍ;\RîÑx›£ˆÔ û±ƒ-w�•Ðt«ñU™œÁ`„ýL,[þßx�ØŒáQ¯^D÷ßxÃÿ× É¿ý€Ër>çKxMþºTõ­Û�üêÀ·°!ÖoÍ,ƉÀâÍú"²ñóàJò;^Œ£�¾J‡;Tš1Œ¯žëqÒî¾8k")“±fjÄßç`ü 6È<�4!Yï¡…Îc.J󲫌[j†£ñMÄ…;ß�ÃÔÒn'LNÃÛQ¼„ ñbìØéäiÓIÀןãOx¤ûWàó”Šáh|UÖÆ±�µxüT<Nnòºqv÷å¸(KÞ:5í0g_„’õ¸÷Í�Þ¿Ô gãË‚~,}xÉd^ÂBW`C|2\×ÚfÜǬ“™á©ùÿ2ÌÃízÆ—;_Ä{ˆIyã5Xô,‰vÎÄÉÃYñ v¤ü€'¸æIÏø²çmØßKºÀõœ\{3Ž1½ovçUÒyy\ù£dÉr3Þ ÿ �5åNÏøÂ±p<Ö9iµÎúkØ ïÅÀi &ÚÎh³£pèZµjî{ȦD5x�{!–bï‰GÐ3¾ð¬„÷�$Û*=¯á›|VM[Ì`^â¼=0�ÀãpàùÄJO¶ܳôð^Cg{xs¡g|ùòVl„“Ÿ0pH^À™ã—`çLY ]CÏøŠa,^_ ìDú*·E±«x_Ui·áµj�è_ñ¬Œ¥&öÃÓ2�ˆ qùMX øFº<ä+OzÆW.FÛ2˜é¾ùéc.ÀΑ»+íŸØð†³wPzÆWnFb�ä6 M¬mÕ â�ýj�øÇq¢ì=8Ògq{Ý푆žñuýX{f[ŸZur¼Zù5govˆ¼XÓfÒ[£•†ÿu64ú‰§·ŒIEND®B`‚python-msgspec-0.22.0/docs/_static/sanic.png000066400000000000000000000464501525673062400207570ustar00rootroot00000000000000‰PNG  IHDRôxÔúsBIT|dˆ pHYsxx¢¤ñŒtEXtSoftwarewww.inkscape.org›î< IDATxœìÝwœ\Uýÿñ×çÎn¶Î¦’@šti"5‰~ù i€ *–¯ò�ßâ׎ØiŠøEé½Ié%¡$Ò7ÛÛÌ=¿?&!=ÙìÎÜsïÌûùxì#›dwÏ{vvç|î9çž"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""ñe¾ˆH4Óú/é¿ÅjÞhL #Š$"©I7èÂ:²íƒqeC! †p0ØàÜûn0¸¡8«j€~@på`u½l¶Ȭþ³ hÅ\Ø2°À p+ Xý~¸Ë,£<\n˯iîû£‘BR â™ã ÒcÊǺ±ÀX,‹³±ÀÀ ÜcÄÞèV 0·Ì›G`ó »Ð\¹À˜Þé9£HIS Ç…ôïÜW¶„;㱌7l;JïwÑa,Â1ÂXj¸·Èð m+^5nêòP¤Ø•Ú‹ŽHÁ¹ê FbnwRÙ=qîc`»{¾³%ƒË€½ îuÌž# ^{�–+_3p¾Ó‰ "½ä˜P³hO‚²ƒ1·/Îíno°¾³'· ì%ŒWpö"Î=Eˈ״hQ¤wTˆô�9±šfö‡²C!ûI°ƒ�Á¾s•¸fÌ=ö8Žç( ³†Ù�¾C‰$� ‘Íp5SG„ŸXývÆ�»,0xãq‚Ô£¶êʾC‰Ä‘ ‘ÕÜ  ëèî> ìXpGã|g’¼x³ûqÁÝT´?¨[ErTHIsý§ìˆs'‚;gŸ"wÿ¼¯,ðƘÝNãŒia¡”*RRÜð3kh«98ãXÛûÎ$^-ÅÜ£`·TÞf«~½Êw ‘¨¨�¢çª&�¢<8ž î°2ß™$Ž\x þJ&u‹µ]±Èw"‘BR Eɥόe�ǹ ¹9}R¾3I¢„À“7“ o²¶Ùø$’o*¤h¸ºsAù ¹NŸÏêJ_òdm1�ÍÜh­W-ñH$TH¢¹ôùƒ!< ?�³ÃÑ•¾”Ëàx³?cÝ·ZÓÕ+}'é-’8ŒôÄO@ðeÌ}gU¾3IIêÂÜßɖͦõÊu7�$� IŒÜÆ<ü?Ïvò�Gd-÷f¤;¸ÆÚëßó�F¤'TH¬åöÛ_v©ÌDœ�LòŽÅ•Ò’ÅÜĩٴ »Õ˜–ñHdsTH,¹ê F’ ¿ á$`¬ï<"ÛÌXˆãR̲U3çûŽ#²!+.=õP/Æ£}R²àþ†¿´¦Où#²† ñÎ1- ½øxàr‡îˆ«ç0¦Ó´â�ÆMYßa¤´©ogURW9Ç÷€�øÎ#¡w0¦SÕzµ-¹¾Õw)M*$r®vò0¦à8ì;�ˆG�8~O–Ÿ[ûÌ…¾ÃHiQ ‘qµSwÇ2ß‚à‹@…ï<"1Ò ü²¿°æßÎõFJƒ )87`òX²|ÜÙÚžWd‹BÌýø�5ÍzÓw)n*¤`ÜÀ‰;� ¾¯Ž_d›uƒ»‘ ø‘5ÎxÇw)N*$ï\Õ¹£I•}‹€ópTúÎ#’`]ÀïÈð_Z# ù¦@òÆÕ^8ë¾sj~‘¼ÊÙðG:šXòE€ôYîD¾ì%ÀT Úw‘"Ö v?·Æ ¾ÃH²©�^sL+#½ôlÈþØPßyDJHÆÒ4¢^ç Ho©�^q5çE�ý°—ï,"%lfß´¦wù"É£@¶‰«›´ ðß8;ÝwYÍÜ„|ÃZf½æ;Š$‡ é7àÈv|ø:ÚÄG$Žºq̤<ük˜Ýè;ŒÄŸ Ù"Ç´€ºÅgàø0ÌwÙªÿMÓŠ+uà�l‰ Ù,—žtF=Îöñ�ED¶ÙóS­iæ3¾ƒH<©��¸‘«i~|HùÎ#"½WS|Ë–Õ·ø#ñ¢@ÖãꦋËÖƒ�ñ�EDòf>A0ÅëïõDâC€àúOHèþ8Ïw)s7ö»ÀZ¦/óEüS ¸Ú©§cÙ+´™�HIh€à{Ö\ÿ[ßAÄ/%ÌUME™»l¼ï,"5w7©²©¶êʾ“ˆ�ï=æj'O¡Œ×Õù‹”*;–löE—ž2ÑwñC#%fõ‰}W'úÎ""qáî%L�m­õ‹}'‘è¨(!®ÿ”£ ÃkÁFúÎ""±³K�cMWÞé;ˆDC@ pœUIºò?€o¡iÙ<\E:¼ØÍnóF K@‘sµçïI�½Ǿ¾³ˆHb¼Fè¾l­³^ôD G@‘r`ÔM¾ÇOÐá="²­Œ\ð#š‡ý˜úŽ#ù§ ¹ê‰ÛØu˜í;‹ˆ$�»›0ûUk½j‰ï$’_*ŠŒKOü$¶ó�EDŠ…[©/Xsý¾“HþhAXqé©çAp?êüE$¯l$dré©—øN"ù£€"�[å_QößYD¤Ø¹?’v“t—@ò©H8W7ug\x3°·ï,"R"̽€¬qÆ;¾£Hïi Á\Ý”ãpáS¨ó‘(9û(aøœKOÑVâ ¦€r`¤§~ÂÿAEœˆøã€ŸÓ<âßu«`ò¨H7pb2vØq¾³ˆˆ¬v;åågÚÊéM¾ƒHÏ©HW5yåîï8û¨ï,""x…²ð$k˜ý®ï Ò3*ÂÕLÚ—”ýÇhßYDD6ã;Ùg<ç;ˆl�æ�ÀõŸz �=¢Î_Dbn;B÷�«›r‚ï ²u*bÎ¥§žG˜½ HûÎ""Ò58÷WW;uªï ²ešˆ©Õ‡ù\ŠãRßYDDzÅ1�–ë�xRC޳*©«¼Çç}g飿’ÿŸvŒ1ãjÎNPv+p�ï,""yò$®üTk™¾ÌwYK@Œ¸�w Ü ìâ;‹ˆHžÍ!“9ÆÚ¯zßwÉQ®ÿ¹ãËîvô�ED¤0Ü,uŒ5Õ¿å;‰¨ˆ—ž¸Ü‹c”ï,""¶Çg­eæ+¾ƒ”:Ý虫ž¼ØÃêüE¤DŒÀ¸ÏÕLÕŽ¦žiÀ#W7õ@\x'0Èw‘h¹UÀ‰Ö<ëIßIJ•FÒw’R¥ÀW7õXîD»û‰Hi«Á¸Ý¥§žä;H)R1—žr .ü+Ϊ|g‰� oté)ã})5Z!×ÊÑ„îï@…ï,""1Ó…¥>gMWÞé;H©P—žü à. Æw‘X2×Nœ`-3ñ¥¨ˆ€«›øq\pšóÙšV�·æÙÿð¤Ø©(0W3i_»­öé©F‚ðhkœý/ßAŠ™ €ré)÷0Üw‘dqËpi-³^ó�¤X©(×âN„ö0ØHßYDDÉXˆÙáÖ8ãßQŠ‘n,WuîhÂàuþ""}àEèpÎã;J1Ò@ž¹šs‡”=‚ŽôÉ—7på‡[Ëôe¾ƒ�ä‘ã¢*‚²[Pç/"’O»a]·¹‘«})&*òÄ1- Ý~=pˆï,""ÅǤ%¸Î1MýVžè™/éÅ¿NõCD¤h9>GzÉ�}Ç(Z�.=õ<gúÎ!"R\p¡µÔ×ûŽ‘t*úÈÕM9Þ Væ;‹ˆH‰ÈBð9k®¿Íw�$SЮÿÄý ƒ‡€ZßYDDJL3ap¸µÖ¿à;HR©è%W5yå<�c´ï,""¥É-¢Ì}Âf¿ë;Ii`/¸AÖQînWç/"â“�$c·»ßà;I©ØFŽiÝ]ÄÙ>¾³ˆˆˆíI¶ãwº=pÛé¶­ê–^ vœï""ò¡I/ù®ïI£5ÛÀÕM9çnE…“ˆHÜ„Xp’5Õßí;HR¨è!W7ug\öi0Í5‰ˆÄS�¤Ó{FW²=ศ þI�¿ˆH¬ Ĺ›uf@Ϩè‰tû `?ß1DDd+ûÒl³|ÇH[áê¦~8Ówé)û’«�<ÅwЏÓ€-p驇BøÐÏwÙ&Ý`Ÿ±æ�ùW*6ÃU_0’TæY`„ï,""Ò ÆB²™­õª%¾£Ä‘¦6Á�‘êþ-êüED’Ë1Š u�ÓÅî&©Ø”ô”‹ÀŽõCDDúÊŽ¡nÊTß)âHUÑ\íä½xG¥ï,""’FY;ÄZg¼ä;Jœh`޳*1þ Î_D¤ˆ8* Â?8ÎÒkû:T¬«¶êgÀÞ¾cˆˆH¾Ùž¤«ÿÛwŠ8ÑÀj®ÿÔcÃ;Ñ÷DD¤X9ÌN²¦wùêìW{áP¬û´ê_D¤Ø-!Ìì§[5�»åϺ¯B�¿ˆH)N�šé;D”|@íäÉÀ‰¾cˆˆHTl¼KO=Ïw ßJz À 8 ÙìK@­ï,""©f2ÁÞÖ^ÿžï ¾”ö@63uþ""¥(MY¶¤§J¶puS¾ v‚ï""â‹ëj§~Áw _Jr À¥'{l¨ï,""âÕr\ù^Ö2}™ï Q+Íg¿Vç/""À¬ë§¾CøPr#®n걸ðß9DD$F‚Ô±Öxå}¾cD©¤ 7üÌÚj^ÆùÎ"""±2ŸÊ`_[Vßâ;HTJk  5ýcÔù‹ˆÈÆÆÒá.õ"J%3àê&~<¤|g‘XʸC­qÖ?}‰BIŒ8&¤Àf¢Î_DD6/EhõŽi%Ñ7–ă¤vÈy8ÛÇw ‰½�‘^òß!¢PôSnÀ7�í˜ ñ�EDDa)eánÖ0»Ñw�B*þ€lÇ¥¨ó‘žF&õ=ß! ­¨G\zân¼”ûÎ"""‰Ò…¹}¬iÖ›¾ƒJ‘�Ø/Qç/""Û®Ž¢Þ!°hG\ÍùGdïõ�CDD¬ˆw,ÊÇ´2‚Ìe¾sˆˆHÂ…Ù_9¦•ùŽQEYP·x*Øž¾cˆˆHâíAí’s}‡(„¢›péóCv0Ðw) Ë l7kœÑà;H>á@öÔù‹ˆHþ Áq±ïùVT#®fê‚ðM Úw)*­8v¶–™K}É—â°ð»¨ó‘ü«Áì[¾CäSÑŒ¸ê FRÖ=gU¾³ˆˆH2:èfWkŸ¹Ðw”|(ž€²ìÔù‹ˆHÁ8*Iñmß1ò¥(FÜ€óÇ�;ôó�EDDŠZ'™à#Ö^ÿžï }U›d3?Sç/ÒfPWå)¨^ýk” ]¹ñÇV”A&„l˜û{S;„níûÈd¡µ3’èEohv#éÊÜóT·úyé_•{î:ºsoMÐ٠Ͱ²æ.v,XÎù{ ŧ‚r÷=Ú™ê;H_%~ÀÕMÝ—}¬8ЉFy TÃÀ¨,‡š~P–2Ì ­ÓÑÐË[ ±ÍwÒõ•0v(l?È’†!µ¹N`ÀêÙ¯ÊòÜÛš÷+ÊÖvð¹¿Û‡ïW–CmE®³Ï·® 4´Áª6XÕæhhÍuH+[aE 4´æþ¿aõÿeCh逬ËuVMí=o«ªú­óXúWåwuEî±ÖV@meîÏšŠÜÿ×VB¿T®ÝŽ |° Þo€ç8^[ä§Ã  ïl||GØo‡\þ¾Z´ n{Áqõ£ŽE«úþõ ›Àö°ÆïøÒÉ/ÒÁ¾sHÄ*Ê`ô \G8zŒ�ëÔ몠¢*Ër�Aíê«¥~)HWæ^Pëª6}u»)Kšà¥÷xzÝ}xµ¥]GÀñûGî{Œ´;øRЕ�öçÏ]oÍ[3rÜø´#¶-È=¦Ïh|ã3ƘÁ…k§3³v\v¯£+S¸vJ†»Öšg%z‡ÀD®vêîXø"�ò�E l×pÀ8ãcc`ŸÑÆ®# såº%O¿ãøÚ Ž…mvÐ8øöñÆ!;%ú÷4±ž~Ç1ñ:ÇŠ–µѿ®<Ó8ü#Ñ=Ç/¼ç8û*DzæÈš,N.ƒ±W’� Nô ‹KOºì+¾sH”§à“»GíGîaì0Èw¢œÆvø|}È«¼ ¨<ÓN1þß¡öá¯øñêB˜PnÓ”DO¥+áÏSö�ÿ¯½5¯/Ê=®U1›âJžßZóÌɾCôVb_]\͹ÃI•½ƒ£Àã�©]GÀé4†¦}§Ù´-pêô�w–åÿk÷+ƒkÏ1>á¡lÙ?ç;þm†££{ë»-f~Å8q_Ïó ï9N¿"ÿ�«´t;ZkýbßAz#¹ûå_Sç_$ú•å:ý»¿ðà%S�Œoç0¸~wnðáú‚|úßÓÕùÇÍc�‹?›ßçä‹ûíü>º}þWé© Nò¢·ù仑«iæ\1#WSg}Òøê§Œáu¾Ól»›žu\ôù[xÄîÆõç%òw²èeB8á²üLýŒè�}? *‹93!ÿ«�×ùN’d+©nkK®oõd[%s %ø*êü“«ª&i<ùƒ€ï��ÌÎ`Â�Æqûä§Ã6ƒï¯Î?®Ê¸ôäü¥ª7ç3ìÚÇÛ£  ?w®cB".VQP·ä³`c|Ç� ±»ñÀ%GïQšWýëjëêýç–'âµBÖXÞ‹Sô†÷�ÿÎÇöôv¤ï=‘ŒÀ…çùŽ ë0Ë­ðÿݹű™O>,iêýçj`²¼¶pÛ·®IÀèØ»+}'(.›ˆ>+ö€«™:ìxß9dµtenÈÿû'˜:®u¼½´÷Ÿ«#“£¡µwÅ^gNÜ{eþε(uŽñ¹¾+Þb_¸³�˜lœ]â†×ÁÍçÕÇÍPŠÑ?çõþÅSßÍäxü­Þ=ÏË[ò$Ï:ºá_ |§(&å|Ùwˆ­‰uàÀ <Ëwvûz ýê7aÑ*˜»¤÷ŸßÒ™¿,RX7>ӻϛ»8ÞW×ÿxÓѪŸÃüÊžãb^ÞǺ æü#Ávö£äí>þrAÀè�¾“ÄÓ­ÿr¸>¼¾ÏYœ¿,R8‹áÑ9½{¢­‚yËò(�þúœïEÈv¥vÊa¾SlI¼ €T& )ŠÚ¸¡ð‡‰µØo“º³ð»Çûvu÷Ä[ŽL˜§@R0—ßçÈöáyºõùx޼ºn{!žÙ’ÎÂs}GØ’Ø.}þ`œ�ì;GI=nœè>õ-¸áIdž¾}�Æ6x¤—W–�—Þƒ?>Õ·çèO¸>Ý.Z¡ƒý-$Ô�_A˜�æ|#¶;}ŶwP"ÉÇPU?øÝyAÉmé»-6ÀÿÞ‘ŸWÎÙé8®:3ð½[Â>]ýCîî�Ëï‹×óüÓ;O¼å;EñrT’íŒí…l| ?ï;BIû忉ý],þ8ß½9 § î~9^�ƒä®�¿þGÇ‹ïæçëÍxÐñèÜx<ÏxÒqåñÈRÔÜ|'ØœX®ö¡8ëÅEmâáÆø�ÆzõªWËšá˳½žßÏKþìX´*¯_RúÀ9ø�[·çq~®'Ò•›?O¡_YnAë]™\'ßÒ�íÐÔËšr?CËš¯¼OäWåk ¯ƒÝGCÒ¹ãƒS= mí„Ì™—·@C‹cá*ú|—ŠäCÇhk™Ù‡=Ãó/v/ö®nò8.÷�£ä¤+áÉ ¨ö�¤g¬€¿<ç¸íÇÜ"ÞH§ªÝÅ;dí±ÁqyŽ:3¬W­jÏý™ sCèMí¹N½©ÃÑܾöß:u꜔ ÇTk™9ËwŒuÅožÝ1Áw„’4ù‹MDz%ÏÍwüòxlnßvßKŠönxàµx "EÎÜ€X±pU玦¬l±]œX¤×ÂãÿPã#Kç.†ÿü»ãá7ÔŠH…dËÆXÛ‹|Y#^#åå§ãœ:ÿ¨M>ÂbÛùwtÃô3ttièXD+ ,sp…ï kÄ«pîßJNe9üÛA± úÐ[K`Êõ!¯Ç¦`é=çbUÄæj;·_²;ÄwŽ’3~?‹åA?·<ç8î2uþ"RDìP7pbß)ÖˆM@¦ëhmþãÁYŸô�`}ÎÁ/îv|ý†èo½)¬r2©#|‡X#>€e�õ¡äì4 öŸáÿLß¹Ùñë{µÐODŠ”‹M_‹+n†Ù1èe?Zã÷‹OçßÚ“—ÿýõEDâÄ8Îw„5â1P3iÚ÷4jÇï� ¡N›ªó‘¢çíjÏßÓw ˆK±)c†Àî#}§ÈmtsöÕ!¯F°Ç¾ˆHÄdÊ;ág}'(9ŸØÅÿÕè`êõ: DDJ‹¡À º°ìPß9JÎ'vö�.¿Ïqß+ö‘Òâø¤òÕ´ïÞ º»�Šì¸³8x'¿#�Ìq\v�:)Eýè¬<Üwÿ‹¡�’2zÐÚ“å|hl‡‹ÿϪÿ‘e¡÷¾/€;Êw‚’³ç(¿WÿÓþæXÒä5‚ˆˆWÎí;‚×ÀU_0ç3CIÚÃãêÿÎwÜü¬.ýE¤ÄÙήzâv>ø²ŸðÚ~©ÚÓcð“;Ný¿ˆ©à`ŸÍ{žp*|7ÔÏÀ£sO½í¥i‘ø ¼ö�~ C·ÿù0j ŸvûˆŸvEDb)ôÚz+Üð3kÀíë«ý’5°j+¢owÁ xä �ý‹ˆ¬µ¿9±ÚWãþFZÓéø_F{ºú¿õ_ºíODd}å4¥ôÕ¸Ç)Íÿ{1$ígþÿô#"²�Sáþ UøÐ¿*ú6ZáÅw£oWD$öüõ…^ Ç´ìã>Ú.yk¢oóÅ÷Ù0úvEDâï�\Ÿ=?#5Köú{i»Ô¥+£osîâèÛI@í²Ý}´ì§tõïM¥‡u—sTˆˆl–9/ù)L·ÿySî¡XÑ}›""IáØÇG³~ çööÒ®@y*ú6[;t€ˆÈæXÖKŸyàÀÀíu»²Z™‡š¯¥3ú6EDÃJd`Àä1`"oWr|lÆ“ŠÁ©Ó""ñ5ÐU�;:êF£e΢«Ÿ2nÇ«*�¾M‘$)/�|ÀÃ¥™Ÿ¡Y-“�¾ÍÊ~~vI  £/L ½êÊDßæ°ºèÛI–À€îð«©#ú6}@$"’f‘O�GZ8.¬v‰²MÙ@c{ômŽR "²»9&ô‹²ÁhGúwî©#€=kòPì¶]ômŠˆ$K95Cv‹²Áh ìi{²±Æ¶èïüÈ󲑈H’¤¢½K.ê5þ÷íƒÆèÛ¬(ƒÝGFß®ˆH¢¸HûȈGܸHÛ“�}° œ‡Í€ûˆnÙçÆFÙ\Ä#6&Úöd#ÝÐÐ}»Gy9íRD$All”­E\h Þ+Ó¶w IDAT[ýÀ~cŒ¡éÈ›I�±Q6Y�»ÐFDÕžlÁÜÅÑ·YÀçÔ4€ˆÈæ�ŠòVÀèFÒc"mO6ï À—>n˜j‘ÍHÑàöQ5]‡”��¬-Ù2#;…£÷T "²9Ù ²µrÑa´«e ^~ßy¹àÛÇ�j‘M² ²µrQÉ��°-Ù’åÍ0o¹Ÿ¶÷ 'ï¯ @DdS,º‹åè Ó±òìTE€ˆ@wIŸMà ÿÇÑû+á±¹ž+rÛÿätãò3Œê ßiDDürIŸÑ"À`P4íÈ6ûý¾¬õ¹�w]°¯Ö‹ŠH)‹¦ÏŒ¨pšˆ«^u|Ðè;ÅZ; ƒÛ¾ðÓ Æ€jßiDD¢ç¢é3#*¢Î�^È„0ó!ÿÓë Î8Äxì{mÔVúN$"¡0’>³,ŠF¢z0ÒK7<é˜t¸1r€ï$ëXß=Þ˜r„qýŽÿ{Ú±ÀÓÆ2ƒºªµ/OAõfnt©*‡ŠòMÿ_¿TõÛôÈÀ ]µÉÿ ] �ÝЕÍý½µ2Yhír¬l�-ÐÜу#"1SL€ �x]dÊ::ºá7÷;~rz°Kò'S^#Rœæ.†~rÏ+š�Þ«©èýð}u0¶¸‡ÿ74°®Ÿha äCá €T¹ö¸,V�mpÎ5ŽoüÑÑÖå;�$Q؇Ý&÷ ýJpÓœíúÃUgkàbWÖ�)t…/ÊšT»›ÿé8é×!¯,ô�D’¦­«÷#H㆖ÖÕÿºöcüç©¥ûøKAYYÁûÎÂý ÿ $æ,†/ ùñŽÎ‚®R,¬èýç®Í_Ž$:ããÔ�©(VËÚŠ``Q… €R‘ ¡þÇñ¿ ù×­ �­{ãƒÞnJK˜øŸÓŒQ}§�‚èW# VPjæ,†S~ã¸ä&Ǫ6ßi$Ξ~§÷…b[gƒ$T]\þ%#Ð@@ñi(øq¬/Œi@E@© üñIǧò§§ {þ»$Ó¢Uðòû½ÿüwWæ/K’¼“qö§T—nã¦b@»Æ”ª-ð­Gý,䎵‹ ¬u{^~O?Ok\r¼¦ŠŠk�¢•ˆ §qàR÷öR˜ô;Ç ¿ùû Žn •¼Û^è[、 Ýy²ZM¿ÜqÈR$,’>3ª’óÒ{0õ÷ŽCÿ;¤þAÇŠ߉ć9‹áù}ÿ:|JCk½‡qü>*Šƒ )b4æÚZÈiÓCþø”£E‹ºJÆ Oæ§ã¾éYÇ{Z ð¡Ž7*Ë}§�¾+¦ šá I lÏ̃Kþìøè¥!_šå˜ýˆcÎbßɤP­‚?=“Ÿ £¾w³#«E¦l?&¡Q€Ä‹f @4{I�h N¶¦£�ãxt€c@5컽±Ï°ïhØq¨±Ã`t…“p—þÕåõ¾‡ßp\rül‚ioàü#�Ÿv,nô�Dz˱*Šf"ÚLÚ­¥²�VµÁ#s�ÌYó/³Ü^è; †�5Æ�ZT›[•®Ìm“ øðˆX³Ü½ÒÕý •1 T'c#™Ævhh…ÆvGóê›iÚ:ÙheM%” ª1ÕävÊ‹Ûcüå=Ž»_ÎÿåÀ�O;^[èøÉcßíKûŦº|ïDãë7è²+±¬[dö\D@° H>8—B^´ z÷C•ûœ5…ÄØ!°Ã`cÇ¡0fpîý1C ®2Ÿ©7¯£Þ] V:,‡yËaÁr˜¿Ü±°a㎾gÖ~_†¤aôÀÜèÉNÃ`·í`÷‘ƃòözä�eð_·9î+àé‘/¿'_î8f/¿±»QÓ¯`ÍÅÚiû×ýÃåe¡¥xDrÖzTÇIER͈ôغ…Äo­Û)åÞTc†À˜ÕÁ˜Á¹£XVC]¥‘®Ê]i”¥ø°£É„кzx;“…¦ŽÜÕûª6XÕ r�ü»+ó—çCò^öå͹·Þ]ÿ1ÖUÁÞ£`�QÆ#a§a0nˆ1°&?í6wäÚ|n~îûûÔ۹͡ -Â�/9î| Ì£Â.Ã�Áµ¹Q¡êŠõ?¾³;W„uvCGfíû�ÝŽ €t•Ñ¿2÷³°×hØ{”1¢áG_™ÁžjŒ¿\{%$’+¦€hŒHÞ¬lͽ=¿É3 ’ÿŠÚÔ�¿�oPüô¯†aéÜôÁ�´Ñ¿*·æ¢bõº‹U¹‚¥±cí×q.Wô,it,oÉÝŸßɦ-sÞ_ ï¯ìËóµáç:v 'îkŒÿ¨1nh_Ö~;ŸûXî´NI– š‹æ¨¦V€VéŠÄ^c[îíÍ%P …N!¼¾^_äøÅÝŽ£ö0¾vtîxÞ8ú÷“Œ»_q´h3Öd‰æ¢9¢Ba$ó""‘qîÕ1þrÇYW;Þoð�hcCÓðµ£ãYœÈæ™EÒgFTÚ©CDŠ×ý¯:ŽøiÈ5�ÅoÎýœÃŒ±C|§�m’�¤ÏŒ¦°.�ˆHqkïÊíqpÆlÇÒ&ßiÖª(ƒÿ8E£IPD#©*-‘ÒðèÇøËCæÆh7ËÏìa¾›Š€¤è×^ïÅ{©¿¶Kž{˜úhÙ×]@𸿶EDbf˜Ç`îbm—<}¡¿À¡@Dd�‡ùkûí¥ZàϾöW´T>èÞ€�‡ùY� áu�ç”¶.š+ÿé«qo€qY;8Ý("RQc‡øiûå…Ž–?mËs¹¾Ð�kÌÛЇˆHl컽¿�€Ÿë§]Áwè·Ð:8xg·þãMÍÿ{ãw1¼ç@wˆˆð‰]ü´ÛÔÏÎóÓ¶@èžöÙ¼×ÀZëïøÌ "âÕàZøøŽ~FîyÙÑÑí¥iáÍÕ} 7ž×f÷ûŽ "âÍÉûež^Šÿþ‚ŸvŒû|Gð_¸ànßDD¼9ý?Wÿ+[ás5ÿï�yïûü•îÀãAØ""žöcŸíý´}ã3Žî¬Ÿ¶¥“ {Äwï€-«oçå$$¯.8ÊO»Ù~ÿ¸®þ}qî±\ßç—÷ GÓ"RbŽÜÃ8ÔÓí¾áxO²zøþ‡¸a6ß ‘HÔTÀON÷wïÿ5�êêß§0½±(¬uöËïùÎ!"‰ÿ<Õ9ÀOÛ/¼çxL»ÿyc¼g-õ¯ûŽ1)pþo‰)¸s3¾p�¿«ÿËõRë—Ýå;Á1*‚Ø|SDD â³{?ï¯óã¸ÿU ÿûäˆM_Ÿ _ê~@[R‰HqúüAƬ¯øÛôà'w:œú�º)/{Øwˆ5bSØÊéMàt: ˆ—òüp¼ñ«óÛù?óŽÓÕ¿gæþ‘ëëâ¡Ìw€õXðWœû´ï""y1z \y¦ñ±±þ†ýœƒß®Îß·Ðnña]± k7ÚšJD’­_L=Êxà;�÷ÎàŽ—ÿœï;E©Ëâ2ñb]þ07àÒ“Ó(€ˆ$O`¹…~ß?Á7Ôwšœ® ñ³�Ë}')mƃÖ4ó3¾c¬+^SÎnÂP7k`h†¥ÁlmáXQ•åk?®_ ªúA]T÷ƒŠ2P�û¸ªòuÿݨ­Ì½ßo�C#÷1[Ò•�öuÖ‹f²ÐÒ™ÛÞ´¥2¡cE+,XÿZ�Ìq4¶åçû�o�Áð:ÞÒ•Fº‚Í ÌutCçëd�s4uäÞ_ó}Xó~kWnè·©½pù%§_ŒßÏ8ÿHc—á¾Ó¬ïO:uþ1àìFß6¿€ò›¡ë×`1ÌVBF€cö2ŽÙ gëuò¾õ+[¿h€Ü™êk­?²Õ™1þüŒã²{K=¯¿Ù®?¾»qÐ8Øw{cì��˶Ùú(^6„†6hh…ÆvGCkî$¸†VXÖ’û³¡ [+ÛrV6\[Ltv£3ã7!0øØX8ícÆI5TûN´±Ævøõ½šû÷Îepåó�bC±›pu“îÇÙ¾s”¤Ñá¢ÏŸ;ÀïŠåBXÑß¼1ú•ÐfpÊþÆÃA;A,íz¦µ+7º°¡Ž Š„uGZ:¡ƒö®\qÑ™É}ìº#�ë¬6õÌtg ­kýë솎ÌÚ¿g²ÐÚ™k«½+÷ñÍÐѵþhQ_TWÀ.Ã`¯ÑƧv…Cv² Ïøùæ�ŽŸVà�»×šgç;ņây•í‚?ƒS%3¸ðh㟱>^‘Æ×àZ¸úlãk7Àßž�æEqÔ@øÍÆÇwLp¯¿Žš~›þ÷þ[œ¶‰ò±oº­¦ö\!ÐÑ�{?ë-ë̦¦XúWCm% ­5F ,Päyâ-ÇŸŸQç ©Ø ÿC\ ²›®i€ˆ ¨ÎuRGî^�Ô–¤¸ü Ã/pð‰�aÆWÕ´é�ºª ×–÷Ïz{7\ògmúÝXçß}‡Ø”XŽñZóìå8ò�£$¤+áÆ)AItþk”pÙ��Œ(\Çìeü~¢:ñãqÌ׿xp÷YÓÕ±<{9–fö¡èU–ÃïÏ3öå;Iô*Êà×_ (Oåÿk¼ÔŸiThK<¸íÍûlj±þ‡XÝ·�[ý8é½ÿ:Õ8p\é\ùohïÑpö§òûøG€ßžÄê® )o-É-ü“x0×N*{›ï›ÛÀš®^‰¹[}ç(Zû��/|¼t;ÿ5&~Úò6 `W|Ù¨añ`e+œuuH›®›bÃÙÍÖ0»ÑwŒÍ‰m@˜ú­ïE)0øùçƒDߎ–/#úÃñûäçñ…ƒŒƒŠdµ¿$KG7œ{M¨yÿ¸±«}'Ø’x-õoúŽQtŽØÝØm;ß)âãôûþ5*ËáÛÇ©ó—èeC¸èÿÏÌó�DÖ7‡æÿðbKb]8°k}ç(:§à;A¼0ÖHõñWá 7†×å'�HO…¾ù'Çm/hÞ?vì*ÛôÖV±ë€°û:@û�æ‹ö]©®+]IŸGD¾¨õ1çàû·8nþg¬;™Õ…sðbkb_XëUKÀÝá;GÑ3xk»¶•¦Ý·ë}>n(ìU‚·RŠ?ÝÙܰÿžPçGæþf-3—úޱ5±/0-Ì›Q|'ˆ§ÚÊÞîá»éê_¢ÓÜ_¹JWþqfÁU¾#ôD2 €¦a÷‚[à;FQ¨ªPgµ)Ù°÷Ÿ»ÏèüåÙ’ásW„<:G�|Í£qøƒ¾CôD" cZˆ ®ó�£(tg¶þ1¥¨¥÷Nï4,9D6ç©·Çý*äµE¾“ÈÙ5Æ´>\QD'Y»ØÄ9¤²M7êÊaS¬èý÷e`�FU¤°þø”ã‹3Ë›}'‘-r2îw¾SôTb k¯Üß|çH¼+rç±ËZÙæ.îýç÷õB‘ÍYÞ_½ÆqÉŸݺþ‰=³¿XûÌ…¾côT²^¹,õ3߯£^|W£ëzu!� ¿-úò¹"›sÏ+Ž£~rï+ú}MŒð×¾l‹DÖTÿ,ð¸ï‰wÛ‹¾ÄË/õívþr½@Kþ,o�¯Ýà8çÇŠßi¤ÇÜ#Ö4ûiß)¶E¢ €û•ï‰wӳޕ­¾SÄCwþÒÇÛ©^Õ¢,Éçà–çGþ4ä/Ï©¨LœäõMÉ+š‡ÿ�Ð7-pù}z�øÛóŽúxX×sóô½”¾yvžãäé!_¿AÅy"¹¹4�¸ÓwŠm•¸ wK —ûΑx×?áxk‰ï~µwÃÏîì{çýÔÛh¨Vzå�ଫ§Nwük¾ï4Òk©_%åÖ¿u%® .ü s/û¢+ç\ÒØî;‰??½Ó±hUß¿N&Ì�$ˆôÔ¿8ιÖqÌ/BîU?;ɶ”æŠØïû¿)‰,lÑì6ÌfúΑxo/…)¿wt•àm�÷¿æ¸úÑü½ð^ù€£]gVÉtgáî—® ¹ãž—¡úþÄsÔ—%òJ*±˜¸ÚÉØ‡£›¸ �ƒÙg ©õ�$Ï¿ëø|½£½+¿_÷œÃŒ�’Øß))�·–ÀŸžuÜò¬c™6ò)2m޳æÙ‰‘Nô‹•KOž œã;GQ5®<Ó8`l¢&¶êÉ·g]åhíÃÖ¿[rÙ� ÷÷P¶îÕ…p×ËŽ»^rÌéÃ&Sof3¬iƾcôV¢_¨\ú¼]!õ �ò�¥h|voã»Ç» ÷�$¿B³vüäG¦€kuÌà»ÇSŽ4‚DÿzIOeÂÜtÚÓo;žz'÷ç’&ß©¤ðº lkœñŽï ½•øW(—žt-Øÿó�£¨¤øØ˜\1pôƸ¡$¶3ëÌÀcs¿¾×ñ»ѵ»ïöðï'‡ìdXB¿w’+›; “ÍÝé±´9×¹°*7´ÿÆŽ7—h{í’dWYóŒI¾SôEâ_™Ü€ÉcÉò:ÐÏw–¢UYÃê vfÔUmüóSQžûøš (  ®*WPÔUBy*÷ïåPYUý _Yîóú¥ ²|ã¯WW•û³i3klŽæŽÜ&*«Úro ­°¢^_äxñ= 6Üß; ƒö5>µ+ì=Ú¨­ð—ek²áú§"6µ³Þ"µ0Ìu†AéÍ,¿)  ¶rÍÏHÁânRw6÷ü¯jƒ†6GC+¬ÜàmU¬jut­Þ[¿¹cíqÐMí°æ!7¶E›]’¤‹ ³‡5^5Ïw�¾H|àÒSf�;×w‘­9F„!ic`ÍÚ"(@º‡ÅAåê"k]vÖÙšWwæ�ݹ3 šÚs{tvCc»££Ú» ©:º {›®Ì 5ý ,µö1¤¨­Øøu¨²T”­ÿo«³´v92«;ðUm¹°¡Mç2H4Œzkšy¡ï}UÀÀ‰;� Þb|y%""‰gtÐ�ùˆµ_õ¾ï(}•È}6d ³ßŸÚw)rÎfCçER�  hÒNDD ¥•°»hŽ¥/šÀÚf6Ûw)ZWZëUEsˆJÑ9Ùÿ´Õ–ˆˆä[ ®ß1’N@XsýÕ`¿ô�CD¤èÿk-3fúŽQ TäKóŒïàÜÿùŽ!"R´ÌÝDÓˆK}Ç(*òÄÀÑÒy.¸'|g)Bÿ ©ó,cZè;H±P�GÆu¸~§oøÎ""RD^ƒÔiÆu¾ƒíP®jò(ÊxØÑw‘„{›lÙáÖvÅ"ßAŠ�F ÀÚg.¤,< ÜßYDDËxŸ óYuþ…¡ @¬aö»ŸûÎ""’@K ƒcuº_á¨( kšõ&¡¬ô�ED$9Ü*²o-õ¯ûNRÌT˜µÎx ã Ùw‘øsMXêXk›ù¼ï$ÅN@¬iæ3´úÎ""cm¸àkªÖw�R  "Ö\ÿ��túÎ""C]X0ÁZf<â;H©P!kœq?Ø¿¡"@Dd]�À„ÜÙ*íà�«½àp,ó7 ÖwÏÚR§épŸè©ðÄ¥§| ¿ƒÕùÎ""âI .8ÅZêò¤©ðÈõŸò1Bw0Øw‘ˆ5`v¢5ÍxÊw�R¥À3W;iÌî¶ó�ED$"KíXk�ñ’ï ¥L‹=³–Y¯�…ñ¾ï,""x²‡«ó÷O@ XóŒ9©ÃÀ½å;‹ˆHÍ#°£¬ù·s}MÄŠ«™:‚ ¼ØËw‘<{ƒ ÇXûÌ…¾ƒHŽFbÄZëãÊ�žô�ED$�ƒÔaêüãE@ÌXËôe4—…ãO¾³ˆˆô™q ÍUÇYó•+|G‘õi ¦u“/Åq©ï,""½â˜Nˈ‹�i¡ï(²1ÿ¿½{‹±«,ã0þ¼kwZ:�¶Ô¡ (P‰š4*U‚•ƒQ£<�Fé µ @I¸0E0�AÚaðbTÅP<†DH€ ‰PÎ``N-�Î^¯-°­Óùfïýü’Þ?sѬ¾µöZÓ\Î]þi`5ÐUºE’¶MN�qZŒö_RºD/ÏÐrþŠ÷P×?÷­�’ZÀ(Ÿˆá5¿-¢Wæh9gÙ4ªµ${—n‘¤—–�ÑŒccCÿ�¥Kô¿ù`‹ˆ±�»™˜q(pGéIú/‘e¢q¨ÿÖáh!±á;�1küHȵ¥[$éy®fVã�±qõÃ¥C´í¼Ђ‚¹}_„ú< QºGRÇj|•áWŸë“þ­ÇвgåáÄÄO€ÝK·Hê8ƒTñÉZs]éí@‹ËÙ}{3£þppéIãÏô¯+¢ç3-.6®~˜‘g�¾_ºER'È12û]^ü[Ÿ'm$çö�õ…ÀÌÒ-’ÚÎ&¨>#«/-¢Éáh39Å’­/ Ú·t‹¤6<õ 1¿à×¹"ç.?r Ä^¥[$ítOœÃýW”QY> b¤ÿZ³.ÅßûJí+òª­÷ú½øË½Pö¬x7Q÷C¼±t‹¤Is?ucyŒ]|}éMžèbtÍ�ŒtÄ–÷4K÷HúäÉEt�½Å‹¿^̽¬œÿÙ·QÇj`IéIÛí6šôņþ;K‡hzrè%ó–ŸHòuàÕ¥{$ýO�Cu#»/XåÛ?õ²Ú&¹ÇÒ9lœs&ð%’]J÷Hú/ã$—0³ëËñÔEÃ¥c4ý9´]rÁ²}˜ˆs!N,Ý"é9ùkªê 1´æþÒ%jí�ìYy8Õæ È8°t‹Ô¹ò^ªÆé1´ú¥KÔzÚaɪŠyO|ŠäÀî¥{¤2HpÃ?÷×:Ú!ýßrþŠdžAr*ÐSºGjc#D|›Fóüxz`¨tŒZ›@“&ç~®šg+�îÒ=R#ù>9ñµûî“¥cÔštÙsêBbóéDžJÆìÒ=R .§YŸ/£öâÐN“³O~-�g,f•î‘ZÈfà2&876ö?Z:FíÉ �nËO«³!O‚˜QºGšÆ6C^I•_‰¡�”ŽQ{shÊä¼Ï¾�Œ3–ú2!éy"7B\NÄ·ü-¿¦Š@SnË3Í“ > سt�TN®‡øÍúBïñkª9TLrê,æm>�̳ —Ð?¾COýÝxl`Céu&€ŠKVUÌ}âDžFÆQ¥{¤�è&²º�ÑõWû•æÐ´’óVy:ɇ€Féi4‰¼â[1Ü[éé9MKÙ½lO3–B} °_éi»��ü˜F£?ž¹øÁÒ9Ò‹94­%«*æ¬?‚ÆÄ22Žf–n’^Á8äÉÆ=æ×tçPËÈù+PÇÇ ^ ¼©t�ôy4~@Ö—Åhÿ?K×HÛ –”óW,¡ÎS€OáwTÆ&"×Òœ1ÀØÅ7dé i{8ÔÒr×/ìJsÓq�ŽºJ7©­�C^OÄ•4êkü"ŸZ™@mcëg‰�&óxˆ÷âÐäh·\EÍO=âW»p¨-å¼Ï¼ º>¸e ð>¿A íT!¸ŠæÄ•~‚WíÈ ¶—ÝËödFõQ2?q(ž è¥�yuã—äø/¼è«Ý9ÔQr�¥s�wÑ<†à8`ŸÒM*ê ÈëÈÆZº&þè=}u€:ZÎ_±uÍc ÞÌ*ݤ�)' n…êZª¼ž¡5wøô¾:•@Ú*öõðlIð~²> âõ¥›4ò>¢ºžÌßÑ=ö§xòбÒEÒtà�^FÎ9yªoÛúïmxB0ÍåÄ]$7Sq;�úÆxzà¡ÒUÒtä�¶Q²¬‹ù�É< ò02v+ÝÕáFˆ¼ â&š�?36óæà‚�¥£¤Và�vP²ª¢gýb"!óÍDý&ˆ�¥ÛÚÔS�w“�»‰ú.2oaô’{½‡/í€4ɶ|³ ¹?QDæˆÅû“ìRº­5äÄ}DÞqÉíTqCkðb/M€4’ãg2çU‹iTûC¾�äuÀ"‚E$¯ªÒ�S¬ < ¬ƒ\GÄ:¨î£™g¬yo0°¹lžÔþRaÉñ3™·pš±/U."ê×Qç"‚}�E½´ÞÇ› �u$RU�±Ž¬ Q?Èy‘—ÊrH- öõ°9zÉz7ˆ^’^¨{�^êè…ì…Ü�ˆl Ý@[Þz¸+Ûÿ=�g€q` Øl"óiˆA Rå 0Õ Á ä Qý‹®Œõ«G'ëo—´s8¤’ ûzÏ—~òÌØì…[’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$IÓÁ¿�Uë@\9(ãIEND®B`‚python-msgspec-0.22.0/docs/_static/zero.png000066400000000000000000001570021525673062400206350ustar00rootroot00000000000000‰PNG  IHDRôôD´HÝ!ízTXtRaw profile type exifxÚÍ›iŽ9’…ÿósî4‡+Ð7˜ãÏ÷)µ¤V¥ê`JU™Y©wº-o12Üùï\÷_üc±x—K³Úkõü“{îqðƒùÏ?ã} >¿¯ïŸ›¿~ ?ÿÞ}ÿ‹È÷Ä÷ôù «ŸïáÛï¿Þðí{üT~¸�­¯¿˜?ÿEÏŸïÑ~¹Ð×�’Vùa]¨](ÅÏ_„¯ ŒÏcùÚ­ýøó|¾½ÿþsú2¿ý¶|½ø—ÿÏ�èíÂ}RŒ'…äùšÒ×’þK. ~¨| ‰pð5ÿMJöµò»8}ÿ§+ØZjþí‹~ÊÊ÷ŸÂïï~ÍVŽ_/I¿¹~ÿþÛß»P~Ÿ•úîœí{™üôû³Âù¬è—èë¿{·Ý÷Ì<ÅÈ•Pׯ‡úö(ï'^7¹…nmŽ¥Ußø¯p‰öþtþU½(…í—ŸüY¡‡HºnÈa‡n8ïû ‹%æx\lüãŠéýÒR‹=®ôÉÂ�-õ´“‘äõÒžSü¾–ðnÛýrïnÆ�wà¥1p±À[þø�ûÓ7Ü«VÁÛ÷X±®l–¡Ìé+/##á~µ¼ûóë?Êk"ƒEQV‹t;?—˜%ü ÒKtâ……ïŸ m]€qëÂbè‰ÈZH%Ôà[Œ-i$h°ô˜rœd ”7‹Œ9¥Jn,êÖ¼¥…÷ÒX"¿vü0#…þj䦧A²r.ÔOËF �’J.¥ÔÒŠ•^FM5×RkmU 8ZjÙµÒjkÍZoÃ’e+V­™Y·ÑcO€féµ·n½÷1¸çàʃw^0ÆŒ3Í<‹›u¶i³Ï±(Ÿ•WYuµe«¯±ãNüØu·m»ïq¡”N>åÔÓŽ�~Æ¥Ônjo¹õ¶k·ßñ=k_iý—?�µð•µø2¥¶ïYã·­}»Dœ匄E—oJ•3o!ç¨Ì)g¾©DY”³”12˜Oˆå†o¹sñ“Qeî?Ê›kù§¼Å¿›9§Ôýaæþ5o¿ËÚ ­—±O*¨>Ñ}¼fDã_¸ê_¿»÷úýÿÁ…Ò°eCœ®ÿ}~ø[ß{轄L·yW Œ›;¤*¹Pmœ– ?k5Ã!-¦²³Ñ™BÈ{îH«�ÒÇ©ã¦Ãßž)„$­Ñ›µ;kžýjs÷¾zI�·öCj§ÝÌíç2•2µrc_6÷�«�˜ëHw—sZeŽ[["õ´ÂÉóž�‹�vÏ.#í�îâßukÖåzeÁ«ÎÂe]%–p:½Æûc÷™®Ù–³ ¦?gûÉ»NnwÕQO…vÖ°<[«i{â°êN,„JwgPf‡ˆk(�+ÇYÁf^}-p‹AK-€¸�¹Ê†üÆ ÌQü;ËÚ;»~ÊÊs—éó½q(x…•�}Sn£ìYÓl¬¶Ý\ÂÝ™Ç.³ÄøïrÍ5f�µ®è¬�r©z�)[1(}›ºvXFŠ®ø¬å5ÃÞA_ΉTô°�Ø:Oà‰Â\ç\î¶a‚ÖéÔÍbwçóøå¥7Ú]cŒ3¶0l”¹šß[2Íqn µÅÅåx÷±|G+üv4 – )5Ý"¬DÂרÀDkh‰9 ƒ-ˆÌ¶S8§ Ua¿!ê!‰—eîÛÏiÈ`”°“TQ™ïÅ£ˆÇà^’IΨ 4ÔcwÆÍÛx,þíþöäyjâATîºÂÂbdIà•[¿=Æ™s«5P�äQç§#g÷§ÿ½î?m¡gA @DUÝ�›@¶õÚÎJ[ë”ÎÇ#ð¸”öR­£LIt�³¹&ò˜–TTéÕfEonz*ò7Ùù�2j-VB�@[C„NB»!ƺTY¨ðL‡U@ƒ]ÇœóœdaÇIý!5Òi�R8. RË6‚I‹DðÚA¥ j,q×ûdͪåÈ3ѻͧY¼2Ƚk-ð—H<´ÀýÒ]¶�k¤ `gÚšÝ DÂ¥7Œ"–ë£y2&ôÐ:²%7`‰æ¢Ö{'±žÈšåá�Ц¢ŒÛ¼}íK‘ôD .¨°´‹í«�Ÿ›ý`­Á�Æ[hÖwñ¿ÙªcmyÝ3 })Âþ�€¤Ÿ4'Z¸‡õ.2h;“‡,ò>€Â[¤ ÁÌfŽçˆ;f�åÀxuƒS2OÁv¯tØí�L‡…äž„É%eÚ[Y`ROó‘ ²æé�Lz{HT�}£Ò©íÖW$ö¬;B°ÆÓ‚¤ƒ{P3šÛÎÜ®úW¸i‘%RŸ:Iñ \\Vç‘/™Z·-òØ)›\ü²}çÊèô•I-ŒÞfsTОe¨0(‹A³”Ò…L…b#ÁoJË61}''®ÈÛãÐZe` 7}áîðAǃyr¤"�ÖòÙäŠ|‚sÃz´ñðS‡\ú^Àe¹Ø‹|à3ɨ£Šá¡¹+}ÙÙ ùCY_ªwdäÜÞñ?)W‹D«Å‹0Z`ÄD™­°Ý¥EØ´+Nè„^Iv]iÞPdY‹þœF™´(%„:¦ÀØy„^ª’8ÌÌ}¨ú#W@±(wL´O¼þà]LP †ÃOÙ¢…`ÈÐ`ÓA°á†'ÖM‹Ò©Ô€Q¿ã¢þ: 9Cîݨg 3Qµ¤ Ož`Âd€ ¦Ú#÷ñ‚œqûNqÏCyªŸ wÏÂ�(q Õèf@dGôÑ‘` Kä7½N­š!®t ‡8c¥A@oÁÝqY–`¤8@6‚u.ˆ‚»y<W0Å‚‹|¥¢<¿hº–oëýáoôàQ:–.%À…èn$¬C1øC/ukðîÝGËéÀÿ¥ïU»=Ó,_ËqJˆÖ9bôSš©-ät„�‡Èq; äF¢4ñ–P”vü:�ý‚hv4Ü­‰Ë™•M7‚·IzÃ2]‰Š È…Wý»;~ãàÜñ‚`X^£Ìåˆ(AP)n‹!£¢i‡ Q뙺Ý%²á¼ŠrÇ �×ÚÈé¼Pp5r[((iI«G@u &ª±¢äû¤ÊáL’¶Šf¤ ÁDÇSô¢0 +J�]°†’¹à»tJ÷BLÚcÞ K%% �´nˆµ¸w©ƒkô/Ú!¹aÔJ>ùJ^_*0›6Ž—Zg™€áãV¨–A³ÒêH+ür�$­‰1¶¬;‘Y/Y|Px€³/ O&BÖÐÂÖ,cç1în·É~ Ç èj<x”hÊ(ŸA ó�±ßûzÓ>ÿ4Ú÷ÈJ(¥±ÃhX¦™$S©öÚÐzÁ!½@+Äk°`¿:EÕn·´Íd*†r"îÐ- ,M‰X¥RЦ €f%æpBb�ãÑW0š8 ²¡0ÊÓ°•�¢_fšÒ6´ãÜ›ëW£þÐ}u-XdceT?¢Æ§ô皆jXÕ]È#æ@KÁ@ü�2Zb¾QI‡ª¿{u�1Â1¯ƒYŽ&3J�Y¤Eú§Ñ›4®³ô†wˆ�ŽÃàfI8¶c"9I ”Z�ð-H�oˆyÝʪ>”Ïÿš®�oé ¨Úa”æAÔE?‘CˆØ`­àÁb¸ªjY/|€°I@ìÓš(©�Ö?hMjV1ÁaÜa„g˜¬ñÚ$5pgšvÁÆz£¹#È™C×�iM¤J´váCA3ÉÖ®ŒTT#9ÂØ¨yg ljÐd~é;Ì `8ô?F‘Êî"Œvn«–u =h7 Õ ‘†tÕð(‡v@N¤^+l¾•I=&�R‡hÔбi9ÞGE¸0É9lÃk#¢´ès²–T zàÓö±ÁÓ@»¬ yu.Y�þÆ“ˆá�UtÙ‰n çNF0hž1A‹ðÜëL:‘d©B’´/ž<*ÐÑo ÒŒè³~ÝÒâx¹9©~JJ‹'Õû‚£(ˆi¤þÑz`*Ø=Káàw× !8Mž©ËQï(š=4àØb®á9¬ÌæÒÁ—úF(A¨Þ.öC–‡9k¯¡Þ@£"lP�hÙÄJÑK§�}L OÆÞ×Ç\ã‚æ\‹óÓtàd,¯}éˆIã4IÄyä[ÁËq¦Ö+_+½€0Zú&CŒäËʼnëÁ)¹Ê-…BÈþ:¤ ÿÅpœÃ“„:žÄç=�‘%^qR†‰(˜cœ€´�RÄ�hyĉh®$ñDçFã9Çõ8|-­død9°¹Z�ÃiBÚ­I¹!Ä@Púƒr*mvèêB®IÖ¦-õˆåN÷ [Vžl�"×Oh"\+Å@{z—¿² „ô{"O<èƒ 7èŠ÷À§^@'AqÜ 67�µÀ®Ããt•t¿†Í©% óh8j�îj®â:ü†Ö‘[ÔÛ<+¦–—êw5Ìð±&²‡Jš`J�É€+*¥ˆ¥�K�%ö½Ž¢'w"ϲ}D±xÓP""€büΟò0¹Nž ¨Áå³\Ñ¢úÐÝV�ኽ3Ä>Td€„á¹"Ͻ19ëâØ ª†‡ïømÿÐ.°Zц×KYê qâmÁi�¡î´W)YCnºŽZÇv�ÿXh–ûS\”ßÔþ†Á‹8‡Uä ¼†*ÕýÄœ@Ú}m"êî‚EÀIÎä"r_…ƒ‘ò‰4+P0'¦Ê§æfKŽ8Ç$uUºÔ±Š\;—D’ÌAÃxG 쳇B™ZÑ¡·Éš†‹SoÏMhà £xB™zHöE� BãTœ€‰‡¡ÛQ åxQäTd°¶T/ôÝîBIÊ}Nˆ[4ÎZz'¨ ˜Gk[S;ó€ïeî“PÉr—Gƒ¡§B¶L¾¬©Üñ#ÐèÞy|f0\´¸ôÜÍ 64�G€_”çºjåËÂ@-ÕzA;Ð^¬š^ÇÀÓätb¤$i@£ï¤/Téq}ÈK…5“±7Â¤ì´ ‰(šÝoèµ&D Ôqü&&(¼%8Š uÚ4F Ya¾'KÓÖìFÐڇϣ³3<<»ÌþJà>½Ð² ¸%=m—±sxt9¡£¹{ aIol= 7Ag¯s£ =Ù; ¹÷¼´ÝÚ¨<8º" éWg�šäeI m2àGqTHÙÚ² _XuE»Ì‘Oÿ´rÓääÛ ³4¾8^wafT–ÆzÑ�ºß€dR ‚§«q 5H#£ÄY}ÅGæBzPNR Émßµð}ü*MIï÷%ï¹°ì�—F͘àoQ7Sso?θa~S¦íè/=ȃø7´‹'Èð…€üŠ>ž Õ€Ònˆt¾´ãú(”¨tƒl.!Ç„•ó'íJQ@ëàó7L*°"¶Q= â¡·MÈ;žˆ:>(<817޾F/N�¬Œ7¯Ñl©ƒhšŒx94aЮ#òƒ4‘þÚ ¡Šh‘ÿ4Æ!F•[ö‰„“t—' kýù&~ ˆ¡=;¬ œ >ºà“dÄòš¡àŠlOVçíå³>°ÿèÔÂ¥ÐçuØw˜ ­3tüÌWK=eÞ­h\mƒ�é?!à!ËÒâH×6T"pi‚&›{jÇÝphÇ� ³Â·W0ÚR’h¾Óå9Ñ€˜›Io~(u}*ÐLWA™(E$�àò0Ùkê„zÚ¬8=Ïú»ìì*Q� UMµttJ„ÍÖ+ÛØ4Û鎂Æ0jý’_šgü�­§Žö)ÅÃÂÑr>½êNèx=˜ÑÐý .äUÛb5Í› IÓå™\=É#&´Ù’¾öøuuŠª"²Q7È_jæR!ˆº^ýЦúnJòW¸âº³R[æB…�Ì AY5¡Á!ø9’½¡¤%§?šŒdm�7Æÿò '¹/ãð6(K4n‚Èߢö—Àk¸ÌÒ;wÕhàs4×E�Š£�c¼1kçÔ} MÇBªF©MhªfÆ’ßä6¼¬)ÿÝú)Ér ìh_Ä~–ù²�“^#¤Çó  sCàÁ{¸}�@‘¦TdS‹I”7J<â~cÔ¶Jk³!o5URø;!%�P½ò1�Ît랺Ñ)Iº§‘ßQ;ê­$8²{dÁ�F �°“qH„¨7î«Al*ibøx²Á iÑ7 «Æ’°�òÕY3inÒ )¸®v Ñè9üx ´"x 5eÁ:#ŠÐ•H_Ce”¦vmð�ðygé…xÈlD;šýCÊÚôGæ$zǃ$¤ä9P¿K}¿±J×aTÃO$±Eõ÷FÒá\äaÑ2P¯Ž–èЋAQëÀU\ùÆ95ºTƒ  ~ -:\ÒµÇ;ÿˆM’Ž[žB¯8�koײ*[¶�Rš0¶³RgÜšêq ž"OÅu0•Æ©iÓ³S5ÈåÙ�ÎQÉu梙µæW¨ý~Ž$ ë)x…НŸéüÈ¿k÷×pb@÷x'º«šFI�RD®P�HCÛR#óо(Ó’ç8"Í îJK|1(Tª6×®ÚéÈ!A÷²ÞTûЬ\§X ÂmnÐýÙ¤äQïË<ÑE Ò7ù‰!è”´—¦¹ŽL1ê:iÄ_•×»ÙƒGW`@üÚ™âs‹ ôðõ��d¡Ñ0«ú ts_�¹Þ À€“‘5FÂ�¾™Rõeh3, ù\8@A)¢ÐÀ©û¤ÃÎñíßð¸go@°9pG#¯‘šPÌ¿3\ÈStàÒa<¹‡Ý5?U[ATnDГwÒÃ<”�pµQ �RšR‹[qß[œ³Ž ¸©-”‡á×*ݹ5.° H)õ c Ôˆ“�õ¾ð°ÈÈC~à-ª:‹—µÔÞ`±>ï­i·v]093ë$¯“w +ãÞ¹™*?QÅ츔4j@ýÞ¦­J0Wþw�t¤ºV<Æ"HÏ@ÈjÃÅ®Ë(ígSD:i¨mÚP›�5ë/rÉ~ýbû÷•MWâ(åÂТˆê‚œ„pâFøI©Y K€?”–wè3?2‚6šOcs�Ï©+ÈýAkù”ûÙrÕù+âÏ;’H²ÁÕ{�ÇæJ9ñEœ{†: AùÙ ±V miš™ê ��ÅOŠ}¥¨3,[¾?ó._¨)Ò�7,Ú¤tࣲw“ ÷ª#Uý„eÎ�qÍèäeH]=X¡¢KçHÙ˜0 cOÊêT‰Ú_ùŽ·bPò:?Ô!80†�)cMï•3à×ÎzÛ;�HiC€#Ô]°2â£c“ÌëÙ ¼J')†¡ÌŠÑ$¶=8Z‰*N:}* Žx�¡³!~@ÌÛíuªN<€ÂèĈrJ+áªhQù•á´K…í%7«Ö¨C„‹NçÇÒq$I�›1Ëä)+=_¹ÑôM† CögEÕŒôûÒ&—=úúFOqië?}ÉŠ!ä¢öZe¤£Ð €†Ônþ{ÇnQ¡W�9ñ:µ–²FüpÚtÊèVeQZò@1�®¢íàOòƒƒ¤ÃI0rŠ®úQbB§�%sÅs`l£+ùø±ôOÉ‘]@Fçväèþ$ü@µM�»{r Íú¼‡Vþ—¿;oò˜bE@ä9®ˆL; ¸˜�Ì¢ƒ‘©hãõZæ~j”KÈ\è‚ „´Óq"Q¬H¦ºõ:�4þÈÚ}»Æ`MÔu¼ZsÛƒzvÍèÇ›M¿O‘ÈèPÃv¦tšœƒ*´Þ 5ÁÀU{ðYb�:ÜÞã&5®u:-pÄÁZžóS0t OB´½º ¤: õöêÜÑ7³J\AµFÌ�“X$ÚÉ}Žf)…q?´‰]0T2° ¾Oáz‰¨óÖ:(bÔ½ s{@”�ñ;²ãS'ëõ Ê'àïy¤Ë�1EHbmðÏ´ô.ÐÍ¡2MP±+øòâD9@)0Êñp}¤ÚA[¥ÅËS™šôc �R wBáH‰� òѹÞø#Ba>¯±0µu€m�Ysð=‡ŽÙc\•ÿél`øA/m¡ÙÒIk[Ž&øªGÚ-Îó6, i,¦àÕ´¨‡¤\ë†jÅt:}‘ìNx§Š93º_;–:n­åÌ�¸�Ò;:Iàç¬ j"+­@Ä# Ô#z[ë['Btˆí_µ¡±Þ'ÎvØT' ¥Ç|䤣³ÖY_ªY;ð,ú­zmVkè…1ɳ¬ÓX8À¥½*"lÖ5q¯úâ÷…ExÿÆ.âÎKÏ« VŸœ2…êkuŽT©¡ºöÓsÙ›é,»šo¡uzÔ©l©hàOÎULä1ëšü¸ÊÃÔ7TMÓÌòö´‚ÎëRD hò€3 »"ztÚ�GZŸ´€bx×÷ST^¯IB=¢5@ûbš¦î0˜é¬kBÙûйŒË3AU‚ ·u:g%Ô{V(‹˜Ýõ’P ²7=kC®ðÚ�z$ûãw÷ë/~ø.,xcÊ=îóþ\K!êd½èÌ£t•¦À_%“6ýœŠ=‹^R¤6ÜLo{J‡¢±Œf° &’•V~Ò¢Œvp²ªÄè�ûP)^m(â&ÐèkDTâ슎VÀz-*h�ؾ/ê °›LMÌ«£F0Þ"ª«£/]‰@’gL8¡Ñ"m¯sQ'#õQ¹­£Ò�QÖt{­åãð À&2¸“$Ší Ê�*‚À�CÁý¢Äà®HÑx�Ôœ¦hë RºÜ¾ ü‘[«{0ùJT¤[ÖG5èÀ%ÞºÊýìËÑОFbjtærç‚Ù,‰À©G‡PÑ7ôJë'Wíú߉n¤qU»¢Ã°0ÒÂM_< €G}Ò±ºüÐY\ƒE>Ñf¤—¦>B‚qAJ ë&Tð Ô8)Ê^Ç+Á„UZÞ d²¶-Ö;b~DY€…¤d¥IÁ }p&鬨Տ�ZšDh{�‚ÑQABš”<1 ¸ÓŒ?·|…Ä~ÖI ¡Ðdm‚å‡rÌ:)‹>ËP8°‘¯¤Þ¨f4Óœ$WǽHGA©]¢Ž{묣>–ü-¦=¡èQ¡ùÍ^:ô‡‡kŽ/éý[AH}2§¾�@ÄëtЧèÜ ®–5]ì^Ÿ {bBSÇ£=Dü´×±×¨Q�Ú‹\“ ¨ÅÕª[!i«cá#%߈ ˆ‹ËøËcöÿì£y?]yáõ ´º”ÑÞðÄ£Ù£†¤p }!XŒ =H9 ¸†¿ÿp=÷¿´ ÿƒ é|‹û¬ž•¶H_Ã5„iCCPICC profilexœ}‘=HÃ@Å_Sµ¢-í â�¡:YqÔ*¡B¨Zu0¹ô š4$).Ž‚kÁÁ�Ūƒ‹³®®‚ øâêâ¤è"%þ/)´ˆõà¸ïî=îÞB½Ì4«kÐtÛL%âb&»*^у~„áGHf–1'IIt_÷ðñõ.Ƴ:Ÿûs„ԜşH<Ë Ó&Þ žÞ´ ÎûÄV”Uâsâ1“.HüÈuÅã7Ηž1Ó©yâ±Xhc¥�YÑÔˆ§ˆ£ª¦S¾�ñXå¼ÅY+WYóžü…Áœ¾²ÌušÃH`K� BA%”a#F«NŠ…íÇ;ø‡\¿D.…\%0r,  ²ëÿƒßÝZùÉ /)º_çcì�šã|;Nãð?WzË_©3Ÿ¤×ZZôØ.®[š²\îƒO†lÊ®ä§)äóÀû}Sß}k^oÍ}œ>iê*y£Ê^ïðîÞöÞþ=ÓìïóÍrt¿º­6 iTXtXML:com.adobe.xmp ¿3ßbKGDä¾­êR pHYsÄÄ•+tIMEç 0ñ7y8 IDATxÚì}uœוõ}ÕÃ<£ÁH3ÂшmÙ²#ÇŽcÇŽp`�dC›Ý8àЗl²Ød7ÉnvÃŽí˜c–™d3 335wU½ûýQô F©{¤‘tÏÏ?¹§¹«^�wßy÷žË�piA¢C@ Dî�@ r'‘;�@ ˆÜ �@äN Dî�@ r'‘;�@ ˆÜ �@äN Dî�@ r'‘;�@ ˆÜ �@äN "w�@ r'‘;�@ ˆÜ �@äN "w�@ r'‘;�@ ˆÜ �@äN "w�@ ¹‘;�@ ˆÜ �@äN "w�@ ¹‘;�@ ˆÜ �@äN "w�@ ¹�È�@ ˆÜ �@äN "w�@ ¹�È�@ ˆÜ �@äN "w�@ ¹�È�@ Dî�@äN "w�@ ¹�È�@ Dî�@äN "w�@ ¹�È�@ Dî�@ r'Sc�ȉÚ:q"‰�@˜ P9ï ¾u°ý¹ÃÝŸyÏ<: DîáâF$ª4´ ¾~°ãÅ“ƒ!™ÏÈLZ½d&"w�p±"–÷�è|åp÷¾6¿ª" "âÖOÏÎL¥ƒCäN .2(*ïé÷¿y¤ó‘½]~™#" æ¥ù®X=›1:HDîáâALV«šúß8ÒýJõpPQ‘!"pUEþŒ’l:PDîá""Ž¢ªzvè:ÙVT�Ó‘s”ÂŽõ³}eñ¹„© Uåm=c»OöüåPïPDD@t?稱ü⢴ÊÅtÐˆÜ ÂÔ…¬¨'^9ܵ«y,S™wDÈ´Go»rN’�Âv"w�0õ€ˆƒ#áCu}ííj‹!æÕµ§rŽ\å@À¹y)ë—Q$‘;�@˜bà›»FÞ9Ù·óT_HEDÀÓÌ rθQ(ýê’Üì4:ŒDîaª UN6 î<Ô¹¿3”92‹7­G®r+†ÈI‘¶¬œÅ(’È�@ LôÕ <~¨§~,fæ5ž!ÀGM�Ñãz�ηÎË-›™GÇ“È�@ \HpÄæ®±W�v¿Ñ8ÒRqâ/TT]�aædð¾Ís(l'r' þP¬ªuè±ýÝûÃ\å€0AJFDÎQUTÐóuµ�¬ž‘¾d>e@¹„ �ž¡àžšþN T�ÄL8Zcv0åxÔÿa7m,MM%."r'ç1Emíñ?¤çõ–ѵ—³p޲b1»ù/ÎÎIY³d:g"w�pž0ŠkÚy¼ïÝÞçÈžËûp޲ªè ï(äÒ0€ë–ægÒÑ&r'“޾‘𮓽/Ö ×bœŸ#§ëÌ®ò˜¢Šï Y@šü~õºR:àDî‚#$ä\7žBEUÁ¨™aŒ%ùô±íc¥aL‘˜ÚØ3¶óhϳmA@®pŒ‡Ö@å\VT@ä’ ÑëÁ;ÂŽ…ysK èȹ.;Ä9�„äh0Èa4ŠEF£¡�õÇ¢Q5VdDä£rDÕ<Á“˜/7E¯uÌJNMb¾ÜÔŒt_J^zfvJzfJzVJzfZzFrZfjz’ä£ã<Œjz¹fð�¾HŒs a¼ï©:»>øÀœõÿß´e|"wÂ¥ •s•«¡Xd08Öé Žtø‡ZC±Pˆ+!U p9†\äÈ9"ŽIèÎSŒ ä¡…ð€bÐnö˜Ê¤\)9#É—!%ÏIË+Ï.œ™5mzvAQfî´Ì¼_r’/Iº â}•óžáÈÕýÏ6Œ´†Î11¨“U°—ªêNƇ¬™‘Q9¯ˆ?‘;á’"†b‘‘p Ï?Ú4ÜÓ66X5Ö_[â´Q©Žã\މ30 Ѹ­¿mô“xb5‘Qieú �É ­Ï™¾ »xnÎô9yÅÅY¹éYiÉ—Z×·HL©éô¿V;ðT[ ¬" 2ÄDÍf*ǘ¢jz™'¿k³ðûÖÍÈÌH¡ka’À‘Žá¼!‹´ õ5 vW u·„Fš‚cATDþÕ³ŸpD¹ÂUÍÿÛÈŠ6˜‚9bq`¶)ÁˆåíQ»v¯u¿ (3¦¿‚1ÃH€ÅI©óÒ å”,-,+ÏŸ9+¯(Ù—|QŸXÙS?ðBÝÐÞ¡hÌTÕ5r7oHˆhÜÃPcí€!ÓŽŽæÌŽÀtAd²Êå˜bwšÏ'!â ûZNÇÆ ØÑnøžîc›–Sl"w”"…{ZêŸn©® û¹¨œ �km¡·¶‡‰ˆ€1ÎCª¾¿ÊDgLØÖ7£o1ôç+�3†gzj£ÉÎq3çÊÀ¶ãêÌž·~–~‡dÿÂG3¦»}‰`ð»öýJè�®COö[—=óýs7­)­LO\UTj’´cÑ´¦Qù¥þ°<ÉBL~Šôñ…7¬/Í5Bïæ®Ñ?ìîT]Ÿk¬àÌJ&ý¾ÛW‘äyeËÎLëÝ£C»ški«T­¢H¤1°ÅÛè¾À9ò�*ËÈ�ÌŠ½‘¹ˆÖ _Ô"ràRàA2Uã Œt-gQ¸™K'0>Å6þ%g M0B¶Š'Ô' [‘”>èDoN ¶$Níßeé…·Íݲ®tIAfnÂâwY}­vðg'‡£;’V9dä´Ä•-#\33ã[ç,*µ:�FcÊ¿_{üÅžÖ^9j-¼ø]—$l„áJ”Ëè`VƒÁ~�stjö°:çñ±Å즙 Ó*!5‘A�‰<˜ÝY/fȘî4"¿KÖlà˜˜ã­Œox&~góRro+ß´}þºœ´¬DMÃ5ÝþŸìí>PKîé ¾}Ŭm˦§Ûû%½q¨ýkÏÔ›³¡„ÈPÿXOrß‚œïjCJ Dî„ Îy×èð3ÕGíjâÀÌ\õ3ó;0ÔÒÄ �©ˆÌRZ,¥ÂmòeÒ¨#øg̃÷µ'Û§=G^”G³µþ1ß[²ÍVj<\ ÐFâŒÙç! Çšl¬£�Öa9 ¿K™RÊ—^³µlU¢¢xXùÓþÎûÚœ'€Ü“�Ý:/çãWÌ)ÉÏp|Pï`ð¯w¨#¬€à= ™[(Z“ñYˆècðË�-Û¼’ÜÛ‰Ü ½c#/ÕŸz´­nDU¼ÈvüáJ˜+h«ó´1)¸xÙŠ‘í16sêãæô`%)ŠJŽøZÉËdÆ^ e{C¯$”x]Ê—\N8fþ¥¾‹xæøÝöçÜÔÜOοjsÙÊì´èѲÂwÕ þìÈ@Ÿ¬ÆCî ³’¿¸yæú……îœtEåÿ÷LÕïŽõIh�ˆþrëý5K z8¿$?õÿîÚBy2Dî„ €ÑpèÕúS5×vË·”1!~GP�¸¬ ocô¶�q•û£¶;汕9îà"§ bp}ŠhìüzÖ Ü+éO³•ÚßÓÎï‹ß�‰�U¦Oûø¢í›ÊV¤ÄíM†�½�¼Ýq2 Ÿ¹gIð±Šün,-Èö6Ï9PÕý¥Çk¢ ‚Ù…Ã wDг¤P[F¡„ˆßÙQö¡•t•¹Î+±Øþ¶ÆßVi‰†\Ä;Q~GDÕ�ª…‹ êÑÌNg6£‹vź!c{ÒK½aŽ<f‹¦�‰AÔÊÁœi¼VÈliŽÈlr ëÕÃ!÷t‰}eUÑ{WÍÈJO>Í€yàÕºŸîéR¹–ƒæ�P—×Å9V{§×ÿíí+}“VÆE r'ØÐ76údõÑ;šËÝÏ�ßUÎCJTîx”ƒÓÕW²2ÐÁ ÏÍj °±¹mÓ S—)˜n¼^cÂÏÐL¾Ð©=ÚùÝ�=‰víE˜iP(¦B‡ÑâËQ°cbî¤V/ëÜÊõr `ŽæMÌE÷¶¹ÀLÖg›é&i_3Mï`h�2f/³BWÝ,r€5öãÚv÷TýÕ’÷..™{Î6dŒÁÕ•EÅ9)ÿðf{sHq?a^ºïókŠ·U§$ŸA Gä?¼Þ2¢9 ¸g‘q^µyNæüÒ|ºè(r'LºÓ5:|Ï‘ý/ö*È[š0nœnÓÍÍ·Šr9Âp¥‚�¥ÎA7pˆÝvE^Œ]‘�£³’­¨Ý^ƒêÔß5¦¶RãM__Bu1èÛJÂ3BG¦•ÒÚ‘õ£˜Ûʘ�‹>^õVY,é“å[Þ_±-7=.ͺm ø£7ZŒÊœë‘{¦Ä>X–õ±M³‹s'´8xæÝæÿ÷j+Gÿ&cZ4\…MÁ%„_|xñ¶µeté¹&QYÞÕXûßÕdžl4äæw0·½$ÍÿK–QqÇmLP*4^C§—º#p6ÃkÓ`ÝÃaÐ3À—lé:‚/r+ê >Ú¿¡$üiû &l&>ŒÙR-ÝÒ�ÓAž¡‡>s®ü€ËÒ‹¾¸ìÆ•³Çã$<è�þbWËsÝ!@X›“ü¹õÓ×Ì›æ“&ô†í½þÏÜ{¬3¬h«ÚìÎ%;¹£žÞ®)@8;Ý÷Ø·¶e¤S¯T"w¤¡wlô÷‡÷½8Ы wúL,~·r ‘-‘Ýãi–;s[Y¹3­ð\ó¨aÌsÂp¸ êÊ�»³³L¿¼h×PÿÇ«S^ Éö³Kœ/Ðý)‚cžÓþª“ß3¤¤O—]qsåÕ™©éç< ù7o¶d$ݶvVNÆDs.c²úŸOžüsÍ0GÉàftÖÖ2 �bTã8!|çš9w¼—2 ‰Ü “YU÷µ6ýäø¡!EáÈÑÎDgÅ"¨1DîPNÀµ]‰B“#tXôzdÈX/¶GîŽLàšEìM”˜ÃaÀÊ€DAÏ‘œa²ðL&VÙ2/�2ÌV5åÒg<÷WMv?—øÝ°"³ä®Õ·-(œs>›�¼u¬óËÏ6¨¹ÑyCoÏf†»NôÜúX”"ÝÿwgçÐ5xþA™I—>ÆÂá?Üó½£ÍSŠ¡•gäj 8]²6ÈÈýj̲_t>M 𙫶c'“9+ŠŒ»™�Q™û;ˆJ=³| ôpÖËì?‡é�¶Fþf;süX¦{”1״„9Ð>÷1±@Êz‚½½+ûnk¿Ó^ödËÇtžá¶ p$Øs÷î?¼R·[Våó3„Fü‘¿Ò¬ z¯¿Üú��+ (·�È�0)hèïûþ[¯=ÔÞ¦rMÖ`"åáYñ;BLUJ Çá°Y®3³©‘`ðk±·=ùĽ_ v™„1;¿ÛË\uÒf–|!јϘ½¸JäwÃTÒ´³žá^ò‚gïn‡ã»¹pÉIN~G~Gç=ÖGñ諟ýÅÞ‡c“ÏïªÊz³©=¢ž¾[Ÿ¶snh2€>¶c]©ÏG$sa@©�—²óNSÃON pÕ^Òi¦ze7Z¾[ …ÆFåjXUt¾cÎÔ=“‚ÅÎD`»Í„ÏìÎŽRC3[1o‹â†ªÐÂÉâwq1a$&ZÆ�he.¢MµqK9Úq€Ùo³®]?Ùjkï¶êlá­†Vÿ"£åˆ§=v’æùÒ6Ï\š,Mú%|¢iàO'dCX?=ÄC°aFÆbr÷%r'$¡XìÁc‡mo‹ #ƒ�ú€©ö+íù*žüŽ€U‰A"Gc<æ Ð">ÆìLª=*iùrº^ B;�˜»¢ÖdcïkŠŽMެbv»µ*üT�|%p¸ÕˆJ=sö²ÅÑ¿3&¸^¢óÀZûÁöÛ ­ÿ�wþ»›ßç¦æ}Ý ‹Ê&[v†å_½Ö<¦:¼ìÄ ýt4+¼ecir2uÁ&r'$Ý££ÿy`ïÁ±1W=½Ä¾ÞÇ3ð;bXU¢\q 6{fò0Љ�Ì#.f¶^vÌày1¼¶ççØ[° ê9Ú|ócì,~I41Pg–åîÖd4Ým² î¿®ø]?°B¯AgÒŽEìÖúGœ„<øýª¼¹_]ÿ¡¢¬‚ÉHˆøôž–·"¢f¤‰3&gs/mæf%­«œN#‘;!a8ÕÝýó£‡ëÂ!±É꺳˜n#S/~׈êәݩ-¸ƒrÄz{ï$›8c=„VÏ{‹TûB™@óþÕrï˜+ç’¡áùŽ®¾Ø ”Ë2cÂÆF4ï5ö`Ñ¿;u+~·ä%/~·*mõé‡{è3àjôª¿ãÇf®ûÄÊëÕßãôhêýõÁÏÕŠÈéÜkUó¡u3²3Óèz$r'$*ç»[šrâD@U˜Gn:ša—C<[†Úrƪãª]ü°Ïv~GwJ¢= f®ØNs†Þ lÆhZ r0sDý l<î°ªDûžDnƘĘ�I"Ѩ\ED®p‘c9ˆ…GÂ�áH°'8Òæ® uËawû'aN²}[ÉùsØxñ»Ëí4üŽ�^4uwáÍKS²~°þŽŠâòó6¢úGB?ÚÕvºuŠIñŽÊ4xïÚYäîKäNˆcáÈoz©m1–ójä¢Ñ¶©83ùt½8Ì•¨ªˆ{¡Ì©y˜3„SxÔ[ÀÎüi©ÜÀ$ƒß‹“’*2sçeå/Ê/š™SPœ•W”�›–<)Î$£áàPp´Ç?Ü16Ð0Ú×n ü(ƒ¾÷Éî•Âu~N�ß­™Ã¶¿ Ûóç~eÝ­ÅÙÓÎç z·ª¯OñÏí£ãÇ#ÀÚÂôe ŠéÂ$r'ÄËìÿ±gßîÑ‘¸Ñ¶#"pݱÝI²îø=ÂÕˆÞ=UÌC§0%p±;�¡œØª“L•Æ+Y[�ó“|[óJVÎ\X8£$;//#k’ØÜ�ÜôÌÜô̹…3µ?ÑðH(Ð1:P7Ôyj¸û�ѹµ4q³°—œuNú ¸-‚µ5Ìm%K?·î¦ìÔÌó<®®[Sz°yäÑ–1÷CÜrÚñ®iúøÖÙT¸4@Þ21zÇüÿuààá1¿j¨äz×;³91rD±F’y9y!"ÆP )1aŽ  ËaöL`Æ[Îq%Ù•Úi¾äŠÌ¬mÓË——–O+ÉHIMòM¡œhYUFÂ�æÁÍï´tÇB!®º�_бgìt v”¦ÂÄ-hÒ%ßç_yÓâ+S’’/È ÿàñªç;†½ƒ¾À�©"j&bhú¤á¢ìäßiSAn:]žDî„sgöí=x"0µO‘Ü sDUtõHr‡i …1®Ô˜�ù`2»˜ã‘Sèæ,ϾHX””rE~É–Ys+KJ§çæ'IA‘KDŽuŒôín<<к{¤[ÑËìÏ’ßmåY§±�D(�R¿½âÆÍe+¤ ª\wõ¾ñÈÉCÃQƒÜ¹Q¸¤;¹£ø'|{[é'®¯d”(CäN87ô?Ú{ð¸?`kkoÄßÌÎg¨rUuuFõäwŽ|Lލ`6²ØÜi!É@¬­7VèNóE‡/ãµyE×—U¬š5· 3{JéGTŽõø‡vÔ=Ûq²!2*ÈUÎÀÏ¿»ø]?bå©Yß[s[<­—ˆšÖÁÏ?|ª7ÊõÙÇ$wÃRB+º(H’îûüÚyÔt‰È�pnèõÿèÀ¡ê@ˆѺ° RŒ–+­¢ª âàtO~Q‘ûå(7§ !s�9$#Bg.íE4ÑÕ.w“Öfåì˜5okyŬ¼‚K& S¹ZÛÛþNÛ©]ý�í± Àïèu¨-Ÿ‡E°›ß·äÎúæÆe%’9b{×Hñ´¬ô´sQxÞ=Ñõ�� C2ׂtn�Ù-+Ä�TäýÃ_­—(l'r'œ[Ìþo{� ÁÒÙÁ(NÒƒwÔ¥v.sÙ“ÓüÎJT16 ·^dŽª~!T—œ±¹Ø· àæ’Ù×ϯ¬,)ÍJ»4XD Žíjx¡õøAŸÐ܃âÏÈïÀ‡f®øäªërZ}ª(|÷ÑöŠò‚’ÂsL<ç«ñßîP¹Þz Œ¦Kr¿ÿË×-™A)‘;á¬Ñë÷ÿǾ#'!£ íänèì1ÆeMjg§çw„ 3 ¬' ˆy/6~·u·`6r÷›ž”|ëì¹ï]¸lVÞ´‹T~9[Ĺº·õù¦Co´PœPÇiAåjñ‘Ƥ¿YpÅM•W$vû4Ž=ñZ݆¥ÓÍ�Ë�QQùÏž8þǪa­Õ’zƒ‹Ü7¥ÿï—6§¥RÞT�£Í‰" IDAT‰‹#¡Èÿ:q"Ýz3ƒw[½’ÊUÔk ½|c¬×ášÁ€ÓÂW²gþyùëÁ3ž¹8-ãö²EW/¨,ÎÉ»¬NMJRòÊY VÌœÿá�®—=ß[;¢ÊNË7Í› Š’Rï^vý–¹++h Žÿï/'¶¯™¹°<Þù$Ÿôùëwޱ3Ín'Öˆùð¦YÄì¹ÎáXì—û޾64¬‹žF¹)3‚w4ôŽÈ¹ãŠW7güãj@‰¹»Í�høèJÿpdR2¾¤»¯¾rÞ¢‚¬Ë½è\å¼{tà™Ú=�vU+ žQŸ)LJýц�T”$ؼ·µsø¿=±uIÑwT$ªX´¥{ôÎ?튨Únª¶¿ªåD.ÌJúÝ6dÒ¥JäN8f—åß<ñbß  ÜÔ�zS†vC0TcJLÈ¢Ñϳ›ßÎÇ”¨w{k#ý½¸I|«yÉi›¿èúÅ+ó3è¶¡}¸ï‰šwŸï©¢ì©ÏøÛš;ë®u7OÏIdõ)çüHuÏ:yÍ’‚¿ûÈšÄÖí>Ñõ·OÔTn¶À–À×7NÿÜÍË餹Î.|ðXÕýmÝ DZ:,›Ù2 xT‘µºJ�HÐÍïqL‰ªèÑ)›Yj»=QÏî÷’#±;çÌÿÀ’U3ó è4�wîêúZ­ÙýÚPî˜#?X²ø3«¯ÏÍHäZGVÔ×ö4ÿÏËM+¦g|çÎu9Y 6ÝUUþçWëþõÝN­—3’Ü_üÛõå3óèŒO)�F6¥�ˆ¯Ô7?Ô.zj‹�﬚í†Â¹‚œ=7™½‹CÄ *«ˆÞÝA™Ó�€Ù{Ñ¥0¶#¿ðó«7Í+*!¨ÓÀ'I•Óçþ¿¢Ù×¶VÝ[ûvmx”€T�>?oÓ­Ë\}‰*÷í<ùÄ¡¾™Ù)w}xe™|>é¶móN´�=Óê7ïüÀÜœ²¹tº)r'œ´uýDZZ?W€2{1ª¼k‚;GQd³Õ’‹ñ{DUª,9ÕsÝ ˜‰��ûÍ ´•™_X²jóÜ…©ÉÉt‚&ŽÑpà…º}n9$süþÊë7—/Oì¼Ø?øíS§^«ÉMóýðΕ‹çMÞoéè»ã·‡zcª¹ßÿñ¥ë—̤SLäN˜(Z‡F¾¿ïø`LFÝ×ê>o�»Áõ€<ªÊ ª®‚#'¿+ÀGå¨Yï´çµÌœZMc=gÞGV¬+ÌΡ³sàˆÍƒ�ŠÊ+Jæ$x¨t�üìác'z#©ûîmW®�3Ùõb¯hùÒ3 qKaÚ~CVF*�_’eÂP0ü“CUƒ²Õ¹T+)R�ô3Ôl^ ÕDAT ßG[ŸbQpáˆUÜɺ²_Ðì*¦Í[Ÿ™õÕ5›V•–‘mÈ9Cbl~aiÂ'Œ£Õ=ÿúÈÉá€/¼§ìŠ5³ÏÃ9ºjõì»:Çþ÷`ßmëf³¹&Šˆ¢Þw¼¶%Õci«¹2JÀ¸ÐšÙÌ•‰©Ž6§(0µ†‡¸¬ Ó}×ròef[Ë7%•IS>ÿök¦eRo�©•ó—ßmúõ«Í£În^>íýW-8?^cÉI¾�^½ðx»•¤’,C˜ á±u÷·vq³úmŽ1˜V¢Š€ˆˆ1.Ë\�ñí ™žÕÎGÕ(î{ËSW=*,JMýîê�ëËçÑÆéTC8"?úJíý{ºŽ€pEyÖ·>¹v26QOƒžÁÀôiYt.(r'LG:{hí1v?mý MuEø“qàšys6²Ê#Gô«2XZ�ØIÎíÀÎðŽ’Ÿ[»if™üM9 Ž„~ý䉗kGµ%×Âi©_þÐÊóÌì@Ì>•AáØÔB÷Xà7§š¸a-àÔÌM*F³{†)Ȉ�îœ71ÄeU's›¡/ê²»67X÷½…K¾uåµÄìSíÝ£ÿrïá—kGµ?sS¤o|hYIa¼< Gß~|¯•éSäNHôB[V~´®+&ÛâgAþfšU#깉˜ÂUû&*cÎÆž,†<ÌÅ~ÌÖõZhÀ¦¦~íÆõesiïtªWuÿø‰šž ¢�›Ì$ßwn[\Ÿ/p•¿~ÿÛ5�7"çWÞ¾™N=‘;!‘x¡¶åÀhЊ»½j‰D®°Âvð¶c¨eÈhº��©ñ»­(lÍÊþÞæ+çQƒã)Eå¯ïoù¯çÃBëêÏmŸ½ay¼9æˆxøµã5O4!â‘?Ÿ*]Õ ªüÕ½-ÿð©€�ÙÓ“ØÝX´`N¼6Ë\åo<ônÇî^½c—}´@ 3üîcûUgˆÜ çr�q|¾¶½1ui뎶Gµ°Ý|‚¿#bHU¸ ½€�ß°\É÷£µë·/ª êÓsFT‰…cÑ„¿m$ª<ðbõ�ŸoÈÎ¥Û®)Û¼²4ÎÉ9xùhÍSÍ� Õ ;[ë7ÒY&r'œ5jû‡ŸìW&Œ+Z·ÅT2WTtT“:ù]EŒr£Ç›“ ù|?]»îÊ… )f?Gþ•cG;j{ÛS“l}<8úåcGÿ°»KqÍ·¯*ºiÛIŠ÷”ÕjØsÏQn4ÀµÆ‰}k†#¾sÏ~ÿH�N7‘;álØAQ®íhš1]:9]l®¬“xÄp@Ïp €„ôž×&áÛè Ïçû÷5k¯\¸�ι&œŸìnùÙîg“$ßò™ókÔÕÙ7ö/÷}¾zÄýÐåÙuceümózZû^ûÕ%¤žŸÎ\,‘ßÇšƒ‡^<Šœ¨.>Іê…"¾ÙÔsÊÙií¢ºÃÙMVUU°ö}}�ÝRŒ©\á*3âx½ôÔ¸h³û÷U«®Z´ˆÎÂÙBV•Ú¾Žªö„UåÛoœ‘[�Ø!q´¶÷ÇOÔô÷£‹ Rïº}yüî1#£ÏüÇk‘�¨Èà Ķ\Ìè Ã9}¨jÁÚ¹¥ ©Eî„  /~ªµŸ z sÜFf&ˆ®/U¶+ò¦ã—~›#¹ŠoãQÀ?.[zME�‚³G¬îiýåžç¾ºç™üäôØzKb™]Uù«ûZ¾ÿHUOPqÉ©¾»o_Z·KW8yù­áfîæ0†ãÄïj”¿yÿUQiPäN8sŒölmgL1bsKbÑþ»£‚`Ю —í9Ä^»^£\UÁ4‰DíBÕ»§~oÑ‚—.¥Ô³aÚ†ûž­9´³¯™#~ª|Ň–oIMNIàG„#ò_^¯»wo·â•™’žÄ¾uKEEy¼î1ªÊßxhOûî[g\-D2tÅï=ûªöÕ.ߺ„Æ‘;áth{¹wÄ)Áx™Ãèͪ�Ž#I†�Ãï€Rµ‹¡`2€ŒàJg}dõêdŸ�NÁçàŽ‘�§ký¥«NÈ÷%}ué–«¬HìÔ8<þõS'_¬Ï}Ò¿½vî†å³â]yp~ð•cÕÏ6#Ú�è^¢ÈŒ>êBüŽû>:wYYVn& "w‚7bªúT}'Úö@m[§z9’7Æ�ˆQ[»%~�pÎ…NLÚ»hºÌ¦|~Ãú”$:ãBŸäéêƒ;»Õ&¥üë†ë—L/“š\ÔÑ;öóÇOì7åöU…7l�zLýÑæÝ÷Cä Fí†Ë(Ø 4–“b?Rï?ùvõÆ×Rz‘;Á'º‡�†ñ¹ñ?puÛ°¸;ªÊB§%³6ÕzG«*ÚãzmªX—žñÍ­›sÒÓéøŸ1Zïó�¼Üpü�–ª0r9Û”;ík믛•W˜Ø:V×ûÏ�Õ E”ñžsͼÜÏÜ´4))Þ…BgSÏ ?}[ ©¶1¦ó¸ÀïB‹÷+"îÿó±Š ò‹óhœ¹œÇ”§{ÄôGÔuóª3Cv­Kµö/"†U=Ú-Y7¢\U-/_0�Ý‹|I¿i}INÿÓc08öfcÕC-'ºå(0DpSqÙçÖmÏÏH¤Ÿšªò7¶þ×KÍî%©_¼eIfz¼âþÈÀØó¿zKªîhÂÎïâ0Ô$x{üQ¾t|Ç'·ÑP!r'8q¨s°&¨u15­`˜Kût(ï eή÷ɶzf ñ;"F5n=óAË�LöÏ«V,™9�þi0¾ÕTu_ã±n9jÿTÉ÷©ò¥·/ßœ–ÐíÓHLyä•ÚôFTOàÈOõ}ëCËJâO� D^øýÛ£ÍA1»Ñ“ßŦ0§Ùb­ÞÙ¸âêÊ’ÙE4fˆÜ B1åÙÖ~SC.0Q^[š‚Ú›…K Ó¶ÕnI»6£œ+è1+üMùìí‹�N:ü‘Ð;Í56oŠ…„V�ɤï,ߺmþRŸ”Èýç¡Ñð=Ï×ì¬Rǯ ÊH’¾sKÜcT…¿úÐîö}½Úo²§´�äVÛõÐ6‚l[¬±ÑØ‘WN^wçU’�®ˆÜ Žv µ‡cŒ1ÐSDBw@˜€qÀ˜î%`]Ÿ6~GŒ¨ŠµA«w`ÅMY™w®[�Dס¢ŠüNSõ�'OGMd6ŽàŒäÔï­¹få¬7ììûùÕû»ÎPÍÿ…í³×/K@s¥ý¯¯y±ÍºG“_¬Ò7Ûhs³½í½¬ VûBÓšë–—Ò"r'¢òs-ýB±(¢·{ªÊ\uÈôzþ;Óù=ƹ£ô…ÌNNþ§-²ÒȢݽ„Šíh¾§ú`]8ÀuY€!à ÙÓ¾¹aÇ̼i üDD<ÙÐÿƒ¿T÷…ÏP ô‘5‰q�©:P¿û¾£ŽòfÌþÅv»gð0†«öZ9 xîØ�_¸–‘;àX÷PS8¦]WšJ.pm³Ô%‚23U�€åÜ눴ÀÈjˆpnJö €&ܽ¤b~…W6ÄåxWË#µG÷Œ8¬ðµãcáì/®Û^�™ÈíSŽøú�¶ÿyµe8rf¿znö'®_?³w6õ¼òëýjÌCôC{�F:¤}l�Œ¨Þœªw6n¼iUáÌi4¢ˆÜ/wÈ*ÿKc¿#4g $îÊQÐj‘¬ôvt§· ‘€ŠãÜ‘7ù‘’•äø(ž¥ª»ýÏÕ‡û‡£Èµ˜~OøÌÜe·¯Ø˜žØêÓ¨ü䮆?ŒS}*¢¢ õK·.‹¿¹ÒÈÀØÎÿy+6*;W Ú[ @àf•›ø Õý­°Áˆß8üÊÉëÆ‘;…íÃý²jÛ¥Òâ Æ´|;»Üiû#bÙ²£+0Ì�¹íóR’¿¸~U*Õ+´^Û×ýdÍÑW{¸¼2ù=Û—ôÕÊõ×.JxõiäÏÕ<[3tÆg§'}ûCK‹ â­ÿ Â/üá�‘¶ ½[#³éìÚ€c–:£×3‹ \Z€ÁA=ÓõĺW[Ö¾wÅ´éÔ§‰Èý²&uWû7 - @ÿ[T…H‰�PŸ 14ô*OG„¨Ê…G~cYÅŒ¼\:òPß×ýtíñú:¢¨zÌ�ŒBaRÊ?­Û¾|Vyb«O»úýÿùxÕ�î3›¡§'±»o^8vÜÍ•8íáýmú´Í›só».¦›ô�Ž^�æóA=c€ˆVï«ßzózZ¹_¾h‹¸jŽüܹ­Å�£–'cµTuT¥F¸j*õÚ›~rzÑÕ‹æ_æÇ\å¼mh౪#;û:ŒhÝ.j§bmvÁ77\SšŸàêÓãõýÿöTmOPžó}eGù¦¸Ýc ä�4îî4xœYÕq);xõ"9›s�}e8.¿{ªfõöe™9t�OMP’Üä‚s¾§kذiÊö–§L7öÕ¯D#-�Éœs›g»ÕÊCÛ9b3È–¤O­^–š|YÏÙmCý¿?ðÖ—Þ~þé¾vÕFTN«ä›ŠJÿáŠËìªÊwnÿÞcÕ=!e"ÏÿØÚâç&䣳r3¶Ý¹Ê úC&übÆ´7ý?óNÓh™­õ‹¹Iï8xŒ{"õG›é§Èý2Å@0º«Ïï´Ž±2ÐônLï–„ª×kE§Îµ´Y˜Êä ŠÜϾ±°|naÁåy¨±Ï?º³æÄ�M#ªbÆ¢ö ý&ÜYVyǪÍiɉl’‰©�¿Q゙èZI×ÌËùø{Çïcb鯵ûZÛô™ñ»-­�y¬a,ÑFL¡qGëbPo�þ‘窖mªHJ!!r¿ü°¿sXÁÓ» ˆ0Ÿ®¿ëD¹bOF¶.8DŒr.�oÉJ¿yÙeÚ…£Ï?úzCÍŸZjüª‡¶îà÷lŸïî%ë¶/\–ØíÓäwÏU﬙àó—¦~é–¥Y‰LÎIMKÙrËÊ®“¯Éanöêv™}_ÔV-.1YÒÎïî¼ÉÁº±öÆî¹•³éJ'r¿¼Ž)o÷ŽŽ×BÏñ§IÀ8 2¦r-ÇQ4 ãwS“a�Ìà³Kæe\v¾�cáðKµ'þÒÚÐ.G™—-�ƒß§%%ýóº«VÎ*OìN`÷@àçOUïíœh/é¼éî.-ÌO¼`=gÁŒEWÍ9õb‹•h>.ÝÜNæLoˈëŸV‚ç1~ê�º²ŠYµ!r¿¬P7àï‰pkÙ+·RQì¾dîš23Á ÑF4œ‰¡•ÿ!¼/?wëü²ËêðŽ„‚o7×ÿªöD€slNjÞü¾!'ïë믞�èíÓêæÁï=R=S'8]d'³¼mñüÙ“’GÈ$¶õ¦U {:£c²i$'n±ºù]<`Ȭ*VÏh�:;íΆ7ÛÇn ä’ç(‘ûe•ãÞîQѫŒǿŒ™Ž $À¨nƒ"¿›úLT/\ÒïøÌŠŠ”¤Ë¥Å’?ÞÓÜøXcÍ©pÀÆMÂìèæ÷ë¦Mÿò†«[}ªrþöÑΟ¿Ô2;‹£_Ú^¶jqÉäŸü¢œÕï_¸÷Á*Kk1%x1~á€Nab›1á]m!:,7oY{Í ºä‰Ü/ £‡Âù‹ºvîØœ…ýr”UաØú êU©ZTŸ�Q¸tfÉåpTñØÞ–Æ뫪C!-Z·Ž¡Õ@ÎÉïI }º|áGVlHOI¤ÓN4¦>þfÃ=ûº£&vð‘UEïÝy4ä7ǹáÅï’t÷âµ;'~ûô�/Ö>]3Œx¯ºv~Î_ÝPá›ü“•[�½ú†EoÿéºæÙ;ª{„ lù3¶V/çÈ¡š±îÖ¾™å%tÕ¹_ú@€]]£®+ÇQ|êõB£}¥l™ xð»™ÞÎn-É_8ýR6S9?ÔÖòx}õî‘aÅÕüôü^œ”üýµW¬.Mpõiï`ðÇ�Ÿ:Ð:«7]�—òÅ›Ð\i‚XuÅâÝ�RDJmࡰɌޣ״¯sô’A7¿3„ºƒÍDîDî—:GCÍ!Do=+ZB°5 6÷T��Š1†`¸»ó §0�ÄîX¶(éÍUˆ)JMoϽ'�îQÁÖ.|"ü¾23ç»›¶ÏÎO´yoãÀŸ®ë +gõÂéIßÿȲ¢üóWÏ™™�¾õcËÞüÃ1·jcR¼ÕƒÉÞª ÅHÿtü®¿¾~Oë¦÷­NË i"÷KU}~AlA{º™{]ëØ_Ý1Æ õE~W´&öÀðŽ¢ü…%— óªÊymoÏ5'_P�‹G&Æï7Mÿº­…Y‰Ìâàœ¿y¤ó¿_kŒªg#Æ@V²ô�÷/,›y¾ –n˜pgm°7â¦uWã=áQ›=�Èïú±}áµè¸Ñß×90gá,ºö‰Ü/eÄTõ`ÀÅÝžZm;@a8¢‚h-�íüãz[2c]2ÿÛÈR9oè´êäëƒý!®‚]Æ ð{cŸ*[øÑ•ë2º}‰)O¾ÕtÏĪOS÷ßmŸ³nÉôó¦rò³–_;oïCU戳·`gÎø¼Æ©Óœ‰¦\�Æ£mDîDî—8zýѦ�"f[ZŒ¸›BŒ7Á!ªö�/�ßµ›y27æg/žqé¨í±¹¿ÿù†ÚG:;Tq›¥–zœ(ô·f@�ßs|¾¯T®¸®"ÁÛ§cÁèož«y¶väèùãkНÛ<÷‚ÌÁŒ±e›æÚYóËà2‰D�ßõxÑ=ˆ-×Á2ÀGÑ¿T{NíÛ­[oZ›’–B @ä~É¢n  wh�Ù½mÜ•MæóeäâÝ(<ʹ¥Þ<¿4±Ö(�#ÃÏÕV?ÕÙ1¬ª§-赎ض"æø|?\ÅÊÒ²D›÷~ùlÍžîà9¼öš¹ÙÛ±È']°ÕUáôü¹ë¦×îê°efyò»‘)Š6èZgºú†éÿŽ4º‡gÎ¥mU"÷K ÇÃýA“•˜£³†—ÉŒÄk }Ì–ánó‰q®Ý»2=e}ÙÌ‹ýp!bߨØÓ5Õ÷·µpË÷ØIè¢ÝáºÈï²ó¾¾akYA‚«OO5 þÛ3µ�Aå^¾¢(ýË\–·{ŒªòsΞdŒ­{Oeí®‡{»“ßÁÕÖ×-ÊÛ‚s jÅïõG[‰Ü‰Ü/YŒE䪀EvüZWY¯‹Ïmú \_Xò¥u[в\}ºûD÷Ï^nŠªçðò’4ß×o­,ȉ×í'è‡á¢çnö9³¬pú’üžªa·znò»í¶g ˜ý=À#…´_ù�uä3Cä~i¢q(¤ ›ÓÍmSg5ÚR ²«'ªö\ލr`É ®Y0çâ=Jƒ�àë õ�¶´tÄbhÆå.yݦfÙï5õ™d€OÌ™û‰ÕëÓS©öÊŠúø®¦{ö„ÏØüÔ ÙÉìÛ7/œ7+/Þ FáGÞ­ÛxÍÒxÞ$9%yÅÕó{ªjÇ~×oIiFÁ‰àPÔbp¯œÜqùÝ`Ÿ¦�´Æv̯t5÷¹¹_‚ˆ*¼Æ³388xJPØÅ]A몒‘[éîv~WŒ›×•ϸèü±ػÍ-÷×ÕÕ†Ã`gð ó;ˆ;ÌÅIÉß]½~}Y‚Qz‡‚?¦fwgðœßáŽUE;6$`S÷ÔÁ¦î¦ámï[ÿ�Ê/Ìž½¢¨fWǸϰmï;­’ñt5Õ¶2×–ª®e›‘Ï ‘û¥†nt0&ÈåbZö8Yî¦8 GÓE› üŽˆ rV‘’´bVñEtXB±Øžæ–?ÖÖ6GbÜÆ§çwp.t„Û«³r¾±~óÜ¢~OD¬nú×§ë:ƒò9¿Éõ óî¼~qüî1-õÝ/Ý{äC_»’%"Ó†1¶|뼚·:‘ îvEÝ”è\YÚBÂ8!?tžè‹„¢é™iÄDî—ÚGÃ2:»`3ÁgÜ壊vÀ²Õ‚ÃÈm0ø]«lºbZnaÖÅÑ”#*ËÚÚ¯oÜ7æçf®�—Ï¥¿‹ú»�߯/,úÛõ› ³¹}ŠˆoéüùmCåœÙtYaúçn¬HO‹÷²ì}þž ÖN/-OØ,>gÁ _ФDT<¦EúF&0·}�j>3Ìkª5pë¯iŒ ˆÜ‰Ü/)p„ºá8 ”\•À„ È™?ÃD¯¼†2ØVV2õ¢Šr²«ûÁªÚ=ccª•OÁÎ’ß�úŒàSeå[µ&#Ñæ½Ïîiùß=ÝÊ9«ì%iÒ7n©(Ì‹×=&è?wß¾ÀPxý5›|‰k¯š–‘ºx[éÉWZöfÌaýnEÞJ}G7¿Ûëô´9²«¹¯dv!‘û¥ƒ°¬4ùeÛŽÕ¬)ÆXq:¸¼Ý.²è‡:é§[>³h*‡˜¢ÖõõýéDÕÛ£c‚tk5ôtèTŽöÓð{ŽÏ÷wÄ^� IDAT•ï«\šàêÓ@ôžWꯆs'vÈM‘¾só¢¹q§Ç(ŠúâÃû;ª†–^U:³,Á'ºr}ÙÉWZ]þàYß.w0ÝþÁ¾…d•añ{Ë©îÕÛ–!¹_:‹¨=1ÅNè8Î ðxšáN #Šôon!jM�>Xœ›—9E5D¬éí{¬ªöõÁá0òñ²×òþLñ{QRÒ÷׬[;{NbW-=ƒÁŸ?[³»;çû|éªÙ«ãn®„w¿z²n_�”Ì6ïX’ðmÉ™eÅ™…iÁ�ˆMóWg/~7ûc#³ÜœíúBëÁnD¤=U"÷Kcn\8.‘iW„£Ä Þê®2àæw…# \3g*Vªœ7ôþ¥ªö¹þ>ƒÛ#t}æ4ñûꬬomØT>-Á‹ýSMÿ¾³®#¤Æù>ŸZW|ýæ¹q²"ÛßðîSµqÍö¹…Óó~š2³Óæ,/®z£ÝÔ …Ìugý*zÅïznŒYÚ ®v} BÑá�±‚¢\â"÷K-£QmŒK`õc ¸Q­äåOkí¦jw*ˆ–c¶Èï2B¶Ä—L©_�ˆ-ƒCÏ×5=ÔÑ-[Ûpãö´ë38‘ø}Ç´Â/oØXœàêSÜs²ç‡/7ûåx™ýú9½vaüqj[Sï«ç ¦e'¯»jÑdl«H’4ùŒª7Úm;ú¦Lf¯o²‰6â6lð@Ør´ëëë$r'r¿tP31´×r s¦<:HÍö/G=WÆ‘Fˆ*âU¹™…ÙSä÷rÄžQÿUµOw÷ŽªÜXa€é 0>¿G¹rÄïÉÀ>:kÖgÖ'¸ú4&«Ïìiùý¾žÐ9UŸŠX]œþÅ÷Wf¤Åkß6Ø7úì÷Gƒ ,ßV6a»®Ì”¥d$ÅBŠžÛÜ5½ë›lw곎Ëmƒ‹WÏ#N r¿–Õæ�*j�€:NV0£~ÛÁò(Œˆñ»æ”¸¦8'-yJœ²žQÿΚúG:ºGUn§l3‹ÑìqêQ¦{šýUóÑ IúÚâŠ÷VV&ûY}:ˆÞÿzã£UCñ¿UiVò×n®ˆß=&0zú¾½£}aHN÷­¿ªbòë‚¢ÜìâÔÁܳ®¥ÏÀ™·X™±E!_Æþ]õ$»¹_" 9Ê^JF4änÇáyeiW�»O“¹›º| h2ƒ�à‹µMO´wµÇdÏÂQ¿�»ÒmG#ßçû§µkÖÍIðöiïPèWÏ×¾Gõ©‰Ì$éî”ÏŒÛ=Få/>z¨»nTûùë®›—?-{/ødßÜ•Ó[­PC< hù ˆÒ›¥ÝØO[HŽÌš±Þ`4£®{Dî—º ×GW={;Jë"1CZ‡ç»•e‚f¡"–'ûʦ]Hs |»©í· mŠbT­° ó»Ç”&ð»MŸY•™ù­ ëç%¶úê;†ÿþÉšž�š�xòî÷”­«Œws[UùÏ©;ЭýôÌü´5[Möy,_<ãà3�¶ì`ãpæ:ÜA>0[¯máîÑî``,DäNä~I�{@v6Þ@ÑUg|̰ÁÒâÍÕ-3þ³Õß#0anjò…*L GßinûS}KsT*«ÎŠßÙvãòû5ùù_ß´©0;+�ߟ#î>Ñ󟯵 ÄÔ„¼á�kŠ·¯�÷|ƒ'6z¥…Ggýµóró3'ûlÏ*ªžÝm7Œê &”ÛY�ùì!¼)¼ mÄÊul(PHbDî—Ú1»˜i¤Ç˜&LdFAu±‚V±´xµ¨ˆKò|ç½05“ßjh½¿¾µ^³…1L`ωßÏ¿'1é“¥³>±fUfj"#¾˜¬>»§í×ûº¢qTŸŠQì r?zí‚ø›+µ4ô¼üÐ 9Ƶƒ�S˜¶ró‚ó SgçfäÍÎi‚é_êj«dµˆq¤B µí 8ø�ÁPßè¼%³‰ˆÜ/nD>deÔÙòÓÑÚ_eh$¾ˆ×�caŒÖf#X öU€ÅÓΫÇo0Û×ÒùPmÛ‘Pȶbg¢h”°ø=Sò}mñ–T&%t FÿüzÓ£ÕC§ñ5<+¬,LÿÜ ñ§Çô÷Œ<󧱈jËvÌÏÊ>+³¤d߬…#Aa?[XIZçÚp¯³–�BÉ´'¿ éƒÝcÄ Dî=²:“ê܉�Zm8¼ÃÐ*1ÓÛÝá= ý7;?ûüüYU¶u?RÓ²{,ÈÝž¨'¼¹~,;çýÕi>éÖ¬ÚP–àíÓ�‘ð<]³»'”¨`xZšïk7/*È�»¹R òìƒüƒQóä¥-_?ÿüœ_I’f”O;íàŽÄÑ)Ñ8’…“+¾Jl˜�Ã=cñt$¹O „b|T±Y€�ðL‡0Sèj¿Ñ,YEpÜk]HÙŒMÏ™ô ÷¨¬œêîûõ‰Æ#�°fâ蕦ÅâÙ_]š‘ñ›7”OKd""Ö¶�üð¹úÖ8Ì{ÈMaÿø�Eñ§Ç(²úìƒûºFÅéqë ™YçÏI±¸4ßrCq ^<še bU¯-Vƒß‡Úý\U‰Ü‰Ü/nŒF�Ýà@¼Pg%fÉ/b Ï 0&ú›WÛ•9é©“™á®r~²«ÿ‘ê–7†Çb(îh“Ž¿{ž£>³£ ïËÖ•ä$rQÂ9î©êùék­CQ÷¶w]]¶ra¼ <\åï¼z²ñh? Õ´Ò¬Å+ÎkÓļ‚ì¤tŸV­ˆ®¥˜×«}0QP´�{ýl·cQ%9%™ø�Èý"ÆHDuº@}SÍ…,êq°nš->¶â?gÔÏ€!be^Ö$µ^R9¯í|´ºùµ�Ñ0zd�‹ì|ÎünãùÉŒÝ1kæ�kW&|ûtçÞÖßìï sL”Ã|zMɵëfǹۉˆÇ6í~±‘[ó[®?¯a;dd¥æ¦ ¶ÙÌì¼ÚÌ0½¹C6~ÍpƒcáÌìtâ"÷‹CáñÖþã^9Lì:ïñd}Á¬ÝÅfç¤K‰Î£P9oì~º¶õÑî!.Ô®ŽÈ‰ßá´û«¶ �eJ쮊ï«\”’”ÈË¿¹þ‰º‘Ĩ÷/ÌûÈöùñï´4ô¼øðIEæVÌ ¿$£reÙy±ié)YÓÒÛƒÖYw®:™mÙi…%èÌàÚ‰ÕÿúCÄDî+q8¦NÄÛ–ÙbA]}±µIÐZr¡²I‡`F¢÷Žá±ÇO5?Ý=4ÆU‡ŽÄœ�v,—Êñùݲ‹ñâwWiŒýpíŠue³›ÙÙ?úŸvu{ V¦ýõõ‹ÒãN�è}æÏ‡å˜êؘÙþ�%Éɾó{qþ‚ÊYdÜæg TîÁïž«P³Y=‡ˆ€±á ñ‘ûEMî8ªo§:ä ³A6zŒ|ËõQK•ýg g£»Þ Ÿ”�–[ÄžÑÀ‹µí�wôõÈ*ˆýuGFÑØËÞ?Ù¡Ï8ìÀôIv~ßQ�w×úU%¹ Þ>Ý_ÝûÓ7Úz#jbÏln²ôí”–ÄûmeYyñ‰#=-~;W2ÉÇ6^½0%õÂl9æd¹k”˜“ß­Œó)hEâ@ð˜ü#¹¹_Ôä0U…ÐFlN#º\[¬gð»N¬Œ1nP»Ä˜!Œ˜Ý*`zrRzʹŸ)D F^®k¨¥§W6\Á¡�‹ß�Ù qû«ÞqÝxüžÂسJî\³"+-‘Û§²¢>³§í7{Ã*Oìie îÚ>'þôUåo¾t²æP¯ÛMwö¢üEKJ/Ô¸ÍÉË�ãÎvKq»{ì!ع0|Ø8=Ç‚$˹_ÔP9Ž(èìV �„^•mEñ1&pCÛpð{Aª/í\7‡‚á7º~_ßÕ§ª¥U‚¡·WüîÉïžñûxü 0Ø·+¾wñ‚”¤DŠËþPì�]ÍU©ˆ ¯ÙÿÌÚ’k�G÷7î}µÙ2�3V9°uÇâö¿>[df§s‚°$Æ6� Œí!¡<Ù–&ϬR«„#0DäNä~1#"s;c‚Cvg&¿;[s؃"Æ$ɾ�©ñ{¶Ï—rö,ŒÊoÔw<ÔÐ]‰�Ø*ÓÉÔVÆò„ù]Ì€tÅïv;ß|_Ò÷WUn™7'±Ù>ý#á_<_ÿfW'áœÞ0?çö«æÇÿ…[{^y¢šsç|€ V•Í/¾€ã6-#u<Çe4 ‘otj²½À®Å‹£×ßOäNä~ñ“»k`»ÝóìüèÁøº,£ué3W· XIzêY…�þptOKïoª;Úc Ú€0<#¿Ÿ•>ãΟ@ ØÊŒôïlX± xZ8"ÔwŽüËÎú– 2'tMqúo\œ‘ï¥ÑÛ=üø=cQ��€¤iëµII¾ 8n32�ú˜à‰a7sµ>°•ªºöZõ ^–EV’’‰dˆÜ/NÈÜüX�‡œ©d®J'gÌÄÀ'�ObœÛB¦‚ MDVöµô>XÛy «ÝL˜ßÏJŸùÜû«×æguÓªé ­>EÄwOõüì�Žþ˜2ö‰33’¾~SE^v¼¹Iþ±ÐÎG�„ü²Å‰Â\¿pEqiYÑ…·Œ±Ì‚Ôà`O;�2wB€³nÁmÐRž¢ ŠÂ“¨F•Èý"EXæ\í\Àº×¾Ž;tꔀIB‹mí™ȃŽÊêáö¾{«Ú¢ÜšIl•¿›tcçwÛåâw‡ßÁÕ»GöW¥Åw®]–�ÐíÓ˜¢> ý—{»c|RNen2ûÎ� æL�×}S–Õ��iocV‡R+•$vÅ{*§‚éJfnj`0ê±$„%Â0vt•±/MÁ–¯Iðª rLNKO!– r¿(¡8™ÍÖ Tcœ‰^× “˜L¦JÜxyþió £Šz¼càÁêÎ7Fƒ`oña³­ùÝùÜí�<âwsõẟ N‘˜Îà®Ee·,¯HlïS(vïMÕÃ8³füøúµå+$ =f×Ë'kOôƒ±9iM¨ÀpñÚ’¥S¢n3·(£·yÌìjmŸØ­;�ñøé–æ² Α«œ(‚Èýƒ£Ýz6"¶÷f¨iîÚË%=GpW9Vw=TÕñúP0ŒÜ«…“͆u"úÌéyÜÜ)eÞü9Ì÷ƒµ‹7Ï-MlõéÀhø/Ö¿Þ9‰E1Ÿ][¼mÕ¬ø7}�jÞ»«UˆdŃ)©I[¯] „å?¿Õ|_ÕФž¹üé»7-(-Žß=FÝùøá®V¿­u®=25MZ¿eþT»Öv Tq80ÏÞ¥äŒÐˆÜ/ZeÆq[Ü¡bã”þ F†j’,ùlÒ<ƒÕÝ5Áh�¬¥¿[Œ<¿»£ï3ó»‡e ;#¿gKÒV/Ü2/ÁÛ§ý£á_½Òøjç¤{ ~e{ÙÒyñî ⛯VÕžôòÛ²Tº W—çågNÍÑë˜ÒOÓÀ]<À8-;Fº ‘ûENëv2uÔå»bykÛÓ›ñS$Iˆ v�D4.—P[JŸ�ßÁÒLÎ’ßÏFŸY•™öíõ•‹J¦%öx6v�ýãκ¦�:¹g�Ág×o_]'ÿ âÁ½�ï¾ÞŠ^ƒÁ¼‘S�ºnó|65ÉN·jFçüμ:sØ;ƒÉ+Ó†@ä~)î  ¾2vWËsFèQÄ ,I’$`ÜfìeéïF ì™ã÷sÔgБ?ã­Ï\•—ùÍM˧çf%2~DÜ[Ó÷Ó7Ûº"|²Y𦹷]9/~²m¨ëyéÙZÎÑìœh¶³ã÷5›çäæeNí!Ìlünˆ3xFS6&üÏ©äˆÜ/fè¹VÖ:s(2žW‘M½¡Ï( ¤ø|ÝÄÑÅï¶öV{Òqø}¼ýU¿ƒÕà@RÇ�ß%`wÌ*üôÚÅ9鉬>UTþÜÁŽ_îï ©“õ­)Jÿì{¥§Æ;ø{ºGž|ä˜ãbª”½~€`Fvò†- þ?{×E™¾¿oÚ–”Mï !…Þ{ï`öîÉéaÁz ÜÙî¬w§"ÖÓSφè‰AEQ@"%@BI •ôí;3ßï�Ý�ù¦lHv7É.|ÏÝq);›™Ùožyçyß÷y#péò¼ Ë慎I¤½¤´ÕÐ<²`ÃgÅr�jÄr´6†×Pc{•3Ú!MM;ª�yuãw (ÎPŽpêHü€dÿ‡‰ìŠTÞˆ…ðÞ>Ùs…ݼ×óáÏÇ>(m»¾Ÿ±W,óç‹úXbC½3µ4ÛV®Ømmõà‘«Ôà ±Ofòì"­KW$ÀÖêÆ‘U‘¿ËA½¦`Ïžjr1ÐF“�P!÷(ê€A˜Ê|@ù2üê0Rt‹¢a¤�ø]bjl„“7þÆ.ºvâw Q…5‘¦Z8©0;¼éÓÆVçÒoË×UY»áS²°ð�s B/�áyaõÊ’ªJ+€@c"¤8ω©ÆÁÃò"sÍŠ¢¨uÆÊÎi¼UU)Ú š(éõñÇ~BA¢Ïr�fxwrR g~ƒ¿m +'׋ߑBŸ�ª÷‚²«Wûñ;žÝUTDbüÞÏÈ=<¶_ߌ0§O�lyêÛ#e6Ow¬uHÝ?=ohq¨.ê‚ ®[»ïàþF\˜VP!¦ÏLžUgŒÌ¥ÛXg×�BT)VŒÑ5ý«ŠU�¼®þÃÀÀHðG#äN,¹3”WÑ-_Çw@y¶:f—:þ| GѤD$9ÿæw “_ÅâwœßTV7jù]OŸÂ‰±w�é›�ÞS÷ëÁúg6TÔºuG„w˨ԩC³B~BC;·ݶå„BoÃ[YŸIiƃr"véÚ[]íE#øAéV¯kù]*~‡€€fi–˜¹r�^hˆ€Ò…Å·âÒ�,©7’Is3²ºõõø¿/(ò«�â÷Óó;PZÀS\�•|Ëè¾a™Ð-ÁËßî:ùâ¯5V¡;²n‚KŠ/�T@…,(•®]ûÕ!Åp¥ÀÂÅ”YEkx+¢­ÙÓÎŒéçH�Mõÿ éë�Þ|«™¹1åFìºuÚ]¸ç�ÆFÉó²1=ÐöU¤M†£i†�;!÷¨…‰¡4#—”WVº¢ö�ÁE (b4Ñt«Ç£ÿ†2ƒcüDòˆTw—NÇïfž^0±0+¼éÓ†Vçkë�®=ií¶(ÇÌÜ{~KÈõ*mmÎ/>ÛÓÖê@1jKæ9?å{?Ò Ó 9Cä^_‡“[0j–gæŸE¢!€Ʀ ?r�bÐLa©z�} ªœ¨P–Ñ}¤•#Íh (ñû€–ß½-¬âéò«Ò=öƃ6Ð`“añ˜â~™áî>­n}|í‘Ãv�Ø]Œ©æ‘ ‹²SCm¶òx„ÏVìª:aÃ?/¤Ëïò‹,ýdGòºmk±kÓ?ø2Ôò;6‰ª¬NU6§ CbL„¹G1 @¹C hOROŸÄ¬}¡n¿ö*h i BéØuáúŒ’ß�ß^Ñß”ùUe㾃>LO0ÿy\ÿ¬°vTŠí,kxfcåI'ß�ÕqwOÍéŸêØ#Aøþ@ùá&íý8¿ƒ “ X.¢/®Ö‡ZQ ¿Eë)òó;R¾X:34½/ˆ%äNÈ=ªAA*‘£€Ýï²áS]1G0¬6N áŒ�ßh å�ÞX €ôãw€�øÐ/XüŽ×7@l€*©+2âç�éÞîSAD_ï8ùâÎÚ6^„Ý÷¹€[G¦Oš÷˜íG·ü|BÁãíñ;ÈÍ�/î›á붹ц4bŸ~ü”%íP/•Š�–öÍ‹µ˜ ?r�fr§@*#;')*Vl}u FèØZÄU&èÞâU^´1¾rI² å­�ôÖù&fÄ×0BîQKY}rÊ9@ɘüt¯¸pÅÑ”S�? ÃÁï±|rXL&¬—_S›ë• GWUÚzäS¸´Øò{‡>ÊîðáÚo¾+DßמŊZ‚‡°=fl~T„í¢(ž8Þ¤ŽÛõž(ñ¦ ¨œ¯§âw i)yù=1-Ž"äNÈ=ÚÁÑ0ÍÀ”Ûexƒ=ÃC%ÁþkEm´çû¹Ô?˰NÁ¥Ú ýK³#ü>ÀÈ=6¶÷€¬0ǘå5­O­;ºÏÊ÷ÈG0)Ãtëœ>¡»ÇTU5¯ølŸÇ#â<%}n˜u»ÊUŒ™‘™•ËÕãŽní�:9´#­aüÎyÕvl£”Ìx = rk ²ci\UšoÄ�¢ATõ…ol¼—QâX åo1ÉjþR¾â1³MÏOë^fGüv¤ñ¾¯�”´ñ‚Ø'¿0–»ëÜâXâû´´8>_¹Ïfç6e§2ûò„øè8è¤(jüÄ‚�­=Ìf[kƒ ¯ƒÑéa‚z«êñ;„ )Ú¯Zù_“˜Gh�Dîg2b=AFQºî}°ExW)Ò3ÈÆ5 4e h—(àsqN›_ÕŽø ¸2Ãrç¸Âðš÷ò‚øÝžš%;k›n·ðùÊß«ªmÚ�C=lP“b;>;99j¸ìdEP6^ÉÏ"Šä”Êe‘ò[Õ½�ehÅü& f†ÔAr?C�f¦�ÂåQýôêK«B¬§Ñï2…µƒ¨L|ÌÇ2.ìWË, IDAT—èOêɪ ÌïØ×Äx_qê¥Cr�a-`°9ùå[+ÿSÚ„zîÌÿyFîÀÞ¡œ ‚¸îû‡Ë›�j‚!v:‘72WK406–?¡w­Õ#‡êdfVýª}K˜žâ[ï:fhHSþÅ |Í®ñi¦˜8ÒÁDÈýŒ@r £¸ëµž*Œ~ÛKhùDZ�.·ü÷‚Žñ»¤¿› õä°ìi}2ÂkÞÛdu¿ºá誓¶<í·�J›00#dY mßy|ë¯Õ:Ÿ›Šßõ$ø‘£2c¢e¡z<|yiƒ¬8µó´)¨Â”TµjY¥Úî]‰ i1#Gh��û™Ž¦Ä1ûÛxyù«-`àÆ% GFþ²x/‡x¹›¥(#C;x|$j‡ø} ‰ûëè¼AÙaNŸ«m[üÍÑ2;zh2 á}.Ÿ˜O…¬t—¬ùjm¹ "¨Ý~��gÇŒÍ�µPWÓÜÚèDŠ'½AØyðE +kß·,) jžafï$ =’P zÇ2®é+9êõ̓êÌ*^ #¿–‚0Že�œ¯’ò¥P1áR“_gxvZqx™!°£¬aá7G¼ÌÞS›f¼azr£uMËç_• ""‘*ë�W?*î¾ïǎ˵D•¸|¢¢Áí¥¤½ttê®eŽ?ÀmÈ2ÄW¥«ôœDB$r?ƒÈÝÂ�jgÀøGçâèé®ýQ,ËœrAyt'ÂGÿmüNpUfüŸFç'Æ„³û”ÄoöÔ,ÙYÛ*ô Ì c¹{Ï-¶Ä„úàßÜâødå¾6›|—BP2mVöàâ´—ßãbÙ#ò¢h‰ ‚Xú{ öø§3û4вÕ~Þ!Ôü€@z‰Ü ¹ŸAȈch¥óµ_cÁ~¨îìÃs°ª™MòÃR”™aÚ<¥­Õqä`ƒ­#ÝYK·Á“¦("z(Ü(NQ|š‘”Êr?£o ³MT…£S•ÞR*Ê?Y[Cëƒ[8®ÍÃ{©GkÉüž@Á‡‡dNï›Î„5}Úbs?ÿý‘¯«í ‡Dv ÷NÎîß+ ÕÖýp°¼¢M÷II�ß�J‚ON6 ˜]K´òx½ã´]fP1NL*Ù…Ê;ÇRR±­ªJ´÷ ´(JBr'8=Œ UËT8Üíi1Ú‡_܂ۑzÈ�™¦ 4í$[Ö¨Òa°È@?1.@–%¼‡v¬¶íé*vµ¹{ö SÜ5*cê�P)!´eÛÑ-;kt<Ù1~WEhø}Ê伨hs=ܽ£RYh{-¤“•ßâë–¡ íÉ¡˜@0·(•°A$€$TÃA¡…ÒØÉ@q‘BÁõ)3ÊL)žbÅßZXÖû•÷ÑY•_�f1¾0µ(ìÌþۑƾ9º³Õ-ЍgÏðUʼnsÇ…Aã.=TûÝÆJQT~xP“;õŸgåÏ! )Ñ0tHNt­O›Íy`WžGE’†ÞŠUTÐ@Iz�@Ž¡ ôWHKEÃÌÜdÂ$r?Ó�Ïr¸‘î³¾t�È:¦·ûÅNÉ ®'½.Že]�DI:ðnLxefìmcòÌaî>]¿·î¹uM¼ÐãçvjFìM3 BÏ"œ¬jþtõ!�÷ˆÔs”4AÕ&ý¾ZÈÓ 8.Ê®�Cªx�¨šåp‡¯Ò/b¿aY R* 5Ù@-9/6>!†P!÷3 )±L2GU»DŒ°%7<ÑŠM¸SÂ+ø›áÝž¡¨8–ir{ü’ qÜU˜tåð¬ðvŸ:Ýü²­'þ]Ú êiŸ8öžs âB¾u55Û?YuÀjç�tkl‡ß��Ê‘ßòÖËï½rãôÏŒ®•)âž�• g_ìx‡ï;…ëMC–�@ÕË$䜢$£‰´/YæŒGSý-¡ØWùŸ{é>$8EÈá3#²®•^fo¶¹—®?öÆ¡¦H8«É,\8§wFR¨ñ Û-|¾zM½Ã’CˆL§">ÅiF~+7Š‚Æç�lt­ÌƆ¶òÒFÝuZß}„‰+ÏZÒ®\@~q:áBîg&¥€Fv‡¾–_ !ò… 8ò«üÝ5,EÅ{•wû™÷'÷šÕ/-¼…1Gë¬÷­:üÙ kOkìÀBê¡Yùz…>\IX³þࡊ6—u„ß�‚ß³³búõ͈ºe¹wO…ÃÎ{VùˆÅÀÿJ@À±!f9­æwC,›ñÃÁ‰,C$ò, �Gÿªñ)3Êä ¿Y‡fp€ DŽmóðãÙ…ãr{%‡SßDì>ÖôÌæåvát¼» wŽL×/-äãBÛvVlÛ]‡ü3”p-!uD ÿ·Êø™Ó ÙˆŸ­‚ËéÙ±µR¡5Ž6T¢¼ô Ê;kÉÿ(!Ø+S³‰àNÈýÌE,G Žgkñ¨™»Š BÒÀk‚ZŠ71ôÕYñóGg&†5}*ˆèÛ’šýV×Ê£HÐÙ)®î“8w\^èEÓ×}½á¸ Ê"»>¿ƒÓ¤X‹z[ zG_dz¤¼¶ö¤¯ãô§ü=ÒX¢–ÆO”Ú¹@ßaÙr®•€�ûš‚ƒ“9‰Üu¯¨*£VÍÈWŽ4ÈZq ]‘{a¿$cXãG»‹_±ýäË¥M"Š”399Ý|Ó´p”ÇT·|²ú/¨)[Íï´Ÿbe8mr>ÃDYØ.ŠâÖMåº}X*4EP¯|Ž10þ‚ø‰’æ¬úß®w¿ „ÜÏd%qÆcvGPî+HS.‰?ú²�º¹8~Z�…k|Ôló¼ò㱕U¶ÈaöÞfæî9qæPó–Í-Ž_—Ú�‚Žê¢âw¼ºT�ßû&æG¡ \]Õ\v  h$µü® F Ñ”× LïDaÑJJnLr ­GÈýŒFŠ™ím¦XB¨=ætἈuÿ€Ò9zþ ¤aÖ4�ÕYŸÚP±³Õ�zÚW@B†�~ìüÂÌ�Ëc\nþã¯öŸ¬s ßæåw¼]ù'«¨ø�¢©©“{3L” mý¹Ìí”kN±úCh—&¤ ‘£1õ‰’Öhÿ‘Y,Gø„�û™}Ni8,™;€›xè:ˆ }¬^Žß‹Íì­C’r áÝÕߎ6þkKõaQ'ðÁ©¹ÅÙ¡öÙò¼°ö‡Ãå'¬Ò¸€YSM¹·6Å:°ob^ÚØÖŸjݳ½Z&tlfž\‰9ÚAÅP0²%EíHmz'Ið úe’k?¢@J!»ƒÓMxH�Æ5Á»÷Cø¨&$î“^fDñû½uÞx"¢˜�‚àþQéãû‡ê<%"´eGÅÖ=õ{øA�μ¶Ü[i<À²ôÔè™­¸yÿz«€„Hy˜r�MÇ™�c(††ê«WKšš—–A<ÜIä~ 5†éC´ §‹Ó¥kÄÑ+_d›/�ÈÑá¼ ;Üü'ÛO¾|°YAä0Áõ}çŽË �F÷¬[½é„ˆ�ª½3zÔQÕõ%x‡ LÎ̈>5¹¥Å¶áû£h¯KóÕ!öȢʸ@SÐÀRPO…WÇïôžeˆ¶Æ.¹‰‰™&ÝÀü4áõ2¸žºâ¯‘„Ð44h©ía“åNTe6µï°ô¸x¹Ø ¹Ÿ]àh8!Íxü˜M~´E Ð|yÂë b§ôŽcÂÝ}úŸ-•+NÚ"ó]U”pÁ¨œp¸ÇÔ¯ÙzŸ45Ýöz@{ü>~xFrRôÙ`‡xür?;o¤'¥@»µ�¹FæÞa‰ƒ2Ìaü»�ÝÇ›\wl�Õ‘ÄúŲwÍ*0C}vll¶òm™ÓƒüŒ£è»T‰@™˜N›b�=)7êæ_¶n-?QiEJ Z~Wçñ¡‰c(Jæ«ÜÖw3ÀùÝûFM, (Â!„ÜÏÎó áØ,G©ÒRò×£¸?�JÊIo÷)ú~_Ýý?ž8ä"ó´d©¿Ì)HO õ~ær ­9|²Á‰3>nèÇï§I±&[¸áC²¢n±UU5}óu™”8EêIìÊ•‡Ý Å0Ú9íêm‘ò¾hI1õË"×xÄ‚hî]ŽœxnH<³£Ù£dˆ:7Ã8·ŸÅÈ„·ûTø|WÍK¥M±À@ðàäܾ9¡–Çxxá« ee56 ˜¿ý.)¾&&èû­~ŠU·|{⨬øh Û].~õª/úîSHCå*;_?ù³,Å14ÔébÕú“*R¬c¦ö&ãRIä~Vƒ¦à”3PV»³^ß;æ²þ áev«‹ý—š×·F,³îž:¶ojˆo‚Úº«ê—ý�RŸ¦hO©ÏÀ¡«¦ý2Éb1$;ê–ÙÎGìoÒ?H½ï„–¥ ,íÓ[T£!!þ0„¿ DÆY¸~ƒIW*‰ÜÏzôK5ÆXËm>‘$ž†·ô�”æ²MÎ¥ÛjK­| Ç:Q#®ô‘¦àM}ÿol•{Jk¿øùq‹CÜ¿W¿K/“%g7&‚wý�9!×lŠ2›”ªªÆ•+K¥´9òïòT/•ÌŽ€e(#ç/|ôZcjC~í &Ã&æ%&Å’K›DîgýY†à‚^¾¢º\ußЄ°3û¾*ë›kJ­<€¦`<‰ô4#Ýtý¤<6d÷˜c'›?ßXðªuÊR¥ €ư4/ŠŽžH®ÎÉ4ߎáJÇ«Zþ·¡ÂÛ¡£:<|ø:}Šb?—³Žýòc‹z'GÑ2øuû±õ+åO_§ÐQAßC™ ŒÞSf¦’h€¿{¿Š±pc‰ÚNÈ� +àôˆk4.?fý—¢_;–+>ßy_a<Ç ¢èìÞäêÐxîžY½cBv�9Õd_¾îˆÍ-(¢Qœß|¦I±ß9 ”be8ytvèšÝ†ƒ‡jV|ºÏ7GP%É@�²GŽ¥L^#_¤.„W>ò)ùú@0ev!q÷�"�:÷¨�Í%¼³óÔÿŽÛ�25/,î1Ÿm(/«³#ÿ|µ y}Æ—{Ðê3š+EQ³&DÍüë¦fÛk¯okjv�rµ}¤˜ '•Þj>w¤¾Eb%4ë€ 0ãÜ~f³�\‰„Ü Â‰µö7KšNºxÕe¨�Ãé4eñ7„�¡¨#×ìtw5¿ß?"uLŸPm¾E„6ýVµíp ½ò€¬*@¿ƒN§X%EbhQBvF|T,ƒÖVÇûËv(™]V™ü�Y> B`2°Œï¦¥Ì‹ªr­à~ÇþĬ/Qá=Á}&õÉ W"!w‚°AÑ/Ç­ohvˆ²ÇÄÒ\@®Úö9Êj3ô_ÓHV#XšŠ7p-NWÑ;M�y}.'ؽ‡Vm¯E„‡çÈWü¢äwÑ)²‚ëÌÁcSoünâ¨écs£"l·Ù\Ë?þípy«ê@äÃ&7Ò4Y úõ9ÝÖSØŽ¯(¡1˜è™ç ¾í„Ü Â/~]ÚôE…݃pf×ányNöJ�ˆ•ÁCF–Fˆkq¹»bŸÏ͈¹aR¯ÐËcŽUµ|¸ñ¸l}†q™B¢‘‚PÅp8UÕDÞ˜çýñТ„¬ô(èÇq:ÝË>Ú±÷@£Zq“8»3 möµ)I¯Dú­§°)V NœÑ;=#�\�„Ü Â«‹ÿ°¤qc½ Ç•Õ0@Ç´#.ˆµ‘ YZDl›ÛÞ}Ç.˜‘o¹É³¡Ù±|ýq»[”-M€Â”< ^1ÙÙÞ¦ŽÉ�üÚv—ËóùÊ’ß÷5J�&©=¥B#G Äz—€f©tŒß}MjºyôØÒµDÈ� <¨nu¿¹§ñ •ê¾pmè&M1ÖTÀ)*$Õ¿2³ „ Í6~/0ÓÍÎOµ„:ãÂáäßý¶¼ªÕ ýBPšt‚ß�,ÁkKà§ IÉH�ô~›Íõ¿ÏvíØ]Ú™Ôè=2  ÇP;zS­OÃï’ê hꂹI•�;Axp¸ÞñêïMu.!¤bj©SɘCeLÝŽ¯| Øõìͯš€Õ~_8)·0ä̤‡¾üéøÑF—´“¾£ÁK�:Îïj‰F.�7°pÂðHŸÈaµº–òÛî} Hñ™Êú›š†&#CS”|Þ�<#"Liz­§ª^ÿŠ5.+¿ •\’„Ü B…(‚m•mïnkáE¯@î«G“-žð¦K¬D–däh]EèŠ0ÏO1 @¨üÎB°xTú¨Â¤�_Üø[õ–²f *æK@­…ñûiJh€NŠR`êðô´ds$/†æû‡ŸìÞ[ÚˆKIXC²|àK 4Ä|T/@ {ÌOFÁ䪳SÒŒSfô%yTBî¡Â͋ߔµ~âïQ’r¤) "/!!ìj…Hú�ŸÆ¤;�¿®MiÎ „f–�´¹ÝÁyÏÐÌë›xÞ°ÌÐeÙ݇Ví¬¥ˆ]®Õóó–¿ë”ÐH‚÷îbŒ�38#’uäÚºÖ÷?Úu¤ÂªÈ£køB`20 Cé”IÏ=añ;P;z�—BÊ6་ÆÅ‘~TBî¡!´¶¬åËJÎ7Hg&R>7+edUY§âµ’JÛÄÒ°­AÅïsÒÍ׌ÏeCž{¼ºíãÍ'|N’J|€Ê2FÐnŠUïø%~Ÿ0(%9!rÃöã ïÿ¯¤ªÖ ¶U)¤Cy ñGŒßq Gc�©y’¸¡Ñã³ ‹ÒÈ…Õ Ï\áð S µ3ëef“ ? â‡Z#ˆÿV5ÜXùþÒM,c1r� eGX¸{g†Á=¦¾ÉñÎ÷ǬnÁ?Î÷_¼W)΂Ξ"¼oë³WJT ÎÌN¡“�EQü}ßɽºíd­])K©×�ÑÀ˜ÍESøÊÐŒô¿v*”3�BþòÆgåÅOŸÕ�TÈr'òŒ—åÇ€ÀŒ �ô¤ ñ—i.A(Ó>Tr!¾5TÜZ€M[ŒÕáK:Ç@/œž—j)…ÃÅ¿¿þh�Õƒ3Ò“¿CÕ)@j_~Ÿ6,5Ö‰ƒôx^ÜðÓá7—ÿîµwST;bÇH3TL Çh!‚P tœß¥w†BЦ¼‹‹5Ðç�ß/&†TÈr'&öŠ›’l�œ¿¤À\qëÐ9€*(ÕPçV¡¤8šJ0²ñ3Qð¡)9E™¡—Lj_ü|¼¼Á¥fŒß‘’ßQ»±j{üAZ7j`zƤV«ëã/vºæˆËë }Ž` o¿PÀ`dbÌ,MSÒ¢�Ÿr:ÅïxB耜5§0¯W ¹ ¹„, /ïo)0ÓRŒ® ½±q?M”�ý*¶Q=`_ùÂyÈP”ÅȱíväS<82mtQ¨è"B?ìªþ©¼Õ«…#�C!Ò•Y¤o¡R¢Áø]Iyò†S‡¦Y⌑ö¹WT6¾öî¯?m¯åúuU"ËP±fÎh`¤‡7I}SêQšs•ü.)]( RÞB„§Œ�O®DBîáG’™½¡¯ª£n¨ /Wí—jÍê¼@¨’t¤¯i ÆYC` �[ŠÎ©’²Æ¯v×áa§Æ’#& �à•¬­#¿h%ø83r@d¹_‰¢¸cWÅKÿÝY^aÊ8[º;S4›Y³‰óyàèH1Úçís™Jꊡ(ZºO‚äãœsú3ÑãkO@È=ÊPœjšWG}5FëÕ®ko�2>—z­r!ªÔ,aœ��á­€qIvÌõóBw�9r²õÝM'}³•°xAeÔ eåA?Å ~×RÞ%“rLÆ*kiu,ût÷›ÿÛßjç5z@@  L\¬�eh¨M«*�ô}Ø�–ß„€‚4KCJî‰àXúÒK[,frž1 ¥�‘ˆ‰½â*ÛÜßU;¡ÒôÑWÍè-~à-K¾_©ZU^˜$ðWÑã”� é&†f ´º<’EðH wÇ´0¸ÇÔ7;>ØtÂ!È“ý»¨�zê;JÝþ„•xâ3ƒ¤0U*‘ÌI4 (Œ)YDèàáºO¿.­¬µëL=… Ȳ”‘chJ™ü–›HuÓ4-»@·³—¢ MC¡÷ÍB4 Ï9¯('7‰\z„Ü º, /í—xÒzj_›GјŠq´týg0óH 4'Ðõ�QôOÀÒt¼Z]�ˆ ÌÌâé½’ãB­£°;ùwÖ«jsà# œz*ÿ¼ü®s$B‚Ù£3Í‘¶[m®5ënÚ^ãöˆªCóžwš†FŽah(gM Xû�ÚoÙU³Ó4EÓXÅ Àq㳇'S–¹t b ô¼¡IÏm?Uít¯%O(¯Ó!Gå}*ø¨&kË-P²é„DST¼‘s{ø¿LÊ)ÈÕ ×í>ý¹²¼É�ùïà#yê©ì‹‚ÆïþHö´.49Ɇ�E=¶ó‚¸ÿ`Íçß–�¨³û͹�& ÖqŠ}¨Þ.ÜÓð»ÿ\([vå6e–¡ EùO¢o�'L�Ú'ZfQr?�Ëþq å…=M6y% l.õ³!DAŸxÀÛ IDAT¤ |qÕ3:ª >¡ 7®˜X¿pdúðÞ‰¡Ëv×n9ÖŠßlÔäÔSñ rˆ„ÂÞJj¿”:.3Gdrlç ë¬_¯?´mï)�äÞþC£ih4Ð,�ië?vYui�ß�úÅ¿SdZ1B€PJŠé¢  „¹t/ú¦™ÿ4@|yo �ùȨ"n jHº2ºâ]µ-ÂÂD­¶!¸¶Ð2gPjèåá;5|VR�ÿ•“¥®ž åwÜ`büðܪÿtõÍ2¹j3Øì®Ÿ¶_ýãq§!¿Î-*MAÇxý FPCÊyŠò°ÜÓé3øÍ€fiÚ+Þ{}füþr †+/b±Bî=�Ù±WÛøeG¬ò5,Yþ*}"jOC—¿…x\§H®b!°ì?9Íxéˆt&äÇöòªÖå¿Ô(•tåÔS­žàçh]_} ^2ƒ HA0}xfO•÷¹=BÉþª5�¯sxE%œ¾š2rŒÔ30k Té:]íÓ«“b…4Ų4TÞ–½7 šs/꟞O.1Bî=†™…«[\y®x”×VÂø2ˆg¡C?CbÂ~~Çço*f] Ð7Ž›?>ÇÌ…ºNj›ïn:aãE p°ÂBT™Ì”|UB30'¶O¯çá…òc _®//;Ù&Š'ÇÑ–a(Œuu�éeÖF˜­#Æïí†e¯¡H™naYêâ ûôîM:Q ¹ôì‡DËú'Z=⺧2$Ç x½5“j‰ó‹TZÄ€¨©�Ì42÷ŽÏLŠ Õ‰ÅîäßÙXQmã!�*Ùêtü”)V Y×¶Ÿb�9*‹íÞ°ÝãÊ+Ön:¶§¼â¥ùP4e`iŽ¡(JU”®™ûª§º($x)K¡¿SdY†¦)„ð%d¼ï! çÌê=°¹²¹ô<8^1 ±Éݸ½Ñ±é *ñiCz€O•ŸØ5óD¥ê ™ßŸjW‹‡>ÿåDY³(JÚuØJÅïŠÚžv$xK[Ñ@”j î“žjyŒÓ#þPÞjŽ3Å Àj÷ȶ^šy�öØ­ã%44§ g)H«Õy¤²y×Áúýmµ­n$ †‚F–aŠ¡( Êã]«FŠN+ ÔÍq vŒß9Ža9Æ7>I¹g„TŸ4Á‘ƒSfM+b‰—ïY…K]°¹„÷v7lip‹Èû@"RÃ{?_ï?"þC$=Üû–K�ÇÆ¥ÊÙ=F¿?Ð|´É-"„°9=5ͫã(ÍFòú“n0òþ$‘rÊ�ÿM”î+×4fLš;¹W(©TQíO}“½¬²y×Á†½'mÞt YŠ¢}Ú¶Ò]X±Ï@šQ­°RWf¼ý¿E�·RŸË1ËxUuIöAÒhùO €E�É£3'�':;‰Ü ¢ 1ú¦aIìïMj�R] TZ‰aWüY÷¨�"€?õO �ÙE„v³mrû+ÍQ¬‰-42mOC««ÅæVYz)-Pü¹Ä R¬þø=–£& L ‚ÙE5µ:O5Ù�W·”WY�×9êÛ<4MÅ™8 Bèí~•É‹©½�B?麪PHðËÆvR¬ǰ, )lˆ¸ä"„`å:3'挑C˜��;A4ò;sÃФø-«OØy?q¼”5Ò»'^–7-å1û«l»jòè볉3q±FÖéNµ8[lnAµü‘b�Ø'1-©=³„€(Š‚ˆ<¼ØÜêlhqÔ5:�Õ´¯w¶:—@Þ†ý#«8™ª&•f|†êö�Æ+L¢ñ‘¹^ŠÕÿÎ9˰ÞzJP•­ š66Ž¥fOÎ1$3ÆY† £àEôÝÁæ�ŽZ=ÞÖ„ÚŒÿ[Q)ÓHßMJ1Ü9!ËȆšm«lt}}°Å#È„\Ø�9¸y¡±ÍÕlu¹<‚ÂáRÕR�”Z‡ò=Õ’Žÿh¸° Áï8/ŠÈ#<�.ÞæðØœ¼ÕÁ7[ÝÍVw}«»¦Å÷xAiçС@Bãy¦Þ+¤h=Å­6‘rK¥ÜC5–¥8Î[ #gÌ¡_º‘{d=Ç÷*³‘¾pF~ߢ4Bì„Ü ¢‚ˆ¶k}ë`›S¥‹Üáûþ‘ôuü‡…fæ¡)™¡'QmüWšÛÜØ_ÌïA­Oc›³Íá‘ôb¥žP€n‡ßc8 à�Ç‹ÀÉ‹ÞTÄ烫µo¤ Èò; ¼WªÌ0ê¿C9ÃùÇ0©Ò'»oûø)^kb.;¿8/;�\„Ü ¹Ÿ98XçxeOc½KÐ Þä@(“¥þ2)3'1ÔáJ·ðùÞæ&§ ÓÒ¡B|±IlïáÅ&«³Åêv¹€LCL±â¦:§ãw�ø]ÿ®Ó.¿J±âwËМ�aYZ–f¤Û2vKöÝp~÷ÿ*7Ý|ñ좤D2 •€�û‡Í®·w7hã%.•HAD2½"X“20+6Ä¿èÄõ‡ÛŽ4¹Î{ø]¿K¿Eäpñ-6w›Ããvó§áw ¶ÏÕH:�ÈàQ¼ö>�ßõT£võY?Qí’º„–¡¼¥�þP©¢uåO|ÿƒJ†ôïm9z�ÙÌ‘«€€�û™‰VÿÑÞÆ�5QÉ’  ¸m@ÂŒ¾!WÑ/Ç­»ë\¢ˆT…ê~~G Zq�ÁY!$"àtó-6·Õîöð‚Bá "~Ìï•hN¿køœN‚÷Þ]oœÎÑžôT²¹"0WÞª}ûƒ€¦À¤éãGä°,)f' ä~FÃ#ˆë¶¬8ÚfYU¿Ýº"?ö²!)¡7èÿ^eßTa²Õ®.¿c…ƒôU˜Œ@9ݼÍá¶:#Ï{Óò»^ŒÅï:�¾ ˆ^py—[p»�Gðð‚ˆtùœ>ÅÚ™<~§(HÓCC†¡Y†¦iè³èBŠˆP ~‡ŠúTNÇï1úœ‰9} ’‰!÷³[¢AèP­cÙ¾Æk$ÌŒ ñÝ<ú¾¬íX‹GÄØêÄï8y#íÏ Rpzàøi9!u ìžD$ò¼èáE/ò�/ò‚ˆ�ß[!Щ+&ÙC()2EÓKS4 oB*JäýBHG®‘» :ÁïÞRægšÏ�Ø+)ÁD6!wpº…Ðuv�­Ç­{êݸjŒMýQÆï²Y™BÁË!a}F5¡ÕgT�í ÊíÿF‘ ˆ¢ˆDï¿!ˆ¢”{Šë6^0Š@ B!EiÔ|tîLH¿Ër¼¿cíZíó»�¡¦ O> �TÅr'3öÕ8~®tÊð30¿#<•ªh�U‰0~WÌ,ò)<èôñ»ò­ðH\s'Ð'b¿O�‚´ý¶ºH³¡¿«òÉ�ãwÍIR<ÍHÜï=¥9)Æ9ãs3ÓH�;A¸QÑäúöˆ�5 IHC·èð.FˆHÁŒ�áweÝ ^ß>¿ëÝ tˆXiŽ®ËïŠ+¾ÀøÝgÆ‰Ûø`Z¿kþ^ 2rôä!)#¤3 QØ ¹„§lüÚ2«×œLfE¤§š(ùàf7#¤áw4²Š¢ ¿%À@ü^|‰‹íGúo¼Â z‘"a øJÁËJ~GØNÊvm Å áÙfÍ­Ñw˜}rb§ŒÈHOŽ!+�€�;Aøáðˆ_–¶5»E¤-ŒÁåŽôPëÚˆ²ªô2,ìè¾É}ò,$Z' äNÐ3°¹…#Mž]u.›�†ßõf·jo°ñ;þn°3ÉUMð® quì�¹+û•Ô¥ú8;Cp~×4 ü­² ãû'åeÄ9†¬.Bî= �€Ž5»÷Ö»kB¨}~׺Ä(èWâÇÓò;PªˆGÞÊû Äï:“.ä ¶U]€¯1N:ºŠßñ M#C¤™†%æeÄ’:Bî‘^@u6¾´Á]ÖìæÅÇïwAJmDa•Õ!8HWoÑ/žÞ\*OÌè¿«$¿‰úÎÒ~Ç^k †ôŠëŸŸl1R¤#‰€�;AÄ!`u å�®ý§Ü­¥Ê®[@ÇmFÖ®5#U5Âv€Y}�ù]Q4`â�šßýï ó»^m‡âwïMŒ£aV‚aH¾¥ +ÖÀR¤n�€�;A4òµVÏ‘&ÏÑV�Õí ½�¶ EU1‰±§^Õ Ò‰ßõõ•¤zX8 ¿ËN–¨}~×Ü��R˜ƒB®(Ý\œ—š`$”N@È� Šy/V·zÊÝGÛ¼Ã�ÐÄïÚ1R¹‹^H®_ª¨Ñ[”OHKû:Ff ºŠßUž‘Þý1qÔ ,saflF¢‘ÔÀr'8£àâÅ“-ž²Fw­�·zê<¿ëê3x®©ùZ]k¯vÚ^*~zS[OÇ¨DÕ;ÕT”›•l"&_„Ü Îp8<â)¢Å]ÙÆ78Eép.ž…H—ßõ‹Ö‘®Þ¢àwMüîùµ} øèÈ>¾_14̱°ù©¦œSrœ�c‰Ó:!w‚³ ¼€¬n¡¦�?ÙÆŸló8xQ�¨�è%c¿«Evµbu²¶Š»Ðí‡Rfw}N;óöbih1Ò½’Œ9I†¬d“�£IœN@È�€ÀGô-N¡ÁÎ×Xù:+ßä]BmEÝŪÇïhõ5¿#ç2 ©·Ëï¾ÄsTr —Çf%’cYK KŠ^¹œ†è]¼ØæìB½�¯³ñõAò(ƒŒß®�jý¦Süîý½�‚™ñlZ›Ï%Ų±F†c)¡r' "V—ÐâZ]B‹Chq ­NÁ-"·ˆÜ<ò¢Z\A*µB®k9àX8 Ú@£“`fâ�LB g¢c 4‰Í ¹t1Ý‹È#"�€Ü¼è�Ó#ÚÝ‚[Atx� ˆ„ÜX¯,¶ EK„ ÍÑÀÈR �mb)–†,Cq ÅÒarBî„”õðJæ& äN@@@@pæ€çr' äN@@@@@È�€€€€€�;!wBî„Ü ¹r' äN@@@@È�œBî„Ü ¹r' äN@@@@È�€€€€€�;!w‚®CNA;hiiillljjjmmu»Ý.—«­­-%%Ÿ”””œœÌq9W„ÜÏd¸\.—Ëá; !Œ‹‹ zs·Ûít:{d·ccc!„ay7»ÝÎó|x®"†�REÓ4MÓáÚÞ‚Ãᨯ¯ß¿ÿž’’õë×oß¾Ãûs›Ý®}qŒÙ ˆ��»à‚ ÆŽ;hàÀÞ½{[,š¦ ôðeŽ"g!ŒØ´iÓ?ÿùÏßÉk®¹æºë® šƒ~ùå—'žx¢ûw;++kÉ’%¡Ü–p¼ùæ›+W® Ë[¥§§Ó4m2›ãbccbcS’“SRRÒÓÓÓÒÒÒÒÒ,KT,]AŽ?þË/¿lܸñÛᆱ®© î}ÆŒuî¹çNžü0¼ïlµÙ7þ¸iã�›23Ò/ZtÞyçõêÕ+Ú«è¹�ž]¸ãŽ;FŒAÎC÷£¢òă‹_~Åo¼ñ«Õ »tèСGyäŠ+¯ ;³«îp÷ÜwÿUW]µlÙ²¶¶6²¹„ǹå�dY–œŠžÂþ¥÷ÜwßM7Ý´ÿþLwµµµ½÷Þ{cÇ�_úÒË �MÝðwí)¹ûž{¯½öÚíÛ· ‚@V!w‚pâé§ŸNNN&ç¡ÇñÕ×kn¾ùæ;vôÈ_?zôèC?|ëüÛt«_º6»ýÛuß_}úü¼éÇX¬ ӳɃûï¿?//OõC›ÍV]]½oß¾µk×~¹jUÐÈîÝ{Âøy!„¾\µê½÷?ñ}fÏœqÑE�;¶°°0>>^õ[�ÇS]]½wïÞU«V…Hô �MO<ñDqqqVV¡B¤¤¤¤¤¤°¼•(Š[·n ‚Ù3f̸ä’KºÈ ÊëdK>k/bbbŠŠŠŠŠŠæÌ™sÅW<ö·¿Ëoݺåºë® ×^UTT¼øâ‹¡ô Ž=êž{î™1}z;]Í,Ëæååååå͘1cþ�ï¼ûn(íQ›~ÞüÞûï/^´ˆ‰aÑÜ#¥¥¥O<ùd&'%.Z¸011‘œÃî„Édš9sæk¯¾:|è� 6?tøp¸|µxž_öá‡AëE1fó=w-øäÿ»ü²Ë:èWa4‡þÏüãã�–èß/è=öÙg÷íÛGÖ!÷3v»ýù矯¨<Ķ |�X?ö† òÀÄt>ÕÑØÐ.r/++ûûãANSINJ\òüs�?þxVVVg#h“Étéÿýßï¿?eÒÄàþºÕf_¶lY7tur'è „Ö¬YóùÁÌ š1}Ú5×\C†œõ fÍšÄV'«ªÂb§%ŠâG}ôæKžþ†n0™LA¿ÃàÁƒ_ýõÙ3g·ùG\ZZJV!÷3eeeO>õTp‚éÃ=”‘‘AÎa"11qþŸníìV �M�',‹çÃå˃Ø06Æüâ /\yå• j*®¨¨è¹çž3zTÛV×Ô®\ù%)‹$ä~Âãñ¼üÊ+ÁÕ&/|àÏãÆ�#ç°Ç1tèОzæÛ¸qcpjÞ¼›o¾þúëÂõÌ׿ÿ¿ÿíoÁmûöß&ž‘„ÜÏ@|ûí·|°,ˆ Ç�{Ûm·…v„ŽžzxjiiùòË/ƒØ0/7gÁ‚»Â5|Ü‹©S§>õd0ÒuMí/¿üBV!÷3 •••K–, B�‰1›/&Ö�s]u¾59)1ô!Y‡nê÷ßÿö·üü^á= Ã\wíµ“&ŒbÛÕ«We†�û™žçßyçÝŸ·l bÛn¸~úôéäF/ÒÓÓCIcz±cG0Ó?¦M�ÒE¾¡™™™7Þxcþ¶kWMM Y„ÜÏlÚ´é…¥KƒØp@ÿ~÷Ý{/±~Œ1;%9YÛÚ)ˆ¢øñDZáu×^ÛEó!„çŸ~fFzg7¬¨¨8tèYH!=9‘S!¨¯¯á…‚«�y衇òóó»mWÛÚÚššºÛeÐd2¥¦¦F˧¹·ó�899¹±±±¡üÑÚÚÚ’ßïìV…½ó'L˜ÐuM¡iii7Ýxã?þõlçîŽ6ûÞ½{g̘A˜��{tƒçùeË–mÞ²%ˆmÿxóÎ;÷ÜîìØ.))¹í¶ÛºùÝqç�·wû ---¯½öZg·š8qBˆv'«ª‚Øjð�!ZÜðbÖ¬Y�%wÀáÇ�N'y%äÝØ¹s翞}ÖjëtØžœ”x÷Ýw‡ñu¡ƒ‡»{:š(QñQŠ¢¸zõê zMGŽ⟮¬¨âÉoú´i]=\·¸¸83#½³¶b%%¿rDsïyX­Ö'Ÿ|287ÁÇÿþ÷~ýú‘s!@mݺõÙçžëì}züر¡ÏT nžQÿþý»ú´ÄÇÇO™<¹³[mݶ-ˆÔ!÷ ô>ø`ÙÏ›ƒd®¹êÊ+®¸‚XèEÈçXWW÷Ö[o]xÑÅA4 ýñ�óBÒàU ¤IDATüª¬¬ b«n(É7�………AlØÒÒB–VÐ ²LcïÞ½¯½öjOÓy¹9 ,HHH ç°G"t§Ó‰r8MMMUUU¿lÛöõ꯷nÛÄ»�=jæÌ™!Þ¤=Op“ê¤ñ#]š¦ƒ»…„Ål‡�;AÀjµ.YòBpúõ‚;ï$Ö�ÝŒÛo¿Ýd6�(:�NA­VkeeeˆÓˆî¹ûîÐ'Tˆ¢\×O÷$l‚û+öüè ¹÷$¾øâ‹åA&Ïž9ãúë¯'Ö�ÝŒàš?ÛÇü[o¹è¢‹B×ÖDQ‚Ê9w�_E¸&ØtDsï1”••½øâ‹Al˜œ”¸pÑ¢””r£³gÎX¼x1)! ä~æÀn·¿òÊ+%{ƒ:sÏ=÷L?žœÃhÇÅ]øÚk¯egg‡çJ¦¨àžäºÇÂ…¤F ¹Ÿ5øëÖ½öúAl8 ¿?ÜtSèS=‹;n›ÿâÒ¥½z…Í« B¹w�®\Qcèf;g3ˆæÞ8yòäŸx ˆ cÌægž~šÌâˆj 4pÑ¢EçŸ~LLLß–ã¸à {[[[ÓÓÓ»ô�EQ¬®Æ¬›»ó¹„—Ëõúë¯7NáŽÛo›6m9‡QŠIÆ_}õÕçŸ~93ç"P]]zÿTûp:�Ç�bÃn(Ó$äN6lÞ¼ù­·ßbÃýûÍ›7�<¨F#î½û®Ù³g><99¹ëšÎ‚“ïËË˧L™Ò¥‡oµZ·lÙÜÙ­F�C"wBîQ‚ÚÚÚ¿ÿýñàœ}ôÑàÚü“ÉtÓ ×wó�ÒZºk¯¾úùçŸë"C]rsscÌæÎ6ÄmܸñÆoìÒ²Ú#GŽ”=ÖÙ­FŒa2‘:"BîÑAÞ}ï½àšoùã¼sæÌ‰�6lØ+¯¼ÒÍ4DÇİà�7ÿáíwÞíÔ&ß~÷íõ»®›5kV7ì^pjÏž’’ªªªÜÜܮ۱M?ýÄVEEE]íhFÈ� <Øöë¯A8Áôï·àÎ;Û 4MŸ�ýS·Þzk]]ÝW_¯éø& �M‹/^½zu7¤ÁÓÓÓ‡ÚÙI^û”nß±£ëȽ¹¹ùÕW_ fÙ@|“BЇÈ)è444<ÿÜsÁõ©ßwß}Äú1�’’rÏ=÷tv«’½ûÞxã —ËÕ 7—]vY~ºbEÅ Û7m âÍûõéÓ—,9BîQ€�>ú¨SŸ„ Î;÷²K/�Q‚0vìØ;n›ßÙ­^ã�ü±vo̘1Á�ûç_l jPÌiÑØØøÞ{ï1¨`àÀ�ÙÙYd½r�tìÚµë‘G büܜG}”TûF Ãí·ßÞ·¸¨sÏm�M - Î’·S(..ž1}Z>úè£���áÝA¾øâ‹ 7±í%—\B:õ¹G:Z[[_yåÕà†£Þß}ƒ&ç0¢PTTtÇwtv«ýJ_û÷¿Ýnw—î›Åb™{ñÜ`â�=%ï¼û®Çã ãΔ””<þÄA„í€ &�•FÈ=¢!ŠâÊ•+¿XùEÛ^pÞ¹W]uU÷˜öt4M_yå•C ì솯¿þÆ÷ßߥû!œ9sFaïü ¶}î¹çÖ¬Y#ŠbXö¤ªªêoû[pI¦Å  Ý™€�{×âðáÃA/>ø`÷ÔGtÉÉÉ�?þxg·²ÙíO>ùdyyy—î[aaáå—_Ć �M·Ý~û?ü€ qjjj{ì±µß~̹MJœ;w.‰i¹G4œNç‹/½œÓÀc�>2zôhr#S§N ¢“kÇo»^|é¥ðªÚ‹«¯¾:¸m›îºë®uëÖ !Œ#?qâÄâÅyïƒeÁm~Éܹ Œ�{ä!´zõê�> rǼ›o& ¥HFLLÌ‚ òr;Ý7ôúÿY½zuèÑq;èÛ·ï#=ܶåG�]uõ5¯½öZsssg·õx{ùå—ƒs×ðbñÂI!÷ˆÏóK^xá×í;‚Û¼¾¾~ÅŠaß«3f„EÄß±cÇO<Ñýg5++kÉ’%ÁÛv‘rÓ�7~òÉ'û”vjÃ_·ïXºté³Ï>Ûu!jAAÁ=÷ÜsÛíwØ‚µk_ñégkÖ¬�={Öå—]6lذÜÜ\†ahšö¶\ „¼S[›ššJKK×®]»jÕª dpŒ;ö–[n!Ã# ¹G4¾ÿþû‚Õón¹µ+öêà�ýa!wžç»bšèéoNÓ§u©šÜýæ¯ùËõ7ÞÔÙ ÿóÖÛ“'O¾êª«ºhÇ „sçÎݰaÃß}/è7±Ùí+¿\µòËU€áC‡Œ7.'''1!�¦i›ÍÖØØøûÞ½«¾Z–NNJüË_çZL@Ƚ›P]]´ C]€Ξ3çÒKæ~¾òËÎnûì³ÏŽ9²ëģѸxñâJƒóªSaמ’]{JºîLÞu×]3gÎ$+*Œ Õ0Ããñ¼õÖÛ?lØHNÅY‚Ä„„{ï½7Ælîì†%{÷ýë_ÿjmmíº}ËÏÏöÙu¶Ÿ¶ûqÃu×Ýqûí¤‚€�{Dã×_}â©§Èy8«0jÔ¨?λ9ˆ ß}ÿƒ/¿ü²«÷íé§ŸŽä³7{æŒGy$!!�,$Bî‘‹†††¿�º ÃÌŸ??¸¾Ð‡y¤´´´ ¯pŠ:ï¼ó>úpYfFzžº1£G-]º4?¿YE„Ü#<Ï/_¾¼G2�=ŽÂÂÂ… ±auMíÒ¥K»Tœaæ’K.Yú AhG]³¿õæ›]=Á•�;A¨øý÷ß_|é%rÎÒ ‰¢.¾øâiSƒFúÉŠ+W® —©‹.hš¾øâ‹ßüÏÉI‰rÆÎ™=kéÒ¥dP!÷H‡Õj}øá‡ƒs 83�œœüà³xlö{î½oïÞ½]º{4M_vÙeŸ®X1~ìØž=Q±1æ»ÜùöÛo“˜��{¤CÅ+VlÙú 9g9&Mš4ï7±¡Ínþùç»n’‰'¾ù殹êÊù„çù®ÞÉ>}ú¼ôÒKÿ~õ• ŒqBAŒÙ|ù¥ÿ·uóÏ7ÜpCä´r'sÙl/¼ðBgÐ ÎTôïßþüùÁ,$»ýñ'žØ³gO7ì¤Åb™7oÞgŸ~zÛü?ÅÆtG–uÈ �/½¸ôßÿþ÷È‘#ÉÌHBîÑ�5kÖ¼‚ÓÁ†a®¾úêàê«kjüq«ÕÚ û !:tè?žyæóÏ>»è‚ó»ôo=óôS+V¬¸îºë, Y!„Ü£åååO‘Âv%222^\º4¸m×~ûÝûï¿ß âŒf³yÚ´iË—/_¿î»ù·Þ^¡fÆôi¯¾üRÙ¡ƒ¾ÿþÞ½{“€½»ã r ‚Ïó?oÞNeed help?

Open an issue in the issue tracker.

python-msgspec-0.22.0/docs/api.rst000066400000000000000000000060211525673062400170170ustar00rootroot00000000000000API Docs ======== Structs ------- .. currentmodule:: msgspec .. autoclass:: Struct .. autoclass:: StructMeta(name, bases, namespace, /, **struct_config) .. autofunction:: field .. autofunction:: defstruct .. autofunction:: msgspec.structs.replace .. autofunction:: msgspec.structs.asdict .. autofunction:: msgspec.structs.astuple .. autofunction:: msgspec.structs.force_setattr .. autofunction:: msgspec.structs.fields .. autoclass:: msgspec.structs.FieldInfo .. autoclass:: msgspec.structs.StructConfig .. autodata:: NODEFAULT :no-value: Meta ---- .. autoclass:: Meta :members: Raw --- .. currentmodule:: msgspec .. autoclass:: Raw :members: Unset ----- .. autodata:: UNSET :no-value: .. autoclass:: UnsetType JSON ---- .. currentmodule:: msgspec.json .. autoclass:: Encoder :members: encode, encode_lines, encode_into .. autoclass:: Decoder :members: decode, decode_lines .. autofunction:: encode .. autofunction:: decode .. autofunction:: format MessagePack ----------- .. currentmodule:: msgspec.msgpack .. autoclass:: Encoder :members: encode, encode_into .. autoclass:: Decoder :members: decode .. autoclass:: Ext :members: .. autofunction:: encode .. autofunction:: decode YAML ---- .. currentmodule:: msgspec.yaml .. autofunction:: encode .. autofunction:: decode TOML ---- .. currentmodule:: msgspec.toml .. autofunction:: encode .. autofunction:: decode JSON Schema ----------- .. currentmodule:: msgspec.json .. autofunction:: schema .. autofunction:: schema_components .. _inspect-api: Converters ---------- .. currentmodule:: msgspec .. autofunction:: convert .. autofunction:: to_builtins Inspect ------- .. currentmodule:: msgspec.inspect .. autofunction:: is_struct .. autofunction:: is_struct_type .. autofunction:: type_info .. autofunction:: multi_type_info .. autoclass:: Type .. autoclass:: Metadata .. autoclass:: AnyType .. autoclass:: NoneType .. autoclass:: BoolType .. autoclass:: IntType .. autoclass:: FloatType .. autoclass:: StrType .. autoclass:: BytesType .. autoclass:: ByteArrayType .. autoclass:: MemoryViewType .. autoclass:: DateTimeType .. autoclass:: TimeType .. autoclass:: DateType .. autoclass:: TimeDeltaType .. autoclass:: UUIDType .. autoclass:: DecimalType .. autoclass:: ExtType .. autoclass:: RawType .. autoclass:: EnumType .. autoclass:: LiteralType .. autoclass:: CustomType .. autoclass:: UnionType :members: .. autoclass:: CollectionType .. autoclass:: ListType .. autoclass:: SetType .. autoclass:: FrozenSetType .. autoclass:: DictType .. autoclass:: TypedDictType .. autoclass:: FrozenDictType .. autoclass:: VarTupleType .. autoclass:: TupleType .. autoclass:: Field .. autoclass:: NamedTupleType .. autoclass:: DataclassType .. autoclass:: StructType Exceptions ---------- .. currentmodule:: msgspec .. autoexception:: MsgspecError :show-inheritance: .. autoexception:: EncodeError :show-inheritance: .. autoexception:: DecodeError :show-inheritance: .. autoexception:: ValidationError :show-inheritance: python-msgspec-0.22.0/docs/benchmarks.rst000066400000000000000000000537001525673062400203710ustar00rootroot00000000000000Benchmarks ========== .. note:: Benchmarks are *hard*. Repeatedly calling the same function in a tight loop will lead to the instruction cache staying hot and branches being highly predictable. That's not representative of real world access patterns. It's also hard to write a nonbiased benchmark. I wrote msgspec, naturally whatever benchmark I publish it's going to perform well in. Even so, people like to see benchmarks. I've tried to be as nonbiased as I can be, and the results hopefully indicate a few tradeoffs you make when you choose different serialization formats. I encourage you to write your own benchmarks before making these decisions. In all cases benchmarks were run on my local development machine (a ~2020 x86 Linux laptop) using CPython 3.11. JSON Serialization & Validation ------------------------------- This benchmark covers the common case when working with ``msgspec`` or other validation libraries. It measures two things: - Decoding some JSON input, validating it against a schema, and converting it into user-friendly python objects. - Encoding these same python objects back into JSON. The data we're working with has the following schema (defined here using `msgspec.Struct` types): .. code-block:: python import enum import datetime import msgspec class Permissions(enum.Enum): READ = "READ" WRITE = "WRITE" READ_WRITE = "READ_WRITE" class File(msgspec.Struct, kw_only=True, tag="file"): name: str created_by: str created_at: datetime.datetime updated_by: str | None = None updated_at: datetime.datetime | None = None nbytes: int permissions: Permissions class Directory(msgspec.Struct, kw_only=True, tag="directory"): name: str created_by: str created_at: datetime.datetime updated_by: str | None = None updated_at: datetime.datetime | None = None contents: list[File | Directory] The libraries we're comparing are the following: - msgspec_ (0.18.5) - mashumaro_ (3.11) - pydantic_ (both 1.10.13 and 2.5.2) - cattrs_ (23.2.3) Each benchmark creates a message containing one or more ``File`` / ``Directory`` instances, then serializes, deserializes, and validates it in a loop. The full benchmark source can be found `here `__. .. raw:: html
In this benchmark ``msgspec`` is ~6x faster than ``mashumaro``, ~10x faster than ``cattrs``, and ~12x faster than ``pydantic`` V2, and ~85x faster than ``pydantic`` V1. This plot shows the performance benefit of performing type validation during message decoding (as done by ``msgspec``) rather than as a secondary step with a third-party library like cattrs_ or pydantic_ V1. Validating after decoding is slower for two reasons: - It requires traversing over the entire output structure a second time (which can be slow due to pointer chasing) - It may require converting some python objects to their desired output types (e.g. converting a decoded `dict` to a pydantic_ model), resulting in allocating many temporary python objects. In contrast, libraries like ``msgspec`` that validate during decoding have none of these issues. Only a single pass over the decoded data is taken, and the specified output types are created correctly the first time, avoiding the need for additional unnecessary allocations. This benefit also shows up in the memory usage for the same benchmark: .. raw:: html
Here we compare the peak increase in memory usage (RSS) after loading the schemas and data. ``msgspec``'s small library size, schema representation, and in-memory state means it uses a fraction of the memory of other tools. .. _json-benchmark: JSON Serialization ------------------ ``msgspec`` includes its own high performance JSON library, which may be used by itself as a replacement for the standard library's `json.dumps` / `json.loads` functions. Here we compare msgspec's JSON implementation against several other popular Python JSON libraries. - msgspec_ (0.18.5) - orjson_ (3.9.10) - ujson_ (5.9.0) - rapidjson_ (1.13) - simdjson_ (5.0.2) - json_ (standard library) The full benchmark source can be found `here `__. .. raw:: html
In this case ``msgspec structs`` (which measures ``msgspec`` with ``msgspec.Struct`` schemas pre-defined) is the fastest. When used without schemas, ``msgspec`` is on-par with ``orjson`` (the next fastest JSON library). This shows that ``msgspec`` is able to decode JSON faster when a schema is provided. Due to a more efficient in memory representation, JSON decoding AND schema validation with ``msgspec`` than just JSON decoding alone. .. _msgpack-benchmark: MessagePack Serialization ------------------------- Likewise, ``msgspec`` includes its own high performance MessagePack_ library, which may be used by itself without requiring usage of any of msgspec's validation machinery. Here we compare msgspec's MessagePack implementation against several other popular Python MessagePack libraries. - msgspec_ (0.18.5) - msgpack_ (1.0.7) - ormsgpack_ (1.4.1) .. raw:: html
As with the JSON benchmark above, ``msgspec`` with a schema provided (``msgspec structs``) is faster than ``msgspec`` with no schema. In both cases though ``msgspec`` is measurably faster than other Python MessagePack libraries like ``msgpack`` or ``ormsgpack``. JSON Serialization - Large Data ------------------------------- Here we benchmark loading a `large JSON file `__ (~77 MiB) containing information on all the ``noarch`` packages in conda-forge_. We compare the following libraries: - msgspec_ (0.18.5) - orjson_ (3.9.10) - ujson_ (5.9.0) - rapidjson_ (1.13) - simdjson_ (5.0.2) - json_ (standard library) For each library, we measure both the peak increase in memory usage (RSS) and the time to JSON decode the file. The full benchmark source can be found `here `__. **Results (smaller is better):** +---------------------+--------------+------+-----------+------+ | | memory (MiB) | vs. | time (ms) | vs. | +=====================+==============+======+===========+======+ | **msgspec structs** | 67.6 | 1.0x | 176.8 | 1.0x | +---------------------+--------------+------+-----------+------+ | **msgspec** | 218.3 | 3.2x | 630.5 | 3.6x | +---------------------+--------------+------+-----------+------+ | **json** | 295.0 | 4.4x | 868.6 | 4.9x | +---------------------+--------------+------+-----------+------+ | **ujson** | 349.1 | 5.2x | 1087.0 | 6.1x | +---------------------+--------------+------+-----------+------+ | **rapidjson** | 375.0 | 5.6x | 1004.0 | 5.7x | +---------------------+--------------+------+-----------+------+ | **orjson** | 406.3 | 6.0x | 691.7 | 3.9x | +---------------------+--------------+------+-----------+------+ | **simdjson** | 603.2 | 8.9x | 1053.0 | 6.0x | +---------------------+--------------+------+-----------+------+ - ``msgspec`` decoding into :doc:`Struct ` types uses the least amount of memory, and is also the fastest to decode. This makes sense; ``Struct`` types are cheaper to allocate and more memory efficient than ``dict`` types, and for large messages these differences can really add up. - ``msgspec`` decoding without a schema is the second best option for both memory usage and speed. When decoding without a schema, ``msgspec`` makes the assumption that the underlying message probably still has some structure; short dict keys are temporarily cached to be reused later on, rather than reallocated every time. This means that instead of allocating 10,000 copies of the string ``"name"``, only a single copy is allocated and reused. For large messages this can lead to significant memory savings. ``json`` and ``orjson`` also use similar optimizations, but not as effectively. - ``orjson`` and ``simdjson`` use 6-9x more memory than ``msgspec`` in this benchmark. In addition to the reasons above, both of these decoders require copying the original message into a temporary buffer. In this case, the extra copy adds an extra 77 MiB of overhead! .. _struct-benchmark: Structs ------- Here we benchmark common `msgspec.Struct` operations, comparing their performance against other similar libraries. The cases compared are: - Standard Python classes - dataclasses_ - msgspec_ (0.18.5) - attrs_ (23.1.0) - pydantic_ (2.5.2) For each library, the following operations are benchmarked: - Time to define a new class. Many libraries that abstract away class boilerplate add overhead when defining classes, slowing import times for libraries that make use of these classes. - Time to create an instance of that class. - Time to compare two instances for equality (``==`` / ``!=``). - Time to compare two instances for order (``<`` / ``>`` / ``<=`` / ``>=``) The full benchmark source can be found `here `__. **Results (smaller is better):** +----------------------+-------------+-------------+---------------+------------+ | | import (μs) | create (μs) | equality (μs) | order (μs) | +======================+=============+=============+===============+============+ | **msgspec** | 12.51 | 0.09 | 0.02 | 0.03 | +----------------------+-------------+-------------+---------------+------------+ | **standard classes** | 7.88 | 0.35 | 0.08 | 0.16 | +----------------------+-------------+-------------+---------------+------------+ | **attrs** | 483.10 | 0.37 | 0.14 | 1.87 | +----------------------+-------------+-------------+---------------+------------+ | **dataclasses** | 506.09 | 0.36 | 0.14 | 0.16 | +----------------------+-------------+-------------+---------------+------------+ | **pydantic** | 673.47 | 1.54 | 0.60 | N/A | +----------------------+-------------+-------------+---------------+------------+ - Standard Python classes are the fastest to import (any library can only add overhead here). Still, ``msgspec`` isn't *that* much slower, especially compared to other options. - Structs are optimized to be cheap to create, and that shows for the creation benchmark. They're roughly 4x faster than standard classes/``attrs``/``dataclasses``, and 17x faster than ``pydantic``. - For equality comparison, msgspec Structs are roughly 4x to 30x faster than the alternatives. - For order comparison, msgspec Structs are roughly 5x to 60x faster than the alternatives. .. _struct-gc-benchmark: Garbage Collection ------------------ `msgspec.Struct` instances implement several optimizations for reducing garbage collection (GC) pressure and decreasing memory usage. Here we benchmark structs (with and without :ref:`gc=False `) against standard Python classes (with and without `__slots__ `__). For each option we create a large dictionary containing many simple instances of the benchmarked type, then measure: - The amount of time it takes to do a full garbage collection (gc) pass - The total amount of memory used by this data structure The full benchmark source can be found `here `__. **Results (smaller is better):** +-----------------------------------+--------------+-------------------+ | | GC time (ms) | Memory Used (MiB) | +===================================+==============+===================+ | **standard class** | 80.46 | 211.66 | +-----------------------------------+--------------+-------------------+ | **standard class with __slots__** | 80.06 | 120.11 | +-----------------------------------+--------------+-------------------+ | **msgspec struct** | 13.96 | 120.11 | +-----------------------------------+--------------+-------------------+ | **msgspec struct with gc=False** | 1.07 | 104.85 | +-----------------------------------+--------------+-------------------+ - Standard Python classes are the most memory hungry (since all data is stored in an instance dict). They also result in the largest GC pause, as the GC has to traverse the entire outer dict, each class instance, and each instance dict. All that pointer chasing has a cost. - Standard classes with ``__slots__`` are less memory hungry, but still results in an equivalent GC pauses. - `msgspec.Struct` instances have the same memory layout as a class with ``__slots__`` (and thus have the same memory usage), but due to deferred GC tracking a full GC pass completes in a fraction of the time. - `msgspec.Struct` instances with ``gc=False`` have the lowest memory usage (lack of GC reduces memory by 16 bytes per instance). They also have the lowest GC pause (75x faster than standard classes!) since the entire composing dict can be skipped during GC traversal. .. _benchmark-library-size: Library Size ------------ Here we compare the on-disk size of ``msgspec`` and ``pydantic``, its closest equivalent. The full benchmark source can be found `here `__. **Results (smaller is better)** +--------------+---------+------------+-------------+ | | version | size (MiB) | vs. msgspec | +==============+=========+============+=============+ | **msgspec** | 0.18.4 | 0.46 | 1.00x | +--------------+---------+------------+-------------+ | **pydantic** | 2.5.2 | 6.71 | 14.66x | +--------------+---------+------------+-------------+ For applications where dependency size matters, ``msgspec`` is roughly 15x smaller on disk. .. raw:: html .. raw:: html .. _msgspec: https://msgspec.dev .. _msgpack: https://github.com/msgpack/msgpack-python .. _ormsgpack: https://github.com/ormsgpack/ormsgpack .. _MessagePack: https://msgpack.org .. _orjson: https://github.com/ijl/orjson .. _json: https://docs.python.org/3/library/json.html .. _simdjson: https://github.com/TkTech/pysimdjson .. _ujson: https://github.com/ultrajson/ultrajson .. _rapidjson: https://github.com/python-rapidjson/python-rapidjson .. _attrs: https://www.attrs.org/en/stable/ .. _dataclasses: https://docs.python.org/3/library/dataclasses.html .. _pydantic: https://pydantic.dev/docs/validation/latest/get-started/ .. _cattrs: https://catt.rs/en/latest/ .. _mashumaro: https://github.com/Fatal1ty/mashumaro .. _conda-forge: https://conda-forge.org/ python-msgspec-0.22.0/docs/changelog.md000066400000000000000000000743731525673062400200040ustar00rootroot00000000000000# Changelog ## Version 0.22.0 (2026-09-29) - **BREAKING**: Setting `gc=False` on a struct type that has a weakref slot, whether from `weakref=True` or from a base class, now raises `ValueError`. On CPython 3.12 and later the weakref slot is stored in a pre-header in front of the instance, so releasing an instance of a `gc=False` type with that slot corrupted memory, in most builds crashing the interpreter outright. The combination worked on 3.10 and 3.11, and the restriction applies there as well, so that the same class definition behaves the same way on every supported version ({pr}`1207`). - Add `frozendict` support on Python 3.15+ ({pr}`1052`, {pr}`1105`). - Support passing a callable as `decimal_format` to `msgspec.json.Encoder` and `msgspec.msgpack.Encoder` for custom `Decimal` encoding ({pr}`978`). - Support `Literal[True]` and `Literal[False]` types ({pr}`1004`). - Publish CPython 3.15 wheels, including freethreaded builds ({pr}`1152`). - Publish Linux `riscv64` wheels ({pr}`987`). - Support the PyEmscripten (Pyodide) platform ({pr}`1083`). - Fix handling of PEP 695 type parameter syntax (`class Foo[T]`) and of `types.GenericAlias` instances in type annotations ({pr}`962`). - Fix `NameError` when creating a `Struct` with an unquoted forward reference on Python 3.14 ({issue}`1165`). - Fix a crash on incorrect `typing.ClassVar` annotations ({pr}`1097`). - Fix an `AttributeError` when converting to a `Struct` type defined in a namespace without a `__name__` ({pr}`1072`). - Fix overriding an inherited field alias back to the field's own name ({pr}`1133`). - Raise `ValidationError` instead of `SystemError` when `convert` receives an out-of-range `int` for a `float` target ({pr}`1162`). - Report `raw` rather than the misleading `any` as the expected type when a non-`Raw` value is given for a `Raw` field in `convert`, and therefore in `yaml.decode` and `toml.decode` ({pr}`1169`). - Fix an empty expected-type name in validation errors for a required `Raw` field in a `TypedDict`, or a `Raw` field with a `default_factory` on a `dataclass` or an `attrs` class ({pr}`1176`). - Correct the error messages for out-of-range `Meta` length bounds ({pr}`1172`). - Fix a reference leak when decoding msgpack `Ext` payloads ({pr}`1109`). - Fix backing type declaration of `Ext.code` ({pr}`1135`). - Fix a reference leak in `msgspec.to_builtins`, and therefore in `yaml.encode`, for `array_like=True` structs ({pr}`1177`). - Fix reference leaks in `typenode_collect_literal`, `Meta.__rich_repr__`, `ms_decode_bigint`, and `Encoder.__init__` ({pr}`1021`, {pr}`1022`, {pr}`1023`, {pr}`1040`). - Fix `msgspec.inspect.type_info` and `msgspec.json.schema` crashing on mixed-type `Literal`s such as `Literal[1, None]` ({pr}`1080`). - Place `null` last in the `anyOf` generated for optional unions in JSON schemas ({pr}`1028`). - Fix `minItems` in the JSON schema for `array_like=True` structs whose fields are all optional ({pr}`1124`). - Use `[]` or `""` rather than a Python `set` or `bytearray` object as the JSON schema `default` for `Struct` fields with a `set` or `bytearray` `default_factory` ({pr}`1183`). - Preserve JSON Schema metadata and string constraints in `propertyNames` for annotated dictionary key types ({issue}`866`). - Fix `msgspec.json.encode` raising `TypeError` for a `dict` keyed by a plain `enum.Enum` with `str` values ({pr}`1118`). - Fix missing GC traversal and clearing of some module state members ({pr}`1060`). - Ensure an exception is always set on allocation failures ({pr}`1044`). - Fix compilation warnings on Python 3.15 ({pr}`1077`). - Report the leading argument of the `encode` and `decode` functions and methods as positional-only in `inspect.signature` and the rendered docs, matching runtime behavior ({pr}`1116`). - Add overloads to the `Meta` type stub, so type checkers reject mixing `gt` with `ge` or `lt` with `le` ({pr}`700`). - Many type stub improvements and fixes ({pr}`1014`, {pr}`1043`, {pr}`1053`, {pr}`1055`, {pr}`1057`, {pr}`1062`, {pr}`1063`, {pr}`1064`, {pr}`1065`, {pr}`1074`, {pr}`1093`, {pr}`1114`, {pr}`1116`, {pr}`1163`, {pr}`1173`, {pr}`1179`). - Document the differences between `msgspec.structs.asdict`/`astuple` and `msgspec.to_builtins` ({pr}`1025`). - Document that `omit_defaults` ignores fields with a custom `default_factory` ({pr}`1076`). - Fix the `msgspec.json.decode` docstring to say `dec_hook` should raise `NotImplementedError` for unsupported types, not `TypeError` ({issue}`774`). - msgspec moved to the [msgspec GitHub organization](https://github.com/msgspec/msgspec); documentation now lives at [msgspec.dev](https://msgspec.dev) (repository references updated in {pr}`1045`). ## Version 0.21.1 (2026-04-13) - Fix `ValidationError` and `DecodeError` raised in `dec_hook` being incorrectly wrapped in another `ValidationError` ({pr}`1013`). - Fix a potential `NULL` dereference in `structmeta_get_module_ns` ({pr}`1016`). - Fix a reference leak in `ms_passes_big_int_constraints` ({pr}`1017`). - Fix missing `ref_template` parameter in `msgspec.json.schema` type stub ({pr}`1002`). - Clarify `order='deterministic'` encoder docstrings ({pr}`1011`). - Add a porting guide for users migrating from orjson ({pr}`1007`). ## Version 0.21.0 (2026-04-08) - Fix a segfault on Python 3.13+ that could occur when creating structs that contained a `__dict__`, instead of only using `__slots__` ({pr}`960`). - Improve type annotations for `msgspec.UNSET` ({pr}`975`). - Fix hashing of decoded tuples on Python 3.14 ({pr}`980`). - Add `ref_template` arg to `msgspec.json.schema` ({pr}`983`). - Add missing `libm` linkage to some architectures ({pr}`993`). - Fix memory leak when decoding sets ({pr}`991`). - Add `uniqueItems` annotation to `set`/`frozenset` JSON schemas ({pr}`984`). - **BREAKING**: Call `__post_init__` from `msgspec.structs.replace`/`copy.replace` ({pr}`1000`). ## Version 0.20.0 (2025-11-23) - Support Python 3.14, including freethreaded mode ({pr}`852`, {pr}`877`). - Expose the `StructMeta` metaclass ({pr}`890`, {pr}`927`, {pr}`928`, {pr}`940`, {pr}`945`). - Add `msgspec.inspect.is_struct` and `msgspec.inspect.is_struct_type` functions for checking whether an object is a `msgspec.Struct`-like instance or class ({pr}`950`). - Support Windows `arm64` builds ({pr}`943`). - Enable ThinLTO on macOS `aarch64` builds ({pr}`937`). - Fix leaks of `re.Pattern` objects when using `pattern` constraints of `msgspec.Meta` ({pr}`899`). - Fixed `memoryview` support for `msgspec.msgpack` ({pr}`836`). - Fix crash when `typing.TypedDict` contains incorrect metadata ({pr}`853`, {pr}`947`). - Add `setuptools-scm` as a build dependency instead of vendoring `versioneer` ({pr}`905`). - Remove support for legacy packaging builds ({pr}`907`). - Improved the developer experience by adding the `just` command runner and Dev Container support ({pr}`918`). ## Version 0.19.0 (2024-12-27) - Improve JSON encoding performance by up to 40% ({pr}`647`). - Ensure `tuple` and `frozenset` default values are treated identically whether specified by value or `default_factory` ({pr}`653`). - Fix memory leak of `match_args` in `StructConfig` object ({pr}`684`). - Fix memory leak in `Raw.copy()` ({pr}`709`). - Update `decode` signatures for PEP 688 ({pr}`740`). - Generate `__replace__` method on `Struct` types, for use with `copy.replace` ({pr}`747`). - Fix incorrect decoding of certain > 64 bit integers ({pr}`751`). - Call `__post_init__` when converting from an object to a Struct ({pr}`752`). - **BREAKING**: Expand buffer when `encode_into` is passed a buffer smaller than `offset` ({pr}`753`). - Support `Raw` objects as inputs to `convert` ({pr}`754`). - Error nicely when a dataclass *type* (instead of an *instance*) is passed to `encode` ({pr}`755`). - Drop support for Python 3.8 ({pr}`756`, {pr}`763`). - Add support for Python 3.13 ({pr}`711`). - Remove deprecated `from_builtins` ({pr}`761`). - Support encoding any `Enum` type whose `.value` is a supported type ({pr}`757`). - Don't fail eagerly when processing generic types with unsupported `__parameters__` ({pr}`772`). - Use `eval_type_backport` to backport type annotations to Python 3.9 ({pr}`773`). ## Version 0.18.6 (2024-01-21) - Support coercing integral floats to ints when `strict=False` ({pr}`619`). - Preserve leading `_` when renaming fields to camel or pascal case ({pr}`620`). - Support zero-copy decoding binary fields to a `memoryview` ({pr}`624`). - Fix a bug when inheriting from the same `Generic` base class multiple times ({pr}`626`). - Add an `order` option to all encoders for enforcing deterministic/sorted ordering when encoding. This can help provide a more consistent or human readable output ({pr}`627`). - Support inheriting from any slots-class when defining a new `Struct` type with `gc=False` ({pr}`635`). - Automatically infer the input field naming convention when converting non-dict mappings or arbitrary objects to `Struct` types in `msgspec.convert` ({pr}`636`). ## Version 0.18.5 (2023-12-12) - Support unhashable `Annotated` metadata in `msgspec.inspect.type_info` ({pr}`566`). - Fix bug preventing decoding dataclasses/attrs types with default values and `slots=True, frozen=True` ({pr}`569`). - Support passing parametrized generic struct types to `msgspec.structs.fields` ({pr}`571`). - Validate `str` constraints on dict keys when decoding msgpack ({pr}`577`). - Support `UUID` subclasses as inputs to `msgspec.convert` ({pr}`592`). - Call `__eq__` from generated `__ne__` if user defines manual `__eq__` method on a `Struct` type ({pr}`593`). - Include the `Struct` type in the generated hash ({pr}`595`). - Add a `cache_hash` struct option ({pr}`596`). - Fix a bug around caching of dataclass type info when dealing with subclasses of dataclasses ({pr}`599`). - Add `msgspec.structs.force_setattr` ({pr}`600`). - Support custom dict key types in JSON encoder and decoder ({pr}`602`). - Include `dict` key constraints in generated JSON schema via the `propertyNames` field ({pr}`604`). - Add a `schema_hook` for generating JSON schemas for custom types ({pr}`605`). - Add support for Python 3.12's `type` aliases ({pr}`606`). ## Version 0.18.4 (2023-10-04) - Resolve an issue leading to periodic segfaults when importing `msgspec` on CPython 3.12 ({pr}`561`) ## Version 0.18.3 (2023-10-03) - Improve type annotation for `Struct.__rich_repr__` ({pr}`557`) - Add pre-built wheels for Python 3.12 ({pr}`558`) ## Version 0.18.2 (2023-08-26) - Support `Enum._missing_` hooks for handling unknown enum values ({pr}`532`). - Fix JSON encoding of `datetime.datetime` objects with `zoneinfo.ZoneInfo` timezone components ({pr}`534`). - Add support for `attrs` validators ({pr}`538`). - Relax datetime/time parsing format to allow some RFC3339 extensions from ISO8601 ({pr}`539`). ## Version 0.18.1 (2023-08-16) - Support custom `builtin_types` in `msgspec.to_builtins` ({pr}`517`). - Try `getattr` before `getitem` when converting with `from_attributes=True` ({pr}`519`). - More efficient module state access in top-level functions ({pr}`521`). ## Version 0.18.0 (2023-08-10) - Add a new `msgspec.json.Decoder.decode_lines` method for decoding newline-delimited JSON into a list of values ({pr}`485`). - Support for decoding UUIDs from binary values ({pr}`499`). - Support for encoding UUIDs in alternate formats ({pr}`499`). - Overhaul how dataclasses are encoded to support more dataclass-like objects ({pr}`501`). - Encode all declared fields on a dataclass ({pr}`501`). - Support encoding `edgedb.Object` instances as dataclass-like objects ({pr}`501`). - Improve performance when json decoding `float` values ({pr}`510`). - Support for JSON encoding dicts with `float` keys ({pr}`510`). - Support for JSON decoding dicts with `float` keys ({pr}`510`). - Add `float_hook` to `msgspec.json.Decoder` to support changing the default for how JSON floats are decoded ({pr}`511`). ## Version 0.17.0 (2023-07-11) - Ensure `None` may be explicitly passed to `defstruct` for `module`/`namespace`/`bases` ({pr}`445`). - Support decoding `datetime.datetime` values from `int`/`float` values (interpreted as seconds since the Unix epoch) when `strict=False` ({pr}`452`). - Support subclasses of collection types (`list`, `dict`, ...) as inputs to `convert` ({pr}`453`). - Support `str` subclasses as keys in `to_builtins` and all protocol `encode` methods ({pr}`454`). - Improved performance when JSON encoding `decimal.Decimal` values ({pr}`455`). - Improved performance when JSON encoding `int`/`float` values ({pr}`458`). - Improved performance when JSON encoding `str` values ({pr}`459`). - Wrap errors in `dec_hook` with a `ValidationError` ({pr}`460`). - Support decoding `decimal.Decimal` values from numeric values ({pr}`463`) - Support encoding `decimal.Decimal` values as numeric values ({pr}`465`). - Support converting `decimal.Decimal` values to `float` in `convert` ({pr}`466`). - Preliminary support for CPython 3.12 beta releases ({pr}`467`). - Support decoding integers that don't fit into an `int64`/`uint64` ({pr}`469`). - Add a new optional `__post_init__` method for `Struct` types ({pr}`470`). - Support decoding `0`/`1` into `bool` types when `strict=False` ({pr}`471`). - Wrap errors raised in `__post_init__`/`__attrs_post_init__` in a `ValidationError` when decoding ({pr}`472`). - Add native support for encoding/decoding `datetime.timedelta` types ({pr}`475`). - Add a new `msgspec.json.Encoder.encode_lines` method for encoding an iterable of values as newline-delimited JSON ({pr}`479`). ## Version 0.16.0 (2023-06-12) - Deprecate `msgspec.from_builtins` in favor of `msgspec.convert`. The new `convert` function provides a superset of the functionality available in the old `from_builtins` function ({pr}`431`). - Add a `from_attributes` argument to `msgspec.convert` for allowing conversion between object types with matching attribute names. One use case for this is converting ORM objects to `Struct` or `dataclasses` types ({pr}`419`). - Support passing generic `Mapping` objects as inputs to `msgspec.convert`. These may be coerced to `dict`/`Struct`/`dataclasses`/`attrs` types ({pr}`427`). - Add a new `strict` keyword argument to all `decode` functions, `Decoder` classes, as well as `msgspec.convert`. This defaults to `True`, setting it to false enables a wider set of coercion rules (e.g. coercing a `str` input to an `int`). See "Strict" vs "Lax" mode for more information ({pr}`434`). - Support all supported types as inputs to `msgspec.convert` ({pr}`431`, {pr}`418`). - Passthrough input unchanged when coercing to `typing.Any` type in `msgspec.convert` ({pr}`435`). - Support parametrizing `Decoder` types at runtime ({pr}`415`). - Support encoding subclasses of `UUID` ({pr}`429`). ## Version 0.15.1 (2023-05-19) - Fix a reference counting bug introduced in 0.15.0 when decoding naive (no timezone) `datetime`/`time` objects in both the `msgpack` and `json` decoders ({pr}`409`). - Work around an upstream bug in CPython to properly support `typing.Required`/`typing.NotRequired` in `typing.TypedDict` when `__future__.annotations` is enabled ({pr}`410`). ## Version 0.15.0 (2023-05-10) - Add support for Generic `Struct` types ({pr}`386`, {pr}`393`). - Add support for Generic `dataclasses` and `attrs` types ({pr}`396`). - Add support for Generic `typing.TypedDict` and `typing.NamedTuple` types ({pr}`398`). - **BREAKING**: No longer normalize timezones to UTC when decoding `datetime` objects from JSON ({pr}`391`). - Support decoding unhyphenated UUIDs ({pr}`392`). - A few type annotation fixups ({pr}`383`, {pr}`387`). - Dedent docstrings for descriptions when generating JSON schemas ({pr}`397`). - Use a variant of `__qualname__` when auto-generating Struct tags rather than `__name__` ({pr}`399`). - Fix bug when handling `typing.Literal` types containing a literal `None` ({pr}`400`). - Make all `Encoder`/`Decoder` methods threadsafe ({pr}`402`). - **BREAKING**: Drop the `write_buffer_size` kwarg to `Encoder` ({pr}`402`). ## Version 0.14.2 (2023-04-19) - Remove `__del__` trashcan usage for structs with `gc=False` ({pr}`369`). - Support overriding `__setattr__` in Struct types ({pr}`376`). - Support encoding large integers in JSON ({pr}`378`). - Fix a memory leak when msgpack decoding variable length tuples with more than 16 elements ({pr}`380`). - Remove JSON compatibility checks when constructing a `msgspec.json.Decoder`. Trying to decode messages into types that JSON doesn't support will now error at decode time, rather than when the decoder is constructed ({pr}`381`). ## Version 0.14.1 (2023-04-07) - Further optimize decoding of JSON arrays into lists ({pr}`363`). - Fix a bug preventing using structs configured with `dict=True` on Python 3.11 ({pr}`365`). - Avoid preallocating large lists/tuples in the msgpack decoder ({pr}`367`). ## Version 0.14.0 (2023-04-02) - Support encoding and decoding `attrs` types ({pr}`323`). - Add `repr_omit_defaults` configuration option for omitting struct default values in the `repr` ({pr}`322`). - Expose a struct's configuration through a `__struct_config__` attribute ({pr}`328`). - Add `msgspec.structs.fields` utility function for inspecting the fields configured on a Struct ({pr}`330`). - Add a `dict` configuration option for adding a `__dict__` attribute to a Struct ({pr}`331`). - Allow non-struct mixins to be used with struct types ({pr}`332`). - Fix a bug when defining both `lt` and `gt` constraints on an integer type ({pr}`335`). - Fix a bug supporting fields defined with `msgspec.field()` with no arguments ({pr}`343`). - Allow arbitrary input types to `msgspec.from_builtins` ({pr}`346`). - Support decoding into subclasses of `int` & `bytes` in `msgspec.from_builtins` ({pr}`346`). - Add `msgspec.UNSET` and `msgspec.UnsetType` for tracking unset fields. See the the docs for more information ({pr}`350`). - **BREAKING**: In the unlikely event you were using the previous `msgspec.UNSET` singleton to explicitly indicate no default value on struct types, you should now make use of `msgspec.NODEFAULT` instead ({pr}`350`). - Improve struct type annotations now that `mypy` supports `typing.dataclass_transform` ({pr}`352`). - Support `typing.Final` annotations for indicating that an object field should be treated as immutable ({pr}`354`). - Add a `name` keyword option to `msgspec.field` for renaming a single field ({pr}`356`). - **BREAKING**: The rules around class inheritance and a struct's `rename` option have changed. See {pr}`356` for more information. ## Version 0.13.1 (2023-02-10) - Fix a memory leak in the JSON decoder introduced in 0.13.0, caused by a reference counting bug when decoding into `Struct` types ({pr}`312`). ## Version 0.13.0 (2023-02-08) - Add `to_builtins` function for converting messages composed of any supported type to ones composed of only simple builtin types commonly supported by Python serialization libraries ({pr}`258`). - Add `from_builtins` function for converting and validating messages composed of simple builtin types to ones composed of any type msgspec supports ({pr}`266`, {pr}`302`). - Add `msgspec.yaml` module for encoding/decoding YAML ({pr}`267`). - Add `msgspec.toml` module for encoding/decoding TOML ({pr}`268`). - Add `msgspec.structs.replace` function for creating a copy of an existing `Struct` with some changes applied ({pr}`262`). - Add `msgspec.structs.asdict` and `msgspec.structs.astuple` functions for converting a struct instance to a `dict` or `tuple` respectively ({pr}`300`). - Support arbitrarily nested `typing.NewType`/`typing.Annotated` types ({pr}`272`). - Improve error message for invalid keyword arguments passed to `Struct.__init__` ({pr}`273`). - Support `default_factory` configuration for `Struct` fields ({pr}`274`). - **BREAKING**: With the exception of empty builtin collections (`[]`, `{}`, `set()`, `bytearray()`), mutable default values in Struct types are no longer deepcopied when used. If a different mutable default value is needed, please configure a `default_factory` instead ({pr}`274`). - Improve performance of creating Structs with default parameters ({pr}`274`). - Support `typing.ClassVar` annotations of `Struct` types ({pr}`281`). - Support encoding/decoding `decimal.Decimal` types ({pr}`288`). - Support "abstract" type annotations like `collections.abc.MutableMapping`/`typing.MutableMapping` in decoders ({pr}`290`). - Support any string-like or int-like type as a `dict` key when encoding or decoding JSON ({pr}`292`). - Improved performance encoding large collections in JSON and MessagePack encoders ({pr}`294`, {pr}`298`). ## Version 0.12.0 (2023-01-05) - Support encoding `set` and `frozenset` subclasses ({pr}`249`). - Support encoding/decoding `typing.NewType` types ({pr}`251`). - Allow creating a `msgspec.Raw` object from a `str` ({pr}`252`). - Add new experimental `msgspec.inspect` module for inspecting type annotations. This is intended to be used for building downstream tooling based on msgspec-compatible types. See the docs for more information ({pr}`253`). - Add new `extra` field to `msgspec.Meta`, for storing arbitrary user-defined metadata ({pr}`255`). - Improved performance for JSON encoding strings ({pr}`256`). ## Version 0.11.0 (2022-12-19) - Improve performance of constructors for `Struct` types when using keyword arguments ({pr}`237`). - Support `constraints` on dict keys for JSON ({pr}`239`). - Add support for keyword-only arguments in `Struct` types, matching the behavior of `kw_only` for `dataclasses` ({pr}`242`). - **BREAKING**: Change the parameter ordering rules used by `Struct` types to match the behavior of `dataclasses`. For most users this change shouldn't break anything. However, if your struct definitions have required fields after optional fields, you'll now get an error on import. This error can be fixed by either: - Reordering your fields so all required fields are before all optional fields - Using keyword-only parameters (by passing the `kw_only=True` option). See field ordering for more information ({pr}`242`). - Support encoding/decoding dictionaries with integer keys for JSON ({pr}`243`). ## Version 0.10.1 (2022-12-08) - Ignore attributes with leading underscores (`"_"`) when encoding `dataclasses` ({pr}`234`) ## Version 0.10.0 (2022-12-07) - Add `forbid_unknown_fields` configuration option to `Struct` types ({pr}`210`) - **BREAKING**: Encode all `enum` types by value, rather than name ({pr}`211`) - Fix a bug in the JSON encoder when base64 encoding binary objects ({pr}`217`) - Add support for encoding/decoding `dataclasses` ({pr}`218`) - Add support for encoding/decoding `datetime.date` objects ({pr}`221`) - Add support for encoding/decoding `uuid.UUID` objects ({pr}`222`) - **BREAKING**: support encoding/decoding `datetime.datetime` values without timezones by default ({pr}`224`). - Add a `tz` `constraint` to require aware or naive datetime/time objects when decoding ({pr}`224`). - Add support for encoding/decoding `datetime.time` objects ({pr}`225`) - Add a `msgspec.json.format` utility for efficiently pretty-printing already encoded JSON documents ({pr}`226`). - Support decoding JSON from strings instead of just bytes-like objects ({pr}`229`) ## Version 0.9.1 (2022-10-27) - Enable Python 3.11 builds ({pr}`205`) - Support greater than microsecond resolution when parsing JSON timestamps ({pr}`201`) - Work around a limitation in mypy for typed decoders ({pr}`191`) ## Version 0.9.0 (2022-09-13) - Support for `constraints` during validation. For example, this allows ensuring a field is an integer >= 0. ({pr}`176`) - New utilities for generating JSON Schema from type definitions ({pr}`181`) - Support for pretty printing using `rich` ({pr}`183`) - Improve integer encoding performance ({pr}`170`) - Builtin support for renaming fields using kebab-case ({pr}`175`) - Support for passing a mapping when renaming fields ({pr}`185`) ## Version 0.8.0 (2022-08-01) - Support integer tag values when using tagged unions ({pr}`135`). - Support decoding into `typing.TypedDict` types ({pr}`142`). - Support encoding/decoding `typing.NamedTuple` types ({pr}`161`). - Test against CPython 3.11 prelease builds ({pr}`146`). - Add `ValidationError` (a subclass of `DecodeError`) to allow differentiating between errors due to a message not matching the schema from those due to the message being invalid JSON ({pr}`155`). - Support encoding subclasses of `list`/`dict` ({pr}`160`). - Fix a bug preventing decoding custom types wrapped in a `typing.Optional` ({pr}`162`). ## Version 0.7.1 (2022-06-27) - Further reduce the size of packaged wheels ({pr}`130`). - Add `weakref` support for `Struct` types through a new `weakref` configuration option ({pr}`131`). - Fix a couple unlikely (but possible) bugs in the deallocation routine for Struct types ({pr}`131`). ## Version 0.7.0 (2022-06-20) - Dramatically speedup JSON string decoding, up to 2x speedup in some cases ({pr}`118`). - Adds a cache for decoding short (< 32 character) ASCII dict keys. This results in up to a 40% speedup when decoding many dicts with common keys using an untyped decoder. It's still recommended to define `Struct` types when your messages have a common structure, but in cases where no type is provided decoding is now much more performant ({pr}`120`, {pr}`121`). - Adds `order` and `eq` configuration options for `Struct` types, mirroring the `dataclasses` options of the same name. Order comparisons for Struct types are very performant, roughly 10x to 70x faster than alternative libraries ({pr}`122`). - Speedup `Struct` decoding for both JSON and MessagePack, on average 20% faster ({pr}`119`). - Various additional performance improvements, mostly to the JSON implementation ({pr}`100`, {pr}`101`, {pr}`102`). - Add `defstruct` method for dynamically defining new `Struct` types at runtime ({pr}`105`). - Fix ARM support and publish ARM wheels for Linux and Mac ({pr}`104`). - Reduce published wheel sizes by stripping debug symbols ({pr}`113`). - Fix a memory leak in `Struct.__reduce__` ({pr}`117`). - **BREAKING**: Rename `nogc` struct option to `gc`. To disable GC on a Struct instance you now want to specify `gc=False` instead of `nogc=True` ({pr}`124`). ## Version 0.6.0 (2022-04-06) - Add a new `msgspec.Raw` type for delayed decoding of message fields / serializing already encoded fields ({pr}`92`). - Add `omit_defaults` option to `Struct` types. If enabled, fields containing their respective default value will be omitted from serialized message. This improves both encode and decode performance ({pr}`94`). - Add `rename` option to `Struct` types for altering the field names used for encoding. A major use of this is supporting `camelCase` JSON field names, while letting Python code use the more standard `snake_case` field names ({pr}`98`). - Improve performance of `nogc=True` structs. GC is now avoided in more cases, and `nogc=True` structs use 16 fewer bytes per instance. Also added a benchmark for how `msgspec` can interact with application GC usage ({pr}`93`). - Cache creation of tagged union lookup tables, reducing memory usage for applications making heavy use of tagged unions ({pr}`91`). - Support encoding and decoding `frozenset` instances ({pr}`95`). - A smattering of other performance improvements. ## Version 0.5.0 (2022-03-09) - Support tagged unions for encoding/decoding a `Union` of `msgspec.Struct` types ({pr}`83`). - Further improve encoding performance of `enum.Enum` instances by 20-30% ({pr}`84`). - Reduce overhead of calling `msgspec.json.decode`/`msgspec.msgpack.decode` with `type=SomeStructType`. It's still faster to create a `Decoder` once and call `decoder.decode` multiple times, but for struct types the overhead of calling the top-level function is decreased significantly ({pr}`77`, {pr}`88`). - **BREAKING**: Rename the Struct option `asarray` to `array_like` ({pr}`85`). ## Version 0.4.2 (2022-02-28) - Support `typing.Literal` string types as dict keys in JSON ({pr}`78`). - Support Python 3.10 style unions (for example, `int | float | None`) ({pr}`75`). - Publish Python 3.10 wheels ({pr}`80`). ## Version 0.4.1 (2022-02-23) - Optimize decoding of `Enum` types, on average ~10x faster ({pr}`69`). - Optimize decoding of `IntEnum` types, on average ~12x faster ({pr}`68`). - Support decoding `typing.Literal` types ({pr}`71`). - Add `nogc` option for `Struct` types, disabling the cyclic garbage collector for their instances ({pr}`72`). ## Version 0.4.0 (2022-02-08) - Moved MessagePack support to the `msgspec.msgpack` submodule ({pr}`56`). - New JSON support available in `msgspec.json` ({pr}`56`). - Improved error message generation to provide full path to the mistyped values ({pr}`56`). - Renamed the `immutable` kwarg in `msgspec.Struct` to `frozen` to better match python conventions ({pr}`60`). - Renamed `EncodingError` to `EncodeError`/`DecodingError` to `DecodeError` to better match python conventions ({pr}`61`). - Improved `pyright` support, allowing more errors to be statically caught by their type checker ({pr}`60`). - Adds support for Python 3.10 pattern matching on `msgspec.Struct` types ({pr}`53`). - Adds support for decoding into `typing.Union` types (with a few restrictions) ({pr}`54`). - General performance improvements across all encoders/decoders. ## Version 0.3.2 (2021-07-23) - Faster float encoding and decoding ({pr}`47`). - General micro-optimizations for MessagePack encode/decode. This is most visible for large messages ({pr}`48`, {pr}`50`). ## Version 0.3.1 (2021-07-12) - Use a freelist for small structs to improve struct allocation time ({pr}`44`). - Small performance improvements for struct serialization ({pr}`45`). ## Version 0.3.0 (2021-07-07) - Add `Encoder.encode_into` api, for encoding into an existing buffer without copying ({pr}`34`). - Add support for encoding/decoding MessagePack extensions ({pr}`31`). - Add support for encoding/decoding `datetime` objects ({pr}`36`). - Add support for encoding/decoding custom objects without relying on MessagePack extensions ({pr}`32`, {pr}`33`). - Add support for marking `Struct` types as hashable ({pr}`39`). - Add support for serializing `Struct` types as MessagePack `array` objects rather than `map` objects ({pr}`39`). - Several performance improvements. On average 50% faster encoding and 30% faster decoding. ## Version 0.2.0 (2021-02-25) - Add `default` callback to `encode`/`Encoder` ({pr}`21`). - Fix bug in `Encoder` dealloc ({pr}`21`). ## Version 0.1.0 (2021-02-23) - Initial Release python-msgspec-0.22.0/docs/conf.py000066400000000000000000000073131525673062400170200ustar00rootroot00000000000000# We want to document both the UNSET singleton, and the UnsetType class, but we # don't want them to have the same docstring. I couldn't find an easy way to # do this in sphinx. For now, we patch the UnsetType object when building types # to override the docstring handling. try: import msgspec class UnsetType: """The type of `UNSET`. See Also -------- UNSET """ msgspec.UnsetType = UnsetType except ImportError: pass project = "msgspec" copyright = "Jim Crist-Harif" author = "Jim Crist-Harif" GITHUB_LOGO = """ """.strip() html_theme = "furo" html_title = "" templates_path = ["_templates"] html_static_path = ["_static"] html_css_files = ["custom.css"] pygments_style = "default" _link_color_light = "#024bb0" _link_color_dark = "#5192d2" html_theme_options = { "light_logo": "msgspec-logo-light.svg", "dark_logo": "msgspec-logo-dark.svg", "light_css_variables": { "color-brand-primary": "black", "color-brand-content": _link_color_light, "color-foreground-muted": "#808080", "color-highlight-on-target": "inherit", "color-highlighted-background": "#ffffcc", "color-sidebar-link-text": "black", "color-sidebar-link-text--top-level": "black", "color-link": _link_color_light, "color-link--hover": _link_color_light, "color-link-underline": "transparent", "color-link-underline--hover": _link_color_light, }, "dark_css_variables": { "color-brand-primary": "#ffffff", "color-brand-content": _link_color_dark, "color-highlight-on-target": "inherit", "color-highlighted-background": "#333300", "color-sidebar-link-text": "#ffffffcc", "color-sidebar-link-text--top-level": "#ffffffcc", "color-link": _link_color_dark, "color-link--hover": _link_color_dark, "color-link-underline": "transparent", "color-link-underline--hover": _link_color_dark, }, "sidebar_hide_name": True, "footer_icons": [ { "name": "GitHub", "url": "https://github.com/msgspec/msgspec", "html": GITHUB_LOGO, "class": "", }, ], } extensions = [ "sphinx.ext.autodoc", "sphinx.ext.napoleon", "sphinx.ext.extlinks", "sphinx.ext.intersphinx", "sphinx_copybutton", "sphinx_design", "IPython.sphinxext.ipython_console_highlighting", "myst_parser", ] intersphinx_mapping = { "python": ("https://docs.python.org/3", None), "attrs": ("https://www.attrs.org/en/stable/", None), } autodoc_typehints = "none" napoleon_numpy_docstring = True napoleon_google_docstring = False napoleon_use_rtype = False napoleon_custom_sections = [("Configuration", "params_style")] default_role = "obj" extlinks = { "issue": ("https://github.com/msgspec/msgspec/issues/%s", "Issue #%s"), "pr": ("https://github.com/msgspec/msgspec/pull/%s", "PR #%s"), } copybutton_prompt_text = r">>> |\.\.\. |\$ |In \[\d*\]: | {2,5}\.\.\.: " copybutton_prompt_is_regexp = True python-msgspec-0.22.0/docs/constraints.rst000066400000000000000000000170101525673062400206150ustar00rootroot00000000000000Constraints =========== When using :ref:`typed-decoding` ``msgspec`` will ensure decoded messages match the specified types. For example, to decode a list of integers from JSON: .. code-block:: python >>> import msgspec >>> msgspec.json.decode(b"[1, 2, 3]", type=list[int]) [1, 2, 3] >>> msgspec.json.decode(b'[1, 2, "oops"]', type=list[int]) Traceback (most recent call last): File "", line 1, in msgspec.ValidationError: Expected `int`, got `str` - at `$[2]` Often this is sufficient, but sometimes you also need to impose constraints on the *values* (rather than the *types*) found in the message. Constraints in ``msgspec`` are specified by wrapping a type with `typing.Annotated`, and adding a `msgspec.Meta` annotation. For example, to constrain the list to positive integers (``> 0``), you'd make use of the ``gt`` (greater-than) constraint: .. code-block:: python >>> from typing import Annotated >>> PositiveInt = Annotated[int, msgspec.Meta(gt=0)] >>> msgspec.json.decode(b'[1, 2, 3]', type=list[PositiveInt]) [1, 2, 3] >>> msgspec.json.decode(b'[1, 2, -1]', type=list[PositiveInt]) Traceback (most recent call last): File "", line 1, in msgspec.ValidationError: Expected `int` >= 1 - at `$[2]` Constraints can be combined to enforce complex requirements. Here's a more complete example enforcing the following constraints on a ``User`` struct: - ``name`` is a ``str`` with ``1 <= length <= 32`` matching the regular expression ``"^[a-z_][a-z0-9_-]*$"``. - ``groups`` is a ``set`` of at most 16 strings, each with the same constraints as ``name`` above, defaulting to the empty ``set``. - ``cpu_limit`` is a ``float`` with a value ``>= 0.1`` and ``<= 8``, defaulting to 1. - ``mem_limit`` is an ``int`` with a value ``>= 256`` and ``<= 8192``, defaulting to 1024. .. code-block:: python >>> from typing import Annotated >>> from msgspec import Struct, Meta >>> UnixName = Annotated[ ... str, Meta(min_length=1, max_length=32, pattern="^[a-z_][a-z0-9_-]*$") ... ] >>> class User(Struct): ... name: UnixName ... groups: Annotated[set[UnixName], Meta(max_length=16)] = set() ... cpu_limit: Annotated[float, Meta(ge=0.1, le=8)] = 1 ... mem_limit: Annotated[int, Meta(ge=256, le=8192)] = 1024 As shown above, ``Annotated`` types can applied inline, or used to create type aliases and then reused elsewhere (as done with ``UnixName``). The following constraints are supported: Numeric Constraints ------------------- These constraints are valid on `int` or `float` types: - ``ge``: The value must be greater than or equal to ``ge``. - ``gt``: The value must be greater than ``gt``. - ``le``: The value must be less than or equal to ``le``. - ``lt``: The value must be less than ``lt``. - ``multiple_of``: The value must be a multiple of ``multiple_of``. .. code-block:: python >>> import msgspec >>> from typing import Annotated >>> msgspec.json.decode(b'-1', type=Annotated[int, msgspec.Meta(ge=0)]) Traceback (most recent call last): File "", line 1, in msgspec.ValidationError: Expected `int` >= 0 .. warning:: While ``multiple_of`` works on ``float`` types, we don't recommend specifying *non-integral* ``multiple_of`` constraints, as they may be erroneously marked as invalid due to floating point precision issues. For example, annotating a ``float`` type with ``multiple_of=10`` is fine, but ``multiple_of=0.1`` may lead to issues. See `this GitHub issue `_ for more details. String Constraints ------------------ These constraints are valid on `str` types: - ``min_length``: The minimum valid length, inclusive. - ``max_length``: The maximum valid length, inclusive. - ``pattern``: A regular expression pattern that the value must match. Note that patterns are treated as *unanchored*. This means that the pattern "es" matches not just "es" but also "expression". If required, you must explicitly anchor the pattern by adding a "^" prefix and "$" suffix. For example, the pattern "^es$" only matches the string "es" .. code-block:: python >>> import msgspec >>> from typing import Annotated >>> msgspec.json.decode( ... b'"invalid username"', ... type=Annotated[str, msgspec.Meta(pattern="^[a-z0-9_]*$")] ... ) Traceback (most recent call last): File "", line 1, in msgspec.ValidationError: Expected `str` matching regex '^[a-z0-9_]*$' .. _datetime-constraints: Datetime Constraints -------------------- These constraints are valid on `datetime.datetime` and `datetime.time` types: - ``tz``: Whether the annotated type is required to be timezone-aware_. Set to ``True`` to require timezone-aware values, or ``False`` to require timezone-naive values. The default is ``None``, which accepts either timezone-aware or timezone-naive values. .. code-block:: python >>> import msgspec >>> from datetime import datetime >>> from typing import Annotated >>> msgspec.json.decode( ... b'"2022-04-02T18:18:10"', ... type=Annotated[datetime, msgspec.Meta(tz=True)] # require timezone aware ... ) Traceback (most recent call last): File "", line 1, in msgspec.ValidationError: Expected `datetime` with a timezone component >>> msgspec.json.decode( ... b'"2022-04-02T18:18:10-06:00"', ... type=Annotated[datetime, msgspec.Meta(tz=False)] # require timezone naive ... ) Traceback (most recent call last): File "", line 1, in msgspec.ValidationError: Expected `datetime` with no timezone component Bytes Constraints ----------------- These constraints are valid on `bytes` and `bytearray` types: - ``min_length``: The minimum valid length, inclusive. - ``max_length``: The maximum valid length, inclusive. .. code-block:: python >>> import msgspec >>> from typing import Annotated >>> msgspec.json.decode( ... b'"ZXhhbXBsZQ=="', ... type=Annotated[bytes, msgspec.Meta(min_length=10)] ... ) Traceback (most recent call last): File "", line 1, in msgspec.ValidationError: Expected `bytes` of length >= 10 Sequence Constraints -------------------- These constraints are valid on `list`, `tuple`, `set`, and `frozenset` types: - ``min_length``: The minimum valid length, inclusive. - ``max_length``: The maximum valid length, inclusive. .. code-block:: python >>> import msgspec >>> from typing import Annotated >>> msgspec.json.decode( ... b'[1, 2, 3, 4]', ... type=Annotated[list[int], msgspec.Meta(max_length=3)] ... ) Traceback (most recent call last): File "", line 1, in msgspec.ValidationError: Expected `array` of length <= 3 Mapping Constraints ------------------- These constraints are valid on `dict` types: - ``min_length``: The minimum valid length, inclusive. - ``max_length``: The maximum valid length, inclusive. .. code-block:: python >>> import msgspec >>> from typing import Annotated >>> msgspec.json.decode( ... b'{"a": 1, "b": 2, "c": 3, "d": 4}', ... type=Annotated[dict[str, int], msgspec.Meta(max_length=3)] ... ) Traceback (most recent call last): File "", line 1, in msgspec.ValidationError: Expected `object` of length <= 3 .. _timezone-aware: https://docs.python.org/3/library/datetime.html#aware-and-naive-objects python-msgspec-0.22.0/docs/converters.rst000066400000000000000000000114741525673062400204500ustar00rootroot00000000000000Converters ========== .. currentmodule:: msgspec ``msgspec`` provides builtin support for several common protocols (``json``, ``msgpack``, ``yaml``, and ``toml``). Support for additional protocols may be added by combining a serialization library with msgspec's *converter functions*: `msgspec.to_builtins` and `msgspec.convert`. - `msgspec.to_builtins`: takes an object composed of any :doc:`supported type ` and converts it into one composed of only simple builtin types typically supported by Python serialization libraries. - `msgspec.convert`: takes an object composed of any :doc:`supported type `, and converts it to match a specified schema (validating along the way). If the conversion fails due to a schema mismatch, a nice error message is raised. These functions are designed to be paired with a Python serialization library as pre/post processors for typical ``dumps`` and ``loads`` functions. .. image:: _static/converters-light.svg :align: center :class: only-light .. image:: _static/converters-dark.svg :align: center :class: only-dark For example, if ``msgspec`` didn't already provide support for ``json``, you could add support by wrapping the standard library's `json` module as follows: .. code-block:: ipython In [1]: import json ...: from typing import Any ...: ...: import msgspec In [2]: def encode(obj): ...: return json.dumps(msgspec.to_builtins(obj)) In [3]: def decode(msg, type=Any): ...: return msgspec.convert(json.loads(msg), type=type) In [4]: class Point(msgspec.Struct): ...: x: int ...: y: int In [5]: x = Point(1, 2) In [6]: msg = encode(x) # Encoding a high-level type works In [7]: msg '{"x": 1, "y": 2}' In [8]: decode(msg, type=Point) # Decoding a high-level type works Point(x=1, y=2) In [9]: decode('{"x": "oops", "y": 2}', type=Point) # Schema mismatches error --------------------------------------------------------------------------- ValidationError Traceback (most recent call last) Cell In[9], line 1 ----> 1 decode('{"x": "oops", "y": 2}', type=Point) # Schema mismatches error Cell In[3], line 2, in decode(msg, type) 1 def decode(msg, type=Any): ---> 2 return msgspec.convert(json.loads(msg), type=type) ValidationError: Expected `int`, got `str` - at `$.x` Since all protocols are different, `to_builtins` and `convert` have a few configuration options: - ``builtin_types``: an iterable of additional types to treat as builtin types, beyond the standard `dict`, `list`, `tuple`, `set`, `frozenset`, `str`, `int`, `float`, `bool`, and `None`. - ``str_keys``: whether the wrapped protocol only supports strings for object keys, rather than any hashable type. - ``strict``: `convert` only. Whether type coercion rules should be strict. Defaults is True, setting to False enables a wider set of coercion rules from string to non-string types for all values. Among other uses, this may be used to handle completely untyped protocols like URL querystrings, where only string values exist. See :ref:`strict-vs-lax` for more information. - ``from_attributes``: `convert` only. If True, input objects may be coerced to ``Struct`` / ``dataclass`` / ``attrs`` types by extracting attributes from the input matching fields in the output type. One use case is converting database query results (ORM or otherwise) to msgspec structured types. The default is False. - ``enc_hook`` / ``dec_hook``: the standard keyword arguments used for :doc:`extending` msgspec to support additional types. ----- Taking a look at another protocol - TOML_. This protocol - Includes native support for `datetime.datetime`, `datetime.date`, and `datetime.time` types. - Only supports strings for object keys. If ``msgspec`` didn't already provide support for ``toml``, you could add support by wrapping the standard library's `tomllib` module as follows: .. code-block:: python import datetime import tomllib from typing import Any import msgspec def decode(msg, *, type=Any, dec_hook=None): return msgspec.convert( toml.loads(msg), type, builtin_types=(datetime.datetime, datetime.date, datetime.time), str_keys=True, dec_hook=dec_hook, ) ``msgspec`` uses these APIs to implement ``toml`` and ``yaml`` support, wrapping external serialization libraries: - ``msgspec.toml`` (`code `__) - ``msgspec.yaml`` (`code `__) The implementation in ``msgspec.toml`` is *almost* identical to the one above, with some additional code for error handling. .. _TOML: https://toml.io/en/ python-msgspec-0.22.0/docs/examples/000077500000000000000000000000001525673062400173335ustar00rootroot00000000000000python-msgspec-0.22.0/docs/examples/asyncio-kv.rst000066400000000000000000000035111525673062400221500ustar00rootroot00000000000000Asyncio TCP Key-Value Server ============================ This example demonstrates writing a small TCP server and client using `asyncio` and ``msgspec``. The server defines a few operations: - ``get(key: str) -> str | None``: get the value for a single key from the store if it exists. - ``put(key: str, val: str) -> None``: add a new key-value pair to the store. - ``delete(key: str) -> None``: delete a key-value pair from the store if it exists. - ``list_keys() -> list[str]``: list all the keys currently set in the store. Each operation has a corresponding request type defined as a :doc:`Struct <../structs>` type. Note that these structs are :ref:`tagged ` so they can be part of a ``Union`` of all request types the server handles. `msgspec.msgpack` is used to handle the encoding/decoding of the various messages. The length of each message is prefixed to each message (`Length-prefix framing `__) to make it easier to efficiently determine message boundaries. The full example source can be found `here `__. .. literalinclude:: ../../examples/asyncio-kv/kv.py :language: python An example usage session: **Server** .. code-block:: shell $ python kv.py Serving on tcp://127.0.0.1:8888... Connection opened Connection closed **Client** .. code-block:: ipython3 In [1]: from kv import Client In [2]: client = await Client.create() In [3]: await client.put("foo", "bar") In [4]: await client.put("fizz", "buzz") In [5]: await client.get("foo") Out[5]: 'bar' In [6]: await client.list_keys() Out[6]: ['fizz', 'foo'] In [7]: await client.delete("fizz") In [8]: await client.list_keys() Out[8]: ['foo'] python-msgspec-0.22.0/docs/examples/conda-repodata.rst000066400000000000000000000105441525673062400227520ustar00rootroot00000000000000Conda Repodata ============== This example benchmarks using different JSON libraries to parse and query the `current_repodata.json`_ file from conda-forge_. This is a medium-sized (~14 MiB) JSON file containing nested metadata about every package on conda-forge. The following libraries are compared: - json_ - ujson_ - orjson_ - simdjson_ - msgspec_ This benchmark measures how long it takes each library to decode the ``current_repodata.json`` file, extract the name and size of each package, and determine the top 10 packages by file size. **Results** .. raw:: html
.. code-block:: text $ python query_repodata.py json: 139.14 ms ujson: 124.91 ms orjson: 91.69 ms simdjson: 66.40 ms msgspec: 25.73 ms **Commentary** - All of these are fairly quick, library choice likely doesn't matter at all for simple scripts on small- to medium-sized data. - While ``orjson`` is faster than ``json``, the difference between them is only ~30%. Creating python objects dominates the execution time of any well optimized decoding library. How fast the underlying JSON parser is matters, but JSON optimizations can only get you so far if you're still creating a new Python object for every node in the JSON object. - ``simdjson`` is much more performant. This is partly due to the SIMD optimizations it uses, but mostly it's due to not creating so many Python objects. ``simdjson`` first parses a JSON blob into a proxy object. It then lazily creates Python objects as needed as different fields are accessed. This means you only pay the cost of creating Python objects for the fields you use; a query that only accesses a few fields runs much faster since not as many Python objects are created. The downside is every attribute access results in some indirection as new objects are created - ``msgspec`` is the fastest option tested. It relies on defining a known schema beforehand. We don't define the schema for the entire structure, only for the fields we access. Only fields that are part of the schema are decoded, with a new Python object created for each. This allocates the same number of objects as ``simdjson``, but does it all at once, avoiding indirection costs later on during use. See :ref:`this performance tip ` for more information. **Source** The full example source can be found `here `__. .. literalinclude:: ../../examples/conda-repodata/query_repodata.py :language: python .. raw:: html .. _conda-forge: https://conda-forge.org/ .. _current_repodata.json: https://conda.anaconda.org/conda-forge/noarch/current_repodata.json .. _json: https://docs.python.org/3/library/json.html .. _ujson: https://github.com/ultrajson/ultrajson .. _msgspec: https://msgspec.dev .. _orjson: https://github.com/ijl/orjson .. _simdjson: https://github.com/TkTech/pysimdjson python-msgspec-0.22.0/docs/examples/geojson.rst000066400000000000000000000054571525673062400215440ustar00rootroot00000000000000GeoJSON ======= `GeoJSON `__ is a popular format for encoding geographic data. Its specification_ describes nine different types a message may take (seven "geometry" types, plus two "feature" types). Here we provide one way of implementing that specification using ``msgspec`` to handle the parsing and validation. The ``loads`` and ``dumps`` methods defined below work similar to the standard library's ``json.loads`` / ``json.dumps``, but: - Will result in high-level `msgspec.Struct` objects representing GeoJSON types - Will error nicely if a field is missing or the wrong type - Will fill in default values for optional fields - Decodes and encodes *significantly faster* than the `json` module (as well as most other ``json`` implementations in Python). This example makes use `msgspec.Struct` types to define the different GeoJSON types, and :ref:`struct-tagged-unions` to differentiate between them. See the relevant docs for more information. The full example source can be found `here `__. .. literalinclude:: ../../examples/geojson/msgspec_geojson.py :language: python Here we use the ``loads`` method defined above to read some `example GeoJSON`_. .. code-block:: ipython3 In [1]: import msgspec_geojson In [2]: with open("canada.json", "rb") as f: ...: data = f.read() In [3]: canada = msgspec_geojson.loads(data) In [4]: type(canada) # loaded as high-level, validated object Out[4]: msgspec_geojson.FeatureCollection In [5]: canada.features[0].properties Out[5]: {'name': 'Canada'} Comparing performance to: - orjson_ - `json` - geojson_ (another validating Python implementation) .. code-block:: ipython3 In [6]: %timeit msgspec_geojson.loads(data) # benchmark msgspec 6.15 ms ± 13.8 µs per loop (mean ± std. dev. of 7 runs, 100 loops each) In [7]: %timeit orjson.loads(data) # benchmark orjson 8.67 ms ± 20.8 µs per loop (mean ± std. dev. of 7 runs, 100 loops each) In [8]: %timeit json.loads(data) # benchmark json 27.6 ms ± 102 µs per loop (mean ± std. dev. of 7 runs, 10 loops each) In [9]: %timeit geojson.loads(data) # benchmark geojson 93.9 ms ± 88.1 µs per loop (mean ± std. dev. of 7 runs, 10 loops each) This shows that the readable ``msgspec`` implementation above is 1.4x faster than `orjson` (on this data), while also ensuring the loaded data is valid GeoJSON. Compared to geojson_ (another validating geojson library for python), loading the data using ``msgspec`` was **15.3x faster**. .. _specification: https://datatracker.ietf.org/doc/html/rfc7946 .. _example GeoJSON: https://github.com/msgspec/msgspec/blob/main/examples/geojson/canada.json .. _orjson: https://github.com/ijl/orjson .. _geojson: https://github.com/jazzband/geojson python-msgspec-0.22.0/docs/examples/index.rst000066400000000000000000000003221525673062400211710ustar00rootroot00000000000000Examples ======== Here we provide a few examples using ``msgspec`` to accomplish various tasks. .. toctree:: :maxdepth: 1 geojson.rst asyncio-kv.rst conda-repodata.rst pyproject-toml.rst python-msgspec-0.22.0/docs/examples/pyproject-toml.rst000066400000000000000000000103561525673062400230620ustar00rootroot00000000000000Parsing ``pyproject.toml`` ========================== `PEP 518`_ defined a new ``pyproject.toml`` configuration file Python projects can use for configuring: - Metadata (name, version, ...) - Dependencies - Build systems - Additional development tools (black_, mypy_, pytest_, ... all support ``pyproject.toml`` files for configuration). The format was defined in a series of Python Enhancement Proposals (PEPs), which also serve as the main documentation for the file schema. - `PEP 517`_: A build-system independent format for source trees - `PEP 518`_: Specifying minimum build system requirements for Python projects - `PEP 621`_: Storing project metadata in pyproject.toml Here we define a msgspec schema for parsing and validating a ``pyproject.toml`` file. This includes full schema definitions for all fields in the ``build-system`` and ``project`` tables, as well as an untyped table under ``tool``. The full example source can be found `here `__. .. literalinclude:: ../../examples/pyproject-toml/pyproject.py :language: python Here we use it to load the `pyproject.toml for Starlette `__: .. code-block:: ipython3 In [1]: import pyproject In [2]: import urllib.request In [3]: url = "https://raw.githubusercontent.com/Kludex/starlette/HEAD/pyproject.toml" In [4]: with urllib.request.urlopen(url) as f: ...: data = f.read() In [5]: result = pyproject.decode(data) # decode the pyproject.toml In [6]: result.build_system Out[6]: BuildSystem(requires=['hatchling'], build_backend='hatchling.build', backend_path=[]) In [7]: result.project.name Out[7]: 'starlette' Note that this only validates that fields are of the proper type. It doesn't check: - Whether strings like URLs or `dependency specifiers`_ are valid. Some of these could be handled using msgspec's existing :doc:`../constraints` system, but not all of them. - Mutually exclusive field restrictions (for example, you can't set both ``project.license.file`` and ``project.license.text``). ``msgspec`` currently has no way of declaring these restrictions. Even with these caveats, the schemas here are still useful: - Since ``forbid_unknown_fields=True`` is configured, any extra fields will raise a nice error message. This is very useful for catching typos in configuration files, as the misspelled field names won't be silently ignored. - Type errors for fields will also be caught, with a nice error raised. - Any downstream consumers of ``decode`` have a nice high-level object to work with, complete with type annotations. This plays well with tab-completion and tools like mypy_ or pyright_, improving usability. For example, here's an invalid ``pyproject.toml``. .. code-block:: toml [build-system] requires = "hatchling" build-backend = "hatchling.build" [project] name = "myproject" version = "0.1.0" description = "a super great library" authors = [ {name = "alice shmalice", email = "alice@company.com"} ] Can you spot the error? Using the schemas defined above, ``msgpspec`` can detect schema issues like this, and raise a nice error message. In this case the issue is that ``build-system.requires`` should be an array of strings, not a single string: .. code-block:: ipython In [1]: import pyproject In [2]: with open("pyproject.toml", "rb") as f: ...: invalid = f.read() In [3]: pyproject.decode(invalid) --------------------------------------------------------------------------- ValidationError Traceback (most recent call last) Cell In [3], line 1 ----> 1 pyproject.decode(invalid) ValidationError: Expected `array`, got `str` - at `$.build-system.requires` .. _PEP 517: https://peps.python.org/pep-0517/ .. _PEP 518: https://peps.python.org/pep-0518/ .. _PEP 621: https://peps.python.org/pep-0621/ .. _black: https://black.readthedocs.io/en/stable/ .. _mypy: https://mypy.readthedocs.io/en/stable/ .. _pyright: https://github.com/microsoft/pyright .. _pytest: https://docs.pytest.org/en/stable/ .. _dependency specifiers: https://packaging.python.org/en/latest/specifications/dependency-specifiers/ python-msgspec-0.22.0/docs/extending.rst000066400000000000000000000214351525673062400202410ustar00rootroot00000000000000Extending ========= To allow encoding/decoding types other than those :doc:`natively supported `, ``msgspec`` provides a few callbacks to ``Encoder`` / ``Decoder``. - ``enc_hook``, for transforming custom types into values that ``msgspec``:doc:`natively supports `. - ``dec_hook``, for converting natively supported types back into a custom type when using :ref:`typed decoding `. - ``ext_hook`` (MessagePack only), for converting `MessagePack extensions`_ back into custom types. These should have the following signatures: .. code-block:: python def enc_hook(obj: Any) -> Any: """Given an object that msgspec doesn't know how to serialize by default, convert it into an object that it does know how to serialize""" pass def dec_hook(type: Type, obj: Any) -> Any: """Given a type in a schema, convert ``obj`` (composed of natively supported objects) into an object of type ``type``. Any `TypeError` or `ValueError` exceptions raised by this method will be considered "user facing" and converted into a `ValidationError` with additional context. All other exceptions will be raised directly. """ pass def ext_hook(code: int, data: memoryview) -> Any: """MessagePack only. Given an extension type code and data buffer, deserialize whatever custom object the extension type represents""" pass These can be composed together to form complex behaviors as needed. However, most use cases follow one of these patterns: - Mapping a custom type to/from natively supported types via ``enc_hook`` and ``dec_hook`` callbacks. - Defining a custom `MessagePack extension`_ to represent your type, then mapping to/from that extension via ``enc_hook`` and ``ext_hook`` callbacks. Both methods are illustrated below. Mapping to/from native types ---------------------------- This method uses messages composed only of natively supported types. During encoding, custom types are mapped to natively supported types, which are then serialized. This process is then reversed during decoding. .. code-block:: custom type -> native types -> encoded message -> native types -> custom type This means that :ref:`typed decoding ` is required to roundtrip a message, since no custom type info is sent as part of the message. This method works best for types that are similar to a natively supported type (e.g. a `collections.deque` is similar to a `list`). This can be accomplished by defining two callback functions: - ``enc_hook`` in ``Encoder``, for transforming custom types into values that ``msgspec`` already knows how to serialize. - ``dec_hook`` in ``Decoder``, for converting natively supported types back into a custom type when using :ref:`typed decoding `. Here we define ``enc_hook`` and ``dec_hook`` callbacks to convert `complex` objects to/from objects, which are then natively handled by ``msgspec``. .. code-block:: python import msgspec from typing import Any, Type def enc_hook(obj: Any) -> Any: if isinstance(obj, complex): # convert the complex to a tuple of real, imag return (obj.real, obj.imag) else: # Raise a NotImplementedError for other types raise NotImplementedError(f"Objects of type {type(obj)} are not supported") def dec_hook(type: Type, obj: Any) -> Any: # `type` here is the value of the custom type annotation being decoded. if type is complex: # Convert ``obj`` (which should be a ``tuple``) to a complex real, imag = obj return complex(real, imag) else: # Raise a NotImplementedError for other types raise NotImplementedError(f"Objects of type {type} are not supported") # Define a message that contains a complex type class MyMessage(msgspec.Struct): field_1: str field_2: complex # Create an encoder and a decoder using the custom callbacks. # Note that typed deserialization is required for successful # roundtripping here, so we pass `MyMessage` to `Decoder`. enc = msgspec.json.Encoder(enc_hook=enc_hook) dec = msgspec.json.Decoder(MyMessage, dec_hook=dec_hook) # An example message msg = MyMessage("some string", complex(1, 2)) # Encode and decode the message to show that things work buf = enc.encode(msg) msg2 = dec.decode(buf) assert msg == msg2 # True .. _defining-extensions: Defining a custom extension (MessagePack only) ---------------------------------------------- The MessagePack specification provides support for defining custom Extensions_. Extensions consist of: - An integer code (between 0 and 127, inclusive) representing the "type" of the extension. - An arbitrary byte buffer of data (up to ``(2^32) - 1`` in length). By default extensions are serialized to/from `msgspec.msgpack.Ext` objects. .. code-block:: python >>> ext = msgspec.msgpack.Ext(1, b"some data") # an extension object, with type code 1 >>> msg = msgspec.msgpack.encode(ext) >>> ext2 = msgspec.msgpack.decode(msg) >>> ext == ext2 # deserializes as an Ext object True While manually creating `Ext` objects from buffers can be useful, usually the user wants to map extension types to/from their own custom objects. This can be accomplished by defining two callback functions: - ``enc_hook`` in `msgspec.msgpack.Encoder`, for transforming custom types into values that ``msgspec`` already knows how to serialize. - ``ext_hook`` in `msgspec.msgpack.Decoder`, for converting extensions back into those custom types. This method defines a new extension type, and sends this type information along as part of the message. This means that when properly configured, custom types can be deserialized even when using untyped deserialization. However, if you're communicating with MessagePack libraries other than ``msgspec``, you'd have to ensure your extension type was supported by those libraries as well. For example, perhaps you wanted to serialize `complex` number objects as an extension type. These objects can be represented as tuples of two floats (one "real" and one "imaginary"). If we represent each float as 8 bytes (a "double"), then any complex number can be fully represented by a 16 byte buffer. .. code-block:: +---------+---------+ | real | imag | +---------+---------+ 8 bytes 8 bytes Here we define ``enc_hook`` and ``ext_hook`` callbacks to convert `complex` objects to/from this binary representation as a MessagePack extension. .. code-block:: python import msgspec import struct from typing import Any # All extension types need a unique integer designator so the decoder knows # which type they're decoding. Here we arbitrarily choose 1, but any integer # between 0 and 127 (inclusive) would work. COMPLEX_TYPE_CODE = 1 def enc_hook(obj: Any) -> Any: if isinstance(obj, complex): # encode the complex number into a 16 byte buffer data = struct.pack('dd', obj.real, obj.imag) # Return an `Ext` object so msgspec serializes it as an extension type. return msgspec.msgpack.Ext(COMPLEX_TYPE_CODE, data) else: # Raise a NotImplementedError for other types raise NotImplementedError(f"Objects of type {type(obj)} are not supported") def ext_hook(code: int, data: memoryview) -> Any: if code == COMPLEX_TYPE_CODE: # This extension type represents a complex number, decode the data # buffer accordingly. real, imag = struct.unpack('dd', data) return complex(real, imag) else: # Raise a NotImplementedError for other extension type codes raise NotImplementedError(f"Extension type code {code} is not supported") # Create an encoder and a decoder using the custom callbacks enc = msgspec.msgpack.Encoder(enc_hook=enc_hook) dec = msgspec.msgpack.Decoder(ext_hook=ext_hook) # Define a message that contains complex numbers msg = {"roots": [0, 0.75, 1 + 0.5j, 1 - 0.5j]} # Encode and decode the message to show that things work buf = enc.encode(msg) msg2 = dec.decode(buf) assert msg == msg2 # True .. note:: Note that the ``data`` argument to ``ext_hook`` is a `memoryview`. This view is attached to the larger buffer containing the complete message being decoded. As such, you'll want to ensure that you don't keep a reference to the underlying buffer, otherwise you may accidentally persist the larger message buffer around for longer than necessary, resulting in increased memory usage. .. _extensions: .. _MessagePack extensions: .. _MessagePack extension: https://github.com/msgpack/msgpack/blob/master/spec.md#extension-types python-msgspec-0.22.0/docs/index.rst000066400000000000000000000161121525673062400173570ustar00rootroot00000000000000msgspec ======= ``msgspec`` is a *fast* serialization and validation library, with builtin support for JSON_, MessagePack_, YAML_, and TOML_. It features: - 🚀 **High performance encoders/decoders** for common protocols. The JSON and MessagePack implementations regularly :doc:`benchmark ` as the fastest options for Python. - 🎉 **Support for a wide variety of Python types**. Additional types may be supported through :doc:`extensions `. - � **Zero-cost schema validation** using familiar Python type annotations. In :doc:`benchmarks ` ``msgspec`` decodes *and* validates JSON faster than orjson_ can decode it alone. - ✨ **A speedy Struct type** for representing structured data. If you already use dataclasses_ or attrs_, :doc:`structs` should feel familiar. However, they're :ref:`5-60x ` faster for common operations. All of this is included in a :ref:`lightweight library ` with no required dependencies. ----- ``msgspec`` may be used for serialization alone, as a faster JSON or MessagePack library. For the greatest benefit though, we recommend using ``msgspec`` to handle the full serialization & validation workflow: **Define** your message schemas using standard Python type annotations. .. code-block:: python >>> import msgspec >>> class User(msgspec.Struct): ... """A new type describing a User""" ... name: str ... groups: set[str] = set() ... email: str | None = None **Encode** messages as JSON, or one of the many other supported protocols. .. code-block:: python >>> alice = User("alice", groups={"admin", "engineering"}) >>> alice User(name='alice', groups={"admin", "engineering"}, email=None) >>> msg = msgspec.json.encode(alice) >>> msg b'{"name":"alice","groups":["admin","engineering"],"email":null}' **Decode** messages back into Python objects, with optional schema validation. .. code-block:: python >>> msgspec.json.decode(msg, type=User) User(name='alice', groups={"admin", "engineering"}, email=None) >>> msgspec.json.decode(b'{"name":"bob","groups":[123]}', type=User) Traceback (most recent call last): File "", line 1, in msgspec.ValidationError: Expected `str`, got `int` - at `$.groups[0]` ``msgspec`` is designed to be as performant as possible, while retaining some of the nicities of validation libraries like pydantic_. For supported types, encoding/decoding a message with ``msgspec`` can be :doc:`~10-80x faster than alternative libraries `. Highlights ---------- - ``msgspec`` is **fast**. It :doc:`benchmarks ` as the fastest serialization library for Python, outperforming all other JSON/MessagePack libraries compared. - ``msgspec`` is **friendly**. Through use of Python's type annotations, messages are :ref:`validated ` during deserialization in a declarative way. ``msgspec`` also works well with other type-checking tooling like mypy_ and pyright_, providing excellent editor integration. - ``msgspec`` is **flexible**. It natively supports a :doc:`wide range of Python builtin types `. Support for additional types can also be added through :doc:`extensions `. - ``msgspec`` is **lightweight**. It has no required dependencies, and the binary size is :ref:`a fraction of that of comparable libraries `. - ``msgspec`` is **correct**. The encoders/decoders implemented are strictly compliant with their respective specifications, providing stronger guarantees of compatibility with other systems. Used By ------- ``msgspec`` is used by many organizations and `open source projects `__, here we highlight a few: .. grid:: 2 2 4 4 .. grid-item-card:: `NautilusTrader `_ .. image:: _static/nautilus-trader.png :target: https://nautilustrader.io/ .. grid-item-card:: `Litestar `_ .. image:: _static/litestar.png :target: https://litestar.dev/ .. grid-item-card:: `Sanic `_ .. image:: _static/sanic.png :target: https://sanic.dev/en/ .. grid-item-card:: `Mosec `_ .. image:: _static/mosec.png :target: https://mosecorg.github.io/mosec/ .. grid-item-card:: `Pioreactor `_ .. image:: _static/pioreactor.png :target: https://pioreactor.com/ .. grid-item-card:: `Zero `_ .. image:: _static/zero.png :target: https://github.com/Ananto30/zero .. grid-item-card:: `anywidget `_ .. image:: _static/anywidget.png :target: https://anywidget.dev/ .. grid-item-card:: `Ravyn `_ .. image:: _static/ravyn.png :target: https://www.ravyn.dev/ .. grid-item-card:: `Faststream `_ .. image:: _static/faststream.png :target: https://faststream.ag2.ai/ .. grid-item-card:: `django-modern-rest `_ .. image:: _static/django-modern-rest.png :target: https://django-modern-rest.readthedocs.io/en/latest/ .. grid-item-card:: `Meltano `_ .. image:: _static/meltano.svg :target: https://meltano.com/ .. _type annotations: https://docs.python.org/3/library/typing.html .. _JSON: https://json.org .. _MessagePack: https://msgpack.org .. _YAML: https://yaml.org .. _TOML: https://toml.io/en/ .. _attrs: https://www.attrs.org/en/stable/ .. _dataclasses: https://docs.python.org/3/library/dataclasses.html .. _orjson: https://github.com/ijl/orjson .. _pydantic: https://pydantic.dev/docs/validation/latest/get-started/ .. _mypy: https://mypy.readthedocs.io/en/stable/ .. _pyright: https://github.com/microsoft/pyright .. toctree:: :hidden: :maxdepth: 2 :caption: Overview why.rst install.rst benchmarks.rst .. toctree:: :hidden: :maxdepth: 2 :caption: User Guide usage.rst supported-types.rst structs.rst constraints.rst converters.rst jsonschema.rst schema-evolution.rst .. toctree:: :hidden: :maxdepth: 2 :caption: Advanced extending.rst inspect.rst perf-tips.rst .. toctree:: :hidden: :maxdepth: 2 :caption: Porting porting/index.rst .. toctree:: :hidden: :maxdepth: 2 :caption: Reference api.rst examples/index.rst changelog.md python-msgspec-0.22.0/docs/inspect.rst000066400000000000000000000112601525673062400177140ustar00rootroot00000000000000Inspecting Types ---------------- .. currentmodule:: msgspec.inspect .. warning:: This module is experimental. While we don't expect any breaking changes, we also don't promise not to break things between releases while this interface stabilizes. ``msgspec`` provides type-introspection support, which can be used to build tooling on top of msgspec-compatible types. Possible use cases include: - Generating OpenAPI_ specifications from msgspec-compatible types (note that the builtin :doc:`jsonschema` support may be a better starting point for this). - Generating example instances of types for testing or documentation purposes - Integration with hypothesis_ for testing The main function here is `msgspec.inspect.type_info` for converting a type annotation into a corresponding `msgspec.inspect.Type` object. There's also `msgspec.inspect.multi_type_info` which converts an iterable of annotations; this function is more efficient than calling `type_info` in a loop. .. code-block:: python >>> import msgspec >>> msgspec.inspect.type_info(bool) BoolType() >>> msgspec.inspect.type_info(int) IntType(gt=None, ge=None, lt=None, le=None, multiple_of=None) >>> msgspec.inspect.type_info(list[int]) # nested types are traversed ListType( item_type=IntType(gt=None, ge=None, lt=None, le=None, multiple_of=None), min_length=None, max_length=None ) >>> msgspec.inspect.multi_type_info([bool, int]) # inspect multiple types (BoolType(), IntType(gt=None, ge=None, lt=None, le=None, multiple_of=None)) Types with :doc:`constraints` will include the constraint information as well: .. code-block:: python >>> from typing import Annotated >>> from msgspec import Meta >>> PositiveInt = Annotated[int, Meta(gt=0)] >>> msgspec.inspect.type_info(PositiveInt) IntType(gt=0, ge=None, lt=None, le=None, multiple_of=None) Compound types like :doc:`structs` are also supported: .. code-block:: python >>> class User(msgspec.Struct): ... name: str ... groups: list[str] = [] ... email: str | None = None >>> msgspec.inspect.type_info(User) StructType( cls=User, fields=( Field( name='name', encode_name='name', type=StrType(min_length=None, max_length=None, pattern=None), required=True, default=UNSET, default_factory=UNSET ), Field( name='groups', encode_name='groups', type=ListType( item_type=StrType(min_length=None, max_length=None, pattern=None), min_length=None, max_length=None ), required=False, default=[], default_factory=UNSET ), Field( name='email', encode_name='email', type=UnionType( types=( StrType(min_length=None, max_length=None, pattern=None), NoneType() ) ), required=False, default=None, default_factory=UNSET ) ), tag_field=None, tag=None, array_like=False, forbid_unknown_fields=False ) Types with additional metadata like ``extra_json_schema`` or ``title`` will be wrapped in a `msgspec.inspect.Metadata` object. Note that all JSON schema specific fields are merged into a single ``extra_json_schema`` dict. .. code-block:: python >>> UnixName = Annotated[ ... str, ... Meta( ... min_length=1, ... max_length=32, ... pattern="^[a-z_][a-z0-9_-]*$", ... description="A valid UNIX username" ... ) ... ] >>> msgspec.inspect.type_info(UnixName) Metadata( type=StrType( min_length=1, max_length=32, pattern='^[a-z_][a-z0-9_-]*$' ), extra_json_schema={'description': 'A valid UNIX username'} ) Every type supported by ``msgspec`` has a corresponding `msgspec.inspect.Type` subclass. See the :ref:`API docs ` for a complete list of types. For an example of using these functions, you might find our builtin :doc:`jsonschema` generator implementation useful - the code for this can be found `here `__. In particular, take a look at the large if-else statement in ``_to_schema``. .. _OpenAPI: https://www.openapis.org/ .. _hypothesis: https://hypothesis.readthedocs.io/en/latest/ python-msgspec-0.22.0/docs/install.rst000066400000000000000000000033261525673062400177210ustar00rootroot00000000000000Installation ============ ``msgspec`` may be installed via ``pip`` or ``conda``. Note that Python >= 3.10 is required. The basic install has no required dependencies. **pip** .. code-block:: shell pip install msgspec **conda** .. code-block:: shell conda install msgspec -c conda-forge Optional Dependencies --------------------- Depending on your platform, the base install of ``msgspec`` may not support TOML_ or YAML_ without additional dependencies. TOML ~~~~ The TOML_ protocol requires: - Python < 3.11: `tomli`_ and `tomli_w`_ for reading and writing TOML. - Python >= 3.11: `tomli_w`_ for writing TOML. Reading TOML is done using the standard library's `tomllib` and requires no additional dependencies. You may either install these dependencies manually, or depend on the ``toml`` extra: **pip** .. code-block:: shell pip install "msgspec[toml]" **conda** .. code-block:: shell conda install msgspec-toml -c conda-forge YAML ~~~~ The YAML_ protocol requires PyYAML_ on all platforms. You may either install this dependency manually, or depend on the ``yaml`` extra: **pip** .. code-block:: shell pip install "msgspec[yaml]" **conda** .. code-block:: shell conda install msgspec-yaml -c conda-forge Installing from GitHub ---------------------- If you want wish to use a feature that hasn't been released yet, you may install from the `development branch on GitHub `__ using ``pip``: .. code-block:: shell pip install git+https://github.com/msgspec/msgspec.git .. _YAML: https://yaml.org .. _TOML: https://toml.io/en/ .. _PyYAML: https://pyyaml.org/ .. _tomli: https://github.com/hukkin/tomli .. _tomli_w: https://github.com/hukkin/tomli-w python-msgspec-0.22.0/docs/jsonschema.rst000066400000000000000000000052541525673062400204070ustar00rootroot00000000000000JSON Schema =========== ``msgspec`` provides a few utilities for generating `JSON Schema`_ specifications from msgspec-compatible :doc:`types ` and :doc:`constraints `. - `msgspec.json.schema`: generates a complete JSON Schema for a single type. - `msgspec.json.schema_components`: generates JSON schemas for multiple types, along with a corresponding ``components`` mapping. This is mainly useful when generating multiple schemas to include in a larger specification like OpenAPI_. The generated schemas are compatible with `JSON Schema`_ 2020-12 and OpenAPI_ 3.1. Example ------- .. code-block:: python import msgspec from msgspec import Struct, Meta from typing import Annotated # A float constrained to values > 0 PositiveFloat = Annotated[float, Meta(gt=0)] class Dimensions(Struct): """Dimensions for a product, all measurements in centimeters""" length: PositiveFloat width: PositiveFloat height: PositiveFloat class Product(Struct): """A product in a catalog""" id: int name: str price: PositiveFloat tags: set[str] = set() dimensions: Dimensions | None = None # Generate a schema for a list of products schema = msgspec.json.schema(list[Product]) # Print out that schema as JSON print(msgspec.json.encode(schema)) .. code-block:: json { "type": "array", "items": {"$ref": "#/$defs/Product"}, "$defs": { "Dimensions": { "title": "Dimensions", "description": "Dimensions for a product, all measurements in centimeters", "type": "object", "properties": { "length": {"type": "number", "exclusiveMinimum": 0}, "width": {"type": "number", "exclusiveMinimum": 0}, "height": {"type": "number", "exclusiveMinimum": 0} }, "required": ["length", "width", "height"] }, "Product": { "title": "Product", "description": "A product in a catalog", "type": "object", "properties": { "id": {"type": "integer"}, "name": {"type": "string"}, "price": {"type": "number", "exclusiveMinimum": 0}, "tags": { "type": "array", "items": {"type": "string"}, "default": [], }, "dimensions": { "anyOf": [{"type": "null"}, {"$ref": "#/$defs/Dimensions"}], "default": null, } }, "required": ["id", "name", "price"] } } } .. _JSON Schema: https://json-schema.org/ .. _OpenAPI: https://www.openapis.org/ python-msgspec-0.22.0/docs/perf-tips.rst000066400000000000000000000273231525673062400201670ustar00rootroot00000000000000Performance Tips ================ Here we present a few tips and tricks for squeezing maximum performance out of ``msgspec``. They're presented in order from "sane, definitely a good idea" to "fast, but you may not want to do this". Reuse Encoders/Decoders ----------------------- Every call to a top-level ``encode`` function like `msgspec.json.encode` allocates some temporary internal state used for encoding. While fine for normal use, for maximum performance you'll want to create an ``Encoder`` (e.g. `msgspec.json.Encoder`) once and reuse it for all encoding calls, avoiding paying that setup cost for every call. .. code-block:: python >>> import msgspec >>> encoder = msgspec.json.Encoder() # Create once >>> for msg in msgs: ... data = encoder.encode(msg) # reuse multiple times The same goes for decoding. If you're making multiple ``decode`` calls in a performance-sensitive code path, you'll want to create a ``Decoder`` (e.g. `msgspec.json.Decoder`) once and reuse it for each call. Since decoders are typed, you may need to create multiple decoders, one for each type. .. code-block:: python >>> import msgspec >>> decoder = msgspec.json.Decoder(list[int]) # Create once >>> for data in input_buffers: ... msg = decoder.decode(data) # reuse multiple times Use Structs ----------- :doc:`structs` are msgspec's native way of expressing user-defined types. They're :ref:`fast to encode/decode ` and :ref:`fast to use `. If you have data with a known schema, we recommend defining a `msgspec.Struct` type (or types) for your schema and preferring that over other types like `dict` / `dataclasses` / etc. Avoid Encoding Default Values ----------------------------- By default, ``msgspec`` encodes all fields in a ``Struct`` type, including optional fields (those configured with a default value). If the default values are known on the decoding end (making serializing them redundant), it may be beneficial to omit default values from the encoded message. This can be done by configuring ``omit_defaults=True`` as part of the ``Struct`` definition. Omitting defaults reduces the size of the encoded message, and often also improves encoding and decoding performance (since there's less work to do). For more information, see :ref:`omit_defaults`. .. _avoid-decoding-unused-fields: Avoid Decoding Unused Fields ---------------------------- When decoding large inputs, sometimes you're only interested in a few specific fields. Since decoding large objects is inherently allocation heavy, it may be beneficial to define a smaller `msgspec.Struct` type that only has the fields you require. For example, say you're interested in decoding some JSON from the `Twitter API `__. A ``Tweet`` object has many nested fields on it - perhaps you only care about the tweet text, the user name, and the number of favorites. By defining struct types with only those fields, ``msgspec`` can avoid doing unnecessary work decoding fields that are never used. .. code-block:: python >>> import msgspec >>> class User(msgspec.Struct): ... name: str >>> class Tweet(msgspec.Struct): ... user: User ... full_text: str ... favorite_count: int We can then use these types to decode the `example tweet json `__: .. code-block:: python >>> tweet = msgspec.json.decode(example_json, type=Tweet) >>> tweet.user.name 'Twitter Dev' >>> tweet.user.favorite_count 70 Of course there are downsides to defining smaller "view" types, but if decoding performance is a bottleneck in your workflow, you may benefit from this technique. For a more in-depth example of this technique, see the :doc:`examples/conda-repodata` example. Reduce Allocations ------------------ Every call to ``encode`` / ``Encoder.encode`` allocates a new `bytes` object for the output. ``msgspec`` exposes an alternative ``Encoder.encode_into`` (e.g. `msgspec.json.Encoder.encode_into`) that writes into a pre-allocated `bytearray` instead (possibly reallocating to increase capacity). This has the following uses. Reusing an output buffer ^^^^^^^^^^^^^^^^^^^^^^^^ If you're encoding and writing messages to a socket/file in a hot loop, you *may* benefit from allocating a single `bytearray` buffer once and reusing it for every message. For example: .. code-block:: python encoder = msgspec.msgpack.Encoder() # Allocate a single shared buffer buffer = bytearray() for msg in msgs: # Encode a message into the buffer at the start of the buffer. # Note that this overwrites any previous contents. encoder.encode_into(msg, buffer) # Write the buffer to the socket socket.sendall(buffer) A few caveats: - ``Encoder.encode_into`` will expand the capacity of ``buffer`` as needed to fit the message size. This means that if a large message is encountered the buffer will be expanded to be equally large, but won't be reduced back to normal afterwards (possibly bloating memory usage). You can use `sys.getsizeof` (or call `bytearray.__sizeof__`) directly to determine the actual capacity of the buffer, since ``len(buffer)`` will only reflect the part of the buffer that is written to. - Small messages (for some definition of "small") likely won't see a performance improvement from using this method, and may instead see a slowdown. We recommend using a realistic benchmark to determine if this method can benefit your workload. Line-Delimited JSON ^^^^^^^^^^^^^^^^^^^ Some protocols require appending a suffix to an encoded message. One place where this comes up is when encoding `line-delimited JSON`_, where every payload contains a JSON message followed by ``b"\n"``. This *could* be handled in python as: .. code-block:: python import msgspec json_msg = msgspec.json.encode(["my", "message"]) full_payload = json_msg + b'\n' However, this results in an unnecessary copy of ``json_msg``, which can be avoided by using `msgspec.json.Encoder.encode_into`. .. code-block:: python import msgspec encoder = msgspec.json.Encoder() # Allocate a buffer. We recommend using a small non-empty buffer to # avoid reallocating for small messages. Choose something larger than # your common message size, but not excessively large. buffer = bytearray(64) # Encode into the existing buffer. encoder.encode_into(["my", "message"], buffer) # Append a newline character without copying buffer.extend(b"\n") # Write the full buffer to a socket/file/etc... socket.sendall(buffer) Length-Prefix Framing ^^^^^^^^^^^^^^^^^^^^^ Some protocols require prepending a prefix to an encoded message. This comes up in `Length-prefix framing `__ , where every message is prefixed by its length stored as a fixed-width integer (e.g. a big-endian ``uint32``). Like line-delimited JSON above, this is more efficient to do using ``Encoder.encode_into`` to avoid excessive copying. .. code-block:: python import msgspec encoder = msgspec.msgpack.Encoder() # Allocate a buffer. We recommend using a small non-empty buffer to # avoid reallocating for small messages. Choose something larger than # your common message size, but not excessively large. buffer = bytearray(64) # Encode into the existing buffer, offset by 4 bytes at the front to # store the length prefix. encoder.encode_into(msg, buffer, 4) # Encode the message length as a 4 byte big-endian integer, and # prefix the message with it (without copying). n = len(msg) - 4 buffer[:4] = n.to_bytes(4, "big") # Write the buffer to a socket/file/etc... socket.sendall(buffer) Use MessagePack --------------- ``msgspec`` supports both JSON_ and MessagePack_ protocols. The latter is less commonly used, but :ref:`can be more performant `. If performance is an issue (and MessagePack is an acceptable solution), you may benefit from using it instead of JSON. And since ``msgspec`` supports both protocols with a consistent interface, switching from ``msgspec.json`` to ``msgspec.msgpack`` should be fairly painless. Use ``gc=False`` ----------------- Python processes with a large number of long-lived objects, or operations that allocate a large number of objects at once may suffer reduced performance due to Python's garbage collector (GC). By default, `msgspec.Struct` types implement a few optimizations to reduce the load on the GC (and thus reduce the frequency and duration of a GC pause). If you find that GC is still a problem, and **are certain** that your ``Struct`` types may never participate in a reference cycle, then you **may** benefit from setting ``gc=False`` on your ``Struct`` types. Depending on workload, this can result in a measurable decrease in pause time and frequency due to GC passes. See :ref:`struct-gc` for more details. Use ``array_like=True`` ----------------------- One touted benefit of JSON_ and MessagePack_ is that they're "self-describing" protocols. JSON objects serialize their field names along with their values. If both ends of a connection already know the field names though, serializing them may be an unnecessary cost. If you need higher performance (at the cost of more inscrutable message encoding), you can set ``array_like=True`` on a struct definition. Structs with this option enabled are encoded/decoded like array types, removing the field names from the encoded message. This can provide on average another ~2x speedup for decoding (and ~1.5x speedup for encoding). .. code-block:: python >>> class Example(msgspec.Struct, array_like=True): ... my_first_field: str ... my_second_field: int >>> x = Example("some string", 2) >>> msg = msgspec.json.encode(x) >>> msg b'["some string",2]' >>> msgspec.json.decode(msg, type=Example) Example(my_first_field="some string", my_second_field=2) Think about type conversion --------------------------- When converting raw data into Python types, the internal machinery will treat different datastructures differently. Some type conversions are faster than others. For example, this model: .. code-block:: python class Example(msgspec.Struct): items: frozendict[str, int] # requires Python3.15+ to be used msg = b'{"items": {"pen": 1, "book": 2}}' msgspec.json.decode(msg, type=Example) # Example(items=frozendict({"pen": 1, "book": 2})) As ``frozendict`` does not allow adding items one at a time, ``msgspec`` will first parse ``items`` as a regular :class:`dict`, and will then convert it to ``frozendict``, which results in the total decoding operation having ``O(n*2)`` time complexity. Which might be slow on big dictionaries and consume more memory. Regular :class:`dict` would be more efficient to use. The same can be said for :class:`tuple` vs :class:`list`: .. code-block:: python >>> class Example(msgspec.Struct): ... items: tuple[str, ...] >>> msg = b'{"items": ["pen", "book"]}' >>> msgspec.json.decode(msg, type=Example) Example(items=("pen", "book")) We would first create a ``list`` object and then convert it to variable-sized ``tuple``, using double the memory and ``O(n*2)`` time to do that. This is true for all conversions, that require an intermediate representation. To achieve the best performance, use collection types that can be constructed natively: ``list``, ``set``, ``frozenset``, fixed-sized ``tuple``, and ``dict``. .. _JSON: https://json.org .. _MessagePack: https://msgpack.org .. _line-delimited JSON: https://en.wikipedia.org/wiki/JSON_streaming#Line-delimited_JSON python-msgspec-0.22.0/docs/porting/000077500000000000000000000000001525673062400171775ustar00rootroot00000000000000python-msgspec-0.22.0/docs/porting/index.rst000066400000000000000000000002041525673062400210340ustar00rootroot00000000000000Porting guides ============== Guides for migrating to ``msgspec`` from other libraries. .. toctree:: :maxdepth: 1 orjson python-msgspec-0.22.0/docs/porting/orjson.rst000066400000000000000000000214551525673062400212520ustar00rootroot00000000000000Porting from orjson =================== If you're currently using orjson_ and considering migrating to ``msgspec``, this guide covers the key API differences and shows how to translate common patterns. Why migrate? ------------ Both ``orjson`` and ``msgspec`` are high-performance JSON libraries written in compiled languages. There are a few reasons you might prefer ``msgspec``: - **Typed decoding and validation**. ``orjson.loads`` always returns plain Python builtins (``dict``, ``list``, ...). With ``msgspec`` you can decode directly into typed objects (``Struct``, ``dataclass``, ``TypedDict``, etc.) while validating the schema in a single pass. See :doc:`../usage` for details. - **Schema evolution**. ``msgspec`` has first-class support for evolving schemas over time without breaking existing clients. See :doc:`../schema-evolution`. - **Multiple protocols**. ``msgspec`` also supports MessagePack, YAML, and TOML with a consistent API, making it easy to switch between formats. - **JSON Schema generation**. ``msgspec`` can generate JSON Schema definitions from your types via :func:`msgspec.json.schema`. Useful for OpenAPI documentation and API tooling. Basic usage ----------- For most users, migration is straightforward -- swap function names and you're done: .. code-block:: python # Before (orjson) import orjson data = orjson.dumps({"hello": "world"}) obj = orjson.loads(data) # After (msgspec) import msgspec data = msgspec.json.encode({"hello": "world"}) obj = msgspec.json.decode(data) Both return ``bytes`` from encoding and accept ``bytes`` or ``str`` for decoding. Typed decoding -------------- The main advantage of ``msgspec`` over ``orjson`` is typed decoding. Instead of getting a plain ``dict`` back, you can decode directly into structured types: .. code-block:: python import msgspec class User(msgspec.Struct): name: str age: int email: str | None = None data = b'{"name": "Alice", "age": 30}' user = msgspec.json.decode(data, type=User) print(user.name) # "Alice" print(user.age) # 30 print(user.email) # None This validates the data while decoding -- if a field is missing or has the wrong type, a ``msgspec.ValidationError`` is raised with a clear error message. Encoder and Decoder classes --------------------------- If you're making multiple calls, using the ``Encoder`` and ``Decoder`` classes is more efficient: .. code-block:: python # orjson has no stateful encoder/decoder # msgspec encoder = msgspec.json.Encoder() decoder = msgspec.json.Decoder(User) data = encoder.encode(user) user = decoder.decode(data) Option mapping -------------- ``orjson`` uses bitwise ``OPT_*`` flags. ``msgspec`` uses keyword arguments on ``Encoder`` / ``Decoder`` or the ``encode`` / ``decode`` functions. Sorting keys ^^^^^^^^^^^^ .. code-block:: python # orjson orjson.dumps(obj, option=orjson.OPT_SORT_KEYS) # msgspec msgspec.json.encode(obj, order="sorted") # Or with an Encoder encoder = msgspec.json.Encoder(order="sorted") ``msgspec`` also supports ``order="deterministic"`` which provides a consistent ordering without the cost of full alphabetical sorting. Pretty-printing ^^^^^^^^^^^^^^^ .. code-block:: python # orjson orjson.dumps(obj, option=orjson.OPT_INDENT_2) # msgspec -- use format() on already-encoded JSON raw = msgspec.json.encode(obj) pretty = msgspec.json.format(raw, indent=2) Unlike ``orjson``'s single-pass approach, ``msgspec`` uses a two-step process: encode first, then format. ``msgspec.json.format`` works on any JSON bytes/str, not just ``msgspec``-encoded data, and supports arbitrary indent levels. Custom type serialization ^^^^^^^^^^^^^^^^^^^^^^^^^ .. code-block:: python # orjson def default(obj): if isinstance(obj, complex): return {"real": obj.real, "imag": obj.imag} raise TypeError orjson.dumps(obj, default=default) # msgspec def enc_hook(obj): if isinstance(obj, complex): return {"real": obj.real, "imag": obj.imag} raise NotImplementedError msgspec.json.encode(obj, enc_hook=enc_hook) The key difference: ``orjson``'s ``default`` should raise ``TypeError`` for unhandled types, while ``msgspec``'s ``enc_hook`` should raise ``NotImplementedError``. Appending newlines ^^^^^^^^^^^^^^^^^^ .. code-block:: python # orjson orjson.dumps(obj, option=orjson.OPT_APPEND_NEWLINE) # msgspec -- no built-in flag, just append manually msgspec.json.encode(obj) + b"\n" Naive datetimes ^^^^^^^^^^^^^^^ By default, both libraries encode naive datetimes identically (without timezone info): .. code-block:: python import datetime dt = datetime.datetime(2024, 1, 1, 12, 0, 0) orjson.dumps(dt) # b'"2024-01-01T12:00:00"' msgspec.json.encode(dt) # b'"2024-01-01T12:00:00"' ``orjson`` has ``OPT_NAIVE_UTC`` to force treating naive datetimes as UTC: .. code-block:: python orjson.dumps(dt, option=orjson.OPT_NAIVE_UTC) # b'"2024-01-01T12:00:00+00:00"' ``msgspec`` has no equivalent flag. Convert before encoding instead: .. code-block:: python def ensure_utc(dt): if dt.tzinfo is None: return dt.replace(tzinfo=datetime.timezone.utc) return dt msgspec.json.encode(ensure_utc(dt)) .. note:: ``enc_hook`` is only called for types that ``msgspec`` doesn't natively support. Since ``datetime`` is natively supported, you need to convert before passing to ``encode``. Numpy arrays ^^^^^^^^^^^^ .. code-block:: python import numpy as np # orjson -- native support orjson.dumps(arr, option=orjson.OPT_SERIALIZE_NUMPY) # msgspec -- use enc_hook def enc_hook(obj): if isinstance(obj, np.ndarray): return obj.tolist() raise NotImplementedError msgspec.json.encode(arr, enc_hook=enc_hook) Pre-serialized JSON fragments ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. code-block:: python # orjson orjson.dumps({"key": orjson.Fragment(b'{"already":"json"}')}) # msgspec msgspec.json.encode({"key": msgspec.Raw(b'{"already":"json"}')}) Decimal and UUID handling ------------------------- ``msgspec`` has built-in support for both ``Decimal`` and ``UUID``, with configurable output formats: .. code-block:: python from decimal import Decimal from uuid import uuid4 enc = msgspec.json.Encoder( decimal_format="number", # or "string" (default) uuid_format="hex", # or "canonical" (default) ) ``orjson`` requires a ``default`` callback for ``Decimal``. Line-delimited JSON ------------------- ``msgspec`` has built-in support for encoding and decoding newline-delimited JSON (NDJSON): .. code-block:: python encoder = msgspec.json.Encoder() decoder = msgspec.json.Decoder(User) # Encode multiple objects as NDJSON data = encoder.encode_lines([user1, user2, user3]) # Decode NDJSON back users = decoder.decode_lines(data) ``orjson`` has no equivalent -- you'd need to encode each object separately and join with newlines. Error handling -------------- .. code-block:: python # orjson try: orjson.loads(bad_data) except orjson.JSONDecodeError: ... # msgspec try: msgspec.json.decode(bad_data, type=User) except msgspec.ValidationError: # Schema validation error (wrong type, missing field, etc.) ... except msgspec.DecodeError: # Malformed JSON ... ``msgspec`` distinguishes between malformed JSON (``DecodeError``) and valid JSON that doesn't match the schema (``ValidationError``, a subclass of ``DecodeError``). Note that ``ValidationError`` must be caught first since it inherits from ``DecodeError``. Features with no direct equivalent ----------------------------------- Some ``orjson`` options have no direct ``msgspec`` flag, but can be achieved through other means: .. list-table:: :header-rows: 1 * - orjson - msgspec workaround * - ``OPT_NON_STR_KEYS`` - Use ``enc_hook`` / ``dec_hook`` or ``msgspec.to_builtins(obj, str_keys=True)`` * - ``OPT_OMIT_MICROSECONDS`` - Convert before encoding: ``dt.replace(microsecond=0)``. ``enc_hook`` cannot be used here because ``datetime`` is a natively supported type. * - ``OPT_STRICT_INTEGER`` (53-bit) - Use ``Meta(ge=-(2**53 - 1), le=2**53 - 1)`` constraint * - ``OPT_PASSTHROUGH_DATACLASS`` - Not directly supported. ``dataclass`` is natively supported, so ``enc_hook`` is not called for it. Convert to a ``dict`` before encoding if you need custom serialization. * - ``OPT_PASSTHROUGH_SUBCLASS`` - Not applicable. ``msgspec`` always serializes subclasses of builtins as their parent type, with no option to redirect them to ``enc_hook``. .. _orjson: https://github.com/ijl/orjson python-msgspec-0.22.0/docs/schema-evolution.rst000066400000000000000000000052531525673062400215360ustar00rootroot00000000000000Schema Evolution ================ ``msgspec`` includes support for "schema evolution", meaning that: - Messages serialized with an older version of a schema will be deserializable using a newer version of the schema. - Messages serialized with a newer version of the schema will be deserializable using an older version of the schema. This can be useful if, for example, you have clients and servers with mismatched versions. For schema evolution to work smoothly, you need to follow a few guidelines: 1. Any new fields on a `msgspec.Struct` must specify default values. 2. Structs with ``array_like=True`` must not reorder fields, and any new fields must be appended to the end (and have defaults). 3. Don't change the type annotations for existing messages or fields. 4. Don't change the type codes or implementations for any defined :ref:`extensions ` (MessagePack only). For example, suppose we had a `msgspec.Struct` type representing a user: .. code-block:: python >>> import msgspec >>> class User(msgspec.Struct): ... """A struct representing a user""" ... name: str ... groups: set[str] = set() ... email: str | None = None Then suppose we wanted to add a new ``phone`` field to this struct in a way that wouldn't break clients/servers still using the prior definition. To accomplish this, we add ``phone`` as an _optional_ field (defaulting to ``None``), at the end of the struct. .. code-block:: python >>> class User2(msgspec.Struct): ... """An updated version of the User struct, now with a phone number""" ... name: str ... groups: set[str] = set() ... email: str | None = None ... phone : str | None = None Messages serialized using both the old and new schemas can still be exchanged without error. If an old message is deserialized using the new schema, the missing fields all have default values that will be used. Likewise, if a new message is deserialized with the old schema the unknown new fields will be efficiently skipped without decoding. .. code-block:: python >>> old_dec = msgspec.json.Decoder(User) >>> new_dec = msgspec.json.Decoder(User2) >>> new_msg = msgspec.json.encode( ... User2("bob", groups={"finance"}, phone="512-867-5309") ... ) >>> old_dec.decode(new_msg) # deserializing a new msg with an older decoder User(name='bob', groups={'finance'}, email=None) >>> old_msg = msgspec.json.encode( ... User("alice", groups={"admin", "engineering"}) ... ) >>> new_dec.decode(old_msg) # deserializing an old msg with a new decoder User2(name="alice", groups={"admin", "engineering"}, email=None, phone=None) python-msgspec-0.22.0/docs/structs.rst000066400000000000000000001136761525673062400177740ustar00rootroot00000000000000Structs ======= Structs are the preferred way of defining structured data types in ``msgspec``. They're written in C and are quite speedy and lightweight (:doc:`measurably faster ` to create/compare/encode/decode than similar options like dataclasses_, attrs_, or pydantic_). They're great for representing structured data both for serialization and for use in an application. Structs are defined by subclassing from `msgspec.Struct` and annotating the types of individual fields. Default values can also be provided for any optional arguments. Here we define a struct representing a user, with one required field and two optional fields. .. code-block:: python >>> import msgspec >>> class User(msgspec.Struct): ... """A struct describing a user""" ... name : str ... email : str | None = None ... groups : set[str] = set() - ``name`` is a *required* field expecting a `str` - ``email`` is an *optional* field expecting a `str` or `None`, defaulting to `None` if no value is provided. - ``groups`` is an *optional* field expecting a `set` of `str`. If no value is provided, it defaults to the empty set. Struct types automatically generate a few methods based on the provided type annotations: - ``__init__`` - ``__repr__`` - ``__copy__`` - ``__replace__`` - ``__eq__`` & ``__ne__`` - ``__match_args__`` (for Python 3.10+'s `pattern matching`_) - ``__rich_repr__`` (for pretty printing support with rich_) .. code-block:: python >>> alice = User("alice", groups={"admin", "engineering"}) >>> alice User(name='alice', email=None, groups={'admin', 'engineering'}) >>> bob = User("bob", email="bob@company.com") >>> bob User(name='bob', email='bob@company.com', groups=set()) >>> alice.name "alice" >>> bob.groups set() >>> alice == bob False >>> alice == User("alice", groups={"admin", "engineering"}) True Note that it is forbidden to override ``__init__`` / ``__new__`` in a struct definition, but other methods can be overridden or added as needed. If you need to customize the generated ``__init__``, see :ref:`struct-post-init`. The struct fields are available via the ``__struct_fields__`` attribute (a tuple of the fields in argument order ) if you need them. Here we add a method for converting a struct to a dict. .. code-block:: python >>> class Point(msgspec.Struct): ... """A point in 2D space""" ... x : float ... y : float ... ... def to_dict(self): ... return {f: getattr(self, f) for f in self.__struct_fields__} ... >>> p = Point(1.0, 2.0) >>> p.to_dict() {"x": 1.0, "y": 2.0} Default Values -------------- Struct fields may be given default values, which are used if no value is provided to ``__init__``, or when decoding a message. Default values are configured as part of a Struct definition by assigning them after a field's type annotation. .. code-block:: python >>> from msgspec import Struct, field >>> import uuid >>> class Example(Struct): ... a: int = 1 ... b: uuid.UUID = field(default_factory=uuid.uuid4) ... c: list[int] = [] >>> Example() Example(a=1, b=UUID('f63219d5-e9ca-4ae8-afd0-cba30e84222d'), c=[]) >>> Example(a=2) Example(a=2, b=UUID('319a6c0f-2841-4439-8bc8-2c1daf7d77a2'), c=[]) >>> Example().c is Example().c # new list instance used each time False Default values may be one of 3 kinds: - A "static" default value. Here the same default value is used for all instances. These are specified by assigning the default value itself as part of the field definition (as in ``a`` above). Most default values will be of this variety. - A "dynamic" default value. Here a new default value is used for every instance. These are specified by passing a 0-argument callable to the ``default_factory`` argument of `msgspec.field` (as in ``b`` above). This function will be called as needed to create a new default value per instance. These are mainly useful for occasions where you need dynamic defaults, or when a default value is a mutable object that you don't want to share between all instances of the struct (a `common gotcha `_ in Python). Note that since the ``default_factory`` callables take no arguments, you might need to make use of a lambda_ or `functools.partial` to forward any additional parameters needed to the default factory. - Builtin *empty* mutable collections (``[]``, ``{}``, ``set()``, and ``bytearray()``) may be used as default values (as in ``c`` above). Since defaults of these types are so common, these are "syntactic sugar" for specifying the corresponding ``default_factory`` (to avoid accidental sharing of mutable values). A default of ``[]`` is identical to a default of ``field(default_factory=list)``, with a new list instance used each time. Specifying a non-empty mutable collection (e.g. ``[1, 2, 3]``) as a default value will cause the struct definition to error (you should manually define a ``default_factory`` in this case). .. _struct-post-init: Post-Init Processing -------------------- If a struct type defines a ``__post_init__(self)`` method, this will be called at the end of the generated ``__init__`` method. It has the same semantics as the ``dataclasses`` method `of the same name `__. This method may be useful for adding additional logic to the init (such as custom validation). In addition to in ``__init__``, the ``__post_init__`` hook is also called when: - Decoding into a struct type (e.g. ``msgspec.json.decode(..., type=MyStruct)``) - Converting into a struct type (e.g. ``msgspec.convert(..., type=MyStruct)``) In these cases any `TypeError` or `ValueError` exceptions raised by this method will be considered "user facing" and converted into a `msgspec.ValidationError` with additional context. All other exceptions will be raised directly. .. code-block:: python >>> import msgspec >>> class Interval(msgspec.Struct): ... low: float ... high: float ... ... def __post_init__(self): ... if self.low > self.high: ... raise ValueError("`low` may not be greater than `high`") >>> Interval(1, 2) # valid interval Interval(low=1, high=2) >>> Interval(2, 1) # invalid interval Traceback (most recent call last): File "", line 1, in File "", line 6, in __post_init__ ValueError: `low` may not be greater than `high` >>> msgspec.json.decode(b'{"low": 2, "high": 1}', type=Interval) # invalid interval from JSON Traceback (most recent call last): File "", line 6, in __post_init__ ValueError: `low` may not be greater than `high` The above exception was the direct cause of the following exception: Traceback (most recent call last): File "", line 1, in msgspec.ValidationError: `low` may not be greater than `high` .. _struct-field-ordering: Field Ordering -------------- When defining a new struct type, fields are stored in the order they're defined (keyword-only fields excluded, more on this later). This is nice for readability since the generated ``__init__`` matches the field order. .. code-block:: python class Example(msgspec.Struct): a: str b: int = 0 The generated ``__init__()`` for ``User`` looks like: .. code-block:: python def __init__(self, a: str, b: int = 0): One consequence of this is that you can't put fields without defaults after fields with defaults, since the Python VM doesn't allow keyword arguments before positional arguments. The following struct definition will error: .. code-block:: python >>> class Invalid(msgspec.Struct): ... a: str = "" ... b: int # oop, no default! Traceback (most recent call last): File "", line 1, in TypeError: Required field 'b' cannot follow optional fields. Either reorder the struct fields, or set `kw_only=True` in the struct definition. Thankfully the error message includes some solutions: - Reorder the struct fields, putting all required fields before all optional fields. - Set ``kw_only=True`` in the struct definition. This option makes all fields defined on the struct `keyword-only parameters`_. Keyword-only parameters have no such restriction; required and optional parameters can be mixed in any order. .. code-block:: python >>> class Example(msgspec.Struct, kw_only=True): ... a: str = "" ... b: int # this is fine with kw_only=True >>> Example(a="example", b=123) Example(a='example', b=123) Note that the ``kw_only`` setting only affects fields defined on that class, *not* those defined on base or subclasses. This means you can define keyword-only parameters on a base class then add positional parameters in a subclass. All keyword-only parameters are reordered to go after all positional fields. .. code-block:: python >>> class Base(msgspec.Struct, kw_only=True): ... a: str = "" ... b: int >>> class Subclass(Base): ... c: float ... d: bytes = b"" The generated ``__init__()`` for ``Subclass`` looks like: .. code-block:: python def __init__(self, c: float, d: bytes = b"", *, a: str, b: int = 0): The field ordering rules for ``Struct`` types are identical to those for `dataclasses`, see the `dataclasses docs `_ for more information. Class Variables --------------- Like `dataclasses`, `msgspec.Struct` types will exclude any attribute annotations wrapped in `typing.ClassVar` from their fields. .. code-block:: python >>> import msgspec >>> from typing import ClassVar >>> class Example(msgspec.Struct): ... x: int ... a_class_variable: ClassVar[int] = 2 >>> Example.a_class_variable 2 >>> Example(1) # only `x` is counted as a field Example(x=1) Note that if using `PEP 563`_ "postponed evaluation of annotations" (e.g. ``from __future__ import annotations``) only the following spellings will work: - ``ClassVar`` or ``ClassVar[]`` - ``typing.ClassVar`` or ``typing.ClassVar[]`` Importing ``ClassVar`` or ``typing`` under an aliased name (e.g. ``import typing as typ`` or ``from typing import ClassVar as CV``) will not be properly detected. Type Validation --------------- Unlike some other libraries (e.g. pydantic_), the type annotations on a `msgspec.Struct` class are not checked at runtime during normal use. Types are only checked when *decoding* a serialized message when using a `typed decoder `. .. code-block:: python >>> import msgspec >>> class Point(msgspec.Struct): ... x: float ... y: float >>> # Improper types in *your* code aren't checked at runtime ... Point(x=1, y="oops") Point(x=1, y='oops') >>> # Improper types when decoding *are* checked at runtime ... msgspec.json.decode(b'{"x": 1.0, "y": "oops"}', type=Point) Traceback (most recent call last): File "", line 1, in msgspec.ValidationError: Expected `float`, got `str` - at `$.y` This is intentional. Static type checkers like mypy_/pyright_ work well with ``msgspec``, and can be used to catch bugs without ever running your code. When possible, static tools or unit tests should be preferred over adding expensive runtime checks which slow down every ``__init__`` call. The input(s) to your programs however cannot be checked statically, as they aren't known until runtime. As such, ``msgspec`` does perform type validation when decoding messages (provided an expected decode type is provided). This validation is fast enough that it is *negligible in cost* - there is no added performance benefit when not using it. In fact, in most cases it's faster to decode a message into a type validated `msgspec.Struct` than into an untyped `dict`. Pattern Matching ---------------- If using Python 3.10+, `msgspec.Struct` types can be used in `pattern matching`_ blocks. Replicating an example from `PEP 636`_: .. code-block:: python # NOTE: this example requires Python 3.10+ >>> import msgspec >>> class Point(msgspec.Struct): ... x: float ... y: float >>> def where_is(point): ... match point: ... case Point(0, 0): ... print("Origin") ... case Point(0, y): ... print(f"Y={y}") ... case Point(x, 0): ... print(f"X={x}") ... case Point(): ... print("Somewhere else") ... case _: ... print("Not a point") >>> where_is(Point(0, 6)) "Y=6" Equality and Order ------------------ By default struct types define an ``__eq__`` method based on the type definition. This enables support for equality comparisons. Additionally, you may configure ``order=True`` to make a struct type *orderable* through generation of ``__lt__``, ``__le__``, ``__gt__``, and ``__ge__`` methods. These methods compare and order instances of a struct type the same as if they were tuples of their field values (in definition order). .. code-block:: python >>> class Point(msgspec.Struct, order=True): ... x: float ... y: float >>> Point(1, 2) == Point(1, 2) True >>> Point(1, 2) < Point(3, 4) True In *rare* instances you may opt to disable generation of the ``__eq__`` method by configuring ``eq=False``. Equality checks will then fall back to *identity comparisons*, where the only value a struct instance of that type will compare equal to is itself. .. code-block:: python >>> class Point(msgspec.Struct, eq=False): ... x: float ... y: float >>> p = Point(1, 2) >>> p == Point(1, 2) False >>> p == p # identity comparison only True Frozen Instances ---------------- A struct type can optionally be marked as "frozen" by specifying ``frozen=True``. This disables modifying attributes after initialization, and adds a ``__hash__`` method to the class definition. Note that for the ``__hash__`` to work, all fields on the struct must also be hashable. .. code-block:: python >>> class Point(msgspec.Struct, frozen=True): ... """This struct is immutable & hashable""" ... x: float ... y: float ... >>> p = Point(1.0, 2.0) >>> {p: 1} # frozen structs are hashable, and can be keys in dicts {Point(1.0, 2.0): 1} >>> p.x = 2.0 # frozen structs cannot be modified after creation Traceback (most recent call last): ... AttributeError: immutable type: 'Point' .. _struct-tagged-unions: Tagged Unions ------------- By default a serialized struct only contains information on the *values* present in the struct instance - no information is serialized noting which struct type corresponds to the message. Instead, the user is expected to know the type the message corresponds to, and pass that information appropriately to the decoder. .. code-block:: python >>> import msgspec >>> class Get(msgspec.Struct): ... key: str >>> msg = msgspec.json.encode(Get("my key")) >>> msg # No type information present in the message b'{"key":"my key"}' >>> msgspec.json.decode(msg, type=Get) Get(key='my key') In most cases this works well - schemas are often simple and each value may only correspond to at most one Struct type. However, sometimes you may have a message (or a field in a message) that may contain one of a number of different structured types. In this case we need some way to determine the type of the message from the message itself! ``msgspec`` handles this through the use of `Tagged Unions`_. A new field (the "tag field") is added to the serialized representation of all struct types in the union. Each struct type associates a different value (the "tag") with this field. When the decoder encounters a tagged union it decodes the tag first and uses it to determine the type to use when decoding the rest of the object. This process is efficient and makes determining the type of a serialized message unambiguous. The quickest way to enable tagged unions is to set ``tag=True`` when defining every struct type in the union. In this case ``tag_field`` defaults to ``"type"``, and ``tag`` defaults to the struct class name (e.g. ``"Get"``). .. code-block:: python >>> import msgspec >>> from typing import Union >>> # Pass in ``tag=True`` to tag the structs using the default configuration ... class Get(msgspec.Struct, tag=True): ... key: str >>> class Put(msgspec.Struct, tag=True): ... key: str ... val: str >>> msg = msgspec.json.encode(Get("my key")) >>> msg # "type" is the tag field, "Get" is the tag b'{"type":"Get","key":"my key"}' >>> # Create a decoder for decoding either Get or Put ... dec = msgspec.json.Decoder(Get | Put) >>> # The tag value is used to determine the message type ... dec.decode(b'{"type": "Put", "key": "my key", "val": "my val"}') Put(key='my key', val='my val') >>> dec.decode(b'{"type": "Get", "key": "my key"}') Get(key='my key') >>> # A tagged union can also contain non-struct types. ... msgspec.json.decode( ... b'123', ... type=Get | Put | int, ... ) 123 If you want to change this behavior to use a different tag field and/or value, you can further configure things through the ``tag_field`` and ``tag`` kwargs. A struct's tagging configuration is determined as follows. - If ``tag`` and ``tag_field`` are ``None`` (the default), or ``tag=False``, then the struct is considered "untagged". The struct is serialized with only its standard fields, and cannot participate in ``Union`` types with other structs. - If either ``tag`` or ``tag_field`` are non-None, then the struct is considered "tagged". The struct is serialized with an additional field (the ``tag_field``) mapping to its corresponding ``tag`` value. It can participate in ``Union`` types with other structs, provided they all share the same ``tag_field`` and have unique ``tag`` values. - If a struct is tagged, ``tag_field`` defaults to ``"type"`` if not provided or inherited. This can be overridden by passing a tag field explicitly (e.g. ``tag_field="kind"``). Note that ``tag_field`` must not conflict with any other field names in the struct, and must be the same for all struct types in a union. - If a struct is tagged, ``tag`` defaults to the class name (e.g. ``"Get"``) if not provided or inherited. This can be overridden by passing a string (or less commonly an integer) value explicitly (e.g. ``tag="get"``). ``tag`` can also be passed a callable that takes the class qualname and returns a valid tag value (e.g. ``tag=str.lower``). Note that tag values must be unique for all struct types in a union, and ``str`` and ``int`` tag types cannot both be used within the same union. If you like subclassing, both ``tag_field`` and ``tag`` are inheritable by subclasses, allowing configuration to be set once on a base class and reused for all struct types you wish to tag. .. code-block:: python >>> import msgspec >>> from typing import Union >>> # Create a base class for tagged structs, where: ... # - the tag field is "op" ... # - the tag is the class name lowercased ... class TaggedBase(msgspec.Struct, tag_field="op", tag=str.lower): ... pass >>> # Use the base class to pass on the configuration ... class Get(TaggedBase): ... key: str >>> class Put(TaggedBase): ... key: str ... val: str >>> msg = msgspec.json.encode(Get("my key")) >>> msg # "op" is the tag field, "get" is the tag b'{"op":"get","key":"my key"}' >>> # Create a decoder for decoding either Get or Put ... dec = msgspec.json.Decoder(Get | Put) >>> # The tag value is used to determine the message type ... dec.decode(b'{"op": "put", "key": "my key", "val": "my val"}') Put(key='my key', val='my val') >>> dec.decode(b'{"op": "get", "key": "my key"}') Get(key='my key') .. _omit_defaults: Omitting Default Values ----------------------- By default, ``msgspec`` encodes all fields in a Struct type, including optional fields (those configured with a default value). .. code-block:: python >>> import msgspec >>> class User(msgspec.Struct): ... name : str ... email : str | None = None ... groups : set[str] = set() >>> alice = User("alice") >>> alice # email & groups are using the default values User(name='alice', email=None, groups=set()) >>> msgspec.json.encode(alice) # default values are present in encoded message b'{"name":"alice","email":null,"groups":[]}' If the default values are known on the decoding end (making serializing them redundant), it may be beneficial and desired to omit default values from the encoded message. This can be done by configuring ``omit_defaults=True`` as part of the Struct definition: .. code-block:: python >>> import msgspec >>> class User(msgspec.Struct, omit_defaults=True): ... name : str ... email : str | None = None ... groups : set[str] = set() >>> alice = User("alice") >>> msgspec.json.encode(alice) # default values are omitted b'{"name":"alice"}' >>> bob = User("bob", email="bob@company.com") >>> msgspec.json.encode(bob) b'{"name":"bob","email":"bob@company.com"}' Omitting defaults reduces the size of the encoded message, and often also improves encoding and decoding performance (since there's less work to do). ``omit_defaults`` affects `msgspec.json.encode`, `msgspec.msgpack.encode`, `msgspec.yaml.encode`, `msgspec.toml.encode`, and `msgspec.to_builtins`. It has no effect on `msgspec.structs.asdict` or `msgspec.structs.astuple`, which always include every field - see :ref:`to-builtins-vs-asdict`. Note that detection of default values is optimized for performance; in certain situations a default value may still be encoded. For the curious, the current detection logic is as follows: .. code-block:: python >>> def matches_default(value: Any, default: Any) -> bool: ... """Whether a value matches the default for a field""" ... if value is default: ... return True ... if type(value) != type(default): ... return False ... if type(value) in (list, set, dict) and (len(value) == len(default) == 0): ... return True ... return False This detection never calls a ``default_factory``. A field configured with a custom ``default_factory`` is only omitted when the factory is one of the builtin collection constructors (``list``, ``dict``, ``set``, ``tuple``, or ``frozenset``). Any other callable (a user-defined function, a ``lambda``, or a ``Struct``/``dataclass``/``attrs`` type) is treated as opaque, so the field is always encoded, even when the value it produces is empty. To omit an empty collection default, configure the builtin constructor directly: .. code-block:: python >>> class Basket(msgspec.Struct, omit_defaults=True): ... items: list[int] = msgspec.field(default_factory=list) The field annotation supplies the element type, so ``default_factory=list`` still type checks. Specifying ``default=[]`` works too: ``msgspec`` doesn't share mutable default values between instances. .. _forbid-unknown-fields: Forbidding Unknown Fields ------------------------- By default ``msgspec`` will skip unknown fields encountered when decoding into ``Struct`` types. This is normally desired, as it allows for :doc:`schema-evolution` and more flexible decoding. One downside is that typos may go unnoticed when decoding ``Struct`` types with optional fields. For example: .. code-block:: python >>> class Example(msgspec.Struct): ... field_one: int ... field_two: bool = False >>> msgspec.json.decode( ... b'{"field_one": 1, "field_twoo": true}', # oops, a typo ... type=Example ... ) Example(field_one=1, field_two=False) In this example, the misspelled ``"field_twoo"`` is ignored since no field with that name exists. Since ``field_two`` has a default value, the default is used and no error is raised for a missing field. To prevent typos like this, you can configure ``forbid_unknown_fields=True`` as part of the struct definition. If this option is enabled, any unknown fields encountered will result in an error. .. code-block:: python >>> class Example(msgspec.Struct, forbid_unknown_fields=True): ... field_one: int ... field_two: bool = False >>> msgspec.json.decode( ... b'{"field_one": 1, "field_twoo": true}', # oops, a typo ... type=Example ... ) Traceback (most recent call last): File "", line 1, in msgspec.ValidationError: Object contains unknown field `field_twoo` Renaming Fields --------------- Sometimes you want the field name used in the encoded message to differ from the name used by your Python code. Perhaps you want a ``camelCase`` naming convention in your JSON messages, but to use ``snake_case`` field names in Python. ``msgspec`` supports two places for configuring a field's name used for encoding/decoding: **On the field definition** If you're only renaming a few fields, you might find configuring the new names as part of the field definition to be the simplest option. To do this you can use the ``name`` argument in `msgspec.field`. Any fields declared with this option will use the new name for encoding/decoding. .. code-block:: python >>> import msgspec >>> class Example(msgspec.Struct): ... x: int ... y: int ... z: int = msgspec.field(name="field_z") # renamed to "field_z" >>> # Python code uses the original field names ... ex = Example(x=1, y=2, z=3) >>> # Encoded messages use the renamed field names ... msgspec.json.encode(ex) b'{"x":1,"y":2,"field_z":3}' >>> # Decoding also uses the renamed field names ... msgspec.json.decode(b'{"x": 1, "y": 2, "field_z": 3}', type=Example) Example(x=1, y=2, z=3) **On the struct definition** If you're renaming lots of fields (especially if you're renaming them with a naming convention like ``camelCase``), you may wish to make use of the ``rename`` configuration option in the `Struct` definition instead. This can take a few different values: - ``None``: the default, no field renaming (``example_field``) - ``"lower"``: lowercase all fields (``example_field``) - ``"upper"``: uppercase all fields (``EXAMPLE_FIELD``) - ``"camel"``: camelCase all fields (``exampleField``) - ``"pascal"``: PascalCase all fields (``ExampleField``) - A mapping from field names to the renamed names. Field names missing from the mapping will not be renamed. - A callable (signature ``rename(name: str) -> str | None``) to use to rename all field names. Note that ``None`` for a return value indicates the original field name should be used. The renamed field names are used for encoding and decoding only, any python code will still refer to them using their original names. .. code-block:: python >>> import msgspec >>> class Example(msgspec.Struct, rename="camel"): ... """A struct with fields renamed using camelCase""" ... field_one: int ... field_two: str >>> # Python code uses the original field names ... ex = Example(1, field_two="two") >>> # Encoded messages use the renamed field names ... msgspec.json.encode(ex) b'{"fieldOne":1,"fieldTwo":"two"}' >>> # Decoding uses the renamed field names ... msgspec.json.decode(b'{"fieldOne": 3, "fieldTwo": "four"}', type=Example) Example(field_one=3, field_two='four') >>> # Decoding errors also use the renamed field names ... msgspec.json.decode(b'{"fieldOne": 5}', type=Example) Traceback (most recent call last): File "", line 1, in msgspec.ValidationError: Object missing required field `fieldTwo` If renaming to camelCase, you may run into issues if your field names contain acronyms (e.g. ``FQDN`` in ``setHostnameAsFQDN``). Some JSON style guides prefer to fully-uppercase these components (``FQDN``), but ``msgspec`` has no way to know if a component is an acronym or not (and so will result in ``Fqdn``). As such, we recommend using an explicit dict mapping for renaming if generating `Struct` types to match an existing API. .. code-block:: python # https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#PodSpec # An explicit mapping from python name -> JSON field name v1podspec_names = { ... "service_account_name": "serviceAccountName", "set_hostname_as_fqdn": "setHostnameAsFQDN", ... } # Pass the mapping to `rename` to explicitly rename all fields class V1PodSpec(msgspec.Struct, rename=v1podspec_names): ... service_account_name: str = "" set_hostname_as_fqdn: bool = False ... Note that if both the ``rename`` configuration option and the ``name`` arg to `msgspec.field` are used, names set explicitly via `msgspec.field` take precedence. .. code-block:: python >>> import msgspec >>> class Example(msgspec.Struct, rename="camel"): ... field_x: int ... field_y: int = msgspec.field(name="y") # set explicitly >>> msgspec.json.encode(Example(1, 2)) b'{"fieldX":1,"y":2}' Encoding/Decoding as Arrays --------------------------- By default Struct objects encode the same dicts, with both the keys and values present in the message. .. code-block:: python >>> import msgspec >>> class Point(msgspec.Struct): ... x: int ... y: int >>> msgspec.json.encode(Point(1, 2)) b'{"x":1,"y":2}' If you need higher performance (at the cost of more inscrutable message encoding), you can set ``array_like=True`` on a struct definition. Structs with this option enabled are encoded/decoded as array-like types, removing the field names from the encoded message. This can provide on average another ~2x speedup for decoding (and ~1.5x speedup for encoding). .. code-block:: python >>> class Point2(msgspec.Struct, array_like=True): ... x: int ... y: int >>> msgspec.json.encode(Point2(1, 2)) b'[1,2]' >>> msgspec.json.decode(b'[3,4]', type=Point2) Point2(x=3, y=4) Note that :ref:`struct-tagged-unions` also work with structs with ``array_like=True``. In this case the tag is encoded as the first item in the array, and is used to determine which type in the union to use when decoding. .. code-block:: python >>> import msgspec >>> from typing import Union >>> class Get(msgspec.Struct, tag=True, array_like=True): ... key: str >>> class Put(msgspec.Struct, tag=True, array_like=True): ... key: str ... val: str >>> msgspec.json.encode(Get("my key")) b'["Get","my key"]' >>> msgspec.json.decode( ... b'["Put", "my key", "my val"]', ... type=Get | Put, ... ) Put(key='my key', val='my val') Runtime Definition ------------------ In some cases it can be useful to dynamically generate `msgspec.Struct` classes at runtime. This can be handled through the use of `msgspec.defstruct`, which has a signature similar to `dataclasses.make_dataclass`. See `msgspec.defstruct` for more information. .. code-block:: python >>> import msgspec >>> Point = msgspec.defstruct("Point", [("x", float), ("y", float)]) >>> p = Point(1.0, 2.0) >>> p Point(x=1.0, y=2.0) Advanced -------- Metaclasses ~~~~~~~~~~~ You can define project-wide :class:`msgspec.Struct` policies at class-creation time by extending the :class:`msgspec.StructMeta` metaclass. In the following example, we flip the default value of ``kw_only`` to ``True`` in all subclasses of ``KwOnlyStruct``. .. code-block:: python >>> from msgspec import Struct, StructMeta >>> class KwOnlyStructMeta(StructMeta): ... def __new__(mcls, name, bases, namespace, **struct_config): ... struct_config.setdefault("kw_only", True) ... return super().__new__(mcls, name, bases, namespace, **struct_config) >>> class KwOnlyStruct(Struct, metaclass=KwOnlyStructMeta): ... >>> class Example(KwOnlyStruct): ... a: str = "" ... b: int >>> Example() Traceback (most recent call last): File "", line 1, in Example() ~~~~~~~^^ TypeError: Missing required argument 'b' >>> Example(b=123) Example(a='', b=123) You can also mix :class:`msgspec.StructMeta` with other metaclasses. One common use case is combining it with :class:`abc.ABCMeta` to define abstract base Structs. .. code-block:: python >>> from abc import ABCMeta, abstractmethod >>> from msgspec import Struct, StructMeta >>> class EventMeta(StructMeta, ABCMeta): ... >>> class Event(Struct, metaclass=EventMeta): ... id: int ... @abstractmethod ... def kind(self) -> str: ... ... >>> Event(id=1) Traceback (most recent call last): File "", line 1, in Event(id=1) ~~~~~^^^^^^ TypeError: Can't instantiate abstract class Event without an implementation for abstract method 'kind' >>> class UserCreated(Event): ... username: str ... def kind(self) -> str: ... return "user_created" ... >>> UserCreated(id=1, username="alice") UserCreated(id=1, username='alice') Here :class:`msgspec.Struct` participates fully in the ABC machinery: abstract base Structs (like ``Event``) cannot be instantiated, and :func:`isinstance` and :func:`issubclass` checks behave the same as for normal ABCs. .. important:: - Classes with a :class:`msgspec.StructMeta`-derived metaclass do not *technically* need to inherit from :class:`msgspec.Struct`, but it is recommended to do so for static typing support in IDEs and other tools. - Mixing :class:`msgspec.StructMeta` with arbitrary metaclasses is not supported. Only combinations involving :class:`abc.ABCMeta` (or its subclasses) are guaranteed to work. Prefer using :meth:`object.__init_subclass__` on a :class:`msgspec.Struct` base class instead of additional custom metaclasses. .. _struct-gc: Disabling Garbage Collection ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. warning:: This is an advanced optimization, and only recommended for users who fully understand the implications of disabling the GC. Python uses `reference counting`_ to detect when memory can be freed, with a periodic `cyclic garbage collector`_ pass to detect and free cyclic references. Garbage collection (GC) is triggered by the number of uncollected GC-enabled (objects that contain other objects) objects passing a certain threshold. This design means that garbage collection passes often run during code that creates a lot of objects (for example, deserializing a large message). By default, `msgspec.Struct` types will only be tracked if they contain a reference to a tracked object themselves. This means that structs referencing only scalar values (ints, strings, bools, ...) won't contribute to GC load, but structs referencing containers (lists, dicts, structs, ...) will. .. code-block:: python >>> import msgspec >>> from typing import Any >>> import gc >>> class Example(msgspec.Struct): ... x: Any ... y: Any >>> ex1 = Example(1, "two") >>> # ex1 is untracked, since it only references untracked objects ... gc.is_tracked(ex1) False >>> ex2 = Example([1, 2, 3], (4, 5, 6)) >>> # ex2 is tracked, since it references tracked objects ... gc.is_tracked(ex2) True If you *are certain* that your struct types can *never* participate in a reference cycle, you *may* find a :ref:`performance boost ` from setting ``gc=False`` on a struct definition. This boost is tricky to measure in isolation, since it should only result in the garbage collector not running as frequently - an integration benchmark is recommended to determine if this is worthwhile for your workload. A workload is likely to benefit from this optimization in the following situations: - You're allocating a lot of struct objects at once (for example, decoding a large object). Setting ``gc=False`` on these types will reduce the likelihood of a GC pass occurring while decoding, improving application latency. - You have a large number of long-lived struct objects. Setting ``gc=False`` on these types will reduce the load on the GC during collection cycles of later generations. Struct types with ``gc=False`` will never be tracked, even if they reference container types. It is your responsibility to ensure cycles with these objects don't occur, as a cycle containing only ``gc=False`` structs will *never* be collected (leading to a memory leak). ``gc=False`` cannot be combined with a weakref slot, whether that slot comes from ``weakref=True`` or from a base class. Setting both raises ``ValueError`` at class creation. On Python 3.12 and later such a slot is stored in a pre-header in front of the instance, and disabling garbage collection for the type makes releasing an instance unsafe. .. _type annotations: https://docs.python.org/3/library/typing.html .. _pattern matching: https://docs.python.org/3/reference/compound_stmts.html#the-match-statement .. _PEP 636: https://peps.python.org/pep-0636/ .. _PEP 563: https://peps.python.org/pep-0563/ .. _dataclasses: https://docs.python.org/3/library/dataclasses.html .. _attrs: https://www.attrs.org/en/stable/index.html .. _pydantic: https://pydantic.dev/docs/validation/latest/get-started/ .. _mypy: https://mypy.readthedocs.io/en/stable/ .. _pyright: https://github.com/microsoft/pyright .. _reference counting: https://en.wikipedia.org/wiki/Reference_counting .. _cyclic garbage collector: https://github.com/python/cpython/blob/main/InternalDocs/garbage_collector.md .. _tagged unions: https://en.wikipedia.org/wiki/Tagged_union .. _rich: https://rich.readthedocs.io/en/stable/pretty.html .. _keyword-only parameters: https://docs.python.org/3/glossary.html#term-parameter .. _lambda: https://docs.python.org/3/tutorial/controlflow.html#lambda-expressions .. _metaclass: https://docs.python.org/3/reference/datamodel.html#metaclasses python-msgspec-0.22.0/docs/supported-types.rst000066400000000000000000001503411525673062400214420ustar00rootroot00000000000000Supported Types =============== ``msgspec`` uses Python `type annotations`_ to describe the expected types. Most combinations of the following types are supported (with a few restrictions): **Builtin Types** - `None` - `bool` - `int` - `float` - `str` - `bytes` - `bytearray` - `tuple` / `typing.Tuple` - `list` / `typing.List` - `dict` / `typing.Dict` - `set` / `typing.Set` - `frozenset` / `typing.FrozenSet` - `frozendict `__ for Python 3.15+ **Msgspec types** - `msgspec.msgpack.Ext` - `msgspec.Raw` - `msgspec.UNSET` - `msgspec.Struct` types **Standard Library Types** - `datetime.datetime` - `datetime.date` - `datetime.time` - `datetime.timedelta` - `uuid.UUID` - `decimal.Decimal` - `enum.Enum` types - `enum.IntEnum` types - `enum.StrEnum` types - `enum.Flag` types - `enum.IntFlag` types - `dataclasses.dataclass` types **Typing module types** - `typing.Any` - `typing.Optional` - `typing.Union` - `typing.Literal` - `typing.NewType` - `typing.Final` - `typing.TypeAliasType` - `typing.TypeAlias` - `typing.NamedTuple` / `collections.namedtuple` - `typing.TypedDict` - `typing.Generic` - `typing.TypeVar` **Abstract types** - `collections.abc.Collection` / `typing.Collection` - `collections.abc.Sequence` / `typing.Sequence` - `collections.abc.MutableSequence` / `typing.MutableSequence` - `collections.abc.Set` / `typing.AbstractSet` - `collections.abc.MutableSet` / `typing.MutableSet` - `collections.abc.Mapping` / `typing.Mapping` - `collections.abc.MutableMapping` / `typing.MutableMapping` **Third-Party Libraries** - attrs_ types Additional types may be supported through :doc:`extensions `. Note that except where explicitly stated, subclasses of these types are not supported by default (see :doc:`extending` for how to add support yourself). Here we document how msgspec maps Python objects to/from the various supported protocols. ``None`` -------- `None` maps to the ``null`` value in all supported protocols. Note that TOML_ lacks a ``null`` value, attempting to encode a message containing ``None`` to ``TOML`` will result in an error. .. code-block:: python >>> msgspec.json.encode(None) b'null' >>> msgspec.json.decode(b'null') None If ``strict=False`` is specified, a string value of ``"null"`` (case insensitive) may also be coerced to ``None``. See :ref:`strict-vs-lax` for more information. .. code-block:: python >>> msgspec.json.decode(b'"null"', type=None, strict=False) None ``bool`` -------- Booleans map to their corresponding ``true`` / ``false`` values in both all supported protocols. .. code-block:: python >>> msgspec.json.encode(True) b'true' >>> msgspec.json.decode(b'true') True If ``strict=False`` is specified, values of ``"true"`` / ``"1"`` / ``1`` or ``"false"`` / ``"0"`` / ``0`` (case insensitive for strings) may also be coerced to ``True`` / ``False`` respectively. See :ref:`strict-vs-lax` for more information. .. code-block:: python >>> msgspec.json.decode(b'"false"', type=bool, strict=False) False >>> msgspec.json.decode(b'"TRUE"', type=bool, strict=False) True >>> msgspec.json.decode(b'1', type=bool, strict=False) True ``int`` ------- Integers map to integers in all supported protocols. Support for large integers varies by protocol: - ``msgpack`` only supports encoding/decoding integers within ``[-2**63, 2**64 - 1]``, inclusive. - ``json``, ``yaml``, and ``toml`` have no restrictions on encode or decode. .. code-block:: python >>> msgspec.json.encode(123) b"123" >>> msgspec.json.decode(b"123", type=int) 123 If ``strict=False`` is specified, string values may also be coerced to integers, following the same restrictions as above. Likewise floats that have an exact integer representation (i.e. no decimal component) may also be coerced as integers. See :ref:`strict-vs-lax` for more information. .. code-block:: python >>> msgspec.json.decode(b'"123"', type=int, strict=False) 123 >>> msgspec.json.decode(b'123.0', type=int, strict=False) 123 ``float`` --------- Floats map to floats in all supported protocols. Note that per RFC8259_, JSON doesn't support nonfinite numbers (``nan``, ``infinity``, ``-infinity``); ``msgspec.json`` handles this by encoding these values as ``null``. The ``msgpack``, ``toml``, and ``yaml`` protocols lack this restriction, and can accurately roundtrip any IEEE754 64 bit floating point value. For all protocols, if a `float` type is specified and an `int` value is provided, the `int` will be automatically converted. .. code-block:: python >>> msgspec.json.encode(123.0) b"123.0" >>> # JSON doesn't support nonfinite values, these serialize as null ... msgspec.json.encode(float("nan")) b"null" >>> msgspec.json.decode(b"123.0", type=float) 123.0 >>> # Ints are automatically converted to floats ... msgspec.json.decode(b"123", type=float) 123.0 If ``strict=False`` is specified, string values may also be coerced to floats. Note that in this case the strings ``"nan"``, ``"inf"`` / ``"infinity"``, ``"-inf"`` / ``"-infinity"`` (case insensitive) will coerce to ``nan`` / ``inf`` / ``-inf``. See :ref:`strict-vs-lax` for more information. .. code-block:: python >>> msgspec.json.decode(b'"123.45"', type=float, strict=False) 123.45 >>> msgspec.json.decode(b'"-inf"', type=float, strict=False) -inf ``str`` ------- Strings map to strings in all supported protocols. Note that for JSON, only the characters required by RFC8259_ are escaped to ascii; unicode characters (e.g. ``"�"``) are *not* escaped and are serialized directly as UTF-8 bytes. .. code-block:: python >>> msgspec.json.encode("Hello, world!") b'"Hello, world!"' >>> msgspec.json.encode("� is not escaped") b'"\xf0\x9d\x84\x9e is not escaped"' >>> msgspec.json.decode(b'"Hello, world!"') "Hello, world!" ``bytes`` / ``bytearray`` / ``memoryview`` ------------------------------------------ Bytes-like objects map to base64-encoded strings in JSON, YAML, and TOML. The ``bin`` type is used for MessagePack. .. code-block:: python >>> msg = msgspec.json.encode(b"\xf0\x9d\x84\x9e") >>> msg b'"85+Eng=="' >>> msgspec.json.decode(msg, type=bytes) b'\xf0\x9d\x84\x9e' >>> msgspec.json.decode(msg, type=bytearray) bytearray(b'\xf0\x9d\x84\x9e') .. note:: For the ``msgpack`` protocol, `memoryview` objects will be decoded as direct views into the larger buffer containing the input message being decoded. This may be useful for implementing efficient zero-copy handling of large binary messages, but is also a potential footgun. As long as a decoded ``memoryview`` remains in memory, the input message buffer will also be persisted, potentially resulting in unnecessarily large memory usage. The usage of ``memoryview`` types in this manner is considered an advanced topic, and should only be used when you know their usage will result in a performance benefit. For all other protocols `memoryview` objects will still result in a copy, and will likely be slightly slower than decoding into a `bytes` object ``datetime`` ------------ The encoding used for `datetime.datetime` objects depends on both the protocol and whether these objects are timezone-aware_ or timezone-naive: - **JSON**: Timezone-aware datetimes are encoded as RFC3339_ compatible strings. Timezone-naive datetimes are encoded the same, but lack the timezone component (making them not strictly RFC3339_ compatible, but still ISO8601_ compatible). - **MessagePack**: Timezone-aware datetimes are encoded using the `timestamp extension`. Timezone-naive datetimes are encoded the same, but lack the timezone component (making them not strictly RFC3339_ compatible, but still ISO8601_ compatible). During decoding, both string and timestamp-extension values are supported for flexibility. - **YAML**: Datetimes are encoded using YAML's native datetime type. Both timezone-aware and timezone-naive datetimes are supported. - **TOML**: Datetimes are encoded using TOML's native datetime type. Both timezone-aware and timezone-naive datetimes are supported. Note that you can require a `datetime.datetime` object to be timezone-aware or timezone-naive by specifying a ``tz`` constraint (see :ref:`datetime-constraints` for more information). .. code-block:: python >>> import datetime >>> tz = datetime.timezone(datetime.timedelta(hours=6)) >>> tz_aware = datetime.datetime(2021, 4, 2, 18, 18, 10, 123, tzinfo=tz) >>> msg = msgspec.json.encode(tz_aware) >>> msg b'"2021-04-02T18:18:10.000123+06:00"' >>> msgspec.json.decode(msg, type=datetime.datetime) datetime.datetime(2021, 4, 2, 18, 18, 10, 123, tzinfo=datetime.timezone(datetime.timedelta(seconds=21600))) >>> tz_naive = datetime.datetime(2021, 4, 2, 18, 18, 10, 123) >>> msg = msgspec.json.encode(tz_naive) >>> msg b'"2021-04-02T18:18:10.000123"' >>> msgspec.json.decode(msg, type=datetime.datetime) datetime.datetime(2021, 4, 2, 18, 18, 10, 123) >>> msgspec.json.decode(b'"oops"', type=datetime.datetime) Traceback (most recent call last): File "", line 1, in msgspec.ValidationError: Invalid RFC3339 encoded datetime Additionally, if ``strict=False`` is specified, all protocols will decode ints, floats, or strings containing ints/floats as timezone-aware datetimes, interpreting the value as seconds since the epoch in UTC (a `Unix Timestamp `__). See :ref:`strict-vs-lax` for more information. .. code-block:: python >>> msgspec.json.decode(b"1617405490.000123", type=datetime.datetime) Traceback (most recent call last): File "", line 1, in msgspec.ValidationError: Expected `datetime`, got `float` >>> msgspec.json.decode(b"1617405490.000123", type=datetime.datetime, strict=False) datetime.datetime(2021, 4, 2, 18, 18, 10, 123, tzinfo=datetime.timezone.utc) ``date`` -------- `datetime.date` values map to: - **JSON**: RFC3339_ encoded strings - **MessagePack**: RFC3339_ encoded strings - **YAML**: YAML's native date type - **TOML** TOML's native date type .. code-block:: python >>> import datetime >>> date = datetime.date(2021, 4, 2) >>> msg = msgspec.json.encode(date) >>> msg b'"2021-04-02"' >>> msgspec.json.decode(msg, type=datetime.date) datetime.date(2021, 4, 2) >>> msgspec.json.decode(b'"oops"', type=datetime.date) Traceback (most recent call last): File "", line 1, in msgspec.ValidationError: Invalid RFC3339 encoded date ``time`` -------- The encoding used for `datetime.time` objects is dependent on both the protocol and whether these objects are timezone-aware_ or timezone-naive: - **JSON**, **MessagePack**, and **YAML**: Timezone-aware times are encoded as RFC3339_ compatible strings. Timezone-naive times are encoded the same, but lack the timezone component (making them not strictly RFC3339_ compatible, but still ISO8601_ compatible). - **TOML**: Timezone-naive times are encoded using TOML's native time type. Timezone-aware times aren't supported. Note that you can require a `datetime.time` object to be timezone-aware or timezone-naive by specifying a ``tz`` constraint (see :ref:`datetime-constraints` for more information). .. code-block:: python >>> import datetime >>> tz = datetime.timezone(datetime.timedelta(hours=6)) >>> tz_aware = datetime.time(18, 18, 10, 123, tzinfo=tz) >>> msg = msgspec.json.encode(tz_aware) >>> msg b'"18:18:10.000123+06:00"' >>> msgspec.json.decode(msg, type=datetime.time) datetime.time(18, 18, 10, 123, tzinfo=datetime.timezone(datetime.timedelta(seconds=21600))) >>> tz_naive = datetime.time(18, 18, 10, 123) >>> msg = msgspec.json.encode(tz_naive) >>> msg b'"18:18:10.000123"' >>> msgspec.json.decode(msg, type=datetime.time) datetime.time(18, 18, 10, 123) >>> msgspec.json.decode(b'"oops"', type=datetime.time) Traceback (most recent call last): File "", line 1, in msgspec.ValidationError: Invalid RFC3339 encoded time ``timedelta`` ------------- `datetime.timedelta` values map to extended `ISO 8601 duration strings`_ in all protocols. The format as described in the ISO specification is fairly lax and a bit underspecified, leading most real-world implementations to implement a stricter subset. The duration format used here is as follows: .. code-block:: text [+/-]P[#D][T[#H][#M][#S]] - The format starts with an optional sign (``-`` or ``+``). If negative, the whole duration is negated. - The letter ``P`` follows (case insensitive) - There are then four segments, each consisting of a number and unit. The units are ``D``, ``H``, ``M``, ``S`` (case insensitive) for days, hours, minutes, and seconds respectively. These segments must occur in this order. - If a segment would have a 0 value it may be omitted, with the caveat that at least one segment must be present. - If a time (hour, minute, or second) segment is present then the letter ``T`` (case insensitive) must precede the first time segment. Likewise if a ``T`` is present, there must be at least 1 segment after the ``T``. - Each segment is composed of 1 or more digits, followed by the unit. Leading 0s are accepted. The *final* segment may include a decimal component if needed. A few examples: .. code-block:: python "P0D" # 0 days "P1D" # 1 Day "PT1H30S" # 1 Hour and 30 minutes "PT1.5H" # 1 Hour and 30 minutes "-PT1M30S" # -90 seconds "PT1H30M25.5S" # 1 Hour, 30 minutes, and 25.5 seconds While msgspec will decode duration strings making use of the ``H`` (hour) or ``M`` (minute) units, durations encoded by msgspec will only consist of ``D`` (day) and ``S`` (second) segments. The implementation in ``msgspec`` is compatible with the ones in: - Java's ``time.Duration.parse`` (`docs `__) - Javascript's proposed ``Temporal.Duration`` standard API (`docs `__) - Python libraries like pendulum_ or pydantic_. Duration strings produced by msgspec should be interchangeable with these libraries, as well as similar ones in other language ecosystems. .. code-block:: python >>> from datetime import timedelta >>> msgspec.json.encode(timedelta(seconds=123)) b'"PT123S"' >>> msgspec.json.encode(timedelta(days=1, seconds=30, microseconds=123)) b'"P1DT30.000123S"' >>> msgspec.json.decode(b'"PT123S"', type=timedelta) datetime.timedelta(seconds=123) >>> msgspec.json.decode(b'"PT1.5M"', type=timedelta) datetime.timedelta(seconds=90) >>> msgspec.json.decode(b'"oops"', type=datetime.timedelta) Traceback (most recent call last): File "", line 1, in msgspec.ValidationError: Invalid ISO8601 duration Additionally, if ``strict=False`` is specified, all protocols will decode ints, floats, or strings containing ints/floats as timedeltas, interpreting the value as total seconds. See :ref:`strict-vs-lax` for more information. .. code-block:: python >>> msgspec.json.decode(b"123.4", type=datetime.timedelta) Traceback (most recent call last): File "", line 1, in msgspec.ValidationError: Expected `duration`, got `float` >>> msgspec.json.decode(b"123.4", type=datetime.timedelta, strict=False) datetime.timedelta(seconds=123, microseconds=400000) ``uuid`` -------- `uuid.UUID` values are serialized as RFC4122_ encoded canonical strings in all protocols by default. Subclasses of `uuid.UUID` are also supported for encoding only. .. code-block:: python >>> import uuid >>> u = uuid.UUID("c4524ac0-e81e-4aa8-a595-0aec605a659a") >>> msgspec.json.encode(u) b'"c4524ac0-e81e-4aa8-a595-0aec605a659a"' >>> msgspec.json.decode(b'"c4524ac0-e81e-4aa8-a595-0aec605a659a"', type=uuid.UUID) UUID('c4524ac0-e81e-4aa8-a595-0aec605a659a') >>> msgspec.json.decode(b'"oops"', type=uuid.UUID) Traceback (most recent call last): File "", line 1, in msgspec.ValidationError: Invalid UUID Alternative formats are also supported by the JSON and MessagePack encoders. The format may be selected by passing it to ``uuid_format`` when creating an ``Encoder``. The following options are supported: - ``canonical``: UUIDs are encoded as RFC4122_ canonical strings (same as ``str(uuid)``). This is the default. - ``hex``: UUIDs are encoded as RFC4122_ hex strings (same as ``uuid.hex``). - ``bytes``: UUIDs are encoded as binary values of the uuid's big-endian 128-bit integer representation (same as ``uuid.bytes``). This is only supported by the MessagePack encoder. When decoding, any of the above formats are accepted. .. code-block:: python >>> enc = msgspec.json.Encoder(uuid_format="hex") >>> uuid_hex = enc.encode(u) >>> uuid_hex b'"c4524ac0e81e4aa8a5950aec605a659a"' >>> msgspec.json.decode(uuid_hex, type=uuid.UUID) UUID('c4524ac0-e81e-4aa8-a595-0aec605a659a') >>> enc = msgspec.msgpack.Encoder(uuid_format="bytes") >>> uuid_bytes = enc.encode(u) >>> msgspec.msgpack.decode(uuid_bytes, type=uuid.UUID) UUID('c4524ac0-e81e-4aa8-a595-0aec605a659a') ``decimal`` ----------- `decimal.Decimal` values are encoded as their string representation in all protocols by default. This ensures no precision loss during serialization, as would happen with a float representation. .. code-block:: python >>> import decimal >>> x = decimal.Decimal("1.2345") >>> msg = msgspec.json.encode(x) >>> msg b'"1.2345"' >>> msgspec.json.decode(msg, type=decimal.Decimal) Decimal('1.2345') >>> msgspec.json.decode(b'"oops"', type=decimal.Decimal) Traceback (most recent call last): File "", line 1, in msgspec.ValidationError: Invalid decimal string For JSON and MessagePack you may instead encode decimal values the same as numbers by creating a ``Encoder`` and specifying ``decimal_format='number'``. .. code-block:: python >>> encoder = msgspec.json.Encoder(decimal_format="number") >>> encoder.encode(x) b'1.2345' For JSON and MessagePack you may also pass a callable to ``decimal_format`` to customize how decimals are encoded. The callable will be called with the `decimal.Decimal` instance as the only argument, and must return a JSON-serializable value (but **not** another `decimal.Decimal` or a nested structure containing `decimal.Decimal`). This is useful for custom rounding, formatting, or transforming decimal values before encoding. .. code-block:: python >>> import decimal >>> class Price(msgspec.Struct): ... amount: decimal.Decimal ... currency: str >>> enc = msgspec.json.Encoder( ... decimal_format=lambda d: str(d.quantize(decimal.Decimal("0.01"))) ... ) >>> enc.encode(Price(amount=decimal.Decimal("10.123456"), currency="USD")) b'{"amount":"10.12","currency":"USD"}' .. warning:: The callable passed to ``decimal_format`` must **not** return a `decimal.Decimal` instance or any nested structure (list, dict, tuple, set) containing `decimal.Decimal`, as this would cause infinite recursion. The callable should return a `str`, `int`, `float`, or other JSON-serializable type. If the callable returns a value containing a `decimal.Decimal`, a `TypeError` will be raised. This setting is not yet supported for YAML or TOML - if this option is important for you please `open an issue`_. All protocols will also decode `decimal.Decimal` values from ``int`` or ``float`` inputs. For JSON the value is parsed directly from the serialized bytes, avoiding any precision loss: .. code-block:: python >>> msgspec.json.decode(b"1.3", type=decimal.Decimal) Decimal('1.3') >>> msgspec.json.decode(b"1.300", type=decimal.Decimal) Decimal('1.300') >>> msgspec.json.decode(b"0.1234567891234567811", type=decimal.Decimal) Decimal('0.1234567891234567811') Other protocols will coerce float inputs to the shortest decimal value that roundtrips back to the corresponding IEEE754 float representation (this is effectively equivalent to ``decimal.Decimal(str(float_val))``). This may result in precision loss for some inputs! In general we recommend avoiding parsing `decimal.Decimal` values from anything but strings. .. code-block:: python >>> msgspec.yaml.decode(b"1.3", type=decimal.Decimal) Decimal('1.3') >>> msgspec.yaml.decode(b"1.300", type=decimal.Decimal) # trailing 0s truncated! Decimal('1.3') >>> msgspec.yaml.decode(b"0.1234567891234567811", type=decimal.Decimal) # precision loss! Decimal('0.12345678912345678') ``list`` / ``tuple`` / ``set`` / ``frozenset`` ---------------------------------------------- `list`, `tuple`, `set`, and `frozenset` objects map to arrays in all protocols. An error is raised if the elements don't match the specified element type (if provided). Subclasses of these types are also supported for encoding only. To decode into a ``list`` subclass you'll need to implement a ``dec_hook`` (see :doc:`extending`). .. code-block:: python >>> msgspec.json.encode([1, 2, 3]) b'[1,2,3]' >>> msgspec.json.encode({1, 2, 3}) b'[1,2,3]' >>> msgspec.json.decode(b'[1,2,3]', type=set) {1, 2, 3} >>> # Decode as a set of ints ... msgspec.json.decode(b'[1, 2, 3]', type=set[int]) {1, 2, 3} >>> # Oops, all elements should be ints ... msgspec.json.decode(b'[1, 2, "oops"]', type=set[int]) Traceback (most recent call last): File "", line 1, in msgspec.ValidationError: Expected `int`, got `str` - at `$[2]` ``NamedTuple`` -------------- `typing.NamedTuple` types map to arrays in all protocols. An error is raised during decoding if the type doesn't match or if any required fields are missing. Note that ``msgspec`` supports both `typing.NamedTuple` and `collections.namedtuple`, although the latter lacks a way to specify field types. When possible we recommend using `msgspec.Struct` (possibly with ``array_like=True`` and ``frozen=True``) instead of ``NamedTuple`` for specifying schemas - :doc:`structs` are faster, more ergonomic, and support additional features. Still, you may want to use a ``NamedTuple`` if you're already using them elsewhere, or if you have downstream code that requires a ``tuple`` instead of an object. .. code-block:: python >>> from typing import NamedTuple >>> class Person(NamedTuple): ... name: str ... age: int >>> ben = Person("ben", 25) >>> msg = msgspec.json.encode(ben) >>> msgspec.json.decode(msg, type=Person) Person(name='ben', age=25) >>> wrong_type = b'["chad", "twenty"]' >>> msgspec.json.decode(wrong_type, type=Person) Traceback (most recent call last): File "", line 1, in msgspec.ValidationError: Expected `int`, got `str` - at `$[1]` Other types that duck-type as ``NamedTuple`` are also supported, such as `os.stat_result`. .. code-block:: python >>> import os >>> import sys >>> result = os.stat(sys.executable) >>> result os.stat_result(st_mode=33261, st_ino=5396073, st_dev=105, st_nlink=1, st_uid=0, st_gid=0, st_size=18440, st_atime=1760547094, st_mtime=1760547094, st_ctime=1760907672) >>> msgspec.json.encode(result) b'[33261,5396073,105,1,0,0,18440,1760547094,1760547094,1760907672]' ``dict`` -------- Dicts encode/decode as objects/maps in all protocols. Dict subclasses (`collections.OrderedDict`, for example) are also supported for encoding only. To decode into a ``dict`` subclass you'll need to implement a ``dec_hook`` (see :doc:`extending`). JSON and TOML only support key types that encode as strings or numbers (for example `str`, `int`, `float`, `enum.Enum`, `datetime.datetime`, `uuid.UUID`, ...). MessagePack and YAML support any hashable for the key type. An error is raised during decoding if the keys or values don't match their respective types (if specified). .. code-block:: python >>> msgspec.json.encode({"x": 1, "y": 2}) b'{"x":1,"y":2}' >>> # Decode as a Dict of str -> int ... msgspec.json.decode(b'{"x":1,"y":2}', type=dict[str, int]) {"x": 1, "y": 2} >>> # Oops, there's a mistyped value ... msgspec.json.decode(b'{"x":1,"y":"oops"}', type=dict[str, int]) Traceback (most recent call last): File "", line 1, in msgspec.ValidationError: Expected `int`, got `str` - at `$[...]` ``TypedDict`` ------------- `typing.TypedDict` provides a way to specify different types for different values in a ``dict``, rather than a single value type (the ``int`` in ``dict[str, int]``, for example). At runtime these are just standard ``dict`` types, the ``TypedDict`` type is only there to provide the schema information during decoding. Note that ``msgspec`` supports both `typing.TypedDict` and ``typing_extensions.TypedDict`` (a backport). `typing.TypedDict` types map to objects/maps in all protocols. During decoding, any extra fields are ignored. An error is raised during decoding if the type doesn't match or if any required fields are missing. When possible we recommend using `msgspec.Struct` instead of ``TypedDict`` for specifying schemas - :doc:`structs` are faster, more ergonomic, and support additional features. Still, you may want to use a ``TypedDict`` if you're already using them elsewhere, or if you have downstream code that requires a ``dict`` instead of an object. .. code-block:: python >>> from typing import TypedDict >>> class Person(TypedDict): ... name: str ... age: int >>> ben = {"name": "ben", "age": 25} >>> msg = msgspec.json.encode(ben) >>> msgspec.json.decode(msg, type=Person) {'name': 'ben', 'age': 25} >>> wrong_type = b'{"name": "chad", "age": "twenty"}' >>> msgspec.json.decode(wrong_type, type=Person) Traceback (most recent call last): File "", line 1, in msgspec.ValidationError: Expected `int`, got `str` - at `$.age` ``dataclasses`` --------------- `dataclasses` map to objects/maps in all protocols. During decoding, any extra fields are ignored. An error is raised if a field's type doesn't match or if any required fields are missing. If a ``__post_init__`` method is defined on the dataclass, it is called after the object is decoded. Note that `"Init-only parameters" `__ (i.e. ``InitVar`` fields) are _not_ supported. When possible we recommend using `msgspec.Struct` instead of dataclasses for specifying schemas - :doc:`structs` are faster, more ergonomic, and support additional features. .. code-block:: python >>> from dataclasses import dataclass >>> @dataclass ... class Person: ... name: str ... age: int >>> carol = Person(name="carol", age=32) >>> msg = msgspec.json.encode(carol) >>> msgspec.json.decode(msg, type=Person) Person(name='carol', age=32) >>> wrong_type = b'{"name": "doug", "age": "thirty"}' >>> msgspec.json.decode(wrong_type, type=Person) Traceback (most recent call last): File "", line 1, in msgspec.ValidationError: Expected `int`, got `str` - at `$.age` Other types that duck-type as ``dataclasses`` are also supported, such as `pydantic dataclasses `__. .. code-block:: python >>> from datetime import datetime >>> from pydantic.dataclasses import dataclass >>> @dataclass ... class User: ... id: int ... name: str = 'John Doe' ... signup_ts: datetime | None = None >>> user = User(id='42', signup_ts='2032-06-21T12:00') >>> user User(id=42, name='John Doe', signup_ts=datetime.datetime(2032, 6, 21, 12, 0)) >>> msgspec.json.encode(user) b'{"id":42,"name":"John Doe","signup_ts":"2032-06-21T12:00:00"}' ``attrs`` --------- attrs_ types map to objects/maps in all protocols. During encoding, all attributes without a leading underscore (``"_"``) are encoded. During decoding, any extra fields are ignored. An error is raised if a field's type doesn't match or if any required fields are missing. If the ``__attrs_pre_init__`` or ``__attrs_post_init__`` methods are defined on the class, they are called as part of the decoding process. Likewise, if a class makes use of attrs' `validators `__, the validators will be called, and a `msgspec.ValidationError` raised on error. Note that attrs' `converters `__ are not currently supported. When possible we recommend using `msgspec.Struct` instead of attrs_ types for specifying schemas - :doc:`structs` are faster, more ergonomic, and support additional features. .. code-block:: python >>> from attrs import define >>> @define ... class Person: ... name: str ... age: int >>> carol = Person(name="carol", age=32) >>> msg = msgspec.json.encode(carol) >>> msgspec.json.decode(msg, type=Person) Person(name='carol', age=32) >>> wrong_type = b'{"name": "doug", "age": "thirty"}' >>> msgspec.json.decode(wrong_type, type=Person) Traceback (most recent call last): File "", line 1, in msgspec.ValidationError: Expected `int`, got `str` - at `$.age` ``Struct`` ---------- Structs are the preferred way of defining structured data types in ``msgspec``. You can think of them as similar to dataclasses_/attrs_/pydantic_, but much faster to create/compare/encode/decode. For more information, see the :doc:`structs` page. By default `msgspec.Struct` types map to objects/maps in all protocols. During decoding, any unknown fields are ignored (this can be disabled, see :ref:`forbid-unknown-fields`), and any missing optional fields have their default values applied. An error is raised during decoding if the type doesn't match or if any required fields are missing. .. code-block:: python >>> from typing import Set, Optional >>> class User(msgspec.Struct): ... name: str ... groups: set[str] = set() ... email: str | None = None >>> alice = User("alice", groups={"admin", "engineering"}) >>> msgspec.json.encode(alice) b'{"name":"alice","groups":["admin","engineering"],"email":null}' >>> msg = b""" ... { ... "name": "bob", ... "email": "bob@company.com", ... "unknown_field": [1, 2, 3] ... } ... """ >>> msgspec.json.decode(msg, type=User) User(name='bob', groups=[], email="bob@company.com") >>> wrong_type = b""" ... { ... "name": "bob", ... "groups": ["engineering", 123] ... } ... """ >>> msgspec.json.decode(wrong_type, type=User) Traceback (most recent call last): File "", line 1, in msgspec.ValidationError: Expected `str`, got `int` - at `$.groups[1]` If you pass ``array_like=True`` when defining the struct type, they're instead treated as array types during encoding/decoding. In this case fields are serialized in their :ref:`field order `. This can further improve performance at the cost of less human readable messaging. Like ``array_like=False`` (the default) structs, extra (trailing) fields are ignored during decoding, and any missing optional fields have their defaults applied. Type checking also still applies. .. code-block:: python >>> class User(msgspec.Struct, array_like=True): ... name: str ... groups: set[str] = set() ... email: str | None = None >>> alice = User("alice", groups={"admin", "engineering"}) >>> msgspec.json.encode(alice) b'["alice",["admin","engineering"],null]' >>> msgspec.json.decode(b'["bob"]', type=User) User(name="bob", groups=[], email=None) >>> msgspec.json.decode(b'["carol", ["admin"], null, ["extra", "field"]]', type=User) User(name="carol", groups=["admin"], email=None) >>> msgspec.json.decode(b'["david", ["finance", 123]]') Traceback (most recent call last): File "", line 1, in msgspec.ValidationError: Expected `str`, got `int` - at `$[1][1]` .. _unset-type: ``UNSET`` --------- `msgspec.UNSET` is a singleton object used to indicate that a field has no set value. This is useful for cases where you need to differentiate between a message where a field is missing and a message where the field is explicitly ``None``. .. code-block:: python >>> from msgspec import Struct, UnsetType, UNSET, json >>> class Example(Struct): ... x: int ... y: int | None | UnsetType = UNSET # a field, defaulting to UNSET During encoding, any field containing ``UNSET`` is omitted from the message. .. code-block:: python >>> json.encode(Example(1)) # y is UNSET b'{"x":1}' >>> json.encode(Example(1, UNSET)) # y is UNSET b'{"x":1}' >>> json.encode(Example(1, None)) # y is None b'{"x":1,"y":null}' >>> json.encode(Example(1, 2)) # y is 2 b'{"x":1,"y":2}' During decoding, if a field isn't explicitly set in the message, the default value of ``UNSET`` will be set instead. This lets downstream consumers determine whether a field was left unset, or explicitly set to ``None`` .. code-block:: python >>> json.decode(b'{"x": 1}', type=Example) # y defaults to UNSET Example(x=1, y=UNSET) >>> json.decode(b'{"x": 1, "y": null}', type=Example) # y is None Example(x=1, y=None) >>> json.decode(b'{"x": 1, "y": 2}', type=Example) # y is 2 Example(x=1, y=2) ``UNSET`` fields are supported for `msgspec.Struct`, `dataclasses`, and attrs_ types. It is an error to use `msgspec.UNSET` or `msgspec.UnsetType` anywhere other than a field for one of these types. Omission of ``UNSET`` fields applies to `msgspec.json.encode`, `msgspec.msgpack.encode`, `msgspec.yaml.encode`, `msgspec.toml.encode`, and `msgspec.to_builtins`. `msgspec.structs.asdict` and `msgspec.structs.astuple` always include every field, so ``UNSET`` values appear in their output unchanged - see :ref:`to-builtins-vs-asdict`. ``Enum`` / ``IntEnum`` / ``StrEnum`` ------------------------------------ Enum types (`enum.Enum`, `enum.IntEnum`, `enum.StrEnum`, ...) encode as their member *values* in all protocols. Any enum whose *value* is a supported type may be encoded, but only enums composed of all string or all integer values may be decoded. An error is raised during decoding if the value isn't the proper type, or doesn't match any valid member. .. code-block:: python >>> import enum >>> class Fruit(enum.Enum): ... APPLE = "apple" ... BANANA = "banana" >>> msgspec.json.encode(Fruit.APPLE) b'"apple"' >>> msgspec.json.decode(b'"apple"', type=Fruit) >>> msgspec.json.decode(b'"grape"', type=Fruit) Traceback (most recent call last): File "", line 1, in msgspec.ValidationError: Invalid enum value 'grape' >>> class JobState(enum.IntEnum): ... CREATED = 0 ... RUNNING = 1 ... SUCCEEDED = 2 ... FAILED = 3 >>> msgspec.json.encode(JobState.RUNNING) b'1' >>> msgspec.json.decode(b'2', type=JobState) >>> msgspec.json.decode(b'4', type=JobState) Traceback (most recent call last): File "", line 1, in msgspec.ValidationError: Invalid enum value 4 If the enum type includes a ``_missing_`` method (`docs `__), this method will be called to handle any missing values. It should return a valid enum member, or ``None`` if the value is invalid. One potential use case of this is supporting case-insensitive enums: .. code-block:: python >>> import enum >>> class Fruit(enum.Enum): ... APPLE = "apple" ... BANANA = "banana" ... ... @classmethod ... def _missing_(cls, name): ... """Called to handle missing enum values""" ... # Normalize value to lowercase ... value = name.lower() ... # Return valid enum value, or None if invalid ... return cls._value2member_map_.get(value) >>> msgspec.json.decode(b'"apple"', type=Fruit) >>> msgspec.json.decode(b'"ApPlE"', type=Fruit) >>> msgspec.json.decode(b'"grape"', type=Fruit) Traceback (most recent call last): File "", line 1, in msgspec.ValidationError: Invalid enum value 'grape' ``Literal`` ----------- `typing.Literal` types can be used to ensure that a decoded object is within a set of valid values. An `enum.Enum` or `enum.IntEnum` can be used for the same purpose, but with a `typing.Literal` the decoded values are literal `int` or `str` instances rather than `enum` objects. A literal can be composed of any of the following objects: - `None` - `bool` values (`True` and `False`) - `int` values - `str` values - Nested `typing.Literal` types An error is raised during decoding if the value isn't in the set of valid values, or doesn't match any of their component types. .. code-block:: python >>> from typing import Literal >>> msgspec.json.decode(b'1', type=Literal[1, 2, 3]) 1 >>> msgspec.json.decode(b'"one"', type=Literal["one", "two", "three"]) 'one' >>> msgspec.json.decode(b'4', type=Literal[1, 2, 3]) Traceback (most recent call last): File "", line 1, in msgspec.ValidationError: Invalid enum value 4 >>> msgspec.json.decode(b'"bad"', type=Literal[1, 2, 3]) Traceback (most recent call last): File "", line 1, in msgspec.ValidationError: Expected `int`, got `str` >>> msgspec.json.decode(b'true', type=Literal[True]) True >>> msgspec.json.decode(b'false', type=Literal[True, False]) False ``NewType`` ----------- `typing.NewType` types are treated identically to their base type. Their support here is purely to aid static analysis tools like mypy_ or pyright_. .. code-block:: python >>> from typing import NewType >>> UserId = NewType("UserId", int) >>> msgspec.json.encode(UserId(1234)) b'1234' >>> msgspec.json.decode(b'1234', type=UserId) 1234 >>> msgspec.json.decode(b'"oops"', type=UserId) Traceback (most recent call last): File "", line 1, in msgspec.ValidationError: Expected `int`, got `str` Type Aliases ------------ For complex types, sometimes it can be nice to write the type once so you can reuse it later. .. code-block:: python Point = tuple[float, float] Here ``Point`` is a "type alias" for ``tuple[float, float]`` - ``msgspec`` will substitute in ``tuple[float, float]`` whenever the ``Point`` type is used in an annotation. ``msgspec`` supports the following equivalent forms: .. code-block:: python # Using variable assignment Point = tuple[float, float] # Using variable assignment, annotated as a `TypeAlias` Point: TypeAlias = tuple[float, float] # Using Python 3.12's new `type` statement. This only works on Python 3.12+ type Point = tuple[float, float] To learn more about Type Aliases, see Python's `Type Alias docs here `__. Generic Types ------------- ``msgspec`` supports generic types, including `user-defined generic types`_ based on any of the following types: - `msgspec.Struct` - `dataclasses` - `attrs` - `typing.TypedDict` - `typing.NamedTuple` Generic types may be useful for reusing common message structures. To define a generic type: - Define one or more type variables (`typing.TypeVar`) to parametrize your type with. - Add `typing.Generic` as a base class when defining your type, parametrizing it by the relevant type variables. - When annotating the field types, use the relevant type variables instead of "concrete" types anywhere you want to be generic. For example, here we define a generic ``Paginated`` struct type for storing extra pagination information in an API response. .. code-block:: python import msgspec from typing import Generic, TypeVar # A type variable for the item type T = TypeVar("T") class Paginated(msgspec.Struct, Generic[T]): """A generic paginated API wrapper, parametrized by the item type.""" page: int # The current page number per_page: int # Number of items per page total: int # The total number of items found items: list[T] # Items returned, up to `per_page` in length This type is generic over the type of item contained in ``Paginated.items``. This ``Paginated`` wrapper may then be used to decode a message containing a specific item type by parametrizing it with that type. When processing a generic type, the parametrized types are substituted for the type variables. Here we define a ``User`` type, then use it to decode a paginated API response containing a list of users: .. code-block:: python class User(msgspec.Struct): """A user model""" name: str groups: list[str] = [] json_str = """ { "page": 1, "per_page": 5, "total": 252, "items": [ {"name": "alice", "groups": ["admin"]}, {"name": "ben"}, {"name": "carol", "groups": ["engineering"]}, {"name": "dan", "groups": ["hr"]}, {"name": "ellen", "groups": ["engineering"]} ] } """ # Decode a paginated response containing a list of users msg = msgspec.json.decode(json_str, type=Paginated[User]) print(msg) #> Paginated( #> page=1, per_page=5, total=252, #> items=[ #> User(name='alice', groups=['admin']), #> User(name='ben', groups=[]), #> User(name='carol', groups=['engineering']), #> User(name='dan', groups=['hr']), #> User(name='ellen', groups=['engineering']) #> ] #> ) If instead we wanted to decode a paginated response of another type (say ``Team``), we could do this by parametrizing ``Paginated`` with a different type. .. code-block:: python # Decode a paginated response containing a list of teams msgspec.json.decode(some_other_message, type=Paginated[Team]) Any unparametrized type variables will be treated as `typing.Any` when decoding. .. code-block:: python # These are equivalent. # The unparametrized version substitutes in `Any` for `T` msgspec.json.decode(some_other_message, type=Paginated) msgspec.json.decode(some_other_message, type=Paginated[Any]) However, if an unparametrized type variable has a ``bound`` (`docs `__), then the bound type will be used instead. .. code-block:: python from collections.abc import Sequence S = TypeVar("S", bound=Sequence) # Can be any sequence type class Example(msgspec.Struct, Generic[S]): value: S msg = b'{"value": [1, 2, 3]}' # These are equivalent. # The unparametrized version substitutes in `Sequence` for `S` msgspec.json.decode(some_other_message, type=Example) msgspec.json.decode(some_other_message, type=Example[Sequence]) See the official Python docs on `generic types`_ and the `corresponding PEP `__ for more information. Abstract Types -------------- ``msgspec`` supports several "abstract" types, decoding them as instances of their most common concrete type. **Decoded as lists** - `collections.abc.Collection` / `typing.Collection` - `collections.abc.Sequence` / `typing.Sequence` - `collections.abc.MutableSequence` / `typing.MutableSequence` **Decoded as sets** - `collections.abc.Set` / `typing.AbstractSet` - `collections.abc.MutableSet` / `typing.MutableSet` **Decoded as dicts** - `collections.abc.Mapping` / `typing.Mapping` - `collections.abc.MutableMapping` / `typing.MutableMapping` .. code-block:: python >>> from typing import MutableMapping >>> msgspec.json.decode(b'{"x": 1}', type=MutableMapping[str, int]) {"x": 1} >>> msgspec.json.decode(b'{"x": "oops"}', type=MutableMapping[str, int]) Traceback (most recent call last): File "", line 1, in msgspec.ValidationError: Expected `int`, got `str` - at `$[...]` ``Union`` / ``Optional`` ------------------------- Type unions are supported, with a few restrictions. These restrictions are in place to remove any ambiguity during decoding - given an encoded value there must always be a single type in a given `typing.Union` that can decode that value. Union restrictions are as follows: - Unions may contain at most one type that encodes to an integer (`int`, `enum.IntEnum`) - Unions may contain at most one type that encodes to a string (`str`, `enum.Enum`, `bytes`, `bytearray`, `datetime.datetime`, `datetime.date`, `datetime.time`, `uuid.UUID`, `decimal.Decimal`). Note that this restriction is fixable with some work, if this is a feature you need please `open an issue`_. - Unions may contain at most one type that encodes to an object (`dict`, `typing.TypedDict`, dataclasses_, attrs_, `Struct` with ``array_like=False``) - Unions may contain at most one type that encodes to an array (`list`, `tuple`, `set`, `frozenset`, `typing.NamedTuple`, `Struct` with ``array_like=True``). - Unions may contain at most one *untagged* `Struct` type. Unions containing multiple struct types are only supported through :ref:`struct-tagged-unions`. - Unions with custom types are unsupported beyond optionality (i.e. ``CustomType | None``) .. code-block:: python >>> # A decoder expecting either an int, a str, or a list of strings ... decoder = msgspec.json.Decoder(int | str | list[str]) >>> decoder.decode(b'1') 1 >>> decoder.decode(b'"two"') "two" >>> decoder.decode(b'["three", "four"]') ["three", "four"] >>> decoder.decode(b'false') Traceback (most recent call last): File "", line 1, in msgspec.ValidationError: Expected `int | str | array`, got `bool` ``Raw`` ------- `msgspec.Raw` is a buffer-like type containing an already-encoded message. They have two common uses: **1. Avoiding unnecessary encoding cost** Wrapping an already-encoded buffer in `msgspec.Raw` lets the encoder avoid re-encoding the message, instead it will simply be copied to the output buffer. This can be useful when part of a message already exists in an encoded format (e.g. reading JSON bytes from a database and returning them as part of a larger message). .. code-block:: python >>> import msgspec >>> # Create a new `Raw` object wrapping a pre-encoded message ... fragment = msgspec.Raw(b'{"x": 1, "y": 2}') >>> # Compose a larger message containing the pre-encoded fragment ... msg = {"a": 1, "b": fragment} >>> # During encoding, the raw message is efficiently copied into ... # the output buffer, avoiding any extra encoding cost ... msgspec.json.encode(msg) b'{"a":1,"b":{"x": 1, "y": 2}}' **2. Delaying decoding of part of a message** Sometimes the type of a serialized value depends on the value of other fields in a message. ``msgspec`` provides an optimized version of one common pattern (:ref:`struct-tagged-unions`), but if you need to do something more complicated you may find using `msgspec.Raw` useful here. For example, here we demonstrate how to decode a message where the type of one field (``point``) depends on the value of another (``dimensions``). .. code-block:: python >>> import msgspec >>> from typing import Union >>> class Point1D(msgspec.Struct): ... x: int >>> class Point2D(msgspec.Struct): ... x: int ... y: int >>> class Point3D(msgspec.Struct): ... x: int ... y: int ... z: int >>> class Model(msgspec.Struct): ... dimensions: int ... point: msgspec.Raw # use msgspec.Raw to delay decoding the point field >>> def decode_point(msg: bytes) -> Point1D | Point2D | Point3D: ... """A function for efficiently decoding the `point` field""" ... # First decode the outer `Model` struct. Decoding of the `point` ... # field is delayed, with the composite bytes stored as a `Raw` object ... # on `point`. ... model = msgspec.json.decode(msg, type=Model) ... ... # Based on the value of `dimensions`, determine which type to use ... # when decoding the `point` field ... if model.dimensions == 1: ... point_type = Point1D ... elif model.dimensions == 2: ... point_type = Point2D ... elif model.dimensions == 3: ... point_type = Point3D ... else: ... raise ValueError("Too many dimensions!") ... ... # Now that we know the type of `point`, we can finish decoding it. ... # Note that `Raw` objects are buffer-like, and can be passed ... # directly to the `decode` method. ... return msgspec.json.decode(model.point, type=point_type) >>> decode_point(b'{"dimensions": 2, "point": {"x": 1, "y": 2}}') Point2D(x=1, y=2) >>> decode_point(b'{"dimensions": 3, "point": {"x": 1, "y": 2, "z": 3}}') Point3D(x=1, y=2, z=3) .. note:: `msgspec.Raw` values are only populated by `msgspec.json.decode` and `msgspec.msgpack.decode`, which can capture the original encoded bytes of a field before decoding it further. `msgspec.convert` (and anything built on it, like `msgspec.yaml.decode` and `msgspec.toml.decode`) operates on already-decoded Python objects, so there's no encoded byte buffer left to capture -- a `Raw`-typed field will only accept an already-constructed `Raw` object as input, not an arbitrary value. ``Any`` ------- When decoding a message with `Any` type (or no type specified), encoded types map to Python types in a protocol specific manner. **JSON** JSON_ types are decoded to Python types as follows: - ``null``: `None` - ``bool``: `bool` - ``string``: `str` - ``number``: `int` or `float` [#number_json]_ - ``array``: `list` - ``object``: `dict` .. [#number_json] Numbers are decoded as integers if they contain no decimal or exponent components (e.g. ``1`` but not ``1.0`` or ``1e10``). All other numbers decode as floats. **MessagePack** MessagePack_ types are decoded to Python types as follows: - ``nil``: `None` - ``bool``: `bool` - ``int``: `int` - ``float``: `float` - ``str``: `str` - ``bin``: `bytes` - ``array``: `list` or `tuple` [#tuple]_ - ``map``: `dict` - ``ext``: `msgspec.msgpack.Ext`, `datetime.datetime`, or a custom type .. [#tuple] Tuples are only used when the array type must be hashable (e.g. keys in a ``dict`` or ``set``). All other array types are deserialized as lists by default. **YAML** YAML_ types are decoded to Python types as follows: - ``null``: `None` - ``bool``: `bool` - ``string``: `str` - ``int``: `int` - ``float``: `float` - ``array``: `list` - ``object``: `dict` - ``timestamp``: `datetime.datetime` - ``date``: `datetime.date` **TOML** TOML_ types are decoded to Python types as follows: - ``bool``: `bool` - ``string``: `str` - ``int``: `int` - ``float``: `float` - ``array``: `list` - ``table``: `dict` - ``datetime``: `datetime.datetime` - ``date``: `datetime.date` - ``time``: `datetime.time` .. _type annotations: https://docs.python.org/3/library/typing.html .. _JSON: https://json.org .. _MessagePack: https://msgpack.org .. _YAML: https://yaml.org .. _TOML: https://toml.io/en/ .. _pydantic: https://pydantic.dev/docs/validation/latest/get-started/ .. _pendulum: https://pendulum.eustace.io/ .. _RFC8259: https://datatracker.ietf.org/doc/html/rfc8259 .. _RFC3339: https://datatracker.ietf.org/doc/html/rfc3339 .. _RFC4122: https://datatracker.ietf.org/doc/html/rfc4122 .. _ISO8601: https://en.wikipedia.org/wiki/ISO_8601 .. _timestamp extension: https://github.com/msgpack/msgpack/blob/master/spec.md#timestamp-extension-type .. _dataclasses: https://docs.python.org/3/library/dataclasses.html .. _attrs: https://www.attrs.org/en/stable/index.html .. _timezone-aware: https://docs.python.org/3/library/datetime.html#aware-and-naive-objects .. _mypy: https://mypy.readthedocs.io/en/stable/ .. _pyright: https://github.com/microsoft/pyright .. _generic types: .. _user-defined generic types: https://docs.python.org/3/library/typing.html#user-defined-generic-types .. _open an issue: https://github.com/msgspec/msgspec/issues .. _ISO 8601 duration strings: https://en.wikipedia.org/wiki/ISO_8601#Durations python-msgspec-0.22.0/docs/usage.rst000066400000000000000000000177011525673062400173610ustar00rootroot00000000000000Usage ===== ``msgspec`` supports multiple serialization protocols, accessed through separate submodules: - ``msgspec.json`` (JSON_) - ``msgspec.msgpack`` (MessagePack_) - ``msgspec.yaml`` (YAML_) - ``msgspec.toml`` (TOML_) Each supports a consistent interface, making it simple to switch between protocols as needed. Encoding -------- Each submodule has an ``encode`` method for encoding Python objects using the respective protocol. .. code-block:: python >>> import msgspec >>> # Encode as JSON ... msgspec.json.encode({"hello": "world"}) b'{"hello":"world"}' >>> # Encode as msgpack ... msgspec.msgpack.encode({"hello": "world"}) b'\x81\xa5hello\xa5world' Note that if you're making multiple calls to ``encode``, it's more efficient to create an ``Encoder`` once and use the ``Encoder.encode`` method instead. .. code-block:: python >>> import msgspec >>> # Create a JSON encoder ... encoder = msgspec.json.Encoder() >>> # Encode as JSON using the encoder ... encoder.encode({"hello": "world"}) b'{"hello":"world"}' Decoding -------- Each submodule has ``decode`` method for decoding messages using the respective protocol. .. code-block:: python >>> import msgspec >>> # Decode JSON ... msgspec.json.decode(b'{"hello":"world"}') {'hello': 'world'} >>> # Decode msgpack ... msgspec.msgpack.decode(b'\x81\xa5hello\xa5world') {'hello': 'world'} Note that if you're making multiple calls to ``decode``, it's more efficient to create a ``Decoder`` once and use the ``Decoder.decode`` method instead. .. code-block:: python >>> import msgspec >>> # Create a JSON decoder ... decoder = msgspec.json.Decoder() >>> # Decode JSON using the decoder ... decoder.decode(b'{"hello":"world"}') {'hello': 'world'} .. _typed-decoding: Typed Decoding -------------- ``msgspec`` optionally supports specifying the expected output types during decoding. This serves a few purposes: - Often serialized data has a fixed schema (e.g. a request handler in a REST api expects a certain JSON structure). Specifying the expected types allows ``msgspec`` to perform validation during decoding, with *no* added runtime cost. - Python has a much richer type system than serialization protocols like JSON_ or MessagePack_. Specifying the output types lets ``msgspec`` decode messages into types other than the defaults described above (e.g. decoding JSON objects into a :doc:`Struct ` instead of the default `dict`). - The `type annotations`_ used to describe the expected types are compatible with tools like mypy_ or pyright_, providing excellent editor integration. ``msgspec`` uses Python `type annotations`_ to describe the expected types. A :doc:`wide variety of builtin types are supported `. Here we define a user schema as a :doc:`Struct ` type. We then pass the type to ``decode`` via the ``type`` keyword argument: .. code-block:: python >>> import msgspec >>> class User(msgspec.Struct): ... name: str ... groups: set[str] = set() ... email: str | None = None >>> msgspec.json.decode( ... b'{"name": "alice", "groups": ["admin", "engineering"]}', ... type=User ... ) User(name='alice', groups={'admin', 'engineering'}, email=None) If a message doesn't match the expected type, an error is raised. .. code-block:: python >>> msgspec.json.decode( ... b'{"name": "bill", "groups": ["devops", 123]}', ... type=User ... ) Traceback (most recent call last): File "", line 1, in msgspec.ValidationError: Expected `str`, got `int` - at `$.groups[1]` .. _strict-vs-lax: "Strict" vs "Lax" Mode ~~~~~~~~~~~~~~~~~~~~~~ Unlike some other libraries (e.g. pydantic_), ``msgspec`` won't perform any unsafe implicit conversion by default ("strict" mode). For example, if an integer is specified and a string is provided instead, an error is raised rather than attempting to cast the string to an int. .. code-block:: python >>> msgspec.json.decode(b'[1, 2, "3"]', type=list[int]) Traceback (most recent call last): File "", line 1, in msgspec.ValidationError: Expected `int`, got `str` - at `$[2]` For cases where you'd like a more lax set of conversion rules, you can pass ``strict=False`` to any ``decode`` function or ``Decoder`` class ("lax" mode). See :doc:`supported-types` for information on how this affects individual types. .. code-block:: python >>> msgspec.json.decode(b'[1, 2, "3"]', type=list[int], strict=False) [1, 2, 3] .. _to-builtins-vs-asdict: Converting to and from Builtin Types ------------------------------------ In some cases, ``msgspec`` only needs to process part of a message, and the rest is handled by another library. For these situations, `msgspec.to_builtins` and `msgspec.convert` convert between high-level types and plain builtin types (`dict`, `list`, `str`, `int`, ...) without going through an encoded representation. - `msgspec.to_builtins` is the "encoding" half. It applies the same semantics as `msgspec.json.encode` / `msgspec.msgpack.encode` - just with builtin Python types as the output rather than an encoded byte string. This includes: - Struct-level settings: ``rename``, :ref:`omit_defaults`, ``array_like``, and ``tag`` for :ref:`tagged unions `. - Omission of :ref:`UNSET ` fields. - Recursive expansion of nested `msgspec.Struct`, `dataclasses.dataclass`, attrs_, `typing.TypedDict`, and `typing.NamedTuple` values. - Value-level conversions of types that don't map directly to builtin types: `bytes` / `bytearray` / `memoryview` to base64 string, `datetime.datetime` / `datetime.date` / `datetime.time` / `datetime.timedelta` to ISO 8601 string, `uuid.UUID` and `decimal.Decimal` to string, `set` / `frozenset` to `list`, ``frozendict`` to `dict`, `enum.Enum` to its member value. - Optional ``enc_hook``, ``str_keys``, ``order``, and ``builtin_types`` kwargs for tuning the output to the wrapping protocol. - `msgspec.convert` is the "decoding" half: it takes builtin types and validates them against a schema, producing high-level types. .. code-block:: python >>> import msgspec >>> class User(msgspec.Struct, omit_defaults=True): ... name: str ... groups: set[str] = set() ... email: str | None = None >>> alice = User("alice") >>> # to_builtins applies omit_defaults and expands nested types ... msgspec.to_builtins(alice) {'name': 'alice'} >>> # convert is the inverse operation ... msgspec.convert({"name": "bill", "groups": ["devops"]}, User) User(name='bill', groups={'devops'}, email=None) See :doc:`converters` for a more detailed guide, including how to use these functions to add ``msgspec`` support for additional serialization protocols. Note that `msgspec.structs.asdict` and `msgspec.structs.astuple` are *not* equivalent to `msgspec.to_builtins`. They are modeled on `dataclasses.asdict` / `dataclasses.astuple`: a one-to-one conversion of a single struct instance to a `dict` or `tuple`, using the raw attribute names. None of the semantics listed above apply. Every field is included regardless of ``omit_defaults`` or `msgspec.UNSET`, ``rename`` and ``tag`` are ignored, nested `msgspec.Struct` / `dataclasses.dataclass` / attrs_ values are left as-is, and value-level types (`bytes`, `datetime.datetime`, `uuid.UUID`, `decimal.Decimal`, `enum.Enum`, ...) are not converted. Prefer `msgspec.to_builtins` when the output is intended for serialization. .. _JSON: https://json.org .. _MessagePack: https://msgpack.org .. _YAML: https://yaml.org .. _TOML: https://toml.io/en/ .. _type annotations: https://docs.python.org/3/library/typing.html .. _pydantic: https://pydantic.dev/docs/validation/latest/get-started/ .. _mypy: https://mypy.readthedocs.io/en/stable/ .. _pyright: https://github.com/microsoft/pyright .. _attrs: https://www.attrs.org/en/stable/index.html python-msgspec-0.22.0/docs/why.rst000066400000000000000000000041251525673062400170600ustar00rootroot00000000000000Why msgspec? ------------ If you're writing a networked application, you'll need some agreed upon protocol that your clients and servers can use to communicate. JSON is a decent choice here (though there are many other options). It's ubiquitous, and Python has many libraries for parsing it into builtin types (``json``, ``ujson``, ``orjson``, ...). *However, servers don't just parse JSON, they also need to do something with it*. ``msgspec`` goes above and beyond other Python JSON libraries to help with the following: - **Validation** If a field is missing from a request or has the wrong type, you probably want to raise a nice error message rather than just throwing a 500 error. ``msgspec`` lets you describe your schema via type annotations, and will efficiently :ref:`validate ` messages against this schema while decoding. It also integrates well with static analysis tools like mypy_ and pyright_, helping you avoid whole classes of runtime errors. - **Application Logic** What your application actually does! While builtin types like dicts are fine for writing application logic, they aren't as ergonomic as custom classes (no attribute access, poor type checking, ...). ``msgspec`` supports a :doc:`wide variety of types `, letting you decouple the objects your application logic uses from those that JSON natively supports. - **Future Flexibility** Application needs change; you'll want to make sure your clients/servers won't break if the JSON schema evolves over time. To handle this, ``msgspec`` supports :doc:`"schema evolution" `. Messages can be sent between clients with different schemas without error, allowing systems to evolve over time. While there are other tools in this space, ``msgspec`` should be an :doc:`order of magnitude faster ` than other options. We also hope that it's quick to learn and friendly to use, letting you focus less on serialization and more on your application code. .. _mypy: https://mypy.readthedocs.io/en/stable/ .. _pyright: https://github.com/microsoft/pyright python-msgspec-0.22.0/examples/000077500000000000000000000000001525673062400164035ustar00rootroot00000000000000python-msgspec-0.22.0/examples/asyncio-kv/000077500000000000000000000000001525673062400204665ustar00rootroot00000000000000python-msgspec-0.22.0/examples/asyncio-kv/kv.py000066400000000000000000000130261525673062400214620ustar00rootroot00000000000000from __future__ import annotations import asyncio from typing import Any import msgspec # Some utilities for writing and reading length-prefix framed messages. Using # length-prefixed framing makes it easier for the reader to determine the # boundaries of each message before passing it to msgspec to be decoded. async def prefixed_send(stream: asyncio.StreamWriter, buffer: bytes) -> None: """Write a length-prefixed buffer to the stream""" # Encode the message length as a 4 byte big-endian integer. prefix = len(buffer).to_bytes(4, "big") # Write the prefix and buffer to the stream. stream.write(prefix) stream.write(buffer) await stream.drain() async def prefixed_recv(stream: asyncio.StreamReader) -> bytes: """Read a length-prefixed buffer from the stream""" # Read the next 4 byte prefix prefix = await stream.readexactly(4) # Convert the prefix back into an integer for the next message length n = int.from_bytes(prefix, "big") # Read in the full message buffer return await stream.readexactly(n) # Define some request types. We set `tag=True` on each type so they can be used # in a "tagged-union" defining the request types. class Get(msgspec.Struct, tag=True): key: str class Put(msgspec.Struct, tag=True): key: str val: str class Del(msgspec.Struct, tag=True): key: str class ListKeys(msgspec.Struct, tag=True): pass # A union of all valid request types Request = Get | Put | Del | ListKeys class Server: """An example TCP key-value server using asyncio and msgspec""" def __init__(self, host: str = "127.0.0.1", port: int = 8888): self.host = host self.port = port self.kv: dict[str, str] = {} # A msgpack encoder for encoding responses self.encoder = msgspec.msgpack.Encoder() # A *typed* msgpack decoder for decoding requests. If a request doesn't # match the specified types, a nice error will be raised. self.decoder = msgspec.msgpack.Decoder(Request) async def handle_connection( self, reader: asyncio.StreamReader, writer: asyncio.StreamWriter ): """Handle the full lifetime of a single connection""" print("Connection opened") while True: try: # Receive and decode a request buffer = await prefixed_recv(reader) req = self.decoder.decode(buffer) # Process the request resp = await self.handle_request(req) # Encode and write the response buffer = self.encoder.encode(resp) await prefixed_send(writer, buffer) except EOFError: print("Connection closed") return async def handle_request(self, req: Request) -> Any: """Handle a single request and return the result (if any)""" # We use pattern matching here to branch on the different message types. # You could just as well use an if-else statement, but pattern matching # works pretty well here. match req: case Get(key): # Return the value for a key, or None if missing return self.kv.get(key) case Put(key, val): # Add a new key-value pair self.kv[key] = val return None case Del(key): # Remove a key-value pair if it exists self.kv.pop(key, None) return None case ListKeys(): # Return a list of all keys in the store return sorted(self.kv) async def serve_forever(self) -> None: server = await asyncio.start_server( self.handle_connection, self.host, self.port ) print(f"Serving on tcp://{self.host}:{self.port}...") async with server: await server.serve_forever() def run(self) -> None: """Run the server until ctrl-C""" asyncio.run(self.serve_forever()) class Client: """An example TCP key-value client using asyncio and msgspec.""" def __init__(self, reader: asyncio.StreamReader, writer: asyncio.StreamWriter): self.reader = reader self.writer = writer @classmethod async def create(cls, host: str = "127.0.0.1", port: int = 8888): """Create a new client""" reader, writer = await asyncio.open_connection(host, port) return cls(reader, writer) async def close(self) -> None: """Close the client.""" self.writer.close() await self.writer.wait_closed() async def request(self, req): """Send a request and await the response""" # Encode and send the request buffer = msgspec.msgpack.encode(req) await prefixed_send(self.writer, buffer) # Receive and decode the response buffer = await prefixed_recv(self.reader) return msgspec.msgpack.decode(buffer) async def get(self, key: str) -> str | None: """Get a key from the KV store, returning None if not present""" return await self.request(Get(key)) async def put(self, key: str, val: str) -> None: """Put a key-val pair in the KV store""" return await self.request(Put(key, val)) async def delete(self, key: str) -> None: """Delete a key-val pair from the KV store""" return await self.request(Del(key)) async def list_keys(self) -> list[str]: """List all keys in the KV store""" return await self.request(ListKeys()) if __name__ == "__main__": Server().run() python-msgspec-0.22.0/examples/conda-repodata/000077500000000000000000000000001525673062400212645ustar00rootroot00000000000000python-msgspec-0.22.0/examples/conda-repodata/query_repodata.py000066400000000000000000000040651525673062400246670ustar00rootroot00000000000000import json import time import orjson import requests import simdjson import ujson import msgspec def query_msgspec(data: bytes) -> list[tuple[int, str]]: # Use Struct types to define the JSON schema. For efficiency we only define # the fields we actually need. class Package(msgspec.Struct): name: str size: int class RepoData(msgspec.Struct): packages: dict[str, Package] # Decode the data as a `RepoData` type repo_data = msgspec.json.decode(data, type=RepoData) # Sort packages by `size`, and return the top 10 return sorted( ((p.size, p.name) for p in repo_data.packages.values()), reverse=True )[:10] def query_orjson(data: bytes) -> list[tuple[int, str]]: repo_data = orjson.loads(data) return sorted( ((p["size"], p["name"]) for p in repo_data["packages"].values()), reverse=True )[:10] def query_json(data: bytes) -> list[tuple[int, str]]: repo_data = json.loads(data) return sorted( ((p["size"], p["name"]) for p in repo_data["packages"].values()), reverse=True )[:10] def query_ujson(data: bytes) -> list[tuple[int, str]]: repo_data = ujson.loads(data) return sorted( ((p["size"], p["name"]) for p in repo_data["packages"].values()), reverse=True )[:10] def query_simdjson(data: bytes) -> list[tuple[int, str]]: repo_data = simdjson.Parser().parse(data) return sorted( ((p["size"], p["name"]) for p in repo_data["packages"].values()), reverse=True )[:10] # Download the current_repodata.json file resp = requests.get( "https://conda.anaconda.org/conda-forge/noarch/current_repodata.json" ) resp.raise_for_status() data = resp.content libraries = [ ("json", query_json), ("ujson", query_ujson), ("orjson", query_orjson), ("simdjson", query_simdjson), ("msgspec", query_msgspec), ] # Run the query with each JSON library, timing the execution for lib, func in libraries: start = time.perf_counter() func(data) stop = time.perf_counter() print(f"{lib}: {(stop - start) * 1000:.2f} ms") python-msgspec-0.22.0/examples/geojson/000077500000000000000000000000001525673062400200475ustar00rootroot00000000000000python-msgspec-0.22.0/examples/geojson/canada.json000066400000000000000000077623721525673062400222010ustar00rootroot00000000000000{"type":"FeatureCollection","features":[{"type":"Feature","properties":{"name":"Canada"},"geometry":{"type":"Polygon","coordinates":[[[-65.61361699999998,43.42027300000001],[-65.61972000000003,43.418052999999986],[-65.625,43.42137900000006],[-65.63612399999988,43.44971499999997],[-65.63305699999995,43.47470900000013],[-65.61138900000003,43.51305400000007],[-65.60583500000001,43.51610599999998],[-65.598343,43.515830999999935],[-65.566101,43.508331000000055],[-65.561935,43.50443999999999],[-65.55999799999995,43.49971800000009],[-65.57333399999999,43.476379000000065],[-65.59361299999995,43.44415300000003],[-65.61361699999998,43.42027300000001]],[[-59.81694799999991,43.92832899999996],[-59.84166700000003,43.91860200000002],[-59.86639399999996,43.909988],[-59.879722999999956,43.906654],[-59.895835999999974,43.90416000000005],[-59.91944899999993,43.901099999999985],[-59.95333099999999,43.898604999999975],[-60.01361799999995,43.90332000000001],[-60.02860999999996,43.905548000000124],[-60.078338999999914,43.91749600000003],[-60.10388899999998,43.92665900000003],[-60.121666000000005,43.934990000000084],[-60.129997,43.94193300000006],[-60.124168,43.94526700000006],[-60.09500099999997,43.93943000000013],[-60.017776000000026,43.92582700000008],[-59.975554999999986,43.92193600000002],[-59.96694200000002,43.92193600000002],[-59.91500099999996,43.925552000000096],[-59.86194599999999,43.93443300000001],[-59.841385,43.93888099999998],[-59.80972300000002,43.950829],[-59.793334999999956,43.9594350000001],[-59.77722199999994,43.96804800000007],[-59.75527999999997,43.97943100000009],[-59.724716,43.99110400000012],[-59.72777599999995,43.98638200000005],[-59.73638900000003,43.9791560000001],[-59.753615999999965,43.964995999999985],[-59.76250499999992,43.95777100000009],[-59.782501000000025,43.944435],[-59.79305999999997,43.93832400000008],[-59.81694799999991,43.92832899999996]],[[-66.28277599999996,44.289719000000105],[-66.314438,44.25054899999998],[-66.32223499999998,44.252777000000094],[-66.32444800000002,44.25750000000005],[-66.32389799999999,44.26332900000011],[-66.310272,44.28999300000004],[-66.30305499999992,44.30054500000006],[-66.29472399999992,44.310272],[-66.22833300000002,44.38582600000001],[-66.21945199999999,44.394713999999965],[-66.214447,44.39777400000003],[-66.20638999999994,44.39527100000004],[-66.20472699999993,44.384995],[-66.20527599999997,44.37943300000006],[-66.20805399999995,44.37276500000007],[-66.21472199999994,44.36360900000011],[-66.24972500000001,44.32721700000013],[-66.28277599999996,44.289719000000105]],[[-66.886124,44.614441],[-66.900284,44.61332699999997],[-66.90417499999995,44.61804999999998],[-66.904449,44.62248999999997],[-66.88473499999998,44.68332700000002],[-66.85861199999994,44.74305000000004],[-66.83778399999994,44.770827999999995],[-66.83332799999994,44.77499400000005],[-66.80332900000002,44.79888199999999],[-66.79804999999993,44.80249000000009],[-66.78666699999985,44.80804400000011],[-66.77972399999993,44.80915800000008],[-66.77250700000002,44.80915800000008],[-66.76722699999993,44.80554999999998],[-66.764725,44.801102000000014],[-66.75778199999996,44.792496000000085],[-66.73472600000002,44.7291560000001],[-66.73693800000001,44.71720900000014],[-66.74027999999993,44.70777099999998],[-66.761124,44.67610200000013],[-66.765015,44.671378999999945],[-66.87527499999993,44.61943800000006],[-66.886124,44.614441]],[[-61.199996999999996,45.55832700000008],[-61.20472000000001,45.55526700000007],[-61.21277599999996,45.55665600000003],[-61.219993999999986,45.55999000000003],[-61.22416700000002,45.56415600000014],[-61.222220999999934,45.569443000000035],[-61.21416499999998,45.568886000000134],[-61.20861099999996,45.56721500000009],[-61.20249899999999,45.56332400000002],[-61.199996999999996,45.55832700000008]],[[-60.993889000000024,45.45777099999998],[-61.00028199999997,45.455826],[-61.00778199999996,45.45721400000008],[-61.01944699999996,45.46388200000007],[-61.101943999999946,45.52304800000002],[-61.10583500000001,45.526939000000084],[-61.108337000000006,45.54083300000002],[-61.10444599999994,45.54638700000004],[-61.09860999999995,45.549164000000076],[-61.023612999999955,45.57499700000005],[-61.01722000000001,45.57527200000004],[-60.936942999999985,45.57665999999995],[-60.908051,45.576103000000046],[-60.900275999999906,45.575554000000125],[-60.879996999999946,45.5605470000001],[-60.87860899999987,45.55582400000014],[-60.88388800000001,45.55054499999994],[-60.889167999999984,45.548332000000016],[-60.91027799999995,45.54610400000007],[-60.93611099999998,45.539161999999976],[-60.947495,45.533607000000075],[-60.95249899999993,45.529990999999995],[-60.962501999999915,45.519989000000066],[-60.96305799999999,45.51499899999999],[-60.96166999999991,45.51027700000009],[-60.95861100000002,45.50582900000012],[-60.950553999999954,45.497772],[-60.993889000000024,45.45777099999998]],[[-63.24639100000002,46.43554700000004],[-63.25389100000001,46.43526500000013],[-63.26167299999986,46.43637800000005],[-63.26944699999996,46.4397130000001],[-63.285004000000015,46.450829000000056],[-63.27055399999989,46.450271999999984],[-63.245834,46.442764000000125],[-63.240837,46.438599000000124],[-63.24639100000002,46.43554700000004]],[[-71.11111499999998,46.850548],[-71.118607,46.850273000000016],[-71.12748699999992,46.85166200000003],[-71.13027999999991,46.85610200000002],[-71.12832600000002,46.86221300000011],[-71.12138399999998,46.87416100000013],[-71.09889199999998,46.89804800000002],[-71.07833900000003,46.913605000000075],[-70.936935,46.992493000000024],[-70.89666699999987,47.013329000000056],[-70.87222300000002,47.02416200000005],[-70.86000100000001,47.02777100000003],[-70.84527600000001,47.02916000000005],[-70.83639499999998,47.02777100000003],[-70.818893,47.02276599999999],[-70.81361400000003,47.019440000000145],[-70.80915800000002,47.01527400000009],[-70.80749500000002,47.00999500000006],[-70.80943299999996,47.00443999999999],[-70.814438,46.998329000000126],[-70.87721299999998,46.93110700000011],[-70.88751200000002,46.923607000000004],[-70.90417499999995,46.913605000000075],[-71.00917099999992,46.87110100000007],[-71.03332499999993,46.86249499999997],[-71.04083299999996,46.86054999999999],[-71.08222999999992,46.8533250000001],[-71.11111499999998,46.850548]],[[-60.44527399999998,46.86166400000013],[-60.436942999999985,46.86110700000006],[-60.35278299999999,46.86166400000013],[-60.34583299999986,46.86249499999997],[-60.33444199999997,46.8688810000001],[-60.32611099999997,46.86832399999997],[-60.32083899999998,46.864441000000056],[-60.309440999999936,46.85110500000013],[-60.302223000000026,46.837493999999936],[-60.30139200000002,46.831940000000145],[-60.304442999999935,46.815269000000114],[-60.32277699999992,46.73638200000005],[-60.327224999999885,46.724991000000045],[-60.47888199999994,46.38999200000006],[-60.53527799999995,46.32166300000006],[-60.58943899999986,46.25499700000006],[-60.60916900000001,46.201934999999935],[-60.59033199999993,46.20782100000008],[-60.587001999999984,46.209488000000135],[-60.57150299999995,46.22865300000012],[-60.55332900000002,46.24887800000005],[-60.551391999999964,46.25499700000006],[-60.54333500000001,46.26666300000005],[-60.528053,46.27860299999992],[-60.479720999999984,46.31110400000006],[-60.46805599999999,46.316666],[-60.44388600000002,46.32694200000009],[-60.43055700000002,46.33138299999996],[-60.424171,46.331665000000044],[-60.41638899999987,46.32804900000002],[-60.412216,46.31888600000002],[-60.41777799999994,46.28582799999998],[-60.419997999999964,46.27999100000005],[-60.42472099999992,46.27526899999998],[-60.43804899999992,46.27082800000005],[-60.45471999999995,46.26221500000008],[-60.47055099999994,46.25110599999999],[-60.53583100000003,46.19243600000004],[-60.59027900000001,46.1386030000001],[-60.60028099999994,46.13027199999999],[-60.61611199999993,46.12082700000013],[-60.64583600000003,46.10610200000002],[-60.687774999999874,46.08832600000005],[-60.70111099999991,46.08526599999999],[-60.788895000000025,46.066666000000055],[-60.86333499999995,46.052490000000034],[-60.98611499999993,45.982491000000095],[-61.02388799999994,45.96943700000003],[-61.08028399999995,45.951660000000004],[-61.08777600000002,45.95138500000013],[-61.09583299999997,45.952217000000076],[-61.10500300000001,45.954712000000086],[-61.113059999999905,45.95526899999999],[-61.11777499999994,45.950829],[-61.12694499999998,45.92832900000013],[-61.12555699999996,45.92360700000006],[-61.11833200000001,45.92304999999993],[-61.05699900000002,45.93121699999995],[-61.05283400000002,45.93188100000003],[-61.01749799999999,45.940712000000076],[-61.014835000000005,45.94338200000004],[-60.989165999999955,45.95638300000013],[-60.987777999999935,45.96249400000005],[-60.98416899999995,45.96749099999994],[-60.957221999999945,45.984992999999974],[-60.94055199999991,45.99443800000006],[-60.892776000000026,46.01527400000009],[-60.853057999999976,46.03138000000007],[-60.77083599999992,46.057495000000074],[-60.75750699999992,46.060546999999985],[-60.743056999999965,46.061661000000015],[-60.73555799999991,46.05804400000005],[-60.73416900000001,46.05332199999998],[-60.73416900000001,46.047493000000145],[-60.807503,45.93110700000011],[-60.87027699999999,45.91082000000006],[-60.898056,45.90665400000012],[-60.956947000000014,45.90304600000002],[-61.042888999999946,45.8913270000001],[-61.047053999999946,45.890659000000085],[-61.05055599999997,45.88899199999997],[-61.053390999999976,45.88616200000013],[-61.096663999999976,45.860275],[-61.09777799999995,45.85471300000006],[-61.094719,45.850273000000016],[-61.08777600000002,45.847488],[-61.07972699999999,45.84693900000002],[-61.073059,45.84804500000007],[-61.06082900000001,45.852776000000006],[-61.04944599999999,45.858330000000024],[-61.026107999999965,45.86971299999999],[-60.98999799999996,45.881935],[-60.96805599999999,45.883331000000055],[-60.96028100000001,45.88027200000005],[-60.919448999999986,45.85749800000008],[-60.91583300000002,45.852776000000006],[-60.91777799999994,45.847488],[-60.93527199999994,45.825271999999984],[-60.94055199999991,45.821663],[-60.947495,45.82054900000003],[-61.01944699999996,45.80998999999997],[-61.06750499999998,45.79166399999997],[-61.079169999999976,45.78611000000001],[-61.11805700000002,45.763611000000026],[-61.12777699999998,45.75527199999999],[-61.147223999999994,45.704994],[-61.14917000000003,45.699715000000026],[-61.14250199999992,45.69638100000003],[-61.07749899999993,45.68888099999998],[-61.07083899999998,45.68998700000003],[-61.041945999999996,45.704162999999994],[-61.012778999999966,45.71888000000001],[-60.99639100000002,45.72776799999997],[-60.97277100000002,45.738045],[-60.95471999999995,45.74554399999994],[-60.93582900000001,45.751389000000074],[-60.92222599999991,45.75360900000004],[-60.914443999999946,45.75360900000004],[-60.890556000000004,45.75166300000001],[-60.88194299999992,45.75000000000006],[-60.8641659999999,45.744438000000116],[-60.84416199999998,45.735268000000076],[-60.816666,45.72248800000011],[-60.80999800000001,45.71915400000012],[-60.800835000000006,45.71166199999999],[-60.72943899999996,45.77860300000003],[-60.719719,45.78832999999997],[-60.516944999999964,45.92083000000014],[-60.49194299999988,45.92943600000007],[-60.46694200000002,45.938041999999996],[-60.409163999999976,45.979987999999935],[-60.40416699999997,45.98443600000007],[-60.395835999999974,45.99610100000001],[-60.40166499999998,45.994713000000104],[-60.55500000000001,45.9469380000001],[-60.611671,45.92499500000014],[-60.6297229999999,45.91749600000014],[-60.63999899999999,45.91027100000008],[-60.644721999999945,45.905548000000124],[-60.655272999999966,45.898330999999985],[-60.66111000000001,45.89527099999992],[-60.6733319999999,45.89054900000002],[-60.686110999999926,45.88694000000004],[-60.69388600000002,45.88610799999992],[-60.708892999999875,45.887215000000026],[-60.72332799999998,45.893326000000116],[-60.78833799999995,45.92943600000007],[-60.78972599999997,45.934433000000126],[-60.788895000000025,45.939986999999974],[-60.785278000000005,45.94638100000003],[-60.78055599999999,45.950829],[-60.69138299999997,46.00193799999994],[-60.679168999999945,46.00666000000001],[-60.601395000000025,46.039719000000105],[-60.54111499999999,46.0655440000001],[-60.523612999999955,46.07555400000001],[-60.49083699999994,46.094437000000084],[-60.30999799999995,46.206939999999975],[-60.30499999999995,46.210548000000074],[-60.29999499999997,46.21499600000004],[-60.295279999999934,46.22693600000014],[-60.295279999999934,46.23220800000007],[-60.304169,46.233878999999945],[-60.36555499999997,46.22499099999999],[-60.372772,46.223320000000115],[-60.39611100000002,46.213051000000064],[-60.40193899999991,46.21027399999997],[-60.41833500000001,46.199996999999996],[-60.428054999999915,46.19249000000008],[-60.442497,46.17943600000001],[-60.46333299999992,46.16387900000012],[-60.47916399999991,46.15277100000014],[-60.528053,46.12165800000014],[-60.60583500000001,46.07471500000008],[-60.629997,46.065269000000114],[-60.64416499999999,46.06304900000009],[-60.65193899999997,46.06388099999998],[-60.65610499999997,46.06777200000005],[-60.65638699999994,46.07305100000002],[-60.652495999999985,46.079436999999984],[-60.63833599999987,46.093048000000124],[-60.45610799999997,46.24137900000005],[-60.404998999999975,46.27999100000005],[-60.399726999999984,46.28388200000012],[-60.388892999999996,46.291106999999954],[-60.35972599999997,46.30499300000014],[-60.347778000000005,46.310546999999985],[-60.285278000000005,46.32138100000003],[-60.205558999999994,46.240273],[-60.13805400000001,46.246658000000025],[-60.13194299999992,46.248604000000114],[-60.124168,46.248604000000114],[-60.09999799999997,46.24638400000009],[-60.091666999999916,46.24471300000005],[-59.9505539999999,46.20138500000007],[-59.873054999999965,46.17582699999997],[-59.808608999999876,46.111938000000066],[-59.80972300000002,46.10638400000005],[-59.81944999999996,46.09721400000001],[-59.83416699999998,46.08471700000001],[-59.853888999999924,46.00249500000001],[-59.840553,45.93832400000002],[-59.95861099999996,45.90165700000006],[-60.13027999999997,45.86776700000013],[-60.13611599999996,45.86499799999996],[-60.155272999999966,45.84665699999999],[-60.15943899999996,45.841102999999976],[-60.160552999999936,45.835548000000074],[-60.17444599999999,45.76388500000013],[-60.22916399999997,45.70555100000013],[-60.233886999999925,45.70110299999993],[-60.245834,45.69499200000007],[-60.37972300000001,45.644997000000046],[-60.39222699999999,45.64110599999998],[-60.411666999999966,45.636940000000095],[-60.49888599999997,45.62026999999995],[-60.513061999999934,45.61888099999999],[-60.55750299999994,45.61804999999998],[-60.765556000000004,45.5949940000001],[-60.96083099999993,45.59943399999992],[-61.101669000000015,45.564437999999996],[-61.14833799999991,45.55526700000007],[-61.168334999999956,45.5513840000001],[-61.19691799999998,45.58374000000009],[-61.21869699999996,45.5807880000001],[-61.237521999999956,45.58152800000005],[-61.273056,45.561935000000005],[-61.336945000000014,45.57332600000001],[-61.37557599999991,45.62213100000014],[-61.430556999999965,45.66554300000007],[-61.45471999999995,45.70555100000013],[-61.45750399999997,45.71527100000003],[-61.478049999999996,45.80387900000011],[-61.49472000000003,45.84638199999995],[-61.527495999999985,45.98943300000002],[-61.455558999999994,46.13749700000005],[-61.447776999999974,46.14943699999998],[-61.43888899999996,46.159430999999984],[-61.41277299999996,46.178329000000076],[-61.39083900000003,46.191376000000105],[-61.37388599999997,46.20082900000011],[-61.34332999999992,46.21249399999999],[-61.30555700000002,46.22499099999999],[-61.29389200000003,46.230819999999994],[-61.28333299999997,46.23888400000004],[-61.09722099999999,46.44609800000012],[-61.08943899999991,46.45804600000014],[-61.035278000000005,46.55554999999998],[-61.033057999999926,46.56166100000007],[-61.031113000000005,46.57276900000005],[-61.032501000000025,46.57749200000006],[-60.99694799999992,46.63472000000007],[-60.89222699999999,46.77388000000002],[-60.87361099999987,46.79305299999993],[-60.86361699999992,46.80138400000004],[-60.84027900000001,46.81360599999999],[-60.833884999999896,46.81554399999993],[-60.80555700000002,46.82027399999998],[-60.79389200000003,46.825271999999984],[-60.724716,46.874992000000134],[-60.714721999999995,46.88249200000007],[-60.70444499999991,46.89138000000003],[-60.69527399999993,46.901657],[-60.68666099999996,46.912491000000045],[-60.67833699999994,46.93082400000014],[-60.67055499999998,46.953606000000036],[-60.664444,46.96610300000003],[-60.65694400000001,46.97860000000003],[-60.64028200000001,47],[-60.60916900000001,47.02443700000009],[-60.59777799999989,47.031105000000025],[-60.59194200000002,47.03333300000003],[-60.58332799999994,47.031661999999926],[-60.46083099999987,46.999161000000015],[-60.427498000000014,46.96582799999999],[-60.493889000000024,46.90221400000007],[-60.49805500000002,46.89666000000011],[-60.45222499999994,46.864441000000056],[-60.44527399999998,46.86166400000013]],[[-64.03971899999999,46.74332400000009],[-64.031677,46.742767000000015],[-64.01640299999991,46.743607000000054],[-64.00917099999998,46.74415600000003],[-64.00500499999998,46.74971800000014],[-63.99999999999994,46.75360900000004],[-63.991668999999945,46.75305200000014],[-63.97916399999991,46.74638399999998],[-63.974715999999944,46.74249300000008],[-63.83250399999997,46.61721000000006],[-63.83167300000002,46.61193800000012],[-63.86500499999988,46.537498000000085],[-63.86888899999997,46.531937000000084],[-63.840836000000024,46.46443899999991],[-63.82833900000003,46.45804600000014],[-63.780281,46.44499200000007],[-63.74222600000002,46.43943000000013],[-63.73305499999998,46.43888100000004],[-63.709442000000024,46.43749200000002],[-63.703888000000006,46.4405440000001],[-63.698050999999964,46.45638300000007],[-63.69860799999998,46.46166200000005],[-63.70027900000002,46.466385],[-63.72277100000002,46.48054500000012],[-63.73805199999998,46.491378999999995],[-63.739998000000014,46.49610100000007],[-63.723327999999924,46.54361000000006],[-63.716110000000015,46.55387900000011],[-63.709723999999994,46.55609900000013],[-63.676391999999964,46.56415600000008],[-63.662216,46.56638299999997],[-63.64722399999988,46.56721500000009],[-63.618889000000024,46.561104],[-63.49777999999998,46.52777100000014],[-63.315001999999936,46.48860200000007],[-63.27197999999993,46.426926000000094],[-63.240661999999986,46.420456],[-63.21639299999998,46.41220900000013],[-62.94277199999988,46.42694100000011],[-62.862777999999935,46.4347150000001],[-62.69860799999998,46.45249200000001],[-62.692497,46.456100000000106],[-62.686385999999914,46.457497000000046],[-62.66583300000002,46.461104999999975],[-62.595001000000025,46.47082500000005],[-62.47721899999999,46.477768000000026],[-62.455558999999994,46.47860000000014],[-62.182503,46.48582499999998],[-62.16638899999998,46.48610700000006],[-62.13333099999994,46.482764999999915],[-62.058051999999975,46.472762999999986],[-62.01472499999994,46.46527100000003],[-61.979720999999984,46.45915999999994],[-61.970551,46.456940000000145],[-61.965003999999965,46.45332300000001],[-61.968886999999995,46.447768999999994],[-61.97360999999995,46.44304700000009],[-62.01306199999999,46.42110400000013],[-62.101112,46.37971500000003],[-62.17333199999996,46.349433999999974],[-62.21555299999994,46.34360500000014],[-62.27972399999993,46.33804300000003],[-62.309166000000005,46.349998000000085],[-62.326392999999996,46.354996000000085],[-62.34277300000002,46.356102000000135],[-62.357779999999934,46.35582700000009],[-62.355834999999956,46.35083000000003],[-62.34805299999999,46.33221400000002],[-62.334723999999994,46.31193500000006],[-62.36194599999993,46.27665700000006],[-62.419448999999986,46.21998600000012],[-62.42472099999998,46.215546000000074],[-62.453888000000006,46.21443899999997],[-62.50750699999992,46.214157000000114],[-62.603888999999924,46.18249500000013],[-62.603888999999924,46.17721599999999],[-62.54222900000002,46.12249000000003],[-62.50750699999992,46.118881000000044],[-62.5,46.11915600000009],[-62.47833300000002,46.12082700000013],[-62.47721899999999,46.126380999999924],[-62.478882,46.13193500000011],[-62.481667000000016,46.13638300000008],[-62.489998000000014,46.138329],[-62.49722299999996,46.13804600000003],[-62.506110999999976,46.139717000000076],[-62.513892999999996,46.142220000000066],[-62.509727,46.14860500000003],[-62.504448000000025,46.150825999999995],[-62.48916600000001,46.151382000000126],[-62.47305299999999,46.150269000000094],[-62.468886999999995,46.14610299999998],[-62.44916499999994,46.100548],[-62.44749499999995,46.095543000000134],[-62.44694500000003,46.09054600000002],[-62.45472000000001,46.01888300000007],[-62.45916699999998,46.00638600000008],[-62.47360999999995,45.994713000000104],[-62.496947999999975,45.983879],[-62.51000199999993,45.979156000000046],[-62.54167199999995,45.97054300000008],[-62.54861499999993,45.96943700000003],[-62.59166700000003,45.9649960000001],[-62.613891999999964,45.96276900000004],[-62.65027600000002,45.96027400000003],[-62.76111599999996,45.95416299999994],[-62.83777600000002,45.96749099999994],[-62.856667000000016,45.977486000000056],[-62.88277399999998,45.99554400000011],[-62.93028300000003,46.037215999999944],[-62.97083299999997,46.07416500000005],[-62.922500999999954,46.09249100000005],[-62.917220999999984,46.09638200000012],[-62.87527499999993,46.134995],[-62.871940999999936,46.14360799999997],[-62.885276999999974,46.155823000000055],[-62.89083900000003,46.159430999999984],[-63.02527600000002,46.18915600000008],[-63.10361499999999,46.201934999999935],[-63.11277799999999,46.20416300000011],[-63.11944599999987,46.207214000000135],[-63.12222300000002,46.2116620000001],[-63.12027699999999,46.2177660000001],[-63.11583699999994,46.222488],[-63.038895000000025,46.28027300000008],[-63.02416999999997,46.29027599999995],[-63.017776000000026,46.29249600000014],[-63.01028400000001,46.292770000000075],[-63.002228,46.28999299999998],[-62.99610899999999,46.292220999999984],[-62.97943899999996,46.30165899999997],[-62.96916199999998,46.309432999999956],[-62.96472199999988,46.31415600000014],[-62.96277599999996,46.31999200000001],[-62.96944399999995,46.31888600000002],[-63.03527799999989,46.30165899999997],[-63.04138899999998,46.299721000000034],[-63.05277999999993,46.29388400000005],[-63.05860899999993,46.29083300000002],[-63.090836000000024,46.26915699999995],[-63.16500100000002,46.210548000000074],[-63.143332999999984,46.20166000000012],[-63.139167999999984,46.19776900000005],[-63.13861099999991,46.19249000000008],[-63.140556000000004,46.186378000000104],[-63.22444200000001,46.139717000000076],[-63.23860899999994,46.13804600000003],[-63.253615999999965,46.13749700000005],[-63.26167299999986,46.13804600000003],[-63.289169000000015,46.14388299999996],[-63.40916399999992,46.176941],[-63.519722,46.206099999999935],[-63.59194200000002,46.21193700000009],[-63.64277599999991,46.22499099999999],[-63.64972699999993,46.22804300000007],[-63.69972200000001,46.25943799999999],[-63.700553999999954,46.269989000000066],[-63.702225,46.27526899999998],[-63.70666499999993,46.27860299999992],[-63.741942999999935,46.30443600000007],[-63.75444799999997,46.310822000000144],[-63.811110999999926,46.32749200000012],[-63.77222399999994,46.36082500000009],[-63.73694599999993,46.35388200000011],[-63.72916399999997,46.35277600000006],[-63.714721999999995,46.354164000000026],[-63.73916600000001,46.391106000000036],[-63.745003,46.394714000000135],[-63.75444799999997,46.39638500000001],[-63.76167299999992,46.39666],[-63.84110999999996,46.39888000000002],[-63.963615000000004,46.40110000000004],[-63.981941000000006,46.39388300000013],[-63.9891659999999,46.393608000000086],[-64.12193300000001,46.404709000000025],[-64.12998999999996,46.40721100000013],[-64.13305700000001,46.4116590000001],[-64.13500999999991,46.416382000000056],[-64.13305700000001,46.43332700000002],[-64.11582899999996,46.52304800000002],[-64.11332699999997,46.53472099999999],[-64.11000099999995,46.541107000000125],[-64.10555999999997,46.54583000000008],[-64.10028099999988,46.54972099999998],[-64.09416199999993,46.551659000000086],[-64.10555999999997,46.618050000000096],[-64.27389499999998,46.62332200000003],[-64.38751199999996,46.62082700000002],[-64.39195299999994,46.624709999999936],[-64.41389500000002,46.6658250000001],[-64.41555800000003,46.670547],[-64.41665599999993,46.68110699999994],[-64.41471899999999,46.69776900000011],[-64.41027799999995,46.71110500000009],[-64.40028399999994,46.72748600000011],[-64.38249200000001,46.74665800000008],[-64.34695399999998,46.77360500000003],[-64.32389799999993,46.786384999999996],[-64.29638699999998,46.80165900000003],[-64.28611799999993,46.80943300000007],[-64.27305599999994,46.82360799999998],[-64.24972499999996,46.86805000000004],[-64.24777199999994,46.87416100000013],[-64.2472229999999,46.879714999999976],[-64.24388099999999,46.88610800000009],[-64.23638900000003,46.897491000000116],[-64.22694399999995,46.906097000000045],[-64.18277,46.945541000000105],[-64.16861,46.956657000000064],[-64.02084400000001,47.03860500000013],[-63.99500299999994,46.984161000000086],[-63.969993999999986,46.901657],[-63.96749899999986,46.891662999999994],[-64.041382,46.82249500000006],[-64.06610099999995,46.80443600000012],[-64.07640100000003,46.79888199999999],[-64.09167499999995,46.77860300000003],[-64.07749899999993,46.756386000000134],[-64.07444800000002,46.75222000000002],[-64.06750499999993,46.74916100000007],[-64.03971899999999,46.74332400000009]],[[-55.87610599999999,47.26055100000002],[-55.96832999999987,47.25777399999993],[-55.94638800000001,47.27332300000006],[-55.934440999999936,47.279434000000094],[-55.89500399999997,47.29083300000002],[-55.888053999999954,47.29249600000014],[-55.881110999999976,47.29332699999998],[-55.872772,47.2922210000001],[-55.865836999999885,47.28777300000013],[-55.85500300000001,47.26971400000002],[-55.87610599999999,47.26055100000002]],[[-61.38055400000002,47.62027000000012],[-61.49305700000002,47.55249000000009],[-61.498610999999926,47.55027000000007],[-61.53556099999997,47.54583000000008],[-61.54222900000002,47.54554700000011],[-61.54778299999987,47.549164000000076],[-61.54944599999999,47.55387900000011],[-61.54527999999999,47.55943300000007],[-61.520279000000016,47.56916000000001],[-61.51389299999994,47.57249500000012],[-61.477492999999924,47.60054800000006],[-61.47361000000001,47.6055530000001],[-61.471382000000006,47.611382000000106],[-61.470551,47.61693600000012],[-61.47916399999997,47.61859900000002],[-61.534447,47.6188810000001],[-61.541945999999996,47.61721000000006],[-61.55944099999999,47.60916100000003],[-61.653610000000015,47.54999500000008],[-61.85555999999997,47.41721300000006],[-61.84972399999998,47.41360500000013],[-61.84166700000003,47.410820000000115],[-61.83361100000002,47.409988],[-61.789169000000015,47.42582700000008],[-61.777221999999995,47.43166400000007],[-61.76666299999994,47.439156000000025],[-61.71444700000001,47.48998999999998],[-61.69138299999997,47.515548999999965],[-61.70139299999994,47.49193600000007],[-61.74083699999994,47.44499200000007],[-61.84332999999992,47.388603000000046],[-61.90589099999994,47.35493500000001],[-61.92527799999999,47.34360500000014],[-61.93332700000002,47.33332799999994],[-61.96277600000002,47.2816620000001],[-61.965003999999965,47.27555100000001],[-61.964721999999995,47.27027100000009],[-61.961945000000014,47.26610600000009],[-61.95750399999997,47.26194000000004],[-61.93860599999999,47.257217000000026],[-61.82778200000001,47.23416100000003],[-61.81945000000002,47.233330000000024],[-61.80777699999999,47.23915900000003],[-61.79944599999999,47.25027499999993],[-61.79472399999992,47.254714999999976],[-61.78305799999987,47.26055100000002],[-61.782775999999956,47.25527200000005],[-61.789725999999916,47.242493000000024],[-61.79389200000003,47.23693800000012],[-61.79944599999999,47.23276499999997],[-61.81027999999998,47.22665400000005],[-61.816948000000025,47.224709000000075],[-61.84444400000001,47.21943699999997],[-61.85944399999988,47.21804799999995],[-61.955276000000026,47.21166200000005],[-61.97999599999997,47.213608000000136],[-61.9963909999999,47.21499600000004],[-62.004722999999956,47.2177660000001],[-62.01000199999987,47.22137500000008],[-62.01306199999999,47.225821999999994],[-62.01472499999994,47.23054500000012],[-62.01500699999991,47.235825000000034],[-62.01306199999999,47.24166100000008],[-61.94860799999998,47.37943299999995],[-61.94166599999994,47.39221999999995],[-61.93749999999994,47.39777400000014],[-61.92805499999997,47.407211000000075],[-61.92222599999997,47.409988],[-61.90888999999993,47.413879000000065],[-61.736114999999984,47.50721699999997],[-61.705832999999984,47.5324940000001],[-61.684440999999936,47.547492999999974],[-61.662216,47.56166100000007],[-61.61694299999999,47.588042999999914],[-61.57111400000002,47.613609],[-61.55361199999999,47.623046999999985],[-61.53583500000002,47.631659999999954],[-61.52916700000003,47.63360600000004],[-61.52111099999996,47.63443799999999],[-61.42527799999999,47.642769000000044],[-61.407775999999956,47.64110599999992],[-61.388892999999996,47.637771999999984],[-61.38194299999992,47.63443799999999],[-61.377776999999924,47.63110399999999],[-61.37610599999999,47.62638099999998],[-61.38055400000002,47.62027000000012]],[[-54.261391,47.39027400000009],[-54.26889,47.38971700000002],[-54.29305999999997,47.39166300000005],[-54.341385,47.398048000000074],[-54.35805499999998,47.403046000000074],[-54.36444899999998,47.406654],[-54.365554999999915,47.41165900000004],[-54.35972600000002,47.41666400000008],[-54.326392999999996,47.436653000000035],[-54.29527999999999,47.44999700000011],[-54.278053,47.46082300000006],[-54.26722000000001,47.469437000000084],[-54.26222200000001,47.47470900000002],[-54.25778199999996,47.48082000000011],[-54.230552999999986,47.52360500000003],[-54.22999600000003,47.55027000000007],[-54.20471999999995,47.59360500000008],[-54.13527699999986,47.66805300000004],[-54.12888299999997,47.670547],[-54.122772,47.66693900000007],[-54.12194099999999,47.66193400000003],[-54.12222299999996,47.656937000000084],[-54.12499999999994,47.640831000000105],[-54.16082799999998,47.534996000000035],[-54.23889200000002,47.40387700000008],[-54.24333199999995,47.39943700000009],[-54.25500499999998,47.3927690000001],[-54.261391,47.39027400000009]],[[-54.07749899999999,47.47943100000009],[-54.08306099999993,47.4749910000001],[-54.09305599999993,47.483047],[-54.096663999999976,47.487213000000054],[-54.101112,47.496384000000035],[-54.101944,47.501389000000074],[-54.099723999999924,47.55888399999998],[-54.09833500000002,47.589714000000015],[-54.097220999999934,47.60527000000013],[-54.09332999999998,47.631659999999954],[-54.08361099999996,47.67971799999992],[-54.07861299999996,47.68499000000003],[-54.07138800000001,47.68554699999993],[-54.06750499999998,47.68110700000011],[-54.06055500000002,47.651099999999985],[-54.078056000000004,47.56388100000004],[-54.05972300000002,47.53221100000013],[-54.05889100000002,47.52721400000007],[-54.07749899999999,47.47943100000009]],[[-55.90193899999986,47.60249300000004],[-55.92305799999991,47.59943400000009],[-55.947220000000016,47.60193600000014],[-56.01333599999998,47.61166400000002],[-56.097778000000005,47.62748700000003],[-56.105559999999855,47.630821000000026],[-56.10916900000001,47.63499500000006],[-56.11361699999998,47.64471400000002],[-56.11222099999998,47.64971900000012],[-56.10666699999996,47.65470900000014],[-56.10028099999994,47.65721100000002],[-56.00583599999999,47.680274999999995],[-55.94110899999998,47.68915600000014],[-55.93388399999998,47.68832400000002],[-55.92861199999993,47.684432999999956],[-55.927498000000014,47.67665899999997],[-55.934440999999936,47.65888200000012],[-55.934440999999936,47.65387700000002],[-55.932503,47.64388300000002],[-55.93000000000001,47.63943500000005],[-55.92639200000002,47.635268999999994],[-55.914161999999976,47.628326000000015],[-55.88944200000003,47.6188810000001],[-55.87638899999996,47.61166400000002],[-55.882499999999936,47.60777300000012],[-55.90193899999986,47.60249300000004]],[[-64.48277300000001,47.91777000000002],[-64.50167799999997,47.85638400000005],[-64.50361599999991,47.850273000000016],[-64.514725,47.832497000000046],[-64.523056,47.822220000000016],[-64.54110699999995,47.80332199999998],[-64.60499599999997,47.748329000000126],[-64.61054999999999,47.745270000000005],[-64.63583399999999,47.73582500000009],[-64.64750700000002,47.733879],[-64.69055199999997,47.75305200000014],[-64.69332899999995,47.75804900000003],[-64.70278899999994,47.82360799999998],[-64.697769,47.83610499999992],[-64.68554699999999,47.85221900000005],[-64.66749600000003,47.86693600000007],[-64.66221599999994,47.87082700000013],[-64.62416099999996,47.88471999999996],[-64.61776700000001,47.886658000000125],[-64.60916099999997,47.88693999999998],[-64.58416699999992,47.884995],[-64.50805700000001,47.90387700000002],[-64.48277300000001,47.91777000000002]],[[-64.56750499999993,47.89943699999998],[-64.57444800000002,47.89804799999996],[-64.58361799999989,47.89943699999998],[-64.589447,47.90277100000014],[-64.593887,47.90665400000006],[-64.59445199999993,47.911933999999974],[-64.59361299999989,47.918052999999986],[-64.531677,48.01610599999998],[-64.52694699999995,48.02165999999994],[-64.52278099999995,48.02555100000001],[-64.51695299999994,48.028602999999976],[-64.50973499999992,48.02999100000005],[-64.50111400000003,48.027488999999946],[-64.49554399999994,48.02388000000013],[-64.4908289999999,48.019989000000066],[-64.48582499999992,48.01305400000001],[-64.48277300000001,48.00860600000004],[-64.46972699999998,47.96971100000013],[-64.46916199999987,47.96443899999997],[-64.47055099999994,47.95332300000007],[-64.47444200000001,47.94776900000005],[-64.49638399999998,47.933876],[-64.51390100000003,47.924713],[-64.56750499999993,47.89943699999998]],[[-53.71277599999996,48.14888000000002],[-53.68972000000002,48.147217000000126],[-53.682503,48.14777400000003],[-53.66750300000001,48.15054299999997],[-53.64778100000001,48.155265999999926],[-53.615554999999915,48.16749600000003],[-53.583327999999995,48.18082400000003],[-53.57111399999991,48.186104000000114],[-53.56416299999995,48.19054399999993],[-53.55305499999997,48.19915800000001],[-53.539444,48.20221700000013],[-53.53167000000002,48.20277400000003],[-53.516395999999986,48.201935000000105],[-53.50972699999994,48.198326000000066],[-53.50917099999987,48.193321000000026],[-53.51083399999999,48.15082600000011],[-53.51250499999992,48.14527100000004],[-53.53082999999992,48.09777100000002],[-53.53639199999998,48.093323000000055],[-53.54944599999999,48.0886000000001],[-53.56361400000003,48.084991000000116],[-53.598884999999996,48.0794370000001],[-53.634170999999924,48.0752720000001],[-53.82333399999993,48.09276599999998],[-53.83943899999997,48.094437000000084],[-53.85611,48.098044999999956],[-53.871940999999936,48.10471300000012],[-53.87666300000001,48.108604000000014],[-53.93250299999994,48.17276799999996],[-53.93582900000001,48.18249500000013],[-53.93277699999999,48.198326000000066],[-53.929168999999945,48.209434999999985],[-53.92222599999997,48.212493999999936],[-53.90638699999994,48.21027400000014],[-53.89888799999994,48.20665700000001],[-53.860000999999954,48.17443800000012],[-53.85555999999997,48.169991000000095],[-53.71277599999996,48.14888000000002]],[[-123.47444200000001,48.709160000000054],[-123.48277300000001,48.70832800000011],[-123.48999000000003,48.70943500000004],[-123.51306199999993,48.716385000000116],[-123.52471899999989,48.722488000000055],[-123.54943800000001,48.74665800000008],[-123.551941,48.75222000000002],[-123.59277299999991,48.8983310000001],[-123.595551,48.90971400000012],[-123.59612299999998,48.928329000000076],[-123.59665699999994,48.946938000000046],[-123.59361299999995,48.94721199999998],[-123.58056599999992,48.93554700000004],[-123.57721699999996,48.929161000000136],[-123.53611799999999,48.914993000000095],[-123.53028899999998,48.911933999999974],[-123.45749699999993,48.86305200000004],[-123.43388400000003,48.844437000000084],[-123.37027,48.768326],[-123.36888099999993,48.762771999999984],[-123.37165800000002,48.75750000000005],[-123.37638900000002,48.75360899999998],[-123.43195300000002,48.72109999999998],[-123.47444200000001,48.709160000000054]],[[-58.34222399999999,49.06610100000012],[-58.349166999999966,49.064437999999996],[-58.356109999999944,49.06582600000013],[-58.35194399999989,49.0719380000001],[-58.341385,49.07638500000013],[-58.33361100000002,49.07777399999998],[-58.330558999999994,49.07332600000001],[-58.33583099999993,49.068885999999964],[-58.34222399999999,49.06610100000012]],[[-123.32277699999997,48.861107000000004],[-123.3705369999999,48.85638400000005],[-123.37888299999997,48.85694100000012],[-123.38474299999996,48.85999300000003],[-123.54055799999998,48.94499200000013],[-123.66251399999999,49.03527100000008],[-123.703888,49.09526800000003],[-123.70527599999997,49.10027300000007],[-123.70249899999999,49.105552999999986],[-123.695831,49.10804700000011],[-123.686394,49.106659000000036],[-123.68055700000002,49.10360700000007],[-123.674713,49.09304800000007],[-123.65943900000002,49.073608000000036],[-123.60444599999994,49.01471700000013],[-123.58640300000002,49.00054900000009],[-123.52166699999998,48.96027400000014],[-123.49916099999996,48.94721199999998],[-123.487503,48.94110100000006],[-123.45973200000003,48.93054999999998],[-123.43639399999995,48.92443800000001],[-123.42027299999995,48.92054700000011],[-123.38194299999992,48.910819999999944],[-123.32833900000003,48.89582799999994],[-123.32250999999991,48.89276899999999],[-123.31777999999997,48.88888500000013],[-123.31276700000001,48.87276500000007],[-123.3125,48.86805000000004],[-123.31639100000001,48.86332700000003],[-123.32277699999997,48.861107000000004]],[[-125.816101,49.12582400000014],[-125.82028200000002,49.12470999999999],[-125.86028299999998,49.134438000000046],[-125.906387,49.160820000000115],[-125.910278,49.16554300000007],[-125.92582699999991,49.190826000000015],[-125.93360899999993,49.21110499999992],[-125.93306000000001,49.218048000000124],[-125.93055700000002,49.21998600000006],[-125.92610200000001,49.22332000000006],[-125.87888299999992,49.23582499999998],[-125.86749299999997,49.23333000000014],[-125.82917800000001,49.22637900000001],[-125.81806899999987,49.220543000000134],[-125.79915599999998,49.20832800000005],[-125.78888699999993,49.17276800000013],[-125.79583699999995,49.1519320000001],[-125.79833999999994,49.14638500000001],[-125.81249999999994,49.12915800000013],[-125.816101,49.12582400000014]],[[-126.13194299999992,49.393325999999945],[-126.126938,49.39027400000003],[-126.12471,49.39027400000003],[-126.12053699999996,49.38860299999999],[-126.11054999999999,49.38221000000004],[-126.10665899999992,49.378601],[-126.09612300000003,49.368599000000074],[-126.08640300000002,49.35860400000013],[-126.07277699999997,49.34304800000001],[-126.0497279999999,49.265548999999965],[-126.0511019999999,49.260550999999964],[-126.05583200000001,49.25610400000011],[-126.06471299999987,49.250832],[-126.071121,49.24832900000001],[-126.07972699999999,49.24665800000014],[-126.0891719999999,49.24610100000007],[-126.09638999999999,49.24721500000004],[-126.18666100000002,49.263329],[-126.19167299999992,49.265548999999965],[-126.22332799999992,49.27971600000012],[-126.22944599999994,49.28249399999993],[-126.23916600000001,49.28971899999999],[-126.23473399999995,49.374161000000015],[-126.229172,49.378601],[-126.22138999999999,49.38054700000009],[-126.141388,49.39415699999995],[-126.13194299999992,49.393325999999945]],[[-123.37943999999999,49.326941999999974],[-123.39222699999999,49.326103000000046],[-123.41027799999995,49.33416],[-123.42194399999994,49.339714000000015],[-123.42666600000001,49.344154],[-123.42804699999999,49.348877000000016],[-123.42027299999995,49.38166000000001],[-123.41332999999997,49.38610799999998],[-123.3600009999999,49.411658999999986],[-123.35472099999998,49.41332200000011],[-123.327789,49.41666400000008],[-123.31696299999999,49.41749600000014],[-123.31221,49.41499299999998],[-123.30943300000001,49.41137700000013],[-123.31027199999994,49.40526600000004],[-123.31194299999993,49.401932000000045],[-123.327789,49.363052000000096],[-123.33112299999999,49.35499600000003],[-123.34472699999998,49.34193400000004],[-123.36833199999995,49.33027599999997],[-123.37943999999999,49.326941999999974]],[[-54.705276000000026,49.400543000000084],[-54.71277600000002,49.398330999999985],[-54.730278,49.40304600000002],[-54.73555799999997,49.40721100000002],[-54.75972699999994,49.43249500000002],[-54.75917099999998,49.43776699999995],[-54.75472300000001,49.44387800000004],[-54.74944299999993,49.449158000000125],[-54.73833499999995,49.45777100000009],[-54.68055699999991,49.49193600000001],[-54.67305799999991,49.49249300000008],[-54.66500100000002,49.489159000000086],[-54.64416499999999,49.47332],[-54.64028199999996,49.46915400000006],[-54.64083899999997,49.463881999999955],[-54.65471600000001,49.460823000000005],[-54.68444099999999,49.420547],[-54.699164999999994,49.40387700000008],[-54.705276000000026,49.400543000000084]],[[-124.179169,49.44110100000012],[-124.18554699999999,49.439986999999974],[-124.313606,49.45609999999999],[-124.32668299999995,49.460823000000005],[-124.36000099999995,49.474433999999974],[-124.36609599999997,49.477486000000056],[-124.37082699999996,49.481102000000135],[-124.37165799999997,49.48304700000011],[-124.38054699999998,49.506943000000035],[-124.38110399999994,49.511940000000095],[-124.37832599999996,49.51583099999999],[-124.37165799999997,49.518326],[-124.361107,49.519157000000064],[-124.35500299999995,49.51749400000011],[-124.34889199999998,49.51444200000003],[-124.30471799999992,49.51221499999997],[-124.24471999999997,49.50138900000002],[-124.23750299999995,49.498329000000126],[-124.22138999999993,49.49137900000011],[-124.1875,49.474433999999974],[-124.181671,49.47137500000002],[-124.17388900000003,49.45638299999996],[-124.17194399999994,49.446655000000135],[-124.17223399999989,49.444153000000085],[-124.179169,49.44110100000012]],[[-123.33277899999996,49.44110100000012],[-123.36028299999987,49.43305199999992],[-123.37499999999994,49.43332700000013],[-123.442207,49.43859900000007],[-123.448036,49.44165800000002],[-123.45944199999997,49.46720900000008],[-123.45973200000003,49.47054300000008],[-123.45305599999995,49.49554400000011],[-123.44526699999994,49.51527400000009],[-123.43666100000002,49.52221700000007],[-123.38082899999995,49.53611000000012],[-123.37000299999994,49.53611000000012],[-123.360817,49.53499599999998],[-123.3550029999999,49.53193699999997],[-123.33833300000003,49.50610400000005],[-123.33167999999995,49.500832000000116],[-123.32805599999995,49.49638399999998],[-123.32389799999993,49.488602000000014],[-123.319458,49.47470899999996],[-123.31777999999997,49.464157],[-123.319458,49.45193499999999],[-123.32224300000001,49.448043999999925],[-123.32695000000001,49.444153000000085],[-123.33277899999996,49.44110100000012]],[[-55.69554899999997,49.506943000000035],[-55.72582999999997,49.50555400000002],[-55.732497999999964,49.509163],[-55.73500100000001,49.51361099999997],[-55.736114999999984,49.518599999999935],[-55.735832000000016,49.52388000000002],[-55.73027799999994,49.545547000000056],[-55.72277100000002,49.55777000000012],[-55.716110000000015,49.560272],[-55.68499800000001,49.561104000000114],[-55.67694899999998,49.561104000000114],[-55.65833299999997,49.559158000000025],[-55.653052999999886,49.55526700000013],[-55.65222199999994,49.55027000000007],[-55.653885,49.54471600000005],[-55.66138499999994,49.529716000000064],[-55.664444,49.52388000000002],[-55.68111399999998,49.51082600000012],[-55.68749999999994,49.50804900000003],[-55.69554899999997,49.506943000000035]],[[-124.68943799999994,49.48027000000002],[-124.69611399999997,49.47776799999997],[-124.70221700000002,49.47804299999996],[-124.74137899999994,49.48804500000011],[-124.75361599999991,49.49137900000011],[-124.82362399999994,49.53943599999997],[-124.83666999999997,49.554993000000024],[-124.84111000000001,49.56276700000001],[-124.84249899999992,49.57860599999998],[-124.84194899999989,49.58415999999994],[-124.83416699999992,49.607773000000066],[-124.83168,49.61054999999999],[-124.82749899999993,49.60888700000004],[-124.81054699999993,49.58971400000013],[-124.80888400000003,49.58665500000001],[-124.80583200000001,49.58582300000006],[-124.77887699999997,49.56888600000008],[-124.68804899999986,49.483604000000014],[-124.68943799999994,49.48027000000002]],[[-55.69305399999996,49.56749700000006],[-55.70916699999998,49.56638300000009],[-55.71665999999993,49.567214999999976],[-55.72083299999997,49.57138100000009],[-55.72305299999999,49.57610299999999],[-55.72277100000002,49.58138300000007],[-55.70583299999993,49.613883999999985],[-55.68499800000001,49.624992000000134],[-55.673888999999974,49.630547000000035],[-55.659720999999934,49.63555100000002],[-55.653052999999886,49.63638300000008],[-55.572776999999974,49.603882],[-55.567504999999926,49.59999800000014],[-55.573058999999944,49.595543000000134],[-55.58638799999994,49.59137700000008],[-55.60805499999998,49.586104999999975],[-55.67166900000001,49.57138100000009],[-55.69305399999996,49.56749700000006]],[[-54.576667999999984,49.558601000000124],[-54.77305599999994,49.49388099999999],[-54.80944099999999,49.48804500000011],[-54.83916499999998,49.48443600000013],[-54.85583500000001,49.48443600000013],[-54.86306000000002,49.48526800000002],[-54.871940999999936,49.48749500000008],[-54.87305500000002,49.49221800000009],[-54.89361600000001,49.58055100000013],[-54.894447000000014,49.58526599999999],[-54.89194500000002,49.590546000000074],[-54.885276999999974,49.593048000000124],[-54.805556999999965,49.59582500000005],[-54.79222899999996,49.572768999999994],[-54.79333500000001,49.56693999999999],[-54.79167199999989,49.56249200000002],[-54.78833800000001,49.55777000000012],[-54.78417200000001,49.554161000000136],[-54.76860799999997,49.54666100000003],[-54.760001999999986,49.545547000000056],[-54.743889000000024,49.544998000000135],[-54.729720999999984,49.548050000000046],[-54.70861100000002,49.55443600000012],[-54.61472299999997,49.60610200000002],[-54.57472200000001,49.63526900000011],[-54.56194299999993,49.65360300000009],[-54.54888900000003,49.659988000000055],[-54.53611799999993,49.664153999999996],[-54.52972399999999,49.63388100000003],[-54.53166999999996,49.62221500000004],[-54.538054999999986,49.587494000000106],[-54.543334999999956,49.582497000000046],[-54.57055700000001,49.562209999999936],[-54.576667999999984,49.558601000000124]],[[-54.004448000000025,49.647491000000116],[-54.25778199999996,49.566666000000055],[-54.26583900000003,49.56693999999999],[-54.274719000000005,49.56916000000001],[-54.289444,49.57610299999999],[-54.29333500000001,49.58055100000013],[-54.29888899999992,49.60999300000009],[-54.29778299999998,49.6511000000001],[-54.28805499999993,49.71138000000002],[-54.282775999999956,49.716660000000104],[-54.26999699999999,49.722488],[-54.14194500000002,49.75],[-54.10222599999997,49.75027499999999],[-54.09388699999994,49.74887800000005],[-54.085830999999985,49.74554400000005],[-54.08111599999995,49.736381999999935],[-54.04000099999996,49.68998700000009],[-54.00305899999995,49.659988000000055],[-54.004448000000025,49.647491000000116]],[[-124.129707,49.650825999999995],[-124.139183,49.65054300000003],[-124.15361000000001,49.65554800000007],[-124.18694299999993,49.66888399999999],[-124.196663,49.676941],[-124.20195000000001,49.70193499999999],[-124.19943199999989,49.70609999999999],[-124.14750699999996,49.746658000000025],[-124.14277600000003,49.75],[-124.13722199999995,49.752219999999966],[-124.09166699999997,49.7677690000001],[-124.03611799999999,49.77721400000013],[-124.029449,49.7783280000001],[-124.021118,49.77777100000003],[-124.01611299999996,49.77555100000001],[-124.01862299999999,49.77165999999994],[-124.02555799999993,49.7677690000001],[-124.046112,49.75638600000008],[-124.06054699999999,49.74499500000013],[-124.07472200000001,49.733330000000024],[-124.090843,49.71554600000013],[-124.10109699999992,49.70027200000004],[-124.10555999999991,49.689430000000016],[-124.10722399999992,49.67721599999999],[-124.11081699999994,49.664992999999924],[-124.11361699999998,49.65971399999995],[-124.12304699999993,49.65193199999999],[-124.129707,49.650825999999995]],[[-56.80361199999993,49.763329000000056],[-56.82749899999999,49.76110799999998],[-56.83555599999994,49.762771999999984],[-56.83805099999995,49.767494000000056],[-56.832779000000016,49.771934999999985],[-56.826667999999984,49.77526899999998],[-56.79250300000001,49.78555299999999],[-56.782219,49.78694200000001],[-56.78194400000001,49.78082299999994],[-56.79084,49.768326],[-56.79666900000001,49.764999000000046],[-56.80361199999993,49.763329000000056]],[[-124.44611399999991,49.723320000000115],[-124.43749999999994,49.72304500000013],[-124.42887899999994,49.723877000000016],[-124.41000400000001,49.72304500000013],[-124.38137799999998,49.71332600000011],[-124.35138699999999,49.698044000000095],[-124.33277900000002,49.68332700000008],[-124.13474300000001,49.52526900000004],[-124.13221699999991,49.52027100000004],[-124.12416100000002,49.49916100000007],[-124.122772,49.493607000000054],[-124.12748699999997,49.48971599999999],[-124.13417099999992,49.48749500000008],[-124.14167799999996,49.48582500000009],[-124.14916999999997,49.486107000000004],[-124.15527299999985,49.488602000000014],[-124.281387,49.54666100000003],[-124.40583800000002,49.60582699999998],[-124.43804899999998,49.62887599999999],[-124.44220699999994,49.63804600000003],[-124.47666900000002,49.67193600000013],[-124.5396649999999,49.692768],[-124.55249799999996,49.69710500000002],[-124.56167599999998,49.69993599999992],[-124.61416600000001,49.713607999999965],[-124.62721299999993,49.71915400000006],[-124.65416699999997,49.73610700000012],[-124.66082799999992,49.74276700000013],[-124.65666199999993,49.79694399999994],[-124.65110800000002,49.79999500000014],[-124.61945300000002,49.79721800000004],[-124.604446,49.78943600000014],[-124.59944199999995,49.78443900000002],[-124.59028599999999,49.77165999999994],[-124.56234,49.753326000000015],[-124.55933399999998,49.751495000000034],[-124.49472000000003,49.733330000000024],[-124.44611399999991,49.723320000000115]],[[-126.67610199999996,49.58360300000004],[-126.68138099999993,49.58305400000012],[-126.68888899999996,49.583878000000084],[-126.69722000000002,49.585548000000074],[-126.78971899999999,49.61221300000011],[-126.80803699999996,49.61971299999999],[-126.81416299999995,49.62276500000007],[-126.90556300000003,49.6855470000001],[-126.96528599999999,49.72693599999997],[-126.96945199999999,49.73110200000008],[-126.97416699999991,49.740273],[-126.97556299999997,49.75],[-126.94055200000003,49.83138300000002],[-126.890556,49.84777100000008],[-126.79915599999993,49.87609900000001],[-126.77749599999993,49.87971500000009],[-126.76872299999997,49.87861600000008],[-126.74944299999999,49.85694100000012],[-126.73416099999997,49.84804500000001],[-126.67804699999994,49.8252720000001],[-126.64472999999992,49.77416200000005],[-126.636124,49.75943799999999],[-126.63445300000001,49.75388300000009],[-126.61332699999997,49.648330999999985],[-126.61609599999997,49.62443500000006],[-126.62053699999996,49.60610200000002],[-126.62416099999996,49.60138699999999],[-126.63305700000001,49.596100000000035],[-126.66861,49.585548000000074],[-126.67610199999996,49.58360300000004]],[[-62.08972199999988,49.38638300000014],[-62.08139,49.38555100000008],[-62.051665999999955,49.39027400000003],[-62.04361699999993,49.39054900000008],[-62.02527600000002,49.38749700000011],[-61.892226999999934,49.351387000000045],[-61.875557000000015,49.34499400000004],[-61.825835999999924,49.31220999999999],[-61.82111400000002,49.30888399999998],[-61.66332999999992,49.14916200000005],[-61.661666999999966,49.144439999999975],[-61.670837000000006,49.134163],[-61.70222499999994,49.111107000000004],[-61.73555799999997,49.09609999999998],[-61.79611199999994,49.078048999999965],[-62.01999699999999,49.069443000000035],[-62.02916700000003,49.069443000000035],[-62.19554900000003,49.07499700000005],[-62.36805700000002,49.0991590000001],[-62.72610500000002,49.154709000000025],[-62.782218999999884,49.165824999999984],[-62.946662999999944,49.19887499999999],[-63.089995999999985,49.228043000000014],[-63.097778000000005,49.23054500000012],[-63.209442000000024,49.270827999999995],[-63.23082699999992,49.28027300000002],[-63.24277499999994,49.287498000000085],[-63.25305900000001,49.294997999999964],[-63.26999699999999,49.311104],[-63.27583299999998,49.31471299999998],[-63.283332999999914,49.317771999999934],[-63.38722199999995,49.34388000000007],[-63.41694599999988,49.35082999999997],[-63.501296999999965,49.370384000000115],[-63.53722399999987,49.379714999999976],[-63.573058999999944,49.39666000000011],[-63.61611199999993,49.4469380000001],[-63.62194099999988,49.45555100000007],[-63.620833999999945,49.46110500000009],[-63.61666099999991,49.46665999999999],[-63.61333499999995,49.473044999999956],[-63.61250299999995,49.47887399999996],[-63.61611199999993,49.48832700000003],[-63.61972000000003,49.492767000000015],[-63.66277299999996,49.533051],[-63.67888599999992,49.54471600000005],[-63.71444699999989,49.56638300000009],[-63.84194199999996,49.639160000000004],[-63.88194299999998,49.65915700000005],[-63.918334999999956,49.67443800000001],[-64.01556399999987,49.70249200000006],[-64.30694599999993,49.777489],[-64.38221699999997,49.78943600000014],[-64.38999899999993,49.789719000000105],[-64.41833500000001,49.80165899999997],[-64.511124,49.858604000000014],[-64.51390100000003,49.863609000000054],[-64.51028399999996,49.86859900000013],[-64.50111400000003,49.87804399999999],[-64.49610899999988,49.883049000000085],[-64.4908289999999,49.886939999999925],[-64.472778,49.89582800000011],[-64.458618,49.90082600000011],[-64.44554099999999,49.90443400000004],[-64.22694399999995,49.948326000000066],[-64.20361300000002,49.950271999999984],[-64.14277599999997,49.94804400000004],[-64.13305700000001,49.94721200000009],[-64.12388599999997,49.945267000000115],[-64.02917500000001,49.92443800000012],[-63.95889299999993,49.89804800000013],[-63.61583699999994,49.849158999999986],[-63.545006,49.84332300000011],[-63.49222599999996,49.840828000000045],[-63.47527299999996,49.84054600000002],[-63.34694699999994,49.8202740000001],[-63.30972299999996,49.81388099999998],[-63.13611599999996,49.78082299999994],[-63.07444799999996,49.76416000000006],[-62.99610899999999,49.736656000000096],[-62.78666700000002,49.6763840000001],[-62.71055599999994,49.66082],[-62.54555499999998,49.59999800000014],[-62.44361099999992,49.5472180000001],[-62.340553,49.48693800000001],[-62.21221899999995,49.41443600000008],[-62.205832999999984,49.41137700000013],[-62.18888900000002,49.40582300000011],[-62.16916699999996,49.401099999999985],[-62.09916700000002,49.387771999999984],[-62.08972199999988,49.38638300000014]],[[-124.92415599999998,50.05860100000001],[-124.96861299999995,50.03582799999998],[-125.00055699999996,50.05665600000003],[-125.06304899999998,50.103324999999984],[-125.06696299999999,50.107498000000135],[-125.066101,50.11388400000004],[-125.0625,50.11832400000009],[-125.03971899999999,50.13054699999992],[-124.991669,50.16832700000003],[-124.98222399999992,50.17610200000013],[-124.98055999999991,50.18221299999999],[-124.98332199999999,50.225548],[-124.93138099999993,50.17110400000013],[-124.92859599999997,50.16610000000014],[-124.91528299999999,50.14138000000008],[-124.89778100000001,50.07749200000006],[-124.92415599999998,50.05860100000001]],[[-63.859443999999996,50.19776899999994],[-63.87361099999998,50.194435],[-63.89028200000001,50.194709999999986],[-63.899993999999936,50.19609800000006],[-63.90860700000002,50.19860100000005],[-63.91610700000001,50.201660000000004],[-63.920837000000006,50.20555100000007],[-63.93055700000002,50.218597000000045],[-63.931389000000024,50.22387700000007],[-63.93055700000002,50.22943100000009],[-63.92694899999992,50.236107000000004],[-63.92277499999989,50.24166100000002],[-63.91666399999997,50.244713000000104],[-63.90999599999992,50.24665800000014],[-63.90193899999997,50.24721500000004],[-63.889725,50.24221800000009],[-63.865554999999915,50.22832500000004],[-63.859443999999996,50.22470900000002],[-63.85472099999993,50.22082499999999],[-63.85278299999999,50.21610300000009],[-63.85361499999999,50.21054800000002],[-63.85583500000001,50.2044370000001],[-63.859443999999996,50.19776899999994]],[[-125.16777000000002,49.98081999999994],[-125.16999800000002,49.98081999999994],[-125.17111199999994,49.98165900000009],[-125.18582199999997,50.004166],[-125.20722999999998,50.04499800000002],[-125.21417199999996,50.06999200000001],[-125.28167699999989,50.11332700000014],[-125.31777999999986,50.13610799999998],[-125.32362399999994,50.143326],[-125.33999599999993,50.20304900000002],[-125.34916699999997,50.24249300000014],[-125.34973100000002,50.25777400000004],[-125.348343,50.26166500000011],[-125.34554299999996,50.26390100000003],[-125.33999599999993,50.26888300000013],[-125.31082200000003,50.28138000000013],[-125.26334400000002,50.29388399999999],[-125.25472999999988,50.29361000000006],[-125.24638399999998,50.290549999999996],[-125.24333199999995,50.28832999999997],[-125.16722099999987,50.21360800000008],[-125.16111799999999,50.2002720000001],[-125.16000400000001,50.1905440000001],[-125.18666100000002,50.14166300000005],[-125.1536099999999,50.00610399999994],[-125.15416699999997,50.000832],[-125.16416900000002,49.98526800000013],[-125.16777000000002,49.98081999999994]],[[-124.8125,50.11138199999999],[-124.821121,50.11110700000012],[-124.82749899999993,50.11193799999995],[-124.83361799999989,50.11444100000011],[-124.86110699999989,50.13638300000002],[-124.93916299999995,50.20777100000009],[-124.96305799999999,50.23638200000005],[-124.96610999999996,50.246941000000106],[-124.96556099999992,50.25166300000001],[-124.92304999999993,50.29638699999998],[-124.91832699999986,50.29972099999992],[-124.91082799999998,50.29999500000008],[-124.90249599999999,50.29833200000013],[-124.89862099999999,50.29388399999999],[-124.87581599999993,50.28472099999999],[-124.82167099999992,50.239716000000044],[-124.75666799999999,50.17832899999996],[-124.75250199999999,50.16777000000013],[-124.752228,50.16137699999996],[-124.75499699999995,50.1560970000001],[-124.80695300000002,50.11388400000004],[-124.8125,50.11138199999999]],[[-124.73082699999992,50.30221599999999],[-124.72693599999997,50.29916400000002],[-124.72471599999994,50.29916400000002],[-124.69554099999999,50.28943600000002],[-124.68331899999993,50.283333000000084],[-124.67250100000001,50.27610000000004],[-124.66860999999994,50.27249100000006],[-124.66111799999993,50.263054000000125],[-124.65943900000002,50.25833099999994],[-124.65750099999997,50.24777200000011],[-124.65611299999989,50.23137700000001],[-124.65834000000001,50.21221200000002],[-124.66000399999996,50.20749699999999],[-124.66251399999999,50.203323000000125],[-124.695831,50.15749400000004],[-124.70195000000001,50.15860000000009],[-124.70805399999995,50.16137699999996],[-124.79222099999993,50.22526600000009],[-124.79499800000002,50.22887400000002],[-124.78083800000002,50.26944000000003],[-124.77778599999999,50.27748900000006],[-124.74500299999994,50.29943799999995],[-124.74054699999994,50.30193300000002],[-124.73082699999992,50.30221599999999]],[[-125.54387700000001,50.39388300000002],[-125.63583399999999,50.379714999999976],[-125.693604,50.383331],[-125.70333899999991,50.384163000000115],[-125.75527999999997,50.391662999999994],[-125.762787,50.39415700000012],[-125.76363400000002,50.397491000000116],[-125.75527999999997,50.40554800000007],[-125.74416399999996,50.40776800000009],[-125.59528399999999,50.43305200000009],[-125.58640300000002,50.43415800000014],[-125.52390300000002,50.434433000000126],[-125.51889,50.431381000000044],[-125.51806599999998,50.42860400000012],[-125.51777600000003,50.40943100000004],[-125.520554,50.40332000000012],[-125.52500899999995,50.400825999999995],[-125.53639199999998,50.395827999999995],[-125.54387700000001,50.39388300000002]],[[-125.16555800000003,50.37443500000006],[-125.061394,50.24054700000005],[-125.05194099999989,50.226653999999996],[-125.05027799999993,50.22165700000011],[-125.048607,50.20777100000009],[-125.04915599999993,50.19332099999997],[-125.05166599999995,50.19082600000013],[-125.11638599999998,50.13665800000001],[-125.12917299999998,50.126098999999954],[-125.13390400000003,50.12276499999996],[-125.14028899999994,50.121658000000025],[-125.14472999999987,50.12193300000007],[-125.15083299999998,50.12499200000002],[-125.15416699999997,50.133331000000055],[-125.13971699999996,50.1594310000001],[-125.15611299999995,50.23915899999997],[-125.21083099999993,50.31304899999992],[-125.21362299999993,50.316666000000055],[-125.22000099999991,50.318329000000006],[-125.26363400000002,50.32360799999998],[-125.27194199999997,50.32388300000002],[-125.31555199999997,50.31805400000002],[-125.32112099999989,50.31693999999999],[-125.32695000000001,50.31388100000004],[-125.33306900000002,50.30443599999995],[-125.33473200000003,50.29972099999992],[-125.3394469999999,50.29583000000008],[-125.35610999999994,50.29027600000006],[-125.37222300000002,50.28943600000002],[-125.38527699999997,50.289993000000095],[-125.390289,50.29222100000004],[-125.39306599999998,50.29583000000008],[-125.39917000000003,50.311104000000114],[-125.400284,50.320831000000055],[-125.39943699999998,50.331108000000086],[-125.39806399999998,50.333878000000084],[-125.391953,50.340546000000074],[-125.291946,50.433876000000055],[-125.28443899999996,50.435822000000144],[-125.27500900000001,50.43332700000013],[-125.27306399999992,50.43110700000011],[-125.23665599999993,50.4158250000001],[-125.21640000000002,50.40470900000014],[-125.16555800000003,50.37443500000006]],[[-125.42610200000001,50.3555530000001],[-125.45777899999996,50.34943400000009],[-125.46749899999998,50.350273000000016],[-125.52610800000002,50.37887599999999],[-125.52806099999998,50.381660000000124],[-125.51862299999993,50.39027400000003],[-125.47749299999998,50.42416400000013],[-125.471657,50.42748999999998],[-125.465012,50.42999300000014],[-125.37998999999996,50.460823000000005],[-125.37165799999997,50.45777100000004],[-125.37082699999996,50.45582600000006],[-125.36665299999993,50.45416299999994],[-125.34306300000003,50.44165800000002],[-125.33194700000001,50.4355470000001],[-125.33000199999998,50.43082400000014],[-125.33056599999986,50.425270000000125],[-125.33693700000003,50.416664000000026],[-125.38583399999999,50.36971299999999],[-125.39835399999998,50.36415900000003],[-125.42610200000001,50.3555530000001]],[[-125.80721999999997,50.413605000000075],[-125.90695199999993,50.40971400000001],[-125.92194399999988,50.41027100000008],[-125.92804699999999,50.411658999999986],[-125.93110699999988,50.41387900000001],[-125.95111099999997,50.433876000000055],[-125.93943799999988,50.443047000000035],[-125.90583799999996,50.45638300000013],[-125.81416299999995,50.46804800000001],[-125.80777,50.46776599999998],[-125.80359599999997,50.46554600000013],[-125.79055799999998,50.45694000000003],[-125.74109599999997,50.43166400000001],[-125.73805199999998,50.42804700000005],[-125.73805199999998,50.42665899999997],[-125.74276700000001,50.42416400000013],[-125.75834700000001,50.41999099999998],[-125.79110700000001,50.41499299999998],[-125.80721999999997,50.413605000000075]],[[-126.22582999999997,50.55526700000013],[-126.30888399999998,50.52832799999999],[-126.33640299999996,50.52166],[-126.35056299999997,50.52027099999998],[-126.486107,50.51554900000008],[-126.58805799999999,50.521378000000084],[-126.60417199999995,50.52526899999998],[-126.623894,50.53388199999995],[-126.60417199999995,50.539719000000105],[-126.57444800000002,50.546387000000095],[-126.55695300000002,50.54860700000012],[-126.54194599999994,50.54943800000012],[-126.52667200000002,50.548882000000106],[-126.48860200000001,50.55332199999992],[-126.381104,50.574715000000026],[-126.28611799999999,50.59832799999998],[-126.28278399999999,50.59748800000011],[-126.22609699999998,50.564156000000025],[-126.223053,50.560546999999985],[-126.224716,50.55665599999992],[-126.22582999999997,50.55526700000013]],[[-126.46639999999996,50.575829000000056],[-126.47501399999993,50.57555400000001],[-126.47917199999995,50.576385000000016],[-126.535553,50.59054600000002],[-126.54915599999998,50.59638200000006],[-126.55222300000003,50.598602000000085],[-126.554169,50.60277600000012],[-126.55248999999998,50.60749800000002],[-126.55027799999999,50.60860400000007],[-126.54360999999994,50.61138200000005],[-126.52916699999997,50.61499800000013],[-126.45361299999996,50.626937999999996],[-126.40499899999992,50.62609900000007],[-126.385559,50.625549000000035],[-126.37721299999993,50.623877999999934],[-126.364441,50.619438000000116],[-126.36138900000003,50.61582900000013],[-126.36165599999998,50.61305200000004],[-126.36971999999992,50.60582699999998],[-126.38027999999997,50.598602000000085],[-126.38474300000001,50.596100000000035],[-126.39138799999995,50.59276600000004],[-126.39806399999998,50.59110300000009],[-126.46639999999996,50.575829000000056]],[[-59.34583299999997,50.53388199999995],[-59.353888999999924,50.53388199999995],[-59.358337000000006,50.537773000000016],[-59.384170999999924,50.633049000000085],[-59.384170999999924,50.638329],[-59.38277399999998,50.64388300000013],[-59.37805199999991,50.64916199999993],[-59.37194099999999,50.65277100000014],[-59.36444899999998,50.653876999999966],[-59.35500300000001,50.65221400000007],[-59.337775999999906,50.64083100000005],[-59.333610999999905,50.636108000000036],[-59.32167099999998,50.618881000000044],[-59.305556999999965,50.59165999999999],[-59.30027799999999,50.58194000000009],[-59.29833999999994,50.57249500000006],[-59.29833999999994,50.56193500000012],[-59.30889100000002,50.553047000000106],[-59.32055700000001,50.545830000000024],[-59.33306099999987,50.53943600000014],[-59.34583299999997,50.53388199999995]],[[-126.87332200000003,50.66332200000005],[-126.83416699999998,50.63416300000006],[-126.83112299999999,50.62915800000002],[-126.83583099999998,50.62526700000012],[-126.90249599999993,50.61388399999993],[-126.91251399999999,50.61360900000011],[-127.016663,50.638329],[-127.025284,50.63999200000006],[-127.04276999999996,50.63749700000005],[-127.05832700000002,50.63249200000001],[-127.10193600000002,50.627486999999974],[-127.12249800000001,50.62721300000004],[-127.13221699999991,50.62832600000013],[-127.14055599999995,50.62971500000009],[-127.14472999999998,50.63388100000003],[-127.14334100000002,50.63888500000013],[-127.13166799999999,50.65221400000007],[-127.12721299999998,50.65609699999999],[-127.10916099999997,50.66526799999997],[-127.093887,50.669159000000036],[-127.08640300000002,50.66971600000011],[-126.89028899999994,50.66721300000012],[-126.87970699999994,50.66610000000003],[-126.87332200000003,50.66332200000005]],[[-126.64388999999994,50.691933000000006],[-126.65249599999999,50.691376000000105],[-126.65888999999993,50.694435000000055],[-126.662781,50.69860099999994],[-126.66583300000002,50.70332300000001],[-126.69027699999998,50.75499700000006],[-126.68554699999993,50.75888800000013],[-126.66832699999998,50.759163000000115],[-126.60221899999999,50.77082800000005],[-126.58277900000002,50.76971400000002],[-126.54387700000001,50.765831000000105],[-126.53639199999992,50.76361100000008],[-126.53582799999998,50.75860600000004],[-126.63806199999993,50.69499200000013],[-126.64388999999994,50.691933000000006]],[[-55.56472000000002,50.69971499999991],[-55.58000199999992,50.69832600000012],[-55.58888999999999,50.699431999999945],[-55.64527899999996,50.71888000000007],[-55.65166499999998,50.72304500000007],[-55.653052999999886,50.72721100000001],[-55.62943999999993,50.78082300000011],[-55.62471800000003,50.78721600000006],[-55.619163999999955,50.791382],[-55.46277599999996,50.80582400000014],[-55.454444999999964,50.80248999999998],[-55.45055400000001,50.798332000000016],[-55.44972200000001,50.792770000000075],[-55.45472000000001,50.788048],[-55.46694199999996,50.784163999999976],[-55.512504999999976,50.72276300000004],[-55.52500199999997,50.71582799999999],[-55.55139200000002,50.70332300000001],[-55.557503,50.70138500000007],[-55.56472000000002,50.69971499999991]],[[-126.27306399999998,50.65277100000014],[-126.46333300000003,50.64166299999994],[-126.56806899999998,50.6483310000001],[-126.58416699999992,50.65026900000004],[-126.59889199999998,50.65415999999993],[-126.60637699999995,50.65721100000013],[-126.612503,50.659988000000055],[-126.61749299999997,50.664993000000095],[-126.61749299999997,50.66777000000002],[-126.545837,50.72609699999998],[-126.43721,50.78388200000012],[-126.38971699999996,50.806381000000044],[-126.38221699999997,50.808043999999995],[-126.28056299999997,50.82833100000005],[-126.26640299999997,50.82777399999998],[-126.25805699999995,50.824715000000026],[-126.2538909999999,50.8219380000001],[-126.25171699999987,50.818932000000075],[-126.23832699999997,50.81110400000006],[-126.22944599999994,50.803322000000094],[-126.17832900000002,50.75083200000006],[-126.17722299999997,50.748604000000114],[-126.17666600000001,50.7438810000001],[-126.25305200000003,50.69964600000009],[-126.25611900000001,50.66137700000007],[-126.26083399999999,50.65721100000013],[-126.26640299999997,50.65470900000008],[-126.27306399999998,50.65277100000014]],[[-126.73137700000001,50.771934999999985],[-126.79778299999992,50.76888300000002],[-126.807503,50.769989000000066],[-126.85333300000002,50.78276799999992],[-126.86472299999997,50.78943600000008],[-126.90583799999996,50.82276900000011],[-126.90139799999992,50.8252720000001],[-126.88806199999999,50.829162999999994],[-126.88137799999993,50.830276000000026],[-126.64862099999999,50.84721400000012],[-126.64334100000002,50.846939000000134],[-126.63583399999999,50.84526800000003],[-126.62943999999993,50.842490999999995],[-126.58860800000002,50.82138100000003],[-126.56806899999998,50.80777000000006],[-126.56304899999992,50.79999500000014],[-126.56861900000001,50.79749300000009],[-126.73137700000001,50.771934999999985]],[[-127.22693599999991,50.636108000000036],[-126.975281,50.57694200000009],[-126.85472099999993,50.55443600000012],[-126.77639799999997,50.54610400000013],[-126.76806599999998,50.544441000000006],[-126.72138999999999,50.53193699999997],[-126.70527600000003,50.527489],[-126.63999899999999,50.50777399999998],[-126.62332199999992,50.498329000000126],[-126.56388899999996,50.483604000000014],[-126.49388099999993,50.481934000000024],[-126.39472999999998,50.48165899999998],[-126.38694800000002,50.48276500000003],[-126.35582699999998,50.48333000000008],[-126.327789,50.48082000000005],[-126.22112299999998,50.46859699999999],[-126.20500199999992,50.466660000000104],[-126.15471600000001,50.45943500000004],[-126.06916799999999,50.43859900000007],[-126.04611199999994,50.43249500000002],[-126.031387,50.427773000000116],[-126.01889,50.42193600000013],[-125.97609699999992,50.39499699999999],[-125.96250900000001,50.388885000000016],[-125.94776899999994,50.38499500000006],[-125.92859599999997,50.382209999999986],[-125.81696299999999,50.3780440000001],[-125.58000199999987,50.36582899999996],[-125.56416300000001,50.363883999999985],[-125.54860699999989,50.35916100000003],[-125.46305799999993,50.32971999999995],[-125.44972200000001,50.32360799999998],[-125.44055200000003,50.318329000000006],[-125.43554699999999,50.31471299999998],[-125.431671,50.31054700000004],[-125.42887899999994,50.30554999999998],[-125.42722300000003,50.29999500000008],[-125.42666599999995,50.29388399999999],[-125.42722300000003,50.287498000000085],[-125.41500899999994,50.26166500000011],[-125.39362299999999,50.21554600000002],[-125.37777699999998,50.17971799999998],[-125.36277799999993,50.13804600000009],[-125.33084099999996,50.11388400000004],[-125.28694199999995,50.08138300000013],[-125.229446,50.026657],[-125.221657,50.01805100000007],[-125.21611000000001,50.001389000000074],[-125.21417199999996,49.976379000000065],[-125.212784,49.97082500000005],[-125.20722999999998,49.96166200000005],[-125.16860999999994,49.91276600000003],[-125.11221299999994,49.86832400000009],[-124.99305699999991,49.78833000000009],[-124.89806399999998,49.73165899999998],[-124.89138799999989,49.66471100000007],[-124.91639700000002,49.631660000000124],[-124.86028299999992,49.54166399999997],[-124.85305800000003,49.5324940000001],[-124.83306900000002,49.51082600000012],[-124.78943599999991,49.464157],[-124.579453,49.38749700000011],[-124.55110200000001,49.3780440000001],[-124.535553,49.37387800000005],[-124.51917300000002,49.37027000000012],[-124.26083399999993,49.315269],[-124.12193299999996,49.27027100000009],[-123.94304699999992,49.21110499999992],[-123.85637699999995,49.14916200000005],[-123.86028299999992,49.153046000000074],[-123.86638599999998,49.160820000000115],[-123.86805700000002,49.16443600000014],[-123.87110899999988,49.17360700000012],[-123.87138399999998,49.181107],[-123.86638599999998,49.18637800000005],[-123.86165599999993,49.18888099999998],[-123.84999099999999,49.191658000000075],[-123.82444800000002,49.192764000000125],[-123.82055699999995,49.1905440000001],[-123.80722000000003,49.18027500000005],[-123.79444899999993,49.173325000000034],[-123.78859699999998,49.17027300000012],[-123.76944700000001,49.16304800000006],[-123.73805199999993,49.15443399999998],[-123.71112099999999,49.14999399999999],[-123.70417800000001,49.147491],[-123.699432,49.14388300000007],[-123.696663,49.14027400000009],[-123.69638099999997,49.13555100000008],[-123.69915799999995,49.130272000000105],[-123.703888,49.12638100000004],[-123.73137700000001,49.11749300000008],[-123.74166899999989,49.11804999999998],[-123.83750899999995,49.14138000000014],[-123.85056299999997,49.145546000000024],[-123.81027199999994,49.115829000000076],[-123.75195300000001,49.04083300000002],[-123.74944299999999,49.03527100000008],[-123.7502899999999,49.02915999999999],[-123.75695799999994,48.98693800000012],[-123.75862099999989,48.980819999999994],[-123.76334399999996,48.97693600000014],[-123.69193999999993,48.908325000000104],[-123.68222000000003,48.90221400000007],[-123.5911099999999,48.83998900000012],[-123.58277900000002,48.83194000000009],[-123.56555199999997,48.789719000000105],[-123.56304899999998,48.77832799999999],[-123.56471299999993,48.74971800000009],[-123.50945300000001,48.58749399999999],[-123.47666899999996,48.631660000000124],[-123.47083999999995,48.67332499999998],[-123.46916199999993,48.67943600000001],[-123.464447,48.68332700000008],[-123.45973200000003,48.685822000000144],[-123.45140100000003,48.68665299999998],[-123.44193999999999,48.68665299999998],[-123.41639699999996,48.684433000000126],[-123.40110800000002,48.681381000000044],[-123.39639299999999,48.677773000000116],[-123.34973099999996,48.54777500000006],[-123.34834299999994,48.535828000000095],[-123.29527300000001,48.48471800000004],[-123.291672,48.48082000000011],[-123.27861000000001,48.45610000000005],[-123.27610800000002,48.4511030000001],[-123.276947,48.44554099999999],[-123.28694200000001,48.41860200000002],[-123.28971899999999,48.41332199999994],[-123.29444899999993,48.409714000000065],[-123.30082699999997,48.406654],[-123.3205569999999,48.399437000000034],[-123.33640299999996,48.396942000000024],[-123.36028299999987,48.39721700000007],[-123.41665599999999,48.423882000000106],[-123.42138699999992,48.427490000000034],[-123.425003,48.431938],[-123.45973200000003,48.41193400000003],[-123.51334400000002,48.37470999999999],[-123.53694200000001,48.33832600000011],[-123.54250300000001,48.31249200000008],[-123.546112,48.307770000000005],[-123.55166600000001,48.304710000000114],[-123.55915800000002,48.30304700000005],[-123.58332799999994,48.301102000000014],[-123.598343,48.31166100000007],[-123.71444699999995,48.34804500000013],[-123.76251199999996,48.36166400000002],[-123.77166699999998,48.36166400000002],[-123.77999899999998,48.360550000000046],[-123.79499799999996,48.357498000000135],[-123.80888400000003,48.353324999999984],[-123.817497,48.352493000000095],[-123.823624,48.35277600000006],[-123.91610699999995,48.36415900000003],[-123.92415599999998,48.366104000000064],[-123.97609699999998,48.381935],[-124.26363399999997,48.46888000000001],[-124.423607,48.51693700000004],[-124.609444,48.56054700000004],[-124.6885989999999,48.57833099999999],[-124.72083999999995,48.58665500000001],[-124.75917099999998,48.6055530000001],[-124.77111799999994,48.61166399999996],[-124.79499800000002,48.629989999999964],[-124.81777999999997,48.64888000000013],[-124.82277699999997,48.65248900000012],[-124.9225009999999,48.67999300000014],[-125.02887699999997,48.70888500000001],[-125.0625,48.7149960000001],[-125.09500100000002,48.721930999999984],[-125.10221899999993,48.72443399999992],[-125.11389199999996,48.73110200000008],[-125.18443299999996,48.79610400000013],[-125.18499800000001,48.80082700000008],[-125.01722699999999,48.92054700000011],[-124.90862300000003,48.969154],[-124.90306099999998,48.97137500000008],[-124.84750399999996,49.011664999999994],[-124.84277299999985,49.01554900000002],[-124.83556399999998,49.02416199999999],[-124.78083800000002,49.131377999999984],[-124.77944899999994,49.144439999999975],[-124.78083800000002,49.150542999999914],[-124.79695099999998,49.2158280000001],[-124.79972799999996,49.22693600000008],[-124.80499299999997,49.236938000000066],[-124.80776999999995,49.24054700000005],[-124.81555199999997,49.238045],[-124.818893,49.23471800000004],[-124.82444800000002,49.224158999999986],[-124.82501199999996,49.21720900000014],[-124.82333399999993,49.20555100000013],[-124.81723,49.18332700000002],[-124.81610099999995,49.16471100000001],[-124.81806899999998,49.146103000000096],[-124.82611099999997,49.12248999999997],[-124.83139,49.11249500000008],[-124.87832599999996,49.02526899999992],[-124.88194299999998,49.02054600000014],[-124.89472999999998,49.00888800000013],[-124.90055799999993,49.00499700000006],[-124.906113,49.00193800000005],[-124.93694299999999,48.98804500000006],[-124.94999699999994,48.983330000000024],[-124.96278399999994,48.98110200000002],[-125.06916799999999,48.98443600000002],[-125.126938,48.99110400000001],[-125.19888300000002,48.96276899999998],[-125.21000699999996,48.955826],[-125.21665999999988,48.95332300000001],[-125.22416699999991,48.95166000000012],[-125.23137699999995,48.951103000000046],[-125.24194299999988,48.95166000000012],[-125.318893,48.96443899999997],[-125.32721699999996,48.966102999999976],[-125.45722999999992,48.918052999999986],[-125.46472199999988,48.91638200000011],[-125.483612,48.91582500000004],[-125.502228,48.91777000000002],[-125.50723299999999,48.92027300000001],[-125.75110599999994,49.05526700000007],[-125.76806599999998,49.09860200000003],[-125.73805199999998,49.105552999999986],[-125.69304699999992,49.12860100000006],[-125.64167800000001,49.16304800000006],[-125.63722200000001,49.16693900000013],[-125.60888699999998,49.19804399999998],[-125.60582699999992,49.210274000000084],[-125.60749800000002,49.2158280000001],[-125.611107,49.22026799999992],[-125.61638599999998,49.21971100000002],[-125.66443599999991,49.18998700000003],[-125.72083999999995,49.157767999999976],[-125.74694799999997,49.148604999999975],[-125.75334199999998,49.147491],[-125.75611899999996,49.151657000000114],[-125.779449,49.24166100000002],[-125.79666099999992,49.310272000000055],[-125.86609599999991,49.27443699999998],[-125.952789,49.230270000000075],[-125.96501199999989,49.22526599999992],[-125.97028399999999,49.22470900000002],[-125.97444199999995,49.2249910000001],[-125.98137700000001,49.227211000000125],[-125.98750299999989,49.230270000000075],[-126.020554,49.263054000000125],[-126.02333099999993,49.26805100000007],[-126.02223200000003,49.280823000000055],[-126.01862299999993,49.28555300000011],[-126.01306199999999,49.2888870000001],[-126.00666799999993,49.290549999999996],[-125.98029300000002,49.292496000000085],[-125.97361799999999,49.294997999999964],[-125.96916199999998,49.29749300000003],[-125.950287,49.311935000000005],[-125.94554099999999,49.31666600000011],[-125.89750699999996,49.41027100000008],[-125.89584399999995,49.416382],[-125.89695699999993,49.42804700000005],[-125.89972699999998,49.43360100000007],[-125.90471599999995,49.435822000000144],[-125.90915699999988,49.431938000000116],[-125.94722000000002,49.39554600000014],[-125.96250900000001,49.37748700000003],[-125.96501199999989,49.373604000000114],[-125.96528599999999,49.367493000000024],[-125.962219,49.3555530000001],[-125.962784,49.35027300000007],[-125.96610999999996,49.34554300000002],[-125.99527,49.324440000000095],[-126.00195300000001,49.321938000000046],[-126.0094529999999,49.321663],[-126.03916900000002,49.33027599999997],[-126.04638699999987,49.33332800000011],[-126.06111099999998,49.344154],[-126.06500199999999,49.34832800000004],[-126.07556199999999,49.38638300000014],[-126.07389799999999,49.392494000000056],[-126.120003,49.42304999999999],[-126.22556299999991,49.41027100000008],[-126.26390099999998,49.38943500000005],[-126.36527999999998,49.40165700000006],[-126.45916699999998,49.401932000000045],[-126.46167000000003,49.382767000000115],[-126.46611000000001,49.38027200000005],[-126.52667200000002,49.37193300000001],[-126.54222099999993,49.37443500000012],[-126.54723399999995,49.3780440000001],[-126.57778899999988,49.40776799999992],[-126.579453,49.41332200000011],[-126.57917799999996,49.41944099999995],[-126.56973299999999,49.57638500000007],[-126.56610099999995,49.584434999999985],[-126.47028399999999,49.63555100000002],[-126.46167000000003,49.636658000000125],[-126.40416699999997,49.6377720000001],[-126.38417099999992,49.63638300000008],[-126.36749299999997,49.633049000000085],[-126.36028299999998,49.63082099999997],[-126.34137699999997,49.62887599999999],[-126.28472899999997,49.6344380000001],[-126.22389199999998,49.64054900000002],[-126.13417099999998,49.64999400000005],[-126.09445199999988,49.65554800000007],[-126.08693699999998,49.65721100000002],[-126.08750899999995,49.66220900000002],[-126.09028599999999,49.66638200000011],[-126.09416199999993,49.671104000000014],[-126.10305799999998,49.67916100000002],[-126.11028299999992,49.68138099999999],[-126.11972000000003,49.681107000000054],[-126.20944199999991,49.67388199999999],[-126.23444399999994,49.669159000000036],[-126.24638400000003,49.66471100000007],[-126.283073,49.654990999999995],[-126.29833999999994,49.65221400000007],[-126.340843,49.64860500000009],[-126.43110699999994,49.662491000000045],[-126.43831599999993,49.664153999999996],[-126.58500699999996,49.701103000000046],[-126.59028599999994,49.70443700000004],[-126.63027999999997,49.79499800000008],[-126.67971799999998,49.878876000000105],[-126.80444299999988,49.90915699999999],[-126.83917200000002,49.88472000000013],[-126.84555099999989,49.8822100000001],[-126.85221899999993,49.87971500000009],[-126.87609899999995,49.87332200000009],[-126.93943799999994,49.862770000000125],[-126.99416399999996,49.85527000000002],[-127.12111699999997,49.85228699999999],[-127.13249200000001,49.85694100000012],[-127.17749000000003,49.88888500000013],[-127.18554699999999,49.89749100000006],[-127.22444199999995,49.940269000000114],[-127.241379,49.961937000000034],[-127.23889199999996,49.96720899999997],[-127.234444,49.97137500000008],[-127.17999299999991,50.02137800000003],[-127.18277,50.03166200000004],[-127.18360899999999,50.051102000000014],[-127.17666599999995,50.061104],[-127.172234,50.06499500000007],[-127.13027999999997,50.084717000000126],[-127.15833999999995,50.096382000000006],[-127.27055399999995,50.0991590000001],[-127.27500899999995,50.05999000000003],[-127.27749599999993,50.055267000000015],[-127.28388999999999,50.052216000000044],[-127.33000199999998,50.03388200000006],[-127.34500100000002,50.03027300000008],[-127.38054699999998,50.0261000000001],[-127.38999899999993,50.02860300000009],[-127.42331699999994,50.0422210000001],[-127.45195000000001,50.06971699999997],[-127.46916199999993,50.08804299999997],[-127.47193900000002,50.09276599999998],[-127.54804999999993,50.130272000000105],[-127.63276699999994,50.12999000000002],[-127.78028899999993,50.084160000000054],[-127.781387,50.084160000000054],[-127.78362299999998,50.084160000000054],[-127.890556,50.10694100000006],[-127.89584400000001,50.108886999999925],[-127.90083299999998,50.112495000000024],[-127.90695199999999,50.12082700000002],[-127.90666199999998,50.127769000000114],[-127.903343,50.13249200000013],[-127.89222699999988,50.13916000000006],[-127.87917299999998,50.144440000000145],[-127.86805700000002,50.151099999999985],[-127.83721899999995,50.17249300000009],[-127.82833900000003,50.180550000000096],[-127.78888699999999,50.22221400000001],[-127.79915599999993,50.317772000000105],[-127.80444299999994,50.32138099999992],[-127.86389200000002,50.33693700000009],[-127.87138399999998,50.33776899999998],[-127.881104,50.33721200000008],[-127.895554,50.32638500000007],[-127.90778399999999,50.31971700000008],[-127.92166099999997,50.316666000000055],[-127.93138099999993,50.31610100000006],[-127.94833399999993,50.32193799999999],[-127.95249899999993,50.32471500000008],[-127.97860700000001,50.34249100000005],[-127.97944599999994,50.347214000000065],[-127.92610199999996,50.45999100000006],[-127.92388900000003,50.46276900000004],[-127.91722099999993,50.46415699999994],[-127.75666799999993,50.48638199999999],[-127.708054,50.491661000000136],[-127.70028699999995,50.49221800000004],[-127.58416699999998,50.48693800000001],[-127.576683,50.48471799999999],[-127.57140400000003,50.481934000000024],[-127.56331599999999,50.4741590000001],[-127.53278399999999,50.439986999999974],[-127.50750700000003,50.40915700000011],[-127.49527,50.395827999999995],[-127.47444200000001,50.381660000000124],[-127.46193699999998,50.37582400000008],[-127.454453,50.37360400000006],[-127.44695300000001,50.37276500000013],[-127.446663,50.379714999999976],[-127.45249899999988,50.388885000000016],[-127.48665599999993,50.437492000000134],[-127.50583599999999,50.45860299999998],[-127.52027899999996,50.46971100000013],[-127.53083800000002,50.47693600000002],[-127.54750100000001,50.48693800000001],[-127.56388899999996,50.50222000000002],[-127.57000699999998,50.51221499999991],[-127.56749699999995,50.51610599999998],[-127.55027799999999,50.53832999999992],[-127.54472399999997,50.54166400000008],[-127.50361599999997,50.56221000000011],[-127.49694799999992,50.56526900000006],[-127.49027999999993,50.56805400000013],[-127.47501399999999,50.571663000000115],[-127.443604,50.571663000000115],[-127.41972399999992,50.57388300000014],[-127.41416900000002,50.575829000000056],[-127.41166699999997,50.58138300000002],[-127.41139199999992,50.587494000000106],[-127.41944899999999,50.59665700000011],[-127.58168,50.59388000000001],[-127.69138299999997,50.60665900000009],[-127.87332200000003,50.623877999999934],[-127.87666299999995,50.62165800000014],[-127.87361099999993,50.61693600000007],[-127.854446,50.60833000000014],[-127.80055199999998,50.587494000000106],[-127.78666699999997,50.58221400000002],[-127.76834099999996,50.579994000000056],[-127.751106,50.58110800000003],[-127.72501399999993,50.58443499999993],[-127.708618,50.584991000000116],[-127.66251399999999,50.58138300000002],[-127.63445300000001,50.57804900000002],[-127.61028299999998,50.56582599999996],[-127.595551,50.55582400000003],[-127.59166699999997,50.55165900000003],[-127.589722,50.54610400000013],[-127.595551,50.53665900000004],[-127.60109699999998,50.53333300000003],[-127.60888699999987,50.53138000000007],[-128.05142199999995,50.44669300000004],[-128.13363599999997,50.47470900000013],[-128.224152,50.53110500000008],[-128.319458,50.60860400000007],[-128.37527499999993,50.678604000000064],[-128.406952,50.738883999999985],[-128.41473399999995,50.762771999999984],[-128.416656,50.76915699999995],[-128.41305499999993,50.77388000000013],[-128.40863000000002,50.77777100000003],[-128.35583499999996,50.799721000000034],[-128.349152,50.80165899999997],[-128.10693400000002,50.8605500000001],[-128.05307,50.87193300000007],[-127.91832699999998,50.87221499999998],[-127.90972899999991,50.871376],[-127.882767,50.86554699999999],[-127.833328,50.85416399999997],[-127.67749000000003,50.817497],[-127.51471700000002,50.774437000000034],[-127.50723299999993,50.77221700000001],[-127.49582699999996,50.765831000000105],[-127.48750299999995,50.75721700000008],[-127.45916699999992,50.718323],[-127.354446,50.676102000000014],[-127.22693599999991,50.636108000000036]],[[-127.65471599999995,50.837769000000094],[-127.66139199999998,50.83499100000006],[-127.67027300000001,50.835266000000104],[-127.75306699999999,50.85277600000006],[-127.833328,50.87971500000003],[-127.83860799999997,50.88166000000007],[-127.83306899999997,50.88499500000012],[-127.73500100000001,50.909988],[-127.72638699999993,50.90860000000009],[-127.71665999999999,50.90554800000001],[-127.71028099999995,50.9019320000001],[-127.69138299999997,50.88721499999997],[-127.67083699999995,50.86693600000001],[-127.65833999999995,50.85416399999997],[-127.65527299999997,50.849433999999974],[-127.65334299999995,50.84388000000013],[-127.65471599999995,50.837769000000094]],[[-55.55555700000002,50.88638300000002],[-55.56388899999996,50.88499500000012],[-55.571670999999924,50.88582600000012],[-55.58111600000001,50.888046000000145],[-55.604720999999984,50.898048000000074],[-55.61555499999997,50.9060970000001],[-55.61972000000003,50.91027100000014],[-55.63611599999996,50.950829000000056],[-55.63527699999992,50.96138000000013],[-55.62943999999993,50.96554600000002],[-55.565552000000025,50.983047],[-55.558334,50.98443600000002],[-55.550551999999925,50.985268000000076],[-55.54222900000002,50.98499300000009],[-55.53527799999995,50.98137700000001],[-55.531386999999995,50.977211000000125],[-55.52972399999999,50.96832300000011],[-55.549995000000024,50.89083099999999],[-55.55555700000002,50.88638300000002]],[[-55.993889000000024,51.2002720000001],[-55.99999999999994,51.196655000000135],[-56.00111400000003,51.201660000000004],[-55.99805500000002,51.20749699999999],[-55.992774999999995,51.212769000000094],[-55.981383999999935,51.22165700000005],[-55.975554999999986,51.22582200000005],[-55.967772999999966,51.226653999999996],[-55.96832999999987,51.22137500000002],[-55.97055099999994,51.218323000000055],[-55.98249800000002,51.208885000000066],[-55.993889000000024,51.2002720000001]],[[-58.41332999999992,51.2388840000001],[-58.462219000000005,51.21610300000009],[-58.56361399999997,51.22832500000004],[-58.56500199999999,51.23333000000008],[-58.56194299999993,51.239159000000086],[-58.55583199999995,51.242767000000015],[-58.513335999999924,51.2649990000001],[-58.506392999999946,51.26832600000006],[-58.419448999999986,51.274712000000136],[-58.412773000000016,51.26721200000003],[-58.40916399999992,51.256943000000035],[-58.41332999999992,51.2388840000001]],[[-53.756366999999955,48.50326200000012],[-53.99749800000001,48.42555200000004],[-54.011116000000015,48.42166099999997],[-54.025001999999915,48.41860200000002],[-54.04888900000003,48.420547],[-54.05722000000003,48.42193600000002],[-54.07277699999992,48.42860400000001],[-54.08111599999995,48.42999299999997],[-54.09444399999995,48.42582700000008],[-54.10055499999993,48.42249300000009],[-54.147223999999994,48.39138000000008],[-54.13805400000001,48.35916100000003],[-54.134727,48.35443899999996],[-54.12749500000001,48.353324999999984],[-54.118607,48.364998000000014],[-54.088607999999965,48.39554599999997],[-54.075561999999934,48.4019320000001],[-54.06944999999996,48.40387700000008],[-54.054442999999935,48.40416000000005],[-54.04555499999998,48.4019320000001],[-54.02916700000003,48.399437000000034],[-54.02111100000002,48.39916200000005],[-53.998885999999914,48.40082600000005],[-53.99222599999996,48.402489],[-53.97972099999987,48.408042999999964],[-53.91305499999993,48.444153000000085],[-53.756366999999955,48.50326200000012],[-53.67444599999993,48.53416400000009],[-53.647223999999994,48.54110700000007],[-53.63194299999998,48.541382000000056],[-53.623054999999965,48.53916200000009],[-53.586388,48.52526900000004],[-53.57472200000001,48.50721699999997],[-53.558051999999975,48.47470900000002],[-53.58805100000001,48.428047000000106],[-53.56221799999997,48.43915599999997],[-53.533889999999985,48.45193500000005],[-53.48860899999994,48.50721699999997],[-53.461945000000014,48.55526699999996],[-53.46527900000001,48.56860399999999],[-53.46583599999997,48.57416500000005],[-53.465003999999965,48.579436999999984],[-53.43721799999997,48.619987000000094],[-53.42444599999999,48.625549000000035],[-53.345832999999914,48.61582899999996],[-53.33805099999995,48.61249499999997],[-53.31305699999996,48.595267999999976],[-53.30583200000001,48.58665500000001],[-53.30332900000002,48.581940000000145],[-53.22638699999993,48.555549999999926],[-53.216392999999925,48.56693999999999],[-53.153884999999946,48.628601],[-53.07972699999999,48.6988750000001],[-53.07277699999992,48.70027200000004],[-53.067779999999914,48.696380999999974],[-53.02305599999994,48.66082],[-53.01888999999994,48.65638000000001],[-52.978049999999996,48.60443900000013],[-52.97638699999999,48.59915900000004],[-52.976944,48.59388000000007],[-52.98722099999998,48.548050000000046],[-53.05388599999998,48.44276400000007],[-53.07556199999999,48.42249300000009],[-53.09749599999998,48.4052660000001],[-53.1875,48.35082999999997],[-53.194159999999954,48.34860200000003],[-53.201941999999974,48.347488000000055],[-53.20972399999994,48.34777100000002],[-53.21805599999993,48.3491590000001],[-53.24888599999997,48.36277000000007],[-53.261391,48.37082700000002],[-53.266395999999986,48.37499200000002],[-53.345001000000025,48.36027500000006],[-53.38889299999988,48.30387900000011],[-53.615279999999984,48.178046999999935],[-53.62138399999992,48.174713],[-53.634170999999924,48.169991000000095],[-53.662216,48.163321999999994],[-53.668609999999944,48.16249099999999],[-53.67694899999998,48.163879000000065],[-53.69471699999991,48.16915899999998],[-53.71055599999994,48.17582700000014],[-53.89250199999998,48.22693600000014],[-53.901389999999935,48.2291560000001],[-53.93416599999995,48.23333000000014],[-53.94055199999997,48.23081999999994],[-53.94527399999998,48.17887900000005],[-53.9441599999999,48.163879000000065],[-53.917778,48.08804300000003],[-53.91249800000003,48.084160000000054],[-53.90416700000003,48.08194000000009],[-53.823616000000015,48.07443999999998],[-53.79333500000001,48.07360800000009],[-53.77027899999996,48.07332600000001],[-53.733611999999994,48.0761030000001],[-53.71860499999997,48.07804900000002],[-53.69694499999997,48.079162999999994],[-53.68916300000001,48.07888000000003],[-53.69288599999987,48.067993],[-53.68838900000003,48.06599],[-53.68521900000002,48.06366000000014],[-53.68388700000003,48.060822000000144],[-53.68422299999992,48.057822999999985],[-53.68788899999993,48.05482500000011],[-53.691055000000006,48.052658000000065],[-53.69888300000002,48.049328],[-53.73694599999999,48.032767999999976],[-53.76333599999998,48.02638200000001],[-53.79944599999999,48.02165999999994],[-53.83666199999993,48.02221700000001],[-53.85222599999997,48.023048000000074],[-53.87638900000002,48.02582600000005],[-53.89388999999994,48.02999100000005],[-53.90166499999998,48.033607000000075],[-53.90943899999996,48.03388200000012],[-53.91666399999991,48.03333299999997],[-53.923614999999984,48.0316620000001],[-53.924170999999944,48.02665700000006],[-53.919167000000016,48.022490999999945],[-53.91138499999994,48.01915700000001],[-53.89305899999994,48.014442000000145],[-53.794448999999986,47.99638400000009],[-53.77916699999997,47.996658000000025],[-53.69538899999992,48.01821899999999],[-53.69138700000002,48.019215000000145],[-53.668724,48.02988099999999],[-53.65021899999999,48.03788400000013],[-53.60777999999999,48.05110200000007],[-53.60583500000001,48.04638700000004],[-53.61916400000001,47.99887800000005],[-53.62249800000001,47.993050000000096],[-53.72361000000001,47.84388000000001],[-53.73777799999999,47.82666000000006],[-53.78750600000001,47.773048000000074],[-53.79333500000001,47.768599999999935],[-53.801391999999964,47.76998900000012],[-53.807503,47.773604999999975],[-53.82556199999999,47.79499800000008],[-53.85250099999996,47.78527100000014],[-53.850554999999986,47.760551000000135],[-53.837501999999915,47.69943200000006],[-53.760283999999956,47.609993000000145],[-53.631110999999976,47.54332700000009],[-53.55055199999998,47.52915999999993],[-53.54527999999999,47.534439000000134],[-53.542502999999954,47.55027000000007],[-53.54111499999999,47.58526600000005],[-53.49777999999998,47.73471799999999],[-53.495834,47.74027300000006],[-53.46111300000001,47.806655999999975],[-53.43499800000001,47.83776899999998],[-53.30610699999994,47.98416100000003],[-53.29084,47.99943500000012],[-53.274445000000014,48.013329000000056],[-53.17055499999998,48.05360399999995],[-53.11000100000001,48.03943600000008],[-53.101943999999946,48.038048],[-53.095001000000025,48.03943600000008],[-53.05332900000002,48.049721000000034],[-53.041945999999996,48.05582400000014],[-52.996947999999975,48.08638000000008],[-52.974716,48.11638599999998],[-52.959723999999994,48.143051000000014],[-52.95639,48.14860500000003],[-52.92694899999998,48.169991000000095],[-52.91999800000002,48.171379],[-52.902221999999995,48.16304800000006],[-52.88611599999996,48.15110000000004],[-52.88194299999992,48.14749100000006],[-52.83555599999994,48.10638399999999],[-52.83138999999994,48.10166199999992],[-52.832779000000016,48.096939000000134],[-52.838889999999935,48.09360500000014],[-52.87194099999999,48.08221400000002],[-52.880279999999914,48.083327999999995],[-52.898056,48.09054600000002],[-52.90416700000003,48.08971400000007],[-52.911384999999996,48.08804300000003],[-52.91750300000001,48.084716999999955],[-52.928337,48.075553999999954],[-53.058051999999975,47.92249300000003],[-53.05999799999995,47.91693900000001],[-53.05944099999999,47.886658000000125],[-53.07583599999998,47.85083000000009],[-53.15860700000002,47.68305200000009],[-53.178337,47.65138200000001],[-53.18360899999993,47.64638500000012],[-53.201667999999984,47.63638300000014],[-53.22110699999996,47.628601],[-53.24083699999994,47.622489999999914],[-53.259727,47.61582900000002],[-53.26500699999997,47.61166400000002],[-53.26722000000001,47.60610200000008],[-53.26167299999997,47.54638699999998],[-53.17556000000002,47.4313810000001],[-53.128333999999995,47.41110200000014],[-53.12194099999999,47.413321999999994],[-53.11194599999999,47.42360700000012],[-53.08306099999999,47.458327999999995],[-53.06583399999994,47.46998600000006],[-53.013061999999934,47.501389000000074],[-52.995003,47.51138300000008],[-52.95166799999993,47.530823000000055],[-52.919167000000016,47.54166399999997],[-52.907219,47.54833200000013],[-52.89694999999995,47.55860100000001],[-52.84916700000002,47.621101000000124],[-52.84249899999992,47.632767000000115],[-52.84055299999994,47.638329000000056],[-52.837501999999915,47.65415999999999],[-52.838889999999935,47.66387900000001],[-52.841110000000015,47.66860200000002],[-52.84166700000003,47.67332499999998],[-52.84055299999994,47.683876000000055],[-52.79888900000003,47.78416400000003],[-52.79138899999998,47.795547000000056],[-52.78556100000003,47.79972100000009],[-52.77944200000002,47.803047000000106],[-52.770554000000004,47.79972100000009],[-52.704169999999976,47.75388299999997],[-52.70055400000001,47.749435000000005],[-52.65777600000001,47.657493999999986],[-52.61444899999998,47.51666299999994],[-52.62027699999999,47.5002750000001],[-52.625832,47.48915899999997],[-52.65332799999999,47.43776700000001],[-52.71805599999993,47.364998000000014],[-52.78750600000001,47.30804399999994],[-52.818610999999976,47.22415900000004],[-52.84972399999998,47.1616590000001],[-52.84527600000001,47.14249399999994],[-52.843613000000005,47.06388099999998],[-52.84416199999998,47.05860100000007],[-52.85278299999999,47.022491],[-52.88417099999998,46.9741590000001],[-52.90999599999998,46.911658999999986],[-52.92972599999996,46.85166200000003],[-52.93277699999999,46.82555400000007],[-52.93499800000001,46.804993000000024],[-52.938332,46.78916200000009],[-53.090836000000024,46.643326],[-53.10250100000002,46.63665800000001],[-53.16111000000001,46.61998699999998],[-53.16916699999996,46.61971300000005],[-53.192497,46.62332200000003],[-53.20722199999989,46.630272000000105],[-53.21333299999998,46.63388100000009],[-53.315552000000025,46.694709999999986],[-53.35417199999995,46.73693800000001],[-53.36194599999993,46.73749500000008],[-53.38417099999998,46.72137500000002],[-53.410552999999936,46.700829],[-53.426391999999964,46.68721000000011],[-53.451392999999996,46.66137700000013],[-53.46361499999995,46.65416000000005],[-53.52111100000002,46.62082700000002],[-53.53277600000001,46.61415900000003],[-53.56166799999994,46.61277000000007],[-53.56944999999996,46.61415900000003],[-53.577225,46.617493000000024],[-53.60777999999999,46.63610799999998],[-53.613891999999964,46.64027400000003],[-53.617774999999995,46.64415700000001],[-53.63500199999993,46.68082399999997],[-53.643058999999994,46.7044370000001],[-53.64416499999993,46.70916000000011],[-53.648056,46.79666100000003],[-53.64778100000001,46.80193299999996],[-53.645279000000016,46.81249200000002],[-53.639725,46.82916300000005],[-53.636391,46.83471700000007],[-53.594719,46.9447100000001],[-53.64166999999992,46.983879],[-53.63361400000002,47.00110599999999],[-53.57778199999996,47.08526599999993],[-53.55083499999995,47.106659000000036],[-53.539444,47.11415899999997],[-53.591385,47.15609699999999],[-53.64639299999999,47.105270000000075],[-53.70361299999996,47.053047000000106],[-53.823059,46.956657000000064],[-53.89416499999999,46.899994000000106],[-53.94583099999994,46.85888700000004],[-54.05332899999996,46.794998000000135],[-54.097220999999934,46.79943800000012],[-54.17888599999992,46.81610100000006],[-54.18777499999999,46.81916000000001],[-54.18999500000001,46.82360799999998],[-54.190833999999995,46.82860599999998],[-54.196387999999956,46.86249499999997],[-54.196663,46.883331],[-54.193329000000006,46.89360799999997],[-54.16082799999998,46.981934000000024],[-54.13194299999998,47.012496999999996],[-54.11500499999994,47.039719000000105],[-54.092498999999975,47.0794370000001],[-54.066666,47.13110400000011],[-53.993889000000024,47.26527400000003],[-53.964721999999995,47.299721000000034],[-53.92861199999999,47.302773000000116],[-53.921943999999996,47.30416100000002],[-53.879997,47.34804500000013],[-53.875557000000015,47.35416399999997],[-53.86750000000001,47.40277100000009],[-53.87943999999993,47.43082400000003],[-53.90027599999996,47.48610700000006],[-53.891669999999976,47.524711999999965],[-53.885558999999944,47.576941999999974],[-53.894721999999945,47.6055530000001],[-53.896950000000004,47.609993000000145],[-53.983886999999925,47.75777400000004],[-54.003333999999995,47.778877000000136],[-54.033332999999914,47.79666100000003],[-54.19527399999998,47.85749800000002],[-54.19499999999999,47.843048000000124],[-54.1972199999999,47.83221400000008],[-54.21277600000002,47.77777100000009],[-54.219161999999926,47.766106000000036],[-54.22388499999994,47.75999500000012],[-54.25917099999998,47.71527100000014],[-54.33777600000002,47.621658000000025],[-54.435272,47.505554000000075],[-54.468605000000025,47.441658000000075],[-54.47749299999998,47.40499100000005],[-54.47249599999998,47.401099999999985],[-54.47749299999998,47.39582800000005],[-54.48277299999995,47.39166300000005],[-54.511116000000015,47.372765000000015],[-54.51721999999995,47.36943800000006],[-54.60139499999997,47.34526800000003],[-54.611388999999974,47.353049999999996],[-54.61306000000002,47.35833000000008],[-54.61333499999995,47.36277000000007],[-54.606948999999986,47.37443499999995],[-54.601944,47.37971500000003],[-54.59666399999986,47.38388099999992],[-54.55999800000001,47.413879000000065],[-54.52916699999997,47.442214999999976],[-54.489998000000014,47.48638200000005],[-54.417220999999984,47.583603000000096],[-54.41082799999987,47.59499400000004],[-54.41332999999992,47.599715999999944],[-54.418334999999956,47.60360700000001],[-54.43055700000002,47.59777100000014],[-54.44083399999994,47.58693700000009],[-54.50861400000002,47.513329],[-54.53194400000001,47.47998799999999],[-54.539444,47.468048000000124],[-54.56361399999997,47.43998700000003],[-54.57888799999989,47.423882000000106],[-54.604720999999984,47.4019320000001],[-54.62138399999998,47.38999200000001],[-54.70027900000002,47.35777300000001],[-54.71999399999993,47.35221899999999],[-54.72721899999999,47.351387000000045],[-54.81861099999986,47.363609000000054],[-54.81945000000002,47.368599000000074],[-54.80305499999997,47.38054699999998],[-54.79361699999998,47.391936999999984],[-54.78666700000002,47.413879000000065],[-54.78750600000001,47.418884000000105],[-54.796111999999994,47.420830000000024],[-54.85639200000003,47.39054900000008],[-54.98055299999993,47.285552999999936],[-55.039169000000015,47.225821999999994],[-55.04389200000003,47.22082500000005],[-55.04555499999998,47.21527100000009],[-55.04333500000001,47.210548000000074],[-55.05361199999993,47.15082600000011],[-55.065833999999995,47.09332300000011],[-55.06945000000002,47.08221400000002],[-55.100280999999995,47.05471],[-55.14944499999996,47.01221500000008],[-55.15471600000001,47.00804900000003],[-55.193329000000006,46.984993000000145],[-55.22582999999997,46.934433000000126],[-55.23027799999994,46.928329000000076],[-55.23694599999993,46.923607000000004],[-55.246947999999975,46.91693900000001],[-55.258613999999966,46.91027100000008],[-55.358337000000006,46.87416100000013],[-55.384170999999924,46.86582900000013],[-55.399993999999936,46.86582900000013],[-55.45666499999999,46.87471000000011],[-55.463615000000004,46.877486999999974],[-55.46860499999997,46.881660000000124],[-55.47193899999996,46.88638300000014],[-55.62694499999992,46.8688810000001],[-55.63417099999998,46.86666100000008],[-55.689719999999966,46.85832999999997],[-55.80332899999996,46.86054999999999],[-55.84583299999997,46.86971299999999],[-55.91500099999996,46.88749700000011],[-55.92361499999993,46.889717000000076],[-55.931389000000024,46.892769000000044],[-55.946663,46.89943699999998],[-55.966110000000015,46.90998800000011],[-55.98082699999992,46.932213000000104],[-55.98277300000001,46.93665299999998],[-55.98416899999995,46.94165800000002],[-55.98305499999998,46.95249200000006],[-55.980552999999986,46.95777100000004],[-55.96665999999999,46.98137700000012],[-55.95249899999999,46.99638399999992],[-55.88694800000002,47.05609900000002],[-55.87110899999999,47.069160000000124],[-55.86555499999997,47.07276899999994],[-55.77527600000002,47.10193600000008],[-55.76860799999997,47.10332500000004],[-55.74555199999992,47.10443900000007],[-55.73889200000002,47.10443900000007],[-55.72360999999995,47.104164000000026],[-55.715553,47.10305000000005],[-55.698050999999964,47.09804500000001],[-55.68250299999994,47.09137700000002],[-55.67444599999999,47.09027099999997],[-55.586945000000014,47.110275000000115],[-55.573616000000015,47.11360900000011],[-55.493331999999896,47.133880999999974],[-55.48777799999999,47.13721499999997],[-55.32944500000002,47.242493000000024],[-55.29833999999994,47.26721199999997],[-55.290557999999976,47.2783280000001],[-55.285278000000005,47.29499800000002],[-55.28583500000002,47.31027200000011],[-55.28694899999999,47.31499500000007],[-55.28611799999999,47.325554000000125],[-55.269721999999945,47.39083099999999],[-55.266662999999994,47.39666],[-55.262221999999895,47.40277100000009],[-55.25694999999996,47.407211000000075],[-55.202225,47.44609800000012],[-55.179169,47.46054800000002],[-55.17250100000001,47.46388200000001],[-55.10777999999999,47.48360400000007],[-55.100554999999986,47.48416099999997],[-55.08361100000002,47.481101999999964],[-55.07583599999987,47.48082000000011],[-55.04028299999993,47.48499300000003],[-54.95139299999988,47.504997],[-54.86805700000002,47.54388399999999],[-54.84583299999997,47.55693800000006],[-54.84166699999997,47.56332400000014],[-54.841385,47.583603000000096],[-54.845551,47.63388100000009],[-54.949439999999925,47.599715999999944],[-54.95639,47.59804500000007],[-54.97083299999997,47.59665699999999],[-55.019278999999926,47.621101000000124],[-55.02827799999989,47.62076600000012],[-55.033278999999936,47.62160100000011],[-55.036109999999894,47.623936000000015],[-55.03761299999991,47.62660199999999],[-55.03744099999989,47.62977200000006],[-55.03561000000002,47.63326999999998],[-55.02961299999993,47.639598999999976],[-55.013779,47.65310299999993],[-55.00777800000003,47.65943500000003],[-54.95639,47.74137900000011],[-54.94749499999995,47.75360900000004],[-54.93804899999998,47.771103000000096],[-54.936110999999926,47.78166199999998],[-54.94305400000002,47.78110500000008],[-54.94860799999992,47.776657000000114],[-55.011391,47.721374999999966],[-55.021942000000024,47.71166199999993],[-55.02527600000002,47.70526899999999],[-55.027221999999995,47.69526700000006],[-55.03055599999999,47.68415800000014],[-55.03361499999994,47.67832900000013],[-55.119114000000025,47.61693600000012],[-55.122443999999916,47.61426900000009],[-55.12628199999995,47.612774],[-55.130774999999915,47.61193800000012],[-55.13577700000002,47.61360500000001],[-55.262778999999966,47.650543000000084],[-55.34916700000002,47.7044370000001],[-55.34833500000002,47.71027400000003],[-55.357506,47.726097000000095],[-55.365005,47.72637900000012],[-55.379722999999956,47.724991000000045],[-55.42749799999996,47.71166199999993],[-55.432503,47.70638299999996],[-55.46194499999996,47.64610300000004],[-55.46472199999994,47.64027400000003],[-55.467498999999975,47.61915599999992],[-55.46665999999999,47.61415900000003],[-55.46138799999994,47.610275],[-55.454444999999964,47.61110700000012],[-55.446663,47.623046999999985],[-55.436110999999926,47.631659999999954],[-55.43000000000001,47.634163000000115],[-55.42305799999997,47.635826000000066],[-55.415276000000006,47.63249200000007],[-55.40777600000001,47.624161000000015],[-55.40027600000002,47.615547000000106],[-55.39833799999997,47.610275],[-55.389725,47.58638000000002],[-55.40027600000002,47.514717000000076],[-55.406661999999926,47.49305000000004],[-55.40972099999999,47.487213000000054],[-55.41416199999992,47.481101999999964],[-55.42972600000002,47.46720900000014],[-55.43638599999997,47.46554600000002],[-55.49861099999998,47.45388000000003],[-55.50583599999993,47.453322999999955],[-55.52610800000002,47.45443699999993],[-55.55527499999994,47.44026900000006],[-55.56055500000002,47.43610400000006],[-55.56500199999999,47.429993000000024],[-55.58777600000002,47.398604999999975],[-55.625,47.46360800000008],[-55.65416700000003,47.49527000000006],[-55.79527999999999,47.49276700000007],[-55.914443999999946,47.43776700000001],[-55.920279999999934,47.43526500000013],[-55.92556000000002,47.439156000000025],[-55.92388900000003,47.444709999999986],[-55.91972399999986,47.450829000000056],[-55.83167300000002,47.517212000000086],[-55.788895000000025,47.551102000000014],[-55.745834,47.58526600000005],[-55.77305599999994,47.57972000000001],[-55.82417299999997,47.56638299999997],[-55.89222699999999,47.5366590000001],[-55.98777799999999,47.500549000000035],[-56.104172000000005,47.46360800000008],[-56.110557999999855,47.462494000000106],[-56.11860699999994,47.46360800000008],[-56.15888999999993,47.48471800000004],[-56.169167000000016,47.49249300000014],[-56.1725009999999,47.49721500000004],[-56.1725009999999,47.50166300000001],[-56.16805999999997,47.50721699999997],[-56.16249800000003,47.51138300000008],[-56.12027699999993,47.519157000000064],[-56.044448999999986,47.53527100000002],[-55.94193999999993,47.56166100000007],[-55.88999899999993,47.57833099999999],[-55.63999899999999,47.66805300000004],[-55.633331,47.67110400000007],[-55.628333999999995,47.674713000000054],[-55.635001999999986,47.67832900000013],[-55.64250199999998,47.67860400000012],[-55.64999399999999,47.677773000000116],[-55.66388699999993,47.67555200000004],[-55.704169999999976,47.66499299999998],[-55.75,47.649437000000034],[-55.756110999999976,47.646942000000024],[-55.77471899999995,47.638329000000056],[-55.80471799999998,47.62443500000012],[-55.82444799999996,47.61859900000002],[-55.838889999999935,47.61721000000006],[-55.85583500000001,47.62027000000012],[-55.90332799999993,47.64527099999992],[-55.913611999999944,47.65304600000002],[-55.91750300000001,47.657493999999986],[-55.91944899999993,47.667213000000004],[-55.918609999999944,47.67304999999999],[-55.91638899999998,47.67832900000013],[-55.91194200000001,47.684432999999956],[-55.90138999999999,47.693047000000035],[-55.895554000000004,47.696655000000135],[-55.86639399999996,47.713882000000126],[-55.83277899999996,47.74249300000008],[-55.81500199999999,47.772491],[-55.799445999999875,47.79916400000002],[-55.74222600000002,47.92332500000009],[-55.746947999999975,47.93249499999996],[-55.75444799999997,47.94110100000006],[-55.76721999999995,47.95332300000007],[-55.77361300000001,47.95694000000003],[-55.78055599999999,47.95526899999993],[-55.81750499999998,47.88693999999998],[-55.83527399999991,47.85083000000009],[-55.835556,47.845543000000134],[-55.847220999999934,47.806938],[-55.84999800000003,47.80110200000013],[-55.854445999999996,47.79471600000005],[-55.865279999999984,47.78611000000012],[-55.877219999999966,47.778602999999976],[-55.888892999999996,47.773048000000074],[-56.04972799999996,47.69943200000006],[-56.08750199999997,47.73693800000001],[-56.08111600000001,47.73971599999999],[-56.05361199999999,47.77388000000002],[-56.057503,47.77832799999999],[-56.06416300000001,47.776657000000114],[-56.111671,47.76361099999997],[-56.125,47.75721699999997],[-56.185272,47.680274999999995],[-56.160278000000005,47.64222000000012],[-56.15499899999986,47.638329000000056],[-56.16138499999994,47.634163000000115],[-56.173332000000016,47.629714999999976],[-56.18749999999994,47.6272130000001],[-56.35833699999989,47.603324999999984],[-56.394722,47.60110500000013],[-56.41027799999995,47.601387000000045],[-56.41889200000003,47.60193600000014],[-56.443053999999904,47.60582700000003],[-56.54695099999998,47.613883999999985],[-56.615554999999915,47.61332700000008],[-56.64416499999999,47.59610000000009],[-56.64111300000002,47.592216000000064],[-56.63999899999999,47.58721200000008],[-56.64416499999999,47.581108000000086],[-56.65055099999995,47.57833099999999],[-56.774719000000005,47.53193700000003],[-56.840836000000024,47.52137799999997],[-56.902221999999995,47.55249000000009],[-56.92444599999999,47.56220999999999],[-56.95610799999997,47.574996999999996],[-56.96527900000001,47.57777400000009],[-56.99250000000001,47.58387800000014],[-56.99972500000001,47.58471700000007],[-57.01472499999994,47.58387800000014],[-57.096663999999976,47.56610100000006],[-57.11833200000001,47.56388100000004],[-57.12610599999999,47.56388100000004],[-57.13444500000003,47.56638299999997],[-57.15027600000002,47.57276900000005],[-57.16332999999992,47.57972000000001],[-57.20472000000001,47.59304800000001],[-57.53082999999987,47.630821000000026],[-57.65777600000001,47.60305000000011],[-57.779441999999904,47.62748700000003],[-57.88249999999999,47.65138200000001],[-58.02749599999993,47.69415300000003],[-58.03639199999998,47.69609800000006],[-58.35944399999994,47.64721700000001],[-58.690552000000025,47.598877000000016],[-58.77111099999996,47.59137700000008],[-58.86194599999993,47.589157000000114],[-58.88500199999987,47.5927660000001],[-58.89416499999987,47.59388000000007],[-58.93749999999994,47.589989],[-59.076667999999984,47.571663],[-59.10213099999993,47.56425100000013],[-59.11361699999992,47.55832700000008],[-59.118889000000024,47.554710000000114],[-59.135559,47.55638099999999],[-59.161941999999954,47.56166100000007],[-59.29778299999987,47.60665899999998],[-59.30444299999999,47.609993000000145],[-59.30583199999995,47.614998000000014],[-59.30944099999999,47.661102000000085],[-59.30944099999999,47.67137900000006],[-59.30499999999995,47.724991000000045],[-59.3024979999999,47.736107000000004],[-59.32556199999999,47.80721300000005],[-59.32972699999999,47.81638300000009],[-59.36916400000001,47.85277599999995],[-59.40193899999997,47.88027199999999],[-59.40694400000001,47.889717000000076],[-59.40471599999995,47.900269000000094],[-59.40083299999992,47.90665400000006],[-59.39166999999992,47.916664000000026],[-59.37805199999991,47.92249300000003],[-59.365554999999915,47.92499500000008],[-59.328612999999905,47.92887900000011],[-59.32194500000003,47.93054999999998],[-59.31639100000001,47.93415800000008],[-59.31138599999997,47.938881000000094],[-59.26777599999997,47.98220800000007],[-59.26500699999991,47.98804500000006],[-59.262778999999966,47.99943500000012],[-59.246947999999975,48.01194000000004],[-59.23027799999994,48.02276599999999],[-59.218605000000025,48.02916000000005],[-59.091384999999946,48.09027100000014],[-59.05388599999986,48.105552999999986],[-59.041114999999934,48.11027500000006],[-59.020554000000004,48.11638599999998],[-58.958054000000004,48.14999399999999],[-58.75,48.287498000000085],[-58.701392999999996,48.31971699999997],[-58.69110899999998,48.32888000000014],[-58.686385999999914,48.334160000000054],[-58.682503,48.34054600000013],[-58.678337,48.35193600000002],[-58.675835000000006,48.363051999999925],[-58.67027999999999,48.37499200000002],[-58.59888499999994,48.423325000000034],[-58.58777599999996,48.43055000000004],[-58.56889299999989,48.43859900000007],[-58.55583199999995,48.443047000000035],[-58.514725,48.45277399999998],[-58.50055699999996,48.45555100000007],[-58.492774999999995,48.45555100000007],[-58.492774999999995,48.4502720000001],[-58.49777999999998,48.44582400000013],[-58.51889,48.44137599999999],[-58.52610800000002,48.4405440000001],[-58.54639400000002,48.434990000000084],[-58.55889100000002,48.42971799999998],[-58.588889999999935,48.412765999999976],[-58.59999800000003,48.405823],[-58.601112,48.40082600000005],[-58.59194199999996,48.39887999999996],[-58.483611999999994,48.427773],[-58.47083299999997,48.43221299999999],[-58.464721999999995,48.43637799999999],[-58.449439999999925,48.449158000000125],[-58.4183349999999,48.48665599999998],[-58.42027999999999,48.508049000000085],[-58.56944999999996,48.53860500000002],[-58.673614999999984,48.55471000000006],[-58.682503,48.554993000000024],[-58.69721999999996,48.55304699999999],[-58.732215999999994,48.545830000000024],[-58.765556000000004,48.535828000000095],[-58.778052999999886,48.53193700000003],[-58.81249999999994,48.52388000000002],[-58.857506,48.51859999999999],[-58.931389000000024,48.51193999999998],[-58.95472000000001,48.51082599999995],[-58.97916399999997,48.51249700000005],[-58.988335000000006,48.51444200000003],[-59.004722999999956,48.52027100000004],[-59.013335999999924,48.522217000000126],[-59.09166700000003,48.50833100000011],[-59.10555999999997,48.50471500000009],[-59.118889000000024,48.50110600000005],[-59.146392999999875,48.49304999999998],[-59.19277199999999,48.47776799999997],[-59.232497999999964,48.468597000000045],[-59.246947999999975,48.46665999999999],[-59.25527999999997,48.467490999999995],[-59.260558999999944,48.47193100000004],[-59.26111599999996,48.476653999999996],[-59.23277300000001,48.52304800000013],[-59.228882,48.529160000000104],[-59.215003999999965,48.545547000000056],[-59.209998999999925,48.549995000000024],[-59.137504999999976,48.59887699999996],[-59.084166999999866,48.62638099999998],[-59.07778200000001,48.629158000000075],[-59.050277999999935,48.63555100000002],[-59.03055599999999,48.6419370000001],[-59.02416999999997,48.64471400000002],[-58.908889999999985,48.70193499999999],[-58.828888000000006,48.750832000000116],[-58.81166799999994,48.76166500000005],[-58.79972799999996,48.76805099999996],[-58.774719000000005,48.77887700000008],[-58.76777599999997,48.775551000000064],[-58.77249899999998,48.76998900000012],[-58.815001999999936,48.73582500000009],[-58.84972399999987,48.7149960000001],[-58.873885999999914,48.70165999999995],[-58.89111300000002,48.69082600000007],[-58.912773000000016,48.674713000000054],[-58.93860599999988,48.65360300000009],[-58.94777699999992,48.642769000000044],[-58.955832999999984,48.63027200000005],[-58.95861099999996,48.62416100000013],[-58.95861099999996,48.613883999999985],[-58.955832999999984,48.60943600000002],[-58.94749499999995,48.60110500000013],[-58.896950000000004,48.55193300000002],[-58.888335999999924,48.55110199999996],[-58.74305700000002,48.56082200000009],[-58.728332999999964,48.56249200000002],[-58.72138199999995,48.56443800000011],[-58.715003999999965,48.56721500000003],[-58.709442000000024,48.570831000000055],[-58.70444500000002,48.575271999999984],[-58.69554900000003,48.58693700000009],[-58.68332700000002,48.60582700000003],[-58.67666600000001,48.618050000000096],[-58.67250100000001,48.62943300000006],[-58.66999800000002,48.640831000000105],[-58.671386999999925,48.650825999999995],[-58.674171,48.65526600000004],[-58.67944299999999,48.66944100000012],[-58.68083200000001,48.68471500000004],[-58.658051,48.74304999999998],[-58.618331999999896,48.779716000000064],[-58.54389200000003,48.86082499999998],[-58.53583499999996,48.87860100000012],[-58.506667999999934,48.949431999999945],[-58.506667999999934,48.98054499999995],[-58.503333999999995,48.997490000000084],[-58.50083899999993,49.003608999999926],[-58.400832999999864,49.12748700000009],[-58.39611099999996,49.131377999999984],[-58.35194399999989,49.15026899999998],[-58.348884999999996,49.14582800000011],[-58.342967999999985,49.10020100000003],[-58.365635,49.07992200000007],[-58.368019000000004,49.061428000000035],[-58.35370299999994,49.05665600000003],[-58.31075299999992,49.068584000000044],[-58.29285799999997,49.07276200000007],[-58.24055499999997,49.0702740000001],[-58.17832199999998,49.063217000000066],[-58.143726000000015,49.04174000000012],[-58.09833500000002,48.99221799999998],[-58.08472399999994,48.98526800000013],[-58.07778199999996,48.98193400000014],[-58.06027999999992,48.97609699999998],[-58.05055199999998,48.973320000000115],[-57.99610899999999,48.96138000000002],[-57.961388,48.95665700000001],[-57.93860599999999,48.95832800000005],[-57.90166499999998,48.96276899999998],[-57.88805400000001,48.966102999999976],[-57.88166799999999,48.96888000000007],[-57.892226999999934,48.98165899999992],[-57.90055100000001,48.9847180000001],[-57.92944299999999,48.978874000000076],[-57.95861100000002,48.97609699999998],[-57.974716,48.97609699999998],[-58.00922399999996,48.98041500000005],[-58.02777900000001,48.98554999999999],[-58.03583499999996,48.98860200000013],[-58.05055199999998,48.99582700000002],[-58.09332999999998,49.025825999999995],[-58.103888999999924,49.033607000000075],[-58.10805499999992,49.03777299999996],[-58.135276999999974,49.08277100000004],[-58.144447000000014,49.12193300000007],[-58.122612000000004,49.124931000000004],[-58.119282,49.127102000000036],[-58.11560800000001,49.12910500000004],[-58.111110999999994,49.129771999999946],[-58.09477599999997,49.124603000000036],[-58.078776999999945,49.12176900000003],[-58.04944599999993,49.120270000000005],[-57.92555999999996,49.12304700000004],[-57.91861,49.12470999999999],[-57.91332999999997,49.12915800000013],[-57.88277399999993,49.157767999999976],[-57.87888299999997,49.17027300000012],[-57.89805599999994,49.15860000000009],[-57.912215999999944,49.15277100000009],[-57.92583499999989,49.14833100000004],[-57.939437999999996,49.144997000000046],[-57.94749499999995,49.144997000000046],[-58.05722000000003,49.144997000000046],[-58.075558,49.153271000000075],[-58.08105499999999,49.15443800000014],[-58.08605599999993,49.15626900000012],[-58.092555999999945,49.16093400000011],[-58.09589399999993,49.16627100000011],[-58.064055999999994,49.18335000000013],[-58.063057000000015,49.18545199999994],[-58.06545599999998,49.19041400000003],[-58.060622999999964,49.18858300000005],[-58.05495499999995,49.18758399999996],[-58.034957999999904,49.185749000000044],[-58.02545900000001,49.185749000000044],[-58.011292000000026,49.186252999999965],[-58.00245699999999,49.18825100000009],[-57.99562100000003,49.19207800000004],[-57.98878500000001,49.19724700000012],[-57.93221999999997,49.23416099999997],[-57.92805499999997,49.240273000000116],[-57.93638599999997,49.239716000000044],[-57.99516299999999,49.236885000000086],[-58.003330000000005,49.234215000000006],[-58.011662,49.23071299999998],[-58.031001999999944,49.22454800000003],[-58.03566399999994,49.22371300000003],[-58.049331999999936,49.222717000000046],[-58.05882999999994,49.223049],[-58.19193999999993,49.23638200000005],[-58.20083599999987,49.239716000000044],[-58.211945000000014,49.24721500000004],[-58.23388699999998,49.27304799999996],[-58.236663999999905,49.27748900000006],[-58.24083699999994,49.28694200000007],[-58.24194299999999,49.29166399999997],[-58.24194299999999,49.30221599999999],[-58.223327999999924,49.39027400000003],[-58.21639299999998,49.402488999999946],[-58.192497,49.42943600000007],[-58.15777600000001,49.46443900000003],[-58.152221999999995,49.468879999999956],[-58.04389200000003,49.541382000000056],[-58.03221899999994,49.54833200000007],[-58.01916499999987,49.55387900000005],[-57.99833699999999,49.559158000000025],[-57.97110700000002,49.554993000000024],[-57.91511200000002,49.532047000000034],[-57.91060999999996,49.53021600000005],[-57.903445999999974,49.525551000000064],[-57.861445999999944,49.505885999999975],[-57.74694799999992,49.45360600000009],[-57.71500400000002,49.454712000000086],[-57.707503999999915,49.45555100000007],[-57.70111099999997,49.458327999999995],[-57.69638800000001,49.46360800000002],[-57.69888300000002,49.468323000000055],[-57.705832999999984,49.47165700000005],[-57.788895000000025,49.500832000000116],[-57.86422299999998,49.534939000000065],[-57.86938900000001,49.53543900000005],[-57.87271900000002,49.53777300000007],[-57.94222300000001,49.60305000000011],[-57.94471699999997,49.60749800000008],[-57.95111099999991,49.65277100000014],[-57.95111099999991,49.65776800000009],[-57.94833399999993,49.674164000000076],[-57.935272,49.708602999999925],[-57.926391999999964,49.726379000000065],[-57.89999399999999,49.76221500000008],[-57.82916999999992,49.84554300000008],[-57.67111199999994,50.084160000000054],[-57.631667999999934,50.14471400000008],[-57.543334999999956,50.29833200000013],[-57.524445000000014,50.33416],[-57.52138499999995,50.345267999999976],[-57.52111100000002,50.35054800000006],[-57.51555599999995,50.37360400000006],[-57.50722499999995,50.390831000000105],[-57.49833699999999,50.408600000000035],[-57.490837,50.42083000000014],[-57.44860799999998,50.48610699999995],[-57.37722000000002,50.58443499999993],[-57.37249799999995,50.5908280000001],[-57.36111499999993,50.598602000000085],[-57.34166700000003,50.60749800000002],[-57.310059000000024,50.60894000000013],[-57.300220000000024,50.60977600000007],[-57.295559000000026,50.60927200000009],[-57.291225,50.60710500000005],[-57.27622200000002,50.60144000000008],[-57.24527699999999,50.59638200000006],[-57.22804999999994,50.594437000000084],[-57.204444999999964,50.596100000000035],[-57.17361499999993,50.60083000000003],[-57.166945999999996,50.6033250000001],[-57.161384999999996,50.60638400000005],[-57.15083299999992,50.61610400000012],[-57.148056,50.621933000000126],[-57.15471599999995,50.625549000000035],[-57.171943999999996,50.624992000000134],[-57.276442999999915,50.64071700000005],[-57.378608999999926,50.687767000000065],[-57.33416699999992,50.71193700000009],[-57.32500499999992,50.71166200000005],[-57.23694599999999,50.72721100000001],[-57.16249800000003,50.75110599999999],[-57.14833799999991,50.75610399999999],[-57.08943899999991,50.780548000000124],[-57.072501999999986,50.79388400000005],[-56.98305499999998,50.86832400000009],[-56.927498000000014,50.915824999999984],[-56.898056,51.01944000000009],[-56.89917000000003,51.02443699999998],[-56.90332799999999,51.02860300000009],[-56.90999599999998,51.03276800000009],[-56.927223000000026,51.03860500000002],[-56.964721999999995,51.04332700000009],[-56.92166900000001,51.0513840000001],[-56.89222699999999,51.060272000000055],[-56.879996999999946,51.06554399999999],[-56.78444699999994,51.137771999999984],[-56.781386999999995,51.14360800000003],[-56.78194400000001,51.14916200000005],[-56.785278000000005,51.153046000000074],[-56.793334999999956,51.16137700000013],[-56.80972300000002,51.18360100000007],[-56.79389200000003,51.23998999999992],[-56.74416400000001,51.29305299999993],[-56.738609,51.298881999999935],[-56.733330000000024,51.302773],[-56.68250299999994,51.3394320000001],[-56.623885999999914,51.366386000000034],[-56.616942999999935,51.368881000000044],[-56.512504999999976,51.40221400000007],[-56.47666199999992,51.411658999999986],[-56.461945000000014,51.41499299999998],[-56.45416999999992,51.415543000000014],[-56.27138499999995,51.47165699999999],[-56.110557999999855,51.52387999999996],[-56.011391,51.56638300000003],[-55.99833699999999,51.572220000000016],[-55.96028100000001,51.59388000000001],[-55.943329000000006,51.60638400000005],[-55.918609999999944,51.62110100000001],[-55.90555599999999,51.626937999999996],[-55.898056,51.62860100000012],[-55.89028200000001,51.629433000000006],[-55.83777599999996,51.621376000000055],[-55.84638999999993,51.60193600000008],[-55.85777999999999,51.59332300000011],[-55.88500199999993,51.562492000000134],[-55.88666499999994,51.556938],[-55.88694800000002,51.55193300000013],[-55.88722200000001,51.50027499999999],[-55.886116000000015,51.49527000000012],[-55.87777699999998,51.49221800000004],[-55.69444299999998,51.48110200000008],[-55.63999899999999,51.481934000000024],[-55.648612999999955,51.48526799999996],[-55.68360899999999,51.5],[-55.729720999999984,51.54332700000003],[-55.737503000000004,51.552490000000034],[-55.73916600000001,51.55665600000009],[-55.73860899999994,51.567214999999976],[-55.735274999999945,51.57305100000002],[-55.724716,51.58360300000004],[-55.718605000000025,51.58721200000002],[-55.65332799999999,51.59054600000002],[-55.63166799999999,51.569717000000026],[-55.625,51.5655440000001],[-55.59861000000001,51.56137799999999],[-55.589721999999995,51.56027199999994],[-55.58138999999994,51.56027199999994],[-55.57444800000002,51.56276700000001],[-55.54750100000001,51.584991000000116],[-55.51583899999997,51.60221900000005],[-55.45861099999996,51.59221600000001],[-55.41111000000001,51.580826000000116],[-55.40555599999999,51.57694200000009],[-55.40444200000002,51.5719380000001],[-55.40527300000002,51.56166100000013],[-55.40694400000001,51.55609900000002],[-55.454444999999964,51.45526899999999],[-55.49222600000002,51.37776900000006],[-55.50805700000001,51.36332700000008],[-55.597778000000005,51.303604000000064],[-55.612777999999935,51.30110200000013],[-55.62222300000002,51.30332199999998],[-55.70278200000001,51.32804900000008],[-55.82055700000001,51.35083000000009],[-56.030555999999876,51.37860099999995],[-56.07833899999997,51.36971299999999],[-56.085556,51.36832399999997],[-56.096389999999985,51.318329000000006],[-56.025557999999876,51.23832700000003],[-56.01225299999999,51.21233700000005],[-55.99256100000002,51.17657500000013],[-55.95944199999997,51.19748700000008],[-55.85139499999997,51.22693600000002],[-55.83777599999996,51.23054500000006],[-55.76916499999999,51.216934000000094],[-55.76083399999999,51.213881999999955],[-55.72610500000002,51.190544000000045],[-55.71277600000002,51.17804700000005],[-55.70999899999998,51.17360700000006],[-55.71916199999998,51.12304700000004],[-55.732497999999964,51.07999400000011],[-55.73555799999991,51.07416500000011],[-55.75111399999997,51.05832700000008],[-55.75695000000002,51.05387900000011],[-55.796111999999994,51.03916200000009],[-55.80555700000002,51.00916300000006],[-55.85916900000001,50.94249000000002],[-55.99944299999987,50.788605000000075],[-56.068893,50.72443400000009],[-56.09227800000002,50.72571600000009],[-56.097279000000015,50.72588000000002],[-56.10127999999992,50.72804599999995],[-56.125832,50.754166000000055],[-56.130829000000006,50.763329000000056],[-56.133331,50.77304800000002],[-56.128052000000025,50.84638200000006],[-56.12222300000002,50.8638840000001],[-56.11972000000003,50.86915600000003],[-56.116394000000014,50.87499200000008],[-56.107223999999974,50.88721499999997],[-56.10388899999998,50.893326],[-56.10388899999998,50.89833100000004],[-56.107779999999934,50.90277100000009],[-56.12222300000002,50.89943700000009],[-56.14305899999994,50.89249400000011],[-56.155272999999966,50.885551000000135],[-56.1725009999999,50.85582700000009],[-56.15721899999994,50.69082600000007],[-56.141272999999956,50.6710470000001],[-56.13577699999996,50.66988400000014],[-56.16332999999992,50.61776700000007],[-56.25861400000002,50.502777000000094],[-56.32361599999996,50.446380999999974],[-56.42305799999991,50.352776000000006],[-56.42194399999994,50.34777100000014],[-56.42222600000002,50.34249100000005],[-56.423614999999984,50.33693700000009],[-56.42666600000001,50.331108000000086],[-56.462501999999915,50.272217000000126],[-56.50194499999992,50.214439000000084],[-56.51194799999996,50.20360600000009],[-56.55583200000001,50.16749600000003],[-56.635276999999974,50.10638399999999],[-56.743056999999965,50.022766000000104],[-56.76750199999992,49.96221200000008],[-56.778610000000015,49.933876],[-56.78194400000001,49.91749600000003],[-56.77500199999997,49.91915899999998],[-56.726661999999976,49.91610000000003],[-56.75984599999998,49.837275999999974],[-56.82790399999999,49.78500000000008],[-56.86686300000002,49.777603],[-56.90533099999999,49.74752000000012],[-56.82099900000003,49.74209600000006],[-56.78400799999997,49.731243000000006],[-56.78277600000001,49.69082600000007],[-56.815552000000025,49.59499400000004],[-56.818610999999976,49.58888200000001],[-56.84888499999994,49.544441000000006],[-56.84305599999993,49.548050000000046],[-56.826667999999984,49.56276700000001],[-56.78277600000001,49.60999300000009],[-56.76306199999999,49.63137800000004],[-56.749167999999884,49.64916199999999],[-56.73555799999997,49.66693900000001],[-56.71250199999997,49.696380999999974],[-56.67777999999993,49.73360400000013],[-56.598609999999894,49.81193500000006],[-56.56138599999997,49.84221599999995],[-56.477776000000006,49.89222000000001],[-56.46416499999992,49.89638500000001],[-56.43194599999998,49.890549000000135],[-56.412216,49.90971400000012],[-56.38805400000001,49.94304700000009],[-56.38500199999993,49.94915800000001],[-56.330284000000006,50.024994000000106],[-56.32417299999997,50.029990999999995],[-56.23777799999999,50.10027300000007],[-56.22083299999997,50.112495000000024],[-56.20889299999999,50.12027000000012],[-56.160278000000005,50.148048000000074],[-56.153884999999946,50.150543000000084],[-56.13249999999999,50.155548000000124],[-56.12471800000003,50.15638000000007],[-56.116660999999965,50.153046000000074],[-56.067222999999956,50.096382000000006],[-56.065001999999936,50.091377000000136],[-56.00500499999998,50.03138000000001],[-55.938605999999936,50.03638500000005],[-55.90527300000002,50.03388200000006],[-55.89611100000002,50.031937000000084],[-55.881110999999976,50.024994000000106],[-55.853888999999924,50.005554000000075],[-55.84610699999996,49.996940999999936],[-55.845275999999956,49.99221799999998],[-55.845551,49.986938000000066],[-55.84416199999998,49.98193400000014],[-55.840836000000024,49.977211000000125],[-55.83000199999998,49.969154],[-55.75500499999987,49.92416400000002],[-55.74610899999993,49.923050000000046],[-55.58721899999995,49.96415700000006],[-55.55610699999994,49.98027000000013],[-55.54389200000003,49.98721300000011],[-55.527221999999995,50.0002750000001],[-55.49169899999998,50.00730900000002],[-55.46333299999998,49.96693399999998],[-55.460830999999985,49.96221200000008],[-55.45972399999994,49.957497000000046],[-55.46028100000001,49.95221699999996],[-55.46500400000002,49.940826000000015],[-55.47527299999996,49.93027500000011],[-55.49222600000002,49.91721300000006],[-55.511391,49.908882000000006],[-55.659163999999976,49.84777100000008],[-55.84305599999993,49.78833000000009],[-55.98611499999987,49.74694099999999],[-56.11527999999993,49.63999200000012],[-56.124168,49.61332700000008],[-56.050551999999925,49.66638200000011],[-56.044448999999986,49.669990999999925],[-55.963889999999935,49.698601],[-55.957779000000016,49.70027200000004],[-55.89389,49.714157000000114],[-55.833327999999995,49.68665299999992],[-55.88027999999997,49.584990999999945],[-55.93544399999996,49.54399100000012],[-55.94544199999996,49.536159999999995],[-55.95344499999999,49.533660999999995],[-55.971607000000006,49.531826000000024],[-55.980278,49.53049500000003],[-56.03527799999995,49.50666000000007],[-56.08000199999992,49.48693800000001],[-56.12749500000001,49.43110700000011],[-56.129166,49.42555200000004],[-56.12277199999994,49.421379000000115],[-56.073891,49.434432999999956],[-56.06221800000003,49.440544000000045],[-56.02527599999996,49.46110500000009],[-56.02027899999996,49.46499599999993],[-56.005279999999914,49.48082000000005],[-55.99972500000001,49.48526800000002],[-55.96305499999994,49.496155000000044],[-55.91705300000001,49.50749600000012],[-55.87471799999997,49.51721200000003],[-55.82778199999996,49.5241620000001],[-55.783332999999914,49.511940000000095],[-55.775001999999915,49.50860599999993],[-55.72499799999997,49.47943100000009],[-55.72083299999997,49.47582200000005],[-55.725554999999986,49.47054300000008],[-55.72277100000002,49.45388000000003],[-55.67833699999994,49.38694000000004],[-55.67305799999997,49.38304900000014],[-55.664444,49.381935],[-55.65638699999994,49.38221000000004],[-55.65027599999996,49.384162999999944],[-55.639167999999984,49.392769000000044],[-55.63611599999996,49.39860499999992],[-55.637778999999966,49.40915700000011],[-55.637778999999966,49.413605000000075],[-55.63611599999996,49.41915900000009],[-55.58916499999992,49.46249400000005],[-55.56027999999998,49.482490999999925],[-55.55388599999992,49.48499300000003],[-55.54695099999998,49.48638199999999],[-55.53167000000002,49.487770000000125],[-55.523056,49.486655999999925],[-55.522223999999994,49.481934000000024],[-55.56639099999995,49.40915700000011],[-55.572776999999974,49.376656000000025],[-55.573058999999944,49.371658000000025],[-55.57055699999995,49.36693600000012],[-55.566666,49.36277000000001],[-55.55999800000001,49.365273],[-55.55471799999992,49.36971300000005],[-55.539443999999946,49.38555100000008],[-55.52972399999999,49.396942000000024],[-55.528053,49.402488999999946],[-55.528885,49.408043000000134],[-55.52916699999997,49.42332499999998],[-55.52638999999999,49.42860399999995],[-55.49610899999999,49.45388000000003],[-55.441666,49.491104000000064],[-55.430282999999974,49.498878000000104],[-55.37749500000001,49.50360900000004],[-55.36944599999998,49.50332600000007],[-55.34927699999997,49.468159000000014],[-55.33294699999993,49.41648900000013],[-55.33577699999995,49.388161000000025],[-55.333610999999905,49.35916100000003],[-55.33860800000002,49.35527000000013],[-55.336112999999955,49.35082999999997],[-55.315276999999924,49.31443799999994],[-55.31099699999993,49.35593799999998],[-55.30683099999993,49.356772999999976],[-55.274834,49.385605000000055],[-55.26750199999998,49.39660300000003],[-55.2645,49.40343500000006],[-55.264336000000014,49.406441000000086],[-55.26666999999986,49.40910300000007],[-55.269833000000006,49.41143800000003],[-55.28083800000002,49.41443600000008],[-55.28317299999992,49.41693500000008],[-55.31000099999994,49.48477200000002],[-55.310832999999946,49.487770000000125],[-55.30555700000002,49.53443900000008],[-55.261390999999946,49.54110700000007],[-55.14972699999993,49.546387000000095],[-55.14111299999996,49.54527300000012],[-55.13722200000001,49.540833000000134],[-55.123328999999956,49.49694100000005],[-55.12471799999997,49.46527100000014],[-55.22110700000002,49.26193999999998],[-55.231109999999944,49.251389000000074],[-55.23722099999998,49.24804699999993],[-55.29639400000002,49.22637900000001],[-55.315001999999936,49.216933999999924],[-55.365837,49.16526800000008],[-55.36916400000001,49.1594310000001],[-55.36944599999998,49.15416000000005],[-55.36000100000001,49.15138200000007],[-55.34749599999998,49.157211000000075],[-55.339721999999995,49.15860000000009],[-55.33167300000002,49.156654],[-55.32361599999996,49.153602999999976],[-55.319449999999904,49.14916200000005],[-55.30721999999997,49.104996000000085],[-55.30777699999999,49.0991590000001],[-55.31750499999998,49.08776900000004],[-55.323059,49.08332799999994],[-55.383331,49.04083300000002],[-55.345551,49.05777000000006],[-55.27222399999994,49.099998000000085],[-55.277495999999985,49.10388200000011],[-55.282501000000025,49.11305199999998],[-55.283332999999914,49.11804999999998],[-55.288054999999986,49.182495000000074],[-55.288054999999986,49.18721000000011],[-55.285004000000015,49.19304700000009],[-55.28055599999993,49.199157999999954],[-55.27527599999996,49.204436999999984],[-55.148056,49.259995],[-55.08111600000001,49.28388200000006],[-55.08167300000002,49.345825000000104],[-55.08138999999994,49.35110500000013],[-55.07805599999995,49.356941000000006],[-55.06945000000002,49.3555530000001],[-55.01028400000001,49.32388300000002],[-54.989998000000014,49.28694200000007],[-54.99055499999997,49.28166200000004],[-54.82444800000002,49.269157000000064],[-54.817779999999914,49.271660000000054],[-54.78750600000001,49.28860500000002],[-54.78194400000001,49.29277000000002],[-54.67972599999996,49.37999000000002],[-54.65833299999997,49.39916200000005],[-54.648056,49.40943100000004],[-54.641388000000006,49.42110400000007],[-54.64389,49.42582700000008],[-54.579726999999934,49.494713000000104],[-54.541114999999934,49.526657000000114],[-54.528885,49.53333300000003],[-54.52111100000002,49.533882000000006],[-54.474716,49.53499599999998],[-54.431945999999925,49.47082499999999],[-54.43083199999995,49.465828000000045],[-54.45055400000001,49.427773000000116],[-54.483330000000024,49.36193800000012],[-54.49361399999998,49.26805100000007],[-54.49250000000001,49.263611000000026],[-54.48694599999999,49.25971999999996],[-54.48055299999993,49.262215000000026],[-54.474716,49.266662999999994],[-54.40638699999994,49.32083100000011],[-54.40083299999992,49.32527200000004],[-54.39917000000003,49.330551000000014],[-54.410278000000005,49.34360500000008],[-54.412773000000016,49.34804500000007],[-54.413612,49.35304999999994],[-54.407501000000025,49.37471000000011],[-54.40416700000003,49.38054700000009],[-54.395003999999915,49.392769000000044],[-54.38027999999997,49.40888200000012],[-54.36999499999996,49.41915900000009],[-54.36416600000001,49.42360700000006],[-54.35805499999998,49.426941000000056],[-54.32527900000002,49.42388200000005],[-54.24888599999997,49.397490999999945],[-54.186661000000015,49.371101000000124],[-54.17888599999992,49.37082700000002],[-54.1661069999999,49.3780440000001],[-54.1619419999999,49.38360600000004],[-54.15582999999998,49.40526600000004],[-54.15332799999993,49.416100000000085],[-54.15193899999991,49.427216000000044],[-54.14833799999997,49.437492000000134],[-54.145279000000016,49.44332099999997],[-54.13999899999993,49.44860100000005],[-54.13388800000001,49.45193499999999],[-54.04888900000003,49.47943100000009],[-54.04167199999995,49.48082000000005],[-53.91999800000002,49.44776900000011],[-53.77500199999997,49.39610300000004],[-53.67333199999996,49.34304800000001],[-53.511116000000015,49.27721400000007],[-53.48860899999994,49.220543000000134],[-53.58833299999998,49.04083300000002],[-53.593886999999995,49.03555299999999],[-53.66194200000001,49.03221100000002],[-53.71472199999994,49.02915999999999],[-53.80444299999999,49.02221700000001],[-53.78527799999995,49.01110799999992],[-53.731667000000016,49.013329000000056],[-53.725273000000016,49.009720000000016],[-53.73666400000002,49.00110599999999],[-53.742774999999995,48.997772],[-53.74916799999994,48.99527000000012],[-53.77027899999996,48.98943300000013],[-53.80361199999999,48.97804300000007],[-53.81305699999996,48.93888100000004],[-53.974441999999954,48.84777100000008],[-54.02138499999995,48.833327999999995],[-54.09610699999996,48.81221000000011],[-53.92027999999999,48.834991000000116],[-53.89917000000003,48.83804300000003],[-53.875557000000015,48.836937000000034],[-53.82944500000002,48.83138300000002],[-53.82055699999995,48.82943699999993],[-53.800835000000006,48.81276700000001],[-53.802223000000026,48.80777000000006],[-53.84527600000001,48.766936999999984],[-53.86777499999994,48.75],[-53.89055599999989,48.733604000000014],[-53.89722399999994,48.73137700000012],[-53.93221999999997,48.71393599999999],[-53.95055400000001,48.67083000000014],[-53.93250299999994,48.62471000000011],[-53.92444599999999,48.62443500000006],[-53.91722099999993,48.62499199999996],[-53.88861099999997,48.631660000000124],[-53.88277399999993,48.63360600000004],[-53.869163999999955,48.638885000000016],[-53.857223999999974,48.64415700000012],[-53.79555499999992,48.67582700000003],[-53.79000100000002,48.67999300000014],[-53.79888900000003,48.682213000000104],[-53.81777999999997,48.67388200000005],[-53.83139,48.66999099999998],[-53.85278299999993,48.66638199999994],[-53.896950000000004,48.66220900000002],[-53.91305499999993,48.663605000000075],[-53.92083699999995,48.667213000000004],[-53.92444599999999,48.67137900000006],[-53.892058999999904,48.68293800000009],[-53.88722599999994,48.690102000000024],[-53.884052,48.69310000000013],[-53.88055400000002,48.69509900000014],[-53.85755899999998,48.70493700000003],[-53.75917099999998,48.71415699999994],[-53.618056999999965,48.69443500000011],[-53.61000100000001,48.69304699999998],[-53.601943999999946,48.68971300000004],[-53.599723999999924,48.68499000000003],[-53.603888999999924,48.674164000000076],[-53.61000100000001,48.668602000000135],[-53.645835999999974,48.648330999999985],[-53.65860700000002,48.6419370000001],[-53.67194399999994,48.63860299999993],[-53.72888199999994,48.62943300000006],[-53.779998999999975,48.62360400000006],[-53.787780999999995,48.622490000000084],[-53.92833699999994,48.575829000000056],[-53.93332700000002,48.57222000000007],[-53.951392999999996,48.549995000000024],[-53.956107999999915,48.54388399999999],[-53.95249899999993,48.53943600000002],[-53.9441599999999,48.53971899999999],[-53.93221999999997,48.544998000000135],[-53.91999800000002,48.551659000000086],[-53.914444,48.55582400000009],[-53.908332999999914,48.559158000000025],[-53.901389999999935,48.56220999999999],[-53.89500399999986,48.56304899999992],[-53.804169,48.56805399999996],[-53.78805499999993,48.56638300000009],[-53.74639100000002,48.55860099999995],[-53.74694799999992,48.52332299999995],[-53.74888599999997,48.51332900000011],[-53.750838999999985,48.50777400000004],[-53.756366999999955,48.50326200000012]],[[-127.91443599999991,51.41082],[-127.92443799999995,51.41027100000008],[-128.06527700000004,51.464157000000114],[-128.07583599999998,51.47054300000002],[-128.08111599999995,51.47470900000013],[-128.15307599999988,51.601661999999976],[-128.15417499999995,51.60582699999998],[-128.15280199999995,51.638046000000145],[-128.15249600000004,51.64193700000004],[-128.15029899999996,51.64749100000006],[-128.14556900000002,51.65360300000003],[-128.136414,51.6616590000001],[-128.01306199999993,51.72137500000008],[-128.00527999999997,51.72332000000006],[-128,51.720542999999964],[-127.99694799999997,51.71415700000006],[-127.99804699999999,51.71166200000005],[-127.995003,51.7052690000001],[-127.98388699999998,51.68249500000013],[-127.96749899999992,51.65193199999999],[-127.951683,51.633880999999974],[-127.93776699999995,51.621933000000126],[-127.92639199999996,51.60888699999998],[-127.91999800000002,51.60054799999995],[-127.90556300000003,51.55971500000004],[-127.87361099999993,51.46443900000003],[-127.87193300000001,51.45193499999999],[-127.87332200000003,51.44776900000005],[-127.87666299999995,51.44304699999998],[-127.90444899999994,51.41471100000007],[-127.91443599999991,51.41082]],[[-55.36750000000001,51.874161000000015],[-55.37471800000003,51.87387800000005],[-55.38221699999991,51.875267000000065],[-55.42888599999998,51.884163],[-55.43000000000001,51.88582600000012],[-55.43111399999992,51.887771999999984],[-55.43055700000002,51.89666],[-55.42610899999994,51.905823],[-55.42333199999996,51.9094310000001],[-55.38777900000002,51.942764000000125],[-55.35361499999999,51.96360800000008],[-55.30139200000002,51.99305000000004],[-55.283889999999985,52.001389000000074],[-55.27722199999994,52.00249500000007],[-55.26999699999999,52.000549000000035],[-55.26888999999994,51.998604],[-55.26750199999998,51.993881000000044],[-55.27417000000003,51.97693600000008],[-55.27417000000003,51.975548],[-55.28194400000001,51.961937000000034],[-55.295005999999944,51.943321000000026],[-55.30222299999997,51.93332699999996],[-55.33250399999997,51.89638499999995],[-55.342223999999874,51.88638300000002],[-55.35472099999993,51.87804399999999],[-55.36000100000001,51.87582400000014],[-55.36750000000001,51.874161000000015]],[[-128.053894,51.7536090000001],[-128.11972000000003,51.74166100000008],[-128.13192699999996,51.7438810000001],[-128.13613899999996,51.74665799999997],[-128.25445599999995,51.86582900000002],[-128.25308199999995,51.87221499999998],[-128.22222899999997,51.953323000000125],[-128.21749899999998,51.962769000000094],[-128.177795,52.00833099999994],[-128.150848,52.03527100000002],[-128.14529400000004,52.03860500000002],[-128.107758,52.051659000000086],[-128.06082200000003,52.05638099999999],[-127.99582699999996,52.062767000000065],[-127.98332199999993,52.06193499999995],[-127.96028100000001,52.05554999999998],[-127.95472699999999,52.05332199999998],[-127.95121799999998,52.04691300000013],[-127.95140100000003,52.03054800000001],[-127.95472699999999,51.981101999999964],[-128.00723299999993,51.782493999999986],[-128.00946,51.7783280000001],[-128.01306199999993,51.77360500000009],[-128.018616,51.77027100000009],[-128.03582800000004,51.760826000000066],[-128.053894,51.7536090000001]],[[-79.252792,52.07138099999992],[-79.31973299999999,51.96998600000006],[-79.36444099999994,51.942214999999976],[-79.370544,51.938599000000124],[-79.37666300000001,51.93610400000006],[-79.38583399999999,51.935546999999985],[-79.42361499999987,51.93693500000006],[-79.43331899999987,51.93832400000008],[-79.45056199999988,51.942214999999976],[-79.50111400000003,51.942489999999964],[-79.56834400000002,51.935546999999985],[-79.57667500000002,51.934158000000025],[-79.591949,51.92276800000013],[-79.604446,51.91666400000008],[-79.61166400000002,51.91443600000014],[-79.61776700000001,51.91777000000013],[-79.62138399999998,51.9222180000001],[-79.65278599999999,51.981101999999964],[-79.65417500000001,51.98665599999998],[-79.65083299999998,51.99193600000007],[-79.633896,52.01749399999994],[-79.62943999999999,52.022217000000126],[-79.62332200000003,52.02526900000004],[-79.61471599999993,52.02304800000013],[-79.608612,52.01998900000001],[-79.60388199999994,52.016106000000036],[-79.596115,52.013611000000026],[-79.58528100000001,52.01277200000004],[-79.56777999999997,52.0149990000001],[-79.53832999999997,52.023323000000005],[-79.40888999999999,52.071938000000046],[-79.39666699999987,52.07721700000002],[-79.38389599999994,52.09082799999999],[-79.345551,52.10860400000013],[-79.33833299999998,52.110275],[-79.29722599999997,52.09193399999998],[-79.27722199999988,52.090546000000074],[-79.26972999999992,52.08776899999998],[-79.26362599999999,52.083878000000084],[-79.252792,52.07138099999992]],[[-131.01889,51.94609800000006],[-131.02166699999998,51.94082599999996],[-131.029175,51.94137599999999],[-131.03695700000003,51.944435],[-131.04861499999998,51.951385000000016],[-131.074158,51.970543000000134],[-131.09500099999997,51.98998999999998],[-131.10165399999994,52.00277699999998],[-131.120544,52.05554999999998],[-131.12719699999997,52.09554300000002],[-131.126373,52.106941000000006],[-131.122498,52.12471000000011],[-131.116394,52.14804800000002],[-131.11026000000004,52.15109999999993],[-131.10192899999998,52.151932000000045],[-131.0836179999999,52.15138200000001],[-131.07720900000004,52.15026899999992],[-131.00946,52.102776000000006],[-130.9924929999999,52.06082200000009],[-131.00473,52.00582900000006],[-131.01889,51.94609800000006]],[[-127.96278399999989,52.07471499999991],[-128.05111699999992,52.07416500000005],[-128.062225,52.074996999999996],[-128.07638499999996,52.07999400000011],[-128.09387199999998,52.090546000000074],[-128.105835,52.100273000000016],[-128.10888699999992,52.10527000000013],[-128.12081899999998,52.14193699999993],[-128.11471599999987,52.14916199999999],[-128.10693400000002,52.15248900000012],[-128.03167699999995,52.163292000000126],[-128.01583900000003,52.164711000000125],[-127.89111299999996,52.17166099999997],[-127.881104,52.17221800000004],[-127.87917299999998,52.166664000000026],[-127.88971700000002,52.13110399999999],[-127.89334100000002,52.12693800000005],[-127.943604,52.07916300000005],[-127.94721999999996,52.07582900000011],[-127.96278399999989,52.07471499999991]],[[-128.21194499999996,52.015549000000135],[-128.220825,52.01444200000003],[-128.23858599999994,52.014717000000076],[-128.2463679999999,52.01666299999994],[-128.25308199999995,52.019714000000135],[-128.29110699999995,52.10193600000014],[-128.29415899999998,52.113609],[-128.29168700000002,52.1188810000001],[-128.25280799999996,52.17137900000006],[-128.24444600000004,52.17999300000014],[-128.23971599999993,52.18415800000014],[-128.23193399999997,52.187492000000134],[-128.18804899999998,52.19360400000011],[-128.16223100000002,52.196655000000135],[-128.15307599999988,52.195267],[-128.14779699999997,52.19165800000002],[-128.14584399999995,52.186104],[-128.1480709999999,52.18332700000013],[-128.154724,52.15943100000004],[-128.15612799999997,52.15332000000012],[-128.15862999999996,52.11971299999999],[-128.154449,52.10860400000013],[-128.15139799999997,52.103882000000056],[-128.14752199999998,52.0927660000001],[-128.15112299999993,52.081108000000086],[-128.206116,52.01888300000013],[-128.21194499999996,52.015549000000135]],[[-128.42834499999992,52.13749700000011],[-128.44415300000003,52.134163000000115],[-128.44638099999997,52.13499500000006],[-128.50472999999994,52.16027100000008],[-128.50918599999994,52.16443600000008],[-128.51113899999996,52.16999099999998],[-128.50863600000002,52.17555200000004],[-128.50527999999997,52.180274999999995],[-128.50058,52.18415800000014],[-128.45138499999996,52.21720900000008],[-128.448059,52.21915400000006],[-128.43331899999998,52.22332],[-128.41641200000004,52.22637900000012],[-128.40972899999997,52.224991000000045],[-128.40640299999995,52.2227630000001],[-128.40527299999997,52.21859699999999],[-128.4100039999999,52.21471400000007],[-128.40777599999996,52.15277100000003],[-128.408905,52.149437000000034],[-128.41363499999994,52.14527099999992],[-128.42834499999992,52.13749700000011]],[[-128.29998799999998,52.13360600000004],[-128.308044,52.12887599999999],[-128.313629,52.129714999999976],[-128.36499000000003,52.1624910000001],[-128.37304699999999,52.18526500000007],[-128.378601,52.21360800000002],[-128.37832599999996,52.22026800000003],[-128.3771969999999,52.22387700000007],[-128.37027,52.22860000000003],[-128.35665900000004,52.23582500000009],[-128.345276,52.238602000000014],[-128.29724099999999,52.237213],[-128.23721299999994,52.222488000000055],[-128.22943099999998,52.22026800000003],[-128.22720300000003,52.21888000000013],[-128.22610499999996,52.21693400000004],[-128.22747799999996,52.21276900000004],[-128.22997999999995,52.2094350000001],[-128.29998799999998,52.13360600000004]],[[-81.476944,52.24916100000007],[-81.48582499999992,52.248329000000126],[-81.646118,52.25138900000002],[-81.68749999999994,52.25499700000012],[-81.70611599999995,52.25804900000003],[-81.71000700000002,52.262496999999996],[-81.69583099999994,52.26721200000003],[-81.57806399999998,52.29471600000005],[-81.55166600000001,52.298050000000046],[-81.541672,52.29666100000003],[-81.49305700000002,52.28388199999995],[-81.48055999999997,52.277489],[-81.475281,52.27388000000002],[-81.47166400000003,52.268051000000014],[-81.46806300000003,52.26305400000007],[-81.46777299999997,52.25694299999998],[-81.47083999999995,52.25222000000002],[-81.476944,52.24916100000007]],[[-127.924713,52.17416400000013],[-127.93360899999999,52.17304999999993],[-128.036407,52.17748999999998],[-128.05416899999994,52.18055000000004],[-128.07971199999997,52.186377999999934],[-128.08639500000004,52.18859900000007],[-128.0927729999999,52.19221500000009],[-128.16696199999996,52.244713000000104],[-128.17001299999998,52.24971800000014],[-128.15862999999996,52.25638600000008],[-128.06945799999994,52.29471600000005],[-128.0477909999999,52.30054500000006],[-128.04000899999994,52.30165900000003],[-127.97944599999994,52.29666100000003],[-127.972778,52.29527300000012],[-127.96193700000003,52.28943600000014],[-127.95861799999989,52.28749800000003],[-127.95111099999997,52.279716000000064],[-127.90943899999996,52.21027400000003],[-127.90750100000002,52.204712000000086],[-127.90666199999998,52.198601],[-127.91055299999988,52.186377999999934],[-127.91776999999996,52.176941],[-127.924713,52.17416400000013]],[[-128.18444799999992,52.278602999999976],[-128.20361299999996,52.277489],[-128.21026599999993,52.27832799999999],[-128.21362299999998,52.279716000000064],[-128.18917799999986,52.330826000000116],[-128.18307499999997,52.33971400000013],[-128.11471599999987,52.41832700000009],[-128.11111499999998,52.421661000000086],[-128.10443099999992,52.421379],[-128.0999759999999,52.418602000000135],[-128.093597,52.41165899999993],[-128.09249899999998,52.408324999999934],[-128.085266,52.396385000000066],[-128.05917399999998,52.35221900000005],[-128.05694600000004,52.346100000000035],[-128.05526699999996,52.334991000000116],[-128.05667099999994,52.32888000000008],[-128.061401,52.32471500000008],[-128.151947,52.282211000000075],[-128.18444799999992,52.278602999999976]],[[-127.72444199999995,51.97693600000008],[-127.8708269999999,51.944709999999986],[-127.87970699999994,51.94499200000007],[-127.886124,51.947768999999994],[-127.89167800000001,51.951385000000016],[-127.89472999999992,51.95610000000005],[-127.89943700000003,51.97332],[-127.90110799999991,51.98582499999998],[-127.90055799999988,51.999435000000005],[-127.881104,52.07888000000008],[-127.87361099999993,52.09499400000004],[-127.85138699999999,52.14138000000003],[-127.82833900000003,52.17582700000003],[-127.817497,52.191375999999934],[-127.79750100000001,52.213882000000126],[-127.78916899999996,52.221930999999984],[-127.75334199999998,52.24582700000008],[-127.74527,52.247772000000055],[-127.699997,52.25721699999991],[-127.68083199999995,52.25888800000001],[-127.65943900000002,52.259163],[-127.65055799999999,52.260276999999974],[-127.58640300000002,52.28110500000008],[-127.516663,52.30443600000012],[-127.51000999999985,52.306938],[-127.46056399999998,52.34582499999999],[-127.45694700000001,52.350548],[-127.45612299999988,52.362213000000054],[-127.45694700000001,52.36832400000014],[-127.45333900000003,52.37304699999993],[-127.4177699999999,52.38526900000011],[-127.36277799999999,52.403876999999966],[-127.26390100000003,52.43665300000009],[-127.25945300000001,52.435265000000015],[-127.23473399999995,52.41693900000001],[-127.20777899999996,52.34471100000002],[-127.21056399999992,52.33526599999999],[-127.218887,52.325829000000056],[-127.23222399999992,52.31304900000009],[-127.24749800000001,52.30193300000013],[-127.27084399999995,52.28860500000013],[-127.28916899999996,52.27943399999998],[-127.30304699999999,52.27416200000005],[-127.30999800000001,52.27166],[-127.32584400000002,52.268051000000014],[-127.36193800000001,52.26471700000002],[-127.42582699999997,52.24610100000001],[-127.43971299999993,52.240829000000076],[-127.44526699999994,52.23832699999997],[-127.57972699999999,52.177216000000044],[-127.58444199999991,52.17332499999998],[-127.58805799999999,52.167770000000075],[-127.59631300000001,52.151793999999995],[-127.65416700000003,52.12387799999999],[-127.68694299999993,52.074440000000095],[-127.69193999999993,52.06360600000005],[-127.70111099999991,52.04110700000007],[-127.703888,52.028877000000136],[-127.699997,52.01776899999999],[-127.69915799999995,52.01138300000008],[-127.699432,52.00471500000009],[-127.70194999999995,51.998604],[-127.708054,51.98832700000003],[-127.71749899999998,51.980270000000075],[-127.72444199999995,51.97693600000008]],[[-128.66860999999994,52.26638800000006],[-128.67556799999994,52.26638800000006],[-128.72055099999994,52.306938],[-128.724152,52.31137800000005],[-128.72637899999995,52.316101],[-128.74832200000003,52.36915600000009],[-128.76196299999998,52.41832700000009],[-128.76251200000002,52.42332500000009],[-128.76196299999998,52.429160999999965],[-128.759186,52.449432],[-128.75280799999996,52.4677660000001],[-128.74722299999996,52.47165699999999],[-128.6813959999999,52.48220800000007],[-128.674438,52.48220800000007],[-128.65029899999996,52.47443400000009],[-128.63696299999992,52.4685970000001],[-128.624146,52.4616620000001],[-128.61914099999996,52.45777100000004],[-128.615814,52.453606000000036],[-128.61608899999993,52.44860099999994],[-128.61331199999995,52.364441000000056],[-128.61471599999993,52.3533250000001],[-128.61776699999996,52.329994000000056],[-128.61999500000002,52.32388300000014],[-128.62554899999992,52.31137800000005],[-128.62997399999995,52.305550000000096],[-128.66860999999994,52.26638800000006]],[[-128.471924,52.49276700000013],[-128.4677729999999,52.483047000000056],[-128.46499599999993,52.47304500000007],[-128.46417199999996,52.46804800000001],[-128.46499599999993,52.462212000000136],[-128.467224,52.456099999999935],[-128.47082499999993,52.44971499999997],[-128.4805599999999,52.440269],[-128.4869379999999,52.43720999999999],[-128.494141,52.43498999999997],[-128.50946,52.432213000000104],[-128.51806599999998,52.43193800000006],[-128.59553499999998,52.46014000000008],[-128.66314699999987,52.49192799999997],[-128.75500499999998,52.48777000000001],[-128.77557399999995,52.49332400000003],[-128.7847289999999,52.496101000000124],[-128.80944799999997,52.51554900000008],[-128.81304899999992,52.519989000000066],[-128.81390399999998,52.524994000000106],[-128.811127,52.536941999999954],[-128.808899,52.54305300000004],[-128.73889199999996,52.58749400000005],[-128.732483,52.59054599999996],[-128.72470099999998,52.59165999999999],[-128.5781859999999,52.5936430000001],[-128.56750499999998,52.62249000000003],[-128.535278,52.64721700000007],[-128.53167699999995,52.62110100000001],[-128.52890000000002,52.611107000000004],[-128.52194199999997,52.59137700000002],[-128.50085399999995,52.543610000000115],[-128.4888919999999,52.52027099999998],[-128.48526000000004,52.515831000000105],[-128.47970599999996,52.50666000000001],[-128.471924,52.49276700000013]],[[-131.464447,52.62748700000009],[-131.58554099999998,52.585266000000104],[-131.593597,52.585823000000005],[-131.601379,52.5886000000001],[-131.6119379999999,52.59609999999998],[-131.62359600000002,52.60888699999998],[-131.709717,52.705269000000044],[-131.691101,52.7249910000001],[-131.68499799999995,52.728043000000014],[-131.65945399999993,52.730270000000075],[-131.48471099999995,52.736938000000066],[-131.475281,52.73665599999998],[-131.468597,52.73333000000014],[-131.46887200000003,52.73054500000012],[-131.44943199999994,52.71499600000004],[-131.44027699999998,52.706940000000145],[-131.4391779999999,52.70166000000006],[-131.441376,52.684158000000025],[-131.45443699999998,52.63638300000002],[-131.45834399999995,52.63082100000008],[-131.464447,52.62748700000009]],[[-128.43029799999994,52.36805000000004],[-128.44168099999996,52.36805000000004],[-128.4561159999999,52.37304699999993],[-128.460266,52.37721300000004],[-128.46664399999986,52.38693999999998],[-128.4677729999999,52.39305100000007],[-128.437775,52.543610000000115],[-128.44973800000002,52.62082700000008],[-128.450562,52.626937999999996],[-128.44168099999996,52.746941000000106],[-128.43917799999997,52.75222000000008],[-128.43582200000003,52.75694300000009],[-128.390015,52.79749300000003],[-128.383331,52.79749300000003],[-128.37332200000003,52.791107000000125],[-128.36276199999998,52.740272999999945],[-128.35861199999988,52.7291560000001],[-128.32138099999992,52.63472000000013],[-128.275848,52.496101000000124],[-128.27502400000003,52.489990000000034],[-128.28640699999994,52.45777100000004],[-128.311401,52.42388199999999],[-128.365814,52.38220999999993],[-128.371643,52.37887599999999],[-128.386414,52.374992000000134],[-128.40335099999993,52.37165800000014],[-128.43029799999994,52.36805000000004]],[[-128.974426,52.45332300000007],[-128.982758,52.453049000000135],[-129.11471599999993,52.55665600000009],[-129.21081499999997,52.64888000000002],[-129.26333599999998,52.710548000000074],[-129.27056899999997,52.719153999999946],[-129.291962,52.761664999999994],[-129.29278599999998,52.7669370000001],[-129.28140299999995,52.81721500000009],[-129.27722199999988,52.823051000000135],[-129.270844,52.826103000000046],[-129.26223799999997,52.82666000000012],[-129.252228,52.82527200000004],[-129.23111,52.81610100000006],[-129.218323,52.80915800000008],[-129.104156,52.74110399999995],[-129.066101,52.71471400000013],[-128.94695999999993,52.626381000000094],[-128.926941,52.61082500000009],[-128.92333999999994,52.606659000000036],[-128.919739,52.60221899999999],[-128.91861,52.527488999999946],[-128.92251599999997,52.51527400000003],[-128.936401,52.480545000000006],[-128.943604,52.469711000000075],[-128.9491579999999,52.465546000000074],[-128.96166999999997,52.45943500000004],[-128.974426,52.45332300000007]],[[-128.26974499999994,52.596939000000134],[-128.27416999999997,52.59554300000008],[-128.27890000000002,52.59582499999999],[-128.28445399999998,52.59860200000003],[-128.287506,52.60277600000006],[-128.28973399999995,52.60833000000008],[-128.29269399999993,52.661549000000036],[-128.32305899999994,52.74110399999995],[-128.32638499999996,52.77137800000003],[-128.32501199999996,52.7761000000001],[-128.26322900000002,52.784645000000125],[-128.21063200000003,52.79851500000001],[-128.18582199999992,52.82694200000003],[-128.177795,52.826103000000046],[-128.17334,52.82332600000012],[-128.17028799999997,52.81777199999999],[-128.175842,52.78777300000013],[-128.17861899999997,52.7761000000001],[-128.20776399999994,52.704436999999984],[-128.21026599999993,52.698875000000044],[-128.24722299999996,52.62054400000011],[-128.249725,52.616660999999965],[-128.26141399999995,52.60443900000001],[-128.26974499999994,52.596939000000134]],[[-131.63973999999996,52.828049000000135],[-131.64666699999992,52.82582900000011],[-131.64889499999998,52.826103000000046],[-131.669739,52.81916000000007],[-131.708344,52.811378000000104],[-131.72387700000002,52.80832700000008],[-131.73306299999996,52.80860100000001],[-131.81332399999997,52.82027400000004],[-131.82388300000002,52.82777400000009],[-131.83138999999994,52.84193400000004],[-131.830292,52.84665699999999],[-131.8225099999999,52.84804500000013],[-131.74859599999996,52.853324999999984],[-131.72860699999995,52.851387000000045],[-131.644745,52.83554800000013],[-131.636414,52.8324970000001],[-131.63973999999996,52.828049000000135]],[[-128.50527999999997,52.641106000000036],[-128.5125119999999,52.641106000000036],[-128.51611300000002,52.64527100000004],[-128.52029400000004,52.65499100000011],[-128.54000899999994,52.70332300000001],[-128.53500399999996,52.758049000000085],[-128.53362999999996,52.76915700000012],[-128.513916,52.860825000000034],[-128.510284,52.867493000000024],[-128.50613399999992,52.87304700000004],[-128.498871,52.87082700000002],[-128.49194299999994,52.868599000000074],[-128.48553499999997,52.865273],[-128.471924,52.853049999999996],[-128.46832299999994,52.84860200000003],[-128.45083599999992,52.805267000000015],[-128.45361300000002,52.782493999999986],[-128.45443699999998,52.776939000000084],[-128.5016779999999,52.647491],[-128.50527999999997,52.641106000000036]],[[-129.61053500000003,52.954994],[-129.618317,52.95360600000009],[-129.62222299999996,52.95804600000008],[-129.65139799999992,53.01332900000011],[-129.650848,53.01888300000013],[-129.62441999999993,53.02388000000002],[-129.615814,53.02443699999992],[-129.607208,53.02276600000005],[-129.5705569999999,53.013611000000026],[-129.5625,53.010551000000135],[-129.55749499999996,53.00666000000007],[-129.556671,53.00138900000002],[-129.558624,52.99749000000003],[-129.55334500000004,52.98499300000003],[-129.561127,52.97054300000008],[-129.5963749999999,52.9594350000001],[-129.61053500000003,52.954994]],[[-129.531677,53.010551000000135],[-129.53890999999993,53.008049000000085],[-129.546967,53.00888800000001],[-129.58859299999995,53.0241620000001],[-129.640015,53.04415899999998],[-129.63391099999996,53.056099000000074],[-129.56277499999993,53.05304699999999],[-129.52444500000001,53.03360699999996],[-129.51779199999993,53.02999100000011],[-129.517242,53.02499399999999],[-129.52056900000002,53.01832600000006],[-129.531677,53.010551000000135]],[[-55.76306199999999,53.02943400000004],[-55.85333300000002,53.01527399999992],[-55.86194599999999,53.015549000000135],[-55.870834,53.01859999999999],[-55.87638899999996,53.02748900000006],[-55.87610599999999,53.03276800000003],[-55.872772,53.04388399999999],[-55.86971999999997,53.04972100000009],[-55.85777999999999,53.06749700000006],[-55.854445999999996,53.071663],[-55.84860999999995,53.07610299999999],[-55.808333999999945,53.09137700000008],[-55.80055199999998,53.093605000000025],[-55.79222900000002,53.093048000000124],[-55.788612,53.08971400000013],[-55.78833799999995,53.08665500000001],[-55.749168,53.06916000000001],[-55.748885999999914,53.06471299999993],[-55.75500499999987,53.03860499999996],[-55.75666799999999,53.033051],[-55.76306199999999,53.02943400000004]],[[-129.60247799999996,53.05721300000005],[-129.61080899999996,53.056655999999975],[-129.69250499999993,53.075829000000056],[-129.701935,53.078330999999935],[-129.70834399999995,53.08166499999993],[-129.723053,53.09915900000004],[-129.73611500000004,53.12221500000004],[-129.738312,53.12721300000004],[-129.732758,53.13110399999994],[-129.716949,53.13388100000003],[-129.69973800000002,53.134995],[-129.6680599999999,53.13610800000009],[-129.662506,53.13555100000002],[-129.65444899999994,53.13276700000006],[-129.650848,53.130547000000035],[-129.644165,53.12721300000004],[-129.62081899999998,53.11249499999997],[-129.615814,53.10860400000007],[-129.5880429999999,53.08471700000007],[-129.58416699999998,53.08027600000014],[-129.58193999999997,53.07555400000007],[-129.586121,53.06999200000013],[-129.596649,53.061104000000114],[-129.60247799999996,53.05721300000005]],[[-79.90916400000003,53.081940000000145],[-79.91972399999997,53.081940000000145],[-79.92610200000001,53.084991],[-79.92971799999998,53.0894320000001],[-79.93222000000003,53.09443699999997],[-79.93859900000001,53.122490000000084],[-79.93859900000001,53.134995],[-79.93499799999995,53.147774000000084],[-79.93055700000002,53.15248900000012],[-79.906387,53.172768000000076],[-79.89778100000001,53.17443800000001],[-79.88751199999996,53.17443800000001],[-79.87748699999997,53.1730500000001],[-79.86639399999996,53.16944100000012],[-79.85888699999987,53.16693900000001],[-79.84611499999994,53.16054500000001],[-79.79583699999989,53.116386000000034],[-79.789444,53.106941000000006],[-79.78721599999994,53.10193600000014],[-79.789444,53.09582500000005],[-79.79695100000004,53.093605000000025],[-79.835556,53.083878000000084],[-79.843887,53.08221400000008],[-79.90916400000003,53.081940000000145]],[[-129.4324949999999,53.15138200000001],[-129.35278299999993,53.07222000000007],[-129.29000899999988,52.993607000000054],[-129.287506,52.978043000000014],[-129.28945899999985,52.971930999999984],[-129.295837,52.96888000000001],[-129.31222499999996,52.966934000000094],[-129.341095,52.97332],[-129.41418499999997,53.010551000000135],[-129.41915900000004,53.01444200000003],[-129.42138699999998,53.019157000000064],[-129.42471299999994,53.04027600000006],[-129.42916899999994,53.04972100000009],[-129.475281,53.10193600000014],[-129.50527999999997,53.12638099999998],[-129.51196300000004,53.129714999999976],[-129.52194199999985,53.13110399999994],[-129.537506,53.12832600000013],[-129.54473899999994,53.12832600000013],[-129.54724099999993,53.13304900000014],[-129.548065,53.14916199999999],[-129.546967,53.16027100000008],[-129.5386049999999,53.171660999999915],[-129.52166699999992,53.18360100000001],[-129.51446499999997,53.185822000000144],[-129.49859599999996,53.18859900000001],[-129.49026499999997,53.188881000000094],[-129.47997999999995,53.18776700000012],[-129.470551,53.185265000000015],[-129.46276899999992,53.17999300000008],[-129.4324949999999,53.15138200000001]],[[-81.10610999999989,53.19971499999997],[-81.08778399999989,53.17943600000001],[-81.04527299999995,53.14860500000009],[-80.97888199999994,53.11305200000004],[-80.97361799999999,53.10943600000002],[-80.80943300000001,52.97693600000008],[-80.77500899999995,52.94443499999994],[-80.76333599999992,52.931381000000044],[-80.66915899999998,52.776939000000084],[-80.66776999999996,52.7719350000001],[-80.66749600000003,52.7594380000001],[-80.67083699999989,52.74582700000013],[-80.67304999999993,52.74054700000005],[-80.69972200000001,52.69609800000012],[-80.70500199999998,52.692214999999976],[-80.71250900000001,52.689156000000025],[-80.720551,52.68832400000014],[-80.731674,52.68888100000004],[-80.73916600000001,52.69137600000005],[-80.74916100000002,52.698875000000044],[-80.75306699999999,52.70332300000001],[-80.76583900000003,52.70971700000001],[-80.79750099999995,52.719153999999946],[-80.81500199999999,52.72304500000001],[-80.86138899999992,52.73110200000002],[-80.89889499999998,52.73749500000014],[-80.91888399999999,52.740272999999945],[-80.99554399999994,52.74610100000007],[-81.01556399999993,52.74860400000006],[-81.02444499999996,52.750549000000035],[-81.13806199999993,52.78804800000012],[-81.15306099999998,52.793052999999986],[-81.19888299999997,52.81415600000008],[-81.21278399999994,52.81999199999996],[-81.25195300000001,52.8324970000001],[-81.287216,52.83998900000006],[-81.36915599999986,52.85610200000008],[-81.41722099999987,52.863052000000096],[-81.58444199999991,52.88916000000006],[-81.64917000000003,52.907211000000075],[-81.76362599999993,52.93776700000001],[-81.781387,52.941658000000075],[-81.81166099999996,52.94526700000006],[-81.83416699999987,52.94638100000003],[-81.88137799999998,52.954162999999994],[-81.91665599999999,52.96166199999999],[-81.93331899999998,52.965828000000045],[-81.94972199999995,52.97137500000002],[-81.96278399999989,52.97693600000008],[-82.04998799999998,53.01444200000003],[-82.05665599999986,53.01749400000011],[-82.06166100000002,53.021102999999925],[-82.06332399999991,53.026657000000114],[-82.060272,53.03193700000003],[-82.05332900000002,53.04193899999996],[-82.04916400000002,53.04666100000003],[-81.974716,53.113883999999985],[-81.96528599999994,53.12221500000004],[-81.95417799999996,53.129990000000134],[-81.91082799999998,53.15888200000006],[-81.89222699999999,53.16832699999998],[-81.864441,53.17860400000012],[-81.84805299999994,53.18166400000001],[-81.82611099999997,53.181381000000044],[-81.71472199999988,53.18859900000001],[-81.54305999999997,53.209160000000054],[-81.3852839999999,53.22499099999999],[-81.37499999999994,53.22499099999999],[-81.295547,53.21776599999998],[-81.11639400000001,53.20082900000011],[-81.10610999999989,53.19971499999997]],[[-131.76223800000002,53.19665500000008],[-131.6305539999999,53.08416],[-131.595551,53.04610399999996],[-131.593048,53.041382000000056],[-131.59472700000003,53.03527100000002],[-131.60165399999994,53.033051],[-131.61026000000004,53.03221100000013],[-131.628876,53.0324940000001],[-131.63973999999996,53.03443900000008],[-131.73666400000002,53.05387900000005],[-131.75558499999994,53.058601000000124],[-131.77444500000001,53.06888600000008],[-131.7839049999999,53.07138100000009],[-131.79473899999994,53.07305100000008],[-131.813629,53.07360799999998],[-131.82971199999992,53.07138100000009],[-131.943329,53.054993000000024],[-131.964722,53.046386999999925],[-131.91195700000003,53.00527199999999],[-131.9083559999999,53.011108000000036],[-131.89944499999996,53.019714000000135],[-131.888062,53.02693900000003],[-131.87027,53.03749800000003],[-131.85611,53.04222100000004],[-131.847778,53.04305299999993],[-131.831116,53.04305299999993],[-131.81167600000003,53.03971899999999],[-131.662781,53.00777400000004],[-131.644745,53.00388299999997],[-131.62860099999995,52.998328999999956],[-131.61498999999998,52.99166100000002],[-131.609711,52.98804500000011],[-131.598053,52.97526600000009],[-131.59582499999993,52.96471400000007],[-131.59750399999996,52.95860299999998],[-131.61554,52.920273000000066],[-131.662781,52.88221000000004],[-131.66805999999997,52.87804399999993],[-131.68057299999992,52.871658000000025],[-131.68749999999994,52.869155999999975],[-131.70443699999993,52.86776700000013],[-131.802216,52.86471599999993],[-131.808624,52.86582900000002],[-131.833618,52.88499500000006],[-131.849152,52.9019320000001],[-131.87027,52.922768000000076],[-131.88473499999992,52.93443300000001],[-131.890015,52.93832400000008],[-131.898346,52.94110099999995],[-131.906677,52.94026900000006],[-131.93859899999995,52.934990000000084],[-131.94473299999999,52.93166400000001],[-131.982483,52.87971500000003],[-131.978607,52.87554900000009],[-131.968597,52.87443500000012],[-131.95278899999988,52.875267000000065],[-131.94528200000002,52.87693800000011],[-131.93139599999995,52.88166000000001],[-131.85638399999993,52.85610200000008],[-131.7755739999999,52.71666000000005],[-131.767517,52.71388200000001],[-131.733612,52.69860100000011],[-131.72692900000004,52.69554100000005],[-131.72305299999988,52.691101],[-131.683899,52.64222000000001],[-131.681396,52.637496999999996],[-131.65945399999993,52.581665000000044],[-131.572784,52.52999100000005],[-131.56527700000004,52.5316620000001],[-131.55667099999994,52.53221100000002],[-131.545837,52.53027300000008],[-131.48193400000002,52.50777399999998],[-131.46749899999992,52.50138900000013],[-131.42361499999998,52.46082300000012],[-131.42748999999998,52.414993000000095],[-131.39849899999996,52.377827000000025],[-131.39533999999998,52.37549200000012],[-131.39016699999996,52.374660000000006],[-131.3674929999999,52.381827999999985],[-131.365494,52.384491000000025],[-131.36599699999988,52.390986999999996],[-131.36715700000002,52.39716000000004],[-131.357483,52.403320000000065],[-131.3583369999999,52.414153999999996],[-131.35305799999998,52.41832700000009],[-131.32833900000003,52.431107000000054],[-131.31304899999998,52.43415800000008],[-131.27252199999998,52.43888100000004],[-131.25558499999988,52.440269],[-131.23638900000003,52.43915600000008],[-131.23248299999995,52.43471499999998],[-131.247498,52.36582900000013],[-131.25085399999995,52.35916099999997],[-131.25836200000003,52.34777100000008],[-131.263062,52.34276600000004],[-131.30311599999993,52.332100000000025],[-131.31977799999993,52.33510600000005],[-131.330597,52.33277099999992],[-131.33248899999995,52.29361],[-131.32833900000003,52.28499599999998],[-131.3244319999999,52.280823],[-131.271393,52.27777100000009],[-131.259186,52.28416400000003],[-131.25613399999992,52.29083300000008],[-131.24832199999997,52.3022160000001],[-131.17971799999998,52.31777200000005],[-131.17193599999996,52.31944299999992],[-131.136414,52.31137800000005],[-131.09500099999997,52.28611000000012],[-131.015015,52.22554800000012],[-131.00750699999998,52.21720900000008],[-131.0052799999999,52.206657000000064],[-131.01168799999988,52.19360400000011],[-131.01556400000004,52.18776700000012],[-131.024719,52.17804700000005],[-131.030304,52.17388200000005],[-131.036407,52.17083000000014],[-131.0430599999999,52.16832699999998],[-131.11512799999997,52.168289000000016],[-131.166107,52.12554900000009],[-131.18057299999987,52.121658000000025],[-131.26473999999985,52.11971299999999],[-131.29888900000003,52.15026899999992],[-131.36025999999993,52.18915600000014],[-131.366943,52.192490000000134],[-131.38946499999997,52.20582600000006],[-131.41168200000004,52.22054300000008],[-131.55111699999998,52.333878000000084],[-131.57333399999993,52.36082499999998],[-131.58194000000003,52.379990000000134],[-131.582764,52.38526900000011],[-131.58056599999986,52.390548999999965],[-131.57778899999994,52.39360799999997],[-131.57083099999994,52.39610299999998],[-131.548065,52.40054300000003],[-131.53973399999995,52.4011000000001],[-131.52972399999993,52.400269000000094],[-131.52029400000004,52.39777400000003],[-131.561401,52.431664000000126],[-131.66168199999998,52.478324999999984],[-131.67916899999994,52.48360400000013],[-131.7094419999999,52.49110400000001],[-131.76223800000002,52.50499700000006],[-131.77529899999996,52.51166500000005],[-131.892792,52.58277100000009],[-132.01751699999994,52.677490000000034],[-132.08194000000003,52.72748599999994],[-132.084717,52.732208000000014],[-132.060272,52.75527200000005],[-132.01028399999996,52.775269000000094],[-132.002502,52.776939000000084],[-131.993042,52.77443699999998],[-131.973053,52.764717000000076],[-131.96389799999997,52.756660000000124],[-131.94445799999988,52.73554999999999],[-131.933624,52.728043000000014],[-131.92694099999994,52.724709000000075],[-131.91751099999988,52.72248799999994],[-131.91723599999995,52.72582200000011],[-131.93722499999996,52.76361100000008],[-131.93972799999995,52.768326000000116],[-131.95166,52.78110500000014],[-131.96221899999995,52.78860500000002],[-131.96887200000003,52.79193900000001],[-132.03417999999994,52.81276700000012],[-132.06167599999998,52.813881000000094],[-132.05804399999994,52.80416100000002],[-132.05557299999987,52.79361000000006],[-132.10247800000002,52.74943500000006],[-132.11026000000004,52.748046999999985],[-132.12026999999995,52.74887799999999],[-132.12747199999995,52.750832],[-132.2141719999999,52.804710000000114],[-132.219452,52.80832700000008],[-132.22888199999994,52.81638299999997],[-132.31640599999997,52.90221400000013],[-132.34414700000002,52.93166400000001],[-132.34695399999993,52.93637799999999],[-132.34304799999995,52.942214999999976],[-132.32971199999992,52.94582400000013],[-132.313629,52.94804399999998],[-132.25558499999994,52.954711999999915],[-132.24527,52.95388000000003],[-132.2380369999999,52.95193500000005],[-132.16778599999992,52.928047000000106],[-132.156403,52.958885000000066],[-132.11248799999998,52.987770000000125],[-132.11026000000004,52.99304999999998],[-132.11276199999992,52.997772000000055],[-132.11944599999998,53.00110600000005],[-132.25613399999997,53.028877000000136],[-132.26696799999996,53.030823000000055],[-132.29501300000004,53.03110500000008],[-132.41195700000003,53.03193700000003],[-132.47970599999996,53.027214000000015],[-132.4960939999999,53.03276800000003],[-132.50778199999996,53.040549999999996],[-132.51196300000004,53.04471600000005],[-132.55279499999995,53.08971400000013],[-132.55557299999992,53.09443699999997],[-132.563629,53.139160000000004],[-132.562225,53.14527100000009],[-132.55667099999994,53.14943699999998],[-132.5491639999999,53.1511000000001],[-132.5394589999999,53.14888000000008],[-132.52584799999994,53.142220000000066],[-132.50140399999998,53.13388100000003],[-132.48165899999998,53.13082099999997],[-132.45111099999986,53.1280440000001],[-132.41363499999989,53.127486999999974],[-132.378601,53.12943300000006],[-132.21081499999997,53.141662999999994],[-132.07083099999994,53.15387700000002],[-132.06390399999987,53.15638000000001],[-132.05777,53.15971400000001],[-132.030579,53.17999300000008],[-132.00750700000003,53.1947100000001],[-131.92834500000004,53.230545000000006],[-131.92138699999992,53.233047000000056],[-131.811127,53.25360899999998],[-131.80194099999994,53.253326000000015],[-131.794464,53.25138899999996],[-131.79055800000003,53.247214999999926],[-131.76223800000002,53.19665500000008]],[[-55.77805299999994,53.289719000000105],[-55.78666700000002,53.28833000000009],[-55.79444899999993,53.29110700000001],[-55.79722600000002,53.295547],[-55.793334999999956,53.300545],[-55.78500399999996,53.30360400000001],[-55.77610800000002,53.30027000000001],[-55.77638999999999,53.295273000000066],[-55.77805299999994,53.289719000000105]],[[-128.68945299999996,53.16443600000008],[-128.67944299999994,53.16304799999995],[-128.670837,53.163605000000075],[-128.652222,53.16276600000009],[-128.64196799999996,53.16137700000007],[-128.62469499999997,53.15554800000007],[-128.60555999999997,53.14527100000009],[-128.5761109999999,53.10527000000013],[-128.53167699999995,53.021102999999925],[-128.52890000000002,53.011108000000036],[-128.52056900000002,52.9594350000001],[-128.5183409999999,52.94360400000011],[-128.51779199999987,52.92748999999998],[-128.5183409999999,52.91110200000014],[-128.52002,52.89971900000012],[-128.5227969999999,52.88804600000009],[-128.57028199999996,52.69137600000005],[-128.57223499999992,52.68526500000013],[-128.57528699999995,52.679993000000024],[-128.59359699999993,52.65915699999999],[-128.58526599999988,52.6594310000001],[-128.57748400000003,52.65638000000007],[-128.5858149999999,52.6322100000001],[-128.59222399999993,52.6138840000001],[-128.5972289999999,52.609161000000086],[-128.60497999999995,52.60777300000001],[-128.74887099999995,52.59721400000012],[-128.75167799999997,52.60083000000003],[-128.74859600000002,52.74860400000006],[-128.74804699999999,52.754166],[-128.74444600000004,52.76082600000001],[-128.69250499999998,52.85610200000008],[-128.653351,52.8927690000001],[-128.648346,52.89777400000014],[-128.64474499999994,52.90416000000005],[-128.64334099999996,52.91554300000007],[-128.64196799999996,52.94860100000005],[-128.64334099999996,52.958885000000066],[-128.646973,52.963325999999995],[-128.653351,52.96665999999999],[-128.663635,52.96804800000007],[-128.67138699999998,52.96665999999999],[-128.67694099999994,52.962769000000094],[-128.67999299999997,52.95777100000009],[-128.751129,52.83582300000012],[-128.75390600000003,52.83082600000006],[-128.76223800000002,52.81082200000009],[-128.76446499999997,52.804710000000114],[-128.780579,52.73998999999998],[-128.78140299999995,52.73416099999997],[-128.77999899999998,52.72387700000013],[-128.777802,52.71888000000001],[-128.77111799999994,52.70471199999997],[-128.76556400000004,52.69554100000005],[-128.7788999999999,52.66415400000011],[-128.84637499999997,52.653320000000065],[-128.88446,52.64804800000013],[-128.89251699999994,52.64888000000002],[-129,52.69721200000009],[-129.032776,52.719711000000075],[-129.04779099999996,52.73137700000001],[-129.080292,52.772491000000116],[-129.108612,52.81276700000012],[-129.11080899999996,52.81749700000012],[-129.114441,52.821938000000046],[-129.11886600000003,52.83138300000013],[-129.12191799999994,52.852218999999934],[-129.12191799999994,52.863052000000096],[-129.11999500000002,52.869155999999975],[-129.11080899999996,52.87748700000003],[-129.10360699999995,52.87971500000003],[-129.09500100000002,52.880272000000105],[-129.08444199999997,52.87804399999993],[-129.0763849999999,52.87499200000002],[-129.02224699999988,52.905548000000124],[-128.95178199999992,52.97366000000005],[-128.86999499999996,53.02193500000004],[-128.85498,53.02526900000004],[-128.84082,53.02971600000012],[-128.83639499999998,53.03555300000005],[-128.843597,53.04415899999998],[-128.89556899999997,53.08277099999998],[-128.96389799999992,53.12165799999997],[-128.970551,53.124992000000134],[-129.00222799999995,53.13694000000004],[-129.011688,53.139717000000076],[-129.01583900000003,53.13388100000003],[-129.01501499999995,53.12887599999999],[-129.00473,53.10999300000009],[-128.99386599999997,53.097214000000065],[-128.98748799999998,53.09582500000005],[-128.98110999999994,53.09887700000013],[-128.97387700000002,53.10110500000013],[-128.96444699999995,53.100548],[-128.956665,53.09777100000014],[-128.912781,53.07305100000008],[-128.86444099999989,53.038887000000045],[-128.862213,53.03416400000009],[-129.05584699999997,52.90915699999994],[-129.06915299999991,52.90387700000008],[-129.09500100000002,52.902489],[-129.105835,52.90470899999997],[-129.15945399999998,52.919715999999994],[-129.16583299999996,52.92304999999999],[-129.169464,52.92748999999998],[-129.175293,52.93637799999999],[-129.18554700000004,52.955269000000044],[-129.18722499999996,52.96554600000002],[-129.191956,53.00777400000004],[-129.191376,53.01332900000011],[-129.18804899999992,53.0241620000001],[-129.16665599999993,53.06610100000006],[-129.16168200000004,53.0711060000001],[-129.154724,53.073326000000066],[-129.13165300000003,53.07804900000008],[-129.1180419999999,53.07916300000005],[-129.1174929999999,53.07388299999997],[-129.1180419999999,53.068329000000006],[-129.11499000000003,53.06471299999993],[-129.108612,53.067772000000105],[-129.08248899999995,53.089989],[-129.075287,53.10305000000011],[-129.073334,53.10916099999997],[-129.070557,53.131660000000124],[-129.05889899999988,53.23137700000012],[-129.06027199999988,53.241661000000136],[-129.064728,53.25110599999999],[-129.07193,53.25999500000006],[-129.08221400000002,53.2677690000001],[-129.08972199999994,53.287216000000114],[-129.086121,53.29361],[-129.07971199999997,53.29666100000003],[-129.06664999999992,53.30082700000008],[-129.04305999999997,53.30471],[-129.025848,53.305550000000096],[-129.018616,53.305550000000096],[-128.90084799999994,53.290276000000006],[-128.8913879999999,53.287773000000016],[-128.88137800000004,53.27999100000005],[-128.87777699999992,53.27582600000005],[-128.8638919999999,53.26361099999997],[-128.843597,53.24804700000004],[-128.83221399999996,53.24054699999999],[-128.77529900000002,53.20888500000001],[-128.71167000000003,53.17388200000005],[-128.7052609999999,53.17054699999994],[-128.68945299999996,53.16443600000008]],[[-129.15307599999994,53.09832800000004],[-129.16168200000004,53.09777100000014],[-129.25946,53.09804500000007],[-129.28945899999985,53.10193600000014],[-129.311401,53.11693600000007],[-129.3266599999999,53.128601],[-129.332489,53.13749700000011],[-129.33471699999996,53.142494],[-129.33639500000004,53.15277099999997],[-129.33889799999986,53.17916100000002],[-129.3383179999999,53.18499000000003],[-129.33639500000004,53.19110100000012],[-129.3252869999999,53.21610300000003],[-129.27389500000004,53.32804900000002],[-129.26806599999992,53.33194000000009],[-129.26028399999996,53.333327999999995],[-129.250854,53.33305400000006],[-129.22915599999988,53.32888000000003],[-129.22692899999998,53.32610299999993],[-129.208893,53.32193799999993],[-129.19415299999997,53.3155440000001],[-129.18112199999996,53.30860100000007],[-129.17611699999998,53.30471],[-129.16860999999994,53.29610400000013],[-129.14529399999998,53.22165700000005],[-129.132477,53.11859900000002],[-129.13192699999996,53.11360899999994],[-129.1339109999999,53.10749800000008],[-129.13891599999994,53.10249300000004],[-129.15307599999994,53.09832800000004]],[[-79.94276400000001,53.266936999999984],[-80.00917099999992,53.26388500000007],[-80.01806599999986,53.26583099999999],[-80.02444500000001,53.26888300000007],[-80.08167999999995,53.316101],[-80.08389299999999,53.32110600000004],[-80.08528100000001,53.32694200000009],[-80.07333399999999,53.34887700000007],[-80.06889299999995,53.35332500000004],[-80.06138599999991,53.35555300000004],[-79.99972499999996,53.364716000000044],[-79.94471699999997,53.36805000000004],[-79.95056199999993,53.34971600000006],[-79.95194999999995,53.34832799999998],[-79.91305499999999,53.29610400000013],[-79.91194200000001,53.29055000000011],[-79.91332999999992,53.283051000000114],[-79.92083699999995,53.273048000000074],[-79.92721599999999,53.27027099999998],[-79.94276400000001,53.266936999999984]],[[-129.358337,53.30416100000008],[-129.37442,53.301383999999985],[-129.38363600000002,53.30193300000013],[-129.3875119999999,53.30609900000002],[-129.43499799999995,53.378876000000105],[-129.43307500000003,53.38472000000013],[-129.39502,53.410819999999944],[-129.386414,53.40915700000005],[-129.3797,53.40554800000001],[-129.373871,53.40082600000011],[-129.3666379999999,53.39888000000008],[-129.32861300000002,53.377769],[-129.30557299999998,53.335823000000005],[-129.30334499999992,53.33110799999997],[-129.30749500000002,53.31888600000002],[-129.3124999999999,53.31388099999998],[-129.326935,53.3097150000001],[-129.358337,53.30416100000008]],[[-55.78750599999995,53.394157000000064],[-55.79305999999997,53.39166300000011],[-55.80139200000002,53.39249399999994],[-55.94943999999998,53.43027500000011],[-55.95805399999995,53.43415800000008],[-55.97166399999992,53.445824000000016],[-55.97888199999994,53.45471200000003],[-55.97916399999991,53.45916],[-55.97638699999999,53.463051000000064],[-55.95889299999993,53.472488],[-55.94554900000003,53.47860000000014],[-55.931670999999994,53.483879000000115],[-55.92388900000003,53.48554999999999],[-55.91638899999998,53.485825000000034],[-55.88305700000001,53.486382000000106],[-55.87805199999997,53.48665600000004],[-55.81194299999993,53.483879000000115],[-55.75722499999995,53.468323],[-55.740554999999915,53.46221200000008],[-55.72916399999997,53.4552690000001],[-55.72943900000001,53.450271999999984],[-55.78750599999995,53.394157000000064]],[[-128.94250499999998,53.317497],[-129.11138899999997,53.31582600000013],[-129.12222299999996,53.31805400000013],[-129.1258239999999,53.322495],[-129.13891599999994,53.33998900000012],[-129.14334099999996,53.34971600000006],[-129.14416499999993,53.35499600000014],[-129.14306599999986,53.36610400000012],[-129.14083899999997,53.37221500000004],[-129.13445999999993,53.383880999999974],[-129.08270299999998,53.42926],[-129.054062,53.45360199999999],[-129.05883799999998,53.487965000000145],[-129.051941,53.50499700000006],[-129.04779099999996,53.51055100000002],[-129.03778099999988,53.52027100000009],[-129.02194199999997,53.53388200000006],[-129.015289,53.536658999999986],[-128.99941999999987,53.53943600000008],[-128.988586,53.53721600000006],[-128.984711,53.53305100000006],[-128.98416099999997,53.52777100000003],[-128.98553499999997,53.52304800000002],[-128.98611499999998,53.51305400000001],[-128.98611499999998,53.502220000000136],[-128.9844359999999,53.49166100000008],[-128.97555499999987,53.472762999999986],[-128.95361300000002,53.44665500000002],[-128.94137599999993,53.43415800000008],[-128.93612699999994,53.43027500000011],[-128.90335099999993,53.39138000000014],[-128.90112299999998,53.38665800000007],[-128.90029900000002,53.38137800000004],[-128.91805999999997,53.33138300000002],[-128.92251599999997,53.325829],[-128.92807,53.321663000000115],[-128.94250499999998,53.317497]],[[-79.70973200000003,53.50804900000014],[-79.72027600000001,53.50749999999999],[-79.73055999999997,53.50888800000013],[-79.74694799999992,53.513329],[-79.76472499999994,53.52360500000009],[-79.76972999999992,53.52721400000013],[-79.77362099999999,53.5316620000001],[-79.77027899999996,53.536942000000124],[-79.76139799999993,53.54610400000007],[-79.75500499999998,53.54305300000004],[-79.70695499999988,53.51554900000002],[-79.70333899999991,53.51110800000009],[-79.70973200000003,53.50804900000014]],[[-129.93472299999985,53.48416100000003],[-129.9427799999999,53.48276499999997],[-129.95220899999998,53.483047000000056],[-130.01446499999997,53.50193800000005],[-130.02111799999994,53.50527200000005],[-129.98858599999988,53.52860300000009],[-129.94195599999995,53.55110200000007],[-129.93417399999998,53.55248999999998],[-129.92611699999992,53.55165899999997],[-129.8933409999999,53.545547],[-129.886688,53.5422210000001],[-129.88418599999994,53.53721600000006],[-129.88696300000004,53.534163999999976],[-129.894745,53.52193499999993],[-129.89889499999998,53.516388000000006],[-129.913635,53.50193800000005],[-129.92916899999994,53.48832700000008],[-129.93472299999985,53.48416100000003]],[[-129.8794249999999,53.39276899999999],[-129.72915599999993,53.21527100000009],[-129.73028599999992,53.20416300000011],[-129.73220799999996,53.198044000000095],[-129.74249299999997,53.178329000000076],[-129.7508539999999,53.16693900000001],[-129.75585899999993,53.16220900000002],[-129.76223799999997,53.15888200000006],[-129.864166,53.15304600000002],[-129.91223100000002,53.15638000000001],[-129.931671,53.15804300000008],[-129.93695099999997,53.161933999999974],[-130.0880429999999,53.28943600000014],[-130.11111500000004,53.32804900000002],[-130.16500899999988,53.35833000000014],[-130.20333899999997,53.378876000000105],[-130.24249299999997,53.38416300000006],[-130.261414,53.38472000000013],[-130.28695700000003,53.38137800000004],[-130.29638699999998,53.38166000000007],[-130.30584699999997,53.38416300000006],[-130.31640600000003,53.39193700000004],[-130.401947,53.47998800000005],[-130.527222,53.552216000000044],[-130.52999899999998,53.56777199999999],[-130.52944899999994,53.57332600000001],[-130.52224699999994,53.618599000000074],[-130.52029399999998,53.62470999999999],[-130.50836200000003,53.631935000000055],[-130.459991,53.637496999999996],[-130.450287,53.63499500000012],[-130.39584399999995,53.61943800000006],[-130.39111300000002,53.61693600000001],[-130.37554899999992,53.612213],[-130.27529900000002,53.580276000000026],[-130.20220900000004,53.55387899999994],[-130.14083900000003,53.52887700000002],[-129.97720300000003,53.45555099999996],[-129.94415299999991,53.438598999999954],[-129.93222000000003,53.43138099999999],[-129.92056300000002,53.42416400000002],[-129.88418599999994,53.397217000000126],[-129.8794249999999,53.39276899999999]],[[-129.08639500000004,53.44609799999995],[-129.15750099999997,53.39276899999999],[-129.16778599999998,53.59388000000013],[-129.16583299999996,53.61082500000009],[-129.16305499999999,53.62248999999997],[-129.16082799999998,53.62860100000006],[-129.15307599999994,53.638603000000046],[-129.14724699999994,53.64249400000011],[-129.14083899999997,53.645546000000024],[-129.05249000000003,53.681107],[-129.03860499999985,53.68637799999999],[-129.00805699999995,53.693321000000026],[-128.9833069999999,53.69665500000002],[-128.87554899999998,53.70943499999993],[-128.832764,53.712494000000106],[-128.82388299999997,53.71305100000001],[-128.81887800000004,53.70916000000011],[-128.821106,53.70304900000002],[-128.82360799999998,53.70054600000009],[-128.8722229999999,53.66110200000014],[-128.97970599999996,53.58387799999997],[-128.98638900000003,53.58082600000006],[-128.99221799999992,53.57694200000003],[-129.07556199999993,53.51471700000013],[-129.08554100000003,53.50499700000006],[-129.08999599999999,53.49943500000006],[-129.09359699999993,53.49276700000013],[-129.09414699999996,53.48721300000011],[-129.093323,53.48193400000014],[-129.08889799999997,53.472488],[-129.08526599999993,53.46804799999995],[-129.08306899999997,53.46332600000005],[-129.08221400000002,53.45832800000005],[-129.08276399999988,53.45249200000001],[-129.08639500000004,53.44609799999995]],[[-130.09109499999994,53.569443000000035],[-130.09832800000004,53.5669400000001],[-130.107758,53.567497],[-130.148621,53.5719380000001],[-130.21887199999992,53.587212000000136],[-130.22833299999996,53.58943199999999],[-130.32916299999994,53.61804999999998],[-130.34249899999998,53.62470999999999],[-130.39028899999988,53.66999100000004],[-130.403351,53.682495000000074],[-130.39111300000002,53.69943200000006],[-130.29888899999997,53.79694400000005],[-130.2836299999999,53.79833200000013],[-130.27194199999997,53.79777500000006],[-130.26168799999994,53.79638699999998],[-130.2466429999999,53.79027600000006],[-130.23330699999985,53.78360700000002],[-130.11944600000004,53.686653000000035],[-130.11721799999998,53.681938],[-130.09109499999994,53.569443000000035]],[[-56.86721799999998,53.76499899999993],[-56.94860799999998,53.75000000000006],[-56.98277300000001,53.75527199999999],[-57.01139099999989,53.78110500000014],[-57.01445000000001,53.78555300000011],[-57.01222200000001,53.79027600000006],[-57.00666799999999,53.79471600000011],[-57,53.79833200000013],[-56.98472600000002,53.80387900000011],[-56.96694200000002,53.80387900000011],[-56.86306000000002,53.7980500000001],[-56.84444400000001,53.792496000000085],[-56.84751899999998,53.78664400000014],[-56.86721799999998,53.76499899999993]],[[-129.8261109999999,53.724158999999986],[-129.59722899999997,53.550270000000125],[-129.51611300000002,53.48804500000006],[-129.42471299999994,53.411377000000016],[-129.43472299999996,53.40165699999994],[-129.45165999999995,53.37915800000002],[-129.45498699999996,53.37249000000003],[-129.47415199999995,53.28916200000003],[-129.47387700000002,53.23999000000009],[-129.50668299999995,53.216660000000104],[-129.56390399999998,53.2074970000001],[-129.72582999999992,53.34054600000002],[-129.800568,53.38054699999998],[-129.80721999999997,53.38416300000006],[-129.82223499999986,53.401382000000126],[-129.858337,53.45638300000007],[-129.87719699999997,53.50499700000006],[-129.87026999999995,53.51805100000013],[-129.86999500000002,53.53472100000005],[-129.87026999999995,53.545547],[-129.883911,53.57972000000001],[-129.91607699999992,53.60171500000001],[-129.9192349999999,53.60405000000014],[-129.924896,53.605545000000006],[-129.93022199999996,53.605213000000106],[-129.939728,53.603549999999984],[-129.94305399999985,53.601215000000025],[-129.94605999999987,53.59821699999998],[-129.945557,53.59521500000011],[-129.96139500000004,53.59471100000013],[-129.96554600000002,53.58915699999994],[-129.99941999999993,53.57471499999997],[-130.00750699999998,53.57332600000001],[-130.01611300000002,53.57276900000011],[-130.0269469999999,53.57471499999997],[-130.04028299999993,53.58138300000013],[-130.051666,53.59443700000003],[-130.05639599999995,53.60388200000011],[-130.05584699999991,53.60943600000007],[-130.051666,53.61527300000006],[-130.03085299999987,53.622765000000015],[-129.98288000000002,53.641605000000084],[-129.97805799999992,53.64243699999997],[-129.96240199999994,53.643436000000065],[-129.95622300000002,53.6427690000001],[-129.94955400000003,53.64143400000012],[-129.93505900000002,53.636272000000076],[-129.92938199999998,53.634765999999956],[-129.926895,53.636772000000065],[-129.92820699999993,53.639602999999966],[-129.93440199999992,53.644268000000125],[-129.94956999999994,53.646805000000086],[-129.95996100000002,53.64950199999993],[-129.96726999999993,53.65029900000002],[-129.98693799999995,53.65860000000009],[-130.01889,53.653046000000074],[-130.091949,53.6772160000001],[-130.156952,53.72137500000002],[-130.283905,53.83277099999998],[-130.286407,53.83749399999999],[-130.27917499999995,53.856384000000105],[-130.27029400000004,53.87554900000009],[-130.266418,53.8813780000001],[-130.25472999999994,53.88916000000006],[-130.20166,53.9124910000001],[-130.19445799999994,53.914711000000125],[-130.186401,53.916100000000085],[-130.10916099999992,53.88555100000002],[-129.96444699999995,53.80582400000009],[-129.83139,53.728043000000014],[-129.8261109999999,53.724158999999986]],[[-79.86416600000001,53.90638000000001],[-79.87388599999991,53.90415999999999],[-79.906113,53.91387900000001],[-79.91888399999999,53.920273000000066],[-79.922775,53.924713000000054],[-79.92527799999988,53.92971799999992],[-79.92639200000002,53.93526500000007],[-79.915009,53.933876000000055],[-79.86749299999997,53.919715999999994],[-79.862213,53.9158250000001],[-79.86000100000001,53.91082000000006],[-79.86416600000001,53.90638000000001]],[[-130.14974999999998,53.989159000000086],[-130.16805999999997,53.9888840000001],[-130.179169,53.990829000000076],[-130.19415300000003,53.99721499999998],[-130.20306400000004,54.005271999999934],[-130.21499600000004,54.029160000000104],[-130.21694899999994,54.03943600000014],[-130.21640000000002,54.04499800000008],[-130.21304299999997,54.05165900000003],[-130.20278899999994,54.06916000000001],[-130.193604,54.07972000000012],[-130.186401,54.081940000000145],[-130.17834500000004,54.08332800000005],[-130.16861,54.08305400000012],[-130.15917999999994,54.08055100000013],[-130.155579,54.07555400000001],[-130.14889500000004,54.072220000000016],[-130.14361599999995,54.06832899999995],[-130.13973999999996,54.064156000000025],[-130.132477,54.049995000000024],[-130.12249799999995,54.02499399999999],[-130.1213679999999,54.01998900000012],[-130.12249799999995,54.0086060000001],[-130.12442,54.00249500000007],[-130.13528399999996,53.993607000000054],[-130.14974999999998,53.989159000000086]],[[-130.25918599999994,54.00471500000003],[-130.237213,53.984161000000086],[-130.23330699999985,53.979987999999935],[-130.23083499999996,53.97526600000003],[-130.228882,53.96471400000007],[-130.22998,53.95360600000009],[-130.23330699999985,53.9469380000001],[-130.24249299999997,53.93637799999999],[-130.338593,53.839157000000114],[-130.344452,53.83526600000005],[-130.35220299999997,53.83387800000014],[-130.37860099999995,53.831939999999975],[-130.38723800000002,53.83138300000007],[-130.45016499999997,53.864326000000005],[-130.45433000000003,53.86632500000002],[-130.45849599999997,53.88215999999994],[-130.41278099999994,53.95860299999998],[-130.407776,53.963325999999995],[-130.400848,53.965828000000045],[-130.38165300000003,53.96527100000014],[-130.35055499999993,53.96166199999993],[-130.341095,53.96138000000008],[-130.3330689999999,53.962769000000094],[-130.32748400000003,53.966934000000094],[-130.34359699999987,53.98499300000003],[-130.35497999999995,53.99332400000009],[-130.42944299999994,53.98304700000011],[-130.4375,53.981659000000036],[-130.44387800000004,53.97860000000003],[-130.452789,53.96804800000007],[-130.47517400000004,53.94421399999993],[-130.47550999999993,53.940712000000076],[-130.47917199999995,53.926379999999995],[-130.48266599999988,53.915379000000144],[-130.48516799999993,53.91204800000003],[-130.4895019999999,53.910549],[-130.494659,53.910217000000046],[-130.500854,53.91088100000013],[-130.524338,53.914711000000125],[-130.54724099999999,53.90387700000002],[-130.55248999999998,53.90776799999992],[-130.55639599999995,53.91193400000003],[-130.56527699999998,53.92582700000003],[-130.57748400000003,53.93721000000005],[-130.591949,53.949158000000125],[-130.59722899999997,53.953048999999965],[-130.60278299999993,53.956657000000064],[-130.61080900000002,53.959717000000126],[-130.621918,53.96166199999993],[-130.6580509999999,53.96443900000003],[-130.666962,53.963882000000126],[-130.67251599999997,53.95999100000006],[-130.676666,53.954162999999994],[-130.69528200000002,53.91944100000012],[-130.698059,53.91415400000005],[-130.695557,53.90943100000004],[-130.6849979999999,53.901932000000045],[-130.66305499999993,53.89222000000012],[-130.64666699999998,53.886657999999954],[-130.633331,53.87999000000002],[-130.62777700000004,53.876099000000124],[-130.62249799999995,53.8722150000001],[-130.6177669999999,53.86277000000001],[-130.61804199999995,53.85721600000005],[-130.62136799999996,53.85054800000006],[-130.62554899999998,53.844711000000075],[-130.6305539999999,53.839989],[-130.64251699999994,53.83277099999998],[-130.65139799999997,53.83443500000004],[-130.69583099999994,53.84443699999997],[-130.70639,53.85193600000014],[-130.710266,53.856384000000105],[-130.71276899999998,53.86110700000012],[-130.723053,53.917213000000004],[-130.72277799999995,53.922768000000076],[-130.7202759999999,53.93471500000004],[-130.7177729999999,53.939986999999974],[-130.667236,53.98693800000001],[-130.66168200000004,53.990829000000076],[-130.595276,54.02638200000007],[-130.523346,54.059989999999914],[-130.411133,54.10083000000009],[-130.40249600000004,54.10138699999999],[-130.37081899999998,54.08721200000008],[-130.336121,54.06749700000006],[-130.3049929999999,54.04527300000012],[-130.25918599999994,54.00471500000003]],[[-58.51833299999993,54.05165900000003],[-58.52666499999992,54.05054500000006],[-58.536666999999966,54.05082700000014],[-58.54555499999998,54.0522160000001],[-58.556389000000024,54.05471000000006],[-58.56138599999997,54.05804400000005],[-58.56138599999997,54.06388099999998],[-58.55777699999993,54.06916000000001],[-58.55277999999993,54.07444000000004],[-58.53556100000003,54.08665499999995],[-58.50305899999995,54.10305000000005],[-58.468605000000025,54.114716000000044],[-58.45055400000001,54.11721],[-58.43777499999999,54.11554700000005],[-58.378608999999926,54.10665900000009],[-58.373885999999914,54.10416400000008],[-58.378052000000025,54.09999800000014],[-58.40717299999994,54.09056100000004],[-58.426109,54.070831000000055],[-58.43250299999994,54.067214999999976],[-58.44055199999997,54.0647130000001],[-58.45639,54.061661000000015],[-58.51833299999993,54.05165900000003]],[[-132.808044,54.12027000000006],[-132.78891,54.119987000000094],[-132.77999899999998,54.12082700000013],[-132.75723300000004,54.126380999999924],[-132.73580899999996,54.13388100000003],[-132.70306399999993,54.139160000000004],[-132.65835600000003,54.142220000000066],[-132.6480709999999,54.14138000000003],[-132.63946499999997,54.1386030000001],[-132.57528699999995,54.11554700000005],[-132.56973300000004,54.111938000000066],[-132.55777,54.088043000000084],[-132.558899,54.04833200000007],[-132.56054699999999,54.04222100000004],[-132.56664999999992,54.029160000000104],[-132.57583599999998,54.01915700000001],[-132.58139,54.0149990000001],[-132.59387199999998,54.0086060000001],[-132.62554899999992,54.00222000000002],[-132.63275099999993,53.99971800000014],[-132.66418499999997,53.98333000000008],[-132.67999299999997,53.958885000000066],[-132.681671,53.95277399999998],[-132.680298,53.94776900000011],[-132.6589049999999,53.93943000000007],[-132.57223499999992,53.976653999999996],[-132.55584699999997,53.989159000000086],[-132.55029299999995,53.99388099999999],[-132.5477909999999,53.99916100000007],[-132.54888899999997,54.00416600000011],[-132.55307,54.00833100000011],[-132.54833999999994,54.02693899999997],[-132.54528800000003,54.03360700000013],[-132.54055799999998,54.03832999999997],[-132.416656,54.096100000000035],[-132.40972899999997,54.098602000000085],[-132.40167199999985,54.09999800000014],[-132.30111699999998,54.11166400000013],[-132.29055800000003,54.11054999999999],[-132.28582799999998,54.107773000000066],[-132.25280799999996,54.08526599999999],[-132.22833300000002,54.065826000000015],[-132.15029899999996,53.992767000000015],[-132.142517,53.97860000000003],[-132.11111499999998,53.878326000000015],[-132.11721799999992,53.864998000000014],[-132.125,53.853324999999984],[-132.13445999999988,53.84360500000008],[-132.225006,53.78027300000002],[-132.23111,53.77693900000003],[-132.24527,53.772217000000126],[-132.474426,53.70749699999999],[-132.50500499999998,53.70027199999993],[-132.52084399999995,53.69721200000009],[-132.53805499999999,53.69582399999996],[-132.55721999999997,53.69582399999996],[-132.56832899999995,53.697768999999994],[-132.58889799999992,53.699715000000026],[-132.6069339999999,53.69887499999999],[-132.62441999999993,53.69748700000008],[-132.64724699999994,53.69193300000012],[-132.6589049999999,53.68443300000001],[-132.66332999999997,53.67943600000012],[-132.665009,53.673325000000034],[-132.46362299999993,53.61277000000007],[-132.41805999999997,53.60610200000008],[-132.32138099999992,53.66360500000013],[-132.31527699999998,53.66693900000013],[-132.308044,53.66915899999992],[-132.29943799999995,53.66999100000004],[-132.290009,53.66971600000005],[-132.27890000000002,53.6680530000001],[-132.24554399999994,53.66249099999999],[-132.156403,53.716385],[-132.15249600000004,53.81249200000008],[-132.08450299999998,53.87273800000003],[-132.106201,53.91788100000002],[-132.126373,53.979431000000034],[-132.07250999999997,54.02276600000005],[-132.0150149999999,54.02193500000004],[-131.98803699999996,54.023048000000074],[-131.97109999999998,54.02526900000004],[-131.87499999999994,54.052773],[-131.86053500000003,54.057495000000074],[-131.81777999999997,54.07193799999999],[-131.75473,54.094993999999986],[-131.727783,54.10610200000002],[-131.71499599999999,54.11249500000014],[-131.70361299999996,54.120543999999995],[-131.67193599999996,54.146660000000054],[-131.66305499999999,54.15221400000007],[-131.66000399999996,54.13110400000011],[-131.666656,54.079436999999984],[-131.67279099999996,54.04415899999998],[-131.67971799999998,54.019714000000135],[-131.70498699999996,53.966934000000094],[-131.720825,53.94387800000004],[-131.73889199999996,53.92332499999998],[-131.78640699999994,53.87443500000012],[-131.79666099999997,53.865273],[-131.82971199999992,53.841102999999976],[-131.85333300000002,53.81638299999997],[-131.86886600000003,53.79332700000009],[-131.87222299999996,53.78694200000007],[-131.93331899999998,53.61527300000006],[-131.934998,53.609161000000086],[-131.94000199999988,53.51971400000002],[-131.9391779999999,53.50888800000013],[-131.91778599999998,53.3991620000001],[-131.90863000000002,53.35749800000002],[-131.95916699999992,53.27638200000007],[-131.96832299999988,53.26638800000006],[-131.98220799999996,53.25166300000012],[-131.988586,53.248604000000114],[-132.00585899999993,53.247214999999926],[-132.036407,53.25],[-132.0561219999999,53.253326000000015],[-132.08331299999992,53.25305200000008],[-132.17138699999998,53.23832700000014],[-132.19500700000003,53.233879],[-132.21054100000003,53.230545000000006],[-132.21749899999998,53.228324999999984],[-132.27279699999997,53.21027400000003],[-132.27029399999998,53.205551000000014],[-132.26611300000002,53.20138500000013],[-132.25558499999994,53.193877999999984],[-132.23776199999998,53.188881000000094],[-132.22997999999995,53.190544000000045],[-132.21581999999995,53.195267],[-132.20361299999996,53.20165999999995],[-132.19415299999991,53.20165999999995],[-132.14502,53.19832599999995],[-132.133911,53.19665500000008],[-132.12441999999987,53.19415300000003],[-132.121918,53.189430000000016],[-132.158905,53.16999099999998],[-132.18695099999997,53.16054500000001],[-132.19473300000004,53.15888200000006],[-132.390289,53.142769000000044],[-132.40835599999997,53.142220000000066],[-132.4466549999999,53.14360799999997],[-132.457489,53.14527100000009],[-132.506958,53.161102000000085],[-132.53668199999998,53.17887900000011],[-132.56527700000004,53.21276900000004],[-132.57638499999996,53.23220800000013],[-132.58581500000003,53.24027300000006],[-132.59664899999996,53.24748999999997],[-132.61471599999993,53.252777000000094],[-132.64529399999992,53.25555399999996],[-132.664734,53.25638600000008],[-132.683624,53.25666000000001],[-132.675842,53.281661999999926],[-132.61944599999998,53.30027000000001],[-132.552216,53.308043999999995],[-132.54446399999995,53.30943300000001],[-132.539734,53.31443800000005],[-132.53695700000003,53.32110600000004],[-132.53918499999997,53.326385000000016],[-132.54333499999996,53.33055100000007],[-132.54998799999987,53.33387800000003],[-132.55835000000002,53.33665500000012],[-132.568604,53.337494000000106],[-132.67001300000004,53.32694200000009],[-132.72000100000002,53.320831],[-132.73388699999998,53.33721200000002],[-132.709991,53.370270000000005],[-132.70443699999993,53.374435000000005],[-132.6975099999999,53.376937999999996],[-132.52076699999998,53.340160000000026],[-132.51744099999996,53.337990000000104],[-132.41641200000004,53.2972180000001],[-132.41055299999994,53.294715999999994],[-132.406677,53.300545],[-132.40362500000003,53.30721299999999],[-132.40057399999995,53.31944300000009],[-132.40029900000002,53.330826000000116],[-132.402802,53.33554800000002],[-132.406677,53.33971400000007],[-132.41223099999996,53.34360499999997],[-132.52084399999995,53.41220900000013],[-132.54138199999994,53.41638200000011],[-132.73580899999996,53.45332300000001],[-132.857758,53.461104999999975],[-132.86749299999997,53.463608000000136],[-132.87277199999988,53.467209000000025],[-132.97250399999996,53.55582400000014],[-132.991669,53.583054000000004],[-132.9941409999999,53.58776900000004],[-132.9888919999999,53.59193400000004],[-132.96139500000004,53.60027300000007],[-132.95361300000002,53.60193600000002],[-132.94415300000003,53.60193600000002],[-132.93444799999986,53.599716],[-132.91805999999997,53.58860000000004],[-132.90972899999997,53.585823000000005],[-132.898621,53.584160000000054],[-132.89083900000003,53.58554800000013],[-132.88446,53.588882000000126],[-132.880829,53.59471100000013],[-132.8805539999999,53.60027300000007],[-132.88192700000002,53.605552999999986],[-132.8861389999999,53.60971799999999],[-132.92028800000003,53.63721499999991],[-132.935272,53.648604999999975],[-132.950562,53.654709000000025],[-133.00778200000002,53.676383999999985],[-132.95361300000002,53.68277000000012],[-132.95443699999998,53.70277400000003],[-132.9844359999999,53.74276700000007],[-133.02471899999995,53.751389000000074],[-133.03362999999996,53.75277699999998],[-133.09387200000003,53.77555100000012],[-133.10082999999997,53.77860300000003],[-133.10638399999993,53.7824940000001],[-133.10916099999997,53.78694200000007],[-133.13751199999996,53.87499200000002],[-133.13891599999994,53.88027200000005],[-133.140015,53.908043000000134],[-133.13833599999992,53.91415400000005],[-133.133911,53.91915900000009],[-133.11639399999996,53.93415800000014],[-133.09527599999996,53.94943200000006],[-133.09081999999995,53.954162999999994],[-133.041107,54.03166199999998],[-133.039734,54.03777300000007],[-133.04083299999996,54.0430530000001],[-133.05862399999995,54.07610299999999],[-133.079163,54.09777100000008],[-133.08193999999992,54.10249299999998],[-133.07165499999996,54.16888399999999],[-133.06722999999988,54.17388199999999],[-133.04083299999996,54.176102000000014],[-133.0311279999999,54.176102000000014],[-132.94027700000004,54.16137700000007],[-132.93029799999994,54.15915700000005],[-132.92001299999993,54.15248900000006],[-132.90335099999993,54.13582600000001],[-132.82748400000003,54.122490000000084],[-132.808044,54.12027000000006]],[[-130.19555699999995,54.11805000000004],[-130.21166999999997,54.115273000000116],[-130.22109999999998,54.11554700000005],[-130.23220799999996,54.11749300000014],[-130.24581899999993,54.12416100000013],[-130.251129,54.128044000000045],[-130.25500499999998,54.132209999999986],[-130.261414,54.14138000000003],[-130.26364099999995,54.14610299999998],[-130.26473999999996,54.151381999999955],[-130.26306199999993,54.16832700000009],[-130.2611389999999,54.174164000000076],[-130.25778199999996,54.18082400000009],[-130.2528079999999,54.1855470000001],[-130.239716,54.18971299999998],[-130.23083499999996,54.190269],[-130.20944199999985,54.18720999999999],[-130.2099909999999,54.18360100000001],[-130.20166,54.18305200000003],[-130.19223,54.18054999999998],[-130.17861900000003,54.173607000000004],[-130.161133,54.16276600000009],[-130.15585299999992,54.15888200000006],[-130.15194699999995,54.154434000000094],[-130.15112299999998,54.14943699999998],[-130.153076,54.14332600000006],[-130.158051,54.138329],[-130.169464,54.130547000000035],[-130.19555699999995,54.11805000000004]],[[-79.46972700000003,54.167496000000085],[-79.47721899999988,54.16582500000004],[-79.483612,54.169159000000036],[-79.48500100000001,54.174713],[-79.48110999999994,54.18749200000008],[-79.47555499999993,54.191376000000105],[-79.43472300000002,54.20027200000004],[-79.41305499999999,54.19165799999996],[-79.41861,54.18720999999999],[-79.42639200000002,54.18305200000003],[-79.46972700000003,54.167496000000085]],[[-130.648621,54.114441000000056],[-130.67138699999992,54.107773000000066],[-130.69055199999997,54.10833000000014],[-130.69888299999997,54.11110700000006],[-130.77417000000003,54.142220000000066],[-130.78500399999996,54.14999400000005],[-130.798065,54.16220899999996],[-130.800568,54.16693900000001],[-130.79861500000004,54.1730500000001],[-130.78167699999995,54.2116620000001],[-130.77444500000001,54.21388200000007],[-130.763916,54.21276900000004],[-130.75613399999992,54.20916],[-130.74636799999996,54.206657000000064],[-130.72582999999997,54.19665500000008],[-130.64889500000004,54.14971900000006],[-130.64501999999993,54.14527100000009],[-130.640015,54.13582600000001],[-130.63919099999993,54.13082099999997],[-130.63946499999997,54.124992000000134],[-130.642792,54.11859900000002],[-130.648621,54.114441000000056]],[[-130.3555599999999,54.25777399999998],[-130.3666379999999,54.24110400000001],[-130.375,54.244155999999975],[-130.38861099999997,54.25083200000006],[-130.400574,54.25804899999997],[-130.45556599999998,54.29583000000014],[-130.46639999999996,54.303322000000094],[-130.46722399999993,54.30860100000007],[-130.4475099999999,54.325829],[-130.440002,54.32804900000002],[-130.43112199999996,54.32860600000009],[-130.41778599999992,54.326385000000016],[-130.39196799999996,54.312492000000134],[-130.385284,54.308884000000035],[-130.37997399999995,54.30526700000007],[-130.37582399999997,54.30082700000008],[-130.35470599999996,54.26915700000001],[-130.35220299999997,54.264442000000145],[-130.3555599999999,54.25777399999998]],[[-130.266418,54.26055100000008],[-130.32528699999995,54.243050000000096],[-130.33416699999998,54.24471300000005],[-130.33804299999997,54.24887800000005],[-130.355255,54.282211000000075],[-130.354156,54.29332699999998],[-130.350281,54.30555000000004],[-130.344452,54.30971500000004],[-130.29000899999994,54.33221400000002],[-130.2727969999999,54.329720000000066],[-130.26751699999994,54.325829],[-130.25973499999998,54.317497],[-130.252502,54.30304700000005],[-130.25058,54.292770000000075],[-130.2516779999999,54.28138000000001],[-130.255585,54.269440000000145],[-130.25973499999998,54.26361099999991],[-130.266418,54.26055100000008]],[[-130.70416299999994,54.356659000000036],[-130.745544,54.35471300000012],[-130.754456,54.356102000000135],[-130.763916,54.364159000000086],[-130.767242,54.37416100000007],[-130.7683409999999,54.379433000000006],[-130.76779199999987,54.38499500000012],[-130.76446499999992,54.38943499999999],[-130.75805699999995,54.39249400000011],[-130.72943099999986,54.40277100000009],[-130.7222289999999,54.40499100000011],[-130.71417199999996,54.40638000000013],[-130.699432,54.40665400000006],[-130.68890399999998,54.39332600000006],[-130.68331899999998,54.3730470000001],[-130.685272,54.36693600000001],[-130.6894529999999,54.36138199999999],[-130.696106,54.35804700000011],[-130.70416299999994,54.356659000000036]],[[-57.32472199999995,54.49887799999999],[-57.34249899999992,54.49860400000006],[-57.35166899999996,54.5002750000001],[-57.35666699999996,54.50222000000008],[-57.36277799999999,54.50610400000011],[-57.365005,54.511664999999994],[-57.36555499999997,54.51638799999995],[-57.36250299999995,54.52748900000012],[-57.359443999999996,54.533332999999914],[-57.333327999999995,54.56554399999999],[-57.32778200000001,54.57083100000011],[-57.32111400000002,54.57499700000005],[-57.26722000000001,54.58554800000013],[-57.265556000000004,54.580551000000014],[-57.269722,54.57499700000005],[-57.27272800000003,54.57249500000012],[-57.239441,54.52221700000001],[-57.240279999999984,54.517769000000044],[-57.255004999999926,54.513329],[-57.29305999999991,54.5036090000001],[-57.30777699999999,54.500549000000035],[-57.32472199999995,54.49887799999999]],[[-130.95166,54.45471199999997],[-130.95944199999997,54.45332300000001],[-130.96499600000004,54.456940000000145],[-130.96749899999992,54.46166200000005],[-130.96609499999994,54.51082600000001],[-130.96472199999994,54.52777100000014],[-130.961121,54.53999299999998],[-130.93057299999998,54.61471599999993],[-130.92556799999994,54.61943800000006],[-130.88891599999994,54.62887600000005],[-130.88137800000004,54.62915800000013],[-130.754456,54.62943300000012],[-130.74777199999994,54.626099000000124],[-130.74664299999995,54.62082700000002],[-130.74694799999997,54.61527300000006],[-130.7441409999999,54.60166200000009],[-130.745544,54.584717000000126],[-130.74914599999994,54.57276900000005],[-130.752502,54.56610100000012],[-130.75613399999992,54.559433000000126],[-130.760834,54.554710000000114],[-130.766663,54.55054500000011],[-130.84915199999995,54.496941000000106],[-130.855835,54.493881000000044],[-130.93695099999997,54.459434999999985],[-130.95166,54.45471199999997]],[[-79.66722099999993,54.76388500000013],[-79.726944,54.75249500000007],[-79.71028100000001,54.76388500000013],[-79.70361300000002,54.76693700000004],[-79.61111499999998,54.79332700000009],[-79.58721899999995,54.79916400000002],[-79.624435,54.77971600000012],[-79.631104,54.776657000000114],[-79.63778699999995,54.77360500000003],[-79.65972899999991,54.766106000000036],[-79.66722099999993,54.76388500000013]],[[-130.2683409999999,54.714995999999985],[-130.370544,54.692214999999976],[-130.37887599999988,54.69526700000006],[-130.37609899999995,54.70054600000003],[-130.3710939999999,54.705269000000044],[-130.326935,54.739716000000044],[-130.32110599999987,54.743881000000044],[-130.2241519999999,54.80304699999999],[-130.21749899999998,54.80638099999999],[-130.20944199999985,54.80777000000012],[-130.20694000000003,54.80304699999999],[-130.19860800000004,54.78360700000002],[-130.200562,54.77748900000006],[-130.20971699999996,54.760551000000135],[-130.21362299999993,54.74832900000001],[-130.217224,54.74166100000002],[-130.22222899999986,54.73693800000001],[-130.23388699999998,54.72887400000002],[-130.2611389999999,54.71720900000014],[-130.2683409999999,54.714995999999985]],[[-130.51834099999996,54.70249200000012],[-130.527222,54.70193500000005],[-130.5386049999999,54.70388000000003],[-130.56750499999993,54.716934000000094],[-130.57443199999994,54.72026800000009],[-130.585266,54.72776799999997],[-130.60803199999992,54.74832900000001],[-130.6105349999999,54.75305200000014],[-130.61166399999996,54.758049000000085],[-130.60665900000004,54.763054000000125],[-130.4880369999999,54.80749500000013],[-130.47998,54.80888399999992],[-130.469452,54.80777000000012],[-130.458618,54.80027000000007],[-130.44665499999996,54.787216],[-130.44027699999992,54.77832799999999],[-130.43777499999993,54.77360500000003],[-130.43582199999997,54.76332900000011],[-130.4397279999999,54.75110600000005],[-130.4538879999999,54.71915400000012],[-130.457489,54.712769000000094],[-130.46331799999996,54.70860300000004],[-130.51834099999996,54.70249200000012]],[[-57.94083399999994,54.911933999999974],[-57.985832000000016,54.87082699999996],[-57.98860899999994,54.86721],[-57.991942999999935,54.833878000000084],[-57.98388699999987,54.80221599999999],[-57.98027799999994,54.79860700000012],[-57.971663999999976,54.798050000000046],[-57.965553,54.79943799999995],[-57.95889299999999,54.80304699999999],[-57.955558999999994,54.80582400000009],[-57.923888999999974,54.82332600000012],[-57.871666000000005,54.83166499999993],[-57.864723000000026,54.83221400000008],[-57.85972600000002,54.83027600000014],[-57.843613000000005,54.82054900000003],[-57.841110000000015,54.81693999999999],[-57.84166700000003,54.81249200000002],[-57.84833499999996,54.80693800000006],[-57.875,54.79332700000009],[-57.88194299999992,54.790549999999996],[-58.02277400000003,54.75555400000002],[-58.031386999999995,54.75388299999997],[-58.04000099999996,54.75277699999998],[-58.04999499999991,54.75305200000014],[-58.11999500000002,54.75555400000002],[-58.13916799999993,54.75721699999997],[-58.15943900000002,54.76138300000008],[-58.174171,54.76776899999999],[-58.17694899999998,54.77082800000011],[-58.17237899999998,54.797314000000085],[-58.184173999999985,54.80847199999994],[-58.21971899999994,54.825829000000056],[-58.22277100000002,54.83027600000014],[-58.224715999999944,54.83526599999999],[-58.225554999999986,54.850273000000016],[-58.225554999999986,54.86277000000001],[-58.22499800000003,54.86693600000007],[-58.21888699999994,54.87526700000001],[-58.215836000000024,54.8780440000001],[-58.20972399999994,54.87748700000003],[-58.04944599999993,54.893326000000116],[-57.96777300000002,54.919159000000036],[-57.94277199999999,54.92499500000014],[-57.94027699999998,54.923607000000004],[-57.93860599999999,54.918602000000135],[-57.94083399999994,54.911933999999974]],[[-79.12582399999991,54.89721700000001],[-79.13444500000003,54.895827999999995],[-79.23500099999995,54.89666000000011],[-79.51528899999994,54.840546000000074],[-79.66027799999995,54.805549999999926],[-79.76362599999999,54.771660000000054],[-79.77417000000003,54.77304800000013],[-79.776947,54.77804600000013],[-79.77333099999998,54.783333000000084],[-79.76888999999994,54.78777300000007],[-79.72555499999999,54.81888600000008],[-79.714722,54.82638500000007],[-79.68693499999995,54.83832600000005],[-79.65666199999998,54.84665699999999],[-79.46722399999993,54.888329],[-79.45861799999994,54.88999200000012],[-79.43055700000002,54.892769000000044],[-79.41944899999987,54.892769000000044],[-79.3394469999999,54.89694199999997],[-79.16416900000002,54.92555200000004],[-79.053879,54.94665500000008],[-79.04194599999988,54.94582400000007],[-79.01501499999995,54.93832400000002],[-79.01501499999995,54.932213000000104],[-79.027222,54.925270000000125],[-79.05749499999996,54.917770000000075],[-79.10278299999999,54.90387700000002],[-79.12582399999991,54.89721700000001]],[[-58.67527799999999,54.914153999999996],[-58.68360899999999,54.913048],[-58.75250199999999,54.91582500000004],[-58.757225000000005,54.916100000000085],[-58.76055899999989,54.92054699999994],[-58.75917099999998,54.92610200000007],[-58.75472300000001,54.93249500000002],[-58.70166799999993,54.999161000000015],[-58.697495,55.003326000000015],[-58.69110899999998,55.00694299999998],[-58.684722999999906,55.008331000000055],[-58.67639199999991,55.00943799999999],[-58.66027799999995,55.0086060000001],[-58.6536099999999,55.00555400000002],[-58.65277899999995,55.00110600000005],[-58.65750099999997,54.99610099999995],[-58.6627729999999,54.99221800000004],[-58.65833299999997,54.96249400000005],[-58.65666199999998,54.94221500000009],[-58.65860700000002,54.93249500000002],[-58.663054999999986,54.92249300000003],[-58.66889200000003,54.917770000000075],[-58.67527799999999,54.914153999999996]],[[-130.385284,54.76998899999995],[-130.39916999999997,54.76471700000002],[-130.40918,54.767212000000086],[-130.41445899999997,54.77082800000011],[-130.45556599999998,54.81332400000014],[-130.45944199999997,54.81749700000006],[-130.46194499999996,54.82222000000007],[-130.459991,54.82833099999999],[-130.41833499999996,54.85332499999993],[-130.385284,54.8688810000001],[-130.343048,54.89499699999999],[-130.27029400000004,54.95027200000004],[-130.25,54.96971100000013],[-130.22778299999993,54.99721499999998],[-130.2133179999999,55.012496999999996],[-130.20083599999992,55.01971400000008],[-130.184998,55.02332300000012],[-130.175293,55.023048000000074],[-130.168335,55.01971400000008],[-130.16500899999988,55.01416000000012],[-130.16027799999995,55.00443999999999],[-130.146973,54.97582200000005],[-130.14529399999998,54.96527100000014],[-130.14556899999997,54.959717000000126],[-130.14611799999994,54.95416300000011],[-130.14974999999998,54.947487000000024],[-130.16332999999997,54.931381000000044],[-130.27029400000004,54.830826],[-130.385284,54.76998899999995]],[[-82.964722,55.26361100000008],[-82.97000099999997,55.259720000000016],[-83.01445000000001,55.26971400000002],[-83.03195199999988,55.27388000000013],[-83.035278,55.27887700000002],[-83.02749599999993,55.28138000000001],[-83.016953,55.2816620000001],[-82.99027999999998,55.280548000000124],[-82.98083500000001,55.27887700000002],[-82.96333299999998,55.27388000000013],[-82.96166999999997,55.26915700000012],[-82.964722,55.26361100000008]],[[-77.59277299999991,55.43526500000013],[-77.633331,55.42443800000012],[-77.64416499999987,55.42582700000008],[-77.44943199999994,55.53388200000006],[-77.33612099999999,55.60443900000013],[-77.32305899999994,55.610550000000046],[-77.22138999999993,55.65360299999992],[-77.21389799999992,55.65526600000004],[-77.20527600000003,55.65387700000008],[-77.19999699999994,55.65026899999998],[-77.20111099999991,55.64415699999995],[-77.210556,55.63971700000013],[-77.25222799999995,55.618050000000096],[-77.38917499999997,55.54638699999998],[-77.45222499999994,55.5127720000001],[-77.47416699999997,55.49804699999993],[-77.48416099999992,55.48915899999997],[-77.49499499999996,55.48137700000001],[-77.50056499999994,55.4783250000001],[-77.55221599999993,55.45304900000002],[-77.59277299999991,55.43526500000013]],[[-60.970832999999914,55.869437999999946],[-60.98833499999995,55.86721],[-60.99833699999999,55.86776700000007],[-61.008895999999936,55.86915600000009],[-61.016944999999964,55.873046999999985],[-61.05166600000001,55.9011000000001],[-61.05666400000001,55.905823000000055],[-61.05916599999995,55.909988000000055],[-61.07055700000001,55.93859900000001],[-61.06555199999997,55.94415300000003],[-61.04778299999998,55.945541000000105],[-61.03694899999999,55.9447100000001],[-60.96805599999999,55.93665299999992],[-60.94860799999998,55.93054999999998],[-60.90833299999997,55.898330999999985],[-60.906386999999995,55.893326000000116],[-60.91110999999995,55.8877720000001],[-60.91750300000001,55.884163000000115],[-60.970832999999914,55.869437999999946]],[[-60.858611999999994,55.864716000000044],[-60.87610599999999,55.863883999999985],[-60.89250199999998,55.864441000000056],[-60.898612999999955,55.86721],[-60.902221999999995,55.87137600000011],[-60.90055100000001,55.87638099999998],[-60.87361099999987,55.94360400000005],[-60.86999500000002,55.949432],[-60.86500499999994,55.95277400000009],[-60.851944,55.95526899999993],[-60.748336999999935,55.94415300000003],[-60.74138599999992,55.94276400000001],[-60.74250000000001,55.93915600000008],[-60.74749800000001,55.931663999999955],[-60.691939999999875,55.925270000000125],[-60.68638599999997,55.92193600000013],[-60.68804899999998,55.91721300000012],[-60.69277199999999,55.911658999999986],[-60.70500199999998,55.90304600000002],[-60.71860499999991,55.896385000000066],[-60.756393,55.88027200000005],[-60.778610000000015,55.87609900000007],[-60.840836000000024,55.86610399999995],[-60.858611999999994,55.864716000000044]],[[-79.12304699999993,55.78999300000004],[-79.13055399999996,55.788887000000045],[-79.135559,55.78916200000003],[-79.13778699999995,55.79054999999994],[-79.13612399999994,55.79415899999998],[-79.13166799999993,55.799995000000024],[-79.12609900000001,55.80387900000005],[-79.12193299999996,55.808601000000124],[-79.10888699999992,55.82388300000014],[-79.10278299999999,55.83305400000012],[-79.03916899999996,55.95249200000006],[-79.03083799999996,55.96859699999993],[-79.027222,55.97693599999997],[-79.02223200000003,55.99638400000009],[-79.00935399999997,56.063614000000086],[-78.96000700000002,56.08305400000006],[-78.95750399999997,56.08360299999998],[-78.95278899999994,56.080826000000116],[-78.9491579999999,56.071663000000115],[-78.93971299999998,56.02526899999998],[-79.05444299999994,55.86554700000005],[-79.08999599999999,55.81693999999999],[-79.104446,55.80082700000014],[-79.11665299999999,55.79249600000003],[-79.12304699999993,55.78999300000004]],[[-60.943329000000006,56.00666000000001],[-61.040557999999976,56.005272000000105],[-61.0819469999999,56.01138299999997],[-61.14138799999995,56.02054599999997],[-61.17111199999988,56.028602999999976],[-61.18721800000003,56.03388200000012],[-61.215836000000024,56.04638700000004],[-61.22083299999997,56.05082700000008],[-61.22833300000002,56.06332400000008],[-61.23277299999995,56.07276900000011],[-61.233611999999994,56.08554800000002],[-61.23277299999995,56.09110300000009],[-61.226944,56.09804500000001],[-61.217498999999975,56.10054799999995],[-61.21167000000003,56.1013870000001],[-61.08916499999998,56.169991000000095],[-61.05916599999995,56.15971400000012],[-61.04583699999989,56.153877000000136],[-60.94444299999998,56.094993999999986],[-60.943610999999976,56.09027100000014],[-60.93444099999999,56.015830999999935],[-60.93472299999996,56.01138299999997],[-60.943329000000006,56.00666000000001]],[[-61.62361099999998,56.39999399999999],[-61.54666899999995,56.39083099999999],[-61.49305700000002,56.40499100000005],[-61.48277300000001,56.406654],[-61.474716,56.406654],[-61.46832999999992,56.40443399999998],[-61.41527599999995,56.376656000000025],[-61.41166700000002,56.372214999999926],[-61.41110999999995,56.36721000000006],[-61.412216,56.32665999999995],[-61.416106999999954,56.32222000000013],[-61.424171,56.32027400000004],[-61.48277300000001,56.30999000000003],[-61.569449999999904,56.320549000000085],[-61.57972699999999,56.32249499999995],[-61.599723999999924,56.32777399999992],[-61.68638599999986,56.35277600000006],[-61.719993999999986,56.36582900000002],[-61.788895000000025,56.405823],[-61.79333500000001,56.40888200000012],[-61.79611199999994,56.41304800000006],[-61.79055799999992,56.41582499999993],[-61.78388999999987,56.41582499999993],[-61.67777999999993,56.405548000000124],[-61.62361099999998,56.39999399999999]],[[-78.83999599999993,56.12999000000008],[-78.92749000000003,56.1138840000001],[-78.93331899999998,56.11554700000005],[-78.93055699999996,56.12860100000012],[-78.916946,56.172493000000145],[-78.9083399999999,56.18249500000013],[-78.90388499999995,56.18720999999999],[-78.883331,56.201935000000105],[-78.84638999999999,56.2347180000001],[-78.83029199999993,56.25332600000013],[-78.825287,56.2627720000001],[-78.81332399999997,56.30470999999994],[-78.80943299999996,56.338882000000126],[-78.81388899999996,56.343323000000055],[-78.83473200000003,56.34554300000002],[-78.83250399999991,56.35082999999997],[-78.76251200000002,56.42471300000011],[-78.75140399999992,56.432495000000074],[-78.73167399999994,56.4405440000001],[-78.69499200000001,56.4438780000001],[-78.68638599999991,56.44332099999997],[-78.66722099999998,56.4397130000001],[-78.66166699999997,56.43610400000006],[-78.66000399999996,56.430550000000096],[-78.65083299999992,56.289161999999976],[-78.65278599999994,56.24193600000007],[-78.65556300000003,56.22360200000014],[-78.67639200000002,56.181107],[-78.68859900000001,56.17276799999996],[-78.83999599999993,56.12999000000008]],[[-79.626938,56.26527399999998],[-79.63583399999999,56.26499899999999],[-79.63667299999997,56.266388000000006],[-79.63639799999987,56.26915700000012],[-79.60943600000002,56.31971699999997],[-79.53860500000002,56.433051999999975],[-79.53443900000002,56.43749199999996],[-79.52389499999998,56.44276400000007],[-79.51112399999994,56.44638100000003],[-79.49694799999997,56.44860100000005],[-79.49221799999992,56.44693799999993],[-79.49055499999992,56.44082600000013],[-79.51083399999993,56.397491],[-79.55776999999989,56.305267000000015],[-79.56111099999993,56.299164000000076],[-79.56555200000003,56.29388400000005],[-79.569458,56.28999299999998],[-79.61944599999987,56.26721199999997],[-79.626938,56.26527399999998]],[[-79.61999500000002,56.385268999999994],[-79.63806199999999,56.360550000000046],[-79.64944499999996,56.346382000000006],[-79.66332999999997,56.33387800000014],[-79.68249500000002,56.317496999999946],[-79.70111099999997,56.306381000000044],[-79.714447,56.29999500000008],[-79.90666199999993,56.227211000000125],[-79.92832899999996,56.219711000000075],[-79.98611499999998,56.19971500000008],[-80.01916499999993,56.19137600000005],[-80.06054699999999,56.18443300000007],[-80.08250399999991,56.18665300000009],[-80.09222399999999,56.18832400000014],[-80.10055499999999,56.19137600000005],[-80.10749799999991,56.19499200000013],[-80.10972600000002,56.197768999999994],[-80.110275,56.20332300000001],[-80.100281,56.23915899999997],[-80.09861799999987,56.24415600000009],[-80.05526700000001,56.30360400000012],[-80.04444899999993,56.310822000000144],[-80.04055800000003,56.31276700000012],[-80.02250699999996,56.31971699999997],[-79.86749299999997,56.357498000000135],[-79.79554699999994,56.366661000000136],[-79.75666799999999,56.36193799999995],[-79.72444200000001,56.36277000000007],[-79.69888299999991,56.36888099999999],[-79.679169,56.378326000000015],[-79.656387,56.3927690000001],[-79.64250199999998,56.40443399999998],[-79.61888099999993,56.426941000000056],[-79.614441,56.43166400000007],[-79.60417199999995,56.444153000000085],[-79.59805299999994,56.4544370000001],[-79.59138499999995,56.46915400000012],[-79.58833300000003,56.493881000000044],[-79.58528100000001,56.49916100000007],[-79.58250399999991,56.50166300000001],[-79.54972800000002,56.52526900000004],[-79.54333499999996,56.52777100000014],[-79.54277000000002,56.522217000000126],[-79.54943800000001,56.508049000000085],[-79.61389199999996,56.39527099999998],[-79.61999500000002,56.385268999999994]],[[-61.43582900000001,56.54138200000011],[-61.16805999999997,56.47470900000002],[-61.14999399999999,56.44554099999999],[-61.14888799999994,56.441101],[-61.15444200000002,56.43859900000007],[-61.163612,56.436653000000035],[-61.181945999999925,56.43526500000013],[-61.200278999999966,56.43526500000013],[-61.22083299999997,56.435546999999985],[-61.517501999999865,56.44693799999993],[-61.60916900000001,56.46166199999999],[-61.63055399999996,56.46527099999997],[-61.64222699999999,56.48638200000005],[-61.63722199999995,56.489716000000044],[-61.629997,56.49054700000005],[-61.54639400000002,56.48804499999994],[-61.538612,56.48582499999998],[-61.525832999999864,56.47887400000002],[-61.512778999999966,56.4749910000001],[-61.43804899999992,56.47637900000001],[-61.42305799999997,56.4791560000001],[-61.417778,56.48333000000014],[-61.41833500000001,56.48832700000003],[-61.42250100000001,56.49054700000005],[-61.455276000000026,56.49638399999998],[-61.496666000000005,56.50000000000006],[-61.52722199999994,56.50166300000001],[-61.624168,56.50388299999997],[-61.633331,56.506386000000134],[-61.63444500000003,56.51249700000005],[-61.63194299999998,56.51638800000012],[-61.602225999999916,56.55277300000006],[-61.59583299999997,56.55638099999999],[-61.58833299999998,56.55804400000005],[-61.576667999999984,56.55776999999995],[-61.56166799999994,56.554161000000136],[-61.558051999999975,56.55193300000002],[-61.52594799999997,56.550212999999985],[-61.45916699999992,56.54583000000008],[-61.43582900000001,56.54138200000011]],[[-79.02166699999992,56.426941000000056],[-79.00944500000003,56.426383999999985],[-78.98832699999997,56.426941000000056],[-78.9491579999999,56.43082400000003],[-78.94305400000002,56.430550000000096],[-78.93582200000003,56.428878999999995],[-78.92887899999994,56.42582700000008],[-78.92471299999994,56.419441000000006],[-78.922775,56.415268000000026],[-78.921112,56.409714000000065],[-78.92054699999994,56.40332000000001],[-78.92304999999993,56.386940000000095],[-78.93638599999997,56.317496999999946],[-78.94332899999995,56.284996000000035],[-78.94999699999994,56.282493999999986],[-78.95527600000003,56.27915999999999],[-78.96139499999987,56.27137800000003],[-79.02917499999995,56.172493000000145],[-79.06138599999997,56.124435000000005],[-79.07167099999998,56.104996000000085],[-79.08500700000002,56.07749200000012],[-79.09416199999998,56.05499300000014],[-79.12999000000002,55.98943299999996],[-79.17527799999993,55.92332499999992],[-79.19526699999994,55.8919370000001],[-79.20361300000002,55.89415700000012],[-79.166267,55.973881000000006],[-79.122116,56.046715000000006],[-79.061935,56.14860500000003],[-79.02278100000001,56.20249200000001],[-79.008896,56.22165699999994],[-78.99082900000002,56.261664999999994],[-78.98582499999998,56.27360500000009],[-78.97277799999995,56.30665600000003],[-78.97027599999996,56.31415600000008],[-78.96777299999991,56.323608000000036],[-78.9661099999999,56.33610500000003],[-78.97027599999996,56.37804399999999],[-78.97084000000001,56.3836060000001],[-78.97721899999999,56.38860299999999],[-78.98332199999999,56.38971699999996],[-78.99888599999991,56.384163],[-79.04333499999996,56.360550000000046],[-79.05526700000001,56.34443700000003],[-79.06221,56.32972000000001],[-79.08917200000002,56.267769000000044],[-79.09110999999996,56.26305400000001],[-79.09306299999997,56.25694300000009],[-79.09294899999998,56.231716000000006],[-79.09544399999999,56.2190480000001],[-79.09394800000001,56.21371799999997],[-79.092781,56.21155199999998],[-79.08911099999995,56.21188400000011],[-79.083328,56.17416400000002],[-79.212784,55.95416300000011],[-79.23611499999993,55.917496000000085],[-79.25944499999991,55.88610800000009],[-79.275284,55.87027000000006],[-79.28332499999999,55.864441000000056],[-79.28666699999985,55.86666100000008],[-79.28611799999999,55.869987000000094],[-79.27806099999992,55.88555100000002],[-79.26722699999993,55.90304600000002],[-79.22666899999996,55.96249399999999],[-79.18360899999993,56.03749799999997],[-79.13999899999993,56.115273000000116],[-79.133896,56.12665600000008],[-79.132721,56.17577000000006],[-79.13856499999986,56.2052690000001],[-79.139725,56.20776699999999],[-79.14356199999997,56.21126600000014],[-79.15055799999999,56.233047],[-79.160553,56.231377000000066],[-79.17027299999995,56.225548],[-79.20556599999998,56.190826000000015],[-79.24388099999999,56.15110000000004],[-79.256393,56.13110400000005],[-79.27084400000001,56.10471299999995],[-79.27749599999999,56.090828000000045],[-79.28416400000003,56.07804900000002],[-79.29972799999996,56.05165899999997],[-79.30915800000002,56.03638500000011],[-79.32362399999994,56.016936999999984],[-79.35861199999994,55.97443400000009],[-79.45249899999999,55.879990000000134],[-79.47999600000003,55.863883999999985],[-79.49305699999996,55.85888700000004],[-79.500565,55.85665900000009],[-79.510559,55.85555300000004],[-79.52027900000002,55.854713000000004],[-79.53250099999997,55.85499600000014],[-79.56777999999997,55.864716000000044],[-79.59388699999994,55.87443500000006],[-79.60499600000003,55.881660000000124],[-79.78195199999999,55.78804800000006],[-79.76306199999993,55.814156000000025],[-79.59805299999994,55.98165899999998],[-79.48693799999995,56.08721200000002],[-79.474716,56.09832799999998],[-79.47027599999996,56.10443900000001],[-79.470551,56.112770000000125],[-79.47250400000001,56.11693600000001],[-79.478882,56.12332200000009],[-79.49722299999996,56.133605999999986],[-79.51306199999999,56.13499500000012],[-79.523056,56.133880999999974],[-79.537216,56.12971500000009],[-79.55027799999993,56.12332200000009],[-79.56750499999998,56.112770000000125],[-79.59722899999997,56.09137700000002],[-79.64500399999997,56.050545],[-79.81945799999994,55.9011000000001],[-79.83168,55.88999200000012],[-79.84666399999998,55.87416100000013],[-79.858047,55.85999300000009],[-79.86389200000002,55.85083000000009],[-79.86582900000002,55.84721400000001],[-79.90916400000003,55.840546000000074],[-79.98582499999998,55.89804800000002],[-79.96194499999996,55.96027400000003],[-79.77444499999996,56.112213000000054],[-79.66805999999991,56.18998700000003],[-79.64862099999999,56.198326000000066],[-79.64222699999999,56.20138500000007],[-79.587784,56.23027000000013],[-79.53633099999996,56.295052000000055],[-79.52683999999999,56.304214000000115],[-79.51617399999998,56.319881000000066],[-79.49466699999999,56.36721400000005],[-79.48733500000003,56.40271400000012],[-79.45889299999988,56.464157],[-79.45861799999994,56.46832300000011],[-79.45861799999994,56.478600000000085],[-79.46610999999996,56.498878000000104],[-79.47444199999995,56.52110299999998],[-79.47138999999993,56.54444100000006],[-79.46610999999996,56.54833200000013],[-79.45666499999999,56.55332199999998],[-79.44888300000002,56.55443599999995],[-79.445267,56.553604000000064],[-79.44193999999987,56.55138400000004],[-79.43859900000001,56.54777500000006],[-79.41833499999996,56.490829000000076],[-79.41944899999987,56.44360399999994],[-79.44300099999998,56.39343600000001],[-79.47499800000003,56.32043800000014],[-79.531387,56.206940000000145],[-79.51445000000001,56.18637800000005],[-79.46167000000003,56.193321000000026],[-79.43888900000002,56.19721200000009],[-79.42721599999999,56.20304900000008],[-79.41639700000002,56.21221200000008],[-79.41305499999999,56.21666000000005],[-79.30999800000001,56.42416399999996],[-79.30110199999996,56.447212000000036],[-79.29804999999993,56.4594350000001],[-79.29333500000001,56.48804499999994],[-79.291672,56.498878000000104],[-79.28639199999992,56.57027399999998],[-79.13999899999993,56.54638699999998],[-79.13305700000001,56.54277000000002],[-79.12999000000002,56.53777300000007],[-79.12554899999998,56.51415999999995],[-79.12193299999996,56.49554399999994],[-79.11999500000002,56.48998999999998],[-79.11193800000001,56.47526600000009],[-79.09999099999999,56.46305100000001],[-79.09138499999989,56.4544370000001],[-79.07556199999993,56.444153000000085],[-79.05555700000002,56.43387600000011],[-79.03889500000002,56.428878999999995],[-79.02166699999992,56.426941000000056]],[[-79.14195299999994,56.61666100000008],[-79.15194699999995,56.61638600000009],[-79.26000999999997,56.6280440000001],[-79.26889,56.629158000000075],[-79.274719,56.632209999999986],[-79.27749599999999,56.637215000000026],[-79.27999899999998,56.64888000000013],[-79.28028899999998,56.654990999999995],[-79.27500900000001,56.667213000000004],[-79.27194199999997,56.67193600000013],[-79.25472999999988,56.67999300000014],[-79.24415599999992,56.68249500000002],[-79.21888699999994,56.68499000000003],[-79.20889299999999,56.683876000000055],[-79.19360399999994,56.67832900000013],[-79.16000400000001,56.65776800000009],[-79.15110800000002,56.649994000000106],[-79.14167800000001,56.635826000000066],[-79.13806199999999,56.626099000000124],[-79.13890100000003,56.619986999999924],[-79.14195299999994,56.61666100000008]],[[-61.1875,56.586104999999975],[-61.21167000000003,56.58166499999999],[-61.217498999999975,56.58277099999998],[-61.222770999999966,56.58888200000007],[-61.231667000000016,56.61166399999996],[-61.231941000000006,56.61971299999999],[-61.22610499999996,56.626656000000025],[-61.165832999999964,56.684433000000126],[-61.15916399999992,56.68832400000002],[-61.15027600000002,56.68943000000007],[-61.13194299999998,56.68721000000005],[-61.0819469999999,56.67887899999994],[-61.0777819999999,56.67499500000014],[-61.05777699999999,56.62887599999999],[-61.05944099999999,56.62638099999998],[-61.06361400000003,56.62416099999996],[-61.10388899999987,56.60665899999992],[-61.1875,56.586104999999975]],[[-79.56082199999997,56.61776700000013],[-79.56750499999998,56.615273],[-79.57333399999999,56.6188810000001],[-79.583618,56.64804800000002],[-79.58389299999993,56.65277100000003],[-79.58999599999999,56.768326],[-79.5875089999999,56.78888699999999],[-79.58167999999995,56.80721299999999],[-79.57833900000003,56.81249200000002],[-79.57417299999986,56.81582599999996],[-79.56750499999998,56.81777200000005],[-79.51666299999994,56.78555300000005],[-79.49638400000003,56.766936999999984],[-79.47694399999995,56.72165700000005],[-79.474716,56.68915600000014],[-79.48611499999998,56.658043000000134],[-79.48889199999996,56.65554800000007],[-79.56082199999997,56.61776700000013]],[[-79.88194299999998,56.743607000000054],[-79.88861099999997,56.741104000000064],[-79.90472399999999,56.741661000000136],[-79.92388900000003,56.75138900000002],[-79.93083199999995,56.75499700000012],[-79.941101,56.76361099999997],[-79.94444299999992,56.7677690000001],[-79.94749499999995,56.77332300000012],[-79.95722999999992,56.79916400000002],[-79.95889299999993,56.80526700000013],[-79.958618,56.81137799999999],[-79.95472699999993,56.82360799999992],[-79.945831,56.83360300000004],[-79.91915899999992,56.85833000000014],[-79.915009,56.86138200000005],[-79.86582900000002,56.86610400000012],[-79.858047,56.86582900000013],[-79.843887,56.85833000000014],[-79.83444199999991,56.85249299999998],[-79.81945799999994,56.84027100000003],[-79.81639100000001,56.83554800000002],[-79.81471299999993,56.829162999999994],[-79.81361400000003,56.81693999999999],[-79.83389299999999,56.79361],[-79.83805799999999,56.78888699999999],[-79.8722229999999,56.75222000000002],[-79.87666300000001,56.747772000000055],[-79.88194299999998,56.743607000000054]],[[-79.75056499999994,56.905823000000055],[-79.71749899999992,56.81360599999999],[-79.71833799999996,56.80721299999999],[-79.72111499999988,56.802773],[-79.72555499999999,56.79804999999999],[-79.73083499999996,56.79415899999992],[-79.74972500000001,56.78360700000013],[-79.75750700000003,56.78193699999997],[-79.781113,56.784721000000104],[-79.78832999999986,56.78582800000004],[-79.79355599999997,56.79579200000006],[-79.79437300000001,56.832947000000104],[-79.79314399999998,56.859890000000064],[-79.82376899999997,56.89500399999997],[-79.852753,56.885204000000044],[-79.89416499999987,56.88193500000011],[-79.89750699999996,56.884995],[-79.89805599999994,56.891106000000036],[-79.896118,56.897217000000126],[-79.89277600000003,56.90248900000006],[-79.85861199999994,56.93859900000001],[-79.85194399999995,56.940268999999944],[-79.80833399999995,56.94832600000012],[-79.79943800000001,56.949431999999945],[-79.79083300000002,56.94776900000005],[-79.78416400000003,56.94082600000007],[-79.75361599999997,56.91082],[-79.75056499999994,56.905823000000055]],[[-61.42921100000001,56.92970700000001],[-61.397204999999985,56.927715000000035],[-61.37261199999989,56.930972999999994],[-61.35488899999996,56.93639799999994],[-61.34331900000001,56.93422700000008],[-61.340785999999866,56.930248000000006],[-61.355278,56.91082],[-61.40027599999996,56.88472000000013],[-61.40471600000001,56.87971500000009],[-61.39944499999996,56.87582400000002],[-61.378052000000025,56.87165800000014],[-61.360282999999924,56.86610400000012],[-61.35222599999997,56.857773000000066],[-61.355834999999956,56.85277600000012],[-61.361670999999944,56.84804500000001],[-61.375831999999946,56.84054600000002],[-61.4431689999999,56.817719000000125],[-61.48966999999999,56.80754900000011],[-61.563331999999946,56.784721000000104],[-61.57028199999991,56.78166199999998],[-61.576949999999954,56.778046000000074],[-61.585556,56.76638800000006],[-61.58499899999998,56.76138300000002],[-61.58277899999996,56.75666000000001],[-61.57556199999999,56.75305200000008],[-61.56472000000002,56.75166300000012],[-61.55583199999995,56.752777000000094],[-61.540839999999946,56.75777399999998],[-61.526664999999866,56.76527400000009],[-61.51528200000001,56.77471200000008],[-61.497653999999955,56.78694200000001],[-61.48897599999992,56.78929500000004],[-61.476315,56.79019900000003],[-61.43400200000002,56.7836880000001],[-61.39331399999992,56.77898800000003],[-61.386626999999976,56.775913],[-61.38210700000002,56.7713930000001],[-61.373965999999996,56.74390800000009],[-61.36872499999998,56.695988],[-61.36863299999999,56.6857720000001],[-61.37080400000002,56.67528200000004],[-61.378399,56.63260700000001],[-61.37911999999994,56.626820000000066],[-61.39358900000002,56.61777900000004],[-61.40913799999993,56.61560800000001],[-61.44421799999998,56.61958700000008],[-61.48400099999998,56.64164700000009],[-61.52197599999994,56.66985700000009],[-61.56103499999995,56.68251399999997],[-61.588157999999964,56.70385399999998],[-61.60533499999997,56.713798999999995],[-61.63535300000001,56.73151800000005],[-61.64439399999998,56.734775999999954],[-61.64403199999987,56.73802900000004],[-61.634991000000014,56.770939],[-61.624866,56.82591200000013],[-61.63209899999998,56.85954700000008],[-61.58869899999996,56.89353900000009],[-61.534812999999986,56.901859],[-61.522517999999934,56.9148790000001],[-61.5261339999999,56.93332300000009],[-61.52396399999992,56.94019300000008],[-61.499371,56.952849999999955],[-61.47369400000002,56.95900000000006],[-61.46067399999998,56.955021000000045],[-61.446571000000006,56.935131000000126],[-61.42921100000001,56.92970700000001]],[[-76.62110899999993,57.075554000000125],[-76.64695699999999,57.073050999999964],[-76.660278,57.075829],[-76.67138699999992,57.083327999999995],[-76.67555199999993,57.087769000000094],[-76.681107,57.09777100000002],[-76.70973200000003,57.18221300000005],[-76.70861799999994,57.18832400000008],[-76.67832900000002,57.205269000000044],[-76.66999800000002,57.20249199999995],[-76.66749600000003,57.19554100000005],[-76.62609900000001,57.1427690000001],[-76.61888099999999,57.080276000000026],[-76.62110899999993,57.075554000000125]],[[-61.621666000000005,57.33554800000013],[-61.611114999999984,57.334991],[-61.60555999999991,57.33554800000013],[-61.59444399999995,57.33416],[-61.589995999999985,57.33027599999997],[-61.58943899999991,57.32527200000004],[-61.59194199999996,57.321380999999974],[-61.608337000000006,57.30832700000008],[-61.652221999999995,57.290549999999996],[-61.658051,57.29027600000006],[-61.73472599999997,57.29027600000006],[-61.739998000000014,57.29193900000001],[-61.75333399999994,57.30249000000009],[-61.76361799999995,57.31166100000007],[-61.76666299999994,57.315269],[-61.767776000000026,57.31971699999997],[-61.768607999999915,57.324996999999996],[-61.76750199999998,57.32833099999999],[-61.752228,57.360275],[-61.74888599999997,57.365546999999935],[-61.74500299999994,57.369155999999975],[-61.726944,57.37443500000012],[-61.70249899999999,57.37276500000013],[-61.693329000000006,57.368050000000096],[-61.67749799999996,57.35721600000005],[-61.63221699999991,57.33776900000004],[-61.621666000000005,57.33554800000013]],[[-76.715012,57.29277000000002],[-76.72972099999987,57.28971899999999],[-76.73472600000002,57.29138200000011],[-76.74027999999998,57.29444100000006],[-76.74444599999998,57.29943800000001],[-76.79305999999997,57.374709999999936],[-76.82194499999991,57.419715999999994],[-76.823624,57.42471300000011],[-76.82167099999998,57.42943600000007],[-76.81277499999993,57.42832900000013],[-76.78443900000002,57.41693900000007],[-76.76139799999999,57.40387700000008],[-76.73554999999999,57.38638300000014],[-76.73110999999994,57.381935],[-76.72555499999999,57.37276500000013],[-76.72111499999994,57.35665899999998],[-76.708054,57.29583000000008],[-76.715012,57.29277000000002]],[[-61.65527300000002,57.39138000000008],[-61.675003000000004,57.38999200000001],[-61.839721999999995,57.408043000000134],[-61.860000999999954,57.4124910000001],[-61.87749499999995,57.41860200000002],[-61.88999899999999,57.42610200000007],[-61.89444699999996,57.42971799999998],[-61.89778099999995,57.43332700000013],[-61.90027599999996,57.437492000000134],[-61.89749899999998,57.444153000000085],[-61.81300399999992,57.47370900000004],[-61.772738999999945,57.495097999999984],[-61.742774999999995,57.53499599999998],[-61.73722099999998,57.53694200000007],[-61.719993999999986,57.536384999999996],[-61.648056,57.530272999999966],[-61.64389,57.52276600000005],[-61.634727,57.509438000000046],[-61.61361699999998,57.41610000000014],[-61.615279999999984,57.40915700000011],[-61.634170999999924,57.39888000000013],[-61.64833799999997,57.39360800000003],[-61.65527300000002,57.39138000000008]],[[-61.878333999999995,57.46305099999995],[-61.92694899999998,57.45249200000012],[-61.93749999999994,57.45304900000002],[-61.94694500000003,57.454994],[-61.95583299999993,57.45804600000008],[-61.96277600000002,57.46221200000002],[-62.01250499999992,57.50833100000011],[-62.021942000000024,57.521102999999925],[-62.02305599999994,57.53416400000003],[-62.020279000000016,57.54027600000006],[-62.01445000000001,57.54943800000012],[-61.99250000000001,57.56916000000001],[-61.97499799999997,57.58138300000007],[-61.968886999999995,57.584434999999985],[-61.953056000000004,57.59027100000003],[-61.94444299999998,57.5908280000001],[-61.878052000000025,57.584991],[-61.855002999999954,57.58055100000013],[-61.833327999999995,57.57444000000004],[-61.817504999999926,57.56721500000003],[-61.78361499999994,57.55054500000006],[-61.781386999999995,57.548050000000046],[-61.778885,57.543883999999935],[-61.77694699999995,57.52388000000002],[-61.77777899999995,57.51832600000006],[-61.779441999999904,57.513611000000026],[-61.78305799999987,57.50833100000011],[-61.864165999999955,57.466385000000116],[-61.878333999999995,57.46305099999995]],[[-79.79750100000001,57.41888400000005],[-79.80166600000001,57.4158250000001],[-79.80555699999996,57.41805300000004],[-79.83583099999998,57.460274000000084],[-79.8269499999999,57.53804800000006],[-79.80888399999998,57.561661000000015],[-79.79276999999996,57.57888000000008],[-79.74916099999996,57.60971800000004],[-79.74082899999996,57.615547000000106],[-79.73416099999992,57.618881000000044],[-79.72778299999993,57.61721],[-79.723053,57.61277000000001],[-79.70611600000001,57.585548000000074],[-79.70666499999993,57.580826],[-79.70472699999999,57.57666000000006],[-79.69860799999998,57.56332400000014],[-79.695831,57.53166199999998],[-79.69860799999998,57.51998900000012],[-79.70500199999992,57.50860599999993],[-79.71250899999995,57.50054899999998],[-79.79750100000001,57.41888400000005]],[[-61.688605999999936,57.71305100000012],[-61.69610599999993,57.712212000000136],[-61.757506999999976,57.71554600000013],[-61.76889,57.71693400000004],[-61.89416499999999,57.754166000000055],[-61.896950000000004,57.758331000000055],[-61.89611099999996,57.76971400000008],[-61.891669999999976,57.77916000000005],[-61.865837,57.799721000000034],[-61.853614999999934,57.80832700000013],[-61.80889099999996,57.83693699999998],[-61.800551999999925,57.84137700000002],[-61.778885,57.84526800000009],[-61.773056,57.84554300000008],[-61.71111300000001,57.83416000000011],[-61.69860799999992,57.83027600000008],[-61.653610000000015,57.784721000000104],[-61.652221999999995,57.78249400000004],[-61.65166499999992,57.77943399999998],[-61.65249599999993,57.77582600000005],[-61.654166999999916,57.771103000000096],[-61.66860999999989,57.73888400000004],[-61.674171,57.72693600000002],[-61.684440999999936,57.7149960000001],[-61.688605999999936,57.71305100000012]],[[-61.94749499999995,57.787216000000114],[-61.957222,57.78694200000001],[-62.08916499999998,57.808043999999995],[-62.100280999999995,57.816101],[-62.108337000000006,57.824715000000026],[-62.109443999999996,57.8294370000001],[-62.10805499999992,57.837769000000094],[-62.099723999999924,57.84638200000006],[-62.09444399999995,57.85054799999995],[-62.065276999999924,57.87054400000011],[-62.028884999999946,57.89276899999999],[-62.009170999999924,57.90443400000004],[-61.995003,57.90915700000005],[-61.986114999999984,57.91027100000002],[-61.971663999999976,57.911377000000016],[-61.94110899999998,57.909988000000055],[-61.92833699999994,57.90859999999992],[-61.923332000000016,57.90609699999999],[-61.91889199999997,57.90248900000006],[-61.88444499999997,57.86693600000001],[-61.86777499999988,57.84276600000004],[-61.86777499999988,57.8386000000001],[-61.87943999999993,57.816666],[-61.88194299999992,57.81276700000001],[-61.88555899999989,57.80915799999997],[-61.88999899999999,57.8063810000001],[-61.94083399999994,57.78888699999999],[-61.94749499999995,57.787216000000114]],[[-77.67832899999996,58.23554999999993],[-77.68777499999993,58.235268000000076],[-77.702789,58.2388840000001],[-77.76112399999994,58.257499999999936],[-77.94638099999992,58.3211060000001],[-77.95083599999992,58.32416500000005],[-77.947495,58.32860599999998],[-77.94055199999997,58.330551000000014],[-77.93249500000002,58.33138300000007],[-77.91731299999992,58.32936900000004],[-77.82972699999993,58.31137800000005],[-77.80749499999996,58.305267000000015],[-77.80139200000002,58.30304699999999],[-77.702789,58.26027700000003],[-77.689438,58.25388299999997],[-77.67027300000001,58.24415600000003],[-77.66833499999996,58.24193600000007],[-77.66833499999996,58.24054700000005],[-77.67832899999996,58.23554999999993]],[[-67.596115,58.28416400000009],[-67.61639400000001,58.28416400000009],[-67.63778699999995,58.28472099999999],[-67.66610699999995,58.29277000000002],[-67.67388899999992,58.296104000000014],[-67.67666600000001,58.30138400000004],[-67.67582700000003,58.306099000000074],[-67.672775,58.31220999999999],[-67.624435,58.368050000000096],[-67.61999499999996,58.3722150000001],[-67.61082499999992,58.37387799999999],[-67.59916699999991,58.373046999999985],[-67.58056599999998,58.369986999999924],[-67.527222,58.34360500000008],[-67.52084400000001,58.339989],[-67.51750199999998,58.33526600000005],[-67.51916499999993,58.32971999999995],[-67.52444500000001,58.32416500000005],[-67.55110200000001,58.30221599999999],[-67.55722000000003,58.298050000000046],[-67.57167099999987,58.290833000000134],[-67.596115,58.28416400000009]],[[-78.453888,58.53999300000004],[-78.45556599999986,58.537215999999944],[-78.46333299999998,58.53749800000003],[-78.474716,58.541382000000056],[-78.64999399999994,58.60138699999999],[-78.67250100000001,58.61054999999999],[-78.68388400000003,58.62082700000013],[-78.697495,58.678329000000076],[-78.69860799999998,58.68859900000001],[-78.69694499999997,58.69054399999999],[-78.69276400000001,58.691933000000006],[-78.665009,58.67499500000008],[-78.65916399999998,58.669991000000095],[-78.63528400000001,58.61859899999996],[-78.63194299999998,58.616386000000034],[-78.62805199999997,58.61415899999997],[-78.56639100000001,58.58610499999992],[-78.51306199999993,58.56388099999998],[-78.45722999999998,58.54277000000013],[-78.453888,58.53999300000004]],[[-69.19444299999992,59.06471299999998],[-69.18638599999997,59.064437999999996],[-69.18083199999995,59.06721500000009],[-69.1783289999999,59.02971599999995],[-69.22721899999993,58.97193100000004],[-69.32028199999996,58.94638100000009],[-69.32749899999999,58.94499200000007],[-69.33889799999997,58.944435],[-69.350281,58.94638100000009],[-69.35555999999997,58.94971500000008],[-69.36000099999995,58.95860300000004],[-69.35722399999997,58.96471400000013],[-69.31834400000002,59.02555099999995],[-69.319458,59.09804500000013],[-69.35305799999998,59.1272130000001],[-69.35777300000001,59.13499500000006],[-69.35722399999997,59.13971700000013],[-69.34555099999994,59.14471400000008],[-69.339447,59.14610300000004],[-69.28222700000003,59.15443399999998],[-69.27528399999994,59.15499100000005],[-69.19860799999992,59.14527099999998],[-69.18638599999997,59.138329000000056],[-69.18249499999996,59.128601],[-69.19499199999996,59.09415400000006],[-69.199997,59.07721700000002],[-69.20056199999988,59.07249500000012],[-69.19860799999992,59.06721500000009],[-69.19444299999992,59.06471299999998]],[[-80.53443900000002,59.369438],[-80.54415899999998,59.365547000000106],[-80.55221599999987,59.36582900000013],[-80.55583200000001,59.369438],[-80.54943799999995,59.446938000000046],[-80.53750600000001,59.45526899999999],[-80.48805199999998,59.477486000000056],[-80.47555499999993,59.48110200000008],[-80.46501199999994,59.463882000000126],[-80.47138999999993,59.45499400000011],[-80.47721899999993,59.451103000000046],[-80.52084400000001,59.38276700000006],[-80.52528399999994,59.377486999999974],[-80.53443900000002,59.369438]],[[-80.27749599999999,59.61859900000013],[-80.31916799999999,59.612213000000054],[-80.32972699999999,59.61249500000014],[-80.34056099999992,59.61415899999997],[-80.343887,59.61915600000003],[-80.34083599999997,59.62526700000012],[-80.29527300000001,59.67832900000002],[-80.23277300000001,59.725265999999976],[-80.22222899999986,59.72360200000014],[-80.17138699999992,59.71527100000009],[-80.15417500000001,59.709991],[-80.14527899999996,59.70555099999996],[-80.15472399999993,59.68249500000013],[-80.15666199999998,59.67832900000002],[-80.170547,59.67388199999999],[-80.20584099999996,59.66526799999991],[-80.22277799999989,59.66027100000002],[-80.22972099999998,59.65638000000013],[-80.23306300000002,59.65110000000004],[-80.237213,59.63943499999999],[-80.24055499999986,59.63416300000006],[-80.24638400000003,59.62999000000008],[-80.26083399999999,59.623604],[-80.27749599999999,59.61859900000013]],[[-64.01972999999992,59.71471399999996],[-64.12416099999996,59.695267000000115],[-64.13417099999998,59.69554100000005],[-64.146118,59.69665500000002],[-64.15722699999998,59.69971500000008],[-64.16332999999986,59.70360599999998],[-64.20445299999994,59.73443600000002],[-64.19249000000002,59.76554900000002],[-64.12193300000001,59.849433999999974],[-64.11582899999996,59.85277600000006],[-64.10722399999997,59.854996000000085],[-64.06750499999993,59.86388400000004],[-64.06138599999991,59.86444099999994],[-64.05277999999998,59.859992999999974],[-64.04972799999996,59.85527000000002],[-64.04777499999994,59.849433999999974],[-64.05526699999996,59.835266000000104],[-64.05444299999999,59.82943700000004],[-64.0427699999999,59.78388200000006],[-64.0202789999999,59.78110499999997],[-64.00279199999994,59.77471200000002],[-63.95972399999994,59.75638600000002],[-63.95944199999997,59.752220000000136],[-63.99722300000002,59.72360200000014],[-64.01139799999987,59.71638500000006],[-64.01972999999992,59.71471399999996]],[[-80.08972199999994,59.75193800000005],[-80.166946,59.742493000000024],[-80.17777999999998,59.74415600000009],[-80.18415800000002,59.747772],[-80.18472299999996,59.75277700000004],[-80.12887599999999,59.82388300000008],[-80.11500499999994,59.83776900000004],[-80.10305799999998,59.8449940000001],[-80.015015,59.88499500000012],[-80.00778200000002,59.88610799999998],[-79.94694499999991,59.880272000000105],[-79.93777499999993,59.877768999999944],[-79.92999299999991,59.87360399999994],[-79.88417099999992,59.85833000000008],[-79.87887599999999,59.85471300000012],[-79.883621,59.849998000000085],[-79.90666199999993,59.828049000000135],[-79.92222600000002,59.815544000000045],[-79.92805499999997,59.81166100000007],[-80.02528399999994,59.76444200000009],[-80.08972199999994,59.75193800000005]],[[-64.42767300000003,60.37293200000005],[-64.452789,60.357215999999994],[-64.4427639999999,60.3097150000001],[-64.43832399999997,60.305550000000096],[-64.42361499999998,60.28249400000004],[-64.42944299999994,60.28193699999997],[-64.43804899999986,60.28249400000004],[-64.44860799999998,60.28416400000003],[-64.50111400000003,60.30193300000013],[-64.52171299999998,60.310730000000035],[-64.54110699999995,60.32444000000004],[-64.55721999999992,60.33138300000002],[-64.60194399999989,60.350273000000016],[-64.61000100000001,60.353606999999954],[-64.63221699999991,60.35749800000002],[-64.64388999999994,60.357773000000066],[-64.65556299999997,60.35749800000002],[-64.66610700000001,60.35694099999995],[-64.67555199999998,60.355270000000075],[-64.71000700000002,60.35833000000014],[-64.728882,60.36332700000008],[-64.79028299999993,60.39110600000009],[-64.81555200000003,60.40609699999999],[-64.83111600000001,60.419159000000036],[-64.86749299999991,60.45027200000004],[-64.868607,60.45332300000007],[-64.86805699999996,60.45888500000001],[-64.85611,60.473877000000016],[-64.84722899999997,60.47887400000013],[-64.837784,60.48249100000004],[-64.82305899999994,60.48526800000013],[-64.63999899999999,60.4847180000001],[-64.61860699999994,60.47721100000001],[-64.42694099999994,60.401381999999955],[-64.42388900000003,60.397216999999955],[-64.42250100000001,60.3919370000001],[-64.42388900000003,60.383049000000085],[-64.42767300000003,60.37293200000005]],[[-68.25140399999998,60.23082000000005],[-68.31054699999999,60.22304500000013],[-68.34028599999999,60.22332],[-68.36193799999995,60.22582200000005],[-68.376938,60.232491000000095],[-68.38722200000001,60.240829000000076],[-68.39306599999998,60.24916100000007],[-68.39472999999998,60.254440000000045],[-68.39500399999997,60.25999500000012],[-68.39306599999998,60.27610000000004],[-68.38417099999992,60.29972100000009],[-68.37777699999998,60.310272],[-68.314438,60.39027399999998],[-68.17527799999999,60.53443900000002],[-68.12943999999993,60.570549000000085],[-68.11915599999992,60.577217000000076],[-68.09222399999999,60.581665000000044],[-68.08167999999995,60.58249699999999],[-68.03527799999995,60.58110799999997],[-67.999435,60.57749200000012],[-67.95666499999999,60.56610099999995],[-67.94860799999992,60.56137799999999],[-67.88722199999995,60.50388300000009],[-67.862213,60.48804500000006],[-67.839722,60.47804300000007],[-67.83139,60.47499099999999],[-67.821396,60.472488],[-67.80804399999994,60.467209000000025],[-67.80305499999997,60.463051000000064],[-67.79861499999987,60.4574970000001],[-67.79499800000002,60.44776900000005],[-67.79554699999994,60.443877999999984],[-67.79861499999987,60.432213000000104],[-67.806107,60.417496000000085],[-67.81527699999992,60.40804300000008],[-67.83639499999992,60.3886030000001],[-67.841385,60.3844380000001],[-67.85333300000002,60.37526699999995],[-67.885559,60.353606999999954],[-67.898056,60.34526799999992],[-67.93443300000001,60.321662999999944],[-67.96528599999999,60.30832700000002],[-67.97222899999997,60.30582400000003],[-68.16749600000003,60.24554400000011],[-68.17721599999993,60.24304999999998],[-68.20527600000003,60.23804500000011],[-68.25140399999998,60.23082000000005]],[[-64.68998699999992,60.5844350000001],[-64.69722000000002,60.58221400000002],[-64.70445299999994,60.58249699999999],[-64.71278399999994,60.59027100000014],[-64.71389799999992,60.59526800000009],[-64.71305799999988,60.59887700000007],[-64.71083099999998,60.60277600000012],[-64.61555499999986,60.68166400000007],[-64.61027499999994,60.68526500000013],[-64.59916699999997,60.68943000000013],[-64.59277299999991,60.68554700000004],[-64.59083599999997,60.67665900000003],[-64.59249899999998,60.66693900000013],[-64.593887,60.6483310000001],[-64.59584000000001,60.64527100000004],[-64.620544,60.61666100000002],[-64.63166799999999,60.60833000000008],[-64.63806199999993,60.604996000000085],[-64.68998699999992,60.5844350000001]],[[-78.656387,60.70277400000003],[-78.66471899999999,60.70221700000013],[-78.67416399999996,60.70471199999997],[-78.68998699999997,60.71221200000008],[-78.69471699999991,60.71666000000005],[-78.69833399999999,60.72165699999994],[-78.69776899999994,60.72415900000004],[-78.61639399999996,60.7719350000001],[-78.573624,60.78416399999992],[-78.39999399999999,60.80999000000003],[-78.22389199999998,60.83082600000006],[-78.21945199999999,60.82388300000002],[-78.21916199999998,60.81749700000012],[-78.221115,60.81415600000008],[-78.22666900000002,60.80888399999998],[-78.277222,60.76915700000012],[-78.28500400000001,60.76610600000009],[-78.39723199999992,60.743881000000044],[-78.62332200000003,60.70555100000013],[-78.656387,60.70277400000003]],[[-69.97721899999999,60.933051999999975],[-69.98388699999998,60.93110699999994],[-69.99526999999995,60.9313810000001],[-70.00361599999997,60.93526500000007],[-70.00778199999996,60.93915599999997],[-70.02610799999997,60.99582700000008],[-70.02500899999995,61.001937999999996],[-70.02166699999987,61.008605999999986],[-70.016663,61.013611000000026],[-70.00917099999987,61.01776899999999],[-70.00334199999992,61.02082800000011],[-69.9827729999999,61.02832799999999],[-69.964722,61.03276800000003],[-69.95417799999996,61.033882000000006],[-69.943604,61.03138000000013],[-69.93138099999993,61.02027100000004],[-69.92999299999985,61.01666300000011],[-69.92971799999992,61.01082599999995],[-69.93083200000001,61.00471500000009],[-69.93388399999992,60.9980470000001],[-69.97721899999999,60.933051999999975]],[[-64.72389199999992,61.53833000000003],[-64.71665999999999,61.53582799999998],[-64.706955,61.536658999999986],[-64.68832399999991,61.53555299999999],[-64.68331899999987,61.531105000000025],[-64.67527799999999,61.50860600000004],[-64.67416400000002,61.50332599999996],[-64.686935,61.46582799999999],[-64.70527600000003,61.44415300000014],[-64.715012,61.43332700000008],[-64.82055700000001,61.355270000000075],[-64.86694299999999,61.324164999999994],[-64.87083399999995,61.32249500000006],[-64.87527499999999,61.32249500000006],[-64.88722200000001,61.324715000000026],[-64.97250399999996,61.34415400000012],[-64.97749299999992,61.34777100000008],[-64.98500099999995,61.36749300000014],[-65.17916899999994,61.46693399999998],[-65.18582200000003,61.47554800000006],[-65.18749999999994,61.48027000000013],[-65.19055200000003,61.494995000000074],[-65.195267,61.49916099999996],[-65.2952729999999,61.52887700000002],[-65.329453,61.531937000000084],[-65.35333300000002,61.53472100000005],[-65.37249799999995,61.53721600000006],[-65.381104,61.54055000000005],[-65.47444200000001,61.58693699999998],[-65.48110999999989,61.590828000000045],[-65.48777799999993,61.599433999999974],[-65.48693800000001,61.61082500000009],[-65.48500099999995,61.62193300000007],[-65.48222399999997,61.62860100000006],[-65.47222899999986,61.64027400000009],[-65.46640000000002,61.644997000000046],[-65.45944199999985,61.64916200000005],[-65.45306399999998,61.6519320000001],[-65.44915800000001,61.653602999999976],[-65.44137599999993,61.656654],[-65.43582200000003,61.65804300000002],[-65.33972199999994,61.670547000000056],[-65.24749800000001,61.68082400000003],[-65.17443800000001,61.68693500000012],[-65.06834399999997,61.69304700000009],[-65.03639199999992,61.69360399999999],[-65.01888999999989,61.69249000000002],[-65.01611299999996,61.692214999999976],[-64.99499499999996,61.68998700000003],[-64.73306299999996,61.659988],[-64.71916199999998,61.65804300000002],[-64.64639299999993,61.60388200000011],[-64.646118,61.599716],[-64.65083300000003,61.59443700000003],[-64.65972899999997,61.58804299999997],[-64.662781,61.58776900000004],[-64.71417200000002,61.556381000000044],[-64.72027599999996,61.55138399999993],[-64.72610499999996,61.54222099999993],[-64.72389199999992,61.53833000000003]],[[-65.69526699999989,61.776657],[-65.71945199999999,61.754166],[-65.80305499999992,61.755554000000075],[-65.82722499999994,61.758049000000085],[-65.891388,61.76638800000012],[-65.903885,61.76832600000006],[-65.931107,61.778328000000045],[-65.93916300000001,61.78221099999996],[-65.94444299999998,61.785828000000095],[-65.94804399999992,61.79027600000006],[-65.94749499999989,61.796104000000014],[-65.94387799999993,61.79972099999998],[-65.81834400000002,61.860825000000034],[-65.80943299999996,61.86332700000014],[-65.78999299999998,61.865547000000106],[-65.77806099999987,61.865547000000106],[-65.76750199999998,61.86277000000001],[-65.718613,61.841102999999976],[-65.71472199999994,61.83693700000009],[-65.71362299999998,61.82416500000011],[-65.69526699999989,61.776657]],[[-92.96389799999997,61.879158000000075],[-92.99527,61.85110500000013],[-93.00167799999997,61.847214000000065],[-93.05194099999994,61.82943700000004],[-93.07028200000002,61.82527200000004],[-93.07972699999999,61.826941999999974],[-93.08666999999991,61.82943700000004],[-93.11582899999996,61.860275],[-93.12027,61.86444100000011],[-93.12693799999988,61.868599000000074],[-93.13583399999999,61.872489999999914],[-93.14805599999994,61.87582400000008],[-93.17971799999992,61.87554900000009],[-93.189438,61.874161000000015],[-93.21112099999993,61.87526700000001],[-93.218887,61.87943300000012],[-93.22332799999998,61.888329000000056],[-93.22610500000002,61.90832500000005],[-93.22361799999993,61.913048],[-93.218887,61.91888400000005],[-93.20944199999991,61.92110400000007],[-93.07250999999991,61.92999300000014],[-93.06221,61.93055000000004],[-92.96945199999999,61.888329000000056],[-92.962784,61.884162999999944],[-92.96389799999997,61.879158000000075]],[[-64.91610699999995,61.719437000000084],[-64.92694099999994,61.71888000000001],[-64.95195000000001,61.72248800000011],[-65.14805599999994,61.78054800000007],[-65.15666199999993,61.78388200000006],[-65.21055599999988,61.816940000000045],[-65.21472199999988,61.821938000000046],[-65.25195300000001,61.86971300000005],[-65.25584399999997,61.88555100000008],[-65.25500499999993,61.90165700000006],[-65.249435,61.91027100000008],[-65.24527,61.914711000000125],[-65.18971299999998,61.94554099999999],[-65.17027300000001,61.94776900000011],[-65.15695199999988,61.9469380000001],[-65.08029199999993,61.93110700000011],[-65.07444800000002,61.92832900000013],[-65.06806899999998,61.92388200000005],[-65.03916900000002,61.89971900000012],[-64.98083499999996,61.885826000000066],[-64.89334100000002,61.82999400000011],[-64.88694800000002,61.82555400000007],[-64.82888799999989,61.766662999999994],[-64.82583599999998,61.76193999999998],[-64.825287,61.758331],[-64.82888799999989,61.75222000000008],[-64.83555599999994,61.74887799999999],[-64.85804699999994,61.73915899999997],[-64.88944999999995,61.72582200000011],[-64.90611299999995,61.721100000000035],[-64.91610699999995,61.719437000000084]],[[-65.85249299999992,62.08471700000001],[-65.86915599999992,62.07972000000012],[-65.88999899999999,62.08055100000013],[-65.91332999999997,62.084990999999945],[-66.00973499999998,62.11666100000008],[-66.016663,62.120543999999995],[-66.02027900000002,62.12443500000006],[-66.021118,62.12832600000013],[-66.02084399999995,62.131660000000124],[-66.01472499999994,62.136658000000125],[-65.99194299999994,62.14138000000003],[-65.92805499999997,62.151657],[-65.904449,62.15277100000014],[-65.85360700000001,62.13110400000011],[-65.84500099999991,62.124992000000134],[-65.83555599999994,62.115272999999945],[-65.83583099999993,62.099716000000114],[-65.843887,62.088599999999985],[-65.85249299999992,62.08471700000001]],[[-92.22361799999993,62.355552999999986],[-92.306107,62.35166199999992],[-92.339722,62.35471299999995],[-92.34973100000002,62.356659000000036],[-92.37193299999996,62.386939999999925],[-92.37249800000001,62.39193700000004],[-92.35444599999994,62.410820000000115],[-92.34777799999995,62.41443600000002],[-92.31945799999994,62.41526800000008],[-92.30833399999995,62.41443600000002],[-92.162216,62.402214000000015],[-92.139725,62.399719000000005],[-92.1411129999999,62.394714000000135],[-92.15834000000001,62.390549000000135],[-92.22361799999993,62.355552999999986]],[[-79.54055800000003,62.41110200000003],[-79.44999699999994,62.382767],[-79.44276400000001,62.37999000000008],[-79.43388399999998,62.371376000000055],[-79.42916899999994,62.361664000000076],[-79.42721599999999,62.356102000000135],[-79.42443800000001,62.34415400000012],[-79.42054699999994,62.33998900000012],[-79.35916099999997,62.29610400000007],[-79.34722899999991,62.28888699999999],[-79.32861300000002,62.28333299999997],[-79.27278099999995,62.26221500000008],[-79.26611299999996,62.25804899999997],[-79.26083399999999,62.25360899999998],[-79.256393,62.244438],[-79.25556899999992,62.23971599999993],[-79.26139799999993,62.16360500000002],[-79.26222200000001,62.15888200000006],[-79.32972699999999,62.01527400000009],[-79.353882,61.99971800000014],[-79.39639299999993,61.968879999999956],[-79.45722999999992,61.89388300000002],[-79.46194499999996,61.88166000000001],[-79.46556099999992,61.876099000000124],[-79.52444500000001,61.811378000000104],[-79.54132099999993,61.79978900000009],[-79.55277999999993,61.79638699999998],[-79.56834400000002,61.79027600000006],[-79.583618,61.783051],[-79.59666400000003,61.77443699999998],[-79.60526999999996,61.76527399999998],[-79.61111499999998,61.7544400000001],[-79.61277799999999,61.74276700000007],[-79.61193800000001,61.738045],[-79.60833699999995,61.732208000000014],[-79.60611,61.72665400000005],[-79.60555999999997,61.721100000000035],[-79.60749800000002,61.70888500000012],[-79.62887599999993,61.66915899999998],[-79.63221699999997,61.66499300000004],[-79.64222699999999,61.655823],[-79.65695199999999,61.64249400000011],[-79.74082899999996,61.5886000000001],[-79.75389100000001,61.580276000000026],[-79.76139799999993,61.57694200000003],[-79.779449,61.5719380000001],[-79.8058319999999,61.568054000000075],[-79.82778899999994,61.566666],[-79.84611499999994,61.56999200000001],[-79.87110899999999,61.60971799999999],[-79.95417800000001,61.683601000000124],[-80.06806899999998,61.74527000000006],[-80.079453,61.74777200000011],[-80.09222399999999,61.74804699999993],[-80.13861099999991,61.74860400000006],[-80.16194199999995,61.74860400000006],[-80.17332499999998,61.7502750000001],[-80.19166599999988,61.755554000000075],[-80.20527600000003,61.7627720000001],[-80.275284,61.80665600000003],[-80.27806099999998,61.810272000000055],[-80.27888499999995,61.81638299999997],[-80.29138199999994,61.92999300000014],[-80.29527300000001,61.983604000000014],[-80.26861600000001,62.107215999999994],[-80.266663,62.11138200000005],[-80.19860799999998,62.1988750000001],[-80.18028300000003,62.21749100000011],[-80.01750199999998,62.358604000000014],[-80.00944500000003,62.36249500000008],[-79.98138399999993,62.37416100000007],[-79.94722000000002,62.386108000000036],[-79.93804899999998,62.388603000000046],[-79.91972399999997,62.393051000000014],[-79.900284,62.39582800000011],[-79.84277299999991,62.40360300000003],[-79.83361799999994,62.404160000000104],[-79.73083499999996,62.3991620000001],[-79.60555999999997,62.41304800000006],[-79.58416699999998,62.41721300000006],[-79.56193499999989,62.41721300000006],[-79.54055800000003,62.41110200000003]],[[-92.41111799999993,62.39388300000013],[-92.42054699999994,62.39166300000011],[-92.43138099999999,62.39166300000011],[-92.44082599999996,62.393608000000086],[-92.52917500000001,62.37832600000007],[-92.53944399999995,62.37721299999998],[-92.56138599999991,62.37748699999992],[-92.58389299999999,62.37999000000008],[-92.59583999999995,62.38249199999996],[-92.60055499999999,62.386939999999925],[-92.600281,62.39249400000011],[-92.59695399999993,62.39777400000003],[-92.59277299999997,62.40248900000006],[-92.53999299999998,62.42832900000002],[-92.53111299999995,62.43138099999993],[-92.410278,62.408882000000006],[-92.40388499999995,62.404709000000025],[-92.40556300000003,62.39943699999992],[-92.41111799999993,62.39388300000013]],[[-64.65388499999995,62.54083300000002],[-64.58084099999996,62.538605000000075],[-64.55972299999996,62.55416100000002],[-64.55999800000001,62.55860100000001],[-64.55555699999996,62.560822000000144],[-64.54972799999996,62.56221000000005],[-64.39750699999996,62.53638500000005],[-64.389725,62.53388200000006],[-64.38528400000001,62.53110500000014],[-64.382767,62.525825999999995],[-64.382767,62.51138300000014],[-64.39416499999993,62.46137999999996],[-64.47721899999999,62.40804300000002],[-64.52860999999996,62.38665800000007],[-64.59056099999998,62.367210000000114],[-64.59889199999998,62.36638599999998],[-64.65361000000001,62.37249000000003],[-64.77278100000001,62.38638300000002],[-64.87110899999999,62.40638000000013],[-64.92666600000001,62.41832700000009],[-64.93721,62.42110399999996],[-64.945831,62.42443800000012],[-64.95249899999988,62.42832900000002],[-64.95388799999995,62.43138099999993],[-64.96583599999991,62.46582799999993],[-64.846115,62.555267000000015],[-64.81555200000003,62.55971499999998],[-64.79750099999995,62.561378000000104],[-64.766953,62.56276700000012],[-64.75306699999999,62.56249200000008],[-64.741669,62.560822000000144],[-64.65388499999995,62.54083300000002]],[[-78.00834700000001,62.59360500000008],[-77.86721799999998,62.589157000000114],[-77.85055499999999,62.58277100000004],[-77.84167499999995,62.56805400000002],[-77.837784,62.556938000000116],[-77.84083599999991,62.54999500000008],[-77.84472699999998,62.54471600000011],[-77.85278299999999,62.541664000000026],[-77.86221299999994,62.53943600000008],[-77.87304699999999,62.53777300000013],[-77.88500999999997,62.53749800000014],[-77.91305499999993,62.53943600000008],[-78.10333300000002,62.55915800000008],[-78.11305199999993,62.56221000000005],[-78.11444099999994,62.570549000000085],[-78.11166400000002,62.578049000000135],[-78.10777299999995,62.58277100000004],[-78.10583500000001,62.58332800000011],[-78.0475009999999,62.59193400000004],[-78.03083800000002,62.593323000000055],[-78.01916499999999,62.59193400000004],[-78.00834700000001,62.59360500000008]],[[-77.80526700000001,62.59249100000011],[-77.72721899999993,62.58582299999995],[-77.6658329999999,62.586655000000064],[-77.62805200000003,62.58832600000011],[-77.62138400000003,62.58443500000004],[-77.637787,62.57083100000011],[-77.65110800000002,62.563881000000094],[-77.65916400000003,62.560822000000144],[-77.73472599999997,62.53582799999998],[-77.74527,62.534163999999976],[-77.75862099999989,62.53555300000011],[-77.78028899999993,62.539161999999976],[-77.80860899999993,62.546660999999915],[-77.81361399999997,62.551102000000014],[-77.83111600000001,62.59027100000009],[-77.83167999999995,62.595825000000104],[-77.821121,62.59609999999992],[-77.80943300000001,62.59415400000006],[-77.80526700000001,62.59249100000011]],[[-64.98306300000002,62.52804600000002],[-65.00723299999993,62.52638200000001],[-65.09638999999999,62.534996000000035],[-65.11972000000003,62.53749800000014],[-65.13194299999998,62.53971900000005],[-65.13806199999999,62.542770000000075],[-65.14167799999996,62.54694400000011],[-65.137787,62.55054499999994],[-65.02250700000002,62.5949940000001],[-65.00306699999993,62.598877000000016],[-64.97250399999996,62.602493000000095],[-64.90916399999998,62.60443899999996],[-64.89250199999998,62.598877000000016],[-64.88473499999992,62.59415400000006],[-64.84388699999994,62.58277100000004],[-64.839447,62.57777399999992],[-64.86082499999986,62.561378000000104],[-64.866104,62.55804400000011],[-64.874435,62.55470999999994],[-64.96528599999988,62.53138000000001],[-64.972778,62.52971600000001],[-64.98306300000002,62.52804600000002]],[[-91.57278399999996,62.62748700000009],[-91.57861299999996,62.62193300000007],[-91.66805999999991,62.64916200000005],[-91.68305999999995,62.662209000000075],[-91.68554699999999,62.66693900000013],[-91.67582699999997,62.66915900000009],[-91.66332999999997,62.66554300000007],[-91.65527299999991,62.662209000000075],[-91.581955,62.64138000000008],[-91.57556199999993,62.63721500000008],[-91.571121,62.632767000000115],[-91.57278399999996,62.62748700000009]],[[-90.97999599999997,62.657767999999976],[-90.99027999999998,62.656654],[-91.00334199999992,62.657211000000075],[-91.09889199999992,62.65443399999998],[-91.24471999999997,62.66999100000004],[-91.256393,62.67193600000002],[-91.26695299999994,62.675552000000096],[-91.27111799999994,62.67999299999997],[-91.26722699999999,62.685546999999985],[-91.226944,62.691658000000075],[-91.17304999999999,62.69137599999999],[-91.08029199999999,62.68693500000006],[-91.056107,62.68166400000007],[-90.981674,62.66137699999996],[-90.97999599999997,62.657767999999976]],[[-74.347778,62.67943600000007],[-74.30999800000001,62.67916100000008],[-74.285553,62.67999299999997],[-74.25028999999995,62.682495000000074],[-74.21610999999996,62.684990000000084],[-74.181671,62.68888099999998],[-74.15888999999999,62.68888099999998],[-74.14584399999995,62.68776700000001],[-74.01583900000003,62.66499300000004],[-74.00917099999998,62.66249099999993],[-73.95973200000003,62.62082700000002],[-73.958054,62.616661000000136],[-73.958054,62.612495000000024],[-73.96250899999995,62.60777299999995],[-73.96972700000003,62.60416399999997],[-73.98860200000001,62.60221899999999],[-74.12887599999988,62.60082999999997],[-74.15444899999989,62.60110500000002],[-74.16915899999992,62.60221899999999],[-74.18360899999993,62.603882000000056],[-74.333618,62.62943300000012],[-74.54138199999994,62.66832700000003],[-74.55110200000001,62.67082999999997],[-74.58639499999992,62.683051999999975],[-74.61721799999992,62.69609800000006],[-74.639725,62.70638300000002],[-74.64973399999991,62.712769000000094],[-74.65139799999986,62.716934000000094],[-74.64584400000001,62.72082499999999],[-74.53721599999994,62.748878000000104],[-74.5266719999999,62.748878000000104],[-74.51916499999987,62.74777200000011],[-74.48277299999995,62.739716000000044],[-74.39222699999993,62.68721000000011],[-74.37998999999996,62.682495000000074],[-74.37416099999996,62.6813810000001],[-74.347778,62.67943600000007]],[[-70.71167000000003,62.81499500000001],[-70.65972899999991,62.79833200000013],[-70.587784,62.7741620000001],[-70.54750099999995,62.76527399999998],[-70.41555799999998,62.7291560000001],[-70.39695699999999,62.72304500000001],[-70.22610499999996,62.603049999999996],[-70.21777299999997,62.59443700000003],[-70.21221899999995,62.584160000000054],[-70.21112099999999,62.57916300000011],[-70.21194500000001,62.57777399999992],[-70.264725,62.55915800000008],[-70.28332499999999,62.55443600000001],[-70.37361099999993,62.533332999999914],[-70.39306599999998,62.53027300000008],[-70.414444,62.529434000000094],[-70.46665999999993,62.53166200000004],[-70.50111399999997,62.533607000000075],[-70.68638599999991,62.546104000000014],[-70.72389199999998,62.550270000000125],[-70.74638399999998,62.55470999999994],[-70.765015,62.5605470000001],[-70.77084400000001,62.56471299999998],[-70.81973299999999,62.60471300000012],[-70.82501199999996,62.61444100000011],[-70.85444599999994,62.71360800000008],[-70.84666399999998,62.766106000000036],[-70.94554099999993,62.798050000000046],[-71.01916499999993,62.81193499999995],[-71.03250099999997,62.81249200000002],[-71.04333499999996,62.81193499999995],[-71.05166599999995,62.81054700000004],[-71.10638399999993,62.80082700000014],[-71.14111300000002,62.794998000000135],[-71.14862099999993,62.794998000000135],[-71.15834000000001,62.79721799999999],[-71.17610199999996,62.80915800000008],[-71.24055499999997,62.87638099999998],[-71.241379,62.8813780000001],[-71.23638900000003,62.886658000000125],[-71.22944599999988,62.88804600000003],[-71.19110099999995,62.884720000000016],[-71.07389799999993,62.87193300000001],[-70.78805499999993,62.836104999999975],[-70.76028399999996,62.829994000000056],[-70.71167000000003,62.81499500000001]],[[-66.36833199999995,62.83526599999999],[-66.37388599999986,62.833603000000096],[-66.386124,62.834434999999985],[-66.49027999999998,62.85527000000013],[-66.50527999999997,62.861382000000106],[-66.60166900000002,62.90665400000012],[-66.59388699999994,62.91193400000003],[-66.57417299999997,62.913048],[-66.547775,62.91054500000001],[-66.54028299999993,62.907493999999986],[-66.44193999999999,62.871101000000124],[-66.37777699999992,62.843323],[-66.37027,62.83971399999996],[-66.36833199999995,62.83526599999999]],[[-81.87110899999999,62.92832900000013],[-81.86555499999997,62.92332499999998],[-81.86416599999995,62.91999099999998],[-81.90695199999999,62.86638600000009],[-81.92610199999996,62.74415600000003],[-81.924713,62.73915899999997],[-81.92388900000003,62.73304699999994],[-81.92416400000002,62.72832500000004],[-81.92610199999996,62.723602000000085],[-81.929169,62.719437000000084],[-81.93859899999995,62.709991000000116],[-81.95889299999999,62.69776899999994],[-81.973053,62.6897130000001],[-82.10221899999999,62.62915800000013],[-82.1875,62.59943399999992],[-82.27778599999994,62.584160000000054],[-82.2869419999999,62.58166499999999],[-82.31555200000003,62.57166300000006],[-82.36915599999992,62.54749300000003],[-82.38166799999999,62.53943600000008],[-82.38778699999995,62.53472100000005],[-82.40194699999995,62.52054600000014],[-82.40834000000001,62.509720000000016],[-82.40888999999993,62.49665799999997],[-82.414444,62.47804300000007],[-82.42581199999995,62.46998600000006],[-82.44221499999992,62.458603000000096],[-82.44972200000001,62.4552690000001],[-82.49943499999995,62.438599000000124],[-82.53388999999999,62.428604000000064],[-82.551941,62.42388199999999],[-82.58361799999994,62.41276600000003],[-82.62138400000003,62.39527100000004],[-82.64111300000002,62.38526900000005],[-82.64723200000003,62.38110400000005],[-82.67027300000001,62.35943600000013],[-82.68859900000001,62.34110300000009],[-82.71305799999993,62.32138100000003],[-82.73138399999993,62.309990000000084],[-82.743607,62.30248999999998],[-82.76916499999999,62.290276000000006],[-82.98554999999999,62.209717000000126],[-83.00195300000001,62.20443700000004],[-83.087784,62.17887900000011],[-83.12193299999996,62.1730500000001],[-83.13639799999999,62.1730500000001],[-83.14389,62.176659000000086],[-83.15083299999998,62.182770000000005],[-83.15943900000002,62.198601],[-83.16805999999991,62.2074970000001],[-83.17639200000002,62.213051000000064],[-83.19860799999998,62.222214000000065],[-83.249435,62.24082900000002],[-83.27583299999998,62.248604000000114],[-83.30804399999988,62.25277700000004],[-83.32278400000001,62.25305200000008],[-83.33778399999994,62.252219999999966],[-83.35972600000002,62.24971800000009],[-83.40556299999997,62.23888400000004],[-83.4719389999999,62.22276300000004],[-83.48083500000001,62.21998600000012],[-83.49888599999991,62.21332600000011],[-83.51333599999992,62.20638300000013],[-83.53999299999992,62.191933000000006],[-83.57417299999986,62.1763840000001],[-83.63917499999997,62.1511000000001],[-83.653885,62.145827999999995],[-83.67277499999994,62.14110600000009],[-83.68331899999998,62.139717000000076],[-83.70388799999995,62.141662999999994],[-83.70944199999997,62.14444000000009],[-83.71389799999997,62.147216999999955],[-83.71833799999996,62.15221400000007],[-83.722778,62.16027100000002],[-83.722778,62.16721300000012],[-83.71806300000003,62.17943600000001],[-83.71194500000001,62.217209000000025],[-83.71166999999991,62.235825000000034],[-83.72138999999999,62.2816620000001],[-83.722778,62.28638500000011],[-83.72582999999992,62.295273000000066],[-83.731674,62.30360400000001],[-83.73889200000002,62.306937999999946],[-83.75666799999999,62.312492000000134],[-83.78332499999999,62.31888600000002],[-83.80665599999998,62.326385000000016],[-83.82444800000002,62.33721200000002],[-83.90249599999987,62.38749700000005],[-83.91861,62.3991620000001],[-83.93360899999988,62.41220900000013],[-83.94248999999996,62.42166100000003],[-83.945267,62.42721599999993],[-83.94665499999996,62.434158000000025],[-83.94665499999996,62.440269000000114],[-83.945267,62.44721200000009],[-83.93916299999995,62.457497000000046],[-83.91416899999996,62.47860000000014],[-83.90833999999995,62.48276499999997],[-83.86944599999998,62.501105999999936],[-83.85305800000003,62.50804900000014],[-83.814438,62.52388000000008],[-83.741379,62.551658999999916],[-83.70417799999996,62.569443000000035],[-83.69804399999992,62.573051000000135],[-83.57000700000003,62.67527000000001],[-83.55943300000001,62.68415799999997],[-83.55027799999993,62.69999700000011],[-83.545547,62.71221200000002],[-83.545547,62.71776600000004],[-83.55139200000002,62.726653999999996],[-83.55583199999995,62.731659000000036],[-83.55888400000003,62.743881000000044],[-83.53361499999988,62.810272000000055],[-83.52749599999993,62.8211060000001],[-83.523056,62.825271999999984],[-83.516953,62.829994000000056],[-83.400284,62.897491000000116],[-83.37416099999996,62.906937000000084],[-83.31082200000003,62.924438000000066],[-83.29861499999998,62.92582700000003],[-83.21167000000003,62.913605000000075],[-83.20417799999996,62.91027100000008],[-83.19833399999999,62.90665400000012],[-83.19387799999998,62.901932000000045],[-83.18249500000002,62.8813780000001],[-83.17805499999992,62.87638099999998],[-83.15611299999995,62.86054999999999],[-83.14250199999998,62.85443900000013],[-83.12470999999994,62.84804500000007],[-83.108337,62.843323],[-83.08750900000001,62.84027100000009],[-83.061935,62.83749399999999],[-83.04110700000001,62.83721200000008],[-83.02139299999999,62.838599999999985],[-83.00167799999991,62.84249100000005],[-82.98222399999992,62.84777100000014],[-82.85749799999996,62.88999200000012],[-82.82556199999999,62.90277100000003],[-82.79333500000001,62.915543000000014],[-82.75973499999992,62.926941],[-82.7519529999999,62.92887899999994],[-82.69444299999998,62.93943000000007],[-82.652222,62.94387800000004],[-82.62470999999988,62.945540999999935],[-82.60665899999998,62.945540999999935],[-82.573624,62.94387800000004],[-82.54083300000002,62.93943000000007],[-82.50778199999996,62.93360100000007],[-82.46139499999998,62.92748999999998],[-82.43611099999998,62.925270000000125],[-82.420837,62.92499500000014],[-82.39805599999988,62.92748999999998],[-82.38137799999998,62.932770000000005],[-82.37805200000003,62.936377999999934],[-82.37638900000002,62.94110100000012],[-82.379166,62.946655000000135],[-82.38362099999995,62.95138500000013],[-82.37998999999996,62.9574970000001],[-82.37222300000002,62.96027400000003],[-82.29277000000002,62.98333000000008],[-82.26666299999994,62.989159000000086],[-82.239441,62.99027300000006],[-82.18582199999992,62.979988000000105],[-82.12193299999996,62.966660000000104],[-82.00805700000001,62.95499399999994],[-81.94027699999998,62.95387999999997],[-81.91166699999997,62.952217000000076],[-81.90583800000002,62.94999700000005],[-81.87110899999999,62.92832900000013]],[[-66.82556199999999,62.984161000000086],[-66.83139,62.98276500000003],[-66.87138400000003,62.98888400000004],[-66.88194299999998,62.991661000000136],[-66.88945000000001,62.99526999999995],[-67.069458,63.10749800000002],[-67.03277600000001,63.103882],[-66.96528599999999,63.08249699999999],[-66.952225,63.07804900000002],[-66.94610599999987,63.07499700000011],[-66.94444299999992,63.072768999999994],[-66.93055700000002,63.06693999999999],[-66.91749600000003,63.0597150000001],[-66.90750100000002,63.052773],[-66.83000199999992,62.99249300000008],[-66.82695000000001,62.98999000000009],[-66.82501199999996,62.985550000000046],[-66.82556199999999,62.984161000000086]],[[-67.76445000000001,63.162491000000045],[-67.77583300000003,63.1616590000001],[-67.78750599999995,63.16304800000012],[-67.79861499999987,63.16554300000013],[-67.80638099999999,63.168602000000135],[-67.85194399999995,63.191376000000105],[-67.86332700000003,63.19915800000001],[-67.87638899999996,63.21193700000009],[-67.876938,63.21693399999998],[-67.875,63.22304500000007],[-67.86639399999996,63.23249100000004],[-67.85221899999988,63.244438],[-67.84445199999999,63.2472150000001],[-67.839722,63.2472150000001],[-67.831955,63.24415599999992],[-67.82194500000003,63.23665600000004],[-67.82223499999992,63.233330000000024],[-67.816101,63.23054499999995],[-67.79167199999995,63.21499600000004],[-67.769455,63.19832600000012],[-67.74610899999993,63.17887900000011],[-67.74472000000003,63.1730500000001],[-67.74638400000003,63.16693900000001],[-67.76445000000001,63.162491000000045]],[[-67.925003,63.18332700000008],[-67.95611600000001,63.181107000000054],[-67.966949,63.183876],[-68.00083899999998,63.208046000000024],[-68.01722699999999,63.22054300000002],[-68.06138599999991,63.25777399999998],[-68.10583499999996,63.299438000000066],[-68.11166399999996,63.30915800000014],[-68.112213,63.31360600000011],[-68.10638399999999,63.31860400000011],[-68.09695399999993,63.318885999999964],[-68.085556,63.31610100000012],[-68.06916799999988,63.309432999999956],[-68.04888900000003,63.29749300000009],[-68.03222700000003,63.28499600000009],[-68.00028999999995,63.26027699999992],[-67.92582699999997,63.196098000000006],[-67.920547,63.191376000000105],[-67.91694599999994,63.18665300000009],[-67.925003,63.18332700000008]],[[-78.07972699999999,63.469436999999914],[-77.94610599999999,63.468048000000124],[-77.93777499999999,63.471100000000035],[-77.93055699999996,63.4749910000001],[-77.92416400000002,63.47693600000008],[-77.91194199999995,63.47637900000001],[-77.84500100000002,63.47221400000001],[-77.68055700000002,63.43443300000001],[-77.63667299999992,63.40277100000009],[-77.495834,63.274994000000106],[-77.49388099999999,63.269989000000066],[-77.49499499999996,63.265831000000105],[-77.50389100000001,63.25249499999995],[-77.57333399999993,63.200546000000145],[-77.641953,63.17193600000007],[-77.78527799999989,63.12165800000014],[-77.89889499999992,63.09276600000004],[-77.90666199999998,63.09165999999999],[-77.93138099999993,63.09054600000002],[-77.94665500000002,63.09110300000009],[-77.95834399999995,63.093048000000124],[-78.0250089999999,63.11721],[-78.12471,63.16582500000004],[-78.226944,63.22165699999999],[-78.295547,63.25999500000006],[-78.31138599999991,63.27221700000001],[-78.32223499999998,63.281105000000025],[-78.343613,63.29694400000011],[-78.354446,63.30360400000012],[-78.44665500000002,63.35027300000013],[-78.4869379999999,63.36499800000007],[-78.51972999999998,63.370270000000005],[-78.52389499999998,63.37248999999997],[-78.56249999999994,63.39582800000011],[-78.57223499999992,63.4347150000001],[-78.57278399999996,63.440269000000114],[-78.55166599999995,63.44499200000007],[-78.37998999999996,63.47637900000001],[-78.278885,63.489716000000044],[-78.214111,63.49653599999999],[-78.212784,63.49610100000007],[-78.15861499999988,63.482208000000014],[-78.09167500000001,63.470543000000134],[-78.07972699999999,63.469436999999914]],[[-90.65388499999995,63.441101],[-90.697495,63.4397130000001],[-90.70889299999993,63.4405440000001],[-90.71916199999998,63.44360399999999],[-90.72582999999986,63.44804399999998],[-90.75500499999998,63.489716000000044],[-90.75723299999999,63.494438000000116],[-90.74804699999993,63.49832900000001],[-90.73750299999995,63.49916100000013],[-90.64555399999995,63.48333000000014],[-90.62026999999995,63.47693600000008],[-90.60278299999999,63.46388200000001],[-90.598053,63.454436999999984],[-90.60221899999999,63.44915800000001],[-90.61193799999995,63.44609800000012],[-90.62193299999996,63.44415300000014],[-90.65388499999995,63.441101]],[[-78.55749499999996,63.457497000000046],[-78.60055499999993,63.45638300000002],[-78.60333300000002,63.45777099999998],[-78.56138599999997,63.502495000000124],[-78.54333499999996,63.51610600000009],[-78.51583900000003,63.53166200000004],[-78.50500499999987,63.53249399999993],[-78.49610899999993,63.529434000000094],[-78.47332799999998,63.51915700000012],[-78.46806300000003,63.51554900000002],[-78.46166999999997,63.50749999999999],[-78.45916699999998,63.47998800000005],[-78.46194500000001,63.47387700000013],[-78.46722399999999,63.469436999999914],[-78.47555499999999,63.46693399999998],[-78.531113,63.45860300000004],[-78.55749499999996,63.457497000000046]],[[-90.79360999999994,63.49415600000009],[-90.80444299999994,63.49332400000014],[-90.816956,63.49582700000013],[-90.87721299999998,63.514717000000076],[-90.93331899999998,63.53416400000009],[-90.96583599999997,63.54583000000008],[-90.96833799999996,63.550270000000125],[-90.95750399999997,63.5513840000001],[-90.77111799999994,63.55193300000002],[-90.74804699999993,63.550270000000125],[-90.72000100000002,63.543052999999986],[-90.70973199999997,63.539992999999924],[-90.70083599999998,63.53611000000001],[-90.68138099999999,63.52304799999996],[-90.67694099999989,63.51859999999999],[-90.674713,63.51388499999996],[-90.678604,63.508331],[-90.68888900000002,63.50638600000002],[-90.79360999999994,63.49415600000009]],[[-64.851944,63.38582600000012],[-64.85694899999999,63.38582600000012],[-64.88221699999997,63.395546000000024],[-64.90417500000001,63.40638000000007],[-64.91833500000001,63.413879000000065],[-64.94221500000003,63.43082400000003],[-64.95083599999992,63.439156000000025],[-65.02667200000002,63.51554900000002],[-65.035278,63.52443699999998],[-65.05305499999997,63.54833199999996],[-65.051941,63.55221599999999],[-64.97721899999999,63.56832900000006],[-64.96749899999992,63.56832900000006],[-64.95472699999999,63.55888399999998],[-64.95472699999999,63.55387900000011],[-64.93360899999999,63.54471600000011],[-64.912216,63.533333000000084],[-64.90916399999998,63.52860300000009],[-64.86749299999991,63.46166200000005],[-64.86082499999986,63.44721200000009],[-64.84750400000001,63.40749400000004],[-64.84472699999998,63.39694200000008],[-64.847778,63.387496999999996],[-64.851944,63.38582600000012]],[[-72.18249500000002,63.51998900000001],[-72.20750399999997,63.51998900000001],[-72.218887,63.52249100000006],[-72.22694399999995,63.525825999999995],[-72.2327729999999,63.53027300000002],[-72.28666699999991,63.58332800000011],[-72.27917499999995,63.58554800000013],[-72.23222399999992,63.586655000000064],[-72.23028599999998,63.587212000000136],[-72.20527600000003,63.583054000000004],[-72.18443299999996,63.57721700000002],[-72.135559,63.562767000000065],[-72.129166,63.55888399999998],[-72.12805200000003,63.55387900000011],[-72.14500399999997,63.53943600000002],[-72.16583300000002,63.526381999999955],[-72.17361499999998,63.522766000000104],[-72.18249500000002,63.51998900000001]],[[-91.32917799999996,63.55971499999998],[-91.401947,63.54943800000001],[-91.42443800000001,63.550270000000125],[-91.43638599999997,63.55193300000002],[-91.4619449999999,63.55832700000008],[-91.54028299999993,63.60166200000003],[-91.54055800000003,63.60665899999998],[-91.53416400000003,63.611381999999935],[-91.50111399999997,63.61193800000012],[-91.46389799999992,63.6097180000001],[-91.44082600000002,63.608047000000056],[-91.428604,63.606383999999935],[-91.41639699999996,63.60360700000007],[-91.362503,63.59027100000009],[-91.34944200000001,63.586655000000064],[-91.29972799999996,63.567771999999934],[-91.30888400000003,63.563881000000094],[-91.32917799999996,63.55971499999998]],[[-64.09249899999992,63.48165900000009],[-64.101944,63.47943099999992],[-64.10916099999992,63.483047],[-64.16944899999999,63.52360500000009],[-64.18055699999996,63.53305100000006],[-64.18415800000002,63.53721600000006],[-64.20916699999998,63.574996999999996],[-64.2161099999999,63.59526800000003],[-64.21694899999994,63.60110500000013],[-64.21528599999994,63.617493000000024],[-64.21278399999994,63.623604000000114],[-64.19972200000001,63.633331000000055],[-64.19193999999999,63.63721500000008],[-64.18249500000002,63.639435000000105],[-64.17193599999996,63.63360600000004],[-64.09333799999996,63.56832900000006],[-64.07833899999991,63.55054500000011],[-64.077225,63.54527300000001],[-64.07778899999988,63.53971899999999],[-64.08612099999993,63.49305000000004],[-64.08750899999995,63.48665599999998],[-64.09249899999992,63.48165900000009]],[[-68.65638699999994,63.62638100000004],[-68.71777299999991,63.624161000000015],[-68.73110999999994,63.62554900000009],[-68.81555200000003,63.64916200000005],[-68.82167099999998,63.652488999999946],[-68.82000700000003,63.65526600000004],[-68.79305999999997,63.66165900000004],[-68.71444699999995,63.67249300000009],[-68.69166599999994,63.67360700000006],[-68.676941,63.671379000000115],[-68.66888399999993,63.66832699999998],[-68.66639700000002,63.66387900000001],[-68.66625999999997,63.662581999999986],[-68.65527299999997,63.63443799999999],[-68.654449,63.630272000000105],[-68.65638699999994,63.62638100000004]],[[-64.06111099999998,63.27054600000014],[-64.07055699999995,63.268326000000116],[-64.07833899999991,63.26888300000002],[-64.18194599999998,63.29694400000011],[-64.25140399999998,63.320831],[-64.266953,63.32638499999996],[-64.34973099999996,63.39222000000001],[-64.35388199999989,63.39582800000011],[-64.42193600000002,63.47165700000011],[-64.49610899999988,63.6097180000001],[-64.49055499999997,63.62054400000005],[-64.47917199999995,63.63694000000004],[-64.47361799999987,63.64054900000008],[-64.38667299999997,63.67527000000001],[-64.37721299999993,63.67748999999998],[-64.36721799999992,63.67527000000001],[-64.36305199999993,63.67193600000002],[-64.328888,63.644440000000145],[-64.32556199999993,63.63749699999994],[-64.32556199999993,63.59804500000007],[-64.32444799999996,63.58804299999997],[-64.32167099999998,63.57749200000006],[-64.316101,63.56249200000008],[-64.26251199999996,63.42110400000013],[-64.23249800000002,63.38832900000011],[-64.22528099999994,63.384438000000046],[-64.20666499999993,63.384163],[-64.166946,63.36943800000006],[-64.14472999999992,63.355552999999986],[-64.09999099999993,63.32276900000011],[-64.05749500000002,63.27804600000002],[-64.05749500000002,63.27388000000013],[-64.06111099999998,63.27054600000014]],[[-71.79916400000002,63.615546999999935],[-71.80694599999987,63.61193800000012],[-71.84527599999996,63.613609],[-71.8552699999999,63.61582900000002],[-71.86332700000003,63.619438],[-71.86582900000002,63.62443500000012],[-71.86582900000002,63.63638300000014],[-71.86416600000001,63.66944099999995],[-71.83056599999992,63.69387800000004],[-71.82194500000003,63.69526700000006],[-71.789444,63.69137599999999],[-71.779449,63.68832400000008],[-71.775284,63.68305199999992],[-71.77722199999994,63.67083000000014],[-71.79110700000001,63.6272130000001],[-71.79916400000002,63.615546999999935]],[[-76.81054699999999,63.60110500000013],[-76.710556,63.56582600000007],[-76.67222599999997,63.52887700000002],[-76.67555199999993,63.49665800000014],[-76.68160999999998,63.48135400000007],[-76.61332699999997,63.473602000000085],[-76.56555199999991,63.46776600000004],[-76.546112,63.46471400000013],[-76.54194599999994,63.462494000000106],[-76.54388399999999,63.46110499999992],[-76.67500299999995,63.37470999999999],[-76.68221999999997,63.37082700000008],[-76.69221499999998,63.367767000000015],[-76.70333899999997,63.365829000000076],[-76.71278399999994,63.36554699999999],[-76.72610500000002,63.36693600000001],[-76.847778,63.38526900000005],[-76.98416099999992,63.40638000000007],[-77.03527799999995,63.423882000000106],[-77.03944399999995,63.42610200000013],[-77.046112,63.42971799999998],[-77.05139199999996,63.434158000000025],[-77.05360399999995,63.43693500000012],[-77.05555699999996,63.442764000000125],[-77.06138599999997,63.45054600000009],[-77.10583499999996,63.47665400000005],[-77.11166399999996,63.479713000000004],[-77.327789,63.57222000000013],[-77.36721799999998,63.583054000000004],[-77.391388,63.58554800000013],[-77.41166699999997,63.584991],[-77.42222600000002,63.586655000000064],[-77.42777999999998,63.589157000000114],[-77.43194599999998,63.59193400000004],[-77.44221500000003,63.608330000000024],[-77.45722999999998,63.643325999999945],[-77.45388799999995,63.65221400000013],[-77.44027699999998,63.665268000000026],[-77.41027799999995,63.68665299999998],[-77.40055799999999,63.68888099999998],[-77.37805199999997,63.69221499999992],[-77.34333800000002,63.69609800000006],[-77.11694299999994,63.68110700000011],[-77.10333299999996,63.67971799999998],[-77.06138599999997,63.672768000000076],[-77.02139299999993,63.66415400000005],[-76.81054699999999,63.60110500000013]],[[-72.59472700000003,63.642494000000056],[-72.60444599999994,63.64166300000005],[-72.78056300000003,63.65998799999994],[-72.78332499999988,63.66443600000008],[-72.77055399999995,63.669715999999994],[-72.75666799999988,63.672768000000076],[-72.723053,63.67860399999995],[-72.50666799999999,63.70721400000002],[-72.48388699999998,63.708885000000066],[-72.47416699999991,63.705826000000116],[-72.47083999999995,63.702217000000076],[-72.47138999999999,63.700829],[-72.46888699999994,63.699158000000125],[-72.46333300000003,63.68915600000014],[-72.45973199999997,63.67916100000008],[-72.46055599999994,63.672768000000076],[-72.46389799999997,63.66832699999998],[-72.58444199999997,63.644440000000145],[-72.59472700000003,63.642494000000056]],[[-64.03250100000002,63.68971300000004],[-64.16111799999999,63.674438000000066],[-64.181107,63.67582700000008],[-64.20028699999995,63.685546999999985],[-64.20834400000001,63.69748700000008],[-64.21166999999997,63.70638300000002],[-64.21250900000001,63.71221200000002],[-64.20889299999999,63.721930999999984],[-64.18028300000003,63.74221800000009],[-64.17471299999994,63.745270000000005],[-64.16665599999999,63.747772000000055],[-64.08306900000002,63.75833100000011],[-64.07806399999998,63.75833100000011],[-64.075287,63.75804900000003],[-64.07333399999993,63.756386000000134],[-64.05484000000001,63.73659500000008],[-64.04333500000001,63.734161000000086],[-64.03028899999998,63.72971300000012],[-64.02528399999994,63.70249200000012],[-64.02528399999994,63.69748700000008],[-64.02639799999992,63.69387800000004],[-64.03250100000002,63.68971300000004]],[[-72.66776999999996,63.69582400000013],[-72.6949919999999,63.69026900000006],[-72.70361300000002,63.692490000000134],[-72.73416099999997,63.710823000000005],[-72.73889199999991,63.714439000000084],[-72.741669,63.71971100000002],[-72.74388099999987,63.73027000000002],[-72.73998999999998,63.736107000000004],[-72.71972700000003,63.76388500000013],[-72.71556099999992,63.766106000000036],[-72.70584100000002,63.76749400000011],[-72.69387799999998,63.76583099999999],[-72.68249500000002,63.76221499999997],[-72.66471899999993,63.75555400000002],[-72.64222699999993,63.745270000000005],[-72.63583399999999,63.74137900000011],[-72.62666300000001,63.73220799999996],[-72.62582399999997,63.727486000000056],[-72.62638900000002,63.72109999999998],[-72.63417099999998,63.709160000000054],[-72.64999399999999,63.701385000000016],[-72.66776999999996,63.69582400000013]],[[-64.28443900000002,63.70860299999998],[-64.28639199999998,63.70804600000008],[-64.31111099999993,63.709991000000116],[-64.32917800000001,63.71665999999999],[-64.33639499999992,63.719986000000006],[-64.34861799999999,63.72804299999996],[-64.35694899999999,63.73693800000001],[-64.36361699999998,63.74638399999998],[-64.381104,63.80749500000013],[-64.35943599999996,63.80387900000005],[-64.33972199999994,63.796943999999996],[-64.331955,63.79166399999997],[-64.30277999999993,63.78054800000001],[-64.27861000000001,63.77082800000011],[-64.27500899999995,63.76666300000011],[-64.25527999999997,63.72971300000012],[-64.25500499999993,63.72526600000009],[-64.26083399999987,63.71971100000002],[-64.28443900000002,63.70860299999998]],[[-64.17027300000001,63.856384000000105],[-64.1808319999999,63.785270999999966],[-64.195267,63.77860300000003],[-64.20333899999997,63.776382000000126],[-64.2344359999999,63.77137800000014],[-64.245834,63.77137800000014],[-64.256958,63.7741620000001],[-64.32556199999993,63.80582400000003],[-64.398346,63.845543000000134],[-64.39916999999997,63.84943400000003],[-64.3977809999999,63.85138699999999],[-64.39611799999994,63.85193600000014],[-64.35388199999989,63.86110700000006],[-64.334091,63.852081000000055],[-64.32556199999993,63.850273000000016],[-64.31082200000003,63.84832800000004],[-64.26834099999991,63.846100000000035],[-64.215012,63.850273000000016],[-64.20834400000001,63.852776000000006],[-64.20028699999995,63.85971800000004],[-64.18666100000002,63.86721],[-64.17999299999991,63.865547000000106],[-64.17582700000003,63.861938000000066],[-64.17027300000001,63.856384000000105]],[[-92.95417800000001,63.87110100000007],[-92.96055599999994,63.866386000000034],[-92.972778,63.86776700000007],[-92.99861099999998,63.873046999999985],[-93.06861900000001,63.88804600000003],[-93.093887,63.89999400000005],[-93.09445199999993,63.904990999999995],[-93.087784,63.90888200000006],[-93.07000700000003,63.90971399999995],[-93.00279199999994,63.91137700000007],[-92.99082900000002,63.91082],[-92.97833300000002,63.90832499999999],[-92.97444200000001,63.901657],[-92.95527599999997,63.88082099999997],[-92.95249899999999,63.87609900000007],[-92.95417800000001,63.87110100000007]],[[-64.57611099999986,63.780823],[-64.52583299999998,63.77137800000014],[-64.46777299999997,63.77137800000014],[-64.46194500000001,63.774712000000136],[-64.45249899999999,63.777214000000015],[-64.43276999999995,63.77943400000004],[-64.42610200000001,63.77777100000009],[-64.39472999999998,63.74582700000008],[-64.38751199999996,63.73749500000008],[-64.38612399999994,63.73443600000013],[-64.38612399999994,63.701660000000004],[-64.38999899999993,63.69638100000003],[-64.40417500000001,63.687492000000134],[-64.41915899999998,63.67971799999998],[-64.43638599999991,63.67332499999998],[-64.45056199999993,63.67166099999997],[-64.45944199999997,63.672768000000076],[-64.47444200000001,63.67916100000008],[-64.49694799999992,63.69082600000013],[-64.66166699999991,63.75499700000012],[-64.80221599999999,63.76444200000003],[-64.81332399999997,63.76721200000003],[-64.89028899999994,63.78943599999997],[-64.90055799999999,63.793883999999935],[-64.906387,63.797493000000145],[-64.9163969999999,63.80638099999993],[-64.91833500000001,63.815269000000114],[-64.92027299999995,63.82471500000008],[-64.9177699999999,63.83110800000003],[-64.91027799999995,63.83721200000008],[-64.89639299999999,63.845267999999976],[-64.81166099999996,63.87721300000004],[-64.710556,63.90888200000006],[-64.6824949999999,63.91443600000008],[-64.660278,63.91638200000011],[-64.64723199999997,63.916100000000085],[-64.55721999999992,63.90998800000011],[-64.55305499999992,63.90638000000001],[-64.54943799999995,63.89527100000009],[-64.571121,63.87082700000013],[-64.585556,63.84499400000004],[-64.57611099999986,63.780823]],[[-77.74388099999993,63.926658999999916],[-77.75334199999998,63.92555199999998],[-77.94860799999998,63.95082900000011],[-77.95695499999994,63.95388000000014],[-77.96694899999989,63.959160000000054],[-77.978882,63.96915400000006],[-77.98249799999996,63.97554800000006],[-77.98249799999996,63.983047000000056],[-77.97610500000002,63.99027300000006],[-77.95750399999997,64.00471500000003],[-77.950287,64.00915500000002],[-77.943604,64.01110799999998],[-77.92388900000003,64.01499900000005],[-77.88999899999999,64.01998900000007],[-77.77444500000001,64.0316620000001],[-77.75389099999995,64.03276100000011],[-77.64862099999999,64.03248600000006],[-77.59111000000001,64.03027299999997],[-77.55721999999997,64.02804600000007],[-77.54972799999996,64.02554300000008],[-77.54444899999999,64.02192700000006],[-77.54527300000001,64.0186000000001],[-77.62361099999998,63.997214999999926],[-77.62388599999991,63.99582700000002],[-77.62805200000003,63.991104000000064],[-77.63945000000001,63.981934000000024],[-77.68638599999997,63.95443700000004],[-77.72860699999995,63.932213000000104],[-77.73721299999988,63.928329000000076],[-77.74388099999993,63.926658999999916]],[[-89.80888400000003,64.05636600000008],[-89.81722999999994,64.05470300000013],[-89.82888799999989,64.05581699999993],[-89.839447,64.05886800000013],[-89.847778,64.06303400000007],[-89.86111499999998,64.07165500000013],[-89.86999500000002,64.08082600000012],[-89.87193300000001,64.08554100000015],[-89.86776700000001,64.09582499999999],[-89.85749800000002,64.0977630000001],[-89.83167999999989,64.09109499999994],[-89.82806399999993,64.08831800000007],[-89.81973299999993,64.08027600000008],[-89.80471799999998,64.0619200000001],[-89.80888400000003,64.05636600000008]],[[-64.962784,64.11080900000007],[-64.94860799999998,64.10971099999995],[-64.9036099999999,64.11109900000008],[-64.87110899999999,64.09915200000012],[-64.86944599999998,64.09664900000013],[-64.86999500000002,64.09332300000011],[-64.87332200000003,64.09082000000012],[-64.88444500000003,64.08665500000012],[-64.90556300000003,64.08221400000002],[-64.94665500000002,64.07887299999999],[-64.98889200000002,64.08137500000004],[-65.002228,64.08387800000003],[-65.02305599999994,64.08943200000004],[-65.04554699999994,64.09942600000005],[-65.05555699999996,64.10859699999997],[-65.05749500000002,64.11303700000002],[-65.05638099999993,64.11720300000007],[-65.05221599999993,64.12109399999997],[-65.03971899999993,64.12498500000004],[-65.02500900000001,64.12747200000013],[-65.01556399999993,64.12692299999998],[-64.99527,64.12303199999991],[-64.98999000000003,64.11859099999998],[-64.98083499999996,64.11526500000014],[-64.962784,64.11080900000007]],[[-64.491104,64.10914600000012],[-64.49999999999994,64.10803199999998],[-64.51139799999993,64.10832199999999],[-64.58750899999995,64.14749100000006],[-64.59249899999998,64.15193199999999],[-64.59527600000001,64.15498400000007],[-64.59584000000001,64.15664700000002],[-64.56777999999997,64.16360500000002],[-64.554169,64.16693100000003],[-64.52444499999996,64.16720600000002],[-64.51811199999992,64.16621400000002],[-64.50111400000003,64.16331499999995],[-64.45333900000003,64.14694200000008],[-64.450287,64.13026400000001],[-64.491104,64.10914600000012]],[[-73.176941,64.20027199999998],[-73.28277600000001,64.14332600000006],[-73.29194599999994,64.14387499999998],[-73.38639799999987,64.15887499999997],[-73.39695699999999,64.16110200000003],[-73.40167200000002,64.16554300000013],[-73.39472999999992,64.18775900000009],[-73.39306599999992,64.19247400000012],[-73.385559,64.19636500000001],[-73.30943300000001,64.19497700000011],[-73.20666499999999,64.21388200000007],[-73.18998699999992,64.21220399999993],[-73.17805499999997,64.209991],[-73.17332499999992,64.20526100000012],[-73.176941,64.20027199999998]],[[-81.47138999999999,64.18887300000006],[-81.493607,64.18830900000012],[-81.51611299999996,64.19053600000001],[-81.52778599999999,64.19413799999995],[-81.53666699999985,64.2086030000001],[-81.53805499999993,64.21804800000012],[-81.53222699999992,64.22303800000003],[-81.47000099999991,64.2394260000001],[-81.458618,64.23887600000006],[-81.41332999999997,64.23332200000004],[-81.39028899999994,64.22915599999993],[-81.378601,64.22554000000008],[-81.37582399999991,64.22082500000005],[-81.37499999999994,64.21582000000001],[-81.37887599999993,64.21192900000011],[-81.38890100000003,64.20498700000002],[-81.40527299999991,64.19470200000012],[-81.47138999999999,64.18887300000006]],[[-64.52027899999996,64.22026100000011],[-64.57640100000003,64.21054100000003],[-64.60166899999996,64.21249399999999],[-64.61193800000001,64.21582000000001],[-64.61944599999993,64.21971100000007],[-64.64695699999999,64.24414100000013],[-64.64778100000001,64.25000000000011],[-64.64361600000001,64.25582900000012],[-64.63751200000002,64.259995],[-64.62971500000003,64.26165800000012],[-64.57167099999992,64.26499899999999],[-64.557526,64.26486200000005],[-64.55305499999992,64.26332100000008],[-64.55221599999993,64.26165800000012],[-64.55249000000003,64.25665300000009],[-64.46806299999997,64.24331699999993],[-64.46472199999994,64.240814],[-64.46221899999995,64.23748799999993],[-64.464447,64.234421],[-64.471115,64.23165900000009],[-64.52027899999996,64.22026100000011]],[[-75.55139200000002,64.30386399999998],[-75.69193999999999,64.30247500000013],[-75.702225,64.3058170000001],[-75.70889299999999,64.31526200000013],[-75.70584099999996,64.34193400000004],[-75.69665500000002,64.35108900000012],[-75.68638599999991,64.35331700000006],[-75.665009,64.35081500000001],[-75.57888799999995,64.34609999999998],[-75.57278400000001,64.34498599999995],[-75.50250199999994,64.31971699999997],[-75.493607,64.3163760000001],[-75.50111400000003,64.313309],[-75.51112399999994,64.31109600000008],[-75.55139200000002,64.30386399999998]],[[-64.93859899999995,64.23553500000003],[-64.98916599999995,64.20915200000002],[-65.00306699999993,64.21026599999999],[-65.04861499999998,64.218323],[-65.05277999999998,64.21943699999997],[-65.0599979999999,64.22331200000013],[-65.06555199999997,64.22747800000002],[-65.073059,64.24054000000007],[-65.10249299999998,64.29637100000014],[-65.10916099999997,64.31080600000007],[-65.11389200000002,64.32360800000004],[-65.11471599999999,64.32943700000004],[-65.11416600000001,64.33499100000006],[-65.112503,64.33970600000009],[-65.11000100000001,64.34359699999999],[-65.10166900000002,64.34637499999997],[-65.08944699999995,64.349716],[-65.02888499999989,64.36109900000002],[-65.02139299999993,64.36248799999998],[-65.01028399999996,64.36164900000006],[-65.006393,64.36053500000008],[-65.00195299999996,64.35693400000002],[-64.99888599999997,64.35443100000003],[-64.98222399999997,64.333054],[-64.88473499999992,64.28776600000009],[-64.88612399999994,64.28305100000006],[-64.89083899999997,64.27638200000001],[-64.92694099999994,64.24247700000006],[-64.93859899999995,64.23553500000003]],[[-73.87638900000002,64.301376],[-73.88362099999995,64.29887400000007],[-73.95167499999997,64.30497700000001],[-73.96556099999998,64.30664100000007],[-73.97250399999996,64.30970799999994],[-73.97444200000001,64.313309],[-73.96028100000001,64.36219799999998],[-73.95666499999993,64.36831700000005],[-73.95249899999993,64.3708190000001],[-73.94221499999992,64.37275700000004],[-73.93221999999992,64.37359600000002],[-73.91833500000001,64.37191800000005],[-73.90943899999996,64.36998000000011],[-73.88917500000002,64.35971100000012],[-73.87916599999994,64.35192899999998],[-73.87416099999996,64.34332300000005],[-73.87332200000003,64.30525200000005],[-73.87638900000002,64.301376]],[[-73.69776899999988,64.26998900000007],[-73.70472699999993,64.26887500000004],[-73.72084000000001,64.27276599999993],[-73.75389100000001,64.28276100000005],[-73.77667199999996,64.29470800000001],[-73.82333399999999,64.32470700000005],[-73.833618,64.33166500000004],[-73.781387,64.40554799999995],[-73.77610800000002,64.40748600000012],[-73.76556399999998,64.40942400000006],[-73.74916100000002,64.41026299999999],[-73.74444599999998,64.405823],[-73.73083500000001,64.38638300000002],[-73.729172,64.38610799999998],[-73.726944,64.38333100000006],[-73.72444199999995,64.37747200000007],[-73.70249899999999,64.32276900000011],[-73.69915799999995,64.31414799999999],[-73.69055200000003,64.27693200000004],[-73.691666,64.27360500000009],[-73.69444299999992,64.27110300000004],[-73.69776899999988,64.26998900000007]],[[-64.84973099999996,64.30748],[-64.86138899999997,64.30748],[-64.87721299999998,64.313309],[-64.88806199999999,64.32110599999999],[-64.93777499999999,64.36164900000006],[-64.94499200000001,64.37052900000009],[-64.95556599999998,64.38388099999992],[-64.95973200000003,64.39721700000007],[-64.958618,64.405823],[-64.95167499999991,64.41137699999996],[-64.94665500000002,64.41360500000013],[-64.93249500000002,64.41748000000013],[-64.92527799999999,64.4185940000001],[-64.91000400000001,64.41665599999999],[-64.90249599999999,64.41276600000015],[-64.89750700000002,64.40860000000009],[-64.82000700000003,64.37942500000003],[-64.77194199999997,64.34887700000002],[-64.77055399999995,64.3458250000001],[-64.773056,64.34248400000007],[-64.84973099999996,64.30748]],[[-74.27194199999991,64.41360500000013],[-74.28500400000001,64.41304000000008],[-74.35749799999996,64.42109700000009],[-74.37721299999998,64.4244230000001],[-74.42332499999998,64.44386300000008],[-74.43720999999994,64.45027199999993],[-74.439438,64.45332300000013],[-74.33860800000002,64.49470500000001],[-74.33167999999995,64.49693300000013],[-74.31040999999999,64.49884000000003],[-74.28527799999995,64.48165900000004],[-74.22860700000001,64.45109600000006],[-74.20584100000002,64.44747899999993],[-74.18306000000001,64.44303900000011],[-74.17332499999992,64.43914800000005],[-74.174713,64.43498199999999],[-74.17832899999996,64.43386799999996],[-74.27194199999991,64.41360500000013]],[[-73.74499500000002,64.42608600000005],[-73.75834699999996,64.42553700000008],[-73.77806099999998,64.428314],[-73.781387,64.43193100000013],[-73.78277600000001,64.43748499999992],[-73.78250099999997,64.44247400000006],[-73.77610800000002,64.49581899999998],[-73.77389499999998,64.501938],[-73.77333099999993,64.50332600000007],[-73.74691799999994,64.50851399999999],[-73.73666400000002,64.50721699999997],[-73.729172,64.50526400000007],[-73.72416699999985,64.50221300000004],[-73.67304999999999,64.46971100000002],[-73.66861,64.46443200000004],[-73.66833499999996,64.46026599999993],[-73.67193600000002,64.45582600000012],[-73.67971799999998,64.45220899999998],[-73.72721899999993,64.4310910000001],[-73.73500100000001,64.42804000000007],[-73.74499500000002,64.42608600000005]],[[-74.212784,64.483047],[-74.22332799999998,64.48027000000008],[-74.22917199999995,64.48136900000003],[-74.30749500000002,64.51609800000011],[-74.33111600000001,64.52665699999994],[-74.33750899999995,64.53109699999999],[-74.35777300000001,64.54693600000007],[-74.35777300000001,64.55108600000011],[-74.353882,64.55358900000004],[-74.34555099999994,64.555252],[-74.25306699999999,64.54803500000008],[-74.24055499999997,64.54637100000008],[-74.23611499999998,64.5455320000001],[-74.16972399999997,64.52388000000008],[-74.16944899999993,64.51971400000014],[-74.20666499999999,64.48637400000007],[-74.212784,64.483047]],[[-73.55749500000002,64.31275899999997],[-73.57778899999994,64.3099820000001],[-73.60166900000002,64.31025700000009],[-73.6263889999999,64.31275899999997],[-73.650284,64.31721500000009],[-73.65556300000003,64.320267],[-73.65833999999995,64.33499100000006],[-73.66953299999989,64.42684900000012],[-73.61044299999998,64.47048999999998],[-73.68249499999996,64.50972000000013],[-73.67999299999991,64.526093],[-73.67777999999993,64.53221100000013],[-73.66665599999988,64.53553800000009],[-73.577225,64.55998200000005],[-73.53721599999994,64.56776400000001],[-73.52778599999999,64.56694000000005],[-73.521118,64.56303400000013],[-73.50917099999998,64.55247500000007],[-73.50472999999994,64.54248000000001],[-73.50306699999993,64.53414900000007],[-73.48916599999995,64.46331800000007],[-73.48805199999998,64.453598],[-73.48832699999997,64.44386300000008],[-73.49027999999993,64.43914800000005],[-73.55526699999996,64.31469700000014],[-73.55749500000002,64.31275899999997]],[[-65.49276700000001,64.51776100000001],[-65.65833999999995,64.50972000000013],[-65.66944899999993,64.51026900000011],[-65.67971799999998,64.51220700000005],[-65.68611099999993,64.51527399999998],[-65.68971299999998,64.51998900000001],[-65.69027699999992,64.52415500000006],[-65.68971299999998,64.52998400000007],[-65.686935,64.53887900000012],[-65.67250099999995,64.56053200000008],[-65.660278,64.57388300000002],[-65.65110800000002,64.58055100000001],[-65.61582900000002,64.599152],[-65.56332399999991,64.61554000000007],[-65.55444299999999,64.6185910000001],[-65.54695100000004,64.62248199999999],[-65.44915800000001,64.67886399999998],[-65.44387799999993,64.684708],[-65.43582200000003,64.69636500000013],[-65.38194299999992,64.71693400000004],[-65.29249599999997,64.73553500000008],[-65.25695799999994,64.70999100000006],[-65.25250199999994,64.70637500000004],[-65.25805700000001,64.70082100000002],[-65.26640299999991,64.6933140000001],[-65.24999999999989,64.66360500000008],[-65.208054,64.63970899999998],[-65.208618,64.63136300000008],[-65.21389799999992,64.62608300000005],[-65.22805799999992,64.6202550000001],[-65.30943300000001,64.60054000000008],[-65.42027299999995,64.55442800000003],[-65.45278899999994,64.532761],[-65.45083599999992,64.52832000000006],[-65.45361300000002,64.524429],[-65.460556,64.52110299999998],[-65.468887,64.51915000000002],[-65.49276700000001,64.51776100000001]],[[-63.35333300000002,64.99498000000011],[-63.34916700000002,64.99165299999999],[-63.34722099999999,64.99192799999997],[-63.330558999999994,64.9869230000001],[-63.257506999999976,64.92942800000003],[-63.25639299999989,64.92637600000012],[-63.258895999999936,64.92109700000015],[-63.27305599999994,64.91804500000006],[-63.28138699999994,64.91832000000005],[-63.37777699999998,64.94081100000005],[-63.385276999999974,64.94413800000001],[-63.39388999999994,64.951096],[-63.417220999999984,64.97137499999991],[-63.420279999999934,64.97608900000006],[-63.420279999999934,64.978317],[-63.41889200000003,64.98248300000012],[-63.415549999999996,64.9869230000001],[-63.395279000000016,64.99552900000003],[-63.37610599999999,64.99887100000001],[-63.36361699999998,64.99720800000006],[-63.35333300000002,64.99498000000011]],[[-63.24361399999992,65.25499000000013],[-63.25139599999994,65.25387599999999],[-63.25666799999999,65.25610400000011],[-63.310554999999965,65.29054299999996],[-63.313331999999946,65.29386900000003],[-63.31166799999994,65.29803500000008],[-63.3066639999999,65.30247500000013],[-63.25778199999996,65.32083100000011],[-63.244445999999925,65.32276900000005],[-63.23666399999996,65.32165500000008],[-63.22721899999999,65.31387300000011],[-63.166388999999924,65.28610200000008],[-63.16583300000002,65.282486],[-63.16666399999997,65.27915999999999],[-63.23527499999989,65.25694300000009],[-63.24361399999992,65.25499000000013]],[[-66.92471299999994,65.28442400000012],[-66.93388399999998,65.28332499999999],[-66.96250900000001,65.28359999999998],[-66.97694399999995,65.28442400000012],[-66.98916600000001,65.28637700000007],[-66.99110399999995,65.28887899999995],[-67.01112399999994,65.31915300000003],[-67.01194800000002,65.3230440000001],[-67.010559,65.33332800000011],[-67.00500499999993,65.33970600000009],[-66.99221799999992,65.34610000000009],[-66.97444199999995,65.35054000000014],[-66.9324949999999,65.3580320000001],[-66.92027300000001,65.35859700000009],[-66.91082799999987,65.35693399999997],[-66.908615,65.355255],[-66.90805099999994,65.35108900000006],[-66.90943900000002,65.34610000000009],[-66.91194200000001,65.34220900000003],[-66.92027300000001,65.29443400000002],[-66.92138699999998,65.28970300000009],[-66.92471299999994,65.28442400000012]],[[-89.00556899999992,65.38554400000004],[-89.01750199999998,65.38554400000004],[-89.03028899999998,65.38749699999994],[-89.07611099999997,65.39471400000008],[-89.10028099999988,65.40081800000007],[-89.09999099999993,65.40582299999994],[-89.09167499999995,65.40832500000005],[-89.06806899999998,65.40832500000005],[-89.03195199999999,65.40721100000007],[-89.01861599999995,65.40332000000001],[-89.00944500000003,65.39915500000001],[-89.00527999999991,65.39553800000004],[-89.00306699999999,65.39054900000008],[-89.00556899999992,65.38554400000004]],[[-88.43028299999992,65.45526100000006],[-88.46501199999989,65.45359799999994],[-88.48999000000003,65.45665000000008],[-88.50361599999991,65.46054100000015],[-88.51028400000001,65.46499599999999],[-88.51222200000001,65.46971100000002],[-88.50750699999998,65.47499100000005],[-88.49638399999998,65.47692899999998],[-88.48500100000001,65.47776799999997],[-88.46112099999999,65.47747800000013],[-88.42416399999996,65.47442600000005],[-88.39862099999988,65.47026100000005],[-88.39416499999993,65.46582000000012],[-88.39973399999997,65.46138000000008],[-88.42138699999998,65.45694000000009],[-88.43028299999992,65.45526100000006]],[[-62.79500599999989,65.51998899999995],[-62.80444299999999,65.51915000000002],[-62.81945000000002,65.52415500000006],[-62.82695000000001,65.52804600000013],[-62.89388999999994,65.5811000000001],[-62.89555399999995,65.58554100000003],[-62.89555399999995,65.58998100000002],[-62.88972499999994,65.599152],[-62.88444499999997,65.60554500000012],[-62.87471800000003,65.61360200000007],[-62.8663939999999,65.61747700000006],[-62.85639200000003,65.61914100000007],[-62.84972399999998,65.61886600000008],[-62.84277300000002,65.616379],[-62.83805100000001,65.61360200000007],[-62.834998999999925,65.60664400000013],[-62.834998999999925,65.60470599999996],[-62.83000199999998,65.59304800000012],[-62.82444800000002,65.58526599999999],[-62.817504999999926,65.578598],[-62.81027999999998,65.57470699999993],[-62.78556099999997,65.5641480000001],[-62.76500699999997,65.55748000000011],[-62.750838999999985,65.55137600000006],[-62.78889499999997,65.52331500000003],[-62.79500599999989,65.51998899999995]],[[-83.88276699999994,65.66693100000009],[-83.89388999999994,65.66470300000015],[-83.90638699999994,65.66693100000009],[-83.93749999999994,65.67719999999991],[-83.94305400000002,65.68193100000008],[-83.94221499999998,65.68692000000004],[-83.93638599999997,65.69192500000008],[-83.92832899999996,65.69720500000011],[-83.896118,65.71026600000005],[-83.88473499999998,65.71276900000004],[-83.87277199999994,65.71220399999999],[-83.86444099999994,65.707764],[-83.86888099999999,65.69693000000012],[-83.87138400000003,65.68692000000004],[-83.87693799999994,65.67221099999995],[-83.88276699999994,65.66693100000009]],[[-67.47250400000001,65.70526100000001],[-67.55972300000002,65.7022090000001],[-67.58473199999997,65.70359800000011],[-67.64056399999993,65.69609100000014],[-67.69137599999993,65.68580600000001],[-67.70140100000003,65.68609600000008],[-67.70695499999994,65.68803400000002],[-67.71389799999986,65.69664000000012],[-67.71583599999997,65.70165999999995],[-67.71333299999992,65.70555100000001],[-67.69583099999988,65.7208250000001],[-67.658615,65.72526600000003],[-67.57749899999999,65.73165899999998],[-67.52917500000001,65.73498500000005],[-67.49999999999994,65.73498500000005],[-67.48971599999993,65.73498500000005],[-67.42443800000001,65.73526000000004],[-67.44694499999991,65.71859699999999],[-67.47250400000001,65.70526100000001]],[[-62.268332999999984,65.70165999999995],[-62.25944500000003,65.69970700000005],[-62.23805199999998,65.70248400000008],[-62.22110700000002,65.7080380000001],[-62.20416999999992,65.71165500000006],[-62.186385999999914,65.711929],[-62.16777799999994,65.70277399999992],[-62.131667999999934,65.67886399999998],[-62.12833399999994,65.67414900000011],[-62.13194299999998,65.65721100000002],[-62.135276999999974,65.65138200000001],[-62.14222699999999,65.64498900000001],[-62.19499999999999,65.61276200000003],[-62.20249899999999,65.61025999999998],[-62.21500400000002,65.60998499999994],[-62.22444200000001,65.61109899999997],[-62.29695099999998,65.6249850000001],[-62.45500199999998,65.65998800000011],[-62.46610999999996,65.66387900000001],[-62.483886999999925,65.72109999999992],[-62.48444399999994,65.72692899999998],[-62.483611999999994,65.73165899999998],[-62.48055299999987,65.73776199999992],[-62.47360999999995,65.74192800000003],[-62.46832999999998,65.74414099999996],[-62.46194499999996,65.74525499999999],[-62.28388999999993,65.74443100000002],[-62.27194199999991,65.74414099999996],[-62.260283999999956,65.74331699999999],[-62.25250199999999,65.74192800000003],[-62.251396,65.7391510000001],[-62.25861399999991,65.72859200000005],[-62.27027899999996,65.72303800000009],[-62.29750100000001,65.70860299999998],[-62.268332999999984,65.70165999999995]],[[-83.28388999999993,65.83415200000013],[-83.29222099999993,65.82887299999999],[-83.30360399999995,65.82638500000002],[-83.31555199999997,65.82609600000006],[-83.32749899999993,65.82748399999997],[-83.34777799999989,65.83248900000007],[-83.39527900000002,65.8316650000001],[-83.40666199999998,65.83027600000008],[-83.41805999999997,65.82777400000003],[-83.42916899999994,65.82443200000006],[-83.43998699999992,65.81915300000009],[-83.45639,65.80886799999996],[-83.47332799999998,65.80026200000003],[-83.48527499999994,65.80081200000006],[-83.49804699999993,65.80415299999993],[-83.52972399999999,65.81748999999996],[-83.55915799999997,65.83110000000005],[-83.57556199999993,65.83998099999997],[-83.58167999999989,65.84471100000002],[-83.58500700000002,65.84942600000005],[-83.58612099999999,65.8541560000001],[-83.58029199999999,65.85942099999994],[-83.57167099999998,65.86248800000004],[-83.56027199999994,65.86499000000015],[-83.52528399999989,65.8683170000001],[-83.47805800000003,65.87025500000004],[-83.44249000000002,65.87081899999998],[-83.36999499999996,65.86665300000004],[-83.345551,65.863876],[-83.33306900000002,65.8602600000001],[-83.29110699999995,65.84359700000005],[-83.28527799999995,65.83888200000001],[-83.28388999999993,65.83415200000013]],[[-65.64584399999995,65.81303400000007],[-65.656387,65.81275900000003],[-65.660278,65.81971700000003],[-65.65499899999992,65.86943100000008],[-65.65167199999996,65.87664799999999],[-65.64778100000001,65.879974],[-65.63612399999988,65.88638300000008],[-65.62388599999991,65.8913730000001],[-65.58306900000002,65.90277100000014],[-65.54276999999996,65.9080350000001],[-65.53167699999995,65.90887499999997],[-65.51611299999996,65.90637199999998],[-65.51139799999993,65.90304600000013],[-65.5122219999999,65.89444000000003],[-65.51333599999998,65.89054899999996],[-65.52806099999998,65.85942099999994],[-65.55943300000001,65.83471700000001],[-65.64584399999995,65.81303400000007]],[[-85.48055999999997,65.79193099999998],[-85.46806299999997,65.790817],[-85.45638999999994,65.79136700000004],[-85.44526699999994,65.79386900000009],[-85.42416400000002,65.8019260000001],[-85.41389500000002,65.80748000000006],[-85.40834000000001,65.8124850000001],[-85.40499899999998,65.81748999999996],[-85.40417500000001,65.822495],[-85.39306599999986,65.83276400000005],[-85.38194299999998,65.83526599999993],[-85.36999500000002,65.83499100000012],[-85.333328,65.83221400000002],[-85.31361399999992,65.83027600000008],[-85.28860500000002,65.82666],[-85.26306199999999,65.82110600000004],[-85.21362299999998,65.80802900000003],[-85.20278899999994,65.80358899999999],[-85.18582200000003,65.79470800000007],[-85.1625059999999,65.78137200000009],[-85.15638699999994,65.77665700000006],[-85.04916400000002,65.621643],[-85.04777499999994,65.61692800000014],[-85.04861499999998,65.6119230000001],[-85.05166600000001,65.60693400000014],[-85.06750499999993,65.59637500000008],[-85.08805799999999,65.58554100000003],[-85.12027,65.574997],[-85.14222699999993,65.56999200000013],[-85.17582700000003,65.56330900000012],[-85.23222399999992,65.55470300000002],[-85.24360699999994,65.55386400000009],[-85.26777600000003,65.555542],[-85.28056300000003,65.55802900000009],[-85.29194599999988,65.55720500000012],[-85.30249000000003,65.55276500000008],[-85.30777,65.54776000000004],[-85.31111099999993,65.54247999999995],[-85.311935,65.53776600000003],[-85.308044,65.533051],[-85.29583699999995,65.52388000000002],[-85.271118,65.51165800000007],[-85.24082900000002,65.49832200000009],[-85.20417800000001,65.48580900000002],[-85.16555799999998,65.47499100000005],[-85.12777699999992,65.46609500000011],[-85.08860800000002,65.45359799999994],[-85.04360999999994,65.43637100000012],[-85.02694699999995,65.42747500000002],[-85.015015,65.41831999999994],[-85.01112399999994,65.41360500000008],[-85.00279199999994,65.40138200000007],[-85.00140399999992,65.39665200000002],[-85.00500499999998,65.37692300000009],[-85.01167299999997,65.35220300000003],[-84.93055700000002,65.21415700000006],[-84.924713,65.20971700000001],[-84.912216,65.2063750000001],[-84.90028399999994,65.2061000000001],[-84.83250399999997,65.2124940000001],[-84.82139599999988,65.21388200000001],[-84.810272,65.216385],[-84.80027799999999,65.22164900000001],[-84.79249600000003,65.22692900000004],[-84.74804699999999,65.29275500000006],[-84.74694799999997,65.29748500000005],[-84.7497249999999,65.30720499999995],[-84.75500499999987,65.31666600000011],[-84.76222199999995,65.326096],[-84.761124,65.33109999999999],[-84.75805699999995,65.33610500000003],[-84.75472999999994,65.34109500000005],[-84.745834,65.35137900000007],[-84.74027999999998,65.35636899999997],[-84.59583999999995,65.47554000000002],[-84.58555599999994,65.48109399999998],[-84.573624,65.48165900000004],[-84.56193499999995,65.48109399999998],[-84.54943799999995,65.47886699999998],[-84.44027699999992,65.45665000000008],[-84.43222000000003,65.45332300000013],[-84.42639200000002,65.44859300000007],[-84.424713,65.44386300000008],[-84.42582699999997,65.438873],[-84.314438,65.38165300000014],[-84.291946,65.37692300000009],[-84.16139199999992,65.34193400000004],[-84.15110799999991,65.338593],[-84.14750700000002,65.33387800000014],[-84.15306099999992,65.32859800000006],[-84.19415300000003,65.29748500000005],[-84.20195000000001,65.29220600000008],[-84.22083999999995,65.28471399999995],[-84.228882,65.2794340000001],[-84.23083499999996,65.26944000000009],[-84.22972099999998,65.26470899999998],[-84.141388,65.21998600000006],[-84.08833300000003,65.20387300000004],[-83.89999399999999,65.16554300000007],[-83.87609899999995,65.16276600000003],[-83.85278299999993,65.161652],[-83.66694599999994,65.16081199999996],[-83.62054399999994,65.16081199999996],[-83.54028299999993,65.16415400000011],[-83.52806099999998,65.16192599999994],[-83.408615,65.1355440000001],[-83.38806199999993,65.12664799999993],[-83.37887599999999,65.11720300000007],[-83.33805799999999,65.07470700000005],[-83.33473200000003,65.06999200000001],[-83.33583099999993,65.06498699999997],[-83.339447,65.0599820000001],[-83.34306300000003,65.04525800000005],[-83.34083599999997,65.03553799999997],[-83.33084099999996,65.02137800000008],[-83.31945799999994,65.0122070000001],[-83.20805399999995,64.94552600000009],[-83.19804399999987,64.9410860000001],[-83.19055200000003,64.93942300000015],[-83.156387,64.93997200000007],[-83.00500499999993,64.91303999999997],[-82.9927669999999,64.90971400000012],[-82.86582899999996,64.87359600000008],[-82.85583499999996,64.86914100000007],[-82.848053,64.86442600000004],[-82.84249899999992,64.85998500000011],[-82.82972699999999,64.84081999999995],[-82.82861300000002,64.83610499999992],[-82.825287,64.8313750000001],[-82.81639099999995,64.82193000000001],[-82.80027799999999,64.80886800000002],[-82.77000399999997,64.79553200000004],[-82.75778200000002,64.79109200000005],[-82.70916699999998,64.77638200000007],[-82.69722000000002,64.77388000000002],[-82.56973299999993,64.76388500000007],[-82.36138899999997,64.76361099999997],[-82.34944200000001,64.76026900000005],[-82.21194499999996,64.71832300000005],[-82.20222499999988,64.71360800000002],[-82.20333900000003,64.70860299999998],[-82.20916699999998,64.70359800000011],[-82.21749899999998,64.69859300000007],[-82.20361299999996,64.684418],[-82.064438,64.64860500000009],[-81.93249500000002,64.58442700000006],[-81.76306199999999,64.50109900000007],[-81.75389099999995,64.48692300000005],[-81.75140399999998,64.47248800000011],[-81.75306699999999,64.35582000000005],[-81.76417499999997,64.34109500000011],[-81.77000399999997,64.33610500000003],[-81.777222,64.326096],[-81.778885,64.32110599999999],[-81.777222,64.31164600000011],[-81.77416999999997,64.30664100000007],[-81.74888599999997,64.27360500000009],[-81.72721899999993,64.258331],[-81.712784,64.25000000000011],[-81.702789,64.2452550000001],[-81.66972399999997,64.2327580000001],[-81.646118,64.22554000000008],[-81.62249800000001,64.21666000000005],[-81.61305199999998,64.21220399999993],[-81.60028099999994,64.20277400000009],[-81.59445199999993,64.19331399999999],[-81.59083599999997,64.18359400000008],[-81.58999599999993,64.17886400000009],[-81.60249299999998,64.129974],[-81.61082499999998,64.125809],[-81.71777299999997,64.09942600000005],[-81.758621,64.08943200000004],[-81.76916499999993,64.08804300000003],[-81.82444799999996,64.08638000000008],[-81.87916599999994,64.08082600000012],[-81.95584099999996,64.0619200000001],[-81.96417199999996,64.0577550000001],[-81.97000099999997,64.05276500000002],[-81.97361799999993,64.04775999999998],[-81.99916099999996,64.00332600000002],[-81.99638400000003,63.998604000000114],[-81.98693800000001,63.994155999999975],[-81.97500599999995,63.99054699999999],[-81.96389799999997,63.98888400000004],[-81.95249899999993,63.98832700000014],[-81.93055699999996,63.98804500000006],[-81.89750700000002,63.98999000000009],[-81.87582399999991,63.991661000000136],[-81.56082200000003,64.02943399999998],[-81.44027699999998,64.06776400000007],[-81.38362099999995,64.09054600000002],[-81.28778099999988,64.08027600000008],[-81.27639799999997,64.07748399999997],[-81.27000399999991,64.072495],[-81.26417499999997,64.06275900000003],[-81.256958,64.059143],[-81.245544,64.05554200000012],[-80.96472199999994,63.99193600000012],[-80.94248999999996,63.99054699999999],[-80.931671,63.99193600000012],[-80.920837,63.99499500000013],[-80.91027799999989,63.999161000000015],[-80.90666199999993,64.00416600000005],[-80.90333599999997,64.01388500000007],[-80.90916399999998,64.02331500000014],[-80.91416899999996,64.02804600000007],[-80.92582699999997,64.03276100000011],[-80.94860799999998,64.03887900000007],[-80.96749899999992,64.04803499999997],[-80.972778,64.05276500000002],[-80.97555499999999,64.0577550000001],[-80.97389199999998,64.0624850000001],[-80.93582199999997,64.11192300000005],[-80.89083899999997,64.11554000000001],[-80.81221,64.09109499999994],[-80.77749599999987,64.0794370000001],[-80.73472600000002,64.0541530000001],[-80.56610099999995,63.994155999999975],[-80.54333500000001,63.98777000000007],[-80.531677,63.983330000000024],[-80.52250700000002,63.97860000000003],[-80.51750199999998,63.973877000000016],[-80.48832700000003,63.91054500000001],[-80.49221799999998,63.90554800000007],[-80.50306699999999,63.90248900000012],[-80.56750499999993,63.88943500000005],[-80.45306399999993,63.85943600000002],[-80.36305199999993,63.841102999999976],[-80.21722399999999,63.80998999999997],[-80.194481,63.804474000000084],[-80.18998699999997,63.799995000000024],[-80.17471299999988,63.780823],[-80.17222599999997,63.77610000000004],[-80.17166099999997,63.771102999999925],[-80.17887899999988,63.75666000000007],[-80.18499800000001,63.75166300000012],[-80.19583099999988,63.748604],[-80.34695399999998,63.72804299999996],[-80.35777299999995,63.728600000000085],[-80.36915599999998,63.73333000000008],[-80.38027999999997,63.73499300000003],[-80.39138799999995,63.73499300000003],[-80.402222,63.73471799999999],[-80.43443300000001,63.731102000000135],[-80.45417800000001,63.72776799999997],[-80.485275,63.71554600000002],[-80.493607,63.710274000000084],[-80.50473,63.69082600000013],[-80.506393,63.685822000000144],[-80.51000999999997,63.68110700000011],[-80.52194199999991,63.67110400000007],[-80.587784,63.635826000000066],[-80.60888699999998,63.628326000000015],[-80.77444500000001,63.57332600000012],[-80.912216,63.526381999999955],[-80.92250100000001,63.52137800000003],[-80.93055700000002,63.51610600000009],[-80.93638599999991,63.51110800000009],[-80.93804899999986,63.50638600000002],[-80.9375,63.501389000000074],[-80.93443300000001,63.49665800000014],[-80.93055700000002,63.482208000000014],[-80.93028299999997,63.47748600000011],[-80.9375,63.46749100000005],[-80.95805399999995,63.45832800000005],[-80.968613,63.455269000000044],[-80.989441,63.450829000000056],[-81.011124,63.44915800000001],[-81.03277599999996,63.44860100000011],[-81.05444299999999,63.44915800000001],[-81.07640100000003,63.451385000000016],[-81.11000099999995,63.45832800000005],[-81.38612399999994,63.526381999999955],[-81.69415300000003,63.607498000000135],[-81.73416099999997,63.62554900000009],[-81.75723299999999,63.63472000000007],[-81.76889,63.63804600000009],[-81.77999899999998,63.63971700000013],[-81.80194099999994,63.64110599999998],[-81.823624,63.639435000000105],[-81.85527000000002,63.63249200000007],[-81.87666299999995,63.62999000000002],[-81.88751200000002,63.62943300000012],[-81.90972899999991,63.631935],[-81.99527,63.66110200000014],[-82.01167299999986,63.667213000000004],[-82.02639799999997,63.676383999999985],[-82.03138699999994,63.68110700000011],[-82.04110700000001,63.685822000000144],[-82.05249000000003,63.68915600000014],[-82.06361400000003,63.69082600000013],[-82.10777299999995,63.69221499999992],[-82.12943999999999,63.69165800000002],[-82.21417200000002,63.68776699999995],[-82.22471599999989,63.68637799999999],[-82.285553,63.67804700000005],[-82.29611199999994,63.67471300000011],[-82.29943799999995,63.669715999999994],[-82.29888900000003,63.66499299999998],[-82.30221599999999,63.65998799999994],[-82.30776999999995,63.65499100000005],[-82.31834400000002,63.65165700000006],[-82.32888799999995,63.65026899999998],[-82.33999599999987,63.65082600000005],[-82.35139500000002,63.65332000000001],[-82.47222899999991,63.68027500000005],[-82.48388699999998,63.68471500000004],[-82.4911039999999,63.68915600000014],[-82.535278,63.72637899999995],[-82.54583699999995,63.7355500000001],[-82.54972800000002,63.745270000000005],[-82.55082700000003,63.75000000000006],[-82.54695100000004,63.76471700000002],[-82.54333499999996,63.769714000000135],[-82.53222699999998,63.77999100000011],[-82.51445000000001,63.79027600000006],[-82.504456,63.795547000000056],[-82.48416099999997,63.804993000000024],[-82.47361799999993,63.80832700000002],[-82.43194599999998,63.82027399999998],[-82.420837,63.820831000000055],[-82.40972899999997,63.81916000000001],[-82.39805599999988,63.815826000000015],[-82.38667299999997,63.814156000000025],[-82.37638900000002,63.81749700000006],[-82.372772,63.82249500000006],[-82.35388199999994,63.852219000000105],[-82.35139500000002,63.861938000000066],[-82.35833699999995,63.90054300000003],[-82.36138899999997,63.90526599999998],[-82.36888099999999,63.90998800000011],[-82.37832599999996,63.91443600000008],[-82.41389499999997,63.926941],[-82.52583300000003,63.96610300000003],[-82.54888899999997,63.96915400000006],[-82.82861300000002,63.979431000000034],[-82.96722399999999,63.96554600000013],[-82.97805800000003,63.96305100000012],[-83.06416299999995,63.95193499999999],[-83.08694499999996,63.95499400000011],[-83.09889199999992,63.959160000000054],[-83.12388599999997,63.97276300000004],[-83.12916599999994,63.977486000000056],[-83.14527900000002,64.00109900000012],[-83.139725,64.006104],[-83.09555099999989,64.02832000000001],[-83.029449,64.0747070000001],[-83.01611300000002,64.08499100000012],[-82.99694799999997,64.10026600000009],[-82.98028599999998,64.11554000000001],[-82.97084000000001,64.12553400000002],[-82.9619449999999,64.13581800000003],[-82.960556,64.14054899999996],[-82.96166999999997,64.1455380000001],[-82.964722,64.15026900000004],[-83.00834699999996,64.18748499999998],[-83.01972999999998,64.18887300000006],[-83.07278399999996,64.18664600000005],[-83.10526999999996,64.18165599999998],[-83.12638899999996,64.17581199999995],[-83.15722700000003,64.16304000000014],[-83.339447,64.13472000000013],[-83.48832700000003,64.12248200000005],[-83.51972999999998,64.11442599999998],[-83.53028899999993,64.11109900000008],[-83.54834,64.10247800000013],[-83.67332499999998,64.01721200000003],[-83.68222000000003,64.00721700000008],[-83.68331899999998,64.00221299999993],[-83.67666600000001,63.99276699999996],[-83.66583300000002,63.98360399999996],[-83.64250199999998,63.96998600000012],[-83.62609900000001,63.95609999999999],[-83.608612,63.93749200000008],[-83.60555999999997,63.932770000000005],[-83.60417199999995,63.92804700000005],[-83.5958399999999,63.825829000000056],[-83.59666400000003,63.820831000000055],[-83.62304699999993,63.78166199999998],[-83.63194299999986,63.77166],[-83.63722200000001,63.76638800000006],[-83.64750700000002,63.763054000000125],[-83.65861499999994,63.763611000000026],[-83.67027299999995,63.76693700000004],[-83.69444299999998,63.77582600000011],[-83.718613,63.77999100000011],[-83.74055499999997,63.77999100000011],[-83.75083899999998,63.776657000000114],[-83.82417299999997,63.74749000000003],[-84.00723299999999,63.66805300000004],[-84.01278699999989,63.662765999999976],[-84.02111799999994,63.65277100000003],[-84.02749599999993,63.642769000000044],[-84.05027799999993,63.62693800000011],[-84.069458,63.61638600000009],[-84.079453,63.61193800000012],[-84.089447,63.60777300000012],[-84.09973100000002,63.60527000000013],[-84.11000099999995,63.60360700000007],[-84.12138399999998,63.60416399999997],[-84.132767,63.60665899999998],[-84.14472999999992,63.610825000000034],[-84.162216,63.61971300000005],[-84.17416400000002,63.62304700000004],[-84.19638099999992,63.62499200000002],[-84.261124,63.62082700000002],[-84.28611799999999,63.615546999999935],[-84.38806199999999,63.55915800000008],[-84.39527900000002,63.55387900000011],[-84.40055799999999,63.548607000000004],[-84.44638099999997,63.488045],[-84.44943199999989,63.483047],[-84.45222499999994,63.47248800000011],[-84.44722000000002,63.45332300000001],[-84.44915799999995,63.44360399999999],[-84.47749299999998,63.3836060000001],[-84.56332399999997,63.33749400000005],[-84.754456,63.26416000000006],[-84.77417000000003,63.25721700000008],[-84.79388399999999,63.25027499999999],[-84.823059,63.23721300000011],[-84.841949,63.22721100000001],[-84.870834,63.214157000000114],[-84.89056399999998,63.20721400000008],[-85.14334100000002,63.13999200000006],[-85.22416699999997,63.12082700000013],[-85.24499500000002,63.11859899999996],[-85.26640299999997,63.11749300000014],[-85.28805499999999,63.11832400000014],[-85.34333800000002,63.12276500000007],[-85.37582399999991,63.123877999999934],[-85.39695699999993,63.12276500000007],[-85.44915800000001,63.11666100000002],[-85.48222399999997,63.11859899999996],[-85.49333199999995,63.119987000000094],[-85.50500499999998,63.12304699999993],[-85.53639199999992,63.134995],[-85.54388399999993,63.138329],[-85.57778899999994,63.16554300000013],[-85.58917199999996,63.174713],[-85.59249899999998,63.17943600000001],[-85.63806199999993,63.244995000000074],[-85.63917500000002,63.24971800000009],[-85.64834599999995,63.33554799999996],[-85.65388499999995,63.408882000000006],[-85.65083300000003,63.42860400000001],[-85.644455,63.44360399999999],[-85.63583399999999,63.45860300000004],[-85.6260989999999,63.46888000000001],[-85.61805700000002,63.4791560000001],[-85.60722399999986,63.494438000000116],[-85.60499599999997,63.50916300000006],[-85.59111000000001,63.617493000000024],[-85.59333799999996,63.631935],[-85.59611499999994,63.64138000000008],[-85.60749799999996,63.665268000000026],[-85.61332699999997,63.669715999999994],[-85.71749899999998,63.71610300000009],[-85.87943999999999,63.704711999999915],[-85.98582499999992,63.69332099999997],[-86.01722699999993,63.68832400000008],[-86.18360899999993,63.653046000000074],[-86.22444199999995,63.642769000000044],[-86.24499500000002,63.639435000000105],[-86.26695299999994,63.63804600000009],[-86.30027799999993,63.63971700000013],[-86.346115,63.64554600000014],[-86.38137799999998,63.65221400000013],[-86.45028699999989,63.66054500000001],[-86.55277999999987,63.670273000000066],[-86.56361400000003,63.670547],[-86.59611499999994,63.66860200000002],[-86.626938,63.66165900000004],[-86.66639700000002,63.64833100000004],[-86.69444299999992,63.63360600000004],[-86.73388699999998,63.60665899999998],[-86.75917099999998,63.59027100000009],[-86.77806099999992,63.581108000000086],[-86.80749500000002,63.571380999999974],[-86.837784,63.563323999999966],[-86.847778,63.56082200000009],[-86.879166,63.55554999999998],[-86.92222599999997,63.55277300000006],[-87.05055199999998,63.54972099999998],[-87.083618,63.550270000000125],[-87.09527599999996,63.5513840000001],[-87.118607,63.55582400000009],[-87.141388,63.563881000000094],[-87.14973399999991,63.56832900000006],[-87.18804899999986,63.589989],[-87.21722399999999,63.6222150000001],[-87.222778,63.63166000000001],[-87.22639499999997,63.64110599999998],[-87.225281,63.651099999999985],[-87.22193900000002,63.6658250000001],[-87.21888699999994,63.67582700000008],[-87.21083099999998,63.69110099999995],[-87.20083599999987,63.70665700000012],[-87.18666100000002,63.72221399999995],[-87.16111799999993,63.743607000000054],[-86.94387799999993,63.90054300000003],[-86.93443299999996,63.906097000000045],[-86.91528299999999,63.91443600000008],[-86.87582399999997,63.92860400000012],[-86.78416399999998,63.95694000000003],[-86.76362599999999,63.962212000000136],[-86.700287,63.97221400000012],[-86.66860999999989,63.978324999999984],[-86.5038909999999,64.018326],[-86.41361999999998,64.04859899999997],[-86.25500499999993,64.07609600000006],[-86.233612,64.0794370000001],[-86.22332799999998,64.08194000000009],[-86.21333300000003,64.08554100000015],[-86.203888,64.09109499999994],[-86.18943799999988,64.101654],[-86.17832899999996,64.12191800000011],[-86.178879,64.13165300000003],[-86.18222000000003,64.1413730000001],[-86.212219,64.17858900000004],[-86.25306699999999,64.20054600000009],[-86.27389499999998,64.20887800000008],[-86.30055199999998,64.22192400000006],[-86.30888400000003,64.22637900000007],[-86.3125,64.23082],[-86.35472099999998,64.28997800000013],[-86.38417099999998,64.36442599999998],[-86.40167200000002,64.436646],[-86.40110799999997,64.44164999999992],[-86.38362099999995,64.56498700000009],[-86.36888099999999,64.62942499999997],[-86.31555200000003,64.70109600000006],[-86.27250699999996,64.76805100000001],[-86.24888599999997,64.79386899999992],[-86.23889199999996,64.80415299999999],[-86.23138399999993,64.80941800000005],[-86.221115,64.81303400000007],[-86.21028099999995,64.81469700000002],[-86.19860799999992,64.81442300000009],[-86.18721,64.81526200000002],[-86.17666599999995,64.81776400000012],[-86.17166099999992,64.82304399999998],[-86.15249599999993,64.91804500000006],[-86.151947,64.92303500000008],[-86.15333599999991,64.92776500000014],[-86.15722699999998,64.93248],[-86.181107,64.95555100000001],[-86.18721,64.959991],[-86.21250900000001,64.96638500000006],[-86.22084000000001,64.97053500000004],[-86.22639499999997,64.97998000000013],[-86.22778299999999,64.98387100000002],[-86.22582999999997,64.99859600000013],[-86.22500600000001,65.003601],[-86.212219,65.03387500000008],[-86.20638999999989,65.04386900000009],[-86.19833399999999,65.0541530000001],[-86.18998699999992,65.06442300000003],[-86.18472300000002,65.06971700000003],[-86.16528299999993,65.08055100000007],[-86.14472999999998,65.08859300000006],[-86.13833599999992,65.09443700000003],[-86.13806199999999,65.099426],[-86.13555899999994,65.1827550000001],[-86.13722199999995,65.19775399999997],[-86.141953,65.2122040000001],[-86.146118,65.21666000000005],[-86.15139799999997,65.22637900000001],[-86.16416899999996,65.25000000000011],[-86.17054699999994,65.26915000000008],[-86.17166099999992,65.27886999999998],[-86.15333599999991,65.38472000000007],[-86.14973399999997,65.39471400000008],[-86.11193799999995,65.49414100000001],[-86.09777799999995,65.5291600000001],[-86.01390099999998,65.70915200000007],[-86.01000999999991,65.7149960000001],[-85.99388099999999,65.730545],[-85.98277300000001,65.74081400000006],[-85.97528099999988,65.74609400000008],[-85.88833599999998,65.79998799999993],[-85.83250399999991,65.83248900000007],[-85.791382,65.85331700000012],[-85.770554,65.86219800000003],[-85.72833300000002,65.87942500000008],[-85.69665499999991,65.89193700000004],[-85.62110899999993,65.91748000000001],[-85.56527699999998,65.93026700000001],[-85.54249600000003,65.9333190000001],[-85.50666799999999,65.93441800000005],[-85.49388099999999,65.93220500000012],[-85.49101300000001,65.93106099999994],[-85.48277300000001,65.92776500000008],[-85.476944,65.92330900000002],[-85.46888699999994,65.91387900000012],[-85.46972699999998,65.90887499999997],[-85.47389199999998,65.89888000000008],[-85.48889200000002,65.8785860000001],[-85.511124,65.85775800000005],[-85.520554,65.84275800000006],[-85.52362099999999,65.82304399999998],[-85.520554,65.81330900000006],[-85.516663,65.80859400000003],[-85.510559,65.80415299999993],[-85.49333199999995,65.7952580000001],[-85.48055999999997,65.79193099999998]],[[-62.13666499999994,65.85137900000001],[-62.141669999999976,65.84971600000006],[-62.15444200000002,65.85081500000007],[-62.162216,65.8541560000001],[-62.210830999999985,65.88053900000006],[-62.29695099999998,65.92776500000008],[-62.29666900000001,65.93858300000005],[-62.281386999999995,65.94636500000001],[-62.26500699999997,65.94693000000007],[-62.230552999999986,65.94386299999996],[-62.167220999999984,65.93275499999999],[-62.13777900000002,65.92581199999995],[-62.139725,65.91304000000014],[-62.118607,65.88108799999998],[-62.12999699999989,65.85914600000012],[-62.13666499999994,65.85137900000001]],[[-67.13833599999998,65.92692599999998],[-67.14584400000001,65.92637600000012],[-67.15444899999994,65.92886400000009],[-67.16111799999999,65.93220500000012],[-67.18527199999994,65.94831799999997],[-67.20916699999992,65.97886700000004],[-67.21194500000001,65.9827580000001],[-67.20889299999999,65.98442100000005],[-67.19915800000001,65.98637399999996],[-67.18138099999987,65.98719800000009],[-67.16694599999994,65.984985],[-67.153885,65.97859199999999],[-67.15278599999999,65.97499099999999],[-67.15260299999989,65.970734],[-67.13444500000003,65.93304400000005],[-67.13473499999992,65.93026700000001],[-67.13833599999998,65.92692599999998]],[[-83.57695000000001,65.98304700000006],[-83.58860799999997,65.98165899999992],[-83.60082999999986,65.98332200000004],[-83.604446,65.98776200000009],[-83.60082999999986,65.99304200000012],[-83.58889799999997,66.00305200000003],[-83.57000700000003,66.01361100000008],[-83.54750099999995,66.01944000000009],[-83.51139799999999,66.01998900000007],[-83.49888599999991,66.01748699999996],[-83.49305699999996,66.01277199999993],[-83.50140399999998,66.00749200000007],[-83.51000999999997,66.00332599999996],[-83.55444299999994,65.98887600000006],[-83.57695000000001,65.98304700000006]],[[-84.72277799999995,65.54609700000009],[-84.73388699999998,65.54470800000013],[-84.74610899999993,65.5458220000001],[-84.78472899999997,65.55664099999996],[-84.803604,65.56553600000001],[-84.82861299999996,65.57887300000004],[-84.84083599999997,65.58804300000008],[-84.84805299999988,65.597488],[-84.85333300000002,65.60693400000014],[-84.85221899999993,65.6119230000001],[-84.85777299999995,65.645828],[-84.85888699999992,65.65081800000007],[-84.86639399999996,65.65998800000011],[-84.878601,65.66914400000007],[-84.90028399999994,65.67804000000001],[-85.02860999999996,65.71165500000006],[-85.06304899999992,65.72331200000002],[-85.07389799999999,65.72776800000008],[-85.08222999999998,65.73220800000013],[-85.10694899999993,65.75054899999992],[-85.11805700000002,65.76470900000004],[-85.18194599999998,65.94552600000009],[-85.17304999999993,65.99470500000007],[-85.14388999999994,66.02110300000004],[-85.13722200000001,66.02331500000008],[-85.08167999999995,66.026657],[-85.05749500000002,66.02609300000006],[-84.9375,66.01054399999998],[-84.924713,66.00804099999999],[-84.91027799999989,66.00000000000011],[-84.88722199999995,65.94552600000009],[-84.88333099999988,65.94081100000005],[-84.80777,65.89582800000011],[-84.75500499999987,65.85331700000012],[-84.71611000000001,65.81721500000015],[-84.71417199999996,65.80720500000007],[-84.71278399999994,65.80220000000003],[-84.70777900000002,65.79275500000011],[-84.63722200000001,65.71220399999999],[-84.59750399999996,65.69664000000012],[-84.58667000000003,65.69220000000007],[-84.57417299999992,65.63916],[-84.57611099999997,65.6291500000001],[-84.58500699999996,65.61914100000007],[-84.59861799999993,65.60859700000003],[-84.66776999999996,65.56053200000002],[-84.72277799999995,65.54609700000009]],[[-83.608612,66.04414400000007],[-83.64222699999999,66.03498800000011],[-83.652222,66.03665200000012],[-83.6536099999999,66.04136699999998],[-83.64750700000002,66.04664600000012],[-83.64416499999999,66.05165099999999],[-83.62609900000001,66.0669400000001],[-83.61805699999996,66.07222000000013],[-83.60722399999997,66.07748400000014],[-83.597778,66.0788730000001],[-83.583618,66.07054099999993],[-83.577789,66.06581100000011],[-83.57084700000001,66.05636600000003],[-83.57444799999996,66.051376],[-83.58555599999994,66.04803500000014],[-83.59722899999997,66.04664600000012],[-83.608612,66.04414400000007]],[[-85.01916499999999,66.05720500000001],[-85.13555899999994,66.04443400000008],[-85.14778100000001,66.04582199999999],[-85.14917000000003,66.05053700000002],[-85.10777300000001,66.08442700000012],[-85.09973100000002,66.08970600000009],[-85.06332399999997,66.08776900000004],[-85.03860499999996,66.08610500000003],[-85.0161129999999,66.07971200000009],[-85.00862099999995,66.07054099999993],[-85.00695799999994,66.06553600000007],[-85.01028399999996,66.06053199999997],[-85.01916499999999,66.05720500000001]],[[-83.6494449999999,66.08360299999998],[-83.66111799999999,66.08194000000003],[-83.67361499999998,66.08332799999994],[-83.69249000000002,66.0913700000001],[-83.69610599999999,66.09609999999998],[-83.68998699999997,66.11109900000002],[-83.68527199999994,66.12109399999991],[-83.678879,66.12525900000014],[-83.60665899999998,66.12414600000005],[-83.59388699999994,66.12164300000006],[-83.587784,66.11720300000007],[-83.5916749999999,66.11219799999998],[-83.604446,66.10582000000005],[-83.61054999999993,66.10165399999994],[-83.63806199999999,66.086929],[-83.6494449999999,66.08360299999998]],[[-83.92138699999998,66.00972000000002],[-83.73083499999996,65.94775400000003],[-83.70584099999996,65.93414300000006],[-83.69415299999997,65.92469799999998],[-83.68331899999998,65.91053800000009],[-83.68083200000001,65.901093],[-83.68916300000001,65.86665300000004],[-83.69972199999995,65.85137900000001],[-83.71389799999997,65.84109499999994],[-83.72471599999994,65.83692900000005],[-83.73582499999992,65.83360300000004],[-83.72749299999992,65.79971300000011],[-83.52500899999995,65.73776199999992],[-83.36000100000001,65.72747800000008],[-83.348053,65.72692899999998],[-83.25111400000003,65.71693400000004],[-83.226944,65.71415700000011],[-83.214447,65.71054100000009],[-83.21083099999987,65.70582600000006],[-83.25111400000003,65.65470900000014],[-83.25944500000003,65.64942900000005],[-83.28889499999997,65.63275099999998],[-83.29972799999996,65.62942499999997],[-83.31111099999998,65.62719699999997],[-83.34500099999997,65.62081900000004],[-83.379166,65.61554000000007],[-83.39138799999995,65.61720300000013],[-83.39917000000003,65.62081900000004],[-83.406113,65.63026400000007],[-83.41194200000001,65.63472000000002],[-83.41999800000002,65.63943500000005],[-83.43055700000002,65.64387500000004],[-83.44332899999995,65.64804100000015],[-83.46861299999995,65.65498400000013],[-83.49305699999996,65.65776100000005],[-83.50500499999993,65.65832499999999],[-83.52861000000001,65.65832499999999],[-83.59889199999998,65.65637200000003],[-83.66027799999995,65.64721700000001],[-83.82972699999999,65.64498900000001],[-83.84277299999991,65.64915500000012],[-83.84611499999994,65.65386999999998],[-83.84973100000002,65.66832000000011],[-83.84638999999999,65.67330900000007],[-83.84056099999987,65.6785890000001],[-83.79415899999998,65.71943700000003],[-83.78582799999998,65.72470099999998],[-83.77500900000001,65.72804300000013],[-83.74082899999996,65.7333220000001],[-83.69526699999994,65.74108900000004],[-83.68415800000002,65.74443100000002],[-83.68276999999995,65.74941999999999],[-83.68888899999996,65.75416600000005],[-83.785278,65.78887900000007],[-83.79750100000001,65.7894290000001],[-83.80888399999998,65.78804000000008],[-83.84973100000002,65.78054800000012],[-83.90583799999996,65.76748700000002],[-83.92749000000003,65.75972000000007],[-83.93804899999998,65.74443100000002],[-83.94860799999992,65.74026500000008],[-83.96000700000002,65.73776199999992],[-83.97166400000003,65.73719800000015],[-83.98388699999992,65.73858600000005],[-84.071121,65.75],[-84.12054399999994,65.75833100000006],[-84.13333099999994,65.76081799999997],[-84.14361599999995,65.76416000000006],[-84.14500399999997,65.76914999999997],[-84.141388,65.77415500000001],[-84.11721799999998,65.78970300000003],[-84.11138899999997,65.79498300000006],[-84.10333300000002,65.80998199999993],[-84.10110500000002,65.81971700000003],[-84.12361099999993,65.90026900000004],[-84.189438,65.968323],[-84.19804399999992,65.97303800000003],[-84.20861799999989,65.97720300000003],[-84.28639199999998,65.999146],[-84.29943800000001,66.00248700000003],[-84.31138599999997,66.00305200000003],[-84.32333399999999,66.00248700000003],[-84.358047,65.99775699999998],[-84.36999500000002,65.99720800000006],[-84.38276699999994,66.00054900000009],[-84.42416399999996,66.02804600000002],[-84.43611099999993,66.0372010000001],[-84.464447,66.06025700000009],[-84.46806299999997,66.06498699999997],[-84.46916199999998,66.06999200000001],[-84.47000100000002,66.08943199999999],[-84.471115,66.12831100000005],[-84.47027599999996,66.13333100000011],[-84.464447,66.13832100000013],[-84.45584100000002,66.14166300000005],[-84.43306000000001,66.13888500000007],[-84.381104,66.12914999999998],[-84.36805699999991,66.12580899999995],[-84.24027999999993,66.0983280000001],[-84.14639299999988,66.08109999999999],[-84.03944399999995,66.07693499999999],[-84.00167799999997,66.03360000000004],[-83.92138699999998,66.00972000000002]],[[-84.57972699999999,66.14137300000004],[-84.62748699999992,66.13916000000012],[-84.63999899999999,66.14054900000008],[-84.648346,66.14498900000012],[-84.654449,66.14942900000011],[-84.67582700000003,66.17303500000003],[-84.678604,66.18248000000006],[-84.66722099999993,66.18498199999999],[-84.61888099999999,66.17665100000005],[-84.59333799999996,66.17109700000009],[-84.589447,66.16638200000006],[-84.57444800000002,66.147491],[-84.57972699999999,66.14137300000004]],[[-84.265289,66.17776500000002],[-84.276947,66.17526200000009],[-84.28916900000002,66.17553700000008],[-84.30139199999996,66.1769260000001],[-84.31388900000002,66.17942800000014],[-84.35333300000002,66.19026200000002],[-84.36193799999995,66.19470200000006],[-84.36444099999994,66.20443699999993],[-84.36361699999998,66.209427],[-84.36000100000001,66.21443200000004],[-84.348343,66.21582000000012],[-84.33583099999998,66.21443200000004],[-84.30972300000002,66.20776400000005],[-84.29916400000002,66.20332299999995],[-84.27305599999994,66.19664],[-84.26445000000001,66.19219999999996],[-84.25834700000001,66.18775900000009],[-84.256958,66.1827550000001],[-84.265289,66.17776500000002]],[[-62.183883999999864,66.23719800000009],[-62.199164999999994,66.21693399999992],[-62.40499899999986,66.21859700000005],[-62.415276000000006,66.21914700000008],[-62.42166899999995,66.22221400000001],[-62.42999999999995,66.2291560000001],[-62.4266659999999,66.233047],[-62.419167000000016,66.23776200000003],[-62.31945000000002,66.26944000000003],[-62.301941,66.27499400000005],[-62.287223999999924,66.27804600000013],[-62.278336000000024,66.27970900000008],[-62.26167299999997,66.28027300000002],[-62.24888599999997,66.27859500000011],[-62.24305700000002,66.27693199999999],[-62.231383999999935,66.26944000000003],[-62.183883999999864,66.23719800000009]],[[-83.06722999999988,66.25555400000007],[-83.05499299999991,66.25499000000013],[-83.04305999999997,66.25526400000007],[-83.031113,66.25665300000003],[-83.019455,66.25915500000013],[-82.99694799999997,66.26582300000007],[-82.96083099999998,66.27249100000006],[-82.93720999999994,66.27526900000004],[-82.91332999999986,66.276093],[-82.90249599999999,66.27165200000013],[-82.90417500000001,66.26666299999994],[-82.910278,66.26165800000007],[-82.91861,66.25749200000001],[-82.92971799999998,66.25221300000004],[-82.93554699999993,66.25138900000007],[-82.99027999999998,66.203598],[-82.99638400000003,66.19859300000013],[-83.00778200000002,66.19525099999998],[-83.01972999999998,66.19497700000005],[-83.08029199999999,66.19664],[-83.09306299999997,66.19886800000012],[-83.26333599999998,66.247208],[-83.287216,66.25610400000011],[-83.29333500000001,66.2605440000001],[-83.29666099999997,66.26527399999998],[-83.297775,66.270264],[-83.29833999999988,66.31387300000011],[-83.28500400000001,66.32916300000011],[-83.273056,66.3394320000001],[-83.26417500000002,66.3435970000001],[-83.252228,66.34498600000012],[-83.226944,66.33998100000008],[-83.21611000000001,66.33554100000003],[-83.20472699999993,66.31666600000011],[-83.17388900000003,66.28858900000012],[-83.16805999999991,66.28387499999997],[-83.06722999999988,66.25555400000007]],[[-66.62332200000003,66.28082300000005],[-66.64195299999994,66.27943400000004],[-66.65695199999993,66.28027300000002],[-66.66749599999997,66.282761],[-66.678879,66.286926],[-66.70140099999998,66.29776000000004],[-66.74194299999988,66.3163760000001],[-66.84306300000003,66.36248799999998],[-66.9058379999999,66.37664800000005],[-66.91610700000001,66.37997400000012],[-66.94471699999997,66.39498900000007],[-66.95611599999995,66.40193200000004],[-66.95861799999994,66.40637200000009],[-66.95834400000001,66.41192600000005],[-66.95527600000003,66.41360500000008],[-66.94444299999992,66.41387900000001],[-66.85194399999995,66.40220599999998],[-66.82972699999999,66.39833099999998],[-66.823059,66.39276100000012],[-66.82084699999996,66.38804600000009],[-66.80110199999996,66.37553400000007],[-66.78222700000003,66.36914100000013],[-66.726944,66.35498000000013],[-66.70556599999998,66.34971599999994],[-66.67832900000002,66.34553500000004],[-66.662216,66.3435970000001],[-66.65028399999994,66.34304800000001],[-66.639725,66.34054600000007],[-66.62388599999997,66.33526600000005],[-66.58444199999997,66.3205410000001],[-66.57501200000002,66.31387300000011],[-66.573624,66.31080600000001],[-66.59167500000001,66.29359399999998],[-66.60526999999996,66.28665200000006],[-66.62332200000003,66.28082300000005]],[[-66.99833699999994,66.493042],[-66.99027999999998,66.48915099999994],[-66.97610499999996,66.48915099999994],[-66.96333299999998,66.48719800000003],[-66.87332199999997,66.46859699999999],[-66.86888099999999,66.46443199999999],[-66.87138400000003,66.46054100000009],[-66.87805200000003,66.458328],[-66.93611099999993,66.44552599999997],[-66.94888300000002,66.444702],[-66.987213,66.44525099999993],[-67.03028899999993,66.45248400000014],[-67.03666699999997,66.45609999999999],[-67.03832999999997,66.47248800000006],[-67.03805499999999,66.47804300000013],[-67.035278,66.48471100000012],[-67.02500899999995,66.48997500000013],[-67.00695799999988,66.493042],[-66.99833699999994,66.493042]],[[-107.92304999999993,66.85054000000002],[-107.9349979999999,66.84915200000012],[-107.94611399999991,66.85108900000012],[-107.94554099999993,66.85693400000002],[-107.837784,67.00387599999999],[-107.83029199999993,67.00860600000004],[-107.81696299999993,67.00915500000013],[-107.80666400000001,67.00582900000012],[-107.79499800000002,66.997208],[-107.79110699999995,66.98831200000006],[-107.78971899999999,66.98525999999998],[-107.79055800000003,66.97970599999996],[-107.82389799999999,66.901093],[-107.83000199999992,66.8955380000001],[-107.89499699999999,66.86080900000002],[-107.90360999999996,66.85693400000002],[-107.92304999999993,66.85054000000002]],[[-108.01445000000001,66.89776600000005],[-108.025284,66.8955380000001],[-108.03859699999998,66.89721700000013],[-108.04444899999993,66.90138200000013],[-108.09638999999993,66.96748400000001],[-108.097778,66.97276299999999],[-108.10659799999996,67.02600100000006],[-108.06360599999988,67.00109900000007],[-107.93831599999999,66.94693000000007],[-107.95944199999991,66.93165599999998],[-107.96665999999993,66.9266510000001],[-108.00583599999987,66.90193199999993],[-108.01445000000001,66.89776600000005]],[[-63.059166000000005,66.95776400000011],[-63.083327999999995,66.95498700000002],[-63.09555099999994,66.955826],[-63.11694299999999,66.96304300000008],[-63.136391,66.9747010000001],[-63.16305499999993,66.99525500000004],[-63.165549999999996,66.99914599999994],[-63.166106999999954,67.00499000000013],[-63.159163999999976,67.01554900000002],[-63.15416699999997,67.02137800000003],[-63.14444699999996,67.02886999999998],[-63.12749499999995,67.03359999999998],[-63.12305500000002,67.03471399999995],[-63.1108319999999,67.03387500000002],[-63.1016689999999,67.02970900000008],[-63.098052999999936,67.02720599999998],[-63.097778000000005,67.02331500000008],[-63.02111100000002,66.996643],[-63.01167299999997,66.99247700000006],[-63.00389099999995,66.988586],[-62.999999999999886,66.984421],[-62.999442999999985,66.97859199999999],[-63.002228,66.97554000000008],[-63.020835999999974,66.966385],[-63.04000099999996,66.96081500000014],[-63.059166000000005,66.95776400000011]],[[-62.918334999999956,67.00972000000002],[-62.93804899999998,67.00582900000012],[-62.97777599999995,67.00665300000009],[-63.009727,67.009995],[-63.03778099999994,67.01582300000013],[-63.06833599999999,67.02554300000003],[-63.092772999999966,67.03581200000008],[-63.12388599999997,67.04914900000011],[-63.135559,67.05470300000007],[-63.138892999999996,67.05941800000011],[-63.13805400000001,67.06526200000013],[-63.13583399999999,67.06971699999997],[-63.130279999999914,67.07415800000007],[-63.11721799999998,67.0788730000001],[-63.11055799999997,67.08027600000003],[-63.10008199999993,67.07971200000009],[-63.002228,67.06944300000004],[-62.97833300000002,67.06275900000014],[-62.961112999999955,67.05470300000007],[-62.941108999999926,67.04359399999998],[-62.922500999999954,67.03109700000005],[-62.914444,67.02304100000015],[-62.912215999999944,67.01470899999998],[-62.918334999999956,67.00972000000002]],[[-62.64416499999993,67.05748],[-62.64694999999995,67.04998800000004],[-62.65166499999998,67.04693600000013],[-62.75250199999999,67.01054399999998],[-62.764449999999954,67.00915500000013],[-62.782775999999956,67.00943000000001],[-62.81305699999996,67.0169370000001],[-62.832222,67.02442900000005],[-62.899445000000014,67.05831899999998],[-62.89459999999997,67.05911300000008],[-62.865005,67.05748],[-62.82028200000002,67.05581700000005],[-62.81027999999998,67.05693100000002],[-62.80666400000001,67.05914300000012],[-62.70286900000002,67.12868500000008],[-62.652221999999995,67.16609199999999],[-62.64194500000002,67.174149],[-62.631942999999865,67.17692600000004],[-62.547782999999924,67.18609600000013],[-62.533889999999985,67.18719500000009],[-62.42527799999999,67.19108599999998],[-62.41805999999997,67.19081099999994],[-62.37888299999986,67.16970800000007],[-62.37527499999993,67.165817],[-62.376105999999936,67.1644290000001],[-62.38805400000001,67.15748600000006],[-62.44361099999992,67.13581799999997],[-62.45194200000003,67.13275100000004],[-62.47249599999998,67.12608300000005],[-62.50417299999992,67.11943099999996],[-62.538612,67.11387600000006],[-62.56944999999996,67.10582],[-62.58000199999998,67.10220300000009],[-62.59610699999996,67.09220900000003],[-62.631667999999934,67.06999199999996],[-62.63861099999991,67.06387300000011],[-62.64416499999993,67.05748]],[[-107.40778399999999,67.083054],[-107.49054699999999,67.07138099999997],[-107.50639299999995,67.07249500000012],[-107.51750199999987,67.07470699999999],[-107.52778599999999,67.07804899999996],[-107.54972800000002,67.08998100000008],[-107.56500199999999,67.10331700000006],[-107.57444799999996,67.11219800000015],[-107.58389299999988,67.12136800000002],[-107.59110999999996,67.13081399999999],[-107.62917299999992,67.18331900000004],[-107.63054699999992,67.188583],[-107.62970699999988,67.19413800000007],[-107.62666300000001,67.2002720000001],[-107.62053700000001,67.20610000000005],[-107.608337,67.20748900000001],[-107.59777799999995,67.204163],[-107.58168,67.19636500000013],[-107.57584400000002,67.19220000000013],[-107.56194299999987,67.18386800000013],[-107.51000999999991,67.15637200000009],[-107.47778299999993,67.14082300000001],[-107.46193700000003,67.13333100000006],[-107.443604,67.12608300000005],[-107.412781,67.11581400000006],[-107.40055799999993,67.11303700000013],[-107.40778399999999,67.083054]],[[-95.36166399999996,67.19775400000015],[-95.37361099999993,67.19636500000013],[-95.40055799999993,67.197205],[-95.41528299999999,67.1997070000001],[-95.4308319999999,67.20277399999998],[-95.52749599999993,67.22303799999997],[-95.54333499999996,67.22637900000001],[-95.55139200000002,67.23027000000008],[-95.55277999999993,67.2352600000001],[-95.54222099999998,67.23858599999994],[-95.39111299999996,67.26304600000014],[-95.37777699999992,67.26277200000004],[-95.31723,67.25555400000002],[-95.30722000000003,67.25248699999992],[-95.30583200000001,67.24775700000009],[-95.30943299999996,67.24220300000007],[-95.31471299999993,67.23858599999994],[-95.33666999999991,67.2127690000001],[-95.34277299999997,67.20694000000009],[-95.36166399999996,67.19775400000015]],[[-107.66278099999994,67.22026100000005],[-107.675003,67.21887200000003],[-107.73029300000002,67.28997800000008],[-107.73306300000002,67.30026199999992],[-107.73029300000002,67.30636600000014],[-107.72501399999993,67.31303400000013],[-107.71083099999998,67.31915300000014],[-107.67777999999993,67.31191999999999],[-107.66944899999993,67.30802900000009],[-107.66000399999996,67.29887400000001],[-107.64472999999998,67.26915000000002],[-107.64028899999994,67.25360100000012],[-107.63945000000001,67.24275200000005],[-107.64250199999992,67.23664900000011],[-107.64778100000001,67.22998000000001],[-107.65416699999997,67.22442600000005],[-107.66278099999994,67.22026100000005]],[[-63.36639399999996,67.28776600000003],[-63.39611100000002,67.26998899999995],[-63.417778,67.26638800000012],[-63.45610799999997,67.26443499999999],[-63.507506999999976,67.26944000000003],[-63.54194599999994,67.27249100000006],[-63.55972300000002,67.27304100000009],[-63.57833900000003,67.27331500000003],[-63.62027699999993,67.26915000000002],[-63.76361800000001,67.27249100000006],[-63.81361400000003,67.2791600000001],[-63.82972699999988,67.28414900000007],[-63.81944999999996,67.28997800000008],[-63.79666899999995,67.29998799999998],[-63.68833199999989,67.34166000000005],[-63.66666399999997,67.34553500000004],[-63.64611099999996,67.34803800000003],[-63.60555999999997,67.35220300000003],[-63.58583099999987,67.353317],[-63.48500100000001,67.341095],[-63.36916400000001,67.30247500000007],[-63.35777999999999,67.29386899999997],[-63.36639399999996,67.28776600000003]],[[-107.91082799999998,67.31053200000002],[-107.93443300000001,67.30664099999996],[-107.94803599999995,67.3083190000001],[-108.08444199999997,67.38136300000008],[-108.076683,67.42469800000003],[-108.07389799999993,67.4308170000001],[-108.06861899999996,67.43748500000004],[-108.06111099999993,67.44220000000007],[-107.94748700000002,67.47998000000001],[-107.91776999999996,67.48942599999998],[-107.90306099999992,67.4891510000001],[-107.89472999999992,67.48553500000008],[-107.88722200000001,67.47608900000012],[-107.88276699999989,67.46249400000005],[-107.89806399999998,67.31971700000008],[-107.90110799999997,67.31359899999995],[-107.91082799999998,67.31053200000002]],[[-108.36833200000001,67.46720900000008],[-108.38194299999998,67.4666600000001],[-108.39806399999998,67.467758],[-108.43388399999998,67.47665400000011],[-108.44444299999992,67.47998000000001],[-108.45278899999994,67.48387100000008],[-108.45889299999988,67.48803700000013],[-108.49249299999997,67.51971400000008],[-108.49638400000003,67.52442900000011],[-108.49582700000002,67.52998400000001],[-108.491379,67.56303400000007],[-108.48137700000001,67.56637599999999],[-108.45777899999996,67.56805400000013],[-108.33583099999993,67.565811],[-108.29750100000001,67.55720500000007],[-108.28582799999998,67.54304500000012],[-108.28443899999996,67.53776600000015],[-108.29527299999995,67.49693300000007],[-108.30166600000001,67.49108900000004],[-108.35722399999986,67.46943700000003],[-108.36833200000001,67.46720900000008]],[[-108.14111300000002,67.44999700000005],[-108.16944899999993,67.44970700000005],[-108.23665599999993,67.45665000000002],[-108.25167799999997,67.45887800000014],[-108.26222200000001,67.46220400000004],[-108.26806599999992,67.4666600000001],[-108.27194199999991,67.47137499999997],[-108.275284,67.48165899999998],[-108.22556299999997,67.56553600000012],[-108.21916199999987,67.57110600000004],[-108.20638999999994,67.57054099999999],[-108.19833399999999,67.566666],[-108.17360699999995,67.55247500000002],[-108.1661069999999,67.54304500000012],[-108.13137799999993,67.48193400000002],[-108.12970699999994,67.47665400000011],[-108.12888299999997,67.46582000000006],[-108.12943999999999,67.46026600000005],[-108.13249200000001,67.45416300000011],[-108.14111300000002,67.44999700000005]],[[-108.32277699999997,67.58998099999997],[-108.32362399999994,67.58665500000012],[-108.339447,67.5877690000001],[-108.42027300000001,67.59942600000005],[-108.48222399999992,67.63136300000002],[-108.48388699999992,67.63665800000007],[-108.475281,67.64054899999996],[-108.46389799999992,67.64305100000007],[-108.44803599999995,67.64193700000004],[-108.41832699999992,67.63638300000008],[-108.40334299999995,67.63415500000013],[-108.390289,67.63108800000003],[-108.379707,67.62776200000013],[-108.37138400000003,67.62414600000011],[-108.33416699999992,67.6041560000001],[-108.32277699999997,67.58998099999997]],[[-63.88194299999998,67.50332600000002],[-63.93555500000002,67.50193800000011],[-63.97916399999991,67.50305200000008],[-63.99500299999994,67.50416600000005],[-64.00527999999991,67.50526399999995],[-64.02528399999994,67.51054400000004],[-64.02972399999987,67.51388500000007],[-64.031677,67.5186000000001],[-64.03472899999991,67.52887000000004],[-64.03805499999987,67.54275500000011],[-64.0344389999999,67.55859400000003],[-63.98111,67.64415000000002],[-63.976944,67.649429],[-63.969993999999986,67.65359500000011],[-63.96277599999996,67.65554800000001],[-63.95249899999999,67.65443400000004],[-63.94554900000003,67.65138200000013],[-63.93721800000003,67.645264],[-63.92639200000002,67.63333099999994],[-63.92222600000002,67.62498500000004],[-63.915549999999996,67.61720300000013],[-63.90444200000002,67.60803199999998],[-63.87555699999996,67.59304800000007],[-63.853888999999924,67.58554100000015],[-63.815276999999924,67.566666],[-63.78722399999998,67.55053700000008],[-63.76999699999999,67.53776600000015],[-63.76361800000001,67.52970900000003],[-63.75805699999995,67.52053800000004],[-63.76083399999999,67.51527400000009],[-63.769447000000014,67.51332100000013],[-63.81833599999999,67.5086060000001],[-63.84222399999993,67.50637799999998],[-63.88194299999998,67.50332600000002]],[[-108.05999799999995,67.47526600000003],[-108.08972199999994,67.46554600000013],[-108.10333300000002,67.46720900000008],[-108.109444,67.47137499999997],[-108.11332700000003,67.47608900000012],[-108.14389,67.53054799999995],[-108.14277600000003,67.54165599999999],[-108.13362099999989,67.62803600000007],[-108.13221699999997,67.63943499999999],[-108.11776699999996,67.66998299999995],[-108.11361699999998,67.67526199999998],[-108.10109699999992,67.6766510000001],[-108.087219,67.67498800000004],[-108.01418299999995,67.66249100000005],[-108.00361599999997,67.65914900000007],[-107.99553700000001,67.655258],[-107.98944099999994,67.651093],[-107.98332199999999,67.64471400000014],[-107.92832900000002,67.561646],[-107.92304999999993,67.55165100000005],[-107.92138699999992,67.54664600000001],[-107.922234,67.540817],[-107.92749000000003,67.53442400000006],[-108.05999799999995,67.47526600000003]],[[-97.50279199999994,67.62442000000004],[-97.51556399999993,67.62387100000007],[-97.53028899999998,67.62498500000004],[-97.541382,67.62886000000003],[-97.54943799999995,67.63804599999997],[-97.55139199999996,67.64276100000001],[-97.55305499999992,67.6477660000001],[-97.56054699999993,67.69274899999999],[-97.40055799999999,67.73165899999992],[-97.38778699999989,67.73220800000007],[-97.36000100000001,67.73165899999992],[-97.34638999999993,67.728317],[-97.337784,67.724152],[-97.337784,67.72110000000009],[-97.33277899999996,67.70637499999998],[-97.327225,67.68165599999998],[-97.33277899999996,67.67581200000001],[-97.34167500000001,67.6705320000001],[-97.37054399999988,67.657761],[-97.43360899999993,67.63749700000005],[-97.47888199999994,67.62747200000013],[-97.50279199999994,67.62442000000004]],[[-109.11221299999994,67.76332100000008],[-109.12581599999987,67.76249700000011],[-109.14111299999996,67.76499899999999],[-109.195267,67.77554300000003],[-109.20612299999993,67.77886999999998],[-109.20777900000002,67.78387500000002],[-109.16944899999999,67.79775999999993],[-109.15943899999996,67.801086],[-109.135559,67.80276499999997],[-109.0933379999999,67.80386399999998],[-109.07584400000002,67.80219999999997],[-109.06054699999999,67.79971300000005],[-109.03916899999996,67.79332000000011],[-109.04083299999996,67.78831500000007],[-109.05277999999993,67.78248600000006],[-109.08000199999987,67.77110300000004],[-109.08972199999994,67.76805100000013],[-109.11221299999994,67.76332100000008]],[[-96.170547,67.77304100000015],[-96.18276999999995,67.77165199999996],[-96.19249000000002,67.77360500000009],[-96.19638099999992,67.77804600000002],[-96.18582199999997,67.79470800000001],[-96.17999299999997,67.80026200000003],[-96.17138699999992,67.80636600000003],[-96.09861799999999,67.83221399999996],[-96.07722499999994,67.83888200000013],[-96.06555200000003,67.84109500000011],[-96.05332899999996,67.842758],[-96.04028299999993,67.84332300000005],[-96.02806099999998,67.84165999999993],[-95.99749800000001,67.820831],[-95.99638400000003,67.81581100000011],[-96.00473,67.809708],[-96.01611300000002,67.80748],[-96.04083299999996,67.80442800000009],[-96.170547,67.77304100000015]],[[-114.11501299999998,67.88388099999997],[-114.08222999999998,67.8830410000001],[-114.02223200000003,67.88415500000008],[-114.00583599999999,67.8836060000001],[-113.95500199999998,67.88136299999996],[-113.92138699999998,67.87803600000001],[-113.925003,67.87469499999997],[-113.94138299999986,67.87525900000014],[-113.98638899999997,67.87441999999999],[-113.99999999999994,67.87330600000001],[-114.01027699999992,67.87136800000007],[-114.05166600000001,67.87025499999999],[-114.08306900000002,67.87052900000009],[-114.195267,67.87248200000005],[-114.22972099999987,67.87414600000005],[-114.25250199999999,67.879974],[-114.29638699999998,67.89221200000003],[-114.29695100000004,67.89526399999994],[-114.27555799999999,67.90054299999991],[-114.25110599999994,67.90443399999998],[-114.21972700000003,67.90416000000005],[-114.20612299999993,67.9019320000001],[-114.17388899999997,67.89248700000007],[-114.14862099999999,67.88720699999999],[-114.13305700000001,67.88526900000005],[-114.11501299999998,67.88388099999997]],[[-97.85638399999993,67.85053999999997],[-97.86694299999999,67.84693900000013],[-97.92416400000002,67.84999100000005],[-97.954453,67.85636899999997],[-97.96333300000003,67.86026000000004],[-97.97000100000002,67.86442599999998],[-97.97416699999991,67.86914100000001],[-97.97332799999992,67.87414600000005],[-97.976944,67.88415500000008],[-97.97444200000001,67.90498400000001],[-97.96112099999999,67.90554800000001],[-97.93331899999998,67.89888000000002],[-97.92027299999995,67.8936000000001],[-97.91361999999998,67.88916000000012],[-97.895554,67.88136299999996],[-97.86221299999994,67.85998500000005],[-97.85804699999994,67.855255],[-97.85638399999993,67.85053999999997]],[[-108.64695699999999,67.86943100000002],[-108.66082799999998,67.86886599999997],[-108.66915899999998,67.87248200000005],[-108.64666699999998,67.88720699999999],[-108.58500700000002,67.91554300000007],[-108.56610099999989,67.92275999999998],[-108.54472399999997,67.928314],[-108.531113,67.92886400000003],[-108.38027999999997,67.922485],[-108.37082699999996,67.91970800000007],[-108.36444099999994,67.91554300000007],[-108.36110699999989,67.90525799999995],[-108.35944399999994,67.89999399999999],[-108.41221599999994,67.88581799999997],[-108.64695699999999,67.86943100000002]],[[-113.390289,67.89776600000005],[-113.46389799999997,67.89582800000011],[-113.52694699999995,67.89637800000014],[-113.55972300000002,67.897491],[-113.59416199999993,67.89942899999994],[-113.6033329999999,67.90304600000007],[-113.59750399999996,67.90664700000013],[-113.58528100000001,67.90860000000009],[-113.41972399999997,67.92526200000009],[-113.39111300000002,67.92665100000005],[-113.34750400000001,67.92804000000007],[-113.27390299999996,67.92997700000012],[-113.25723299999993,67.92942800000014],[-113.25029,67.92526200000009],[-113.24694799999997,67.9144290000001],[-113.25361599999997,67.90942400000006],[-113.27778599999999,67.905823],[-113.297234,67.90443399999998],[-113.33444199999991,67.90109299999995],[-113.390289,67.89776600000005]],[[-112.93055700000002,67.91665599999999],[-112.983612,67.91526800000008],[-112.99999999999989,67.91609200000005],[-113.06027199999994,67.91526800000008],[-113.131104,67.911652],[-113.14750700000002,67.91220099999998],[-113.14750700000002,67.915817],[-113.13806199999999,67.91914400000013],[-112.94304699999998,67.9310910000001],[-112.89639299999999,67.93081699999999],[-112.88722199999995,67.92720000000003],[-112.890289,67.92192100000005],[-112.90110800000002,67.91914400000013],[-112.93055700000002,67.91665599999999]],[[-111.07167099999998,67.84748800000006],[-111.08666999999997,67.84748800000006],[-111.0911099999999,67.85220300000009],[-111.08693700000003,67.85887100000008],[-111.07028200000002,67.86720300000007],[-110.84889199999998,67.95471199999997],[-110.83917200000002,67.95803799999999],[-110.82668299999995,67.95971700000001],[-110.81388900000002,67.95915200000002],[-110.80722000000003,67.95498700000002],[-110.80943300000001,67.94886799999995],[-110.81696299999999,67.94026200000002],[-110.86221299999994,67.89498900000012],[-110.86945300000002,67.88998400000008],[-110.88027999999991,67.887497],[-111.05943300000001,67.84915200000006],[-111.07167099999998,67.84748800000006]],[[-114.21916199999998,67.94525099999998],[-114.29583699999995,67.94470200000006],[-114.30999799999995,67.94581600000004],[-114.31722999999988,67.9497070000001],[-114.31082200000003,67.95471199999997],[-114.30027799999988,67.95748900000007],[-114.25446299999987,67.96331800000007],[-114.17138699999992,67.96914700000008],[-114.13999899999999,67.96887200000009],[-114.12416099999996,67.96720900000014],[-114.12110899999993,67.96192900000005],[-114.12332199999992,67.95803799999999],[-114.16332999999986,67.94914200000005],[-114.203888,67.94581600000004],[-114.21916199999998,67.94525099999998]],[[-108.13806199999999,67.87248200000005],[-108.15167199999996,67.87191800000011],[-108.24553699999996,67.87803600000001],[-108.25418100000002,67.88192700000008],[-108.25556899999992,67.88720699999999],[-108.23916599999995,67.9202580000001],[-108.236107,67.92637600000006],[-108.23111,67.93304400000005],[-108.22471599999994,67.93887300000006],[-108.198036,67.95082100000008],[-108.14723200000003,67.96665999999999],[-108.12581599999999,67.97221400000001],[-108.114441,67.97442600000005],[-108.10056299999997,67.9749910000001],[-108.08416699999998,67.97387700000013],[-108.07140399999992,67.97110000000004],[-108.06054699999999,67.96775800000012],[-108.05444299999988,67.96331800000007],[-108.05055199999998,67.95860300000004],[-108.048607,67.94914200000005],[-108.05139200000002,67.92665100000005],[-108.06331599999993,67.90220600000004],[-108.06833599999999,67.89553800000004],[-108.07501200000002,67.88970900000004],[-108.08249699999999,67.88499500000012],[-108.09137699999985,67.88081400000004],[-108.11277799999999,67.87553400000013],[-108.13806199999999,67.87248200000005]],[[-113.72000099999997,67.97331200000008],[-113.72778299999993,67.96914700000008],[-113.73998999999998,67.96720900000014],[-113.75361599999997,67.966095],[-113.79750099999995,67.96470599999998],[-113.99305699999996,67.96110499999992],[-113.99109599999997,67.96499599999999],[-113.98249800000002,67.96720900000014],[-113.97250400000001,67.96859700000005],[-113.91639700000002,67.97221400000001],[-113.88639799999999,67.97276299999999],[-113.83833299999998,67.971924],[-113.81111099999993,67.97387700000013],[-113.785278,67.97692900000004],[-113.77223199999997,67.98027000000008],[-113.74082899999996,67.97998000000007],[-113.72501399999999,67.97804300000001],[-113.72000099999997,67.97331200000008]],[[-109.195267,67.98997499999996],[-109.04998799999993,67.95832800000005],[-109.03028899999993,67.96693399999992],[-108.99082900000002,67.97637900000001],[-108.97693599999997,67.97692900000004],[-108.95111099999991,67.97331200000008],[-108.89723199999997,67.95694000000009],[-108.88445300000001,67.94859300000013],[-108.86554699999999,67.905823],[-108.86609599999991,67.90026899999998],[-108.87943999999999,67.87525900000014],[-108.88806199999999,67.87109399999997],[-108.90055799999999,67.86970500000012],[-108.916946,67.87052900000009],[-109.04888900000003,67.90387000000004],[-109.10305799999998,67.9202580000001],[-109.135559,67.93026700000013],[-109.16972399999992,67.94525099999998],[-109.18888899999996,67.95776400000005],[-109.195267,67.9622040000001],[-109.19888299999997,67.97248800000011],[-109.198036,67.98387100000014],[-109.195267,67.98997499999996]],[[-110.33444199999997,68.01165800000012],[-110.39362299999993,68.01110800000009],[-110.41000400000001,68.01193200000006],[-110.42111199999994,68.01499899999993],[-110.420837,68.020828],[-110.410553,68.02470400000004],[-110.32640099999992,68.0477600000001],[-110.317497,68.049713],[-110.31082199999992,68.0455320000001],[-110.30888400000003,68.03749100000005],[-110.316101,68.01915000000002],[-110.32333399999999,68.01416],[-110.33444199999997,68.01165800000012]],[[-98.95140100000003,67.97998000000007],[-98.96362299999993,67.97831700000012],[-98.97944599999994,67.98027000000008],[-99.00500499999998,67.98719800000009],[-99.01445000000001,67.99108899999999],[-99.02833599999991,67.99942000000004],[-99.0786129999999,68.045593],[-99.05139200000002,68.05581700000005],[-98.99055499999986,68.07832300000007],[-98.97555499999999,68.07720900000004],[-98.968887,68.07304400000004],[-98.964722,68.06498700000009],[-98.93443299999996,67.99664300000012],[-98.93499800000001,67.99136399999998],[-98.94276399999995,67.98525999999993],[-98.95140100000003,67.97998000000007]],[[-65.39723200000003,68.03997800000013],[-65.40916399999998,68.03942899999998],[-65.50029,68.04609700000015],[-65.51083399999999,68.04942299999999],[-65.516663,68.05442800000003],[-65.51972999999998,68.06749000000008],[-65.51806599999998,68.07222000000007],[-65.50527999999997,68.07638500000007],[-65.43582200000003,68.08804299999997],[-65.394455,68.08998100000008],[-65.38639799999993,68.08831800000013],[-65.390289,68.07832300000007],[-65.38305700000001,68.05331400000006],[-65.38333099999994,68.04859900000002],[-65.38722200000001,68.04332000000005],[-65.39723200000003,68.03997800000013]],[[-108.50611900000001,68.03471400000012],[-108.51862299999993,68.03332499999993],[-108.53388999999999,68.03553800000009],[-108.54028299999993,68.03997800000013],[-108.53751399999999,68.04609700000015],[-108.45472699999999,68.09054600000007],[-108.44748700000002,68.08776900000004],[-108.44583099999994,68.08248900000012],[-108.44611399999991,68.07470699999999],[-108.45140100000003,68.06805400000002],[-108.46665999999999,68.0583190000001],[-108.49722299999996,68.03887900000012],[-108.50611900000001,68.03471400000012]],[[-109.32167099999998,67.98109400000004],[-109.33556399999992,67.98027000000008],[-109.35193600000002,67.98136900000009],[-109.37805199999991,67.98692300000005],[-109.432503,68.00305200000003],[-109.49804699999993,68.0227660000001],[-109.50666799999993,68.02638200000013],[-109.53888699999999,68.04748500000005],[-109.54305999999991,68.05220000000008],[-109.50473,68.08888200000007],[-109.4974979999999,68.0935970000001],[-109.484734,68.09526099999994],[-109.44722000000002,68.09220900000003],[-109.410553,68.07193000000007],[-109.32167099999998,68.03997800000013],[-109.31527699999987,68.03581200000002],[-109.3116609999999,68.02554300000003],[-109.31111099999987,67.99775699999992],[-109.3116609999999,67.99192800000009],[-109.31416299999995,67.98580900000007],[-109.32167099999998,67.98109400000004]],[[-108.36054999999999,68.049713],[-108.37444299999993,68.04887400000007],[-108.38751200000002,68.05192599999998],[-108.40638699999994,68.06469700000008],[-108.40805099999994,68.06971699999997],[-108.40167200000002,68.07554600000014],[-108.38221699999991,68.092758],[-108.37444299999993,68.09553500000004],[-108.36193800000001,68.09693900000008],[-108.32000699999992,68.09887700000002],[-108.306107,68.09942599999994],[-108.29444899999999,68.09721400000006],[-108.297234,68.09109500000005],[-108.29778299999998,68.08554100000003],[-108.30082700000003,68.07943700000004],[-108.30860899999999,68.07470699999999],[-108.34916699999997,68.05192599999998],[-108.36054999999999,68.049713]],[[-110.21362299999998,68.03803999999997],[-110.23998999999998,68.03581200000002],[-110.25639299999995,68.03665200000006],[-110.258621,68.04193100000003],[-110.25,68.04609700000015],[-110.22165699999994,68.05664100000001],[-110.18195300000002,68.06971699999997],[-109.93276999999989,68.13192700000008],[-109.92166099999997,68.13415500000002],[-109.89639299999999,68.13749700000011],[-109.88583399999993,68.13638300000014],[-109.87721299999993,68.12692300000009],[-109.87748699999997,68.12136800000002],[-109.882767,68.1141510000001],[-109.88527699999997,68.10803200000004],[-109.88999899999993,68.10137900000007],[-109.89584399999995,68.09553500000004],[-109.903343,68.09054600000007],[-109.92111199999994,68.08166499999999],[-109.93222000000003,68.07916300000011],[-110.08721899999995,68.05331400000006],[-110.21362299999998,68.03803999999997]],[[-112.78056299999997,68.13108800000009],[-112.79276999999996,68.12942499999997],[-112.88999899999999,68.1372070000001],[-112.9058379999999,68.13916000000006],[-112.91722099999998,68.14221199999997],[-112.922234,68.14665200000002],[-112.91832699999992,68.153595],[-112.91306299999997,68.159424],[-112.90638699999994,68.16442900000004],[-112.89835399999998,68.16886900000009],[-112.88861099999997,68.172211],[-112.87638900000002,68.17387400000013],[-112.86110699999995,68.17414900000011],[-112.76722699999993,68.1666560000001],[-112.75167799999997,68.16470300000015],[-112.74973299999994,68.15803499999998],[-112.74472000000003,68.153595],[-112.74638399999998,68.14749099999995],[-112.75334199999998,68.14221199999997],[-112.76139799999993,68.13804600000009],[-112.78056299999997,68.13108800000009]],[[-74.21556099999998,68.11775199999994],[-74.16471899999999,68.06553600000007],[-73.974716,68.0410920000001],[-73.73638899999997,68.01361100000003],[-73.65547199999997,68.00770599999998],[-73.64334099999991,68.01220700000005],[-73.61999500000002,68.01499899999993],[-73.60888699999987,68.01554899999996],[-73.57806399999998,68.01443499999999],[-73.56750499999998,68.01304600000003],[-73.54388399999993,68.008331],[-73.43998699999997,67.98553500000014],[-73.42832900000002,67.98220800000001],[-73.41888399999999,67.97886699999998],[-73.41166699999997,67.9749910000001],[-73.40972899999991,67.97053499999998],[-73.34861799999999,67.82804899999996],[-73.36166400000002,67.81025700000009],[-73.37777699999987,67.79386900000003],[-73.38333099999994,67.78942900000004],[-73.40417500000001,67.7749940000001],[-73.41139199999992,67.77053799999999],[-73.41860999999994,67.766388],[-73.42944299999999,67.76277199999993],[-73.44943199999994,67.76249700000011],[-73.66416899999996,67.7747040000001],[-73.93221999999992,67.78637700000013],[-73.99305700000002,67.78804000000002],[-74.03832999999992,67.788589],[-74.08389299999988,67.78831500000007],[-74.11332700000003,67.7872010000001],[-74.16805999999985,67.78276100000005],[-74.22888199999994,67.77526899999992],[-74.2519529999999,67.77249100000012],[-74.26306199999999,67.77165199999996],[-74.30583200000001,67.76860000000005],[-74.32028200000002,67.7688750000001],[-74.38861099999997,67.77526899999992],[-74.40083300000003,67.77665700000006],[-74.48110999999994,67.78942900000004],[-74.535278,67.80470300000013],[-74.56416299999995,67.81442300000003],[-74.58168,67.82138100000003],[-74.59722899999997,67.82859800000011],[-74.64083899999997,67.85220300000009],[-74.65972899999991,67.86470000000008],[-74.68443300000001,67.88192700000008],[-74.758896,67.95027199999998],[-74.77223200000003,67.96331800000007],[-74.77555799999988,67.96914700000008],[-74.777222,67.97387700000013],[-74.77806099999992,68.00610400000011],[-74.77749599999999,68.01776100000006],[-74.773056,68.02998400000013],[-74.76000999999997,68.05442800000003],[-74.75418100000002,68.06053200000008],[-74.74861099999993,68.06553600000007],[-74.73194899999987,68.07083100000011],[-74.718613,68.07222000000007],[-74.62999000000002,68.07859800000006],[-74.61527999999998,68.07832300000007],[-74.43666100000002,68.097488],[-74.36389200000002,68.166382],[-74.35583499999996,68.17275999999998],[-74.34695399999993,68.176376],[-74.339447,68.17719999999997],[-74.32250999999991,68.17303500000014],[-74.26889,68.15498400000001],[-74.239441,68.14498900000007],[-74.23167399999994,68.14193699999998],[-74.21639999999996,68.13415500000002],[-74.21250900000001,68.13053899999994],[-74.21083099999998,68.12498499999998],[-74.21556099999998,68.11775199999994]],[[-65.64222699999999,68.159424],[-65.56639100000001,68.15220599999998],[-65.512787,68.15277100000003],[-65.502792,68.15109300000012],[-65.49777199999994,68.14776599999999],[-65.49444599999993,68.14248700000002],[-65.495544,68.128311],[-65.50083899999998,68.12191800000005],[-65.516953,68.11303700000008],[-65.525284,68.10971100000006],[-65.67555199999998,68.09610000000009],[-65.686935,68.0958250000001],[-65.69610599999993,68.09887700000002],[-65.70973199999997,68.1060940000001],[-65.71389799999997,68.11276200000009],[-65.72193899999996,68.16442900000004],[-65.716949,68.17581200000006],[-65.71167000000003,68.18026700000007],[-65.70140099999998,68.18136600000008],[-65.67582699999997,68.17997700000006],[-65.65666199999993,68.17526200000003],[-65.64834599999995,68.16859400000004],[-65.64666699999992,68.16360500000008],[-65.64222699999999,68.159424]],[[-107.47361799999993,68.14471400000008],[-107.48500100000001,68.14248700000002],[-107.50140399999998,68.14360000000005],[-107.55499299999991,68.16053799999997],[-107.55416899999994,68.16609199999999],[-107.54499800000002,68.16998300000006],[-107.5038909999999,68.18248000000006],[-107.49472000000003,68.18664600000011],[-107.48444399999994,68.18969700000014],[-107.46806300000003,68.188583],[-107.46193700000003,68.18414299999995],[-107.46028100000001,68.1791530000001],[-107.45935800000001,68.17562900000001],[-107.45667299999997,68.17442300000005],[-107.45527600000003,68.16914400000007],[-107.45584099999996,68.16360500000008],[-107.46694899999994,68.15026899999998],[-107.47361799999993,68.14471400000008]],[[-104.453056,68.10220300000003],[-104.48277299999995,68.07971200000003],[-104.497772,68.08027599999997],[-104.50334199999992,68.08471700000007],[-104.55304699999999,68.14027400000003],[-104.55610699999994,68.14526400000011],[-104.55695299999996,68.15026899999998],[-104.553879,68.16165199999995],[-104.54666099999997,68.16499299999998],[-104.42639200000002,68.19999700000005],[-104.41555799999998,68.20277399999998],[-104.391953,68.20694000000009],[-104.37721299999998,68.19970700000005],[-104.36860699999994,68.19053600000012],[-104.370003,68.1849820000001],[-104.37416100000002,68.17886399999998],[-104.40499899999992,68.13943500000005],[-104.453056,68.10220300000003]],[[-107.38890100000003,68.172211],[-107.40278599999999,68.17164599999995],[-107.41111799999999,68.17553700000002],[-107.44167299999992,68.19692999999995],[-107.445267,68.20166],[-107.43998699999997,68.208328],[-107.42944299999999,68.21138000000008],[-107.41443599999997,68.21110500000009],[-107.30972300000002,68.20915200000013],[-107.295547,68.20748900000001],[-107.291672,68.20277399999998],[-107.31054699999999,68.19609100000002],[-107.38890100000003,68.172211]],[[-111.833328,68.18193100000008],[-111.84722899999997,68.1808170000001],[-111.860817,68.18359400000003],[-111.86554699999999,68.18803400000002],[-111.83222999999998,68.20498700000013],[-111.81416300000001,68.21249400000005],[-111.79194599999994,68.21775800000006],[-111.77944899999994,68.21943700000003],[-111.764183,68.21943700000003],[-111.75499699999995,68.21582000000012],[-111.75945299999995,68.20915200000013],[-111.76666299999994,68.20637500000004],[-111.79194599999994,68.19358800000003],[-111.81111099999998,68.18692000000004],[-111.833328,68.18193100000008]],[[-98.650284,68.18026700000007],[-98.67443800000001,68.17387400000013],[-98.704453,68.176086],[-98.702789,68.1916500000001],[-98.69332899999995,68.21360800000002],[-98.68443300000001,68.21887200000003],[-98.67222600000002,68.22053499999993],[-98.65722699999998,68.21943700000003],[-98.64306599999998,68.21609500000011],[-98.63861099999997,68.21165500000012],[-98.63667299999992,68.20665000000002],[-98.64306599999998,68.20166],[-98.650284,68.18026700000007]],[[-74.06277499999999,68.15165700000006],[-74.07362399999994,68.15081800000007],[-74.13833599999992,68.17025800000005],[-74.16972399999997,68.19552599999997],[-74.17639200000002,68.204163],[-74.17138699999998,68.20860299999998],[-74.15583799999996,68.21748400000013],[-74.13806199999999,68.22581500000001],[-74.11721799999992,68.23220799999996],[-74.10583500000001,68.2352600000001],[-74.09722899999991,68.23664900000006],[-74.08694499999996,68.2352600000001],[-74.07972699999999,68.232483],[-74.07528699999995,68.22776799999997],[-74.073059,68.22387700000007],[-74.06332399999991,68.20304900000002],[-74.05555700000002,68.17248500000011],[-74.05444299999999,68.15998800000011],[-74.05721999999997,68.15498400000001],[-74.06277499999999,68.15165700000006]],[[-108.59028599999999,68.21443199999999],[-108.63944999999995,68.15138200000001],[-108.6499859999999,68.15248100000002],[-108.65862299999998,68.15609700000005],[-108.67748999999998,68.16886900000009],[-108.67360699999995,68.18637100000012],[-108.67194399999994,68.19108599999998],[-108.63500999999997,68.2285920000001],[-108.62748699999992,68.23359700000015],[-108.60555999999997,68.23692299999999],[-108.56610099999989,68.24054000000012],[-108.55972300000002,68.23609900000002],[-108.59028599999999,68.21443199999999]],[[-109.78388999999999,68.13749700000011],[-109.81166099999996,68.13610799999998],[-109.828056,68.13693200000012],[-109.84137699999997,68.13970899999998],[-109.84999099999999,68.14332599999994],[-109.85665899999998,68.14776599999999],[-109.854172,68.15386999999998],[-109.845551,68.15803499999998],[-109.77194199999997,68.18830900000006],[-109.676941,68.22415200000006],[-109.64417300000002,68.23220799999996],[-109.58889799999997,68.24525499999999],[-109.57749899999988,68.24748200000005],[-109.56806899999998,68.24720800000011],[-109.57055699999995,68.2410890000001],[-109.57695000000001,68.232483],[-109.58194700000001,68.22581500000001],[-109.59416199999993,68.21443199999999],[-109.67388899999997,68.17330900000007],[-109.7625119999999,68.14332599999994],[-109.7725069999999,68.13998400000003],[-109.78388999999999,68.13749700000011]],[[-66.31361400000003,68.14776599999999],[-66.32695000000001,68.14749099999995],[-66.35499599999997,68.15331999999995],[-66.38110399999994,68.15860000000004],[-66.39639299999993,68.16110200000008],[-66.46861299999995,68.17109700000003],[-66.52778599999988,68.17776500000002],[-66.57084700000001,68.18136600000008],[-66.601944,68.18248000000006],[-66.60722399999997,68.21720900000008],[-66.5,68.23970000000008],[-66.29943799999995,68.25444000000005],[-66.22193899999996,68.2410890000001],[-66.25666799999999,68.16360500000008],[-66.26972999999992,68.15860000000004],[-66.30139199999996,68.14915499999995],[-66.31361400000003,68.14776599999999]],[[-96.38417099999992,68.20082100000002],[-96.422775,68.19831800000009],[-96.436935,68.19859300000007],[-96.44860799999992,68.20248400000014],[-96.45472699999993,68.20665000000002],[-96.462784,68.21609500000011],[-96.45666499999999,68.22164900000013],[-96.375,68.25471500000003],[-96.36416600000001,68.2580410000001],[-96.35082999999997,68.25860599999993],[-96.34445199999993,68.25416600000011],[-96.31750499999993,68.23193400000002],[-96.32444800000002,68.22109999999998],[-96.33889799999992,68.21220400000004],[-96.34889199999986,68.20803799999999],[-96.36000100000001,68.20471200000009],[-96.38417099999992,68.20082100000002]],[[-78.57167099999998,68.2002720000001],[-78.65556300000003,68.18775900000003],[-78.662216,68.18914799999999],[-78.66027799999989,68.19636500000013],[-78.64306599999998,68.21832300000005],[-78.60722399999992,68.24832200000009],[-78.59388699999988,68.25555400000002],[-78.58111599999995,68.25888099999997],[-78.55027799999999,68.26361099999997],[-78.54804999999999,68.26304600000014],[-78.54527300000001,68.25],[-78.525284,68.23359700000015],[-78.51722699999993,68.22331200000002],[-78.5225069999999,68.21775800000006],[-78.53222699999998,68.21304300000003],[-78.55888399999998,68.20304900000002],[-78.57167099999998,68.2002720000001]],[[-86.42639199999996,68.06915299999997],[-86.39750700000002,68.02165200000013],[-86.37832599999996,67.9933170000001],[-86.37666299999995,67.988586],[-86.368607,67.95471199999997],[-86.37083399999995,67.93997200000001],[-86.39611799999994,67.85971100000012],[-86.40360999999996,67.84887700000007],[-86.465012,67.78665200000012],[-86.47084000000001,67.78137200000009],[-86.48998999999998,67.77053799999999],[-86.57194500000003,67.72886700000004],[-86.58361799999994,67.72526600000015],[-86.59666399999998,67.72554000000008],[-86.67666599999995,67.73165899999992],[-86.69055200000003,67.73387100000002],[-86.85833699999995,67.79693599999996],[-86.87943999999993,67.81025700000009],[-86.88389599999994,67.81498699999997],[-86.910278,67.8477630000001],[-86.91861,67.86192299999999],[-86.926941,67.87637300000011],[-86.94583099999994,67.90942400000006],[-86.9519499999999,67.92387400000001],[-86.94860799999998,67.92886400000003],[-86.94055199999997,67.93441800000005],[-86.92610199999996,67.93136600000008],[-86.91332999999997,67.93193100000013],[-86.85444599999988,67.95416300000005],[-86.84333799999996,67.95860300000004],[-86.83889799999997,67.98637400000013],[-86.83694500000001,68.00109900000007],[-86.84083599999991,68.01081800000003],[-86.84750399999996,68.020264],[-86.851944,68.02499400000005],[-86.86389200000002,68.02915999999993],[-86.87832599999996,68.03221099999996],[-86.90417500000001,68.03054800000007],[-86.93249500000002,68.03581200000002],[-86.94221499999998,68.04026799999997],[-86.98666400000002,68.06164600000005],[-86.9927669999999,68.06666600000011],[-86.99194299999994,68.07165500000008],[-86.98832699999997,68.08166499999999],[-86.978882,68.09693900000008],[-86.90638699999994,68.18026700000007],[-86.89805599999994,68.18553199999997],[-86.74249299999991,68.28276099999994],[-86.71194499999996,68.299149],[-86.70056199999993,68.30358900000004],[-86.675003,68.3060910000001],[-86.64666699999992,68.3016510000001],[-86.60278299999999,68.29136700000004],[-86.53860500000002,68.2705380000001],[-86.487503,68.24859600000002],[-86.45861799999989,68.23553500000008],[-86.41111799999999,68.20887800000003],[-86.40666199999998,68.204163],[-86.40278599999999,68.19442700000002],[-86.43499800000001,68.1624910000001],[-86.43388400000003,68.09860199999997],[-86.43249500000002,68.08888200000007],[-86.42639199999996,68.06915299999997]],[[-111.71028100000001,68.22053499999993],[-111.72556299999997,68.220261],[-111.74221799999998,68.22109999999998],[-111.75583599999993,68.22360200000003],[-111.76500699999997,68.22720300000009],[-111.77194199999991,68.23136900000003],[-111.77639799999992,68.23609900000002],[-111.77887699999997,68.2410890000001],[-111.77916699999997,68.24693300000013],[-111.777222,68.25305200000014],[-111.77166699999998,68.25888099999997],[-111.71501199999994,68.29693600000007],[-111.70388799999989,68.29942299999993],[-111.52887699999991,68.31080600000013],[-111.51363400000002,68.31109600000013],[-111.49944299999993,68.29693600000007],[-111.50446299999999,68.29248000000013],[-111.52861000000001,68.29054300000007],[-111.55777,68.2894290000001],[-111.58277899999996,68.28610199999997],[-111.60526999999996,68.28109699999993],[-111.61361699999998,68.27665700000011],[-111.62777699999998,68.26666300000011],[-111.633331,68.26081800000003],[-111.63305699999995,68.24971],[-111.63054699999992,68.24443100000002],[-111.63249200000001,68.23831200000001],[-111.63945000000001,68.23332199999993],[-111.64943700000003,68.22998000000001],[-111.67166099999997,68.22470100000004],[-111.696663,68.22137500000002],[-111.71028100000001,68.22053499999993]],[[-75.58277900000002,68.30026200000009],[-75.5625,68.29443399999997],[-75.453888,68.26666300000011],[-75.42971799999998,68.26220699999999],[-75.38667299999992,68.2580410000001],[-75.26306199999993,68.24720800000011],[-75.22888199999994,68.24552900000009],[-75.19915800000001,68.24552900000009],[-75.18305999999995,68.24386600000003],[-75.15861499999994,68.23997500000013],[-75.13473499999986,68.23471100000012],[-75.12193300000001,68.22915600000005],[-75.03056300000003,68.16720599999996],[-75.01194800000002,68.14776599999999],[-75.00306699999999,68.13220200000006],[-75,68.1196900000001],[-75.00222799999995,68.1144260000001],[-75.04916399999996,68.0413670000001],[-75.05249000000003,68.03665200000006],[-75.06332399999997,68.02720600000009],[-75.09167500000001,68.009995],[-75.148056,67.97442600000005],[-75.1536099999999,67.96943700000008],[-75.16444399999995,67.95416300000005],[-75.16444399999995,67.9494170000001],[-75.16278099999994,67.94386300000008],[-75.11389199999996,67.86192299999999],[-75.104446,67.84748800000006],[-75.06416299999995,67.78248600000006],[-75.02500899999995,67.62553400000002],[-75.025284,67.61943100000008],[-75.06889299999989,67.54275500000011],[-75.07194499999997,67.53887900000007],[-75.13362099999995,67.48165899999998],[-75.16111799999999,67.46388200000013],[-75.19860799999998,67.44331400000004],[-75.38806199999993,67.35470599999996],[-75.39584399999995,67.35304300000007],[-75.5536039999999,67.3336030000001],[-75.66250600000001,67.305252],[-75.84445199999999,67.26415999999995],[-75.94610599999993,67.251938],[-76.11665299999993,67.25555400000002],[-76.22694399999995,67.26081800000003],[-76.30860899999999,67.25360100000012],[-76.49082900000002,67.23637400000007],[-76.66361999999998,67.219986],[-76.69305399999996,67.22109999999998],[-76.97805799999998,67.24552900000015],[-77.02667200000002,67.25499000000008],[-77.04472399999992,67.2605440000001],[-77.05721999999992,67.26721200000009],[-77.07444800000002,67.28082300000005],[-77.10139500000002,67.30581699999999],[-77.24694799999997,67.45193499999999],[-77.24722299999996,67.45721400000014],[-77.23693799999995,67.49525499999999],[-77.22444199999995,67.53553800000003],[-77.22582999999997,67.54386900000009],[-77.23028599999998,67.55442800000014],[-77.24221799999992,67.56915300000009],[-77.27500899999995,67.61469999999997],[-77.31221,67.67637600000012],[-77.32084700000001,67.69164999999998],[-77.32250999999991,67.69802900000008],[-77.31916799999999,67.71138000000002],[-77.25834699999996,67.81637599999993],[-77.25195300000001,67.82638500000013],[-77.24333200000001,67.83749400000005],[-77.23306299999996,67.84887700000007],[-77.22833300000002,67.8538670000001],[-77.220551,67.86192299999999],[-77.203888,67.87637300000011],[-76.86555499999997,68.15776100000005],[-76.85888699999992,68.16165199999995],[-76.72610500000002,68.23887600000012],[-76.70249899999993,68.24859600000002],[-76.67388899999997,68.25915500000008],[-76.63500999999991,68.27192700000006],[-76.60694899999993,68.27943400000004],[-76.28195199999999,68.33276400000011],[-76.26722699999993,68.33276400000011],[-76.2583469999999,68.3316650000001],[-76.25195300000001,68.328598],[-76.25,68.32304400000004],[-76.25306699999993,68.31359900000012],[-76.24916100000002,68.30748000000011],[-76.23582499999998,68.303314],[-76.22166399999998,68.30137600000006],[-76.116104,68.29664600000007],[-76.083328,68.29525799999993],[-76.06054699999999,68.29693600000007],[-76.05277999999998,68.29859899999997],[-76.03222700000003,68.30470300000002],[-76.000565,68.31693999999999],[-75.98500100000001,68.32443200000012],[-75.96639999999996,68.3311000000001],[-75.95417800000001,68.33387800000008],[-75.93083199999995,68.33692900000011],[-75.91749599999991,68.33831800000007],[-75.88751199999996,68.33970599999998],[-75.81806899999987,68.33665500000001],[-75.75666799999999,68.33248900000007],[-75.72610500000002,68.33027600000014],[-75.69554099999988,68.3269350000001],[-75.66749600000003,68.322769],[-75.62249799999995,68.31303400000007],[-75.60249299999987,68.30748000000011],[-75.58277900000002,68.30026200000009]],[[-79.02055399999995,68.16914400000007],[-79.03250099999991,68.16526800000003],[-79.07501200000002,68.16832000000011],[-79.08972199999994,68.17025800000005],[-79.10166900000002,68.17526200000003],[-79.17138699999987,68.20526100000006],[-79.17694099999994,68.20942700000012],[-79.17999299999997,68.21554599999996],[-79.18832399999997,68.24720800000011],[-79.19110099999995,68.31944299999998],[-79.15167199999996,68.34664900000001],[-79.14195299999994,68.34887700000013],[-79.12554899999998,68.35026600000015],[-79.09944199999995,68.34860200000014],[-79.04499799999996,68.34332299999994],[-78.92999299999991,68.33888200000001],[-78.82611099999997,68.29553200000004],[-78.80999800000001,68.28749099999999],[-78.80471799999992,68.283051],[-78.80166600000001,68.2791600000001],[-78.80221599999993,68.272491],[-78.80526699999996,68.26666300000011],[-78.81555199999991,68.25555400000002],[-78.82333399999993,68.25054899999998],[-78.84194899999989,68.24054000000012],[-79.02055399999995,68.16914400000007]],[[-100.07472200000001,68.34971600000011],[-100.08640299999996,68.29609700000009],[-100.09166700000003,68.284988],[-100.09944200000001,68.27859500000005],[-100.11221299999994,68.27638200000007],[-100.12832600000002,68.27832000000006],[-100.14028899999994,68.28166199999998],[-100.16443600000002,68.28858900000006],[-100.20056199999999,68.299149],[-100.22693600000002,68.31608600000004],[-100.23082699999992,68.31971700000008],[-100.21556099999998,68.318604],[-100.20249899999988,68.31971700000008],[-100.19110099999995,68.32222000000007],[-100.1183319999999,68.34721400000001],[-100.11000100000001,68.35247800000002],[-100.08583099999998,68.36886600000008],[-100.07668299999989,68.359711],[-100.07444799999996,68.35498000000007],[-100.07472200000001,68.34971600000011]],[[-82.05999799999995,68.3060910000001],[-82.07250999999997,68.30304000000007],[-82.27111799999994,68.33859300000012],[-82.31277499999999,68.34915199999995],[-82.32667500000002,68.35359199999999],[-82.33805799999999,68.35832200000004],[-82.34445199999988,68.36276200000003],[-82.34555099999994,68.36775200000011],[-82.333328,68.371918],[-82.23055999999997,68.38554399999998],[-82.216949,68.38415500000013],[-82.13555899999994,68.37275699999998],[-82.01251200000002,68.35081500000007],[-82.00111399999997,68.34637500000008],[-81.99722300000002,68.34137000000004],[-82.01000999999991,68.33276400000011],[-82.05999799999995,68.3060910000001]],[[-111.11444099999994,68.40582300000005],[-111.12832600000002,68.40498400000013],[-111.13751199999996,68.40859999999998],[-111.141953,68.41331500000001],[-111.14890300000002,68.42886399999992],[-111.14917000000003,68.43997200000013],[-111.141953,68.444977],[-111.13054699999992,68.44747900000004],[-111.11527999999998,68.44775400000009],[-111.09861799999999,68.44693000000012],[-111.08249699999993,68.44470200000012],[-111.07611099999991,68.43691999999999],[-111.08416699999998,68.42498800000004],[-111.10582699999998,68.40998800000006],[-111.11444099999994,68.40582300000005]],[[-99.04527300000001,68.42387400000007],[-99.05499299999991,68.40832499999999],[-99.14778100000001,68.44220000000007],[-99.15472399999999,68.44636500000007],[-99.15916399999992,68.451096],[-99.14973399999985,68.45526100000001],[-99.12110899999999,68.45498700000007],[-99.10526999999996,68.45304899999996],[-99.087219,68.44941699999998],[-99.04527300000001,68.42387400000007]],[[-74.162216,68.24609399999997],[-74.19055200000003,68.24247700000001],[-74.20777899999996,68.24331700000005],[-74.221115,68.24720800000011],[-74.22888199999994,68.25082399999997],[-74.24415599999986,68.26138300000002],[-74.260559,68.27331499999997],[-74.38861099999997,68.39833099999998],[-74.39973399999997,68.42025799999999],[-74.40222199999994,68.42776500000014],[-74.400284,68.43414300000012],[-74.39306599999992,68.4452510000001],[-74.37693799999988,68.45971700000013],[-74.360275,68.46388200000013],[-74.34083599999991,68.46249399999999],[-74.30776999999995,68.46165500000006],[-74.29388399999999,68.46054100000009],[-74.27944899999994,68.45832800000011],[-74.26972999999987,68.45471200000003],[-74.21749899999986,68.42608600000011],[-74.19804399999998,68.41499299999992],[-74.07945299999994,68.33859300000012],[-74.07472200000001,68.33082599999994],[-74.07749899999999,68.32554600000009],[-74.14445499999994,68.25444000000005],[-74.14973399999985,68.25],[-74.162216,68.24609399999997]],[[-100.71056399999998,68.40248099999997],[-100.72416699999997,68.401657],[-100.78943599999997,68.40998800000006],[-100.88971699999996,68.45277400000009],[-100.88027999999997,68.45721400000014],[-100.84889199999992,68.4649960000001],[-100.83029199999999,68.46859699999993],[-100.79332699999986,68.46887200000015],[-100.78611799999999,68.46470600000009],[-100.71806300000003,68.41192600000005],[-100.71305799999999,68.407486],[-100.71056399999998,68.40248099999997]],[[-110.86250299999995,68.47415200000006],[-110.92610199999996,68.46582000000006],[-111.05444299999999,68.46971100000013],[-111.08833299999998,68.47331199999996],[-111.09750400000001,68.47720300000003],[-111.09750400000001,68.48275799999993],[-111.09249899999998,68.48719800000015],[-111.08528099999995,68.49220300000002],[-111.07528699999995,68.49552900000003],[-110.984734,68.51554900000008],[-110.82167099999998,68.54803499999997],[-110.80332899999996,68.54637100000014],[-110.79222099999998,68.54331999999994],[-110.76390100000003,68.53360000000004],[-110.74582700000002,68.52638200000007],[-110.69833399999999,68.49136400000003],[-110.69611399999991,68.48637400000001],[-110.70889299999988,68.48471100000006],[-110.72833300000002,68.48442100000005],[-110.79499799999996,68.47998000000013],[-110.86250299999995,68.47415200000006]],[[-110.58693700000003,68.52415500000001],[-110.625,68.51944000000015],[-110.6600039999999,68.521927],[-110.72112299999998,68.5310970000001],[-110.73249800000002,68.53414900000001],[-110.74610899999999,68.54248000000007],[-110.75974300000001,68.55664100000007],[-110.76194800000002,68.56164599999994],[-110.75473,68.566666],[-110.63861099999997,68.56944300000009],[-110.62832600000002,68.559143],[-110.52971600000001,68.54803499999997],[-110.520554,68.54414400000007],[-110.51834100000002,68.53915400000005],[-110.52722199999988,68.53498799999994],[-110.53859699999992,68.53248600000006],[-110.58693700000003,68.52415500000001]],[[-104.54527300000001,68.39610299999998],[-104.58667000000003,68.39444000000009],[-104.64666699999998,68.395828],[-104.693329,68.40248099999997],[-104.708618,68.40525800000006],[-104.75974299999996,68.41804500000006],[-104.88305699999995,68.449997],[-104.91915899999992,68.45999100000006],[-104.9375,68.46748400000007],[-105.08167999999995,68.54637100000014],[-105.04415899999998,68.56275900000003],[-105.024719,68.57054099999999],[-105.01390100000003,68.57331800000009],[-104.98999000000003,68.57748400000014],[-104.93859900000001,68.583328],[-104.91000399999996,68.58387800000003],[-104.76167299999997,68.58276400000005],[-104.74610899999993,68.58221400000002],[-104.71193699999998,68.57859799999994],[-104.682503,68.57388300000008],[-104.55332899999996,68.5372010000001],[-104.52999899999992,68.53054800000012],[-104.50917099999992,68.52331500000014],[-104.48277299999995,68.51165800000001],[-104.46916199999998,68.50332600000002],[-104.46362299999998,68.49887100000001],[-104.44915799999995,68.48526000000004],[-104.44055200000003,68.47608900000006],[-104.42777999999987,68.45694000000003],[-104.42527799999999,68.44136000000003],[-104.426941,68.43580600000001],[-104.43083199999995,68.42970300000007],[-104.43499799999995,68.42359900000002],[-104.44138299999997,68.41720600000008],[-104.45111099999991,68.41331500000001],[-104.48332199999999,68.40470900000008],[-104.51917299999997,68.39833099999998],[-104.54527300000001,68.39610299999998]],[[-105.139183,68.53637700000013],[-105.12609900000001,68.53332500000005],[-105.11305199999998,68.534424],[-105.10109699999998,68.536652],[-105.08693699999998,68.53692600000011],[-105.07861300000002,68.53305100000011],[-105.06639099999995,68.51914999999997],[-105.05972300000002,68.50943000000007],[-105.05888400000003,68.50416600000005],[-105.06833599999999,68.50027499999999],[-105.08612099999999,68.50277700000004],[-105.11193800000001,68.50888100000009],[-105.23361199999994,68.54109199999999],[-105.24416400000001,68.54470800000007],[-105.29110700000001,68.57693500000005],[-105.29222099999998,68.58221400000002],[-105.28138699999994,68.58499100000012],[-105.25611900000001,68.58831800000002],[-105.24305700000002,68.58970599999998],[-105.228882,68.58998099999997],[-105.21112099999993,68.5877690000001],[-105.18582200000003,68.58082600000012],[-105.18611099999998,68.57666],[-105.18167099999994,68.566666],[-105.17832900000002,68.56164599999994],[-105.139183,68.53637700000013]],[[-113.78611799999999,68.58276400000005],[-113.80166599999995,68.58248900000001],[-113.85249299999998,68.58415200000013],[-113.88945000000001,68.58692900000005],[-113.93138099999999,68.59387200000003],[-113.95259099999987,68.59738900000008],[-113.95966299999998,68.60319500000014],[-113.96611000000001,68.61109900000008],[-113.95667300000002,68.61469999999991],[-113.94248999999996,68.61581400000011],[-113.91388699999999,68.61581400000011],[-113.89972699999998,68.61692800000009],[-113.83693700000003,68.60887100000008],[-113.80027799999999,68.60609399999998],[-113.78611799999999,68.60386699999998],[-113.77667200000002,68.60026600000009],[-113.76194800000002,68.59220900000008],[-113.761124,68.58665500000012],[-113.77223199999997,68.58387800000003],[-113.78611799999999,68.58276400000005]],[[-100.74054699999999,68.59637500000002],[-100.78388999999993,68.59443700000008],[-100.86805699999991,68.60304300000001],[-100.88249200000001,68.61137400000007],[-100.87666300000001,68.61637900000011],[-100.86527999999998,68.61914100000001],[-100.85305800000003,68.62081899999998],[-100.839722,68.62164300000012],[-100.81388900000002,68.61914100000001],[-100.75556899999992,68.60775800000005],[-100.74082899999996,68.60470600000008],[-100.73361199999994,68.60054000000002],[-100.74054699999999,68.59637500000002]],[[-78.468887,68.563873],[-78.4744419999999,68.55831900000004],[-78.48222399999992,68.55331399999994],[-78.50306699999999,68.54553200000004],[-78.5308379999999,68.54109199999999],[-78.54583699999995,68.540817],[-78.56221,68.54193099999998],[-78.59922799999993,68.55064400000003],[-78.61455499999994,68.55365000000006],[-78.63890100000003,68.55802899999998],[-78.65472399999999,68.55859400000003],[-78.66888399999999,68.5541530000001],[-78.72471599999994,68.521927],[-78.71583599999991,68.51582300000001],[-78.69137599999999,68.50915500000002],[-78.67443800000001,68.50972000000007],[-78.65333599999997,68.51249699999994],[-78.63612399999994,68.51304600000009],[-78.62194799999997,68.50972000000007],[-78.617615,68.50721700000008],[-78.610275,68.5022130000001],[-78.61082499999998,68.49803200000002],[-78.61805699999996,68.49220300000002],[-78.70556599999998,68.45166000000012],[-78.71611000000001,68.44775400000009],[-78.74305700000002,68.44274899999999],[-78.77667200000002,68.43914799999999],[-78.79527299999995,68.43858300000011],[-78.81304899999992,68.43887300000011],[-78.82806399999998,68.44081100000005],[-78.86166399999996,68.44636500000007],[-78.87638900000002,68.45054600000014],[-78.95973200000003,68.47470099999998],[-78.94610599999999,68.50804100000005],[-78.94332899999995,68.51193200000012],[-78.936935,68.516388],[-78.82278400000001,68.54775999999998],[-78.80943299999996,68.55053700000008],[-78.791672,68.55026200000003],[-78.75917099999998,68.54803499999997],[-78.74388099999999,68.54609700000003],[-78.72389199999998,68.54748499999994],[-78.7041779999999,68.55470300000013],[-78.69888300000002,68.55802899999998],[-78.68888900000002,68.56469700000014],[-78.670837,68.57887299999999],[-78.66860999999994,68.583328],[-78.67277499999994,68.58859300000006],[-78.68055700000002,68.59332300000011],[-78.69305400000002,68.59693900000013],[-78.70584100000002,68.60054000000002],[-78.78416399999998,68.61859099999998],[-78.85139500000002,68.63415500000008],[-78.894455,68.64637800000014],[-78.89805599999994,68.64888000000002],[-78.88972499999994,68.65277100000009],[-78.86389200000002,68.65971400000012],[-78.83778399999989,68.66110200000003],[-78.72000100000002,68.65721100000013],[-78.68943799999994,68.65332000000006],[-78.495834,68.62776200000013],[-78.48194899999993,68.62498500000004],[-78.46945199999993,68.62109399999997],[-78.460556,68.61720300000007],[-78.46722399999999,68.56915300000009],[-78.468887,68.563873]],[[-74.76889,68.67387400000001],[-74.75666799999999,68.67276000000004],[-74.65583799999996,68.65498400000007],[-74.648346,68.65220600000009],[-74.52223199999997,68.56526200000002],[-74.51834099999991,68.55859400000003],[-74.53195199999988,68.55276500000002],[-74.55139200000002,68.55053700000008],[-74.58694499999996,68.54887400000013],[-74.7266689999999,68.55609100000004],[-74.74276700000001,68.55748000000006],[-74.80721999999992,68.56359900000007],[-74.82194500000003,68.56581099999994],[-74.83389299999999,68.56971700000003],[-74.84333799999996,68.57582100000008],[-74.870544,68.59887700000007],[-74.8830569999999,68.61303700000002],[-74.890289,68.62498500000004],[-74.80583200000001,68.66886899999997],[-74.796112,68.67164600000007],[-74.787216,68.67303500000003],[-74.77999899999998,68.67387400000001],[-74.77194199999991,68.67303500000003],[-74.76889,68.67387400000001]],[[-114.04723399999995,68.61360200000001],[-114.06139399999995,68.61248800000004],[-114.075287,68.61469999999991],[-114.10193600000002,68.625809],[-114.12666299999995,68.63720699999999],[-114.14890299999996,68.649429],[-114.16166699999991,68.6580350000001],[-114.18998699999986,68.68026699999996],[-114.186394,68.68359400000008],[-114.15387699999991,68.67970300000002],[-114.141953,68.67692599999992],[-114.14111299999996,68.67109700000009],[-114.05638099999987,68.63581800000003],[-114.04888900000003,68.63192700000013],[-114.041672,68.62776200000013],[-114.03778099999994,68.61692800000009],[-114.04723399999995,68.61360200000001]],[[-74.81138599999991,68.32054100000005],[-74.81750499999993,68.318604],[-75,68.33334400000012],[-75.00222799999995,68.33360300000004],[-75.00834699999996,68.3372040000001],[-75.01028400000001,68.34664900000001],[-75.00500499999993,68.35359199999999],[-75.002792,68.35914600000001],[-75.00140399999998,68.366379],[-75.01501499999995,68.37970000000013],[-75.02917499999995,68.39054900000002],[-75.03750599999995,68.39471400000002],[-75.08167999999989,68.40498400000013],[-75.10943599999996,68.40693700000008],[-75.13806199999999,68.40998800000006],[-75.15306099999987,68.41304000000002],[-75.241379,68.43637100000007],[-75.26390099999992,68.444977],[-75.29472399999997,68.457764],[-75.36999500000002,68.48970000000003],[-75.396118,68.503601],[-75.41639700000002,68.51805100000013],[-75.41639700000002,68.52442900000011],[-75.39695699999987,68.61109900000008],[-75.38917500000002,68.62303200000008],[-75.30777,68.69470200000006],[-75.29972799999996,68.70054600000009],[-75.28056299999997,68.70971700000007],[-75.25472999999988,68.71748400000001],[-75.239441,68.71804800000012],[-75.01445000000001,68.67720000000003],[-75,68.6722410000001],[-74.94276400000001,68.57609600000006],[-74.93832399999991,68.57165500000013],[-74.93138099999993,68.566666],[-74.83694500000001,68.51165800000001],[-74.801941,68.50109900000012],[-74.78500400000001,68.49470500000007],[-74.78028899999998,68.49026500000008],[-74.77223200000003,68.47998000000013],[-74.76834100000002,68.47331199999996],[-74.77639799999992,68.41053799999992],[-74.81138599999991,68.32054100000005]],[[-84.80804399999994,68.76388500000002],[-84.82139599999988,68.76361100000008],[-84.83583099999998,68.766663],[-84.93916300000001,68.79359400000004],[-84.90777600000001,68.8035890000001],[-84.89527900000002,68.80720500000001],[-84.88249200000001,68.80970799999994],[-84.85583500000001,68.81080600000001],[-84.841385,68.80748],[-84.837219,68.80276500000014],[-84.837784,68.79693600000013],[-84.80166599999995,68.76915000000008],[-84.80804399999994,68.76388500000002]],[[-68.110275,68.78276100000005],[-67.8074949999999,68.73359700000003],[-67.78167699999995,68.72915599999993],[-67.679169,68.71137999999996],[-67.66833500000001,68.70721400000008],[-67.66139199999992,68.7019350000001],[-67.662216,68.69831799999997],[-67.67666600000001,68.6958160000001],[-67.85055499999993,68.69775400000003],[-67.86972000000003,68.69859299999996],[-67.89778100000001,68.70498700000002],[-67.91860999999989,68.71249399999994],[-67.95140099999998,68.72164900000001],[-68.03916900000002,68.73803700000008],[-68.18832399999991,68.76388500000002],[-68.306107,68.7794340000001],[-68.323624,68.77998400000013],[-68.33999599999999,68.77859499999994],[-68.35249299999998,68.77554300000003],[-68.36749299999985,68.7749940000001],[-68.43360899999993,68.78109700000005],[-68.45140099999998,68.78387500000002],[-68.45777900000002,68.78581200000008],[-68.45944199999997,68.7910920000001],[-68.45527599999997,68.80219999999991],[-68.45083599999987,68.80720500000001],[-68.43916300000001,68.81248500000004],[-68.42832899999996,68.81303400000002],[-68.4188999999999,68.81025700000009],[-68.37554899999992,68.80802900000015],[-68.24194299999994,68.79887400000007],[-68.224716,68.79748500000011],[-68.110275,68.78276100000005]],[[-101.83112299999999,68.5669400000001],[-101.84555099999989,68.566666],[-101.86028299999998,68.56971700000003],[-101.88527699999986,68.57638500000002],[-101.90527299999991,68.58387800000003],[-102.00583599999999,68.61387599999995],[-102.112213,68.62359600000002],[-102.23000300000001,68.64027399999992],[-102.254997,68.64694200000008],[-102.31639100000001,68.67221100000006],[-102.3125,68.68858300000005],[-102.21665999999999,68.718323],[-102.14862099999999,68.73498499999994],[-102.13639799999993,68.7369230000001],[-102.11389200000002,68.74247700000006],[-102.09249899999998,68.74887100000012],[-102.073059,68.75694300000009],[-102.05638099999993,68.76805100000007],[-102.05166600000001,68.77388000000008],[-102.04943799999995,68.7794340000001],[-102.04972799999996,68.78471400000001],[-102.05555699999996,68.79443400000008],[-102.05555699999996,68.79971300000005],[-102.05082700000003,68.80554200000006],[-102.04276999999996,68.81109600000008],[-102.02306399999992,68.81944300000004],[-101.99833699999999,68.8230440000001],[-101.98500099999995,68.82415800000007],[-101.95612299999999,68.82415800000007],[-101.93943799999994,68.82249499999995],[-101.9119419999999,68.8160860000001],[-101.77861000000001,68.78387500000002],[-101.69387799999993,68.76805100000007],[-101.69999699999994,68.73776200000003],[-101.68055699999996,68.672485],[-101.68250299999994,68.66165200000006],[-101.701683,68.63777200000004],[-101.83112299999999,68.5669400000001]],[[-102.60082999999997,68.813309],[-102.60749799999996,68.80914300000012],[-102.69695299999995,68.81303400000002],[-102.70722999999992,68.81666600000011],[-102.68888900000002,68.83332800000011],[-102.67859599999997,68.836929],[-102.64055599999995,68.84193400000004],[-102.61277799999993,68.84304800000001],[-102.59889199999986,68.84109500000005],[-102.60221899999999,68.83415200000007],[-102.60082999999997,68.813309]],[[-89.94444299999998,68.66220099999998],[-89.95638999999994,68.66165200000006],[-89.97416699999997,68.705826],[-89.99916099999996,68.73081999999994],[-90.01722699999993,68.74054000000007],[-90.02250700000002,68.74581900000004],[-90.02749599999999,68.75248699999997],[-90.02778599999999,68.75860600000004],[-90.02555799999993,68.771927],[-90.00306699999993,68.80664100000001],[-89.958618,68.83804299999997],[-89.94444299999998,68.84748800000006],[-89.93194599999998,68.85220300000009],[-89.9219359999999,68.8538670000001],[-89.91444399999995,68.85304300000013],[-89.781677,68.766663],[-89.78416399999992,68.76081800000009],[-89.791382,68.75248699999997],[-89.80888400000003,68.73332200000004],[-89.85749800000002,68.70054600000009],[-89.87748699999992,68.690811],[-89.94444299999998,68.66220099999998]],[[-114.35082999999997,68.87164300000006],[-114.37917299999992,68.86943100000002],[-114.39639299999999,68.86970500000012],[-114.429169,68.87359600000002],[-114.45333900000003,68.87942500000003],[-114.46305799999999,68.88275100000004],[-114.468613,68.88720699999999],[-114.471657,68.89248700000002],[-114.46056399999998,68.89526400000011],[-114.44444299999998,68.8961030000001],[-114.424713,68.89694200000002],[-114.37609899999995,68.8936000000001],[-114.340843,68.89054900000008],[-114.328888,68.887497],[-114.32333399999999,68.88304100000005],[-114.32861299999996,68.87692300000009],[-114.33805799999993,68.87359600000002],[-114.35082999999997,68.87164300000006]],[[-67.84777799999995,68.85192899999998],[-67.86389199999996,68.849426],[-67.88305699999995,68.84999099999999],[-67.89723200000003,68.85304300000013],[-67.908051,68.85720800000013],[-67.95638999999994,68.91526800000003],[-67.96055599999994,68.922485],[-67.96055599999994,68.92997700000006],[-67.95472699999993,68.93580600000013],[-67.94665499999996,68.940811],[-67.93804899999998,68.94442700000002],[-67.92388900000003,68.94859300000013],[-67.89222699999999,68.95166],[-67.87638899999996,68.9494170000001],[-67.86944599999998,68.94413800000007],[-67.83944699999995,68.91192600000011],[-67.83139,68.87580900000012],[-67.83306899999991,68.86137400000001],[-67.83750900000001,68.85636899999997],[-67.84777799999995,68.85192899999998]],[[-85.34167500000001,68.98359699999997],[-85.35166900000002,68.98109400000004],[-85.37916599999994,68.98193400000008],[-85.40722700000003,68.98442099999994],[-85.43721,68.99192800000009],[-85.44694499999997,68.99636800000007],[-85.45140099999998,69.00109900000001],[-85.45306399999998,69.00582900000006],[-85.44387799999987,69.01026900000011],[-85.41888399999999,69.00943000000012],[-85.36999500000002,69.001938],[-85.35472099999993,68.99775700000009],[-85.34222399999993,68.9933170000001],[-85.337784,68.98858599999994],[-85.34167500000001,68.98359699999997]],[[-89.90834000000001,68.91775500000011],[-89.915009,68.91331500000013],[-89.95249899999988,68.92637600000006],[-89.97833299999996,68.93386799999996],[-90,68.93757599999998],[-90.03195199999999,68.94303900000011],[-90.07556199999999,68.94802899999996],[-90.07055700000001,68.98193400000008],[-89.94638099999992,69.01026900000011],[-89.93360899999999,69.01165800000007],[-89.920837,69.01026900000011],[-89.91416900000002,69.00694300000004],[-89.91027799999995,69.00305200000014],[-89.90666199999998,68.922485],[-89.90834000000001,68.91775500000011]],[[-100.17555199999987,68.79470800000001],[-100.22083999999995,68.76443500000005],[-100.25446299999999,68.76915000000008],[-100.26917300000002,68.77221700000001],[-100.28555299999994,68.77415500000012],[-100.29915599999998,68.77331500000008],[-100.30860899999999,68.76887500000004],[-100.31639100000001,68.76249700000011],[-100.35749799999996,68.71527100000003],[-100.36694299999994,68.71054100000003],[-100.40722699999998,68.70803800000004],[-100.423607,68.709991],[-100.61332700000003,68.75804099999999],[-100.62304699999999,68.76193200000006],[-100.62805199999997,68.766388],[-100.632767,68.77609300000006],[-100.62581599999999,68.91249099999993],[-100.59999099999999,69.00054899999998],[-100.56111099999993,69.02581800000002],[-100.54360999999994,69.03665200000006],[-100.52916699999997,69.03665200000006],[-100.497772,69.03471400000012],[-100.41610700000001,69.02638200000013],[-100.38110399999994,69.02082800000011],[-100.35082999999997,69.0147090000001],[-100.34111000000001,69.01081800000003],[-100.33361799999994,69.00665300000003],[-100.32861300000002,69.00221300000004],[-100.32362399999994,68.99609399999997],[-100.328888,68.98997500000013],[-100.33168,68.98442099999994],[-100.33168,68.97943100000009],[-100.326683,68.97470100000004],[-100.31276700000001,68.96582000000012],[-100.23889200000002,68.924149],[-100.22888199999994,68.9202580000001],[-100.21665999999988,68.91693099999998],[-100.20361300000002,68.91554300000007],[-100.16027799999995,68.91526800000003],[-100.14362299999993,68.91331500000013],[-100.131104,68.909988],[-100.12638899999996,68.90554800000012],[-100.17194399999994,68.79942300000005],[-100.17555199999987,68.79470800000001]],[[-85.11944599999993,69.0147090000001],[-85.13221699999986,69.01304599999997],[-85.16610700000001,69.03109699999999],[-85.17027300000001,69.03581200000002],[-85.15556299999997,69.05609099999998],[-85.14555399999989,69.0583190000001],[-85.095551,69.04803500000008],[-85.06834399999997,69.0413670000001],[-85.06138599999991,69.03665200000006],[-85.07583599999992,69.03109699999999],[-85.11944599999993,69.0147090000001]],[[-85.265289,69.07249500000012],[-85.34388699999994,69.06303400000013],[-85.35777300000001,69.06359899999995],[-85.37304699999993,69.06776399999995],[-85.39277600000003,69.07666000000012],[-85.39723200000003,69.08137499999992],[-85.39889499999998,69.08610499999998],[-85.39250199999998,69.09137000000004],[-85.38027999999991,69.09582500000005],[-85.30139200000002,69.10415599999999],[-85.28778099999988,69.10470600000002],[-85.258896,69.10026600000015],[-85.24888599999991,69.09582500000005],[-85.24194299999999,69.09137000000004],[-85.245544,69.08610499999998],[-85.24665800000002,69.08137499999992],[-85.25306699999999,69.07609599999995],[-85.265289,69.07249500000012]],[[-99.99943499999995,68.94358800000003],[-100.006958,68.93942300000003],[-100.021118,68.93969699999997],[-100.03778099999988,68.94136000000009],[-100.12000299999994,68.95082100000008],[-100.16166699999997,68.96138000000013],[-100.18138099999999,68.96887200000003],[-100.19860799999998,68.97692900000004],[-100.20612299999988,68.98109400000004],[-100.23693800000001,69.00860599999999],[-100.25666799999999,69.02665699999994],[-100.25890399999992,69.03166199999998],[-100.25862099999995,69.04193100000003],[-100.23693800000001,69.08137499999992],[-100.23194899999993,69.08720399999999],[-100.21333300000003,69.09721400000006],[-100.12970699999994,69.13026400000012],[-100.09555099999994,69.11747700000012],[-100.05304699999999,69.10247800000002],[-100.03333299999991,69.09471100000007],[-100.02834299999995,69.09027100000009],[-99.978882,69.01388500000013],[-99.97694399999995,69.0038760000001],[-99.99943499999995,68.94358800000003]],[[-90.12471,69.04942299999999],[-90.12721299999987,69.04498299999995],[-90.13806199999999,69.04525799999999],[-90.23194899999999,69.06553600000001],[-90.24749800000001,69.07026700000011],[-90.27917500000001,69.09832800000004],[-90.27639799999986,69.12580900000006],[-90.26333599999992,69.14193699999993],[-90.26251199999996,69.14276100000006],[-90.25389099999995,69.14276100000006],[-90.14723199999997,69.10359199999999],[-90.125,69.055542],[-90.12471,69.04942299999999]],[[-101.66416900000002,69.0836030000001],[-101.67749000000003,69.08276400000011],[-101.69027699999998,69.08610499999998],[-101.69554099999993,69.09054600000007],[-101.69833399999993,69.09526100000011],[-101.71806300000003,69.17858899999993],[-101.715843,69.18914799999999],[-101.71112099999993,69.1952510000001],[-101.70361300000002,69.20166],[-101.695267,69.20694000000003],[-101.68443300000001,69.21081500000003],[-101.65834000000001,69.21360800000002],[-101.60166899999996,69.21554600000013],[-101.55860899999999,69.2166600000001],[-101.53527799999995,69.20942700000012],[-101.5202789999999,69.1974790000001],[-101.497772,69.17025800000005],[-101.49500299999994,69.16554300000001],[-101.49500299999994,69.16026299999993],[-101.49999999999994,69.1544340000001],[-101.55555699999991,69.10525500000011],[-101.563606,69.09999099999999],[-101.65139799999997,69.08554100000003],[-101.66416900000002,69.0836030000001]],[[-90.51251200000002,69.20248400000014],[-90.57556199999999,69.19859300000007],[-90.61332700000003,69.207764],[-90.777222,69.272491],[-90.7786099999999,69.31721500000015],[-90.77583299999998,69.32998699999996],[-90.76251200000002,69.34553499999998],[-90.75723299999999,69.34942600000005],[-90.74082900000002,69.35748300000006],[-90.69221500000003,69.37164300000012],[-90.67332499999992,69.37387100000007],[-90.65527299999997,69.37469500000003],[-90.63861099999997,69.37387100000007],[-90.608047,69.36970500000001],[-90.59500100000002,69.36526499999997],[-90.58250399999997,69.359711],[-90.55943300000001,69.34721400000001],[-90.54861499999998,69.33998100000002],[-90.47193900000002,69.2810970000001],[-90.46083099999993,69.26748700000002],[-90.45556599999998,69.23471100000012],[-90.45445299999989,69.22637900000012],[-90.45750399999997,69.22276300000004],[-90.51251200000002,69.20248400000014]],[[-78.41221599999989,69.37970000000013],[-78.39639299999993,69.37776199999996],[-78.33860800000002,69.3808140000001],[-78.30583200000001,69.37776199999996],[-78.291382,69.3749850000001],[-78.27972399999999,69.37025500000004],[-78.27084400000001,69.36415099999999],[-78.21139499999992,69.29998799999998],[-78.21083099999998,69.29443400000014],[-78.214447,69.28831500000013],[-78.31834400000002,69.23831200000001],[-78.396118,69.21054100000009],[-78.47250400000001,69.19136000000003],[-78.55139200000002,69.08915700000006],[-78.55665599999992,69.0836030000001],[-78.57223499999992,69.07331799999997],[-78.60194399999995,69.06608600000004],[-78.62777699999998,69.05859399999991],[-78.70722999999998,69.0147090000001],[-78.71501199999994,69.00972000000013],[-78.71806299999997,69.00360100000012],[-78.71665999999999,68.99664300000012],[-78.712784,68.98498500000011],[-78.71611000000001,68.9791560000001],[-78.725281,68.96887200000003],[-78.73500099999995,68.96360800000008],[-78.83029199999993,68.91304000000008],[-78.84028599999994,68.90860000000009],[-78.86749299999997,68.90054300000008],[-78.93443300000001,68.88859600000012],[-78.978882,68.88247700000011],[-79.033615,68.87719700000002],[-79.09527599999996,68.87275700000004],[-79.18527199999994,68.85331700000006],[-79.19415299999997,68.849426],[-79.1972199999999,68.83915700000011],[-79.20472699999999,68.83387800000014],[-79.216949,68.82998700000007],[-79.23889200000002,68.82748400000008],[-79.287216,68.83137499999998],[-79.35333299999996,68.84414700000002],[-79.3661039999999,68.84776300000004],[-79.38694800000002,68.85609399999998],[-79.39250199999987,68.86053500000008],[-79.39639299999993,68.86499000000009],[-79.400284,68.87191800000005],[-79.40222199999994,68.92359899999997],[-79.37943999999993,68.93165600000009],[-79.353882,68.94386300000008],[-79.33056599999998,68.958328],[-79.30943299999996,68.97360200000008],[-79.30387899999994,68.97831700000012],[-79.29276999999996,68.99581899999998],[-79.28306599999996,69.01277200000004],[-79.23889200000002,69.06637600000005],[-79.22721899999999,69.07638500000007],[-79.216949,69.0811000000001],[-79.14611799999994,69.0935970000001],[-79.04943800000001,69.10220300000003],[-78.98582499999998,69.09999099999999],[-78.97444199999995,69.10026600000015],[-78.96028099999995,69.10247800000002],[-78.86416599999995,69.141098],[-78.85583499999996,69.14553799999999],[-78.7491609999999,69.26110799999998],[-78.72193899999996,69.31053200000002],[-78.7266689999999,69.318604],[-78.72471599999994,69.33110000000005],[-78.722778,69.33610500000009],[-78.71611000000001,69.34027100000003],[-78.60694899999999,69.37136800000013],[-78.57749899999999,69.37719700000014],[-78.56861899999996,69.37886000000003],[-78.48998999999998,69.39109800000011],[-78.47084000000001,69.39221200000009],[-78.45861799999994,69.38998400000014],[-78.41221599999989,69.37970000000013]],[[-135.28890999999993,69.30941800000005],[-135.29751599999997,69.30497700000012],[-135.33138999999989,69.322769],[-135.34805299999994,69.33055100000013],[-135.38613899999996,69.34498600000006],[-135.39779699999997,69.34803799999997],[-135.440002,69.35582000000011],[-135.486938,69.36219800000009],[-135.515015,69.36747700000006],[-135.52694699999995,69.37052900000015],[-135.559998,69.38026400000007],[-135.56527700000004,69.384995],[-135.56555199999997,69.39054899999996],[-135.559998,69.39665200000013],[-135.54998799999998,69.39999400000005],[-135.52444499999996,69.40359500000011],[-135.50723300000004,69.40304600000013],[-135.42028799999997,69.39749100000006],[-135.365814,69.39359999999999],[-135.33776899999992,69.38859600000006],[-135.32806400000004,69.384995],[-135.27224699999988,69.35832199999999],[-135.271393,69.34693899999996],[-135.277222,69.32832299999995],[-135.28332499999988,69.31526200000002],[-135.28890999999993,69.30941800000005]],[[-76.95083599999987,69.395264],[-76.92361499999998,69.39359999999999],[-76.902222,69.39471399999996],[-76.80416899999994,69.40026900000004],[-76.787781,69.40248099999997],[-76.77917499999995,69.4038700000001],[-76.76083399999987,69.40914900000007],[-76.75140399999998,69.41276600000003],[-76.74444599999998,69.41693100000003],[-76.73277299999995,69.42276000000004],[-76.72332799999998,69.42359900000002],[-76.71640000000002,69.42221100000012],[-76.70584099999996,69.41886899999997],[-76.65222199999994,69.38638300000008],[-76.64472999999992,69.38136300000002],[-76.64388999999994,69.37442000000004],[-76.64666699999998,69.33692900000005],[-76.64889499999992,69.33194000000009],[-76.67639199999996,69.3060910000001],[-76.70639,69.30358899999999],[-76.718887,69.30165100000005],[-76.73693799999995,69.29637100000002],[-76.79943800000001,69.272491],[-76.92639200000002,69.21748400000007],[-76.93360899999993,69.21388200000013],[-76.93998699999997,69.20915200000007],[-76.945831,69.20359800000011],[-76.94943199999994,69.1974790000001],[-76.95056199999993,69.1933140000001],[-76.95889299999999,69.14248699999996],[-77.11805700000002,69.11943100000013],[-77.137787,69.11665299999993],[-77.17166099999992,69.11720299999996],[-77.21362299999998,69.12580900000006],[-77.23860199999996,69.13275099999998],[-77.25778200000002,69.13998400000003],[-77.28582799999992,69.153595],[-77.30139200000002,69.164154],[-77.32028199999996,69.18136600000003],[-77.38194299999986,69.24748200000005],[-77.38417099999998,69.26361099999997],[-77.38333099999994,69.27053800000004],[-77.35972599999997,69.39276100000006],[-77.35638399999993,69.39665200000013],[-77.34834299999994,69.401657],[-77.28832999999992,69.417755],[-77.25917099999992,69.42469800000003],[-77.18916299999995,69.438309],[-77.15361000000001,69.44442700000008],[-77.12998999999996,69.44525100000004],[-77.11361699999998,69.44165000000004],[-77.07556199999999,69.42831400000006],[-77.04333500000001,69.41720600000008],[-77.006958,69.40637200000003],[-76.9783329999999,69.39999400000005],[-76.95083599999987,69.395264]],[[-90.329453,69.23580900000002],[-90.34722899999997,69.23471100000012],[-90.36138899999997,69.23831200000001],[-90.50639299999995,69.329163],[-90.51000999999991,69.33471700000001],[-90.51445000000001,69.363876],[-90.50111399999997,69.3724820000001],[-90.491669,69.37664799999999],[-90.30194099999994,69.43441800000011],[-90.20527599999991,69.4458160000001],[-90.20083599999998,69.44442700000008],[-90.19972200000001,69.4391480000001],[-90.195267,69.41693100000003],[-90.178604,69.40998800000006],[-90.14973399999997,69.37553400000002],[-90.14834599999995,69.37025500000004],[-90.15472399999999,69.35081500000007],[-90.15972899999997,69.34526100000005],[-90.27166699999992,69.25555400000002],[-90.28860500000002,69.24941999999999],[-90.329453,69.23580900000002]],[[-135.592224,69.48220800000007],[-135.574432,69.44664000000006],[-135.61999499999996,69.4685970000001],[-135.6294249999999,69.47221400000006],[-135.665283,69.48136899999992],[-135.693604,69.486649],[-135.74081399999994,69.49304199999995],[-135.778351,69.49609400000008],[-135.81054700000004,69.49775699999998],[-135.81555200000003,69.50248700000003],[-135.8125,69.50804100000005],[-135.79528799999997,69.51666300000005],[-135.785553,69.51998900000007],[-135.77389500000004,69.52276599999999],[-135.76113899999996,69.52442900000005],[-135.74526999999995,69.5247040000001],[-135.666107,69.50582899999995],[-135.599426,69.48609899999997],[-135.592224,69.48220800000007]],[[-101.05304699999999,69.50443999999999],[-101.00611900000001,69.4869230000001],[-101.00862099999995,69.45027200000004],[-101.12526700000001,69.40138200000013],[-101.21861299999989,69.37136800000013],[-101.23029299999996,69.36859100000004],[-101.24305700000002,69.371918],[-101.26888999999994,69.37886000000003],[-101.27916700000003,69.382477],[-101.271118,69.38581800000003],[-101.256958,69.38665800000007],[-101.24526999999995,69.38943499999999],[-101.2369379999999,69.39471399999996],[-101.23166699999996,69.40081800000002],[-101.18888899999996,69.46971100000007],[-101.186394,69.47526599999998],[-101.22749299999992,69.49552900000003],[-101.23805199999998,69.499146],[-101.2538909999999,69.50027499999999],[-101.266953,69.49832200000003],[-101.31749699999995,69.51110799999992],[-101.38445300000001,69.53276100000005],[-101.38722199999995,69.53776600000009],[-101.358337,69.5669400000001],[-101.34973099999996,69.572495],[-101.34056099999992,69.57470700000005],[-101.27555799999993,69.58082600000006],[-101.26167299999992,69.58166500000004],[-101.07305899999994,69.53498800000011],[-101.06276699999995,69.53137200000009],[-101.05999800000001,69.52638200000001],[-101.05304699999999,69.50443999999999]],[[-96.66305499999993,69.56971700000003],[-96.56332399999997,69.56414799999999],[-96.46112099999999,69.56414799999999],[-96.4016719999999,69.56275900000003],[-96.37361099999998,69.56080600000007],[-96.35888699999987,69.55720500000001],[-96.35194399999995,69.55304000000001],[-96.3452759999999,69.54859900000008],[-96.343887,69.54359400000004],[-96.335556,69.534424],[-96.32861300000002,69.52998399999996],[-96.31639100000001,69.52638200000001],[-96.29167199999989,69.53109700000005],[-96.21806300000003,69.54637100000014],[-96.20722999999998,69.55053700000002],[-96.19833399999987,69.55664100000007],[-96.19444299999998,69.56192000000004],[-96.18443299999996,69.56721500000009],[-96.16972399999992,69.5669400000001],[-96.152222,69.56359900000007],[-96.13999899999993,69.5599820000001],[-96.13333099999994,69.55554200000006],[-96.13444500000003,69.55026200000003],[-96.13639799999999,69.54609700000003],[-96.10417199999995,69.49832200000003],[-96.10110499999996,69.49304199999995],[-96.097778,69.48332200000004],[-96.096115,69.46804800000001],[-96.09861799999999,69.45776399999994],[-96.14306599999992,69.35137900000001],[-96.14666699999998,69.34582499999999],[-96.16332999999997,69.34803799999997],[-96.23388699999998,69.359711],[-96.24861099999993,69.36303700000002],[-96.27000399999997,69.37081899999998],[-96.28860499999996,69.37886000000003],[-96.30499299999991,69.38749700000005],[-96.32528699999995,69.40026900000004],[-96.33361799999994,69.40971400000012],[-96.348343,69.42303500000008],[-96.38221699999991,69.44470200000012],[-96.40110800000002,69.45304899999991],[-96.43055700000002,69.45971700000007],[-96.46194499999996,69.46249399999999],[-96.50723299999999,69.4644320000001],[-96.524719,69.46748400000001],[-96.54888900000003,69.47499099999999],[-96.63082899999995,69.5122070000001],[-96.65417500000001,69.5249940000001],[-96.73666399999996,69.57666],[-96.73554999999999,69.58194000000003],[-96.72166399999992,69.58248900000001],[-96.69166599999988,69.58194000000003],[-96.676941,69.57832300000013],[-96.66305499999993,69.56971700000003]],[[-67.31054699999993,69.54914900000011],[-67.32417299999997,69.53387500000002],[-67.33168,69.53137200000009],[-67.35110500000002,69.53082300000011],[-67.38861099999997,69.53305100000006],[-67.47305299999994,69.53387500000002],[-67.49276699999996,69.53305100000006],[-67.53083799999996,69.52915999999999],[-67.5452729999999,69.52581800000007],[-67.55248999999998,69.52304100000015],[-67.5494379999999,69.51971400000002],[-67.50723299999999,69.51499899999999],[-67.49999999999994,69.51283300000006],[-67.49888599999997,69.51249700000011],[-67.48999000000003,69.50860600000004],[-67.48167399999994,69.50000000000011],[-67.49249299999985,69.49552900000003],[-67.50778200000002,69.49498000000011],[-67.573624,69.50665300000009],[-67.58555599999994,69.50749200000007],[-67.59889199999998,69.5063780000001],[-67.62666299999995,69.50054900000009],[-67.64222699999988,69.50027499999999],[-67.73194899999993,69.51361100000008],[-67.74444599999993,69.51582299999995],[-67.74972500000001,69.52110300000004],[-67.73944099999994,69.54081700000012],[-67.73083499999996,69.54443400000008],[-67.723053,69.54525800000005],[-67.70722999999998,69.54443400000008],[-67.68666100000002,69.54109199999999],[-67.67471299999988,69.54026800000003],[-67.66332999999997,69.54193099999992],[-67.57806399999998,69.559708],[-67.55027799999993,69.56553600000012],[-67.541382,69.56915300000003],[-67.531387,69.57638499999996],[-67.527222,69.58194000000003],[-67.48443599999996,69.59027100000014],[-67.42500299999995,69.58888200000013],[-67.394455,69.58499100000006],[-67.36721799999992,69.57832300000013],[-67.321396,69.56053199999997],[-67.314438,69.55664100000007],[-67.30943300000001,69.55276500000002],[-67.31054699999993,69.54914900000011]],[[-96.76055899999994,69.54553199999998],[-96.77000399999991,69.54359400000004],[-96.78666699999991,69.54553199999998],[-96.86888099999987,69.5558170000001],[-96.883896,69.55914300000012],[-96.88806199999999,69.563873],[-96.902222,69.5977630000001],[-96.900284,69.60220300000009],[-96.870544,69.60137900000012],[-96.85139500000002,69.599426],[-96.84083599999997,69.59748800000006],[-96.81639100000001,69.59027100000014],[-96.80943300000001,69.58581500000003],[-96.76640299999997,69.55497700000006],[-96.76194799999996,69.55053700000002],[-96.76055899999994,69.54553199999998]],[[-91.11000100000001,69.54942300000005],[-91.11915599999998,69.54832499999998],[-91.14028899999994,69.56080600000007],[-91.14250199999992,69.56498699999997],[-91.13639799999999,69.57554600000003],[-91.12138400000003,69.59304800000007],[-91.10888699999992,69.60220300000009],[-91.03721599999994,69.61499000000009],[-90.96916199999993,69.61831700000005],[-90.95973200000003,69.61943100000002],[-90.93749999999994,69.61637900000011],[-90.92304999999993,69.61137400000007],[-90.92027299999995,69.6080320000001],[-90.91915899999998,69.60609399999998],[-90.93083200000001,69.59915200000006],[-91.11000100000001,69.54942300000005]],[[-133.93222000000003,69.56025699999992],[-133.948059,69.56025699999992],[-133.96304299999997,69.56137100000012],[-133.98611499999998,69.56553600000012],[-134.01196299999992,69.57138100000003],[-134.01666299999994,69.57609600000006],[-134.01419099999998,69.58248900000001],[-134.010284,69.58554100000009],[-133.94528199999996,69.61331200000001],[-133.93362399999995,69.6160890000001],[-133.89446999999996,69.62109399999997],[-133.87997399999995,69.62191800000011],[-133.86581399999994,69.61914100000001],[-133.84472700000003,69.60081500000001],[-133.84695399999998,69.58888200000013],[-133.868042,69.56721500000009],[-133.87719699999997,69.56526199999996],[-133.93222000000003,69.56025699999992]],[[-95.48889200000002,69.56553600000012],[-95.45249899999993,69.55026200000003],[-95.37554899999998,69.51776100000012],[-95.366104,69.51361100000008],[-95.35972600000002,69.50915500000002],[-95.362213,69.49887099999995],[-95.40249599999999,69.383331],[-95.51583900000003,69.33082600000012],[-95.527222,69.32748400000003],[-95.53971899999999,69.32527199999993],[-95.60638399999993,69.31915300000009],[-95.62027,69.318604],[-95.63417099999992,69.31832900000012],[-95.69248999999996,69.31915300000009],[-95.706955,69.31944299999992],[-95.722778,69.32083100000006],[-95.73693800000001,69.32443200000006],[-95.741104,69.329163],[-95.74166899999994,69.33471700000001],[-95.73167399999994,69.37303199999997],[-95.72778299999987,69.37858599999993],[-95.716949,69.38275099999993],[-95.69387799999998,69.38943499999999],[-95.66915899999998,69.39415000000002],[-95.65777600000001,69.39721700000013],[-95.648346,69.40332000000006],[-95.66639700000002,69.49775699999998],[-95.66915899999998,69.50749200000007],[-95.69444299999998,69.54026800000003],[-95.70805399999995,69.54887400000013],[-95.72000100000002,69.55276500000002],[-95.7366639999999,69.55497700000006],[-95.81582600000002,69.56275900000003],[-95.82749899999993,69.559708],[-95.83168,69.5541530000001],[-95.82278400000001,69.51443500000005],[-95.81750499999993,69.50499000000002],[-95.80943299999996,69.49552900000003],[-95.79722599999997,69.48165899999998],[-95.862213,69.34803799999997],[-95.87222300000002,69.34275800000006],[-95.89944500000001,69.34082000000012],[-95.96167000000003,69.34637500000002],[-95.978882,69.34942600000005],[-95.99082900000002,69.35331700000012],[-96.01112399999988,69.47804300000007],[-96.00973499999998,69.48304700000006],[-95.91999800000002,69.595261],[-95.90916400000003,69.599426],[-95.78944399999995,69.63415500000008],[-95.77389499999992,69.6327510000001],[-95.62554899999992,69.6160890000001],[-95.61221299999994,69.61442599999998],[-95.48889200000002,69.56553600000012]],[[-138.86721799999992,69.58831800000002],[-138.87332200000003,69.58305400000006],[-138.88305699999995,69.5794370000001],[-138.91000399999996,69.57609600000006],[-138.945831,69.57887299999993],[-138.97720300000003,69.58305400000006],[-138.99609399999997,69.58415200000013],[-139.02307099999996,69.58082600000006],[-139.03418,69.57804899999996],[-139.05307,69.57054099999999],[-139.12109399999997,69.52915999999999],[-139.137787,69.53082300000011],[-139.33248899999995,69.56608599999993],[-139.32998699999996,69.57165500000013],[-139.32223499999992,69.57609600000006],[-139.26779199999993,69.60582000000005],[-139.24221799999992,69.61831700000005],[-139.232758,69.62191800000011],[-139.19973800000002,69.630539],[-139.144165,69.64498900000012],[-139.133057,69.64776600000005],[-139.12027,69.64999399999999],[-139.10333299999996,69.64804100000003],[-139.02029399999998,69.63333100000011],[-138.956116,69.61970500000012],[-138.92111199999994,69.61053500000008],[-138.88055399999996,69.59693900000013],[-138.872772,69.59275800000006],[-138.86721799999992,69.58831800000002]],[[-135.51724199999995,69.56915300000003],[-135.54305999999997,69.56553600000012],[-135.55721999999997,69.56805400000007],[-135.57138099999997,69.57693499999999],[-135.581116,69.58055100000007],[-135.5883179999999,69.58471700000013],[-135.591095,69.58998099999997],[-135.5894469999999,69.59609999999998],[-135.58612099999993,69.601654],[-135.578888,69.60664400000002],[-135.55471799999992,69.62025499999999],[-135.51196299999998,69.64166300000011],[-135.50030500000003,69.64443999999997],[-135.43972799999995,69.65248100000008],[-135.42388900000003,69.65248100000008],[-135.4097289999999,69.64999399999999],[-135.39779699999997,69.64694200000008],[-135.40918,69.63499500000012],[-135.4655459999999,69.58554100000009],[-135.474152,69.58137500000004],[-135.505585,69.57165500000013],[-135.51724199999995,69.56915300000003]],[[-67.92027300000001,69.521927],[-67.93527199999994,69.5188750000001],[-68.002228,69.52665700000006],[-68.04943799999995,69.53387500000002],[-68.23889200000002,69.57026700000006],[-68.24888599999991,69.59664900000013],[-68.07833900000003,69.66526800000008],[-67.9708399999999,69.70193500000005],[-67.95973199999997,69.70498700000002],[-67.94638099999997,69.7063750000001],[-67.89555399999995,69.70860300000004],[-67.889725,69.70832800000005],[-67.86972000000003,69.70082100000008],[-67.82112099999995,69.67637600000006],[-67.83168,69.60192899999998],[-67.910278,69.52665700000006],[-67.92027300000001,69.521927]],[[-134.26058999999987,68.73353599999996],[-134.2324829999999,68.7061000000001],[-134.22778299999993,68.70138500000007],[-134.227264,68.69642600000009],[-134.23580900000002,68.69497700000011],[-134.267792,68.6958160000001],[-134.35693400000002,68.70304900000008],[-134.38861099999997,68.70721400000008],[-134.436127,68.71360800000014],[-134.45748899999995,68.71914700000013],[-134.46194499999996,68.72387700000013],[-134.49554399999994,68.75221300000004],[-134.53640699999994,68.78692600000005],[-134.6694639999999,68.89444000000015],[-134.741669,68.93553199999997],[-134.75500499999987,68.94442700000002],[-134.7669679999999,68.95332300000013],[-134.78306599999996,68.96535500000005],[-134.82583599999998,68.97886699999998],[-134.852783,68.97637900000001],[-134.892242,68.971924],[-134.904724,68.969986],[-134.914734,68.96665999999999],[-134.92028799999997,68.96081500000008],[-134.91973899999994,68.9494170000001],[-134.91723599999995,68.94413800000007],[-134.91641199999998,68.9269260000001],[-134.92028799999997,68.91470300000003],[-134.925842,68.90860000000009],[-134.93307499999997,68.903595],[-134.941376,68.89942900000011],[-134.961121,68.89248700000002],[-134.97500599999995,68.89166300000005],[-134.99999999999994,68.89208200000007],[-135.00750699999998,68.89221200000003],[-135.126099,68.89942900000011],[-135.14196800000002,68.90138200000007],[-135.167236,68.90721100000007],[-135.17083699999995,68.91110200000014],[-135.17807,68.92082200000004],[-135.18084699999997,68.926086],[-135.20165999999995,68.9327550000001],[-135.2333069999999,68.934708],[-135.262787,68.93359400000003],[-135.36111500000004,68.92665100000005],[-135.39196799999996,68.92665100000005],[-135.42138699999987,68.92886400000003],[-135.444458,68.93498199999993],[-135.45388799999995,68.938583],[-135.46081499999997,68.9427490000001],[-135.76916499999993,68.89637800000008],[-135.808044,68.89526400000011],[-135.843323,68.89721700000007],[-135.882477,68.90525800000012],[-135.90585299999992,68.91137699999996],[-135.94805899999994,68.92469800000009],[-135.99527,68.94247400000006],[-136.002502,68.94664],[-136.00527999999997,68.95193500000005],[-135.98916599999995,69.0291600000001],[-135.98525999999998,69.03581200000002],[-135.97833299999996,69.04081700000006],[-135.968597,69.04443400000002],[-135.95443699999998,69.0455320000001],[-135.8886109999999,69.026093],[-135.85012800000004,69.00740100000013],[-135.83389299999993,68.99832200000014],[-135.8288879999999,68.99359100000004],[-135.80248999999992,68.98942600000004],[-135.77002,68.98915099999999],[-135.64889499999998,68.99192800000009],[-135.63473499999998,68.99304200000006],[-135.57861300000002,69.00610400000011],[-135.52557399999995,69.02110299999998],[-135.517792,69.02388000000008],[-135.529449,69.02693199999999],[-135.720825,69.04609700000015],[-135.91583300000002,69.08831800000013],[-135.92748999999998,69.09137000000004],[-135.93472299999996,69.09553500000004],[-135.95138499999996,69.14276100000006],[-135.96582,69.19775400000009],[-135.967224,69.21470600000009],[-135.95944199999997,69.22831700000006],[-135.94695999999993,69.23942599999998],[-135.92611699999998,69.25471500000003],[-135.915009,69.25749200000013],[-135.898621,69.25555400000002],[-135.891388,69.25138900000002],[-135.82138099999986,69.21527100000014],[-135.75140399999998,69.17942800000009],[-135.741943,69.17581200000006],[-135.666107,69.14694199999997],[-135.65667699999995,69.14360000000005],[-135.56750499999993,69.11775200000011],[-135.5527949999999,69.11665299999993],[-135.486938,69.11331200000012],[-135.49581899999993,69.124146],[-135.60720799999996,69.14526400000005],[-135.6305539999999,69.15138200000001],[-135.64001499999995,69.15498400000013],[-135.81082199999997,69.242752],[-135.83999600000004,69.25943000000007],[-135.85220300000003,69.26805100000001],[-135.85498,69.27331500000014],[-135.8558349999999,69.28471400000006],[-135.854156,69.290817],[-135.84860199999997,69.29693600000002],[-135.8416749999999,69.3019260000001],[-135.83331299999998,69.30636600000008],[-135.803894,69.31666600000005],[-135.792511,69.31944299999992],[-135.57192999999995,69.33859300000006],[-135.5561219999999,69.33888200000001],[-135.48580900000002,69.33526599999999],[-135.44860799999998,69.33221400000002],[-135.41332999999997,69.32304399999998],[-135.39196799999996,69.30998199999999],[-135.38723800000002,69.30525200000011],[-135.379974,69.30108600000005],[-135.37027,69.297485],[-135.323334,69.28526299999999],[-135.25778200000002,69.27137800000008],[-135.24386599999997,69.2686000000001],[-135.22970599999996,69.26609800000006],[-135.18554699999993,69.25888099999992],[-135.17056300000002,69.25776699999994],[-135.16223099999996,69.26193199999994],[-135.15805099999994,69.2686000000001],[-135.15835599999997,69.27442900000011],[-135.16500899999994,69.27916000000005],[-135.174438,69.28305100000011],[-135.23971599999987,69.3316650000001],[-135.28695699999992,69.41360500000002],[-135.28723100000002,69.41914400000002],[-135.285278,69.42553700000013],[-135.278076,69.430542],[-135.26834099999996,69.43414300000006],[-135.16082800000004,69.47360200000014],[-135.15084799999994,69.4769290000001],[-135.137787,69.47859200000005],[-134.996643,69.48414600000001],[-134.91528299999993,69.48525999999998],[-134.69473300000004,69.48165899999998],[-134.67749000000003,69.48082],[-134.64251699999988,69.47720300000003],[-134.62832599999996,69.47442600000011],[-134.60861199999988,69.4685970000001],[-134.570831,69.45387300000004],[-134.55917399999987,69.45082100000013],[-134.53112799999997,69.44552600000009],[-134.49609399999997,69.44192500000003],[-134.48165900000004,69.44274899999999],[-134.46859699999993,69.44442700000008],[-134.43832399999997,69.45471200000003],[-134.42083699999995,69.46304299999991],[-134.413635,69.468323],[-134.407776,69.474152],[-134.40557899999993,69.48027000000013],[-134.40835600000003,69.49136400000003],[-134.41778599999992,69.50054900000009],[-134.43667600000003,69.50804100000005],[-134.448334,69.51110799999992],[-134.46887200000003,69.54275500000006],[-134.40167199999996,69.63832100000013],[-134.40249600000004,69.649719],[-134.406677,69.65443400000004],[-134.44277999999997,69.68081699999999],[-134.48580899999996,69.70610000000005],[-134.49054,69.71081500000008],[-134.49304199999995,69.71581999999995],[-134.49108899999993,69.72221400000001],[-134.476379,69.72303799999997],[-134.30972299999996,69.71581999999995],[-134.20388799999995,69.66886899999997],[-134.17748999999998,69.64027400000009],[-134.19638099999992,69.62109399999997],[-134.20388799999995,69.6160890000001],[-134.24026500000002,69.58581500000003],[-134.24472000000003,69.579163],[-134.24472000000003,69.57331800000003],[-134.24221799999998,69.56805400000007],[-134.113312,69.53887900000001],[-134.09860199999997,69.53997800000002],[-134.081116,69.54832499999998],[-134.06195099999997,69.5558170000001],[-134.037506,69.56025699999992],[-134.02002,69.559418],[-134.00836200000003,69.55609100000004],[-134.00140399999998,69.55192600000004],[-133.977783,69.528595],[-133.961121,69.50915500000002],[-133.94723499999992,69.5063780000001],[-133.91833499999996,69.50833100000006],[-133.87914999999998,69.51332100000008],[-133.86749299999997,69.51582299999995],[-133.86026000000004,69.52082800000005],[-133.82250999999997,69.55525200000005],[-133.823151,69.5600740000001],[-133.81973300000004,69.56498699999997],[-133.801941,69.57360800000009],[-133.79168699999997,69.57693499999999],[-133.77835099999993,69.57638499999996],[-133.75057999999996,69.54748500000011],[-133.74832199999992,69.54220599999996],[-133.79861500000004,69.4810940000001],[-133.81805399999996,69.46415700000011],[-133.85055499999999,69.4458160000001],[-133.87692300000003,69.43304400000011],[-133.92083699999995,69.41220100000004],[-133.941376,69.405258],[-133.96444699999995,69.40026900000004],[-134.08554100000003,69.34054600000002],[-134.21112099999993,69.27609299999995],[-134.21832299999988,69.2711030000001],[-134.275574,69.22608900000012],[-134.27999899999986,69.21943700000003],[-134.28222699999998,69.21331800000002],[-134.281952,69.20748900000001],[-134.27722199999994,69.20277399999998],[-134.27471899999995,69.19775400000009],[-134.27444500000001,69.18609600000008],[-134.28030399999994,69.18026700000007],[-134.287781,69.17526200000003],[-134.38363599999997,69.11831699999999],[-134.39779699999997,69.11747700000012],[-134.44888300000002,69.11970500000007],[-134.47720300000003,69.11804200000012],[-134.53112799999997,69.11276200000009],[-134.5680539999999,69.10664400000013],[-134.585266,69.09803800000003],[-134.67361500000004,69.01776100000001],[-134.67584199999993,69.01138300000008],[-134.675568,69.00582900000006],[-134.669739,68.9727630000001],[-134.67166099999997,68.966385],[-134.666656,68.95610000000005],[-134.652802,68.94775400000015],[-134.60665900000004,68.93525699999998],[-134.58831799999996,68.92804000000007],[-134.51419099999987,68.887497],[-134.50723300000004,68.88304100000005],[-134.48858599999994,68.87025499999999],[-134.47470099999998,68.85609399999998],[-134.4641719999999,68.84248400000007],[-134.45693999999997,68.82693499999999],[-134.4475099999999,68.81192000000004],[-134.44027700000004,68.80192599999998],[-134.43112199999996,68.79275500000006],[-134.417236,68.78442399999994],[-134.39889499999998,68.77720599999998],[-134.37609899999995,68.770828],[-134.3511049999999,68.76499899999999],[-134.29666099999992,68.7544400000001],[-134.28750599999995,68.75082400000008],[-134.280579,68.746643],[-134.26058999999987,68.73353599999996]],[[-102.14527900000002,69.64860499999998],[-102.160278,69.64833100000004],[-102.17832900000002,69.651093],[-102.21028099999995,69.66220099999998],[-102.22609699999992,69.6702580000001],[-102.23166700000002,69.67469800000015],[-102.24305699999996,69.69413800000012],[-102.243607,69.70443699999998],[-102.241379,69.71026599999999],[-102.23416099999997,69.71666000000005],[-102.22556299999991,69.721924],[-102.215843,69.72665400000005],[-102.15778399999999,69.73609900000008],[-102.13474300000001,69.7247010000001],[-102.12943999999993,69.72026100000005],[-102.12332199999997,69.71276899999998],[-102.12026999999989,69.70803800000004],[-102.11721799999998,69.69775399999997],[-102.11554699999999,69.66665599999999],[-102.11805700000002,69.66081200000013],[-102.12277199999994,69.65498400000007],[-102.13221699999991,69.65054299999997],[-102.14527900000002,69.64860499999998]],[[-77.94665500000002,69.64665200000007],[-77.94499200000001,69.63970900000004],[-77.94610599999999,69.63333100000011],[-77.96583599999997,69.62498500000004],[-78.07028200000002,69.59275800000006],[-78.16999799999996,69.57054099999999],[-78.31193499999995,69.54304500000012],[-78.39778099999995,69.52082800000005],[-78.50500499999987,69.48887600000006],[-78.57640100000003,69.50166300000006],[-78.58805799999993,69.506104],[-78.61138899999992,69.50943000000001],[-78.62609899999995,69.50999500000006],[-78.64611799999989,69.50999500000006],[-78.66444399999989,69.50749200000007],[-78.68527199999994,69.49832200000003],[-78.69804399999998,69.48915100000005],[-78.71888699999994,69.47998000000013],[-78.75695799999994,69.46748400000001],[-78.80194099999994,69.455826],[-78.81750499999993,69.45277400000009],[-78.83860800000002,69.45138500000007],[-78.85305800000003,69.45416300000011],[-78.86193800000001,69.45748900000012],[-78.86833199999995,69.46054100000003],[-78.87388599999986,69.46470600000004],[-78.88027999999997,69.4769290000001],[-78.87860099999989,69.47998000000013],[-78.87416099999996,69.4869230000001],[-78.865005,69.49498000000011],[-78.841385,69.50804100000005],[-78.82611099999997,69.51165799999995],[-78.80972299999996,69.51416000000006],[-78.78332499999999,69.52110300000004],[-78.76417500000002,69.52720599999998],[-78.71777299999997,69.54470800000001],[-78.69526699999994,69.55693100000008],[-78.67443800000001,69.56832900000006],[-78.65278599999994,69.58194000000003],[-78.62805199999997,69.60859700000015],[-78.61555499999992,69.61747700000001],[-78.58639499999992,69.63192700000013],[-78.57583599999998,69.63638300000002],[-78.5225069999999,69.64833100000004],[-78.4997249999999,69.65054299999997],[-78.4827729999999,69.64942899999994],[-78.400284,69.643326],[-78.26083399999993,69.659988],[-78.24527,69.66360500000013],[-78.229446,69.67164600000001],[-78.22805799999998,69.67747500000007],[-78.23693800000001,69.68858300000005],[-78.24499500000002,69.69331399999999],[-78.25695799999994,69.70582599999994],[-78.26362599999993,69.71360800000008],[-78.26916499999993,69.72804300000001],[-78.26861599999995,69.73220800000001],[-78.26583899999997,69.73387100000014],[-78.18055700000002,69.75221300000004],[-78.16416899999996,69.75248699999997],[-78.15417499999995,69.75054900000003],[-78.141953,69.74247700000006],[-78.08000199999998,69.72943099999992],[-78.01834100000002,69.70832800000005],[-77.99276700000001,69.6994170000001],[-77.98277300000001,69.69470200000006],[-77.97389199999998,69.68858300000005],[-77.96611000000001,69.68165599999998],[-77.95556599999998,69.66832],[-77.94665500000002,69.64665200000007]],[[-82.50778199999996,69.70498700000002],[-82.54277000000002,69.70416300000005],[-82.678879,69.72637900000001],[-82.72000100000002,69.73332199999999],[-82.865005,69.770828],[-82.87777699999992,69.77499400000005],[-82.87943999999993,69.77859500000011],[-82.85638399999999,69.80026199999998],[-82.84666400000003,69.80304000000012],[-82.83917199999996,69.80386400000009],[-82.81166100000002,69.80609099999998],[-82.80305499999992,69.80581700000005],[-82.796112,69.805252],[-82.77610800000002,69.80415300000004],[-82.67777999999993,69.79470799999996],[-82.62999000000002,69.789154],[-82.56388900000002,69.77859500000011],[-82.46028100000001,69.76165800000012],[-82.45306399999998,69.72053499999998],[-82.45500199999992,69.71443200000004],[-82.46722399999999,69.70999099999995],[-82.50778199999996,69.70498700000002]],[[-79.42304999999999,69.78498800000006],[-79.33168,69.71331800000007],[-79.32833899999997,69.70721400000008],[-79.32945299999994,69.70138500000002],[-79.33389299999999,69.69747899999999],[-79.35472099999998,69.68803400000007],[-79.48222399999992,69.6461030000001],[-79.54499799999996,69.62664799999993],[-79.57167099999998,69.61943100000002],[-79.600281,69.61276199999998],[-79.63166799999993,69.60887100000008],[-79.95750399999997,69.61998],[-79.96333300000003,69.62637300000011],[-79.97416699999985,69.63165299999997],[-79.99499500000002,69.638596],[-80.02194199999991,69.64359999999994],[-80.03805499999999,69.64526399999994],[-80.0594329999999,69.64387499999998],[-80.06555200000003,69.64166300000011],[-80.081955,69.630539],[-80.08277900000002,69.62692300000015],[-80.07888799999995,69.62220800000011],[-80.03277600000001,69.58720400000004],[-79.99137899999994,69.56887800000004],[-79.93777499999993,69.53193700000008],[-79.93554699999999,69.52720599999998],[-79.93638599999997,69.52360499999992],[-79.94027699999992,69.5188750000001],[-79.97444199999995,69.5022130000001],[-79.99388099999993,69.49443100000013],[-80.01194800000002,69.49165299999999],[-80.02111799999994,69.49275200000011],[-80.04611199999994,69.49775699999998],[-80.20056199999999,69.53082300000011],[-80.214722,69.58665500000006],[-80.35360699999995,69.61470000000008],[-80.46194499999996,69.65637200000015],[-80.49276700000001,69.66499300000004],[-80.577789,69.66748000000013],[-80.74360699999994,69.66609200000005],[-80.761124,69.66693099999998],[-80.79333499999996,69.6702580000001],[-80.80444299999988,69.67553700000008],[-80.80943300000001,69.68304400000005],[-80.80943300000001,69.68942300000009],[-80.80139200000002,69.70109600000012],[-80.73083500000001,69.74636800000013],[-80.72500600000001,69.74914600000011],[-80.7202759999999,69.75054900000003],[-80.64973399999997,69.74859600000008],[-80.52000399999997,69.72082500000005],[-80.49861099999998,69.75971999999996],[-80.50111400000003,69.76249700000005],[-80.50279199999994,69.76638800000012],[-80.50445599999995,69.77499400000005],[-80.50306699999999,69.77998400000013],[-80.49999999999994,69.78332499999999],[-80.49055499999997,69.78858900000012],[-80.46665999999999,69.79193100000009],[-80.38890100000003,69.79998800000004],[-80.37138400000003,69.79914900000006],[-80.34028599999999,69.79470799999996],[-80.33860799999991,69.79054299999996],[-80.34306300000003,69.78414900000013],[-80.34445199999999,69.77693199999999],[-80.32972699999999,69.77415500000012],[-80.31471299999998,69.77804599999996],[-80.289444,69.78665200000006],[-80.26417500000002,69.79525799999999],[-80.24665799999997,69.79859900000002],[-80.23277300000001,69.79942299999999],[-80.20666499999993,69.79803500000008],[-80.19166599999988,69.79525799999999],[-80.18276999999995,69.79275500000006],[-80.12916599999994,69.76554900000002],[-80.07305899999994,69.74971000000005],[-79.972778,69.72331200000008],[-79.86277799999993,69.74108899999999],[-79.76806599999998,69.75277699999998],[-79.75639299999989,69.77886999999993],[-79.75250199999999,69.78359999999998],[-79.74472000000003,69.78858900000012],[-79.68721,69.81469700000008],[-79.67832900000002,69.81442300000015],[-79.512787,69.80693100000002],[-79.47694399999995,69.8035890000001],[-79.453888,69.79887400000007],[-79.4424899999999,69.794983],[-79.43167099999994,69.78970300000009],[-79.42304999999999,69.78498800000006]],[[-83.67443799999995,69.71998600000006],[-83.68859899999995,69.71943699999991],[-83.71777299999997,69.72331200000008],[-83.776947,69.73275800000005],[-83.80694599999998,69.73942600000004],[-83.89889499999998,69.76443499999999],[-83.908615,69.76915000000002],[-83.91722099999998,69.77859500000011],[-83.91305499999999,69.79332000000005],[-83.90083300000003,69.80831899999993],[-83.88694800000002,69.81860400000005],[-83.87388599999991,69.8230440000001],[-83.86027499999994,69.824432],[-83.83250399999997,69.82527200000004],[-83.57749899999999,69.7977600000001],[-83.53332499999993,69.79136699999992],[-83.52917499999995,69.78665200000006],[-83.54222099999998,69.78332499999999],[-83.57667500000002,69.78082300000005],[-83.601944,69.77998400000013],[-83.695831,69.76388499999996],[-83.708618,69.75942999999995],[-83.712784,69.7544400000001],[-83.70584099999996,69.75000000000006],[-83.693329,69.74552900000015],[-83.66250600000001,69.73692300000005],[-83.65583800000002,69.73220800000001],[-83.65417500000001,69.72720300000015],[-83.66111799999999,69.72221400000001],[-83.67443799999995,69.71998600000006]],[[-82.42944299999999,69.78221099999996],[-82.44415300000003,69.77832000000012],[-82.470551,69.78137200000003],[-82.51333599999987,69.78831500000001],[-82.52610799999997,69.79054299999996],[-82.55139200000002,69.79664600000012],[-82.564438,69.80081200000001],[-82.68859900000001,69.85081500000013],[-82.67443800000001,69.87498499999998],[-82.67304999999999,69.87580900000012],[-82.660553,69.87608300000005],[-82.63639799999999,69.87109400000008],[-82.55583199999995,69.86080900000013],[-82.51722699999993,69.85415599999999],[-82.44610599999999,69.82222000000013],[-82.43666100000002,69.81749000000008],[-82.42887899999994,69.81219500000003],[-82.42666600000001,69.79998800000004],[-82.42582700000003,69.79304500000006],[-82.42610199999996,69.786926],[-82.42944299999999,69.78221099999996]],[[-91.52000399999991,69.73136900000009],[-91.535278,69.72692900000004],[-91.54943800000001,69.72720300000015],[-91.56027199999988,69.72831699999995],[-91.725281,69.78414900000013],[-91.73554999999999,69.789154],[-91.73332199999987,69.79193100000009],[-91.47582999999997,69.87553400000007],[-91.449432,69.87914999999998],[-91.43388399999998,69.88053899999994],[-91.41944899999999,69.87997400000012],[-91.40916400000003,69.87498499999998],[-91.45666499999999,69.77499400000005],[-91.46333299999998,69.76361100000003],[-91.470551,69.75555400000007],[-91.52000399999991,69.73136900000009]],[[-91.81916799999993,69.82165500000008],[-91.83389299999999,69.82110599999993],[-91.84472700000003,69.82222000000013],[-91.86000100000001,69.838593],[-91.86416600000001,69.84414699999996],[-91.86054999999999,69.84887700000002],[-91.84944200000001,69.85887100000002],[-91.82112099999989,69.868042],[-91.78250100000002,69.87776200000008],[-91.76390100000003,69.88026400000012],[-91.745544,69.88165300000014],[-91.72860700000001,69.88081399999999],[-91.71305799999999,69.878311],[-91.70111099999997,69.87525900000009],[-91.64445499999994,69.85942100000005],[-91.639725,69.85498000000013],[-91.65167199999996,69.85108900000006],[-91.66639700000002,69.847488],[-91.81916799999993,69.82165500000008]],[[-97.39778100000001,69.68553200000002],[-97.41194200000001,69.68470800000006],[-97.44193999999993,69.68553200000002],[-97.45584100000002,69.68470800000006],[-97.46833800000002,69.68248000000011],[-97.47972099999998,69.67886400000003],[-97.489441,69.67387400000001],[-97.49027999999987,69.6685940000001],[-97.476944,69.65470900000003],[-97.398346,69.59748800000006],[-97.391388,69.59332300000005],[-97.37887599999993,69.59248400000013],[-97.372772,69.5983280000001],[-97.35194399999995,69.63136299999996],[-97.35082999999997,69.63665800000007],[-97.34750400000001,69.64221200000003],[-97.32972699999988,69.66970800000007],[-97.31639100000001,69.686646],[-97.30387899999994,69.69831799999992],[-97.28916899999996,69.69802900000002],[-97.27389499999998,69.69470200000006],[-97.22639500000002,69.67553700000008],[-97.20695499999994,69.66748000000013],[-97.11389200000002,69.62220800000011],[-97.10694899999993,69.617752],[-97.10360700000001,69.61415099999994],[-97.101944,69.60914600000007],[-97.10278299999993,69.6038670000001],[-97.09944200000001,69.59414700000002],[-97.09056099999998,69.58499100000006],[-97.06443799999994,69.57276900000011],[-96.95556599999998,69.52331500000008],[-96.879166,69.49136400000003],[-96.86694299999999,69.48776200000009],[-96.63778699999995,69.43719499999997],[-96.50250199999994,69.40971400000012],[-96.32028200000002,69.35470599999996],[-96.30139199999996,69.34664899999996],[-96.20889299999999,69.30693100000013],[-96.20222499999994,69.30276500000002],[-96.18998699999997,69.28887900000007],[-96.17222600000002,69.26527400000009],[-96.170547,69.26054400000004],[-96.1719359999999,69.25526400000001],[-96.17555199999993,69.24971],[-96.193329,69.23748800000004],[-96.20333900000003,69.23248299999995],[-96.20973200000003,69.22665399999994],[-96.21305799999999,69.21110500000003],[-96.22361799999993,69.14193699999993],[-96.23500099999995,69.0641480000001],[-96.23361199999988,69.05941800000005],[-96.22972099999998,69.05470300000002],[-96.22555499999999,69.04998799999998],[-96.218887,69.0458220000001],[-96.19526699999994,69.03831500000001],[-96.1663969999999,69.03137199999998],[-96.1324919999999,69.02499400000005],[-96.11888099999993,69.02554299999997],[-96.11527999999998,69.03082300000005],[-96.11389199999996,69.03610200000003],[-96.12999000000002,69.05470300000002],[-96.152222,69.10304300000007],[-96.15695199999999,69.16331500000007],[-96.15583800000002,69.16859400000004],[-96.1494449999999,69.17442300000005],[-96.073624,69.23165899999998],[-96.05972300000002,69.23220800000013],[-96.04777499999989,69.22831700000006],[-96.04110700000001,69.22387700000007],[-95.95556599999992,69.14193699999993],[-95.95167500000002,69.13749700000011],[-95.92443800000001,69.0894320000001],[-95.92582700000003,69.08442700000006],[-95.93472300000002,69.07832300000001],[-95.9536129999999,69.06721500000003],[-95.97138999999993,69.05497699999995],[-95.97778299999999,69.04914900000006],[-95.978882,69.04386899999997],[-95.97084000000001,69.03471400000012],[-95.93859900000001,69.0038760000001],[-95.92555199999998,68.99525500000004],[-95.843887,68.92303500000003],[-95.82028200000002,68.87025499999999],[-95.770554,68.89109800000006],[-95.756958,68.89137300000004],[-95.74583399999995,68.88859600000012],[-95.67416399999996,68.86998000000011],[-95.6702729999999,68.86554000000012],[-95.66860999999994,68.86053500000008],[-95.66749599999997,68.855545],[-95.67138699999998,68.85026600000003],[-95.66722099999998,68.83526600000005],[-95.66332999999997,68.83082600000006],[-95.65417500000001,68.82665999999995],[-95.62609899999995,68.82665999999995],[-95.57583599999998,68.83027600000003],[-95.55027799999988,68.833054],[-95.52833599999991,68.84027100000009],[-95.51028400000001,68.85247800000008],[-95.48998999999998,68.86164900000006],[-95.44665500000002,68.87914999999998],[-95.42471299999994,68.88665800000001],[-95.38999899999999,68.89526400000011],[-95.37805200000003,68.89776599999999],[-95.365005,68.89915500000001],[-95.35139500000002,68.89942900000011],[-95.335556,68.89721700000007],[-95.321396,68.8936000000001],[-95.24027999999998,68.86692800000003],[-95.22888199999994,68.86303700000013],[-95.21055599999994,68.85470600000002],[-95.206955,68.85026600000003],[-95.21083099999998,68.84471100000013],[-95.26306199999999,68.80276500000014],[-95.273056,68.79748500000011],[-95.47639500000002,68.71192900000011],[-95.54361,68.70248400000003],[-95.53999299999992,68.70803800000004],[-95.53889500000002,68.71331800000013],[-95.53889500000002,68.72331200000013],[-95.54638699999998,68.73248300000006],[-95.55943300000001,68.74136400000003],[-95.56834400000002,68.74552900000003],[-95.59388699999994,68.75277700000004],[-95.60804699999989,68.75332600000013],[-95.62193299999996,68.75277700000004],[-95.79055800000003,68.73719800000009],[-95.80166600000001,68.73387099999997],[-95.848343,68.66998300000012],[-95.85972600000002,68.65332000000006],[-95.98889199999996,68.62164300000012],[-96.00083899999993,68.61943100000002],[-96.14973399999991,68.55720500000001],[-96.256393,68.50332600000002],[-96.26251200000002,68.49748199999999],[-96.26472499999988,68.48719800000015],[-96.27084400000001,68.48136899999997],[-96.29138199999994,68.47303800000003],[-96.30221599999993,68.46971100000013],[-96.31388899999996,68.46720900000003],[-96.50361599999991,68.44609100000014],[-96.53056300000003,68.444977],[-96.71749899999992,68.47499099999999],[-96.76834100000002,68.48526000000004],[-96.91389500000002,68.51805100000013],[-96.92832899999996,68.52137800000008],[-97.09445199999988,68.53915400000005],[-97.09555099999994,68.53414900000001],[-97.09889199999998,68.528595],[-97.11999499999996,68.52082800000005],[-97.13082899999995,68.51748700000002],[-97.14250199999998,68.51499900000005],[-97.15417500000001,68.51277199999998],[-97.181107,68.51138299999997],[-97.46000700000002,68.53414900000001],[-97.47500599999995,68.53553799999997],[-97.50611899999996,68.54193099999998],[-97.55332900000002,68.55664100000007],[-97.57417299999992,68.56414800000005],[-97.583618,68.56805400000007],[-97.66722099999993,68.60386699999998],[-97.72721899999999,68.63220199999995],[-97.91860999999994,68.67553700000013],[-98.020554,68.69358800000009],[-98.03555299999994,68.69470200000006],[-98.04998799999998,68.69497700000011],[-98.06277499999999,68.69358800000009],[-98.07833899999997,68.6833190000001],[-98.08389299999999,68.67747500000007],[-98.09333799999996,68.67221100000006],[-98.10499599999997,68.66970800000013],[-98.11999499999996,68.6708220000001],[-98.12971500000003,68.67469800000015],[-98.24027999999998,68.72082500000005],[-98.26112399999994,68.73359700000003],[-98.281677,68.74636800000013],[-98.29055800000003,68.75555400000007],[-98.29249599999997,68.76054399999998],[-98.29194599999994,68.76582300000013],[-98.28611799999993,68.77165200000013],[-98.26972999999998,68.78387500000002],[-98.26083399999993,68.789154],[-98.24916100000002,68.80081200000001],[-98.24305699999996,68.81192000000004],[-98.24415599999998,68.82222000000013],[-98.26306199999999,68.82998700000007],[-98.27528399999989,68.83360299999998],[-98.36971999999997,68.85748300000012],[-98.38333099999994,68.85998500000005],[-98.408051,68.85582000000005],[-98.41860999999994,68.85247800000008],[-98.425003,68.8413700000001],[-98.41528299999999,68.81526200000013],[-98.40194699999995,68.80165099999999],[-98.39361599999995,68.78720100000004],[-98.39472999999992,68.77693200000004],[-98.40028399999994,68.770828],[-98.40861499999994,68.76470899999998],[-98.41860999999994,68.76054399999998],[-98.45111099999997,68.75000000000011],[-98.47639500000002,68.74693300000001],[-98.48999000000003,68.74609400000003],[-98.519455,68.74748199999993],[-98.72471599999989,68.7910920000001],[-98.84722899999997,68.82554600000014],[-98.85943600000002,68.82916300000011],[-98.86639400000001,68.83332800000011],[-98.87554899999998,68.84248400000007],[-98.87971499999998,68.85220300000009],[-98.87916599999994,68.85748300000012],[-98.86999499999996,68.87414600000005],[-98.864441,68.87997400000012],[-98.85638399999999,68.88638300000002],[-98.84750399999996,68.89166300000005],[-98.82667500000002,68.89942900000011],[-98.81750499999987,68.90470900000003],[-98.81193499999995,68.91053800000003],[-98.81138599999991,68.915817],[-98.82055699999995,68.92498799999993],[-98.82749899999999,68.92915299999993],[-98.84944200000001,68.93359400000003],[-98.96583599999997,68.9494170000001],[-98.98110999999994,68.95054600000003],[-98.99305700000002,68.94775400000015],[-99.07749899999999,68.91832],[-99.09584000000001,68.89942900000011],[-99.07640100000003,68.89166300000005],[-99.06220999999994,68.88304100000005],[-99.04388399999993,68.86499000000009],[-99.04415899999987,68.85971100000012],[-99.17610200000001,68.82582100000002],[-99.18859900000001,68.82415800000007],[-99.21055599999994,68.83166499999999],[-99.23666400000002,68.84887700000002],[-99.24610899999999,68.85276800000008],[-99.26722699999999,68.85914600000007],[-99.31138599999991,68.86886600000014],[-99.41332999999997,68.88415500000002],[-99.42805499999997,68.88720699999999],[-99.43777499999999,68.89109800000006],[-99.44499200000001,68.89553800000004],[-99.44972200000001,68.89999399999999],[-99.45417800000001,68.90971400000006],[-99.45111099999991,68.91526800000003],[-99.447769,68.926086],[-99.44888299999997,68.936646],[-99.45083599999998,68.9416500000001],[-99.460556,68.95082100000008],[-99.48916600000001,68.96748400000013],[-99.52333099999987,68.98359699999997],[-99.56249999999994,68.99914600000011],[-99.58972199999988,69.01110800000004],[-99.59416199999998,69.01582300000007],[-99.59638999999993,69.0205380000001],[-99.596115,69.02581800000002],[-99.59333800000002,69.03137199999998],[-99.57988,69.04393000000005],[-99.51362599999987,69.1019290000001],[-99.49221799999987,69.1202550000001],[-99.48582499999998,69.12525900000003],[-99.47694399999995,69.13081399999993],[-99.46665999999993,69.13499500000006],[-99.31138599999991,69.15887500000002],[-99.29666099999997,69.15860000000004],[-99.23805199999998,69.14971900000006],[-99.16833499999996,69.13832100000008],[-99.035278,69.13581800000009],[-99.006958,69.13638300000014],[-98.79804999999999,69.17053199999998],[-98.77444500000001,69.17553700000002],[-98.73055999999997,69.18942300000003],[-98.72027599999996,69.19386300000002],[-98.71112099999999,69.199142],[-98.702789,69.20526100000001],[-98.69972200000001,69.21081500000003],[-98.70111099999997,69.2208250000001],[-98.70527599999997,69.23082000000005],[-98.61555499999992,69.29470800000007],[-98.53388999999993,69.29136700000004],[-98.44137599999988,69.29803500000003],[-98.41555800000003,69.30108600000005],[-98.40333599999997,69.30358899999999],[-98.39334100000002,69.30802900000003],[-98.38751200000002,69.31387300000006],[-98.38417099999998,69.31944299999992],[-98.38806199999999,69.329163],[-98.39723200000003,69.33831800000007],[-98.44027699999998,69.363876],[-98.45722999999998,69.371918],[-98.476944,69.37997400000006],[-98.48889200000002,69.38360599999999],[-98.52333099999998,69.38832100000002],[-98.53555299999994,69.3919370000001],[-98.55555699999996,69.39999400000005],[-98.56249999999994,69.40415999999993],[-98.598053,69.430542],[-98.61193799999995,69.44413800000001],[-98.60888699999987,69.44970699999999],[-98.59167500000001,69.46748400000001],[-98.585556,69.47331200000013],[-98.577225,69.47943099999998],[-98.56332399999991,69.47720300000003],[-98.55332900000002,69.47331200000013],[-98.54083300000002,69.46971100000007],[-98.50834700000001,69.46331800000013],[-98.47749299999992,69.46192899999994],[-98.447769,69.46165500000001],[-98.42250100000001,69.46582000000001],[-98.41944899999999,69.47137499999991],[-98.42416400000002,69.47581500000013],[-98.44888299999991,69.48304700000006],[-98.46389799999997,69.48637400000001],[-98.54943800000001,69.50138900000013],[-98.56471299999993,69.50471500000015],[-98.577225,69.50833100000006],[-98.5869449999999,69.5122070000001],[-98.60166900000002,69.52082800000005],[-98.60555999999991,69.53054800000012],[-98.60499599999997,69.53581200000008],[-98.60194399999995,69.54109199999999],[-98.59277299999991,69.55276500000002],[-98.57556199999999,69.57026700000006],[-98.56695599999995,69.57638499999996],[-98.55665599999986,69.58082600000006],[-98.53138699999994,69.58499100000006],[-98.50140399999992,69.58442700000012],[-98.48554999999999,69.583328],[-98.43331899999998,69.57554600000003],[-98.385559,69.56608599999993],[-98.35777300000001,69.55914300000012],[-98.35055499999993,69.55470300000013],[-98.33889799999997,69.54609700000003],[-98.33416699999998,69.54136699999998],[-98.32250999999991,69.53248600000006],[-98.31082199999997,69.52388000000013],[-98.28443900000002,69.5063780000001],[-98.24861099999998,69.484985],[-98.09249899999998,69.42498800000004],[-98.07861300000002,69.42276000000004],[-98.04972799999996,69.42303500000008],[-98.03666699999985,69.42469800000003],[-98.024719,69.42720000000008],[-98.00389100000001,69.43580600000001],[-97.997772,69.44165000000004],[-97.99722300000002,69.44693000000007],[-98.006958,69.45082100000013],[-98.071396,69.46887200000015],[-98.15722699999998,69.4994200000001],[-98.166946,69.50332600000002],[-98.18859900000001,69.516098],[-98.21139499999992,69.53887900000001],[-98.25584399999997,69.57470700000005],[-98.26306199999999,69.57887299999993],[-98.295837,69.5852660000001],[-98.33029199999999,69.59027100000014],[-98.36054999999993,69.59664900000013],[-98.36776700000001,69.60108900000012],[-98.32167099999998,69.71360800000008],[-98.31416300000001,69.72221400000001],[-98.28195199999993,69.75166300000001],[-98.23028599999998,69.78887900000012],[-98.21112099999999,69.79942299999999],[-98.19972200000001,69.80276500000014],[-98.18720999999994,69.805252],[-98.14388999999994,69.80636600000003],[-98.11805700000002,69.81053200000008],[-98.1077729999999,69.81469700000008],[-98.08860800000002,69.82527200000004],[-98.07972699999999,69.83137499999998],[-98.06166100000002,69.84887700000002],[-98.05833399999989,69.85443100000003],[-98.04916400000002,69.865814],[-98.04305999999997,69.871643],[-98.03416400000003,69.87803600000001],[-98.01222200000001,69.88581799999997],[-97.99972500000001,69.88804600000009],[-97.97416699999991,69.89221199999997],[-97.94554099999999,69.8936000000001],[-97.93055700000002,69.89332599999994],[-97.91332999999997,69.891098],[-97.88027999999991,69.88499500000006],[-97.75500499999993,69.85137900000007],[-97.691101,69.81999200000013],[-97.68916299999995,69.81526200000013],[-97.68221999999997,69.81080600000001],[-97.66000400000001,69.80331400000006],[-97.61000099999995,69.78858900000012],[-97.57972699999999,69.78193700000003],[-97.44915800000001,69.76026900000011],[-97.34110999999996,69.7063750000001],[-97.33944699999995,69.70138500000002],[-97.34805299999988,69.69525100000004],[-97.358612,69.690811],[-97.37110899999999,69.68858300000005],[-97.39778100000001,69.68553200000002]],[[-97.32501200000002,69.88916000000006],[-97.31527699999992,69.88804600000009],[-97.30166599999995,69.88970900000004],[-97.28999299999992,69.89305100000013],[-97.276947,69.89444000000015],[-97.26777599999997,69.89444000000015],[-97.25,69.89137300000004],[-97.237503,69.88777199999998],[-97.23055999999991,69.88333100000006],[-97.22694399999995,69.87359600000013],[-97.23055999999991,69.868042],[-97.2369379999999,69.86219800000015],[-97.24388099999999,69.85748300000012],[-97.26916499999999,69.85247800000008],[-97.28388999999999,69.85276800000008],[-97.2991639999999,69.8560940000001],[-97.30888399999998,69.86026000000004],[-97.31777999999991,69.86943100000013],[-97.41833499999996,69.8936000000001],[-97.44888300000002,69.89414999999991],[-97.46583599999991,69.89637800000008],[-97.48028599999992,69.89888000000013],[-97.48889200000002,69.90803500000004],[-97.49276700000001,69.91775500000011],[-97.48860200000001,69.94386300000008],[-97.48500099999995,69.94941700000004],[-97.47610500000002,69.95555100000007],[-97.46639999999996,69.96081500000008],[-97.45361299999996,69.96304300000003],[-97.4375,69.96192900000005],[-97.35082999999997,69.94941700000004],[-97.335556,69.94609100000002],[-97.32833900000003,69.9416500000001],[-97.32749899999999,69.93165600000009],[-97.346115,69.91720599999996],[-97.34973099999996,69.91165199999995],[-97.35166900000002,69.90138200000001],[-97.34722899999991,69.89665200000002],[-97.33750900000001,69.89276100000012],[-97.32501200000002,69.88916000000006]],[[-100.8497309999999,69.92553700000008],[-100.86389199999991,69.92469800000009],[-100.87444299999999,69.92858899999999],[-100.87999000000002,69.933044],[-100.87999000000002,69.93830900000006],[-100.85861199999994,69.97776799999997],[-100.85333300000002,69.98359700000015],[-100.84333800000002,69.98803700000002],[-100.83112299999993,69.99081400000006],[-100.81500199999994,69.98970000000008],[-100.80695300000002,69.98580900000002],[-100.80526700000001,69.98027000000002],[-100.80721999999997,69.97526600000009],[-100.80721999999997,69.969986],[-100.81249999999994,69.95887800000003],[-100.83112299999993,69.93553199999997],[-100.83999599999999,69.92997700000006],[-100.8497309999999,69.92553700000008]],[[-87.091385,70.1502690000001],[-87.06361400000003,70.1477660000001],[-87.05166599999995,70.1419370000001],[-87.02555799999999,70.13554399999998],[-87.02084399999995,70.13192700000002],[-87.02389499999998,70.12776200000002],[-87.02194199999997,70.12109400000003],[-87.00917099999992,70.116379],[-86.99415599999998,70.11360200000007],[-86.92250100000001,70.1041560000001],[-86.90556299999997,70.10304300000007],[-86.87388599999997,70.09887700000013],[-86.85665899999992,70.09776299999999],[-86.82583599999992,70.09275800000012],[-86.79888900000003,70.0872040000001],[-86.77806099999992,70.08970600000004],[-86.76112399999994,70.0935970000001],[-86.68859900000001,70.11526500000002],[-86.67027300000001,70.11804200000012],[-86.639725,70.1166530000001],[-86.61166400000002,70.1119230000001],[-86.59861799999999,70.10859700000003],[-86.58667000000003,70.10443099999998],[-86.54554699999994,70.0813750000001],[-86.54972800000002,70.07249500000006],[-86.55055199999998,70.06637600000005],[-86.53666699999991,70.06248499999998],[-86.511124,70.05304000000007],[-86.50500499999998,70.04803500000003],[-86.50361599999997,70.036926],[-86.50584400000002,70.02859500000005],[-86.50556899999998,70.02331500000003],[-86.50250199999999,70.02082800000011],[-86.487503,70.01776100000001],[-86.47193900000002,70.01582300000007],[-86.460556,70.01220699999999],[-86.45666499999993,70.00749199999996],[-86.46000699999996,70.00471500000009],[-86.468887,69.99971],[-86.48971599999999,69.98387100000008],[-86.502792,69.98054500000006],[-86.52362099999999,69.97804299999996],[-86.54249600000003,69.97747800000013],[-86.662216,69.96748400000013],[-86.714447,69.9669340000001],[-86.747772,69.96943700000008],[-86.76556399999987,69.96971100000002],[-86.83306900000002,69.97442600000005],[-86.864441,69.9785920000001],[-86.88137799999998,69.97970600000008],[-86.89805599999994,69.98220799999996],[-86.92639199999996,69.98915099999999],[-86.93859900000001,69.99331700000005],[-86.962219,70.00471500000009],[-86.98527499999994,70.01388500000013],[-87.00222799999995,70.0149990000001],[-87.01611300000002,70.0105440000001],[-87.02194199999997,70.00526400000001],[-87.029449,70.00082400000002],[-87.03721599999994,69.99664300000012],[-87.05027799999988,69.99165300000004],[-87.066666,69.98915099999999],[-87.08639499999992,69.98776199999998],[-87.104172,69.98776199999998],[-87.13500999999997,69.99275200000005],[-87.148056,69.99748200000005],[-87.16888399999999,70.00860599999993],[-87.18276999999995,70.01388500000013],[-87.195831,70.01721200000003],[-87.21362299999987,70.01748700000007],[-87.229446,70.01944000000003],[-87.2408289999999,70.02137800000014],[-87.25500499999998,70.02526900000004],[-87.27444499999996,70.034988],[-87.27749599999999,70.03887900000007],[-87.27694699999995,70.04498300000012],[-87.27362099999999,70.05081200000012],[-87.27250700000002,70.05470300000002],[-87.27278099999995,70.05998199999999],[-87.27833599999997,70.06749000000002],[-87.28832999999997,70.07331799999997],[-87.295837,70.07748400000003],[-87.30749500000002,70.080826],[-87.31945799999988,70.08332800000005],[-87.335556,70.08554100000003],[-87.34973100000002,70.08610499999998],[-87.36389200000002,70.08859300000012],[-87.37693799999994,70.09332299999994],[-87.37832599999996,70.09610000000004],[-87.37609900000001,70.09942600000011],[-87.37138400000003,70.10386700000004],[-87.35583499999996,70.10720800000007],[-87.34194899999989,70.10859700000003],[-87.30749500000002,70.10720800000007],[-87.27778599999999,70.11469999999997],[-87.26722699999988,70.11331200000006],[-87.26560999999992,70.11355600000002],[-87.25473,70.11219800000009],[-87.2225039999999,70.11137400000013],[-87.18777499999993,70.10832200000004],[-87.18055700000002,70.109421],[-87.17304999999999,70.11219800000009],[-87.16444399999995,70.11720300000013],[-87.15611299999989,70.11914100000007],[-87.130829,70.12025500000004],[-87.11833200000001,70.11914100000007],[-87.10278299999999,70.12081900000004],[-87.09973099999996,70.12359600000008],[-87.10055499999993,70.12553400000007],[-87.14306599999998,70.13943500000005],[-87.14527900000002,70.14276100000006],[-87.141388,70.14637800000003],[-87.12832600000002,70.14971900000006],[-87.11389199999996,70.14888000000008],[-87.091385,70.1502690000001]],[[-125.05695299999996,70.1183170000001],[-125.08500700000002,70.11633300000011],[-125.10221899999993,70.11807299999998],[-125.11971999999997,70.124954],[-125.122772,70.13006600000006],[-125.12332200000003,70.13546800000006],[-125.12110899999999,70.14137299999999],[-125.11277799999999,70.14697300000006],[-125.10333300000002,70.15168800000009],[-125.083328,70.1599730000001],[-125.07055700000001,70.16187999999994],[-125,70.16293300000007],[-124.97693600000002,70.16720600000008],[-124.96305799999999,70.16832000000005],[-124.95500199999998,70.164154],[-124.98832700000003,70.13443000000001],[-124.99777199999994,70.12997400000006],[-125.04415899999992,70.12031599999995],[-125.05695299999996,70.1183170000001]],[[-124.67944299999994,70.16165200000012],[-124.69444299999998,70.16137700000007],[-124.73750299999995,70.17414900000011],[-124.75361599999991,70.18248],[-124.75917099999998,70.18691999999999],[-124.76194799999996,70.19192500000008],[-124.75890400000003,70.19664000000012],[-124.74471999999997,70.19775400000009],[-124.55110200000001,70.20860299999993],[-124.53611799999987,70.20860299999993],[-124.51888999999994,70.20694000000003],[-124.51055899999994,70.20277399999992],[-124.50527999999997,70.19831800000003],[-124.50750700000003,70.19274900000005],[-124.53694200000001,70.18193100000002],[-124.67944299999994,70.16165200000012]],[[-112.65527299999991,70.266098],[-112.67223399999995,70.266098],[-112.69193999999999,70.26748700000002],[-112.72193900000002,70.272491],[-112.74722300000002,70.278595],[-112.75499699999995,70.28276100000011],[-112.76027699999992,70.2872010000001],[-112.76306199999993,70.29248000000007],[-112.76139799999993,70.29859899999997],[-112.75389100000001,70.30358899999999],[-112.73111,70.309708],[-112.71611000000001,70.31053199999997],[-112.699997,70.309418],[-112.6875,70.30636600000008],[-112.67971799999992,70.30247500000002],[-112.67859599999991,70.30081200000006],[-112.64334099999996,70.28137200000009],[-112.64277600000003,70.27581800000013],[-112.64472999999987,70.26971400000008],[-112.65527299999991,70.266098]],[[-112.96972700000003,70.28137200000009],[-113.00306699999999,70.2810970000001],[-113.104446,70.28193699999997],[-113.14083899999997,70.28332500000005],[-113.15834000000001,70.28526299999999],[-113.20361300000002,70.29248000000007],[-113.16972399999992,70.30693100000013],[-113.15750100000002,70.309708],[-113.12888299999997,70.3124850000001],[-113.11054999999993,70.3119200000001],[-112.993607,70.2994230000001],[-112.97609699999992,70.29748499999994],[-112.96362299999998,70.29443400000014],[-112.95333900000003,70.290817],[-112.94554099999999,70.286652],[-112.95612299999999,70.28332500000005],[-112.96972700000003,70.28137200000009]],[[-100.765289,70.25],[-100.78083800000002,70.25],[-100.7938769999999,70.25332600000002],[-100.84166699999997,70.27832000000001],[-100.86305199999993,70.29109199999999],[-100.86833200000001,70.29553200000004],[-100.85193600000002,70.32388300000014],[-100.83889799999992,70.32554600000003],[-100.80943300000001,70.32415800000012],[-100.77639799999997,70.322495],[-100.75890399999997,70.32054099999999],[-100.74804699999999,70.3169400000001],[-100.74082899999996,70.31053199999997],[-100.75890399999997,70.25499000000002],[-100.765289,70.25]],[[-116.80526699999996,70.50943000000001],[-116.78971899999993,70.50721700000003],[-116.75418100000002,70.50749200000007],[-116.63390400000003,70.4935910000001],[-116.60722399999997,70.48803700000008],[-116.59638999999993,70.484985],[-116.56833599999999,70.47387699999996],[-116.57305899999989,70.46775800000012],[-116.70111099999997,70.4685970000001],[-116.71916199999993,70.47026100000011],[-116.787781,70.48359700000003],[-116.814438,70.48887600000006],[-116.82055700000001,70.4935910000001],[-116.82861300000002,70.503601],[-116.82224300000001,70.50888100000003],[-116.80526699999996,70.50943000000001]],[[-116.287781,70.55331400000011],[-116.26027699999992,70.54998800000004],[-116.24333199999995,70.55026199999998],[-116.18943799999994,70.54553199999998],[-116.140556,70.538589],[-116.12748699999997,70.53581200000008],[-116.131104,70.532486],[-116.29110699999995,70.51554900000002],[-116.32333399999993,70.51361100000008],[-116.44611399999991,70.50888100000003],[-116.464722,70.50915499999996],[-116.47778299999999,70.51193200000006],[-116.495003,70.51998900000007],[-116.49582700000002,70.52276599999993],[-116.47000099999997,70.53804000000002],[-116.30304699999988,70.55219999999997],[-116.287781,70.55331400000011]],[[-116.56304899999998,70.534424],[-116.57833900000003,70.53305100000006],[-116.596947,70.53332499999999],[-116.75028999999995,70.539154],[-116.76363400000002,70.54193100000009],[-116.77443700000003,70.54525800000005],[-116.766953,70.54832499999998],[-116.75527999999991,70.55108599999994],[-116.72361799999987,70.55636600000003],[-116.71193699999998,70.55941799999994],[-116.681671,70.56192000000004],[-116.66471899999999,70.56248500000004],[-116.64611799999994,70.56219500000003],[-116.54305999999997,70.55970799999994],[-116.52278100000001,70.55859399999997],[-116.50945300000001,70.55609100000004],[-116.50778200000002,70.55026199999998],[-116.51806599999998,70.54664600000012],[-116.56304899999998,70.534424]],[[-115.92054699999989,70.54136699999998],[-115.95445299999994,70.54026799999997],[-115.99333200000001,70.5416560000001],[-116.051941,70.54553199999998],[-116.06111099999993,70.54832499999998],[-116.04250299999995,70.55219999999997],[-115.98388699999998,70.56080600000007],[-115.97222899999991,70.56359900000001],[-115.91972399999997,70.57249499999995],[-115.87917299999998,70.57859800000011],[-115.86389200000002,70.57998700000007],[-115.82501199999996,70.57832300000007],[-115.81416300000001,70.57499700000005],[-115.80803700000001,70.5705410000001],[-115.81082199999997,70.56498699999997],[-115.81916799999999,70.56080600000007],[-115.84111000000001,70.55415300000004],[-115.86638599999998,70.54942300000005],[-115.92054699999989,70.54136699999998]],[[-116.87943999999993,70.54748500000011],[-116.88945000000001,70.54386900000003],[-116.923317,70.54275500000006],[-117.03611799999993,70.54637100000014],[-117.18331899999998,70.5374910000001],[-117.20195000000001,70.53776600000009],[-117.22000099999997,70.539154],[-117.27555799999993,70.55026199999998],[-117.28888699999993,70.55304000000001],[-117.29778299999998,70.55693100000008],[-117.30166600000001,70.56192000000004],[-117.29778299999998,70.57138099999997],[-117.26083399999999,70.58471700000013],[-117.25140399999992,70.58720400000004],[-117.23805199999998,70.58915699999994],[-117.21640000000002,70.59109500000011],[-117.19943199999994,70.5916600000001],[-117.16332999999997,70.588593],[-116.89444700000001,70.55609100000004],[-116.883621,70.55276500000014],[-116.87943999999993,70.54748500000011]],[[-128.086121,70.605545],[-128.104156,70.5958250000001],[-128.1201779999999,70.59721400000012],[-128.11444099999994,70.59193400000004],[-128.11721799999992,70.58055100000001],[-128.123871,70.57388300000008],[-128.13275099999993,70.56915300000003],[-128.34054599999996,70.539154],[-128.34167499999995,70.54220599999991],[-128.252228,70.64637800000008],[-128.24581899999998,70.65304600000007],[-128.23416099999986,70.6560970000001],[-128.21639999999996,70.65470900000003],[-128.18832399999997,70.64860499999998],[-128.11498999999998,70.62803600000001],[-128.10360699999995,70.62441999999999],[-128.09472700000003,70.62052900000009],[-128.0883179999999,70.61608900000004],[-128.08499099999995,70.61109900000002],[-128.086121,70.605545]],[[-100.23082699999992,70.45166000000006],[-100.24333199999995,70.44914200000011],[-100.26000999999985,70.449997],[-100.27610799999997,70.45304900000008],[-100.47250400000001,70.49636799999996],[-100.49916100000002,70.50332600000013],[-100.63054699999998,70.54332000000011],[-100.662781,70.55470300000007],[-100.670837,70.55886800000007],[-100.67639199999996,70.563309],[-100.68138099999993,70.5730440000001],[-100.68138099999993,70.58360299999998],[-100.67832900000002,70.59414700000002],[-100.66443599999991,70.63777199999998],[-100.65194699999995,70.66970800000007],[-100.51194800000002,70.67637600000006],[-100.49500299999988,70.67526200000009],[-100.48000300000001,70.67330900000013],[-100.46916199999998,70.66943400000014],[-100.46112099999999,70.659988],[-100.451683,70.6519320000001],[-100.443604,70.64776599999999],[-100.34722899999991,70.6080320000001],[-100.33640300000002,70.60443100000003],[-100.31945799999994,70.60331700000006],[-100.21833799999996,70.56442299999998],[-100.22444200000001,70.45664999999997],[-100.23082699999992,70.45166000000006]],[[-103.17777999999993,70.62248200000005],[-103.19360399999994,70.62220800000011],[-103.24833699999994,70.62275700000004],[-103.26640299999991,70.62414600000005],[-103.27500900000001,70.62831100000005],[-103.28111299999995,70.63275100000004],[-103.281387,70.63804600000009],[-103.26834099999996,70.66638200000006],[-103.22582999999986,70.67637600000006],[-103.21000700000002,70.67665100000005],[-103.19415299999997,70.67303500000003],[-103.173607,70.6336060000001],[-103.17304999999999,70.62858600000004],[-103.17777999999993,70.62248200000005]],[[-103.35082999999992,70.68719500000009],[-103.36416599999995,70.68525699999998],[-103.38110399999988,70.68580600000013],[-103.39499699999999,70.68914800000005],[-103.42887899999994,70.69999700000011],[-103.43776700000001,70.70387299999999],[-103.44638099999997,70.70803799999999],[-103.45249899999993,70.7124940000001],[-103.45889299999999,70.72221400000001],[-103.46278399999994,70.73220800000001],[-103.45694700000001,70.73719800000003],[-103.443604,70.73915099999999],[-103.42777999999998,70.73942600000004],[-103.39917000000003,70.73719800000003],[-103.36361699999992,70.72776799999997],[-103.34111000000001,70.72026100000005],[-103.33500699999996,70.716095],[-103.33444199999997,70.71081500000008],[-103.33860800000002,70.6994170000001],[-103.34333799999996,70.69358800000009],[-103.35082999999992,70.68719500000009]],[[-71.47166400000003,71.01277200000004],[-71.428879,71.01220699999999],[-71.38917500000002,71.01388500000007],[-71.37110899999993,71.01193199999994],[-71.35749799999996,71.00972000000007],[-71.34472700000003,71.00555400000002],[-71.33917199999996,70.99832200000009],[-71.339722,70.99136400000009],[-71.34306300000003,70.98498500000005],[-71.38667299999992,70.92248500000011],[-71.39222699999999,70.9166560000001],[-71.40249599999987,70.91192600000005],[-71.41555799999998,70.90776100000005],[-71.43306000000001,70.90470900000014],[-71.45111099999991,70.90304600000002],[-71.47444199999995,70.90248100000002],[-71.49554399999994,70.90277100000003],[-71.65444899999994,70.89082299999995],[-71.73306300000002,70.87498499999992],[-71.93388400000003,70.83332800000005],[-71.93777499999993,70.82470699999999],[-71.94638099999997,70.82083100000011],[-71.95556599999998,70.818329],[-71.99166899999994,70.81469700000008],[-72.03860500000002,70.81137100000001],[-72.081955,70.80970800000011],[-72.09666400000003,70.80970800000011],[-72.112213,70.81137100000001],[-72.19860799999998,70.88275099999998],[-72.22332799999998,70.91693100000009],[-72.22528099999994,70.92442300000005],[-72.22639500000002,70.93054200000006],[-72.21389799999992,70.934708],[-72.202225,70.93664600000011],[-72.16665599999999,70.93803400000002],[-72.14889499999992,70.93637100000007],[-72.13667299999997,70.93359400000003],[-72.13362099999995,70.93165600000003],[-72.145554,70.926086],[-72.14917000000003,70.92109700000003],[-72.136124,70.91693100000009],[-72.11749299999991,70.91720599999996],[-72.097778,70.91970800000001],[-72.07833900000003,70.92359900000008],[-72.05776999999995,70.933044],[-72.04472399999992,70.94442699999996],[-72.03944399999995,70.9502720000001],[-72.03332499999993,70.96304299999997],[-72.02667200000002,70.98275799999999],[-72.01972999999987,71.03442400000006],[-72.02139299999999,71.04193099999998],[-72.00862099999995,71.04971300000011],[-71.91610700000001,71.06442300000009],[-71.88417099999992,71.0688780000001],[-71.85166900000002,71.07222000000002],[-71.83168,71.07110600000004],[-71.79472399999997,71.05304000000007],[-71.73083499999996,71.04553200000004],[-71.644455,71.034988],[-71.54695099999998,71.0186000000001],[-71.47166400000003,71.01277200000004]],[[-96.56332399999997,71.29220599999996],[-96.54695099999998,71.28915400000005],[-96.535553,71.28276100000005],[-96.47250400000001,71.23220800000007],[-96.47027599999996,71.22608900000006],[-96.48083500000001,71.20887800000014],[-96.487503,71.20359800000006],[-96.56111099999998,71.20832800000011],[-96.57806399999998,71.21054100000003],[-96.628601,71.22026099999994],[-96.63861099999991,71.22608900000006],[-96.64167800000001,71.23136899999997],[-96.64277600000003,71.23442100000005],[-96.65249599999999,71.2872010000001],[-96.64917000000003,71.29304500000012],[-96.61054999999999,71.29054300000001],[-96.58111600000001,71.29359400000004],[-96.56332399999997,71.29220599999996]],[[-98.895554,71.27777100000003],[-98.90834000000001,71.27304099999998],[-98.97444200000001,71.28471400000001],[-98.98971599999999,71.29054300000001],[-99.00029,71.297211],[-99.00556899999998,71.30192600000004],[-99.008621,71.30802900000015],[-99.00889599999994,71.313873],[-99.00306699999993,71.31944300000009],[-98.96362299999993,71.35220300000009],[-98.95584099999996,71.35220300000009],[-98.93028300000003,71.34220900000008],[-98.92332499999998,71.3377690000001],[-98.91444399999995,71.33166500000004],[-98.895554,71.27777100000003]],[[-73.120544,71.47970599999996],[-73.12943999999993,71.45082100000008],[-73.07749899999993,71.466385],[-73.04333500000001,71.47886699999998],[-73.03555299999994,71.48414600000001],[-73.01640299999997,71.50000000000011],[-73.00584400000002,71.51165800000012],[-72.99804699999999,71.51721199999992],[-72.985275,71.52137800000003],[-72.97222899999997,71.52137800000003],[-72.96250899999995,71.51998900000001],[-72.93415799999997,71.50915500000013],[-72.82749899999999,71.45498700000002],[-72.82028199999996,71.4497070000001],[-72.81750499999998,71.44497700000011],[-72.82333399999999,71.43969700000002],[-72.831955,71.43580600000013],[-72.84973099999996,71.4327550000001],[-72.8724979999999,71.43081699999999],[-72.92166099999997,71.428314],[-72.99276700000001,71.41943399999997],[-73.01000999999997,71.41554300000007],[-73.02278099999995,71.41110199999997],[-73.03111299999995,71.40664699999996],[-73.028885,71.39915500000006],[-73.00750700000003,71.35220300000009],[-72.97888199999994,71.32971200000009],[-72.97416699999991,71.32499700000005],[-72.97193900000002,71.31749000000013],[-72.97361799999987,71.31330900000006],[-72.98388699999998,71.30859400000003],[-72.99665799999991,71.3041530000001],[-73.025284,71.29748500000011],[-73.06054699999993,71.29470800000001],[-73.0894469999999,71.313873],[-73.16332999999992,71.33248900000001],[-73.19860799999992,71.33638000000008],[-73.24499500000002,71.34887700000007],[-73.26528899999994,71.357483],[-73.27250699999996,71.36192299999999],[-73.27500899999995,71.36581400000006],[-73.27639799999997,71.37915000000004],[-73.265015,71.39637800000014],[-73.25500499999993,71.40887499999997],[-73.25473,71.41526800000008],[-73.29360999999989,71.45471199999997],[-73.30139200000002,71.45971700000001],[-73.3205569999999,71.46971100000007],[-73.34750400000001,71.47776800000003],[-73.36250299999995,71.48109400000004],[-73.3741609999999,71.48580900000007],[-73.37999000000002,71.51971400000002],[-73.37721299999998,71.5227660000001],[-73.36694299999999,71.52748099999997],[-73.18998699999992,71.56553600000007],[-73.176941,71.5663760000001],[-73.14750700000002,71.56442300000015],[-73.13221699999991,71.56137100000007],[-73.09028599999994,71.54637100000008],[-73.08111600000001,71.54220600000008],[-73.07362399999994,71.53692600000005],[-73.07472200000001,71.53137200000003],[-73.11332699999997,71.48580900000007],[-73.120544,71.47970599999996]],[[-72.76083399999987,71.53193700000008],[-72.78639199999998,71.53027300000002],[-72.83084100000002,71.53109699999999],[-72.84889199999992,71.53221100000002],[-72.86749299999991,71.53387500000002],[-72.949997,71.54721100000012],[-72.98249799999991,71.5535890000001],[-73.00889599999988,71.56109600000002],[-73.020554,71.56581100000005],[-73.03056299999992,71.57165500000008],[-73.03527799999995,71.57554600000014],[-73.03999299999998,71.57998700000007],[-73.03750600000001,71.58720399999999],[-73.03416400000003,71.59220900000003],[-72.96806299999997,71.63665800000001],[-72.94860799999998,71.64471400000008],[-72.924713,71.64942900000011],[-72.80665599999992,71.65914900000001],[-72.781113,71.66081200000013],[-72.74526999999995,71.65998799999994],[-72.72666900000002,71.65832500000005],[-72.70916699999998,71.65525800000012],[-72.69583099999994,71.65109300000012],[-72.68443300000001,71.64276100000012],[-72.66221599999994,71.60443100000003],[-72.66055299999994,71.59803800000003],[-72.671112,71.58581500000003],[-72.68249500000002,71.57470699999999],[-72.70111099999991,71.55748],[-72.71278399999994,71.54721100000012],[-72.718887,71.54275500000006],[-72.72749299999998,71.53858900000012],[-72.74249299999997,71.53414900000013],[-72.76083399999987,71.53193700000008]],[[-73.37027,71.55442800000009],[-73.39445499999994,71.55442800000009],[-73.40666199999998,71.55636600000003],[-73.41833500000001,71.56109600000002],[-73.42860399999995,71.56694000000005],[-73.43693499999995,71.57331800000003],[-73.45056199999999,71.58415200000007],[-73.44972199999995,71.58998100000008],[-73.44804399999992,71.59414699999996],[-73.44193999999999,71.59887700000002],[-73.38861099999991,71.63415500000002],[-73.34834299999994,71.65832500000005],[-73.27610800000002,71.69192499999991],[-73.24333200000001,71.69663999999995],[-73.21333299999998,71.69859300000007],[-73.20916699999998,71.69886800000012],[-73.19055200000003,71.697205],[-73.16749600000003,71.69220000000013],[-73.15556299999997,71.68719500000009],[-73.14889499999998,71.67997700000006],[-73.14999399999999,71.6744230000001],[-73.17054699999994,71.66831999999994],[-73.221115,71.66026299999999],[-73.24943499999995,71.65248100000002],[-73.26251199999996,71.64804100000003],[-73.28277600000001,71.63777199999998],[-73.303604,71.62191800000005],[-73.32028199999996,71.605545],[-73.32501200000002,71.59915200000006],[-73.33167999999995,71.58804299999997],[-73.33860799999997,71.57110599999993],[-73.33972199999994,71.56526200000013],[-73.35249299999998,71.55748],[-73.37027,71.55442800000009]],[[-96.95889299999993,71.7044370000001],[-96.99888599999997,71.70109600000006],[-97.03639199999992,71.70138500000002],[-97.05027799999993,71.704163],[-97.0497279999999,71.70999100000012],[-97.04028299999999,71.72026100000005],[-97.02416999999997,71.73109399999998],[-96.99888599999997,71.74136399999992],[-96.99166899999994,71.74304200000006],[-96.99082900000002,71.74386600000003],[-96.96945199999999,71.74859600000002],[-96.96389799999997,71.75221299999998],[-96.92416399999996,71.75555400000002],[-96.88639799999999,71.75526400000001],[-96.86694299999999,71.75360100000012],[-96.85055499999987,71.74941999999999],[-96.84445199999999,71.74414100000001],[-96.8511049999999,71.73887599999995],[-96.86860699999994,71.7285920000001],[-96.88137799999993,71.72331200000008],[-96.89695699999993,71.71832300000011],[-96.91583299999996,71.71360800000008],[-96.95889299999993,71.7044370000001]],[[-95.33999599999993,71.73136900000003],[-95.39805599999994,71.72943100000009],[-95.43582200000003,71.72998000000001],[-95.47111499999994,71.73359700000015],[-95.4830629999999,71.73692300000005],[-95.48832699999997,71.74081400000011],[-95.48805199999987,71.74552900000015],[-95.45028699999995,71.81887799999993],[-95.44027699999998,71.82415800000001],[-95.42083699999989,71.82887300000004],[-95.38417099999998,71.83610499999998],[-95.34889199999998,71.84054600000007],[-95.32861300000002,71.84220899999997],[-95.30166600000001,71.84414700000013],[-95.28666699999997,71.84304800000012],[-95.27583299999998,71.84027100000003],[-95.26583899999997,71.83665500000001],[-95.26167299999997,71.83332800000005],[-95.25973499999992,71.82748400000003],[-95.31054699999993,71.73719800000003],[-95.32472199999995,71.73275800000005],[-95.33999599999993,71.73136900000003]],[[-134.49554399999994,68.75221300000004],[-134.4880369999999,68.736649],[-134.4880369999999,68.7310940000001],[-134.48306299999996,68.72053500000004],[-134.47387700000002,68.71137999999996],[-134.46472199999994,68.70748900000007],[-134.44638099999997,68.70027199999998],[-134.40112299999993,68.68775900000009],[-134.373871,68.68248000000011],[-134.33999599999999,68.67886400000009],[-134.30804399999994,68.67804000000012],[-134.282776,68.68136600000014],[-134.24636799999996,68.68748499999998],[-134.23071299999998,68.6928410000001],[-134.22692899999998,68.69413800000012],[-134.22332800000004,68.69970699999993],[-134.26058999999987,68.73353599999996],[-134.26251200000002,68.73637400000013],[-134.28750599999995,68.753601],[-134.30835000000002,68.76609799999994],[-134.32638499999996,68.77360500000009],[-134.423065,68.83166499999999],[-134.54168700000002,68.91970800000007],[-134.558044,68.933044],[-134.614441,68.98332199999999],[-134.62387099999995,68.99275200000005],[-134.628876,69.00305200000014],[-134.62914999999992,69.00888099999997],[-134.62469499999992,69.01554899999996],[-134.56222499999996,69.08276400000011],[-134.55499299999997,69.08776899999998],[-134.537506,69.09387200000009],[-134.491943,69.10415599999999],[-134.46362299999998,69.1060940000001],[-134.4480589999999,69.1060940000001],[-134.36303699999996,69.10220300000003],[-134.34887700000002,69.10304300000007],[-134.33889799999992,69.10636900000009],[-134.22747800000002,69.1749880000001],[-134.223053,69.18165600000003],[-134.22082499999993,69.18803400000002],[-134.22137499999997,69.21638500000012],[-134.2169489999999,69.22303800000009],[-134.162781,69.25471500000003],[-134.15389999999996,69.25888099999992],[-134.142517,69.26138300000002],[-134.12832599999996,69.26220699999999],[-134.06915299999997,69.26277199999998],[-134.05471799999998,69.26361099999997],[-134.029175,69.26693699999998],[-133.9286189999999,69.28221100000007],[-133.90557899999988,69.28749099999999],[-133.89529400000004,69.290817],[-133.886688,69.29498300000012],[-133.87914999999998,69.29998799999998],[-133.87332199999997,69.30581699999999],[-133.86859100000004,69.31248499999992],[-133.86886599999997,69.31832900000012],[-133.87332199999997,69.32304399999998],[-133.87582399999997,69.32832299999995],[-133.86972000000003,69.33415199999996],[-133.67028799999997,69.38665800000007],[-133.65863000000002,69.38916],[-133.55056799999994,69.40582300000005],[-133.407776,69.41470300000009],[-133.3722229999999,69.41220100000004],[-133.35583499999996,69.40998800000006],[-133.32806400000004,69.40470900000008],[-133.30972299999996,69.40277100000014],[-133.23443599999996,69.39721700000013],[-133.21749899999992,69.39637799999997],[-133.2058409999999,69.39888000000008],[-133.073059,69.43498200000005],[-132.99942,69.48193400000014],[-132.966095,69.51165799999995],[-132.95220899999998,69.56330900000006],[-132.951935,69.56915300000003],[-132.95666499999993,69.57388300000008],[-132.96581999999995,69.57748400000014],[-132.98638900000003,69.59027100000014],[-132.988586,69.595261],[-132.98361199999994,69.60220300000009],[-132.97747800000002,69.6080320000001],[-132.92251599999997,69.64221200000003],[-132.904449,69.65054299999997],[-132.89388999999994,69.65387000000004],[-132.864716,69.6583250000001],[-132.821106,69.66053800000003],[-132.78778099999994,69.65971400000006],[-132.66229199999998,69.651207],[-132.628784,69.64804800000007],[-132.62028499999997,69.64637800000014],[-132.6147919999999,69.64404300000001],[-132.606628,69.63904600000012],[-132.55279499999995,69.63136299999996],[-132.535278,69.63026400000001],[-132.41751099999993,69.63554400000004],[-132.39389,69.64027400000009],[-132.372772,69.64694200000008],[-132.345276,69.65942400000006],[-132.332489,69.67109700000009],[-132.32748399999997,69.67776500000008],[-132.333618,69.68248000000011],[-132.441101,69.70248400000003],[-132.457489,69.70471199999997],[-132.4677729999999,69.70138500000002],[-132.517792,69.68331900000004],[-132.54823299999998,69.68531000000013],[-132.55523700000003,69.68382300000002],[-132.57455400000003,69.68398300000013],[-132.582718,69.685654],[-132.586884,69.68814800000013],[-132.58673099999993,69.69164999999998],[-132.54833999999994,69.73580900000007],[-132.54055799999998,69.74081400000011],[-132.52749600000004,69.74247700000006],[-132.473053,69.74775699999992],[-132.39974999999998,69.75166300000001],[-132.28918499999992,69.7249910000001],[-132.21304299999997,69.690811],[-132.19888300000002,69.68803400000007],[-132.16305499999999,69.68525699999998],[-132.14697299999995,69.68525699999998],[-132.12304700000004,69.71360800000008],[-132.1166379999999,69.71943699999991],[-132.107208,69.72360200000008],[-132.08331299999992,69.72859199999999],[-131.95443699999998,69.75471500000009],[-131.87469499999992,69.76388499999996],[-131.858612,69.76361100000003],[-131.845276,69.76527399999998],[-131.8347169999999,69.76859999999999],[-131.76556400000004,69.79470799999996],[-131.758911,69.80053699999996],[-131.75836200000003,69.80636600000003],[-131.760284,69.81164600000005],[-131.7647399999999,69.8163760000001],[-131.76666299999994,69.82165500000008],[-131.76000999999997,69.82748400000008],[-131.75058,69.83137499999998],[-131.64502,69.86499000000003],[-131.62359600000002,69.87136800000002],[-131.447784,69.91859400000004],[-131.4263919999999,69.9474790000001],[-131.42111199999994,69.954163],[-131.41027799999995,69.95721400000002],[-131.34887700000002,69.95248400000014],[-131.26916499999993,69.93775900000003],[-131.2460939999999,69.93109100000004],[-131.237213,69.92719999999997],[-131.2305599999999,69.92303500000014],[-131.20916699999998,69.89915500000001],[-131.20333899999997,69.88916000000006],[-131.20138499999996,69.88388100000009],[-131.201935,69.87803600000001],[-131.2049869999999,69.87191800000005],[-131.21054099999998,69.86526500000008],[-131.21722399999987,69.85942100000005],[-131.22164899999996,69.85415599999999],[-131.2222289999999,69.84832800000004],[-131.220551,69.84304800000001],[-131.21194499999996,69.8336030000001],[-131.205261,69.82943700000004],[-131.19638099999997,69.82554600000014],[-131.18499799999995,69.82415800000007],[-131.08056599999998,69.88499500000006],[-131.07501199999996,69.89166300000005],[-131.03140299999995,69.94941700000004],[-131.01028399999996,69.98692299999999],[-131.01278699999995,70.02331500000003],[-131.01947,70.02777100000009],[-130.930298,70.08305400000012],[-130.892242,70.099152],[-130.74832199999997,70.08194000000015],[-130.6561279999999,70.10859700000003],[-130.554169,70.16526799999997],[-130.5430599999999,70.16832000000005],[-130.48721299999994,70.17330900000002],[-130.47222899999997,70.17387400000007],[-130.467712,70.17008999999996],[-130.47271699999993,70.16709900000012],[-130.48388699999998,70.16499299999998],[-130.51141399999995,70.16220100000004],[-130.52224699999994,70.15887500000002],[-130.54724099999999,70.12747200000001],[-130.54806499999995,70.121643],[-130.54638699999992,70.116379],[-130.54223599999995,70.11164899999994],[-130.535553,70.10748300000006],[-130.52416999999997,70.10386700000004],[-130.5102839999999,70.101089],[-130.49527,70.10165400000005],[-130.48416099999992,70.10470599999996],[-130.43237299999998,70.12587000000013],[-130.40722700000003,70.14053300000012],[-130.35360699999995,70.132202],[-130.33084099999996,70.11080900000007],[-130.32250999999997,70.10137900000001],[-130.18472299999996,70.05358900000004],[-130.16861,70.053314],[-129.97555499999993,70.06944299999998],[-129.96304299999997,70.07165500000002],[-129.92611699999992,70.078598],[-129.89083900000003,70.09275800000012],[-129.86444099999994,70.12692300000003],[-129.84609999999986,70.15498400000013],[-129.8324889999999,70.19552599999992],[-129.79000899999994,70.21998600000012],[-129.731384,70.25305200000008],[-129.697784,70.262497],[-129.68667600000003,70.26554900000008],[-129.67306499999995,70.26693699999998],[-129.647247,70.25166300000006],[-129.60916099999992,70.21304299999997],[-129.45916699999998,70.14749100000012],[-129.404724,70.12303199999997],[-129.403351,70.11775200000011],[-129.40527299999997,70.10636900000009],[-129.406403,70.10054000000008],[-129.4100039999999,70.09443699999997],[-129.433899,70.06805400000013],[-129.497498,70.0205380000001],[-129.57360799999998,69.99775700000009],[-129.59555099999994,69.99136399999992],[-129.88946499999992,69.91720599999996],[-129.9930419999999,69.89248700000002],[-130.22805800000003,69.84054600000013],[-130.49581899999998,69.78166200000004],[-130.559998,69.73719800000009],[-130.561401,69.72581500000007],[-130.56472799999995,69.71971100000002],[-130.57028200000002,69.71304300000008],[-130.57833900000003,69.70803800000004],[-130.62136799999996,69.69525100000004],[-130.6469729999999,69.69136000000015],[-130.70416299999994,69.68830900000012],[-130.75750700000003,69.68248000000011],[-130.78030399999994,69.6769260000001],[-130.789734,69.67276000000004],[-130.83639500000004,69.6336060000001],[-130.83944699999995,69.62747200000007],[-130.84081999999995,69.6160890000001],[-130.83667000000003,69.61109900000002],[-130.837494,69.60554500000006],[-130.84414699999996,69.599716],[-130.91915899999998,69.56721500000009],[-130.92861899999997,69.56330900000006],[-130.94473299999999,69.56553600000012],[-131.02667199999996,69.59304800000007],[-131.03973399999995,69.601654],[-131.04168699999997,69.60693400000002],[-131.04083300000002,69.61276199999998],[-131.05307,69.63720699999999],[-131.16332999999992,69.62776200000013],[-131.188599,69.62387100000007],[-131.32861299999996,69.57998700000013],[-131.40750099999997,69.58665500000006],[-131.58694500000001,69.56749000000013],[-131.69168100000002,69.55165099999999],[-131.70498699999996,69.56025699999992],[-131.71389799999992,69.563873],[-131.727783,69.5669400000001],[-131.74108899999993,69.56749000000013],[-131.755859,69.5669400000001],[-131.9972229999999,69.53137200000009],[-132.00640899999996,69.52720599999998],[-132.03891,69.50833100000006],[-132.04666099999992,69.50332600000002],[-132.0799869999999,69.48082],[-132.14169300000003,69.41276600000003],[-132.13305699999995,69.40332000000006],[-132.12164299999995,69.39999400000005],[-132.09750399999996,69.3960570000001],[-132.085266,69.39082300000007],[-132.08084099999996,69.38610800000004],[-132.078888,69.3808140000001],[-132.081665,69.37469500000003],[-132.09472700000003,69.36276200000003],[-132.1166379999999,69.35720800000001],[-132.329163,69.31442300000009],[-132.52417000000003,69.27777100000009],[-132.531952,69.28054799999995],[-132.54556300000002,69.28332500000005],[-132.56167599999998,69.28581200000013],[-132.57998699999996,69.28749099999999],[-132.59222399999993,69.28720099999998],[-132.706116,69.26887499999998],[-132.71777299999997,69.26638800000006],[-132.739441,69.26081799999997],[-132.76028399999996,69.25416600000011],[-132.767792,69.24914600000005],[-132.90722699999998,69.1244200000001],[-132.90722699999998,69.11886600000008],[-132.90527299999997,69.042755],[-132.946106,69.03749100000005],[-133.050842,69.05470300000002],[-133.10638399999993,69.05053700000013],[-133.1719359999999,69.04332000000005],[-133.18331899999998,69.04081700000006],[-133.193329,69.03749100000005],[-133.20083599999987,69.03248599999995],[-133.20556599999998,69.02581800000002],[-133.21499600000004,69.00665300000003],[-133.21664399999997,69.001938],[-133.214447,68.99664300000012],[-133.209991,68.99192800000009],[-133.20333900000003,68.98776199999998],[-133.19860799999998,68.98304699999994],[-133.19888300000002,68.97720300000015],[-133.2130429999999,68.93803400000007],[-133.22610499999996,68.91360500000013],[-133.233612,68.90860000000009],[-133.31332399999985,68.87191800000005],[-133.32333399999993,68.86859099999992],[-133.33471699999996,68.86608900000004],[-133.34887699999996,68.86526500000008],[-133.363312,68.86665299999999],[-133.37692300000003,68.86914099999996],[-133.385834,68.87303200000002],[-133.39944500000001,68.88136299999996],[-133.4016719999999,68.88665800000001],[-133.39529400000004,68.89027400000009],[-133.37969999999996,68.89027400000009],[-133.36694299999994,68.89193699999998],[-133.359711,68.89694200000002],[-133.353607,68.90277100000003],[-133.35803199999992,68.90748600000006],[-133.36944599999993,68.91053800000003],[-133.38275099999998,68.91110200000014],[-133.39556899999997,68.90942400000006],[-133.461121,68.89276100000012],[-133.466095,68.88832100000013],[-133.484711,68.85026600000003],[-133.493042,68.82665999999995],[-133.49081399999994,68.82165500000008],[-133.48416099999997,68.81164600000011],[-133.470825,68.79748500000011],[-133.46389799999992,68.79332000000011],[-133.4549869999999,68.78970300000015],[-133.405579,68.77221700000001],[-133.32138099999992,68.74636800000013],[-133.16418499999992,68.70721400000008],[-133.08999599999999,68.69497700000011],[-133.05416899999994,68.69136000000015],[-133.03750599999995,68.69053600000001],[-133.02334599999995,68.69136000000015],[-133.01083399999987,68.693039],[-132.98803699999996,68.69775400000003],[-132.95861799999994,68.69859299999996],[-132.94305399999996,68.69636500000001],[-132.918335,68.69026200000008],[-132.92056299999996,68.69552600000003],[-132.9336239999999,68.70971700000007],[-132.94250499999998,68.71331800000013],[-132.95471199999997,68.71527100000003],[-133.00723299999999,68.71971100000007],[-133.02252199999998,68.71971100000007],[-133.035278,68.71804800000012],[-133.04583699999995,68.71137999999996],[-133.11248799999998,68.71499600000004],[-133.142517,68.7185970000001],[-133.15249599999993,68.72082500000005],[-133.25500499999998,68.75860600000004],[-133.25946,68.76332100000008],[-133.26611299999996,68.77886999999998],[-133.26141399999995,68.78553799999997],[-133.24999999999994,68.78804000000002],[-133.23416099999992,68.78581200000008],[-133.225281,68.78221100000002],[-133.220825,68.77748099999997],[-133.220825,68.77165200000013],[-133.21664399999997,68.7669370000001],[-133.20306399999998,68.76416],[-133.16168200000004,68.75749200000007],[-133.14752199999998,68.758331],[-133.13891599999994,68.76249700000011],[-133.1397399999999,68.7669370000001],[-133.21139499999998,68.79081700000012],[-133.234985,68.79582199999999],[-133.250854,68.79803500000014],[-133.28178399999996,68.7944260000001],[-133.28863499999989,68.79309799999999],[-133.30145300000004,68.78942900000004],[-133.325562,68.78749100000005],[-133.33554099999992,68.78970300000015],[-133.34445199999993,68.79359400000004],[-133.35665899999992,68.80108599999994],[-133.35888699999998,68.80636600000003],[-133.35415599999993,68.83221400000014],[-133.332764,68.84387200000015],[-133.27722199999988,68.85693400000002],[-133.26583900000003,68.85942100000005],[-133.23776199999998,68.86109900000002],[-133.22192399999994,68.85887100000002],[-133.18804899999986,68.84915200000006],[-133.16778599999998,68.83665500000006],[-133.15918,68.8272090000001],[-133.152222,68.8230440000001],[-133.12191799999994,68.80581700000005],[-133.108337,68.80304000000001],[-133.091675,68.80219999999991],[-133.062225,68.80276500000014],[-133.00527999999997,68.81526200000013],[-132.95803799999993,68.83554100000009],[-132.962219,68.84609999999992],[-132.9619449999999,68.85165400000011],[-132.951935,68.85497999999995],[-132.93667599999998,68.85497999999995],[-132.86749299999997,68.84609999999992],[-132.85611,68.842758],[-132.78594999999996,68.8184280000001],[-132.75363199999998,68.80276500000014],[-132.49194299999994,68.80108599999994],[-132.4805599999999,68.8035890000001],[-132.470276,68.80693100000008],[-132.405579,68.842758],[-132.40029900000002,68.84721400000012],[-132.39529400000004,68.8538670000001],[-132.392792,68.85998500000005],[-132.396973,68.86470000000008],[-132.49249299999997,68.90637200000009],[-132.50363200000004,68.90971400000006],[-132.55334499999998,68.91609199999999],[-132.56750499999998,68.91526800000003],[-132.57638499999996,68.91110200000014],[-132.574432,68.9060970000001],[-132.5677799999999,68.90165700000006],[-132.54055799999998,68.8961030000001],[-132.55557299999992,68.87831100000005],[-132.66528299999993,68.84193400000004],[-132.67806999999993,68.84027100000009],[-132.69360399999994,68.84054600000013],[-132.76229899999998,68.8574910000001],[-132.77094999999997,68.85814700000003],[-132.777786,68.86015300000008],[-132.7802729999999,68.86298399999998],[-132.833618,68.91775500000011],[-132.85998499999988,68.98915099999999],[-132.868042,69.02137800000014],[-132.871918,69.05664100000001],[-132.86944600000004,69.06275900000009],[-132.86553999999995,69.068329],[-132.81527699999998,69.08638000000002],[-132.80526699999996,69.0894320000001],[-132.77111799999994,69.08554100000003],[-132.75418100000002,69.08471700000007],[-132.6891779999999,69.08248900000012],[-132.67501800000002,69.08332800000005],[-132.66332999999997,69.08581500000014],[-132.54083300000002,69.135269],[-132.46081500000003,69.12469500000009],[-132.464722,69.11914100000013],[-132.46749899999998,69.10720800000007],[-132.45916699999992,69.10803200000004],[-132.42861900000003,69.11775200000011],[-132.40777599999996,69.1244200000001],[-132.38500999999997,69.13916000000006],[-132.378876,69.14526400000005],[-132.36886600000003,69.15860000000004],[-132.36138899999997,69.17137100000014],[-132.343323,69.20332300000007],[-132.34249899999992,69.220261],[-132.33972199999994,69.22665399999994],[-132.33056599999998,69.23082000000005],[-132.32055699999995,69.23387100000008],[-132.30612199999996,69.23471100000012],[-132.22360199999997,69.21360800000002],[-132.2225039999999,69.141663],[-132.16805999999997,69.21388200000013],[-132.116943,69.24220300000007],[-132.05804399999994,69.24220300000007],[-131.99600199999998,69.25163299999991],[-131.96389799999997,69.25694299999998],[-131.875275,69.27970900000003],[-131.86499000000003,69.28305100000011],[-131.8052669999999,69.31637599999999],[-131.79751599999986,69.32138100000009],[-131.791107,69.32720899999998],[-131.71444699999995,69.3977660000001],[-131.72555499999993,69.401093],[-131.73416099999997,69.40054299999997],[-131.806671,69.39137299999993],[-131.950287,69.39582799999994],[-131.96499600000004,69.39721700000013],[-131.972778,69.40026900000004],[-131.97000099999997,69.40637200000003],[-131.65222199999994,69.47192400000006],[-131.63919099999998,69.47360200000014],[-131.60748299999995,69.47331200000013],[-131.59136999999993,69.47082500000005],[-131.458893,69.44914199999994],[-131.44528200000002,69.44636500000007],[-131.432953,69.43719499999997],[-131.42910799999993,69.43470000000013],[-131.43160999999998,69.43136599999997],[-131.43710299999992,69.42903100000007],[-131.451935,69.4205320000001],[-131.46221899999995,69.41720600000008],[-131.471649,69.41303999999997],[-131.47943099999998,69.4080350000001],[-131.48611500000004,69.40220600000009],[-131.53472899999997,69.333328],[-131.52584799999994,69.32943699999993],[-131.49942,69.33248900000007],[-131.420837,69.36164900000011],[-131.41278099999994,69.3666530000001],[-131.40750099999997,69.37330600000007],[-131.38989300000003,69.40415999999993],[-131.377228,69.42748300000005],[-131.32193,69.49331699999999],[-131.27166699999992,69.50109900000012],[-131.25723299999999,69.50166300000006],[-131.24581899999998,69.49832200000003],[-131.2333069999999,69.48414600000001],[-131.22387700000002,69.46360800000014],[-131.22027599999996,69.45332300000001],[-131.21664399999992,69.44274899999999],[-131.21276899999992,69.42220299999997],[-131.21093799999989,69.4125370000001],[-131.210266,69.40604400000007],[-131.21304299999997,69.38749700000005],[-131.22360200000003,69.38443000000012],[-131.2333069999999,69.38472000000013],[-131.24526999999995,69.382202],[-131.26641799999993,69.37580900000006],[-131.31777999999997,69.35887100000014],[-131.39529399999998,69.318604],[-131.40307599999994,69.31387300000006],[-131.415009,69.30137600000006],[-131.41445899999997,69.29693600000002],[-131.33526599999993,69.31666600000005],[-131.324707,69.31999200000007],[-131.19332899999995,69.36526499999997],[-131.188599,69.3683170000001],[-131.16650400000003,69.40493000000009],[-131.16223099999996,69.49054000000007],[-131.16418499999997,69.49552900000003],[-131.23123199999992,69.54389200000003],[-131.25385999999997,69.57184600000011],[-131.225464,69.5807190000001],[-131.20681799999994,69.55720500000001],[-131.15046699999994,69.51860000000005],[-131.13006599999994,69.516388],[-131.11053499999997,69.48532900000004],[-131.130157,69.4293750000001],[-131.14851399999992,69.40353400000004],[-131.1458439999999,69.37469500000003],[-131.135834,69.35998500000011],[-131.12832599999996,69.36192300000005],[-131.101227,69.39392100000009],[-131.08525099999991,69.44051400000001],[-131.06085199999995,69.47068800000011],[-131.06617699999993,69.49109600000008],[-131.06394999999998,69.51238999999998],[-131.08924899999994,69.53191400000014],[-131.10920699999997,69.54344900000012],[-131.127838,69.55454300000002],[-131.14781199999993,69.56119500000011],[-131.16599999999988,69.567856],[-131.1883239999999,69.57470700000005],[-131.19473300000004,69.57887299999993],[-131.1966549999999,69.58415200000013],[-131.196106,69.58998099999997],[-131.19055199999997,69.59664900000013],[-131.183899,69.60247800000013],[-131.17471299999994,69.60636900000003],[-131.13833599999998,69.61415099999994],[-131.12359600000002,69.61470000000008],[-131.1074829999999,69.61248800000004],[-131.093597,69.60942100000011],[-131.087219,69.605255],[-131.08306900000002,69.60053999999997],[-131.045776,69.52442900000005],[-131.02999899999998,69.48580900000013],[-131.027802,69.46388200000007],[-131.03390499999995,69.42915300000004],[-131.03695700000003,69.42303500000008],[-131.07028200000002,69.36747700000006],[-131.10803199999992,69.33526599999999],[-131.113312,69.328598],[-131.116394,69.32249500000006],[-131.10888699999998,69.32165500000002],[-131.09973100000002,69.32582100000008],[-131.05084199999993,69.35443100000009],[-131.02667199999996,69.38386500000013],[-130.98999000000003,69.44914199999994],[-130.99121099999996,69.50104500000009],[-130.9922029999999,69.50420399999996],[-130.99026500000002,69.53942900000004],[-130.98083499999996,69.54359400000004],[-130.96887200000003,69.54582199999999],[-130.952789,69.54332000000011],[-130.94638099999992,69.53915400000005],[-130.94222999999994,69.53414899999996],[-130.94055200000003,69.52915999999999],[-130.9244379999999,69.44859300000002],[-130.93971299999998,69.42148600000002],[-130.94154400000002,69.41781600000007],[-130.94555699999995,69.41431400000005],[-130.95039399999996,69.41132400000009],[-130.98580900000002,69.38304099999993],[-131.02583299999998,69.34787800000004],[-131.02984600000002,69.34436800000009],[-131.03317300000003,69.34037799999999],[-131.031998,69.33721200000002],[-131.03668200000004,69.31053200000002],[-131.027802,69.30664100000013],[-131.01696800000002,69.30748000000006],[-131.01419099999993,69.31387300000006],[-131.01333599999998,69.31944299999992],[-131.010559,69.32554600000009],[-131.00500499999998,69.33221400000002],[-130.99832200000003,69.33804300000003],[-130.95693999999997,69.371918],[-130.93194599999998,69.38348400000001],[-130.92710899999992,69.38649000000004],[-130.91844200000003,69.386818],[-130.91177400000004,69.384819],[-130.90928599999995,69.381981],[-130.89611799999994,69.38053900000006],[-130.89889500000004,69.35276800000003],[-130.90249600000004,69.34082000000012],[-130.906403,69.32887299999999],[-130.91427599999992,69.31831399999999],[-130.93194599999998,69.30497700000012],[-130.93972799999995,69.29998799999998],[-130.96362299999987,69.28526299999999],[-131.00057999999996,69.25665300000014],[-131.024719,69.20971700000013],[-131.01806599999992,69.14193699999993],[-131.01419099999993,69.13693200000006],[-130.99832200000003,69.13472000000002],[-130.9372249999999,69.13443000000001],[-130.92861899999997,69.14526400000005],[-130.93112199999996,69.22248800000006],[-130.93276999999995,69.22776799999991],[-130.9391779999999,69.23220800000013],[-130.9513849999999,69.24636800000007],[-130.950287,69.25776699999994],[-130.94723499999998,69.26416000000012],[-130.94168100000002,69.27053800000004],[-130.934998,69.27638200000007],[-130.82110599999993,69.37469500000003],[-130.81304899999998,69.37970000000013],[-130.771393,69.39888000000008],[-130.76055899999994,69.40220600000009],[-130.73165899999998,69.40332000000006],[-130.714722,69.40220600000009],[-130.70028699999995,69.40277100000014],[-130.689728,69.40609699999999],[-130.660278,69.42942800000003],[-130.65472399999993,69.43609600000002],[-130.64529400000004,69.45471200000003],[-130.652802,69.45776399999994],[-130.667236,69.45721400000008],[-130.74777199999994,69.44914199999994],[-130.71499599999993,69.46220399999999],[-130.52502400000003,69.54359400000004],[-130.50723300000004,69.55247499999996],[-130.478607,69.57470700000005],[-130.392517,69.64582800000011],[-130.385559,69.65165700000011],[-130.36248799999998,69.67387400000001],[-130.36608899999987,69.68637100000001],[-130.2811279999999,69.70027199999998],[-130.03308099999998,69.73193400000008],[-129.691956,69.78442400000012],[-129.67251599999992,69.79248000000001],[-129.65307599999994,69.80053699999996],[-129.624146,69.81248500000004],[-129.60220300000003,69.81887799999998],[-129.41332999999992,69.83804299999997],[-129.31555199999997,69.84664900000007],[-129.24276699999984,69.84999099999999],[-129.17999299999997,69.849152],[-129.14862099999993,69.84999099999999],[-129.09942599999994,69.85887100000002],[-129.05889899999988,69.87387100000001],[-129.04196199999996,69.88360600000004],[-129.027222,69.89526400000011],[-129.01501499999995,69.90832500000005],[-129.00058,69.933044],[-128.98831199999995,69.94609100000002],[-128.97360200000003,69.95748900000001],[-128.96527100000003,69.96249400000005],[-128.955261,69.96638500000012],[-128.94415300000003,69.96943700000008],[-128.93194600000004,69.97164900000013],[-128.90084799999994,69.97192400000012],[-128.88723799999997,69.96887200000003],[-128.864716,69.96165500000012],[-128.8561099999999,69.95776400000005],[-128.85470599999996,69.95471199999992],[-128.93444799999992,69.84414699999996],[-128.9466549999999,69.84193400000004],[-128.96417199999996,69.843323],[-129.03805499999999,69.8519290000001],[-129.08248899999995,69.85054000000014],[-129.1097109999999,69.84776300000004],[-129.134186,69.843323],[-129.14529399999998,69.84027100000009],[-129.15612799999997,69.836929],[-129.163635,69.83137499999998],[-129.169464,69.82470699999999],[-129.16027799999995,69.71581999999995],[-129.15390000000002,69.70027199999998],[-129.14999399999994,69.69552600000003],[-129.141388,69.69164999999998],[-129.1302799999999,69.68803400000007],[-128.97747800000002,69.67469800000015],[-128.96304299999997,69.67526200000009],[-128.92501799999997,69.68081699999999],[-128.786133,69.76081800000009],[-128.640015,69.84304800000001],[-128.544739,69.885269],[-128.4419559999999,69.921921],[-128.324158,69.94831800000009],[-128.31054700000004,69.958328],[-128.308624,70.0080410000001],[-128.31222499999996,70.01277200000004],[-128.349152,70.03915400000011],[-128.356384,70.04887400000001],[-128.36138900000003,70.05886800000002],[-128.36972000000003,70.09582500000005],[-128.36831699999988,70.10165400000005],[-128.361938,70.10832200000004],[-128.35333299999996,70.11303700000008],[-128.34304799999995,70.11692800000014],[-128.31054700000004,70.12692300000003],[-128.24414099999996,70.14637800000003],[-128.10916099999997,70.18220499999995],[-128.09414700000002,70.18248],[-128.05667099999994,70.17803999999995],[-128.01055899999994,70.17831400000011],[-127.99472000000003,70.17942800000009],[-127.96833799999996,70.18275499999999],[-127.84861799999999,70.20887800000014],[-127.61501299999992,70.2288670000001],[-127.58500699999996,70.22943100000003],[-127.54998799999998,70.22665400000011],[-127.51500699999985,70.22164900000007],[-127.51750199999998,70.22554000000014],[-127.55082700000003,70.23637400000001],[-127.578056,70.242752],[-127.61305199999987,70.24775700000004],[-127.71665999999999,70.25972000000007],[-127.73166700000002,70.26138299999997],[-127.79194599999994,70.25999500000006],[-127.85833699999995,70.26304600000009],[-127.87581599999987,70.2644350000001],[-128.02835099999993,70.28637700000013],[-128.03695700000003,70.29054300000007],[-128.06664999999987,70.30720500000007],[-128.0761109999999,70.34359700000005],[-128.07843000000003,70.3464360000001],[-128.07144199999988,70.34826700000008],[-128.0616149999999,70.34792300000004],[-128.05343599999998,70.34609200000006],[-128.04661599999986,70.3439330000001],[-128.02711499999998,70.34076699999997],[-127.98889200000002,70.34582499999999],[-127.97250399999996,70.34526100000005],[-127.96000699999996,70.34748800000011],[-127.94860799999998,70.35054000000002],[-127.94082600000002,70.35609400000004],[-127.90194699999995,70.39332600000006],[-127.91555800000003,70.39665200000007],[-127.93195300000002,70.39694200000008],[-127.95417799999996,70.39387499999998],[-127.97693600000002,70.38777200000004],[-127.987213,70.38388099999997],[-128.02166699999998,70.37469500000003],[-128.06500199999994,70.37731200000002],[-128.13833599999992,70.37598400000013],[-128.15183999999994,70.38031000000012],[-128.15933199999995,70.38548300000002],[-128.19665499999996,70.39193700000004],[-128.19888300000002,70.40248100000008],[-128.19055200000003,70.43664600000005],[-128.17749000000003,70.46081500000014],[-128.160553,70.49136400000003],[-128.15249600000004,70.503601],[-128.13583399999993,70.52304100000015],[-128.006958,70.588593],[-127.99665799999997,70.59054600000013],[-127.97138999999999,70.58387800000014],[-127.90360999999996,70.56248500000004],[-127.83556399999998,70.54081700000012],[-127.68028300000003,70.48609899999997],[-127.51583900000003,70.42608600000005],[-127.42859599999991,70.39332600000006],[-127.27471899999995,70.32609600000006],[-127.24889399999995,70.31414800000005],[-127.18831599999999,70.28054800000012],[-127.173607,70.27221700000007],[-127.125,70.23719800000015],[-127.07640100000003,70.19636500000007],[-127.05499299999997,70.17803999999995],[-127.03443899999996,70.14888000000008],[-126.89334099999996,70.00888099999997],[-126.87888299999997,70.00054899999998],[-126.81276700000001,69.91053799999997],[-126.81194299999993,69.90525800000012],[-126.80526700000001,69.89553800000004],[-126.74388099999999,69.81387300000011],[-126.714722,69.7752690000001],[-126.70584099999996,69.76609800000011],[-126.69999699999994,69.76138300000008],[-126.6808319999999,69.74803199999997],[-126.67250100000001,69.74386600000008],[-126.62053699999996,69.71998600000006],[-126.60166899999996,69.71247900000014],[-126.45944199999997,69.64414999999997],[-126.29055799999998,69.55859400000003],[-126.26777599999997,69.54081700000012],[-126.26722699999993,69.53553799999997],[-126.25583599999999,69.52665700000006],[-126.11221299999994,69.46943699999997],[-126.08860800000002,69.46249399999999],[-126.0497279999999,69.45277400000009],[-126.03666699999997,69.44970699999999],[-125.98889199999996,69.430542],[-125.96806299999997,69.42303500000008],[-125.95749699999999,69.41943400000002],[-125.910553,69.40554800000007],[-125.88474300000001,69.39915500000006],[-125.839722,69.38916],[-125.55110200000001,69.33718900000008],[-125.42639200000002,69.31218000000013],[-125.41528299999987,69.31301900000005],[-125.37249800000001,69.33580000000012],[-125.36554699999999,69.34246800000005],[-125.39083900000003,69.37051399999996],[-125.40110800000002,69.37413000000004],[-125.37748699999997,69.39608799999996],[-125.21000699999996,69.381912],[-125.16528299999999,69.38163800000007],[-125.14167800000001,69.38638300000008],[-125.13249200000001,69.39109800000011],[-125.12554899999998,69.39749100000006],[-125.11193800000001,69.41581700000006],[-125.089447,69.44970699999999],[-125.11277799999999,69.46415700000011],[-125.12304699999993,69.46803299999999],[-125.462784,69.45246900000006],[-125.53056300000003,69.43524200000007],[-125.609444,69.41525300000012],[-125.62249799999995,69.41859399999998],[-125.61805700000002,69.42442299999999],[-125.57805599999995,69.47164900000001],[-125.48832700000003,69.50749200000007],[-125.47721899999993,69.510269],[-125.46472199999988,69.5122070000001],[-125.449997,69.51249700000011],[-125.30695300000002,69.49998499999998],[-125.14723200000003,69.48551900000012],[-125.13166799999993,69.48469499999999],[-125.11805699999996,69.48579399999994],[-125.12082700000002,69.49079899999998],[-125.13137799999993,69.49441500000006],[-125.18554699999987,69.50720200000006],[-125.21640000000002,69.51303100000007],[-125.25499699999995,69.52302600000002],[-125.265556,69.52691700000008],[-125.41000399999996,69.62803600000007],[-125.41306299999997,69.6330410000001],[-125.41361999999992,69.63832100000013],[-125.41166699999991,69.64387499999998],[-125.37805200000003,69.67858900000004],[-125.36554699999999,69.69026200000008],[-125.35527000000002,69.69413800000012],[-125.079453,69.74275200000005],[-125.06555200000003,69.74359100000004],[-125.04972800000002,69.74304200000012],[-125.016953,69.74052400000011],[-125,69.73819000000009],[-124.98581699999994,69.734711],[-124.97528099999994,69.73082000000011],[-124.96749899999998,69.72692900000004],[-124.93554699999999,69.678314],[-124.92500299999995,69.64471400000014],[-124.90638699999994,69.65387000000004],[-124.88166799999999,69.67053200000004],[-124.82195300000001,69.71499599999999],[-124.82972699999999,69.71914700000008],[-124.86165599999993,69.73580900000007],[-124.88555899999994,69.74803199999997],[-124.89750700000002,69.75054900000003],[-125.01418299999995,69.75053400000002],[-125.22805799999998,69.75914000000012],[-125.241379,69.76025400000009],[-125.25890399999992,69.78410300000002],[-125.27639799999997,69.80824300000006],[-125.225281,69.83967600000005],[-125.20638999999994,69.84912099999997],[-125.19611399999997,69.853027],[-125.18443299999996,69.85580400000009],[-125.16750300000001,69.85414099999997],[-125.16194199999995,69.84970099999998],[-125.15722700000003,69.82356300000004],[-125.15666199999998,69.81828300000012],[-125.170837,69.80549600000012],[-125.170547,69.80021699999998],[-125.165009,69.79550200000011],[-125.15055799999999,69.793564],[-125.05666399999996,69.79524200000009],[-125.03222700000003,69.81720000000007],[-125.00945300000001,69.84552000000008],[-124.94748700000002,69.91053799999997],[-124.94027699999987,69.91693099999998],[-124.89334100000002,69.94026200000002],[-124.76444999999995,69.97082499999999],[-124.79527299999995,70.00888099999997],[-124.82695000000001,70.012497],[-124.88694799999996,70.011932],[-124.99027999999998,70.00610400000005],[-125.025284,69.99800099999999],[-125.04695100000004,69.98999000000009],[-125.08640299999996,69.96853599999992],[-125.10722399999997,69.95352200000008],[-125.10759699999994,69.9479750000001],[-125.11138899999997,69.9419400000001],[-125.123894,69.93995699999999],[-125.19082600000002,69.93243399999994],[-125.20667299999991,69.9332280000001],[-125.21721599999995,69.93690500000008],[-125.21777299999997,69.94233700000007],[-125.2022169999999,69.99858100000006],[-125.19748700000002,70.00450100000012],[-125.18831599999999,70.0090330000001],[-125.016953,70.0762180000001],[-125,70.07998700000002],[-124.98972300000003,70.078598],[-124.98166700000002,70.07443200000012],[-124.97556299999991,70.06469700000002],[-124.97528099999994,70.05941800000005],[-124.98194899999999,70.04776000000004],[-124.98665599999998,70.04165599999999],[-124.99610899999999,70.036926],[-124.99768799999998,70.036926],[-125,70.036926],[-125.03999299999992,70.02906800000011],[-125.04804999999999,70.02304100000009],[-125.04527300000001,70.01799000000011],[-125.03443900000002,70.01393100000001],[-125.01999699999993,70.01199300000007],[-124.90139799999997,70.02137800000014],[-124.86332699999997,70.02720600000009],[-124.85527000000002,70.03054800000001],[-124.86972000000003,70.032761],[-124.93916299999995,70.02748100000008],[-124.95500199999998,70.02832000000006],[-124.95694699999996,70.03221100000013],[-124.93916299999995,70.04248000000013],[-124.92859599999997,70.04609700000009],[-124.81416300000001,70.061646],[-124.714447,70.06915300000014],[-124.67527799999993,70.07193000000007],[-124.64527900000002,70.07193000000007],[-124.63474300000001,70.068329],[-124.63417099999992,70.05775499999993],[-124.60333300000002,70.01971400000014],[-124.59777799999995,70.01527400000009],[-124.58473199999992,70.011932],[-124.56861899999996,70.01110800000004],[-124.55583199999995,70.01304600000014],[-124.45754999999997,70.03570600000012],[-124.45172100000002,70.03837600000003],[-124.44672400000002,70.0417020000001],[-124.423607,70.05636600000014],[-124.44138299999997,70.07609600000012],[-124.449432,70.08027600000014],[-124.506958,70.10026600000015],[-124.51999699999999,70.10386700000004],[-124.54888899999997,70.10998499999994],[-124.58556399999992,70.11526500000002],[-124.59944199999995,70.11415100000005],[-124.62053700000001,70.10664400000007],[-124.63221699999997,70.10386700000004],[-124.68138099999999,70.09443699999997],[-124.71972699999998,70.08859300000012],[-124.735817,70.0894320000001],[-124.73889200000002,70.09443699999997],[-124.75195299999996,70.116379],[-124.75250199999999,70.121643],[-124.74388099999999,70.12719700000014],[-124.734444,70.13192700000002],[-124.70472699999993,70.14498900000001],[-124.69415299999997,70.14860500000009],[-124.68028299999997,70.14971900000006],[-124.43611099999998,70.15109300000006],[-124.391388,70.13415500000013],[-124.35861199999988,70.068604],[-124.36945299999996,70.034988],[-124.37193300000001,70.02943400000004],[-124.38394199999993,70.01776100000001],[-124.41776999999996,69.98942599999998],[-124.42610199999996,69.98387100000008],[-124.45944199999991,69.95637500000004],[-124.42971799999992,69.84942599999994],[-124.44249000000002,69.832764],[-124.45722999999998,69.81971699999997],[-124.47972099999998,69.8035890000001],[-124.50167799999991,69.78442400000012],[-124.50361599999997,69.73082000000011],[-124.5005569999999,69.72581500000007],[-124.49526999999995,69.72137500000008],[-124.487503,69.71720900000014],[-124.45916699999998,69.71081500000008],[-124.36138900000003,69.70109600000012],[-124.29499800000002,69.69525100000004],[-124.28111299999995,69.69609100000008],[-124.26862299999993,69.69802900000002],[-124.2433319999999,69.71470599999998],[-124.23388699999998,69.71914700000008],[-124.21305799999993,69.72665400000005],[-124.20140099999998,69.72943099999992],[-124.1875,69.73054500000012],[-124.06973299999987,69.72360200000008],[-124.04083300000002,69.70138500000002],[-124.05526700000001,69.67053200000004],[-124.21193699999998,69.58638000000008],[-124.24054699999994,69.55026200000003],[-124.24999999999994,69.54553199999998],[-124.28028899999998,69.53360000000004],[-124.33444199999997,69.51693699999998],[-124.37777699999992,69.49693300000001],[-124.39527899999996,69.4869230000001],[-124.51888999999994,69.40415999999993],[-124.51390099999998,69.399429],[-124.48000300000001,69.37803600000007],[-124.47222899999991,69.37414600000011],[-124.44666299999994,69.36720300000013],[-124.32584399999996,69.35192900000004],[-124.26363399999997,69.34860200000008],[-124.21888699999994,69.34776299999993],[-124.16194200000001,69.34915200000012],[-124.12026999999995,69.35137900000001],[-124.09528399999999,69.35498000000007],[-124.01640299999997,69.3791500000001],[-123.962219,69.38304099999993],[-123.83138999999994,69.38888500000013],[-123.81696299999999,69.38888500000013],[-123.73055999999997,69.37747200000013],[-123.702789,69.37109400000003],[-123.69776899999988,69.366379],[-123.69748699999997,69.36109900000008],[-123.69248999999996,69.35664400000007],[-123.67999299999991,69.35331700000012],[-123.66639700000002,69.3541560000001],[-123.502792,69.37719700000014],[-123.47778299999993,69.38108800000003],[-123.46611000000001,69.38388100000003],[-123.41915899999998,69.40443400000004],[-123.40750100000002,69.4160920000001],[-123.43276999999995,69.42303500000008],[-123.44027699999998,69.42720000000008],[-123.45084399999996,69.44693000000007],[-123.45084399999996,69.45220900000004],[-123.44833399999993,69.45776399999994],[-123.443329,69.46388200000007],[-123.43611099999998,69.47026100000011],[-123.42859599999991,69.47637900000007],[-123.39998599999996,69.49026500000008],[-123.36527999999998,69.49832200000003],[-123.33999599999999,69.5022130000001],[-123.30110200000001,69.50665300000009],[-123.27306399999998,69.50776700000011],[-123.26139799999999,69.50499000000002],[-123.26287799999994,69.50026700000001],[-123.25723299999999,69.49609400000008],[-123.19275699999997,69.490814],[-123.17999299999991,69.49247700000012],[-123.16861,69.4952550000001],[-123.16332999999992,69.50138900000013],[-123.13166799999999,69.559708],[-123.12666300000001,69.57110599999999],[-123.09638999999999,69.67053200000004],[-123.09612299999998,69.68637100000001],[-123.10637700000001,69.74304200000012],[-123.10888699999998,69.74775699999992],[-123.11665299999993,69.75221300000004],[-123.10527000000002,69.77915999999999],[-123.01583900000003,69.81832900000006],[-122.97083999999995,69.830826],[-122.95916699999992,69.8336030000001],[-122.943329,69.832764],[-122.90499899999998,69.82222000000013],[-122.876938,69.81025700000009],[-122.85388199999994,69.80304000000012],[-122.82584400000002,69.79637100000008],[-122.80803699999996,69.79359399999998],[-122.79332699999992,69.79359399999998],[-122.779449,69.79470799999996],[-122.766663,69.79637100000008],[-122.754997,69.79914900000006],[-122.74610899999999,69.80442800000003],[-122.66443599999997,69.81805400000002],[-122.61554699999999,69.81219500000003],[-122.58833300000003,69.80748],[-122.47778299999999,69.80276500000014],[-122.45805399999995,69.80247500000013],[-122.24333200000001,69.80220000000008],[-122.12777699999992,69.80247500000013],[-122.06221,69.813309],[-122.04415899999998,69.81359900000001],[-121.89639299999999,69.80554200000006],[-121.71916199999993,69.79582199999993],[-121.68388400000003,69.79359399999998],[-121.44304699999998,69.76554900000002],[-121.41639700000002,69.76081800000009],[-121.38054699999992,69.75221300000004],[-121.33332799999994,69.74081400000011],[-121.28611799999999,69.7291560000001],[-121.18305999999995,69.70248400000003],[-121.12027,69.6827550000001],[-121.08667000000003,69.67359899999997],[-121.035553,69.66331500000013],[-121.00890400000003,69.6583250000001],[-120.93415800000002,69.64860499999998],[-120.88110399999994,69.63888500000007],[-120.82556199999999,69.62359600000002],[-120.79638699999992,69.61303699999996],[-120.760559,69.5983280000001],[-120.73999000000003,69.5852660000001],[-120.73528299999992,69.58027600000003],[-120.72860700000001,69.57582100000002],[-120.70111099999997,69.55859400000003],[-120.67859599999991,69.54609700000003],[-120.61609599999997,69.52026400000005],[-120.39334100000002,69.43969700000008],[-120.27528399999994,69.40415999999993],[-120.23166700000002,69.39166299999994],[-119.98222399999986,69.34471100000002],[-119.93499800000001,69.33970599999998],[-119.91776999999996,69.33831800000007],[-119.63527699999997,69.315811],[-119.46140300000002,69.303314],[-119.33500700000002,69.3019260000001],[-119.31582599999996,69.30108600000005],[-119.23000300000001,69.29443400000014],[-118.94082600000002,69.25943000000007],[-118.85555999999997,69.25248700000009],[-118.84056099999992,69.25054899999998],[-118.79998799999993,69.24331700000005],[-118.693604,69.22360200000003],[-118.65527299999997,69.21582000000006],[-118.64472999999998,69.21249400000005],[-118.63639799999993,69.20887799999997],[-118.58168,69.18026700000007],[-118.55248999999998,69.16360500000008],[-118.53999299999998,69.15498400000013],[-118.502228,69.13472000000002],[-118.48554999999999,69.12692300000009],[-118.45777900000002,69.11747700000012],[-118.432503,69.11219800000009],[-118.18611099999998,69.06387300000011],[-118.08167999999995,69.03137199999998],[-118.035553,69.01971400000014],[-118.010559,69.01443499999999],[-117.87053700000001,68.98553500000014],[-117.83693700000003,68.982483],[-117.74221799999998,68.97804300000001],[-117.63390400000003,68.97360200000008],[-117.59612300000003,68.97164900000013],[-117.5625,68.96859700000005],[-117.41583299999996,68.953598],[-117.26917300000002,68.91526800000003],[-117.19110099999995,68.89387499999992],[-117.15387699999997,68.88554400000004],[-117.13667299999997,68.88554400000004],[-116.978882,68.89999399999999],[-116.96639999999996,68.90220600000004],[-116.96056399999992,68.90721100000007],[-116.93907899999994,68.91100300000011],[-116.88667299999992,68.90887500000008],[-116.74445299999996,68.880539],[-116.515289,68.8580320000001],[-116.50029,68.85720800000013],[-116.43611099999998,68.85859700000009],[-116.42054699999994,68.85914600000007],[-116.41111799999999,68.86276199999992],[-116.40666199999998,68.86859099999992],[-116.40943899999996,68.87997400000012],[-116.39862099999999,68.88275100000004],[-116.38137799999998,68.88247700000011],[-116.36472300000003,68.88081399999999],[-116.34028599999994,68.87525900000009],[-116.285553,68.85971100000012],[-116.22721899999993,68.83915700000011],[-116.22138999999999,68.83442700000012],[-116.21362299999998,68.83055100000001],[-116.12304699999993,68.81832900000006],[-116.10637700000001,68.81666600000011],[-115.99388099999999,68.80664100000001],[-115.96000699999996,68.80470300000007],[-115.94915800000001,68.80748],[-115.94138299999997,68.81192000000004],[-115.94471699999997,68.81694000000005],[-115.95249899999993,68.82083100000011],[-116.12193299999996,68.87248199999999],[-116.31639099999995,68.94747899999993],[-116.32417299999992,68.95166],[-116.33000199999992,68.95610000000005],[-116.325287,68.96192900000005],[-116.31610099999995,68.96554600000002],[-116.30526699999996,68.96859700000005],[-116.26139799999987,68.97998000000007],[-116.239441,68.98553500000014],[-116.20500199999987,68.98498500000011],[-116.19027699999998,68.98275800000005],[-116.068893,68.96054100000015],[-116.00750700000003,68.94636500000013],[-115.96833799999996,68.938583],[-115.88417099999998,68.92469800000009],[-115.86749299999991,68.92275999999998],[-115.77806099999987,68.93637100000012],[-115.76695299999994,68.93914800000005],[-115.77500900000001,68.94303900000011],[-115.80943299999996,68.95220899999998],[-115.833328,68.99247700000001],[-115.59306300000003,68.97164900000013],[-115.44638099999992,68.93775900000003],[-115.06471299999993,68.86747699999995],[-115.05055199999993,68.86886600000014],[-115.03500400000001,68.86914099999996],[-115.01640299999997,68.868042],[-114.98999000000003,68.86276199999992],[-114.97805800000003,68.85914600000007],[-114.82167099999998,68.80970799999994],[-114.79194599999994,68.79942300000005],[-114.77916699999992,68.77915999999999],[-114.77055399999995,68.76944000000009],[-114.74916100000002,68.75138900000007],[-114.729446,68.74443100000013],[-114.71528599999999,68.74220300000013],[-114.69666299999994,68.740814],[-114.66555799999998,68.7416530000001],[-114.57833899999997,68.72804300000007],[-114.54250300000001,68.71943699999997],[-114.44833399999999,68.68969700000002],[-114.44055200000003,68.68580599999996],[-114.46028100000001,68.6705320000001],[-114.46528599999999,68.66442899999993],[-114.46221899999995,68.65942400000006],[-114.45667300000002,68.65470900000003],[-114.40471600000001,68.61499000000015],[-114.39499699999993,68.61137400000007],[-114.30444299999988,68.58692900000005],[-114.23361199999994,68.56944300000009],[-114.12165799999997,68.51748700000002],[-114.10665899999992,68.50943000000007],[-114.08889799999997,68.49636800000002],[-114.07055699999995,68.47747800000008],[-114.064438,68.46720900000003],[-114.06054699999993,68.45665000000002],[-114.01112399999994,68.25027500000004],[-114.01390100000003,68.24498],[-114.02333099999998,68.24136400000009],[-114.03582799999998,68.23942599999998],[-114.28806299999997,68.22886699999992],[-114.32000700000003,68.22915600000005],[-114.33805799999993,68.23054500000006],[-114.35166900000002,68.23359700000015],[-114.37053700000001,68.24054000000012],[-114.37805199999997,68.24443100000002],[-114.38305700000001,68.24887100000007],[-114.390556,68.25305200000014],[-114.41166699999997,68.25943000000007],[-114.42555199999998,68.261932],[-114.44167299999987,68.26361099999997],[-114.47361799999987,68.26388500000013],[-114.70249899999999,68.25027500000004],[-114.75527999999997,68.18969700000014],[-114.76471699999996,68.18609600000008],[-114.861107,68.153595],[-114.87193300000001,68.15109300000012],[-114.89639299999999,68.14694200000002],[-114.92971799999992,68.14776599999999],[-114.97749299999992,68.15331999999995],[-115.00750700000003,68.15721100000002],[-115.076683,68.16886900000009],[-115.17054699999994,68.18054200000012],[-115.22501399999993,68.18414299999995],[-115.23721299999988,68.18220500000001],[-115.24194299999999,68.176376],[-115.24388099999993,68.0413670000001],[-115.24054699999994,68.03637700000007],[-115.23528299999998,68.03166200000004],[-115.220551,68.02388000000008],[-115.204453,68.02192700000012],[-115.17138699999998,68.02110299999998],[-115.15638699999994,68.02165200000013],[-115.12526699999995,68.020264],[-115.11389200000002,68.01748700000013],[-115.11054999999999,68.01220700000005],[-115.11665299999999,68.00721700000003],[-115.12581599999999,68.00360100000012],[-115.20472699999993,67.97804300000001],[-115.216949,67.976089],[-115.34221599999995,67.95803799999999],[-115.50334199999986,67.93441800000005],[-115.52749599999999,67.93026700000013],[-115.53639199999998,67.92665100000005],[-115.5425029999999,67.92164600000001],[-115.53694200000001,67.90525799999995],[-115.53388999999993,67.89999399999999],[-115.52834299999995,67.89553800000004],[-115.521118,67.89166300000011],[-115.50723299999993,67.8894350000001],[-115.281387,67.86637900000011],[-115.27610800000002,67.86164900000006],[-115.20028699999995,67.82193000000012],[-115.19082599999996,67.81832900000006],[-115.11361699999998,67.79859900000008],[-115.1036069999999,67.79664600000012],[-115.02887699999985,67.78665200000012],[-115.01251200000002,67.78637700000013],[-114.99916099999996,67.7874910000001],[-114.93611099999998,67.79553199999998],[-114.88667299999997,67.80276499999997],[-114.84916699999991,67.80775500000004],[-114.80999800000001,67.81219500000003],[-114.78307299999989,67.81442300000003],[-114.75334199999992,67.81498699999997],[-114.73693799999995,67.81469700000014],[-114.718887,67.81330900000006],[-114.70749699999999,67.81053199999997],[-114.6866609999999,67.8041530000001],[-114.67722299999997,67.80081200000006],[-114.65527299999997,67.78887900000001],[-114.64499699999999,67.77970900000014],[-114.637787,67.77554300000003],[-114.29778299999992,67.7185970000001],[-114.28362300000003,67.71748400000001],[-114.27139299999999,67.71943699999997],[-114.25029,67.72470099999998],[-114.24109599999991,67.728317],[-114.22000099999997,67.73387100000002],[-114.19583099999994,67.73776200000009],[-114.1808319999999,67.73803700000008],[-114.14835399999993,67.7369230000001],[-114.11472300000003,67.73387100000002],[-113.99694799999992,67.72303800000003],[-113.98332199999999,67.72053500000004],[-113.94943199999994,67.71165500000001],[-113.89250199999992,67.69693000000007],[-113.84584000000001,67.69135999999997],[-113.76862299999999,67.69108600000004],[-113.70889299999999,67.69192500000003],[-113.55082699999997,67.69802900000008],[-113.25583599999999,67.70443699999998],[-113.24082899999996,67.70443699999998],[-113.20694700000001,67.70248400000008],[-113.17804699999988,67.69802900000008],[-113.15556300000003,67.69220000000001],[-113.11916399999996,67.67804000000012],[-113.10777300000001,67.67498800000004],[-113.06777999999997,67.66748000000001],[-113.04998799999993,67.6660920000001],[-112.965012,67.66970800000013],[-112.73972300000003,67.66943400000002],[-112.3958439999999,67.67915300000004],[-112.370003,67.68193100000002],[-112.348343,67.68719499999997],[-112.34056099999998,67.69135999999997],[-112.33361799999989,67.69636500000001],[-112.18331899999993,67.72776800000008],[-111.912781,67.75416600000005],[-111.88305700000001,67.75443999999999],[-111.79972799999996,67.75082400000008],[-111.66000399999996,67.73332200000004],[-111.57277699999992,67.74443100000013],[-111.45861799999989,67.76304600000009],[-111.3708269999999,67.78109700000005],[-111.32250999999991,67.80693100000008],[-111.31276699999995,67.81053199999997],[-111.29083299999996,67.81553600000007],[-111.200287,67.83415200000013],[-111.17582699999991,67.83749400000005],[-111.15943900000002,67.83665500000006],[-111.14835399999998,67.83360299999998],[-111.14388999999994,67.82887299999993],[-111.146118,67.82276900000011],[-111.12082700000002,67.78082300000011],[-111.03443899999996,67.76416000000006],[-111.01834100000002,67.76332100000008],[-111.00583599999999,67.76499899999999],[-110.84056099999998,67.80026200000003],[-110.83222999999998,67.80442800000009],[-110.80972300000002,67.81860400000011],[-110.78859699999998,67.83360299999998],[-110.78278399999994,67.83943199999999],[-110.75890400000003,67.85276799999997],[-110.74221799999992,67.86109900000002],[-110.73249800000002,67.86442599999998],[-110.41443600000002,67.94775400000015],[-110.33999599999999,67.96554600000002],[-110.1991579999999,67.97221400000001],[-110.17999299999991,67.99443100000008],[-110.1725009999999,67.99942000000004],[-110.162781,68.00277699999998],[-110.15167200000002,68.00526400000007],[-110.13054699999998,68.00804099999999],[-110.11694299999994,68.00888100000003],[-110.08389299999999,68.00694300000009],[-110.07084699999996,68.004166],[-110.04888900000003,67.99775699999992],[-110.001106,67.97970599999996],[-109.979446,67.96748399999996],[-109.97083999999995,67.95803799999999],[-109.96888699999994,67.95304900000002],[-109.96749899999992,67.94136000000015],[-109.97028399999999,67.92970300000002],[-109.97749299999987,67.91137700000002],[-109.99166899999994,67.89137300000004],[-110.001106,67.87248200000005],[-110.00361599999991,67.86637900000011],[-110.00361599999991,67.86053500000008],[-109.99749799999995,67.85081500000001],[-109.98889200000002,67.8413700000001],[-109.98249800000002,67.83720400000004],[-109.97389199999998,67.83360299999998],[-109.96305799999993,67.83027600000003],[-109.948036,67.83027600000003],[-109.93554699999999,67.83194000000003],[-109.92582699999997,67.8352660000001],[-109.91722099999998,67.839157],[-109.91251399999999,67.84582499999993],[-109.912216,67.85165399999994],[-109.91639700000002,67.85609399999998],[-109.94888300000002,67.87719700000008],[-109.95305599999995,67.88192700000008],[-109.94193999999993,67.88443000000007],[-109.89028899999994,67.879974],[-109.86193799999995,67.87498500000004],[-109.823059,67.8660890000001],[-109.81416299999995,67.86219800000003],[-109.80777,67.8580320000001],[-109.76722699999993,67.82777399999998],[-109.73082699999998,67.79193100000009],[-109.729172,67.76776100000012],[-109.73581699999994,67.74275200000011],[-109.74553700000001,67.7394260000001],[-109.75167799999991,67.73359700000009],[-109.74973299999994,67.72859200000005],[-109.7369379999999,67.72026100000011],[-109.72609699999998,67.71693399999998],[-109.55222300000003,67.68775900000014],[-109.53472899999991,67.68580600000001],[-109.52250700000002,67.68748499999998],[-109.51139799999999,67.68969700000008],[-109.50279199999994,67.69386299999996],[-109.48805199999993,67.70387300000004],[-109.37026999999995,67.72915599999999],[-109.25361599999997,67.73193400000014],[-109.21028100000001,67.73220800000007],[-109.159157,67.72747800000002],[-109.06582600000002,67.71415700000011],[-109.05972300000002,67.709991],[-109.01471699999996,67.6766510000001],[-109.00279199999994,67.66249100000005],[-108.91915899999992,67.53581200000013],[-108.921944,67.52970900000003],[-108.953888,67.51193200000012],[-108.96362299999998,67.5086060000001],[-108.99665800000002,67.50138900000002],[-109.00119000000001,67.5],[-109.00666799999993,67.49832200000009],[-109.01528899999994,67.49414100000001],[-109.02139299999999,67.48831199999995],[-109.02528399999994,67.4833220000001],[-109.01806599999998,67.46249400000005],[-109.002228,67.44358799999998],[-108.98554999999993,67.43609600000008],[-108.84999099999993,67.38859600000006],[-108.83112299999993,67.35359199999999],[-108.82501200000002,67.34942600000011],[-108.81276700000001,67.34887699999996],[-108.80416899999994,67.35276800000003],[-108.79666099999986,67.3577580000001],[-108.79055799999998,67.36360200000013],[-108.76611299999996,67.39637800000003],[-108.75834700000001,67.40914900000013],[-108.75583599999999,67.41526799999997],[-108.74445299999996,67.44552599999997],[-108.74109599999997,67.45721400000014],[-108.73638900000003,67.48109399999998],[-108.735817,67.48664900000006],[-108.734734,67.54775999999998],[-108.735817,67.55859400000003],[-108.73777799999993,67.56387300000006],[-108.73889200000002,67.5747070000001],[-108.73916599999995,67.59693899999996],[-108.73638900000003,67.60304300000001],[-108.73000299999995,67.60859700000003],[-108.714722,67.61914100000007],[-108.70612299999988,67.62330600000007],[-108.69611399999997,67.626373],[-108.67027299999995,67.6285860000001],[-108.65527299999991,67.62831100000011],[-108.62053700000001,67.62469500000003],[-108.6100009999999,67.62109399999997],[-108.58500700000002,67.60998500000011],[-108.57888799999989,67.60554500000006],[-108.516953,67.49748200000005],[-108.51139799999999,67.48748799999998],[-108.510559,67.47665400000011],[-108.51334399999996,67.4705350000001],[-108.52333099999993,67.45748900000001],[-108.52390300000002,67.45165999999995],[-108.52278100000001,67.44081100000011],[-108.49804699999993,67.36303700000008],[-108.49027999999998,67.35359199999999],[-108.48416099999997,67.34942600000011],[-108.47138999999993,67.34664900000001],[-108.458054,67.34721400000006],[-108.43720999999994,67.35276800000003],[-108.42971799999998,67.35748300000006],[-108.42471299999994,67.36415100000005],[-108.421944,67.3702550000001],[-108.42944299999999,67.37970000000013],[-108.43554699999999,67.38388100000003],[-108.439438,67.38859600000006],[-108.44275699999997,67.39915500000012],[-108.43998699999992,67.42747500000013],[-108.43472300000002,67.43165600000003],[-108.39388999999994,67.44358799999998],[-108.38166799999999,67.4452510000001],[-108.36694299999994,67.444977],[-108.34361299999989,67.43858299999994],[-108.33556399999998,67.4349820000001],[-108.321121,67.42692600000004],[-108.30750299999988,67.41304000000002],[-108.301941,67.40332000000012],[-108.30027799999999,67.39804100000015],[-108.29666099999997,67.39332600000012],[-108.28832999999997,67.38943500000005],[-108.13417099999992,67.32916300000005],[-108.06360599999988,67.305252],[-108.02583300000003,67.29637100000002],[-108.015289,67.293045],[-107.98554999999999,67.27192700000012],[-107.94471699999997,67.23637400000007],[-107.94082600000002,67.23165900000004],[-107.875,67.14082300000001],[-107.87526700000001,67.05276500000014],[-107.88054699999998,67.04832499999992],[-107.89362299999999,67.0477600000001],[-107.90499899999998,67.04971300000005],[-107.95028699999995,67.06219500000003],[-108.00834699999996,67.07748400000008],[-108.02084399999995,67.08055100000001],[-108.03666699999991,67.08166499999999],[-108.14862099999993,67.07666000000012],[-108.15722700000003,67.07276900000005],[-108.18916300000001,67.05497700000001],[-108.19304699999986,67.04971300000005],[-108.192207,67.03887899999995],[-108.19082600000002,67.03359999999998],[-108.19138299999992,67.02804600000002],[-108.19526699999994,67.0227660000001],[-108.20388799999995,67.01887500000004],[-108.21611000000001,67.01721199999992],[-108.23277300000001,67.01915000000008],[-108.24527,67.02221700000001],[-108.45028699999995,67.08332800000011],[-108.46056399999992,67.086929],[-108.495003,67.10220300000009],[-108.51722699999999,67.11387600000006],[-108.541382,67.13081399999999],[-108.55555700000002,67.13888500000007],[-108.58029199999999,67.15026899999998],[-108.59056099999998,67.153595],[-108.6063769999999,67.15470899999997],[-108.61971999999997,67.15387000000004],[-108.622772,67.14999399999994],[-108.53028899999993,67.04248000000001],[-108.52416999999997,67.03831500000001],[-108.51611300000002,67.03442399999994],[-108.50140399999998,67.03221100000002],[-108.491669,67.0352630000001],[-108.48554999999988,67.0410920000001],[-108.48500100000001,67.04664600000012],[-108.48665599999998,67.05192599999998],[-108.49054699999988,67.05664100000001],[-108.48944099999994,67.06776400000001],[-108.48194899999999,67.07276900000005],[-108.468887,67.07331800000003],[-108.45612299999999,67.0705410000001],[-108.44193999999999,67.06248500000004],[-108.39222699999993,67.02886999999998],[-108.35637700000001,67.00332600000013],[-108.34665699999994,66.99443100000008],[-108.33056599999998,66.9869230000001],[-108.31806899999998,66.98387100000014],[-108.28971899999993,66.97998000000007],[-108.25862099999995,66.97776800000003],[-108.22860700000001,66.97665400000005],[-108.19695300000001,66.97221400000001],[-108.16639700000002,66.9622040000001],[-108.14998600000001,66.95443699999998],[-108.11472299999997,66.92886400000003],[-107.98528299999998,66.82859800000011],[-107.94138299999997,66.78831500000007],[-107.93831599999999,66.77804600000007],[-107.93971299999993,66.76666300000005],[-107.94193999999999,66.74970999999994],[-107.94471699999997,66.7435910000001],[-107.94803599999995,66.73193399999997],[-107.949432,66.7205350000001],[-107.94583099999994,66.71582000000006],[-107.89444699999996,66.67164600000012],[-107.88276699999989,66.66331500000001],[-107.87082699999996,66.66249100000005],[-107.86444099999989,66.66832000000005],[-107.86389200000002,66.67387400000007],[-107.86776700000001,66.71138000000002],[-107.88474299999996,66.75082399999991],[-107.88834400000002,66.75555400000013],[-107.88194299999992,66.75915500000002],[-107.86776700000001,66.75888100000009],[-107.85333299999996,66.7563780000001],[-107.829453,66.74498000000011],[-107.81777999999997,66.73637400000001],[-107.76500699999997,66.68691999999999],[-107.72416699999991,66.62970000000013],[-107.64750699999996,66.5747070000001],[-107.62805199999997,66.56219499999997],[-107.60082999999997,66.54609700000009],[-107.56945799999994,66.53054800000001],[-107.55721999999997,66.52777100000009],[-107.43305999999995,66.45359800000011],[-107.2911069999999,66.36831699999999],[-107.26027699999986,66.35304300000007],[-107.24804699999993,66.34999099999999],[-107.23500100000001,66.34860200000014],[-107.22222899999997,66.349152],[-107.21140299999996,66.35137900000007],[-107.203056,66.35525499999994],[-107.196663,66.36080900000013],[-107.195831,66.36637900000005],[-107.19722000000002,66.371643],[-107.20056199999993,66.37637300000006],[-107.23554999999993,66.40748600000006],[-107.34221599999995,66.46165500000006],[-107.43888899999996,66.51304600000014],[-107.56220999999994,66.59136999999998],[-107.56582599999996,66.59610000000004],[-107.56861899999996,66.60664400000007],[-107.56777999999991,66.61219800000009],[-107.56916799999999,66.61747700000006],[-107.57055700000001,66.6224820000001],[-107.57417299999997,66.62747199999995],[-107.62416100000002,66.66081200000002],[-107.64943700000003,66.69386299999996],[-107.69387799999998,66.755829],[-107.74665800000002,66.92276000000004],[-107.68861399999997,66.97709700000013],[-107.63806199999999,67.02442900000005],[-107.66665599999993,67.06303400000002],[-107.66805999999985,67.06832900000006],[-107.66166699999997,67.07388300000002],[-107.65083299999992,67.076096],[-107.63612399999994,67.07388300000002],[-107.60777299999995,67.063309],[-107.58361799999994,67.05165099999999],[-107.52390300000002,67.02026400000005],[-107.516663,67.01054399999998],[-107.48388699999998,66.924149],[-107.48473399999995,66.91859399999993],[-107.49694799999997,66.91720600000002],[-107.57972699999988,66.91638200000006],[-107.59445199999999,66.91886899999997],[-107.60221899999988,66.92276000000004],[-107.608047,66.9269260000001],[-107.62332200000003,66.94026200000008],[-107.626938,66.94497700000011],[-107.632767,66.9494170000001],[-107.64083899999997,66.95304900000008],[-107.647064,66.94271100000003],[-107.65521999999999,66.94371000000007],[-107.66238399999997,66.94287900000006],[-107.66754900000001,66.94037600000007],[-107.67138699999998,66.93703500000004],[-107.670387,66.93386800000002],[-107.63527699999997,66.89221200000003],[-107.5702819999999,66.8377690000001],[-107.564438,66.83360299999998],[-107.51306199999993,66.82222000000002],[-107.42832900000002,66.80470300000013],[-107.41610699999995,66.80609100000004],[-107.40888999999993,66.81109600000008],[-107.39111299999996,66.8913730000001],[-107.39584400000001,66.90138200000013],[-107.422234,66.93969700000002],[-107.42944299999999,66.94914200000011],[-107.43888899999996,66.95832800000005],[-107.44471699999997,66.96249399999994],[-107.44387799999993,66.96804800000012],[-107.435272,66.97221400000001],[-107.421944,66.97276299999999],[-107.40611299999995,66.97137500000008],[-107.37943999999993,66.966095],[-107.35916099999992,66.959427],[-107.23388699999992,66.90220600000009],[-107.21806299999997,66.89471400000014],[-107.21028099999995,66.89082300000007],[-107.1875,66.87359600000002],[-107.15750099999991,66.84693900000013],[-107.15055799999999,66.83749400000005],[-107.14916999999991,66.83221400000002],[-107.137787,66.82360800000009],[-107.12554899999992,66.82054099999999],[-107.09472700000003,66.81832900000012],[-107.08361799999994,66.82054099999999],[-107.15527299999997,66.899719],[-107.203888,66.94470200000006],[-107.22666900000002,66.96165500000001],[-107.24027999999998,66.96998600000006],[-107.29750100000001,67.00193800000005],[-107.3052669999999,67.00582900000012],[-107.31139399999995,67.12719700000002],[-107.38806199999993,67.14444000000015],[-107.43083200000001,67.15832500000005],[-107.44915800000001,67.16554300000007],[-107.47332799999992,67.17692600000004],[-107.48137700000001,67.18081699999993],[-107.50306699999993,67.1927490000001],[-107.53250100000002,67.214157],[-107.64862099999993,67.359985],[-107.57694999999995,67.47554000000014],[-107.57389799999993,67.48165899999998],[-107.57528699999995,67.48692299999999],[-107.578888,67.49165299999999],[-107.58277899999996,67.49636800000002],[-107.58860799999991,67.50082399999997],[-107.71833800000002,67.57331800000009],[-107.74054699999994,67.58526599999993],[-107.77362099999999,67.60054000000002],[-107.81331599999999,67.61442600000004],[-107.84472700000003,67.62442000000004],[-107.89055599999989,67.64248700000007],[-107.96916199999998,67.6766510000001],[-107.98972300000003,67.68887300000011],[-107.99944299999999,67.69802900000008],[-108.006958,67.70748900000012],[-108.01334399999996,67.728317],[-108.01445000000001,67.73414600000001],[-108.015289,67.74498000000006],[-108.01390099999998,67.756104],[-108.00805699999995,67.76832600000012],[-107.99249299999997,67.78804000000002],[-107.94833399999993,67.84109500000011],[-107.94193999999999,67.84693900000013],[-107.93415800000002,67.85165399999994],[-107.92278299999998,67.8538670000001],[-107.890289,67.85165399999994],[-107.87777699999992,67.85331700000006],[-107.85527000000002,67.85775799999999],[-107.75666799999993,67.88081400000004],[-107.71472199999994,67.89248700000007],[-107.70472699999993,67.89582800000011],[-107.674713,67.91609200000005],[-107.66166699999997,67.92747500000002],[-107.65110800000002,67.94053599999995],[-107.65499899999992,67.94525099999998],[-107.66555800000003,67.94859300000013],[-107.770508,67.96526300000005],[-107.81133999999992,67.97159600000003],[-107.910278,67.988586],[-107.91639699999996,67.99304200000006],[-107.91999800000002,67.99775699999992],[-107.89055599999989,68.08166499999999],[-107.88527699999997,68.08831800000013],[-107.87888299999997,68.09387200000015],[-107.86332699999997,68.10359200000005],[-107.85166899999996,68.1060940000001],[-107.837784,68.10443099999998],[-107.72112300000003,68.08276399999994],[-107.69943199999994,68.07582100000013],[-107.69360399999994,68.07165500000008],[-107.69776899999994,68.0663760000001],[-107.70667300000002,68.06248500000004],[-107.72721899999993,68.05609099999998],[-107.73860200000001,68.05386400000009],[-107.77250700000002,68.05693100000002],[-107.78778099999994,68.05720500000012],[-107.80027799999999,68.05581700000005],[-107.80943299999996,68.05165099999994],[-107.83332799999988,68.01304600000003],[-107.83389299999999,68.00721700000003],[-107.82778899999988,68.00305200000003],[-107.8038479999999,68.00426499999998],[-107.78733799999998,67.99759700000004],[-107.77900699999998,67.9967650000001],[-107.763847,67.99842800000005],[-107.75699599999996,67.99977100000012],[-107.75426500000003,68.00681299999997],[-107.73306300000002,68.020828],[-107.72501399999993,68.02581800000002],[-107.69027699999992,68.04248000000001],[-107.67999299999997,68.04582199999993],[-107.61028299999998,68.05859399999997],[-107.58583099999998,68.05998200000005],[-107.57084700000001,68.05970800000011],[-107.53806299999997,68.05748],[-107.45028699999989,68.04721100000012],[-107.38890100000003,68.04525799999999],[-107.36221299999994,68.04693600000013],[-107.34944200000001,68.04859900000002],[-107.32640099999998,68.05304000000012],[-107.28778099999994,68.06498700000009],[-107.25140399999998,68.080826],[-107.22638699999993,68.09443699999997],[-107.154449,68.12692300000009],[-107.141953,68.128311],[-107.11028299999998,68.12692300000009],[-107.10665899999998,68.12220800000006],[-107.11888099999987,68.08471700000007],[-106.96556099999998,68.11331200000012],[-106.95278899999988,68.11470000000003],[-106.85611,68.11692799999997],[-106.84111000000001,68.11637900000005],[-106.80194099999994,68.1974790000001],[-106.80943300000001,68.20721400000002],[-106.80610699999994,68.21304300000003],[-106.80027799999993,68.21748400000013],[-106.79110700000001,68.22137500000002],[-106.62748699999997,68.24664300000006],[-106.61444099999994,68.24803200000008],[-106.5994419999999,68.24748200000005],[-106.58860800000002,68.24414100000001],[-106.468613,68.19053600000012],[-106.45777900000002,68.176376],[-106.45417799999996,68.16081200000008],[-106.45056199999999,68.15582300000011],[-106.44471699999991,68.15165700000006],[-106.43195300000002,68.15304600000002],[-106.42138699999987,68.15609700000005],[-106.35056299999997,68.1791530000001],[-106.34472699999998,68.18331899999998],[-106.35056299999997,68.18775900000003],[-106.35888699999992,68.1916500000001],[-106.39277600000003,68.20166],[-106.420837,68.20721400000002],[-106.468887,68.21443199999999],[-106.48194899999993,68.21748400000013],[-106.48999000000003,68.22137500000002],[-106.49582699999996,68.22554000000002],[-106.49722300000002,68.23082000000005],[-106.46833799999996,68.32971199999997],[-106.46501199999994,68.33581500000014],[-106.45667299999991,68.34082000000001],[-106.44748700000002,68.34471100000007],[-106.42639200000002,68.35081500000007],[-106.25611900000001,68.3877720000001],[-106.24416400000001,68.38998400000014],[-106.21833800000002,68.39248700000013],[-106.203056,68.39221199999992],[-106.185272,68.38998400000014],[-106.17471299999994,68.38665800000012],[-106.16665599999999,68.38275099999998],[-106.1547159999999,68.37387100000012],[-105.79638699999998,68.42221100000012],[-105.79055799999998,68.41804500000006],[-105.78222699999998,68.41387899999995],[-105.76583900000003,68.41276600000009],[-105.75167799999991,68.41304000000002],[-105.73972300000003,68.41526799999997],[-105.73029300000002,68.41914400000002],[-105.723053,68.42469800000003],[-105.70111099999991,68.46971100000013],[-105.69721999999996,68.486649],[-105.69833399999993,68.49192800000003],[-105.70278899999994,68.50193800000011],[-105.71444699999995,68.51054400000004],[-105.74305700000002,68.56469700000014],[-105.724716,68.57415800000012],[-105.64499699999999,68.63388099999997],[-105.65083300000003,68.63804600000014],[-105.66639699999996,68.638596],[-105.902222,68.63526900000005],[-105.92832899999996,68.632477],[-106.02944899999994,68.61970499999995],[-106.041382,68.61747700000001],[-106.04972799999996,68.61276199999998],[-106.04750100000001,68.60220300000015],[-106.05332900000002,68.59582499999999],[-106.06416300000001,68.59275800000006],[-106.2077789999999,68.56776400000007],[-106.23638900000003,68.566666],[-106.37027,68.5452580000001],[-106.51083399999999,68.518326],[-106.54387700000001,68.51193200000012],[-106.62471,68.46748400000007],[-106.63166799999999,68.461929],[-106.62888299999992,68.45138500000013],[-106.62165799999997,68.44192500000003],[-106.61582899999996,68.43775900000014],[-106.59528399999994,68.42526199999998],[-106.58473200000003,68.42164600000012],[-106.57167099999992,68.41859399999998],[-106.55387899999994,68.41665600000005],[-106.52194199999997,68.41499299999992],[-106.50446299999999,68.41276600000009],[-106.493607,68.40942400000012],[-106.48777799999988,68.40498400000013],[-106.48055999999997,68.39553799999999],[-106.52722199999994,68.30081200000012],[-106.534157,68.29525799999993],[-106.54332699999998,68.29136700000004],[-106.556107,68.28997800000008],[-106.57277699999986,68.29109200000005],[-106.58444199999991,68.29332],[-106.59500099999997,68.29664600000007],[-106.60109699999998,68.30108600000005],[-106.6119379999999,68.31526200000008],[-106.6383439999999,68.34304800000012],[-106.64444700000001,68.34748799999994],[-106.77887699999997,68.40803499999998],[-106.78971899999999,68.41165200000012],[-106.80277999999993,68.41442899999998],[-107.01363400000002,68.36943100000008],[-107.02166699999998,68.36469999999997],[-107.02027899999996,68.359421],[-107.016663,68.35470599999996],[-107.01750199999998,68.34915199999995],[-107.03138699999994,68.33776899999998],[-107.13221699999991,68.2833250000001],[-107.24610899999999,68.26138300000002],[-107.25890400000003,68.25999500000012],[-107.26500699999997,68.26416000000012],[-107.274719,68.27331499999997],[-107.28611799999993,68.28749099999999],[-107.29611199999994,68.29664600000007],[-107.30194099999994,68.30081200000012],[-107.3272169999999,68.31248499999998],[-107.33805799999999,68.315811],[-107.54666099999992,68.34748799999994],[-107.56082200000003,68.34915199999995],[-107.81331599999999,68.34248400000001],[-107.82611099999997,68.341095],[-107.83640300000002,68.33804300000008],[-107.84973100000002,68.32638500000007],[-107.85500299999995,68.31999200000007],[-107.88527699999997,68.26887499999998],[-107.883621,68.26361099999997],[-107.879707,68.25888099999997],[-107.85417199999995,68.24748200000005],[-107.83029199999993,68.2410890000001],[-107.74194299999999,68.2169340000001],[-107.61332700000003,68.17858899999999],[-107.60249299999998,68.17526200000003],[-107.59861799999999,68.17053199999998],[-107.60305800000003,68.16526800000003],[-107.61582900000002,68.16387900000001],[-107.63221699999997,68.16499299999998],[-107.68998699999997,68.17442300000005],[-107.78639199999992,68.18386800000013],[-107.80027799999999,68.18331899999998],[-107.82584399999996,68.18054200000012],[-107.87193300000001,68.17137100000014],[-108.03388999999999,68.16859400000004],[-108.16139199999986,68.17275999999998],[-108.18694299999999,68.16998300000006],[-108.19695300000001,68.1666560000001],[-108.22028399999999,68.15220599999998],[-108.24944299999993,68.14166300000005],[-108.30055199999993,68.12580900000012],[-108.33222999999998,68.11720300000002],[-108.37026999999989,68.11276200000009],[-108.38555899999994,68.11303700000008],[-108.40306099999998,68.11499000000003],[-108.41388699999993,68.11831699999999],[-108.42250099999995,68.12220800000006],[-108.43277,68.13108800000009],[-108.43611099999987,68.14137300000004],[-108.43306000000001,68.14749099999995],[-108.42804699999994,68.15416000000005],[-108.40888999999999,68.16137700000013],[-108.39750700000002,68.16360500000008],[-108.36694299999994,68.16110200000008],[-108.36277799999993,68.15637200000009],[-108.36582899999996,68.15026899999998],[-108.37361099999993,68.14526400000011],[-108.37998999999996,68.13970899999998],[-108.37832599999996,68.13443000000001],[-108.36527999999993,68.13360600000004],[-108.34612299999998,68.14082300000001],[-108.33860800000002,68.14582800000005],[-108.33332799999994,68.15220599999998],[-108.33056599999998,68.15860000000004],[-108.32695000000001,68.17025800000005],[-108.32444800000002,68.19274900000005],[-108.32945299999989,68.208328],[-108.3958439999999,68.28997800000008],[-108.40222199999994,68.29414400000013],[-108.443604,68.30802900000003],[-108.46000700000002,68.309143],[-108.484444,68.30525199999994],[-108.504997,68.29887400000001],[-108.55999800000001,68.27554299999997],[-108.56500199999999,68.26887499999998],[-108.56806899999992,68.26277200000004],[-108.57444799999996,68.25721699999997],[-108.58444199999997,68.2538760000001],[-108.71556099999998,68.23136900000003],[-108.72944599999988,68.23082000000005],[-108.74610899999993,68.23193400000002],[-108.756958,68.2352600000001],[-108.765556,68.23887600000012],[-108.81527699999998,68.26220699999999],[-108.81916799999993,68.26666300000011],[-108.8141629999999,68.27331499999997],[-108.748894,68.33776899999998],[-108.74109599999997,68.34275800000012],[-108.71417199999996,68.35470599999996],[-108.70417799999996,68.35803199999998],[-108.69387799999993,68.36109899999991],[-108.670837,68.36581399999994],[-108.63999899999993,68.37553400000002],[-108.62082700000002,68.38275099999998],[-108.61193800000001,68.38665800000012],[-108.58112299999999,68.40637200000003],[-108.56667299999998,68.41693100000009],[-108.53443900000002,68.44552600000009],[-108.52916699999992,68.4522090000001],[-108.52278100000001,68.4580380000001],[-108.43167099999994,68.53831500000007],[-108.40416700000003,68.56025699999998],[-108.383331,68.57666],[-108.36888099999999,68.58720400000004],[-108.34528399999994,68.60192899999998],[-108.31416300000001,68.61137400000007],[-108.27916700000003,68.61831700000005],[-108.25195299999996,68.62052900000015],[-108.1702729999999,68.62664799999999],[-107.93331899999998,68.64027399999992],[-107.80499299999997,68.6455380000001],[-107.63834399999996,68.66554300000013],[-107.43167099999994,68.69053600000001],[-107.23137700000001,68.71887200000009],[-107.108337,68.74859600000013],[-106.96140300000002,68.78305100000006],[-106.93859899999995,68.78831500000001],[-106.82084700000001,68.81137100000007],[-106.79444899999993,68.81387299999994],[-106.765556,68.81498699999992],[-106.63500999999991,68.81832900000006],[-106.31555200000003,68.89276100000012],[-106.27250699999996,68.90470900000003],[-106.262787,68.90887500000008],[-106.25446299999993,68.91360500000013],[-106.24833699999988,68.91998300000006],[-106.24472000000003,68.926086],[-106.24360699999994,68.93165600000009],[-106.23998999999998,68.93775900000003],[-106.229172,68.940811],[-106.214722,68.94136000000009],[-106.20140100000003,68.94053600000012],[-106.14943699999998,68.93359400000003],[-106.08084099999996,68.91886900000009],[-105.81360599999988,68.88192700000008],[-105.79804999999999,68.87942500000003],[-105.77639799999997,68.87248199999999],[-105.71806300000003,68.84498599999995],[-105.48693800000001,68.72943099999998],[-105.475281,68.72053500000004],[-105.471657,68.71582000000001],[-105.47833300000002,68.69859299999996],[-105.48194899999999,68.69247400000012],[-105.4891659999999,68.68691999999993],[-105.498894,68.68304400000005],[-105.49944299999999,68.62136800000007],[-105.41443600000002,68.528595],[-105.380829,68.486649],[-105.40888999999999,68.49247700000012],[-105.42304999999999,68.49192800000003],[-105.43388400000003,68.4891510000001],[-105.44360399999994,68.48526000000004],[-105.52944899999994,68.45027200000004],[-105.53806299999991,68.44552600000009],[-105.54387700000001,68.43914799999999],[-105.54778299999998,68.43304400000011],[-105.54888900000003,68.42747500000013],[-105.54804999999999,68.42221100000012],[-105.54110699999995,68.41276600000009],[-105.53307299999994,68.40859999999998],[-105.51777600000003,68.40609699999999],[-105.41639700000002,68.40693700000008],[-105.39028899999988,68.40942400000012],[-105.34528399999999,68.38415500000013],[-105.34889199999992,68.37803600000012],[-105.350281,68.3724820000001],[-105.34472700000003,68.36804200000012],[-105.29499800000002,68.33915700000006],[-105.28694200000001,68.33526599999999],[-105.10082999999992,68.26609800000006],[-105.07305899999994,68.26026900000005],[-105.05555700000002,68.2580410000001],[-105.02639799999992,68.257767],[-105.00894900000003,68.26493800000003],[-105.00661500000001,68.26859999999994],[-105.00578300000001,68.27209499999992],[-105.00666799999993,68.27859500000005],[-105.01695299999994,68.28221100000013],[-105.02610800000002,68.30941800000005],[-104.88474300000001,68.33970599999998],[-104.86416600000001,68.33248900000007],[-104.848053,68.3247070000001],[-104.83917200000002,68.31553600000001],[-104.83583099999998,68.31080600000013],[-104.83416699999998,68.30026200000009],[-104.83944699999995,68.28858900000006],[-104.84584000000001,68.28221100000013],[-104.85305800000003,68.27665700000011],[-104.86277799999993,68.27276600000005],[-104.87332199999997,68.26971400000014],[-104.94554099999999,68.2580410000001],[-104.952789,68.25248700000009],[-104.95194999999995,68.24748200000005],[-104.94055200000003,68.23858600000011],[-104.924713,68.23054500000006],[-104.91443600000002,68.22720300000009],[-104.900284,68.22526600000009],[-104.88639799999999,68.22554000000002],[-104.87332199999997,68.22692899999998],[-104.79750100000001,68.24443100000002],[-104.73111,68.25027500000004],[-104.68776699999995,68.25027500000004],[-104.63999899999999,68.24693300000013],[-104.609734,68.24136400000009],[-104.59889199999998,68.232483],[-104.59722899999997,68.22221400000012],[-104.61277799999999,68.19802900000013],[-104.61888099999993,68.1916500000001],[-104.6324919999999,68.17942800000009],[-104.65471600000001,68.16276600000015],[-104.66722099999993,68.1499940000001],[-104.67027299999995,68.13859600000012],[-104.5922159999999,68.0836030000001],[-104.50778200000002,68.03581200000002],[-104.5,68.03193700000003],[-104.48638900000003,68.02998400000013],[-104.45722999999992,68.02970900000008],[-104.36694299999994,68.03414900000013],[-104.21472199999994,68.02415500000006],[-104.199997,68.02137800000003],[-104.16665599999993,68.01748700000013],[-104.12470999999994,68.01832600000006],[-104.11193800000001,68.01944000000003],[-104.06471299999998,68.02748099999997],[-104.01139799999999,68.04220600000008],[-103.99944299999999,68.04414400000002],[-103.98554999999999,68.04443400000002],[-103.97084000000001,68.04386900000003],[-103.94082600000002,68.03831500000001],[-103.92832900000002,68.03498800000006],[-103.89806399999998,68.02415500000006],[-103.883621,68.02137800000003],[-103.87082699999996,68.020264],[-103.84306300000003,68.020828],[-103.791382,68.0252690000001],[-103.76695299999994,68.02832000000006],[-103.55526700000001,68.05720500000012],[-103.54444899999987,68.05998200000005],[-103.53694200000001,68.06553600000007],[-103.53278399999999,68.07165500000008],[-103.53333299999991,68.07666000000012],[-103.53639199999998,68.08166499999999],[-103.54472399999997,68.09082000000001],[-103.55526700000001,68.09971599999994],[-103.55803699999996,68.10443099999998],[-103.55304699999999,68.10971100000006],[-103.52139299999999,68.13081399999999],[-103.50389099999995,68.14027400000003],[-103.49526999999995,68.14471400000008],[-103.46694899999994,68.15693699999991],[-103.45722999999998,68.16053799999997],[-103.42166099999997,68.1666560000001],[-103.40416700000003,68.16415400000005],[-103.38971700000002,68.16137700000013],[-103.38194299999992,68.15721100000002],[-103.36888099999999,68.14888000000013],[-103.34416199999993,68.12109400000008],[-103.34137699999991,68.11608900000004],[-103.34028599999988,68.10582],[-103.341949,68.10026599999998],[-103.37249799999995,68.06860400000005],[-103.36916399999996,68.01081800000003],[-103.36609599999997,68.00582900000006],[-103.25418100000002,67.966385],[-103.22084000000001,67.9622040000001],[-103.20612299999999,67.96138000000013],[-103.17832899999996,67.96192900000005],[-103.14943699999998,67.96138000000013],[-103.13694800000002,67.95803799999999],[-103.12943999999999,67.95387299999999],[-103.12416100000002,67.9497070000001],[-103.11277799999999,67.93026700000013],[-103.1052699999999,67.92608600000005],[-103.09306300000003,67.92303500000003],[-103.01471700000002,67.91360500000013],[-103.00083899999998,67.91387900000007],[-102.99082899999996,67.91748000000013],[-102.98222399999997,67.92221100000006],[-102.97250399999996,67.92581200000012],[-102.95944199999985,67.9269260000001],[-102.94972199999995,67.92330900000013],[-102.94444299999998,67.91886899999992],[-102.939438,67.9144290000001],[-102.921112,67.89637800000014],[-102.82972699999993,67.83194000000003],[-102.80027799999993,67.820831],[-102.686394,67.80470300000013],[-102.67054699999994,67.80304000000001],[-102.53611799999999,67.79525800000005],[-102.50446299999999,67.79193100000009],[-102.47083999999995,67.78692600000005],[-102.446663,67.78027300000008],[-102.39306599999992,67.76249700000011],[-102.33972199999994,67.74470500000007],[-102.251106,67.72526600000015],[-102.22444199999995,67.73387100000002],[-102.21556099999992,67.73831200000012],[-102.15139799999997,67.76554900000002],[-102.1416779999999,67.76915000000008],[-101.92610200000001,67.760269],[-101.7647169999999,67.72331200000013],[-101.671944,67.69164999999998],[-101.54250300000001,67.67942800000003],[-101.51500699999997,67.67942800000003],[-101.446663,67.73248300000012],[-101.43388400000003,67.73332200000004],[-101.10582699999992,67.74192800000014],[-101.09889199999998,67.73776200000009],[-101.01278699999995,67.74247700000012],[-100.99973299999999,67.74331699999999],[-100.92749000000003,67.75332599999996],[-100.90387699999991,67.75694299999992],[-100.89277600000003,67.75972000000002],[-100.811394,67.79470800000001],[-100.72028399999994,67.83442700000012],[-100.58167999999995,67.83415200000013],[-100.39555399999995,67.84748800000006],[-100.18415799999997,67.84304800000007],[-100.16832699999998,67.84109500000011],[-100.156387,67.83776900000004],[-100.14723200000003,67.82859800000011],[-100.135559,67.8252720000001],[-100.083618,67.81498699999997],[-99.82000699999992,67.79582199999999],[-99.618607,67.789154],[-99.60777299999995,67.79193100000009],[-99.58917200000002,67.80081200000006],[-99.577789,67.80331400000011],[-99.50056499999994,67.79971300000005],[-99.41221599999989,67.78831500000007],[-99.40306099999992,67.784424],[-99.39862099999999,67.77998399999996],[-99.39666699999998,67.7749940000001],[-99.387787,67.76582299999995],[-99.37832599999996,67.76193200000006],[-99.23611499999998,67.71360800000014],[-99.21055599999994,67.70694000000015],[-98.98693800000001,67.718323],[-98.81361399999997,67.74192800000014],[-98.52888499999989,67.77748100000002],[-98.38583399999999,67.78581200000008],[-98.36332700000003,67.79081700000012],[-98.354446,67.79609700000003],[-98.35804699999994,67.8058170000001],[-98.44249000000002,67.86137400000007],[-98.44943199999994,67.86581400000006],[-98.46333300000003,67.86886599999997],[-98.47555499999999,67.86720300000007],[-98.48611499999993,67.86387600000012],[-98.49888599999997,67.86331200000001],[-98.51472499999994,67.86526500000014],[-98.54028299999999,67.87220800000011],[-98.65583799999996,67.91638200000006],[-98.665009,67.9202580000001],[-98.69694499999991,67.936646],[-98.71972699999992,67.94886799999995],[-98.72416699999985,67.953598],[-98.74694799999997,68.0477600000001],[-98.73277299999995,68.070267],[-98.61555499999992,68.07470699999999],[-98.54499800000002,68.06137100000007],[-98.33694500000001,67.96026599999999],[-98.321121,67.95220899999998],[-98.26695299999989,67.92330900000013],[-98.23332199999999,67.9019320000001],[-98.171112,67.84332300000005],[-98.16915899999992,67.838593],[-98.12277199999994,67.78804000000002],[-98.09445199999993,67.766098],[-97.95666499999987,67.72776800000008],[-97.79943800000001,67.68553200000008],[-97.66194200000001,67.64305100000007],[-97.650284,67.63943499999999],[-97.63751200000002,67.6308140000001],[-97.62609900000001,67.61804200000006],[-97.61305199999998,67.609421],[-97.603882,67.60525500000006],[-97.59277299999985,67.601654],[-97.57667499999997,67.59860200000008],[-97.56138599999991,67.59664900000013],[-97.54750100000001,67.59637500000002],[-97.50973499999992,67.59915200000012],[-97.48582499999992,67.60220300000015],[-97.415009,67.61331200000006],[-97.39222699999999,67.61804200000006],[-97.38194299999998,67.62136800000013],[-97.35305800000003,67.63443000000012],[-97.33444199999991,67.64387500000004],[-97.31666599999994,67.65443400000004],[-97.29554699999994,67.66110200000003],[-97.28332499999999,67.66249100000005],[-97.16722099999993,67.67553700000013],[-97.13890099999992,67.67414900000006],[-97.11694299999988,67.77748100000002],[-97.11582899999996,67.78276100000005],[-97.11915599999992,67.79248000000007],[-97.12721299999998,67.80165099999999],[-97.24027999999998,67.92608600000005],[-97.2541809999999,67.92942800000014],[-97.26306199999993,67.924149],[-97.26888999999994,67.91832],[-97.27305599999994,67.90776100000011],[-97.27362099999999,67.90248100000008],[-97.27722199999994,67.89694200000008],[-97.28277600000001,67.89109800000006],[-97.29110700000001,67.88499500000012],[-97.30139200000002,67.88165299999997],[-97.32444799999996,67.8766480000001],[-97.33667000000003,67.87525900000014],[-97.362503,67.87387100000001],[-97.37638899999996,67.87414600000005],[-97.39222699999999,67.87637300000011],[-97.40333599999997,67.879974],[-97.412216,67.88415500000008],[-97.41639700000002,67.888596],[-97.41972399999986,67.89833100000004],[-97.42805499999986,67.90776100000011],[-97.43443300000001,67.91192600000011],[-97.449997,67.9202580000001],[-97.64361600000001,68.008331],[-97.65249599999999,68.01220700000005],[-97.68306000000001,68.01859999999999],[-97.695267,68.01721200000009],[-97.70500199999998,68.0127720000001],[-97.70834400000001,68.00721700000003],[-97.710556,67.9916530000001],[-97.87777699999998,67.96360800000008],[-97.99665799999991,67.95027199999998],[-98.00973499999992,67.9497070000001],[-98.02999899999998,67.94192499999997],[-98.045837,67.92942800000014],[-98.05139199999996,67.92359899999997],[-98.05749500000002,67.91249099999999],[-98.060272,67.89166300000011],[-98.06388899999996,67.82916299999994],[-98.07861300000002,67.83027600000003],[-98.09527600000001,67.83332799999994],[-98.10665899999998,67.836929],[-98.11582899999996,67.84082000000006],[-98.17639200000002,67.87387100000001],[-98.189438,67.88247699999994],[-98.19471699999997,67.89721700000007],[-98.20083599999998,67.90664700000013],[-98.21362299999998,67.92053200000004],[-98.224716,67.92942800000014],[-98.25140399999998,67.94636500000001],[-98.28332499999993,67.96276899999992],[-98.31973299999993,67.97859199999999],[-98.34056099999998,67.98609900000008],[-98.37805199999997,67.99636800000013],[-98.39862099999999,68.004166],[-98.412216,68.01249700000005],[-98.58111599999995,68.13998400000003],[-98.58750900000001,68.14942900000011],[-98.58444199999991,68.15498400000001],[-98.485275,68.184418],[-98.47389199999998,68.18692000000004],[-98.45973200000003,68.18359400000003],[-98.45056199999999,68.17970300000013],[-98.43249500000002,68.1666560000001],[-98.42805499999992,68.1622010000001],[-98.42443799999995,68.15220599999998],[-98.42555199999993,68.14193699999998],[-98.42832900000002,68.13638300000014],[-98.43415800000002,68.13053899999994],[-98.44027699999998,68.11943100000013],[-98.44110099999995,68.10914600000001],[-98.439438,68.10415599999999],[-98.43055699999991,68.09498600000012],[-98.41722099999993,68.08638000000002],[-98.408051,68.08248900000012],[-98.39389,68.07916300000011],[-98.37999000000002,68.07916300000011],[-98.36776700000001,68.08055100000001],[-98.35888699999998,68.08581499999997],[-98.35082999999992,68.09220900000003],[-98.33972199999994,68.10386700000004],[-98.32167099999998,68.13693200000012],[-98.31777999999997,68.14776599999999],[-98.31722999999994,68.15304600000002],[-98.31750499999998,68.1622010000001],[-98.32611099999997,68.17137100000014],[-98.33306899999997,68.17553700000002],[-98.34222399999993,68.17942800000009],[-98.37748699999992,68.19026200000002],[-98.40834000000001,68.19664000000012],[-98.43971299999993,68.20082100000002],[-98.46972700000003,68.20304900000002],[-98.485275,68.20498700000013],[-98.50111399999997,68.20860299999998],[-98.531113,68.22526600000009],[-98.537781,68.22943100000009],[-98.54222099999993,68.23414600000012],[-98.56111099999998,68.27388000000002],[-98.60777299999995,68.29332],[-98.70417800000001,68.35276800000003],[-98.71083099999998,68.35693400000008],[-98.71528599999999,68.36164899999994],[-98.71722399999993,68.366379],[-98.71444699999995,68.372208],[-98.70472699999993,68.376373],[-98.68055700000002,68.38053900000011],[-98.66749600000003,68.38136300000008],[-98.63722199999995,68.3791500000001],[-98.60638399999999,68.37275699999998],[-98.59416199999998,68.36914100000007],[-98.58056599999992,68.36080900000007],[-98.57167099999998,68.35165400000005],[-98.54861499999998,68.33915700000006],[-98.53250100000002,68.3311000000001],[-98.52139299999993,68.32832300000001],[-98.51139799999993,68.32971199999997],[-98.47083999999995,68.34832799999998],[-98.46221899999995,68.35359199999999],[-98.46139499999998,68.35887100000014],[-98.47138999999999,68.37359600000008],[-98.49194299999994,68.38638300000008],[-98.50361599999997,68.38998400000014],[-98.49499499999996,68.40942400000012],[-98.319458,68.35887100000014],[-98.30972300000002,68.35498000000007],[-98.29888900000003,68.34610000000004],[-98.29444899999993,68.34137000000004],[-98.29249599999997,68.33665500000001],[-98.28832999999997,68.33194000000015],[-98.281387,68.32777400000003],[-98.22555499999993,68.30415299999999],[-98.21389799999992,68.30053700000013],[-98.19972200000001,68.30026200000009],[-98.18749999999994,68.3019260000001],[-98.09666399999998,68.31776400000012],[-98.07389799999999,68.33499099999995],[-97.90583800000002,68.38415500000013],[-97.89411899999993,68.386459],[-97.86471599999993,68.384995],[-97.84916699999991,68.38304099999999],[-97.77778599999988,68.366379],[-97.761124,68.36331200000006],[-97.74888599999991,68.36469999999997],[-97.74305699999991,68.37052899999998],[-97.75140399999998,68.37970000000013],[-97.76417499999991,68.39360000000005],[-97.76861600000001,68.39804100000015],[-97.78195199999993,68.40664700000002],[-97.79611199999988,68.40998800000006],[-97.81138599999997,68.41137700000007],[-97.86971999999997,68.414154],[-97.885559,68.41638200000011],[-97.89999399999994,68.41970799999996],[-97.906387,68.42387400000007],[-98.00973499999992,68.49803200000002],[-98.01139799999993,68.50305200000008],[-98.01083399999999,68.50804100000005],[-97.99972500000001,68.53526299999999],[-97.99415599999992,68.54109199999999],[-97.85249299999998,68.54248000000007],[-97.83639499999992,68.54026800000003],[-97.72389199999992,68.52304100000003],[-97.69276400000001,68.51666300000005],[-97.66500899999994,68.50471500000003],[-97.6583399999999,68.50054900000009],[-97.6541749999999,68.49609400000008],[-97.65055799999993,68.48609899999997],[-97.65388499999995,68.480545],[-97.65527299999997,68.470261],[-97.650284,68.45555100000001],[-97.646118,68.45082099999996],[-97.63917500000002,68.44664000000006],[-97.61166399999996,68.43470800000011],[-97.537781,68.41832000000005],[-97.523056,68.41693100000009],[-97.51112399999994,68.41943400000002],[-97.502228,68.42469800000003],[-97.49888599999997,68.43026700000001],[-97.500565,68.43498200000005],[-97.50917099999998,68.44442700000013],[-97.520554,68.44802900000008],[-97.535553,68.449142],[-97.54750100000001,68.44664000000006],[-97.57333399999993,68.44442700000013],[-97.58917199999996,68.44664000000006],[-97.60333299999996,68.449997],[-97.615005,68.45359800000006],[-97.61915599999992,68.45832800000011],[-97.61776700000001,68.46249399999999],[-97.597778,68.48359700000009],[-97.57861300000002,68.493042],[-97.56777999999997,68.49636800000002],[-97.54444899999999,68.50138900000013],[-97.53111299999995,68.50193800000011],[-97.51695299999994,68.50166300000006],[-97.385559,68.49525499999993],[-97.35360699999995,68.49108900000004],[-97.28277600000001,68.47415200000006],[-97.25917099999987,68.4666600000001],[-97.160278,68.38943500000005],[-97.05332900000002,68.35331699999995],[-97.058334,68.30276500000008],[-97.07000700000003,68.30026200000009],[-97.07583599999992,68.29443399999997],[-97.09111000000001,68.26805100000001],[-97.089447,68.26332099999996],[-97.08029199999993,68.25915500000008],[-96.93916299999995,68.23970000000008],[-96.925003,68.23915099999999],[-96.91250599999995,68.24081400000006],[-96.81777999999991,68.25833100000011],[-96.80638099999993,68.26081800000003],[-96.79943800000001,68.26554899999996],[-96.76777599999997,68.270264],[-96.69387799999993,68.28027299999997],[-96.68055699999996,68.280823],[-96.66915899999998,68.27693199999993],[-96.62527499999987,68.25166300000012],[-96.55332899999996,68.27360500000003],[-96.53306600000002,68.28193699999997],[-96.47084000000001,68.305542],[-96.44888300000002,68.31219499999997],[-96.43721,68.31469700000002],[-96.42471299999994,68.31608600000004],[-96.410553,68.31553600000001],[-96.40417499999995,68.31137100000001],[-96.49694799999997,68.20776400000005],[-96.508896,68.19636500000013],[-96.52583299999998,68.18414299999995],[-96.62304699999999,68.11554000000007],[-96.69055199999997,68.07998700000007],[-96.702225,68.07748400000008],[-96.73028599999992,68.07832300000007],[-96.74305700000002,68.07777400000009],[-96.75556899999998,68.076096],[-96.77888499999995,68.07138099999997],[-96.79722599999997,68.06109600000002],[-96.80888399999998,68.04942299999999],[-96.81220999999994,68.04386900000003],[-96.81332399999991,68.03858900000012],[-96.8116609999999,68.03359999999998],[-96.801941,68.02581800000002],[-96.78916900000002,68.01721200000009],[-96.77305599999994,68.01388499999996],[-96.722778,68.00971999999996],[-96.70834399999995,68.00860599999999],[-96.67610199999996,68.01859999999999],[-96.55665599999998,68.03332499999993],[-96.54028299999993,68.03027300000002],[-96.52806099999998,68.03166200000004],[-96.46639999999996,68.03887900000012],[-96.45083599999998,68.05304000000012],[-96.47999600000003,68.09027100000009],[-96.49110399999995,68.09414700000013],[-96.50500499999993,68.09443699999997],[-96.51611300000002,68.09109500000005],[-96.53443900000002,68.080826],[-96.54695099999998,68.07943700000004],[-96.54834,68.08415200000007],[-96.54750100000001,68.0894320000001],[-96.53527799999989,68.10108900000006],[-96.51000999999997,68.11943100000013],[-96.48249800000002,68.13472000000002],[-96.46305799999993,68.14414999999991],[-96.43222000000003,68.15609700000005],[-96.31082200000003,68.19220000000013],[-96.28832999999997,68.19775400000009],[-96.17138699999992,68.22164900000013],[-96.13612399999994,68.2285920000001],[-95.98028599999998,68.25471500000003],[-95.96833800000002,68.23082000000005],[-96.04333499999996,68.17942800000009],[-96.06916799999999,68.16137700000013],[-96.07501200000002,68.15554800000012],[-96.07861299999996,68.1499940000001],[-96.07749899999999,68.14498900000007],[-96.073624,68.14027400000003],[-96.045837,68.13333100000006],[-96.03443900000002,68.12970000000001],[-96.02806099999998,68.12525900000009],[-96.02055399999995,68.11608900000004],[-96.01916499999993,68.11109899999997],[-96.02027900000002,68.1060940000001],[-96.083618,68.00221300000004],[-96.14416499999999,67.92359899999997],[-96.21166999999991,67.82916299999994],[-96.21528599999988,67.82360800000004],[-96.21722399999999,67.81330900000006],[-96.22138999999999,67.69775400000003],[-96.22000099999991,67.693039],[-96.21250899999995,67.68386800000007],[-96.20611600000001,67.67942800000003],[-96.19554099999999,67.68275499999999],[-96.18693499999995,67.68887300000011],[-96.17971799999992,67.69274899999999],[-96.16833500000001,67.69497700000011],[-96.16665599999999,67.69026200000008],[-96.174713,67.64305100000007],[-96.18527199999994,67.626373],[-96.19193999999999,67.62164300000012],[-96.20333900000003,67.61914100000007],[-96.21640000000002,67.61859100000004],[-96.23083499999996,67.61998],[-96.24665799999997,67.62330600000007],[-96.25778199999996,67.62692300000003],[-96.26640299999997,67.63108800000003],[-96.32972699999999,67.6102600000001],[-96.43777499999993,67.54136700000004],[-96.46139499999992,67.50888099999992],[-96.46472199999988,67.50332600000002],[-96.46916199999998,67.492752],[-96.46472199999988,67.47804300000013],[-96.46112099999999,67.47331200000002],[-96.45167500000002,67.47137499999997],[-96.44193999999993,67.47554000000014],[-96.36389200000002,67.47804300000013],[-96.29415899999998,67.444702],[-96.222778,67.42192099999994],[-96.21000699999996,67.41914400000007],[-96.19638099999992,67.41886900000003],[-96.18582199999997,67.422211],[-96.158051,67.43664600000011],[-96.141388,67.44886800000006],[-96.135559,67.45471200000009],[-96.11888099999993,67.4666600000001],[-96.10749800000002,67.46914700000002],[-96.09722899999997,67.46470600000009],[-96.069458,67.43359399999997],[-96.07028199999996,67.42831400000011],[-96.12416100000002,67.37719699999997],[-96.16665599999999,67.34166000000005],[-96.17721599999987,67.33692900000011],[-96.208618,67.3269350000001],[-96.218613,67.322769],[-96.226944,67.31666600000005],[-96.25111399999992,67.25277699999998],[-96.252228,67.24748200000005],[-96.24360699999988,67.24331700000005],[-96.12999000000002,67.21665999999999],[-96.114441,67.21331800000007],[-96.10249299999998,67.21470599999998],[-96.09138499999995,67.21720900000014],[-95.921112,67.27859500000005],[-95.81750499999993,67.33194000000015],[-95.756393,67.36747700000006],[-95.73999000000003,67.37664800000005],[-95.60305799999992,67.383331],[-95.58944699999995,67.38304099999999],[-95.57694999999995,67.38026400000007],[-95.56582599999996,67.37664800000005],[-95.54916399999996,67.36831699999993],[-95.53472899999997,67.359985],[-95.52861000000001,67.35554500000012],[-95.52500899999995,67.35108900000006],[-95.55332899999996,67.31330900000012],[-95.56166099999996,67.30720500000012],[-95.61805699999996,67.27832000000006],[-95.63806199999999,67.27082800000011],[-95.67748999999998,67.25416600000011],[-95.69665499999996,67.24498],[-95.76306199999988,67.2127690000001],[-95.80749500000002,67.18609600000013],[-95.82389799999999,67.174149],[-95.82972699999999,67.16831999999994],[-95.83332799999994,67.16276600000015],[-95.82167099999992,67.16110200000014],[-95.79695100000004,67.16304000000008],[-95.774719,67.16775500000011],[-95.74221799999998,67.17665100000005],[-95.71221899999995,67.18830900000006],[-95.65139799999992,67.19886800000012],[-95.568893,67.21054100000015],[-95.54415899999992,67.2124940000001],[-95.51583900000003,67.20971700000001],[-95.50111399999997,67.20748900000001],[-95.43554699999993,67.19386300000008],[-95.37943999999993,67.15470899999997],[-95.32611099999997,67.02720599999998],[-95.32861300000002,67.0169370000001],[-95.33721899999995,66.99054000000001],[-95.34333799999996,66.9747010000001],[-95.35028099999988,66.96388200000007],[-95.35777300000001,66.959991],[-95.41639699999996,66.9519350000001],[-95.53472899999997,66.94108600000004],[-95.597778,66.948868],[-95.61416600000001,66.97026100000011],[-95.721115,66.96470600000004],[-95.74333199999995,66.959991],[-95.83917199999996,66.94802900000002],[-95.87609900000001,66.94581600000004],[-95.90249599999999,66.94664],[-95.92805499999997,66.95248400000003],[-95.93638599999997,66.95664999999997],[-95.99027999999998,67.00499000000013],[-95.99388099999993,67.00972000000002],[-95.99055499999992,67.01499899999999],[-95.978882,67.026657],[-95.96112099999999,67.04386900000003],[-95.93638599999997,67.06526200000013],[-95.93221999999997,67.06971699999997],[-95.94694500000003,67.07222000000013],[-95.95834400000001,67.06971699999997],[-95.96777299999991,67.06553600000007],[-96.004456,67.04582199999999],[-96.04611199999994,67.01638799999995],[-96.05166599999995,67.01081800000009],[-96.053879,67.0002750000001],[-96.04666099999997,66.99108899999999],[-96.04055800000003,66.98664899999994],[-96.02362099999993,66.97859199999999],[-96.02500899999995,66.97331200000013],[-96.03306600000002,66.96748400000001],[-96.04277000000002,66.96304300000008],[-96.11054999999993,66.95082100000013],[-96.12332200000003,66.95027199999998],[-96.13861099999991,66.953598],[-96.24082899999996,66.98359700000003],[-96.26251200000002,66.99108899999999],[-96.27917500000001,66.99914599999994],[-96.285278,67.00360099999995],[-96.28694199999995,67.00860600000004],[-96.28582799999998,67.01361100000008],[-96.27417000000003,67.0252690000001],[-96.265289,67.03054800000007],[-96.26194799999996,67.03581200000008],[-96.261124,67.0410920000001],[-96.26362599999999,67.05108600000011],[-96.26888999999989,67.06053200000008],[-96.28805499999993,67.06832900000006],[-96.37721299999987,67.08471700000013],[-96.39222699999999,67.086929],[-96.40388499999995,67.08554100000009],[-96.45249899999999,67.06832900000006],[-96.46055599999988,67.06219500000003],[-96.45666499999999,67.05775499999999],[-96.40388499999995,67.008331],[-96.27362099999999,66.95027199999998],[-96.14639299999999,66.89471400000014],[-96.12805199999997,66.88165300000003],[-96.11721799999998,66.86775200000005],[-96.11582900000002,66.86276199999998],[-96.11721799999998,66.857483],[-96.11665299999999,66.84748800000006],[-96.11555499999997,66.84248400000013],[-96.1141659999999,66.83749400000005],[-96.10888699999998,66.83276400000005],[-96.10055499999993,66.82859800000011],[-96.00666799999993,66.79443400000008],[-95.98055999999991,66.7874910000001],[-95.95611599999995,66.78221100000007],[-95.91221599999994,66.77554300000008],[-95.883621,66.7688750000001],[-95.862213,66.76110799999998],[-95.848053,66.75277700000004],[-95.84194899999994,66.74832200000003],[-95.78472899999991,66.67414900000006],[-95.77749599999999,66.65498400000013],[-95.77722199999988,66.64471400000002],[-95.78083800000002,66.6291500000001],[-95.74137899999994,66.63804600000003],[-95.656387,66.6602630000001],[-95.64666699999998,66.66442899999998],[-95.62971499999998,66.67553699999996],[-95.62748699999997,66.68609600000002],[-95.64889499999998,66.724152],[-95.652222,66.72859200000005],[-95.660553,66.73275799999993],[-95.6744379999999,66.73414600000007],[-95.78472899999991,66.73719800000015],[-95.99305699999996,66.84275800000006],[-96.087784,66.90748600000012],[-96.0916749999999,66.911926],[-96.09277299999997,66.91693100000003],[-96.0916749999999,66.92221100000006],[-96.08555599999994,66.9269260000001],[-96.066956,66.93637100000001],[-96.04750099999995,66.94470200000006],[-96.037216,66.94802900000002],[-96.02610800000002,66.95027199999998],[-96.00029,66.95054600000009],[-95.90249599999999,66.94664],[-95.814438,66.94136000000015],[-95.78500400000001,66.93691999999993],[-95.77278099999995,66.93275499999993],[-95.766663,66.928314],[-95.76306199999988,66.92387400000001],[-95.760559,66.91387900000007],[-95.756958,66.90914900000007],[-95.75111400000003,66.90498400000007],[-95.73805199999998,66.90138200000013],[-95.72471599999994,66.90081799999996],[-95.516663,66.90220600000009],[-95.49305700000002,66.90498400000007],[-95.47222899999991,66.91165200000006],[-95.38917500000002,66.91110200000003],[-95.33666999999991,66.89305100000001],[-95.32362399999988,66.88943499999999],[-95.31138599999991,66.88998400000008],[-95.30082700000003,66.89332600000006],[-95.291672,66.8983310000001],[-95.26750199999998,66.91415400000011],[-95.25917099999998,66.92025799999993],[-95.2208399999999,66.96832299999994],[-95.21945199999999,66.97360200000014],[-95.22639499999997,66.9827580000001],[-95.23222399999997,66.98719800000009],[-95.28944399999995,67.02499400000005],[-95.34500099999997,67.08442700000012],[-95.35221899999999,67.14833100000004],[-95.34638999999999,67.15387000000004],[-95.2661129999999,67.2127690000001],[-95.16610700000001,67.27693199999999],[-95.162216,67.28221100000013],[-95.16332999999997,67.28720099999998],[-95.17193600000002,67.2913670000001],[-95.18249499999996,67.29525799999999],[-95.21722399999993,67.30636600000014],[-95.27972399999987,67.31944299999998],[-95.30638099999987,67.32666000000006],[-95.31471299999993,67.33055099999996],[-95.33277900000002,67.34387200000009],[-95.33639499999998,67.34832800000004],[-95.38417099999998,67.44413800000001],[-95.33999599999993,67.49971],[-95.33167999999995,67.505829],[-95.32417299999992,67.51666300000005],[-95.32167099999992,67.52720600000004],[-95.32305899999994,67.53193699999997],[-95.33000199999992,67.54136700000004],[-95.343613,67.55497700000012],[-95.34973100000002,67.559418],[-95.46640000000002,67.63720700000005],[-95.49249299999997,67.64332600000006],[-95.53500399999996,67.64665200000007],[-95.54834,67.64999400000005],[-95.69305400000002,67.70443699999998],[-95.70777900000002,67.72303800000003],[-95.70916699999992,67.72776800000008],[-95.70805399999995,67.73304700000006],[-95.704453,67.73858600000005],[-95.69833399999999,67.74443100000013],[-95.68110699999994,67.7563780000001],[-95.67193600000002,67.76165799999995],[-95.64973399999991,67.76721199999997],[-95.63751199999996,67.76860000000005],[-95.62638899999996,67.771927],[-95.57749899999999,67.7874910000001],[-95.55888399999998,67.79775999999993],[-95.55027799999988,67.80386399999998],[-95.54415899999992,67.809708],[-95.53443900000002,67.820831],[-95.52583300000003,67.836929],[-95.52223199999997,67.85276799999997],[-95.527222,67.87220800000011],[-95.452225,67.98109400000004],[-95.416946,68.02777100000014],[-95.42721599999993,68.032486],[-95.47193900000002,68.05497700000001],[-95.47528099999994,68.0583190000001],[-95.47277799999995,68.06053200000008],[-95.46139499999987,68.06387300000011],[-95.40417500000001,68.06944300000004],[-95.34973100000002,68.074432],[-95.34306300000003,68.074432],[-95.07556199999988,68.06887799999998],[-95.07112099999995,68.06359900000001],[-95.06527699999992,68.06025700000004],[-95.05499299999991,68.055252],[-95.04388399999993,68.05137600000012],[-95.02362099999999,68.04582199999993],[-95.00889599999994,68.04443400000002],[-94.86721799999998,68.03414900000013],[-94.83972199999994,68.03414900000013],[-94.78805499999999,68.04054300000013],[-94.72222899999997,68.05497700000001],[-94.71417200000002,68.05941800000011],[-94.70750399999997,68.06581100000005],[-94.69665499999996,68.07859800000006],[-94.69387799999998,68.08332800000011],[-94.60499599999997,68.13970899999998],[-94.37249799999995,68.22137500000002],[-94.210556,68.26277200000004],[-94.19915799999995,68.26776100000001],[-94.193604,68.27221700000007],[-94.19221499999998,68.27638200000007],[-94.19166599999994,68.28137200000015],[-94.1924899999999,68.29220600000002],[-94.193604,68.29832500000003],[-94.20527599999991,68.31330900000012],[-94.20916699999998,68.32360799999998],[-94.21028099999995,68.32804900000008],[-94.21083099999998,68.36137400000013],[-94.208054,68.36608899999999],[-94.203888,68.37025500000004],[-94.12304699999999,68.41693100000009],[-94.10472099999998,68.42414900000006],[-94.00028999999995,68.46081500000003],[-93.96806300000003,68.46859699999993],[-93.95361300000002,68.47192400000006],[-93.93666100000002,68.47470099999998],[-93.92277499999994,68.47554000000014],[-93.89361599999995,68.47470099999998],[-93.87582399999991,68.47720300000003],[-93.81138599999997,68.48803700000013],[-93.66139199999998,68.52082800000005],[-93.65666199999998,68.52331500000014],[-93.61915599999998,68.54414400000007],[-93.55332900000002,68.58638000000008],[-93.55972299999996,68.61164900000011],[-93.62193300000001,68.62441999999999],[-93.64750700000002,68.62692300000015],[-93.65306099999998,68.62637300000011],[-93.70527600000003,68.65721100000013],[-93.69722000000002,68.74914599999994],[-93.695267,68.75193800000005],[-93.63945000000001,68.78054800000007],[-93.57167099999992,68.83415200000007],[-93.56750499999993,68.83970600000009],[-93.56610099999995,68.849426],[-93.63444499999997,68.95915200000013],[-93.64222699999993,68.96388200000001],[-93.666946,68.97221400000001],[-93.73138399999999,68.9749910000001],[-93.92555199999987,68.97470100000004],[-94.03083800000002,68.9185940000001],[-94.03916900000002,68.91415400000005],[-94.05583200000001,68.9019320000001],[-94.068893,68.89109800000006],[-94.07972699999999,68.84748800000006],[-94.07112099999989,68.84359699999999],[-94.03416400000003,68.83332800000011],[-94.021118,68.83610500000003],[-93.93388400000003,68.855255],[-93.85249299999998,68.87914999999998],[-93.83860799999997,68.885269],[-93.837784,68.88638300000002],[-93.82472200000001,68.89137300000004],[-93.81388900000002,68.89305099999996],[-93.80999799999995,68.89054900000008],[-93.81388900000002,68.88499500000006],[-93.82972699999993,68.87608300000005],[-93.93415799999997,68.82499700000005],[-94.08500699999996,68.76110800000009],[-94.09527600000001,68.75804099999999],[-94.108047,68.75526400000007],[-94.15972899999997,68.74775699999998],[-94.385559,68.72915599999993],[-94.49082899999996,68.72886700000004],[-94.625,68.76138300000014],[-94.60888699999992,68.81944300000004],[-94.58889799999992,68.8413700000001],[-94.58332799999994,68.8458250000001],[-94.57084700000001,68.85026600000003],[-94.56166100000002,68.855255],[-94.556107,68.85998500000005],[-94.55305499999997,68.86442599999992],[-94.54527300000001,68.88472000000007],[-94.54804999999993,68.88888500000007],[-94.55749500000002,68.89305099999996],[-94.56945799999994,68.8936000000001],[-94.577225,68.89665200000002],[-94.585556,68.90304600000007],[-94.58999599999999,68.90832500000005],[-94.60583500000001,68.95109600000006],[-94.604172,68.96192900000005],[-94.59916699999997,68.96554600000002],[-94.587219,68.96887200000003],[-94.55332900000002,68.97387700000007],[-94.37388599999997,69.00305200000014],[-94.22416699999997,69.02777100000014],[-94.16305499999999,69.05220000000008],[-94.15139799999997,69.05720500000012],[-94.07278400000001,69.12664800000005],[-94.07250999999997,69.14498900000007],[-94.1375119999999,69.13192700000002],[-94.22084000000001,69.1202550000001],[-94.23500100000001,69.11943100000013],[-94.24833699999994,69.12052900000003],[-94.31221,69.14498900000007],[-94.32305899999994,69.1499940000001],[-94.32749899999999,69.15525800000006],[-94.3291779999999,69.16137700000013],[-94.30943300000001,69.29414400000013],[-94.30665599999998,69.30026200000009],[-94.30332899999996,69.30497700000012],[-94.291672,69.31387300000006],[-94.28416399999998,69.3188780000001],[-94.25917099999992,69.32666000000006],[-94.16665599999999,69.34248399999996],[-94.04333500000001,69.35748300000006],[-94.02500900000001,69.359711],[-93.95527600000003,69.36276200000003],[-93.73666400000002,69.39999400000005],[-93.62693799999994,69.43247999999994],[-93.57472199999995,69.44165000000004],[-93.56277499999999,69.44274899999999],[-93.52639799999992,69.438309],[-93.53250100000002,69.42997700000001],[-93.54777499999994,69.4205320000001],[-93.67971799999998,69.34776299999993],[-93.69166599999994,69.34275800000006],[-93.741379,69.32443200000006],[-93.75306699999999,69.32054099999999],[-93.76417499999997,69.32054099999999],[-93.82861299999996,69.26554900000008],[-93.85611,69.17692600000004],[-93.85665899999998,69.172211],[-93.84500100000002,69.16499299999998],[-93.83721899999989,69.16442900000004],[-93.63473499999998,69.25166300000012],[-93.46749899999992,69.31749000000002],[-93.45666499999999,69.32304399999998],[-93.36277799999999,69.37164300000012],[-93.36527999999998,69.376083],[-93.37943999999999,69.376373],[-93.45916699999987,69.359711],[-93.47000100000002,69.35664400000007],[-93.47805799999998,69.35331700000012],[-93.49804699999999,69.34915200000012],[-93.51194799999996,69.34942600000005],[-93.56500199999994,69.36775200000005],[-93.56054699999993,69.38388100000003],[-93.53805499999993,69.41053800000009],[-93.527222,69.42164600000007],[-93.51583900000003,69.42553700000013],[-93.50306699999987,69.42747500000007],[-93.48889200000002,69.43498200000005],[-93.43943799999994,69.47526599999998],[-93.44137599999999,69.48054499999995],[-93.48777799999999,69.50277700000004],[-93.50973499999992,69.51304600000009],[-93.53250100000002,69.52110300000004],[-93.54083300000002,69.52331500000008],[-93.587219,69.52804600000002],[-93.62193300000001,69.52720599999998],[-93.68388399999998,69.52221700000001],[-93.70973200000003,69.516098],[-93.80888400000003,69.48887600000006],[-93.86971999999997,69.45166000000012],[-94.04527299999995,69.4391480000001],[-94.27917500000001,69.44026200000008],[-94.29972800000002,69.443039],[-94.31304899999998,69.44664000000006],[-94.34388699999994,69.45915200000007],[-94.45167499999997,69.51860000000005],[-94.50250199999999,69.55636600000003],[-94.59194899999994,69.63720699999999],[-94.62943999999999,69.68304400000005],[-94.67027300000001,69.67747500000007],[-94.712784,69.67164600000001],[-94.749435,69.66360500000013],[-94.75500499999993,69.661652],[-94.76417499999997,69.65498400000007],[-94.76666299999994,69.651093],[-94.76222200000001,69.64471400000014],[-94.74221799999992,69.62831100000005],[-94.72444199999995,69.61442599999998],[-94.72555499999993,69.60859700000015],[-94.73083500000001,69.60276799999997],[-94.74027999999998,69.59748800000006],[-94.76972999999998,69.58305400000006],[-94.8011019999999,69.57221999999996],[-94.82000700000003,69.56721500000009],[-94.83111600000001,69.56581100000011],[-94.84666400000003,69.56553600000012],[-94.86277799999988,69.5669400000001],[-94.95195000000001,69.58442700000012],[-95.01055899999994,69.60304300000013],[-95,69.61886599999997],[-95.00944499999997,69.62164300000006],[-95.021118,69.62164300000006],[-95.07861299999996,69.61637900000011],[-95.16860999999989,69.630539],[-95.396118,69.67886400000003],[-95.40834000000001,69.68193100000013],[-95.42304999999993,69.68609600000013],[-95.54499799999996,69.72692900000004],[-95.648056,69.78027300000002],[-95.71556099999998,69.79136699999992],[-95.72471599999994,69.78997800000013],[-95.7283329999999,69.789154],[-95.73889200000002,69.78610200000003],[-95.75723299999993,69.77720599999992],[-95.75862099999995,69.7727660000001],[-95.86332699999997,69.77221699999996],[-95.96083099999998,69.77804599999996],[-95.97555499999993,69.78193700000003],[-96.02027900000002,69.80442800000003],[-96.03582799999992,69.81387300000011],[-96.07444799999996,69.84193400000004],[-96.087784,69.86914100000013],[-96.08222999999992,69.87359600000013],[-96.08500700000002,69.91137700000013],[-96.097778,69.94663999999995],[-96.116104,69.95387299999999],[-96.17721599999987,69.96470599999992],[-96.19554099999999,69.96554600000002],[-96.19860799999998,69.96499599999999],[-96.20944199999997,69.96165500000012],[-96.21722399999999,69.958328],[-96.22055099999994,69.95748900000001],[-96.23500099999995,69.95748900000001],[-96.24694799999992,69.95887800000003],[-96.25723299999993,69.96304300000003],[-96.27278099999995,69.97109999999998],[-96.38137799999987,70.02748100000008],[-96.40249599999987,70.03997800000008],[-96.45944199999997,70.07554600000009],[-96.50029,70.10137900000001],[-96.50917099999992,70.10859700000003],[-96.52528399999994,70.12275699999998],[-96.531677,70.13108800000003],[-96.55610699999994,70.19192500000008],[-96.56889299999995,70.224426],[-96.57167099999987,70.23442100000005],[-96.57028199999996,70.25109900000012],[-96.56861900000001,70.2686000000001],[-96.56277499999993,70.30026200000003],[-96.55860899999993,70.3119200000001],[-96.55555700000002,70.31749000000013],[-96.54834,70.32887299999999],[-96.53500399999996,70.34414700000008],[-96.29472399999997,70.52249100000012],[-96.23277300000001,70.56219500000003],[-96.07888799999989,70.58749400000005],[-96.06973299999993,70.58776900000004],[-96.04527300000001,70.58415200000007],[-96.04110700000001,70.57693499999999],[-96.03332499999993,70.57276900000011],[-95.99526999999995,70.55970799999994],[-95.93499799999995,70.54748500000011],[-95.92332499999992,70.54525800000005],[-95.806107,70.52886999999998],[-95.79722599999997,70.5294340000001],[-95.78944399999995,70.53665200000012],[-95.791382,70.54275500000006],[-95.79916400000002,70.54914900000011],[-95.85583499999996,70.55331400000011],[-95.9141689999999,70.55941799999994],[-95.93167099999994,70.56219500000003],[-95.96444699999995,70.56887800000004],[-96.000565,70.57998700000007],[-96.04998799999993,70.60026600000003],[-96.058334,70.60582000000005],[-96.06138599999986,70.61720300000002],[-96.05555700000002,70.64305099999996],[-96.04834,70.64694200000002],[-95.95249899999999,70.67970299999996],[-95.848343,70.70694000000009],[-95.81555199999997,70.70915199999996],[-95.81777999999997,70.71026599999993],[-95.901947,70.70776400000005],[-95.93277,70.70109600000006],[-96.11555499999997,70.6560970000001],[-96.13806199999999,70.64637800000008],[-96.14999399999994,70.63720699999999],[-96.15278599999994,70.63247700000011],[-96.15472399999999,70.62469499999997],[-96.153885,70.62164300000006],[-96.158051,70.61747699999995],[-96.16027799999995,70.61637900000005],[-96.16361999999998,70.61554000000012],[-96.202789,70.62164300000006],[-96.37609899999995,70.67303500000003],[-96.38528400000001,70.67776500000002],[-96.39472999999998,70.68359400000003],[-96.40110800000002,70.69053600000012],[-96.41000399999996,70.70248400000003],[-96.41555799999998,70.71527100000003],[-96.42250099999995,70.726089],[-96.43472300000002,70.73719800000003],[-96.44665499999996,70.74192800000009],[-96.53694200000001,70.76332100000002],[-96.58056599999998,70.77748099999991],[-96.60388199999994,70.78804000000014],[-96.61193800000001,70.79443400000002],[-96.61500499999994,70.80442800000003],[-96.61361699999992,70.8211060000001],[-96.601944,70.84999099999999],[-96.59167499999995,70.86692800000014],[-96.57861300000002,70.87803599999995],[-96.571121,70.88304099999999],[-96.5452729999999,70.90498399999996],[-96.53083799999996,70.92137100000014],[-96.52416999999997,70.93165600000003],[-96.51306199999999,70.94970700000005],[-96.51083399999993,70.95582600000006],[-96.50306699999999,70.99693300000007],[-96.49583399999989,71.04026800000008],[-96.48167399999988,71.04332],[-96.45028699999995,71.04498300000012],[-96.414444,71.05358900000004],[-96.40666199999993,71.05859400000008],[-96.36999500000002,71.08998100000002],[-96.37110899999993,71.09304800000012],[-96.37582399999997,71.09803799999997],[-96.40943900000002,71.11943100000008],[-96.41777000000002,71.11360200000007],[-96.42027300000001,71.10720800000001],[-96.41221599999994,71.09582499999999],[-96.41000399999996,71.08970599999998],[-96.41361999999992,71.08415200000002],[-96.421112,71.0816650000001],[-96.44082599999996,71.07916300000005],[-96.46139499999992,71.08055100000013],[-96.47666900000002,71.08526599999999],[-96.50556899999998,71.09721400000001],[-96.53832999999997,71.11303700000002],[-96.55221599999999,71.11998000000006],[-96.56054699999999,71.126373],[-96.55943300000001,71.1308140000001],[-96.553879,71.13693200000006],[-96.54861499999993,71.14054899999996],[-96.46722399999993,71.16526799999997],[-96.45799299999999,71.19556400000005],[-96.46220399999999,71.25550100000004],[-96.50445599999989,71.27609300000012],[-96.50389099999995,71.27720599999998],[-96.48889199999996,71.28610200000008],[-96.27806099999992,71.32638499999996],[-96.24499499999996,71.35386699999992],[-96.21833799999996,71.375809],[-96.193329,71.38998400000008],[-96.16833500000001,71.39999399999999],[-96.13417099999998,71.40971400000006],[-96.04638699999998,71.418045],[-96.02778599999994,71.417755],[-95.92639200000002,71.40054299999997],[-95.89388999999994,71.39082300000007],[-95.88276699999994,71.38415500000008],[-95.87887599999999,71.3785860000001],[-95.87805200000003,71.37303200000008],[-95.87887599999999,71.36720300000007],[-95.85916099999997,71.35498000000001],[-95.83000199999992,71.34304800000007],[-95.79222099999993,71.32804900000002],[-95.67304999999999,71.2874910000001],[-95.65888999999999,71.28553799999997],[-95.55110200000001,71.28997800000002],[-95.535278,71.29081699999995],[-95.45527600000003,71.367752],[-95.45140100000003,71.375809],[-95.547775,71.48776200000003],[-95.77999899999998,71.50387599999999],[-95.83277900000002,71.51582300000013],[-95.9366609999999,71.54664600000012],[-95.94305400000002,71.5535890000001],[-95.90833999999995,71.60054000000014],[-95.89500399999991,71.61053500000003],[-95.88999899999999,71.61331200000012],[-95.87721299999998,71.61831699999999],[-95.86389200000002,71.61943099999996],[-95.81220999999994,71.62191800000005],[-95.74471999999997,71.624146],[-95.678879,71.64637800000008],[-95.53971899999999,71.70359799999994],[-95.39973399999997,71.71859700000005],[-95.30162000000001,71.72109999999998],[-95.28944399999995,71.75360100000012],[-95.28944399999995,71.75749199999996],[-95.28805499999987,71.761932],[-95.28582799999998,71.76721200000009],[-95.239441,71.82249500000006],[-95.226944,71.82666000000006],[-95.073059,71.84137000000004],[-94.890289,71.84471100000007],[-94.85638399999999,71.843323],[-94.83889799999997,71.841095],[-94.79527299999995,71.83332800000005],[-94.74415599999998,71.82304400000004],[-94.73443599999996,71.82331799999997],[-94.71639999999996,71.82609600000012],[-94.65388499999995,71.84526100000011],[-94.612503,71.859711],[-94.60665899999998,71.86331200000006],[-94.60777299999995,71.866379],[-94.61527999999998,71.86886600000008],[-94.62971500000003,71.86692800000014],[-94.65583799999996,71.8619230000001],[-94.70611599999995,71.84803800000003],[-94.74305699999996,71.8394320000001],[-94.75695799999994,71.83749399999994],[-94.77528399999994,71.83888200000007],[-94.78306600000002,71.84137000000004],[-94.82611099999997,71.847488],[-94.85360700000001,71.84942600000011],[-94.903885,71.85026600000015],[-95.10249299999998,71.851089],[-95.11915599999998,71.85026600000015],[-95.15722700000003,71.84582500000005],[-95.17999299999997,71.84304800000012],[-95.18055700000002,71.84220899999997],[-95.19248999999996,71.84137000000004],[-95.21333300000003,71.84304800000012],[-95.23111,71.849152],[-95.24082900000002,71.85386700000004],[-95.25167799999997,71.86053499999997],[-95.25666799999993,71.86692800000014],[-95.25500499999998,71.89553799999999],[-95.222778,71.94220000000007],[-95.21749899999986,71.944977],[-95.20140099999998,71.94720500000011],[-94.97193900000002,71.97581499999995],[-94.741104,71.99192800000003],[-94.69804399999998,71.99359099999992],[-94.66166699999997,71.99498000000011],[-94.57972699999999,71.99693300000007],[-94.56361400000003,71.99693300000007],[-94.53028899999998,71.99443100000002],[-94.499435,71.98803700000013],[-94.487213,71.9833220000001],[-94.39361599999995,71.938309],[-94.38722200000001,71.93386800000007],[-94.38861099999991,71.92414900000011],[-94.460556,71.84942600000011],[-94.47222899999997,71.84721400000006],[-94.50666799999999,71.84776299999999],[-94.521118,71.84999099999993],[-94.539444,71.85137900000007],[-94.56249999999994,71.84999099999993],[-94.57444800000002,71.84693900000002],[-94.64416499999993,71.818329],[-94.61860699999994,71.75332600000007],[-94.61193799999995,71.74971000000005],[-94.5997309999999,71.74470499999995],[-94.59416199999998,71.74331700000005],[-94.56945799999994,71.74498],[-94.5558319999999,71.75000000000006],[-94.53860499999996,71.75833100000011],[-94.53639199999998,71.76110800000004],[-94.52860999999996,71.77137800000014],[-94.51972999999992,71.78915400000011],[-94.49749800000001,71.818329],[-94.48832699999997,71.82415800000001],[-94.48472600000002,71.82470699999993],[-94.39222699999999,71.81442300000009],[-94.366104,71.80247500000007],[-94.35665899999987,71.79637100000002],[-94.35472099999998,71.79247999999995],[-94.38999899999999,71.71775800000006],[-94.41944899999999,71.66720599999996],[-94.42388900000003,71.66137700000013],[-94.41833500000001,71.65998799999994],[-94.40695199999999,71.66081200000013],[-94.36888099999999,71.67526200000003],[-94.26722699999999,71.73082000000005],[-94.258896,71.74192800000009],[-94.25584399999997,71.7538760000001],[-94.24276699999996,71.77082800000011],[-94.22805800000003,71.78166199999998],[-94.20722999999992,71.78942899999993],[-94.19444299999992,71.79193100000003],[-94.181671,71.79193100000003],[-94.03694199999995,71.78720099999998],[-94.02362099999999,71.78581200000002],[-94.01472499999988,71.78109699999999],[-94.00834700000001,71.77499399999999],[-94.006393,71.76332100000002],[-93.99388099999999,71.75305200000014],[-93.97250399999996,71.74581899999998],[-93.94249000000002,71.74359099999998],[-93.90972899999991,71.74498],[-93.88806199999999,71.74832200000009],[-93.87138399999998,71.75305200000014],[-93.850281,71.76332100000002],[-93.83084100000002,71.77165200000007],[-93.81889299999989,71.77470399999999],[-93.80221599999999,71.77554299999997],[-93.78416400000003,71.77415500000006],[-93.74194299999999,71.76915000000002],[-93.72666900000002,71.76638800000012],[-93.71166999999997,71.76138300000002],[-93.70722999999992,71.75499000000008],[-93.69415300000003,71.71609500000011],[-93.69665500000002,71.71081500000008],[-93.70445299999994,71.70526100000006],[-93.73777799999999,71.68942300000003],[-93.764725,71.67970300000013],[-93.81111099999993,71.65748600000006],[-93.81861899999996,71.6519320000001],[-93.81138599999997,71.64553800000004],[-93.79722600000002,71.6394350000001],[-93.6583399999999,71.58194000000003],[-93.61805700000002,71.56860400000005],[-93.589447,71.56137100000007],[-93.51306199999988,71.54470799999996],[-93.4949949999999,71.54165600000005],[-93.476944,71.54026799999997],[-93.42832899999996,71.53414900000013],[-93.412216,71.53082300000005],[-93.23083500000001,71.47360200000014],[-93.21417199999996,71.46720900000014],[-93.20140100000003,71.46138000000013],[-93.18638599999997,71.43580600000013],[-93.18638599999997,71.43026700000013],[-93.18998699999986,71.42387400000001],[-93.19387799999993,71.41943399999997],[-93.19554099999993,71.41360500000013],[-93.19055199999997,71.4080350000001],[-93.18055699999996,71.401093],[-93.14250199999998,71.37498500000004],[-93.12887599999999,71.36886600000003],[-93.101944,71.36747700000001],[-93.06277499999999,71.36943100000002],[-93.04527299999995,71.367752],[-93.02917500000001,71.36442599999998],[-92.99722299999996,71.35386699999992],[-92.98582499999986,71.34887700000007],[-92.97721899999993,71.34387200000003],[-92.97389199999998,71.34082000000012],[-92.94193999999993,71.28887900000001],[-92.93859900000001,71.27053800000004],[-92.93611099999993,71.24748199999999],[-92.93194599999993,71.22053500000004],[-92.93083199999995,71.2144320000001],[-92.92388900000003,71.20776399999994],[-92.854446,71.15138200000013],[-92.86277799999999,71.13943499999999],[-92.86915599999998,71.12803600000012],[-92.88861099999997,71.0747070000001],[-92.88999899999993,71.065811],[-92.90695199999993,70.9124910000001],[-93.03083800000002,70.87886000000009],[-93.04083300000002,70.87776200000002],[-93.04834,70.87387099999995],[-93.04611199999994,70.86720300000002],[-93.0427699999999,70.86387600000006],[-93.02749599999999,70.85276800000008],[-92.98249800000002,70.82554600000014],[-92.958618,70.81749000000008],[-92.92832899999996,70.81137100000001],[-92.91139199999998,70.80998200000005],[-92.81304899999998,70.80581700000005],[-92.68859899999995,70.77554299999997],[-92.67666600000001,70.77165200000007],[-92.64111299999996,70.71527100000003],[-92.63944999999995,70.70999100000012],[-92.64250199999998,70.7063750000001],[-92.62193300000001,70.68359400000003],[-92.59277299999997,70.68580600000013],[-92.43055700000002,70.66609199999999],[-92.41805999999997,70.66304000000008],[-92.20805399999995,70.61026000000004],[-92.19915800000001,70.60664400000002],[-92.16915899999998,70.59027100000014],[-92.15916399999998,70.58415200000007],[-92.15750100000002,70.57916300000011],[-92.15666199999998,70.5730440000001],[-92.16833500000001,70.56999200000001],[-92.19610599999999,70.57110599999999],[-92.22860700000001,70.57360800000004],[-92.245544,70.57138099999997],[-92.25,70.56971699999997],[-92.26501499999989,70.55192600000004],[-92.26501499999989,70.54803500000014],[-92.25,70.50138900000013],[-92.23805199999998,70.48719800000009],[-92.11665299999999,70.47082500000005],[-92.1100009999999,70.468323],[-91.99694799999997,70.39082300000007],[-91.98777799999999,70.35582000000011],[-91.99249299999997,70.32054099999999],[-91.99526999999995,70.316666],[-91.98554999999993,70.28970300000003],[-91.95973200000003,70.2586060000001],[-91.952225,70.25526400000012],[-91.94694500000003,70.25804100000005],[-91.94221499999998,70.26361099999997],[-91.92027300000001,70.29637099999997],[-91.900284,70.33082600000012],[-91.90361000000001,70.33720400000004],[-91.904449,70.34332300000011],[-91.89805599999994,70.34915200000012],[-91.890289,70.35443100000009],[-91.87805200000003,70.35832199999999],[-91.86749299999997,70.3602600000001],[-91.85305800000003,70.36137400000007],[-91.73721299999994,70.35859699999997],[-91.72972099999998,70.35693400000008],[-91.70388799999995,70.34526100000005],[-91.69888300000002,70.34248400000013],[-91.69387799999987,70.33638000000008],[-91.63612399999994,70.23165899999998],[-91.56527699999992,70.20054600000014],[-91.52416999999991,70.17915300000004],[-91.51362599999993,70.16720600000008],[-91.51194800000002,70.15887500000002],[-91.51139799999999,70.15277100000014],[-91.516953,70.14637800000003],[-91.52917499999995,70.14248700000013],[-91.54249599999991,70.14082300000013],[-91.57806399999993,70.13749700000011],[-91.91665599999999,70.11998000000006],[-91.95333900000003,70.1183170000001],[-91.97222899999991,70.11859100000004],[-92.00389099999995,70.12136800000013],[-92.02139299999999,70.12359600000008],[-92.03611799999993,70.12692300000003],[-92.04943800000001,70.132202],[-92.05749499999996,70.13693200000006],[-92.23443600000002,70.21220399999999],[-92.26834100000002,70.20887800000014],[-92.39306599999998,70.15054300000003],[-92.450287,70.0711060000001],[-92.43222000000003,70.07554600000009],[-92.285278,70.08970600000004],[-92.26834100000002,70.09054600000007],[-92.17748999999998,70.08831800000007],[-92.12999000000002,70.084991],[-92.0875089999999,70.07971199999997],[-92.02639799999997,70.06637600000005],[-91.99305699999996,70.05859400000008],[-91.98527499999994,70.05386400000003],[-91.93971299999998,70.020264],[-91.94665499999991,70.01582300000007],[-92.114441,69.95637500000004],[-92.14889499999992,69.94663999999995],[-92.20388799999995,69.92053199999998],[-92.36944599999998,69.84776300000004],[-92.54333500000001,69.78054800000007],[-92.658615,69.76110800000009],[-92.77861000000001,69.72221400000001],[-92.775284,69.7063750000001],[-92.56555200000003,69.71276899999998],[-92.55139200000002,69.7124940000001],[-92.53500400000001,69.709427],[-92.53527799999995,69.70526100000012],[-92.70973200000003,69.67387400000001],[-92.728882,69.67164600000001],[-92.74380500000001,69.67195100000004],[-92.77722199999994,69.67608600000005],[-92.858047,69.6827550000001],[-92.87138400000003,69.68248000000011],[-92.90888999999999,69.68054199999995],[-92.92277499999989,69.67942799999997],[-92.92361499999993,69.678314],[-92.92027300000001,69.66970800000007],[-92.89750699999996,69.66554300000007],[-92.83612099999999,69.655823],[-92.82749899999999,69.655823],[-92.69444299999998,69.65637200000015],[-92.634727,69.67108899999994],[-92.62937899999997,69.6735920000001],[-92.619057,69.67575800000009],[-92.5625,69.68748499999998],[-92.52362099999993,69.6927490000001],[-92.50695799999994,69.69358800000009],[-92.34083599999997,69.69413800000012],[-92.3058319999999,69.665817],[-92.20527600000003,69.6455380000001],[-92.09111000000001,69.62469500000003],[-92.08833300000003,69.62303200000008],[-92.08860799999997,69.61886599999997],[-92.09083599999991,69.6160890000001],[-92.11054999999993,69.61303699999996],[-92.122772,69.61219800000003],[-92.13417099999998,69.61248800000004],[-92.24360699999988,69.63026400000001],[-92.28195199999999,69.63998400000008],[-92.29110700000001,69.6413730000001],[-92.30055199999993,69.64166300000011],[-92.29750100000001,69.636932],[-92.12470999999994,69.55497700000006],[-92.08416699999998,69.54470800000001],[-91.93832399999991,69.51776100000012],[-91.80332900000002,69.49887099999995],[-91.80416899999989,69.50499000000002],[-91.79833999999994,69.51388500000002],[-91.49749800000001,69.65860000000009],[-91.48500100000001,69.66331500000013],[-91.47528099999994,69.6644290000001],[-91.45083599999998,69.65887499999991],[-91.41888399999993,69.65554800000001],[-91.31416300000001,69.65277100000009],[-91.221115,69.65332000000001],[-91.20222499999994,69.655258],[-91.18859900000001,69.65387000000004],[-91.09777799999995,69.63832100000013],[-91.09416199999998,69.63610800000004],[-91.091949,69.63165299999997],[-91.09527599999996,69.62664799999993],[-91.10194399999995,69.6208190000001],[-91.10583500000001,69.61914100000001],[-91.33444199999997,69.55276500000002],[-91.36082499999992,69.54553199999998],[-91.38055400000002,69.54248000000007],[-91.396118,69.54109199999999],[-91.460556,69.53970300000015],[-91.49472000000003,69.5372010000001],[-91.51445000000001,69.53414899999996],[-91.56277499999993,69.52249100000012],[-91.57028199999996,69.52026400000005],[-91.56639100000001,69.51470899999998],[-91.55777,69.50804100000005],[-91.553879,69.50555400000013],[-91.40222199999994,69.52221700000001],[-91.333618,69.53498800000011],[-91.32167099999992,69.53887900000001],[-91.19221500000003,69.56275900000003],[-91.17971799999998,69.55886800000013],[-91.16027799999989,69.54609700000003],[-91.15055799999999,69.5372010000001],[-91.14666699999992,69.5316620000001],[-91.14361600000001,69.52526899999992],[-91.13861099999986,69.51915000000008],[-91.12832600000002,69.51416000000006],[-91.11416600000001,69.51081799999992],[-91.10278299999999,69.50888100000009],[-90.96972700000003,69.51138300000014],[-90.83000199999992,69.484985],[-90.75862099999995,69.4827580000001],[-90.75195300000001,69.48719800000015],[-90.75140399999987,69.49275200000011],[-90.75805700000001,69.50138900000013],[-90.75584399999997,69.50721700000008],[-90.75418100000002,69.50915500000002],[-90.71610999999996,69.53942900000004],[-90.69860799999992,69.53942900000004],[-90.65110800000002,69.534424],[-90.53666699999991,69.51388500000002],[-90.49333200000001,69.50416600000005],[-90.43666100000002,69.48970000000003],[-90.31861900000001,69.45443700000004],[-90.30776999999995,69.45027200000004],[-90.30776999999995,69.44720500000011],[-90.319458,69.44053600000001],[-90.34445199999999,69.43220500000012],[-90.35804699999994,69.42970300000007],[-90.39639299999988,69.4285890000001],[-90.41139199999992,69.43136599999997],[-90.42748999999998,69.44081100000005],[-90.43360899999999,69.44497699999994],[-90.43832399999997,69.44802900000008],[-90.45056199999999,69.45027200000004],[-90.46333299999992,69.44859300000002],[-90.49333200000001,69.44081100000005],[-90.55555699999996,69.42248500000005],[-90.61389199999991,69.451096],[-90.62193299999996,69.45332300000001],[-90.70361299999996,69.45359800000006],[-90.704453,69.45138500000007],[-90.69860799999992,69.44609100000014],[-90.63694800000002,69.42970300000007],[-90.58583099999998,69.41914400000002],[-90.58222999999992,69.41693100000003],[-90.58473200000003,69.41415399999994],[-90.60082999999997,69.40859999999998],[-90.69499199999996,69.3897090000001],[-90.70527599999997,69.3877720000001],[-90.718613,69.3877720000001],[-90.74137899999994,69.38275099999993],[-90.79028299999999,69.36276200000003],[-90.80943299999996,69.34220900000014],[-90.81304899999992,69.33831800000007],[-90.81582600000002,69.333328],[-90.81861900000001,69.29859899999997],[-90.81500199999999,69.29332],[-90.80860899999999,69.28749099999999],[-90.80555700000002,69.28276100000011],[-90.803879,69.25972000000007],[-90.80471799999992,69.255829],[-90.80943299999996,69.25332600000002],[-90.82223499999998,69.25166300000012],[-90.903885,69.24636800000007],[-90.920837,69.24636800000007],[-90.93138099999993,69.24748200000005],[-91.08111599999995,69.26693699999998],[-91.21472199999994,69.29026800000008],[-91.29638699999992,69.3119200000001],[-91.34527600000001,69.32804900000002],[-91.35583499999996,69.33221400000002],[-91.42639199999996,69.35054000000002],[-91.43859900000001,69.35276800000003],[-91.44722000000002,69.35276800000003],[-91.44665500000002,69.34971600000006],[-91.43194599999998,69.33859300000006],[-91.33528100000001,69.30442800000014],[-91.13055399999996,69.24192800000003],[-91.03138699999994,69.21832300000005],[-90.91888399999993,69.16081200000008],[-90.89500399999997,69.15081800000007],[-90.81500199999999,69.13360600000004],[-90.66471899999999,69.08332800000005],[-90.65499899999992,69.07804900000008],[-90.65417499999995,69.07609599999995],[-90.654449,69.07054100000005],[-90.660553,69.05998200000005],[-90.66944899999993,69.04998799999998],[-90.58389299999999,68.92886400000003],[-90.54499800000002,68.91110200000014],[-90.52888499999995,68.90860000000009],[-90.47444200000001,68.89054900000008],[-90.43638599999991,68.87441999999999],[-90.41944899999999,68.84082000000006],[-90.44610599999999,68.77970900000014],[-90.44915800000001,68.77609300000006],[-90.45417799999996,68.77360500000009],[-90.464722,68.770828],[-90.47833299999996,68.76832600000012],[-90.49249299999997,68.76776100000006],[-90.49749800000001,68.76832600000012],[-90.50111399999997,68.770828],[-90.51390099999998,68.75915500000013],[-90.52667200000002,68.74443100000013],[-90.52778599999999,68.736649],[-90.52250700000002,68.72998000000007],[-90.506958,68.72499099999993],[-90.48028599999992,68.70776400000011],[-90.479172,68.705826],[-90.47444200000001,68.53082299999994],[-90.50973499999998,68.49525499999993],[-90.519455,68.48748799999998],[-90.52833599999991,68.4833220000001],[-90.55777,68.47470099999998],[-90.58473200000003,68.46554600000013],[-90.603882,68.45582600000006],[-90.60777299999995,68.451096],[-90.60665899999998,68.44609100000014],[-90.603882,68.43969700000008],[-90.60139500000002,68.43637100000007],[-90.55999799999995,68.42359900000002],[-90.52389499999998,68.41442899999998],[-90.46694899999989,68.40386999999998],[-90.36193800000001,68.38415500000013],[-90.33277900000002,68.37803600000012],[-90.31750499999998,68.37330600000007],[-90.31500199999999,68.36998000000006],[-90.31916799999999,68.3683170000001],[-90.34388699999994,68.36526500000002],[-90.36749299999991,68.34526100000011],[-90.27139299999999,68.23887600000012],[-90.25500499999993,68.23275799999999],[-90.23277299999995,68.23027000000002],[-90.20722999999992,68.23109399999998],[-90.178604,68.23580900000002],[-90.144455,68.24386600000003],[-90.13221699999991,68.24859600000002],[-90.12277199999994,68.25360100000006],[-90.11972000000003,68.25721699999997],[-90.11805700000002,68.26220699999999],[-90.03860499999996,68.35220299999997],[-89.985275,68.39610299999998],[-89.912216,68.46720900000003],[-89.89306599999992,68.54331999999994],[-89.91166699999997,68.54748499999994],[-89.91999800000002,68.55358899999999],[-89.92777999999998,68.56359900000007],[-89.94860799999998,68.59942600000005],[-89.95056199999999,68.60386699999998],[-89.94972199999995,68.60775800000005],[-89.89472999999987,68.65248100000008],[-89.80972300000002,68.71026599999999],[-89.80248999999992,68.71220399999993],[-89.78916899999996,68.71026599999999],[-89.78056300000003,68.705826],[-89.76333599999992,68.69053600000001],[-89.75750700000003,68.68470800000006],[-89.74694799999997,68.66970800000013],[-89.729172,68.69914200000011],[-89.69332899999995,68.76388500000002],[-89.68472300000002,68.81025700000009],[-89.68749999999994,68.81971699999997],[-89.68998699999992,68.82470700000005],[-89.714722,68.84693900000008],[-89.73388699999992,68.88165300000014],[-89.73916600000001,68.89276100000012],[-89.75695799999988,68.93997200000001],[-89.75556899999998,68.954163],[-89.75306699999999,68.958328],[-89.71665999999999,69.00610400000011],[-89.70722999999992,69.0147090000001],[-89.70056199999999,69.01915000000002],[-89.68443300000001,69.0288700000001],[-89.66610700000001,69.03831500000001],[-89.64416499999999,69.04832500000009],[-89.58277900000002,69.06860400000005],[-89.56082200000003,69.07720900000004],[-89.52935799999995,69.09060699999998],[-89.48999000000003,69.11053500000003],[-89.48249799999991,69.11554000000007],[-89.458618,69.13360600000004],[-89.402222,69.17886399999998],[-89.39862099999993,69.18248],[-89.39445499999994,69.19303900000006],[-89.39445499999994,69.199142],[-89.39695699999993,69.20860299999998],[-89.39445499999994,69.21443199999999],[-89.38999899999993,69.21914700000002],[-89.32223499999992,69.24720800000011],[-89.30665599999992,69.25138900000002],[-89.258621,69.25999500000012],[-89.220551,69.26666300000005],[-89.17416400000002,69.27331500000014],[-89.13417099999998,69.27554299999991],[-89.11444099999989,69.27526899999998],[-89.09056099999998,69.27192700000006],[-89.04998799999998,69.2644350000001],[-89.03805499999987,69.26193199999994],[-88.999435,69.25138900000002],[-88.96888699999994,69.24136400000009],[-88.94248999999996,69.22998000000001],[-88.93804899999998,69.22692899999998],[-88.93554699999999,69.22221400000012],[-88.93472300000002,69.219986],[-88.9375,69.21415699999994],[-88.93666099999996,69.20915200000007],[-88.92999299999997,69.19802900000013],[-88.87026999999995,69.14860500000009],[-88.85943599999996,69.14221199999997],[-88.78250100000002,69.10304300000007],[-88.77250700000002,69.09887699999996],[-88.62388599999997,69.042755],[-88.48028599999998,68.99887100000007],[-88.45722999999992,68.99275200000005],[-88.406113,68.98275800000005],[-88.27084400000001,68.93498199999993],[-88.208618,68.911652],[-88.197769,68.90664700000013],[-88.11582900000002,68.86053500000008],[-88.08222999999998,68.8413700000001],[-88.05221599999999,68.8230440000001],[-88.03832999999997,68.81414799999999],[-87.97166400000003,68.76609799999994],[-87.96444699999995,68.76054399999998],[-87.947769,68.73165900000009],[-87.92166099999992,68.67303500000003],[-87.91665599999999,68.65637200000015],[-87.91749600000003,68.64749100000006],[-87.92500299999995,68.632477],[-87.93499799999995,68.61943100000002],[-87.9424899999999,68.61080900000002],[-87.947769,68.60525500000006],[-87.93388399999998,68.57693500000005],[-87.9241639999999,68.559708],[-87.883621,68.49443099999996],[-87.88137799999998,68.49108900000004],[-87.84167500000001,68.43248],[-87.835556,68.42442299999999],[-87.81750499999993,68.41720600000008],[-87.79861499999998,68.40525800000006],[-87.791672,68.39833099999998],[-87.78971899999993,68.3919370000001],[-87.789444,68.38665800000012],[-87.79222099999993,68.334427],[-87.80055199999993,68.3119200000001],[-87.84527600000001,68.24775700000009],[-87.84889199999986,68.24414100000001],[-87.92916899999994,68.197205],[-87.93582200000003,68.19581599999998],[-87.94694500000003,68.19859300000007],[-88.10665899999987,68.242752],[-88.22193900000002,68.36554000000001],[-88.38444500000003,68.29109200000005],[-88.39222699999999,68.28749099999999],[-88.39555399999995,68.28526300000004],[-88.40167199999996,68.28027299999997],[-88.40333599999991,68.27554299999997],[-88.40278599999988,68.270264],[-88.39834599999995,68.2605440000001],[-88.380829,68.24552900000009],[-88.36193799999995,68.23387100000008],[-88.34249899999998,68.22360200000003],[-88.33473200000003,68.21748400000013],[-88.33084100000002,68.21304300000003],[-88.27972399999993,68.11804199999995],[-88.27749599999999,68.111649],[-88.27778599999999,68.105545],[-88.28306599999996,68.09999099999999],[-88.31555199999997,68.08610499999998],[-88.33168,68.07638500000007],[-88.33833299999998,68.0705410000001],[-88.3411099999999,68.06498700000009],[-88.34777799999995,68.03720100000004],[-88.36694299999999,68.03166200000004],[-88.381104,68.0252690000001],[-88.37277199999994,67.96887200000009],[-88.370834,67.95915200000002],[-88.36860699999994,67.95443699999998],[-88.285278,67.81721500000009],[-88.27639799999997,67.80304000000001],[-88.26916499999999,67.79359400000004],[-88.160553,67.68247999999994],[-88.15110799999991,67.67330900000002],[-88.13944999999995,67.66442899999998],[-88.12499999999994,67.65554800000001],[-88.09583999999995,67.64248700000007],[-88.06610099999995,67.63472000000013],[-88.00917099999992,67.62275700000009],[-87.97999600000003,67.61581400000011],[-87.96528599999999,67.61164900000011],[-87.95584100000002,67.607483],[-87.88137799999998,67.56805400000013],[-87.841385,67.53610200000014],[-87.827225,67.52720600000004],[-87.78916900000002,67.50526399999995],[-87.62304699999993,67.4124910000001],[-87.60638399999993,67.40386999999998],[-87.58500700000002,67.39526400000005],[-87.53694200000001,67.37886000000009],[-87.46083099999998,67.34414700000013],[-87.35777300000001,67.26220700000005],[-87.35916099999997,67.24748200000005],[-87.36193800000001,67.24220300000007],[-87.42916899999994,67.20860300000004],[-87.44055199999997,67.20498700000013],[-87.48666400000002,67.19413800000007],[-87.49777199999994,67.19053600000012],[-87.50556899999998,67.18525699999998],[-87.51139799999999,67.1749880000001],[-87.51194800000002,67.16998300000006],[-87.516953,67.11554000000012],[-87.51028400000001,67.11219800000015],[-87.49749800000001,67.11526500000008],[-87.32278400000001,67.16276600000015],[-87.2408289999999,67.21609499999994],[-87.11776699999996,67.2127690000001],[-87.06973299999993,67.21943700000008],[-86.96861299999995,67.24525500000004],[-86.96305799999999,67.25054899999998],[-86.96749899999998,67.25526400000001],[-87.00889599999994,67.28221100000013],[-87.07556199999993,67.32720900000004],[-87.08667000000003,67.33637999999996],[-87.09056099999992,67.34582500000005],[-87.08999599999999,67.35081500000013],[-87.08139,67.35443099999998],[-86.874435,67.40498400000013],[-86.804169,67.42082199999999],[-86.79222099999987,67.42248500000011],[-86.77917500000001,67.422211],[-86.76528899999994,67.41914400000007],[-86.70973199999997,67.38804600000003],[-86.68916300000001,67.3744200000001],[-86.68472300000002,67.36998000000006],[-86.67555199999998,67.36554000000007],[-86.64723200000003,67.35832200000004],[-86.59249899999998,67.34526100000011],[-86.57972699999999,67.34498600000006],[-86.54388399999993,67.34498600000006],[-86.53195199999999,67.34664900000001],[-86.52362099999999,67.35220300000003],[-86.51806599999998,67.35720800000007],[-86.50917099999998,67.36775200000011],[-86.50306699999993,67.37776200000002],[-86.47389199999998,67.46859699999999],[-86.47277799999989,67.47859200000005],[-86.47444200000001,67.4833220000001],[-86.49499499999996,67.49693300000007],[-86.48500100000001,67.51693699999998],[-86.452225,67.59248400000013],[-86.45140100000003,67.59748800000011],[-86.45584099999996,67.60192900000004],[-86.46528599999994,67.60636900000003],[-86.47972099999998,67.61053500000014],[-86.48889200000002,67.61469999999997],[-86.52139299999993,67.67192100000011],[-86.525284,67.68136600000014],[-86.5080569999999,67.69720500000011],[-86.35916099999992,67.82777399999998],[-86.35055499999999,67.83332799999994],[-86.2869419999999,67.86997999999994],[-86.098053,67.97804300000001],[-86.04138199999994,68.00054900000003],[-86.02972399999993,68.00499000000013],[-86.00500499999998,68.008331],[-85.99221799999998,68.00915500000013],[-85.97999599999991,68.01165800000012],[-85.898346,68.04609700000015],[-85.89250199999998,68.05137600000012],[-85.89083899999997,68.06137100000007],[-85.91250600000001,68.08471700000007],[-85.91639699999996,68.09414700000013],[-85.91444399999995,68.10415599999999],[-85.88806199999999,68.18969700000014],[-85.84277299999997,68.31721499999998],[-85.83917200000002,68.32138100000009],[-85.71278399999994,68.41165200000012],[-85.72694399999995,68.48637400000001],[-85.73332199999999,68.59860200000008],[-85.67527799999999,68.71110499999998],[-85.66361999999992,68.7269290000001],[-85.64584399999995,68.7374880000001],[-85.63389599999994,68.74192800000014],[-85.62026999999995,68.7416530000001],[-85.60638399999999,68.74026500000002],[-85.59167500000001,68.73719800000009],[-85.56945799999994,68.728317],[-85.55804399999994,68.726089],[-85.49444599999993,68.7369230000001],[-85.48194899999993,68.73942600000004],[-85.46617100000003,68.74999200000013],[-85.46416499999992,68.75299100000012],[-85.46472199999994,68.75972000000002],[-85.50778199999996,68.766663],[-85.55082700000003,68.77331500000008],[-85.56277499999999,68.776657],[-85.55360399999995,68.78109700000005],[-85.54083300000002,68.78276100000005],[-85.51417500000002,68.78387500000002],[-85.45805399999995,68.77777099999997],[-85.415009,68.770828],[-85.37138399999998,68.7622070000001],[-85.36166400000002,68.75776700000006],[-85.36805699999996,68.75248699999997],[-85.37943999999999,68.747208],[-85.38833599999998,68.74192800000014],[-85.38417099999998,68.73719800000009],[-85.32861299999996,68.72499099999993],[-85.31416299999995,68.72276299999999],[-85.228882,68.71026599999999],[-85.21583599999997,68.71081500000014],[-85.20916699999998,68.71499600000004],[-85.21083099999998,68.71971100000007],[-85.21945199999999,68.72915599999993],[-85.22666900000002,68.73359700000003],[-85.14834599999995,68.75000000000011],[-85.06750499999993,68.7497100000001],[-84.91278099999994,68.74693300000001],[-84.898056,68.74247700000006],[-84.883896,68.74026500000002],[-84.80110200000001,68.73414600000001],[-84.78721599999994,68.73359700000003],[-84.775284,68.73719800000009],[-84.76750199999992,68.747208],[-84.76000999999991,68.75721700000003],[-84.752792,68.76748700000013],[-84.7541809999999,68.77221700000001],[-84.761124,68.77693200000004],[-84.83473200000003,68.8205410000001],[-84.84666400000003,68.82388300000008],[-84.86082499999998,68.82527200000004],[-84.89999399999994,68.8205410000001],[-84.912216,68.81805400000002],[-84.976944,68.80941800000011],[-85.00361599999991,68.80831899999998],[-85.031677,68.81080600000001],[-85.13194299999992,68.82693499999999],[-85.14388999999994,68.83027600000003],[-85.16305499999993,68.83915700000011],[-85.17721599999993,68.8483280000001],[-85.18415800000002,68.85304300000013],[-85.19276400000001,68.86219800000015],[-85.19444299999986,68.86720300000002],[-85.19082600000002,68.87220800000006],[-85.17777999999998,68.87359600000002],[-85.15306099999998,68.87303200000002],[-85.125,68.87025499999999],[-85.05332900000002,68.85887100000002],[-85.03999299999998,68.85942100000005],[-85.00556899999992,68.87747200000007],[-85.00195299999996,68.88247700000011],[-84.99749799999995,68.92581200000006],[-85.00723299999987,68.93026700000013],[-85.02111799999994,68.93165600000009],[-85.04666099999997,68.92665100000005],[-85.05999800000001,68.92581200000006],[-85.08805799999999,68.92858899999999],[-85.11694299999994,68.93331900000004],[-85.12943999999993,68.9374850000001],[-85.136124,68.94220000000013],[-85.14056399999993,68.94664],[-85.13694799999996,68.95193500000005],[-85.12777699999992,68.95610000000005],[-85.115005,68.95860300000004],[-85.08750899999995,68.95803799999999],[-84.97378500000002,68.9468690000001],[-84.91471899999999,68.93803400000007],[-84.818893,68.92776500000002],[-84.80583199999995,68.92915299999993],[-84.79638699999998,68.93359400000003],[-84.79138199999994,68.94331399999993],[-84.79333499999996,68.94831800000009],[-84.79998799999987,68.95277400000003],[-84.80943300000001,68.95721400000002],[-84.82194500000003,68.96165500000012],[-84.837219,68.96582000000012],[-84.85139499999997,68.96832300000011],[-84.86555499999992,68.96971100000002],[-84.90695199999993,68.97164900000013],[-84.92138699999998,68.97387700000007],[-84.93611099999993,68.97720300000015],[-84.98692299999993,68.99951199999998],[-84.98167399999994,69.00749200000001],[-84.95777900000002,69.01748700000007],[-84.94444299999998,69.01805100000001],[-84.83639499999992,69.01277200000004],[-84.72000099999997,69.00694300000004],[-84.59167499999995,68.99443100000008],[-84.57806399999998,68.99386600000003],[-84.56555200000003,68.9974820000001],[-84.541382,69.00721699999997],[-84.53222700000003,69.01249700000005],[-84.52833599999997,69.01748700000007],[-84.53527799999995,69.02221700000013],[-84.56361399999997,69.02581800000002],[-84.745544,69.03970300000009],[-84.95388799999995,69.08581500000014],[-85.108337,69.11331200000012],[-85.020554,69.16026299999993],[-85.00695799999994,69.16081200000008],[-84.99415599999992,69.16331500000007],[-84.98750299999995,69.16859400000004],[-84.99471999999997,69.17303500000014],[-85.008896,69.17442300000005],[-85.06471299999993,69.17692600000004],[-85.14377599999995,69.16709100000003],[-85.15177899999998,69.16609199999994],[-85.159111,69.16410100000007],[-85.163277,69.16159800000008],[-85.15527299999997,69.15310700000009],[-85.1766659999999,69.14360000000005],[-85.19749499999995,69.13275099999998],[-85.210556,69.13026400000012],[-85.22361799999999,69.12886000000009],[-85.23693799999995,69.12803600000012],[-85.25140399999998,69.13026400000012],[-85.266663,69.13360600000004],[-85.308334,69.14360000000005],[-85.31555200000003,69.14804100000015],[-85.31750499999998,69.15277100000003],[-85.308044,69.15803499999998],[-85.29611199999988,69.1624910000001],[-85.28332499999988,69.16526799999997],[-85.23500100000001,69.17469800000003],[-85.22750100000002,69.176872],[-85.22683699999999,69.17987099999999],[-85.23116299999998,69.18254100000007],[-85.24082900000002,69.192474],[-85.25473,69.19274900000005],[-85.337784,69.19386300000002],[-85.38305700000001,69.20555100000007],[-85.39277600000003,69.20999100000006],[-85.47332799999992,69.27192700000006],[-85.47778299999987,69.27638200000007],[-85.50306699999993,69.31442300000009],[-85.50805700000001,69.395264],[-85.506958,69.40026900000004],[-85.50334199999998,69.405258],[-85.49415599999992,69.41081200000002],[-85.48194899999993,69.41526799999997],[-85.46749899999992,69.41720600000008],[-85.45333900000003,69.41693100000003],[-85.42443799999995,69.41331500000001],[-85.39611799999994,69.41165200000006],[-85.38333099999994,69.41526799999997],[-85.33917200000002,69.43887300000011],[-85.343613,69.44358799999998],[-85.35360699999995,69.44802900000008],[-85.37887599999993,69.45664999999997],[-85.39416499999993,69.46081500000014],[-85.42277499999994,69.46249399999999],[-85.43638599999991,69.46081500000014],[-85.445831,69.45637499999998],[-85.46501199999994,69.44081100000005],[-85.47721899999999,69.43637100000001],[-85.491379,69.43664600000005],[-85.50083899999998,69.4391480000001],[-85.51083399999999,69.44358799999998],[-85.525284,69.45277400000009],[-85.53889499999997,69.46693399999998],[-85.54249600000003,69.47637900000007],[-85.547775,69.64721700000007],[-85.54695100000004,69.65220600000004],[-85.514725,69.76805100000007],[-85.450287,69.78471400000012],[-85.42332499999998,69.78887900000012],[-85.40916399999998,69.78858900000012],[-85.39389,69.7852630000001],[-85.38917499999997,69.78054800000007],[-85.38999899999993,69.77581800000002],[-85.39416499999993,69.77053799999999],[-85.40695199999993,69.76026900000011],[-85.41082799999998,69.75526400000007],[-85.406387,69.75054900000003],[-85.39195299999994,69.7502750000001],[-85.37916599999994,69.75360100000012],[-85.36665299999999,69.75804099999999],[-85.34249899999998,69.76887500000004],[-85.33306899999997,69.77415500000012],[-85.331955,69.77915999999999],[-85.34445199999999,69.81303399999996],[-85.34916699999991,69.81749000000008],[-85.36193800000001,69.82193000000007],[-85.37721299999993,69.82415800000007],[-85.43360899999993,69.82360800000004],[-85.46139499999998,69.82249500000012],[-85.48999000000003,69.8230440000001],[-85.51861599999995,69.82360800000004],[-85.56138599999997,69.82470699999999],[-85.58639499999998,69.82693499999993],[-85.58222999999998,69.8458250000001],[-85.57861300000002,69.85081500000013],[-85.57194500000003,69.8560940000001],[-85.561935,69.85942100000005],[-85.54804999999993,69.859985],[-85.37721299999993,69.85108900000006],[-85.36193800000001,69.84887700000002],[-85.31555200000003,69.83804299999997],[-85.27416999999991,69.82527200000004],[-85.22250400000001,69.80802900000009],[-85.21250900000001,69.8035890000001],[-85.199432,69.79914900000006],[-85.17083699999995,69.79054299999996],[-85.093887,69.77331500000003],[-85.07917799999996,69.77110299999998],[-85.064438,69.76998900000001],[-84.87165800000002,69.8160860000001],[-84.86471599999993,69.82110599999993],[-84.854172,69.83137499999998],[-84.57417299999992,69.85748300000012],[-84.54638699999987,69.85942100000005],[-84.47666900000002,69.86219800000015],[-84.43360899999993,69.86109899999997],[-84.37582399999997,69.85748300000012],[-84.34666399999998,69.85470600000002],[-84.33168,69.85220300000003],[-84.16944899999999,69.82222000000013],[-84.12582399999991,69.80941800000011],[-84.118607,69.80470300000007],[-84.11416599999995,69.79998800000004],[-84.11222099999998,69.79359399999998],[-84.10417199999995,69.78581200000002],[-84.09167499999995,69.78137200000003],[-83.97193899999996,69.74971000000005],[-83.941666,69.74304200000012],[-83.74861099999993,69.70887800000008],[-83.73388699999998,69.70664999999991],[-83.70500199999992,69.703598],[-83.60388199999994,69.69358800000009],[-83.589447,69.69220000000001],[-83.36054999999999,69.67637600000006],[-83.34638999999999,69.67608600000005],[-83.33306900000002,69.678314],[-83.30638099999993,69.69386299999991],[-83.29361,69.69914200000011],[-83.28056299999992,69.70248400000003],[-83.25334199999998,69.70526100000012],[-83.23889200000002,69.70471199999997],[-83.18055700000002,69.69497700000011],[-83.122772,69.68914800000005],[-83.02194199999997,69.67970300000002],[-83.00805699999995,69.67915299999999],[-82.82695000000001,69.68887300000006],[-82.69665499999996,69.69581600000004],[-82.54100799999998,69.67447700000014],[-82.53967299999994,69.67159300000009],[-82.53616299999987,69.66882300000003],[-82.52732800000001,69.66615300000012],[-82.50950599999987,69.66197999999997],[-82.50067100000001,69.66049199999998],[-82.48332999999997,69.6579900000001],[-82.45750399999997,69.655327],[-82.291672,69.63998400000008],[-82.26333599999998,69.63804600000014],[-82.25473,69.63638300000002],[-82.30749500000002,69.62220800000011],[-82.33473199999997,69.61943100000002],[-82.390289,69.61886599999997],[-82.47066499999994,69.62303200000008],[-82.47633399999995,69.62587000000008],[-82.48366499999997,69.62853999999999],[-82.4925,69.630043],[-82.55233799999996,69.63537600000001],[-82.56083699999999,69.63570400000015],[-82.56899999999996,69.63487200000009],[-82.57700299999999,69.63287400000013],[-82.653885,69.62303200000008],[-82.65472399999999,69.56860400000011],[-82.612503,69.5669400000001],[-82.600281,69.5624850000001],[-82.535278,69.53498800000011],[-82.48998999999998,69.50721700000008],[-82.47666899999996,69.49775699999998],[-82.4869379999999,69.4935910000001],[-82.50056499999994,69.49220300000002],[-82.52888499999995,69.4952550000001],[-82.74221799999998,69.50999500000006],[-82.89750700000002,69.5188750000001],[-82.93971299999993,69.52137800000008],[-82.98222399999992,69.52415499999995],[-83.06777999999991,69.53305100000006],[-83.12554899999992,69.53997800000002],[-83.15417500000001,69.54386900000009],[-83.22805799999998,69.538589],[-83.08250399999997,69.51416000000006],[-83.025284,69.50804100000005],[-82.95472699999999,69.503601],[-82.87027,69.50027499999999],[-82.85665899999992,69.50082400000008],[-82.84249899999992,69.50027499999999],[-82.78527799999995,69.49414100000013],[-82.68472300000002,69.47970600000002],[-82.32417299999992,69.41886899999997],[-82.29527299999995,69.41387900000012],[-82.23721299999994,69.40081800000002],[-82.225281,69.39637799999997],[-82.22138999999993,69.39166299999994],[-82.23167399999994,69.38749700000005],[-82.28971899999999,69.25166300000012],[-82.291382,69.24664300000006],[-82.273056,69.23748800000004],[-82.25862099999995,69.23387100000008],[-82.24499500000002,69.2333220000001],[-82.21722399999993,69.23304700000011],[-82.20361299999996,69.23359700000015],[-82.05444299999999,69.24136400000009],[-82.04110700000001,69.242752],[-82.02778599999999,69.24497999999994],[-81.99129499999998,69.25470700000011],[-81.91471899999988,69.26944000000015],[-81.70777899999996,69.26470900000004],[-81.69387799999998,69.26304600000014],[-81.67971799999998,69.26054400000004],[-81.650284,69.25166300000012],[-81.51222200000001,69.20138500000013],[-81.4163969999999,69.2080380000001],[-81.402222,69.20721400000014],[-81.38833599999998,69.20471200000009],[-81.35972599999997,69.19664000000012],[-81.347778,69.19192500000008],[-81.33889799999997,69.18748500000004],[-81.33250399999986,69.18248],[-81.29943800000001,69.1202550000001],[-81.33084100000002,69.09526100000011],[-81.57028200000002,68.99247700000001],[-81.59584000000001,68.98414600000012],[-81.71665999999999,68.94914200000005],[-81.75556899999998,68.94136000000009],[-81.80943300000001,68.9327550000001],[-81.88806199999999,68.91914400000013],[-81.91416900000002,68.9144290000001],[-81.96611000000001,68.90443399999998],[-82.00500499999998,68.89553800000004],[-82.04305999999997,68.88388100000009],[-82.05555699999996,68.87858600000004],[-82.05721999999997,68.87387100000001],[-82.04333500000001,68.87220800000006],[-82.00306699999993,68.87414600000005],[-81.97721899999999,68.87970000000001],[-81.83306899999997,68.90721100000007],[-81.819458,68.90860000000009],[-81.68638599999997,68.90525800000012],[-81.67304999999999,68.90443399999998],[-81.66194200000001,68.90277100000003],[-81.650284,68.89915500000001],[-81.58805799999999,68.86970500000012],[-81.58195499999994,68.86499000000009],[-81.43832399999997,68.87498499999998],[-81.424713,68.87553400000013],[-81.382767,68.86665299999999],[-81.35417199999989,68.85748300000012],[-81.23805199999993,68.77470400000004],[-81.23443599999996,68.76998900000001],[-81.23277299999995,68.76026899999994],[-81.25222799999995,68.65304600000013],[-81.25584399999991,68.64305100000001],[-81.26055899999994,68.63804600000014],[-81.26750199999992,68.6330410000001],[-81.35777300000001,68.59915200000012],[-81.560272,68.5416560000001],[-81.68721,68.50943000000007],[-81.79888900000003,68.48970000000003],[-81.8163909999999,68.46971100000013],[-81.83029199999999,68.45971700000013],[-81.84249899999992,68.45555100000001],[-81.95805399999995,68.42330900000002],[-81.97083999999995,68.42109700000015],[-81.99777199999994,68.42303500000008],[-82.01194799999996,68.42776500000014],[-82.02444499999996,68.43691999999999],[-82.02778599999999,68.44165000000004],[-82.02888499999995,68.44664000000006],[-82.03332499999999,68.45609999999999],[-82.03805499999993,68.46582000000006],[-82.04167199999995,68.4705350000001],[-82.06220999999994,68.49443099999996],[-82.0686189999999,68.499146],[-82.07749899999993,68.503601],[-82.09167500000001,68.50721700000008],[-82.229446,68.5316620000001],[-82.256393,68.53360000000004],[-82.26945499999994,68.53248600000006],[-82.27111799999994,68.52748100000002],[-82.26722699999999,68.52276599999999],[-82.25473,68.51332100000013],[-82.24305699999996,68.50888100000009],[-82.22917199999989,68.50526400000012],[-82.1875,68.4958190000001],[-82.17582699999991,68.49136400000003],[-82.17332499999992,68.48580899999996],[-82.17500299999995,68.48109399999993],[-82.179169,68.47608900000006],[-82.18360899999993,68.47110000000009],[-82.19055200000003,68.46609500000005],[-82.20249899999999,68.46081500000003],[-82.21501199999989,68.45748900000012],[-82.22805799999998,68.45526100000001],[-82.25418099999996,68.45443700000004],[-82.382767,68.46693400000004],[-82.39389,68.468323],[-82.44888299999997,68.47859200000005],[-82.47694399999995,68.48553500000003],[-82.50029,68.49443099999996],[-82.53250100000002,68.50804100000005],[-82.54527300000001,68.51748700000002],[-82.5491639999999,68.52221700000007],[-82.55777,68.5269320000001],[-82.571396,68.52638200000007],[-82.58389299999988,68.52415500000001],[-82.60888699999992,68.51748700000002],[-82.62110899999999,68.51220699999993],[-82.63473499999998,68.5022130000001],[-82.63890100000003,68.49720800000006],[-82.63528400000001,68.49220300000002],[-82.4911039999999,68.4538730000001],[-82.49055499999992,68.40220599999992],[-82.36305199999998,68.35054000000008],[-82.35665899999992,68.34582500000005],[-82.35305799999998,68.341095],[-82.35110500000002,68.3313750000001],[-82.35249299999992,68.32666000000006],[-82.35665899999992,68.32165500000002],[-82.36944599999993,68.318329],[-82.38194299999992,68.31693999999999],[-82.39527899999996,68.31666600000005],[-82.42222599999997,68.318604],[-82.44860799999998,68.32083100000006],[-82.47500600000001,68.32110600000004],[-82.50083899999998,68.31749000000002],[-82.50778199999996,68.31330900000012],[-82.50140399999998,68.30859400000008],[-82.48361199999994,68.29942299999993],[-82.42610199999996,68.27665700000011],[-82.40055799999993,68.26887499999998],[-82.38694799999996,68.26638800000006],[-82.37388599999997,68.26554899999996],[-82.36082499999992,68.26693700000004],[-82.31166100000002,68.283051],[-82.2869419999999,68.28970300000003],[-82.27333099999993,68.28887900000007],[-82.264725,68.28442400000006],[-82.26000999999997,68.27499399999999],[-82.25917099999998,68.26998900000012],[-82.25862099999995,68.25555400000002],[-82.2644499999999,68.24552900000009],[-82.27027900000002,68.23553500000008],[-82.27861000000001,68.22554000000002],[-82.28944399999995,68.21554599999996],[-82.30055199999987,68.20555100000007],[-82.321121,68.19026200000002],[-82.33029199999987,68.18525699999992],[-82.33721899999995,68.18026700000007],[-82.34555099999994,68.17025800000005],[-82.34722899999997,68.16526800000003],[-82.34583999999995,68.16053799999997],[-82.33721899999995,68.15582300000011],[-82.31443799999994,68.14665200000002],[-82.27250699999996,68.13333100000006],[-82.23083500000001,68.12191800000005],[-82.20611599999995,68.115814],[-82.19248999999996,68.11248799999998],[-82.179169,68.111649],[-82.16639700000002,68.1141510000001],[-82.145782,68.12548800000002],[-82.09916699999997,68.15498400000001],[-82.08056599999992,68.17970300000013],[-82.06361400000003,68.19970700000005],[-82.05694599999998,68.20471200000009],[-82.0475009999999,68.20971699999996],[-82.0375059999999,68.21388199999996],[-82.02500900000001,68.21609500000011],[-82.01167299999986,68.21470599999992],[-81.99777199999994,68.21110500000009],[-81.98889200000002,68.20665000000002],[-81.98554999999999,68.20166],[-81.98472600000002,68.19692999999995],[-81.99305700000002,68.17248500000011],[-82.00889599999994,68.14776599999999],[-82.01916499999999,68.13275100000004],[-82.02722199999994,68.12275699999998],[-82.03416400000003,68.11775199999994],[-82.04361,68.11276200000009],[-82.056107,68.10942100000005],[-82.11450200000002,68.08287000000001],[-82.17388900000003,68.00248699999997],[-82.17555199999998,67.9974820000001],[-82.10278299999999,67.90721100000007],[-82.09666399999998,67.90248100000008],[-82.07945299999994,67.893326],[-82.07055700000001,67.888596],[-81.837784,67.78387500000002],[-81.72721899999993,67.740814],[-81.70750399999997,67.73165899999992],[-81.69055200000003,67.722488],[-81.6783289999999,67.71304299999991],[-81.66639700000002,67.70359800000006],[-81.65972899999997,67.69413800000001],[-81.65388499999995,67.68942300000015],[-81.63667299999992,67.67997700000001],[-81.59249899999998,67.66165200000006],[-81.53832999999997,67.64359999999999],[-81.49804699999999,67.63192700000013],[-81.45777900000002,67.62052900000015],[-81.43305999999995,67.61137400000007],[-81.4163969999999,67.60192900000004],[-81.24888599999991,67.47970600000008],[-81.24305699999991,67.47499100000005],[-81.23971599999987,67.470261],[-81.237213,67.45555100000001],[-81.237503,67.4410860000001],[-81.23916600000001,67.43609600000008],[-81.24526999999995,67.426376],[-81.25639299999995,67.41638199999994],[-81.29361,67.39610300000004],[-81.30055199999998,67.391098],[-81.30471799999998,67.38610800000009],[-81.347778,67.292755],[-81.36639400000001,67.23887599999995],[-81.37361099999998,67.20471199999997],[-81.37609900000001,67.18997200000001],[-81.37527499999999,67.18525699999998],[-81.38027999999991,67.17053200000004],[-81.41389500000002,67.0913700000001],[-81.43222000000003,67.06666600000011],[-81.49665799999991,67.00471500000015],[-81.50306699999993,66.9997100000001],[-81.51251200000002,66.99470500000001],[-81.52417000000003,66.99054000000001],[-81.53611799999999,66.98831200000006],[-81.69972200000001,66.97026100000011],[-81.71194499999996,66.96998600000006],[-81.75083899999993,66.97859199999999],[-81.76390100000003,66.983047],[-81.77223200000003,66.98776200000003],[-81.78306600000002,66.99247700000006],[-81.79611199999994,66.99693300000001],[-81.80915799999997,66.99832199999997],[-81.833618,66.99775699999998],[-81.92971799999992,66.97859199999999],[-81.95249899999993,66.96804800000012],[-81.98889200000002,66.94970699999993],[-82.026947,66.92608600000005],[-82.17999299999997,66.7688750000001],[-82.18388400000003,66.76416000000006],[-82.36972000000003,66.72581500000013],[-82.48110999999994,66.66970799999996],[-82.55638099999999,66.62387100000012],[-82.56277499999987,66.61886600000008],[-82.56666599999994,66.613876],[-82.57167099999998,66.60386699999998],[-82.57749899999999,66.584427],[-82.57667500000002,66.57943699999998],[-82.57945299999994,66.56971700000008],[-82.585556,66.56469700000002],[-82.59695399999998,66.56025699999998],[-82.69444299999998,66.55802900000003],[-82.78195199999999,66.56666600000005],[-82.86999499999996,66.56749000000002],[-83.01806599999998,66.53997800000008],[-83.012787,66.51582300000007],[-83.015289,66.50610400000005],[-83.01916499999987,66.50109900000001],[-83.025284,66.4958190000001],[-83.04998799999993,66.47553999999997],[-83.05860899999993,66.470261],[-83.35749799999996,66.35304300000007],[-83.36833200000001,66.34887700000002],[-83.40222199999994,66.347488],[-83.45056199999999,66.34664900000001],[-83.51528899999988,66.35386700000004],[-83.56750499999998,66.36747700000012],[-83.65278599999994,66.40776100000005],[-83.65417500000001,66.4124910000001],[-83.63944999999995,66.43719500000009],[-83.63082899999995,66.44220000000013],[-83.6183319999999,66.44081100000011],[-83.60777300000001,66.43637100000012],[-83.597778,66.42692600000004],[-83.60166900000002,66.4122010000001],[-83.597778,66.40748600000006],[-83.54527300000001,66.38136300000008],[-83.53472899999997,66.37803599999995],[-83.57972699999993,66.43165600000009],[-83.67250100000001,66.5205380000001],[-83.68110699999994,66.52499399999999],[-83.70695499999988,66.530823],[-83.73249799999996,66.53471400000006],[-83.79527300000001,66.54193099999998],[-83.82028200000002,66.54275499999994],[-83.83222999999998,66.54220600000002],[-83.85749799999996,66.54414400000013],[-83.96888699999988,66.57748400000003],[-83.97749299999998,66.58221400000008],[-83.98500100000001,66.59166000000005],[-84.01139799999999,66.66360500000002],[-84.01417499999997,66.67330900000002],[-84.01556399999998,66.68775900000014],[-84.01445000000001,66.69274899999999],[-84.00611900000001,66.69802900000008],[-83.99471999999997,66.70138500000013],[-83.98277299999995,66.70277400000009],[-83.94554099999999,66.70248400000008],[-83.89111300000002,66.8041530000001],[-83.886124,66.813873],[-83.88389599999994,66.82388300000008],[-83.88417099999992,66.83360299999998],[-83.890289,66.85775799999999],[-83.9016719999999,66.87191800000011],[-83.90777600000001,66.87664799999999],[-83.91639700000002,66.88108799999998],[-83.928879,66.86303700000002],[-83.93832399999991,66.82360800000009],[-83.94554099999999,66.81359900000007],[-84.10499600000003,66.70832800000011],[-84.11639400000001,66.70498700000007],[-84.140289,66.70193499999993],[-84.15278599999999,66.70248400000008],[-84.16555800000003,66.7038730000001],[-84.26028400000001,66.71638500000006],[-84.27305599999994,66.71859699999993],[-84.28666699999991,66.72303800000003],[-84.29527300000001,66.72747800000008],[-84.43638599999997,66.81832900000012],[-84.42777999999993,66.96110499999998],[-84.415009,66.96081500000014],[-84.39028899999988,66.96192900000011],[-84.37860099999995,66.96415700000006],[-84.36749299999997,66.9685970000001],[-84.370834,66.97137500000008],[-84.43611099999993,66.98136900000009],[-84.48805199999993,66.988876],[-84.61805700000002,67.00637800000004],[-84.69415300000003,67.00972000000002],[-84.73306300000002,67.01470899999998],[-84.837784,67.0294340000001],[-84.85082999999997,67.03166200000004],[-84.87332200000003,67.03942899999998],[-84.88194299999998,67.04386900000003],[-84.88612399999994,67.04859900000008],[-84.89250199999992,67.05331400000011],[-84.90139799999986,67.05775499999999],[-84.915009,67.06080600000001],[-84.92694099999994,67.05941800000011],[-84.93611099999993,67.05609099999998],[-84.88027999999997,66.98942600000004],[-84.87165800000002,66.98498499999994],[-84.85777299999995,66.98165900000009],[-84.84584000000001,66.98220800000007],[-84.83389299999993,66.984711],[-84.81111099999993,66.9916530000001],[-84.789444,67.00248699999997],[-84.77833599999991,67.00665300000009],[-84.76556399999998,67.00637800000004],[-84.69999699999994,66.99581900000004],[-84.64584400000001,66.98165900000009],[-84.63972499999988,66.97804300000007],[-84.65139799999997,66.97554000000008],[-84.71278399999994,66.97276299999999],[-84.88583399999993,66.96666000000005],[-84.96000700000002,66.96415700000006],[-85.01000999999997,66.96470600000004],[-85.04834,66.96331800000007],[-85.05972299999996,66.95971700000007],[-85.14277599999997,66.93026700000013],[-85.22833300000002,66.87831100000005],[-85.228882,66.87330600000001],[-85.22277799999995,66.86886600000003],[-85.19610599999999,66.85525500000006],[-85.18443300000001,66.85108900000012],[-85.146118,66.83943199999999],[-85.13305700000001,66.83692900000005],[-85.11999499999996,66.83554100000015],[-84.94860799999998,66.85859700000015],[-84.94027699999998,66.86387600000012],[-84.90455600000001,66.8972020000001],[-84.90105399999999,66.90037500000011],[-84.90489200000002,66.90303799999998],[-84.91288800000001,66.90504499999997],[-84.920547,66.90537300000011],[-84.93522599999989,66.904541],[-84.94306199999994,66.90537300000011],[-84.95105000000001,66.90737899999999],[-84.95788600000003,66.909874],[-84.96173099999999,66.91270400000002],[-84.95638999999994,66.91536700000012],[-84.86233500000003,66.93983500000007],[-84.855164,66.94066600000008],[-84.76777599999997,66.95220900000004],[-84.75527999999997,66.95166000000006],[-84.60221899999999,66.93580600000013],[-84.56221,66.90138200000013],[-84.57389799999999,66.89888000000002],[-84.61082499999992,66.89387499999998],[-84.62332200000003,66.89332600000006],[-84.650284,66.90081799999996],[-84.67582700000003,66.90277100000009],[-84.68832399999991,66.90304600000013],[-84.74638400000003,66.89749100000006],[-84.70639,66.888596],[-84.58555599999994,66.85887100000008],[-84.558334,66.85054000000002],[-84.52333099999998,66.83692900000005],[-84.50584399999997,66.82777399999998],[-84.50473,66.82304399999998],[-84.51611300000002,66.82054099999999],[-84.541382,66.82138100000003],[-84.58056599999998,66.82832300000013],[-84.63417099999998,66.84165999999999],[-84.660278,66.84637500000002],[-84.67250100000001,66.84582499999999],[-84.68443299999996,66.84414700000002],[-84.69055199999997,66.83998099999997],[-84.68443299999996,66.8352660000001],[-84.67555199999993,66.83082600000012],[-84.664444,66.82748400000014],[-84.65110799999997,66.82415800000012],[-84.466949,66.78776600000015],[-84.43443300000001,66.72554000000014],[-84.44526699999989,66.72026099999994],[-84.44860799999992,66.71527100000009],[-84.44248999999996,66.71081499999997],[-84.42944299999994,66.70832800000011],[-84.40417499999995,66.70555100000001],[-84.34306300000003,66.69941699999998],[-84.20388799999995,66.69136000000003],[-84.15306099999992,66.68580600000001],[-84.144455,66.68136600000003],[-84.13667299999997,66.66220100000004],[-84.13806199999988,66.65721099999996],[-84.14250199999998,66.64721699999996],[-84.14611799999994,66.64221200000009],[-84.18055699999996,66.60664400000007],[-84.18638599999991,66.60137900000001],[-84.12832599999996,66.55470300000002],[-83.96722399999993,66.47387700000007],[-83.91639700000002,66.44664000000012],[-83.89805599999994,66.43275500000004],[-83.88806199999999,66.42359900000008],[-83.87110899999993,66.39498900000007],[-83.86749299999997,66.38053900000011],[-83.80471799999992,66.30720500000012],[-83.77362099999999,66.28970300000009],[-83.774719,66.27526900000004],[-83.77223199999997,66.26554899999996],[-83.76861599999995,66.26081800000003],[-83.762787,66.25610400000011],[-83.728882,66.23803700000002],[-83.71833799999996,66.23359700000003],[-83.6847229999999,66.21554600000002],[-83.68110699999994,66.21081500000008],[-83.67860399999995,66.20109600000012],[-83.68443299999996,66.19609100000002],[-83.69305399999996,66.190811],[-83.76789899999994,66.16863999999998],[-83.78971899999993,66.16331500000013],[-83.83583099999993,66.15470900000003],[-83.84777799999995,66.15332000000001],[-83.85555999999991,66.155823],[-83.97778299999999,66.1994170000001],[-84.11805700000002,66.25471500000009],[-84.13528399999996,66.26388500000013],[-84.14111299999996,66.26832600000006],[-84.14862099999999,66.27777100000014],[-84.14999399999999,66.282761],[-84.15028399999994,66.29248000000001],[-84.14889499999992,66.29748500000005],[-84.15249599999999,66.30220000000008],[-84.158615,66.30664100000001],[-84.16722099999993,66.31109600000002],[-84.17832900000002,66.31553600000001],[-84.19082600000002,66.31805400000002],[-84.21640000000002,66.32165500000008],[-84.22833299999996,66.3211060000001],[-84.31723,66.299713],[-84.42694099999989,66.36303700000008],[-84.44193999999993,66.37220800000006],[-84.506393,66.40220599999998],[-84.51695299999994,66.40470900000014],[-84.528885,66.40415999999999],[-84.55055199999987,66.39444000000009],[-84.55888400000003,66.38916000000006],[-84.61915599999992,66.34971599999994],[-84.62693799999988,66.3435970000001],[-84.635559,66.334991],[-84.636124,66.32887300000004],[-84.625,66.31915299999997],[-84.527222,66.27859500000011],[-84.42443800000001,66.2247010000001],[-84.40750099999997,66.21554600000002],[-84.40139799999997,66.21110500000009],[-84.38999899999993,66.19693000000001],[-84.38639799999999,66.19219999999996],[-84.37777699999998,66.17804000000007],[-84.37249800000001,66.16832],[-84.37471,66.15860000000009],[-84.44860799999992,66.15860000000009],[-84.46055599999994,66.15914900000001],[-84.47332799999998,66.16137700000002],[-84.48388699999992,66.16470300000003],[-84.50944500000003,66.178314],[-84.64111299999996,66.216095],[-84.86915599999998,66.26666299999994],[-84.88194299999998,66.26805100000007],[-84.90583799999996,66.2669370000001],[-84.92748999999998,66.25888100000003],[-84.94387799999998,66.24832200000014],[-84.95472699999993,66.24386600000003],[-84.96665999999999,66.24443100000008],[-84.97972099999998,66.24664300000012],[-85.00167799999997,66.25526400000007],[-85.13194299999992,66.29193100000003],[-85.17832900000002,66.26220700000005],[-85.19027699999987,66.2605440000001],[-85.20249899999993,66.26081800000003],[-85.214722,66.26220700000005],[-85.22778299999999,66.26443499999999],[-85.25222799999995,66.27304100000009],[-85.26972999999998,66.28193700000003],[-85.30139200000002,66.30470300000007],[-85.30665599999992,66.3141480000001],[-85.33972199999994,66.39915499999995],[-85.34555099999989,66.44775400000009],[-85.346115,66.45748900000001],[-85.34167500000001,66.48220800000013],[-85.34333800000002,66.48692299999999],[-85.35139499999997,66.49609399999997],[-85.45750399999991,66.57388300000014],[-85.46640000000002,66.57832300000001],[-85.47972099999998,66.5813750000001],[-85.49194299999988,66.58194000000015],[-85.55221599999993,66.57777400000003],[-85.57556199999999,66.5747070000001],[-85.59861799999993,66.56944299999998],[-85.710556,66.53610199999997],[-85.84527600000001,66.49941999999999],[-85.85777300000001,66.49971],[-85.86888099999993,66.50416600000011],[-85.87554899999998,66.5086060000001],[-85.88890100000003,66.511932],[-85.995544,66.5080410000001],[-86.00750700000003,66.50721699999997],[-86.078888,66.49693300000007],[-86.10333300000002,66.49664300000006],[-86.12832600000002,66.49803200000008],[-86.14111300000002,66.49941999999999],[-86.25666799999993,66.51332100000013],[-86.28332499999993,66.51859999999994],[-86.578888,66.53027299999997],[-86.58000199999998,66.5205380000001],[-86.58778399999994,66.51527400000009],[-86.59973099999996,66.51110800000004],[-86.61138900000003,66.50833100000011],[-86.622772,66.50665299999997],[-86.63500999999997,66.50610400000005],[-86.65972899999997,66.50637799999998],[-86.67250099999995,66.507767],[-86.68554699999999,66.50972000000007],[-86.69888300000002,66.51304600000014],[-86.726944,66.5211030000001],[-86.73805199999998,66.52526900000004],[-86.75167799999997,66.52832000000001],[-86.76417499999997,66.52859500000005],[-86.77528399999994,66.526093],[-86.78083800000002,66.52082800000011],[-86.781387,66.51582300000007],[-86.777222,66.51110800000004],[-86.74388099999993,66.48858600000011],[-86.70111099999997,66.46665999999993],[-86.66278099999994,66.44941700000004],[-86.63999899999993,66.44108599999993],[-86.633621,66.43637100000012],[-86.64167799999996,66.43193100000008],[-86.678604,66.43275500000004],[-86.73055999999997,66.43692000000004],[-86.75695799999994,66.44136000000009],[-86.78361499999994,66.4474790000001],[-86.79638699999992,66.44859300000007],[-86.80749500000002,66.44609100000002],[-86.81111099999998,66.44192500000008],[-86.80915800000002,66.43719500000009],[-86.80499299999997,66.43248000000006],[-86.65167199999996,66.32415800000001],[-86.63833599999992,66.31526200000008],[-86.61277799999999,66.31164600000005],[-86.49722300000002,66.29942299999999],[-86.39611799999994,66.28970300000009],[-86.30610699999994,66.27638200000013],[-86.14222699999999,66.23969999999997],[-86.07611099999991,66.22387700000013],[-85.92748999999998,66.18637099999995],[-85.91389500000002,66.18220500000007],[-85.90110800000002,66.17303500000003],[-85.89723200000003,66.16832],[-85.97749299999992,66.07777399999998],[-85.97582999999992,66.0730440000001],[-85.97389199999998,66.03887900000001],[-85.974716,66.03387500000002],[-85.97999599999991,66.028595],[-85.99055499999997,66.02415500000012],[-86.077225,65.99581900000004],[-86.12138400000003,65.98442100000005],[-86.21749899999998,65.95748900000012],[-86.22084000000001,65.95220900000004],[-86.23138399999993,65.94192500000003],[-86.23916600000001,65.93664600000005],[-86.249435,65.93193100000002],[-86.32640099999998,65.90498400000007],[-86.34861799999987,65.899719],[-86.360275,65.89915500000006],[-86.42027299999995,65.89248700000007],[-86.47222899999986,65.83998099999997],[-86.49694799999997,65.80802900000003],[-86.49499499999996,65.803314],[-86.48638900000003,65.799149],[-86.46417199999996,65.79054300000007],[-86.45527600000003,65.78610200000014],[-86.453888,65.78137200000009],[-86.45111099999986,65.74720800000006],[-86.45417799999996,65.74220300000002],[-86.53028899999987,65.69552599999992],[-86.71610999999996,65.61747700000006],[-86.819458,65.56053200000002],[-86.82972699999999,65.55581699999999],[-86.84056099999998,65.55331400000006],[-86.85278299999993,65.55442800000003],[-86.86582899999996,65.55748000000011],[-86.87805200000003,65.55775499999993],[-86.88861099999997,65.555252],[-86.953888,65.53915400000011],[-86.97277799999995,65.520264],[-87.01722699999999,65.48692300000005],[-87.02444500000001,65.48165900000004],[-87.035278,65.47915600000005],[-87.05471799999998,65.48664900000011],[-87.06750499999998,65.48887599999995],[-87.077789,65.48498500000005],[-87.087784,65.47943100000009],[-87.09500100000002,65.47415200000012],[-87.110275,65.45860299999998],[-87.118607,65.4433140000001],[-87.11915599999998,65.43830900000006],[-87.11500499999994,65.43359400000003],[-87.101944,65.42970300000013],[-87.11166400000002,65.39027400000003],[-87.35110500000002,65.3272090000001],[-87.36193800000001,65.324432],[-87.37277199999994,65.32276900000005],[-87.3958439999999,65.32138099999997],[-87.43083199999995,65.32083100000011],[-87.83332799999994,65.32388300000002],[-87.86915599999998,65.32527200000004],[-87.89306599999998,65.32666000000012],[-87.94193999999987,65.33082600000006],[-87.96665999999999,65.333054],[-88.004456,65.33915700000011],[-88.03028899999993,65.345261],[-88.07028199999996,65.35609399999993],[-88.09445199999999,65.36331200000012],[-88.21278399999989,65.40277100000003],[-88.22138999999999,65.40721100000007],[-88.23472600000002,65.41609199999999],[-88.24333199999995,65.42526200000003],[-88.24527,65.42997700000006],[-88.25389100000001,65.43914800000005],[-88.31361400000003,65.47915600000005],[-88.33361799999994,65.49247700000001],[-88.54861499999998,65.58276400000011],[-88.55972300000002,65.58692900000011],[-88.57305899999994,65.58970600000004],[-88.58555599999994,65.59082000000001],[-88.633331,65.591095],[-88.645554,65.59220899999997],[-88.65888999999993,65.59498600000006],[-88.68582200000003,65.6019290000001],[-88.82972699999988,65.64137299999999],[-88.828888,65.64415000000008],[-88.75666799999999,65.64276100000006],[-88.62249799999995,65.6372070000001],[-88.49888599999997,65.62692300000003],[-88.51333599999998,65.64444000000009],[-88.77972399999999,65.67608599999994],[-88.9497219999999,65.68664600000011],[-88.962784,65.68858300000011],[-89.00083899999998,65.69859300000002],[-89.09944200000001,65.72526600000003],[-89.124435,65.7333220000001],[-89.13389599999994,65.73748799999998],[-89.14056399999993,65.74192800000003],[-89.14527899999996,65.74636800000002],[-89.14750700000002,65.75138899999996],[-89.14723199999997,65.76110799999998],[-89.14944499999996,65.76582300000001],[-89.15638699999994,65.77026400000011],[-89.17443800000001,65.778595],[-89.37999000000002,65.84637500000002],[-89.525284,65.886932],[-89.59722899999986,65.91081200000002],[-89.66471899999993,65.93498200000005],[-89.67166099999992,65.93942300000015],[-89.70944199999991,65.94220000000001],[-89.96722399999999,65.94859300000002],[-89.991104,65.94747899999999],[-90,65.94435900000013],[-89.96417199999996,65.93691999999999],[-89.93916300000001,65.93609600000002],[-89.92639199999991,65.93414300000006],[-89.89916999999997,65.92858900000004],[-89.87110899999999,65.92109700000015],[-89.83416699999998,65.91026300000004],[-89.79943800000001,65.8983310000001],[-89.74082900000002,65.87330600000007],[-89.731674,65.86914100000007],[-89.72694399999995,65.83998099999997],[-89.729172,65.83471700000001],[-89.73638900000003,65.829163],[-89.74694799999997,65.82638500000002],[-89.76916499999993,65.822495],[-89.79333499999996,65.822495],[-89.81889299999989,65.82554600000003],[-89.83222999999992,65.82832300000013],[-89.84388699999994,65.83221400000002],[-89.89056399999987,65.85304300000001],[-89.902222,65.85720800000001],[-90.04861499999998,65.88832100000002],[-90.07362399999994,65.89027399999998],[-90.085556,65.88915999999995],[-90.11999500000002,65.88388099999997],[-90.162781,65.87220799999994],[-90.20722999999992,65.86442600000004],[-90.24194299999999,65.86137400000007],[-90.26583899999997,65.86053500000014],[-90.31500199999999,65.86219800000003],[-90.40444899999994,65.87109399999997],[-90.41833500000001,65.87414600000011],[-90.42748999999998,65.87803600000007],[-90.43249500000002,65.8827510000001],[-90.42555199999993,65.88832100000002],[-90.39306599999992,65.89610299999998],[-90.35777300000001,65.89804100000009],[-90.333328,65.89721700000013],[-90.27278100000001,65.89749100000006],[-90.22555499999993,65.90054299999997],[-90.21556099999992,65.90443400000004],[-90.21333300000003,65.90942400000012],[-90.21333300000003,65.91442899999998],[-90.220551,65.91886899999997],[-90.23472599999997,65.92248500000005],[-90.258896,65.92248500000005],[-90.29333500000001,65.91859399999998],[-90.360275,65.907761],[-90.41888399999988,65.901093],[-90.57417299999997,65.89665200000007],[-90.59611499999994,65.89665200000007],[-90.708618,65.90248099999991],[-90.73388699999992,65.9041600000001],[-90.850281,65.91526799999991],[-91.06834400000002,65.94026200000008],[-91.31639099999995,65.96998600000012],[-91.32861300000002,65.96998600000012],[-91.34028599999994,65.96887200000009],[-91.42916899999994,65.95109599999995],[-91.44444299999986,65.93081700000005],[-91.36277799999993,65.89359999999999],[-91.35333299999996,65.88943499999999],[-91.341385,65.88581800000003],[-91.32806399999998,65.88388099999997],[-91.18943799999994,65.85304300000001],[-91.06082200000003,65.81330900000006],[-91.04666099999992,65.809418],[-91.02055399999995,65.8060910000001],[-91.008621,65.8060910000001],[-91.0041809999999,65.81137100000012],[-91.01390099999998,65.82054099999999],[-91.05471799999998,65.84664900000013],[-91.108337,65.8913730000001],[-91.12304699999993,65.90470900000008],[-91.12582399999985,65.90971400000012],[-91.12138400000003,65.9149930000001],[-91.09973099999996,65.91998299999995],[-91.08805799999993,65.92109700000015],[-91.06388900000002,65.92109700000015],[-90.99027999999998,65.91998299999995],[-90.97694399999995,65.918045],[-90.94860799999998,65.91081200000002],[-90.92138699999992,65.905258],[-90.90834000000001,65.90359500000011],[-90.74194299999999,65.88777200000004],[-90.69248999999996,65.88610800000004],[-90.53167699999995,65.88053900000006],[-90.07806399999998,65.8124850000001],[-90.01390099999992,65.80026200000003],[-90,65.79740099999992],[-89.98693800000001,65.79470800000007],[-89.96000699999996,65.78887900000007],[-89.93222000000003,65.78137200000009],[-89.74499500000002,65.72470099999998],[-89.72027599999996,65.71304299999997],[-89.660278,65.68331899999998],[-89.65333599999991,65.67886399999998],[-89.42832899999996,65.52943400000004],[-89.30888399999998,65.46943700000008],[-89.146118,65.40054300000008],[-89.06555199999991,65.333054],[-89.05444299999999,65.3288730000001],[-89.04444899999999,65.32777400000009],[-88.771118,65.30775499999999],[-88.73388699999998,65.30609099999998],[-88.71028100000001,65.30609099999998],[-88.69860799999998,65.30693100000002],[-88.676941,65.31053200000008],[-88.60694899999993,65.30693100000002],[-88.49027999999998,65.29332000000005],[-88.38917499999991,65.27720599999992],[-88.36471599999987,65.27499400000005],[-88.215012,65.27720599999992],[-88.13333099999994,65.27832000000012],[-88.10972599999997,65.27804600000002],[-88.09666400000003,65.27499400000005],[-88.06166099999996,65.25888100000003],[-88.02111799999989,65.27470400000004],[-88.01112399999994,65.27832000000012],[-87.97805800000003,65.28359999999998],[-87.943604,65.28610200000008],[-87.73138399999999,65.29026799999997],[-87.67304999999999,65.29136699999992],[-87.60221899999993,65.29054299999996],[-87.35777300000001,65.270828],[-87.21055599999994,65.254166],[-87.07501200000002,65.23664899999994],[-86.95777900000002,65.165817],[-86.94499200000001,65.15693699999997],[-86.936935,65.14776600000005],[-86.93331899999998,65.13804600000014],[-86.96749899999998,65.059418],[-86.9702759999999,65.05442800000009],[-86.97749299999998,65.04887400000013],[-86.99777199999994,65.04081699999995],[-87.04055799999998,65.03109700000005],[-87.11000100000001,64.999146],[-87.43028300000003,64.711929],[-87.52166699999992,64.62109400000008],[-87.57194499999997,64.57360799999998],[-87.57917800000001,64.56805400000002],[-87.58612099999999,64.56275900000014],[-87.59555099999994,64.55720500000012],[-87.69804399999992,64.52720600000009],[-87.76441999999997,64.52090499999991],[-87.78639199999992,64.51998900000001],[-87.79722599999997,64.51805100000007],[-87.80721999999997,64.51443499999999],[-87.85527000000002,64.43942300000009],[-87.85583500000001,64.42942800000014],[-87.86361699999998,64.37970000000001],[-87.8663939999999,64.36970500000012],[-87.98388699999992,64.19108600000004],[-87.99082900000002,64.18580599999996],[-88.11332700000003,64.13610800000004],[-88.12332200000003,64.13360599999999],[-88.28555299999994,64.10636900000003],[-88.55166600000001,64.02554300000008],[-88.553879,64.02053800000004],[-88.67443799999995,63.98026999999996],[-88.68443299999996,63.977486000000056],[-88.73666399999996,63.968323000000055],[-88.75944499999997,63.96943700000003],[-88.99388099999993,63.998604000000114],[-89.07778899999988,64.02609300000012],[-89.11000099999995,64.03804000000008],[-89.12721299999998,64.04664600000001],[-89.15083300000003,64.059418],[-89.18277,64.08137500000004],[-89.19804399999998,64.09471100000002],[-89.202225,64.09942600000005],[-89.20861799999994,64.10887100000008],[-89.210556,64.11831700000005],[-89.210556,64.12330600000001],[-89.21278399999994,64.12803600000007],[-89.22084000000001,64.13720700000005],[-89.24472000000003,64.15498400000007],[-89.25111399999997,64.15942400000012],[-89.26083399999987,64.16053800000009],[-89.28416400000003,64.14193700000004],[-89.28639199999998,64.13665800000007],[-89.18249500000002,64.036652],[-89.09666400000003,63.973877000000016],[-89.06166100000002,63.96082300000012],[-89.05110199999996,63.96193699999992],[-89.04083300000002,63.958602999999925],[-89.02362099999999,63.95027200000004],[-89.02860999999996,63.946098000000006],[-89.03944399999995,63.94499199999996],[-89.05055199999993,63.94499199999996],[-89.24665799999997,63.959717000000126],[-89.25472999999994,63.96305100000012],[-89.32139599999994,63.996658000000025],[-89.39611799999994,64.038589],[-89.50723299999993,64.07054099999999],[-89.55110199999996,64.07748399999997],[-89.55860899999999,64.07388300000014],[-89.56082200000003,64.06887800000004],[-89.56527699999998,64.01914999999997],[-89.56332399999985,64.00943000000007],[-89.55444299999999,64.00027499999999],[-89.54804999999993,63.996101000000124],[-89.53083800000002,63.98777000000007],[-89.51777599999991,63.97887400000013],[-89.48999000000003,63.956657000000064],[-89.48554999999999,63.95193499999999],[-89.48332199999987,63.94721199999998],[-89.48554999999999,63.94221500000009],[-89.49722300000002,63.94304699999998],[-89.52111799999994,63.95582600000006],[-89.52749599999999,63.96027400000003],[-89.577225,63.99554400000005],[-89.585556,64.00443999999999],[-89.58999599999993,64.01416000000006],[-89.59416199999993,64.0186000000001],[-89.637787,64.0494230000001],[-89.64416499999999,64.05386400000003],[-89.69972200000001,64.07638500000002],[-89.712219,64.0794370000001],[-89.71916199999998,64.0747070000001],[-89.72694399999995,64.04748499999994],[-89.785553,64.07693500000005],[-89.81806899999992,64.09860200000008],[-89.82250999999991,64.10331700000012],[-89.82278399999996,64.10803199999998],[-89.82055700000001,64.11331200000001],[-89.80972300000002,64.12886000000003],[-89.80221599999999,64.132477],[-89.78056300000003,64.13443000000012],[-89.75750700000003,64.13360599999999],[-89.74694799999997,64.1355440000001],[-89.73805199999993,64.14027399999992],[-89.73582499999998,64.145264],[-89.75111400000003,64.21804800000012],[-89.75556899999998,64.22747800000002],[-89.76000999999997,64.23220800000007],[-89.773056,64.240814],[-89.78416399999992,64.24470500000007],[-89.79415899999992,64.24192800000014],[-89.80110200000001,64.23748799999993],[-89.80555700000002,64.22720300000003],[-89.80332899999996,64.222488],[-89.80305499999997,64.20277400000009],[-89.81639100000001,64.14804100000009],[-89.823624,64.14444000000003],[-89.84555099999994,64.14276100000001],[-89.87943999999999,64.14248700000007],[-89.89222699999999,64.1455380000001],[-89.90972899999991,64.15859999999992],[-89.92250100000001,64.16137700000002],[-89.96749899999992,64.16137700000002],[-89.98693800000001,64.15971400000012],[-90.12416100000002,64.1285860000001],[-90.11805700000002,64.12525900000014],[-90.10499599999997,64.12136800000007],[-90.05860899999999,64.10971099999995],[-89.95056199999999,64.08692900000005],[-89.94610599999999,64.05748000000006],[-89.90417500000001,64.01582300000001],[-89.86694299999999,63.98971599999993],[-89.8416749999999,63.983879],[-89.83111600000001,63.979988000000105],[-89.82444799999996,63.97554800000006],[-89.82028199999996,63.97109999999992],[-89.81361399999997,63.946938000000046],[-89.81361399999997,63.93721000000005],[-89.81555200000003,63.931938000000116],[-89.82194499999997,63.9263840000001],[-89.82861299999996,63.921104000000014],[-89.83805799999993,63.91721299999995],[-89.93888899999996,63.90971399999995],[-89.95140099999998,63.912491000000045],[-89.989441,63.92193600000013],[-89.99833699999999,63.926102000000014],[-89.99527,63.92916100000002],[-89.97471599999994,63.93305200000009],[-89.964722,63.93582200000009],[-89.95527600000003,63.93971299999998],[-89.94860799999998,63.945267],[-89.94665500000002,63.950546000000145],[-89.94665500000002,63.96027400000003],[-89.94665500000002,63.96527100000009],[-89.94888299999991,63.96998600000012],[-89.95556599999998,63.9741590000001],[-89.968613,63.97804300000013],[-90,63.98404300000004],[-90.18249499999996,64.0086060000001],[-90.19415300000003,64.00943000000007],[-90.249435,64.00749200000013],[-90.27139299999999,64.00637799999993],[-90.27917500000001,64.00360100000006],[-90.27500900000001,63.999161000000015],[-90.26278699999989,63.997214999999926],[-90.22749299999998,63.99443800000006],[-90.21472199999988,63.99082900000002],[-90.19694499999991,63.982491000000095],[-90.11389200000002,63.93082400000009],[-89.97500599999995,63.825829000000056],[-89.96640000000002,63.81693999999999],[-89.96417199999996,63.81193500000012],[-89.96417199999996,63.80221599999993],[-89.96611000000001,63.79222100000004],[-89.96833799999996,63.78221100000013],[-89.97250399999996,63.776657000000114],[-89.981674,63.77304800000013],[-90.05777,63.74443800000006],[-90.08999599999993,63.69887499999999],[-90.14889499999998,63.629158000000075],[-90.15638699999994,63.626656000000025],[-90.20527599999991,63.61221299999994],[-90.23638899999992,63.60721600000005],[-90.25862099999989,63.60721600000005],[-90.42944299999999,63.61582900000002],[-90.46139499999998,63.64054900000008],[-90.468613,63.652309],[-90.48805199999998,63.67249300000009],[-90.50111399999997,63.676383999999985],[-90.61193799999995,63.70249200000012],[-90.62388599999991,63.704162999999994],[-90.63444500000003,63.70304900000002],[-90.64416499999993,63.7002720000001],[-90.70140099999998,63.662209000000075],[-90.69915799999995,63.65749400000004],[-90.68666099999996,63.65470900000014],[-90.67777999999993,63.65443399999998],[-90.65556300000003,63.65470900000014],[-90.62361099999998,63.657767999999976],[-90.61389199999991,63.66054500000001],[-90.60972599999991,63.6658250000001],[-90.61000100000001,63.67582700000008],[-90.60278299999999,63.67943600000007],[-90.59028599999999,63.67665899999997],[-90.55972300000002,63.65971400000001],[-90.55555699999996,63.65526600000004],[-90.55332900000002,63.650543000000084],[-90.54138199999994,63.61721000000006],[-90.54138199999994,63.61221299999994],[-90.54527300000001,63.606941000000006],[-90.55139199999996,63.601387000000045],[-90.56082200000003,63.597488],[-90.57112099999995,63.59554300000002],[-90.73388699999992,63.57388300000002],[-90.82806399999998,63.56166100000007],[-90.84944200000001,63.55971499999998],[-90.93055699999996,63.56415600000008],[-90.94276399999995,63.56666600000011],[-90.978882,63.576103000000046],[-90.98944099999994,63.57999400000011],[-91.03500399999996,63.5991590000001],[-91.13778699999989,63.630821000000026],[-91.158051,63.63555100000008],[-91.18859900000001,63.62943300000012],[-91.19888300000002,63.628601],[-91.21028100000001,63.628326000000015],[-91.23332199999999,63.62999000000002],[-91.37582399999997,63.65915700000011],[-91.39973399999997,63.66666400000008],[-91.40638699999994,63.67110400000007],[-91.40666199999998,63.67610200000007],[-91.40278599999999,63.681381000000044],[-91.39361600000001,63.68526500000007],[-91.37138400000003,63.685546999999985],[-91.34973100000002,63.677772999999945],[-91.33694500000001,63.67527000000001],[-91.329453,63.677772999999945],[-91.33389299999999,63.68249500000002],[-91.34056099999998,63.68665299999998],[-91.34944200000001,63.69082600000013],[-91.362503,63.69443500000011],[-91.41166699999991,63.70721400000002],[-91.52917499999995,63.72998799999999],[-91.54055800000003,63.73082000000005],[-91.55139200000002,63.72971300000012],[-91.56082199999992,63.726653999999996],[-91.569458,63.721930999999984],[-91.57556199999993,63.716385000000116],[-91.58416699999998,63.71138000000008],[-91.59555099999989,63.71138000000008],[-91.91055299999994,63.74054699999999],[-92.06639100000001,63.74193600000001],[-92.13612399999994,63.74554400000011],[-92.14862099999999,63.7480470000001],[-92.175003,63.75527199999999],[-92.18611099999998,63.75888800000001],[-92.43443300000001,63.804993000000024],[-92.48277299999995,63.81193500000012],[-92.47166400000003,63.80832700000002],[-92.43777499999993,63.79222100000004],[-92.42832899999996,63.783051],[-92.42555199999998,63.77860300000003],[-92.42250099999995,63.748878000000104],[-92.41583299999996,63.744713000000104],[-92.40666199999993,63.74054699999999],[-92.39555399999995,63.73693800000001],[-92.38276699999994,63.734161000000086],[-92.34889199999992,63.73387900000006],[-92.30638099999993,63.738602000000014],[-92.26306199999993,63.74137900000011],[-92.25111399999997,63.74054699999999],[-92.148056,63.716934000000094],[-92.10388199999994,63.701660000000004],[-92.10166900000002,63.6969380000001],[-92.10555999999997,63.69165800000002],[-92.20417799999996,63.63804600000009],[-92.25250199999999,63.62387800000005],[-92.26251200000002,63.62193300000007],[-92.38500999999991,63.59249100000011],[-92.48971599999993,63.56721500000003],[-92.49305699999996,63.540832999999964],[-92.48083500000001,63.52721400000007],[-92.42916899999994,63.54694400000005],[-92.33639499999987,63.55693800000006],[-92.27999899999998,63.55609900000013],[-92.20666499999993,63.60610200000008],[-92.20278899999988,63.611381999999935],[-92.19387799999993,63.615273],[-92.16528299999999,63.62443500000012],[-91.971115,63.67999300000014],[-91.83029199999993,63.71221200000002],[-91.82000699999998,63.714157],[-91.80943299999996,63.71527100000014],[-91.77610799999997,63.715828000000045],[-91.76333599999998,63.713325999999995],[-91.69526699999994,63.690544000000045],[-91.670837,63.67804700000005],[-91.61749299999991,63.64888000000013],[-91.61305199999993,63.644440000000145],[-91.61138899999997,63.63916000000006],[-91.61250299999989,63.629158000000075],[-91.61805699999996,63.613609],[-91.61721799999992,63.603882000000056],[-91.60749800000002,63.584991],[-91.60082999999997,63.580551000000014],[-91.39805599999994,63.52499400000005],[-91.27417000000003,63.502495000000124],[-91.13305699999995,63.478043000000014],[-90.94554099999993,63.440269000000114],[-90.85472099999998,63.40860000000009],[-90.91555799999992,63.41054500000007],[-90.93277,63.41860200000008],[-90.94554099999993,63.422493000000145],[-90.95695499999994,63.423325000000034],[-90.96833799999996,63.423050000000046],[-90.97500600000001,63.419441000000006],[-90.97277799999995,63.41471100000001],[-90.95750399999997,63.40138200000007],[-90.94221499999998,63.393051000000014],[-90.93138099999993,63.38916000000012],[-90.91888399999993,63.38638300000002],[-90.816666,63.36915600000003],[-90.74194299999999,63.36082500000009],[-90.69082599999996,63.228324999999984],[-90.62748699999997,63.05943300000001],[-90.64916999999991,63.03638500000011],[-90.73999000000003,62.962212000000136],[-90.77583299999998,62.941933000000006],[-90.78500400000001,62.93804199999994],[-90.79499800000002,62.936104],[-90.82583599999992,62.93305200000009],[-90.847778,62.932770000000005],[-90.87027,62.934433000000126],[-90.92944299999999,62.94443500000011],[-90.94055199999997,62.945267],[-91.01722699999993,62.946380999999974],[-91.03832999999992,62.94415300000003],[-91.04804999999999,62.94221500000009],[-91.17304999999999,62.908600000000035],[-91.18249499999996,62.90582300000011],[-91.19082599999996,62.900825999999995],[-91.19665499999996,62.89527100000009],[-91.20056199999993,62.88999200000012],[-91.1997219999999,62.87027000000006],[-91.20722999999998,62.8597180000001],[-91.21333300000003,62.85416400000008],[-91.35638399999999,62.78860500000002],[-91.36665299999993,62.787498000000085],[-91.44027699999987,62.78276800000003],[-91.46166999999997,62.7824940000001],[-91.57917800000001,62.79999500000008],[-91.84028599999994,62.82638500000007],[-91.99027999999998,62.84693900000002],[-92.0875089999999,62.81888600000008],[-92.214722,62.82471500000008],[-92.223053,62.82888000000008],[-92.23611499999993,62.83221400000008],[-92.33999599999999,62.843605000000025],[-92.36193799999995,62.844154],[-92.38276699999994,62.84166000000005],[-92.39250199999992,62.83971399999996],[-92.402222,62.83749399999999],[-92.42083699999995,62.83138300000007],[-92.43832399999997,62.82360799999998],[-92.45527599999997,62.81471299999998],[-92.45944199999997,62.810272000000055],[-92.458618,62.80027000000007],[-92.45584100000002,62.79583000000008],[-92.45140099999992,62.79110700000007],[-92.33361799999994,62.709991000000116],[-92.23277300000001,62.67304999999999],[-92.18859899999995,62.65915699999999],[-92.17832900000002,62.65638000000007],[-92.06777999999997,62.65165700000006],[-92.03472899999986,62.65026899999998],[-91.97138999999993,62.65332000000001],[-91.94888300000002,62.6519320000001],[-91.92582700000003,62.644440000000145],[-91.908615,62.63638300000002],[-91.88276699999994,62.624161000000015],[-91.88055400000002,62.61943800000006],[-91.883331,62.60443899999996],[-91.88500999999991,62.5991590000001],[-91.890289,62.58860000000004],[-91.94137599999999,62.534996000000035],[-91.94804399999998,62.53138000000001],[-92.05332899999996,62.526657],[-92.15306099999992,62.59804500000013],[-92.16332999999997,62.60082999999997],[-92.18611099999998,62.603324999999984],[-92.19665500000002,62.603049999999996],[-92.26611299999996,62.59526800000003],[-92.27500900000001,62.591377000000136],[-92.27139999999997,62.578049000000135],[-92.27555799999993,62.56027200000011],[-92.32556199999999,62.54083300000002],[-92.365005,62.533332999999914],[-92.38473499999998,62.529990999999995],[-92.396118,62.53082300000011],[-92.43083199999995,62.53582799999998],[-92.46806299999997,62.54444100000012],[-92.53916900000002,62.532493999999986],[-92.60611,62.46499600000004],[-92.61776700000001,62.46666000000005],[-92.71000699999996,62.46582799999993],[-92.72610500000002,62.44415300000014],[-92.72972099999998,62.438599000000124],[-92.73110999999994,62.433601000000124],[-92.73083499999996,62.428604000000064],[-92.724716,62.358604000000014],[-92.714722,62.34388000000001],[-92.66583300000002,62.33277100000009],[-92.62805200000003,62.322220000000016],[-92.60665899999992,62.31471300000004],[-92.59805299999994,62.31082199999997],[-92.5850069999999,62.302216000000044],[-92.58444199999997,62.29749300000009],[-92.58583099999987,62.292220999999984],[-92.60166899999996,62.26554900000008],[-92.610275,62.26138299999997],[-92.60399599999994,62.23632400000014],[-92.57305899999994,62.196098000000006],[-92.56861900000001,62.19165799999996],[-92.56193499999995,62.18749200000008],[-92.53666699999997,62.17555199999998],[-92.48638899999997,62.16137700000007],[-92.47805799999992,62.157493999999986],[-92.47001599999993,62.146614],[-92.47778299999999,62.14388300000002],[-92.48721299999994,62.14415700000012],[-92.59222399999999,62.154990999999995],[-92.60388199999994,62.156379999999956],[-92.62582399999991,62.19165799999996],[-92.64044199999995,62.209098999999924],[-92.63843500000002,62.21227300000004],[-92.63827500000002,62.215103000000056],[-92.63993800000003,62.21777000000009],[-92.70056199999999,62.26554900000008],[-92.7411039999999,62.28694200000001],[-92.74749800000001,62.28999300000004],[-92.845551,62.30943300000001],[-93.07556199999999,62.33221400000002],[-93.12222300000002,62.334991000000116],[-92.90417499999995,62.26221500000008],[-92.89222699999999,62.25972000000007],[-92.86639399999996,62.26305400000007],[-92.83999599999999,62.260276999999974],[-92.8286129999999,62.25721700000008],[-92.78028899999987,62.23693800000012],[-92.765289,62.22443400000009],[-92.76472499999994,62.21943700000003],[-92.79028299999999,62.17748999999992],[-92.79583699999995,62.17276800000002],[-92.80096399999996,62.172905000000014],[-92.84028599999999,62.17443800000001],[-92.85194399999995,62.17582700000003],[-92.862503,62.17943600000001],[-92.954453,62.19276400000001],[-93.06806899999998,62.17499500000008],[-93.07667499999991,62.17193600000013],[-93.11000099999995,62.15665400000012],[-93.114441,62.15415999999999],[-93.11972000000003,62.148330999999985],[-93.12693799999988,62.13249200000001],[-93.12416099999996,62.128044000000045],[-93.11944599999993,62.12360400000006],[-93.08138999999994,62.10443900000007],[-93.06916799999988,62.10360700000001],[-93.0597229999999,62.10582699999998],[-93.03750600000001,62.12165800000014],[-93.028885,62.12471000000005],[-93.01916499999999,62.12609900000007],[-93.00805700000001,62.125549000000035],[-92.94055200000003,62.11554700000005],[-92.93306000000001,62.11360900000011],[-92.93055700000002,62.10916099999997],[-92.93138099999999,62.10416400000008],[-92.936935,62.09915900000004],[-92.96833800000002,62.07721700000013],[-92.991104,62.067772000000105],[-93.14083900000003,62.00972000000013],[-93.237213,62.02693899999997],[-93.24638400000003,62.03333300000003],[-93.27749599999987,62.04277000000013],[-93.30277999999993,62.04943800000012],[-93.32528699999995,62.05138400000004],[-93.41139199999998,62.03138000000007],[-93.41305499999999,62.025551000000064],[-93.39416499999993,62.01361099999997],[-93.385559,62.00999500000012],[-93.37361099999998,62.00750000000011],[-93.36193799999995,62.00610400000005],[-93.34222399999993,62.00499700000012],[-93.318893,61.9980470000001],[-93.24444599999998,61.96943700000003],[-93.23554999999999,61.96554599999996],[-93.22222899999991,61.95749699999999],[-93.21833800000002,61.95249200000012],[-93.21722399999999,61.94776900000011],[-93.28195199999988,61.89138000000008],[-93.29972800000002,61.885826000000066],[-93.30915799999991,61.88360600000004],[-93.33056599999992,61.88638300000014],[-93.44248999999996,61.915268000000026],[-93.46167000000003,61.92249300000009],[-93.616104,61.939986999999974],[-93.60028099999994,61.879158000000075],[-93.61721799999998,61.86193800000012],[-93.55694599999998,61.84777100000014],[-93.43582199999997,61.80888399999998],[-93.28277600000001,61.7888870000001],[-93.24861099999998,61.78472099999999],[-93.23777799999993,61.77721400000007],[-93.24249299999997,61.767494],[-93.25556899999998,61.74249300000014],[-93.35694899999999,61.70721400000002],[-93.44943199999994,61.68221300000005],[-93.54276999999996,61.663321999999994],[-93.59416199999993,61.648048000000074],[-93.65499899999986,61.62915800000013],[-93.85665899999998,61.54916400000013],[-93.98472600000002,61.456100000000106],[-93.985275,61.45416300000005],[-93.968613,61.396660000000054],[-93.93249500000002,61.38721499999997],[-93.9219359999999,61.38526900000011],[-93.91166699999997,61.38582600000001],[-93.906387,61.38749700000005],[-93.89500399999997,61.389160000000004],[-93.88473499999986,61.389717000000076],[-93.86805699999996,61.389160000000004],[-93.85749800000002,61.385551000000135],[-93.82028199999996,61.35582699999998],[-93.81750499999998,61.35138699999993],[-93.81916799999999,61.34721400000001],[-93.839447,61.31944300000009],[-93.84445199999999,61.316101],[-93.85804699999994,61.31276700000001],[-93.93222000000003,61.29666100000003],[-93.94055200000003,61.29499800000008],[-94.05721999999997,61.178329000000076],[-94.14805599999994,61.04361000000006],[-94.22694399999995,60.94276400000007],[-94.34916699999991,60.85860399999996],[-94.35333300000002,60.85360700000007],[-94.3911129999999,60.79888200000005],[-94.41528299999999,60.762215000000026],[-94.415009,60.756660000000124],[-94.45167499999997,60.67110400000013],[-94.50500499999998,60.54999500000014],[-94.50944499999997,60.54415900000009],[-94.56304899999998,60.52221700000001],[-94.57583599999998,60.52027099999998],[-94.61138900000003,60.52777100000003],[-94.67332499999992,60.522490999999945],[-94.67166099999992,60.46610300000003],[-94.62943999999999,60.41832700000009],[-94.62638899999996,60.41360500000002],[-94.61471599999987,60.38999200000012],[-94.61389199999991,60.380547000000035],[-94.615005,60.37526699999995],[-94.620834,60.363883999999985],[-94.68194599999993,60.22415899999993],[-94.67361499999993,60.19110100000012],[-94.70472699999993,60.09193399999998],[-94.70750399999997,60.083603000000096],[-94.71139499999992,60.07833099999999],[-94.71472199999994,60.07527200000004],[-94.72833300000002,60.071380999999974],[-94.74665800000002,60.06999200000013],[-94.75279199999994,60.06860400000005],[-94.76640299999991,60.061378000000104],[-94.77111799999994,60.05554999999998],[-94.803879,60.008331],[-94.803879,60.0036090000001],[-94.80043,59.99956500000013],[-94.81916799999999,59.96471400000013],[-94.82167099999992,59.95916000000011],[-94.82250999999991,59.954162999999994],[-94.82055699999995,59.944435],[-94.80332900000002,59.877768999999944],[-94.80332900000002,59.711104999999975],[-94.81916799999999,59.63638300000008],[-94.78860500000002,59.51527400000009],[-94.735275,59.4263840000001],[-94.68055700000002,59.357215999999994],[-94.71528599999999,59.323326000000066],[-94.77000399999997,59.29833200000013],[-94.77500900000001,59.29332700000009],[-94.781387,59.263611000000026],[-94.78222700000003,59.25833100000011],[-94.78971899999999,59.092216000000064],[-94.681671,58.97582200000011],[-94.67999299999997,58.97137500000008],[-94.67639200000002,58.93443300000007],[-94.59777799999995,58.87832600000007],[-94.58639499999987,58.87499200000008],[-94.48693800000001,58.81526900000006],[-94.48222399999997,58.81110400000006],[-94.47778299999993,58.80665600000009],[-94.474716,58.802216000000044],[-94.45750399999991,58.77416200000005],[-94.45333899999991,58.76527400000003],[-94.45278899999988,58.759720000000016],[-94.45333899999991,58.75054900000009],[-94.44860799999998,58.736382000000106],[-94.44610599999999,58.73165899999998],[-94.43720999999988,58.72304500000007],[-94.42166099999997,58.71638500000006],[-94.410553,58.714157000000114],[-94.36138899999997,58.71276900000004],[-94.343613,58.715546000000074],[-94.32695000000001,58.72165699999999],[-94.29110700000001,58.743607],[-94.27917500000001,58.77110300000004],[-94.228882,58.78499600000009],[-94.23472599999997,58.714714000000015],[-94.252228,58.64999400000005],[-94.28527799999989,58.512496999999996],[-94.287216,58.438041999999996],[-94.28916899999996,58.427773000000116],[-94.291672,58.42221800000004],[-94.29666099999997,58.4158250000001],[-94.32640099999998,58.34915900000004],[-94.34861799999999,58.2866590000001],[-94.3516689999999,58.27665699999994],[-94.36389200000002,58.22387700000013],[-94.36332700000003,58.21888000000001],[-94.360275,58.220543000000134],[-94.3558349999999,58.226097000000095],[-94.25944500000003,58.35138699999999],[-94.23111,58.39054900000002],[-94.22860699999995,58.39610300000004],[-94.22694399999995,58.40638000000001],[-94.23111,58.43082400000014],[-94.23889199999996,58.494155999999975],[-94.24610899999999,58.576385000000016],[-94.24610899999999,58.58665499999995],[-94.24526999999995,58.59165999999999],[-94.24276699999996,58.59721400000001],[-94.14388999999994,58.76361099999991],[-94.11389200000002,58.76221500000008],[-93.99583399999995,58.760826000000066],[-93.94915800000001,58.76249700000011],[-93.84388699999994,58.767769000000044],[-93.79861499999993,58.77360499999992],[-93.72805800000003,58.78388200000012],[-93.70973200000003,58.78582799999998],[-93.67304999999993,58.78082300000011],[-93.57556199999999,58.763885000000016],[-93.47555499999999,58.73249100000004],[-93.35055499999993,58.74582700000002],[-93.34388699999988,58.75083200000006],[-93.327789,58.75721700000008],[-93.31916799999999,58.75860600000004],[-93.23666400000002,58.766936999999984],[-93.21665999999993,58.76416000000006],[-93.19638099999997,58.758331000000055],[-93.15556299999997,58.740273],[-93.15222199999994,58.73777000000001],[-93.14111299999996,58.691933000000006],[-93.13972499999988,58.653876999999966],[-93.12693799999988,58.53249400000004],[-93.12609900000001,58.52777100000009],[-93.11805700000002,58.50888800000001],[-93.09527600000001,58.46720900000008],[-93.03527799999995,58.37082700000002],[-92.96472199999994,58.261108000000036],[-92.93110699999994,58.21166199999999],[-92.86888099999993,58.14305099999996],[-92.8116609999999,58.07166300000006],[-92.80332900000002,58.057213000000104],[-92.79998799999998,58.0422210000001],[-92.80555700000002,58.01194000000004],[-92.80555700000002,58.00638600000002],[-92.80471799999998,57.997490000000084],[-92.79527300000001,57.96888000000007],[-92.75361599999997,57.85083000000003],[-92.724716,57.801383999999985],[-92.67250100000001,57.733047000000056],[-92.62110899999988,57.67054700000011],[-92.45083599999998,57.442490000000134],[-92.44638099999997,57.43305199999992],[-92.41888399999999,57.33749399999999],[-92.41833499999996,57.3324970000001],[-92.41888399999999,57.32332600000012],[-92.42721599999999,57.263053999999954],[-92.43028300000003,57.25222000000008],[-92.441101,57.23054500000012],[-92.5494379999999,57.08554799999996],[-92.56388900000002,57.068885999999964],[-92.57640099999998,57.056938000000116],[-92.695267,56.96166200000005],[-92.70861799999989,56.95166000000012],[-92.71583599999997,56.94748700000014],[-92.72332799999992,56.944435000000055],[-92.73832699999997,56.94110100000006],[-92.77139299999993,56.93804200000011],[-92.837219,56.92443800000001],[-92.86805699999996,56.91415399999994],[-92.87721299999993,56.90915700000005],[-92.87609899999995,56.9074940000001],[-92.86833200000001,56.90665400000006],[-92.85055499999993,56.90721100000013],[-92.83168,56.90859999999998],[-92.79055799999998,56.91387900000012],[-92.756958,56.918602000000135],[-92.73138399999999,56.922492999999974],[-92.691101,56.93360100000001],[-92.66027799999995,56.945266999999944],[-92.65222199999988,56.94915800000001],[-92.61721799999998,56.96888000000007],[-92.61000099999995,56.974709000000075],[-92.5891719999999,56.986382000000106],[-92.55277999999998,57.004714999999976],[-92.51445000000001,57.02360499999992],[-92.49221799999992,57.032493999999986],[-92.475281,57.03749800000014],[-92.44305400000002,57.044715999999994],[-92.40055799999999,57.052216000000044],[-92.37609899999995,57.056381000000044],[-92.25361599999997,57.065544000000045],[-92.23554999999999,57.06610100000012],[-92.22610500000002,57.065544000000045],[-92.21722399999999,57.063049000000035],[-92.21221899999995,57.058043999999995],[-92.21893299999999,57.052779999999984],[-92.33750900000001,56.981377000000066],[-92.34472700000003,56.977486],[-92.35221899999999,56.97415900000004],[-92.36833200000001,56.969711000000075],[-92.38555899999994,56.967209000000025],[-92.394455,56.96693399999998],[-92.41861,56.96193700000009],[-92.43222000000003,56.955826],[-92.46945199999999,56.93498999999997],[-92.46639999999996,56.93249500000013],[-92.375,56.94971499999991],[-92.30305499999997,56.96749100000011],[-92.28721599999994,56.97443400000009],[-92.281113,56.978874000000076],[-92.26861600000001,56.99082900000002],[-92.26194799999996,56.99582700000002],[-92.235275,57.012771999999984],[-92.22027600000001,57.01888300000002],[-92.204453,57.02416199999999],[-92.18028299999997,57.03082300000011],[-92.15527299999991,57.036658999999986],[-92.14666699999998,57.03777299999996],[-92.12916599999994,57.03943600000008],[-92.09306299999997,57.04083300000002],[-92.05776999999989,57.04388400000005],[-92.031677,57.04666099999997],[-91.987503,57.05248999999998],[-91.952225,57.05721299999999],[-91.828888,57.087211999999965],[-91.77999899999998,57.10027300000013],[-91.241104,57.22221400000001],[-91.15583799999996,57.23998999999998],[-91.08944699999995,57.25110600000011],[-91.05471799999998,57.25610400000011],[-91.03639199999998,57.258049000000085],[-91.00167799999991,57.26138300000008],[-90.99276700000001,57.26138300000008],[-90.83416699999992,57.257217000000026],[-90.81527699999998,57.25582900000012],[-90.795547,57.24971800000003],[-90.77917500000001,57.24332400000014],[-90.758896,57.237769999999955],[-90.73805199999993,57.23249099999998],[-90.71945199999999,57.228043000000014],[-90.70944199999997,57.22637900000001],[-90.56332399999991,57.21221200000008],[-90.45111099999997,57.1938780000001],[-90.408615,57.18166400000007],[-90.39167800000001,57.17610200000013],[-90.38778699999995,57.171378999999945],[-90.31082199999997,57.13499500000012],[-90.22555499999993,57.10443900000001],[-90.02500900000001,57.03138000000001],[-90.00500499999998,57.01915699999995],[-90,57.016369000000054],[-89.99055499999997,57.01110799999992],[-89.97027600000001,57.004166000000055],[-89.83306899999997,56.978324999999984],[-89.71528599999999,56.95721400000008],[-89.52139299999993,56.92943600000001],[-89.43916300000001,56.92388199999999],[-89.13294199999996,56.86485299999998],[-89.06806899999998,56.85221900000005],[-89.01528899999994,56.84777100000008],[-88.950287,56.843048000000124],[-88.94261199999994,56.844269000000054],[-88.81500199999999,56.82444000000004],[-88.74276700000001,56.764442000000145],[-88.67193599999996,56.70943500000004],[-88.65472399999993,56.696380999999974],[-88.63999899999999,56.68859900000007],[-88.63137799999998,56.68471500000004],[-88.58416699999992,56.670547],[-88.44055200000003,56.60360700000001],[-88.415009,56.58638000000002],[-88.36582900000002,56.561661000000015],[-88.32417299999997,56.54277000000002],[-88.218887,56.504440000000045],[-88.14944499999996,56.48693800000001],[-88.10305799999998,56.476097000000095],[-88.06973299999993,56.46888000000001],[-88.04888900000003,56.46554600000002],[-88.028885,56.459991000000116],[-88.01861600000001,56.45610000000005],[-87.98277299999995,56.441658000000075],[-87.97555499999993,56.43749199999996],[-87.84111000000001,56.315269],[-87.72389199999998,56.20388000000008],[-87.71916199999993,56.198875000000044],[-87.71501199999994,56.18998700000003],[-87.71556099999998,56.16971600000005],[-87.71389799999997,56.164993000000095],[-87.70805399999995,56.15609699999999],[-87.702789,56.15193199999999],[-87.54861499999993,56.04999500000014],[-87.478882,56.02916000000005],[-87.36888099999999,56.00083200000006],[-87.35194399999989,55.99276700000013],[-87.34527600000001,55.98860200000013],[-87.343613,55.983879],[-87.348343,55.973320000000115],[-87.35527000000002,55.96276900000004],[-87.19833399999999,55.940269],[-87.11000100000001,55.92943600000001],[-87.09167500000001,55.92748999999992],[-87.05722000000003,55.926941],[-87.03167699999995,55.92971800000009],[-86.99694799999997,55.931663999999955],[-86.97944599999994,55.931663999999955],[-86.97000099999997,55.92971800000009],[-86.88194299999992,55.90721100000002],[-86.837784,55.89138000000003],[-86.61694299999999,55.83888200000001],[-86.57278399999996,55.83027600000014],[-86.54444899999999,55.82444000000004],[-86.48666399999996,55.81137800000005],[-86.47778299999993,55.80888400000009],[-86.44860799999998,55.799995000000024],[-86.39862099999999,55.78416400000003],[-86.372772,55.77499399999999],[-86.346115,55.76305400000007],[-86.33277900000002,55.75471500000003],[-86.32194499999997,55.74554400000011],[-86.31527699999998,55.741104000000064],[-86.277222,55.72887399999996],[-86.26777600000003,55.72693600000002],[-85.86721799999998,55.657493999999986],[-85.74082900000002,55.63804600000009],[-85.731674,55.63694000000004],[-85.71444699999995,55.63166000000001],[-85.56945799999994,55.55860100000001],[-85.55665599999998,55.55027000000007],[-85.53222700000003,55.52804599999996],[-85.52583300000003,55.51888299999996],[-85.516663,55.50000000000006],[-85.515015,55.49527000000006],[-85.515289,55.490273000000116],[-85.50917099999998,55.48110200000002],[-85.499435,55.47221400000001],[-85.47416699999991,55.45471199999997],[-85.39334099999996,55.40888199999995],[-85.38362099999995,55.40499100000011],[-85.27223200000003,55.37470999999999],[-85.23472600000002,55.36471599999999],[-85.224716,55.364159000000086],[-85.20861799999994,55.36527300000006],[-85.18221999999997,55.36527300000006],[-85.164444,55.361664000000076],[-85.146118,55.354996000000085],[-85.12887599999999,55.346382000000006],[-85.12388599999986,55.34193400000004],[-85.12193300000001,55.33776900000004],[-85.11665299999993,55.323050999999964],[-85.11639400000001,55.31360600000011],[-85.11833199999995,55.30860100000007],[-85.12193300000001,55.303322000000094],[-85.129166,55.297775000000115],[-85.14416499999999,55.29027600000012],[-85.21528599999994,55.26860000000005],[-85.275284,55.21666000000005],[-85.398056,55.10083000000003],[-85.39999399999994,55.09582499999999],[-85.39750699999996,55.09054600000002],[-85.38362099999995,55.06749700000006],[-85.398056,55.0472180000001],[-85.41944899999999,55.01082600000012],[-85.425003,55.00027499999999],[-85.425003,54.99554400000005],[-85.42388900000003,54.99054699999999],[-85.41444399999995,54.991104000000064],[-85.40750099999997,54.99332400000009],[-85.40028399999994,54.997772000000055],[-85.38612399999994,55.00804900000003],[-85.37054399999994,55.02443700000009],[-85.36694299999999,55.029716000000064],[-85.36250299999989,55.04055000000011],[-85.347778,55.080826000000116],[-85.33555599999994,55.101661999999976],[-85.31834400000002,55.127486999999974],[-85.31304899999998,55.132767],[-85.22027599999996,55.22443400000009],[-85.19415300000003,55.24415599999992],[-85.17971799999998,55.253608999999926],[-85.156113,55.26416000000006],[-85.13999899999999,55.27027099999992],[-85.11665299999993,55.27665700000006],[-85.06806899999998,55.28749800000014],[-85.04388399999988,55.292770000000075],[-85.00195299999996,55.29666099999997],[-84.97471599999994,55.29583000000014],[-84.86944599999998,55.27971600000001],[-84.75140399999998,55.25610399999999],[-84.72361799999993,55.24971800000009],[-84.71278399999994,55.247772],[-84.68804899999992,55.24527000000012],[-84.635559,55.24221799999998],[-84.59916699999991,55.24166100000008],[-84.56639099999995,55.24415599999992],[-84.541382,55.247490000000084],[-84.44471699999986,55.267769000000044],[-84.428879,55.27304800000002],[-84.38861099999997,55.282493999999986],[-84.32278399999996,55.28999299999998],[-84.20695499999994,55.295547],[-84.19860799999998,55.295273000000066],[-84.189438,55.29415900000009],[-84.170837,55.28305100000006],[-84.15943899999996,55.2783280000001],[-84.14917000000003,55.27555100000001],[-84.12222300000002,55.27221700000001],[-84.11389200000002,55.27193499999993],[-84.09222399999999,55.27166000000011],[-84.07611099999997,55.27609999999993],[-84.04998799999993,55.286110000000065],[-84.006393,55.30138399999993],[-83.96888699999988,55.313881000000094],[-83.95167500000002,55.317497],[-83.93249499999996,55.319443000000035],[-83.92027300000001,55.31916000000007],[-83.8975069999999,55.3169400000001],[-83.65838600000001,55.23732400000006],[-83.65439600000002,55.235493000000076],[-83.65173299999992,55.23298599999998],[-83.57028199999996,55.18804200000011],[-83.56722999999994,55.18305200000003],[-83.57000700000003,55.17777300000006],[-83.58555599999994,55.16610000000003],[-83.5916749999999,55.15443400000004],[-83.58972199999994,55.149719000000005],[-83.57444799999996,55.138045999999974],[-83.561935,55.13082099999997],[-83.55665599999992,55.13416300000006],[-83.55665599999992,55.17943600000001],[-83.55860899999993,55.18498999999997],[-83.57950599999987,55.221157000000005],[-83.58805799999993,55.233330000000024],[-83.59388699999994,55.23693800000012],[-83.60082999999986,55.239990000000034],[-83.62083399999995,55.24276700000013],[-83.64389,55.24276700000013],[-83.65444899999994,55.2438810000001],[-83.670837,55.24860400000006],[-83.68443299999996,55.25443999999999],[-83.69610599999999,55.261664999999994],[-83.70611600000001,55.26971400000002],[-83.70889299999999,55.274437000000034],[-83.70611600000001,55.279990999999995],[-83.69860799999998,55.28305100000006],[-83.68888899999996,55.281937000000084],[-83.57417299999986,55.262215000000026],[-83.53332499999993,55.25054900000009],[-83.51945499999994,55.2438810000001],[-83.49888599999991,55.23554999999999],[-83.48944099999994,55.233879000000115],[-83.17971799999987,55.19721199999998],[-83.16860999999994,55.19748700000014],[-83.15028399999994,55.200271999999984],[-83.12805199999997,55.207497000000046],[-83.12027,55.21082300000012],[-83.08972199999994,55.22665400000005],[-83.07444799999996,55.23165899999992],[-83.03750599999995,55.23832700000008],[-83.02917499999995,55.238883999999985],[-83.00639299999995,55.23860200000013],[-82.98500100000001,55.236382000000106],[-82.964722,55.23360400000013],[-82.94860799999987,55.228874000000076],[-82.94166599999994,55.225821999999994],[-82.93055699999996,55.218323],[-82.91332999999986,55.20138500000007],[-82.906113,55.19193299999995],[-82.89695699999999,55.17721599999999],[-82.874435,55.15443400000004],[-82.83833300000003,55.146660000000054],[-82.80999800000001,55.14222000000001],[-82.78611799999999,55.141106000000036],[-82.77528399999994,55.14137999999997],[-82.76556399999987,55.14249399999994],[-82.73971599999993,55.14749100000006],[-82.708618,55.15638000000013],[-82.70083599999998,55.15971400000012],[-82.66972399999997,55.168052999999986],[-82.66111799999993,55.16971600000011],[-82.65028399999989,55.16971600000011],[-82.5083469999999,55.15277100000014],[-82.449432,55.133049000000085],[-82.41250600000001,55.112770000000125],[-82.40972899999997,55.108047],[-82.40083300000003,55.08277100000009],[-82.33555599999994,55.07101400000005],[-82.30749500000002,55.11582900000013],[-82.308044,55.121933000000126],[-82.3094329999999,55.127486999999974],[-82.3125,55.13249200000001],[-82.323624,55.13999200000006],[-82.33721899999995,55.14610299999998],[-82.34527600000001,55.1483310000001],[-82.35555999999997,55.162491000000045],[-82.34999099999987,55.16638200000011],[-82.34056099999998,55.16471100000001],[-82.333618,55.1616590000001],[-82.30776999999995,55.14888000000008],[-82.25418099999996,55.11138200000005],[-82.24583399999995,55.10277600000012],[-82.24499500000002,55.09027100000003],[-82.24694799999986,55.08416000000011],[-82.25334199999998,55.07360800000009],[-82.25778200000002,55.06888600000002],[-82.27362099999993,55.05721299999999],[-82.28222700000003,55.04804999999999],[-82.28527799999995,55.04277000000013],[-82.287216,55.03665900000004],[-82.287216,55.030273000000136],[-82.27084400000001,54.931381000000044],[-82.26722699999999,54.92027300000001],[-82.25527999999991,54.89415700000012],[-82.24694799999986,54.87943300000006],[-82.24137899999994,54.87499199999996],[-82.23194899999999,54.87387799999999],[-82.221115,54.787498000000085],[-82.32084699999996,54.571380999999974],[-82.403885,54.410820000000115],[-82.41915899999998,54.38416300000006],[-82.43167099999994,54.370270000000005],[-82.436935,54.36638599999998],[-82.441101,54.361664000000076],[-82.44166599999994,54.330826000000116],[-82.43415800000002,54.20943500000004],[-82.42166099999997,54.19721199999998],[-82.38999899999999,54.16832700000009],[-82.36277799999988,54.14360799999997],[-82.30139200000002,54.10305000000005],[-82.28388999999999,54.09249100000005],[-82.25334199999998,54.07610299999999],[-82.24804699999993,54.072220000000016],[-82.24388099999993,54.06805400000013],[-82.23832700000003,54.057495000000074],[-82.160278,53.89888000000013],[-82.13194299999998,53.817772000000105],[-82.13055399999996,53.793052999999986],[-82.12971500000003,53.77443699999998],[-82.13055399999996,53.767494],[-82.13667299999992,53.74916100000013],[-82.14889499999998,53.727768000000026],[-82.18998699999992,53.67416400000002],[-82.19415299999991,53.669441000000006],[-82.20306399999993,53.65332000000001],[-82.20834400000001,53.641936999999984],[-82.212784,53.622765000000015],[-82.21665999999999,53.60388200000011],[-82.21194499999996,53.536110000000065],[-82.208618,53.524994000000106],[-82.19888300000002,53.504714999999976],[-82.19055200000003,53.4897160000001],[-82.17250099999995,53.460548000000074],[-82.16555800000003,53.45138500000007],[-82.158615,53.44221500000003],[-82.14778100000001,53.421661000000086],[-82.13806199999999,53.38888500000013],[-82.12582399999997,53.34415400000012],[-82.11944599999998,53.31582600000013],[-82.11582900000002,53.29833200000007],[-82.11389199999991,53.28665900000004],[-82.11389199999991,53.280273000000136],[-82.11471599999987,53.273604999999975],[-82.11776699999996,53.26805099999996],[-82.12193299999996,53.26361099999997],[-82.14138799999995,53.25471500000003],[-82.21055599999994,53.22026800000003],[-82.24833699999994,53.193877999999984],[-82.26945499999994,53.16387900000001],[-82.27555799999999,53.15332000000012],[-82.27944899999994,53.14110600000009],[-82.30027799999993,53.060272],[-82.30139200000002,53.05332199999998],[-82.30166600000001,53.04166399999997],[-82.29666099999997,53.01859999999999],[-82.27389499999998,52.95638300000002],[-82.26139799999999,52.93721000000011],[-82.25750699999998,52.93277000000006],[-82.23582499999998,52.92416400000013],[-82.19638099999997,52.91332199999994],[-82.136124,52.89471400000008],[-82.120544,52.88971700000013],[-82.10166900000002,52.87999000000002],[-82.05055199999998,52.84304800000001],[-82.02583300000003,52.82388300000002],[-82.00111399999997,52.804710000000114],[-81.97778299999993,52.784996000000035],[-81.97361799999993,52.78054800000007],[-81.95140100000003,52.736938000000066],[-81.733612,52.54999500000014],[-81.71916199999998,52.53833000000009],[-81.71417200000002,52.53472100000005],[-81.69749499999995,52.52416200000005],[-81.63917500000002,52.490547000000106],[-81.62138400000003,52.480819999999994],[-81.60749799999996,52.475265999999976],[-81.577225,52.46527100000009],[-81.56945799999994,52.462212000000136],[-81.55804399999994,52.456099999999935],[-81.55416899999989,52.45166000000012],[-81.55139199999996,52.44665500000008],[-81.54998799999998,52.44110100000006],[-81.54249600000003,52.33888200000001],[-81.56138599999997,52.31638300000009],[-81.66305499999999,52.292220999999984],[-81.82250999999991,52.254440000000045],[-81.85082999999992,52.24499500000013],[-81.86305199999998,52.23888400000004],[-81.86582900000002,52.23333000000008],[-81.88362099999995,52.187492000000134],[-81.8741609999999,52.18832400000002],[-81.841949,52.19499200000001],[-81.82695000000001,52.19887499999993],[-81.80555700000002,52.20609999999999],[-81.795547,52.213882000000126],[-81.79249599999997,52.21915400000006],[-81.78860500000002,52.22387700000007],[-81.77944899999994,52.23220800000013],[-81.765015,52.23777000000007],[-81.75834699999996,52.23943300000002],[-81.74888599999997,52.24027300000006],[-81.71888699999988,52.240829000000076],[-81.55499299999985,52.23749500000008],[-81.52139299999993,52.23582500000009],[-81.50167799999997,52.23333000000008],[-81.47888199999994,52.22582200000005],[-81.472778,52.221930999999984],[-81.46000699999996,52.21027400000003],[-81.44360399999994,52.19276400000007],[-81.44055200000003,52.18859900000007],[-81.43443299999996,52.17916100000002],[-81.431671,52.17416400000013],[-81.43055700000002,52.16805300000004],[-81.41833500000001,52.149437000000034],[-81.41444399999995,52.14499699999999],[-81.40583800000002,52.13694000000004],[-81.36527999999998,52.10721600000005],[-81.35278299999999,52.10110500000013],[-81.337784,52.09610000000009],[-81.31054699999999,52.091102999999976],[-81.29083299999996,52.088599999999985],[-81.264725,52.08277099999998],[-81.21250900000001,52.06554399999999],[-81.18611099999987,52.053604000000064],[-81.16749600000003,52.04415899999998],[-81.11805700000002,52.04554700000011],[-80.99444599999993,52.01138300000008],[-80.98832700000003,52.008049000000085],[-80.97833300000002,52.000832],[-80.97444200000001,51.996384000000035],[-80.97305299999994,51.99082900000013],[-80.972778,51.9783250000001],[-80.92999299999997,51.92416399999996],[-80.91860999999994,51.91027100000014],[-80.89999399999994,51.89527099999998],[-80.89472999999998,51.89166300000005],[-80.80972300000002,51.857498000000135],[-80.69860799999998,51.79471599999994],[-80.61527999999993,51.73027000000013],[-80.610275,51.726379000000065],[-80.58917199999996,51.69971500000008],[-80.58917199999996,51.693321000000026],[-80.59028599999988,51.68665300000009],[-80.58999599999993,51.67416400000002],[-80.58612099999988,51.66360500000002],[-80.57888799999995,51.64860500000003],[-80.571396,51.633605999999986],[-80.515015,51.524437000000034],[-80.50750699999998,51.515830999999935],[-80.497772,51.508331000000055],[-80.46221899999989,51.48860199999996],[-80.45722999999992,51.484993000000145],[-80.44248999999996,51.47360200000003],[-80.43888900000002,51.46915400000006],[-80.43638599999986,51.464157000000114],[-80.43499800000001,51.458602999999925],[-80.42443800000001,51.36360899999994],[-80.42639200000002,51.35888700000004],[-80.43055700000002,51.35416400000008],[-80.44248999999996,51.34804500000007],[-80.47166400000003,51.33971400000013],[-80.50279199999994,51.331940000000145],[-80.54055800000003,51.323326000000066],[-80.56861900000001,51.314156000000025],[-80.65249599999999,51.27832799999999],[-80.69193999999999,51.24749000000003],[-80.70695499999994,51.2355500000001],[-80.83168,51.15582299999994],[-80.95249899999999,51.07972000000001],[-80.95944199999997,51.07749200000006],[-80.96528599999999,51.074440000000095],[-80.98111,51.06360600000005],[-80.9949949999999,51.0513840000001],[-81.00418100000002,51.043052999999986],[-81.01222200000001,51.03388200000006],[-81.015015,51.028328000000045],[-81.00527999999991,51.02860300000009],[-80.92805499999992,51.04583000000008],[-80.88833599999992,51.08277100000004],[-80.87527499999999,51.103324999999984],[-80.86221299999988,51.11610400000001],[-80.850281,51.12248999999997],[-80.83528099999995,51.12693800000011],[-80.82055700000001,51.130272000000105],[-80.79361,51.132767000000115],[-80.76501499999995,51.13360600000004],[-80.74804699999999,51.13665800000001],[-80.74082900000002,51.13888500000007],[-80.69444299999998,51.156097000000045],[-80.68859900000001,51.15915700000011],[-80.61000099999995,51.214157],[-80.56777999999997,51.25833100000011],[-80.56277499999999,51.26221499999997],[-80.541382,51.276657000000114],[-80.53056300000003,51.28360699999996],[-80.51251200000002,51.29276999999996],[-80.48028599999986,51.30721300000005],[-80.414444,51.332497000000046],[-80.40028399999989,51.33721200000008],[-80.39222699999999,51.338599999999985],[-80.37165800000002,51.33665500000001],[-80.33029199999999,51.32638500000007],[-80.21972700000003,51.30165900000003],[-80.19055199999997,51.297493000000145],[-80.1299899999999,51.297775],[-80.12027,51.296387000000095],[-80.01695299999994,51.263054000000125],[-79.99638399999992,51.25471500000009],[-79.80027799999999,51.156097000000045],[-79.78805499999993,51.14971900000012],[-79.741104,51.123604000000114],[-79.73638900000003,51.11971300000005],[-79.72917199999995,51.110825000000034],[-79.71651500000002,51.08171500000003],[-79.68510399999997,51.045361000000014],[-79.61277799999999,51.008049000000085],[-79.53761299999991,50.95839700000005],[-79.51972999999998,50.929993000000024],[-79.51611300000002,50.92638400000004],[-79.46610999999996,50.889434999999935],[-79.45056199999988,50.87860100000006],[-79.43859900000001,50.87221499999998],[-79.41500899999994,50.846939000000134],[-79.41139199999998,50.842490999999995],[-79.35278299999993,50.74832900000007],[-79.35028099999994,50.73693800000012],[-79.348053,50.73193400000014],[-79.34361299999989,50.728324999999984],[-79.33750900000001,50.72499099999999],[-79.33222999999998,50.723877000000016],[-79.33000199999992,50.758331000000055],[-79.33000199999992,50.76444200000009],[-79.33222999999998,50.77582600000005],[-79.42083699999995,50.87971500000003],[-79.43998699999992,50.8949970000001],[-79.464722,50.913321999999994],[-79.515015,50.95665699999995],[-79.537354,50.98376500000006],[-79.571121,51.00277699999998],[-79.66000400000001,51.04527300000001],[-79.67304999999988,51.05082700000003],[-79.67805499999992,51.054710000000114],[-79.69833399999993,51.07555400000007],[-79.70527600000003,51.08443500000004],[-79.749435,51.16832699999998],[-79.75195299999996,51.178878999999995],[-79.75222799999989,51.18443300000001],[-79.75111399999997,51.19748700000008],[-79.745544,51.208885000000066],[-79.74249299999997,51.214157],[-79.720551,51.243607000000054],[-79.70388799999995,51.26166500000011],[-79.69943199999994,51.26693700000004],[-79.68888899999996,51.28193700000003],[-79.68249500000002,51.29249600000003],[-79.68055699999991,51.298050000000046],[-79.67944299999999,51.30471000000006],[-79.66860999999994,51.39860500000009],[-79.59388699999994,51.44915800000007],[-79.58167999999995,51.45526899999999],[-79.5747219999999,51.4574970000001],[-79.54710399999988,51.46012900000011],[-79.53361499999994,51.50499700000006],[-79.47416699999997,51.579162999999994],[-79.37638900000002,51.64249400000011],[-79.353882,51.65609699999999],[-79.33168,51.66193399999992],[-79.32223499999998,51.66276600000003],[-79.23971599999999,51.63499499999995],[-79.23611499999993,51.63082099999991],[-79.23500099999995,51.62499200000008],[-79.23721299999994,51.61915600000003],[-79.25195299999996,51.60694100000012],[-79.275284,51.57777399999998],[-79.28527799999995,51.562492000000134],[-79.28527799999995,51.5563810000001],[-79.274719,51.530548000000124],[-79.271118,51.525551000000064],[-79.26722699999993,51.52166],[-79.20249899999999,51.51888300000007],[-79.18331899999998,51.51971400000008],[-79.17527799999993,51.521103000000096],[-79.16111799999993,51.525551000000064],[-79.15499899999998,51.528602999999976],[-79.14445499999994,51.536110000000065],[-79.13751200000002,51.53833000000009],[-79.12748699999986,51.538048],[-79.12027,51.53555299999999],[-79.02444500000001,51.47637900000012],[-79.02055399999995,51.473320000000115],[-79.01222199999995,51.4649960000001],[-79.00500499999993,51.44999700000005],[-78.96333299999998,51.3533250000001],[-78.95028699999995,51.29222100000004],[-78.95527600000003,51.25666000000007],[-78.95944199999991,51.25222000000002],[-78.96278399999994,51.24694100000005],[-78.96278399999994,51.24054699999999],[-78.95834400000001,51.23054500000006],[-78.95140100000003,51.21554600000002],[-78.93720999999994,51.19776900000011],[-78.92887899999994,51.18971300000004],[-78.92416400000002,51.185822000000144],[-78.91221599999994,51.17943600000007],[-78.906113,51.17665899999997],[-78.85333299999996,51.165543000000014],[-78.91471899999993,51.22165700000005],[-78.91833500000001,51.226097000000095],[-78.92054699999994,51.231102000000135],[-78.92166099999992,51.23749500000008],[-78.92027300000001,51.24971800000014],[-78.89056399999993,51.39054900000002],[-78.88833599999998,51.39666000000011],[-78.88305700000001,51.4011000000001],[-78.83222999999998,51.43859900000001],[-78.77917500000001,51.47499099999999],[-78.82028200000002,51.51305400000007],[-78.82389799999999,51.517494000000056],[-78.82611099999997,51.522491],[-78.82444800000002,51.54166400000008],[-78.82084699999996,51.55443600000007],[-78.80860899999999,51.576385000000016],[-78.791672,51.60388199999994],[-78.79638699999992,51.608604000000014],[-78.85916099999997,51.63416300000006],[-78.94415300000003,51.670547000000056],[-79.03472899999997,51.76471700000013],[-79.035553,51.77027100000009],[-79.03332499999988,51.77638200000001],[-79.02917499999995,51.78138000000001],[-79.00834699999996,51.79583000000014],[-78.995834,51.80165899999997],[-78.98582499999998,51.80165899999997],[-78.9761049999999,51.79972099999998],[-78.96139499999987,51.79499800000002],[-78.94444299999986,51.79083300000002],[-78.91805999999997,51.79444100000012],[-78.91082799999998,51.79666099999997],[-78.90360999999996,51.79943800000001],[-78.87998999999996,51.811378000000104],[-78.851944,51.828606000000036],[-78.84638999999999,51.8324970000001],[-78.83694500000001,51.841377000000136],[-78.833618,51.845825000000104],[-78.83222999999998,51.85277600000006],[-78.83444199999997,51.85777299999995],[-78.84167499999995,51.866661000000136],[-78.84638999999999,51.87026999999995],[-78.85861199999994,51.87693800000011],[-78.86361699999992,51.88082100000008],[-78.89555399999989,51.92665900000003],[-78.89639299999993,51.932495000000074],[-78.89416499999999,51.93832400000008],[-78.88194299999992,51.944435],[-78.86027499999989,51.95110299999993],[-78.851944,51.95249200000012],[-78.81054699999993,51.958885000000066],[-78.769455,51.96610300000009],[-78.747772,51.97332],[-78.73666400000002,51.97943100000009],[-78.695831,52.008049000000085],[-78.57945299999994,52.111382000000106],[-78.53750599999995,52.18082400000014],[-78.50111399999997,52.255829000000006],[-78.52444500000001,52.311104000000114],[-78.516953,52.36776700000007],[-78.50723299999999,52.45443700000004],[-78.506958,52.460548000000074],[-78.54527300000001,52.51471700000013],[-78.56471299999998,52.53027300000008],[-78.577225,52.536658999999986],[-78.585556,52.538605000000075],[-78.59584000000001,52.53888699999999],[-78.65444899999994,52.54694400000011],[-78.68443300000001,52.551383999999985],[-78.76333599999998,52.56443800000005],[-78.76112399999994,52.570549000000085],[-78.75556899999992,52.574164999999994],[-78.721115,52.58665500000012],[-78.69193999999993,52.59609999999998],[-78.71333300000003,52.628876000000105],[-78.75306699999987,52.68387599999994],[-78.79083300000002,52.73749500000014],[-78.79695099999998,52.77388000000008],[-78.765015,52.77748900000012],[-78.73194899999999,52.783333000000084],[-78.72471599999994,52.78555300000011],[-78.7225039999999,52.791664000000026],[-78.72555499999999,52.819443000000035],[-78.73832700000003,52.8722150000001],[-78.79444899999999,52.861381999999935],[-78.85610999999989,52.877769000000114],[-78.880829,52.896942000000024],[-78.88194299999992,52.90277100000003],[-78.87860099999989,52.908043000000134],[-78.86471599999999,52.96360800000008],[-78.91583300000002,53.00000000000006],[-78.92304999999993,53.06888600000008],[-78.88806199999993,53.22470900000013],[-78.894455,53.25972000000007],[-78.89584400000001,53.26527400000009],[-78.94249000000002,53.38499499999995],[-78.94972200000001,53.39999400000005],[-78.99172199999992,53.43404800000002],[-78.99472000000003,53.43637800000005],[-79.00455499999993,53.43921699999993],[-79.00955199999993,53.43821300000002],[-79.04472399999997,53.439430000000016],[-79.05305499999997,53.43804200000005],[-79.06332399999997,53.439430000000016],[-79.06806899999992,53.44332100000008],[-79.09028599999999,53.47054300000002],[-79.09306299999997,53.474709000000075],[-79.10777300000001,53.4972150000001],[-79.110275,53.502495000000124],[-79.10360699999995,53.51305400000001],[-79.08416699999998,53.522491000000116],[-79.05444299999994,53.53138000000001],[-79.035553,53.53276800000009],[-79.012787,53.53110499999997],[-79.031387,53.52971600000001],[-79.03805499999999,53.526657],[-79.04333499999996,53.52304800000002],[-79.04249599999991,53.51110800000009],[-79.041382,53.50555400000013],[-79.03639199999998,53.501663000000065],[-79.01483899999994,53.498940000000005],[-79.01100200000002,53.496937],[-79.00567599999994,53.49577000000005],[-79.00067899999993,53.496609000000035],[-78.96278399999994,53.50888800000013],[-78.91915899999998,53.55526700000007],[-78.91583300000002,53.5605470000001],[-78.91833500000001,53.565544000000045],[-78.92193599999996,53.56999200000001],[-78.95056199999999,53.599716],[-79.00334199999992,53.64166300000005],[-79.08972199999994,53.691658000000075],[-79.14500399999997,53.70166000000006],[-79.15139799999992,53.704994000000056],[-79.152222,53.71054800000002],[-79.05249000000003,53.831939999999975],[-79.04695100000004,53.835548000000074],[-79.039444,53.83776899999998],[-79.02972399999999,53.839157000000114],[-79.011124,53.839989],[-78.98889199999991,53.83888200000007],[-78.97999599999997,53.836104999999975],[-78.9661099999999,53.83027600000014],[-78.94833399999993,53.82083100000011],[-78.93277,53.81554399999999],[-78.91082799999998,53.81443799999994],[-78.90139799999997,53.815268999999944],[-78.90222199999994,53.821380999999974],[-78.90638699999994,53.82527200000004],[-78.91776999999996,53.83221400000008],[-78.92416400000002,53.835548000000074],[-78.96972700000003,53.851387000000045],[-78.98889199999991,53.85471300000006],[-79.01194800000002,53.85665899999998],[-79.05665599999992,53.873046999999985],[-79.10110499999996,53.90165700000006],[-79.10611,53.905548000000124],[-79.07250999999985,53.99916100000007],[-79.066956,54.002777000000094],[-79.05110200000001,54.00666000000007],[-79.041382,54.00777400000004],[-79.03167699999995,54.00777400000004],[-79.02139299999999,54.006386000000134],[-79.00109899999995,53.99999200000008],[-78.96495099999993,53.99716200000006],[-78.96162399999997,53.99999200000008],[-78.96028099999995,54.00138900000002],[-78.96278399999994,54.006386000000134],[-78.96665999999993,54.01082600000012],[-78.97666900000002,54.018326],[-78.98416099999997,54.02166],[-79.11944599999998,54.07860599999998],[-79.11639399999996,54.10305000000005],[-79.10638399999993,54.11138200000005],[-79.04638699999998,54.178329000000076],[-79.04888900000003,54.18332700000008],[-79.06054699999999,54.18415800000008],[-79.17332499999998,54.17499500000008],[-79.191666,54.17276800000002],[-79.19804399999987,54.16971600000011],[-79.19694499999997,54.16360500000002],[-79.19833399999999,54.15721099999996],[-79.20584099999991,54.154990999999995],[-79.23805199999998,54.15888200000006],[-79.27639799999992,54.16693900000001],[-79.34527600000001,54.199432],[-79.41999800000002,54.274437000000034],[-79.43055700000002,54.29027599999995],[-79.47666900000002,54.36859900000013],[-79.50500499999993,54.42582700000014],[-79.48805199999993,54.45221700000013],[-79.48805199999993,54.45860300000004],[-79.52139299999999,54.587212000000136],[-79.52528399999989,54.591377000000136],[-79.531677,54.59471100000013],[-79.56555200000003,54.609993000000145],[-79.61888099999993,54.62387800000005],[-79.67555199999993,54.62582400000014],[-79.68611099999998,54.62721299999993],[-79.76083399999999,54.648048000000074],[-79.76444999999995,54.65221400000013],[-79.761124,54.65832500000005],[-79.63166799999993,54.70277399999998],[-79.49415599999998,54.744713000000104],[-79.46362299999998,54.75360900000004],[-79.45722999999992,54.750275000000045],[-79.44749499999995,54.75110600000005],[-79.33778399999994,54.77249100000006],[-79.31582600000002,54.77999100000011],[-79.10110499999996,54.82721699999996],[-78.97666900000002,54.843048000000124],[-78.968887,54.845267999999976],[-78.95666499999999,54.85193600000014],[-78.94554099999993,54.85943600000002],[-78.9125059999999,54.884163000000115],[-78.83860800000002,54.91443600000008],[-78.73277300000001,54.93110700000011],[-78.56111099999993,54.97776799999991],[-78.37388599999997,55.030273000000136],[-78.2561189999999,55.08221400000002],[-78.207672,55.11165599999998],[-78.18222000000003,55.12526700000012],[-78.11944599999998,55.14999400000005],[-77.972778,55.20499400000011],[-77.87249799999995,55.243607],[-77.74861099999998,55.30082700000003],[-77.62222300000002,55.382766999999944],[-77.41665599999999,55.48610700000006],[-77.22582999999997,55.58832600000011],[-77.214722,55.595267999999976],[-77.1372219999999,55.65416000000005],[-77.11527999999993,55.67416400000013],[-77.10472099999998,55.683876000000055],[-77.08833299999992,55.69943200000006],[-77.08612099999993,55.70555100000007],[-77.085556,55.70804600000008],[-77.08778399999994,55.709716999999955],[-77.06834399999997,55.75471500000003],[-77.01306199999988,55.803046999999935],[-76.81138599999997,55.97110000000009],[-76.75195300000001,55.997772],[-76.737503,56.001663000000065],[-76.718887,56.00804899999997],[-76.70249899999993,56.017494000000056],[-76.6891629999999,56.027489],[-76.68194599999998,56.03388200000012],[-76.67721599999993,56.038605000000075],[-76.67083699999989,56.04583000000014],[-76.65805099999994,56.06082199999997],[-76.65083300000003,56.0719380000001],[-76.62666299999995,56.11804999999998],[-76.53832999999997,56.297775000000115],[-76.53222700000003,56.315269],[-76.53111299999995,56.32222000000013],[-76.51889,56.4060970000001],[-76.51750199999998,56.423325000000034],[-76.51750199999998,56.43582200000003],[-76.51916499999999,56.46471400000007],[-76.52583299999998,56.49276700000007],[-76.527222,56.50305200000014],[-76.52639799999992,56.60582700000003],[-76.50695799999994,56.710823000000005],[-76.50500499999998,56.733879],[-76.50445599999995,56.771934999999985],[-76.50556899999992,56.78499599999992],[-76.50527999999991,56.791382000000056],[-76.50556899999992,56.803047000000106],[-76.50944500000003,56.819717000000026],[-76.53083800000002,56.90665400000006],[-76.55444299999999,57.00582899999995],[-76.55471799999992,57.010826000000066],[-76.55583200000001,57.03499600000009],[-76.55332900000002,57.053322000000094],[-76.54916400000002,57.06221000000005],[-76.54527299999995,57.068885999999964],[-76.535553,57.07777399999998],[-76.53111299999995,57.087211999999965],[-76.52917500000001,57.09665700000005],[-76.52972399999987,57.10582700000009],[-76.564438,57.20721400000008],[-76.59138499999995,57.27443699999998],[-76.59999099999993,57.29361000000006],[-76.60444599999988,57.30277300000006],[-76.65306099999992,57.40138200000001],[-76.65834000000001,57.406653999999946],[-76.68804899999998,57.43055000000004],[-76.73222399999992,57.49027300000006],[-76.74082900000002,57.50332600000007],[-76.81138599999997,57.62471000000011],[-76.80943300000001,57.634720000000016],[-76.80777,57.641662999999994],[-76.80555700000002,57.647774000000084],[-76.86193799999995,57.71915400000006],[-76.92304999999999,57.786110000000065],[-77.14723199999997,58.02276599999993],[-77.24665800000002,58.07388300000008],[-77.27972399999999,58.08443500000004],[-77.31750499999998,58.09193400000004],[-77.34944200000001,58.10193600000002],[-77.44444299999998,58.152489],[-77.45111099999997,58.171379000000115],[-77.44665500000002,58.173882000000106],[-77.44110099999995,58.18277000000006],[-77.44415299999997,58.18776700000001],[-77.454453,58.19638100000003],[-77.46722399999999,58.203323000000125],[-77.48777799999993,58.212769000000094],[-77.57167099999998,58.2480470000001],[-77.64584399999995,58.27860300000003],[-77.81527699999998,58.32721700000002],[-77.851944,58.334991],[-77.883896,58.339989],[-77.91444399999995,58.34554300000002],[-77.93916300000001,58.35305000000011],[-77.95527600000003,58.35860400000013],[-78.01251200000002,58.378601],[-78.02444500000001,58.384163000000115],[-78.02806099999998,58.38694000000004],[-78.03138699999994,58.39138000000003],[-78.06268299999999,58.4173090000001],[-78.13055399999996,58.46276900000004],[-78.35555999999997,58.601661999999976],[-78.39723199999992,58.62082700000013],[-78.41999800000002,58.62721300000004],[-78.42527799999999,58.62609900000007],[-78.42832900000002,58.62360400000006],[-78.42777999999998,58.61110700000006],[-78.42610199999996,58.60610200000002],[-78.347778,58.53665900000004],[-78.38972499999988,58.54471600000005],[-78.5491639999999,58.603882],[-78.56388900000002,58.60999300000009],[-78.56861899999996,58.614441000000056],[-78.57389799999993,58.630547000000035],[-78.57472200000001,58.63526900000011],[-78.57000699999998,58.6730500000001],[-78.56388900000002,58.676941],[-78.55583199999995,58.67777300000006],[-78.54388399999999,58.67804699999999],[-78.51472499999994,58.67943600000001],[-78.46972700000003,58.695541000000105],[-78.46722399999999,58.70166000000012],[-78.48832699999997,58.78638500000005],[-78.50556899999998,58.835266000000104],[-78.51167299999992,58.839157],[-78.51640299999997,58.843323000000055],[-78.53860500000002,58.886940000000095],[-78.57139599999988,58.95721400000008],[-78.57055700000001,58.96138000000013],[-78.561935,58.9658280000001],[-78.55221599999999,58.968048000000124],[-78.39639299999993,58.96471400000013],[-78.36166399999996,58.95860300000004],[-78.35249299999992,58.95665700000001],[-78.34638999999999,58.95360599999998],[-78.34445199999988,58.949432000000115],[-78.34472699999998,58.94665500000002],[-78.34527600000001,58.94471000000004],[-78.34834299999994,58.942214999999976],[-78.36639400000001,58.92027300000012],[-78.36389200000002,58.91249099999999],[-78.35777300000001,58.910270999999966],[-78.34583999999995,58.909714000000065],[-78.33833300000003,58.91276600000003],[-78.31082199999997,58.9272160000001],[-78.30471799999992,58.931107],[-78.20556599999998,59.05054500000011],[-78.12748699999997,59.108330000000024],[-78.08666999999997,59.156654],[-78.093887,59.193047000000035],[-78.09861799999999,59.196655000000135],[-78.10194399999995,59.200829],[-78.103882,59.205826000000116],[-78.09277299999991,59.214995999999985],[-77.96112099999993,59.25833100000011],[-77.94972199999995,59.261939999999925],[-77.93028300000003,59.26527399999992],[-77.88444500000003,59.27193500000004],[-77.86000099999995,59.272217000000126],[-77.843613,59.27555100000012],[-77.82888799999995,59.28110500000008],[-77.82444800000002,59.28360699999996],[-77.68499799999995,59.393326000000116],[-77.67721599999999,59.399994000000106],[-77.67832899999996,59.401932000000045],[-77.77917500000001,59.426102000000014],[-77.787216,59.426658999999916],[-77.79804999999999,59.4263840000001],[-77.83138999999994,59.41471100000007],[-77.88027999999991,59.39916199999999],[-77.88751200000002,59.397491000000116],[-77.89695699999999,59.39721700000001],[-77.902222,59.39888000000008],[-77.90583800000002,59.4011000000001],[-77.91027799999995,59.40554800000007],[-77.91250600000001,59.41526799999997],[-77.91055299999988,59.42555199999998],[-77.872772,59.49193599999995],[-77.86749299999991,59.5],[-77.86111499999987,59.50388300000009],[-77.84056099999998,59.51305400000007],[-77.79888900000003,59.52499399999999],[-77.77917500000001,59.52887700000008],[-77.76945499999994,59.52916000000005],[-77.74999999999989,59.532211000000075],[-77.72138999999993,59.539719000000105],[-77.724716,59.59388000000001],[-77.75500499999993,59.62832600000007],[-77.76278699999989,59.63137800000004],[-77.76750199999992,59.63499499999995],[-77.79777499999994,59.67027299999995],[-77.80110200000001,59.67527000000007],[-77.79861499999993,59.67999300000008],[-77.77389499999998,59.70971700000007],[-77.76167299999997,59.709991],[-77.73194899999999,59.70777099999998],[-77.71055599999988,59.70471200000003],[-77.58522800000003,59.66921200000013],[-77.53988599999991,59.65338100000014],[-77.53539299999994,59.65137900000008],[-77.52439099999992,59.644714000000135],[-77.51888999999989,59.63938100000013],[-77.51322900000002,59.63054699999998],[-77.51372500000002,59.62021599999997],[-77.51489300000003,59.614044000000035],[-77.464722,59.58721200000002],[-77.46000699999996,59.58277100000009],[-77.45417799999996,59.579162999999994],[-77.44499200000001,59.576385000000016],[-77.42694099999994,59.57138100000003],[-77.35360700000001,59.563605999999936],[-77.32250999999991,59.56276700000001],[-77.31388900000002,59.564995000000124],[-77.311935,59.56693999999993],[-77.316956,59.56999200000007],[-77.34416199999998,59.57694200000009],[-77.42799400000001,59.619049000000075],[-77.433334,59.62054399999994],[-77.441666,59.62471799999997],[-77.50233500000002,59.67821500000002],[-77.54249600000003,59.747490000000084],[-77.541946,59.75027499999993],[-77.53306599999996,59.754714999999976],[-77.43276999999995,59.784163999999976],[-77.41278099999994,59.78777300000013],[-77.38944999999995,59.78888699999993],[-77.333618,59.78527100000008],[-77.31166099999996,59.785552999999936],[-77.30471799999998,59.78721600000006],[-77.29888900000003,59.78971900000005],[-77.29360999999989,59.793610000000115],[-77.29611199999994,59.801933000000076],[-77.30139200000002,59.811104],[-77.36361699999986,59.89083099999999],[-77.36805699999996,59.89471400000008],[-77.37805199999997,59.90138200000007],[-77.385559,59.90443399999998],[-77.42748999999998,59.914710999999954],[-77.206955,60.04277000000002],[-77.07000699999992,60.06415600000008],[-76.84805299999994,60.09915900000004],[-76.77583300000003,60.131659999999954],[-76.77084399999995,60.13638300000014],[-76.758896,60.15915700000011],[-76.80860899999993,60.15971400000001],[-76.82833900000003,60.157493999999986],[-76.846115,60.15221400000013],[-76.85249299999998,60.148330999999985],[-76.85777299999995,60.14388300000002],[-76.86054999999993,60.137771999999984],[-76.85749800000002,60.132767000000115],[-76.854172,60.121658000000025],[-76.85943599999996,60.11693600000012],[-76.86694299999999,60.113883999999985],[-76.889725,60.112495000000024],[-76.9244379999999,60.11166400000002],[-76.95056199999993,60.11221300000011],[-76.962784,60.113609],[-77.00389100000001,60.12193300000001],[-77.03138699999988,60.129714999999976],[-77.05555699999996,60.13860299999999],[-77.07417299999997,60.142769000000044],[-77.11193800000001,60.146942000000024],[-77.17388899999997,60.15026899999992],[-77.18749999999994,60.15082600000005],[-77.19999699999994,60.15082600000005],[-77.19972200000001,60.14527099999992],[-77.19471699999997,60.129158000000075],[-77.23249800000002,60.05387900000011],[-77.27278100000001,60.039993000000095],[-77.31582599999996,60.03054800000007],[-77.51916499999999,60.044159000000036],[-77.54028299999999,60.0480500000001],[-77.55721999999997,60.05277300000006],[-77.59222399999999,60.06415600000008],[-77.60028099999994,60.10860400000013],[-77.5952759999999,60.112495000000024],[-77.58168,60.1188810000001],[-77.55804399999994,60.126656000000025],[-77.54916400000002,60.129158000000075],[-77.49694799999992,60.156097000000045],[-77.47027600000001,60.213325999999995],[-77.47361799999993,60.216934000000094],[-77.60278299999993,60.329994000000056],[-77.63972499999994,60.362213000000054],[-77.6475069999999,60.365273000000116],[-77.65833999999995,60.36805000000004],[-77.68306000000001,60.36776700000007],[-77.69248999999996,60.369438000000116],[-77.70834400000001,60.37582400000002],[-77.743607,60.39332600000006],[-77.74722299999996,60.39694200000014],[-77.74775699999992,60.40813400000013],[-77.74082900000002,60.423607000000004],[-77.73693799999995,60.42887900000011],[-77.71945199999999,60.44721199999998],[-77.69193999999993,60.466660000000104],[-77.56750499999993,60.52971600000001],[-77.47999599999991,60.54055000000011],[-77.43083200000001,60.54027599999995],[-77.41972399999992,60.54110700000001],[-77.41332999999997,60.54415900000009],[-77.43638599999991,60.55443600000007],[-77.464447,60.56193500000006],[-77.48611499999993,60.56638300000003],[-77.52166699999998,60.5702740000001],[-77.54943800000001,60.57138100000003],[-77.57362399999994,60.570549000000085],[-77.59861799999993,60.56360600000011],[-77.63194299999998,60.551933000000076],[-77.64056399999998,60.55027000000001],[-77.65055799999999,60.54888200000005],[-77.67027300000001,60.549721000000034],[-77.68083199999995,60.552216000000044],[-77.704453,60.56166100000013],[-77.787216,60.59665700000005],[-77.829453,60.63360599999993],[-77.83389299999993,60.63943499999999],[-77.83167999999995,60.644714000000135],[-77.82167099999987,60.65193199999993],[-77.77583299999998,60.67110400000013],[-77.72250400000001,60.69193300000012],[-77.71639999999996,60.694435],[-77.61000100000001,60.755554000000075],[-77.51583900000003,60.830551000000014],[-77.51251200000002,60.833602999999925],[-77.51167299999997,60.83638000000002],[-77.53195199999999,60.83526600000005],[-77.57167099999998,60.82833099999999],[-77.708054,60.79554700000011],[-77.85638399999993,60.76444200000009],[-77.920547,60.79138200000011],[-77.903885,60.81249200000008],[-77.88999899999999,60.818886000000134],[-77.88333099999994,60.82332599999995],[-77.88722200000001,60.82582900000011],[-77.89639299999988,60.828049000000135],[-77.90916399999998,60.82888000000014],[-77.97528099999994,60.82276900000005],[-78.0786129999999,60.80609900000013],[-78.11694299999999,60.7980500000001],[-78.12582399999997,60.79554700000011],[-78.17250099999995,60.78721600000006],[-78.17971799999998,60.786942000000124],[-78.18638599999997,60.78804799999995],[-78.19055200000003,60.7888870000001],[-78.19276400000001,60.79083300000002],[-78.17166099999992,60.85471300000006],[-78.15943900000002,60.86721000000006],[-77.95472699999999,61.000831999999946],[-77.92555199999993,61.01888300000013],[-77.88917500000002,61.03804800000012],[-77.87361099999993,61.045547000000056],[-77.85804699999994,61.05110199999996],[-77.85388199999994,61.05221599999999],[-77.84666400000003,61.05249000000009],[-77.70167500000002,61.21749100000011],[-77.72444199999995,61.25443999999999],[-77.73999000000003,61.29860700000006],[-77.74665800000002,61.337494000000106],[-77.76112399999994,61.41027100000002],[-77.678879,61.461104999999975],[-77.620834,61.46249399999999],[-77.56361400000003,61.46666000000005],[-77.56054699999993,61.46804799999995],[-77.54249600000003,61.47943099999998],[-77.54333500000001,61.483047000000056],[-77.54833999999994,61.48610700000012],[-77.61389200000002,61.504166000000055],[-77.59611499999994,61.55582400000014],[-77.57278400000001,61.54999500000014],[-77.51722699999993,61.53971900000005],[-77.47860700000001,61.53638500000005],[-77.47500599999995,61.539161999999976],[-77.47471599999994,61.541664000000026],[-77.48028599999992,61.54888200000005],[-77.58139,61.60054800000012],[-77.58917199999996,61.60443900000001],[-77.61650099999997,61.60632700000008],[-77.62799799999999,61.60599500000012],[-77.66749600000003,61.603049999999996],[-77.69082599999996,61.60221899999999],[-77.70249899999999,61.60277600000006],[-77.71055599999988,61.60582700000009],[-77.74415599999998,61.64027400000009],[-77.816666,61.684989999999914],[-77.88444500000003,61.68582200000003],[-77.89889499999992,61.68637800000005],[-77.93138099999993,61.69193300000012],[-77.97582999999997,61.70277400000003],[-77.98222399999997,61.70665699999995],[-77.99249299999997,61.71471400000013],[-78.00306699999993,61.7283250000001],[-78.00611900000001,61.733047],[-78.01194799999996,61.74860400000006],[-78.0744479999999,61.917213000000004],[-78.07749899999999,61.940544000000045],[-78.08139,61.9511030000001],[-78.09167500000001,61.96527100000014],[-78.11000100000001,61.984161000000086],[-78.12026999999995,61.99193600000001],[-78.137787,62.009163],[-78.14138799999995,62.020546000000024],[-78.14361600000001,62.03138000000007],[-78.15943900000002,62.14999400000005],[-78.16166699999997,62.169159000000036],[-78.15777600000001,62.267494000000056],[-78.15583799999996,62.2783280000001],[-78.14973399999997,62.287216000000114],[-78.10305800000003,62.33749400000005],[-78.08500700000002,62.35332500000004],[-78.02389499999998,62.39332600000006],[-78.01640299999997,62.39388300000013],[-78.0080569999999,62.390549000000135],[-77.99665799999997,62.388046000000145],[-77.98306300000002,62.38832900000011],[-77.96305799999999,62.39276899999999],[-77.71139499999992,62.468048000000124],[-77.68721,62.47665400000005],[-77.55555699999996,62.53611000000001],[-77.535278,62.54694400000011],[-77.50834700000001,62.56166100000007],[-77.35499600000003,62.55804400000011],[-77.07362399999994,62.534163999999976],[-76.92582699999997,62.52638200000001],[-76.756958,62.50694300000009],[-76.74694799999997,62.504997],[-76.65556299999997,62.46998600000006],[-76.49861099999987,62.44110100000006],[-76.401947,62.42749000000009],[-76.31777999999991,62.41220900000013],[-76.14306599999992,62.37915800000002],[-75.70973200000003,62.29638700000004],[-75.71921499999996,62.242493000000024],[-75.73956299999992,62.23616000000004],[-75.819885,62.20565799999997],[-75.87887599999999,62.168602000000135],[-75.89111300000002,62.161933999999974],[-75.89500399999991,62.15859999999998],[-75.89083900000003,62.156937000000084],[-75.83583099999998,62.15804300000008],[-75.82694999999995,62.15888200000006],[-75.77239999999995,62.17721599999999],[-75.77072099999992,62.180049999999994],[-75.76505299999991,62.18471899999997],[-75.76088700000003,62.18705000000011],[-75.75605799999988,62.18871300000001],[-75.705063,62.203216999999995],[-75.656883,62.216544999999996],[-75.5791779999999,62.24221800000004],[-75.57389799999993,62.244155999999975],[-75.55694599999993,62.25277700000004],[-75.55277999999993,62.25666000000001],[-75.55027799999993,62.260826000000066],[-75.53944399999989,62.268326],[-75.493607,62.29332699999998],[-75.48693799999995,62.29638700000004],[-75.478882,62.29860700000006],[-75.47277799999995,62.299438000000066],[-75.40222199999994,62.306381000000044],[-75.35638399999999,62.310546999999985],[-75.32194500000003,62.31110400000006],[-75.30749500000002,62.31027199999994],[-75.18443299999996,62.292220999999984],[-75.01556399999998,62.264999000000046],[-75,62.262245000000064],[-74.93832399999991,62.25027499999999],[-74.91861,62.24554400000005],[-74.89805599999994,62.240273],[-74.88999899999999,62.237495000000024],[-74.88221699999991,62.23360400000013],[-74.87388599999986,62.22609700000004],[-74.76722699999988,62.161102000000085],[-74.70083599999987,62.13110400000011],[-74.69305400000002,62.12776900000006],[-74.66888399999999,62.11915600000009],[-74.62083399999989,62.107215999999994],[-74.59805299999994,62.10416400000008],[-74.57167099999998,62.10305000000011],[-74.55638099999999,62.104713000000004],[-74.55305499999997,62.10610200000002],[-74.553879,62.108047],[-74.55860899999988,62.111938000000066],[-74.61888099999993,62.13249200000001],[-74.662216,62.146660000000054],[-74.68611099999998,62.155823000000055],[-74.700287,62.16276600000009],[-74.75111400000003,62.19110100000006],[-74.758896,62.19915800000007],[-74.75973499999992,62.20138500000013],[-74.75973499999992,62.20638300000013],[-74.756393,62.212212000000136],[-74.72582999999992,62.24499500000013],[-74.71749899999992,62.247772],[-74.700287,62.25083200000006],[-74.67832899999996,62.25360899999998],[-74.64584400000001,62.25360899999998],[-74.579453,62.25193800000011],[-74.52583300000003,62.24694099999999],[-74.47361799999993,62.24332400000003],[-74.46139499999998,62.24388099999993],[-74.42887899999994,62.247772],[-74.41000400000001,62.25138900000013],[-74.38389599999994,62.2586060000001],[-74.14167799999996,62.326660000000004],[-73.98138399999999,62.377769],[-73.97444200000001,62.386108000000036],[-73.96972700000003,62.39083099999999],[-73.94027699999998,62.41220900000013],[-73.88890100000003,62.44054399999993],[-73.83805799999999,62.457497000000046],[-73.68804899999998,62.47998800000005],[-73.678879,62.47998800000005],[-73.65972899999997,62.475265999999976],[-73.64834599999995,62.468323],[-73.64250199999992,62.463608000000136],[-73.502792,62.38665800000007],[-73.36999500000002,62.363609000000054],[-73.22721899999988,62.318054000000075],[-73.21139499999992,62.31276700000001],[-73.20666499999999,62.308884000000035],[-73.20417800000001,62.303878999999995],[-73.202789,62.298882000000106],[-73.20722999999992,62.28582800000004],[-73.21028099999995,62.28193699999997],[-73.21083099999998,62.27582600000005],[-73.20973200000003,62.27082800000005],[-73.20417800000001,62.26138299999997],[-73.19193999999987,62.25360899999998],[-73.17805499999997,62.246101000000124],[-73.13194299999998,62.22526600000003],[-73.07000699999998,62.197487000000024],[-72.89944500000001,62.138329],[-72.72389199999992,62.142220000000066],[-72.62666300000001,62.11554700000005],[-72.61721799999998,62.10860400000007],[-72.59611499999988,62.04916400000002],[-72.61871300000001,61.97421299999996],[-72.619888,61.97087899999997],[-72.66571799999991,61.928383],[-72.68998699999992,61.891936999999984],[-72.74861099999998,61.856384000000105],[-72.724716,61.845267999999976],[-72.612503,61.80499300000008],[-72.60278299999993,61.804160999999965],[-72.59611499999988,61.80554999999998],[-72.59167499999995,61.80998999999997],[-72.58778399999989,61.82027400000004],[-72.62277199999994,61.861382000000106],[-72.62887599999999,61.87304700000004],[-72.60955799999999,61.88771400000013],[-72.61089300000003,61.893714999999986],[-72.61139700000001,61.900047000000086],[-72.61022200000002,61.90538000000009],[-72.607552,61.910049000000015],[-72.59754899999996,61.92021199999999],[-72.593887,61.92321400000003],[-72.58722699999998,61.92437699999999],[-72.58122299999997,61.92337800000013],[-72.51972999999992,61.920547],[-72.44860799999998,61.90138200000001],[-72.39666699999992,61.88943500000005],[-72.38694800000002,61.887771999999984],[-72.345551,61.88443799999999],[-72.32194500000003,61.88388100000009],[-72.256958,61.87693800000011],[-72.23500100000001,61.8722150000001],[-72.20584099999996,61.86332700000014],[-72.20083599999992,61.860275],[-72.041382,61.72248800000011],[-72.01005600000002,61.67527000000001],[-72.03805499999999,61.62470999999999],[-72.08056599999998,61.60193600000002],[-72.087784,61.59887700000007],[-72.09583999999995,61.59609999999998],[-72.11389200000002,61.59554300000008],[-72.12388599999997,61.596382000000006],[-72.16000400000001,61.60527000000002],[-72.19415300000003,61.615829000000076],[-72.22749299999998,61.61998700000004],[-72.23666399999996,61.61943800000006],[-72.254456,61.61554699999999],[-72.271118,61.609161000000086],[-72.3033289999999,61.570831],[-72.30387899999994,61.568885999999964],[-72.3033289999999,61.56721500000009],[-72.083618,61.58249699999993],[-72.05722000000003,61.586655000000064],[-71.98028599999998,61.599998000000085],[-71.97833300000002,61.6013870000001],[-71.96777299999997,61.60943600000007],[-71.94082599999996,61.64833100000004],[-71.93666099999996,61.65554800000001],[-71.93360899999993,61.66360500000013],[-71.93306000000001,61.66860200000008],[-71.93388400000003,61.67416400000002],[-71.93666099999996,61.677773],[-71.94137599999999,61.681107],[-71.94688400000001,61.68838099999999],[-71.95038599999987,61.68871300000012],[-71.953888,61.69071600000012],[-71.95655799999992,61.69304700000009],[-71.95688599999988,61.69421399999999],[-71.95605499999994,61.69888300000014],[-71.95054600000003,61.7012180000001],[-71.94888300000002,61.70155],[-71.945221,61.701714000000095],[-71.928879,61.705826000000116],[-71.81945799999994,61.688599000000124],[-71.79527300000001,61.68221300000005],[-71.64472999999992,61.639435000000105],[-71.5750119999999,61.608604000000014],[-71.57167099999987,61.605552999999986],[-71.545547,61.5719380000001],[-71.54611199999994,61.5669400000001],[-71.5494379999999,61.558884000000035],[-71.56027199999994,61.55721299999993],[-71.62971499999998,61.54860700000006],[-71.63500999999997,61.54583000000014],[-71.652222,61.54305300000004],[-71.66305499999993,61.54193900000007],[-71.75111399999997,61.538048],[-71.789444,61.52193499999993],[-71.74638400000003,61.47137500000008],[-71.74694799999997,61.46582799999999],[-71.80277999999998,61.446938000000046],[-71.81750499999998,61.44276400000001],[-71.87554899999992,61.43610399999994],[-71.88555899999994,61.43276999999995],[-71.887787,61.43082400000009],[-71.88751199999996,61.42804699999999],[-71.87943999999999,61.422492999999974],[-71.87304699999993,61.41971600000011],[-71.85333300000002,61.41443600000002],[-71.70056199999999,61.405823000000055],[-71.68472299999996,61.40499099999994],[-71.67610199999996,61.37221500000004],[-71.67193599999996,61.33055100000013],[-71.59889199999998,61.254166000000055],[-71.53083799999996,61.21360800000002],[-71.38999899999999,61.1377720000001],[-71.29583699999989,61.14860500000009],[-71.28666699999991,61.14971900000006],[-71.27917500000001,61.1511000000001],[-71.174713,61.13999200000012],[-71.01139799999999,61.12165799999997],[-70.96694899999994,61.113883999999985],[-70.94583099999994,61.108887000000095],[-70.92832900000002,61.10249300000004],[-70.92193600000002,61.09693900000002],[-70.92138699999998,61.09137700000008],[-70.77333099999998,61.08166499999993],[-70.656387,61.05054500000006],[-70.55305499999997,61.02499400000005],[-70.53971899999999,61.05582400000009],[-70.535278,61.05943300000007],[-70.41999800000002,61.08526599999999],[-70.41361999999998,61.08665500000001],[-70.31555199999991,61.09499400000004],[-70.165009,61.088043000000084],[-70.14611799999989,61.08471700000007],[-70.14138799999995,61.08277099999998],[-70.10722399999992,61.06443800000011],[-70.08583099999998,60.954994],[-70.08805799999988,60.89777400000014],[-69.92749000000003,60.807770000000005],[-69.914444,60.80860100000001],[-69.90110799999997,60.81221000000005],[-69.88806199999993,60.81916000000007],[-69.85638399999999,60.83832600000011],[-69.85055499999999,60.84193400000004],[-69.84973100000002,60.84665699999999],[-69.85139500000002,60.849716],[-69.85888699999998,60.85193600000002],[-69.86944599999993,60.85082999999997],[-69.88362099999995,60.84526800000003],[-69.89472999999992,60.85555299999993],[-69.833328,60.88999200000001],[-69.82611099999997,60.893326],[-69.778885,60.91137700000013],[-69.75695799999994,60.918884000000105],[-69.75083899999993,60.919715999999994],[-69.741104,60.9180530000001],[-69.73805199999993,60.91554300000007],[-69.74333200000001,60.90693699999997],[-69.75140399999998,60.89887999999996],[-69.750565,60.894440000000145],[-69.74610899999999,60.88472000000007],[-69.74055499999997,60.88137799999993],[-69.71055599999994,60.87387800000005],[-69.68859900000001,60.871658000000025],[-69.67721599999999,60.871101000000124],[-69.658615,60.87693800000011],[-69.64999399999988,60.8836060000001],[-69.64584399999995,60.89305100000013],[-69.64388999999994,60.90332000000001],[-69.64916999999991,60.913879000000065],[-69.65556300000003,60.9222180000001],[-69.67166099999992,60.93443300000001],[-69.68083199999995,60.943047000000035],[-69.68859900000001,60.951660000000004],[-69.68943799999988,60.95610000000005],[-69.68971299999998,60.96166199999999],[-69.68055700000002,61.01415999999995],[-69.67944299999994,61.01944000000003],[-69.67666599999995,61.02555100000012],[-69.65666199999993,61.053604000000064],[-69.65388499999995,61.05693800000006],[-69.61305199999993,61.07916300000005],[-69.59999099999999,61.081940000000145],[-69.55416899999994,61.08055099999996],[-69.52860999999996,61.07638500000007],[-69.51972999999992,61.07332600000012],[-69.51445000000001,61.06944299999998],[-69.51139799999993,61.06610100000006],[-69.50834700000001,61.06082200000009],[-69.49276700000001,61.03193700000003],[-69.468887,60.99499500000002],[-69.46528599999994,60.990273000000116],[-69.45361300000002,60.974991000000045],[-69.36805700000002,60.903046000000074],[-69.368607,60.811104],[-69.37193300000001,60.80443600000001],[-69.38055400000002,60.79471600000011],[-69.38667299999997,60.79055000000005],[-69.40444899999994,60.783332999999914],[-69.42138699999992,60.77804600000002],[-69.43859899999995,60.77499400000005],[-69.49665799999997,60.76444200000009],[-69.53306599999996,60.757217000000026],[-69.59167500000001,60.73915899999997],[-69.61582900000002,60.730270000000075],[-69.708618,60.68693500000012],[-69.71610999999996,60.68277000000012],[-69.71055599999994,60.67527000000007],[-69.70500199999998,60.67193600000007],[-69.695831,60.663879000000065],[-69.656387,60.59554300000008],[-69.65417499999995,60.584991000000116],[-69.65417499999995,60.58138300000002],[-69.65695199999993,60.574715000000026],[-69.6875,60.551383999999985],[-69.69360399999994,60.54694400000011],[-69.70222499999988,60.54444099999995],[-69.74861099999998,60.53971900000005],[-69.79777499999994,60.53443900000002],[-69.8138889999999,60.530548000000124],[-69.82223499999998,60.52777100000003],[-69.82611099999997,60.52555100000001],[-69.82444800000002,60.522490999999945],[-69.78750600000001,60.480545000000006],[-69.78443900000002,60.47804300000007],[-69.77833599999997,60.47526600000003],[-69.76222200000001,60.47026800000003],[-69.74888599999997,60.4616620000001],[-69.72166400000003,60.368881000000044],[-69.72250400000001,60.36415899999997],[-69.72778299999999,60.35193600000008],[-69.74444599999998,60.34054600000002],[-69.75195300000001,60.33638000000013],[-69.75666799999993,60.331940000000145],[-69.764725,60.32360799999998],[-69.76695299999994,60.31832899999995],[-69.76806599999986,60.31221000000011],[-69.764725,60.307495000000074],[-69.758896,60.30471000000006],[-69.69638099999997,60.278877000000136],[-69.60638399999999,60.23276500000003],[-69.6052699999999,60.2227630000001],[-69.60583500000001,60.21859699999999],[-69.61000100000001,60.208327999999995],[-69.61416600000001,60.20249200000006],[-69.636978,60.179047000000025],[-69.60194399999995,60.18305200000009],[-69.59416199999998,60.18082400000014],[-69.593887,60.17582700000003],[-69.60360699999995,60.10305000000011],[-69.62471,60.06749700000012],[-69.63694800000002,60.065268999999944],[-69.70666499999999,60.05749500000013],[-69.83721899999995,60.019713999999965],[-69.89222699999993,59.99971800000003],[-70.21722399999993,60.00721699999997],[-70.2963939999999,60.01119600000004],[-70.33612099999993,60.0044400000001],[-70.48805199999987,59.99360700000011],[-70.50500499999993,59.99249300000014],[-70.53472899999997,59.99193600000007],[-70.55694599999993,59.99276700000007],[-70.57972699999993,59.99471299999993],[-70.59306299999997,59.99665800000014],[-70.77084400000001,60.02804600000013],[-70.94583099999994,60.06304899999998],[-70.900284,60.04027600000006],[-70.631104,59.98582499999998],[-70.61054999999993,59.98082000000011],[-70.58500700000002,59.97193100000004],[-70.56695599999995,59.968597000000045],[-70.50723299999999,59.96665999999999],[-70.47582999999997,59.96832300000011],[-70.33805799999999,59.97637900000001],[-70.23693800000001,59.986938000000066],[-70.22721899999993,59.98665599999998],[-70.218613,59.98416099999997],[-70.197495,59.974158999999986],[-70.16471899999999,59.962494000000106],[-70.112503,59.949715000000026],[-70.08612099999999,59.94638100000009],[-70.06138599999997,59.94499200000007],[-70.04998799999987,59.94526700000006],[-70.0308379999999,59.94804399999998],[-69.947769,59.95888500000012],[-69.758896,59.96776600000004],[-69.726944,59.96360800000008],[-69.71888699999994,59.95971700000001],[-69.60055499999987,59.833054000000004],[-69.60555999999991,59.77721400000013],[-69.61000100000001,59.72860000000014],[-69.54083300000002,59.671104000000014],[-69.60499599999997,59.588325999999995],[-69.61332699999997,59.588325999999995],[-69.62777699999998,59.58387800000003],[-69.65888999999999,59.572495],[-69.67944299999994,59.563605999999936],[-69.69804399999998,59.553047000000106],[-69.718613,59.537773000000016],[-69.72972099999993,59.52777100000003],[-69.74833699999994,59.50999500000006],[-69.75944500000003,59.49388099999999],[-69.76112399999994,59.484161000000086],[-69.75944500000003,59.48110200000008],[-69.756393,59.47860000000003],[-69.72833300000002,59.47971300000012],[-69.703888,59.481934000000024],[-69.69860799999992,59.48137700000012],[-69.697495,59.480545000000006],[-69.66944899999993,59.455551000000014],[-69.66583299999996,59.45165999999995],[-69.64944500000001,59.42887900000011],[-69.64527900000002,59.419159000000036],[-69.63166799999988,59.37776900000006],[-69.63137799999993,59.374992000000134],[-69.63999899999988,59.36110700000006],[-69.64639299999999,59.35888700000004],[-69.67777999999993,59.356941000000006],[-69.73666400000002,59.345267999999976],[-69.74415599999998,59.343323],[-69.75778200000002,59.330826],[-69.75834700000001,59.32027399999998],[-69.75111400000003,59.311104000000114],[-69.74694799999986,59.30777000000012],[-69.73860199999996,59.30526699999996],[-69.64500399999991,59.29833200000013],[-69.631104,59.29888199999999],[-69.62666300000001,59.29972100000009],[-69.61639399999996,59.30443600000012],[-69.55027799999999,59.32972000000012],[-69.445831,59.35443900000007],[-69.43582200000003,59.3555530000001],[-69.41250600000001,59.35499599999997],[-69.25944500000003,59.32666000000006],[-69.24972499999996,59.32360799999998],[-69.23832700000003,59.25972000000013],[-69.23500100000001,59.23943300000002],[-69.23472599999997,59.23387900000006],[-69.23805199999993,59.22943100000009],[-69.24444599999998,59.224433999999974],[-69.28582799999992,59.208327999999995],[-69.36639400000001,59.19082600000013],[-69.37388599999997,59.18943000000007],[-69.40499899999998,59.19026900000006],[-69.41915899999998,59.192490000000134],[-69.42027299999995,59.19609800000006],[-69.41749600000003,59.202217000000076],[-69.41444399999995,59.21249400000005],[-69.41665599999999,59.21971100000002],[-69.420837,59.22304500000001],[-69.42971799999992,59.22470900000002],[-69.439438,59.224433999999974],[-69.44860799999998,59.2227630000001],[-69.47027600000001,59.21388200000001],[-69.51222200000001,59.19276400000007],[-69.53056299999997,59.18221299999999],[-69.5375059999999,59.17249300000009],[-69.54028299999999,59.166382],[-69.54110700000001,59.16165900000004],[-69.53721599999994,59.12304700000004],[-69.53306599999996,59.110825000000034],[-69.52778599999999,59.10665899999998],[-69.52055399999989,59.10443900000013],[-69.51139799999993,59.103324999999984],[-69.50556899999992,59.10416399999997],[-69.49499499999996,59.109993000000145],[-69.48443600000002,59.121376],[-69.474716,59.12804399999993],[-69.46305799999999,59.12943300000012],[-69.45388799999995,59.128326000000015],[-69.38417099999998,59.11888099999993],[-69.36749299999991,59.11638600000009],[-69.35972599999997,59.11277000000007],[-69.34916699999991,59.10499600000003],[-69.34527600000001,59.09554300000002],[-69.34416199999998,59.09110300000003],[-69.35278299999999,59.08082600000006],[-69.43194599999998,59.025269000000094],[-69.46611000000001,59.044159000000036],[-69.49333199999995,59.037498000000085],[-69.47528099999994,58.97193100000004],[-69.45750399999991,58.915824999999984],[-69.45472699999999,58.90638000000007],[-69.45388799999995,58.89582800000011],[-69.45417799999996,58.89222000000001],[-69.45639,58.884163],[-69.46000699999996,58.878876000000105],[-69.5475009999999,58.808043999999995],[-69.55749500000002,58.80360399999995],[-69.58778399999994,58.79666099999997],[-69.61111499999998,58.792220999999984],[-69.656387,58.787773000000016],[-69.67083699999995,58.792220999999984],[-69.68083199999995,58.800269999999955],[-69.71194499999996,58.84887700000007],[-69.71472199999994,58.85833000000008],[-69.71610999999996,58.86471599999999],[-69.702789,58.876381000000094],[-69.67222600000002,58.89138000000014],[-69.66861,58.89943700000009],[-69.66833499999996,58.90277100000009],[-69.66833499999996,58.92582700000014],[-69.67166099999992,58.930550000000096],[-69.70944199999997,58.972762999999986],[-69.84834299999994,59.04721799999999],[-69.86527999999993,59.05277300000006],[-69.86915599999992,59.05304699999999],[-69.872772,59.05082700000003],[-69.87388599999997,59.041107000000125],[-69.87416099999996,59.03416399999992],[-69.87388599999997,59.02915999999999],[-69.86555499999997,58.977768000000026],[-69.83277900000002,58.95166000000006],[-69.81582600000002,58.82388300000008],[-69.97277799999989,58.80860100000007],[-70.15361000000001,58.777488999999946],[-70.15888999999999,58.76110799999998],[-70.04972800000002,58.743607],[-69.974716,58.75555400000013],[-69.931107,58.733047000000056],[-69.91055299999994,58.68804200000011],[-69.864441,58.61749300000014],[-69.86166399999996,58.61499800000013],[-69.81889299999995,58.588599999999985],[-69.81304899999992,58.58915700000006],[-69.79943799999995,58.59887700000013],[-69.79333500000001,58.603882],[-69.72444199999995,58.66888399999999],[-69.625,58.7438810000001],[-69.608047,58.754714999999976],[-69.58168,58.765831000000105],[-69.57084700000001,58.769440000000145],[-69.54472399999997,58.77332300000006],[-69.50750700000003,58.77471200000008],[-69.49888599999986,58.77860299999992],[-69.44554099999988,58.80832700000013],[-69.41888399999988,58.825553999999954],[-69.41166699999997,58.830276000000026],[-69.41027799999995,58.83998900000006],[-69.40583800000002,58.85027300000013],[-69.39472999999992,58.856659000000036],[-69.38194299999992,58.86138199999999],[-69.34889199999998,58.87165800000008],[-69.27917500000001,58.888046000000145],[-69.15388499999995,58.89999399999999],[-69.12998999999996,58.901657000000114],[-69.098343,58.8991620000001],[-69.03167699999989,58.893326],[-68.99221799999998,58.883880999999974],[-68.84167500000001,58.891106000000036],[-68.756958,58.91249099999999],[-68.65638699999994,58.90026900000004],[-68.63751200000002,58.89666],[-68.60166899999996,58.88582600000012],[-68.39639299999999,58.81610100000012],[-68.39068600000002,58.81170700000001],[-68.36054999999993,58.781936999999914],[-68.35583500000001,58.774437000000034],[-68.35777299999995,58.76471700000013],[-68.360275,58.75943799999999],[-68.36639399999996,58.68749200000008],[-68.34584000000001,58.626937999999996],[-68.323059,58.58526599999999],[-68.2908329999999,58.54110700000001],[-68.21665999999993,58.490829000000076],[-68.20973200000003,58.46249400000005],[-68.20472699999999,58.45332300000007],[-68.20306399999998,58.44165800000002],[-68.20417800000001,58.43693500000006],[-68.22694399999995,58.37638099999998],[-68.24472000000003,58.33776899999998],[-68.25666799999999,58.32360799999998],[-68.28582799999992,58.294998000000135],[-68.28999299999992,58.28916200000009],[-68.30915799999991,58.25332600000007],[-68.32250999999997,58.22693600000008],[-68.34584000000001,58.16999100000004],[-68.34805299999994,58.159714000000065],[-68.34777799999995,58.15387700000008],[-68.34416199999998,58.14166300000005],[-68.341385,58.133331000000055],[-68.34416199999998,58.12748700000009],[-68.35055499999993,58.12193300000007],[-68.46665999999999,58.04554699999994],[-68.47721899999993,58.03999299999998],[-68.50361599999991,58.03138000000001],[-68.52860999999996,58.029434000000094],[-68.72988900000001,57.99971800000003],[-68.87416100000002,57.969154],[-69.12721299999998,57.89943699999992],[-69.13500999999991,57.89694200000008],[-69.18138099999999,57.878044000000045],[-69.20249899999999,57.86859900000013],[-69.22138999999993,57.85888699999998],[-69.26251199999996,57.83360300000004],[-69.35777300000001,57.77416200000005],[-69.36904899999996,57.76525100000009],[-69.36389200000002,57.765830999999935],[-69.33972199999994,57.77332300000006],[-69.30499299999997,57.78665900000004],[-69.29834,57.78943600000014],[-69.21028099999995,57.8294370000001],[-69.19082599999996,57.84054600000002],[-69.172775,57.851661999999976],[-69.1119379999999,57.88582599999995],[-68.96528599999988,57.933876],[-68.90417500000001,57.94971500000008],[-68.69572399999998,57.9877130000001],[-68.67889400000001,57.9897160000001],[-68.66738899999996,57.99038300000001],[-68.63472000000002,57.988879999999995],[-68.62239099999988,57.98937999999998],[-68.54527299999995,58.000549000000035],[-68.49583399999995,58.013329],[-68.41694599999994,58.034439000000134],[-68.40417500000001,58.03971900000005],[-68.31361400000003,58.103049999999996],[-68.30888399999998,58.10804700000011],[-68.30499299999991,58.11388400000004],[-68.30249000000003,58.119155999999975],[-68.29998799999993,58.12748700000009],[-68.30027799999988,58.13249200000013],[-68.30471799999998,58.14638499999995],[-68.30555700000002,58.14999399999999],[-68.30722000000003,58.16443600000014],[-68.306107,58.181107],[-68.30526700000001,58.18610400000006],[-68.30110200000001,58.19804399999998],[-68.29527300000001,58.209991000000116],[-68.28416400000003,58.21998600000006],[-68.23083500000001,58.26888300000013],[-68.18582200000003,58.36054999999999],[-68.16833500000001,58.414711000000125],[-68.16665599999999,58.424438000000066],[-68.166946,58.435822000000144],[-68.16999800000002,58.446655000000135],[-68.172775,58.454994],[-68.17805499999997,58.46971100000013],[-68.17832900000002,58.48027000000002],[-68.17138699999992,58.48999000000009],[-68.13917500000002,58.521103000000096],[-68.13500999999985,58.52416200000005],[-68.01306199999999,58.57360799999992],[-68.00334199999998,58.576385000000016],[-67.98332199999999,58.57305100000002],[-67.96916199999998,58.565826000000015],[-67.95916699999998,58.55804400000005],[-67.896118,58.50054899999998],[-67.89389,58.49665800000008],[-67.89222699999999,58.49137900000011],[-67.891953,58.483604000000014],[-67.89500399999991,58.47693600000002],[-67.90110800000002,58.46720900000008],[-67.908051,58.45804600000008],[-67.914444,58.45332300000007],[-67.91944899999993,58.445540999999935],[-67.920837,58.43943000000007],[-67.92416399999996,58.41276600000009],[-67.92332499999992,58.40304600000002],[-67.90833999999995,58.360825000000034],[-67.906113,58.356941000000006],[-67.90361000000001,58.35360700000001],[-67.89334099999996,58.34665699999999],[-67.86805699999996,58.33221400000008],[-67.86416600000001,58.32888000000008],[-67.85749800000002,58.32027399999998],[-67.89450099999993,58.28716300000008],[-67.89665999999988,58.28115800000006],[-67.90449499999994,58.26766200000003],[-67.91332999999992,58.25616100000002],[-67.91934199999997,58.250159999999994],[-67.92633099999995,58.245491000000015],[-67.93482999999998,58.241161000000034],[-67.946999,58.235992000000124],[-67.97499099999999,58.22099300000002],[-68.04750100000001,58.170547000000056],[-68.06582600000002,58.1594310000001],[-68.09583999999995,58.13860299999999],[-68.10110500000002,58.13304900000003],[-68.12748699999992,58.084717000000126],[-68.12998999999996,58.07888000000014],[-68.12832599999996,58.073608000000036],[-68.12554899999998,58.071105999999986],[-68.11582899999996,58.071938000000046],[-68.10110500000002,58.07777399999998],[-68.00666799999993,58.131935000000055],[-67.99166899999994,58.146103000000096],[-67.97833300000002,58.16360500000013],[-67.87694499999998,58.24305000000004],[-67.80139200000002,58.296661000000086],[-67.81555199999997,58.30888399999998],[-67.82389799999987,58.31721500000003],[-67.82917800000001,58.32638500000007],[-67.83056599999992,58.33138300000007],[-67.828888,58.349716000000114],[-67.81973299999987,58.39360800000003],[-67.81723,58.40526600000004],[-67.81332399999991,58.416100000000085],[-67.78750599999995,58.46443900000003],[-67.78306600000002,58.46804800000007],[-67.7750089999999,58.47109999999998],[-67.76445000000001,58.47054300000008],[-67.72389199999998,58.458885000000066],[-67.66944899999999,58.431938000000116],[-67.66749600000003,58.42748999999998],[-67.66999800000002,58.42193599999996],[-67.67999299999997,58.41276600000009],[-67.69193999999999,58.404433999999924],[-67.69694500000003,58.399437000000034],[-67.70472699999999,58.38916000000006],[-67.737213,58.326942000000145],[-67.73889200000002,58.32083100000011],[-67.737213,58.31554399999999],[-67.73249799999996,58.311661000000015],[-67.69804399999992,58.28499599999998],[-67.66082799999998,58.26444200000003],[-67.64611799999994,58.25332600000007],[-67.64277599999991,58.248604],[-67.65249599999999,58.21471400000013],[-67.65417500000001,58.21054800000002],[-67.72860700000001,57.97665400000005],[-67.71389799999986,57.923050000000046],[-67.71028100000001,57.97554800000006],[-67.70834399999995,57.98249100000004],[-67.65943899999996,58.11027500000006],[-67.65360999999996,58.122765000000015],[-67.64527899999996,58.13443799999999],[-67.591949,58.200829],[-67.57833900000003,58.21527100000003],[-67.56610099999995,58.223602000000085],[-67.48138399999993,58.27388000000008],[-67.46665999999999,58.27971600000012],[-67.33277900000002,58.31610100000006],[-67.17222599999991,58.37638099999998],[-67.16860999999994,58.3780440000001],[-67.15194699999995,58.376656000000025],[-67.13751200000002,58.373046999999985],[-67.11665299999999,58.36332700000008],[-67.10694899999999,58.3555530000001],[-67.09555099999994,58.348877000000016],[-67.09056099999998,58.35054800000006],[-66.995834,58.43943000000007],[-66.991669,58.445267],[-66.98998999999998,58.45138500000013],[-66.98666400000002,58.45804600000008],[-66.978882,58.468323000000055],[-66.95140100000003,58.49860399999994],[-66.94415300000003,58.50193799999994],[-66.92805499999997,58.50166300000012],[-66.88722199999995,58.4855500000001],[-66.87693799999994,58.479156000000046],[-66.87554899999986,58.47387700000007],[-66.87805200000003,58.46859699999999],[-66.80110199999996,58.47360200000003],[-66.62971499999998,58.50360900000004],[-66.65167199999996,58.54277000000013],[-66.551941,58.71138000000002],[-66.46972700000003,58.81638300000003],[-66.465012,58.81999200000001],[-66.38861099999997,58.85054800000012],[-66.36665299999993,58.848044999999956],[-66.35777300000001,58.84609999999998],[-66.34999099999993,58.84304800000007],[-66.35028099999994,58.83721200000002],[-66.34889199999998,58.83194000000009],[-66.34416199999993,58.82777399999998],[-66.11471599999993,58.69971499999997],[-66.10611,58.68498999999997],[-66.077225,58.654434000000094],[-66.07223499999992,58.650825999999995],[-66.06777999999991,58.64888000000008],[-66.05416899999994,58.64610299999998],[-65.94554099999993,58.61693600000007],[-65.93888899999996,58.61388399999993],[-65.93582200000003,58.60971800000004],[-65.93582200000003,58.604713000000004],[-65.93859899999995,58.594437000000084],[-65.94193999999999,58.58277099999992],[-66.02194199999997,58.48693800000001],[-66.08944699999995,58.365273],[-66.091385,58.358887000000095],[-66.091385,58.35416400000008],[-66.073059,58.32721700000002],[-66.06555200000003,58.32027399999998],[-66.05888399999998,58.32027399999998],[-66.05277999999993,58.34693900000002],[-66.05139200000002,58.35249300000004],[-66.04554699999994,58.363052000000096],[-66.04167199999995,58.368050000000096],[-66.03056299999997,58.37638099999998],[-66.02305599999994,58.379714999999976],[-66.01501499999995,58.381935],[-65.98805199999998,58.38443799999999],[-65.979172,58.38610799999992],[-65.97277799999995,58.38804600000009],[-65.965012,58.39193699999993],[-65.9602809999999,58.39610300000004],[-65.92027299999995,58.44582400000013],[-65.920837,58.449432],[-65.92666600000001,58.45609999999999],[-65.93221999999997,58.458885000000066],[-65.94027699999998,58.46166199999993],[-65.96166999999997,58.46471400000007],[-65.98055999999991,58.47026800000003],[-65.98249799999996,58.4741590000001],[-65.98194899999993,58.480545000000006],[-65.98055999999991,58.48304700000011],[-65.88751200000002,58.57777400000003],[-65.88417099999998,58.580826000000116],[-65.87693799999988,58.58194000000009],[-65.87998999999996,58.62721300000004],[-65.94554099999993,58.66526799999997],[-66.03222699999998,58.710548000000074],[-66.10139499999997,58.77110300000004],[-66.103882,58.77360499999992],[-66.081955,58.80971500000004],[-66.03721599999994,58.85166200000009],[-65.99011199999995,58.85266100000001],[-65.98495499999996,58.85149400000006],[-65.95227799999986,58.83682299999998],[-65.84583999999995,58.826660000000004],[-65.839722,58.827217000000076],[-65.79750100000001,58.847488000000055],[-65.79277000000002,58.85332500000004],[-65.79028299999999,58.85777300000001],[-65.78944399999995,58.86193800000001],[-65.791382,58.865829000000076],[-65.79499800000002,58.86693600000001],[-65.80610699999994,58.866660999999965],[-65.833328,58.86471599999999],[-65.86193800000001,58.86332700000003],[-65.88027999999991,58.864441],[-65.94044500000001,58.87910500000004],[-65.952606,58.88126799999992],[-65.95811500000002,58.88293500000003],[-65.96477500000003,58.88744000000008],[-65.96827699999989,58.893440000000055],[-65.98860200000001,58.90360300000003],[-65.885559,59.00193800000005],[-65.77749599999999,59.029990999999995],[-65.69526699999989,59.04361000000006],[-65.67304999999999,59.046104000000014],[-65.660278,59.044159000000036],[-65.65417499999995,59.042496000000085],[-65.6346739999999,59.03321799999998],[-65.63249200000001,59.031216000000086],[-65.61416600000001,59.01944000000009],[-65.56500199999994,58.99360700000011],[-65.51445000000001,58.98471800000004],[-65.5,58.98333000000014],[-65.49499499999996,58.98471800000004],[-65.49333200000001,58.98749500000014],[-65.49499499999996,58.99193600000007],[-65.50944499999997,59.008331],[-65.51640299999997,59.01082600000001],[-65.533615,59.014717000000076],[-65.54305999999997,59.01554900000002],[-65.55305499999997,59.017494],[-65.56082200000003,59.020827999999995],[-65.57138800000001,59.03910800000011],[-65.57289100000003,59.04410600000011],[-65.570221,59.045773],[-65.56805400000002,59.04677600000002],[-65.53277600000001,59.063881000000094],[-65.51861600000001,59.06666600000011],[-65.51028400000001,59.066940000000045],[-65.50639299999995,59.06638299999997],[-65.49249299999997,59.061378000000104],[-65.45472699999999,59.0422210000001],[-65.34028599999999,59.03833000000003],[-65.33056599999998,59.03804800000012],[-65.32472199999995,59.0388870000001],[-65.31750499999998,59.04138200000011],[-65.31973299999999,59.04721799999999],[-65.333618,59.05999000000003],[-65.34472699999998,59.06471299999998],[-65.35417199999995,59.06749700000012],[-65.53355399999992,59.07766300000014],[-65.53687999999994,59.074665000000095],[-65.54672199999999,59.07183100000009],[-65.56438399999996,59.07016399999998],[-65.57705699999997,59.06999600000012],[-65.58406100000002,59.07099900000014],[-65.58656300000001,59.072159000000056],[-65.651947,59.07916300000011],[-65.71501199999994,59.14833100000004],[-65.71806299999997,59.153046000000074],[-65.74082900000002,59.21471400000007],[-65.74249299999991,59.219437000000084],[-65.74305699999996,59.228043000000014],[-65.74499500000002,59.25972000000013],[-65.74471999999997,59.263054000000125],[-65.74305699999996,59.26583099999999],[-65.73194899999999,59.26906600000001],[-65.70666499999999,59.26832600000006],[-65.68527199999988,59.26444200000003],[-65.67610200000001,59.261108000000036],[-65.646118,59.244713000000104],[-65.58750900000001,59.20249200000012],[-65.612503,59.23749500000008],[-65.61471599999987,59.243607000000054],[-65.61416600000001,59.24694100000005],[-65.58168,59.37721300000004],[-65.57250999999997,59.378601],[-65.57000699999998,59.37832600000013],[-65.551941,59.37276500000007],[-65.49916099999996,59.352219000000105],[-65.48332199999993,59.345542999999964],[-65.47610500000002,59.33888200000007],[-65.47111499999994,59.32749200000001],[-65.45333899999997,59.31693999999999],[-65.383896,59.28166199999998],[-65.372772,59.276657000000114],[-65.36665299999987,59.27499399999999],[-65.36111499999987,59.274712000000136],[-65.35722399999997,59.277214000000015],[-65.35665899999992,59.28276800000003],[-65.43777499999999,59.39388300000002],[-65.49526999999989,59.433876000000055],[-65.55943300000001,59.48165899999998],[-65.56138599999997,59.48610700000012],[-65.55749500000002,59.48777000000007],[-65.54943800000001,59.48943300000002],[-65.54222099999998,59.48999000000009],[-65.36000099999995,59.48165899999998],[-65.347778,59.48082000000005],[-65.260559,59.466385000000116],[-65.19766199999998,59.45049300000005],[-65.195831,59.447659000000044],[-65.176941,59.440269],[-65.17027300000001,59.434433000000126],[-65.141953,59.41582500000004],[-65.12666300000001,59.40776800000009],[-65.11999500000002,59.40526600000004],[-65.060272,59.3844380000001],[-65.04138199999994,59.378601],[-65.01777599999997,59.373046999999985],[-65.00584400000002,59.37193300000001],[-64.995544,59.372490000000084],[-64.98332199999993,59.37638099999998],[-65.03138699999994,59.392769000000044],[-65.07583599999998,59.40804300000008],[-65.11111499999998,59.42054699999994],[-65.11888099999999,59.42388200000005],[-65.14111300000002,59.434433000000126],[-65.14723199999997,59.43804200000011],[-65.15139799999997,59.44304699999998],[-65.15638699999994,59.45165999999995],[-65.15899699999989,59.46082700000011],[-65.16194200000001,59.466660000000104],[-65.16805999999997,59.47054300000002],[-65.22084000000001,59.48832700000014],[-65.29083299999996,59.50666000000001],[-65.30860899999993,59.50999500000006],[-65.33000199999987,59.50943799999999],[-65.38890100000003,59.50750000000005],[-65.41166699999997,59.50943799999999],[-65.41999800000002,59.516936999999984],[-65.46278399999989,59.57804900000002],[-65.49415599999998,59.626937999999996],[-65.50167799999991,59.63888500000013],[-65.52778599999999,59.71693399999998],[-65.50195299999996,59.7472150000001],[-65.43331899999998,59.79804999999993],[-65.37499999999994,59.828049000000135],[-65.33555599999994,59.84665700000005],[-65.33389299999993,59.84721400000012],[-65.323624,59.84554300000008],[-65.23611499999998,59.81938199999996],[-65.21945199999999,59.81437700000009],[-65.20594799999998,59.80854800000009],[-65.20344499999993,59.80688100000003],[-65.19877599999995,59.80287900000002],[-65.19528199999996,59.79721800000004],[-65.158615,59.78221100000002],[-65.15278599999999,59.779990999999995],[-65.136124,59.776657],[-65.05305499999997,59.76361100000008],[-65.03306599999996,59.76138300000014],[-65.00666799999999,59.76027700000009],[-64.98860200000001,59.76194000000004],[-64.98388699999998,59.76277199999993],[-64.98306300000002,59.76416000000006],[-64.98916599999995,59.765831000000105],[-65.05555699999996,59.7783280000001],[-65.13276699999994,59.79694400000011],[-65.16139199999998,59.817490000000134],[-65.19939399999993,59.83565900000008],[-65.20271300000002,59.83732600000002],[-65.20605499999999,59.8404920000001],[-65.23083500000001,59.88054699999998],[-65.23194899999999,59.88582600000012],[-65.22610499999996,59.888603000000046],[-65.20639,59.888603000000046],[-65.14334099999991,59.94999700000011],[-65.12609899999995,60.011108000000036],[-65.11000100000001,60.043052999999986],[-65.02972399999993,60.07721700000002],[-64.92111199999994,60.19499200000001],[-64.83416699999998,60.32305100000008],[-64.83222999999992,60.32860599999998],[-64.83444199999997,60.334434999999985],[-64.84638999999993,60.345543000000134],[-64.85833699999995,60.35249299999998],[-64.85722399999997,60.35943600000002],[-64.854446,60.36110700000006],[-64.846115,60.362769999999955],[-64.83555599999994,60.36332700000008],[-64.65306099999998,60.34693900000002],[-64.6416779999999,60.34471100000002],[-64.61027499999994,60.33638000000013],[-64.57667499999997,60.322768999999994],[-64.53324900000001,60.302498000000014],[-64.47560099999998,60.281609],[-64.46691900000002,60.278602999999976],[-64.43109099999998,60.25810599999994],[-64.432594,60.25560800000005],[-64.43460099999993,60.255108000000064],[-64.44609100000002,60.254771999999946],[-64.45309399999991,60.25627100000003],[-64.46242499999994,60.25927399999995],[-64.47759199999996,60.26560999999998],[-64.47721899999999,60.260551000000135],[-64.55749500000002,60.28110500000008],[-64.58029199999993,60.28611000000012],[-64.61305199999998,60.28943600000014],[-64.64306599999998,60.28749800000003],[-64.72111499999994,60.261108000000036],[-64.72582999999997,60.25833100000011],[-64.75805699999995,60.23582500000009],[-64.75944500000003,60.231102000000135],[-64.75250199999988,60.22860000000003],[-64.74526999999995,60.22832500000004],[-64.73693799999995,60.23054500000006],[-64.68554699999999,60.250832000000116],[-64.646118,60.26583099999999],[-64.63417099999998,60.26888300000007],[-64.59638999999999,60.26693700000004],[-64.57444800000002,60.2649990000001],[-64.554169,60.26277200000004],[-64.53639199999992,60.2586060000001],[-64.42167699999999,60.215656000000024],[-64.41950199999997,60.213661],[-64.376938,60.16054500000001],[-64.46501199999994,60.084991],[-64.46916199999987,60.08277099999998],[-64.476944,60.07972000000001],[-64.49137899999994,60.07471499999991],[-64.50445599999995,60.07249500000012],[-64.515015,60.071938000000046],[-64.65499899999992,60.053604000000064],[-64.80471799999998,60.00721699999997],[-64.8125,60.004166],[-64.82333399999999,59.99777200000011],[-64.82667500000002,59.99471299999993],[-64.82749899999999,59.98638200000005],[-64.82000700000003,59.97943100000009],[-64.811935,59.9783250000001],[-64.79666099999997,59.980270000000075],[-64.73527499999994,60.00110600000011],[-64.4908289999999,60.05943300000007],[-64.41027799999995,60.11110700000012],[-64.39639299999999,60.12193300000001],[-64.39222699999999,60.124161000000015],[-64.38583399999993,60.12526700000001],[-64.37999000000002,60.12526700000001],[-64.37388599999997,60.123604000000114],[-64.36776699999996,60.11971300000005],[-64.366104,60.117493000000024],[-64.36500499999994,60.109993000000145],[-64.37461100000002,60.03382900000008],[-64.37528199999986,60.028324000000055],[-64.39472999999998,59.941658000000075],[-64.39695699999993,59.93776700000001],[-64.40888999999999,59.932495000000074],[-64.45056199999993,59.92527000000001],[-64.46221899999995,59.92249300000009],[-64.49194299999999,59.91360500000013],[-64.506958,59.907211000000075],[-64.514725,59.9019320000001],[-64.51390100000003,59.896103000000096],[-64.506393,59.891936999999984],[-64.499435,59.89166300000005],[-64.48194899999987,59.89471400000008],[-64.37609899999995,59.9180530000001],[-64.36776699999996,59.92027300000012],[-64.36332700000003,59.92249300000009],[-64.36054999999993,59.924995000000024],[-64.32028199999996,60.004107999999974],[-64.32211299999994,60.006439000000114],[-64.32412,60.01160400000009],[-64.32428699999997,60.014107000000024],[-64.32211299999994,60.02460500000001],[-64.32044999999994,60.027270999999985],[-64.31744399999991,60.028103000000044],[-64.26501499999995,60.0480500000001],[-64.21665999999993,60.039993000000095],[-64.17361499999998,60.028328000000045],[-64.166946,60.02499400000005],[-64.16082799999998,60.01638800000012],[-64.150284,59.985268000000076],[-64.150284,59.982208000000014],[-64.16583300000002,59.85054800000012],[-64.17721599999993,59.785552999999936],[-64.1808319999999,59.7816620000001],[-64.19305399999996,59.775825999999995],[-64.20249899999993,59.77416199999999],[-64.22000099999997,59.77416199999999],[-64.23666400000002,59.77971600000001],[-64.24472000000003,59.784996000000035],[-64.25140399999998,59.78749800000014],[-64.25750700000003,59.78943600000008],[-64.26194800000002,59.789161999999976],[-64.26445000000001,59.78749800000014],[-64.266663,59.77915999999999],[-64.261124,59.76471700000013],[-64.25500499999993,59.756660000000124],[-64.21305799999999,59.7177660000001],[-64.197769,59.7052690000001],[-64.17388899999997,59.688598999999954],[-64.16389499999997,59.68415800000008],[-64.15167200000002,59.68082400000009],[-64.12998999999996,59.676659000000086],[-64.05776999999995,59.62526700000012],[-64.11694299999994,59.517494000000056],[-64.04750100000001,59.549721000000034],[-64.04083300000002,59.55360400000001],[-64.03332499999999,59.56388099999998],[-64.0344389999999,59.57360800000009],[-64.0344389999999,59.58277100000009],[-64.02972399999987,59.599433999999974],[-64.024719,59.60999300000003],[-64.01945499999994,59.61859900000013],[-64.01112399999994,59.62499200000008],[-64.00473,59.626381000000094],[-63.99722300000002,59.62665600000014],[-63.90055099999995,59.61998700000004],[-63.885559,59.618881000000044],[-63.87610599999999,59.615829000000076],[-63.865554999999915,59.60999300000003],[-63.73166699999996,59.526099999999985],[-63.724166999999966,59.5177690000001],[-63.72249599999998,59.51388500000007],[-63.723884999999996,59.50666000000001],[-63.785278000000005,59.426102000000014],[-63.80783799999995,59.420437000000106],[-63.81017299999996,59.41944100000012],[-63.814502999999945,59.418101999999976],[-63.86639399999996,59.421104000000014],[-63.90694400000001,59.421660999999915],[-63.947776999999974,59.41971600000011],[-64.000565,59.41443600000008],[-64.01834100000002,59.41054500000001],[-64.03332499999999,59.40665400000012],[-64.05027799999999,59.399994000000106],[-64.06111099999998,59.39388300000002],[-64.06582600000002,59.38804600000003],[-64.06221,59.38249200000007],[-64.05277999999998,59.37943300000006],[-63.805167999999924,59.36816400000009],[-63.79014599999999,59.370293000000004],[-63.786652000000004,59.371792000000084],[-63.78264999999999,59.3741260000001],[-63.75139599999994,59.37582400000008],[-63.748111999999935,59.333878000000084],[-63.75644699999998,59.30838],[-63.768280000000004,59.28788000000003],[-63.77044699999999,59.284381999999994],[-63.77344499999998,59.28221500000012],[-63.780944999999974,59.27821399999999],[-63.81416299999995,59.249435000000005],[-63.82472200000001,59.24610100000001],[-63.82549999999998,59.24437700000004],[-63.82527899999991,59.24332400000009],[-63.81388900000002,59.240829000000076],[-63.77794299999999,59.26393899999999],[-63.76677699999999,59.264275000000055],[-63.760940999999946,59.26543400000003],[-63.755942999999945,59.266773],[-63.739112999999975,59.27360500000003],[-63.730441999999925,59.28076900000002],[-63.723777999999925,59.287436999999954],[-63.71877699999993,59.293941000000075],[-63.71611399999989,59.3009340000001],[-63.71527900000001,59.303768000000105],[-63.71527900000001,59.30643800000007],[-63.71594199999987,59.30943700000006],[-63.713775999999996,59.315605000000005],[-63.71060899999986,59.318107999999995],[-63.65833299999997,59.358047],[-63.64999399999999,59.36249499999997],[-63.54305999999991,59.34804500000007],[-63.53527799999995,59.34443699999997],[-63.39333299999993,59.2649990000001],[-63.357506,59.20804600000008],[-63.35639200000003,59.204994],[-63.35805499999992,59.19804399999998],[-63.36666100000002,59.18637799999999],[-63.412773000000016,59.135826000000066],[-63.42556000000002,59.12638100000004],[-63.441108999999926,59.119438],[-63.476944,59.10443900000013],[-63.56361399999997,59.07332600000012],[-63.58000199999992,59.06749700000012],[-63.58972199999994,59.06554399999999],[-63.73139200000003,59.05627099999998],[-63.74105500000002,59.05577099999999],[-63.74872199999993,59.056934000000126],[-63.753890999999896,59.058266],[-63.76022299999994,59.06276700000012],[-63.81221799999997,59.06582600000007],[-63.934440999999936,59.081108000000086],[-63.94833399999999,59.07888000000014],[-63.966110000000015,59.07471499999997],[-63.98833499999995,59.06832900000006],[-64.045547,59.02416199999999],[-64.04722599999991,59.01944000000009],[-64.04388399999999,59.01527399999998],[-64.03944399999995,59.013885000000016],[-63.912216,59.000549000000035],[-63.80171999999999,59.013992000000144],[-63.798388999999986,59.01132999999999],[-63.766395999999986,59.0127720000001],[-63.75944499999997,59.01249700000005],[-63.73444399999994,59.01499899999999],[-63.50805700000001,59.05277300000006],[-63.38166799999988,59.09804500000013],[-63.37277199999994,59.10110499999996],[-63.365554999999915,59.10110499999996],[-63.30944099999999,59.09415400000006],[-63.29333500000001,59.091377000000136],[-63.13417099999998,59.05832700000008],[-63.12499999999994,59.055267000000015],[-63.12194099999999,59.0513840000001],[-63.122772,59.04554700000011],[-63.12694499999992,59.04138200000011],[-63.13333099999994,59.03804800000012],[-63.15943899999991,59.029990999999995],[-63.17527799999999,59.026939000000084],[-63.185272,59.026381999999955],[-63.21694200000002,59.02748900000012],[-63.23889200000002,59.03054800000007],[-63.32333399999993,59.02777100000014],[-63.336112999999955,59.02499400000005],[-63.335556,59.0219350000001],[-63.26445000000001,58.98554999999999],[-63.21388999999999,58.977211000000125],[-63.19527399999998,58.979713000000004],[-63.185272,58.980270000000075],[-63.17305799999991,58.979713000000004],[-63.16750300000001,58.97082500000005],[-63.16055299999999,58.92638400000004],[-63.16305499999993,58.92027300000012],[-63.23638900000003,58.876937999999996],[-63.313331999999946,58.861107000000004],[-63.325004999999976,58.85582700000009],[-63.31277499999999,58.853049999999996],[-63.294723999999974,58.85083000000003],[-63.19027699999998,58.854996000000085],[-63.11277799999999,58.87804399999999],[-63.03333299999997,58.873878000000104],[-62.924170999999944,58.82138100000003],[-62.918334999999956,58.817497],[-62.90694400000001,58.80471],[-62.90416700000003,58.79999500000014],[-62.84749599999998,58.69054399999999],[-62.84527600000001,58.68498999999997],[-62.84222399999999,58.669991000000095],[-62.84361299999995,58.659430999999984],[-62.84777799999995,58.65304599999996],[-62.91583299999991,58.60027299999996],[-62.97499800000003,58.57666000000006],[-63.169167000000016,58.50305200000014],[-63.334109999999896,58.455768999999975],[-63.33460999999994,58.45227100000011],[-63.33710899999994,58.448437000000126],[-63.373444000000006,58.41743500000007],[-63.38528100000002,58.41027100000008],[-63.39910900000001,58.40527300000008],[-63.486388999999974,58.37082700000002],[-63.52249899999998,58.36110700000012],[-63.53750600000001,58.35416400000008],[-63.58306099999999,58.31137800000005],[-63.58777600000002,58.30554999999998],[-63.58943899999997,58.30082700000014],[-63.584998999999925,58.29888199999999],[-63.57972699999999,58.29860699999995],[-63.571670999999924,58.29999500000008],[-63.55527499999994,58.305267000000015],[-63.53305799999998,58.31443800000011],[-63.428223,58.36904900000013],[-63.39238699999993,58.38838199999998],[-63.37855899999994,58.399044],[-63.36421999999993,58.410049000000015],[-63.35155500000002,58.41871600000002],[-63.28639199999998,58.456657000000064],[-63.28082999999998,58.459160000000054],[-63.26472499999994,58.46305100000012],[-63.241669,58.466385000000116],[-63.213615000000004,58.46943700000003],[-63.148612999999955,58.47637900000012],[-63.13277399999987,58.47721100000007],[-63.12444299999987,58.47526600000003],[-63.096947,58.46193699999998],[-63.08972199999994,58.45832799999994],[-63.08611300000001,58.454994],[-63.03750600000001,58.453048999999965],[-62.76333599999998,58.48082000000005],[-62.63666499999994,58.50138900000002],[-62.620551999999975,58.50499700000012],[-62.61000100000001,58.50388299999997],[-62.58943899999997,58.49971800000014],[-62.57361599999996,58.49388099999999],[-62.566108999999926,58.49054699999999],[-62.56138599999997,58.48749500000008],[-62.557503,58.482491000000095],[-62.556389000000024,58.47804300000013],[-62.61971999999997,58.37693800000005],[-62.61944599999998,58.310272000000055],[-62.623054999999965,58.30443600000001],[-62.63417099999998,58.29777500000006],[-62.70861100000002,58.27610000000004],[-62.77666499999998,58.26859999999999],[-62.828056000000004,58.25222000000008],[-62.661666999999966,58.26998900000001],[-62.65860700000002,58.27027100000004],[-62.65444200000002,58.27027100000004],[-62.60972599999997,58.25666000000007],[-62.597778000000005,58.25166300000001],[-62.592772999999966,58.248604],[-62.58250399999986,58.23443600000013],[-62.58111600000001,58.22193100000004],[-62.58277899999996,58.216934000000094],[-62.58444199999997,58.214439000000084],[-62.631942999999865,58.18526500000013],[-62.63805400000001,58.181938],[-62.653053,58.17527000000001],[-62.661384999999996,58.17304999999999],[-62.68916300000001,58.16999100000004],[-62.71971899999994,58.169715999999994],[-62.74027999999993,58.17193600000002],[-62.773887999999886,58.176941000000056],[-62.78388999999993,58.17665900000003],[-62.822227,58.17471300000011],[-62.84166699999997,58.1722180000001],[-62.96500400000002,58.15387700000008],[-63.01222199999995,58.13555100000008],[-63.01666299999994,58.126098999999954],[-63.023888,58.11888099999999],[-63.045279999999934,58.10888699999998],[-63.12694499999992,58.08693699999998],[-63.205558999999994,58.06582600000007],[-63.21166999999997,58.06249200000008],[-63.211388,58.06027200000011],[-63.20889299999999,58.057770000000005],[-63.19027699999998,58.05304700000005],[-63.14083899999997,58.04888200000005],[-63.146998999999994,58.03683100000001],[-63.15582999999998,58.026939000000084],[-63.16777799999994,58.02110300000004],[-63.193329000000006,58.01471700000013],[-63.26722000000001,58.007217000000026],[-63.27527599999996,58.00555400000013],[-63.30471799999998,57.996940999999936],[-63.34166699999997,57.98110200000002],[-63.34083599999997,57.97998800000005],[-63.32972699999999,57.98027000000013],[-63.15166499999998,57.993607],[-63.12888299999997,57.997772],[-63.10777999999999,58.0077740000001],[-63.101944,58.01249700000011],[-63.09888499999994,58.017769000000044],[-63.097778000000005,58.01971400000002],[-63.09833500000002,58.026939000000084],[-63.09999800000003,58.03305100000006],[-63.101944,58.036942000000124],[-63.1016689999999,58.044159000000036],[-63.097778000000005,58.052216000000044],[-63.09471899999994,58.05749500000002],[-63.089164999999866,58.06221000000005],[-62.946662999999944,58.124161000000015],[-62.940276999999924,58.12582400000014],[-62.886390999999946,58.137496999999996],[-62.83805100000001,58.144997000000046],[-62.832222,58.14527099999998],[-62.82944500000002,58.143326],[-62.77277399999997,58.12915800000013],[-62.652221999999995,58.118599000000074],[-62.64611100000002,58.119155999999975],[-62.643058999999994,58.11998699999998],[-62.61250299999995,58.137771999999984],[-62.59944200000001,58.145546000000024],[-62.560828999999956,58.156654],[-62.515838999999914,58.16915899999992],[-62.49194299999999,58.17416399999996],[-62.46665999999999,58.175552000000096],[-62.45278199999996,58.17527000000001],[-62.44805100000002,58.1722180000001],[-62.44638800000001,58.16832700000003],[-62.44777699999992,58.16415400000005],[-62.46300099999996,58.15104700000006],[-62.46966600000002,58.145718000000045],[-62.47833300000002,58.14121200000005],[-62.48616800000002,58.136547000000064],[-62.50389099999995,58.123604000000114],[-62.519447000000014,58.11193799999995],[-62.529166999999916,58.10277600000006],[-62.531386999999995,58.09526800000003],[-62.51445000000001,58.05749500000002],[-62.506392999999946,58.05526700000007],[-62.49805499999991,58.057213000000104],[-62.49138599999992,58.061378000000104],[-62.48666400000002,58.066940000000045],[-62.48444399999994,58.07222000000013],[-62.48555799999991,58.081107999999915],[-62.488051999999925,58.08610500000003],[-62.48889199999991,58.09110300000003],[-62.488051999999925,58.09665700000005],[-62.48277299999995,58.10027300000007],[-62.444827999999916,58.10672000000005],[-62.41305499999993,58.11082500000009],[-62.375,58.11277000000007],[-62.368889000000024,58.11166400000002],[-62.36389200000002,58.108604000000014],[-62.31777999999997,58.05248999999998],[-62.30750299999988,58.039161999999976],[-62.30694599999998,58.03110499999997],[-62.30972299999996,58.02860300000009],[-62.38144699999998,58.008327000000065],[-62.39411200000001,58.00365800000009],[-62.40628099999998,58.00282700000008],[-62.41311300000001,58.00365800000009],[-62.43761399999988,58.0101590000001],[-62.45044300000001,58.01199300000013],[-62.50083899999993,58.00804900000014],[-62.51916499999993,58.00694300000009],[-62.52833599999997,58.00555400000013],[-62.545279999999934,58.000549000000035],[-62.648056,57.95832800000005],[-62.65527300000002,57.95360599999998],[-62.65972099999999,57.94860100000011],[-62.672774999999945,57.929993000000024],[-62.664443999999946,57.928604000000064],[-62.65527300000002,57.929993000000024],[-62.64083899999997,57.93526499999996],[-62.636116000000015,57.938598999999954],[-62.620833999999945,57.94748700000014],[-62.611670999999944,57.95166000000006],[-62.57749899999999,57.96221200000008],[-62.53778099999988,57.97110000000009],[-62.51250499999992,57.972488],[-62.45516599999996,57.96821200000005],[-62.448001999999974,57.96770899999996],[-62.32500499999992,57.956100000000106],[-62.268332999999984,57.948875000000044],[-62.200278999999966,57.93582200000009],[-62.148888,57.97499099999993],[-62.145279000000016,57.97415900000004],[-62.12749500000001,57.968048000000124],[-62.11611199999999,57.96249399999999],[-62.08361099999996,57.94499200000013],[-62.079726999999934,57.942763999999954],[-62.072227,57.931107000000054],[-62.05972300000002,57.89777400000003],[-62.060828999999956,57.88999200000006],[-62.06277499999993,57.88665800000007],[-62.115279999999984,57.854164000000026],[-62.13194299999998,57.84276600000004],[-62.138053999999954,57.835823000000005],[-62.13916799999993,57.83194000000009],[-62.12527499999999,57.806938],[-62.12083399999989,57.80082700000008],[-62.11999500000002,57.79999499999997],[-62.10777999999999,57.789719000000105],[-62.08916499999998,57.780548000000124],[-62.085830999999985,57.77943399999998],[-62.079169999999976,57.77943399999998],[-62.061110999999926,57.78193699999997],[-62.04639400000002,57.78582800000004],[-62.033332999999914,57.787216000000114],[-62.01805899999994,57.78360700000013],[-61.996666000000005,57.77221700000007],[-61.99138599999992,57.7677690000001],[-61.88999899999999,57.66638200000011],[-61.883331,57.64554600000008],[-61.88305700000001,57.63749700000011],[-61.88444499999997,57.62693800000005],[-61.88861099999997,57.622490000000084],[-61.89805599999994,57.616386000000034],[-62.07167099999998,57.56360599999999],[-62.1922229999999,57.535828000000095],[-62.30860899999999,57.49054699999999],[-62.42138699999998,57.48220799999996],[-62.43194599999987,57.48471799999999],[-62.531113000000005,57.506943000000035],[-62.54138899999998,57.50750000000011],[-62.544723999999974,57.504440000000045],[-62.545279999999934,57.50110600000005],[-62.533332999999914,57.49221800000009],[-62.52055399999995,57.48499300000003],[-62.46444699999995,57.4544370000001],[-62.457222,57.4511030000001],[-62.37722000000002,57.42193600000002],[-62.36527999999993,57.419715999999994],[-62.35388899999998,57.41832699999998],[-62.33583099999993,57.41944099999995],[-62.230552999999986,57.44360400000011],[-62.17333199999996,57.46360800000002],[-62.167220999999984,57.464439000000084],[-62.060828999999956,57.45638300000002],[-62.03972599999997,57.453323000000125],[-61.891388000000006,57.41193400000003],[-61.816948000000025,57.37693800000011],[-61.803054999999915,57.369155999999975],[-61.80139199999991,57.363052000000096],[-61.803054999999915,57.358887000000095],[-61.86389200000002,57.28555300000011],[-61.89416499999999,57.26944000000009],[-61.93749999999994,57.25222000000008],[-61.944999999999936,57.250832],[-61.953888000000006,57.24943500000006],[-61.99777999999998,57.25638600000002],[-62.01721999999995,57.25694300000009],[-62.02638999999999,57.25582900000012],[-62.02361300000001,57.25166300000001],[-62.01583900000003,57.24305000000004],[-62.00500499999987,57.23665599999998],[-61.85889400000002,57.16777000000013],[-61.85250099999996,57.16526800000008],[-61.664444,57.14388300000007],[-61.65555599999999,57.143051000000014],[-61.56555199999997,57.149719000000005],[-61.51555599999995,57.15638000000007],[-61.490837,57.1594310000001],[-61.478882,57.1594310000001],[-61.45889299999999,57.154709000000025],[-61.441665999999884,57.148604999999975],[-61.39305899999988,57.12470999999999],[-61.380279999999914,57.117210000000114],[-61.36389200000002,57.09721400000012],[-61.35833699999995,57.08749400000005],[-61.35555999999997,57.016388000000006],[-61.370833999999945,56.97860000000014],[-61.378052000000025,56.98220800000007],[-61.393332999999984,56.983047000000056],[-61.479720999999984,56.98360400000013],[-61.487777999999935,56.98165899999998],[-61.49555199999986,56.97943099999998],[-61.51639599999993,56.970267999999976],[-61.53556099999997,56.961104999999975],[-61.54666899999995,56.95443700000004],[-61.63999899999993,56.88388100000003],[-61.645003999999915,56.87832600000013],[-61.64833799999997,56.87304699999993],[-61.65083299999992,56.86693600000007],[-61.65277900000001,56.85582699999998],[-61.65277900000001,56.845543000000134],[-61.65055099999995,56.8408280000001],[-61.64611100000002,56.82694200000009],[-61.64611100000002,56.82110600000004],[-61.65027600000002,56.816666000000055],[-61.661384999999996,56.80943300000001],[-61.67639200000002,56.802773],[-61.78239100000002,56.794441000000006],[-61.79922499999992,56.79293799999999],[-61.81688699999995,56.79361],[-61.82355899999999,56.794441000000006],[-61.83455699999996,56.79610800000012],[-61.844559000000004,56.79894300000001],[-61.892226999999934,56.79860700000012],[-61.90638699999994,56.79527300000012],[-61.90860699999996,56.78916200000003],[-61.90222199999994,56.71415699999994],[-61.89999399999999,56.707214000000135],[-61.89722399999994,56.703049000000135],[-61.88999899999999,56.698044000000095],[-61.88611599999996,56.698044000000095],[-61.877776999999924,56.71305100000012],[-61.87027699999993,56.72693600000002],[-61.83366799999993,56.74199300000009],[-61.83083299999993,56.74532700000009],[-61.824996999999996,56.74682600000011],[-61.81150400000001,56.74682600000011],[-61.79333500000001,56.74682600000011],[-61.78049899999996,56.74565899999999],[-61.772834999999986,56.744160000000136],[-61.76266899999996,56.741325000000074],[-61.716392999999925,56.73804500000011],[-61.70249899999999,56.73082000000005],[-61.69694499999997,56.72470900000013],[-61.701667999999984,56.71332599999994],[-61.71055599999994,56.70555100000007],[-61.72110699999996,56.7011030000001],[-61.734443999999996,56.697212000000036],[-61.75417299999998,56.697487000000024],[-61.76500699999997,56.6988750000001],[-61.773056,56.7011030000001],[-61.798339999999996,56.710823000000005],[-61.808334,56.712212000000136],[-61.821670999999924,56.709717000000126],[-61.82500499999992,56.706657000000064],[-61.821670999999924,56.701660000000004],[-61.799171,56.682770000000005],[-61.79250300000001,56.68082400000014],[-61.73221599999994,56.66332200000011],[-61.681670999999994,56.65360300000009],[-61.67444599999993,56.65304600000002],[-61.658889999999985,56.647774000000084],[-61.649726999999984,56.641662999999994],[-61.649993999999936,56.635268999999994],[-61.65860700000002,56.62748700000003],[-61.672500999999954,56.619986999999924],[-61.68055700000002,56.618050000000096],[-61.68888900000002,56.61721000000006],[-61.699164999999994,56.61776700000013],[-61.835556,56.631660000000124],[-61.91166700000002,56.642769000000044],[-61.99277499999994,56.66027100000008],[-62.01000199999987,56.664153999999996],[-62.06694799999991,56.67860400000012],[-62.31111099999998,56.735550000000046],[-62.47999599999997,56.77388000000002],[-62.498885999999914,56.779716000000064],[-62.504448000000025,56.78360700000013],[-62.505004999999926,56.78888699999999],[-62.50194499999998,56.79193900000013],[-62.486114999999984,56.79610400000013],[-62.468886999999995,56.79860700000012],[-62.326392999999996,56.81276700000001],[-62.22749299999987,56.816666000000055],[-62.18999500000001,56.81332400000008],[-62.138335999999924,56.81082200000003],[-62.06833599999999,56.817214999999976],[-62.05944099999988,56.81860399999999],[-62.051665999999955,56.82054900000014],[-62.042502999999954,56.82694200000009],[-62.043334999999956,56.829994000000056],[-62.049445999999875,56.83249699999999],[-62.06694799999991,56.83443499999993],[-62.23472600000002,56.836937000000034],[-62.38166799999999,56.83027600000008],[-62.478606999999954,56.84665700000011],[-62.48889199999991,56.84943400000003],[-62.498885999999914,56.850548],[-62.50833899999992,56.84999800000014],[-62.51721999999995,56.84804500000001],[-62.53194400000001,56.843605000000025],[-62.54389200000003,56.83721200000002],[-62.54695099999992,56.83471700000001],[-62.57028199999996,56.79860700000012],[-62.57389099999989,56.79277000000013],[-62.53833799999995,56.775551000000064],[-62.50305899999995,56.76221499999991],[-62.35610999999989,56.72221400000012],[-62.162773000000016,56.672768000000076],[-62.02277399999997,56.62748700000003],[-62.00527999999997,56.61693600000012],[-62.11750000000001,56.623046999999985],[-62.175003000000004,56.62387799999999],[-62.23555799999997,56.62360400000006],[-62.24111199999987,56.62332200000003],[-62.23972299999997,56.61721000000006],[-62.224715999999944,56.60916100000003],[-62.1922229999999,56.60249300000004],[-62.10500300000001,56.59693900000002],[-62.04639400000002,56.59582500000005],[-62.036117999999874,56.595267999999976],[-61.901389999999935,56.58776899999998],[-61.72943900000001,56.574440000000095],[-61.71500400000002,56.57222000000007],[-61.70805399999989,56.56888600000008],[-61.70111099999997,56.56082200000009],[-61.690833999999995,56.548050000000046],[-61.66666399999997,56.540549999999996],[-61.65833299999997,56.537498000000085],[-61.65527300000002,56.533882000000006],[-61.65332799999993,56.53054800000001],[-61.652221999999995,56.52610000000004],[-61.65332799999993,56.52054600000008],[-61.656661999999926,56.51082600000001],[-61.662216,56.50610400000011],[-61.680282999999974,56.49665800000014],[-61.68916300000001,56.494713000000104],[-61.75472300000001,56.48499300000003],[-61.773056,56.48471800000004],[-61.80388599999992,56.487770000000125],[-61.878052000000025,56.49777200000011],[-61.95194200000003,56.505554000000075],[-62.038612,56.50527199999999],[-62.04695099999992,56.50471500000009],[-62.05471799999998,56.50249500000007],[-62.061668,56.499435000000005],[-62.075561999999934,56.49193600000001],[-62.08306099999993,56.48693800000001],[-62.08527399999991,56.48304699999994],[-62.082222,56.481659000000036],[-62.076667999999984,56.47998799999999],[-62.07083899999998,56.481102000000135],[-62.02417000000003,56.48443600000013],[-61.97638699999999,56.48333000000014],[-61.965278999999896,56.48193400000008],[-61.952225,56.47582200000011],[-61.94694500000003,56.471100000000035],[-61.95616499999994,56.46405000000004],[-61.95883199999997,56.461048000000005],[-61.961333999999965,56.45971700000001],[-61.966003,56.458549000000005],[-61.97983599999998,56.45555100000007],[-61.999724999999955,56.44999700000011],[-62.01028400000001,56.44999700000011],[-62.01999699999999,56.45110299999993],[-62.048888999999974,56.45721400000002],[-62.05972300000002,56.45860300000004],[-62.06999999999999,56.45916000000011],[-62.124999999999886,56.45721400000002],[-62.13999899999993,56.45221700000013],[-62.143058999999994,56.449158000000125],[-62.13916799999993,56.444709999999986],[-62.124999999999886,56.43832400000008],[-62.11750000000001,56.435546999999985],[-62.083327999999995,56.423325000000034],[-62.073059,56.420547],[-61.98472600000002,56.415268000000026],[-61.96371799999997,56.41565700000007],[-61.95688999999999,56.41782399999994],[-61.909720999999934,56.413879000000065],[-61.79805799999991,56.39527099999998],[-61.79084,56.392494000000056],[-61.661384999999996,56.27027100000009],[-61.67833299999995,56.26916100000011],[-61.679169,56.26799399999999],[-61.68683599999997,56.26699400000001],[-61.70283499999999,56.26532700000013],[-61.74999999999994,56.26132999999999],[-61.76066599999996,56.261662000000115],[-61.77216699999997,56.263493000000096],[-61.77716799999996,56.26532700000013],[-61.77967100000001,56.267494],[-61.77833599999997,56.26866100000012],[-61.77500199999997,56.268826000000104],[-61.76516699999996,56.26816200000002],[-61.756667999999934,56.26699400000001],[-61.74600199999992,56.267494],[-61.741000999999926,56.26916100000011],[-61.75361600000002,56.27304800000002],[-61.75305900000001,56.27777099999997],[-61.76999699999993,56.284163999999976],[-61.800835000000006,56.28943600000008],[-61.878608999999926,56.298607000000004],[-61.88861099999997,56.299164000000076],[-62.02972399999999,56.305267000000015],[-62.07444799999996,56.29638699999998],[-62.08000199999998,56.293610000000115],[-62.080832999999984,56.29249600000014],[-62.07611099999991,56.284996000000035],[-62.016395999999986,56.238883999999985],[-62.01167299999992,56.235825000000034],[-62.00389099999995,56.23360400000007],[-61.956947000000014,56.22082500000005],[-61.938331999999946,56.21582799999993],[-61.919448999999986,56.21221200000008],[-61.910278000000005,56.212493999999936],[-61.80205499999994,56.21638100000007],[-61.769889999999975,56.218048000000124],[-61.575004999999976,56.21693399999998],[-61.57556199999999,56.211937000000034],[-61.578612999999905,56.206940000000145],[-61.57972699999999,56.19915800000001],[-61.57527900000002,56.19609800000012],[-61.56027999999992,56.194435],[-61.53583500000002,56.19638100000009],[-61.450553999999954,56.204994000000056],[-61.411941999999954,56.21471400000013],[-61.40444199999996,56.21749100000005],[-61.380279999999914,56.22304500000007],[-61.361670999999944,56.22360200000014],[-61.35083799999995,56.222214000000065],[-61.34555099999994,56.218323],[-61.33083299999987,56.18193800000006],[-61.330284000000006,56.17665900000003],[-61.33555599999994,56.17276799999996],[-61.34332999999992,56.170547000000056],[-61.37722000000002,56.16860200000008],[-61.38361399999991,56.16471100000001],[-61.39722399999988,56.155823000000055],[-61.40610499999991,56.146102999999925],[-61.45249899999993,56.06276700000001],[-61.452225,56.056937999999946],[-61.44860799999998,56.052772999999945],[-61.41388699999993,56.037773000000016],[-61.41138499999988,56.03749799999997],[-61.39749899999998,56.04110700000001],[-61.38277399999993,56.04749300000009],[-61.35639199999997,56.05832700000013],[-61.34666399999992,56.06137799999999],[-61.34027900000001,56.063049000000035],[-61.32472199999995,56.06526900000006],[-61.315552000000025,56.065544000000045],[-61.24361399999998,56.04749300000009],[-61.23972299999997,56.045273000000066],[-61.23750299999989,56.042770000000075],[-61.24055499999997,56.040276000000006],[-61.26583899999997,56.02276599999999],[-61.27361300000001,56.02082800000005],[-61.28250099999997,56.01971400000008],[-61.31027999999998,56.018600000000106],[-61.357223999999974,56.018600000000106],[-61.38861099999991,56.021934999999985],[-61.419167000000016,56.02721400000013],[-61.43860599999999,56.027489],[-61.48999799999996,56.02027099999998],[-61.50139599999994,56.014442000000145],[-61.503890999999896,56.01055100000008],[-61.503615999999965,56.00694299999998],[-61.421943999999996,55.963882000000126],[-61.41500100000002,55.96027400000003],[-61.39917000000003,55.958602999999925],[-61.38999899999999,55.95888500000001],[-61.38138600000002,55.96027400000003],[-61.32805599999995,55.964157000000114],[-61.254722999999956,55.96749100000011],[-61.15444200000002,55.97137500000014],[-61.14361600000001,55.97054300000002],[-61.12555699999996,55.96859699999993],[-61.11777499999994,55.96610300000003],[-61.11361699999998,55.96249399999999],[-61.07444800000002,55.928329000000076],[-61.073891,55.9230500000001],[-61.076667999999984,55.906937000000084],[-61.09411199999994,55.895606999999984],[-61.156386999999995,55.8919370000001],[-61.165276000000006,55.892220000000066],[-61.181670999999994,55.89916199999999],[-61.19499999999999,55.892220000000066],[-61.201667999999984,55.884163000000115],[-61.19860799999992,55.87638099999998],[-61.192771999999934,55.869437999999946],[-61.10444599999994,55.845543000000134],[-61.0952759999999,55.84388000000001],[-61.08527400000003,55.84332299999994],[-61.077225,55.84388000000001],[-61.068062,55.845543000000134],[-61.039665000000014,55.850937000000044],[-61.035999000000004,55.85327100000006],[-61.02716800000002,55.85727300000008],[-60.946105999999986,55.86582900000013],[-60.91722099999993,55.864441000000056],[-60.78250099999997,55.85416400000008],[-60.76222199999995,55.85138699999999],[-60.755562,55.84943400000003],[-60.741669,55.843048000000124],[-60.72972099999993,55.829436999999984],[-60.72916399999997,55.82444000000004],[-60.73082699999998,55.80804400000005],[-60.734443999999996,55.80121200000002],[-60.736942,55.79738200000003],[-60.74222599999996,55.79054999999994],[-60.774719000000005,55.772491],[-60.80777699999993,55.755271999999934],[-60.88055400000002,55.74916100000007],[-60.87943999999999,55.73276500000003],[-60.76500699999997,55.72804299999996],[-60.756393,55.72943100000009],[-60.746947999999975,55.731659000000036],[-60.740279999999984,55.734161000000086],[-60.72721899999988,55.73999000000009],[-60.721663999999976,55.744713000000104],[-60.7016109999999,55.76344300000011],[-60.66889199999997,55.795830000000024],[-60.65638699999994,55.81276700000001],[-60.64722399999994,55.822768999999994],[-60.63999899999999,55.82555400000001],[-60.63166799999999,55.82666000000006],[-60.623885999999914,55.82499699999994],[-60.61527999999993,55.82193799999999],[-60.601943999999946,55.8147130000001],[-60.59777799999989,55.80943300000007],[-60.59805299999999,55.80443600000012],[-60.60583500000001,55.73387900000006],[-60.615837,55.68693500000006],[-60.6297229999999,55.638329000000056],[-60.66805999999997,55.5894320000001],[-60.65555599999993,55.58443500000004],[-60.606109999999944,55.622489999999914],[-60.60222599999986,55.626656000000025],[-60.59027900000001,55.64471400000008],[-60.544167000000016,55.72693600000002],[-60.52722199999988,55.760551000000135],[-60.527495999999985,55.76583099999999],[-60.52555799999993,55.77693899999997],[-60.51944699999996,55.78804800000006],[-60.514449999999954,55.79361],[-60.50305900000001,55.803046999999935],[-60.48777799999988,55.808601000000124],[-60.483611999999994,55.809158000000025],[-60.339995999999985,55.78638499999994],[-60.33499899999998,55.78443900000008],[-60.328888000000006,55.78166199999998],[-60.327224999999885,55.77276600000005],[-60.329444999999964,55.76138300000002],[-60.33777599999996,55.748604],[-60.38055399999996,55.69193300000006],[-60.406386999999995,55.674713000000054],[-60.463218999999924,55.66604600000011],[-60.47272099999998,55.6632120000001],[-60.493889000000024,55.658043000000134],[-60.49999999999994,55.65416000000005],[-60.50389100000001,55.648330999999985],[-60.52500199999997,55.610550000000046],[-60.53111299999995,55.597214000000065],[-60.532218999999884,55.591660000000104],[-60.53185999999994,55.58819599999998],[-60.51500699999997,55.599715999999944],[-60.50611099999992,55.61166400000002],[-60.495003,55.621101000000124],[-60.48138399999999,55.627769000000114],[-60.44033400000001,55.620216000000084],[-60.42616700000002,55.61821700000007],[-60.420334000000025,55.61637900000005],[-60.415501000000006,55.61454800000007],[-60.32277699999992,55.57833099999999],[-60.31639100000001,55.57388300000002],[-60.31639100000001,55.57027400000004],[-60.31944999999996,55.530823000000055],[-60.32167099999998,55.509995],[-60.42631899999998,55.44820400000009],[-60.442210999999986,55.427696000000026],[-60.43777499999999,55.39943700000009],[-60.47833299999991,55.347488000000055],[-60.47277100000002,55.34777100000002],[-60.45139299999994,55.35721600000011],[-60.42610899999994,55.37665600000008],[-60.420837000000006,55.38221000000004],[-60.41833500000001,55.38610799999998],[-60.41527599999995,55.39471400000008],[-60.41777799999994,55.40277100000009],[-60.42250100000001,55.407211000000075],[-60.425003000000004,55.411377000000016],[-60.423614999999984,55.421378999999945],[-60.41833500000001,55.427490000000034],[-60.413054999999986,55.43166400000007],[-60.34916700000002,55.47582200000011],[-60.33167300000002,55.48665599999998],[-60.31944999999996,55.491378999999995],[-60.26860799999997,55.502495000000124],[-60.25389099999995,55.503052000000025],[-60.21388999999999,55.489433000000076],[-60.20361300000002,55.48360400000007],[-60.201667999999984,55.478600000000085],[-60.19554899999997,55.4313810000001],[-60.26583900000003,55.40915699999999],[-60.27416999999991,55.40804300000002],[-60.284171999999955,55.40860000000009],[-60.295279999999934,55.41110200000014],[-60.30527499999988,55.41165900000004],[-60.313332,55.41110200000014],[-60.35472099999993,55.394997000000046],[-60.46888699999994,55.28582799999998],[-60.49888599999997,55.25332599999996],[-60.53805499999993,55.200546000000145],[-60.49999999999994,55.21804799999995],[-60.48889200000002,55.227210999999954],[-60.482215999999994,55.23165899999992],[-60.47638699999999,55.2347180000001],[-60.46832999999992,55.237495000000024],[-60.37388599999997,55.26055100000002],[-60.36583699999994,55.260826000000066],[-60.355278,55.25943799999999],[-60.34861000000001,55.25582900000012],[-60.348052999999936,55.25054900000009],[-60.353057999999976,55.244995000000074],[-60.51222200000001,55.12054399999994],[-60.58777600000002,55.08859999999993],[-60.616660999999965,55.07721700000013],[-60.636116000000015,55.066666],[-60.67055499999998,55.044715999999994],[-60.68111399999992,55.00471500000003],[-60.683326999999906,54.99499500000013],[-60.59277300000002,55.05888400000009],[-60.475273000000016,55.124435000000005],[-60.266395999999986,55.240547000000106],[-60.259170999999924,55.24415599999992],[-60.25250199999999,55.24638400000009],[-60.176109,55.270827999999995],[-60.079781000000025,55.24960299999998],[-60.07377600000001,55.24794000000003],[-60.072776999999974,55.24510600000002],[-60.11077899999992,55.199268000000075],[-60.123610999999926,55.15638000000013],[-60.14639299999993,55.13721499999997],[-60.15721899999994,55.12860100000012],[-60.18721799999997,55.108047],[-60.20444500000002,55.10749800000002],[-60.21277600000002,55.10860400000007],[-60.220551,55.10638400000005],[-60.28277600000001,55.05777000000006],[-60.28833799999995,55.05332199999992],[-60.295006,55.041382000000056],[-60.29695099999992,55.03443900000002],[-60.29666899999995,55.02499399999999],[-60.29389200000003,55.019440000000145],[-60.284171999999955,55.02443700000009],[-60.152495999999985,55.10277600000012],[-60.12444299999993,55.120270000000005],[-60.09944200000001,55.13665800000007],[-60.08833299999992,55.14582799999994],[-60.08388499999995,55.15221400000007],[-60.051223999999934,55.182381000000134],[-60.04571900000002,55.19304699999998],[-60.04472399999992,55.19671199999999],[-60.04272100000003,55.199883],[-60.03971899999988,55.203213000000005],[-60.03605700000003,55.20638300000007],[-60.02188899999999,55.21854799999994],[-60.01522399999999,55.221546000000046],[-60.00922400000002,55.22121400000009],[-59.96472199999994,55.23554999999999],[-59.93943799999994,55.233047000000056],[-59.922774999999945,55.233047000000056],[-59.91694599999994,55.233879000000115],[-59.91249799999997,55.238883999999985],[-59.89083899999997,55.26554900000002],[-59.86833200000001,55.291382],[-59.863891999999964,55.29610400000007],[-59.85139499999997,55.30304700000005],[-59.80750299999994,55.32416499999994],[-59.79527999999999,55.32749200000006],[-59.77916700000003,55.329720000000066],[-59.77610800000002,55.32916299999994],[-59.715003999999965,55.27609999999993],[-59.711945000000014,55.26971400000002],[-59.71333299999998,55.25610399999999],[-59.72943900000001,55.2052690000001],[-59.732497999999964,55.19721199999998],[-59.735832000000016,55.19415300000014],[-59.74277499999994,55.19137600000005],[-59.83139,55.162491000000045],[-59.84749599999998,55.15804300000008],[-59.863891999999964,55.154160000000104],[-59.89778100000001,55.151382000000126],[-59.918334999999956,55.15526599999998],[-59.94027699999998,55.16276600000003],[-59.9505539999999,55.16443600000002],[-59.96277599999996,55.16110200000003],[-59.96721599999995,55.15859999999998],[-59.970832999999914,55.15554800000001],[-59.97332799999987,55.14749100000006],[-59.96805599999993,55.11915600000003],[-59.963615000000004,55.110275000000115],[-59.80083499999995,55.10888700000004],[-59.79527999999999,55.10916099999997],[-59.615837,55.13638300000008],[-59.57028200000002,55.159988000000055],[-59.531386999999995,55.18138099999999],[-59.48777799999999,55.18138099999999],[-59.43055700000002,55.15193199999999],[-59.428337,55.149719000000005],[-59.427223000000026,55.13999200000006],[-59.42777999999993,55.13582600000001],[-59.431945999999925,55.129433000000006],[-59.438605999999936,55.123604],[-59.49610899999999,55.078331000000105],[-59.539169000000015,55.04916399999996],[-59.593886999999995,55.02082800000005],[-59.61083199999996,55.012771999999984],[-59.71665999999993,54.95582600000006],[-59.80216599999994,54.887268000000006],[-59.82399699999996,54.85110500000013],[-59.93916300000001,54.75888800000001],[-59.94416000000001,54.75555400000002],[-59.94554900000003,54.75305200000014],[-59.94416000000001,54.74971800000014],[-59.938605999999936,54.74638399999998],[-59.91916699999996,54.74137900000011],[-59.90943900000002,54.740829000000076],[-59.888610999999855,54.74332400000014],[-59.882499999999936,54.74499500000002],[-59.797500999999954,54.78166199999998],[-59.79111499999999,54.78555300000005],[-59.788612,54.78943600000002],[-59.790282999999874,54.79415899999998],[-59.79099999999994,54.82265899999999],[-59.79416699999996,54.82815900000014],[-59.79466599999995,54.83099400000003],[-59.7938309999999,54.83999299999999],[-59.79099999999994,54.846825000000024],[-59.78433999999993,54.857658000000015],[-59.77200299999993,54.86949200000004],[-59.7547229999999,54.897491000000116],[-59.72999599999997,54.907493999999986],[-59.703888000000006,54.91054500000001],[-59.68888899999996,54.913605000000075],[-59.67444599999999,54.91999099999998],[-59.61833199999995,54.948601],[-59.41111000000001,55.0563810000001],[-59.29389199999997,55.16971600000011],[-59.16527599999995,55.23499300000009],[-59.161384999999996,55.23693800000012],[-59.15471600000001,55.23554999999999],[-59.14416499999999,55.22804300000007],[-59.13944200000003,55.223877000000016],[-59.13111099999992,55.215546000000074],[-59.12749499999995,55.205826],[-59.12499999999994,55.19638099999992],[-59.12444299999987,55.18610399999994],[-59.14944099999991,55.16182699999996],[-59.15060799999992,55.15899299999995],[-59.155276999999955,55.15215699999993],[-59.16127799999998,55.146823999999924],[-59.168609999999944,55.141827000000035],[-59.176608999999985,55.13798900000006],[-59.205276000000026,55.13116100000002],[-59.20911000000001,55.12982200000005],[-59.24027999999993,55.11138200000005],[-59.25278499999996,55.10249299999998],[-59.363335000000006,55.01583099999999],[-59.37471800000003,55.00638600000008],[-59.38305699999995,54.99804700000004],[-59.386390999999946,54.99304999999998],[-59.39111300000002,54.98220800000013],[-59.39138799999995,54.98027000000002],[-59.38861099999997,54.97665400000011],[-59.384170999999924,54.973319999999944],[-59.37471800000003,54.97276300000004],[-59.36916400000001,54.97526600000003],[-59.275001999999915,55.02166],[-59.26250499999986,55.02832799999999],[-59.250838999999985,55.03582800000004],[-59.23722099999998,55.04833200000007],[-59.24250000000001,55.06110400000006],[-59.24305700000002,55.06638300000003],[-59.240837,55.07110600000004],[-59.23666399999996,55.07749200000012],[-59.13333099999994,55.120491000000015],[-59.05166600000001,55.153320000000065],[-59.03527799999989,55.15693700000003],[-59.02361300000001,55.15665400000006],[-58.96055599999988,55.134995],[-58.956107999999915,55.13027199999999],[-58.955832999999984,55.126381000000094],[-58.955832999999984,55.10083000000003],[-58.95833600000003,55.09165999999999],[-58.96167000000003,55.08526599999993],[-58.97110699999996,55.07110600000004],[-58.980278,55.059990000000084],[-59.005562,55.032767999999976],[-59.00194499999998,55.0177690000001],[-58.97249599999998,54.99554400000005],[-58.947220000000016,54.985550000000046],[-58.90721899999994,54.963882000000126],[-58.896950000000004,54.95638300000013],[-58.89416499999987,54.95277399999998],[-58.895279000000016,54.94776900000011],[-58.90055099999995,54.94387800000004],[-58.90694400000001,54.940269],[-58.96472199999988,54.91749600000014],[-59.01306199999999,54.89610300000004],[-59.015556000000004,54.892220000000066],[-59.01361800000001,54.88971700000013],[-58.90416700000003,54.844711000000075],[-58.83833299999998,54.832497000000046],[-58.83250399999997,54.831940000000145],[-58.82417299999997,54.834434999999985],[-58.69444299999998,54.82054900000003],[-58.68527199999994,54.81554399999999],[-58.560828999999956,54.77610000000004],[-58.44361099999992,54.77388000000002],[-58.39888799999994,54.78472099999999],[-58.391944999999964,54.787498000000085],[-58.379997,54.789993000000095],[-58.328056000000004,54.792496000000085],[-58.24333199999995,54.79471600000005],[-58.196663,54.79527299999995],[-58.19110899999998,54.79415899999998],[-58.188332,54.792496000000085],[-58.18721800000003,54.78860500000002],[-58.188605999999936,54.783051],[-58.19388600000002,54.77777100000009],[-58.19694499999997,54.77332299999995],[-58.19860799999998,54.76776899999999],[-58.184166000000005,54.75166299999995],[-58.173332000000016,54.74554400000011],[-58.145554000000004,54.739716000000044],[-58.11000100000001,54.737213000000054],[-58.00139599999994,54.73333000000008],[-57.94554899999997,54.73998999999998],[-57.935554999999965,54.74110400000012],[-57.910552999999936,54.74193600000001],[-57.855002999999954,54.73749500000008],[-57.84749599999992,54.7355500000001],[-57.84249899999992,54.73137700000001],[-57.831947000000014,54.71776600000004],[-57.789725999999916,54.68221299999999],[-57.78556100000003,54.67916100000008],[-57.71305799999993,54.64305100000013],[-57.70083599999998,54.63721500000008],[-57.693610999999976,54.63472000000007],[-57.67639200000002,54.630272000000105],[-57.660278000000005,54.62804399999993],[-57.64222699999999,54.62804399999993],[-57.62638899999996,54.62999000000002],[-57.57778199999996,54.63888500000007],[-57.57417299999997,54.64027400000003],[-57.569725000000005,54.644440000000145],[-57.56722300000001,54.64833100000004],[-57.55916599999995,54.655823],[-57.54583699999995,54.66165900000004],[-57.5391689999999,54.662209000000075],[-57.45639,54.65082600000005],[-57.450553999999954,54.649993999999936],[-57.44471699999997,54.64721700000007],[-57.355834999999956,54.59027100000009],[-57.352782999999874,54.58749399999999],[-57.34749599999992,54.57943700000004],[-57.346947,54.57471499999997],[-57.34861000000001,54.566940000000045],[-57.38082899999995,54.50749999999999],[-57.38527699999992,54.50332600000013],[-57.39694999999995,54.49582700000013],[-57.42722299999997,54.48777000000001],[-57.48472600000002,54.48249100000004],[-57.49305700000002,54.48333000000014],[-57.519447000000014,54.483879000000115],[-57.590836000000024,54.48416099999997],[-57.618056999999965,54.48360400000007],[-57.67277499999989,54.47998800000005],[-57.69499999999999,54.475548],[-57.70222499999994,54.47304500000007],[-57.704169999999976,54.470543000000134],[-57.70527599999997,54.46693399999998],[-57.70055400000001,54.45915999999994],[-57.68694299999993,54.45888500000012],[-57.65833299999997,54.46305100000001],[-57.58777599999996,54.46720899999997],[-57.487777999999935,54.47304500000007],[-57.47222099999999,54.47360200000014],[-57.44999699999994,54.46749100000005],[-57.442497,54.46499600000004],[-57.42527799999999,54.45915999999994],[-57.421111999999994,54.455826],[-57.42166900000001,54.45360599999998],[-57.523330999999985,54.41721300000006],[-57.621666000000005,54.38360599999993],[-57.62943999999999,54.38166000000007],[-57.660827999999924,54.376937999999996],[-57.678337,54.37526700000012],[-57.69527399999993,54.37499200000008],[-57.71555299999994,54.376937999999996],[-57.743056999999965,54.38082100000008],[-57.78333299999997,54.38832900000011],[-57.79722600000002,54.38888500000013],[-57.876105999999936,54.38665800000007],[-57.910278000000005,54.38526900000005],[-58.05027799999988,54.37748700000009],[-58.14639299999999,54.36527300000006],[-58.15416699999997,54.36332700000003],[-58.17250100000001,54.35749800000002],[-58.18527199999994,54.35166199999992],[-58.24805500000002,54.3202740000001],[-58.259727,54.31276699999995],[-58.26194799999996,54.31110400000006],[-58.25917099999998,54.30971500000004],[-58.253333999999995,54.308884000000035],[-58.22110700000002,54.31166100000013],[-58.197495,54.31638300000003],[-58.108337000000006,54.32804900000002],[-58.09860999999995,54.327217000000076],[-58.09583299999997,54.325829],[-58.23388699999998,54.254166000000055],[-58.24722300000002,54.25277700000004],[-58.344161999999926,54.244438],[-58.383056999999894,54.24110400000001],[-58.410278000000005,54.241661000000136],[-58.417220999999984,54.242493000000024],[-58.43138899999997,54.24221800000004],[-58.453888000000006,54.23721299999994],[-58.566108999999926,54.20416300000011],[-58.579169999999976,54.199996999999996],[-58.60139499999997,54.186104],[-58.61194599999999,54.178329000000076],[-58.62888299999997,54.16971600000011],[-58.6444469999999,54.16526799999997],[-58.69277199999999,54.151657],[-58.724715999999944,54.14527100000009],[-58.75694999999996,54.14110600000009],[-58.77111099999996,54.13999200000012],[-58.79778299999998,54.139717000000076],[-58.83361100000002,54.145827999999995],[-58.84277300000002,54.145827999999995],[-58.86000100000001,54.14471400000002],[-58.915276000000006,54.1386030000001],[-58.92833699999994,54.13638300000008],[-59.114165999999955,54.103882],[-59.19055199999997,54.08721200000008],[-59.24833699999999,54.07193799999999],[-59.27944199999996,54.06443800000011],[-59.37610599999999,54.046943999999996],[-59.434440999999936,54.0472180000001],[-59.470275999999956,54.05165900000003],[-59.51000199999993,54.05943300000001],[-59.53444699999994,54.05832700000002],[-59.561385999999914,54.05332199999998],[-59.57556199999999,54.04943800000012],[-59.582221999999945,54.046387000000095],[-59.586945000000014,54.0430530000001],[-59.58860800000002,54.04054999999994],[-59.584723999999994,54.03527100000014],[-59.51722000000001,53.99721499999998],[-59.509727,53.99554400000011],[-59.49444599999998,53.99638399999998],[-59.26583900000003,54.023048000000074],[-59.04944599999993,54.057495000000074],[-58.87722000000002,54.094993999999986],[-58.70305599999995,54.12416100000013],[-58.43111399999992,54.217209000000025],[-58.42639200000002,54.2219310000001],[-58.417502999999954,54.22804300000007],[-58.40638699999994,54.22971300000006],[-58.37943999999993,54.229988000000105],[-58.371940999999936,54.22804300000007],[-58.37444299999993,54.22443400000009],[-58.44972200000001,54.154434000000094],[-58.60500300000001,54.04415899999998],[-58.61028299999998,54.04166399999991],[-58.632499999999936,54.03527100000014],[-58.654998999999975,54.03166199999998],[-58.678054999999915,54.029160000000104],[-58.70444500000002,54.027214000000015],[-58.72166399999992,54.027489],[-58.749168,54.03110500000008],[-58.75917099999998,54.032767999999976],[-58.76805899999994,54.03499599999998],[-58.77972399999993,54.03777300000007],[-58.80750299999994,54.04332700000003],[-58.83583099999993,54.0472180000001],[-58.879997,54.04499800000008],[-58.93749999999994,54.04166399999991],[-59.002501999999936,54.03249400000004],[-59.038611999999944,54.02693899999997],[-59.04138899999998,54.02610000000004],[-59.04277799999994,54.02276600000005],[-59.04055799999986,54.02175100000005],[-59.00695000000002,54.018051000000014],[-58.95194200000003,54.01471700000002],[-58.944159999999954,54.01527400000009],[-58.92583499999995,54.01471700000002],[-58.922500999999954,54.01388500000007],[-58.91944899999993,54.01082600000012],[-58.92305799999997,54.00721699999997],[-58.954169999999976,53.983879],[-58.96305799999993,53.97776799999997],[-58.98082699999998,53.966385000000116],[-59.00833899999992,53.95526899999999],[-59.01583899999997,53.953323000000125],[-59.04778299999998,53.94832600000001],[-59.07222699999994,53.947487000000024],[-59.11527999999987,53.94638100000003],[-59.12222300000002,53.94526700000006],[-59.172774999999945,53.93499000000003],[-59.201392999999996,53.92748999999998],[-59.33194699999996,53.888329000000056],[-59.345551,53.88304900000014],[-59.36389199999991,53.8722150000001],[-59.36944599999998,53.867493000000024],[-59.39361600000001,53.8555530000001],[-59.43638599999997,53.83749399999999],[-59.46333299999998,53.830551000000014],[-59.480278,53.82777400000009],[-59.527221999999995,53.82249500000012],[-59.54389200000003,53.8211060000001],[-59.59610700000002,53.81916000000001],[-59.62388599999997,53.82027400000004],[-59.63583399999999,53.82083100000011],[-59.69860799999998,53.82943700000004],[-59.71665999999993,53.831939999999975],[-59.728049999999996,53.83526600000005],[-59.75556199999994,53.83860000000004],[-59.79833999999994,53.843323],[-59.807776999999874,53.84388000000007],[-59.82583599999998,53.8427660000001],[-59.85278299999999,53.8394320000001],[-59.87249800000001,53.833603000000096],[-59.877219999999966,53.83027600000014],[-59.88055399999996,53.82527200000004],[-59.989165999999955,53.77971600000012],[-60.082779000000016,53.76249700000005],[-60.12110899999993,53.625267000000065],[-60.11999499999996,53.61138199999999],[-60.11361699999992,53.602493000000095],[-60.110000999999954,53.59887700000007],[-60.105002999999954,53.59471100000013],[-60.087501999999915,53.58360299999998],[-60.068062,53.57332600000001],[-60.06444499999998,53.56971699999997],[-60.063332,53.56582600000007],[-60.06444499999998,53.56027200000011],[-60.06972499999995,53.55555000000004],[-60.07500499999992,53.55304700000005],[-60.13388800000001,53.5283280000001],[-60.13833599999998,53.52860300000009],[-60.34749599999998,53.62693800000011],[-60.358611999999994,53.634438000000046],[-60.361670999999944,53.63971700000002],[-60.36444899999998,53.64833100000004],[-60.368056999999965,53.65277100000009],[-60.382499999999936,53.66249099999999],[-60.390556000000004,53.66554300000007],[-60.50305900000001,53.705826000000116],[-60.51111599999996,53.708327999999995],[-60.56027999999998,53.71832300000011],[-60.64861300000001,53.73737699999998],[-60.670612000000006,53.74004700000006],[-60.705115999999975,53.74488100000002],[-60.75894900000003,53.76171899999997],[-60.76994300000001,53.765381000000104],[-60.856948999999986,53.79277000000002],[-60.88722200000001,53.751389000000074],[-60.880279999999914,53.71305100000001],[-60.83472399999994,53.72137500000002],[-60.75772499999999,53.713768000000016],[-60.74722299999996,53.71276499999999],[-60.65489199999996,53.69876899999991],[-60.64422599999995,53.69693799999999],[-60.537223999999924,53.67832900000002],[-60.51194799999996,53.66971600000005],[-60.44656399999997,53.64485200000013],[-60.431670999999994,53.63916000000012],[-60.36028299999998,53.60665899999998],[-60.354445999999996,53.60388200000011],[-60.34222399999993,53.59609999999998],[-60.33416699999998,53.58915699999994],[-60.32333399999999,53.581665000000044],[-60.29861499999993,53.568054000000075],[-60.278884999999946,53.55860100000007],[-60.25361600000002,53.54999500000014],[-60.103614999999934,53.50054900000009],[-60.10639200000003,53.457497000000046],[-60.123328999999956,53.456100000000106],[-60.13805400000001,53.45360599999998],[-60.202225,53.43360099999995],[-60.40582999999998,53.36415899999997],[-60.41332999999997,53.35777300000001],[-60.412216,53.34971600000006],[-60.404998999999975,53.33416000000011],[-60.395835999999974,53.33138300000002],[-60.39111300000002,53.33110799999997],[-60.30139200000002,53.33638000000013],[-60.23082699999998,53.34332300000011],[-60.2161099999999,53.34582499999999],[-60.203888000000006,53.34971600000006],[-60.198607999999865,53.350548],[-60.18860599999999,53.350548],[-60.18332700000002,53.349433999999974],[-60.1766659999999,53.34638200000006],[-60.17500299999995,53.34304800000007],[-60.17472099999998,53.33804300000003],[-60.180831999999896,53.329994],[-60.19083399999994,53.32193799999993],[-60.202225,53.313605999999936],[-60.20889299999999,53.310546999999985],[-60.283332999999914,53.28943600000014],[-60.29583699999995,53.28665900000004],[-60.33388500000001,53.280548000000124],[-60.36721799999992,53.27777100000003],[-60.389725,53.27693899999997],[-60.41833500000001,53.269440000000145],[-60.41666399999997,53.268326],[-60.398056,53.26554900000008],[-60.316108999999926,53.26416000000006],[-60.289444,53.26388500000007],[-60.133613999999966,53.28360700000013],[-60.024719000000005,53.35499600000014],[-59.95388799999995,53.40693700000003],[-59.931945999999925,53.42582700000014],[-59.84194199999996,53.476379000000065],[-59.82167099999998,53.47165699999999],[-59.806107,53.47110000000009],[-59.79805799999997,53.472214000000065],[-59.78916899999996,53.47443400000009],[-59.78500399999996,53.477210999999954],[-59.783615,53.48110200000002],[-59.78472899999997,53.48526800000013],[-59.799170999999944,53.491378999999995],[-59.82361599999996,53.49332400000003],[-59.858611999999994,53.496101000000124],[-59.89916999999997,53.51693699999993],[-59.90110800000002,53.51971400000002],[-59.89833799999997,53.52416199999999],[-59.893058999999994,53.52860300000009],[-59.87555699999996,53.534996000000035],[-59.85583500000001,53.536942000000124],[-59.84749599999998,53.536658999999986],[-59.80999799999995,53.52971600000001],[-59.77361300000001,53.517769000000044],[-59.763061999999934,53.51527400000003],[-59.75556199999994,53.51499899999999],[-59.740279999999984,53.515831000000105],[-59.62110899999993,53.52721400000013],[-59.605834999999956,53.52971600000001],[-59.56082900000001,53.54055000000005],[-59.53082999999998,53.54888200000005],[-59.51750199999998,53.55387899999994],[-59.47833300000002,53.57276900000011],[-59.32972699999999,53.65387700000008],[-59.162216,53.671379000000115],[-59.079726999999934,53.680550000000096],[-59.07417299999992,53.683051999999975],[-59.023888,53.71388200000001],[-59.01916499999993,53.71915400000012],[-59.01083399999993,53.744438000000116],[-59.010559,53.74665800000014],[-59.01889,53.74916100000013],[-59.03500399999996,53.74721500000004],[-59.04138899999998,53.748604],[-59.04611199999994,53.75277699999998],[-59.06527699999998,53.79110700000007],[-59.066390999999896,53.794998000000135],[-59.058334,53.80332200000004],[-59.04944599999993,53.81082200000009],[-59.04277799999994,53.81499500000001],[-58.87027699999999,53.90470900000014],[-58.550277999999935,54.009163],[-58.32611099999997,54.04627199999999],[-58.21694200000002,54.07177000000013],[-58.204612999999995,54.074604000000136],[-58.19377499999996,54.07593900000006],[-58.18044699999996,54.075436000000025],[-58.156780000000026,54.07143400000001],[-58.15060799999992,54.06943899999999],[-58.028610000000015,54.07972000000012],[-57.95194200000003,54.070831000000055],[-57.93860599999999,54.07027399999998],[-57.815552000000025,54.066101],[-57.79750100000001,54.066101],[-57.789443999999946,54.06860399999999],[-57.78639199999992,54.071662999999944],[-57.78611799999999,54.075271999999984],[-57.789443999999946,54.07972000000012],[-57.80555699999991,54.08665499999995],[-57.85166899999996,54.100273000000016],[-57.86972000000003,54.10305000000005],[-58.07650000000001,54.124489000000096],[-58.15249599999993,54.12915800000002],[-58.16716399999996,54.127827000000025],[-58.18150300000002,54.124660000000006],[-58.195831,54.120159000000115],[-58.21083499999992,54.1139950000001],[-58.21466800000002,54.111828],[-58.216995,54.110493000000076],[-58.22300000000001,54.10399200000006],[-58.22683299999994,54.101826000000074],[-58.22983199999993,54.10082200000011],[-58.23683499999993,54.09932700000007],[-58.24516699999998,54.099158999999986],[-58.254332999999974,54.101322000000096],[-58.415276000000006,54.13526900000011],[-58.4183349999999,54.139717000000076],[-58.417220999999984,54.14305100000007],[-58.383613999999966,54.18971299999998],[-58.37943999999993,54.193877999999984],[-58.373885999999914,54.19832600000012],[-58.36750000000001,54.201934999999935],[-58.35555999999991,54.20638300000013],[-58.20361300000002,54.23416100000003],[-58.177779999999984,54.23693800000012],[-58.03082999999992,54.235550000000046],[-58.00305899999995,54.233879],[-57.99361399999998,54.230819999999994],[-57.97360999999995,54.22165699999999],[-57.9611129999999,54.2177660000001],[-57.935272,54.2116620000001],[-57.866660999999965,54.19776900000005],[-57.85639200000003,54.196098000000006],[-57.65916399999992,54.199432],[-57.46832999999992,54.193877999999984],[-57.428336999999885,54.18249499999996],[-57.38417099999998,54.15054300000003],[-57.385559,54.145827999999995],[-57.38999899999999,54.14110600000009],[-57.383613999999966,54.12887599999999],[-57.370833999999945,54.10638400000005],[-57.367774999999995,54.10193600000008],[-57.32333399999999,54.039719000000105],[-57.22110699999996,53.91832699999998],[-57.115279999999984,53.83860000000004],[-57.09277300000002,53.83166499999999],[-57.08361100000002,53.82860599999998],[-57.07972699999999,53.82666000000012],[-57.076392999999996,53.82305100000008],[-57.07749899999993,53.81944299999998],[-57.15138999999999,53.73582499999998],[-57.302498000000014,53.67916100000008],[-57.31472000000002,53.676383999999985],[-57.387504999999976,53.65832500000005],[-57.429169,53.647491],[-57.48416900000001,53.63166000000001],[-57.49111199999993,53.62887600000005],[-57.52305599999994,53.61249500000008],[-57.53889499999997,53.60221899999999],[-57.544448999999986,53.59777100000002],[-57.549995000000024,53.59193400000004],[-57.55055199999998,53.58749400000005],[-57.54527999999999,53.584717000000126],[-57.54111499999999,53.585266000000104],[-57.533332999999914,53.58749400000005],[-57.52777900000001,53.591377000000136],[-57.49361399999998,53.60943600000007],[-57.479720999999984,53.61332700000014],[-57.458054000000004,53.61749300000008],[-57.44471699999997,53.618599000000074],[-57.373610999999926,53.60665899999998],[-57.316666,53.57972000000001],[-57.31361399999997,53.573608000000036],[-57.303054999999915,53.53082300000011],[-57.302498000000014,53.52638200000001],[-57.30332900000002,53.50943799999993],[-57.30555700000002,53.49971800000003],[-57.30666400000001,53.49638400000009],[-57.31777999999997,53.47554800000006],[-57.32888799999995,53.46193700000009],[-57.332503999999915,53.45832800000005],[-57.345832999999914,53.45054600000009],[-57.336945000000014,53.440269000000114],[-57.31639099999995,53.43582200000009],[-57.30332900000002,53.43332700000002],[-57.29750100000001,53.43305200000003],[-57.289169000000015,53.433876],[-57.28333299999997,53.438598999999954],[-57.29361699999998,53.4677660000001],[-57.28527799999995,53.477486],[-57.281386999999995,53.47943099999998],[-57.24861099999998,53.49415600000009],[-57.23750299999989,53.49860400000006],[-57.13027999999997,53.59388000000013],[-57.11138900000003,53.62165800000008],[-57.06138599999997,53.671379000000115],[-57.01472499999994,53.71138000000013],[-56.97361000000001,53.72443400000003],[-56.959442000000024,53.7283250000001],[-56.926391999999964,53.730270000000075],[-56.91666399999997,53.728600000000085],[-56.860832000000016,53.72248800000011],[-56.79722600000002,53.71998600000006],[-56.660827999999924,53.720543000000134],[-56.62222300000002,53.73360400000007],[-56.62860899999998,53.74193600000007],[-56.628333999999995,53.74415600000003],[-56.626105999999936,53.74582700000013],[-56.603332999999964,53.75916300000006],[-56.483611999999994,53.7824940000001],[-56.464691000000016,53.782272000000034],[-56.44833399999999,53.77777100000014],[-56.431670999999994,53.76444200000003],[-56.42694899999998,53.75721699999997],[-56.41388699999999,53.727768000000026],[-56.414443999999946,53.72193100000004],[-56.41527599999995,53.720543000000134],[-56.42166900000001,53.716933999999924],[-56.429169,53.71527100000003],[-56.43804899999992,53.71527100000003],[-56.44694499999997,53.716933999999924],[-56.48277300000001,53.718048000000124],[-56.506393,53.716933999999924],[-56.52166699999998,53.71471400000013],[-56.544448999999986,53.70971700000001],[-56.662215999999944,53.679993000000024],[-56.68028300000003,53.67276800000013],[-56.62722000000002,53.65082600000005],[-56.61805700000002,53.647491],[-56.34055299999994,53.58832599999994],[-56.32028199999996,53.585266000000104],[-56.22555499999987,53.577217000000076],[-56.21665999999999,53.577217000000076],[-56.205832999999984,53.581665000000044],[-56.15582999999998,53.591660000000104],[-56.07861300000002,53.58387799999997],[-56.069167999999934,53.58277100000004],[-56.031386999999995,53.57638500000013],[-56.027221999999995,53.57527200000004],[-55.99138599999998,53.552216000000044],[-55.97888199999994,53.5422210000001],[-55.99083699999994,53.51027700000009],[-55.99694799999992,53.50527200000005],[-56.00878099999994,53.50366600000007],[-56.01294699999994,53.50399399999998],[-56.01744499999995,53.50599699999998],[-56.01861199999996,53.508495000000096],[-56.02111099999996,53.51305400000001],[-56.02249899999998,53.516388000000006],[-56.04750100000001,53.533607000000075],[-56.063332,53.54083300000002],[-56.14583600000003,53.55304700000005],[-56.20889299999999,53.559433000000126],[-56.24250000000001,53.55999000000003],[-56.25833899999992,53.55915800000014],[-56.264725,53.55555000000004],[-56.26611300000002,53.54999500000014],[-56.263335999999924,53.54027600000012],[-56.259170999999924,53.53777300000013],[-56.14555399999995,53.500000000000114],[-56.11527999999993,53.49193600000012],[-56.07749899999993,53.483330000000024],[-56.037780999999995,53.46165500000001],[-56.02744299999995,53.45432699999998],[-55.96555299999994,53.40915700000005],[-55.965836000000024,53.40554800000001],[-55.96944400000001,53.40054299999997],[-56.00417299999998,53.388045999999974],[-56.02527599999996,53.37971500000009],[-56.03167000000002,53.37609900000001],[-56.03833800000001,53.36749300000014],[-56.029998999999975,53.365273000000116],[-56.020835999999974,53.36415899999997],[-56.01306199999999,53.364441],[-56.001396,53.36666100000002],[-55.98805199999998,53.369713000000104],[-55.981383999999935,53.3730470000001],[-55.969497999999874,53.38077500000003],[-55.95972399999994,53.39027399999998],[-55.95313299999992,53.39244100000002],[-55.938605999999936,53.39527100000004],[-55.92511699999994,53.396133000000134],[-55.912216,53.3949970000001],[-55.89361600000001,53.389717000000076],[-55.881385999999964,53.382767],[-55.808051999999975,53.34054600000002],[-55.80745699999994,53.28496600000011],[-55.745834,53.24943500000012],[-55.74749800000001,53.14360799999997],[-55.749442999999985,53.139717000000076],[-55.75417299999992,53.134995],[-55.83331299999992,53.09793100000002],[-55.87985600000002,53.07379500000002],[-55.91194200000001,53.02832799999999],[-55.92666600000001,53.02332300000012],[-55.934440999999936,53.021660000000054],[-55.943329000000006,53.021102999999925],[-55.96444700000001,53.021660000000054],[-55.99083699999994,53.0241620000001],[-56.00833899999998,53.02748900000006],[-56.02500199999997,53.03360699999996],[-56.03417200000001,53.03611000000012],[-56.056107,53.03832999999997],[-56.160278000000005,53.03360699999996],[-56.16583300000002,53.03276800000003],[-56.166945999999996,53.02943400000004],[-56.165276000000006,53.02499399999999],[-56.04084,53.00582900000006],[-55.95861100000002,52.99610100000001],[-55.94943999999998,52.99499500000002],[-55.88944200000003,52.96915400000012],[-55.885276999999974,52.966384999999946],[-55.83416699999998,52.92193600000002],[-55.80471799999998,52.8772130000001],[-55.80332899999996,52.83943199999993],[-55.80388599999998,52.83194000000003],[-55.808051999999975,52.82638500000013],[-55.84110999999996,52.82721700000002],[-55.87916599999994,52.82416500000011],[-55.97361000000001,52.8105470000001],[-55.98777799999999,52.80609900000013],[-56.06082900000001,52.76610600000009],[-55.96472199999994,52.68166400000007],[-55.96055599999994,52.679161000000136],[-55.9505539999999,52.6772160000001],[-55.93360899999993,52.675552000000096],[-55.91833500000001,52.677490000000034],[-55.87471799999997,52.68332700000002],[-55.78694899999999,52.683601000000124],[-55.77916700000003,52.682495000000074],[-55.77305599999994,52.679161000000136],[-55.76888999999994,52.674995000000024],[-55.740837,52.64638500000001],[-55.73860899999994,52.64276899999993],[-55.739998000000014,52.639434999999935],[-55.75750699999992,52.614441],[-55.769447000000014,52.60804700000011],[-55.792778,52.60166200000009],[-55.888892999999996,52.60804700000011],[-55.89861300000001,52.60999300000003],[-55.939940999999976,52.62826899999999],[-55.958777999999995,52.63560499999994],[-56.032775999999956,52.654709000000025],[-56.04888900000003,52.65609699999993],[-56.07500499999992,52.655823],[-56.10861199999994,52.6552660000001],[-56.12277199999994,52.65110000000004],[-56.12388599999986,52.647491],[-56.11972000000003,52.643326],[-56.112007000000006,52.64103699999998],[-56.09906000000001,52.64100600000012],[-56.07194500000003,52.644714000000135],[-56.06361400000003,52.644714000000135],[-56.05444299999999,52.643608000000086],[-55.98277300000001,52.62249000000003],[-55.97499800000003,52.619713000000104],[-55.970832999999914,52.61554699999999],[-55.972770999999966,52.61082500000009],[-55.985275,52.60221899999999],[-56.039169000000015,52.58499100000006],[-56.155777,52.557438000000104],[-56.17261100000002,52.55360800000011],[-56.18611099999998,52.55093800000003],[-56.20077900000001,52.55093800000003],[-56.25305899999995,52.54388400000005],[-56.297500999999954,52.56360600000011],[-56.315552000000025,52.57221999999996],[-56.322501999999986,52.574715000000026],[-56.333327999999995,52.57694200000009],[-56.35639199999997,52.580276000000026],[-56.45638999999994,52.59276599999998],[-56.47860700000001,52.59443700000003],[-56.49687199999994,52.59414700000002],[-56.45278200000001,52.56888600000002],[-56.44416000000001,52.56582600000013],[-56.28055599999999,52.53499600000009],[-56.26222199999995,52.5316620000001],[-56.19755600000002,52.52510500000005],[-56.15355699999992,52.52610399999992],[-55.98889200000002,52.50638600000008],[-55.829726999999934,52.51249700000011],[-55.761390999999946,52.49887800000005],[-55.75139599999994,52.496101000000124],[-55.746947999999975,52.4938810000001],[-55.74305700000002,52.49082900000002],[-55.73500100000001,52.47859999999997],[-55.73416900000001,52.474709000000075],[-55.735832000000016,52.469154],[-55.76445000000001,52.45388000000014],[-55.76750199999992,52.451103000000046],[-55.766395999999986,52.44776900000005],[-55.73277299999995,52.44221500000003],[-55.706107999999915,52.44165800000013],[-55.67666600000001,52.44165800000013],[-55.65666199999998,52.441933000000006],[-55.648612999999955,52.43971299999998],[-55.645554000000004,52.43749200000008],[-55.64277599999997,52.432770000000005],[-55.64277599999997,52.42777300000006],[-55.641669999999976,52.368881000000044],[-55.641944999999964,52.36388399999993],[-55.643332999999984,52.35833000000014],[-55.64778099999995,52.354164000000026],[-55.65444199999996,52.351661999999976],[-55.782501000000025,52.33416000000011],[-55.825004999999976,52.343048000000124],[-55.92861199999993,52.369438000000116],[-56.06833599999993,52.40721099999996],[-56.173614999999984,52.43888100000004],[-56.180556999999965,52.44082600000007],[-56.19444299999992,52.44221500000003],[-56.19694500000003,52.43998700000009],[-56.19527399999998,52.43582200000009],[-56.19138299999997,52.431107000000054],[-56.18138899999997,52.4230500000001],[-56.169448999999986,52.41610000000003],[-55.95666499999999,52.35027299999996],[-55.85777999999999,52.325271999999984],[-55.707222,52.248329000000126],[-55.67722299999997,52.20832799999994],[-55.68638599999997,52.10943600000002],[-55.69694500000003,52.08832600000005],[-55.70166799999993,52.08221400000008],[-55.89666699999992,51.950829],[-56.023330999999985,51.9019320000001],[-56.203330999999935,51.79332699999998],[-56.209723999999994,51.78971900000005],[-56.235832000000016,51.783607000000075],[-56.346663999999976,51.759720000000016],[-56.468886999999995,51.709434999999985],[-56.68972000000002,51.59221600000001],[-56.76445000000001,51.54860700000006],[-56.804169,51.50777399999998],[-56.80583200000001,51.502219999999966],[-56.80889100000002,51.49638400000009],[-56.81361399999997,51.491661000000136],[-56.94277199999999,51.42748999999992],[-56.94972199999995,51.424713000000054],[-56.956947000000014,51.4230500000001],[-57.00556199999994,51.41944100000012],[-57.078056000000004,51.41443600000008],[-57.10423999999995,51.412674000000095],[-57.14222699999999,51.424164000000076],[-57.23221599999994,51.498604000000114],[-57.23777799999999,51.502219999999966],[-57.24722299999996,51.504166000000055],[-57.255562,51.50443999999999],[-57.263617999999894,51.50360899999998],[-57.421386999999925,51.480545000000006],[-57.43777499999999,51.46110500000003],[-57.43638599999997,51.45638300000013],[-57.44083399999994,51.44999700000005],[-57.447495,51.447487000000024],[-57.45472000000001,51.445541000000105],[-57.58666199999999,51.42971800000009],[-57.602225999999916,51.42804700000005],[-57.676665999999955,51.42999300000008],[-57.685828999999956,51.43082400000009],[-57.688605999999936,51.4355470000001],[-57.692497,51.45526899999999],[-57.69193999999993,51.46110500000003],[-57.68943799999994,51.46638500000006],[-57.70527599999997,51.46943700000003],[-57.73082699999986,51.47109999999992],[-57.748054999999965,51.47221400000012],[-57.88388800000001,51.392494],[-57.88999899999999,51.388885000000016],[-57.94277199999999,51.35610200000002],[-57.95472000000001,51.34804500000007],[-57.966110000000015,51.338599999999985],[-57.975554999999986,51.328330999999935],[-57.98666400000002,51.31944299999998],[-58.00695000000002,51.31249200000002],[-58.02138499999995,51.30888400000009],[-58.21138799999994,51.27166],[-58.29722599999997,51.26859999999999],[-58.305556999999965,51.26859999999999],[-58.32444800000002,51.272217000000126],[-58.40777600000001,51.295547000000056],[-58.620551999999975,51.277214000000015],[-58.62805199999997,51.275551000000064],[-58.675003000000004,51.25527199999999],[-58.68000000000001,51.25000000000006],[-58.68055699999991,51.24415600000003],[-58.68000000000001,51.234161000000086],[-58.678337,51.22943100000009],[-58.675559999999905,51.224991000000045],[-58.67111199999994,51.22082499999999],[-58.665549999999996,51.216934000000094],[-58.63583399999993,51.19776900000011],[-58.62138399999998,51.19110099999995],[-58.59222399999993,51.18471500000004],[-58.61333499999995,51.15749400000004],[-58.618607,51.153046000000074],[-58.63055400000002,51.14582800000005],[-58.713615000000004,51.10610200000008],[-58.726944,51.09999800000003],[-58.73332999999997,51.09804500000007],[-58.785278000000005,51.08804299999997],[-58.91471899999999,51.05249000000009],[-58.92805499999997,51.048607000000004],[-58.990836999999885,51.0219350000001],[-59.00333399999994,51.01554900000002],[-59.006110999999976,51.00971999999996],[-59.00361600000002,51.0044400000001],[-58.99888599999997,51.00110600000011],[-58.990279999999984,50.998046999999985],[-58.981383999999935,50.99721500000004],[-58.97527299999996,51.000832],[-58.96832999999998,51.002495000000124],[-58.95944199999997,51.00166300000001],[-58.95472000000001,50.99665800000014],[-58.95249899999999,50.99249300000014],[-58.946662999999944,50.83387800000003],[-58.94805100000002,50.82833100000005],[-59.010559,50.754166000000055],[-59.01528200000001,50.748604000000114],[-59.041672000000005,50.75138900000013],[-59.061385999999914,50.75555400000013],[-59.06833599999999,50.759163000000115],[-59.08721899999995,50.77526899999992],[-59.09305599999993,50.78943600000008],[-59.09444400000001,50.799438000000066],[-59.09471899999994,50.81526900000006],[-59.118889000000024,50.80360400000012],[-59.15582999999998,50.77110300000004],[-59.186385999999914,50.74221799999998],[-59.228882,50.73832700000008],[-59.397223999999994,50.65721100000013],[-59.454444999999964,50.621933000000126],[-59.45972399999994,50.61721],[-59.51916499999993,50.552773],[-59.57055699999995,50.493607000000054],[-59.58000199999992,50.48276500000003],[-59.58527400000003,50.47804300000013],[-59.59166700000003,50.47526600000003],[-59.59861000000001,50.47360200000003],[-59.73361199999994,50.44499200000001],[-59.778336000000024,50.438881000000094],[-59.80388599999998,50.438881000000094],[-59.81055500000002,50.437492000000134],[-59.816108999999926,50.433876000000055],[-59.82167099999998,50.42943600000007],[-59.87222299999996,50.38110399999999],[-59.881667999999934,50.371658000000025],[-59.881667999999934,50.36638600000009],[-59.858893999999964,50.329436999999984],[-59.853888999999924,50.32610299999999],[-59.844719,50.324440000000095],[-59.83777599999996,50.32610299999999],[-59.83472399999988,50.338043000000084],[-59.83499899999998,50.343323],[-59.830832999999984,50.34943400000009],[-59.82472200000001,50.35166200000003],[-59.81500199999999,50.34915900000004],[-59.813331999999946,50.344154],[-59.81722300000001,50.33277099999998],[-59.82749899999999,50.32360799999998],[-59.83388500000001,50.31916000000001],[-59.86028299999998,50.31054700000004],[-59.90527300000002,50.29110700000007],[-60.00500499999998,50.248878000000104],[-60.11444899999992,50.23304699999994],[-60.14778100000001,50.2741620000001],[-60.18444099999999,50.27971600000012],[-60.23694599999999,50.268051000000014],[-60.29167199999995,50.245270000000005],[-60.29861499999993,50.24332400000014],[-60.32444799999996,50.244713000000104],[-60.36000100000001,50.250831999999946],[-60.40444200000002,50.251389000000074],[-60.45889299999999,50.25110600000011],[-60.48332999999991,50.250831999999946],[-60.491668999999945,50.25054899999998],[-60.498610999999926,50.248604],[-60.51167299999997,50.24249300000014],[-60.52222399999988,50.23471800000004],[-60.52694699999995,50.2291560000001],[-60.58361100000002,50.208327999999995],[-60.59166699999997,50.20804600000014],[-60.67444599999999,50.219986000000006],[-60.710556,50.2227630000001],[-60.838607999999965,50.214995999999985],[-61.05222299999997,50.21554600000002],[-61.289443999999946,50.199158000000125],[-61.427779999999984,50.171379000000115],[-61.50556199999994,50.152489],[-61.583610999999905,50.13249200000013],[-61.65083299999992,50.109993000000145],[-61.720832999999914,50.09193400000004],[-61.73161299999998,50.10193600000002],[-61.742106999999976,50.10527000000002],[-61.74627700000002,50.10726900000003],[-61.74828000000002,50.10994000000005],[-61.71210499999995,50.12226899999996],[-61.70378099999999,50.12477100000007],[-61.69944399999997,50.125435000000095],[-61.69444299999992,50.125435000000095],[-61.67138699999998,50.136940000000095],[-61.62055199999992,50.147491],[-61.593055999999876,50.1552660000001],[-61.57972699999999,50.16082000000006],[-61.574447999999904,50.16554300000007],[-61.57194500000003,50.17166100000003],[-61.573891,50.18166400000007],[-61.577225,50.18610400000006],[-61.58916499999998,50.18888099999998],[-61.59361299999995,50.185546999999985],[-61.602225999999916,50.174438000000066],[-61.60777999999999,50.17082999999997],[-61.62222299999996,50.16610000000014],[-61.731833999999935,50.144268000000125],[-61.746997999999905,50.144431999999995],[-61.75750399999998,50.14527099999998],[-61.76183299999997,50.14726999999999],[-61.76366399999995,50.14976899999999],[-61.76299999999998,50.15327100000002],[-61.76066599999996,50.15709700000008],[-61.794448999999986,50.1594310000001],[-61.79527999999999,50.16999100000004],[-61.79695099999998,50.17471300000011],[-61.80444299999999,50.18332699999996],[-61.848884999999996,50.22248800000011],[-61.864723000000026,50.228600000000085],[-61.898338000000024,50.23360400000007],[-61.90721899999994,50.23416099999997],[-61.96333299999998,50.236107000000004],[-61.97721899999999,50.23193400000008],[-61.989723000000026,50.22637900000001],[-61.996666000000005,50.224158999999986],[-62.00417299999992,50.22304500000001],[-62.20249899999999,50.23443600000013],[-62.26889,50.25972000000013],[-62.31777999999997,50.28138000000013],[-62.328056000000004,50.283882000000006],[-62.39749899999998,50.29444100000006],[-62.40416700000003,50.29222100000004],[-62.41554999999994,50.28472099999999],[-62.42556000000002,50.27526900000004],[-62.42999999999995,50.269714000000135],[-62.43999499999995,50.260551000000135],[-62.446105999999986,50.25750000000011],[-62.57222699999994,50.274712000000136],[-62.74694799999992,50.28472099999999],[-63.11250299999995,50.29138200000011],[-63.15833299999997,50.26027700000003],[-63.159163999999976,50.25471500000009],[-63.22860700000001,50.23471800000004],[-63.23666399999996,50.23443600000013],[-63.37194099999999,50.23665599999998],[-63.46944399999995,50.25721699999997],[-63.565552000000025,50.26415999999995],[-63.61666099999991,50.26666300000011],[-63.64972699999993,50.27276600000005],[-63.687499999999886,50.2824940000001],[-63.693885999999964,50.29193900000001],[-63.69860799999998,50.29527299999995],[-63.70750399999997,50.29777500000006],[-63.803328999999906,50.311661000000015],[-63.82138800000001,50.31220999999999],[-63.97610499999996,50.30554999999998],[-64.06723,50.29222100000004],[-64.12777699999992,50.27193500000004],[-64.14056399999993,50.26693700000004],[-64.15417500000001,50.26249700000005],[-64.16221599999994,50.26221499999997],[-64.21528599999994,50.2649990000001],[-64.23472600000002,50.26693700000004],[-64.262787,50.271660000000054],[-64.36527999999998,50.29222100000004],[-64.37388599999997,50.294998000000135],[-64.402222,50.30749500000013],[-64.41777000000002,50.31304899999992],[-64.43666100000002,50.317772000000105],[-64.44610599999999,50.31916000000001],[-64.45500199999992,50.31944299999998],[-64.46305799999999,50.31916000000001],[-64.47083999999995,50.317772000000105],[-64.51000999999997,50.30304699999999],[-64.61193800000001,50.28138000000013],[-64.62805200000003,50.279160000000104],[-64.65943899999996,50.277214000000015],[-64.72500600000001,50.27443699999998],[-64.89999399999994,50.27082800000011],[-65.18055700000002,50.28555300000005],[-65.18998699999992,50.2866590000001],[-65.22277799999995,50.29777500000006],[-65.237503,50.30387900000005],[-65.24249299999985,50.30776999999995],[-65.27500900000001,50.30804400000005],[-65.464447,50.29943799999995],[-65.48666399999996,50.29527299999995],[-65.52166699999998,50.285828000000095],[-65.58999599999999,50.27526900000004],[-65.69055200000003,50.261108000000036],[-65.747772,50.256943000000035],[-65.829453,50.25332600000007],[-65.84583999999995,50.25888800000001],[-65.864441,50.26888300000013],[-65.87638900000002,50.276382000000126],[-65.89805599999988,50.28499599999998],[-65.91805999999997,50.28832999999997],[-65.95249899999993,50.288887000000045],[-65.97416699999997,50.283882000000006],[-65.9869379999999,50.278328000000045],[-65.99305700000002,50.27526900000004],[-66.0041809999999,50.26832600000006],[-66.02471899999995,50.251389000000074],[-66.04333499999996,50.22221400000001],[-66.083328,50.19360399999994],[-66.08972199999988,50.19137599999999],[-66.16332999999997,50.197212000000036],[-66.31416300000001,50.20971700000001],[-66.40638699999994,50.23998999999998],[-66.40695199999999,50.245270000000005],[-66.41221599999994,50.260551000000135],[-66.416946,50.26444200000003],[-66.42304999999993,50.26776899999999],[-66.43331899999998,50.269714000000135],[-66.44166599999994,50.269157000000064],[-66.45639,50.26638800000012],[-66.46972700000003,50.26193999999998],[-66.49472000000003,50.249435000000005],[-66.51194800000002,50.23915899999997],[-66.70083599999992,50.102493000000095],[-66.72332799999992,50.07833100000005],[-66.8619379999999,50.022491000000116],[-66.88249200000001,50.016662999999994],[-66.896118,50.01194000000004],[-66.92027300000001,50.0002750000001],[-66.9424899999999,49.985825000000034],[-66.95861799999994,49.974709000000075],[-66.96362299999998,49.969154],[-66.96639999999996,49.96332600000005],[-66.975281,49.94360399999999],[-66.97582999999997,49.937767000000065],[-66.96556099999992,49.91944100000006],[-66.96333299999998,49.91471100000001],[-67.01640299999985,49.85471299999995],[-67.06138599999986,49.84137700000002],[-67.06527699999992,49.84554300000008],[-67.07389799999993,49.84804500000001],[-67.0958399999999,49.84360500000014],[-67.11582900000002,49.83665500000012],[-67.12165800000002,49.833327999999995],[-67.13722200000001,49.82138100000003],[-67.14666699999998,49.812492000000134],[-67.15139799999992,49.806937999999946],[-67.162216,49.79055000000011],[-67.17416400000002,49.76471700000013],[-67.23889200000002,49.590546000000074],[-67.24082899999996,49.57888000000008],[-67.241379,49.56749700000006],[-67.24082899999996,49.556655999999975],[-67.23999000000003,49.55165900000003],[-67.23500099999995,49.53555300000005],[-67.228882,49.51027700000003],[-67.22917199999995,49.48304700000011],[-67.23083499999996,49.47693600000002],[-67.23388699999998,49.47026800000009],[-67.36915599999998,49.33277100000004],[-67.375,49.32721700000002],[-67.386124,49.32222000000007],[-67.40278599999988,49.3211060000001],[-67.42027300000001,49.321663],[-67.43859900000001,49.324440000000095],[-67.47361799999999,49.32666000000012],[-67.56973299999999,49.32999400000011],[-67.57749899999999,49.32916300000011],[-67.70639,49.312767000000065],[-67.93916300000001,49.28777300000013],[-67.975281,49.284996000000035],[-68.11972000000003,49.271660000000054],[-68.12721299999998,49.26944000000003],[-68.13194299999992,49.26610600000009],[-68.13639799999993,49.260550999999964],[-68.13890099999992,49.25471500000009],[-68.14056399999993,49.24860400000006],[-68.14388999999989,49.23054500000012],[-68.18083200000001,49.12193300000007],[-68.1849979999999,49.116104000000064],[-68.18971299999993,49.112213],[-68.19499200000001,49.10833000000008],[-68.20111099999991,49.105552999999986],[-68.22166399999998,49.10027300000007],[-68.36944599999998,49.069443000000035],[-68.44248999999996,49.09554300000008],[-68.571396,49.061104],[-68.59056099999998,49.05416100000002],[-68.60694899999993,49.04249600000014],[-68.62609900000001,49.02388000000013],[-68.69638099999997,48.93998700000009],[-68.876938,48.85193600000008],[-69.047775,48.773048000000074],[-69.06082200000003,48.767494000000056],[-69.064438,48.762496999999996],[-69.08473200000003,48.72165700000005],[-69.0894469999999,48.70943500000004],[-69.09361299999995,48.691933000000006],[-69.09611499999994,48.67499500000014],[-69.0994419999999,48.66332200000011],[-69.10610999999994,48.64499699999999],[-69.1119379999999,48.63249200000007],[-69.12388599999991,48.6147160000001],[-69.14250199999992,48.59499400000004],[-69.14805599999994,48.591102999999976],[-69.15972899999997,48.58526599999999],[-69.16639700000002,48.58332800000005],[-69.18415800000002,48.58471700000007],[-69.20167500000002,48.588599999999985],[-69.21861299999995,48.58971399999996],[-69.22666900000002,48.58888200000007],[-69.23138399999993,48.585548000000074],[-69.23638899999992,48.58110800000003],[-69.26528899999994,48.54166399999997],[-69.27944899999994,48.51583100000005],[-69.28277600000001,48.50416600000011],[-69.28332499999993,48.49304999999998],[-69.28250099999997,48.48249099999998],[-69.29277000000002,48.45777100000009],[-69.30110200000001,48.446655000000135],[-69.43276999999995,48.307770000000005],[-69.43777499999999,48.30304700000005],[-69.45472699999999,48.29193900000001],[-69.59777799999995,48.207497000000046],[-69.672775,48.14388300000013],[-69.68388400000003,48.13777200000004],[-69.69137599999999,48.137496999999996],[-69.80082699999997,48.15360300000003],[-69.81027199999994,48.155823],[-69.73472599999997,48.113609000000054],[-69.73028599999998,48.10943600000013],[-69.73249800000002,48.103607000000125],[-69.78639199999986,47.99471300000005],[-69.839447,47.90721099999996],[-69.92582700000003,47.773048000000074],[-69.93582200000003,47.764441999999974],[-70.00222799999995,47.71193699999998],[-70.01556399999998,47.70277399999998],[-70.07194500000003,47.674713000000054],[-70.07749899999999,47.67249300000009],[-70.09110999999996,47.66915900000009],[-70.132767,47.64499699999999],[-70.17999299999997,47.608330000000024],[-70.19027699999992,47.59915900000004],[-70.20249899999999,47.58305399999995],[-70.20611600000001,47.57666000000012],[-70.2083439999999,47.57054900000003],[-70.20944199999997,47.55387900000011],[-70.20750399999991,47.533051],[-70.208618,47.52721400000007],[-70.21722399999993,47.508331],[-70.22555499999993,47.496384000000035],[-70.2308349999999,47.49249300000014],[-70.29972799999996,47.466933999999924],[-70.34167499999995,47.46054800000002],[-70.4619449999999,47.429993000000024],[-70.50250199999999,47.39083099999999],[-70.55583199999995,47.32276900000011],[-70.56639100000001,47.30416100000002],[-70.56861899999996,47.29804999999993],[-70.57112099999995,47.28110499999997],[-70.57417299999997,47.274437000000034],[-70.58612099999999,47.25777399999993],[-70.69943199999994,47.12609900000001],[-70.72166400000003,47.1013870000001],[-70.73306300000002,47.095543000000134],[-70.79249600000003,47.06832900000012],[-70.81750499999993,47.058884000000035],[-70.82362399999994,47.056938],[-70.86694299999994,47.051383999999985],[-70.89334100000002,47.045273000000066],[-70.92304999999993,47.032211000000075],[-70.97361799999999,47.003326000000015],[-71.11361699999986,46.912491000000045],[-71.18249500000002,46.86415899999997],[-71.197495,46.85249300000004],[-71.19860799999998,46.84638200000012],[-71.29916400000002,46.74221800000009],[-71.291946,46.74415600000003],[-71.27972399999993,46.74916100000007],[-71.20944199999997,46.7824940000001],[-71.19888299999991,46.788887000000045],[-71.18888899999996,46.79666100000003],[-71.18443299999996,46.80277300000006],[-71.17832900000002,46.815269000000114],[-71.1663969999999,46.83110800000003],[-71.15611299999995,46.83888200000007],[-71.14999399999994,46.84249100000005],[-71.14361599999995,46.844711000000075],[-71.13055400000002,46.847488],[-71.11527999999998,46.84887700000013],[-71.100281,46.84887700000013],[-71.083328,46.847488],[-70.98693799999995,46.85416400000008],[-70.77223200000003,46.91582500000004],[-70.76640299999991,46.91888400000005],[-70.75500499999998,46.93665299999998],[-70.74444599999993,46.94332099999991],[-70.73750299999995,46.946098000000006],[-70.63806199999999,46.98165899999998],[-70.61888099999993,46.98804500000006],[-70.60499600000003,46.99027300000006],[-70.57501200000002,46.99332400000009],[-70.55332899999996,46.99804700000004],[-70.54138199999994,47.00249500000001],[-70.53028899999993,47.00777399999998],[-70.506958,47.02027099999998],[-70.48638900000003,47.03360700000013],[-70.46112099999993,47.05360400000001],[-70.33416699999992,47.15554800000001],[-70.31027199999994,47.176659000000086],[-70.273056,47.213608000000136],[-70.11111499999998,47.34054600000013],[-70.078888,47.36110699999995],[-70.04888899999997,47.38610799999998],[-70.04415899999992,47.39083099999999],[-70.04083300000002,47.39721700000007],[-70.03999299999987,47.40277100000009],[-69.96749899999998,47.50582900000006],[-69.90194699999995,47.537216],[-69.89639299999993,47.54110700000007],[-69.80583200000001,47.613052000000096],[-69.65943900000002,47.744713000000104],[-69.63999899999988,47.76277200000004],[-69.59306300000003,47.80888400000009],[-69.55665599999986,47.85638400000005],[-69.55638099999993,47.86666100000002],[-69.54415899999998,47.883605999999986],[-69.52667200000002,47.90415999999999],[-69.50805700000001,47.92443800000001],[-69.49888599999986,47.933876],[-69.46972700000003,47.96193700000009],[-69.45056199999999,47.97915599999999],[-69.429169,47.99527000000012],[-69.41833500000001,48.00138900000013],[-69.41166699999997,48.003326000000015],[-69.27528399999994,48.06777200000005],[-69.11610399999995,48.178604000000064],[-69.10194399999995,48.192764000000125],[-69.08666999999997,48.204994000000056],[-69.05416899999989,48.22860000000014],[-69.01640299999997,48.254166],[-68.968613,48.279990999999995],[-68.94055200000003,48.29499800000002],[-68.83167999999989,48.34471100000013],[-68.695267,48.39638500000012],[-68.541382,48.451385000000016],[-68.52944899999994,48.45721400000002],[-68.51916499999999,48.464157],[-68.51306199999988,48.469437000000084],[-68.49694799999992,48.490273000000116],[-68.47389199999998,48.515549000000135],[-68.46916199999987,48.52027100000004],[-68.45361300000002,48.5324940000001],[-68.43443300000001,48.54166399999997],[-68.42250100000001,48.54527299999995],[-68.40777600000001,48.548050000000046],[-68.37582399999985,48.546386999999925],[-68.368607,48.547493000000145],[-68.354446,48.55138400000004],[-68.34834299999989,48.554161000000136],[-68.33667000000003,48.561661000000015],[-68.28332499999999,48.600273000000016],[-68.23693799999995,48.625549000000035],[-68.21112099999993,48.636658000000125],[-68.19332899999989,48.64305100000007],[-68.17916899999994,48.64666000000011],[-68.15695199999999,48.64916199999999],[-68.12554899999998,48.648330999999985],[-68.11193800000001,48.65138200000001],[-67.97361799999999,48.695541000000105],[-67.70944199999985,48.793884000000105],[-67.531387,48.85916099999997],[-67.20973200000003,48.93582200000009],[-67.087784,48.96082300000012],[-67.06750499999998,48.96693399999998],[-67.01583899999997,48.98693800000012],[-66.991669,48.99916099999996],[-66.96083099999998,49.01194000000004],[-66.922775,49.02665700000006],[-66.91639700000002,49.02887700000002],[-66.72250399999996,49.08998900000006],[-66.42166099999992,49.162765999999976],[-66.306107,49.18693500000012],[-66.22500599999995,49.200829000000056],[-66.08917200000002,49.218597000000045],[-66.07417299999997,49.21971100000002],[-65.83250399999991,49.23137700000001],[-65.67832899999996,49.245543999999995],[-65.49694799999997,49.261664999999994],[-65.44721999999996,49.262215000000026],[-65.394455,49.25971999999996],[-65.35972600000002,49.256660000000124],[-64.99694799999992,49.22026799999992],[-64.91665599999999,49.20665699999995],[-64.82556199999993,49.18776700000001],[-64.80583199999995,49.18332700000002],[-64.79527300000001,49.17610200000013],[-64.79194599999994,49.17166100000003],[-64.77471899999995,49.159988],[-64.76333599999992,49.15416000000005],[-64.74888599999991,49.148048000000074],[-64.73194899999999,49.14222000000001],[-64.66082799999987,49.12304700000004],[-64.64111299999996,49.11888099999999],[-64.60665899999992,49.117210000000114],[-64.58805799999999,49.112213],[-64.37638899999996,48.997772],[-64.23554999999999,48.91027100000002],[-64.22166399999998,48.8983310000001],[-64.21444699999995,48.88943499999999],[-64.20889299999999,48.880547000000035],[-64.15222199999994,48.764999000000046],[-64.15249599999999,48.75999500000012],[-64.15805099999994,48.75610400000005],[-64.16776999999996,48.758331000000055],[-64.20889299999999,48.782767999999976],[-64.21333299999998,48.78665900000004],[-64.22999599999997,48.79749300000009],[-64.24415599999998,48.80360400000001],[-64.29028299999993,48.82110600000004],[-64.29888900000003,48.82388300000014],[-64.31555200000003,48.82888000000003],[-64.37721299999993,48.84638200000006],[-64.39584400000001,48.851105000000075],[-64.51222200000001,48.87471000000005],[-64.53056299999992,48.87721300000004],[-64.54888899999992,48.87832600000007],[-64.54333500000001,48.873604],[-64.53277599999996,48.86693600000007],[-64.464447,48.82444000000004],[-64.37416100000002,48.787773000000016],[-64.266663,48.71332600000011],[-64.256958,48.70609999999999],[-64.17304999999993,48.63943500000005],[-64.16194200000001,48.62748700000003],[-64.16000400000001,48.62276500000013],[-64.166946,48.62137600000011],[-64.19305399999996,48.62360400000006],[-64.24110399999995,48.6222150000001],[-64.25500499999993,48.61859900000002],[-64.26083399999987,48.61582899999996],[-64.265289,48.610825000000034],[-64.26972999999998,48.60471300000006],[-64.27471899999995,48.5927660000001],[-64.28056300000003,48.575271999999984],[-64.28250099999991,48.56916000000001],[-64.28332499999988,48.56360599999999],[-64.27917499999995,48.554161000000136],[-64.27333099999993,48.55054500000006],[-64.26417499999991,48.54916400000002],[-64.245834,48.546661000000086],[-64.21916199999998,48.52832799999999],[-64.24638400000003,48.48804499999994],[-64.32250999999985,48.43721000000011],[-64.42639200000002,48.40416000000005],[-64.49305700000002,48.394440000000145],[-64.50666799999999,48.39166300000005],[-64.58694500000001,48.36832400000003],[-64.68638599999997,48.33832600000011],[-64.73138399999988,48.27471200000002],[-64.75029,48.24582700000013],[-64.75389099999995,48.23998999999998],[-64.760559,48.227211000000125],[-64.76806599999998,48.20277400000003],[-64.77139299999999,48.19638100000009],[-64.77861000000001,48.19499200000007],[-64.87332200000003,48.180550000000096],[-64.931671,48.17166100000003],[-64.97250399999996,48.13526900000005],[-65.15306099999998,48.052216000000044],[-65.19665499999996,48.033607000000075],[-65.202789,48.03138000000001],[-65.27000399999997,48.012771999999984],[-65.30583200000001,48.00555400000013],[-65.32695000000001,48.002220000000136],[-65.45556599999998,48.00027499999999],[-65.46389799999997,48.00277700000004],[-65.472778,48.01138300000014],[-65.47860700000001,48.01971400000008],[-65.48472600000002,48.03388200000012],[-65.491104,48.04249600000014],[-65.50418100000002,48.04888200000005],[-65.68916299999995,48.093879999999956],[-65.7644499999999,48.10999300000003],[-65.88890099999992,48.19915800000001],[-65.90417500000001,48.205826],[-65.94999699999994,48.191101],[-65.95639,48.18888100000004],[-66.006958,48.15915699999999],[-66.02471899999995,48.13916000000012],[-66.12971499999992,48.10721600000011],[-66.24276700000001,48.109161000000086],[-66.39639299999993,48.11499800000007],[-66.40638699999994,48.11638599999998],[-66.43249500000002,48.11859900000013],[-66.47084000000001,48.11943800000006],[-66.47778299999999,48.11804999999998],[-66.48416099999997,48.11554699999999],[-66.495544,48.10943600000013],[-66.50639299999995,48.10221899999999],[-66.52555799999999,48.08554800000002],[-66.52999899999992,48.08055100000007],[-66.66722099999998,48.0283280000001],[-66.67361499999998,48.026099999999985],[-66.76371799999998,48.00622599999997],[-66.84370399999995,47.996650999999986],[-66.84249899999998,47.99221800000004],[-66.83666999999997,47.98888400000004],[-66.828888,47.98721299999994],[-66.74999999999994,47.979988000000105],[-66.72888199999994,47.98443600000007],[-66.61082499999998,48.01110799999998],[-66.58473199999997,48.019440000000145],[-66.57333399999999,48.02582600000005],[-66.54055800000003,48.03638500000011],[-66.43443300000001,48.067497],[-66.42027300000001,48.070549000000085],[-66.36416599999995,48.07332600000001],[-66.35665899999992,48.07332600000001],[-66.35082999999992,48.069717000000026],[-66.34999099999993,48.06471300000004],[-66.25917099999998,47.99943500000012],[-66.04222099999998,47.93582200000009],[-65.98889200000002,47.92388199999999],[-65.97027600000001,47.92083000000008],[-65.936935,47.92083000000008],[-65.92222599999997,47.92276800000002],[-65.90695199999999,47.92332500000009],[-65.88027999999991,47.92054700000011],[-65.843887,47.91137700000007],[-65.81861900000001,47.90387700000002],[-65.81138599999991,47.900825999999995],[-65.79360999999994,47.89083100000005],[-65.77278099999995,47.876380999999924],[-65.75750699999998,47.865273000000116],[-65.74638399999998,47.85277599999995],[-65.7250059999999,47.82749199999995],[-65.718613,47.81888600000008],[-65.714447,47.80943300000001],[-65.71362299999998,47.80416100000008],[-65.69694499999997,47.73304700000011],[-65.67193600000002,47.64582800000005],[-65.66777000000002,47.64138000000008],[-65.63473499999998,47.62082700000002],[-65.62832600000002,47.623046999999985],[-65.38999899999999,47.736107000000004],[-65.33277900000002,47.76693700000004],[-65.25389099999995,47.80165900000003],[-65.24082900000002,47.806655999999975],[-65.202789,47.81860399999999],[-65.16749600000003,47.825271999999984],[-65.04472399999997,47.844436999999914],[-65.02084400000001,47.844993999999986],[-64.98500099999995,47.84137700000008],[-64.81555200000003,47.811104000000114],[-64.80555700000002,47.80888400000009],[-64.79722600000002,47.8063810000001],[-64.71916199999998,47.764441999999974],[-64.71333299999998,47.761108000000036],[-64.67666599999995,47.7355500000001],[-64.67027300000001,47.72693600000002],[-64.67332499999992,47.72026800000003],[-64.67944299999999,47.71665999999993],[-64.7036129999999,47.70694000000003],[-64.80332899999996,47.63054700000009],[-64.85972599999997,47.57666000000012],[-64.870094,47.53629300000006],[-64.87110899999999,47.51583100000005],[-64.87027,47.51082600000001],[-64.87554899999998,47.46082300000006],[-64.88082899999995,47.432495000000074],[-64.88639799999999,47.41415400000005],[-64.91000400000001,47.353049999999996],[-65.13806199999999,47.19221500000003],[-65.226944,47.14083100000005],[-65.23832700000003,47.13472000000013],[-65.26333599999992,47.124435000000005],[-65.33972199999994,47.099433999999974],[-65.36416599999995,47.08971400000007],[-65.3699949999999,47.08665500000012],[-65.36527999999987,47.08277100000009],[-65.21888699999988,47.05360400000001],[-65.10110500000002,47.07694200000009],[-65.01722699999993,47.09137700000002],[-64.80555700000002,47.08305400000006],[-64.79861499999993,47.079994],[-64.80277999999993,46.993049999999926],[-64.80332899999996,46.987495000000024],[-64.80722000000003,46.98165899999998],[-64.81221,46.97776800000008],[-64.81806899999992,46.9741590000001],[-64.83583099999998,46.96582799999999],[-64.85722399999997,46.95277399999992],[-64.87193300000001,46.939430000000016],[-64.88027999999991,46.93054999999998],[-64.89222699999999,46.91443600000008],[-64.89611799999994,46.90888200000006],[-64.89916999999997,46.90248900000012],[-64.90499899999998,46.88360600000004],[-64.906387,46.872490000000084],[-64.90499899999998,46.85110500000013],[-64.9036099999999,46.84082799999993],[-64.87721299999998,46.79110700000007],[-64.86389199999996,46.77443699999992],[-64.81806899999992,46.72165700000005],[-64.74861099999998,46.70277399999998],[-64.74027999999998,46.70249200000012],[-64.72639499999991,46.69638100000003],[-64.72084000000001,46.693047000000035],[-64.71333299999998,46.68415800000014],[-64.71112099999999,46.67999300000014],[-64.70861799999994,46.66999100000004],[-64.70500199999998,46.638329000000056],[-64.67332499999992,46.500832],[-64.66194200000001,46.468048000000124],[-64.65083300000003,46.460548000000074],[-64.62193300000001,46.4272160000001],[-64.61361699999998,46.41443599999997],[-64.61193800000001,46.409714000000065],[-64.615005,46.39249400000011],[-64.61305199999998,46.366104000000064],[-64.50418100000002,46.240273],[-64.402222,46.233047000000056],[-64.237503,46.22915599999999],[-64.11694299999994,46.18193800000006],[-64.035553,46.182213000000104],[-63.970832999999914,46.18054999999998],[-63.954444999999964,46.17804699999999],[-63.83028399999995,46.146385000000066],[-63.822227,46.14388299999996],[-63.776389999999935,46.12110100000007],[-63.77305599999994,46.11749300000014],[-63.77111100000002,46.112769999999955],[-63.77249899999987,46.108047],[-63.77694700000001,46.1033250000001],[-63.78305799999998,46.09971600000006],[-63.79944599999999,46.09137700000002],[-63.80555700000002,46.08915700000006],[-63.886391,46.06082200000003],[-63.89250199999992,46.05888400000009],[-63.91944899999993,46.053047000000106],[-63.92694899999992,46.052490000000034],[-63.988609,46.05193300000013],[-64.02333099999998,46.057495000000074],[-64.06806899999998,46.05943300000001],[-64.07250999999997,46.05471000000006],[-64.093887,46.02166],[-64.06500199999988,46.00471500000003],[-64.04278599999998,45.99189800000005],[-64.01251200000002,46.005829000000006],[-64.00527999999991,46.00555400000002],[-63.913054999999986,45.979987999999935],[-63.86416600000001,45.96110500000003],[-63.859443999999996,45.95193499999999],[-63.86138900000003,45.94582400000013],[-63.84610699999996,45.93082400000014],[-63.714721999999995,45.840546000000074],[-63.66999800000002,45.81805400000002],[-63.664161999999976,45.815268999999944],[-63.64583600000003,45.83332800000005],[-63.63166799999999,45.85943600000002],[-63.600280999999995,45.869986999999924],[-63.58055899999994,45.87443500000012],[-63.48249800000002,45.8772130000001],[-63.474441999999954,45.87693800000005],[-63.45722199999989,45.87416099999996],[-63.420279999999934,45.86499799999996],[-63.406661999999926,45.858887000000095],[-63.403884999999946,45.85443900000013],[-63.42861199999993,45.82360799999998],[-63.434440999999936,45.82083100000011],[-63.441108999999926,45.81944299999998],[-63.45610799999997,45.81888600000008],[-63.488051999999925,45.82083100000011],[-63.51333599999998,45.82416500000005],[-63.520835999999974,45.82388300000002],[-63.52583299999998,45.81999200000013],[-63.52666499999998,45.81443800000011],[-63.5236129999999,45.80998999999997],[-63.515556000000004,45.80721300000005],[-63.50695000000002,45.80582400000009],[-63.43360899999993,45.79943800000001],[-63.42556000000002,45.799164000000076],[-63.34332999999998,45.797492999999974],[-63.32833899999997,45.79833200000013],[-63.28722399999998,45.80554999999998],[-63.281113000000005,45.80776999999995],[-63.27417000000003,45.80888399999998],[-63.25111399999997,45.80971499999998],[-63.235000999999954,45.80860100000001],[-63.22943900000001,45.80499300000008],[-63.23332999999997,45.79943800000001],[-63.23889200000002,45.79638699999998],[-63.31388900000002,45.76944000000003],[-63.319725000000005,45.76805100000007],[-63.35583500000001,45.76444200000003],[-63.372222999999906,45.76638800000012],[-63.379997,45.766106000000036],[-63.38194299999998,45.759995],[-63.37666300000001,45.75582900000006],[-63.361114999999984,45.74554399999994],[-63.35444599999994,45.74249300000014],[-63.31361400000003,45.736938000000066],[-63.282501000000025,45.73333000000014],[-63.189719999999966,45.73443600000013],[-63.120833999999945,45.7594380000001],[-63.09055299999994,45.79027600000006],[-63.082779000000016,45.80332199999998],[-62.99388899999997,45.79638699999998],[-62.985275,45.794998000000135],[-62.95833600000003,45.788887000000045],[-62.72361000000001,45.764160000000004],[-62.677779999999984,45.764160000000004],[-62.55722000000003,45.67471300000011],[-62.50389099999995,45.62748700000009],[-62.46194499999996,45.61249500000008],[-62.25028199999991,45.708327999999995],[-62.092772999999966,45.78110500000014],[-62.03500399999996,45.82083100000011],[-62.01500699999991,45.83665500000001],[-61.97332799999998,45.86721000000006],[-61.93138899999997,45.884720000000016],[-61.92555999999996,45.88610799999992],[-61.91750300000001,45.88555100000002],[-61.903052999999886,45.87943300000012],[-61.89805599999994,45.87526700000001],[-61.89611099999996,45.871101000000124],[-61.89805599999994,45.865273],[-61.90332799999999,45.861382000000106],[-61.914718999999934,45.8555530000001],[-61.919448999999986,45.85110500000013],[-61.923332000000016,45.84554300000002],[-61.92555999999996,45.8394320000001],[-61.92527799999999,45.834434999999985],[-61.88999899999999,45.701385000000016],[-61.88555899999989,45.6905440000001],[-61.88138600000002,45.686653000000035],[-61.79222899999991,45.63916000000012],[-61.78333299999997,45.63665800000001],[-61.7350009999999,45.62332200000009],[-61.72499800000003,45.62082700000002],[-61.618056999999965,45.610550000000046],[-61.603888999999924,45.63526900000005],[-61.569999999999936,45.66999100000004],[-61.565001999999936,45.673882000000106],[-61.55916599999995,45.67665900000003],[-61.546111999999994,45.681107],[-61.526107999999965,45.68526500000013],[-61.50444799999997,45.68693500000006],[-61.48889200000002,45.68693500000006],[-61.471382000000006,45.682495000000074],[-61.466110000000015,45.678878999999995],[-61.39639299999993,45.62665600000008],[-61.38694799999996,45.61888099999999],[-61.35342799999995,45.56971400000009],[-61.316146999999944,45.53317300000003],[-61.26000199999993,45.51027700000009],[-61.23235699999998,45.46119299999998],[-61.294167000000016,45.434714999999926],[-61.36500499999994,45.404160000000104],[-61.36805700000002,45.41387900000012],[-61.37471799999997,45.41693899999996],[-61.38861099999991,45.41415400000011],[-61.40083299999998,45.410820000000115],[-61.41332999999997,45.40693700000003],[-61.462219000000005,45.384438000000046],[-61.477492999999924,45.3730470000001],[-61.48166699999996,45.367767000000015],[-61.478882,45.36332700000003],[-61.46388999999999,45.346939000000134],[-61.457222,45.34360500000014],[-61.22638699999993,45.34415400000012],[-61.153327999999874,45.34832799999998],[-61.139441999999974,45.34887700000007],[-61.13166799999999,45.34832799999998],[-61.04722599999997,45.33554800000002],[-60.99639100000002,45.32749200000012],[-60.980552999999986,45.32444000000004],[-60.970551,45.321663000000115],[-60.966110000000015,45.31832900000012],[-60.964721999999995,45.313049000000035],[-60.96527900000001,45.295547],[-60.97027600000001,45.26971400000008],[-61.05083499999989,45.23110200000008],[-61.0777819999999,45.21943700000003],[-61.09027899999995,45.21554600000013],[-61.10972600000002,45.21082300000012],[-61.12332900000001,45.208602999999925],[-61.13972499999994,45.21082300000012],[-61.14222699999999,45.21527100000009],[-61.222220999999934,45.23832700000014],[-61.26750199999998,45.24638400000009],[-61.3130569999999,45.24276699999996],[-61.323890999999946,45.23610700000012],[-61.360000999999954,45.20999100000006],[-61.373610999999926,45.196380999999974],[-61.373328999999956,45.19110100000012],[-61.36555499999997,45.18832400000002],[-61.34972399999998,45.186935000000005],[-61.340836000000024,45.184433000000126],[-61.34416199999987,45.17804700000005],[-61.34944200000001,45.17443800000001],[-61.355002999999954,45.171660999999915],[-61.38444500000003,45.15915700000005],[-61.39749899999998,45.156097000000045],[-61.450835999999924,45.14554600000008],[-61.45861100000002,45.14471400000002],[-61.54389199999997,45.141662999999994],[-61.638053999999954,45.12027000000006],[-61.724715999999944,45.09166000000005],[-61.898338000000024,45.02499399999999],[-62.02666499999992,44.98471799999999],[-62.08777599999996,44.97026800000009],[-62.28639199999992,44.92804700000005],[-62.391944999999964,44.90832500000005],[-62.476386999999875,44.89554600000014],[-62.521942000000024,44.85082999999997],[-62.54611199999994,44.821663],[-62.641388000000006,44.80915800000008],[-62.79500599999989,44.78054800000007],[-62.801109,44.77860300000009],[-62.81388899999996,44.750832],[-62.80999800000001,44.73471800000004],[-62.851111999999944,44.71832300000011],[-62.92861199999987,44.733879000000115],[-63.01277900000002,44.773323000000005],[-63.020554000000004,44.77388000000008],[-63.05555700000002,44.772766000000104],[-63.0625,44.77137800000003],[-63.06194299999993,44.76638800000012],[-63.06027999999998,44.761664999999994],[-63.057503,44.757217000000026],[-63.04361699999993,44.73998999999998],[-63.017776000000026,44.72248800000011],[-63.01250499999992,44.71332600000005],[-63.01194800000002,44.70804600000014],[-63.01361800000001,44.70277400000003],[-63.01833299999993,44.69748700000008],[-63.048339999999996,44.67610200000013],[-63.05471799999998,44.673325000000034],[-63.104445999999996,44.74665800000014],[-63.11527999999987,44.73137700000001],[-63.11833199999995,44.7249910000001],[-63.13833599999998,44.69304700000009],[-63.142776000000026,44.688599000000124],[-63.283057999999926,44.62721299999998],[-63.43999499999995,44.590828000000045],[-63.44888300000002,44.59304800000007],[-63.49500299999994,44.61471599999999],[-63.526336999999955,44.63610099999994],[-63.535168,44.6427690000001],[-63.545334000000025,44.65210700000006],[-63.55699900000002,44.66160600000012],[-63.61583699999994,44.70249199999995],[-63.635001999999986,44.71138000000013],[-63.64277599999991,44.71415700000006],[-63.651107999999965,44.71554600000002],[-63.65833299999997,44.714995999999985],[-63.660552999999936,44.70832800000005],[-63.64944499999996,44.686104000000114],[-63.640556000000004,44.673050000000046],[-63.635559,44.668884000000105],[-63.627776999999924,44.666382000000056],[-63.60611,44.668884000000105],[-63.59861000000001,44.66777000000013],[-63.59194200000002,44.66471100000001],[-63.58361100000002,44.65693699999997],[-63.56422399999991,44.62076999999999],[-63.558220000000006,44.613266000000124],[-63.555388999999934,44.60776900000002],[-63.546059000000014,44.58860400000003],[-63.520835999999974,44.512771999999984],[-63.520279000000016,44.50777399999998],[-63.52527600000002,44.49527000000012],[-63.53333299999997,44.484993000000145],[-63.54277799999994,44.476379000000065],[-63.553054999999915,44.469711000000075],[-63.57083899999992,44.46193700000009],[-63.63111099999992,44.43582200000009],[-63.63861099999991,44.436935000000005],[-63.90694400000001,44.49527000000012],[-63.91361199999989,44.498604000000114],[-63.924171,44.50610399999999],[-63.932503,44.513329000000056],[-63.93555500000002,44.517494000000056],[-63.94388600000002,44.536110000000065],[-63.938605999999936,44.616104000000064],[-63.93777499999993,44.62165800000008],[-63.92805499999986,44.64222000000001],[-63.91916699999996,44.651657000000114],[-63.91444399999989,44.65554800000001],[-63.90860700000002,44.678047000000106],[-64.00834700000001,44.647491],[-64.04527299999995,44.63582600000012],[-64.05526699999996,44.61943800000006],[-64.06555199999991,44.59526800000003],[-64.06388899999996,44.59054599999996],[-64.05915800000002,44.581665000000044],[-64.05499299999997,44.57777399999998],[-64.03944399999995,44.572495],[-64.03361499999994,44.563049000000035],[-64.00917099999998,44.513329000000056],[-64.01000999999997,44.50777399999998],[-64.08306900000002,44.46666000000005],[-64.091949,44.46888000000007],[-64.11054999999999,44.478324999999984],[-64.12165799999997,44.48526800000013],[-64.12554899999998,44.51055100000002],[-64.12361099999993,44.52748900000012],[-64.11972000000003,44.53943600000008],[-64.12165799999997,44.54415900000009],[-64.12748699999992,44.552773000000116],[-64.13583399999999,44.56054699999993],[-64.146118,44.56832900000006],[-64.17027300000001,44.58610500000003],[-64.20083599999998,44.57638499999996],[-64.30526700000001,44.53333299999997],[-64.33750900000001,44.411933999999974],[-64.34666400000003,44.36249500000014],[-64.346115,44.357215999999994],[-64.32972699999993,44.32888000000003],[-64.31111099999993,44.319159999999954],[-64.30332899999996,44.316666000000055],[-64.29527300000001,44.316101],[-64.29055799999998,44.31999200000007],[-64.29222099999998,44.324715000000026],[-64.29998799999993,44.32749200000012],[-64.30555700000002,44.330826000000116],[-64.30943300000001,44.33554800000002],[-64.30777,44.3408280000001],[-64.30110200000001,44.341933999999924],[-64.27362099999988,44.33027600000008],[-64.26055899999994,44.324164999999994],[-64.23944099999994,44.29415899999992],[-64.25334199999992,44.27526899999998],[-64.25805699999995,44.26998900000012],[-64.28332499999988,44.25305200000008],[-64.319458,44.26471700000002],[-64.35583500000001,44.27332300000012],[-64.39111300000002,44.253326000000015],[-64.42805499999992,44.22832500000004],[-64.43222000000003,44.22360200000003],[-64.44471699999991,44.190269],[-64.61639400000001,44.13304900000014],[-64.61860699999994,44.07193799999999],[-64.66639700000002,43.990273000000116],[-64.67138699999998,43.98638200000005],[-64.73222399999992,43.951660000000004],[-64.73805199999993,43.94943200000006],[-64.74526999999995,43.94887499999999],[-64.77639799999997,43.950829],[-64.80610699999994,43.95054600000003],[-64.81277499999993,43.94943200000006],[-64.81806899999992,43.94638100000003],[-64.83222999999992,43.92610200000013],[-64.881104,43.838882000000126],[-64.906387,43.80054499999994],[-65.03056299999997,43.70416300000005],[-65.06666599999994,43.69638100000009],[-65.24221799999992,43.679161000000136],[-65.32583599999987,43.674995000000024],[-65.37527499999987,43.5752720000001],[-65.44915800000001,43.55971500000004],[-65.45333899999997,43.55499300000014],[-65.47582999999997,43.505829000000006],[-65.48138399999999,43.46443900000003],[-65.49694799999997,43.49082900000002],[-65.54804999999993,43.55609900000002],[-65.55943300000001,43.568054000000075],[-65.56861899999996,43.5702740000001],[-65.57556199999999,43.569717000000026],[-65.58473200000003,43.56027199999994],[-65.591385,43.549721000000034],[-65.603882,43.534721000000104],[-65.612213,43.526099999999985],[-65.61749299999997,43.523604999999975],[-65.646118,43.51194000000004],[-65.67332499999992,43.50610399999999],[-65.712784,43.498604000000114],[-65.72055099999994,43.499161000000015],[-65.72582999999986,43.50249500000001],[-65.777222,43.562492000000134],[-65.78332499999993,43.57110600000004],[-65.78388999999999,43.576385000000016],[-65.78195199999993,43.587769000000094],[-65.778885,43.599998000000085],[-65.773056,43.612770000000125],[-65.77111799999994,43.624435000000005],[-65.76945499999994,43.64138000000014],[-65.76806599999992,43.65804300000002],[-65.76834099999996,43.66888399999999],[-65.76972999999987,43.679161000000136],[-65.77555799999999,43.68832400000014],[-65.86888099999999,43.78638500000005],[-65.90777599999996,43.82166300000006],[-65.91221599999989,43.82527200000004],[-65.91861,43.82833100000005],[-65.93277,43.82721700000002],[-65.93888899999996,43.82499700000005],[-65.94249000000002,43.819443000000035],[-65.9561159999999,43.7761000000001],[-65.968887,43.71943699999997],[-65.97166399999998,43.71276899999998],[-65.97500600000001,43.70721400000008],[-65.98306300000002,43.697768999999994],[-66.01333599999987,43.69165800000013],[-66.02055399999995,43.69110100000006],[-66.029449,43.73165900000009],[-66.03056299999997,43.73610700000006],[-66.033615,43.740273],[-66.04222099999998,43.748046999999985],[-66.08084100000002,43.76805100000007],[-66.08860799999997,43.768326000000116],[-66.09445199999999,43.76610600000009],[-66.10777299999995,43.75332600000013],[-66.12165800000002,43.762215000000026],[-66.135559,43.78943600000008],[-66.16694599999994,43.85860399999996],[-66.16805999999991,43.863051999999925],[-66.16805999999991,43.895546000000024],[-66.16749599999997,43.90138200000007],[-66.16583299999996,43.907211000000075],[-66.151947,43.91915900000009],[-66.15028399999994,43.92527000000001],[-66.14999399999994,43.93082400000003],[-66.14916999999997,44.00110600000011],[-66.14973399999991,44.011108000000036],[-66.18194599999993,44.06749700000012],[-66.204453,44.08665500000001],[-66.19055200000003,44.15054300000003],[-66.18777499999993,44.16193400000003],[-66.118607,44.33804300000003],[-66.09388699999988,44.36749300000014],[-66.08999599999999,44.37165800000014],[-66.03750599999995,44.42332500000009],[-65.97694399999995,44.477486],[-65.96722399999999,44.48610700000012],[-65.95666499999993,44.49166100000008],[-65.95028699999995,44.493050000000096],[-65.94444299999998,44.4897160000001],[-65.93804899999992,44.49110400000001],[-65.86582899999996,44.53888699999999],[-65.84167499999995,44.56860400000011],[-65.84138499999995,44.574164999999994],[-65.84445199999988,44.57833100000005],[-65.84889199999998,44.582213999999965],[-65.85527000000002,44.585823000000005],[-65.86277799999988,44.58693699999998],[-65.931107,44.582213999999965],[-65.94305399999996,44.57777399999998],[-65.95861799999994,44.567497],[-66.004456,44.53582799999998],[-66.03472899999997,44.51471700000013],[-66.12332200000003,44.448875000000044],[-66.17777999999993,44.396660000000054],[-66.18582199999997,44.38721499999997],[-66.19055200000003,44.383331],[-66.19722000000002,44.386108000000036],[-66.19860799999998,44.41276600000003],[-66.19110099999995,44.42332500000009],[-66.10305800000003,44.500000000000114],[-66.06806899999992,44.524994000000106],[-65.97166399999998,44.591934000000094],[-65.82022099999995,44.65443400000004],[-65.81672699999996,44.655768999999964],[-65.80872299999993,44.65193600000009],[-65.80289500000003,44.64460400000007],[-65.79639400000002,44.62426800000003],[-65.79689799999994,44.617603000000145],[-65.79789700000003,44.61393700000002],[-65.75695799999994,44.61527300000006],[-65.756393,44.60999300000003],[-65.75306699999999,44.60582700000009],[-65.74527,44.605552999999986],[-65.69722000000002,44.61249500000008],[-65.69027699999992,44.614441],[-65.68499799999995,44.61693600000001],[-65.62527499999999,44.658882000000006],[-65.52250700000002,44.737769999999955],[-65.54861499999998,44.733879000000115],[-65.68261699999994,44.69315699999993],[-65.68627899999996,44.691825999999935],[-65.69027699999992,44.69116200000008],[-65.69544199999996,44.691825999999935],[-65.704117,44.69499200000007],[-65.70611600000001,44.697655],[-65.70711499999999,44.700489000000005],[-65.70745099999999,44.70348700000005],[-65.70594799999998,44.707489000000066],[-65.70094299999994,44.713157999999964],[-65.69793700000002,44.71549200000004],[-65.71777299999997,44.72193100000004],[-65.65833999999995,44.758605999999986],[-65.64695699999993,44.76527399999998],[-65.29998799999993,44.92832900000013],[-65.20249899999999,44.97387700000007],[-65.11416600000001,45.01166500000011],[-64.93415800000002,45.100273000000016],[-64.91805999999991,45.11110700000006],[-64.87943999999999,45.13082099999997],[-64.86193800000001,45.139717000000076],[-64.81471299999998,45.15804300000008],[-64.80860899999993,45.16027100000008],[-64.777222,45.16999099999998],[-64.74499500000002,45.178329000000076],[-64.71083099999998,45.183876000000055],[-64.59028599999994,45.208046000000024],[-64.55055199999993,45.216660000000104],[-64.46888699999994,45.24276699999996],[-64.45140099999998,45.24943500000012],[-64.4344329999999,45.25750000000005],[-64.41777000000002,45.26666300000005],[-64.39750699999996,45.281105000000025],[-64.39389,45.28694200000001],[-64.39195299999994,45.29277000000013],[-64.39111300000002,45.29833200000007],[-64.39306599999986,45.303322000000094],[-64.40167199999996,45.31110400000006],[-64.40695199999993,45.31443800000005],[-64.41389500000002,45.317497],[-64.43083200000001,45.322220000000016],[-64.45472699999993,45.32360800000009],[-64.46221899999995,45.32305100000002],[-64.47083999999995,45.32444000000004],[-64.48805199999998,45.329162999999994],[-64.49471999999997,45.33221400000002],[-64.48916599999995,45.335266000000104],[-64.46583599999991,45.33471700000001],[-64.44055200000003,45.331665000000044],[-64.35305799999992,45.316101],[-64.33833300000003,45.31027199999994],[-64.32749899999999,45.303322000000094],[-64.32139599999994,45.294715999999994],[-64.31777999999991,45.28527100000014],[-64.31722999999988,45.280273000000136],[-64.31777999999991,45.274437000000034],[-64.32194499999991,45.26971400000008],[-64.32749899999999,45.266936999999984],[-64.34306299999997,45.25610399999999],[-64.35333300000002,45.23915900000003],[-64.38583399999993,45.14554600000008],[-64.38027999999986,45.13110400000011],[-64.36389199999996,45.10138699999999],[-64.35972599999997,45.09748799999994],[-64.35221899999993,45.09804500000007],[-64.34695399999998,45.101105000000075],[-64.337219,45.10860400000007],[-64.33389299999993,45.115272999999945],[-64.33444199999997,45.12027000000006],[-64.333328,45.131660000000124],[-64.32917800000001,45.13638300000008],[-64.324387,45.13934300000005],[-64.31138599999997,45.14138000000003],[-64.29583699999995,45.14138000000003],[-64.24415599999998,45.12387799999999],[-64.22111499999994,45.11054999999999],[-64.21028099999995,45.10360700000001],[-64.15722699999998,45.056938],[-64.14695699999999,45.04444100000006],[-64.14555399999989,45.034720999999934],[-64.154449,44.98443600000013],[-64.15638699999994,44.97832500000004],[-64.11694299999994,45.00916300000006],[-64.11416599999995,45.04666100000003],[-64.12193300000001,45.05804400000005],[-64.13639799999993,45.07444000000004],[-64.14167800000001,45.07860599999998],[-64.1625059999999,45.09221600000001],[-64.18832399999991,45.104713000000004],[-64.19249000000002,45.10860400000007],[-64.19860799999987,45.11721],[-64.19888299999997,45.122490000000084],[-64.19583099999994,45.15054300000003],[-64.16361999999998,45.185265000000015],[-64.15278599999999,45.19276400000001],[-64.11833199999995,45.20888500000001],[-64.10611,45.21332600000011],[-64.09999099999993,45.21527100000009],[-64.06582600000002,45.22221400000012],[-64.00805700000001,45.23638199999999],[-63.98221599999994,45.243049999999926],[-63.95666499999999,45.25138899999996],[-63.80583199999995,45.30193300000013],[-63.59610700000002,45.3155440000001],[-63.47083299999986,45.321663000000115],[-63.384170999999924,45.35083000000003],[-63.37194099999999,45.35499600000014],[-63.365554999999915,45.35777300000001],[-63.360832000000016,45.36082499999998],[-63.36860699999994,45.36360900000011],[-63.73889200000002,45.396660000000054],[-63.75556199999994,45.39804800000013],[-63.79722600000002,45.39276899999999],[-63.83777599999996,45.385551000000135],[-63.98805199999998,45.384438000000046],[-64.04055800000003,45.40110000000004],[-64.04499800000002,45.40443400000004],[-64.06111099999998,45.40971400000012],[-64.06973299999999,45.41027100000002],[-64.083618,45.409430999999984],[-64.16332999999986,45.403877000000136],[-64.214722,45.399719000000005],[-64.31277499999993,45.39138000000014],[-64.35777299999995,45.38110400000005],[-64.52999899999998,45.40804300000002],[-64.67416400000002,45.383049000000085],[-64.81582599999996,45.348602000000085],[-64.92944299999999,45.32444000000004],[-64.93721,45.32694200000009],[-64.93804899999992,45.33221400000002],[-64.93666100000002,45.34332300000011],[-64.93331899999998,45.35555300000004],[-64.9177699999999,45.40859999999992],[-64.90916399999998,45.418052999999986],[-64.83138999999994,45.47915599999993],[-64.76556399999998,45.50555400000013],[-64.69915799999995,45.53110499999997],[-64.568893,45.60416399999997],[-64.47055099999994,45.67027300000012],[-64.43028299999997,45.71554600000002],[-64.33222999999992,45.76888300000013],[-64.33168,45.763611000000026],[-64.32611099999997,45.749435000000005],[-64.29666099999992,45.76332899999994],[-64.28306600000002,45.77665699999994],[-64.27555799999999,45.79999500000008],[-64.27305599999994,45.811661000000015],[-64.27000399999991,45.82888000000008],[-64.27293399999996,45.835754000000065],[-64.27362099999988,45.838599999999985],[-64.27667199999996,45.8427660000001],[-64.32472200000001,45.87999000000002],[-64.33277899999996,45.88276700000006],[-64.347778,45.881935],[-64.36138899999997,45.879158000000075],[-64.36694299999999,45.87638099999998],[-64.36776699999996,45.87054400000005],[-64.36332700000003,45.86666100000008],[-64.35472099999993,45.865547000000106],[-64.35749800000002,45.85110500000013],[-64.41805999999991,45.796104000000014],[-64.4783329999999,45.750549000000035],[-64.49722300000002,45.783882000000006],[-64.48999000000003,45.794998000000135],[-64.48805199999998,45.801102000000014],[-64.48916599999995,45.81137800000005],[-64.49221799999998,45.81554399999999],[-64.59733599999998,45.92210400000005],[-64.68194599999987,46.02166],[-64.686935,46.041382000000056],[-64.69055199999997,46.05082700000008],[-64.69499199999996,46.05471000000006],[-64.73693799999995,46.083878000000084],[-64.74749800000001,46.09054600000002],[-64.754456,46.08915700000006],[-64.76445000000001,46.08305400000012],[-64.70639,45.994713000000104],[-64.70194999999995,45.990829000000076],[-64.64800999999994,45.93304799999993],[-64.63117199999999,45.92271800000003],[-64.62899800000002,45.92038300000007],[-64.601181,45.88155000000012],[-64.601181,45.877384000000006],[-64.60134099999999,45.87388199999998],[-64.602844,45.86721399999999],[-64.60450700000001,45.863552000000084],[-64.58306900000002,45.826942000000145],[-64.75639299999995,45.62248999999997],[-64.77250699999996,45.609993000000145],[-64.77833599999997,45.60721600000005],[-64.78582799999992,45.61027500000006],[-64.791382,45.613609000000054],[-64.79666099999997,45.62248999999997],[-64.80166599999995,45.62638100000004],[-64.808334,45.62971500000003],[-64.81722999999994,45.63249200000013],[-64.825287,45.633331000000055],[-64.84750400000001,45.633331000000055],[-64.88444500000003,45.63166000000001],[-64.90417500000001,45.627769000000114],[-64.94137599999999,45.60221899999999],[-64.94721999999996,45.59804500000013],[-64.96194500000001,45.58610500000003],[-64.97639500000002,45.57249499999995],[-64.98666399999996,45.564437999999996],[-64.99722300000002,45.557213000000104],[-65.015015,45.54888200000005],[-65.04750100000001,45.539161999999976],[-65.10444599999994,45.524994000000106],[-65.13833599999992,45.517769000000044],[-65.15222199999994,45.51610600000009],[-65.164444,45.51305400000001],[-65.220551,45.4938810000001],[-65.32667500000002,45.457497000000046],[-65.339447,45.45221699999996],[-65.36805700000002,45.437767000000065],[-65.394455,45.41944100000006],[-65.42138699999992,45.40277100000009],[-65.53195199999999,45.342490999999995],[-65.88362099999995,45.209160000000054],[-65.88999899999999,45.2074970000001],[-65.90360999999996,45.205551000000014],[-65.91082799999998,45.20526899999999],[-65.91888399999993,45.20609999999999],[-65.98332199999993,45.21971100000013],[-65.98998999999998,45.22304500000013],[-66.09060699999992,45.295657999999946],[-66.09294099999994,45.297989000000086],[-66.09461199999998,45.30065900000005],[-66.09160599999996,45.30382499999996],[-66.08389299999993,45.34276600000004],[-66.07806399999993,45.34554300000008],[-66.05749499999996,45.348602000000085],[-66.04527300000001,45.35332500000004],[-66.029449,45.364158999999916],[-66.015289,45.377769],[-66.00306699999999,45.3949970000001],[-66.00083899999998,45.40110000000004],[-65.99722300000002,45.41777000000002],[-65.99444599999998,45.45555099999996],[-65.99444599999998,45.46082300000006],[-66.00250199999999,45.46166200000005],[-66.0083469999999,45.45888500000012],[-66.19027699999998,45.339432000000045],[-66.193329,45.33360300000004],[-66.193329,45.328331000000105],[-66.19055200000003,45.32388300000014],[-66.179169,45.30582399999997],[-66.17610200000001,45.30193300000013],[-66.14527900000002,45.27916000000005],[-66.14166999999992,45.259769000000006],[-66.13700099999994,45.25927000000013],[-66.11399799999998,45.25877400000013],[-66.1135099999999,45.23777000000007],[-66.14723200000003,45.19221500000009],[-66.20556599999998,45.16387899999995],[-66.21665999999999,45.15915700000005],[-66.42777999999998,45.084991],[-66.45973200000003,45.10610200000002],[-66.45973200000003,45.111382000000106],[-66.46112099999993,45.11610400000001],[-66.46806300000003,45.129714999999976],[-66.48889199999991,45.14999400000005],[-66.49638400000003,45.14971900000006],[-66.531387,45.14721700000001],[-66.53750599999995,45.14527100000009],[-66.55999799999995,45.133331],[-66.57139599999994,45.12665600000014],[-66.58612099999999,45.11693600000007],[-66.60804699999994,45.10416400000008],[-66.64222699999999,45.08638000000013],[-66.648056,45.08360300000004],[-66.75472999999988,45.055550000000096],[-66.79249600000003,45.05526700000013],[-66.77694699999995,45.08638000000013],[-66.77610799999997,45.09137700000008],[-66.77778599999999,45.096100000000035],[-66.78306599999996,45.099716000000114],[-66.96556099999992,45.17943600000001],[-67.02194199999985,45.17027300000001],[-67.027222,45.168052999999986],[-67.04638699999998,45.12693800000005],[-67.12943999999999,45.17221799999999],[-67.18693499999995,45.19221500000009],[-67.2065429999999,45.18303700000007],[-67.23611499999993,45.193877999999984],[-67.25306699999993,45.199432],[-67.261124,45.201103000000046],[-67.26777599999997,45.200546000000145],[-67.27500900000001,45.1988750000001],[-67.28721599999994,45.19415300000003],[-67.29055799999998,45.182770000000005],[-67.29028299999999,45.17748999999992],[-67.29222099999993,45.166100000000085],[-67.29638699999992,45.16082],[-67.30139199999996,45.156937000000084],[-67.30665599999986,45.15332000000012],[-67.318893,45.14860500000009],[-67.32556199999999,45.147491000000116],[-67.33306900000002,45.147491000000116],[-67.34194899999994,45.14999400000005],[-67.354172,45.156097000000045],[-67.40388499999995,45.194435000000055],[-67.40805099999994,45.19832599999995],[-67.42250099999995,45.2149960000001],[-67.45527599999997,45.26305400000007],[-67.462784,45.276099999999985],[-67.46501199999989,45.281105000000025],[-67.46528599999999,45.28638500000011],[-67.46417200000002,45.29193900000007],[-67.45056199999993,45.33305400000006],[-67.48500100000001,45.48915900000003],[-67.485275,45.494438],[-67.48277299999995,45.50027499999993],[-67.47888199999989,45.50443999999993],[-67.46777299999997,45.510826000000066],[-67.43638599999997,45.52137800000003],[-67.42193600000002,45.523323000000005],[-67.41583299999996,45.525269000000094],[-67.41082799999992,45.529990999999995],[-67.40695199999988,45.578049000000135],[-67.40888999999999,45.582214000000135],[-67.41250599999995,45.58693699999998],[-67.42416399999996,45.59471100000013],[-67.453888,45.61249500000008],[-67.462219,45.61471599999999],[-67.46945199999999,45.61305199999998],[-67.48611499999998,45.60360700000007],[-67.49999999999994,45.60166200000009],[-67.515015,45.60110500000002],[-67.57389799999999,45.61166400000002],[-67.65666199999998,45.63054699999992],[-67.66444399999995,45.6336060000001],[-67.79110700000001,45.69304700000009],[-67.79666099999992,45.69609800000006],[-67.79916400000002,45.70110299999993],[-67.80444299999999,45.73137700000001],[-67.80638099999999,45.78472099999999],[-67.78666699999991,45.888329000000056],[-67.77250700000002,45.95749699999993],[-67.77917499999995,46.28333299999997],[-67.78889499999997,46.78777300000007],[-67.79167199999995,46.92137900000006],[-67.79499800000002,47.06999200000007],[-67.85972599999991,47.09748800000011],[-67.87416100000002,47.103607000000125],[-67.89222699999999,47.114441],[-67.94860799999992,47.16638200000011],[-67.95140099999998,47.17083000000008],[-67.95584100000002,47.17999300000008],[-67.95722999999992,47.18498999999997],[-67.96194499999996,47.19415300000014],[-67.96888699999994,47.20277400000009],[-68.18582200000003,47.33277100000004],[-68.20861799999994,47.341660000000104],[-68.24499500000002,47.35193600000002],[-68.30665599999992,47.36444099999994],[-68.323059,47.365829000000076],[-68.337219,47.363609000000054],[-68.34889199999992,47.359992999999974],[-68.36776699999996,47.35110500000002],[-68.37304699999993,47.34721400000012],[-68.56471299999993,47.28971900000005],[-68.76194800000002,47.23276499999997],[-68.78750599999995,47.224709000000075],[-68.83167999999989,47.20888499999995],[-68.88778699999995,47.18804200000005],[-68.89527900000002,47.18998700000009],[-68.958618,47.217209000000025],[-68.96528599999988,47.22054300000002],[-69.02389499999992,47.25027499999993],[-69.03611799999999,47.257217000000026],[-69.04499800000002,47.26444200000009],[-69.04916400000002,47.274437000000034],[-69.05305499999997,47.28943600000008],[-69.05358899999993,47.29377700000009],[-69.05499299999985,47.299438000000066],[-69.05526699999996,47.30471],[-69.056107,47.336655000000064],[-69.05555699999996,47.347488000000055],[-69.05249000000003,47.38054699999998],[-69.04943799999995,47.39221999999995],[-69.045837,47.398604999999975],[-69.04361,47.404709000000025],[-69.039444,47.41693900000013],[-69.03832999999997,47.42249300000009],[-69.03999299999998,47.427490000000034],[-69.04861499999998,47.435546999999985],[-69.05555699999996,47.438599000000124],[-69.12388599999991,47.458327999999995],[-69.13276699999994,47.459991000000116],[-69.23249800000002,47.47137500000002],[-69.23962399999999,47.46441300000009],[-69.30526700000001,47.40026899999998],[-69.42361499999998,47.28333299999997],[-69.65388499999995,47.05526700000013],[-69.71250900000001,46.99694099999999],[-69.84722899999997,46.86221300000011],[-69.99276700000001,46.715828000000045],[-70.00917099999987,46.69804399999998],[-70.026947,46.58749399999999],[-70.03860500000002,46.509995],[-70.04415899999992,46.4749910000001],[-70.047775,46.45388000000008],[-70.05055199999998,46.438599000000124],[-70.06361400000003,46.42416400000002],[-70.068893,46.41971600000005],[-70.07528699999995,46.41777000000013],[-70.08139,46.41777000000013],[-70.08805799999988,46.41499300000004],[-70.11915599999998,46.393608000000086],[-70.200287,46.33638000000008],[-70.24249299999991,46.27916000000005],[-70.28778099999994,46.203049000000135],[-70.30555699999991,46.07888000000008],[-70.3125,45.98582500000009],[-70.30972299999996,45.98082000000005],[-70.30332900000002,45.97776799999997],[-70.29388399999999,45.97554800000012],[-70.27833599999997,45.97526600000003],[-70.260559,45.971374999999966],[-70.25361599999991,45.968323000000055],[-70.24833699999994,45.96471400000007],[-70.23971599999993,45.956657000000064],[-70.23805199999998,45.95193499999999],[-70.25500499999998,45.913048],[-70.258896,45.907493999999986],[-70.26333599999998,45.90277100000003],[-70.39388999999994,45.77804600000013],[-70.46665999999993,45.711937000000034],[-70.55526700000001,45.67276800000013],[-70.57694999999995,45.66082000000006],[-70.63194299999998,45.627769000000114],[-70.69305400000002,45.571938000000046],[-70.72027600000001,45.5283280000001],[-70.725281,45.49971800000003],[-70.72471599999994,45.49471299999999],[-70.712784,45.477768000000026],[-70.70472699999993,45.469154],[-70.68943799999994,45.458046000000024],[-70.86860699999994,45.246101000000124],[-70.87304699999999,45.24137900000005],[-70.87860099999995,45.23860199999996],[-70.886124,45.23804500000006],[-71.021118,45.326660000000004],[-71.085129,45.30770899999999],[-71.13999899999993,45.25305200000008],[-71.14639299999999,45.25249500000001],[-71.17027299999995,45.25388300000009],[-71.18916300000001,45.25777399999998],[-71.21166999999991,45.26610599999998],[-71.23306300000002,45.274993999999936],[-71.23971599999999,45.278046000000074],[-71.26444999999995,45.29083300000008],[-71.28056299999997,45.30193300000013],[-71.28860499999996,45.30443600000007],[-71.30277999999998,45.303047000000106],[-71.31471299999993,45.299438000000066],[-71.32749899999993,45.294441000000006],[-71.42443800000001,45.25],[-71.408615,45.22304500000013],[-71.40222199999994,45.21915400000006],[-71.39889499999998,45.21554600000013],[-71.396118,45.21054800000013],[-71.39584399999995,45.20526899999999],[-71.39862099999999,45.199432],[-71.43249499999996,45.13027200000005],[-71.43611099999993,45.12526700000001],[-71.45916699999998,45.102776000000006],[-71.48277299999995,45.083878000000084],[-71.49305699999996,45.075271999999984],[-71.49638399999992,45.06888600000008],[-71.49888599999997,45.05721300000005],[-71.49722299999996,45.04166399999997],[-71.49415599999998,45.020546000000024],[-71.55471799999998,45.01998900000012],[-71.89277600000003,45.019157000000064],[-72.04998799999998,45.01944000000003],[-72.27165200000002,45.018775999999946],[-72.45916699999987,45.01749400000011],[-72.51028399999996,45.01721200000003],[-72.77888499999995,45.02082800000011],[-72.95638999999994,45.01832600000006],[-73.337173,45.01186400000006],[-73.346115,45.01138300000002],[-73.35299700000002,45.00942199999997],[-73.35926799999999,45.01006300000006],[-73.37666299999995,45.011108000000036],[-73.62277199999994,45.00666000000007],[-73.91164399999991,45.00000000000006],[-74.24916100000002,44.99221800000009],[-74.6820219999999,45.0067140000001],[-74.75111400000003,45.00222000000002],[-74.76972999999992,45.006386000000134],[-74.78582799999998,45.01138300000002],[-74.81220999999988,45.01776899999993],[-74.82888799999995,45.019157000000064],[-74.85028099999994,45.01666300000011],[-74.99082900000002,44.986655999999925],[-75.00140399999998,44.98054500000006],[-75.170547,44.898604999999975],[-75.27806099999992,44.85721600000005],[-75.30166600000001,44.84665699999999],[-75.31777999999986,44.837212000000136],[-75.39584399999995,44.785827999999924],[-75.537216,44.69137600000005],[-75.5625,44.673882000000106],[-75.61805700000002,44.63499500000012],[-75.62805199999997,44.627769],[-75.68249500000002,44.58804300000003],[-75.73611499999993,44.54638700000004],[-75.801941,44.49110400000001],[-75.81138599999997,44.483047000000056],[-75.82055700000001,44.47499099999999],[-75.82472200000001,44.46998600000012],[-75.82833899999997,44.44665500000008],[-75.83416699999998,44.43443300000007],[-75.8411099999999,44.4230500000001],[-75.84944199999995,44.41471100000007],[-75.86416600000001,44.40277100000014],[-75.87999000000002,44.39332600000006],[-75.904449,44.384995],[-75.96610999999996,44.36415899999997],[-75.98217799999992,44.358864000000096],[-75.997772,44.355270000000075],[-76.01945499999994,44.3533250000001],[-76.03472899999991,44.35305000000005],[-76.04695099999998,44.34971600000006],[-76.05776999999995,44.344993999999986],[-76.06443799999994,44.34137700000002],[-76.36337300000002,44.15099299999997],[-76.410278,44.121101000000124],[-76.43472300000002,44.10471300000006],[-76.43998699999997,44.09943400000009],[-76.531387,43.98304699999994],[-76.569458,43.93415799999997],[-76.583618,43.91582499999993],[-76.69749499999995,43.76860000000005],[-76.801941,43.633605999999986],[-76.81695599999995,43.633049000000085],[-76.97416699999991,43.634438000000046],[-77.28832999999992,43.63665800000007],[-77.58277900000002,43.638603000000046],[-77.72999600000003,43.63916000000012],[-77.85777300000001,43.63943499999999],[-77.88722200000001,43.63943499999999],[-78.38806199999993,43.63832900000011],[-78.66305499999999,43.63749700000005],[-78.72471599999994,43.629433000000006],[-78.93832399999991,43.553878999999995],[-79.02806099999998,43.521934999999985],[-79.09527599999996,43.497772],[-79.18472300000002,43.46554600000013],[-79.13221699999997,43.38249200000001],[-79.06678799999997,43.27940000000007],[-79.054169,43.262496999999996],[-79.05332899999996,43.25666000000007],[-79.04499799999996,43.165543000000014],[-79.04472399999997,43.16054500000001],[-79.04583699999995,43.14888000000013],[-79.04943800000001,43.14388300000002],[-79.05972300000002,43.13721500000008],[-79.06361399999992,43.13221000000004],[-79.08111599999995,43.085548000000074],[-79.04333499999996,43.011664999999994],[-79.04083299999996,43.0077740000001],[-79.02166699999992,42.987213000000054],[-79.00584399999991,42.977211000000125],[-78.97860699999995,42.96138000000013],[-78.97193900000002,42.95804600000014],[-78.96278399999994,42.95638300000002],[-78.94665500000002,42.95555100000013],[-78.93859900000001,42.953322999999955],[-78.93277,42.950829000000056],[-78.92749000000003,42.94693799999999],[-78.92027300000001,42.939156000000025],[-78.91833500000001,42.9347150000001],[-78.91528299999999,42.92416400000002],[-78.91722099999993,42.90499100000011],[-78.91833500000001,42.89888000000002],[-78.9266659999999,42.88054699999998],[-78.93221999999997,42.86832400000009],[-78.935272,42.86249500000008],[-78.94249000000002,42.852493000000095],[-78.96583599999997,42.83360299999998],[-78.98693799999995,42.81999200000001],[-79.12110899999999,42.76915700000012],[-79.15444899999994,42.757217000000026],[-79.29943799999995,42.70249200000001],[-79.56645199999997,42.600708000000054],[-79.76342799999992,42.524703999999986],[-79.77667200000002,42.52027099999998],[-80.08612099999999,42.399994000000106],[-80.09695399999993,42.396385000000066],[-80.5102839999999,42.32916300000005],[-80.528549,42.326617999999996],[-80.86915599999998,42.279160000000104],[-81.24916100000002,42.224991000000045],[-81.42443799999995,42.144997000000046],[-81.62361099999998,42.052773000000116],[-81.82223499999998,41.96027400000014],[-82.21806299999997,41.774437000000034],[-82.23889199999996,41.76388500000007],[-82.42527799999999,41.67555199999998],[-82.46278399999994,41.676102000000014],[-82.64999399999994,41.68193800000006],[-82.69665499999996,41.683876],[-83.07194499999991,41.85971799999999],[-83.08084100000002,41.87499200000008],[-83.11741599999988,41.94619400000005],[-83.13082899999989,41.970543000000134],[-83.15028399999994,42.008331],[-83.16860999999994,42.046104000000014],[-83.16833500000001,42.0480500000001],[-83.13722200000001,42.201385000000016],[-83.13249200000001,42.22082499999999],[-83.12332200000003,42.24582700000008],[-83.11805699999996,42.25777400000004],[-83.10777299999995,42.27276600000005],[-83.08695999999998,42.30054500000006],[-83.06221,42.31860399999999],[-83.051941,42.32471500000008],[-83.027222,42.331940000000145],[-83.00222799999995,42.33915700000006],[-82.97582999999997,42.344711000000075],[-82.94055199999997,42.35749800000008],[-82.84138499999995,42.39694199999997],[-82.80888400000003,42.41332200000011],[-82.79360999999994,42.422768000000076],[-82.77528399999994,42.43721000000005],[-82.76306199999999,42.448601],[-82.72999600000003,42.48333000000008],[-82.704453,42.508331000000055],[-82.67027300000001,42.53999300000004],[-82.66528299999993,42.54415899999992],[-82.65910300000002,42.54819500000008],[-82.65075699999994,42.55364200000014],[-82.64497399999999,42.556411999999966],[-82.63055399999996,42.557495000000074],[-82.62222299999996,42.55665600000009],[-82.61416600000001,42.55471000000006],[-82.60583500000001,42.55416100000008],[-82.58639499999992,42.558601000000124],[-82.57167099999998,42.56888600000002],[-82.53582799999987,42.59943400000003],[-82.52139299999993,42.618881000000044],[-82.51333599999987,42.63638300000008],[-82.48472600000002,42.719154],[-82.474716,42.751663000000065],[-82.47111499999994,42.769989000000066],[-82.470551,42.782493999999986],[-82.47193900000002,42.79305300000004],[-82.47332799999992,42.79749300000003],[-82.48055999999991,42.812492000000134],[-82.48194899999993,42.82332600000001],[-82.48110999999994,42.8294370000001],[-82.4644469999999,42.898048000000074],[-82.46250900000001,42.904709000000025],[-82.41877699999998,43.018639000000064],[-82.40417500000001,43.049164000000076],[-82.32223499999998,43.21054799999996],[-82.25279199999994,43.34638200000012],[-82.22888199999994,43.39138000000003],[-82.146118,43.553047000000106],[-82.13027999999997,43.585266000000104],[-82.214447,43.95221700000013],[-82.33167999999995,44.46082300000012],[-82.43055699999996,44.882767000000115],[-82.54305999999997,45.35582699999998],[-82.62999000000002,45.39610299999998],[-82.665009,45.41193399999992],[-82.95417800000001,45.54193900000007],[-83.05082699999991,45.58526600000005],[-83.11221299999994,45.61277000000007],[-83.27084400000001,45.68332699999996],[-83.50029,45.78499599999998],[-83.597778,45.82721700000002],[-83.52389499999998,45.91805300000004],[-83.48777799999999,45.96166199999993],[-83.447769,46.011940000000095],[-83.474716,46.03638500000011],[-83.48332199999999,46.043884000000105],[-83.566666,46.098602000000085],[-83.57749899999999,46.105270000000075],[-83.596115,46.11415899999997],[-83.61054999999993,46.11915600000009],[-83.62777699999987,46.12304699999993],[-83.66305499999987,46.12609900000007],[-83.83056599999986,46.12609900000007],[-83.84611499999994,46.124992000000134],[-83.88389599999994,46.10277600000012],[-83.88803100000001,46.09616100000011],[-83.89225799999991,46.092346000000134],[-83.89800999999994,46.08718900000008],[-83.91799899999995,46.073303000000124],[-83.92300399999993,46.070250999999985],[-83.93600499999997,46.065383999999995],[-83.94284099999999,46.066101],[-83.952789,46.06860399999999],[-83.95889299999993,46.071663000000115],[-83.962784,46.07555400000001],[-84.07667500000002,46.203049000000135],[-84.08972199999994,46.220267999999976],[-84.09916699999991,46.23276499999997],[-84.10583499999996,46.247772],[-84.15695199999999,46.39166300000011],[-84.15834000000001,46.39666],[-84.16027799999995,46.424995000000024],[-84.15444899999994,46.445267000000115],[-84.14917000000003,46.45721400000008],[-84.13999899999999,46.47415900000004],[-84.12193300000001,46.49887799999999],[-84.11805700000002,46.51249700000005],[-84.11833199999995,46.51805100000007],[-84.1199949999999,46.523323000000005],[-84.12249799999995,46.52777100000014],[-84.12638900000002,46.531937000000084],[-84.13249199999996,46.53472099999999],[-84.19276399999995,46.546661000000086],[-84.40861499999988,46.508605999999986],[-84.42832899999996,46.503052000000025],[-84.43443300000001,46.5002750000001],[-84.454453,46.486938000000066],[-84.45944199999997,46.482764999999915],[-84.46389799999997,46.4783250000001],[-84.47471599999994,46.46360800000008],[-84.47999600000003,46.46027400000014],[-84.48638899999997,46.45888500000012],[-84.49471999999997,46.45804600000014],[-84.51251200000002,46.45915999999994],[-84.52999899999998,46.46138000000013],[-84.56500199999999,46.466385],[-84.77500899999995,46.653046000000074],[-84.787781,46.68971300000004],[-84.80694599999993,46.748328999999956],[-84.82556199999988,46.80693800000006],[-84.83277899999996,46.82916300000005],[-84.85694899999999,46.90221400000007],[-84.87222299999996,46.90943100000004],[-84.91749599999997,46.92860400000012],[-85.354446,47.111664000000076],[-85.4641719999999,47.15721100000013],[-85.73889199999996,47.270827999999995],[-85.83972199999994,47.31221000000005],[-86.01472499999994,47.38388099999992],[-86.05139199999996,47.39888000000002],[-86.46665999999993,47.56721500000003],[-86.568893,47.608330000000024],[-86.88444499999997,47.73471799999999],[-87.20140099999998,47.860275000000115],[-87.34167499999995,47.91554299999996],[-87.44471699999997,47.955826],[-88.18832399999997,48.24415600000009],[-88.36805699999991,48.31221000000005],[-88.645554,48.264160000000004],[-88.69166599999994,48.255554000000075],[-88.97416699999991,48.13916000000012],[-89.32333399999999,47.993050000000096],[-89.35665899999998,47.97971300000006],[-89.44776899999994,48.003326000000015],[-89.49312599999996,48.00316600000008],[-89.55665599999998,48.00138900000013],[-89.573059,48.001663000000065],[-89.57887299999993,48.00262500000008],[-89.58306900000002,48.003326000000015],[-89.59861799999993,48.00666000000001],[-89.603882,48.00999500000006],[-89.608337,48.01416000000006],[-89.61471599999999,48.01666300000005],[-89.750565,48.02916000000005],[-89.760559,48.02999100000005],[-89.83889799999997,48.01166500000005],[-89.86250299999995,48.00083200000006],[-89.88806199999999,47.99193600000012],[-89.895554,47.989990000000034],[-89.903885,47.98915900000003],[-89.91166699999997,47.99137900000005],[-89.98222399999997,48.01610599999998],[-89.99305700000002,48.02276599999999],[-90,48.03020499999997],[-90.00083899999998,48.031105000000025],[-90.03277599999996,48.069717000000026],[-90.056107,48.10054800000012],[-90.05943299999996,48.104996000000085],[-90.06500199999994,48.10833000000008],[-90.08168,48.11193800000001],[-90.12721299999987,48.11915600000003],[-90.146118,48.12165800000008],[-90.15638699999994,48.12249000000003],[-90.27999899999998,48.11305199999998],[-90.74082900000002,48.090828000000045],[-90.758896,48.09471100000002],[-90.76945499999994,48.099998000000085],[-90.77833599999997,48.10749800000002],[-90.83860800000002,48.184158000000025],[-90.84167499999995,48.19165800000013],[-90.84306300000003,48.205826],[-90.83805799999999,48.20860300000004],[-90.83362599999992,48.209099000000094],[-90.82972699999999,48.212493999999936],[-90.82919299999998,48.21463800000009],[-90.82888799999995,48.22165699999994],[-90.83029199999993,48.225548],[-90.83250399999991,48.227211000000125],[-90.84916699999991,48.233879000000115],[-90.868607,48.23749500000014],[-90.89805599999988,48.23665600000004],[-90.92832900000002,48.22860000000014],[-90.96916199999993,48.21471400000013],[-91.12609899999995,48.15499100000011],[-91.14916999999997,48.144157000000064],[-91.19248999999996,48.11499800000007],[-91.23222399999997,48.087769000000094],[-91.24888599999997,48.0794370000001],[-91.269455,48.07388300000008],[-91.28332499999999,48.07138100000003],[-91.31166100000002,48.069160000000124],[-91.32556199999999,48.069717000000026],[-91.34722899999997,48.068054000000075],[-91.38137799999998,48.06166100000013],[-91.39222699999993,48.05609900000002],[-91.41833500000001,48.04110700000001],[-91.46278399999994,48.05777000000006],[-91.573624,48.09304800000007],[-91.64514200000002,48.09834300000011],[-91.6875,48.144714000000135],[-91.72972099999998,48.187209999999936],[-91.73416099999992,48.19054399999993],[-91.73971599999999,48.193321000000026],[-91.756958,48.194435],[-91.77610799999997,48.19415300000014],[-91.791672,48.195267000000115],[-91.85055499999999,48.20388000000008],[-91.94027699999992,48.23054500000012],[-91.95658900000001,48.23663300000004],[-91.97084000000001,48.244437999999946],[-91.98582499999998,48.25582900000012],[-91.997772,48.266662999999994],[-92.00723299999999,48.27915999999999],[-92.008896,48.28276800000009],[-92.01112399999994,48.292496000000085],[-92.01167299999992,48.29749300000003],[-92.01333599999992,48.30499300000008],[-92.020554,48.32276900000005],[-92.02806099999998,48.33610500000003],[-92.035553,48.34360500000008],[-92.04194599999994,48.34777100000002],[-92.05194099999994,48.353882000000056],[-92.14167800000001,48.35721600000005],[-92.162216,48.35665899999998],[-92.25723299999993,48.34693900000008],[-92.26501499999989,48.34360500000008],[-92.27610799999997,48.33749399999999],[-92.28028899999998,48.33277100000004],[-92.28582799999998,48.326103000000046],[-92.30055199999993,48.30499300000008],[-92.30082700000003,48.2980500000001],[-92.29722599999997,48.28943600000008],[-92.28860499999996,48.2761000000001],[-92.283615,48.263885000000016],[-92.28306599999996,48.256660000000124],[-92.28555299999994,48.250549000000035],[-92.29028299999999,48.24665800000014],[-92.30671699999994,48.241592000000026],[-92.33168,48.23416099999997],[-92.35194399999995,48.2283250000001],[-92.35665899999998,48.22860000000014],[-92.36166400000002,48.23110200000002],[-92.36915599999998,48.238883999999985],[-92.42639200000002,48.31166100000007],[-92.45527599999997,48.39415700000001],[-92.58222999999998,48.44137599999999],[-92.697769,48.485268000000076],[-92.71528599999994,48.541382000000056],[-92.94305400000002,48.62110100000007],[-92.95306399999993,48.62332200000003],[-92.96610999999996,48.62499199999996],[-93.24499500000002,48.64054900000002],[-93.30888399999998,48.63027200000005],[-93.32250999999997,48.6280440000001],[-93.40834000000001,48.60860400000013],[-93.449997,48.597214000000065],[-93.45666499999999,48.59499400000004],[-93.458618,48.59249100000005],[-93.458618,48.5894320000001],[-93.45611600000001,48.58305400000012],[-93.452789,48.579436999999984],[-93.44972199999995,48.57054900000003],[-93.449997,48.56749700000006],[-93.4541779999999,48.559714999999926],[-93.46055599999994,48.55332199999998],[-93.46583599999991,48.54972099999992],[-93.47639499999997,48.54415899999998],[-93.489441,48.53971899999999],[-93.50306699999987,48.537498000000085],[-93.65695199999999,48.51527399999992],[-93.664444,48.5149990000001],[-93.72416699999997,48.51388500000013],[-93.77861000000001,48.51638800000012],[-93.79305999999997,48.51776899999999],[-93.80027799999993,48.52027100000004],[-93.803604,48.524712000000136],[-93.80555700000002,48.53221100000013],[-93.80972300000002,48.55027000000007],[-93.81777999999997,48.581940000000145],[-93.82000700000003,48.590546000000074],[-93.83000199999998,48.61277000000001],[-93.833328,48.616386000000034],[-93.84249899999998,48.62360400000006],[-93.851944,48.62693800000005],[-93.86555499999997,48.63027200000005],[-93.88055399999996,48.63027200000005],[-93.8852839999999,48.63027200000005],[-94.06388899999996,48.63804600000003],[-94.1119379999999,48.64110600000009],[-94.13417099999987,48.642769000000044],[-94.235275,48.65304600000002],[-94.250565,48.656097000000045],[-94.25279199999989,48.65776800000009],[-94.25418099999996,48.66054500000001],[-94.252228,48.67137900000006],[-94.252228,48.67999300000014],[-94.25666799999993,48.68776700000012],[-94.26306199999999,48.69415300000003],[-94.27111799999989,48.69915800000007],[-94.27861000000001,48.70249200000006],[-94.29110700000001,48.70609999999999],[-94.30583200000001,48.70832800000011],[-94.39056399999993,48.71110500000003],[-94.40611299999995,48.71110500000003],[-94.41416900000002,48.70999100000006],[-94.43331899999998,48.70193499999999],[-94.45361300000002,48.69582400000007],[-94.460556,48.69443500000011],[-94.47639500000002,48.69387800000004],[-94.50083899999998,48.696938000000046],[-94.52389499999992,48.70193499999999],[-94.60583500000001,48.72443399999992],[-94.63722199999995,48.739159000000086],[-94.64361600000001,48.74304999999998],[-94.68998699999992,48.77471200000008],[-94.699997,48.782767999999976],[-94.70666499999999,48.79055000000011],[-94.70944199999997,48.803047000000106],[-94.71112099999999,48.84638200000006],[-94.71000700000002,48.855270000000075],[-94.70907599999998,48.857948000000135],[-94.70500199999998,48.862770000000125],[-94.700287,48.868881000000044],[-94.69972200000001,48.87110100000007],[-94.700287,48.89527100000004],[-94.70167500000002,48.90971400000012],[-94.70417800000001,48.92443800000001],[-94.70750399999997,48.94193299999995],[-94.71665999999999,48.97054300000002],[-94.72055099999989,48.978874000000076],[-94.72721899999993,48.99221799999998],[-94.73277300000001,49.001663000000065],[-94.74527,49.02860300000009],[-94.76695299999994,49.075554000000125],[-94.79777499999994,49.155823],[-94.79888900000003,49.15915699999999],[-94.80471799999987,49.17971799999998],[-94.80665599999998,49.19360399999999],[-94.81527699999998,49.29332700000009],[-94.81555200000003,49.30609900000013],[-94.81834400000002,49.30998999999997],[-94.82194499999997,49.312767000000065],[-94.922775,49.35582700000003],[-94.93592799999993,49.36029799999994],[-94.94638099999997,49.36221299999994],[-94.95861799999994,49.36166400000002],[-94.96556099999998,49.360275],[-94.99861099999998,49.35749800000008],[-95.02583300000003,49.35749800000008],[-95.07806399999993,49.35916100000003],[-95.08566299999995,49.360023000000126],[-95.120834,49.364998000000014],[-95.14250199999992,49.371658000000025],[-95.15278599999994,49.376656000000025],[-95.15417499999995,49.36638600000009],[-95.15444899999989,49.33332800000011],[-95.15396099999998,49.17333200000007],[-95.15417499999995,48.99943500000012],[-95.26655599999998,48.999977],[-97.21994000000001,48.99971800000009],[-97.50279199999994,48.99943500000012],[-97.63583399999999,48.99943500000012],[-97.801941,49.000000000000114],[-97.96916199999993,49.00027499999999],[-98.26916499999993,49.00027499999999],[-98.50222799999989,48.99943500000012],[-98.868607,49.000000000000114],[-99.335556,48.99943500000012],[-99.835556,49.000000000000114],[-100.00222799999995,49.000000000000114],[-100.50195300000001,48.99971800000009],[-101.06916799999999,49.000000000000114],[-101.30222299999997,49.00027499999999],[-101.367233,48.99878700000011],[-101.46888699999994,48.99943500000012],[-102.16887699999995,49.000000000000114],[-102.33556399999998,48.99943500000012],[-102.53555299999994,49.00027499999999],[-102.76834099999996,48.99943500000012],[-103.035278,48.99943500000012],[-103.16832699999992,48.99943500000012],[-103.26889,49.000000000000114],[-103.43554699999993,49.00027499999999],[-103.535278,48.99943500000012],[-103.73528299999987,48.99943500000012],[-104.033096,49.00025199999999],[-104.13527699999986,48.99971800000009],[-104.33500699999996,48.99943500000012],[-104.83500700000002,48.99943500000012],[-105.00140399999998,48.99943500000012],[-105.26834100000002,49.000000000000114],[-105.70221699999996,48.99943500000012],[-105.93554699999999,48.99943500000012],[-106.03472899999991,48.99943500000012],[-106.13527699999997,48.99943500000012],[-106.26862299999993,48.99943500000012],[-106.46806300000003,48.99943500000012],[-106.73554999999993,48.99943500000012],[-107.33528100000001,49.000000000000114],[-107.43499800000001,49.000000000000114],[-107.63474300000001,48.99943500000012],[-107.73554999999993,48.99943500000012],[-107.80110199999996,48.99943500000012],[-108.16887700000001,48.99943500000012],[-108.33500699999996,48.99943500000012],[-108.53472899999997,48.99943500000012],[-108.6677699999999,48.99943500000012],[-108.83473200000003,48.99943500000012],[-109.33473200000003,48.99943500000012],[-109.63474299999996,48.99943500000012],[-109.801941,48.99943500000012],[-109.96777299999997,48.99971800000009],[-109.99965700000001,49.000603000000126],[-110.10138699999999,48.99943500000012],[-110.20111099999991,48.99943500000012],[-110.30166599999995,49.000000000000114],[-110.36776699999996,49.000000000000114],[-110.50110599999988,49.000000000000114],[-110.66777000000002,49.000000000000114],[-110.76862299999993,48.99943500000012],[-111.36833199999995,48.99943500000012],[-111.80110199999996,48.99943500000012],[-112.03472899999997,48.99943500000012],[-112.16832699999998,48.99943500000012],[-112.234734,49.000000000000114],[-112.33500699999996,49.000000000000114],[-112.43499799999995,49.000000000000114],[-112.53500399999996,49.000000000000114],[-112.60166900000002,49.000000000000114],[-112.93472300000002,49.000000000000114],[-113.03443900000002,49.000000000000114],[-113.23416099999997,48.99943500000012],[-113.36833200000001,48.99943500000012],[-113.567497,48.99943500000012],[-114.0344389999999,48.99943500000012],[-114.05985999999996,49.000603000000126],[-114.33500700000002,48.99943500000012],[-114.46749899999992,48.99943500000012],[-114.53472899999991,49.000000000000114],[-114.63390399999997,49.000000000000114],[-114.90110800000002,48.99943500000012],[-115.034157,48.99943500000012],[-115.16750299999995,48.99943500000012],[-115.36805700000002,49.000000000000114],[-115.46806300000003,49.000000000000114],[-115.56723,49.000000000000114],[-115.60138699999987,48.99943500000012],[-115.734444,48.99943500000012],[-116.04833999999994,48.99971800000009],[-117.00140399999998,48.99971800000009],[-117.03662099999997,49.00312800000012],[-117.06722999999994,48.99971800000009],[-117.20084399999996,48.99943500000012],[-117.234734,49.000000000000114],[-117.30055199999993,49.000000000000114],[-117.567497,49.000000000000114],[-117.83444199999991,49.000000000000114],[-117.86749299999997,48.99943500000012],[-118.00083899999998,48.99943500000012],[-118.13417099999998,48.99943500000012],[-118.36805699999996,48.99943500000012],[-118.76777600000003,48.99943500000012],[-118.96749899999992,48.99943500000012],[-119.13417099999987,48.99943500000012],[-119.26722699999999,48.99943500000012],[-119.46777299999985,48.99943500000012],[-119.86749299999991,48.99943500000012],[-119.93415800000002,48.99943500000012],[-120.034157,48.99943500000012],[-120.53472899999997,48.99943500000012],[-121.08497599999993,48.99971800000009],[-122.10056299999997,49.000000000000114],[-122.33389299999993,49.000000000000114],[-122.43360899999993,49.000000000000114],[-122.56667299999992,49.000000000000114],[-122.69999699999994,49.000000000000114],[-122.76030000000003,48.99943500000012],[-122.81360599999994,49.00527200000005],[-122.83112299999999,49.00860600000004],[-122.86250299999989,49.02221700000001],[-122.87777699999998,49.03221100000002],[-122.87970699999994,49.03443899999996],[-122.881104,49.038605000000075],[-122.87748699999986,49.049438000000066],[-122.87609900000001,49.05138399999993],[-122.8724979999999,49.05443600000007],[-122.86416600000001,49.06166100000013],[-122.85888699999992,49.067497],[-122.85804699999994,49.07276900000011],[-122.859444,49.077217000000076],[-122.86638599999998,49.08110799999997],[-122.87444299999999,49.08360299999998],[-122.89998600000001,49.087211999999965],[-122.91887700000001,49.087211999999965],[-122.94167299999992,49.08249699999993],[-123.02194199999997,49.05165899999997],[-123.03916900000002,49.04249600000014],[-123.04666099999997,49.03333299999997],[-123.048607,49.02721400000013],[-123.04833999999994,49.022491000000116],[-123.04778299999998,49.018326000000116],[-123.03916900000002,49.00527200000005],[-123.03431699999999,48.99943500000012],[-123.09374999999994,48.99943500000012],[-123.11332699999997,49.036658999999986],[-123.13890099999998,49.10721600000011],[-123.14835399999998,49.10833000000008],[-123.20500199999998,49.12360399999994],[-123.20973200000003,49.12721299999998],[-123.247772,49.26527399999998],[-123.24889399999995,49.27360500000003],[-123.24749800000001,49.27555100000012],[-123.09449799999993,49.283938999999975],[-123.00933800000001,49.28194400000007],[-122.943329,49.28416400000009],[-122.92360699999995,49.28833000000003],[-122.91251399999999,49.29332700000009],[-122.87917299999998,49.339157000000114],[-122.87499999999994,49.351387000000045],[-122.85388199999994,49.42999300000014],[-122.85278299999999,49.43610400000006],[-122.85333300000002,49.438880999999924],[-122.86054999999993,49.447487000000024],[-122.87082700000002,49.45721400000002],[-122.87638899999996,49.45555100000007],[-122.87832600000002,49.44943200000006],[-122.876938,49.42999300000014],[-122.87721299999993,49.41499299999998],[-122.881104,49.40277100000003],[-122.88583399999993,49.391936999999984],[-122.90139799999992,49.360550000000046],[-122.91555800000003,49.342216000000064],[-122.93138099999999,49.328049000000135],[-123.00538599999999,49.31954999999999],[-123.03671999999989,49.31321700000001],[-123.04521899999992,49.312550000000044],[-123.06339299999996,49.31321700000001],[-123.08023100000003,49.31554799999998],[-123.23638900000003,49.33888200000007],[-123.25418099999996,49.384720000000016],[-123.25666799999993,49.51277200000004],[-123.25334199999992,49.52304800000013],[-123.24722299999996,49.53499599999998],[-123.20162199999999,49.61571500000014],[-123.1558379999999,49.676102000000014],[-123.15416700000003,49.67943600000001],[-123.15222199999994,49.6855470000001],[-123.15361000000001,49.690269],[-123.15972899999997,49.69915800000007],[-123.16471899999993,49.70221700000002],[-123.16777000000002,49.70221700000002],[-123.17027300000001,49.701103000000046],[-123.24194299999999,49.660544999999956],[-123.24804699999993,49.64860500000009],[-123.24804699999993,49.639717000000076],[-123.26677699999999,49.61737800000003],[-123.26594499999999,49.61038200000013],[-123.265106,49.60788000000002],[-123.26494600000001,49.60371399999997],[-123.26576999999997,49.59838100000013],[-123.26812000000001,49.595551000000114],[-123.27095799999995,49.593215999999984],[-123.27977799999991,49.59005000000002],[-123.34333800000002,49.56137800000005],[-123.381104,49.556655999999975],[-123.39444699999996,49.55193300000013],[-123.43028299999997,49.53832999999997],[-123.48306300000002,49.51666300000011],[-123.49249299999997,49.50972000000013],[-123.495003,49.506943000000035],[-123.49610899999993,49.500275000000045],[-123.49416399999996,49.46859699999999],[-123.491669,49.46360800000002],[-123.48777799999993,49.46054799999996],[-123.47778299999993,49.45526899999999],[-123.47416699999997,49.450829],[-123.47332799999992,49.44110100000012],[-123.47609699999998,49.42193600000002],[-123.47666899999996,49.41915900000009],[-123.48194899999993,49.40998800000011],[-123.48665599999993,49.406097000000045],[-123.506958,49.38943500000005],[-123.512787,49.38638300000014],[-123.51944699999996,49.38388100000009],[-123.526947,49.38221000000004],[-123.53555299999994,49.3813780000001],[-123.54499800000002,49.383331000000055],[-123.60109699999987,49.397490999999945],[-123.60610999999994,49.399994000000106],[-123.67555199999998,49.425269999999955],[-123.77500900000001,49.458327999999995],[-123.85500299999995,49.468879999999956],[-123.86165599999993,49.46665999999999],[-123.88082899999995,49.466385000000116],[-123.88890100000003,49.46804800000007],[-123.89611799999994,49.47054300000008],[-123.95973200000003,49.510551000000135],[-123.96362299999993,49.51332900000011],[-123.98860200000001,49.54166399999997],[-124.06806899999992,49.63388100000003],[-124.07055700000001,49.63804600000003],[-124.07112099999995,49.64444000000009],[-124.0702819999999,49.64971900000006],[-124.05915800000002,49.671104000000014],[-124.03250100000002,49.713882000000126],[-124.02861000000001,49.71915400000006],[-124.021118,49.726379000000065],[-124.00527999999997,49.735825000000034],[-123.99833699999999,49.73888400000004],[-123.987213,49.743050000000096],[-123.97528099999994,49.74527000000012],[-123.95694700000001,49.746101000000124],[-123.94748700000002,49.74499500000013],[-123.94055199999997,49.742493000000024],[-123.93443299999996,49.73943299999996],[-123.92971799999992,49.735825000000034],[-123.876938,49.68332700000008],[-123.83306900000002,49.627486999999974],[-123.82917799999996,49.61693600000007],[-123.82444800000002,49.59582500000005],[-123.82277699999997,49.585548000000074],[-123.82333399999999,49.58138300000007],[-123.82224300000001,49.57305100000008],[-123.79972800000002,49.51944000000003],[-123.79444899999993,49.51027700000003],[-123.78971899999999,49.50666000000007],[-123.78250099999997,49.50416600000011],[-123.77639799999992,49.50388299999997],[-123.76972999999998,49.50471500000003],[-123.76640299999991,49.50666000000007],[-123.76390100000003,49.509438000000046],[-123.76139799999999,49.51332900000011],[-123.75389100000001,49.53777300000007],[-123.76862299999993,49.56193500000012],[-123.77139299999999,49.57222000000007],[-123.77223200000003,49.581940000000145],[-123.77027900000002,49.588043000000084],[-123.74017300000003,49.602599999999995],[-123.73733500000003,49.605270000000075],[-123.73517599999991,49.606937000000016],[-123.69599899999997,49.62360400000006],[-123.68683599999997,49.62560300000007],[-123.67283599999996,49.62527100000011],[-123.63890099999998,49.634995],[-123.61501299999992,49.639160000000004],[-123.56331599999999,49.66721300000012],[-123.54695100000004,49.67721599999999],[-123.53751399999993,49.68499000000003],[-123.53362300000003,49.68971299999998],[-123.53167699999995,49.695541000000105],[-123.53222699999998,49.700546000000145],[-123.53388999999993,49.70193499999999],[-123.54167199999989,49.701103000000046],[-123.54998799999998,49.693877999999984],[-123.56054699999993,49.686935000000005],[-123.57195299999995,49.68082400000009],[-123.58556399999992,49.676102000000014],[-123.67578100000003,49.65304600000002],[-123.69061299999993,49.65105100000011],[-123.73978399999999,49.64588200000003],[-123.75010700000001,49.64521400000001],[-123.79666099999997,49.638329],[-123.803879,49.64083100000005],[-123.8125,49.647491000000116],[-123.93499800000001,49.768326],[-123.93749999999989,49.77276599999999],[-123.93582200000003,49.778046000000074],[-123.93055699999996,49.78527100000014],[-123.91999800000002,49.79249599999997],[-123.88890100000003,49.819717000000026],[-123.88500999999997,49.82360800000009],[-123.88249199999996,49.82749200000012],[-123.87970699999994,49.83277100000009],[-123.87638900000002,49.84221599999995],[-123.87332200000003,49.864158999999916],[-123.87249799999995,49.87110100000001],[-123.872772,49.87721299999998],[-123.88500999999997,49.914993000000095],[-123.889183,49.92276799999996],[-123.89417300000002,49.92721599999993],[-123.90139799999992,49.92887900000005],[-123.91082799999998,49.93027500000011],[-123.920547,49.928604000000064],[-123.92999299999997,49.92971800000004],[-123.93720999999994,49.93221300000005],[-123.94193999999999,49.936104000000114],[-123.94860799999998,49.94387799999993],[-123.95472699999999,49.95304900000008],[-123.95889299999999,49.96221200000008],[-123.929779,49.985321000000056],[-123.929283,49.98949399999998],[-123.92544599999997,49.99415600000009],[-123.92044099999998,49.99732599999999],[-123.88160700000003,50.01499600000011],[-123.87343599999986,50.018326000000116],[-123.860771,50.02166000000011],[-123.85294299999998,50.02299500000004],[-123.84310199999999,50.02365900000012],[-123.80832699999996,50.04027600000012],[-123.79611199999994,50.04444100000012],[-123.75334199999998,50.07638500000013],[-123.74861099999998,50.080276000000026],[-123.74445300000002,50.08693699999992],[-123.74944299999999,50.09665700000005],[-123.82140399999997,50.15221399999996],[-123.83056599999998,50.15693699999997],[-123.846947,50.163321999999994],[-123.97778299999993,50.21388200000001],[-123.98500100000001,50.21610300000009],[-123.99054699999999,50.2158280000001],[-123.99109599999986,50.21166199999999],[-123.98832699999997,50.20749699999999],[-123.96056399999998,50.180550000000096],[-123.94695300000001,50.169441000000006],[-123.93720999999994,50.163321999999994],[-123.92388899999992,50.15860000000009],[-123.90583800000002,50.15638000000007],[-123.88806199999988,50.152489],[-123.882767,50.15082600000005],[-123.87165800000002,50.145546000000024],[-123.80915799999997,50.099998000000085],[-123.8125,50.09054600000013],[-123.81639099999995,50.08610500000003],[-123.85716200000002,50.06688300000013],[-123.86933099999993,50.0580480000001],[-123.87499999999994,50.054214000000115],[-123.87899799999997,50.052380000000085],[-123.916,50.03988300000009],[-123.95465899999988,50.029217000000074],[-123.99526999999989,50.011664999999994],[-123.99916099999996,50.00638600000002],[-124,50.0002750000001],[-123.99916099999996,49.990547000000106],[-123.99526999999989,49.96166200000005],[-123.99249299999997,49.942764000000125],[-123.99109599999986,49.93720999999999],[-123.98860200000001,49.931664000000126],[-123.97972099999998,49.91666399999997],[-123.96721600000001,49.90638000000013],[-123.95140100000003,49.89582800000011],[-123.91972399999992,49.877769],[-123.91471899999993,49.873878000000104],[-123.91111799999999,49.869713000000104],[-123.922234,49.8344350000001],[-123.92639199999996,49.825829],[-123.97277799999989,49.80471],[-123.97833299999996,49.803047000000106],[-123.98581699999994,49.802772999999945],[-123.99194299999994,49.80443600000007],[-124.00418100000002,49.810546999999985],[-124.01012400000002,49.834602000000075],[-124.008621,49.841938000000084],[-124.00728600000002,49.85676999999998],[-124.01806599999998,49.90915699999999],[-124.02166699999987,49.91415400000011],[-124.029449,49.920547000000056],[-124.037781,49.922493000000145],[-124.04222099999998,49.921379],[-124.04472399999997,49.91749600000003],[-124.068893,49.878876000000105],[-124.07195299999995,49.87332200000009],[-124.0702819999999,49.86915600000003],[-124.06261399999988,49.84632899999991],[-124.05877700000002,49.84199100000001],[-124.05860899999999,49.838325999999995],[-124.06028000000003,49.835158999999976],[-124.08444199999991,49.79916400000013],[-124.09028599999999,49.79583000000014],[-124.14555399999995,49.77971600000001],[-124.17694099999989,49.773604999999975],[-124.18582199999997,49.77276599999999],[-124.2702789999999,49.76805100000013],[-124.40416700000003,49.763329000000056],[-124.41361999999998,49.76361099999997],[-124.42916899999994,49.766388000000006],[-124.436394,49.76888300000007],[-124.51194800000002,49.79610400000007],[-124.52166699999992,49.80416100000008],[-124.52443699999998,49.80832700000013],[-124.52583300000003,49.81388099999998],[-124.52583300000003,49.831665000000044],[-124.52749599999987,49.83721200000002],[-124.53278399999999,49.844437000000084],[-124.57195299999995,49.874435000000005],[-124.59137699999997,49.883049000000085],[-124.63221699999997,49.89943699999992],[-124.702789,49.93498999999997],[-124.74194299999999,49.95832800000005],[-124.77306399999992,49.985825000000034],[-124.80332900000002,50.02027100000009],[-124.82556199999999,50.0513840000001],[-124.82972699999999,50.061935000000005],[-124.828056,50.06666600000011],[-124.82140400000003,50.06916000000007],[-124.81304899999992,50.067496999999946],[-124.80695300000002,50.06360600000005],[-124.76722699999988,50.03638500000005],[-124.70333900000003,49.995543999999995],[-124.66805999999991,50.07027400000004],[-124.61694299999999,50.17916100000008],[-124.60193599999997,50.23499300000003],[-124.60138699999993,50.2388840000001],[-124.604172,50.243881000000044],[-124.631104,50.27971600000012],[-124.63890100000003,50.28694200000007],[-124.665009,50.30387900000005],[-124.708618,50.318329000000006],[-124.71362299999987,50.32193799999999],[-124.71501199999994,50.32749200000001],[-124.65778399999994,50.38610800000009],[-124.6519469999999,50.38916000000006],[-124.62609899999995,50.398330999999985],[-124.60193599999997,50.40277100000003],[-124.58055100000001,50.399990000000116],[-124.57555400000001,50.39899400000013],[-124.57122800000002,50.397495000000106],[-124.54998799999993,50.39388300000002],[-124.53362300000003,50.395827999999995],[-124.51999699999999,50.399994000000106],[-124.43415800000002,50.43166400000001],[-124.42054699999994,50.43721000000005],[-124.39862099999999,50.450545999999974],[-124.38305700000001,50.462212000000136],[-124.36138900000003,50.47971300000012],[-124.35193600000002,50.48749500000008],[-124.348053,50.49221800000004],[-124.34528399999988,50.49748999999997],[-124.347778,50.50249500000001],[-124.35527000000002,50.50499700000012],[-124.36389200000002,50.50388299999992],[-124.378601,50.499161000000015],[-124.38445299999995,50.49610100000001],[-124.39388999999989,50.48888400000004],[-124.39778099999995,50.484161000000086],[-124.40055799999993,50.47887400000013],[-124.404449,50.4741590000001],[-124.409157,50.47026800000003],[-124.42749000000003,50.462212000000136],[-124.51834099999991,50.43221299999993],[-124.58383199999997,50.41405100000003],[-124.58833300000003,50.41338300000001],[-124.59999800000003,50.413048],[-124.71167000000003,50.37554900000009],[-124.73916599999995,50.35193600000014],[-124.80332900000002,50.317772000000105],[-124.81582600000002,50.31220999999999],[-124.83000199999992,50.30943300000007],[-124.85056299999991,50.30971499999998],[-124.93916299999995,50.325271999999984],[-125.06388900000002,50.317772000000105],[-125.07224299999996,50.31944299999998],[-125.07833900000003,50.32249500000012],[-125.08416699999998,50.32971999999995],[-125.08889799999997,50.34638200000012],[-125.08750900000001,50.357215999999994],[-125.05666399999996,50.47693600000002],[-125.05194099999989,50.48082000000005],[-125.04499799999996,50.48333000000008],[-125.02667199999996,50.48304700000011],[-125.01806599999998,50.484161000000086],[-124.97112299999998,50.49804700000004],[-124.96528599999999,50.50110600000005],[-124.880829,50.560546999999985],[-124.85973399999989,50.58582300000006],[-124.858047,50.59054600000002],[-124.85444599999994,50.691376000000105],[-124.86888099999999,50.76499899999999],[-124.87805200000003,50.81137799999999],[-124.86749299999997,50.81777199999999],[-124.78943599999991,50.88110400000005],[-124.78694199999995,50.884438000000046],[-124.78751399999993,50.88916000000012],[-124.79998799999998,50.91304800000006],[-124.80277999999998,50.9180530000001],[-124.80583200000001,50.920830000000024],[-124.81916799999993,50.92638400000004],[-124.84999099999993,50.93526500000013],[-124.854172,50.93554700000004],[-124.86138900000003,50.92887900000005],[-124.92443800000001,50.834717000000126],[-124.9449919999999,50.77526899999992],[-124.91221599999994,50.699431999999945],[-124.90139799999997,50.63027199999999],[-124.901947,50.62471000000005],[-124.90361000000001,50.619987000000094],[-124.91111799999999,50.61138200000005],[-124.92887899999994,50.59638200000006],[-125.026947,50.54083300000008],[-125.09944200000001,50.5],[-125.10417199999989,50.49694100000005],[-125.11277799999999,50.48749500000008],[-125.11694299999999,50.47804300000013],[-125.118607,50.471930999999984],[-125.11193800000001,50.45249200000006],[-125.11138899999997,50.44776900000011],[-125.11221299999994,50.44221500000009],[-125.11472299999997,50.436935000000005],[-125.11945300000002,50.432770000000005],[-125.12526700000001,50.42971800000009],[-125.17027299999995,50.4124910000001],[-125.17777999999998,50.41137700000013],[-125.1875,50.4124910000001],[-125.195831,50.41471100000007],[-125.2022169999999,50.417213000000004],[-125.20722999999998,50.42083000000014],[-125.24610899999993,50.462212000000136],[-125.33612099999993,50.47971300000012],[-125.40361000000001,50.47360200000003],[-125.42166099999992,50.46527100000014],[-125.44275699999997,50.45943500000004],[-125.46028099999995,50.457214000000135],[-125.48832700000003,50.45638300000013],[-125.54444899999993,50.49037900000013],[-125.54811099999995,50.492050000000006],[-125.54928599999994,50.494549000000006],[-125.54961399999996,50.497547000000054],[-125.54911799999996,50.501545000000135],[-125.53222700000003,50.62721300000004],[-125.51944700000001,50.647217000000126],[-125.51194800000002,50.65721100000013],[-125.50723299999999,50.66110200000003],[-125.50055699999996,50.66304800000012],[-125.48194899999999,50.664993000000095],[-125.46749899999998,50.668602000000135],[-125.45612299999999,50.67499500000008],[-125.45140100000003,50.67887900000011],[-125.42804699999999,50.705551000000014],[-125.42555199999998,50.71082300000012],[-125.43277,50.71388200000007],[-125.443604,50.714157000000114],[-125.45889299999993,50.713608000000136],[-125.46639999999996,50.713051000000064],[-125.47332799999998,50.70916],[-125.53778099999994,50.669991000000095],[-125.54723399999995,50.661933999999974],[-125.55832699999996,50.64804800000013],[-125.56388900000002,50.63721499999997],[-125.56806899999998,50.62721300000004],[-125.57167099999998,50.61138200000005],[-125.57224300000001,50.605270000000075],[-125.5849,50.57132300000006],[-125.58206899999999,50.56582300000008],[-125.58039099999996,50.56365600000004],[-125.5800549999999,50.559994000000074],[-125.58623499999999,50.53665900000004],[-125.610229,50.48932600000006],[-125.61238900000001,50.486492000000055],[-125.63722200000001,50.445540999999935],[-125.65167200000002,50.441375999999934],[-125.69249000000002,50.42999300000014],[-125.700287,50.42804700000005],[-125.70584099999996,50.427773000000116],[-125.71611000000001,50.43221299999993],[-125.84665699999994,50.502777000000094],[-125.86472300000003,50.49526999999995],[-125.93028299999992,50.47360200000003],[-125.95221700000002,50.46888000000013],[-125.968613,50.46888000000013],[-126.06331599999999,50.470825000000104],[-126.159157,50.484992999999974],[-126.193329,50.49027300000006],[-126.26777599999997,50.50499700000012],[-126.27500899999995,50.50750000000005],[-126.27916700000003,50.51166500000005],[-126.2808379999999,50.51583099999999],[-126.279449,50.520546000000024],[-126.276947,50.52471200000008],[-126.22670699999998,50.53628500000002],[-126.18665299999998,50.54840500000006],[-126.18559999999997,50.566322000000014],[-126.23805199999998,50.59137700000002],[-126.25167799999991,50.60971800000004],[-126.26418299999995,50.61554700000005],[-126.27500899999995,50.627486999999974],[-126.27471899999995,50.63166000000007],[-126.266953,50.63472000000013],[-126.02006499999999,50.66188000000011],[-126.014725,50.66204800000014],[-125.90856200000002,50.66404699999998],[-125.73832699999997,50.682213000000104],[-125.69387799999993,50.70471200000003],[-125.62249799999995,50.750000000000114],[-125.61776700000001,50.754166000000055],[-125.54305999999991,50.8638840000001],[-125.53778099999994,50.87193300000007],[-125.51000999999997,50.92166100000003],[-125.50723299999999,50.92694100000011],[-125.50556899999998,50.93332700000002],[-125.50666799999993,50.94554100000005],[-125.50834699999996,50.95110299999999],[-125.55166600000001,51.0422210000001],[-125.56555200000003,51.05638099999999],[-125.58167999999995,51.07222000000013],[-125.59306299999997,51.07888000000014],[-125.610817,51.08776900000004],[-125.63390400000003,51.09693900000008],[-125.63722200000001,51.096382000000006],[-125.63890100000003,51.09027100000009],[-125.639183,51.07721700000002],[-125.63806199999999,51.06610100000006],[-125.583328,50.97470900000002],[-125.61028299999987,50.89888000000002],[-125.69110099999995,50.771378000000084],[-125.73110999999989,50.735550000000046],[-125.81527699999987,50.70721400000008],[-125.96383700000001,50.688660000000084],[-126.12516799999997,50.678989000000115],[-126.13100400000002,50.6786580000001],[-126.133667,50.678825000000074],[-126.13799999999998,50.681827999999996],[-126.13917500000002,50.68349500000011],[-126.22222899999991,50.69110100000006],[-126.21362299999993,50.70388000000014],[-126.20889299999999,50.70777099999998],[-126.20333899999997,50.711104999999975],[-126.11165599999993,50.75388300000009],[-126.19888299999997,50.85582700000009],[-126.26944700000001,50.85804700000011],[-126.37609899999995,50.85527000000002],[-126.39750699999996,50.84860200000003],[-126.40306099999998,50.84526800000003],[-126.42166099999997,50.8294370000001],[-126.42748999999992,50.8261030000001],[-126.43415799999997,50.82360800000009],[-126.44304699999998,50.82166300000006],[-126.49333199999995,50.81638300000003],[-126.55277999999998,50.834717000000126],[-126.55695300000002,50.838882000000126],[-126.55972299999996,50.84388000000013],[-126.557503,50.87665600000008],[-126.55359599999991,50.881377999999984],[-126.53611799999999,50.898048000000074],[-126.531387,50.9019320000001],[-126.501106,50.91609999999997],[-126.49445300000002,50.9180530000001],[-126.48332199999999,50.91915899999998],[-126.47471599999994,50.91749600000003],[-126.468613,50.91443600000014],[-126.464447,50.91027100000014],[-126.45805399999995,50.907211000000075],[-126.36833200000001,50.9019320000001],[-126.358337,50.90138200000007],[-126.24638400000003,50.898604999999975],[-126.22582999999997,50.898604999999975],[-126.21028100000001,50.90277100000009],[-126.20445299999994,50.90554800000001],[-126.18388399999992,50.91860200000008],[-126.17555199999993,50.92582700000014],[-126.17027299999995,50.936653000000035],[-126.17166099999997,50.94638100000009],[-126.17471299999988,50.95054600000009],[-126.17777999999998,50.951385000000016],[-126.181107,50.950829000000056],[-126.18888899999996,50.948875000000044],[-126.20028699999989,50.94249000000002],[-126.20500199999992,50.93832400000008],[-126.21556099999998,50.931107],[-126.228882,50.92610200000013],[-126.24553700000001,50.923325000000034],[-126.30860899999999,50.92527000000001],[-126.412216,50.936104000000114],[-126.42639200000002,50.938599000000124],[-126.5625,50.907767999999976],[-126.56833599999993,50.903877000000136],[-126.58084099999996,50.898604999999975],[-126.66139199999998,50.86804999999998],[-126.67777999999998,50.86638599999998],[-126.72165699999994,50.87609900000001],[-126.80638099999999,50.90915699999999],[-126.81916799999999,50.915824999999984],[-126.90261799999996,50.905098000000066],[-126.90595199999996,50.90410200000008],[-126.91711399999997,50.903439000000105],[-127.01471700000002,50.903877000000136],[-127.04804999999993,50.91027100000014],[-127.08556399999998,50.921378999999945],[-127.112213,50.931107],[-127.1641689999999,50.932495000000074],[-127.17639200000002,50.92916100000008],[-127.17999299999991,50.92582700000014],[-127.17804699999994,50.92027300000012],[-127.17166099999992,50.91749600000003],[-127.06276699999995,50.88526900000005],[-127.01883700000002,50.868267],[-127.00765999999993,50.867939000000035],[-126.976158,50.870438000000036],[-126.97166400000003,50.86993800000005],[-126.9691699999999,50.86910599999993],[-126.96599600000002,50.86693600000001],[-126.96681999999998,50.86410100000006],[-127.01471700000002,50.81944300000009],[-127.02250700000002,50.817497],[-127.03333299999997,50.81777199999999],[-127.047234,50.82166300000006],[-127.05776999999995,50.828048999999965],[-127.06166100000002,50.832213999999965],[-127.06696299999993,50.835823000000005],[-127.07333399999993,50.838882000000126],[-127.13276699999994,50.862213],[-127.243607,50.89666],[-127.33444199999997,50.90693699999997],[-127.39862099999993,50.92638400000004],[-127.43055699999991,50.9405440000001],[-127.535278,51.000549000000035],[-127.53832999999997,51.005554000000075],[-127.53806299999997,51.008331],[-127.502792,51.097488],[-127.495003,51.0991590000001],[-127.47749299999992,51.097488],[-127.43582199999997,51.08277100000004],[-127.40888999999987,51.071938000000046],[-127.39306599999992,51.06471299999998],[-127.38137799999998,51.05971499999998],[-127.3683319999999,51.055267000000015],[-127.354446,51.051659000000086],[-127.33056599999998,51.04833199999996],[-127.24249299999997,51.04138200000011],[-127.23610699999995,51.041107000000125],[-127.21861299999995,51.040832999999964],[-127.09612299999998,51.04388399999999],[-126.99873400000001,51.05888399999998],[-126.97956099999999,51.06288100000012],[-126.94840199999999,51.06705099999999],[-126.87339800000001,51.07288399999999],[-126.86672999999996,51.07271600000013],[-126.82656899999995,51.06705099999999],[-126.81689499999987,51.06471600000003],[-126.69167299999998,51.110550000000046],[-126.68694299999999,51.1147160000001],[-126.65278599999999,51.149994000000106],[-126.65139799999997,51.15332000000001],[-126.65110799999997,51.15749400000004],[-126.654449,51.185822000000144],[-126.65527299999997,51.18776699999995],[-126.65834000000001,51.19276400000007],[-126.66251399999993,51.19499200000001],[-126.67582700000003,51.19387800000004],[-126.67916899999994,51.19276400000007],[-126.68167099999994,51.18859900000007],[-126.68250299999994,51.176383999999985],[-126.68167099999994,51.172768000000076],[-126.68331899999998,51.165268000000026],[-126.68831599999999,51.157211000000075],[-126.69666299999994,51.14777400000014],[-126.71749899999998,51.132767000000115],[-126.84055299999989,51.094936000000075],[-126.84654999999992,51.093105000000094],[-126.85589599999997,51.09210200000007],[-126.927887,51.08493800000008],[-127.14111299999996,51.060272000000055],[-127.19249000000002,51.057213000000104],[-127.20667300000002,51.05638099999999],[-127.23832700000003,51.05693800000006],[-127.32668299999995,51.05971499999998],[-127.3408429999999,51.06082200000009],[-127.35916099999992,51.063323999999966],[-127.38861099999991,51.06805400000002],[-127.49273700000003,51.11488300000008],[-127.50985000000003,51.117359000000135],[-127.53376000000003,51.10808200000014],[-127.556107,51.09999800000003],[-127.63194299999998,51.09193400000004],[-127.64943699999998,51.092216000000064],[-127.66665599999988,51.09526800000003],[-127.67944299999988,51.10110500000013],[-127.78999299999992,51.165543000000014],[-127.79611199999994,51.197212000000036],[-127.795837,51.202217000000076],[-127.787216,51.226097000000095],[-127.78472899999991,51.23137699999995],[-127.76194800000002,51.249435000000005],[-127.59973100000002,51.28943599999997],[-127.59306300000003,51.290833000000134],[-127.56555199999997,51.29305299999993],[-127.53999299999998,51.29444100000006],[-127.45140099999998,51.29193900000013],[-127.4036099999999,51.2824940000001],[-127.37554899999998,51.27443700000009],[-127.36472299999997,51.2741620000001],[-127.23110999999994,51.28611000000012],[-127.22222899999991,51.287216],[-127.21444699999995,51.290549999999996],[-127.203888,51.29860700000012],[-127.14334100000002,51.318329000000006],[-127.1330569999999,51.32555400000007],[-127.12693799999994,51.334991],[-127.11776700000001,51.35749800000008],[-127.11110699999989,51.37721300000004],[-127.10973399999995,51.383331],[-127.11028299999992,51.389717000000076],[-127.11582899999996,51.391662999999994],[-127.12249800000001,51.389160000000004],[-127.13054699999998,51.38193499999994],[-127.13417099999998,51.37721300000004],[-127.14417300000002,51.358047],[-127.18250299999994,51.326942000000145],[-127.18804899999998,51.32360799999998],[-127.20834400000001,51.315826000000015],[-127.24749800000001,51.30638099999993],[-127.28056300000003,51.30110200000013],[-127.29055800000003,51.30054500000006],[-127.36749299999991,51.298881999999935],[-127.39584400000001,51.30221599999993],[-127.45221699999996,51.315826000000015],[-127.462784,51.34166000000005],[-127.55444299999999,51.332497000000046],[-127.57000699999998,51.32860599999998],[-127.75499699999989,51.31944299999998],[-127.76390100000003,51.31944299999998],[-127.77250699999996,51.3211060000001],[-127.77887699999997,51.32471500000008],[-127.78415699999994,51.33305400000012],[-127.78778099999994,51.34887700000013],[-127.78307299999994,51.356941000000006],[-127.778343,51.36110700000006],[-127.74109599999997,51.38027200000005],[-127.72749299999998,51.38555100000002],[-127.69332899999995,51.39083100000005],[-127.68443300000001,51.39083100000005],[-127.65055799999999,51.40804300000008],[-127.55166600000001,51.468323000000055],[-127.51583900000003,51.51915700000001],[-127.51306199999993,51.52999100000005],[-127.512787,51.53555299999999],[-127.515289,51.5472180000001],[-127.521118,51.56388099999998],[-127.51640299999997,51.587769000000094],[-127.51500699999985,51.59388000000001],[-127.50890399999997,51.60471299999995],[-127.50055700000001,51.61360900000011],[-127.48805199999998,51.619438000000116],[-127.44444299999998,51.62999000000008],[-127.37609900000001,51.6449970000001],[-127.32584400000002,51.651382000000126],[-127.23332199999999,51.66249099999999],[-127.09584000000001,51.668052999999986],[-126.95344499999999,51.658325000000104],[-126.94693799999993,51.65765799999997],[-126.93778199999997,51.65532700000006],[-126.88377400000002,51.64949400000006],[-126.708054,51.64193700000004],[-126.66332999999986,51.64888000000002],[-126.65527299999997,51.651382000000126],[-126.620003,51.679993000000024],[-126.60694899999993,51.706940000000145],[-126.60527000000002,51.713051000000064],[-126.60582699999992,51.71943699999997],[-126.60777300000001,51.72499099999993],[-126.63555899999989,51.76971400000002],[-126.63944999999995,51.77388000000013],[-126.660278,51.7922210000001],[-126.66528299999999,51.772491000000116],[-126.66665599999999,51.766388000000006],[-126.66251399999993,51.7472150000001],[-126.65387699999991,51.73249100000004],[-126.64362299999999,51.719154],[-126.63999899999999,51.709991],[-126.641388,51.7052690000001],[-126.64388999999994,51.70110299999999],[-126.64750700000002,51.697768999999994],[-126.69304699999998,51.66471100000001],[-126.703056,51.66443600000002],[-126.91521499999999,51.68243800000005],[-126.96421799999996,51.6866040000001],[-126.97788199999997,51.69060500000006],[-127.05387899999988,51.697768999999994],[-127.07501199999996,51.697768999999994],[-127.14055599999995,51.694435000000055],[-127.27416999999997,51.68332700000002],[-127.3999859999999,51.66971600000005],[-127.41583300000002,51.665824999999984],[-127.42582699999997,51.66666399999997],[-127.43222000000003,51.66832700000009],[-127.43554699999987,51.67110399999996],[-127.43971299999993,51.674713],[-127.44167299999992,51.68027500000011],[-127.42748999999998,51.73193400000014],[-127.364441,51.768326000000116],[-127.36193800000001,51.77166000000011],[-127.359444,51.77721400000007],[-127.33917200000002,51.83915699999994],[-127.33721899999989,51.851387000000045],[-127.33999599999999,51.86110699999995],[-127.34555099999994,51.864159000000086],[-127.35109699999992,51.863609000000054],[-127.35694899999999,51.86027500000006],[-127.44833399999987,51.77721400000007],[-127.5719529999999,51.706940000000145],[-127.58556399999986,51.67777300000006],[-127.54638699999992,51.62748699999992],[-127.55860899999999,51.543884000000105],[-127.56111099999998,51.53860500000013],[-127.57417299999997,51.51888300000007],[-127.58139,51.50943799999999],[-127.63583399999999,51.46054800000013],[-127.640289,51.458602999999925],[-127.659157,51.4574970000001],[-127.70639,51.45638300000013],[-127.71639999999996,51.457214000000135],[-127.72389199999992,51.45943500000004],[-127.73029300000002,51.46305100000012],[-127.75473,51.479988000000105],[-127.75917099999992,51.48416100000003],[-127.76083399999993,51.48971599999993],[-127.75974300000001,51.49443800000006],[-127.74416400000001,51.498329000000126],[-127.712784,51.50443999999999],[-127.787216,51.56027199999994],[-127.87416099999996,51.66332200000005],[-127.87805200000003,51.67388199999999],[-127.88999899999999,51.798332000000016],[-127.88944999999995,51.807770000000005],[-127.886124,51.85221899999999],[-127.88474299999996,51.858604000000014],[-127.86971999999997,51.89527099999998],[-127.86609599999997,51.89999399999999],[-127.86165599999987,51.90416000000005],[-127.83306899999997,51.91999100000004],[-127.82055699999995,51.92665900000003],[-127.79638699999998,51.938599000000124],[-127.78971899999999,51.941101],[-127.76611300000002,51.94693799999993],[-127.73805199999993,51.949715000000026],[-127.66443600000002,51.95388000000003],[-127.65527299999997,52.04027600000006],[-127.65387699999991,52.04638699999998],[-127.65139799999997,52.051659000000086],[-127.64527900000002,52.06193499999995],[-127.62943999999999,52.08832600000005],[-127.62581599999999,52.09304799999995],[-127.61749299999997,52.10193600000014],[-127.58029199999993,52.129158000000075],[-127.52555799999993,52.14721700000001],[-127.49944299999993,52.15165700000006],[-127.48055999999997,52.15109999999993],[-127.47721899999999,52.15054300000003],[-127.46528599999988,52.14388300000002],[-127.46140300000002,52.13304900000014],[-127.46250899999995,52.112495000000024],[-127.46611000000001,52.10777300000012],[-127.47556299999997,52.099716000000114],[-127.48249799999996,52.09693900000002],[-127.49833699999999,52.093323],[-127.50834700000001,52.093323],[-127.51834100000002,52.09443699999997],[-127.52722199999994,52.09582500000005],[-127.53500400000001,52.098877000000016],[-127.55277999999998,52.10110500000013],[-127.56276700000001,52.10082999999992],[-127.57167099999998,52.098877000000016],[-127.58444199999991,52.09360500000008],[-127.58889799999992,52.089714000000015],[-127.61416600000001,52.035828000000095],[-127.61332699999997,52.0324940000001],[-127.59416199999998,52.03555300000011],[-127.58612099999993,52.03804800000012],[-127.420837,52.12027000000012],[-127.43360899999999,52.131659999999954],[-127.45056199999999,52.16915900000009],[-127.45249899999988,52.17388200000005],[-127.45305599999995,52.17999300000014],[-127.44972199999995,52.18277000000006],[-127.37609900000001,52.21693400000004],[-127.35417199999995,52.22470900000013],[-127.33138999999994,52.23027000000002],[-127.30027799999993,52.22832500000004],[-127.29110700000001,52.229431000000034],[-127.28443900000002,52.231934000000024],[-127.24526999999995,52.248878000000104],[-127.23944099999994,52.25222000000002],[-127.19304699999998,52.29083300000008],[-127.18582200000003,52.30027000000001],[-127.17749000000003,52.3097150000001],[-127.17166099999992,52.31249200000002],[-127.16361999999987,52.314156000000025],[-127.04276999999996,52.309158000000025],[-127.01251200000002,52.3063810000001],[-127.00499699999995,52.30360400000001],[-126.99861099999993,52.29860700000012],[-126.964447,52.27166],[-126.94526699999994,52.25610400000005],[-126.93804899999986,52.24694100000005],[-126.93611099999998,52.24137900000011],[-126.93554699999999,52.23526800000002],[-126.82749899999999,52.1280440000001],[-126.75195300000001,52.07860599999998],[-126.71193700000003,52.04444100000006],[-126.69415300000003,52.028877000000136],[-126.691101,52.02388000000008],[-126.68388399999998,51.99971799999997],[-126.67804699999994,51.99054700000005],[-126.67388899999997,51.98638200000005],[-126.66944899999999,51.98360400000007],[-126.66832699999998,51.98554999999993],[-126.66776999999996,51.99110400000012],[-126.66583300000002,52.03138000000013],[-126.66665599999999,52.036384999999996],[-126.66972399999997,52.04193900000001],[-126.73805199999987,52.113052000000096],[-126.76363399999991,52.13249200000007],[-126.81722999999988,52.166100000000085],[-126.83112299999999,52.17193599999996],[-126.85555999999997,52.17804700000005],[-126.86305199999993,52.18110700000011],[-126.88027999999986,52.190544000000045],[-126.90055799999999,52.20526899999999],[-126.90666199999993,52.21527100000014],[-126.94082600000002,52.30387900000005],[-126.94027699999998,52.31082200000003],[-126.93611099999998,52.32249500000006],[-126.932503,52.32721700000013],[-126.920837,52.33360300000004],[-126.87361099999998,52.35083000000009],[-126.82084700000001,52.36388399999993],[-126.81416299999995,52.365273000000116],[-126.78888699999999,52.369987000000094],[-126.77667199999996,52.37027000000006],[-126.76194800000002,52.370543999999995],[-126.73638900000003,52.366386000000034],[-126.73166700000002,52.36776700000007],[-126.73249800000002,52.37387799999999],[-126.73665599999998,52.378044000000045],[-126.75167799999991,52.388329],[-126.76363399999991,52.39332600000006],[-126.79277000000002,52.39554600000008],[-126.91027799999995,52.37387799999999],[-126.92610200000001,52.37082700000013],[-126.94110099999995,52.366386000000034],[-126.948036,52.36388399999993],[-126.95973199999997,52.357215999999994],[-126.96972699999998,52.34165999999999],[-126.97444200000001,52.33776899999992],[-126.98137699999995,52.33526599999999],[-127.00279199999994,52.334991000000116],[-127.08249699999993,52.334991000000116],[-127.14111299999996,52.34804500000001],[-127.15778399999999,52.35249299999998],[-127.186394,52.38082099999997],[-127.22805800000003,52.453049000000135],[-127.23610699999995,52.50555400000013],[-127.23665599999998,52.51166500000005],[-127.23416099999997,52.51721199999997],[-127.19695299999995,52.54999500000014],[-127.186394,52.55777000000006],[-127.08112299999993,52.61305199999998],[-127.07417299999997,52.61638599999998],[-127.05915800000002,52.62082700000008],[-127.00446299999999,52.626937999999996],[-126.99638399999998,52.62860100000006],[-126.989441,52.631935000000055],[-126.97972099999998,52.639434999999935],[-126.97609699999998,52.64388300000013],[-126.924713,52.71471400000013],[-126.92223399999995,52.71888000000001],[-126.92166099999997,52.72582200000011],[-126.92250100000001,52.73110200000002],[-126.966949,52.828606000000036],[-126.97112300000003,52.83277100000004],[-126.975281,52.83554800000013],[-126.98332199999987,52.83776900000004],[-127.01777599999991,52.84554300000002],[-127.02139299999993,52.82777400000009],[-127.01834100000002,52.823608000000036],[-127.00778199999996,52.80888399999998],[-126.98082699999992,52.72443400000003],[-126.98111,52.71749100000005],[-126.98528299999992,52.707497000000046],[-127.04250300000001,52.64777399999997],[-127.04737899999992,52.643463],[-127.05561799999998,52.641815000000065],[-127.13445300000001,52.60943600000013],[-127.24054699999988,52.55777000000006],[-127.25723299999999,52.54583000000014],[-127.28083799999996,52.509162999999944],[-127.28222700000003,52.50305200000008],[-127.28028899999993,52.497489999999914],[-127.27610800000002,52.49332400000003],[-127.26528899999988,52.485550000000046],[-127.25805699999995,52.47721100000001],[-127.25834699999996,52.47304500000007],[-127.26194800000002,52.46749100000011],[-127.26666299999988,52.464157000000114],[-127.33345800000001,52.43389500000001],[-127.40082599999994,52.42443100000014],[-127.46541599999995,52.395477000000085],[-127.48935699999987,52.362072000000126],[-127.61165599999998,52.29471600000005],[-127.61833200000001,52.29193900000013],[-127.72138999999993,52.27471200000008],[-127.73055999999997,52.273604999999975],[-127.739441,52.27388000000002],[-127.74610899999999,52.276657000000114],[-127.75029,52.28166199999998],[-127.80471799999998,52.248878000000104],[-127.84277299999997,52.2241590000001],[-127.84528399999999,52.21943700000003],[-127.85249299999987,52.20999100000006],[-127.85833699999995,52.206657000000064],[-127.86389200000002,52.20749699999993],[-127.86916399999996,52.21110500000003],[-127.87110899999999,52.216385000000116],[-127.87304699999999,52.22332],[-127.90527299999991,52.27887700000008],[-127.86776700000001,52.494995000000074],[-127.86776700000001,52.50054900000009],[-127.86971999999997,52.50610399999999],[-127.87499999999994,52.51027699999992],[-127.88166799999999,52.51249700000011],[-127.89195299999994,52.513329000000056],[-127.89998599999996,52.50999500000006],[-127.92488899999995,52.443886000000134],[-127.92971799999992,52.427547000000004],[-127.92854299999999,52.42421300000001],[-127.92588,52.42121500000013],[-127.916718,52.4148790000001],[-127.90905800000002,52.40738299999998],[-127.90589099999988,52.401549999999986],[-127.90538800000002,52.39788400000009],[-127.95694700000001,52.32444000000004],[-127.96389799999997,52.321663000000115],[-127.972778,52.323326000000066],[-127.995003,52.33055100000013],[-128.0080569999999,52.336937000000034],[-128.01251200000002,52.34110299999992],[-128.05721999999997,52.394713999999965],[-128.05917399999998,52.400269000000094],[-128.06832899999995,52.44776900000005],[-128.06695599999995,52.45388000000014],[-128.05944799999992,52.470267999999976],[-128.05111699999992,52.478874000000076],[-128.0419619999999,52.48777000000001],[-128.03250100000002,52.49527000000012],[-128.00946,52.50860600000004],[-127.97721899999999,52.51971400000008],[-127.96916199999993,52.52166000000011],[-127.96140300000002,52.519440000000145],[-127.95612299999993,52.515831000000105],[-127.89611799999994,52.542220999999984],[-127.891388,52.54638700000004],[-127.88778699999995,52.55110200000007],[-127.8799899999999,52.574164999999994],[-127.87970699999994,52.579720000000066],[-127.88751200000002,52.57777399999998],[-128.0291749999999,52.54166400000008],[-128.04083300000002,52.53582799999998],[-128.0997309999999,52.50305200000008],[-128.1049349999999,52.49238200000008],[-128.118317,52.465546000000074],[-128.14834599999995,52.42221799999999],[-128.2250059999999,52.330826000000116],[-128.23330699999997,52.32193799999999],[-128.27862499999998,52.280823],[-128.28332499999993,52.276657000000114],[-128.28891,52.27332300000012],[-128.295837,52.27082800000011],[-128.30499299999997,52.269439999999975],[-128.39388999999989,52.291382000000056],[-128.32971199999992,52.38027199999999],[-128.29751599999992,52.40054300000003],[-128.29083300000002,52.401657],[-128.28085299999992,52.400825999999995],[-128.27416999999997,52.39804799999996],[-128.267517,52.396660000000054],[-128.260559,52.39916199999993],[-128.255859,52.403320000000065],[-128.22442599999994,52.45971700000007],[-128.2219239999999,52.46527100000009],[-128.22055099999994,52.47137500000014],[-128.22109999999992,52.48443600000007],[-128.228607,52.52304800000002],[-128.23055999999997,52.5283280000001],[-128.238312,52.536658999999986],[-128.24221799999998,52.547775000000115],[-128.241943,52.55471],[-128.239166,52.5669400000001],[-128.18527199999988,52.67110400000013],[-128.14584399999995,52.71998600000006],[-128.120544,52.757217000000026],[-128.13165300000003,52.87638100000004],[-128.17001299999998,52.85665899999998],[-128.17501800000002,52.85193599999997],[-128.22305299999994,52.81249200000008],[-128.22888199999994,52.80860100000001],[-128.23525999999993,52.80582400000009],[-128.249725,52.8013840000001],[-128.2744449999999,52.79943800000001],[-128.300293,52.800270000000125],[-128.33999600000004,52.80554999999998],[-128.42611699999998,52.81749700000012],[-128.43612699999994,52.818886000000134],[-128.441101,52.82276900000005],[-128.48776199999986,52.873604000000114],[-128.49359100000004,52.882767000000115],[-128.495544,52.88749699999994],[-128.498871,52.903602999999976],[-128.50640899999996,52.96305099999995],[-128.51556399999998,53.01998899999995],[-128.539734,53.13193499999994],[-128.62554899999992,53.20221700000002],[-128.66140699999994,53.20221700000002],[-128.66082799999992,53.196938000000046],[-128.66305499999999,53.19082600000007],[-128.66723599999995,53.18749200000008],[-128.676666,53.18776700000012],[-128.68527199999994,53.189430000000016],[-128.70111099999997,53.195541000000105],[-128.78832999999997,53.23971599999999],[-128.794739,53.24332400000009],[-128.84887699999996,53.27582600000005],[-128.85888699999998,53.28360700000013],[-128.866394,53.292220999999984],[-128.86944600000004,53.2972180000001],[-128.87832599999996,53.31638300000003],[-128.88558999999998,53.37437800000009],[-128.88798499999996,53.42496500000004],[-128.92186000000004,53.45360199999999],[-128.95916699999998,53.50277700000004],[-128.97332799999998,53.54749300000003],[-128.97277799999995,53.55304700000005],[-128.966095,53.55609900000013],[-128.80499299999997,53.56999200000001],[-128.79501300000004,53.56860400000011],[-128.78832999999997,53.56499500000007],[-128.783325,53.561104],[-128.77972399999987,53.556938000000116],[-128.69250499999998,53.48526800000013],[-128.55862399999995,53.41387900000012],[-128.523621,53.396660000000054],[-128.446014,53.413158000000124],[-128.44517499999995,53.41599300000007],[-128.4295039999999,53.429824999999994],[-128.1897279999999,53.459991],[-128.15945399999993,53.455826],[-128.14862099999993,53.45360599999998],[-128.13192699999996,53.448875000000044],[-128.105255,53.44054399999999],[-128.09387199999998,53.43305200000003],[-128.07081600000004,53.39411499999994],[-128.03488200000004,53.36928900000004],[-128.00598099999996,53.34705699999995],[-127.95195000000001,53.32610299999993],[-127.94999699999988,53.32138100000003],[-127.951683,53.309990000000084],[-127.95388799999995,53.30416100000008],[-127.95694700000001,53.28138000000007],[-127.95527600000003,53.26583099999999],[-127.95111099999997,53.25638600000008],[-127.94611399999985,53.25222000000002],[-127.87526700000001,53.22443399999992],[-127.87027,53.22276300000004],[-127.868607,53.233879],[-127.86776700000001,53.23971599999999],[-127.87138399999998,53.244155999999975],[-127.92259999999993,53.273685],[-127.93297599999994,53.29332399999993],[-127.92408,53.31815300000011],[-127.92593399999993,53.33075000000002],[-127.98805199999998,53.35388199999994],[-128.0716549999999,53.43138099999999],[-128.09387199999998,53.451935000000105],[-128.12692300000003,53.48110200000002],[-128.16528299999993,53.483879000000115],[-128.18331899999993,53.48416100000003],[-128.3013919999999,53.47832499999993],[-128.45187399999992,53.50332300000008],[-128.4534,53.49965699999996],[-128.45640600000002,53.496822000000066],[-128.48156700000004,53.487987999999916],[-128.49021900000002,53.485325000000046],[-128.53340100000003,53.47832499999993],[-128.54457100000002,53.47899200000006],[-128.54937699999994,53.48082399999993],[-128.81304899999992,53.619155999999975],[-128.81664999999998,53.62332200000009],[-128.81805399999996,53.64471400000008],[-128.81750499999993,53.65026899999998],[-128.81390399999998,53.65693699999997],[-128.808899,53.66165900000004],[-128.78417999999988,53.675552000000096],[-128.77279699999997,53.73333000000014],[-128.79388399999988,53.76499899999993],[-128.793335,53.77054600000008],[-128.79110699999995,53.776657],[-128.7705689999999,53.79583000000008],[-128.67767300000003,53.83977500000009],[-128.67384300000003,53.84160600000007],[-128.66551200000004,53.84460800000011],[-128.66067499999997,53.845439999999996],[-128.65583799999996,53.84360500000008],[-128.64482099999987,53.83710500000012],[-128.64166299999994,53.83477000000005],[-128.60360699999995,53.842216000000064],[-128.59387199999998,53.839714000000015],[-128.47720299999997,53.82860599999998],[-128.47137499999997,53.832497000000046],[-128.47555499999999,53.842216000000064],[-128.482758,53.85082999999992],[-128.48944099999994,53.85416399999991],[-128.498871,53.856941000000006],[-128.5100099999999,53.85916100000003],[-128.53030399999994,53.86166400000002],[-128.53832999999992,53.860275],[-128.54501299999998,53.85721600000005],[-128.55306999999988,53.85610200000008],[-128.61726399999992,53.868546000000094],[-128.65962199999996,53.8828850000001],[-128.662598,53.885216000000014],[-128.66461200000003,53.88821800000011],[-128.67903099999995,53.90752400000002],[-128.67869599999995,53.91085799999996],[-128.66686999999996,53.92285900000013],[-128.66072099999997,53.928524000000095],[-128.6480709999999,53.94943200000006],[-128.63946499999997,53.96054799999996],[-128.59832799999998,54.02693899999997],[-128.60055499999993,54.03166199999998],[-128.60916099999997,54.03138000000007],[-128.61663799999997,54.029160000000104],[-128.67861899999997,54.00360900000004],[-128.68527199999994,54.000832000000116],[-128.68890399999998,53.99415600000003],[-128.6955569999999,53.976097000000095],[-128.7228389999999,53.94404600000007],[-128.724991,53.94021600000008],[-128.727661,53.93671000000006],[-128.73100299999993,53.93354799999992],[-128.79943799999995,53.87499200000002],[-128.915283,53.787216],[-128.93194600000004,53.774711999999965],[-128.98361199999994,53.76221499999997],[-129.10497999999995,53.72026800000009],[-129.1180419999999,53.71415700000006],[-129.12359599999996,53.710274000000084],[-129.21749899999992,53.64027400000009],[-129.232483,53.62582400000014],[-129.2380369999999,53.61332700000014],[-129.239441,53.60193600000002],[-129.236938,53.53721600000006],[-129.231384,53.50083200000006],[-129.23443599999996,53.46193700000009],[-129.234985,53.456100000000106],[-129.23748799999993,53.43360099999995],[-129.27279699999997,53.37915800000002],[-129.30334499999992,53.38499499999995],[-129.333893,53.39749100000006],[-129.353607,53.40776800000003],[-129.518616,53.51499899999999],[-129.62914999999987,53.58776900000004],[-129.686127,53.630272000000105],[-129.83084099999996,53.74721500000004],[-129.86111499999998,53.76527399999998],[-129.912781,53.79833200000013],[-130.04501300000004,53.88304900000014],[-130.050293,53.88694000000004],[-130.099152,53.94193300000006],[-130.10137899999995,53.946655000000135],[-130.09136999999987,54.066101],[-130.09082,54.071662999999944],[-130.07693499999993,54.114441000000056],[-130.073334,54.12082700000013],[-130.065002,54.132209999999986],[-130.051666,54.14860500000009],[-130.04666099999997,54.15332000000012],[-129.86361699999998,54.213051000000064],[-129.84887700000002,54.21749100000011],[-129.83194000000003,54.21943699999997],[-129.78205899999995,54.21060199999994],[-129.72637899999995,54.20077100000009],[-129.69738799999993,54.194435000000055],[-129.68756099999996,54.19093300000003],[-129.644165,54.18193800000006],[-129.63333099999994,54.17999300000008],[-129.6141659999999,54.17891700000007],[-129.591949,54.18582200000009],[-129.470825,54.235825000000034],[-129.47000100000002,54.23721299999994],[-129.474426,54.239990000000034],[-129.48275799999988,54.243050000000096],[-129.5114139999999,54.244155999999975],[-129.51889,54.24193600000012],[-129.56140099999993,54.22693599999997],[-129.56777999999997,54.223877000000016],[-129.68238799999995,54.22160299999996],[-129.68823199999997,54.223099000000104],[-129.77654999999993,54.234767999999974],[-129.83666999999997,54.23832700000014],[-129.8549799999999,54.23804500000006],[-129.87136799999996,54.23526800000013],[-129.966949,54.20694000000003],[-129.97997999999995,54.20082900000011],[-129.9916689999999,54.19276400000001],[-130.037506,54.1730500000001],[-130.10443099999998,54.154434000000094],[-130.113312,54.15387700000002],[-130.122772,54.154434000000094],[-130.131104,54.15721099999996],[-130.19168099999996,54.19332100000008],[-130.22805800000003,54.25860600000004],[-130.238586,54.29499800000008],[-130.2611389999999,54.34276599999998],[-130.27584799999994,54.34971600000006],[-130.28250100000002,54.34638200000006],[-130.332764,54.329720000000066],[-130.34887700000002,54.32694200000009],[-130.39138799999995,54.33027600000008],[-130.45166,54.33665500000012],[-130.45916699999998,54.3386000000001],[-130.48111,54.36471599999999],[-130.48388699999998,54.401657000000114],[-130.4763789999999,54.430550000000096],[-130.47360199999997,54.43582200000003],[-130.433624,54.49665800000014],[-130.42999299999997,54.56249200000008],[-130.4397279999999,54.612213],[-130.44055200000003,54.617493000000024],[-130.438599,54.623604000000114],[-130.43277,54.62748700000003],[-130.42556799999994,54.62971500000003],[-130.41665599999993,54.630272000000105],[-130.40750099999997,54.62860100000006],[-130.39779699999997,54.62638100000004],[-130.38946499999992,54.62332200000003],[-130.37554899999992,54.616661000000136],[-130.33215299999995,54.578552],[-130.28167699999995,54.528381000000024],[-130.2227779999999,54.47193100000004],[-130.06304899999986,54.33998900000012],[-130.05776999999995,54.33610500000009],[-130.03723100000002,54.3261030000001],[-130.020844,54.31999200000001],[-129.9930419999999,54.31221000000005],[-129.98275799999993,54.31110400000006],[-129.96581999999995,54.313049000000035],[-129.95916699999998,54.31610099999995],[-129.95584099999985,54.322495],[-129.959717,54.32694200000009],[-129.96722399999993,54.32888000000003],[-129.98165900000004,54.32443999999998],[-129.99054,54.32388300000008],[-130.02362099999993,54.33554800000002],[-130.0386049999999,54.341934000000094],[-130.043884,54.34582499999999],[-130.14779699999997,54.44193300000012],[-130.31382799999994,54.58626900000007],[-130.36721799999992,54.635268999999994],[-130.37222299999996,54.64471400000008],[-130.374146,54.65499100000005],[-130.36859100000004,54.66777000000013],[-130.358612,54.677490000000034],[-130.352783,54.6813810000001],[-130.339722,54.687492000000134],[-130.32501200000002,54.692214999999976],[-130.24386599999997,54.70777100000009],[-130.23553499999997,54.70916000000011],[-130.22582999999997,54.708885000000066],[-130.17193599999996,54.70360600000009],[-130.16195700000003,54.7011030000001],[-130.15362500000003,54.69832600000001],[-130.10110499999996,54.67166099999997],[-130.075287,54.657767999999976],[-130.06887800000004,54.648604999999975],[-130.065002,54.644440000000145],[-130.054169,54.63665800000001],[-130.0269469999999,54.62304700000004],[-130.00058,54.61471599999993],[-129.980835,54.609993000000145],[-129.959991,54.607498000000135],[-129.910278,54.60555299999993],[-129.968323,54.62193300000007],[-130.0044559999999,54.632767000000115],[-130.02807599999994,54.641936999999984],[-130.19473299999999,54.72332],[-130.20166,54.72693600000008],[-130.20111099999986,54.73249099999998],[-130.17388899999992,54.84665699999999],[-130.171112,54.85166200000003],[-130.16583300000002,54.85665900000009],[-130.16082799999998,54.861382000000106],[-130.05835000000002,54.95277399999998],[-130.045837,54.95999100000006],[-130.03195199999993,54.96527100000014],[-129.94694499999991,54.9704900000001],[-129.9362789999999,54.97115300000007],[-129.92394999999993,54.97032200000007],[-129.91810599999985,54.96882600000009],[-129.90977499999997,54.96466100000009],[-129.90745500000003,54.9621580000001],[-129.65444899999994,54.980545000000006],[-129.646973,54.98276500000003],[-129.64028899999994,54.98582500000009],[-129.62249799999995,54.997772000000055],[-129.62499999999994,55.00249500000001],[-129.79998799999998,55.00694299999998],[-129.866089,55.00666000000001],[-129.875275,55.00610400000005],[-129.883331,55.00471500000003],[-129.90585299999998,54.997772000000055],[-129.91390999999993,54.99638399999992],[-129.964874,55.00343699999996],[-129.97171000000003,55.004608000000076],[-129.97905000000003,55.00893800000006],[-129.98138399999993,55.01160800000014],[-129.98104899999993,55.01493800000014],[-129.9963679999999,55.02416200000005],[-129.97555499999993,55.06693999999993],[-129.96139500000004,55.09332300000011],[-129.95638999999989,55.09804500000001],[-129.84750399999996,55.210548000000074],[-129.72665399999988,55.3386000000001],[-129.66300999999999,55.41221200000001],[-129.64334099999996,55.434158000000025],[-129.63723800000002,55.43804200000005],[-129.62222299999996,55.44249000000002],[-129.60525499999994,55.445267000000115],[-129.584717,55.4438780000001],[-129.541107,55.43804200000005],[-129.52389500000004,55.43998700000003],[-129.50863599999997,55.444435],[-129.48831199999995,55.45360599999992],[-129.47610499999996,55.46138000000013],[-129.47164899999996,55.46720900000014],[-129.47109999999992,55.472762999999986],[-129.475006,55.47693600000008],[-129.48416099999997,55.478600000000085],[-129.62027,55.459434999999985],[-129.63696299999998,55.45665699999995],[-129.679123,55.47315600000013],[-129.68611099999998,55.46749100000005],[-129.69662500000004,55.45399100000003],[-129.69979899999993,55.450993000000096],[-129.70428500000003,55.44966100000005],[-129.70979299999993,55.450657000000035],[-129.712112,55.453327000000115],[-129.71362299999993,55.45616100000012],[-129.78695700000003,55.56666600000011],[-129.78582800000004,55.50277699999998],[-129.779449,55.49360700000011],[-129.772247,55.47943099999992],[-129.78030399999994,55.35971799999999],[-129.78250100000002,55.35360700000007],[-129.81390399999987,55.28971900000005],[-129.81750499999998,55.28333299999997],[-129.90695199999988,55.168052999999986],[-129.911407,55.162491000000045],[-129.92083699999995,55.15193199999999],[-130.028351,55.03638500000011],[-130.068329,54.99694100000005],[-130.07443199999994,54.992767000000015],[-130.081665,54.99054699999999],[-130.09082,54.98999000000009],[-130.10055499999999,54.99054699999999],[-130.10833699999995,54.99249300000008],[-130.11361699999992,54.99638399999992],[-130.12777700000004,55.01388500000007],[-130.16027799999995,55.069717000000026],[-130.16223099999996,55.079994],[-130.1600039999999,55.08610500000009],[-130.11859099999998,55.14249399999994],[-130.11416599999995,55.1483310000001],[-130.0808409999999,55.18471499999998],[-130.06390399999998,55.195266999999944],[-130.04528799999997,55.20416300000005],[-130.03918499999992,55.208046000000024],[-129.948059,55.27638200000001],[-129.94387799999998,55.28221100000002],[-129.94473300000004,55.28721600000006],[-129.94888300000002,55.29583000000014],[-129.96054100000003,55.308884000000035],[-130.00863599999997,55.37082700000008],[-130.101654,55.55638099999999],[-130.103607,55.56666600000011],[-130.128876,55.72221400000012],[-130.12942499999997,55.73276500000003],[-130.128876,55.738602000000014],[-130.126099,55.750275000000045],[-130.12191799999994,55.762496999999996],[-130.116394,55.77499399999999],[-130.11276199999998,55.78166199999998],[-130.10833699999995,55.787216],[-130.09109499999994,55.799995000000024],[-130.079163,55.80804400000005],[-130.06722999999994,55.815826000000015],[-130.0552669999999,55.82388300000014],[-130.03945899999997,55.83832600000005],[-129.96664399999992,55.91220900000002],[-129.962219,55.91777000000002],[-129.9641719999999,55.928329000000076],[-129.97137499999985,55.931663999999955],[-129.97970599999985,55.932213000000104],[-129.99499500000002,55.92777300000006],[-130.0019529999999,55.924713000000054],[-130.00500499999993,55.921661000000086],[-130.01507600000002,55.90917999999999],[-130.01419099999998,56.02388000000013],[-130.0147399999999,56.02582600000005],[-130.0538939999999,56.07555400000001],[-130.08859299999995,56.11804999999998],[-130.22915599999993,56.09027100000014],[-130.3652649999999,56.123878000000104],[-130.4475099999999,56.20638300000007],[-130.46194499999996,56.23526800000013],[-130.48471099999995,56.23943300000013],[-130.53277599999996,56.246384000000035],[-130.5607149999999,56.250000000000114],[-130.62719699999997,56.25860600000004],[-130.720551,56.325554000000125],[-130.755859,56.353049999999996],[-130.77444500000001,56.366104000000064],[-130.84722899999997,56.37443500000012],[-130.92001300000004,56.38249200000013],[-131.05499299999997,56.398048000000074],[-131.07055699999995,56.403602999999976],[-131.12582399999997,56.42416399999996],[-131.1444699999999,56.4347150000001],[-131.164734,56.44526700000006],[-131.205261,56.4658280000001],[-131.22137499999997,56.47248800000011],[-131.290009,56.50054899999998],[-131.31445299999996,56.50999499999995],[-131.5394589999999,56.59665699999999],[-131.55777,56.602219000000105],[-131.578888,56.60332499999993],[-131.61111499999998,56.602219000000105],[-131.81610099999995,56.59499400000004],[-131.824158,56.59693900000002],[-131.82861299999996,56.60083000000009],[-131.85803199999987,56.71888000000013],[-131.86361699999992,56.78611000000012],[-131.86053500000003,56.797775],[-131.86138899999997,56.79972100000009],[-132.10305800000003,56.86666100000002],[-132.09194899999994,56.89360799999997],[-132.06195100000002,56.95971700000007],[-132.03668199999993,57.01305400000001],[-132.02749600000004,57.03638500000005],[-132.22109999999992,57.068054000000075],[-132.316956,57.08387800000003],[-132.33694500000001,57.088325999999995],[-132.32611099999997,57.10054800000012],[-132.26806599999986,57.16304800000006],[-132.25473,57.17471299999994],[-132.226654,57.20471199999997],[-132.35415599999988,57.35443900000013],[-132.36972000000003,57.37082700000002],[-132.37914999999992,57.37943300000012],[-132.45111099999986,57.43526500000007],[-132.471924,57.4511030000001],[-132.4927669999999,57.46665999999999],[-132.50363200000004,57.474158999999986],[-132.61944599999998,57.58332800000005],[-132.75250199999994,57.70943500000004],[-132.76113899999996,57.717765999999926],[-132.76889,57.72665400000011],[-132.78222700000003,57.74527000000012],[-132.79110699999995,57.7586060000001],[-132.795837,57.76888300000007],[-132.796112,57.77387999999996],[-132.80722000000003,57.787773000000016],[-132.81362899999988,57.795547],[-132.82138099999992,57.80443600000007],[-132.87304699999999,57.855270000000075],[-132.88165299999997,57.86360900000011],[-132.92861900000003,57.90554800000001],[-132.937775,57.91332200000005],[-132.964722,57.93332700000002],[-132.99499500000002,57.95166000000006],[-133.03332499999988,57.978874000000076],[-133.043884,57.986938000000066],[-133.05306999999993,57.99471299999999],[-133.058044,57.99943500000006],[-133.070831,58.012215000000026],[-133.087494,58.03333299999997],[-133.09500100000002,58.047775000000115],[-133.104156,58.073051000000135],[-133.107208,58.08332800000011],[-133.11111500000004,58.093323000000055],[-133.13696299999998,58.13582600000012],[-133.1847229999999,58.17610200000013],[-133.19500700000003,58.184158000000025],[-133.21139499999998,58.19638100000003],[-133.233612,58.21138000000013],[-133.3061219999999,58.25721699999997],[-133.36111499999993,58.28054800000001],[-133.43029799999994,58.35999300000009],[-133.408905,58.40026899999992],[-133.38790899999998,58.4120640000001],[-133.4299929999999,58.459160000000054],[-133.55889899999994,58.528046000000074],[-133.73580900000002,58.644713999999965],[-133.80834999999996,58.709991],[-133.826935,58.72609700000004],[-134.087494,58.80832700000013],[-134.2311099999999,58.85193600000002],[-134.245544,58.85694100000006],[-134.32000699999998,58.91609999999997],[-134.325562,58.920830000000024],[-134.33221400000002,58.92971800000004],[-134.33221400000002,58.93526500000013],[-134.325562,58.971100000000035],[-134.3794249999999,59.049164000000076],[-134.38613899999996,59.05804400000011],[-134.45556599999998,59.12248999999997],[-134.46139499999992,59.126656000000025],[-134.4750059999999,59.1336060000001],[-134.53222700000003,59.13221000000004],[-134.56640599999997,59.13054700000009],[-134.65084799999994,59.185546999999985],[-134.67166099999997,59.2002720000001],[-134.675293,59.21471400000007],[-134.68804899999992,59.24332400000009],[-134.7388919999999,59.250275000000045],[-134.95193499999993,59.27999100000011],[-135.09167499999995,59.426941],[-135.07971199999992,59.4447100000001],[-135.06332399999997,59.45804600000008],[-135.03973399999995,59.46693400000004],[-135.030579,59.46804800000001],[-135.02111799999994,59.47109999999992],[-135.017792,59.49887800000005],[-135.015015,59.54055000000011],[-135.01446499999997,59.567497],[-135.09722899999997,59.621376000000055],[-135.12027,59.62165800000014],[-135.13275099999998,59.62276500000007],[-135.1541749999999,59.62721300000004],[-135.17749000000003,59.63693999999998],[-135.336121,59.72665400000005],[-135.47360199999997,59.801933000000076],[-135.50613399999997,59.79388400000005],[-135.823334,59.70555099999996],[-135.949158,59.66915899999998],[-136.07138099999997,59.6574940000001],[-136.12081899999998,59.65165699999994],[-136.16000399999996,59.646660000000054],[-136.20776399999988,59.63943499999999],[-136.31054700000004,59.61249500000014],[-136.34387200000003,59.60277600000012],[-136.3463749999999,59.600548],[-136.29834,59.58360300000004],[-136.239166,59.56137799999999],[-136.23388699999992,59.52582600000005],[-136.2930599999999,59.47609700000004],[-136.29998799999993,59.47109999999992],[-136.371643,59.45249200000006],[-136.46362299999993,59.46971100000013],[-136.46417199999996,59.414153999999996],[-136.46249399999994,59.37221500000004],[-136.46249399999994,59.30249000000009],[-136.46276899999998,59.28943600000002],[-136.48083499999996,59.261939999999925],[-136.49221799999998,59.24971800000014],[-136.55835000000002,59.18637799999999],[-136.58389299999988,59.16332199999994],[-136.61138900000003,59.164711000000125],[-136.71972699999998,59.165268000000026],[-136.80889899999994,59.165268000000026],[-136.88833599999998,59.131935],[-136.94195599999995,59.10943600000007],[-136.96972700000003,59.098328000000095],[-137.03308100000004,59.07749200000006],[-137.25167799999997,59.00610400000011],[-137.296112,58.98998999999998],[-137.31417799999997,58.98110200000002],[-137.33889799999997,58.965546000000074],[-137.392792,58.92832900000002],[-137.42028800000003,58.91415400000011],[-137.42749000000003,58.911377000000016],[-137.44500699999998,58.9074940000001],[-137.46554600000002,58.90609699999993],[-137.47805800000003,58.90721100000013],[-137.48803699999996,58.90915699999999],[-137.49581899999998,58.91193400000009],[-137.5016779999999,58.916382000000056],[-137.50500499999993,58.92027300000012],[-137.50750700000003,58.925552000000096],[-137.50723299999999,58.93776700000001],[-137.50527999999997,58.94415300000014],[-137.49722299999996,58.96415700000006],[-137.48776199999992,58.98249099999998],[-137.47970599999996,58.998046999999985],[-137.49914599999994,59.04138200000011],[-137.54528799999997,59.14305100000013],[-137.566101,59.18693500000006],[-137.59082,59.238602000000014],[-137.910278,59.40804300000008],[-138.11776699999996,59.51666300000005],[-138.30361900000003,59.61305200000004],[-138.49108899999993,59.70832800000005],[-138.5386049999999,59.73220800000007],[-138.615814,59.77416199999999],[-138.647247,59.80555000000004],[-138.65472399999993,59.81471300000004],[-138.66363499999989,59.82916299999994],[-138.66610699999995,59.83443500000004],[-138.66915900000004,59.8449940000001],[-138.67501799999997,59.86693600000001],[-138.69027700000004,59.90693699999997],[-138.97192399999994,59.978600000000085],[-139.04779099999996,59.99749000000003],[-139.116394,60.04138200000011],[-139.161407,60.07027400000004],[-139.18890399999987,60.08888200000007],[-139.183899,60.102219000000105],[-139.15527299999997,60.15499100000005],[-139.13363600000002,60.19443500000011],[-139.12527499999993,60.20777100000009],[-139.08221399999996,60.28749800000003],[-139.06500199999988,60.33027600000008],[-139.06640600000003,60.344153999999946],[-139.06805399999996,60.35221900000005],[-139.51947,60.34471100000002],[-139.67666599999995,60.34054600000002],[-139.77166699999992,60.29249600000003],[-139.866394,60.24443800000006],[-139.91305499999987,60.220824999999934],[-139.97943099999998,60.18776700000012],[-140.005585,60.19387800000004],[-140.45083599999992,60.3097150000001],[-140.471924,60.283882000000006],[-140.493042,60.25777400000004],[-140.50195299999996,60.244713000000104],[-140.52139299999993,60.22221400000012],[-140.94638099999997,60.297775],[-140.995544,60.30721300000005],[-141.00058,60.36666100000002],[-141.001129,60.39943699999998],[-141.00030500000003,60.933051999999975],[-141.0016779999999,60.966384999999946],[-141.00030500000003,62.73304699999994],[-141.00140399999998,63.09999800000014],[-141.00195299999996,63.83277099999998],[-141.00030500000003,63.96638500000006],[-141.00030500000003,64.19970699999999],[-141.00195299999996,65.1327510000001],[-141.00030500000003,65.16609200000005],[-141.00030500000003,65.23275800000005],[-141.00195299999996,65.69941699999998],[-141.00195299999996,66.099426],[-141.0016779999999,66.49941999999999],[-141.00085399999995,66.66638200000011],[-141.00058,66.8660890000001],[-141.0016779999999,67.0663760000001],[-141.00222799999995,67.29914900000006],[-141.00058,67.53248600000012],[-141,67.7327580000001],[-141.00195299999996,67.86581400000006],[-141.00195299999996,68.06581100000005],[-141.00195299999996,68.23275799999999],[-141.0016779999999,68.53276100000011],[-141.00085399999995,68.96554600000002],[-141.00058,69.43247999999994],[-141.00085399999995,69.53221100000002],[-141.002991,69.6423650000001],[-140.982208,69.64276100000001],[-140.90945399999998,69.63916000000012],[-140.83306900000002,69.63526900000005],[-140.81610099999995,69.6336060000001],[-140.79528799999997,69.62719700000008],[-140.77002,69.62164300000006],[-140.738312,69.617752],[-140.61554,69.60832199999993],[-140.488312,69.599426],[-140.39611799999994,69.59609999999998],[-140.26141399999995,69.59664900000013],[-140.21887200000003,69.60081500000001],[-140.17944299999988,69.60636900000003],[-140.12914999999998,69.61499000000009],[-140.10055499999999,69.61747700000001],[-140.084717,69.618042],[-139.94387800000004,69.61886599999997],[-139.9263919999999,69.61859099999998],[-139.88833599999998,69.61665300000004],[-139.81054699999999,69.60664400000002],[-139.78112799999997,69.60220300000009],[-139.605255,69.57554600000003],[-139.57611099999986,69.570831],[-139.67001299999998,69.579163],[-139.68472299999996,69.58137500000004],[-139.77639799999997,69.599716],[-139.7647399999999,69.59082000000006],[-139.75668299999995,69.58665500000006],[-139.73165899999998,69.58109999999999],[-139.60665899999992,69.559418],[-139.573059,69.55609100000004],[-139.5350039999999,69.55386399999998],[-139.351654,69.53637700000013],[-139.14306599999998,69.51081799999992],[-139.116394,69.50555400000013],[-139.10833699999995,69.50166300000006],[-139.10137899999995,69.49136400000003],[-139.092224,69.48165899999998],[-139.069458,69.46331800000013],[-139.05584699999991,69.45498700000007],[-139.04806499999995,69.45082100000013],[-138.975281,69.4149930000001],[-138.957489,69.407486],[-138.93945299999996,69.39999400000005],[-138.88275099999993,69.38472000000013],[-138.83361799999994,69.37330600000007],[-138.7991639999999,69.36415099999999],[-138.769165,69.35386699999998],[-138.75140399999998,69.34637500000002],[-138.64389,69.29136700000004],[-138.621643,69.27304100000003],[-138.616394,69.268326],[-138.60720799999996,69.2586060000001],[-138.60498,69.24748200000005],[-138.44998199999992,69.22915600000005],[-138.269165,69.19636500000007],[-138.25390599999997,69.188309],[-138.21887200000003,69.17330900000007],[-138.17721599999993,69.15998800000011],[-138.14334099999996,69.15081800000007],[-138.06332399999997,69.12942499999997],[-138.03945899999997,69.12359600000013],[-138.00112899999993,69.11526500000002],[-137.69638099999992,69.049713],[-137.594452,69.02777100000014],[-137.41915900000004,68.988876],[-137.25500499999998,68.94831800000009],[-137.22610499999996,68.94497700000005],[-137.19222999999994,68.94386300000008],[-137.13027999999986,68.94497700000005],[-136.9786069999999,68.93193100000013],[-136.97332799999998,68.92720000000003],[-136.966095,68.92330900000013],[-136.95416299999994,68.9202580000001],[-136.78973399999995,68.88192700000008],[-136.74554399999994,68.87525900000009],[-136.68249499999996,68.87191800000005],[-136.65972899999997,68.87498499999998],[-136.64279199999993,68.87803600000001],[-136.63751199999996,68.88415500000002],[-136.630829,68.88916000000006],[-136.61999500000002,68.89193699999998],[-136.522247,68.90914900000001],[-136.50836199999998,68.91026299999999],[-136.47747800000002,68.91081200000013],[-136.42059299999994,68.9015500000001],[-136.39306599999992,68.89721700000007],[-136.358612,68.89387499999992],[-136.255859,68.8894350000001],[-136.14502,68.88581799999997],[-136.0972289999999,68.88220200000012],[-136.0278019999999,68.87303200000002],[-135.98666399999996,68.86499000000009],[-135.85879499999993,68.83897400000006],[-135.831665,68.83194000000003],[-135.54055799999992,68.75248699999997],[-135.519745,68.74581900000004],[-135.49194299999988,68.73525999999998],[-135.484985,68.7310940000001],[-135.45388799999995,68.70942700000006],[-135.40695199999993,68.67997700000012],[-135.36554,68.67581200000012],[-135.21054099999998,68.66137700000002],[-135.1600039999999,68.65721100000013],[-135.14752199999998,68.65887499999997],[-135.14639299999993,68.66387900000012],[-135.21444699999995,68.693039],[-135.25363200000004,68.70694000000015],[-135.34359699999993,68.73776200000003],[-135.48193400000002,68.80941800000011],[-135.50613399999997,68.83248899999995],[-135.500854,68.838593],[-135.48666399999996,68.83943199999999],[-135.45306399999998,68.83804299999997],[-135.4391779999999,68.83554100000009],[-135.40499899999998,68.83194000000003],[-135.341949,68.83166499999999],[-135.33804299999997,68.83499100000006],[-135.34973099999996,68.83804299999997],[-135.42166099999997,68.84887700000002],[-135.49472000000003,68.85497999999995],[-135.52835099999993,68.85636899999997],[-135.56054700000004,68.86026000000004],[-135.595276,68.86943100000002],[-135.60443099999998,68.87303200000002],[-135.61886599999997,68.88136299999996],[-135.62359600000002,68.88610799999998],[-135.6138919999999,68.8894350000001],[-135.33581499999997,68.91775500000011],[-135.241669,68.9269260000001],[-135.22720299999997,68.92553700000008],[-135.21554600000002,68.922485],[-135.20861799999994,68.91832],[-135.1966549999999,68.90971400000006],[-135.19168100000002,68.90498400000001],[-135.18695100000002,68.90026899999998],[-135.121918,68.893326],[-134.97747799999996,68.87831100000005],[-134.95111099999997,68.88108799999992],[-134.91723599999995,68.89804100000003],[-134.89474499999994,68.91249099999993],[-134.87777700000004,68.92082200000004],[-134.85803199999998,68.92776500000002],[-134.845551,68.92942800000014],[-134.81723,68.92581200000006],[-134.80334499999998,68.92303500000003],[-134.74581899999998,68.90748600000006],[-134.708893,68.89276100000012],[-134.6694639999999,68.87330599999996],[-134.64169299999992,68.85664400000002],[-134.49554399999994,68.75221300000004]],[[-93.51972999999992,63.8394320000001],[-93.33999599999999,63.80832700000002],[-93.32972699999993,63.8097150000001],[-93.21749899999998,63.838599999999985],[-93.21611000000001,63.843605000000025],[-93.22500600000001,63.84777100000014],[-93.23638900000003,63.84748799999994],[-93.26750199999992,63.84276600000004],[-93.27888499999995,63.84249100000005],[-93.29167199999995,63.84499400000004],[-93.33389299999993,63.85916099999997],[-93.34333800000002,63.86305200000004],[-93.35749800000002,63.87137600000011],[-93.44193999999993,63.921660999999915],[-93.44888300000002,63.92582700000003],[-93.44972199999995,63.93082400000009],[-93.45249899999999,63.95443700000004],[-93.45111099999997,63.959717000000126],[-93.443329,63.96554600000013],[-93.43388400000003,63.96859699999999],[-93.42361499999993,63.970825000000104],[-93.41305499999999,63.97193099999993],[-93.38999899999993,63.97165699999999],[-93.36471599999993,63.96749100000011],[-93.27305599999994,63.92804700000005],[-93.12222300000002,63.892494],[-92.96028100000001,63.85582699999998],[-92.84167500000001,63.83526599999999],[-92.65194699999995,63.78749800000003],[-92.54972800000002,63.81082200000003],[-92.54055800000003,63.8147130000001],[-92.53056300000003,63.81693999999999],[-92.50750699999998,63.81638300000009],[-92.58389299999999,63.829436999999984],[-92.60694899999987,63.82972000000012],[-92.61915599999992,63.83138300000007],[-92.66915899999998,63.839989],[-92.70695499999994,63.84665699999994],[-92.93554699999999,63.904990999999995],[-92.94248999999996,63.90915700000005],[-92.95611600000001,63.932770000000005],[-92.96528599999999,63.93665299999992],[-93.218887,63.979431000000034],[-93.26611300000002,63.981934000000024],[-93.27639799999997,63.97971300000006],[-93.28805499999999,63.980545000000006],[-93.30110200000001,63.983047000000056],[-93.43666100000002,64.01527400000003],[-93.612213,64.09304800000007],[-93.62721299999998,64.10636900000003],[-93.63500999999991,64.11526500000014],[-93.63583399999999,64.12025500000004],[-93.68998699999992,64.15609699999999],[-93.75167799999991,64.18887300000006],[-93.76112399999988,64.19274899999999],[-93.773056,64.19358799999992],[-93.77972399999999,64.18969700000002],[-93.776947,64.18498199999999],[-93.66500899999994,64.08720400000004],[-93.66000400000001,64.08305400000006],[-93.604172,64.04443400000014],[-93.65472399999993,63.992493000000024],[-93.731674,63.987213],[-93.75917099999992,63.98416100000003],[-93.77055399999995,63.95777100000004],[-93.654449,63.89666000000011],[-93.59973100000002,63.87027000000006],[-93.55360399999995,63.850548],[-93.53332499999999,63.84276600000004],[-93.51972999999992,63.8394320000001]],[[-70.78306599999996,48.38054700000009],[-70.78250100000002,48.34804500000013],[-70.76806599999992,48.35054800000006],[-70.54804999999999,48.35638399999999],[-70.49888599999991,48.353324999999984],[-70.46417200000002,48.3491590000001],[-70.38305700000001,48.331108000000086],[-70.33222999999998,48.31666600000011],[-70.27278099999995,48.298332000000016],[-70.23777799999999,48.282493999999986],[-70.21000700000002,48.26971400000002],[-70.19860799999998,48.26249700000011],[-70.06138599999997,48.23998999999998],[-70.04083300000002,48.244437999999946],[-70.02583300000003,48.24610100000007],[-70.01750199999987,48.24527000000006],[-69.995544,48.23998999999998],[-69.936935,48.22193100000004],[-69.92054699999989,48.216385],[-69.82833900000003,48.166382000000056],[-69.83833300000003,48.173881999999935],[-69.84722899999997,48.181938],[-69.86193800000001,48.198875000000044],[-69.87193300000001,48.212493999999936],[-69.87943999999993,48.22082500000005],[-69.88417099999998,48.22415900000004],[-69.95944199999991,48.26944000000009],[-69.97721899999999,48.27443699999998],[-69.98554999999999,48.27499400000005],[-69.99333200000001,48.27471200000002],[-70.04361,48.267211999999915],[-70.09999099999999,48.267211999999915],[-70.13194299999998,48.26971400000002],[-70.15110800000002,48.27443699999998],[-70.16777000000002,48.279990999999995],[-70.27250700000002,48.325554000000125],[-70.42027300000001,48.36138199999999],[-70.42777999999998,48.36110700000012],[-70.63500999999997,48.39054900000008],[-70.72778299999987,48.4158250000001],[-70.73916599999995,48.42304999999999],[-70.75195299999996,48.42849300000006],[-70.76139799999993,48.431938],[-70.77999899999998,48.435546999999985],[-70.95472699999999,48.45971700000001],[-70.98055999999991,48.46221200000002],[-71.01222199999995,48.46166199999999],[-71.02528399999989,48.45749699999999],[-71.04861499999993,48.44526700000006],[-71.04777499999989,48.44443499999994],[-71.031387,48.44332099999997],[-70.90638699999994,48.423325000000034],[-70.79998799999998,48.40165700000006],[-70.78555299999988,48.39582800000005],[-70.78138699999988,48.391936999999984],[-70.779449,48.386940000000095],[-70.78306599999996,48.38054700000009]],[[-108.13890100000003,71.98165899999998],[-108.15583799999996,71.98082000000005],[-108.17415599999998,71.9833220000001],[-108.18721,71.98664900000006],[-108.18916300000001,71.99192800000003],[-108.19972199999995,72.05053700000008],[-108.19027699999998,72.05554200000012],[-108.1702729999999,72.06442300000003],[-108.16027799999995,72.06275900000003],[-108.13417099999992,72.0560910000001],[-108.07444799999996,72.03414900000001],[-108.06416299999995,72.03027299999997],[-108.06221,72.02526899999998],[-108.06304899999998,72.01944000000015],[-108.069458,72.01304600000009],[-108.07721700000002,72.00721700000008],[-108.10526999999996,71.992752],[-108.12526700000001,71.98387100000002],[-108.13890100000003,71.98165899999998]],[[-85.84722899999997,72.29414400000007],[-85.83721899999995,72.28887900000001],[-85.83721899999995,72.26277199999993],[-85.85166900000002,72.24136400000003],[-85.87748699999992,72.22164900000001],[-85.88917500000002,72.21804799999995],[-85.90834000000001,72.21775800000012],[-85.98111,72.23637399999996],[-86.00584400000002,72.2435910000001],[-86.06111099999998,72.26165800000012],[-86.09638999999999,72.27638200000001],[-86.10722399999992,72.28387500000002],[-86.11000100000001,72.28970300000015],[-86.10139500000002,72.29359400000004],[-86.09333800000002,72.29470800000001],[-86.06723,72.29386900000003],[-86.00500499999998,72.29664600000012],[-85.86389199999996,72.297211],[-85.84722899999997,72.29414400000007]],[[-78.73500099999995,72.36554000000012],[-78.75389100000001,72.36331200000001],[-78.81220999999988,72.36526500000008],[-78.83084099999996,72.36499000000009],[-78.854172,72.36219799999998],[-78.874435,72.35887100000008],[-78.88945000000001,72.35470600000008],[-78.91332999999986,72.3455350000001],[-78.92083699999995,72.3413700000001],[-78.93499799999995,72.33638000000008],[-78.95028699999995,72.33499100000006],[-79.05305499999997,72.36080900000002],[-79.07556199999993,72.40304600000007],[-79.07501200000002,72.40971400000006],[-79.07084700000001,72.41499300000004],[-79.066666,72.4202580000001],[-79.04444899999993,72.42665100000005],[-79.00140399999998,72.43830900000012],[-78.97084000000001,72.44525099999998],[-78.95556599999992,72.44442700000002],[-78.95056199999999,72.44219999999996],[-78.94665500000002,72.44026200000002],[-78.93998699999992,72.43580600000013],[-78.84695399999993,72.41554300000007],[-78.83389299999999,72.41192600000011],[-78.74082900000002,72.37441999999999],[-78.73167399999994,72.36943100000002],[-78.73500099999995,72.36554000000012]],[[-79.50805699999995,72.34860200000003],[-79.53388999999999,72.34609999999998],[-79.55583200000001,72.34693900000008],[-79.57223499999998,72.34915200000006],[-79.581955,72.35165399999994],[-79.59445199999999,72.35693400000002],[-79.60943600000002,72.36692800000003],[-79.6241609999999,72.37942500000003],[-79.68331899999998,72.43054200000012],[-79.58612099999999,72.45387299999999],[-79.57667500000002,72.45610000000005],[-79.55248999999992,72.45109600000012],[-79.541382,72.44497700000005],[-79.52917499999995,72.43969700000002],[-79.50279199999989,72.42997700000012],[-79.46945199999999,72.42303500000003],[-79.43638599999997,72.41832],[-79.42971799999998,72.411652],[-79.44055200000003,72.37052900000009],[-79.44665499999991,72.36499000000009],[-79.45556599999992,72.35998500000005],[-79.47027599999996,72.355545],[-79.50805699999995,72.34860200000003]],[[-79.993607,72.41331500000013],[-80.00944500000003,72.41053800000003],[-80.02223200000003,72.41360500000013],[-80.124435,72.50665300000003],[-80.13055400000002,72.51249700000005],[-80.13333099999994,72.51944000000003],[-80.1299899999999,72.52304100000009],[-80.11999499999996,72.52693199999999],[-80.11250299999995,72.52693199999999],[-80.06361399999997,72.52388000000008],[-80.0369419999999,72.51638800000012],[-79.92193600000002,72.46331800000007],[-79.91639700000002,72.45803799999999],[-79.926941,72.44775400000015],[-79.93916299999995,72.436646],[-79.956955,72.42608600000005],[-79.97888199999989,72.41775500000011],[-79.993607,72.41331500000013]],[[-110.46916199999993,72.56915299999997],[-110.48137699999995,72.56581100000005],[-110.54415899999998,72.56915299999997],[-110.57195300000001,72.57554600000014],[-110.58833299999998,72.58387800000014],[-110.593887,72.58859299999995],[-110.593887,72.59414700000013],[-110.576683,72.59498600000012],[-110.53888699999993,72.59498600000012],[-110.516663,72.593323],[-110.50446299999999,72.59082000000001],[-110.48249799999991,72.5836030000001],[-110.47444200000001,72.57943700000004],[-110.46888699999994,72.57470699999999],[-110.46916199999993,72.56915299999997]],[[-110.35582699999998,72.6019290000001],[-110.37304699999993,72.60137900000007],[-110.39499699999993,72.60304300000007],[-110.4641719999999,72.61331200000012],[-110.49472000000003,72.61914100000013],[-110.46916199999993,72.62136800000002],[-110.450287,72.62136800000002],[-110.39862099999993,72.61804199999995],[-110.35888699999992,72.61499000000003],[-110.34500100000002,72.6119230000001],[-110.34500100000002,72.6060940000001],[-110.35582699999998,72.6019290000001]],[[-108.510559,72.60276800000008],[-108.51999699999993,72.59803800000003],[-108.53778099999994,72.59942600000011],[-108.593613,72.61775200000011],[-108.604446,72.621643],[-108.61221299999994,72.62580900000012],[-108.6141659999999,72.63108800000009],[-108.61361699999986,72.63665799999995],[-108.60388199999994,72.63943500000005],[-108.51722699999999,72.64248700000002],[-108.49665800000002,72.64137299999999],[-108.49194299999999,72.63665799999995],[-108.49416400000001,72.63192700000002],[-108.510559,72.60276800000008]],[[-110.30722000000003,72.63081399999999],[-110.36389199999996,72.63081399999999],[-110.39695699999993,72.63638300000014],[-110.41082799999998,72.63943500000005],[-110.40028399999994,72.64360000000005],[-110.36000100000001,72.64888000000013],[-110.31500199999999,72.65193200000004],[-110.28083799999996,72.64221199999997],[-110.281113,72.63638300000014],[-110.28999299999992,72.63165300000009],[-110.30722000000003,72.63081399999999]],[[-109.215012,72.79026800000008],[-109.22749299999992,72.78720099999998],[-109.24833699999999,72.78804000000014],[-109.37277199999994,72.8060910000001],[-109.41694599999988,72.81526200000008],[-109.41944899999993,72.82054100000005],[-109.37832600000002,72.828598],[-109.33389299999999,72.83499099999995],[-109.32028200000002,72.8316650000001],[-109.31220999999994,72.82748400000003],[-109.22444200000001,72.81109600000013],[-109.21056399999998,72.8077550000001],[-109.21166999999997,72.79637100000002],[-109.215012,72.79026800000008]],[[-95.73500099999995,72.79887400000001],[-95.75361599999991,72.79609700000009],[-95.77139299999993,72.799149],[-95.835556,72.83110000000005],[-95.854172,72.85359199999999],[-95.85082999999997,72.85832199999999],[-95.81054699999993,72.87664799999999],[-95.79110699999995,72.88026400000007],[-95.77417000000003,72.88026400000007],[-95.76916499999999,72.87803600000012],[-95.76306199999988,72.8724820000001],[-95.735275,72.85998500000011],[-95.72055099999994,72.84803799999997],[-95.716949,72.84387200000009],[-95.7141719999999,72.83859300000012],[-95.71362299999987,72.83221400000008],[-95.71888699999994,72.80941800000005],[-95.72500599999995,72.803314],[-95.73500099999995,72.79887400000001]],[[-96.75418100000002,72.72137499999997],[-96.77027899999996,72.71971099999996],[-96.95527599999997,72.73414600000007],[-96.96945199999999,72.73776199999998],[-96.97778299999999,72.74525499999999],[-97.01112399999994,72.77581800000013],[-97.0102839999999,72.77665700000011],[-96.92138699999998,72.83581500000008],[-96.91111799999993,72.841095],[-96.79861499999998,72.88136300000002],[-96.75723299999993,72.89276100000006],[-96.737213,72.89526400000005],[-96.72555499999999,72.89498900000001],[-96.71333299999992,72.89332600000006],[-96.68832399999997,72.883331],[-96.69221500000003,72.86276200000003],[-96.666946,72.81109600000013],[-96.65167200000002,72.80415299999999],[-96.64250199999998,72.79776000000004],[-96.63999899999999,72.79165599999999],[-96.63999899999999,72.786652],[-96.641388,72.78221100000007],[-96.72805800000003,72.73054500000006],[-96.741379,72.72553999999997],[-96.75418100000002,72.72137499999997]],[[-95.756958,72.89248700000013],[-95.77749599999999,72.8919370000001],[-95.79527299999995,72.89498900000001],[-95.808334,72.90721099999996],[-95.82472199999995,72.96527100000009],[-95.78666699999997,73.01249699999994],[-95.76167299999997,73.00471499999998],[-95.75723299999993,73.00166300000006],[-95.75611899999996,72.99859600000013],[-95.743607,72.98776200000009],[-95.70249899999999,72.93359399999997],[-95.70834399999995,72.91720600000008],[-95.73554999999999,72.90054300000003],[-95.74444599999993,72.895828],[-95.756958,72.89248700000013]],[[-95.73388699999998,73.12886000000003],[-95.71806299999997,73.11804200000006],[-95.71583599999991,73.11192299999999],[-95.71556099999998,73.10554500000006],[-95.71777299999997,73.10026600000009],[-95.72639500000002,73.08888199999996],[-95.72917199999995,73.07110599999999],[-95.72471599999994,73.05914299999995],[-95.7283329999999,73.05442800000014],[-95.74554399999994,73.04942300000005],[-95.775284,73.05525200000011],[-95.787216,73.06192000000004],[-95.79943799999995,73.07276900000011],[-95.82250999999997,73.08305400000006],[-95.85972600000002,73.09082000000012],[-95.89334100000002,73.09582499999999],[-95.89306599999998,73.10081500000001],[-95.89111299999996,73.10108900000012],[-95.88500999999991,73.10470600000008],[-95.88194299999998,73.10859700000015],[-95.87471,73.11415099999999],[-95.86527999999993,73.11998],[-95.86305199999998,73.12525900000014],[-95.86527999999993,73.13136300000002],[-95.86833200000001,73.13638300000002],[-95.86888099999999,73.14054899999996],[-95.85499599999997,73.14054899999996],[-95.84083599999997,73.13665800000007],[-95.828888,73.129974],[-95.82250999999997,73.12469500000003],[-95.81834399999997,73.12553399999996],[-95.81416300000001,73.13108799999998],[-95.80749500000002,73.1355440000001],[-95.79083300000002,73.13943499999999],[-95.77639799999992,73.14054899999996],[-95.76333599999998,73.1397090000001],[-95.74499499999996,73.13665800000007],[-95.73889200000002,73.13388099999997],[-95.73388699999998,73.12886000000003]],[[-96.80833399999995,72.92637600000012],[-96.91528299999993,72.91775500000006],[-96.95527599999997,72.92053199999992],[-96.96833800000002,72.92387400000007],[-96.99055499999997,72.93109099999998],[-97.01777600000003,72.94053600000007],[-97.03222700000003,72.94664000000006],[-97.06138599999991,72.96331800000013],[-97.089722,72.98165899999998],[-97.10583499999996,72.99832200000003],[-97.11193800000001,73.00471499999998],[-97.13694799999996,73.04582200000004],[-97.13972499999988,73.05192600000004],[-97.141953,73.06414800000005],[-97.14277599999997,73.0752720000001],[-97.14111299999996,73.08554100000015],[-97.12777699999992,73.09582499999999],[-97.06973299999999,73.136932],[-97.05943299999996,73.14221200000003],[-97.045547,73.14749100000006],[-97.00334199999998,73.15971400000006],[-96.94694499999997,73.172485],[-96.904449,73.17997700000012],[-96.848053,73.18748499999998],[-96.80943300000001,73.1891480000001],[-96.78639199999998,73.18803400000013],[-96.77194199999997,73.18165599999998],[-96.75527999999997,73.17581200000012],[-96.65306099999992,73.13638300000002],[-96.60221899999993,73.09915200000012],[-96.58084100000002,73.08110000000005],[-96.5750119999999,73.07499700000005],[-96.56861900000001,73.06219500000009],[-96.56582600000002,73.05609100000004],[-96.56471299999998,73.05053700000008],[-96.56555200000003,73.04470800000001],[-96.573624,73.03332500000005],[-96.63667299999997,72.96582000000006],[-96.64334100000002,72.96138000000002],[-96.65834000000001,72.95416300000011],[-96.69721999999996,72.94165000000004],[-96.74305700000002,72.93359399999997],[-96.76501499999995,72.93081700000005],[-96.80833399999995,72.92637600000012]],[[-96.90583799999996,73.22082500000005],[-96.924713,73.21804800000012],[-96.94499199999996,73.21832299999994],[-96.98472599999997,73.22053500000004],[-97.04083300000002,73.22859199999999],[-97.07917799999996,73.23525999999998],[-97.10694899999993,73.24220300000013],[-97.11776700000001,73.24914599999994],[-97.11527999999993,73.25305200000003],[-97.09028599999988,73.26193200000006],[-97.058044,73.26915000000008],[-97.03500400000001,73.2727660000001],[-96.97749299999998,73.27388000000008],[-96.96777299999997,73.27331500000008],[-96.96833800000002,73.26748700000013],[-96.95140099999998,73.23942600000004],[-96.90916400000003,73.23831200000006],[-96.896118,73.23776200000003],[-96.88667299999992,73.23109400000004],[-96.88917499999997,73.2249910000001],[-96.90583799999996,73.22082500000005]],[[-113.99749799999995,72.7994230000001],[-114.01112399999994,72.79664600000001],[-114.06806899999998,72.79582200000004],[-114.15167200000002,72.79803500000003],[-114.20861799999994,72.79693600000007],[-114.22416699999997,72.79498300000012],[-114.23581699999994,72.79165599999999],[-114.35138699999993,72.74748200000005],[-114.35749800000002,72.74136400000009],[-114.35637700000001,72.73580900000002],[-114.33444199999997,72.69358800000003],[-114.327789,72.688873],[-114.36582900000002,72.66276600000009],[-114.45168299999995,72.62303200000002],[-114.46501199999994,72.6202550000001],[-114.49553699999996,72.61637900000005],[-114.53138699999988,72.61499000000003],[-114.576683,72.60914600000001],[-114.58999599999993,72.60636899999992],[-114.60472099999998,72.60165400000011],[-114.55832700000002,72.56080600000001],[-114.42666600000001,72.55609099999998],[-114.38527699999986,72.555252],[-114.35138699999993,72.55747999999994],[-114.33999599999999,72.56080600000001],[-114.33029199999999,72.56526200000008],[-114.32584400000002,72.57193000000007],[-114.12805200000003,72.62608300000005],[-114.10305800000003,72.63220200000006],[-114.06276699999995,72.64027400000003],[-113.99027999999998,72.65138200000001],[-113.910278,72.65914899999996],[-113.89306599999998,72.66026299999999],[-113.88333099999988,72.65748600000006],[-113.89046499999995,72.64804800000002],[-113.89222699999999,72.64082299999995],[-113.88054699999992,72.6372070000001],[-113.858047,72.63581799999992],[-113.80666399999996,72.63916000000006],[-113.76222199999995,72.64610300000004],[-113.70834400000001,72.65693700000008],[-113.67138699999992,72.6666560000001],[-113.61277799999988,72.68386800000013],[-113.58750899999995,72.68997199999995],[-113.54666099999997,72.69802900000013],[-113.51611300000002,72.70193499999999],[-113.50611900000001,72.699142],[-113.52084400000001,72.68803400000002],[-113.55055199999987,72.67526200000003],[-113.57250999999991,72.66748000000007],[-113.61945299999996,72.653595],[-113.64277599999991,72.64665200000002],[-113.68776699999995,72.63192700000002],[-113.70944199999991,72.624146],[-113.729172,72.61554000000007],[-113.73082699999998,72.60942100000005],[-113.72193900000002,72.60554499999995],[-113.69972200000001,72.60415599999999],[-113.68443299999996,72.6060940000001],[-113.65750100000002,72.61137400000001],[-113.46639999999996,72.66526800000003],[-113.44275700000003,72.672211],[-113.436394,72.67804000000001],[-113.431671,72.684708],[-113.41000399999996,72.72943100000003],[-113.41332999999992,72.73471100000012],[-113.41972399999997,72.73915099999994],[-113.43138099999999,72.742752],[-113.44860799999992,72.74498],[-113.53527799999995,72.74887100000007],[-113.58029199999987,72.75166300000012],[-113.59750399999996,72.75416600000011],[-113.60637699999995,72.75833100000011],[-113.60804699999994,72.76943999999997],[-113.59889199999998,72.78276099999994],[-113.58249699999999,72.793045],[-113.38694800000002,72.907486],[-113.33139,72.93525700000009],[-113.30277999999998,72.94886800000006],[-113.26862299999999,72.96026600000005],[-113.14862099999999,72.99470500000007],[-113.0627669999999,73.00749200000007],[-113.02806099999998,73.00943000000001],[-113.00695799999994,73.00888100000009],[-112.823059,72.99887100000001],[-112.811394,72.9952550000001],[-112.79472399999997,72.98220800000007],[-112.78582799999998,72.978317],[-112.77139299999993,72.97526600000003],[-112.75418100000002,72.97276300000004],[-112.708618,72.96971100000013],[-112.64362299999993,72.96693400000004],[-112.60082999999986,72.96360799999997],[-112.56360599999994,72.95915200000007],[-112.51500699999991,72.951096],[-112.5,72.94792200000012],[-112.47165699999994,72.94192500000003],[-112.44583099999994,72.93525700000009],[-112.41388699999993,72.92414900000006],[-112.387787,72.91110200000003],[-112.37638900000002,72.907761],[-112.36193800000001,72.90470900000008],[-112.34472700000003,72.90220599999992],[-112.27944899999994,72.89694199999997],[-112.23777799999999,72.89553799999999],[-112.14195299999994,72.89637800000003],[-112.09834299999989,72.89415000000002],[-112.06166099999996,72.88943499999999],[-111.947769,72.87052900000015],[-111.78333299999997,72.83471700000001],[-111.67582699999997,72.81469700000002],[-111.65888999999999,72.8119200000001],[-111.59416199999998,72.80664100000013],[-111.54055799999998,72.7994230000001],[-111.52639799999997,72.79637100000002],[-111.23693799999995,72.72637900000012],[-111.22582999999997,72.7227630000001],[-111.22000100000002,72.71832300000005],[-111.20249899999999,72.67053199999998],[-111.20527599999997,72.66442900000004],[-111.26278699999995,72.57916300000011],[-111.2769469999999,72.56749000000008],[-111.45221699999996,72.47776800000003],[-111.52778599999999,72.44999700000011],[-111.65110800000002,72.40887500000008],[-111.675003,72.40220600000004],[-111.736107,72.39526400000011],[-111.76999699999993,72.3936000000001],[-111.78527799999995,72.39193699999998],[-111.81221,72.38665800000001],[-111.859734,72.37330600000001],[-111.890289,72.36053500000008],[-111.89890299999996,72.355545],[-111.90556299999997,72.349716],[-111.90167200000002,72.34609999999998],[-111.86250299999995,72.33055100000007],[-111.85138699999999,72.32693499999999],[-111.66388699999999,72.27638200000001],[-111.50446299999999,72.31192000000004],[-111.44499200000001,72.3288730000001],[-111.42443799999995,72.33720400000004],[-111.41915899999998,72.34387199999998],[-111.43305999999995,72.34693900000008],[-111.45140100000003,72.34693900000008],[-111.487213,72.33665500000006],[-111.51944700000001,72.33415200000007],[-111.5616609999999,72.33665500000006],[-111.578056,72.33915699999994],[-111.58917200000002,72.342758],[-111.60582699999998,72.35081500000001],[-111.61165599999998,72.36109900000002],[-111.609444,72.36720300000007],[-111.58833299999998,72.37637300000011],[-111.37444299999993,72.44664],[-111.350281,72.45332299999995],[-111.3094329999999,72.46081500000008],[-111.29387700000001,72.46276899999992],[-111.26583899999997,72.46554600000002],[-111.248894,72.466385],[-111.22860699999995,72.46554600000002],[-111.20249899999999,72.46026599999999],[-111.21333300000003,72.44693000000001],[-111.23277299999995,72.4369200000001],[-111.24500299999994,72.43359400000008],[-111.27223200000003,72.42858899999999],[-111.30139200000002,72.40416000000005],[-111.27749599999993,72.36997999999994],[-111.11277799999993,72.3352660000001],[-111.09528399999994,72.37970000000001],[-111.09137699999997,72.4019320000001],[-111.00446299999999,72.46527100000003],[-110.8691639999999,72.47331200000008],[-110.82444799999996,72.4791560000001],[-110.80304699999999,72.48525999999993],[-110.82501200000002,72.50387599999993],[-110.833328,72.51915000000002],[-110.827789,72.52581800000002],[-110.73805199999993,72.56553600000001],[-110.72749299999998,72.56971699999991],[-110.71528599999999,72.57304400000004],[-110.70140100000003,72.57554600000014],[-110.68083199999995,72.57470699999999],[-110.66610700000001,72.57304400000004],[-110.53527799999995,72.54664600000007],[-110.52639799999992,72.52693199999999],[-110.57501199999996,72.51388500000013],[-110.59445199999993,72.50471500000009],[-110.60166899999996,72.49887100000007],[-110.60193600000002,72.4933170000001],[-110.59361299999989,72.48915099999999],[-110.55249000000003,72.47387700000013],[-110.53083800000002,72.46665999999999],[-110.35056299999997,72.42804000000007],[-110.32861299999996,72.42608600000005],[-110.30999799999995,72.42608600000005],[-110.303879,72.43054200000012],[-110.31194299999993,72.43470800000006],[-110.41027799999995,72.4622040000001],[-110.50334199999998,72.48498500000011],[-110.514183,72.488586],[-110.52250700000002,72.49275200000005],[-110.52778599999999,72.4974820000001],[-110.53056299999992,72.50248699999997],[-110.52333099999998,72.508331],[-110.39639299999999,72.55220000000008],[-110.38417099999998,72.555542],[-110.36527999999998,72.555542],[-110.34333800000002,72.55386400000009],[-110.32389799999993,72.55165099999994],[-110.31304899999998,72.54776000000004],[-110.22028399999994,72.51388500000013],[-110.20140100000003,72.50582900000006],[-110.15527299999997,72.48027000000008],[-110.06139399999995,72.43748499999992],[-110.05055199999993,72.43386800000002],[-110.03999299999998,72.43803400000007],[-110.02194199999991,72.44775400000015],[-109.998894,72.45526100000012],[-109.97112300000003,72.46026599999999],[-109.95249899999999,72.45999100000012],[-109.91972399999986,72.45471199999997],[-109.81388900000002,72.428314],[-109.79666099999992,72.4269260000001],[-109.78278399999999,72.42942800000014],[-109.77806099999998,72.43470800000006],[-109.78582799999992,72.43887300000006],[-109.80583199999995,72.44552600000003],[-109.83029199999999,72.45220899999998],[-110.04250300000001,72.50471500000009],[-110.223053,72.5458220000001],[-110.23665599999998,72.54887400000007],[-110.24777199999994,72.55276500000014],[-110.25583599999987,72.55693100000002],[-110.252792,72.56303400000013],[-110.24221799999992,72.56694000000005],[-110.22165699999994,72.56608600000004],[-110.12082699999996,72.56025700000004],[-110.104172,72.55775499999999],[-110.09056099999998,72.55442800000003],[-110.06889299999995,72.54693600000007],[-110.03888699999987,72.53553800000009],[-110.02278099999995,72.52720600000009],[-110.00361599999991,72.51944000000003],[-109.97112300000003,72.508331],[-109.90499899999998,72.48719800000009],[-109.88861099999986,72.484711],[-109.80943300000001,72.4916530000001],[-109.79527300000001,72.49414100000007],[-109.78472899999997,72.49832200000014],[-109.78278399999999,72.50305199999997],[-109.94275700000003,72.60415599999999],[-109.95889299999993,72.61276200000009],[-110.09306300000003,72.65637200000009],[-110.11332699999997,72.65721100000002],[-110.171112,72.64833099999998],[-110.18666100000002,72.64665200000002],[-110.22112299999998,72.64526400000005],[-110.241669,72.64610300000004],[-110.25556899999998,72.64942900000005],[-110.266663,72.65304600000002],[-110.283073,72.66137700000013],[-110.28832999999992,72.66609199999999],[-110.29110700000001,72.67109700000003],[-110.20973200000003,72.71775800000006],[-110.20056199999999,72.7227630000001],[-110.18831599999999,72.72608900000012],[-110.17083699999995,72.72692899999998],[-110.078079,72.72706599999998],[-110.041672,72.72248800000006],[-110.03056300000003,72.71859699999999],[-109.99804699999999,72.70193499999999],[-109.98693800000001,72.69831800000003],[-109.85221899999993,72.66581700000012],[-109.83277899999996,72.66331500000007],[-109.81723,72.66499299999998],[-109.77084399999995,72.71638500000012],[-109.77027900000002,72.72221400000012],[-109.78138699999994,72.72581500000001],[-109.80082700000003,72.72804300000013],[-109.81973299999993,72.72804300000013],[-110.03111299999995,72.74775700000004],[-110.17887899999994,72.76914999999997],[-110.17138699999998,72.77499399999999],[-110.16832699999986,72.7810970000001],[-110.17083699999995,72.78610199999997],[-110.17639199999996,72.790817],[-110.21166999999997,72.81832899999995],[-110.24526999999995,72.82360799999998],[-110.32640099999992,72.82638500000002],[-110.36638599999998,72.82720899999998],[-110.47666899999996,72.83499099999995],[-110.493607,72.83776899999998],[-110.53555299999994,72.84721400000001],[-110.54666099999997,72.85081500000007],[-110.56331599999999,72.85914599999995],[-110.74276699999996,72.95721400000014],[-110.75389099999995,72.96638500000006],[-110.75666799999993,72.97137499999997],[-110.75389099999995,72.97776800000008],[-110.74804699999993,72.98442100000005],[-110.74082900000002,72.98997500000007],[-110.73166700000002,72.99498000000011],[-110.70834400000001,73.00248700000003],[-110.69415300000003,73.00499000000002],[-110.6783289999999,73.00665300000014],[-110.61860699999994,73.01138300000014],[-110.51139799999993,73.01527400000003],[-110.432503,73.0144350000001],[-110.39083899999997,73.01249699999994],[-110.16610700000001,72.99609400000008],[-110.05110199999996,72.98471100000006],[-109.91887700000001,72.96804800000001],[-109.65943899999996,72.92498800000004],[-109.63445299999995,72.91804500000006],[-109.61805700000002,72.90942400000012],[-109.618607,72.90386999999993],[-109.62943999999993,72.89971900000006],[-109.66111799999999,72.89665200000013],[-109.69471699999997,72.89444000000009],[-109.724716,72.89054900000002],[-109.73889200000002,72.88804600000003],[-109.75,72.88388100000003],[-109.75472999999994,72.87858599999998],[-109.74665799999997,72.87442000000004],[-109.65862300000003,72.84471100000002],[-109.379707,72.7705380000001],[-109.22778299999993,72.76165800000007],[-109.05110200000001,72.68026700000007],[-109.02999899999998,72.64721700000001],[-109.04915599999993,72.60415599999999],[-109.045547,72.57249500000012],[-109.04332699999998,72.56749000000008],[-109.02861000000001,72.56553600000001],[-108.88249200000001,72.56442300000015],[-108.86527999999998,72.56498700000009],[-108.85109699999998,72.56749000000008],[-108.84194899999994,72.57249500000012],[-108.81916799999993,72.59109500000005],[-108.722778,72.58276399999994],[-108.70361300000002,72.58027600000014],[-108.67666600000001,72.57388300000002],[-108.64472999999987,72.56248500000004],[-108.62138399999998,72.54998800000004],[-108.61638599999998,72.54525799999999],[-108.58805799999993,72.50555400000007],[-108.589447,72.49443100000008],[-108.59638999999993,72.48220800000001],[-108.60278299999999,72.47554000000002],[-108.61054999999993,72.46998600000006],[-108.62470999999994,72.45748900000007],[-108.63722200000001,72.44442700000002],[-108.64499699999993,72.42665100000005],[-108.65055799999999,72.40359500000005],[-108.66361999999998,72.36276199999998],[-108.66278099999994,72.34637499999997],[-108.65834000000001,72.33610500000003],[-108.52416999999997,72.19970699999999],[-108.45500199999998,72.15721100000013],[-108.44415300000003,72.16110200000003],[-108.42832900000002,72.1583250000001],[-108.41805999999997,72.15443400000004],[-108.404449,72.14694199999991],[-108.40222199999994,72.14166300000011],[-108.39890300000002,72.11360200000007],[-108.39472999999998,72.04275500000011],[-108.39527900000002,72.03692600000011],[-108.396118,72.03137200000009],[-108.31639099999995,71.98414600000007],[-108.20417799999996,71.96388200000013],[-108.19138299999992,71.96054100000009],[-108.18666100000002,71.95582600000006],[-108.18276999999995,71.94552599999992],[-108.18971299999998,71.93331899999998],[-108.19611399999997,71.92692599999998],[-108.233612,71.89971900000006],[-108.28639199999992,71.86080900000013],[-108.28278399999999,71.79220600000002],[-108.28083800000002,71.786926],[-108.24276700000001,71.71859700000005],[-108.23805199999998,71.71388200000001],[-108.23082699999992,71.70942699999995],[-108.22055099999994,71.70582600000012],[-108.20777900000002,71.70248400000014],[-108.19248999999996,71.69970700000005],[-108.17748999999998,71.70109600000006],[-108.14111300000002,71.71054100000015],[-108.13054699999992,71.71443200000004],[-108.10333300000002,71.71914700000008],[-108.08693700000003,71.71971100000002],[-108.066101,71.71775800000006],[-108.03639199999998,71.70582600000012],[-108.02194199999997,71.697205],[-107.98805199999987,71.67553700000008],[-107.97609699999987,71.666382],[-107.96694899999994,71.65693699999997],[-107.96777299999991,71.65138200000007],[-107.91583300000002,71.62498499999998],[-107.84528399999994,71.6038670000001],[-107.82888799999995,71.60443100000003],[-107.75334199999998,71.61026000000004],[-107.74109599999997,71.61331200000012],[-107.73194899999999,71.618042],[-107.72416699999991,71.62387100000001],[-107.72609699999998,71.62914999999998],[-107.74054699999994,71.63749699999994],[-107.75028999999995,71.64137300000004],[-107.77583299999998,71.64804100000003],[-107.82472199999995,71.67275999999998],[-107.83194700000001,71.67692600000004],[-107.83640300000002,71.68165600000009],[-107.83833300000003,71.68692000000004],[-107.83750899999995,71.69247400000006],[-107.82305899999994,71.7169340000001],[-107.81527699999998,71.7227630000001],[-107.80444299999999,71.726654],[-107.78943600000002,71.72804300000001],[-107.7519529999999,71.726654],[-107.73665599999998,71.72360200000008],[-107.63027999999997,71.73220800000001],[-107.49472000000003,71.78637700000002],[-107.451683,71.85748300000006],[-107.36361699999992,71.871918],[-107.34555099999994,71.871643],[-107.29695099999998,71.87414599999994],[-107.28333299999997,71.876373],[-107.27084400000001,71.87942499999997],[-107.26139799999999,71.88415500000013],[-107.25334199999998,71.88970899999998],[-107.25250199999994,71.89553799999999],[-107.25695799999994,71.9002690000001],[-107.264183,71.9044340000001],[-107.41805999999997,71.9538730000001],[-107.59638999999993,72.00443999999999],[-107.61389199999996,72.012497],[-107.62581599999999,72.02165200000002],[-107.63027999999997,72.02638200000007],[-107.65139799999997,72.06109600000013],[-107.653343,72.06637599999999],[-107.64943700000003,72.072495],[-107.63999899999993,72.07720899999998],[-107.62609899999995,72.0794370000001],[-107.61389199999996,72.08276400000005],[-107.61000100000001,72.08859300000006],[-107.61193799999995,72.09387200000003],[-107.63527699999997,72.12191799999994],[-107.68138099999999,72.13610800000004],[-107.699997,72.138596],[-107.729446,72.13720700000005],[-107.74333199999995,72.13499499999995],[-107.76027699999992,72.13443000000012],[-107.77887699999997,72.13665800000007],[-107.78083800000002,72.14193700000004],[-107.787216,72.18470800000011],[-107.77806099999992,72.20803800000004],[-107.843887,72.35415600000005],[-107.87748699999992,72.4244230000001],[-107.88639799999993,72.51971399999996],[-107.87693799999994,72.524429],[-107.87165799999997,72.52970900000008],[-107.87666299999995,72.56721500000003],[-107.88054699999998,72.57748400000008],[-107.88555899999989,72.58665500000001],[-107.91555799999998,72.59721400000006],[-107.92887899999994,72.60054000000008],[-107.99082900000002,72.61248799999998],[-108.00418099999996,72.615814],[-108.01194800000002,72.61998000000011],[-108.025284,72.66609199999999],[-108.02639799999997,72.67692600000004],[-108.02667199999996,72.719986],[-108.05110200000001,72.78137200000015],[-108.05803699999996,72.79109200000005],[-108.11193799999995,72.89082300000013],[-108.1519469999999,72.97110000000009],[-108.16528299999993,73.01081799999997],[-108.26363400000002,73.0919340000001],[-108.29361,73.12025499999999],[-108.29998799999998,73.1355440000001],[-108.295547,73.14749100000006],[-108.291946,73.15359500000005],[-108.28527799999995,73.159988],[-108.26862299999999,73.17137100000002],[-108.23029299999996,73.18748499999998],[-108.18110699999994,73.20166000000006],[-108.16639700000002,73.20387300000004],[-108.13390400000003,73.20694000000015],[-108.11582900000002,73.20748900000007],[-108.07389799999993,73.20526100000012],[-108.02390300000002,73.20109600000012],[-107.93443300000001,73.18748499999998],[-107.91471899999993,73.18498199999999],[-107.89388999999994,73.18386800000002],[-107.87416099999996,73.18359400000008],[-107.86416599999995,73.18858300000005],[-107.87222300000002,73.19274899999994],[-107.90471600000001,73.20416300000005],[-107.94611399999991,73.21415700000006],[-108.01027699999997,73.226089],[-108.05166599999995,73.23609899999991],[-108.08444199999997,73.2474820000001],[-108.11638599999992,73.26443500000005],[-108.15361000000001,73.30247500000013],[-108.08444199999997,73.34999099999999],[-108.07140399999992,73.35331700000006],[-108.05332899999996,73.3538670000001],[-107.99109599999991,73.35137900000012],[-107.94722000000002,73.3483280000001],[-107.77139299999999,73.32388300000002],[-107.675003,73.32331800000003],[-107.631104,73.31999199999996],[-107.614441,73.31721500000009],[-107.403343,73.27053799999999],[-107.33583099999987,73.24803199999997],[-107.24999999999994,73.21748400000001],[-107.21028099999995,73.20166000000006],[-107.18888900000002,73.19413800000012],[-107.172234,73.19108600000004],[-107.10582699999998,73.17942800000003],[-107.06973299999999,73.17387400000001],[-107.05027799999999,73.17359899999997],[-107.03694200000001,73.1766510000001],[-107.025284,73.180542],[-107.016663,73.18609599999996],[-107.01083399999999,73.19136000000015],[-107.02027899999996,73.20082100000013],[-107.05249000000003,73.21249399999994],[-107.09028599999994,73.22303799999997],[-107.11081699999994,73.23136900000009],[-107.11860699999994,73.23553499999997],[-107.12361099999998,73.24026500000002],[-107.11945300000002,73.24636800000013],[-107.03028899999998,73.29553199999998],[-107.01862299999999,73.29942300000005],[-106.88249199999996,73.31219500000003],[-106.86138899999997,73.31080600000001],[-106.76139799999999,73.29304500000006],[-106.75083899999993,73.289154],[-106.74610899999999,73.28442399999994],[-106.74109599999991,73.26887500000004],[-106.72721899999993,73.25471500000015],[-106.69666299999994,73.2374880000001],[-106.66471899999999,73.226089],[-106.65110800000002,73.22248799999994],[-106.63474300000001,73.21971100000007],[-106.60305800000003,73.21666000000005],[-106.58222999999998,73.21527100000003],[-106.39862099999993,73.14915500000006],[-106.24027999999998,73.08581500000008],[-106.06388899999996,73.04775999999998],[-106.04750100000001,73.04470800000001],[-106.028343,73.04443400000008],[-105.94888300000002,73.05331399999994],[-105.91027799999989,73.05886800000013],[-105.87638899999996,73.05831899999998],[-105.85555999999997,73.05693100000008],[-105.84221600000001,73.05358899999999],[-105.83194699999996,73.04971300000011],[-105.82472200000001,73.04525800000005],[-105.82195299999995,73.03498799999994],[-105.82333399999999,73.02943399999998],[-105.83249699999999,73.01721199999997],[-105.82972699999993,73.00694299999998],[-105.82224299999996,73.00248700000003],[-105.80471799999998,72.99443100000013],[-105.79444899999993,72.99026500000008],[-105.76083399999999,72.9769290000001],[-105.737503,72.96943699999997],[-105.697769,72.95915200000007],[-105.67859599999997,72.95637499999998],[-105.62917299999998,72.93997200000013],[-105.56221,72.91304000000002],[-105.445831,72.83831800000007],[-105.32611099999991,72.74636800000007],[-105.32195299999995,72.74165300000004],[-105.32055700000001,72.73664900000006],[-105.32528699999995,72.73054500000006],[-105.33693700000003,72.726654],[-105.35610999999994,72.72720300000009],[-105.37777699999998,72.72943100000003],[-105.39778100000001,72.73719800000003],[-105.41194200000001,72.7458190000001],[-105.41915899999992,72.75027500000004],[-105.42748999999992,72.75972000000007],[-105.43472300000002,72.76416000000012],[-105.46472199999994,72.77581800000013],[-105.47778299999999,72.77943400000004],[-105.49833699999994,72.780823],[-105.51000999999997,72.7769320000001],[-105.45722999999992,72.70277399999998],[-105.44722000000002,72.69886800000006],[-105.38249200000001,72.68136600000003],[-105.35665899999998,72.67442300000005],[-105.29472399999997,72.63192700000002],[-105.23110999999994,72.54332000000005],[-105.19583099999988,72.48248300000006],[-105.19972199999995,72.46054100000015],[-105.20140100000003,72.45471199999997],[-105.20612299999993,72.44886800000012],[-105.21777299999991,72.44497700000005],[-105.23194899999993,72.44720500000005],[-105.26167299999992,72.45887800000003],[-105.27722199999994,72.4622040000001],[-105.29305999999997,72.46081500000008],[-105.301941,72.45526100000012],[-105.29778299999987,72.45054600000009],[-105.241379,72.39971899999995],[-105.23029299999996,72.39054900000008],[-105.21665999999993,72.38192700000008],[-105.18998699999997,72.36970500000012],[-105.16055299999988,72.35775799999999],[-105.13999899999999,72.34471100000013],[-105.04415899999998,72.24803200000002],[-105.03639199999986,72.23858600000005],[-105.03362299999998,72.23471100000006],[-105.02443700000003,72.21998600000012],[-104.99166899999989,72.20332300000001],[-104.95749699999999,72.18136600000014],[-104.95527599999997,72.17109700000015],[-104.95722999999992,72.16554300000013],[-104.96167000000003,72.15942400000012],[-104.96916199999998,72.15304600000013],[-104.97805799999992,72.14749100000006],[-104.98805199999993,72.14276100000001],[-104.99973299999999,72.13888500000013],[-105.02999899999998,72.12469500000003],[-105.03751399999999,72.1183170000001],[-105.03639199999986,72.11303700000002],[-105.01862299999993,72.06693999999993],[-104.92944299999988,72.03414900000001],[-104.87193299999996,71.98997500000007],[-104.82917800000001,71.93719500000003],[-104.82444800000002,71.92747500000013],[-104.82028200000002,71.90664700000008],[-104.82556199999999,71.88970899999998],[-104.82250999999997,71.87414599999994],[-104.8186189999999,71.86914100000007],[-104.78999299999998,71.84137000000004],[-104.78333299999986,71.83692900000011],[-104.771118,71.8336030000001],[-104.70056199999999,71.82998700000002],[-104.68554699999993,71.8269350000001],[-104.67331699999994,71.82331799999997],[-104.66000400000001,71.81442300000009],[-104.53472899999986,71.71971100000002],[-104.37638900000002,71.59803800000003],[-104.36638600000003,71.58888200000013],[-104.35527000000002,71.574432],[-104.35916099999997,71.563309],[-104.36361699999998,71.55720499999995],[-104.37581599999993,71.54470799999996],[-104.383331,71.53831500000001],[-104.40167200000002,71.51443500000005],[-104.40361000000001,71.50860599999999],[-104.401947,71.49832200000014],[-104.34416199999993,71.41081199999996],[-104.33332799999994,71.39637800000014],[-104.35722399999986,71.357483],[-104.37165799999997,71.36080900000002],[-104.38918299999995,71.36360200000001],[-104.40805099999994,71.36499000000009],[-104.43804899999998,71.36276199999998],[-104.45056199999988,71.35971100000012],[-104.46167000000003,71.35582000000005],[-104.47138999999993,71.35108900000012],[-104.48860199999996,71.33998099999997],[-104.49333200000001,71.33415200000013],[-104.49694799999997,71.32276900000011],[-104.49500299999988,71.3124850000001],[-104.49137899999988,71.30748000000006],[-104.46250900000001,71.28109700000005],[-104.44972200000001,71.27221700000001],[-104.43888900000002,71.25776700000011],[-104.43971299999998,71.24693300000001],[-104.44055200000003,71.23609899999997],[-104.44444299999992,71.22499099999999],[-104.44888300000002,71.21887200000015],[-104.470551,71.19970699999999],[-104.49610899999999,71.18304400000011],[-104.52555799999999,71.16886900000003],[-104.55610699999994,71.15554800000007],[-104.57805599999995,71.14804100000009],[-104.59056099999998,71.145264],[-104.62361099999987,71.13360599999999],[-104.64862099999999,71.11914100000007],[-104.60472099999998,71.07971199999997],[-104.58583099999998,71.06666600000005],[-104.57028199999996,71.05831900000004],[-104.53666699999997,71.04414400000013],[-104.48916600000001,71.02470399999999],[-104.45667300000002,71.01361099999997],[-104.33778399999994,70.97970600000008],[-104.23805199999998,70.9649960000001],[-104.22389199999998,70.961929],[-104.122772,70.91470300000015],[-104.11665299999999,70.91026299999993],[-104.09999099999999,70.89137299999999],[-104.07640099999992,70.86303700000008],[-104.05277999999993,70.83442700000006],[-104.04583699999995,70.824997],[-104.04277000000002,70.80415300000004],[-104.02887699999991,70.78498800000006],[-104.01583900000003,70.77082799999994],[-104.00029,70.75721699999997],[-103.99416400000001,70.75277699999998],[-103.98528299999998,70.74887100000007],[-103.97138999999987,70.74552900000015],[-103.95472699999999,70.74275200000005],[-103.94027699999987,70.7416530000001],[-103.92443800000001,70.74192800000009],[-103.806107,70.72303799999997],[-103.73111,70.69164999999992],[-103.64083899999997,70.64665200000002],[-103.63417099999992,70.63720699999999],[-103.62470999999994,70.62803600000001],[-103.59889199999992,70.61581400000006],[-103.55638099999999,70.60081500000001],[-103.52333099999987,70.59304800000001],[-103.506958,70.59027100000014],[-103.49027999999998,70.58749400000005],[-103.473053,70.586929],[-103.44193999999999,70.58720400000004],[-103.39835399999993,70.59054600000013],[-103.34277299999997,70.59664900000007],[-103.3272169999999,70.59664900000007],[-103.30915799999997,70.595261],[-103.26500699999997,70.58166500000004],[-103.239441,70.56944300000004],[-103.20472699999993,70.54803500000014],[-103.14972699999998,70.51388500000002],[-103.13276699999994,70.50582900000012],[-103.12165800000002,70.50193800000005],[-103.095551,70.49803199999997],[-103.01194799999996,70.49220299999996],[-102.97693600000002,70.48997500000002],[-102.96056399999998,70.48915100000005],[-102.93055699999996,70.49054000000007],[-102.92027299999995,70.49498000000006],[-102.91443599999991,70.50000000000011],[-102.915009,70.50526400000007],[-102.91832699999998,70.51026899999994],[-102.92388900000003,70.51443500000005],[-102.93250299999988,70.51860000000005],[-102.95722999999998,70.52554300000003],[-102.97528099999994,70.52720599999998],[-103.03028899999998,70.53498800000011],[-103.05526700000001,70.54193100000009],[-103.0997309999999,70.55664100000007],[-103.108337,70.56053199999991],[-103.12609899999995,70.57388300000008],[-103.13999899999993,70.60942100000011],[-103.15556300000003,70.65498400000001],[-103.156113,70.659988],[-103.15387699999997,70.665817],[-103.14916999999991,70.67164600000001],[-103.13667299999992,70.6744230000001],[-103.12110899999999,70.67469800000009],[-103.104172,70.67387399999996],[-103.08583099999998,70.672485],[-103.06667299999998,70.66998300000006],[-103.0250089999999,70.66026299999999],[-103.00250199999999,70.65277100000009],[-102.85665899999992,70.59776300000004],[-102.84834299999994,70.59387199999998],[-102.84528399999999,70.58888200000013],[-102.83833300000003,70.57415800000007],[-102.83583099999998,70.54803500000014],[-102.74445300000002,70.49470500000007],[-102.61501299999992,70.46054100000003],[-102.60138699999999,70.45721400000008],[-102.52027899999996,70.43830900000012],[-102.45749699999988,70.42637600000012],[-102.40862299999998,70.41747999999995],[-102.333328,70.39776600000005],[-102.281387,70.38415500000008],[-102.11749299999997,70.33943200000004],[-101.99610899999988,70.2872010000001],[-101.97972099999998,70.27916000000005],[-101.92555199999998,70.26054400000004],[-101.89334099999996,70.25443999999999],[-101.87666300000001,70.25360100000006],[-101.86138899999997,70.25387600000005],[-101.84916699999985,70.25665300000014],[-101.83805799999993,70.260269],[-101.828056,70.26470900000004],[-101.82195299999995,70.26971400000008],[-101.81722999999988,70.2810970000001],[-101.81749699999995,70.28610200000014],[-101.80972300000002,70.29775999999998],[-101.79972800000002,70.30219999999997],[-101.714722,70.30886800000013],[-101.69803599999995,70.30802900000003],[-101.68195300000002,70.30497700000006],[-101.59944200000001,70.27581800000013],[-101.58860800000002,70.27192700000006],[-101.58029199999993,70.26776100000012],[-101.58029199999993,70.26277199999998],[-101.58556399999998,70.25665300000014],[-101.60555999999997,70.24775700000004],[-101.63417099999998,70.23304700000006],[-101.64306599999998,70.22776800000008],[-101.65083300000003,70.22137499999997],[-101.65055799999993,70.21081500000003],[-101.64222699999993,70.19636500000007],[-101.62249799999995,70.16249100000005],[-101.61416599999995,70.15304600000002],[-101.55999800000001,70.11360200000007],[-101.55194099999994,70.109421],[-101.53971899999999,70.10693400000014],[-101.52667200000002,70.10859700000003],[-101.39723200000003,70.13943500000005],[-101.39222699999999,70.15054300000003],[-101.37581599999999,70.17776500000014],[-101.358047,70.17608600000011],[-101.28666699999991,70.15248099999997],[-101.265289,70.14498900000001],[-101.25723299999999,70.14082300000013],[-101.25195300000001,70.13638300000008],[-101.23889200000002,70.13304099999999],[-101.22222899999991,70.13192700000002],[-101.14499699999999,70.15525800000006],[-101.13500999999997,70.15971399999995],[-101.12721299999998,70.1660920000001],[-101.12193300000001,70.17192100000011],[-101.11665299999993,70.18304400000011],[-101.12193300000001,70.19274900000005],[-101.11193800000001,70.19720500000011],[-101.09555099999994,70.19636500000007],[-101.03971899999999,70.18304400000011],[-100.99973299999999,70.1727600000001],[-100.98388699999992,70.16470300000015],[-100.97332799999998,70.15554800000007],[-100.97332799999998,70.14526400000005],[-100.97609699999992,70.13443000000001],[-100.96028099999995,70.05304000000007],[-100.92194399999988,69.96527100000014],[-100.88694800000002,69.88415500000002],[-100.870003,69.81442300000015],[-100.870003,69.78831500000001],[-100.87805200000003,69.77165200000013],[-100.89998600000001,69.75387599999999],[-100.92555199999998,69.72110000000004],[-100.92027300000001,69.71138000000013],[-100.92027300000001,69.70109600000012],[-100.92832899999996,69.684143],[-100.93859900000001,69.672485],[-100.94748699999997,69.66693099999998],[-100.95722999999992,69.66249099999999],[-100.96916199999998,69.65971400000006],[-101.06443799999994,69.64860499999998],[-101.28362300000003,69.66387900000007],[-101.31777999999991,69.66748000000013],[-101.32972699999988,69.66998300000012],[-101.34028599999999,69.67886400000003],[-101.43831599999993,69.76971400000002],[-101.45472699999993,69.79887400000007],[-101.46806299999997,69.8230440000001],[-101.47332799999998,69.832764],[-101.468613,69.83888200000007],[-101.458618,69.843323],[-101.43998699999997,69.853317],[-101.43472300000002,69.85914600000007],[-101.41610700000001,69.88693200000012],[-101.41860999999989,69.89193699999998],[-101.42944299999994,69.90609700000005],[-101.44526699999994,69.90914900000001],[-101.45638999999994,69.90554800000012],[-101.46888699999994,69.89305100000013],[-101.47917199999995,69.88136299999991],[-101.51972999999992,69.82832300000007],[-101.53999299999998,69.79942299999999],[-101.54750100000001,69.78776600000009],[-101.55972299999996,69.76499899999999],[-101.56221,69.754166],[-101.56194299999999,69.74914600000011],[-101.564438,69.7433170000001],[-101.569458,69.7374880000001],[-101.60777300000001,69.70582599999994],[-101.65249599999999,69.6827550000001],[-101.69193999999999,69.68026700000013],[-101.69722000000002,69.68470800000006],[-101.75805699999995,69.71775800000012],[-101.76611300000002,69.721924],[-101.77916700000003,69.72526600000015],[-101.85637700000001,69.74304200000012],[-101.87000299999994,69.74414100000007],[-101.88722200000001,69.73332199999999],[-101.89916999999997,69.73054500000012],[-101.91416900000002,69.73054500000012],[-101.92999299999997,69.73359700000003],[-101.94055200000003,69.73719800000009],[-101.94860799999998,69.74136399999998],[-101.962784,69.75305200000003],[-102.02306399999992,69.81776400000001],[-102.06555199999997,69.85054000000014],[-102.20667300000002,69.91304000000008],[-102.21749899999998,69.91693099999998],[-102.23029300000002,69.91720599999996],[-102.24082900000002,69.91331500000007],[-102.37581599999999,69.80941800000011],[-102.51027699999992,69.75804099999999],[-102.57640100000003,69.7374880000001],[-102.59249899999998,69.73831200000006],[-102.60582699999998,69.7416530000001],[-102.61638600000003,69.74525500000004],[-102.64890300000002,69.76165800000012],[-102.65972899999997,69.76527399999998],[-102.673317,69.76638800000012],[-102.68055700000002,69.759995],[-102.67443800000001,69.7502750000001],[-102.65805099999994,69.73692300000005],[-102.60028099999994,69.69802900000002],[-102.59221600000001,69.69386299999991],[-102.57640100000003,69.69108600000004],[-102.55943299999996,69.68942300000009],[-102.53138699999994,69.69136000000015],[-102.52084400000001,69.69525100000004],[-102.50917099999998,69.69802900000002],[-102.49194299999994,69.69636500000001],[-102.48361199999988,69.69220000000001],[-102.47805800000003,69.68248000000011],[-102.49777199999988,69.595261],[-102.50778199999996,69.56414799999999],[-102.51500699999985,69.5599820000001],[-102.525284,69.55636600000003],[-102.60305800000003,69.53831500000007],[-102.81304899999986,69.52970900000014],[-102.82861300000002,69.53276100000005],[-102.94387799999993,69.559418],[-103.08528099999995,69.59721400000012],[-103.18666099999996,69.62942500000003],[-103.20556599999998,69.636932],[-103.22471599999994,69.64471400000014],[-103.23277300000001,69.64860499999998],[-103.260559,69.66554300000007],[-103.27166699999998,69.6744230000001],[-103.32195300000001,69.69220000000001],[-103.41639699999996,69.7063750000001],[-103.43055699999996,69.70526100000012],[-103.47693600000002,69.69358800000009],[-103.48665599999998,69.68470800000006],[-103.50723299999999,69.617752],[-103.5041809999999,69.61303699999996],[-103.33528100000001,69.57499700000005],[-103.08917200000002,69.521927],[-103.07528699999995,69.52304100000015],[-103.05695300000002,69.52053799999999],[-103.04638699999998,69.51693699999998],[-103.03806299999997,69.51277199999998],[-103.03278399999999,69.50833100000006],[-103.02333099999998,69.49386600000008],[-103.01390099999998,69.474152],[-102.991379,69.42469800000003],[-102.99082899999996,69.41943400000002],[-103.00778199999996,69.32693500000005],[-103.01917300000002,69.28276100000011],[-103.02306399999998,69.27165200000002],[-103.04444899999999,69.25248700000009],[-103.07195299999995,69.23858600000011],[-103.11332700000003,69.22360200000003],[-103.12444299999999,69.2208250000001],[-103.16000399999996,69.21304299999997],[-103.17250099999995,69.21138000000008],[-103.19415299999997,69.20471200000009],[-103.204453,69.20082100000002],[-103.21140299999996,69.19442700000013],[-103.214447,69.18969700000014],[-103.21777299999997,69.1372070000001],[-103.208618,69.12275699999998],[-103.20305599999989,69.11831699999999],[-103.19499199999996,69.1144260000001],[-103.18222000000003,69.11109899999997],[-103.141953,69.15776100000005],[-103.13390400000003,69.16331500000007],[-103.12444299999999,69.16775500000006],[-103.10500300000001,69.176086],[-103.07417299999997,69.18748500000004],[-103.03721599999994,69.20582600000006],[-103.021118,69.21693400000004],[-103.00611900000001,69.2285920000001],[-102.9988939999999,69.23498500000005],[-102.98082699999992,69.25915500000008],[-102.96916199999993,69.27137800000008],[-102.95056199999999,69.29026800000008],[-102.943604,69.29664600000001],[-102.87249799999995,69.36053500000014],[-102.84084299999995,69.383331],[-102.829453,69.38610800000004],[-102.817497,69.38388100000003],[-102.80666400000001,69.37997400000006],[-102.79360999999994,69.37692300000003],[-102.76083399999993,69.37442000000004],[-102.74694799999997,69.37553400000002],[-102.72277799999995,69.38026400000007],[-102.51083399999999,69.43969700000008],[-102.508621,69.44552600000009],[-102.48972300000003,69.46943699999997],[-102.47193900000002,69.47943099999998],[-102.46028100000001,69.48220800000007],[-102.31304899999998,69.49832200000003],[-102.29804999999999,69.49859600000013],[-102.09306300000003,69.48776200000009],[-102.05750299999988,69.48359700000009],[-102.04750100000001,69.47998000000013],[-101.95527599999997,69.43553200000008],[-101.94748699999997,69.43136599999997],[-101.93694299999999,69.42248500000005],[-101.93138099999999,69.41276600000003],[-101.93110699999994,69.407486],[-101.93611099999998,69.401657],[-102.03527799999995,69.28720099999998],[-102.14890300000002,69.27026400000011],[-102.15943899999996,69.27388000000002],[-102.18776700000001,69.28027299999997],[-102.20140100000003,69.27916000000005],[-102.21278399999994,69.27638200000007],[-102.22972099999993,69.26554900000008],[-102.23194899999999,69.25972000000007],[-102.21721600000001,69.22526600000003],[-102.11972000000003,69.18304399999994],[-102.10665899999992,69.17970300000013],[-102.09361299999989,69.17858899999993],[-102.08112299999993,69.18026700000007],[-102.07167099999992,69.1849820000001],[-102.06416300000001,69.19136000000003],[-102.05943299999996,69.19720499999994],[-102.05721999999992,69.20277399999998],[-102.05750299999988,69.2080380000001],[-102.05444299999999,69.21443199999999],[-102.04499800000002,69.22608900000012],[-102.03666699999997,69.23165899999998],[-102.016663,69.23997500000007],[-102.00611899999996,69.24359099999998],[-101.96305799999999,69.25721699999991],[-101.95140099999998,69.25999500000012],[-101.9385989999999,69.26193199999994],[-101.92194399999994,69.26026900000005],[-101.78500399999996,69.19636500000007],[-101.77055399999995,69.18914799999999],[-101.75472999999994,69.17581200000006],[-101.75195300000001,69.16554300000001],[-101.75167799999991,69.16053799999997],[-101.75389099999995,69.14971900000006],[-101.80638099999999,69.0038760000001],[-101.80860899999993,68.99803199999991],[-101.81806899999992,68.99359100000004],[-101.85138699999993,68.98442099999994],[-101.89916999999997,68.97526600000009],[-101.94888300000002,68.96775800000006],[-101.962784,68.96665999999999],[-101.97693600000002,68.96665999999999],[-101.993607,68.96832300000011],[-102.00140399999992,68.97248800000011],[-102.02223200000003,68.99026500000014],[-102.03250100000002,68.99414100000007],[-102.04778299999998,68.99693300000013],[-102.06220999999994,68.99693300000013],[-102.09665699999994,68.98858599999994],[-102.11305199999998,68.97776799999997],[-102.12609900000001,68.966385],[-102.130829,68.96026599999993],[-102.14502699999997,68.94766199999998],[-102.15638699999994,68.94470200000006],[-102.16972399999997,68.94609100000002],[-102.323624,68.93719500000009],[-102.38612399999994,68.92553700000008],[-102.38583399999993,68.9202580000001],[-102.39028899999994,68.9144290000001],[-102.39835399999987,68.90887500000008],[-102.48554999999999,68.87136800000002],[-102.53582799999998,68.86442599999992],[-102.589722,68.86053500000008],[-102.604172,68.86026000000004],[-102.61972000000003,68.86109900000002],[-102.63500999999991,68.86387600000012],[-102.64527900000002,68.867752],[-102.76306199999999,68.87776200000008],[-102.81889299999995,68.83415200000007],[-102.89472999999992,68.79998800000004],[-102.99054699999999,68.79443400000008],[-103.00583599999999,68.79525800000005],[-103.047234,68.80970799999994],[-103.146118,68.84054600000013],[-103.16416899999996,68.84304800000001],[-103.19499199999996,68.84443700000003],[-103.208618,68.84359699999999],[-103.32084699999996,68.82971200000009],[-103.34111000000001,68.82222000000013],[-103.36000099999995,68.81387299999994],[-103.36805700000002,68.80831899999998],[-103.40306099999992,68.77720599999998],[-103.50917099999987,68.80137599999995],[-103.83583099999993,68.83638000000002],[-104.09472699999992,68.85664400000002],[-104.11028299999998,68.85942100000005],[-104.13834399999996,68.86554000000012],[-104.287781,68.9019320000001],[-104.40249599999999,68.9310910000001],[-104.43083199999995,68.9369200000001],[-104.445267,68.938873],[-104.45749699999999,68.936646],[-104.46167000000003,68.93054200000012],[-104.46305799999988,68.92498799999993],[-104.46250900000001,68.91970800000007],[-104.47444199999995,68.90165700000006],[-104.487503,68.88888500000007],[-104.50279199999989,68.87776200000008],[-104.51167299999992,68.87303200000002],[-104.52139299999999,68.86914099999996],[-104.54360999999989,68.86331199999995],[-104.583618,68.85971100000012],[-104.84999099999993,68.87025499999999],[-105.12917299999998,68.89637800000008],[-105.14472999999992,68.89915500000001],[-105.16610699999995,68.9060970000001],[-105.193329,68.91748000000013],[-105.2488939999999,68.94552600000003],[-105.18305999999995,68.98831200000001],[-105.173317,68.99192800000009],[-105.14666699999998,68.99247700000001],[-105.128601,68.98997500000013],[-105.06471299999998,68.98692300000005],[-105.03916900000002,68.99026500000014],[-104.936394,69.03054800000001],[-104.928879,69.03610200000003],[-104.91610700000001,69.04887400000001],[-104.91166699999991,69.06581100000005],[-104.915009,69.07054100000005],[-104.92304999999999,69.07470699999999],[-104.93388399999998,69.07832300000001],[-105.06500199999999,69.10415599999999],[-105.083328,69.10636900000009],[-105.096657,69.10525500000011],[-105.122772,69.09109500000005],[-105.16027799999995,69.07193000000007],[-105.47361799999999,69.10693400000014],[-105.48055999999997,69.11665299999993],[-105.49249299999991,69.12525900000003],[-105.50695799999994,69.13360600000004],[-105.51528899999994,69.13749700000011],[-105.553879,69.15248099999997],[-105.58056599999998,69.15637200000003],[-105.61694299999994,69.16081200000008],[-105.76806599999998,69.17137100000014],[-105.83029199999999,69.172211],[-105.87416100000002,69.17109700000003],[-105.902222,69.16914400000007],[-105.91443600000002,69.16720599999996],[-105.92555199999998,69.164154],[-106.03888699999993,69.15386999999998],[-106.17777999999998,69.14415000000008],[-106.193604,69.14471400000002],[-106.256958,69.15498400000013],[-106.28888699999999,69.16026299999993],[-106.39611799999994,69.17804000000001],[-106.40611299999995,69.18054200000006],[-106.41471899999999,69.18441799999994],[-106.41471899999999,69.1952510000001],[-106.41027799999995,69.217758],[-106.40666199999998,69.22387700000007],[-106.3944469999999,69.23692299999999],[-106.38612399999994,69.24165300000004],[-106.37638899999996,69.24552900000009],[-106.30777,69.26220699999999],[-106.28832999999992,69.26998900000012],[-106.27362099999993,69.28137200000015],[-106.26777600000003,69.29220600000002],[-106.26889,69.29721100000006],[-106.31639100000001,69.38665800000007],[-106.49527,69.47442600000011],[-106.52139299999993,69.48609899999997],[-106.54138199999989,69.49331699999999],[-106.55499299999985,69.49636800000002],[-106.57112099999989,69.49887099999995],[-106.60221899999999,69.49887099999995],[-106.61444099999994,69.496643],[-106.62554899999986,69.4935910000001],[-106.73306299999996,69.44165000000004],[-106.74027999999998,69.43580600000001],[-106.74388099999993,69.42970300000007],[-106.74553700000001,69.407761],[-106.86277799999999,69.36914100000007],[-106.93083200000001,69.36164900000011],[-106.95500199999992,69.35720800000001],[-106.96611000000001,69.3541560000001],[-106.98554999999999,69.34610000000004],[-106.99249299999997,69.34054600000002],[-106.99722300000002,69.33526599999999],[-106.99833699999999,69.32971199999997],[-106.99694799999997,69.32443200000006],[-106.96528599999994,69.30304000000007],[-106.95749699999993,69.29332],[-106.925003,69.23942599999998],[-106.92223399999995,69.2288670000001],[-106.929169,69.2166600000001],[-106.93611099999998,69.21110500000003],[-106.94444299999998,69.20637500000004],[-106.96362299999993,69.19831800000003],[-107.03999299999998,69.18109100000004],[-107.12832600000002,69.1544340000001],[-107.13806199999999,69.15054300000003],[-107.16221599999994,69.13443000000001],[-107.19167299999998,69.11248799999993],[-107.22666900000002,69.08415200000002],[-107.248894,69.06805400000002],[-107.264183,69.05748000000011],[-107.27944899999994,69.04693600000007],[-107.304169,69.03248599999995],[-107.31360599999994,69.02859500000011],[-107.34221599999995,69.01887499999998],[-107.37444299999993,69.00943000000012],[-107.43167099999994,68.99636800000007],[-107.50334199999992,68.98275800000005],[-107.55387899999994,68.97554000000002],[-107.64611799999989,68.96554600000002],[-107.67388900000003,68.96360800000008],[-107.74610899999999,68.96081500000008],[-107.93749999999994,68.93498199999993],[-107.95584099999996,68.9310460000001],[-107.97693600000002,68.93054200000012],[-108.17555199999998,68.9310910000001],[-108.20944199999997,68.93331900000004],[-108.26444999999995,68.93914800000005],[-108.29833999999988,68.94136000000009],[-108.42804699999994,68.94581600000004],[-108.49221799999992,68.94747899999993],[-108.521118,68.94636500000013],[-108.53443900000002,68.94470200000006],[-108.54611199999994,68.94247400000006],[-108.56331599999993,68.93359400000003],[-108.56388900000002,68.92776500000002],[-108.55082699999997,68.91943400000014],[-108.54194599999994,68.91554300000007],[-108.535553,68.91137699999996],[-108.531387,68.90664700000013],[-108.52971599999995,68.90138200000007],[-108.53028899999993,68.89582800000005],[-108.535553,68.88916000000006],[-108.55139200000002,68.87942500000003],[-108.59722899999997,68.85914600000007],[-108.67443799999995,68.82943700000004],[-108.926941,68.74443100000013],[-108.93749999999994,68.74108899999999],[-108.97250400000001,68.73387099999997],[-109.10472099999998,68.71054100000003],[-109.19138299999992,68.69720500000005],[-109.23416099999997,68.69497700000011],[-109.26390099999998,68.69442700000008],[-109.31194299999999,68.6958160000001],[-109.345551,68.69775400000003],[-109.37416100000002,68.69636500000001],[-109.39998600000001,68.69331399999999],[-109.43472300000002,68.68609599999996],[-109.49137899999994,68.67330899999996],[-109.52306399999992,68.6649930000001],[-109.55359599999991,68.655258],[-109.59722899999997,68.64387499999998],[-109.64362299999999,68.63443000000012],[-109.65638699999994,68.6327510000001],[-109.68331899999998,68.63053900000006],[-109.756958,68.6285860000001],[-109.97028399999999,68.62719700000008],[-110.12416099999996,68.62719700000008],[-110.16055299999994,68.63053900000006],[-110.19167299999998,68.63081400000004],[-110.22000099999997,68.62915000000004],[-110.24416400000001,68.62525900000014],[-110.26306199999999,68.61775200000005],[-110.27194199999997,68.61360200000001],[-110.27916700000003,68.60859700000015],[-110.295547,68.59942600000005],[-110.32917800000001,68.58221400000002],[-110.33917200000002,68.57887299999999],[-110.35082999999997,68.57638500000002],[-110.36361699999998,68.57470700000005],[-110.37777699999998,68.57415800000012],[-110.391388,68.57666],[-110.39806399999986,68.58082600000012],[-110.42027299999995,68.60415600000005],[-110.42722300000003,68.60832199999999],[-110.44082600000002,68.61109900000008],[-110.45889299999999,68.61276199999998],[-110.56111099999998,68.61665300000004],[-110.576683,68.61665300000004],[-110.5894469999999,68.61499000000015],[-110.60944399999994,68.60832199999999],[-110.61694299999994,68.6035920000001],[-110.63417099999987,68.59526100000005],[-110.65695199999999,68.59027100000014],[-110.68138099999999,68.58610500000009],[-110.89666699999998,68.55720500000001],[-110.92223399999995,68.55386399999998],[-110.950287,68.55192600000004],[-111.01363400000002,68.55276500000002],[-111.03195199999999,68.55442800000014],[-111.03859699999992,68.55859400000003],[-111.03500400000001,68.563873],[-110.98332199999993,68.57777399999998],[-110.97193900000002,68.58027600000008],[-110.95777900000002,68.58110000000005],[-110.92555199999993,68.58027600000008],[-110.89723200000003,68.58194000000009],[-110.87165800000002,68.5852660000001],[-110.86028299999987,68.5877690000001],[-110.850281,68.59109500000011],[-110.84306299999997,68.59609999999998],[-110.84306299999997,68.601654],[-110.84973099999996,68.60582000000005],[-110.86361699999992,68.60859700000015],[-111.01750199999998,68.59832799999998],[-111.03028899999998,68.59664900000013],[-111.05888399999998,68.58581500000008],[-111.068893,68.58248900000001],[-111.08029199999999,68.57998700000013],[-111.09306300000003,68.57832300000013],[-111.13527699999997,68.57582100000008],[-111.16639700000002,68.57582100000008],[-111.23249800000002,68.57804900000002],[-111.26750199999998,68.58055100000007],[-111.28362299999998,68.58276400000005],[-111.32000700000003,68.58581500000008],[-111.33693699999998,68.58665500000012],[-111.37917299999998,68.58415200000013],[-111.39195299999994,68.58248900000001],[-111.41166699999997,68.57554600000003],[-111.41665599999999,68.57110600000004],[-111.40527299999997,68.56805400000007],[-111.389183,68.56581099999994],[-111.29804999999999,68.55775500000004],[-111.2502899999999,68.55720500000001],[-111.23194899999999,68.55554200000012],[-111.21833800000002,68.55276500000002],[-111.20916699999998,68.54914899999994],[-111.204453,68.54470800000007],[-111.204453,68.53887900000001],[-111.21112099999999,68.52609300000012],[-111.21556099999992,68.51944000000015],[-111.22556299999997,68.516098],[-111.23805199999993,68.5144350000001],[-111.25361599999991,68.5144350000001],[-111.358612,68.52165200000002],[-111.37471,68.52360499999998],[-111.38834400000002,68.52638200000007],[-111.46806300000003,68.53692600000011],[-111.52278100000001,68.5416560000001],[-111.60056299999991,68.54359400000004],[-111.85109699999998,68.53414900000001],[-112.060272,68.52304100000003],[-112.21000700000002,68.51361099999997],[-112.23665599999987,68.51081799999997],[-112.35916099999997,68.50193800000011],[-112.40110799999997,68.499146],[-112.50917099999992,68.49803200000002],[-112.63527699999992,68.48304700000006],[-112.63694800000002,68.47692899999993],[-112.64527900000002,68.47276300000004],[-112.67027299999995,68.46914699999996],[-112.72749299999992,68.46582000000006],[-112.77390299999996,68.46554600000013],[-112.80750299999994,68.4666600000001],[-113.05166600000001,68.46415700000011],[-113.091949,68.46026600000005],[-113.220551,68.45277400000009],[-113.25140399999992,68.4522090000001],[-113.26944699999996,68.4538730000001],[-113.297234,68.45860299999993],[-113.30444299999999,68.46276900000004],[-113.30943300000001,68.46720900000003],[-113.310272,68.47303800000003],[-113.30638099999993,68.47970600000002],[-113.29972800000002,68.48471100000006],[-113.29138199999994,68.4891510000001],[-113.26944699999996,68.49443099999996],[-113.256958,68.49609400000008],[-113.193604,68.49636800000002],[-113.05166600000001,68.48748799999998],[-113.03778099999994,68.48831200000012],[-113.03388999999999,68.49498000000011],[-113.04360999999994,68.50416600000005],[-113.07250999999991,68.52053800000004],[-113.11805700000002,68.54443400000014],[-113.141388,68.55053700000008],[-113.19721999999996,68.56025699999998],[-113.21333300000003,68.56219500000009],[-113.26888999999994,68.57222000000002],[-113.33416699999998,68.58554100000015],[-113.35777299999995,68.59136999999998],[-113.36721799999992,68.594986],[-113.38166799999988,68.60304300000001],[-113.44304699999998,68.64054899999996],[-113.44833399999999,68.645264],[-113.45111099999997,68.65026900000004],[-113.45249899999999,68.66165200000006],[-113.45084400000002,68.667755],[-113.52443700000003,68.72499099999993],[-113.66665599999999,68.80219999999991],[-113.676941,68.81109600000008],[-113.67887899999994,68.89471400000008],[-113.67722299999997,68.90081800000013],[-113.671944,68.90664700000013],[-113.623894,68.93331900000004],[-113.60694899999993,68.94247400000006],[-113.58444199999997,68.94802899999996],[-113.57472199999995,68.95138500000002],[-113.569458,68.95721400000002],[-113.545837,69.043045],[-113.54499799999996,69.04803500000008],[-113.55471799999987,69.05137600000012],[-113.61501299999998,69.06637600000005],[-113.63221699999997,69.07388300000002],[-113.64723199999992,69.08194000000015],[-113.65778399999999,69.09109500000005],[-113.69611399999991,69.15470900000014],[-113.69220699999994,69.18942300000003],[-113.68083200000001,69.19192500000008],[-113.66583300000002,69.1910860000001],[-113.65583800000002,69.18748500000004],[-113.62193300000001,69.17804000000001],[-113.53888699999999,69.16859400000004],[-113.51972999999998,69.16720599999996],[-113.50862099999995,69.16970800000001],[-113.51363399999997,69.17442300000005],[-113.52111799999994,69.17858899999993],[-113.55359599999991,69.18719500000003],[-113.58000199999992,69.192474],[-113.62332200000003,69.19970700000005],[-113.90888999999999,69.24192800000003],[-114.27555799999999,69.28193699999997],[-114.311394,69.284988],[-114.328888,69.28553800000003],[-114.39277600000003,69.28414900000001],[-114.42138699999998,69.28193699999997],[-114.4472199999999,69.27804600000007],[-114.49249299999991,69.26721200000003],[-114.51834100000002,69.26332100000013],[-114.66972399999997,69.255829],[-114.764183,69.25221299999998],[-115.08889799999992,69.24470500000012],[-115.25361599999991,69.24525499999999],[-115.40083299999998,69.25694299999998],[-115.64472999999998,69.27331500000014],[-115.79527299999995,69.28276100000011],[-115.92138699999992,69.29026800000008],[-115.95584099999996,69.29220600000002],[-115.96833799999996,69.29498300000012],[-115.9786069999999,69.29859899999997],[-115.98665599999998,69.30247500000002],[-116.00029,69.31080600000013],[-116.00611900000001,69.31526200000002],[-116.016953,69.32222000000002],[-116.026947,69.32554600000009],[-116.05638099999999,69.32998699999996],[-116.17527799999993,69.34165999999999],[-116.21945199999999,69.34832799999998],[-116.52583300000003,69.407486],[-116.53859699999998,69.4102630000001],[-116.54888900000003,69.41360500000002],[-116.56527699999992,69.42137100000008],[-116.62970699999994,69.45887800000014],[-116.63137799999993,69.46470600000004],[-116.6266629999999,69.47053500000004],[-116.61888099999993,69.47499099999999],[-116.60777300000001,69.47804300000007],[-116.569458,69.48414600000001],[-116.561394,69.48858600000005],[-116.55860899999993,69.4952550000001],[-116.57556199999993,69.5558170000001],[-116.58138999999989,69.56053199999997],[-116.591949,69.563873],[-116.60472099999993,69.566666],[-116.63667299999997,69.57026700000006],[-116.73388699999998,69.57554600000003],[-116.74999999999994,69.57499700000005],[-116.75945299999995,69.57138100000003],[-116.76611299999996,69.56517799999995],[-116.78138699999988,69.55720500000001],[-116.89750700000002,69.58749400000005],[-116.88054699999986,69.60887100000008],[-116.85193600000002,69.61970500000012],[-116.84612299999998,69.64305100000001],[-116.84750399999996,69.64860499999998],[-116.858047,69.6519320000001],[-116.96193700000003,69.67942799999997],[-116.987503,69.68498199999999],[-117.01777600000003,69.68942300000009],[-117.03500399999996,69.690811],[-117.05027799999993,69.69303899999994],[-117.07584400000002,69.69859300000013],[-117.11805699999996,69.71165499999995],[-117.23889200000002,69.75305200000003],[-117.24749799999995,69.75694300000009],[-117.26917300000002,69.78166200000004],[-117.27278100000001,69.79275500000006],[-117.30777,69.84443699999997],[-117.36721799999992,69.91998300000006],[-117.42250099999995,69.97248800000006],[-117.43499799999995,69.98136900000003],[-117.43666099999996,69.98692299999999],[-117.43611099999993,69.99304200000006],[-117.41528299999993,70.00999500000012],[-117.38527699999997,70.02859500000005],[-117.35637700000001,70.03970300000003],[-117.32584400000002,70.04998799999998],[-117.28362300000003,70.06330900000012],[-117.25140399999992,70.072769],[-117.23999000000003,70.07582100000013],[-117.19444299999998,70.08749399999994],[-117.16999800000002,70.09248400000001],[-117.12082700000002,70.10247800000002],[-117.08167999999995,70.10887100000014],[-117.01083399999993,70.11692800000014],[-116.87721299999998,70.1291500000001],[-116.58306899999997,70.15693700000008],[-116.236107,70.19136000000003],[-116.16639700000002,70.19999700000005],[-116.09999099999999,70.21026600000005],[-116.07167099999998,70.21360800000002],[-115.90834000000001,70.2288670000001],[-115.80194099999994,70.23664900000006],[-115.69360399999994,70.24386600000014],[-115.64695699999993,70.24664300000006],[-115.49665799999997,70.25054900000009],[-115.44833399999993,70.25248700000003],[-115.31471299999998,70.26416000000006],[-115.30139200000002,70.26638800000006],[-115.229446,70.27387999999996],[-115.16750299999995,70.27777100000003],[-115.08389299999999,70.27970899999997],[-115.03028899999998,70.27998400000001],[-114.86721799999998,70.28387500000008],[-114.80194099999989,70.28610200000014],[-114.741379,70.290817],[-114.71305799999988,70.29386900000009],[-114.65888999999999,70.30165100000005],[-114.61694299999994,70.30664100000007],[-114.58833299999992,70.309708],[-114.54305999999997,70.31330900000006],[-114.511124,70.31469699999997],[-114.323624,70.316666],[-114.254997,70.31721500000015],[-114.21833800000002,70.31608599999998],[-114.17832900000002,70.31359900000007],[-114.16082799999998,70.31164599999994],[-114.13527699999997,70.30581699999993],[-114.111107,70.29386900000009],[-114.09028599999994,70.28692600000011],[-114.057503,70.28248600000006],[-113.84166700000003,70.26944000000015],[-113.68388399999992,70.26304600000009],[-113.65055799999993,70.26361099999997],[-113.59166700000003,70.2686000000001],[-113.54943799999995,70.27331500000014],[-113.50556899999998,70.27748100000002],[-113.46000700000002,70.28054800000012],[-113.42804699999999,70.2816620000001],[-113.39138799999995,70.28054800000012],[-113.33332799999994,70.27720600000004],[-113.296112,70.27387999999996],[-113.16832699999998,70.25915500000002],[-113.09084299999995,70.24748199999999],[-112.66665599999993,70.2038730000001],[-112.56471299999998,70.19831800000003],[-112.54804999999999,70.19859300000002],[-112.53278399999994,70.19941699999998],[-112.52084399999995,70.2022090000001],[-112.51722699999999,70.20748899999995],[-112.52749599999993,70.21110500000003],[-112.56304899999998,70.21360800000002],[-112.577789,70.21609500000005],[-112.58084100000002,70.22137499999997],[-112.57501200000002,70.22720300000009],[-112.56582599999996,70.23136899999997],[-112.55526700000001,70.234985],[-112.54332699999992,70.23748799999998],[-112.295547,70.26666300000005],[-112.212784,70.26582300000001],[-112.195831,70.26582300000001],[-112.16388699999999,70.26693699999998],[-112.13834399999996,70.27137800000008],[-112.14584400000001,70.27554300000008],[-112.16306299999991,70.27748100000002],[-112.24249299999991,70.28360000000004],[-112.29695099999998,70.28915400000005],[-112.30471799999992,70.29331999999994],[-112.29723399999995,70.29832500000003],[-112.28333299999997,70.2999880000001],[-112.266663,70.30026200000003],[-112.24833699999999,70.2994230000001],[-112.23111,70.29748499999994],[-112.10888699999992,70.27748100000002],[-111.92639199999996,70.25221299999993],[-111.91583300000002,70.25555399999996],[-111.90805099999989,70.26054400000004],[-111.89917000000003,70.26470900000004],[-111.88054699999998,70.27026400000011],[-111.86527999999993,70.27137800000008],[-111.84861799999993,70.27137800000008],[-111.743607,70.26944000000015],[-111.55555700000002,70.26971400000008],[-111.53888699999993,70.26998900000007],[-111.46806300000003,70.27832000000001],[-111.45445299999989,70.27998400000001],[-111.445267,70.28414900000001],[-111.44275699999992,70.29026800000003],[-111.487213,70.33692900000005],[-111.49472000000003,70.34109499999994],[-111.50723299999993,70.34414700000008],[-111.53694200000001,70.34942600000005],[-111.631104,70.35832199999999],[-111.66471899999999,70.35803199999998],[-111.69387799999998,70.35554500000006],[-111.73528299999998,70.35026600000009],[-111.75055700000001,70.34942600000005],[-111.803879,70.35081500000001],[-111.98055999999991,70.37081899999998],[-112.00083899999987,70.37803600000007],[-112.053879,70.401093],[-112.06166099999996,70.405258],[-112.06973299999993,70.4149930000001],[-112.07250999999997,70.42025799999999],[-112.073059,70.43165599999998],[-112.07584400000002,70.43664600000005],[-112.08917200000002,70.45109600000012],[-112.11527999999998,70.474152],[-112.14611799999994,70.49054000000007],[-112.156387,70.49414100000013],[-112.16915899999998,70.497208],[-112.19915800000001,70.5022130000001],[-112.42722299999997,70.52638200000001],[-112.49553700000001,70.51527400000003],[-112.5,70.51474000000007],[-112.50945300000001,70.51361100000008],[-112.52806099999998,70.51416],[-112.58612099999999,70.5249940000001],[-112.62193300000001,70.534424],[-112.65278599999994,70.54525800000005],[-112.670837,70.55276500000014],[-112.67859599999991,70.55693100000008],[-112.70973199999997,70.56749000000008],[-112.72805799999998,70.56832900000006],[-112.81471299999993,70.56805400000007],[-112.84861799999993,70.56776400000001],[-112.85610999999994,70.56275899999997],[-112.93749999999994,70.56721500000009],[-113.00083899999993,70.57665999999995],[-113.01611300000002,70.57916300000011],[-113.14222699999999,70.60609399999998],[-113.30304699999994,70.64193699999998],[-113.49221799999992,70.67720000000003],[-113.51112399999994,70.67776500000002],[-113.51999699999993,70.67359899999997],[-113.51917299999997,70.66775500000011],[-113.5227809999999,70.65554799999995],[-113.528343,70.64971900000012],[-113.54055800000003,70.64694200000002],[-113.55444299999994,70.64498900000012],[-113.57140399999997,70.64471400000008],[-113.59166700000003,70.6461030000001],[-113.60722399999997,70.64860499999998],[-113.63054699999998,70.65498400000001],[-113.64917000000003,70.66276600000015],[-113.66528299999999,70.67082200000004],[-113.68388399999992,70.678314],[-113.72860700000001,70.69164999999992],[-113.76194800000002,70.69609100000002],[-113.88221699999997,70.71026599999993],[-113.93831599999993,70.71527100000003],[-113.97416699999991,70.71554600000002],[-113.98972299999997,70.71443200000004],[-114.015556,70.70999100000012],[-114.06833599999993,70.69247400000006],[-114.089447,70.68525699999998],[-114.12082699999996,70.67469800000009],[-114.14362299999999,70.6685940000001],[-114.171112,70.66470300000003],[-114.20834400000001,70.665817],[-114.26194800000002,70.67137100000002],[-114.323059,70.67526200000009],[-114.37748699999997,70.67581200000012],[-114.40834000000001,70.67359899999997],[-114.4202729999999,70.67082200000004],[-114.43083200000001,70.66720600000002],[-114.44833399999999,70.65860000000009],[-114.45889299999999,70.65525800000012],[-114.49500299999994,70.64694200000002],[-114.54527299999995,70.63610799999998],[-114.571121,70.63136299999996],[-114.64111299999996,70.62248200000005],[-114.98916599999995,70.6038670000001],[-115.13694800000002,70.59803800000009],[-115.25250199999994,70.60137900000012],[-115.38054699999998,70.60470600000008],[-115.39943700000003,70.60498000000001],[-115.88971700000002,70.595261],[-115.921944,70.59359699999999],[-115.97609699999998,70.58526600000005],[-116.05555700000002,70.57222000000013],[-116.08556399999992,70.58776900000004],[-116.16251399999999,70.62303200000008],[-116.17111199999994,70.62692300000015],[-116.26363400000002,70.63472000000007],[-116.36389200000002,70.63916000000012],[-116.380829,70.63888500000007],[-116.52999899999992,70.63247700000011],[-116.63221699999997,70.61499000000009],[-116.65583800000002,70.60914600000007],[-116.66915899999998,70.60720800000013],[-116.71501199999994,70.60304300000013],[-116.90110799999997,70.59721400000012],[-116.91972399999997,70.59748800000006],[-117.05972300000002,70.60137900000012],[-117.10056299999997,70.60331700000006],[-117.34584000000001,70.61499000000009],[-117.34973100000002,70.61998000000011],[-117.35861199999994,70.62387100000001],[-117.37666300000001,70.62553400000013],[-117.50556899999998,70.61692800000003],[-117.51528899999994,70.61331199999995],[-117.51806599999986,70.60636899999997],[-117.51862299999993,70.60026600000003],[-117.52500900000001,70.59498599999995],[-117.54360999999994,70.595261],[-117.5594329999999,70.59721400000012],[-117.61305199999998,70.60859700000015],[-117.671112,70.62441999999999],[-117.70472699999999,70.63415500000002],[-117.724716,70.64137300000004],[-117.73777799999993,70.65026899999998],[-117.74194299999994,70.65525800000012],[-117.741669,70.66137699999996],[-117.73944099999994,70.66693099999998],[-117.73473399999995,70.67303500000003],[-117.72222899999986,70.68331900000004],[-117.71417199999996,70.68803400000007],[-117.70944199999985,70.69386300000008],[-117.71140300000002,70.6997070000001],[-117.71806300000003,70.70387299999999],[-117.73581699999994,70.71165500000012],[-117.74694799999997,70.71499599999999],[-117.89806399999998,70.75610400000011],[-117.94554099999999,70.76859999999999],[-118.00890400000003,70.783051],[-118.04750100000001,70.79165600000005],[-118.09277299999997,70.80470300000007],[-118.13583399999999,70.81805400000002],[-118.16750300000001,70.82859800000006],[-118.18776700000001,70.83610499999998],[-118.20584099999996,70.84387200000015],[-118.26445000000001,70.87191800000005],[-118.28028899999993,70.87997400000012],[-118.30972300000002,70.89721700000001],[-118.31639100000001,70.90165700000006],[-118.32972699999993,70.91053799999997],[-118.40862299999998,70.970261],[-118.41750300000001,70.98027000000002],[-118.41972399999986,70.98580900000002],[-118.41944899999993,70.99192800000003],[-118.415009,70.99803200000008],[-118.40862299999998,71.00332600000007],[-118.40055799999999,71.00776699999994],[-118.37082700000002,71.01914999999997],[-118.33944699999995,71.02943399999998],[-118.2725069999999,71.04887400000001],[-117.98055999999997,71.12442000000004],[-117.84973099999996,71.15693700000003],[-117.79666099999992,71.16638200000011],[-117.728882,71.16970800000013],[-117.69055199999997,71.16943400000002],[-117.640289,71.17192100000011],[-117.54305999999991,71.1785890000001],[-117.49445300000002,71.18193100000002],[-117.41665599999988,71.18887300000011],[-117.38722199999995,71.192474],[-117.28859699999992,71.20664999999997],[-116.98528299999998,71.23609899999997],[-116.83666999999997,71.26914999999991],[-116.83332799999994,71.27609300000012],[-116.82472200000001,71.28054800000012],[-116.80055199999993,71.28610200000008],[-116.71333300000003,71.297211],[-116.66972399999992,71.30276500000002],[-116.60166900000002,71.313873],[-116.51777600000003,71.32638499999996],[-116.40583800000002,71.34304800000007],[-116.20889299999993,71.36415099999999],[-116.17722300000003,71.36665300000004],[-116.14195299999989,71.367752],[-116.08556399999992,71.36747700000001],[-116.077789,71.36581400000006],[-116.05249000000003,71.35609399999998],[-115.81027199999994,71.36276199999998],[-115.77667200000002,71.36442599999998],[-115.76083399999993,71.36581400000006],[-115.74638399999998,71.36831700000005],[-115.73416099999986,71.37136800000007],[-115.72693599999997,71.37637300000011],[-115.72666900000002,71.38136299999996],[-115.73306299999996,71.38581800000003],[-115.74416400000001,71.38916000000012],[-115.75805700000001,71.39193700000004],[-115.79055800000003,71.39637800000014],[-115.84166700000003,71.39444000000003],[-115.85582699999992,71.39221200000003],[-115.885559,71.38916000000012],[-115.91915899999998,71.38720699999999],[-115.93360899999999,71.38888500000013],[-116.01777599999997,71.41110199999997],[-116.06471299999998,71.43858300000005],[-115.82805599999995,71.483047],[-115.76306199999999,71.49026500000002],[-115.62082700000002,71.49859600000008],[-115.60472099999993,71.49609400000003],[-115.58444199999991,71.488876],[-115.58416699999998,71.48525999999998],[-115.53555299999994,71.47026100000011],[-115.41555800000003,71.4497070000001],[-115.37832599999996,71.4497070000001],[-115.20028699999995,71.47943099999998],[-115.17527799999988,71.48498500000011],[-115.06667299999998,71.51860000000005],[-115.05750299999994,71.52304100000015],[-115.06194299999999,71.526657],[-115.08168,71.52720599999992],[-115.11361699999998,71.52470400000004],[-115.15638699999994,71.51887500000004],[-115.17054699999994,71.516663],[-115.24553700000001,71.50000000000011],[-115.26000999999997,71.49803199999997],[-115.32224300000001,71.49247700000006],[-115.44275699999992,71.48803700000008],[-115.45973200000003,71.48915100000005],[-115.53859699999998,71.50082400000008],[-115.54998799999998,71.5044400000001],[-115.55860899999999,71.508331],[-115.55583199999995,71.51361100000008],[-115.54332699999986,71.516663],[-115.53083800000002,71.51944000000009],[-115.516663,71.52137800000003],[-115.5122219999999,71.53776600000009],[-115.61888099999987,71.55525200000005],[-115.65499899999992,71.55802900000009],[-115.70638999999994,71.55581700000005],[-115.79194599999994,71.54359399999998],[-115.87638900000002,71.53276100000005],[-115.965012,71.52221699999996],[-116.16027799999989,71.49971000000005],[-116.20805399999995,71.49581899999998],[-116.28250100000002,71.49552899999998],[-116.33389299999999,71.4933170000001],[-116.41361999999998,71.48664899999994],[-116.443604,71.48332200000004],[-116.806107,71.43609600000013],[-116.98610699999995,71.42720000000003],[-117.17666600000001,71.40470900000003],[-117.20111099999997,71.3983310000001],[-117.21528599999994,71.39637800000014],[-117.328056,71.38610800000004],[-117.35944399999994,71.38333100000011],[-117.37721299999987,71.3827510000001],[-117.39835399999998,71.38388099999997],[-117.41221599999994,71.38638300000002],[-117.41665599999988,71.3913730000001],[-117.41610700000001,71.39776600000005],[-117.41306299999997,71.40443400000004],[-117.39083900000003,71.43525700000004],[-117.38110399999994,71.44720500000005],[-117.37832600000002,71.45416300000005],[-117.44776899999988,71.47387700000013],[-117.49445300000002,71.48692300000005],[-117.51750199999998,71.4933170000001],[-117.545837,71.49887100000012],[-117.56276699999995,71.49971000000005],[-117.628601,71.46775800000012],[-117.63333099999994,71.46192900000011],[-117.63166799999999,71.4563750000001],[-117.62471,71.4519350000001],[-117.61305199999998,71.44859300000013],[-117.596657,71.44636500000001],[-117.55583200000001,71.44525100000004],[-117.5369419999999,71.44386299999991],[-117.506393,71.4391480000001],[-117.48332199999999,71.43248000000011],[-117.47888199999989,71.42747500000007],[-117.48194899999999,71.42053200000004],[-117.51722699999999,71.37942500000003],[-117.52749599999993,71.375809],[-117.53943600000002,71.37275700000009],[-117.59416199999987,71.37164300000006],[-117.68138099999993,71.37970000000007],[-117.75666799999999,71.37608300000011],[-117.79444899999999,71.36804200000006],[-117.82749899999999,71.37220800000011],[-117.94833399999999,71.37776200000013],[-118.01500699999997,71.37303200000008],[-118.03278399999994,71.37248200000005],[-118.09084299999995,71.37275700000009],[-118.112213,71.37359600000002],[-118.18536399999999,71.37979100000013],[-118.24388099999999,71.38998400000008],[-118.25556899999998,71.393326],[-118.28362300000003,71.40470900000003],[-118.29750099999995,71.41360500000013],[-118.31111099999993,71.42858900000004],[-118.31527699999992,71.43969700000002],[-118.31471299999998,71.45220900000004],[-118.30943300000001,71.46582000000001],[-118.28999299999992,71.48165900000009],[-118.28195199999988,71.48609899999991],[-118.2633439999999,71.49414100000007],[-118.21250900000001,71.51304600000003],[-118.20221699999996,71.516663],[-118.19027699999998,71.51971400000002],[-118.17804699999994,71.5227660000001],[-118.12609900000001,71.53305100000006],[-118.08612099999988,71.54026799999997],[-118.05444299999999,71.54304500000006],[-117.83583099999998,71.55470300000007],[-117.70722999999998,71.54942299999999],[-117.68720999999994,71.54998800000004],[-117.675003,71.55276500000014],[-117.658051,71.56164600000005],[-117.65139799999992,71.56694000000005],[-117.65583800000002,71.57193000000012],[-117.66999800000002,71.57470699999999],[-117.87304699999993,71.611649],[-117.88722199999995,71.6141510000001],[-117.90888999999999,71.61499000000003],[-117.86361699999998,71.6394350000001],[-117.718887,71.65971400000001],[-117.70694700000001,71.6624910000001],[-117.69638099999992,71.66609199999999],[-117.70084399999996,71.67137100000014],[-117.715012,71.67387400000013],[-117.73665599999993,71.6749880000001],[-118.01000999999997,71.67248499999994],[-118.02778599999994,71.67164600000001],[-118.11665299999993,71.65277100000003],[-118.12693799999988,71.64888000000013],[-118.17278299999998,71.62803600000001],[-118.17749000000003,71.62191800000005],[-118.16388699999993,71.60693399999997],[-118.16639699999996,71.59999099999999],[-118.17666600000001,71.59637499999997],[-118.19082600000002,71.59414699999996],[-118.29998799999993,71.58332800000011],[-118.31777999999991,71.582764],[-118.33444199999997,71.58471700000013],[-118.36527999999998,71.58943199999993],[-118.38639799999999,71.61360200000013],[-118.38612399999994,71.61970500000007],[-118.45500199999987,71.65081800000007],[-118.485817,71.65554800000012],[-118.56639099999995,71.66276600000015],[-118.60527000000002,71.66415400000005],[-118.84166700000003,71.66470299999997],[-118.85555999999997,71.6624910000001],[-118.86389199999996,71.65803500000004],[-118.90387699999997,71.61470000000003],[-118.90387699999997,71.6083220000001],[-118.88971699999996,71.599716],[-118.88027999999991,71.5958250000001],[-118.86609599999997,71.586929],[-118.8683319999999,71.58027600000003],[-118.88054699999998,71.5772090000001],[-118.89778099999995,71.57777400000009],[-118.90972899999991,71.58109999999999],[-119.05027799999999,71.6266480000001],[-119.07472200000001,71.64414999999997],[-119.08416699999998,71.65416000000005],[-119.10582699999998,71.68580600000007],[-119.12471,71.73054500000006],[-119.13445300000001,71.76527399999992],[-119.13445300000001,71.78387499999997],[-119.10555999999991,71.87664800000005],[-119.10305800000003,71.883331],[-119.09194899999994,71.90220599999998],[-119.08750900000001,71.90832499999999],[-118.945831,71.99136400000009],[-118.929169,72.00054899999992],[-118.86694299999999,72.02387999999996],[-118.84249899999998,72.02970900000003],[-118.80166599999995,72.03720099999992],[-118.76471699999996,72.04637099999997],[-118.733612,72.05748000000006],[-118.72501399999987,72.0619200000001],[-118.71665999999999,72.066666],[-118.71028099999995,72.07193000000001],[-118.70556599999992,72.07777400000003],[-118.703056,72.08471700000001],[-118.70749699999999,72.09582499999999],[-118.715012,72.10026600000009],[-118.71972700000003,72.10525500000006],[-118.71945199999999,72.11137400000007],[-118.71749899999998,72.11692800000009],[-118.69193999999999,72.13053900000006],[-118.58860800000002,72.17608600000011],[-118.57640100000003,72.17915299999999],[-118.56194299999999,72.18136600000014],[-118.545547,72.18275499999999],[-118.44248999999996,72.18165599999998],[-118.40583799999996,72.18304400000005],[-118.38945000000001,72.18470800000011],[-118.15722699999992,72.21775800000012],[-118.12832599999996,72.22221400000006],[-118.11945299999996,72.22665400000005],[-118.11277799999993,72.23193400000014],[-118.108047,72.23776200000009],[-118.10527000000002,72.24470500000007],[-118.10417199999995,72.26332100000008],[-118.12138400000003,72.30802900000015],[-118.13082899999995,72.31805400000007],[-118.14527899999996,72.32693499999999],[-118.16471899999993,72.33442700000012],[-118.176941,72.33776900000004],[-118.19193999999999,72.34054600000013],[-118.20916699999998,72.34248400000007],[-118.25140399999998,72.34471100000013],[-118.27166699999992,72.34471100000013],[-118.28832999999992,72.34332300000005],[-118.32528699999995,72.34193400000004],[-118.36416600000001,72.3413700000001],[-118.40695199999993,72.34248400000007],[-118.446663,72.345261],[-118.49109599999997,72.35304300000013],[-118.52306399999992,72.36387600000012],[-118.55499299999997,72.38081400000004],[-118.56973299999999,72.38970900000004],[-118.58194700000001,72.39915500000001],[-118.58860800000002,72.41665599999999],[-118.58805799999999,72.43525699999998],[-118.58528100000001,72.44192499999997],[-118.573059,72.46081500000008],[-118.56833599999993,72.46665999999999],[-118.55027799999999,72.48332199999999],[-118.53694199999995,72.49386600000003],[-118.51972999999992,72.50277699999998],[-118.20722999999998,72.6185910000001],[-118.12554899999998,72.64248700000002],[-118.08306900000002,72.64971900000012],[-117.90361000000001,72.68969700000014],[-117.89083899999991,72.69274900000005],[-117.86888099999993,72.69999700000005],[-117.63305700000001,72.784988],[-117.60193600000002,72.79693600000007],[-117.51944700000001,72.82887300000004],[-117.48999000000003,72.84136999999998],[-117.48111,72.84582500000005],[-117.46472199999994,72.85554500000012],[-117.43611099999993,72.876373],[-117.42054699999994,72.89444000000009],[-117.402222,72.90332000000012],[-117.37999000000002,72.91053800000009],[-117.35360699999995,72.91638200000011],[-117.32333399999993,72.92082199999993],[-117.30638099999993,72.92192100000011],[-117.24916099999996,72.92387400000007],[-117.12721299999998,72.93248],[-116.95639,72.95416300000011],[-116.94138299999997,72.95637499999998],[-116.89972699999998,72.96415700000011],[-116.862503,72.97221400000006],[-116.83805799999999,72.97859200000005],[-116.775284,72.9952550000001],[-116.70722999999998,73.01721199999997],[-116.65972899999991,73.03109700000005],[-116.58750900000001,73.051376],[-116.57417299999997,73.0541530000001],[-116.54167199999995,73.05748000000006],[-116.52416999999991,73.05886800000013],[-116.31916799999993,73.09165999999999],[-116.24221799999998,73.1102600000001],[-116.20195000000001,73.11859099999998],[-116.15556300000003,73.12469500000003],[-115.90055799999993,73.1541600000001],[-115.60973399999995,73.19413800000012],[-115.44082600000002,73.22387700000013],[-115.34638999999999,73.25332600000013],[-115.32305899999994,73.26026900000011],[-115.30915799999997,73.26304600000003],[-115.14917000000003,73.28831500000001],[-115.10221899999999,73.29414400000002],[-115.01418299999989,73.29998800000004],[-114.95111099999997,73.30775499999999],[-114.89417299999997,73.31805400000002],[-114.86638599999998,73.32360800000004],[-114.83056599999998,73.33415200000007],[-114.81054699999999,73.342758],[-114.70722999999992,73.368042],[-114.67555199999998,73.37191800000005],[-114.65778399999999,73.37303200000002],[-114.56166100000002,73.37553400000013],[-114.54083300000002,73.37359599999996],[-114.50527999999991,73.36886600000014],[-114.337784,73.34332300000005],[-114.30499299999991,73.33804299999997],[-114.27500899999995,73.33221400000014],[-114.22609699999987,73.31832900000006],[-114.197769,73.30636600000003],[-114.16306299999997,73.28970300000015],[-114.11054999999999,73.26388500000002],[-114.05610699999994,73.23359700000003],[-114.01666299999994,73.2063750000001],[-113.96167000000003,73.15304600000013],[-113.95694700000001,73.14248700000007],[-113.95388799999989,73.12553399999996],[-113.95749699999999,73.11331200000001],[-113.99582700000002,73.07777399999998],[-114.00499699999995,73.06442300000003],[-114.035553,73.00499000000002],[-114.04750100000001,72.95498700000007],[-114.05499299999997,72.88360599999999],[-114.05277999999998,72.872208],[-114.04915599999998,72.86720300000013],[-114.0427699999999,72.86276200000003],[-114.027222,72.8541560000001],[-113.98166700000002,72.83415200000002],[-113.96888699999994,72.82499700000011],[-113.96777299999997,72.81944299999998],[-113.96945199999999,72.81303400000007],[-113.97582999999992,72.80720500000007],[-113.985817,72.80304000000007],[-113.99749799999995,72.7994230000001]],[[-95.66972399999992,73.60498000000013],[-95.6885989999999,73.603317],[-95.70249899999999,73.60554500000012],[-95.71167000000003,73.61219800000009],[-95.70388799999995,73.61747700000006],[-95.68415799999997,73.6202550000001],[-95.66999799999996,73.62052900000003],[-95.65556300000003,73.61665299999993],[-95.65499899999998,73.609985],[-95.66972399999992,73.60498000000013]],[[-107.89555399999989,73.5413670000001],[-107.93055699999996,73.53942899999998],[-107.9519499999999,73.54026800000008],[-107.97193900000002,73.542755],[-108.00917099999992,73.54803500000008],[-108.02306399999998,73.55137600000012],[-108.07472200000001,73.57638500000007],[-108.08277899999996,73.580826],[-108.08500700000002,73.58581500000014],[-108.083328,73.59721400000006],[-108.07640099999992,73.60359199999999],[-108.066101,73.60859700000003],[-108.05444299999988,73.61248799999993],[-108.04083299999996,73.61554000000007],[-108.00750700000003,73.6185910000001],[-107.89943699999992,73.62275699999998],[-107.86277799999993,73.624146],[-107.82444800000002,73.6244200000001],[-107.80444299999999,73.624146],[-107.68110699999994,73.62136799999996],[-107.61472299999991,73.61470000000003],[-107.60056299999997,73.61137400000013],[-107.58944699999995,73.6077580000001],[-107.58473200000003,73.60304300000007],[-107.58249699999999,73.59776299999999],[-107.58473200000003,73.58665500000001],[-107.59194899999994,73.57998700000002],[-107.60221899999988,73.57527199999998],[-107.64527900000002,73.57026700000011],[-107.65722700000003,73.568604],[-107.7491609999999,73.55581699999999],[-107.89555399999989,73.5413670000001]],[[-124.307503,73.55636600000014],[-124.33167999999995,73.55636600000014],[-124.343613,73.55998199999999],[-124.35193600000002,73.5711060000001],[-124.35861199999988,73.63026400000007],[-124.34612300000003,73.63360600000004],[-124.33138999999994,73.63638300000014],[-124.307503,73.63220200000006],[-124.30332900000002,73.62664800000005],[-124.29387700000001,73.62248199999993],[-124.28222700000003,73.61886600000008],[-124.26806599999992,73.61608899999999],[-124.21028100000001,73.61137400000013],[-124.19360399999994,73.60914600000001],[-124.17944299999994,73.60636900000009],[-124.16777000000002,73.60304300000007],[-124.14916999999997,73.59471100000007],[-124.12666300000001,73.580826],[-124.11972000000003,73.57582100000013],[-124.11554699999988,73.57054100000005],[-124.11389199999996,73.5641480000001],[-124.12638899999996,73.56080599999996],[-124.307503,73.55636600000014]],[[-124.58473199999992,73.67915300000004],[-124.59944199999995,73.676376],[-124.62361099999998,73.67665099999999],[-124.640556,73.67886399999998],[-124.70056199999993,73.68942299999998],[-124.72917199999995,73.694977],[-124.733612,73.70054599999997],[-124.72582999999992,73.70526100000001],[-124.71584299999995,73.70915200000007],[-124.70111099999997,73.711929],[-124.681671,73.71304299999997],[-124.66471899999999,73.71081500000003],[-124.66278099999994,73.70609999999999],[-124.64835399999998,73.70471200000009],[-124.61694299999999,73.69970700000005],[-124.57140399999992,73.69192500000008],[-124.564438,73.68719500000003],[-124.57224299999996,73.68248],[-124.58473199999992,73.67915300000004]],[[-105.089447,73.73526000000004],[-104.96028099999995,73.68858299999994],[-104.84306300000003,73.65081800000007],[-104.71140300000002,73.63081399999993],[-104.69167299999992,73.628311],[-104.675003,73.6249850000001],[-104.58084100000002,73.60026600000015],[-104.53056300000003,73.58137499999992],[-104.51306199999999,73.57304400000004],[-104.49445300000002,73.55941800000005],[-104.49027999999998,73.55470300000002],[-104.48528299999998,73.54470800000013],[-104.48306299999996,73.53442400000012],[-104.512787,73.49304200000006],[-104.55583200000001,73.40332000000001],[-104.56639100000001,73.33471700000013],[-104.56833599999999,73.32916300000011],[-104.57333399999999,73.3230440000001],[-104.58138999999994,73.31666600000011],[-104.60193599999997,73.30636600000003],[-104.64916999999997,73.28082300000011],[-104.69499200000001,73.25221300000004],[-104.76000999999991,73.20387300000004],[-104.76500699999985,73.19775400000003],[-104.76390099999998,73.19247400000012],[-104.79415899999998,73.168045],[-104.86805700000002,73.13665800000007],[-104.97556299999997,73.0852660000001],[-104.98332199999999,73.07887299999999],[-104.98805199999993,73.07304399999998],[-104.98388699999992,73.06805400000007],[-104.97749299999998,73.05304000000001],[-104.97361799999999,73.0316620000001],[-104.97860699999995,73.02554300000008],[-104.984734,73.02053800000004],[-104.99527,73.01582300000001],[-105.031677,73.00416600000005],[-105.0750119999999,72.99720800000006],[-105.08833300000003,72.99414100000013],[-105.13639799999993,72.97886700000004],[-105.14695699999999,72.974152],[-105.22582999999997,72.93304400000011],[-105.30304699999994,72.951096],[-105.31916799999999,72.95416300000011],[-105.339722,72.95555100000001],[-105.354446,72.95332300000007],[-105.35610999999994,72.94775400000003],[-105.33139,72.91053800000009],[-105.32417299999997,72.90609699999999],[-105.279449,72.88554399999992],[-105.25361599999997,72.87858599999998],[-105.237503,72.87553400000002],[-105.21140300000002,72.86859100000004],[-105.20417799999996,72.86415100000005],[-105.2622219999999,72.84860200000008],[-105.27555799999993,72.84553499999998],[-105.28999299999987,72.84776299999999],[-105.38305699999995,72.8666530000001],[-105.43611099999993,72.89665200000013],[-105.443329,72.90109300000006],[-105.45612299999999,72.91526799999997],[-105.458618,72.92553699999996],[-105.45694699999996,72.93136600000003],[-105.45834400000001,72.93637100000007],[-105.46250900000001,72.94136000000003],[-105.57472199999995,72.98442100000005],[-105.73277299999995,73.04775999999998],[-105.91388699999999,73.1455380000001],[-105.94638099999992,73.16026300000004],[-106.09249899999992,73.19970699999993],[-106.08194700000001,73.24108899999999],[-106.32195300000001,73.33888200000013],[-106.44776899999994,73.39305100000013],[-106.45556599999998,73.397491],[-106.46611000000001,73.40138200000007],[-106.72028399999999,73.44999700000011],[-106.88137799999998,73.46331800000007],[-106.89806399999992,73.46192900000005],[-106.91610699999995,73.46138000000008],[-106.9375,73.4624940000001],[-107,73.46971100000002],[-107.016953,73.4727630000001],[-107.02749599999999,73.47637900000001],[-107.03555299999994,73.48082000000011],[-107.034157,73.48637400000007],[-107.02583300000003,73.49859600000008],[-107.01834100000002,73.50499000000008],[-107.00974299999996,73.5105440000001],[-106.97112299999992,73.53166199999998],[-106.92944299999999,73.55053700000013],[-106.89334100000002,73.56248499999998],[-106.74526999999995,73.64804100000015],[-106.70028699999995,73.67608599999994],[-106.65805099999994,73.6952510000001],[-106.64584399999995,73.699142],[-106.61833200000001,73.70526100000001],[-106.57224300000001,73.711929],[-106.32721700000002,73.72665400000011],[-106.18554699999999,73.73359700000015],[-106.03916900000002,73.73136899999997],[-105.80055199999998,73.72692899999998],[-105.72666900000002,73.72859200000005],[-105.68028300000003,73.73498500000005],[-105.66639699999996,73.73776199999992],[-105.637787,73.74443100000002],[-105.61277799999993,73.75221299999998],[-105.58473200000003,73.75804100000005],[-105.569458,73.76026900000005],[-105.53527799999995,73.76277199999998],[-105.51666299999994,73.76332100000013],[-105.30387899999994,73.76220699999999],[-105.28388999999999,73.76165800000001],[-105.16999800000002,73.75555400000002],[-105.14862099999999,73.75416600000005],[-105.10749799999991,73.74359099999998],[-105.089447,73.73526000000004]],[[-80.14222699999988,73.69664000000012],[-80.108612,73.69386300000002],[-80.07444800000002,73.69747900000004],[-79.90139799999997,73.69831800000003],[-79.62554899999998,73.67082199999999],[-79.58612099999999,73.66276600000009],[-79.523056,73.64665200000013],[-79.49305699999996,73.6377720000001],[-79.47639499999991,73.63415499999996],[-79.45194999999995,73.63053900000011],[-79.37361099999998,73.63081399999993],[-78.96166999999997,73.63275099999998],[-78.94610599999999,73.63472000000002],[-78.93443300000001,73.63859600000006],[-78.931107,73.64248700000013],[-78.92887899999994,73.64749100000012],[-78.92416400000002,73.6502690000001],[-78.9125059999999,73.65386999999998],[-78.887787,73.65664700000008],[-78.86138900000003,73.65832499999999],[-78.64416499999993,73.65664700000008],[-78.40834000000001,73.66165200000012],[-78.20666499999999,73.66775500000006],[-78.16639700000002,73.66804500000006],[-78.12777699999998,73.66470300000015],[-78.11332700000003,73.66304000000002],[-78.064438,73.65193200000004],[-78.00973499999998,73.63749700000011],[-77.96528599999994,73.628311],[-77.82305899999994,73.60386700000004],[-77.73860199999996,73.59193399999998],[-77.608047,73.57415800000001],[-77.53500400000001,73.56553600000001],[-77.45388799999995,73.55970800000006],[-77.42443799999995,73.55470300000002],[-77.395554,73.5458220000001],[-77.37304699999993,73.52970900000008],[-77.36332700000003,73.52470399999999],[-77.35139499999997,73.51998899999995],[-77.33833300000003,73.51666300000011],[-77.29472399999997,73.51277200000004],[-77.237213,73.50999499999995],[-77.20306399999993,73.50555400000002],[-77.19193999999999,73.50138900000002],[-77.14862099999999,73.47637900000001],[-77.15361000000001,73.46804800000007],[-77.15722699999998,73.45860300000004],[-77.05526699999996,73.36637900000005],[-77.04888899999992,73.36192299999999],[-76.999435,73.3458250000001],[-76.96972699999998,73.33720399999999],[-76.91361999999998,73.324432],[-76.89334099999996,73.32110599999999],[-76.88417099999992,73.32165500000008],[-76.87887599999993,73.32415800000007],[-76.858612,73.32638500000013],[-76.837219,73.3272090000001],[-76.73638900000003,73.32470699999999],[-76.72193900000002,73.32249500000012],[-76.708054,73.31776400000001],[-76.57972699999999,73.21971100000007],[-76.57749899999993,73.20555100000013],[-76.58500699999996,73.19442700000008],[-76.601944,73.1833190000001],[-76.61972000000003,73.17581200000012],[-76.60527000000002,73.15914900000007],[-76.58694500000001,73.14637800000014],[-76.58222999999998,73.14387499999998],[-76.510559,73.12025499999999],[-76.49554399999994,73.11692800000009],[-76.48750299999995,73.1160890000001],[-76.38194299999998,73.10609399999998],[-76.31361400000003,73.10054000000002],[-76.31249999999994,73.06749000000013],[-76.31806899999992,73.06275900000003],[-76.31945799999994,73.05831899999998],[-76.33306899999991,72.96360799999997],[-76.323059,72.95721400000014],[-76.30943300000001,72.95248400000008],[-76.29167199999995,72.94886800000006],[-76.275284,72.94664000000006],[-76.21194500000001,72.94552600000009],[-76.162216,72.94636500000007],[-76.118607,72.94026200000013],[-76.10360700000001,72.93637100000007],[-76.07722499999994,72.92498800000004],[-76.07167099999992,72.92109700000015],[-76.06221,72.90693700000003],[-76.0594329999999,72.90081800000002],[-76.08639499999998,72.86360200000007],[-76.09388699999994,72.85803199999998],[-76.10388199999994,72.85304300000001],[-76.11527999999993,72.84942600000005],[-76.13110399999988,72.84553499999998],[-76.14999399999999,72.84220900000014],[-76.25140399999998,72.82638500000002],[-76.31555200000003,72.81721499999998],[-76.339722,72.81498700000003],[-76.5625,72.81248499999998],[-76.58167999999995,72.81248499999998],[-76.601944,72.81387300000006],[-76.61860699999988,72.81693999999999],[-76.63417099999998,72.82054100000005],[-76.662781,72.82916300000005],[-76.68138099999993,72.8313750000001],[-76.72193900000002,72.83387800000008],[-76.74082900000002,72.83387800000008],[-76.76750199999992,72.83387800000008],[-76.89195299999994,72.83082599999994],[-76.93721,72.83082599999994],[-77.08475499999997,72.83968400000015],[-77.10166899999996,72.84027100000003],[-77.14388999999994,72.84193399999998],[-77.22694399999995,72.84610000000004],[-77.26583899999991,72.84942600000005],[-77.31443799999994,72.85554500000012],[-77.36582900000002,72.86442600000004],[-77.40055799999999,72.87081899999998],[-77.41610699999995,72.87469500000009],[-77.44721999999996,72.87997400000006],[-77.52278099999995,72.88610800000009],[-77.70417800000001,72.89721699999996],[-77.72332799999998,72.89694199999997],[-77.86000099999995,72.89305100000007],[-77.90417500000001,72.891663],[-77.99777199999994,72.88832100000002],[-78.10722399999992,72.88638300000008],[-78.236359,72.89300500000002],[-78.273056,72.89054900000002],[-78.29722600000002,72.8877720000001],[-78.48611499999998,72.86554000000001],[-78.62388599999997,72.84803799999997],[-78.86582899999996,72.80442799999997],[-79.047775,72.77137800000014],[-79.1619419999999,72.75054899999998],[-79.20916699999992,72.74498],[-79.296112,72.73776199999998],[-79.35916099999997,72.73359700000015],[-79.38249200000001,72.73304700000011],[-79.400284,72.73359700000015],[-79.42916899999994,72.73580900000002],[-79.54333499999996,72.74859600000002],[-79.62388599999997,72.76332100000013],[-79.92777999999993,72.84248400000001],[-79.972778,72.85470599999996],[-79.99861099999998,72.86303700000002],[-80.00917099999992,72.87275699999992],[-80.12083399999995,72.97886700000004],[-80.15167200000002,73.01193200000012],[-80.18138099999993,73.04386900000009],[-80.181107,73.05026200000003],[-80.16416900000002,73.06192000000004],[-80.14723200000003,73.07138100000003],[-80.13473499999992,73.08471699999996],[-80.13166799999999,73.08859300000006],[-80.12887599999999,73.09526100000005],[-80.122772,73.11442599999998],[-80.11000099999995,73.17970300000002],[-80.114441,73.18637100000001],[-80.13444500000003,73.20915200000002],[-80.14306599999992,73.21693399999998],[-80.15194699999995,73.22248799999994],[-80.21694899999994,73.2433170000001],[-80.23805199999998,73.24414100000007],[-80.41528299999993,73.24414100000007],[-80.61999499999996,73.26416],[-80.76000999999991,73.27470400000004],[-80.79750099999995,73.27693200000004],[-80.87609899999995,73.32777399999992],[-80.87609899999995,73.338593],[-80.87249800000001,73.4249880000001],[-80.82028199999996,73.48915099999999],[-80.80999799999995,73.64444000000009],[-80.85777299999995,73.74192800000003],[-80.77166699999992,73.74971],[-80.68331899999998,73.755829],[-80.56054699999987,73.76776099999995],[-80.43499800000001,73.76609800000006],[-80.37332200000003,73.76165800000001],[-80.35305800000003,73.75972000000007],[-80.32084700000001,73.75387600000005],[-80.30860899999999,73.75],[-80.29861499999987,73.7458190000001],[-80.265289,73.73027000000002],[-80.22332799999992,73.71582000000006],[-80.19276399999995,73.70721400000014],[-80.15834000000001,73.69941700000004],[-80.14222699999988,73.69664000000012]],[[-73.35467499999993,68.32921599999997],[-73.328171,68.32820899999996],[-73.31617,68.32871200000005],[-73.30683099999999,68.33054400000009],[-73.21167000000003,68.37692300000003],[-73.23055999999991,68.38415500000013],[-73.25306699999999,68.39082300000013],[-73.27944899999989,68.39498900000001],[-73.30277999999993,68.39610299999998],[-73.31806899999998,68.39305100000007],[-73.35749800000002,68.37136800000013],[-73.35972599999997,68.36498999999998],[-73.35777300000001,68.35748300000006],[-73.35305799999998,68.35247800000002],[-73.34916699999991,68.34498600000006],[-73.34722899999997,68.3374940000001],[-73.34944200000001,68.3311000000001],[-73.35467499999993,68.32921599999997],[-73.50666799999999,68.29136700000004],[-73.589722,68.25471500000003],[-73.59777799999995,68.251938],[-73.620834,68.24609399999997],[-73.63221699999991,68.24664300000006],[-73.63972499999994,68.24971],[-73.85166899999996,68.34220900000014],[-73.85583499999996,68.34664900000001],[-73.89611799999994,68.39221199999992],[-73.88944999999995,68.44470200000012],[-73.87748699999992,68.48109399999993],[-73.87361099999993,68.48776200000009],[-73.86721799999998,68.493042],[-73.85611,68.49748199999999],[-73.823624,68.50332600000002],[-73.80665599999998,68.50387600000005],[-73.74999999999994,68.51081799999997],[-73.73889199999996,68.51499900000005],[-73.73028599999998,68.51998900000007],[-73.72582999999997,68.52581800000007],[-73.70472699999993,68.65664700000002],[-73.75389100000001,68.68359400000008],[-73.76139799999999,68.68637100000001],[-73.774719,68.68969700000002],[-73.8658289999999,68.705826],[-73.89389,68.70776400000011],[-74.09416199999998,68.71998600000006],[-74.10610999999994,68.69053600000001],[-73.99221799999998,68.62469500000003],[-73.88806199999988,68.56164599999994],[-73.88166799999999,68.55664100000007],[-73.88166799999999,68.54971300000011],[-73.90360999999996,68.52777100000003],[-73.92138699999992,68.51193200000012],[-73.94193999999999,68.50471500000003],[-73.99027999999993,68.492752],[-74.02833599999991,68.51361099999997],[-74.17166099999997,68.52165200000002],[-74.221115,68.52526899999998],[-74.35139500000002,68.53692600000011],[-74.366104,68.53915400000005],[-74.37943999999993,68.54220599999996],[-74.39111299999996,68.54637100000014],[-74.51417500000002,68.59999100000005],[-74.52639799999997,68.61080900000002],[-74.53277600000001,68.62164300000012],[-74.53167699999995,68.62637300000011],[-74.59889199999992,68.68193099999996],[-74.70195000000001,68.71887200000009],[-74.71221899999995,68.72303800000003],[-74.72610500000002,68.73027000000013],[-74.72833300000002,68.73719800000009],[-74.72471599999994,68.76609799999994],[-74.71945199999999,68.77053799999999],[-74.66416899999996,68.77415500000012],[-74.62083399999989,68.782486],[-74.591949,68.78887900000001],[-74.57694999999995,68.79304500000006],[-74.56527699999992,68.80219999999991],[-74.54638699999998,68.82249499999995],[-74.54804999999999,68.82859800000011],[-74.55139200000002,68.83055100000001],[-74.604172,68.8416600000001],[-74.63417099999992,68.84637499999997],[-74.648056,68.84721400000012],[-74.66665599999993,68.8458250000001],[-74.67832899999996,68.842758],[-74.68737799999997,68.83599100000004],[-74.71871899999996,68.82482100000004],[-74.72305299999994,68.822319],[-74.72122199999995,68.82115200000004],[-74.71421799999996,68.82098400000001],[-74.70522299999993,68.82165500000008],[-74.68943799999994,68.81971699999997],[-74.67166099999997,68.81887799999998],[-74.66027799999989,68.81581100000011],[-74.639725,68.80748],[-74.63333099999994,68.79693600000013],[-74.63500999999997,68.79332000000011],[-74.648056,68.78942900000004],[-74.66583299999996,68.78665200000012],[-74.77166699999998,68.77415500000012],[-74.91776999999996,68.80137599999995],[-74.91389499999997,68.81721500000009],[-74.83750899999995,68.84082000000006],[-74.787781,68.85443100000003],[-74.76416799999998,68.87204000000003],[-74.74017299999997,68.87271099999998],[-74.72222899999997,68.934143],[-74.86294599999991,68.95417800000001],[-74.87277999999998,68.95500199999998],[-74.88761099999999,68.95417800000001],[-74.89810899999998,68.95251500000006],[-74.92011300000001,68.94667100000004],[-74.935944,68.942001],[-75,68.93760700000007],[-75.00500499999993,68.92997700000006],[-75.03361499999988,68.926086],[-75.04277000000002,68.928314],[-75.04194599999988,68.93026700000013],[-75.021118,68.95304900000002],[-74.96234099999998,68.972824],[-74.95300299999997,68.97848499999998],[-74.91533700000002,68.99282100000005],[-74.90766899999988,68.993988],[-74.764725,69.01944000000003],[-74.74833699999999,69.02137800000014],[-74.73500099999995,69.02192700000012],[-74.729446,69.01944000000003],[-74.75805700000001,69.00888099999997],[-74.752228,69.00248699999997],[-74.675003,69.00694300000004],[-74.65834000000001,69.00833099999994],[-74.64277600000003,69.01165800000007],[-74.63806199999999,69.01609800000011],[-74.64111300000002,69.02137800000014],[-74.65249599999993,69.04026799999991],[-74.78582799999998,69.07638500000007],[-74.82084699999996,69.08221400000008],[-74.83416699999992,69.08166499999999],[-74.84583999999995,69.07859800000006],[-74.94860799999992,69.04887400000001],[-75.04333499999996,69.01332100000002],[-75.05194099999989,69.00860599999999],[-75.03611799999993,68.99220300000007],[-75.03778099999988,68.98580900000007],[-75.07139599999994,68.92109700000003],[-75.07556199999993,68.915817],[-75.10916099999986,68.89498900000012],[-75.11639400000001,68.89082300000001],[-75.12416100000002,68.88804600000009],[-75.139725,68.88472000000007],[-75.16999800000002,68.88638300000002],[-75.19249000000002,68.89166300000005],[-75.20195000000001,68.89444000000015],[-75.31582600000002,68.94220000000013],[-75.37388599999991,68.96887200000003],[-75.383331,68.97442600000005],[-75.400284,68.98553500000014],[-75.42250099999995,69.001938],[-75.44583099999994,69.01693700000004],[-75.45445299999994,69.02110299999998],[-75.46639999999996,69.02137800000014],[-75.478882,69.01971400000014],[-75.49415599999998,69.01638800000012],[-75.52833599999997,69.00582900000006],[-75.56555200000003,68.99359100000004],[-75.573624,68.98858599999994],[-75.57861299999996,68.98414600000012],[-75.58084100000002,68.97554000000002],[-75.57417299999992,68.96832300000011],[-75.53778099999994,68.95109600000006],[-75.50695799999994,68.93969699999997],[-75.49972499999996,68.934708],[-75.49499500000002,68.93026700000013],[-75.53416399999998,68.90387000000004],[-75.54277000000002,68.89887999999996],[-75.56527699999998,68.89137300000004],[-75.60388199999994,68.87970000000001],[-75.64778099999995,68.86914099999996],[-75.80915800000002,68.836929],[-75.97610499999996,68.7910920000001],[-75.979446,68.78720100000004],[-75.98500100000001,68.78387500000002],[-75.99554399999994,68.7794340000001],[-76.00862099999995,68.77554300000003],[-76.04943799999995,68.76443500000005],[-76.22721899999999,68.72110000000004],[-76.327225,68.69747899999999],[-76.37609899999995,68.68748499999998],[-76.420547,68.67915299999999],[-76.43638599999986,68.67720000000003],[-76.45666499999999,68.67526200000009],[-76.54028299999999,68.67330899999996],[-76.55943299999996,68.67303500000003],[-76.57556199999999,68.67414900000006],[-76.59056099999998,68.67637600000006],[-76.62887599999999,68.68691999999993],[-76.66082799999998,68.69941699999993],[-76.67416400000002,68.71026599999999],[-76.68028300000003,68.716095],[-76.68859900000001,68.73359700000003],[-76.689438,68.74054000000007],[-76.68804899999998,68.74693300000001],[-76.678604,68.758331],[-76.666946,68.76915000000008],[-76.63694799999996,68.78166200000004],[-76.60861199999994,68.79414400000007],[-76.57749899999993,68.80831899999998],[-76.56138599999991,68.81805400000002],[-76.546112,68.833054],[-76.537216,68.84220900000008],[-76.523056,68.86387600000012],[-76.52166699999998,68.87025499999999],[-76.52389499999992,68.87637300000006],[-76.53277599999996,68.880539],[-76.54415899999998,68.88304100000005],[-76.55943299999996,68.88499500000006],[-76.57667499999997,68.88499500000006],[-76.59333799999996,68.88333100000006],[-76.60665899999992,68.88304100000005],[-76.61000099999995,68.88472000000007],[-76.64416499999999,68.91110200000014],[-76.65556299999997,68.92469800000009],[-76.65556299999997,68.93054200000012],[-76.64277599999997,69.0038760000001],[-76.64056399999993,69.00915500000008],[-76.62554899999998,69.01832600000006],[-76.60360700000001,69.02581800000002],[-76.57833899999991,69.03221100000013],[-76.54333500000001,69.03831500000001],[-76.50140399999992,69.042755],[-76.42250099999995,69.05053700000013],[-76.368607,69.055252],[-76.34889199999992,69.05497699999995],[-76.33277899999996,69.05442800000003],[-76.24027999999993,69.04832500000009],[-76.208054,69.04414400000002],[-76.14056399999993,69.03471400000012],[-76.124435,69.03109699999999],[-76.11416599999995,69.02777100000014],[-76.09167499999995,69.01165800000007],[-76.08000199999992,69.00637800000004],[-76.06861900000001,69.0038760000001],[-75.99693299999996,69.00303600000007],[-75.96916199999998,69.01026900000011],[-75.90499899999992,69.036926],[-75.81388900000002,69.06776399999995],[-75.65583800000002,69.08055099999996],[-75.63778699999995,69.07998700000002],[-75.61915599999992,69.08137499999992],[-75.6058349999999,69.08526599999999],[-75.59889199999998,69.0894320000001],[-75.59388699999994,69.09971600000011],[-75.56973299999993,69.15277100000003],[-75.569458,69.15832499999999],[-75.571121,69.16387900000001],[-75.59167499999995,69.22164900000007],[-75.60305799999998,69.23887600000012],[-75.61971999999997,69.24941999999999],[-75.66972399999992,69.2711030000001],[-75.75973499999998,69.30497700000012],[-75.78332499999999,69.31359900000012],[-75.95638999999989,69.36608899999993],[-75.97027599999996,69.36914100000007],[-76.16861,69.41137700000007],[-76.20249899999993,69.41387900000012],[-76.24194299999994,69.41331500000001],[-76.29804999999999,69.407761],[-76.41777000000002,69.44720500000011],[-76.60749799999996,69.52970900000014],[-76.637787,69.54664599999995],[-76.64111299999996,69.5541530000001],[-76.64167800000001,69.55748000000006],[-76.62666299999995,69.58137500000004],[-76.61999499999996,69.58638000000008],[-76.61166399999996,69.59109500000011],[-76.4891659999999,69.64833100000004],[-76.47778299999999,69.65220600000004],[-76.45916699999998,69.65443400000004],[-76.44221500000003,69.65304600000007],[-76.34777799999995,69.64027400000009],[-76.26139799999999,69.62664799999993],[-76.22694399999995,69.63720699999999],[-76.18611099999998,69.65971400000006],[-76.18249500000002,69.66360500000013],[-76.18777499999999,69.66526800000008],[-76.22610500000002,69.66470300000003],[-76.29554699999994,69.66026300000004],[-76.37638899999996,69.67137100000002],[-76.38833599999992,69.67387400000001],[-76.39750699999996,69.67804000000007],[-76.39973399999985,69.684143],[-76.45056199999993,69.69026200000008],[-76.53778099999994,69.69609100000008],[-76.55166600000001,69.69552600000003],[-76.63417099999998,69.68359400000008],[-76.641953,69.67997700000012],[-76.63890099999998,69.67330900000013],[-76.63194299999992,69.66970800000007],[-76.61639400000001,69.66748000000013],[-76.58167999999995,69.66693099999998],[-76.55776999999995,69.67330900000013],[-76.5427699999999,69.67469800000015],[-76.53083800000002,69.67221100000006],[-76.51777600000003,69.66276599999998],[-76.52278099999995,69.65248100000008],[-76.53500400000001,69.638596],[-76.55332900000002,69.62525900000014],[-76.56166100000002,69.62025499999999],[-76.68388399999998,69.56581100000011],[-76.69193999999999,69.56303400000002],[-76.70750399999997,69.559418],[-76.73028599999998,69.56025699999992],[-76.84472699999992,69.57609600000006],[-77.13694799999996,69.62637300000011],[-77.18582200000003,69.637497],[-77.19166599999994,69.63970900000004],[-77.20056199999999,69.6461030000001],[-77.20056199999999,69.64888000000002],[-77.19444299999992,69.65721100000007],[-77.164444,69.67608600000005],[-77.15556299999997,69.68054199999995],[-77.144455,69.68220500000007],[-76.94943199999994,69.69552600000003],[-76.93943799999994,69.67970300000002],[-76.92999299999997,69.67776500000008],[-76.89666699999998,69.67915299999999],[-76.86805699999996,69.68470800000006],[-76.82972699999993,69.69581600000004],[-76.82028199999996,69.6994170000001],[-76.80471799999998,69.70860300000004],[-76.79388399999999,69.71859700000005],[-76.791946,69.72164900000001],[-76.781387,69.74304200000012],[-76.781387,69.74859600000008],[-76.83528099999995,69.81581100000005],[-76.851944,69.81359900000001],[-76.9330599999999,69.80970800000011],[-77.02667200000002,69.81191999999999],[-77.150284,69.8160860000001],[-77.29305999999985,69.8288730000001],[-77.30888400000003,69.830826],[-77.31054699999999,69.83581499999997],[-77.30777,69.84027100000009],[-77.29777499999989,69.85108900000006],[-77.28472899999997,69.86053500000003],[-77.25418099999996,69.87692300000009],[-77.24305699999996,69.88136299999991],[-77.20834400000001,69.88665800000001],[-77.11665299999993,69.90138200000001],[-76.99276700000001,69.92719999999997],[-76.98167399999994,69.93165600000009],[-76.97471599999994,69.93580600000007],[-76.98055999999997,69.93803400000002],[-76.99276700000001,69.94053600000012],[-77.00279199999994,69.94053600000012],[-77.12527499999993,69.92581200000006],[-77.14111299999996,69.92248500000011],[-77.164444,69.91526800000003],[-77.18832399999991,69.90609700000005],[-77.22694399999995,69.89498900000007],[-77.26028400000001,69.88749699999994],[-77.43804899999992,69.85720800000007],[-77.50834700000001,69.82666000000012],[-77.45556599999998,69.79832500000009],[-77.44444299999998,69.78942899999998],[-77.44915800000001,69.78471400000012],[-77.55139199999996,69.74775699999992],[-77.55915800000002,69.74498000000006],[-77.57472200000001,69.74136399999998],[-77.59777799999995,69.73915100000005],[-77.60861199999994,69.74026500000002],[-77.61582900000002,69.7416530000001],[-77.6263889999999,69.74498000000006],[-77.637787,69.75387599999999],[-77.64527900000002,69.76081800000009],[-77.64999399999999,69.76971400000002],[-77.66805999999997,69.83665500000006],[-77.69193999999993,69.96304300000003],[-77.695267,69.98803700000002],[-77.69444299999992,70.00027500000004],[-77.69305400000002,70.00610400000005],[-77.68582200000003,70.02304100000009],[-77.678604,70.034988],[-77.67250099999995,70.0455320000001],[-77.66972399999997,70.05220000000003],[-77.66722099999998,70.06219499999997],[-77.66500899999994,70.08804300000008],[-77.66555799999998,70.10693400000014],[-77.66833499999996,70.11303700000008],[-77.67388899999997,70.11970500000001],[-77.67193600000002,70.17719999999991],[-77.67250099999995,70.18054200000006],[-77.67832899999996,70.18775900000014],[-77.685272,70.19136000000003],[-77.81082199999997,70.24552900000009],[-77.88417099999998,70.2586060000001],[-77.89222699999988,70.25804100000005],[-78.133621,70.21527100000009],[-78.23916600000001,70.2038730000001],[-78.34500099999991,70.19720500000011],[-78.35139500000002,70.19747900000004],[-78.36471599999999,70.201096],[-78.40167200000002,70.21249399999999],[-78.40527299999997,70.21415700000011],[-78.48083500000001,70.288589],[-78.406113,70.32693500000005],[-78.396118,70.32804900000002],[-78.38917500000002,70.33221400000002],[-78.39889499999992,70.33638000000008],[-78.42582700000003,70.3477630000001],[-78.43666100000002,70.35108899999994],[-78.48638900000003,70.35693400000008],[-78.5041809999999,70.35803199999998],[-78.521118,70.35775800000005],[-78.53639199999998,70.35636900000003],[-78.55749499999996,70.35137900000001],[-78.573624,70.34553499999998],[-78.57972699999988,70.34304800000007],[-78.583328,70.33692900000005],[-78.58111599999995,70.33415200000013],[-78.56916799999999,70.32554600000003],[-78.56471299999998,70.32026700000006],[-78.56138599999997,70.31414800000005],[-78.56471299999998,70.31025699999998],[-78.578888,70.309708],[-78.65527299999991,70.34693900000013],[-78.66250600000001,70.35054000000002],[-78.70472699999993,70.37469500000003],[-78.74749799999995,70.43887300000006],[-78.858337,70.45387300000004],[-78.90333599999991,70.44941699999993],[-78.94444299999986,70.45027199999998],[-79.03195199999993,70.45498700000002],[-79.07055700000001,70.46971100000007],[-79.09555099999989,70.49304200000012],[-79.100281,70.49832200000003],[-79.08168,70.52998400000013],[-79.06806899999992,70.53637700000007],[-78.89361600000001,70.59054600000013],[-78.87998999999996,70.59471100000013],[-78.86027499999989,70.59664900000007],[-78.83277900000002,70.59443700000003],[-78.82194500000003,70.58970600000009],[-78.81555199999991,70.57748400000014],[-78.81610099999995,70.57331800000003],[-78.81500199999988,70.57193000000012],[-78.80665599999998,70.56498699999997],[-78.78805499999993,70.55609100000004],[-78.7661129999999,70.55026199999998],[-78.73332199999999,70.547211],[-78.71888699999994,70.5477600000001],[-78.72027600000001,70.54914900000011],[-78.84056099999998,70.63499500000012],[-78.851944,70.63804600000009],[-78.86193800000001,70.63720699999999],[-78.86833199999995,70.63220200000012],[-78.86749299999997,70.62858600000004],[-78.86805700000002,70.62441999999999],[-78.87193300000001,70.62191800000005],[-78.87998999999996,70.62109399999991],[-78.91221599999994,70.62136800000002],[-78.96528599999994,70.63275100000004],[-78.97694399999995,70.63581799999997],[-78.99415599999998,70.643326],[-78.99916100000002,70.65138200000007],[-79.00083899999993,70.66276600000015],[-78.99472000000003,70.672485],[-79.000565,70.6769260000001],[-79.00944500000003,70.67970299999996],[-79.025284,70.68026700000013],[-79.04110700000001,70.67858899999999],[-79.05722000000003,70.67275999999998],[-79.152222,70.62776200000008],[-79.158051,70.62220800000011],[-79.15583800000002,70.61747699999995],[-79.14973399999991,70.61303700000013],[-79.13694800000002,70.61080900000002],[-79.097778,70.61026000000004],[-79.06806899999992,70.61554000000012],[-79.14389,70.45387300000004],[-79.15972899999991,70.43803400000013],[-79.17416400000002,70.42804000000012],[-79.18472300000002,70.42359900000002],[-79.20973199999997,70.418045],[-79.22389199999998,70.41943400000002],[-79.23582499999992,70.42330900000002],[-79.26889,70.43637100000001],[-79.29110699999995,70.44693000000007],[-79.29055799999992,70.45359800000006],[-79.291946,70.45971700000007],[-79.30221599999993,70.47360200000014],[-79.30833399999989,70.48027000000013],[-79.38806199999993,70.49275200000011],[-79.40361000000001,70.49331699999993],[-79.412781,70.49165299999993],[-79.42054699999994,70.48887600000006],[-79.57556199999993,70.42942800000003],[-79.58555599999994,70.42137100000002],[-79.59111000000001,70.41360500000002],[-79.59138499999995,70.40914900000007],[-79.58889799999997,70.399429],[-79.57583599999998,70.38998400000008],[-79.56361399999997,70.3855440000001],[-79.42361499999987,70.35582000000011],[-79.42054699999994,70.35971099999995],[-79.41610700000001,70.36360200000001],[-79.40666199999987,70.36747700000001],[-79.38694800000002,70.37164300000012],[-79.37165799999997,70.37109399999997],[-79.3577729999999,70.36970500000001],[-79.31723,70.3602600000001],[-79.295837,70.35304300000001],[-79.28666699999985,70.34971600000006],[-79.26611299999996,70.34109499999994],[-79.252792,70.333328],[-79.24305700000002,70.3247070000001],[-79.23332199999987,70.31860399999994],[-79.22471599999994,70.31608599999998],[-79.20944199999997,70.31330900000006],[-79.12582399999991,70.30470300000013],[-79.10888699999992,70.30497700000006],[-79.09973099999996,70.30859400000003],[-79.08667000000003,70.31776400000007],[-79.08833300000003,70.3247070000001],[-79.09056099999992,70.3294370000001],[-79.08583099999998,70.33859300000006],[-79.07084700000001,70.34082000000012],[-79.05665599999992,70.34136999999998],[-79.03889500000002,70.34054600000002],[-79.027222,70.33943200000004],[-78.98832699999997,70.33137500000004],[-78.96665999999993,70.32331800000009],[-78.93916299999995,70.31109600000013],[-78.92166099999992,70.30081200000006],[-78.79055800000003,70.20555100000001],[-78.777222,70.194977],[-78.76306199999999,70.18359399999997],[-78.75306699999987,70.16943400000008],[-78.74888599999997,70.16220100000004],[-78.73750299999995,70.11498999999998],[-78.68859900000001,70.05497700000012],[-78.68306000000001,70.04637100000002],[-78.68028299999997,70.04026800000008],[-78.66416899999996,70.00416600000011],[-78.66250600000001,69.98304700000011],[-78.66250600000001,69.97303799999992],[-78.665009,69.96138000000008],[-78.67639200000002,69.94525099999998],[-78.68777499999993,69.934418],[-78.7041779999999,69.92414899999994],[-78.791946,69.891098],[-78.84973100000002,69.88610799999998],[-79.06639100000001,69.878311],[-79.17860399999995,69.88388100000009],[-79.200287,69.88443000000001],[-79.37777699999998,69.88610799999998],[-79.40805099999994,69.88499500000006],[-79.474716,69.87858600000004],[-79.526947,69.87191800000005],[-79.54083299999996,69.86886600000014],[-79.553604,69.86470000000003],[-79.56388900000002,69.859985],[-79.57695000000001,69.85582],[-79.60499600000003,69.84999099999999],[-79.63612399999994,69.84803800000003],[-79.68249500000002,69.84887700000002],[-79.69499200000001,69.85108900000006],[-79.70722999999998,69.855545],[-79.77362099999999,69.88554400000004],[-79.78028899999998,69.89054900000008],[-79.78639199999998,69.89721700000001],[-79.79638699999992,69.90832500000005],[-79.80110199999996,69.91554300000001],[-79.80027799999999,69.91720599999996],[-79.80332900000002,69.92747500000002],[-79.83361799999994,69.94941700000004],[-79.89138799999995,69.97387700000007],[-80.05305499999992,69.99720800000011],[-80.16805999999997,70.00637799999998],[-80.19694500000003,70.0080410000001],[-80.23249799999996,70.007767],[-80.26306199999993,70.00248700000009],[-80.27305599999994,69.99971],[-80.29249600000003,69.98692299999999],[-80.30777,69.98109399999998],[-80.31361400000003,69.98027000000002],[-80.32611099999991,69.98027000000002],[-80.33612099999999,69.98220799999996],[-80.43499800000001,70.00499000000008],[-80.45777899999996,70.01332099999996],[-80.46639999999996,70.01805100000001],[-80.47444200000001,70.024429],[-80.48554999999993,70.02943400000004],[-80.54777499999994,70.04414399999996],[-80.56111099999998,70.04693600000007],[-80.57749899999988,70.04887400000001],[-80.597778,70.04803500000003],[-80.65222199999994,70.03887900000007],[-80.66999800000002,70.03997800000008],[-80.78750599999995,70.05053700000013],[-80.906387,70.07083100000006],[-81.06220999999988,70.08554100000003],[-81.22582999999997,70.09693900000002],[-81.285553,70.09526100000011],[-81.37805199999997,70.09248400000001],[-81.42999299999997,70.0935970000001],[-81.46250899999995,70.09637500000008],[-81.60305800000003,70.113876],[-81.69860799999992,70.12858599999998],[-81.71167000000003,70.13053900000011],[-81.72833300000002,70.132202],[-81.745834,70.1308140000001],[-81.75611900000001,70.12831099999994],[-81.76333599999992,70.12303199999997],[-81.76194800000002,70.11747700000006],[-81.737503,70.0935970000001],[-81.71888699999988,70.07916300000005],[-81.70973200000003,70.07443200000012],[-81.68777499999987,70.06776400000012],[-81.67054699999994,70.06526200000008],[-81.62582399999997,70.06275900000009],[-81.55833399999989,70.05693099999996],[-81.53971899999993,70.053314],[-81.531113,70.05081200000012],[-81.464722,70.02470399999999],[-81.31361399999997,70.03221100000013],[-81.26222199999995,70.01638800000006],[-81.18859900000001,69.9910890000001],[-81.16972399999997,69.982483],[-81.15333599999991,69.969986],[-81.15306099999998,69.96360800000002],[-81.1541749999999,69.958328],[-81.150284,69.94581599999998],[-81.14277599999997,69.93803400000002],[-81.136124,69.933044],[-81.12638900000002,69.92776500000002],[-81.089722,69.91387900000001],[-81.02833599999997,69.8936000000001],[-80.99999999999994,69.88610799999998],[-80.93998699999997,69.86276200000009],[-80.79138199999994,69.79054299999996],[-80.76916499999987,69.77804599999996],[-80.76417500000002,69.77053799999999],[-80.76306199999999,69.76721200000009],[-80.76306199999999,69.76081800000009],[-80.77555799999999,69.75221300000004],[-80.82611099999991,69.73359700000003],[-80.83555599999988,69.73027000000008],[-80.84944199999995,69.72720300000015],[-80.93888900000002,69.71470599999998],[-80.95249899999999,69.71388200000001],[-80.95222499999994,69.73275800000005],[-80.95584100000002,69.734421],[-81.01444999999995,69.74552900000015],[-81.023056,69.74609400000003],[-81.03805499999993,69.74859600000008],[-81.07417299999992,69.75804099999999],[-81.09306300000003,69.76443499999999],[-81.10305800000003,69.76832600000006],[-81.11555499999986,69.77693199999999],[-81.12943999999993,69.7977600000001],[-81.1458439999999,69.81248500000004],[-81.166946,69.82138099999997],[-81.17887899999994,69.824997],[-81.21665999999999,69.8336030000001],[-81.354446,69.88026400000012],[-81.43305999999995,69.91304000000008],[-81.48055999999997,69.92692600000004],[-81.49194299999988,69.92970300000013],[-81.59889199999986,69.95248400000014],[-81.68249499999996,69.96443199999999],[-81.79527300000001,69.98858600000011],[-81.94554099999988,70.03997800000008],[-81.95388799999995,70.04386899999997],[-81.95722999999998,70.04721100000006],[-81.958618,70.05276500000008],[-81.96665999999993,70.06053200000002],[-82.06500199999994,70.09582500000005],[-82.1011049999999,70.10803200000004],[-82.214447,70.134995],[-82.36166399999996,70.16137700000007],[-82.44665500000002,70.17498800000004],[-82.47500600000001,70.17942800000009],[-82.61000100000001,70.20721400000014],[-82.7391659999999,70.23776200000009],[-82.91389499999997,70.28276100000011],[-82.93888899999996,70.29220599999996],[-82.952225,70.29637099999997],[-82.97778299999999,70.30192600000004],[-82.9927669999999,70.30358899999999],[-83.006958,70.30470300000013],[-83.04804999999999,70.30693100000013],[-82.89778100000001,70.24859599999996],[-82.82223499999998,70.2208250000001],[-82.68360899999993,70.18997200000013],[-82.573624,70.17164600000012],[-82.49388099999999,70.15887500000002],[-82.41528299999999,70.14305100000007],[-82.2997279999999,70.11886600000008],[-82.10305800000003,70.06526200000008],[-81.97639500000002,70.01220699999999],[-81.84167499999995,69.96331800000002],[-81.77333099999993,69.954163],[-81.75805699999995,69.95166],[-81.72500600000001,69.94413800000007],[-81.72000100000002,69.94108599999998],[-81.71083099999998,69.93414299999995],[-81.73832700000003,69.87608300000005],[-81.74137899999988,69.87275700000004],[-81.85417199999995,69.855545],[-81.88027999999991,69.85247800000008],[-81.96028100000001,69.84414699999996],[-81.96278399999989,69.84471100000013],[-81.96333300000003,69.847488],[-81.96250899999995,69.85276800000008],[-81.96333300000003,69.85775799999993],[-81.97250399999996,69.86248799999998],[-81.99527,69.87248199999999],[-82.00167799999986,69.87469499999997],[-82.011124,69.87580900000012],[-82.02000399999986,69.87387100000001],[-82.06166100000002,69.85942100000005],[-82.11888099999987,69.81469700000008],[-82.11860699999994,69.81053200000008],[-82.12609899999995,69.78498800000006],[-82.12971500000003,69.782486],[-82.14334099999996,69.78137200000003],[-82.18998699999992,69.79026799999997],[-82.243607,69.80165099999999],[-82.27139299999999,69.82638500000013],[-82.24166899999994,69.82804899999996],[-82.22444199999995,69.82360800000004],[-82.21028099999995,69.826096],[-82.20666499999999,69.82859800000006],[-82.21501199999989,69.832764],[-82.30305499999992,69.85664400000013],[-82.31416300000001,69.85748300000012],[-82.40360999999996,69.86026000000004],[-82.41776999999996,69.85775799999993],[-82.52639799999997,69.86080900000013],[-82.57501200000002,69.87081900000004],[-82.64416499999993,69.89248700000002],[-82.74137899999994,69.91024800000014],[-83.035278,69.98803700000002],[-83.04083299999996,69.99304200000006],[-83.04444899999993,70.00416600000011],[-83.05139200000002,70.00860599999993],[-83.066666,70.01081800000003],[-83.15028399999994,70.00972000000013],[-83.23889200000002,69.99887100000007],[-83.33917199999996,69.97943100000009],[-83.34527600000001,69.97720300000009],[-83.61389199999996,69.94886800000012],[-83.65417500000001,69.94636500000013],[-83.71528599999988,69.94775400000015],[-83.89862099999999,69.96081500000008],[-83.94471699999997,69.96582000000012],[-84.00167799999997,69.97415200000012],[-84.01083399999993,69.976654],[-84.041672,69.98136900000003],[-84.08277900000002,69.9852600000001],[-84.16166699999997,69.98498500000005],[-84.31416299999995,69.97970600000008],[-84.56054699999987,69.99386600000003],[-84.65695199999999,70.00248700000009],[-84.7286069999999,70.01026900000005],[-84.78388999999999,70.01887499999998],[-85.16305499999993,70.09137000000004],[-85.17610200000001,70.09304800000012],[-85.33528099999995,70.10247800000002],[-85.35388199999994,70.103317],[-85.36915599999998,70.10359199999999],[-85.66639700000002,70.10470599999996],[-85.71972700000003,70.10359199999999],[-85.75250199999994,70.10192900000004],[-85.84722899999997,70.08888200000007],[-85.86944599999987,70.08554100000003],[-85.87499999999994,70.08332800000005],[-85.87805199999997,70.0769350000001],[-85.87609900000001,70.07193000000007],[-85.85472099999998,70.04081700000006],[-85.85166900000002,70.03831500000013],[-85.83833300000003,70.04193100000003],[-85.82695000000001,70.04637100000002],[-85.80194099999994,70.05442800000003],[-85.785278,70.0583190000001],[-85.73277299999995,70.06693999999999],[-85.69166599999994,70.07054100000005],[-85.63639799999999,70.07193000000007],[-85.61805700000002,70.07083100000006],[-85.585556,70.06749000000002],[-85.4688339999999,70.04926300000005],[-85.376938,70.03221100000013],[-85.350281,70.02638200000013],[-85.25140399999998,69.99832200000009],[-85.24305699999991,69.99498],[-85.23611499999998,69.98915099999999],[-85.23944099999994,69.98664900000006],[-85.24499500000002,69.98442100000011],[-85.25778200000002,69.98387100000008],[-85.41339099999999,69.99742900000012],[-85.44123099999996,70.00093099999998],[-85.45122499999997,70.00176999999991],[-85.57749899999993,70.00999500000012],[-85.61389200000002,70.00999500000012],[-85.63500999999991,70.00749199999996],[-85.651947,70.00360100000006],[-85.6783289999999,69.99525499999999],[-85.695267,69.99136399999992],[-85.72694399999995,69.99053999999995],[-85.808334,69.99859600000002],[-85.82333399999999,70.00027500000004],[-85.851944,70.00555400000002],[-86.09306300000003,70.06248499999998],[-86.23083500000001,70.09860200000014],[-86.25500499999993,70.10554500000012],[-86.30194099999994,70.121643],[-86.32640099999998,70.132202],[-86.551941,70.234985],[-86.556107,70.24470500000012],[-86.58111599999995,70.35693400000008],[-86.577225,70.36554000000001],[-86.55860899999999,70.386932],[-86.541946,70.40138200000013],[-86.52417000000003,70.41165200000006],[-86.512787,70.41638200000006],[-86.48110999999994,70.42469800000015],[-86.44833399999993,70.43165599999998],[-86.37304699999999,70.4458160000001],[-86.31304899999986,70.46276899999998],[-86.29499799999996,70.47276299999999],[-86.28750600000001,70.484421],[-86.29777499999994,70.49414100000013],[-86.31388900000002,70.50277700000004],[-86.33444199999997,70.51165800000012],[-86.35360700000001,70.51944000000009],[-86.36221299999994,70.52276599999993],[-86.37471,70.5252690000001],[-86.39083900000003,70.52221700000001],[-86.38999899999999,70.51998900000007],[-86.38389599999988,70.51361100000008],[-86.37554899999998,70.50888100000003],[-86.36776700000001,70.50471500000015],[-86.350281,70.49832200000003],[-86.33972199999994,70.49165299999993],[-86.339447,70.48637400000013],[-86.34056099999998,70.48387099999997],[-86.36332700000003,70.474152],[-86.37388599999997,70.47026100000011],[-86.40750100000002,70.459991],[-86.51568599999996,70.43364000000003],[-86.56500199999994,70.42553700000013],[-86.57833899999997,70.42221100000012],[-86.589722,70.41747999999995],[-86.62777699999998,70.3955380000001],[-86.65139799999997,70.37469500000003],[-86.662216,70.36109900000008],[-86.65943900000002,70.35720800000001],[-86.63833599999992,70.32443200000006],[-86.64723200000003,70.31944300000009],[-86.65556300000003,70.31887800000004],[-86.839722,70.32026700000006],[-86.86193800000001,70.32222000000002],[-86.87609900000001,70.32609600000006],[-86.88110399999994,70.32971199999997],[-86.99055499999992,70.43165599999998],[-86.98889200000002,70.43553200000002],[-86.98249799999996,70.43887300000006],[-86.95361300000002,70.44247400000012],[-86.936935,70.44331399999999],[-86.92471299999994,70.44609100000008],[-86.922775,70.44775400000003],[-86.92138699999992,70.45166000000006],[-86.92193599999996,70.45555099999996],[-86.92832900000002,70.46054100000003],[-86.93720999999994,70.46360800000014],[-86.95333899999997,70.46720900000003],[-86.96777299999991,70.46804800000012],[-86.99638400000003,70.46748400000001],[-87.03416400000003,70.46415700000006],[-87.07250999999997,70.45748900000012],[-87.08944699999995,70.45332300000001],[-87.132767,70.4391480000001],[-87.14056399999998,70.43498199999999],[-87.18222000000003,70.399429],[-87.18499800000001,70.388596],[-87.05749499999996,70.38165300000003],[-87.04388399999999,70.379974],[-87.03167699999995,70.37747200000013],[-87.01055899999994,70.37164300000012],[-86.991379,70.36415099999999],[-86.98110999999994,70.35803199999998],[-86.97277799999995,70.35192900000004],[-86.97639500000002,70.28471400000006],[-86.98582499999998,70.2816620000001],[-86.99943499999995,70.28054800000012],[-87.00917099999992,70.2810970000001],[-87.10749800000002,70.28804000000008],[-87.18443300000001,70.29553200000004],[-87.25500499999998,70.30664100000007],[-87.5625,70.32276899999994],[-87.67361499999998,70.31915300000009],[-87.66999800000002,70.29859899999997],[-87.64389,70.29582200000004],[-87.628601,70.29304500000012],[-87.61721799999998,70.2894290000001],[-87.610275,70.28471400000006],[-87.61332700000003,70.28193699999997],[-87.62388599999997,70.27804600000007],[-87.70417799999996,70.25721700000008],[-87.77694699999995,70.24331699999999],[-87.79695100000004,70.24026500000008],[-87.83389299999999,70.23803700000013],[-87.8663939999999,70.23887600000006],[-87.914444,70.24136400000009],[-87.92304999999999,70.242752],[-87.93554699999999,70.24693300000007],[-88.01282500000002,70.27726700000011],[-88.088165,70.28509500000013],[-88.13861099999991,70.29609700000003],[-88.25056499999994,70.32138100000003],[-88.26306199999993,70.3252720000001],[-88.26472499999994,70.32804900000002],[-88.256958,70.33387800000003],[-88.21417199999996,70.35137900000001],[-88.20666499999993,70.35247800000013],[-88.06177499999995,70.32954400000006],[-88.05494699999997,70.32736999999997],[-88.0501099999999,70.325043],[-88.03828399999992,70.31553600000012],[-88.03078499999992,70.31403399999999],[-88.02427699999987,70.3132020000001],[-87.99444599999998,70.31203499999998],[-87.91639700000002,70.30192600000004],[-87.9016719999999,70.30442800000014],[-87.88861099999997,70.30802900000003],[-87.87998999999996,70.31137100000012],[-87.88249200000001,70.31637599999999],[-87.88999899999999,70.32193000000001],[-87.91471899999999,70.33166500000004],[-88.083618,70.37803600000007],[-88.11193800000001,70.38415500000008],[-88.166946,70.39444000000003],[-88.37443499999995,70.43220500000012],[-88.43998699999992,70.43858300000005],[-88.57917799999996,70.45027199999998],[-88.67027299999995,70.45359800000006],[-88.67944299999999,70.45359800000006],[-88.69305399999996,70.45526100000012],[-88.797775,70.48970000000003],[-88.89750699999996,70.53276100000005],[-88.91444399999989,70.54609699999997],[-88.98582499999986,70.6083220000001],[-89.00389100000001,70.62498499999998],[-89.00917099999998,70.63638300000002],[-88.99999999999994,70.64553800000004],[-88.99972500000001,70.65165700000006],[-89.00527999999991,70.65693699999997],[-89.07667499999997,70.69693000000001],[-89.10583499999996,70.70748900000007],[-89.11888099999999,70.71138000000013],[-89.14388999999994,70.71720900000014],[-89.203888,70.73719800000003],[-89.261124,70.75972000000013],[-89.285278,70.76971400000014],[-89.33056599999992,70.79193100000003],[-89.36971999999997,70.81469700000008],[-89.37416100000002,70.81915300000014],[-89.44833399999999,70.90248100000002],[-89.4472199999999,70.90664700000008],[-89.44360399999994,70.91026299999993],[-89.43249500000002,70.91526800000003],[-89.41639700000002,70.91859400000004],[-89.37165800000002,70.92581200000006],[-89.29861499999993,70.933044],[-89.22277799999995,70.93553199999997],[-89.20944199999991,70.93914799999999],[-89.20584099999996,70.94274900000005],[-89.18859900000001,70.96081500000003],[-89.195267,70.96832300000005],[-89.20556599999992,70.97360200000003],[-89.27027900000002,70.98359700000015],[-89.31527699999992,70.99165300000004],[-89.34056099999992,70.99748200000005],[-89.35472099999993,71.00193799999994],[-89.49499499999996,71.0577550000001],[-89.54972799999996,71.08859300000012],[-89.49137899999994,71.09220900000014],[-89.46972699999998,71.09193399999992],[-89.22833300000002,71.072769],[-89.21694899999994,71.06999200000007],[-89.20861799999994,71.06303400000007],[-89.21528599999994,71.05664100000013],[-89.21806300000003,71.05081200000012],[-89.21250900000001,71.04553200000004],[-89.20306399999998,71.03804000000008],[-89.19665500000002,71.03526300000004],[-89.178604,71.03137200000015],[-89.13444499999997,71.0269320000001],[-89.11776700000001,71.02665700000011],[-89.10082999999992,71.02777100000009],[-89.07611099999997,71.03027299999997],[-89.03944399999995,71.03526300000004],[-88.97999600000003,71.04109200000005],[-88.90472399999999,71.0452580000001],[-88.68916300000001,71.04693600000002],[-88.61776700000001,71.04443400000014],[-88.49027999999998,71.0310970000001],[-88.47888199999994,71.02970900000003],[-88.43249499999996,71.02192700000006],[-88.38027999999997,71.01193199999994],[-88.36915599999998,71.00749200000013],[-88.36582900000002,71.00193799999994],[-88.36332699999997,70.99552900000009],[-88.362503,70.99026500000014],[-88.36277799999999,70.98414600000007],[-88.36027499999994,70.97776799999997],[-88.35694899999999,70.97221400000012],[-88.34361299999995,70.96138000000008],[-88.33250399999997,70.95721399999996],[-88.3186189999999,70.95387299999993],[-88.28971899999993,70.9502720000001],[-88.26083399999999,70.94775400000009],[-88.02528399999994,70.93054200000006],[-87.99999999999989,70.9291530000001],[-87.96888699999988,70.92858899999993],[-87.93055700000002,70.92942800000009],[-87.912781,70.93136600000003],[-87.8577729999999,70.94136000000003],[-87.79804999999993,70.94970700000005],[-87.752792,70.95359800000011],[-87.699997,70.95555100000007],[-87.66444399999995,70.95471200000009],[-87.62748699999986,70.95138500000013],[-87.61054999999993,70.94941700000004],[-87.55943300000001,70.9474790000001],[-87.43582200000003,70.944977],[-87.371216,70.94472500000012],[-87.35360700000001,70.94525099999993],[-87.345551,70.94941700000004],[-87.34306300000003,70.95416299999994],[-87.343613,70.95942700000012],[-87.33778399999989,70.969986],[-87.32917799999996,70.980545],[-87.30860899999999,70.99552900000009],[-87.29888900000003,71],[-87.28611799999999,71.00416600000011],[-87.26722699999988,71.00694299999998],[-87.24694799999992,71.00915500000008],[-87.21250899999995,71.00749200000013],[-87.15139799999986,71],[-87.141388,70.99775700000004],[-87.11610399999995,70.99470500000012],[-87.05139200000002,70.98776199999998],[-87.033615,70.98664900000006],[-87.01750199999992,70.98664900000006],[-87.0041809999999,70.99026500000014],[-87.00306699999999,70.9910890000001],[-87.002792,70.99414100000001],[-87.00973499999998,70.99609399999997],[-87.039444,71.00082399999997],[-87.13500999999997,71.01138300000002],[-87.16639700000002,71.0144350000001],[-87.18443300000001,71.01527400000009],[-87.27917500000001,71.0269320000001],[-87.38583399999999,71.04193099999998],[-87.39472999999998,71.0435940000001],[-87.40472399999993,71.04721100000006],[-87.41082799999998,71.053314],[-87.47277799999995,71.07415799999995],[-87.57278399999996,71.09526100000005],[-87.70140099999998,71.12330600000007],[-87.712784,71.126083],[-87.76028399999996,71.14305100000007],[-87.84889199999986,71.18498200000005],[-87.85194399999995,71.19192500000003],[-87.85249299999998,71.19720500000011],[-87.848343,71.20220900000004],[-87.82528699999995,71.21720900000003],[-87.823059,71.22360199999997],[-87.81666599999994,71.25471499999998],[-87.82194500000003,71.25833100000006],[-87.82945299999994,71.26193200000012],[-87.84416199999993,71.26416000000006],[-87.900284,71.26860000000005],[-87.91166699999991,71.26693699999998],[-87.97193899999996,71.25027499999999],[-88.01972999999998,71.23609899999997],[-88.03416399999998,71.23165899999998],[-88.04194599999994,71.22886700000004],[-88.131104,71.21914700000013],[-88.32167099999998,71.22859200000005],[-88.583618,71.234985],[-88.70666499999993,71.24775699999998],[-88.84999099999999,71.25972000000002],[-89.058044,71.27638200000001],[-89.20666499999993,71.28332500000005],[-89.29916399999996,71.2874910000001],[-89.42860399999995,71.29443400000008],[-89.703888,71.31581100000011],[-89.816666,71.32499700000005],[-89.83000199999998,71.32887299999999],[-89.89973399999991,71.35137900000012],[-89.90722700000003,71.35470600000008],[-89.964722,71.41137700000002],[-89.968613,71.41693100000003],[-89.98306300000002,71.44693000000001],[-90.01055899999989,71.57777400000009],[-90.01306199999993,71.60026600000003],[-90.00472999999994,71.63081399999999],[-90.00306699999993,71.63581799999997],[-89.99722300000002,71.64137300000004],[-89.964722,71.65582299999994],[-89.93276999999995,71.66775500000011],[-89.89611799999994,71.67997700000006],[-89.88473499999992,71.684708],[-89.81750499999998,71.72470100000004],[-89.808334,71.74775700000009],[-89.82139599999994,71.76026900000005],[-89.83138999999994,71.76026900000005],[-89.83612099999999,71.76165800000007],[-89.84306299999997,71.76443499999999],[-89.89361599999995,71.78942899999993],[-89.954453,71.82054100000005],[-89.96028100000001,71.82415800000001],[-90.02667200000002,71.89276100000006],[-90.04861499999998,71.9538730000001],[-90.00111399999992,72.06303400000007],[-89.99305700000002,72.07054099999999],[-89.962784,72.07748399999997],[-89.81221,72.11192300000005],[-89.75083899999993,72.12303199999991],[-89.73889199999996,72.12498500000004],[-89.72582999999997,72.12469500000003],[-89.718887,72.12191799999994],[-89.71583599999997,72.11859100000004],[-89.70472699999999,72.11331200000001],[-89.69166599999994,72.10998500000011],[-89.6824949999999,72.11053500000014],[-89.66471899999993,72.11331200000001],[-89.59750399999996,72.1483310000001],[-89.57972699999999,72.15887499999997],[-89.57472199999995,72.16360500000002],[-89.57667499999997,72.16914400000002],[-89.58473200000003,72.17581199999995],[-89.59889199999998,72.17804000000012],[-89.61805700000002,72.17886400000009],[-89.67666599999995,72.17692599999998],[-89.70584100000002,72.17469799999998],[-89.724716,72.17248500000005],[-89.73889199999996,72.16859399999998],[-89.75944500000003,72.15998800000006],[-89.77055399999995,72.15748599999995],[-89.78056300000003,72.15748599999995],[-89.80248999999992,72.161926],[-89.89222699999999,72.18691999999999],[-89.89723200000003,72.18858300000005],[-89.90139799999992,72.19413799999995],[-89.93943799999994,72.26193200000006],[-89.95417799999996,72.30497700000006],[-89.95750399999991,72.3160860000001],[-89.95666499999993,72.32165500000013],[-89.91332999999997,72.42221100000006],[-89.90750099999997,72.43220500000007],[-89.89056399999987,72.44497700000005],[-89.87249799999995,72.44914200000005],[-89.860275,72.45109600000012],[-89.81361399999997,72.45665000000008],[-89.79943800000001,72.46026599999999],[-89.79360999999989,72.46276899999992],[-89.777222,72.49386600000003],[-89.77528399999989,72.49859600000008],[-89.77250699999996,72.51998900000001],[-89.77278100000001,72.526093],[-89.78666699999997,72.55998200000005],[-89.75389099999995,72.60554499999995],[-89.73693799999995,72.61665299999999],[-89.69999699999994,72.62525900000009],[-89.67832900000002,72.62942499999997],[-89.65695199999999,72.63026400000012],[-89.64361600000001,72.62692300000009],[-89.61471599999999,72.61608900000004],[-89.59750399999996,72.61470000000003],[-89.57278400000001,72.61692800000014],[-89.56054699999993,72.62191800000005],[-89.47055099999994,72.66609199999999],[-89.47361799999987,72.67248500000011],[-89.51194799999996,72.688873],[-89.525284,72.69386300000002],[-89.54916400000002,72.69108599999993],[-89.56750499999993,72.69303900000006],[-89.57472199999995,72.69886800000006],[-89.58000199999992,72.71110500000003],[-89.58139,72.71775800000006],[-89.57472199999995,72.78526300000004],[-89.56945799999994,72.78692599999994],[-89.479446,72.77970900000003],[-89.44638099999992,72.77554299999997],[-89.36471599999993,72.76220699999999],[-89.33056599999992,72.755829],[-89.29415899999992,72.79721100000006],[-89.333328,72.95054600000014],[-89.358337,72.96527100000009],[-89.36138899999997,72.99165299999999],[-89.30888399999998,73.04832499999998],[-89.22833300000002,73.125809],[-89.04333500000001,73.25248699999997],[-89.03582799999998,73.25749200000001],[-89.00028999999995,73.27832000000012],[-88.99055499999997,73.28359999999998],[-88.85694899999999,73.33610500000003],[-88.69583099999994,73.41192600000011],[-88.68360899999999,73.41748000000007],[-88.46806299999997,73.49192800000009],[-88.43331899999993,73.51415999999995],[-88.40916400000003,73.52360500000003],[-88.28639199999998,73.56693999999999],[-88.26306199999993,73.57388300000002],[-88.0747219999999,73.62776200000002],[-87.97444199999995,73.65470900000014],[-87.92332499999992,73.66775500000006],[-87.81723,73.69442700000013],[-87.78028899999998,73.70304899999996],[-87.73999000000003,73.71138000000008],[-87.539444,73.74664300000006],[-87.45666499999999,73.76026900000005],[-87.18360899999993,73.79275500000011],[-87.04943800000001,73.80831900000004],[-86.71665999999999,73.84082000000012],[-86.59666399999998,73.84526100000005],[-86.49305700000002,73.84443700000008],[-86.40139799999992,73.84582499999999],[-86.239441,73.84915200000012],[-86.208618,73.8499910000001],[-86.10916099999997,73.8499910000001],[-85.747772,73.83638000000013],[-85.70666499999999,73.83221400000002],[-85.55305499999997,73.820831],[-85.52000399999997,73.81999200000007],[-85.46250899999995,73.820831],[-85.42193600000002,73.82415800000012],[-85.30777,73.82110600000004],[-85.16332999999986,73.81330900000006],[-85.12110899999993,73.80998199999999],[-85.10499599999997,73.80802900000003],[-85.06945799999988,73.8019260000001],[-85.03472899999991,73.79470800000007],[-84.97000100000002,73.77777100000009],[-84.837784,73.74165299999999],[-84.84277299999997,73.73580900000002],[-84.86555499999992,73.71331800000002],[-84.92250100000001,73.68026700000007],[-84.93138099999999,73.67553700000002],[-84.95611600000001,73.66526799999997],[-84.98500099999995,73.65582300000011],[-85.34083599999985,73.55636600000014],[-85.59638999999999,73.48664900000011],[-85.76640299999985,73.42526200000003],[-85.85110499999996,73.391098],[-85.93028299999997,73.355255],[-86.04666099999986,73.28720100000004],[-86.137787,73.22886700000004],[-86.29222099999998,73.10331700000012],[-86.29638699999998,73.09748800000006],[-86.29444899999993,73.09109500000011],[-86.28889500000002,73.08720400000004],[-86.28443900000002,73.08248900000001],[-86.28416399999998,73.07720899999998],[-86.287216,73.072495],[-86.32833900000003,73.03665199999995],[-86.45445299999989,72.96360799999997],[-86.474716,72.95332300000007],[-86.49526999999989,72.94331400000004],[-86.50556899999998,72.938309],[-86.57112099999995,72.90887500000002],[-86.62721299999993,72.88360599999999],[-86.64750699999996,72.87330600000007],[-86.65361000000001,72.86886600000008],[-86.65833999999995,72.86360200000007],[-86.69554099999999,72.81915300000014],[-86.69665499999996,72.81666600000005],[-86.73277300000001,72.71609500000011],[-86.70333900000003,72.65914899999996],[-86.69833399999999,72.65220599999998],[-86.686935,72.64471400000002],[-86.662216,72.63165300000009],[-86.63833599999992,72.62052900000003],[-86.61138900000003,72.60914600000001],[-86.50418100000002,72.56860400000005],[-86.47972099999998,72.56053200000008],[-86.46611000000001,72.55636599999997],[-86.45140100000003,72.55304000000012],[-86.41444399999995,72.54165600000005],[-86.39723200000003,72.53498800000006],[-86.35305799999998,72.51165800000007],[-86.33805799999999,72.50305199999997],[-86.28306600000002,72.46832300000011],[-86.27583299999998,72.46331800000007],[-86.26777600000003,72.4563750000001],[-86.25500499999993,72.44358800000009],[-86.24082900000002,72.4202580000001],[-86.24082900000002,72.40664700000013],[-86.24610899999999,72.39498900000012],[-86.25805700000001,72.38443000000007],[-86.27528399999994,72.37387100000001],[-86.308044,72.35914600000007],[-86.35082999999992,72.33915699999994],[-86.37777699999992,72.32360800000004],[-86.39611799999994,72.30914300000012],[-86.42805499999992,72.28193700000008],[-86.43582200000003,72.27026400000005],[-86.45527600000003,72.20721400000008],[-86.43443299999996,72.04998799999993],[-86.43249500000002,72.04332],[-86.42582700000003,72.02499399999999],[-86.420547,72.01277199999998],[-86.33667000000003,71.95193499999999],[-86.16610700000001,71.824997],[-86.13276699999994,71.7958220000001],[-86.11054999999999,71.783051],[-86.07861300000002,71.77554299999997],[-86.05166600000001,71.77165200000007],[-86.02444499999996,71.76582300000007],[-85.94721999999996,71.72692899999998],[-85.90556300000003,71.69970700000005],[-85.87193300000001,71.67692600000004],[-85.50083899999998,71.51110800000009],[-85.39195299999994,71.48165900000009],[-85.37416100000002,71.47886699999998],[-85.22860699999995,71.46554600000007],[-84.94860799999998,71.42164600000007],[-84.93472300000002,71.41832],[-84.92999299999997,71.4144290000001],[-84.85916099999997,71.32110599999999],[-84.83805799999993,71.29193099999992],[-84.83416699999998,71.28526299999999],[-84.83277899999996,71.27886999999998],[-84.83389299999993,71.27415499999995],[-84.835556,71.27165200000002],[-84.848343,71.26944000000015],[-84.868607,71.2688750000001],[-84.92166099999997,71.27082800000005],[-85.041946,71.278595],[-85.1725009999999,71.27249099999995],[-85.17388899999997,71.26998900000007],[-85.17832900000002,71.266388],[-85.38999899999993,71.19664000000006],[-85.39999399999994,71.19386299999996],[-85.50028999999995,71.17720000000008],[-85.514725,71.17608600000011],[-85.53250100000002,71.17720000000008],[-85.66305499999999,71.19442700000013],[-85.76139799999999,71.19220000000007],[-85.83833300000003,71.18748500000004],[-85.93276999999995,71.17886400000009],[-85.96665999999993,71.17109700000015],[-86.17083699999995,71.10693400000008],[-86.21083099999998,71.09387200000009],[-86.21444699999995,71.08970599999998],[-86.206955,71.08387800000008],[-86.20611599999995,71.07804900000002],[-86.212784,71.072769],[-86.24888599999997,71.05859400000008],[-86.28860500000002,71.05220000000003],[-86.408051,71.03526300000004],[-86.45083599999992,71.03137200000015],[-86.51777599999997,71.03166199999998],[-86.64389,71.01943999999997],[-86.74999999999994,71.00776699999994],[-86.7702789999999,71.00416600000011],[-86.785553,71.00027500000004],[-86.79861499999998,70.99636800000007],[-86.81916799999988,70.98942599999998],[-86.82000700000003,70.98858600000011],[-86.80665599999998,70.98387100000008],[-86.75778200000002,70.97665399999994],[-86.71305799999993,70.97415200000006],[-86.60194399999995,70.97164900000007],[-86.54750099999995,70.9788670000001],[-86.43028300000003,70.98887600000012],[-86.29222099999998,71.00027500000004],[-86.27027900000002,71.0027770000001],[-86.22416699999985,71.0144350000001],[-86.026947,71.07138100000009],[-85.83250399999991,71.12719700000014],[-85.80221599999999,71.13581800000003],[-85.77917499999995,71.13916],[-85.67027300000001,71.14888000000008],[-85.650284,71.149429],[-85.50500499999998,71.15803499999993],[-85.41166699999997,71.17442299999999],[-85.39167800000001,71.17498800000004],[-85.28860500000002,71.15914900000013],[-85.27416999999991,71.15525800000006],[-85.11054999999999,71.16165200000006],[-85.04222099999993,71.18165600000003],[-85.037216,71.18304400000011],[-84.99888599999997,71.18748500000004],[-84.96167000000003,71.18858300000011],[-84.94415299999997,71.18719500000003],[-84.87527499999999,71.1727600000001],[-84.84999099999999,71.15470900000008],[-84.84584000000001,71.1477660000001],[-84.87110899999999,71.07360799999992],[-84.87582399999985,71.06999200000007],[-84.87971499999992,71.06944299999992],[-84.90417500000001,71.07804900000002],[-84.93582199999997,71.09248399999996],[-84.95056199999993,71.09693900000002],[-84.96611000000001,71.10026600000009],[-84.9808349999999,71.101089],[-85.00111400000003,71.10081500000007],[-85.14222699999993,71.08638000000013],[-85.14695699999999,71.08276400000005],[-85.11277799999993,71.07916300000005],[-85.06138599999991,71.07638500000002],[-84.99221799999998,71.07748400000003],[-84.9766689999999,71.07582100000008],[-84.96028100000001,71.07222000000002],[-84.92971799999998,71.00444000000005],[-84.92694099999994,70.98803700000013],[-84.93028299999997,70.98165900000004],[-84.94137599999999,70.9705350000001],[-84.95083599999998,70.96554600000013],[-84.96333300000003,70.95582600000006],[-84.975281,70.94525099999993],[-84.97610500000002,70.93331899999998],[-84.97083999999995,70.92747499999996],[-84.96472199999994,70.92248500000011],[-84.958618,70.91943400000008],[-84.94110099999995,70.91804500000006],[-84.81416299999995,70.91943400000008],[-84.79888899999997,70.92164600000012],[-84.79361,70.92665099999999],[-84.74833699999999,70.97553999999997],[-84.74804699999999,70.98803700000013],[-84.771118,71.03749099999999],[-84.803604,71.04721100000006],[-84.81916799999999,71.05748000000011],[-84.827789,71.06832899999995],[-84.82972699999988,71.07331799999992],[-84.828888,71.07998700000002],[-84.82667500000002,71.08554100000015],[-84.80139200000002,71.14860500000003],[-84.766663,71.19747900000004],[-84.77084399999995,71.25499000000002],[-84.78138699999994,71.26193200000012],[-84.78666699999991,71.26776100000012],[-84.79305999999997,71.27804600000002],[-84.79666099999992,71.29748500000011],[-84.79722600000002,71.30331400000011],[-84.7625119999999,71.40664699999996],[-84.74943499999995,71.41665599999999],[-84.73194899999993,71.42469800000015],[-84.720551,71.428314],[-84.69305399999996,71.434143],[-84.67832900000002,71.43525700000004],[-84.66000400000001,71.43165599999998],[-84.65306099999992,71.43193100000013],[-84.57167099999992,71.440811],[-84.55749500000002,71.44413800000012],[-84.54777499999994,71.44747899999999],[-84.53916900000002,71.45166000000006],[-84.53195199999993,71.45694000000015],[-84.52610800000002,71.46887200000009],[-84.52639799999992,71.47831699999995],[-84.53056300000003,71.49247700000006],[-84.53361499999994,71.50248699999997],[-84.54666099999997,71.52748099999997],[-84.55471799999992,71.5410920000001],[-84.56138599999991,71.54998800000004],[-84.56443799999994,71.55247500000013],[-84.610275,71.56275900000014],[-84.63639799999993,71.5705410000001],[-84.64862099999999,71.57638500000013],[-84.65834000000001,71.58387800000014],[-84.65499899999998,71.60887100000002],[-84.65306099999992,71.61276200000009],[-84.64250199999998,71.62275700000004],[-84.62554899999998,71.63304100000005],[-84.61054999999999,71.64166300000005],[-84.604446,71.64610300000004],[-84.60665899999992,71.64942900000011],[-84.625,71.665817],[-84.62805200000003,71.66831999999994],[-84.635559,71.6702580000001],[-84.64973399999997,71.672211],[-84.71083099999993,71.676086],[-84.77305599999994,71.67858899999999],[-84.78277600000001,71.67886399999998],[-84.82749899999999,71.67526200000003],[-84.86721799999992,71.66804500000012],[-84.88620000000003,71.6542510000001],[-84.92666600000001,71.63610799999998],[-84.975281,71.64444000000015],[-85.09750399999996,71.65525800000012],[-85.176941,71.65664700000013],[-85.19665500000002,71.65582299999994],[-85.23083500000001,71.65998799999994],[-85.26390099999998,71.66554300000007],[-85.27972399999999,71.66859400000004],[-85.291382,71.672211],[-85.57084699999996,71.77998400000007],[-85.57972699999999,71.78498800000006],[-85.57362399999994,71.79081700000006],[-85.55777,71.79525799999999],[-85.54388399999993,71.7955320000001],[-85.45889299999999,71.79414399999996],[-85.44972199999995,71.79609700000009],[-85.43693499999995,71.80081200000012],[-85.43276999999995,71.80636600000014],[-85.43194599999998,71.81469700000002],[-85.4344329999999,71.81805399999996],[-85.55166600000001,71.89637800000003],[-85.55972299999996,71.90054300000003],[-85.74499500000002,71.94136000000003],[-85.8458399999999,71.96249400000005],[-85.90083299999998,71.96914700000002],[-85.93998699999997,71.97303800000009],[-85.96333300000003,71.974426],[-86.00250199999999,71.97804300000013],[-86.02278100000001,71.980545],[-86.02667200000002,71.98165899999998],[-86.03916900000002,71.98887600000012],[-86.04361,71.99552900000009],[-86.05082700000003,72.01110799999998],[-86.04750100000001,72.01388500000007],[-85.98111,72.028595],[-85.778885,72.0269320000001],[-85.53832999999997,72.059143],[-85.50944499999991,72.06805400000013],[-85.49527,72.07887299999999],[-85.44055200000003,72.1327510000001],[-85.44915800000001,72.1583250000001],[-85.48194899999993,72.17330900000002],[-85.50167799999997,72.18414300000006],[-85.50250199999999,72.25166300000006],[-85.49749799999995,72.25526400000012],[-85.48721299999994,72.260269],[-85.29194599999988,72.25999500000006],[-85.27194199999997,72.25972000000002],[-85.02917500000001,72.25082400000008],[-85.01333599999998,72.25000000000011],[-84.93638599999991,72.23580900000013],[-84.91999799999996,72.2327580000001],[-84.86776699999996,72.22082500000005],[-84.86138899999992,72.21775800000012],[-84.84750400000001,72.20555099999996],[-84.83917200000002,72.19413799999995],[-84.81527699999992,72.18136600000014],[-84.8033289999999,72.17776500000008],[-84.710556,72.15165699999994],[-84.612213,72.14109800000011],[-84.59583999999995,72.13777200000004],[-84.51222200000001,72.11415099999999],[-84.28639199999998,72.028595],[-84.27555799999993,72.02387999999996],[-84.269455,72.02082800000005],[-84.261124,72.01609800000006],[-84.2580569999999,72.01193200000012],[-84.25,71.99832200000009],[-84.23998999999992,71.97387700000002],[-84.23638900000003,71.96165500000006],[-84.23055999999985,71.95138500000013],[-84.22500600000001,71.94552599999992],[-84.218887,71.94026200000013],[-84.20861799999989,71.93414300000012],[-84.19444299999998,71.93081700000005],[-84.18472299999996,71.93054200000006],[-84.17832900000002,71.93275500000004],[-84.17277499999994,71.93775900000014],[-84.16888399999988,71.94413800000001],[-84.158615,71.97720300000009],[-84.16471899999988,72.0211030000001],[-84.171112,72.02415500000001],[-84.21806300000003,72.04414400000013],[-84.27000399999991,72.051086],[-84.28582799999998,72.05415299999993],[-84.31973299999987,72.0619200000001],[-84.34666399999998,72.06971700000003],[-84.35777299999995,72.07638500000002],[-84.37999000000002,72.10832199999999],[-84.38055399999996,72.12359600000008],[-84.45611600000001,72.13360599999999],[-84.47332799999998,72.13581800000003],[-84.61332699999991,72.16360500000002],[-84.65222199999994,72.17886400000009],[-84.72193900000002,72.21304300000008],[-84.93331899999993,72.284424],[-84.93527199999994,72.28942900000004],[-84.91749599999997,72.29971300000005],[-84.82945299999994,72.3483280000001],[-84.816101,72.35276799999991],[-84.80139200000002,72.35470600000008],[-84.76972999999998,72.35636899999997],[-84.715012,72.35582000000005],[-84.66194199999995,72.35415600000005],[-84.56500199999999,72.34887700000007],[-84.52111799999994,72.35054000000014],[-84.50083899999993,72.3538670000001],[-84.48443599999996,72.3580320000001],[-84.43611099999993,72.37498499999998],[-84.43306000000001,72.37831100000005],[-84.44221500000003,72.38304100000005],[-84.45333900000003,72.38247700000011],[-84.47138999999993,72.37942500000003],[-84.57167099999992,72.36137400000001],[-84.86416600000001,72.36692800000003],[-84.872772,72.36943100000002],[-84.87609899999995,72.37220800000011],[-84.87554899999992,72.39498900000012],[-84.870834,72.40081800000013],[-84.85777299999995,72.40554799999995],[-84.83667000000003,72.40803500000004],[-84.81750499999998,72.40664700000013],[-84.80027799999999,72.40664700000013],[-84.78666699999991,72.40887500000008],[-84.76834100000002,72.44442700000002],[-84.76722699999993,72.44747899999999],[-84.76834100000002,72.45193500000005],[-84.771118,72.45748900000007],[-84.776947,72.458328],[-84.791946,72.45498699999996],[-84.91860999999994,72.42526200000009],[-85.00834700000001,72.39942900000011],[-85.02166699999998,72.39471400000008],[-85.14472999999992,72.35942100000011],[-85.33901999999995,72.40641800000003],[-85.37027,72.41470300000003],[-85.515289,72.45887800000003],[-85.53527799999995,72.46971100000002],[-85.61000100000001,72.53166200000004],[-85.61805700000002,72.54081700000006],[-85.61721799999998,72.5455320000001],[-85.61389200000002,72.55026199999998],[-85.59861799999993,72.555252],[-85.50834700000001,72.56137100000001],[-85.48611499999993,72.56498700000009],[-85.47805799999998,72.568329],[-85.473053,72.57193000000007],[-85.47555499999999,72.57527200000004],[-85.48111,72.57748400000008],[-85.49999999999994,72.58027600000014],[-85.55999800000001,72.58248900000012],[-85.62388599999991,72.58692899999994],[-85.641953,72.59275799999995],[-85.65417499999995,72.59803800000003],[-85.66471899999993,72.60554499999995],[-85.70306399999993,72.63415500000002],[-85.70527600000003,72.63777199999998],[-85.70777899999996,72.64637800000008],[-85.70944199999991,72.73692299999999],[-85.68804899999998,72.89359999999999],[-85.68472300000002,72.89833099999993],[-85.67944299999999,72.90359500000011],[-85.59222399999999,72.95915200000007],[-85.58168,72.96415700000011],[-85.57055700000001,72.96693400000004],[-85.54916400000002,72.96971100000013],[-85.49972500000001,72.974152],[-85.48194899999993,72.974152],[-85.37887599999993,72.97110000000009],[-85.28306600000002,72.96443199999993],[-85.25750700000003,72.96081499999997],[-85.12748699999997,72.94026200000013],[-85.07749899999993,72.92997700000001],[-85.015015,72.9160920000001],[-84.96665999999999,72.90498400000013],[-84.93249499999996,72.89637800000003],[-84.87443499999995,72.88554399999992],[-84.819458,72.88026400000007],[-84.70750399999997,72.86998000000006],[-84.66861,72.86747700000006],[-84.61082499999992,72.86164900000011],[-84.50445599999995,72.84610000000004],[-84.43721,72.83360300000004],[-84.40499899999992,72.82609600000012],[-84.38945000000001,72.82222000000002],[-84.32084700000001,72.80081200000012],[-84.29110700000001,72.79165599999999],[-84.25750700000003,72.78526300000004],[-84.18832399999997,72.77442899999994],[-83.99137899999994,72.7458190000001],[-83.97222899999997,72.74414100000001],[-83.958054,72.74664300000006],[-83.95527599999991,72.74832200000009],[-83.95306399999993,72.75248700000009],[-83.95639,72.75499000000008],[-83.989441,72.76887499999998],[-84.04083299999996,72.77748100000008],[-84.073624,72.78166199999998],[-84.10804699999994,72.78526300000004],[-84.218613,72.79498300000012],[-84.24694799999997,72.79971299999994],[-84.29138199999994,72.81248499999998],[-84.311935,72.82026700000011],[-84.33528099999995,72.82998700000002],[-84.41915899999992,72.85331699999995],[-84.528885,72.88247700000005],[-84.57722499999994,72.89221200000009],[-84.65249599999999,72.89942900000005],[-84.70639,72.90582300000005],[-84.74360699999994,72.91081200000002],[-84.76055899999994,72.914154],[-84.79110700000001,72.92137100000008],[-84.85583500000001,72.93748500000004],[-84.87026999999995,72.94220000000007],[-85.05999800000001,72.996643],[-85.22360999999995,73.01498400000003],[-85.51390100000003,73.01914999999991],[-85.53527799999995,73.021927],[-85.537216,73.02832000000001],[-85.47193900000002,73.09803799999992],[-85.44776899999994,73.12025499999999],[-85.44027699999998,73.12553399999996],[-85.42944299999994,73.13053900000006],[-85.41583299999996,73.13526900000005],[-85.40695199999993,73.13638300000002],[-85.395554,73.1355440000001],[-85.37999000000002,73.13360599999993],[-85.37332200000003,73.13081400000004],[-85.36999500000002,73.12831100000005],[-85.36389199999996,73.12081899999993],[-85.35943599999996,73.11387600000012],[-85.35804699999994,73.10971100000012],[-85.333618,73.09248400000013],[-85.30027799999993,73.07804900000002],[-85.25688899999994,73.0714870000001],[-85.24806199999995,73.06864900000011],[-85.24089100000003,73.06681800000013],[-85.18805700000001,73.05981400000007],[-85.17588799999999,73.0586550000001],[-85.16638899999998,73.06065400000011],[-85.17139399999996,73.06631500000009],[-85.15249599999999,73.07276900000011],[-85.186935,73.09693900000013],[-85.22694399999995,73.11581400000006],[-85.229172,73.12303200000008],[-85.22778299999999,73.12915000000004],[-85.223053,73.13472000000013],[-85.21362299999998,73.13888500000013],[-85.19193999999999,73.14166300000011],[-85.14834599999995,73.14166300000011],[-85.08917199999996,73.137497],[-85.05332900000002,73.13220200000012],[-85.00306699999987,73.12191800000011],[-84.98860200000001,73.11692800000009],[-84.92138699999998,73.09832799999992],[-84.90417500000001,73.09526100000005],[-84.82972699999988,73.08554100000015],[-84.77278100000001,73.08110000000005],[-84.55665599999998,73.06442300000003],[-84.21250899999995,73.04026800000003],[-84.07722499999994,73.03387500000008],[-83.92332499999992,73.03360000000004],[-83.8677669999999,73.02970900000014],[-83.84973100000002,73.02748100000002],[-83.83250399999997,73.02415500000001],[-83.76139799999993,73.0063780000001],[-83.718887,72.9891510000001],[-83.63444500000003,72.98248300000012],[-83.63333099999994,72.9833220000001],[-83.63444500000003,72.98637400000001],[-83.648346,72.99136400000003],[-83.69249000000002,73.00555400000013],[-83.77667200000002,73.03109700000005],[-83.87971500000003,73.05192600000004],[-83.91361999999992,73.05831899999998],[-83.93472300000002,73.06109600000008],[-83.95584100000002,73.06164600000011],[-83.974716,73.06080600000007],[-84.03971899999999,73.05636600000008],[-84.05972300000002,73.05636600000008],[-84.09500100000002,73.05831899999998],[-84.197495,73.06860400000011],[-84.23693800000001,73.08110000000005],[-84.24804699999999,73.083328],[-84.275284,73.08692900000005],[-84.43388400000003,73.10609399999998],[-84.53111299999995,73.1102600000001],[-84.54750100000001,73.11137400000007],[-84.58444199999997,73.11581400000006],[-84.73638900000003,73.13720699999999],[-84.789444,73.14582800000011],[-84.86500499999988,73.16360499999996],[-84.91278099999994,73.17553700000013],[-84.94221500000003,73.18165599999998],[-84.985275,73.19053600000001],[-85.02000399999997,73.19693000000007],[-85.058334,73.20054600000009],[-85.10055499999999,73.20138500000007],[-85.13806199999993,73.20443699999998],[-85.17054699999994,73.21081500000014],[-85.17721599999993,73.21388200000007],[-85.18443300000001,73.21887200000009],[-85.18859900000001,73.22360200000014],[-85.18859900000001,73.22886700000004],[-85.13890099999998,73.29998800000004],[-85.13417099999998,73.30554200000006],[-85.11582899999996,73.31442300000015],[-85.07778899999988,73.32943700000004],[-85.01722699999999,73.3483280000001],[-84.97999600000003,73.35664399999996],[-84.80804399999994,73.38832100000013],[-84.78694200000001,73.38804600000009],[-84.75639299999995,73.38108800000009],[-84.741669,73.37608300000005],[-84.72193900000002,73.36219800000015],[-84.71278399999994,73.34860200000003],[-84.69499200000001,73.32693499999999],[-84.685272,73.31999199999996],[-84.65499899999998,73.30554200000006],[-84.424713,73.23248300000006],[-84.40888999999999,73.22859199999999],[-84.39250199999992,73.226089],[-84.37721299999993,73.224152],[-84.3552699999999,73.22303799999997],[-84.33944699999995,73.226089],[-84.34777799999995,73.23248300000006],[-84.41305499999999,73.27221700000001],[-84.45111099999997,73.28858899999994],[-84.46083099999998,73.29193100000009],[-84.48971599999993,73.29971300000005],[-84.56361399999997,73.31387300000011],[-84.57667499999991,73.31776400000001],[-84.58694500000001,73.3230440000001],[-84.597778,73.33082600000006],[-84.65360999999996,73.38720699999993],[-84.656113,73.39054900000008],[-84.65222199999994,73.393326],[-84.64222699999993,73.39721700000007],[-84.625,73.40138200000007],[-84.58389299999999,73.40914900000001],[-84.43415799999997,73.43525699999998],[-84.28443899999996,73.46110500000009],[-84.229172,73.47026100000005],[-84.19444299999998,73.47470100000004],[-84.17138699999992,73.47526600000009],[-84.11389200000002,73.46914700000008],[-83.75192300000003,73.42749000000003],[-83.72471599999994,73.41304000000008],[-83.71777299999997,73.405823],[-83.71972699999998,73.39971900000012],[-83.72471599999994,73.3938750000001],[-83.72805800000003,73.38108800000009],[-83.72055099999994,73.36581400000006],[-83.71221899999995,73.35192899999993],[-83.70249899999988,73.33915700000011],[-83.68943799999994,73.32360800000004],[-83.66583300000002,73.30775499999999],[-83.65750099999997,73.3035890000001],[-83.648056,73.30026199999998],[-83.63082899999995,73.29721099999995],[-83.61389199999996,73.29609700000015],[-83.60055499999993,73.29748500000005],[-83.59306299999997,73.30137599999995],[-83.59083599999991,73.30720499999995],[-83.59110999999996,73.313309],[-83.59416199999998,73.32527200000004],[-83.62499999999994,73.41526800000003],[-83.63333099999994,73.42886400000003],[-83.64250199999998,73.43969699999997],[-83.65249599999999,73.44525099999998],[-83.66389500000002,73.4497070000001],[-83.67971799999992,73.45387299999999],[-83.69694500000003,73.45721400000002],[-83.754456,73.46331800000007],[-83.81054699999993,73.47053499999998],[-83.95472699999993,73.49275200000005],[-83.97860699999995,73.49664300000012],[-83.993607,73.50027500000004],[-84.00418099999996,73.50416600000011],[-84.00695799999994,73.50972000000013],[-83.99694799999997,73.51388500000013],[-83.979172,73.51805100000001],[-83.74082899999996,73.56776399999995],[-83.57749899999999,73.59637500000008],[-83.445267,73.615814],[-83.21916199999987,73.65664700000008],[-83.08528099999995,73.65776100000005],[-83.01834099999991,73.66609199999994],[-82.931107,73.69053600000007],[-82.90222199999994,73.70027200000004],[-82.88999899999999,73.70526100000001],[-82.87277199999988,73.71554600000013],[-82.86972000000003,73.72109999999998],[-82.86332699999997,73.72608900000012],[-82.85278299999993,73.73027000000002],[-82.84083599999997,73.73275799999999],[-82.82084699999996,73.73359700000015],[-82.63612399999994,73.72776799999991],[-82.52999899999992,73.72221400000012],[-82.47500600000001,73.71998599999995],[-82.41389499999997,73.71887199999998],[-82.36749299999991,73.71914700000002],[-82.21945199999999,73.72526600000003],[-81.99082899999996,73.73136899999997],[-81.61805700000002,73.72109999999998],[-81.57250999999997,73.71971100000013],[-81.55387899999994,73.71720900000008],[-81.53666699999985,73.71388200000013],[-81.47610500000002,73.69802900000008],[-81.45722999999998,73.6910860000001],[-81.28250099999997,73.58027600000014],[-81.23971599999987,73.54693600000007],[-81.228882,73.53553800000009],[-81.21945199999999,73.52137800000014],[-81.19749499999995,73.47720300000015],[-81.18832399999991,73.38970900000004],[-81.21166999999997,73.326096],[-81.21610999999996,73.31469700000008],[-81.21583599999997,73.30386399999992],[-81.21417200000002,73.29193100000009],[-81.20944199999991,73.2727660000001],[-81.20472699999999,73.266663],[-81.19249000000002,73.26054399999998],[-81.17749000000003,73.25637800000004],[-81.10166899999996,73.23831200000006],[-81.07444800000002,73.23220800000007],[-80.90028399999994,73.209427],[-80.71278399999994,73.18026700000013],[-80.66471899999993,73.17109700000009],[-80.64083900000003,73.16554300000013],[-80.61721799999998,73.157761],[-80.59638999999999,73.14804100000009],[-80.55776999999995,73.11137400000007],[-80.54750100000001,73.09803799999992],[-80.54777499999994,73.09136999999998],[-80.54943799999995,73.08194000000009],[-80.59333799999996,73.02581800000007],[-80.61749299999997,73.00555400000013],[-80.641388,72.99609400000008],[-80.64750700000002,72.99054000000007],[-80.65222199999994,72.97470099999998],[-80.65083300000003,72.96914699999996],[-80.63389599999994,72.94053600000007],[-80.64250199999998,72.93553200000008],[-80.64277599999997,72.92886400000009],[-80.63833599999998,72.9227600000001],[-80.537216,72.851089],[-80.51390100000003,72.83888200000001],[-80.48777799999999,72.828598],[-80.44055200000003,72.818604],[-80.40556300000003,72.81330900000012],[-80.34916699999997,72.80636600000014],[-80.33332799999994,72.80304000000007],[-80.31945799999994,72.799149],[-80.29998799999998,72.78804000000014],[-80.283615,72.77748100000008],[-80.24749800000001,72.73054500000006],[-80.2580569999999,72.724426],[-80.33222999999992,72.71249400000005],[-80.36166400000002,72.70609999999999],[-80.44499199999996,72.67359900000008],[-80.46472199999994,72.66526800000003],[-80.541382,72.62886000000015],[-80.55610699999994,72.6202550000001],[-80.55638099999987,72.60720800000007],[-80.64862099999999,72.55497700000001],[-80.67639199999996,72.54721100000012],[-80.765289,72.5169370000001],[-80.94248999999996,72.45526100000012],[-80.95388799999995,72.45054600000009],[-80.98832700000003,72.42970300000002],[-81.186935,72.29914900000011],[-81.19249000000002,72.29359400000004],[-81.19972200000001,72.289154],[-81.22250400000001,72.2816620000001],[-81.23916600000001,72.27777100000003],[-81.30471799999998,72.26832600000012],[-81.37943999999999,72.24165299999993],[-81.36527999999998,72.24165299999993],[-81.30139200000002,72.24609400000003],[-81.28582799999992,72.24720800000006],[-81.25306699999999,72.25193800000005],[-81.24194299999999,72.25443999999993],[-81.22972099999993,72.25860600000004],[-81.16416900000002,72.2872010000001],[-81.03750600000001,72.35108900000012],[-80.92944299999994,72.40026899999998],[-80.82167099999998,72.43914800000005],[-80.715012,72.47303799999997],[-80.60055499999999,72.50665300000003],[-80.58029199999993,72.509995],[-80.55444299999999,72.51249700000005],[-80.53944399999995,72.51165800000007],[-80.52555799999999,72.50804099999993],[-80.51640299999991,72.50387599999993],[-80.508896,72.49664300000012],[-80.50306699999999,72.48498500000011],[-80.49527,72.46415700000006],[-80.49276700000001,72.45304900000002],[-80.493607,72.44720500000005],[-80.51417499999997,72.37970000000001],[-80.52500900000001,72.37414600000005],[-80.54222099999987,72.37052900000009],[-80.56443799999994,72.36665300000004],[-80.60305800000003,72.36303700000013],[-80.65556299999997,72.35192899999998],[-80.66915899999998,72.34721400000012],[-80.68055699999996,72.34220900000008],[-80.78332499999999,72.29026799999997],[-80.79415899999992,72.28471400000001],[-80.80833399999995,72.27415500000012],[-80.854172,72.23553500000003],[-80.89695699999993,72.19442700000008],[-80.90556300000003,72.180542],[-80.816666,72.15054299999997],[-80.769455,72.14166300000011],[-80.75389099999995,72.14054899999996],[-80.70973200000003,72.13192700000013],[-80.58084099999996,72.09443700000008],[-80.569458,72.08831800000007],[-80.56723,72.07720899999998],[-80.56723,72.07276899999994],[-80.57417299999992,72.06832900000012],[-80.58833300000003,72.06414800000005],[-80.63055400000002,72.06219500000009],[-80.646118,72.06330900000006],[-80.68666100000002,72.07304399999998],[-80.74194299999994,72.09414700000008],[-80.94110099999995,72.0874940000001],[-81.08029199999993,72.05165100000005],[-81.08666999999997,72.04664600000001],[-81.08332799999994,72.04553200000004],[-81.06500199999994,72.04165599999993],[-81.04666099999997,72.03997800000002],[-80.99055499999997,72.03776600000015],[-80.92721599999999,72.03776600000015],[-80.906387,72.03997800000002],[-80.89222699999999,72.04414400000013],[-80.88639799999999,72.04971300000011],[-80.87943999999999,72.05415299999993],[-80.86665299999999,72.0577550000001],[-80.84722899999997,72.05664100000013],[-80.79277000000002,72.02777100000003],[-80.79415899999992,72.022491],[-80.82139599999988,71.95637499999998],[-80.833328,71.94581599999998],[-80.84944199999995,71.93470799999994],[-80.88612399999994,71.92082199999999],[-80.93331899999993,71.90887500000002],[-80.97500599999995,71.895828],[-80.98083499999996,71.89027399999998],[-80.983612,71.88638300000014],[-80.97166400000003,71.88165300000009],[-80.950287,71.88108800000003],[-80.92639200000002,71.88275099999998],[-80.90361000000001,71.88526899999994],[-80.86805699999996,71.89305100000007],[-80.76722699999999,71.92942800000009],[-80.75611900000001,71.93414300000012],[-80.75029,71.93969700000008],[-80.74694799999997,71.9452510000001],[-80.74472000000003,71.95193499999999],[-80.745834,71.95748899999995],[-80.75556899999998,71.97109999999992],[-80.75834699999996,71.97776800000008],[-80.74694799999997,71.98248300000012],[-80.65916400000003,72.00305200000008],[-80.63944999999995,72.00637799999993],[-80.620544,72.006104],[-80.53527799999995,72.01609800000006],[-80.44888300000002,72.02916000000005],[-80.410553,72.0394290000001],[-80.38500999999997,72.04832500000003],[-80.35055499999993,72.06915300000009],[-80.34777799999995,72.0752720000001],[-80.34666399999998,72.08110000000005],[-80.34722899999991,72.08831800000007],[-80.35249299999998,72.09553499999998],[-80.358612,72.10137900000001],[-80.37026999999995,72.10803199999998],[-80.38305699999995,72.11331200000001],[-80.410278,72.12136800000007],[-80.43388400000003,72.1327510000001],[-80.44554099999999,72.1397090000001],[-80.45527599999997,72.14665200000007],[-80.47860700000001,72.16859399999998],[-80.48332199999999,72.17526199999992],[-80.48693800000001,72.18304400000005],[-80.48666400000002,72.18942300000015],[-80.46806299999997,72.19192500000003],[-80.42694099999989,72.19108600000004],[-80.40861499999988,72.1891480000001],[-80.39361600000001,72.17720000000008],[-80.37666300000001,72.17442299999999],[-80.35555999999991,72.17442299999999],[-80.33139,72.17608600000011],[-80.2411039999999,72.19775400000003],[-80.23527499999994,72.20332300000001],[-80.24444599999993,72.20971700000007],[-80.27305599999994,72.21914700000013],[-80.27972399999993,72.22554000000008],[-80.30166599999995,72.24859600000013],[-80.30638099999999,72.25526400000012],[-80.29554699999994,72.27442900000005],[-80.28971899999993,72.27998400000013],[-80.27223199999997,72.29026799999997],[-80.26083399999999,72.294983],[-80.24221799999998,72.29748500000011],[-80.22444200000001,72.29637100000014],[-80.19415300000003,72.28776600000009],[-80.15583800000002,72.27360500000009],[-80.13473499999992,72.26277199999993],[-80.11305199999998,72.24414100000013],[-80.08555599999994,72.22665400000005],[-80.02139299999999,72.18969700000008],[-79.99166899999989,72.1766510000001],[-79.962784,72.16886899999997],[-79.94722000000002,72.16526799999991],[-79.89973399999997,72.15554800000001],[-79.84028599999994,72.145264],[-79.79055799999998,72.13777200000004],[-79.761124,72.13415500000008],[-79.68554699999993,72.12637299999994],[-79.67443799999995,72.12664799999999],[-79.67250100000001,72.12970000000007],[-79.691666,72.14166300000011],[-79.71916199999993,72.1483310000001],[-79.78999299999998,72.15582300000005],[-79.81111099999998,72.16026300000004],[-79.85499599999997,72.17109700000015],[-79.92388900000003,72.19053600000001],[-79.941101,72.1958160000001],[-80.045547,72.24247700000012],[-80.15194699999995,72.31053199999997],[-80.16639699999996,72.32222000000013],[-80.16444399999995,72.32748400000014],[-80.15556299999992,72.336929],[-80.13362099999995,72.349716],[-80.11527999999993,72.35942100000011],[-80.07640099999998,72.37885999999997],[-80.06471299999998,72.3836060000001],[-80.05221599999999,72.38777199999998],[-79.99194299999999,72.40277100000009],[-79.95722999999992,72.40832500000005],[-79.87443499999995,72.47053499999998],[-79.870834,72.483047],[-79.86332699999997,72.48969999999997],[-79.8369449999999,72.49859600000008],[-79.82084700000001,72.50138900000007],[-79.79916400000002,72.50138900000007],[-79.78056299999997,72.49942000000004],[-79.77084400000001,72.49664300000012],[-79.73416099999992,72.484421],[-79.70056199999999,72.47248800000011],[-79.69221500000003,72.46693399999992],[-79.7686389999999,72.411766],[-79.68786599999999,72.3843920000001],[-79.59555099999994,72.33471700000013],[-79.63890100000003,72.289154],[-79.66805999999991,72.28082300000011],[-79.70556599999998,72.27360500000009],[-79.72000099999997,72.26944000000009],[-79.731674,72.26470899999998],[-79.75973499999992,72.25054900000009],[-79.76861600000001,72.2452550000001],[-79.77471899999989,72.23970000000003],[-79.775284,72.23332200000004],[-79.76972999999992,72.22581500000013],[-79.75,72.21554600000007],[-79.73277300000001,72.21220399999999],[-79.712784,72.21110499999998],[-79.70111099999997,72.21582000000001],[-79.56582599999996,72.2752690000001],[-79.48500100000001,72.32554599999997],[-79.35555999999991,72.39915500000001],[-79.34249899999998,72.40026899999998],[-79.32972699999999,72.39721700000007],[-79.24333199999995,72.37441999999999],[-79.18249500000002,72.3583220000001],[-79.14666699999998,72.3458250000001],[-79.11332700000003,72.33109999999999],[-79.08222999999992,72.313873],[-79.012787,72.27388000000013],[-78.94554099999993,72.199997],[-78.943604,72.193039],[-78.94694500000003,72.18691999999999],[-79.03639199999998,72.06944300000009],[-79.13612399999994,72.00749200000013],[-79.14500399999997,72.00248700000009],[-79.15666199999998,71.99775700000004],[-79.20638999999994,71.98664900000006],[-79.22999600000003,71.98027000000002],[-79.23306300000002,71.97637900000012],[-79.20306399999998,71.961929],[-79.19027699999998,71.95832800000011],[-79.17639200000002,71.95582600000006],[-79.16111799999993,71.95443700000004],[-79.13861099999991,71.95526100000001],[-79.12304699999993,71.9580380000001],[-79.09973099999996,71.96720900000008],[-79.09083599999985,71.97248800000006],[-79.07223499999992,71.97499099999999],[-79.06111099999993,71.97526600000003],[-79.02667199999996,71.9705350000001],[-78.81806899999998,71.93525700000009],[-78.76889,71.92692599999998],[-78.7225039999999,71.91886900000003],[-78.68388400000003,71.90971400000001],[-78.65306099999998,71.89387500000004],[-78.639725,71.88443000000001],[-78.62582399999985,71.8791500000001],[-78.585556,71.865814],[-78.57139599999988,71.86276200000003],[-78.55139200000002,71.86109899999997],[-78.52917499999995,71.861649],[-78.511124,71.86469999999997],[-78.50361599999997,71.86886600000008],[-78.5083469999999,71.876373],[-78.595551,71.93331899999998],[-78.60749800000002,71.93858300000011],[-78.62222299999996,71.94220000000007],[-78.69137599999999,71.94970700000005],[-78.74055499999997,71.9580380000001],[-78.85555999999985,71.97970600000002],[-78.914444,72.00776700000011],[-78.92361499999998,72.01499900000005],[-78.92443800000001,72.02053800000004],[-78.87748699999997,72.15332000000006],[-78.86944599999993,72.16665600000005],[-78.866104,72.1705320000001],[-78.85444599999994,72.17303500000008],[-78.843613,72.17109700000015],[-78.55444299999999,72.11137400000007],[-78.51222199999995,72.101089],[-78.48777799999993,72.09248400000013],[-78.47610500000002,72.0872040000001],[-78.46083099999993,72.07331800000009],[-78.43277,72.03804000000008],[-78.39527899999996,71.98248300000012],[-78.38999899999999,71.96943700000003],[-78.39277599999997,71.94999700000005],[-78.39167800000001,71.94358799999998],[-78.38667299999997,71.93331899999998],[-78.38194299999992,71.92804000000001],[-78.36527999999993,71.91748000000001],[-78.31777999999997,71.88832100000008],[-78.22666900000002,71.83305400000012],[-78.21083099999998,71.82582100000013],[-78.18499799999995,71.81749000000002],[-78.15760799999998,71.81057700000002],[-78.12304699999993,71.80636600000014],[-78.09056099999992,71.80081200000012],[-78.05972300000002,71.79414399999996],[-77.92443799999995,71.7647090000001],[-77.90777599999996,71.76638800000012],[-77.90444899999994,71.76805100000001],[-77.90695199999999,71.7705380000001],[-77.91416900000002,71.77360500000003],[-77.96665999999993,71.78665200000006],[-77.99749800000001,71.79332],[-78.02972399999993,71.79887400000001],[-78.08583099999998,71.81330900000012],[-78.10722399999992,71.81915300000014],[-78.13999899999993,71.83055100000013],[-78.178879,71.84860200000014],[-78.30888400000003,71.92109699999997],[-78.316666,71.92942800000009],[-78.321396,71.93692000000004],[-78.31500199999999,71.942474],[-78.3052669999999,71.94693000000012],[-78.27917500000001,71.95359800000011],[-78.258896,71.95665000000002],[-78.178879,71.96720900000008],[-78.15695199999993,71.96832300000005],[-78.14167799999996,71.96415700000011],[-78.01861600000001,71.89082300000013],[-77.974716,71.85998499999994],[-77.785553,71.78749099999999],[-77.80776999999995,71.82304400000004],[-77.96000699999996,71.88165300000009],[-78.09695399999998,71.96804800000001],[-78.10722399999992,71.97415200000006],[-78.11639399999996,71.97692899999998],[-78.14973399999997,71.980545],[-78.156387,71.980545],[-78.19610599999993,71.97859200000005],[-78.26222200000001,71.97276300000004],[-78.281387,71.97387700000002],[-78.29861499999998,71.97747800000008],[-78.32250999999991,71.98580900000002],[-78.33416699999992,71.99136400000009],[-78.34111000000001,71.99859600000002],[-78.34249899999992,72.01277199999998],[-78.34167499999995,72.01914999999997],[-78.34167499999995,72.03193699999997],[-78.35694899999993,72.05831900000004],[-78.37554899999998,72.08581500000008],[-78.38667299999997,72.09553499999998],[-78.40222199999994,72.10498000000007],[-78.42443799999995,72.11360200000007],[-78.436935,72.11747700000001],[-78.468887,72.12414600000011],[-78.51501499999995,72.13136300000002],[-78.59999099999999,72.145264],[-78.69665499999996,72.16360500000002],[-78.80999800000001,72.19720500000005],[-78.84249899999992,72.20915200000002],[-78.85472099999998,72.2144320000001],[-78.870834,72.22665400000005],[-78.86915599999992,72.22970600000002],[-78.73472599999997,72.32859800000011],[-78.61582900000002,72.35914600000007],[-78.604172,72.35942100000011],[-78.58056599999992,72.35415600000005],[-78.51583900000003,72.33055100000007],[-78.5125119999999,72.324432],[-78.51916499999999,72.31915300000003],[-78.52833599999991,72.313873],[-78.53332499999999,72.30914300000012],[-78.53694200000001,72.30331400000011],[-78.537781,72.25471500000015],[-78.53138699999994,72.24026500000002],[-78.52917499999995,72.23553500000003],[-78.52084399999995,72.22915599999999],[-78.42193599999996,72.1708220000001],[-78.40834000000001,72.16638200000011],[-78.39973399999997,72.16720600000008],[-78.39083900000003,72.16998299999995],[-78.386124,72.17248500000005],[-78.38417099999998,72.17553700000013],[-78.41111799999999,72.21666000000005],[-78.41471899999993,72.22053500000004],[-78.422775,72.224152],[-78.45973200000003,72.23387100000002],[-78.47277799999995,72.24247700000012],[-78.46833799999996,72.31498699999997],[-78.46278399999994,72.31887800000004],[-78.45111099999991,72.32415800000007],[-78.439438,72.32666],[-78.40834000000001,72.32582100000002],[-78.3052669999999,72.313309],[-78.01251200000002,72.2749940000001],[-77.89361599999995,72.25943000000001],[-77.82749899999999,72.24859600000013],[-77.79388399999999,72.24220299999996],[-77.66528299999987,72.20471200000003],[-77.65527299999997,72.20138500000007],[-77.64862099999999,72.19413799999995],[-77.644455,72.18664600000005],[-77.54083300000002,72.17692599999998],[-77.381104,72.18498200000005],[-77.32417299999986,72.18609600000002],[-77.289444,72.1833190000001],[-77.23998999999998,72.17442299999999],[-77.11582899999996,72.1483310000001],[-77.03944399999995,72.13165300000003],[-77.02333099999998,72.12886000000003],[-77.00611899999996,72.12747200000013],[-76.99722300000002,72.12803600000007],[-76.99583399999995,72.12886000000003],[-76.99471999999997,72.13053900000006],[-77.00500499999998,72.13443000000012],[-77.06861900000001,72.15220600000009],[-77.25167799999991,72.19331399999999],[-77.27806099999998,72.19693000000007],[-77.30694599999993,72.19802900000002],[-77.39723200000003,72.19274899999999],[-77.45584099999996,72.19081100000005],[-77.476944,72.19136000000015],[-77.51417500000002,72.19386299999996],[-77.54998799999998,72.19802900000002],[-77.578888,72.20416300000005],[-77.604172,72.21192900000011],[-77.62388599999991,72.22110000000009],[-77.658615,72.23165899999992],[-77.76083399999993,72.25721700000003],[-77.82305899999994,72.271927],[-77.866104,72.28109700000005],[-77.94999699999988,72.29609700000003],[-78.07250999999997,72.31248500000004],[-78.12138400000003,72.31971699999997],[-78.15472399999999,72.32554599999997],[-78.22000100000002,72.33776900000004],[-78.32695000000001,72.35914600000007],[-78.37388599999997,72.36943100000002],[-78.38917500000002,72.37303200000008],[-78.47332799999998,72.39498900000012],[-78.49916100000002,72.40470900000003],[-78.52084399999995,72.41499300000004],[-78.55915800000002,72.43803400000007],[-78.56111099999993,72.44497700000005],[-78.55665599999992,72.5044400000001],[-78.44305399999996,72.58193999999997],[-78.43055699999996,72.58665500000001],[-78.17027300000001,72.653595],[-78.156387,72.65693700000008],[-78.00167799999991,72.68248000000006],[-77.8699949999999,72.6974790000001],[-77.84500100000002,72.69886800000006],[-77.78083799999996,72.70694000000003],[-77.76861600000001,72.70942700000012],[-77.70140100000003,72.72470100000004],[-77.67027300000001,72.73220800000013],[-77.65695199999988,72.73609900000002],[-77.63999899999999,72.74386599999997],[-77.62748699999997,72.74859600000002],[-77.61389200000002,72.75166300000012],[-77.57640100000003,72.75555400000002],[-77.53222699999992,72.75694300000004],[-77.51362599999999,72.75471500000003],[-77.41305499999987,72.75221299999998],[-77.25973499999998,72.75166300000012],[-77.05581699999999,72.75286100000011],[-77.00250199999999,72.74941999999999],[-76.9472199999999,72.74386599999997],[-76.79972800000002,72.72747800000013],[-76.75306699999999,72.72053499999993],[-76.69305399999996,72.694702],[-76.6849979999999,72.69108599999993],[-76.6625059999999,72.67858899999999],[-76.65360999999996,72.67082199999999],[-76.65527299999997,72.66442900000004],[-76.65972899999997,72.65832499999999],[-76.646118,72.63970899999998],[-76.58473200000003,72.62858599999998],[-76.42832899999996,72.61415100000005],[-76.32833900000003,72.60748300000012],[-76.28832999999992,72.60498000000013],[-76.21528599999994,72.59610000000009],[-76.18221999999997,72.58998100000008],[-76.166946,72.58638000000002],[-76.15556299999992,72.580826],[-76.150284,72.57415800000001],[-76.15472399999993,72.56248500000004],[-76.16055299999994,72.54942299999999],[-76.16583300000002,72.53831500000001],[-76.16250600000001,72.526093],[-76.15611299999995,72.51805100000007],[-76.12165799999991,72.47831700000012],[-76.10777300000001,72.47303799999997],[-76.087784,72.47164899999996],[-76.069458,72.4749910000001],[-76.04638699999987,72.48359700000003],[-76.0369419999999,72.48942600000004],[-76.03778099999994,72.49636800000013],[-76.05221599999999,72.51138300000008],[-76.06861900000001,72.52581800000002],[-76.07722499999994,72.53637700000007],[-76.07417299999992,72.54165600000005],[-76.06471299999987,72.54998800000004],[-76.01889,72.57443199999994],[-76.00584399999997,72.57916300000011],[-75.98860199999996,72.580826],[-75.93194599999993,72.5836030000001],[-75.88528400000001,72.58415200000007],[-75.84194899999994,72.58305399999995],[-75.79888899999997,72.58193999999997],[-75.75917099999998,72.57916300000011],[-75.56806899999998,72.55747999999994],[-75.55332899999996,72.5535890000001],[-75.54722600000002,72.5455320000001],[-75.53778099999994,72.53970300000009],[-75.52111799999989,72.53610200000003],[-75.47222899999991,72.52748099999997],[-75.435272,72.52249100000006],[-75.37943999999993,72.51638800000012],[-75.36000100000001,72.51554899999996],[-75.30166600000001,72.50972000000013],[-75.231674,72.50054900000003],[-75.21528599999988,72.4974820000001],[-75.19249000000002,72.49192800000009],[-75.18666100000002,72.4874880000001],[-75.18916300000001,72.47831700000012],[-75.19915800000001,72.46693399999992],[-75.200287,72.46192900000005],[-75.16027799999995,72.42109700000009],[-75.13249200000001,72.3936000000001],[-75.054169,72.3288730000001],[-75.03416400000003,72.31749000000013],[-75,72.29836999999998],[-74.98055999999991,72.28831500000007],[-74.95083599999998,72.26998900000007],[-74.943604,72.26332100000008],[-74.94249000000002,72.25582900000012],[-74.94749499999995,72.2497100000001],[-75.04499799999996,72.18830899999995],[-75.06806899999992,72.17915299999999],[-75.225281,72.1224820000001],[-75.23832699999991,72.1183170000001],[-75.25306699999993,72.11637899999994],[-75.27166699999998,72.11720300000007],[-75.29138199999989,72.11943100000008],[-75.32362399999994,72.12553400000002],[-75.3875119999999,72.13443000000012],[-75.44055200000003,72.14109800000011],[-75.47778299999999,72.14471400000014],[-75.52000399999997,72.14610299999998],[-75.60749800000002,72.14332600000006],[-75.71000699999996,72.13665800000007],[-75.73332199999993,72.13415500000008],[-75.81388900000002,72.1224820000001],[-75.86665299999999,72.113876],[-76.015015,72.08665500000012],[-76.03332499999993,72.08110000000005],[-76.05471799999987,72.07304399999998],[-76.07806399999998,72.059418],[-76.08416699999992,72.04971300000011],[-76.09973100000002,72.02887000000004],[-76.11193800000001,72.01805099999996],[-76.12805200000003,72.00416600000005],[-76.14222699999993,71.99331699999999],[-76.15638699999988,71.98526000000004],[-76.17361499999998,71.97554000000014],[-76.19249000000002,71.967758],[-76.23472600000002,71.95748899999995],[-76.2625119999999,71.94970700000005],[-76.27444500000001,71.94442700000013],[-76.30166599999995,71.93054200000006],[-76.31834400000002,71.919983],[-76.34805299999988,71.891663],[-76.31082200000003,71.88472000000002],[-76.08972199999994,71.9788670000001],[-76.07305899999994,71.98942599999992],[-76.06332399999997,72],[-76.0497279999999,72.01776100000012],[-76.04750100000001,72.02360499999998],[-76.04360999999994,72.03027299999997],[-76.02944899999994,72.04109199999999],[-76.01972999999998,72.04609700000003],[-75.99861099999998,72.05415299999993],[-75.95611599999995,72.06721500000015],[-75.89445499999988,72.08221400000002],[-75.82833899999997,72.09693900000013],[-75.79666099999992,72.10359199999994],[-75.710556,72.11331200000001],[-75.63055400000002,72.11970500000001],[-75.58612099999999,72.12164300000012],[-75.52833599999997,72.12081899999998],[-75.48805199999993,72.11886600000003],[-75.43306000000001,72.11276199999998],[-75.23332199999993,72.08415200000013],[-75.22610500000002,72.08027600000008],[-75.21945199999988,72.07443200000006],[-75.218887,72.07026700000006],[-75.221115,72.06469699999997],[-75.22888199999994,72.059143],[-75.25527999999991,72.04609700000003],[-75.28167699999989,72.03858900000006],[-75.31750499999993,72.03166199999993],[-75.33833299999998,72.02887000000004],[-75.40417499999995,72.02554300000008],[-75.449432,72.02526899999998],[-75.49415599999998,72.02137800000008],[-75.515015,72.018326],[-75.54804999999999,72.01110799999998],[-75.57417299999992,72.00360100000006],[-75.58667000000003,71.99914600000005],[-75.60638399999993,71.98942599999992],[-75.61389200000002,71.98387100000002],[-75.61888099999999,71.97859200000005],[-75.68666100000002,71.88304099999999],[-75.697495,71.85832200000004],[-75.69137599999988,71.85026600000015],[-75.68804899999992,71.84275800000012],[-75.6875,71.83915700000006],[-75.69221500000003,71.83332800000005],[-75.80249000000003,71.75054899999998],[-75.83000199999998,71.73664900000011],[-75.8722229999999,71.72137500000002],[-75.89834599999995,71.71443200000004],[-75.93415799999997,71.71110500000009],[-75.95361299999996,71.7102660000001],[-75.9974979999999,71.70915200000013],[-76.04028299999993,71.70942699999995],[-76.06750499999987,71.70665000000008],[-76.07917799999996,71.7044370000001],[-76.09083599999991,71.70220899999998],[-76.096115,71.6974790000001],[-76.09583999999995,71.69386300000008],[-76.08528100000001,71.69192499999991],[-75.90167199999996,71.70109600000006],[-75.88027999999997,71.70248400000014],[-75.84695399999998,71.70860299999998],[-75.81945799999994,71.7169340000001],[-75.79499800000002,71.72581500000001],[-75.78721599999994,71.73054500000006],[-75.675003,71.81053200000002],[-75.65499899999998,71.82609600000012],[-75.58000199999987,71.90609700000005],[-75.57028199999996,71.91748000000001],[-75.56582599999996,71.92970300000007],[-75.56722999999994,71.93748500000004],[-75.57028199999996,71.94136000000003],[-75.57444799999996,71.95304899999996],[-75.57194499999997,71.95887800000014],[-75.56916799999999,71.96388200000013],[-75.558334,71.97665400000011],[-75.53860500000002,71.98637400000001],[-75.51333599999992,71.99525499999999],[-75.49804699999993,71.99914600000005],[-75.47666900000002,72.00082399999997],[-75.414444,71.99971],[-75.3719329999999,71.99775700000004],[-75.3494419999999,71.99803200000002],[-75.32778899999994,71.99941999999999],[-75.24888599999997,72.01277199999998],[-75.19776899999994,72.02331500000014],[-75.17443799999995,72.03193699999997],[-75.15861499999994,72.04165599999993],[-75.15028399999994,72.0577550000001],[-75.13500999999997,72.08055100000007],[-75.12999000000002,72.08638000000013],[-75.11915599999986,72.09637500000002],[-75.10916099999986,72.101089],[-75.093613,72.10803199999998],[-75.08138999999994,72.11303700000002],[-75.05139200000002,72.12191799999994],[-75.03582799999992,72.125809],[-75.01251199999996,72.12831100000011],[-75,72.12852500000002],[-74.98443599999996,72.12747200000013],[-74.95167500000002,72.12330600000007],[-74.83500699999996,72.10386699999998],[-74.80139199999996,72.09832799999998],[-74.76444999999995,72.09471100000002],[-74.65943900000002,72.09109499999994],[-74.62554899999992,72.09136999999998],[-74.535278,72.08970599999998],[-74.31639099999995,72.08221400000002],[-74.29722600000002,72.08082600000012],[-74.26000999999997,72.07609600000006],[-74.24415599999986,72.07304399999998],[-74.23332199999999,72.06748999999996],[-74.21806299999997,72.05802900000003],[-74.17748999999992,72.03193699999997],[-74.12222299999996,71.98359700000009],[-74.11776699999996,71.96998599999995],[-74.11944599999998,71.95582600000006],[-74.16610700000001,71.87469500000009],[-74.17111199999994,71.86859100000004],[-74.18499800000001,71.85581999999994],[-74.22999600000003,71.822769],[-74.24305699999996,71.818604],[-74.26333599999998,71.815811],[-74.40306099999992,71.80386400000009],[-74.43998699999986,71.80192599999992],[-74.460556,71.80276500000008],[-74.47778299999993,71.80497700000012],[-74.50140399999998,71.80970800000006],[-74.51362599999987,71.81805399999996],[-74.57055700000001,71.80941800000005],[-74.60499600000003,71.78471400000012],[-74.67832899999996,71.74525499999999],[-74.69610599999993,71.73858600000011],[-74.71362299999987,71.7352600000001],[-74.88500999999991,71.70860299999998],[-75,71.71191400000004],[-75.04666099999992,71.71609500000011],[-75.09056099999992,71.71804800000007],[-75.13667299999997,71.7169340000001],[-75.158051,71.71527100000014],[-75.34277299999991,71.69581599999998],[-75.36389200000002,71.69136000000009],[-75.37860099999995,71.68692000000004],[-75.38999899999999,71.68109100000004],[-75.39388999999994,71.67747500000002],[-75.391953,71.67469800000009],[-75.38500999999991,71.6744230000001],[-75.24194299999988,71.68609600000008],[-75.17832900000002,71.69413800000007],[-75.08500700000002,71.70082100000008],[-75.04361,71.69970700000005],[-75.02500899999995,71.69802900000013],[-75.00917099999992,71.69497700000005],[-74.941101,71.67469800000009],[-74.93415800000002,71.67082200000004],[-74.93360899999999,71.66387900000001],[-74.93638599999997,71.65803500000004],[-74.94554099999993,71.65248100000002],[-74.95611599999995,71.64833100000004],[-75.008896,71.63192700000008],[-75.05555700000002,71.62248199999999],[-75.11416600000001,71.61109899999997],[-75.19415299999997,71.5955350000001],[-75.206955,71.59193400000004],[-75.39834599999995,71.5252690000001],[-75.40972899999997,71.51971400000002],[-75.40833999999995,71.51470899999998],[-75.40638699999994,71.51220700000005],[-75.40222199999994,71.51249700000005],[-75.20527600000003,71.54637100000008],[-75,71.60723899999999],[-74.86111499999993,71.64942900000011],[-74.85166899999996,71.65498400000001],[-74.79943799999995,71.67886399999998],[-74.78416399999998,71.68275500000004],[-74.7183379999999,71.69358800000003],[-74.69776899999994,71.69636500000013],[-74.68666100000002,71.69636500000013],[-74.67277499999994,71.69247400000006],[-74.63194299999998,71.6624910000001],[-74.62971499999992,71.65277100000003],[-74.63194299999998,71.64637800000008],[-74.64639299999999,71.63192700000008],[-74.6744379999999,71.6083220000001],[-74.68971299999998,71.59803800000003],[-74.70472699999993,71.58804299999997],[-74.71305799999993,71.58387800000014],[-74.73388699999998,71.57554600000014],[-74.81193499999995,71.5477600000001],[-74.86972000000003,71.54165600000005],[-74.9225009999999,71.53776600000009],[-74.94027699999987,71.53804000000002],[-74.97084000000001,71.53720100000004],[-74.99027999999998,71.53665200000012],[-75,71.53558300000009],[-75.027222,71.532486],[-75.03666699999997,71.53054800000007],[-75.08138999999994,71.51527399999998],[-75.10777300000001,71.50305200000003],[-75.12470999999994,71.49247700000006],[-75.15194699999995,71.47164900000001],[-75.152222,71.466095],[-75.14611799999994,71.46360800000008],[-75.12777699999998,71.46582000000001],[-75.11555499999997,71.46998600000006],[-75.10611,71.48193400000008],[-75.09388699999994,71.49275200000011],[-75.08473199999997,71.49832200000014],[-75.06138599999997,71.50637800000004],[-75.05082699999997,71.50972000000002],[-75.03332499999993,71.51304600000003],[-75,71.51789900000011],[-74.99305699999991,71.51887500000004],[-74.94415300000003,71.52165200000013],[-74.87748699999997,71.52415500000012],[-74.85722399999997,71.52360500000009],[-74.83833299999992,71.52192699999995],[-74.82833899999997,71.51721199999992],[-74.71665999999999,71.41914400000013],[-74.69943199999994,71.39082300000007],[-74.70056199999993,71.38665800000007],[-74.70556599999998,71.38081400000004],[-74.71528599999999,71.375809],[-74.88833599999998,71.2872010000001],[-75.07501200000002,71.20443700000004],[-75.08138999999994,71.17942800000003],[-75.06500199999999,71.18081700000005],[-75,71.19934100000006],[-74.987503,71.2038730000001],[-74.87416099999996,71.24775699999998],[-74.86444099999994,71.25248700000003],[-74.67166099999997,71.35998500000005],[-74.65444899999994,71.37025499999999],[-74.63751199999996,71.380539],[-74.63221699999997,71.38581800000003],[-74.62805199999997,71.39248700000007],[-74.62582399999985,71.39888000000002],[-74.62609899999995,71.405823],[-74.631104,71.41943399999997],[-74.63806199999999,71.4266510000001],[-74.64695699999993,71.43304400000005],[-74.65722700000003,71.43858300000005],[-74.71972699999998,71.4624940000001],[-74.726944,71.466095],[-74.73554999999999,71.47248799999994],[-74.73638899999997,71.47665400000005],[-74.74305700000002,71.51193200000006],[-74.73611499999987,71.53054800000007],[-74.72389199999998,71.54193100000009],[-74.71417200000002,71.54664600000012],[-74.70167500000002,71.55108600000011],[-74.68638599999991,71.55497700000001],[-74.66389500000002,71.55720499999995],[-74.62887599999993,71.55470300000007],[-74.61999500000002,71.55802900000009],[-74.583618,71.58581500000003],[-74.57640100000003,71.5913700000001],[-74.54388399999999,71.63136299999996],[-74.38194299999992,71.67719999999997],[-74.34555099999994,71.68942300000003],[-74.335556,71.69413800000007],[-74.31777999999997,71.7044370000001],[-74.30943299999996,71.71220400000004],[-74.30694599999998,71.71775800000006],[-74.29943799999995,71.72387700000007],[-74.2886049999999,71.72747800000013],[-74.26834100000002,71.73027000000002],[-74.14695699999993,71.73887599999995],[-74.12470999999988,71.73887599999995],[-74.10916099999997,71.73580900000002],[-74.10305800000003,71.73332199999999],[-74.09777799999995,71.72886699999998],[-74.12388599999991,71.6808170000001],[-74.12887599999988,71.67164600000001],[-74.14222699999999,71.661652],[-74.15055799999999,71.65748600000006],[-74.17304999999999,71.65109300000012],[-74.202789,71.64582800000005],[-74.22027600000001,71.64166300000005],[-74.23277300000001,71.63749699999994],[-74.239441,71.63415500000002],[-74.24888599999997,71.62164300000006],[-74.25306699999999,71.611649],[-74.25445599999995,71.60664399999996],[-74.25473,71.6038670000001],[-74.252228,71.58998100000008],[-74.24916100000002,71.58248900000012],[-74.24305699999996,71.56971699999997],[-74.21888699999994,71.55664100000001],[-74.18028299999997,71.53831500000001],[-74.16833499999996,71.53332499999999],[-74.156387,71.53221100000002],[-74.15028399999989,71.53332499999999],[-74.14862099999993,71.53749100000005],[-74.15167199999996,71.544983],[-74.165009,71.55525200000005],[-74.146118,71.63749699999994],[-74.03971899999993,71.72221399999995],[-74.01916499999999,71.73803700000002],[-74.01472499999994,71.7410890000001],[-73.99694799999997,71.75138900000002],[-73.97778299999993,71.75972000000013],[-73.964447,71.76332100000002],[-73.92832900000002,71.76915000000002],[-73.74804699999993,71.77693199999999],[-73.71888699999994,71.77693199999999],[-73.61610399999995,71.77331500000003],[-73.604172,71.77221700000013],[-73.593887,71.76998899999995],[-73.589722,71.76332100000002],[-73.58999599999999,71.75694300000004],[-73.59167500000001,71.751938],[-73.598343,71.73831200000001],[-73.612503,71.72221399999995],[-73.61999500000002,71.71609500000011],[-73.63806199999999,71.70637500000004],[-73.66332999999992,71.697205],[-73.69444299999992,71.69026200000002],[-73.73277299999995,71.68386800000013],[-73.77111799999994,71.67082200000004],[-73.791382,71.66110200000014],[-73.89083900000003,71.60942100000005],[-73.98554999999999,71.53414900000013],[-73.99027999999993,71.52748099999997],[-74.01083399999999,71.49136399999998],[-74.09527599999996,71.46276899999998],[-74.16999799999996,71.44581600000004],[-74.303879,71.41943399999997],[-74.31582600000002,71.4144290000001],[-74.31916799999988,71.40942400000006],[-74.31221,71.40554800000001],[-74.29722600000002,71.405823],[-74.191666,71.42553700000013],[-74.15916399999992,71.4327550000001],[-74.12138400000003,71.43858300000005],[-74.08361799999994,71.44108600000004],[-74.04583699999995,71.440811],[-74.02861000000001,71.43775900000009],[-74.06388900000002,71.33692900000005],[-74.09167500000001,71.28553799999997],[-74.10638399999988,71.2747040000001],[-74.137787,71.25582899999995],[-74.152222,71.24803200000002],[-74.18777499999993,71.22943099999998],[-74.20750399999986,71.21971100000007],[-74.21722399999993,71.21499600000004],[-74.22666900000002,71.21220399999999],[-74.23832700000003,71.2038730000001],[-74.24082900000002,71.20082100000013],[-74.2350009999999,71.19831799999997],[-74.22888199999994,71.19941699999998],[-74.21777299999997,71.20220900000004],[-74.19082599999996,71.21110499999998],[-74.15833999999995,71.22387700000002],[-74.148056,71.22859200000005],[-74.11833200000001,71.24331699999999],[-74.039444,71.30219999999997],[-74.00944499999997,71.36080900000002],[-74.006958,71.36720300000007],[-73.97332799999992,71.41360500000013],[-73.96861299999989,71.41943399999997],[-73.86776700000001,71.52581800000002],[-73.86221299999994,71.53109699999999],[-73.76167299999997,71.58082600000006],[-73.74694799999997,71.58526600000005],[-73.73277299999995,71.586929],[-73.68916299999995,71.58804299999997],[-73.65361000000001,71.58749399999999],[-73.63972499999994,71.58638000000002],[-73.62193299999996,71.58332800000011],[-73.59500099999997,71.57527200000004],[-73.58860800000002,71.57222000000013],[-73.56500199999994,71.55192599999998],[-73.56666599999994,71.54414400000002],[-73.598343,71.52832000000012],[-73.61555499999992,71.52026400000005],[-73.61944599999998,71.51582300000013],[-73.63027999999997,71.45664999999991],[-73.63500999999991,71.35942100000011],[-73.62249800000001,71.35664400000002],[-73.61332699999997,71.35582000000005],[-73.59472700000003,71.35775799999999],[-73.54038999999995,71.37286400000005],[-73.51888999999994,71.37915000000004],[-73.51722699999993,71.379974],[-73.51611299999996,71.38581800000003],[-73.51556399999993,71.39888000000002],[-73.51333599999998,71.41304000000014],[-73.50306699999993,71.42469800000015],[-73.49694799999992,71.42858900000004],[-73.47749299999992,71.43637100000001],[-73.44694500000003,71.44026200000008],[-73.428879,71.43580600000013],[-73.38444500000003,71.39193700000004],[-73.38027999999991,71.38526900000005],[-73.38500999999997,71.38192700000013],[-73.50089999999994,71.33721200000002],[-73.59028599999994,71.30497700000006],[-73.61555499999992,71.29637100000014],[-73.62304699999987,71.29109199999999],[-73.63555899999994,71.27970900000014],[-73.66305499999999,71.25416600000005],[-73.678879,71.23803700000008],[-73.712784,71.17776500000014],[-73.71777299999997,71.1649930000001],[-73.71888699999994,71.15942400000012],[-73.71639999999996,71.14498900000001],[-73.71362299999998,71.13749700000005],[-73.71362299999998,71.13053900000006],[-73.71665999999999,71.1183170000001],[-73.72860699999995,71.09860200000008],[-73.73582499999998,71.09332300000011],[-73.74583399999989,71.08859300000012],[-73.76083399999993,71.08471700000001],[-73.77806099999998,71.0816650000001],[-73.79777499999994,71.07887299999999],[-73.84249899999992,71.07443200000012],[-73.87388599999997,71.06971700000008],[-73.890289,71.06498700000003],[-73.898346,71.05748000000011],[-73.89500399999997,71.05220000000003],[-73.88667299999997,71.049149],[-73.87943999999987,71.04775999999998],[-73.872772,71.047485],[-73.85055499999999,71.05998199999999],[-73.84222399999999,71.06414800000005],[-73.75306699999999,71.065811],[-73.73277299999995,71.06776400000012],[-73.71583599999985,71.07165500000002],[-73.69276400000001,71.07943699999998],[-73.67443800000001,71.08831800000007],[-73.66722099999998,71.09359700000005],[-73.660553,71.10386699999998],[-73.65833999999995,71.1249850000001],[-73.66250599999995,71.134995],[-73.66665599999988,71.141663],[-73.67361499999993,71.16303999999997],[-73.66888399999999,71.17303500000008],[-73.62361099999998,71.22554000000014],[-73.61582900000002,71.23027000000013],[-73.54916400000002,71.26998900000007],[-73.45472699999999,71.30026200000003],[-73.43388400000003,71.30859400000003],[-73.42860399999995,71.31442300000003],[-73.42777999999998,71.32720899999993],[-73.43527199999994,71.33221400000002],[-73.43777499999999,71.33638000000008],[-73.43611099999998,71.34054599999996],[-73.43028299999997,71.34165999999999],[-73.38221699999997,71.345261],[-73.36305199999998,71.34582499999999],[-73.34973099999996,71.345261],[-73.32084700000001,71.34082000000012],[-73.08361799999994,71.28581200000008],[-73.06111099999998,71.27748100000002],[-73.04943799999995,71.26832599999994],[-73.05387899999994,71.26165800000001],[-73.06500199999994,71.25833100000006],[-73.15556299999997,71.246643],[-73.214722,71.240814],[-73.23083500000001,71.23831200000012],[-73.24943499999995,71.23387100000002],[-73.26611300000002,71.22499099999999],[-73.27194199999985,71.22053500000004],[-73.26306199999999,71.205826],[-73.25250199999994,71.1952510000001],[-73.24444599999998,71.18887300000011],[-73.23500100000001,71.17330900000002],[-73.23500100000001,71.16220100000004],[-73.23832700000003,71.15721099999996],[-73.247772,71.14415000000002],[-73.25695799999988,71.13388100000003],[-73.29444899999993,71.09248399999996],[-73.31111099999993,71.08082600000012],[-73.327789,71.072769],[-73.37943999999999,71.05831900000004],[-73.42639199999991,71.04775999999998],[-73.44610599999999,71.04109200000005],[-73.45083599999992,71.03526300000004],[-73.45195000000001,71.02943399999998],[-73.44694500000003,71.02499399999999],[-73.37748699999992,70.980545],[-73.36999500000002,70.98580900000002],[-73.17361499999987,71.15693700000003],[-73.16861,71.1705320000001],[-73.17749000000003,71.18525700000004],[-73.18306000000001,71.19136000000003],[-73.18804899999998,71.19914199999994],[-73.185272,71.205826],[-73.18028300000003,71.21165500000001],[-73.17222600000002,71.21638500000006],[-73.14222699999993,71.22442599999994],[-73.11555499999992,71.23027000000013],[-73.10139500000002,71.23165899999998],[-73.07972699999999,71.23165899999998],[-73.06777999999986,71.23027000000013],[-73.04554699999989,71.22554000000014],[-73.02722199999988,71.22720300000003],[-73.01194799999996,71.23442100000005],[-73.00445599999995,71.23970000000003],[-72.99499499999996,71.24999999999994],[-72.98167399999994,71.26748700000002],[-72.952789,71.31109600000008],[-72.95140099999998,71.31608599999998],[-72.95973199999997,71.35582000000005],[-72.96362299999993,71.36248800000004],[-72.97000100000002,71.36998],[-72.9783329999999,71.37637300000011],[-72.989441,71.39166300000011],[-72.99305700000002,71.39776600000005],[-72.99333199999995,71.40193199999993],[-72.98889200000002,71.40554800000001],[-72.97582999999992,71.40914900000007],[-72.89723200000003,71.41665599999999],[-72.85804699999994,71.41331500000013],[-72.83639499999992,71.41331500000013],[-72.76583900000003,71.42387400000001],[-72.75917099999992,71.4269260000001],[-72.75750700000003,71.43193100000013],[-72.758621,71.43748499999998],[-72.76472499999994,71.45166000000006],[-72.76916499999993,71.45915200000002],[-72.67999299999991,71.52470400000004],[-72.64973399999997,71.53692600000005],[-72.61860699999994,71.55941800000011],[-72.61332699999997,71.56553600000007],[-72.61027499999989,71.57193000000012],[-72.608337,71.58387800000014],[-72.61082499999992,71.5955350000001],[-72.608337,71.60664399999996],[-72.593887,71.64248700000002],[-72.58332799999988,71.65138200000007],[-72.58029199999993,71.653595],[-72.57333399999993,71.65664700000013],[-72.55749500000002,71.66026299999999],[-72.53805499999993,71.66081200000013],[-72.52362099999999,71.65887500000008],[-72.50306699999987,71.65026899999998],[-72.47471599999994,71.64276100000012],[-72.44444299999998,71.63610799999998],[-72.30110200000001,71.61219800000015],[-72.15222199999994,71.58998100000008],[-71.84777799999995,71.54664600000012],[-71.689438,71.52442900000005],[-71.670547,71.52221699999996],[-71.635559,71.51776100000006],[-71.58555599999994,71.509995],[-71.554169,71.50387599999999],[-71.45527599999991,71.47303799999997],[-71.44444299999992,71.46859700000005],[-71.435272,71.46360800000008],[-71.29554699999994,71.38472000000013],[-71.241379,71.349426],[-71.12332200000003,71.27165200000002],[-71.11971999999997,71.26416000000006],[-71.122772,71.25721700000008],[-71.128601,71.25138900000013],[-71.14778099999995,71.24192799999997],[-71.16944899999999,71.23332200000004],[-71.20611600000001,71.22053500000004],[-71.22138999999999,71.21693400000004],[-71.23472600000002,71.21276900000004],[-71.32472200000001,71.17776500000014],[-71.34056099999987,71.1705320000001],[-71.34277299999991,71.16638200000011],[-71.34611499999994,71.15582300000005],[-71.3494419999999,71.149429],[-71.4158329999999,71.09332300000011],[-71.452225,71.06805400000013],[-71.46444699999995,71.06248499999998],[-71.47027599999996,71.06137099999995],[-71.48971599999993,71.0619200000001],[-71.55110200000001,71.06469700000002],[-71.60833699999995,71.068604],[-71.64083900000003,71.07388300000014],[-71.714447,71.08804300000008],[-71.81249999999994,71.1041560000001],[-71.84889199999992,71.10832199999999],[-71.86888099999987,71.109421],[-71.89028899999988,71.109421],[-71.91082799999992,71.10775800000005],[-72.069458,71.07527199999998],[-72.08555599999994,71.07026700000011],[-72.09973100000002,71.06387300000006],[-72.110275,71.05220000000003],[-72.11389200000002,71.04721100000006],[-72.114441,71.0435940000001],[-72.11332699999991,71.03749099999999],[-72.10722399999997,71.03027299999997],[-72.09973100000002,71.02026399999994],[-72.101944,71.01609800000006],[-72.16555799999992,70.96804800000007],[-72.17971799999992,70.96220400000004],[-72.20028699999995,70.96110500000003],[-72.23500100000001,70.961929],[-72.261124,70.95915200000013],[-72.27806099999998,70.95526100000006],[-72.29055799999998,70.95109600000006],[-72.29722600000002,70.947205],[-72.31750499999998,70.93026700000007],[-72.319458,70.92581200000006],[-72.31750499999998,70.91832000000011],[-72.31138599999997,70.91110200000008],[-72.31388900000002,70.89971900000006],[-72.32055700000001,70.88832100000008],[-72.32556199999988,70.88247700000005],[-72.33416699999998,70.87858599999998],[-72.514725,70.84443699999997],[-72.5344389999999,70.84193399999998],[-72.65360999999996,70.82777400000009],[-72.6541749999999,70.82083100000011],[-72.51139799999987,70.82720900000004],[-72.476944,70.83332800000005],[-72.40110800000002,70.84971600000011],[-72.35611,70.86053500000003],[-72.30277999999993,70.86720300000002],[-72.26417500000002,70.86665299999999],[-72.25,70.86387600000006],[-72.18472299999996,70.84471100000007],[-72.17222599999997,70.84054600000007],[-72.16361999999998,70.83638000000002],[-72.16221599999989,70.82998700000002],[-72.36332700000003,70.68609600000013],[-72.38194299999998,70.67720000000003],[-72.45944199999997,70.65387000000004],[-72.47582999999992,70.64942900000011],[-72.499435,70.64665200000002],[-72.54249600000003,70.64471400000008],[-72.57806399999998,70.64137300000004],[-72.597778,70.63859599999995],[-72.60916099999997,70.63665800000001],[-72.61582899999996,70.63333100000006],[-72.62332199999997,70.62803600000001],[-72.56945799999988,70.60998500000005],[-72.55166600000001,70.6080320000001],[-72.50306699999987,70.62997399999995],[-72.49055499999997,70.63415500000002],[-72.37193299999996,70.65498400000001],[-72.34222399999993,70.66220099999992],[-72.32611099999991,70.66720600000002],[-72.30638099999999,70.67747500000002],[-72.27749599999987,70.69802899999996],[-72.26472499999994,70.70915199999996],[-72.24861099999998,70.726654],[-72.245834,70.733047],[-72.2369379999999,70.74386600000003],[-72.229172,70.74942000000004],[-72.210556,70.75804099999993],[-72.18554699999993,70.76638800000012],[-72.15583800000002,70.77360500000003],[-72.136124,70.776093],[-72.00473,70.786926],[-71.89695699999993,70.80693100000002],[-71.818893,70.82304400000004],[-71.68916300000001,70.85026600000015],[-71.54388399999999,70.87248199999999],[-71.35444599999994,70.88275099999998],[-71.28750600000001,70.90609700000005],[-71.28916900000002,70.90887500000002],[-71.289444,70.91360500000008],[-71.20834399999995,71.00499000000008],[-71.18554699999987,71.01943999999997],[-71.162216,71.02832000000001],[-70.89555399999995,71.09971600000006],[-70.83612099999993,71.11442600000004],[-70.79972799999996,71.11886600000003],[-70.77166699999998,71.11804200000006],[-70.75556899999992,71.11554000000001],[-70.72471599999994,71.10443099999992],[-70.635559,71.07222000000002],[-70.61389199999996,71.06219499999992],[-70.60472099999993,71.05636600000008],[-70.60166900000002,71.05386400000003],[-70.591949,71.04248000000013],[-70.51472499999994,70.94053600000007],[-70.51251199999996,70.926086],[-70.51445000000001,70.92109700000003],[-70.51972999999998,70.91387900000001],[-70.553604,70.89498900000007],[-70.58944699999995,70.87608300000005],[-70.678879,70.84054600000007],[-70.7408289999999,70.75471500000009],[-70.74694799999992,70.74552900000015],[-70.77333099999998,70.734421],[-70.79888899999992,70.72554000000002],[-70.87249800000001,70.70387299999999],[-70.89111299999996,70.69886800000012],[-70.96583599999997,70.684143],[-71.02444500000001,70.67498799999993],[-71.05526700000001,70.66914400000013],[-71.08277899999996,70.661652],[-71.10055499999993,70.65498400000001],[-71.108612,70.64999399999999],[-71.11805699999996,70.63888500000007],[-71.12805199999997,70.62052900000009],[-71.12943999999999,70.6141510000001],[-71.13444500000003,70.60276799999991],[-71.13999899999993,70.59637499999997],[-71.14778099999995,70.59109500000011],[-71.16027799999995,70.586929],[-71.17527799999999,70.58360299999998],[-71.191666,70.58248900000001],[-71.22471599999994,70.58221400000014],[-71.28167699999989,70.58415200000007],[-71.31249999999994,70.58720400000004],[-71.34584000000001,70.5916600000001],[-71.38972499999994,70.60054000000014],[-71.40750100000002,70.60304300000013],[-71.422775,70.60498000000001],[-71.46194499999996,70.60775799999999],[-71.55860899999993,70.60942100000011],[-71.59277299999997,70.60693400000002],[-71.59555099999994,70.6038670000001],[-71.59583999999995,70.60054000000014],[-71.59249899999992,70.58970600000009],[-71.58667000000003,70.58166500000004],[-71.58389299999993,70.576096],[-71.58029199999999,70.56469700000014],[-71.581955,70.551376],[-71.583618,70.54637100000014],[-71.58805799999993,70.54275500000006],[-71.74360699999994,70.46693399999998],[-71.80305499999997,70.42831400000006],[-71.76306199999993,70.42720000000008],[-71.74804699999999,70.42581199999995],[-71.73638900000003,70.42303500000008],[-71.72721899999999,70.41747999999995],[-71.72805800000003,70.41053800000009],[-71.731674,70.39721700000013],[-71.74638400000003,70.3477630000001],[-71.75556899999998,70.329163],[-71.76306199999993,70.32331800000009],[-71.78306599999996,70.313873],[-71.81666599999994,70.30304000000007],[-71.84416199999998,70.29664600000001],[-71.8497309999999,70.290817],[-71.83694499999996,70.28997800000002],[-71.80694599999987,70.29582200000004],[-71.74804699999999,70.309708],[-71.73361199999994,70.313873],[-71.68638599999991,70.35582000000011],[-71.674713,70.36970500000001],[-71.64167800000001,70.44497700000011],[-71.640289,70.45054600000009],[-71.54333500000001,70.51470899999998],[-71.52528399999994,70.5247040000001],[-71.51000999999997,70.53581200000008],[-71.50250199999994,70.54609699999997],[-71.50167799999997,70.55304000000001],[-71.50334199999998,70.56053199999991],[-71.50750699999998,70.56915300000003],[-71.51167299999997,70.57331800000003],[-71.50695799999994,70.57638500000013],[-71.49554399999994,70.5788730000001],[-71.435272,70.57859800000011],[-71.42027300000001,70.57748400000014],[-71.39778100000001,70.574432],[-71.25306699999993,70.54971300000005],[-71.18499800000001,70.53804000000002],[-71.17582699999997,70.53581200000008],[-71.17027299999995,70.53332499999999],[-71.1677699999999,70.53193700000008],[-71.16250600000001,70.5252690000001],[-71.162216,70.52053799999999],[-71.26055899999989,70.37776200000013],[-71.32250999999997,70.31275900000003],[-71.32167099999998,70.30664100000007],[-71.31834399999997,70.2999880000001],[-71.30110199999996,70.284988],[-71.28889499999997,70.280823],[-71.27999899999998,70.27499399999994],[-71.276947,70.268326],[-71.27833599999985,70.26277199999998],[-71.285278,70.25138899999996],[-71.28916900000002,70.24609400000008],[-71.31695599999995,70.21859699999999],[-71.36305199999987,70.18220499999995],[-71.43472300000002,70.12692300000003],[-71.485275,70.08831800000007],[-71.49804699999993,70.08055100000013],[-71.523056,70.05220000000003],[-71.53277600000001,70.03858900000006],[-71.53916899999996,70.02638200000013],[-71.54110700000001,70.02221700000013],[-71.53582799999992,70.01971400000014],[-71.52806099999998,70.020264],[-71.51806599999998,70.02499399999999],[-71.50029,70.03831500000013],[-71.493607,70.05053700000013],[-71.47582999999997,70.06805400000013],[-71.43804899999998,70.08665500000001],[-71.39361600000001,70.10443099999998],[-71.36665299999999,70.1119230000001],[-71.33168,70.12858599999998],[-71.210556,70.26220699999993],[-71.20889299999999,70.26776100000012],[-71.21305799999999,70.272491],[-71.218887,70.27638200000007],[-71.22972099999998,70.2810970000001],[-71.23194899999993,70.29498300000006],[-71.17166099999997,70.36804200000006],[-71.13583399999993,70.41053800000009],[-71.09306299999997,70.46054100000003],[-71.03056300000003,70.54054300000001],[-71.04998799999993,70.54637100000014],[-71.05305499999997,70.55304000000001],[-71.04943800000001,70.55886800000007],[-71.00584399999997,70.61692800000003],[-70.99722299999996,70.62580899999995],[-70.968887,70.63220200000012],[-70.91305499999999,70.63777199999998],[-70.77111799999994,70.66886900000009],[-70.61193799999995,70.72360200000008],[-70.42166099999986,70.77221700000013],[-70.39695699999999,70.77832000000006],[-70.36527999999993,70.782486],[-70.32472199999995,70.78581200000002],[-70.25500499999998,70.79386899999997],[-70.22888199999994,70.79721100000012],[-70.07501200000002,70.83027600000014],[-69.98805199999998,70.85359200000005],[-69.91583300000002,70.87747200000001],[-69.90472399999993,70.88136300000008],[-69.89277599999991,70.88333100000006],[-69.87388599999997,70.88333100000006],[-69.86527999999993,70.88247700000005],[-69.833618,70.87692300000009],[-69.78443900000002,70.86470000000003],[-69.77111799999994,70.85748300000012],[-69.770554,70.8560940000001],[-69.77250699999996,70.85054000000008],[-69.795837,70.82054100000005],[-69.80888400000003,70.81109600000002],[-69.87943999999993,70.76805100000007],[-69.91555799999992,70.74914600000011],[-69.96528599999994,70.72776799999997],[-70.07389799999993,70.68748499999992],[-70.08473200000003,70.68359400000003],[-70.12165800000002,70.67164600000001],[-70.21055599999994,70.6461030000001],[-70.22555499999993,70.64193699999998],[-70.24499500000002,70.63832100000013],[-70.277222,70.63610799999998],[-70.33805799999999,70.637497],[-70.35333299999996,70.63888500000007],[-70.40777599999996,70.63888500000007],[-70.42332499999998,70.63693200000012],[-70.45472699999999,70.62776200000008],[-70.473053,70.61720300000002],[-70.47694399999995,70.61219799999998],[-70.478882,70.60664400000002],[-70.460556,70.57415800000007],[-70.44276400000001,70.56192000000004],[-70.42416400000002,70.55192600000004],[-70.41139199999998,70.54220599999991],[-70.40472399999993,70.53637700000007],[-70.400284,70.53027300000008],[-70.39750700000002,70.52415500000012],[-70.40167200000002,70.51915000000008],[-70.40777599999996,70.51416],[-70.42332499999998,70.50694300000009],[-70.46722399999999,70.49386600000008],[-70.48222399999992,70.49054000000007],[-70.49082900000002,70.486649],[-70.49444599999998,70.484985],[-70.49610899999999,70.47943099999998],[-70.48889200000002,70.4769290000001],[-70.47778299999999,70.47554000000008],[-70.45916699999998,70.47554000000008],[-70.44137599999993,70.47720300000003],[-70.30972299999996,70.49803199999997],[-70.316666,70.52859499999994],[-70.32000700000003,70.53692600000005],[-70.33167999999995,70.54859900000008],[-70.34861799999993,70.55970799999994],[-70.37110899999993,70.57360800000004],[-70.34445199999993,70.61303700000013],[-70.15833999999995,70.61554000000012],[-70.09249899999998,70.61219799999998],[-70.02333099999998,70.61053500000008],[-69.99221799999998,70.64582800000005],[-69.98777799999993,70.64999399999999],[-69.97860700000001,70.65332000000001],[-69.87582399999991,70.67720000000003],[-69.77583299999998,70.68220500000007],[-69.65139799999997,70.72554000000002],[-69.64916999999991,70.73109400000004],[-69.64472999999998,70.74108899999993],[-69.63861099999997,70.74693300000013],[-69.61999500000002,70.75804099999993],[-69.56916799999993,70.77192700000012],[-69.53832999999986,70.77859500000011],[-69.46972700000003,70.79054300000013],[-69.45140100000003,70.79193100000003],[-69.24276699999996,70.782486],[-69.22694399999995,70.77998400000007],[-69.215012,70.776093],[-69.19055200000003,70.76693700000004],[-69.13194299999998,70.7374880000001],[-68.95805399999995,70.688583],[-68.92832900000002,70.68165600000009],[-68.664444,70.62692300000015],[-68.61860699999994,70.62052900000009],[-68.58250399999997,70.617752],[-68.54972799999996,70.61360200000001],[-68.515289,70.60914600000007],[-68.48472600000002,70.60415600000005],[-68.39056399999998,70.58221400000014],[-68.32556199999993,70.56666599999994],[-68.31388900000002,70.56303400000002],[-68.29361,70.551376],[-68.28416400000003,70.54054300000001],[-68.27917499999995,70.53109700000005],[-68.279449,70.51944000000009],[-68.28138699999994,70.51249700000011],[-68.28971899999999,70.50000000000011],[-68.296112,70.49414100000013],[-68.31361400000003,70.48471100000006],[-68.33168,70.47637900000007],[-68.37193299999996,70.455826],[-68.44665499999996,70.41304000000014],[-68.45140099999998,70.40942400000012],[-68.45361300000002,70.4038700000001],[-68.45195000000001,70.39221200000009],[-68.44915800000001,70.38415500000008],[-68.44860799999998,70.37525900000014],[-68.45167500000002,70.37248200000005],[-68.458618,70.36943100000008],[-68.48500099999995,70.36775200000005],[-68.49527,70.36859099999998],[-68.506393,70.37109399999997],[-68.519455,70.37414600000011],[-68.56138599999991,70.3897090000001],[-68.571121,70.39332600000006],[-68.57583599999992,70.39610299999998],[-68.58084099999996,70.4041600000001],[-68.58056599999998,70.41581700000006],[-68.56973299999999,70.42637600000012],[-68.556107,70.43525700000004],[-68.54998799999998,70.44081100000005],[-68.54804999999993,70.44775400000003],[-68.55694599999998,70.46192900000011],[-68.56471299999993,70.46638500000006],[-68.58250399999997,70.4644320000001],[-68.62165799999997,70.45277400000009],[-68.65083300000003,70.44192500000003],[-68.6541749999999,70.4391480000001],[-68.66166699999991,70.43109099999992],[-68.66665599999999,70.42221100000012],[-68.67027300000001,70.40887499999997],[-68.67083699999995,70.4041600000001],[-68.664444,70.38499499999995],[-68.65722699999998,70.375809],[-68.651947,70.35942099999994],[-68.65055799999993,70.34999100000005],[-68.65110799999997,70.34582499999999],[-68.65388499999995,70.34136999999998],[-68.65695199999999,70.33859300000006],[-68.66416900000002,70.33554100000015],[-68.68249500000002,70.3294370000001],[-68.73554999999988,70.31776400000007],[-68.78416400000003,70.31025699999998],[-68.90695199999993,70.29386900000009],[-68.94137599999999,70.29304500000012],[-69.07194500000003,70.28804000000008],[-69.23500100000001,70.27026400000011],[-69.28388999999999,70.26470900000004],[-69.47389199999998,70.23887600000006],[-69.63999899999988,70.20471200000009],[-69.66805999999997,70.19859300000002],[-69.82389799999999,70.15582300000011],[-69.829453,70.15415999999999],[-69.83612099999999,70.15054300000003],[-69.83972199999994,70.14415000000008],[-69.84083599999991,70.1419370000001],[-69.83972199999994,70.13443000000001],[-69.84306299999997,70.121918],[-69.84889199999998,70.11608899999999],[-69.85694899999993,70.11080900000007],[-69.87582399999991,70.10192900000004],[-69.91776999999996,70.08554100000003],[-69.94665500000002,70.07638500000007],[-69.96833799999996,70.07470699999993],[-69.99027999999993,70.07443200000012],[-70.037781,70.07222000000007],[-70.073059,70.06915300000014],[-70.08612099999999,70.06666600000005],[-70.09695399999998,70.06330900000012],[-70.14138799999995,70.04332],[-70.17443800000001,70.034988],[-70.18276999999989,70.03109699999993],[-70.18554699999999,70.02804600000013],[-70.18276999999989,70.02137800000014],[-70.16999799999996,70.01443499999999],[-70.15449499999994,70.0151600000001],[-70.14750699999996,70.01548800000006],[-70.13950299999993,70.0171590000001],[-70.11332700000003,70.02388000000002],[-70.10305800000003,70.02859500000005],[-70.08999599999999,70.03610200000003],[-70.08889799999992,70.03831500000013],[-70.07749899999999,70.049713],[-70.06695599999995,70.05358900000004],[-70.04998799999987,70.05720500000007],[-70.02861000000001,70.05886800000002],[-70.02027900000002,70.05859400000008],[-69.90110799999997,70.04832500000003],[-69.89222699999993,70.0458220000001],[-69.88473499999992,70.042755],[-69.85360700000001,70.02970900000003],[-69.83555599999994,70.020264],[-69.82749899999999,70.01443499999999],[-69.82084699999996,70.0080410000001],[-69.81304899999992,69.99859600000002],[-69.81221,69.9910890000001],[-69.81555200000003,69.98471100000012],[-69.82250999999991,69.98165900000004],[-69.83750899999995,69.97831700000012],[-69.85139500000002,69.97831700000012],[-69.89750700000002,69.98304700000011],[-69.93638599999997,69.98942599999998],[-69.96333299999998,69.99165300000004],[-69.98138399999999,69.99165300000004],[-70.00306699999993,69.98970000000008],[-70.0574949999999,69.98109399999998],[-70.09889199999992,69.97360200000008],[-70.16444399999989,69.96165500000012],[-70.21888699999994,69.9416500000001],[-70.22332799999998,69.93803400000002],[-70.22389199999998,69.92970300000013],[-70.21806299999997,69.92526200000003],[-70.21611000000001,69.92053199999998],[-70.22027600000001,69.91554300000001],[-70.22860700000001,69.91165199999995],[-70.291382,69.8894350000001],[-70.38417099999998,69.86053500000003],[-70.40139799999997,69.85914600000007],[-70.42222599999997,69.86080900000013],[-70.43249500000002,69.86248799999998],[-70.44387799999993,69.86053500000003],[-70.45056199999999,69.85720800000007],[-70.46722399999999,69.84471100000013],[-70.46861299999995,69.842758],[-70.46028099999995,69.8416600000001],[-70.436935,69.83943199999993],[-70.41221599999994,69.83776900000004],[-70.396118,69.83720399999999],[-70.38417099999998,69.83720399999999],[-70.37277199999988,69.83831800000013],[-70.35583499999996,69.8413700000001],[-70.343613,69.84526099999994],[-70.25527999999991,69.87914999999998],[-70.19276400000001,69.90776100000011],[-70.13694800000002,69.93331899999998],[-70.12609899999995,69.94053600000012],[-70.09861799999999,69.95304900000002],[-70.07667500000002,69.95803799999999],[-70.05943300000001,69.95971699999996],[-69.97860700000001,69.964157],[-69.94193999999999,69.96304300000003],[-69.925003,69.96110500000009],[-69.89695699999999,69.95610000000005],[-69.86805700000002,69.95332300000013],[-69.83750899999995,69.95277399999998],[-69.81311,69.9554290000001],[-69.777222,69.96360800000002],[-69.75083899999993,69.97248800000006],[-69.74554399999994,69.97470100000004],[-69.73805199999993,69.98136900000003],[-69.73554999999993,69.98553500000008],[-69.735275,69.99053999999995],[-69.739441,70.00138900000002],[-69.74415599999998,70.0080410000001],[-69.76000999999997,70.01748700000007],[-69.76945499999994,70.02137800000014],[-69.78111299999995,70.02499399999999],[-69.795547,70.03166199999998],[-69.80471799999987,70.03887900000007],[-69.80888400000003,70.049713],[-69.80694599999998,70.055252],[-69.79277000000002,70.080826],[-69.79028299999993,70.084991],[-69.78388999999999,70.0894320000001],[-69.74082900000002,70.11415100000005],[-69.67582699999991,70.13970899999998],[-69.65333599999991,70.14498900000001],[-69.42610199999996,70.17608600000011],[-69.40417500000001,70.17776500000014],[-69.21945199999999,70.188309],[-69.18249499999996,70.18719500000003],[-69.16999799999991,70.18609600000002],[-69.15472399999999,70.18331899999998],[-69.011124,70.17831400000011],[-68.93693499999995,70.19303900000006],[-68.85916099999986,70.20304899999996],[-68.83917200000002,70.20359800000006],[-68.69722000000002,70.2038730000001],[-68.68277,70.20359800000006],[-68.67832900000002,70.20248400000008],[-68.67639199999996,70.20166000000012],[-68.64750700000002,70.15832499999999],[-68.64250199999998,70.14942900000005],[-68.64500399999991,70.14526400000005],[-68.741379,70.06526200000008],[-68.74665800000002,70.06248499999998],[-68.78306600000002,70.04443399999997],[-68.80055199999998,70.03749099999999],[-68.81332399999997,70.032761],[-68.86805699999996,70.01693700000004],[-68.90028399999994,70.01165800000007],[-68.954453,70.00471500000009],[-69.08860800000002,69.97499100000005],[-69.15306099999998,69.95304900000002],[-69.31310999999994,69.88229400000006],[-69.346115,69.855545],[-69.37054399999994,69.83998100000008],[-69.398056,69.82859800000006],[-69.42694099999994,69.81971699999997],[-69.43971299999993,69.8163760000001],[-69.460556,69.813309],[-69.474716,69.81359900000001],[-69.516953,69.81999200000013],[-69.54333500000001,69.82693499999993],[-69.56582600000002,69.83415200000007],[-69.58084100000002,69.836929],[-69.68388400000003,69.83998100000008],[-69.71389799999997,69.83998100000008],[-69.74499500000002,69.83776900000004],[-69.76000999999997,69.834991],[-69.77084400000001,69.83194000000003],[-69.80583200000001,69.81999200000013],[-69.827789,69.80941800000011],[-69.84416199999993,69.80026199999998],[-69.85583499999996,69.79359399999998],[-69.87249799999995,69.78109699999999],[-69.99804699999999,69.66998300000012],[-70,69.66415400000011],[-70.00083899999998,69.6560970000001],[-70.00140399999998,69.62275700000004],[-69.99888599999991,69.6160890000001],[-69.99055499999992,69.61499000000009],[-69.94444299999998,69.649719],[-69.816956,69.72442600000005],[-69.81082199999997,69.72886699999998],[-69.808334,69.733047],[-69.808334,69.73803700000002],[-69.81471299999987,69.75471500000009],[-69.81500199999999,69.76026900000011],[-69.81416300000001,69.76388499999996],[-69.80555700000002,69.77249100000006],[-69.78306600000002,69.78581200000002],[-69.764725,69.79553199999992],[-69.75445599999995,69.799713],[-69.74194299999999,69.8035890000001],[-69.73083500000001,69.80609099999998],[-69.71333300000003,69.80748],[-69.64306599999998,69.81080600000001],[-69.60278299999999,69.80970800000011],[-69.5727839999999,69.80442800000003],[-69.56111099999998,69.79998800000004],[-69.54527300000001,69.79443400000002],[-69.48998999999992,69.77970900000008],[-69.45666499999993,69.77581800000002],[-69.44665500000002,69.77554300000003],[-69.40916399999998,69.77638199999996],[-69.39584400000001,69.77777100000014],[-69.38473499999992,69.78082300000005],[-69.37805199999997,69.78387500000002],[-69.31388900000002,69.8163760000001],[-69.291382,69.83109999999994],[-69.27944899999994,69.84248400000007],[-69.26916499999993,69.85276800000008],[-69.25306699999999,69.86219800000015],[-69.20056199999988,69.88360600000004],[-69.18804899999998,69.88777199999998],[-69.10194399999995,69.91609199999999],[-69.07667499999997,69.92387400000013],[-68.94554099999999,69.94999700000005],[-68.93388400000003,69.95109600000006],[-68.87027,69.95304900000002],[-68.80194099999989,69.95220899999998],[-68.76666299999988,69.94886800000012],[-68.75195300000001,69.94663999999995],[-68.62281799999994,69.98240699999991],[-68.47166400000003,70.04664600000007],[-68.33833300000003,70.0641480000001],[-68.241379,70.09582500000005],[-68.22138999999999,70.10276800000003],[-68.20722999999998,70.109421],[-68.19638099999997,70.11943100000008],[-68.193604,70.12359600000008],[-68.20333899999997,70.12886000000009],[-68.22944599999994,70.13526900000011],[-68.26861600000001,70.13749700000011],[-68.2908329999999,70.13720700000005],[-68.30833399999995,70.13526900000011],[-68.32055700000001,70.13554399999998],[-68.333618,70.13916],[-68.34916699999985,70.16804500000006],[-68.34861799999999,70.1727600000001],[-68.34527599999996,70.18803400000002],[-68.31861899999996,70.21859699999999],[-68.31361400000003,70.22221400000012],[-68.16000400000001,70.28276100000011],[-68.03944399999995,70.301376],[-67.80804399999994,70.262497],[-67.79472399999997,70.25888100000009],[-67.77417000000003,70.25054900000009],[-67.76806599999998,70.24386600000014],[-67.76000999999991,70.22970600000002],[-67.74055499999986,70.21887200000015],[-67.69721999999996,70.2022090000001],[-67.67443799999995,70.19358799999998],[-67.648056,70.18609600000002],[-67.59167499999995,70.16526799999997],[-67.57556199999993,70.15832499999999],[-67.55694599999998,70.14915500000012],[-67.52833599999997,70.13388100000003],[-67.41221599999994,70.0688780000001],[-67.40472399999999,70.06442300000009],[-67.37805200000003,70.04803500000003],[-67.24249299999997,69.958328],[-67.222778,69.94386300000008],[-67.216949,69.93775900000003],[-67.15249599999999,69.81776400000001],[-67.14862099999999,69.81025700000009],[-67.12777699999987,69.72692900000004],[-67.193604,69.721924],[-67.37138400000003,69.71443200000004],[-67.39111300000002,69.71388200000001],[-67.40695199999988,69.71470599999998],[-67.43611099999993,69.71914700000008],[-67.49999999999994,69.73183399999999],[-67.60249299999992,69.7502750000001],[-67.761124,69.77859500000011],[-67.77305599999994,69.7794340000001],[-67.81082200000003,69.77886999999993],[-67.99610899999999,69.77442900000005],[-68.01306199999999,69.77192700000012],[-68.087784,69.75610400000011],[-68.208054,69.71554600000002],[-68.21665999999993,69.71026599999999],[-68.22277799999995,69.70471199999997],[-68.2286069999999,69.69136000000015],[-68.23028599999998,69.68441800000005],[-68.24110399999995,69.67498799999998],[-68.31138599999997,69.63333100000011],[-68.323624,69.62886000000003],[-68.329453,69.62776200000013],[-68.35278299999999,69.62692300000015],[-68.49638399999998,69.625809],[-68.51806599999992,69.62608300000011],[-68.62026999999989,69.63720699999999],[-68.64527899999996,69.64109800000006],[-68.83999599999999,69.6160890000001],[-68.98083499999996,69.589157],[-69.18859900000001,69.54193099999992],[-69.20111099999991,69.53804000000002],[-69.22000100000002,69.53581200000008],[-69.32501200000002,69.53248600000006],[-69.34277299999997,69.53248600000006],[-69.36416599999995,69.53776600000009],[-69.41027799999995,69.54609700000003],[-69.42694099999994,69.54803500000014],[-69.54943800000001,69.56053199999997],[-69.630829,69.56721500000009],[-69.68888900000002,69.56944300000009],[-69.73777799999999,69.56832900000006],[-69.75111400000003,69.56721500000009],[-69.83860800000002,69.55886800000013],[-70.0308379999999,69.53610200000008],[-70.02861000000001,69.53082300000011],[-70.025284,69.52748100000002],[-70.011124,69.52110300000004],[-69.995544,69.51721199999997],[-69.964722,69.51388500000002],[-69.89944499999996,69.50721700000008],[-69.88583399999999,69.50721700000008],[-69.86694299999988,69.50943000000001],[-69.84416199999993,69.51748700000002],[-69.82444800000002,69.52720599999998],[-69.81582600000002,69.53054800000012],[-69.803879,69.53498800000011],[-69.78944399999995,69.538589],[-69.73277300000001,69.54525800000005],[-69.69860799999992,69.54832499999998],[-69.68499799999995,69.54887400000013],[-69.66332999999992,69.54832499999998],[-69.61389199999991,69.54304500000012],[-69.506958,69.52943399999992],[-69.44999699999988,69.5188750000001],[-69.37582399999991,69.50972000000002],[-69.34306299999997,69.50582899999995],[-69.32333399999999,69.50526400000012],[-69.29998799999993,69.506104],[-69.20666499999999,69.51499899999999],[-69.1516719999999,69.52026400000005],[-69.00584400000002,69.53581200000008],[-68.99527,69.53970300000015],[-68.98222399999997,69.547211],[-68.97138999999999,69.5558170000001],[-68.95722999999998,69.56053199999997],[-68.9261019999999,69.566666],[-68.76945499999988,69.58749400000005],[-68.75250199999988,69.58943199999999],[-68.6683349999999,69.59082000000006],[-68.61193800000001,69.58749400000005],[-68.54472399999992,69.57998700000013],[-68.52806099999992,69.57720899999993],[-68.31722999999988,69.53027300000008],[-68.29333499999996,69.52360499999992],[-68.18194599999998,69.49832200000003],[-68.02555799999999,69.46609500000005],[-67.98222399999997,69.45748900000012],[-67.94610599999993,69.45471200000003],[-67.92639200000002,69.45416300000011],[-67.89334099999996,69.45443700000004],[-67.87416100000002,69.45664999999997],[-67.86193799999995,69.46026600000005],[-67.84083599999997,69.46943699999997],[-67.81945799999994,69.4769290000001],[-67.80694599999987,69.48082],[-67.79222099999998,69.48414600000001],[-67.60499600000003,69.47804300000007],[-67.56221,69.47192400000006],[-67.51167299999997,69.46609500000005],[-67.47582999999997,69.46304299999991],[-67.43277,69.46331800000013],[-67.30526699999996,69.46720900000003],[-67.25834700000001,69.46748400000001],[-67.21000699999996,69.46138000000002],[-67.18083200000001,69.45471200000003],[-66.921112,69.3791500000001],[-66.79554699999989,69.341095],[-66.78527799999995,69.3372040000001],[-66.77444499999996,69.33194000000009],[-66.76722699999993,69.32748400000003],[-66.69499200000001,69.28166199999998],[-66.68276999999995,69.27026400000011],[-66.65028399999994,69.23637400000001],[-66.64584400000001,69.22499100000005],[-66.64666699999998,69.20359800000011],[-66.65861499999994,69.188309],[-66.66833500000001,69.17831400000011],[-66.68943799999994,69.16192600000005],[-66.72000100000002,69.14415000000008],[-66.73055999999997,69.13888500000002],[-66.75306699999993,69.12942499999997],[-66.75862099999995,69.12803600000012],[-66.77610799999997,69.12886000000009],[-66.837219,69.13581800000009],[-66.84944200000001,69.13832100000008],[-66.912781,69.15498400000013],[-66.9283289999999,69.164154],[-66.95333900000003,69.172211],[-66.96528599999999,69.17442300000005],[-66.99694799999997,69.17776499999997],[-67.132767,69.18248],[-67.37193299999996,69.18441799999994],[-67.38555899999994,69.18386800000013],[-67.41471899999999,69.17831400000011],[-67.42721599999999,69.17442300000005],[-67.45889299999993,69.1624910000001],[-67.46610999999996,69.16081200000008],[-67.50556899999998,69.15748600000006],[-67.52111799999994,69.15776100000005],[-67.64862099999999,69.16693100000009],[-67.67639199999996,69.16943400000008],[-67.86416600000001,69.22192400000012],[-68.18447900000001,69.30801400000001],[-68.20973200000003,69.31137099999995],[-68.22166399999998,69.31219499999992],[-68.23277299999995,69.31137099999995],[-68.25195300000001,69.30970800000006],[-68.285278,69.30442800000014],[-68.31082200000003,69.29859899999997],[-68.32749899999999,69.29609700000009],[-68.34416199999998,69.29470800000007],[-68.35583500000001,69.29414400000013],[-68.37554899999992,69.29470800000007],[-68.46472199999994,69.30165100000005],[-68.67527799999999,69.32222000000002],[-68.74027999999998,69.33055100000013],[-68.811935,69.34193399999992],[-68.84445199999999,69.34610000000004],[-68.94471699999991,69.35498000000007],[-68.962784,69.35636900000003],[-68.98443600000002,69.35693400000008],[-69.015015,69.35498000000007],[-69.04028299999999,69.34971600000006],[-69.17666599999995,69.31080600000013],[-69.20306399999993,69.30304000000007],[-69.24137899999988,69.28414900000001],[-69.25389099999995,69.27526899999998],[-69.25778200000002,69.27026400000011],[-69.25167799999997,69.26361099999997],[-69.24694799999997,69.26110799999998],[-69.23500100000001,69.25972000000007],[-69.22193899999996,69.26165800000001],[-69.21305799999993,69.26470900000004],[-69.20333900000003,69.26998900000012],[-69.197769,69.27554299999991],[-69.17639200000002,69.28749099999999],[-69.15638699999994,69.297485],[-69.146118,69.30053700000008],[-69.133331,69.303314],[-69.01333599999998,69.32748400000003],[-68.95666499999987,69.33194000000009],[-68.94110099999995,69.33248900000007],[-68.92138699999987,69.33194000000009],[-68.6583399999999,69.30026200000009],[-68.537216,69.28526299999999],[-68.50473,69.28027299999997],[-68.33056599999992,69.27526899999998],[-68.25195300000001,69.27748100000008],[-68.23083500000001,69.27777100000009],[-68.19860799999998,69.27470399999999],[-68.17222599999997,69.26971400000008],[-68.15943899999996,69.26609800000006],[-68.14834599999989,69.26165800000001],[-68.13972499999988,69.25776699999994],[-68.08860800000002,69.2288670000001],[-68.083618,69.22554000000014],[-68.07749899999988,69.21748400000007],[-68.08167999999995,69.211929],[-68.09138499999995,69.20555100000007],[-68.103882,69.2022090000001],[-68.12971500000003,69.19775400000009],[-68.16305499999993,69.19999700000005],[-68.26306199999999,69.21138000000008],[-68.41082799999992,69.22137499999997],[-68.54998799999998,69.22692899999998],[-68.64361600000001,69.22943100000003],[-68.664444,69.22804300000013],[-68.68998699999992,69.22360200000003],[-68.83972199999994,69.21470600000009],[-68.92304999999999,69.2208250000001],[-68.96777299999997,69.22109999999998],[-68.94833399999987,69.21415699999994],[-68.93971299999987,69.211929],[-68.91305499999999,69.20748900000001],[-68.86277799999999,69.20193499999999],[-68.80749499999996,69.19886800000006],[-68.78805499999999,69.19831800000003],[-68.76722699999999,69.19970700000005],[-68.73777799999999,69.20359800000011],[-68.70472699999999,69.20915200000007],[-68.65695199999999,69.21054100000009],[-68.61805700000002,69.20915200000007],[-68.515015,69.20248400000014],[-68.50250199999999,69.19859300000007],[-68.50527999999991,69.19581599999998],[-68.51390100000003,69.19192500000008],[-68.69055199999997,69.141098],[-68.70722999999992,69.13832100000008],[-68.872772,69.12052900000003],[-68.99804699999999,69.10359199999999],[-68.96167000000003,69.10386700000004],[-68.92971799999992,69.10026600000015],[-68.92694099999994,69.09832800000004],[-68.92666600000001,69.07998700000002],[-68.95777900000002,69.00526400000001],[-68.95889299999999,69.00305200000014],[-68.96916199999993,68.99359100000004],[-68.99415599999992,68.982483],[-69.00611899999996,68.97831700000012],[-69.01888999999989,68.97581500000007],[-69.028885,68.97137500000002],[-69.02583300000003,68.96859700000005],[-69.01750199999998,68.966385],[-69.00556899999992,68.96470599999998],[-68.99804699999999,68.96499599999999],[-68.973053,68.97082499999999],[-68.962784,68.97470100000004],[-68.94638099999992,68.982483],[-68.93055700000002,68.99275200000005],[-68.92027299999995,69.00277699999998],[-68.89416499999993,69.04498299999995],[-68.89416499999993,69.05053700000013],[-68.89222699999999,69.06219499999997],[-68.889725,69.06637600000005],[-68.88194299999986,69.07777400000009],[-68.87916599999994,69.08137499999992],[-68.8724979999999,69.084991],[-68.85833699999989,69.08831800000013],[-68.75361599999997,69.10971100000006],[-68.471115,69.166382],[-68.41278099999994,69.17692600000004],[-68.38137799999993,69.17526200000003],[-68.35139499999997,69.17164600000012],[-68.17832900000002,69.14665199999996],[-68.089447,69.126083],[-67.72528099999994,69.03221100000013],[-67.715012,69.0291600000001],[-67.708054,69.02470400000004],[-67.70584099999996,69.01638800000012],[-67.72111499999994,69.00972000000013],[-67.97471599999994,68.9727630000001],[-68.02944899999994,68.97137500000002],[-68.05888400000003,68.97360200000008],[-68.21112099999993,68.99192800000009],[-68.241379,68.99693300000013],[-68.26806599999998,69.00277699999998],[-68.31416299999995,69.0105440000001],[-68.33500700000002,69.00915500000008],[-68.53555299999988,68.98414600000012],[-68.54861499999998,68.98220800000001],[-68.55277999999998,68.97720300000015],[-68.55471799999992,68.97110000000004],[-68.556107,68.964157],[-68.54527299999995,68.95971700000001],[-68.44055200000003,68.9727630000001],[-68.33750900000001,68.98580900000007],[-68.32028199999996,68.98637400000007],[-68.30305499999997,68.98580900000007],[-68.29055799999998,68.98220800000001],[-68.285278,68.97747800000013],[-68.28443900000002,68.97470100000004],[-68.26417500000002,68.96470599999998],[-68.19694500000003,68.94999700000011],[-68.18666100000002,68.94775400000015],[-68.16944899999999,68.94693000000001],[-68.15222199999994,68.94693000000001],[-68.116104,68.94747899999993],[-68.08167999999995,68.94747899999993],[-68.06416300000001,68.94609100000002],[-68.04834,68.94386300000008],[-68.03999299999998,68.94136000000009],[-67.97471599999994,68.86526500000008],[-67.972778,68.85914600000007],[-67.97749299999998,68.855545],[-67.98693800000001,68.85443100000003],[-68.0061189999999,68.85497999999995],[-68.08222999999998,68.86248799999998],[-68.129166,68.867752],[-68.18360899999999,68.87858600000004],[-68.24221799999987,68.88998400000003],[-68.25611900000001,68.89221200000003],[-68.289444,68.89498900000012],[-68.37388599999997,68.89721700000007],[-68.475281,68.89942900000011],[-68.48999000000003,68.897491],[-68.49166899999994,68.89665200000002],[-68.48889200000002,68.893326],[-68.48582499999992,68.89027400000009],[-68.47721899999993,68.88693200000012],[-68.46333300000003,68.88554400000004],[-68.43249499999996,68.88333100000006],[-68.37304699999993,68.88220200000012],[-68.35360699999995,68.88108799999992],[-68.29305999999997,68.87498499999998],[-68.266663,68.86998000000011],[-68.17971799999992,68.85192899999998],[-68.13389599999994,68.83720399999999],[-68.00834700000001,68.81666600000011],[-67.972778,68.81192000000004],[-67.95556599999998,68.81025700000009],[-67.91694599999994,68.80831899999998],[-67.88667299999992,68.80886800000007],[-67.86138900000003,68.80554200000006],[-67.77833599999991,68.78610200000008],[-67.77194199999997,68.78276100000005],[-67.77139299999993,68.78137200000003],[-67.77471899999995,68.77915999999999],[-67.80332900000002,68.77415500000012],[-67.82000699999998,68.7727660000001],[-67.85777299999995,68.77137800000003],[-67.872772,68.77165200000013],[-67.915009,68.77415500000012],[-67.94444299999992,68.77804600000002],[-68.07611099999997,68.80192599999998],[-68.17083699999989,68.81469700000008],[-68.35221899999993,68.83248899999995],[-68.42639200000002,68.83915700000011],[-68.54666099999997,68.84664900000007],[-68.56555199999997,68.84721400000012],[-68.58805799999999,68.84637499999997],[-68.60610999999989,68.842758],[-68.61054999999999,68.83915700000011],[-68.61166399999996,68.83581500000003],[-68.60444599999994,68.83137499999998],[-68.593887,68.82748400000008],[-68.55776999999995,68.82138099999997],[-68.52694699999995,68.79525800000005],[-68.60249299999992,68.794983],[-68.67887899999994,68.79664600000012],[-68.79527300000001,68.79942300000005],[-68.80722000000003,68.80026199999998],[-68.90028399999994,68.80720500000001],[-68.96749899999992,68.81469700000008],[-68.99527,68.81915300000003],[-69.00389100000001,68.82222000000013],[-69.015015,68.8272090000001],[-69.10583500000001,68.84860200000003],[-69.25111400000003,68.87248199999999],[-69.28083799999996,68.87580900000012],[-69.32305899999994,68.8766480000001],[-69.36193800000001,68.87414600000005],[-69.37805199999997,68.87136800000002],[-69.38999899999999,68.86747699999995],[-69.398056,68.86219800000015],[-69.394455,68.85775799999999],[-69.37999000000002,68.85497999999995],[-69.36082499999992,68.85443100000003],[-69.33167999999995,68.85693400000002],[-69.27944899999994,68.855255],[-69.24554399999988,68.85137900000012],[-69.18554699999999,68.84220900000008],[-69.171112,68.83888200000013],[-69.16221599999994,68.83581500000003],[-69.15222199999994,68.82804899999996],[-69.15388499999995,68.8272090000001],[-69.16305499999999,68.826096],[-69.22999600000003,68.8272090000001],[-69.29415899999992,68.83194000000003],[-69.31500199999999,68.83166499999999],[-69.35777300000001,68.82916300000011],[-69.368607,68.8272090000001],[-69.37554899999998,68.82499700000005],[-69.382767,68.81915300000003],[-69.383896,68.8163760000001],[-69.38137799999998,68.81498699999992],[-69.37110899999999,68.81275900000014],[-69.193604,68.80415300000004],[-68.971115,68.79193100000009],[-68.95916699999992,68.78970300000015],[-68.94499200000001,68.78692600000005],[-68.94249000000002,68.78498800000011],[-68.19638099999997,68.70694000000015],[-68.04943799999995,68.68165599999998],[-68.04499800000002,68.67831400000006],[-68.04611199999994,68.67637600000006],[-68.08750899999995,68.62942500000008],[-68.09445199999993,68.62776200000013],[-68.34445199999999,68.6285860000001],[-68.56220999999988,68.65193199999999],[-68.62193300000001,68.65582300000005],[-68.65777600000001,68.65637200000015],[-68.68028300000003,68.65554800000001],[-68.74777199999994,68.64915500000006],[-68.77778599999994,68.64305100000001],[-68.89416499999993,68.60720800000001],[-68.90249599999999,68.6035920000001],[-68.90028399999994,68.60304300000001],[-68.83583099999998,68.589157],[-68.804169,68.58998099999997],[-68.75767499999995,68.60064699999998],[-68.74934399999995,68.60265400000014],[-68.73500100000001,68.60731499999997],[-68.71116599999999,68.62114700000012],[-68.67999299999991,68.63081400000004],[-68.64750700000002,68.6355440000001],[-68.62860099999989,68.6355440000001],[-68.59416199999993,68.63360599999999],[-68.56304899999992,68.62942500000008],[-68.53332499999999,68.62498500000004],[-68.48138399999993,68.61499000000015],[-68.475281,68.61303700000002],[-68.47027600000001,68.60914600000012],[-68.46945199999999,68.60636900000003],[-68.48332199999999,68.59693900000013],[-68.50389100000001,68.58998099999997],[-68.519455,68.58581500000008],[-68.53388999999993,68.58387800000003],[-68.60583499999996,68.57887299999999],[-68.64834599999995,68.57777399999998],[-68.66000400000001,68.57887299999999],[-68.68288399999994,68.57521100000002],[-68.69506100000001,68.57437900000014],[-68.70705399999997,68.57337200000012],[-68.71238700000004,68.572044],[-68.71606400000002,68.56938200000002],[-68.71672799999993,68.56804700000004],[-68.70705399999997,68.5660400000001],[-68.69672400000002,68.56520799999998],[-68.656113,68.559708],[-68.46000700000002,68.56219500000009],[-68.44722000000002,68.56359900000007],[-68.43527199999994,68.56749000000013],[-68.42721599999999,68.57193000000001],[-68.42277499999994,68.57609600000006],[-68.4202729999999,68.57971199999992],[-68.41999799999996,68.5852660000001],[-68.41639700000002,68.59136999999998],[-68.39611799999994,68.59304800000007],[-68.337784,68.59332300000011],[-68.24444599999998,68.58804300000003],[-68.21556099999987,68.58554100000015],[-68.13667299999997,68.57222000000002],[-68.06534599999992,68.54582200000004],[-67.92027300000001,68.534424],[-67.86694299999999,68.50972000000007],[-67.80915800000002,68.5310970000001],[-67.67304999999993,68.56109600000008],[-67.66416900000002,68.56275900000003],[-67.64361599999995,68.56275900000003],[-67.53944399999995,68.55081200000006],[-67.52555799999999,68.54859899999991],[-67.50083899999993,68.53831500000007],[-67.49221799999992,68.52720600000004],[-67.49305699999996,68.52360499999998],[-67.502228,68.51499900000005],[-67.510559,68.51138299999997],[-67.51916499999993,68.50915500000002],[-67.54305999999991,68.506104],[-67.60777300000001,68.50387600000005],[-67.62165800000002,68.5],[-67.62805200000003,68.49636800000002],[-67.63473499999992,68.486649],[-67.62138399999998,68.38442999999995],[-67.618607,68.38108800000003],[-67.61250299999995,68.37942499999991],[-67.6033329999999,68.37886000000009],[-67.59445199999999,68.38136300000008],[-67.55110200000001,68.41442899999998],[-67.54834,68.44026200000013],[-67.5494379999999,68.44386300000002],[-67.55583200000001,68.45526100000001],[-67.51112399999994,68.4833220000001],[-67.42610200000001,68.49443099999996],[-67.335556,68.49693300000007],[-67.31639100000001,68.49609400000008],[-67.23249799999996,68.480545],[-67.22416699999997,68.47665400000011],[-67.21749899999992,68.47192400000006],[-67.21362299999993,68.44081100000005],[-67.223053,68.42608600000011],[-67.30777,68.42330900000002],[-67.32583599999998,68.42137100000008],[-67.33277900000002,68.41886900000003],[-67.33583099999998,68.4160920000001],[-67.33860800000002,68.41192600000005],[-67.33805799999999,68.40998800000006],[-67.32444800000002,68.40776100000005],[-67.15695199999999,68.40637200000003],[-67.11193800000001,68.41192600000005],[-67.10499600000003,68.414154],[-67.10055499999993,68.41832000000005],[-67.09722899999997,68.45138500000013],[-67.100281,68.45721400000014],[-67.10665899999987,68.46054100000009],[-67.11665299999999,68.46360799999997],[-67.12721299999998,68.46804800000001],[-67.12999000000002,68.47276300000004],[-67.126938,68.47554000000014],[-67.11277799999999,68.4788670000001],[-66.90805099999994,68.4538730000001],[-66.821396,68.46527100000009],[-66.80305499999997,68.46720900000003],[-66.78750600000001,68.4649960000001],[-66.706955,68.44470200000012],[-66.69776899999994,68.42803999999995],[-66.72416699999991,68.42915300000004],[-66.78277599999996,68.42608600000011],[-66.90499899999992,68.41638200000011],[-66.92054699999994,68.41110200000008],[-66.92166099999992,68.40832499999999],[-66.9141689999999,68.39888000000008],[-66.91305499999999,68.39498900000001],[-66.914444,68.3919370000001],[-66.93638599999997,68.37442000000004],[-66.94665499999991,68.36998000000006],[-66.95500199999998,68.36747700000006],[-67.00584399999997,68.35443099999998],[-67.01112399999994,68.35359199999999],[-67.02416999999997,68.35386699999998],[-67.04888900000003,68.35582000000011],[-67.07556199999993,68.36053500000014],[-67.11138899999997,68.37025500000004],[-67.13027999999991,68.37970000000013],[-67.14222699999999,68.38275099999998],[-67.23055999999997,68.39498900000001],[-67.245544,68.395828],[-67.28639199999998,68.395828],[-67.37971500000003,68.39082300000013],[-67.41111799999993,68.38275099999998],[-67.41555799999998,68.37803600000012],[-67.41888399999999,68.376373],[-67.45556599999992,68.36775200000011],[-67.49471999999997,68.36080900000007],[-67.59527600000001,68.34776299999999],[-67.63166799999999,68.34526100000011],[-67.64611799999994,68.34471100000007],[-67.74388099999999,68.34332299999994],[-67.78138699999994,68.3372040000001],[-67.81054699999999,68.328598],[-67.83222999999992,68.32026700000011],[-67.84973099999996,68.30998199999999],[-67.86582900000002,68.29971299999994],[-67.87110899999999,68.292755],[-67.87832600000002,68.26527400000009],[-67.86972000000003,68.25999500000012],[-67.86000100000001,68.25833100000011],[-67.845551,68.25888099999997],[-67.83332799999994,68.26138300000002],[-67.82667500000002,68.26443499999993],[-67.8202819999999,68.26859999999994],[-67.81806899999992,68.27415500000006],[-67.82112099999995,68.284988],[-67.82055700000001,68.28970300000003],[-67.81555199999997,68.29220600000002],[-67.75250199999999,68.3188780000001],[-67.74526999999989,68.32054100000005],[-67.597778,68.32304400000004],[-67.58306900000002,68.30802900000003],[-67.57223499999998,68.27331499999997],[-67.57667500000002,68.26859999999994],[-67.583328,68.26554899999996],[-67.59167499999995,68.26304600000014],[-67.61639400000001,68.25833100000011],[-67.64666699999998,68.25360100000006],[-67.662781,68.25248700000009],[-67.689438,68.24803200000008],[-67.695267,68.24247700000001],[-67.69499200000001,68.2410890000001],[-67.69082600000002,68.23970000000008],[-67.67971799999992,68.23887600000012],[-67.666946,68.23997500000013],[-67.57972699999993,68.25138900000002],[-67.5708469999999,68.25305200000014],[-67.55166600000001,68.25833100000011],[-67.54695099999998,68.2605440000001],[-67.53916900000002,68.26582300000007],[-67.53306600000002,68.27137800000014],[-67.53111299999995,68.27832000000006],[-67.53500400000001,68.28553800000003],[-67.541382,68.28887900000007],[-67.54611199999994,68.29414400000013],[-67.54499799999996,68.29637100000002],[-67.54028299999993,68.29971299999994],[-67.52389499999998,68.30859400000008],[-67.49415599999998,68.32193000000001],[-67.401947,68.35247800000002],[-67.39472999999998,68.3541560000001],[-67.38555899999994,68.35443099999998],[-67.24388099999999,68.35832200000004],[-67.23249799999996,68.35748300000006],[-67.18249500000002,68.34942600000011],[-67.13027999999991,68.34082000000001],[-67.07806399999993,68.3311000000001],[-67.01611300000002,68.318604],[-67.01167299999992,68.31608600000004],[-67.01834099999996,68.311646],[-67.03250099999997,68.309143],[-67.152222,68.29998799999998],[-67.23500099999995,68.29165599999999],[-67.30387899999994,68.25888099999997],[-67.31973299999999,68.24971],[-67.32778899999994,68.24359099999998],[-67.33361799999994,68.23776199999998],[-67.33750900000001,68.232483],[-67.33889799999992,68.22776799999997],[-67.33944699999995,68.22164900000013],[-67.33944699999995,68.20555100000007],[-67.33500700000002,68.20082100000002],[-67.32749899999993,68.18664600000011],[-67.32778899999994,68.18109100000004],[-67.33860800000002,68.17109700000003],[-67.34584000000001,68.16609199999999],[-67.37110899999999,68.15386999999998],[-67.387787,68.14637800000008],[-67.39862099999988,68.1438750000001],[-67.41250599999995,68.14305100000013],[-67.43028300000003,68.14471400000008],[-67.456955,68.14942900000011],[-67.47778299999999,68.15498400000001],[-67.51390100000003,68.1624910000001],[-67.528885,68.16526800000003],[-67.56777999999997,68.16914400000007],[-67.58111600000001,68.16886900000009],[-67.59889199999998,68.16499299999998],[-67.59834299999994,68.16276600000015],[-67.57556199999993,68.15498400000001],[-67.54472399999992,68.14776599999999],[-67.48028599999998,68.13472000000002],[-67.466949,68.13220200000006],[-67.43804899999998,68.12803600000001],[-67.40805099999994,68.12498499999998],[-67.39695699999993,68.12469499999997],[-67.37416100000002,68.12747200000001],[-67.353882,68.135269],[-67.30777,68.15554800000012],[-67.30416899999994,68.15860000000004],[-67.27389499999992,68.19081100000011],[-67.27278100000001,68.19552599999997],[-67.27471899999989,68.20054600000003],[-67.27917500000001,68.20526100000006],[-67.283615,68.21192900000005],[-67.28889499999997,68.22637900000012],[-67.289444,68.23082000000005],[-67.289444,68.23637400000007],[-67.27471899999989,68.24414100000001],[-67.178879,68.26998900000012],[-67.139725,68.27998400000007],[-67.05776999999989,68.29109200000005],[-67.01139799999999,68.29498300000012],[-66.99833699999994,68.29248000000013],[-66.99110399999995,68.28887900000007],[-66.98611499999998,68.28553800000003],[-66.98416099999997,68.28054800000001],[-66.97361799999999,68.27388000000002],[-66.964722,68.270264],[-66.93057299999992,68.26248200000003],[-66.86582899999996,68.25],[-66.83583099999993,68.24636800000007],[-66.791672,68.24470500000012],[-66.77749599999999,68.24331700000005],[-66.76972999999992,68.2410890000001],[-66.76583900000003,68.23858600000011],[-66.78028899999998,68.20776400000005],[-66.85221899999999,68.11526500000008],[-66.88890099999998,68.092758],[-66.89666699999987,68.0894320000001],[-66.91389499999997,68.08415200000007],[-66.94583099999994,68.076096],[-66.95445299999994,68.07193000000007],[-66.96556099999992,68.06387300000011],[-66.971115,68.05331400000006],[-66.97277799999995,68.04859900000002],[-66.97332799999998,68.03942899999998],[-66.96972700000003,68.03414900000013],[-66.96112099999999,68.02499400000005],[-66.95361299999996,68.01721200000009],[-66.94665499999991,68.01361100000003],[-66.92805499999997,68.042755],[-66.92166099999992,68.04914900000006],[-66.83612099999993,68.09553500000004],[-66.74804699999999,68.13165300000014],[-66.70916699999992,68.141098],[-66.69444299999998,68.14305100000013],[-66.68276999999995,68.14137300000004],[-66.678879,68.13888500000002],[-66.670837,68.12886000000015],[-66.67027299999995,68.1141510000001],[-66.67805499999992,68.04332000000005],[-66.68055700000002,68.036926],[-66.6930539999999,68.02221700000013],[-66.70638999999994,68.01165800000012],[-66.72083999999995,68.00166300000001],[-66.73500099999995,67.98220800000001],[-66.73277300000001,67.98193400000008],[-66.71472199999994,67.98359700000003],[-66.6972199999999,67.9874880000001],[-66.64723200000003,68.01554899999996],[-66.63473499999986,68.06414799999993],[-66.63194299999998,68.07582100000013],[-66.62554899999998,68.103317],[-66.62027,68.12580900000012],[-66.61555499999997,68.13247700000011],[-66.61054999999993,68.13693200000012],[-66.59472699999992,68.14305100000013],[-66.56138599999997,68.14749099999995],[-66.54194599999988,68.14833099999998],[-66.51362599999993,68.14833099999998],[-66.32888799999995,68.13220200000006],[-66.31527699999998,68.13026400000012],[-66.30943299999996,68.12747200000001],[-66.31054699999993,68.1185910000001],[-66.31500199999988,68.11248799999998],[-66.321121,68.10693400000014],[-66.35028099999994,68.09027100000009],[-66.36639400000001,68.08332800000011],[-66.37165799999997,68.08166499999999],[-66.38861099999997,68.08137499999998],[-66.41361999999998,68.08610499999998],[-66.42777999999998,68.08749399999999],[-66.45056199999999,68.08692899999994],[-66.46861299999995,68.083054],[-66.4761049999999,68.08055100000001],[-66.47860699999995,68.07720900000004],[-66.47222899999991,68.07304400000004],[-66.460556,68.0705410000001],[-66.43804899999998,68.06805400000002],[-66.38999899999999,68.06944300000004],[-66.36944599999993,68.07165500000008],[-66.32611099999997,68.07916300000011],[-66.303879,68.08387800000014],[-66.29666099999997,68.08610499999998],[-66.27278099999995,68.08776900000004],[-66.25917099999998,68.08581499999997],[-66.25083899999998,68.08221400000014],[-66.24027999999987,68.07331799999997],[-66.18415799999997,68.01887500000004],[-66.18443300000001,68.01332100000002],[-66.18638599999991,68.01081800000003],[-66.19276400000001,68.00721700000003],[-66.2041779999999,68.00471500000009],[-66.25306699999987,68.00221300000004],[-66.26417500000002,67.99971000000005],[-66.29444899999999,67.9916530000001],[-66.30972299999996,67.98609900000008],[-66.32084699999996,67.97886699999998],[-66.34445199999993,67.95665000000008],[-66.40583800000002,67.89804100000003],[-66.40139799999997,67.888596],[-66.52223200000003,67.86080900000002],[-66.535278,67.86360200000001],[-66.59416199999998,67.87248200000005],[-66.628601,67.8766480000001],[-66.67250100000001,67.88026400000001],[-66.729446,67.87885999999997],[-66.73971599999999,67.87776200000008],[-66.74694799999992,67.87525900000014],[-66.74499499999996,67.87275700000004],[-66.73222399999997,67.86720300000007],[-66.70306399999998,67.86360200000001],[-66.68693499999995,67.86276199999998],[-66.653885,67.85942100000011],[-66.56138599999997,67.84304800000007],[-66.40139799999997,67.81109600000008],[-66.35665899999992,67.82138100000003],[-66.34638999999999,67.86109900000002],[-66.33277900000002,67.88777200000004],[-66.31945799999988,67.91110200000014],[-66.295837,67.93830900000012],[-66.27667200000002,67.95443699999998],[-66.26861599999995,67.95803799999999],[-66.25195299999996,67.9624940000001],[-66.24055499999997,67.96276899999992],[-66.22749299999987,67.95999100000012],[-66.21389799999997,67.96081500000008],[-66.13694800000002,67.976089],[-66.11999500000002,67.98136900000009],[-66.00321999999989,68.02049299999999],[-65.98872399999988,68.02614599999998],[-65.98138399999999,68.02998400000013],[-65.943604,68.04609700000015],[-65.94860799999998,68.09248400000007],[-65.95861799999994,68.12942499999997],[-65.96194500000001,68.13749700000011],[-65.960556,68.14444000000015],[-65.94749499999989,68.15416000000005],[-65.94166599999994,68.15721100000002],[-65.92832900000002,68.1622010000001],[-65.920837,68.16192600000005],[-65.91194199999995,68.15887500000008],[-65.86749299999991,68.12469499999997],[-65.86389200000002,68.11943100000013],[-65.85777300000001,68.11026000000004],[-65.85360700000001,68.07804899999991],[-65.85360700000001,68.07331799999997],[-65.85777300000001,68.06721500000003],[-65.93383799999992,68.01226800000012],[-65.96032699999995,67.99642900000003],[-65.98083500000001,67.98726700000009],[-65.99433099999999,67.97976700000004],[-66.03222699999998,67.95248400000003],[-65.98582499999998,67.91665599999999],[-65.96722399999999,67.85331700000006],[-65.98083500000001,67.842758],[-66.00500499999987,67.81498699999997],[-66.00973499999998,67.80331400000011],[-66.02888499999995,67.72442600000011],[-66.02888499999995,67.71943699999997],[-66.02194199999997,67.65026900000004],[-66.02000399999991,67.63526900000011],[-66.01306199999993,67.62692300000003],[-66.008621,67.62553400000002],[-65.9997249999999,67.62747200000013],[-65.98666399999996,67.63526900000011],[-65.96139499999998,67.68969700000008],[-65.95028699999995,67.722488],[-65.936935,67.76554900000002],[-65.93859899999995,67.77609300000006],[-65.94249000000002,67.78082300000011],[-65.953888,67.79832499999998],[-65.95666499999993,67.81192000000004],[-65.95584099999996,67.81832900000006],[-65.95333899999997,67.82138100000003],[-65.94610599999999,67.82638500000013],[-65.92639199999996,67.832764],[-65.86915599999992,67.84414700000002],[-65.83167999999995,67.85443100000003],[-65.804169,67.86360200000001],[-65.79527299999995,67.868042],[-65.76362599999993,67.909988],[-65.76222200000001,67.91470300000003],[-65.76390100000003,67.91970800000007],[-65.76722699999999,67.92303500000003],[-65.79888900000003,67.93830900000012],[-65.81973299999999,67.95555100000013],[-65.823624,67.96276899999992],[-65.81777999999997,67.96804800000012],[-65.80776999999995,67.97110000000004],[-65.68443300000001,67.99247700000006],[-65.46305799999999,67.99636800000013],[-65.44860799999998,67.99552900000015],[-65.443604,67.99220300000013],[-65.44193999999999,67.98692300000005],[-65.44249000000002,67.98136900000009],[-65.45750399999997,67.93719499999992],[-65.464447,67.92082200000004],[-65.52027899999996,67.84304800000007],[-65.52583300000003,67.83776900000004],[-65.54527300000001,67.82222000000013],[-65.55860899999999,67.81442300000003],[-65.57362399999994,67.80693100000008],[-65.603882,67.79693599999996],[-65.61054999999988,67.79275500000006],[-65.61582900000002,67.78610200000008],[-65.61389199999991,67.78082300000011],[-65.61000100000001,67.77638200000001],[-65.59194899999994,67.76304600000009],[-65.57250999999997,67.75166300000006],[-65.55694599999987,67.7452550000001],[-65.51750199999998,67.73304700000006],[-65.47361799999993,67.71971100000007],[-65.45472699999999,67.71276899999998],[-65.43971299999993,67.70555100000001],[-65.42639199999996,67.69636500000001],[-65.41361999999998,67.68359399999991],[-65.40695199999999,67.67498800000004],[-65.40360999999996,67.66470300000009],[-65.40028399999994,67.65443400000004],[-65.39639299999988,67.64498900000001],[-65.38473499999992,67.625809],[-65.36389200000002,67.59748800000011],[-65.35665899999992,67.59471100000002],[-65.34638999999999,67.59332300000011],[-65.33528100000001,67.59359700000005],[-65.32278400000001,67.59498600000006],[-65.31834400000002,67.601089],[-65.36915599999992,67.70277400000009],[-65.37916599999994,67.71165500000001],[-65.40264899999994,67.72322100000008],[-65.46250899999995,67.74192800000014],[-65.49249299999997,67.75166300000006],[-65.51083399999999,67.75915500000002],[-65.54444899999999,67.77415500000012],[-65.55055199999998,67.77832000000012],[-65.55444299999999,67.78305100000006],[-65.55444299999999,67.78804000000002],[-65.42361499999998,67.89804100000003],[-65.29249599999997,67.934143],[-65.235275,67.94470200000006],[-65.20140100000003,67.95443699999998],[-65.17166099999992,67.966095],[-65.15638699999994,67.97360200000008],[-65.14416499999987,67.98414599999995],[-65.14138799999995,67.99026500000002],[-65.14555399999995,67.997208],[-65.17582700000003,68.00888100000003],[-65.18083199999995,68.01220700000005],[-65.181107,68.016663],[-65.17666599999995,68.02249100000006],[-65.16915899999992,68.02720600000009],[-65.047775,68.04942299999999],[-65.00111399999992,68.055542],[-64.973053,68.05026199999998],[-64.73416099999997,67.99386600000003],[-64.72361799999999,67.99054000000001],[-64.71749899999998,67.98637400000013],[-64.71362299999998,67.98165900000009],[-64.71806300000003,67.97665400000005],[-64.72555499999993,67.97164899999996],[-64.74333200000001,67.96581999999995],[-64.84722899999997,67.93498199999999],[-64.94249000000002,67.91249099999999],[-65.015289,67.86248800000004],[-65.01777599999997,67.820831],[-65.00834700000001,67.78526299999993],[-65.01417500000002,67.78027300000008],[-65.05110199999996,67.75443999999999],[-65.06054699999993,67.7522130000001],[-65.0852809999999,67.749146],[-65.112213,67.74803200000002],[-65.12443499999995,67.74636800000002],[-65.136124,67.7435910000001],[-65.14555399999995,67.73887600000006],[-65.15833999999995,67.72970600000002],[-65.17999299999991,67.71360800000014],[-65.19248999999996,67.70220900000004],[-65.19638099999997,67.69720500000011],[-65.19860799999992,67.69164999999998],[-65.20500199999998,67.65914900000007],[-65.20556599999992,67.65359500000011],[-65.20417800000001,67.6483310000001],[-65.20028699999995,67.64387500000004],[-65.17832899999996,67.63360599999999],[-65.17250099999995,67.63360599999999],[-65.16722099999998,67.63581800000003],[-65.162781,67.63888500000013],[-65.150284,67.67221100000012],[-65.14973399999997,67.67776500000008],[-65.150284,67.68193100000002],[-65.15417499999995,67.68664600000005],[-65.15333599999991,67.69220000000001],[-65.14889499999998,67.69831799999997],[-65.12971500000003,67.71582000000001],[-65.12416100000002,67.71804799999995],[-64.92971799999992,67.78776600000009],[-64.91972399999992,67.79081700000012],[-64.90722700000003,67.79220599999996],[-64.82722499999994,67.78471400000001],[-64.81639100000001,67.78137200000009],[-64.81054699999999,67.77720599999998],[-64.80888400000003,67.771927],[-64.80749499999996,67.74275200000011],[-64.81610099999989,67.71054100000003],[-64.82583599999998,67.70304900000008],[-64.83750900000001,67.70027199999998],[-64.86277799999999,67.69164999999998],[-64.86250299999995,67.68748499999998],[-64.84944200000001,67.68719499999997],[-64.82055700000001,67.68830899999995],[-64.79972800000002,67.69081100000005],[-64.77944899999989,67.69775400000003],[-64.773056,67.70359800000006],[-64.76861600000001,67.70942700000006],[-64.76222199999995,67.76249700000011],[-64.75584399999997,67.81776400000007],[-64.75,67.82276900000011],[-64.74082900000002,67.82470700000005],[-64.65306099999998,67.82887299999993],[-64.61193800000001,67.82638500000013],[-64.56806899999998,67.81999200000001],[-64.506958,67.80720500000001],[-64.36888099999993,67.76416000000006],[-64.36332700000003,67.75943000000001],[-64.36389199999996,67.75443999999999],[-64.39611799999994,67.71192900000011],[-64.40139799999992,67.70776400000011],[-64.41471899999999,67.70721400000008],[-64.43138099999999,67.70971700000007],[-64.44526699999994,67.71138000000002],[-64.4600069999999,67.71165500000001],[-64.47250399999996,67.71026600000005],[-64.57833899999997,67.69693000000007],[-64.59722899999986,67.68969700000008],[-64.61721799999998,67.67858900000004],[-64.6372219999999,67.66526799999991],[-64.63917500000002,67.66053800000009],[-64.62638900000002,67.65971400000012],[-64.61833200000001,67.66304000000014],[-64.58139,67.67442299999999],[-64.51583900000003,67.68609600000002],[-64.45417799999996,67.69331400000004],[-64.38082899999989,67.69802900000008],[-64.36250299999989,67.70248400000008],[-64.34722899999997,67.709991],[-64.33138999999989,67.72720300000003],[-64.32640099999992,67.7310940000001],[-64.31806899999992,67.73414600000001],[-64.30555700000002,67.73359700000009],[-64.29527300000001,67.73027000000013],[-64.07278400000001,67.6102600000001],[-64.06777999999997,67.60247799999996],[-64.03971899999999,67.53360000000009],[-64.0386049999999,67.52859500000005],[-64.03889500000002,67.52581800000013],[-64.04499800000002,67.52082800000005],[-64.05305499999992,67.51748700000002],[-64.13473499999992,67.49026500000008],[-64.14472999999992,67.48719799999998],[-64.16528299999999,67.48248299999995],[-64.2386019999999,67.46748400000007],[-64.25083899999987,67.46609500000011],[-64.27194199999997,67.4649960000001],[-64.281113,67.46554600000013],[-64.34388699999994,67.46998599999995],[-64.38694800000002,67.474426],[-64.412216,67.47747800000008],[-64.42304999999999,67.47804300000013],[-64.43554699999999,67.47859200000005],[-64.44055200000003,67.47499100000005],[-64.43222000000003,67.47109999999998],[-64.41000400000001,67.46415699999994],[-64.38473499999998,67.45832800000011],[-64.35694899999999,67.4538730000001],[-64.29666099999992,67.44802900000008],[-64.283615,67.44802900000008],[-64.20445299999994,67.4522090000001],[-64.19055199999997,67.45332300000007],[-64.166946,67.45694000000003],[-64.14500399999986,67.46165500000006],[-64.12332199999992,67.46527100000014],[-64.11111499999993,67.4666600000001],[-64.08639499999998,67.46748400000007],[-64.04804999999988,67.46415699999994],[-64.01083399999999,67.45971700000013],[-64.00111400000003,67.45582600000006],[-63.99265300000002,67.44862400000011],[-63.95111099999997,67.40998800000011],[-63.90416699999997,67.30581699999999],[-63.90416699999997,67.3016510000001],[-63.90582999999992,67.299713],[-63.912773000000016,67.2955320000001],[-63.92388900000003,67.29332000000005],[-63.93721800000003,67.292755],[-64.02278099999995,67.30802900000009],[-64.05526699999996,67.31137100000001],[-64.08473200000003,67.31330900000012],[-64.18167099999994,67.31219499999997],[-64.21749899999998,67.31359899999995],[-64.33999599999999,67.31944299999998],[-64.53056299999992,67.33776899999998],[-64.74027999999998,67.35693400000014],[-64.75750700000003,67.35832200000004],[-64.78832999999992,67.35914600000001],[-64.79750099999995,67.35664400000013],[-64.80082699999997,67.35276800000003],[-64.79888900000003,67.35026600000015],[-64.78860500000002,67.34693900000002],[-64.73443599999996,67.3336030000001],[-64.72138999999993,67.33137499999992],[-64.68777499999999,67.32748400000003],[-64.441666,67.30304000000012],[-64.402222,67.29914900000006],[-64.37249800000001,67.29721100000012],[-64.34472699999992,67.29748500000005],[-64.283615,67.29998799999998],[-64.258621,67.29914900000006],[-64.24610899999999,67.29859900000002],[-64.23832699999997,67.29693600000007],[-64.23194899999999,67.29332000000005],[-64.23388699999987,67.28858900000012],[-64.24833699999999,67.27943400000004],[-64.30638099999999,67.26220700000005],[-64.32501200000002,67.25721699999997],[-64.35611,67.25027500000004],[-64.39222699999999,67.24664300000012],[-64.41944899999993,67.24720799999994],[-64.50917099999998,67.25499000000008],[-64.53694199999995,67.25665300000003],[-64.55027799999999,67.25610400000005],[-64.66861,67.23858599999994],[-64.72416699999997,67.22886699999998],[-64.77917499999995,67.21887200000003],[-64.79028299999993,67.21665999999999],[-64.79998799999993,67.21360800000008],[-64.80972300000002,67.2102660000001],[-64.81610099999989,67.20694000000009],[-64.81304899999998,67.20138500000002],[-64.808044,67.19802900000013],[-64.80139200000002,67.19525099999998],[-64.78332499999993,67.19026200000002],[-64.77278100000001,67.18969699999997],[-64.758896,67.19081099999994],[-64.71665999999999,67.2002720000001],[-64.65583800000002,67.21720900000014],[-64.46665999999999,67.22915600000005],[-64.42527799999993,67.22804300000001],[-64.35078399999998,67.2347640000001],[-64.28744499999999,67.23825799999997],[-64.267113,67.24142500000005],[-64.23277299999995,67.25143400000002],[-64.16944899999999,67.26081800000003],[-64.15888999999993,67.26249700000005],[-64.11471599999999,67.26721200000009],[-64.010559,67.27526900000004],[-63.976944,67.27777100000009],[-63.969993999999986,67.27748100000008],[-63.965836000000024,67.27554299999997],[-63.96277599999996,67.27249100000006],[-63.96277599999996,67.270264],[-63.97582999999992,67.251938],[-63.993056999999965,67.22831700000012],[-63.998336999999935,67.22164900000013],[-64.01333599999998,67.21220400000004],[-64.02139299999999,67.20887800000003],[-64.04527299999995,67.20471199999997],[-64.05610699999994,67.2044370000001],[-64.08860800000002,67.20776400000005],[-64.22022200000004,67.20171400000004],[-64.46749899999992,67.16748000000007],[-64.50140399999992,67.161652],[-64.54527299999995,67.15248100000002],[-64.57501199999996,67.14471400000008],[-64.58416699999992,67.14221200000003],[-64.61193800000001,67.13247700000011],[-64.65805099999994,67.11303700000013],[-64.68083199999995,67.09304800000001],[-64.686935,67.08749399999999],[-64.68998699999992,67.08360299999993],[-64.69249000000002,67.07804899999996],[-64.70056199999999,67.01805100000007],[-64.70111099999991,67.01220700000005],[-64.70056199999999,67.00804099999999],[-64.69694500000003,67.00332600000013],[-64.69193999999999,67.00054900000003],[-64.68306000000001,67.0002750000001],[-64.660278,67.00387599999999],[-64.63861099999997,67.00860600000004],[-64.62832599999996,67.01220700000005],[-64.62388599999991,67.01805100000007],[-64.61972000000003,67.02832000000012],[-64.61805700000002,67.03942899999998],[-64.61805700000002,67.04443400000008],[-64.61972000000003,67.04971300000005],[-64.61888099999999,67.05525200000005],[-64.61527999999993,67.06694000000005],[-64.60916099999997,67.08194000000003],[-64.604172,67.08831799999996],[-64.59777799999989,67.09387200000015],[-64.58361799999989,67.10304300000013],[-64.54750100000001,67.11859099999992],[-64.52722199999988,67.124146],[-64.506393,67.12942500000003],[-64.47471599999994,67.13499500000006],[-64.22999599999997,67.16415400000005],[-64.08721899999995,67.17970300000013],[-64.008896,67.17886400000003],[-63.995551999999975,67.17942800000014],[-63.97138199999995,67.18220500000007],[-63.96055599999994,67.184418],[-63.92972600000002,67.1927490000001],[-63.91916699999996,67.19636500000013],[-63.912216,67.20054600000003],[-63.86222099999992,67.22581500000001],[-63.80750299999994,67.23915099999999],[-63.797500999999954,67.24026500000014],[-63.561942999999985,67.23692300000005],[-63.54639400000002,67.23580900000007],[-63.46944399999995,67.22831700000012],[-63.45833600000003,67.22608899999994],[-63.45055400000001,67.22248800000011],[-63.449164999999994,67.21943700000008],[-63.449164999999994,67.21499599999999],[-63.45083599999998,67.17970300000013],[-63.453888000000006,67.16943400000014],[-63.52944200000002,67.10443100000003],[-63.53833800000001,67.10054000000014],[-63.604720999999984,67.07527200000004],[-63.61389200000002,67.07276900000005],[-63.64805599999988,67.06694000000005],[-63.672775,67.06359900000001],[-63.71277600000002,67.05497700000001],[-63.72277100000002,67.05192599999998],[-63.73138399999999,67.04803500000008],[-63.74444599999998,67.0410920000001],[-63.77972399999999,67.01748700000013],[-63.79583699999995,67.00665300000009],[-63.806389000000024,66.99581900000004],[-63.80721999999997,66.98803700000008],[-63.80139200000002,66.97970599999996],[-63.78138699999994,66.96360800000014],[-63.77249899999987,66.95887800000008],[-63.769447000000014,66.97137500000008],[-63.76888999999994,66.97692900000004],[-63.77111100000002,66.98081999999994],[-63.77249899999987,66.98609899999991],[-63.77361300000001,66.99108899999999],[-63.773330999999985,66.99609400000003],[-63.77083600000003,67.00138900000007],[-63.76721999999995,67.00610400000011],[-63.75695000000002,67.01416],[-63.750557000000015,67.01748700000013],[-63.73444399999994,67.02415500000012],[-63.69860799999998,67.03887899999995],[-63.68000000000001,67.04582199999999],[-63.65083299999998,67.05247500000013],[-63.63833599999998,67.05442800000009],[-63.60083799999995,67.05748],[-63.565552000000025,67.06248500000004],[-63.53527799999995,67.07083100000011],[-63.49722299999996,67.08526600000005],[-63.40277900000001,67.14444000000015],[-63.39639299999999,67.15220600000004],[-63.39416499999993,67.15693699999997],[-63.39388999999994,67.161652],[-63.398056,67.165817],[-63.41694599999988,67.18026700000007],[-63.419997999999964,67.18580600000007],[-63.42194399999988,67.194702],[-63.42083699999995,67.2002720000001],[-63.417778,67.20610000000005],[-63.40916399999992,67.21665999999999],[-63.351669000000015,67.26805100000001],[-63.340553,67.27665700000011],[-63.33250399999997,67.28193700000003],[-63.298888999999974,67.29776000000004],[-63.28055599999993,67.30636600000014],[-63.27249899999998,67.30941800000005],[-63.16027799999995,67.32832300000001],[-63.13722200000001,67.3311000000001],[-63.11028299999987,67.32998700000002],[-63.03972599999986,67.30609099999992],[-63.022498999999925,67.29803500000008],[-63.01500699999997,67.29359399999998],[-62.99777999999998,67.28137200000015],[-62.992774999999995,67.27638200000013],[-62.97388499999988,67.23553500000014],[-62.97083299999997,67.22581500000001],[-62.97083299999997,67.22137500000002],[-63.023056,67.17942800000014],[-63.03583499999996,67.17109700000003],[-63.04472399999986,67.16720599999996],[-63.075561999999934,67.15887500000008],[-63.100554999999986,67.15554800000012],[-63.13417099999998,67.15277100000003],[-63.17027999999999,67.14721700000007],[-63.19027699999998,67.143326],[-63.232497999999964,67.13220200000006],[-63.24250000000001,67.12914999999998],[-63.26888999999994,67.11747700000012],[-63.27583299999998,67.11331200000012],[-63.284447,67.105255],[-63.285278000000005,67.099716],[-63.283615,67.09498600000012],[-63.27805299999994,67.09082000000006],[-63.26860799999997,67.08248899999995],[-63.26083399999999,67.07415800000007],[-63.25389100000001,67.06469700000008],[-63.224716,67.02470400000004],[-63.22027600000001,67.0169370000001],[-63.22027600000001,67.00610400000011],[-63.22083299999997,66.98969999999997],[-63.22138199999995,66.98498499999994],[-63.223884999999996,66.97943099999998],[-63.227776000000006,66.97276299999999],[-63.240837,66.96165500000001],[-63.27777900000001,66.94970699999993],[-63.32055700000001,66.94026200000008],[-63.356109999999944,66.93470800000006],[-63.36860699999994,66.93470800000006],[-63.43638599999997,66.92553700000013],[-63.469993999999986,66.9205320000001],[-63.514725,66.91249099999999],[-63.526138,66.90927100000005],[-63.545554999999865,66.90359500000005],[-63.554442999999935,66.899719],[-63.565552000000025,66.89248700000007],[-63.565552000000025,66.88804600000014],[-63.56361399999997,66.88360599999993],[-63.557503,66.875809],[-63.554717999999866,66.87025499999999],[-63.55139200000002,66.86053500000008],[-63.55555700000002,66.84887700000007],[-63.57194499999997,66.83749400000005],[-63.59332999999992,66.83166500000004],[-63.615005,66.82720899999998],[-63.63889299999988,66.82443200000006],[-63.65222199999988,66.82388300000008],[-63.69860799999998,66.822495],[-63.725273000000016,66.82304399999998],[-63.77583299999992,66.82582100000002],[-63.77138499999995,66.81109600000008],[-63.653053,66.80247500000002],[-63.62444299999993,66.80192600000004],[-63.598334999999906,66.80304000000001],[-63.58777600000002,66.80442800000014],[-63.54888900000003,66.8124850000001],[-63.539443999999946,66.81469700000014],[-63.53527799999995,66.81581100000011],[-63.488891999999964,66.82832300000013],[-63.47888199999994,66.83581500000008],[-63.47638699999993,66.839157],[-63.47527299999996,66.84248400000013],[-63.476944,66.84693900000013],[-63.48722099999998,66.85887100000008],[-63.49471999999997,66.86553999999995],[-63.49694799999986,66.88081400000004],[-63.48722099999998,66.89694200000008],[-63.48082699999998,66.90248100000008],[-63.474441999999954,66.90609699999993],[-63.45610799999997,66.91081199999996],[-63.441666,66.9083250000001],[-63.427223000000026,66.90138200000013],[-63.407219,66.81442300000003],[-63.40777600000001,66.809708],[-63.410278000000005,66.7999880000001],[-63.41471899999999,66.78332500000005],[-63.417778,66.77304099999998],[-63.436110999999926,66.72804300000007],[-63.449439999999925,66.71609500000005],[-63.453056000000004,66.71165500000006],[-63.45194199999992,66.70637499999998],[-63.44193999999993,66.70304899999996],[-63.420279999999934,66.69886800000006],[-63.415276000000006,66.70054600000014],[-63.408332999999914,66.70443700000004],[-63.40277900000001,66.70887800000014],[-63.37666300000001,66.73414600000007],[-63.32028200000002,66.81414800000005],[-63.31945000000002,66.81999200000001],[-63.224716,66.899429],[-62.97388499999988,66.96110499999998],[-62.96250199999997,66.96388200000007],[-62.93999499999995,66.96666000000005],[-62.87222300000002,66.9644320000001],[-62.84694699999994,66.96192900000011],[-62.83777600000002,66.95776400000011],[-62.82111400000002,66.83027600000008],[-62.82055700000001,66.81359900000007],[-62.82749899999993,66.78804000000008],[-62.82972699999999,66.78332500000005],[-62.83750199999997,66.771927],[-62.84332999999998,66.76914999999991],[-62.86444899999998,66.74609400000008],[-62.86999500000002,66.73970000000003],[-62.87305500000002,66.73359700000009],[-62.91194200000001,66.65277100000014],[-62.914444,66.64721699999996],[-62.90805099999994,66.63998400000014],[-62.90305299999994,66.63720700000005],[-62.899726999999984,66.63665800000012],[-62.85916900000001,66.65304599999996],[-62.85028099999994,66.65693700000003],[-62.83527400000003,66.66638200000011],[-62.819999999999936,66.68441800000011],[-62.73416899999995,66.79081699999995],[-62.73583199999996,66.80165100000005],[-62.74333199999995,66.8099820000001],[-62.751113999999916,66.81805400000007],[-62.76805899999994,66.83055100000007],[-62.77417000000003,66.84054600000002],[-62.768332999999984,66.907761],[-62.764449999999954,66.92526200000009],[-62.76111599999996,66.92915299999999],[-62.74305700000002,66.94192499999997],[-62.725273000000016,66.94747899999999],[-62.63417099999998,66.95138500000007],[-62.60777999999999,66.95220900000004],[-62.59222399999993,66.95082100000013],[-62.57861299999996,66.94775400000003],[-62.56889299999989,66.94413800000012],[-62.54999499999997,66.93165599999998],[-62.51999699999993,66.91110200000003],[-62.40277900000001,66.809418],[-62.401389999999935,66.80497700000006],[-62.40193899999997,66.78915400000005],[-62.39861300000001,66.78027299999991],[-62.393332999999984,66.77581800000007],[-62.32695000000001,66.73027000000013],[-62.31945000000002,66.72637900000007],[-62.313332,66.7269290000001],[-62.299171,66.73304700000006],[-62.291388999999924,66.7563780000001],[-62.292778,66.76165800000001],[-62.295837000000006,66.766388],[-62.36222099999998,66.81832900000012],[-62.419448999999986,66.84332300000005],[-62.42472099999998,66.84748800000006],[-62.426948999999865,66.85137899999995],[-62.436942999999985,66.88443000000012],[-62.42722299999997,66.92109700000009],[-62.41889199999997,66.9266510000001],[-62.407501000000025,66.92942800000003],[-62.394721999999945,66.92915299999999],[-62.346946999999886,66.93359400000008],[-62.28472899999991,66.94609100000008],[-62.27166699999998,66.96081500000014],[-62.27972399999993,66.9791560000001],[-62.291388999999924,67.00582900000012],[-62.294448999999986,67.02137800000003],[-62.29361699999998,67.02638200000001],[-62.29028299999999,67.032486],[-62.28527799999995,67.03610200000008],[-62.27860999999996,67.03942899999998],[-62.262504999999976,67.04525800000005],[-62.10139499999997,67.05470300000007],[-62.05444299999988,67.04914900000011],[-62.03194400000001,67.04525800000005],[-62.019721999999945,67.04220600000008],[-62.00556199999994,67.0352630000001],[-62.00695000000002,67.03193700000008],[-62.04999499999991,66.98719800000009],[-62.10611,66.91720600000002],[-62.102225999999916,66.91304000000014],[-62.072227,66.90748600000012],[-62.02972399999999,66.90165700000011],[-62.01888999999994,66.90165700000011],[-62.01860799999997,66.9080350000001],[-62.01500699999991,66.91415400000011],[-61.95666499999993,66.96388200000007],[-61.94972200000001,66.96720899999997],[-61.93860599999999,66.96943699999997],[-61.91332999999997,66.97082500000005],[-61.86555499999997,66.97082500000005],[-61.851395000000025,66.97053500000004],[-61.83805099999995,66.9685970000001],[-61.74972500000001,66.94802900000002],[-61.73722099999998,66.94108600000004],[-61.731941000000006,66.93691999999993],[-61.72888199999994,66.93220500000007],[-61.73082699999986,66.92387400000001],[-61.61277799999999,66.87081899999993],[-61.31416300000001,66.68719500000003],[-61.29472399999992,66.67442299999999],[-61.289443999999946,66.669983],[-61.281386999999995,66.66110200000003],[-61.262504999999976,66.62942500000008],[-61.26666299999994,66.62275699999992],[-61.300277999999935,66.59359700000005],[-61.34166700000003,66.57193000000001],[-61.348052999999936,66.57054100000005],[-61.35666699999996,66.57110600000004],[-61.38833599999998,66.578598],[-61.40027599999996,66.57720899999998],[-61.409720999999934,66.572769],[-61.425003000000004,66.55970800000006],[-61.447776999999974,66.53831500000013],[-61.46166999999997,66.54332],[-61.54861499999987,66.547485],[-61.584723999999994,66.54776000000004],[-61.59860999999995,66.55026200000009],[-61.618056999999965,66.55720500000007],[-61.623885999999914,66.56693999999999],[-61.63194299999998,66.58665499999995],[-61.63861099999997,66.59553499999998],[-61.64389,66.5999910000001],[-61.66916699999996,66.616379],[-61.69138299999997,66.62831100000011],[-61.72582999999986,66.64305100000007],[-61.734443999999996,66.645828],[-61.95055400000001,66.67692599999998],[-62.01555599999995,66.67137100000008],[-62.12388599999997,66.626373],[-62.05055199999998,66.6249850000001],[-62.01860799999997,66.64082300000013],[-61.990837,66.64804100000009],[-61.97999599999997,66.64804100000009],[-61.95055400000001,66.64610299999998],[-61.830284000000006,66.62136800000013],[-61.79695099999998,66.61192300000005],[-61.788895000000025,66.60859700000003],[-61.75389100000001,66.58859300000012],[-61.576667999999984,66.48719800000003],[-61.57527900000002,66.48275799999999],[-61.576392999999996,66.47720300000009],[-61.58332799999994,66.47164900000013],[-61.59194199999996,66.46775800000006],[-61.61416600000001,66.46304300000003],[-61.63500199999993,66.45999100000006],[-61.731383999999935,66.45109600000006],[-61.844161999999926,66.44609100000002],[-61.857779999999934,66.447205],[-61.86972000000003,66.44581599999998],[-61.956947000000014,66.42414900000011],[-61.976943999999946,66.41748000000007],[-61.985832000000016,66.41360500000008],[-61.98694599999993,66.41026299999999],[-61.978049999999996,66.40386999999998],[-61.96416499999998,66.40138200000001],[-61.93416599999989,66.40081800000007],[-61.75500499999998,66.40748600000006],[-61.578612999999905,66.41526800000003],[-61.569449999999904,66.41554300000001],[-61.55726600000003,66.413681],[-61.54527999999999,66.40998800000011],[-61.46694200000002,66.37191800000005],[-61.46250199999997,66.36914100000013],[-61.46361499999989,66.365814],[-61.665276000000006,66.324997],[-61.87749499999995,66.28332499999993],[-61.92888599999998,66.28387499999997],[-62.19888300000002,66.3141480000001],[-62.207503999999915,66.31666600000011],[-62.21221899999995,66.31944299999998],[-62.21805599999993,66.33193999999997],[-62.231941000000006,66.36608900000004],[-62.23221599999994,66.36970500000007],[-62.22943900000001,66.37525900000009],[-62.22499800000003,66.38026400000012],[-62.21860499999997,66.39248700000002],[-62.21832999999987,66.39665200000002],[-62.22361000000001,66.40109300000012],[-62.22999600000003,66.40415999999999],[-62.255279999999914,66.40832499999999],[-62.26889,66.409424],[-62.41861,66.42109700000003],[-62.456107999999915,66.42387400000013],[-62.565833999999995,66.42804000000001],[-62.626662999999894,66.426086],[-62.69888300000002,66.41276600000009],[-62.709723999999994,66.41053799999997],[-62.716110000000015,66.40721100000002],[-62.71028100000001,66.403595],[-62.673614999999984,66.39360000000005],[-62.629996999999946,66.38777199999998],[-62.478049999999996,66.36998000000011],[-62.33750199999997,66.31581100000005],[-62.32028200000002,66.3083190000001],[-62.31610899999998,66.30497700000001],[-62.32055699999995,66.299713],[-62.323616000000015,66.29803500000008],[-62.38889299999994,66.276093],[-62.398338000000024,66.27304100000009],[-62.62194099999999,66.22137500000002],[-62.64361599999995,66.21693399999992],[-62.66694599999994,66.21443200000004],[-62.68083200000001,66.21693399999992],[-62.75194499999992,66.24108899999993],[-62.757225000000005,66.24525500000004],[-62.78055599999993,66.27777100000014],[-62.782218999999884,66.282486],[-62.782218999999884,66.28887900000012],[-62.773330999999985,66.29693600000007],[-62.77417000000003,66.30276500000014],[-62.77944199999996,66.30720500000012],[-62.79722599999997,66.31387300000011],[-62.81666599999994,66.32083100000011],[-62.82611099999991,66.32415800000001],[-62.85889400000002,66.33415200000007],[-62.86805700000002,66.33610499999998],[-62.881110999999976,66.33581500000014],[-62.88999899999999,66.33332800000011],[-62.895003999999915,66.32971200000003],[-62.80944099999999,66.24081400000011],[-62.801391999999964,66.23525999999993],[-62.71500399999991,66.20166000000006],[-62.70610799999997,66.1997070000001],[-62.681389000000024,66.19693000000001],[-62.647223999999994,66.1997070000001],[-62.60361499999999,66.20526100000012],[-62.488051999999925,66.20027199999993],[-62.366660999999965,66.17498799999998],[-62.18055700000002,66.14860499999998],[-62.03750599999995,66.10081500000001],[-61.9611129999999,66.03387500000002],[-61.95500199999998,66.02415500000012],[-61.95444500000002,66.01915000000008],[-61.95583299999993,66.01499899999999],[-61.960280999999895,66.01193200000006],[-61.975554999999986,66.01054399999998],[-62.088889999999935,66.00027499999993],[-62.13361400000002,66.00000000000011],[-62.148056,66.00138900000013],[-62.16638899999998,66.00749200000007],[-62.17250100000001,66.01054399999998],[-62.18888900000002,66.0122070000001],[-62.196663,66.01110800000009],[-62.291672000000005,65.98027000000013],[-62.30777699999999,65.97387699999996],[-62.39166999999986,66.01138300000014],[-62.404715999999894,66.01470899999998],[-62.52527600000002,66.03414900000013],[-62.54138899999998,66.03553799999997],[-62.69554900000003,66.04220599999996],[-62.74111199999993,66.03831500000007],[-62.759726999999884,66.03305100000006],[-62.778885,66.03332499999999],[-62.799995000000024,66.03970300000015],[-62.80916599999989,66.04386900000003],[-62.83167299999997,66.05554200000006],[-62.84222399999999,66.06414799999999],[-62.84694699999994,66.06915300000003],[-62.85500300000001,66.083054],[-62.856667000000016,66.08749400000005],[-62.86000100000001,66.10304300000013],[-62.8663939999999,66.11276199999998],[-62.87332900000001,66.12136800000007],[-62.88417099999987,66.12997399999995],[-62.90555599999999,66.14082300000001],[-62.93055700000002,66.14694200000008],[-62.94694500000003,66.14860499999998],[-62.95944199999991,66.14888000000002],[-62.970551,66.14804100000003],[-63.01361800000001,66.13888500000007],[-63.041672000000005,66.13026400000001],[-63.06194299999993,66.1208190000001],[-63.06027999999998,66.11637900000011],[-63.03944399999989,66.11331200000001],[-63.006393,66.11692800000003],[-62.892226999999934,66.07666],[-62.88999899999999,66.06637599999993],[-62.88583399999999,66.05636600000003],[-62.875,66.0477600000001],[-62.86222099999986,66.03942900000004],[-62.84194200000002,66.02748099999997],[-62.82666799999993,66.02026400000005],[-62.81583399999994,66.016098],[-62.79361699999998,66.01081800000009],[-62.778885,66.00972000000002],[-62.768332999999984,66.00972000000002],[-62.755561999999884,66.00999500000006],[-62.743889000000024,66.01138300000014],[-62.67472099999992,66.01554900000002],[-62.523056,66.0022130000001],[-62.51721999999995,66.00054900000009],[-62.4183349999999,65.97053500000004],[-62.40555599999993,65.96304300000008],[-62.395003999999915,65.949997],[-62.386664999999994,65.93664600000005],[-62.32111400000002,65.83110000000005],[-62.317222999999956,65.80802900000003],[-62.44166599999994,65.7935940000001],[-62.478882,65.790817],[-62.50527999999997,65.790817],[-62.52138499999995,65.79248000000013],[-62.60417199999989,65.801086],[-62.61999500000002,65.80304000000007],[-62.684440999999936,65.81637599999999],[-62.71777300000002,65.8252720000001],[-62.72721899999999,65.828598],[-62.72999600000003,65.83194000000009],[-62.75278499999996,65.85359199999994],[-62.80750299999994,65.88998400000014],[-62.82944500000002,65.89999400000005],[-62.857506,65.91110200000003],[-62.86416600000001,65.91110200000003],[-62.87055199999992,65.90554800000001],[-62.871940999999936,65.90138200000013],[-62.87471800000003,65.88749700000005],[-62.87471800000003,65.8830410000001],[-62.760001999999986,65.816666],[-62.74639100000002,65.809708],[-62.73694599999993,65.80831900000004],[-62.71999399999993,65.809708],[-62.658889999999985,65.79193099999998],[-62.597778000000005,65.77192700000006],[-62.58222199999989,65.76554900000008],[-62.575004999999976,65.76165800000001],[-62.56944999999996,65.75749200000013],[-62.56861099999992,65.75221299999993],[-62.569725000000005,65.74664300000006],[-62.579444999999964,65.72831700000006],[-62.58361099999996,65.72331200000002],[-62.58777599999996,65.720261],[-62.59027900000001,65.71914700000002],[-62.59944200000001,65.71887200000015],[-62.61277799999999,65.72164900000007],[-62.62194099999999,65.72554000000014],[-62.67472099999992,65.73580900000002],[-62.823891,65.76138300000002],[-62.833442999999875,65.75299100000001],[-62.83377799999988,65.74999200000002],[-62.82878099999988,65.7444920000001],[-62.79917099999989,65.711929],[-62.78805499999993,65.70832800000011],[-62.72638699999999,65.71138000000002],[-62.69888300000002,65.71026600000005],[-62.681670999999994,65.7080380000001],[-62.6627729999999,65.701096],[-62.59944200000001,65.67581200000001],[-62.59194199999996,65.67192099999994],[-62.58972199999994,65.66859400000004],[-62.59583299999986,65.65220599999998],[-62.60222599999997,65.64027399999998],[-62.611670999999944,65.62414599999994],[-62.61749999999989,65.61499000000003],[-62.62805199999997,65.6019290000001],[-62.645279000000016,65.58720399999993],[-62.653053,65.58610499999998],[-62.751113999999916,65.58526599999999],[-62.76722000000001,65.58749399999994],[-62.78472899999997,65.59137000000004],[-62.80305499999997,65.59887700000013],[-62.85972600000002,65.63472000000002],[-62.86138900000003,65.63916],[-62.85861199999994,65.65525800000006],[-62.862503000000004,65.68525700000009],[-62.882998999999984,65.72415200000006],[-62.885001999999986,65.72697399999993],[-62.88799999999986,65.72965200000004],[-62.90416700000003,65.74636800000002],[-62.922500999999954,65.75221299999993],[-62.936110999999926,65.75499000000002],[-62.949439999999925,65.75526399999995],[-62.95944199999991,65.75387600000005],[-62.962219000000005,65.74832200000009],[-62.94361099999992,65.743042],[-62.93472300000002,65.73887600000012],[-62.92527799999999,65.73109399999998],[-62.91666399999991,65.72221400000012],[-62.914444,65.71832300000005],[-62.892226999999934,65.6419370000001],[-62.89166999999992,65.63832100000008],[-62.89583600000003,65.63304099999999],[-62.901389999999935,65.62803600000012],[-62.95333099999999,65.58692900000011],[-62.96167000000003,65.58305400000012],[-62.972220999999934,65.580826],[-63.005004999999926,65.6249850000001],[-63.01611300000002,65.63275099999998],[-63.02749599999993,65.63581800000009],[-63.04028299999993,65.63749700000011],[-63.13777900000002,65.64415000000008],[-63.16249800000003,65.63247700000005],[-63.16240699999997,65.62886800000007],[-63.164443999999946,65.62553400000007],[-63.17861199999999,65.62747200000001],[-63.20027900000002,65.633331],[-63.211945000000014,65.64054900000002],[-63.29389199999997,65.70887800000014],[-63.43638599999997,65.84526100000005],[-63.44305400000002,65.85470599999991],[-63.47416700000002,65.83305400000006],[-63.379166,65.720261],[-63.36833200000001,65.69386300000002],[-63.36833200000001,65.66943400000008],[-63.399726999999984,65.67637599999995],[-63.412215999999944,65.67804000000001],[-63.44860799999992,65.68081700000005],[-63.46194499999996,65.68109099999998],[-63.70472000000001,65.68220500000001],[-63.71721600000001,65.68165600000003],[-63.723609999999894,65.68026700000001],[-63.72860700000001,65.67581200000001],[-63.728882,65.67303500000014],[-63.723609999999894,65.66886900000003],[-63.700553999999954,65.65582300000011],[-63.68360899999999,65.65081800000007],[-63.67166900000001,65.64833099999998],[-63.50472300000001,65.6308140000001],[-63.45333099999999,65.62970000000013],[-63.432503,65.63192700000002],[-63.399726999999984,65.63415500000013],[-63.375,65.632202],[-63.36860699999994,65.6291500000001],[-63.351669000000015,65.61775200000011],[-63.326667999999984,65.60081500000007],[-63.319999999999936,65.593323],[-63.33666199999993,65.55693099999996],[-63.34332999999998,65.54832500000009],[-63.35500300000001,65.53776600000003],[-63.35972600000002,65.53610200000003],[-63.37361099999998,65.53387499999997],[-63.46333299999998,65.52276600000005],[-63.47471599999989,65.52360500000003],[-63.48221599999994,65.52526900000004],[-63.488609,65.52832000000006],[-63.501396,65.53637700000002],[-63.523056,65.55081200000012],[-63.5327759999999,65.55859400000008],[-63.541114999999934,65.57026700000011],[-63.54138899999987,65.57415800000001],[-63.54666900000001,65.5811000000001],[-63.561278999999956,65.58537299999995],[-63.567943999999954,65.5900420000001],[-63.572449000000006,65.59120900000005],[-63.58127999999999,65.59187300000008],[-63.589943000000005,65.59120900000005],[-63.59577899999999,65.58903500000008],[-63.60889400000002,65.58998100000002],[-63.61833199999995,65.54193100000003],[-63.61666099999991,65.53749099999999],[-63.61277799999988,65.5333250000001],[-63.601395000000025,65.53027300000002],[-63.530280999999945,65.51220699999999],[-63.43277699999993,65.48442100000011],[-63.39194500000002,65.47248800000011],[-63.362503000000004,65.46331800000002],[-63.30916599999995,65.44552599999997],[-63.3016659999999,65.4416500000001],[-63.29527999999999,65.43637100000012],[-63.290839999999946,65.43165600000009],[-63.292778,65.42886399999998],[-63.39388999999994,65.42526200000003],[-63.40999599999992,65.42665100000005],[-63.46888699999994,65.43969700000014],[-63.49527699999999,65.4502720000001],[-63.50278500000002,65.454163],[-63.52166699999998,65.46110500000009],[-63.5327759999999,65.46470599999998],[-63.55332900000002,65.46887200000003],[-63.568892999999946,65.47164900000013],[-63.583327999999995,65.4727630000001],[-63.64305899999988,65.47360200000008],[-63.65444199999996,65.47221399999995],[-63.65555599999993,65.47082499999999],[-63.65471600000001,65.46499599999999],[-63.62749499999995,65.45582600000012],[-63.56361399999997,65.43580600000007],[-63.483611999999994,65.40498400000001],[-63.335556,65.30053700000002],[-63.335830999999985,65.29553199999992],[-63.42472099999998,65.22943099999998],[-63.472220999999934,65.19636500000001],[-63.41889200000003,65.145264],[-63.37694499999998,65.11080900000002],[-63.42444599999993,65.04914900000011],[-63.46472199999994,65.01805100000013],[-63.527221999999995,64.97192400000006],[-63.52833599999997,64.967758],[-63.54695099999998,64.88720700000005],[-63.653885,64.91165200000006],[-63.659720999999934,64.93969700000008],[-63.74777999999998,64.96220399999999],[-63.82417299999997,64.98471100000006],[-63.82833900000003,65.01081799999992],[-63.82556199999988,65.01277199999998],[-63.72027600000001,65.03082300000011],[-63.66972399999992,65.03498800000011],[-63.65999599999998,65.03637700000013],[-63.655272999999966,65.03804000000008],[-63.658051,65.04109199999999],[-63.664718999999934,65.04359400000004],[-63.685554999999965,65.04775999999998],[-63.697776999999974,65.04942300000005],[-63.732215999999994,65.04887400000013],[-63.75194499999998,65.04525800000005],[-63.78221899999994,65.03414900000001],[-63.801941,65.03027300000008],[-63.82444799999996,65.02748100000002],[-63.849723999999924,65.03027300000008],[-63.861114999999984,65.03332500000005],[-63.87055199999992,65.04081699999995],[-63.873885999999914,65.04553199999998],[-63.87555699999996,65.05026200000003],[-63.885559,65.07998700000013],[-63.886116000000015,65.08581500000003],[-63.881667999999934,65.09693900000013],[-63.94860799999998,65.10054000000002],[-64.12110899999993,65.04386900000009],[-64.13249199999996,65.04443400000008],[-64.14083900000003,65.047211],[-64.26722699999999,65.09414700000002],[-64.27583300000003,65.09887700000007],[-64.271118,65.10331700000006],[-64.22193900000002,65.14694200000008],[-64.20889299999999,65.155258],[-64.18582200000003,65.16387900000007],[-64.16722099999993,65.17053200000004],[-64.13110399999994,65.18248000000011],[-64.12971500000003,65.19358800000009],[-64.20361300000002,65.1997070000001],[-64.2119449999999,65.19999699999994],[-64.23138399999999,65.19693000000001],[-64.301941,65.16304000000014],[-64.30999799999995,65.15914900000007],[-64.31471299999998,65.15248100000008],[-64.33917200000002,65.16137700000002],[-64.37332200000003,65.17720000000003],[-64.38082899999989,65.1810910000001],[-64.39584400000001,65.20721400000008],[-64.40722700000003,65.27581800000002],[-64.40527299999991,65.28553799999992],[-64.40278599999994,65.2910920000001],[-64.39862099999993,65.29693600000013],[-64.389725,65.30442800000009],[-64.35583500000001,65.324997],[-64.333328,65.33720399999999],[-64.30999799999995,65.34999099999999],[-64.30055199999998,65.35582],[-64.25556899999998,65.38638299999997],[-64.25083899999987,65.39082300000001],[-64.23638900000003,65.421921],[-64.23416099999997,65.42719999999997],[-64.237213,65.42997700000006],[-64.24888599999991,65.43054200000012],[-64.27278100000001,65.42858899999999],[-64.29110700000001,65.42248499999994],[-64.43138099999999,65.32693499999999],[-64.46167000000003,65.294983],[-64.47166400000003,65.28332499999999],[-64.47471599999994,65.27249100000012],[-64.46888699999994,65.26388500000002],[-64.46389799999997,65.25888100000003],[-64.456955,65.24942000000004],[-64.45249899999999,65.2416530000001],[-64.45556599999998,65.20721400000008],[-64.46221899999995,65.190811],[-64.4683379999999,65.18026700000013],[-64.50973499999992,65.12052900000009],[-64.52111799999994,65.10914600000012],[-64.53500400000001,65.09721400000012],[-64.54998799999998,65.09275800000006],[-64.55555699999996,65.09220900000008],[-64.56193499999995,65.094986],[-64.56750499999993,65.11581400000006],[-64.56750499999993,65.11998],[-64.56945799999994,65.12441999999999],[-64.58000199999992,65.12886000000003],[-64.61138900000003,65.14193700000004],[-64.64111299999996,65.14999399999999],[-64.65527299999997,65.16609200000005],[-64.71833800000002,65.22248799999994],[-64.76028400000001,65.25221300000004],[-64.76501499999995,65.24775699999998],[-64.77833599999997,65.238586],[-64.78832999999992,65.23414600000001],[-64.80110200000001,65.23082000000011],[-64.81471299999998,65.23525999999998],[-64.864441,65.25665300000009],[-64.883896,65.26527399999998],[-64.89111300000002,65.26915000000008],[-64.89666699999998,65.27331500000008],[-64.898346,65.27581800000002],[-64.910553,65.29942299999999],[-64.91082799999998,65.3035890000001],[-64.91000400000001,65.30497700000001],[-64.85588799999994,65.31454500000012],[-64.83422899999994,65.31904600000001],[-64.82338700000003,65.31821400000013],[-64.79611199999994,65.31860400000005],[-64.79388399999999,65.31469700000008],[-64.78639199999998,65.31080600000001],[-64.777222,65.30914300000012],[-64.75717199999991,65.31309500000003],[-64.75217399999991,65.31425500000012],[-64.69610599999987,65.32971200000003],[-64.691101,65.33194000000003],[-64.68720999999994,65.33499100000006],[-64.685272,65.33749399999999],[-64.68443300000001,65.34109500000005],[-64.68916299999995,65.3416600000001],[-64.79972800000002,65.34693900000008],[-64.81361399999997,65.34721400000006],[-64.86805699999996,65.33970600000009],[-64.89778099999995,65.33415200000007],[-64.90916399999998,65.33471700000013],[-64.912216,65.33804299999997],[-64.910553,65.33998100000008],[-64.90472399999999,65.34359699999993],[-64.60916099999997,65.426376],[-64.59111000000001,65.42970300000013],[-64.58389299999999,65.43026700000007],[-64.50834700000001,65.42581200000006],[-64.47721899999999,65.42109700000003],[-64.46640000000002,65.41748000000007],[-64.45834399999995,65.4166560000001],[-64.44860799999998,65.41831999999994],[-64.44193999999993,65.4202580000001],[-64.43360899999993,65.4291530000001],[-64.42999299999997,65.434418],[-64.40943900000002,65.47387700000007],[-64.41278099999994,65.4785920000001],[-64.41833500000001,65.48275800000005],[-64.4344329999999,65.48414600000012],[-64.551941,65.45776400000005],[-64.695267,65.42776500000002],[-64.79527300000001,65.41526800000003],[-64.80665599999992,65.41387900000001],[-64.82417299999986,65.41331500000007],[-64.833618,65.41442900000004],[-64.84388699999994,65.41720599999996],[-64.84555099999994,65.41943400000014],[-64.85499600000003,65.42275999999998],[-64.86389199999996,65.42469800000009],[-64.86971999999997,65.42387400000013],[-64.97416699999997,65.40470899999997],[-64.98111,65.4019320000001],[-64.98750299999995,65.39776599999999],[-64.99027999999993,65.3938750000001],[-64.98860200000001,65.37942499999997],[-64.98582499999992,65.37136800000002],[-64.98971599999999,65.36831699999999],[-65.00111399999992,65.36665299999999],[-65.01611299999996,65.36720300000002],[-65.05888399999998,65.3766480000001],[-65.07501200000002,65.38304100000005],[-65.136124,65.42248499999994],[-65.14416499999987,65.42776500000002],[-65.14999399999999,65.434143],[-65.16888399999999,65.48275800000005],[-65.16805999999997,65.48387100000008],[-65.16000399999996,65.48803700000002],[-65.14944500000001,65.49304200000006],[-65.14250199999992,65.49581899999998],[-65.12999000000002,65.49859600000002],[-65.11027499999994,65.49748200000005],[-65.08250399999997,65.50054899999998],[-64.92971799999992,65.52470399999999],[-64.854446,65.5836030000001],[-64.83694499999996,65.60581999999994],[-64.76722699999999,65.63998399999997],[-64.741669,65.641663],[-64.723053,65.64360000000005],[-64.71194499999996,65.64721700000001],[-64.70944199999991,65.65054300000003],[-64.71000700000002,65.65220599999998],[-64.71444699999995,65.65332000000012],[-64.76834099999996,65.65998800000011],[-64.79472399999997,65.66192600000005],[-64.81861899999996,65.66192600000005],[-64.82806399999993,65.66110200000008],[-64.84388699999994,65.65803499999998],[-64.85333300000002,65.65470900000014],[-64.87222299999996,65.64498900000001],[-64.88890100000003,65.6291500000001],[-64.89999399999994,65.616379],[-64.95249899999988,65.56442300000009],[-64.97416699999997,65.55137600000006],[-64.99360699999988,65.54803500000003],[-65.11027499999994,65.54109200000005],[-65.15306099999998,65.53915400000011],[-65.31111099999998,65.54887400000001],[-65.31834400000002,65.55053700000013],[-65.32640099999998,65.55636600000014],[-65.333328,65.56359900000012],[-65.33860799999997,65.57554600000009],[-65.308334,65.62109400000003],[-65.30332899999996,65.62831099999994],[-65.29998799999993,65.6308140000001],[-65.295837,65.63165300000009],[-65.27528399999994,65.63136300000008],[-65.252228,65.62997400000006],[-65.21777299999997,65.62997400000006],[-65.18859900000001,65.62997400000006],[-65.15388499999995,65.63026400000007],[-65.12582399999997,65.633331],[-65.112503,65.6372070000001],[-65.10583500000001,65.63943500000005],[-65.103882,65.64248700000013],[-65.103882,65.65193200000004],[-65.10943600000002,65.65887500000002],[-65.10694899999999,65.66720599999991],[-65.10583500000001,65.66859400000004],[-65.09973100000002,65.67192099999994],[-64.99444599999993,65.70138500000013],[-64.98138399999999,65.70471200000009],[-64.96972699999998,65.70665000000002],[-64.94221500000003,65.70915200000007],[-64.92250100000001,65.70942700000012],[-64.90249599999999,65.70860299999998],[-64.81471299999998,65.71276900000004],[-64.80332899999996,65.71415700000011],[-64.79834,65.71638500000012],[-64.79360999999989,65.71998599999995],[-64.791382,65.72331200000002],[-64.79499799999996,65.72804300000013],[-64.80194099999989,65.73027000000002],[-64.81555200000003,65.730545],[-64.90695199999999,65.7288670000001],[-64.973053,65.72360200000003],[-64.99694799999992,65.72137499999997],[-65.024719,65.71693400000004],[-65.05721999999997,65.71026600000005],[-65.07611099999991,65.70555100000001],[-65.10305800000003,65.69442700000013],[-65.11610399999995,65.68525700000009],[-65.13861099999997,65.67109699999997],[-65.144455,65.66748000000001],[-65.16416899999996,65.65693700000008],[-65.16833499999996,65.65609700000005],[-65.3699949999999,65.66110200000008],[-65.43138099999993,65.66914400000007],[-65.44166599999988,65.67164600000012],[-65.44999699999988,65.67498800000004],[-65.45445299999989,65.67831400000011],[-65.45695499999994,65.68220500000001],[-65.45639,65.68553199999991],[-65.45249899999993,65.69081100000011],[-65.447769,65.6952510000001],[-65.46028100000001,65.74136400000009],[-65.49027999999993,65.73580900000002],[-65.49777199999994,65.73748799999998],[-65.50556899999998,65.74331699999999],[-65.50500499999998,65.75166300000012],[-65.49888599999986,65.76304600000009],[-65.45527600000003,65.83248900000007],[-65.44915800000001,65.84109499999994],[-65.439438,65.8477630000001],[-65.35722399999997,65.90248099999991],[-65.15222199999994,65.95776400000011],[-65.137787,65.96110499999998],[-65.05027799999999,65.98054500000012],[-64.96389799999997,65.99859600000013],[-64.94610599999999,66.00138900000013],[-64.9347229999999,66.0022130000001],[-64.92304999999999,66.00138900000013],[-64.898346,65.99693300000001],[-64.88082899999995,65.98997500000002],[-64.85110499999996,65.98054500000012],[-64.84222399999993,65.97804300000007],[-64.80139200000002,65.96943699999997],[-64.77250699999996,65.96609500000005],[-64.75500499999993,65.96609500000005],[-64.74333200000001,65.96748400000001],[-64.73500100000001,65.96943699999997],[-64.73388699999992,65.97554000000008],[-64.73860199999996,65.97886700000004],[-64.76501499999995,65.98803700000008],[-64.82167099999998,66.04470800000001],[-64.75083899999993,66.18553200000002],[-64.72166399999998,66.21748399999996],[-64.712219,66.22360200000008],[-64.60583499999996,66.25915500000013],[-64.48055999999997,66.29637100000008],[-64.45195000000001,66.3035890000001],[-64.40556300000003,66.31581100000005],[-64.38861099999991,66.32165500000008],[-64.37554899999992,66.32720900000004],[-64.36582900000002,66.33305399999995],[-64.35638399999993,66.34054600000007],[-64.354172,66.34803800000003],[-64.35638399999993,66.34971599999994],[-64.366104,66.35081500000013],[-64.37748699999997,66.34999099999999],[-64.44387799999998,66.34471100000007],[-64.46472199999994,66.34304800000001],[-64.71444699999995,66.27499400000005],[-64.718887,66.27331500000003],[-64.78916899999996,66.23637400000013],[-64.79611199999994,66.23165900000009],[-64.83999599999999,66.19331399999999],[-64.85804699999994,66.14999399999999],[-64.85665899999998,66.13998400000008],[-64.851944,66.12498499999998],[-64.84973099999996,66.12052900000009],[-64.85417199999995,66.10971100000012],[-64.85888699999998,66.10609399999998],[-64.93388400000003,66.08027600000003],[-64.94860799999998,66.07693499999999],[-65.12609899999995,66.03776600000009],[-65.38194299999992,65.97581500000013],[-65.398056,65.97470099999992],[-65.827789,65.95304900000008],[-65.87638900000002,65.94802900000002],[-65.91610699999995,65.95109599999995],[-65.92805499999997,65.95387300000004],[-65.93554699999993,65.95832800000005],[-65.93971299999993,65.96249399999999],[-65.96305799999999,66.034424],[-65.96389799999992,66.04386900000003],[-65.91888399999993,66.08610500000003],[-65.91166699999985,66.0916600000001],[-65.90417500000001,66.09443700000003],[-65.78611799999999,66.12637300000011],[-65.674713,66.15748600000012],[-65.65055799999999,66.1644290000001],[-65.64083899999991,66.16832],[-65.63417099999992,66.172485],[-65.56416299999995,66.22692900000004],[-65.54554699999994,66.2433170000001],[-65.47111499999994,66.34248400000001],[-65.47166399999992,66.38360600000004],[-65.47361799999993,66.38581799999992],[-65.47582999999997,66.38777199999998],[-65.479172,66.38804600000009],[-65.48277300000001,66.38777199999998],[-65.48971599999999,66.38581799999992],[-65.50167799999991,66.37637300000006],[-65.55387899999994,66.32777400000009],[-65.55583199999995,66.32527200000004],[-65.55943300000001,66.3205410000001],[-65.5616609999999,66.31442300000015],[-65.564438,66.29359399999998],[-65.56277499999999,66.28831500000001],[-65.56277499999999,66.28332499999993],[-65.57167099999998,66.26832600000006],[-65.59889199999992,66.24498],[-65.61054999999988,66.23580900000007],[-65.69694499999997,66.18054200000012],[-65.70249899999999,66.17747500000002],[-65.84416199999993,66.13581799999997],[-65.926941,66.11470000000008],[-65.95195000000001,66.10887100000008],[-65.96833799999996,66.1080320000001],[-66.073624,66.12052900000009],[-66.13917499999997,66.13136299999996],[-66.14500399999997,66.1336060000001],[-66.14723200000003,66.13526900000005],[-66.20083599999998,66.19497700000005],[-66.19110099999995,66.23997499999996],[-66.25111400000003,66.24220300000013],[-66.37138400000003,66.22526600000009],[-66.401947,66.20082100000008],[-66.47833300000002,66.20166000000006],[-66.48971599999987,66.20277400000003],[-66.49694799999997,66.20498699999996],[-66.50500499999993,66.20887800000003],[-66.52444500000001,66.22415200000012],[-66.52999899999992,66.2291560000001],[-66.53416400000003,66.233047],[-66.54083299999996,66.2416530000001],[-66.54277000000002,66.24664300000012],[-66.57749899999999,66.35443099999998],[-66.57611099999997,66.35914600000001],[-66.57000700000003,66.36554000000007],[-66.56416299999995,66.36914100000013],[-66.53694200000001,66.37803599999995],[-66.500565,66.38804600000009],[-66.45472699999999,66.39804100000015],[-66.445267,66.40138200000001],[-66.43832399999991,66.40415999999999],[-66.43443300000001,66.40721100000002],[-66.43720999999994,66.41331500000007],[-66.44193999999999,66.41442900000004],[-66.4661099999999,66.41499299999998],[-66.47361799999999,66.41442900000004],[-66.48138399999999,66.41304000000002],[-66.597778,66.38693200000012],[-66.60499600000003,66.37637300000006],[-66.61000100000001,66.37136800000002],[-66.61749299999991,66.3685910000001],[-66.62999000000002,66.36775200000011],[-66.71389799999997,66.36886600000008],[-66.72416699999991,66.36943100000013],[-66.73083499999996,66.36998000000011],[-66.74305700000002,66.37275699999998],[-66.76777599999991,66.38053900000011],[-66.82167099999992,66.45803799999993],[-66.82167099999992,66.46081500000003],[-66.80638099999993,66.53193699999997],[-66.85194399999995,66.58332800000005],[-66.97222899999991,66.62886000000009],[-66.99972499999996,66.63832100000002],[-67.023056,66.64332600000006],[-67.03611799999993,66.64471400000002],[-67.04888900000003,66.64471400000002],[-67.05888400000003,66.64276100000006],[-67.06054699999999,66.64027399999998],[-67.05610699999994,66.63360599999999],[-67.04333499999996,66.62580900000006],[-67.01666299999994,66.61526500000002],[-66.95056199999988,66.59220900000014],[-66.90833999999995,66.57804900000008],[-66.8875119999999,66.56944299999998],[-66.88417099999987,66.56608600000004],[-66.88945000000001,66.56109600000013],[-67.10555999999997,66.48580900000002],[-67.11833199999995,66.48498500000005],[-67.13362099999995,66.48580900000002],[-67.17694099999994,66.48970000000008],[-67.18971299999993,66.49165300000004],[-67.19860799999998,66.49414100000001],[-67.202225,66.49720800000011],[-67.20388799999995,66.50526400000001],[-67.19221500000003,66.51527400000009],[-67.18611099999998,66.52442899999994],[-67.19027699999998,66.5291600000001],[-67.327225,66.59582500000005],[-67.33833299999998,66.59776299999999],[-67.34584000000001,66.59721400000001],[-67.39862099999988,66.58915700000006],[-67.41000399999996,66.58554099999998],[-67.46362299999998,66.57887300000004],[-67.515015,66.57360799999998],[-67.58111600000001,66.57527199999998],[-67.639725,66.58055100000013],[-67.72694399999989,66.57666000000006],[-67.737213,66.57415800000001],[-67.74082899999996,66.57110600000004],[-67.74276700000001,66.56832899999995],[-67.74194299999994,66.56414800000005],[-67.73500100000001,66.56137100000001],[-67.72277799999989,66.55802900000003],[-67.70111099999986,66.55581699999999],[-67.49999999999994,66.54483800000003],[-67.42610200000001,66.54136700000004],[-67.40777600000001,66.54220600000002],[-67.39584399999995,66.54470800000007],[-67.3805539999999,66.54582200000004],[-67.37388599999991,66.54582200000004],[-67.36582900000002,66.54443400000014],[-67.29638699999992,66.526093],[-67.28167699999995,66.51887499999998],[-67.14862099999999,66.44386300000002],[-67.14389,66.43775900000003],[-67.14361599999995,66.43553199999997],[-67.13806199999999,66.38220200000006],[-67.139725,66.37664800000005],[-67.16082799999998,66.36554000000007],[-67.17250100000001,66.36387600000006],[-67.18527199999994,66.36360200000013],[-67.197769,66.365814],[-67.29167199999989,66.39942900000005],[-67.33750900000001,66.41886900000009],[-67.33898899999991,66.42285200000009],[-67.34306300000003,66.42665099999999],[-67.35028099999994,66.42886399999998],[-67.36582900000002,66.42970300000013],[-67.38972499999994,66.4308170000001],[-67.406387,66.42970300000013],[-67.410553,66.42526200000003],[-67.41000399999996,66.42082199999999],[-67.383331,66.40193200000004],[-67.37832600000002,66.39860499999992],[-67.36860699999994,66.39471400000002],[-67.31361400000003,66.37637300000006],[-67.28860499999996,66.36886600000008],[-67.24082899999996,66.35887100000002],[-67.195831,66.35498000000013],[-67.18859899999995,66.35220300000003],[-67.13305700000001,66.31387300000011],[-67.12527499999999,66.30693100000002],[-67.12609900000001,66.305542],[-67.12916599999994,66.3035890000001],[-67.13944999999995,66.30137600000012],[-67.162216,66.29887400000007],[-67.18388400000003,66.29748500000005],[-67.19415300000003,66.29776000000004],[-67.208618,66.29998800000004],[-67.226944,66.30415300000004],[-67.24082899999996,66.30415300000004],[-67.25418100000002,66.30276500000014],[-67.26167299999997,66.29914900000006],[-67.28222699999998,66.27526900000004],[-67.29750100000001,66.276093],[-67.39917000000003,66.29248000000001],[-67.41389500000002,66.29664600000007],[-67.450287,66.31666600000011],[-67.45306399999993,66.3205410000001],[-67.45333900000003,66.32249500000012],[-67.49471999999997,66.35693400000014],[-67.52610800000002,66.38220200000006],[-67.5625,66.40748600000006],[-67.566666,66.409424],[-67.60305799999998,66.41859400000004],[-67.63417099999998,66.42469800000009],[-67.69082600000002,66.43525699999992],[-67.71305799999999,66.43609600000008],[-67.73028599999998,66.43997199999995],[-67.81249999999994,66.46304300000003],[-67.82528699999995,66.46775800000006],[-67.8286129999999,66.47082499999993],[-67.83473200000003,66.48332199999993],[-67.83860799999991,66.49165300000004],[-67.92361499999993,66.51609800000006],[-67.95249899999999,66.51470900000004],[-67.98582499999986,66.50972000000007],[-67.99276700000001,66.50694300000004],[-67.99276700000001,66.5038760000001],[-67.94471699999986,66.4788670000001],[-67.929169,66.47303800000009],[-67.906113,66.46804800000007],[-67.88694800000002,66.461929],[-67.87026999999995,66.45471200000009],[-67.76055899999994,66.35803200000004],[-67.75639299999995,66.353317],[-67.71112099999993,66.29693600000007],[-67.70140100000003,66.28471400000012],[-67.70167499999997,66.27832000000006],[-67.70556599999998,66.27526900000004],[-67.724716,66.26081800000003],[-67.67222599999997,66.22831700000012],[-67.57055699999995,66.184143],[-67.454453,66.14471400000008],[-67.39999399999999,66.12637300000011],[-67.28138699999994,66.083054],[-67.165009,66.03692600000005],[-67.16250600000001,66.03526299999993],[-67.24352299999993,65.97830199999999],[-67.17304999999988,65.91859399999998],[-67.18582199999997,65.91220099999998],[-67.19444299999998,65.90971400000012],[-67.20167499999997,65.90914900000007],[-67.42999299999991,65.90554800000001],[-67.74055499999986,65.89415000000002],[-67.79527300000001,65.87719700000014],[-67.82417299999997,65.88081400000004],[-67.86471599999993,65.88777200000004],[-67.914444,65.89915500000006],[-67.93859900000001,65.9080350000001],[-68.02694699999995,65.99275200000011],[-68.03056300000003,65.99803200000002],[-68.031387,66.0022130000001],[-68.027222,66.06080600000007],[-68.02583299999998,66.06581100000011],[-68.13082899999995,66.1266480000001],[-68.24472000000003,66.1827550000001],[-68.34028599999999,66.19693000000001],[-68.53805499999993,66.20082100000008],[-68.71278399999994,66.19859300000013],[-68.808334,66.19581600000004],[-68.84249899999998,66.19331399999999],[-68.85139499999997,66.18997200000001],[-68.84638999999993,66.186646],[-68.83528100000001,66.18498199999999],[-68.66861,66.17886400000003],[-68.56834399999997,66.17858899999999],[-68.41471899999999,66.15942400000006],[-68.40361000000001,66.14637800000008],[-68.39111300000002,66.13526900000005],[-68.38333099999994,66.13108799999998],[-68.30027799999988,66.092758],[-68.27806099999998,66.08360299999998],[-68.24415599999998,66.07110599999999],[-68.23777799999993,66.06999200000001],[-68.22555499999999,66.06999200000001],[-68.220551,66.0730440000001],[-68.218887,66.08137500000004],[-68.22193900000002,66.0852660000001],[-68.22972099999998,66.09220900000008],[-68.24415599999998,66.09999100000005],[-68.24694799999997,66.11276199999998],[-68.22000099999997,66.12858600000004],[-68.20249899999993,66.12885999999997],[-68.19471699999997,66.12747200000007],[-68.15750100000002,66.11747700000001],[-68.13417099999998,66.10998500000005],[-68.11888099999999,66.1035920000001],[-68.04722600000002,66.06498699999997],[-68.04888900000003,66.00749200000007],[-68.05194099999994,65.996643],[-68.05360399999995,65.99108899999999],[-68.06443799999994,65.98442100000005],[-68.12388599999997,65.96304300000008],[-68.13417099999998,65.96331800000013],[-68.17361499999998,65.96943699999997],[-68.19694500000003,65.97387699999996],[-68.210556,65.97943099999998],[-68.27806099999998,66.01416000000006],[-68.30444299999988,66.02804600000002],[-68.32389799999993,66.00387599999999],[-68.333618,65.93193100000002],[-68.33222999999992,65.92886400000009],[-68.32583599999998,65.91638200000011],[-68.32167099999998,65.911926],[-68.30474899999996,65.90866100000005],[-68.287781,65.907761],[-68.26000999999991,65.91137700000002],[-68.19415300000003,65.92109700000015],[-68.156113,65.92970300000002],[-68.150284,65.930542],[-68.14277599999997,65.92915299999999],[-68.13999899999999,65.92747500000007],[-68.136124,65.92276000000004],[-68.13473499999992,65.91360500000002],[-68.13290399999994,65.83488500000004],[-68.13917500000002,65.81721500000015],[-68.14723199999997,65.79832500000003],[-68.03332499999993,65.77638200000007],[-68.02389499999987,65.77526899999998],[-68.00306699999999,65.77832000000001],[-67.92361499999993,65.79386900000009],[-67.88612399999988,65.80497700000006],[-67.82112099999995,65.76805099999996],[-67.87026999999995,65.68942299999998],[-67.94248999999996,65.61804200000012],[-67.9891659999999,65.61914100000007],[-68.05888400000003,65.56805399999996],[-68.027222,65.5583190000001],[-68.01251200000002,65.55775499999993],[-68.01167299999997,65.55886800000002],[-67.99861099999998,65.56693999999999],[-67.98721299999994,65.57138100000009],[-67.971115,65.57527199999998],[-67.95666499999999,65.57165500000002],[-67.95167500000002,65.568329],[-67.95306399999993,65.55720500000012],[-67.95500199999998,65.55386400000009],[-68.02084400000001,65.49803200000008],[-68.02778599999994,65.49165300000004],[-68.03028899999998,65.48776199999998],[-68.03056300000003,65.48442100000011],[-68.02583299999998,65.48109399999998],[-68.02250700000002,65.48054500000006],[-68.00778200000002,65.48553500000008],[-67.94193999999993,65.52526900000004],[-67.92250099999995,65.53804000000014],[-67.86027499999994,65.58442700000006],[-67.73028599999998,65.63638300000014],[-67.712219,65.64082300000013],[-67.65249599999999,65.65138200000001],[-67.46610999999996,65.67414900000011],[-67.428604,65.67665099999999],[-67.40249599999993,65.67747500000013],[-67.396118,65.67665099999999],[-67.38221699999991,65.67387400000007],[-67.32806399999998,65.66249100000005],[-67.31945799999994,65.65942399999994],[-67.28056299999997,65.64248700000013],[-67.275284,65.6377720000001],[-67.25666799999999,65.61526500000002],[-67.25389100000001,65.611649],[-67.25167799999986,65.60693400000014],[-67.25334199999998,65.60165400000005],[-67.25666799999999,65.599152],[-67.27278100000001,65.59526100000011],[-67.32055700000001,65.58692900000011],[-67.33332799999994,65.58248900000007],[-67.33612099999993,65.580826],[-67.45666499999999,65.501938],[-67.45889299999993,65.49803200000008],[-67.45140099999992,65.49359099999998],[-67.34750400000001,65.45860299999998],[-67.22138999999999,65.45637500000004],[-67.18998699999997,65.45803799999999],[-67.18083200000001,65.45915200000013],[-67.16915899999998,65.46138000000008],[-67.15556300000003,65.4669340000001],[-67.14222699999999,65.46914700000008],[-67.08167999999995,65.46249400000005],[-67.06555200000003,65.45860299999998],[-67.05860899999993,65.45359799999994],[-67.058044,65.45138500000002],[-67.058334,65.42665100000005],[-67.06277499999993,65.41748000000007],[-67.07833900000003,65.39221199999997],[-67.11111499999998,65.36470000000003],[-67.11805699999996,65.36192299999993],[-67.12388599999997,65.36053500000003],[-67.13444500000003,65.35971100000006],[-67.21806300000003,65.35859700000009],[-67.25556899999992,65.36053500000003],[-67.316101,65.35859700000009],[-67.40083300000003,65.35026600000003],[-67.40888999999999,65.3483280000001],[-67.41361999999992,65.3458250000001],[-67.41777000000002,65.34220900000003],[-67.41610700000001,65.33915700000011],[-67.40943900000002,65.33332800000011],[-67.39999399999999,65.32971200000003],[-67.39111300000002,65.3272090000001],[-67.33666999999997,65.31721500000009],[-67.32667499999997,65.31694000000005],[-67.31916799999993,65.31805400000002],[-67.31582600000002,65.3205410000001],[-67.30665599999986,65.33027600000003],[-67.306107,65.33360299999993],[-67.30694599999998,65.33804299999997],[-67.30387899999994,65.34248400000007],[-67.29750100000001,65.347488],[-67.29138199999994,65.349716],[-67.283615,65.35108900000006],[-67.26916499999999,65.35220300000003],[-67.12554899999998,65.31191999999999],[-67.11999500000002,65.30998200000005],[-67.077789,65.2502750000001],[-67.06388900000002,65.21832299999994],[-66.93472300000002,65.23387100000014],[-66.93306000000001,65.23359700000003],[-66.92887899999994,65.22970599999996],[-66.94888300000002,65.12525900000014],[-66.95083599999998,65.11692800000003],[-66.95333900000003,65.11303699999996],[-66.95916699999998,65.10664400000002],[-66.96749899999998,65.10386699999992],[-67.02528399999989,65.10832199999993],[-67.04415899999992,65.107483],[-67.05555700000002,65.10525500000006],[-67.066666,65.10081500000001],[-67.07223499999998,65.09721400000012],[-67.10611,65.06414799999999],[-67.108612,65.06025699999992],[-67.10777300000001,65.05886800000013],[-67.096115,65.05609100000004],[-67.08583099999998,65.05636600000008],[-67.07501200000002,65.05802900000015],[-66.89056399999998,65.10331700000006],[-66.835556,65.13720699999999],[-66.756393,65.17720000000003],[-66.74749799999995,65.180542],[-66.73028599999992,65.18136600000014],[-66.72610500000002,65.18026700000013],[-66.72555499999999,65.17804000000007],[-66.75334199999998,65.11331200000001],[-66.80166600000001,65.06080600000007],[-66.76750199999998,65.02442900000011],[-66.74305700000002,64.96304299999997],[-66.726944,64.91387900000012],[-66.72749299999992,64.90525800000006],[-66.72805799999998,64.901657],[-66.73306300000002,64.88832100000002],[-66.73916599999995,64.85998500000011],[-66.73500099999995,64.8247070000001],[-66.73416099999992,64.82054100000005],[-66.69804399999987,64.76193199999994],[-66.69471699999991,64.76138300000002],[-66.68777499999999,64.76220699999999],[-66.65417500000001,64.7711030000001],[-66.64111300000002,64.77581800000013],[-66.63249200000001,64.78137200000015],[-66.63806199999999,64.78553800000003],[-66.6761019999999,64.876083],[-66.69694499999997,65.03276100000005],[-66.69415299999997,65.0372010000001],[-66.68866000000003,65.03877299999994],[-66.67332499999998,65.038589],[-66.66082799999998,65.0372010000001],[-66.61805699999996,65.03027300000008],[-66.535278,65.01081799999992],[-66.53056300000003,65.00749200000007],[-66.49610899999999,64.98304700000006],[-66.48889199999991,64.95748900000012],[-66.49665800000002,64.94552600000009],[-66.495544,64.93887300000011],[-66.491379,64.93498200000005],[-66.48666400000002,64.93220500000012],[-66.47860699999995,64.92915300000004],[-66.38861099999997,64.91331500000001],[-66.379166,64.91220100000004],[-66.36805700000002,64.91360500000002],[-66.36389200000002,64.91748000000001],[-66.36193800000001,64.92359900000002],[-66.36361699999992,64.9285890000001],[-66.33473200000003,64.93470800000011],[-66.17777999999993,64.88026400000007],[-66.148346,64.86886600000003],[-66.17721599999999,64.79637100000002],[-66.18472300000002,64.78442400000006],[-66.19193999999993,64.77887000000004],[-66.19943199999994,64.77499399999999],[-66.20333900000003,64.77388000000002],[-66.21333300000003,64.75610400000005],[-66.21916199999998,64.72608900000012],[-66.21888699999994,64.69081100000011],[-66.21221899999995,64.68553199999997],[-66.18472300000002,64.68165600000003],[-66.16694599999994,64.68109100000004],[-66.16111799999993,64.68248],[-66.15834000000001,64.68414300000012],[-66.151947,64.68914799999999],[-66.14778100000001,64.69581599999998],[-66.14723200000003,64.70138500000013],[-66.14723200000003,64.70416299999994],[-66.15028399999994,64.71748400000007],[-66.14973399999991,64.73359700000015],[-66.145554,64.74026500000014],[-66.13639799999999,64.75416600000011],[-66.11694299999999,64.78137200000015],[-66.09167500000001,64.80970800000006],[-66.08084100000002,64.81915300000009],[-66.05833399999995,64.83276400000005],[-66.03721599999994,64.84498600000006],[-66.02084399999995,64.84971600000006],[-66.01139799999999,64.84832799999998],[-66.011124,64.84637500000002],[-66.008621,64.78915400000011],[-66.00917099999987,64.77804600000007],[-66.0125119999999,64.69941700000004],[-65.89999399999999,64.67330900000007],[-65.84666400000003,64.676086],[-65.85221899999999,64.68026700000007],[-65.86138900000003,64.68914799999999],[-65.88944999999995,64.71971100000013],[-65.89917000000003,64.73275799999999],[-65.95861799999994,64.87776199999996],[-65.95666499999993,64.88610800000009],[-65.95333899999997,64.88832100000002],[-65.94193999999999,64.89054899999996],[-65.93138099999993,64.89137299999993],[-65.92471299999994,64.89137299999993],[-65.83860800000002,64.882477],[-65.72721899999993,64.84359700000005],[-65.71777299999997,64.84027100000003],[-65.67443800000001,64.81805400000013],[-65.66416899999996,64.80831900000004],[-65.66166699999997,64.80442800000014],[-65.660278,64.799149],[-65.665009,64.79693600000002],[-65.68331899999993,64.79220600000002],[-65.69833399999999,64.78471400000006],[-65.72027599999996,64.76666300000011],[-65.73611499999998,64.75027500000004],[-65.74249299999991,64.7410890000001],[-65.74276699999996,64.73526000000004],[-65.73693800000001,64.72608900000012],[-65.726944,64.71138000000008],[-65.71083099999998,64.69303900000006],[-65.70472699999993,64.6874850000001],[-65.70306399999993,64.69220000000013],[-65.70944199999997,64.71276900000004],[-65.71055599999994,64.71859699999999],[-65.71000700000002,64.73220800000013],[-65.708618,64.73609900000002],[-65.68415799999997,64.76110799999998],[-65.67610200000001,64.76554899999991],[-65.66528299999993,64.77137800000014],[-65.648056,64.77499399999999],[-65.64277600000003,64.77499399999999],[-65.62721299999993,64.7711030000001],[-65.59889199999992,64.75637799999998],[-65.56639100000001,64.73748800000004],[-65.56111099999987,64.73304700000011],[-65.55749500000002,64.72831700000006],[-65.55583199999995,64.72331200000002],[-65.55638099999993,64.717758],[-65.57223499999992,64.664154],[-65.57667500000002,64.65248100000002],[-65.58332799999994,64.64276100000012],[-65.58639499999992,64.64027400000003],[-65.65472399999999,64.60247800000002],[-65.66250599999995,64.59832800000004],[-65.71417200000002,64.57054100000005],[-65.73083500000001,64.51776100000001],[-65.73222399999997,64.50804099999993],[-65.72555499999993,64.49803199999997],[-65.72166400000003,64.49414100000007],[-65.70834400000001,64.48664900000011],[-65.69554099999999,64.48580900000007],[-65.665009,64.49220300000013],[-65.64334099999996,64.49498],[-65.57333399999999,64.49859600000008],[-65.52471899999995,64.49971000000005],[-65.51806599999998,64.49971000000005],[-65.50639299999995,64.4974820000001],[-65.50418100000002,64.49581899999998],[-65.50556899999998,64.46887200000003],[-65.39611799999994,64.52137799999997],[-65.38417099999998,64.52415500000006],[-65.3658289999999,64.52693199999999],[-65.21055599999988,64.53610200000003],[-65.203888,64.53387499999997],[-65.144455,64.51138300000008],[-65.08500699999996,64.47970599999996],[-65.07778899999994,64.47581500000007],[-65.07583599999998,64.47137500000002],[-65.07417299999997,64.46192900000005],[-65.07167099999998,64.440811],[-65.07194500000003,64.43081699999999],[-65.07362399999994,64.42608600000005],[-65.19499199999996,64.31025700000009],[-65.20249899999999,64.30636600000003],[-65.21083099999998,64.30386399999998],[-65.28472899999991,64.2916560000001],[-65.2952729999999,64.29026799999997],[-65.30943300000001,64.29136699999998],[-65.3433379999999,64.294983],[-65.37721299999998,64.30331400000011],[-65.38639799999993,64.30664100000007],[-65.40888999999993,64.31248500000004],[-65.45167499999997,64.31999200000001],[-65.49888599999986,64.32276900000011],[-65.5250089999999,64.32331800000003],[-65.55416899999994,64.32331800000003],[-65.56332399999991,64.32249499999995],[-65.65583799999996,64.30886800000007],[-65.66166699999997,64.30748],[-65.65833999999995,64.30276500000014],[-65.654449,64.30081200000001],[-65.61860699999994,64.29304500000006],[-65.60194399999995,64.29359400000004],[-65.59194899999994,64.29609699999997],[-65.57223499999992,64.29859900000008],[-65.50584400000002,64.30247500000013],[-65.46583599999997,64.30304000000001],[-65.43415800000002,64.29914900000011],[-65.42277499999994,64.29637100000014],[-65.250565,64.20832800000005],[-65.24610899999999,64.20498700000002],[-65.24276699999996,64.20027199999998],[-65.265015,64.17886400000009],[-65.16194200000001,64.13804600000014],[-65.04943800000001,64.07222000000002],[-65.05387899999994,64.06776400000007],[-65.06054699999993,64.06498699999997],[-65.093887,64.05219999999997],[-65.103882,64.049149],[-65.13667299999992,64.04136700000004],[-65.15833999999995,64.03831500000007],[-65.19610599999993,64.04026800000003],[-65.20611599999995,64.04026800000003],[-65.21665999999999,64.038589],[-65.22138999999993,64.03637700000013],[-65.22555499999993,64.03276100000011],[-65.22193899999996,64.028595],[-65.21417200000002,64.02554300000008],[-65.18998699999992,64.02026400000011],[-65.09666399999998,64.00915500000002],[-65.08805799999999,64.00943000000007],[-64.94915800000001,64.01499900000005],[-64.80055199999998,64.02777100000003],[-64.68638599999997,64.03915400000005],[-64.676941,64.036652],[-64.66805999999997,64.03305100000011],[-64.66111799999999,64.028595],[-64.63055400000002,63.978324999999984],[-64.63137799999998,63.97470900000013],[-64.63276699999994,63.97276300000004],[-64.63833599999998,63.96915400000006],[-64.64805599999994,63.96693400000004],[-64.65888999999999,63.96554600000013],[-64.66999800000002,63.96638500000006],[-64.689438,63.96610300000003],[-64.70056199999999,63.963882000000126],[-64.81750499999998,63.923607000000004],[-64.87527499999999,63.9011000000001],[-64.88890100000003,63.89499699999999],[-64.97471599999994,63.85193600000014],[-64.98500099999995,63.82916300000005],[-64.98750299999995,63.82305100000008],[-64.98416099999992,63.81388100000004],[-64.95417799999996,63.776382000000126],[-64.94888299999991,63.77443700000009],[-64.77806099999998,63.747772000000055],[-64.68360899999999,63.74638399999998],[-64.58444199999985,63.704711999999915],[-64.55943299999996,63.694153000000085],[-64.54028299999999,63.68443300000001],[-64.52749599999999,63.676941000000056],[-64.52250700000002,63.672768000000076],[-64.50834700000001,63.65082600000005],[-64.50666799999999,63.63694000000004],[-64.50750699999998,63.630821000000026],[-64.515015,63.62027000000012],[-64.52194199999991,63.61193800000012],[-64.53666699999997,63.581108000000086],[-64.529449,63.534996000000035],[-64.52250700000002,63.514717000000076],[-64.50167799999997,63.4438780000001],[-64.49888599999997,63.42916100000008],[-64.49554399999994,63.32777399999998],[-64.51083399999999,63.30777000000006],[-64.58889799999986,63.3219380000001],[-64.608337,63.32388300000008],[-64.61999499999996,63.32332600000001],[-64.62222300000002,63.32221999999996],[-64.62471,63.318054000000075],[-64.61999499999996,63.31332400000002],[-64.61471599999999,63.30971500000004],[-64.58778399999994,63.299721000000034],[-64.577225,63.29666099999997],[-64.56639099999995,63.29388400000005],[-64.52555799999993,63.29055000000005],[-64.50083899999998,63.28999299999998],[-64.48889200000002,63.28833000000009],[-64.48277300000001,63.28582799999998],[-64.48194899999987,63.28221100000002],[-64.53111299999995,63.24971800000009],[-64.53805499999993,63.24832900000007],[-64.65833999999995,63.249161000000015],[-64.76750199999992,63.32388300000008],[-64.82695000000001,63.45249199999995],[-64.85055499999993,63.51082600000001],[-64.94249000000002,63.63221000000004],[-64.95500199999992,63.64027400000003],[-64.973053,63.646942000000024],[-64.99499499999996,63.652488999999946],[-65.04638699999992,63.662209000000075],[-65.06361400000003,63.66805300000004],[-65.07084700000001,63.67193600000002],[-65.166946,63.747772000000055],[-65.16639700000002,63.77332300000012],[-65.15333599999991,63.771102999999925],[-65.15083300000003,63.772217000000126],[-65.15417499999995,63.77693900000003],[-65.15943900000002,63.78110500000008],[-65.20472699999993,63.80332199999998],[-65.29360999999994,63.812767000000065],[-65.29861499999993,63.81249200000002],[-65.30139200000002,63.81082200000003],[-65.303879,63.806938],[-65.30027799999993,63.799995000000024],[-65.281677,63.788887000000045],[-65.21556099999992,63.75471500000009],[-65.15566999999993,63.72532699999999],[-65.13528400000001,63.71527100000014],[-65.05305499999997,63.63804600000009],[-65.03916900000002,63.57416500000011],[-65.06973299999999,63.568886000000134],[-65.08583099999993,63.563881000000094],[-65.09194899999994,63.55971499999998],[-65.09999099999993,63.54721799999999],[-65.10221899999999,63.541664000000026],[-65.10221899999999,63.53665899999993],[-65.0994419999999,63.526381999999955],[-65.026947,63.3991620000001],[-64.96501199999994,63.36943800000006],[-64.95249899999988,63.362213],[-64.94249000000002,63.353049999999996],[-64.90916399999998,63.280548000000124],[-64.90110800000002,63.237495000000024],[-64.90861499999994,63.235550000000046],[-64.92138699999992,63.235825000000034],[-65.04638699999992,63.24832900000007],[-65.068893,63.25249499999995],[-65.08250399999997,63.260826000000066],[-65.10333299999996,63.27777100000003],[-65.11416600000001,63.28499600000009],[-65.12332199999997,63.28833000000009],[-65.136124,63.29083300000002],[-65.141953,63.28943600000008],[-65.14862099999999,63.286110000000065],[-65.14695699999987,63.28138000000001],[-65.08332799999994,63.20388000000014],[-65.05777,63.174713],[-65.05499299999991,63.17221799999999],[-65.046112,63.171104000000014],[-65.01652499999994,63.171516],[-64.99861099999993,63.176102000000014],[-64.94471699999991,63.18332700000008],[-64.92027299999995,63.18415800000008],[-64.91139199999992,63.18082400000009],[-64.81166099999996,63.13749700000005],[-64.79750099999995,63.130547000000035],[-64.78388999999999,63.12221500000004],[-64.75500499999993,63.099158999999986],[-64.75334199999992,63.09665700000011],[-64.76251199999996,63.0472180000001],[-64.77139299999999,62.98333000000008],[-64.70333899999997,62.95332300000007],[-64.69610599999987,62.952217000000076],[-64.67639200000002,62.94165800000002],[-64.64555399999995,62.92166099999997],[-64.63444499999997,62.9124910000001],[-64.62721299999998,62.90415999999999],[-64.62693799999994,62.899994000000106],[-64.62998999999996,62.897491000000116],[-64.63833599999998,62.89444000000009],[-64.733612,62.87887599999999],[-64.76945499999994,62.86221300000011],[-64.85526999999996,62.865273],[-64.88194299999986,62.867493000000024],[-64.903885,62.872490000000084],[-64.92332499999998,62.87887599999999],[-65.00500499999998,62.90776800000009],[-65.16221599999994,62.943047000000035],[-65.225281,62.95499399999994],[-65.23611499999998,62.95777100000004],[-65.24305699999996,62.9616620000001],[-65.24833699999994,62.965828000000045],[-65.25140399999998,62.97054300000008],[-65.25500499999993,62.97971300000012],[-65.25473,62.98526800000002],[-65.26916499999993,62.95999100000006],[-65.19444299999992,62.87887599999999],[-65.19027699999992,62.87526700000001],[-65.17500299999995,62.862495000000024],[-65.15388499999995,62.84693900000002],[-65.14805599999994,62.843323],[-65.129166,62.83638000000002],[-65.11527999999998,62.82888000000008],[-64.98472600000002,62.714157],[-64.97833299999996,62.70471199999997],[-64.94888299999991,62.648604999999975],[-64.964722,62.6336060000001],[-64.98083499999996,62.623604000000114],[-65.06277499999999,62.58749400000005],[-65.07112099999995,62.58443500000004],[-65.087219,62.57888000000014],[-65.11471599999999,62.57166300000006],[-65.14500399999991,62.56582600000007],[-65.18749999999994,62.56221000000005],[-65.19776899999988,62.56304899999998],[-65.20500199999998,62.56610100000012],[-65.212219,62.56999200000001],[-65.22084000000001,62.57833100000005],[-65.28860500000002,62.659988],[-65.29499799999996,62.669441000000006],[-65.29666099999997,62.67416399999996],[-65.29055800000003,62.678878999999995],[-65.27389499999998,62.68526500000013],[-65.26777600000003,62.69026900000006],[-65.26695299999994,62.694435],[-65.27917500000001,62.696654999999964],[-65.321121,62.694435],[-65.32749899999999,62.691658000000075],[-65.32972699999993,62.685546999999985],[-65.32806399999998,62.66610000000014],[-65.33721899999995,62.66666400000008],[-65.34695399999987,62.67582700000008],[-65.35388199999994,62.68443300000001],[-65.35665899999992,62.69499200000007],[-65.33972199999994,62.83749399999999],[-65.39195299999994,62.843605000000025],[-65.43666100000002,62.81944299999998],[-65.56666599999994,62.811661000000015],[-65.57917800000001,62.81193499999995],[-65.60194399999995,62.817772000000105],[-65.60943599999996,62.820831000000055],[-65.61610399999995,62.82471500000008],[-65.74694799999986,62.917770000000075],[-65.90943899999996,62.92582700000003],[-65.93331899999998,62.95582600000006],[-65.910278,62.96776599999998],[-65.839722,63.02082800000005],[-65.83473199999997,63.02638200000007],[-65.833328,63.03138000000007],[-65.83833300000003,63.03333300000003],[-65.84973100000002,63.032767999999976],[-65.86639400000001,63.028602999999976],[-65.92610199999996,63.00833100000011],[-65.94972200000001,62.997772000000055],[-65.95500199999998,62.994155999999975],[-65.95556599999986,62.990829000000076],[-65.94638099999997,62.98304700000011],[-65.94583099999994,62.97887400000013],[-65.95056199999999,62.97582200000005],[-65.96083099999993,62.974433999999974],[-65.97389199999986,62.97387700000007],[-65.987213,62.97470900000013],[-66.01445000000001,62.97887400000013],[-66.03138699999994,62.98471799999999],[-66.03971899999999,62.988602000000014],[-66.05221599999999,62.99665800000008],[-66.14973399999991,63.059990000000084],[-66.15556300000003,63.08138300000002],[-66.16278099999994,63.08998900000012],[-66.17443800000001,63.09638200000006],[-66.26695299999994,63.13082099999997],[-66.27583299999998,63.13388100000003],[-66.28250100000002,63.133331],[-66.287781,63.12971500000009],[-66.291946,63.12526700000012],[-66.29333500000001,63.120543999999995],[-66.291382,63.11610400000012],[-66.206955,63.04083300000008],[-66.19665499999996,63.03166199999998],[-66.18276999999989,63.023604999999975],[-66.12165800000002,63.00110600000005],[-66.10555999999997,62.99388099999999],[-66.098343,62.99027300000006],[-66.091385,62.983604000000014],[-66.08972199999988,62.97860000000003],[-66.09777799999995,62.95249200000006],[-66.10305800000003,62.946655000000135],[-66.10777299999995,62.94387800000004],[-66.11610399999995,62.940544000000045],[-66.13583399999993,62.93665299999998],[-66.14723200000003,62.936104],[-66.15916399999998,62.93665299999998],[-66.16888399999999,62.938881000000094],[-66.19221500000003,62.95443700000004],[-66.22083999999995,62.96943700000003],[-66.28472899999991,62.99027300000006],[-66.29388399999988,62.992767000000015],[-66.34500099999997,62.999161000000015],[-66.35166899999996,62.99860399999994],[-66.366104,62.99249300000008],[-66.37860099999989,62.99249300000008],[-66.39277599999997,62.99499500000013],[-66.40888999999993,63.00193800000011],[-66.44444299999986,63.020546000000024],[-66.46444699999995,63.032211000000075],[-66.51834099999996,63.06526900000006],[-66.525284,63.074715000000026],[-66.551941,63.17943600000001],[-66.62638899999996,63.252220000000136],[-66.64666699999998,63.32638499999996],[-66.63833599999998,63.34027100000014],[-66.63751200000002,63.349998000000085],[-66.63694800000002,63.35833000000008],[-66.63778699999995,63.36277000000007],[-66.64277600000003,63.37248999999997],[-66.65083299999998,63.37499200000008],[-66.65750099999997,63.374435000000005],[-66.66416900000002,63.37165800000008],[-66.73554999999999,63.299438000000066],[-66.73860200000001,63.29415900000009],[-66.74082899999996,63.288048],[-66.74027999999993,63.283607000000075],[-66.73111,63.27471200000002],[-66.72055099999994,63.266388000000006],[-66.68554699999999,63.248046999999985],[-66.67138699999987,63.24276700000013],[-66.64695699999993,63.23915900000003],[-66.63917499999997,63.23610700000012],[-66.60749800000002,63.21027400000014],[-66.60249299999998,63.2052690000001],[-66.600281,63.20082900000011],[-66.558334,63.08721200000002],[-66.53778099999988,62.99804700000004],[-66.54028299999993,62.994155999999975],[-66.54666099999992,62.99137900000011],[-66.55722000000003,62.99193600000001],[-66.67304999999999,63.023048000000074],[-66.68222000000003,63.02638200000007],[-66.76306199999993,63.08305400000006],[-66.76806599999992,63.08776899999992],[-66.77389499999992,63.09638200000006],[-66.77444499999996,63.100548],[-66.778885,63.14360799999997],[-66.78916900000002,63.21138000000002],[-66.80665599999998,63.272491000000116],[-66.80749500000002,63.27332300000006],[-66.81166100000002,63.274437000000034],[-66.82028200000002,63.27332300000006],[-66.82917799999996,63.27166000000011],[-66.83778399999994,63.267769000000044],[-66.84695399999993,63.25750000000005],[-66.84916699999997,63.25138900000013],[-66.84916699999997,63.24554400000005],[-66.84611499999994,63.22971300000006],[-66.84472700000003,63.22665400000011],[-66.837219,63.21804800000001],[-66.82833899999997,63.20916],[-66.81945799999994,63.20027200000004],[-66.81388899999996,63.196098000000006],[-66.80387899999994,63.186378000000104],[-66.80139199999996,63.18249500000013],[-66.79972799999996,63.17749000000009],[-66.79943799999995,63.172492999999974],[-66.80166600000001,63.16638200000011],[-66.80665599999998,63.16054500000013],[-66.81834399999997,63.15415999999993],[-66.835556,63.14916199999993],[-66.84416199999993,63.147217000000126],[-66.85527000000002,63.147217000000126],[-66.86833200000001,63.14888000000008],[-66.87777699999998,63.15193199999999],[-67.01834099999996,63.238883999999985],[-67.02389499999998,63.243050000000096],[-67.02500899999995,63.246658000000025],[-67.02444500000001,63.25027499999999],[-67.023056,63.25277700000004],[-67.006393,63.26221500000008],[-66.971115,63.38971700000002],[-66.97277799999995,63.3949970000001],[-66.97778299999999,63.399719000000005],[-66.98889199999996,63.402489],[-67.01112399999994,63.39999399999999],[-67.01722699999999,63.39721700000007],[-67.04083299999996,63.33554799999996],[-67.03916899999996,63.33055100000007],[-67.03582799999992,63.3252720000001],[-67.02500899999995,63.31110400000006],[-67.01611300000002,63.29666099999997],[-67.01417499999997,63.28638500000005],[-67.01722699999999,63.281105000000025],[-67.03332499999993,63.27526899999992],[-67.05194099999994,63.27332300000006],[-67.171112,63.27388000000013],[-67.17971799999992,63.27555100000001],[-67.20388799999995,63.28527100000008],[-67.431671,63.412765999999976],[-67.49999999999994,63.442764000000125],[-67.62165800000002,63.54888199999999],[-67.68331899999998,63.619438],[-67.83889799999992,63.72971300000012],[-67.89750699999996,63.75305200000014],[-67.91471899999999,63.759438000000046],[-67.92332499999992,63.761108000000036],[-67.92610200000001,63.75916300000006],[-67.92527799999993,63.75471500000009],[-67.92138699999998,63.74443800000006],[-67.91805999999985,63.739159000000086],[-67.82000699999998,63.596382000000006],[-67.710556,63.45860300000004],[-67.68331899999998,63.43166400000007],[-67.675003,63.4180530000001],[-67.67193599999996,63.41249099999999],[-67.66776999999996,63.403046000000074],[-67.66639699999996,63.394439999999975],[-67.66665599999999,63.388046000000145],[-67.67832900000002,63.3730470000001],[-67.685272,63.36888099999999],[-67.69444299999998,63.36638599999998],[-67.71665999999993,63.3638840000001],[-67.72416699999997,63.364159000000086],[-67.737213,63.36638599999998],[-67.74638400000003,63.36943800000006],[-67.82055700000001,63.40026900000004],[-67.827225,63.4052660000001],[-67.83750900000001,63.42416400000002],[-67.854446,63.45277400000003],[-67.858047,63.457497000000046],[-67.87165800000002,63.46471400000013],[-67.95083599999998,63.506660000000124],[-68.02528399999994,63.540832999999964],[-68.03332499999993,63.54388399999999],[-68.041382,63.546104000000014],[-68.05305499999992,63.54527300000001],[-68.06166100000002,63.54332700000009],[-68.07556199999999,63.544159000000036],[-68.36582900000002,63.64527099999998],[-68.38861099999986,63.655548000000124],[-68.40028399999994,63.66387900000001],[-68.40556300000003,63.66860200000002],[-68.42832899999996,63.69638100000003],[-68.54276999999996,63.732490999999925],[-68.6458439999999,63.74749000000003],[-68.71362299999998,63.74249300000008],[-68.70973200000003,63.73804500000011],[-68.71139499999992,63.73471799999999],[-68.71610999999996,63.73220799999996],[-68.72361799999999,63.72971300000012],[-68.795547,63.728600000000085],[-68.80444299999994,63.73027000000002],[-68.87609900000001,63.744713000000104],[-68.91583300000002,63.75721699999997],[-68.92443799999995,63.75888800000001],[-68.96250899999995,63.75916300000006],[-68.99472000000003,63.75555400000002],[-68.99694799999992,63.75360900000004],[-68.99833699999999,63.745270000000005],[-68.99527,63.74137900000011],[-68.98971599999999,63.73749500000008],[-68.97778299999993,63.72971300000012],[-68.93305999999995,63.71193699999998],[-68.91944899999999,63.704994],[-68.82472200000001,63.64388300000007],[-68.81304899999998,63.63555100000008],[-68.80943300000001,63.630821000000026],[-68.80722000000003,63.62582400000014],[-68.80943300000001,63.621658000000025],[-68.79333499999996,63.589157000000114],[-68.76611300000002,63.55665600000003],[-68.75473,63.548607000000004],[-68.71777299999991,63.52860300000009],[-68.55776999999995,63.45249199999995],[-68.49583399999995,63.421378999999945],[-68.35943599999996,63.34471099999996],[-68.28860500000002,63.298332000000016],[-68.27055399999995,63.28499600000009],[-68.20639,63.22721100000001],[-68.20249899999993,63.21693399999998],[-68.20639,63.21249399999999],[-68.18638599999997,63.18832400000014],[-68.156113,63.158324999999934],[-68.146118,63.15026900000004],[-68.13917500000002,63.14860500000003],[-68.128601,63.14804800000013],[-68.11555499999997,63.15248900000006],[-68.08277900000002,63.16360500000002],[-68.06388899999996,63.16360500000002],[-67.95222499999994,63.14554600000008],[-67.92639200000002,63.141106000000036],[-67.91749599999997,63.13721499999997],[-67.91665599999993,63.133049000000085],[-67.92332499999992,63.12943300000006],[-67.91278099999994,63.083327999999995],[-67.64611799999994,63.10027299999996],[-67.632767,63.09887700000013],[-67.610275,63.09415400000012],[-67.60499600000003,63.08998900000012],[-67.59999099999999,63.08443499999993],[-67.59999099999999,63.07888000000003],[-67.601944,63.073326000000066],[-67.61500499999994,63.06360599999999],[-67.62416099999996,63.06110400000006],[-67.636124,63.0597150000001],[-67.68221999999992,63.05777000000012],[-67.68971299999993,63.05804400000005],[-67.70916699999992,63.05665599999992],[-67.71945199999993,63.054993000000024],[-67.72749299999992,63.05165900000003],[-67.77305599999994,63.02582600000005],[-67.77250700000002,62.962212000000136],[-67.76972999999998,62.95832799999994],[-67.76362599999999,62.95555100000007],[-67.74804699999999,62.953049000000135],[-67.73860200000001,62.95332300000007],[-67.72805800000003,62.95499399999994],[-67.72183199999995,62.96265800000009],[-67.718842,62.96449300000006],[-67.71816999999999,62.96732700000007],[-67.71932999999996,62.9704900000001],[-67.72444200000001,62.984161000000086],[-67.72999599999997,62.98832700000014],[-67.73693800000001,62.99554400000011],[-67.73388699999998,63.000832000000116],[-67.69804399999992,63.02082800000005],[-67.68693499999995,63.026657000000114],[-67.65943899999996,63.03416400000003],[-67.56527699999998,63.04943800000012],[-67.55305499999992,63.04860700000012],[-67.52999899999998,63.03694200000001],[-67.510559,63.02471200000008],[-67.49999999999994,63.01554900000008],[-67.49972499999996,63.00777399999998],[-67.50917099999992,63.00193800000011],[-67.531387,62.99526999999995],[-67.55055199999998,62.99193600000001],[-67.57333399999999,62.99027300000006],[-67.593613,62.98749500000008],[-67.63082899999995,62.97637900000012],[-67.65139799999992,62.96749099999994],[-67.670998,62.944323999999995],[-67.671829,62.94132200000013],[-67.67266799999999,62.937996000000055],[-67.672775,62.92332499999998],[-67.66583300000002,62.91888400000005],[-67.65916400000003,62.916664000000026],[-67.654922,62.917282],[-67.64889499999992,62.92110400000007],[-67.64666699999998,62.925270000000125],[-67.63833599999998,62.931938000000116],[-67.57250999999991,62.963882000000126],[-67.566956,62.96554600000013],[-67.47027599999996,62.98526800000002],[-67.462784,62.98526800000002],[-67.39805599999994,62.96720900000008],[-67.19471699999991,62.87027000000006],[-67.04834,62.77137800000014],[-67.01222199999995,62.73443600000013],[-66.95777899999996,62.681107],[-66.91332999999992,62.66999100000004],[-66.82472200000001,62.67916100000008],[-66.81332399999985,62.67999299999997],[-66.741104,62.673882000000106],[-66.73306300000002,62.67166100000003],[-66.726944,62.66860200000002],[-66.72888199999994,62.66610000000014],[-66.735275,62.66249099999993],[-66.74444599999993,62.66027100000014],[-66.752792,62.65693699999997],[-66.760559,62.653602999999976],[-66.76806599999992,62.64887999999996],[-66.77305599999988,62.64305099999996],[-66.77500900000001,62.636940000000095],[-66.77305599999988,62.63249200000013],[-66.60694899999999,62.604996000000085],[-66.42500299999995,62.445267000000115],[-66.35943600000002,62.44748700000014],[-66.35166899999996,62.44499200000013],[-66.34916699999997,62.44137600000005],[-66.32749899999993,62.384438000000046],[-66.33056599999998,62.37915800000002],[-66.33778399999989,62.37499200000008],[-66.42639199999996,62.349433999999974],[-66.43554699999993,62.349158999999986],[-66.45861799999994,62.35193600000008],[-66.46916199999998,62.35193600000008],[-66.47582999999997,62.348602000000085],[-66.478882,62.34332300000011],[-66.478882,62.338325999999995],[-66.47694399999995,62.335823000000005],[-66.47000099999997,62.33221400000002],[-66.37471,62.286110000000065],[-66.32917799999996,62.267494000000056],[-66.31861900000001,62.26471700000013],[-66.35583499999996,62.30777000000006],[-66.35916099999997,62.312492000000134],[-66.36389200000002,62.32305100000002],[-66.36138900000003,62.32694200000009],[-66.35555999999985,62.33194000000009],[-66.351944,62.334991000000116],[-66.33277900000002,62.341934000000094],[-66.3125,62.344993999999986],[-66.29415899999998,62.34471100000002],[-66.285553,62.34360500000014],[-66.2083439999999,62.33221400000002],[-66.16528299999993,62.291382],[-66.16027799999989,62.271378000000084],[-66.16722099999998,62.25443999999999],[-66.20195000000001,62.26055100000008],[-66.25666799999999,62.26610599999998],[-66.26139799999987,62.26305400000007],[-66.25723299999987,62.25972000000007],[-66.241104,62.253326000000015],[-66.2125089999999,62.24527000000012],[-66.16639700000002,62.23526799999996],[-66.08168,62.226379000000065],[-66.05860899999988,62.2241590000001],[-66.051941,62.22470900000013],[-66.04583699999995,62.227486],[-66.04361,62.23360400000013],[-66.03889500000002,62.23943299999996],[-66.03388999999999,62.24499500000013],[-66.02861000000001,62.248604000000114],[-66.02500899999995,62.24971800000009],[-66.01501499999995,62.25138900000013],[-66,62.247772],[-65.99305700000002,62.244155999999975],[-65.939438,62.208602999999925],[-65.93305999999995,62.20416300000011],[-65.92916899999989,62.198044000000095],[-65.93055699999996,62.19332100000008],[-65.93443299999996,62.19165799999996],[-65.95278899999994,62.18915600000008],[-65.96333299999998,62.186935000000005],[-65.96916199999993,62.18471499999998],[-66.04361,62.151657],[-66.05082700000003,62.147774000000084],[-66.13249200000001,62.089432000000045],[-66.11000100000001,62.01749400000011],[-66.041946,61.95804600000008],[-66.03582799999992,61.95277399999998],[-66.03306600000002,61.95249200000012],[-66.019455,61.954994],[-66.00306699999999,61.96221200000002],[-65.99943499999995,61.96305100000012],[-65.99221799999987,61.962769000000094],[-65.98860200000001,61.958885000000066],[-65.949432,61.9124910000001],[-65.94665500000002,61.906936999999914],[-65.94665500000002,61.89916200000005],[-65.94888299999997,61.89527099999998],[-65.95500199999998,61.89027400000003],[-65.96194500000001,61.88638300000014],[-65.97084000000001,61.88388100000009],[-66.05777,61.86971300000005],[-66.066101,61.868599000000074],[-66.27583299999998,61.858330000000024],[-66.287781,61.858330000000024],[-66.39500399999986,61.87082700000002],[-66.404449,61.87276500000013],[-66.52166699999992,61.896942000000024],[-66.54333499999996,61.89888000000013],[-66.55555700000002,61.90138200000001],[-66.62609900000001,61.917213000000004],[-66.632767,61.91888400000005],[-66.65916399999998,61.93360100000007],[-66.66528299999993,61.94137599999999],[-66.662216,61.946655000000135],[-66.74694799999992,62.00777400000004],[-66.75556899999992,62.011108000000036],[-66.78138699999988,62.015549000000135],[-66.80332900000002,62.01693700000004],[-66.81277499999999,62.01666300000011],[-66.82583599999992,62.011940000000095],[-67.091949,62.030823],[-67.10472099999998,62.03221100000013],[-67.25472999999994,62.07804900000008],[-67.3452759999999,62.119437999999946],[-67.46305799999993,62.13943500000005],[-67.49999999999994,62.13865700000014],[-67.73165899999992,62.158356000000026],[-67.75723299999993,62.160544999999956],[-67.79833999999994,62.166100000000085],[-68.00306699999999,62.213882000000126],[-68.11389200000002,62.21610300000003],[-68.2330629999999,62.21971100000013],[-68.256958,62.220825000000104],[-68.26916499999987,62.22304500000013],[-68.29943800000001,62.23220800000013],[-68.32528699999995,62.234993000000145],[-68.40167199999996,62.23943299999996],[-68.46945199999999,62.24276700000013],[-68.51972999999992,62.24471300000005],[-68.54804999999993,62.248604000000114],[-68.56471299999993,62.25193800000011],[-68.61582899999996,62.26388500000007],[-68.72222899999991,62.302216000000044],[-68.72555499999987,62.30471],[-68.72694399999995,62.30777000000006],[-68.75917099999992,62.32804900000002],[-68.88221699999997,62.3605500000001],[-68.92250100000001,62.36554700000005],[-68.99583399999995,62.37332200000009],[-69.03900099999998,62.38135500000004],[-69.12138400000003,62.410820000000115],[-69.16000399999996,62.42527000000007],[-69.19305400000002,62.43804200000005],[-69.23167399999988,62.4552690000001],[-69.270554,62.4783250000001],[-69.36082499999992,62.53638500000005],[-69.40834000000001,62.56999200000001],[-69.43055699999996,62.584160000000054],[-69.42666600000001,62.55443600000001],[-69.42832900000002,62.548332000000016],[-69.44221500000003,62.54749300000003],[-69.44972199999995,62.551102000000014],[-69.51916499999999,62.602493000000095],[-69.58389299999999,62.6519320000001],[-69.59722899999991,62.66249099999993],[-69.59750400000001,62.665268000000026],[-69.56555199999997,62.71804800000007],[-69.55721999999997,62.72637900000001],[-69.54333500000001,62.732765000000086],[-69.52555799999993,62.73804499999994],[-69.50389100000001,62.74137899999994],[-69.48249799999996,62.763611000000026],[-69.72749299999998,62.77999100000011],[-69.90638699999988,62.76859999999999],[-70.12193299999996,62.748878000000104],[-70.21749899999986,62.74777200000011],[-70.22917199999995,62.748878000000104],[-70.24027999999998,62.751389000000074],[-70.35499599999991,62.78832999999997],[-70.36000099999995,62.79027600000006],[-70.36776700000001,62.79388399999999],[-70.47778299999999,62.84832800000004],[-70.49943499999995,62.864441000000056],[-70.50805699999995,62.86582899999996],[-70.66555800000003,62.88054700000009],[-70.83029199999993,62.89666000000011],[-70.85333299999996,62.899994000000106],[-70.88555899999994,62.90721100000002],[-70.896118,62.91443600000008],[-70.89306599999998,62.917770000000075],[-70.88583399999999,62.920547],[-70.87138400000003,62.924713000000054],[-70.86361699999998,62.92555200000004],[-70.848343,62.924713000000054],[-70.84777799999989,62.947212000000036],[-70.97483799999998,62.98943700000001],[-70.97734100000002,62.983768000000055],[-71.01306199999999,62.98999000000009],[-71.06027199999994,62.98110200000008],[-71.07167099999998,62.979431000000034],[-71.12083399999995,62.979431000000034],[-71.13583399999993,62.98082000000005],[-71.152222,62.98526800000002],[-71.15666199999998,62.989159000000086],[-71.15666199999998,62.99943499999995],[-71.13667299999997,63.028602999999976],[-71.11810300000002,63.032219000000055],[-71.09138499999995,63.02999100000005],[-71.02088899999995,63.0442700000001],[-71.01372499999997,63.04360200000002],[-71.00738499999994,63.04343799999998],[-71.00321999999994,63.044768999999974],[-70.86389200000002,63.112213000000054],[-70.85638399999999,63.13943499999999],[-70.90888999999999,63.17083000000008],[-70.92054699999994,63.16888399999999],[-70.95249899999999,63.16276600000003],[-70.97138999999993,63.158882000000006],[-70.97694399999995,63.15665400000006],[-70.99027999999998,63.14804800000013],[-70.99749800000001,63.14166299999994],[-71.00195300000001,63.128044000000045],[-71.002792,63.123322000000144],[-71.00140399999998,63.118881000000044],[-70.99333200000001,63.112770000000125],[-70.99082900000002,63.10833000000014],[-70.98998999999998,63.10249299999998],[-70.993607,63.09804500000001],[-71.02972399999999,63.07193799999999],[-71.041672,63.06944299999992],[-71.12721299999998,63.071663000000115],[-71.13861099999991,63.073326000000066],[-71.19526699999994,63.03166199999998],[-71.195831,63.026657000000114],[-71.19860799999998,63.01998900000012],[-71.208618,63.01166500000005],[-71.23277300000001,63.00193800000011],[-71.24388099999999,63.00110600000005],[-71.25584400000002,63.00193800000011],[-71.26251200000002,63.00416600000011],[-71.40055799999999,63.05165900000003],[-71.40833999999995,63.05526700000013],[-71.41389500000002,63.060546999999985],[-71.42138699999998,63.071663000000115],[-71.45472699999993,63.10193600000008],[-71.465012,63.1033250000001],[-71.60583499999996,63.134995],[-71.62499999999994,63.14083100000005],[-71.70666499999993,63.17499500000008],[-71.71389799999997,63.179161000000136],[-71.77000399999991,63.25638600000002],[-71.79499800000002,63.326660000000004],[-71.79554699999994,63.38472000000007],[-71.80583199999995,63.382767],[-72.00917099999998,63.391106000000036],[-72.06304899999992,63.39638500000001],[-72.07640099999998,63.398048000000074],[-72.08306900000002,63.40054299999997],[-72.14167800000001,63.436104000000114],[-72.146118,63.43998700000003],[-72.145554,63.44609800000012],[-72.12666299999995,63.450271999999984],[-72.023056,63.44804399999998],[-71.93331899999993,63.443321000000026],[-71.82583599999998,63.43526500000013],[-71.785278,63.431938],[-71.74804699999999,63.428047000000106],[-71.71112099999993,63.42276800000013],[-71.68305999999995,63.41971600000005],[-71.63473499999992,63.41971600000005],[-71.61500499999994,63.422493000000145],[-71.59944200000001,63.42582700000014],[-71.41166699999991,63.48582499999998],[-71.31695599999995,63.530823000000055],[-71.22749299999992,63.598877000000016],[-71.22972099999998,63.60471300000006],[-71.23472600000002,63.608047000000056],[-71.24562099999997,63.61093900000009],[-71.261124,63.612495000000024],[-71.29527300000001,63.612495000000024],[-71.30694599999998,63.611381999999935],[-71.32362399999994,63.60527000000013],[-71.32806399999998,63.602218999999934],[-71.33168,63.59832800000004],[-71.33306900000002,63.583603000000096],[-71.33250399999997,63.58166499999999],[-71.32806399999998,63.57694200000003],[-71.32556199999999,63.571938000000046],[-71.32611099999991,63.57054900000003],[-71.33168,63.56554399999999],[-71.3352809999999,63.564437999999996],[-71.37999000000002,63.56554399999999],[-71.40750100000002,63.567771999999934],[-71.41416899999996,63.57054900000003],[-71.41639700000002,63.57276900000005],[-71.37805200000003,63.59526800000003],[-71.36749299999997,63.60193599999997],[-71.36361699999998,63.60721600000005],[-71.362503,63.61332700000014],[-71.37748699999997,63.632767000000115],[-71.39666699999992,63.635826000000066],[-71.40777600000001,63.63555100000008],[-71.41139199999998,63.63443799999999],[-71.41805999999997,63.62999000000002],[-71.45249899999999,63.60443900000013],[-71.441101,63.59082799999999],[-71.439438,63.58804299999997],[-71.44694499999991,63.580826],[-71.45584100000002,63.57888000000014],[-71.47027599999996,63.578049000000135],[-71.56166100000002,63.58027599999997],[-71.57695000000001,63.58166499999999],[-71.58056599999998,63.58387800000014],[-71.58138999999994,63.59304800000001],[-71.583618,63.64971900000012],[-71.569458,63.67555200000004],[-71.56221,63.685546999999985],[-71.58111600000001,63.714995999999985],[-71.58500700000002,63.71665999999999],[-71.6158289999999,63.72221399999995],[-71.62916599999994,63.72387700000007],[-71.63806199999988,63.72109999999998],[-71.66000400000001,63.70694000000009],[-71.66471899999988,63.70304900000002],[-71.66722099999993,63.697212000000036],[-71.70056199999999,63.69638100000003],[-71.82389799999987,63.78054800000001],[-71.83000199999998,63.78443900000008],[-71.89111300000002,63.80832700000002],[-71.904449,63.80998999999997],[-71.91555800000003,63.810272],[-71.93859900000001,63.80804400000005],[-71.95834400000001,63.802490000000034],[-71.97055099999994,63.795830000000024],[-71.98554999999993,63.78193700000003],[-72.000565,63.76138300000002],[-72.00418100000002,63.752776999999924],[-71.99972500000001,63.748328999999956],[-71.991104,63.74610100000001],[-71.972778,63.7480470000001],[-71.966949,63.75110600000005],[-71.95472699999993,63.76527400000009],[-71.94665499999996,63.77027100000004],[-71.93916299999995,63.77249100000006],[-71.93443300000001,63.77276600000005],[-71.853882,63.76138300000002],[-71.84861799999999,63.759438000000046],[-71.843887,63.75555400000002],[-71.87943999999999,63.681937999999946],[-71.88276699999994,63.67804700000005],[-71.92027300000001,63.655548000000124],[-71.93388400000003,63.649437000000034],[-71.96362299999998,63.64916200000005],[-72.05194099999994,63.67860399999995],[-72.15417500000001,63.7355500000001],[-72.16944899999999,63.748604],[-72.21305799999999,63.68387600000011],[-72.21278399999994,63.68055000000004],[-72.21389799999992,63.677772999999945],[-72.218887,63.67388200000005],[-72.22389199999986,63.67221800000004],[-72.23416099999997,63.670273000000066],[-72.24526999999995,63.669715999999994],[-72.28694200000001,63.67166099999997],[-72.31750499999998,63.67416400000013],[-72.32417299999997,63.67665899999997],[-72.32749899999999,63.67971799999998],[-72.36389199999996,63.749435000000005],[-72.36361699999998,63.754440000000045],[-72.35777299999995,63.76138300000002],[-72.35278299999999,63.76527400000009],[-72.34249899999998,63.77137800000014],[-72.32472200000001,63.77693900000003],[-72.31777999999991,63.77777100000009],[-72.30277999999993,63.776657000000114],[-72.29138199999994,63.77360500000003],[-72.27000399999991,63.787216],[-72.215012,63.86776700000007],[-72.20973200000003,63.89305100000007],[-72.223053,63.92943600000001],[-72.2327729999999,63.94832599999995],[-72.23889200000002,63.95249200000006],[-72.24638400000003,63.95027200000004],[-72.25056499999994,63.94776900000005],[-72.36471599999993,63.845543000000134],[-72.38305699999995,63.81554399999993],[-72.37638899999996,63.812209999999936],[-72.37165800000002,63.809158000000025],[-72.36694299999999,63.80471000000006],[-72.36555499999992,63.80027000000007],[-72.36305199999993,63.79110700000007],[-72.36805699999996,63.7824940000001],[-72.372772,63.77860300000003],[-72.43611099999993,63.78166199999998],[-72.51583899999997,63.786384999999996],[-72.52639799999992,63.78777300000007],[-72.531387,63.79110700000007],[-72.53222700000003,63.79666100000003],[-72.531387,63.79943800000012],[-72.51972999999992,63.80471000000006],[-72.49665800000002,63.803604000000064],[-72.47416699999991,63.80471000000006],[-72.46389799999997,63.806655999999975],[-72.45973199999997,63.809158000000025],[-72.45611600000001,63.81443800000011],[-72.456955,63.815826000000015],[-72.46501199999994,63.81916000000001],[-72.52111799999994,63.84027100000003],[-72.537216,63.844154],[-72.585556,63.852776000000006],[-72.63473499999998,63.85249300000004],[-72.63751200000002,63.87360400000006],[-72.64111299999996,63.904434000000094],[-72.61166399999996,63.94304699999998],[-72.59277299999985,64.01805100000013],[-72.59277299999985,64.02221700000007],[-72.6583399999999,64.07666],[-72.66471899999993,64.08055100000007],[-72.67471299999994,64.083328],[-72.68249500000002,64.07971199999997],[-72.68554699999993,64.07638500000002],[-72.68804899999998,64.07054099999999],[-72.70472699999999,64.01554900000008],[-72.70584100000002,64.00915500000002],[-72.70249899999993,64.00555399999996],[-72.69694500000003,64.00305200000008],[-72.66833500000001,63.996101000000124],[-72.66000400000001,63.992493000000024],[-72.658615,63.98777000000007],[-72.66639699999996,63.980545000000006],[-72.67887899999994,63.972488000000055],[-72.69249000000002,63.966660000000104],[-72.69972200000001,63.96443900000003],[-72.72000099999997,63.96110500000003],[-72.75334199999992,64.00027499999999],[-72.75834699999996,64.00416600000005],[-72.779449,64.01054400000004],[-72.83612099999999,64.01971400000008],[-72.93138099999999,64.05247500000002],[-72.94027699999998,64.05859400000003],[-72.94137599999999,64.06359900000007],[-72.93971299999987,64.06776400000007],[-72.93331899999998,64.07638500000002],[-72.92555199999987,64.08415200000013],[-72.91972399999992,64.08692900000005],[-72.91111799999993,64.08859300000006],[-72.88806199999999,64.08610500000009],[-72.87832600000002,64.08665500000012],[-72.874435,64.08859300000006],[-72.87083399999995,64.09387200000003],[-72.86888099999993,64.09915200000012],[-72.86833200000001,64.10832199999999],[-72.89723200000003,64.15693700000003],[-72.90527299999991,64.1649930000001],[-72.91166699999997,64.16886899999997],[-73.22389199999992,64.31164600000011],[-73.27111799999989,64.28387500000002],[-73.26722699999999,64.27388000000013],[-73.27000399999997,64.26582300000013],[-73.273056,64.26249700000011],[-73.27917499999995,64.25860600000004],[-73.33972199999994,64.25804099999999],[-73.36582900000002,64.26193200000006],[-73.38055400000002,64.26860000000005],[-73.38417099999998,64.27249100000012],[-73.3869479999999,64.27748099999997],[-73.4177699999999,64.37109399999991],[-73.41555800000003,64.44581600000004],[-73.32695000000001,64.476089],[-73.16777000000002,64.57666000000012],[-73.16471899999993,64.57971200000003],[-73.16471899999993,64.60554499999995],[-73.16555799999998,64.60748300000012],[-73.16944899999987,64.609985],[-73.29695099999992,64.65693700000008],[-73.30277999999993,64.65887500000002],[-73.30943300000001,64.65860000000004],[-73.34222399999993,64.64415000000008],[-73.34666400000003,64.641098],[-73.34750400000001,64.63499500000006],[-73.34111000000001,64.62608300000005],[-73.32611099999997,64.609985],[-73.31443799999994,64.59803800000003],[-73.308044,64.593323],[-73.30221599999999,64.58387800000008],[-73.29861499999993,64.55941800000011],[-73.29916399999996,64.54498299999995],[-73.30332899999996,64.53831500000001],[-73.30749499999996,64.53581200000002],[-73.31527699999992,64.53221100000013],[-73.32417299999986,64.52998400000007],[-73.42416400000002,64.509995],[-73.46333300000003,64.50248699999997],[-73.47222899999997,64.5044400000001],[-73.47582999999992,64.50804099999993],[-73.47721899999999,64.51220700000005],[-73.473053,64.55358900000004],[-73.44871499999994,64.56542200000001],[-73.46722399999999,64.61276200000009],[-73.59500099999997,64.62969999999996],[-73.65556300000003,64.63165300000009],[-73.65556300000003,64.62359600000013],[-73.66749600000003,64.57720900000004],[-73.7502899999999,64.53637700000007],[-73.75389100000001,64.53526300000004],[-73.76445000000001,64.53749100000005],[-73.78778099999994,64.54803500000008],[-73.80305499999992,64.555252],[-73.821121,64.56749000000008],[-73.837784,64.57971200000003],[-73.84944200000001,64.58749399999999],[-73.86138899999997,64.59443699999997],[-73.87666299999995,64.60081500000013],[-73.88694799999996,64.60359200000005],[-73.91027799999995,64.60582],[-73.92027299999995,64.60525500000011],[-73.92944299999999,64.60220300000003],[-73.93249500000002,64.5935970000001],[-73.931107,64.58387800000008],[-73.84472699999998,64.501938],[-73.92555199999993,64.46026599999993],[-73.97277799999989,64.43026700000013],[-73.99943499999989,64.32804899999996],[-74.06277499999999,64.33442700000012],[-74.10221899999988,64.36747699999995],[-74.12805199999991,64.533051],[-74.12748699999997,64.53442400000012],[-74.10583500000001,64.53581200000002],[-74.08222999999992,64.53498800000006],[-74.06527699999992,64.533051],[-74.05555700000002,64.61053500000003],[-74.05055199999998,64.72499100000005],[-74.05387899999994,64.7285920000001],[-74.06054699999999,64.7333220000001],[-74.089722,64.75109900000001],[-74.09611499999994,64.75138900000002],[-74.11444099999994,64.7458190000001],[-74.120544,64.74192800000003],[-74.19526699999989,64.66304000000002],[-74.20889299999993,64.61415100000005],[-74.212784,64.60276800000008],[-74.22471599999994,64.59248400000001],[-74.24027999999998,64.58027600000014],[-74.38194299999992,64.56999200000013],[-74.390289,64.56971699999991],[-74.39750700000002,64.57222000000007],[-74.535278,64.62220800000006],[-74.65750099999997,64.7002720000001],[-74.70167500000002,64.732483],[-74.7041779999999,64.73553500000008],[-74.70083599999987,64.74026500000014],[-74.68331899999993,64.75833100000011],[-74.56750499999998,64.83276400000005],[-74.50111399999997,64.83360300000004],[-74.48777799999993,64.83415200000002],[-74.478882,64.83581500000008],[-74.47639500000002,64.83888200000001],[-74.47694399999995,64.84165999999999],[-74.54055799999998,64.88916],[-74.54583699999995,64.89221200000009],[-74.56111099999993,64.89610299999998],[-74.62193299999996,64.90386999999993],[-74.63999899999993,64.90359500000011],[-74.64862099999993,64.90138200000013],[-74.66027799999989,64.89637800000003],[-74.73277300000001,64.85470599999996],[-74.74137899999994,64.84748800000011],[-74.74305700000002,64.84220900000014],[-74.74194299999999,64.83581500000008],[-74.73889200000002,64.8313750000001],[-74.72222899999997,64.82222000000002],[-74.71472199999994,64.81553599999995],[-74.71000700000002,64.81053200000002],[-74.70666499999999,64.80053700000008],[-74.70666499999999,64.79498300000012],[-74.71083099999998,64.78276100000011],[-74.71888699999994,64.77360499999998],[-74.72639499999997,64.77082800000011],[-74.837219,64.77859500000005],[-74.86833200000001,64.78193699999997],[-74.89334100000002,64.78471400000006],[-74.90222199999994,64.78804000000008],[-74.90916400000003,64.79136700000004],[-74.91583300000002,64.79582200000004],[-74.92443800000001,64.799149],[-74.94415300000003,64.80358900000004],[-74.95500199999998,64.80442800000014],[-74.97555499999987,64.80137600000006],[-74.98527499999994,64.79582200000004],[-74.98554999999988,64.79026800000008],[-74.98249800000002,64.78526300000004],[-74.978882,64.78137200000015],[-74.96333299999998,64.77360499999998],[-74.83473200000003,64.71638500000012],[-74.73332199999999,64.68553199999997],[-74.69444299999998,64.676376],[-74.67555199999998,64.67025800000005],[-74.66000399999996,64.66387900000001],[-74.61305199999993,64.64027400000003],[-74.54527300000001,64.60220300000003],[-74.512787,64.5836030000001],[-74.47528099999994,64.56137100000001],[-74.47000099999997,64.55747999999994],[-74.47084000000001,64.555542],[-74.51362599999987,64.5333250000001],[-74.52027900000002,64.53221100000013],[-74.58583099999998,64.48027000000008],[-74.68554699999999,64.39193699999998],[-74.68582199999997,64.37109399999991],[-74.79777499999994,64.38081399999999],[-74.974716,64.41609199999999],[-74.98527499999994,64.41886900000009],[-75.01055899999994,64.42997700000012],[-75.05638099999999,64.45220899999998],[-75.14250199999998,64.48332199999999],[-75.174713,64.49275200000005],[-75.18276999999995,64.49247700000006],[-75.18859899999995,64.48942600000004],[-75.1888889999999,64.48332199999999],[-75.18721,64.47360200000008],[-75.18249500000002,64.46832300000011],[-75.17721599999999,64.46470599999998],[-75.15139799999992,64.46026599999993],[-75.14611799999994,64.45721400000002],[-75.14416499999993,64.45304900000002],[-75.15055799999999,64.447205],[-75.15444899999994,64.44470200000006],[-75.19972199999995,64.42804000000007],[-75.20777900000002,64.42776500000002],[-75.21556099999998,64.42886400000003],[-75.22416699999991,64.43220500000007],[-75.29527299999995,64.46665999999999],[-75.32389799999999,64.48193400000008],[-75.33250399999997,64.49081400000011],[-75.34416199999993,64.49914600000011],[-75.34973100000002,64.50221300000004],[-75.38166799999999,64.51361100000003],[-75.40916400000003,64.5227660000001],[-75.47972099999993,64.53915399999994],[-75.49082900000002,64.53970300000009],[-75.56610099999995,64.54998800000004],[-75.66639699999996,64.56387300000011],[-75.693329,64.56999200000013],[-75.70388799999995,64.57276900000005],[-75.72138999999999,64.57916300000005],[-75.73693800000001,64.58610499999998],[-75.74722300000002,64.59443699999997],[-75.76362599999999,64.60498000000013],[-75.77389499999992,64.60832200000004],[-75.79695100000004,64.61219800000015],[-75.82417299999997,64.611649],[-75.84306300000003,64.6077580000001],[-75.84722899999991,64.60443099999998],[-75.837219,64.56137100000001],[-75.82362399999994,64.53581200000002],[-75.818893,64.53082300000005],[-75.80749500000002,64.52526900000004],[-75.729172,64.50305199999997],[-75.64472999999992,64.46887200000003],[-75.63944999999995,64.46527100000003],[-75.63055400000002,64.45721400000002],[-75.63166799999999,64.453598],[-75.63612399999994,64.44914200000005],[-75.641388,64.44802899999996],[-75.69665500000002,64.43942300000009],[-75.70834399999995,64.43775900000003],[-75.72778299999993,64.44247400000006],[-75.74694799999997,64.45304900000002],[-75.76583900000003,64.46527100000003],[-75.77305599999994,64.46748400000013],[-75.87471,64.48692300000005],[-75.89527900000002,64.48803700000002],[-75.90833999999995,64.48719800000003],[-75.92027300000001,64.484421],[-75.92250099999995,64.48109400000004],[-75.910553,64.47831700000012],[-75.87527499999999,64.47387700000013],[-75.85777299999995,64.46804800000007],[-75.72083999999995,64.38333100000006],[-75.71722399999999,64.37970000000001],[-75.718887,64.37441999999999],[-75.72332799999992,64.36970500000012],[-75.726944,64.36720300000002],[-75.83805799999999,64.36914100000001],[-75.86166400000002,64.37109399999991],[-75.95056199999993,64.39915500000001],[-76.04388399999999,64.36831700000005],[-76.25361599999997,64.35775799999999],[-76.26445000000001,64.31915300000003],[-76.214722,64.31498699999997],[-76.20556599999998,64.313309],[-76.19665500000002,64.31080600000007],[-76.18832399999985,64.30693100000008],[-76.18971299999993,64.301376],[-76.19721999999996,64.29693600000013],[-76.20584099999996,64.29470800000001],[-76.30055199999998,64.27886999999998],[-76.48472599999997,64.266663],[-76.493607,64.26860000000005],[-76.50306699999999,64.2752690000001],[-76.50695799999994,64.284424],[-76.50556899999992,64.289154],[-76.50361599999991,64.29109199999994],[-76.50250199999994,64.29525800000005],[-76.50666799999993,64.29748500000011],[-76.541382,64.30470300000007],[-76.591949,64.31053199999991],[-76.70584099999996,64.30081200000001],[-76.71945199999993,64.29664600000012],[-76.73388699999987,64.29054300000001],[-76.73666400000002,64.28581200000008],[-76.73889200000002,64.27638200000001],[-76.72166399999998,64.23831200000006],[-76.714722,64.23387099999997],[-76.70611599999995,64.23136900000009],[-76.68472299999996,64.22776800000003],[-76.67443800000001,64.22499099999993],[-76.66722099999993,64.22192400000006],[-76.660278,64.218323],[-76.65472399999993,64.20915200000002],[-76.65472399999993,64.19664000000006],[-76.65834000000001,64.18997200000007],[-76.66221599999994,64.18664600000005],[-76.67054699999994,64.18414300000006],[-76.84722899999997,64.23054500000012],[-76.9683379999999,64.25972000000002],[-77.13833599999998,64.28942900000004],[-77.27610800000002,64.2563780000001],[-77.29611199999994,64.25193800000005],[-77.32749899999999,64.24636799999996],[-77.351944,64.24386600000008],[-77.366104,64.24386600000008],[-77.37999000000002,64.2452550000001],[-77.38137799999998,64.246643],[-77.38221699999997,64.2494200000001],[-77.38137799999998,64.253601],[-77.37887599999993,64.25694300000009],[-77.43415800000002,64.320267],[-77.58833299999998,64.36831700000005],[-77.65222199999994,64.38804600000009],[-77.660278,64.38638300000002],[-77.664444,64.3836060000001],[-77.6658329999999,64.37692300000015],[-77.66471899999999,64.37414600000005],[-77.65888999999999,64.36499000000009],[-77.67971799999998,64.32110599999999],[-77.74722299999996,64.33776900000004],[-77.83138999999994,64.41249099999999],[-77.97027600000001,64.45443699999993],[-78.17805499999997,64.56749000000008],[-78.18331899999993,64.57249500000012],[-78.16857899999997,64.62619799999993],[-78.160553,64.69053600000007],[-78.18443300000001,64.73109399999998],[-78.07362399999994,64.81359900000012],[-78.064438,64.84942600000005],[-78.06527699999987,64.85359199999999],[-78.06639100000001,64.85582000000011],[-78.07362399999994,64.859421],[-78.10249299999998,64.86886600000003],[-78.11721799999992,64.876083],[-78.120834,64.88108800000003],[-78.12971500000003,64.89387500000004],[-78.146118,64.938309],[-78.148056,64.94386299999996],[-78.14973399999997,64.95220900000004],[-78.14527900000002,64.95748900000012],[-77.973053,65.04136699999998],[-77.67971799999998,65.12330600000001],[-77.54361,65.1397090000001],[-77.50306699999993,65.138596],[-77.48832699999991,65.13943499999993],[-77.47972099999998,65.14109800000006],[-77.34472699999998,65.17330900000013],[-77.32861299999996,65.17886400000003],[-77.32278399999996,65.18331900000004],[-77.31582599999996,65.19053600000001],[-77.31304899999998,65.19581600000004],[-77.31555200000003,65.1994170000001],[-77.3824919999999,65.2474820000001],[-77.39723200000003,65.25499000000013],[-77.42277499999994,65.26443500000005],[-77.44471699999991,65.27554300000003],[-77.49804699999999,65.30664100000001],[-77.51306199999993,65.31887799999998],[-77.515015,65.32582099999996],[-77.51222200000001,65.33055100000001],[-77.471115,65.37136800000002],[-77.466949,65.37525900000009],[-77.46112099999988,65.37914999999998],[-77.45249899999988,65.38081399999999],[-77.43804899999992,65.37970000000001],[-77.41361999999998,65.37164300000006],[-77.40249599999999,65.36914100000013],[-77.3458399999999,65.35859700000009],[-77.337784,65.35748300000012],[-77.32305899999994,65.35775799999993],[-77.30610699999994,65.35971100000006],[-77.295547,65.36192299999993],[-77.29194599999994,65.36387600000006],[-77.28750599999995,65.367752],[-77.287216,65.37525900000009],[-77.28999299999992,65.37886000000015],[-77.29527300000001,65.38333100000006],[-77.319458,65.393326],[-77.32695000000001,65.39553800000004],[-77.341949,65.40165700000006],[-77.36749299999991,65.4124910000001],[-77.39862099999993,65.42665100000005],[-77.42027299999995,65.43997200000001],[-77.42832900000002,65.44775400000015],[-77.43443299999996,65.45694000000009],[-77.43055699999991,65.45887800000003],[-77.42166099999997,65.46138000000008],[-77.385559,65.46804800000007],[-77.33667000000003,65.47137500000002],[-77.26528899999988,65.47192399999994],[-77.23805199999993,65.46943700000008],[-77.154449,65.44581599999998],[-77.13473499999998,65.43942300000003],[-77.12443499999989,65.434143],[-77.11582899999996,65.42970300000013],[-77.11166399999996,65.426086],[-77.11111499999993,65.42137100000014],[-77.10638399999999,65.41360500000008],[-77.09944200000001,65.40914900000001],[-77.08666999999997,65.40721100000007],[-76.962784,65.40721100000007],[-76.956955,65.41053799999997],[-76.95249899999999,65.41499300000004],[-76.95611600000001,65.42137100000014],[-76.95556599999998,65.42275999999998],[-76.95167500000002,65.42526200000003],[-76.94444299999998,65.42776500000002],[-76.920837,65.42942800000014],[-76.84999099999999,65.42831399999994],[-76.82472200000001,65.42526200000003],[-76.62693799999994,65.39888000000013],[-76.36193799999995,65.34220900000003],[-76.23500100000001,65.31275900000014],[-76.164444,65.29609700000015],[-76.07250999999991,65.27720599999992],[-75.96665999999999,65.25582900000012],[-75.953888,65.25526400000007],[-75.92527799999993,65.25721700000003],[-75.92027300000001,65.258331],[-75.91221599999994,65.25721700000003],[-75.89834599999995,65.25387599999999],[-75.80555699999996,65.22970599999996],[-75.78555299999994,65.22442600000011],[-75.76916499999999,65.21887200000009],[-75.76501499999989,65.21666000000005],[-75.76000999999991,65.21081500000014],[-75.741379,65.17387400000001],[-75.73998999999992,65.16832],[-75.57084700000001,65.12081899999993],[-75.52861000000001,65.10887100000008],[-75.47500600000001,65.08610500000009],[-75.46665999999999,65.08221400000002],[-75.45722999999992,65.07470700000005],[-75.44694500000003,65.06581100000011],[-75.42805499999997,65.04832499999998],[-75.42443800000001,65.04386900000009],[-75.41055299999994,65.0247040000001],[-75.41555799999998,64.97747800000008],[-75.42027300000001,64.97221400000006],[-75.42805499999997,64.968323],[-75.49694799999997,64.94053600000007],[-75.50723299999999,64.938309],[-75.51916499999993,64.93691999999999],[-75.53361499999994,64.93691999999999],[-75.55722000000003,64.94026200000013],[-75.63473499999992,64.94720500000011],[-75.65444899999994,64.94636500000007],[-75.66305499999993,64.9452510000001],[-75.66749600000003,64.94081100000005],[-75.601944,64.86775200000005],[-75.59416199999998,64.86025999999993],[-75.5875089999999,64.85664400000007],[-75.56806899999998,64.85054000000002],[-75.55555700000002,64.84860200000008],[-75.46139499999992,64.811646],[-75.38917500000002,64.73609900000002],[-75.37304699999999,64.7149960000001],[-75.31666599999994,64.71943700000003],[-75.30833399999989,64.72109999999998],[-75.29818699999998,64.72576900000013],[-75.29472399999997,64.72804300000013],[-75.29138199999989,64.73387100000008],[-75.289444,64.73997500000007],[-75.29138199999989,64.74443100000002],[-75.30221599999993,64.75109900000001],[-75.31054699999993,64.75499000000008],[-75.32972699999999,64.76110799999998],[-75.33389299999999,64.76332100000013],[-75.34416199999993,64.77221700000007],[-75.37388599999991,64.83305400000012],[-75.35722399999992,64.8977660000001],[-75.422775,64.89027399999998],[-75.45167500000002,64.87525900000003],[-75.46083099999998,64.87164300000012],[-75.46972700000003,64.86943100000008],[-75.55749499999996,64.87414600000011],[-75.56332399999997,64.87719700000014],[-75.56555200000003,64.87942500000008],[-75.56750499999998,64.88360599999999],[-75.56527699999998,64.88693200000006],[-75.47389199999992,64.93580600000001],[-75.390289,64.97943099999998],[-75.38473499999998,64.98193400000014],[-75.3760989999999,64.98332200000004],[-75.36305199999998,64.98414600000001],[-75.35333299999996,64.98359700000009],[-75.34416199999993,64.9810940000001],[-75.335556,64.97776800000008],[-75.26417500000002,64.96609500000005],[-75.19610599999999,65.06860400000011],[-75.18916300000001,65.07971200000009],[-75.18554699999987,65.09136999999993],[-75.18693499999995,65.101654],[-75.19249000000002,65.10554500000006],[-75.19665500000002,65.10720799999996],[-75.21250899999995,65.10942100000011],[-75.22555499999999,65.10942100000011],[-75.24082899999996,65.10832199999993],[-75.25917099999998,65.10220300000009],[-75.26362599999999,65.0977630000001],[-75.26556399999993,65.09165999999999],[-75.26251200000002,65.08055100000007],[-75.26000999999985,65.07276900000011],[-75.261124,65.05914299999995],[-75.26306199999993,65.05219999999997],[-75.27999899999998,65.03526299999999],[-75.29972799999996,65.0247040000001],[-75.34861799999993,65.00387600000005],[-75.36000100000001,65.00387600000005],[-75.36749299999997,65.0063780000001],[-75.37304699999999,65.00943000000001],[-75.37887599999999,65.01666300000005],[-75.379166,65.02137800000008],[-75.38110399999994,65.02581800000007],[-75.40249599999987,65.0558170000001],[-75.41000399999996,65.063873],[-75.42555199999998,65.07720899999993],[-75.44137599999999,65.089157],[-75.44804399999998,65.09414700000002],[-75.51640299999985,65.138596],[-75.72805800000003,65.22415199999995],[-75.76194799999996,65.23776200000003],[-75.78167699999995,65.24304200000012],[-75.835556,65.25526400000007],[-75.86416600000001,65.258331],[-75.89056399999998,65.26915000000008],[-75.93971299999998,65.29248000000001],[-75.94387799999998,65.29525799999999],[-75.95083599999998,65.3163760000001],[-75.950287,65.31832900000006],[-75.941101,65.32138099999997],[-75.93110699999988,65.32222000000013],[-75.904449,65.32222000000013],[-75.87388599999991,65.3205410000001],[-75.85777299999995,65.31915300000003],[-75.60305799999998,65.29553199999992],[-75.59222399999993,65.28720100000004],[-75.57556199999993,65.27804600000002],[-75.5663909999999,65.27499400000005],[-75.55526700000001,65.27360500000009],[-75.495834,65.26915000000008],[-75.48443599999996,65.26832600000012],[-75.21194500000001,65.25054900000003],[-75.18666100000002,65.25193800000005],[-75.153885,65.25694300000009],[-75.114441,65.26638799999995],[-75.10166900000002,65.27137800000003],[-75.09388699999994,65.27499400000005],[-75.083618,65.28610200000008],[-75.08167999999989,65.29220600000008],[-75.07084700000001,65.33027600000003],[-75.09083599999991,65.355545],[-75.10916099999986,65.37997400000012],[-75.11082499999998,65.38472000000007],[-75.11111499999998,65.38888500000007],[-75.11054999999993,65.391098],[-75.10804699999994,65.39305100000013],[-75.097778,65.39498900000007],[-75.08277899999996,65.39498900000007],[-74.82362399999994,65.37747200000007],[-74.660553,65.34637499999997],[-74.64584400000001,65.3413700000001],[-74.63500999999997,65.338593],[-74.62416100000002,65.33665500000006],[-74.58944699999995,65.33248900000012],[-74.54666099999992,65.33137499999998],[-74.52444500000001,65.33332800000011],[-74.508621,65.33665500000006],[-74.49694799999997,65.34082000000006],[-74.35777300000001,65.39860499999998],[-74.34783899999996,65.40718100000004],[-74.32389799999999,65.43775900000003],[-74.31889299999995,65.447205],[-74.31527699999998,65.45803799999999],[-74.31138599999991,65.46388200000001],[-74.18277,65.52526900000004],[-74.10583500000001,65.53498800000006],[-73.84527600000001,65.53221100000013],[-73.791382,65.524429],[-73.76777600000003,65.52082800000011],[-73.74722299999996,65.51748700000007],[-73.73693799999995,65.5147090000001],[-73.73277299999995,65.511932],[-73.73138399999993,65.50694300000004],[-73.73083500000001,65.50416600000011],[-73.73500100000001,65.50166299999995],[-73.74027999999998,65.49693300000013],[-73.74082900000002,65.49081400000011],[-73.73693799999995,65.48776199999998],[-73.71167000000003,65.47109999999998],[-73.70306399999993,65.4669340000001],[-73.69415299999991,65.46443200000004],[-73.66389500000002,65.45694000000009],[-73.65139799999997,65.45471199999992],[-73.64111300000002,65.45526100000006],[-73.5599979999999,65.46249400000005],[-73.50056499999994,65.47442600000005],[-73.56361400000003,65.56219499999997],[-73.61833200000001,65.61970500000007],[-73.66221599999994,65.65859999999998],[-73.68415799999991,65.71527100000009],[-73.68499799999995,65.730545],[-73.70472699999993,65.75804100000005],[-73.70973199999992,65.762497],[-73.72055099999989,65.76944000000015],[-73.81082199999997,65.81109600000013],[-73.84111000000001,65.81999200000007],[-73.88417099999998,65.82193000000001],[-73.886124,65.82138100000003],[-73.92361499999998,65.82443200000006],[-73.93167099999994,65.82554600000003],[-73.94249000000002,65.82832300000013],[-74.01194799999996,65.85470599999991],[-74.02917499999995,65.86192300000005],[-74.05804399999994,65.87553400000002],[-74.12943999999999,65.92469799999998],[-74.258896,66.00166300000006],[-74.29695099999998,66.01832600000012],[-74.337784,66.03665200000012],[-74.37388599999997,66.05386399999998],[-74.38806199999993,66.06164600000011],[-74.42555199999993,66.08471700000013],[-74.44499200000001,66.09693900000008],[-74.45556599999986,66.10582000000005],[-74.47138999999999,66.12719700000008],[-74.47277799999995,66.13304100000005],[-74.47250400000001,66.13916000000012],[-74.47000099999997,66.14582800000005],[-74.46611000000001,66.1519320000001],[-74.44665500000002,66.1685940000001],[-74.43443299999996,66.178314],[-74.406113,66.19581600000004],[-74.36665299999993,66.21415700000006],[-74.34222399999999,66.22526600000009],[-74.31639099999995,66.23525999999993],[-74.30665599999998,66.238876],[-74.18721,66.26971399999996],[-74.07778899999994,66.30081200000001],[-73.86082499999992,66.38832100000008],[-73.74499500000002,66.43775900000003],[-73.66610700000001,66.47192400000012],[-73.60665899999998,66.49525499999999],[-73.52999899999998,66.52276600000005],[-73.460556,66.54443400000014],[-73.44415300000003,66.55108600000005],[-73.43055699999991,66.55831900000004],[-73.42027299999995,66.57165500000002],[-73.41833500000001,66.57971199999997],[-73.41833500000001,66.58471700000001],[-73.41639699999996,66.58998100000002],[-73.40028399999994,66.61164900000011],[-73.39695699999999,66.61554000000001],[-73.37971499999998,66.63247700000005],[-73.351944,66.64999400000005],[-73.32833900000003,66.6602630000001],[-73.29638699999998,66.66581700000006],[-73.26722699999999,66.6727600000001],[-73.10861199999994,66.72331199999996],[-73.00111400000003,66.81553600000012],[-72.87388599999997,66.93193099999996],[-72.85249299999998,66.9685970000001],[-72.837784,66.99803199999997],[-72.83138999999989,67.01332100000008],[-72.83111599999995,67.01832600000012],[-72.82806399999993,67.02499400000005],[-72.82417299999997,67.0294340000001],[-72.80665599999992,67.03720100000004],[-72.79167199999995,67.04332000000005],[-72.73889199999991,67.06303400000002],[-72.71665999999993,67.06860400000005],[-72.68499799999995,67.076096],[-72.62609900000001,67.08471700000013],[-72.55082700000003,67.082764],[-72.52583299999998,67.08332800000011],[-72.46417200000002,67.08998100000008],[-72.43110699999994,67.09609999999992],[-72.39944500000001,67.10359200000005],[-72.368607,67.11248799999998],[-72.35139499999997,67.11970500000012],[-72.337784,67.12637300000006],[-72.31555200000003,67.1394350000001],[-72.28250100000002,67.16110200000014],[-72.27610800000002,67.16693099999998],[-72.2583469999999,67.24803199999991],[-72.28694200000001,67.29081700000006],[-72.36361699999998,67.353317],[-72.43638599999991,67.47221400000012],[-72.48111,67.609711],[-72.48582499999992,67.62303199999997],[-72.49082900000002,67.62831100000011],[-72.49749799999995,67.63304099999993],[-72.508896,67.63638300000008],[-72.597778,67.6397090000001],[-72.66639699999996,67.68414300000006],[-72.67639199999996,67.69386299999996],[-72.67777999999998,67.69941699999998],[-72.67500299999995,67.70526099999995],[-72.66888399999993,67.71054100000003],[-72.66166699999991,67.71470600000004],[-72.61389200000002,67.73525999999998],[-72.59695399999993,67.740814],[-72.59194899999989,67.74331699999999],[-72.58332799999988,67.75027499999999],[-72.60888699999998,67.78581200000008],[-72.612503,67.79026800000003],[-72.61944599999993,67.79470800000001],[-72.73500100000001,67.84165999999993],[-72.82000700000003,67.85108900000012],[-72.833328,67.84999100000005],[-72.84388699999994,67.85081500000001],[-72.84805299999994,67.8535920000001],[-72.94221500000003,67.92526200000009],[-72.94444299999998,67.92804000000007],[-72.94499200000001,67.93081699999999],[-72.94387799999987,67.93775900000009],[-72.94249000000002,67.94108599999998],[-72.92999299999997,67.94886799999995],[-72.92277499999994,67.95277400000003],[-72.90417500000001,67.95971700000001],[-72.90249599999993,67.96388200000001],[-72.89611799999994,68.01416],[-72.910553,68.05415300000004],[-72.91389500000002,68.06080600000001],[-72.94110099999995,68.07832300000007],[-72.956955,68.09498600000012],[-72.98111,68.13916000000006],[-72.99276700000001,68.19859300000007],[-72.99388099999999,68.21220400000004],[-73.16111799999999,68.22886699999992],[-73.19027699999992,68.24887100000007],[-73.189438,68.25471500000003],[-73.18998699999992,68.25943000000007],[-73.19471699999997,68.26527400000009],[-73.20083599999998,68.26971400000014],[-73.21556099999992,68.27276600000005],[-73.27111799999989,68.28193699999997],[-73.30332899999996,68.27843499999994],[-73.31449900000001,68.27843499999994],[-73.33667000000003,68.27560400000004],[-73.355186,68.26783],[-73.395554,68.25860599999993],[-73.49610899999993,68.27554299999997],[-73.41000400000001,68.31080600000013],[-73.39916999999997,68.31498700000003],[-73.35467499999993,68.32921599999997]],[[-124.43055699999996,73.8785860000001],[-124.45028699999995,73.8785860000001],[-124.46721600000001,73.8808140000001],[-124.515289,73.89498900000001],[-124.53666699999991,73.90248099999991],[-124.546112,73.90664700000002],[-124.55055199999998,73.91220100000004],[-124.55277999999993,73.91693100000003],[-124.53056299999997,73.91748000000001],[-124.5133439999999,73.91665600000005],[-124.43250299999994,73.91276600000003],[-124.42027300000001,73.90914900000007],[-124.41583300000002,73.90498400000007],[-124.40888999999993,73.90026900000004],[-124.40943899999996,73.89332600000006],[-124.42027300000001,73.882477],[-124.43055699999996,73.8785860000001]],[[-99.80455799999993,73.8890990000001],[-99.73277300000001,73.8499910000001],[-99.71362299999987,73.84637500000002],[-99.58972199999988,73.8377690000001],[-99.53138699999994,73.83194000000009],[-99.49388099999999,73.82582100000008],[-99.48028599999998,73.82193000000001],[-99.2350009999999,73.73776199999992],[-99.115005,73.74859600000002],[-98.97193900000002,73.75054899999992],[-98.82917799999996,73.75166300000012],[-98.756393,73.75610400000005],[-98.71665999999999,73.76666300000005],[-98.68832399999997,73.77201800000012],[-98.641953,73.77720600000004],[-98.51444999999995,73.78749099999999],[-98.42443799999995,73.7935940000001],[-98.29083299999996,73.80165100000005],[-98.20722999999992,73.80525200000011],[-98.19055200000003,73.80358899999999],[-98.17999299999991,73.80415299999993],[-98.13417099999987,73.80970800000006],[-98.09500099999997,73.81553600000012],[-98.07167099999992,73.81944300000009],[-97.976944,73.84275800000006],[-97.96028100000001,73.84693899999996],[-97.94833399999999,73.851654],[-97.9430539999999,73.85693400000008],[-97.94276399999995,73.86276200000003],[-97.94137599999999,73.86804200000006],[-97.93638599999991,73.87831100000011],[-97.91833500000001,73.89027399999998],[-97.90834000000001,73.89471400000014],[-97.88751200000002,73.899429],[-97.80526700000001,73.91110200000003],[-97.78805499999999,73.91276600000003],[-97.76194800000002,73.911926],[-97.58195499999994,73.89387500000004],[-97.56277499999999,73.89082300000007],[-97.54472399999992,73.88610800000004],[-97.52917500000001,73.87970000000007],[-97.52084400000001,73.87387100000007],[-97.51417500000002,73.86775200000005],[-97.50028999999995,73.86192300000005],[-97.47138999999999,73.85775800000005],[-97.456955,73.85775800000005],[-97.39973399999991,73.85887100000014],[-97.35777299999995,73.8624880000001],[-97.34584000000001,73.86499000000015],[-97.32749899999999,73.86581400000011],[-97.26028400000001,73.8602600000001],[-97.22361799999993,73.85636900000003],[-96.97250400000001,73.74414100000001],[-96.96221899999989,73.73858600000011],[-96.95584100000002,73.73248299999995],[-96.93721,73.70359800000011],[-96.93277,73.69220000000007],[-96.93472300000002,73.68692000000004],[-96.96389799999997,73.63998399999997],[-96.968613,73.633331],[-96.98889199999996,73.62469500000009],[-97.00195300000001,73.6202550000001],[-97.18499800000001,73.56219499999997],[-97.20249899999993,73.55720500000012],[-97.43611099999993,73.52554299999997],[-97.62388599999986,73.53887900000012],[-97.63806199999993,73.53858900000012],[-97.64111299999996,73.53359999999992],[-97.66833500000001,73.48332199999999],[-97.66749600000003,73.47943100000009],[-97.66305499999993,73.4727630000001],[-97.65472399999993,73.4669340000001],[-97.63833599999998,73.4602660000001],[-97.62332199999997,73.45637500000004],[-97.60722399999997,73.45471199999997],[-97.579453,73.45498700000013],[-97.56277499999999,73.45915200000013],[-97.53416399999998,73.47387700000007],[-97.52223200000003,73.4785920000001],[-97.50389100000001,73.48304699999994],[-97.43721,73.49192800000009],[-97.41722099999998,73.49331700000005],[-97.401947,73.49304200000006],[-97.23222399999992,73.47442600000005],[-97.19721999999996,73.46971100000002],[-97.18305999999995,73.46499599999999],[-97.17222599999997,73.4602660000001],[-97.16610699999995,73.454163],[-97.15722699999992,73.39553800000004],[-97.150284,73.38998400000003],[-97.16944899999999,73.35664399999996],[-97.17193599999996,73.35276800000008],[-97.18388399999992,73.35054000000014],[-97.20750399999997,73.3483280000001],[-97.2369379999999,73.34860200000003],[-97.24305700000002,73.35470600000002],[-97.37554899999992,73.34721400000012],[-97.64500399999986,73.31805400000002],[-97.660278,73.3160860000001],[-97.70861799999994,73.30470300000007],[-97.84138499999989,73.27331500000008],[-97.84445199999999,73.26832600000012],[-97.84805299999994,73.2544400000001],[-97.847778,73.24942000000004],[-97.84861799999999,73.24498000000006],[-97.86250299999989,73.23387100000014],[-97.983612,73.1810910000001],[-98.02917500000001,73.16526800000008],[-98.07667499999997,73.15138200000013],[-98.112503,73.14248700000007],[-98.15167200000002,73.13108799999998],[-98.202789,73.11053500000008],[-98.22277799999995,73.09999100000005],[-98.22999600000003,73.09082000000012],[-98.23138399999988,73.08554100000015],[-98.23500100000001,73.07971199999992],[-98.24082900000002,73.0752720000001],[-98.319458,73.05053700000008],[-98.36582900000002,73.03776600000015],[-98.450287,73.02026400000011],[-98.45916699999992,72.99331699999999],[-98.45361300000002,72.89860500000009],[-98.45056199999999,72.8749850000001],[-98.445831,72.86581400000011],[-98.43859899999995,72.86053500000014],[-98.42805499999992,72.85609400000004],[-98.41999800000002,72.85859700000003],[-98.41332999999997,72.86415100000005],[-98.40333599999997,72.88136300000002],[-98.40333599999997,72.88720700000005],[-98.40583800000002,72.891663],[-98.402222,72.89749100000006],[-98.39778099999995,72.90277100000014],[-98.38806199999999,72.90803499999993],[-98.26640299999985,72.97276300000004],[-98.25500499999993,72.97747800000008],[-98.22721899999988,72.98748799999998],[-98.176941,72.99859600000013],[-97.99499499999996,73.0374910000001],[-97.98055999999997,73.03970299999997],[-97.86416600000001,73.04748500000011],[-97.84695399999998,73.04859899999991],[-97.68443300000001,73.03305100000011],[-97.66833500000001,73.03137200000009],[-97.52749599999999,73.01138300000014],[-97.44248999999996,72.999146],[-97.29972800000002,72.96971100000013],[-97.28332499999999,72.96388200000007],[-97.22972099999998,72.943039],[-97.22500600000001,72.93997200000013],[-97.25805699999995,72.88360599999999],[-97.26640299999997,72.87858599999998],[-97.265289,72.84887700000013],[-97.20361300000002,72.82582100000008],[-97.08167999999995,72.77998400000007],[-97.03028899999998,72.74136400000009],[-97.023056,72.73220800000013],[-97.023056,72.72720300000009],[-97.02972399999999,72.71665999999993],[-97.079453,72.70193499999999],[-97.10583499999996,72.69636500000013],[-97.13444499999991,72.68830900000006],[-97.16111799999999,72.67804000000001],[-97.17054699999989,72.67359900000008],[-97.17944299999999,72.66748000000007],[-97.18305999999995,72.66192600000005],[-97.19027699999998,72.64054900000002],[-97.19833399999993,72.609985],[-97.19665500000002,72.60443099999998],[-97.185272,72.6019290000001],[-97.16555799999992,72.60165400000011],[-97.09056099999998,72.60525499999994],[-97.08100899999994,72.60592700000012],[-97.07028200000002,72.60859700000009],[-97.04277000000002,72.62330600000013],[-97.03582799999998,72.62886000000015],[-97.00556899999987,72.64471400000002],[-96.98222399999997,72.65525800000012],[-96.96888699999994,72.66026299999999],[-96.91555800000003,72.67858899999999],[-96.61193800000001,72.74693300000007],[-96.51750199999992,72.71470600000009],[-96.52194199999991,72.67442300000005],[-96.45973199999992,72.6077580000001],[-96.40527299999997,72.55941800000011],[-96.37471,72.53442400000012],[-96.33694500000001,72.50082400000002],[-96.32556199999999,72.48831200000006],[-96.30221599999993,72.43386800000002],[-96.29750100000001,72.42164600000001],[-96.29833999999994,72.415817],[-96.53860500000002,72.34332300000005],[-96.66833500000001,72.309708],[-96.69694500000003,72.31053199999997],[-96.73889200000002,72.32110599999999],[-96.77639799999997,72.32331800000003],[-96.83139,72.32360800000004],[-96.86833200000001,72.32193000000012],[-96.87193299999996,72.32110599999999],[-96.86444099999994,72.31776400000007],[-96.771118,72.29887400000007],[-96.66888399999988,72.27915999999999],[-96.57833900000003,72.278595],[-96.56111099999998,72.27554300000003],[-96.554169,72.26388500000002],[-96.48721299999988,72.13610800000004],[-96.48500100000001,72.129974],[-96.48306299999996,72.11303700000002],[-96.487503,72.101654],[-96.49833699999994,72.09027099999997],[-96.50834699999996,72.08499100000012],[-96.52111799999994,72.07998700000013],[-96.537216,72.07499700000011],[-96.55722000000003,72.07193000000001],[-96.72166399999992,72.05276500000002],[-96.77305599999994,72.05304000000007],[-96.789444,72.05220000000003],[-96.86694299999999,72.04109199999999],[-96.853882,72.03637699999996],[-96.828888,72.030823],[-96.67250100000001,72.01277199999998],[-96.63500999999997,72.01388500000007],[-96.61805700000002,72.018326],[-96.60916099999992,72.02415500000001],[-96.60055499999999,72.02777100000003],[-96.56777999999997,72.03360000000009],[-96.52111799999994,72.03887900000007],[-96.50195300000001,72.03858900000006],[-96.48860199999996,72.034988],[-96.48999000000003,72.018326],[-96.49082900000002,72.01220699999999],[-96.49305699999996,72.00109899999995],[-96.502228,71.97554000000014],[-96.50584399999997,71.96971100000013],[-96.51278699999989,71.96443199999999],[-96.52250699999996,71.95915200000007],[-96.55444299999994,71.949142],[-96.56555200000003,71.94693000000012],[-96.57389799999999,71.94831800000003],[-96.589447,71.95443700000004],[-96.60278299999999,71.9580380000001],[-96.61749299999991,71.95999100000006],[-96.63833599999998,71.95748899999995],[-96.73332199999993,71.92886399999998],[-96.74916099999996,71.92387400000007],[-96.76194799999996,71.91859400000004],[-96.76445000000001,71.91499299999998],[-96.76139799999993,71.90971400000001],[-96.74972500000001,71.90304600000002],[-96.73638900000003,71.89942900000005],[-96.72416699999997,71.89860500000009],[-96.70083599999992,71.8999940000001],[-96.64527899999996,71.91748000000001],[-96.60722399999997,71.92692599999998],[-96.56555200000003,71.93220500000001],[-96.52278100000001,71.93441800000011],[-96.50917099999992,71.93304400000011],[-96.50389099999995,71.93165600000003],[-96.49166899999989,71.92608599999994],[-96.49110399999995,71.91943400000008],[-96.49305699999996,71.914154],[-96.52583299999998,71.86886600000008],[-96.55776999999995,71.82943699999998],[-96.5708469999999,71.81944299999998],[-96.57972699999993,71.81498700000003],[-96.591949,71.81080599999996],[-96.61332700000003,71.80720500000012],[-96.72666899999996,71.79359399999993],[-96.74472000000003,71.79220600000002],[-96.73805199999998,71.824997],[-96.79138199999994,71.82777400000003],[-96.983612,71.77581799999996],[-97.01306199999999,71.74914600000005],[-97.08416699999992,71.7002720000001],[-97.16500899999994,71.67553700000008],[-97.21000699999996,71.66360500000008],[-97.43443300000001,71.617752],[-97.47055099999994,71.61248799999998],[-97.50500499999998,71.611649],[-97.65638699999994,71.61470000000003],[-97.69665500000002,71.61970500000007],[-97.71333299999998,71.62387100000001],[-97.72639500000002,71.628311],[-97.78721599999994,71.64414999999997],[-97.97471599999994,71.66081200000013],[-97.98805199999998,71.66192600000011],[-98.03527799999995,71.65332000000001],[-98.05332900000002,71.64833100000004],[-98.07278400000001,71.64166300000005],[-98.11277799999993,71.63693200000012],[-98.13110399999994,71.63804600000009],[-98.17887899999994,71.64166300000005],[-98.19665499999991,71.6436000000001],[-98.20750399999997,71.64610300000004],[-98.21806300000003,71.64971900000012],[-98.24082900000002,71.65971400000001],[-98.25279199999989,71.66609199999999],[-98.33111600000001,71.708328],[-98.34916699999991,71.71859700000005],[-98.3558349999999,71.7227630000001],[-98.35972599999997,71.72804300000001],[-98.35943600000002,71.73387100000008],[-98.333328,71.78749099999999],[-98.32556199999993,71.79832500000009],[-98.32139599999994,71.80331400000006],[-98.31527699999992,71.80914300000006],[-98.27917499999995,71.83471700000007],[-98.25917099999992,71.84471100000007],[-98.228882,71.86219800000009],[-98.21194499999996,71.87858599999998],[-98.20861799999994,71.88443000000001],[-98.20916699999998,71.88916],[-98.22193899999996,71.89498900000001],[-98.25527999999997,71.90248099999997],[-98.26722699999999,71.90415999999999],[-98.28277600000001,71.89915500000012],[-98.291382,71.89471400000002],[-98.45056199999999,71.79414399999996],[-98.46250899999995,71.78387499999997],[-98.47778299999993,71.76721200000009],[-98.48889200000002,71.74941999999999],[-98.49749799999995,71.73332199999999],[-98.49749799999995,71.72164900000013],[-98.49388099999999,71.71388200000001],[-98.38137799999998,71.653595],[-98.36749299999991,71.647491],[-98.17999299999991,71.57193000000012],[-98.04138199999989,71.53082300000005],[-98.03750600000001,71.526657],[-98.120544,71.46054099999998],[-98.18083199999995,71.42359899999997],[-98.19804399999998,71.41470300000003],[-98.46611000000001,71.31330900000006],[-98.50556899999992,71.29914900000011],[-98.54138199999994,71.28942900000004],[-98.55471799999998,71.2872010000001],[-98.70167500000002,71.271927],[-98.72084000000001,71.26998900000007],[-98.72972099999993,71.27053800000004],[-98.75111400000003,71.27415499999995],[-98.81639099999995,71.28915400000005],[-98.829453,71.29386900000009],[-98.84472699999998,71.30554200000012],[-98.88221699999997,71.33387800000003],[-98.93832399999985,71.36914100000001],[-98.96028100000001,71.379974],[-98.978882,71.382477],[-98.995544,71.3827510000001],[-99.01472499999994,71.38165300000003],[-99.03443899999996,71.37886000000003],[-99.04277000000002,71.37441999999999],[-99.04554699999994,71.36859099999998],[-99.05139200000002,71.36303699999996],[-99.05972300000002,71.35859700000015],[-99.07749899999999,71.3535920000001],[-99.11582900000002,71.35054000000002],[-99.2208399999999,71.34220900000008],[-99.23805199999998,71.344986],[-99.28805499999987,71.40277100000009],[-99.31332399999997,71.43942300000009],[-99.46278399999994,71.59304800000001],[-99.52972399999999,71.605255],[-99.55860899999988,71.61303700000013],[-99.57417299999997,71.61970500000007],[-99.578888,71.62275700000004],[-99.59167500000001,71.635269],[-99.67639200000002,71.72526600000009],[-99.67777999999993,71.72915600000005],[-99.67721599999999,71.73692300000005],[-99.6744379999999,71.74275200000005],[-99.67304999999999,71.74914600000005],[-99.67388900000003,71.7538760000001],[-99.67639200000002,71.75860599999999],[-99.67832899999996,71.7605440000001],[-99.84222399999999,71.834991],[-99.95916699999998,71.85415599999993],[-99.97721899999999,71.85581999999994],[-100.05110200000001,71.865814],[-100.067497,71.87052900000003],[-100.10193599999997,71.88472000000002],[-100.31471299999993,71.97997999999995],[-100.3219529999999,71.98498500000005],[-100.33222999999998,71.99720800000006],[-100.33583099999993,72.00665300000014],[-100.579453,72.15443400000004],[-100.63445299999995,72.18553200000008],[-100.64417300000002,72.18830899999995],[-100.72000099999997,72.20166000000012],[-100.88527699999997,72.20776400000011],[-100.88999899999988,72.20748900000012],[-100.92388900000003,72.19941699999998],[-100.95140099999992,72.17109700000015],[-100.96777299999997,72.17414900000006],[-101.01334399999996,72.19108600000004],[-101.02084400000001,72.19636500000001],[-101.054169,72.23165899999992],[-101.05555700000002,72.236649],[-101.11776700000001,72.284424],[-101.19444299999998,72.324432],[-101.20861799999994,72.32971200000009],[-101.220551,72.33221400000014],[-101.23889200000002,72.33387799999997],[-101.27667200000002,72.32832300000007],[-101.32528699999995,72.31498699999997],[-101.395554,72.28692600000005],[-101.40416699999997,72.28137200000003],[-101.40972899999986,72.27554300000003],[-101.46945199999999,72.26554900000002],[-101.50917099999998,72.28305100000006],[-101.58556399999998,72.301376],[-101.63474299999996,72.30693100000008],[-101.65638699999994,72.30525200000005],[-101.66416900000002,72.30165099999999],[-101.672234,72.29275500000006],[-101.6849979999999,72.28776600000009],[-101.69444299999986,72.28804000000002],[-101.776947,72.29971300000005],[-101.83056599999992,72.31915300000003],[-101.84472699999992,72.324432],[-101.88834399999996,72.35859700000015],[-101.94167299999987,72.45193500000005],[-101.98131599999999,72.47811100000013],[-102.08033799999993,72.51600600000012],[-102.22222899999991,72.54220600000008],[-102.258621,72.54914900000006],[-102.37721299999998,72.57748400000008],[-102.46584299999995,72.60470600000002],[-102.6219329999999,72.66470300000015],[-102.73638899999992,72.719986],[-102.74166899999989,72.72415200000006],[-102.75583599999993,72.76138300000002],[-102.76471699999996,72.784988],[-102.76306199999999,72.790817],[-102.75306699999999,72.81109600000013],[-102.74944299999999,72.81721499999998],[-102.74305699999996,72.82249500000006],[-102.73500100000001,72.82609600000012],[-102.69860799999992,72.83665499999995],[-102.66361999999992,72.85331699999995],[-102.64666699999992,72.86442600000004],[-102.61277799999993,72.89665200000013],[-102.59722899999991,72.91360500000002],[-102.59361299999995,72.919983],[-102.59166699999997,72.92553699999996],[-102.59306300000003,72.93165600000003],[-102.59416199999998,72.94274899999999],[-102.593887,72.949142],[-102.59166699999997,72.95498700000007],[-102.576683,72.97970600000002],[-102.56304899999998,72.99108900000004],[-102.51306199999993,73.02609300000012],[-102.50110599999994,73.03054800000012],[-102.38806199999999,73.06275900000003],[-102.36805699999996,73.06749000000013],[-102.27610800000002,73.08248900000001],[-102.24694799999997,73.08387800000003],[-102.1372219999999,73.08692900000005],[-102.08444199999985,73.08415200000013],[-102.014183,73.07971199999992],[-101.97083999999995,73.07054099999999],[-101.88417099999992,73.0247040000001],[-101.81777999999991,72.9666600000001],[-101.810272,72.96054100000003],[-101.75527999999997,72.93054200000006],[-101.74109599999991,72.92414900000006],[-101.67527799999999,72.90971400000012],[-101.59528399999994,72.90220599999992],[-101.52166699999998,72.87831100000011],[-101.50974299999996,72.87164299999995],[-101.40444899999989,72.78248600000012],[-101.41332999999997,72.74832200000009],[-101.37249800000001,72.72720300000009],[-101.36665299999999,72.72526600000003],[-101.29750099999995,72.70999100000006],[-101.03333299999997,72.68969700000014],[-100.91583299999996,72.68803400000002],[-100.88221699999991,72.68969700000014],[-100.82778899999994,72.70582600000006],[-100.81945799999994,72.7102660000001],[-100.81220999999994,72.71554599999996],[-100.81194299999999,72.71971099999996],[-100.79833999999994,72.74359099999998],[-100.70722999999998,72.755829],[-100.53307299999994,72.75138900000002],[-100.50917099999992,72.74914600000005],[-100.49833699999994,72.74803200000008],[-100.47582999999997,72.742752],[-100.44803599999995,72.73553500000008],[-100.43443300000001,72.73692299999999],[-100.41221599999994,72.74192800000003],[-100.34973100000002,72.7705380000001],[-100.340843,72.77499399999999],[-100.33168,72.78054800000001],[-100.314438,72.79637100000002],[-100.31555199999997,72.80137600000006],[-100.35077699999994,72.85132600000009],[-100.35160799999994,72.85366099999999],[-100.35711699999996,72.8591540000001],[-100.46916199999998,72.95027200000004],[-100.48638899999992,72.949142],[-100.49889399999995,72.95054600000014],[-100.49973299999999,72.95637499999998],[-100.46305799999993,73.01470900000004],[-100.45194999999995,73.02053800000004],[-100.421944,73.03498799999994],[-100.36776700000001,73.04693600000002],[-100.35637700000001,73.04942300000005],[-100.34221600000001,73.04414400000007],[-100.31667299999992,73.03414900000001],[-100.30943299999996,73.02804600000007],[-100.31555199999997,73.02249099999995],[-100.34306300000003,73.01388500000007],[-100.3577729999999,73.01054400000004],[-100.38137799999998,72.949142],[-100.3289949999999,72.89137299999999],[-100.31732899999992,72.88887],[-100.285278,72.87359600000008],[-100.21721599999995,72.87664799999999],[-100.196663,72.87776200000002],[-100.09638999999993,72.88638300000008],[-100.06722999999994,72.90220599999992],[-100.031387,72.93498200000005],[-100.04750099999995,72.95721400000014],[-100.11277799999999,73.02581800000007],[-100.16972399999992,73.07859800000011],[-100.23222399999997,73.13443000000012],[-100.24445299999996,73.136932],[-100.25446299999999,73.13720699999999],[-100.28888699999993,73.13581800000003],[-100.32362399999994,73.13333100000011],[-100.345551,73.13026400000001],[-100.38249200000001,73.12275700000009],[-100.39138799999995,73.11831700000005],[-100.41443600000002,73.10470600000008],[-100.44275699999997,73.08720400000004],[-100.51862299999993,73.0977630000001],[-100.58667000000003,73.1327510000001],[-100.60193599999997,73.14082300000007],[-100.60777300000001,73.14637800000014],[-100.58612099999999,73.16748000000013],[-100.58000199999987,73.17303500000003],[-100.49082900000002,73.23081999999994],[-100.40666199999987,73.28027300000008],[-100.39778100000001,73.28471399999995],[-100.37832600000002,73.28997800000013],[-100.36110699999995,73.29026799999997],[-100.28138699999994,73.27915999999999],[-100.1347429999999,73.22110000000004],[-100.05332899999996,73.18637100000001],[-100.03751399999999,73.18386800000002],[-100.021118,73.18304400000005],[-100.00418099999996,73.1833190000001],[-99.84111000000001,73.19136000000015],[-99.80166600000001,73.19552600000003],[-99.77166699999998,73.20109600000012],[-99.77027899999996,73.20387300000004],[-99.77166699999998,73.20803800000004],[-99.78639199999992,73.21249399999994],[-99.81193499999995,73.21554600000007],[-99.84944200000001,73.21527100000003],[-99.886124,73.21331800000007],[-99.92582700000003,73.21499600000004],[-99.945267,73.21666000000005],[-99.96444699999995,73.21943699999997],[-100.07749899999999,73.25138900000007],[-100.09500100000002,73.25721700000003],[-100.15915699999994,73.28942899999998],[-100.19943199999994,73.31860400000005],[-100.27223199999992,73.35859700000009],[-100.32362399999994,73.3836060000001],[-100.33332799999994,73.38832100000013],[-100.358047,73.393326],[-100.37389399999995,73.39582800000005],[-100.38417099999987,73.39637800000008],[-100.38806199999993,73.39553800000004],[-100.4058379999999,73.36137400000001],[-100.387787,73.338593],[-100.56166099999996,73.28665200000012],[-100.583618,73.28359999999998],[-100.823059,73.26081800000009],[-100.84056099999992,73.25972000000002],[-100.88945000000001,73.26443500000005],[-100.97749299999998,73.28027300000008],[-101.30499299999991,73.36164900000006],[-101.31276700000001,73.37109400000008],[-101.311394,73.38275100000004],[-101.31054699999999,73.39248700000002],[-101.311394,73.39833100000004],[-101.31723,73.40165700000006],[-101.47055099999994,73.43609600000013],[-101.55832700000002,73.44664],[-101.58084099999996,73.4502720000001],[-101.61665299999993,73.4852600000001],[-101.62138400000003,73.49026500000014],[-101.44055200000003,73.54914900000006],[-101.42748999999992,73.55220000000008],[-101.40083299999992,73.55358900000004],[-101.31582599999996,73.55081199999995],[-101.2808379999999,73.55247500000007],[-101.26888999999994,73.55609099999992],[-101.25974300000001,73.56164600000005],[-101.25527999999997,73.56776399999995],[-101.25222799999995,73.57887300000004],[-101.25306699999993,73.584991],[-101.25110599999994,73.58970600000004],[-101.24194299999994,73.59526100000011],[-101.23082699999998,73.60026600000015],[-101.21721600000001,73.60415599999993],[-101.199432,73.60554500000012],[-100.92639200000002,73.60026600000015],[-100.90943900000002,73.59971600000011],[-100.890289,73.59610000000009],[-100.87748699999997,73.59027100000003],[-100.77084400000001,73.53997800000008],[-100.71749899999992,73.50915500000008],[-100.70667299999997,73.49942000000004],[-100.70221699999996,73.49443100000008],[-100.70140100000003,73.48858599999994],[-100.69721999999996,73.482483],[-100.69110099999995,73.47692900000004],[-100.67278299999998,73.46443200000004],[-100.51834099999996,73.41693099999998],[-100.49973299999999,73.41249099999993],[-100.46472199999988,73.40721100000007],[-100.44444299999992,73.40637200000009],[-100.43055700000002,73.40693699999997],[-100.41722099999998,73.41331500000007],[-100.41500899999994,73.41804500000012],[-100.42971799999998,73.43026700000007],[-100.45500199999998,73.44192499999997],[-100.484734,73.45193500000005],[-100.50279199999989,73.45748900000001],[-100.531387,73.46609499999994],[-100.58389299999993,73.48220800000001],[-100.59221599999995,73.48637400000007],[-100.59861799999999,73.4910890000001],[-100.60611,73.49720799999994],[-100.61000099999995,73.50305200000014],[-100.610817,73.50915500000008],[-100.60804699999994,73.5149990000001],[-100.60388199999994,73.52110299999998],[-100.55915799999997,73.54609700000009],[-100.54387700000001,73.55636600000014],[-100.541382,73.56219499999997],[-100.54277000000002,73.57388300000002],[-100.54998799999993,73.59471100000007],[-100.55166600000001,73.59887699999996],[-100.573624,73.59664900000001],[-100.628601,73.593323],[-100.76750199999998,73.60386700000004],[-100.89167799999996,73.61998000000006],[-100.91139199999998,73.62275699999998],[-100.91194200000001,73.62525900000003],[-100.91139199999998,73.63053900000011],[-100.87943999999999,73.63581800000009],[-100.86472300000003,73.641663],[-100.86110699999995,73.645828],[-100.85360699999995,73.66220100000004],[-100.858047,73.66720599999991],[-100.97444199999995,73.67915300000004],[-100.99194299999999,73.67886399999998],[-101.03333299999997,73.67137100000014],[-101.04695099999998,73.67303500000014],[-101.057503,73.67665099999999],[-101.11833199999995,73.72331200000002],[-101.120003,73.72720300000009],[-101.01390100000003,73.79721100000006],[-100.9974979999999,73.80247500000002],[-100.98222399999997,73.80581699999999],[-100.95973199999997,73.809143],[-100.93804899999998,73.81025699999998],[-100.82861300000002,73.81553600000012],[-100.79527300000001,73.81248499999992],[-100.77583300000003,73.81219500000009],[-100.754997,73.81248499999992],[-100.73416099999997,73.81526200000002],[-100.714447,73.82026700000006],[-100.69915800000001,73.82609600000006],[-100.66416900000002,73.84498600000006],[-100.64835399999993,73.84832799999998],[-100.554169,73.85470599999996],[-100.52999899999998,73.85359199999994],[-100.41777000000002,73.84553499999998],[-100.39555399999995,73.84082000000012],[-100.38945000000001,73.83859300000006],[-100.370003,73.82804900000002],[-100.34999099999993,73.818604],[-100.33612099999993,73.81469700000002],[-100.06304899999998,73.76499900000005],[-99.86582899999996,73.8377690000001],[-99.85777300000001,73.84275800000006],[-99.87010999999995,73.86154199999999],[-99.86910999999992,73.86737099999999],[-99.86978099999993,73.87020100000001],[-99.87710599999991,73.87654100000003],[-99.88677199999995,73.8822100000001],[-99.89244099999996,73.88353699999993],[-99.96194499999996,73.87330600000007],[-99.97166399999998,73.86804200000006],[-99.98805199999993,73.85693400000008],[-99.99082900000002,73.851089],[-99.99749800000001,73.84553499999998],[-100.00834699999996,73.84136999999998],[-100.02639799999997,73.83692900000005],[-100.04943800000001,73.83276400000005],[-100.13667299999997,73.82748400000003],[-100.175003,73.82804900000002],[-100.24944299999993,73.83387800000003],[-100.26139799999993,73.83831800000007],[-100.29972799999996,73.8602600000001],[-100.29695100000004,73.86581400000011],[-100.29222099999993,73.872208],[-100.27860999999996,73.888596],[-100.26583900000003,73.89999400000005],[-100.252792,73.905258],[-100.24305700000002,73.907486],[-100.14306599999992,73.92997700000001],[-100.12721299999993,73.9333190000001],[-100.104446,73.93637100000001],[-100.03751399999999,73.94247399999995],[-99.98110999999994,73.9458160000001],[-99.93859900000001,73.94609100000008],[-99.89695699999999,73.94413800000001],[-99.85610999999989,73.94081100000005],[-99.81610099999995,73.93609600000002],[-99.80082700000003,73.93165599999998],[-99.80055199999993,73.92581200000001],[-99.81332399999997,73.92137100000008],[-99.80622099999994,73.90210000000002],[-99.81005899999997,73.89876600000002],[-99.81088999999997,73.8949280000001],[-99.80822799999999,73.89193700000004],[-99.80455799999993,73.8890990000001]],[[-89.98889200000002,73.98831200000012],[-90.00778199999996,73.984985],[-90.05804399999994,73.99247700000012],[-90.158615,74.00138900000013],[-90.21777299999997,74.00443999999999],[-90.25029,74.00999500000006],[-90.265015,74.01470899999998],[-90.28111299999989,74.02165199999996],[-90.28472899999991,74.0249940000001],[-90.28500399999996,74.02970900000014],[-90.27639799999986,74.038589],[-90.27111799999994,74.04332000000011],[-90.24055499999997,74.05386399999998],[-90.20611599999995,74.05775500000004],[-89.99194299999994,74.066666],[-89.97193900000002,74.06469700000014],[-89.94137599999999,74.05748],[-89.91444399999995,74.04748500000011],[-89.90194699999995,74.03776600000009],[-89.903885,74.03137200000009],[-89.91860999999994,74.01054399999998],[-89.92832900000002,74.00555400000013],[-89.98889200000002,73.98831200000012]],[[-98.91861,73.8060910000001],[-98.96166999999997,73.80525200000011],[-99.104172,73.81442300000009],[-99.14083899999991,73.81805400000013],[-99.36361699999992,73.86442600000004],[-99.38194299999992,73.86914100000007],[-99.42971799999992,73.89166299999994],[-99.43749999999994,73.89694199999991],[-99.43638599999997,73.90220600000009],[-99.42971799999992,73.9080350000001],[-99.42250100000001,73.91110200000003],[-99.406113,73.91526799999991],[-99.28250099999997,73.93691999999999],[-99.22389199999998,73.94026200000008],[-99.09277299999991,73.95220900000004],[-99.02027900000002,73.97970600000002],[-98.93804899999992,73.99859600000013],[-98.80166600000001,74.01805100000013],[-98.66194200000001,74.03137200000009],[-98.57583599999998,74.03137200000009],[-98.53250100000002,74.03221100000002],[-98.49194299999994,74.03414899999996],[-98.42527799999999,74.04386900000003],[-98.3558349999999,74.05748],[-98.27583299999992,74.07388300000008],[-98.25500499999993,74.07859800000011],[-98.23028599999998,74.08332799999994],[-98.17083699999995,74.09248400000007],[-98.03999299999998,74.10582000000005],[-97.99444599999993,74.10942100000011],[-97.80610699999988,74.11943100000002],[-97.75834699999996,74.11859099999998],[-97.737213,74.11747700000001],[-97.70361300000002,74.11387600000012],[-97.69082600000002,74.11137400000007],[-97.65360999999996,74.09999100000005],[-97.64805599999994,74.0977630000001],[-97.64222699999993,74.08720400000004],[-97.637787,74.07554600000003],[-97.63833599999998,74.063873],[-97.64944499999996,74.05247499999996],[-97.65666199999998,74.04693599999996],[-97.67332499999986,74.03553799999997],[-97.71722399999999,74.00972000000002],[-97.72805800000003,74.00416600000005],[-97.76362599999993,73.98831200000012],[-97.82305899999989,73.9685970000001],[-98.12416100000002,73.8785860000001],[-98.14500399999991,73.87359600000008],[-98.16833499999996,73.87081899999998],[-98.39277600000003,73.84526100000005],[-98.478882,73.8374940000001],[-98.777222,73.81359900000012],[-98.91861,73.8060910000001]],[[-92.63806199999988,74.10304300000013],[-92.36860699999994,74.04109199999999],[-92.35694899999999,74.03804000000002],[-92.33444199999991,74.03137200000009],[-92.31138599999997,74.02165199999996],[-92.29695100000004,74.01443500000005],[-92.289444,74.00915500000002],[-92.28277599999996,74.00332599999996],[-92.27362099999999,73.99054000000007],[-92.27278100000001,73.98442100000005],[-92.28195199999999,73.97499099999999],[-92.29110700000001,73.96971100000007],[-92.31054699999993,73.96110499999998],[-92.32778899999994,73.95138500000007],[-92.33000199999998,73.94552600000009],[-92.32972699999999,73.94247399999995],[-92.30943300000001,73.94081100000005],[-92.1324919999999,73.94636500000001],[-92.118607,73.94914200000011],[-92.11665299999999,73.95109599999995],[-92.11332700000003,73.95637499999998],[-92.1100009999999,73.96470600000004],[-92.11305199999998,73.97442600000011],[-92.114441,73.97665400000005],[-92.11305199999998,73.98136899999992],[-92.10777300000001,73.98471100000006],[-92.09416199999998,73.98915100000005],[-91.92555199999998,74.01277199999993],[-91.87721299999998,74.01693699999993],[-91.83833299999998,74.0188750000001],[-91.57084700000001,74.02581800000007],[-91.52833599999991,74.02442900000005],[-91.13999899999993,74.00999500000006],[-91.09750400000001,74.00833100000006],[-91.06500199999999,74.006104],[-91.04695100000004,74.00416600000005],[-90.73554999999993,73.968323],[-90.66000399999996,73.95387300000004],[-90.63305699999995,73.94831799999997],[-90.44137599999993,73.91970800000013],[-90.40666199999998,73.91470300000009],[-90.364441,73.91165200000006],[-90.35472099999998,73.91220100000004],[-90.34495500000003,73.91436800000008],[-90.34167499999995,73.91720600000008],[-90.33972199999994,73.9205320000001],[-90.34111000000001,73.92414900000006],[-90.33555599999994,73.92581200000001],[-90.31777999999997,73.92526199999998],[-90.22500600000001,73.90859999999998],[-90.195831,73.90193199999999],[-90.19444299999992,73.899719],[-90.20417800000001,73.88832100000002],[-90.23028599999998,73.86219800000003],[-90.24194299999999,73.85192900000004],[-90.25140399999998,73.84664900000013],[-90.26445000000001,73.84165999999999],[-90.27528399999994,73.83859300000006],[-90.28306600000002,73.83831800000007],[-90.36000099999995,73.80081200000012],[-90.474716,73.72164900000007],[-90.58139,73.65776100000005],[-90.72471599999994,73.58305400000012],[-90.84973100000002,73.54026800000008],[-90.92138699999992,73.49525500000004],[-90.93028300000003,73.48387100000008],[-90.93221999999997,73.48193400000008],[-91.08917200000002,73.38415500000002],[-91.152222,73.36109900000002],[-91.17138699999998,73.35108900000006],[-91.18055700000002,73.3458250000001],[-91.18638599999991,73.34027100000009],[-91.23860200000001,73.27998400000013],[-91.25306699999987,73.26915000000008],[-91.26222200000001,73.26388500000002],[-91.36776700000001,73.20082100000013],[-91.569458,73.06330900000006],[-91.64277600000003,73.02110300000004],[-91.64750699999996,73.01666300000005],[-91.64500399999997,72.99803200000002],[-91.77084400000001,72.91304000000002],[-91.79972799999996,72.89721699999996],[-91.80833399999989,72.8919370000001],[-91.81277499999999,72.88581800000009],[-91.81304899999992,72.88026400000007],[-91.81138599999997,72.86804200000012],[-91.818893,72.86219800000009],[-91.84973100000002,72.84610000000004],[-92.06610099999989,72.75248700000009],[-92.0958399999999,72.743042],[-92.12748699999992,72.73442100000011],[-92.16639699999996,72.72553999999997],[-92.23222399999997,72.71304300000003],[-92.27471899999989,72.70748900000001],[-92.314438,72.70498700000013],[-92.33528099999995,72.7044370000001],[-92.39334099999991,72.70721399999996],[-92.431107,72.71054100000009],[-92.524719,72.72053499999993],[-92.74526999999989,72.73997500000013],[-92.898346,72.75027500000004],[-93.07749899999988,72.76943999999997],[-93.24888599999991,72.78970300000003],[-93.337784,72.8077550000001],[-93.34916699999985,72.80247500000007],[-93.36665299999999,72.79776000000004],[-93.39195299999994,72.79414400000013],[-93.412216,72.79220600000002],[-93.58000199999992,72.77804600000007],[-93.67999299999991,72.77970900000003],[-93.7261049999999,72.7810970000001],[-93.76445000000001,72.78137200000015],[-93.93276999999995,72.77415500000001],[-94.03860499999996,72.76638800000006],[-94.09916699999997,72.76416000000012],[-94.13249200000001,72.76470900000004],[-94.17054699999994,72.76748700000007],[-94.18249499999996,72.76943999999997],[-94.24610899999999,72.77388000000002],[-94.26278699999989,72.77415500000001],[-94.29804999999999,72.77026399999994],[-94.31555200000003,72.76304600000014],[-94.32194499999997,72.75943000000007],[-94.32749899999999,72.75444000000005],[-94.33444199999997,72.73803699999996],[-94.33277900000002,72.73193400000002],[-94.32749899999999,72.72164900000013],[-94.319458,72.71748400000013],[-94.3125,72.71554599999996],[-94.29750100000001,72.71331800000002],[-94.26916499999993,72.71914700000002],[-94.26528899999994,72.72387700000007],[-94.26390100000003,72.72998000000001],[-94.25834699999996,72.732483],[-94.23638899999992,72.73498500000005],[-94.160278,72.72943100000003],[-94.1036069999999,72.71859699999999],[-94.09333799999996,72.71499599999993],[-94.00140399999992,72.704163],[-93.98500099999995,72.70387299999993],[-93.88667299999997,72.70471200000009],[-93.839447,72.71720900000008],[-93.79834,72.70220899999993],[-93.82305899999989,72.65304600000002],[-93.81722999999994,72.64221199999997],[-93.80166599999995,72.63443000000001],[-93.78611799999993,72.62914999999998],[-93.76945499999988,72.62498499999998],[-93.75778200000002,72.62303200000002],[-93.6866609999999,72.62220800000006],[-93.67443800000001,72.61886600000008],[-93.589722,72.58137499999998],[-93.56861900000001,72.57083100000011],[-93.49888599999997,72.52192700000012],[-93.46333300000003,72.4622040000001],[-93.46611000000001,72.45138500000002],[-93.46945199999999,72.43969700000002],[-93.62805200000003,72.34193400000004],[-93.64527899999996,72.33720400000004],[-93.66639700000002,72.33360299999998],[-93.68832399999991,72.33109999999999],[-93.74861099999998,72.32971200000009],[-93.76722699999999,72.3272090000001],[-93.787216,72.32276900000011],[-93.80139200000002,72.31776400000007],[-93.81973299999993,72.30720500000001],[-93.82749899999999,72.30192600000004],[-93.91332999999997,72.24165299999993],[-93.92527799999993,72.23304700000006],[-94.01417500000002,72.16387900000012],[-94.03666699999985,72.14221200000009],[-94.04028299999999,72.13749700000005],[-94.04361,72.13136300000002],[-94.04554699999989,72.12692299999998],[-94.04472399999997,72.11581400000011],[-94.04222099999993,72.10664400000007],[-94.04388399999993,72.09693900000013],[-94.04833999999994,72.09109499999994],[-94.05471799999992,72.08526599999993],[-94.06666599999994,72.07666],[-94.08084099999996,72.06693999999993],[-94.09167500000001,72.061646],[-94.12768599999993,72.05636600000008],[-94.14334100000002,72.05748000000006],[-94.17250099999995,72.0577550000001],[-94.18666099999996,72.05581699999993],[-94.19888300000002,72.05276500000002],[-94.18872099999999,72.0452580000001],[-94.19505300000003,72.04209100000008],[-94.19838700000003,72.03910100000013],[-94.199547,72.03643800000003],[-94.196053,72.03243299999997],[-94.18838499999998,72.03093000000013],[-94.17204299999992,72.02959400000009],[-94.14988699999992,72.02943399999998],[-94.13738299999989,72.03176900000011],[-94.13055400000002,72.03310400000004],[-94.12521400000003,72.03509500000013],[-94.091385,72.03776600000015],[-94.06082200000003,72.03526299999999],[-94.02972399999993,71.99941999999999],[-94.06304899999992,71.97831700000006],[-94.08222999999998,71.97608900000012],[-94.19171900000003,71.99431600000008],[-94.35388199999994,72.01805099999996],[-94.37193300000001,72.01944000000015],[-94.41805999999991,72.02276599999999],[-94.44972199999995,72.02331500000014],[-94.74388099999993,72.01138300000002],[-94.78028899999998,72.006104],[-94.82556199999999,71.99748199999999],[-94.90222199999988,71.9891510000001],[-95.12193299999996,71.96609500000005],[-95.16111799999993,71.96470600000009],[-95.17582699999997,71.96693400000004],[-95.20777899999996,71.98887600000012],[-95.21333300000003,71.99443100000002],[-95.20666499999999,72.09748800000011],[-95.204453,72.10276799999997],[-95.19665499999996,72.10664400000007],[-95.039444,72.13136300000002],[-94.981674,72.13943499999999],[-94.92971799999992,72.14359999999999],[-94.89999399999999,72.14444000000003],[-94.86805700000002,72.1455380000001],[-94.752228,72.15332000000006],[-94.76083399999993,72.15498400000007],[-94.80610699999994,72.15914900000007],[-94.8391719999999,72.15859999999998],[-94.96139499999998,72.155258],[-95.02749599999999,72.14498900000001],[-95.12110899999999,72.13665800000007],[-95.13999899999993,72.1355440000001],[-95.15888999999999,72.13581800000003],[-95.17111199999994,72.13915999999995],[-95.20666499999999,72.18081700000005],[-95.21167000000003,72.18719499999997],[-95.21362299999998,72.19331399999999],[-95.21472199999994,72.20027199999998],[-95.21472199999994,72.20526099999995],[-95.20388799999989,72.22192400000006],[-95.19137599999999,72.2452550000001],[-95.17111199999994,72.28332499999999],[-95.13333099999988,72.46026599999999],[-95.200287,72.524429],[-95.22639499999997,72.53166200000004],[-95.2830659999999,72.53553800000009],[-95.31610099999995,72.53970300000009],[-95.321396,72.54609700000015],[-95.34445199999993,72.58137499999998],[-95.34666400000003,72.58749399999999],[-95.345551,72.593323],[-95.33167999999995,72.59832800000004],[-95.31332399999997,72.60108900000006],[-95.31582600000002,72.60636899999992],[-95.35555999999997,72.63777199999998],[-95.36444099999989,72.64332600000012],[-95.45861799999994,72.68220500000001],[-95.47555499999999,72.68637100000012],[-95.4927669999999,72.68803400000002],[-95.50556899999998,72.68637100000012],[-95.52555799999999,72.68165600000009],[-95.53582799999992,72.68136600000003],[-95.54861499999993,72.68220500000001],[-95.57611099999997,72.68997199999995],[-95.59056099999992,72.69552599999997],[-95.60221899999993,72.70220899999993],[-95.6661069999999,72.80137600000006],[-95.67361499999998,72.81387300000006],[-95.67555199999998,72.82499700000011],[-95.67527799999993,72.841095],[-95.67193600000002,72.85247800000002],[-95.653885,72.87692300000003],[-95.64584400000001,72.91276600000009],[-95.65556300000003,73.01998900000007],[-95.68331899999998,73.07582100000002],[-95.58250399999997,73.12776200000013],[-95.57501200000002,73.1649930000001],[-95.60054000000002,73.283905],[-95.65083299999998,73.32527200000004],[-95.64666699999998,73.33082600000006],[-95.61361699999998,73.342758],[-95.62361099999998,73.36109900000002],[-95.65361000000001,73.41249099999993],[-95.681671,73.44413800000007],[-95.68388400000003,73.4502720000001],[-95.700287,73.55386400000009],[-95.66836499999994,73.58178700000008],[-95.61256399999996,73.61097699999999],[-95.65605900000003,73.63186600000012],[-95.676086,73.66506199999998],[-95.68194599999998,73.711929],[-95.67304999999999,73.72331200000002],[-95.65888999999999,73.73248299999995],[-95.64584400000001,73.73553500000008],[-95.45083599999998,73.7711030000001],[-95.42832900000002,73.77276599999999],[-95.29972799999996,73.7711030000001],[-95.28361499999994,73.76914999999997],[-95.26640299999991,73.76416000000012],[-95.23693800000001,73.75221299999998],[-95.160278,73.71304299999997],[-95.15472399999999,73.70694000000003],[-95.13833599999992,73.70082100000002],[-95.10694899999999,73.69192500000008],[-95.07640100000003,73.68331899999998],[-95.02417000000003,73.67164600000012],[-94.95666499999993,73.65914900000013],[-94.89056399999993,73.64915500000012],[-94.84555099999994,73.64415000000008],[-94.82861300000002,73.64305100000007],[-94.81221,73.64332600000012],[-94.652222,73.64860500000009],[-94.63417099999992,73.64942900000005],[-94.61805699999991,73.65138200000001],[-94.61915599999998,73.6544340000001],[-94.63806199999999,73.66581700000012],[-94.64944500000001,73.67082199999999],[-94.67639200000002,73.67665099999999],[-94.73277300000001,73.68136600000003],[-94.773056,73.67997700000001],[-94.81471299999987,73.6808170000001],[-94.866104,73.68719500000003],[-94.883331,73.69220000000007],[-95.07556199999988,73.77331500000014],[-95.08917200000002,73.78332500000005],[-95.11193799999995,73.80108600000005],[-95.11610399999995,73.80664100000013],[-95.108047,73.81219500000009],[-95.07084700000001,73.822769],[-95.03666699999991,73.82943699999993],[-95.00556899999998,73.83248900000007],[-94.97666899999996,73.83110000000005],[-94.958054,73.83194000000009],[-94.96333299999998,73.83831800000007],[-94.98249799999996,73.84553499999998],[-95.00500499999998,73.85276799999997],[-95.02444500000001,73.85525500000006],[-95.04554699999994,73.85554500000006],[-95.07667500000002,73.85247799999996],[-95.10916099999997,73.84359700000005],[-95.11639399999996,73.839157],[-95.12721299999993,73.82582100000008],[-95.13612399999994,73.82360800000009],[-95.15417499999995,73.82360800000009],[-95.26306199999999,73.86276200000003],[-95.304169,73.8808140000001],[-95.31138599999991,73.88526900000011],[-95.32333399999993,73.89694199999991],[-95.32778899999988,73.90914900000007],[-95.32972699999999,73.91998299999995],[-95.32611099999997,73.94413800000001],[-95.32472199999995,73.95248400000008],[-95.31916799999988,73.96415700000011],[-95.29834,73.98082],[-95.24527,74.010269],[-95.22778299999999,74.01416000000006],[-95.22000100000002,74.01470899999998],[-95.19248999999996,74.00888100000009],[-95.17443800000001,74.00888100000009],[-95.04083300000002,74.02638200000001],[-94.90695199999999,74.04748500000011],[-94.850281,74.05886800000013],[-94.80610699999994,74.06805400000007],[-94.78750600000001,74.07276900000011],[-94.75527999999991,74.08720400000004],[-94.74583399999995,74.09220900000008],[-94.73222399999997,74.095261],[-94.61833200000001,74.09027100000014],[-94.46028100000001,74.09443700000003],[-94.43693499999995,74.09582499999993],[-94.42721599999993,74.10081500000001],[-94.421112,74.10582000000005],[-94.412781,74.11526500000014],[-94.40611299999995,74.11886599999997],[-94.39222699999999,74.12191800000011],[-94.21749899999998,74.13165299999997],[-94.17777999999993,74.1336060000001],[-94.09306300000003,74.13638300000002],[-93.99249299999991,74.138596],[-93.95195000000001,74.13888500000007],[-93.91416900000002,74.13610799999998],[-93.90194699999995,74.13333100000011],[-93.75834699999996,74.09693900000013],[-93.76139799999999,74.12915000000004],[-93.75944500000003,74.13916000000012],[-93.754456,74.14471400000008],[-93.73083500000001,74.15416000000005],[-93.69055199999997,74.16220099999998],[-93.64111299999996,74.16775499999994],[-93.58361799999989,74.17082200000004],[-93.515015,74.17303500000003],[-93.431671,74.17221100000006],[-93.32749899999999,74.16998300000012],[-93.24388099999999,74.16499300000004],[-93.028885,74.14999399999999],[-92.979446,74.14582800000011],[-92.79638699999998,74.12498500000004],[-92.63806199999988,74.10304300000013]],[[-98.65722699999998,74.29942299999999],[-98.74694799999997,74.29803500000008],[-98.81027199999994,74.29832500000009],[-98.83167999999995,74.29914900000006],[-98.85943600000002,74.30137600000012],[-98.86221299999994,74.30247500000013],[-98.86471599999999,74.30470300000007],[-98.86305199999998,74.30748],[-98.85722399999997,74.31137100000007],[-98.75250199999994,74.33415200000007],[-98.71833800000002,74.33665500000001],[-98.630829,74.34248400000007],[-98.61665299999999,74.34193400000004],[-98.58583099999998,74.338593],[-98.57362399999994,74.334991],[-98.535278,74.3288730000001],[-98.52166699999998,74.32470699999999],[-98.511124,74.318329],[-98.51556399999993,74.31414799999993],[-98.52500900000001,74.31053200000008],[-98.5686189999999,74.30470300000007],[-98.65722699999998,74.29942299999999]],[[-120.14998600000001,74.27249100000006],[-119.86472300000003,74.23776200000003],[-119.84528399999999,74.23580900000007],[-119.79527299999995,74.234421],[-119.72501399999993,74.23387100000014],[-119.60916099999997,74.23332199999999],[-119.63971699999996,74.19303900000011],[-119.65139799999997,74.18165599999992],[-119.67250099999995,74.165817],[-119.69082599999996,74.15693699999997],[-119.70249899999999,74.15304600000007],[-119.72305299999994,74.14471400000008],[-119.79415899999998,74.11526500000014],[-119.80332900000002,74.11053500000008],[-119.82417299999992,74.09471100000013],[-119.833618,74.082764],[-119.83612099999999,74.07582100000002],[-119.83277900000002,74.06414799999999],[-119.8272169999999,74.05914300000012],[-119.77916699999997,74.03387500000002],[-119.76806599999986,74.03027300000008],[-119.74481199999997,74.02551300000005],[-119.72860699999995,74.02915999999999],[-119.72609699999992,74.03581200000008],[-119.72638699999993,74.04193100000009],[-119.73777799999999,74.05802900000015],[-119.650284,74.11859099999998],[-119.51000999999991,74.20915200000002],[-119.50083899999998,74.21388200000001],[-119.48916599999995,74.21748399999996],[-119.46528599999994,74.22110000000004],[-119.44972199999995,74.221924],[-119.25723299999999,74.21832300000011],[-119.18472300000002,74.21693399999992],[-119.16528299999987,74.21499599999999],[-119.14862099999999,74.2122040000001],[-119.137787,74.20860300000004],[-119.12110899999993,74.1997070000001],[-119.11554699999999,74.19497700000005],[-119.10193600000002,74.17942800000014],[-119.09638999999999,74.16832],[-119.090843,74.15693699999997],[-119.07055700000001,74.11470000000008],[-119.06527699999998,74.10331700000006],[-119.07084699999996,74.08998099999997],[-119.08084099999996,74.07777399999998],[-119.08805799999999,74.07276900000011],[-119.10166900000002,74.06971699999997],[-119.11972000000003,74.06805400000007],[-119.14723199999997,74.06219500000003],[-119.15222199999994,74.05609100000004],[-119.18721,73.99414100000013],[-119.18721,73.98776200000009],[-119.16750299999995,73.98719800000015],[-118.98889200000002,73.99803200000002],[-118.973053,74.00027499999999],[-118.96362299999993,74.00499000000002],[-118.80777,74.09054600000013],[-118.80055199999998,74.09582499999993],[-118.79028299999993,74.10775799999999],[-118.78751399999999,74.11470000000008],[-118.79277000000002,74.125809],[-118.79804999999999,74.13081400000004],[-118.80695299999996,74.13388099999997],[-118.82333399999999,74.13638300000002],[-118.83693699999992,74.1394350000001],[-118.84805299999994,74.143326],[-118.86721799999998,74.15138200000007],[-118.88333099999994,74.16638200000006],[-118.88612399999994,74.17192100000005],[-118.881104,74.17804000000007],[-118.84388699999994,74.18830900000012],[-118.72000100000002,74.21276899999992],[-118.67388899999997,74.21998600000006],[-118.60722399999997,74.22831700000012],[-118.50583599999999,74.23997499999996],[-118.17999299999991,74.27221700000013],[-118.12249799999995,74.27581800000002],[-118.10193600000002,74.27638200000013],[-118.031387,74.2752690000001],[-117.97361799999999,74.26915000000002],[-117.91860999999989,74.26220700000005],[-117.62832599999996,74.24498000000006],[-117.51251199999996,74.238586],[-117.43859900000001,74.22943099999992],[-117.422234,74.22692900000004],[-117.37609899999995,74.21832300000011],[-117.28943599999997,74.1997070000001],[-117.15722700000003,74.16775499999994],[-116.82833899999997,74.072495],[-116.78500400000001,74.059708],[-116.735817,74.03970300000015],[-116.6224979999999,73.990814],[-116.52806099999998,73.94970699999999],[-116.441101,73.91360500000002],[-116.348053,73.87553400000002],[-116.33805799999999,73.87164300000012],[-116.32778899999988,73.86775200000005],[-116.31471299999993,73.86442600000004],[-116.29888900000003,73.86164900000011],[-116.20805399999995,73.83831800000007],[-116.05583199999995,73.79275500000011],[-116.00556899999998,73.77331500000014],[-115.97638699999999,73.75555400000002],[-115.91443599999997,73.72637900000012],[-115.89444699999996,73.71859699999999],[-115.817497,73.69831800000003],[-115.603882,73.65220599999998],[-115.402222,73.568329],[-115.36694299999999,73.5458220000001],[-115.34889199999998,73.53193700000003],[-115.33194700000001,73.51165800000007],[-115.31500199999999,73.47970599999991],[-115.32305899999994,73.47442600000005],[-115.449432,73.42665100000005],[-115.46140300000002,73.42303499999997],[-115.69943199999989,73.36886600000014],[-115.83473199999997,73.33998100000008],[-115.862213,73.33442700000012],[-116.26750199999998,73.27304100000015],[-116.33556399999998,73.26721199999992],[-116.37249800000001,73.26554900000002],[-116.42500299999995,73.26165800000012],[-116.45612299999993,73.25749200000001],[-116.46945199999999,73.25471500000015],[-116.69304699999992,73.20387300000004],[-116.80943299999996,73.168045],[-116.94803599999995,73.12498500000004],[-117.02639799999997,73.10693400000002],[-117.16915899999998,73.08194000000009],[-117.39388999999994,73.04859899999991],[-117.42639200000002,73.04498300000006],[-117.46610999999996,73.03637700000013],[-117.708054,72.97776800000008],[-117.83667000000003,72.93858300000011],[-117.891953,72.919983],[-117.925003,72.90887500000002],[-117.97501399999993,72.89637800000003],[-118.01611300000002,72.88832100000002],[-118.11527999999993,72.87081899999998],[-118.21806300000003,72.85470599999996],[-118.27362099999999,72.84443699999991],[-118.314438,72.83610499999992],[-118.36609599999997,72.82443200000012],[-118.38999899999993,72.81776400000012],[-118.44444299999998,72.79887400000001],[-118.45333900000003,72.79443400000014],[-118.46000700000002,72.78915400000011],[-118.46472199999994,72.7833250000001],[-118.48528299999992,72.76748700000007],[-118.49610899999999,72.76361099999997],[-118.53472899999991,72.75471500000003],[-118.54943799999995,72.75248700000009],[-118.58528100000001,72.75027500000004],[-118.65805099999994,72.74803200000008],[-118.70861799999994,72.74359099999998],[-118.75306699999999,72.73692299999999],[-118.77861000000001,72.73109399999998],[-119.11444099999994,72.63943500000005],[-119.1375119999999,72.63247700000005],[-119.15888999999999,72.62498499999998],[-119.16750299999995,72.62052900000003],[-119.30943300000001,72.43887300000006],[-119.3163909999999,72.42581200000012],[-119.33000199999987,72.39414999999997],[-119.33249699999999,72.38720699999999],[-119.33000199999987,72.38165300000014],[-119.32501200000002,72.3766480000001],[-119.30999800000001,72.368042],[-119.30277999999993,72.36303700000013],[-119.30248999999998,72.35664400000002],[-119.31111099999993,72.35220300000009],[-119.40444899999994,72.32554599999997],[-119.429169,72.31971699999997],[-119.51555599999989,72.3058170000001],[-119.62666300000001,72.27832000000012],[-119.65750099999991,72.26721199999997],[-119.67804699999999,72.25943000000001],[-119.760559,72.22886700000004],[-119.80139200000002,72.22137500000008],[-119.837784,72.21971100000007],[-119.97250399999996,72.22110000000009],[-120.12372599999998,72.23259700000011],[-120.13405599999999,72.23375699999997],[-120.13871799999998,72.23642000000007],[-120.13621499999994,72.23992900000013],[-120.12888299999992,72.24192800000014],[-120.14362299999993,72.2494200000001],[-120.12943999999999,72.25166300000006],[-120.12721299999993,72.25860600000004],[-120.12999000000002,72.26416000000006],[-120.13999899999993,72.26776100000006],[-120.15750099999997,72.26971400000002],[-120.17582699999997,72.2688750000001],[-120.24109599999997,72.26249700000011],[-120.251106,72.25860600000004],[-120.25945299999995,72.246643],[-120.26139799999987,72.23970000000003],[-120.25862099999995,72.23414600000001],[-120.23144500000001,72.21481299999999],[-120.225281,72.21247900000014],[-120.21028899999999,72.20881700000001],[-120.19810499999994,72.20432299999999],[-120.18894999999998,72.19915000000009],[-120.18578299999996,72.19615199999998],[-120.14527900000002,72.14999400000005],[-120.14499699999993,72.14359999999999],[-120.17582699999997,72.09443700000008],[-120.19415299999997,72.07832300000013],[-120.30526699999996,72.01304600000009],[-120.329453,71.99914600000005],[-120.34750399999996,71.99081400000006],[-120.383621,71.98165899999998],[-120.41332999999986,71.97137499999997],[-120.423317,71.96748400000007],[-120.4391629999999,71.95832800000011],[-120.445267,71.95304899999996],[-120.4491579999999,71.94693000000012],[-120.45278899999994,71.93470799999994],[-120.45249899999993,71.92776500000014],[-120.44972200000001,71.92221099999995],[-120.439438,71.91220100000004],[-120.43167099999994,71.90803499999998],[-120.391953,71.89305100000007],[-120.38445300000001,71.88888500000002],[-120.37917299999998,71.88388100000003],[-120.380829,71.87831099999994],[-120.41500899999994,71.77638200000013],[-120.42278299999998,71.76416000000012],[-120.42471299999994,71.75721699999997],[-120.42639199999996,71.74443100000002],[-120.423607,71.73887599999995],[-120.41332999999986,71.72886699999998],[-120.40805099999994,71.72387700000007],[-120.40055799999993,71.71943700000008],[-120.37998999999996,71.69970700000005],[-120.37748699999992,71.69413800000007],[-120.37693799999994,71.68803400000007],[-120.380829,71.68193100000008],[-120.43611099999998,71.61192299999993],[-120.473053,71.56553600000007],[-120.49665799999997,71.54414400000002],[-120.54332699999992,71.516663],[-120.60166900000002,71.49359100000004],[-120.63639799999999,71.48553500000014],[-120.78028899999998,71.45721400000008],[-120.80750299999988,71.45248400000003],[-120.87721299999998,71.44136000000015],[-120.921944,71.43553200000002],[-121.13333099999994,71.40942400000006],[-121.33249699999993,71.386932],[-121.39444700000001,71.38026400000001],[-121.42916899999994,71.37831100000005],[-121.44833399999999,71.37942500000003],[-121.59056099999998,71.39637800000014],[-121.60305799999998,71.399429],[-121.59137699999991,71.40277100000009],[-121.57611099999997,71.40443400000004],[-121.54915599999993,71.40914900000007],[-121.53751399999999,71.41249099999999],[-121.53195199999993,71.417755],[-121.52861000000001,71.42387400000001],[-121.531677,71.42942799999997],[-121.53694200000001,71.43441800000005],[-121.54998799999993,71.44358800000009],[-121.56973299999999,71.45166000000006],[-121.59638999999999,71.45694000000015],[-121.63027999999991,71.46054099999998],[-121.66860999999994,71.46276899999998],[-121.70361300000002,71.46081500000014],[-121.74388099999999,71.45332300000001],[-121.75556899999998,71.45027199999998],[-121.77639799999997,71.44303899999994],[-121.81220999999994,71.4266510000001],[-121.82917800000001,71.41832],[-121.84612299999998,71.40971400000006],[-121.901947,71.3785860000001],[-121.96528599999999,71.34275800000006],[-122.07501199999996,71.28692600000005],[-122.12165799999991,71.26721199999997],[-122.14417300000002,71.26081799999992],[-122.21056399999986,71.24832200000003],[-122.25446299999999,71.24247700000012],[-122.29833999999994,71.23637400000001],[-122.35526999999996,71.22776800000008],[-122.43028299999997,71.21415700000011],[-122.50556899999992,71.19775400000003],[-122.593887,71.17804000000012],[-122.60500299999995,71.17498800000004],[-122.61638600000003,71.17164600000007],[-122.64584400000001,71.16053800000009],[-122.66221599999994,71.15193199999999],[-122.67832900000002,71.14332600000006],[-122.7069469999999,71.12442000000004],[-122.74249299999997,71.101089],[-122.76999699999988,71.08915700000006],[-122.781113,71.08610499999992],[-122.79611199999988,71.08415200000002],[-122.84944199999995,71.0816650000001],[-123.07611099999986,71.07916300000005],[-123.09500099999997,71.07998700000002],[-123.1260989999999,71.08387800000008],[-123.162781,71.09275800000012],[-123.22332799999998,71.11415099999999],[-123.25945300000001,71.12970000000013],[-123.29305999999985,71.14610299999998],[-123.31696299999999,71.15859999999998],[-123.37027,71.18887300000011],[-123.3952789999999,71.20776399999994],[-123.42999299999997,71.2369230000001],[-123.44860799999998,71.25776700000011],[-123.46640000000002,71.28553799999997],[-123.51390099999998,71.34915200000006],[-123.56696299999993,71.40609699999993],[-123.63417099999992,71.47248799999994],[-123.66583299999996,71.49636800000013],[-123.67971799999998,71.50526400000007],[-123.84388699999994,71.58332800000011],[-123.88722200000001,71.62359599999996],[-123.89917000000003,71.63304100000005],[-123.94888299999997,71.65832500000005],[-123.97582999999997,71.6702580000001],[-124.01334400000002,71.68580600000007],[-124.02390300000002,71.68914800000005],[-124.07055700000001,71.70193500000005],[-124.11138900000003,71.70999100000012],[-124.13694800000002,71.71443200000004],[-124.38474299999996,71.75471500000009],[-124.458054,71.76638800000012],[-124.609734,71.78804000000014],[-124.65278599999994,71.79525799999999],[-124.678879,71.80081200000012],[-124.700287,71.80636600000014],[-124.83194700000001,71.84082000000001],[-124.86665299999993,71.85054000000008],[-125.07694999999995,71.90914900000013],[-125.16000400000001,71.92468300000007],[-125.23638900000003,71.94191000000006],[-125.24722300000002,71.94551100000012],[-125.25361599999997,71.95025599999997],[-125.24472000000003,71.95442200000008],[-125.04804999999999,71.95553600000005],[-124.98029300000002,71.94358799999998],[-124.96945199999999,71.93997200000013],[-124.953888,71.93803400000002],[-124.94275699999997,71.93997200000013],[-124.93804899999998,71.94552599999992],[-124.93554699999999,71.95165999999995],[-124.93971299999998,71.95694000000003],[-124.94833399999999,71.96110500000003],[-124.98777799999999,71.96971100000013],[-125.02278100000001,71.97250400000013],[-125.23277300000001,71.97552499999995],[-125.35221899999999,71.97468600000002],[-125.41639700000002,71.97413599999999],[-125.47833300000002,71.97276300000004],[-125.59111000000001,71.96638500000012],[-125.62666299999995,71.96360800000002],[-125.68639399999995,71.95498700000007],[-125.72165699999994,71.9522090000001],[-125.76139799999993,71.95082100000002],[-125.80139199999996,71.9522090000001],[-125.93582199999992,71.95860299999998],[-125.97361799999999,71.96054100000009],[-125.984444,71.96388200000013],[-125.99333200000001,71.96804800000001],[-125.997772,71.97360200000003],[-125.99333200000001,71.9788670000001],[-125.97778299999999,71.97970600000002],[-125.966949,71.97637900000012],[-125.90055799999999,71.96249400000005],[-125.88054699999992,71.96331800000002],[-125.8497309999999,71.96720900000008],[-125.80999799999995,71.97554000000014],[-125.787781,71.98220800000013],[-125.77887699999991,71.98637400000001],[-125.765289,71.99609400000008],[-125.75418100000002,72.006104],[-125.74082899999996,72.02275100000003],[-125.73388699999998,72.034134],[-125.724716,72.0519260000001],[-125.71777299999985,72.07054099999999],[-125.71528599999994,72.08360300000004],[-125.71528599999994,72.09027099999997],[-125.71749899999992,72.09637500000002],[-125.72165699999994,72.10192900000004],[-125.72833299999996,72.10664400000007],[-125.73944099999989,72.1102600000001],[-125.714447,72.15748599999995],[-125.57389799999993,72.24746700000014],[-125.51445000000001,72.29107699999997],[-125.46777299999997,72.3510740000001],[-125.43221999999997,72.40358000000003],[-125.43666099999996,72.40913400000005],[-125.30055199999993,72.48330700000002],[-125.29110699999995,72.48718300000007],[-125.27971600000001,72.49052400000011],[-125.25787399999996,72.49512500000014],[-125.247772,72.49523899999997],[-125.17194399999994,72.51359600000006],[-125.1394499999999,72.52413899999999],[-125.02806099999998,72.56607100000008],[-125,72.60525499999994],[-124.94055199999997,72.70248400000014],[-124.9719389999999,72.755829],[-125.02610800000002,72.82109100000008],[-124.95916699999998,72.85636900000009],[-124.89334100000002,72.87387100000012],[-124.87917299999998,72.876373],[-124.801941,72.88749700000005],[-124.76695299999994,72.89082300000013],[-124.72749299999987,72.88859600000006],[-124.68804899999986,72.88749700000005],[-124.66944899999993,72.88888499999996],[-124.63667299999997,72.89276100000006],[-124.60611,72.89721699999996],[-124.591949,72.89999400000005],[-124.49722300000002,72.91970799999996],[-124.48554999999999,72.92303500000008],[-124.47582999999997,72.92720000000008],[-124.473053,72.93331899999993],[-124.49305700000002,72.97164900000007],[-124.49722300000002,72.97720300000003],[-124.62138399999992,73.00138900000013],[-124.71250899999995,73.00387600000005],[-124.72609699999998,73.00665300000014],[-124.73777799999999,73.010269],[-124.76972999999992,73.02137800000008],[-124.82417299999992,73.04609700000003],[-124.83332799999994,73.05026200000003],[-124.84916699999997,73.059418],[-124.862503,73.06887800000004],[-124.86694299999994,73.07443200000006],[-124.86888099999999,73.08055100000007],[-124.86389200000002,73.08610500000009],[-124.79472399999992,73.13472000000013],[-124.78500400000001,73.13888500000013],[-124.71362299999987,73.149429],[-124.59916699999985,73.22776800000003],[-124.58640299999996,73.23803700000008],[-124.57389799999993,73.24832199999997],[-124.56360599999988,73.25915500000013],[-124.50805699999995,73.32638500000013],[-124.44583099999994,73.41110200000014],[-124.44055199999997,73.41665599999993],[-124.43306000000001,73.42137099999997],[-124.40556299999997,73.434143],[-124.30555699999991,73.4785920000001],[-124.29332699999998,73.48165900000004],[-124.252228,73.48359699999997],[-124.22833300000002,73.48332199999999],[-124.20916699999998,73.48165900000004],[-124.18998699999997,73.48165900000004],[-124.17304999999999,73.48359699999997],[-124.160553,73.48692300000005],[-124.07000699999998,73.54609700000009],[-124.041946,73.58221400000008],[-124.03888699999993,73.58692900000011],[-124.07167099999998,73.61775200000011],[-124.0786129999999,73.62275699999998],[-124.07611099999991,73.64305100000007],[-124.073059,73.64915500000012],[-124.06777999999991,73.65470900000014],[-124.05526700000001,73.65803499999998],[-123.94554099999993,73.68165600000003],[-123.86138899999997,73.69581599999998],[-123.83389299999999,73.70027200000004],[-123.774719,73.7644350000001],[-123.80471799999987,73.79693600000002],[-123.83833300000003,73.82110600000004],[-123.847778,73.82527199999993],[-123.93639399999995,73.84054600000002],[-123.95834399999995,73.84136999999998],[-123.98055999999991,73.84082000000012],[-124.01999699999999,73.83831800000007],[-124.06639100000001,73.83943200000004],[-124.08583099999998,73.841095],[-124.13417099999992,73.84832799999998],[-124.16306299999985,73.8541560000001],[-124.19860799999992,73.86469999999997],[-124.21749899999986,73.87275700000009],[-124.36860699999988,74.01443500000005],[-124.41166699999991,74.05636600000003],[-124.42666600000001,74.10971100000012],[-124.43415800000002,74.13443000000007],[-124.600281,74.26832600000006],[-124.61805699999996,74.26638800000012],[-124.66082799999992,74.26470899999993],[-124.68083200000001,74.26609800000011],[-124.69304699999986,74.26944000000003],[-124.77500900000001,74.31915299999997],[-124.784157,74.32998700000007],[-124.781387,74.33610499999998],[-124.77084400000001,74.34027100000009],[-124.75556899999992,74.342758],[-124.69722000000002,74.34721400000006],[-124.40471600000001,74.36914100000013],[-124.108612,74.39276100000012],[-123.89527899999996,74.39637800000008],[-123.85694899999987,74.39942900000011],[-123.676941,74.41832000000011],[-123.63834399999996,74.42137100000014],[-123.57444800000002,74.42414900000011],[-123.41887700000001,74.42831400000011],[-123.20584100000002,74.44303900000006],[-123.02250700000002,74.444702],[-122.68998699999992,74.45387299999999],[-122.43804899999998,74.46499599999993],[-122.33750900000001,74.47109999999998],[-122.118607,74.49192800000003],[-122.06610099999995,74.49803200000008],[-121.93859900000001,74.518326],[-121.766663,74.53970300000003],[-121.73000299999995,74.54332],[-121.65194699999995,74.54859899999997],[-121.61028299999992,74.55053700000013],[-121.56416300000001,74.55108600000005],[-121.51862299999993,74.54887400000001],[-121.31082200000003,74.53166199999998],[-121.25361599999997,74.52581800000013],[-121.13612399999994,74.50694300000004],[-121.08389299999993,74.49359099999998],[-121.05777,74.48664900000006],[-121.01112399999988,74.47221400000012],[-121.00222799999995,74.46775800000006],[-120.98998999999998,74.45803799999999],[-120.98055999999991,74.4474790000001],[-120.97693599999991,74.44192500000008],[-120.97556299999991,74.42970300000013],[-120.90638699999994,74.41526800000003],[-120.70584100000002,74.37359600000013],[-120.48166700000002,74.32998700000007],[-120.2172159999999,74.282486],[-120.14998600000001,74.27249100000006]],[[-97.65278599999999,74.45582600000006],[-97.67555199999998,74.45498700000013],[-97.69193999999999,74.45526100000006],[-97.70889299999999,74.45721400000002],[-97.777222,74.47637900000012],[-97.789444,74.47998000000001],[-97.79249599999991,74.48580900000002],[-97.781387,74.49720800000011],[-97.76861600000001,74.5080410000001],[-97.76167299999992,74.512497],[-97.75389099999995,74.51554899999996],[-97.61805700000002,74.55220000000003],[-97.53222700000003,74.60636900000009],[-97.51362599999999,74.61137400000013],[-97.47000100000002,74.62109400000003],[-97.445831,74.626083],[-97.42277499999994,74.62942499999991],[-97.40695199999993,74.62831100000011],[-97.389725,74.626373],[-97.36805699999996,74.62275699999998],[-97.35777299999995,74.62136800000013],[-97.29138199999994,74.60525500000011],[-97.26722699999993,74.59721400000001],[-97.26167299999992,74.59471100000007],[-97.256958,74.59054600000007],[-97.26194800000002,74.58387800000008],[-97.29998799999987,74.55137600000006],[-97.37609899999995,74.51165800000007],[-97.38751199999996,74.50637799999998],[-97.60638399999999,74.46192900000005],[-97.65278599999999,74.45582600000006]],[[-95.31111099999998,74.49775700000009],[-95.33139,74.49609399999997],[-95.35333299999996,74.49636800000007],[-95.45889299999999,74.49859600000002],[-95.48055999999991,74.5],[-95.52278100000001,74.50499000000008],[-95.60305799999992,74.51554899999996],[-95.66166699999997,74.52360500000003],[-95.69776899999994,74.52970900000003],[-95.71665999999999,74.53387499999997],[-95.80943299999996,74.55442799999997],[-95.84500099999997,74.56387300000006],[-95.862213,74.56999200000007],[-95.86639400000001,74.57415800000001],[-95.86054999999999,74.57916300000005],[-95.85749799999996,74.58055100000013],[-95.68249500000002,74.634995],[-95.653885,74.64221199999992],[-95.63806199999999,74.64332600000012],[-95.62416100000002,74.641663],[-95.628601,74.64082300000013],[-95.51750199999992,74.63026400000007],[-95.49749800000001,74.62719700000014],[-95.441101,74.613876],[-95.40360999999996,74.60331699999995],[-95.33444199999997,74.58082599999994],[-95.31777999999997,74.57388300000014],[-95.29194599999994,74.56025700000004],[-95.26028399999996,74.54054300000007],[-95.25111400000003,74.53414900000007],[-95.24499500000002,74.52777100000009],[-95.24638399999998,74.52165200000007],[-95.25111400000003,74.51609800000006],[-95.25917099999998,74.5105440000001],[-95.27111799999994,74.50555400000002],[-95.28944399999995,74.50138900000002],[-95.31111099999998,74.49775700000009]],[[-97.17582700000003,75.24414100000007],[-97.19444299999998,75.24275200000005],[-97.21611000000001,75.24470500000001],[-97.22500600000001,75.24803199999991],[-97.23194899999993,75.25444000000005],[-97.27806099999998,75.3435970000001],[-97.275284,75.347488],[-97.25805699999995,75.34942600000011],[-97.20861799999994,75.34220900000003],[-97.19055199999997,75.33526599999999],[-97.16166699999985,75.32222000000007],[-97.15306099999992,75.31526200000008],[-97.14889499999992,75.29776000000004],[-97.14695699999999,75.27998400000007],[-97.14750700000002,75.27388000000008],[-97.15583800000002,75.25526400000001],[-97.16166699999985,75.25000000000006],[-97.17582700000003,75.24414100000007]],[[-103.9175029999999,75.05497700000001],[-104.22917199999995,75.01805100000007],[-104.261124,75.01832600000012],[-104.45944199999991,75.02886999999998],[-104.662216,75.06248500000004],[-104.84722899999991,75.10914600000007],[-104.85722399999992,75.16470300000003],[-104.82000699999998,75.17776500000002],[-104.79998799999998,75.18942300000003],[-104.79305999999997,75.19470200000006],[-104.74472000000003,75.24609399999997],[-104.76862299999999,75.28193700000003],[-104.71083099999993,75.32222000000007],[-104.68222000000003,75.33776899999998],[-104.67360699999995,75.34166000000005],[-104.49722299999996,75.40637200000003],[-104.42804699999994,75.42082199999999],[-104.37777699999998,75.42804000000001],[-104.33000199999992,75.43304399999994],[-104.18222000000003,75.43553199999997],[-104.15177900000003,75.4345550000001],[-104.11416600000001,75.43026700000007],[-103.97112299999998,75.4044340000001],[-103.953056,75.3999940000001],[-103.935272,75.39498900000007],[-103.848053,75.36499000000003],[-103.81054699999993,75.34860200000014],[-103.74166899999994,75.28610200000003],[-103.587219,75.16998300000006],[-103.58306899999997,75.16470300000003],[-103.59028599999999,75.15942400000006],[-103.60888699999992,75.14915500000001],[-103.7302929999999,75.09999099999999],[-103.76390100000003,75.08888200000013],[-103.79943799999995,75.07748400000008],[-103.81777999999997,75.07249499999995],[-103.88999899999999,75.05831899999998],[-103.9175029999999,75.05497700000001]],[[-100.17223399999995,75.60137900000001],[-100.15722700000003,75.58943200000004],[-100.15778399999994,75.58499100000012],[-100.17639200000002,75.57998699999996],[-100.23332199999993,75.56915300000009],[-100.383331,75.55358899999999],[-100.45417800000001,75.54637100000002],[-100.47972099999993,75.54582200000004],[-100.47556299999997,75.54998799999998],[-100.45749699999999,75.55415299999999],[-100.43195299999991,75.55831900000004],[-100.40666199999987,75.56137099999995],[-100.36110699999995,75.56553599999995],[-100.31777999999986,75.57304399999998],[-100.30332900000002,75.57748400000003],[-100.29361,75.584427],[-100.30332900000002,75.58859300000006],[-100.31973299999999,75.59082000000012],[-100.33917199999996,75.59136999999998],[-100.36332699999997,75.59027100000003],[-100.52778599999994,75.57720899999998],[-100.74973299999994,75.55802900000003],[-100.86527999999998,75.54721100000006],[-100.88555899999994,75.54582200000004],[-100.90862300000003,75.54637100000002],[-100.950287,75.54971300000011],[-100.99445300000002,75.55497700000012],[-101.02333099999993,75.55998199999999],[-101.03333299999997,75.56303400000007],[-101.03943600000002,75.56721500000015],[-101.02583299999998,75.57054099999999],[-100.84277299999991,75.58692900000005],[-100.70249899999993,75.58888200000001],[-100.68055699999996,75.58943200000004],[-100.65583800000002,75.59165999999999],[-100.64167800000001,75.59610000000004],[-100.62027,75.60609400000004],[-100.59861799999999,75.61025999999993],[-100.51112399999994,75.61914100000007],[-100.39444700000001,75.62303199999997],[-100.27639799999997,75.62303199999997],[-100.23500099999995,75.62303199999997],[-100.21777299999997,75.621918],[-100.204453,75.61747700000006],[-100.19499200000001,75.61331200000006],[-100.17223399999995,75.60137900000001]],[[-94.36389200000002,75.59082000000012],[-94.32695000000001,75.57971199999997],[-94.24388099999993,75.54971300000011],[-94.20527599999991,75.52970900000003],[-94.01028399999996,75.44220000000007],[-93.98971599999999,75.4349820000001],[-93.83972199999994,75.38804600000003],[-93.74249299999997,75.3644260000001],[-93.49916099999996,75.2647090000001],[-93.48750299999995,75.25665300000003],[-93.49333199999995,75.24720799999994],[-93.52917500000001,75.17637600000006],[-93.48889200000002,75.07249499999995],[-93.43415799999997,74.966385],[-93.406387,74.88360599999999],[-93.45805399999995,74.7149960000001],[-93.46250899999995,74.70860299999993],[-93.46777299999997,74.70304899999996],[-93.48472600000002,74.68775900000014],[-93.49610899999999,74.68193100000002],[-93.53056300000003,74.66775500000006],[-93.56332399999997,74.65942400000012],[-93.69166599999994,74.63998400000014],[-93.71722399999987,74.63693200000006],[-93.741379,74.63554399999998],[-94.04028299999999,74.64082300000013],[-94.24999999999989,74.64637800000003],[-94.38806199999999,74.63526900000011],[-94.47111499999988,74.62664800000005],[-94.51194799999996,74.62330600000007],[-94.5475009999999,74.62136800000013],[-94.64334099999996,74.62359600000008],[-94.68777499999993,74.62831100000011],[-95.02471899999995,74.67303500000008],[-95.08000199999998,74.68081700000005],[-95.08583099999998,74.68719500000003],[-95.07694999999995,74.69747900000004],[-95.07278399999996,74.7022090000001],[-95.104446,74.74414100000013],[-95.26640299999991,74.79331999999994],[-95.28332499999999,74.79803499999997],[-95.29834,74.80026200000003],[-95.40333599999991,74.80386399999998],[-95.43415800000002,74.801376],[-95.45750399999997,74.79832499999998],[-95.479172,74.78804000000008],[-95.4830629999999,74.78332500000005],[-95.48277299999995,74.77943399999998],[-95.47555499999999,74.76998900000007],[-95.462219,74.75665300000014],[-95.54722600000002,74.76110799999998],[-95.62582399999991,74.80748000000006],[-95.70556599999998,74.82998700000013],[-95.7408289999999,74.82388300000008],[-95.77139299999993,74.82360800000009],[-95.86416600000001,74.82609600000006],[-95.959473,74.85636900000003],[-96.00250199999988,74.87275700000009],[-96.00666799999993,74.87692300000015],[-96.07722499999994,74.90277100000009],[-96.1352839999999,74.95109600000012],[-96.14167800000001,74.95721400000008],[-96.13694800000002,74.96304300000008],[-96.12470999999994,74.97581500000007],[-96.09472699999998,74.99136400000003],[-96.07084700000001,75.00193800000005],[-96.05638099999999,75.01026899999994],[-96.05555700000002,75.01609799999994],[-96.06054699999999,75.01944000000009],[-96.07417299999986,75.02360500000009],[-96.08306899999997,75.02442900000005],[-96.14222699999999,75.01776100000006],[-96.14750700000002,75.01361100000008],[-96.20083599999992,74.95471200000003],[-96.20333900000003,74.95166000000006],[-96.20666499999993,74.943039],[-96.20388799999995,74.93691999999993],[-96.20584099999996,74.92025799999999],[-96.20973200000003,74.91554300000013],[-96.22138999999999,74.91026300000004],[-96.24777199999988,74.90554800000001],[-96.26834100000002,74.9038700000001],[-96.31527699999998,74.90248100000008],[-96.337219,74.90359500000005],[-96.35749799999996,74.90664700000002],[-96.37361099999998,74.91026300000004],[-96.38722199999995,74.91470300000009],[-96.39666699999992,74.91970800000013],[-96.40306099999998,74.92581200000012],[-96.386124,74.97387700000013],[-96.35749799999996,74.97137500000008],[-96.341385,74.972488],[-96.32806399999998,74.9747010000001],[-96.32055700000001,74.97943099999998],[-96.31834399999997,74.98220800000007],[-96.32223499999986,75.00138900000007],[-96.3311159999999,75.00471500000015],[-96.47666900000002,75.0044400000001],[-96.50083899999993,75.00277700000004],[-96.523056,74.99914599999994],[-96.53388999999999,74.99470500000007],[-96.55972300000002,74.98609899999997],[-96.58029199999999,74.98414600000001],[-96.59999099999999,74.98332200000004],[-96.61416599999995,74.98498499999994],[-96.61694299999999,74.99108899999999],[-96.60472099999998,75.063309],[-96.57139599999994,75.10108900000012],[-96.46305799999993,75.19331399999993],[-96.45639,75.19693000000001],[-96.37860099999995,75.21665999999999],[-96.077789,75.27249100000006],[-95.94804399999998,75.2833250000001],[-95.92250099999995,75.28610200000003],[-95.90333599999991,75.28997800000008],[-95.91055299999994,75.29525799999999],[-95.93443300000001,75.29721100000012],[-95.97805800000003,75.29887400000001],[-96.02667199999996,75.29914900000006],[-96.04998799999993,75.29693600000007],[-96.061935,75.31526200000008],[-96.00361599999997,75.34304799999995],[-95.9324949999999,75.35304300000007],[-95.93471499999998,75.35017399999998],[-95.93472300000002,75.34776299999999],[-95.91999800000002,75.34693900000002],[-95.890289,75.349152],[-95.88744399999996,75.36026800000013],[-95.83677699999987,75.36992600000002],[-95.83078,75.37142900000003],[-95.82978100000003,75.37258900000012],[-95.83061199999986,75.37442800000002],[-95.83278699999994,75.37592300000011],[-95.848274,75.37843299999997],[-95.90677599999998,75.38742800000006],[-95.92777999999987,75.39804100000015],[-96.03332499999993,75.40109300000006],[-96.05526700000001,75.40081800000007],[-96.07888799999989,75.39610300000004],[-96.07917800000001,75.391098],[-96.083618,75.38554399999998],[-96.09973099999996,75.38026400000012],[-96.12609900000001,75.37692300000009],[-96.15110800000002,75.37498499999992],[-96.17527799999999,75.37942499999997],[-96.178879,75.38443000000001],[-96.16194199999995,75.39553799999999],[-96.14973399999991,75.40081800000007],[-96.13500999999997,75.40637200000003],[-96.0958399999999,75.41775500000006],[-96.0625,75.4249880000001],[-95.97416699999997,75.43609600000008],[-95.95834400000001,75.43637100000007],[-95.93638599999997,75.43414300000012],[-95.87416099999996,75.42387400000007],[-95.83104699999996,75.41531400000008],[-95.83254999999997,75.41365100000013],[-95.83322099999998,75.40998800000011],[-95.83104699999996,75.40698200000008],[-95.82588199999998,75.40332000000012],[-95.81438399999996,75.40032200000007],[-95.76955399999986,75.40032200000007],[-95.69110099999995,75.40525800000006],[-95.68249500000002,75.40832499999999],[-95.67610200000001,75.41581700000012],[-95.67832899999996,75.421921],[-95.68472300000002,75.42831400000011],[-95.691666,75.42970300000013],[-95.71583599999991,75.4291530000001],[-95.73416099999992,75.426086],[-95.75862099999995,75.42553700000002],[-95.781677,75.42804000000001],[-95.80055199999993,75.43165600000003],[-95.82501199999996,75.43997200000013],[-95.83000199999992,75.4433140000001],[-95.83694500000001,75.45359800000011],[-95.83805799999999,75.45915200000007],[-95.835556,75.46443199999999],[-95.83222999999998,75.4705350000001],[-95.82417299999997,75.47776799999991],[-95.80055199999993,75.49136400000009],[-95.76222200000001,75.50804100000005],[-95.74972500000001,75.51332100000013],[-95.47000099999997,75.56693999999999],[-95.27528399999994,75.59942600000005],[-95.26417500000002,75.59387200000009],[-95.23443600000002,75.58471700000001],[-95.212784,75.58248900000007],[-95.178604,75.584427],[-95.12470999999988,75.59526100000005],[-95.104172,75.60026600000009],[-95.09333800000002,75.60359199999999],[-95.08583099999998,75.60720800000001],[-95.08416699999998,75.60914600000012],[-95.07528699999995,75.61442600000004],[-95.06332399999991,75.61886600000003],[-95.04444899999987,75.62164300000012],[-94.91776999999996,75.63720700000005],[-94.90167200000002,75.63749700000005],[-94.74137899999994,75.62414600000011],[-94.55972299999996,75.6124880000001],[-94.511124,75.61109900000008],[-94.46556099999998,75.60832199999999],[-94.40417500000001,75.59915200000012],[-94.36389200000002,75.59082000000012]],[[-95.9100039999999,75.56025699999998],[-95.91111799999999,75.55415299999999],[-95.93472300000002,75.54054300000007],[-96.170837,75.4580380000001],[-96.22027600000001,75.45555100000007],[-96.23889200000002,75.45665000000002],[-96.25500499999998,75.46138000000008],[-96.39917000000003,75.51638800000006],[-96.41722099999998,75.52331500000014],[-96.42471299999994,75.52859500000005],[-96.45099599999998,75.52999100000005],[-96.44116199999996,75.53598799999997],[-96.4158329999999,75.54364800000013],[-96.41265900000002,75.54615000000001],[-96.41166699999991,75.54881999999998],[-96.41799200000003,75.55265800000006],[-96.43116799999996,75.55548900000002],[-96.44183299999997,75.55566400000009],[-96.45099599999998,75.55315400000006],[-96.50383799999992,75.53515600000003],[-96.50799599999993,75.53298200000012],[-96.51816599999995,75.526321],[-96.52516199999991,75.51932500000004],[-96.5536039999999,75.50888099999992],[-96.55221599999999,75.50332600000002],[-96.5494379999999,75.49720800000011],[-96.545547,75.49220300000007],[-96.54110700000001,75.48803700000013],[-96.53332499999993,75.48275799999999],[-96.51750199999992,75.47804300000013],[-96.50334199999998,75.47137499999997],[-96.500565,75.4649960000001],[-96.50418099999996,75.4602660000001],[-96.51194800000002,75.45582600000006],[-96.65834000000001,75.38859600000006],[-96.83361799999994,75.35247800000002],[-96.8511049999999,75.35026600000015],[-96.862213,75.35081500000013],[-96.87609899999995,75.35359199999999],[-96.93249499999996,75.376083],[-97.03083800000002,75.45443700000004],[-97.05305499999992,75.49220300000007],[-97.05305499999992,75.49720800000011],[-97.00695799999994,75.50833100000011],[-96.94082599999996,75.52165200000002],[-96.91361999999992,75.52638200000007],[-96.89167799999996,75.52916000000005],[-96.666946,75.55276500000002],[-96.469383,75.58842500000003],[-96.46655299999992,75.59193399999992],[-96.46772799999991,75.59909100000004],[-96.47005499999989,75.60226400000005],[-96.42250099999995,75.62359600000008],[-96.42443800000001,75.6355440000001],[-96.41500899999994,75.64694199999997],[-96.39639299999999,75.64999400000005],[-96.37971500000003,75.651093],[-96.34722899999991,75.65138200000013],[-96.335556,75.65081800000002],[-96.314438,75.6477660000001],[-96.241104,75.62997400000006],[-96.13333099999994,75.60664400000007],[-96.11582900000002,75.60386699999998],[-96.101944,75.60359199999999],[-96.02543600000001,75.60284400000006],[-95.95777899999996,75.58360300000004],[-95.93888900000002,75.57748400000003],[-95.92388899999997,75.57165500000002],[-95.91639700000002,75.56637599999999],[-95.9100039999999,75.56025699999998]],[[-96.954453,75.59553499999998],[-96.9750059999999,75.59471100000002],[-96.99665800000002,75.59776299999993],[-97.00500499999998,75.60443100000009],[-97.00195300000001,75.61080900000007],[-96.98860199999996,75.61804200000006],[-96.97860700000001,75.62303199999997],[-96.96083099999998,75.62747200000013],[-96.779449,75.6602630000001],[-96.75195299999996,75.66470300000009],[-96.72972099999998,75.66526799999997],[-96.720551,75.66415399999994],[-96.71583599999997,75.65998800000006],[-96.718887,75.6538700000001],[-96.722305,75.65295400000002],[-96.74027999999993,75.64694199999997],[-96.84916699999997,75.61331200000006],[-96.954453,75.59553499999998]],[[-96.5791779999999,75.7369230000001],[-96.69665500000002,75.73082],[-96.710556,75.73359700000009],[-96.71722399999999,75.73970000000003],[-96.67860399999995,75.77748100000002],[-96.666946,75.78665200000012],[-96.66082799999998,75.78942900000004],[-96.54110700000001,75.82221999999996],[-96.52528399999994,75.82638499999996],[-96.50750699999998,75.82832300000013],[-96.48443599999996,75.82720899999993],[-96.46806299999992,75.822495],[-96.45584100000002,75.81776400000007],[-96.45750399999997,75.801086],[-96.45916699999998,75.78942900000004],[-96.53971899999999,75.74331699999999],[-96.5536039999999,75.73858600000005],[-96.5791779999999,75.7369230000001]],[[-111.79998799999998,75.839157],[-111.823624,75.83859300000006],[-111.86582899999996,75.84054599999996],[-111.900284,75.84359699999999],[-111.91722099999993,75.84693900000013],[-111.92250100000001,75.85276799999997],[-111.91972399999997,75.85775799999999],[-111.90139799999997,75.86387600000012],[-111.85665899999992,75.867752],[-111.79972799999996,75.87109399999997],[-111.61305199999993,75.88192700000013],[-111.59528399999999,75.8827510000001],[-111.58306899999991,75.88192700000013],[-111.5786129999999,75.879974],[-111.58194699999996,75.87608300000011],[-111.59306300000003,75.87303200000008],[-111.62917299999992,75.85693400000002],[-111.64806399999998,75.85192899999998],[-111.75695799999994,75.84165999999993],[-111.79998799999998,75.839157]],[[-122.340843,75.86276199999998],[-122.36277799999999,75.8580320000001],[-122.39862099999993,75.85942100000011],[-122.66471899999993,75.89387499999998],[-122.69167299999998,75.90026900000004],[-122.693604,75.90220600000004],[-122.69554099999993,75.90803500000004],[-122.68277,75.911652],[-122.633331,75.91970800000007],[-122.58222999999998,75.92192100000005],[-122.53751399999993,75.922485],[-122.37917299999992,75.915817],[-122.35305800000003,75.9144290000001],[-122.337784,75.91137700000002],[-122.32833900000003,75.905823],[-122.32417299999997,75.899719],[-122.33473200000003,75.86914100000001],[-122.340843,75.86276199999998]],[[-121.09306299999997,75.72608900000006],[-121.1100009999999,75.72470099999998],[-121.14306599999992,75.72581500000013],[-121.27555799999993,75.74748199999999],[-121.28832999999997,75.75277700000004],[-121.28582799999998,75.75888100000009],[-121.27194199999997,75.77053799999999],[-121.26306199999993,75.77415499999995],[-121.11694299999999,75.79582199999999],[-121.04332699999992,75.80886800000013],[-121.02944899999989,75.81137100000012],[-121.01917299999997,75.81805400000007],[-121.01500699999997,75.82470700000005],[-121.00083899999993,75.85664400000002],[-120.99833699999988,75.867752],[-121.00695799999988,75.87970000000007],[-121.01363399999997,75.88472000000007],[-121.04222099999998,75.89414999999997],[-121.04750099999995,75.89999399999999],[-121.04250299999995,75.90554800000001],[-121.03859699999998,75.9083250000001],[-120.997772,75.92637600000006],[-120.98000300000001,75.92942799999997],[-120.87777699999998,75.93609600000013],[-120.86776700000001,75.92469800000015],[-120.86776700000001,75.91331500000013],[-120.86972000000003,75.88108799999998],[-120.87110899999993,75.87553400000013],[-120.88474300000001,75.844986],[-120.89835399999998,75.82582100000002],[-120.921112,75.80331400000011],[-120.93804899999998,75.79054300000001],[-120.99388099999993,75.75776700000011],[-121.01862299999993,75.74443100000013],[-121.03278399999994,75.73776200000009],[-121.05248999999992,75.7327580000001],[-121.09306299999997,75.72608900000006]],[[-95.79276999999996,75.899719],[-95.80943299999996,75.89471400000014],[-95.818893,75.90721100000007],[-95.82556199999999,75.91331500000013],[-95.84777799999989,75.92942799999997],[-95.862503,75.93609600000013],[-95.88249200000001,75.94108600000004],[-95.89695699999999,75.94775399999997],[-95.89999399999999,75.95387300000004],[-95.89083900000003,75.959427],[-95.86000100000001,75.96666000000005],[-95.79666099999997,75.97331200000008],[-95.770554,75.9749910000001],[-95.74694799999992,75.97387700000013],[-95.73582499999992,75.96832300000011],[-95.73693800000001,75.9624940000001],[-95.75195299999996,75.92747500000007],[-95.76194799999996,75.91609200000005],[-95.77972399999993,75.90498400000007],[-95.79276999999996,75.899719]],[[-94.40556300000003,75.75082400000008],[-94.5827789999999,75.74581900000004],[-94.629166,75.74609400000008],[-94.67610200000001,75.74775699999998],[-94.72084000000001,75.75387600000005],[-94.739441,75.75749200000007],[-94.77749599999993,75.76860000000005],[-94.79527299999995,75.77581800000007],[-94.80915799999997,75.78248600000006],[-94.82223499999998,75.79414400000007],[-94.89889499999992,75.91276599999998],[-94.90278599999999,75.91943400000014],[-94.90527299999997,75.92553700000008],[-94.90611299999995,75.93081699999999],[-94.904449,75.9369200000001],[-94.89527899999996,75.94220000000001],[-94.87998999999996,75.94552600000003],[-94.86555499999997,75.94747899999999],[-94.81361399999997,75.95054600000009],[-94.73777799999999,75.95220899999998],[-94.69972200000001,75.95555100000013],[-94.53832999999986,75.98609900000008],[-94.48194899999993,75.97442600000005],[-94.46694899999989,75.96859700000005],[-94.45333899999991,75.96192900000011],[-94.44972199999995,75.95526100000012],[-94.443604,75.93830900000012],[-94.42027299999995,75.86859099999998],[-94.41027799999995,75.86192299999999],[-94.37083399999995,75.84220900000008],[-94.32223499999998,75.81498699999997],[-94.30555700000002,75.80304000000001],[-94.28778099999994,75.78387500000002],[-94.28805499999999,75.77748100000002],[-94.291382,75.77221700000001],[-94.29695099999998,75.766388],[-94.31027199999994,75.76138300000014],[-94.32640099999998,75.75721700000008],[-94.35388199999994,75.75387600000005],[-94.40556300000003,75.75082400000008]],[[-103.137787,75.74275200000011],[-103.20667300000002,75.74275200000011],[-103.3011019999999,75.74470500000007],[-103.32389799999999,75.74720800000006],[-103.36888099999999,75.75387600000005],[-103.38082899999995,75.75943000000001],[-103.382767,75.76554900000002],[-103.31139399999995,75.80525200000005],[-103.07749899999999,75.89082300000007],[-103.05943300000001,75.89637800000014],[-103.03751399999993,75.90165700000011],[-103.01194799999996,75.9060970000001],[-102.98693800000001,75.90942400000006],[-102.69611399999997,75.94664],[-102.59889199999986,75.953598],[-102.52278099999995,75.95803800000004],[-102.43360899999999,75.96415700000006],[-102.291382,75.97720300000015],[-102.21749899999998,75.98553500000014],[-102.19138299999997,75.98969999999997],[-102.16471899999993,75.99054000000001],[-102.07861300000002,75.97137500000008],[-101.98916599999995,75.95082100000008],[-101.98332199999987,75.94581600000004],[-101.98860200000001,75.93441800000005],[-102.020554,75.92553700000008],[-102.09472700000003,75.911652],[-102.14639299999993,75.90332000000001],[-102.19638099999997,75.899719],[-102.29638699999998,75.89498900000012],[-102.31916799999999,75.89305100000001],[-102.346657,75.88943499999993],[-102.39417299999997,75.88081400000004],[-102.43055699999991,75.86998],[-102.44082600000002,75.86442599999998],[-102.44943199999994,75.85832199999993],[-102.45584099999996,75.85247800000013],[-102.46000699999996,75.84721400000012],[-102.47165699999988,75.81832900000006],[-102.48277300000001,75.80636600000003],[-102.49694799999992,75.79553199999998],[-102.50917099999998,75.78942900000004],[-102.54527300000001,75.77970900000014],[-102.59028599999994,75.77053799999999],[-102.61165599999998,75.76721199999997],[-102.636124,75.76470899999998],[-102.86638599999998,75.753601],[-103.015289,75.74720800000006],[-103.137787,75.74275200000011]],[[-122.81916799999999,76.06053200000008],[-122.78056300000003,76.05720500000012],[-122.68776700000001,76.05998200000005],[-122.66194200000001,76.05693100000002],[-122.64277599999997,76.05247500000013],[-122.630829,76.04664600000012],[-122.72501399999987,76.02360500000009],[-122.88194299999998,76.01110800000009],[-122.89250199999998,76.01361100000003],[-122.89611799999994,76.02693199999999],[-122.89222699999999,76.03109699999999],[-122.85082999999997,76.05720500000012],[-122.81916799999999,76.06053200000008]],[[-102.38999899999993,76.0836030000001],[-102.37554899999998,76.07916300000011],[-102.37138399999998,76.07916300000011],[-102.36805699999996,76.0772090000001],[-102.3563769999999,76.07582099999996],[-102.35333300000002,76.07388300000002],[-102.33889799999997,76.06944300000004],[-102.33249699999999,76.06553600000007],[-102.32167099999998,76.0535890000001],[-102.31639100000001,76.036926],[-102.31889299999989,76.03109699999999],[-102.319458,76.02470400000004],[-102.32972699999993,76.01582300000013],[-102.34388699999994,76.01026900000011],[-102.36582900000002,76.00582900000012],[-102.41665599999999,76.0002750000001],[-102.51722699999993,75.99108899999999],[-102.56777999999991,75.98553500000014],[-102.695267,75.97331200000008],[-102.71472199999988,75.97026100000005],[-102.73972299999997,75.96804800000012],[-102.79055800000003,75.96138000000013],[-102.81139399999995,75.95999099999995],[-102.93611099999998,75.94802900000002],[-103.01027699999997,75.94303899999994],[-103.08528099999995,75.93580600000013],[-103.15695199999993,75.92581200000012],[-103.21888699999994,75.9202580000001],[-103.26500699999997,75.9144290000001],[-103.28943600000002,75.91304000000014],[-103.339447,75.90803500000004],[-103.37998999999996,75.9060970000001],[-103.39639299999993,75.90443400000004],[-103.43305999999995,75.90332000000001],[-103.45333899999997,75.90165700000011],[-103.52443699999998,75.89888000000002],[-103.59277299999997,75.89721700000007],[-103.61332700000003,75.8955380000001],[-103.63474300000001,75.89109800000006],[-103.65556300000003,75.888596],[-103.6997219999999,75.887497],[-103.72332799999987,75.88916000000012],[-103.77111799999994,75.89637800000014],[-103.81166100000002,75.89942899999994],[-103.88806199999993,75.89804100000003],[-103.901947,75.89860499999998],[-103.91471899999993,75.90248100000008],[-103.91500899999994,75.90776099999994],[-103.91722099999993,75.91360500000013],[-103.92555199999998,75.91914400000013],[-103.93611099999998,75.924149],[-103.964722,75.93441800000005],[-103.97165699999994,75.93830900000012],[-103.94220699999994,75.9427490000001],[-103.901947,75.94386299999991],[-103.82556199999999,75.95082100000008],[-103.80248999999998,75.95387300000004],[-103.78527799999995,75.95748900000007],[-103.77139299999988,75.96304300000008],[-103.75834700000001,75.96666000000005],[-103.7083439999999,75.97248800000011],[-103.6877669999999,75.97387700000013],[-103.598343,75.97720300000015],[-103.57444799999996,75.97665400000005],[-103.55471799999998,75.97526600000015],[-103.5225069999999,75.97554000000008],[-103.49694799999997,75.97998000000007],[-103.474716,75.98525999999998],[-103.45694700000001,75.99081400000011],[-103.41306299999997,76.00166300000001],[-103.391388,76.00610400000011],[-103.36582899999996,76.00942999999995],[-103.34028599999988,76.01388499999996],[-103.31500199999999,76.01721200000009],[-103.29028299999999,76.01859999999999],[-103.26363399999997,76.01944000000009],[-103.22138999999993,76.01915000000002],[-103.196663,76.02053799999999],[-103.178879,76.02499400000005],[-103.15666199999993,76.03665200000006],[-103.13667299999992,76.04165600000005],[-103.120003,76.04332000000005],[-103.05110200000001,76.04359399999998],[-103.00639299999995,76.04470799999996],[-102.98110999999989,76.04693600000013],[-102.95556599999998,76.05026199999998],[-102.91555800000003,76.06025700000009],[-102.88971700000002,76.06442300000015],[-102.86833199999995,76.06694000000005],[-102.86028299999992,76.06666600000011],[-102.85582699999992,76.06776400000001],[-102.75666799999993,76.0730440000001],[-102.708618,76.07748400000008],[-102.68138099999999,76.07916300000011],[-102.65805099999994,76.08221400000014],[-102.60777299999995,76.08581499999997],[-102.53138699999994,76.08943199999993],[-102.46806300000003,76.09027100000009],[-102.42804699999999,76.08943199999993],[-102.40416699999997,76.08776900000004],[-102.39639299999999,76.08665500000006],[-102.38999899999993,76.0836030000001]],[[-118.31639100000001,75.57249500000006],[-118.35472099999993,75.55886800000002],[-118.58306900000002,75.49941999999999],[-118.60472099999998,75.49636800000007],[-118.7036129999999,75.50305200000008],[-118.72250400000001,75.50444000000005],[-118.82749899999999,75.53276100000011],[-118.87361099999998,75.547485],[-118.87777699999998,75.553314],[-118.92804699999999,75.56275900000009],[-118.95305599999995,75.56469700000002],[-119.08194700000001,75.56776400000012],[-119.130829,75.56693999999999],[-119.19695299999995,75.56248499999992],[-119.22250400000001,75.56526200000002],[-119.34028599999999,75.57943699999993],[-119.36749299999991,75.58415199999996],[-119.38333099999994,75.58915700000006],[-119.39527899999996,75.59471100000002],[-119.40583800000002,75.60054000000002],[-119.408051,75.60582000000011],[-119.40471600000001,75.61192300000005],[-119.39750700000002,75.6183170000001],[-119.37554899999998,75.63108800000003],[-119.27528399999994,75.67469800000003],[-119.18831599999987,75.70248400000008],[-119.11389200000002,75.72053500000004],[-118.95472699999999,75.778595],[-118.78888699999999,75.84304800000007],[-118.762787,75.85693400000002],[-118.75834699999996,75.86219800000003],[-118.75334199999992,75.86637900000011],[-118.71694899999994,75.8827510000001],[-118.61916399999996,75.91554300000007],[-118.58139,75.92498799999998],[-118.56388899999996,75.92858900000004],[-118.40444899999994,75.96081500000008],[-118.36776699999996,75.966385],[-118.34028599999999,75.96748400000001],[-118.19415300000003,75.96748400000001],[-118.16832699999998,75.96832300000011],[-118.15222199999994,75.97137500000008],[-118.13751200000002,75.97970599999996],[-118.13137799999998,75.98553500000014],[-118.13137799999998,75.99136399999998],[-118.12748699999992,75.9974820000001],[-118.10500299999995,76.02388000000008],[-118.08860800000002,76.0294340000001],[-118.07140400000003,76.03414900000013],[-118.03751399999987,76.03831500000001],[-117.99804699999993,76.03997800000013],[-117.95722999999992,76.04304500000006],[-117.93360899999993,76.04748500000005],[-117.89972699999998,76.05748],[-117.88971699999996,76.06080600000001],[-117.88500999999997,76.0660860000001],[-117.89138799999995,76.07222000000013],[-117.89277600000003,76.07748400000008],[-117.88612399999988,76.07971200000003],[-117.77887699999991,76.10859700000009],[-117.72609699999998,76.11554000000007],[-117.70694700000001,76.11720300000002],[-117.662216,76.11775199999994],[-117.64111299999996,76.11665299999999],[-117.62304699999999,76.1144260000001],[-117.51944700000001,76.099716],[-117.49166899999989,76.09498600000012],[-117.47138999999993,76.08888200000007],[-117.46389799999997,76.083054],[-117.48916600000001,76.04693600000013],[-117.57305899999994,75.98193400000008],[-117.681107,75.92109700000009],[-117.70445299999989,75.91693099999998],[-117.74694799999997,75.91081200000013],[-117.77555799999993,75.89888000000002],[-117.83833299999998,75.85998500000005],[-117.93721,75.78526299999999],[-117.94499199999996,75.77915999999999],[-117.95221700000002,75.771927],[-117.95638999999994,75.76582299999995],[-117.95638999999994,75.75999500000006],[-117.97138999999993,75.72886700000004],[-118.01583899999997,75.69941699999998],[-118.06221,75.68580600000001],[-118.096947,75.6785890000001],[-118.11389200000002,75.67387400000007],[-118.14277599999997,75.66387900000012],[-118.22193900000002,75.63388100000003],[-118.26363400000002,75.61692800000009],[-118.2675089999999,75.61285399999997],[-118.266953,75.60998500000011],[-118.26834099999991,75.59165999999999],[-118.31639100000001,75.57249500000006]],[[-78.92639199999996,75.875809],[-78.91416900000002,75.87303200000008],[-78.9041749999999,75.86720300000007],[-78.88137799999998,75.85331700000006],[-78.87666300000001,75.84915200000006],[-78.87943999999993,75.84414700000002],[-78.89778100000001,75.83970600000009],[-78.921112,75.83749400000005],[-79.04888900000003,75.836929],[-79.06777999999997,75.84027100000014],[-79.07278399999996,75.84443700000003],[-79.06861899999996,75.8483280000001],[-79.05749499999996,75.85331700000006],[-79.04249599999991,75.8580320000001],[-79.02166699999992,75.86747700000001],[-79.03167699999995,75.8708190000001],[-79.05471799999998,75.87275700000004],[-79.26889,75.87525900000014],[-79.31945799999994,75.87359600000002],[-79.34306300000003,75.87109399999997],[-79.36138900000003,75.86692800000003],[-79.40833999999995,75.85276799999997],[-79.42027300000001,75.84803800000009],[-79.42805499999997,75.84248400000013],[-79.45861799999994,75.81080600000007],[-79.59805299999994,75.86137400000007],[-79.62027,75.86276199999998],[-79.70584099999996,75.86053500000008],[-79.726944,75.86109900000002],[-79.73999000000003,75.86442599999998],[-79.75222799999989,75.8785860000001],[-79.58000199999998,75.94525100000004],[-79.56750499999998,75.94914200000011],[-79.39695699999999,76.00193800000005],[-79.375,76.00555400000007],[-79.27278099999995,76.02804599999996],[-79.13778699999995,76.0772090000001],[-79.12971499999998,76.082764],[-79.12193299999996,76.088593],[-79.11305199999993,76.10054000000014],[-79.09138499999989,76.1144260000001],[-79.081955,76.11637900000005],[-78.92388899999997,76.12109400000008],[-78.9041749999999,76.11970500000007],[-78.89306599999998,76.11554000000007],[-78.82167099999992,76.09832800000004],[-78.80583200000001,76.09304800000001],[-78.79804999999988,76.08638000000002],[-78.79916400000002,76.07998700000007],[-78.82583599999992,76.05802900000009],[-78.83389299999999,76.05247500000013],[-78.845551,76.04748500000005],[-78.86138900000003,76.04332000000005],[-78.92166099999992,76.03193700000003],[-78.99861099999998,76.01499899999999],[-79.06973299999993,75.99832200000014],[-79.08500700000002,75.99386600000008],[-79.14472999999998,75.97526600000015],[-79.15611299999995,75.96998600000006],[-79.16665599999993,75.96415700000006],[-79.17193600000002,75.95887800000008],[-79.17639200000002,75.95277400000003],[-79.17694099999994,75.94636500000001],[-79.17443799999995,75.93942300000009],[-79.16833500000001,75.93193100000013],[-79.14028899999994,75.91886899999997],[-79.11193800000001,75.91026300000004],[-79.029449,75.88832100000013],[-79.01028400000001,75.88472000000007],[-78.98944099999994,75.88192700000013],[-78.943604,75.87803600000007],[-78.92639199999996,75.875809]],[[-94.843613,76.12220800000006],[-94.83111600000001,76.09664900000007],[-94.87027,76.06887799999998],[-94.88917500000002,76.05802900000009],[-94.90556299999992,76.05386400000009],[-94.92860399999995,76.05108600000011],[-95.00666799999999,76.04748500000005],[-95.02722199999994,76.0477600000001],[-95.04888899999997,76.05081200000001],[-95.06249999999994,76.05609099999998],[-95.08639499999992,76.06805400000002],[-95.10194399999995,76.07777400000009],[-95.139725,76.10775799999993],[-95.14416499999993,76.11192299999993],[-95.14723200000003,76.11692799999997],[-95.14639299999999,76.118042],[-95.12110899999999,76.1185910000001],[-95.09445199999999,76.11360200000013],[-95.07694999999995,76.1083220000001],[-95.06054699999999,76.10582],[-95.03056299999997,76.10470600000002],[-95.01306199999993,76.10582],[-94.99276700000001,76.10942100000005],[-94.854446,76.13665800000001],[-94.843613,76.12220800000006]],[[-81.327789,76.14721700000001],[-81.33860799999997,76.14637800000008],[-81.45249899999988,76.15582299999994],[-81.46250899999995,76.15887500000008],[-81.456955,76.16360500000008],[-81.41583300000002,76.17692600000004],[-81.37805199999997,76.184418],[-81.34889199999998,76.1874850000001],[-81.29444899999993,76.18775900000003],[-81.26722699999999,76.18775900000003],[-81.22166399999998,76.18553199999997],[-81.20333899999997,76.18109100000004],[-81.20140100000003,76.17776500000002],[-81.20861799999994,76.172211],[-81.30610699999988,76.15109300000012],[-81.327789,76.14721700000001]],[[-102.53083800000002,76.22331200000002],[-102.52722199999994,76.2169340000001],[-102.53138699999994,76.21165500000012],[-102.58056599999986,76.15248100000002],[-102.636124,76.12553400000007],[-102.65055799999999,76.11998000000011],[-102.67138699999998,76.1141510000001],[-102.73665599999998,76.09860199999997],[-102.78056300000003,76.08970600000004],[-102.80638099999999,76.08554100000003],[-102.85777300000001,76.0788730000001],[-102.93360899999999,76.07083100000011],[-103.34221599999995,76.03665200000006],[-103.36472300000003,76.03581200000002],[-103.67999299999997,76.03414900000013],[-103.82000700000003,76.03137200000003],[-103.86638600000003,76.03082300000005],[-103.91443599999997,76.03166200000004],[-103.962219,76.03471400000012],[-103.97277799999995,76.03970300000009],[-103.92388899999997,76.04081700000006],[-103.87832599999996,76.04386900000003],[-103.86945299999996,76.04748500000005],[-103.88861099999997,76.049713],[-103.98332199999999,76.05720500000012],[-104.06054699999999,76.06219500000003],[-104.08677699999998,76.06053200000008],[-104.08743999999996,76.05819699999995],[-104.13082899999989,76.05636600000003],[-104.39111300000002,76.07832300000007],[-104.40833999999995,76.08221400000014],[-104.47833300000002,76.13581799999997],[-104.48277299999995,76.14221199999997],[-104.46389799999992,76.15887500000008],[-104.45417800000001,76.16442900000004],[-104.31582600000002,76.20803799999999],[-104.29804999999993,76.21249400000005],[-104.27250700000002,76.21609500000011],[-104.24722300000002,76.21859699999999],[-104.17223399999995,76.22415200000012],[-104.14806399999986,76.2227630000001],[-104.07472200000001,76.22221399999995],[-103.9569469999999,76.23304700000011],[-103.91805999999997,76.23997500000013],[-103.85138699999999,76.25000000000006],[-103.59445199999999,76.26527400000009],[-103.33693699999998,76.27998400000007],[-103.13137799999993,76.30304000000007],[-103.11000100000001,76.30470300000002],[-103.05999799999995,76.30636600000014],[-102.86472299999997,76.31109599999996],[-102.81696299999999,76.31219499999997],[-102.765556,76.311646],[-102.72693599999997,76.30581699999999],[-102.66915899999992,76.2958220000001],[-102.66555799999998,76.29470800000013],[-102.65222199999994,76.28776600000003],[-102.64277599999997,76.26998900000012],[-102.633621,76.25749199999996],[-102.62554899999992,76.251938],[-102.6036069999999,76.24552900000009],[-102.55832700000002,76.23580900000002],[-102.54055799999998,76.22943100000009],[-102.53083800000002,76.22331200000002]],[[-89.39889499999998,76.43553200000008],[-89.425003,76.43553200000008],[-89.59916699999997,76.44026200000013],[-89.61361699999998,76.44081100000005],[-89.62554899999998,76.444977],[-89.615005,76.449142],[-89.55915800000002,76.4705350000001],[-89.53306599999996,76.47665400000011],[-89.49499499999996,76.47248800000006],[-89.48832700000003,76.46804800000001],[-89.46583599999991,76.46220399999999],[-89.44638099999992,76.457764],[-89.40834000000001,76.45054600000014],[-89.38612399999994,76.44775400000009],[-89.37805199999997,76.44413800000001],[-89.38055399999996,76.43914799999999],[-89.39889499999998,76.43553200000008]],[[-83.962784,76.42637599999995],[-83.98611499999998,76.42330900000002],[-84.00917099999992,76.42581200000001],[-84.10943600000002,76.44442700000013],[-84.12388599999997,76.451096],[-84.13944999999995,76.50721700000008],[-84.12805200000003,76.50999500000006],[-84.0975039999999,76.50665300000014],[-84.01362599999993,76.49803200000002],[-83.99249299999985,76.49498000000011],[-83.976944,76.49108900000004],[-83.91833499999996,76.46943700000003],[-83.90805099999994,76.4649960000001],[-83.962784,76.42637599999995]],[[-104.053879,76.56303400000007],[-104.03388999999999,76.559708],[-103.87888299999997,76.57360800000009],[-103.86860699999994,76.579163],[-103.86665299999993,76.58499100000012],[-103.87138400000003,76.59664900000013],[-103.86721799999998,76.60304300000001],[-103.85944399999994,76.60720800000001],[-103.82640100000003,76.61831700000005],[-103.804169,76.62191800000011],[-103.78751399999993,76.62052900000015],[-103.58194699999996,76.54775999999998],[-103.58805799999993,76.54193099999998],[-103.59249899999998,76.53581200000013],[-103.59166700000003,76.53137200000009],[-103.587784,76.52499399999994],[-103.57028199999996,76.5211030000001],[-103.404449,76.49470500000012],[-103.38445299999995,76.49220300000002],[-103.321121,76.49498000000011],[-103.24500299999994,76.48553500000003],[-103.05777,76.457764],[-103.03666699999991,76.4538730000001],[-103.01418299999995,76.44775400000009],[-103.0080569999999,76.44165000000004],[-103.00446299999999,76.43525700000009],[-103.00446299999999,76.42997700000001],[-103.011124,76.42330900000002],[-103.01917300000002,76.41804500000006],[-103.0297159999999,76.41249100000005],[-103.0425029999999,76.40637200000003],[-103.098343,76.38472000000002],[-103.17250099999995,76.36276200000003],[-103.20472699999993,76.35470599999996],[-103.281387,76.33692900000011],[-103.37805200000003,76.32554600000009],[-103.55444299999999,76.31025700000004],[-103.70056199999993,76.30415299999999],[-103.75195299999996,76.30358900000004],[-103.848343,76.31025700000004],[-104.06194299999993,76.31749000000002],[-104.11165599999998,76.31637600000005],[-104.33500699999996,76.318604],[-104.37888299999992,76.32331799999997],[-104.396118,76.32777400000003],[-104.40471599999995,76.33332800000005],[-104.404449,76.334427],[-104.38971700000002,76.34275800000012],[-104.37581599999993,76.34832800000004],[-104.362213,76.35220299999997],[-104.34333799999996,76.3541560000001],[-104.32972699999999,76.35803200000004],[-104.328056,76.363876],[-104.39111300000002,76.46110500000003],[-104.43388399999998,76.484985],[-104.44888300000002,76.49108900000004],[-104.47332799999998,76.49331699999999],[-104.48249800000002,76.49054000000012],[-104.483612,76.48580899999996],[-104.49749800000001,76.48109399999993],[-104.52278100000001,76.480545],[-104.56388900000002,76.48220800000013],[-104.65888999999987,76.54582200000004],[-104.66583300000002,76.55165100000005],[-104.63722200000001,76.60331700000012],[-104.56304899999998,76.61276199999998],[-104.53666699999997,76.61720300000007],[-104.445267,76.63581800000003],[-104.40666199999987,76.6455380000001],[-104.37416100000002,76.65582300000005],[-104.35193600000002,76.66026300000004],[-104.31500199999994,76.66387900000012],[-104.26750199999998,76.66720600000002],[-104.21665999999999,76.66832000000005],[-104.13417099999998,76.66943400000002],[-104.05332899999996,76.66470300000009],[-104.031113,76.66165200000006],[-103.96333299999998,76.64999400000005],[-103.93971299999998,76.64471400000014],[-103.926941,76.63804600000014],[-103.9225009999999,76.63360599999999],[-103.92610200000001,76.62191800000011],[-103.93831599999999,76.61053500000014],[-103.95861799999994,76.59915200000012],[-104.02778599999988,76.579163],[-104.051941,76.56887800000004],[-104.053879,76.56303400000007]],[[-98.41805999999991,76.66832000000005],[-98.403885,76.66137700000002],[-98.41393999999991,76.64749100000006],[-98.42360699999995,76.64148699999993],[-98.42578099999997,76.63848900000005],[-98.42527799999999,76.63564300000013],[-98.429169,76.62692299999998],[-98.41972399999992,76.62248200000005],[-98.37609900000001,76.61192300000005],[-98.35777300000001,76.60832199999999],[-98.281387,76.60220300000015],[-98.18055700000002,76.58692900000005],[-98.18971299999998,76.58027600000008],[-98.24276699999996,76.57165500000013],[-98.258621,76.57331800000009],[-98.27833599999997,76.58110000000005],[-98.29834,76.5852660000001],[-98.319458,76.58859300000006],[-98.36250299999995,76.59332300000011],[-98.395554,76.59443700000008],[-98.40194699999995,76.5919340000001],[-98.39889499999992,76.58137500000004],[-98.37805199999997,76.57222000000002],[-98.35777300000001,76.56553600000012],[-98.32278400000001,76.56109600000013],[-98.08056599999998,76.5310970000001],[-97.94444299999998,76.51805100000013],[-97.8977809999999,76.51582300000001],[-97.80777,76.5144350000001],[-97.76445000000001,76.51054400000004],[-97.75029,76.50694299999998],[-97.69332899999995,76.48776200000009],[-97.68472299999996,76.47164900000007],[-97.66221599999994,76.42526199999998],[-97.6625059999999,76.41943400000008],[-97.67027300000001,76.41499299999998],[-97.70695499999994,76.40554800000007],[-97.718887,76.40109300000006],[-97.72721899999999,76.39553799999999],[-97.731674,76.38998400000014],[-97.76139799999999,76.334991],[-97.728882,76.282761],[-97.7261049999999,76.27832000000006],[-97.699432,76.26666300000011],[-97.64805599999994,76.25027500000004],[-97.61054999999999,76.24220300000007],[-97.59167499999995,76.23692299999999],[-97.57556199999999,76.23136900000003],[-97.523056,76.20582600000012],[-97.51695299999994,76.19999700000005],[-97.50917099999998,76.188873],[-97.4949949999999,76.14888000000013],[-97.49444599999987,76.13888500000007],[-97.50306699999987,76.12747200000007],[-97.51777600000003,76.11914100000013],[-97.54249600000003,76.1083220000001],[-97.56332399999997,76.097488],[-97.58833300000003,76.080826],[-97.65638699999994,75.97276299999999],[-97.64750700000002,75.94442700000008],[-97.64555399999989,75.93887300000006],[-97.64222699999993,75.9327550000001],[-97.612503,75.9019320000001],[-97.597778,75.88943499999993],[-97.597778,75.84693900000013],[-97.6541749999999,75.79832499999998],[-97.66416900000002,75.79332000000011],[-97.693604,75.78581200000008],[-97.70750399999997,75.78332499999999],[-97.837219,75.76554900000002],[-97.91332999999997,75.75166300000006],[-97.93055700000002,75.74693300000001],[-97.93859899999995,75.74136400000003],[-97.87054399999994,75.73054499999995],[-97.82722499999988,75.7269290000001],[-97.69027699999987,75.72053500000004],[-97.42555199999998,75.69220000000007],[-97.40444899999994,75.68803400000013],[-97.38667299999997,75.68275499999999],[-97.37582399999985,75.67637600000012],[-97.36999500000002,75.6708220000001],[-97.368607,75.65942400000012],[-97.36915599999998,75.65332000000006],[-97.38473499999998,75.64332600000006],[-97.39445499999994,75.63832100000002],[-97.41000399999996,75.62081899999998],[-97.41194200000001,75.61554000000001],[-97.42388900000003,75.52859500000005],[-97.42250100000001,75.50637799999998],[-97.41749599999997,75.49470500000012],[-97.40139799999986,75.45860299999998],[-97.398056,75.45248400000014],[-97.37832600000002,75.43414300000012],[-97.34973099999996,75.419983],[-97.33056599999992,75.414154],[-97.29388399999999,75.40554800000007],[-97.28500399999996,75.40220599999998],[-97.2808379999999,75.39694199999997],[-97.29333499999996,75.39082300000013],[-97.30555700000002,75.39027400000003],[-97.32055700000001,75.391098],[-97.34167500000001,75.3938750000001],[-97.441666,75.41499299999998],[-97.46916199999998,75.4227600000001],[-97.48416099999992,75.42942800000009],[-97.49610899999999,75.44220000000007],[-97.49888599999997,75.469986],[-97.49665800000002,75.4785920000001],[-97.57362399999988,75.51304600000014],[-97.7119449999999,75.56666600000005],[-97.728882,75.57026700000006],[-97.74415599999998,75.57110600000004],[-97.76251199999996,75.56805400000013],[-97.81806199999988,75.54898100000014],[-97.82755299999991,75.545815],[-97.82705699999991,75.53981799999997],[-97.82172400000002,75.53732300000013],[-97.81156199999992,75.53515600000003],[-97.802055,75.53532400000006],[-97.801941,75.52442900000011],[-97.78999299999992,75.51887499999998],[-97.77416999999991,75.50833100000011],[-97.758896,75.49664300000006],[-97.74804699999987,75.48442100000011],[-97.74472000000003,75.47831700000006],[-97.74333200000001,75.47192400000012],[-97.74526999999995,75.4666600000001],[-97.75639299999995,75.46220400000004],[-97.78332499999988,75.45748900000001],[-97.80749499999996,75.45665000000002],[-97.83583099999998,75.46081500000003],[-97.84083599999985,75.4649960000001],[-97.84500100000002,75.469986],[-97.8556749999999,75.48448200000001],[-97.85600299999993,75.48748800000004],[-97.85800199999989,75.49464400000005],[-97.85916900000001,75.49798599999997],[-97.86983499999991,75.50116000000008],[-97.88233899999994,75.5034940000001],[-97.90834000000001,75.51332100000013],[-97.93249500000002,75.512497],[-97.95195000000001,75.50749200000013],[-98.041672,75.4833220000001],[-98.04333500000001,75.48136899999997],[-97.98554999999999,75.45721400000014],[-97.95750399999991,75.44720499999994],[-97.93331899999998,75.44802900000013],[-97.91111799999993,75.44609099999997],[-97.78277600000001,75.42831400000011],[-97.77471899999995,75.42303500000014],[-97.79361,75.41304000000002],[-97.80860899999993,75.40887500000002],[-97.9344329999999,75.40748600000006],[-97.98472600000002,75.40887500000002],[-98.00472999999988,75.41360500000008],[-98.02806099999992,75.41387900000001],[-98.01989000000003,75.40704299999999],[-98.0287249999999,75.40454100000011],[-98.03238699999991,75.40087900000015],[-98.02955600000001,75.39837599999998],[-98.02122500000002,75.39521000000002],[-97.96055599999994,75.38472000000002],[-97.92027299999995,75.38081399999993],[-97.90139799999992,75.37997400000006],[-97.88444500000003,75.37637300000006],[-97.872772,75.37081900000004],[-97.8766629999999,75.36499000000003],[-97.88778699999995,75.36053500000003],[-97.91027799999995,75.35664400000013],[-97.92639200000002,75.35554500000012],[-97.99055499999997,75.35582],[-98.04276999999996,75.35914600000001],[-98.07010700000001,75.36470000000003],[-98.07076999999998,75.36708800000008],[-98.07411200000001,75.36903399999994],[-98.08277900000002,75.37003300000003],[-98.1077729999999,75.371918],[-98.12471,75.36720299999996],[-98.13639799999999,75.3619230000001],[-98.141953,75.35664400000013],[-98.15361000000001,75.34553500000004],[-98.16528299999999,75.33415200000002],[-98.16471899999993,75.32916300000005],[-98.129166,75.30192599999998],[-98.120544,75.29776000000004],[-98.10139500000002,75.29193100000003],[-98.06471299999993,75.28581200000002],[-97.91305499999999,75.26415999999995],[-97.87388599999997,75.270264],[-97.75584399999991,75.22943100000009],[-97.74360699999994,75.2249910000001],[-97.73500100000001,75.20721400000002],[-97.73693799999995,75.2044370000001],[-97.75973499999998,75.188583],[-97.676941,75.16415400000005],[-97.62860099999989,75.15109300000012],[-97.60249299999992,75.14721700000007],[-97.59750399999996,75.14915500000001],[-97.60583499999996,75.15832500000005],[-97.61444099999989,75.16276600000015],[-97.61305199999998,75.16470300000003],[-97.597778,75.16470300000003],[-97.57861300000002,75.15887500000008],[-97.56777999999997,75.15248100000002],[-97.56750499999993,75.147491],[-97.58250399999991,75.137497],[-97.61944599999993,75.11859099999992],[-97.63999899999999,75.11637900000005],[-97.74694799999997,75.11164900000006],[-97.84388699999994,75.11026000000004],[-97.86250299999989,75.11109900000002],[-97.88137799999993,75.11692800000003],[-98.024719,75.16249099999993],[-98.033615,75.17164600000001],[-98.03443899999996,75.18165600000009],[-98.02694699999995,75.18719500000009],[-98.02027899999996,75.19664],[-98.01916499999999,75.20109600000006],[-98.02583300000003,75.21081500000008],[-98.04138199999989,75.216385],[-98.06166100000002,75.22026100000005],[-98.08528100000001,75.2227630000001],[-98.09861799999993,75.2227630000001],[-98.14666699999987,75.18081699999993],[-98.14666699999987,75.16387900000007],[-98.14555399999995,75.159988],[-98.136124,75.15416000000005],[-98.12138400000003,75.147491],[-98.08139,75.130539],[-98.03916900000002,75.11637900000005],[-98.02555799999993,75.11360199999996],[-98.00306699999993,75.11276199999992],[-97.98167399999994,75.11080900000002],[-97.966949,75.10415599999999],[-97.9472199999999,75.07998700000007],[-97.9388889999999,75.06971699999997],[-97.93859899999995,75.06498699999992],[-97.945831,75.026657],[-97.949997,75.02110300000004],[-97.9600069999999,75.01748700000013],[-97.98249799999991,75.01527399999998],[-98.00306699999993,75.01554900000002],[-98.02027899999996,75.01832600000012],[-98.10888699999998,75.02249100000012],[-98.25917099999992,75.0227660000001],[-98.276947,75.02221700000001],[-98.30027799999993,75.02110300000004],[-98.36971999999997,75.01443500000005],[-98.44444299999998,75.00499000000013],[-98.46833799999996,75.00305200000003],[-98.63473499999998,74.99247700000006],[-98.72389199999992,74.98942600000004],[-98.78500400000001,74.99498000000006],[-98.98500100000001,75.00000000000011],[-99.06695599999995,74.99636800000013],[-99.35444599999988,74.984421],[-99.37666299999995,74.98553499999997],[-99.39416499999999,74.98803700000008],[-99.406113,74.99331699999993],[-99.39361599999995,75.02720599999998],[-99.38751200000002,75.03776600000009],[-99.335556,75.0705410000001],[-99.29943799999995,75.092758],[-99.28195199999999,75.10276800000008],[-99.27694699999995,75.1080320000001],[-99.27223200000003,75.11581400000006],[-99.281387,75.12248199999999],[-99.308044,75.12248199999999],[-99.32583599999992,75.11831699999999],[-99.34056099999998,75.11303700000013],[-99.44554099999993,75.05831899999998],[-99.48249799999996,75.03776600000009],[-99.49665799999997,75.02638200000001],[-99.5,75.02053799999999],[-99.49610899999993,75.01470899999998],[-99.48028599999998,75.00915500000013],[-99.44554099999993,75.00387599999999],[-99.43249500000002,75.0002750000001],[-99.42721599999993,74.99636800000013],[-99.42639199999996,74.99136400000003],[-99.53860500000002,74.974152],[-99.56249999999994,74.97221400000006],[-99.60278299999999,74.97110000000004],[-99.61971999999997,74.97137500000008],[-99.70167500000002,74.97360200000014],[-99.99055499999992,74.984421],[-100.05722000000003,74.9869230000001],[-100.14584400000001,74.99108899999999],[-100.21056399999998,74.997208],[-100.25306699999993,75.00277700000004],[-100.34777799999995,75.0169370000001],[-100.36389200000002,75.02137800000003],[-100.38945000000001,75.03109700000005],[-100.39388999999994,75.03720100000004],[-100.396118,75.04359400000004],[-100.3975069999999,75.05554200000006],[-100.39723199999997,75.06666600000011],[-100.39472999999998,75.07832300000007],[-100.38583399999999,75.0955350000001],[-100.38054699999986,75.10192899999998],[-100.37805200000003,75.11331199999995],[-100.39806399999998,75.15860000000009],[-100.41221599999994,75.16804500000012],[-100.43250299999994,75.17359899999997],[-100.45333900000003,75.17720000000003],[-100.47693599999997,75.17942800000014],[-100.51112399999994,75.184143],[-100.528343,75.18775900000003],[-100.54444899999993,75.19303900000011],[-100.54695099999998,75.1994170000001],[-100.53859699999998,75.20471199999997],[-100.46333299999998,75.22360200000008],[-100.43859900000001,75.226654],[-100.41722099999998,75.22747800000013],[-100.32528699999995,75.23054500000006],[-100.30222299999997,75.23082000000011],[-100.27999899999998,75.22886699999998],[-100.24833699999999,75.22387700000007],[-100.22556299999997,75.22303799999997],[-100.031387,75.22692900000004],[-100.00778200000002,75.22804300000001],[-99.99055499999992,75.23136900000003],[-99.98777799999999,75.23609900000008],[-99.99526999999995,75.23997500000013],[-100.00945300000001,75.24220300000007],[-100.11945300000002,75.24859600000008],[-100.20333900000003,75.25332600000007],[-100.22609699999998,75.25416599999994],[-100.314438,75.25082400000002],[-100.354172,75.25166300000001],[-100.37554899999986,75.25526400000001],[-100.39388999999994,75.26026900000011],[-100.406113,75.26666300000011],[-100.40278599999999,75.27249100000006],[-100.33444199999991,75.274429],[-100.31166100000002,75.27720600000009],[-100.29387700000001,75.28137199999998],[-100.279449,75.28665200000006],[-100.25805700000001,75.29776000000004],[-100.24445299999996,75.30886800000002],[-100.25723299999993,75.31330899999995],[-100.28222699999992,75.31025700000004],[-100.33277900000002,75.30220000000008],[-100.35944399999994,75.299713],[-100.49999999999989,75.29248000000001],[-100.52306399999998,75.293045],[-100.60888699999998,75.30581700000005],[-100.62249799999995,75.30914300000006],[-100.76555599999989,75.34637500000008],[-100.77887699999991,75.35054000000008],[-100.76888999999994,75.35525500000011],[-100.67639199999996,75.37664800000005],[-100.652222,75.37858599999998],[-100.63305700000001,75.37803600000012],[-100.61805700000002,75.37664800000005],[-100.60221899999993,75.37359600000013],[-100.61833199999995,75.36886600000008],[-100.64389,75.36470000000003],[-100.67999299999997,75.3619230000001],[-100.69833399999993,75.35664400000013],[-100.68222000000003,75.35026600000015],[-100.63806199999999,75.34582500000005],[-100.61472299999997,75.34610000000009],[-100.59472699999998,75.347488],[-100.44748699999991,75.36998000000006],[-100.43277,75.37525900000003],[-100.4283289999999,75.38053900000011],[-100.44055200000003,75.38665800000012],[-100.56527699999998,75.422211],[-100.58444199999997,75.426376],[-100.60694899999999,75.42804000000001],[-100.67555199999993,75.42692600000004],[-100.71694899999989,75.4291530000001],[-100.723053,75.43248],[-100.697769,75.43637100000007],[-100.67331699999994,75.43858299999994],[-100.43388399999998,75.44581599999998],[-100.339722,75.4474790000001],[-100.27084400000001,75.44859300000007],[-100.17666600000001,75.449142],[-100.11138899999997,75.451096],[-100.06276700000001,75.45443700000004],[-100.01194800000002,75.46138000000008],[-100.00917099999992,75.46609500000011],[-100.01944700000001,75.46859699999999],[-100.10056299999997,75.4705350000001],[-100.19193999999999,75.467758],[-100.21528599999988,75.467758],[-100.30695300000002,75.47164900000007],[-100.30555699999996,75.47360200000003],[-100.12999000000002,75.52581800000013],[-100.03415699999988,75.52943399999998],[-99.96694899999994,75.53332500000005],[-99.84500099999997,75.540817],[-99.83139,75.54414400000013],[-99.83222999999998,75.54553200000004],[-99.84500099999997,75.547485],[-99.85638399999999,75.54803500000003],[-99.89999399999999,75.547485],[-99.94665500000002,75.54470800000007],[-99.99027999999998,75.54443400000014],[-100.03859699999998,75.549149],[-100.03943600000002,75.55415299999999],[-100.02806099999998,75.55720500000007],[-99.82362399999994,75.58415199999996],[-99.80055199999993,75.58665500000012],[-99.756393,75.58804300000003],[-99.73693800000001,75.5872040000001],[-99.71250899999995,75.58915700000006],[-99.67277499999994,75.60609400000004],[-99.66777000000002,75.61109900000008],[-99.68582199999997,75.613876],[-99.79083300000002,75.6166530000001],[-99.84056099999998,75.6124880000001],[-99.86305199999998,75.61442600000004],[-99.862503,75.61886600000003],[-99.82362399999994,75.651657],[-99.81750499999993,75.655258],[-99.78805499999993,75.65832499999993],[-99.45861799999994,75.67248500000005],[-99.22666900000002,75.67553700000013],[-99.20249899999999,75.67553700000013],[-99.08361799999994,75.67581200000001],[-99.03306600000002,75.67720000000008],[-98.98277300000001,75.68109099999998],[-98.92971799999992,75.68637100000001],[-98.90556299999992,75.68997200000007],[-98.88999899999999,75.69525100000004],[-98.891388,75.69914199999994],[-98.90777599999996,75.70471200000003],[-98.92582700000003,75.70748900000012],[-98.95028699999989,75.709991],[-98.97193900000002,75.71026600000005],[-99.329453,75.69525100000004],[-99.55749499999996,75.69192500000003],[-99.61999500000002,75.69413800000001],[-99.64389,75.69413800000001],[-99.7408289999999,75.69081100000005],[-99.84973100000002,75.67747500000007],[-100.031677,75.66442899999998],[-100.256393,75.651657],[-100.37332199999997,75.65470900000008],[-100.39723199999997,75.65443400000004],[-100.54028299999993,75.64553799999993],[-100.62888299999997,75.63472000000013],[-100.65416699999997,75.63165300000003],[-100.80471799999998,75.61499000000015],[-100.82972699999999,75.61303700000002],[-101.22556299999991,75.5874940000001],[-101.24916100000002,75.5872040000001],[-101.30638099999999,75.591095],[-101.37721299999993,75.59887700000013],[-101.38806199999999,75.60026600000009],[-101.471657,75.60220300000015],[-101.4955369999999,75.60192900000004],[-101.74944299999999,75.57443200000006],[-101.89835399999998,75.5560910000001],[-101.97250399999996,75.54832500000003],[-101.99638399999998,75.54721100000006],[-102.06723,75.54609700000009],[-102.13639799999993,75.553314],[-102.159157,75.55497700000012],[-102.20667300000002,75.553314],[-102.35193599999997,75.54220600000002],[-102.39916999999997,75.53720099999998],[-102.44860799999998,75.53054799999995],[-102.49916099999996,75.5211030000001],[-102.534157,75.51138300000002],[-102.67304999999999,75.51470900000004],[-102.86694299999999,75.601089],[-102.87805200000003,75.60775800000005],[-102.88194299999992,75.61331200000006],[-102.88390400000003,75.61914100000007],[-102.87777699999992,75.62469500000003],[-102.86054999999999,75.62831100000011],[-102.8125,75.63108800000003],[-102.79305999999991,75.63053900000006],[-102.70140100000003,75.62886000000003],[-102.68916299999995,75.6705320000001],[-102.58168,75.71276899999998],[-102.563606,75.718323],[-102.53888699999993,75.72137499999991],[-102.37748699999992,75.72915599999999],[-102.35193599999997,75.72915599999999],[-102.311394,75.72665400000011],[-102.26390100000003,75.72192400000006],[-102.16832699999992,75.70915200000007],[-102.15416700000003,75.7061000000001],[-102.07861300000002,75.688309],[-102.05776999999995,75.69081100000005],[-102.03666699999997,75.69413800000001],[-102.01862299999999,75.69941699999998],[-102.00917099999998,75.70304899999991],[-102.00805700000001,75.70498700000007],[-102.09166699999997,75.72192400000006],[-102.120003,75.77638200000001],[-102.10185200000001,75.78424799999999],[-102.09361299999989,75.79109199999999],[-102.112213,75.79359400000004],[-102.23277299999995,75.78665200000012],[-102.28222700000003,75.78193700000008],[-102.32668299999995,75.77998399999996],[-102.34388699999994,75.78193700000008],[-102.36609599999997,75.78997800000002],[-102.37165800000002,75.79582199999999],[-102.37332200000003,75.80165099999999],[-102.37082700000002,75.80748000000006],[-102.36250299999995,75.81805400000007],[-102.339447,75.83499100000006],[-102.31667299999998,75.84664900000013],[-102.29028299999993,75.85720800000013],[-102.26640299999997,75.86192299999999],[-102.16306299999997,75.87886000000003],[-102.13806199999993,75.88108799999998],[-101.864441,75.90220600000004],[-101.82640099999992,75.89833100000004],[-101.80526700000001,75.89193700000004],[-101.79943800000001,75.88665800000007],[-101.77194199999997,75.86859099999998],[-101.74833699999999,75.85914600000007],[-101.74109599999991,75.85693400000002],[-101.55638099999987,75.82110599999999],[-101.47028399999999,75.77221700000001],[-101.46888699999994,75.766388],[-101.45973199999997,75.76110799999992],[-101.43859900000001,75.75555400000013],[-101.41416899999996,75.75248700000003],[-101.301941,75.74609400000008],[-101.254997,75.74470500000007],[-101.24416400000001,75.74693300000001],[-101.23388699999998,75.75138900000013],[-101.20249899999993,75.76721199999997],[-101.18221999999997,75.77970900000014],[-101.23110999999994,75.77720599999998],[-101.328056,75.77442900000005],[-101.34777799999995,75.7749940000001],[-101.35555999999991,75.77943399999992],[-101.358612,75.78498800000011],[-101.35193599999991,75.79054300000001],[-101.34137699999997,75.79609700000003],[-101.326683,75.80165099999999],[-101.323624,75.80748000000006],[-101.32501200000002,75.81330900000006],[-101.33500700000002,75.8252720000001],[-101.34056099999992,75.83027600000003],[-101.35637700000001,75.84304800000007],[-101.36389199999996,75.8477630000001],[-101.37805199999997,75.85192899999998],[-101.39277600000003,75.85443100000003],[-101.40833999999995,75.85582000000005],[-101.42388900000003,75.85636900000003],[-101.48889199999996,75.85415600000005],[-101.52694699999995,75.85832199999993],[-101.537216,75.86137400000007],[-101.54638699999992,75.86747700000001],[-101.57917799999996,75.90860000000009],[-101.56500199999988,75.92970300000002],[-101.49665800000002,75.95498700000002],[-101.47778299999999,75.96026599999999],[-101.45221700000002,75.96360800000008],[-101.39417299999997,75.97554000000008],[-101.30915800000002,76.008331],[-101.30277999999987,76.01304600000003],[-101.31582599999996,76.01915000000002],[-101.33556399999992,76.020828],[-101.36971999999992,76.0169370000001],[-101.38249200000001,76.01081800000009],[-101.39195299999989,76.00054900000003],[-101.40833999999995,75.99552900000015],[-101.61721799999998,75.98082000000011],[-101.641953,75.97970599999996],[-101.67832900000002,75.97970599999996],[-101.68388399999998,75.98027000000008],[-101.728882,75.9874880000001],[-101.80638099999999,76.00749200000001],[-101.83249699999999,76.016663],[-101.84889199999992,76.02470400000004],[-101.89362299999993,76.06025700000009],[-101.90055799999999,76.06666600000011],[-101.90722700000003,76.07859800000006],[-101.90862299999998,76.08442700000006],[-101.90750099999997,76.09610000000009],[-101.902222,76.10775799999993],[-101.88861099999991,76.11914100000013],[-101.761124,76.17414899999994],[-101.71140300000002,76.184708],[-101.685272,76.18775900000003],[-101.60833699999995,76.19442700000002],[-101.53362299999998,76.20526100000006],[-101.48860200000001,76.21360800000002],[-101.46556099999998,76.21887200000003],[-101.39611799999989,76.24331700000005],[-101.38500999999997,76.24887100000007],[-101.387787,76.251938],[-101.44193999999993,76.24165300000004],[-101.49694799999992,76.23387100000008],[-101.69888299999997,76.21943700000008],[-101.74973299999999,76.21582000000012],[-101.77471899999995,76.21554600000002],[-102.051941,76.21360800000002],[-102.11444099999994,76.21554600000002],[-102.1330569999999,76.219986],[-102.14835399999998,76.226654],[-102.16583300000002,76.23831200000001],[-102.15972899999997,76.24304200000006],[-102.133621,76.24636800000007],[-102.08222999999998,76.25082400000002],[-102.06388899999996,76.25526400000001],[-102.05803700000001,76.25915500000008],[-102.001106,76.35276800000003],[-102.029449,76.3808140000001],[-102.051941,76.38638300000008],[-102.05332900000002,76.39221199999992],[-102.05082700000003,76.39804100000015],[-102.03999299999998,76.40359500000011],[-102.01862299999999,76.40942399999994],[-101.88583399999993,76.444977],[-101.86221299999994,76.45027200000004],[-101.80832699999996,76.45416300000011],[-101.78333299999991,76.45443700000004],[-101.671112,76.449142],[-101.45667300000002,76.43637100000007],[-101.43472300000002,76.43441800000011],[-101.41166699999997,76.43081700000005],[-101.31582599999996,76.41442899999998],[-101.30249000000003,76.40832499999999],[-101.29138199999994,76.401657],[-101.28362300000003,76.39610299999998],[-101.27667200000002,76.38943500000005],[-101.24027999999993,76.371643],[-101.22805800000003,76.36692800000014],[-101.20612299999993,76.36137400000013],[-101.13694799999996,76.35081500000007],[-101.06806899999998,76.33194000000015],[-101.05832700000002,76.3269350000001],[-101.09388699999994,76.283051],[-101.00446299999993,76.23776199999998],[-100.98111,76.2352600000001],[-100.92832899999996,76.22581500000001],[-100.91000399999996,76.22221399999995],[-100.86582900000002,76.21220400000004],[-100.783073,76.19108599999998],[-100.75110599999994,76.18220500000001],[-100.71056399999998,76.166382],[-100.63027999999991,76.13333100000006],[-100.43998699999992,76.105255],[-100.31582600000002,76.05137600000012],[-100.30943299999996,76.04803500000008],[-100.13166799999993,75.95248400000003],[-100.047234,75.91387900000007],[-99.98249800000002,75.89054899999991],[-99.88833599999998,75.88638300000002],[-99.75361599999991,75.90637200000015],[-99.73083499999996,75.91053800000003],[-99.71556099999998,75.91609200000005],[-99.67832899999996,75.93136600000014],[-99.587784,75.94999700000011],[-99.508621,75.95748900000007],[-99.48361199999994,75.95860300000004],[-99.45750399999997,75.96138000000013],[-99.44249000000002,75.96581999999995],[-99.439438,75.97053499999998],[-99.45461999999992,75.97480800000005],[-99.49444599999998,75.97360200000008],[-99.65777600000001,75.96138000000013],[-99.78527799999995,75.95138500000002],[-99.81111099999998,75.94831799999992],[-99.85943600000002,75.93525699999998],[-99.86332699999997,75.93553200000002],[-99.89862099999999,75.95027199999998],[-100.07749899999999,76.03887900000012],[-100.08249699999999,76.04386900000003],[-100.09221600000001,76.05497700000001],[-100.14222699999999,76.11219800000015],[-100.15278599999994,76.13247700000011],[-100.12499999999994,76.14888000000013],[-100.10388199999994,76.15332000000001],[-100.07167099999998,76.15582299999994],[-100.031113,76.15554800000012],[-100.01139799999999,76.15387000000004],[-99.86833200000001,76.13998400000003],[-99.73083499999996,76.11747700000012],[-99.68083200000001,76.1185910000001],[-99.65083299999998,76.12747200000007],[-99.60916099999997,76.13581799999997],[-99.556107,76.14166300000005],[-99.50222799999995,76.14610300000004],[-99.4830629999999,76.14694200000002],[-99.42971799999992,76.15387000000004],[-99.414444,76.15832500000005],[-99.42138699999992,76.16026299999999],[-99.445267,76.16137700000013],[-99.49888599999991,76.15776100000011],[-99.54888899999997,76.15332000000001],[-99.66805999999991,76.13970900000004],[-99.69305400000002,76.13859600000012],[-99.716949,76.13970900000004],[-99.87443499999989,76.17053199999998],[-99.91583300000002,76.18026700000007],[-99.94888299999997,76.18969700000014],[-100.15028399999994,76.1933140000001],[-100.17832900000002,76.19081100000011],[-100.20140099999998,76.18997200000001],[-100.22556299999997,76.19081100000011],[-100.43888900000002,76.21249400000005],[-100.47222899999991,76.22637899999995],[-100.49861099999998,76.23776199999998],[-100.51278699999989,76.24914600000005],[-100.514183,76.25416600000011],[-100.51112399999994,76.25972000000013],[-100.49944299999999,76.26527400000009],[-100.465012,76.27499399999999],[-100.43804899999998,76.2788700000001],[-100.41665599999999,76.28027299999997],[-100.36638600000003,76.28166199999998],[-100.26917300000002,76.27859500000005],[-100.18276999999995,76.27082800000011],[-100.111107,76.26638800000006],[-99.89555399999995,76.27470399999999],[-99.86999499999996,76.27581799999996],[-99.84472700000003,76.28027299999997],[-99.84861799999993,76.28387499999997],[-100.03859699999998,76.3188780000001],[-100.27722199999994,76.37858599999998],[-100.30166600000001,76.38275099999998],[-100.32362399999994,76.38415500000013],[-100.35056299999991,76.38443000000001],[-100.37444299999999,76.38275099999998],[-100.48137700000001,76.37387100000012],[-100.55332899999996,76.37109400000003],[-100.67360699999995,76.371918],[-100.69444299999998,76.3749850000001],[-100.95249899999999,76.47470099999998],[-100.97222899999997,76.48526000000004],[-100.98388699999992,76.49443099999996],[-100.98554999999993,76.499146],[-100.98249800000002,76.50499000000002],[-100.962784,76.510269],[-100.93943799999988,76.5144350000001],[-100.89277600000003,76.51944000000015],[-100.82972699999999,76.51971400000008],[-100.80526700000001,76.52221700000007],[-100.737213,76.5310970000001],[-100.72083999999995,76.54609700000003],[-100.72341899999998,76.55109400000015],[-100.72332799999992,76.55609100000004],[-100.71250899999995,76.56053199999997],[-100.65306099999992,76.57638500000002],[-100.45861799999994,76.61360200000001],[-100.383827,76.6275020000001],[-100.36389200000002,76.63108799999998],[-100.318893,76.6355440000001],[-100.21665999999988,76.64305100000001],[-100.19193999999999,76.64221200000009],[-100.05222300000003,76.63136300000002],[-99.981674,76.62220799999994],[-99.91111799999999,76.61303700000002],[-99.88500999999991,76.61053500000014],[-99.83778399999989,76.60859699999997],[-99.81138599999991,76.60971099999995],[-99.796112,76.61387599999995],[-99.79527299999995,76.61831700000005],[-99.770554,76.62776200000013],[-99.74194299999999,76.6327510000001],[-99.72582999999992,76.63472000000013],[-99.68443300000001,76.63333100000011],[-99.58833300000003,76.62387100000007],[-99.569458,76.62052900000015],[-99.36694299999994,76.52638200000007],[-99.25695799999994,76.4705350000001],[-99.260559,76.46470600000009],[-99.25527999999991,76.45359800000006],[-99.18443300000001,76.41581700000012],[-99.16361999999992,76.40914900000013],[-99.12332200000003,76.40081800000002],[-99.09999099999999,76.39804100000015],[-99.07972699999999,76.39721700000001],[-99.066101,76.39860500000009],[-99.06639100000001,76.4044340000001],[-99.08361799999994,76.4160920000001],[-99.11000100000001,76.42665099999999],[-99.11833200000001,76.43304400000011],[-99.13722199999995,76.45193499999999],[-99.133896,76.45665000000002],[-99.12249800000001,76.46110500000003],[-98.99415599999998,76.47109999999992],[-98.98083499999996,76.47164900000007],[-98.95527600000003,76.46914700000002],[-98.94694500000003,76.46304299999997],[-98.94804399999992,76.45277399999992],[-98.95028699999989,76.44636500000007],[-98.943604,76.44081100000005],[-98.92582700000003,76.43609600000002],[-98.90638699999988,76.43331899999998],[-98.882767,76.43136600000003],[-98.85777300000001,76.43136600000003],[-98.846115,76.43609600000002],[-98.85611,76.46388200000013],[-98.86527999999993,76.46914700000002],[-98.89862099999999,76.48109399999993],[-98.953888,76.499146],[-99.03805499999999,76.52970899999997],[-99.05055199999998,76.53610200000014],[-99.051941,76.53997800000002],[-99.02722199999994,76.60108899999994],[-98.99916099999996,76.60498000000001],[-98.97166399999998,76.60775800000005],[-98.86082499999992,76.61442599999998],[-98.71472199999994,76.61415099999999],[-98.61111499999998,76.6102600000001],[-98.58917200000002,76.61137400000007],[-98.56639100000001,76.61360200000001],[-98.53889499999997,76.61637900000011],[-98.51806599999998,76.62136800000007],[-98.511124,76.62525900000014],[-98.489731,76.6447070000001],[-98.48832699999997,76.65081800000002],[-98.54695100000004,76.6580350000001],[-98.5911099999999,76.66165200000006],[-98.59500099999997,76.65942400000012],[-98.59249899999998,76.6538700000001],[-98.59861799999999,76.651093],[-98.62304699999987,76.64721700000013],[-98.67443800000001,76.64387499999998],[-98.74444599999998,76.64387499999998],[-98.81416300000001,76.65359500000005],[-98.85110500000002,76.66165200000006],[-98.85777300000001,76.66387900000012],[-98.85583499999996,76.67025799999999],[-98.85249299999992,76.67164600000007],[-98.82139599999994,76.67692599999992],[-98.733612,76.68275499999999],[-98.71250900000001,76.68304400000005],[-98.50472999999994,76.68109099999992],[-98.48028599999992,76.67915299999999],[-98.43998699999997,76.67303500000008],[-98.41805999999991,76.66832000000005]],[[-99.99694799999997,76.734421],[-99.97639500000002,76.73359700000003],[-99.86999499999996,76.73637400000013],[-99.81945799999988,76.73831200000006],[-99.74833699999999,76.74275200000011],[-99.72083999999995,76.74581900000004],[-99.69387799999998,76.74775699999998],[-99.64639299999999,76.74803199999997],[-99.62249800000001,76.7452550000001],[-99.52888499999995,76.72554000000008],[-99.447769,76.7061000000001],[-99.43055699999996,76.69941699999993],[-99.43388399999998,76.69470200000012],[-99.52806099999998,76.67442299999999],[-99.556107,76.6705320000001],[-99.58168,76.67025799999999],[-99.626938,76.67303500000008],[-99.65777600000001,76.67776500000008],[-99.73332199999999,76.70248400000003],[-99.8883899999999,76.71865100000014],[-99.90022299999993,76.72015399999998],[-99.91555799999998,76.72015399999998],[-100.01112399999988,76.71914700000013],[-100.02999899999992,76.71582000000001],[-100.05139200000002,76.71554600000007],[-100.09750400000001,76.71720900000003],[-100.12138399999998,76.71971100000007],[-100.128601,76.72192400000006],[-100.12805199999997,76.72303800000003],[-100.10193599999997,76.74470500000007],[-100.08277899999996,76.74803199999997],[-100.05526700000001,76.75082400000008],[-100.03778099999988,76.75138900000013],[-99.99943499999995,76.75109900000007],[-99.97222899999991,76.747208],[-99.97500600000001,76.74247700000006],[-99.99415599999998,76.73915100000005],[-100.004997,76.73553500000003],[-99.99694799999997,76.734421]],[[-120.883621,76.73970000000003],[-120.886124,76.72859199999999],[-120.90334299999995,76.72387699999996],[-120.94499199999996,76.71775800000012],[-120.97000100000002,76.71666000000005],[-121.0908429999999,76.71887200000009],[-121.11749299999991,76.71971100000007],[-121.16000400000001,76.72331200000013],[-121.18110699999994,76.72720300000003],[-121.1847229999999,76.7310940000001],[-121.181671,76.73220800000007],[-121.15666199999998,76.73359700000003],[-121.12832600000002,76.73082],[-121.083618,76.72915599999993],[-121.05972300000002,76.73136900000009],[-121.05638099999999,76.73248300000006],[-121.01806599999998,76.75138900000013],[-120.99082900000002,76.75471500000015],[-120.97833300000002,76.75526400000007],[-120.91443599999997,76.754166],[-120.89083900000003,76.7497100000001],[-120.88474300000001,76.74552900000003],[-120.883621,76.73970000000003]],[[-101.38054699999992,76.55358899999999],[-101.40416699999997,76.55276500000002],[-101.45388799999989,76.5541530000001],[-101.54083300000002,76.56080600000007],[-101.56471299999993,76.56359900000007],[-101.62332199999992,76.57276899999994],[-101.68831599999999,76.58638000000008],[-101.57556199999999,76.61415099999999],[-101.52194199999991,76.62387100000007],[-101.38583399999993,76.64248700000007],[-101.31777999999991,76.64276100000001],[-101.21362299999993,76.65193199999999],[-101.05999800000001,76.68580599999996],[-101.04250300000001,76.69053600000001],[-101.03943600000002,76.69636500000001],[-101.04028299999993,76.70220900000004],[-101.03307299999994,76.70803800000004],[-101.00583599999993,76.71887200000009],[-100.983612,76.72470099999992],[-100.95749699999999,76.72915599999993],[-100.90249599999993,76.73637400000013],[-100.74388099999999,76.75332600000013],[-100.69193999999999,76.75471500000015],[-100.53443900000002,76.75721700000003],[-100.50917099999992,76.7563780000001],[-100.484734,76.75471500000015],[-100.26888999999989,76.73719800000009],[-100.248894,76.73471100000006],[-100.25917099999998,76.72859199999999],[-100.266663,76.72637900000007],[-100.29305999999997,76.72192400000006],[-100.297234,76.72192400000006],[-100.31723,76.71666000000005],[-100.48721299999988,76.68441800000005],[-100.761124,76.63581800000003],[-100.92304999999999,76.6102600000001],[-101.19275699999997,76.57138100000003],[-101.27390300000002,76.56080600000007],[-101.326683,76.55636600000008],[-101.38054699999992,76.55358899999999]],[[-89.93443299999996,76.47665400000011],[-89.978882,76.46971100000013],[-89.99972500000001,76.470261],[-90.04083300000002,76.47692899999993],[-90.08168,76.484985],[-90.15110800000002,76.50443999999999],[-90.18443300000001,76.51527400000003],[-90.21444699999995,76.528595],[-90.22666900000002,76.53553800000003],[-90.412216,76.63610800000004],[-90.47805800000003,76.66220099999998],[-90.504456,76.67526199999992],[-90.56361400000003,76.709991],[-90.57333399999999,76.71582000000001],[-90.59445199999999,76.72970599999996],[-90.60028099999994,76.734985],[-90.60082999999997,76.74108899999999],[-90.59999099999999,76.746643],[-90.59777799999995,76.75000000000011],[-90.58666999999997,76.76138300000014],[-90.57917800000001,76.7669370000001],[-90.57028200000002,76.771927],[-90.54444899999999,76.78305100000006],[-90.51028400000001,76.79332000000011],[-90.474716,76.79971300000005],[-90.23055999999997,76.82804899999996],[-90.10305800000003,76.83610500000003],[-90.025284,76.83915699999994],[-89.98306300000002,76.836929],[-89.92777999999998,76.8288730000001],[-89.86527999999998,76.8160860000001],[-89.82583599999998,76.80609100000004],[-89.77944899999989,76.7852630000001],[-89.67388899999997,76.73748799999993],[-89.67388899999997,76.73136900000009],[-89.68777499999999,76.70887800000008],[-89.702225,76.68969700000002],[-89.729446,76.67330900000002],[-89.74415599999998,76.66943400000002],[-89.76806599999998,76.668045],[-89.81973299999993,76.66720600000002],[-89.83721899999989,76.66304000000014],[-89.84083599999991,76.65721100000013],[-89.86277799999999,76.60386699999998],[-89.86250299999995,76.59748800000011],[-89.85833699999995,76.59109499999994],[-89.81750499999998,76.54693600000002],[-89.79444899999993,76.53332500000005],[-89.75611900000001,76.52470399999993],[-89.72166399999998,76.51971400000008],[-89.69915799999995,76.51693699999998],[-89.68443300000001,76.51165800000001],[-89.67138699999998,76.50416600000005],[-89.67388899999997,76.50221299999993],[-89.75750700000003,76.48609900000002],[-89.78361499999988,76.48304700000006],[-89.93443299999996,76.47665400000011]],[[-108.65110800000002,76.81359900000001],[-108.65110800000002,76.80886800000007],[-108.65527299999991,76.80386399999998],[-108.67804699999999,76.78498800000011],[-108.68443299999996,76.78054800000007],[-108.69055200000003,76.77442900000005],[-108.69249000000002,76.76998900000007],[-108.68831599999999,76.766098],[-108.67971799999992,76.76332100000008],[-108.66278099999994,76.76138300000014],[-108.596947,76.76081800000009],[-108.55248999999992,76.76138300000014],[-108.527222,76.76026899999994],[-108.50389099999995,76.75610399999994],[-108.48889199999996,76.75166300000006],[-108.46333299999998,76.73915100000005],[-108.45500199999998,76.73332200000004],[-108.44638099999997,76.72360200000014],[-108.44220699999994,76.71775800000012],[-108.43804899999998,76.70803800000004],[-108.44193999999999,76.69636500000001],[-108.45889299999988,76.68470800000006],[-108.54472399999997,76.64637800000014],[-108.56555200000003,76.64166300000011],[-108.58667000000003,76.64166300000011],[-108.60749800000002,76.64248700000007],[-108.628601,76.645264],[-108.65387699999997,76.64721700000013],[-108.68110699999994,76.64776600000005],[-108.70417799999996,76.64637800000014],[-108.72083999999995,76.64248700000007],[-108.72721899999999,76.63804600000014],[-108.72693600000002,76.63415500000008],[-108.69915800000001,76.60554500000006],[-108.69055200000003,76.60054000000002],[-108.62721299999998,76.57554600000003],[-108.61054999999993,76.56971700000003],[-108.58389299999993,76.47747800000008],[-108.58112299999999,76.43914799999999],[-108.55803699999996,76.40859999999998],[-108.475281,76.40693700000008],[-108.36389200000002,76.39999400000005],[-108.328888,76.39665200000013],[-108.31861900000001,76.39415000000008],[-108.28971899999993,76.38443000000001],[-108.26917300000002,76.3749850000001],[-108.07749899999999,76.28054800000001],[-108.11472299999997,76.26138300000002],[-108.252228,76.19692999999995],[-108.33139,76.18193100000008],[-108.38027999999997,76.16526800000003],[-108.39222699999993,76.159424],[-108.40862300000003,76.14776599999999],[-108.396118,76.04609700000015],[-108.35193600000002,76.04887400000007],[-108.02555799999999,76.06219500000003],[-108.00140399999998,76.06303399999996],[-107.916946,76.06303399999996],[-107.83833300000003,76.06137100000007],[-107.81221,76.05609099999998],[-107.73665599999998,76.03942899999998],[-107.72471599999994,76.03553800000009],[-107.63834399999996,75.99636800000013],[-107.63249200000001,75.99108899999999],[-107.63305699999995,75.98136900000009],[-107.639183,75.976089],[-107.65139799999997,75.97026100000005],[-107.785553,75.91998300000012],[-107.84221599999995,75.89999399999999],[-107.901947,75.8961030000001],[-107.91805999999997,75.8913730000001],[-107.93028300000003,75.88554400000004],[-108.031113,75.822495],[-108.04361,75.80219999999997],[-108.02417000000003,75.78387500000002],[-108.02027900000002,75.78082300000011],[-108.00639299999995,75.77943399999992],[-107.9569469999999,75.78471400000001],[-107.91332999999986,75.78942900000004],[-107.87361099999993,75.79803500000014],[-107.82084699999996,75.829163],[-107.778343,75.85470600000008],[-107.75974299999996,75.86970500000012],[-107.75974299999996,75.87441999999999],[-107.739441,75.87915000000004],[-107.51555599999995,75.89999399999999],[-107.36945299999996,75.911652],[-107.33750899999995,75.91137700000002],[-107.18666099999996,75.90387000000004],[-107.08000199999998,75.89276100000001],[-107.08583099999998,75.87248200000005],[-107.09028599999994,75.86747700000001],[-107.10500300000001,75.83471700000013],[-107.098053,75.82304399999992],[-107.03167699999995,75.77110300000004],[-106.96362299999993,75.73858600000005],[-106.89666699999998,75.72026100000011],[-106.88027999999991,75.76582299999995],[-106.83056599999998,75.78581200000008],[-106.79444899999993,75.7916560000001],[-106.74471999999992,75.79553199999998],[-106.72277799999995,75.79582199999999],[-106.67944299999999,75.79359400000004],[-106.6558379999999,75.79359400000004],[-106.636124,75.79443400000008],[-106.61582899999996,75.797211],[-106.62110899999993,75.80331400000011],[-106.6383439999999,75.80693100000008],[-106.67944299999999,75.8124850000001],[-106.72666900000002,75.813873],[-106.78611799999993,75.81330900000006],[-106.829453,75.816666],[-106.85082999999992,75.81999200000001],[-106.87000299999994,75.82499700000005],[-106.88890100000003,75.83471700000013],[-106.89584400000001,75.84443700000003],[-106.89666699999998,75.93525699999998],[-106.89611799999994,75.94108600000004],[-106.89334100000002,75.94747899999999],[-106.86971999999997,75.96415700000006],[-106.63890099999998,76.05304000000012],[-106.60610999999994,76.05775499999999],[-106.58583099999993,76.05859399999997],[-106.368607,76.05581700000005],[-106.33667000000003,76.05470300000007],[-106.30082699999997,76.05137600000012],[-106.01611299999996,76.01971400000002],[-105.93721,76.01026900000011],[-105.89998600000001,76.00555400000007],[-105.837219,75.99693299999996],[-105.73500100000001,75.9749910000001],[-105.66832699999998,75.95555100000013],[-105.61945299999996,75.93942300000009],[-105.60637699999995,75.93470800000006],[-105.59528399999988,75.92970300000002],[-105.47888199999994,75.86303699999996],[-105.46528599999999,75.85192899999998],[-105.45333900000003,75.84165999999993],[-105.445831,75.83055100000007],[-105.40028399999989,75.69442700000008],[-105.38834399999996,75.65637200000003],[-105.391953,75.63888500000013],[-105.48750299999995,75.56080600000013],[-105.49638399999998,75.55525200000011],[-105.51666299999994,75.55053700000008],[-105.54083300000002,75.54693600000002],[-105.60444599999988,75.53997800000002],[-105.63667299999997,75.53360000000009],[-105.68582200000003,75.51944000000015],[-105.74082900000002,75.49497999999994],[-105.75140399999998,75.48970000000008],[-105.74804699999999,75.48580900000002],[-105.73693799999995,75.48275799999999],[-105.68666100000002,75.48304700000011],[-105.67166099999986,75.48109399999998],[-105.61138900000003,75.47164900000007],[-105.59277299999997,75.46748400000007],[-105.593613,75.46276900000004],[-105.64639299999993,75.36526500000002],[-105.65110799999997,75.35942100000005],[-105.66055299999994,75.34971600000011],[-105.72666900000002,75.31303400000013],[-105.7386019999999,75.30941800000005],[-105.76251199999996,75.30497699999995],[-105.79361,75.30220000000008],[-105.81304899999998,75.29942299999999],[-105.82140399999992,75.2958220000001],[-105.86694299999999,75.27581800000002],[-105.87526699999995,75.27110299999998],[-105.9377669999999,75.21443200000004],[-105.93888900000002,75.20860300000004],[-105.93582199999997,75.20277400000003],[-105.929169,75.19775400000015],[-105.89222699999999,75.190811],[-105.87249800000001,75.171921],[-105.876938,75.14582800000005],[-105.88527699999997,75.14027400000009],[-105.90499899999998,75.13638300000002],[-105.92582699999997,75.135269],[-106.00361599999991,75.13554400000004],[-106.01889,75.13388100000009],[-106.07028200000002,75.10664400000002],[-106.07945299999989,75.09693900000008],[-106.07333399999993,75.08720399999999],[-106.01862299999999,75.07415800000007],[-106.00446299999999,75.06805400000002],[-105.99416399999996,75.06219500000003],[-105.99333199999995,75.05581700000005],[-106.011124,75.05081200000001],[-106.23528299999998,75.02137800000003],[-106.26000999999997,75.01915000000008],[-106.45500199999992,75.00582900000012],[-106.54554699999989,75.00166300000001],[-106.564438,75.00082400000008],[-106.66332999999992,75.004166],[-106.72556299999997,75.00221300000004],[-106.77111799999989,74.996643],[-106.78639199999998,74.99192800000014],[-106.78307299999994,74.98997500000002],[-106.78333299999997,74.98609899999997],[-106.78582799999992,74.98054500000012],[-106.79194599999994,74.97526600000015],[-106.807503,74.96971100000007],[-106.93055699999996,74.93359400000008],[-106.97222899999997,74.92608600000005],[-107.01000999999991,74.922485],[-107.05110200000001,74.92164600000007],[-107.07362399999994,74.91998300000012],[-107.16000399999996,74.91053800000009],[-107.19722000000002,74.91081200000002],[-107.215843,74.911926],[-107.46417199999996,74.93441800000005],[-107.506958,74.93997200000007],[-107.630829,74.96110499999998],[-107.66251399999999,74.96666000000005],[-107.68804899999998,74.97637900000007],[-107.69554099999999,74.98220800000007],[-107.72389199999998,75.016388],[-107.72389199999998,75.02026400000005],[-107.71972699999998,75.02609300000006],[-107.704453,75.03082300000011],[-107.68138099999999,75.04248000000001],[-107.67944299999994,75.04859900000008],[-107.68110699999994,75.05304000000001],[-107.69499199999996,75.07527200000004],[-107.70584100000002,75.08610500000003],[-107.716949,75.09082000000006],[-107.739441,75.0958250000001],[-107.75834700000001,75.09693900000008],[-107.77333099999998,75.09609999999992],[-107.78307299999994,75.09359699999999],[-107.77999899999998,75.07222000000013],[-107.77084400000001,75.06581100000011],[-107.75778200000002,75.06053199999991],[-107.74500299999994,75.05415300000004],[-107.739441,75.04887400000007],[-107.73972299999997,75.04304500000006],[-107.74388099999993,75.03720100000004],[-107.77778599999999,75.0294340000001],[-107.89499699999999,75.003601],[-107.94193999999999,74.93081699999999],[-107.95527600000003,74.92858900000004],[-107.97749299999998,74.92747500000007],[-108.02417000000003,74.92915299999999],[-108.13417099999992,74.92776500000008],[-108.21083099999987,74.92359900000002],[-108.37304699999999,74.91053800000009],[-108.3916779999999,74.91137700000002],[-108.436394,74.91526800000008],[-108.45500199999998,74.91832],[-108.52971599999995,74.936646],[-108.54110700000001,74.94053600000001],[-108.548607,74.94636500000001],[-108.547958,74.95165300000002],[-108.55055199999998,74.9563750000001],[-108.55999800000001,74.96081500000014],[-108.67971799999992,74.97026100000011],[-108.781113,74.97998000000007],[-108.80721999999997,74.98359700000003],[-108.80721999999997,74.984711],[-108.796112,74.98580900000013],[-108.74553699999996,74.984421],[-108.63890100000003,74.9810940000001],[-108.614441,74.97970599999996],[-108.55999800000001,74.97637900000007],[-108.53028899999993,74.97331200000013],[-108.51139799999999,74.97554000000008],[-108.52667199999996,75.00166300000001],[-108.53056300000003,75.00555400000007],[-108.53806299999985,75.00943000000001],[-108.628601,75.04609699999997],[-108.65139799999992,75.05386399999998],[-108.79472399999997,75.06915300000003],[-108.83249699999993,75.06999200000001],[-108.92777999999993,75.05192599999998],[-108.94972200000001,75.04026799999997],[-109.001106,75.00499000000013],[-109.11971999999997,74.97943099999998],[-109.34584000000001,74.94470200000006],[-109.36416600000001,74.93969700000002],[-109.39998600000001,74.91832],[-109.40722700000003,74.91249099999999],[-109.40695199999993,74.90859999999992],[-109.420547,74.89305100000001],[-109.50805700000001,74.86637900000011],[-109.52278099999995,74.86331200000001],[-109.56861900000001,74.85775800000005],[-109.58721899999995,74.85664400000002],[-109.66139199999992,74.85636900000003],[-109.76944700000001,74.85942100000011],[-109.79750099999995,74.86360200000001],[-109.81111099999993,74.86804200000006],[-109.83361799999994,74.86970499999995],[-109.87249800000001,74.86914100000001],[-109.93472300000002,74.86080900000002],[-109.95500199999987,74.85720800000001],[-109.99471999999997,74.84832799999998],[-110.01640299999991,74.84220900000008],[-110.13971700000002,74.83305400000006],[-110.30444299999994,74.84637500000002],[-110.32501200000002,74.84748800000011],[-110.34555099999989,74.84693900000013],[-110.36000100000001,74.84387200000003],[-110.37053700000001,74.83998099999997],[-110.40416699999997,74.82666],[-110.39620999999994,74.81368999999995],[-110.39666699999998,74.7994230000001],[-110.43666100000002,74.79331999999994],[-110.58999599999993,74.77804600000007],[-110.59137699999997,74.72415200000006],[-110.75666799999993,74.68525700000009],[-110.77250699999996,74.68081700000005],[-110.78639199999998,74.67469800000003],[-110.79638699999998,74.66886900000003],[-110.807503,74.657486],[-110.83389299999993,74.65193199999999],[-110.98111,74.62136800000013],[-111.28056300000003,74.56776400000012],[-111.38722200000001,74.56303400000007],[-111.409157,74.56275900000009],[-111.43055699999996,74.56053200000002],[-111.55888399999998,74.52748100000008],[-111.64250199999992,74.50138900000002],[-111.67722300000003,74.49331700000005],[-111.700287,74.49136400000009],[-111.82389799999999,74.48332199999993],[-111.94554099999993,74.474426],[-111.98416099999997,74.46887200000003],[-112.087219,74.45220899999993],[-112.29305999999991,74.42776500000002],[-112.37053699999996,74.41859400000004],[-112.43831599999999,74.41442900000004],[-112.54194599999988,74.409424],[-112.75306699999993,74.40138200000001],[-112.85694899999993,74.39833099999998],[-112.91999799999991,74.39749099999995],[-113.00890400000003,74.39804099999998],[-113.25723299999993,74.40525800000012],[-113.406113,74.41331500000007],[-113.42832899999996,74.41470300000015],[-113.47168699999997,74.41891499999997],[-113.64083900000003,74.4374850000001],[-113.69638099999997,74.44609100000002],[-113.84221600000001,74.47970600000008],[-113.94167299999998,74.50360100000006],[-114.053879,74.530823],[-114.12110899999993,74.54998799999998],[-114.29834,74.60276800000003],[-114.34861799999999,74.61886600000008],[-114.37470999999994,74.6291500000001],[-114.39695699999993,74.63916],[-114.43804899999986,74.65942400000012],[-114.44360399999994,74.664154],[-114.44776899999994,74.67469800000003],[-114.42859599999991,74.69192500000003],[-114.41972399999992,74.69802900000008],[-114.40750099999997,74.70416300000011],[-114.39444700000001,74.70832800000011],[-114.21444699999995,74.75555400000013],[-114.10166899999996,74.77665700000006],[-114.01027699999992,74.79054300000007],[-113.73166699999996,74.82720899999998],[-113.71000699999996,74.82971199999992],[-113.55695300000002,74.839157],[-113.41861,74.84275800000006],[-113.28278399999999,74.84860200000008],[-113.25334199999998,74.87359600000002],[-113.22269399999988,74.89646900000002],[-113.15194699999995,74.92498799999998],[-113.1205369999999,74.93248000000011],[-113.00750699999992,74.95416300000005],[-112.91111799999987,74.97082500000005],[-112.86749299999997,74.97554000000008],[-112.84528399999994,74.9769290000001],[-112.57224299999996,74.99275200000011],[-112.52416999999991,74.99552900000003],[-112.5,74.99601000000001],[-112.453056,74.99693300000001],[-112.37444299999993,74.99832199999997],[-112.01500699999991,75.00248699999997],[-111.962219,75.00138900000007],[-111.935272,74.99887100000012],[-111.89890299999996,74.99498000000006],[-111.86527999999993,74.98831200000006],[-111.84056099999998,74.98637400000013],[-111.76444999999995,74.98165900000009],[-111.75334199999998,74.98165900000009],[-111.718613,74.986649],[-111.62666300000001,75.00387599999999],[-111.589722,75.00637800000004],[-111.55139200000002,75.01138300000014],[-111.535278,75.01499899999999],[-111.28971899999999,75.08610500000003],[-111.02916700000003,75.17109700000003],[-110.920547,75.22360200000008],[-110.91361999999998,75.22859199999994],[-110.91278099999994,75.23387100000014],[-110.91750300000001,75.23969999999997],[-111.05249000000003,75.270264],[-111.06806899999987,75.27192700000012],[-111.23082699999998,75.26415999999995],[-111.248894,75.25915500000008],[-111.25195300000001,75.25416599999994],[-111.25083899999993,75.24859600000008],[-111.25167799999997,75.24304200000006],[-111.25611900000001,75.23664900000011],[-111.26112399999994,75.23220800000001],[-111.27778599999994,75.22053499999998],[-111.33416699999992,75.19747899999993],[-111.39167800000001,75.1810910000001],[-111.47501399999999,75.161652],[-111.56082200000003,75.1461030000001],[-111.57721700000002,75.1436000000001],[-111.59612299999998,75.143326],[-111.69526699999989,75.14582800000005],[-111.70584100000002,75.15109300000012],[-111.787216,75.16665599999993],[-111.958054,75.13499500000006],[-112.22833300000002,75.12469499999997],[-112.39055599999995,75.12303200000002],[-112.40972899999997,75.12359600000002],[-112.42916899999994,75.12525900000009],[-112.439438,75.12858600000004],[-112.44833399999999,75.13304100000005],[-112.47084000000001,75.14637800000008],[-112.46833800000002,75.15138200000007],[-112.46166999999997,75.15443399999998],[-112.45249899999999,75.155823],[-112.41197199999993,75.15901200000008],[-112.36860699999994,75.16914400000013],[-112.358337,75.17303500000003],[-112.29472399999992,75.19802899999996],[-112.295837,75.20277400000003],[-112.339447,75.22360200000008],[-112.39750700000002,75.2410890000001],[-112.40888999999993,75.24081400000011],[-112.4366609999999,75.23054500000006],[-112.46193700000003,75.21887200000003],[-112.46417200000002,75.21304300000003],[-112.46305799999999,75.208328],[-112.45056199999999,75.20471199999997],[-112.43749999999994,75.19886800000012],[-112.43221999999997,75.19331399999993],[-112.43250299999994,75.1869200000001],[-112.44471699999997,75.18331900000004],[-112.46665999999999,75.17997700000006],[-112.56111099999993,75.178314],[-112.59249899999998,75.18165600000009],[-112.60888699999992,75.18525699999998],[-112.62554899999998,75.190811],[-112.6347429999999,75.19636500000013],[-112.63722200000001,75.20498700000013],[-112.63694800000002,75.21054100000015],[-112.632767,75.21582000000012],[-112.61609599999997,75.22387700000007],[-112.59472699999998,75.23027000000008],[-112.58583099999998,75.23915099999999],[-112.59472699999998,75.25000000000006],[-112.61277799999999,75.25943000000012],[-112.65167200000002,75.27526900000004],[-112.66583300000002,75.27859500000011],[-112.679169,75.27777100000014],[-112.71305799999999,75.25610400000011],[-112.718887,75.25027500000004],[-112.735817,75.20332300000013],[-112.73416099999992,75.19747899999993],[-112.72888199999994,75.1927490000001],[-112.71584299999995,75.18719500000009],[-112.698036,75.17776500000002],[-112.68859899999995,75.171921],[-112.699997,75.13832100000013],[-112.80695300000002,75.11581400000006],[-112.89417300000002,75.10331700000006],[-112.95667300000002,75.09721400000012],[-113.25446299999999,75.076096],[-113.29888899999997,75.0730440000001],[-113.343887,75.07222000000013],[-113.610817,75.06275900000014],[-113.68083200000001,75.05192599999998],[-113.699432,75.05137599999995],[-113.89417299999997,75.05219999999991],[-113.91750299999995,75.0535890000001],[-113.94138299999986,75.05693100000008],[-113.950287,75.06053199999991],[-113.96888699999994,75.07527200000004],[-113.97305299999994,75.08665500000006],[-113.97305299999994,75.09637499999997],[-113.93138099999999,75.18914800000005],[-113.82055700000001,75.31442300000015],[-113.80583199999995,75.32666000000012],[-113.78278399999999,75.33776899999998],[-113.72805800000003,75.34582500000005],[-113.66055299999994,75.35137900000007],[-113.64222699999993,75.35359199999999],[-113.573624,75.36692800000014],[-113.34056099999992,75.41331500000007],[-113.381104,75.41832000000011],[-113.47112300000003,75.42776499999997],[-113.577789,75.41165200000012],[-113.66027799999995,75.39860500000009],[-113.74445299999996,75.38581800000009],[-113.83389299999988,75.37692300000009],[-113.87138400000003,75.374146],[-113.902222,75.3744200000001],[-113.91139199999998,75.37803600000012],[-113.92111199999994,75.38388100000003],[-113.958618,75.41110200000008],[-113.98166700000002,75.43109100000004],[-113.98416099999992,75.43775899999997],[-113.99221799999998,75.44831800000003],[-114.02416999999997,75.46110500000003],[-114.04083300000002,75.46388200000013],[-114.06500199999988,75.46609500000011],[-114.08389299999999,75.46470600000009],[-114.08693699999998,75.46249400000005],[-114.08917199999996,75.45860299999998],[-114.093887,75.41081200000008],[-114.09166699999992,75.40498400000013],[-114.08583099999993,75.4002690000001],[-114.07778899999988,75.39415000000008],[-114.06610099999995,75.38916000000006],[-114.05638099999987,75.383331],[-114.04472399999992,75.37303200000002],[-114.04055800000003,75.36775200000011],[-114.04055800000003,75.36219800000009],[-114.04750100000001,75.35054000000008],[-114.13751200000002,75.24498],[-114.15805099999994,75.23332199999999],[-114.17083699999989,75.22692900000004],[-114.18666100000002,75.22331200000008],[-114.203056,75.22137500000002],[-114.22277799999995,75.2227630000001],[-114.26363399999991,75.22970599999991],[-114.28472899999997,75.23498500000011],[-114.319458,75.24470500000001],[-114.34638999999993,75.25471500000009],[-114.35082999999997,75.26638800000012],[-114.34916699999985,75.27137800000014],[-114.35109699999992,75.276093],[-114.35888699999992,75.28137199999998],[-114.49999999999994,75.31219499999997],[-114.51278699999995,75.31469700000008],[-114.52806099999992,75.31442300000015],[-114.54276999999996,75.31303400000013],[-114.60973399999995,75.27998400000007],[-114.61527999999993,75.27499400000005],[-114.61138900000003,75.26527399999998],[-114.598343,75.26165800000007],[-114.57972699999999,75.26332100000002],[-114.57250999999997,75.26443499999999],[-114.54666099999997,75.26693700000004],[-114.49638399999998,75.26554899999996],[-114.46806299999997,75.26220700000005],[-114.44304699999986,75.25721699999997],[-114.41278099999994,75.24803199999991],[-114.39723200000003,75.238876],[-114.30249000000003,75.1827550000001],[-114.297234,75.17915299999993],[-114.29472399999997,75.17330900000013],[-114.29804999999999,75.16665599999993],[-114.30860899999993,75.15470900000003],[-114.32112099999995,75.143326],[-114.33528099999995,75.13108799999992],[-114.34944199999995,75.11914099999996],[-114.36749299999985,75.10693400000002],[-114.39499699999993,75.09054600000013],[-114.42971799999987,75.0730440000001],[-114.46640000000002,75.06053199999991],[-114.48332199999987,75.05609099999998],[-114.51889,75.05026199999998],[-114.60082999999997,75.03831500000001],[-114.72416699999997,75.01193200000006],[-114.76342799999998,75.00247200000001],[-114.825287,74.98803700000008],[-114.88861099999991,74.97747800000002],[-114.94915800000001,74.96998600000006],[-115.03222699999992,74.96165500000001],[-115.05082700000003,74.96110499999998],[-115.066101,74.96165500000001],[-115.160553,74.97943099999998],[-115.18582200000003,74.98525999999998],[-115.195267,74.98997500000002],[-115.22609699999992,75.04971300000005],[-115.22638699999993,75.05831899999998],[-115.225281,75.06414799999999],[-115.21861299999995,75.07083100000011],[-115.21167000000003,75.07638500000013],[-115.199432,75.082764],[-115.18331899999993,75.08888200000013],[-115.17415599999993,75.09414700000002],[-115.17304999999999,75.09999099999999],[-115.17278299999992,75.10775799999999],[-115.17832899999996,75.11581400000006],[-115.216949,75.16748000000013],[-115.23554999999993,75.17469800000009],[-115.24861099999998,75.178314],[-115.25695799999994,75.17997700000006],[-115.26083399999993,75.17997700000006],[-115.25611900000001,75.17804000000007],[-115.252228,75.17387400000013],[-115.25361599999991,75.1644290000001],[-115.256393,75.15803500000004],[-115.26139799999999,75.1519320000001],[-115.27916699999997,75.14082300000001],[-115.291382,75.13443000000007],[-115.33640300000002,75.11665299999999],[-115.35305799999998,75.11109900000002],[-115.37304699999999,75.10582000000005],[-115.38694799999996,75.10220300000009],[-115.40416700000003,75.09887700000002],[-115.42666600000001,75.09803800000009],[-115.451683,75.09887700000002],[-115.48361199999994,75.10609399999998],[-115.51944700000001,75.117752],[-115.62389399999995,75.12136800000002],[-115.60472099999993,75.10859700000009],[-115.54888899999997,75.05581700000005],[-115.53971899999993,75.04443400000008],[-115.53751399999993,75.03942900000004],[-115.53751399999993,75.02720599999998],[-115.54527300000001,75.01582300000013],[-115.5516659999999,75.00915500000013],[-115.57472200000001,74.99832199999997],[-115.60249299999998,74.98553499999997],[-115.61833200000001,74.97915599999993],[-115.658051,74.96720899999997],[-115.67194399999988,74.96470600000004],[-115.69055200000003,74.96415700000006],[-115.73500100000001,74.96720899999997],[-115.75723299999999,74.96998600000006],[-115.847778,74.98553499999997],[-116.16306299999991,75.04026799999997],[-116.27916699999997,75.099426],[-116.28639199999992,75.13108799999992],[-116.27694699999995,75.135269],[-116.26889,75.14137300000004],[-116.2455369999999,75.16276600000015],[-116.24109599999997,75.16886900000009],[-116.23860200000001,75.19693000000001],[-116.23916599999995,75.20138500000002],[-116.24694799999992,75.20526100000006],[-116.26834100000002,75.20610000000005],[-116.287216,75.20555100000007],[-116.527222,75.184708],[-116.56054699999999,75.17915299999993],[-116.58084100000002,75.1744230000001],[-116.59388699999994,75.1702580000001],[-116.60249299999998,75.16499300000004],[-116.618607,75.15248100000002],[-116.66332999999997,75.12248199999999],[-116.679169,75.11720300000002],[-116.69415299999997,75.11665299999999],[-116.71721599999995,75.11665299999999],[-117.16860999999994,75.15748600000006],[-117.38417099999992,75.17858899999999],[-117.41915899999992,75.18248000000006],[-117.45777899999996,75.188873],[-117.47501399999993,75.19220000000013],[-117.66361999999998,75.23915099999999],[-117.67832900000002,75.24443100000008],[-117.68305999999995,75.24859600000008],[-117.68388400000003,75.25305200000014],[-117.67166099999997,75.28887900000012],[-117.666946,75.29414400000002],[-117.66194199999995,75.29803500000008],[-117.53666699999997,75.361649],[-117.45527599999997,75.4002690000001],[-117.42054699999994,75.41331500000007],[-117.35360699999995,75.43748500000004],[-117.32112099999995,75.44859300000007],[-117.26139799999993,75.46887199999998],[-117.24054699999999,75.47360200000003],[-117.218887,75.47637900000012],[-117.14666699999998,75.48027000000002],[-117.10305799999998,75.48220800000013],[-117.041382,75.48359700000015],[-116.89778100000001,75.48248299999995],[-116.87748699999997,75.48136899999997],[-116.75334199999998,75.47943100000003],[-116.13474300000001,75.47637900000012],[-116.11554699999994,75.47692899999998],[-116.02194199999997,75.48498500000005],[-115.97332799999998,75.492752],[-115.92250100000001,75.50387600000005],[-115.81833599999987,75.52970900000003],[-115.68888900000002,75.56442300000009],[-115.64639299999999,75.57360799999992],[-115.61972000000003,75.57887299999999],[-115.56527699999987,75.58387800000003],[-115.53056299999997,75.58499100000012],[-115.50611900000001,75.5872040000001],[-115.46305799999999,75.59193399999992],[-115.36609599999997,75.60276800000003],[-115.28832999999997,75.62052900000015],[-115.28611799999993,75.62442000000004],[-115.277222,75.63053900000006],[-115.26777600000003,75.63581800000003],[-115.20333900000003,75.65721100000013],[-115.18611099999993,75.66276600000003],[-115.09665699999994,75.68719499999997],[-115.08194700000001,75.68942300000015],[-115.07028200000002,75.68997200000007],[-115.04250300000001,75.68969700000008],[-114.99973299999994,75.69081100000005],[-114.99804699999999,75.6958160000001],[-115.00556899999992,75.698868],[-115.028343,75.70166000000012],[-115.05277999999998,75.70304899999991],[-115.07611099999991,75.70248400000008],[-115.10305800000003,75.70082100000013],[-115.14555399999995,75.69413800000001],[-115.21721600000001,75.67932100000007],[-115.27916699999997,75.667755],[-115.32472199999995,75.65998800000006],[-115.38305700000001,75.6538700000001],[-115.40194699999995,75.65248099999997],[-115.47193900000002,75.65026900000004],[-115.51888999999994,75.64999400000005],[-115.60637700000001,75.651093],[-115.66750299999995,75.64721700000013],[-115.714447,75.64248700000013],[-115.889183,75.61442600000004],[-116.09166700000003,75.58055100000013],[-116.108047,75.57415799999995],[-116.11916400000001,75.572769],[-116.34750399999996,75.559143],[-116.38971700000002,75.5577550000001],[-116.46028099999995,75.55748000000006],[-116.48610699999995,75.5577550000001],[-116.84361299999989,75.56498700000003],[-117.19499200000001,75.57360799999992],[-117.21556099999998,75.5747070000001],[-117.23277300000001,75.57693500000005],[-117.24276700000001,75.58055100000013],[-117.25,75.58610500000009],[-117.25110599999994,75.59748800000011],[-117.24833699999999,75.60304300000001],[-117.23999000000003,75.61499000000015],[-117.23361199999994,75.62052900000015],[-117.21362299999993,75.633331],[-117.07805599999995,75.70721400000008],[-117.06443799999994,75.71415700000011],[-117.03971899999999,75.72581500000013],[-117.02362099999993,75.73248300000012],[-117.01666299999994,75.73719800000015],[-116.95556599999992,75.76193200000012],[-116.923317,75.7747040000001],[-116.88667299999992,75.78692600000005],[-116.86888099999999,75.79054300000001],[-116.85056299999991,75.79304500000012],[-116.81639099999995,75.79637100000014],[-116.76278699999995,75.7999880000001],[-116.71972699999998,75.80165099999999],[-116.58860799999997,75.80331400000011],[-116.53056300000003,75.80276500000002],[-116.32417299999992,75.80470300000013],[-116.10582699999998,75.80693100000008],[-116.03721599999994,75.809708],[-115.82305899999994,75.82720899999993],[-115.80444299999994,75.82998700000013],[-115.79444899999999,75.83415200000013],[-115.78415699999994,75.845261],[-115.77971600000001,75.85220300000009],[-115.76500699999997,75.85443100000003],[-115.74944299999999,75.85498000000001],[-115.73693800000001,75.85443100000003],[-115.72638699999993,75.85331700000006],[-115.69193999999993,75.8483280000001],[-115.67388900000003,75.84414700000002],[-115.65943900000002,75.83970600000009],[-115.62277199999994,75.83442700000012],[-115.59445199999999,75.833328],[-115.50723299999993,75.83499100000006],[-115.40499899999998,75.83804300000003],[-115.38194299999992,75.83970600000009],[-115.36416599999995,75.84414700000002],[-115.35193599999997,75.85220300000009],[-115.31360599999994,75.855255],[-115.13945000000001,75.85942100000011],[-115.07277699999986,75.85775799999999],[-115.04998799999998,75.85582000000005],[-115.00083899999998,75.85331700000006],[-114.98082699999992,75.85304300000013],[-114.932503,75.85664400000002],[-114.91194199999995,75.85971100000012],[-114.83860799999997,75.87441999999999],[-114.817497,75.88081400000004],[-114.80444299999994,75.886932],[-114.798607,75.89221200000003],[-114.80999800000001,75.89942899999994],[-114.82417299999986,75.9041600000001],[-114.83667000000003,75.905823],[-114.88166799999993,75.90748600000012],[-114.90722700000003,75.90637200000015],[-115.01806599999992,75.89888000000002],[-115.0641629999999,75.89471400000014],[-115.10527000000002,75.888596],[-115.221657,75.88026400000001],[-115.29277000000002,75.87831100000005],[-115.39472999999992,75.87776200000013],[-115.54055799999998,75.88136299999996],[-115.68222000000003,75.88832100000013],[-115.74694799999986,75.88943499999993],[-115.83029199999993,75.88777200000004],[-115.86888099999999,75.88443000000007],[-116.00472999999994,75.86859099999998],[-116.0533289999999,75.86554000000012],[-116.10665899999998,75.86415099999994],[-116.13474300000001,75.86442599999998],[-116.15083299999992,75.86470000000008],[-116.48277299999995,75.87387100000007],[-116.623894,75.88192700000013],[-116.64972699999998,75.88499500000012],[-116.67666600000001,75.88970900000004],[-116.69972199999995,75.89498900000012],[-116.71501199999994,75.90026900000004],[-116.72444200000001,75.90637200000015],[-116.73416099999992,75.922485],[-116.733612,75.92858900000004],[-116.73137699999995,75.94525100000004],[-116.72666899999996,75.95138500000002],[-116.71389799999997,75.95664999999991],[-116.69972199999995,75.95999099999995],[-116.67748999999998,75.96388200000001],[-116.63221699999997,75.96914700000008],[-116.58528099999995,75.971924],[-116.561394,75.97276299999999],[-116.53721599999994,75.97248800000011],[-116.51611300000002,75.97110000000004],[-116.48528299999998,75.966385],[-116.470551,75.96887200000009],[-116.46193700000003,75.9749910000001],[-116.46833800000002,75.98637400000013],[-116.52834299999995,76.02748099999997],[-116.60221899999993,76.02221699999996],[-116.645554,76.02304100000009],[-116.66944899999999,76.02581800000002],[-116.6875,76.02915999999999],[-116.69888300000002,76.03442400000012],[-116.70556599999998,76.039154],[-116.708618,76.04386900000003],[-116.70777900000002,76.04998800000004],[-116.70612299999999,76.05386400000009],[-116.70168299999995,76.05998200000005],[-116.69638099999992,76.06498700000009],[-116.641388,76.11331200000012],[-116.53388999999999,76.15332000000001],[-116.51611300000002,76.15776100000011],[-116.34221599999995,76.183044],[-116.296112,76.188583],[-116.21362299999998,76.19497700000005],[-116.16361999999992,76.197205],[-116.08416699999998,76.19831800000009],[-116.05943300000001,76.19802900000013],[-115.95889299999999,76.19413800000007],[-115.90862300000003,76.19192499999991],[-115.86554699999999,76.18830900000006],[-115.81582600000002,76.18692000000004],[-115.64334099999996,76.18609600000008],[-115.59500100000002,76.18775900000003],[-115.44721999999996,76.18692000000004],[-115.32749899999999,76.184708],[-115.27306399999998,76.18220500000001],[-115.154449,76.16943400000008],[-115.13027999999997,76.16581699999995],[-115.02166699999998,76.15637200000009],[-114.87554899999998,76.14971900000012],[-114.85109699999992,76.14942900000011],[-114.790771,76.15107700000004],[-114.72833300000002,76.15304600000007],[-114.68499799999995,76.15609700000005],[-114.66972399999997,76.15832500000005],[-114.66251399999999,76.16053799999997],[-114.662781,76.16165199999995],[-114.68083199999995,76.16499299999998],[-114.70639,76.16720599999996],[-114.80082699999997,76.16859400000004],[-114.85056299999997,76.17025800000005],[-114.89862099999993,76.17248500000011],[-114.94499200000001,76.176086],[-114.99305700000002,76.18248000000006],[-115.00974299999996,76.1874850000001],[-115.01444999999995,76.19274900000005],[-115.02250700000002,76.19692999999995],[-115.04527300000001,76.20220899999998],[-115.08944699999995,76.20887800000003],[-115.15972899999997,76.21859699999999],[-115.27223200000003,76.23027000000002],[-115.37304699999999,76.23082000000005],[-115.54943800000001,76.23054500000006],[-115.75666799999993,76.23414600000012],[-115.78195199999993,76.2352600000001],[-115.8272169999999,76.23942599999998],[-115.847778,76.24304200000006],[-115.86665299999993,76.24748200000005],[-115.88194299999992,76.25277699999992],[-115.91471899999993,76.27526900000004],[-115.92166099999997,76.28109699999993],[-115.92500299999989,76.28665200000006],[-115.90943899999996,76.34553500000004],[-115.90139799999997,76.3499910000001],[-115.86054999999999,76.3624880000001],[-115.64835399999998,76.42025800000005],[-115.62638899999996,76.42581200000001],[-115.51471700000002,76.45138500000013],[-115.49973299999994,76.45471200000009],[-115.46665999999993,76.45582600000006],[-115.26944700000001,76.46110500000003],[-115.02139299999993,76.47470099999998],[-115.00167799999997,76.47720300000009],[-114.978882,76.48165899999998],[-114.95638999999994,76.48719800000015],[-114.94638099999992,76.49247700000012],[-114.93360899999999,76.50499000000002],[-114.92999299999997,76.510269],[-114.91944899999999,76.5144350000001],[-114.89972699999987,76.51693699999998],[-114.74054699999988,76.51721200000003],[-114.71112099999999,76.51693699999998],[-114.70194999999995,76.51527400000003],[-114.69611399999991,76.51138299999997],[-114.69833399999999,76.50749200000013],[-114.720551,76.50109900000012],[-114.70694699999996,76.48970000000003],[-114.61028299999992,76.48831200000012],[-114.45140099999998,76.49693300000007],[-114.29361,76.48026999999996],[-114.25167799999991,76.47499099999999],[-114.20722999999987,76.46804800000001],[-114.17471299999994,76.46026600000005],[-114.14806399999998,76.45138500000013],[-114.13555899999989,76.44636500000007],[-114.11833199999995,76.43525700000009],[-114.11193800000001,76.42942800000009],[-114.10333299999996,76.41886900000003],[-114.096947,76.40359500000011],[-114.09111000000001,76.38888500000002],[-114.10611,76.35554500000012],[-114.11749299999997,76.353317],[-114.12943999999993,76.31191999999993],[-114.05972299999996,76.21775800000006],[-113.99665800000002,76.19274900000005],[-113.98332199999999,76.19026200000002],[-113.9583439999999,76.188873],[-113.94833399999999,76.18942300000003],[-113.70889299999999,76.20359800000011],[-113.685272,76.20610000000005],[-113.63890100000003,76.2127690000001],[-113.61609599999997,76.21832300000005],[-113.52443700000003,76.23580900000002],[-113.36501299999992,76.25860599999993],[-113.32333399999993,76.26277200000004],[-113.26055899999994,76.26443499999999],[-112.99916100000002,76.26748700000007],[-112.95667300000002,76.26361100000003],[-112.90972899999997,76.25749199999996],[-112.89222699999993,76.2538760000001],[-112.86860699999994,76.24470499999995],[-112.85888699999998,76.23997500000013],[-112.85305800000003,76.23414600000012],[-112.75055700000001,76.20054600000003],[-112.71721599999995,76.19831800000009],[-112.62138399999998,76.19831800000009],[-112.59028599999999,76.19663999999995],[-112.48194899999999,76.18136600000008],[-112.46278399999994,76.17831399999994],[-112.453888,76.176376],[-112.42500299999995,76.16775500000011],[-112.43138099999993,76.16192600000011],[-112.43859900000001,76.15887500000008],[-112.47721899999999,76.15138200000001],[-112.49416400000001,76.14665200000002],[-112.50389099999995,76.13859600000012],[-112.52610800000002,76.11053500000003],[-112.52806099999998,76.10386700000004],[-112.52278100000001,76.099152],[-112.42278299999987,76.04721100000012],[-112.41332999999992,76.04248000000001],[-112.38555899999994,76.03665200000006],[-112.29888900000003,76.0294340000001],[-112.15416699999997,76.01499899999999],[-112.06861899999996,76.00332600000013],[-112.04332699999992,75.99887100000012],[-111.9786069999999,75.98136900000009],[-111.78443900000002,75.9497070000001],[-111.76390100000003,75.94693000000001],[-111.75279199999994,75.9427490000001],[-111.72778299999999,75.92164600000001],[-111.72666900000002,75.915817],[-111.729446,75.91110199999997],[-111.736107,75.90498400000007],[-111.77749599999999,75.89471400000014],[-111.87138400000003,75.887497],[-111.94444299999998,75.88499500000012],[-112.00945300000001,75.88165299999997],[-112.03472899999997,75.879974],[-112.05222300000003,75.87803600000007],[-112.07501200000002,75.87387100000007],[-112.165009,75.85192899999998],[-112.17971799999998,75.84803800000009],[-112.18694299999993,75.844986],[-112.22556299999997,75.81109600000008],[-112.218613,75.80802900000015],[-112.20834399999995,75.80664100000007],[-112.19248999999996,75.8058170000001],[-112.02834299999995,75.81526199999996],[-111.85861199999988,75.82693499999999],[-111.69082599999996,75.82276900000011],[-111.64499699999993,75.82165500000013],[-111.604446,75.82666],[-111.53971899999993,75.83831800000002],[-111.49638400000003,75.83970600000009],[-111.47638699999999,75.839157],[-111.45195000000001,75.83665500000006],[-111.44499200000001,75.83221399999996],[-111.35527000000002,75.72442600000011],[-111.35388199999994,75.7185970000001],[-111.35500299999995,75.7144320000001],[-111.38971700000002,75.66303999999997],[-111.40834000000001,75.62081899999998],[-111.40722700000003,75.61499000000015],[-111.35360700000001,75.57249500000006],[-111.31861900000001,75.5452580000001],[-111.27139299999999,75.522491],[-111.24722299999996,75.51805100000001],[-111.221657,75.51693699999998],[-110.995003,75.52916000000005],[-110.97222899999997,75.53248600000012],[-110.89943700000003,75.55026200000009],[-110.79499799999996,75.56526200000002],[-110.77166699999992,75.56666600000005],[-110.54222099999993,75.5688780000001],[-110.49553699999996,75.56915300000009],[-110.47582999999992,75.56832900000012],[-110.45612299999999,75.56553599999995],[-110.43110699999994,75.55415299999999],[-110.42443799999995,75.54887399999996],[-110.42223399999995,75.54553200000004],[-110.33389299999993,75.53915400000005],[-110.19583099999994,75.53970300000003],[-110.06777999999997,75.54054300000007],[-109.97416699999991,75.53749099999999],[-109.75,75.52970900000003],[-109.55304699999999,75.52165200000002],[-109.30444299999999,75.51499900000005],[-109.25389100000001,75.51416000000012],[-109.18360899999999,75.5086060000001],[-109.07472199999995,75.49832200000009],[-108.936394,75.47665399999994],[-108.89943699999998,75.47637900000012],[-108.89584399999995,75.47720300000009],[-108.891953,75.48027000000002],[-108.91639700000002,75.51332100000013],[-108.92443800000001,75.52388000000002],[-108.83612099999993,75.61276200000003],[-108.8269499999999,75.68664600000005],[-108.84277299999991,75.69135999999997],[-108.88194299999998,75.69220000000007],[-108.91332999999992,75.69108600000004],[-108.94499199999996,75.69497699999994],[-109.05832699999996,75.72804300000007],[-109.05860899999993,75.73304700000006],[-109.0627669999999,75.73776200000009],[-109.12638900000002,75.7494200000001],[-109.21000699999996,75.76277199999998],[-109.26555599999995,75.77026400000005],[-109.30526700000001,75.77110300000004],[-109.45221700000002,75.78305100000006],[-109.62943999999993,75.7999880000001],[-109.63751200000002,75.82276900000011],[-109.62805200000003,75.829163],[-109.62638900000002,75.83248900000001],[-109.65722699999992,75.86637900000011],[-109.66361999999998,75.8708190000001],[-109.72972099999998,75.87664799999993],[-109.737503,75.87664799999993],[-109.845551,75.86303699999996],[-109.85722399999992,75.86080900000002],[-109.88390400000003,75.84999100000005],[-109.90778399999994,75.84999100000005],[-109.9363939999999,75.85664400000002],[-110.05555699999996,75.89054899999991],[-110.05583200000001,75.89443999999997],[-110.04055800000003,75.89860499999998],[-109.92610200000001,75.92776500000008],[-109.826683,75.93054199999995],[-109.697769,75.94026200000008],[-109.672234,75.94386299999991],[-109.65666199999998,75.94802900000002],[-109.42138699999998,76.03581200000002],[-109.30499299999991,76.10054000000014],[-109.30943300000001,76.1060940000001],[-109.313606,76.10914600000007],[-109.396118,76.13304100000005],[-109.69999699999994,76.21887200000003],[-109.72250400000001,76.22221399999995],[-109.80943300000001,76.23442100000011],[-109.83416699999998,76.23609900000002],[-109.858612,76.23580900000002],[-109.882767,76.23387100000008],[-109.89666699999992,76.23027000000002],[-109.902222,76.22608900000012],[-109.90167199999996,76.22109999999998],[-109.88305699999995,76.19886800000012],[-109.88667299999997,76.19497700000005],[-109.89666699999992,76.19358800000003],[-109.91944899999993,76.19663999999995],[-109.94055200000003,76.20248400000014],[-110.01471700000002,76.22970600000008],[-110.06833599999993,76.25000000000006],[-110.08528100000001,76.25582900000006],[-110.12332199999997,76.26609800000006],[-110.15306099999998,76.27388000000002],[-110.201683,76.28553800000003],[-110.24109599999991,76.29054300000013],[-110.26583900000003,76.2913670000001],[-110.33138999999989,76.29081700000006],[-110.35804699999994,76.29220600000002],[-110.372772,76.29443399999997],[-110.38362099999995,76.29776000000004],[-110.39306599999986,76.3919370000001],[-110.38527699999986,76.42303500000008],[-110.38390400000003,76.42747500000013],[-110.28943600000002,76.43304400000011],[-110.095551,76.45416300000011],[-109.80721999999997,76.49054000000012],[-109.74638400000003,76.50555399999996],[-109.71833799999996,76.51527400000003],[-109.70639,76.5211030000001],[-109.70694700000001,76.52609300000012],[-109.71140300000002,76.52998400000001],[-109.72416699999997,76.5316620000001],[-109.74916100000002,76.5316620000001],[-109.81111099999993,76.52720600000004],[-109.83222999999992,76.52916000000005],[-109.84722899999991,76.53248600000006],[-109.83750900000001,76.53887900000007],[-109.75527999999997,76.57276899999994],[-109.70667299999997,76.5874940000001],[-109.64666699999998,76.59332300000011],[-109.56082199999997,76.64082300000007],[-109.5097429999999,76.70832800000005],[-109.30277999999998,76.79693600000013],[-109.222778,76.80802900000015],[-109.12777699999992,76.81944300000004],[-109.02583299999998,76.82276900000011],[-108.97444199999995,76.8160860000001],[-108.95084400000002,76.81164600000011],[-108.93582200000003,76.80941799999994],[-108.91887699999995,76.80941799999994],[-108.88945000000001,76.81414799999999],[-108.84500099999997,76.82360800000004],[-108.8219529999999,76.82998700000007],[-108.81331599999999,76.83387800000014],[-108.813606,76.83776900000004],[-108.81582600000002,76.84304800000001],[-108.81388899999996,76.84748800000006],[-108.78859699999992,76.85720800000013],[-108.77362099999999,76.85775799999999],[-108.74804699999999,76.85582000000005],[-108.65556300000003,76.81749000000008],[-108.65110800000002,76.81359900000001]],[[-97.04527299999995,76.7977600000001],[-97.075287,76.79332000000011],[-97.093887,76.79693600000013],[-97.18859899999995,76.82276900000011],[-97.20056199999999,76.82943700000004],[-97.20083599999992,76.83415200000007],[-97.20083599999992,76.85748299999995],[-97.18749999999994,76.86026000000004],[-97.14917000000003,76.85971100000012],[-97.12887599999999,76.85775799999999],[-97.08694500000001,76.85108900000012],[-97.00500499999998,76.81971699999997],[-96.99722299999996,76.813309],[-97.00917099999998,76.80748],[-97.02639799999992,76.80247500000013],[-97.04527299999995,76.7977600000001]],[[-113.46610999999996,76.766388],[-113.61361699999992,76.71304300000008],[-113.628601,76.70803800000004],[-113.65249599999999,76.70443699999998],[-113.67999299999985,76.70443699999998],[-113.70417799999996,76.70637499999992],[-113.78472899999997,76.71720900000003],[-113.83667000000003,76.71998600000006],[-113.889183,76.7185970000001],[-114.05471799999992,76.70359800000006],[-114.16194200000001,76.71693399999998],[-114.21444699999995,76.72053500000004],[-114.501106,76.73414600000001],[-114.73416099999997,76.746643],[-114.78694200000001,76.75027499999993],[-114.82501200000002,76.753601],[-114.85888699999998,76.75804099999999],[-114.87304699999993,76.76081800000009],[-114.87526700000001,76.76554900000002],[-114.87581599999999,76.770828],[-114.85526999999996,76.79443400000008],[-114.83721899999989,76.80165099999999],[-114.80444299999994,76.813309],[-114.76666299999988,76.82388300000008],[-114.62416099999996,76.86192299999999],[-114.60637700000001,76.86581400000006],[-114.58583099999993,76.86747699999995],[-114.33693700000003,76.87719700000008],[-114.13834400000002,76.88443000000007],[-113.96221899999995,76.88998400000008],[-113.885559,76.89166300000005],[-113.80750299999994,76.8894350000001],[-113.7625119999999,76.88443000000007],[-113.73444399999994,76.87914999999998],[-113.49804699999993,76.83332800000011],[-113.48750299999989,76.82777399999998],[-113.44915799999995,76.77720599999998],[-113.453888,76.77276599999993],[-113.46610999999996,76.766388]],[[-109.06610099999995,76.90054300000008],[-109.07444800000002,76.89471400000008],[-109.12581599999987,76.89860499999998],[-109.229172,76.90693699999997],[-109.254997,76.91081200000013],[-109.29888899999997,76.92221100000006],[-109.30777,76.92804000000007],[-109.30387899999994,76.93386799999996],[-109.28278399999999,76.93775900000003],[-109.256958,76.93887300000006],[-109.20527600000003,76.93525699999998],[-109.17944299999999,76.93248000000006],[-109.12721299999998,76.92387399999996],[-109.09249899999992,76.91220099999992],[-109.07695000000001,76.9060970000001],[-109.06610099999995,76.90054300000008]],[[-97.25639299999995,76.96748400000013],[-97.28416400000003,76.96582000000012],[-97.33500700000002,76.96804800000007],[-97.40943900000002,76.97303799999997],[-97.458618,76.97720300000015],[-97.47305299999994,76.98054500000006],[-97.42388900000003,77.00582900000006],[-97.37470999999994,77.02249100000006],[-97.28611799999987,77.0333250000001],[-97.24305700000002,77.03749100000005],[-97.19915800000001,77.03776600000003],[-97.15472399999993,77.03027300000002],[-97.13667299999997,77.02554299999997],[-97.09222399999999,77.01081800000003],[-97.09306300000003,77.00499000000013],[-97.23110999999994,76.97137500000002],[-97.25639299999995,76.96748400000013]],[[-95.65972899999991,77.05886800000007],[-95.58555599999988,77.05331400000006],[-95.56082200000003,77.05358900000004],[-95.46528599999994,77.0583190000001],[-95.41776999999996,77.05693100000002],[-95.38667299999997,77.05247500000007],[-95.36833199999995,77.04859900000002],[-95.33721899999995,77.03997800000008],[-95.28805499999987,77.02249100000006],[-95.22471599999994,77.00637800000004],[-95.18194599999993,76.99636800000013],[-95.16833499999996,76.99414100000007],[-95.11582900000002,76.99581899999998],[-95,76.99054000000001],[-94.90638699999988,76.976089],[-94.8138889999999,76.97137500000002],[-94.72860699999995,76.97276299999993],[-94.71417200000002,76.97387700000013],[-94.68859900000001,76.97526600000009],[-94.636124,76.97692900000004],[-94.59306300000003,76.97554000000002],[-94.52639799999997,76.96943700000008],[-94.51000999999991,76.966095],[-94.49415599999992,76.96026599999993],[-94.48971599999999,76.95610000000005],[-94.40194699999995,76.91832],[-94.25778200000002,76.89637800000008],[-94.25473,76.89137300000004],[-94.23889199999996,76.8894350000001],[-94.20722999999992,76.88804600000009],[-94.15972899999997,76.887497],[-94.09638999999999,76.88888500000007],[-94.08168,76.89027400000009],[-94.05499299999985,76.89471400000008],[-94.03222699999992,76.90332000000001],[-94.02610799999997,76.90914900000001],[-94.010559,76.91914400000013],[-94.00111399999992,76.92359899999997],[-93.98666399999996,76.92886400000003],[-93.964722,76.93248000000006],[-93.94360399999994,76.93386799999996],[-93.89999399999994,76.93331900000004],[-93.75500499999993,76.922485],[-93.73916600000001,76.92082200000004],[-93.6583399999999,76.909988],[-93.64944500000001,76.90803500000004],[-93.641953,76.90525800000012],[-93.63583399999999,76.89888000000002],[-93.48860200000001,76.83970600000009],[-93.30139200000002,76.76860000000005],[-93.208054,76.74693300000001],[-93.20278899999994,76.74748199999993],[-93.19221499999998,76.747208],[-93.18749999999994,76.74552900000003],[-93.17971799999992,76.74108899999999],[-93.16972399999997,76.68691999999999],[-93.17443800000001,76.67498799999998],[-93.18638599999997,76.66081200000002],[-93.30027799999988,76.55219999999997],[-93.30665599999992,76.54664600000001],[-93.46139499999998,76.49832200000003],[-93.59527600000001,76.46249399999999],[-93.62998999999996,76.45193499999999],[-93.641953,76.44720500000011],[-93.651947,76.44165000000004],[-93.65222199999994,76.43775900000014],[-93.650284,76.43553200000008],[-93.54833999999988,76.38610800000009],[-93.52860999999996,76.38472000000002],[-93.50944500000003,76.38665800000012],[-93.49833699999999,76.38888500000002],[-93.46362299999987,76.39942900000005],[-93.456955,76.40359500000011],[-93.4674,76.40792799999997],[-93.48055999999997,76.40992700000004],[-93.50083899999998,76.4102630000001],[-93.508896,76.40664700000008],[-93.520554,76.40582300000011],[-93.537781,76.407486],[-93.55499299999997,76.41137700000007],[-93.57084699999996,76.41638200000011],[-93.58056599999998,76.42303500000008],[-93.57640100000003,76.42665099999999],[-93.53306599999996,76.44303900000006],[-93.51889,76.44831800000003],[-93.50140399999992,76.4522090000001],[-93.476562,76.45477299999993],[-93.45422399999995,76.45643600000005],[-93.42222600000002,76.45832800000011],[-93.39277600000003,76.46165500000006],[-93.37027,76.46638500000006],[-93.35722399999992,76.4705350000001],[-93.12361099999993,76.57304399999998],[-93.11111499999993,76.58027600000008],[-93.09527600000001,76.59054600000002],[-93.09695399999993,76.59664900000013],[-93.09973100000002,76.601654],[-93.04638699999992,76.6160890000001],[-92.945831,76.62248200000005],[-92.90306099999998,76.62191800000011],[-92.88027999999997,76.62081899999998],[-92.85722399999992,76.61831700000005],[-92.78971899999993,76.60914600000012],[-92.70527600000003,76.59443700000008],[-92.68360899999999,76.59248400000013],[-92.65499899999998,76.59471100000002],[-92.64250199999998,76.59803799999997],[-92.632767,76.60247800000013],[-92.61805700000002,76.607483],[-92.60583499999996,76.61053500000014],[-92.56443799999994,76.6160890000001],[-92.5411069999999,76.61775200000005],[-92.506393,76.61747700000001],[-92.46833800000002,76.61303700000002],[-92.44082599999996,76.60331700000012],[-92.42111199999988,76.59803799999997],[-92.40055799999999,76.594986],[-92.38694800000002,76.59387200000003],[-92.36860699999994,76.59443700000008],[-92.33084099999996,76.59721400000001],[-92.18331899999998,76.61469999999991],[-92.07749899999999,76.63720700000005],[-92.04360999999989,76.64694200000008],[-92.00433299999992,76.65789799999993],[-91.99194299999999,76.66081200000002],[-91.97000100000002,76.66442899999998],[-91.93859900000001,76.66832000000005],[-91.9100039999999,76.6705320000001],[-91.77555799999993,76.67970300000002],[-91.66860999999994,76.68470800000006],[-91.53582799999992,76.68887300000006],[-91.41055299999994,76.6891480000001],[-91.38528399999996,76.68830900000012],[-91.132767,76.66442899999998],[-91.00889599999994,76.65165700000011],[-90.98611499999998,76.64915500000006],[-90.88389599999994,76.62664799999999],[-90.87138399999998,76.62275700000009],[-90.85472099999998,76.61554000000001],[-90.84999099999987,76.60914600000012],[-90.84416199999993,76.6035920000001],[-90.83721899999995,76.59915200000012],[-90.81777999999997,76.59359700000005],[-90.77999899999998,76.58581500000008],[-90.741104,76.58055100000007],[-90.67443800000001,76.57331800000009],[-90.62638899999996,76.56999200000007],[-90.58250399999997,76.56526200000002],[-90.56361400000003,76.559708],[-90.50306699999993,76.53137200000009],[-90.49861099999993,76.52499399999994],[-90.468613,76.47915599999999],[-90.46806300000003,76.47303800000009],[-90.48332199999993,76.46804800000001],[-90.51083399999999,76.46388200000013],[-90.53805499999993,76.46138000000002],[-90.61610399999995,76.45637499999998],[-90.63833599999992,76.45582600000006],[-90.77917500000001,76.46110500000003],[-90.82640099999998,76.46304299999997],[-91.09056099999992,76.47804300000013],[-91.304169,76.50416600000005],[-91.34973100000002,76.50943000000007],[-91.37388599999986,76.51110799999998],[-91.41471899999993,76.51277199999998],[-91.441101,76.51277199999998],[-91.56416299999995,76.50082399999997],[-91.566666,76.49887100000001],[-91.41639699999996,76.46026600000005],[-91.40249599999999,76.45748899999995],[-91.27111799999994,76.4538730000001],[-91.14750699999996,76.45082100000002],[-91.05721999999997,76.45054600000014],[-90.99110399999995,76.44775400000009],[-90.97416699999997,76.44609100000014],[-90.79777499999994,76.42692599999998],[-90.64222699999999,76.41053799999992],[-90.41444399999995,76.40304600000002],[-90.36833199999995,76.39999400000005],[-90.31722999999994,76.39471400000002],[-90.281387,76.38916],[-90.06361400000003,76.36164899999994],[-89.83138999999994,76.34027100000003],[-89.54388399999993,76.31693999999999],[-89.36776699999996,76.30415299999999],[-89.30555700000002,76.299149],[-89.29249600000003,76.29609700000009],[-89.23055999999991,76.27276600000005],[-89.21777299999991,76.26666300000011],[-89.20861799999994,76.26081800000003],[-89.20111099999991,76.25416600000011],[-89.19221499999998,76.24220300000007],[-89.19249000000002,76.23609900000002],[-89.19860799999987,76.22526600000009],[-89.20916699999998,76.22109999999998],[-89.29554699999994,76.19775400000015],[-89.32640099999992,76.18942300000003],[-89.34973099999996,76.18359400000003],[-89.37805199999997,76.18026700000007],[-89.58833299999992,76.16581699999995],[-89.831955,76.16081200000008],[-89.88861099999991,76.16609199999999],[-89.90417500000001,76.16886900000009],[-89.97610500000002,76.17387400000013],[-90.37332200000003,76.18136600000008],[-90.39778099999995,76.18054200000012],[-90.416946,76.17886399999998],[-90.43859899999995,76.17553700000008],[-90.45361300000002,76.17053199999998],[-90.45584099999996,76.16720599999996],[-90.45556599999998,76.16554300000001],[-90.43859899999995,76.1622010000001],[-90.41444399999995,76.15998799999994],[-90.25695799999994,76.14694200000002],[-90.22222899999997,76.14444000000015],[-90.1516719999999,76.14166300000005],[-90.0641629999999,76.13693200000012],[-90.04861499999998,76.13275100000004],[-90.06361400000003,76.12776200000008],[-90.0852809999999,76.1244200000001],[-90.11082499999998,76.124146],[-90.30888400000003,76.13832100000008],[-90.44860799999998,76.15498400000001],[-90.66639700000002,76.16693099999998],[-90.78611799999999,76.17137100000014],[-90.93720999999994,76.1808170000001],[-91.11221299999988,76.19192499999991],[-91.20472699999993,76.2127690000001],[-91.21972699999998,76.21832300000005],[-91.25695799999994,76.22720300000009],[-91.27444499999996,76.23027000000002],[-91.42361499999998,76.2538760000001],[-91.44583099999994,76.25665300000003],[-91.57139599999994,76.26527400000009],[-91.59722899999997,76.2649990000001],[-91.61361699999998,76.26220699999999],[-91.59973099999996,76.25610400000005],[-91.579453,76.25166300000012],[-91.41665599999999,76.22526600000009],[-91.33277900000002,76.214157],[-91.33666999999997,76.17858899999999],[-91.27194199999991,76.15582299999994],[-91.22027600000001,76.16165199999995],[-91.20333900000003,76.16137700000013],[-91.16332999999997,76.15971400000001],[-91.11665299999999,76.15637200000009],[-90.88249199999996,76.1372070000001],[-90.700287,76.11943100000013],[-90.67971799999998,76.11720300000002],[-90.665009,76.11219800000015],[-90.75750699999998,76.07638500000013],[-90.78527799999995,76.07276900000005],[-90.80943299999996,76.07193000000007],[-90.833618,76.07276900000005],[-90.85527000000002,76.07222000000013],[-90.86250299999995,76.06999200000013],[-90.866104,76.06721500000003],[-90.86471599999999,76.06498700000009],[-90.84889199999998,76.06080600000001],[-90.71578199999999,76.06343099999998],[-90.70360599999992,76.06492600000001],[-90.66394000000003,76.07426500000003],[-90.66094199999986,76.07643100000001],[-90.61166400000002,76.08471700000007],[-90.59916699999997,76.08804299999997],[-90.57501200000002,76.09027100000009],[-90.54833999999994,76.0913700000001],[-90.47416699999997,76.08970600000004],[-90.42944299999999,76.08831800000013],[-90.408615,76.08638000000002],[-90.19444299999992,76.06275900000014],[-90.19055200000003,76.06109600000002],[-90.19387799999998,76.055252],[-90.20249899999999,76.05026199999998],[-90.215012,76.04582199999993],[-90.23388699999992,76.0410920000001],[-90.27416999999997,76.03442400000012],[-90.30166600000001,76.032486],[-90.32861300000002,76.03137200000003],[-90.40472399999993,76.03109699999999],[-90.63594799999998,76.02815200000003],[-90.71845200000001,76.02265899999998],[-90.90417500000001,76.01554900000002],[-90.92916899999989,76.01554900000002],[-91.00527999999997,76.02499400000005],[-91.14472999999998,76.02110299999998],[-91.16082799999992,76.01805100000007],[-91.15527299999991,76.01416],[-91.06973299999993,75.99026500000002],[-90.95028699999995,75.9622040000001],[-90.94193999999999,75.95555100000013],[-90.93859899999995,75.95138500000002],[-90.94193999999999,75.94552600000003],[-90.94888299999997,75.93997200000001],[-90.96806300000003,75.9310910000001],[-91.016953,75.92553700000008],[-91.07055700000001,75.922485],[-91.100281,75.9185940000001],[-91.11888099999993,75.91387900000007],[-91.12943999999999,75.90860000000009],[-91.14334099999996,75.89721700000007],[-91.12582399999985,75.857483],[-91.13249200000001,75.85192899999998],[-91.13583399999993,75.84609999999998],[-91.13417099999992,75.84248400000013],[-91.12999000000002,75.839157],[-91.10749800000002,75.84054599999996],[-91.09167500000001,75.84332300000005],[-91.07945299999994,75.84803800000009],[-91.0533289999999,75.88108799999998],[-90.93998699999997,75.91526800000008],[-90.90306099999992,75.92469800000015],[-90.89584400000001,75.92720000000003],[-90.886124,75.93165599999998],[-90.847778,75.95220899999998],[-90.833618,75.96026599999999],[-90.827789,75.966385],[-90.80555700000002,75.98553500000014],[-90.79388399999999,75.99470500000001],[-90.77749599999999,75.99609400000003],[-90.75584399999997,75.99498000000006],[-90.71722399999993,75.98915100000005],[-90.56945799999994,75.97998000000007],[-90.48332199999993,75.98027000000008],[-90.464447,75.97859199999999],[-90.44471699999997,75.97415199999995],[-90.43331899999998,75.97026100000005],[-90.42944299999999,75.96832300000011],[-90.43415800000002,75.96331800000007],[-90.44249000000002,75.95971700000001],[-90.49221799999998,75.94581600000004],[-90.51916499999999,75.93609600000013],[-90.52610799999997,75.93054199999995],[-90.52833599999991,75.92553700000008],[-90.53138699999994,75.91360500000013],[-90.53167699999995,75.90359500000005],[-90.52999899999986,75.89833100000004],[-90.521118,75.8955380000001],[-90.50472999999994,75.89526399999994],[-90.49694799999997,75.89776600000005],[-90.34722899999997,75.9494170000001],[-90.34222399999999,75.95304900000008],[-90.337784,75.96304300000008],[-90.339447,75.96832300000011],[-90.25695799999994,75.96693399999998],[-90.11805700000002,75.94192499999997],[-90.11444099999994,75.94775399999997],[-90.10249299999998,75.96165499999995],[-90.07250999999997,75.99552900000015],[-90.060272,76.00471500000009],[-90.05277999999998,76.00721700000003],[-90.03750600000001,76.00915500000013],[-90.015015,76.01026900000011],[-89.96665999999988,76.00860599999999],[-89.947495,76.00721700000003],[-89.92971799999992,76.00471500000009],[-89.92443799999995,76.00221300000004],[-89.90916399999998,75.96499599999999],[-89.82501200000002,75.94303899999994],[-89.68749999999994,75.89999399999999],[-89.68998699999992,75.89498900000012],[-89.702225,75.87970000000007],[-89.70944199999991,75.87414600000005],[-89.72444199999995,75.86303699999996],[-89.75029,75.84664900000013],[-89.77278100000001,75.83638000000008],[-89.778885,75.83166500000004],[-89.78222700000003,75.82582100000002],[-89.77639799999997,75.79275500000006],[-89.77500899999995,75.7874910000001],[-89.76501499999995,75.78581200000008],[-89.73889199999996,75.78665200000012],[-89.69249000000002,75.79637100000014],[-89.68638599999997,75.80247499999996],[-89.68804899999998,75.80442800000009],[-89.68916299999995,75.809708],[-89.68554699999999,75.81414799999999],[-89.61999499999996,75.8535920000001],[-89.61111499999993,75.85720800000013],[-89.58750899999995,75.85914600000007],[-89.558334,75.857483],[-89.43916300000001,75.845261],[-89.42277499999994,75.8419340000001],[-89.41027799999995,75.82971200000009],[-89.39250199999998,75.82110599999999],[-89.37777699999998,75.816666],[-89.32000700000003,75.80386399999998],[-89.27749599999993,75.79832499999998],[-89.20140100000003,75.78692600000005],[-89.172775,75.78054800000012],[-89.16416900000002,75.7747040000001],[-89.160278,75.76805100000013],[-89.16055299999994,75.75582899999995],[-89.166946,75.7452550000001],[-89.25389099999995,75.63108800000003],[-89.262787,75.62776199999996],[-89.27500899999995,75.62776199999996],[-89.33667000000003,75.62776199999996],[-89.54305999999997,75.61053500000014],[-89.64917000000003,75.61554000000001],[-89.76306199999999,75.57748400000003],[-89.76528899999988,75.57554600000009],[-89.73944099999994,75.57360799999992],[-89.72250400000001,75.57415799999995],[-89.68194599999987,75.57998699999996],[-89.64999399999999,75.5872040000001],[-89.60555999999991,75.58970599999998],[-89.58833299999992,75.58859300000006],[-89.550995,75.57971199999997],[-89.54249600000003,75.57054099999999],[-89.54861499999998,75.56608599999998],[-89.56806899999998,75.5619200000001],[-89.62832599999996,75.56137099999995],[-89.67639200000002,75.56219499999992],[-89.69249000000002,75.56109600000013],[-89.706955,75.55748000000006],[-89.70083599999998,75.55304000000007],[-89.64555399999995,75.54832500000003],[-89.57667499999997,75.54775999999998],[-89.55082700000003,75.54887399999996],[-89.52639799999992,75.5519260000001],[-89.515015,75.55415299999999],[-89.500565,75.55886800000002],[-89.49194299999999,75.56553599999995],[-89.47361799999987,75.5747070000001],[-89.458618,75.57943699999993],[-89.441666,75.583328],[-89.431671,75.584427],[-89.40333599999997,75.5872040000001],[-89.35166900000002,75.58915700000006],[-89.30221599999999,75.58915700000006],[-89.23582499999998,75.58665500000012],[-89.21722399999999,75.58499100000012],[-89.18277,75.57720899999998],[-89.17443800000001,75.572769],[-89.16833500000001,75.56666600000005],[-89.15638699999994,75.54971300000011],[-89.15499899999998,75.54443400000014],[-89.14917000000003,75.53221100000007],[-89.14306599999998,75.52442900000011],[-89.09973100000002,75.48414600000007],[-88.96389799999997,75.43193100000008],[-88.95056199999993,75.42970300000013],[-88.92138699999998,75.42719999999997],[-88.87110899999999,75.43414300000012],[-88.84167500000001,75.43637100000007],[-88.81861899999996,75.43692000000004],[-88.79695100000004,75.4349820000001],[-88.77972399999999,75.43248],[-88.76888999999994,75.434708],[-88.74777199999994,75.4708250000001],[-88.75,75.47499100000005],[-88.80139200000002,75.53137200000015],[-88.86582900000002,75.58610500000009],[-88.75500499999998,75.67665099999994],[-88.73889200000002,75.67942800000003],[-88.72277799999989,75.67915300000004],[-88.67832900000002,75.67526199999998],[-88.63166799999999,75.66720600000008],[-88.60082999999992,75.65942400000012],[-88.57417299999992,75.64888000000008],[-88.54277000000002,75.63581800000003],[-88.50778200000002,75.61943100000008],[-88.44888300000002,75.59526100000005],[-88.39944500000001,75.579163],[-88.36416600000001,75.5688780000001],[-88.31582600000002,75.55636600000008],[-88.228882,75.5394290000001],[-88.20361300000002,75.5310970000001],[-88.19888299999997,75.52859500000005],[-88.19694500000003,75.52276600000005],[-88.19860799999998,75.51721200000003],[-88.20140100000003,75.51220699999999],[-88.21749899999992,75.50972000000007],[-88.24082899999996,75.50915500000008],[-88.29083300000002,75.49693300000007],[-88.3058319999999,75.49220300000007],[-88.30139199999996,75.48803700000013],[-88.29527300000001,75.48498500000005],[-88.26306199999993,75.47608900000012],[-88.228882,75.47109999999998],[-88.21305799999999,75.4705350000001],[-88.20083599999992,75.47192400000012],[-88.148056,75.48887600000012],[-88.12249799999995,75.50109900000001],[-88.06806899999998,75.52192700000006],[-87.958054,75.54414400000013],[-87.75140399999992,75.57666000000006],[-87.71611000000001,75.57527199999993],[-87.69776899999994,75.57360799999992],[-87.66139199999992,75.56721500000015],[-87.648346,75.5619200000001],[-87.495544,75.48580900000002],[-87.49499500000002,75.48387100000008],[-87.49888599999991,75.47804300000013],[-87.50473,75.474426],[-87.52999899999992,75.46527100000014],[-87.56388900000002,75.45915200000007],[-87.58860799999997,75.45637500000004],[-87.60139499999997,75.45332300000007],[-87.60638399999993,75.44970700000005],[-87.59472699999998,75.44636500000007],[-87.58277899999996,75.444702],[-87.56834400000002,75.44358800000003],[-87.54861499999993,75.44442700000013],[-87.53361499999988,75.44609099999997],[-87.5,75.4522090000001],[-87.45973200000003,75.46138000000008],[-87.44583099999994,75.46527100000014],[-87.43443300000001,75.46887199999998],[-87.4183349999999,75.47970600000008],[-87.41639700000002,75.48526000000004],[-87.43028300000003,75.50109900000001],[-87.43777499999999,75.5086060000001],[-87.44444299999992,75.51388500000007],[-87.46665999999999,75.5211030000001],[-87.46278399999994,75.56303400000007],[-87.39306599999998,75.6041560000001],[-87.38110399999994,75.609421],[-87.35472099999998,75.61303700000002],[-87.28555299999988,75.62025500000004],[-87.26333599999998,75.62109400000003],[-87.25111400000003,75.62109400000003],[-87.23416099999992,75.6183170000001],[-87.08805799999993,75.57998699999996],[-87.07917800000001,75.56666600000005],[-87.07278399999996,75.55998199999999],[-87.05526700000001,75.54693600000002],[-87.01194800000002,75.53137200000015],[-86.96749899999998,75.518326],[-86.931107,75.50804100000005],[-86.914444,75.50387600000005],[-86.86277799999993,75.49165300000004],[-86.80749500000002,75.47915600000005],[-86.77111799999994,75.47554000000014],[-86.72222899999997,75.47499100000005],[-86.64334099999996,75.47804300000013],[-86.631104,75.47776799999991],[-86.60194399999995,75.47637900000012],[-86.58389299999988,75.47470100000004],[-86.56750499999998,75.47221400000012],[-86.48332199999993,75.45665000000002],[-86.464722,75.45277399999998],[-86.37554899999998,75.42747500000013],[-86.36555499999997,75.42330900000007],[-86.36888099999999,75.41832000000011],[-86.38917500000002,75.40776100000005],[-86.400284,75.40220599999998],[-86.41528299999999,75.39888000000013],[-86.50639299999995,75.38804600000003],[-86.55387899999994,75.38136300000008],[-86.57667500000002,75.37719700000002],[-86.61111499999998,75.36831699999999],[-86.61527999999998,75.36554000000007],[-86.59666399999998,75.361649],[-86.54472399999997,75.35914600000001],[-86.52027900000002,75.36025999999998],[-86.49194299999994,75.36276200000009],[-86.37609900000001,75.37637300000006],[-86.35833699999995,75.37969999999996],[-86.24527,75.40193200000004],[-86.19860799999992,75.41609199999994],[-86.16999799999996,75.41859400000004],[-86.08250399999997,75.42137100000014],[-86.03138699999994,75.42248500000011],[-85.833618,75.41609199999994],[-85.68055700000002,75.40803499999998],[-85.67443800000001,75.41832000000011],[-85.90861499999994,75.4602660000001],[-86.00639299999989,75.47221400000012],[-86.10972600000002,75.48193400000002],[-86.12471,75.48553500000008],[-86.13833599999992,75.48997500000007],[-86.14944500000001,75.49636800000007],[-86.154449,75.50082399999997],[-86.14306599999998,75.50804100000005],[-86.11332699999997,75.51499900000005],[-86.09695399999998,75.51776099999995],[-86.00389100000001,75.53137200000015],[-85.90861499999994,75.54386899999992],[-85.86555499999997,75.54470800000007],[-85.76306199999999,75.54609700000009],[-85.44387799999987,75.56025699999998],[-85.32917800000001,75.56109600000013],[-85.30332899999996,75.5688780000001],[-85.18998699999992,75.61192300000005],[-85.07417299999992,75.65193199999999],[-85.05444299999999,75.65609699999999],[-85.03916900000002,75.657761],[-84.92694099999994,75.65887499999997],[-84.87916599999988,75.65693700000003],[-84.79722600000002,75.65277100000014],[-84.76306199999993,75.65026900000004],[-84.71833799999996,75.64276100000006],[-84.68388399999992,75.63443000000012],[-84.62249799999995,75.62803600000007],[-84.59973100000002,75.62664799999999],[-84.57223499999998,75.626373],[-84.524719,75.62803600000007],[-84.4974979999999,75.63165300000003],[-84.50306699999999,75.633331],[-84.51945499999994,75.63610800000004],[-84.53999299999998,75.6377720000001],[-84.55722000000003,75.63888500000013],[-84.60777300000001,75.63916],[-84.63110399999988,75.64054899999996],[-84.65110799999997,75.64359999999999],[-84.65722699999992,75.64749100000006],[-84.66361999999998,75.68609600000002],[-84.644455,75.68719499999997],[-84.48277300000001,75.69442700000008],[-84.35055499999987,75.69775400000003],[-84.32278399999996,75.69914199999994],[-84.29916400000002,75.70277400000009],[-84.07055699999995,75.76193200000012],[-83.92944299999988,75.81080600000007],[-83.87815099999995,75.81896200000006],[-83.76722699999993,75.82415800000012],[-83.74055499999997,75.82443200000006],[-83.72250399999996,75.822495],[-83.70388799999995,75.81832900000006],[-83.69804399999992,75.81442300000003],[-83.70638999999994,75.81219500000009],[-83.72193900000002,75.81080600000007],[-83.74888599999997,75.80664100000007],[-83.752228,75.801376],[-83.73693800000001,75.79525800000005],[-83.69860799999998,75.79026800000003],[-83.67277499999994,75.78887900000001],[-83.61999500000002,75.78942900000004],[-83.56610099999989,75.7916560000001],[-83.51528899999988,75.78970300000015],[-83.49526999999995,75.78637700000013],[-83.47972099999993,75.78221100000002],[-83.464722,75.77609300000012],[-83.45834400000001,75.77026400000005],[-83.447769,75.75582899999995],[-83.43360899999999,75.75027499999999],[-83.41915899999987,75.74887099999995],[-83.29222099999993,75.73776200000009],[-83.12361099999998,75.73442100000005],[-83.06527699999992,75.73915100000005],[-82.96000700000002,75.756104],[-82.82028200000002,75.78193700000008],[-82.79943799999995,75.78610200000008],[-82.66471899999999,75.81137100000012],[-82.46640000000002,75.82804899999996],[-82.32722499999994,75.836929],[-82.27917500000001,75.83665500000006],[-82.13999899999988,75.82693499999999],[-81.95666499999993,75.81526199999996],[-81.885559,75.81109600000008],[-81.66082799999992,75.81137100000012],[-81.53694199999995,75.809418],[-81.45056199999999,75.80081200000006],[-81.21250900000001,75.77137800000008],[-81.22084000000001,75.70471200000003],[-81.27667199999996,75.66832000000005],[-81.281677,75.66360500000002],[-81.285278,75.657486],[-81.271118,75.65138200000013],[-81.256958,75.649719],[-81.01000999999997,75.633331],[-80.98388699999998,75.633331],[-80.85777299999995,75.634995],[-80.77999899999992,75.6377720000001],[-80.54722600000002,75.65081800000002],[-80.50250199999994,75.65220600000009],[-80.48055999999997,75.651093],[-80.46665999999999,75.649429],[-80.31695599999995,75.63053900000006],[-80.275284,75.6249850000001],[-80.25611900000001,75.62164300000012],[-80.19915800000001,75.60887100000014],[-80.101944,75.58692900000005],[-80.06834400000002,75.57887299999999],[-79.95361299999996,75.54026800000008],[-79.94860799999992,75.53414900000001],[-79.95611599999995,75.530823],[-80.0850069999999,75.50776699999994],[-80.19166599999988,75.48997500000007],[-80.25250199999999,75.48580900000002],[-80.35526999999996,75.47387700000007],[-80.37193299999996,75.46887199999998],[-80.37304699999993,75.46304299999997],[-80.358337,75.45860299999998],[-80.33860799999991,75.45637500000004],[-80.30665599999992,75.45609999999999],[-80.10804699999994,75.46914700000002],[-80.0002899999999,75.47692899999998],[-79.92916899999994,75.47970600000008],[-79.73332199999993,75.47192400000012],[-79.714722,75.4705350000001],[-79.64416499999999,75.46249400000005],[-79.58639499999998,75.45471200000009],[-79.5747219999999,75.44999700000005],[-79.581955,75.44636500000007],[-79.635559,75.44581599999998],[-79.656387,75.44413800000007],[-79.67555199999993,75.44136000000003],[-79.68305999999995,75.43580600000007],[-79.68249500000002,75.4308170000001],[-79.62222300000002,75.40248099999997],[-79.60555999999997,75.39804100000015],[-79.56166099999996,75.39498900000007],[-79.52000399999997,75.391098],[-79.50306699999999,75.38859600000006],[-79.48805199999993,75.383331],[-79.48693799999995,75.37997400000006],[-79.48860199999996,75.36248799999993],[-79.51000999999997,75.33804300000008],[-79.52749599999993,75.32222000000007],[-79.53944399999989,75.31776399999995],[-79.56332399999997,75.31860400000005],[-79.59666400000003,75.31608600000004],[-79.6100009999999,75.31080600000001],[-79.61471599999993,75.305542],[-79.61193800000001,75.29832500000009],[-79.5875089999999,75.28749100000005],[-79.57084700000001,75.283051],[-79.54888900000003,75.28109699999999],[-79.443085,75.28019000000006],[-79.50695799999988,75.22998000000007],[-79.571121,75.19914200000005],[-79.62943999999999,75.17498799999993],[-79.65167200000002,75.172485],[-79.73194899999993,75.16470300000003],[-79.77417000000003,75.16720599999996],[-79.835556,75.16026299999999],[-79.92944299999988,75.14054900000008],[-79.94415299999991,75.13638300000002],[-79.95472699999993,75.12692300000009],[-79.95584100000002,75.11387600000012],[-79.95527599999997,75.10664400000002],[-79.95584100000002,75.10026600000003],[-79.96055599999988,75.09471100000013],[-79.97416699999985,75.08998100000008],[-80.12887599999999,75.06805400000002],[-80.15083299999998,75.06553600000007],[-80.215012,75.063309],[-80.296112,75.05886800000007],[-80.44055200000003,75.03804000000002],[-80.42748999999992,75.02998400000013],[-80.40249599999993,75.02110300000004],[-80.32749899999999,74.99859600000013],[-80.31054699999999,74.99636800000013],[-80.29722599999997,74.996643],[-80.23889200000002,74.99443100000013],[-80.19444299999998,74.98997500000002],[-80.18221999999992,74.986649],[-80.17388899999992,74.98248300000006],[-80.18415800000002,74.97943099999998],[-80.21611000000001,74.976089],[-80.24305700000002,74.97303800000003],[-80.25834700000001,74.96971100000007],[-80.27194199999997,74.96499600000004],[-80.27888499999995,74.95942700000006],[-80.27888499999995,74.95721400000008],[-80.27417000000003,74.95109600000012],[-80.26611299999996,74.94664000000006],[-80.24082899999996,74.94664000000006],[-80.03361499999994,74.97442600000011],[-80.0269469999999,74.97998000000007],[-80.01306199999999,74.9869230000001],[-79.975281,74.9994200000001],[-79.94276400000001,75.00694300000009],[-79.91915899999992,75.01054399999998],[-79.79527300000001,75.02748099999997],[-79.776947,75.02832000000012],[-79.71640000000002,75.02886999999998],[-79.69276399999995,75.02804600000002],[-79.61389199999996,75.01998900000001],[-79.59722899999997,75.01748700000013],[-79.58250399999991,75.01443500000005],[-79.50500499999993,74.99832199999997],[-79.50195300000001,74.99581900000004],[-79.50723299999999,74.99304200000012],[-79.53582799999992,74.9916530000001],[-79.55555700000002,74.98719800000009],[-79.55194099999994,74.98165900000009],[-79.464722,74.9333190000001],[-79.4424899999999,74.92164600000007],[-79.42639200000002,74.91720600000002],[-79.391953,74.91110200000003],[-79.35722399999986,74.90748600000012],[-79.33860800000002,74.90332000000006],[-79.33473200000003,74.89999399999999],[-79.33361799999994,74.89637800000014],[-79.33361799999994,74.89444000000003],[-79.33583099999993,74.88916000000012],[-79.370544,74.87637300000011],[-79.39083900000003,74.87248200000005],[-79.50195300000001,74.85942100000011],[-79.53028899999993,74.85775800000005],[-79.58000199999998,74.85832199999999],[-79.73277300000001,74.83665500000012],[-79.85194399999995,74.81887800000004],[-79.86054999999999,74.81469700000014],[-79.8805539999999,74.81303400000007],[-79.93055700000002,74.81330900000006],[-80.06806899999998,74.83638000000008],[-80.25306699999993,74.87081899999998],[-80.27417000000003,74.88108799999998],[-80.28195199999999,74.88998400000008],[-80.29388399999993,74.91998300000012],[-80.29361,74.92637600000006],[-80.29695100000004,74.93109099999992],[-80.30638099999999,74.9391480000001],[-80.32167099999998,74.93775900000009],[-80.33528099999995,74.93304400000005],[-80.362213,74.92359900000002],[-80.38612399999988,74.91360499999996],[-80.396118,74.90859999999992],[-80.41305499999999,74.89776600000005],[-80.41665599999993,74.89387499999998],[-80.41610700000001,74.88888500000013],[-80.36111499999998,74.86886600000003],[-80.34777799999995,74.86499000000015],[-80.32972699999999,74.86137400000007],[-80.29695100000004,74.85693400000008],[-80.261124,74.85276799999997],[-80.22416699999997,74.84942600000005],[-80.18638599999997,74.84332300000011],[-80.15360999999996,74.83665500000012],[-80.108612,74.82443200000006],[-80.097778,74.82026700000006],[-80.10166899999996,74.78915400000005],[-80.15916400000003,74.73026999999996],[-80.19137599999993,74.69802900000008],[-80.15611299999995,74.63693200000006],[-80.14889499999992,74.63108800000003],[-80.14666699999998,74.62692300000003],[-80.14944499999996,74.6224820000001],[-80.16139199999992,74.61219800000009],[-80.231674,74.57804900000008],[-80.24804699999999,74.57609600000012],[-80.253716,74.57605000000007],[-80.33999599999999,74.58055100000013],[-80.38500999999997,74.5816650000001],[-80.454453,74.58082599999994],[-80.46888699999994,74.57943699999998],[-80.48889199999996,74.57554600000009],[-80.59167499999995,74.56442300000009],[-80.75306699999999,74.56330900000012],[-80.84416199999998,74.56275900000009],[-80.95195000000001,74.56608600000004],[-80.97471599999994,74.56693999999999],[-80.99415599999992,74.56971700000008],[-81.02999899999998,74.57666000000006],[-81.04972799999996,74.57916300000005],[-81.06945799999988,74.57971199999997],[-81.21916199999998,74.57138100000009],[-81.26972999999998,74.56608600000004],[-81.28750599999995,74.56303400000007],[-81.51083399999999,74.51443499999993],[-81.67083699999995,74.4785920000001],[-81.75917099999992,74.46110500000009],[-81.78500399999996,74.45776400000005],[-81.81082199999997,74.45694000000009],[-81.85472099999998,74.45942700000012],[-82.06054699999993,74.47554000000002],[-82.08168,74.47720300000009],[-82.10139500000002,74.47970600000008],[-82.32749899999999,74.5105440000001],[-82.511124,74.52720600000004],[-82.55721999999997,74.5147090000001],[-82.57472200000001,74.51165800000007],[-82.59249899999998,74.5105440000001],[-82.61527999999998,74.51110800000004],[-82.74749799999995,74.51805100000001],[-82.78361499999994,74.520264],[-82.87193300000001,74.53858900000006],[-82.91416900000002,74.549149],[-82.95361300000002,74.565811],[-83.01834099999991,74.59443699999991],[-83.05638099999999,74.61554000000001],[-83.07972699999993,74.63026400000007],[-83.08860799999997,74.63665800000012],[-83.09249899999998,74.64137299999999],[-83.10221899999993,74.65415999999999],[-83.12388599999997,74.68498200000005],[-83.12805199999997,74.69192500000003],[-83.13194299999998,74.70832800000011],[-83.12805199999997,74.71748400000007],[-83.10777299999995,74.74803200000002],[-83.09083599999985,74.75776700000011],[-83.07501200000002,74.76220699999993],[-83.04138199999994,74.76998900000007],[-83.02888499999995,74.77499399999994],[-83.02305599999994,74.78054800000012],[-83.02417000000003,74.78332500000005],[-83.08168,74.81805400000007],[-83.09584000000001,74.82388300000008],[-83.10526999999996,74.82666],[-83.116104,74.82859799999994],[-83.15583799999996,74.82693500000005],[-83.20306399999998,74.820831],[-83.22778299999987,74.82054099999999],[-83.24888599999997,74.82360800000009],[-83.29972799999996,74.83554100000015],[-83.33666999999997,74.84942600000005],[-83.380829,74.86637900000011],[-83.40222199999994,74.87525900000014],[-83.47555499999993,74.89665200000007],[-83.51139799999999,74.90165700000011],[-83.52806099999998,74.90165700000011],[-83.54750099999995,74.89749100000006],[-83.55972300000002,74.89248700000007],[-83.56054699999999,74.88720699999999],[-83.55943300000001,74.88081400000004],[-83.55694599999993,74.87525900000014],[-83.527222,74.84526100000005],[-83.51861600000001,74.83943200000004],[-83.47250400000001,74.81526200000002],[-83.45861799999994,74.80802899999998],[-83.42999299999991,74.79748499999994],[-83.39416499999999,74.79026800000003],[-83.37527499999993,74.78692600000011],[-83.35499599999997,74.784424],[-83.32749899999993,74.77916000000005],[-83.318893,74.77499399999994],[-83.32417299999997,74.75526400000012],[-83.32749899999993,74.75],[-83.45472699999999,74.591095],[-83.47444199999995,74.57971199999997],[-83.48416099999997,74.57499699999994],[-83.59889199999998,74.5435940000001],[-83.61166400000002,74.540817],[-83.72083999999995,74.54553200000004],[-83.78555299999994,74.54859899999997],[-83.80555699999996,74.55081200000012],[-83.83084099999996,74.55137600000006],[-83.85527000000002,74.55081200000012],[-83.90750100000002,74.54693600000007],[-84.03778099999994,74.53414900000007],[-84.06332399999997,74.530823],[-84.10749800000002,74.52331499999997],[-84.14584400000001,74.51554899999996],[-84.21640000000002,74.50721699999997],[-84.23889200000002,74.50555400000002],[-84.28555299999994,74.50360100000006],[-84.3327789999999,74.5038760000001],[-84.35583500000001,74.50444000000005],[-84.396118,74.50749200000013],[-84.64167800000001,74.50694300000004],[-84.850281,74.50221299999998],[-84.87138400000003,74.50138900000002],[-84.88945000000001,74.50221299999998],[-84.89944500000001,74.50332600000007],[-84.91194200000001,74.5080410000001],[-84.91665599999993,74.51110800000004],[-84.98306300000002,74.57054100000005],[-84.985275,74.57916300000005],[-84.97471599999994,74.61747700000006],[-84.96028100000001,74.65693700000008],[-84.95500199999987,74.66276600000009],[-84.95083599999998,74.66886900000003],[-84.95083599999998,74.6727600000001],[-84.95249899999999,74.67915300000004],[-84.95556599999998,74.68470800000011],[-84.96417200000002,74.69192500000003],[-84.97332799999987,74.69609100000014],[-84.99055499999997,74.69802900000008],[-85.00334199999998,74.69747900000004],[-85.06388899999996,74.651657],[-85.07250999999997,74.64109800000011],[-85.04472399999992,74.61219800000009],[-85.03750600000001,74.54109200000005],[-85.03694199999995,74.53526300000004],[-85.03860499999996,74.5288700000001],[-85.04360999999994,74.52331499999997],[-85.07417299999992,74.50888099999997],[-85.08778399999989,74.50499000000008],[-85.10472099999998,74.50166300000012],[-85.12527499999993,74.49859600000002],[-85.21444699999995,74.49192800000003],[-85.25944500000003,74.49054000000012],[-85.35305799999998,74.49859600000002],[-85.36361699999998,74.501938],[-85.36999500000002,74.50943000000007],[-85.36389199999996,74.53749099999999],[-85.36555499999997,74.54414400000013],[-85.37027,74.55247500000007],[-85.468613,74.65887500000002],[-85.47416699999991,74.66442899999998],[-85.48277300000001,74.67164600000012],[-85.49499499999996,74.67915300000004],[-85.50445599999995,74.68331899999993],[-85.520554,74.68803399999996],[-85.52722199999988,74.68887300000011],[-85.54333500000001,74.68637100000007],[-85.54998799999998,74.68193100000002],[-85.52417000000003,74.59860200000014],[-85.52084400000001,74.59304800000012],[-85.50917099999998,74.57998700000002],[-85.48693800000001,74.56109600000013],[-85.48194899999993,74.55415299999999],[-85.47999600000003,74.54776000000004],[-85.47917199999995,74.54165599999999],[-85.48028599999992,74.53720099999998],[-85.50389100000001,74.5205380000001],[-85.52722199999988,74.51026900000005],[-85.54222099999993,74.50555400000002],[-85.56054699999993,74.50138900000002],[-85.58084099999996,74.49832200000009],[-85.604172,74.49581899999993],[-86.01333599999998,74.47943100000009],[-86.05943300000001,74.4785920000001],[-86.08250399999997,74.47915600000005],[-86.120834,74.48220799999996],[-86.12304699999987,74.48332199999993],[-86.12277199999994,74.48997500000013],[-86.10110500000002,74.51138300000002],[-86.085556,74.52943400000004],[-86.07917800000001,74.53915400000011],[-86.07778899999994,74.54525799999993],[-86.08277900000002,74.55525199999994],[-86.15361000000001,74.60914600000001],[-86.17777999999993,74.61526500000002],[-86.19749499999995,74.61526500000002],[-86.21583599999985,74.61080900000007],[-86.22444199999995,74.60775800000005],[-86.23500100000001,74.60192900000004],[-86.24055499999997,74.59693900000002],[-86.24276699999996,74.59137000000004],[-86.23443599999996,74.5811000000001],[-86.22749299999998,74.57527199999998],[-86.22305299999994,74.56219499999997],[-86.23222399999997,74.54026800000008],[-86.235275,74.53526300000004],[-86.24471999999997,74.52388000000002],[-86.278885,74.50860599999993],[-86.33277900000002,74.49026500000014],[-86.39917000000003,74.47943100000009],[-86.42332499999998,74.47886699999992],[-86.443604,74.48109399999998],[-86.46250899999995,74.48553500000008],[-86.633331,74.526093],[-86.66416899999996,74.53471400000006],[-86.69110099999989,74.54414400000013],[-86.708618,74.55108600000005],[-86.7208399999999,74.55859400000008],[-86.75917099999998,74.58638000000013],[-86.76278699999995,74.59193399999998],[-86.76167299999997,74.59803799999997],[-86.75140399999987,74.60386699999998],[-86.74610899999999,74.60887100000014],[-86.75111400000003,74.61360200000007],[-86.76695299999994,74.61608899999999],[-86.78527799999995,74.61692800000014],[-86.79943799999995,74.61526500000002],[-86.80110199999996,74.61137400000013],[-86.80055199999993,74.55220000000003],[-86.79722600000002,74.5435940000001],[-86.79444899999999,74.53997800000008],[-86.70556599999998,74.50027500000004],[-86.69360399999994,74.46804800000007],[-86.90583800000002,74.46054100000009],[-87.22582999999992,74.4669340000001],[-87.27027899999996,74.46832300000005],[-87.304169,74.47164900000013],[-87.32084699999996,74.476654],[-87.35278299999993,74.49525499999999],[-87.47444199999995,74.47581500000001],[-87.508621,74.46775800000006],[-87.527222,74.46554599999996],[-87.57472200000001,74.46192900000005],[-87.66999800000002,74.45999100000006],[-87.71083099999993,74.46081500000003],[-87.73222399999997,74.46638500000012],[-87.75500499999998,74.47943100000009],[-87.848053,74.47608900000012],[-87.90361000000001,74.47221400000012],[-88.03611799999993,74.47692899999998],[-88.26362599999999,74.48359700000015],[-88.35610999999994,74.48915099999999],[-88.49694799999986,74.49775700000009],[-88.51722699999999,74.49971],[-88.52972399999999,74.501938],[-88.53527799999995,74.50360100000006],[-88.53999299999998,74.50610400000005],[-88.571121,74.54998799999998],[-88.57084699999996,74.5560910000001],[-88.56082199999997,74.59304800000012],[-88.54222099999998,74.61608899999999],[-88.406387,74.73609899999997],[-88.34750400000001,74.78471400000001],[-88.48472599999997,74.85775800000005],[-88.52806099999987,74.90193199999999],[-88.537216,74.90693700000003],[-88.54777499999994,74.907761],[-88.55722000000003,74.90664700000002],[-88.56806899999998,74.90138200000013],[-88.66471899999993,74.844986],[-88.67582700000003,74.83692900000005],[-88.74360699999994,74.78387500000008],[-88.7497249999999,74.77777100000003],[-88.75250199999999,74.768326],[-88.75306699999993,74.756104],[-88.7497249999999,74.74970999999994],[-88.74888599999991,74.74136400000003],[-88.74943499999995,74.72608900000006],[-88.75334199999992,74.71415700000011],[-88.811935,74.67221100000012],[-88.821396,74.66638200000011],[-88.835556,74.66137700000007],[-88.848343,74.65914900000013],[-88.862213,74.65887500000002],[-88.87388599999991,74.6602630000001],[-88.88305699999995,74.66526799999997],[-88.889725,74.67053199999992],[-88.91722099999998,74.71971100000013],[-88.91805999999985,74.73248300000012],[-88.91416899999996,74.749146],[-88.910278,74.75499000000002],[-88.90556300000003,74.75999500000006],[-88.90417499999995,74.76554900000008],[-88.906387,74.77304100000003],[-88.90972899999986,74.77777100000003],[-88.92694099999994,74.78387500000008],[-89.07362399999988,74.83387800000003],[-89.08860800000002,74.83720400000004],[-89.097778,74.83610500000009],[-89.09916699999997,74.8352660000001],[-89.05999800000001,74.79748499999994],[-89.05332900000002,74.79359400000004],[-89.0427699999999,74.78970299999997],[-89.01112399999994,74.78082299999994],[-89.01028399999996,74.77554300000008],[-89.01278699999995,74.77053800000004],[-89.041382,74.73026999999996],[-89.04750100000001,74.722488],[-89.05583200000001,74.71914699999996],[-89.07778899999988,74.71720900000003],[-89.10221899999999,74.71943700000003],[-89.17887899999994,74.73220800000013],[-89.17887899999994,74.73526000000004],[-89.181107,74.73970000000003],[-89.19055199999997,74.74443099999996],[-89.223053,74.75248700000003],[-89.24305700000002,74.75526400000012],[-89.26501499999995,74.7563780000001],[-89.271118,74.75471500000003],[-89.21640000000002,74.72110000000009],[-89.20249899999993,74.71388200000013],[-89.18971299999993,74.70860299999993],[-89.14111299999996,74.69802900000008],[-89.12249799999995,74.69609100000014],[-89.10527000000002,74.69303900000006],[-89.09583999999995,74.68803399999996],[-89.09583999999995,74.68193100000002],[-89.125,74.61692800000014],[-89.13194299999992,74.61137400000013],[-89.15055799999993,74.59971600000011],[-89.185272,74.5874940000001],[-89.19694500000003,74.584427],[-89.43888900000002,74.55081200000012],[-89.45500199999992,74.54859899999997],[-89.48971599999999,74.54553200000004],[-89.58056599999998,74.54026800000008],[-89.92860399999995,74.530823],[-89.94610599999999,74.53221100000013],[-90.10665899999998,74.54942299999993],[-90.22389199999992,74.56359900000012],[-90.24499500000002,74.56693999999999],[-90.26333599999992,74.57054100000005],[-90.36305199999998,74.59471100000007],[-90.45666499999993,74.60081500000007],[-90.49638400000003,74.60165400000005],[-90.52999899999986,74.60525500000011],[-90.589722,74.61331200000006],[-90.60722399999992,74.616379],[-90.61999500000002,74.61998000000006],[-90.70805399999989,74.64804100000015],[-90.73167399999994,74.664154],[-90.73693800000001,74.66943400000002],[-90.739441,74.67387400000007],[-90.747772,74.70304899999996],[-90.75111400000003,74.71638500000006],[-90.86749299999991,74.70248400000008],[-90.87582399999997,74.69192500000003],[-90.885559,74.68359399999997],[-90.89561499999996,74.68113700000009],[-91.01362599999999,74.69886800000006],[-91.02471899999995,74.70277400000009],[-91.02362099999999,74.70694000000003],[-91.01222199999995,74.71720900000003],[-90.97833299999996,74.73970000000003],[-90.965012,74.74775700000004],[-90.94583099999994,74.75138900000013],[-90.93859899999995,74.75082399999997],[-90.92610199999996,74.75166300000006],[-90.896118,74.75749200000007],[-90.88389599999994,74.76165800000001],[-90.85139500000002,74.77609300000012],[-90.75805700000001,74.83110000000005],[-90.75279199999994,74.83581500000008],[-90.74082900000002,74.84748800000011],[-90.74249299999991,74.85276799999997],[-90.74665800000002,74.86053500000008],[-90.75778200000002,74.88081400000004],[-90.77223200000003,74.88499500000012],[-90.816956,74.88360599999999],[-90.84111000000001,74.87942500000008],[-90.85388199999994,74.87525900000014],[-90.86389200000002,74.86998],[-90.87027,74.86442599999998],[-90.874435,74.85914600000012],[-90.87388599999997,74.85304300000001],[-90.883331,74.84165999999999],[-90.97500600000001,74.7994230000001],[-91,74.78970299999997],[-91.07528699999995,74.76110799999998],[-91.10194399999995,74.75109900000012],[-91.132767,74.74443099999996],[-91.14472999999998,74.74748199999999],[-91.14416499999993,74.75138900000013],[-91.14666699999992,74.75555400000013],[-91.17166099999997,74.75749200000007],[-91.18859900000001,74.75277700000004],[-91.21611000000001,74.73887600000006],[-91.22582999999992,74.73359700000009],[-91.22888199999994,74.72776800000008],[-91.226944,74.722488],[-91.18527199999994,74.68470800000011],[-91.17748999999998,74.67803999999995],[-91.15499899999998,74.66554299999996],[-91.11471599999993,74.645828],[-91.10583500000001,74.63998400000014],[-91.09805299999988,74.633331],[-91.09973099999996,74.62831100000011],[-91.10665899999998,74.62580900000006],[-91.13305699999995,74.62442000000004],[-91.256393,74.62858599999998],[-91.45584100000002,74.63970899999998],[-91.53999299999992,74.64637800000003],[-91.55332899999996,74.64833099999998],[-91.6761019999999,74.67192100000011],[-91.68499800000001,74.67776500000014],[-91.67166099999997,74.68969700000008],[-91.66416900000002,74.69331400000004],[-91.63417099999998,74.69609100000014],[-91.62193299999996,74.70027200000004],[-91.62027,74.70498700000007],[-91.624435,74.70999100000006],[-91.63583399999993,74.71527100000009],[-91.65167199999996,74.71998600000012],[-91.708618,74.72747800000008],[-91.75418100000002,74.72776800000008],[-91.779449,74.72581500000013],[-91.79888899999992,74.72221400000006],[-91.81111099999998,74.71804800000001],[-91.81249999999989,74.71304299999997],[-91.80296299999992,74.70618400000001],[-91.79888899999992,74.69941699999998],[-91.81555199999997,74.69470200000012],[-91.83306900000002,74.69609100000014],[-91.85110500000002,74.69886800000006],[-91.86665299999993,74.7022090000001],[-91.87666300000001,74.70694000000003],[-91.87527499999993,74.711929],[-91.85916099999997,74.72110000000009],[-91.89222699999993,74.75082399999997],[-91.96194499999996,74.76416000000006],[-91.99861099999998,74.77304100000003],[-92.01583899999997,74.77832000000001],[-92.045547,74.78970299999997],[-92.05749499999996,74.79664600000001],[-92.06361399999997,74.80358899999999],[-92.06527699999992,74.80720500000001],[-92.06639100000001,74.81330900000006],[-92.05749499999996,74.82499700000011],[-92.05166599999995,74.83055100000007],[-92.04333499999996,74.83638000000008],[-92.01916499999993,74.84609999999998],[-92.01306199999999,74.85192899999998],[-92.00805699999995,74.86360200000001],[-92.006393,74.88804600000014],[-92.01333599999992,74.9083250000001],[-92.01528899999994,74.91360499999996],[-92.04333499999996,74.9519350000001],[-92.04804999999999,74.95832800000005],[-92.06332399999997,74.96388200000007],[-92.0916749999999,74.97164900000001],[-92.1058349999999,74.97665400000005],[-92.16416900000002,74.99803199999997],[-92.20973200000003,75.03858899999994],[-92.228882,75.07110599999999],[-92.22582999999992,75.07388300000008],[-92.21556099999998,75.07638500000013],[-92.18638599999991,75.08137499999998],[-92.15249599999999,75.08387800000014],[-92.11166400000002,75.08194000000003],[-92.04618800000003,75.08496100000008],[-92.02999899999992,75.08638000000002],[-92.01251199999996,75.095261],[-92.01000999999997,75.10108900000012],[-92.05139200000002,75.14694200000002],[-92.05555700000002,75.15026899999998],[-92.0705569999999,75.15304600000007],[-92.083618,75.15332000000001],[-92.10526999999996,75.1519320000001],[-92.193329,75.143326],[-92.32556199999999,75.15165700000006],[-92.49082900000002,75.21360800000008],[-92.46888699999994,75.28471400000012],[-92.428604,75.39444000000009],[-92.38833599999992,75.44192500000008],[-92.32806399999998,75.4891510000001],[-92.22027600000001,75.54609700000009],[-92.21028100000001,75.55137600000006],[-92.19943199999994,75.55386400000003],[-92.15583800000002,75.55664100000013],[-92.100281,75.56275900000009],[-92.08583099999998,75.56498700000003],[-92.069458,75.5688780000001],[-92.05665599999998,75.57304399999998],[-92.01390100000003,75.58915700000006],[-92.00500499999993,75.59498600000006],[-92.00834699999996,75.66137700000007],[-92.04360999999989,75.68553200000008],[-92.05749499999996,75.69135999999997],[-92.08999599999999,75.70027200000004],[-92.13751200000002,75.72110000000009],[-92.15666199999998,75.7310940000001],[-92.17443799999995,75.74443100000013],[-92.17555199999993,75.75054900000009],[-92.139725,75.77831999999995],[-92.11915599999992,75.78915400000005],[-92.11277799999999,75.79470800000001],[-92.10472099999998,75.80525200000005],[-92.10055499999993,75.82304399999992],[-92.10388199999994,75.84136999999993],[-92.10526999999996,75.84748800000006],[-92.108612,75.85887100000008],[-92.11332700000003,75.86360200000001],[-92.12971499999998,75.87637300000011],[-92.13806199999999,75.879974],[-92.15110800000002,75.8830410000001],[-92.17277499999994,75.88554400000004],[-92.215012,75.88832100000013],[-92.23832699999997,75.8913730000001],[-92.31777999999991,75.90498400000007],[-92.33639499999987,75.90860000000009],[-92.408615,75.92858900000004],[-92.43306000000001,75.93637100000001],[-92.44444299999992,75.94108600000004],[-92.583618,76.00888100000003],[-92.63583399999999,76.10415599999999],[-92.63583399999999,76.10971100000006],[-92.63722200000001,76.115814],[-92.79388399999993,76.20748900000001],[-92.80943300000001,76.21249400000005],[-92.94665499999996,76.24581899999993],[-93.066956,76.299149],[-93.07667499999991,76.31693999999999],[-93.05722000000003,76.32666000000006],[-93.05499299999997,76.33248900000007],[-93.05638099999987,76.33859300000012],[-93.05915800000002,76.34387200000009],[-93.07194500000003,76.353317],[-93.083618,76.35803200000004],[-93.11527999999993,76.363876],[-93.13806199999993,76.366379],[-93.186935,76.3683170000001],[-93.21278399999994,76.36804200000012],[-93.23998999999998,76.3666530000001],[-93.31527699999992,76.36025999999998],[-93.34527599999996,76.35609400000004],[-93.38137799999993,76.34637500000008],[-93.449997,76.32638500000007],[-93.56193499999995,76.29721100000006],[-93.58778399999989,76.292755],[-93.61749299999997,76.29109200000005],[-93.63583399999999,76.29165599999999],[-93.6583399999999,76.29386899999997],[-93.66639700000002,76.29859899999997],[-93.65333599999991,76.30276500000008],[-93.62443499999989,76.30581699999999],[-93.62361099999993,76.31080600000013],[-93.636124,76.32666000000006],[-93.6541749999999,76.32582100000013],[-93.67887899999994,76.32222000000007],[-93.718887,76.31248499999998],[-93.73138399999999,76.30693099999996],[-93.76390100000003,76.28637700000002],[-93.76390100000003,76.28221100000013],[-93.76194800000002,76.28027299999997],[-93.75389099999995,76.27581799999996],[-93.74110399999995,76.27192700000006],[-93.720551,76.26776100000001],[-93.69722000000002,76.26388500000013],[-93.78443900000002,76.25305200000014],[-93.954453,76.257767],[-93.95611600000001,76.257767],[-93.95834399999995,76.257767],[-94.09750400000001,76.25943000000012],[-94.11888099999999,76.26138300000002],[-94.13417099999987,76.2647090000001],[-94.14138799999995,76.26998900000012],[-94.1516719999999,76.27415500000006],[-94.16861,76.27832000000006],[-94.21250900000001,76.280823],[-94.47083999999995,76.28109699999993],[-94.64167799999996,76.29332],[-94.78028899999998,76.28887900000007],[-94.78999299999998,76.28360000000009],[-94.80332900000002,76.27832000000006],[-94.83860800000002,76.26832600000006],[-95.02917499999995,76.23609900000002],[-95.35499599999991,76.23414600000012],[-95.37609900000001,76.23442100000011],[-95.38694799999996,76.23580900000002],[-95.38806199999993,76.28360000000009],[-95.374435,76.29776000000004],[-95.36694299999994,76.30137600000006],[-95.35722399999997,76.30276500000008],[-95.34306300000003,76.30026200000009],[-95.31806899999998,76.29081700000006],[-95.27917500000001,76.28137200000015],[-95.258896,76.282761],[-95.11833200000001,76.29803500000003],[-95.09277299999991,76.30276500000008],[-95.07556199999988,76.30775499999993],[-95.06973299999993,76.31330900000012],[-95.06655899999998,76.319862],[-95.05888399999998,76.32470699999993],[-95.01055899999994,76.3311000000001],[-94.98388699999998,76.33248900000007],[-94.95889299999999,76.33221400000008],[-94.91500899999988,76.32971199999997],[-94.86639400000001,76.32554600000009],[-94.84973100000002,76.32331799999997],[-94.84056099999998,76.31971700000008],[-94.84999099999987,76.31442300000009],[-94.86277799999988,76.30998199999999],[-94.86166399999996,76.30693099999996],[-94.843613,76.30386400000003],[-94.82861300000002,76.3060910000001],[-94.80860899999993,76.31137100000001],[-94.80248999999998,76.31553600000001],[-94.80082699999997,76.32165500000002],[-94.81416300000001,76.32916300000005],[-94.83444199999997,76.334427],[-94.89472999999992,76.34166000000005],[-94.965012,76.34748799999994],[-95.132767,76.36137400000013],[-95.274719,76.372208],[-95.29943799999995,76.3724820000001],[-95.32640100000003,76.37081900000004],[-95.33167999999995,76.36526500000002],[-95.34138499999995,76.359711],[-95.38890099999998,76.35192900000004],[-95.39999399999999,76.353317],[-95.44722000000002,76.36581399999994],[-95.64527900000002,76.38415500000013],[-95.66833500000001,76.38610800000009],[-95.71583599999991,76.39221199999992],[-95.73750299999995,76.39387500000004],[-95.85110500000002,76.40109300000006],[-95.995834,76.43691999999999],[-96.08167999999989,76.47804300000013],[-96.10694899999999,76.49443099999996],[-96.10417199999995,76.5],[-96.09916699999991,76.50555399999996],[-96.09056099999998,76.510269],[-96.06555200000003,76.52137800000008],[-96.05248999999992,76.52415500000001],[-95.99722299999996,76.51944000000015],[-95.94499199999996,76.518326],[-95.80638099999993,76.51638800000006],[-95.77860999999996,76.5188750000001],[-95.69415299999997,76.5452580000001],[-95.68055700000002,76.55053700000008],[-95.65777600000001,76.56137100000012],[-95.59388699999994,76.59304800000007],[-95.58416699999998,76.59832799999998],[-95.587784,76.6035920000001],[-95.59944199999995,76.60525500000006],[-95.61971999999997,76.60609400000004],[-95.63890100000003,76.60415600000005],[-95.66027799999995,76.59942600000005],[-95.69610599999999,76.58415200000013],[-95.69554099999999,76.58027600000008],[-95.69665499999996,76.57443200000006],[-95.712784,76.56860399999994],[-95.75917099999998,76.55358899999999],[-95.78056299999992,76.54887400000013],[-95.99249299999997,76.54803499999997],[-96.016953,76.549149],[-96.15861499999994,76.583328],[-96.17860399999995,76.59414700000008],[-96.22528099999988,76.625809],[-96.27027899999996,76.6327510000001],[-96.33944699999995,76.63220199999995],[-96.35583500000001,76.6330410000001],[-96.38137799999987,76.63581800000003],[-96.40333599999991,76.6397090000001],[-96.42138699999998,76.64610299999998],[-96.445831,76.65721100000013],[-96.45417800000001,76.66249099999999],[-96.46139499999992,76.66859399999998],[-96.46112099999999,76.67359900000002],[-96.46444699999995,76.67970300000002],[-96.47027599999996,76.68553200000002],[-96.52778599999994,76.693039],[-96.61193800000001,76.70248400000003],[-96.636124,76.70443699999998],[-96.66166699999997,76.70471200000003],[-96.73693800000001,76.69720500000005],[-96.76417500000002,76.69552600000009],[-96.78971899999993,76.6958160000001],[-96.81639100000001,76.69747899999999],[-96.85777299999995,76.7019350000001],[-96.87999000000002,76.705826],[-96.91583299999996,76.7144320000001],[-96.94665499999996,76.72360200000014],[-96.95916699999998,76.72915599999993],[-96.964447,76.73332200000004],[-96.900284,76.79525800000005],[-96.88722199999995,76.80554200000006],[-96.87388599999991,76.81080600000007],[-96.85499599999997,76.81303400000002],[-96.839722,76.81025700000009],[-96.724716,76.78332499999999],[-96.67971799999992,76.77026400000005],[-96.59249899999992,76.75888100000003],[-96.42610200000001,76.74470500000007],[-96.33029199999993,76.75027499999993],[-96.311935,76.75138900000013],[-96.30555699999996,76.75387599999999],[-96.31555199999997,76.80247500000013],[-96.32055700000001,76.80664100000007],[-96.36694299999994,76.81275899999997],[-96.45361299999996,76.81526200000013],[-96.50111400000003,76.81805400000007],[-96.54722600000002,76.82276900000011],[-96.7975009999999,76.86137400000001],[-96.81361400000003,76.868042],[-96.84889199999992,76.887497],[-96.86582900000002,76.89804100000003],[-96.86915599999998,76.90416000000005],[-96.86944599999998,76.91387900000007],[-96.86416600000001,76.91970800000007],[-96.85777299999995,76.92498799999993],[-96.83361799999994,76.9327550000001],[-96.79638699999998,76.93748499999992],[-96.77194199999997,76.93775900000003],[-96.761124,76.93775900000003],[-96.72389199999998,76.93525699999998],[-96.708054,76.93331900000004],[-96.69860799999998,76.934143],[-96.66082799999998,76.947205],[-96.65916399999998,76.94914200000005],[-96.66776999999996,76.95443699999993],[-96.67777999999998,76.95776400000005],[-96.69694500000003,76.96054100000015],[-96.718887,76.96304300000003],[-96.765289,76.96527100000003],[-96.80833399999995,76.966095],[-96.8244479999999,76.96775800000006],[-96.82778899999994,76.96887200000003],[-96.82556199999999,76.97442600000005],[-96.810272,76.9791560000001],[-96.77203400000002,76.98101800000012],[-96.74203499999999,76.98220800000001],[-96.67332499999998,76.98220800000001],[-96.622772,76.97998000000007],[-96.483612,76.97110000000004],[-96.353882,76.99304200000006],[-96.39111300000002,77.02693199999999],[-96.387787,77.03054800000001],[-96.37332199999997,77.03193700000003],[-96.28472899999997,77.03942899999998],[-96.27305599999994,77.04026799999991],[-96.24499499999996,77.04193100000003],[-96.22610500000002,77.043045],[-96.10305799999998,77.04470800000013],[-95.96665999999999,77.05304000000012],[-95.88806199999993,77.06109600000002],[-95.75250199999999,77.06860400000005],[-95.73472600000002,77.06860400000005],[-95.70750399999991,77.06694000000005],[-95.65972899999991,77.05886800000007]],[[-113.328888,77.07998700000002],[-113.353882,77.07748400000008],[-113.40888999999999,77.07887300000004],[-113.45140099999992,77.08166499999999],[-113.49194299999999,77.08554100000003],[-113.4974979999999,77.08831800000013],[-113.49027999999998,77.09248400000001],[-113.34472700000003,77.12776200000002],[-113.33528099999995,77.12608300000005],[-113.31471299999998,77.11775200000011],[-113.29332699999986,77.10748300000012],[-113.28694200000001,77.09637500000008],[-113.29110700000001,77.08998100000008],[-113.30471799999998,77.08526600000005],[-113.328888,77.07998700000002]],[[-113.77861000000001,77.10415599999999],[-113.80695299999991,77.10415599999999],[-113.85333300000002,77.10554499999995],[-113.88054699999992,77.10803200000004],[-113.90888999999999,77.11303700000008],[-113.92443800000001,77.1185910000001],[-113.93138099999999,77.1244200000001],[-113.93138099999999,77.12969999999996],[-113.92722300000003,77.135269],[-113.920837,77.141098],[-113.90110800000002,77.14637800000003],[-113.880829,77.14971900000006],[-113.859444,77.15138200000001],[-113.798607,77.15248100000002],[-113.77417000000003,77.15165700000006],[-113.72250399999996,77.14804100000015],[-113.69915800000001,77.14471400000002],[-113.67555199999993,77.14027400000003],[-113.66443599999997,77.13472000000002],[-113.65778399999999,77.12914999999992],[-113.66416900000002,77.12303200000002],[-113.67916899999989,77.11692800000014],[-113.703056,77.111649],[-113.72778299999993,77.10803200000004],[-113.75306699999993,77.10554499999995],[-113.77861000000001,77.10415599999999]],[[-104.25250199999999,77.07276900000005],[-104.30277999999998,77.07222000000007],[-104.354172,77.07388300000002],[-104.37721299999998,77.07666000000012],[-104.40222199999994,77.0811000000001],[-104.421944,77.08720399999999],[-104.43167099999994,77.09887700000002],[-104.42639200000002,77.11637900000005],[-104.42027300000001,77.12220800000006],[-104.40556299999997,77.12776200000002],[-104.31973299999999,77.15165700000006],[-104.30082700000003,77.15525800000006],[-104.27333099999998,77.15971400000001],[-104.18360899999993,77.16720599999996],[-104.11389199999996,77.16609199999999],[-104.07140399999997,77.16137700000013],[-104.061394,77.15887500000002],[-104.031113,77.15109300000006],[-104.01972999999998,77.14610300000004],[-104.001106,77.13581800000009],[-103.99889399999995,77.12387099999995],[-104.00945300000001,77.11804200000012],[-104.02416999999991,77.11248799999998],[-104.04778299999992,77.10693400000014],[-104.15028399999994,77.08638000000002],[-104.196663,77.07748400000008],[-104.25250199999999,77.07276900000005]],[[-95.22444200000001,77.16720599999996],[-95.24527,77.164154],[-95.291382,77.16499299999998],[-95.314438,77.1666560000001],[-95.36277799999993,77.171921],[-95.41999800000002,77.18193100000008],[-95.57250999999985,77.21304299999997],[-95.61305199999993,77.22192400000012],[-95.63417099999992,77.22804300000013],[-95.63890100000003,77.23220800000013],[-95.63999899999993,77.23776199999998],[-95.63667299999997,77.23915099999994],[-95.63137799999993,77.23970000000008],[-95.60804699999989,77.24081400000006],[-95.511124,77.243042],[-95.43804899999998,77.24443100000002],[-95.38751200000002,77.24081400000006],[-95.37222300000002,77.23803700000013],[-95.35611,77.23637400000007],[-95.31361400000003,77.22915600000005],[-95.24415599999992,77.21388200000013],[-95.21639999999996,77.20166],[-95.20666499999999,77.18914799999999],[-95.206955,77.17776499999997],[-95.214447,77.17248500000011],[-95.22444200000001,77.16720599999996]],[[-90.93305999999995,77.25444000000005],[-90.90916400000003,77.25166300000012],[-90.81500199999999,77.24026500000014],[-90.77223200000003,77.23136899999997],[-90.73638899999997,77.22082499999993],[-90.71833800000002,77.20721399999996],[-90.71362299999998,77.20082100000002],[-90.72416699999991,77.18331899999998],[-90.73194899999999,77.17776499999997],[-90.77917500000001,77.15664700000008],[-90.81138599999991,77.14665199999996],[-90.83555599999994,77.14221199999997],[-90.86833199999995,77.13832100000008],[-90.89999399999999,77.13693200000006],[-90.9786069999999,77.13777199999993],[-91.04972800000002,77.14553799999999],[-91.18472300000002,77.16360500000008],[-91.22166400000003,77.17025800000005],[-91.23889200000002,77.17442300000005],[-91.26251200000002,77.18414300000012],[-91.28639199999992,77.19664000000012],[-91.295547,77.20332300000007],[-91.29750100000001,77.20721399999996],[-91.29916400000002,77.217758],[-91.277222,77.22747800000013],[-91.24749799999995,77.23580900000002],[-91.18971299999998,77.24803200000008],[-91.162216,77.25138900000002],[-91.10722399999992,77.25471500000003],[-91.08473200000003,77.25444000000005],[-91.07223499999992,77.25332600000007],[-91.05721999999997,77.25444000000005],[-90.987503,77.25499000000008],[-90.93305999999995,77.25444000000005]],[[-116.35109699999998,77.53915400000005],[-116.20333900000003,77.51998900000007],[-116.09056099999992,77.49108900000004],[-116.073624,77.48553500000003],[-115.88027999999991,77.4333190000001],[-115.52055399999995,77.36442600000004],[-115.49526999999989,77.359421],[-115.458054,77.34860200000008],[-115.44611399999985,77.34304800000012],[-115.389183,77.31219499999992],[-115.390289,77.30636600000008],[-115.54332699999986,77.26554899999991],[-115.59110999999996,77.25999500000012],[-115.61694299999999,77.25833100000011],[-115.66915899999992,77.25694299999998],[-115.69499199999996,77.25526400000001],[-115.77250700000002,77.24775700000004],[-115.81973299999999,77.23748800000004],[-115.83084099999991,77.2333220000001],[-115.85888699999998,77.22082499999993],[-115.87777699999992,77.21527100000014],[-115.9469529999999,77.20887799999997],[-116.112503,77.19386300000002],[-116.13806199999999,77.19220000000013],[-116.19055200000003,77.1916500000001],[-116.21777299999997,77.19274900000005],[-116.26917300000002,77.19026199999996],[-116.28056300000003,77.18359400000003],[-116.31416300000001,77.14444000000009],[-116.31973299999999,77.11775200000011],[-116.28028899999998,77.06721500000003],[-116.26917300000002,77.05581700000005],[-116.24249299999991,77.04414400000002],[-116.17360699999989,77.02720600000009],[-116.06388900000002,77.00749200000001],[-116.00583599999999,76.9974820000001],[-115.95028699999995,76.99136399999998],[-115.860817,76.9791560000001],[-115.75499699999995,76.96081500000008],[-115.73889199999996,76.95526100000006],[-115.73137700000001,76.9497070000001],[-115.72833300000002,76.94386300000008],[-115.729446,76.93803400000007],[-115.73222399999997,76.93165600000009],[-115.74610899999999,76.92526200000009],[-115.80695300000002,76.90637200000009],[-115.829453,76.90081800000013],[-115.85333299999996,76.89721700000007],[-115.903343,76.89387499999992],[-115.92859599999997,76.89305099999996],[-115.98194899999993,76.89553800000004],[-116.06388900000002,76.90277100000009],[-116.11501299999992,76.90914900000001],[-116.25389100000001,76.93248000000006],[-116.306107,76.93609600000013],[-116.32721699999996,76.93553200000002],[-116.35166899999996,76.9327550000001],[-116.36527999999993,76.92637600000006],[-116.36721799999998,76.91554300000007],[-116.36332699999997,76.90887500000008],[-116.35555999999985,76.90332000000001],[-116.34612299999992,76.89833100000004],[-116.32972699999999,76.89276099999995],[-116.18360899999993,76.8458250000001],[-116.16388699999999,76.8416600000001],[-116.10749800000002,76.83360299999998],[-116.031113,76.820267],[-116.00029,76.81137100000007],[-115.89472999999992,76.70332300000001],[-115.891388,76.69747899999999],[-115.89666699999998,76.69164999999998],[-116.07140400000003,76.625809],[-116.09306299999992,76.61914100000001],[-116.11582900000002,76.61442599999998],[-116.160553,76.61109900000008],[-116.23194899999999,76.60304300000001],[-116.25446299999999,76.59860200000008],[-116.32250999999997,76.58110000000005],[-116.37351999999993,76.58180200000004],[-116.73277300000001,76.572495],[-116.75890399999992,76.56999200000007],[-116.97112299999998,76.54859899999997],[-116.99471999999992,76.54582200000004],[-117.01750199999992,76.54220599999996],[-117.03999299999992,76.53749099999993],[-117.053879,76.53305100000011],[-117.06861900000001,76.52609300000012],[-117.07556199999993,76.52053800000004],[-117.07749899999999,76.51416000000006],[-117.07640099999998,76.50888100000009],[-117.07277699999997,76.50305200000008],[-117.05695299999996,76.49165299999999],[-117.04360999999989,76.48692299999999],[-117.01750199999992,76.48248300000012],[-117.00389099999995,76.47747800000008],[-116.983612,76.45498700000007],[-116.94082599999996,76.38693200000006],[-116.93916299999995,76.38053900000011],[-116.93582200000003,76.35192900000004],[-116.93859900000001,76.34637500000008],[-117.09555099999994,76.29525799999993],[-117.13971700000002,76.286926],[-117.31973299999999,76.257767],[-117.345551,76.25637799999998],[-117.36888099999999,76.25694300000004],[-117.52390300000002,76.26361100000003],[-117.5750119999999,76.26887499999998],[-117.60305799999998,76.27388000000002],[-117.62304699999999,76.2788700000001],[-117.639183,76.28414900000007],[-117.65778399999999,76.29332],[-117.64917000000003,76.305542],[-117.64890299999996,76.31137100000001],[-117.65527299999997,76.31749000000002],[-117.67304999999993,76.32222000000007],[-117.69915800000001,76.32415800000001],[-117.72416699999997,76.32443200000012],[-117.87777699999998,76.34193399999998],[-117.889183,76.35581999999994],[-117.90139799999997,76.36720300000013],[-117.90695199999993,76.372208],[-117.99722299999996,76.39694199999997],[-118.02139299999999,76.40193200000004],[-118.04444899999999,76.40498400000013],[-118.05999800000001,76.40914900000013],[-118.04750100000001,76.44165000000004],[-118.02749599999999,76.48471100000006],[-117.97332799999998,76.59637500000002],[-117.92832899999996,76.6766510000001],[-117.91915899999992,76.68803400000013],[-117.90666199999993,76.69413799999995],[-117.883331,76.70054600000009],[-117.86444099999994,76.70416300000005],[-117.848053,76.70832800000005],[-117.81331599999999,76.71943699999997],[-117.79638699999998,76.72581500000013],[-117.78806299999997,76.73220800000007],[-117.73889200000002,76.77221700000001],[-117.73444399999994,76.77832000000012],[-117.73860200000001,76.78414900000013],[-117.79888899999997,76.81776400000001],[-117.81667299999998,76.82138099999997],[-117.84221600000001,76.82388300000008],[-117.86665299999999,76.82222000000013],[-117.88806199999999,76.81887800000004],[-117.90499899999992,76.81219500000003],[-117.91777000000002,76.79998800000004],[-117.92610200000001,76.78804000000002],[-117.96056399999998,76.76998900000007],[-118.00583599999993,76.76138300000014],[-118.02971600000001,76.75860600000004],[-118.08222999999998,76.75694300000009],[-118.10611,76.75749200000007],[-118.15695199999999,76.76249700000011],[-118.21362299999998,76.76915000000008],[-118.29361,76.77304100000015],[-118.319458,76.77304100000015],[-118.33750900000001,76.76832600000012],[-118.49500299999994,76.71220399999993],[-118.47471599999994,76.67970300000002],[-118.45973199999997,76.67387400000001],[-118.428879,76.66387900000012],[-118.40306099999998,76.657761],[-118.35804699999989,76.64888000000002],[-118.34137699999997,76.64359999999999],[-118.33473199999992,76.63749700000005],[-118.316101,76.5747070000001],[-118.50279199999994,76.50972000000007],[-118.52390299999996,76.50387600000005],[-118.546112,76.5],[-118.57084699999996,76.499146],[-118.59694699999989,76.5],[-118.62361099999993,76.50193800000011],[-118.65167200000002,76.50555399999996],[-118.67804699999994,76.50999500000006],[-118.70916699999998,76.51998900000007],[-118.71333299999998,76.52581800000013],[-118.71362299999998,76.5316620000001],[-118.72222899999991,76.5372010000001],[-118.73473399999995,76.54248000000007],[-118.76139799999999,76.54693600000002],[-118.81471299999998,76.55304000000007],[-118.84166700000003,76.55497700000006],[-118.94415299999997,76.51805100000013],[-118.96806300000003,76.50526400000012],[-118.97582999999992,76.49887100000001],[-118.97609699999998,76.49636800000002],[-118.97250399999996,76.49165299999999],[-118.96777299999997,76.48831200000012],[-118.95527600000003,76.48304700000006],[-118.93110699999994,76.47915599999999],[-118.82195300000001,76.47137499999997],[-118.68195300000002,76.4452510000001],[-118.64862099999999,76.42886399999992],[-118.612503,76.4002690000001],[-118.59416199999993,76.38388100000003],[-118.56610099999995,76.34304800000012],[-118.567497,76.33665500000001],[-118.58168,76.32470699999993],[-118.62554899999998,76.29443399999997],[-118.63751200000002,76.28804000000014],[-118.65556299999997,76.28414900000007],[-118.67916899999994,76.28221100000013],[-118.70556599999992,76.28166199999998],[-118.78083799999996,76.28248600000012],[-118.82833900000003,76.28193700000003],[-118.8766629999999,76.27748100000008],[-118.89584400000001,76.27221700000013],[-118.91139199999992,76.26554899999996],[-118.91915899999998,76.25943000000012],[-118.92443799999995,76.25277699999992],[-118.942207,76.21054100000015],[-118.93776699999995,76.20471199999992],[-118.92331699999994,76.19413800000007],[-118.91278099999994,76.18803400000002],[-118.90471600000001,76.16914400000007],[-118.95527600000003,76.13247700000011],[-118.96501199999994,76.1266480000001],[-119.07584399999996,76.08332800000011],[-119.10109699999998,76.08415200000007],[-119.12471,76.08804299999997],[-119.22972099999993,76.10720800000007],[-119.24526999999995,76.11137400000001],[-119.26000999999997,76.11720300000002],[-119.28250099999997,76.12747200000007],[-119.29943800000001,76.13859600000012],[-119.30832699999996,76.1499940000001],[-119.31054699999999,76.15525800000012],[-119.30583200000001,76.16775500000011],[-119.30082699999997,76.17442300000005],[-119.29499799999996,76.18026700000007],[-119.29527300000001,76.18609600000008],[-119.30166600000001,76.19136000000009],[-119.36916399999996,76.22970600000008],[-119.54915599999998,76.32415800000001],[-119.5864029999999,76.318604],[-119.65499899999992,76.30304000000007],[-119.67527799999993,76.26416000000012],[-119.67500299999995,76.24581899999993],[-119.64555399999995,76.23054500000006],[-119.59445199999999,76.20304900000002],[-119.58583099999998,76.1974790000001],[-119.57277699999992,76.18637100000012],[-119.56806899999987,76.18054200000012],[-119.56582600000002,76.17526200000003],[-119.56696299999999,76.16886900000009],[-119.57277699999992,76.16304000000008],[-119.64334099999996,76.11248799999998],[-119.74527,76.11665299999999],[-119.76999699999993,76.11637900000005],[-119.79305999999991,76.1144260000001],[-119.80499299999997,76.10887100000002],[-119.79723399999995,76.10415599999999],[-119.7727809999999,76.09942599999994],[-119.74416400000001,76.097488],[-119.64723200000003,76.08166499999999],[-119.62666300000001,76.07666000000012],[-119.50389100000001,76.04081700000006],[-119.491379,76.03553800000009],[-119.47833299999996,76.02415500000012],[-119.47389199999998,76.01859999999999],[-119.47222899999997,76.00082400000002],[-119.47609699999998,75.98248300000006],[-119.48110999999989,75.97082500000005],[-119.48916599999995,75.96554600000002],[-119.50974299999996,75.96054099999998],[-119.53555299999994,75.9624940000001],[-119.54638699999998,75.96832300000011],[-119.56111099999998,75.97886699999998],[-119.57195299999995,75.98498500000011],[-119.58583099999998,75.98969999999997],[-119.612503,75.99247700000006],[-119.63694800000002,75.99220300000013],[-119.64890300000002,75.98664900000011],[-119.699997,75.94859300000013],[-119.70333900000003,75.9427490000001],[-119.6875,75.93830900000012],[-119.612503,75.91026300000004],[-119.81082199999997,75.86943100000002],[-119.870003,75.857483],[-119.93554699999993,75.8483280000001],[-119.98000300000001,75.84332300000005],[-120.02583300000003,75.83998099999997],[-120.04915599999987,75.83888200000013],[-120.07640100000003,75.86720300000007],[-120.08500700000002,75.87275700000004],[-120.11416600000001,75.88832100000013],[-120.12805199999997,75.89305100000001],[-120.14916999999997,75.89637800000014],[-120.16639700000002,75.89248700000007],[-120.18028299999997,75.879974],[-120.18331899999993,75.87387100000007],[-120.19722000000002,75.86137400000007],[-120.21501199999994,75.84860200000003],[-120.22582999999992,75.84220900000008],[-120.26972999999992,75.82193000000012],[-120.28888699999987,75.81608599999993],[-120.30915800000002,75.81109600000008],[-120.33222999999998,75.80748000000006],[-120.35555999999997,75.80636600000003],[-120.37805200000003,75.80664100000007],[-120.40387699999991,75.80831899999998],[-120.43028300000003,75.81109600000008],[-120.45445299999994,75.81581100000011],[-120.46694899999994,75.82110599999999],[-120.47582999999997,75.82666],[-120.48528299999998,75.8377690000001],[-120.4886019999999,75.84414700000002],[-120.48972300000003,75.84999100000005],[-120.48832699999997,75.85554500000006],[-120.46305799999999,75.91638200000006],[-120.46000700000002,75.922485],[-120.44860799999987,75.93553200000002],[-120.406113,75.95498700000002],[-120.40583800000002,75.97137500000008],[-120.4349979999999,76.00305200000003],[-120.45889299999999,76.01165800000012],[-120.46749899999998,76.01220700000005],[-120.53333299999991,76.00305200000003],[-120.56054699999999,75.9916530000001],[-120.56331599999993,75.98553500000014],[-120.57417299999997,75.9791560000001],[-120.59388699999994,75.97804300000001],[-120.61361699999998,75.98193400000008],[-120.64306599999986,75.99247700000006],[-120.696663,76.01388499999996],[-120.70722999999998,76.01887500000004],[-120.71611000000001,76.02442900000005],[-120.729446,76.03942899999998],[-120.75167799999997,76.09942599999994],[-120.751106,76.10582],[-120.74833699999999,76.11192299999993],[-120.74305700000002,76.11775199999994],[-120.73222399999997,76.124146],[-120.71193699999998,76.12914999999998],[-120.72749299999992,76.15860000000004],[-120.85722399999986,76.19663999999995],[-120.883621,76.19831800000009],[-120.90249599999999,76.19636500000013],[-120.95639,76.17776500000002],[-120.96806300000003,76.172211],[-121.00890400000003,76.14414999999991],[-121.01251199999996,76.13916000000006],[-121.016953,76.12109400000008],[-121.02528399999989,76.07331800000003],[-121.02278100000001,76.05914300000006],[-120.99328600000001,76.02681700000011],[-120.97961399999997,76.01965300000012],[-120.970123,76.0134890000001],[-120.93195300000002,75.95999099999995],[-120.93306000000001,75.95694000000015],[-120.94583099999994,75.94859300000013],[-120.98082699999998,75.94164999999998],[-120.99944299999999,75.93969700000002],[-121.01445000000001,75.9427490000001],[-121.01722699999999,75.94802900000002],[-121.01112399999988,75.97082500000005],[-121.00055699999996,75.97720300000015],[-120.98610699999995,75.98414599999995],[-121.00761399999999,75.98898299999996],[-121.01527399999998,75.9921490000001],[-121.030441,75.99247700000006],[-121.09277299999997,75.9933170000001],[-121.11389199999996,75.9916530000001],[-121.25945299999995,75.96443200000004],[-121.26583900000003,75.95832800000005],[-121.271118,75.94609100000008],[-121.27887699999985,75.92776500000008],[-121.34861799999993,75.92804000000007],[-121.423317,75.93386800000002],[-121.436394,75.93914800000005],[-121.422775,75.9464650000001],[-121.41665599999988,75.95304900000008],[-121.42415599999993,75.95664999999991],[-121.479446,75.97637900000001],[-121.58306899999997,76.00360100000012],[-121.59500100000002,76.00555400000007],[-121.83473200000003,76.03442400000012],[-122.13417099999998,76.03637700000007],[-122.14499699999999,76.03082300000005],[-122.14472999999992,75.99693299999996],[-122.16944899999999,75.97804300000001],[-122.33583099999998,75.94247400000012],[-122.37666300000001,75.93386800000002],[-122.41639700000002,75.92858900000004],[-122.442207,75.92747500000007],[-122.48916599999995,75.92720000000003],[-122.51666299999994,75.928314],[-122.563606,75.93193100000013],[-122.67610200000001,75.95166000000006],[-122.69638099999997,75.95555100000013],[-122.72250400000001,75.96887200000009],[-122.728882,75.97303799999997],[-122.66915899999998,75.97692900000004],[-122.64943699999998,75.98220800000001],[-122.59111000000001,76.00166300000001],[-122.57640100000003,76.00749200000001],[-122.5625,76.01443499999999],[-122.47556299999997,76.10443100000003],[-122.47112300000003,76.11026000000004],[-122.47193899999996,76.11499000000003],[-122.48554999999993,76.1202550000001],[-122.49833699999994,76.12052900000003],[-122.60134900000003,76.11509700000005],[-122.62222300000002,76.11137400000001],[-122.67832900000002,76.11137400000001],[-122.69999699999994,76.11219800000015],[-122.70445299999994,76.1144260000001],[-122.69554099999993,76.11775199999994],[-122.58721899999995,76.13415500000002],[-122.50195299999996,76.13638300000014],[-122.48999000000003,76.141098],[-122.57417299999992,76.16609199999999],[-122.595551,76.17082200000004],[-122.62027,76.17442300000005],[-122.64666699999998,76.17581200000006],[-122.67027300000001,76.17442300000005],[-122.693604,76.17053199999998],[-122.73361199999994,76.1624910000001],[-122.84277299999997,76.13108800000009],[-122.885559,76.10443100000003],[-122.90194699999995,76.09803800000003],[-122.92138699999987,76.092758],[-123.01139799999993,76.08332800000011],[-123.037781,76.08471700000007],[-122.97917199999995,76.12580900000012],[-122.84861799999999,76.20887800000003],[-122.72112299999998,76.23136900000003],[-122.636124,76.2647090000001],[-122.63166799999999,76.2705380000001],[-122.63751200000002,76.28804000000014],[-122.64527899999996,76.299713],[-122.63249199999996,76.32998700000002],[-122.62638900000002,76.33638000000013],[-122.61776700000001,76.34220899999997],[-122.59889199999998,76.34832800000004],[-122.57861300000002,76.35359199999999],[-122.39890300000002,76.39694199999997],[-122.30943300000001,76.40887500000002],[-122.01471699999996,76.43248],[-121.826683,76.4227600000001],[-121.78195199999999,76.42025800000005],[-121.73805199999998,76.42109700000015],[-121.54998799999993,76.43470800000011],[-121.53307299999994,76.43719500000003],[-121.51445000000001,76.44413800000001],[-121.421944,76.49359099999992],[-121.31220999999994,76.572495],[-121.30695300000002,76.57832300000013],[-121.31388899999996,76.58970599999998],[-121.30915800000002,76.59387200000003],[-121.21250899999995,76.649719],[-121.118607,76.67330900000002],[-121.10109699999992,76.66832000000005],[-121.079453,76.66832000000005],[-121.05666399999996,76.67137100000002],[-120.923317,76.68997200000007],[-120.900284,76.69331399999999],[-120.88417099999998,76.698868],[-120.86193800000001,76.71192900000011],[-120.84777799999989,76.72470099999992],[-120.83249699999993,76.73136900000009],[-120.81220999999994,76.73719800000009],[-120.76611299999996,76.7435910000001],[-120.66915899999998,76.75109900000007],[-120.64083899999997,76.74859600000013],[-120.62581599999999,76.74636799999996],[-120.604172,76.74636799999996],[-120.58112299999999,76.7494200000001],[-120.40167200000002,76.797211],[-120.38194299999992,76.80415300000004],[-120.36776700000001,76.81025700000009],[-120.36609599999997,76.813309],[-120.36527999999993,76.83610500000003],[-120.09137699999997,77.00305199999997],[-120.06916799999999,77.00804099999993],[-120.03888699999999,77.01332100000002],[-120.02278100000001,77.01527399999998],[-119.99722300000002,77.01638800000012],[-119.97693600000002,77.01332100000002],[-119.96112099999993,77.009995],[-119.94999699999994,77.01249700000005],[-119.92027299999995,77.02360500000003],[-119.839447,77.05693100000002],[-119.83167999999995,77.06303400000013],[-119.83249699999999,77.06915300000014],[-119.83583099999987,77.07527199999998],[-119.83721899999995,77.07971200000003],[-119.83556399999998,77.08526600000005],[-119.825287,77.09109500000005],[-119.8125,77.09664900000001],[-119.77639799999992,77.1060940000001],[-119.60056299999991,77.145828],[-119.43331899999998,77.17359900000008],[-119.41082799999998,77.17858899999993],[-119.389183,77.184418],[-119.360817,77.20332300000007],[-119.354446,77.20915200000013],[-119.346947,77.22137499999997],[-119.34583999999995,77.22776799999997],[-119.33389299999993,77.23997500000007],[-119.31582599999996,77.2580410000001],[-119.295837,77.27665700000011],[-119.26834099999996,77.28915400000011],[-119.25306699999999,77.2952580000001],[-119.22222899999991,77.30636600000008],[-119.20111099999991,77.31303400000007],[-119.15334299999995,77.32582100000008],[-119.11444099999994,77.32748400000003],[-119.08666999999997,77.32666000000006],[-119.00110599999988,77.32110600000004],[-118.94138299999992,77.31971700000008],[-118.91694599999994,77.32249500000006],[-118.89389,77.32748400000003],[-118.87000299999994,77.33387800000008],[-118.75723299999999,77.35247800000002],[-118.73249800000002,77.35554500000012],[-118.65110799999997,77.36053500000014],[-118.44972199999995,77.35887100000014],[-118.224716,77.35609400000004],[-118.19721999999996,77.35498000000007],[-118.16583300000002,77.35525500000006],[-118.14111299999996,77.35803199999998],[-118.12805200000003,77.36442600000004],[-118.12721299999998,77.36943100000008],[-118.125,77.3724820000001],[-118.10694899999993,77.37803600000012],[-118.08750899999995,77.3791500000001],[-117.91111799999993,77.38693200000006],[-117.86721799999992,77.38859600000006],[-117.85056299999991,77.38443000000012],[-117.781113,77.36303700000002],[-117.76806599999998,77.35775800000005],[-117.756958,77.35165400000005],[-117.75083899999998,77.34664899999996],[-117.73860200000001,77.34193399999992],[-117.72444200000001,77.33804300000008],[-117.61193800000001,77.32777400000003],[-117.45084400000002,77.31219499999992],[-117.27639799999997,77.28915400000011],[-117.02306399999998,77.290817],[-117.01478600000002,77.29670000000004],[-117.01711999999992,77.30020899999994],[-117.02749599999993,77.31025699999998],[-117.06082199999997,77.32666000000006],[-117.10555999999997,77.33998100000002],[-117.11582900000002,77.34165999999999],[-117.11805699999996,77.33859300000012],[-117.1324919999999,77.33332800000005],[-117.15416699999997,77.33248900000007],[-117.16999800000002,77.33581500000008],[-117.18195300000002,77.34027100000003],[-117.181671,77.34637500000002],[-117.17666600000001,77.35220300000015],[-117.15888999999987,77.35887100000014],[-117.14277600000003,77.36137400000013],[-117.11945300000002,77.35998500000011],[-117.06082199999997,77.35331700000012],[-117.00749999999994,77.34303999999997],[-116.94666299999994,77.32943699999998],[-116.87638900000002,77.31805400000013],[-116.848343,77.315811],[-116.795837,77.31749000000002],[-116.77887699999997,77.31915300000009],[-116.65167199999996,77.37776199999996],[-116.64835399999998,77.383331],[-116.65167199999996,77.38804600000003],[-116.66278099999994,77.391663],[-116.741379,77.395264],[-116.87082699999996,77.40081800000002],[-116.89917000000003,77.399429],[-116.97582999999997,77.39332600000006],[-116.99471999999992,77.39444000000003],[-117.01112399999994,77.39888000000008],[-117.15306099999992,77.45166000000012],[-117.14998599999996,77.45721400000014],[-117.13890100000003,77.46054100000003],[-117.08306899999997,77.47442599999994],[-117.06667299999998,77.4769290000001],[-117.0613939999999,77.47608900000006],[-117.03833799999995,77.47100100000006],[-116.991669,77.4666600000001],[-116.91972399999997,77.47053500000004],[-116.89444700000001,77.47331200000013],[-116.78527799999995,77.499146],[-116.75723299999993,77.51165800000001],[-116.76944699999996,77.516388],[-116.85109699999998,77.51666300000005],[-116.87917299999987,77.51776100000012],[-116.9058379999999,77.52026400000011],[-116.926941,77.5247040000001],[-116.92054699999994,77.528595],[-116.900284,77.53221100000002],[-116.875,77.53498800000011],[-116.83306900000002,77.53360000000004],[-116.75418100000002,77.534424],[-116.64750699999996,77.53776600000015],[-116.58583099999998,77.54054300000001],[-116.53611799999993,77.54443400000008],[-116.48777799999999,77.55026200000003],[-116.35109699999998,77.53915400000005]],[[-85.285278,77.58749400000005],[-85.25973499999998,77.58665500000012],[-85.23527499999994,77.58665500000012],[-85.10722399999997,77.58109999999999],[-85.01112399999994,77.57388300000008],[-84.99527,77.56944300000009],[-84.82250999999997,77.50526400000012],[-84.81388900000002,77.49720800000006],[-84.82444799999996,77.49192799999997],[-84.84306299999992,77.48719800000015],[-84.93443300000001,77.47026099999994],[-84.96083099999998,77.46638500000006],[-85.027222,77.45971700000007],[-85.095551,77.45443700000004],[-85.12693799999994,77.45304899999991],[-85.15360999999996,77.45443700000004],[-85.16833500000001,77.45693999999997],[-85.178604,77.46415700000011],[-85.1725009999999,77.47360199999997],[-85.15916400000003,77.48414600000001],[-85.14472999999992,77.4894260000001],[-85.13861099999997,77.49498000000011],[-85.14083900000003,77.50166300000006],[-85.15278599999999,77.50776700000011],[-85.17027300000001,77.51165800000001],[-85.24888599999991,77.52748100000002],[-85.27084399999995,77.52998400000001],[-85.31973299999993,77.53221100000002],[-85.34416199999998,77.53221100000002],[-85.39916999999997,77.53387500000008],[-85.53832999999997,77.53997800000002],[-85.53555299999994,77.54386900000009],[-85.35221899999993,77.58276400000005],[-85.31138599999997,77.58665500000012],[-85.285278,77.58749400000005]],[[-90.60305800000003,77.62831100000005],[-90.521118,77.62608300000011],[-90.49249299999997,77.62608300000011],[-90.43859899999995,77.630539],[-90.41444399999995,77.63108799999998],[-90.38806199999988,77.62942500000003],[-90.33917200000002,77.62387100000007],[-90.24249299999985,77.61248800000004],[-90.21916199999998,77.60887100000008],[-90.20889299999993,77.60304299999996],[-90.21000700000002,77.59748800000006],[-90.20666499999999,77.59165999999999],[-90.19665499999996,77.58720400000004],[-90.17777999999993,77.58248900000001],[-90.05972299999996,77.56637599999999],[-89.93721,77.53276100000005],[-89.91722099999987,77.52720599999998],[-89.84110999999996,77.50416600000005],[-89.80665599999992,77.49247700000012],[-89.75361599999997,77.47303800000003],[-89.71916199999998,77.45832800000011],[-89.636124,77.33915700000006],[-89.640289,77.33332800000005],[-89.67471299999994,77.31025699999998],[-89.70777899999996,77.29414400000013],[-89.84973099999996,77.25],[-89.882767,77.23997500000007],[-89.91999800000002,77.23027000000002],[-90,77.21381400000001],[-90.00917099999998,77.211929],[-90.08889799999992,77.19970700000005],[-90.11805700000002,77.19859300000007],[-90.129166,77.20054600000003],[-90.25917099999992,77.20109600000006],[-90.36694299999999,77.19775400000009],[-90.41665599999999,77.21304299999997],[-90.68331899999993,77.27192700000006],[-90.70472699999993,77.27638200000007],[-90.72721899999993,77.27998400000001],[-90.84306300000003,77.29275499999994],[-90.90972899999997,77.30304000000007],[-90.94665500000002,77.30941800000005],[-91.14666699999992,77.36219800000009],[-91.18249499999996,77.38693200000006],[-91.18721,77.39027399999998],[-91.20889299999993,77.4149930000001],[-91.206955,77.56860400000011],[-91.18443300000001,77.60859700000015],[-91.17361499999993,77.61303699999996],[-91.15834000000001,77.61720300000007],[-91.10943599999996,77.62498500000004],[-90.90638699999994,77.65304600000013],[-90.88082899999995,77.65443400000004],[-90.82640099999998,77.65443400000004],[-90.80166600000001,77.65165700000011],[-90.72749299999998,77.64221200000003],[-90.68360899999993,77.63333100000011],[-90.60305800000003,77.62831100000005]],[[-105.01027699999986,77.40803499999993],[-104.98665599999998,77.4044340000001],[-104.96193700000003,77.4044340000001],[-104.90805099999994,77.40693700000003],[-104.82584400000002,77.41360500000002],[-104.77166699999998,77.41665600000005],[-104.74109599999997,77.41442899999998],[-104.73277300000001,77.41137700000007],[-104.53832999999997,77.33831800000007],[-104.48889199999996,77.318604],[-104.39555399999995,77.27638200000007],[-104.38834400000002,77.27137800000014],[-104.38137799999998,77.2644350000001],[-104.37998999999996,77.26193199999994],[-104.36554699999999,77.23027000000002],[-104.36749299999997,77.224426],[-104.40499899999992,77.17248500000011],[-104.416946,77.16192600000005],[-104.43804899999998,77.15054300000003],[-104.47250400000001,77.13749700000011],[-104.5,77.13304099999999],[-104.52250699999996,77.13053900000011],[-104.74027999999993,77.10859700000009],[-104.79028299999999,77.10887100000002],[-104.83249699999993,77.11331200000012],[-104.85333300000002,77.11747700000012],[-104.86916400000001,77.12359600000013],[-104.883331,77.13554399999998],[-104.89250199999992,77.14193699999993],[-104.906387,77.14749100000012],[-104.92250099999995,77.15248100000002],[-104.945267,77.15721100000002],[-104.993607,77.16499299999998],[-105.04444899999993,77.17137100000014],[-105.09583999999995,77.176086],[-105.11971999999997,77.17665099999999],[-105.13751200000002,77.176086],[-105.15167200000002,77.17137100000014],[-105.24694799999997,77.19386300000002],[-105.40888999999999,77.28166199999998],[-105.41722099999998,77.28471400000006],[-105.45527599999997,77.29193099999998],[-105.48111,77.29498300000012],[-105.50666799999993,77.299149],[-105.531677,77.30525200000011],[-105.55027799999999,77.311646],[-105.57195300000001,77.32331799999992],[-105.67916899999994,77.44747900000004],[-105.691101,77.49720800000006],[-105.83444199999997,77.6102600000001],[-105.858337,77.62692300000015],[-105.878601,77.6397090000001],[-105.88890100000003,77.645264],[-105.93083200000001,77.66304000000014],[-105.94776899999994,77.66886899999997],[-105.98000299999995,77.67942799999997],[-106.01471700000002,77.68858300000005],[-106.08361799999989,77.71026599999999],[-106.09166699999997,77.71527100000003],[-106.09472700000003,77.72415199999995],[-106.08917199999996,77.72886699999998],[-106.07945299999989,77.73275800000005],[-106.04055800000003,77.74498000000006],[-106.01222200000001,77.75054900000003],[-105.94167299999987,77.75972000000002],[-105.91388699999999,77.76249700000005],[-105.70056199999999,77.75360099999995],[-105.64890299999996,77.74859600000008],[-105.55248999999998,77.72943099999998],[-105.50666799999993,77.71971100000007],[-105.47028399999999,77.70915200000002],[-105.38971699999996,77.68386800000002],[-105.17360699999995,77.61219800000003],[-105.15695199999999,77.60609399999998],[-105.03971899999999,77.55219999999997],[-105.02778599999994,77.54637100000014],[-104.968613,77.51443500000005],[-104.95916699999998,77.50804100000005],[-104.94888300000002,77.49609400000008],[-104.94499199999996,77.484985],[-104.946663,77.47915599999999],[-104.95249899999999,77.47442599999994],[-104.96749899999998,77.46887200000015],[-105.01027699999986,77.4586030000001],[-105.01194800000002,77.45277400000009],[-105.01806599999986,77.411926],[-105.01027699999986,77.40803499999993]],[[-95.40583800000002,77.76388500000002],[-95.40888999999993,77.75221300000004],[-95.406113,77.74609400000003],[-95.38972499999994,77.73942600000004],[-95.36389200000002,77.73719800000009],[-95.343887,77.73803700000008],[-95.118607,77.74971000000005],[-95.08778399999994,77.75221300000004],[-95.05943300000001,77.75665300000009],[-95.02917499999995,77.76721199999992],[-95.01083399999999,77.77777100000014],[-94.981674,77.78082300000005],[-94.95167499999997,77.782486],[-94.752228,77.78858900000012],[-94.72888199999994,77.78831500000001],[-94.62332199999997,77.78359999999998],[-94.5727839999999,77.78054800000007],[-94.54222099999993,77.77388000000008],[-94.521118,77.76776100000006],[-94.47749299999992,77.76470899999998],[-94.44860799999998,77.76527399999998],[-94.35665899999987,77.76748700000013],[-94.25250199999994,77.77221699999996],[-94.08999599999993,77.76582300000013],[-94.03028899999998,77.76054399999998],[-93.95111099999997,77.73553500000014],[-93.93582199999997,77.73248300000006],[-93.93138099999999,77.73248300000006],[-93.82667500000002,77.73942600000004],[-93.82000700000003,77.74498000000006],[-93.81777999999997,77.75082400000008],[-93.80665599999992,77.75637800000004],[-93.78666699999997,77.76110800000009],[-93.68638599999997,77.77388000000008],[-93.65695199999999,77.776657],[-93.62943999999993,77.77609300000006],[-93.546112,77.770828],[-93.241669,77.73387100000014],[-93.23388699999987,77.73248300000006],[-93.17471299999994,77.70416300000005],[-93.101944,77.66249099999999],[-93.10665899999992,77.66026300000004],[-93.14834599999989,77.6455380000001],[-93.16416900000002,77.64027400000009],[-93.19638099999997,77.63720699999999],[-93.22250400000001,77.638596],[-93.24916100000002,77.64166300000011],[-93.27722199999994,77.64359999999994],[-93.30305499999997,77.64359999999994],[-93.35943599999996,77.63581800000003],[-93.37943999999999,77.63081400000004],[-93.39028899999994,77.62553399999996],[-93.39723200000003,77.61998],[-93.48638899999997,77.54553199999998],[-93.50250199999999,77.50305200000008],[-93.47778299999999,77.49247700000012],[-93.47471599999994,77.48748799999998],[-93.47416699999991,77.47637900000007],[-93.475281,77.47137499999991],[-93.48083499999996,77.4666600000001],[-93.537781,77.4458160000001],[-93.55305499999992,77.44081100000005],[-93.57055699999995,77.43775900000014],[-93.90666199999998,77.4333190000001],[-93.93388400000003,77.43359399999997],[-94.25167799999997,77.45526100000001],[-94.319458,77.4685970000001],[-94.34500100000002,77.472488],[-94.468887,77.4769290000001],[-94.8011019999999,77.48027000000013],[-95.03222699999998,77.46998600000012],[-95.12361099999998,77.46388200000007],[-95.204453,77.46081499999997],[-95.25279199999994,77.46081499999997],[-95.29499800000002,77.46638500000006],[-95.34638999999999,77.46998600000012],[-95.47749299999998,77.47387700000002],[-95.53277600000001,77.47360199999997],[-95.72610500000002,77.47026099999994],[-95.82362399999994,77.46638500000006],[-95.83889799999986,77.46249399999999],[-95.86416600000001,77.46220399999999],[-95.88945000000001,77.4644320000001],[-96,77.47998000000013],[-96.06138599999986,77.49165299999999],[-96.083328,77.49775699999998],[-96.09973099999996,77.50443999999999],[-96.25917099999998,77.57192999999995],[-96.31834399999997,77.59887700000007],[-96.328888,77.60498000000001],[-96.25556899999992,77.68969700000002],[-96.241104,77.69497700000011],[-96.19444299999998,77.70498700000002],[-96.07722499999994,77.72692900000004],[-95.93443300000001,77.75305200000003],[-95.91805999999997,77.75555400000007],[-95.89723199999997,77.75749200000001],[-95.86944599999993,77.75721700000003],[-95.848053,77.75526400000007],[-95.74276700000001,77.76220700000005],[-95.63055399999996,77.77110299999998],[-95.58389299999993,77.77970900000008],[-95.57000700000003,77.78414900000013],[-95.566101,77.78776600000009],[-95.56555200000003,77.79275500000006],[-95.55277999999993,77.79609700000015],[-95.52888499999995,77.80108600000011],[-95.49610899999999,77.80554200000006],[-95.46528599999994,77.80802900000009],[-95.42777999999998,77.80331400000006],[-95.41833500000001,77.79887400000007],[-95.41082799999998,77.79248000000001],[-95.40695199999999,77.78720100000004],[-95.404449,77.77638199999996],[-95.40583800000002,77.76388500000002]],[[-77.851944,77.77442900000005],[-77.87527499999987,77.77442900000005],[-77.88806199999988,77.78137200000003],[-77.93055699999996,77.80886800000007],[-77.95500199999992,77.83027600000003],[-77.952225,77.833054],[-77.93638599999991,77.83915700000011],[-77.906387,77.84443700000003],[-77.88027999999991,77.84803800000003],[-77.821121,77.85443100000003],[-77.71777299999997,77.86303700000013],[-77.67610200000001,77.86470000000003],[-77.62277199999994,77.86276200000009],[-77.59638999999999,77.86080899999996],[-77.58277900000002,77.8580320000001],[-77.57528699999995,77.85498000000013],[-77.56861900000001,77.849716],[-77.57556199999999,77.82360800000004],[-77.57917800000001,77.81860400000005],[-77.59277299999991,77.813309],[-77.62805200000003,77.80415300000004],[-77.65888999999999,77.79693600000013],[-77.68055700000002,77.79275500000006],[-77.851944,77.77442900000005]],[[-101.71140300000002,77.90165700000006],[-101.671944,77.893326],[-101.62082699999996,77.88443000000007],[-101.52443700000003,77.86998000000011],[-101.450287,77.86109899999997],[-101.36833200000001,77.8538670000001],[-101.26555599999995,77.842758],[-101.23777799999993,77.83888200000013],[-101.19138299999997,77.83082600000006],[-101.16139199999992,77.82276900000005],[-100.96056399999992,77.75915500000013],[-100.92639200000002,77.7433170000001],[-100.92555199999998,77.73719800000009],[-100.928879,77.73136900000009],[-100.94055200000003,77.72692900000004],[-100.96472199999994,77.72554000000008],[-101.096947,77.71943699999991],[-101.21694899999994,77.721924],[-101.26777599999997,77.72581500000007],[-101.31806899999992,77.726089],[-101.50695799999994,77.7249910000001],[-101.53527799999995,77.72360200000014],[-101.56471299999993,77.72053500000004],[-101.58583099999993,77.71527100000003],[-101.593613,77.709427],[-101.60582699999992,77.70387300000004],[-101.62249799999995,77.69859300000013],[-101.65222199999994,77.69442700000008],[-101.79888900000003,77.67637600000006],[-101.82640099999992,77.67608600000005],[-102.01695299999994,77.67970300000002],[-102.06777999999997,77.68220500000007],[-102.1416779999999,77.690811],[-102.43639399999995,77.72970599999996],[-102.44444299999998,77.73193400000008],[-102.51083399999999,77.78610200000008],[-102.52971600000001,77.83415200000007],[-102.51806599999992,77.84414699999996],[-102.498894,77.855545],[-102.45889299999999,77.87109400000008],[-102.44249000000002,77.8766480000001],[-102.41665599999999,77.88192700000008],[-102.38778699999995,77.88415500000002],[-102.13999899999999,77.89637800000008],[-102.08389299999999,77.89721700000007],[-102.04915599999998,77.89694200000002],[-101.91583299999996,77.8938750000001],[-101.83194699999996,77.8938750000001],[-101.779449,77.89637800000008],[-101.74973299999999,77.89971900000012],[-101.71140300000002,77.90165700000006]],[[-114.07305899999994,77.98165900000004],[-113.9813769999999,77.9349820000001],[-113.97501399999993,77.93109100000004],[-113.97222899999997,77.92526200000003],[-113.97222899999997,77.91998300000006],[-113.9583439999999,77.91499300000004],[-113.92388900000003,77.91081200000013],[-113.89499699999993,77.90832500000005],[-113.84028599999999,77.9060970000001],[-113.72666899999996,77.89610300000004],[-113.70639,77.89166300000005],[-113.58556399999998,77.82582099999996],[-113.57861300000002,77.81999199999996],[-113.57611099999997,77.81414799999999],[-113.58750899999995,77.80802900000009],[-113.61916399999996,77.79582199999999],[-113.65972899999997,77.78332499999999],[-113.78832999999992,77.74525500000004],[-113.90833999999995,77.72637900000001],[-113.93472300000002,77.72387700000013],[-114.11444099999989,77.70664999999991],[-114.19304699999998,77.69802900000002],[-114.223053,77.698868],[-114.277222,77.70220900000004],[-114.33112299999999,77.70971700000001],[-114.415009,77.73136900000009],[-114.514183,77.76527399999998],[-114.66251399999999,77.80386399999992],[-114.70916699999998,77.81359900000001],[-114.73029300000002,77.81887799999998],[-114.84834299999994,77.85470600000002],[-115.07721699999996,77.938583],[-115.11138900000003,77.95387299999999],[-115.11501299999992,77.95637500000004],[-115.11609599999991,77.958328],[-115.108337,77.96138000000008],[-115.090843,77.96360800000008],[-115.06054699999993,77.96388200000001],[-115.03388999999993,77.96220400000004],[-114.93028299999997,77.96054100000015],[-114.81973299999993,77.97303799999992],[-114.79778299999992,77.97554000000002],[-114.77749599999993,77.98165900000004],[-114.74027999999998,78.00000000000006],[-114.60582699999998,78.03054800000001],[-114.40083299999998,78.06749000000002],[-114.35500300000001,78.07054100000005],[-114.32694999999995,78.0711060000001],[-114.30332899999996,78.07054100000005],[-114.28694200000001,78.06608600000004],[-114.07305899999994,77.98165900000004]],[[-109.58805799999999,78.06469700000002],[-109.58056599999998,78.0583190000001],[-109.58112299999988,78.0413670000001],[-109.58528100000001,78.03553800000009],[-109.66972399999997,77.97164900000013],[-109.68305999999995,77.96582000000012],[-109.70556599999986,77.95999100000012],[-109.76027699999997,77.95109600000006],[-109.81527699999992,77.9427490000001],[-109.84249899999998,77.938873],[-109.89750699999996,77.93275500000004],[-110.00723299999987,77.92137100000014],[-110.14499699999999,77.91192600000011],[-110.162781,77.90693699999997],[-110.16665599999999,77.90109300000012],[-110.19611399999991,77.89665200000002],[-110.22112299999998,77.8938750000001],[-110.24889399999995,77.8938750000001],[-110.48999000000003,77.88388100000009],[-110.62666300000001,77.87303200000002],[-110.65416700000003,77.87191800000005],[-110.79250299999995,77.8708190000001],[-110.846947,77.86637900000005],[-110.873894,77.86219800000015],[-110.89584400000001,77.85609399999993],[-110.90139799999992,77.849716],[-110.90471600000001,77.84387200000015],[-110.90360999999996,77.83804299999997],[-110.90028399999994,77.832764],[-110.89444699999996,77.82693499999999],[-110.88639799999987,77.82083100000011],[-110.74388099999993,77.77360500000009],[-110.71556099999992,77.76887500000004],[-110.65888999999999,77.75972000000002],[-110.63110399999994,77.75804099999999],[-110.60138699999999,77.75888100000003],[-110.51972999999992,77.76332100000002],[-110.41583299999996,77.770828],[-110.39306599999986,77.77304100000015],[-110.368607,77.77638199999996],[-110.28916899999996,77.782486],[-110.16111799999999,77.78414900000013],[-110.13305700000001,77.78054800000007],[-110.10500299999995,77.77499400000005],[-110.09028599999994,77.76915000000008],[-110.08029199999993,77.76332100000002],[-110.04055800000003,77.637497],[-110.08029199999993,77.56359900000007],[-110.08416699999992,77.55775500000004],[-110.09221599999995,77.55192600000004],[-110.11749299999997,77.53997800000002],[-110.20333899999997,77.51138300000014],[-110.22501399999987,77.50526400000012],[-110.27055399999995,77.49581900000004],[-110.29695100000004,77.49165299999999],[-110.502228,77.46026600000005],[-110.81500199999999,77.42498800000004],[-110.82749899999999,77.41914400000002],[-110.85082999999992,77.41442899999998],[-110.87721299999998,77.41137700000007],[-110.95639,77.407486],[-111.00974299999996,77.40609699999999],[-111.06527699999998,77.40609699999999],[-111.11721799999992,77.40887499999997],[-111.172234,77.4160920000001],[-111.29998799999993,77.41914400000002],[-111.46305799999999,77.39305100000007],[-111.61833200000001,77.37387100000012],[-111.82501199999996,77.34887700000013],[-112.031113,77.3247070000001],[-112.05722000000003,77.32331799999992],[-112.083618,77.32304399999998],[-112.13694800000002,77.32331799999992],[-112.16639700000002,77.32527199999998],[-112.41306299999997,77.35609400000004],[-112.43888900000002,77.36109900000008],[-112.48222399999992,77.37109400000003],[-112.5,77.37823500000002],[-112.50778200000002,77.38136300000002],[-112.52139299999999,77.38943499999999],[-112.52333099999993,77.395264],[-112.526947,77.39971900000006],[-112.545547,77.41581700000006],[-112.587784,77.44914199999994],[-112.60109699999992,77.45526100000001],[-112.626938,77.45942700000006],[-112.65387699999997,77.45887800000014],[-112.68222000000003,77.45693999999997],[-112.69721999999996,77.45526100000001],[-112.73889200000002,77.4458160000001],[-112.764183,77.44165000000004],[-112.79083300000002,77.4410860000001],[-112.80249000000003,77.442474],[-112.92887899999994,77.46415700000011],[-112.95777899999996,77.46943699999997],[-112.96389799999992,77.474152],[-112.96806299999992,77.48580900000013],[-112.96806299999992,77.49220300000002],[-112.97028399999999,77.49803200000002],[-112.978882,77.50332600000002],[-112.99445300000002,77.50888100000009],[-113.01167299999997,77.51277199999998],[-113.03751399999999,77.51582300000001],[-113.06500199999999,77.51721199999997],[-113.14611799999994,77.51776100000012],[-113.17388900000003,77.51944000000015],[-113.198036,77.52388000000013],[-113.20472699999999,77.52943399999998],[-113.23805199999998,77.58137500000004],[-113.24027999999993,77.58720400000004],[-113.16251399999993,77.60914600000012],[-113.1875,77.73942600000004],[-113.20556599999998,77.74443100000008],[-113.26251200000002,77.75555400000007],[-113.283073,77.76110800000009],[-113.29444899999999,77.766663],[-113.30387899999994,77.77304100000015],[-113.31054699999993,77.77859500000011],[-113.31500199999994,77.78387500000002],[-113.31973299999999,77.79553199999992],[-113.31973299999999,77.80720499999995],[-113.31749699999995,77.81303399999996],[-113.30638099999993,77.83720399999999],[-113.23473399999989,77.90165700000006],[-113.23082699999992,77.903595],[-113.20973200000003,77.90887500000008],[-113.12721299999998,77.9122010000001],[-113.09973100000002,77.91276600000015],[-113.07167099999998,77.9122010000001],[-113.04666099999997,77.90776100000011],[-113.03971899999999,77.9019320000001],[-112.943604,77.91192600000011],[-112.80499299999985,77.933044],[-112.78333299999997,77.93719500000009],[-112.766663,77.94247400000006],[-112.74194299999988,77.95166],[-112.57444799999996,77.97943100000009],[-112.46694899999994,77.99247700000001],[-112.29499800000002,78.0105440000001],[-112.12526699999995,78.00610400000005],[-111.97944599999994,78.01859999999999],[-111.787216,78.03359999999992],[-111.77610800000002,78.02804600000013],[-111.756393,78.024429],[-111.73055999999997,78.02415500000006],[-111.70556599999998,78.02693199999999],[-111.63221699999991,78.04081700000006],[-111.34583999999995,78.0769350000001],[-111.31833599999999,78.08027600000014],[-111.28832999999997,78.08194000000015],[-111.09333800000002,78.09248400000001],[-111.048607,78.0935970000001],[-111.02749599999999,78.093323],[-110.99861099999993,78.09054600000007],[-110.99749799999995,78.08471700000007],[-111.00110599999994,78.07998700000002],[-110.995003,78.07415800000001],[-110.903343,78.06219499999997],[-110.861107,78.061646],[-110.83306899999997,78.06303400000013],[-110.80555700000002,78.06526200000008],[-110.78778099999994,78.0711060000001],[-110.77500899999995,78.0769350000001],[-110.77139299999999,78.08276400000011],[-110.76334399999996,78.08888200000007],[-110.74553700000001,78.09471100000007],[-110.72721899999988,78.09776299999999],[-110.67051700000002,78.101089],[-110.54998799999998,78.1060940000001],[-110.46584299999995,78.10859700000003],[-110.23777799999999,78.11080900000013],[-110.10082999999992,78.10859700000003],[-109.95916699999987,78.10470599999996],[-109.78916899999996,78.09971600000011],[-109.67777999999998,78.09193399999998],[-109.65387699999985,78.08831800000013],[-109.60527000000002,78.0711060000001],[-109.58805799999999,78.06469700000002]],[[-101.65139799999997,78.14471400000002],[-101.67527799999999,78.14444000000009],[-101.859444,78.15525800000006],[-101.87917299999992,78.15832499999999],[-101.88194299999998,78.16220100000004],[-101.77610800000002,78.21638500000012],[-101.75334199999992,78.22720300000009],[-101.73137700000001,78.23248300000012],[-101.70722999999987,78.23275799999999],[-101.68472299999996,78.230545],[-101.68167099999994,78.22747800000008],[-101.67250100000001,78.22608900000012],[-101.633621,78.21081500000003],[-101.62277199999988,78.20471200000009],[-101.61582899999996,78.19941699999998],[-101.60360700000001,78.18748500000004],[-101.59999099999993,78.18109099999998],[-101.59861799999993,78.17526199999998],[-101.59973100000002,78.16442900000004],[-101.60527000000002,78.15914900000013],[-101.61305199999998,78.15359499999994],[-101.62581599999993,78.14804100000015],[-101.65139799999997,78.14471400000002]],[[-103.05695300000002,78.11970500000007],[-103.11444099999994,78.11775200000011],[-103.19444299999992,78.11914100000007],[-103.212784,78.12052900000003],[-103.23029300000002,78.12387100000012],[-103.25862099999995,78.134995],[-103.27027900000002,78.14109799999994],[-103.277222,78.14694199999997],[-103.28222700000003,78.15776100000005],[-103.27971600000001,78.16360500000008],[-103.274719,78.169983],[-103.26750199999998,78.17553700000002],[-103.23916600000001,78.19220000000007],[-103.22721899999993,78.19775400000009],[-103.17027300000001,78.21998599999995],[-103.12471,78.23664900000006],[-103.06276700000001,78.25804100000005],[-103.04138199999994,78.26361099999997],[-102.98693800000001,78.27276599999999],[-102.93415800000002,78.27276599999999],[-102.89750700000002,78.26914999999997],[-102.82556199999993,78.25888100000009],[-102.8125,78.255829],[-102.79860699999995,78.25027499999999],[-102.78916899999996,78.24443100000002],[-102.78222700000003,78.23858600000005],[-102.78028899999993,78.23275799999999],[-102.77639799999986,78.21554600000013],[-102.77639799999986,78.21026600000005],[-102.781387,78.20498700000007],[-102.79332699999998,78.19941699999998],[-102.85527000000002,78.18887299999994],[-102.89806399999992,78.17804000000001],[-102.93195300000002,78.16693100000009],[-102.97721899999999,78.1502690000001],[-103.01777599999997,78.13360600000004],[-103.04167199999995,78.122208],[-103.05695300000002,78.11970500000007]],[[-94.36665299999999,78.15914900000013],[-94.37805199999997,78.15776100000005],[-94.40444899999994,78.15998800000011],[-94.50611899999996,78.1727600000001],[-94.52000399999986,78.17747500000013],[-94.67111199999988,78.24081400000006],[-94.68306000000001,78.24720800000006],[-94.69415299999991,78.2586060000001],[-94.69221500000003,78.26470900000004],[-94.68110699999988,78.27415500000001],[-94.66082799999992,78.27916000000005],[-94.63555899999994,78.28387500000008],[-94.60221899999999,78.28720099999992],[-94.57223499999992,78.28776600000015],[-94.54638699999998,78.28442400000006],[-94.51501499999989,78.27804600000007],[-94.48194899999993,78.268326],[-94.36111499999987,78.22164900000007],[-94.34472699999998,78.21470600000009],[-94.316666,78.19747900000004],[-94.30943300000001,78.1910860000001],[-94.30694599999993,78.18498200000005],[-94.30915799999997,78.17915300000004],[-94.36665299999999,78.15914900000013]],[[-88.28721599999994,78.24331699999999],[-88.36000100000001,78.23776199999992],[-88.38194299999998,78.24247699999995],[-88.39361600000001,78.24887100000001],[-88.40472399999999,78.25999500000006],[-88.40750099999991,78.2644350000001],[-88.41111799999993,78.27387999999996],[-88.40972899999997,78.29220599999996],[-88.404449,78.29803500000003],[-88.23527499999989,78.42692599999998],[-88.11305199999998,78.45526099999995],[-88.09445199999999,78.45694000000015],[-88.07028199999996,78.45471200000003],[-88.06138599999991,78.45248400000008],[-88.05277999999993,78.44552600000009],[-88.04972800000002,78.44442700000008],[-88.04333499999996,78.43664600000005],[-88.04444899999993,78.42442299999999],[-88.04499799999996,78.42137100000008],[-88.04666099999997,78.41886899999997],[-88.05722000000003,78.40748599999995],[-88.16639699999996,78.30802900000003],[-88.18777499999999,78.29165599999993],[-88.245544,78.2527770000001],[-88.25500499999998,78.24720800000006],[-88.28721599999994,78.24331699999999]],[[-109.64806399999992,78.58804299999997],[-109.569458,78.58638000000008],[-109.54998799999998,78.58665500000006],[-109.50055700000001,78.582764],[-109.40527299999997,78.55693100000008],[-109.33416699999998,78.52415500000012],[-109.26055899999994,78.48719800000009],[-109.25556899999998,78.48248300000006],[-109.254997,78.47859199999999],[-109.26055899999994,78.455826],[-109.31806899999992,78.35803199999998],[-109.32721700000002,78.35220300000015],[-109.40499899999992,78.30636600000008],[-109.42859599999997,78.303314],[-109.59583999999995,78.30276500000002],[-109.766953,78.29414400000013],[-109.82444799999996,78.29386900000009],[-109.85333300000002,78.29664600000001],[-109.882767,78.30137600000006],[-109.89306599999998,78.30720500000007],[-109.89835399999998,78.3119200000001],[-109.90862299999998,78.31776400000007],[-109.92610200000001,78.32304399999998],[-109.95527599999997,78.32582100000008],[-109.98388699999998,78.32554600000003],[-110.01251200000002,78.32360800000009],[-110.19638099999997,78.30386400000003],[-110.22444199999995,78.29998799999993],[-110.25250199999999,78.29582200000004],[-110.279449,78.284988],[-110.29778299999992,78.2810970000001],[-110.354446,78.27665700000006],[-110.4119419999999,78.27720600000004],[-110.484734,78.28442400000006],[-110.57167099999992,78.28970300000003],[-110.65833999999995,78.29304500000012],[-110.71556099999992,78.29248000000013],[-110.78778099999994,78.30693100000013],[-110.85665899999987,78.32720899999998],[-110.85888699999998,78.3377690000001],[-110.97501399999999,78.363876],[-111.00250199999999,78.36804200000006],[-111.14138799999995,78.38610800000004],[-111.16999799999996,78.38415500000008],[-111.27778599999994,78.37220799999994],[-111.27139299999999,78.34610000000004],[-111.30610699999994,78.32110600000004],[-111.41000400000001,78.27720600000004],[-111.42304999999993,78.27221700000007],[-111.43888899999996,78.2686000000001],[-111.46250899999995,78.26748700000002],[-111.50527999999997,78.26693699999998],[-111.57556199999999,78.27053800000004],[-111.65249599999993,78.27276599999999],[-111.73832700000003,78.27276599999999],[-111.76666299999994,78.27137800000008],[-111.79527299999995,78.2711030000001],[-111.82000700000003,78.27360499999998],[-111.86472300000003,78.29637099999997],[-111.88221699999997,78.30693100000013],[-111.88861099999997,78.3124850000001],[-111.89277599999997,78.31805400000013],[-111.89167800000001,78.32222000000002],[-111.91861,78.33276400000005],[-111.939438,78.33831800000007],[-112.13305700000001,78.36554000000001],[-112.21501199999994,78.36526500000014],[-112.43776700000001,78.35443100000009],[-112.58306899999997,78.34359700000005],[-112.68443299999996,78.33137500000004],[-112.73916599999995,78.32304399999998],[-112.78721599999989,78.31053199999997],[-112.89083900000003,78.29248000000013],[-112.94499199999996,78.28387500000008],[-113.026947,78.27276599999999],[-113.05499299999997,78.27137800000008],[-113.14222699999999,78.268326],[-113.16860999999994,78.2686000000001],[-113.18831599999999,78.26998900000012],[-113.21777299999985,78.27777100000003],[-113.27333099999998,78.29637099999997],[-113.28195199999999,78.29971300000011],[-113.287781,78.30247500000002],[-113.33249699999993,78.32887299999999],[-113.33416699999998,78.33276400000005],[-113.21611000000001,78.38526900000011],[-113.1241609999999,78.4208220000001],[-113.11527999999987,78.42303500000008],[-113.03832999999997,78.43691999999999],[-112.71167000000003,78.48471100000006],[-112.60749800000002,78.4994200000001],[-112.36305199999998,78.53332499999999],[-112.31166100000002,78.53997799999996],[-112.23805199999998,78.547211],[-112.12970699999994,78.55192600000004],[-111.98805199999987,78.55276499999997],[-111.90360999999996,78.54887400000007],[-111.87304699999999,78.54443400000008],[-111.85305800000003,78.54275500000006],[-111.8097229999999,78.54525800000005],[-111.75250199999994,78.55053700000002],[-111.67777999999993,78.56303400000002],[-111.641953,78.57415800000007],[-111.60082999999997,78.5852660000001],[-111.57224299999996,78.588593],[-111.45556599999998,78.592758],[-111.39195299999994,78.61192299999999],[-111.378601,78.617752],[-111.3799899999999,78.62275700000004],[-111.36305199999998,78.64276099999995],[-111.160553,78.69164999999992],[-110.95612299999993,78.71832300000011],[-110.79110700000001,78.73525999999993],[-110.6375119999999,78.74859600000008],[-110.46028100000001,78.75749200000001],[-110.43055700000002,78.75860599999999],[-110.410553,78.757767],[-110.39527900000002,78.75610400000011],[-110.3844529999999,78.75138900000007],[-110.271118,78.72776800000003],[-110.16416900000002,78.70915199999996],[-110.07778899999988,78.69497700000005],[-109.99722300000002,78.68386800000002],[-109.86165599999998,78.66693099999998],[-109.85582699999998,78.66026299999999],[-109.86000100000001,78.65443399999998],[-109.86165599999998,78.64915500000001],[-109.86110699999995,78.643326],[-109.85526999999996,78.637497],[-109.67054699999989,78.5913700000001],[-109.64806399999992,78.58804299999997]],[[-74.30694599999998,78.67665100000005],[-74.33416699999992,78.67526200000009],[-74.36721799999998,78.67608600000005],[-74.41944899999999,78.68165599999992],[-74.61416600000001,78.70277400000003],[-74.70472699999993,78.72276299999993],[-74.71000700000002,78.72747799999996],[-74.71028100000001,78.73109400000004],[-74.70666499999999,78.7374880000001],[-74.64500399999997,78.77249100000006],[-74.63221699999997,78.77720600000009],[-74.61582900000002,78.77859500000011],[-74.59110999999996,78.7788700000001],[-74.55555700000002,78.776093],[-74.35694899999993,78.75582900000006],[-74.31204200000002,78.75000000000006],[-74.28195199999999,78.74609400000003],[-74.19248999999996,78.72970599999996],[-74.16777000000002,78.71998600000006],[-74.16361999999992,78.716095],[-74.17277499999989,78.71138000000013],[-74.23638899999997,78.68719499999992],[-74.25666799999993,78.6827550000001],[-74.28443900000002,78.67886400000003],[-74.30694599999998,78.67665100000005]],[[-96.76806599999998,78.684143],[-96.70889299999999,78.6827550000001],[-96.64500399999997,78.68609600000013],[-96.61305199999998,78.68553200000002],[-96.58500700000002,78.68331900000004],[-96.53361499999994,78.6769260000001],[-96.510559,78.672485],[-96.46639999999996,78.66192600000011],[-96.39527900000002,78.64054900000008],[-96.379166,78.63443000000007],[-96.35610999999994,78.62776200000008],[-96.31582600000002,78.618042],[-96.29388399999993,78.61526500000008],[-96.265015,78.61886600000014],[-96.23554999999999,78.62776200000008],[-96.20249899999988,78.63026400000001],[-96.18443299999996,78.62858600000004],[-96.16749599999997,78.62330600000001],[-96.15888999999987,78.61720300000007],[-96.15249599999999,78.61137400000001],[-96.21640000000002,78.56053199999997],[-96.17805499999992,78.5188750000001],[-96.00944500000003,78.49247700000012],[-95.85777300000001,78.49498000000006],[-95.82000699999992,78.5022130000001],[-95.74665800000002,78.51499899999999],[-95.71665999999999,78.51971400000002],[-95.68472300000002,78.52110300000004],[-95.652222,78.52137800000003],[-95.601944,78.51971400000002],[-95.53721599999994,78.51470899999998],[-95.481674,78.50888100000003],[-95.40777599999996,78.49720800000006],[-95.20638999999994,78.46165500000001],[-95.08694499999996,78.43775900000009],[-94.89500399999997,78.39582800000011],[-94.87777699999992,78.3913730000001],[-94.86082499999992,78.38472000000013],[-94.83167999999995,78.36469999999997],[-94.82917799999996,78.35887100000014],[-94.83084099999991,78.35276799999997],[-94.83750899999995,78.34721400000001],[-94.8533329999999,78.3419340000001],[-94.94193999999999,78.31637599999999],[-94.96694899999994,78.31137100000012],[-95.09638999999993,78.29026800000003],[-95.36361699999992,78.24136400000009],[-95.38806199999993,78.23637400000001],[-95.39917000000003,78.23109399999998],[-95.39862099999999,78.22692899999998],[-95.38890099999998,78.22248800000006],[-95.36888099999999,78.21859699999999],[-95.34583999999995,78.217758],[-95.25527999999991,78.21804800000001],[-95.22749299999998,78.2166600000001],[-95.130829,78.19413800000001],[-95.11305199999993,78.18858300000011],[-95.10694899999999,78.18525700000009],[-95.108612,78.17942800000009],[-95.11193799999995,78.17414900000011],[-95.11193799999995,78.16748000000001],[-95.10610999999994,78.16192600000005],[-95.089722,78.15498400000013],[-95.06806899999992,78.14804100000015],[-94.98332199999993,78.13304099999999],[-94.90695199999999,78.11720300000013],[-94.88999899999999,78.10887099999997],[-94.88694799999996,78.10276800000003],[-94.91166699999985,78.055252],[-95.01139799999999,77.99136399999992],[-95.04388399999993,77.97499100000005],[-95.0574949999999,77.96914700000008],[-95.08528099999995,77.95887800000003],[-95.10055499999993,77.95359799999994],[-95.112503,77.95138500000002],[-95.13751199999996,77.95054600000003],[-95.16250600000001,77.95359799999994],[-95.18638599999986,77.95776400000005],[-95.21167000000003,77.96110500000009],[-95.23693800000001,77.964157],[-95.26583899999997,77.96609500000011],[-95.321396,77.96775800000006],[-95.37998999999996,77.96638499999995],[-95.400284,77.9627690000001],[-95.41332999999986,77.95942699999995],[-95.42555199999993,77.94802900000013],[-95.44972200000001,77.9433140000001],[-95.54972800000002,77.934143],[-95.75805700000001,77.91192600000011],[-95.83084099999996,77.89888000000013],[-95.93859900000001,77.88581799999997],[-96.18943799999994,77.86608900000004],[-96.28555299999994,77.85942100000005],[-96.31750499999993,77.8583220000001],[-96.345551,77.85859700000009],[-96.36527999999998,77.859985],[-96.386124,77.86276200000009],[-96.40417499999995,77.8685910000001],[-96.41194200000001,77.87498499999998],[-96.41082799999992,77.88081399999999],[-96.40527299999997,77.88638299999997],[-96.410553,77.89054900000008],[-96.416946,77.8938750000001],[-96.43582200000003,77.89860499999998],[-96.45666499999999,77.90165700000006],[-96.54110700000001,77.89721700000007],[-96.73443600000002,77.87275700000004],[-96.73500099999995,77.86692800000003],[-96.710556,77.855545],[-96.69638099999992,77.85081500000013],[-96.66722099999993,77.84915200000006],[-96.58500700000002,77.85636899999997],[-96.55888400000003,77.85942100000005],[-96.53971899999999,77.8644260000001],[-96.51611300000002,77.86943099999996],[-96.49166899999989,77.87025499999993],[-96.51556399999998,77.8455350000001],[-96.54277000000002,77.84193400000004],[-96.62832599999996,77.84054600000013],[-96.68720999999988,77.84054600000013],[-96.71166999999997,77.83970600000009],[-96.73416099999997,77.83554100000009],[-96.74861099999993,77.83027600000003],[-96.82945299999994,77.789154],[-96.84999099999999,77.78720100000004],[-96.88055399999996,77.78692600000005],[-96.900284,77.78831500000001],[-96.90777600000001,77.79054299999996],[-96.912216,77.79304500000006],[-96.93388400000003,77.79748500000005],[-97.01417499999997,77.80415300000004],[-97.05749500000002,77.80554200000006],[-97.07250999999991,77.80415300000004],[-97.09695399999993,77.80331400000006],[-97.10221899999999,77.80748],[-97.11972000000003,77.86526500000008],[-97.11999499999996,77.87025499999993],[-97.10749799999996,77.87637300000006],[-97.08138999999994,77.88665800000001],[-97.01556399999998,77.90416000000005],[-97.002228,77.90860000000004],[-96.99221799999998,77.91415400000005],[-96.99249299999991,77.91886900000009],[-96.99499500000002,77.92109700000003],[-97.14277599999997,77.9349820000001],[-97.28167699999995,77.94831800000009],[-97.30999799999995,77.95109600000006],[-97.354446,77.96220400000004],[-97.38027999999997,77.969986],[-97.431671,77.98692300000005],[-97.45472699999993,77.99275200000005],[-97.50306699999987,78.00248699999992],[-97.57223499999998,78.01249700000005],[-97.60278299999993,78.01554899999996],[-97.67361499999998,78.02137800000014],[-97.75556899999998,78.02554299999997],[-97.766953,78.0288700000001],[-97.77555799999999,78.03498800000006],[-97.666946,78.08804300000008],[-97.64778100000001,78.09082000000001],[-97.61833199999995,78.09166000000005],[-97.56750499999993,78.08970600000004],[-97.51306199999999,78.08665500000001],[-97.43249499999996,78.08055100000013],[-97.323624,78.0769350000001],[-97.297775,78.07638500000007],[-97.0244449999999,78.07470699999993],[-96.997772,78.07527199999998],[-96.910278,78.07916300000005],[-96.88751199999996,78.08305400000012],[-96.85555999999991,78.10415599999993],[-96.85638399999999,78.10803200000004],[-96.870544,78.133331],[-96.88555899999994,78.13804600000003],[-96.98388699999992,78.15081800000007],[-97.05915799999997,78.15776100000005],[-97.13806199999993,78.16581700000012],[-97.164444,78.16886900000003],[-97.18472299999996,78.17248500000011],[-97.19499200000001,78.17692599999998],[-97.20083599999992,78.18359399999997],[-97.21250900000001,78.18942299999998],[-97.29943800000001,78.20471200000009],[-97.32112099999995,78.20748899999995],[-97.34916699999997,78.20860299999998],[-97.40777600000001,78.207764],[-97.63555899999994,78.20665000000002],[-97.829453,78.21914700000002],[-97.84944199999995,78.23471100000012],[-97.81750499999998,78.23275799999999],[-97.773056,78.23887600000012],[-97.76333599999992,78.24443100000002],[-97.77778599999988,78.25],[-97.86776699999996,78.27970900000003],[-97.881104,78.28360000000009],[-97.90417500000001,78.28804000000008],[-97.93055700000002,78.290817],[-98.01278699999995,78.29693600000002],[-98.05471799999992,78.30165100000005],[-98.06834399999997,78.30802900000003],[-98.07084699999996,78.31359900000007],[-98.04361,78.38943499999999],[-98.14834599999995,78.4038700000001],[-98.17222600000002,78.40498400000007],[-98.19833399999999,78.40859999999998],[-98.347778,78.443039],[-98.36665299999999,78.44941699999998],[-98.38806199999999,78.46748400000001],[-98.410553,78.49026500000002],[-98.41139199999992,78.4952550000001],[-98.41027799999995,78.50804099999999],[-98.30888400000003,78.53387500000002],[-98.17138699999998,78.52970900000014],[-98.05444299999999,78.53360000000004],[-98.02223199999992,78.53637700000013],[-98.01916499999999,78.54275500000006],[-98.02806099999992,78.563309],[-98.04222099999993,78.56971699999997],[-98.08000199999992,78.582764],[-98.115005,78.59387199999998],[-98.13999899999999,78.599426],[-98.16915899999992,78.60304300000013],[-98.23500100000001,78.61914100000001],[-98.31527699999992,78.64387499999998],[-98.32695000000001,78.65054299999991],[-98.32806399999993,78.65220600000004],[-98.37165800000002,78.71998600000006],[-98.366104,78.76361100000003],[-98.36471599999993,78.76805100000007],[-98.17332499999992,78.81275900000014],[-98.144455,78.81666600000011],[-98.06138599999997,78.81887799999998],[-97.77778599999988,78.81526200000008],[-97.65695199999999,78.81137100000001],[-97.59973100000002,78.80747999999994],[-97.48860200000001,78.79664600000007],[-97.46194500000001,78.792755],[-97.43693499999989,78.786926],[-97.385559,78.77693199999999],[-97.35916099999997,78.77304100000009],[-97.27362099999999,78.76443499999999],[-97.160278,78.75888100000003],[-97.07806399999998,78.74971000000005],[-97.02528399999994,78.74192800000009],[-96.99972500000001,78.73692300000005],[-96.95472699999993,78.72637900000001],[-96.92250099999995,78.71331800000007],[-96.91389500000002,78.70694000000009],[-96.90388499999995,78.70166000000006],[-96.88639799999999,78.69664],[-96.76806599999998,78.684143]],[[-86.319458,78.88360600000004],[-86.38806199999988,78.88304100000005],[-86.41471899999993,78.88443000000001],[-86.44444299999998,78.8872070000001],[-86.46916199999993,78.88970899999998],[-86.48443600000002,78.89276100000012],[-86.47694399999989,78.89637800000008],[-86.43638599999997,78.91110200000008],[-86.38667299999997,78.9249880000001],[-86.366104,78.92970300000013],[-86.346115,78.93969700000014],[-86.32861300000002,78.95082100000002],[-86.29277000000002,78.98304700000011],[-86.28527799999995,78.99331700000005],[-86.28361499999994,78.99803200000008],[-86.04695100000004,79.03858900000006],[-85.99082899999996,79.04693600000007],[-85.92443799999995,79.05386400000003],[-85.89611799999994,79.05693100000013],[-85.82000700000003,79.06137100000001],[-85.71250900000001,79.06414800000005],[-85.646118,79.06442300000009],[-85.32139599999994,79.05386400000003],[-85.26333599999992,79.04887400000001],[-85.2161099999999,79.04136700000004],[-85.19972200000001,79.03749099999999],[-85.18249500000002,79.03137200000015],[-85.16722099999993,79.02082800000011],[-85.16944899999999,79.01470900000004],[-85.17639199999996,79.00888099999997],[-85.18666100000002,79.0027770000001],[-85.20944199999991,78.99359099999998],[-85.22582999999997,78.98858600000011],[-85.24694799999997,78.98414600000007],[-85.30139200000002,78.97526600000003],[-85.46611000000001,78.958328],[-85.54666099999997,78.95248400000014],[-85.76556399999998,78.93414300000012],[-86.026947,78.91026299999999],[-86.21389799999997,78.89166300000005],[-86.24499500000002,78.88832100000008],[-86.28416399999998,78.885269],[-86.319458,78.88360600000004]],[[-103.59388699999988,79.32582100000002],[-103.39835399999993,79.2999880000001],[-103.33556399999998,79.2999880000001],[-103.26251200000002,79.2999880000001],[-103.13999899999993,79.28776600000015],[-103.09777799999995,79.28248600000006],[-103.08361799999994,79.27943399999998],[-103.06806899999992,79.27388000000013],[-102.921112,79.21748400000007],[-102.92666600000001,79.21110500000003],[-102.92639199999996,79.20664999999997],[-102.921944,79.20027200000004],[-102.90194699999995,79.17221100000012],[-102.89167800000001,79.16665600000005],[-102.87444299999987,79.16499299999992],[-102.76862299999993,79.13888499999996],[-102.620003,79.09721400000001],[-102.61165599999998,79.09304800000012],[-102.60582699999998,79.07443200000012],[-102.60637700000001,79.06805400000013],[-102.612213,79.05664100000013],[-102.654449,78.99414100000001],[-102.66555799999998,78.98275799999999],[-102.67582700000003,78.97747800000013],[-102.69860799999992,78.97192400000012],[-102.72084000000001,78.93830900000006],[-102.59500099999997,78.87664800000005],[-102.57945299999994,78.87303200000002],[-102.56082200000003,78.86970500000007],[-102.55082700000003,78.86943100000013],[-102.52887699999985,78.87303200000002],[-102.39195299999994,78.93165600000009],[-102.37638900000002,78.94636500000013],[-102.38054699999998,78.9627690000001],[-102.39806399999992,78.98719800000003],[-102.36305199999998,79.0149990000001],[-102.27944899999989,79.01805100000001],[-102.09361299999989,79.04414400000013],[-102.04943799999995,79.05442799999997],[-102.01500699999997,79.06498700000003],[-101.99333199999995,79.07609600000012],[-101.975281,79.08082599999994],[-101.942207,79.08471700000001],[-101.90249599999993,79.08638000000013],[-101.88194299999998,79.08610499999992],[-101.64890299999996,79.07582100000008],[-101.62805200000003,79.07193000000001],[-101.54194599999994,79.04470800000007],[-101.5202789999999,79.03831500000013],[-101.30803699999996,78.97581500000001],[-101.23166699999996,78.95942700000012],[-101.20472699999999,78.954163],[-101.17666600000001,78.95387299999993],[-101.15222199999988,78.95665000000002],[-101.14334100000002,78.96249400000005],[-101.14472999999992,78.96832300000005],[-101.14083900000003,78.97415200000006],[-101.09388699999994,78.96360800000002],[-101.00556899999998,78.94303900000006],[-100.98665599999998,78.93719500000009],[-100.98528299999998,78.93136600000003],[-101.11694299999988,78.85693400000014],[-101.15278599999999,78.83998100000008],[-101.19304699999992,78.82443199999994],[-101.20056199999999,78.82083100000011],[-101.20333899999997,78.81581100000005],[-101.20084399999996,78.81191999999999],[-101.186394,78.80276500000014],[-101.17278299999998,78.80053700000013],[-100.99194299999999,78.78887900000012],[-100.86389199999991,78.78137200000003],[-100.83056599999992,78.78970300000009],[-100.80055199999998,78.79332000000005],[-100.70556599999998,78.799713],[-100.61389200000002,78.79803500000008],[-100.587784,78.79914900000006],[-100.55915799999997,78.80442800000003],[-100.55027799999993,78.80998200000005],[-100.53639199999998,78.81553600000001],[-100.52443700000003,78.81805400000002],[-100.35109699999998,78.82832300000001],[-100.34445199999993,78.82666000000012],[-100.32389799999999,78.80220000000008],[-100.32250999999997,78.79721100000012],[-100.33249699999993,78.782761],[-100.32333399999993,78.77804600000013],[-100.283073,78.76776100000006],[-100.22778299999993,78.7605440000001],[-100.14334099999996,78.75221300000004],[-100.12416100000002,78.75000000000006],[-100.03250099999997,78.73942600000004],[-100.004997,78.73580900000007],[-99.95249899999999,78.72554000000002],[-99.93638599999997,78.71998600000006],[-99.89639299999993,78.69581600000004],[-99.89388999999994,78.69303900000011],[-99.89306599999998,78.6869200000001],[-99.91332999999992,78.67970300000002],[-99.97277799999995,78.659988],[-100.0625,78.63888500000007],[-100.0625,78.63554400000004],[-100.01666299999988,78.61665300000004],[-99.98889199999991,78.61387600000012],[-99.96305799999999,78.61499000000009],[-99.90972899999997,78.62387100000001],[-99.85333299999996,78.63304100000005],[-99.81750499999993,78.630539],[-99.573624,78.5955350000001],[-99.55027799999988,78.59027100000014],[-99.53332499999999,78.58360299999998],[-99.52972399999999,78.57804899999996],[-99.53416400000003,78.57222000000013],[-99.66111799999993,78.48553500000003],[-99.6702729999999,78.47970600000002],[-99.68415799999997,78.47442600000011],[-99.71250899999995,78.46943699999997],[-99.777222,78.46138000000002],[-99.83139,78.45082100000013],[-99.85943600000002,78.44220000000001],[-99.86776700000001,78.43748499999998],[-99.865005,78.43441800000005],[-99.821396,78.42747500000007],[-99.80139199999996,78.4208220000001],[-99.78666699999997,78.41470300000009],[-99.77667200000002,78.40859999999998],[-99.761124,78.39637800000014],[-99.75361599999991,78.3897090000001],[-99.74833699999999,78.38360599999999],[-99.74916099999996,78.3724820000001],[-99.77860999999996,78.33221400000002],[-99.79777499999994,78.30859400000003],[-99.79943799999995,78.303314],[-99.79388399999988,78.29721100000006],[-99.77583299999998,78.29248000000013],[-99.74137899999994,78.28997800000002],[-99.67304999999999,78.290817],[-99.62054399999994,78.29026800000003],[-99.55110200000001,78.28610200000014],[-99.529449,78.28248600000006],[-99.51445000000001,78.27720600000004],[-99.47972099999998,78.24914600000005],[-99.447769,78.22415200000006],[-99.42832900000002,78.21165500000006],[-99.41389499999997,78.20526100000001],[-99.39862099999999,78.19999700000005],[-99.18859900000001,78.13304099999999],[-98.98916600000001,78.07304400000004],[-98.96916199999993,78.068329],[-98.94583099999988,78.061646],[-98.94583099999988,78.05581699999999],[-98.96278399999994,78.00915500000008],[-98.97166399999998,77.99775700000009],[-98.98083499999996,77.99220300000007],[-98.99888599999991,77.98692300000005],[-99.02166699999987,77.98165900000004],[-99.08111599999995,77.97192399999994],[-99.09472700000003,77.96638499999995],[-99.09916699999997,77.96081500000008],[-99.09889199999992,77.95498700000013],[-99.0786129999999,77.92553700000008],[-99.06916799999999,77.91360500000008],[-99.04138199999994,77.90081800000007],[-99.02278100000001,77.89444000000015],[-99.01333599999998,77.88832100000013],[-99.02223199999997,77.88247700000011],[-99.23805199999998,77.83776900000004],[-99.39666699999998,77.82415800000007],[-99.525284,77.81359900000001],[-99.54943800000001,77.81248500000004],[-99.71305799999993,77.81080600000001],[-99.853882,77.79220600000008],[-99.85943600000002,77.78692600000005],[-99.87693799999994,77.78137200000003],[-99.90695199999999,77.77859500000011],[-100.21000699999996,77.80998200000005],[-100.32972699999999,77.82527200000004],[-100.49889399999995,77.85165400000011],[-100.60637699999995,77.87997400000012],[-100.75527999999997,77.95555100000007],[-100.78611799999999,77.97415200000012],[-100.81749699999995,77.99914600000005],[-100.82389799999999,78.00444000000005],[-100.83833299999998,78.02276600000005],[-100.83778399999994,78.03498800000006],[-100.83693700000003,78.04026800000008],[-100.83444199999991,78.04414399999996],[-100.82694999999995,78.04887400000001],[-100.853882,78.09664900000001],[-100.87581599999999,78.09999099999993],[-100.99861099999998,78.13165300000009],[-101.00974300000001,78.13665800000012],[-101.02194199999991,78.1477660000001],[-101.01889,78.15693700000008],[-101.01528899999994,78.16276600000009],[-101.01363399999997,78.17359900000008],[-101.01390100000003,78.18470799999994],[-101.02027900000002,78.18969700000008],[-101.035553,78.19609100000014],[-101.06276699999995,78.19859300000002],[-101.089447,78.19802900000008],[-101.23137700000001,78.18386800000007],[-101.28943599999997,78.18248],[-101.31667299999998,78.18498200000005],[-101.34249899999998,78.18942299999998],[-101.41722099999998,78.20887800000014],[-101.432503,78.21527100000009],[-101.43138099999999,78.22137499999997],[-101.43276999999989,78.22747800000008],[-101.45638999999994,78.23220800000013],[-101.47416699999991,78.23471100000012],[-101.49665800000002,78.23719800000015],[-101.833328,78.26499900000005],[-102.1330569999999,78.28276100000011],[-102.15750100000002,78.28248600000006],[-102.18221999999997,78.2810970000001],[-102.29888900000003,78.27331500000014],[-102.34722899999997,78.26776100000012],[-102.38890100000003,78.26081799999997],[-102.47138999999999,78.24887100000001],[-102.50167799999997,78.2458190000001],[-102.561394,78.24108900000004],[-102.59056099999987,78.23970000000008],[-102.61860699999994,78.24136400000009],[-102.64527900000002,78.24552900000009],[-102.73222399999992,78.26388500000007],[-102.781387,78.27609300000012],[-102.79778299999998,78.28221100000007],[-102.80943300000001,78.28831500000013],[-102.8163909999999,78.29443400000014],[-102.81833599999999,78.30026200000003],[-102.81360599999994,78.31080600000013],[-102.80803700000001,78.31693999999993],[-102.74999999999989,78.33831800000007],[-102.736107,78.34248400000013],[-102.686394,78.35054000000002],[-102.6658329999999,78.35859699999997],[-102.67083699999995,78.36303700000002],[-102.69499199999996,78.36775200000005],[-102.72250400000001,78.37136800000007],[-102.77778599999994,78.37637299999994],[-102.80610699999994,78.37776200000013],[-102.83583099999998,78.37637299999994],[-102.88999899999999,78.36914100000007],[-102.92027299999995,78.36581400000011],[-102.93804899999992,78.36469999999997],[-102.96694899999989,78.36415099999999],[-103.02443699999998,78.36526500000014],[-103.13390400000003,78.36914100000007],[-103.16388699999999,78.36692800000009],[-103.21417200000002,78.35664400000007],[-103.23832700000003,78.35054000000002],[-103.26471699999996,78.34526100000005],[-103.38110399999988,78.3316650000001],[-103.41111799999999,78.3294370000001],[-103.49804699999999,78.32777400000003],[-103.52749599999987,78.32638500000002],[-103.58473200000003,78.32193000000001],[-103.67999299999997,78.3119200000001],[-103.751106,78.30137600000006],[-103.78195199999999,78.29609700000003],[-103.80803700000001,78.29054300000007],[-103.829453,78.284988],[-103.87721299999998,78.27221700000007],[-103.89417300000002,78.25221299999993],[-103.89890299999996,78.2458190000001],[-103.910278,78.24108900000004],[-103.93331899999998,78.23719800000015],[-103.96305799999999,78.23359700000009],[-103.99194299999999,78.23304700000006],[-104.02250699999996,78.23414600000007],[-104.04277000000002,78.23692299999999],[-104.06984699999987,78.24217199999998],[-104.08306899999997,78.24414099999996],[-104.110817,78.24664300000006],[-104.19027699999998,78.25166300000012],[-104.30471799999992,78.25221299999993],[-104.36361699999998,78.25443999999999],[-104.41251399999999,78.25776700000011],[-104.46749899999998,78.26527400000009],[-104.49445300000002,78.27053800000004],[-104.82055700000001,78.35582000000011],[-104.99194299999999,78.43775900000009],[-104.99999999999994,78.44386299999996],[-105.05055199999998,78.48803700000008],[-105.05139200000002,78.49443100000013],[-105.04305999999991,78.50582900000012],[-105.01194800000002,78.52165199999996],[-104.95361299999996,78.5374910000001],[-104.86860699999994,78.56053199999997],[-104.83139,78.56999200000001],[-104.806107,78.572495],[-104.69638099999992,78.5788730000001],[-104.66665599999999,78.57971200000009],[-104.39778100000001,78.56999200000001],[-104.35500300000001,78.56637599999993],[-104.287781,78.55525200000005],[-104.26278699999995,78.54942300000005],[-104.21221899999995,78.53997799999996],[-104.1661069999999,78.53276100000005],[-104.14277600000003,78.5294340000001],[-104.08833300000003,78.52415500000012],[-104.03388999999999,78.51998900000007],[-103.93055699999996,78.516098],[-103.87110899999993,78.51805100000013],[-103.78250100000002,78.51971400000002],[-103.7225039999999,78.51721199999997],[-103.66583299999996,78.51249700000011],[-103.58860799999997,78.50387599999999],[-103.53333299999991,78.49636799999996],[-103.52362099999999,78.49609400000003],[-103.51834100000002,78.49693300000001],[-103.465843,78.51748699999996],[-103.37805200000003,78.58610500000003],[-103.39998599999996,78.61554000000012],[-103.44666299999994,78.62136800000007],[-103.50611900000001,78.62136800000007],[-103.74082900000002,78.61970500000012],[-103.98554999999999,78.61692800000003],[-104.01000999999991,78.61720300000007],[-104.04215999999991,78.62068199999993],[-104.04222099999998,78.62997399999995],[-104.03278399999988,78.63526900000005],[-103.98916600000001,78.6461030000001],[-103.85193600000002,78.66943400000014],[-103.82611099999997,78.67192100000005],[-103.77223200000003,78.67109700000009],[-103.65834000000001,78.66499300000004],[-103.62888299999992,78.6644290000001],[-103.53943600000002,78.66499300000004],[-103.50917099999987,78.66638200000006],[-103.48361199999994,78.66914400000013],[-103.49082899999996,78.67498799999998],[-103.50306699999999,78.6810910000001],[-103.51306199999993,78.68748499999992],[-103.52778599999999,78.6994170000001],[-103.525284,78.70526100000012],[-103.51806599999998,78.71081500000008],[-103.48860200000001,78.71582000000012],[-103.439438,78.72026100000005],[-103.41221599999989,78.72026100000005],[-103.38861099999997,78.71693399999992],[-103.35804699999994,78.71859700000005],[-103.33389299999999,78.72248800000011],[-103.31916799999999,78.72859199999999],[-103.31639099999995,78.734421],[-103.31889299999995,78.74026499999997],[-103.41665599999999,78.7788700000001],[-103.43916300000001,78.78498800000006],[-103.46806300000003,78.78749100000005],[-103.63971699999996,78.76527399999998],[-103.66915899999992,78.7605440000001],[-103.71056399999998,78.75000000000006],[-103.796112,78.73580900000007],[-103.70249899999999,78.78831500000001],[-103.69526699999994,78.79386899999997],[-103.698036,78.799713],[-103.72693599999997,78.80220000000008],[-103.86054999999999,78.80609099999998],[-103.87053699999996,78.80636599999997],[-103.886124,78.80442800000003],[-103.9083399999999,78.79914900000006],[-103.90556299999997,78.79414400000002],[-103.89639299999993,78.78471400000012],[-103.89083900000003,78.78027300000002],[-103.89527899999996,78.77499400000005],[-103.90527299999997,78.76887500000004],[-103.92916899999994,78.76499899999993],[-103.96056399999992,78.76138300000008],[-103.99109599999991,78.75888100000003],[-104.02166699999992,78.75749200000001],[-104.04943800000001,78.75637800000004],[-104.07389799999993,78.757767],[-104.170547,78.76582300000007],[-104.19888300000002,78.770264],[-104.21167000000003,78.776093],[-104.21972699999998,78.78221100000013],[-104.21528599999999,78.79359399999998],[-104.16722099999998,78.8163760000001],[-104.13305700000001,78.82748400000008],[-104.04834,78.83888200000007],[-103.98665599999998,78.85026599999998],[-103.86054999999999,78.87664800000005],[-103.83139,78.88693200000012],[-103.82389799999999,78.89248700000002],[-103.82167099999992,78.89833099999998],[-103.82472199999995,78.90331999999995],[-103.86749299999997,78.91609199999999],[-103.96305799999999,78.92997700000006],[-103.98998999999998,78.93275500000004],[-104.00639299999995,78.93553199999997],[-104.029449,78.9416500000001],[-104.04750099999995,78.94775400000009],[-104.05332899999996,78.95220899999993],[-104.053879,78.95748900000001],[-104.05222300000003,78.96138000000008],[-104.04778299999992,78.96665999999993],[-104.048607,78.97109999999998],[-104.05777,78.97415200000006],[-104.08112299999999,78.97943100000003],[-104.12943999999999,78.98580900000002],[-104.17859599999991,78.99026500000014],[-104.20361300000002,78.99165300000004],[-104.23388699999998,78.99192800000003],[-104.265556,78.98858600000011],[-104.45500199999998,78.95609999999999],[-104.47193899999996,78.95054600000003],[-104.51112399999994,78.91026299999999],[-104.53832999999997,78.88192700000002],[-104.56416300000001,78.86470000000003],[-104.57888799999989,78.85859700000009],[-104.78582799999998,78.80664100000001],[-104.81749699999995,78.80220000000008],[-104.87860099999995,78.79803500000008],[-104.909157,78.79664600000007],[-104.96888699999994,78.79721100000012],[-104.98832700000003,78.79832500000009],[-105.01194800000002,78.8035890000001],[-105.02250699999996,78.80998200000005],[-105.02861000000001,78.81526200000008],[-105.02916699999997,78.82165500000008],[-105.028343,78.83276399999994],[-105.01222200000001,78.84471100000007],[-104.83389299999999,78.92665099999999],[-104.68859899999995,78.99359099999998],[-104.678879,78.99971],[-104.674713,79.00499000000008],[-104.68110699999994,79.01666300000011],[-104.69415300000003,79.02276600000005],[-104.70805399999995,79.02777100000009],[-104.737213,79.03193699999997],[-104.90249599999993,79.04971299999994],[-104.98638899999997,79.043045],[-105.01334399999996,79.03831500000013],[-105.09916699999991,79.02388000000002],[-105.12526700000001,79.0211030000001],[-105.15638699999988,79.01943999999997],[-105.39527900000002,79.01165800000007],[-105.42610200000001,79.01110800000004],[-105.48388699999998,79.01304600000014],[-105.51363399999997,79.01609800000006],[-105.54332699999998,79.02026399999994],[-105.5625,79.02442899999994],[-105.58138999999994,79.03054800000001],[-105.59084299999995,79.03442400000006],[-105.59944200000001,79.04026800000008],[-105.60665899999992,79.0519260000001],[-105.628601,79.16137700000007],[-105.62053699999996,79.1727600000001],[-105.48277300000001,79.30636600000008],[-105.45973199999997,79.32415800000012],[-105.43998699999997,79.329163],[-105.40862299999992,79.32887299999999],[-105.38305699999995,79.32693500000005],[-105.33277899999996,79.31944300000009],[-105.19721999999996,79.29971300000011],[-105.16111799999999,79.29748500000011],[-105.12721299999998,79.29748500000011],[-105.108612,79.29887400000013],[-105.01611300000002,79.31053199999997],[-104.95472699999993,79.31526200000002],[-104.85916099999997,79.31915300000009],[-104.74276700000001,79.322495],[-104.583328,79.3294370000001],[-104.54860699999989,79.33137500000004],[-104.49082900000002,79.339157],[-104.46083099999998,79.34220900000008],[-104.181671,79.35887100000008],[-104.00723299999999,79.36775200000005],[-103.97778299999999,79.36886600000003],[-103.9491579999999,79.36804200000006],[-103.83500699999996,79.36442599999998],[-103.7225039999999,79.35693400000002],[-103.69526699999994,79.35220300000009],[-103.62053700000001,79.33055100000007],[-103.59388699999988,79.32582100000002]],[[-99.47166399999998,80.109711],[-99.43666100000002,80.10720800000001],[-99.40472399999993,80.10803199999998],[-99.29804999999999,80.11886600000003],[-99.13667299999992,80.13304099999993],[-99.11054999999988,80.13053900000006],[-99.08168,80.12469500000003],[-98.86888099999999,80.07777400000003],[-98.85665899999992,80.07249500000006],[-98.774719,80.01527400000009],[-98.70584100000002,79.96582000000006],[-98.64416499999987,79.80026199999992],[-98.64416499999987,79.79414400000002],[-98.64862099999988,79.78359999999992],[-98.67304999999999,79.77192700000012],[-98.77917500000001,79.70220899999998],[-98.83000199999992,79.6644290000001],[-98.86805700000002,79.70082100000008],[-98.93611099999998,79.71971100000002],[-98.96777299999991,79.72415200000012],[-99.13999899999993,79.74081400000011],[-99.24305699999996,79.74859600000008],[-99.27362099999993,79.75138900000002],[-99.30139199999991,79.75471500000009],[-99.31723,79.75860599999999],[-99.32444800000002,79.76249700000005],[-99.32556199999999,79.76748700000007],[-99.32250999999991,79.77137800000014],[-99.31304899999992,79.776093],[-99.30471799999992,79.78221100000013],[-99.30277999999998,79.78749099999999],[-99.29750100000001,79.81275900000009],[-99.295837,79.83332800000005],[-99.29638699999992,79.83915700000006],[-99.30221599999987,79.84526100000011],[-99.31582600000002,79.84860200000014],[-99.36888099999999,79.8577580000001],[-99.55665599999992,79.88888500000002],[-99.58444199999997,79.8919370000001],[-99.61416600000001,79.89332600000012],[-99.64778100000001,79.89305100000007],[-99.67971799999998,79.88804600000003],[-99.70083599999987,79.88275099999998],[-99.73222399999997,79.87886000000009],[-99.80082700000003,79.87664800000005],[-100.00556899999998,79.8744200000001],[-100.03582799999992,79.87469500000009],[-100.07028199999996,79.87692300000003],[-100.097778,79.88108800000003],[-100.12110899999999,79.88665800000012],[-100.14389,79.89305100000007],[-100.15862299999998,79.89860500000009],[-100.17748999999998,79.90998800000011],[-100.17832900000002,79.91581700000012],[-100.193329,80.03387500000008],[-100.08167999999989,80.084427],[-100.06555200000003,80.08998099999997],[-100.02362099999993,80.09971600000006],[-99.827225,80.14359999999999],[-99.79527299999995,80.1477660000001],[-99.75917099999998,80.149719],[-99.726944,80.15054299999997],[-99.62554899999992,80.14888000000008],[-99.59999099999999,80.145264],[-99.59388699999988,80.13916],[-99.57112099999995,80.1327510000001],[-99.47166399999998,80.109711]],[[-99.15556300000003,80.17469799999998],[-99.12721299999993,80.168045],[-99.11389199999996,80.16387900000012],[-99.13806199999999,80.16249100000005],[-99.160553,80.16304000000014],[-99.18499800000001,80.167755],[-99.2519529999999,80.17303500000008],[-99.27749599999999,80.17303500000008],[-99.31361399999997,80.17109700000015],[-99.34138499999995,80.1660920000001],[-99.33306900000002,80.15942400000012],[-99.30360399999995,80.1538700000001],[-99.30555699999991,80.1483310000001],[-99.34249899999992,80.1455380000001],[-99.37527499999993,80.14721700000013],[-99.40055799999993,80.15081800000002],[-99.41805999999997,80.15721100000013],[-99.41833500000001,80.16304000000014],[-99.41332999999997,80.16886899999997],[-99.38694799999996,80.17886400000009],[-99.36694299999994,80.18220500000012],[-99.2391659999999,80.18386800000007],[-99.21194499999996,80.18220500000012],[-99.15556300000003,80.17469799999998]],[[-95.0308379999999,80.67025800000005],[-94.96945199999993,80.64027400000003],[-94.970551,80.635269],[-94.98138399999999,80.63192700000008],[-95.006958,80.62664800000005],[-95.19027699999992,80.60887100000002],[-95.22610499999996,80.60914600000001],[-95.45361300000002,80.62942499999997],[-95.61111499999998,80.64804099999998],[-95.67694099999994,80.65331999999995],[-95.71194500000001,80.65443399999998],[-95.74916099999996,80.65386999999998],[-95.78805499999993,80.65220599999998],[-95.82362399999994,80.64860499999992],[-95.86332699999997,80.64582800000005],[-96.061935,80.65664700000008],[-96.11805699999996,80.66053799999997],[-96.14916999999997,80.66470300000015],[-96.13944999999995,80.66970800000001],[-96.07667500000002,80.683044],[-96.02833599999997,80.68719500000009],[-96.00611900000001,80.68803400000002],[-95.491379,80.69999700000005],[-95.42443800000001,80.69970700000005],[-95.20056199999993,80.6974790000001],[-95.16694599999994,80.69525099999998],[-95.12887599999993,80.69192500000008],[-95.09666399999998,80.688583],[-95.06249999999994,80.68248000000006],[-95.06527699999992,80.68054200000012],[-95.04583699999995,80.67692600000004],[-95.0308379999999,80.67025800000005]],[[-92.72778299999993,81.30554200000006],[-92.53028899999998,81.28498800000011],[-92.21305799999999,81.24552900000003],[-92.148056,81.23637400000013],[-92.12470999999994,81.2327580000001],[-92.05248999999992,81.2185970000001],[-91.95584100000002,81.19636500000001],[-91.858047,81.167755],[-91.781677,81.09027100000014],[-91.78388999999993,81.08360299999998],[-91.79750100000001,81.08166500000004],[-91.83250399999997,81.08027600000008],[-91.88806199999993,81.08194000000009],[-91.914444,81.07804900000002],[-91.91389499999997,81.07499700000011],[-91.908615,81.07054099999999],[-91.89334100000002,81.06498699999997],[-91.86582899999996,81.05859400000003],[-91.76722699999993,81.04914899999994],[-91.72222899999997,81.04220599999996],[-91.53889500000002,80.98165899999998],[-91.52555799999999,80.97499099999999],[-91.52278100000001,80.96276900000004],[-91.53167699999995,80.951096],[-91.527222,80.93969700000008],[-91.51777600000003,80.93275499999999],[-91.481674,80.91943400000002],[-91.321121,80.88275099999998],[-91.306107,80.87553400000002],[-91.152222,80.78553800000003],[-91.15499899999998,80.78054800000001],[-91.14916999999997,80.770264],[-91.14056399999998,80.7647090000001],[-91.12165800000002,80.75471500000003],[-91.09944199999995,80.74803200000008],[-91.03472899999997,80.73748800000004],[-90.97277799999995,80.73027000000002],[-90.90527299999997,80.724426],[-90.777222,80.71775800000006],[-90.75418100000002,80.71499599999993],[-90.712784,80.70555100000007],[-90.66471899999999,80.684708],[-90.65249599999993,80.67804000000001],[-90.603882,80.65138200000001],[-90.59361299999995,80.64526400000011],[-90.59306300000003,80.64082300000001],[-90.60194399999995,80.63610799999998],[-90.61582900000002,80.63026400000012],[-90.67805499999997,80.61554000000007],[-90.71583599999991,80.605545],[-90.74249299999991,80.59471100000007],[-90.76306199999999,80.5836030000001],[-90.77166699999998,80.57748400000008],[-90.77278099999995,80.57193000000007],[-90.76640299999991,80.56553600000007],[-90.74137899999994,80.56219500000003],[-90.70611600000001,80.56137100000007],[-90.60722399999992,80.56137100000007],[-90.58306900000002,80.56137100000007],[-90.41805999999991,80.55220000000008],[-90.23889199999996,80.55053699999996],[-90.20333900000003,80.549713],[-90.17721599999999,80.54887400000007],[-90.04638699999992,80.54165600000005],[-90.01640299999997,80.53803999999997],[-90,80.53459199999998],[-89.98999000000003,80.532486],[-89.96139499999998,80.520264],[-89.95556599999998,80.51554899999996],[-89.93859899999995,80.508331],[-89.84056099999998,80.48136900000009],[-89.81639100000001,80.4749910000001],[-89.79028299999993,80.46943700000008],[-89.76251199999996,80.46499599999999],[-89.75111400000003,80.46443200000004],[-89.78416399999992,80.50082400000002],[-89.74833699999988,80.532761],[-89.58694500000001,80.5455320000001],[-89.546112,80.54748500000005],[-89.48277300000001,80.544983],[-89.4472199999999,80.54248000000001],[-89.354172,80.53498800000006],[-89.32640099999992,80.53193700000003],[-89.27278100000001,80.52331500000003],[-89.24499500000002,80.51721200000009],[-89.05915800000002,80.46138000000013],[-89.08750899999995,80.43858300000005],[-89.11527999999993,80.43386800000002],[-89.17610199999996,80.42665100000005],[-89.19833399999993,80.42164600000001],[-89.20944199999991,80.41775499999994],[-89.23500100000001,80.40803500000004],[-89.25,80.40220600000004],[-89.25723299999999,80.39694200000008],[-89.25361599999997,80.39276100000001],[-89.237213,80.388596],[-89.21694899999994,80.38970900000004],[-89.18971299999993,80.39414999999997],[-89.16749600000003,80.39915500000001],[-89.136124,80.40248100000008],[-89.09973100000002,80.40248100000008],[-89.08332799999988,80.39833100000004],[-89.07583599999992,80.39305100000001],[-89.10499599999991,80.33943199999999],[-89.11416599999995,80.33332799999994],[-89.12527499999993,80.32777399999998],[-89.14361600000001,80.32331800000003],[-89.16915899999998,80.31805400000007],[-89.2202759999999,80.30914300000012],[-89.24194299999994,80.3041530000001],[-89.25666799999999,80.29859900000008],[-89.26390099999998,80.29332000000011],[-89.26222199999995,80.28665200000012],[-89.25140399999998,80.27832000000012],[-89.180496,80.23817400000007],[-89.11389200000002,80.20803800000004],[-89.09222399999999,80.20082100000013],[-89.07278400000001,80.19552600000009],[-88.77667200000002,80.13136300000002],[-88.75,80.12664799999999],[-88.53472899999991,80.09887700000013],[-88.49888599999997,80.09887700000013],[-88.44193999999993,80.10054000000002],[-88.41471899999999,80.10498000000007],[-88.414444,80.10803199999998],[-88.36305199999993,80.12442000000004],[-88.23527499999989,80.10247799999996],[-88.16194199999995,80.09165999999999],[-88.145554,80.09387200000003],[-88.148346,80.09803799999997],[-88.26139799999993,80.18803400000013],[-88.27305599999994,80.19552600000009],[-88.29415899999998,80.20138500000007],[-88.35082999999997,80.20887800000008],[-88.422775,80.21054100000003],[-88.47999600000003,80.21360800000014],[-88.50695799999994,80.218323],[-88.59527600000001,80.2369230000001],[-88.61805700000002,80.24331699999999],[-88.63027999999991,80.249146],[-88.66139199999992,80.27249100000012],[-88.68443299999996,80.35859700000015],[-88.68582200000003,80.36554000000012],[-88.685272,80.37164300000006],[-88.68305999999995,80.37692300000015],[-88.67721599999993,80.38275100000004],[-88.64889499999992,80.3936000000001],[-88.61527999999993,80.40387000000004],[-88.51028400000001,80.42886400000003],[-88.48777799999999,80.43386800000002],[-88.46333300000003,80.43803400000007],[-88.420547,80.44220000000001],[-88.383896,80.44358800000009],[-88.30833399999995,80.4427490000001],[-88.11054999999993,80.4327550000001],[-87.91888399999999,80.42109700000009],[-87.718613,80.41110200000014],[-87.68388400000003,80.41026300000004],[-87.6663969999999,80.40387000000004],[-87.63612399999994,80.36692800000003],[-87.60749800000002,80.32415800000007],[-87.56388900000002,80.23332200000004],[-87.561935,80.18359399999991],[-87.56277499999993,80.17915300000004],[-87.57223499999992,80.17608600000011],[-87.67805499999992,80.15637199999998],[-87.72138999999999,80.15304600000013],[-87.93916299999995,80.14387500000004],[-87.96665999999999,80.13943499999999],[-88.04888900000003,80.125809],[-88.06555200000003,80.12081899999998],[-88.06054699999999,80.11747700000006],[-87.95666499999999,80.06971700000003],[-87.93804899999998,80.06442300000009],[-87.89138799999995,80.05554200000012],[-87.86000100000001,80.05358899999999],[-87.83612099999993,80.0577550000001],[-87.823059,80.06248499999992],[-87.76306199999993,80.07110600000004],[-87.72000099999991,80.0747070000001],[-87.68055700000002,80.07638500000002],[-87.64167800000001,80.07638500000002],[-87.365005,80.072769],[-87.29998799999998,80.06944300000009],[-87.27555799999988,80.06693999999993],[-87.25862099999995,80.06387300000006],[-87.23332199999999,80.05748000000006],[-87.21528599999999,80.05053700000008],[-87.04333499999996,79.9649960000001],[-87.09361299999995,79.92942800000009],[-87.314438,79.86608899999999],[-87.33612099999993,79.86137400000013],[-87.36833200000001,79.85720800000007],[-87.44665500000002,79.8560940000001],[-87.4719389999999,79.85247800000002],[-87.48306299999996,79.84721400000006],[-87.48944099999994,79.84137000000004],[-87.48554999999988,79.834991],[-87.46362299999998,79.83137499999992],[-87.43916299999995,79.83194000000015],[-87.412781,79.83332800000005],[-87.33860800000002,79.84082000000001],[-87.19082600000002,79.86608899999999],[-87.16555800000003,79.87109400000003],[-87.14695699999993,79.87553400000007],[-87.07972699999993,79.89610300000004],[-87.05139200000002,79.90664700000008],[-87.02471899999995,79.91609199999994],[-87.00306699999999,79.91775500000006],[-86.98582499999998,79.91775500000006],[-86.97389199999986,79.91638199999994],[-86.96139499999998,79.90998800000011],[-86.95777900000002,79.90359499999994],[-86.960556,79.89137299999999],[-87.05555700000002,79.73193400000008],[-87.13417099999992,79.64526400000011],[-87.14416499999993,79.63777199999998],[-87.15499899999998,79.6336060000001],[-87.17304999999999,79.62914999999998],[-87.25862099999995,79.61026000000004],[-87.34445199999993,79.59637499999997],[-87.42555199999998,79.57916300000011],[-87.44166599999994,79.57388300000002],[-87.44804399999998,79.56832900000006],[-87.46250900000001,79.53471399999995],[-87.44193999999999,79.52638200000001],[-87.40666199999998,79.51582300000013],[-87.39056399999993,79.51110800000009],[-87.36639400000001,79.50637800000004],[-87.34527600000001,79.50305200000003],[-87.30999800000001,79.50221300000004],[-87.28056300000003,79.50694300000009],[-87.26278699999995,79.51138300000008],[-87.24833699999999,79.5169370000001],[-87.19055200000003,79.54359399999998],[-87.18276999999995,79.54887400000007],[-87.17999299999997,79.55415300000004],[-87.16888399999999,79.5663760000001],[-87.16111799999993,79.57165500000008],[-87.07667500000002,79.58749399999999],[-87.02555799999999,79.5955350000001],[-87.00111399999997,79.59887700000002],[-86.96665999999993,79.60165400000011],[-86.93249500000002,79.60165400000011],[-86.84138499999995,79.59304800000001],[-86.823624,79.58776900000004],[-86.81973299999999,79.576096],[-86.82389799999999,79.5660860000001],[-86.839722,79.55581700000005],[-86.84638999999999,79.54998800000004],[-86.837784,79.54332000000005],[-86.816666,79.53970300000015],[-86.78999299999998,79.53887899999995],[-86.777222,79.54220600000008],[-86.69499199999996,79.56749000000008],[-86.693329,79.57360800000004],[-86.71055599999994,79.58720399999999],[-86.72389199999998,79.59443700000003],[-86.74638399999998,79.59999099999999],[-86.80248999999998,79.60609399999993],[-86.81304899999992,79.61192299999999],[-86.80638099999987,79.617752],[-86.79527299999995,79.62164300000006],[-86.77694699999995,79.62747200000007],[-86.76222200000001,79.63165300000014],[-86.68721,79.64526400000011],[-86.64083899999991,79.65332000000001],[-86.61305199999993,79.655823],[-86.57501200000002,79.65721100000007],[-86.547775,79.65637200000009],[-86.33416699999992,79.64553800000004],[-86.30277999999998,79.64276100000012],[-86.27944899999994,79.64027400000003],[-86.258896,79.63499500000006],[-86.10916099999997,79.595261],[-86.046112,79.56887799999998],[-86.04222099999993,79.56553600000007],[-86.02806099999992,79.4747010000001],[-86.05471799999998,79.47053500000004],[-86.160553,79.46360800000014],[-86.16749600000003,79.45776400000011],[-86.136124,79.44470200000006],[-86.120834,79.43997200000007],[-86.09889199999992,79.43580600000013],[-86.07084700000001,79.43414300000006],[-86.03500400000001,79.43637100000001],[-86.01194799999996,79.44026200000008],[-85.99055499999997,79.44497700000011],[-85.97582999999992,79.44914200000011],[-85.96417199999996,79.45443699999998],[-85.90110800000002,79.49359100000004],[-85.88722200000001,79.50526400000007],[-85.88528399999996,79.51138300000008],[-85.89334100000002,79.52331500000008],[-85.89916999999997,79.53637700000007],[-85.89666699999998,79.54914900000011],[-85.89334100000002,79.55470300000007],[-85.88778699999995,79.56109600000002],[-85.84750400000001,79.59637499999997],[-85.84028599999999,79.60192899999993],[-85.82833900000003,79.60748300000012],[-85.781387,79.61554000000012],[-85.743607,79.61692800000003],[-85.68194599999993,79.61331200000012],[-85.63917500000002,79.60415599999999],[-85.62388599999991,79.59915200000006],[-85.591385,79.58526600000005],[-85.53111299999995,79.55941800000011],[-85.48500099999995,79.51860000000005],[-85.402222,79.47360200000014],[-85.30665599999992,79.428314],[-85.27806099999998,79.41554300000013],[-85.15055799999993,79.38220200000012],[-85.13027999999997,79.3785860000001],[-85.03971899999988,79.35081500000001],[-84.93249499999996,79.30026200000003],[-84.92027300000001,79.29332000000011],[-84.90417500000001,79.27665700000006],[-84.90417500000001,79.26776100000012],[-84.90972899999986,79.26304600000009],[-84.93110699999994,79.25833100000006],[-85.09999099999993,79.2394260000001],[-85.15888999999993,79.23193399999997],[-85.21139499999987,79.22331199999996],[-85.23277299999995,79.21887200000015],[-85.24804699999987,79.21304299999997],[-85.26000999999991,79.207764],[-85.27194199999997,79.19720500000011],[-85.28056300000003,79.19220000000007],[-85.29722600000002,79.18719500000003],[-85.591385,79.15415999999999],[-85.77999899999992,79.13108800000003],[-85.87721299999998,79.12164299999995],[-86.00389100000001,79.11137400000013],[-86.15888999999999,79.10331699999995],[-86.27139299999999,79.09553499999998],[-86.34167499999995,79.08831800000007],[-86.42250100000001,79.07554600000009],[-86.48554999999999,79.06330900000012],[-86.55082700000003,79.04887400000001],[-86.55999799999995,79.04443400000014],[-86.55555700000002,79.04248000000013],[-86.55082700000003,79.03553800000003],[-86.55249000000003,79.02943400000004],[-86.55999799999995,79.01220699999999],[-86.58778399999994,78.98359700000015],[-86.59889199999992,78.97831700000006],[-86.61444099999994,78.97331200000002],[-86.67694099999989,78.95971700000013],[-86.70222499999994,78.95526100000006],[-86.74137899999994,78.95193499999999],[-86.765015,78.95359800000011],[-86.78500400000001,78.95721399999996],[-86.808334,78.96720900000008],[-86.90333599999985,79.00943000000007],[-86.91639699999996,79.01666300000011],[-86.92639199999996,79.03581200000013],[-86.93055699999996,79.04776000000004],[-86.94055199999997,79.05358900000004],[-86.94915800000001,79.05720500000007],[-86.96528599999994,79.05748000000011],[-86.98332199999993,79.05664100000013],[-86.98998999999998,79.04776000000004],[-87.004456,78.98719800000003],[-87.00250199999999,78.98136900000003],[-86.98693799999995,78.94970700000005],[-86.97999599999997,78.9433140000001],[-86.96694899999994,78.93637100000012],[-86.95083599999998,78.92942800000009],[-86.94276400000001,78.92248500000011],[-86.93777499999999,78.91693099999992],[-86.95249899999993,78.90664700000008],[-86.97084000000001,78.89610300000004],[-86.99749800000001,78.88247700000005],[-87.02166699999992,78.87303200000002],[-87.05249000000003,78.86276200000009],[-87.17944299999994,78.83055100000001],[-87.28277599999996,78.81025700000004],[-87.32806399999998,78.79470800000013],[-87.353882,78.78414900000007],[-87.52999899999992,78.6869200000001],[-87.53277600000001,78.66998300000012],[-87.54305999999997,78.66470300000003],[-87.57278399999996,78.65443399999998],[-87.591949,78.64971899999995],[-87.61582900000002,78.64526400000011],[-87.66305499999999,78.64248700000002],[-87.68443299999996,78.64498900000012],[-87.87277199999994,78.69497700000005],[-87.93777499999987,78.73831200000006],[-87.95361299999996,78.74971000000005],[-87.95916699999998,78.75526400000007],[-87.99388099999993,78.79525799999999],[-88.00334199999992,78.80720500000012],[-88.00140399999998,78.82415800000001],[-87.985275,78.95721399999996],[-87.98167399999988,78.96054100000009],[-87.96833800000002,78.96638500000012],[-87.89416499999999,78.97970600000008],[-87.83361799999994,78.99220300000007],[-87.81361400000003,78.99693300000007],[-87.79444899999999,79.00694300000004],[-87.72888199999994,79.06944299999998],[-87.72471599999994,79.07582100000008],[-87.73388699999998,79.08110000000005],[-87.74610899999993,79.08610499999992],[-87.752792,79.08554099999998],[-87.77278099999995,79.08082599999994],[-87.80638099999993,79.06999200000007],[-87.84916699999997,79.05497700000012],[-87.87277199999994,79.0452580000001],[-87.883331,79.03997800000008],[-87.894455,79.02832000000001],[-87.890289,79.02165200000007],[-87.89999399999999,79.01110800000004],[-87.92944299999999,79.00694300000004],[-88.000565,79.00360100000006],[-88.03277600000001,79.0038760000001],[-88.06138599999991,79.005829],[-88.09388699999994,79.00444000000005],[-88.16250600000001,78.99054000000012],[-88.20249899999993,78.97637900000012],[-88.21305799999999,78.96609500000011],[-88.21528599999994,78.96081500000003],[-88.21665999999993,78.94831800000003],[-88.22972099999998,78.80220000000008],[-88.224716,78.78915399999994],[-88.22222899999997,78.78332499999993],[-88.21806300000003,78.77693199999999],[-88.20111099999997,78.75721699999997],[-88.13221699999997,78.68081699999999],[-88.04415899999992,78.65860000000009],[-88.02416999999997,78.65664700000013],[-88.01083399999993,78.65277100000009],[-87.99305699999996,78.64526400000011],[-87.98277299999995,78.6394350000001],[-87.908615,78.59693900000008],[-87.89472999999998,78.58471700000013],[-87.89083900000003,78.57832300000007],[-87.89695699999987,78.56637599999993],[-87.90833999999995,78.54859900000008],[-87.98472599999997,78.49220299999996],[-88.01194800000002,78.48136900000009],[-88.05583200000001,78.47276299999999],[-88.20527600000003,78.45248400000008],[-88.23416099999997,78.45359800000006],[-88.24916099999996,78.45664999999997],[-88.38945000000001,78.52137800000003],[-88.5594329999999,78.60415600000005],[-88.57472199999995,78.60720800000013],[-88.723053,78.61581400000006],[-88.78860500000002,78.61276199999998],[-88.80416899999994,78.60971100000012],[-88.74610899999993,78.53581200000008],[-88.72500600000001,78.52415500000012],[-88.65916400000003,78.49108899999999],[-88.59527600000001,78.459991],[-88.5625,78.44470200000012],[-88.55221599999999,78.43748499999998],[-88.54388399999999,78.42608600000011],[-88.535553,78.41304000000014],[-88.53611799999993,78.40693700000003],[-88.53805499999999,78.40138200000013],[-88.541382,78.39665200000007],[-88.55305499999992,78.3855440000001],[-88.56111099999998,78.37942500000008],[-88.57055699999995,78.37387100000007],[-88.61471599999999,78.34832799999998],[-88.66332999999997,78.32138100000003],[-88.67250100000001,78.31608599999998],[-88.70417799999996,78.2711030000001],[-88.710556,78.26110799999998],[-88.71389799999986,78.25471500000003],[-88.71556099999998,78.24914600000005],[-88.71611000000001,78.243042],[-88.72111499999994,78.23109399999998],[-88.72610500000002,78.22526600000003],[-88.75140399999998,78.19693000000012],[-88.77667200000002,78.17608599999994],[-88.78443900000002,78.169983],[-88.79333499999996,78.16442900000004],[-88.81777999999991,78.1544340000001],[-88.84777799999995,78.15138200000001],[-88.97888199999994,78.16581700000012],[-89.00279199999994,78.16943400000008],[-89.06500199999988,78.18441800000011],[-89.07972699999999,78.18914799999999],[-89.11582899999996,78.20082100000002],[-89.22749299999998,78.24525499999999],[-89.25917099999992,78.26277199999998],[-89.26501499999995,78.268326],[-89.275284,78.28193699999997],[-89.35388199999989,78.33970599999998],[-89.364441,78.34414700000008],[-89.381104,78.3477630000001],[-89.51834100000002,78.39221200000009],[-89.67666599999995,78.44747899999999],[-89.803879,78.49443100000013],[-89.819458,78.50054900000009],[-89.89111300000002,78.55276499999997],[-89.92166099999997,78.57804899999996],[-89.945831,78.599426],[-89.95695499999988,78.605255],[-89.98055999999997,78.60971100000012],[-90.01472499999988,78.60942100000011],[-90.05139199999996,78.60582000000005],[-90.08833299999998,78.5958250000001],[-90.09249899999998,78.58998099999991],[-90.09973100000002,78.55525200000005],[-90.10082999999997,78.54971300000005],[-90.06471299999993,78.51332100000008],[-89.98500099999995,78.43609600000002],[-89.960556,78.43248000000011],[-89.93611099999998,78.43026700000001],[-89.91000400000001,78.42608600000011],[-89.86999500000002,78.417755],[-89.80972300000002,78.40470900000008],[-89.785278,78.39804100000009],[-89.77444500000001,78.39387499999998],[-89.74804699999993,78.38026400000001],[-89.61555499999986,78.30026200000003],[-89.60610999999994,78.29332],[-89.46167000000003,78.17553700000002],[-89.45584100000002,78.169983],[-89.45249899999999,78.16249100000005],[-89.46167000000003,78.15859999999998],[-89.47666899999996,78.15386999999998],[-89.50778199999996,78.1499940000001],[-89.53028899999998,78.14833099999998],[-89.54943799999995,78.14860500000009],[-89.56304899999992,78.14971900000006],[-89.59584000000001,78.15693700000008],[-89.61860699999994,78.16304000000002],[-89.63194299999998,78.16859400000004],[-89.63972499999994,78.17330900000007],[-89.64416499999999,78.17970300000007],[-89.646118,78.18470799999994],[-89.646118,78.19720500000011],[-89.64805599999994,78.2022090000001],[-89.65417499999995,78.20942700000012],[-89.65722699999998,78.21220399999999],[-89.67388899999997,78.21720900000008],[-89.70083599999998,78.21914700000002],[-89.74888599999991,78.21720900000008],[-89.78332499999993,78.21443199999999],[-89.847778,78.21304299999997],[-89.88694800000002,78.21527100000009],[-89.91111799999999,78.21887200000015],[-89.929169,78.22303800000009],[-89.95527600000003,78.2333220000001],[-89.96028100000001,78.23831199999995],[-89.96194500000001,78.24359099999992],[-89.95944199999997,78.25443999999999],[-89.95500199999992,78.26054400000004],[-89.98028599999992,78.27777100000003],[-90.02333099999998,78.29803500000003],[-90.060272,78.30802900000003],[-90.17250099999995,78.33110000000005],[-90.18611099999993,78.333328],[-90.21362299999998,78.33526599999993],[-90.24249299999985,78.33610500000009],[-90.27416999999997,78.33499100000012],[-90.34056099999998,78.33110000000005],[-90.41139199999992,78.32443200000006],[-90.478882,78.32110600000004],[-90.50778199999996,78.32054099999999],[-90.59445199999999,78.32276899999994],[-90.62026999999995,78.32554600000003],[-90.66777000000002,78.32748399999997],[-90.729446,78.32609600000006],[-90.74444599999998,78.32304399999998],[-90.74861099999998,78.32026700000006],[-90.73721299999994,78.31442300000003],[-90.71556099999992,78.309143],[-90.62277199999994,78.29109199999999],[-90.598343,78.28749099999993],[-90.54499800000002,78.28305100000011],[-90.46166999999997,78.27887000000004],[-90.41027799999995,78.27665700000006],[-90.36332700000003,78.25694299999998],[-90.27389499999998,78.19220000000007],[-90.26750199999992,78.18664600000011],[-90.26889,78.18275500000004],[-90.27278100000001,78.17692599999998],[-90.29388399999999,78.15998800000011],[-90.30110200000001,78.15525800000006],[-90.33029199999999,78.14610300000004],[-90.35388199999994,78.14332600000012],[-90.43388400000003,78.13638300000014],[-90.465012,78.13526899999994],[-90.49777199999994,78.134995],[-90.62443499999995,78.13443000000001],[-90.71112099999999,78.13581800000009],[-90.96722399999999,78.14276100000006],[-91.02139299999999,78.14610300000004],[-91.03971899999999,78.1502690000001],[-91.23838799999999,78.16659499999997],[-91.32667499999997,78.16859400000004],[-91.48971599999987,78.17692599999998],[-91.53999299999992,78.18136600000003],[-91.61389199999996,78.19192500000008],[-91.6619419999999,78.19970700000005],[-91.70722999999998,78.20942700000012],[-91.72471599999994,78.21470600000009],[-91.80777,78.23275799999999],[-91.83139,78.23692299999999],[-91.85749799999996,78.23970000000008],[-91.8875119999999,78.23942599999992],[-91.92027300000001,78.23719800000015],[-91.94638099999997,78.23275799999999],[-91.96333299999998,78.22776800000008],[-91.97444199999995,78.22331200000002],[-91.98611499999998,78.21470600000009],[-92.00306699999999,78.20971700000013],[-92.031113,78.20748899999995],[-92.058334,78.20887800000014],[-92.083328,78.21249400000005],[-92.10555999999997,78.217758],[-92.30833399999995,78.278595],[-92.537216,78.31053199999997],[-92.55665599999998,78.31469699999997],[-92.589447,78.32360800000009],[-92.94943199999989,78.43193100000002],[-92.96665999999999,78.44358799999992],[-92.98249800000002,78.45443699999998],[-92.98721299999994,78.46026599999999],[-92.98750299999995,78.46554600000007],[-92.97888199999994,78.48332200000004],[-92.96665999999999,78.48858600000005],[-92.86389199999996,78.50526400000012],[-92.84861799999999,78.50555400000013],[-92.69055199999997,78.49581900000004],[-92.64639299999993,78.48748799999993],[-92.62193300000001,78.48719800000009],[-92.60055499999999,78.48803700000008],[-92.57667500000002,78.49054000000007],[-92.52027900000002,78.49859600000013],[-92.493607,78.50332599999996],[-92.48721299999994,78.50776700000006],[-92.48777799999999,78.50943000000001],[-92.497772,78.51304600000003],[-92.56332399999997,78.52053799999999],[-92.52944899999994,78.52137800000003],[-92.24722300000002,78.52777100000003],[-92.21665999999993,78.52804600000002],[-92.07084700000001,78.52554300000003],[-92.01112399999994,78.526657],[-91.94999699999994,78.53027300000008],[-91.91861,78.534424],[-91.72639500000002,78.53054800000007],[-91.68249500000002,78.52609300000006],[-91.66082799999998,78.52693200000004],[-91.64611799999994,78.52998400000013],[-91.63612399999994,78.53360000000004],[-91.63249200000001,78.53942900000004],[-91.63528400000001,78.54609700000003],[-91.64750699999996,78.56025700000009],[-91.65750099999997,78.563873],[-91.67027299999995,78.56581100000011],[-91.945267,78.57222000000013],[-92.15139799999992,78.57943700000004],[-92.35194399999995,78.586929],[-92.55722000000003,78.59471100000013],[-92.58555599999994,78.59609999999998],[-92.60472099999998,78.59860200000003],[-92.697769,78.6141510000001],[-92.73306300000002,78.62359600000002],[-92.75778199999996,78.62803600000001],[-92.806107,78.6336060000001],[-92.828888,78.63192700000008],[-92.90722700000003,78.62303200000008],[-92.93554699999999,78.61886600000014],[-92.93582199999997,78.61499000000009],[-92.941666,78.60859700000015],[-92.95584100000002,78.6038670000001],[-92.99166899999994,78.599716],[-93.176941,78.58638000000008],[-93.210556,78.58415200000007],[-93.24249299999997,78.582764],[-93.271118,78.58415200000007],[-93.28443900000002,78.58749400000005],[-93.43415799999997,78.6336060000001],[-93.77139299999999,78.75054900000003],[-93.81361399999997,78.76582300000007],[-93.80277999999993,78.770264],[-93.68415800000002,78.782486],[-93.650284,78.78471400000012],[-93.589722,78.78359999999998],[-93.53443899999996,78.7788700000001],[-93.429169,78.76721200000009],[-93.37638899999996,78.7605440000001],[-93.35139499999997,78.75610400000011],[-93.29972800000002,78.74859600000008],[-93.24722300000002,78.74192800000009],[-93.19055199999997,78.73637400000013],[-93.16332999999997,78.73553500000014],[-93.09973100000002,78.73719800000009],[-93.05499299999997,78.73997499999996],[-93.04222099999987,78.74525500000004],[-93.039963,78.75000000000006],[-93.03944399999995,78.75109900000007],[-93.03527799999995,78.761932],[-93.03778099999994,78.76582300000007],[-93.11888099999999,78.77249100000006],[-93.17027300000001,78.77998400000007],[-93.27194199999997,78.79609700000015],[-93.34638999999993,78.80998200000005],[-93.36915599999998,78.81608600000004],[-93.391388,78.82083100000011],[-93.41639700000002,78.824997],[-93.56054699999993,78.83332800000011],[-93.589722,78.83471700000007],[-93.650284,78.83554100000003],[-93.74694799999997,78.834991],[-93.77972399999999,78.8336030000001],[-93.84277299999997,78.83248900000012],[-93.87470999999994,78.8336030000001],[-93.89250199999998,78.83804299999991],[-93.902222,78.84248400000001],[-93.906387,78.849152],[-93.91749599999997,78.86053500000003],[-93.93943799999994,78.871643],[-93.95944199999997,78.878311],[-94.05249000000003,78.90248100000002],[-94.09584000000001,78.91110200000008],[-94.25306699999999,78.95694000000003],[-94.26972999999998,78.96220400000004],[-94.28222700000003,78.96887200000003],[-94.28750600000001,78.98109399999998],[-94.28860500000002,78.98637400000007],[-94.24137899999988,78.99664300000006],[-94.00527999999991,79.02970900000003],[-93.91027799999995,79.04193099999998],[-93.87805199999997,79.04248000000013],[-93.85472099999993,79.04054300000007],[-93.81388900000002,79.03553800000003],[-93.78416400000003,79.03804000000014],[-93.60194399999989,79.06832899999995],[-93.472778,79.10887100000014],[-93.45556599999998,79.11970500000001],[-93.45249899999999,79.12553400000002],[-93.45666499999999,79.132202],[-93.46333300000003,79.13693200000006],[-93.46055599999994,79.14276100000006],[-93.44305400000002,79.14804100000009],[-93.36610399999995,79.16137700000007],[-93.32972699999993,79.16442899999998],[-93.29499799999991,79.16693100000009],[-93.25917099999992,79.16748000000001],[-93.22778299999993,79.16693100000009],[-93.00306699999999,79.1544340000001],[-92.89555399999995,79.14387500000004],[-92.86972000000003,79.13970899999993],[-92.84110999999996,79.14109800000011],[-92.816101,79.14553799999999],[-92.80139200000002,79.1502690000001],[-92.7933349999999,79.15582300000005],[-92.78028899999987,79.16110200000003],[-92.74694799999997,79.164154],[-92.50695799999994,79.15832499999999],[-92.47860699999995,79.15582300000005],[-92.40750099999991,79.14610299999998],[-92.30943300000001,79.14526400000005],[-92.24305700000002,79.14694199999997],[-91.89805599999994,79.16137700000007],[-91.69193999999999,79.17330900000002],[-91.43916299999995,79.18359399999997],[-91.20527599999997,79.19192500000003],[-91.00917099999987,79.20304899999996],[-90.81193499999995,79.2080380000001],[-90.60166900000002,79.21415700000011],[-90.56416299999995,79.21554600000013],[-90.52833599999991,79.21748400000007],[-90.49276700000001,79.2208250000001],[-90.39083900000003,79.23637400000001],[-90.36833199999995,79.243042],[-90.36326600000001,79.2468110000001],[-90.38221699999997,79.2494200000001],[-90.40556300000003,79.25193800000011],[-90.472778,79.25082399999991],[-90.50222799999995,79.2494200000001],[-90.73222399999997,79.23831200000012],[-90.88583399999999,79.24414100000013],[-91.13999899999993,79.24443100000013],[-91.19888300000002,79.24136400000003],[-91.47084000000001,79.22886700000004],[-91.86111499999993,79.21527100000009],[-92.02639799999997,79.20748900000012],[-92.053604,79.20526100000001],[-92.087784,79.20416300000011],[-92.18083200000001,79.20304899999996],[-92.21389799999997,79.20416300000011],[-92.23889200000002,79.20555100000001],[-92.51028400000001,79.23275799999993],[-92.62193300000001,79.24443100000013],[-92.67666600000001,79.25138900000013],[-92.69471699999997,79.25721700000008],[-92.69305399999996,79.2622070000001],[-92.62554899999998,79.29525800000005],[-92.60388199999994,79.30081200000006],[-92.57194499999997,79.3041530000001],[-92.52333099999993,79.30775500000004],[-92.454453,79.30859400000003],[-92.39472999999998,79.30859400000003],[-92.30332900000002,79.30636600000008],[-92.25500499999998,79.30442800000014],[-92.13137799999998,79.2999880000001],[-91.99499500000002,79.29525800000005],[-91.96194499999996,79.29553199999998],[-91.9324949999999,79.297211],[-91.89416499999999,79.301086],[-91.86527999999993,79.30554200000012],[-91.82945299999994,79.31469700000014],[-91.79554699999989,79.31915300000009],[-91.72749299999992,79.32609600000006],[-91.65888999999999,79.32998700000013],[-91.58972199999994,79.33221400000002],[-91.52888499999995,79.33305400000006],[-91.49388099999987,79.33248900000001],[-91.46749899999998,79.33360299999998],[-91.26777600000003,79.34582499999999],[-91.23167399999994,79.34803799999992],[-91.15834000000001,79.35609399999998],[-91.11999500000002,79.38638300000002],[-91.12916599999988,79.39082300000007],[-91.156387,79.39444000000003],[-91.19110099999995,79.39332600000006],[-91.23055999999997,79.38943499999999],[-91.42222599999997,79.37414600000005],[-91.508621,79.37330600000001],[-91.58084100000002,79.36914100000001],[-91.70222499999994,79.36137400000007],[-91.72972099999998,79.35942100000011],[-91.766663,79.35331700000012],[-91.78832999999997,79.34637500000002],[-91.83528100000001,79.34082000000012],[-91.86471599999999,79.33943199999999],[-91.89778100000001,79.339157],[-92.15083299999998,79.34443700000008],[-92.18110699999994,79.34582499999999],[-92.21000699999996,79.34832799999992],[-92.29083300000002,79.35803199999992],[-92.35194399999995,79.36276199999998],[-92.41194200000001,79.36442599999998],[-92.51000999999997,79.36415099999999],[-92.56193499999995,79.36581400000006],[-92.57167099999987,79.37052900000009],[-92.57749899999999,79.37915000000004],[-92.56750499999987,79.38415500000008],[-92.47999600000003,79.40443400000004],[-92.46250900000001,79.40693700000003],[-92.41194200000001,79.41165200000006],[-92.31361400000003,79.41859399999993],[-92.24388099999999,79.4266510000001],[-92.22860700000001,79.43136600000014],[-92.22778299999993,79.43525700000004],[-92.228882,79.43830900000012],[-92.23472600000002,79.44164999999998],[-92.24194299999994,79.44413800000012],[-92.25917099999998,79.44693000000007],[-92.28332499999999,79.44914200000011],[-92.33805799999999,79.45304900000008],[-92.41972399999997,79.45721400000008],[-92.58084100000002,79.45220900000004],[-92.60527000000002,79.45054600000009],[-92.63417099999998,79.44581600000004],[-92.67999299999997,79.43719499999997],[-92.77417000000003,79.417755],[-92.80305499999997,79.41304000000014],[-92.854446,79.407761],[-92.87609899999995,79.407761],[-92.90167199999996,79.40887499999997],[-92.92944299999994,79.41249099999999],[-92.95083599999998,79.41638200000006],[-92.97332799999998,79.42359899999997],[-93.02917500000001,79.46026599999999],[-93.03277599999996,79.46554600000007],[-93.03472899999991,79.47164900000001],[-93.04472399999992,79.476089],[-93.06304899999992,79.48054500000012],[-93.09056099999998,79.48220800000007],[-93.10722399999997,79.48220800000007],[-93.12666299999995,79.47998000000007],[-93.14388999999989,79.47581500000007],[-93.14666699999998,79.46998600000006],[-93.144455,79.46388200000007],[-93.125,79.45082100000013],[-93.10583499999996,79.43942300000009],[-93.08138999999994,79.42637600000006],[-93.06111099999998,79.41581700000006],[-93.03361499999994,79.40443400000004],[-93.01889,79.399719],[-93.00917099999998,79.395264],[-93.00695799999994,79.38916000000012],[-93.00834700000001,79.38804600000014],[-93.00944500000003,79.38720699999999],[-93.02139299999999,79.3827510000001],[-93.125,79.35971100000012],[-93.26417500000002,79.3535920000001],[-93.31249999999994,79.37275700000009],[-93.25111399999997,79.40498400000007],[-93.23611499999998,79.41526800000008],[-93.22972099999998,79.42553700000013],[-93.23138399999999,79.42997700000012],[-93.23500100000001,79.43525700000004],[-93.25250199999999,79.44192499999997],[-93.27583300000003,79.44664],[-93.29333499999996,79.44802900000002],[-93.32000700000003,79.44831799999997],[-93.33805799999993,79.44720500000005],[-93.354446,79.44136000000015],[-93.4244379999999,79.405258],[-93.4330599999999,79.387497],[-93.485275,79.35415600000005],[-93.64138799999989,79.31164600000011],[-93.75750700000003,79.28360000000004],[-93.80194099999989,79.2747040000001],[-93.86999500000002,79.26388500000007],[-93.90666199999998,79.26054400000004],[-93.96972699999998,79.25749200000007],[-93.99722300000002,79.25694299999998],[-94.04722599999997,79.25749200000007],[-94.206955,79.27249099999995],[-94.212219,79.27665700000006],[-94.162781,79.32222000000002],[-94.14805599999994,79.33360299999998],[-94.11972000000003,79.34471100000002],[-94.08860800000002,79.3535920000001],[-94.05638099999993,79.37970000000007],[-94.245834,79.4041600000001],[-94.36665299999999,79.41970800000013],[-94.38612399999994,79.42137100000002],[-94.49472000000003,79.42137100000002],[-94.50917099999998,79.41638200000006],[-94.5,79.37970000000007],[-94.48306300000002,79.375809],[-94.46305799999999,79.37915000000004],[-94.454453,79.3855440000001],[-94.43276999999995,79.3855440000001],[-94.398056,79.37525900000014],[-94.38999899999999,79.36886600000003],[-94.50666799999999,79.33720400000004],[-94.53805499999993,79.33360299999998],[-94.57362399999994,79.33110000000005],[-94.63890099999998,79.33248900000001],[-94.66999799999996,79.33137500000004],[-94.697495,79.32666],[-94.72000100000002,79.32165500000013],[-94.765015,79.31164600000011],[-94.95249899999993,79.28997800000002],[-94.97000099999997,79.28471400000001],[-94.97277799999989,79.27388000000013],[-94.97721899999999,79.27026400000011],[-94.98582499999998,79.26748700000002],[-95.01861600000001,79.26693699999998],[-95.08755500000001,79.27075200000013],[-95.16166699999997,79.28109700000005],[-95.30499299999997,79.32582100000002],[-95.31861900000001,79.33221400000002],[-95.32028200000002,79.3352660000001],[-95.29444899999999,79.33665500000012],[-95.28500400000001,79.35304299999996],[-95.295837,79.37942500000003],[-95.39416499999999,79.387497],[-95.47721899999999,79.38081400000004],[-95.65556300000003,79.39166300000011],[-95.75334199999998,79.40443400000004],[-95.77166699999998,79.40971400000006],[-95.77860999999996,79.41304000000014],[-95.779449,79.42581200000012],[-95.73638899999997,79.53749100000005],[-95.65750099999997,79.55331400000011],[-95.63612399999994,79.55748],[-95.56555200000003,79.55914300000012],[-95.30972299999996,79.56915300000003],[-95.17027300000001,79.57527200000004],[-95.05166599999995,79.58221400000014],[-94.83999599999987,79.59721400000012],[-94.80248999999998,79.60054000000014],[-94.699432,79.61219800000015],[-94.40695199999999,79.66775500000011],[-94.360275,79.67776500000002],[-94.329453,79.68830900000006],[-94.28277600000001,79.75749200000001],[-94.28694200000001,79.76277200000004],[-94.29834,79.76887499999998],[-94.31834400000002,79.77859500000005],[-94.33528100000001,79.78082300000005],[-94.36166400000002,79.78193700000003],[-94.38417099999998,79.77804600000013],[-94.57749899999993,79.73580900000007],[-94.59249899999998,79.73109400000004],[-94.59666399999998,79.72581500000001],[-94.60139500000002,79.71388200000001],[-94.60888699999992,79.708328],[-94.74833699999994,79.678314],[-94.77667199999996,79.67359899999997],[-94.81443799999994,79.6702580000001],[-94.87832599999996,79.66804500000012],[-94.94638099999997,79.66693099999998],[-94.98500100000001,79.66499300000004],[-95.09167500000001,79.65693699999997],[-95.15361000000001,79.647491],[-95.19082599999996,79.64414999999997],[-95.35555999999997,79.63832100000013],[-95.41999800000002,79.637497],[-95.48527499999994,79.63804600000009],[-95.7408289999999,79.64137300000004],[-95.79943799999995,79.64248700000002],[-95.85333299999996,79.6461030000001],[-95.90110799999997,79.65443399999998],[-95.93306000000001,79.6644290000001],[-95.95472699999999,79.671921],[-95.98083500000001,79.6827550000001],[-96.03222700000003,79.70694000000009],[-96.28250100000002,79.79887400000001],[-96.335556,79.81553600000001],[-96.36082499999998,79.82249500000006],[-96.38417099999992,79.82638500000007],[-96.49055499999997,79.83610499999998],[-96.57556199999993,79.84999099999993],[-96.589447,79.85247800000002],[-96.61054999999999,79.87776200000002],[-96.61500499999994,79.88388100000003],[-96.60943600000002,79.88859600000006],[-96.573624,79.9002690000001],[-96.458618,79.91442900000004],[-96.422775,79.91609199999994],[-96.39138799999995,79.91387900000001],[-96.38500999999991,79.90971400000001],[-96.37777699999998,79.89915500000012],[-96.19471699999991,79.90138200000001],[-96.15888999999987,79.90304600000002],[-96.13806199999999,79.90637200000003],[-96.14778099999995,79.9124910000001],[-96.16471899999999,79.91720599999991],[-96.23332199999993,79.93304399999994],[-96.26251200000002,79.93692000000004],[-96.32556199999999,79.94136000000003],[-96.39917000000003,79.9410860000001],[-96.49276699999996,79.94331400000004],[-96.52416999999997,79.9452510000001],[-96.55665599999998,79.94886800000006],[-96.58056599999998,79.95277399999998],[-96.59583999999995,79.95694000000003],[-96.60665899999992,79.96220400000004],[-96.675003,80.00833100000006],[-96.67944299999999,80.0144350000001],[-96.66194199999995,80.01998900000012],[-96.62805200000003,80.02442900000011],[-96.48277299999995,80.04109199999999],[-96.41915899999992,80.04193099999998],[-96.39416499999987,80.04386900000009],[-96.39167799999996,80.04582200000004],[-96.40583799999996,80.04832500000003],[-96.428879,80.05053700000008],[-96.479172,80.05386400000003],[-96.51222200000001,80.05497700000012],[-96.54861499999993,80.053314],[-96.58250399999991,80.04859899999997],[-96.59916699999991,80.04443400000014],[-96.62777699999992,80.0394290000001],[-96.67610199999996,80.04193099999998],[-96.69888299999997,80.04693600000002],[-96.737503,80.05802900000003],[-96.78167699999995,80.07666000000006],[-96.80139199999996,80.08692900000005],[-96.80277999999998,80.09082000000012],[-96.74888599999986,80.13472000000013],[-96.73443600000002,80.1397090000001],[-96.71112099999993,80.14498900000001],[-96.67582700000003,80.1455380000001],[-96.41000399999996,80.13888500000013],[-96.38110399999994,80.13638300000008],[-96.35139500000002,80.132477],[-96.32278400000001,80.12747200000013],[-96.16305499999987,80.09304800000007],[-96.077789,80.07804900000002],[-96.01777600000003,80.070831],[-95.84777799999989,80.053314],[-95.54583699999995,80.04054300000007],[-95.41888399999993,80.036652],[-95.32501199999996,80.03387500000008],[-95.19387799999998,80.03137200000009],[-95.06361400000003,80.02998400000001],[-95.03805499999999,80.03193699999997],[-95.01167299999992,80.03887900000007],[-94.98889200000002,80.04304500000012],[-94.95111099999986,80.04553200000004],[-94.92138699999992,80.04637100000002],[-94.88751200000002,80.04582200000004],[-94.85278299999987,80.04414400000013],[-94.82583599999992,80.04054300000007],[-94.71777299999997,80.02082800000005],[-94.60749800000002,80.0027770000001],[-94.56945799999994,79.99720800000011],[-94.416946,79.9788670000001],[-94.38362099999995,79.98248299999995],[-94.38778699999995,79.98776199999992],[-94.41389499999991,79.99775700000004],[-94.45167499999997,80.00972000000007],[-94.52555799999993,80.02276599999999],[-94.62110899999999,80.04304500000012],[-94.67111199999988,80.05693100000013],[-94.74888599999997,80.07998699999996],[-94.72888199999994,80.10554500000006],[-94.63276699999994,80.13108800000003],[-94.61193799999995,80.1355440000001],[-94.51055899999994,80.15443400000004],[-94.48055999999985,80.15914900000007],[-94.41639699999996,80.16360500000002],[-94.38722200000001,80.16331500000001],[-94.28582799999992,80.1649930000001],[-94.12110899999993,80.17025799999999],[-94.09167500000001,80.17248500000005],[-94.08389299999999,80.17553700000013],[-94.09638999999999,80.17915300000004],[-94.11999500000002,80.18304400000011],[-94.18443300000001,80.18664600000005],[-94.21777299999997,80.18803400000013],[-94.35417199999995,80.19081100000005],[-94.48500099999995,80.209991],[-94.64222699999999,80.199997],[-94.64999399999988,80.19442700000008],[-94.704453,80.17804000000012],[-94.74833699999994,80.16943400000002],[-94.816956,80.15971400000012],[-95.03332499999999,80.134995],[-95.10499600000003,80.12886000000003],[-95.26362599999999,80.1183170000001],[-95.333618,80.11804200000006],[-95.36776700000001,80.1183170000001],[-95.42027300000001,80.1224820000001],[-95.65888999999999,80.16859399999998],[-95.68388400000003,80.17387400000001],[-95.695831,80.17831400000006],[-95.69221500000003,80.18109099999998],[-95.67388900000003,80.18637100000001],[-95.62165800000002,80.19525100000004],[-95.58084100000002,80.19970699999999],[-95.54277000000002,80.20220900000004],[-95.47111499999994,80.20359800000006],[-95.40417500000001,80.20359800000006],[-95.370544,80.20471200000003],[-95.32778899999988,80.2086030000001],[-95.295837,80.21276899999998],[-95.26834100000002,80.21804799999995],[-95.25445599999995,80.22221400000006],[-95.2350009999999,80.23220800000007],[-95.22999600000003,80.23609899999997],[-95.2350009999999,80.24108899999999],[-95.24333199999995,80.2435910000001],[-95.258896,80.24498000000006],[-95.27806099999992,80.24386600000008],[-95.287216,80.24108899999999],[-95.32556199999999,80.23220800000007],[-95.39834599999989,80.22360200000014],[-95.46139499999987,80.21998600000012],[-95.49694799999997,80.21943699999997],[-95.54834,80.22026100000011],[-95.56695599999995,80.224152],[-95.57749899999999,80.22943099999998],[-95.58138999999989,80.23553500000003],[-95.58639499999992,80.24054000000007],[-95.601944,80.24220300000002],[-95.64584400000001,80.23970000000003],[-95.69027699999998,80.23248300000012],[-95.71055599999994,80.22776800000008],[-95.88417099999998,80.19914200000011],[-95.92250099999995,80.19413800000001],[-95.93360899999999,80.19442700000008],[-95.98443599999996,80.20027199999998],[-96.21665999999988,80.23580900000013],[-96.43499799999995,80.26971400000002],[-96.46444699999995,80.31303400000002],[-96.61389200000002,80.32998700000013],[-96.64584400000001,80.333054],[-96.67027299999995,80.336929],[-96.68167099999988,80.34220900000008],[-96.67610199999996,80.34693900000013],[-96.658051,80.35220300000009],[-96.63417099999998,80.35720800000013],[-96.60472099999998,80.36219800000003],[-96.59222399999999,80.36276199999998],[-96.44055200000003,80.35664400000002],[-96.40888999999999,80.3535920000001],[-96.36389200000002,80.34220900000008],[-96.25472999999994,80.33554100000009],[-96.23222399999997,80.33471700000013],[-96.21640000000002,80.33804299999997],[-96.22166400000003,80.34332300000005],[-96.25500499999998,80.35415600000005],[-96.27722199999994,80.35998500000005],[-96.28083800000002,80.36192299999999],[-96.26806599999992,80.36747700000001],[-96.24055499999997,80.37303200000008],[-96.08084100000002,80.38720699999999],[-96.04777499999989,80.38998400000008],[-95.97860699999995,80.388596],[-95.73249799999991,80.37275700000004],[-95.697495,80.36997999999994],[-95.63694800000002,80.36415099999994],[-95.61221299999994,80.36026000000004],[-95.56695599999995,80.35220300000009],[-95.54277000000002,80.34582499999993],[-95.51390099999998,80.34082000000006],[-95.48832699999997,80.33804299999997],[-95.46028099999995,80.336929],[-95.44082600000002,80.33831800000002],[-95.436935,80.34109500000011],[-95.45333899999997,80.37330600000001],[-95.45861799999994,80.37858600000004],[-95.46806300000003,80.38220200000012],[-95.49861099999998,80.38388099999997],[-95.56416299999995,80.38581799999997],[-95.62499999999994,80.39166300000011],[-95.653885,80.39665200000007],[-95.69499200000001,80.4060970000001],[-95.72166400000003,80.41276599999998],[-95.85221899999999,80.45416300000005],[-95.95722999999992,80.50499000000013],[-96.02055399999995,80.56749000000008],[-96.027222,80.57415800000007],[-96.02444500000001,80.57832300000007],[-96.00695799999988,80.58276399999994],[-95.97999600000003,80.58471700000007],[-95.94166599999994,80.58638000000002],[-95.67166099999997,80.58471700000007],[-95.53639199999998,80.59082000000001],[-95.49804699999987,80.59248400000007],[-95.42361499999998,80.5935970000001],[-95.31834399999991,80.59082000000001],[-95.24665800000002,80.58998100000008],[-95.17222600000002,80.59137000000004],[-95.13221699999997,80.59387200000015],[-95.06723,80.60137900000007],[-95.0308379999999,80.603317],[-94.99499499999996,80.60304300000007],[-94.96278399999994,80.59971599999994],[-94.90249599999999,80.58665500000001],[-94.84695399999993,80.57470699999999],[-94.823624,80.56971699999997],[-94.77194199999991,80.56137100000007],[-94.75279199999994,80.55998200000005],[-94.69665499999996,80.55693100000002],[-94.658615,80.55581700000005],[-94.55499299999991,80.55442800000003],[-94.37499999999994,80.55720500000012],[-94.23083500000001,80.55636599999997],[-94.010559,80.54942299999999],[-93.968887,80.54081700000006],[-93.968887,80.536926],[-93.96611000000001,80.53082300000005],[-93.95834399999995,80.52609300000006],[-93.89916999999997,80.51915000000002],[-93.86694299999999,80.51832600000006],[-93.839447,80.51859999999999],[-93.78639199999998,80.52554300000003],[-93.78306600000002,80.52970900000008],[-93.79083299999996,80.53442400000012],[-93.81054699999999,80.5413670000001],[-93.89472999999987,80.56581100000005],[-93.94915800000001,80.57804899999991],[-93.97361799999993,80.58193999999997],[-94.00500499999998,80.58526600000005],[-94.09361299999995,80.593323],[-94.308334,80.60636899999997],[-94.43777499999999,80.605545],[-94.45750399999991,80.60026599999998],[-94.48472600000002,80.59832800000004],[-94.52417000000003,80.59832800000004],[-94.54333500000001,80.59971599999994],[-94.561935,80.60582],[-94.660278,80.65138200000001],[-94.66944899999993,80.65776100000005],[-94.672775,80.66387900000001],[-94.67027300000001,80.66970800000001],[-94.66221599999994,80.67526200000003],[-94.650284,80.68136600000008],[-94.62832600000002,80.68580600000007],[-94.59695399999998,80.69053600000012],[-94.553604,80.69497700000005],[-94.51472499999994,80.69636500000013],[-94.43916300000001,80.6974790000001],[-94.33111600000001,80.69386300000002],[-94.23167399999988,80.69220000000013],[-94.19972200000001,80.69303900000006],[-94.11749299999997,80.69859300000007],[-94.08833299999998,80.70166],[-94.07556199999999,80.70609999999999],[-94.07695000000001,80.70915200000013],[-94.08639499999998,80.71304300000003],[-94.108337,80.71887200000003],[-94.140289,80.72192400000012],[-94.30444299999994,80.73387100000008],[-94.42304999999988,80.73498500000005],[-94.44915800000001,80.73027000000002],[-94.491104,80.72692899999998],[-94.54943800000001,80.72499100000005],[-94.65972899999997,80.72526600000009],[-94.69471699999997,80.726654],[-94.722778,80.7285920000001],[-94.895554,80.74775700000009],[-95.03582799999987,80.768326],[-95.03750599999995,80.77137800000014],[-95.03694200000001,80.776093],[-95.03388999999999,80.77804600000013],[-95.025284,80.8016510000001],[-95.24305699999996,80.78776600000003],[-95.28250100000002,80.78610199999997],[-95.33416699999992,80.78887900000007],[-95.44276400000001,80.79971299999994],[-95.47555499999999,80.80304000000007],[-95.50111399999997,80.80693100000013],[-95.52417000000003,80.81248499999998],[-95.53416400000003,80.8188780000001],[-95.52639799999997,80.83332800000005],[-95.50083899999987,80.83831800000007],[-95.44027699999998,80.84610000000004],[-95.37138400000003,80.85331699999995],[-95.212784,80.8683170000001],[-95.170837,80.87580900000006],[-95.15083299999992,80.88108800000003],[-95.14666699999992,80.88388100000003],[-95.170547,80.88472000000002],[-95.30082700000003,80.88526900000011],[-95.41332999999986,80.88526900000011],[-95.468887,80.89027399999998],[-95.48138399999999,80.89471400000002],[-95.48472600000002,80.89915500000012],[-95.47416699999997,80.9044340000001],[-95.46028099999995,80.90971399999995],[-95.422775,80.92082199999999],[-95.33416699999992,80.93470800000011],[-95.31193499999995,80.93914799999999],[-95.28361499999994,80.949997],[-95.26750199999998,80.96138000000002],[-95.25973499999992,80.97360200000003],[-95.25750699999998,80.97943100000003],[-95.25917099999998,80.984985],[-95.25500499999998,80.99664300000006],[-95.241104,81.006104],[-95.2208399999999,81.01138299999997],[-95.18306000000001,81.01971400000008],[-94.943329,81.04887400000013],[-94.81416300000001,81.0541530000001],[-94.66305499999999,81.04859899999991],[-94.5727839999999,81.03887900000001],[-94.546112,81.03332500000005],[-94.49388099999999,81.01748700000002],[-94.495544,80.9958190000001],[-94.50418100000002,80.99026500000008],[-94.50917099999998,80.98471100000006],[-94.50805700000001,80.97943100000003],[-94.49276700000001,80.97276300000004],[-94.472778,80.96914699999996],[-94.43415800000002,80.96554600000013],[-94.40861499999994,80.96554600000013],[-94.36555499999997,80.96887200000015],[-94.34472699999998,80.97415200000006],[-94.33000199999987,80.97970600000002],[-94.14361600000001,81.01582300000001],[-94.07167099999992,81.02499399999994],[-93.908051,81.03942900000004],[-93.906387,81.04054300000007],[-94.01333599999998,81.05358899999999],[-94.04222099999993,81.05554200000012],[-94.18249499999996,81.06805400000007],[-94.32861299999996,81.08943200000004],[-94.35749800000002,81.09526100000005],[-94.36221299999994,81.10054000000002],[-94.35360700000001,81.10609399999998],[-94.34555099999994,81.10942100000011],[-94.31304899999998,81.11553999999995],[-94.27833599999997,81.11720300000007],[-94.25527999999997,81.11553999999995],[-94.23083500000001,81.11053500000008],[-94.21472199999988,81.10636900000003],[-94.19583099999994,81.10026600000009],[-94.15472399999999,81.09387200000003],[-94.13027999999997,81.09275800000006],[-93.98971599999999,81.09248400000013],[-93.96083099999993,81.09414700000008],[-93.93527199999994,81.09832799999998],[-93.90722700000003,81.101654],[-93.86639400000001,81.10304300000001],[-93.79527300000001,81.09942600000005],[-93.689438,81.09304800000007],[-93.51722699999988,81.08442699999995],[-93.29998799999993,81.07971199999992],[-93.25584400000002,81.08276400000005],[-93.16305499999993,81.0919340000001],[-93.15222199999994,81.09471100000002],[-93.12332199999992,81.11526500000014],[-93.09555099999994,81.1541600000001],[-93.09167499999995,81.15998800000006],[-93.09583999999995,81.16526800000008],[-93.12110899999993,81.18275499999993],[-93.25973499999998,81.21220399999993],[-93.41944899999993,81.21998600000006],[-93.514725,81.21775800000012],[-93.68749999999994,81.21026599999999],[-93.72833300000002,81.20721400000008],[-93.85221899999993,81.20304900000008],[-93.928879,81.20387300000004],[-94.03138699999994,81.20887800000008],[-94.16639700000002,81.21804800000012],[-94.20056199999988,81.22110000000004],[-94.28222700000003,81.2310940000001],[-94.30248999999998,81.23498499999994],[-94.38166799999999,81.25082400000008],[-94.38806199999999,81.25499000000013],[-94.391388,81.26110800000009],[-94.38612399999994,81.2727660000001],[-94.37027,81.28471400000001],[-94.27861000000001,81.34193400000004],[-94.26861600000001,81.34609999999992],[-94.24082900000002,81.35081499999995],[-94.20056199999988,81.355545],[-94.15388499999995,81.35971100000012],[-94.06806899999998,81.36331199999995],[-94.035278,81.36331199999995],[-93.789444,81.34803800000009],[-93.75500499999993,81.34471100000013],[-93.69444299999992,81.33749400000005],[-93.66583300000002,81.332764],[-93.63890099999998,81.3272090000001],[-93.62193300000001,81.32165500000008],[-93.61138900000003,81.3163760000001],[-93.59445199999993,81.31053199999991],[-93.55332900000002,81.30554200000006],[-93.515289,81.31053199999991],[-93.4949949999999,81.31469700000008],[-93.48306300000002,81.31971699999997],[-93.483612,81.32527200000004],[-93.48805199999998,81.33055100000001],[-93.53332499999999,81.34860200000003],[-93.56054699999993,81.367752],[-93.56471299999993,81.3766480000001],[-93.55055199999993,81.38108799999992],[-93.51750199999998,81.38499500000006],[-93.34028599999999,81.37220800000006],[-93.17749000000003,81.35859700000009],[-93.01556399999987,81.3413700000001],[-92.92805499999997,81.33082600000006],[-92.83168,81.31776400000001],[-92.72778299999993,81.30554200000006]],[[-91.71833799999996,81.54914900000006],[-91.76167299999997,81.54803500000008],[-91.80139199999996,81.54859900000002],[-91.83750900000001,81.55108600000011],[-91.86361699999998,81.555252],[-91.95111099999991,81.58415200000002],[-91.95861799999994,81.58888200000007],[-91.960556,81.59498600000012],[-91.95611599999995,81.60081500000013],[-91.9324949999999,81.60582],[-91.90388499999995,81.60832200000004],[-91.86833200000001,81.60859700000009],[-91.82389799999999,81.60693400000014],[-91.789444,81.603317],[-91.72471599999994,81.59610000000009],[-91.597778,81.58055099999996],[-91.58222999999992,81.57804900000008],[-91.61999500000002,81.56248499999998],[-91.6436159999999,81.55748000000011],[-91.67361499999998,81.55276500000008],[-91.71833799999996,81.54914900000006]],[[-78.36582899999996,82.88360599999999],[-78.383331,82.88360599999999],[-78.41944899999999,82.89915500000006],[-78.41722099999993,82.93553200000002],[-78.41471899999993,82.94192500000003],[-78.40583800000002,82.94775400000003],[-78.38972499999988,82.95332300000001],[-78.36166399999996,82.9586030000001],[-78.32333399999987,82.96192900000011],[-78.27389499999987,82.96304300000008],[-78.22361799999999,82.96110499999998],[-78.14527900000002,82.95471200000003],[-78.11972000000003,82.94859299999996],[-78.11694299999999,82.94220000000001],[-78.12249800000001,82.93719499999997],[-78.15083300000003,82.92692599999992],[-78.212784,82.91137700000002],[-78.33639499999998,82.88804600000014],[-78.36582899999996,82.88360599999999]],[[-70.11193799999995,83.10942100000011],[-70.00140399999998,83.10775799999999],[-69.81221,83.11219799999998],[-69.74888599999997,83.11192299999999],[-69.70167500000002,83.11053500000008],[-69.665009,83.1083220000001],[-69.65916400000003,83.10304300000013],[-69.66221599999994,83.07415800000007],[-69.66416899999996,83.07083099999994],[-69.68055700000002,83.06498699999997],[-69.71610999999996,83.06109600000008],[-69.75750699999998,83.05775500000004],[-69.77389499999998,83.05192600000004],[-69.77528399999994,83.0477600000001],[-69.74444599999998,83.04553199999998],[-69.67193600000002,83.04109199999994],[-69.636124,83.03970300000015],[-69.47138999999999,83.03887900000001],[-69.45111099999997,83.03581200000008],[-69.51333599999998,83.01971400000002],[-69.53611799999999,83.01443500000005],[-69.56500199999994,83.009995],[-69.55972299999996,82.99414100000013],[-69.23306299999996,83.01026899999994],[-69.15638699999994,83.01748700000013],[-69.120544,83.02165200000013],[-69.09777799999995,83.026657],[-69.06361400000003,83.03804000000002],[-69.01556399999993,83.04081700000012],[-68.98306300000002,83.03665200000012],[-68.975281,83.02832000000012],[-68.97389199999998,83.01554900000002],[-68.97721899999999,83.00166300000006],[-68.90278599999994,82.98831200000006],[-68.70834400000001,82.97804300000007],[-68.66500899999994,82.98027000000013],[-68.630829,82.98525999999998],[-68.62666300000001,82.9869230000001],[-68.57972699999999,82.99693300000001],[-68.55055199999993,83.00166300000006],[-68.514725,83.00555400000013],[-68.46665999999999,83.00804099999999],[-68.40472399999999,83.008331],[-68.35804699999989,83.00610399999994],[-68.316101,83.00332600000013],[-68.19082600000002,82.99470500000007],[-68.15417500000001,82.99108899999999],[-68.14222699999993,82.98359700000003],[-68.15527299999997,82.972488],[-68.17777999999998,82.959991],[-68.18859900000001,82.94609100000008],[-68.17639199999996,82.93887300000006],[-68.145554,82.93498199999999],[-68.09973100000002,82.93359400000008],[-68.06806899999998,82.93525700000004],[-68.054169,82.93887300000006],[-67.88166799999993,82.95887800000008],[-67.666946,82.96971100000007],[-67.61082499999992,82.96887200000009],[-67.54415899999998,82.96220399999993],[-67.50140399999998,82.95721400000008],[-67.49999999999994,82.95701600000007],[-67.47610499999996,82.95359800000006],[-67.41000399999996,82.94664000000006],[-67.32778899999994,82.94081100000005],[-67.241669,82.93691999999999],[-67.19665500000002,82.93609600000002],[-67.13612399999994,82.93664600000005],[-67.11694299999999,82.94108600000004],[-67.122772,82.94914200000011],[-67.12165800000002,82.95526100000012],[-67.11332700000003,82.95942700000006],[-67.09222399999993,82.96110499999998],[-67.04110700000001,82.95971700000007],[-66.964722,82.95416300000005],[-66.93998699999992,82.95054600000009],[-66.93832399999991,82.94775400000003],[-66.818893,82.93525700000004],[-66.65306099999987,82.93637100000001],[-66.33000199999992,82.93386800000002],[-66.30139199999996,82.93193100000002],[-66.29943799999995,82.92942800000003],[-66.34750399999996,82.89804100000009],[-66.36915599999992,82.88832100000002],[-66.81138599999997,82.81526200000002],[-66.84111000000001,82.81080600000007],[-66.87666300000001,82.80720500000007],[-66.95973200000003,82.80081200000006],[-67.13833599999998,82.78387500000008],[-67.31527699999998,82.76470900000004],[-67.386124,82.75776700000011],[-67.45777899999996,82.75221299999993],[-67.49999999999994,82.74961100000013],[-67.597778,82.74359099999992],[-67.64472999999992,82.74165299999999],[-67.79916400000002,82.73165899999998],[-67.91416899999996,82.71998600000012],[-68.041382,82.7038730000001],[-68.08167999999995,82.70082100000002],[-68.13417099999998,82.69859300000002],[-68.23472600000002,82.69664000000012],[-68.27610800000002,82.69470199999995],[-68.35665899999998,82.68803400000002],[-68.4244379999999,82.67970300000007],[-68.633621,82.64860500000009],[-68.65583800000002,82.64360000000005],[-68.67222599999997,82.6377720000001],[-68.66722099999998,82.63247700000005],[-68.64250199999998,82.62858599999998],[-68.57362399999994,82.62886000000009],[-68.46501199999994,82.63943500000005],[-68.4244379999999,82.6419370000001],[-68.32583599999998,82.64553799999999],[-67.93499800000001,82.65832499999999],[-67.81277499999999,82.65914900000013],[-67.60665899999992,82.65554800000007],[-67.51806599999986,82.65109300000006],[-67.47084000000001,82.65220599999998],[-67.43055700000002,82.65554800000007],[-67.38194299999998,82.66276600000009],[-67.32806399999998,82.67719999999991],[-67.275284,82.68609600000002],[-67.245834,82.68969700000008],[-67.21083099999993,82.69358799999998],[-66.997772,82.71220399999999],[-66.900284,82.71943700000003],[-66.670837,82.74026500000008],[-66.65722700000003,82.74443099999996],[-66.63833599999998,82.74887100000001],[-66.122772,82.81303400000007],[-66.08667000000003,82.816666],[-65.81027199999994,82.84082000000012],[-65.76777600000003,82.84304800000007],[-65.72416699999991,82.84359700000005],[-65.54666099999992,82.83804300000003],[-65.46777299999985,82.833328],[-65.45472699999999,82.829163],[-65.481674,82.816666],[-65.495834,82.8119200000001],[-65.52722199999994,82.79748499999994],[-65.51806599999998,82.78997800000002],[-65.511124,82.786652],[-65.45861799999989,82.77943399999998],[-65.43083200000001,82.77748100000002],[-65.19749499999995,82.76416000000006],[-65.164444,82.76304600000009],[-65.15472399999999,82.76527400000003],[-65.16749600000003,82.76998900000007],[-65.25917099999992,82.7816620000001],[-65.32749899999999,82.78915400000005],[-65.33972199999994,82.79193099999998],[-65.35305799999998,82.797211],[-65.34445199999999,82.80192600000004],[-65.22193899999996,82.83276400000005],[-65.10278299999993,82.84803799999997],[-65.11000100000001,82.85276799999997],[-65.12805200000003,82.85609400000004],[-65.172775,82.85832199999999],[-65.27278100000001,82.86109900000008],[-65.30749499999996,82.86554000000001],[-65.28916899999996,82.87330600000001],[-65.25805700000001,82.87747200000013],[-65.10472099999998,82.89166300000011],[-64.98222399999997,82.901093],[-64.88473499999992,82.90582300000005],[-64.83555599999994,82.90693700000003],[-64.72972099999993,82.9041600000001],[-64.68472300000002,82.90165700000011],[-64.65556299999997,82.89694200000008],[-64.6641689999999,82.89027399999992],[-64.678604,82.88472000000013],[-64.71389799999992,82.87637299999994],[-64.75195300000001,82.87525900000014],[-64.79055800000003,82.875809],[-64.82972699999993,82.87776200000013],[-64.89028899999994,82.87803600000007],[-64.92250100000001,82.87637299999994],[-64.93693499999995,82.87136800000007],[-64.92361499999998,82.86469999999991],[-64.883896,82.86164900000011],[-64.83999599999999,82.86192300000005],[-64.74638400000003,82.86053500000014],[-64.723053,82.85636900000003],[-64.710556,82.85247800000013],[-64.71389799999992,82.84637500000002],[-64.72277799999995,82.84082000000012],[-64.74221799999992,82.834427],[-64.75083899999993,82.82832300000013],[-64.73777799999999,82.82222000000002],[-64.706955,82.81303400000007],[-64.64805599999994,82.79971300000011],[-64.47860700000001,82.7644350000001],[-64.44526699999994,82.76193200000012],[-64.41805999999991,82.76138299999997],[-64.41278099999994,82.76220699999993],[-64.398056,82.76693699999998],[-64.328888,82.7872010000001],[-64.18638599999997,82.81915300000009],[-64.13999899999999,82.82804900000002],[-64.10305800000003,82.83166500000004],[-64.05972299999996,82.833328],[-63.972770999999966,82.83499100000012],[-63.672775,82.83471700000001],[-63.623610999999926,82.83360300000004],[-63.52972399999999,82.82832300000013],[-63.49083699999994,82.8252720000001],[-63.43472300000002,82.816666],[-63.38916799999993,82.80497700000006],[-63.38249999999999,82.79832500000003],[-63.38221699999991,82.76776100000012],[-63.397223999999994,82.76138299999997],[-63.479163999999855,82.73942599999992],[-63.51028400000001,82.73248300000012],[-63.52583299999998,82.730545],[-63.590836000000024,82.73304700000006],[-63.666106999999954,82.73136899999997],[-63.81944999999996,82.72137499999997],[-63.83499899999998,82.71914700000002],[-63.850280999999995,82.71582000000006],[-63.76445000000001,82.71527100000009],[-63.67888599999992,82.717758],[-63.65166499999998,82.7149960000001],[-63.54000100000002,82.69442700000013],[-63.502040999999906,82.68276200000008],[-63.42222600000002,82.66554300000001],[-63.28694899999999,82.6544340000001],[-63.25444799999997,82.6502690000001],[-63.232215999999994,82.64498900000001],[-63.22610500000002,82.64027399999998],[-63.235557999999855,82.633331],[-63.25583599999999,82.62719700000014],[-63.28722399999998,82.6249850000001],[-63.339721999999995,82.62359600000008],[-63.37638899999996,82.61998000000006],[-63.380829000000006,82.61526500000002],[-63.36944599999998,82.61053499999997],[-63.34749599999998,82.60498000000007],[-63.315001999999936,82.601089],[-63.27222399999994,82.59860200000014],[-63.229720999999984,82.59721400000001],[-63.11361699999992,82.59748799999994],[-63.071113999999966,82.59637500000008],[-63.03361499999994,82.59443699999997],[-62.99639099999996,82.59027100000003],[-62.96416499999998,82.58554100000003],[-62.942496999999946,82.5816650000001],[-62.926109,82.57609600000012],[-62.93055700000002,82.56999200000007],[-62.960556,82.55775499999993],[-63.059440999999936,82.511932],[-63.08943899999997,82.46638500000012],[-63.1199949999999,82.46360800000002],[-63.243889000000024,82.45776400000005],[-63.285004000000015,82.45498700000013],[-63.346106999999904,82.44914200000005],[-63.36611199999999,82.44497700000005],[-63.36999500000002,82.438873],[-63.32861300000002,82.43775900000003],[-63.27722199999994,82.43914800000005],[-63.148888,82.44692999999995],[-63.07167099999998,82.45193500000005],[-63.01583899999997,82.45971699999996],[-62.990836999999885,82.46720900000008],[-62.92083699999995,82.4910890000001],[-62.823616000000015,82.50444000000005],[-62.678337,82.51609800000006],[-62.55332899999996,82.524429],[-62.50666799999988,82.52665700000011],[-62.28694899999999,82.52804600000013],[-62.24500299999994,82.52804600000013],[-62.17166900000001,82.52554299999997],[-62.17138699999998,82.52137800000014],[-62.322776999999974,82.51110800000004],[-62.33306099999999,82.50416600000011],[-62.353057999999976,82.48637400000007],[-62.35278299999993,82.48109399999998],[-62.300835000000006,82.482483],[-62.264449999999954,82.48580900000002],[-62.21566799999988,82.49192800000009],[-62.21249799999987,82.495766],[-62.098052999999936,82.50221299999998],[-61.88417099999998,82.49275200000005],[-61.691666,82.48803700000002],[-61.58250399999997,82.482483],[-61.53082999999987,82.47831700000012],[-61.5,82.47415200000012],[-61.44860799999998,82.46443199999999],[-61.32611099999997,82.43969700000014],[-61.28556100000003,82.43026700000007],[-61.17027999999988,82.39526400000011],[-61.14111300000002,82.38304100000005],[-61.13138599999991,82.37747200000007],[-61.11222099999992,82.36387600000006],[-61.09860999999995,82.35026600000003],[-61.076392999999996,82.32083100000011],[-61.07861300000002,82.30108600000011],[-61.084723999999994,82.29359399999998],[-61.107779999999934,82.26776100000006],[-61.130359999999996,82.25293700000009],[-61.135558999999944,82.2474820000001],[-61.15694400000001,82.23525999999998],[-61.19332899999995,82.22360200000008],[-61.28111299999995,82.20277400000003],[-61.306389000000024,82.19720500000005],[-61.38805400000001,82.18331900000004],[-61.43332700000002,82.17637600000006],[-61.46361499999989,82.172485],[-61.5341719999999,82.16554300000007],[-61.599441999999954,82.16081200000013],[-61.80444299999999,82.14665200000007],[-61.86999499999996,82.10664400000002],[-61.885001999999986,82.10053999999997],[-62.07778199999996,82.05358899999999],[-62.12694499999998,82.04386900000009],[-62.25417299999998,82.01998900000007],[-62.278885,82.01582299999995],[-62.31305699999996,82.01249700000011],[-62.35694899999993,82.010269],[-62.51361800000001,82.00471500000015],[-62.57028199999996,81.97608900000006],[-62.94499999999999,81.92221100000012],[-63.040557999999976,81.90971400000012],[-63.2925029999999,81.87776199999996],[-63.38722199999995,81.86775200000005],[-63.65610499999997,81.8374940000001],[-63.715003999999965,81.82083100000006],[-63.761116000000015,81.811646],[-63.81722300000001,81.80470300000002],[-63.849723999999924,81.80108600000005],[-63.925003000000004,81.7952580000001],[-63.96277599999996,81.79248000000013],[-64.01000999999997,81.79026800000008],[-64.05305499999992,81.78997800000002],[-64.08694500000001,81.79193099999998],[-64.11166399999996,81.79498300000012],[-64.13166799999999,81.799149],[-64.14222699999993,81.80304000000007],[-64.17777999999998,81.81053200000002],[-64.20750399999997,81.81442300000009],[-64.27166699999992,81.82165500000002],[-64.30139200000002,81.82415799999995],[-64.325287,81.8247070000001],[-64.323624,81.81915300000009],[-64.308044,81.81469700000002],[-64.25306699999999,81.8060910000001],[-64.23277299999995,81.80053700000008],[-64.12388599999997,81.768326],[-64.11805700000002,81.7644350000001],[-64.13473499999992,81.75471500000003],[-64.20777900000002,81.74192800000003],[-64.35526999999996,81.72637900000012],[-64.47250399999996,81.72137499999997],[-64.62943999999993,81.72248800000006],[-64.72000100000002,81.72387700000007],[-64.76777600000003,81.72581500000001],[-64.80166599999995,81.72831700000006],[-64.81221,81.73082000000005],[-64.83389299999993,81.73887600000012],[-64.83972199999994,81.74220300000007],[-64.885559,81.75082399999997],[-64.91000400000001,81.7527770000001],[-64.96221899999995,81.75221299999998],[-65.21665999999999,81.74552900000009],[-65.33750899999995,81.73776199999998],[-65.40972899999991,81.72831700000006],[-65.63137799999993,81.70248400000014],[-65.66833499999996,81.70082100000002],[-65.72555499999993,81.70166],[-65.77333099999998,81.70277399999998],[-65.92443799999995,81.70138500000013],[-66.01222199999995,81.69693000000012],[-66.03860500000002,81.692474],[-66.04222099999998,81.69053600000007],[-66.03028899999993,81.6849820000001],[-65.991379,81.68275500000004],[-65.82194499999997,81.68441799999994],[-65.612503,81.6808170000001],[-65.48777799999993,81.68748500000004],[-65.40417500000001,81.69081100000011],[-65.35249299999987,81.69192500000008],[-65.33667000000003,81.68803400000002],[-65.37083399999995,81.67886399999998],[-65.402222,81.67442300000005],[-65.52362099999999,81.65971400000001],[-65.61805699999991,81.64860500000009],[-65.78944399999995,81.63220200000006],[-65.87165799999991,81.62719700000002],[-65.910278,81.62969999999996],[-65.92639199999996,81.63415499999996],[-65.92721599999993,81.63554399999998],[-65.92443799999995,81.63970899999998],[-65.92721599999993,81.645828],[-65.94332899999989,81.65054300000003],[-65.98222399999992,81.65277100000003],[-66.02471899999995,81.65304600000002],[-66.04277000000002,81.651657],[-66.06471299999998,81.64776599999993],[-66.085556,81.64276100000006],[-66.10194399999995,81.6372070000001],[-66.14083899999997,81.62052900000003],[-66.17250100000001,81.61804200000012],[-66.21888699999994,81.61692800000014],[-66.35527000000002,81.61747700000012],[-66.39388999999994,81.61970500000007],[-66.43971299999998,81.62692300000009],[-66.47833300000002,81.62858599999998],[-66.57556199999993,81.626083],[-66.72749299999992,81.6202550000001],[-66.80499299999985,81.615814],[-66.89639299999993,81.6119230000001],[-67.15695199999999,81.60803200000004],[-67.50917099999992,81.60054000000008],[-67.55972300000002,81.599152],[-67.766663,81.59304799999995],[-67.79277000000002,81.58970600000004],[-68.11138900000003,81.56303400000013],[-68.15666199999998,81.56109600000002],[-68.23138399999999,81.56137100000001],[-68.27471899999995,81.56275900000009],[-68.30943300000001,81.56553600000001],[-68.33056599999992,81.56860400000005],[-68.35249299999998,81.57304400000004],[-68.41027799999989,81.58804300000008],[-68.45973199999997,81.597488],[-68.66139199999998,81.633331],[-68.71528599999999,81.64221199999997],[-68.976944,81.68441799999994],[-69.05888399999992,81.6974790000001],[-69.13999899999999,81.70887799999997],[-69.17639200000002,81.71249400000005],[-69.24722299999996,81.71748400000007],[-69.291382,81.71887199999998],[-69.29943800000001,81.71720900000008],[-69.30665599999998,81.71443199999999],[-69.291382,81.707764],[-69.26806599999998,81.70248400000014],[-69.21417200000002,81.6952510000001],[-69.12361099999998,81.68386800000013],[-69.00527999999991,81.66748000000007],[-68.902222,81.65138200000001],[-68.62471,81.60443099999998],[-68.44915800000001,81.57083100000006],[-68.37083399999989,81.55358900000004],[-68.35777299999995,81.54832500000009],[-68.35249299999998,81.54165600000005],[-68.37332200000003,81.53776600000003],[-68.40750099999997,81.53387499999997],[-68.50445599999995,81.53221100000013],[-68.55139199999996,81.532761],[-68.63751200000002,81.53553800000009],[-68.71528599999999,81.53970300000009],[-68.81082199999992,81.54859900000002],[-68.84889199999998,81.54914900000006],[-68.85694899999999,81.54776000000004],[-68.851944,81.54165600000005],[-68.83917200000002,81.536926],[-68.81304899999998,81.5333250000001],[-68.77749599999993,81.52970900000008],[-68.57945299999989,81.51443499999999],[-68.53666699999997,81.51332100000002],[-68.44665499999996,81.51748700000007],[-68.37609899999995,81.52276600000005],[-68.28582799999992,81.52693199999999],[-68.091949,81.5291600000001],[-68.05110199999996,81.53054800000001],[-68.01112399999994,81.533051],[-67.91000399999996,81.54220600000008],[-67.81973299999987,81.54693600000007],[-67.724716,81.55108600000011],[-67.38365199999998,81.56088299999999],[-67.18249500000002,81.56469700000008],[-67.15028399999994,81.56498700000009],[-67.10777300000001,81.56498700000009],[-67.06471299999998,81.56275900000009],[-66.85972600000002,81.54664600000007],[-66.79138199999989,81.54081700000006],[-66.76611299999996,81.53749100000005],[-66.62999000000002,81.51805100000001],[-66.608612,81.51277200000004],[-66.62388599999997,81.50637800000004],[-66.741104,81.49192800000009],[-66.887787,81.48054500000006],[-66.96278399999994,81.4749910000001],[-67.04333499999996,81.46971100000002],[-67.24833699999999,81.44999700000011],[-67.45750399999997,81.42303500000003],[-67.7538909999999,81.39166300000005],[-67.81834400000002,81.385269],[-67.99471999999997,81.368042],[-68.24472000000003,81.33998100000008],[-68.35583500000001,81.32388300000008],[-68.429169,81.31164600000011],[-68.48693800000001,81.30386399999998],[-68.61805700000002,81.29054300000001],[-68.79695100000004,81.2752690000001],[-69.02860999999996,81.25860600000004],[-69.319458,81.26026899999994],[-69.34056099999998,81.26388500000002],[-69.35777300000001,81.26832600000012],[-69.36277799999999,81.26887500000004],[-69.391388,81.27053799999999],[-69.42694099999994,81.26998900000001],[-69.45556599999998,81.26582300000013],[-69.468887,81.259995],[-69.46305799999999,81.25332600000013],[-69.43693499999995,81.24914599999994],[-69.36665299999999,81.24636800000013],[-69.319458,81.24359100000004],[-69.31221,81.24054000000007],[-69.32389799999993,81.23803700000008],[-69.54167199999995,81.21249399999994],[-69.91194199999995,81.18248000000011],[-69.99943499999995,81.17997700000012],[-70.15833999999995,81.18136600000014],[-70.20638999999994,81.17970300000002],[-70.21000700000002,81.17387400000001],[-70.12609899999995,81.16554300000013],[-70.05055199999998,81.16165200000006],[-69.96028100000001,81.16053800000009],[-69.90722700000003,81.16165200000006],[-69.864441,81.16415400000011],[-69.76000999999997,81.17303500000003],[-69.63806199999999,81.17747500000007],[-69.64750699999996,81.172485],[-69.831955,81.13720699999999],[-69.88778699999995,81.12915000000004],[-69.95306399999998,81.12220800000011],[-69.97694399999995,81.11886600000003],[-70.01306199999993,81.10914600000012],[-70.025284,81.10276799999997],[-70.02333099999998,81.10081500000001],[-69.99526999999995,81.09942600000005],[-69.95556599999998,81.09942600000005],[-69.92222599999997,81.10220300000015],[-69.83222999999998,81.11164900000011],[-69.63249200000001,81.13916000000012],[-69.60972600000002,81.14387499999998],[-69.59167500000001,81.14888000000002],[-69.54167199999995,81.16442899999993],[-69.52833599999991,81.16943400000002],[-69.46333300000003,81.18304400000005],[-69.43055699999996,81.18719499999997],[-69.35943600000002,81.19331399999999],[-68.87609900000001,81.2310940000001],[-68.76083399999993,81.23942600000004],[-68.37388599999997,81.266663],[-68.24694799999997,81.2727660000001],[-68.11665299999993,81.28027300000008],[-68.05277999999998,81.28610200000008],[-67.88722199999995,81.30304000000001],[-67.82362399999994,81.31025700000009],[-67.79110700000001,81.31553600000007],[-67.69082600000002,81.32943700000004],[-67.59306299999997,81.34027100000009],[-67.35665899999998,81.36360199999996],[-67.24749799999995,81.37191800000005],[-67.1241609999999,81.37970000000001],[-66.99055499999992,81.38554400000004],[-66.62138399999998,81.41387900000007],[-66.36582899999996,81.434708],[-66.29028299999999,81.44026200000002],[-66.16972399999986,81.44775400000015],[-66.13417099999992,81.45082100000008],[-66.05082700000003,81.45915200000013],[-65.98554999999999,81.46804800000007],[-65.83167999999995,81.484711],[-65.72471599999994,81.49386600000003],[-65.64361600000001,81.49887100000007],[-65.55749500000002,81.50305200000014],[-65.46640000000002,81.50637800000004],[-65.25279199999994,81.51721200000009],[-65.002792,81.53082300000005],[-64.612503,81.54498299999995],[-64.56639099999995,81.5455320000001],[-64.537781,81.54359399999998],[-64.52806099999992,81.54165600000005],[-64.51750199999998,81.53749100000005],[-64.44415299999997,81.49081400000011],[-64.43638599999991,81.47943100000009],[-64.45111099999997,81.4669340000001],[-64.49194299999999,81.44886800000012],[-64.50862099999995,81.44192499999997],[-64.52084400000001,81.4369200000001],[-64.554169,81.42581200000006],[-64.61665299999993,81.40498400000001],[-64.65888999999999,81.39305099999996],[-64.73527499999994,81.37414600000005],[-64.80860899999993,81.36053500000008],[-64.85583500000001,81.35276800000008],[-64.99499499999996,81.33332800000011],[-65.060272,81.326096],[-65.16805999999997,81.30998200000005],[-65.28639199999998,81.28720100000004],[-65.323624,81.27804600000002],[-65.44137599999993,81.25637800000004],[-65.49305700000002,81.25054900000003],[-65.52778599999999,81.24748199999993],[-65.57167099999998,81.24498000000006],[-65.747772,81.23580900000013],[-65.941101,81.22637900000007],[-65.98055999999991,81.22387700000013],[-66.01028400000001,81.22026100000011],[-66.1997219999999,81.18386800000002],[-66.24444599999987,81.17442299999999],[-66.26444999999995,81.16943400000002],[-66.41833500000001,81.12886000000003],[-66.43804899999998,81.12359600000002],[-66.48277299999995,81.10693400000008],[-66.50418099999996,81.09553499999998],[-66.50944500000003,81.08859300000006],[-66.52972399999999,81.07609600000006],[-66.54472399999997,81.07054099999999],[-66.60333300000002,81.05525200000011],[-66.68582199999997,81.03581200000013],[-66.75334199999998,81.021927],[-66.921112,80.99108900000004],[-67.16444399999995,80.94859300000002],[-67.208618,80.94192500000003],[-67.27917500000001,80.93553200000008],[-67.30915800000002,80.93441800000011],[-67.34944199999995,80.93637100000007],[-67.44082599999996,80.93664600000005],[-67.56221,80.93553200000008],[-67.59138499999995,80.93304400000011],[-67.60665899999992,80.92997700000001],[-67.60360700000001,80.92442299999999],[-67.58833300000003,80.91387899999995],[-67.56777999999997,80.90859999999998],[-67.54333500000001,80.90415999999999],[-67.53083799999996,80.89749100000012],[-67.53999299999998,80.89109800000011],[-67.583618,80.87664800000005],[-67.63444500000003,80.86080900000007],[-67.65360999999996,80.85636900000009],[-67.86389199999996,80.83415200000002],[-67.910278,80.8119200000001],[-67.96583599999991,80.797485],[-68.01139799999999,80.78831500000013],[-68.06555200000003,80.7791600000001],[-68.089447,80.776093],[-68.13833599999998,80.772491],[-68.20278899999994,80.76582300000007],[-68.22528099999994,80.76138300000002],[-68.6725009999999,80.66693099999992],[-68.73889199999991,80.64721700000001],[-68.81471299999998,80.62858600000004],[-68.95249899999988,80.60304300000007],[-69.14666699999992,80.52970900000008],[-69.171112,80.51748700000013],[-69.273056,80.46388200000001],[-69.28916899999996,80.45166000000006],[-69.291382,80.44413800000012],[-69.29055800000003,80.43719499999992],[-69.29777499999994,80.42469800000015],[-69.30555700000002,80.41832],[-69.31750499999998,80.41249099999999],[-69.33389299999993,80.40664700000013],[-69.38473499999992,80.39193700000004],[-69.42748999999998,80.38275100000004],[-69.47972099999998,80.37553400000013],[-69.55110200000001,80.36637900000011],[-69.59638999999987,80.36109900000002],[-69.72972099999993,80.35276799999997],[-69.9827729999999,80.344986],[-70.07278399999996,80.34443700000003],[-70.21888699999994,80.34637499999997],[-70.2844389999999,80.35108900000012],[-70.30526699999996,80.35609399999998],[-70.31082199999997,80.36303700000013],[-70.28582799999998,80.37248200000005],[-70.256393,80.38136299999996],[-70.24415599999992,80.38665800000001],[-70.22778299999999,80.40138200000007],[-70.22000100000002,80.41693099999998],[-70.2350009999999,80.42970300000002],[-70.27528399999994,80.44802900000002],[-70.31416300000001,80.46443200000004],[-70.49943499999995,80.51388499999996],[-70.53999299999992,80.52192700000012],[-70.68110699999994,80.54803500000008],[-70.70611600000001,80.55247500000013],[-70.75473,80.55941800000011],[-70.78306599999996,80.56303400000013],[-70.81249999999989,80.56275900000014],[-70.82528699999989,80.55859399999997],[-70.82749899999993,80.55137600000012],[-70.81304899999992,80.544983],[-70.796112,80.54054300000013],[-70.765289,80.53442400000012],[-70.74166899999994,80.53137200000003],[-70.670837,80.51805100000007],[-70.63778699999995,80.50915500000013],[-70.531387,80.47442600000005],[-70.49055499999992,80.46081500000008],[-70.47666900000002,80.45443699999998],[-70.42332499999998,80.42164600000001],[-70.43472299999996,80.39166300000011],[-70.45056199999999,80.38581799999997],[-70.45889299999999,80.38136299999996],[-70.47222899999991,80.368042],[-70.47138999999999,80.36248800000004],[-70.46916199999998,80.35498000000001],[-70.462219,80.34693900000013],[-70.44415300000003,80.34027100000014],[-70.42416400000002,80.33610500000003],[-70.35249299999992,80.32470700000005],[-70.30999800000001,80.31805400000007],[-70.25279199999994,80.31330900000006],[-70.15055799999999,80.29914900000011],[-70.035278,80.27832000000012],[-69.9911039999999,80.2688750000001],[-69.97416699999997,80.26304600000009],[-69.960556,80.2563780000001],[-69.96528599999994,80.2522130000001],[-69.99082899999996,80.24331699999999],[-70.12832600000002,80.19720500000011],[-70.145554,80.19358799999998],[-70.178604,80.1891480000001],[-70.21665999999999,80.18637100000001],[-70.24888599999997,80.18609600000002],[-70.31500199999988,80.18748499999998],[-70.61138899999997,80.19720500000011],[-70.645554,80.19914200000011],[-70.821121,80.19552600000009],[-71.12083399999995,80.17248500000005],[-71.18055699999991,80.16665600000005],[-71.23832699999991,80.15887499999997],[-71.38194299999998,80.13916],[-71.41861,80.13108800000003],[-71.44610599999993,80.12136800000013],[-71.46305799999993,80.11804200000006],[-71.50111400000003,80.11554000000001],[-71.65444899999994,80.11137400000007],[-71.69444299999998,80.11080900000007],[-71.73194899999993,80.11192300000005],[-71.762787,80.11442600000004],[-71.78999299999998,80.11775200000005],[-71.8116609999999,80.12359600000008],[-71.83612099999999,80.13192700000013],[-71.848053,80.14387500000004],[-71.87860099999995,80.16249100000005],[-71.90777600000001,80.17137100000008],[-71.95333900000003,80.180542],[-72.006393,80.18858300000011],[-72.05722000000003,80.19470200000012],[-72.08111600000001,80.19413800000001],[-72.09999099999987,80.19274899999999],[-72.12777699999992,80.18775900000014],[-72.16528299999999,80.18887300000011],[-72.18916300000001,80.19220000000001],[-72.22332799999998,80.20166000000012],[-72.241379,80.20748900000012],[-72.25639299999995,80.21388200000007],[-72.27444500000001,80.21971100000007],[-72.29444899999987,80.22331200000013],[-72.32972699999988,80.22554000000008],[-72.35888699999992,80.22608900000006],[-72.37805199999997,80.22470099999998],[-72.39111300000002,80.22164900000001],[-72.40028399999994,80.2185970000001],[-72.420837,80.21110499999998],[-72.41250600000001,80.20721400000008],[-72.18859899999995,80.16387900000012],[-72.14083900000003,80.15693700000003],[-72.08277900000002,80.15165699999994],[-72.05248999999998,80.149719],[-71.99694799999986,80.14305100000007],[-71.97721899999993,80.13943499999999],[-71.89695699999993,80.11554000000001],[-71.89555399999995,80.11415099999999],[-71.898056,80.10859700000003],[-71.90527299999997,80.10359199999994],[-71.92610200000001,80.0999910000001],[-71.95472699999993,80.09637500000002],[-72.11555499999997,80.0874940000001],[-72.25056499999994,80.08554100000015],[-72.39167799999996,80.08554100000015],[-72.39222699999999,80.08194000000009],[-72.358337,80.06498700000003],[-72.34056099999992,80.059143],[-72.30638099999999,80.05748000000006],[-72.17027299999995,80.05386400000003],[-72.137787,80.05358899999999],[-72.05305499999992,80.05748000000006],[-71.92083699999995,80.06637599999999],[-71.88583399999993,80.06721500000015],[-71.8497309999999,80.06776400000012],[-71.70195000000001,80.06414800000005],[-71.61805700000002,80.06442300000009],[-71.48916600000001,80.0688780000001],[-71.37609899999995,80.07693500000005],[-71.31666599999994,80.08194000000009],[-71.18638599999991,80.09387200000003],[-70.96806300000003,80.11499000000015],[-70.85472099999998,80.12831100000011],[-70.821121,80.13108800000003],[-70.76251200000002,80.13333099999994],[-70.65167199999996,80.13136300000002],[-70.62666300000001,80.13053900000006],[-70.50778200000002,80.09971600000006],[-70.50222799999995,80.09304800000007],[-70.49749800000001,80.08276400000005],[-70.48832699999997,80.05720500000007],[-70.49499500000002,80.05081200000012],[-70.50834699999996,80.04775999999998],[-70.56806899999992,80.04275500000011],[-70.59722899999997,80.0394290000001],[-70.64666699999998,80.03193699999997],[-70.662216,80.02665700000006],[-70.67304999999999,80.02082800000005],[-70.67971799999987,80.0144350000001],[-70.67277499999994,80.00637799999998],[-70.67250100000001,80.00138900000002],[-70.68971299999998,79.99331700000005],[-70.71945199999999,79.98637400000001],[-70.76722699999988,79.98165899999998],[-70.91610700000001,79.974426],[-70.95417800000001,79.97276300000004],[-71.08555599999994,79.96859699999999],[-71.241669,79.96081500000003],[-71.27027899999996,79.95721400000014],[-71.40110800000002,79.93553199999991],[-71.41639700000002,79.93026700000007],[-71.45361299999996,79.90637200000003],[-71.46055599999988,79.90138200000001],[-71.45889299999993,79.89498900000007],[-71.43859900000001,79.88998399999997],[-71.4158329999999,79.88665800000012],[-71.394455,79.884995],[-71.35278299999993,79.88693200000006],[-71.33860800000002,79.88859600000006],[-71.16833500000001,79.914154],[-71.10972599999997,79.91526799999997],[-71.06304899999998,79.91165200000012],[-70.94471699999997,79.89415000000008],[-70.92582700000003,79.89027400000003],[-70.910278,79.88581800000009],[-70.91639700000002,79.87942499999997],[-71.00584399999997,79.81971700000008],[-71.11665299999999,79.78970300000009],[-71.13612399999994,79.78498800000006],[-71.18388400000003,79.77748100000008],[-71.212784,79.774429],[-71.34361299999995,79.76388500000013],[-71.37609899999995,79.76081800000003],[-71.400284,79.75749200000001],[-71.44444299999992,79.74165300000004],[-71.46333300000003,79.73692300000005],[-71.49110399999995,79.73332199999999],[-71.69915800000001,79.70999100000012],[-71.73944099999994,79.70721400000002],[-71.781113,79.70610000000005],[-71.81750499999998,79.70359799999994],[-71.92250099999995,79.69552599999997],[-71.99027999999998,79.68914800000005],[-72.09666400000003,79.6749880000001],[-72.21777299999991,79.659988],[-72.26722699999993,79.65914900000001],[-72.28721599999994,79.659988],[-72.31777999999991,79.66720599999996],[-72.33084100000002,79.67248499999994],[-72.34805299999988,79.67804000000007],[-72.36721799999992,79.68165600000009],[-72.39222699999999,79.68359400000003],[-72.425003,79.68553199999997],[-72.46722399999993,79.684708],[-72.57417299999992,79.6791530000001],[-72.61944599999993,79.67776500000002],[-72.66139199999998,79.67719999999997],[-72.69722000000002,79.67804000000007],[-72.72999599999997,79.67970300000013],[-72.75611900000001,79.68220500000007],[-72.91278099999994,79.70220899999998],[-72.93276999999995,79.70637500000004],[-72.94444299999998,79.7102660000001],[-73.06277499999999,79.79942299999999],[-73.06111099999998,79.805252],[-73.04861499999998,79.8083190000001],[-73.02749599999999,79.80693100000002],[-73.01722699999993,79.80470300000002],[-73.00334199999998,79.80304000000012],[-72.97917199999995,79.80220000000008],[-72.945831,79.80415299999999],[-72.92443799999995,79.80636600000014],[-72.912216,79.80941800000005],[-72.90249599999993,79.81526200000008],[-72.92639200000002,79.81944299999998],[-73.05915800000002,79.82554600000009],[-73.09167500000001,79.82638500000007],[-73.1783289999999,79.822769],[-73.21806300000003,79.822769],[-73.28500399999996,79.82609600000012],[-73.34861799999999,79.83027600000014],[-73.37138399999998,79.83305400000012],[-73.39695699999999,79.834991],[-73.43360899999999,79.83581500000014],[-73.57640100000003,79.83276400000011],[-73.66777000000002,79.82971200000003],[-73.74527,79.82832300000001],[-73.78028899999998,79.82777400000009],[-73.8533329999999,79.82916300000005],[-73.86694299999999,79.830826],[-73.86471599999999,79.83581500000014],[-73.85360700000001,79.83970600000004],[-73.80166600000001,79.84637500000008],[-73.74554399999994,79.849152],[-73.74249299999985,79.84999099999993],[-73.74694799999997,79.85415599999993],[-73.7686159999999,79.85887099999997],[-73.89083900000003,79.87525900000003],[-73.94583099999988,79.88165300000009],[-74.01028400000001,79.88581800000009],[-74.11749299999997,79.88888500000002],[-74.15695199999993,79.88888500000002],[-74.23889199999996,79.8872070000001],[-74.28361499999994,79.88136300000008],[-74.30610699999994,79.87692300000003],[-74.383621,79.8685910000001],[-74.41528299999999,79.86526500000002],[-74.57640100000003,79.85693400000014],[-74.66749599999997,79.85359199999999],[-74.79527299999995,79.85081500000013],[-74.83306900000002,79.849152],[-74.84638999999999,79.84721400000006],[-74.84611499999994,79.84387200000009],[-74.71665999999999,79.79693600000007],[-74.69943199999994,79.792755],[-74.68388400000003,79.78997800000008],[-74.65499899999998,79.78887900000012],[-74.48889200000002,79.79165599999999],[-74.44499200000001,79.79470800000013],[-74.39222699999993,79.80026199999992],[-74.35166899999996,79.80247500000007],[-74.30943299999996,79.80331400000006],[-74.23638899999997,79.80192599999992],[-74.10638399999988,79.7955320000001],[-73.95140100000003,79.78442400000012],[-73.71472199999994,79.76638800000012],[-73.51083399999999,79.75637799999998],[-73.38473499999992,79.74887100000007],[-73.36665299999999,79.71804800000007],[-73.36082499999986,79.7127690000001],[-73.295547,79.688583],[-73.25695799999988,79.67804000000007],[-73.20666499999999,79.66360500000013],[-73.18888900000002,79.65803500000004],[-73.17443800000001,79.65165700000006],[-73.16833499999996,79.6461030000001],[-73.1260989999999,79.56944300000004],[-73.12582399999997,79.55831899999998],[-73.12887599999999,79.55415300000004],[-73.13583399999999,79.54971300000005],[-73.14862099999999,79.54359399999998],[-73.16305499999999,79.53887899999995],[-73.18083199999995,79.53414900000013],[-73.24722299999996,79.520828],[-73.29611199999994,79.5127720000001],[-73.35388199999994,79.50582900000012],[-73.44638099999992,79.49914599999994],[-73.65777600000001,79.49636800000013],[-73.69305400000002,79.49693300000001],[-73.729172,79.49859600000008],[-73.75805700000001,79.5002750000001],[-73.77999899999998,79.50305200000003],[-73.79194599999994,79.50665300000009],[-73.81722999999994,79.51554900000002],[-73.837784,79.52748099999997],[-73.86389200000002,79.54026799999997],[-73.87666299999995,79.54470800000001],[-73.91610699999995,79.55247500000013],[-73.95028699999989,79.55525200000005],[-73.965012,79.55470300000007],[-73.98889200000002,79.55192599999998],[-74.00111399999997,79.54582199999999],[-74.00029,79.54165600000005],[-73.99694799999997,79.53553799999992],[-73.98944099999994,79.52859500000011],[-73.96861299999989,79.5169370000001],[-73.95916699999992,79.50888100000003],[-73.94999699999994,79.49386600000008],[-73.94972199999995,79.47998000000007],[-73.95306399999998,79.47276299999999],[-73.96194500000001,79.46693399999998],[-73.98332199999993,79.45555100000013],[-73.99804699999999,79.45138500000007],[-74.02362099999999,79.44693000000007],[-74.08139,79.44053600000001],[-74.11610399999995,79.43803400000013],[-74.160278,79.43637100000001],[-74.19833399999999,79.43609599999996],[-74.54415899999992,79.43803400000013],[-74.61749299999985,79.43858300000005],[-74.67361499999993,79.44413800000012],[-74.6885989999999,79.44693000000007],[-74.93167099999994,79.49887100000012],[-74.93241099999989,79.50479899999999],[-74.94193999999999,79.51054399999998],[-74.96444699999995,79.51304600000003],[-74.987503,79.509995],[-75.04333499999996,79.49581900000004],[-75.06027199999988,79.49081399999994],[-75.05943300000001,79.48387100000014],[-74.99526999999995,79.453598],[-74.98306299999996,79.44970699999993],[-74.94888299999997,79.440811],[-74.91221599999994,79.42970300000002],[-74.89723199999997,79.42330899999996],[-74.88444499999997,79.41609200000005],[-74.8830569999999,79.4083250000001],[-74.91111799999999,79.39387499999998],[-74.93499799999995,79.38526900000005],[-74.95194999999995,79.38026400000001],[-75,79.37548800000008],[-75.016953,79.37414600000005],[-75.058334,79.37387100000007],[-75.21389799999997,79.37637300000011],[-75.31361400000003,79.379974],[-75.410278,79.38415500000008],[-75.531387,79.39248700000007],[-75.69526699999994,79.409988],[-75.79972800000002,79.43136600000014],[-75.90777600000001,79.42608600000005],[-75.93138099999999,79.42359899999997],[-75.95750399999997,79.42608600000005],[-75.985275,79.42970300000002],[-76.031387,79.43830900000012],[-76.04916400000002,79.443039],[-76.09750399999996,79.46192900000011],[-76.10916099999992,79.46775800000012],[-76.11527999999993,79.47248799999994],[-76.12416099999996,79.47637900000001],[-76.13861099999991,79.48136900000009],[-76.17582700000003,79.488876],[-76.203888,79.49247700000006],[-76.261124,79.49775699999998],[-76.3202819999999,79.50138900000007],[-76.636124,79.51944000000009],[-76.66528299999999,79.520828],[-76.71833800000002,79.51998900000001],[-76.79527300000001,79.51138300000008],[-76.83444199999997,79.50888100000003],[-76.872772,79.50860600000004],[-76.90583799999996,79.50972000000002],[-77.05027799999999,79.51860000000005],[-77.06973299999999,79.52388000000008],[-77.09277299999991,79.53970300000015],[-77.112213,79.54525800000005],[-77.14250199999987,79.54748500000005],[-77.16055299999994,79.54359399999998],[-77.19137599999993,79.51110800000009],[-77.18443300000001,79.50360099999995],[-77.178604,79.4997100000001],[-77.13444499999997,79.49026500000002],[-77.07167099999992,79.4869230000001],[-76.895554,79.48054500000012],[-76.86721799999992,79.47970599999996],[-76.612503,79.4747010000001],[-76.406387,79.47360200000014],[-76.20472699999999,79.46138000000013],[-76.17916899999989,79.45971700000007],[-76.15943899999996,79.4563750000001],[-76.14334100000002,79.44999699999994],[-76.13806199999993,79.44331399999999],[-76.13890100000003,79.44108600000004],[-76.14999399999999,79.43775900000009],[-76.15916400000003,79.43609599999996],[-76.18998699999997,79.4333190000001],[-76.208054,79.42970300000002],[-76.20556599999998,79.42469800000015],[-76.16749600000003,79.39610299999993],[-76.15750100000002,79.39166300000011],[-76.11721799999998,79.38443000000012],[-76.083328,79.37886000000003],[-76.05915799999997,79.37498500000004],[-75.902222,79.35720799999996],[-75.88194299999998,79.35331700000012],[-75.879166,79.35137899999995],[-75.88999899999988,79.34803799999992],[-75.90278599999988,79.34609999999998],[-76.08667000000003,79.33221400000002],[-76.12332200000003,79.33110000000005],[-76.35110499999996,79.3419340000001],[-76.68277,79.35276799999997],[-76.71777299999991,79.35331700000012],[-76.79055799999998,79.35331700000012],[-76.82917800000001,79.35081500000001],[-76.86971999999997,79.34942600000005],[-76.89416499999993,79.35331700000012],[-76.95944199999997,79.36720300000007],[-77.01889,79.38192700000013],[-77.07640100000003,79.3983310000001],[-77.09028599999994,79.40554800000001],[-77.10555999999991,79.41609200000005],[-77.108337,79.4208220000001],[-77.21250900000001,79.44775400000003],[-77.32640099999998,79.45416300000005],[-77.35916099999992,79.45555100000013],[-77.38612399999994,79.45277400000003],[-77.39750700000002,79.44720500000005],[-77.39500399999997,79.44026200000008],[-77.38444500000003,79.43304400000005],[-77.26222199999995,79.37248200000005],[-77.17250099999995,79.33638000000008],[-77.158615,79.329163],[-77.16389499999997,79.32470700000005],[-77.18777499999999,79.32276900000011],[-77.22805800000003,79.32165500000013],[-77.260559,79.32276900000011],[-77.31722999999994,79.32777399999998],[-77.36721799999998,79.33610500000009],[-77.38639799999999,79.33859300000006],[-77.41361999999998,79.34165999999999],[-77.46611000000001,79.34609999999998],[-77.47778299999993,79.34609999999998],[-77.59611499999994,79.34582499999999],[-77.63417099999992,79.34553499999998],[-77.70750399999997,79.34332300000005],[-77.73999000000003,79.34443700000008],[-77.76972999999998,79.34637500000002],[-77.81973299999999,79.351654],[-77.90527299999991,79.36526500000014],[-77.92250100000001,79.36637900000011],[-77.95722999999998,79.36387600000012],[-78.05139199999996,79.35470600000008],[-78.05888399999998,79.34942600000005],[-78.04361,79.34443700000008],[-78.02139299999993,79.33998099999997],[-77.90333599999997,79.322495],[-77.87609900000001,79.31971700000003],[-77.846115,79.31776400000007],[-77.80999800000001,79.316666],[-77.76000999999997,79.31637599999999],[-77.726944,79.31749000000013],[-77.65083300000003,79.31776400000007],[-77.62443499999995,79.31553600000012],[-77.52917500000001,79.30525200000011],[-77.47860700000001,79.29664600000001],[-77.32223499999998,79.26748700000002],[-77.32917800000001,79.26138300000014],[-77.34138499999995,79.25943000000001],[-77.35804699999994,79.25776700000011],[-77.42222600000002,79.25471499999998],[-77.45306399999998,79.25248700000003],[-77.48222399999997,79.24887100000001],[-77.49694799999992,79.24581900000004],[-77.48805199999998,79.24498000000011],[-77.424713,79.24609400000008],[-77.35833699999995,79.24999999999994],[-77.19193999999999,79.26388500000007],[-76.99972500000001,79.27331500000014],[-76.67138699999992,79.27748100000002],[-76.23777799999993,79.27110300000004],[-76.16805999999997,79.26998900000007],[-76.136124,79.2686000000001],[-76.10583499999996,79.26582300000001],[-76.06861900000001,79.25749200000007],[-76.05277999999998,79.25109900000012],[-76.03443900000002,79.24581900000004],[-75.99194299999999,79.23637400000001],[-75.93888900000002,79.23027000000013],[-75.80749500000002,79.22776800000008],[-75.77722199999994,79.22747800000008],[-75.73443600000002,79.22943100000003],[-75.67527799999999,79.23637400000001],[-75.63778699999995,79.2394260000001],[-75.60833699999995,79.23997500000007],[-75.465012,79.23997500000007],[-75.4058379999999,79.23748799999998],[-75.08306899999997,79.23526000000004],[-74.87609900000001,79.23803700000013],[-74.80027799999999,79.24054000000007],[-74.777222,79.24026500000008],[-74.52555799999999,79.22720300000003],[-74.49694799999997,79.22499099999999],[-74.47084000000001,79.22164900000007],[-74.464722,79.21998600000012],[-74.46722399999999,79.21554600000013],[-74.47416699999997,79.211929],[-74.52027900000002,79.20304899999996],[-74.57194499999991,79.19609100000014],[-74.601944,79.19274899999999],[-74.75805700000001,79.18553200000008],[-74.791946,79.18275499999999],[-74.81750499999993,79.17886400000009],[-74.82695000000001,79.17414900000006],[-74.81916799999993,79.16775500000006],[-74.795547,79.16360500000002],[-74.76695299999994,79.16137700000007],[-74.67250100000001,79.15693700000003],[-74.61749299999985,79.15138199999996],[-74.44583099999994,79.065811],[-74.43666100000002,79.0577550000001],[-74.44305399999996,79.04693600000007],[-74.45527600000003,79.04165599999999],[-74.47193900000002,79.036652],[-74.51445000000001,79.02859500000005],[-74.54388399999999,79.02526900000004],[-74.57833900000003,79.02331499999997],[-74.65417500000001,79.02221700000007],[-74.72500599999995,79.02276600000005],[-74.96000700000002,79.02832000000001],[-75.116104,79.03581200000013],[-75.24305700000002,79.043045],[-75.62666299999995,79.06608600000004],[-75.65556300000003,79.06832899999995],[-75.76333599999998,79.08055100000013],[-75.88528400000001,79.09748800000011],[-75.89138799999995,79.10220300000015],[-75.88722199999995,79.12831100000011],[-75.880829,79.134995],[-75.85665899999998,79.13970899999993],[-75.84861799999999,79.14498900000001],[-75.85777299999995,79.15220599999992],[-75.94444299999992,79.17303500000008],[-76.04777499999994,79.19220000000007],[-76.07167099999992,79.19609100000014],[-76.098053,79.199142],[-76.132767,79.19970699999999],[-76.30943300000001,79.19081100000005],[-76.51916499999999,79.19026200000013],[-76.85916099999997,79.18525700000009],[-76.97332799999992,79.18331899999993],[-77.04499800000002,79.18331899999993],[-77.08306900000002,79.18359399999997],[-77.11166399999996,79.18498200000005],[-77.16749600000003,79.18997200000013],[-77.20500199999998,79.1952510000001],[-77.250565,79.19802900000008],[-77.38890100000003,79.19970699999999],[-77.51083399999999,79.194977],[-77.54804999999993,79.19442700000013],[-77.64250199999992,79.19970699999999],[-77.695267,79.20471200000003],[-77.74999999999989,79.20832800000011],[-77.77749599999993,79.20887800000014],[-77.81750499999998,79.207764],[-78.15888999999999,79.18997200000013],[-78.21362299999998,79.18359399999997],[-78.23332199999999,79.17886400000009],[-78.24583399999995,79.17469800000003],[-78.25389100000001,79.169983],[-78.25306699999999,79.16442899999998],[-78.22860700000001,79.16053800000009],[-78.181671,79.15942400000012],[-78.08473200000003,79.16804500000006],[-78.056107,79.17192100000011],[-78.02639799999997,79.17469800000003],[-77.98889200000002,79.17747500000013],[-77.912216,79.17942800000003],[-77.84277299999997,79.1785890000001],[-77.47193900000002,79.16775500000006],[-77.23777799999999,79.15693700000003],[-77.20861799999994,79.15470900000008],[-77.181107,79.15386999999993],[-77.01861599999995,79.15359500000011],[-76.841949,79.15359500000011],[-76.70611599999995,79.15304599999996],[-76.63999899999999,79.15109300000006],[-76.61082499999992,79.14915500000012],[-76.48472599999997,79.13610800000009],[-76.43055700000002,79.132202],[-76.31973299999993,79.12469500000009],[-76.26000999999991,79.121918],[-76.23361199999994,79.12164299999995],[-76.19137599999993,79.12359600000008],[-76.15972899999997,79.122208],[-76.13667299999997,79.11914100000007],[-76.081955,79.09971600000011],[-76.0850069999999,79.09332300000011],[-76.09999099999987,79.08776899999998],[-76.11665299999993,79.08332800000005],[-76.14666699999998,79.07777400000003],[-76.17054699999989,79.07582100000008],[-76.21000699999996,79.0747070000001],[-76.26501499999995,79.07443200000012],[-76.36000100000001,79.07832300000001],[-76.515015,79.08581500000008],[-76.57556199999999,79.08943200000004],[-76.63722200000001,79.09054600000002],[-76.67639199999996,79.08943200000004],[-76.82833900000003,79.08276400000011],[-76.99638399999998,79.0747070000001],[-77.07333399999993,79.07083100000006],[-77.15278599999999,79.06608600000004],[-77.223053,79.06053200000002],[-77.32695000000001,79.0516510000001],[-77.35555999999997,79.04832500000003],[-77.42971799999992,79.03720099999998],[-77.44943199999994,79.03276099999994],[-77.464722,79.02777100000009],[-77.49499499999996,79.01776100000001],[-77.52917500000001,79.01805100000001],[-77.69305400000002,79.03360000000009],[-77.71972700000003,79.036652],[-77.74221799999992,79.04193099999998],[-77.78306600000002,79.06248499999998],[-77.79998799999993,79.06666600000005],[-77.84973100000002,79.06971700000008],[-77.91972399999992,79.0688780000001],[-78.03500400000001,79.06553600000001],[-78.10333300000002,79.06608600000004],[-78.13500999999997,79.06749000000002],[-78.16528299999993,79.06999200000007],[-78.214447,79.07527199999998],[-78.23416099999986,79.07832300000001],[-78.28999299999998,79.08332800000005],[-78.35110500000002,79.08638000000013],[-78.42527799999999,79.08305400000012],[-78.67138699999998,79.07193000000001],[-78.81834399999997,79.06944299999998],[-78.86000099999995,79.06721499999998],[-78.89138799999989,79.06330900000012],[-78.87943999999993,79.06025699999998],[-78.69248999999996,79.05859400000008],[-78.58833299999998,79.059143],[-78.40527299999997,79.06498700000003],[-78.28388999999999,79.06666600000005],[-78.23638899999997,79.06498700000003],[-78.15972899999997,79.05108600000005],[-78.108337,79.04664600000001],[-78.07055700000001,79.04664600000001],[-77.96611000000001,79.049149],[-77.86111499999987,79.049149],[-77.829453,79.04803500000003],[-77.7994379999999,79.0452580000001],[-77.785553,79.04109200000005],[-77.70834400000001,79.01304600000014],[-77.70333900000003,79.00694300000004],[-77.71665999999999,79.00332600000007],[-77.79611199999994,78.98858600000011],[-77.83500700000002,78.97943100000003],[-77.94694500000003,78.95166],[-77.94638099999992,78.94581599999998],[-77.95249899999993,78.93969700000014],[-78.04028299999999,78.90609700000005],[-78.14750699999996,78.86526500000008],[-78.28222700000003,78.80386400000009],[-78.28999299999998,78.79914900000006],[-78.29722600000002,78.78887900000012],[-78.29611199999994,78.783051],[-78.285553,78.77581800000002],[-78.26945499999994,78.77249100000006],[-78.24804699999993,78.770264],[-78.21556099999992,78.77053799999993],[-78.19610599999993,78.77221700000013],[-78.16833499999996,78.78082300000005],[-78.15972899999997,78.78498800000006],[-78.15943900000002,78.78997800000013],[-78.14584399999995,78.80081200000001],[-78.12943999999999,78.81219499999997],[-78.1052699999999,78.82859800000006],[-78.04276999999996,78.861649],[-78.0291749999999,78.86747700000012],[-77.902222,78.91276600000009],[-77.88722200000001,78.91775500000006],[-77.75167799999997,78.95748900000001],[-77.71194499999996,78.96609500000011],[-77.689438,78.96859699999999],[-77.52639799999997,78.97915600000005],[-77.37027,78.98442100000011],[-77.25834699999996,78.98637400000007],[-77.17749000000003,78.98970000000008],[-77.10749799999996,78.99552900000009],[-77.078888,78.99887100000007],[-77.02610799999997,79.00665299999997],[-76.96028100000001,79.01277200000004],[-76.75418099999996,79.02777100000009],[-76.710556,79.02832000000001],[-76.68331899999998,79.02777100000009],[-76.42416399999996,79.022491],[-76.36138900000003,79.01971400000014],[-75.98971599999993,78.99552900000009],[-75.73222399999997,78.96914700000002],[-75.72027600000001,78.96554599999996],[-75.769455,78.93997199999995],[-75.781113,78.934708],[-75.79695100000004,78.92970300000013],[-75.82556199999999,78.926086],[-75.85861199999994,78.92330900000007],[-75.896118,78.92082199999999],[-76.09527600000001,78.91026299999999],[-76.25,78.90220599999998],[-76.28721599999994,78.89971900000012],[-76.31555200000003,78.89610300000004],[-76.335556,78.89166300000005],[-76.37554899999992,78.88275099999998],[-76.415009,78.87387099999995],[-76.44610599999993,78.86387600000006],[-76.45638999999994,78.8577580000001],[-76.46000700000002,78.8519290000001],[-76.4583439999999,78.84498600000012],[-76.44027699999992,78.8394320000001],[-76.41194200000001,78.83720399999999],[-76.39445499999994,78.84082000000001],[-76.39111300000002,78.84387200000015],[-76.37470999999988,78.85108900000006],[-76.34472700000003,78.85887100000002],[-76.33000199999998,78.861649],[-76.231674,78.87914999999998],[-76.20472699999999,78.88108800000009],[-76.17832900000002,78.88026400000012],[-76.15834000000001,78.87914999999998],[-76.133331,78.87664800000005],[-76.07749899999999,78.87303200000002],[-75.97500600000001,78.87275699999998],[-75.79167199999995,78.88415500000002],[-75.46112099999999,78.89137299999999],[-75.316101,78.89221199999997],[-75.29222099999993,78.89027400000003],[-75.18055700000002,78.87914999999998],[-74.964722,78.8560940000001],[-74.77500900000001,78.82998700000007],[-74.760559,78.82360799999998],[-74.75279199999994,78.81694000000005],[-74.71972699999998,78.70748900000007],[-74.72721899999993,78.70138500000002],[-74.75584400000002,78.69802900000002],[-74.823059,78.69747899999999],[-74.84333799999996,78.69303900000011],[-74.86999499999996,78.67581200000012],[-74.86944599999993,78.6685940000001],[-74.85777300000001,78.63610799999998],[-74.81945799999988,78.62747200000007],[-74.78999299999998,78.5913700000001],[-74.862213,78.56721500000009],[-74.87805200000003,78.56248500000004],[-75.02416999999991,78.53193700000008],[-75.04804999999999,78.52804600000002],[-75.07250999999991,78.52777100000003],[-75.079453,78.53387500000002],[-75.10139499999997,78.53776600000009],[-75.13137799999993,78.539154],[-75.16722099999987,78.53970300000015],[-75.200287,78.5374910000001],[-75.21972699999998,78.53305100000006],[-75.235275,78.52804600000002],[-75.26167299999997,78.52331500000008],[-75.29055799999992,78.52053799999999],[-75.479446,78.50999500000006],[-75.83000199999998,78.50471500000015],[-75.88833599999992,78.506104],[-75.96501199999989,78.51081800000009],[-75.98999000000003,78.51388500000002],[-76.03056300000003,78.52110300000004],[-76.07305899999994,78.52970900000014],[-76.09555099999994,78.53360000000004],[-76.12027,78.53665200000012],[-76.15110799999997,78.538589],[-76.40444899999989,78.54803500000014],[-76.43721,78.54859900000008],[-76.46888699999994,78.54553199999998],[-76.64277599999997,78.52832000000012],[-76.68443300000001,78.52221700000001],[-76.691101,78.5188750000001],[-76.69276400000001,78.51470899999998],[-76.693604,78.50972000000002],[-76.6849979999999,78.50582900000012],[-76.66833500000001,78.50387599999999],[-76.64584400000001,78.50277700000004],[-76.53999299999998,78.50332599999996],[-76.46833800000002,78.50526400000012],[-76.36471599999993,78.51332100000008],[-76.32472200000001,78.51527400000003],[-76.289444,78.51554900000002],[-76.26194800000002,78.51361100000008],[-76.24305700000002,78.5122070000001],[-76.12499999999994,78.49414100000013],[-76.11416599999995,78.48831200000012],[-76.11277799999988,78.4810940000001],[-76.10888699999998,78.47499099999999],[-76.10055499999999,78.468323],[-76.08167999999995,78.4644320000001],[-76.05749500000002,78.46192900000011],[-75.761124,78.44386299999996],[-75.61721799999998,78.43803400000013],[-75.49888599999997,78.43304400000005],[-75.443604,78.430542],[-75.41082799999992,78.4266510000001],[-75.26972999999992,78.4041600000001],[-75.08999599999999,78.36886600000003],[-75.031387,78.33137500000004],[-75.03832999999992,78.32554600000003],[-75.05194099999989,78.315811],[-75.0625,78.309708],[-75.08667000000003,78.30636600000008],[-75.18998699999997,78.29971300000011],[-75.22193900000002,78.30026200000003],[-75.24610899999993,78.303314],[-75.27305599999988,78.30554200000012],[-75.30749500000002,78.30554200000012],[-75.35861199999994,78.30165100000005],[-75.37721299999998,78.29664600000001],[-75.38500999999991,78.29136700000004],[-75.39222699999993,78.28526299999999],[-75.39805599999994,78.272491],[-75.479172,78.22221400000012],[-75.49415599999998,78.21720900000008],[-75.51333599999992,78.21276900000004],[-75.58250399999991,78.201096],[-75.61361699999992,78.19802900000008],[-75.65028399999994,78.19693000000012],[-75.67944299999999,78.19831800000003],[-75.77639799999997,78.21054100000009],[-75.90249599999993,78.22415200000006],[-75.98554999999993,78.22997999999995],[-76.15722700000003,78.24054000000012],[-76.18888899999996,78.24108900000004],[-76.22582999999997,78.23997500000007],[-76.291946,78.23442100000005],[-76.32444799999996,78.23275799999999],[-76.36138900000003,78.23165899999998],[-76.39306599999998,78.23220800000013],[-76.47471599999994,78.23942599999992],[-76.5202789999999,78.24552900000009],[-76.54804999999988,78.24832200000009],[-76.57417299999992,78.24971],[-76.60833699999995,78.24941999999999],[-76.63055400000002,78.24775700000004],[-76.83168,78.23082000000005],[-76.85526999999996,78.22747800000008],[-76.88806199999999,78.21804800000001],[-76.89862099999993,78.21249400000005],[-76.912216,78.201096],[-76.90834000000001,78.19552599999992],[-76.88333099999994,78.19192500000008],[-76.68859900000001,78.16886900000003],[-76.664444,78.1660920000001],[-76.64167800000001,78.16442900000004],[-76.53778099999994,78.15832499999999],[-76.02139299999999,78.13804600000003],[-75.76390099999998,78.13165300000009],[-75.73554999999999,78.1308140000001],[-75.62193300000001,78.1244200000001],[-75.59722899999997,78.12081900000004],[-75.58138999999994,78.115814],[-75.57556199999993,78.1077580000001],[-75.575287,78.10137900000007],[-75.58889799999997,78.0894320000001],[-75.59916699999991,78.08332800000005],[-75.69276399999995,78.03997800000008],[-75.70750399999991,78.03498800000006],[-75.723053,78.03082300000005],[-75.761124,78.02249100000006],[-75.80943300000001,78.00833100000011],[-75.83860800000002,77.99832200000009],[-75.922775,77.95665000000008],[-75.96501199999989,77.97303799999992],[-75.98416099999986,77.97747800000013],[-76.15722700000003,78.01249700000005],[-76.214722,78.01527399999992],[-76.24610899999993,78.01582300000007],[-76.27667200000002,78.01277200000004],[-76.30305499999997,78.00943000000012],[-76.44471699999991,77.98858600000011],[-76.466949,77.98471099999995],[-76.48138399999993,77.97970600000008],[-76.49194299999999,77.96859700000005],[-76.49972500000001,77.958328],[-76.52610800000002,77.94914200000005],[-76.54834,77.94497700000005],[-76.59583999999995,77.93969700000014],[-76.66999800000002,77.93637100000012],[-76.69444299999986,77.93719500000009],[-76.73055999999991,77.93609600000008],[-76.75723299999999,77.93331900000004],[-76.78028899999993,77.92997700000006],[-76.80249000000003,77.9202580000001],[-76.80555700000002,77.91720599999996],[-76.80694599999993,77.91304000000008],[-76.825287,77.90832500000005],[-76.86221299999994,77.90277100000003],[-76.93110699999994,77.90138200000007],[-76.95973199999997,77.90248100000002],[-76.98611499999993,77.90470899999997],[-77.03639199999992,77.90971400000001],[-77.07778899999994,77.915817],[-77.08917199999996,77.91970800000007],[-77.09527600000001,77.92719999999997],[-77.104172,77.934418],[-77.12026999999989,77.93914800000005],[-77.1600039999999,77.94609100000002],[-77.21083099999998,77.94914200000005],[-77.24444599999998,77.94859300000007],[-77.27223200000003,77.94636500000013],[-77.29834,77.9427490000001],[-77.33612099999999,77.94081099999994],[-77.83889799999997,77.9427490000001],[-77.99749800000001,77.95721400000002],[-78.03694200000001,77.96638499999995],[-78.14083899999991,77.9852600000001],[-78.162216,77.98831200000001],[-78.23750299999995,77.99581899999998],[-78.26083399999993,77.99525499999999],[-78.41139199999992,77.91775500000011],[-78.420837,77.9124910000001],[-78.42639199999996,77.90637200000009],[-78.41972399999997,77.89888000000013],[-78.41055299999994,77.89221199999997],[-78.33084099999991,77.8685910000001],[-78.31710799999996,77.865814],[-78.28250099999997,77.86276200000009],[-78.2602839999999,77.86137400000001],[-78.17388900000003,77.859985],[-78.13945000000001,77.85720800000013],[-77.97193900000002,77.80720499999995],[-77.95861799999989,77.80220000000008],[-77.947769,77.79637100000008],[-77.94082600000002,77.76554900000002],[-77.94055199999997,77.759995],[-77.98110999999989,77.70138500000007],[-77.92027299999995,77.66998300000012],[-77.882767,77.661652],[-77.86277799999999,77.65637200000015],[-77.74276699999996,77.62220800000011],[-77.724716,77.61331200000001],[-77.71861299999995,77.60582000000005],[-77.72305299999994,77.59915200000006],[-77.73083500000001,77.59721400000012],[-77.87222300000002,77.56832900000012],[-77.952225,77.5558170000001],[-77.95834399999995,77.52970900000014],[-77.94444299999998,77.51138300000014],[-77.94610599999999,77.50471499999998],[-77.94860799999998,77.50193800000011],[-77.981674,77.48637400000001],[-77.99499499999996,77.4810940000001],[-78.25666799999993,77.38192699999996],[-78.303879,77.37330600000007],[-78.69055200000003,77.31553599999995],[-78.741104,77.30941800000005],[-78.777222,77.30720500000007],[-78.80665599999998,77.30720500000007],[-78.83416699999992,77.30831900000004],[-78.839722,77.31025699999998],[-78.83306900000002,77.31498700000003],[-78.78611799999999,77.33581500000008],[-78.73388699999998,77.36276200000003],[-78.726944,77.36747700000006],[-78.725281,77.37109400000003],[-78.72778299999999,77.37525900000003],[-78.76444999999995,77.3808140000001],[-78.7844389999999,77.3808140000001],[-78.816666,77.37803600000012],[-78.84111000000001,77.37442000000004],[-78.86166399999996,77.37025500000004],[-78.89805599999994,77.36080900000007],[-78.92027300000001,77.35081500000007],[-78.93998699999992,77.33888200000001],[-78.94804399999998,77.33248900000007],[-78.95556599999992,77.32832299999995],[-78.96833800000002,77.32331799999992],[-79.00418099999996,77.31387300000006],[-79.083328,77.29998799999998],[-79.139725,77.2935940000001],[-79.17138699999987,77.290817],[-79.20722999999998,77.28831500000013],[-79.270554,77.28692600000011],[-79.32167099999992,77.28858900000006],[-79.37332199999997,77.29304499999995],[-79.49333200000001,77.30442800000014],[-79.63137799999998,77.31666600000005],[-79.653885,77.318604],[-79.71221899999995,77.31832899999995],[-79.83666999999997,77.30693100000013],[-79.86082499999998,77.303314],[-79.88194299999998,77.29971300000011],[-79.896118,77.29582200000004],[-79.92332499999992,77.28526300000004],[-79.96055599999988,77.2769320000001],[-79.98832700000003,77.27360499999998],[-80.01916499999993,77.27221700000007],[-80.04249599999997,77.27276600000005],[-80.45611600000001,77.29609700000009],[-80.75334199999992,77.33055100000013],[-80.77583300000003,77.334427],[-80.87971499999992,77.35304300000001],[-81.00556899999992,77.37719700000014],[-81.015289,77.38136300000002],[-81.019455,77.39276100000006],[-81.027222,77.39804100000009],[-81.03527799999995,77.40109300000006],[-81.09527600000001,77.411926],[-81.12110899999993,77.41360500000002],[-81.15083300000003,77.41360500000002],[-81.2077789999999,77.41581700000006],[-81.25473,77.4205320000001],[-81.27749599999993,77.42442299999999],[-81.29444899999993,77.42915300000004],[-81.31054699999999,77.43498200000005],[-81.316666,77.43887300000011],[-81.321121,77.45027200000004],[-81.325287,77.45498700000007],[-81.33750900000001,77.46276900000004],[-81.35166900000002,77.46971100000007],[-81.37054399999994,77.47554000000014],[-81.38890100000003,77.48082],[-81.44221500000003,77.49136400000003],[-81.53388999999993,77.50694299999998],[-81.57362399999994,77.51277199999998],[-81.58778399999994,77.51748700000002],[-81.589722,77.52082800000005],[-81.608337,77.55358899999999],[-81.61054999999999,77.57609600000006],[-81.82028199999996,77.62191800000011],[-81.83972199999994,77.625809],[-81.84500100000002,77.62886000000003],[-81.84861799999999,77.63943499999993],[-81.847778,77.643326],[-81.83667000000003,77.65498400000007],[-81.8475039999999,77.665817],[-81.86000099999995,77.67137100000002],[-81.87666299999995,77.67747500000007],[-81.89527899999996,77.68248000000011],[-81.91389499999991,77.68553200000002],[-81.92832900000002,77.68580600000013],[-81.93028300000003,77.68498199999999],[-81.93554699999993,77.67804000000007],[-81.94915800000001,77.655258],[-81.94943199999994,77.64498900000012],[-81.91139199999992,77.60942100000011],[-81.89584400000001,77.60415600000005],[-81.85722399999997,77.59887700000007],[-81.81027199999994,77.595261],[-81.79804999999999,77.59165999999999],[-81.78750600000001,77.58749400000005],[-81.67805499999997,77.53831500000007],[-81.67054699999994,77.5316620000001],[-81.66722099999998,77.52526899999998],[-81.666946,77.5022130000001],[-81.67083699999995,77.49609400000008],[-81.69027699999992,77.48526000000004],[-81.710556,77.47499099999999],[-81.71945199999999,77.46998600000012],[-81.74804699999993,77.44802900000008],[-81.743607,77.4410860000001],[-81.739441,77.43637100000007],[-81.728882,77.42997700000001],[-81.70056199999988,77.4227600000001],[-81.52362099999999,77.37803600000012],[-81.48472600000002,77.372208],[-81.43222000000003,77.36804200000006],[-81.33667000000003,77.36859100000004],[-81.25140399999998,77.36914100000007],[-81.203888,77.37052900000015],[-81.18998699999992,77.36804200000006],[-81.17805499999997,77.36025999999993],[-81.172775,77.35470599999996],[-81.16776999999996,77.34275800000012],[-81.16583300000002,77.3372040000001],[-81.16583300000002,77.33276400000005],[-81.16944899999999,77.32249500000006],[-81.28388999999999,77.31526200000002],[-81.425003,77.30636600000008],[-81.53832999999997,77.30276500000008],[-81.87499999999994,77.29248000000013],[-81.95388799999995,77.30220000000003],[-82.09194899999994,77.31637600000005],[-82.15139799999997,77.30386400000003],[-82.16610700000001,77.29248000000013],[-82.08168,77.27276600000005],[-82.04333500000001,77.26554899999991],[-81.978882,77.25833100000011],[-81.90695199999999,77.19831800000003],[-81.90657799999997,77.1933140000001],[-81.902222,77.18719500000003],[-81.87609900000001,77.17469800000009],[-81.86805700000002,77.17164600000012],[-81.83416699999987,77.1624910000001],[-81.79666099999997,77.15748600000006],[-81.78694200000001,77.15748600000006],[-81.71583599999997,77.17692600000004],[-81.69665499999991,77.18136600000003],[-81.63444499999997,77.19386300000002],[-81.60749799999996,77.1974790000001],[-81.39500399999997,77.23165900000004],[-81.14917000000003,77.27470399999999],[-80.96028100000001,77.27137800000014],[-80.59277299999997,77.24247700000001],[-80.52639799999992,77.23498500000005],[-80.28028899999987,77.21360800000002],[-80.258621,77.21220400000004],[-80.20584099999996,77.20942700000012],[-80.15499899999998,77.20803799999993],[-80.13583399999999,77.20582600000006],[-80.116104,77.20138500000013],[-80.11471599999999,77.19552599999997],[-80.13694799999996,77.18609600000008],[-80.15278599999999,77.18165600000003],[-80.25500499999998,77.15332000000012],[-80.40167199999996,77.08665500000001],[-80.40972899999997,77.0811000000001],[-80.40972899999997,77.07666000000012],[-80.39445499999994,77.07276900000005],[-80.37304699999993,77.07138099999992],[-80.34584000000001,77.074997],[-80.32806399999993,77.07832300000001],[-80.20695499999994,77.10859700000009],[-80.15943899999996,77.12275699999998],[-80.13500999999997,77.13943500000005],[-80.118607,77.15081800000007],[-80.09472699999998,77.16110200000008],[-80.07250999999991,77.17053199999998],[-80.01333599999992,77.19053600000007],[-79.93582200000003,77.20665000000002],[-79.785278,77.23136899999997],[-79.72582999999992,77.23997500000007],[-79.66027799999995,77.24443100000002],[-79.63305700000001,77.24331700000005],[-79.44554099999999,77.23442100000011],[-79.4241639999999,77.23304700000011],[-79.25500499999998,77.21859699999999],[-79.216949,77.20971700000013],[-79.04194599999988,77.16110200000008],[-79.03306600000002,77.15664700000008],[-79.02806099999998,77.15054300000003],[-79.00389099999995,77.10359200000005],[-79.00500499999993,77.09693900000002],[-79.01333599999992,77.09137000000004],[-79.02972399999999,77.08692900000011],[-79.13249200000001,77.05358900000004],[-79.328888,76.97859199999994],[-79.36555499999992,76.96331800000007],[-79.37666300000001,76.95748900000007],[-79.39138799999995,76.947205],[-79.39500399999991,76.94053600000012],[-79.39306599999998,76.934143],[-79.38694800000002,76.92747500000002],[-79.37222300000002,76.92330900000013],[-79.34584000000001,76.91804500000012],[-79.31750499999993,76.91775500000011],[-79.24444599999993,76.92498799999993],[-79.1930539999999,76.92915299999993],[-79.00584399999991,76.93609600000013],[-78.98083500000001,76.93637100000012],[-78.95417800000001,76.93525699999998],[-78.886124,76.9269260000001],[-78.870834,76.92221100000006],[-78.86639400000001,76.91886900000009],[-78.91000400000001,76.88665800000001],[-78.91528299999999,76.83970600000009],[-78.74833699999994,76.82249499999995],[-78.72193899999996,76.82138099999997],[-78.71221899999995,76.82331800000003],[-78.70805399999995,76.82499700000005],[-78.56361400000003,76.90664700000013],[-78.566101,76.91360500000013],[-78.56750499999998,76.92720000000003],[-78.56277499999987,76.933044],[-78.55387899999994,76.938583],[-78.547775,76.94136000000009],[-78.38444499999991,76.99971000000005],[-78.34416199999993,77.007767],[-78.32028200000002,77.01165800000007],[-78.29277000000002,77.0147090000001],[-78.19694499999997,77.01944000000003],[-78.14083899999991,77.01998900000001],[-78.087219,77.01776100000001],[-78.07028200000002,77.01443499999999],[-77.89666699999998,76.95555100000013],[-77.88694799999996,76.94775400000015],[-77.881104,76.94026200000002],[-77.77944899999994,76.79136699999998],[-77.78944399999995,76.78166200000004],[-77.81332399999997,76.69274899999999],[-77.81361399999997,76.68775900000009],[-77.81304899999986,76.68193100000002],[-77.80499299999997,76.67526199999992],[-77.76945499999994,76.6583250000001],[-77.78443900000002,76.65026900000004],[-77.81027199999994,76.64082300000007],[-77.84111000000001,76.63333100000011],[-77.8616639999999,76.62970000000007],[-77.91833500000001,76.62831100000011],[-77.94721999999996,76.62942500000008],[-77.98500099999995,76.632477],[-78.01362599999999,76.63081400000004],[-78.02749599999999,76.62692299999998],[-78.089722,76.60942099999994],[-78.09777799999995,76.60609400000004],[-78.17832899999996,76.56608599999998],[-78.18611099999993,76.559708],[-78.20610799999997,76.53914600000013],[-78.25666799999993,76.50665300000014],[-78.364441,76.46249399999999],[-78.37748699999992,76.4580380000001],[-78.43510399999997,76.45317100000011],[-78.44332899999989,76.4522090000001],[-78.473053,76.45166000000012],[-78.51916499999999,76.45694000000003],[-78.55249000000003,76.46415700000011],[-78.60777299999995,76.48664900000006],[-78.61471599999993,76.48997500000007],[-78.61944599999998,76.49609400000008],[-78.61694299999999,76.49887100000001],[-78.61500499999988,76.5],[-78.61138899999992,76.49941999999993],[-78.59722899999991,76.50526400000012],[-78.591949,76.5086060000001],[-78.58833299999998,76.51304600000009],[-78.61332700000003,76.54775999999998],[-78.62721299999993,76.563873],[-78.75111400000003,76.57222000000002],[-78.77333099999998,76.57276899999994],[-78.79055800000003,76.57165500000013],[-78.86833199999995,76.5211030000001],[-78.88694799999996,76.49720800000006],[-78.90083300000003,76.4788670000001],[-78.93777499999999,76.44999700000005],[-78.94665500000002,76.444977],[-78.96945199999999,76.43414300000012],[-78.99415599999998,76.42442300000005],[-79.01306199999999,76.42025800000005],[-79.06138599999997,76.41276600000009],[-79.09028599999999,76.41137700000007],[-79.13917499999997,76.41165200000012],[-79.170837,76.40998800000011],[-79.18971299999987,76.40582300000011],[-79.19804399999987,76.4002690000001],[-79.261124,76.35220299999997],[-79.26556399999993,76.34610000000004],[-79.26640299999997,76.3394320000001],[-79.26278699999995,76.33194000000015],[-79.25418100000002,76.32026700000011],[-79.25306699999993,76.31469700000002],[-79.261124,76.30914300000006],[-79.27278099999995,76.30415299999999],[-79.31277499999999,76.297485],[-79.33860800000002,76.29637100000002],[-79.36582899999996,76.29664600000007],[-79.4141689999999,76.30108600000005],[-79.44554099999999,76.30664100000013],[-79.50083899999993,76.3141480000001],[-79.52528399999989,76.31442300000009],[-79.573624,76.311646],[-79.59666400000003,76.30859400000008],[-79.80555699999996,76.27832000000006],[-79.92443800000001,76.25360100000006],[-80.06138599999991,76.22692899999998],[-80.08721899999995,76.22360200000008],[-80.10722399999997,76.2227630000001],[-80.12165800000002,76.22442600000005],[-80.136124,76.22831700000012],[-80.15638699999988,76.23692299999999],[-80.17832900000002,76.23970000000008],[-80.20361300000002,76.24053999999995],[-80.23028599999998,76.23997500000013],[-80.261124,76.23831200000001],[-80.2933349999999,76.2352600000001],[-80.33833299999998,76.22831700000012],[-80.36694299999999,76.21804800000007],[-80.37554899999992,76.21304300000003],[-80.38305699999995,76.20748900000001],[-80.39666699999992,76.20220899999998],[-80.412216,76.19802900000013],[-80.42694099999989,76.19552599999997],[-80.50695799999994,76.19636500000013],[-80.60638399999999,76.1916500000001],[-80.62748699999992,76.18719500000009],[-80.637787,76.17053199999998],[-80.63972499999988,76.16748000000007],[-80.65417500000001,76.1624910000001],[-80.67250100000001,76.15832500000005],[-80.70333899999997,76.15664700000008],[-80.949997,76.14498900000007],[-81.05332900000002,76.12803600000001],[-81.07583599999992,76.12914999999998],[-81.08583099999993,76.13415500000002],[-81.09028599999994,76.13749699999994],[-81.095551,76.21220400000004],[-81.04750100000001,76.24941999999999],[-81.04110699999995,76.25360100000006],[-81.02639799999992,76.25833100000011],[-80.903885,76.31219499999997],[-80.783615,76.3749850000001],[-80.769455,76.38472000000002],[-80.761124,76.39415000000008],[-80.76000999999991,76.40415999999999],[-80.76362599999987,76.41110200000008],[-80.77166699999992,76.41914400000002],[-80.78472899999997,76.42387400000007],[-80.99166899999994,76.48304700000006],[-81.18888900000002,76.5188750000001],[-81.27500899999995,76.53332500000005],[-81.304169,76.51054400000004],[-81.33721899999989,76.49498000000011],[-81.351944,76.49026500000008],[-81.38890100000003,76.48136899999997],[-81.41111799999999,76.47747800000008],[-81.46083099999993,76.47137499999997],[-81.49249299999991,76.46943700000003],[-81.52194199999997,76.46859699999999],[-81.63694800000002,76.46887200000015],[-81.71665999999999,76.470261],[-81.78860500000002,76.47470099999998],[-81.87999000000002,76.48387100000002],[-82.03971899999993,76.50943000000007],[-82.05860899999999,76.51361099999997],[-82.07583599999998,76.5186000000001],[-82.08361799999994,76.52387999999996],[-82.03195199999999,76.55358899999999],[-81.98500099999995,76.57859799999994],[-81.98194899999993,76.58471700000001],[-81.99333199999995,76.59027099999997],[-82.04527300000001,76.6035920000001],[-82.05665599999986,76.60914600000012],[-82.04943800000001,76.61248800000004],[-81.95333899999991,76.63192700000013],[-81.87361099999987,76.64582800000011],[-81.85139499999997,76.649719],[-81.81416300000001,76.65859999999992],[-81.79028299999993,76.667755],[-81.78222700000003,76.67276000000004],[-81.776947,76.67747500000007],[-81.778885,76.68109099999992],[-81.78582799999992,76.68553200000002],[-81.79916399999996,76.68580599999996],[-81.819458,76.68275499999999],[-81.83805799999993,76.67831400000006],[-81.85278299999999,76.67359900000002],[-81.86193800000001,76.66914400000002],[-81.89334100000002,76.66081200000002],[-82.08111599999995,76.63108799999998],[-82.11555499999992,76.62886000000003],[-82.14555399999995,76.62803600000007],[-82.199997,76.6285860000001],[-82.27333099999993,76.63333100000011],[-82.29249599999997,76.6355440000001],[-82.32695000000001,76.6413730000001],[-82.346115,76.6455380000001],[-82.37748699999992,76.65748599999995],[-82.44249000000002,76.68498199999999],[-82.47027600000001,76.698868],[-82.47666899999996,76.70471200000003],[-82.487213,76.71775800000012],[-82.58029199999999,76.77638200000001],[-82.596115,76.782486],[-82.69860799999998,76.81248500000004],[-82.72500599999995,76.81915300000003],[-82.74972500000001,76.81860400000011],[-82.76722699999999,76.813309],[-82.76972999999992,76.81109600000008],[-82.76556399999987,76.80831899999998],[-82.74610899999999,76.80415300000004],[-82.72833300000002,76.79914900000011],[-82.69860799999998,76.788589],[-82.64056399999998,76.766388],[-82.556107,76.72303800000003],[-82.55833399999995,76.718323],[-82.56666599999994,76.70748900000012],[-82.56945799999994,76.70138500000007],[-82.56249999999994,76.68887300000006],[-82.54554699999994,76.67414900000006],[-82.53332499999999,76.66638200000006],[-82.460556,76.63610800000004],[-82.435272,76.62803600000007],[-82.41500899999988,76.62303199999991],[-82.30888400000003,76.60942099999994],[-82.208054,76.59304800000007],[-82.11389199999991,76.57222000000002],[-82.10221899999999,76.56887800000004],[-82.08111599999995,76.56109600000013],[-82.093887,76.55720500000007],[-82.17500299999995,76.54693600000002],[-82.19694499999997,76.54275500000011],[-82.21139499999992,76.53804000000008],[-82.22222899999997,76.53276100000011],[-82.225281,76.52665700000006],[-82.22471599999989,76.52026400000011],[-82.22250400000001,76.5144350000001],[-82.21639999999996,76.5086060000001],[-82.18943799999988,76.48664900000006],[-82.15805099999994,76.46609500000005],[-82.14723200000003,76.46110500000003],[-82.13555899999994,76.45332300000007],[-82.13137799999993,76.44859300000002],[-82.12721299999993,76.44165000000004],[-82.13221699999991,76.43691999999999],[-82.16250599999995,76.42192100000011],[-82.17971799999998,76.41693100000009],[-82.20944199999997,76.40998800000011],[-82.26028400000001,76.39860500000009],[-82.29333500000001,76.395828],[-82.34834299999994,76.39553799999999],[-82.48306300000002,76.39637800000003],[-82.704453,76.38693200000006],[-82.83332799999988,76.3977660000001],[-82.99055499999992,76.42665099999999],[-83.00361599999997,76.42915300000004],[-83.0625,76.45027200000004],[-83.09973099999996,76.46388200000013],[-83.10249299999998,76.46943700000003],[-83.09695399999998,76.47581499999995],[-83.08944699999995,76.48082],[-83.06500199999999,76.49108900000004],[-83.061935,76.49720800000006],[-83.07501200000002,76.53276100000011],[-83.08444199999997,76.54637099999997],[-83.11000100000001,76.57998700000013],[-83.11665299999999,76.58610500000009],[-83.19860799999998,76.61943100000008],[-83.33889799999986,76.66415400000011],[-83.38417099999998,76.73082],[-83.36527999999993,76.74054000000007],[-83.35861199999994,76.74609400000003],[-83.35583499999996,76.7522130000001],[-83.362213,76.75610399999994],[-83.37998999999996,76.75888100000003],[-83.40083300000003,76.759995],[-83.4100039999999,76.75776700000006],[-83.49749800000001,76.72387699999996],[-83.51834099999996,76.71331800000013],[-83.52362099999993,76.70664999999997],[-83.52333099999993,76.70082100000013],[-83.52055399999995,76.69525100000004],[-83.51501499999995,76.68997200000007],[-83.49916100000002,76.6766510000001],[-83.35221899999999,76.61248800000004],[-83.33111600000001,76.60331700000012],[-83.316101,76.59803799999997],[-83.29861499999998,76.59304800000007],[-83.27806099999992,76.58831800000007],[-83.25418100000002,76.5794370000001],[-83.24638399999998,76.57276899999994],[-83.20750399999991,76.50555399999996],[-83.1844329999999,76.42498800000004],[-83.18832399999997,76.41943400000008],[-83.20222499999994,76.41442899999998],[-83.22361799999987,76.41053799999992],[-83.25666799999999,76.407486],[-83.28582799999998,76.40637200000003],[-83.43998699999992,76.41110200000008],[-83.61999500000002,76.42359900000008],[-83.69110099999995,76.42886399999992],[-83.710556,76.43304400000011],[-83.73500099999995,76.44413800000001],[-83.73416099999992,76.449142],[-83.735275,76.45582600000006],[-83.74055499999997,76.46276900000004],[-83.75666799999999,76.46859699999999],[-83.89361600000001,76.50166300000006],[-83.98500100000001,76.52053800000004],[-84.01861600000001,76.52943399999998],[-84.03361499999994,76.53471400000006],[-84.04666099999997,76.54220599999996],[-84.058334,76.55304000000007],[-84.05888400000003,76.55886800000013],[-84.06166100000002,76.5852660000001],[-84.0708469999999,76.61665300000004],[-84.08667000000003,76.62414600000011],[-84.101944,76.62942500000008],[-84.11888099999999,76.63388099999997],[-84.13861099999991,76.63777200000004],[-84.261124,76.65554800000001],[-84.28443899999996,76.657761],[-84.31082200000003,76.6583250000001],[-84.31973299999987,76.65609699999999],[-84.32472200000001,76.65332000000006],[-84.33084100000002,76.64749100000006],[-84.31332399999991,76.64109800000011],[-84.25666799999999,76.6285860000001],[-84.220551,76.62220799999994],[-84.20249899999993,76.61720300000007],[-84.19305399999996,76.60998500000011],[-84.19444299999998,76.60693400000008],[-84.21694899999989,76.57165500000013],[-84.24972500000001,76.53692600000011],[-84.24833699999999,76.53054800000012],[-84.24499499999996,76.52499399999994],[-84.22111499999994,76.51081799999997],[-84.20861799999989,76.50526400000012],[-84.19249000000002,76.49941999999993],[-84.17971799999992,76.49192800000003],[-84.18083200000001,76.484985],[-84.19554099999993,76.45637499999998],[-84.20556599999998,76.451096],[-84.21583599999997,76.44802900000008],[-84.23693800000001,76.44358799999998],[-84.48916600000001,76.42915300000004],[-84.51861599999995,76.42776500000014],[-84.57084699999996,76.42886399999992],[-84.61972000000003,76.43165600000003],[-84.63694799999996,76.43441800000011],[-84.65278599999999,76.43803400000002],[-84.78388999999999,76.46998600000012],[-84.79277000000002,76.47499099999999],[-84.785278,76.48526000000004],[-84.78388999999999,76.48997500000007],[-84.79527300000001,76.50387600000005],[-84.84889199999992,76.53637700000013],[-84.86000100000001,76.54275500000011],[-84.95056199999993,76.57777399999998],[-84.97055099999994,76.58194000000009],[-84.99137899999994,76.58276400000005],[-85.01640299999991,76.57887299999999],[-85.02833599999997,76.57499700000011],[-85.03416399999998,76.56915300000009],[-85.05139199999996,76.51416000000006],[-85.02250700000002,76.45609999999999],[-84.97027600000001,76.42608600000011],[-84.96028100000001,76.42053199999998],[-84.94444299999998,76.41693100000009],[-84.90417500000001,76.41192600000005],[-84.72805800000003,76.39027399999998],[-84.43638599999997,76.33859300000012],[-84.39750699999996,76.33055100000013],[-84.38137799999993,76.32470699999993],[-84.37609899999995,76.31776400000012],[-84.38194299999998,76.31191999999993],[-84.39389,76.30802900000003],[-84.41305499999999,76.30470300000002],[-84.429169,76.30304000000007],[-84.53361499999994,76.30581699999999],[-84.71665999999993,76.30693099999996],[-84.77639799999997,76.303314],[-84.898056,76.28858900000006],[-84.92832899999996,76.28637700000002],[-85.17443800000001,76.28027299999997],[-85.23222399999992,76.29525799999993],[-85.36221299999994,76.303314],[-85.50500499999998,76.32193000000007],[-85.52305599999988,76.32666000000006],[-85.54444899999999,76.32998700000002],[-85.69833399999999,76.34887700000013],[-85.95249899999993,76.36859100000004],[-85.97805800000003,76.37052899999998],[-86.00418100000002,76.37081900000004],[-86.11027499999994,76.3683170000001],[-86.13473499999998,76.36943100000008],[-86.281677,76.37692300000003],[-86.33056599999998,76.3808140000001],[-86.37222300000002,76.38638300000008],[-86.412216,76.40776100000005],[-86.41500899999988,76.41276600000009],[-86.42138699999992,76.45694000000003],[-86.41861,76.46914700000002],[-86.40972899999991,76.47470099999998],[-86.398056,76.4788670000001],[-86.37887599999999,76.48387100000002],[-86.36082499999992,76.48776200000009],[-86.30776999999995,76.49552900000009],[-86.27778599999994,76.5],[-86.25611900000001,76.50387600000005],[-86.22222899999997,76.51332100000013],[-86.21305799999993,76.5186000000001],[-86.20777899999996,76.52442900000011],[-86.21194499999996,76.53526299999999],[-86.22610499999996,76.54275500000011],[-86.53277600000001,76.62330600000001],[-86.59416199999998,76.63499499999995],[-86.63034099999993,76.63513200000011],[-86.62582399999997,76.62942500000008],[-86.60110499999996,76.61998],[-86.51251200000002,76.58692900000005],[-86.36221299999994,76.54165599999993],[-86.34222399999999,76.51220699999993],[-86.5080569999999,76.48776200000009],[-86.64916999999997,76.45887800000014],[-86.66471899999999,76.41970800000001],[-86.71112099999999,76.34803799999997],[-86.71665999999999,76.34610000000004],[-86.770554,76.35081500000007],[-87.083328,76.37942499999991],[-87.130829,76.38415500000013],[-87.148346,76.38832100000008],[-87.15499899999998,76.39498900000001],[-87.15417500000001,76.40109300000006],[-87.225281,76.44802900000008],[-87.4266659999999,76.46859699999999],[-87.46278399999994,76.58692900000005],[-87.468887,76.59165999999999],[-87.52027900000002,76.61248800000004],[-87.53694200000001,76.61747700000001],[-87.56361399999997,76.61637900000011],[-87.58000199999998,76.61137400000007],[-87.583618,76.60498000000001],[-87.59861799999999,76.540817],[-87.59555099999994,76.53414900000001],[-87.553604,76.451096],[-87.54527300000001,76.44358799999998],[-87.53694200000001,76.43914799999999],[-87.516953,76.43248],[-87.50029,76.42886399999992],[-87.45527600000003,76.42387400000007],[-87.42999299999991,76.41775500000006],[-87.40249599999999,76.35276800000003],[-87.41639700000002,76.34803799999997],[-87.59138499999989,76.341095],[-87.64889499999987,76.33804300000008],[-87.71972699999998,76.34304800000012],[-87.74276700000001,76.34637500000008],[-87.760559,76.35220299999997],[-87.78860499999996,76.366379],[-87.81723,76.39054900000002],[-87.86416600000001,76.38998400000014],[-87.90083300000003,76.36303700000008],[-87.916946,76.359711],[-87.94833399999999,76.3577580000001],[-87.997772,76.35832200000004],[-88.3511049999999,76.384995],[-88.38999899999988,76.38970899999998],[-88.42971799999998,76.39804100000015],[-88.43443300000001,76.40220599999998],[-88.391953,76.45416300000011],[-88.37193299999996,76.47608900000006],[-88.35583500000001,76.48109399999993],[-88.34861799999999,76.48719800000015],[-88.34944199999995,76.5144350000001],[-88.35665899999998,76.5211030000001],[-88.44276400000001,76.59165999999999],[-88.51528899999994,76.63610800000004],[-88.50917099999998,76.69747899999999],[-88.48860199999996,76.76527400000003],[-88.47972099999993,76.77693200000004],[-88.47666900000002,76.78332499999999],[-88.47471599999989,76.78887900000001],[-88.47471599999989,76.794983],[-88.47778299999999,76.80775500000004],[-88.485275,76.81442299999998],[-88.49471999999997,76.81721500000009],[-88.51889,76.8160860000001],[-88.54194599999994,76.81275899999997],[-88.55444299999994,76.80748],[-88.55722000000003,76.8058170000001],[-88.70195000000001,76.70748900000012],[-88.68331899999998,76.7019350000001],[-88.64973399999997,76.68414300000006],[-88.591949,76.64276100000001],[-88.58444199999997,76.63581800000003],[-88.49554399999994,76.55219999999997],[-88.489441,76.50332600000002],[-88.49638399999998,76.49720800000006],[-88.57167099999992,76.47360200000003],[-88.59355899999997,76.45593300000002],[-88.60321799999997,76.44926500000003],[-88.60821499999997,76.44226100000014],[-88.60772700000001,76.43909500000001],[-88.608612,76.4160920000001],[-88.59973100000002,76.40998800000011],[-88.59750399999996,76.40582300000011],[-88.60804699999994,76.39999400000005],[-88.63194299999992,76.39721700000001],[-88.65638699999988,76.39833099999998],[-88.67721599999993,76.40193200000004],[-88.68998699999997,76.40832499999999],[-88.693604,76.41470300000015],[-88.693329,76.42082199999999],[-88.68499800000001,76.43248],[-88.67805499999997,76.44165000000004],[-88.65950800000002,76.4787060000001],[-88.64650699999999,76.48921200000001],[-88.640289,76.55859400000003],[-88.64416499999999,76.56526200000002],[-88.65167200000002,76.57193000000001],[-88.66027799999995,76.57777399999998],[-88.68888899999996,76.59136999999998],[-88.71000699999996,76.594986],[-88.73361199999994,76.59387200000003],[-88.74082899999996,76.5877690000001],[-88.79138199999994,76.51332100000013],[-88.79527300000001,76.47943100000003],[-88.78666699999991,76.47360200000003],[-88.78138699999994,76.46638500000006],[-88.78332499999999,76.46081500000003],[-88.79943800000001,76.44999700000005],[-88.90167199999996,76.40832499999999],[-88.92111199999994,76.40525800000006],[-88.94722000000002,76.40525800000006],[-88.99415599999992,76.40914900000013],[-89.16639699999996,76.42442300000005],[-89.21333299999998,76.42970300000007],[-89.231674,76.43359399999997],[-89.35333300000002,76.47997999999995],[-89.40722700000003,76.51582300000001],[-89.49027999999993,76.55748000000006],[-89.499435,76.54664600000001],[-89.515015,76.54165599999993],[-89.541382,76.54165599999993],[-89.66722099999998,76.56442300000003],[-89.67666599999995,76.56721500000015],[-89.67944299999999,76.57165500000013],[-89.61416600000001,76.6160890000001],[-89.60360700000001,76.62191800000011],[-89.57194500000003,76.63165300000003],[-89.52833599999997,76.64082300000007],[-89.48055999999997,76.649429],[-89.443329,76.6583250000001],[-89.43138099999999,76.66360500000002],[-89.41555800000003,76.67442299999999],[-89.41166699999997,76.68026699999996],[-89.4344329999999,76.72442600000011],[-89.47222899999997,76.78471400000001],[-89.49694799999992,76.820267],[-89.51444999999995,76.83581500000003],[-89.52917500000001,76.84721400000012],[-89.53332499999999,76.85359200000005],[-89.52139299999993,76.85887100000008],[-89.41777000000002,76.88665800000001],[-89.279449,76.90693699999997],[-89.23889200000002,76.91609199999999],[-89.14805599999994,76.92553700000008],[-88.98693800000001,76.95443699999993],[-88.97610499999996,76.95999100000012],[-88.89889499999998,76.98553500000014],[-88.76916499999999,76.99887100000007],[-88.74027999999993,77.00277699999998],[-88.71945199999993,77.00749200000001],[-88.70278899999994,77.01220700000005],[-88.50111400000003,77.07165500000008],[-88.47332799999998,77.09664900000001],[-88.54472399999992,77.09803800000003],[-88.545837,77.10026600000015],[-88.42639200000002,77.12081900000004],[-88.30721999999997,77.12886000000009],[-88.27833599999991,77.12969999999996],[-88.17250100000001,77.12803599999995],[-88.15417500000001,77.11608899999999],[-87.96722399999993,77.12747200000001],[-87.69055200000003,77.135269],[-87.67027299999995,77.13360600000004],[-87.65695199999993,77.13026400000012],[-87.64250199999998,77.12498499999992],[-87.626938,77.11747700000012],[-87.61971999999997,77.11080900000013],[-87.56889299999989,77.09942600000011],[-87.45584100000002,77.1019290000001],[-87.34916699999997,77.1060940000001],[-87.33778399999989,77.11025999999998],[-87.35360700000001,77.11470000000003],[-87.37222300000002,77.11720300000002],[-87.45140100000003,77.12275699999998],[-87.460556,77.12553400000007],[-87.45666499999999,77.13192700000002],[-87.452225,77.13638300000014],[-87.43221999999997,77.14971900000006],[-87.41610700000001,77.15664700000008],[-87.4041749999999,77.16081200000008],[-87.35638399999999,77.17553700000002],[-87.33666999999997,77.1791530000001],[-87.31277499999999,77.1808170000001],[-87.06916799999999,77.18275500000004],[-87.04444899999993,77.18054200000006],[-86.95916699999998,77.16192600000005],[-86.95167499999997,77.15832499999999],[-86.94694500000003,77.15443399999992],[-86.9519499999999,77.1499940000001],[-86.95140100000003,77.14471400000002],[-86.94249000000002,77.14193699999993],[-86.87527499999993,77.13220200000006],[-86.82917799999996,77.12776200000002],[-86.80444299999999,77.12719700000002],[-86.791382,77.13081399999999],[-86.73999000000003,77.17414900000011],[-86.77362099999993,77.18580600000007],[-86.96000699999996,77.19581599999998],[-87.15055799999999,77.19941700000004],[-87.148056,77.19802900000013],[-87.14695699999993,77.19581599999998],[-87.16111799999993,77.19442699999996],[-87.18276999999995,77.19693000000012],[-87.19610599999993,77.19999700000005],[-87.21055599999994,77.20526100000006],[-87.1744379999999,77.22943100000003],[-87.16694599999994,77.23387100000008],[-87.141388,77.23803700000013],[-87.00723299999999,77.255829],[-86.97666900000002,77.25749200000013],[-86.94888299999997,77.25555400000002],[-86.92832900000002,77.25526400000001],[-86.91055299999994,77.26026900000005],[-86.91915899999998,77.26609800000006],[-86.94749499999995,77.27165200000007],[-86.98443600000002,77.27470399999999],[-87.01222199999995,77.27499399999999],[-87.07806399999993,77.27360499999998],[-87.10611,77.27221700000007],[-87.13667299999997,77.27221700000007],[-87.18388400000003,77.27360499999998],[-87.197495,77.27526899999998],[-87.22917199999995,77.28553800000003],[-87.24527,77.29832500000003],[-87.24888599999997,77.303314],[-87.108612,77.33831800000007],[-87.09584000000001,77.34027100000003],[-87.06861899999996,77.34220900000014],[-87.037781,77.34220900000014],[-86.96278399999994,77.33915700000006],[-86.93472299999996,77.33888200000001],[-86.900284,77.34220900000014],[-86.84583999999995,77.34915200000012],[-86.82972699999999,77.35304300000001],[-86.83860800000002,77.35748300000006],[-86.851944,77.36053500000014],[-86.96333299999998,77.366379],[-87.06416299999995,77.36692800000009],[-87.09110999999996,77.366379],[-87.24137899999994,77.35609400000004],[-87.26306199999988,77.35165400000005],[-87.28083800000002,77.34693900000002],[-87.29415899999998,77.34165999999999],[-87.32611099999997,77.33387800000008],[-87.35888699999998,77.3313750000001],[-87.39111299999996,77.33055100000013],[-87.41639700000002,77.33082600000012],[-87.695831,77.35554500000012],[-87.71194500000001,77.35998500000011],[-87.71583599999991,77.36331200000006],[-87.775284,77.41554300000013],[-87.78028899999998,77.42109700000015],[-87.78472899999997,77.42970300000007],[-87.77500900000001,77.44136000000003],[-87.74833699999999,77.45166000000012],[-87.73083499999996,77.45637499999998],[-87.66953999999998,77.46923800000002],[-87.65194699999995,77.47499099999999],[-87.64250199999998,77.48027000000013],[-87.64611799999994,77.4869230000001],[-87.69444299999998,77.5372010000001],[-87.71112099999988,77.5416560000001],[-87.86888099999999,77.57859800000011],[-88.06304899999998,77.61886600000003],[-88.162216,77.62692300000015],[-88.18055699999996,77.63192700000013],[-88.20083599999992,77.64276100000001],[-88.214722,77.65054299999997],[-88.22361799999993,77.66249099999999],[-88.223053,77.66720600000002],[-88.22111499999988,77.67276000000004],[-88.162781,77.758331],[-88.06806899999998,77.820267],[-87.83583099999993,77.84027100000009],[-87.64056399999998,77.86248799999998],[-87.29472399999992,77.89804100000003],[-87.23138399999993,77.89888000000013],[-87.174713,77.897491],[-86.87609900000001,77.8836060000001],[-86.82417299999992,77.87942499999997],[-86.65167199999996,77.86026000000004],[-86.46166999999997,77.83610500000003],[-86.42222599999997,77.83082600000006],[-86.37748699999992,77.82276900000005],[-86.222778,77.79443400000002],[-86.19888300000002,77.78610200000008],[-85.98693800000001,77.71138000000013],[-85.97528099999988,77.70582599999994],[-85.88444500000003,77.6327510000001],[-85.718887,77.47221400000006],[-85.71583599999997,77.46720900000003],[-85.71722399999993,77.46249399999999],[-85.72721899999988,77.45193499999993],[-85.74861099999998,77.44693000000007],[-85.76916499999993,77.44358799999998],[-85.77583299999992,77.43997200000007],[-85.795837,77.42387400000007],[-85.79444899999993,77.41970800000013],[-85.776947,77.42137100000008],[-85.55139199999996,77.45832800000011],[-85.53056299999992,77.46192899999994],[-85.49333199999995,77.43026700000001],[-85.43638599999991,77.40415999999993],[-85.39973399999991,77.395828],[-85.3766629999999,77.39248700000013],[-85.29943800000001,77.3877720000001],[-85.27000399999991,77.38665800000012],[-85.15583800000002,77.38749700000005],[-84.97332799999987,77.37719700000014],[-84.95472699999993,77.37442000000004],[-84.9375,77.37081899999998],[-84.87527499999999,77.35165400000005],[-84.82528699999995,77.33415200000002],[-84.75917099999987,77.31832899999995],[-84.71972700000003,77.311646],[-84.64944499999996,77.30442800000014],[-84.601944,77.30053700000008],[-84.52917500000001,77.29582200000004],[-84.479446,77.29443400000014],[-84.46639999999996,77.29637100000002],[-84.46333300000003,77.30026200000009],[-84.47444200000001,77.3119200000001],[-84.48194899999999,77.31776400000012],[-84.49471999999997,77.32110600000004],[-84.52027900000002,77.32415799999995],[-84.553879,77.3313750000001],[-84.56916799999999,77.33970599999998],[-84.615005,77.38304099999999],[-84.61277799999988,77.38916],[-84.60388199999994,77.39359999999999],[-84.58555599999994,77.39804100000009],[-84.55027799999993,77.40138200000013],[-84.52084400000001,77.401657],[-84.49610899999999,77.399429],[-84.47055099999994,77.39637800000003],[-84.42944299999994,77.38888499999996],[-84.38639799999999,77.38388100000003],[-84.33444199999991,77.38304099999999],[-84.27027899999996,77.384995],[-84.15360999999996,77.39498900000001],[-84.06166100000002,77.39860500000003],[-84.00584399999997,77.39749100000006],[-83.985275,77.39553799999993],[-83.949997,77.38888499999996],[-83.86805700000002,77.37692300000003],[-83.79361,77.36914100000007],[-83.53195199999993,77.34637500000002],[-83.50584399999997,77.34471100000002],[-83.47805800000003,77.34414700000008],[-83.464722,77.34832799999998],[-83.46305799999988,77.34915200000012],[-83.46444699999995,77.35554500000012],[-83.47250400000001,77.38720700000005],[-83.55305499999997,77.39305100000007],[-83.65499899999998,77.39553799999993],[-83.71166999999991,77.40470900000008],[-83.72860700000001,77.40832499999993],[-83.77860999999996,77.42330900000002],[-83.82250999999997,77.442474],[-83.83389299999999,77.448868],[-83.835556,77.45526100000001],[-83.82472200000001,77.46054100000003],[-83.80139199999996,77.46470600000004],[-83.76806599999992,77.46693400000004],[-83.68222000000003,77.46804800000001],[-83.62083399999995,77.47192400000006],[-83.59388699999994,77.47554000000014],[-83.42610200000001,77.4997100000001],[-83.38945000000001,77.50776700000011],[-83.36332699999997,77.51805100000013],[-83.21611000000001,77.57777399999998],[-83.011124,77.665817],[-82.89500399999986,77.71748400000001],[-82.67443800000001,77.836929],[-82.65527299999985,77.84776300000004],[-82.54167199999995,77.92053200000004],[-82.52610799999997,77.96192900000005],[-82.577225,78.00332600000007],[-82.59083599999997,78.01110800000004],[-82.59167500000001,78.01748700000007],[-82.57972699999988,78.02276600000005],[-82.56361400000003,78.02777100000009],[-82.53805499999999,78.03109699999999],[-82.49749800000001,78.03414900000007],[-82.470551,78.03471400000012],[-82.40972899999997,78.03414900000007],[-82.37748699999992,78.03581200000002],[-82.36944599999993,78.03942899999993],[-82.32611099999997,78.06526200000008],[-82.31861900000001,78.07083100000006],[-82.32000700000003,78.07582100000013],[-82.33612099999999,78.07887300000004],[-82.51834100000002,78.07415800000001],[-82.54943800000001,78.07193000000007],[-82.652222,78.05609099999992],[-82.67250099999995,78.0516510000001],[-82.69248999999996,78.04498300000012],[-82.78028899999998,78.0149990000001],[-82.79028299999999,78.0105440000001],[-82.7927699999999,78.00582900000006],[-82.79415899999998,77.99498],[-82.78527799999995,77.969986],[-82.77528399999994,77.964157],[-82.735275,77.9474790000001],[-82.72888199999994,77.93997200000001],[-82.72860700000001,77.92970300000013],[-82.73611499999998,77.92414899999994],[-82.76916499999999,77.91499300000004],[-82.85221899999999,77.89694200000002],[-82.9491579999999,77.87469499999997],[-83.12304699999993,77.78054800000007],[-83.15666199999993,77.74498000000006],[-83.18554699999999,77.716385],[-83.19248999999996,77.71054099999998],[-83.20083599999987,77.70555100000013],[-83.38667299999992,77.61665300000004],[-83.42721599999999,77.60081500000001],[-83.52778599999994,77.57276900000011],[-83.648056,77.54081699999995],[-83.73500099999995,77.5188750000001],[-83.87304699999999,77.49331699999999],[-83.89834599999995,77.49054000000007],[-83.92054699999994,77.49165299999999],[-84.14389,77.50943000000001],[-84.19249000000002,77.51554900000008],[-84.22999599999997,77.52137800000008],[-84.38667299999992,77.528595],[-84.41999799999996,77.52777100000003],[-84.45222499999994,77.5249940000001],[-84.48332199999999,77.52165200000002],[-84.500565,77.51805100000013],[-84.55555700000002,77.51249700000011],[-84.57972699999999,77.51249700000011],[-84.76055899999994,77.51971400000008],[-84.77917499999995,77.52249099999995],[-84.85888699999992,77.54275500000011],[-84.86915599999998,77.56275900000003],[-84.87110899999999,77.56915300000009],[-84.86639399999996,77.57415800000012],[-84.837219,77.58387800000003],[-84.81555200000003,77.58888199999996],[-84.77362099999999,77.5977630000001],[-84.70722999999998,77.60998500000005],[-84.66528299999999,77.61886600000003],[-84.62748699999992,77.62803600000007],[-84.52000399999997,77.66470300000003],[-84.44193999999993,77.7061000000001],[-84.42999299999997,77.71832299999994],[-84.42832899999996,77.72276299999999],[-84.43110699999988,77.72637900000001],[-84.44305400000002,77.73637400000013],[-84.48693800000001,77.7502750000001],[-84.49527,77.75109900000007],[-84.50306699999999,77.74971000000005],[-84.48971599999993,77.74636800000013],[-84.48306299999996,77.74470500000001],[-84.475281,77.738876],[-84.47666900000002,77.72831699999995],[-84.48638899999997,77.71138000000013],[-84.49916100000002,77.6997070000001],[-84.52084400000001,77.6891480000001],[-84.53388999999999,77.68498199999999],[-84.54722600000002,77.68081699999999],[-84.715012,77.6397090000001],[-84.92250100000001,77.601654],[-84.95249899999999,77.60137900000012],[-84.9725039999999,77.60636900000003],[-85.1583399999999,77.64166300000011],[-85.29888900000003,77.66053800000003],[-85.31054699999999,77.66470300000003],[-85.34889199999992,77.72886699999998],[-85.34889199999992,77.73387100000014],[-85.33583099999998,77.73803700000008],[-85.19027699999987,77.77998400000013],[-85.05499299999997,77.79693600000013],[-85.05360399999995,77.83055100000001],[-85.14416499999999,77.81749000000008],[-85.297775,77.79721100000012],[-85.32806399999993,77.79832499999992],[-85.38194299999998,77.80775499999999],[-85.40028399999994,77.813309],[-85.40249599999993,77.81999199999996],[-85.40028399999994,77.83638000000002],[-85.389725,77.84193400000004],[-85.35333300000002,77.855545],[-85.32501200000002,77.86608900000004],[-85.281387,77.87441999999993],[-85.23194899999999,77.88165300000014],[-85.2077789999999,77.88388100000009],[-84.92555199999998,77.891098],[-84.837219,77.88749699999994],[-84.69249000000002,77.89860499999998],[-84.664444,77.90220600000004],[-84.61111499999993,77.90387000000004],[-84.498154,77.90011600000008],[-84.428879,77.89694200000002],[-84.38583399999993,77.891098],[-84.36805699999991,77.88720699999993],[-84.34277299999991,77.88499500000006],[-84.31861899999996,77.88693200000012],[-84.31361400000003,77.89193699999998],[-84.32501200000002,77.89610300000004],[-84.37971500000003,77.90637200000009],[-84.40167199999996,77.91026299999999],[-84.55943299999996,77.92303499999997],[-84.57556199999999,77.92387400000013],[-84.63444499999991,77.92692600000004],[-84.66305499999993,77.92526200000003],[-84.81666599999994,77.911652],[-84.84722899999991,77.90887500000008],[-85.05694599999998,77.90054300000008],[-85.16639699999996,77.90220600000004],[-85.20056199999999,77.90165700000006],[-85.26750199999992,77.89804100000003],[-85.303604,77.89471400000008],[-85.33168,77.89082300000001],[-85.37805199999997,77.88220200000006],[-85.42304999999999,77.87469499999997],[-85.47471599999994,77.8685910000001],[-85.515289,77.8836060000001],[-85.67887899999994,77.92942800000014],[-85.67971799999998,77.93664599999994],[-85.67527799999999,77.9416500000001],[-85.660278,77.94663999999995],[-85.45056199999999,77.9910890000001],[-85.28694200000001,78.02165200000007],[-85.06555199999991,78.05636600000014],[-85.03889499999991,78.05720500000012],[-85.00973499999992,78.055252],[-84.96305799999993,78.04414399999996],[-84.88417099999992,78.033051],[-84.81695599999995,78.02638200000013],[-84.78805499999999,78.02415500000006],[-84.76167299999992,78.02360500000003],[-84.72694399999995,78.02581799999996],[-84.70889299999999,78.02943400000004],[-84.69554099999993,78.03359999999992],[-84.68888899999996,78.03915400000011],[-84.67388899999997,78.04414399999996],[-84.65417500000001,78.04887400000001],[-84.57556199999999,78.06721500000003],[-84.54750100000001,78.0711060000001],[-84.5244449999999,78.07222000000007],[-84.36000100000001,78.07026700000011],[-84.3286129999999,78.07054100000005],[-84.30721999999997,78.07249500000006],[-84.28805499999993,78.07554600000009],[-84.29276999999996,78.07804900000008],[-84.29943800000001,78.07971200000003],[-84.32362399999994,78.08276400000011],[-84.41000399999996,78.08692900000011],[-84.5327759999999,78.08554100000003],[-84.55722000000003,78.0836030000001],[-84.62304699999999,78.07138100000009],[-84.67361499999998,78.0641480000001],[-84.7369379999999,78.0583190000001],[-84.76556399999998,78.05636600000014],[-84.79888899999997,78.055252],[-84.85583500000001,78.05693099999996],[-84.88194299999998,78.05914300000006],[-84.99388099999999,78.07415800000001],[-85.07749899999993,78.09082000000001],[-85.09445199999993,78.097488],[-85.08778399999989,78.103317],[-84.9949949999999,78.16304000000002],[-84.901947,78.17082199999999],[-84.82945299999994,78.16886900000003],[-84.79388399999999,78.17109699999997],[-84.761124,78.17442300000005],[-84.70861799999994,78.18248],[-84.68859899999995,78.18719500000003],[-84.65777599999996,78.19720500000011],[-84.63110399999988,78.19999700000005],[-84.54943799999995,78.19720500000011],[-84.43055700000002,78.18637100000007],[-84.31555199999997,78.17359900000008],[-84.28416400000003,78.16638199999994],[-84.222778,78.15887500000002],[-84.20111099999997,78.15693700000008],[-84.17388900000003,78.15776100000005],[-84.12777699999992,78.17109699999997],[-84.12666299999995,78.17997700000001],[-84.45361299999996,78.21470600000009],[-84.47972099999993,78.21693400000004],[-84.50666799999993,78.217758],[-84.693604,78.21720900000008],[-84.72250400000001,78.21693400000004],[-84.77749599999987,78.21026600000005],[-84.87721299999993,78.19303900000006],[-84.90972899999986,78.1910860000001],[-84.93777499999993,78.192474],[-84.95140099999998,78.19552599999992],[-84.968613,78.20248400000008],[-84.97389199999998,78.20860299999998],[-84.97027600000001,78.21415700000011],[-84.96722399999993,78.21804800000001],[-84.95611600000001,78.23220800000013],[-84.94276400000001,78.24386600000014],[-84.83444199999991,78.31498700000003],[-84.81527699999992,78.32165499999996],[-84.79249600000003,78.32499700000011],[-84.73138399999999,78.32554600000003],[-84.658615,78.3294370000001],[-84.62971500000003,78.333328],[-84.60527000000002,78.3374940000001],[-84.58528100000001,78.3419340000001],[-84.57556199999999,78.34637500000002],[-84.57278400000001,78.35054000000002],[-84.57194499999997,78.35554500000006],[-84.57583599999992,78.36137400000007],[-84.58167999999995,78.3660890000001],[-84.601944,78.36886600000003],[-84.63082899999995,78.36499000000015],[-84.66776999999996,78.34860200000008],[-84.68472299999996,78.34414700000008],[-84.70722999999998,78.34109499999994],[-84.73500100000001,78.34027099999997],[-84.77223199999997,78.34220900000014],[-84.81555200000003,78.34915200000012],[-84.86694299999999,78.36914100000007],[-84.86582900000002,78.37220799999994],[-84.785278,78.50166300000006],[-84.78250100000002,78.50582900000012],[-84.77471899999995,78.50915499999996],[-84.75917099999987,78.51416000000006],[-84.73860200000001,78.5188750000001],[-84.72416699999997,78.52442900000005],[-84.70445299999994,78.53498800000011],[-84.62582399999997,78.58415200000007],[-84.61944599999993,78.58831800000002],[-84.61999499999996,78.59054600000013],[-84.63861099999997,78.59414700000002],[-84.66111799999999,78.59248400000007],[-84.67527799999999,78.58831800000002],[-84.83833299999998,78.516663],[-84.84638999999993,78.51165800000012],[-84.97833300000002,78.4149930000001],[-84.97471599999994,78.35887100000014],[-84.97055099999994,78.35331700000012],[-84.96472199999994,78.34860200000008],[-84.96194500000001,78.34359700000005],[-84.96665999999999,78.33888200000001],[-85.04333500000001,78.299149],[-85.18804899999998,78.22831700000006],[-85.41833500000001,78.11886600000008],[-85.43331899999998,78.113876],[-85.45083599999992,78.10998499999994],[-85.48611499999993,78.10247800000002],[-85.50805700000001,78.099152],[-85.52305599999988,78.09942600000011],[-85.52806099999992,78.1019290000001],[-85.60888699999998,78.10081500000007],[-85.74082900000002,78.09304800000012],[-85.80471799999998,78.08888200000007],[-85.87666299999995,78.08166499999993],[-85.89416499999999,78.07804900000008],[-86.01028399999996,78.06608600000004],[-86.11999500000002,78.05636600000014],[-86.14834599999995,78.05470300000002],[-86.17805499999997,78.05497700000012],[-86.22332799999998,78.05748000000011],[-86.26722699999999,78.06637600000005],[-86.28222700000003,78.07165500000002],[-86.28832999999997,78.07638500000007],[-86.291382,78.0813750000001],[-86.29055800000003,78.08581500000014],[-86.25140399999998,78.15664700000008],[-86.23416099999997,78.16053799999997],[-86.13555899999994,78.16554300000001],[-86.11305199999987,78.17053199999998],[-86.098053,78.17553700000002],[-85.949997,78.22831700000006],[-85.93110699999994,78.23664900000006],[-85.83999599999999,78.32582100000008],[-85.83528100000001,78.33221400000002],[-85.82722499999994,78.34414700000008],[-85.82556199999993,78.34860200000008],[-85.83306899999997,78.379974],[-85.85333300000002,78.37915000000004],[-85.87805199999997,78.37692299999998],[-86.05277999999998,78.297485],[-86.060272,78.29248000000013],[-86.06054699999993,78.28054800000012],[-86.06527699999998,78.26361099999997],[-86.07362399999994,78.24859600000002],[-86.25917099999992,78.19636500000007],[-86.28527799999995,78.19331400000004],[-86.31111099999998,78.19331400000004],[-86.45361300000002,78.211929],[-86.47666899999996,78.21582000000006],[-86.49777199999994,78.21554600000013],[-86.51501499999995,78.21165500000006],[-86.53721599999994,78.19470199999995],[-86.54888899999997,78.18304400000011],[-86.56945799999994,78.17221099999995],[-86.71972699999998,78.121918],[-86.73693800000001,78.11804200000012],[-86.76306199999999,78.11499000000003],[-87.07972699999993,78.10276800000003],[-87.10943599999996,78.10304300000007],[-87.19665499999996,78.1060940000001],[-87.43971299999998,78.121643],[-87.50584399999991,78.12831099999994],[-87.52917499999995,78.132202],[-87.53860500000002,78.13804600000003],[-87.53500399999996,78.14305100000007],[-87.52667199999996,78.14915500000012],[-87.48388699999992,78.16442900000004],[-87.43055699999996,78.17831400000011],[-87.40750100000002,78.18304400000011],[-87.35221899999999,78.1910860000001],[-87.31416300000001,78.19386300000002],[-87.28999299999998,78.19470199999995],[-87.16694599999994,78.19552599999992],[-87.10499600000003,78.199142],[-87.08944699999995,78.20193499999999],[-87.087219,78.20609999999999],[-87.10583500000001,78.20942700000012],[-87.26222200000001,78.22665400000011],[-87.29360999999994,78.22608900000012],[-87.36389200000002,78.22109999999992],[-87.37165799999997,78.21943700000003],[-87.396118,78.21720900000008],[-87.42304999999993,78.21609500000005],[-87.47555499999987,78.21638500000012],[-87.49777199999994,78.21971100000013],[-87.51333599999992,78.22499099999999],[-87.51861600000001,78.230545],[-87.516953,78.24136400000009],[-87.51611300000002,78.2458190000001],[-87.49444599999998,78.29859899999997],[-87.50250199999988,78.30525200000011],[-87.51306199999999,78.31637599999999],[-87.51640299999997,78.32276899999994],[-87.52555799999999,78.41026300000004],[-87.52471899999995,78.41638200000011],[-87.51722699999999,78.42637600000012],[-87.50306699999999,78.43664600000005],[-87.47694399999995,78.44802900000002],[-87.31138599999991,78.50915499999996],[-87.29222099999993,78.51388500000002],[-87.15834000000001,78.54637100000014],[-87.14056399999998,78.55026200000003],[-87.01306199999999,78.5541530000001],[-86.89111299999996,78.54553199999998],[-86.86639400000001,78.54637100000014],[-86.85833699999995,78.5477600000001],[-86.85583499999996,78.55165099999999],[-86.85888699999998,78.56637599999993],[-86.864441,78.56887800000004],[-86.87777699999992,78.5730440000001],[-86.89862099999999,78.57582100000002],[-86.95777900000002,78.57499700000005],[-87.03167699999995,78.56915300000003],[-87.066101,78.56749000000013],[-87.09527599999996,78.56860400000011],[-87.11305199999993,78.5730440000001],[-87.12165800000002,78.57693499999999],[-87.12388599999997,78.58109999999999],[-87.12249800000001,78.58720400000004],[-86.94471699999997,78.70471199999997],[-86.93443299999996,78.70999100000012],[-86.92250100000001,78.71470599999998],[-86.85694899999993,78.73498500000011],[-86.63890100000003,78.79942299999999],[-86.61582900000002,78.80304000000012],[-86.37721299999998,78.80998200000005],[-86.13806199999999,78.81666600000011],[-86.06750499999998,78.81971699999991],[-86.03721599999994,78.82138099999997],[-85.64666699999987,78.84860200000014],[-85.60749799999996,78.85165400000011],[-85.57749899999993,78.85582],[-85.350281,78.88749700000011],[-85.32972699999993,78.89221199999997],[-85.29750099999995,78.90220599999998],[-85.25750700000003,78.91053799999997],[-85.09973100000002,78.91775500000006],[-85.06416300000001,78.91914400000007],[-85.03611799999999,78.91693099999992],[-85.008896,78.91331500000007],[-84.84584000000001,78.88888500000002],[-84.78832999999992,78.87803599999995],[-84.76640299999997,78.87303200000002],[-84.74055499999992,78.86998000000011],[-84.71278399999994,78.86775200000011],[-84.56332399999997,78.859985],[-84.412216,78.85554499999995],[-84.21278399999989,78.85693400000014],[-84.14500399999997,78.85554499999995],[-83.85082999999997,78.84526100000011],[-83.74694799999992,78.83692899999994],[-83.69444299999998,78.82971200000003],[-83.67443799999995,78.82554600000014],[-83.66000400000001,78.81999200000013],[-83.64056399999987,78.81387300000011],[-83.601944,78.80220000000008],[-83.57972699999993,78.79637100000008],[-83.53832999999992,78.78720100000004],[-83.51306199999999,78.78387499999997],[-83.48582499999998,78.78137200000003],[-83.428604,78.77915999999993],[-83.39416499999999,78.7788700000001],[-83.34584000000001,78.77360500000003],[-83.32749899999993,78.76971399999996],[-83.308334,78.76388500000013],[-83.29361,78.75610400000011],[-83.28492699999993,78.75000000000006],[-83.23693800000001,78.74054000000001],[-83.10139499999997,78.71443200000004],[-82.99472000000003,78.6997070000001],[-82.94193999999999,78.69552600000003],[-82.91082799999998,78.69470200000006],[-82.84500099999997,78.69747899999999],[-82.82250999999997,78.69525099999998],[-82.68971299999998,78.66415400000005],[-82.69638099999986,78.65776100000011],[-82.704453,78.6519320000001],[-82.69554099999999,78.64526400000011],[-82.61054999999993,78.61137400000001],[-82.506958,78.59109500000011],[-82.41722099999993,78.57415800000007],[-82.37388599999997,78.56860400000011],[-82.35749799999991,78.56749000000013],[-82.337784,78.56666599999994],[-82.308334,78.56887800000004],[-82.26222200000001,78.57804899999996],[-82.23693800000001,78.58831800000002],[-82.23554999999993,78.5958250000001],[-82.24471999999997,78.59887700000007],[-82.31027199999994,78.61665300000004],[-82.41665599999999,78.64276099999995],[-82.49638400000003,78.66192600000011],[-82.516953,78.66693099999998],[-82.535278,78.67275999999998],[-82.55943300000001,78.68220500000007],[-82.56555200000003,78.68525699999998],[-82.58473200000003,78.69552600000003],[-82.59445199999999,78.70304900000002],[-82.581955,78.708328],[-82.56916799999999,78.71138000000013],[-82.45666499999993,78.73082000000011],[-82.43554699999993,78.73165900000009],[-82.40777599999996,78.73082000000011],[-82.35055499999999,78.726089],[-82.27972399999999,78.71775800000006],[-82.25527999999991,78.71665999999999],[-82.23083500000001,78.71775800000006],[-82.22332799999998,78.71971100000002],[-82.21501199999989,78.72303799999997],[-82.22055099999989,78.73220800000001],[-82.23194899999999,78.73637400000013],[-82.25473,78.74081400000011],[-82.27917500000001,78.74414100000007],[-82.31082199999997,78.74693300000013],[-82.39639299999993,78.74914600000011],[-82.45666499999993,78.74914600000011],[-82.48083500000001,78.74832200000014],[-82.50611900000001,78.74581899999998],[-82.52555799999993,78.74220300000013],[-82.54277000000002,78.73719800000009],[-82.564438,78.73275800000005],[-82.61915599999998,78.72804300000001],[-82.66361999999992,78.72804300000001],[-82.75250199999994,78.72970599999996],[-82.781387,78.73109400000004],[-82.80972299999996,78.73414600000012],[-82.82695000000001,78.7374880000001],[-82.84333799999996,78.74220300000013],[-82.91166699999991,78.76638800000012],[-83.06973299999993,78.79220600000008],[-83.108612,78.79664600000007],[-83.21055599999994,78.79887400000007],[-83.22860700000001,78.80415300000004],[-83.25584400000002,78.82998700000007],[-83.25473,78.834991],[-83.24444599999993,78.8394320000001],[-83.2183379999999,78.8435970000001],[-83.1875,78.84721400000006],[-83.08583099999998,78.85554499999995],[-83.05694599999993,78.8560940000001],[-82.991669,78.85554499999995],[-82.81111099999998,78.84803800000003],[-82.67582699999997,78.84220900000003],[-82.65055799999999,78.83888200000007],[-82.62138400000003,78.83749399999999],[-82.46278399999994,78.83332800000011],[-82.42944299999999,78.83332800000011],[-82.28971899999999,78.83720399999999],[-82.25445599999995,78.84054600000007],[-82.11277799999999,78.85748300000012],[-82.07945299999994,78.85971100000006],[-81.947495,78.865814],[-81.91389499999991,78.865814],[-81.76417499999997,78.859985],[-81.74943499999995,78.85803200000004],[-81.74055499999992,78.85525499999994],[-81.76722699999999,78.853317],[-81.82444799999996,78.85386700000004],[-81.83860799999997,78.85137900000007],[-81.833618,78.84664900000001],[-81.82028199999996,78.84526100000011],[-81.74137899999988,78.83915700000011],[-81.71250900000001,78.83970600000004],[-81.69915799999995,78.84275799999995],[-81.66082799999992,78.87776200000002],[-81.65666199999987,78.88388100000009],[-81.65695199999999,78.88832100000008],[-81.66639700000002,78.89553799999999],[-81.68249499999996,78.90026899999992],[-81.73472599999997,78.90637200000009],[-81.75306699999999,78.9122010000001],[-81.75584399999997,78.91804500000012],[-81.69860799999992,78.97387700000007],[-81.69082599999996,78.98027000000002],[-81.68306000000001,78.98442100000011],[-81.553604,79.02415500000001],[-81.48611499999993,79.04165599999999],[-81.47721899999999,79.04721100000006],[-81.48666399999996,79.05247500000007],[-81.50306699999993,79.059143],[-81.521118,79.06109600000013],[-81.54861499999998,79.06135599999999],[-81.61776700000001,79.05108600000005],[-81.86582900000002,79.01361099999997],[-81.91027799999995,79.00499000000008],[-81.92832900000002,79],[-81.96112099999993,78.98692299999999],[-81.97222899999997,78.982483],[-81.97416699999997,78.97943100000003],[-81.99972500000001,78.9602660000001],[-82.09277299999991,78.91832000000011],[-82.11027499999994,78.91360500000008],[-82.34722899999997,78.89444000000009],[-82.50306699999993,78.88275099999998],[-82.55943300000001,78.88472000000002],[-82.68138099999999,78.90331999999995],[-82.81388899999996,78.92303500000014],[-82.839447,78.926376],[-82.92443800000001,78.9349820000001],[-83.06304899999998,78.93969700000014],[-83.12666300000001,78.94108599999993],[-83.26417500000002,78.93914799999999],[-83.51417499999997,78.93054200000006],[-83.57055700000001,78.92997700000006],[-83.63751200000002,78.9308170000001],[-83.69471699999991,78.934708],[-83.78721599999989,78.94247400000006],[-83.81277499999999,78.94581599999998],[-84.03416399999998,78.95665000000002],[-84.16555800000003,78.95694000000003],[-84.20056199999999,78.95721399999996],[-84.25917099999998,78.95942700000012],[-84.328888,78.96527100000014],[-84.36749299999997,78.97248800000006],[-84.38612399999988,78.97776799999997],[-84.42999299999997,78.98776199999998],[-84.47305299999994,78.99552900000009],[-84.57333399999987,79.00999500000012],[-84.65139799999997,79.01943999999997],[-84.67944299999999,79.02165200000007],[-84.72694399999995,79.02777100000009],[-84.74804699999999,79.03193699999997],[-84.766953,79.03720099999998],[-84.77917499999995,79.04664600000001],[-84.78971899999999,79.06414800000005],[-84.78916899999996,79.06944299999998],[-84.78388999999999,79.07443200000012],[-84.65167200000002,79.11469999999997],[-84.54415899999998,79.14137299999999],[-84.5286099999999,79.14332600000006],[-84.50361599999991,79.14444000000009],[-84.47305299999994,79.14305100000007],[-84.16389499999991,79.12414600000011],[-84.135559,79.121918],[-84.07556199999993,79.10443099999992],[-84.0625,79.09054600000002],[-84.04055800000003,79.07544700000005],[-83.99027999999998,79.0516510000001],[-83.95056199999993,79.0435940000001],[-83.89639299999999,79.03804000000014],[-83.74472000000003,79.02804600000007],[-83.60055499999993,79.02526900000004],[-83.504456,79.02360499999998],[-83.474716,79.02415500000001],[-83.45472699999999,79.02554299999997],[-83.386124,79.0394290000001],[-83.36860699999994,79.04443400000014],[-83.35861199999994,79.05081200000012],[-83.37361099999993,79.05636600000014],[-83.39944500000001,79.05970800000006],[-83.41555799999998,79.05998199999999],[-83.43083199999995,79.05831900000004],[-83.46167000000003,79.05220000000003],[-83.49388099999993,79.04332],[-83.521118,79.04136700000004],[-83.54611199999994,79.04248000000013],[-83.70666499999993,79.07777400000003],[-83.97639499999997,79.14109800000011],[-84.00361599999991,79.14860500000009],[-84.02999899999998,79.151657],[-84.02917500000001,79.15693700000003],[-84.01889,79.16137700000007],[-84.00500499999993,79.1660920000001],[-83.95249899999999,79.18026700000001],[-83.93998699999992,79.18553200000008],[-83.93331899999993,79.19192500000003],[-83.941101,79.21638500000006],[-83.95666499999999,79.22192400000006],[-83.97972099999993,79.22164900000007],[-84.01695299999994,79.21304299999997],[-84.04305999999991,79.20304899999996],[-84.05194099999994,79.19802900000008],[-84.06750499999998,79.192474],[-84.08612099999999,79.18803399999996],[-84.12193300000001,79.18470800000011],[-84.15850799999998,79.18330400000013],[-84.193329,79.18304400000011],[-84.30332900000002,79.18664600000005],[-84.32694999999995,79.18858300000011],[-84.32389799999987,79.19470200000012],[-84.31666599999994,79.20054600000014],[-84.31361400000003,79.20664999999997],[-84.335556,79.2522130000001],[-84.34445199999999,79.25804100000005],[-84.36277799999999,79.26499900000005],[-84.40110800000002,79.27526899999998],[-84.428879,79.29026800000003],[-84.452789,79.32887299999999],[-84.45222499999994,79.34165999999999],[-84.44665499999996,79.35386699999992],[-84.44610599999993,79.35887100000008],[-84.48472599999997,79.40637200000015],[-84.50334199999998,79.41304000000014],[-84.58111600000001,79.43386800000002],[-84.60611,79.43803400000013],[-84.660278,79.44413800000012],[-84.70916699999998,79.45166000000006],[-84.82112099999995,79.47303799999997],[-84.88249200000001,79.48609899999991],[-84.89695699999993,79.49247700000006],[-84.96945199999999,79.53749100000005],[-84.9725039999999,79.54220600000008],[-85.02223200000003,79.61109900000002],[-85.028885,79.61581400000006],[-85.05027799999999,79.62164300000006],[-85.06889299999995,79.62608300000005],[-85.25418099999996,79.66720599999996],[-85.3724979999999,79.684418],[-85.49333199999995,79.70054600000003],[-85.55139199999996,79.70582600000012],[-85.61582899999996,79.708328],[-85.68443300000001,79.70915200000013],[-85.76306199999999,79.70555100000007],[-85.94888299999991,79.708328],[-86.20333900000003,79.73580900000007],[-86.38751200000002,79.74748200000005],[-86.41583300000002,79.75054899999998],[-86.44583099999988,79.75416600000011],[-86.47193900000002,79.75972000000013],[-86.48638900000003,79.76361100000003],[-86.49360699999994,79.76832600000006],[-86.50222799999995,79.77526900000004],[-86.47193900000002,79.89054900000002],[-86.46028100000001,79.91970800000001],[-86.45028699999989,79.93109100000004],[-86.43638599999997,79.942474],[-86.42443799999995,79.94802900000008],[-86.389725,79.9580380000001],[-86.36721799999998,79.96276900000004],[-86.30027799999993,79.96859699999999],[-86.26333599999992,79.96914700000002],[-86.23028599999998,79.96804800000001],[-86.08389299999999,79.95748900000001],[-85.88583399999999,79.9410860000001],[-85.81973299999993,79.93858299999994],[-85.78500399999996,79.93803400000002],[-85.71139499999992,79.93748500000004],[-85.65695199999999,79.93803400000002],[-85.519455,79.92498800000004],[-85.4600069999999,79.91081200000008],[-85.41639700000002,79.90138200000001],[-85.38999899999993,79.89749100000012],[-85.36582900000002,79.89637800000003],[-85.308334,79.90054300000003],[-85.28916899999996,79.90498400000013],[-85.27500899999995,79.909424],[-85.26251199999996,79.91499299999998],[-85.25500499999993,79.92082199999999],[-85.271118,79.92387400000007],[-85.44082600000002,79.938309],[-85.64083900000003,79.96276900000004],[-86.19055200000003,80],[-86.30194099999994,79.99832200000009],[-86.34138499999995,79.99693300000007],[-86.41332999999997,79.99803200000008],[-86.44276399999995,79.99971],[-86.46640000000002,80.00387600000005],[-86.48277300000001,80.0086060000001],[-86.56555199999997,80.03581200000013],[-86.57945299999994,80.04304500000012],[-86.64250199999992,80.09803799999997],[-86.65861499999988,80.11775200000005],[-86.65943900000002,80.12803600000007],[-86.65583799999996,80.13526900000011],[-86.51472499999994,80.29914900000011],[-86.49305700000002,80.30442800000009],[-86.46833799999996,80.30859400000003],[-86.43443299999996,80.3124850000001],[-86.34500100000002,80.31915300000003],[-86.11610399999995,80.33360299999998],[-86.07611099999991,80.33360299999998],[-85.89750700000002,80.333054],[-85.74526999999995,80.320267],[-85.71749899999998,80.31637599999993],[-85.67193600000002,80.30693100000008],[-85.61665299999993,80.29887400000013],[-85.50917099999998,80.28581200000008],[-85.47917199999995,80.28276100000005],[-85.35417199999989,80.27304100000015],[-85.29083299999996,80.26860000000005],[-85.256958,80.26721199999997],[-85.09583999999995,80.2622070000001],[-84.9375,80.26721199999997],[-84.898346,80.26944000000009],[-84.77917499999995,80.27249100000012],[-84.70249899999993,80.27331500000008],[-84.589722,80.27360500000009],[-84.19665500000002,80.27137800000003],[-84.0494379999999,80.26776100000012],[-83.989441,80.26443500000005],[-83.92639200000002,80.25972000000002],[-83.81111099999998,80.249146],[-83.78195199999999,80.24581900000004],[-83.71611000000001,80.23387100000002],[-83.62638900000002,80.21360800000014],[-83.56082199999997,80.1958160000001],[-83.54638699999998,80.18942300000015],[-83.47805800000003,80.16442899999998],[-83.46139499999992,80.15914900000007],[-83.42471299999994,80.1483310000001],[-83.40306099999998,80.14221200000009],[-83.24499499999996,80.10359199999994],[-83.13890100000003,80.07832300000013],[-83.02972399999999,80.053314],[-82.89805599999994,80.02526899999998],[-82.80332900000002,80.00637799999998],[-82.73611499999998,79.99247699999995],[-82.60583500000001,79.96443199999999],[-82.28388999999999,79.89305100000007],[-82.15306099999998,79.85887099999997],[-82.10194399999995,79.83970600000004],[-82.09167500000001,79.83471700000007],[-82.06249999999994,79.81608600000004],[-82.04638699999998,79.8016510000001],[-81.976944,79.73580900000007],[-81.981674,79.72387700000007],[-81.978882,79.71832300000011],[-81.91665599999999,79.70332300000013],[-81.85305799999998,79.69358800000003],[-81.79943800000001,79.68664599999994],[-81.76750199999992,79.68498199999993],[-81.73388699999992,79.68637100000012],[-81.68472300000002,79.67581200000006],[-81.6163939999999,79.62330599999996],[-81.61860699999994,79.61831699999999],[-81.62805200000003,79.61470000000003],[-81.6516719999999,79.61026000000004],[-81.67805499999997,79.60720800000013],[-81.68777499999987,79.6080320000001],[-81.69471699999997,79.60971100000006],[-81.70973200000003,79.61554000000012],[-81.73416099999997,79.61970500000012],[-81.74861099999998,79.62109400000008],[-81.76750199999992,79.62052900000009],[-81.777222,79.61914099999996],[-81.78527799999989,79.61499000000009],[-81.78611799999993,79.60914600000007],[-81.78222700000003,79.60497999999995],[-81.76861600000001,79.60026600000003],[-81.75029,79.59471100000013],[-81.72833300000002,79.58970600000009],[-81.70666499999999,79.58665500000006],[-81.67527799999999,79.58499100000006],[-81.63945000000001,79.58499100000006],[-81.60583500000001,79.588593],[-81.57861300000002,79.59304800000001],[-81.56361400000003,79.59776300000004],[-81.54499800000002,79.60914600000007],[-81.50944499999991,79.624146],[-81.49527,79.62942500000003],[-81.47639500000002,79.63415500000002],[-81.45722999999998,79.63693200000012],[-81.424713,79.63665800000001],[-81.36805699999996,79.63443000000007],[-81.27999899999992,79.628311],[-81.25361599999997,79.62469499999997],[-81.01306199999988,79.59887700000002],[-80.69027699999998,79.56860400000005],[-80.63055400000002,79.56414799999999],[-80.598053,79.5660860000001],[-80.589722,79.56805400000002],[-80.591949,79.57360800000004],[-80.60861199999988,79.576096],[-80.62527499999993,79.58082600000006],[-80.641953,79.58804299999997],[-80.63417099999998,79.592758],[-80.61860699999988,79.59721400000012],[-80.598053,79.60137900000012],[-80.56916799999988,79.605255],[-80.50167799999997,79.61192299999999],[-80.100281,79.64444000000015],[-80.05665599999998,79.64694200000002],[-80.02528399999994,79.64721700000007],[-79.972778,79.64444000000015],[-79.93638599999997,79.64444000000015],[-79.90472399999999,79.64694200000002],[-79.89250199999992,79.64915500000001],[-79.76194799999996,79.69581600000004],[-79.75140399999992,79.70138500000002],[-79.76861600000001,79.70193500000005],[-80.041382,79.6974790000001],[-80.35665899999998,79.68525699999998],[-80.389725,79.68331900000004],[-80.43222000000003,79.67776500000002],[-80.47361799999999,79.66970800000007],[-80.51611300000002,79.6644290000001],[-80.61805700000002,79.65416000000005],[-80.65888999999993,79.65248100000002],[-80.79527300000001,79.64804100000003],[-80.82749899999999,79.64833100000004],[-80.910553,79.6519320000001],[-80.94221500000003,79.653595],[-80.95527599999997,79.65860000000004],[-80.95889299999993,79.66499300000004],[-80.97083999999995,79.67137099999997],[-80.97833300000002,79.67303499999997],[-81.07611099999997,79.688873],[-81.17193600000002,79.70332300000013],[-81.22778299999999,79.709427],[-81.29194599999988,79.71360800000008],[-81.385559,79.71360800000008],[-81.42443799999995,79.7127690000001],[-81.51972999999992,79.73082000000011],[-81.56945799999994,79.81971700000008],[-81.58277900000002,79.83692900000011],[-81.58778399999994,79.84166000000005],[-81.59973100000002,79.8519290000001],[-81.608337,79.85859700000003],[-81.63137799999998,79.872208],[-81.651947,79.88275099999998],[-81.65972899999997,79.88859600000006],[-81.66500899999994,79.89776599999993],[-81.66305499999999,79.90304600000002],[-81.64361600000001,79.90998800000011],[-81.54055799999992,79.9227600000001],[-81.51583900000003,79.92498800000004],[-81.41694599999994,79.92719999999997],[-81.402222,79.93248],[-81.40028399999994,79.93775899999997],[-81.42027299999995,79.94358799999998],[-81.55749500000002,79.96081500000003],[-81.589722,79.96249400000005],[-81.63945000000001,79.96220400000004],[-81.64334100000002,79.96220400000004],[-81.710556,79.96470600000009],[-81.74305699999996,79.96638500000012],[-81.83306899999997,79.97387700000002],[-82.00500499999998,79.993042],[-82.16833499999996,80.01361099999997],[-82.191101,80.0186000000001],[-82.28582799999998,80.04609700000009],[-82.34333799999996,80.06387300000006],[-82.35916099999992,80.06915300000009],[-82.61915599999998,80.15054299999997],[-82.94804399999998,80.24748199999999],[-83.12110899999999,80.29275500000006],[-83.16665599999993,80.301376],[-83.18693499999995,80.30664100000007],[-83.20140099999998,80.31330900000006],[-83.20388799999995,80.31805400000007],[-83.19665499999996,80.320831],[-83.16694599999994,80.32693499999999],[-83.13194299999998,80.33055100000007],[-82.94276400000001,80.3455350000001],[-82.85472099999998,80.35081500000001],[-82.78778099999994,80.35220300000009],[-82.70666499999999,80.35276799999997],[-82.57972699999988,80.3583220000001],[-82.27333099999993,80.37747200000007],[-82.03138699999994,80.39833100000004],[-81.987213,80.40026899999998],[-81.89917000000003,80.40165700000011],[-81.88221699999997,80.4019320000001],[-81.67388899999997,80.4060970000001],[-81.33444199999997,80.42053200000004],[-81.20472699999999,80.42720000000003],[-81.07972699999999,80.43609600000013],[-80.98611499999987,80.44358800000009],[-80.83500700000002,80.45277400000003],[-80.66000400000001,80.46081500000008],[-80.48111,80.4624940000001],[-80.412216,80.46054100000015],[-80.36776699999996,80.4622040000001],[-80.33612099999999,80.46581999999995],[-80.318893,80.47053499999998],[-80.30665599999992,80.47526600000009],[-80.29415899999987,80.48664900000011],[-80.297775,80.488876],[-80.31220999999994,80.4916530000001],[-80.34333800000002,80.49414100000007],[-80.35499600000003,80.49803199999997],[-80.35722399999992,80.50138900000007],[-80.22749299999992,80.51971399999996],[-80.19554099999993,80.52360500000003],[-80.15333599999997,80.52638200000013],[-80.11639400000001,80.52777100000014],[-80.05860899999993,80.52720600000009],[-79.94027699999992,80.52886999999993],[-79.558044,80.53637700000007],[-79.49055499999992,80.53970300000009],[-79.33999599999993,80.54998800000004],[-79.23277300000001,80.55331400000006],[-79.19055200000003,80.55386400000009],[-79.011124,80.55331400000006],[-78.81555199999991,80.55581700000005],[-78.59277299999997,80.56219500000003],[-78.46556099999998,80.56387300000011],[-78.34527600000001,80.56442300000015],[-78.09889199999992,80.56248500000004],[-78.06388900000002,80.56469700000008],[-78.03805499999993,80.56721500000003],[-78.01501499999995,80.58665500000001],[-78.01362599999999,80.59109500000005],[-78.01916499999999,80.59443699999997],[-78.03083800000002,80.59610000000009],[-78.08860800000002,80.59693900000008],[-78.35777300000001,80.60165400000011],[-78.74137899999994,80.60914600000001],[-78.851944,80.61248799999998],[-78.92527799999999,80.61665299999999],[-78.98110999999994,80.61608900000004],[-79.114441,80.61248799999998],[-79.25500499999998,80.60582],[-79.34722899999991,80.60108900000006],[-79.39222699999993,80.59971599999994],[-79.56527699999992,80.59610000000009],[-79.63417099999998,80.59553500000004],[-79.86332699999997,80.60304300000007],[-79.93443300000001,80.6060940000001],[-79.96055599999988,80.60803200000004],[-79.96028099999995,80.61470000000003],[-79.90722699999998,80.62387100000001],[-79.84777799999995,80.63192700000008],[-79.55943300000001,80.66998300000006],[-79.35360700000001,80.69664000000012],[-79.291946,80.70387299999999],[-79.17250100000001,80.71304300000003],[-78.99082900000002,80.72970600000008],[-78.80943299999996,80.74693300000013],[-78.62388599999997,80.76914999999997],[-78.58528099999995,80.77221700000007],[-78.50556899999998,80.77748100000008],[-78.23666400000002,80.79332],[-77.894455,80.81330900000012],[-77.80583200000001,80.818604],[-77.73306299999996,80.82554600000009],[-77.63917500000002,80.83027600000014],[-77.28778099999994,80.83526599999999],[-76.92639200000002,80.84193399999998],[-76.84500100000002,80.841095],[-76.729172,80.83804300000008],[-76.68138099999993,80.83859300000012],[-76.59083599999997,80.84275800000012],[-76.55665599999998,80.84637500000008],[-76.51167299999997,80.85443099999998],[-76.48472599999997,80.86554000000001],[-76.4850009999999,80.87109400000003],[-76.49082900000002,80.8749850000001],[-76.52667200000002,80.88638300000008],[-76.62110899999993,80.90081800000002],[-76.65666199999998,80.89804100000015],[-76.699432,80.89137299999999],[-76.73889200000002,80.88832100000002],[-76.79750099999995,80.88610800000009],[-76.84167500000001,80.88554399999998],[-77.16888399999993,80.88693200000006],[-77.20167500000002,80.8877720000001],[-77.30888400000003,80.89305100000007],[-77.42832900000002,80.90304600000002],[-77.45472699999999,80.90525800000006],[-77.5811159999999,80.91137700000007],[-77.76611300000002,80.90693700000008],[-77.98028599999992,80.90109300000006],[-78.421112,80.87942499999991],[-78.83639499999998,80.85386699999998],[-78.86944599999993,80.85220299999997],[-78.88528399999996,80.85359199999999],[-78.896118,80.85470599999996],[-78.908615,80.85887100000014],[-78.92222599999997,80.86608899999999],[-78.93499799999995,80.87553400000002],[-78.93638599999997,80.88136300000008],[-78.93055699999996,80.98193399999997],[-78.928604,80.99054000000007],[-78.839722,81.016098],[-78.79998799999998,81.02638200000007],[-78.7577819999999,81.03553799999997],[-78.63667299999997,81.05859400000003],[-78.52888499999995,81.08194000000009],[-78.50111399999997,81.09165999999999],[-78.45750399999997,81.10775800000005],[-78.42610199999996,81.12081899999998],[-78.41639699999996,81.12525900000014],[-78.39723199999992,81.13749700000005],[-78.39306599999992,81.14276100000001],[-78.40638699999994,81.14498899999995],[-78.46194500000001,81.14749100000006],[-78.47528099999994,81.149719],[-78.47582999999997,81.15248100000008],[-78.47277799999995,81.1583250000001],[-78.46362299999993,81.16081200000002],[-78.43859899999995,81.16470300000009],[-78.41139199999992,81.16747999999995],[-78.29083300000002,81.17469800000015],[-78.25473,81.17776500000008],[-78.2250059999999,81.18193099999996],[-78.15943900000002,81.19386299999996],[-78.05110200000001,81.2185970000001],[-78.03694200000001,81.22331200000013],[-78.016663,81.2327580000001],[-78.00917099999998,81.238586],[-77.97694399999989,81.24914599999994],[-77.87527499999987,81.2727660000001],[-77.85082999999992,81.27720599999998],[-77.612503,81.31887799999998],[-77.5769499999999,81.32249499999995],[-77.50306699999993,81.32832300000007],[-77.36639400000001,81.33610500000003],[-77.233612,81.35108900000012],[-77.11694299999994,81.367752],[-76.95527599999997,81.39387499999992],[-76.76501499999995,81.42858899999999],[-76.74861099999998,81.4327550000001],[-76.74526999999995,81.43914800000005],[-76.761124,81.4427490000001],[-76.77778599999988,81.44442700000002],[-76.80332899999996,81.44552600000003],[-76.85583500000001,81.44552600000003],[-76.95111099999997,81.44053600000012],[-77.02860999999996,81.43331900000004],[-77.20861799999994,81.40942400000006],[-77.26445000000001,81.40081800000013],[-77.41722099999987,81.380539],[-77.571396,81.36665299999999],[-77.60972600000002,81.36442599999992],[-77.8291779999999,81.34248400000007],[-77.89611799999994,81.33554100000009],[-78.17416399999996,81.30053700000002],[-78.22833300000002,81.29165600000005],[-78.27362099999993,81.28359999999998],[-78.29222099999987,81.27832000000012],[-78.30555700000002,81.2727660000001],[-78.32583599999992,81.26138300000014],[-78.351944,81.2502750000001],[-78.37027,81.2452550000001],[-78.41000400000001,81.23637400000013],[-78.43388399999992,81.23193400000014],[-78.487213,81.22303800000003],[-78.60499600000003,81.2063750000001],[-78.65249599999993,81.19720500000005],[-78.67527799999993,81.19192500000003],[-78.70195000000001,81.18165599999998],[-78.721115,81.17221100000006],[-78.72833300000002,81.16638200000006],[-78.75111400000003,81.14166300000011],[-78.75418100000002,81.13581800000003],[-78.74583399999995,81.12915000000004],[-78.71665999999999,81.12330600000001],[-78.69055200000003,81.12164300000012],[-78.69082599999996,81.11943100000002],[-78.81750499999993,81.10609399999998],[-78.89501999999993,81.09899900000005],[-78.916946,81.09803799999992],[-78.94137599999993,81.10108899999994],[-78.96362299999998,81.10775800000005],[-79.01501499999995,81.11553999999995],[-79.075287,81.12275700000009],[-79.16278099999994,81.13220199999995],[-79.21806299999997,81.136932],[-79.24276700000001,81.13998400000008],[-79.39917000000003,81.17469800000015],[-79.46362299999998,81.19331399999999],[-79.48611499999998,81.19497700000011],[-79.50167799999997,81.19358800000009],[-79.49943499999995,81.18997200000007],[-79.491669,81.18609599999996],[-79.47582999999997,81.180542],[-79.275284,81.12359600000002],[-79.21888699999994,81.11109900000008],[-79.17250100000001,81.10386699999998],[-79.08883700000001,81.09475700000007],[-79.073624,81.09082000000012],[-79.06361399999992,81.08554100000015],[-79.07278399999996,81.08082600000012],[-79.087784,81.07666],[-79.14222699999999,81.06915300000009],[-79.226944,81.06303400000007],[-79.25527999999991,81.05886800000013],[-79.30526699999996,81.02998400000001],[-79.31582600000002,81.02388000000013],[-79.32362399999994,81.018326],[-79.33666999999997,81.0086060000001],[-79.343887,80.99832200000003],[-79.33694500000001,80.99220300000002],[-79.32112099999989,80.98858600000005],[-79.29138199999989,80.984985],[-79.25834700000001,80.98442100000005],[-79.20527599999997,80.98776200000009],[-79.18472300000002,80.98637400000001],[-79.16471899999999,80.98304700000006],[-79.15888999999999,80.97776800000008],[-79.15834000000001,80.97276300000004],[-79.16528299999993,80.9666600000001],[-79.265289,80.92414900000006],[-79.60082999999992,80.82443200000012],[-79.61805699999996,80.81944299999998],[-79.883621,80.7833250000001],[-80.06555200000003,80.75972000000013],[-80.24749800000001,80.73692299999999],[-80.51112399999994,80.70582600000006],[-80.651947,80.69192500000008],[-80.720551,80.68414299999995],[-80.85555999999997,80.66331500000007],[-80.91944899999993,80.65554800000012],[-80.95666499999999,80.65193200000004],[-81.33639499999992,80.62330600000013],[-81.53332499999999,80.60720800000007],[-81.57556199999999,80.60415599999999],[-81.80888400000003,80.59304800000001],[-81.96611000000001,80.57971200000003],[-82.35388199999994,80.55636599999997],[-82.43499800000001,80.55304000000012],[-82.79888900000003,80.53942899999998],[-82.88110399999994,80.53665200000006],[-82.95639,80.53637700000007],[-83.02749599999993,80.53858900000012],[-83.09666400000003,80.54165600000005],[-83.1519469999999,80.54637100000008],[-83.165009,80.55192599999998],[-83.1702729999999,80.56414799999993],[-83.16805999999991,80.57666000000012],[-83.16528299999993,80.5894320000001],[-83.16139199999986,80.60108900000006],[-83.15611299999995,80.60664400000013],[-83.14666699999998,80.61219800000015],[-83.09695399999998,80.63943500000005],[-83.07806399999993,80.64498900000007],[-83.05638099999999,80.64915499999995],[-82.773056,80.68664600000011],[-82.52749599999999,80.70332300000013],[-82.43194599999998,80.70887800000003],[-82.25083899999993,80.71638500000012],[-82.21639999999996,80.71914700000002],[-82.13583399999987,80.72943100000009],[-82.02500900000001,80.74664300000006],[-81.94833399999993,80.75915500000008],[-81.90861499999994,80.76776100000001],[-81.76278699999989,80.81080600000013],[-81.758896,80.81303400000007],[-81.76750199999992,80.82138100000009],[-81.943604,80.83305400000012],[-81.96112099999993,80.83305400000012],[-81.99610899999993,80.83027600000014],[-82.05221599999993,80.822769],[-82.0997309999999,80.81359900000012],[-82.146118,80.80358900000004],[-82.19387799999998,80.79664600000007],[-82.33222999999998,80.78137200000015],[-82.51306199999993,80.76304600000014],[-82.52610799999997,80.7527770000001],[-82.53582799999987,80.74720800000011],[-82.54333499999996,80.74443100000002],[-82.56723,80.74081400000006],[-82.60166900000002,80.73803699999996],[-82.94055199999997,80.71443199999999],[-83.31193499999995,80.68775900000003],[-83.35694899999993,80.68553199999997],[-83.51611300000002,80.70138499999996],[-83.54110700000001,80.704163],[-83.54722600000002,80.70694000000009],[-83.569458,80.73915099999999],[-83.5625,80.74386600000003],[-83.52972399999999,80.74748200000005],[-83.45666499999999,80.75109900000001],[-83.42250099999995,80.7538760000001],[-83.39138799999995,80.7580410000001],[-83.26194799999996,80.78637700000002],[-83.13305700000001,80.8188780000001],[-83.12027,80.82331799999997],[-83.13249200000001,80.828598],[-83.158051,80.83360300000004],[-83.19110099999995,80.83581500000014],[-83.256958,80.83859300000012],[-83.29722599999997,80.83610499999998],[-83.32333399999993,80.8316650000001],[-83.32917799999996,80.82832300000001],[-83.33195499999994,80.82388300000014],[-83.353882,80.81359900000012],[-83.38137799999998,80.80386400000003],[-83.40722699999998,80.79942299999993],[-83.49333200000001,80.78776600000003],[-83.58721899999989,80.77526900000004],[-83.61054999999993,80.77165200000007],[-83.63082899999995,80.76693700000004],[-83.645554,80.76165800000007],[-83.64916999999997,80.75555400000002],[-83.65888999999987,80.751938],[-83.6677699999999,80.75],[-83.69665500000002,80.74664300000006],[-83.712784,80.74775700000009],[-83.82749899999993,80.76138300000002],[-83.85916099999997,80.75915500000008],[-83.86389200000002,80.75749200000013],[-83.83639499999998,80.71971099999996],[-83.82167099999998,80.70582600000006],[-83.81249999999994,80.69831800000009],[-83.80139199999996,80.69192500000008],[-83.78306599999996,80.68414299999995],[-83.75723299999993,80.66970800000001],[-83.73443600000002,80.65416000000005],[-83.72332799999992,80.6438750000001],[-83.72000099999991,80.63665800000001],[-83.71972699999998,80.63081399999999],[-83.73582499999992,80.61303700000008],[-83.77917500000001,80.57083100000011],[-83.79472399999997,80.56025700000004],[-83.82112099999995,80.55053699999996],[-83.84056099999987,80.5455320000001],[-83.87110899999993,80.5413670000001],[-83.93472300000002,80.53442400000012],[-83.97332799999998,80.53193700000003],[-84.31332399999991,80.51361100000003],[-84.381104,80.51220700000005],[-84.48971599999993,80.51443499999999],[-84.55139200000002,80.51776100000006],[-84.689438,80.52499400000005],[-84.76362599999999,80.52581800000002],[-84.84666400000003,80.52331500000003],[-84.89056399999998,80.52110299999998],[-84.964447,80.51443499999999],[-85.027222,80.50721700000003],[-85.066956,80.50526400000007],[-85.23277299999995,80.50888100000003],[-85.33473199999997,80.51361100000003],[-85.36665299999999,80.51748700000013],[-85.42582699999997,80.52304100000009],[-85.46221899999995,80.52499400000005],[-85.59472700000003,80.52915999999993],[-85.80943300000001,80.53193700000003],[-85.8641659999999,80.53553800000009],[-85.86582900000002,80.5413670000001],[-85.81277499999993,80.55914300000006],[-85.70584100000002,80.58970600000004],[-85.68916299999995,80.59387200000015],[-85.66500899999994,80.59860199999997],[-85.61305199999998,80.60636899999997],[-85.57194500000003,80.61526500000008],[-85.56471299999993,80.61943100000013],[-85.59445199999993,80.6202550000001],[-85.63639799999999,80.61914100000013],[-85.69471699999997,80.61360200000013],[-85.74471999999992,80.60636899999997],[-85.79305999999985,80.59693900000008],[-85.85472099999998,80.58221400000014],[-85.889725,80.57304400000004],[-85.92527799999999,80.56248500000004],[-85.95060699999999,80.55294799999996],[-85.95666499999993,80.54832500000009],[-85.98277300000001,80.53749100000005],[-86.01194799999996,80.53332499999993],[-86.03721599999994,80.53082300000005],[-86.08084099999996,80.52832000000006],[-86.14834599999995,80.53166200000004],[-86.17749000000003,80.53414900000013],[-86.42832900000002,80.56025700000004],[-86.63999899999993,80.583054],[-86.71806299999997,80.59304800000001],[-86.7391659999999,80.597488],[-86.74499500000002,80.60304300000007],[-86.73249800000002,80.61526500000008],[-86.68028299999997,80.65498400000001],[-86.66000399999996,80.66609199999999],[-86.63806199999999,80.67665100000005],[-86.51472499999994,80.72943100000009],[-86.49777199999994,80.7352600000001],[-86.46611000000001,80.74552900000009],[-86.41000400000001,80.76081800000003],[-86.33833300000003,80.77554299999997],[-86.24471999999997,80.79414400000013],[-86.22555499999993,80.799149],[-86.17443800000001,80.81442300000009],[-86.05027799999999,80.85664400000007],[-85.96417199999996,80.88693200000006],[-85.846115,80.9285890000001],[-85.82833900000003,80.93414300000012],[-85.77416999999997,80.94886800000006],[-85.69860799999992,80.96276900000004],[-85.60583500000001,80.97581500000013],[-85.556107,80.98193399999997],[-85.00306699999987,81.02832000000001],[-84.928879,81.03082299999994],[-84.72666900000002,81.0310970000001],[-84.40499899999992,81.04386900000009],[-84.36833200000001,81.04609700000003],[-84.20666499999993,81.06053199999997],[-84.1199949999999,81.06749000000013],[-84.02500900000001,81.070831],[-83.90805099999994,81.07138100000003],[-83.82362399999994,81.07360800000009],[-83.52999899999992,81.09027100000014],[-83.31138599999997,81.10331700000012],[-83.15055799999999,81.12052900000015],[-83.12332200000003,81.12303200000008],[-83.05332899999996,81.12330600000001],[-82.943604,81.12081899999998],[-82.86944599999993,81.12136800000007],[-82.82640100000003,81.12303200000008],[-82.78500400000001,81.12553400000002],[-82.76028399999996,81.12915000000004],[-82.73889199999996,81.13388099999997],[-82.70722999999998,81.14444000000003],[-82.68832399999997,81.1483310000001],[-82.64416499999993,81.15165700000011],[-82.59916699999997,81.15277100000009],[-82.53138699999994,81.14999399999999],[-82.50306699999993,81.14776600000005],[-82.46665999999993,81.1483310000001],[-82.37222300000002,81.17469800000015],[-82.364441,81.17942800000003],[-82.38999899999999,81.18026699999996],[-82.420837,81.17942800000003],[-82.48416099999997,81.16998300000012],[-82.52305599999994,81.16638200000006],[-82.56527699999992,81.16609200000005],[-82.665009,81.17442299999999],[-82.82806399999998,81.17330899999996],[-82.86665299999993,81.16970800000013],[-82.89416499999999,81.16526800000008],[-82.926941,81.16110200000003],[-82.96278399999994,81.1583250000001],[-83.14973399999991,81.15138200000013],[-83.45333899999997,81.13220199999995],[-83.75750700000003,81.11331200000001],[-84.116104,81.0977630000001],[-84.37277199999994,81.09220900000008],[-84.58555599999994,81.08638000000008],[-84.79750099999995,81.07832300000013],[-85.06555199999991,81.06637599999999],[-85.2119449999999,81.05693100000008],[-85.25,81.05525200000011],[-85.291382,81.05470300000013],[-85.40444899999994,81.05775500000004],[-85.48277300000001,81.05859400000003],[-85.57250999999997,81.05664100000007],[-85.68167099999994,81.0494230000001],[-85.75556899999998,81.04136700000004],[-85.81777999999997,81.03276100000011],[-85.98860200000001,81.00665300000014],[-86.14334099999991,80.97831700000006],[-86.30972300000002,80.94081100000005],[-86.351944,80.93054200000006],[-87.061935,80.72747800000013],[-87.07640100000003,80.7227630000001],[-87.083618,80.7169340000001],[-87.07907899999998,80.7070240000001],[-87.08029199999999,80.69914200000005],[-87.12138399999992,80.67747500000002],[-87.18055700000002,80.64915499999995],[-87.21501199999994,80.63832100000008],[-87.24055499999997,80.63415500000002],[-87.273056,80.63081399999999],[-87.31500199999994,80.62942499999997],[-87.458054,80.62776200000008],[-87.48971599999987,80.62747200000001],[-87.55943300000001,80.62747200000001],[-87.59472699999998,80.62858600000004],[-87.62805199999997,80.63220200000006],[-87.77722199999994,80.64888000000013],[-87.86416600000001,80.659424],[-87.95472699999988,80.67164599999995],[-88.139725,80.68525699999992],[-88.17721599999993,80.68692000000004],[-88.19610599999999,80.688583],[-88.22222899999997,80.69108599999998],[-88.34889199999992,80.70860299999998],[-88.40666199999993,80.7169340000001],[-88.48860199999996,80.73193400000002],[-88.566956,80.74859600000002],[-88.70611600000001,80.77276600000005],[-88.96749899999986,80.80859400000008],[-89.03416399999998,80.81637600000005],[-89.12582399999997,80.82582100000008],[-89.29055799999998,80.84942600000011],[-89.33473199999992,80.85748300000006],[-89.38249200000001,80.86970500000001],[-89.398056,80.876083],[-89.45056199999993,80.90332000000012],[-89.46221899999995,80.90998800000006],[-89.46611000000001,80.914154],[-89.46221899999995,80.91914400000002],[-89.4427639999999,80.92359900000002],[-89.38082899999989,80.93304400000011],[-89.23527499999994,80.94831800000003],[-89.18638599999997,80.95304899999996],[-88.90556300000003,80.97776800000008],[-88.858612,80.98136899999997],[-88.766861,80.98680100000001],[-88.59028599999999,80.99636800000002],[-88.51390100000003,80.99832200000003],[-88.28332499999999,81.0022130000001],[-88.08972199999994,81.003601],[-88.01139799999999,81.00332600000002],[-87.82667499999997,80.99803200000002],[-87.75500499999998,80.99498000000011],[-87.68943799999994,80.990814],[-87.62805199999997,80.98471100000006],[-87.59750400000001,80.98082],[-87.52416999999991,80.97720300000003],[-87.44638099999997,80.97692899999993],[-87.27944899999994,80.98193399999997],[-87.15943900000002,80.98692299999993],[-87.11971999999997,80.98970000000003],[-87.08917200000002,80.99414100000013],[-87.06471299999998,80.99887100000001],[-87.03056299999997,81.00193800000011],[-86.9830629999999,81.00387600000005],[-86.94610599999999,81.00416600000005],[-86.75500499999998,81.00109900000012],[-86.71167000000003,81.00248700000003],[-86.67193600000002,81.00526400000012],[-86.635559,81.00943000000007],[-86.541946,81.02026400000011],[-86.41944899999999,81.03610200000014],[-86.06111099999998,81.08276400000005],[-85.91639699999996,81.10498000000001],[-85.91639699999996,81.1102600000001],[-85.90722700000003,81.11387599999995],[-85.88751200000002,81.11886600000003],[-85.56277499999999,81.17942800000003],[-85.48306300000002,81.19274899999999],[-85.42527799999993,81.20166000000006],[-85.29750099999995,81.2185970000001],[-85.22193900000002,81.22637900000007],[-85.02027899999996,81.24498000000006],[-84.97639499999997,81.24859600000013],[-84.87638899999996,81.25471500000015],[-84.83250399999997,81.258331],[-84.80249000000003,81.26165800000012],[-84.77610800000002,81.26609799999994],[-84.73388699999998,81.28109700000005],[-84.73554999999999,81.28553799999997],[-84.745834,81.28942900000004],[-84.89999399999994,81.30497700000001],[-84.93666099999996,81.30775500000004],[-84.97555499999999,81.30748],[-85.02917500000001,81.30581700000005],[-85.27917499999995,81.28997800000013],[-85.36138899999997,81.28276100000005],[-85.76834099999996,81.24470500000007],[-85.95056199999999,81.2247010000001],[-86.01834100000002,81.21582000000001],[-86.07749899999993,81.20748900000007],[-86.15417499999995,81.19331399999999],[-86.22500600000001,81.17387400000001],[-86.24082900000002,81.16914399999996],[-86.25695799999994,81.16276600000003],[-86.2994379999999,81.14860500000003],[-86.33833300000003,81.138596],[-86.40499899999998,81.12970000000007],[-86.43804899999992,81.12608300000011],[-86.47277799999989,81.12275700000009],[-86.521118,81.11970499999995],[-86.65083300000003,81.11581400000011],[-86.95639,81.09942600000005],[-87.11138899999992,81.0877690000001],[-87.29722599999997,81.07693500000005],[-87.63751200000002,81.059418],[-87.678879,81.05859400000003],[-87.72000099999991,81.059418],[-87.841385,81.06275900000003],[-88.0625,81.06999200000001],[-88.21777299999985,81.07138100000003],[-88.33999599999999,81.06971700000003],[-88.43499799999995,81.06414800000005],[-88.57167099999992,81.05470300000013],[-88.65834000000001,81.051376],[-88.74082899999996,81.04971300000011],[-88.88999899999993,81.05192600000004],[-88.96472199999994,81.0494230000001],[-89.041672,81.04109199999999],[-89.210556,81.02665700000006],[-89.25556899999998,81.02388000000013],[-89.34167500000001,81.02026400000011],[-89.629166,81.00915500000002],[-89.74665800000002,81.00888100000009],[-89.78750599999995,81.00972000000007],[-89.82084700000001,81.01081799999997],[-89.87388599999997,81.016388],[-90.01194799999996,81.03305100000011],[-90.06361400000003,81.03970299999997],[-90.0952759999999,81.04470800000007],[-90.14917000000003,81.05497700000006],[-90.19776899999988,81.06971700000003],[-90.21000700000002,81.07499700000011],[-90.33805799999993,81.15165700000011],[-90.351944,81.16747999999995],[-90.32556199999993,81.18193099999996],[-90.277222,81.19720500000005],[-90.10221899999999,81.23027000000013],[-90.04305999999997,81.23942600000004],[-90.011124,81.24192800000014],[-89.972778,81.24275200000011],[-89.87054399999994,81.24220300000013],[-89.74610899999999,81.236649],[-89.66915899999987,81.21804800000012],[-89.63500999999991,81.21220399999993],[-89.573059,81.20694000000015],[-89.53500400000001,81.2061000000001],[-89.491104,81.2063750000001],[-89.4472199999999,81.20832800000005],[-89.35722399999997,81.2144320000001],[-89.281387,81.22164900000001],[-89.13667299999997,81.238876],[-89.08833300000003,81.24247700000006],[-89.04444899999999,81.24275200000011],[-88.98222399999997,81.24192800000014],[-88.95417800000001,81.24275200000011],[-88.94415299999997,81.24414100000007],[-88.93582199999997,81.24775699999998],[-88.9497219999999,81.253601],[-88.979446,81.258331],[-89.16221599999994,81.25582900000012],[-89.19860799999987,81.25332600000013],[-89.26501499999995,81.24443100000013],[-89.30722000000003,81.24054000000007],[-89.33528099999995,81.24275200000011],[-89.44360399999994,81.26054399999998],[-89.68777499999999,81.28997800000013],[-89.77500899999995,81.29637100000008],[-89.86805699999996,81.30609099999998],[-89.89862099999993,81.31053199999991],[-89.91722099999987,81.31442299999998],[-89.950287,81.32415800000007],[-89.95249899999988,81.32943700000004],[-89.94055200000003,81.33332800000011],[-89.9163969999999,81.336929],[-89.88221699999997,81.34027100000009],[-89.702225,81.35026600000003],[-89.62721299999998,81.35664400000002],[-89.24249299999997,81.42303500000003],[-89.05915800000002,81.45555100000007],[-88.92832899999996,81.48553500000014],[-88.90943900000002,81.49081400000011],[-88.84695399999998,81.49971000000005],[-88.71583599999997,81.51304599999997],[-88.54527299999995,81.52526900000004],[-88.49499500000002,81.52720600000009],[-88.406113,81.52832000000006],[-88.37110899999999,81.52693199999999],[-88.16139199999992,81.53027300000002],[-88.02999899999998,81.53581200000002],[-87.98416099999997,81.53581200000002],[-87.95973200000003,81.53471400000012],[-87.939438,81.53166199999998],[-87.89369999999997,81.52471200000014],[-87.80139199999996,81.51554899999996],[-87.67944299999994,81.51388500000013],[-87.49027999999998,81.50888099999997],[-87.43138099999993,81.50471500000009],[-87.39889499999998,81.50082400000002],[-87.34306300000003,81.49275200000005],[-87.31111099999998,81.488876],[-87.27667200000002,81.48580900000007],[-87.25140399999992,81.48748800000004],[-87.24471999999997,81.49026500000014],[-87.28639199999992,81.50555400000007],[-87.28832999999997,81.50610400000011],[-87.31555199999997,81.51332100000002],[-87.37860099999989,81.51721200000009],[-87.48916600000001,81.52331500000003],[-87.64584400000001,81.52748099999991],[-87.72166400000003,81.53221100000013],[-87.75195299999996,81.53526300000004],[-87.91500899999994,81.55276500000008],[-88.279449,81.57943699999998],[-88.30638099999993,81.58137499999992],[-88.35221899999999,81.57971200000003],[-88.39222699999999,81.57777400000009],[-88.44694499999997,81.57222000000007],[-88.55221599999999,81.55886800000002],[-88.64222699999993,81.5516510000001],[-88.66944899999999,81.55053700000013],[-88.76916499999999,81.55108600000011],[-88.84999099999999,81.55053700000013],[-88.90028399999989,81.54832500000009],[-88.99804699999999,81.54054300000013],[-89.07305899999994,81.53221100000013],[-89.14584400000001,81.52304100000009],[-89.28250099999991,81.50526400000001],[-89.54833999999988,81.47720300000015],[-89.585556,81.47303799999997],[-89.71028099999995,81.45526100000006],[-90.01139799999993,81.41693099999998],[-90.37083399999995,81.37525900000009],[-90.44305399999996,81.36665299999999],[-90.46749899999992,81.367752],[-90.50056499999994,81.37136800000002],[-90.53582799999998,81.37692300000009],[-90.55332900000002,81.38499500000006],[-90.525284,81.38859600000012],[-90.51722699999993,81.38916000000006],[-90.478882,81.39444000000015],[-90.48138399999999,81.39665200000002],[-90.48777799999993,81.39860499999998],[-90.516953,81.40248100000002],[-90.64361600000001,81.416382],[-90.67832899999996,81.41748000000013],[-90.74665800000002,81.42221100000006],[-90.77999899999998,81.42553700000008],[-90.81138599999991,81.42997700000006],[-90.84111000000001,81.43553199999997],[-90.85417199999995,81.44053600000012],[-90.85665899999992,81.44413800000007],[-90.85388199999994,81.45082100000008],[-90.84834299999994,81.45498700000013],[-90.80082699999997,81.46499599999999],[-90.770554,81.46971100000002],[-90.58306900000002,81.4974820000001],[-90.54028299999999,81.50166300000001],[-90.31221,81.53137199999998],[-90.1305539999999,81.56442300000015],[-89.87470999999994,81.599152],[-89.79750099999995,81.60247800000002],[-89.67443800000001,81.60165400000005],[-89.63249200000001,81.60470600000002],[-89.59750399999996,81.61415100000005],[-89.58500699999996,81.61970500000007],[-89.58500699999996,81.62580900000006],[-89.60194399999989,81.62776200000002],[-89.79888900000003,81.62997400000006],[-89.86805699999996,81.63026400000012],[-89.91416900000002,81.628311],[-89.96221899999995,81.62553400000007],[-90.06945799999994,81.63360600000004],[-90.11158,81.65674600000011],[-90.20472699999993,81.68637100000007],[-90.27139299999999,81.6974790000001],[-90.29695099999998,81.69859300000007],[-90.33029199999999,81.69609099999997],[-90.35305799999998,81.69053600000007],[-90.36082499999992,81.68525700000009],[-90.35527000000002,81.67359900000008],[-90.33721899999995,81.6624910000001],[-90.35472099999998,81.65138200000001],[-90.511124,81.65776100000005],[-90.60472099999993,81.66470300000015],[-90.63890100000003,81.66804500000006],[-90.678879,81.66886900000003],[-90.71888699999994,81.6666560000001],[-90.73472599999997,81.66081200000008],[-90.74221799999998,81.65554800000007],[-90.76362599999993,81.64553799999999],[-90.77972399999999,81.641098],[-90.803879,81.63610800000009],[-90.83473199999997,81.63136300000008],[-90.87805200000003,81.62747200000001],[-90.92388899999997,81.62525900000003],[-90.96694899999994,81.62109400000003],[-90.99110399999995,81.61608899999999],[-91.006958,81.59887699999996],[-91.00334199999992,81.59220900000003],[-90.98860200000001,81.57943699999998],[-90.98860200000001,81.55775499999999],[-91.07167099999998,81.53720099999998],[-91.091949,81.53387499999997],[-91.104446,81.53442400000012],[-91.11389199999996,81.53997800000008],[-91.23693800000001,81.54332000000005],[-91.31388899999996,81.53414900000007],[-91.40139799999997,81.52638200000013],[-91.44638099999997,81.524429],[-91.46333299999998,81.526093],[-91.46777299999991,81.52720600000009],[-91.45249899999993,81.53166199999998],[-91.428604,81.53665200000006],[-91.41111799999999,81.54193100000003],[-91.40638699999994,81.54776000000004],[-91.44415300000003,81.5836030000001],[-91.47444199999995,81.58888200000007],[-91.65417500000001,81.60582],[-91.74722300000002,81.60914600000001],[-91.85722399999986,81.61276200000009],[-91.87832600000002,81.61415100000005],[-91.900284,81.61692800000014],[-91.93859900000001,81.62553400000007],[-91.94860799999992,81.63108800000009],[-91.95666499999999,81.65860000000004],[-91.949432,81.6622010000001],[-91.926941,81.66499299999998],[-91.90222199999994,81.66693100000009],[-91.86776700000001,81.66331500000007],[-91.83889799999986,81.65860000000004],[-91.80110199999996,81.65860000000004],[-91.77084400000001,81.66331500000007],[-91.73721299999994,81.68692000000004],[-91.72582999999992,81.70665000000002],[-91.72361799999987,81.72164900000007],[-91.48554999999999,81.76998900000012],[-91.386124,81.77388000000002],[-91.35139500000002,81.77026400000011],[-91.28750600000001,81.76193199999994],[-91.25500499999998,81.75915500000008],[-91.2125089999999,81.75943000000007],[-91.0533289999999,81.76165800000001],[-91.03443900000002,81.76388500000007],[-91.03332499999999,81.76776099999995],[-91.05749499999996,81.77276600000005],[-91.09056099999992,81.77720600000004],[-91.11776699999996,81.78442400000006],[-91.14056399999998,81.79193099999998],[-91.15249599999993,81.79803500000003],[-91.14723200000003,81.80386400000003],[-91.13751199999996,81.80859400000008],[-91.10110499999996,81.8188780000001],[-91.05166599999995,81.82887299999999],[-91.00111399999997,81.83276400000005],[-90.85221899999999,81.84248399999996],[-90.72749299999998,81.841095],[-90.70417800000001,81.84359700000005],[-90.68998699999992,81.84860200000008],[-90.68637799999999,81.85396600000001],[-90.67832899999996,81.85859700000003],[-90.63500999999997,81.86886600000003],[-90.61000100000001,81.87387100000007],[-90.56527699999987,81.87803600000007],[-90.43666100000002,81.88749700000005],[-90.33805799999993,81.89305100000007],[-90.24527,81.89610299999998],[-90.154449,81.89665200000013],[-89.99082899999996,81.90554800000007],[-89.78332499999993,81.91720600000008],[-89.73582499999998,81.91748000000001],[-89.70083599999998,81.91554300000013],[-89.676941,81.9102630000001],[-89.68305199999998,81.89943700000015],[-89.6824949999999,81.883331],[-89.64944500000001,81.86331200000006],[-89.62998999999996,81.85636900000003],[-89.46139499999998,81.81805400000013],[-89.425003,81.81526200000002],[-89.35638399999993,81.81109600000013],[-89.24472000000003,81.84637500000002],[-89.22721899999999,81.85220300000015],[-89.20322399999998,81.87803600000007],[-89.19923399999999,81.88153799999992],[-89.19905900000003,81.88520800000003],[-89.21321899999998,81.88838200000009],[-89.32806399999993,81.90220600000009],[-89.36721799999992,81.90554800000007],[-89.39750699999996,81.90942400000012],[-89.41915899999998,81.91554300000013],[-89.41694599999994,81.92581200000001],[-89.3977809999999,81.93081700000005],[-89.37165800000002,81.93580600000001],[-89.33889799999997,81.94026200000008],[-89.28889500000002,81.943039],[-89.24972499999996,81.94108600000004],[-89.15739399999995,81.92836800000009],[-89.15621899999991,81.92520100000007],[-89.15255699999994,81.92137100000008],[-89.13305700000001,81.91853300000008],[-89.07472199999995,81.91165200000006],[-89.03332499999999,81.91220100000004],[-89.00723299999987,81.91554300000013],[-88.98971599999993,81.92109700000015],[-88.98638899999997,81.94497699999994],[-88.99276700000001,81.95138500000007],[-89.0119479999999,81.9586030000001],[-89.04834,81.97804300000007],[-89.05444299999999,81.98748799999998],[-89.04110699999995,81.99304199999995],[-89.02111799999994,81.99803200000002],[-88.96389799999997,82.00804100000005],[-88.77305599999994,82.03942900000004],[-88.62554899999998,82.06275900000003],[-88.58972199999994,82.066666],[-88.54305999999991,82.07054099999999],[-88.44305400000002,82.07499700000005],[-88.29666099999992,82.08027600000003],[-88.25,82.08082600000006],[-88.14500399999997,82.086929],[-88.11361699999992,82.09054599999996],[-88.09973100000002,82.09304800000007],[-88.09500100000002,82.09637499999997],[-88.08528100000001,82.10137900000012],[-88.07556199999993,82.10498000000001],[-88.03832999999997,82.1038670000001],[-87.91194200000001,82.09082000000006],[-87.71833799999996,82.08387800000003],[-87.70222499999994,82.086929],[-87.6663969999999,82.08943199999999],[-87.64195299999994,82.09027100000014],[-87.59973099999996,82.089157],[-87.50140399999998,82.08415200000013],[-87.40222199999994,82.07388300000008],[-87.35278299999993,82.06721500000009],[-87.33361799999989,82.06330900000006],[-87.27166699999998,82.04775999999993],[-87.23055999999997,82.03692600000005],[-87.195831,82.02638200000001],[-87.18360899999993,82.02249100000012],[-87.1744379999999,82.01470899999998],[-87.17332499999998,82.01110799999992],[-87.1786039999999,82.00776700000011],[-87.19776899999994,82.0022130000001],[-87.23277300000001,81.99331699999999],[-87.25805700000001,81.9894260000001],[-87.29998799999998,81.97915599999999],[-87.314438,81.97387700000002],[-87.30943299999996,81.96748400000001],[-87.26583900000003,81.95887800000014],[-87.16915899999998,81.94552600000009],[-87.10166900000002,81.93775900000014],[-87.06332399999991,81.93441800000011],[-86.939438,81.91886899999997],[-86.87721299999998,81.90942400000012],[-86.82888799999995,81.89749100000006],[-86.804169,81.89305100000007],[-86.76834100000002,81.89027399999998],[-86.72666900000002,81.8919370000001],[-86.726944,81.89721700000013],[-86.73416099999992,81.90277100000014],[-86.74583399999995,81.90664700000002],[-86.83473200000003,81.92776500000014],[-86.86361699999992,81.93359399999997],[-86.91944899999999,81.94274899999999],[-87.066101,81.95498700000007],[-87.09805299999994,81.95832800000011],[-87.12721299999993,81.96388200000007],[-87.13027999999986,81.968323],[-87.00140399999998,82.03610200000008],[-86.987213,82.03997800000002],[-86.93167099999994,82.04942300000005],[-86.89250199999998,82.0541530000001],[-86.84333799999996,82.05720500000001],[-86.79194599999994,82.05802900000015],[-86.58361799999994,82.05386399999998],[-86.35638399999999,82.05358899999999],[-86.27806099999998,82.05081200000006],[-86.23916600000001,82.04859900000008],[-86.202789,82.04553199999998],[-86.16915899999992,82.0416560000001],[-86.01611299999996,82.01666300000005],[-85.960556,82.00749200000007],[-85.91444399999995,81.99748199999999],[-85.81500199999999,81.97387700000002],[-85.76750199999992,81.96192899999994],[-85.73138399999988,81.949997],[-85.62887599999999,81.9160920000001],[-85.46722399999999,81.86720300000013],[-85.42250100000001,81.85748300000006],[-85.37943999999999,81.85693400000008],[-85.37165800000002,81.859711],[-85.37388599999997,81.863876],[-85.38583399999993,81.8749850000001],[-85.398056,81.88108800000003],[-85.44193999999999,81.89387500000004],[-85.46945199999988,81.899719],[-85.566101,81.92498800000004],[-85.65472399999999,81.95082100000013],[-85.73194899999999,81.98332200000004],[-85.72999600000003,81.98776200000009],[-85.72694399999995,81.99026500000008],[-85.69387799999998,81.99498000000011],[-85.65055799999993,81.99832200000003],[-85.55943299999996,82.00166300000006],[-85.258621,81.99693300000001],[-85.21749899999998,81.99552900000003],[-85.18832399999991,81.99275200000011],[-85.16583300000002,81.98525999999998],[-85.16000400000001,81.97970600000002],[-85.14056399999993,81.96609500000005],[-85.09638999999999,81.9458160000001],[-85.01889,81.91943400000002],[-84.98416099999992,81.91110200000003],[-84.87943999999999,81.88749700000005],[-84.83889799999992,81.882477],[-84.81688700000001,81.88536799999991],[-84.82188400000001,81.88821400000006],[-84.84422299999989,81.89488200000005],[-84.86389199999996,81.90026900000004],[-84.915009,81.918045],[-84.99471999999997,81.94859300000002],[-85.02528399999994,81.96081500000014],[-85.037216,81.96693399999998],[-85.04888900000003,81.97442600000011],[-85.06610099999995,81.98748799999998],[-85.05555699999996,81.990814],[-85.03832999999997,81.99414100000013],[-85.00111400000003,81.99414100000013],[-84.929169,81.99304199999995],[-84.88917499999997,81.99026500000008],[-84.85888699999992,81.98525999999998],[-84.83168,81.97943099999998],[-84.81666599999994,81.97082500000005],[-84.814438,81.96638500000006],[-84.81527699999992,81.96110499999998],[-84.82194500000003,81.94914199999994],[-84.79760699999997,81.93087000000014],[-84.78926799999999,81.92469800000003],[-84.75144199999994,81.91053800000009],[-84.74227899999994,81.90837899999997],[-84.68859899999995,81.8919370000001],[-84.656113,81.8877720000001],[-84.63528399999996,81.88610800000004],[-84.62193300000001,81.886932],[-84.60499600000003,81.88998400000014],[-84.714722,81.96998600000012],[-84.72972099999998,81.97720300000003],[-84.75167799999991,81.98471100000006],[-84.81527699999992,82.00082400000008],[-84.84083599999997,82.006104],[-84.89973399999991,82.01527400000003],[-84.93249499999996,82.01944000000009],[-85.03999299999998,82.028595],[-85.11694299999994,82.03305100000006],[-85.40583800000002,82.04220599999996],[-85.6783289999999,82.05442800000009],[-85.75584399999997,82.05886800000013],[-85.85166900000002,82.06721500000009],[-85.91583300000002,82.07748400000014],[-85.99972500000001,82.09414700000002],[-86.06220999999994,82.1038670000001],[-86.0911099999999,82.10443100000003],[-86.278885,82.10720800000013],[-86.48500100000001,82.11415099999994],[-86.56555199999997,82.11886599999997],[-86.63751199999996,82.12441999999999],[-86.70611600000001,82.13192700000013],[-86.73138399999993,82.13638300000002],[-86.752228,82.14109800000006],[-86.85665899999992,82.18470800000006],[-86.86915599999992,82.19525100000004],[-86.87609900000001,82.20220899999998],[-86.87193300000001,82.20776400000011],[-86.843613,82.2124940000001],[-86.76417499999997,82.22164900000001],[-86.66944899999993,82.22831699999995],[-86.61944599999998,82.22970599999996],[-86.57167099999998,82.23027000000008],[-86.52000399999991,82.22970599999996],[-86.316666,82.2247010000001],[-86.22888199999989,82.2247010000001],[-86.181107,82.22526600000015],[-86.137787,82.22692900000004],[-85.98443600000002,82.2374880000001],[-85.93415800000002,82.238876],[-85.84138499999995,82.23915100000005],[-85.79888900000003,82.23776200000003],[-85.75389099999995,82.2374880000001],[-85.70611599999995,82.23803700000002],[-85.66221599999994,82.23969999999997],[-85.61999499999996,82.24359100000004],[-85.603882,82.24914600000011],[-85.59889199999998,82.2544400000001],[-85.58056599999998,82.26443499999999],[-85.55777,82.26944000000009],[-85.50834700000001,82.27304100000009],[-85.41389500000002,82.27609300000006],[-85.37083399999995,82.27998400000013],[-85.35055499999993,82.28387500000002],[-85.34722899999997,82.28637700000007],[-85.36749299999991,82.2910920000001],[-85.39639299999999,82.29693600000013],[-85.45722999999998,82.30748],[-85.48167399999994,82.31359900000001],[-85.48999000000003,82.31971699999997],[-85.515015,82.343323],[-85.531677,82.36970500000007],[-85.50167799999997,82.3936000000001],[-85.50140399999992,82.39888000000013],[-85.515289,82.40332000000001],[-85.53416400000003,82.40748600000006],[-85.66944899999987,82.409424],[-85.86694299999999,82.421921],[-85.90499899999998,82.4249880000001],[-85.921112,82.42997700000006],[-85.91194199999995,82.43580600000007],[-85.81973299999993,82.4544370000001],[-85.79472399999997,82.45860299999998],[-85.74694799999997,82.46138000000008],[-85.70861799999994,82.46360800000002],[-85.50250199999999,82.47109999999998],[-85.29861499999993,82.47804299999996],[-85.04695099999998,82.48193400000002],[-85.00306699999987,82.48082000000005],[-84.69387799999993,82.47137500000002],[-84.662781,82.46859699999999],[-84.64167800000001,82.46554600000002],[-84.62222300000002,82.45915200000013],[-84.61639400000001,82.45359800000011],[-84.61332699999991,82.447205],[-84.61332699999991,82.4433140000001],[-84.63137799999998,82.44026200000002],[-84.787781,82.4349820000001],[-84.89527900000002,82.43359400000003],[-84.94055200000003,82.43193100000008],[-84.94387799999998,82.42581200000006],[-84.91665599999993,82.42053199999998],[-84.88861099999986,82.41693099999998],[-84.714722,82.40582299999994],[-84.5597229999999,82.39498900000007],[-84.48249800000002,82.3894350000001],[-84.449997,82.38610799999998],[-84.41833499999996,82.38108800000009],[-84.38806199999999,82.37109400000008],[-84.38417099999992,82.36608900000004],[-84.38722199999995,82.361649],[-84.37860099999995,82.35693399999997],[-84.34445199999999,82.35276800000008],[-84.30332900000002,82.35582],[-84.228882,82.36387600000006],[-84.18055699999996,82.368042],[-84.14695699999999,82.36970500000007],[-84.09555099999994,82.37109400000008],[-84.04722600000002,82.37136800000002],[-83.96139499999992,82.3685910000001],[-83.87693799999994,82.3641510000001],[-83.84194899999994,82.36137400000001],[-83.76750199999998,82.35304300000007],[-83.60638399999993,82.33137499999998],[-83.51640299999997,82.31694000000005],[-83.38473499999998,82.28221099999996],[-83.36860699999994,82.27638199999996],[-83.36000100000001,82.26944000000009],[-83.36000100000001,82.26361100000003],[-83.36915599999998,82.25166300000001],[-83.37193300000001,82.24470500000001],[-83.37193300000001,82.23915100000005],[-83.34445199999993,82.22720300000015],[-83.308334,82.21832300000011],[-83.24221799999998,82.20416300000005],[-83.18415799999997,82.19470200000006],[-83.13055399999996,82.18498199999999],[-83.08389299999993,82.17581200000012],[-83.02278100000001,82.15942400000006],[-83,82.151093],[-82.97666900000002,82.13832100000013],[-82.95306399999998,82.11998],[-82.95666499999993,82.10971100000012],[-82.95861799999994,82.10443100000003],[-82.96833800000002,82.09803800000009],[-82.97805800000003,82.09387200000003],[-83.00195300000001,82.089157],[-83.0625,82.08027600000003],[-83.12609899999995,82.072495],[-83.12805199999997,82.06721500000009],[-83.11193799999995,82.06526199999996],[-83.07640099999992,82.06192000000004],[-82.97416699999997,82.06498699999997],[-82.88833599999998,82.072495],[-82.79750100000001,82.07777399999998],[-82.75805700000001,82.07693499999999],[-82.67443800000001,82.07304399999992],[-82.63639799999999,82.07054099999999],[-82.42166099999997,82.0669400000001],[-82.28416399999998,82.06637599999999],[-82.199432,82.06414799999999],[-82.1222229999999,82.05859400000003],[-82.05555699999996,82.05081200000006],[-81.96362299999993,82.0372010000001],[-81.92610199999996,82.03471400000001],[-81.88999899999999,82.03498800000011],[-81.87805199999997,82.03637700000013],[-81.88473499999992,82.04109199999999],[-81.92416400000002,82.05886800000013],[-81.96611000000001,82.07110599999999],[-82.02084400000001,82.08221399999996],[-82.05860899999999,82.08471700000013],[-82.10249299999998,82.08554100000009],[-82.24305699999996,82.08499100000006],[-82.41749600000003,82.08720400000004],[-82.54638699999998,82.09027100000014],[-82.58444199999991,82.09275800000006],[-82.61971999999992,82.09609999999998],[-82.651947,82.10026600000003],[-82.67694099999994,82.10775799999999],[-82.68388400000003,82.11831700000005],[-82.68859900000001,82.12608300000011],[-82.697495,82.13136299999996],[-82.71722399999993,82.14276100000001],[-82.73138399999993,82.14999399999999],[-82.77223200000003,82.16331500000013],[-82.860275,82.18775900000009],[-82.88694799999996,82.19386299999991],[-82.94027699999998,82.203598],[-82.987503,82.21499599999999],[-83.01139799999999,82.22164900000001],[-83.02778599999988,82.23525999999998],[-83.02888499999995,82.26499899999999],[-83.02888499999995,82.276657],[-83.02555799999999,82.28332499999999],[-83.01916499999987,82.28887900000012],[-82.99082900000002,82.29248000000001],[-82.73554999999993,82.28610200000003],[-82.69360399999994,82.28471400000012],[-82.65444899999989,82.28221099999996],[-82.62165800000002,82.27804599999996],[-82.50889599999994,82.25804099999999],[-82.45278899999994,82.24942000000004],[-82.28666699999997,82.2291560000001],[-82.26306199999999,82.22221400000001],[-82.21112099999999,82.20471199999997],[-82.160278,82.19331399999999],[-82.10194399999995,82.18304400000005],[-82.011124,82.1685940000001],[-81.91805999999991,82.15498400000007],[-81.60888699999998,82.11859099999998],[-81.42527799999993,82.0977630000001],[-81.35305799999998,82.09165999999993],[-81.24916100000002,82.08137500000004],[-81.150284,82.06887800000004],[-81.09111000000001,82.059418],[-80.86833200000001,82.03137200000009],[-80.640289,82.01832600000012],[-80.43249499999996,81.99748199999999],[-80.22582999999997,81.98609899999997],[-80.15360999999996,81.98136899999992],[-80.0850069999999,81.97360200000014],[-80.03527799999995,81.96304299999991],[-79.88305699999995,81.92469800000003],[-79.6100009999999,81.851089],[-79.58972199999994,81.84414700000008],[-79.587784,81.83831800000007],[-79.57722499999994,81.82887299999999],[-79.56416300000001,81.82527199999993],[-79.53443900000002,81.82083100000006],[-79.49221799999992,81.81971700000003],[-79.24444599999993,81.81608599999998],[-79.22917199999995,81.81608599999998],[-79.452225,81.88998400000014],[-79.48998999999998,81.90026900000004],[-79.52111799999989,81.90554800000007],[-79.57972699999993,81.91360500000002],[-79.670837,81.92747500000007],[-79.84445199999993,81.97137499999991],[-79.83778399999994,82.00721700000008],[-79.83222999999987,82.01388500000002],[-79.85333300000002,82.0188750000001],[-79.880829,82.021927],[-79.91639700000002,82.02388000000013],[-80.21389799999986,82.03221100000002],[-80.33168,82.038589],[-80.368607,82.04109199999999],[-80.624435,82.06192000000004],[-80.65722699999992,82.06469700000014],[-80.72555499999999,82.07165500000013],[-80.79110700000001,82.0794370000001],[-80.82223499999992,82.08387800000003],[-80.87832600000002,82.09414700000002],[-80.92222600000002,82.1035920000001],[-80.94860799999998,82.1102600000001],[-80.962784,82.11637900000011],[-80.97555499999999,82.12359600000002],[-80.97555499999999,82.12776200000013],[-80.95666499999999,82.13720699999999],[-80.93138099999999,82.14221200000003],[-80.89973399999991,82.14637800000014],[-80.874435,82.151093],[-80.86805699999996,82.15498400000007],[-80.90916399999998,82.15664700000013],[-81.05139199999996,82.15470900000003],[-81.171112,82.15637200000015],[-81.25334199999992,82.15971400000006],[-81.32472200000001,82.16499300000004],[-81.42332499999998,82.1769260000001],[-81.79972800000002,82.22276299999999],[-81.82556199999993,82.22665400000005],[-81.88778699999995,82.23803700000002],[-82.170547,82.28665200000006],[-82.45472699999999,82.32804899999996],[-82.51306199999993,82.33776900000004],[-82.62554899999992,82.35914600000007],[-82.67999299999997,82.37081900000004],[-82.71167000000003,82.38247700000011],[-82.722778,82.38832100000008],[-82.7308349999999,82.39526400000011],[-82.73222399999997,82.40165700000006],[-82.72888199999994,82.40832500000005],[-82.71028100000001,82.41943400000008],[-82.69833399999999,82.4249880000001],[-82.539444,82.49720800000011],[-82.52055399999995,82.50248700000009],[-82.49833699999999,82.50637799999998],[-82.45889299999999,82.50833100000011],[-82.40638699999988,82.50915500000008],[-82.316956,82.50694300000004],[-82.09167500000001,82.50138900000002],[-81.66999799999991,82.49247700000001],[-81.541672,82.49609399999997],[-81.54222099999993,82.50499000000008],[-81.71333299999998,82.51527400000009],[-81.75140399999998,82.51693700000004],[-81.84722899999997,82.51554899999996],[-81.88055400000002,82.51776100000001],[-81.92748999999998,82.52276600000005],[-81.96640000000002,82.5288700000001],[-82.26390100000003,82.57666000000006],[-82.321121,82.58915700000006],[-82.34388699999994,82.59526100000011],[-82.390289,82.6119230000001],[-82.39472999999992,82.61747700000006],[-82.39222699999993,82.62275699999998],[-82.38110399999988,82.63472000000002],[-82.37193300000001,82.63970899999998],[-82.354446,82.64553799999999],[-82.33528100000001,82.65054300000003],[-82.28805499999999,82.65998800000011],[-82.25500499999993,82.66442899999998],[-82.21528599999999,82.66859399999998],[-82.15499899999992,82.67109700000015],[-82.060272,82.66970800000001],[-81.97222899999997,82.66638200000011],[-81.93138099999993,82.66387899999995],[-81.54333500000001,82.63720700000005],[-81.43249500000002,82.6291500000001],[-81.35972599999997,82.62081900000004],[-81.30082699999997,82.61109899999991],[-81.136124,82.57804900000008],[-80.989441,82.54721100000006],[-80.94972199999995,82.53804000000014],[-80.89195299999994,82.532761],[-80.58167999999995,82.543045],[-80.57806399999998,82.54609700000009],[-80.59916699999997,82.55442800000003],[-80.87388599999997,82.62970000000013],[-80.99444599999993,82.6502690000001],[-81.04998799999998,82.66081200000008],[-81.077225,82.66693100000009],[-81.09750399999996,82.67248500000005],[-81.12471,82.68691999999999],[-81.22361799999999,82.71582000000006],[-81.30583199999995,82.73387100000002],[-81.449997,82.75555399999996],[-81.50862099999995,82.76470900000004],[-81.57362399999994,82.78831500000007],[-81.58444199999991,82.79443400000014],[-81.58500699999996,82.80081200000006],[-81.57167099999992,82.80636600000008],[-81.55665599999998,82.81137100000012],[-81.53639199999992,82.816666],[-81.51417500000002,82.82110600000004],[-81.473053,82.82499700000011],[-81.41139199999992,82.82777399999998],[-81.35972599999997,82.82777399999998],[-81.02223200000003,82.82193000000001],[-80.97721899999993,82.82026700000006],[-80.801941,82.8124850000001],[-80.500565,82.79748499999994],[-80.41833499999996,82.79220599999996],[-80.381104,82.78887900000007],[-80.31861899999996,82.77998400000001],[-80.2933349999999,82.77442900000011],[-80.15834000000001,82.72776800000008],[-80.13890100000003,82.71998600000012],[-80.13944999999995,82.71582000000006],[-80.17832900000002,82.69999700000005],[-80.18249500000002,82.69470199999995],[-80.18138099999993,82.68775900000014],[-80.16027799999995,82.68136600000003],[-80.0708469999999,82.66554300000001],[-80.00306699999999,82.65637200000003],[-79.941666,82.64942900000005],[-79.86166400000002,82.64415000000008],[-79.81777999999991,82.64444000000009],[-79.80082700000003,82.64665200000013],[-79.803604,82.64999400000005],[-79.82250999999997,82.65776100000005],[-79.84861799999999,82.66387899999995],[-79.966949,82.68470800000011],[-79.98332199999999,82.68914799999999],[-79.97749299999998,82.69581599999992],[-79.96139499999992,82.70082100000002],[-79.928604,82.70555100000001],[-79.88583399999987,82.70860299999993],[-79.82972699999999,82.70887800000014],[-79.7875059999999,82.707764],[-79.74749799999995,82.70498700000007],[-79.68415800000002,82.69970699999999],[-79.61749299999991,82.69303900000006],[-79.46833800000002,82.67747500000013],[-79.38473499999998,82.6727600000001],[-79.14999399999994,82.66775500000006],[-78.843613,82.66499299999998],[-78.56555200000003,82.67469800000003],[-78.521118,82.67692599999998],[-78.502792,82.68109099999998],[-78.53195199999999,82.68441800000011],[-78.57667500000002,82.68691999999999],[-78.84083599999997,82.68081700000005],[-78.89500399999986,82.68026700000001],[-78.93194599999998,82.68165600000003],[-79.24305700000002,82.6952510000001],[-79.33168,82.69970699999999],[-79.40306099999998,82.70637499999998],[-79.62304699999999,82.72776800000008],[-79.8369449999999,82.75054900000009],[-79.88694800000002,82.75943000000007],[-79.91332999999992,82.76527400000003],[-79.93638599999997,82.77221700000007],[-79.99694799999997,82.803314],[-79.97582999999997,82.80859400000003],[-79.94248999999996,82.81137100000012],[-79.69221500000003,82.81805400000007],[-79.67443799999995,82.82026700000006],[-79.67222599999991,82.82388300000014],[-79.67388900000003,82.8247070000001],[-79.84777799999995,82.83499100000012],[-79.896118,82.83581500000008],[-80.00666799999993,82.834427],[-80.11000099999995,82.83471700000001],[-80.15834000000001,82.83554100000015],[-80.19415300000003,82.83831800000007],[-80.21972700000003,82.84165999999999],[-80.27722199999994,82.85081500000001],[-80.39306599999998,82.87553400000002],[-80.43028299999997,82.88749700000005],[-80.42971799999998,82.89415000000002],[-80.398056,82.899719],[-80.09583999999995,82.93719499999997],[-79.90472399999999,82.95109600000012],[-79.79333500000001,82.95748900000012],[-79.45834400000001,82.974152],[-79.414444,82.97526600000015],[-79.370544,82.974152],[-79.17748999999998,82.9519350000001],[-79.07333399999999,82.90193199999999],[-79.06443799999988,82.89582800000011],[-79.066101,82.88943499999999],[-78.92805499999997,82.89860500000003],[-78.825287,82.92804000000012],[-78.78028899999998,82.93803400000013],[-78.75611899999996,82.94247400000012],[-78.71972699999998,82.94664000000006],[-78.67111199999994,82.94552600000009],[-78.63194299999998,82.94136000000015],[-78.546112,82.9266510000001],[-78.52166699999992,82.92109700000009],[-78.50334199999992,82.91331499999995],[-78.50195300000001,82.907761],[-78.5041809999999,82.901093],[-78.52194199999997,82.88915999999995],[-78.53860500000002,82.87664799999999],[-78.55777,82.86053500000014],[-78.5533289999999,82.8535920000001],[-78.53443900000002,82.8477630000001],[-78.50056499999994,82.84553499999998],[-78.34167499999995,82.85054000000002],[-78.17555199999998,82.82720899999998],[-78.14416499999993,82.82331800000009],[-78.10916099999997,82.8252720000001],[-78.10665899999998,82.83194000000009],[-78.12887599999988,82.83665500000012],[-78.19444299999992,82.84582499999999],[-78.22361799999999,82.85108899999994],[-78.24137899999994,82.85887100000008],[-78.23889199999996,82.86526500000014],[-78.108337,82.89332600000006],[-78.08029199999999,82.8983310000001],[-77.98666399999996,82.90998800000006],[-77.94999699999988,82.91415400000011],[-77.86332700000003,82.92137100000002],[-77.81304899999986,82.92442299999999],[-77.76834099999996,82.92248500000005],[-77.70834400000001,82.91609200000005],[-77.68888900000002,82.91249099999999],[-77.61665299999999,82.90277100000009],[-77.52806099999992,82.89109800000011],[-77.46722399999999,82.88388099999997],[-77.40527299999991,82.87886000000003],[-77.319458,82.87330600000001],[-77.12832599999996,82.86331200000001],[-77.108047,82.85914600000012],[-77.08917199999996,82.85276799999997],[-76.96665999999999,82.80470300000013],[-76.95916699999992,82.77415500000001],[-76.941666,82.768326],[-76.898346,82.766098],[-76.85110499999996,82.76499900000005],[-76.81555200000003,82.76110799999998],[-76.78916899999996,82.75637799999993],[-76.766663,82.75082399999997],[-76.70861799999994,82.73304700000006],[-76.67443800000001,82.72137499999997],[-76.64416499999999,82.70915200000007],[-76.612503,82.69609100000014],[-76.598053,82.68887300000011],[-76.57055699999995,82.66665600000005],[-76.53832999999997,82.664154],[-76.38722199999995,82.65138200000001],[-76.09333799999996,82.62081900000004],[-76.05888400000003,82.61692800000014],[-75.91389500000002,82.59748799999994],[-75.89222699999999,82.59193399999998],[-75.89639299999999,82.58831800000007],[-75.91861,82.57998700000002],[-75.93832399999997,82.57582100000013],[-75.972778,82.57138100000009],[-76.03889500000002,82.55720500000007],[-76.19471699999997,82.51110800000004],[-76.20750399999997,82.50637799999998],[-76.21777299999991,82.50054899999998],[-76.25527999999997,82.47192400000012],[-76.26100200000002,82.46655299999998],[-76.2369379999999,82.44525099999998],[-76.23083500000001,82.444702],[-76.18415800000002,82.45387299999999],[-76.10278299999987,82.47053499999998],[-76.03778099999994,82.48442100000011],[-75.97500600000001,82.49971],[-75.88722199999995,82.52221700000013],[-75.80277999999998,82.54637100000002],[-75.77389499999992,82.55720500000007],[-75.67138699999992,82.58692900000011],[-75.648056,82.59166000000005],[-75.60638399999993,82.59582500000005],[-75.50083899999993,82.60026600000015],[-75.45167500000002,82.603317],[-75.42027300000001,82.60693400000014],[-75.396118,82.61469999999997],[-75.40972899999997,82.61914100000007],[-75.43472300000002,82.62387100000012],[-75.46888699999988,82.62776200000002],[-75.50361599999985,82.62886000000009],[-75.55749499999996,82.62858599999998],[-75.62554899999998,82.63304099999999],[-75.670547,82.64276100000006],[-75.80749500000002,82.65470900000008],[-76.10305799999998,82.68609600000002],[-76.23582499999998,82.71220399999999],[-76.25639299999995,82.71720900000003],[-76.27555799999993,82.724426],[-76.29998799999987,82.73970000000003],[-76.30665599999992,82.7458190000001],[-76.30915800000002,82.7527770000001],[-76.269455,82.76081799999997],[-76.22639500000002,82.7644350000001],[-76.17639199999996,82.76721200000003],[-76.05694599999998,82.77165200000002],[-76.014725,82.77581800000013],[-75.989441,82.77998400000001],[-75.97610499999996,82.78471400000006],[-75.99833699999994,82.78749099999993],[-76.18638599999997,82.78387500000008],[-76.241379,82.78360000000004],[-76.28860500000002,82.78471400000006],[-76.37527499999999,82.78915400000005],[-76.447495,82.79748499999994],[-76.50167799999997,82.8077550000001],[-76.52528399999994,82.813873],[-76.54527299999995,82.82110600000004],[-76.58639499999998,82.83859300000006],[-76.629166,82.85971099999995],[-76.66665599999999,82.87248200000005],[-76.71083099999998,82.88581800000003],[-76.752792,82.89498899999995],[-76.84416199999998,82.90914900000007],[-76.88194299999998,82.91360500000002],[-77.02583299999998,82.92776500000008],[-77.06639099999995,82.93081699999999],[-77.13166799999999,82.93997200000007],[-77.34472699999998,82.972488],[-77.3852839999999,82.983047],[-77.38137799999998,82.99443100000013],[-77.364441,83.00000000000011],[-77.341949,83.00555400000013],[-77.27610800000002,83.02026400000005],[-77.25222799999995,83.0252690000001],[-77.22277799999995,83.03054800000007],[-77.18388399999998,83.03387500000002],[-77.13473499999998,83.032486],[-77.1372219999999,83.02832000000012],[-77.17138699999998,83.01721199999997],[-77.16972399999997,83.01388500000002],[-77.13555899999994,83.01138300000014],[-76.86305199999993,83.01081800000009],[-76.55943299999996,83.01193200000006],[-76.36027499999994,83.02137800000003],[-76.266663,83.02915999999999],[-76.20666499999993,83.03665200000012],[-76.11332700000003,83.05053700000002],[-76.07917799999996,83.0535890000001],[-76.02861000000001,83.05442800000009],[-75.97972099999993,83.05304000000001],[-75.94860799999992,83.05192600000004],[-75.58084100000002,83.03804000000002],[-75.31332399999991,83.02748099999997],[-75.04695100000004,83.0416560000001],[-75,83.04388400000005],[-74.95639,83.04553199999998],[-74.79750100000001,83.04359400000004],[-74.70666499999999,83.04109199999994],[-74.43582200000003,83.02720599999998],[-74.40805099999989,83.0247040000001],[-74.27917500000001,83.009995],[-74.17277499999989,82.99108899999999],[-74.08416699999998,82.972488],[-74.01806599999998,82.95694000000015],[-73.87943999999987,82.89721700000013],[-73.85166899999996,82.86665300000004],[-73.81777999999997,82.85276799999997],[-73.60777299999995,82.81581099999994],[-73.54833999999994,82.80609100000004],[-73.28195199999993,82.76638800000006],[-73.24722299999996,82.76165800000001],[-73.160278,82.75138899999996],[-73.07501199999996,82.7458190000001],[-72.94972199999995,82.73887600000006],[-72.90666199999998,82.73580899999996],[-72.83583099999998,82.72859200000005],[-72.75,82.71470600000009],[-72.70083599999998,82.70332300000007],[-72.67222599999997,82.69859300000002],[-72.63389599999994,82.69442700000013],[-72.60333299999996,82.69581599999992],[-72.59472700000003,82.69747900000004],[-72.49888599999997,82.71832300000005],[-72.50250199999994,82.724426],[-72.64889499999992,82.74664300000006],[-72.71665999999993,82.75555399999996],[-72.912216,82.77665700000006],[-72.98388699999998,82.78387500000008],[-73.02722199999988,82.78692600000011],[-73.21139499999992,82.813873],[-73.25750699999992,82.82582100000008],[-73.40139799999992,82.87498500000004],[-73.42027299999995,82.89054899999996],[-73.43055699999991,82.89359999999999],[-73.46083099999993,82.89860500000003],[-73.49499499999996,82.90248100000008],[-73.577225,82.9080350000001],[-73.60749800000002,82.91304000000014],[-73.633331,82.91859399999998],[-73.65055799999999,82.92581199999995],[-73.64416499999987,82.93220500000012],[-73.63444499999997,82.93664600000005],[-73.61915599999998,82.94108600000004],[-73.26194800000002,83.00776700000006],[-73.03388999999993,83.03665200000012],[-72.94860799999998,83.05525200000005],[-72.92748999999998,83.06749000000008],[-72.65055799999993,83.09637499999997],[-72.59973100000002,83.09693900000008],[-72.57028200000002,83.092758],[-72.56861900000001,83.08776900000004],[-72.55665599999998,83.07971200000009],[-72.52389499999992,83.07693499999999],[-72.47749299999987,83.07665999999995],[-72.42416399999996,83.07916300000011],[-72.40777600000001,83.08360299999998],[-72.39361600000001,83.08943199999999],[-72.36582900000002,83.09414700000002],[-72.33639499999992,83.09776300000004],[-72.22694399999995,83.10137900000012],[-72.11193800000001,83.10108900000012],[-72.00556899999987,83.09915200000006],[-71.83168,83.09776300000004],[-71.71278399999989,83.09887700000002],[-71.6116639999999,83.09609999999998],[-71.58167999999995,83.09109500000011],[-71.59695399999987,83.08526600000005],[-71.65444899999994,83.06887800000004],[-71.69638099999992,83.05775500000004],[-71.75,83.04304500000006],[-71.7750089999999,83.03221100000002],[-71.7933349999999,83.02053799999999],[-71.79499800000002,83.01361100000008],[-71.79222099999998,83.00749200000007],[-71.77833599999991,83.00166300000006],[-71.56722999999994,82.94108600000004],[-71.493607,82.93220500000012],[-71.33666999999997,82.91470300000009],[-71.21972699999998,82.9149930000001],[-71.14416499999999,82.9083250000001],[-71.08416699999998,82.90054299999997],[-71.01834099999996,82.89193700000004],[-70.952225,82.88360599999999],[-70.87138400000003,82.88108799999998],[-70.83500699999996,82.8830410000001],[-70.84333799999996,82.88998400000008],[-70.85777300000001,82.89721700000013],[-70.90417499999995,82.9080350000001],[-70.96194499999996,82.91859399999998],[-71.08084100000002,82.93748499999998],[-71.30638099999993,82.98220800000007],[-71.47277799999995,83.00166300000006],[-71.49749800000001,83.00721700000003],[-71.48999000000003,83.01443500000005],[-71.47416699999985,83.01944000000009],[-71.42500299999995,83.0294340000001],[-71.12527499999999,83.08749400000005],[-70.8872219999999,83.09803800000009],[-70.69415299999997,83.10359200000005],[-70.58528099999995,83.10331700000006],[-70.47000099999997,83.10748299999995],[-70.37388599999997,83.11331199999995],[-70.26000999999997,83.11387600000012],[-70.16000399999996,83.11137400000001],[-70.11193799999995,83.10942100000011]]]}}]}python-msgspec-0.22.0/examples/geojson/msgspec_geojson.py000066400000000000000000000026701525673062400236130ustar00rootroot00000000000000from __future__ import annotations import msgspec Position = tuple[float, float] # Define the 7 standard Geometry types. # All types set `tag=True`, meaning that they'll make use of a `type` field to # disambiguate between types when decoding. class Point(msgspec.Struct, tag=True): coordinates: Position class MultiPoint(msgspec.Struct, tag=True): coordinates: list[Position] class LineString(msgspec.Struct, tag=True): coordinates: list[Position] class MultiLineString(msgspec.Struct, tag=True): coordinates: list[list[Position]] class Polygon(msgspec.Struct, tag=True): coordinates: list[list[Position]] class MultiPolygon(msgspec.Struct, tag=True): coordinates: list[list[list[Position]]] class GeometryCollection(msgspec.Struct, tag=True): geometries: list[Geometry] Geometry = ( Point | MultiPoint | LineString | MultiLineString | Polygon | MultiPolygon | GeometryCollection ) # Define the two Feature types class Feature(msgspec.Struct, tag=True): geometry: Geometry | None = None properties: dict | None = None id: str | int | None = None class FeatureCollection(msgspec.Struct, tag=True): features: list[Feature] # A union of all 9 GeoJSON types GeoJSON = Geometry | Feature | FeatureCollection # Create a decoder and an encoder to use for decoding & encoding GeoJSON types loads = msgspec.json.Decoder(GeoJSON).decode dumps = msgspec.json.Encoder().encode python-msgspec-0.22.0/examples/pyproject-toml/000077500000000000000000000000001525673062400213735ustar00rootroot00000000000000python-msgspec-0.22.0/examples/pyproject-toml/pyproject.py000066400000000000000000000042751525673062400237740ustar00rootroot00000000000000from typing import Any import msgspec class Base( msgspec.Struct, omit_defaults=True, forbid_unknown_fields=True, rename="kebab", ): """A base class holding some common settings. - We set ``omit_defaults = True`` to omit any fields containing only their default value from the output when encoding. - We set ``forbid_unknown_fields = True`` to error nicely if an unknown field is present in the input TOML. This helps catch typo errors early, and is also required per PEP 621. - We set ``rename = "kebab"`` to rename all fields to use kebab case when encoding/decoding, as this is the convention used in pyproject.toml. For example, this will rename ``requires_python`` to ``requires-python``. """ pass class BuildSystem(Base): requires: list[str] = [] build_backend: str | None = None backend_path: list[str] = [] class Readme(Base): file: str | None = None text: str | None = None content_type: str | None = None class License(Base): file: str | None = None text: str | None = None class Contributor(Base): name: str | None = None email: str | None = None class Project(Base): name: str | None = None version: str | None = None description: str | None = None readme: str | Readme | None = None license: str | License | None = None authors: list[Contributor] = [] maintainers: list[Contributor] = [] keywords: list[str] = [] classifiers: list[str] = [] urls: dict[str, str] = {} requires_python: str | None = None dependencies: list[str] = [] optional_dependencies: dict[str, list[str]] = {} scripts: dict[str, str] = {} gui_scripts: dict[str, str] = {} entry_points: dict[str, dict[str, str]] = {} dynamic: list[str] = [] class PyProject(Base): build_system: BuildSystem | None = None project: Project | None = None tool: dict[str, dict[str, Any]] = {} def decode(data: bytes | str) -> PyProject: """Decode a ``pyproject.toml`` file from TOML""" return msgspec.toml.decode(data, type=PyProject) def encode(msg: PyProject) -> bytes: """Encode a ``PyProject`` object to TOML""" return msgspec.toml.encode(msg) python-msgspec-0.22.0/lychee.toml000066400000000000000000000007641525673062400167420ustar00rootroot00000000000000require_https = true include_fragments = true cache = true remap = [ # TODO: remove when this is fixed https://github.com/lycheeverse/lychee/issues/1729 "https://github.com/(.*?)/(.*?)/blob/(.*?)/(.*#.*)$ https://raw.githubusercontent.com/$1/$2/$3/$4" ] exclude = [ # This is way too flaky https://github.com/lycheeverse/lychee/issues/1884 '^https://toml.io/.*', # TODO: remove when this is fixed https://github.com/pradyunsg/furo/issues/907 '^http://github\.com/cferdinandi/gumshoe$', ] python-msgspec-0.22.0/pyproject.toml000066400000000000000000000070311525673062400175020ustar00rootroot00000000000000[build-system] requires = [ "setuptools>=80", "setuptools-scm>=8", ] build-backend = "setuptools.build_meta" [project] name = "msgspec" dynamic = [ "version", ] description = "A fast serialization and validation library, with builtin support for JSON, MessagePack, YAML, and TOML." readme = "README.md" license = "BSD-3-Clause" license-files = [ "LICENSE", ] requires-python = ">=3.10" maintainers = [ { name = "Jim Crist-Harif", email = "jcristharif@gmail.com" }, { name = "Ofek Lev", email = "oss@ofek.dev" }, { name = "Nikita Sobolev", email = "mail@sobolevn.me" }, ] keywords = [ "JSON", "MessagePack", "TOML", "YAML", "msgpack", "schema", "serialization", "validation", ] classifiers = [ "Development Status :: 4 - Beta", "Environment :: WebAssembly :: Emscripten", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3 :: Only", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", "Programming Language :: Python :: 3.13", "Programming Language :: Python :: 3.14", "Programming Language :: Python :: 3.15", "Programming Language :: Python :: Implementation :: CPython", "Topic :: Software Development :: Libraries", ] [project.optional-dependencies] toml = [ "tomli ; python_version < '3.11'", "tomli_w", ] yaml = [ "pyyaml", ] [project.urls] Homepage = "https://msgspec.dev" "Issue Tracker" = "https://github.com/msgspec/msgspec/issues" Source = "https://github.com/msgspec/msgspec" [dependency-groups] bench = [ "cattrs==26.1.0", "mashumaro==3.22", "msgpack==1.2.2", "orjson==3.12.0", "ormsgpack==1.12.2", "pydantic==2.13.5", "python-rapidjson==1.25", "pysimdjson==7.0.2", "requests", "ujson==6.0.0", ] dev = [ "rust-just", ] doc = [ "furo", "ipython", "myst-parser", "sphinx", "sphinx-copybutton", "sphinx-design", ] hooks = [ "codespell==2.4.3", "prek>=0.2.13", "ruff==0.16.7", ] test-base = [ "pytest>=9", "pytest-randomly", ] test-prof = [ { include-group = "test-base" }, "memray; sys_platform != 'win32'", "pytest-codspeed", "pytest-memray; sys_platform != 'win32'", ] test-typing = [ { include-group = "test-base" }, "mypy==2.3.1", "pyright==1.1.414", "pyrefly==1.3.1", ] test-unit = [ { include-group = "test-base" }, "attrs", "coverage", "msgpack", "pyyaml", "tomli; python_version < '3.11'", "tomli-w", ] [tool.setuptools] packages = ["msgspec"] [tool.setuptools.package-dir] "" = "src" [tool.setuptools.exclude-package-data] msgspec = [ "*.c", "*.h", ] [tool.setuptools_scm] version_file = "src/msgspec/_version.py" parentdir_prefix_version = "msgspec-" [tool.uv.config-settings] editable_mode = "compat" [tool.mypy] extra_checks = true strict = true strict_equality_for_none = true warn_unreachable = true [tool.pyright] include = ["tests/typing/"] # Strict mode: typeCheckingMode = "strict" reportImplicitStringConcatenation = "error" reportUninitializedInstanceVariable = "error" reportUnnecessaryTypeIgnoreComment = "error" # Don't use '# type: ignore' to suppress with pyright: enableTypeIgnoreComments = false # Don't report unused variables and classes: reportUnusedVariable = false reportUnusedClass = false reportPrivateUsage = false [tool.pyrefly] project-includes = ["tests/typing/"] # Strict mode: preset = 'strict' min-severity = 'warn' # Don't use '# type: ignore' to suppress with pyright: enabled-ignores = ["pyrefly"] [tool.pyrefly.errors] # Do not require type annotations for `lambda` functions: implicit-any-lambda = false python-msgspec-0.22.0/scripts/000077500000000000000000000000001525673062400162545ustar00rootroot00000000000000python-msgspec-0.22.0/scripts/generate_atof_consts.py000066400000000000000000000043231525673062400230240ustar00rootroot00000000000000"""This script generates msgspec/atof_consts.h""" import math import os import textwrap def gen_hpd_tables(): log2log10 = math.log(2) / math.log(10) shifts = ["0x0000"] powers = [] for i in range(1, 61): offset = len(powers) assert offset <= 0x07FF num_new_digits = int(log2log10 * float(i)) + 1 assert num_new_digits <= 31 code = (num_new_digits << 11) | offset p = str(5**i) powers.extend(p) shifts.append("0x%04X" % code) for i in range(61, 65): shifts.append("0x%04X" % len(powers)) n_shifts = len(shifts) n_powers = len(powers) assert n_powers <= 0x07FF shifts_str = "\n".join(textwrap.wrap(", ".join(shifts), width=78)) powers_str = "\n".join(textwrap.wrap(", ".join(powers), width=78)) return n_shifts, shifts_str, n_powers, powers_str def gen_row(e): z = 1 << 2048 if e >= 0: exp = 10**e z = z * exp else: exp = 10 ** (-e) z = z // exp n = -2048 while z >= (1 << 128): z = z >> 1 n += 1 h = hex(z)[2:] assert len(h) == 32 approx_n = ((217706 * e) >> 16) + 1087 biased_n = 1214 + n assert approx_n == biased_n return "{0x%s, 0x%s}, // 1e%-04d" % (h[16:], h[:16], e) table_rows = [gen_row(e) for e in range(-307, 289)] f64_powers = [f"1e{i}" for i in range(23)] n_shifts, shifts, n_powers, powers = gen_hpd_tables() text = """\ /* DO NOT EDIT - generated by scripts/generate_atof_consts.py */ #ifndef MSGSPEC_ATOF_CONSTS_H #define MSGSPEC_ATOF_CONSTS_H static const uint64_t ms_atof_powers_of_10[%d][2] = { %s }; static const double ms_atof_f64_powers_of_10[%d] = { %s }; static const uint16_t ms_atof_left_shift[%d] = { %s }; static const uint8_t ms_atof_powers_of_5[%d] = { %s }; #endif """ % ( len(table_rows), "\n".join(table_rows), len(f64_powers), "\n".join(textwrap.wrap(", ".join(f64_powers), width=78)), n_shifts, shifts, n_powers, powers, ) if __name__ == "__main__": repo = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) path = os.path.join(repo, "src", "msgspec", "atof_consts.h") with open(path, "wb") as f: f.write(text.encode("utf-8")) python-msgspec-0.22.0/scripts/release_github.py000066400000000000000000000016551525673062400216170ustar00rootroot00000000000000import re import webbrowser from pathlib import Path from urllib.parse import urlencode def main(): changelog_path = Path(__file__).parents[1] / "docs" / "changelog.md" changelog = changelog_path.read_text(encoding="utf-8") match = re.search( r"^##\s+Version\s+(?P\S+)[^\n]*\n+(?P.*?)(?=^##\s+Version|\Z)", changelog, re.DOTALL | re.MULTILINE, ) if not match: msg = f"Unable to parse changelog at {changelog_path}" raise RuntimeError(msg) version = match.group("version").strip() notes = match.group("notes").strip() params = urlencode( { "title": f"Version {version}", "tag": version, "body": re.sub(r"\{(?:pr|issue)\}`(\d+)`", r"#\1", notes), } ) url = f"https://github.com/msgspec/msgspec/releases/new?{params}" webbrowser.open_new_tab(url) if __name__ == "__main__": main() python-msgspec-0.22.0/scripts/stubtest.py000066400000000000000000000026361525673062400205120ustar00rootroot00000000000000"""Run stubtest against the installed msgspec package. Entries that apply to every supported Python version live in `tests/typing/stubtest_allowlist.txt`. Findings that only exist from a given version onwards go in `tests/typing/stubtest_allowlist_py_plus.txt`, and every such file whose version is at or below the running interpreter is passed too. stubtest runs without `--ignore-unused-allowlist`, so an entry that stops matching is reported instead of silently lingering. """ import re import subprocess import sys from pathlib import Path ALLOWLIST_DIR = Path(__file__).parents[1] / "tests" / "typing" VERSIONED_ALLOWLIST = re.compile(r"^stubtest_allowlist_py(\d)(\d+)_plus\.txt$") def allowlists(): yield ALLOWLIST_DIR / "stubtest_allowlist.txt" versioned = [] for path in ALLOWLIST_DIR.iterdir(): match = VERSIONED_ALLOWLIST.match(path.name) if match is not None: version = (int(match.group(1)), int(match.group(2))) if version <= sys.version_info[:2]: versioned.append((version, path)) for _, path in sorted(versioned): yield path def main(): command = [sys.executable, "-m", "mypy.stubtest", "msgspec"] for allowlist in allowlists(): command.extend(["--allowlist", str(allowlist)]) command.extend(sys.argv[1:]) return subprocess.call(command) if __name__ == "__main__": raise SystemExit(main()) python-msgspec-0.22.0/setup.py000066400000000000000000000042041525673062400162770ustar00rootroot00000000000000import os import platform import sys from setuptools import setup from setuptools.extension import Extension # Check for 32-bit windows builds, which currently aren't supported. We can't # rely on `platform.architecture` here since users can still run 32-bit python # builds on 64 bit architectures. if sys.platform == "win32" and sys.maxsize == (2**31 - 1): import textwrap error = """ ==================================================================== `msgspec` currently doesn't support 32-bit Python windows builds. If this is important for your use case, please comment on this issue: https://github.com/msgspec/msgspec/issues/845 ==================================================================== """ print(textwrap.dedent(error)) exit(1) SANITIZE = os.environ.get("MSGSPEC_SANITIZE", False) COVERAGE = os.environ.get("MSGSPEC_COVERAGE", False) DEBUG = os.environ.get("MSGSPEC_DEBUG", SANITIZE or COVERAGE) extra_compile_args = [] extra_link_args = [] if SANITIZE: extra_compile_args.extend(["-fsanitize=address", "-fsanitize=undefined"]) extra_link_args.extend(["-lasan", "-lubsan"]) if COVERAGE: extra_compile_args.append("--coverage") extra_link_args.append("-lgcov") if DEBUG: extra_compile_args.extend(["-O0", "-g", "-UNDEBUG"]) elif sys.platform != "win32": extra_compile_args.extend(["-g0"]) if sys.platform == "darwin" and platform.machine().lower() == "arm64": extra_compile_args.extend(["-flto=thin"]) extra_link_args.extend(["-flto=thin"]) # from https://py-free-threading.github.io/faq/#im-trying-to-build-a-library-on-windows-but-msvc-says-c-atomic-support-is-not-enabled if sys.platform == "win32": extra_compile_args.extend( [ "/std:c11", "/experimental:c11atomics", ] ) libraries = [] if sys.platform != "win32": libraries.append("m") ext_modules = [ Extension( "msgspec._core", [os.path.join("src", "msgspec", "_core.c")], libraries=libraries, extra_compile_args=extra_compile_args, extra_link_args=extra_link_args, ) ] setup( ext_modules=ext_modules, ) python-msgspec-0.22.0/src/000077500000000000000000000000001525673062400153545ustar00rootroot00000000000000python-msgspec-0.22.0/src/msgspec/000077500000000000000000000000001525673062400170155ustar00rootroot00000000000000python-msgspec-0.22.0/src/msgspec/__init__.py000066400000000000000000000010211525673062400211200ustar00rootroot00000000000000from ._core import ( NODEFAULT, UNSET, DecodeError, EncodeError, Field as _Field, Meta, MsgspecError, Raw, Struct, StructMeta, UnsetType, ValidationError, convert, defstruct, to_builtins, ) def field(*, default=NODEFAULT, default_factory=NODEFAULT, name=None): return _Field(default=default, default_factory=default_factory, name=name) field.__doc__ = _Field.__doc__ from . import inspect, json, msgpack, structs, toml, yaml from ._version import __version__ python-msgspec-0.22.0/src/msgspec/__init__.pyi000066400000000000000000000214561525673062400213070ustar00rootroot00000000000000import enum from collections.abc import Callable, Iterable, Mapping from inspect import Signature from typing import ( Any, ClassVar, Final, Literal, Optional, Tuple, Type, TypeVar, Union, final, overload, ) from typing_extensions import ( Buffer, Self, TypeAlias, dataclass_transform, disjoint_base, ) from . import inspect, json, msgpack, structs, toml, yaml # PEP 673 explicitly rejects using Self in metaclass definitions: # https://peps.python.org/pep-0673/#valid-locations-for-self # # Typeshed works around this by using a type variable as well: # https://github.com/python/typeshed/blob/17bde1bd5e556de001adde3c2f340ba1c3581bd2/stdlib/abc.pyi#L14-L19 _SM = TypeVar("_SM", bound="StructMeta") @disjoint_base class StructMeta(type): __struct_fields__: ClassVar[tuple[str, ...]] __struct_defaults__: ClassVar[tuple[Any, ...]] __struct_encode_fields__: ClassVar[tuple[str, ...]] __match_args__: ClassVar[tuple[str, ...]] @property def __signature__(self) -> Signature: ... @property def __struct_config__(self) -> structs.StructConfig: ... def __new__( mcls: type[_SM], name: str, bases: tuple[type, ...], namespace: dict[str, Any], /, *, tag: bool | str | int | Callable[[str], str | int] | None = None, tag_field: str | None = None, rename: ( None | Literal["lower", "upper", "camel", "pascal", "kebab"] | Callable[[str], str | None] | Mapping[str, str] ) = None, omit_defaults: bool = False, forbid_unknown_fields: bool = False, frozen: bool = False, eq: bool = True, order: bool = False, kw_only: bool = False, repr_omit_defaults: bool = False, array_like: bool = False, gc: bool = True, weakref: bool = False, dict: bool = False, cache_hash: bool = False, ) -> _SM: ... _T = TypeVar("_T") @final class UnsetType(enum.Enum): UNSET = "UNSET" def __bool__(self, /) -> Literal[False]: ... UNSET: Final = UnsetType.UNSET @final class _NoDefault(enum.Enum): NODEFAULT = "NODEFAULT" NODEFAULT: Final = _NoDefault.NODEFAULT @overload def field(*, default: _T, name: str | None = None) -> _T: ... @overload def field(*, default_factory: Callable[[], _T], name: str | None = None) -> _T: ... @overload def field(*, name: str | None = None) -> Any: ... @dataclass_transform(field_specifiers=(field,)) class Struct(metaclass=StructMeta): __struct_fields__: ClassVar[tuple[str, ...]] __struct_defaults__: ClassVar[tuple[Any, ...]] __struct_config__: ClassVar[structs.StructConfig] __struct_encode_fields__: ClassVar[tuple[str, ...]] __match_args__: ClassVar[tuple[str, ...]] # A default __init__ so that Structs with unknown field types (say # constructed by `defstruct`) won't error on every call to `__init__` def __init__(self, *args: Any, **kwargs: Any) -> None: ... def __init_subclass__( cls, tag: bool | str | int | Callable[[str], str | int] | None = None, tag_field: str | None = None, rename: ( None | Literal["lower", "upper", "camel", "pascal", "kebab"] | Callable[[str], str | None] | Mapping[str, str] ) = None, omit_defaults: bool = False, forbid_unknown_fields: bool = False, frozen: bool = False, eq: bool = True, order: bool = False, kw_only: bool = False, repr_omit_defaults: bool = False, array_like: bool = False, gc: bool = True, weakref: bool = False, dict: bool = False, cache_hash: bool = False, ) -> None: ... def __rich_repr__(self, /) -> list[tuple[str, Any]]: ... def __replace__(self, /, **changes: Any) -> Self: ... def defstruct( name: str, fields: Iterable[str | tuple[str, Any] | tuple[str, Any, Any]], *, bases: tuple[type[Any], ...] | None = None, module: str | None = None, namespace: dict[str, Any] | None = None, tag: bool | str | int | Callable[[str], str | int] | None = None, tag_field: str | None = None, rename: ( None | Literal["lower", "upper", "camel", "pascal", "kebab"] | Callable[[str], str | None] | Mapping[str, str] ) = None, omit_defaults: bool = False, forbid_unknown_fields: bool = False, frozen: bool = False, eq: bool = True, order: bool = False, kw_only: bool = False, repr_omit_defaults: bool = False, array_like: bool = False, gc: bool = True, weakref: bool = False, dict: bool = False, cache_hash: bool = False, ) -> type[Struct]: ... # Lie and say `Raw` is a subclass of `bytes`, so mypy will accept it in most # places where an object that implements the buffer protocol is valid @final class Raw(bytes): @overload def __new__(cls) -> "Raw": ... @overload def __new__(cls, msg: Buffer | str, /) -> "Raw": ... def copy(self, /) -> "Raw": ... #: We can't represent this in types, only via a name: _NonNegativeInt: TypeAlias = int @final class Meta: # Numeric: # You can't mix: # - `gt` and `ge` # - `lt` and `le` @overload def __init__( self, *, gt: int | float | None = None, lt: int | float | None = None, multiple_of: int | float | None = None, title: str | None = None, description: str | None = None, examples: list[Any] | None = None, extra_json_schema: dict[str, Any] | None = None, extra: dict[str, Any] | None = None, ) -> None: ... @overload def __init__( self, *, gt: int | float | None = None, le: int | float | None = None, multiple_of: int | float | None = None, title: str | None = None, description: str | None = None, examples: list[Any] | None = None, extra_json_schema: dict[str, Any] | None = None, extra: dict[str, Any] | None = None, ) -> None: ... @overload def __init__( self, *, ge: int | float | None = None, lt: int | float | None = None, multiple_of: int | float | None = None, title: str | None = None, description: str | None = None, examples: list[Any] | None = None, extra_json_schema: dict[str, Any] | None = None, extra: dict[str, Any] | None = None, ) -> None: ... @overload def __init__( self, *, ge: int | float | None = None, le: int | float | None = None, multiple_of: int | float | None = None, title: str | None = None, description: str | None = None, examples: list[Any] | None = None, extra_json_schema: dict[str, Any] | None = None, extra: dict[str, Any] | None = None, ) -> None: ... # Other: @overload def __init__( self, *, pattern: str | None = None, min_length: _NonNegativeInt | None = None, max_length: _NonNegativeInt | None = None, tz: bool | None = None, title: str | None = None, description: str | None = None, examples: list[Any] | None = None, extra_json_schema: dict[str, Any] | None = None, extra: dict[str, Any] | None = None, ) -> None: ... gt: Final[int | float | None] ge: Final[int | float | None] lt: Final[int | float | None] le: Final[int | float | None] multiple_of: Final[int | float | None] pattern: Final[str | None] min_length: Final[int | None] max_length: Final[int | None] tz: Final[bool | None] title: Final[str | None] description: Final[str | None] examples: Final[list[Any] | None] extra_json_schema: Final[dict[str, Any] | None] extra: Final[dict[str, Any] | None] def __rich_repr__(self, /) -> list[tuple[str, Any]]: ... def to_builtins( obj: Any, *, str_keys: bool = False, builtin_types: Iterable[type[Any]] | None = None, enc_hook: Callable[[Any], Any] | None = None, order: Literal["deterministic", "sorted"] | None = None, ) -> Any: ... @overload def convert( obj: Any, type: type[_T], *, strict: bool = True, from_attributes: bool = False, dec_hook: Callable[[type[Any], Any], Any] | None = None, builtin_types: Iterable[type[Any]] | None = None, str_keys: bool = False, ) -> _T: ... @overload def convert( obj: Any, type: Any, *, strict: bool = True, from_attributes: bool = False, dec_hook: Callable[[type[Any], Any], Any] | None = None, builtin_types: Iterable[type[Any]] | None = None, str_keys: bool = False, ) -> Any: ... class MsgspecError(Exception): ... class EncodeError(MsgspecError): ... class DecodeError(MsgspecError): ... class ValidationError(DecodeError): ... __version__: str python-msgspec-0.22.0/src/msgspec/_core.c000066400000000000000000026363051525673062400202670ustar00rootroot00000000000000#include #include #include #include #include #include #include #define PY_SSIZE_T_CLEAN #include "Python.h" #include "datetime.h" #include "structmember.h" #include "common.h" #include "itoa.h" #include "ryu.h" #include "atof.h" /* Python version checks */ #define PY311_PLUS (PY_VERSION_HEX >= 0x030b0000) #define PY312_PLUS (PY_VERSION_HEX >= 0x030c0000) #define PY313_PLUS (PY_VERSION_HEX >= 0x030d0000) #define PY314_PLUS (PY_VERSION_HEX >= 0x030e0000) #define PY315_PLUS (PY_VERSION_HEX >= 0x030f0000) /* In Python 3.14+, tuples cache their hash value in ob_hash. When a tuple is * allocated via tp_alloc (which zero-initializes memory), ob_hash is 0 — a * valid cached hash — so tuple_hash() returns 0 without computing the real * hash. Reset it to -1 ("not yet computed") after allocation. */ #if PY314_PLUS #define MS_TUPLE_RESET_HASH(op) (((PyTupleObject *)(op))->ob_hash = -1) #else #define MS_TUPLE_RESET_HASH(op) ((void)0) #endif /* Hint to the compiler not to store `x` in a register since it is likely to * change. Results in much higher performance on GCC, with smaller benefits on * clang */ #if defined(__GNUC__) #define OPT_FORCE_RELOAD(x) __asm volatile("":"=m"(x)::); #else #define OPT_FORCE_RELOAD(x) #endif #ifdef __GNUC__ #define ms_popcount(i) __builtin_popcountll(i) #else static int ms_popcount(uint64_t i) { \ i = i - ((i >> 1) & 0x5555555555555555); // pairs i = (i & 0x3333333333333333) + ((i >> 2) & 0x3333333333333333); // quads i = (i + (i >> 4)) & 0x0F0F0F0F0F0F0F0F; // groups of 8 return (uint64_t)(i * 0x0101010101010101) >> 56; // sum bytes } #endif /* In Python 3.12+, tp_dict is NULL for some core types, so PyType_GetDict is * used instead. It returns a new reference, which must be released; before * 3.12 the tp_dict slot is read directly and is borrowed, so there is nothing * to release. */ #if PY312_PLUS #define MS_GET_TYPE_DICT(a) PyType_GetDict(a) #define MS_RELEASE_TYPE_DICT(d) Py_XDECREF(d) #else #define MS_GET_TYPE_DICT(a) ((a)->tp_dict) #define MS_RELEASE_TYPE_DICT(d) ((void)(d)) #endif #if PY313_PLUS #define MS_UNICODE_EQ(a, b) (PyUnicode_Compare(a, b) == 0) #else #define MS_UNICODE_EQ(a, b) _PyUnicode_EQ(a, b) #endif #if defined(Py_GIL_DISABLED) && !PY314_PLUS #error "Py_GIL_DISABLED is only supported in Python 3.14+" #endif #if PY314_PLUS #ifdef Py_GIL_DISABLED #define _PyObject_HEAD_INIT(type) \ { \ 0, \ _Py_STATICALLY_ALLOCATED_FLAG, \ { 0 }, \ 0, \ _Py_IMMORTAL_REFCNT_LOCAL, \ 0, \ (type), \ } #else #if SIZEOF_VOID_P > 4 #define _PyObject_HEAD_INIT(type) \ { \ .ob_refcnt = _Py_IMMORTAL_INITIAL_REFCNT, \ .ob_flags = _Py_STATIC_FLAG_BITS, \ .ob_type = (type) \ } #else #define _PyObject_HEAD_INIT(type) \ { \ .ob_refcnt = _Py_STATIC_IMMORTAL_INITIAL_REFCNT, \ .ob_type = (type) \ } #endif // SIZEOF_VOID_P > 4 #endif // Py_GIL_DISABLED #else #ifndef _Py_IMMORTAL_REFCNT #define _Py_IMMORTAL_REFCNT 999999999 #endif #define _PyObject_HEAD_INIT(type) \ { \ .ob_refcnt = _Py_IMMORTAL_REFCNT, \ .ob_type = (type) \ } #endif // PY314_PLUS #if PY_VERSION_HEX < 0x030D00A1 static inline int PyDict_GetItemRef(PyObject *mp, PyObject *key, PyObject **result) { #if PY_VERSION_HEX >= 0x03000000 PyObject *item = PyDict_GetItemWithError(mp, key); #else PyObject *item = _PyDict_GetItemWithError(mp, key); #endif if (item != NULL) { Py_INCREF(item); *result = item; return 1; // found } if (!PyErr_Occurred()) { *result = NULL; return 0; // not found } *result = NULL; return -1; } #endif // PY_VERSION_HEX < 0x030D00A1 #if PY315_PLUS static inline PyObject * _PyFrozenDict_NewSteal(PyObject *dict) { if (dict == NULL) { return NULL; } PyObject *op = PyFrozenDict_New(dict); Py_DECREF(dict); return op; } #endif #if PY_VERSION_HEX < 0x030D00B3 # define Py_BEGIN_CRITICAL_SECTION(op) { # define Py_END_CRITICAL_SECTION() } # define Py_BEGIN_CRITICAL_SECTION2(a, b) { # define Py_END_CRITICAL_SECTION2() } #endif // PY_VERSION_HEX < 0x030D00B3 #define DIV_ROUND_CLOSEST(n, d) ((((n) < 0) == ((d) < 0)) ? (((n) + (d)/2)/(d)) : (((n) - (d)/2)/(d))) /* These macros are used to manually unroll some loops */ #define repeat8(x) { x(0) x(1) x(2) x(3) x(4) x(5) x(6) x(7) } #define is_digit(c) (c >= '0' && c <= '9') /* Easy access to NoneType object */ #define NONE_TYPE ((PyObject *)(Py_TYPE(Py_None))) /* Capacity of a list */ #define LIST_CAPACITY(x) (((PyListObject *)x)->allocated) /* Get the raw items pointer for a list and tuple */ #define LIST_ITEMS(x) (((PyListObject *)(x))->ob_item) #define TUPLE_ITEMS(x) (((PyTupleObject *)(x))->ob_item) /* Fast shrink of bytes & bytearray objects. This doesn't do any memory * allocations, it just shrinks the size of the view presented to Python. Since * outputs of `encode` should be short lived (immediately written to a * socket/file then dropped), this shouldn't result in increased application * memory usage. */ # define FAST_BYTES_SHRINK(obj, size) \ do { \ Py_SET_SIZE(obj, size); \ PyBytes_AS_STRING(obj)[size] = '\0'; \ } while (0); # define FAST_BYTEARRAY_SHRINK(obj, size) \ do { \ Py_SET_SIZE(obj, size); \ PyByteArray_AS_STRING(obj)[size] = '\0'; \ } while (0); /* XXX: Optimized `PyUnicode_AsUTF8AndSize` for strs that we know have * a cached unicode representation. */ static inline const char * unicode_str_and_size_nocheck(PyObject *str, Py_ssize_t *size) { if (MS_LIKELY(PyUnicode_IS_COMPACT_ASCII(str))) { *size = ((PyASCIIObject *)str)->length; return (char *)(((PyASCIIObject *)str) + 1); } *size = ((PyCompactUnicodeObject *)str)->utf8_length; return ((PyCompactUnicodeObject *)str)->utf8; } /* XXX: Optimized `PyUnicode_AsUTF8AndSize` */ static inline const char * unicode_str_and_size(PyObject *str, Py_ssize_t *size) { #ifndef Py_GIL_DISABLED const char *out = unicode_str_and_size_nocheck(str, size); if (MS_LIKELY(out != NULL)) return out; #endif return PyUnicode_AsUTF8AndSize(str, size); } static MS_INLINE char * ascii_get_buffer(PyObject *str) { return (char *)(((PyASCIIObject *)str) + 1); } /* Fill in view.buf & view.len from either a Unicode or buffer-compatible * object. */ static int ms_get_buffer(PyObject *obj, Py_buffer *view) { if (MS_UNLIKELY(PyUnicode_CheckExact(obj))) { view->buf = (void *)unicode_str_and_size(obj, &(view->len)); if (view->buf == NULL) return -1; Py_INCREF(obj); view->obj = obj; return 0; } return PyObject_GetBuffer(obj, view, PyBUF_CONTIG_RO); } static void ms_release_buffer(Py_buffer *view) { if (MS_LIKELY(!PyUnicode_CheckExact(view->obj))) { PyBuffer_Release(view); } else { Py_CLEAR(view->obj); } } /* Hash algorithm borrowed from cpython 3.10's hashing algorithm for tuples. * See https://github.com/python/cpython/blob/4bcef2bb48b3fd82011a89c1c716421b789f1442/Objects/tupleobject.c#L386-L424 */ #if SIZEOF_PY_UHASH_T > 4 #define MS_HASH_XXPRIME_1 ((Py_uhash_t)11400714785074694791ULL) #define MS_HASH_XXPRIME_2 ((Py_uhash_t)14029467366897019727ULL) #define MS_HASH_XXPRIME_5 ((Py_uhash_t)2870177450012600261ULL) #define MS_HASH_XXROTATE(x) ((x << 31) | (x >> 33)) /* Rotate left 31 bits */ #else #define MS_HASH_XXPRIME_1 ((Py_uhash_t)2654435761UL) #define MS_HASH_XXPRIME_2 ((Py_uhash_t)2246822519UL) #define MS_HASH_XXPRIME_5 ((Py_uhash_t)374761393UL) #define MS_HASH_XXROTATE(x) ((x << 13) | (x >> 19)) /* Rotate left 13 bits */ #endif /* Optimized version of PyLong_AsLongLongAndOverflow/PyLong_AsUnsignedLongLong. * * Returns True if sign * scale won't fit in an `int64` or a `uint64`. */ static inline bool fast_long_extract_parts(PyObject *vv, bool *neg, uint64_t *scale) { PyLongObject *v = (PyLongObject *)vv; uint64_t prev, x = 0; bool negative; #if PY312_PLUS /* CPython 3.12 changed int internal representation */ int sign = 1 - (v->long_value.lv_tag & _PyLong_SIGN_MASK); negative = sign == -1; if (_PyLong_IsCompact(v)) { x = v->long_value.ob_digit[0]; } else { Py_ssize_t i = v->long_value.lv_tag >> _PyLong_NON_SIZE_BITS; while (--i >= 0) { prev = x; x = (x << PyLong_SHIFT) + v->long_value.ob_digit[i]; if ((x >> PyLong_SHIFT) != prev) { return true; } } if (negative && x > (1ull << 63)) { return true; } } #else Py_ssize_t i = Py_SIZE(v); negative = false; if (MS_LIKELY(i == 1)) { x = v->ob_digit[0]; } else if (i != 0) { negative = i < 0; if (MS_UNLIKELY(negative)) { i = -i; } while (--i >= 0) { prev = x; x = (x << PyLong_SHIFT) + v->ob_digit[i]; if ((x >> PyLong_SHIFT) != prev) { return true; } } if (negative && x > (1ull << 63)) { return true; } } #endif *neg = negative; *scale = x; return false; } /* Access macro to the members which are floating "behind" the object */ #define MS_PyHeapType_GET_MEMBERS(etype) \ ((PyMemberDef *)(((char *)(etype)) + Py_TYPE(etype)->tp_basicsize)) #define MS_GET_FIRST_SLOT(obj) \ *((PyObject **)((char *)(obj) + sizeof(PyObject))) \ #define MS_SET_FIRST_SLOT(obj, val) \ MS_GET_FIRST_SLOT(obj) = (val) /************************************************************************* * Lookup Tables * *************************************************************************/ static const char hex_encode_table[] = "0123456789abcdef"; static const char base64_encode_table[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; /************************************************************************* * GC Utilities * *************************************************************************/ #define MS_TYPE_IS_GC(t) (((PyTypeObject *)(t))->tp_flags & Py_TPFLAGS_HAVE_GC) #define MS_OBJECT_IS_GC(obj) MS_TYPE_IS_GC(Py_TYPE(obj)) #define MS_IS_TRACKED(o) PyObject_GC_IsTracked(o) /* Is this object something that is/could be GC tracked? True if * - the value supports GC * - the value isn't a tuple or the object is tracked (skip tracked checks for non-tuples) */ #define MS_MAYBE_TRACKED(x) \ (MS_TYPE_IS_GC(Py_TYPE(x)) && \ (!PyTuple_CheckExact(x) || MS_IS_TRACKED(x))) /************************************************************************* * Murmurhash2 * *************************************************************************/ static inline uint32_t unaligned_load(const unsigned char *p) { uint32_t out; memcpy(&out, p, sizeof(out)); return out; } static inline uint32_t murmur2(const char *p, Py_ssize_t len) { const unsigned char *buf = (unsigned char *)p; const size_t m = 0x5bd1e995; uint32_t hash = (uint32_t)len; while(len >= 4) { uint32_t k = unaligned_load(buf); k *= m; k ^= k >> 24; k *= m; hash *= m; hash ^= k; buf += 4; len -= 4; } switch(len) { case 3: hash ^= buf[2] << 16; case 2: hash ^= buf[1] << 8; case 1: hash ^= buf[0]; hash *= m; }; hash ^= hash >> 13; hash *= m; hash ^= hash >> 15; return hash; } /************************************************************************* * String Cache * *************************************************************************/ #ifndef Py_GIL_DISABLED #ifndef STRING_CACHE_SIZE #define STRING_CACHE_SIZE 512 #endif #ifndef STRING_CACHE_MAX_STRING_LENGTH #define STRING_CACHE_MAX_STRING_LENGTH 32 #endif static PyObject *string_cache[STRING_CACHE_SIZE]; static void string_cache_clear(void) { /* Traverse the string cache, deleting any string with a reference count of * only 1 */ for (Py_ssize_t i = 0; i < STRING_CACHE_SIZE; i++) { PyObject *obj = string_cache[i]; if (obj != NULL) { if (Py_REFCNT(obj) == 1) { Py_DECREF(obj); string_cache[i] = NULL; } } } } #endif /************************************************************************* * Endian handling macros * *************************************************************************/ #define _msgspec_store16(to, x) do { \ ((uint8_t*)to)[0] = (uint8_t)((x >> 8) & 0xff); \ ((uint8_t*)to)[1] = (uint8_t)(x & 0xff); \ } while (0); #define _msgspec_store32(to, x) do { \ ((uint8_t*)to)[0] = (uint8_t)((x >> 24) & 0xff); \ ((uint8_t*)to)[1] = (uint8_t)((x >> 16) & 0xff); \ ((uint8_t*)to)[2] = (uint8_t)((x >> 8) & 0xff); \ ((uint8_t*)to)[3] = (uint8_t)(x & 0xff); \ } while (0); #define _msgspec_store64(to, x) do { \ ((uint8_t*)to)[0] = (uint8_t)((x >> 56) & 0xff); \ ((uint8_t*)to)[1] = (uint8_t)((x >> 48) & 0xff); \ ((uint8_t*)to)[2] = (uint8_t)((x >> 40) & 0xff); \ ((uint8_t*)to)[3] = (uint8_t)((x >> 32) & 0xff); \ ((uint8_t*)to)[4] = (uint8_t)((x >> 24) & 0xff); \ ((uint8_t*)to)[5] = (uint8_t)((x >> 16) & 0xff); \ ((uint8_t*)to)[6] = (uint8_t)((x >> 8) & 0xff); \ ((uint8_t*)to)[7] = (uint8_t)(x & 0xff); \ } while (0); #define _msgspec_load16(cast, from) ((cast)( \ (((uint16_t)((uint8_t*)from)[0]) << 8) | \ (((uint16_t)((uint8_t*)from)[1]) ) )) #define _msgspec_load32(cast, from) ((cast)( \ (((uint32_t)((uint8_t*)from)[0]) << 24) | \ (((uint32_t)((uint8_t*)from)[1]) << 16) | \ (((uint32_t)((uint8_t*)from)[2]) << 8) | \ (((uint32_t)((uint8_t*)from)[3]) ) )) #define _msgspec_load64(cast, from) ((cast)( \ (((uint64_t)((uint8_t*)from)[0]) << 56) | \ (((uint64_t)((uint8_t*)from)[1]) << 48) | \ (((uint64_t)((uint8_t*)from)[2]) << 40) | \ (((uint64_t)((uint8_t*)from)[3]) << 32) | \ (((uint64_t)((uint8_t*)from)[4]) << 24) | \ (((uint64_t)((uint8_t*)from)[5]) << 16) | \ (((uint64_t)((uint8_t*)from)[6]) << 8) | \ (((uint64_t)((uint8_t*)from)[7]) ) )) /************************************************************************* * Module level state * *************************************************************************/ /* State of the msgspec module */ typedef struct { PyObject *MsgspecError; PyObject *EncodeError; PyObject *DecodeError; PyObject *ValidationError; PyObject *StructType; PyTypeObject *EnumMetaType; PyTypeObject *ABCMetaType; PyObject *_abc_init; PyObject *struct_lookup_cache; PyObject *str___weakref__; PyObject *str___dict__; PyObject *str___msgspec_cached_hash__; PyObject *str__value2member_map_; PyObject *str___msgspec_cache__; PyObject *str__value_; PyObject *str__missing_; PyObject *str_type; PyObject *str_enc_hook; PyObject *str_dec_hook; PyObject *str_ext_hook; PyObject *str_strict; PyObject *str_order; PyObject *str_utcoffset; PyObject *str___origin__; PyObject *str___args__; PyObject *str___metadata__; PyObject *str___total__; PyObject *str___required_keys__; PyObject *str__fields; PyObject *str__field_defaults; PyObject *str___post_init__; PyObject *str___dataclass_fields__; PyObject *str___attrs_attrs__; PyObject *str___supertype__; #if PY312_PLUS PyObject *str___value__; #endif PyObject *str___bound__; PyObject *str___constraints__; PyObject *str_int; PyObject *str_is_safe; PyObject *UUIDType; PyObject *uuid_safeuuid_unknown; PyObject *DecimalType; PyObject *typing_union; PyObject *typing_any; PyObject *typing_literal; PyObject *typing_classvar; PyObject *typing_typevar; PyObject *typing_final; PyObject *typing_generic; PyObject *typing_generic_alias; PyObject *typing_annotated_alias; PyObject *concrete_types; PyObject *get_type_hints; PyObject *get_class_annotations; PyObject *call_annotate_forwardref; PyObject *get_typeddict_info; PyObject *get_dataclass_info; PyObject *convert_generic_alias; PyObject *rebuild; PyObject *types_uniontype; #if PY312_PLUS PyObject *typing_typealiastype; #endif PyObject *astimezone; PyObject *re_compile; uint8_t gc_cycle; } MsgspecState; /* Forward declaration of the msgspec module definition. */ static struct PyModuleDef msgspecmodule; /* Given a module object, get its per-module state. */ static MsgspecState * msgspec_get_state(PyObject *module) { return (MsgspecState *)PyModule_GetState(module); } /* Find the module instance imported in the currently running sub-interpreter and get its state. */ static MsgspecState * msgspec_get_global_state(void) { PyObject *module = PyState_FindModule(&msgspecmodule); return module == NULL ? NULL : msgspec_get_state(module); } static int ms_err_truncated(void) { PyErr_SetString(msgspec_get_global_state()->DecodeError, "Input data was truncated"); return -1; } static int ms_decimal_format_error(void) { PyErr_SetString(PyExc_TypeError, "callable returned a value containing a Decimal"); return -1; } /************************************************************************* * Utilities * *************************************************************************/ static PyObject* find_keyword(PyObject *kwnames, PyObject *const *kwstack, PyObject *key) { Py_ssize_t i, nkwargs; nkwargs = PyTuple_GET_SIZE(kwnames); for (i = 0; i < nkwargs; i++) { PyObject *kwname = PyTuple_GET_ITEM(kwnames, i); /* kwname == key will normally find a match in since keyword keys should be interned strings; if not retry below in a new loop. */ if (kwname == key) { return kwstack[i]; } } for (i = 0; i < nkwargs; i++) { PyObject *kwname = PyTuple_GET_ITEM(kwnames, i); assert(PyUnicode_Check(kwname)); if (MS_UNICODE_EQ(kwname, key)) { return kwstack[i]; } } return NULL; } static int check_positional_nargs(Py_ssize_t nargs, Py_ssize_t min, Py_ssize_t max) { if (nargs > max) { PyErr_SetString( PyExc_TypeError, "Extra positional arguments provided" ); return 0; } else if (nargs < min) { PyErr_Format( PyExc_TypeError, "Missing %zd required arguments", min - nargs ); return 0; } return 1; } /* A utility incrementally building strings */ typedef struct strbuilder { char *sep; Py_ssize_t sep_size; char *buffer; Py_ssize_t size; /* How many bytes have been written */ Py_ssize_t capacity; /* How many bytes can be written */ } strbuilder; #define strbuilder_extend_literal(self, str) strbuilder_extend(self, str, sizeof(str) - 1) static bool strbuilder_extend(strbuilder *self, const char *buf, Py_ssize_t nbytes) { bool is_first_write = self->size == 0; Py_ssize_t required = self->size + nbytes + self->sep_size; if (required > self->capacity) { self->capacity = required * 1.5; char *new_buf = PyMem_Realloc(self->buffer, self->capacity); if (new_buf == NULL) { PyErr_NoMemory(); PyMem_Free(self->buffer); self->buffer = NULL; return false; } self->buffer = new_buf; } if (self->sep_size && !is_first_write) { memcpy(self->buffer + self->size, self->sep, self->sep_size); self->size += self->sep_size; } memcpy(self->buffer + self->size, buf, nbytes); self->size += nbytes; return true; } static bool strbuilder_extend_unicode(strbuilder *self, PyObject *obj) { Py_ssize_t size; const char* buf = unicode_str_and_size(obj, &size); if (buf == NULL) return false; return strbuilder_extend(self, buf, size); } static void strbuilder_reset(strbuilder *self) { if (self->capacity != 0 && self->buffer != NULL) { PyMem_Free(self->buffer); } self->buffer = NULL; self->size = 0; self->capacity = 0; } static PyObject * strbuilder_build(strbuilder *self) { PyObject *out = PyUnicode_FromStringAndSize(self->buffer, self->size); strbuilder_reset(self); return out; } static MS_INLINE PyObject * ms_get_annotate_from_class_namespace(PyObject *namespace) { /* We replicate the behavior of the standard library utility to avoid * unnecessary function call overhead. * https://docs.python.org/3/library/annotationlib.html#annotationlib.get_annotate_from_class_namespace */ PyObject *annotate; annotate = PyDict_GetItemString(namespace, "__annotate__"); if (annotate != NULL) { Py_INCREF(annotate); return annotate; } annotate = PyDict_GetItemString(namespace, "__annotate_func__"); if (annotate != NULL) { Py_INCREF(annotate); return annotate; } Py_RETURN_NONE; } /************************************************************************* * PathNode * *************************************************************************/ #define PATH_ELLIPSIS -1 #define PATH_STR -2 #define PATH_KEY -3 typedef struct PathNode { struct PathNode *parent; Py_ssize_t index; PyObject *object; } PathNode; /* reverse the parent pointers in the path linked list */ static PathNode * pathnode_reverse(PathNode *path) { PathNode *current = path, *prev = NULL, *next = NULL; while (current != NULL) { next = current->parent; current->parent = prev; prev = current; current = next; } return prev; } static PyObject* StructMeta_get_field_name(PyObject*, Py_ssize_t); static PyObject * PathNode_ErrSuffix(PathNode *path) { strbuilder parts = {0}; PathNode *path_orig; PyObject *out = NULL, *path_repr = NULL, *groups = NULL, *group = NULL; if (path == NULL) { return PyUnicode_FromString(""); } /* Reverse the parent pointers for easier printing */ path = pathnode_reverse(path); /* Cache the original path to reset the parent pointers later */ path_orig = path; /* Start with the root element */ if (!strbuilder_extend_literal(&parts, "`$")) goto cleanup; while (path != NULL) { if (path->object != NULL) { PyObject *name; if (path->index == PATH_STR) { name = path->object; } else { name = StructMeta_get_field_name(path->object, path->index); } if (!strbuilder_extend_literal(&parts, ".")) goto cleanup; if (!strbuilder_extend_unicode(&parts, name)) goto cleanup; } else if (path->index == PATH_ELLIPSIS) { if (!strbuilder_extend_literal(&parts, "[...]")) goto cleanup; } else if (path->index == PATH_KEY) { if (groups == NULL) { groups = PyList_New(0); if (groups == NULL) goto cleanup; } if (!strbuilder_extend_literal(&parts, "`")) goto cleanup; group = strbuilder_build(&parts); if (group == NULL) goto cleanup; if (PyList_Append(groups, group) < 0) goto cleanup; Py_CLEAR(group); strbuilder_extend_literal(&parts, "`key"); } else { char buf[20]; char *p = &buf[20]; Py_ssize_t x = path->index; if (!strbuilder_extend_literal(&parts, "[")) goto cleanup; while (x >= 100) { const int64_t old = x; p -= 2; x /= 100; memcpy(p, DIGIT_TABLE + ((old - (x * 100)) << 1), 2); } if (x >= 10) { p -= 2; memcpy(p, DIGIT_TABLE + (x << 1), 2); } else { *--p = x + '0'; } if (!strbuilder_extend(&parts, p, &buf[20] - p)) goto cleanup; if (!strbuilder_extend_literal(&parts, "]")) goto cleanup; } path = path->parent; } if (!strbuilder_extend_literal(&parts, "`")) goto cleanup; if (groups == NULL) { path_repr = strbuilder_build(&parts); } else { group = strbuilder_build(&parts); if (group == NULL) goto cleanup; if (PyList_Append(groups, group) < 0) goto cleanup; PyObject *sep = PyUnicode_FromString(" in "); if (sep == NULL) goto cleanup; if (PyList_Reverse(groups) < 0) goto cleanup; path_repr = PyUnicode_Join(sep, groups); Py_DECREF(sep); } out = PyUnicode_FromFormat(" - at %U", path_repr); cleanup: Py_XDECREF(path_repr); Py_XDECREF(group); Py_XDECREF(groups); pathnode_reverse(path_orig); strbuilder_reset(&parts); return out; } /************************************************************************* * Lookup Tables for ints & strings * *************************************************************************/ typedef struct Lookup { PyObject_VAR_HEAD PyObject *tag_field; /* used for struct lookup table only */ PyObject *cls; /* Used for enum lookup table only */ bool array_like; } Lookup; static PyTypeObject IntLookup_Type; static PyTypeObject StrLookup_Type; typedef struct IntLookup { Lookup common; bool compact; } IntLookup; typedef struct IntLookupEntry { int64_t key; PyObject *value; } IntLookupEntry; typedef struct IntLookupHashmap { IntLookup base; IntLookupEntry table[]; } IntLookupHashmap; typedef struct IntLookupCompact { IntLookup base; int64_t offset; PyObject* table[]; } IntLookupCompact; typedef struct StrLookupEntry { PyObject *key; PyObject *value; } StrLookupEntry; typedef struct StrLookup { Lookup common; StrLookupEntry table[]; } StrLookup; #define Lookup_array_like(obj) ((Lookup *)(obj))->array_like #define Lookup_tag_field(obj) ((Lookup *)(obj))->tag_field #define Lookup_IsStrLookup(obj) (Py_TYPE(obj) == &StrLookup_Type) #define Lookup_IsIntLookup(obj) (Py_TYPE(obj) == &IntLookup_Type) /* Handles Enum._missing_ calls. Returns a new reference, or NULL on error. * Will decref val if non-null. */ static PyObject * _Lookup_OnMissing(Lookup *lookup, PyObject *val, PathNode *path) { if (val == NULL) return NULL; MsgspecState *mod = msgspec_get_global_state(); if (lookup->cls != NULL) { PyObject *out = PyObject_CallMethodOneArg(lookup->cls, mod->str__missing_, val); if (out == NULL) { PyErr_Clear(); } else if (out == Py_None) { Py_DECREF(out); } else { Py_DECREF(val); return out; } } PyObject *suffix = PathNode_ErrSuffix(path); if (suffix != NULL) { PyErr_Format(mod->ValidationError, "Invalid enum value %R%U", val, suffix); Py_DECREF(suffix); } Py_DECREF(val); return NULL; } static IntLookupEntry * _IntLookupHashmap_lookup(IntLookupHashmap *self, int64_t key) { IntLookupEntry *table = self->table; size_t mask = Py_SIZE(self) - 1; size_t i = key & mask; while (true) { IntLookupEntry *entry = &table[i]; if (MS_LIKELY(entry->key == key)) return entry; if (entry->value == NULL) return entry; i = (i + 1) & mask; } Py_UNREACHABLE(); } static void _IntLookupHashmap_Set(IntLookupHashmap *self, int64_t key, PyObject *value) { IntLookupEntry *entry = _IntLookupHashmap_lookup(self, key); Py_XDECREF(entry->value); Py_INCREF(value); entry->key = key; entry->value = value; } static PyObject * IntLookup_New(PyObject *arg, PyObject *tag_field, PyObject *cls, bool array_like) { Py_ssize_t nitems; PyObject *item, *items = NULL; IntLookup *self = NULL; int64_t imin = LLONG_MAX, imax = LLONG_MIN; if (PyDict_CheckExact(arg)) { nitems = PyDict_GET_SIZE(arg); } else { items = PySequence_Tuple(arg); if (items == NULL) return NULL; nitems = PyTuple_GET_SIZE(items); } /* Must have at least one item */ if (nitems == 0) { PyErr_Format( PyExc_TypeError, "Enum types must have at least one item, %R is invalid", arg ); goto cleanup; } /* Find the min/max of items, and error if any item isn't an integer or is * out of range */ #define handle(key) \ do { \ int overflow = 0; \ int64_t ival = PyLong_AsLongLongAndOverflow(key, &overflow); \ if (overflow) { \ PyErr_SetString( \ PyExc_NotImplementedError, \ "Integer values > (2**63 - 1) are not currently supported for " \ "Enum/Literal/integer tags. If you need this feature, please " \ "open an issue on GitHub." \ ); \ goto cleanup; \ } \ if (ival == -1 && PyErr_Occurred()) goto cleanup; \ if (ival < imin) { \ imin = ival; \ } \ if (ival > imax) { \ imax = ival; \ } \ } while (false) if (PyDict_CheckExact(arg)) { PyObject *key, *val; Py_ssize_t pos = 0; while (PyDict_Next(arg, &pos, &key, &val)) { handle(key); } } else { for (Py_ssize_t i = 0; i < nitems; i++) { handle(PyTuple_GET_ITEM(items, i)); } } #undef handle /* Calculate range without overflow */ uint64_t range; if (imax > 0) { range = imax; range -= imin; } else { range = imax - imin; } if (range < 1.4 * nitems) { /* Use compact representation */ size_t size = range + 1; /* XXX: In Python 3.11+ there's not an easy way to allocate an untyped * block of memory that is also tracked by the GC. To hack around this * we set `tp_itemsize = 1` for `IntLookup_Type`, and manually calculate * the size of trailing parts. It's gross, but it works. */ size_t nextra = ( sizeof(IntLookupCompact) + (size * sizeof(PyObject *)) - sizeof(IntLookup) ); IntLookupCompact *out = PyObject_GC_NewVar( IntLookupCompact, &IntLookup_Type, nextra ); if (out == NULL) goto cleanup; /* XXX: overwrite `ob_size`, since we lied above */ Py_SET_SIZE(out, size); out->offset = imin; for (size_t i = 0; i < size; i++) { out->table[i] = NULL; } #define setitem(key, val) \ do { \ int64_t ikey = PyLong_AsLongLong(key); \ out->table[ikey - imin] = val; \ Py_INCREF(val); \ } while (false) if (PyDict_CheckExact(arg)) { PyObject *key, *val; Py_ssize_t pos = 0; while (PyDict_Next(arg, &pos, &key, &val)) { setitem(key, val); } } else { for (Py_ssize_t i = 0; i < nitems; i++) { item = PyTuple_GET_ITEM(items, i); setitem(item, item); } } #undef setitem self = (IntLookup *)out; self->compact = true; } else { /* Use hashtable */ size_t needed = nitems * 4 / 3; size_t size = 4; while (size < (size_t)needed) { size <<= 1; } /* XXX: This is hacky, see comment above allocating IntLookupCompact */ size_t nextra = ( sizeof(IntLookupHashmap) + (size * sizeof(IntLookupEntry)) - sizeof(IntLookup) ); IntLookupHashmap *out = PyObject_GC_NewVar( IntLookupHashmap, &IntLookup_Type, nextra ); if (out == NULL) goto cleanup; /* XXX: overwrite `ob_size`, since we lied above */ Py_SET_SIZE(out, size); for (size_t i = 0; i < size; i++) { out->table[i].key = 0; out->table[i].value = NULL; } if (PyDict_CheckExact(arg)) { PyObject *key, *val; Py_ssize_t pos = 0; while (PyDict_Next(arg, &pos, &key, &val)) { int64_t ival = PyLong_AsLongLong(key); _IntLookupHashmap_Set(out, ival, val); } } else { for (Py_ssize_t i = 0; i < nitems; i++) { PyObject *val = PyTuple_GET_ITEM(items, i); int64_t ival = PyLong_AsLongLong(val); _IntLookupHashmap_Set(out, ival, val); } } self = (IntLookup *)out; self->compact = false; } /* Store extra metadata (struct lookup only) */ Py_XINCREF(tag_field); self->common.tag_field = tag_field; Py_XINCREF(cls); self->common.cls = cls; self->common.array_like = array_like; cleanup: Py_XDECREF(items); if (self != NULL) { PyObject_GC_Track(self); } return (PyObject *)self; } static int IntLookup_traverse(IntLookup *self, visitproc visit, void *arg) { Py_VISIT(self->common.cls); if (self->compact) { IntLookupCompact *lk = (IntLookupCompact *)self; for (Py_ssize_t i = 0; i < Py_SIZE(lk); i++) { Py_VISIT(lk->table[i]); } } else { IntLookupHashmap *lk = (IntLookupHashmap *)self; for (Py_ssize_t i = 0; i < Py_SIZE(lk); i++) { Py_VISIT(lk->table[i].value); } } return 0; } static int IntLookup_clear(IntLookup *self) { if (self->compact) { IntLookupCompact *lk = (IntLookupCompact *)self; for (Py_ssize_t i = 0; i < Py_SIZE(lk); i++) { Py_CLEAR(lk->table[i]); } } else { IntLookupHashmap *lk = (IntLookupHashmap *)self; for (Py_ssize_t i = 0; i < Py_SIZE(lk); i++) { Py_CLEAR(lk->table[i].value); } } Py_CLEAR(self->common.cls); Py_CLEAR(self->common.tag_field); return 0; } static void IntLookup_dealloc(IntLookup *self) { PyObject_GC_UnTrack(self); IntLookup_clear(self); Py_TYPE(self)->tp_free((PyObject *)self); } static PyObject * IntLookup_GetInt64(IntLookup *self, int64_t key) { if (MS_LIKELY(self->compact)) { IntLookupCompact *lk = (IntLookupCompact *)self; /* Compute the dense-table index in 64-bit space so large offsets * cannot wrap through Py_ssize_t on 32-bit builds. */ if (key >= lk->offset) { uint64_t index = (uint64_t)key - (uint64_t)(lk->offset); if (index < (uint64_t)Py_SIZE(lk)) { return lk->table[(Py_ssize_t)index]; } } return NULL; } return _IntLookupHashmap_lookup((IntLookupHashmap *)self, key)->value; } static PyObject * IntLookup_GetInt64OrError(IntLookup *self, int64_t key, PathNode *path) { PyObject *out = IntLookup_GetInt64(self, key); if (out != NULL) { Py_INCREF(out); return out; } return _Lookup_OnMissing((Lookup *)self, PyLong_FromLongLong(key), path); } static PyObject * IntLookup_GetUInt64(IntLookup *self, uint64_t key) { if (key > LLONG_MAX) return NULL; return IntLookup_GetInt64(self, key); } static PyObject * IntLookup_GetUInt64OrError(IntLookup *self, uint64_t key, PathNode *path) { PyObject *out = IntLookup_GetUInt64(self, key); if (out != NULL) { Py_INCREF(out); return out; } return _Lookup_OnMissing( (Lookup *)self, PyLong_FromUnsignedLongLong(key), path ); } static PyObject * IntLookup_GetPyIntOrError(IntLookup *self, PyObject *key, PathNode *path) { uint64_t x; bool neg, overflow; PyObject *out = NULL; overflow = fast_long_extract_parts(key, &neg, &x); if (!overflow) { if (neg) { out = IntLookup_GetInt64(self, -(int64_t)x); } else { out = IntLookup_GetUInt64(self, x); } } if (out != NULL) { Py_INCREF(out); return out; } /* PyNumber_Long call ensures input is actual int */ return _Lookup_OnMissing((Lookup *)self, PyNumber_Long(key), path); } static PyTypeObject IntLookup_Type = { PyVarObject_HEAD_INIT(NULL, 0) .tp_name = "msgspec._core.IntLookup", .tp_basicsize = sizeof(IntLookup), .tp_itemsize = 1, .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, .tp_dealloc = (destructor)IntLookup_dealloc, .tp_clear = (inquiry)IntLookup_clear, .tp_traverse = (traverseproc)IntLookup_traverse, }; static StrLookupEntry * _StrLookup_lookup(StrLookup *self, const char *key, Py_ssize_t size) { StrLookupEntry *table = self->table; size_t hash = murmur2(key, size); size_t perturb = hash; size_t mask = Py_SIZE(self) - 1; size_t i = hash & mask; while (true) { StrLookupEntry *entry = &table[i]; if (entry->value == NULL) return entry; Py_ssize_t entry_size; const char *entry_key = unicode_str_and_size_nocheck(entry->key, &entry_size); if (entry_size == size && memcmp(entry_key, key, size) == 0) return entry; /* Collision, perturb and try again */ perturb >>= 5; i = mask & (i*5 + perturb + 1); } Py_UNREACHABLE(); } static int StrLookup_Set(StrLookup *self, PyObject *key, PyObject *value) { Py_ssize_t key_size; const char *key_str = unicode_str_and_size(key, &key_size); if (key_str == NULL) return -1; StrLookupEntry *entry = _StrLookup_lookup(self, key_str, key_size); entry->key = key; Py_INCREF(key); entry->value = value; Py_INCREF(value); return 0; } static PyObject * StrLookup_New(PyObject *arg, PyObject *tag_field, PyObject *cls, bool array_like) { Py_ssize_t nitems; PyObject *item, *items = NULL; StrLookup *self = NULL; if (PyDict_CheckExact(arg)) { nitems = PyDict_GET_SIZE(arg); } else { items = PySequence_Tuple(arg); if (items == NULL) return NULL; nitems = PyTuple_GET_SIZE(items); } /* Must have at least one item */ if (nitems == 0) { PyErr_Format( PyExc_TypeError, "Enum types must have at least one item, %R is invalid", arg ); goto cleanup; } size_t needed = nitems * 4 / 3; size_t size = 4; while (size < (size_t)needed) { size <<= 1; } self = PyObject_GC_NewVar(StrLookup, &StrLookup_Type, size); if (self == NULL) goto cleanup; /* Zero out memory */ self->common.cls = NULL; self->common.tag_field = NULL; for (size_t i = 0; i < size; i++) { self->table[i].key = NULL; self->table[i].value = NULL; } if (PyDict_CheckExact(arg)) { PyObject *key, *val; Py_ssize_t pos = 0; while (PyDict_Next(arg, &pos, &key, &val)) { if (!PyUnicode_CheckExact(key)) { PyErr_SetString(PyExc_RuntimeError, "Enum values must be strings"); Py_CLEAR(self); goto cleanup; } if (StrLookup_Set(self, key, val) < 0) { Py_CLEAR(self); goto cleanup; } } } else { for (Py_ssize_t i = 0; i < nitems; i++) { item = PyTuple_GET_ITEM(items, i); if (!PyUnicode_CheckExact(item)) { PyErr_SetString(PyExc_RuntimeError, "Enum values must be strings"); Py_CLEAR(self); goto cleanup; } if (StrLookup_Set(self, item, item) < 0) { Py_CLEAR(self); goto cleanup; } } } Py_XINCREF(cls); self->common.cls = cls; Py_XINCREF(tag_field); self->common.tag_field = tag_field; self->common.array_like = array_like; cleanup: Py_XDECREF(items); if (self != NULL) { PyObject_GC_Track(self); } return (PyObject *)self; } static int StrLookup_traverse(StrLookup *self, visitproc visit, void *arg) { Py_VISIT(self->common.cls); for (Py_ssize_t i = 0; i < Py_SIZE(self); i++) { Py_VISIT(self->table[i].key); Py_VISIT(self->table[i].value); } return 0; } static int StrLookup_clear(StrLookup *self) { for (Py_ssize_t i = 0; i < Py_SIZE(self); i++) { Py_CLEAR(self->table[i].key); Py_CLEAR(self->table[i].value); } Py_CLEAR(self->common.cls); Py_CLEAR(self->common.tag_field); return 0; } static void StrLookup_dealloc(StrLookup *self) { PyObject_GC_UnTrack(self); StrLookup_clear(self); Py_TYPE(self)->tp_free((PyObject *)self); } static PyObject * StrLookup_Get(StrLookup *self, const char *key, Py_ssize_t size) { StrLookupEntry *entry = _StrLookup_lookup(self, key, size); return entry->value; } static PyObject * StrLookup_GetOrError( StrLookup *self, const char *key, Py_ssize_t size, PathNode *path ) { PyObject *out = StrLookup_Get(self, key, size); if (out != NULL) { Py_INCREF(out); return out; } return _Lookup_OnMissing( (Lookup *)self, PyUnicode_FromStringAndSize(key, size), path ); } static PyTypeObject StrLookup_Type = { PyVarObject_HEAD_INIT(NULL, 0) .tp_name = "msgspec._core.StrLookup", .tp_basicsize = sizeof(StrLookup), .tp_itemsize = sizeof(StrLookupEntry), .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, .tp_dealloc = (destructor) StrLookup_dealloc, .tp_clear = (inquiry)StrLookup_clear, .tp_traverse = (traverseproc) StrLookup_traverse, }; /************************************************************************* * Raw * *************************************************************************/ static PyTypeObject Raw_Type; typedef struct Raw { PyObject_HEAD PyObject *base; char *buf; Py_ssize_t len; bool is_view; } Raw; static PyObject * Raw_New(PyObject *msg) { Raw *out = (Raw *)Raw_Type.tp_alloc(&Raw_Type, 0); if (out == NULL) return NULL; if (PyBytes_CheckExact(msg)) { Py_INCREF(msg); out->base = msg; out->buf = PyBytes_AS_STRING(msg); out->len = PyBytes_GET_SIZE(msg); out->is_view = false; } else if (PyUnicode_CheckExact(msg)) { out->base = msg; out->buf = (char *)unicode_str_and_size(msg, &out->len); if (out->buf == NULL) return NULL; Py_INCREF(msg); out->is_view = false; } else { Py_buffer buffer; if (PyObject_GetBuffer(msg, &buffer, PyBUF_CONTIG_RO) < 0) { Py_DECREF(out); return NULL; } out->base = buffer.obj; out->buf = buffer.buf; out->len = buffer.len; out->is_view = true; } return (PyObject *)out; } PyDoc_STRVAR(Raw__doc__, "Raw(msg=b'', /)\n" "--\n" "\n" "A buffer containing an encoded message.\n" "\n" "Raw objects have two common uses:\n" "\n" "- During decoding. Fields annotated with the ``Raw`` type won't be decoded\n" " immediately, but will instead return a ``Raw`` object with a view into the\n" " original message where that field is encoded. This is useful for decoding\n" " fields whose type may only be inferred after decoding other fields.\n" "- During encoding. Raw objects wrap pre-encoded messages. These can be added\n" " as components of larger messages without having to pay the cost of decoding\n" " and re-encoding them.\n" "\n" "Parameters\n" "----------\n" "msg: bytes, bytearray, memoryview, or str, optional\n" " A buffer containing an encoded message. One of bytes, bytearray, memoryview,\n" " str, or any object that implements the buffer protocol. If not present,\n" " defaults to an empty buffer." ); static PyObject * Raw_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) { PyObject *msg; Py_ssize_t nargs, nkwargs; nargs = PyTuple_GET_SIZE(args); nkwargs = (kwargs == NULL) ? 0 : PyDict_GET_SIZE(kwargs); if (nkwargs != 0) { PyErr_SetString( PyExc_TypeError, "Raw takes no keyword arguments" ); return NULL; } else if (nargs == 0) { msg = PyBytes_FromStringAndSize(NULL, 0); if (msg == NULL) return NULL; /* This looks weird, but is safe since the empty bytes object is an * immortal singleton */ Py_DECREF(msg); } else if (nargs == 1) { msg = PyTuple_GET_ITEM(args, 0); } else { PyErr_Format( PyExc_TypeError, "Raw expected at most 1 arguments, got %zd", nargs ); return NULL; } return Raw_New(msg); } static void Raw_dealloc(Raw *self) { if (self->base != NULL) { if (!self->is_view) { Py_DECREF(self->base); } else { Py_buffer buffer; buffer.obj = self->base; buffer.len = self->len; buffer.buf = self->buf; ms_release_buffer(&buffer); } } Py_TYPE(self)->tp_free((PyObject *)self); } static PyObject * Raw_FromView(PyObject *buffer_obj, char *data, Py_ssize_t len) { Raw *out = (Raw *)Raw_Type.tp_alloc(&Raw_Type, 0); if (out == NULL) return NULL; Py_buffer buffer; if (ms_get_buffer(buffer_obj, &buffer) < 0) { Py_DECREF(out); return NULL; } out->base = buffer.obj; out->buf = data; out->len = len; out->is_view = true; return (PyObject *)out; } static PyObject * Raw_richcompare(Raw *self, PyObject *other, int op) { if (Py_TYPE(other) != &Raw_Type) { Py_RETURN_NOTIMPLEMENTED; } if (op != Py_EQ && op != Py_NE) { Py_RETURN_NOTIMPLEMENTED; } Raw *raw_other = (Raw *)other; bool equal = ( self == raw_other || ( (self->len == raw_other->len) && (memcmp(self->buf, raw_other->buf, self->len) == 0) ) ); bool result = (op == Py_EQ) ? equal : !equal; if (result) { Py_RETURN_TRUE; } Py_RETURN_FALSE; } static int Raw_buffer_getbuffer(Raw *self, Py_buffer *view, int flags) { return PyBuffer_FillInfo(view, (PyObject *)self, self->buf, self->len, 1, flags); } static PyBufferProcs Raw_as_buffer = { .bf_getbuffer = (getbufferproc)Raw_buffer_getbuffer }; static Py_ssize_t Raw_length(Raw *self) { return self->len; } static PySequenceMethods Raw_as_sequence = { .sq_length = (lenfunc)Raw_length }; static PyObject * Raw_reduce(Raw *self, PyObject *unused) { if (!self->is_view) { return Py_BuildValue("O(O)", &Raw_Type, self->base); } return Py_BuildValue("O(y#)", &Raw_Type, self->buf, self->len); } PyDoc_STRVAR(Raw_copy__doc__, "copy($self, /)\n" "--\n" "\n" "Copy a Raw object.\n" "\n" "If the raw message is backed by a memoryview into a larger buffer (as happens\n" "during decoding), the message is copied and the reference to the larger buffer\n" "released. This may be useful to reduce memory usage if a Raw object created\n" "during decoding will be kept in memory for a while rather than immediately\n" "decoded and dropped." ); static PyObject * Raw_copy(Raw *self, PyObject *unused) { if (!self->is_view) { Py_INCREF(self); return (PyObject *)self; } PyObject *buf = PyBytes_FromStringAndSize(self->buf, self->len); if (buf == NULL) return NULL; PyObject *out = Raw_New(buf); Py_DECREF(buf); return out; } static PyMethodDef Raw_methods[] = { {"__reduce__", (PyCFunction)Raw_reduce, METH_NOARGS}, {"copy", (PyCFunction)Raw_copy, METH_NOARGS, Raw_copy__doc__}, {NULL, NULL}, }; static PyTypeObject Raw_Type = { PyVarObject_HEAD_INIT(NULL, 0) .tp_name = "msgspec.Raw", .tp_doc = Raw__doc__, .tp_basicsize = sizeof(Raw), .tp_itemsize = sizeof(char), .tp_flags = Py_TPFLAGS_DEFAULT, .tp_new = Raw_new, .tp_dealloc = (destructor) Raw_dealloc, .tp_as_buffer = &Raw_as_buffer, .tp_as_sequence = &Raw_as_sequence, .tp_methods = Raw_methods, .tp_richcompare = (richcmpfunc) Raw_richcompare, }; /************************************************************************* * Meta * *************************************************************************/ static PyTypeObject Meta_Type; typedef struct Meta { PyObject_HEAD PyObject *gt; PyObject *ge; PyObject *lt; PyObject *le; PyObject *multiple_of; PyObject *pattern; PyObject *regex; PyObject *min_length; PyObject *max_length; PyObject *tz; PyObject *title; PyObject *description; PyObject *examples; PyObject *extra_json_schema; PyObject *extra; } Meta; static bool ensure_is_string(PyObject *val, const char *param) { if (PyUnicode_CheckExact(val)) return true; PyErr_Format( PyExc_TypeError, "`%s` must be a str, got %.200s", param, Py_TYPE(val)->tp_name ); return false; } static bool ensure_is_bool(PyObject *val, const char *param) { if (val == Py_True || val == Py_False) return true; PyErr_Format( PyExc_TypeError, "`%s` must be a bool, got %.200s", param, Py_TYPE(val)->tp_name ); return false; } static bool ensure_is_nonnegative_integer(PyObject *val, const char *param) { if (!PyLong_CheckExact(val)) { PyErr_Format( PyExc_TypeError, "`%s` must be an int, got %.200s", param, Py_TYPE(val)->tp_name ); return false; } Py_ssize_t x = PyLong_AsSsize_t(val); if (x >= 0) return true; if (PyErr_Occurred()) { /* Doesn't fit in a Py_ssize_t, in either direction. Without this the * pending OverflowError is replaced by the message below, which for a * large positive value says it isn't >= 0. */ PyErr_Clear(); PyErr_Format( PyExc_ValueError, "`%s` is out of range, %R is not a valid length", param, val ); return false; } PyErr_Format(PyExc_ValueError, "`%s` must be >= 0, got %R", param, val); return false; } static bool ensure_is_finite_numeric(PyObject *val, const char *param, bool positive) { double x; if (PyLong_CheckExact(val)) { x = PyLong_AsDouble(val); } else if (PyFloat_CheckExact(val)) { x = PyFloat_AS_DOUBLE(val); if (!isfinite(x)) { PyErr_Format( PyExc_ValueError, "`%s` must be finite, %R is not supported", param, val ); return false; } } else { PyErr_Format( PyExc_TypeError, "`%s` must be an int or float, got %.200s", param, Py_TYPE(val)->tp_name ); return false; } if (positive && x <= 0) { PyErr_Format(PyExc_ValueError, "`%s` must be > 0", param); return false; } return true; } PyDoc_STRVAR(Meta__doc__, "Meta(*, gt=None, ge=None, lt=None, le=None, multiple_of=None, pattern=None, " "min_length=None, max_length=None, tz=None, title=None, description=None, " "examples=None, extra_json_schema=None, extra=None)\n" "--\n" "\n" "Extra metadata and constraints for a type or field.\n" "\n" "Parameters\n" "----------\n" "gt : int or float, optional\n" " The annotated value must be greater than ``gt``.\n" "ge : int or float, optional\n" " The annotated value must be greater than or equal to ``ge``.\n" "lt : int or float, optional\n" " The annotated value must be less than ``lt``.\n" "le : int or float, optional\n" " The annotated value must be less than or equal to ``le``.\n" "multiple_of : int or float, optional\n" " The annotated value must be a multiple of ``multiple_of``.\n" "pattern : str, optional\n" " A regex pattern that the annotated value must match against. Note that\n" " the pattern is treated as **unanchored**, meaning the ``re.search``\n" " method is used when matching.\n" "min_length: int, optional\n" " The annotated value must have a length greater than or equal to\n" " ``min_length``.\n" "max_length: int, optional\n" " The annotated value must have a length less than or equal to\n" " ``max_length``.\n" "tz: bool, optional\n" " Configures the timezone-requirements for annotated ``datetime``/``time``\n" " types. Set to ``True`` to require timezone-aware values, or ``False`` to\n" " require timezone-naive values. The default is ``None``, which accepts\n" " either timezone-aware or timezone-naive values.\n" "title: str, optional\n" " The title to use for the annotated value when generating a json-schema.\n" "description: str, optional\n" " The description to use for the annotated value when generating a\n" " json-schema.\n" "examples: list, optional\n" " A list of examples to use for the annotated value when generating a\n" " json-schema.\n" "extra_json_schema: dict, optional\n" " A dict of extra fields to set for the annotated value when generating\n" " a json-schema. This dict is recursively merged with the generated schema,\n" " with ``extra_json_schema`` overriding any conflicting autogenerated fields.\n" "extra: dict, optional\n" " Any additional user-defined metadata.\n" "\n" "Examples\n" "--------\n" "Here we use ``Meta`` to add constraints on two different types. The first\n" "defines a new type alias ``NonNegativeInt``, which is an integer that must be\n" "``>= 0``. This type alias can be reused in multiple locations. The second uses\n" "``Meta`` inline in a struct definition to restrict the ``name`` string field\n" "to a maximum length of 32 characters.\n" "\n" ">>> import msgspec\n" ">>> from typing import Annotated\n" ">>> from msgspec import Struct, Meta\n" ">>> NonNegativeInt = Annotated[int, Meta(ge=0)]\n" ">>> class User(Struct):\n" "... name: Annotated[str, Meta(max_length=32)]\n" "... age: NonNegativeInt\n" "...\n" ">>> msgspec.json.decode(b'{\"name\": \"alice\", \"age\": 25}', type=User)\n" "User(name='alice', age=25)\n" ); static PyObject * Meta_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) { char *kwlist[] = { "gt", "ge", "lt", "le", "multiple_of", "pattern", "min_length", "max_length", "tz", "title", "description", "examples", "extra_json_schema", "extra", NULL }; PyObject *gt = NULL, *ge = NULL, *lt = NULL, *le = NULL, *multiple_of = NULL; PyObject *pattern = NULL, *min_length = NULL, *max_length = NULL, *tz = NULL; PyObject *title = NULL, *description = NULL, *examples = NULL; PyObject *extra_json_schema = NULL, *extra = NULL; PyObject *regex = NULL; if (!PyArg_ParseTupleAndKeywords( args, kwargs, "|$OOOOOOOOOOOOOO:Meta.__new__", kwlist, >, &ge, <, &le, &multiple_of, &pattern, &min_length, &max_length, &tz, &title, &description, &examples, &extra_json_schema, &extra ) ) return NULL; #define NONE_TO_NULL(x) do { if (x == Py_None) {x = NULL;} } while(0) NONE_TO_NULL(gt); NONE_TO_NULL(ge); NONE_TO_NULL(lt); NONE_TO_NULL(le); NONE_TO_NULL(multiple_of); NONE_TO_NULL(pattern); NONE_TO_NULL(min_length); NONE_TO_NULL(max_length); NONE_TO_NULL(tz); NONE_TO_NULL(title); NONE_TO_NULL(description); NONE_TO_NULL(examples); NONE_TO_NULL(extra_json_schema); NONE_TO_NULL(extra); #undef NONE_TO_NULL /* Check parameter types/values */ if (gt != NULL && !ensure_is_finite_numeric(gt, "gt", false)) return NULL; if (ge != NULL && !ensure_is_finite_numeric(ge, "ge", false)) return NULL; if (lt != NULL && !ensure_is_finite_numeric(lt, "lt", false)) return NULL; if (le != NULL && !ensure_is_finite_numeric(le, "le", false)) return NULL; if (multiple_of != NULL && !ensure_is_finite_numeric(multiple_of, "multiple_of", true)) return NULL; if (pattern != NULL && !ensure_is_string(pattern, "pattern")) return NULL; if (min_length != NULL && !ensure_is_nonnegative_integer(min_length, "min_length")) return NULL; if (max_length != NULL && !ensure_is_nonnegative_integer(max_length, "max_length")) return NULL; if (tz != NULL && !ensure_is_bool(tz, "tz")) return NULL; /* Check multiple constraint restrictions */ if (gt != NULL && ge != NULL) { PyErr_SetString(PyExc_ValueError, "Cannot specify both `gt` and `ge`"); return NULL; } if (lt != NULL && le != NULL) { PyErr_SetString(PyExc_ValueError, "Cannot specify both `lt` and `le`"); return NULL; } bool numeric = (gt != NULL || ge != NULL || lt != NULL || le != NULL || multiple_of != NULL); bool other = (pattern != NULL || min_length != NULL || max_length != NULL || tz != NULL); if (numeric && other) { PyErr_SetString( PyExc_ValueError, "Cannot mix numeric constraints (gt, lt, ...) with non-numeric " "constraints (pattern, min_length, max_length, tz)" ); return NULL; } /* Check types/values of extra metadata */ if (title != NULL && !ensure_is_string(title, "title")) return NULL; if (description != NULL && !ensure_is_string(description, "description")) return NULL; if (examples != NULL && !PyList_CheckExact(examples)) { PyErr_Format( PyExc_TypeError, "`examples` must be a list, got %.200s", Py_TYPE(examples)->tp_name ); return NULL; } if (extra_json_schema != NULL && !PyDict_CheckExact(extra_json_schema)) { PyErr_Format( PyExc_TypeError, "`extra_json_schema` must be a dict, got %.200s", Py_TYPE(extra_json_schema)->tp_name ); return NULL; } if (extra != NULL && !PyDict_CheckExact(extra)) { PyErr_Format( PyExc_TypeError, "`extra` must be a dict, got %.200s", Py_TYPE(extra)->tp_name ); return NULL; } /* regex compile pattern if provided */ if (pattern != NULL) { MsgspecState *mod = msgspec_get_global_state(); regex = PyObject_CallOneArg(mod->re_compile, pattern); if (regex == NULL) return NULL; } Meta *out = (Meta *)Meta_Type.tp_alloc(&Meta_Type, 0); if (out == NULL) { Py_XDECREF(regex); return NULL; } /* SET_FIELD handles borrowed values that need an extra INCREF. * SET_FIELD_OWNED passes through references we already own. */ #define SET_FIELD(x) do { Py_XINCREF(x); out->x = x; } while(0) #define SET_FIELD_OWNED(x) do { out->x = x; } while(0) SET_FIELD(gt); SET_FIELD(ge); SET_FIELD(lt); SET_FIELD(le); SET_FIELD(multiple_of); SET_FIELD(pattern); SET_FIELD_OWNED(regex); SET_FIELD(min_length); SET_FIELD(max_length); SET_FIELD(tz); SET_FIELD(title); SET_FIELD(description); SET_FIELD(examples); SET_FIELD(extra_json_schema); SET_FIELD(extra); #undef SET_FIELD #undef SET_FIELD_OWNED return (PyObject *)out; } static int Meta_traverse(Meta *self, visitproc visit, void *arg) { Py_VISIT(self->regex); Py_VISIT(self->examples); Py_VISIT(self->extra_json_schema); Py_VISIT(self->extra); return 0; } static int Meta_clear(Meta *self) { Py_CLEAR(self->gt); Py_CLEAR(self->ge); Py_CLEAR(self->lt); Py_CLEAR(self->le); Py_CLEAR(self->multiple_of); Py_CLEAR(self->pattern); Py_CLEAR(self->regex); Py_CLEAR(self->min_length); Py_CLEAR(self->max_length); Py_CLEAR(self->tz); Py_CLEAR(self->title); Py_CLEAR(self->description); Py_CLEAR(self->examples); Py_CLEAR(self->extra_json_schema); Py_CLEAR(self->extra); return 0; } static void Meta_dealloc(Meta *self) { PyObject_GC_UnTrack(self); Meta_clear(self); Py_TYPE(self)->tp_free((PyObject *)self); } static bool _meta_repr_part(strbuilder *builder, const char *prefix, Py_ssize_t prefix_size, PyObject *field, bool *first) { if (*first) { *first = false; } else { if (!strbuilder_extend_literal(builder, ", ")) return false; } if (!strbuilder_extend(builder, prefix, prefix_size)) return false; PyObject *repr = PyObject_Repr(field); if (repr == NULL) return false; bool ok = strbuilder_extend_unicode(builder, repr); Py_DECREF(repr); return ok; } static PyObject * Meta_repr(Meta *self) { strbuilder builder = {0}; bool first = true; if (!strbuilder_extend_literal(&builder, "msgspec.Meta(")) return NULL; /* sizeof(#field) is the length of the field name + 1 (null terminator). We * want the length of field name + 1 (for the `=`). */ #define DO_REPR(field) do { \ if (self->field != NULL) { \ if (!_meta_repr_part(&builder, #field "=", sizeof(#field), self->field, &first)) { \ goto error; \ } \ } \ } while(0) DO_REPR(gt); DO_REPR(ge); DO_REPR(lt); DO_REPR(le); DO_REPR(multiple_of); DO_REPR(pattern); DO_REPR(min_length); DO_REPR(max_length); DO_REPR(tz); DO_REPR(title); DO_REPR(description); DO_REPR(examples); DO_REPR(extra_json_schema); DO_REPR(extra); #undef DO_REPR if (!strbuilder_extend_literal(&builder, ")")) goto error; return strbuilder_build(&builder); error: strbuilder_reset(&builder); return NULL; } static PyObject * Meta_rich_repr(PyObject *py_self, PyObject *args) { Meta *self = (Meta *)py_self; PyObject *out = PyList_New(0); if (out == NULL) goto error; #define DO_REPR(field) do { \ if (self->field != NULL) { \ PyObject *part = Py_BuildValue("(UO)", #field, self->field); \ if (part == NULL) goto error;\ int ret = PyList_Append(out, part);\ Py_DECREF(part);\ if (ret < 0) goto error;\ } } while(0) DO_REPR(gt); DO_REPR(ge); DO_REPR(lt); DO_REPR(le); DO_REPR(multiple_of); DO_REPR(pattern); DO_REPR(min_length); DO_REPR(max_length); DO_REPR(tz); DO_REPR(title); DO_REPR(description); DO_REPR(examples); DO_REPR(extra_json_schema); DO_REPR(extra); #undef DO_REPR return out; error: Py_XDECREF(out); return NULL; } static int _meta_richcompare_part(PyObject *left, PyObject *right) { if ((left == NULL) != (right == NULL)) { return 0; } if (left != NULL) { return PyObject_RichCompareBool(left, right, Py_EQ); } else { return 1; } } static PyObject * Meta_richcompare(Meta *self, PyObject *py_other, int op) { int equal = 1; PyObject *out; if (Py_TYPE(py_other) != &Meta_Type) { Py_RETURN_NOTIMPLEMENTED; } if (!(op == Py_EQ || op == Py_NE)) { Py_RETURN_NOTIMPLEMENTED; } Meta *other = (Meta *)py_other; /* Only need to loop if self is not other` */ if (MS_LIKELY(self != other)) { #define DO_COMPARE(field) do { \ equal = _meta_richcompare_part(self->field, other->field); \ if (equal < 0) return NULL; \ if (!equal) goto done; \ } while (0) DO_COMPARE(gt); DO_COMPARE(ge); DO_COMPARE(lt); DO_COMPARE(le); DO_COMPARE(multiple_of); DO_COMPARE(pattern); DO_COMPARE(min_length); DO_COMPARE(max_length); DO_COMPARE(tz); DO_COMPARE(title); DO_COMPARE(description); DO_COMPARE(examples); DO_COMPARE(extra_json_schema); DO_COMPARE(extra); } #undef DO_COMPARE done: if (op == Py_EQ) { out = equal ? Py_True : Py_False; } else { out = (!equal) ? Py_True : Py_False; } Py_INCREF(out); return out; } static Py_hash_t Meta_hash(Meta *self) { Py_ssize_t nfields = 0; Py_uhash_t acc = MS_HASH_XXPRIME_5; #define DO_HASH(field) \ if (self->field != NULL) { \ Py_uhash_t lane = PyObject_Hash(self->field); \ if (lane == (Py_uhash_t)-1) return -1; \ acc += lane * MS_HASH_XXPRIME_2; \ acc = MS_HASH_XXROTATE(acc); \ acc *= MS_HASH_XXPRIME_1; \ nfields += 1; \ } DO_HASH(gt); DO_HASH(ge); DO_HASH(lt); DO_HASH(le); DO_HASH(multiple_of); DO_HASH(pattern); DO_HASH(min_length); DO_HASH(max_length); DO_HASH(tz); DO_HASH(title); DO_HASH(description); /* Leave out examples & description, since they could be unhashable */ #undef DO_HASH acc += nfields ^ (MS_HASH_XXPRIME_5 ^ 3527539UL); return (acc == (Py_uhash_t)-1) ? 1546275796 : acc; } static PyMethodDef Meta_methods[] = { {"__rich_repr__", Meta_rich_repr, METH_NOARGS, "rich repr"}, {NULL, NULL}, }; static PyMemberDef Meta_members[] = { {"gt", T_OBJECT, offsetof(Meta, gt), READONLY, NULL}, {"ge", T_OBJECT, offsetof(Meta, ge), READONLY, NULL}, {"lt", T_OBJECT, offsetof(Meta, lt), READONLY, NULL}, {"le", T_OBJECT, offsetof(Meta, le), READONLY, NULL}, {"multiple_of", T_OBJECT, offsetof(Meta, multiple_of), READONLY, NULL}, {"pattern", T_OBJECT, offsetof(Meta, pattern), READONLY, NULL}, {"min_length", T_OBJECT, offsetof(Meta, min_length), READONLY, NULL}, {"max_length", T_OBJECT, offsetof(Meta, max_length), READONLY, NULL}, {"tz", T_OBJECT, offsetof(Meta, tz), READONLY, NULL}, {"title", T_OBJECT, offsetof(Meta, title), READONLY, NULL}, {"description", T_OBJECT, offsetof(Meta, description), READONLY, NULL}, {"examples", T_OBJECT, offsetof(Meta, examples), READONLY, NULL}, {"extra_json_schema", T_OBJECT, offsetof(Meta, extra_json_schema), READONLY, NULL}, {"extra", T_OBJECT, offsetof(Meta, extra), READONLY, NULL}, {NULL}, }; static PyTypeObject Meta_Type = { PyVarObject_HEAD_INIT(NULL, 0) .tp_name = "msgspec.Meta", .tp_doc = Meta__doc__, .tp_basicsize = sizeof(Meta), .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, .tp_new = Meta_new, .tp_traverse = (traverseproc) Meta_traverse, .tp_clear = (inquiry) Meta_clear, .tp_dealloc = (destructor) Meta_dealloc, .tp_methods = Meta_methods, .tp_members = Meta_members, .tp_repr = (reprfunc) Meta_repr, .tp_richcompare = (richcmpfunc) Meta_richcompare, .tp_hash = (hashfunc) Meta_hash }; /************************************************************************* * NODEFAULT singleton * *************************************************************************/ PyObject _NoDefault_Object; #define NODEFAULT &_NoDefault_Object PyDoc_STRVAR(nodefault__doc__, "NoDefaultType()\n" "--\n" "\n" "A singleton indicating no default value is configured." ); static PyObject * nodefault_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) { if (PyTuple_GET_SIZE(args) || (kwargs && PyDict_GET_SIZE(kwargs))) { PyErr_SetString(PyExc_TypeError, "NoDefaultType takes no arguments"); return NULL; } Py_INCREF(NODEFAULT); return NODEFAULT; } static PyObject * nodefault_repr(PyObject *op) { return PyUnicode_FromString("NODEFAULT"); } static PyObject * nodefault_reduce(PyObject *op, PyObject *args) { return PyUnicode_FromString("NODEFAULT"); } static PyMethodDef nodefault_methods[] = { {"__reduce__", nodefault_reduce, METH_NOARGS, NULL}, {NULL, NULL} }; PyTypeObject NoDefault_Type = { PyVarObject_HEAD_INIT(NULL, 0) .tp_name = "msgspec._core.NoDefaultType", .tp_doc = nodefault__doc__, .tp_repr = nodefault_repr, .tp_flags = Py_TPFLAGS_DEFAULT, .tp_methods = nodefault_methods, .tp_new = nodefault_new, .tp_dealloc = 0, .tp_itemsize = 0, .tp_basicsize = 0 }; PyObject _NoDefault_Object = _PyObject_HEAD_INIT(&NoDefault_Type); /************************************************************************* * UNSET singleton * *************************************************************************/ PyObject _Unset_Object; #define UNSET &_Unset_Object PyDoc_STRVAR(unset__doc__, "UnsetType()\n" "--\n" "\n" "A singleton indicating a field value is unset.\n" "\n" "This may be useful for working with message schemas where an unset field\n" "in an object needs to be treated differently than one containing an explicit\n" "``None`` value. In this case, you may use ``UNSET`` as the default value,\n" "rather than ``None`` when defining object schemas. This feature is supported\n" "for any `msgspec.Struct`, `dataclasses` or `attrs` types.\n" "\n" "Examples\n" "--------\n" ">>> from msgspec import Struct, UnsetType, UNSET, json\n" ">>> class Example(Struct):\n" "... x: int\n" "... y: int | None | UnsetType = UNSET\n" "\n" "During encoding, any field containing ``UNSET`` is omitted from the message.\n" "\n" ">>> json.encode(Example(1))\n" "b'{\"x\":1}'\n" ">>> json.encode(Example(1, 2))\n" "b'{\"x\":1,\"y\":2}'\n" "\n" "During decoding, if a field isn't explicitly set in the message, the default\n" "value of ``UNSET`` will be set instead. This lets downstream consumers\n" "determine whether a field was left unset, or explicitly set to ``None``\n" "\n" ">>> json.decode(b'{\"x\": 1}', type=Example) # unset\n" "Example(x=1, y=UNSET)\n" ">>> json.decode(b'{\"x\": 1, \"y\": null}', type=Example) # explicit null\n" "Example(x=1, y=None)\n" ">>> json.decode(b'{\"x\": 1, \"y\": 2}', type=Example) # explicit value\n" "Example(x=1, y=2)" ); static PyObject * unset_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) { if (PyTuple_GET_SIZE(args) || (kwargs && PyDict_GET_SIZE(kwargs))) { PyErr_SetString(PyExc_TypeError, "UnsetType takes no arguments"); return NULL; } Py_INCREF(UNSET); return UNSET; } static PyObject * unset_repr(PyObject *op) { return PyUnicode_FromString("UNSET"); } static PyObject * unset_reduce(PyObject *op, PyObject *args) { return PyUnicode_FromString("UNSET"); } static PyMethodDef unset_methods[] = { {"__reduce__", unset_reduce, METH_NOARGS, NULL}, {NULL, NULL} }; static int unset_bool(PyObject *obj) { return 0; }; static PyNumberMethods unset_as_number = { .nb_bool = unset_bool, }; PyTypeObject Unset_Type = { PyVarObject_HEAD_INIT(NULL, 0) .tp_name = "msgspec.UnsetType", .tp_doc = unset__doc__, .tp_repr = unset_repr, .tp_flags = Py_TPFLAGS_DEFAULT, .tp_methods = unset_methods, .tp_as_number = &unset_as_number, .tp_new = unset_new, .tp_dealloc = 0, .tp_itemsize = 0, .tp_basicsize = 0 }; PyObject _Unset_Object = _PyObject_HEAD_INIT(&Unset_Type); /************************************************************************* * Factory * *************************************************************************/ static PyTypeObject Factory_Type; typedef struct { PyObject_HEAD PyObject *factory; } Factory; static PyObject * Factory_New(PyObject *factory) { if (!PyCallable_Check(factory)) { PyErr_SetString(PyExc_TypeError, "default_factory must be callable"); return NULL; } Factory *out = (Factory *)Factory_Type.tp_alloc(&Factory_Type, 0); if (out == NULL) return NULL; Py_INCREF(factory); out->factory = factory; return (PyObject *)out; } static PyObject * Factory_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) { Py_ssize_t nkwargs = (kwargs == NULL) ? 0 : PyDict_GET_SIZE(kwargs); Py_ssize_t nargs = PyTuple_GET_SIZE(args); if (nkwargs != 0) { PyErr_SetString(PyExc_TypeError, "Factory takes no keyword arguments"); return NULL; } else if (nargs != 1) { PyErr_Format( PyExc_TypeError, "Factory expected 1 argument, got %zd", nargs ); return NULL; } else { return Factory_New(PyTuple_GET_ITEM(args, 0)); } } static PyObject * Factory_Call(PyObject *self) { PyObject *factory = ((Factory *)(self))->factory; /* Inline two common factory types */ if (factory == (PyObject *)(&PyList_Type)) { return PyList_New(0); } else if (factory == (PyObject *)(&PyDict_Type)) { return PyDict_New(); } return PyObject_CallNoArgs(factory); } static PyObject * Factory_repr(PyObject *op) { return PyUnicode_FromString(""); } static int Factory_traverse(Factory *self, visitproc visit, void *arg) { Py_VISIT(self->factory); return 0; } static int Factory_clear(Factory *self) { Py_CLEAR(self->factory); return 0; } static void Factory_dealloc(Factory *self) { PyObject_GC_UnTrack(self); Factory_clear(self); Py_TYPE(self)->tp_free((PyObject *)self); } static PyMemberDef Factory_members[] = { {"factory", T_OBJECT_EX, offsetof(Factory, factory), READONLY, "The factory function"}, {NULL}, }; static PyTypeObject Factory_Type = { PyVarObject_HEAD_INIT(NULL, 0) .tp_name = "msgspec._core.Factory", .tp_basicsize = sizeof(Factory), .tp_itemsize = 0, .tp_new = Factory_new, .tp_repr = Factory_repr, .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, .tp_clear = (inquiry)Factory_clear, .tp_traverse = (traverseproc)Factory_traverse, .tp_dealloc = (destructor) Factory_dealloc, .tp_members = Factory_members, }; /************************************************************************* * Field * *************************************************************************/ static PyTypeObject Field_Type; typedef struct { PyObject_HEAD PyObject *default_value; PyObject *default_factory; PyObject *name; } Field; PyDoc_STRVAR(Field__doc__, "Configuration for a Struct field.\n" "\n" "Parameters\n" "----------\n" "default : Any, optional\n" " A default value to use for this field.\n" "default_factory : callable, optional\n" " A zero-argument function called to generate a new default value\n" " per-instance, rather than using a constant value as in ``default``.\n" "name : str, optional\n" " The name to use when encoding/decoding this field. If present, this\n" " will override any struct-level configuration using the ``rename``\n" " option for this field." ); static PyObject * Field_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) { char *kwlist[] = {"default", "default_factory", "name", NULL}; PyObject *default_value = NODEFAULT, *default_factory = NODEFAULT; PyObject *name = Py_None; if ( !PyArg_ParseTupleAndKeywords( args, kwargs, "|$OOO", kwlist, &default_value, &default_factory, &name ) ) { return NULL; } if (default_value != NODEFAULT && default_factory != NODEFAULT) { PyErr_SetString( PyExc_TypeError, "Cannot set both `default` and `default_factory`" ); return NULL; } if (default_factory != NODEFAULT) { if (!PyCallable_Check(default_factory)) { PyErr_SetString(PyExc_TypeError, "default_factory must be callable"); return NULL; } } if (name == Py_None) { name = NULL; } else if (!PyUnicode_CheckExact(name)) { PyErr_SetString(PyExc_TypeError, "name must be a str or None"); return NULL; } Field *self = (Field *)Field_Type.tp_alloc(&Field_Type, 0); if (self == NULL) return NULL; Py_INCREF(default_value); self->default_value = default_value; Py_INCREF(default_factory); self->default_factory = default_factory; Py_XINCREF(name); self->name = name; return (PyObject *)self; } static int Field_traverse(Field *self, visitproc visit, void *arg) { Py_VISIT(self->default_value); Py_VISIT(self->default_factory); Py_VISIT(self->name); return 0; } static int Field_clear(Field *self) { Py_CLEAR(self->default_value); Py_CLEAR(self->default_factory); Py_CLEAR(self->name); return 0; } static void Field_dealloc(Field *self) { PyObject_GC_UnTrack(self); Field_clear(self); Py_TYPE(self)->tp_free((PyObject *)self); } static PyMemberDef Field_members[] = { { "default", T_OBJECT_EX, offsetof(Field, default_value), READONLY, "The default value, or NODEFAULT if no default" }, { "default_factory", T_OBJECT_EX, offsetof(Field, default_factory), READONLY, "The default_factory, or NODEFAULT if no default" }, { "name", T_OBJECT, offsetof(Field, name), READONLY, "An alternative name to use when encoding/decoding this field" }, {NULL}, }; static PyTypeObject Field_Type = { PyVarObject_HEAD_INIT(NULL, 0) .tp_name = "msgspec._core.Field", .tp_doc = Field__doc__, .tp_basicsize = sizeof(Field), .tp_itemsize = 0, .tp_new = Field_new, .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, .tp_clear = (inquiry)Field_clear, .tp_traverse = (traverseproc)Field_traverse, .tp_dealloc = (destructor) Field_dealloc, .tp_members = Field_members, }; /************************************************************************* * AssocList & order handling * *************************************************************************/ enum order_mode { ORDER_SORTED = -1, ORDER_DEFAULT = 0, ORDER_DETERMINISTIC = 1, ORDER_INVALID = 2, }; static enum order_mode parse_order_arg(PyObject *order) { if (order == NULL || order == Py_None) { return ORDER_DEFAULT; } else if (PyUnicode_CheckExact(order)) { if (PyUnicode_CompareWithASCIIString(order, "deterministic") == 0) { return ORDER_DETERMINISTIC; } else if (PyUnicode_CompareWithASCIIString(order, "sorted") == 0) { return ORDER_SORTED; } } PyErr_Format( PyExc_ValueError, "`order` must be one of `{None, 'deterministic', 'sorted'}`, got %R", order ); return ORDER_INVALID; } #define ASSOCLIST_SORT_CUTOFF 16 typedef struct { const char *key; Py_ssize_t key_size; PyObject *val; } AssocItem; typedef struct { Py_ssize_t size; AssocItem items[]; } AssocList; static AssocList * AssocList_New(Py_ssize_t capacity) { AssocList *out = PyMem_Malloc(sizeof(AssocList) + capacity * sizeof(AssocItem)); if (out == NULL) { PyErr_NoMemory(); return NULL; } out->size = 0; return out; } static void AssocList_Free(AssocList *list) { PyMem_Free(list); } static void AssocList_AppendCStr(AssocList *list, const char *key, PyObject *val) { list->items[list->size].key = key; list->items[list->size].key_size = strlen(key); list->items[list->size].val = val; list->size++; } static int AssocList_Append(AssocList *list, PyObject *key, PyObject *val) { Py_ssize_t key_size; const char* key_buf = unicode_str_and_size(key, &key_size); if (key_buf == NULL) return -1; list->items[list->size].key = key_buf; list->items[list->size].key_size = key_size; list->items[list->size].val = val; list->size++; return 0; } static AssocList * AssocList_FromDict(PyObject *dict) { Py_ssize_t len = PyDict_GET_SIZE(dict); AssocList *out = AssocList_New(len); PyObject *key, *val; Py_ssize_t pos = 0; int err = 0; Py_BEGIN_CRITICAL_SECTION(dict); while (PyDict_Next(dict, &pos, &key, &val)) { if (!PyUnicode_Check(key)) { PyErr_SetString( PyExc_TypeError, "Only dicts with str keys are supported when `order` is not `None`" ); err = 1; break; } if (AssocList_Append(out, key, val) < 0) { err = 1; break; } } Py_END_CRITICAL_SECTION(); if (!err) return out; AssocList_Free(out); return NULL; } static inline int _AssocItem_lt(AssocItem *left, AssocItem *right) { int left_shorter = left->key_size < right->key_size; int cmp = memcmp( left->key, right->key, (left_shorter) ? left->key_size : right->key_size ); return (cmp < 0) || ((cmp == 0) & left_shorter); } static Py_ssize_t _AssocList_sort_partition( AssocList* list, Py_ssize_t lo, Py_ssize_t hi, AssocItem *pivot ) { Py_ssize_t i = lo - 1; Py_ssize_t j = hi + 1; while (true) { while (_AssocItem_lt(pivot, &(list->items[--j]))); while (_AssocItem_lt(&(list->items[++i]), pivot)); if (i < j) { AssocItem tmp = list->items[i]; list->items[i] = list->items[j]; list->items[j] = tmp; } else { return j; } } } static void _AssocList_sort_inner(AssocList* list, Py_ssize_t lo, Py_ssize_t hi) { while (lo + ASSOCLIST_SORT_CUTOFF < hi) { AssocItem *v1 = &(list->items[lo]); AssocItem *v2 = &(list->items[hi]); AssocItem *v3 = &(list->items[(lo + hi)/2]); AssocItem pivot; if (_AssocItem_lt(v1, v2)) { if (_AssocItem_lt(v3, v1)) { pivot = *v1; } else if (_AssocItem_lt(v2, v3)) { pivot = *v2; } else { pivot = *v3; } } else { if (_AssocItem_lt(v3, v2)) { pivot = *v2; } else if (_AssocItem_lt(v1, v3)) { pivot = *v1; } else { pivot = *v3; } } Py_ssize_t partition = _AssocList_sort_partition(list, lo, hi, &pivot); _AssocList_sort_inner(list, lo, partition); lo = partition + 1; } } static void AssocList_Sort(AssocList* list) { if (list->size > ASSOCLIST_SORT_CUTOFF) { _AssocList_sort_inner(list, 0, list->size - 1); } for (Py_ssize_t i = 1; i < list->size; i++) { AssocItem val = list->items[i]; Py_ssize_t j = i; while (j > 0 && _AssocItem_lt(&val, &(list->items[j - 1]))) { list->items[j] = list->items[j - 1]; --j; } list->items[j] = val; } } /************************************************************************* * Struct, PathNode, and TypeNode Types * *************************************************************************/ /* Types */ #define MS_TYPE_ANY (1ull << 0) #define MS_TYPE_NONE (1ull << 1) #define MS_TYPE_BOOL (1ull << 2) #define MS_TYPE_INT (1ull << 3) #define MS_TYPE_FLOAT (1ull << 4) #define MS_TYPE_STR (1ull << 5) #define MS_TYPE_BYTES (1ull << 6) #define MS_TYPE_BYTEARRAY (1ull << 7) #define MS_TYPE_MEMORYVIEW (1ull << 8) #define MS_TYPE_DATETIME (1ull << 9) #define MS_TYPE_DATE (1ull << 10) #define MS_TYPE_TIME (1ull << 11) #define MS_TYPE_TIMEDELTA (1ull << 12) #define MS_TYPE_UUID (1ull << 13) #define MS_TYPE_DECIMAL (1ull << 14) #define MS_TYPE_EXT (1ull << 15) #define MS_TYPE_STRUCT (1ull << 16) #define MS_TYPE_STRUCT_ARRAY (1ull << 17) #define MS_TYPE_STRUCT_UNION (1ull << 18) #define MS_TYPE_STRUCT_ARRAY_UNION (1ull << 19) #define MS_TYPE_ENUM (1ull << 20) #define MS_TYPE_INTENUM (1ull << 21) #define MS_TYPE_CUSTOM (1ull << 22) #define MS_TYPE_CUSTOM_GENERIC (1ull << 23) #define MS_TYPE_DICT ((1ull << 24) | (1ull << 25)) #define MS_TYPE_LIST (1ull << 26) #define MS_TYPE_SET (1ull << 27) #define MS_TYPE_FROZENSET (1ull << 28) #define MS_TYPE_VARTUPLE (1ull << 29) #define MS_TYPE_FIXTUPLE (1ull << 30) #define MS_TYPE_INTLITERAL (1ull << 31) #define MS_TYPE_STRLITERAL (1ull << 32) #define MS_TYPE_TYPEDDICT (1ull << 33) #define MS_TYPE_DATACLASS (1ull << 34) #define MS_TYPE_NAMEDTUPLE (1ull << 35) #define MS_TYPE_BOOLLITERAL_TRUE (1ull << 36) #define MS_TYPE_BOOLLITERAL_FALSE (1ull << 37) // Despite the fact that `frozendict` was added in 3.15, // this type is always defined for order consistency: #define MS_TYPE_FROZENDICT ((1ull << 38) | (1ull << 39)) /* Aliases for commonly used types */ #if PY315_PLUS #define MS_ANY_DICT (MS_TYPE_DICT | MS_TYPE_FROZENDICT) #else // `frozendict` was added in 3.15, before that we can ignore this type. #define MS_ANY_DICT MS_TYPE_DICT #endif /* Constraints */ #define MS_CONSTR_INT_MIN (1ull << 42) #define MS_CONSTR_INT_MAX (1ull << 43) #define MS_CONSTR_INT_MULTIPLE_OF (1ull << 44) #define MS_CONSTR_FLOAT_GT (1ull << 45) #define MS_CONSTR_FLOAT_GE (1ull << 46) #define MS_CONSTR_FLOAT_LT (1ull << 47) #define MS_CONSTR_FLOAT_LE (1ull << 48) #define MS_CONSTR_FLOAT_MULTIPLE_OF (1ull << 49) #define MS_CONSTR_STR_REGEX (1ull << 50) #define MS_CONSTR_STR_MIN_LENGTH (1ull << 51) #define MS_CONSTR_STR_MAX_LENGTH (1ull << 52) #define MS_CONSTR_BYTES_MIN_LENGTH (1ull << 53) #define MS_CONSTR_BYTES_MAX_LENGTH (1ull << 54) #define MS_CONSTR_ARRAY_MIN_LENGTH (1ull << 55) #define MS_CONSTR_ARRAY_MAX_LENGTH (1ull << 56) #define MS_CONSTR_MAP_MIN_LENGTH (1ull << 57) #define MS_CONSTR_MAP_MAX_LENGTH (1ull << 58) #define MS_CONSTR_TZ_AWARE (1ull << 59) #define MS_CONSTR_TZ_NAIVE (1ull << 60) /* Extra flag bit, used by TypedDict/dataclass implementations */ #define MS_EXTRA_FLAG (1ull << 63) /* A TypeNode encodes information about all types at the same hierarchy in the * type tree. They can encode both single types (`int`) and unions of types * (`int | float | list[int]`). The encoding is optimized for the common case * of simple scalar types (or unions of these types) with no constraints - * these values only require a single uint64_t. More complicated types require * extra *details* (`TypeDetail` objects) stored in a variable length array. * * The encoding is *compressed* - only fields that are set are stored. To know * which fields are set, a bitmask of `types` is used, masking both the types * and constraints set on the node. * * The order these details are stored is consistent, allowing the offset of a * field to be computed using an efficient bitmask and popcount. * * The order is documented below: * * O | STRUCT | STRUCT_ARRAY | STRUCT_UNION | STRUCT_ARRAY_UNION | CUSTOM | * O | INTENUM | INTLITERAL | * O | ENUM | STRLITERAL | * O | TYPEDDICT | DATACLASS | * O | NAMEDTUPLE | * O | STR_REGEX | * T | DICT [key, value] | FROZENDICT [key, value] | * T | LIST | SET | FROZENSET | VARTUPLE | * I | INT_MIN | * I | INT_MAX | * I | INT_MULTIPLE_OF | * F | FLOAT_GT | FLOAT_GE | * F | FLOAT_LT | FLOAT_LE | * F | FLOAT_MULTIPLE_OF | * S | STR_MIN_LENGTH | * S | STR_MAX_LENGTH | * S | BYTES_MIN_LENGTH | * S | BYTES_MAX_LENGTH | * S | ARRAY_MIN_LENGTH | * S | ARRAY_MAX_LENGTH | * S | MAP_MIN_LENGTH | * S | MAP_MAX_LENGTH | * T | FIXTUPLE [size, types ...] | * */ #define SLOT_00 ( \ MS_TYPE_STRUCT | MS_TYPE_STRUCT_ARRAY | \ MS_TYPE_STRUCT_UNION | MS_TYPE_STRUCT_ARRAY_UNION | \ MS_TYPE_CUSTOM | MS_TYPE_CUSTOM_GENERIC \ ) #define SLOT_01 (MS_TYPE_INTENUM | MS_TYPE_INTLITERAL) #define SLOT_02 (MS_TYPE_ENUM | MS_TYPE_STRLITERAL) #define SLOT_03 (MS_TYPE_TYPEDDICT | MS_TYPE_DATACLASS) #define SLOT_04 MS_TYPE_NAMEDTUPLE #define SLOT_05 MS_CONSTR_STR_REGEX #define SLOT_06 MS_ANY_DICT #define SLOT_07 (MS_TYPE_LIST | MS_TYPE_VARTUPLE | MS_TYPE_SET | MS_TYPE_FROZENSET) #define SLOT_08 MS_CONSTR_INT_MIN #define SLOT_09 MS_CONSTR_INT_MAX #define SLOT_10 MS_CONSTR_INT_MULTIPLE_OF #define SLOT_11 (MS_CONSTR_FLOAT_GE | MS_CONSTR_FLOAT_GT) #define SLOT_12 (MS_CONSTR_FLOAT_LE | MS_CONSTR_FLOAT_LT) #define SLOT_13 MS_CONSTR_FLOAT_MULTIPLE_OF #define SLOT_14 MS_CONSTR_STR_MIN_LENGTH #define SLOT_15 MS_CONSTR_STR_MAX_LENGTH #define SLOT_16 MS_CONSTR_BYTES_MIN_LENGTH #define SLOT_17 MS_CONSTR_BYTES_MAX_LENGTH #define SLOT_18 MS_CONSTR_ARRAY_MIN_LENGTH #define SLOT_19 MS_CONSTR_ARRAY_MAX_LENGTH #define SLOT_20 MS_CONSTR_MAP_MIN_LENGTH #define SLOT_21 MS_CONSTR_MAP_MAX_LENGTH /* Common groups */ #define MS_INT_CONSTRS (SLOT_08 | SLOT_09 | SLOT_10) #define MS_FLOAT_CONSTRS (SLOT_11 | SLOT_12 | SLOT_13) #define MS_STR_CONSTRS (SLOT_05 | SLOT_14 | SLOT_15) #define MS_BYTES_CONSTRS (SLOT_16 | SLOT_17) #define MS_ARRAY_CONSTRS (SLOT_18 | SLOT_19) #define MS_MAP_CONSTRS (SLOT_20 | SLOT_21) #define MS_TIME_CONSTRS (MS_CONSTR_TZ_AWARE | MS_CONSTR_TZ_NAIVE) typedef union TypeDetail { int64_t i64; double f64; Py_ssize_t py_ssize_t; void *pointer; } TypeDetail; typedef struct TypeNode { uint64_t types; TypeDetail details[]; } TypeNode; /* A simple extension of TypeNode to allow for static allocation */ typedef struct { uint64_t types; TypeDetail details[1]; } TypeNodeSimple; typedef struct { PyObject_HEAD PyObject *int_lookup; PyObject *str_lookup; bool literal_none; bool literal_bool_true; bool literal_bool_false; } LiteralInfo; typedef struct { PyObject *key; TypeNode *type; } TypedDictField; typedef struct { PyObject_VAR_HEAD Py_ssize_t nrequired; TypedDictField fields[]; } TypedDictInfo; typedef struct { PyObject *key; TypeNode *type; } DataclassField; typedef struct { PyObject_VAR_HEAD PyObject *class; PyObject *pre_init; PyObject *post_init; PyObject *defaults; DataclassField fields[]; } DataclassInfo; typedef struct { PyObject_VAR_HEAD PyObject *class; PyObject *defaults; TypeNode *types[]; } NamedTupleInfo; struct StructInfo; typedef struct { PyHeapTypeObject base; PyObject *struct_fields; PyObject *struct_defaults; Py_ssize_t *struct_offsets; PyObject *struct_encode_fields; struct StructInfo *struct_info; Py_ssize_t nkwonly; Py_ssize_t n_trailing_defaults; PyObject *struct_tag_field; /* str or NULL */ PyObject *struct_tag_value; /* str or NULL */ PyObject *struct_tag; /* True, str, or NULL */ PyObject *match_args; PyObject *rename; PyObject *post_init; Py_ssize_t hash_offset; /* 0 for no caching, otherwise offset */ int8_t frozen; int8_t order; int8_t eq; int8_t repr_omit_defaults; int8_t array_like; int8_t gc; int8_t omit_defaults; int8_t forbid_unknown_fields; } StructMetaObject; typedef struct StructInfo { PyObject_VAR_HEAD StructMetaObject *class; #ifdef Py_GIL_DISABLED _Atomic(uint8_t) initialized; #endif TypeNode *types[]; } StructInfo; typedef struct { PyObject_HEAD StructMetaObject *st_type; } StructConfig; static PyTypeObject LiteralInfo_Type; static PyTypeObject TypedDictInfo_Type; static PyTypeObject DataclassInfo_Type; static PyTypeObject NamedTupleInfo_Type; static PyTypeObject StructInfo_Type; static PyTypeObject StructMetaType; static PyTypeObject Ext_Type; static TypeNode* TypeNode_Convert(PyObject *type); static PyObject* StructInfo_Convert(PyObject*); static PyObject* TypedDictInfo_Convert(PyObject*); static PyObject* DataclassInfo_Convert(PyObject*); static PyObject* NamedTupleInfo_Convert(PyObject*); #define StructMeta_GET_FIELDS(s) (((StructMetaObject *)(s))->struct_fields) #define StructMeta_GET_NFIELDS(s) (PyTuple_GET_SIZE((((StructMetaObject *)(s))->struct_fields))) #define StructMeta_GET_DEFAULTS(s) (((StructMetaObject *)(s))->struct_defaults) #define StructMeta_GET_OFFSETS(s) (((StructMetaObject *)(s))->struct_offsets) #define OPT_UNSET -1 #define OPT_FALSE 0 #define OPT_TRUE 1 #define STRUCT_MERGE_OPTIONS(opt1, opt2) (((opt2) != OPT_UNSET) ? (opt2) : (opt1)) static MS_NOINLINE int _ms_is_struct_meta_scan(PyTypeObject *mt) { /* Common path: scan mt->tp_mro for StructMeta without a function call. * This logic is adapted from the CPython implementation: * https://github.com/python/cpython/blob/26b7df2430cd5a9ee772bfa6ee03a73bd0b11619/Objects/typeobject.c#L2890-L2919 */ PyObject *mro = mt->tp_mro; if (MS_LIKELY(mro != NULL)) { /* Skip index 0 since we already checked exact equality. */ Py_ssize_t n = PyTuple_GET_SIZE(mro); for (Py_ssize_t i = 1; i < n; i++) { if (PyTuple_GET_ITEM(mro, i) == (PyObject *)&StructMetaType) { return 1; } } return 0; } /* Very rare during type construction: use CPython's base-chain/MRO logic. */ return PyType_IsSubtype(mt, &StructMetaType); } static MS_INLINE int ms_is_struct_meta(PyTypeObject *mt) { /* Checks whether `mt` is StructMeta or a subclass thereof; first tries an exact * metaclass pointer match, otherwise walks the metaclass inheritance chain * to determine if `mt` derives from StructMeta. */ if (MS_LIKELY(mt == &StructMetaType)) { return 1; } return _ms_is_struct_meta_scan(mt); } static MS_INLINE int ms_is_struct_type(PyTypeObject *t) { /* Checks whether the metaclass of type `t` is StructMeta or a subclass thereof. */ return ms_is_struct_meta(Py_TYPE((PyObject *)t)); } static MS_INLINE int ms_is_struct_cls(PyObject *o) { /* Checks whether the metaclass of class object `o` is StructMeta or a subclass thereof. * Expects `o` to be a type/class object. */ return ms_is_struct_meta(Py_TYPE(o)); } static MS_INLINE int ms_is_struct_inst(PyObject *o) { /* Checks whether the metaclass of `type(o)` is StructMeta or a subclass thereof. */ return ms_is_struct_meta(Py_TYPE((PyObject *)Py_TYPE(o))); } static MS_INLINE StructInfo * TypeNode_get_struct_info(TypeNode *type) { /* Struct types are always first */ StructInfo *info = type->details[0].pointer; #ifdef Py_GIL_DISABLED if (atomic_load(&info->initialized)) { return info; } Py_BEGIN_ALLOW_THREADS /* wait for the StructInfo to be fully initialized by other thread */ while (!atomic_load(&info->initialized)) { } Py_END_ALLOW_THREADS #endif return info; } static MS_INLINE Lookup * TypeNode_get_struct_union(TypeNode *type) { /* Struct union types are always first */ return type->details[0].pointer; } static MS_INLINE PyObject * TypeNode_get_custom(TypeNode *type) { /* Custom types can't be mixed with anything */ return type->details[0].pointer; } static MS_INLINE IntLookup * TypeNode_get_int_enum_or_literal(TypeNode *type) { Py_ssize_t i = ms_popcount(type->types & SLOT_00); return type->details[i].pointer; } static MS_INLINE StrLookup * TypeNode_get_str_enum_or_literal(TypeNode *type) { Py_ssize_t i = ms_popcount(type->types & (SLOT_00 | SLOT_01)); return type->details[i].pointer; } static MS_INLINE TypedDictInfo * TypeNode_get_typeddict_info(TypeNode *type) { Py_ssize_t i = ms_popcount(type->types & (SLOT_00 | SLOT_01 | SLOT_02)); return type->details[i].pointer; } static MS_INLINE DataclassInfo * TypeNode_get_dataclass_info(TypeNode *type) { Py_ssize_t i = ms_popcount(type->types & (SLOT_00 | SLOT_01 | SLOT_02)); return type->details[i].pointer; } static MS_INLINE NamedTupleInfo * TypeNode_get_namedtuple_info(TypeNode *type) { Py_ssize_t i = ms_popcount( type->types & ( SLOT_00 | SLOT_01 | SLOT_02 | SLOT_03 ) ); return type->details[i].pointer; } static MS_INLINE PyObject * TypeNode_get_constr_str_regex(TypeNode *type) { Py_ssize_t i = ms_popcount( type->types & ( SLOT_00 | SLOT_01 | SLOT_02 | SLOT_03 | SLOT_04 ) ); return type->details[i].pointer; } static MS_INLINE void TypeNode_get_dict(TypeNode *type, TypeNode **key, TypeNode **val) { Py_ssize_t i = ms_popcount( type->types & ( SLOT_00 | SLOT_01 | SLOT_02 | SLOT_03 | SLOT_04 | SLOT_05 ) ); *key = type->details[i].pointer; *val = type->details[i + 1].pointer; } static MS_INLINE TypeNode * TypeNode_get_array(TypeNode *type) { Py_ssize_t i = ms_popcount( type->types & ( SLOT_00 | SLOT_01 | SLOT_02 | SLOT_03 | SLOT_04 | SLOT_05 | SLOT_06 ) ); return type->details[i].pointer; } static MS_INLINE int64_t TypeNode_get_constr_int_min(TypeNode *type) { Py_ssize_t i = ms_popcount( type->types & ( SLOT_00 | SLOT_01 | SLOT_02 | SLOT_03 | SLOT_04 | SLOT_05 | SLOT_06 | SLOT_07 ) ); return type->details[i].i64; } static MS_INLINE int64_t TypeNode_get_constr_int_max(TypeNode *type) { Py_ssize_t i = ms_popcount( type->types & ( SLOT_00 | SLOT_01 | SLOT_02 | SLOT_03 | SLOT_04 | SLOT_05 | SLOT_06 | SLOT_07 | SLOT_08 ) ); return type->details[i].i64; } static MS_INLINE int64_t TypeNode_get_constr_int_multiple_of(TypeNode *type) { Py_ssize_t i = ms_popcount( type->types & ( SLOT_00 | SLOT_01 | SLOT_02 | SLOT_03 | SLOT_04 | SLOT_05 | SLOT_06 | SLOT_07 | SLOT_08 | SLOT_09 ) ); return type->details[i].i64; } static MS_INLINE double TypeNode_get_constr_float_min(TypeNode *type) { Py_ssize_t i = ms_popcount( type->types & ( SLOT_00 | SLOT_01 | SLOT_02 | SLOT_03 | SLOT_04 | SLOT_05 | SLOT_06 | SLOT_07 | SLOT_08 | SLOT_09 | SLOT_10 ) ); return type->details[i].f64; } static MS_INLINE double TypeNode_get_constr_float_max(TypeNode *type) { Py_ssize_t i = ms_popcount( type->types & ( SLOT_00 | SLOT_01 | SLOT_02 | SLOT_03 | SLOT_04 | SLOT_05 | SLOT_06 | SLOT_07 | SLOT_08 | SLOT_09 | SLOT_10 | SLOT_11 ) ); return type->details[i].f64; } static MS_INLINE double TypeNode_get_constr_float_multiple_of(TypeNode *type) { Py_ssize_t i = ms_popcount( type->types & ( SLOT_00 | SLOT_01 | SLOT_02 | SLOT_03 | SLOT_04 | SLOT_05 | SLOT_06 | SLOT_07 | SLOT_08 | SLOT_09 | SLOT_10 | SLOT_11 | SLOT_12 ) ); return type->details[i].f64; } static MS_INLINE Py_ssize_t TypeNode_get_constr_str_min_length(TypeNode *type) { Py_ssize_t i = ms_popcount( type->types & ( SLOT_00 | SLOT_01 | SLOT_02 | SLOT_03 | SLOT_04 | SLOT_05 | SLOT_06 | SLOT_07 | SLOT_08 | SLOT_09 | SLOT_10 | SLOT_11 | SLOT_12 | SLOT_13 ) ); return type->details[i].py_ssize_t; } static MS_INLINE Py_ssize_t TypeNode_get_constr_str_max_length(TypeNode *type) { Py_ssize_t i = ms_popcount( type->types & ( SLOT_00 | SLOT_01 | SLOT_02 | SLOT_03 | SLOT_04 | SLOT_05 | SLOT_06 | SLOT_07 | SLOT_08 | SLOT_09 | SLOT_10 | SLOT_11 | SLOT_12 | SLOT_13 | SLOT_14 ) ); return type->details[i].py_ssize_t; } static MS_INLINE Py_ssize_t TypeNode_get_constr_bytes_min_length(TypeNode *type) { Py_ssize_t i = ms_popcount( type->types & ( SLOT_00 | SLOT_01 | SLOT_02 | SLOT_03 | SLOT_04 | SLOT_05 | SLOT_06 | SLOT_07 | SLOT_08 | SLOT_09 | SLOT_10 | SLOT_11 | SLOT_12 | SLOT_13 | SLOT_14 | SLOT_15 ) ); return type->details[i].py_ssize_t; } static MS_INLINE Py_ssize_t TypeNode_get_constr_bytes_max_length(TypeNode *type) { Py_ssize_t i = ms_popcount( type->types & ( SLOT_00 | SLOT_01 | SLOT_02 | SLOT_03 | SLOT_04 | SLOT_05 | SLOT_06 | SLOT_07 | SLOT_08 | SLOT_09 | SLOT_10 | SLOT_11 | SLOT_12 | SLOT_13 | SLOT_14 | SLOT_15 | SLOT_16 ) ); return type->details[i].py_ssize_t; } static MS_INLINE Py_ssize_t TypeNode_get_constr_array_min_length(TypeNode *type) { Py_ssize_t i = ms_popcount( type->types & ( SLOT_00 | SLOT_01 | SLOT_02 | SLOT_03 | SLOT_04 | SLOT_05 | SLOT_06 | SLOT_07 | SLOT_08 | SLOT_09 | SLOT_10 | SLOT_11 | SLOT_12 | SLOT_13 | SLOT_14 | SLOT_15 | SLOT_16 | SLOT_17 ) ); return type->details[i].py_ssize_t; } static MS_INLINE Py_ssize_t TypeNode_get_constr_array_max_length(TypeNode *type) { Py_ssize_t i = ms_popcount( type->types & ( SLOT_00 | SLOT_01 | SLOT_02 | SLOT_03 | SLOT_04 | SLOT_05 | SLOT_06 | SLOT_07 | SLOT_08 | SLOT_09 | SLOT_10 | SLOT_11 | SLOT_12 | SLOT_13 | SLOT_14 | SLOT_15 | SLOT_16 | SLOT_17 | SLOT_18 ) ); return type->details[i].py_ssize_t; } static MS_INLINE Py_ssize_t TypeNode_get_constr_map_min_length(TypeNode *type) { Py_ssize_t i = ms_popcount( type->types & ( SLOT_00 | SLOT_01 | SLOT_02 | SLOT_03 | SLOT_04 | SLOT_05 | SLOT_06 | SLOT_07 | SLOT_08 | SLOT_09 | SLOT_10 | SLOT_11 | SLOT_12 | SLOT_13 | SLOT_14 | SLOT_15 | SLOT_16 | SLOT_17 | SLOT_18 | SLOT_19 ) ); return type->details[i].py_ssize_t; } static MS_INLINE Py_ssize_t TypeNode_get_constr_map_max_length(TypeNode *type) { Py_ssize_t i = ms_popcount( type->types & ( SLOT_00 | SLOT_01 | SLOT_02 | SLOT_03 | SLOT_04 | SLOT_05 | SLOT_06 | SLOT_07 | SLOT_08 | SLOT_09 | SLOT_10 | SLOT_11 | SLOT_12 | SLOT_13 | SLOT_14 | SLOT_15 | SLOT_16 | SLOT_17 | SLOT_18 | SLOT_19 | SLOT_20 ) ); return type->details[i].py_ssize_t; } static MS_INLINE void TypeNode_get_fixtuple(TypeNode *type, Py_ssize_t *offset, Py_ssize_t *size) { Py_ssize_t i = ms_popcount( type->types & ( SLOT_00 | SLOT_01 | SLOT_02 | SLOT_03 | SLOT_04 | SLOT_05 | SLOT_06 | SLOT_07 | SLOT_08 | SLOT_09 | SLOT_10 | SLOT_11 | SLOT_12 | SLOT_13 | SLOT_14 | SLOT_15 | SLOT_16 | SLOT_17 | SLOT_18 | SLOT_19 | SLOT_20 | SLOT_21 ) ); *size = type->details[i].py_ssize_t; *offset = i + 1; } static void TypeNode_get_traverse_ranges( TypeNode *type, Py_ssize_t *n_objects, Py_ssize_t *n_typenode, Py_ssize_t *fixtuple_offset, Py_ssize_t *fixtuple_size ) { Py_ssize_t n_obj = 0, n_type = 0, ft_offset = 0, ft_size = 0; /* Custom types cannot share a union with anything except `None` */ if (type->types & (MS_TYPE_CUSTOM | MS_TYPE_CUSTOM_GENERIC)) { n_obj = 1; } else if (!(type->types & MS_TYPE_ANY)) { /* Number of pyobject details */ n_obj = ms_popcount( type->types & ( MS_TYPE_STRUCT | MS_TYPE_STRUCT_UNION | MS_TYPE_STRUCT_ARRAY | MS_TYPE_STRUCT_ARRAY_UNION | MS_TYPE_INTENUM | MS_TYPE_INTLITERAL | MS_TYPE_ENUM | MS_TYPE_STRLITERAL | MS_TYPE_TYPEDDICT | MS_TYPE_DATACLASS | MS_TYPE_NAMEDTUPLE ) ); /* Number of typenode details */ n_type = ms_popcount( type->types & ( MS_ANY_DICT | MS_TYPE_LIST | MS_TYPE_SET | MS_TYPE_FROZENSET | MS_TYPE_VARTUPLE ) ); if (type->types & MS_TYPE_FIXTUPLE) { TypeNode_get_fixtuple(type, &ft_offset, &ft_size); } } *n_objects = n_obj; *n_typenode = n_type; *fixtuple_offset = ft_offset; *fixtuple_size = ft_size; } static void TypeNode_Free(TypeNode *self) { if (self == NULL) return; Py_ssize_t n_obj, n_typenode, fixtuple_offset, fixtuple_size, i; TypeNode_get_traverse_ranges(self, &n_obj, &n_typenode, &fixtuple_offset, &fixtuple_size); for (i = 0; i < n_obj; i++) { PyObject *obj = (PyObject *)(self->details[i].pointer); Py_XDECREF(obj); } for (i = n_obj; i < (n_obj + n_typenode); i++) { TypeNode *node = (TypeNode *)(self->details[i].pointer); TypeNode_Free(node); } for (i = 0; i < fixtuple_size; i++) { TypeNode *node = (TypeNode *)(self->details[i + fixtuple_offset].pointer); TypeNode_Free(node); } PyMem_Free(self); } static int TypeNode_traverse(TypeNode *self, visitproc visit, void *arg) { if (self == NULL) return 0; Py_ssize_t n_obj, n_typenode, fixtuple_offset, fixtuple_size, i; TypeNode_get_traverse_ranges(self, &n_obj, &n_typenode, &fixtuple_offset, &fixtuple_size); for (i = 0; i < n_obj; i++) { PyObject *obj = (PyObject *)(self->details[i].pointer); Py_VISIT(obj); } for (i = n_obj; i < (n_obj + n_typenode); i++) { int out; TypeNode *node = (TypeNode *)(self->details[i].pointer); if ((out = TypeNode_traverse(node, visit, arg)) != 0) return out; } for (i = 0; i < fixtuple_size; i++) { int out; TypeNode *node = (TypeNode *)(self->details[i + fixtuple_offset].pointer); if ((out = TypeNode_traverse(node, visit, arg)) != 0) return out; } return 0; } static PyObject * typenode_simple_repr(TypeNode *self) { strbuilder builder = {" | ", 3}; if (self->types & (MS_TYPE_ANY | MS_TYPE_CUSTOM | MS_TYPE_CUSTOM_GENERIC)) { return PyUnicode_FromString("any"); } if ((self->types & ~MS_EXTRA_FLAG) == 0) { /* Ignore TypedDict/dataclass field metadata when identifying Raw. */ return PyUnicode_FromString("raw"); } if (self->types & (MS_TYPE_BOOL | MS_TYPE_BOOLLITERAL_TRUE | MS_TYPE_BOOLLITERAL_FALSE)) { if (!strbuilder_extend_literal(&builder, "bool")) return NULL; } if (self->types & (MS_TYPE_INT | MS_TYPE_INTENUM | MS_TYPE_INTLITERAL)) { if (!strbuilder_extend_literal(&builder, "int")) return NULL; } if (self->types & MS_TYPE_FLOAT) { if (!strbuilder_extend_literal(&builder, "float")) return NULL; } if (self->types & (MS_TYPE_STR | MS_TYPE_ENUM | MS_TYPE_STRLITERAL)) { if (!strbuilder_extend_literal(&builder, "str")) return NULL; } if (self->types & (MS_TYPE_BYTES | MS_TYPE_BYTEARRAY | MS_TYPE_MEMORYVIEW)) { if (!strbuilder_extend_literal(&builder, "bytes")) return NULL; } if (self->types & MS_TYPE_DATETIME) { if (!strbuilder_extend_literal(&builder, "datetime")) return NULL; } if (self->types & MS_TYPE_DATE) { if (!strbuilder_extend_literal(&builder, "date")) return NULL; } if (self->types & MS_TYPE_TIME) { if (!strbuilder_extend_literal(&builder, "time")) return NULL; } if (self->types & MS_TYPE_TIMEDELTA) { if (!strbuilder_extend_literal(&builder, "duration")) return NULL; } if (self->types & MS_TYPE_UUID) { if (!strbuilder_extend_literal(&builder, "uuid")) return NULL; } if (self->types & MS_TYPE_DECIMAL) { if (!strbuilder_extend_literal(&builder, "decimal")) return NULL; } if (self->types & MS_TYPE_EXT) { if (!strbuilder_extend_literal(&builder, "ext")) return NULL; } if (self->types & ( MS_TYPE_STRUCT | MS_TYPE_STRUCT_UNION | MS_TYPE_TYPEDDICT | MS_TYPE_DATACLASS | MS_ANY_DICT ) ) { if (!strbuilder_extend_literal(&builder, "object")) return NULL; } if ( self->types & ( MS_TYPE_STRUCT_ARRAY | MS_TYPE_STRUCT_ARRAY_UNION | MS_TYPE_LIST | MS_TYPE_SET | MS_TYPE_FROZENSET | MS_TYPE_VARTUPLE | MS_TYPE_FIXTUPLE | MS_TYPE_NAMEDTUPLE ) ) { if (!strbuilder_extend_literal(&builder, "array")) return NULL; } if (self->types & MS_TYPE_NONE) { if (!strbuilder_extend_literal(&builder, "null")) return NULL; } return strbuilder_build(&builder); } typedef struct { PyObject *gt; PyObject *ge; PyObject *lt; PyObject *le; PyObject *multiple_of; PyObject *regex; PyObject *min_length; PyObject *max_length; PyObject *tz; } Constraints; typedef struct { MsgspecState *mod; PyObject *context; uint64_t types; PyObject *struct_obj; PyObject *struct_info; PyObject *structs_set; PyObject *structs_lookup; PyObject *intenum_obj; PyObject *enum_obj; PyObject *custom_obj; PyObject *array_el_obj; PyObject *dict_key_obj; PyObject *dict_val_obj; PyObject *typeddict_obj; PyObject *dataclass_obj; PyObject *namedtuple_obj; PyObject *literals; PyObject *literal_int_values; PyObject *literal_int_lookup; PyObject *literal_str_values; PyObject *literal_str_lookup; bool literal_none; bool literal_bool_true; bool literal_bool_false; /* Constraints */ int64_t c_int_min; int64_t c_int_max; int64_t c_int_multiple_of; double c_float_min; double c_float_max; double c_float_multiple_of; PyObject *c_str_regex; Py_ssize_t c_str_min_length; Py_ssize_t c_str_max_length; Py_ssize_t c_bytes_min_length; Py_ssize_t c_bytes_max_length; Py_ssize_t c_array_min_length; Py_ssize_t c_array_max_length; Py_ssize_t c_map_min_length; Py_ssize_t c_map_max_length; } TypeNodeCollectState; static MS_INLINE bool constraints_is_empty(Constraints *self) { return ( self->gt == NULL && self->ge == NULL && self->lt == NULL && self->le == NULL && self->multiple_of == NULL && self->regex == NULL && self->min_length == NULL && self->max_length == NULL && self->tz == NULL ); } static int _set_constraint(PyObject *source, PyObject **target, const char *name, PyObject *type) { if (source == NULL) return 0; if (*target == NULL) { *target = source; return 0; } PyErr_Format( PyExc_TypeError, "Multiple `Meta` annotations setting `%s` found, " "type `%R` is invalid", name, type ); return -1; } static int constraints_update(Constraints *self, Meta *meta, PyObject *type) { #define set_constraint(field) do { \ if (_set_constraint(meta->field, &(self->field), #field, type) < 0) return -1; \ } while (0) set_constraint(gt); set_constraint(ge); set_constraint(lt); set_constraint(le); set_constraint(multiple_of); set_constraint(regex); set_constraint(min_length); set_constraint(max_length); set_constraint(tz); if (self->gt != NULL && self->ge != NULL) { PyErr_Format( PyExc_TypeError, "Cannot set both `gt` and `ge` on the same annotated type, " "type `%R` is invalid", type ); return -1; } if (self->lt != NULL && self->le != NULL) { PyErr_Format( PyExc_TypeError, "Cannot set both `lt` and `le` on the same annotated type, " "type `%R` is invalid", type ); return -1; } return 0; #undef set_constraint } enum constraint_kind { CK_INT = 0, CK_FLOAT = 1, CK_STR = 2, CK_BYTES = 3, CK_TIME = 4, CK_ARRAY = 5, CK_MAP = 6, CK_OTHER = 7, }; static int err_invalid_constraint(const char *name, const char *kind, PyObject *obj) { PyErr_Format( PyExc_TypeError, "Can only set `%s` on a %s type - type `%R` is invalid", name, kind, obj ); return -1; } static bool _constr_as_i64(PyObject *obj, int64_t *target, int offset) { int overflow; int64_t x = PyLong_AsLongLongAndOverflow(obj, &overflow); if (overflow != 0) { PyErr_SetString( PyExc_ValueError, "Integer bounds constraints (`ge`, `le`, ...) that don't fit in an " "int64 are currently not supported. If you need this feature, please " "open an issue on GitHub" ); return false; } else if (x == -1 && PyErr_Occurred()) { return false; } /* Do offsets for lt/gt */ if (offset == -1) { if (x == INT64_MIN) { PyErr_SetString(PyExc_ValueError, "lt <= -2**63 is not supported"); return false; } x -= 1; } else if (offset == 1) { if (x == ((1ULL << 63) - 1)) { PyErr_SetString(PyExc_ValueError, "gt >= 2**63 - 1 is not supported"); return false; } x += 1; } *target = x; return true; } static bool _constr_as_f64(PyObject *obj, double *target, int offset) { /* Use PyFloat_AsDouble to also handle integers */ double x = PyFloat_AsDouble(obj); /* Should never be hit, types already checked */ if (x == -1.0 && PyErr_Occurred()) return false; if (offset == 1) { x = nextafter(x, DBL_MAX); } else if (offset == -1) { x = nextafter(x, -DBL_MAX); } *target = x; return true; } static bool _constr_as_py_ssize_t(PyObject *obj, Py_ssize_t *target) { Py_ssize_t x = PyLong_AsSsize_t(obj); /* Should never be hit, types already checked */ if (x == -1 && PyErr_Occurred()) return false; *target = x; return true; } static int typenode_collect_constraints( TypeNodeCollectState *state, Constraints *constraints, enum constraint_kind kind, PyObject *obj ) { /* If no constraints, do nothing */ if (constraints == NULL) return 0; if (constraints_is_empty(constraints)) return 0; /* Check that the constraints are valid for the corresponding type */ if (kind != CK_INT && kind != CK_FLOAT) { if (constraints->gt != NULL) return err_invalid_constraint("gt", "numeric", obj); if (constraints->ge != NULL) return err_invalid_constraint("ge", "numeric", obj); if (constraints->lt != NULL) return err_invalid_constraint("lt", "numeric", obj); if (constraints->le != NULL) return err_invalid_constraint("le", "numeric", obj); if (constraints->multiple_of != NULL) return err_invalid_constraint("multiple_of", "numeric", obj); } if (kind != CK_STR) { if (constraints->regex != NULL) return err_invalid_constraint("pattern", "str", obj); } if (kind != CK_STR && kind != CK_BYTES && kind != CK_ARRAY && kind != CK_MAP) { if (constraints->min_length != NULL) return err_invalid_constraint("min_length", "str, bytes, or collection", obj); if (constraints->max_length != NULL) return err_invalid_constraint("max_length", "str, bytes, or collection", obj); } if (kind != CK_TIME) { if (constraints->tz != NULL) return err_invalid_constraint("tz", "datetime or time", obj); } /* Next attempt to fill in the state. */ if (kind == CK_INT) { if (constraints->gt != NULL) { state->types |= MS_CONSTR_INT_MIN; if (!_constr_as_i64(constraints->gt, &(state->c_int_min), 1)) return -1; } else if (constraints->ge != NULL) { state->types |= MS_CONSTR_INT_MIN; if (!_constr_as_i64(constraints->ge, &(state->c_int_min), 0)) return -1; } if (constraints->lt != NULL) { state->types |= MS_CONSTR_INT_MAX; if (!_constr_as_i64(constraints->lt, &(state->c_int_max), -1)) return -1; } else if (constraints->le != NULL) { state->types |= MS_CONSTR_INT_MAX; if (!_constr_as_i64(constraints->le, &(state->c_int_max), 0)) return -1; } if (constraints->multiple_of != NULL) { state->types |= MS_CONSTR_INT_MULTIPLE_OF; if (!_constr_as_i64(constraints->multiple_of, &(state->c_int_multiple_of), 0)) return -1; } } else if (kind == CK_FLOAT) { if (constraints->gt != NULL) { state->types |= MS_CONSTR_FLOAT_GT; if (!_constr_as_f64(constraints->gt, &(state->c_float_min), 1)) return -1; } else if (constraints->ge != NULL) { state->types |= MS_CONSTR_FLOAT_GE; if (!_constr_as_f64(constraints->ge, &(state->c_float_min), 0)) return -1; } if (constraints->lt != NULL) { state->types |= MS_CONSTR_FLOAT_LT; if (!_constr_as_f64(constraints->lt, &(state->c_float_max), -1)) return -1; } else if (constraints->le != NULL) { state->types |= MS_CONSTR_FLOAT_LE; if (!_constr_as_f64(constraints->le, &(state->c_float_max), 0)) return -1; } if (constraints->multiple_of != NULL) { state->types |= MS_CONSTR_FLOAT_MULTIPLE_OF; if (!_constr_as_f64(constraints->multiple_of, &(state->c_float_multiple_of), 0)) return -1; } } else if (kind == CK_STR) { if (constraints->regex != NULL) { state->types |= MS_CONSTR_STR_REGEX; Py_INCREF(constraints->regex); state->c_str_regex = constraints->regex; } if (constraints->min_length != NULL) { state->types |= MS_CONSTR_STR_MIN_LENGTH; if (!_constr_as_py_ssize_t(constraints->min_length, &(state->c_str_min_length))) return -1; } if (constraints->max_length != NULL) { state->types |= MS_CONSTR_STR_MAX_LENGTH; if (!_constr_as_py_ssize_t(constraints->max_length, &(state->c_str_max_length))) return -1; } } else if (kind == CK_BYTES) { if (constraints->min_length != NULL) { state->types |= MS_CONSTR_BYTES_MIN_LENGTH; if (!_constr_as_py_ssize_t(constraints->min_length, &(state->c_bytes_min_length))) return -1; } if (constraints->max_length != NULL) { state->types |= MS_CONSTR_BYTES_MAX_LENGTH; if (!_constr_as_py_ssize_t(constraints->max_length, &(state->c_bytes_max_length))) return -1; } } else if (kind == CK_TIME) { if (constraints->tz != NULL) { if (constraints->tz == Py_True) { state->types |= MS_CONSTR_TZ_AWARE; } else { state->types |= MS_CONSTR_TZ_NAIVE; } } } else if (kind == CK_ARRAY) { if (constraints->min_length != NULL) { state->types |= MS_CONSTR_ARRAY_MIN_LENGTH; if (!_constr_as_py_ssize_t(constraints->min_length, &(state->c_array_min_length))) return -1; } if (constraints->max_length != NULL) { state->types |= MS_CONSTR_ARRAY_MAX_LENGTH; if (!_constr_as_py_ssize_t(constraints->max_length, &(state->c_array_max_length))) return -1; } } else if (kind == CK_MAP) { if (constraints->min_length != NULL) { state->types |= MS_CONSTR_MAP_MIN_LENGTH; if (!_constr_as_py_ssize_t(constraints->min_length, &(state->c_map_min_length))) return -1; } if (constraints->max_length != NULL) { state->types |= MS_CONSTR_MAP_MAX_LENGTH; if (!_constr_as_py_ssize_t(constraints->max_length, &(state->c_map_max_length))) return -1; } } return 0; } static int typenode_collect_type(TypeNodeCollectState*, PyObject*); static TypeNode * typenode_from_collect_state(TypeNodeCollectState *state) { Py_ssize_t e_ind, n_extra = 0, fixtuple_size = 0; bool has_fixtuple = false; n_extra = ms_popcount( state->types & ( MS_TYPE_STRUCT | MS_TYPE_STRUCT_ARRAY | MS_TYPE_STRUCT_UNION | MS_TYPE_STRUCT_ARRAY_UNION | MS_TYPE_CUSTOM | MS_TYPE_CUSTOM_GENERIC | MS_TYPE_INTENUM | MS_TYPE_INTLITERAL | MS_TYPE_ENUM | MS_TYPE_STRLITERAL | MS_TYPE_TYPEDDICT | MS_TYPE_DATACLASS | MS_TYPE_NAMEDTUPLE | MS_CONSTR_STR_REGEX | MS_ANY_DICT | MS_TYPE_LIST | MS_TYPE_SET | MS_TYPE_FROZENSET | MS_TYPE_VARTUPLE | MS_CONSTR_INT_MIN | MS_CONSTR_INT_MAX | MS_CONSTR_INT_MULTIPLE_OF | MS_CONSTR_FLOAT_GT | MS_CONSTR_FLOAT_GE | MS_CONSTR_FLOAT_LT | MS_CONSTR_FLOAT_LE | MS_CONSTR_FLOAT_MULTIPLE_OF | MS_CONSTR_STR_MIN_LENGTH | MS_CONSTR_STR_MAX_LENGTH | MS_CONSTR_BYTES_MIN_LENGTH | MS_CONSTR_BYTES_MAX_LENGTH | MS_CONSTR_ARRAY_MIN_LENGTH | MS_CONSTR_ARRAY_MAX_LENGTH | MS_CONSTR_MAP_MIN_LENGTH | MS_CONSTR_MAP_MAX_LENGTH ) ); if (state->types & MS_TYPE_FIXTUPLE) { has_fixtuple = true; fixtuple_size = PyTuple_GET_SIZE(state->array_el_obj); n_extra += fixtuple_size + 1; } if (n_extra == 0) { TypeNode *out = (TypeNode *)PyMem_Malloc(sizeof(TypeNode)); if (out == NULL) { PyErr_NoMemory(); return NULL; } out->types = state->types; return out; } /* Use calloc so that `out->details` is initialized, easing cleanup on error */ TypeNode *out = (TypeNode *)PyMem_Calloc( 1, sizeof(TypeNode) + n_extra * sizeof(TypeDetail) ); if (out == NULL) { PyErr_NoMemory(); return NULL; } out->types = state->types; /* Populate `details` fields in order */ e_ind = 0; if (state->custom_obj != NULL) { Py_INCREF(state->custom_obj); /* Add `Any` to the type node, so the individual decode functions can * check for `Any` alone, and only have to handle custom types in one * location (e.g. `mpack_decode`). */ out->types |= MS_TYPE_ANY; out->details[e_ind++].pointer = state->custom_obj; } if (state->struct_info != NULL) { Py_INCREF(state->struct_info); out->details[e_ind++].pointer = state->struct_info; } if (state->structs_lookup != NULL) { Py_INCREF(state->structs_lookup); out->details[e_ind++].pointer = state->structs_lookup; } if (state->intenum_obj != NULL) { PyObject *lookup = PyObject_GetAttr(state->intenum_obj, state->mod->str___msgspec_cache__); if (lookup == NULL) { /* IntLookup isn't created yet, create and store on enum class */ PyErr_Clear(); PyObject *member_map = PyObject_GetAttr(state->intenum_obj, state->mod->str__value2member_map_); if (member_map == NULL) goto error; lookup = IntLookup_New(member_map, NULL, state->intenum_obj, false); Py_DECREF(member_map); if (lookup == NULL) goto error; if (PyObject_SetAttr(state->intenum_obj, state->mod->str___msgspec_cache__, lookup) < 0) { Py_DECREF(lookup); goto error; } } else if (!Lookup_IsIntLookup(lookup)) { /* the lookup attribute has been overwritten, error */ Py_DECREF(lookup); PyErr_Format( PyExc_RuntimeError, "%R.__msgspec_cache__ has been overwritten", state->intenum_obj ); goto error; } out->details[e_ind++].pointer = lookup; } if (state->literal_int_lookup != NULL) { Py_INCREF(state->literal_int_lookup); out->details[e_ind++].pointer = state->literal_int_lookup; } if (state->enum_obj != NULL) { PyObject *lookup = PyObject_GetAttr(state->enum_obj, state->mod->str___msgspec_cache__); if (lookup == NULL) { /* StrLookup isn't created yet, create and store on enum class */ PyErr_Clear(); PyObject *member_map = PyObject_GetAttr(state->enum_obj, state->mod->str__value2member_map_); if (member_map == NULL) goto error; lookup = StrLookup_New(member_map, NULL, state->enum_obj, false); Py_DECREF(member_map); if (lookup == NULL) goto error; if (PyObject_SetAttr(state->enum_obj, state->mod->str___msgspec_cache__, lookup) < 0) { Py_DECREF(lookup); goto error; } } else if (Py_TYPE(lookup) != &StrLookup_Type) { /* the lookup attribute has been overwritten, error */ Py_DECREF(lookup); PyErr_Format( PyExc_RuntimeError, "%R.__msgspec_cache__ has been overwritten", state->enum_obj ); goto error; } out->details[e_ind++].pointer = lookup; } if (state->literal_str_lookup != NULL) { Py_INCREF(state->literal_str_lookup); out->details[e_ind++].pointer = state->literal_str_lookup; } if (state->typeddict_obj != NULL) { PyObject *info = TypedDictInfo_Convert(state->typeddict_obj); if (info == NULL) goto error; out->details[e_ind++].pointer = info; } if (state->dataclass_obj != NULL) { PyObject *info = DataclassInfo_Convert(state->dataclass_obj); if (info == NULL) goto error; out->details[e_ind++].pointer = info; } if (state->namedtuple_obj != NULL) { PyObject *info = NamedTupleInfo_Convert(state->namedtuple_obj); if (info == NULL) goto error; out->details[e_ind++].pointer = info; } if (state->types & MS_CONSTR_STR_REGEX) { Py_INCREF(state->c_str_regex); out->details[e_ind++].pointer = state->c_str_regex; } if (state->dict_key_obj != NULL && state->dict_val_obj != NULL) { TypeNode *temp = TypeNode_Convert(state->dict_key_obj); if (temp == NULL) goto error; out->details[e_ind++].pointer = temp; temp = TypeNode_Convert(state->dict_val_obj); if (temp == NULL) goto error; out->details[e_ind++].pointer = temp; } if (state->array_el_obj != NULL) { if (has_fixtuple) { out->details[e_ind++].py_ssize_t = fixtuple_size; for (Py_ssize_t i = 0; i < fixtuple_size; i++) { TypeNode *temp = TypeNode_Convert( PyTuple_GET_ITEM(state->array_el_obj, i) ); if (temp == NULL) goto error; out->details[e_ind++].pointer = temp; } } else { TypeNode *temp = TypeNode_Convert(state->array_el_obj); if (temp == NULL) goto error; out->details[e_ind++].pointer = temp; } } if (state->types & MS_CONSTR_INT_MIN) { out->details[e_ind++].i64 = state->c_int_min; } if (state->types & MS_CONSTR_INT_MAX) { out->details[e_ind++].i64 = state->c_int_max; } if (state->types & MS_CONSTR_INT_MULTIPLE_OF) { out->details[e_ind++].i64 = state->c_int_multiple_of; } if (state->types & (MS_CONSTR_FLOAT_GT | MS_CONSTR_FLOAT_GE)) { out->details[e_ind++].f64 = state->c_float_min; } if (state->types & (MS_CONSTR_FLOAT_LT | MS_CONSTR_FLOAT_LE)) { out->details[e_ind++].f64 = state->c_float_max; } if (state->types & MS_CONSTR_FLOAT_MULTIPLE_OF) { out->details[e_ind++].f64 = state->c_float_multiple_of; } if (state->types & MS_CONSTR_STR_MIN_LENGTH) { out->details[e_ind++].py_ssize_t = state->c_str_min_length; } if (state->types & MS_CONSTR_STR_MAX_LENGTH) { out->details[e_ind++].py_ssize_t = state->c_str_max_length; } if (state->types & MS_CONSTR_BYTES_MIN_LENGTH) { out->details[e_ind++].py_ssize_t = state->c_bytes_min_length; } if (state->types & MS_CONSTR_BYTES_MAX_LENGTH) { out->details[e_ind++].py_ssize_t = state->c_bytes_max_length; } if (state->types & MS_CONSTR_ARRAY_MIN_LENGTH) { out->details[e_ind++].py_ssize_t = state->c_array_min_length; } if (state->types & MS_CONSTR_ARRAY_MAX_LENGTH) { out->details[e_ind++].py_ssize_t = state->c_array_max_length; } if (state->types & MS_CONSTR_MAP_MIN_LENGTH) { out->details[e_ind++].py_ssize_t = state->c_map_min_length; } if (state->types & MS_CONSTR_MAP_MAX_LENGTH) { out->details[e_ind++].py_ssize_t = state->c_map_max_length; } return (TypeNode *)out; error: TypeNode_Free((TypeNode *)out); return NULL; } static bool get_msgspec_cache(MsgspecState *mod, PyObject *obj, PyTypeObject *type, PyObject **out) { PyObject *cached = PyObject_GenericGetAttr(obj, mod->str___msgspec_cache__); if (cached != NULL) { if (Py_TYPE(cached) != type) { Py_DECREF(cached); PyErr_Format( PyExc_RuntimeError, "%R.__msgspec_cache__ has been overwritten", obj ); } else { *out = cached; } return true; } PyErr_Clear(); return false; } static int typenode_collect_err_unique(TypeNodeCollectState *state, const char *kind) { PyErr_Format( PyExc_TypeError, "Type unions may not contain more than one %s type - " "type `%R` is not supported", kind, state->context ); return -1; } static int typenode_collect_check_invariants(TypeNodeCollectState *state) { /* If a custom type is used, this node may only contain that type and `None */ if ( state->custom_obj != NULL && state->types & ~(MS_TYPE_CUSTOM | MS_TYPE_CUSTOM_GENERIC | MS_TYPE_NONE) ) { PyErr_Format( PyExc_TypeError, "Type unions containing a custom type may not contain any " "additional types other than `None` - type `%R` is not supported", state->context ); return -1; } /* Ensure at most one array-like type in the union */ if (ms_popcount( state->types & ( MS_TYPE_STRUCT_ARRAY | MS_TYPE_STRUCT_ARRAY_UNION | MS_TYPE_LIST | MS_TYPE_SET | MS_TYPE_FROZENSET | MS_TYPE_VARTUPLE | MS_TYPE_FIXTUPLE | MS_TYPE_NAMEDTUPLE ) ) > 1 ) { PyErr_Format( PyExc_TypeError, "Type unions may not contain more than one array-like type " "(`Struct(array_like=True)`, `list`, `set`, `frozenset`, `tuple`, " "`NamedTuple`) - type `%R` is not supported", state->context ); return -1; } /* Ensure at most one dict-like type in the union */ int ndictlike = ms_popcount( state->types & ( MS_TYPE_STRUCT | MS_TYPE_STRUCT_UNION | MS_TYPE_TYPEDDICT | MS_TYPE_DATACLASS ) ); if (state->types & MS_ANY_DICT) { ndictlike++; } if (ndictlike > 1) { PyErr_Format( PyExc_TypeError, "Type unions may not contain more than one dict-like type " "(`Struct`, `dict`, `TypedDict`, `dataclass`) - type `%R` " "is not supported", state->context ); return -1; } /* If int & int literals are both present, drop literals */ if (state->types & MS_TYPE_INT && state->literal_int_lookup) { state->types &= ~MS_TYPE_INTLITERAL; Py_CLEAR(state->literal_int_lookup); } /* If str & str literals are both present, drop literals */ if (state->types & MS_TYPE_STR && state->literal_str_lookup) { state->types &= ~MS_TYPE_STRLITERAL; Py_CLEAR(state->literal_str_lookup); } /* Ensure int-like types don't conflict */ if (ms_popcount(state->types & (MS_TYPE_INT | MS_TYPE_INTLITERAL | MS_TYPE_INTENUM)) > 1) { PyErr_Format( PyExc_TypeError, "Type unions may not contain more than one int-like type (`int`, " "`Enum`, `Literal[int values]`) - type `%R` is not supported", state->context ); return -1; } /* Ensure str-like types don't conflict */ if (ms_popcount( state->types & ( MS_TYPE_STR | MS_TYPE_STRLITERAL | MS_TYPE_ENUM | MS_TYPE_BYTES | MS_TYPE_BYTEARRAY | MS_TYPE_MEMORYVIEW | MS_TYPE_DATETIME | MS_TYPE_DATE | MS_TYPE_TIME | MS_TYPE_TIMEDELTA | MS_TYPE_UUID | MS_TYPE_DECIMAL ) ) > 1 ) { PyErr_Format( PyExc_TypeError, "Type unions may not contain more than one str-like type (`str`, " "`Enum`, `Literal[str values]`, `datetime`, `date`, `time`, `timedelta`, " "`uuid`, `decimal`, `bytes`, `bytearray`) - type `%R` is not supported", state->context ); return -1; } return 0; } static int typenode_collect_enum(TypeNodeCollectState *state, PyObject *obj) { bool is_intenum; if (PyType_IsSubtype((PyTypeObject *)obj, &PyLong_Type)) { is_intenum = true; } else if (PyType_IsSubtype((PyTypeObject *)obj, &PyUnicode_Type)) { is_intenum = false; } else { PyObject *members = PyObject_GetAttr(obj, state->mod->str__value2member_map_); if (members == NULL) return -1; if (!PyDict_Check(members)) { Py_DECREF(members); PyErr_SetString( PyExc_RuntimeError, "Expected _value2member_map_ to be a dict" ); return -1; } /* Traverse _value2member_map_ to determine key type */ Py_ssize_t pos = 0; PyObject *key; bool all_ints = true; bool all_strs = true; while (PyDict_Next(members, &pos, &key, NULL)) { all_ints &= PyLong_CheckExact(key); all_strs &= PyUnicode_CheckExact(key); } Py_CLEAR(members); if (all_ints) { is_intenum = true; } else if (all_strs) { is_intenum = false; } else { PyErr_Format( PyExc_TypeError, "Enums must contain either all str or all int values - " "type `%R` is not supported", state->context ); return -1; } } if (is_intenum) { if (state->intenum_obj != NULL) { return typenode_collect_err_unique(state, "int enum"); } state->types |= MS_TYPE_INTENUM; Py_INCREF(obj); state->intenum_obj = obj; } else { if (state->enum_obj != NULL) { return typenode_collect_err_unique(state, "str enum"); } state->types |= MS_TYPE_ENUM; Py_INCREF(obj); state->enum_obj = obj; } return 0; } static int typenode_collect_dict(TypeNodeCollectState *state, uint64_t type, PyObject *key, PyObject *val) { if (state->dict_key_obj != NULL || state->dict_val_obj != NULL) { return typenode_collect_err_unique(state, "dict"); } state->types |= type; Py_INCREF(key); state->dict_key_obj = key; Py_INCREF(val); state->dict_val_obj = val; return 0; } static int typenode_collect_array(TypeNodeCollectState *state, uint64_t type, PyObject *obj) { if (state->array_el_obj != NULL) { return typenode_collect_err_unique( state, "array-like (list, set, tuple)" ); } state->types |= type; Py_INCREF(obj); state->array_el_obj = obj; return 0; } static int typenode_collect_custom(TypeNodeCollectState *state, uint64_t type, PyObject *obj) { if (state->custom_obj != NULL) { return typenode_collect_err_unique(state, "custom"); } state->types |= type; Py_INCREF(obj); state->custom_obj = obj; return 0; } static int typenode_collect_typevar(TypeNodeCollectState *state, PyObject *obj) { int out; PyObject *bound = PyObject_GetAttr(obj, state->mod->str___bound__); if (bound == NULL) return -1; if (bound == Py_None) { Py_DECREF(bound); /* No `bound`, check for constraints */ PyObject *constraints = PyObject_GetAttr(obj, state->mod->str___constraints__); if (constraints == NULL) return -1; if ( !( (constraints == Py_None) || (PyTuple_CheckExact(constraints) && (PyTuple_GET_SIZE(constraints) == 0)) ) ) { PyErr_Format( PyExc_TypeError, "Unbound TypeVar `%R` has constraints `%R` - constraints are " "currently unsupported. If possible, either explicitly bind " "the parameter, or use `bound` instead of constraints.", obj, constraints ); Py_DECREF(constraints); return -1; } Py_DECREF(constraints); /* No constraints either, use `Any` */ out = typenode_collect_type(state, state->mod->typing_any); } else { /* Bound, substitute in the bound type */ out = typenode_collect_type(state, bound); Py_DECREF(bound); } return out; } static int typenode_collect_struct(TypeNodeCollectState *state, PyObject *obj) { if (state->struct_obj == NULL && state->structs_set == NULL) { /* First struct found, store it directly */ Py_INCREF(obj); state->struct_obj = obj; } else { if (state->structs_set == NULL) { /* Second struct found, create a set and move the existing struct there */ state->structs_set = PyFrozenSet_New(NULL); if (state->structs_set == NULL) return -1; if (PySet_Add(state->structs_set, state->struct_obj) < 0) return -1; Py_CLEAR(state->struct_obj); } if (PySet_Add(state->structs_set, obj) < 0) return -1; } return 0; } static int typenode_collect_typeddict(TypeNodeCollectState *state, PyObject *obj) { if (state->typeddict_obj != NULL) { return typenode_collect_err_unique(state, "TypedDict"); } state->types |= MS_TYPE_TYPEDDICT; Py_INCREF(obj); state->typeddict_obj = obj; return 0; } static int typenode_collect_dataclass(TypeNodeCollectState *state, PyObject *obj) { if (state->dataclass_obj != NULL) { return typenode_collect_err_unique(state, "dataclass or attrs"); } state->types |= MS_TYPE_DATACLASS; Py_INCREF(obj); state->dataclass_obj = obj; return 0; } static int typenode_collect_namedtuple(TypeNodeCollectState *state, PyObject *obj) { if (state->namedtuple_obj != NULL) { return typenode_collect_err_unique(state, "NamedTuple"); } state->types |= MS_TYPE_NAMEDTUPLE; Py_INCREF(obj); state->namedtuple_obj = obj; return 0; } static int typenode_collect_literal(TypeNodeCollectState *state, PyObject *literal) { PyObject *args = PyObject_GetAttr(literal, state->mod->str___args__); /* This should never happen, since we know this is a `Literal` object */ if (args == NULL) return -1; Py_ssize_t size = PyTuple_GET_SIZE(args); if (size < 0) goto error; if (size == 0) { PyErr_Format( PyExc_TypeError, "Literal types must have at least one item, %R is invalid", literal ); goto error; } for (Py_ssize_t i = 0; i < size; i++) { PyObject *obj = PyTuple_GET_ITEM(args, i); PyTypeObject *type = Py_TYPE(obj); if (obj == Py_None || obj == NONE_TYPE) { state->literal_none = true; } else if (type == &PyBool_Type) { if (obj == Py_True) { state->literal_bool_true = true; } else { state->literal_bool_false = true; } } else if (type == &PyLong_Type) { if (state->literal_int_values == NULL) { state->literal_int_values = PySet_New(NULL); if (state->literal_int_values == NULL) goto error; } if (PySet_Add(state->literal_int_values, obj) < 0) goto error; } else if (type == &PyUnicode_Type) { if (state->literal_str_values == NULL) { state->literal_str_values = PySet_New(NULL); if (state->literal_str_values == NULL) goto error; } if (PySet_Add(state->literal_str_values, obj) < 0) goto error; } else { /* Check for nested Literal */ PyObject *origin = PyObject_GetAttr(obj, state->mod->str___origin__); if (origin == NULL) { PyErr_Clear(); goto invalid; } else if (origin != state->mod->typing_literal) { Py_DECREF(origin); goto invalid; } Py_DECREF(origin); if (typenode_collect_literal(state, obj) < 0) goto error; } } Py_DECREF(args); return 0; invalid: PyErr_Format( PyExc_TypeError, "Literal may only contain None/booleans/integers/strings - %R is not supported", literal ); error: Py_DECREF(args); return -1; } static int typenode_collect_convert_literals(TypeNodeCollectState *state) { if (state->literals == NULL) { /* Nothing to do */ return 0; } Py_ssize_t n = PyList_GET_SIZE(state->literals); if (n == 1) { PyObject *literal = PyList_GET_ITEM(state->literals, 0); PyObject *cached = NULL; if (get_msgspec_cache(state->mod, literal, &LiteralInfo_Type, &cached)) { if (cached == NULL) return -1; LiteralInfo *info = (LiteralInfo *)cached; if (info->int_lookup != NULL) { state->types |= MS_TYPE_INTLITERAL; Py_INCREF(info->int_lookup); state->literal_int_lookup = info->int_lookup; } if (info->str_lookup != NULL) { state->types |= MS_TYPE_STRLITERAL; Py_INCREF(info->str_lookup); state->literal_str_lookup = info->str_lookup; } if (info->literal_none) { state->types |= MS_TYPE_NONE; } if (info->literal_bool_true) { state->types |= MS_TYPE_BOOLLITERAL_TRUE; } if (info->literal_bool_false) { state->types |= MS_TYPE_BOOLLITERAL_FALSE; } Py_DECREF(cached); return 0; } } /* Collect all values in all literals */ for (Py_ssize_t i = 0; i < n; i++) { PyObject *literal = PyList_GET_ITEM(state->literals, i); if (typenode_collect_literal(state, literal) < 0) return -1; } /* Convert values to lookup objects (if values exist for each type) */ if (state->literal_int_values != NULL) { state->types |= MS_TYPE_INTLITERAL; state->literal_int_lookup = IntLookup_New( state->literal_int_values, NULL, NULL, false ); if (state->literal_int_lookup == NULL) return -1; } if (state->literal_str_values != NULL) { state->types |= MS_TYPE_STRLITERAL; state->literal_str_lookup = StrLookup_New( state->literal_str_values, NULL, NULL, false ); if (state->literal_str_lookup == NULL) return -1; } if (state->literal_none) { state->types |= MS_TYPE_NONE; } if (state->literal_bool_true) { state->types |= MS_TYPE_BOOLLITERAL_TRUE; } if (state->literal_bool_false) { state->types |= MS_TYPE_BOOLLITERAL_FALSE; } if (n == 1) { /* A single `Literal` object, cache the lookups on it */ LiteralInfo *info = PyObject_GC_New(LiteralInfo, &LiteralInfo_Type); if (info == NULL) return -1; Py_XINCREF(state->literal_int_lookup); info->int_lookup = state->literal_int_lookup; Py_XINCREF(state->literal_str_lookup); info->str_lookup = state->literal_str_lookup; info->literal_none = state->literal_none; info->literal_bool_true = state->literal_bool_true; info->literal_bool_false = state->literal_bool_false; PyObject_GC_Track(info); PyObject *literal = PyList_GET_ITEM(state->literals, 0); int status = PyObject_SetAttr( literal, state->mod->str___msgspec_cache__, (PyObject *)info ); Py_DECREF(info); return status; } return 0; } static int typenode_collect_convert_structs_lock_held(TypeNodeCollectState *state) { if (state->struct_obj == NULL && state->structs_set == NULL) { return 0; } else if (state->struct_obj != NULL) { /* Single struct */ state->struct_info = StructInfo_Convert(state->struct_obj); if (state->struct_info == NULL) return -1; if (((StructInfo *)state->struct_info)->class->array_like == OPT_TRUE) { state->types |= MS_TYPE_STRUCT_ARRAY; } else { state->types |= MS_TYPE_STRUCT; } return 0; } /* Multiple structs. * * Try looking the structs_set up in the cache first, to avoid building a * new one below. */ PyObject *lookup = NULL; if (PyDict_GetItemRef(state->mod->struct_lookup_cache, state->structs_set, &lookup) < 0) { return -1; } if (lookup != NULL) { /* Lookup was in the cache, update the state and return */ state->structs_lookup = lookup; if (Lookup_array_like(lookup)) { state->types |= MS_TYPE_STRUCT_ARRAY_UNION; } else { state->types |= MS_TYPE_STRUCT_UNION; } return 0; } /* Here we check a number of restrictions before building a lookup table * from struct tags to their matching classes. * * Validation checks: * - All structs in the set are tagged. * - All structs in the set have the same `array_like` status * - All structs in the set have the same `tag_field` * - All structs in the set have a unique `tag_value` * * If any of these checks fails, an appropriate error is returned. */ PyObject *tag_mapping = NULL, *tag_field = NULL, *set_iter = NULL, *set_item = NULL; PyObject *struct_info = NULL; bool array_like = false; bool tags_are_strings = true; int status = -1; tag_mapping = PyDict_New(); if (tag_mapping == NULL) goto cleanup; set_iter = PyObject_GetIter(state->structs_set); while ((set_item = PyIter_Next(set_iter))) { struct_info = StructInfo_Convert(set_item); Py_DECREF(set_item); if (struct_info == NULL) goto cleanup; StructMetaObject *struct_type = ((StructInfo *)struct_info)->class; PyObject *item_tag_field = struct_type->struct_tag_field; PyObject *item_tag_value = struct_type->struct_tag_value; bool item_array_like = struct_type->array_like == OPT_TRUE; if (item_tag_value == NULL) { PyErr_Format( PyExc_TypeError, "If a type union contains multiple Struct types, all Struct " "types must be tagged (via `tag` or `tag_field` kwarg) - type " "`%R` is not supported", state->context ); goto cleanup; } if (tag_field == NULL) { array_like = struct_type->array_like == OPT_TRUE; tag_field = struct_type->struct_tag_field; tags_are_strings = PyUnicode_CheckExact(item_tag_value); } else { if (array_like != item_array_like) { PyErr_Format( PyExc_TypeError, "Type unions may not contain Struct types with `array_like=True` " "and `array_like=False` - type `%R` is not supported", state->context ); goto cleanup; } if (tags_are_strings != PyUnicode_CheckExact(item_tag_value)) { PyErr_Format( PyExc_TypeError, "Type unions may not contain Struct types with both `int` " "and `str` tags - type `%R` is not supported", state->context ); goto cleanup; } int compare = PyUnicode_Compare(item_tag_field, tag_field); if (compare == -1 && PyErr_Occurred()) goto cleanup; if (compare != 0) { PyErr_Format( PyExc_TypeError, "If a type union contains multiple Struct types, all Struct types " "must have the same `tag_field` - type `%R` is not supported", state->context ); goto cleanup; } } if (PyDict_GetItem(tag_mapping, item_tag_value) != NULL) { PyErr_Format( PyExc_TypeError, "If a type union contains multiple Struct types, all Struct types " "must have unique `tag` values - type `%R` is not supported", state->context ); goto cleanup; } int ok = PyDict_SetItem(tag_mapping, item_tag_value, struct_info) == 0; Py_CLEAR(struct_info); if (!ok) goto cleanup; } /* Build a lookup from tag_value -> struct_info */ if (tags_are_strings) { lookup = StrLookup_New(tag_mapping, tag_field, NULL, array_like); } else { lookup = IntLookup_New(tag_mapping, tag_field, NULL, array_like); } if (lookup == NULL) goto cleanup; state->structs_lookup = lookup; /* Check if the cache is full, if so clear the oldest item */ if (PyDict_GET_SIZE(state->mod->struct_lookup_cache) == 64) { PyObject *key; Py_ssize_t pos = 0; if (PyDict_Next(state->mod->struct_lookup_cache, &pos, &key, NULL)) { if (PyDict_DelItem(state->mod->struct_lookup_cache, key) < 0) { goto cleanup; } } } /* Add the new lookup to the cache */ if (PyDict_SetItem(state->mod->struct_lookup_cache, state->structs_set, lookup) < 0) { goto cleanup; } /* Update the `types` */ if (array_like) { state->types |= MS_TYPE_STRUCT_ARRAY_UNION; } else { state->types |= MS_TYPE_STRUCT_UNION; } status = 0; cleanup: Py_XDECREF(set_iter); Py_XDECREF(tag_mapping); Py_XDECREF(struct_info); return status; } static int typenode_collect_convert_structs(TypeNodeCollectState *state) { int status; Py_BEGIN_CRITICAL_SECTION(state->mod->struct_lookup_cache); status = typenode_collect_convert_structs_lock_held(state); Py_END_CRITICAL_SECTION(); return status; } static void typenode_collect_clear_state(TypeNodeCollectState *state) { Py_CLEAR(state->struct_obj); Py_CLEAR(state->struct_info); Py_CLEAR(state->structs_set); Py_CLEAR(state->structs_lookup); Py_CLEAR(state->intenum_obj); Py_CLEAR(state->enum_obj); Py_CLEAR(state->custom_obj); Py_CLEAR(state->array_el_obj); Py_CLEAR(state->dict_key_obj); Py_CLEAR(state->dict_val_obj); Py_CLEAR(state->typeddict_obj); Py_CLEAR(state->dataclass_obj); Py_CLEAR(state->namedtuple_obj); Py_CLEAR(state->literals); Py_CLEAR(state->literal_int_values); Py_CLEAR(state->literal_int_lookup); Py_CLEAR(state->literal_str_values); Py_CLEAR(state->literal_str_lookup); Py_CLEAR(state->c_str_regex); } /* This decomposes an input type `obj`, stripping out any "wrapper" types * (Annotated/NewType). It returns the following components: * * - `t` (return value): the first "concrete" type found in the type tree. * - `origin`: `__origin__` on `t` (if present), with a few normalizations * applied to work around differences in type spelling (List vs list) and * python version. * - `args`: `__args__` on `t` (if present) * - `constraints`: Any constraints from `Meta` objects annotated on the type */ static PyObject * typenode_origin_args_metadata( TypeNodeCollectState *state, PyObject *obj, PyObject **out_origin, PyObject **out_args, Constraints *constraints ) { PyObject *origin = NULL, *args = NULL; PyObject *t = obj; Py_INCREF(t); /* First strip out meta "wrapper" types (Annotated, NewType, Final) */ while (true) { assert(t != NULL && origin == NULL && args == NULL); /* Before inspecting attributes, try looking up the object in the * abstract -> concrete mapping. If present, this is an unparametrized * collection of some form. This helps avoid compatibility issues in * Python 3.8, where unparametrized collections still have __args__. */ origin = PyDict_GetItemWithError(state->mod->concrete_types, t); if (origin != NULL) { Py_INCREF(origin); break; } else { /* Ignore all errors in this initial check */ PyErr_Clear(); } /* If `t` is a type instance, no need to inspect further */ if (PyType_CheckExact(t)) { /* t is a concrete type object. */ break; } origin = PyObject_GetAttr(t, state->mod->str___origin__); if (origin != NULL) { if (Py_TYPE(t) == (PyTypeObject *)(state->mod->typing_annotated_alias)) { /* Handle typing.Annotated[...] */ PyObject *metadata = PyObject_GetAttr(t, state->mod->str___metadata__); if (metadata == NULL) goto error; for (Py_ssize_t i = 0; i < PyTuple_GET_SIZE(metadata); i++) { PyObject *annot = PyTuple_GET_ITEM(metadata, i); if (Py_TYPE(annot) == &Meta_Type) { if (constraints_update(constraints, (Meta *)annot, obj) < 0) { Py_DECREF(metadata); goto error; } } } Py_DECREF(metadata); Py_DECREF(t); t = origin; origin = NULL; continue; } else { args = PyObject_GetAttr(t, state->mod->str___args__); if (args != NULL) { if (!PyTuple_Check(args)) { PyErr_SetString(PyExc_TypeError, "__args__ must be a tuple"); goto error; } if (origin == state->mod->typing_final) { /* Handle typing.Final[...] */ PyObject *temp = PyTuple_GetItem(args, 0); if (temp == NULL) goto error; Py_CLEAR(args); Py_CLEAR(origin); Py_DECREF(t); Py_INCREF(temp); t = temp; continue; } /* Check for parametrized TypeAliasType if Python 3.12+ */ #if PY312_PLUS if (Py_TYPE(origin) == (PyTypeObject *)(state->mod->typing_typealiastype)) { PyObject *value = PyObject_GetAttr(origin, state->mod->str___value__); if (value == NULL) goto error; PyObject *temp = PyObject_GetItem(value, args); Py_DECREF(value); if (temp == NULL) goto error; Py_CLEAR(args); Py_CLEAR(origin); Py_DECREF(t); t = temp; continue; } #endif } else { /* Custom non-parametrized generics won't have __args__ * set. Ignore __args__ error */ PyErr_Clear(); } /* Lookup __origin__ in the mapping, in case it's a supported * abstract type. Equal to `origin = mapping.get(origin, origin)` */ PyObject *temp = PyDict_GetItem(state->mod->concrete_types, origin); if (temp != NULL) { Py_DECREF(origin); Py_INCREF(temp); origin = temp; } break; } } else { PyErr_Clear(); /* Check for NewType */ PyObject *supertype = PyObject_GetAttr(t, state->mod->str___supertype__); if (supertype != NULL) { /* It's a newtype, use the wrapped type and loop again */ Py_DECREF(t); t = supertype; continue; } PyErr_Clear(); /* Check for TypeAliasType if Python 3.12+ */ #if PY312_PLUS if (Py_TYPE(t) == (PyTypeObject *)(state->mod->typing_typealiastype)) { PyObject *value = PyObject_GetAttr(t, state->mod->str___value__); if (value == NULL) goto error; Py_DECREF(t); t = value; continue; } #endif break; } } if (Py_TYPE(t) == (PyTypeObject *)(state->mod->types_uniontype)) { /* Handle types.UnionType unions (`int | float | ...`) */ args = PyObject_GetAttr(t, state->mod->str___args__); if (args == NULL) goto error; origin = state->mod->typing_union; Py_INCREF(origin); } *out_origin = origin; *out_args = args; return t; error: Py_XDECREF(t); Py_XDECREF(origin); Py_XDECREF(args); return NULL; } static bool is_namedtuple_class(TypeNodeCollectState *state, PyObject *t) { return ( PyType_Check(t) && PyType_IsSubtype((PyTypeObject *)t, &PyTuple_Type) && PyObject_HasAttr(t, state->mod->str__fields) ); } static bool is_typeddict_class(TypeNodeCollectState *state, PyObject *t) { return ( PyType_Check(t) && PyType_IsSubtype((PyTypeObject *)t, &PyDict_Type) && PyObject_HasAttr(t, state->mod->str___total__) ); } static bool is_dataclass_or_attrs_class(TypeNodeCollectState *state, PyObject *t) { return ( PyType_Check(t) && ( PyObject_HasAttr(t, state->mod->str___dataclass_fields__) || PyObject_HasAttr(t, state->mod->str___attrs_attrs__) ) ); } static MS_INLINE int normalize_types_generic_alias(TypeNodeCollectState *state, PyObject **t, PyObject *origin, PyObject *args) { // if '*t' is a 'types.GenericAlias', replace it (in place) with an equivalent // 'typing._GenericAlias'. 'types.GenericAlias' has __slots__ and forwards // attribute access to its origin, so we can't cache type info (as // '__msgspec_cache__') on it; a 'typing._GenericAlias' can. // // only the branches that cache on the alias (struct/dataclass/TypedDict/ // NamedTuple/Literal) need to call this. a 'types.GenericAlias' here only arises // when subclassing a builtin container generic (e.g. 'collections.abc.Mapping') or // from a manually constructed 'types.GenericAlias' (e.g. wrapping 'typing.Literal'). // // replace '*t' with a new reference on success (dropping the original), or // return -1 with an exception set. if (MS_LIKELY(Py_TYPE(*t) != &Py_GenericAliasType)) return 0; PyObject *converted = PyObject_CallFunctionObjArgs( state->mod->convert_generic_alias, origin, args, NULL ); if (converted == NULL) return -1; Py_SETREF(*t, converted); return 0; } static int typenode_collect_type(TypeNodeCollectState *state, PyObject *obj) { int out = 0; PyObject *t = NULL, *origin = NULL, *args = NULL; Constraints constraints = {0}; enum constraint_kind kind = CK_OTHER; /* If `Any` type already encountered, nothing to do */ if (state->types & MS_TYPE_ANY) return 0; t = typenode_origin_args_metadata(state, obj, &origin, &args, &constraints); if (t == NULL) return -1; if (t == state->mod->typing_any) { /* Any takes precedence, drop all existing and update type flags */ typenode_collect_clear_state(state); state->types = MS_TYPE_ANY; } else if (t == Py_None || t == NONE_TYPE) { state->types |= MS_TYPE_NONE; } else if (t == (PyObject *)(&PyBool_Type)) { state->types |= MS_TYPE_BOOL; } else if (t == (PyObject *)(&PyLong_Type)) { state->types |= MS_TYPE_INT; kind = CK_INT; } else if (t == (PyObject *)(&PyFloat_Type)) { state->types |= MS_TYPE_FLOAT; kind = CK_FLOAT; } else if (t == (PyObject *)(&PyUnicode_Type)) { state->types |= MS_TYPE_STR; kind = CK_STR; } else if (t == (PyObject *)(&PyBytes_Type)) { state->types |= MS_TYPE_BYTES; kind = CK_BYTES; } else if (t == (PyObject *)(&PyByteArray_Type)) { state->types |= MS_TYPE_BYTEARRAY; kind = CK_BYTES; } else if (t == (PyObject *)(&PyMemoryView_Type)) { state->types |= MS_TYPE_MEMORYVIEW; kind = CK_BYTES; } else if (t == (PyObject *)(PyDateTimeAPI->DateTimeType)) { state->types |= MS_TYPE_DATETIME; kind = CK_TIME; } else if (t == (PyObject *)(PyDateTimeAPI->DateType)) { state->types |= MS_TYPE_DATE; } else if (t == (PyObject *)(PyDateTimeAPI->TimeType)) { state->types |= MS_TYPE_TIME; kind = CK_TIME; } else if (t == (PyObject *)(PyDateTimeAPI->DeltaType)) { state->types |= MS_TYPE_TIMEDELTA; } else if (t == state->mod->UUIDType) { state->types |= MS_TYPE_UUID; } else if (t == state->mod->DecimalType) { state->types |= MS_TYPE_DECIMAL; } else if (t == (PyObject *)(&Ext_Type)) { state->types |= MS_TYPE_EXT; } else if (t == (PyObject *)(&Raw_Type)) { /* Raw is marked with a typecode of 0, nothing to do */ } else if (Py_TYPE(t) == (PyTypeObject *)(state->mod->typing_typevar)) { out = typenode_collect_typevar(state, t); } else if ( ms_is_struct_cls(t) || (origin != NULL && ms_is_struct_cls(origin)) ) { if (normalize_types_generic_alias(state, &t, origin, args) < 0) { out = -1; } else { out = typenode_collect_struct(state, t); } } else if (PyType_IsSubtype(Py_TYPE(t), state->mod->EnumMetaType)) { out = typenode_collect_enum(state, t); } else if (origin == (PyObject*)(&PyDict_Type)) { kind = CK_MAP; if (args != NULL && PyTuple_GET_SIZE(args) != 2) goto invalid; out = typenode_collect_dict( state, MS_TYPE_DICT, (args == NULL) ? state->mod->typing_any : PyTuple_GET_ITEM(args, 0), (args == NULL) ? state->mod->typing_any : PyTuple_GET_ITEM(args, 1) ); } else if (origin == (PyObject*)(&PyList_Type)) { kind = CK_ARRAY; if (args != NULL && PyTuple_GET_SIZE(args) != 1) goto invalid; out = typenode_collect_array( state, MS_TYPE_LIST, (args == NULL) ? state->mod->typing_any : PyTuple_GET_ITEM(args, 0) ); } #if PY315_PLUS else if (origin == (PyObject*)(&PyFrozenDict_Type)) { kind = CK_MAP; if (args != NULL && PyTuple_GET_SIZE(args) != 2) goto invalid; out = typenode_collect_dict( state, MS_TYPE_FROZENDICT, (args == NULL) ? state->mod->typing_any : PyTuple_GET_ITEM(args, 0), (args == NULL) ? state->mod->typing_any : PyTuple_GET_ITEM(args, 1) ); } #endif else if (origin == (PyObject*)(&PySet_Type)) { kind = CK_ARRAY; if (args != NULL && PyTuple_GET_SIZE(args) != 1) goto invalid; out = typenode_collect_array( state, MS_TYPE_SET, (args == NULL) ? state->mod->typing_any : PyTuple_GET_ITEM(args, 0) ); } else if (origin == (PyObject*)(&PyFrozenSet_Type)) { kind = CK_ARRAY; if (args != NULL && PyTuple_GET_SIZE(args) != 1) goto invalid; out = typenode_collect_array( state, MS_TYPE_FROZENSET, (args == NULL) ? state->mod->typing_any : PyTuple_GET_ITEM(args, 0) ); } else if (origin == (PyObject*)(&PyTuple_Type)) { if (args == NULL) { kind = CK_ARRAY; out = typenode_collect_array( state, MS_TYPE_VARTUPLE, state->mod->typing_any ); } else if (PyTuple_GET_SIZE(args) == 2 && PyTuple_GET_ITEM(args, 1) == Py_Ellipsis) { kind = CK_ARRAY; out = typenode_collect_array( state, MS_TYPE_VARTUPLE, PyTuple_GET_ITEM(args, 0) ); } else if ( PyTuple_GET_SIZE(args) == 1 && PyTuple_CheckExact(PyTuple_GET_ITEM(args, 0)) && PyTuple_GET_SIZE(PyTuple_GET_ITEM(args, 0)) == 0 ) { /* XXX: this case handles a weird compatibility issue: * - typing.Tuple[()].__args__ == ((),) * - tuple[()].__args__ == () */ out = typenode_collect_array( state, MS_TYPE_FIXTUPLE, PyTuple_GET_ITEM(args, 0) ); } else { out = typenode_collect_array(state, MS_TYPE_FIXTUPLE, args); } } else if (origin == state->mod->typing_union) { if (Py_EnterRecursiveCall(" while analyzing a type")) { out = -1; goto done; } for (Py_ssize_t i = 0; i < PyTuple_GET_SIZE(args); i++) { PyObject *arg = PyTuple_GET_ITEM(args, i); /* Ignore UnsetType in unions */ if (arg == (PyObject *)(&Unset_Type)) continue; out = typenode_collect_type(state, arg); if (out < 0) break; } Py_LeaveRecursiveCall(); } else if (origin == state->mod->typing_literal) { if (state->literals == NULL) { state->literals = PyList_New(0); if (state->literals == NULL) goto done; } if (normalize_types_generic_alias(state, &t, origin, args) < 0) { out = -1; } else { out = PyList_Append(state->literals, t); } } else if ( is_typeddict_class(state, t) || (origin != NULL && is_typeddict_class(state, origin)) ) { if (normalize_types_generic_alias(state, &t, origin, args) < 0) { out = -1; } else { out = typenode_collect_typeddict(state, t); } } else if ( is_namedtuple_class(state, t) || (origin != NULL && is_namedtuple_class(state, origin)) ) { if (normalize_types_generic_alias(state, &t, origin, args) < 0) { out = -1; } else { out = typenode_collect_namedtuple(state, t); } } else if ( is_dataclass_or_attrs_class(state, t) || (origin != NULL && is_dataclass_or_attrs_class(state, origin)) ) { if (normalize_types_generic_alias(state, &t, origin, args) < 0) { out = -1; } else { out = typenode_collect_dataclass(state, t); } } else { if (origin != NULL) { if (!PyType_Check(origin)) goto invalid; } else { if (!PyType_Check(t)) goto invalid; } out = typenode_collect_custom( state, (origin != NULL) ? MS_TYPE_CUSTOM_GENERIC : MS_TYPE_CUSTOM, t ); } done: Py_XDECREF(t); Py_XDECREF(origin); Py_XDECREF(args); if (out == 0) { out = typenode_collect_constraints(state, &constraints, kind, obj); } return out; invalid: PyErr_Format(PyExc_TypeError, "Type '%R' is not supported", t); out = -1; goto done; } static TypeNode * TypeNode_Convert(PyObject *obj) { TypeNode *out = NULL; TypeNodeCollectState state = {0}; state.mod = msgspec_get_global_state(); state.context = obj; if (Py_EnterRecursiveCall(" while analyzing a type")) return NULL; /* Traverse `obj` to collect all type annotations at this level */ if (typenode_collect_type(&state, obj) < 0) goto done; /* Handle structs in a second pass */ if (typenode_collect_convert_structs(&state) < 0) goto done; /* Handle literals in a second pass */ if (typenode_collect_convert_literals(&state) < 0) goto done; /* Check type invariants to ensure Union types are valid */ if (typenode_collect_check_invariants(&state) < 0) goto done; /* Populate a new TypeNode, recursing into subtypes as needed */ out = typenode_from_collect_state(&state); done: typenode_collect_clear_state(&state); Py_LeaveRecursiveCall(); return out; } #define ms_raise_validation_error(path, format, ...) \ do { \ MsgspecState *st = msgspec_get_global_state(); \ PyObject *suffix = PathNode_ErrSuffix(path); \ if (suffix != NULL) { \ PyErr_Format(st->ValidationError, format, __VA_ARGS__, suffix); \ Py_DECREF(suffix); \ } \ } while (0) static MS_NOINLINE PyObject * ms_validation_error(const char *got, TypeNode *type, PathNode *path) { PyObject *type_repr = typenode_simple_repr(type); if (type_repr != NULL) { ms_raise_validation_error(path, "Expected `%U`, got `%s`%U", type_repr, got); Py_DECREF(type_repr); } return NULL; } static void ms_missing_required_field(PyObject *field, PathNode *path) { ms_raise_validation_error( path, "Object missing required field `%U`%U", field ); } static PyObject * ms_invalid_cstr_value(const char *cstr, Py_ssize_t size, PathNode *path) { PyObject *str = PyUnicode_DecodeUTF8(cstr, size, NULL); if (str == NULL) return NULL; ms_raise_validation_error(path, "Invalid value '%U'%U", str); Py_DECREF(str); return NULL; } static PyObject * ms_invalid_cint_value(int64_t val, PathNode *path) { ms_raise_validation_error(path, "Invalid value %lld%U", val); return NULL; } static PyObject * ms_invalid_cuint_value(uint64_t val, PathNode *path) { ms_raise_validation_error(path, "Invalid value %llu%U", val); return NULL; } static MS_NOINLINE PyObject * ms_error_unknown_field(const char *key, Py_ssize_t key_size, PathNode *path) { PyObject *field = PyUnicode_FromStringAndSize(key, key_size); if (field == NULL) return NULL; ms_raise_validation_error( path, "Object contains unknown field `%U`%U", field ); Py_DECREF(field); return NULL; } /* Same as ms_raise_validation_error, except doesn't require any format arguments. */ static PyObject * ms_error_with_path(const char *msg, PathNode *path) { MsgspecState *st = msgspec_get_global_state(); PyObject *suffix = PathNode_ErrSuffix(path); if (suffix != NULL) { PyErr_Format(st->ValidationError, msg, suffix); Py_DECREF(suffix); } return NULL; } static MS_NOINLINE void ms_maybe_wrap_validation_error(PathNode *path) { PyObject *exc_type, *exc, *tb; /* Fetch the exception state */ PyErr_Fetch(&exc_type, &exc, &tb); /* If null, some other c-extension has borked, just return */ if (exc_type == NULL) return; MsgspecState *mod = msgspec_get_global_state(); /* If it's a TypeError or ValueError, wrap it in a ValidationError. * Otherwise we reraise the original error below. * Since DecodeError (and ValidationError) subclass from ValueError, we need * to special case them below - we don't wrap in those cases. */ if ( !PyType_IsSubtype((PyTypeObject *)exc_type, (PyTypeObject *)mod->DecodeError) && ( PyType_IsSubtype( (PyTypeObject *)exc_type, (PyTypeObject *)PyExc_ValueError ) || PyType_IsSubtype( (PyTypeObject *)exc_type, (PyTypeObject *)PyExc_TypeError ) ) ) { PyObject *exc_type2, *exc2, *tb2; /* Normalize the original exception */ PyErr_NormalizeException(&exc_type, &exc, &tb); if (tb != NULL) { PyException_SetTraceback(exc, tb); Py_DECREF(tb); } Py_DECREF(exc_type); /* Raise a new validation error with context based on the * original exception */ ms_raise_validation_error(path, "%S%U", exc); /* Fetch the new exception */ PyErr_Fetch(&exc_type2, &exc2, &tb2); /* Normalize the new exception */ PyErr_NormalizeException(&exc_type2, &exc2, &tb2); /* Set the original exception as the cause and context */ Py_INCREF(exc); PyException_SetCause(exc2, exc); PyException_SetContext(exc2, exc); /* At this point the original exc_type/exc/tb are all dropped, * replace them with the new values */ exc_type = exc_type2; exc = exc2; tb = tb2; } /* Restore the new exception state */ PyErr_Restore(exc_type, exc, tb); } static PyTypeObject StructMixinType; static PyObject * Struct_alloc(PyTypeObject *type) { return type->tp_alloc(type, type->tp_itemsize); } /* Mirrored from cpython Objects/typeobject.c */ static void clear_slots(PyTypeObject *type, PyObject *self) { Py_ssize_t i, n; PyMemberDef *mp; n = Py_SIZE(type); mp = MS_PyHeapType_GET_MEMBERS((PyHeapTypeObject *)type); for (i = 0; i < n; i++, mp++) { if (mp->type == T_OBJECT_EX && !(mp->flags & READONLY)) { char *addr = (char *)self + mp->offset; PyObject *obj = *(PyObject **)addr; if (obj != NULL) { *(PyObject **)addr = NULL; Py_DECREF(obj); } } } } static void Struct_dealloc_nogc(PyObject *self) { PyTypeObject *type = Py_TYPE(self); /* Maybe call a finalizer */ if (type->tp_finalize) { /* If resurrected, exit early */ if (PyObject_CallFinalizerFromDealloc(self) < 0) return; } /* Maybe clear weakrefs */ if (type->tp_weaklistoffset) { PyObject_ClearWeakRefs(self); } /* Clear all slots */ PyTypeObject *base = type; while (base != NULL) { if (Py_SIZE(base)) { clear_slots(base, self); } base = base->tp_base; } type->tp_free(self); /* Decref the object type immediately */ Py_DECREF(type); } static PyObject * StructMeta_get_field_name(PyObject *self, Py_ssize_t field_index) { return PyTuple_GET_ITEM( ((StructMetaObject *)self)->struct_encode_fields, field_index ); } static MS_INLINE Py_ssize_t StructMeta_get_field_index( StructMetaObject *self, const char * key, Py_ssize_t key_size, Py_ssize_t *pos ) { const char *field; Py_ssize_t nfields, field_size, i, offset = *pos; nfields = PyTuple_GET_SIZE(self->struct_encode_fields); for (i = offset; i < nfields; i++) { field = unicode_str_and_size_nocheck( PyTuple_GET_ITEM(self->struct_encode_fields, i), &field_size ); if (key_size == field_size && memcmp(key, field, key_size) == 0) { *pos = i < (nfields - 1) ? (i + 1) : 0; return i; } } for (i = 0; i < offset; i++) { field = unicode_str_and_size_nocheck( PyTuple_GET_ITEM(self->struct_encode_fields, i), &field_size ); if (key_size == field_size && memcmp(key, field, key_size) == 0) { *pos = i + 1; return i; } } /* Not a field, check if it matches the tag field (if present) */ if (MS_UNLIKELY(self->struct_tag_field != NULL)) { Py_ssize_t tag_field_size; const char *tag_field; tag_field = unicode_str_and_size_nocheck(self->struct_tag_field, &tag_field_size); if (key_size == tag_field_size && memcmp(key, tag_field, key_size) == 0) { return -2; } } return -1; } static int dict_discard(PyObject *dict, PyObject *key) { int status = PyDict_Contains(dict, key); if (status < 0) return status; return (status == 1) ? PyDict_DelItem(dict, key) : 0; } static PyObject * Struct_vectorcall(PyTypeObject *cls, PyObject *const *args, size_t nargsf, PyObject *kwnames); /* setattr for frozen=True types */ static int Struct_setattro_frozen(PyObject *self, PyObject *key, PyObject *value) { PyErr_Format( PyExc_AttributeError, "immutable type: '%s'", Py_TYPE(self)->tp_name ); return -1; } /* setattr for frozen=False types */ static int Struct_setattro_default(PyObject *self, PyObject *key, PyObject *value) { if (PyObject_GenericSetAttr(self, key, value) < 0) return -1; if ( value != NULL && MS_OBJECT_IS_GC(self) && !MS_IS_TRACKED(self) && MS_MAYBE_TRACKED(value) ) PyObject_GC_Track(self); return 0; } static PyObject* rename_lower(PyObject *rename, PyObject *field) { return PyObject_CallMethod(field, "lower", NULL); } static PyObject* rename_upper(PyObject *rename, PyObject *field) { return PyObject_CallMethod(field, "upper", NULL); } static PyObject* rename_kebab(PyObject *rename, PyObject *field) { PyObject *underscore = NULL, *dash = NULL, *temp = NULL, *out = NULL; underscore = PyUnicode_FromStringAndSize("_", 1); if (underscore == NULL) goto error; dash = PyUnicode_FromStringAndSize("-", 1); if (dash == NULL) goto error; temp = PyObject_CallMethod(field, "strip", "s", "_"); if (temp == NULL) goto error; out = PyUnicode_Replace(temp, underscore, dash, -1); error: Py_XDECREF(underscore); Py_XDECREF(dash); Py_XDECREF(temp); return out; } static PyObject* rename_camel_inner(PyObject *field, bool cap_first) { PyObject *parts = NULL, *out = NULL, *empty = NULL; PyObject *underscore = PyUnicode_FromStringAndSize("_", 1); if (underscore == NULL) return NULL; parts = PyUnicode_Split(field, underscore, -1); if (parts == NULL) goto cleanup; if (PyList_GET_SIZE(parts) == 1 && !cap_first) { Py_INCREF(field); out = field; goto cleanup; } bool first = true; for (Py_ssize_t i = 0; i < PyList_GET_SIZE(parts); i++) { PyObject *part = PyList_GET_ITEM(parts, i); if (first && (PyUnicode_GET_LENGTH(part) == 0)) { /* Preserve leading underscores */ Py_INCREF(underscore); Py_DECREF(part); PyList_SET_ITEM(parts, i, underscore); } else { if (!first || cap_first) { /* convert part to title case, inplace in the list */ PyObject *part_title = PyObject_CallMethod(part, "title", NULL); if (part_title == NULL) goto cleanup; Py_DECREF(part); PyList_SET_ITEM(parts, i, part_title); } first = false; } } empty = PyUnicode_FromStringAndSize("", 0); if (empty == NULL) goto cleanup; out = PyUnicode_Join(empty, parts); cleanup: Py_XDECREF(empty); Py_XDECREF(underscore); Py_XDECREF(parts); return out; } static PyObject* rename_camel(PyObject *rename, PyObject *field) { return rename_camel_inner(field, false); } static PyObject* rename_pascal(PyObject *rename, PyObject *field) { return rename_camel_inner(field, true); } static PyObject* rename_callable(PyObject *rename, PyObject *field) { PyObject *temp = PyObject_CallOneArg(rename, field); if (temp == NULL) return NULL; if (PyUnicode_CheckExact(temp)) return temp; if (temp == Py_None) { Py_DECREF(temp); Py_INCREF(field); return field; } PyErr_Format( PyExc_TypeError, "Expected calling `rename` to return a `str` or `None`, got `%.200s`", Py_TYPE(temp)->tp_name ); Py_DECREF(temp); return NULL; } static PyObject* rename_mapping(PyObject *rename, PyObject *field) { PyObject *temp = PyObject_GetItem(rename, field); if (temp == NULL) { PyErr_Clear(); Py_INCREF(field); return field; } else if (temp == Py_None) { Py_DECREF(temp); Py_INCREF(field); return field; } else if (PyUnicode_CheckExact(temp)) { return temp; } PyErr_Format( PyExc_TypeError, "Expected `rename[field]` to return a `str` or `None`, got `%.200s`", Py_TYPE(temp)->tp_name ); Py_DECREF(temp); return NULL; } typedef struct { /* Temporary state. All owned references. */ PyObject *defaults_lk; PyObject *offsets_lk; PyObject *kwonly_fields; PyObject *slots; PyObject *namespace; PyObject *renamed_fields; /* Output values. All owned references. */ PyObject *fields; PyObject *encode_fields; PyObject *defaults; PyObject *match_args; PyObject *tag; PyObject *tag_field; PyObject *tag_value; Py_ssize_t *offsets; Py_ssize_t nkwonly; Py_ssize_t n_trailing_defaults; /* Configuration values. All borrowed references. */ PyObject *name; PyObject *temp_tag_field; PyObject *temp_tag; PyObject *rename; int omit_defaults; int forbid_unknown_fields; int frozen; int eq; int order; int repr_omit_defaults; int array_like; int gc; int weakref; bool already_has_weakref; int dict; bool already_has_dict; int cache_hash; Py_ssize_t hash_offset; bool has_non_slots_bases; } StructMetaInfo; static int structmeta_check_namespace(PyObject *namespace) { static const char *attrs[] = {"__init__", "__new__", "__slots__"}; Py_ssize_t nattrs = 3; for (Py_ssize_t i = 0; i < nattrs; i++) { if (PyDict_GetItemString(namespace, attrs[i]) != NULL) { PyErr_Format(PyExc_TypeError, "Struct types cannot define %s", attrs[i]); return -1; } } return 0; } static PyObject * structmeta_get_module_ns(MsgspecState *mod, StructMetaInfo *info) { PyObject *name = PyDict_GetItemString(info->namespace, "__module__"); if (name == NULL) return NULL; PyObject *modules = PySys_GetObject("modules"); if (modules == NULL) return NULL; PyObject *module = PyDict_GetItem(modules, name); if (module == NULL) return NULL; return PyObject_GetAttr(module, mod->str___dict__); } static int structmeta_collect_base(StructMetaInfo *info, MsgspecState *mod, PyObject *base) { if (!PyType_Check(base)) { /* CPython's metaclass conflict check will catch this issue earlier on, * but it's still good to have this check in place in case that's ever * removed */ PyErr_SetString(PyExc_TypeError, "All base classes must be types"); return -1; } if ((PyTypeObject *)base == &StructMixinType) return 0; /* A base that has not been readied yet, which a C extension can expose, * has neither its type dict nor its inherited slots filled in. Readying * a type owned by another extension can have side effects, so such a * base is rejected instead. */ if (!PyType_HasFeature((PyTypeObject *)base, Py_TPFLAGS_READY)) { PyErr_Format(PyExc_TypeError, "Base class %R is not ready", base); return -1; } if (((PyTypeObject *)base)->tp_weaklistoffset) { info->already_has_weakref = true; } if (((PyTypeObject *)base)->tp_dictoffset) { info->already_has_dict = true; } if (!ms_is_struct_cls(base)) { if (((PyTypeObject *)base)->tp_dictoffset) { info->has_non_slots_bases = true; } static const char *attrs[] = {"__init__", "__new__"}; Py_ssize_t nattrs = 2; PyObject *tp_dict = MS_GET_TYPE_DICT((PyTypeObject *)base); if (tp_dict == NULL) { PyErr_Format( PyExc_TypeError, "Cannot read the attributes of base class %R", base ); return -1; } for (Py_ssize_t i = 0; i < nattrs; i++) { if (PyDict_GetItemString(tp_dict, attrs[i]) != NULL) { PyErr_Format(PyExc_TypeError, "Struct base classes cannot define %s", attrs[i]); MS_RELEASE_TYPE_DICT(tp_dict); return -1; } } MS_RELEASE_TYPE_DICT(tp_dict); return 0; } StructMetaObject *st_type = (StructMetaObject *)base; /* Check if a hash_cache slot already exists */ if (st_type->hash_offset != 0) { info->hash_offset = st_type->hash_offset; } /* Inherit config fields */ if (st_type->struct_tag_field != NULL) { info->temp_tag_field = st_type->struct_tag_field; } if (st_type->struct_tag != NULL) { info->temp_tag = st_type->struct_tag; } if (st_type->rename != NULL) { info->rename = st_type->rename; } info->frozen = STRUCT_MERGE_OPTIONS(info->frozen, st_type->frozen); info->eq = STRUCT_MERGE_OPTIONS(info->eq, st_type->eq); info->order = STRUCT_MERGE_OPTIONS(info->order, st_type->order); info->array_like = STRUCT_MERGE_OPTIONS(info->array_like, st_type->array_like); info->gc = STRUCT_MERGE_OPTIONS(info->gc, st_type->gc); info->omit_defaults = STRUCT_MERGE_OPTIONS(info->omit_defaults, st_type->omit_defaults); info->repr_omit_defaults = STRUCT_MERGE_OPTIONS( info->repr_omit_defaults, st_type->repr_omit_defaults ); info->forbid_unknown_fields = STRUCT_MERGE_OPTIONS( info->forbid_unknown_fields, st_type->forbid_unknown_fields ); PyObject *fields = st_type->struct_fields; PyObject *encode_fields = st_type->struct_encode_fields; PyObject *defaults = st_type->struct_defaults; Py_ssize_t *offsets = st_type->struct_offsets; Py_ssize_t nfields = PyTuple_GET_SIZE(fields); Py_ssize_t nkwonly = st_type->nkwonly; Py_ssize_t ndefaults = PyTuple_GET_SIZE(defaults); Py_ssize_t defaults_offset = nfields - ndefaults; for (Py_ssize_t i = 0; i < nfields; i++) { PyObject *field = PyTuple_GET_ITEM(fields, i); PyObject *encode_field = PyTuple_GET_ITEM(encode_fields, i); PyObject *default_val = NODEFAULT; if (i >= defaults_offset) { default_val = PyTuple_GET_ITEM(defaults, i - defaults_offset); } if (PyDict_SetItem(info->defaults_lk, field, default_val) < 0) return -1; /* Mark the field as kwonly or not */ if (i >= (nfields - nkwonly)) { if (PySet_Add(info->kwonly_fields, field) < 0) return -1; } else { if (PySet_Discard(info->kwonly_fields, field) < 0) return -1; } /* Propagate any renamed fields */ if (field != encode_field) { if (PyDict_SetItem(info->renamed_fields, field, encode_field) < 0) return -1; } PyObject *offset = PyLong_FromSsize_t(offsets[i]); if (offset == NULL) return -1; bool errored = PyDict_SetItem(info->offsets_lk, field, offset) < 0; Py_DECREF(offset); if (errored) return -1; } return 0; } static int structmeta_process_rename( StructMetaInfo *info, PyObject *name, PyObject *default_value ) { if ( default_value != NULL && Py_TYPE(default_value) == &Field_Type && ((Field *)default_value)->name != NULL ) { Field *field = (Field *)default_value; if (PyUnicode_Compare(name, field->name) == 0) { if (PyDict_GetItem(info->renamed_fields, name) != NULL) { return PyDict_DelItem(info->renamed_fields, name); } return 0; } return PyDict_SetItem(info->renamed_fields, name, field->name); } if (info->rename == NULL) return 0; PyObject* (*method)(PyObject *, PyObject *); if (PyUnicode_CheckExact(info->rename)) { if (PyUnicode_CompareWithASCIIString(info->rename, "lower") == 0) { method = &rename_lower; } else if (PyUnicode_CompareWithASCIIString(info->rename, "upper") == 0) { method = &rename_upper; } else if (PyUnicode_CompareWithASCIIString(info->rename, "camel") == 0) { method = &rename_camel; } else if (PyUnicode_CompareWithASCIIString(info->rename, "pascal") == 0) { method = &rename_pascal; } else if (PyUnicode_CompareWithASCIIString(info->rename, "kebab") == 0) { method = &rename_kebab; } else { PyErr_Format(PyExc_ValueError, "rename='%U' is unsupported", info->rename); return -1; } } else if (PyCallable_Check(info->rename)) { method = &rename_callable; } else if (PyMapping_Check(info->rename)) { method = &rename_mapping; } else { PyErr_SetString(PyExc_TypeError, "`rename` must be a str, callable, or mapping"); return -1; } PyObject *temp = method(info->rename, name); if (temp == NULL) return -1; int out = 0; if (PyUnicode_Compare(name, temp) != 0) { out = PyDict_SetItem(info->renamed_fields, name, temp); } else if (PyDict_GetItem(info->renamed_fields, name) != NULL) { out = PyDict_DelItem(info->renamed_fields, name); } Py_DECREF(temp); return out; } static int structmeta_process_default(StructMetaInfo *info, PyObject *name) { PyObject *obj = PyDict_GetItem(info->namespace, name); if (structmeta_process_rename(info, name, obj) < 0) return -1; if (obj == NULL) { return PyDict_SetItem(info->defaults_lk, name, NODEFAULT); } PyObject* default_val = NULL; PyTypeObject *type = Py_TYPE(obj); if (type == &Field_Type) { Field *f = (Field *)obj; /* Extract default or default_factory */ if (f->default_value != NODEFAULT) { obj = f->default_value; type = Py_TYPE(obj); } else if (f->default_factory != NODEFAULT) { if (f->default_factory == (PyObject *)&PyTuple_Type) { default_val = PyTuple_New(0); } else if (f->default_factory == (PyObject *)&PyFrozenSet_Type) { default_val = PyFrozenSet_New(NULL); } else { default_val = Factory_New(f->default_factory); } if (default_val == NULL) return -1; goto done; } else { default_val = NODEFAULT; Py_INCREF(default_val); goto done; } } if (type == &PyDict_Type) { if (PyDict_GET_SIZE(obj) != 0) goto error_nonempty; default_val = Factory_New((PyObject*)(&PyDict_Type)); if (default_val == NULL) return -1; } else if (type == &PyList_Type) { if (PyList_GET_SIZE(obj) != 0) goto error_nonempty; default_val = Factory_New((PyObject*)(&PyList_Type)); if (default_val == NULL) return -1; } else if (type == &PySet_Type) { if (PySet_GET_SIZE(obj) != 0) goto error_nonempty; default_val = Factory_New((PyObject*)(&PySet_Type)); if (default_val == NULL) return -1; } else if (type == &PyByteArray_Type) { if (PyByteArray_GET_SIZE(obj) != 0) goto error_nonempty; default_val = Factory_New((PyObject*)(&PyByteArray_Type)); if (default_val == NULL) return -1; } else if ( ms_is_struct_type(type) && ((StructMetaObject *)type)->frozen != OPT_TRUE ) { goto error_mutable_struct; } else { Py_INCREF(obj); default_val = obj; } done: if (dict_discard(info->namespace, name) < 0) { Py_DECREF(default_val); return -1; } int status = PyDict_SetItem(info->defaults_lk, name, default_val); Py_DECREF(default_val); return status; error_nonempty: PyErr_Format( PyExc_TypeError, "Using a non-empty mutable collection (%R) as a default value is unsafe. " "Instead configure a `default_factory` for this field.", obj ); return -1; error_mutable_struct: PyErr_Format( PyExc_TypeError, "Using a mutable struct object (%R) as a default value is unsafe. " "Either configure a `default_factory` for this field, or set " "`frozen=True` on `%.200s`", obj, type->tp_name ); return -1; } static int structmeta_is_classvar( StructMetaInfo *info, MsgspecState *mod, PyObject *ann, PyObject **module_ns ) { PyTypeObject *ann_type = Py_TYPE(ann); if (ann_type == &PyUnicode_Type) { Py_ssize_t ann_len; const char *ann_buf = unicode_str_and_size(ann, &ann_len); if (ann_len < 8) return 0; if (memcmp(ann_buf, "ClassVar", 8) == 0) { if (ann_len != 8 && ann_buf[8] != '[') return 0; if (*module_ns == NULL) { *module_ns = structmeta_get_module_ns(mod, info); } if (*module_ns == NULL) return 0; PyObject *temp = PyDict_GetItemString(*module_ns, "ClassVar"); return temp == mod->typing_classvar; } if (ann_len < 15) return 0; if (memcmp(ann_buf, "typing.ClassVar", 15) == 0) { if (ann_len != 15 && ann_buf[15] != '[') return 0; if (*module_ns == NULL) { *module_ns = structmeta_get_module_ns(mod, info); } if (*module_ns == NULL) return 0; PyObject *temp = PyDict_GetItemString(*module_ns, "typing"); if (temp == NULL) return 0; temp = PyObject_GetAttrString(temp, "ClassVar"); int status = temp == mod->typing_classvar; Py_XDECREF(temp); return status; } } else { if (ann == mod->typing_classvar) { return 1; } else if ((PyObject *)ann_type == mod->typing_generic_alias) { PyObject *temp = PyObject_GetAttr(ann, mod->str___origin__); if (temp == NULL) return -1; int status = temp == mod->typing_classvar; Py_DECREF(temp); return status; } return 0; } return 0; } static int structmeta_collect_fields(StructMetaInfo *info, MsgspecState *mod, bool kwonly) { PyObject *annotations = PyDict_GetItemString( // borrowed reference info->namespace, "__annotations__" ); if (annotations == NULL) { PyObject *annotate = ms_get_annotate_from_class_namespace(info->namespace); if (annotate == NULL) { return -1; } if (annotate == Py_None) { Py_DECREF(annotate); return 0; } /* Use Format.FORWARDREF so unresolved names do not raise NameError * while the class body is still executing. See PEP 649 / annotationlib: * https://docs.python.org/3/library/annotationlib.html#using-annotations-in-a-metaclass */ annotations = PyObject_CallOneArg(mod->call_annotate_forwardref, annotate); Py_DECREF(annotate); if (annotations == NULL) { return -1; } } else { Py_INCREF(annotations); } if (!PyDict_Check(annotations)) { Py_DECREF(annotations); PyErr_SetString(PyExc_TypeError, "__annotations__ must be a dict"); return -1; } PyObject *module_ns = NULL; PyObject *field, *value; Py_ssize_t i = 0; while (PyDict_Next(annotations, &i, &field, &value)) { if (!PyUnicode_CheckExact(field)) { PyErr_SetString( PyExc_TypeError, "__annotations__ keys must be strings" ); goto error; } PyObject *invalid_field_names[] = { mod->str___weakref__, mod->str___dict__, mod->str___msgspec_cached_hash__ }; for (int i = 0; i < 3; i++) { if (PyUnicode_Compare(field, invalid_field_names[i]) == 0) { PyErr_Format( PyExc_TypeError, "Cannot have a struct field named %R", field ); goto error; } } int status = structmeta_is_classvar(info, mod, value, &module_ns); if (status == 1) continue; if (status == -1) goto error; /* If the field is new, add it to slots */ if (PyDict_GetItem(info->defaults_lk, field) == NULL) { if (PyList_Append(info->slots, field) < 0) goto error; } if (kwonly) { if (PySet_Add(info->kwonly_fields, field) < 0) goto error; } else { if (PySet_Discard(info->kwonly_fields, field) < 0) goto error; } if (structmeta_process_default(info, field) < 0) goto error; } Py_DECREF(annotations); Py_XDECREF(module_ns); return 0; error: Py_DECREF(annotations); Py_XDECREF(module_ns); return -1; } static int structmeta_construct_fields(StructMetaInfo *info, MsgspecState *mod) { Py_ssize_t nfields = PyDict_GET_SIZE(info->defaults_lk); Py_ssize_t nkwonly = PySet_GET_SIZE(info->kwonly_fields); Py_ssize_t field_index = 0; info->fields = PyTuple_New(nfields); if (info->fields == NULL) return -1; info->defaults = PyList_New(0); /* First pass - handle all non-kwonly fields. */ PyObject *field, *default_val; Py_ssize_t pos = 0; while (PyDict_Next(info->defaults_lk, &pos, &field, &default_val)) { int kwonly = PySet_Contains(info->kwonly_fields, field); if (kwonly < 0) return -1; if (kwonly) continue; Py_INCREF(field); PyTuple_SET_ITEM(info->fields, field_index, field); if (default_val == NODEFAULT) { if (PyList_GET_SIZE(info->defaults)) { PyErr_Format( PyExc_TypeError, "Required field '%U' cannot follow optional fields. Either " "reorder the struct fields, or set `kw_only=True` in the " "struct definition.", field ); return -1; } } else { if (PyList_Append(info->defaults, default_val) < 0) return -1; } field_index++; } /* Next handle any kw_only fields */ if (nkwonly) { PyObject *field, *default_val; Py_ssize_t pos = 0; while (PyDict_Next(info->defaults_lk, &pos, &field, &default_val)) { int kwonly = PySet_Contains(info->kwonly_fields, field); if (kwonly < 0) return -1; if (!kwonly) continue; Py_INCREF(field); PyTuple_SET_ITEM(info->fields, field_index, field); if (PyList_GET_SIZE(info->defaults) || default_val != NODEFAULT) { if (PyList_Append(info->defaults, default_val) < 0) return -1; } field_index++; } } /* Convert defaults list to tuple */ PyObject *temp_defaults = PyList_AsTuple(info->defaults); Py_DECREF(info->defaults); info->defaults = temp_defaults; if (info->defaults == NULL) return -1; /* Compute n_trailing_defaults */ info->nkwonly = nkwonly; info->n_trailing_defaults = 0; for (Py_ssize_t i = PyTuple_GET_SIZE(info->defaults) - 1; i >= 0; i--) { if (PyTuple_GET_ITEM(info->defaults, i) == NODEFAULT) break; info->n_trailing_defaults++; } /* Construct __match_args__ */ info->match_args = PyTuple_GetSlice(info->fields, 0, nfields - nkwonly); if (info->match_args == NULL) return -1; /* Construct __slots__ */ if (info->weakref == OPT_TRUE && !info->already_has_weakref) { if (PyList_Append(info->slots, mod->str___weakref__) < 0) return -1; } else if (info->weakref == OPT_FALSE && info->already_has_weakref) { PyErr_SetString( PyExc_ValueError, "Cannot set `weakref=False` if base class already has `weakref=True`" ); return -1; } if (info->dict == OPT_TRUE && !info->already_has_dict) { if (PyList_Append(info->slots, mod->str___dict__) < 0) return -1; } else if (info->dict == OPT_FALSE && info->already_has_dict) { PyErr_SetString( PyExc_ValueError, "Cannot set `dict=False` if base class already has `dict=True`" ); return -1; } if (info->cache_hash == OPT_TRUE && !info->hash_offset) { if (PyList_Append(info->slots, mod->str___msgspec_cached_hash__) < 0) return -1; } else if (info->cache_hash == OPT_FALSE && info->hash_offset) { PyErr_SetString( PyExc_ValueError, "Cannot set `cache_hash=False` if base class already has `cache_hash=True`" ); return -1; } if (PyList_Sort(info->slots) < 0) return -1; PyObject *slots = PyList_AsTuple(info->slots); if (slots == NULL) return -1; int out = PyDict_SetItemString(info->namespace, "__slots__", slots); Py_DECREF(slots); return out; } static int json_str_requires_escaping(PyObject *); static int structmeta_construct_encode_fields(StructMetaInfo *info) { if (PyDict_GET_SIZE(info->renamed_fields) == 0) { /* Nothing to do, use original field tuple */ Py_INCREF(info->fields); info->encode_fields = info->fields; return 0; } info->encode_fields = PyTuple_New(PyTuple_GET_SIZE(info->fields)); if (info->encode_fields == NULL) return -1; for (Py_ssize_t i = 0; i < PyTuple_GET_SIZE(info->fields); i++) { PyObject *name = PyTuple_GET_ITEM(info->fields, i); PyObject *temp = PyDict_GetItem(info->renamed_fields, name); if (temp == NULL) { temp = name; } Py_INCREF(temp); PyTuple_SET_ITEM(info->encode_fields, i, temp); } /* Ensure that renamed fields don't collide */ PyObject *fields_set = PySet_New(info->encode_fields); if (fields_set == NULL) return -1; bool unique = PySet_GET_SIZE(fields_set) == PyTuple_GET_SIZE(info->encode_fields); Py_DECREF(fields_set); if (!unique) { PyErr_SetString( PyExc_ValueError, "Multiple fields rename to the same name, field names " "must be unique" ); return -1; } /* Ensure all renamed fields contain characters that don't require quoting * in JSON. This isn't strictly required, but usage of such characters is * extremely unlikely, and forbidding this allows us to optimize encoding */ for (Py_ssize_t i = 0; i < PyTuple_GET_SIZE(info->encode_fields); i++) { PyObject *field = PyTuple_GET_ITEM(info->encode_fields, i); Py_ssize_t status = json_str_requires_escaping(field); if (status == -1) return -1; if (status == 1) { PyErr_Format( PyExc_ValueError, "Renamed field names must not contain '\\', '\"', or control characters " "('\\u0000' to '\\u001F') - '%U' is invalid", field ); return -1; } } return 0; } /* Extracts the qualname for a class, and strips off any leading bits from a * function namespace. Examples: * * - `Foo` -> `Foo` * - `Foo.Bar` -> `Foo.Bar` * - `fizz..Foo.Bar` -> `Foo.Bar` * * This means that (nested) classes dynamically defined within functions should * work the same as (nested) classes defined at the top level. */ static PyObject *simple_qualname(PyObject *cls) { PyObject *qualname = NULL, *dotlocalsdot = NULL, *rsplits = NULL, *out = NULL; qualname = PyObject_GetAttrString(cls, "__qualname__"); if (qualname == NULL) goto cleanup; dotlocalsdot = PyUnicode_FromString(".."); if (dotlocalsdot == NULL) goto cleanup; rsplits = PyUnicode_RSplit(qualname, dotlocalsdot, 1); if (rsplits == NULL) goto cleanup; Py_ssize_t end = PyList_GET_SIZE(rsplits) - 1; out = PyList_GET_ITEM(rsplits, end); Py_INCREF(out); cleanup: Py_XDECREF(qualname); Py_XDECREF(dotlocalsdot); Py_XDECREF(rsplits); return out; } static int structmeta_construct_tag(StructMetaInfo *info, MsgspecState *mod, PyObject *cls) { if (info->temp_tag == Py_False) return 0; if (info->temp_tag == NULL && info->temp_tag_field == NULL) return 0; Py_XINCREF(info->temp_tag); info->tag = info->temp_tag; /* Determine the tag value */ if (info->temp_tag == NULL || info->temp_tag == Py_True) { info->tag_value = simple_qualname(cls); if (info->tag_value == NULL) return -1; } else { if (PyCallable_Check(info->temp_tag)) { PyObject *qualname = simple_qualname(cls); if (qualname == NULL) return -1; info->tag_value = PyObject_CallOneArg(info->temp_tag, qualname); Py_DECREF(qualname); if (info->tag_value == NULL) return -1; } else { Py_INCREF(info->temp_tag); info->tag_value = info->temp_tag; } if (PyLong_CheckExact(info->tag_value)) { int64_t val = PyLong_AsLongLong(info->tag_value); if (val == -1 && PyErr_Occurred()) { PyErr_SetString( PyExc_ValueError, "Integer `tag` values must be within [-2**63, 2**63 - 1]" ); return -1; } } else if (!PyUnicode_CheckExact(info->tag_value)) { PyErr_SetString(PyExc_TypeError, "`tag` must be a `str` or an `int`"); return -1; } } /* Next determine the tag_field to use. */ if (info->temp_tag_field == NULL) { info->tag_field = mod->str_type; Py_INCREF(info->tag_field); } else if (PyUnicode_CheckExact(info->temp_tag_field)) { info->tag_field = info->temp_tag_field; Py_INCREF(info->tag_field); } else { PyErr_SetString(PyExc_TypeError, "`tag_field` must be a `str`"); return -1; } int contains = PySequence_Contains(info->encode_fields, info->tag_field); if (contains < 0) return -1; if (contains) { PyErr_Format( PyExc_ValueError, "`tag_field='%U' conflicts with an existing field of that name", info->tag_field ); return -1; } return 0; } static int structmeta_construct_offsets( StructMetaInfo *info, MsgspecState *mod, StructMetaObject *cls ) { PyMemberDef *mp = MS_PyHeapType_GET_MEMBERS(cls); for (Py_ssize_t i = 0; i < Py_SIZE(cls); i++, mp++) { PyObject *offset = PyLong_FromSsize_t(mp->offset); if (offset == NULL) return -1; bool errored = PyDict_SetItemString(info->offsets_lk, mp->name, offset) < 0; Py_DECREF(offset); if (errored) return -1; } info->offsets = PyMem_New(Py_ssize_t, PyTuple_GET_SIZE(info->fields)); if (info->offsets == NULL) { PyErr_NoMemory(); return -1; } for (Py_ssize_t i = 0; i < PyTuple_GET_SIZE(info->fields); i++) { PyObject *field = PyTuple_GET_ITEM(info->fields, i); PyObject *offset = PyDict_GetItem(info->offsets_lk, field); if (offset == NULL) { PyErr_Format(PyExc_RuntimeError, "Failed to get offset for %R", field); return -1; } info->offsets[i] = PyLong_AsSsize_t(offset); } if (info->cache_hash == OPT_TRUE && info->hash_offset == 0) { PyObject *offset = PyDict_GetItem( info->offsets_lk, mod->str___msgspec_cached_hash__ ); if (offset == NULL) { PyErr_Format( PyExc_RuntimeError, "Failed to get offset for %R", mod->str___msgspec_cached_hash__ ); return -1; } info->hash_offset = PyLong_AsSsize_t(offset); } return 0; } static PyObject * StructMeta_new_inner( PyTypeObject *type, PyObject *name, PyObject *bases, PyObject *namespace, PyObject *arg_tag_field, PyObject *arg_tag, PyObject *arg_rename, int arg_omit_defaults, int arg_forbid_unknown_fields, int arg_frozen, int arg_eq, int arg_order, bool arg_kw_only, int arg_repr_omit_defaults, int arg_array_like, int arg_gc, int arg_weakref, int arg_dict, int arg_cache_hash ) { StructMetaObject *cls = NULL; MsgspecState *mod = msgspec_get_global_state(); bool ok = false; if (structmeta_check_namespace(namespace) < 0) return NULL; StructMetaInfo info = { .defaults_lk = NULL, .offsets_lk = NULL, .kwonly_fields = NULL, .slots = NULL, .namespace = NULL, .renamed_fields = NULL, .fields = NULL, .encode_fields = NULL, .defaults = NULL, .match_args = NULL, .tag = NULL, .tag_field = NULL, .tag_value = NULL, .offsets = NULL, .nkwonly = 0, .n_trailing_defaults = 0, .name = name, .temp_tag_field = NULL, .temp_tag = NULL, .rename = NULL, .omit_defaults = -1, .forbid_unknown_fields = -1, .frozen = -1, .eq = -1, .order = -1, .repr_omit_defaults = -1, .array_like = -1, .gc = -1, .weakref = arg_weakref, .already_has_weakref = false, .dict = arg_dict, .already_has_dict = false, .cache_hash = arg_cache_hash, .hash_offset = 0, .has_non_slots_bases = false, }; info.defaults_lk = PyDict_New(); if (info.defaults_lk == NULL) goto cleanup; info.offsets_lk = PyDict_New(); if (info.offsets_lk == NULL) goto cleanup; info.kwonly_fields = PySet_New(NULL); if (info.kwonly_fields == NULL) goto cleanup; info.namespace = PyDict_Copy(namespace); if (info.namespace == NULL) goto cleanup; info.renamed_fields = PyDict_New(); if (info.renamed_fields == NULL) goto cleanup; info.slots = PyList_New(0); if (info.slots == NULL) goto cleanup; /* Extract info from base classes in reverse MRO order */ for (Py_ssize_t i = PyTuple_GET_SIZE(bases) - 1; i >= 0; i--) { PyObject *base = PyTuple_GET_ITEM(bases, i); if (structmeta_collect_base(&info, mod, base) < 0) goto cleanup; } /* Process configuration options */ if (arg_tag != NULL && arg_tag != Py_None) { info.temp_tag = arg_tag; } if (arg_tag_field != NULL && arg_tag_field != Py_None) { info.temp_tag_field = arg_tag_field; } if (arg_rename != NULL) { info.rename = arg_rename == Py_None ? NULL : arg_rename; } info.frozen = STRUCT_MERGE_OPTIONS(info.frozen, arg_frozen); info.eq = STRUCT_MERGE_OPTIONS(info.eq, arg_eq); info.order = STRUCT_MERGE_OPTIONS(info.order, arg_order); info.repr_omit_defaults = STRUCT_MERGE_OPTIONS(info.repr_omit_defaults, arg_repr_omit_defaults); info.array_like = STRUCT_MERGE_OPTIONS(info.array_like, arg_array_like); info.gc = STRUCT_MERGE_OPTIONS(info.gc, arg_gc); info.omit_defaults = STRUCT_MERGE_OPTIONS(info.omit_defaults, arg_omit_defaults); info.forbid_unknown_fields = STRUCT_MERGE_OPTIONS(info.forbid_unknown_fields, arg_forbid_unknown_fields); if (info.eq == OPT_FALSE && info.order == OPT_TRUE) { PyErr_SetString(PyExc_ValueError, "Cannot set eq=False and order=True"); goto cleanup; } if (info.cache_hash == OPT_TRUE && info.frozen != OPT_TRUE) { PyErr_SetString(PyExc_ValueError, "Cannot set cache_hash=True without frozen=True"); goto cleanup; } if (info.gc == OPT_FALSE) { if (info.has_non_slots_bases) { PyErr_SetString( PyExc_ValueError, "Cannot set gc=False when inheriting from non-struct types with a __dict__" ); goto cleanup; } else if (info.dict == OPT_TRUE || info.already_has_dict) { PyErr_SetString(PyExc_ValueError, "Cannot set gc=False and dict=True"); goto cleanup; } else if (info.weakref == OPT_TRUE || info.already_has_weakref) { PyErr_SetString( PyExc_ValueError, "Cannot set gc=False and weakref=True at the same time, due to " "possible memory corruption" ); goto cleanup; } } /* Collect new fields and defaults */ if (structmeta_collect_fields(&info, mod, arg_kw_only) < 0) goto cleanup; /* Construct fields and defaults */ if (structmeta_construct_fields(&info, mod) < 0) goto cleanup; /* Construct encode_fields */ if (structmeta_construct_encode_fields(&info) < 0) goto cleanup; /* Construct type */ PyObject *args = Py_BuildValue("(OOO)", name, bases, info.namespace); if (args == NULL) goto cleanup; cls = (StructMetaObject *) PyType_Type.tp_new(type, args, NULL); Py_CLEAR(args); if (cls == NULL) goto cleanup; /* If the metaclass participates in abc.ABCMeta, initialise ABC * bookkeeping so issubclass/isinstance work correctly when the * metaclass is mixed with StructMeta. */ if (mod != NULL && mod->ABCMetaType != NULL && mod->_abc_init != NULL) { int is_abc_meta = PyType_IsSubtype(type, mod->ABCMetaType); if (is_abc_meta < 0) goto cleanup; if (is_abc_meta) { PyObject *res = PyObject_CallOneArg(mod->_abc_init, (PyObject *)cls); if (res == NULL) goto cleanup; Py_DECREF(res); } } /* Fill in type methods */ ((PyTypeObject *)cls)->tp_vectorcall = (vectorcallfunc)Struct_vectorcall; if (info.gc == OPT_FALSE) { ((PyTypeObject *)cls)->tp_flags &= ~Py_TPFLAGS_HAVE_GC; ((PyTypeObject *)cls)->tp_dealloc = &Struct_dealloc_nogc; ((PyTypeObject *)cls)->tp_free = &PyObject_Free; } else { ((PyTypeObject *)cls)->tp_flags |= Py_TPFLAGS_HAVE_GC; ((PyTypeObject *)cls)->tp_free = &PyObject_GC_Del; } if (info.frozen == OPT_TRUE) { /* Frozen structs always override __setattr__ */ ((PyTypeObject *)cls)->tp_setattro = &Struct_setattro_frozen; } else if ( ((PyTypeObject *)cls)->tp_setattro == Struct_setattro_frozen || ((PyTypeObject *)cls)->tp_setattro == PyObject_GenericSetAttr ) { /* Only set non-frozen __setattr__ if it hasn't been defined by the * user. All structs will inherit `Struct_setattro_default` from the * base Struct class, so proper use of `super()` should still result in * this being called. */ ((PyTypeObject *)cls)->tp_setattro = &Struct_setattro_default; } /* Construct tag, tag_field, & tag_value */ if (structmeta_construct_tag(&info, mod, (PyObject *)cls) < 0) goto cleanup; /* Fill in struct offsets */ if (structmeta_construct_offsets(&info, mod, cls) < 0) goto cleanup; /* Cache access to __post_init__ (if defined). */ cls->post_init = PyObject_GetAttr((PyObject *)cls, mod->str___post_init__); if (cls->post_init == NULL) { PyErr_Clear(); } cls->nkwonly = info.nkwonly; cls->n_trailing_defaults = info.n_trailing_defaults; cls->struct_offsets = info.offsets; Py_INCREF(info.fields); cls->struct_fields = info.fields; Py_INCREF(info.defaults); cls->struct_defaults = info.defaults; Py_INCREF(info.encode_fields); cls->struct_encode_fields = info.encode_fields; Py_INCREF(info.match_args); cls->match_args = info.match_args; Py_XINCREF(info.tag); cls->struct_tag = info.tag; Py_XINCREF(info.tag_field); cls->struct_tag_field = info.tag_field; Py_XINCREF(info.tag_value); cls->struct_tag_value = info.tag_value; Py_XINCREF(info.rename); cls->rename = info.rename; cls->hash_offset = info.hash_offset; cls->frozen = info.frozen; cls->eq = info.eq; cls->order = info.order; cls->repr_omit_defaults = info.repr_omit_defaults; cls->array_like = info.array_like; cls->gc = info.gc; cls->omit_defaults = info.omit_defaults; cls->forbid_unknown_fields = info.forbid_unknown_fields; ok = true; cleanup: /* Temporary structures */ Py_XDECREF(info.defaults_lk); Py_XDECREF(info.offsets_lk); Py_XDECREF(info.kwonly_fields); Py_XDECREF(info.slots); Py_XDECREF(info.namespace); Py_XDECREF(info.renamed_fields); /* Constructed outputs */ Py_XDECREF(info.fields); Py_XDECREF(info.encode_fields); Py_XDECREF(info.defaults); Py_XDECREF(info.match_args); Py_XDECREF(info.tag); Py_XDECREF(info.tag_field); Py_XDECREF(info.tag_value); if (!ok) { if (info.offsets != NULL) { PyMem_Free(info.offsets); } Py_XDECREF(cls); return NULL; } return (PyObject *) cls; } static PyObject * StructMeta_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) { PyObject *name = NULL, *bases = NULL, *namespace = NULL; PyObject *arg_tag_field = NULL, *arg_tag = NULL, *arg_rename = NULL; int arg_omit_defaults = -1, arg_forbid_unknown_fields = -1; int arg_frozen = -1, arg_eq = -1, arg_order = -1, arg_repr_omit_defaults = -1; int arg_array_like = -1, arg_gc = -1, arg_weakref = -1, arg_dict = -1; int arg_kw_only = 0, arg_cache_hash = -1; char *kwlist[] = { "name", "bases", "dict", "tag_field", "tag", "rename", "omit_defaults", "forbid_unknown_fields", "frozen", "eq", "order", "kw_only", "repr_omit_defaults", "array_like", "gc", "weakref", "dict", "cache_hash", NULL }; /* Parse arguments: (name, bases, dict) */ if (!PyArg_ParseTupleAndKeywords( args, kwargs, "UO!O!|$OOOpppppppppppp:StructMeta.__new__", kwlist, &name, &PyTuple_Type, &bases, &PyDict_Type, &namespace, &arg_tag_field, &arg_tag, &arg_rename, &arg_omit_defaults, &arg_forbid_unknown_fields, &arg_frozen, &arg_eq, &arg_order, &arg_kw_only, &arg_repr_omit_defaults, &arg_array_like, &arg_gc, &arg_weakref, &arg_dict, &arg_cache_hash ) ) return NULL; return StructMeta_new_inner( type, name, bases, namespace, arg_tag_field, arg_tag, arg_rename, arg_omit_defaults, arg_forbid_unknown_fields, arg_frozen, arg_eq, arg_order, arg_kw_only, arg_repr_omit_defaults, arg_array_like, arg_gc, arg_weakref, arg_dict, arg_cache_hash ); } PyDoc_STRVAR(msgspec_defstruct__doc__, "defstruct(name, fields, *, bases=None, module=None, namespace=None, " "tag_field=None, tag=None, rename=None, omit_defaults=False, " "forbid_unknown_fields=False, frozen=False, eq=True, order=False, " "kw_only=False, repr_omit_defaults=False, array_like=False, gc=True, " "weakref=False, dict=False, cache_hash=False)\n" "--\n" "\n" "Dynamically define a new Struct class.\n" "\n" "Parameters\n" "----------\n" "name : str\n" " The name of the new Struct class.\n" "fields : iterable\n" " An iterable of fields in the new class. Elements may be either ``name``,\n" " tuples of ``(name, type)``, ``(name, type, default)``, or \n" " ``(name, type, msgspec.field)``. Fields without a specified type will \n" " default to ``typing.Any``.\n" "bases : tuple, optional\n" " A tuple of any Struct base classes to use when defining the new class.\n" "module : str, optional\n" " The module name to use for the new class. If not provided, will be inferred\n" " from the caller's stack frame.\n" "namespace : dict, optional\n" " If provided, will be used as the base namespace for the new class. This may\n" " be used to add additional methods to the class definition.\n" "**kwargs :\n" " Additional Struct configuration options. See the ``Struct`` docs for more\n" " information.\n" "\n" "Examples\n" "--------\n" ">>> from msgspec import defstruct, field\n" ">>> User = defstruct(\n" "... 'User',\n" "... [\n" "... ('name', str),\n" "... ('email', str | None, None),\n" "... ('groups', set[str], field(default_factory=set)),\n" "... ],\n" "... )\n" ">>> User('alice')\n" "User(name='alice', email=None, groups=set())\n" "\n" "See Also\n" "--------\n" "Struct" ); static PyObject * msgspec_defstruct(PyObject *self, PyObject *args, PyObject *kwargs) { PyObject *name = NULL, *fields = NULL, *bases = NULL, *module = NULL, *namespace = NULL; PyObject *arg_tag_field = NULL, *arg_tag = NULL, *arg_rename = NULL; PyObject *new_bases = NULL, *annotations = NULL, *fields_fast = NULL, *out = NULL; int arg_omit_defaults = -1, arg_forbid_unknown_fields = -1; int arg_frozen = -1, arg_eq = -1, arg_order = -1, arg_kw_only = 0; int arg_repr_omit_defaults = -1, arg_array_like = -1; int arg_gc = -1, arg_weakref = -1, arg_dict = -1, arg_cache_hash = -1; char *kwlist[] = { "name", "fields", "bases", "module", "namespace", "tag_field", "tag", "rename", "omit_defaults", "forbid_unknown_fields", "frozen", "eq", "order", "kw_only", "repr_omit_defaults", "array_like", "gc", "weakref", "dict", "cache_hash", NULL }; /* Parse arguments: (name, bases, dict) */ if (!PyArg_ParseTupleAndKeywords( args, kwargs, "UO|$OOOOOOpppppppppppp:defstruct", kwlist, &name, &fields, &bases, &module, &namespace, &arg_tag_field, &arg_tag, &arg_rename, &arg_omit_defaults, &arg_forbid_unknown_fields, &arg_frozen, &arg_eq, &arg_order, &arg_kw_only, &arg_repr_omit_defaults, &arg_array_like, &arg_gc, &arg_weakref, &arg_dict, &arg_cache_hash) ) return NULL; MsgspecState *mod = msgspec_get_state(self); /* Handle namespace */ if (namespace == NULL || namespace == Py_None) { namespace = PyDict_New(); } else { if (!PyDict_Check(namespace)) { PyErr_SetString(PyExc_TypeError, "namespace must be a dict or None"); return NULL; } namespace = PyDict_Copy(namespace); } if (namespace == NULL) return NULL; /* Handle module */ if (module != NULL && module != Py_None) { if (!PyUnicode_CheckExact(module)) { PyErr_SetString(PyExc_TypeError, "module must be a str or None"); goto cleanup; } if (PyDict_SetItemString(namespace, "__module__", module) < 0) goto cleanup; } /* Handle bases */ if (bases == NULL || bases == Py_None) { new_bases = PyTuple_New(1); if (new_bases == NULL) goto cleanup; Py_INCREF(mod->StructType); PyTuple_SET_ITEM(new_bases, 0, mod->StructType); bases = new_bases; } else if (!PyTuple_CheckExact(bases)) { PyErr_SetString(PyExc_TypeError, "bases must be a tuple or None"); goto cleanup; } annotations = PyDict_New(); if (annotations == NULL) goto cleanup; fields_fast = PySequence_Fast(fields, "`fields` must be an iterable"); if (fields_fast == NULL) goto cleanup; Py_ssize_t nfields = PySequence_Fast_GET_SIZE(fields_fast); for (Py_ssize_t i = 0; i < nfields; i++) { PyObject *name = NULL, *type = NULL, *default_val = NULL; PyObject *field = PySequence_Fast_GET_ITEM(fields_fast, i); if (PyUnicode_Check(field)) { name = field; type = mod->typing_any; } else if (PyTuple_Check(field)) { Py_ssize_t len = PyTuple_GET_SIZE(field); if (len == 2) { name = PyTuple_GET_ITEM(field, 0); type = PyTuple_GET_ITEM(field, 1); } else if (len == 3) { name = PyTuple_GET_ITEM(field, 0); type = PyTuple_GET_ITEM(field, 1); default_val = PyTuple_GET_ITEM(field, 2); } } if (name == NULL || !PyUnicode_Check(name)) { PyErr_SetString( PyExc_TypeError, "items in `fields` must be one of `str`, `tuple[str, type]`, or `tuple[str, type, Any]`" ); goto cleanup; } if (PyDict_SetItem(annotations, name, type) < 0) goto cleanup; if (default_val != NULL) { if (PyDict_SetItem(namespace, name, default_val) < 0) goto cleanup; } } if (PyDict_SetItemString(namespace, "__annotations__", annotations) < 0) goto cleanup; out = StructMeta_new_inner( &StructMetaType, name, bases, namespace, arg_tag_field, arg_tag, arg_rename, arg_omit_defaults, arg_forbid_unknown_fields, arg_frozen, arg_eq, arg_order, arg_kw_only, arg_repr_omit_defaults, arg_array_like, arg_gc, arg_weakref, arg_dict, arg_cache_hash ); cleanup: Py_XDECREF(namespace); Py_XDECREF(new_bases); Py_XDECREF(annotations); Py_XDECREF(fields_fast); return out; } static int StructInfo_traverse(StructInfo *self, visitproc visit, void *arg) { Py_VISIT(self->class); for (Py_ssize_t i = 0; i < Py_SIZE(self); i++) { int out = TypeNode_traverse(self->types[i], visit, arg); if (out != 0) return out; } return 0; } static int StructInfo_clear(StructInfo *self) { Py_CLEAR(self->class); for (Py_ssize_t i = 0; i < Py_SIZE(self); i++) { TypeNode_Free(self->types[i]); self->types[i] = NULL; } return 0; } static void StructInfo_dealloc(StructInfo *self) { PyObject_GC_UnTrack(self); StructInfo_clear(self); Py_TYPE(self)->tp_free((PyObject *)self); } static PyTypeObject StructInfo_Type = { PyVarObject_HEAD_INIT(NULL, 0) .tp_name = "msgspec._core.StructInfo", .tp_basicsize = sizeof(StructInfo), .tp_itemsize = sizeof(TypeNode *), .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, .tp_clear = (inquiry)StructInfo_clear, .tp_traverse = (traverseproc)StructInfo_traverse, .tp_dealloc = (destructor)StructInfo_dealloc, }; static PyObject * StructInfo_Convert_lock_held(PyObject *obj) { MsgspecState *mod = msgspec_get_global_state(); StructMetaObject *class; PyObject *annotations = NULL; StructInfo *info = NULL; bool cache_set = false; bool is_struct = ms_is_struct_cls(obj); /* Check for a cached StructInfo, and return if one exists */ if (MS_LIKELY(is_struct)) { class = (StructMetaObject *)obj; if (class->struct_info != NULL) { Py_INCREF(class->struct_info); return (PyObject *)(class->struct_info); } Py_INCREF(class); } else { PyObject *cached = NULL; if (get_msgspec_cache(mod, obj, &StructInfo_Type, &cached)) { return cached; } PyObject *origin = PyObject_GetAttr(obj, mod->str___origin__); if (origin == NULL) return NULL; if (!ms_is_struct_cls(origin)) { Py_DECREF(origin); PyErr_SetString( PyExc_RuntimeError, "Expected __origin__ to be a Struct type" ); return NULL; } class = (StructMetaObject *)origin; } /* At this point `class` is a StructMetaObject, and `obj` is a * StructMetaObject or Generic. `class` has already been incref'd */ /* Ensure the StructMetaObject is fully initialized */ if (MS_UNLIKELY(class->struct_fields == NULL)) { PyErr_Format( PyExc_ValueError, "Type `%R` isn't fully defined, and can't be used in any " "`Decoder`/`decode` operations. This commonly happens when " "trying to use the struct type within an `__init_subclass__` " "method. If you believe what you're trying to do should work, " "please raise an issue on GitHub.", (PyObject *)class ); goto error; } /* Extract annotations from the original type object */ annotations = PyObject_CallOneArg(mod->get_class_annotations, obj); if (annotations == NULL) goto error; /* Allocate and zero-out a new StructInfo */ Py_ssize_t nfields = PyTuple_GET_SIZE(class->struct_fields); info = PyObject_GC_NewVar(StructInfo, &StructInfo_Type, nfields); if (info == NULL) goto error; for (Py_ssize_t i = 0; i < nfields; i++) { info->types[i] = NULL; } #ifdef Py_GIL_DISABLED atomic_store(&info->initialized, 0); #endif Py_INCREF(class); info->class = class; /* Cache the new StuctInfo on the original type annotation */ if (is_struct) { Py_INCREF(info); class->struct_info = info; } else { if (PyObject_SetAttr(obj, mod->str___msgspec_cache__, (PyObject *)info) < 0) goto error; } cache_set = true; /* Process all the struct fields */ for (Py_ssize_t i = 0; i < nfields; i++) { PyObject *field = PyTuple_GET_ITEM(class->struct_fields, i); PyObject *field_type = PyDict_GetItem(annotations, field); if (field_type == NULL) goto error; TypeNode *type = TypeNode_Convert(field_type); if (type == NULL) goto error; info->types[i] = type; } Py_DECREF(class); Py_DECREF(annotations); PyObject_GC_Track(info); #ifdef Py_GIL_DISABLED atomic_store(&info->initialized, 1); #endif return (PyObject *)info; error: if (cache_set) { /* An error occurred after the cache was created and set on the object. * We need to delete the cached value. */ if (is_struct) { Py_CLEAR(class->struct_info); } else { /* Fetch and restore the original exception to avoid DelAttr * silently clearing it on rare occasions. */ PyObject *err_type, *err_value, *err_tb; PyErr_Fetch(&err_type, &err_value, &err_tb); PyObject_DelAttr(obj, mod->str___msgspec_cache__); PyErr_Restore(err_type, err_value, err_tb); } } Py_DECREF(class); Py_XDECREF(annotations); Py_XDECREF(info); return NULL; } static PyObject * StructInfo_Convert(PyObject *obj) { PyObject *res = NULL; Py_BEGIN_CRITICAL_SECTION(obj); res = StructInfo_Convert_lock_held(obj); Py_END_CRITICAL_SECTION(); return res; } static int StructMeta_traverse(StructMetaObject *self, visitproc visit, void *arg) { Py_VISIT(self->struct_fields); Py_VISIT(self->struct_defaults); Py_VISIT(self->struct_encode_fields); Py_VISIT(self->struct_tag); /* May be a function */ Py_VISIT(self->rename); /* May be a function */ Py_VISIT(self->post_init); Py_VISIT(self->struct_info); return PyType_Type.tp_traverse((PyObject *)self, visit, arg); } static int StructMeta_clear(StructMetaObject *self) { /* skip if clear already invoked */ if (self->struct_fields == NULL) return 0; Py_CLEAR(self->struct_fields); Py_CLEAR(self->struct_defaults); Py_CLEAR(self->struct_encode_fields); Py_CLEAR(self->struct_tag_field); Py_CLEAR(self->struct_tag_value); Py_CLEAR(self->struct_tag); Py_CLEAR(self->rename); Py_CLEAR(self->post_init); Py_CLEAR(self->struct_info); Py_CLEAR(self->match_args); if (self->struct_offsets != NULL) { PyMem_Free(self->struct_offsets); self->struct_offsets = NULL; } return PyType_Type.tp_clear((PyObject *)self); } static void StructMeta_dealloc(StructMetaObject *self) { /* The GC invariants require dealloc immediately untrack to avoid double * deallocation. However, PyType_Type.tp_dealloc assumes the type is * currently tracked. Hence the unfortunate untrack/retrack below. */ PyObject_GC_UnTrack(self); StructMeta_clear(self); PyObject_GC_Track(self); PyType_Type.tp_dealloc((PyObject *)self); } static PyObject* StructMeta_signature(StructMetaObject *self, void *closure) { Py_ssize_t nfields, ndefaults, npos, nkwonly, i; MsgspecState *st; PyObject *res = NULL; PyObject *inspect = NULL; PyObject *parameter_cls = NULL; PyObject *parameter_empty = NULL; PyObject *kind_positional = NULL; PyObject *kind_kw_only = NULL; PyObject *signature_cls = NULL; PyObject *annotations = NULL; PyObject *parameters = NULL; PyObject *temp_args = NULL, *temp_kwargs = NULL; PyObject *field, *kind, *default_val, *parameter, *annotation; st = msgspec_get_global_state(); nfields = PyTuple_GET_SIZE(self->struct_fields); ndefaults = PyTuple_GET_SIZE(self->struct_defaults); npos = nfields - ndefaults; nkwonly = self->nkwonly; inspect = PyImport_ImportModule("inspect"); if (inspect == NULL) goto cleanup; parameter_cls = PyObject_GetAttrString(inspect, "Parameter"); if (parameter_cls == NULL) goto cleanup; parameter_empty = PyObject_GetAttrString(parameter_cls, "empty"); if (parameter_empty == NULL) goto cleanup; kind_positional = PyObject_GetAttrString(parameter_cls, "POSITIONAL_OR_KEYWORD"); if (kind_positional == NULL) goto cleanup; kind_kw_only = PyObject_GetAttrString(parameter_cls, "KEYWORD_ONLY"); if (kind_kw_only == NULL) goto cleanup; signature_cls = PyObject_GetAttrString(inspect, "Signature"); if (signature_cls == NULL) goto cleanup; annotations = PyObject_CallOneArg(st->get_type_hints, (PyObject *)self); if (annotations == NULL) goto cleanup; parameters = PyList_New(nfields); if (parameters == NULL) return NULL; temp_args = PyTuple_New(0); if (temp_args == NULL) goto cleanup; temp_kwargs = PyDict_New(); if (temp_kwargs == NULL) goto cleanup; for (i = 0; i < nfields; i++) { field = PyTuple_GET_ITEM(self->struct_fields, i); if (i < npos) { default_val = parameter_empty; } else { default_val = PyTuple_GET_ITEM(self->struct_defaults, i - npos); if (default_val == NODEFAULT) { default_val = parameter_empty; } } if (i < (nfields - nkwonly)) { kind = kind_positional; } else { kind = kind_kw_only; } annotation = PyDict_GetItem(annotations, field); if (annotation == NULL) { annotation = parameter_empty; } if (PyDict_SetItemString(temp_kwargs, "name", field) < 0) goto cleanup; if (PyDict_SetItemString(temp_kwargs, "kind", kind) < 0) goto cleanup; if (PyDict_SetItemString(temp_kwargs, "default", default_val) < 0) goto cleanup; if (PyDict_SetItemString(temp_kwargs, "annotation", annotation) < 0) goto cleanup; parameter = PyObject_Call(parameter_cls, temp_args, temp_kwargs); if (parameter == NULL) goto cleanup; PyList_SET_ITEM(parameters, i, parameter); } res = PyObject_CallOneArg(signature_cls, parameters); cleanup: Py_XDECREF(inspect); Py_XDECREF(parameter_cls); Py_XDECREF(parameter_empty); Py_XDECREF(kind_positional); Py_XDECREF(kind_kw_only); Py_XDECREF(signature_cls); Py_XDECREF(annotations); Py_XDECREF(parameters); Py_XDECREF(temp_args); Py_XDECREF(temp_kwargs); return res; } static PyObject* StructConfig_frozen(StructConfig *self, void *closure) { if (self->st_type->frozen == OPT_TRUE) { Py_RETURN_TRUE; } else { Py_RETURN_FALSE; } } static PyObject* StructConfig_eq(StructConfig *self, void *closure) { if (self->st_type->eq == OPT_FALSE) { Py_RETURN_FALSE; } else { Py_RETURN_TRUE; } } static PyObject* StructConfig_order(StructConfig *self, void *closure) { if (self->st_type->order == OPT_TRUE) { Py_RETURN_TRUE; } else { Py_RETURN_FALSE; } } static PyObject* StructConfig_array_like(StructConfig *self, void *closure) { if (self->st_type->array_like == OPT_TRUE) { Py_RETURN_TRUE; } else { Py_RETURN_FALSE; } } static PyObject* StructConfig_gc(StructConfig *self, void *closure) { if (self->st_type->gc == OPT_FALSE) { Py_RETURN_FALSE; } else { Py_RETURN_TRUE; } } static PyObject* StructConfig_weakref(StructConfig *self, void *closure) { PyTypeObject *type = (PyTypeObject *)(self->st_type); if (type->tp_weaklistoffset) { Py_RETURN_TRUE; } Py_RETURN_FALSE; } static PyObject* StructConfig_dict(StructConfig *self, void *closure) { PyTypeObject *type = (PyTypeObject *)(self->st_type); if (type->tp_dictoffset) { Py_RETURN_TRUE; } Py_RETURN_FALSE; } static PyObject* StructConfig_cache_hash(StructConfig *self, void *closure) { StructMetaObject *type = (StructMetaObject *)(self->st_type); if (type->hash_offset != 0) { Py_RETURN_TRUE; } Py_RETURN_FALSE; } static PyObject* StructConfig_repr_omit_defaults(StructConfig *self, void *closure) { if (self->st_type->repr_omit_defaults == OPT_TRUE) { Py_RETURN_TRUE; } else { Py_RETURN_FALSE; } } static PyObject* StructConfig_omit_defaults(StructConfig *self, void *closure) { if (self->st_type->omit_defaults == OPT_TRUE) { Py_RETURN_TRUE; } else { Py_RETURN_FALSE; } } static PyObject* StructConfig_forbid_unknown_fields(StructConfig *self, void *closure) { if (self->st_type->forbid_unknown_fields == OPT_TRUE) { Py_RETURN_TRUE; } else { Py_RETURN_FALSE; } } static PyObject* StructConfig_tag_field(StructConfig *self, void *closure) { PyObject *out = self->st_type->struct_tag_field; if (out == NULL) Py_RETURN_NONE; Py_INCREF(out); return out; } static PyObject* StructConfig_tag(StructConfig *self, void *closure) { PyObject *out = self->st_type->struct_tag_value; if (out == NULL) Py_RETURN_NONE; Py_INCREF(out); return out; } static PyGetSetDef StructConfig_getset[] = { {"frozen", (getter) StructConfig_frozen, NULL, NULL, NULL}, {"eq", (getter) StructConfig_eq, NULL, NULL, NULL}, {"order", (getter) StructConfig_order, NULL, NULL, NULL}, {"repr_omit_defaults", (getter) StructConfig_repr_omit_defaults, NULL, NULL, NULL}, {"array_like", (getter) StructConfig_array_like, NULL, NULL, NULL}, {"gc", (getter) StructConfig_gc, NULL, NULL, NULL}, {"weakref", (getter) StructConfig_weakref, NULL, NULL, NULL}, {"dict", (getter) StructConfig_dict, NULL, NULL, NULL}, {"cache_hash", (getter) StructConfig_cache_hash, NULL, NULL, NULL}, {"omit_defaults", (getter) StructConfig_omit_defaults, NULL, NULL, NULL}, {"forbid_unknown_fields", (getter) StructConfig_forbid_unknown_fields, NULL, NULL, NULL}, {"tag", (getter) StructConfig_tag, NULL, NULL, NULL}, {"tag_field", (getter) StructConfig_tag_field, NULL, NULL, NULL}, {NULL}, }; static int StructConfig_traverse(StructConfig *self, visitproc visit, void *arg) { Py_VISIT(self->st_type); return 0; } static int StructConfig_clear(StructConfig *self) { Py_CLEAR(self->st_type); return 0; } static void StructConfig_dealloc(StructConfig *self) { PyObject_GC_UnTrack(self); StructConfig_clear(self); Py_TYPE(self)->tp_free((PyObject *)self); } PyDoc_STRVAR(StructConfig__doc__, "StructConfig()\n" "--\n" "\n" "Configuration settings for a given Struct type.\n" "\n" "This object is accessible through the ``__struct_config__`` field on a struct\n" "type or instance. It exposes the following attributes, matching the Struct\n" "configuration parameters of the same name. See the `Struct` docstring for\n" "details.\n" "\n" "Configuration\n" "-------------\n" "frozen: bool\n" "eq: bool\n" "order: bool\n" "array_like: bool\n" "gc: bool\n" "repr_omit_defaults: bool\n" "omit_defaults: bool\n" "forbid_unknown_fields: bool\n" "weakref: bool\n" "dict: bool\n" "cache_hash: bool\n" "tag_field: str | None\n" "tag: str | int | None" ); static PyTypeObject StructConfig_Type = { PyVarObject_HEAD_INIT(NULL, 0) .tp_name = "msgspec.structs.StructConfig", .tp_doc = StructConfig__doc__, .tp_basicsize = sizeof(StructConfig), .tp_itemsize = 0, .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, .tp_new = NULL, .tp_dealloc = (destructor) StructConfig_dealloc, .tp_clear = (inquiry) StructConfig_clear, .tp_traverse = (traverseproc) StructConfig_traverse, .tp_getset = StructConfig_getset, }; static PyObject* StructConfig_New(StructMetaObject *st_type) { StructConfig *out = (StructConfig *)StructConfig_Type.tp_alloc(&StructConfig_Type, 0); if (out == NULL) return NULL; out->st_type = st_type; Py_INCREF(st_type); return (PyObject *)out; } static PyObject* StructMeta_config(StructMetaObject *self, void *closure) { return StructConfig_New(self); } static PyMemberDef StructMeta_members[] = { {"__struct_fields__", T_OBJECT_EX, offsetof(StructMetaObject, struct_fields), READONLY, "Struct fields"}, {"__struct_defaults__", T_OBJECT_EX, offsetof(StructMetaObject, struct_defaults), READONLY, "Struct defaults"}, {"__struct_encode_fields__", T_OBJECT_EX, offsetof(StructMetaObject, struct_encode_fields), READONLY, "Struct encoded field names"}, {"__match_args__", T_OBJECT_EX, offsetof(StructMetaObject, match_args), READONLY, "Positional match args"}, {NULL}, }; static PyGetSetDef StructMeta_getset[] = { {"__signature__", (getter) StructMeta_signature, NULL, NULL, NULL}, {"__struct_config__", (getter) StructMeta_config, NULL, "Struct configuration", NULL}, {NULL}, }; PyDoc_STRVAR(StructMeta__doc__, "StructMeta(name, bases, namespace, /, **struct_config)\n" "--\n" "\n" "The metaclass for creating `Struct` types. See its documentation for the\n" "available configuration options when subclassing.\n" "\n" "StructMeta can be subclassed, and may be combined with `abc.ABCMeta` to define\n" "abstract base Structs. Other metaclass combinations are not supported; they\n" "may work by accident but are not considered part of the public API.\n" "\n" "Examples\n" "--------\n" "Here we define a metaclass that modifies the default configuration and use\n" "it to create a new `Struct` base class.\n" "\n" ">>> from msgspec import Struct, StructMeta\n" ">>> class KwOnlyStructMeta(StructMeta):\n" "... def __new__(mcls, name, bases, namespace, **struct_config):\n" "... struct_config.setdefault(\"kw_only\", True)\n" "... return super().__new__(mcls, name, bases, namespace, **struct_config)\n" "...\n" ">>> class KwOnlyStruct(Struct, metaclass=KwOnlyStructMeta): ...\n" "\n" "Any subclass of ``KwOnlyStruct`` will have ``kw_only`` set to ``True`` by\n" "default.\n" "\n" ">>> class Example(KwOnlyStruct):\n" "... a: str = ""\n" "... b: int\n" "...\n" ">>> Example(b=123)\n" "Example(a='', b=123)\n" ); static PyTypeObject StructMetaType = { PyVarObject_HEAD_INIT(NULL, 0) .tp_name = "msgspec._core.StructMeta", .tp_doc = StructMeta__doc__, .tp_basicsize = sizeof(StructMetaObject), .tp_itemsize = 0, .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_TYPE_SUBCLASS | Py_TPFLAGS_HAVE_GC | _Py_TPFLAGS_HAVE_VECTORCALL | Py_TPFLAGS_BASETYPE, .tp_new = StructMeta_new, .tp_dealloc = (destructor) StructMeta_dealloc, .tp_clear = (inquiry) StructMeta_clear, .tp_traverse = (traverseproc) StructMeta_traverse, .tp_members = StructMeta_members, .tp_getset = StructMeta_getset, .tp_call = PyVectorcall_Call, .tp_vectorcall_offset = offsetof(PyTypeObject, tp_vectorcall), }; static PyObject * get_default(PyObject *obj) { PyTypeObject *type = Py_TYPE(obj); if (type == &Factory_Type) { return Factory_Call(obj); } Py_INCREF(obj); return obj; } static MS_INLINE bool is_default(PyObject *x, PyObject *d) { if (x == d) return true; if (Py_TYPE(d) == &Factory_Type) { PyTypeObject *factory = (PyTypeObject *)(((Factory *)d)->factory); if (Py_TYPE(x) != factory) return false; if (factory == &PyList_Type && PyList_GET_SIZE(x) == 0) return true; if (factory == &PyDict_Type && PyDict_GET_SIZE(x) == 0) return true; if (factory == &PySet_Type && PySet_GET_SIZE(x) == 0) return true; } return false; } /* Set field #index on obj. Steals a reference to val */ static inline void Struct_set_index(PyObject *obj, Py_ssize_t index, PyObject *val) { StructMetaObject *cls; char *addr; PyObject *old; cls = (StructMetaObject *)Py_TYPE(obj); addr = (char *)obj + cls->struct_offsets[index]; old = *(PyObject **)addr; Py_XDECREF(old); *(PyObject **)addr = val; } /* Get field #index or NULL on obj. Returns a borrowed reference */ static inline PyObject* Struct_get_index_noerror(PyObject *obj, Py_ssize_t index) { StructMetaObject *cls = (StructMetaObject *)Py_TYPE(obj); char *addr = (char *)obj + cls->struct_offsets[index]; return *(PyObject **)addr; } /* Get field #index on obj. Returns a borrowed reference */ static inline PyObject* Struct_get_index(PyObject *obj, Py_ssize_t index) { PyObject *val = Struct_get_index_noerror(obj, index); if (val == NULL) { StructMetaObject *cls = (StructMetaObject *)Py_TYPE(obj); PyErr_Format(PyExc_AttributeError, "Struct field %R is unset", PyTuple_GET_ITEM(cls->struct_fields, index)); } return val; } static MS_INLINE int Struct_post_init(StructMetaObject *st_type, PyObject *obj) { if (st_type->post_init != NULL) { PyObject *res = PyObject_CallOneArg(st_type->post_init, obj); if (res == NULL) return -1; Py_DECREF(res); } return 0; } static MS_INLINE int Struct_decode_post_init(StructMetaObject *st_type, PyObject *obj, PathNode *path) { if (MS_UNLIKELY(Struct_post_init(st_type, obj) < 0)) { ms_maybe_wrap_validation_error(path); return -1; } return 0; } static int Struct_fill_in_defaults(StructMetaObject *st_type, PyObject *obj, PathNode *path) { Py_ssize_t nfields, ndefaults, i; bool is_gc, should_untrack; nfields = PyTuple_GET_SIZE(st_type->struct_encode_fields); ndefaults = PyTuple_GET_SIZE(st_type->struct_defaults); is_gc = MS_TYPE_IS_GC(st_type); should_untrack = is_gc; for (i = 0; i < nfields; i++) { PyObject *val = Struct_get_index_noerror(obj, i); if (val == NULL) { if (MS_UNLIKELY(i < (nfields - ndefaults))) goto missing_required; val = PyTuple_GET_ITEM( st_type->struct_defaults, i - (nfields - ndefaults) ); if (MS_UNLIKELY(val == NODEFAULT)) goto missing_required; val = get_default(val); if (MS_UNLIKELY(val == NULL)) return -1; Struct_set_index(obj, i, val); } if (should_untrack) { should_untrack = !MS_MAYBE_TRACKED(val); } } if (is_gc && should_untrack && MS_IS_TRACKED(obj)) PyObject_GC_UnTrack(obj); if (Struct_decode_post_init(st_type, obj, path) < 0) return -1; return 0; missing_required: ms_missing_required_field( PyTuple_GET_ITEM(st_type->struct_encode_fields, i), path ); return -1; } static MS_NOINLINE void Struct_build_abstract_error(PyTypeObject *cls) { /* This function is adapted from CPython's object machinery. * https://github.com/python/cpython/blob/a486d45/Objects/typeobject.c#L7147-L7193 */ PyObject *abstract_methods = PyObject_GetAttrString((PyObject *)cls, "__abstractmethods__"); if (abstract_methods == NULL) { return; } PyObject *sorted_methods = PySequence_List(abstract_methods); Py_DECREF(abstract_methods); if (sorted_methods == NULL) { return; } if (PyList_Sort(sorted_methods) < 0) { Py_DECREF(sorted_methods); return; } Py_ssize_t method_count = PyList_GET_SIZE(sorted_methods); if (method_count < 0) { Py_DECREF(sorted_methods); return; } PyObject *sep = PyUnicode_FromString("', '"); if (sep == NULL) { Py_DECREF(sorted_methods); return; } PyObject *joined = PyUnicode_Join(sep, sorted_methods); Py_DECREF(sep); Py_DECREF(sorted_methods); if (joined == NULL) { return; } PyErr_Format( PyExc_TypeError, "Can't instantiate abstract class %s without " "an implementation for abstract method%s '%U'", cls->tp_name, method_count > 1 ? "s" : "", joined ); Py_DECREF(joined); } static PyObject * Struct_vectorcall(PyTypeObject *cls, PyObject *const *args, size_t nargsf, PyObject *kwnames) { if (MS_UNLIKELY(cls->tp_flags & Py_TPFLAGS_IS_ABSTRACT)) { Struct_build_abstract_error(cls); return NULL; } Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); Py_ssize_t nkwargs = (kwnames == NULL) ? 0 : PyTuple_GET_SIZE(kwnames); StructMetaObject *st_type = (StructMetaObject *)cls; PyObject *fields = st_type->struct_fields; Py_ssize_t nfields = PyTuple_GET_SIZE(fields); PyObject *defaults = st_type->struct_defaults; Py_ssize_t ndefaults = PyTuple_GET_SIZE(defaults); Py_ssize_t nkwonly = st_type->nkwonly; Py_ssize_t npos = nfields - ndefaults; if (MS_UNLIKELY(nargs > (nfields - nkwonly))) { PyErr_SetString(PyExc_TypeError, "Extra positional arguments provided"); return NULL; } bool is_gc = MS_TYPE_IS_GC(cls); bool should_untrack = is_gc; PyObject *self = Struct_alloc(cls); if (self == NULL) return NULL; /* First, process all positional arguments */ for (Py_ssize_t i = 0; i < nargs; i++) { PyObject *val = args[i]; char *addr = (char *)self + st_type->struct_offsets[i]; Py_INCREF(val); *(PyObject **)addr = val; if (should_untrack) { should_untrack = !MS_MAYBE_TRACKED(val); } } /* Next, process all kwargs */ for (Py_ssize_t i = 0; i < nkwargs; i++) { char *addr; PyObject *val; Py_ssize_t field_index; PyObject *kwname = PyTuple_GET_ITEM(kwnames, i); /* Since keyword names are interned, first loop with pointer * comparisons only. */ for (field_index = nargs; field_index < nfields; field_index++) { PyObject *field = PyTuple_GET_ITEM(fields, field_index); if (MS_LIKELY(kwname == field)) goto kw_found; } /* Fast path failed. It's more likely that this is an invalid kwarg * than that the kwname wasn't interned. Loop from 0 this time to also * check for parameters passed both as arg and kwarg */ for (field_index = 0; field_index < nfields; field_index++) { PyObject *field = PyTuple_GET_ITEM(fields, field_index); if (MS_UNICODE_EQ(kwname, field)) { if (MS_UNLIKELY(field_index < nargs)) { PyErr_Format( PyExc_TypeError, "Argument '%U' given by name and position", kwname ); goto error; } goto kw_found; } } /* Unknown keyword */ PyErr_Format(PyExc_TypeError, "Unexpected keyword argument '%U'", kwname); goto error; kw_found: val = args[i + nargs]; addr = (char *)self + st_type->struct_offsets[field_index]; Py_INCREF(val); *(PyObject **)addr = val; if (should_untrack) { should_untrack = !MS_MAYBE_TRACKED(val); } } /* Finally, fill in missing defaults */ if (nargs + nkwargs < nfields) { for (Py_ssize_t field_index = nargs; field_index < nfields; field_index++) { char *addr = (char *)self + st_type->struct_offsets[field_index]; if (MS_LIKELY(*(PyObject **)addr == NULL)) { if (MS_LIKELY(field_index >= npos)) { PyObject *val = PyTuple_GET_ITEM(defaults, field_index - npos); if (MS_LIKELY(val != NODEFAULT)) { val = get_default(val); if (MS_UNLIKELY(val == NULL)) goto error; *(PyObject **)addr = val; if (should_untrack) { should_untrack = !MS_MAYBE_TRACKED(val); } continue; } } PyErr_Format( PyExc_TypeError, "Missing required argument '%U'", PyTuple_GET_ITEM(fields, field_index) ); goto error; } } } if (is_gc && should_untrack && MS_IS_TRACKED(self)) PyObject_GC_UnTrack(self); if (Struct_post_init(st_type, self) < 0) goto error; return self; error: Py_DECREF(self); return NULL; } static PyObject * Struct_repr(PyObject *self) { StructMetaObject *st_type = (StructMetaObject *)(Py_TYPE(self)); bool omit_defaults = st_type->repr_omit_defaults == OPT_TRUE; PyObject *fields = st_type->struct_fields; Py_ssize_t nfields = PyTuple_GET_SIZE(fields); PyObject *defaults = NULL; Py_ssize_t nunchecked = nfields; if (omit_defaults) { defaults = st_type->struct_defaults; nunchecked = nfields - PyTuple_GET_SIZE(defaults); } int recursive = Py_ReprEnter(self); if (recursive != 0) { return (recursive < 0) ? NULL : PyUnicode_FromString("..."); /* cpylint-ignore */ } strbuilder builder = {0}; bool first = true; const char *name = Py_TYPE(self)->tp_name; if (!strbuilder_extend(&builder, name, strlen(name))) goto error; if (!strbuilder_extend_literal(&builder, "(")) goto error; for (Py_ssize_t i = 0; i < nfields; i++) { PyObject *field = PyTuple_GET_ITEM(fields, i); PyObject *val = Struct_get_index(self, i); if (val == NULL) goto error; if (i >= nunchecked) { PyObject *default_val = PyTuple_GET_ITEM(defaults, i - nunchecked); if (is_default(val, default_val)) continue; } if (first) { first = false; } else { if (!strbuilder_extend_literal(&builder, ", ")) goto error; } if (!strbuilder_extend_unicode(&builder, field)) goto error; if (!strbuilder_extend_literal(&builder, "=")) goto error; PyObject *repr = PyObject_Repr(val); if (repr == NULL) goto error; bool ok = strbuilder_extend_unicode(&builder, repr); Py_DECREF(repr); if (!ok) goto error; } if (!strbuilder_extend_literal(&builder, ")")) goto error; PyObject *out = strbuilder_build(&builder); Py_ReprLeave(self); return out; error: strbuilder_reset(&builder); Py_ReprLeave(self); return NULL; } static Py_hash_t Struct_hash(PyObject *self) { PyObject *val; Py_ssize_t i, nfields; Py_uhash_t acc = MS_HASH_XXPRIME_5; StructMetaObject *st_type = (StructMetaObject *)Py_TYPE(self); if (MS_UNLIKELY(st_type->eq == OPT_FALSE)) { /* If `__eq__` isn't implemented, then the default pointer-based * `__hash__` should be used */ return PyBaseObject_Type.tp_hash(self); } if (MS_UNLIKELY(st_type->frozen != OPT_TRUE)) { /* If `__eq__` is implemented, only frozen types can be hashed */ return PyObject_HashNotImplemented(self); } if (MS_UNLIKELY(st_type->hash_offset != 0)) { PyObject *cached_hash = *(PyObject **)((char *)self + st_type->hash_offset); if (cached_hash != NULL) { /* Use the cached hash */ return PyLong_AsSsize_t(cached_hash); } } /* First hash the type by its pointer */ size_t type_id = (size_t)((void *)st_type); /* The lower bits are likely to be 0; rotate by 4 */ type_id = (type_id >> 4) | (type_id << (8 * sizeof(void *) - 4)); acc += type_id * MS_HASH_XXPRIME_2; acc = MS_HASH_XXROTATE(acc); acc *= MS_HASH_XXPRIME_1; /* Then hash all the fields */ nfields = StructMeta_GET_NFIELDS(Py_TYPE(self)); for (i = 0; i < nfields; i++) { val = Struct_get_index(self, i); if (val == NULL) return -1; Py_uhash_t item_hash = PyObject_Hash(val); if (item_hash == (Py_uhash_t)-1) return -1; acc += item_hash * MS_HASH_XXPRIME_2; acc = MS_HASH_XXROTATE(acc); acc *= MS_HASH_XXPRIME_1; } acc += (1 + nfields) ^ (MS_HASH_XXPRIME_5 ^ 3527539UL); Py_uhash_t hash = (acc == (Py_uhash_t)-1) ? 1546275796 : acc; if (MS_UNLIKELY(st_type->hash_offset != 0)) { /* Cache the hash */ char *addr = (char *)self + st_type->hash_offset; PyObject *cached_hash = PyLong_FromSsize_t(hash); if (cached_hash == NULL) return -1; *(PyObject **)addr = cached_hash; } return hash; } static PyObject * Struct_richcompare(PyObject *self, PyObject *other, int op) { if (Py_TYPE(self) != Py_TYPE(other)) { Py_RETURN_NOTIMPLEMENTED; } StructMetaObject *st_type = (StructMetaObject *)(Py_TYPE(self)); if (op == Py_EQ || op == Py_NE) { if (MS_UNLIKELY(st_type->eq == OPT_FALSE)) { Py_RETURN_NOTIMPLEMENTED; } } else if (st_type->order != OPT_TRUE) { Py_RETURN_NOTIMPLEMENTED; } if ( MS_UNLIKELY(op == Py_NE && (Py_TYPE(self)->tp_richcompare != Struct_richcompare)) ) { /* This case is hit when a subclass has manually defined `__eq__` but * not `__ne__`. In this case we want to dispatch to `__eq__` and invert * the result, rather than relying on the default `__ne__` implementation. */ PyObject *out = Py_TYPE(self)->tp_richcompare(self, other, Py_EQ); if (out != NULL && out != Py_NotImplemented) { int is_true = PyObject_IsTrue(out); Py_DECREF(out); if (is_true < 0) { out = NULL; } else { out = is_true ? Py_False : Py_True; Py_INCREF(out); } } return out; } int equal = 1; PyObject *left = NULL, *right = NULL; /* Only need to loop if self is not other` */ if (MS_LIKELY(self != other)) { Py_ssize_t nfields = StructMeta_GET_NFIELDS(st_type); for (Py_ssize_t i = 0; i < nfields; i++) { left = Struct_get_index(self, i); if (left == NULL) return NULL; right = Struct_get_index(other, i); if (right == NULL) return NULL; equal = PyObject_RichCompareBool(left, right, Py_EQ); if (equal < 0) return NULL; if (equal == 0) break; } } if (equal) { if (op == Py_EQ || op == Py_GE || op == Py_LE) { Py_RETURN_TRUE; } else if (op == Py_NE) { Py_RETURN_FALSE; } else if (left == NULL) { /* < or > on two 0-field or identical structs */ Py_RETURN_FALSE; } } else if (op == Py_EQ) { Py_RETURN_FALSE; } else if (op == Py_NE) { Py_RETURN_TRUE; } /* Need to compare final element again to determine proper result */ return PyObject_RichCompare(left, right, op); } static PyObject * Struct_copy(PyObject *self, PyObject *args) { Py_ssize_t i, nfields; PyObject *val, *res = NULL; res = Struct_alloc(Py_TYPE(self)); if (res == NULL) return NULL; nfields = StructMeta_GET_NFIELDS(Py_TYPE(self)); for (i = 0; i < nfields; i++) { val = Struct_get_index(self, i); if (val == NULL) goto error; Py_INCREF(val); Struct_set_index(res, i, val); } /* If self is tracked, then copy is tracked */ if (MS_OBJECT_IS_GC(self) && !MS_IS_TRACKED(self)) PyObject_GC_UnTrack(res); return res; error: Py_DECREF(res); return NULL; } static PyObject * Struct_replace( PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames ) { Py_ssize_t nkwargs = (kwnames == NULL) ? 0 : PyTuple_GET_SIZE(kwnames); if (!check_positional_nargs(nargs, 0, 0)) return NULL; StructMetaObject *struct_type = (StructMetaObject *)Py_TYPE(self); PyObject *fields = struct_type->struct_fields; Py_ssize_t nfields = PyTuple_GET_SIZE(fields); bool is_gc = MS_TYPE_IS_GC(struct_type); bool should_untrack = is_gc; PyObject *out = Struct_alloc((PyTypeObject *)struct_type); if (out == NULL) return NULL; for (Py_ssize_t i = 0; i < nkwargs; i++) { PyObject *val; Py_ssize_t field_index; PyObject *kwname = PyTuple_GET_ITEM(kwnames, i); /* Since keyword names are interned, first loop with pointer * comparisons only. */ for (field_index = 0; field_index < nfields; field_index++) { PyObject *field = PyTuple_GET_ITEM(fields, field_index); if (MS_LIKELY(kwname == field)) goto kw_found; } for (field_index = 0; field_index < nfields; field_index++) { PyObject *field = PyTuple_GET_ITEM(fields, field_index); if (MS_UNICODE_EQ(kwname, field)) goto kw_found; } /* Unknown keyword */ PyErr_Format( PyExc_TypeError, "`%.200s` has no field '%U'", ((PyTypeObject *)struct_type)->tp_name, kwname ); goto error; kw_found: val = args[i]; Py_INCREF(val); Struct_set_index(out, field_index, val); if (should_untrack) { should_untrack = !MS_MAYBE_TRACKED(val); } } for (Py_ssize_t i = 0; i < nfields; i++) { if (Struct_get_index_noerror(out, i) == NULL) { PyObject *val = Struct_get_index(self, i); if (val == NULL) goto error; if (should_untrack) { should_untrack = !MS_MAYBE_TRACKED(val); } Py_INCREF(val); Struct_set_index(out, i, val); } } if (Struct_post_init(struct_type, out) < 0) goto error; if (is_gc && should_untrack && MS_IS_TRACKED(out)) PyObject_GC_UnTrack(out); return out; error: Py_DECREF(out); return NULL; } static AssocList * AssocList_FromStruct(PyObject *obj) { if (Py_EnterRecursiveCall(" while serializing an object")) return NULL; bool ok = false; StructMetaObject *struct_type = (StructMetaObject *)Py_TYPE(obj); PyObject *tag_field = struct_type->struct_tag_field; PyObject *tag_value = struct_type->struct_tag_value; PyObject *fields = struct_type->struct_encode_fields; PyObject *defaults = struct_type->struct_defaults; Py_ssize_t nfields = PyTuple_GET_SIZE(fields); Py_ssize_t npos = nfields - PyTuple_GET_SIZE(defaults); bool omit_defaults = struct_type->omit_defaults == OPT_TRUE; AssocList *out = AssocList_New(nfields + (tag_value != NULL)); if (out == NULL) goto cleanup; if (tag_value != NULL) { if (AssocList_Append(out, tag_field, tag_value) < 0) goto cleanup; } for (Py_ssize_t i = 0; i < nfields; i++) { PyObject *key = PyTuple_GET_ITEM(fields, i); PyObject *val = Struct_get_index(obj, i); if (MS_UNLIKELY(val == NULL)) goto cleanup; if (MS_UNLIKELY(val == UNSET)) continue; if ( !omit_defaults || i < npos || !is_default(val, PyTuple_GET_ITEM(defaults, i - npos)) ) { if (AssocList_Append(out, key, val) < 0) goto cleanup; } } ok = true; cleanup: Py_LeaveRecursiveCall(); if (!ok) { AssocList_Free(out); } return out; } PyDoc_STRVAR(struct_replace__doc__, "replace(struct, /, **changes)\n" "--\n" "\n" "Create a new struct instance of the same type as ``struct``, replacing fields\n" "with values from ``**changes``.\n" "\n" "Parameters\n" "----------\n" "struct: Struct\n" " The original struct instance.\n" "**changes:\n" " Fields and values that should be replaced in the new struct instance.\n" "\n" "Returns\n" "-------\n" "new_struct: Struct\n" " A new struct instance of the same type as ``struct``.\n" "\n" "Examples\n" "--------\n" ">>> class Point(msgspec.Struct):\n" "... x: int\n" "... y: int\n" ">>> obj = Point(x=1, y=2)\n" ">>> msgspec.structs.replace(obj, x=3)\n" "Point(x=3, y=2)\n" "\n" "See Also\n" "--------\n" "copy.replace\n" "dataclasses.replace" ); static PyObject* struct_replace(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { if (!check_positional_nargs(nargs, 1, 1)) return NULL; PyObject *obj = args[0]; if (!ms_is_struct_inst(obj)) { PyErr_SetString(PyExc_TypeError, "`struct` must be a `msgspec.Struct`"); return NULL; } return Struct_replace(obj, args + 1, 0, kwnames); } PyDoc_STRVAR(struct_asdict__doc__, "asdict(struct, /)\n" "--\n" "\n" "Convert a struct to a dict.\n" "\n" "This is a one-to-one conversion of the struct instance, modeled after\n" "`dataclasses.asdict`. Every field is included unchanged using its raw\n" "attribute name. Struct-level settings (``rename``, ``omit_defaults``,\n" "``array_like``, ``tag``) are ignored, `msgspec.UNSET` values are kept,\n" "nested `msgspec.Struct` / `dataclasses.dataclass` / attrs fields are\n" "not recursively converted, and no value-level conversions are applied\n" "(e.g. `bytes` is not base64-encoded, `datetime.datetime` is not\n" "converted to a string). Use `msgspec.to_builtins` instead when the\n" "output is intended for serialization.\n" "\n" "Parameters\n" "----------\n" "struct: Struct\n" " The struct instance.\n" "\n" "Returns\n" "-------\n" "dict\n" "\n" "Examples\n" "--------\n" ">>> class Point(msgspec.Struct):\n" "... x: int\n" "... y: int\n" ">>> obj = Point(x=1, y=2)\n" ">>> msgspec.structs.asdict(obj)\n" "{'x': 1, 'y': 2}\n" "\n" "See Also\n" "--------\n" "msgspec.structs.astuple\n" "msgspec.to_builtins" ); static PyObject* struct_asdict(PyObject *self, PyObject *const *args, Py_ssize_t nargs) { if (!check_positional_nargs(nargs, 1, 1)) return NULL; PyObject *obj = args[0]; if (!ms_is_struct_inst(obj)) { PyErr_SetString(PyExc_TypeError, "`struct` must be a `msgspec.Struct`"); return NULL; } StructMetaObject *struct_type = (StructMetaObject *)Py_TYPE(obj); PyObject *fields = struct_type->struct_fields; Py_ssize_t nfields = PyTuple_GET_SIZE(fields); PyObject *out = PyDict_New(); if (out == NULL) return NULL; for (Py_ssize_t i = 0; i < nfields; i++) { PyObject *key = PyTuple_GET_ITEM(fields, i); PyObject *val = Struct_get_index(obj, i); if (val == NULL) goto error; if (PyDict_SetItem(out, key, val) < 0) goto error; } return out; error: Py_DECREF(out); return NULL; } PyDoc_STRVAR(struct_astuple__doc__, "astuple(struct, /)\n" "--\n" "\n" "Convert a struct to a tuple.\n" "\n" "This is a one-to-one conversion of the struct instance, modeled after\n" "`dataclasses.astuple`. Every field value is included unchanged.\n" "Struct-level settings (``rename``, ``omit_defaults``, ``array_like``,\n" "``tag``) are ignored, `msgspec.UNSET` values are kept, nested\n" "`msgspec.Struct` / `dataclasses.dataclass` / attrs fields are not\n" "recursively converted, and no value-level conversions are applied\n" "(e.g. `bytes` is not base64-encoded, `datetime.datetime` is not\n" "converted to a string). Use `msgspec.to_builtins` instead when the\n" "output is intended for serialization.\n" "\n" "Parameters\n" "----------\n" "struct: Struct\n" " The struct instance.\n" "\n" "Returns\n" "-------\n" "tuple\n" "\n" "Examples\n" "--------\n" ">>> class Point(msgspec.Struct):\n" "... x: int\n" "... y: int\n" ">>> obj = Point(x=1, y=2)\n" ">>> msgspec.structs.astuple(obj)\n" "(1, 2)\n" "\n" "See Also\n" "--------\n" "msgspec.structs.asdict\n" "msgspec.to_builtins" ); static PyObject* struct_astuple(PyObject *self, PyObject *const *args, Py_ssize_t nargs) { if (!check_positional_nargs(nargs, 1, 1)) return NULL; PyObject *obj = args[0]; if (!ms_is_struct_inst(obj)) { PyErr_SetString(PyExc_TypeError, "`struct` must be a `msgspec.Struct`"); return NULL; } StructMetaObject *struct_type = (StructMetaObject *)Py_TYPE(obj); Py_ssize_t nfields = PyTuple_GET_SIZE(struct_type->struct_fields); PyObject *out = PyTuple_New(nfields); if (out == NULL) return NULL; for (Py_ssize_t i = 0; i < nfields; i++) { PyObject *val = Struct_get_index(obj, i); if (val == NULL) goto error; Py_INCREF(val); PyTuple_SET_ITEM(out, i, val); } return out; error: Py_DECREF(out); return NULL; } PyDoc_STRVAR(struct_force_setattr__doc__, "force_setattr(struct, name, value, /)\n" "--\n" "\n" "Set an attribute on a struct, even if the struct is frozen.\n" "\n" "The main use case for this is modifying a frozen struct in a ``__post_init__``\n" "method before returning.\n" "\n" ".. warning::\n\n" " This function violates the guarantees of a frozen struct, and is potentially\n" " unsafe. Only use it if you know what you're doing!\n" "\n" "Parameters\n" "----------\n" "struct: Struct\n" " The struct instance.\n" "name: str\n" " The attribute name.\n" "value: Any\n" " The attribute value." ); static PyObject* struct_force_setattr(PyObject *self, PyObject *const *args, Py_ssize_t nargs) { if (!check_positional_nargs(nargs, 3, 3)) return NULL; PyObject *obj = args[0]; PyObject *name = args[1]; PyObject *value = args[2]; if (!ms_is_struct_inst(obj)) { PyErr_SetString(PyExc_TypeError, "`struct` must be a `msgspec.Struct`"); return NULL; } if (PyObject_GenericSetAttr(obj, name, value) < 0) { return NULL; } Py_RETURN_NONE; } static PyObject * Struct_reduce(PyObject *self, PyObject *args) { PyObject *values = NULL, *out = NULL; StructMetaObject *st_type = (StructMetaObject *)(Py_TYPE(self)); Py_ssize_t nfields = PyTuple_GET_SIZE(st_type->struct_fields); if (st_type->nkwonly) { MsgspecState *mod = msgspec_get_global_state(); values = PyDict_New(); if (values == NULL) return NULL; for (Py_ssize_t i = 0; i < nfields; i++) { PyObject *field = PyTuple_GET_ITEM(st_type->struct_fields, i); PyObject *val = Struct_get_index(self, i); if (val == NULL) goto cleanup; if (PyDict_SetItem(values, field, val) < 0) goto cleanup; } out = Py_BuildValue("O(OO)", mod->rebuild, Py_TYPE(self), values); } else { values = PyTuple_New(nfields); if (values == NULL) return NULL; for (Py_ssize_t i = 0; i < nfields; i++) { PyObject *val = Struct_get_index(self, i); if (val == NULL) goto cleanup; Py_INCREF(val); PyTuple_SET_ITEM(values, i, val); } out = PyTuple_Pack(2, Py_TYPE(self), values); } cleanup: Py_DECREF(values); return out; } static PyObject * Struct_rich_repr(PyObject *self, PyObject *args) { StructMetaObject *st_type = (StructMetaObject *)(Py_TYPE(self)); bool omit_defaults = st_type->repr_omit_defaults == OPT_TRUE; PyObject *fields = st_type->struct_fields; Py_ssize_t nfields = PyTuple_GET_SIZE(fields); PyObject *defaults = NULL; Py_ssize_t nunchecked = nfields; if (omit_defaults) { defaults = st_type->struct_defaults; nunchecked = nfields - PyTuple_GET_SIZE(defaults); } PyObject *out = PyList_New(0); if (out == NULL) return NULL; for (Py_ssize_t i = 0; i < nfields; i++) { PyObject *field = PyTuple_GET_ITEM(fields, i); PyObject *val = Struct_get_index(self, i); if (i >= nunchecked) { PyObject *default_val = PyTuple_GET_ITEM(defaults, i - nunchecked); if (is_default(val, default_val)) continue; } if (val == NULL) goto error; PyObject *part = PyTuple_Pack(2, field, val); if (part == NULL) goto error; int status = PyList_Append(out, part); Py_DECREF(part); if (status < 0) goto error; } return out; error: Py_DECREF(out); return NULL; } static PyObject * StructMixin_fields(PyObject *self, void *closure) { PyObject *out = ((StructMetaObject *)Py_TYPE(self))->struct_fields; Py_INCREF(out); return out; } static PyObject * StructMixin_encode_fields(PyObject *self, void *closure) { PyObject *out = ((StructMetaObject *)Py_TYPE(self))->struct_encode_fields; Py_INCREF(out); return out; } static PyObject * StructMixin_defaults(PyObject *self, void *closure) { PyObject *out = ((StructMetaObject *)Py_TYPE(self))->struct_defaults; Py_INCREF(out); return out; } static PyObject* StructMixin_config(StructMetaObject *self, void *closure) { return StructConfig_New((StructMetaObject *)Py_TYPE(self)); } static PyMethodDef Struct_methods[] = { {"__copy__", Struct_copy, METH_NOARGS, "copy a struct"}, {"__replace__", (PyCFunction) Struct_replace, METH_FASTCALL | METH_KEYWORDS, "create a new struct with replacements" }, {"__reduce__", Struct_reduce, METH_NOARGS, "reduce a struct"}, {"__rich_repr__", Struct_rich_repr, METH_NOARGS, "rich repr"}, {NULL, NULL}, }; static PyGetSetDef StructMixin_getset[] = { {"__struct_fields__", (getter) StructMixin_fields, NULL, "Struct fields", NULL}, {"__struct_encode_fields__", (getter) StructMixin_encode_fields, NULL, "Struct encoded field names", NULL}, {"__struct_defaults__", (getter) StructMixin_defaults, NULL, "Struct defaults", NULL}, {"__struct_config__", (getter) StructMixin_config, NULL, "Struct configuration", NULL}, {NULL}, }; static PyTypeObject StructMixinType = { PyVarObject_HEAD_INIT(NULL, 0) .tp_name = "msgspec._core._StructMixin", .tp_basicsize = 0, .tp_itemsize = 0, .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, .tp_setattro = Struct_setattro_default, .tp_repr = Struct_repr, .tp_richcompare = Struct_richcompare, .tp_hash = Struct_hash, .tp_methods = Struct_methods, .tp_getset = StructMixin_getset, }; PyDoc_STRVAR(Struct__doc__, "A base class for defining efficient serializable objects.\n" "\n" "Fields are defined using type annotations. Fields may optionally have\n" "default values, which result in keyword parameters to the constructor.\n" "\n" "Structs automatically define ``__init__``, ``__eq__``, ``__repr__``, and\n" "``__copy__`` methods. Additional methods can be defined on the class as\n" "needed. Note that ``__init__``/``__new__`` cannot be overridden, but other\n" "methods can. A tuple of the field names is available on the class via the\n" "``__struct_fields__`` attribute if needed.\n" "\n" "Additional class options can be enabled by passing keywords to the class\n" "definition (see example below). These configuration options may also be\n" "inspected at runtime through the ``__struct_config__`` attribute.\n" "\n" "Configuration\n" "-------------\n" "frozen: bool, default False\n" " Whether instances of this type are pseudo-immutable. If true, attribute\n" " assignment is disabled and a corresponding ``__hash__`` is defined.\n" "order: bool, default False\n" " If True, ``__lt__``, `__le__``, ``__gt__``, and ``__ge__`` methods\n" " will be generated for this type.\n" "eq: bool, default True\n" " If True (the default), an ``__eq__`` method will be generated for this\n" " type. Set to False to compare based on instance identity alone.\n" "kw_only: bool, default False\n" " If True, all fields will be treated as keyword-only arguments in the\n" " generated ``__init__`` method. Default is False.\n" "omit_defaults: bool, default False\n" " Whether fields should be omitted from encoding if the corresponding value\n" " is the default for that field. Enabling this may reduce message size, and\n" " often also improve encoding & decoding performance.\n" "forbid_unknown_fields: bool, default False\n" " If True, an error is raised if an unknown field is encountered while\n" " decoding structs of this type. If False (the default), no error is raised\n" " and the unknown field is skipped.\n" "tag: str, int, bool, callable, or None, default None\n" " Used along with ``tag_field`` for configuring tagged union support. If\n" " either are non-None, then the struct is considered \"tagged\". In this case,\n" " an extra field (the ``tag_field``) and value (the ``tag``) are added to the\n" " encoded message, which can be used to differentiate message types during\n" " decoding.\n" "\n" " Set ``tag=True`` to enable the default tagged configuration (``tag_field``\n" " is ``\"type\"``, ``tag`` is the class name). Alternatively, you can provide\n" " a string (or less commonly int) value directly to be used as the tag\n" " (e.g. ``tag=\"my-tag-value\"``).``tag`` can also be passed a callable that\n" " takes the class qualname and returns a valid tag value (e.g.\n" " ``tag=str.lower``). See the docs for more information.\n" "tag_field: str or None, default None\n" " The field name to use for tagged union support. If ``tag`` is non-None,\n" " then this defaults to ``\"type\"``. See the ``tag`` docs above for more\n" " information.\n" "rename: str, mapping, callable, or None, default None\n" " Controls renaming the field names used when encoding/decoding the struct.\n" " May be one of ``\"lower\"``, ``\"upper\"``, ``\"camel\"``, ``\"pascal\"``, or\n" " ``\"kebab\"`` to rename in lowercase, UPPERCASE, camelCase, PascalCase,\n" " or kebab-case respectively. May also be a mapping from field names to the\n" " renamed names (missing fields are not renamed). Alternatively, may be a\n" " callable that takes the field name and returns a new name or ``None`` to\n" " not rename that field. Default is ``None`` for no field renaming.\n" "repr_omit_defaults: bool, default False\n" " Whether fields should be omitted from the generated repr if the\n" " corresponding value is the default for that field.\n" "array_like: bool, default False\n" " If True, this struct type will be treated as an array-like type during\n" " encoding/decoding, rather than a dict-like type (the default). This may\n" " improve performance, at the cost of a more inscrutable message encoding.\n" "gc: bool, default True\n" " Whether garbage collection is enabled for this type. Disabling this *may*\n" " help reduce GC pressure, but will prevent reference cycles composed of only\n" " ``gc=False`` from being collected. It is the user's responsibility to ensure\n" " that reference cycles don't occur when setting ``gc=False``.\n" "weakref: bool, default False\n" " Whether instances of this type support weak references. Defaults to False.\n" "dict: bool, default False\n" " Whether instances of this type will include a ``__dict__``. Setting this to\n" " True will allow adding additional undeclared attributes to a struct instance,\n" " which may be useful for holding private runtime state. Defaults to False.\n" "cache_hash: bool, default False\n" " If enabled, the hash of a frozen struct instance will be computed at most\n" " once, and then cached on the instance for further reuse. For expensive\n" " hash values this can improve performance at the cost of a small amount of\n" " memory usage.\n" "\n" "Examples\n" "--------\n" "Here we define a new `Struct` type for describing a dog. It has three fields;\n" "two required and one optional.\n" "\n" ">>> class Dog(Struct):\n" "... name: str\n" "... breed: str\n" "... is_good_boy: bool = True\n" "...\n" ">>> Dog('snickers', breed='corgi')\n" "Dog(name='snickers', breed='corgi', is_good_boy=True)\n" "\n" "Additional struct options can be set as part of the class definition. Here\n" "we define a new `Struct` type for a frozen `Point` object.\n" "\n" ">>> class Point(Struct, frozen=True):\n" "... x: float\n" "... y: float\n" "...\n" ">>> {Point(1.5, 2.0): 1} # frozen structs are hashable\n" "{Point(x=1.5, y=2.0): 1}" ); static int LiteralInfo_traverse(LiteralInfo *self, visitproc visit, void *arg) { Py_VISIT(self->str_lookup); Py_VISIT(self->int_lookup); return 0; } static int LiteralInfo_clear(LiteralInfo *self) { Py_CLEAR(self->str_lookup); Py_CLEAR(self->int_lookup); return 0; } static void LiteralInfo_dealloc(LiteralInfo *self) { PyObject_GC_UnTrack(self); LiteralInfo_clear(self); Py_TYPE(self)->tp_free((PyObject *)self); } static PyTypeObject LiteralInfo_Type = { PyVarObject_HEAD_INIT(NULL, 0) .tp_name = "msgspec._core.LiteralInfo", .tp_basicsize = sizeof(LiteralInfo), .tp_itemsize = 0, .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, .tp_clear = (inquiry)LiteralInfo_clear, .tp_traverse = (traverseproc)LiteralInfo_traverse, .tp_dealloc = (destructor)LiteralInfo_dealloc, }; static PyObject * TypedDictInfo_Convert(PyObject *obj) { PyObject *annotations = NULL, *required = NULL; TypedDictInfo *info = NULL; MsgspecState *mod = msgspec_get_global_state(); bool cache_set = false, succeeded = false; PyObject *cached = NULL; if (get_msgspec_cache(mod, obj, &TypedDictInfo_Type, &cached)) { return cached; } /* Not cached, extract fields from TypedDict object */ PyObject *temp = PyObject_CallOneArg(mod->get_typeddict_info, obj); if (temp == NULL) return NULL; annotations = PyTuple_GET_ITEM(temp, 0); Py_INCREF(annotations); required = PyTuple_GET_ITEM(temp, 1); Py_INCREF(required); Py_DECREF(temp); /* Allocate and zero-out a new TypedDictInfo object */ Py_ssize_t nfields = PyDict_GET_SIZE(annotations); info = PyObject_GC_NewVar(TypedDictInfo, &TypedDictInfo_Type, nfields); if (info == NULL) goto cleanup; for (Py_ssize_t i = 0; i < nfields; i++) { info->fields[i].key = NULL; info->fields[i].type = NULL; } /* Initialize nrequired to -1 as a flag in case of a recursive TypedDict * definition. */ info->nrequired = -1; /* If not already cached, then cache on TypedDict object _before_ * traversing fields. This is to ensure self-referential TypedDicts work. */ if (PyObject_SetAttr(obj, mod->str___msgspec_cache__, (PyObject *)info) < 0) { goto cleanup; } cache_set = true; /* Traverse fields and initialize TypedDictInfo */ Py_ssize_t pos = 0, i = 0; PyObject *key, *val; while (PyDict_Next(annotations, &pos, &key, &val)) { TypeNode *type = TypeNode_Convert(val); if (type == NULL) goto cleanup; Py_INCREF(key); info->fields[i].key = key; info->fields[i].type = type; int contains = PySet_Contains(required, key); if (contains == -1) goto cleanup; if (contains) { type->types |= MS_EXTRA_FLAG; } i++; } info->nrequired = PySet_GET_SIZE(required); PyObject_GC_Track(info); succeeded = true; cleanup: if (!succeeded) { Py_CLEAR(info); if (cache_set) { /* An error occurred after the cache was created and set on the * TypedDict. We need to delete the attribute. Fetch and restore the * original exception to avoid DelAttr silently clearing it on rare * occasions. */ PyObject *err_type, *err_value, *err_tb; PyErr_Fetch(&err_type, &err_value, &err_tb); PyObject_DelAttr(obj, mod->str___msgspec_cache__); PyErr_Restore(err_type, err_value, err_tb); } } Py_XDECREF(annotations); Py_XDECREF(required); return (PyObject *)info; } static MS_INLINE PyObject * TypedDictInfo_lookup_key( TypedDictInfo *self, const char * key, Py_ssize_t key_size, TypeNode **type, Py_ssize_t *pos ) { const char *field; Py_ssize_t nfields, field_size, i, offset = *pos; nfields = Py_SIZE(self); for (i = offset; i < nfields; i++) { field = unicode_str_and_size_nocheck(self->fields[i].key, &field_size); if (key_size == field_size && memcmp(key, field, key_size) == 0) { *pos = i < (nfields - 1) ? (i + 1) : 0; *type = self->fields[i].type; return self->fields[i].key; } } for (i = 0; i < offset; i++) { field = unicode_str_and_size_nocheck(self->fields[i].key, &field_size); if (key_size == field_size && memcmp(key, field, key_size) == 0) { *pos = i + 1; *type = self->fields[i].type; return self->fields[i].key; } } return NULL; } static void TypedDictInfo_error_missing(TypedDictInfo *self, PyObject *dict, PathNode *path) { Py_ssize_t nfields = Py_SIZE(self); for (Py_ssize_t i = 0; i < nfields; i++) { if (self->fields[i].type->types & MS_EXTRA_FLAG) { PyObject *field = self->fields[i].key; int contains = PyDict_Contains(dict, field); if (contains < 0) return; if (contains == 0) { ms_missing_required_field(field, path); return; } } } // Should be unreachable, but may happen if the TypedDict info // is inconsistent. assert(0); } static int TypedDictInfo_traverse(TypedDictInfo *self, visitproc visit, void *arg) { for (Py_ssize_t i = 0; i < Py_SIZE(self); i++) { TypedDictField *field = &(self->fields[i]); if (field->key != NULL) { int out = TypeNode_traverse(field->type, visit, arg); if (out != 0) return out; } } return 0; } static int TypedDictInfo_clear(TypedDictInfo *self) { for (Py_ssize_t i = 0; i < Py_SIZE(self); i++) { Py_CLEAR(self->fields[i].key); TypeNode_Free(self->fields[i].type); self->fields[i].type = NULL; } return 0; } static void TypedDictInfo_dealloc(TypedDictInfo *self) { PyObject_GC_UnTrack(self); TypedDictInfo_clear(self); Py_TYPE(self)->tp_free((PyObject *)self); } static PyTypeObject TypedDictInfo_Type = { PyVarObject_HEAD_INIT(NULL, 0) .tp_name = "msgspec._core.TypedDictInfo", .tp_basicsize = sizeof(TypedDictInfo), .tp_itemsize = sizeof(TypedDictField), .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, .tp_clear = (inquiry)TypedDictInfo_clear, .tp_traverse = (traverseproc)TypedDictInfo_traverse, .tp_dealloc = (destructor)TypedDictInfo_dealloc, }; static PyObject * DataclassInfo_Convert(PyObject *obj) { PyObject *cls = NULL, *fields = NULL, *field_defaults = NULL; PyObject *pre_init = NULL, *post_init = NULL; DataclassInfo *info = NULL; MsgspecState *mod = msgspec_get_global_state(); bool cache_set = false, succeeded = false; PyObject *cached = NULL; if (get_msgspec_cache(mod, obj, &DataclassInfo_Type, &cached)) { return cached; } /* Not cached, extract fields from Dataclass object */ PyObject *temp = PyObject_CallOneArg(mod->get_dataclass_info, obj); if (temp == NULL) return NULL; cls = PyTuple_GET_ITEM(temp, 0); Py_INCREF(cls); fields = PyTuple_GET_ITEM(temp, 1); Py_INCREF(fields); field_defaults = PyTuple_GET_ITEM(temp, 2); Py_INCREF(field_defaults); pre_init = PyTuple_GET_ITEM(temp, 3); Py_INCREF(pre_init); post_init = PyTuple_GET_ITEM(temp, 4); Py_INCREF(post_init); Py_DECREF(temp); /* Allocate and zero-out a new DataclassInfo object */ Py_ssize_t nfields = PyTuple_GET_SIZE(fields); info = PyObject_GC_NewVar(DataclassInfo, &DataclassInfo_Type, nfields); if (info == NULL) goto cleanup; for (Py_ssize_t i = 0; i < nfields; i++) { info->fields[i].key = NULL; info->fields[i].type = NULL; } Py_INCREF(field_defaults); info->defaults = field_defaults; Py_INCREF(cls); info->class = cls; if (pre_init == Py_None) { info->pre_init = NULL; } else { Py_INCREF(pre_init); info->pre_init = pre_init; } if (post_init == Py_None) { info->post_init = NULL; } else { Py_INCREF(post_init); info->post_init = post_init; } /* If not already cached, then cache on Dataclass object _before_ * traversing fields. This is to ensure self-referential Dataclasses work. */ if (PyObject_SetAttr(obj, mod->str___msgspec_cache__, (PyObject *)info) < 0) { goto cleanup; } cache_set = true; /* Traverse fields and initialize DataclassInfo */ for (Py_ssize_t i = 0; i < nfields; i++) { PyObject *field = PyTuple_GET_ITEM(fields, i); TypeNode *type = TypeNode_Convert(PyTuple_GET_ITEM(field, 1)); if (type == NULL) goto cleanup; /* If field has a default factory, set extra flag bit */ if (PyObject_IsTrue(PyTuple_GET_ITEM(field, 2))) { type->types |= MS_EXTRA_FLAG; } info->fields[i].type = type; info->fields[i].key = PyTuple_GET_ITEM(field, 0); Py_INCREF(info->fields[i].key); } PyObject_GC_Track(info); succeeded = true; cleanup: if (!succeeded) { Py_CLEAR(info); if (cache_set) { /* An error occurred after the cache was created and set on the * Dataclass. We need to delete the attribute. Fetch and restore the * original exception to avoid DelAttr silently clearing it on rare * occasions. */ PyObject *err_type, *err_value, *err_tb; PyErr_Fetch(&err_type, &err_value, &err_tb); PyObject_DelAttr(obj, mod->str___msgspec_cache__); PyErr_Restore(err_type, err_value, err_tb); } } Py_XDECREF(cls); Py_XDECREF(fields); Py_XDECREF(field_defaults); Py_XDECREF(pre_init); Py_XDECREF(post_init); return (PyObject *)info; } static MS_INLINE PyObject * DataclassInfo_lookup_key( DataclassInfo *self, const char * key, Py_ssize_t key_size, TypeNode **type, Py_ssize_t *pos ) { const char *field; Py_ssize_t nfields, field_size, i, offset = *pos; nfields = Py_SIZE(self); for (i = offset; i < nfields; i++) { field = unicode_str_and_size_nocheck(self->fields[i].key, &field_size); if (key_size == field_size && memcmp(key, field, key_size) == 0) { *pos = i < (nfields - 1) ? (i + 1) : 0; *type = self->fields[i].type; return self->fields[i].key; } } for (i = 0; i < offset; i++) { field = unicode_str_and_size_nocheck(self->fields[i].key, &field_size); if (key_size == field_size && memcmp(key, field, key_size) == 0) { *pos = i + 1; *type = self->fields[i].type; return self->fields[i].key; } } return NULL; } static int DataclassInfo_post_decode(DataclassInfo *self, PyObject *obj, PathNode *path) { Py_ssize_t nfields = Py_SIZE(self); Py_ssize_t ndefaults = PyTuple_GET_SIZE(self->defaults); for (Py_ssize_t i = 0; i < nfields; i++) { PyObject *name = self->fields[i].key; if (!PyObject_HasAttr(obj, name)) { if (i < (nfields - ndefaults)) { ms_missing_required_field(name, path); return -1; } else { PyObject *default_value = PyTuple_GET_ITEM( self->defaults, i - (nfields - ndefaults) ); bool is_factory = self->fields[i].type->types & MS_EXTRA_FLAG; if (is_factory) { default_value = PyObject_CallNoArgs(default_value); if (default_value == NULL) return -1; } int status = PyObject_GenericSetAttr(obj, name, default_value); if (is_factory) { Py_DECREF(default_value); } if (status < 0) return -1; } } } if (self->post_init != NULL) { PyObject *res = PyObject_CallOneArg(self->post_init, obj); if (res == NULL) { ms_maybe_wrap_validation_error(path); return -1; } Py_DECREF(res); } return 0; } static int DataclassInfo_traverse(DataclassInfo *self, visitproc visit, void *arg) { for (Py_ssize_t i = 0; i < Py_SIZE(self); i++) { DataclassField *field = &(self->fields[i]); if (field->key != NULL) { int out = TypeNode_traverse(field->type, visit, arg); if (out != 0) return out; } } Py_VISIT(self->defaults); Py_VISIT(self->class); Py_VISIT(self->pre_init); Py_VISIT(self->post_init); return 0; } static int DataclassInfo_clear(DataclassInfo *self) { for (Py_ssize_t i = 0; i < Py_SIZE(self); i++) { Py_CLEAR(self->fields[i].key); TypeNode_Free(self->fields[i].type); self->fields[i].type = NULL; } Py_CLEAR(self->defaults); Py_CLEAR(self->class); Py_CLEAR(self->pre_init); Py_CLEAR(self->post_init); return 0; } static void DataclassInfo_dealloc(DataclassInfo *self) { PyObject_GC_UnTrack(self); DataclassInfo_clear(self); Py_TYPE(self)->tp_free((PyObject *)self); } static PyTypeObject DataclassInfo_Type = { PyVarObject_HEAD_INIT(NULL, 0) .tp_name = "msgspec._core.DataclassInfo", .tp_basicsize = sizeof(DataclassInfo), .tp_itemsize = sizeof(DataclassField), .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, .tp_clear = (inquiry)DataclassInfo_clear, .tp_traverse = (traverseproc)DataclassInfo_traverse, .tp_dealloc = (destructor)DataclassInfo_dealloc, }; static PyObject * NamedTupleInfo_Convert(PyObject *obj) { MsgspecState *mod = msgspec_get_global_state(); NamedTupleInfo *info = NULL; PyObject *annotations = NULL, *cls = NULL, *fields = NULL; PyObject *defaults = NULL, *defaults_list = NULL; bool cache_set = false, succeeded = false; PyObject *cached = NULL; if (get_msgspec_cache(mod, obj, &NamedTupleInfo_Type, &cached)) { return cached; } /* Not cached, extract fields from NamedTuple object */ annotations = PyObject_CallOneArg(mod->get_class_annotations, obj); if (annotations == NULL) goto cleanup; if (PyType_Check(obj)) { Py_INCREF(obj); cls = obj; } else { cls = PyObject_GetAttr(obj, mod->str___origin__); if (cls == NULL) goto cleanup; } fields = PyObject_GetAttr(cls, mod->str__fields); if (fields == NULL) goto cleanup; defaults = PyObject_GetAttr(cls, mod->str__field_defaults); if (defaults == NULL) goto cleanup; /* Allocate and zero-out a new NamedTupleInfo object */ Py_ssize_t nfields = PyTuple_GET_SIZE(fields); info = PyObject_GC_NewVar(NamedTupleInfo, &NamedTupleInfo_Type, nfields); if (info == NULL) goto cleanup; info->class = NULL; info->defaults = NULL; for (Py_ssize_t i = 0; i < nfields; i++) { info->types[i] = NULL; } /* If not already cached, then cache on NamedTuple object _before_ * traversing fields. This is to ensure self-referential NamedTuple work. */ if (PyObject_SetAttr(obj, mod->str___msgspec_cache__, (PyObject *)info) < 0) { goto cleanup; } cache_set = true; /* Traverse fields and initialize NamedTupleInfo */ defaults_list = PyList_New(0); if (defaults_list == NULL) goto cleanup; for (Py_ssize_t i = 0; i < nfields; i++) { PyObject *field = PyTuple_GET_ITEM(fields, i); /* Get the field type, defaulting to Any */ PyObject *type_obj = PyDict_GetItem(annotations, field); if (type_obj == NULL) { type_obj = mod->typing_any; } /* Convert the type to a TypeNode */ TypeNode *type = TypeNode_Convert(type_obj); if (type == NULL) goto cleanup; info->types[i] = type; /* Get the field default (if any), and append it to the list */ PyObject *default_obj = PyDict_GetItem(defaults, field); if (default_obj != NULL) { if (PyList_Append(defaults_list, default_obj) < 0) goto cleanup; } } Py_INCREF(cls); info->class = cls; info->defaults = PyList_AsTuple(defaults_list); if (info->defaults == NULL) goto cleanup; PyObject_GC_Track(info); succeeded = true; cleanup: if (!succeeded) { Py_CLEAR(info); if (cache_set) { /* An error occurred after the cache was created and set on the * NamedTuple. We need to delete the attribute. Fetch and restore * the original exception to avoid DelAttr silently clearing it * on rare occasions. */ PyObject *err_type, *err_value, *err_tb; PyErr_Fetch(&err_type, &err_value, &err_tb); PyObject_DelAttr(obj, mod->str___msgspec_cache__); PyErr_Restore(err_type, err_value, err_tb); } } Py_XDECREF(cls); Py_XDECREF(annotations); Py_XDECREF(fields); Py_XDECREF(defaults); Py_XDECREF(defaults_list); return (PyObject *)info; } static int NamedTupleInfo_traverse(NamedTupleInfo *self, visitproc visit, void *arg) { Py_VISIT(self->class); Py_VISIT(self->defaults); for (Py_ssize_t i = 0; i < Py_SIZE(self); i++) { int out = TypeNode_traverse(self->types[i], visit, arg); if (out != 0) return out; } return 0; } static int NamedTupleInfo_clear(NamedTupleInfo *self) { Py_CLEAR(self->class); Py_CLEAR(self->defaults); for (Py_ssize_t i = 0; i < Py_SIZE(self); i++) { TypeNode_Free(self->types[i]); self->types[i] = NULL; } return 0; } static void NamedTupleInfo_dealloc(NamedTupleInfo *self) { PyObject_GC_UnTrack(self); NamedTupleInfo_clear(self); Py_TYPE(self)->tp_free((PyObject *)self); } static PyTypeObject NamedTupleInfo_Type = { PyVarObject_HEAD_INIT(NULL, 0) .tp_name = "msgspec._core.NamedTupleInfo", .tp_basicsize = sizeof(NamedTupleInfo), .tp_itemsize = sizeof(TypeNode *), .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, .tp_clear = (inquiry)NamedTupleInfo_clear, .tp_traverse = (traverseproc)NamedTupleInfo_traverse, .tp_dealloc = (destructor)NamedTupleInfo_dealloc, }; /************************************************************************* * Ext * *************************************************************************/ typedef struct Ext { PyObject_HEAD long code; PyObject *data; } Ext; static PyObject * Ext_New(long code, PyObject *data) { Ext *out = (Ext *)Ext_Type.tp_alloc(&Ext_Type, 0); if (out == NULL) return NULL; out->code = code; Py_INCREF(data); out->data = data; return (PyObject *)out; } PyDoc_STRVAR(Ext__doc__, "Ext(code, data, /)\n" "--\n" "\n" "A record representing a MessagePack Extension Type.\n" "\n" "Parameters\n" "----------\n" "code : int\n" " The integer type code for this extension. Must be between -128 and 127.\n" "data : bytes, bytearray, or memoryview\n" " The byte buffer for this extension. One of bytes, bytearray, memoryview,\n" " or any object that implements the buffer protocol." ); static PyObject * Ext_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) { PyObject *pycode, *data; long code; Py_ssize_t nargs, nkwargs; nargs = PyTuple_GET_SIZE(args); nkwargs = (kwargs == NULL) ? 0 : PyDict_GET_SIZE(kwargs); if (nkwargs != 0) { PyErr_SetString( PyExc_TypeError, "Ext takes no keyword arguments" ); return NULL; } else if (nargs != 2) { PyErr_Format( PyExc_TypeError, "Ext expected 2 arguments, got %zd", nargs ); return NULL; } pycode = PyTuple_GET_ITEM(args, 0); data = PyTuple_GET_ITEM(args, 1); if (PyLong_CheckExact(pycode)) { code = PyLong_AsLong(pycode); if ((code == -1 && PyErr_Occurred()) || code > 127 || code < -128) { PyErr_SetString( PyExc_ValueError, "code must be an int between -128 and 127" ); return NULL; } } else { PyErr_Format( PyExc_TypeError, "code must be an int, got %.200s", Py_TYPE(pycode)->tp_name ); return NULL; } if (!(PyBytes_CheckExact(data) || PyByteArray_CheckExact(data) || PyObject_CheckBuffer(data))) { PyErr_Format( PyExc_TypeError, "data must be a bytes, bytearray, or buffer-like object, got %.200s", Py_TYPE(data)->tp_name ); return NULL; } return Ext_New(code, data); } static void Ext_dealloc(Ext *self) { Py_XDECREF(self->data); Py_TYPE(self)->tp_free((PyObject *)self); } static PyMemberDef Ext_members[] = { {"code", T_LONG, offsetof(Ext, code), READONLY, "The extension type code"}, {"data", T_OBJECT_EX, offsetof(Ext, data), READONLY, "The extension data payload"}, {NULL}, }; static PyObject * Ext_reduce(PyObject *self, PyObject *unused) { return Py_BuildValue("O(bO)", Py_TYPE(self), ((Ext*)self)->code, ((Ext*)self)->data); } static PyObject * Ext_richcompare(PyObject *self, PyObject *other, int op) { int status; PyObject *out; Ext *ex_self, *ex_other; if (Py_TYPE(other) != &Ext_Type) { Py_RETURN_NOTIMPLEMENTED; } if (op != Py_EQ && op != Py_NE) { Py_RETURN_NOTIMPLEMENTED; } ex_self = (Ext *)self; ex_other = (Ext *)other; status = ex_self->code == ex_other->code; if (!status) { out = (op == Py_EQ) ? Py_False : Py_True; } else { status = PyObject_RichCompareBool(ex_self->data, ex_other->data, op); if (status == -1) return NULL; out = status ? Py_True : Py_False; } Py_INCREF(out); return out; } static PyMethodDef Ext_methods[] = { {"__reduce__", Ext_reduce, METH_NOARGS, "reduce an Ext"}, {NULL, NULL}, }; static PyTypeObject Ext_Type = { PyVarObject_HEAD_INIT(NULL, 0) .tp_name = "msgspec.msgpack.Ext", .tp_doc = Ext__doc__, .tp_basicsize = sizeof(Ext), .tp_itemsize = 0, .tp_flags = Py_TPFLAGS_DEFAULT, .tp_new = Ext_new, .tp_dealloc = (destructor) Ext_dealloc, .tp_richcompare = Ext_richcompare, .tp_members = Ext_members, .tp_methods = Ext_methods }; /************************************************************************* * Dataclass Utilities * *************************************************************************/ typedef struct { PyObject *obj; PyObject *fields; PyObject *dict; Py_ssize_t fields_pos; Py_ssize_t dict_pos; bool fastpath; bool standard_getattr; } DataclassIter; static MS_INLINE PyObject * ms_type_lookup_ref(PyTypeObject *type, PyObject *name) { #if PY313_PLUS return _PyType_LookupRef(type, name); #else PyObject *out = _PyType_Lookup(type, name); Py_XINCREF(out); return out; #endif } static PyObject * ms_get_dataclass_fields(MsgspecState *mod, PyTypeObject *type, PyObject *obj) { PyObject *fields = ms_type_lookup_ref(type, mod->str___dataclass_fields__); if (fields == NULL) return NULL; if (MS_LIKELY( PyDict_CheckExact(fields) && type->tp_getattro == PyObject_GenericGetAttr )) { return fields; } Py_DECREF(fields); fields = PyObject_GetAttr(obj, mod->str___dataclass_fields__); if (fields == NULL) PyErr_Clear(); return fields; } static bool dataclass_iter_setup(DataclassIter *iter, PyObject *obj, PyObject *fields) { iter->dict = NULL; if (MS_UNLIKELY(!PyDict_CheckExact(fields))) { PyErr_Format(PyExc_RuntimeError, "%R.__dataclass_fields__ is not a dict", obj); return false; } iter->obj = obj; iter->fields = fields; iter->fields_pos = 0; iter->dict_pos = 0; iter->fastpath = false; iter->standard_getattr = ( Py_TYPE(obj)->tp_getattro == PyObject_GenericGetAttr ); if (iter->standard_getattr) { iter->dict = PyObject_GenericGetDict(obj, NULL); if (iter->dict == NULL) { PyErr_Clear(); } else if (PyDict_GET_SIZE(fields) == PyDict_GET_SIZE(iter->dict)) { iter->fastpath = true; } } return true; } static void dataclass_iter_cleanup(DataclassIter *iter) { Py_XDECREF(iter->dict); } static MS_INLINE bool dataclass_iter_next( DataclassIter *iter, PyObject **field_name, PyObject **field_val ) { PyObject *name, *key, *val; next_field: if (!PyDict_Next(iter->fields, &(iter->fields_pos), &name, NULL)) { return false; } if (MS_UNLIKELY(!PyUnicode_CheckExact(name))) goto next_field; if (MS_LIKELY(iter->fastpath)) { if ( PyDict_Next(iter->dict, &(iter->dict_pos), &key, &val) && (key == name) ) { Py_INCREF(val); goto found_val; } else { iter->fastpath = false; } } PyTypeObject *type = Py_TYPE(iter->obj); if (MS_LIKELY(iter->standard_getattr)) { if (iter->dict != NULL) { /* We know it's already hashed, it came from a dict */ Py_hash_t hash = ((PyASCIIObject *)name)->hash; val = _PyDict_GetItem_KnownHash(iter->dict, name, hash); if (val != NULL) { Py_INCREF(val); goto found_val; } } PyObject *descr = _PyType_Lookup(type, name); if (descr != NULL) { descrgetfunc get = Py_TYPE(descr)->tp_descr_get; descrsetfunc set = Py_TYPE(descr)->tp_descr_set; if (get != NULL && set != NULL) { Py_INCREF(descr); val = get(descr, iter->obj, (PyObject *)type); Py_DECREF(descr); if (val != NULL) goto found_val; PyErr_Clear(); } } goto next_field; } else { val = type->tp_getattro(iter->obj, name); if (val == NULL) { PyErr_Clear(); goto next_field; } goto found_val; } found_val: if (MS_UNLIKELY(val == UNSET)) { Py_DECREF(val); goto next_field; } *field_name = name; *field_val = val; return true; } static AssocList * AssocList_FromDataclass(PyObject *obj, PyObject *fields) { if (Py_EnterRecursiveCall(" while serializing an object")) return NULL; bool ok = false; AssocList *out = NULL; DataclassIter iter; if (!dataclass_iter_setup(&iter, obj, fields)) goto cleanup; out = AssocList_New(PyDict_GET_SIZE(fields)); if (out == NULL) goto cleanup; PyObject *field, *val; while (dataclass_iter_next(&iter, &field, &val)) { int status = AssocList_Append(out, field, val); Py_DECREF(val); if (status < 0) goto cleanup; } ok = true; cleanup: Py_LeaveRecursiveCall(); dataclass_iter_cleanup(&iter); if (!ok) { AssocList_Free(out); return NULL; } return out; } /************************************************************************* * Object Utilities * *************************************************************************/ static AssocList * AssocList_FromObject(PyObject *obj) { bool ok = false; PyObject *dict = NULL; AssocList *out = NULL; if (Py_EnterRecursiveCall(" while serializing an object")) return NULL; dict = PyObject_GenericGetDict(obj, NULL); if (MS_UNLIKELY(dict == NULL)) { PyErr_Clear(); } /* Determine max size of AssocList needed */ Py_ssize_t max_size = (dict == NULL) ? 0 : PyDict_GET_SIZE(dict); PyTypeObject *type = Py_TYPE(obj); while (type != NULL) { max_size += Py_SIZE(type); type = type->tp_base; } out = AssocList_New(max_size); Py_BEGIN_CRITICAL_SECTION(obj); if (out == NULL) goto cleanup; /* Append everything in `__dict__` */ if (dict != NULL) { PyObject *key, *val; Py_ssize_t pos = 0; int err = 0; Py_BEGIN_CRITICAL_SECTION(dict); while (PyDict_Next(dict, &pos, &key, &val)) { if (MS_LIKELY(PyUnicode_CheckExact(key))) { Py_ssize_t key_len; if (MS_UNLIKELY(val == UNSET)) continue; const char* key_buf = unicode_str_and_size(key, &key_len); if (MS_UNLIKELY(key_buf == NULL)) { err = 1; break; } if (MS_UNLIKELY(*key_buf == '_')) continue; if (MS_UNLIKELY(AssocList_Append(out, key, val) < 0)) { err = 1; break; } } } Py_END_CRITICAL_SECTION(); if (MS_UNLIKELY(err)) goto cleanup; } /* Then append everything in slots */ type = Py_TYPE(obj); while (type != NULL) { Py_ssize_t n = Py_SIZE(type); if (n) { PyMemberDef *mp = MS_PyHeapType_GET_MEMBERS((PyHeapTypeObject *)type); for (Py_ssize_t i = 0; i < n; i++, mp++) { if (MS_LIKELY(mp->type == T_OBJECT_EX && !(mp->flags & READONLY))) { char *addr = (char *)obj + mp->offset; PyObject *val = *(PyObject **)addr; if (MS_UNLIKELY(val == UNSET)) continue; if (MS_UNLIKELY(val == NULL)) continue; if (MS_UNLIKELY(*mp->name == '_')) continue; AssocList_AppendCStr(out, mp->name, val); } } } type = type->tp_base; } ok = true; cleanup: Py_XDECREF(dict); Py_END_CRITICAL_SECTION(); Py_LeaveRecursiveCall(); if (!ok) { AssocList_Free(out); return NULL; } return out; } /************************************************************************* * Shared Encoder structs/methods * *************************************************************************/ #define ENC_INIT_BUFSIZE 32 #define ENC_LINES_INIT_BUFSIZE 1024 enum decimal_format { DECIMAL_FORMAT_STRING = 0, DECIMAL_FORMAT_NUMBER = 1, DECIMAL_FORMAT_CALLABLE = 2, }; enum uuid_format { UUID_FORMAT_CANONICAL = 0, UUID_FORMAT_HEX = 1, UUID_FORMAT_BYTES = 2, }; typedef struct EncoderState { MsgspecState *mod; /* module reference */ PyObject *enc_hook; /* `enc_hook` callback */ PyObject *decimal_callable; /* `decimal_format` callable */ enum decimal_format decimal_format; enum uuid_format uuid_format; enum order_mode order; char* (*resize_buffer)(PyObject**, Py_ssize_t); /* callback for resizing buffer */ bool in_decimal_callable; char *output_buffer_raw; /* raw pointer to output_buffer internal buffer */ Py_ssize_t output_len; /* Length of output_buffer */ Py_ssize_t max_output_len; /* Allocation size of output_buffer */ PyObject *output_buffer; /* bytes or bytearray storing the output */ } EncoderState; typedef struct Encoder { PyObject_HEAD PyObject *enc_hook; PyObject *decimal_callable; MsgspecState *mod; enum decimal_format decimal_format; enum uuid_format uuid_format; enum order_mode order; } Encoder; static PyTypeObject Encoder_Type; static char* ms_resize_bytes(PyObject** output_buffer, Py_ssize_t size) { int status = _PyBytes_Resize(output_buffer, size); if (status < 0) return NULL; return PyBytes_AS_STRING(*output_buffer); } static char* ms_resize_bytearray(PyObject** output_buffer, Py_ssize_t size) { int status = PyByteArray_Resize(*output_buffer, size); if (status < 0) return NULL; return PyByteArray_AS_STRING(*output_buffer); } static MS_NOINLINE int ms_resize(EncoderState *self, Py_ssize_t size) { self->max_output_len = Py_MAX(8, 1.5 * size); char *new_buf = self->resize_buffer(&self->output_buffer, self->max_output_len); if (new_buf == NULL) return -1; self->output_buffer_raw = new_buf; return 0; } static MS_INLINE int ms_ensure_space(EncoderState *self, Py_ssize_t size) { Py_ssize_t required = self->output_len + size; if (MS_UNLIKELY(required > self->max_output_len)) { return ms_resize(self, required); } return 0; } static MS_INLINE int ms_write(EncoderState *self, const char *s, Py_ssize_t n) { Py_ssize_t required = self->output_len + n; if (MS_UNLIKELY(required > self->max_output_len)) { if (ms_resize(self, required) < 0) return -1; } memcpy(self->output_buffer_raw + self->output_len, s, n); self->output_len += n; return 0; } static int Encoder_init(Encoder *self, PyObject *args, PyObject *kwds) { char *kwlist[] = {"enc_hook", "decimal_format", "uuid_format", "order", NULL}; PyObject *enc_hook = NULL, *decimal_format = NULL, *uuid_format = NULL, *order = NULL; if ( !PyArg_ParseTupleAndKeywords( args, kwds, "|$OOOO", kwlist, &enc_hook, &decimal_format, &uuid_format, &order ) ) { return -1; } /* Process decimal format */ self->decimal_callable = NULL; if (decimal_format == NULL) { self->decimal_format = DECIMAL_FORMAT_STRING; } else if (PyCallable_Check(decimal_format)) { self->decimal_format = DECIMAL_FORMAT_CALLABLE; Py_INCREF(decimal_format); self->decimal_callable = decimal_format; } else { bool ok = false; if (PyUnicode_CheckExact(decimal_format)) { if (PyUnicode_CompareWithASCIIString(decimal_format, "string") == 0) { self->decimal_format = DECIMAL_FORMAT_STRING; ok = true; } else if (PyUnicode_CompareWithASCIIString(decimal_format, "number") == 0) { self->decimal_format = DECIMAL_FORMAT_NUMBER; ok = true; } } if (!ok) { PyErr_Format( PyExc_ValueError, "`decimal_format` must be 'string', 'number', or a callable, got %R", decimal_format ); return -1; } } /* Process uuid format */ if (uuid_format == NULL) { self->uuid_format = UUID_FORMAT_CANONICAL; } else { bool is_msgpack = Py_TYPE(self) == &Encoder_Type; bool ok = false; if (PyUnicode_CheckExact(uuid_format)) { if (PyUnicode_CompareWithASCIIString(uuid_format, "canonical") == 0) { self->uuid_format = UUID_FORMAT_CANONICAL; ok = true; } else if (PyUnicode_CompareWithASCIIString(uuid_format, "hex") == 0) { self->uuid_format = UUID_FORMAT_HEX; ok = true; } else if (is_msgpack && PyUnicode_CompareWithASCIIString(uuid_format, "bytes") == 0) { self->uuid_format = UUID_FORMAT_BYTES; ok = true; } } if (!ok) { const char *errmsg = ( is_msgpack ? "`uuid_format` must be 'canonical', 'hex', or 'bytes', got %R" : "`uuid_format` must be 'canonical' or 'hex', got %R" ); PyErr_Format(PyExc_ValueError, errmsg, uuid_format); return -1; } } /* Process order */ self->order = parse_order_arg(order); if (self->order == ORDER_INVALID) return -1; if (enc_hook == Py_None) { enc_hook = NULL; } if (enc_hook != NULL) { if (!PyCallable_Check(enc_hook)) { PyErr_SetString(PyExc_TypeError, "enc_hook must be callable"); return -1; } Py_INCREF(enc_hook); } self->mod = msgspec_get_global_state(); self->enc_hook = enc_hook; return 0; } static int Encoder_traverse(Encoder *self, visitproc visit, void *arg) { Py_VISIT(self->enc_hook); Py_VISIT(self->decimal_callable); return 0; } static int Encoder_clear(Encoder *self) { Py_CLEAR(self->enc_hook); Py_CLEAR(self->decimal_callable); return 0; } static void Encoder_dealloc(Encoder *self) { PyObject_GC_UnTrack(self); Encoder_clear(self); Py_TYPE(self)->tp_free((PyObject *)self); } PyDoc_STRVAR(Encoder_encode_into__doc__, "encode_into($self, obj, buffer, offset=0, /)\n" "--\n" "\n" "Serialize an object into an existing bytearray buffer.\n" "\n" "Upon success, the buffer will be truncated to the end of the serialized\n" "message. Note that the underlying memory buffer *won't* be truncated,\n" "allowing for efficiently appending additional bytes later.\n" "\n" "Parameters\n" "----------\n" "obj : Any\n" " The object to serialize.\n" "buffer : bytearray\n" " The buffer to serialize into.\n" "offset : int, optional\n" " The offset into the buffer to start writing at. Defaults to 0. Set to -1\n" " to start writing at the end of the buffer.\n" "\n" "Returns\n" "-------\n" "None" ); static PyObject* encoder_encode_into_common( Encoder *self, PyObject *const *args, Py_ssize_t nargs, int(*encode)(EncoderState*, PyObject*) ) { if (!check_positional_nargs(nargs, 2, 3)) return NULL; PyObject *obj = args[0]; PyObject *buf = args[1]; if (!PyByteArray_CheckExact(buf)) { PyErr_SetString(PyExc_TypeError, "buffer must be a `bytearray`"); return NULL; } Py_ssize_t buf_size = PyByteArray_GET_SIZE(buf); Py_ssize_t offset = 0; if (nargs == 3) { offset = PyLong_AsSsize_t(args[2]); if (offset == -1) { if (PyErr_Occurred()) return NULL; offset = buf_size; } if (offset < 0) { PyErr_SetString(PyExc_ValueError, "offset must be >= -1"); return NULL; } if (offset < buf_size) { buf_size = Py_MAX(8, 1.5 * offset); if (PyByteArray_Resize(buf, buf_size) < 0) return NULL; } } /* Setup buffer */ EncoderState state = { .mod = self->mod, .enc_hook = self->enc_hook, .decimal_format = self->decimal_format, .decimal_callable = self->decimal_callable, .in_decimal_callable = false, .uuid_format = self->uuid_format, .order = self->order, .output_buffer = buf, .output_buffer_raw = PyByteArray_AS_STRING(buf), .output_len = offset, .max_output_len = buf_size, .resize_buffer = ms_resize_bytearray }; if (encode(&state, obj) < 0) { return NULL; } FAST_BYTEARRAY_SHRINK(buf, state.output_len); Py_RETURN_NONE; } PyDoc_STRVAR(Encoder_encode__doc__, "encode($self, obj, /)\n" "--\n" "\n" "Serialize an object to bytes.\n" "\n" "Parameters\n" "----------\n" "obj : Any\n" " The object to serialize.\n" "\n" "Returns\n" "-------\n" "data : bytes\n" " The serialized object.\n" ); static PyObject* encoder_encode_common( Encoder *self, PyObject *const *args, Py_ssize_t nargs, int(*encode)(EncoderState*, PyObject*) ) { if (!check_positional_nargs(nargs, 1, 1)) return NULL; EncoderState state = { .mod = self->mod, .enc_hook = self->enc_hook, .decimal_format = self->decimal_format, .decimal_callable = self->decimal_callable, .in_decimal_callable = false, .uuid_format = self->uuid_format, .order = self->order, .output_len = 0, .max_output_len = ENC_INIT_BUFSIZE, .resize_buffer = &ms_resize_bytes }; state.output_buffer = PyBytes_FromStringAndSize(NULL, state.max_output_len); if (state.output_buffer == NULL) return NULL; state.output_buffer_raw = PyBytes_AS_STRING(state.output_buffer); if (encode(&state, args[0]) < 0) { Py_DECREF(state.output_buffer); return NULL; } FAST_BYTES_SHRINK(state.output_buffer, state.output_len); return state.output_buffer; } static PyObject* encode_common( PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames, int(*encode)(EncoderState*, PyObject*) ) { PyObject *enc_hook = NULL, *order = NULL; MsgspecState *mod = msgspec_get_state(module); /* Parse arguments */ if (!check_positional_nargs(nargs, 1, 1)) return NULL; if (kwnames != NULL) { Py_ssize_t nkwargs = PyTuple_GET_SIZE(kwnames); if ((enc_hook = find_keyword(kwnames, args + nargs, mod->str_enc_hook)) != NULL) nkwargs--; if ((order = find_keyword(kwnames, args + nargs, mod->str_order)) != NULL) nkwargs--; if (nkwargs > 0) { PyErr_SetString( PyExc_TypeError, "Extra keyword arguments provided" ); return NULL; } } if (enc_hook == Py_None) { enc_hook = NULL; } if (enc_hook != NULL && !PyCallable_Check(enc_hook)) { PyErr_SetString(PyExc_TypeError, "enc_hook must be callable"); return NULL; } EncoderState state = { .mod = mod, .enc_hook = enc_hook, .decimal_format = DECIMAL_FORMAT_STRING, .decimal_callable = NULL, .in_decimal_callable = false, .uuid_format = UUID_FORMAT_CANONICAL, .output_len = 0, .max_output_len = ENC_INIT_BUFSIZE, .resize_buffer = &ms_resize_bytes }; state.order = parse_order_arg(order); if (state.order == ORDER_INVALID) return NULL; state.output_buffer = PyBytes_FromStringAndSize(NULL, state.max_output_len); if (state.output_buffer == NULL) return NULL; state.output_buffer_raw = PyBytes_AS_STRING(state.output_buffer); if (encode(&state, args[0]) < 0) { Py_DECREF(state.output_buffer); return NULL; } FAST_BYTES_SHRINK(state.output_buffer, state.output_len); return state.output_buffer; } static PyMemberDef Encoder_members[] = { {"enc_hook", T_OBJECT, offsetof(Encoder, enc_hook), READONLY, NULL}, {NULL}, }; static PyObject* Encoder_decimal_format(Encoder *self, void *closure) { if (self->decimal_format == DECIMAL_FORMAT_STRING) { return PyUnicode_InternFromString("string"); } else if (self->decimal_format == DECIMAL_FORMAT_NUMBER) { return PyUnicode_InternFromString("number"); } else { Py_INCREF(self->decimal_callable); return self->decimal_callable; } } static PyObject* Encoder_uuid_format(Encoder *self, void *closure) { if (self->uuid_format == UUID_FORMAT_CANONICAL) { return PyUnicode_InternFromString("canonical"); } else if (self->uuid_format == UUID_FORMAT_HEX) { return PyUnicode_InternFromString("hex"); } else { return PyUnicode_InternFromString("bytes"); } } static PyObject* Encoder_order(Encoder *self, void *closure) { if (self->order == ORDER_DEFAULT) { Py_RETURN_NONE; } else if (self->order == ORDER_DETERMINISTIC) { return PyUnicode_InternFromString("deterministic"); } else { return PyUnicode_InternFromString("sorted"); } } static PyGetSetDef Encoder_getset[] = { {"decimal_format", (getter) Encoder_decimal_format, NULL, NULL, NULL}, {"uuid_format", (getter) Encoder_uuid_format, NULL, NULL, NULL}, {"order", (getter) Encoder_order, NULL, NULL, NULL}, {NULL}, }; /************************************************************************* * Shared Decoding Utilities * *************************************************************************/ static PyObject * ms_maybe_decode_bool_from_uint64(uint64_t x) { if (x == 0) { Py_RETURN_FALSE; } else if (x == 1) { Py_RETURN_TRUE; } return NULL; } static PyObject * ms_maybe_decode_bool_from_int64(int64_t x) { if (x == 0) { Py_RETURN_FALSE; } else if (x == 1) { Py_RETURN_TRUE; } return NULL; } static PyObject * ms_decode_str_enum_or_literal(const char *name, Py_ssize_t size, TypeNode *type, PathNode *path) { StrLookup *lookup = TypeNode_get_str_enum_or_literal(type); return StrLookup_GetOrError(lookup, name, size, path); } static PyObject * ms_decode_int_enum_or_literal_int64(int64_t val, TypeNode *type, PathNode *path) { IntLookup *lookup = TypeNode_get_int_enum_or_literal(type); return IntLookup_GetInt64OrError(lookup, val, path); } static PyObject * ms_decode_int_enum_or_literal_uint64(uint64_t val, TypeNode *type, PathNode *path) { IntLookup *lookup = TypeNode_get_int_enum_or_literal(type); return IntLookup_GetUInt64OrError(lookup, val, path); } static PyObject * ms_decode_int_enum_or_literal_pyint(PyObject *val, TypeNode *type, PathNode *path) { IntLookup *lookup = TypeNode_get_int_enum_or_literal(type); return IntLookup_GetPyIntOrError(lookup, val, path); } static MS_NOINLINE PyObject * ms_decode_custom(PyObject *obj, PyObject *dec_hook, TypeNode* type, PathNode *path) { PyObject *custom_cls = NULL, *custom_obj, *out = NULL; int status; bool generic = type->types & MS_TYPE_CUSTOM_GENERIC; if (obj == NULL) return NULL; if (obj == Py_None && type->types & MS_TYPE_NONE) return obj; custom_obj = TypeNode_get_custom(type); if (dec_hook != NULL) { out = PyObject_CallFunctionObjArgs(dec_hook, custom_obj, obj, NULL); Py_DECREF(obj); if (out == NULL) { ms_maybe_wrap_validation_error(path); return NULL; } } else { out = obj; } /* Generic classes must be checked based on __origin__ */ if (generic) { MsgspecState *st = msgspec_get_global_state(); custom_cls = PyObject_GetAttr(custom_obj, st->str___origin__); if (custom_cls == NULL) { Py_DECREF(out); return NULL; } } else { custom_cls = custom_obj; } /* Check that the decoded value matches the expected type */ status = PyObject_IsInstance(out, custom_cls); if (status == 0) { ms_raise_validation_error( path, "Expected `%s`, got `%s`%U", ((PyTypeObject *)custom_cls)->tp_name, Py_TYPE(out)->tp_name ); Py_CLEAR(out); } else if (status == -1) { Py_CLEAR(out); } if (generic) { Py_DECREF(custom_cls); } return out; } static MS_NOINLINE PyObject * _err_int_constraint(const char *msg, int64_t c, PathNode *path) { ms_raise_validation_error(path, msg, c); return NULL; } static MS_NOINLINE PyObject * ms_decode_constr_int(int64_t x, TypeNode *type, PathNode *path) { if (type->types & MS_CONSTR_INT_MIN) { int64_t c = TypeNode_get_constr_int_min(type); bool ok = x >= c; if (MS_UNLIKELY(!ok)) { return _err_int_constraint("Expected `int` >= %lld%U", c, path); } } if (type->types & MS_CONSTR_INT_MAX) { int64_t c = TypeNode_get_constr_int_max(type); bool ok = x <= c; if (MS_UNLIKELY(!ok)) { return _err_int_constraint("Expected `int` <= %lld%U", c, path); } } if (MS_UNLIKELY(type->types & MS_CONSTR_INT_MULTIPLE_OF)) { int64_t c = TypeNode_get_constr_int_multiple_of(type); bool ok = (x % c) == 0; if (MS_UNLIKELY(!ok)) { return _err_int_constraint( "Expected `int` that's a multiple of %lld%U", c, path ); } } return PyLong_FromLongLong(x); } static MS_INLINE PyObject * ms_decode_int(int64_t x, TypeNode *type, PathNode *path) { if (MS_UNLIKELY(type->types & MS_INT_CONSTRS)) { return ms_decode_constr_int(x, type, path); } return PyLong_FromLongLong(x); } static MS_NOINLINE PyObject * ms_decode_constr_uint(uint64_t x, TypeNode *type, PathNode *path) { if (type->types & MS_CONSTR_INT_MAX) { int64_t c = TypeNode_get_constr_int_max(type); return _err_int_constraint("Expected `int` <= %lld%U", c, path); } if (MS_UNLIKELY(type->types & MS_CONSTR_INT_MULTIPLE_OF)) { int64_t c = TypeNode_get_constr_int_multiple_of(type); bool ok = (x % c) == 0; if (MS_UNLIKELY(!ok)) { return _err_int_constraint( "Expected `int` that's a multiple of %lld%U", c, path ); } } return PyLong_FromUnsignedLongLong(x); } static MS_INLINE PyObject * ms_decode_uint(uint64_t x, TypeNode *type, PathNode *path) { if (MS_UNLIKELY(type->types & MS_INT_CONSTRS)) { if (MS_LIKELY(x <= LLONG_MAX)) { return ms_decode_int(x, type, path); } return ms_decode_constr_uint(x, type, path); } return PyLong_FromUnsignedLongLong(x); } static MS_NOINLINE bool ms_passes_int_constraints(uint64_t ux, bool neg, TypeNode *type, PathNode *path) { if (type->types & MS_CONSTR_INT_MIN) { int64_t c = TypeNode_get_constr_int_min(type); bool ok = ( neg ? ((-(int64_t)ux) >= c) : ((c < 0) || (ux >= (uint64_t)c)) ); if (MS_UNLIKELY(!ok)) { _err_int_constraint("Expected `int` >= %lld%U", c, path); return false; } } if (type->types & MS_CONSTR_INT_MAX) { int64_t c = TypeNode_get_constr_int_max(type); bool ok = ( neg ? ((-(int64_t)ux) <= c) : ((c >= 0) && (ux <= (uint64_t)c)) ); if (MS_UNLIKELY(!ok)) { _err_int_constraint("Expected `int` <= %lld%U", c, path); return false; } } if (MS_UNLIKELY(type->types & MS_CONSTR_INT_MULTIPLE_OF)) { int64_t c = TypeNode_get_constr_int_multiple_of(type); bool ok = (ux % c) == 0; if (MS_UNLIKELY(!ok)) { _err_int_constraint( "Expected `int` that's a multiple of %lld%U", c, path ); return false; } } return true; } /* Constraint checks for a PyLong that is known not to fit into a uint64/int64 */ static bool ms_passes_big_int_constraints(PyObject *obj, TypeNode *type, PathNode *path) { #if PY314_PLUS /* obj is always a PyLong here, so PyLong_GetSign can't fail */ int sign = 0; (void)PyLong_GetSign(obj, &sign); bool neg = sign < 0; #else bool neg = _PyLong_Sign(obj) < 0; #endif if (type->types & MS_CONSTR_INT_MIN) { if (neg) { int64_t c = TypeNode_get_constr_int_min(type); _err_int_constraint("Expected `int` >= %lld%U", c, path); return false; } } if (type->types & MS_CONSTR_INT_MAX) { if (!neg) { int64_t c = TypeNode_get_constr_int_max(type); _err_int_constraint("Expected `int` <= %lld%U", c, path); return false; } } if (MS_UNLIKELY(type->types & MS_CONSTR_INT_MULTIPLE_OF)) { int64_t c = TypeNode_get_constr_int_multiple_of(type); PyObject *base = PyLong_FromLongLong(c); if (base == NULL) return false; PyObject *remainder = PyNumber_Remainder(obj, base); Py_DECREF(base); if (remainder == NULL) return false; long iremainder = PyLong_AsLong(remainder); Py_DECREF(remainder); if (iremainder != 0) { _err_int_constraint( "Expected `int` that's a multiple of %lld%U", c, path ); return false; } } return true; } static MS_NOINLINE PyObject * ms_decode_big_pyint(PyObject *obj, TypeNode *type, PathNode *path) { if (MS_UNLIKELY(type->types & MS_INT_CONSTRS)) { if (!ms_passes_big_int_constraints(obj, type, path)) return NULL; } if (MS_LIKELY(PyLong_CheckExact(obj))) { Py_INCREF(obj); return obj; } else { return PyNumber_Long(obj); } } static MS_INLINE PyObject * ms_decode_pyint(PyObject *obj, TypeNode *type, PathNode *path) { uint64_t ux; bool neg, overflow; overflow = fast_long_extract_parts(obj, &neg, &ux); if (MS_UNLIKELY(overflow)) { return ms_decode_big_pyint(obj, type, path); } if (MS_UNLIKELY(type->types & MS_INT_CONSTRS)) { if (!ms_passes_int_constraints(ux, neg, type, path)) return NULL; } if (MS_LIKELY(PyLong_CheckExact(obj))) { Py_INCREF(obj); return obj; } if (!neg) { return PyLong_FromUnsignedLongLong(ux); } return PyLong_FromLongLong(-(int64_t)ux); } static MS_NOINLINE PyObject * ms_decode_bigint(const char *buf, Py_ssize_t size, TypeNode *type, PathNode *path) { if (size > 4300) goto out_of_range; /* CPython int parsing routine requires NULL terminated buffer */ char *temp = (char *)PyMem_Malloc(size + 1); if (temp == NULL) { return PyErr_NoMemory(); } memcpy(temp, buf, size); temp[size] = '\0'; PyObject *out = PyLong_FromString(temp, NULL, 10); PyMem_Free(temp); /* We already know the int is a valid integer string. An error here is * either a ValueError due to the int being too big (to prevent DDOS * issues), or some issue in the VM. We convert the former to out-of-range * errors for uniformity, and raise the latter directly. */ if (MS_UNLIKELY(out == NULL)) { PyObject *exc_type, *exc, *tb; /* Fetch the exception state. Take a reference to each if not NULL */ PyErr_Fetch(&exc_type, &exc, &tb); if (exc_type == NULL) { /* Some other c-extension has borked, just return. * References might still have been taken, so decred just in case */ Py_XDECREF(exc_type); Py_XDECREF(exc); Py_XDECREF(tb); return NULL; } else if (exc_type == PyExc_ValueError) { Py_XDECREF(exc_type); Py_XDECREF(exc); Py_XDECREF(tb); goto out_of_range; } else { /* Restore the exception state. * No need to decref here as PyErr_Restore steals references to the args */ PyErr_Restore(exc_type, exc, tb); } } if (MS_UNLIKELY(type->types & MS_INT_CONSTRS)) { if (!ms_passes_big_int_constraints(out, type, path)) { Py_CLEAR(out); } } return out; out_of_range: return ms_error_with_path("Integer value out of range%U", path); } static MS_NOINLINE PyObject * _err_float_constraint( const char *msg, int offset, double c, PathNode *path ) { if (offset == 1) { c = nextafter(c, DBL_MAX); } else if (offset == -1) { c = nextafter(c, -DBL_MAX); } PyObject *py_c = PyFloat_FromDouble(c); if (py_c != NULL) { ms_raise_validation_error(path, "Expected `float` %s %R%U", msg, py_c); Py_DECREF(py_c); } return NULL; } static MS_INLINE bool ms_passes_float_constraints_inline(double x, TypeNode *type, PathNode *path) { if (type->types & (MS_CONSTR_FLOAT_GE | MS_CONSTR_FLOAT_GT)) { double c = TypeNode_get_constr_float_min(type); bool ok = x >= c; if (MS_UNLIKELY(!ok)) { bool eq = type->types & MS_CONSTR_FLOAT_GE; _err_float_constraint( eq ? ">=" : ">", eq ? 0 : -1, c, path ); return false; } } if (type->types & (MS_CONSTR_FLOAT_LE | MS_CONSTR_FLOAT_LT)) { double c = TypeNode_get_constr_float_max(type); bool ok = x <= c; if (MS_UNLIKELY(!ok)) { bool eq = type->types & MS_CONSTR_FLOAT_LE; _err_float_constraint( eq ? "<=" : "<", eq ? 0 : 1, c, path ); return false; } } if (MS_UNLIKELY(type->types & MS_CONSTR_FLOAT_MULTIPLE_OF)) { double c = TypeNode_get_constr_float_multiple_of(type); bool ok = x == 0 || fmod(x, c) == 0.0; if (MS_UNLIKELY(!ok)) { _err_float_constraint( "that's a multiple of", 0, c, path ); return false; } } return true; } static MS_NOINLINE PyObject * ms_decode_constr_float(double x, TypeNode *type, PathNode *path) { if (!ms_passes_float_constraints_inline(x, type, path)) return NULL; return PyFloat_FromDouble(x); } static MS_INLINE PyObject * ms_decode_float(double x, TypeNode *type, PathNode *path) { if (MS_UNLIKELY(type->types & MS_FLOAT_CONSTRS)) { return ms_decode_constr_float(x, type, path); } return PyFloat_FromDouble(x); } static MS_NOINLINE PyObject * _ms_check_float_constraints(PyObject *obj, TypeNode *type, PathNode *path) { double x = PyFloat_AS_DOUBLE(obj); if (ms_passes_float_constraints_inline(x, type, path)) return obj; Py_DECREF(obj); return NULL; } static MS_INLINE PyObject * ms_check_float_constraints(PyObject *obj, TypeNode *type, PathNode *path) { if (MS_LIKELY(!(type->types & MS_FLOAT_CONSTRS))) return obj; return _ms_check_float_constraints(obj, type, path); } static MS_NOINLINE bool _err_py_ssize_t_constraint(const char *msg, Py_ssize_t c, PathNode *path) { ms_raise_validation_error(path, msg, c); return false; } static MS_NOINLINE PyObject * _ms_check_str_constraints(PyObject *obj, TypeNode *type, PathNode *path) { if (obj == NULL) return NULL; Py_ssize_t len = PyUnicode_GET_LENGTH(obj); if (type->types & MS_CONSTR_STR_MIN_LENGTH) { Py_ssize_t c = TypeNode_get_constr_str_min_length(type); if (len < c) { _err_py_ssize_t_constraint( "Expected `str` of length >= %zd%U", c, path ); goto error; } } if (type->types & MS_CONSTR_STR_MAX_LENGTH) { Py_ssize_t c = TypeNode_get_constr_str_max_length(type); if (len > c) { _err_py_ssize_t_constraint( "Expected `str` of length <= %zd%U", c, path ); goto error; } } if (type->types & MS_CONSTR_STR_REGEX) { PyObject *regex = TypeNode_get_constr_str_regex(type); PyObject *res = PyObject_CallMethod(regex, "search", "O", obj); if (res == NULL) goto error; bool ok = (res != Py_None); Py_DECREF(res); if (!ok) { PyObject *pattern = PyObject_GetAttrString(regex, "pattern"); if (pattern == NULL) goto error; ms_raise_validation_error( path, "Expected `str` matching regex %R%U", pattern ); Py_DECREF(pattern); goto error; } } return obj; error: Py_DECREF(obj); return NULL; } static MS_INLINE PyObject * ms_check_str_constraints(PyObject *obj, TypeNode *type, PathNode *path) { if (MS_LIKELY(!(type->types & MS_STR_CONSTRS))) return obj; return _ms_check_str_constraints(obj, type, path); } static bool ms_passes_bytes_constraints(Py_ssize_t size, TypeNode *type, PathNode *path) { if (MS_UNLIKELY(type->types & MS_CONSTR_BYTES_MIN_LENGTH)) { Py_ssize_t c = TypeNode_get_constr_bytes_min_length(type); if (size < c) { return _err_py_ssize_t_constraint( "Expected `bytes` of length >= %zd%U", c, path ); } } if (MS_UNLIKELY(type->types & MS_CONSTR_BYTES_MAX_LENGTH)) { Py_ssize_t c = TypeNode_get_constr_bytes_max_length(type); if (size > c) { return _err_py_ssize_t_constraint( "Expected `bytes` of length <= %zd%U", c, path ); } } return true; } static MS_NOINLINE bool _ms_passes_array_constraints(Py_ssize_t size, TypeNode *type, PathNode *path) { if (MS_UNLIKELY(type->types & MS_CONSTR_ARRAY_MIN_LENGTH)) { Py_ssize_t c = TypeNode_get_constr_array_min_length(type); if (size < c) { return _err_py_ssize_t_constraint( "Expected `array` of length >= %zd%U", c, path ); } } if (MS_UNLIKELY(type->types & MS_CONSTR_ARRAY_MAX_LENGTH)) { Py_ssize_t c = TypeNode_get_constr_array_max_length(type); if (size > c) { return _err_py_ssize_t_constraint( "Expected `array` of length <= %zd%U", c, path ); } } return true; } static MS_INLINE bool ms_passes_array_constraints(Py_ssize_t size, TypeNode *type, PathNode *path) { if (MS_UNLIKELY(type->types & MS_ARRAY_CONSTRS)) { return _ms_passes_array_constraints(size, type, path); } return true; } static MS_NOINLINE bool _ms_passes_map_constraints(Py_ssize_t size, TypeNode *type, PathNode *path) { if (MS_UNLIKELY(type->types & MS_CONSTR_MAP_MIN_LENGTH)) { Py_ssize_t c = TypeNode_get_constr_map_min_length(type); if (size < c) { return _err_py_ssize_t_constraint( "Expected `object` of length >= %zd%U", c, path ); } } if (MS_UNLIKELY(type->types & MS_CONSTR_MAP_MAX_LENGTH)) { Py_ssize_t c = TypeNode_get_constr_map_max_length(type); if (size > c) { return _err_py_ssize_t_constraint( "Expected `object` of length <= %zd%U", c, path ); } } return true; } static MS_INLINE bool ms_passes_map_constraints(Py_ssize_t size, TypeNode *type, PathNode *path) { if (MS_UNLIKELY(type->types & MS_MAP_CONSTRS)) { return _ms_passes_map_constraints(size, type, path); } return true; } static bool ms_passes_tz_constraint( PyObject *tz, TypeNode *type, PathNode *path ) { char *err, *type_str; if (tz == Py_None) { if (type->types & MS_CONSTR_TZ_AWARE) { err = "Expected `%s` with a timezone component%U"; goto error; } } else if (type->types & MS_CONSTR_TZ_NAIVE) { err = "Expected `%s` with no timezone component%U"; goto error; } return true; error: if (type->types & MS_TYPE_TIME) { type_str = "time"; } else { type_str = "datetime"; } ms_raise_validation_error(path, err, type_str); return false; } static int ms_encode_err_type_unsupported(PyTypeObject *type) { PyErr_Format( PyExc_TypeError, "Encoding objects of type %.200s is unsupported", type->tp_name ); return -1; } /************************************************************************* * Datetime utilities * *************************************************************************/ #define MS_HAS_TZINFO(o) (((_PyDateTime_BaseTZInfo *)(o))->hastzinfo) #define MS_DATE_GET_TZINFO(o) PyDateTime_DATE_GET_TZINFO(o) #define MS_TIME_GET_TZINFO(o) PyDateTime_TIME_GET_TZINFO(o) #ifndef Py_GIL_DISABLED #ifndef TIMEZONE_CACHE_SIZE #define TIMEZONE_CACHE_SIZE 512 #endif typedef struct { int32_t offset; PyObject *tz; } TimezoneCacheItem; static TimezoneCacheItem timezone_cache[TIMEZONE_CACHE_SIZE]; static void timezone_cache_clear(void) { /* Traverse the timezone cache, deleting any string with a reference count * of only 1 */ for (Py_ssize_t i = 0; i < TIMEZONE_CACHE_SIZE; i++) { PyObject *tz = timezone_cache[i].tz; if (tz != NULL && Py_REFCNT(tz) == 1) { timezone_cache[i].offset = 0; timezone_cache[i].tz = NULL; Py_DECREF(tz); } } } #endif /* Py_GIL_DISABLED */ /* Returns a new reference */ static PyObject* timezone_from_offset(int32_t offset) { #ifndef Py_GIL_DISABLED uint32_t index = ((uint32_t)offset) % TIMEZONE_CACHE_SIZE; if (timezone_cache[index].offset == offset) { PyObject *tz = timezone_cache[index].tz; Py_INCREF(tz); return tz; } PyObject *delta = PyDelta_FromDSU(0, offset * 60, 0); if (delta == NULL) return NULL; PyObject *tz = PyTimeZone_FromOffset(delta); Py_DECREF(delta); if (tz == NULL) return NULL; Py_XDECREF(timezone_cache[index].tz); timezone_cache[index].offset = offset; Py_INCREF(tz); timezone_cache[index].tz = tz; return tz; #else PyObject *delta = PyDelta_FromDSU(0, offset * 60, 0); if (delta == NULL) return NULL; PyObject *tz = PyTimeZone_FromOffset(delta); Py_DECREF(delta); return tz; #endif } static bool is_leap_year(int year) { unsigned int y = (unsigned int)year; return y % 4 == 0 && (y % 100 != 0 || y % 400 == 0); } static int days_in_month(int year, int month) { static const uint8_t ndays[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; if (month == 2 && is_leap_year(year)) return 29; else return ndays[month - 1]; } static MS_NOINLINE int datetime_round_up_micros( int *year, int *month, int *day, int *hour, int *minute, int *second, int *microsecond ) { ++*microsecond; if (*microsecond == 1000000) { *microsecond = 0; ++*second; if (*second == 60) { *second = 0; ++*minute; if (*minute == 60) { *minute = 0; ++*hour; if (*hour == 24) { *hour = 0; ++*day; if (*day == days_in_month(*year, *month) + 1) { ++*month; *day = 1; if (*month > 12) { *month = 1; ++*year; if (*year > 9999) return -1; } } } } } } return 0; } static MS_NOINLINE void time_round_up_micros( int *hour, int *minute, int *second, int *microsecond ) { ++*microsecond; if (*microsecond == 1000000) { *microsecond = 0; ++*second; if (*second == 60) { *second = 0; ++*minute; if (*minute == 60) { *minute = 0; ++*hour; if (*hour == 24) { *hour = 0; } } } } } /* Days since 0001-01-01, the min value for python's datetime objects */ static int days_since_min_datetime(int year, int month, int day) { int out = day; static const int _days_before_month[] = { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 }; out += _days_before_month[month - 1]; if (month > 2 && is_leap_year(year)) out++; year--; /* makes math easier */ out += year*365 + year/4 - year/100 + year/400; return out; } static void datetime_to_epoch(PyObject *obj, int64_t *seconds, int32_t *nanoseconds) { int64_t d = days_since_min_datetime( PyDateTime_GET_YEAR(obj), PyDateTime_GET_MONTH(obj), PyDateTime_GET_DAY(obj) ) - 719163; /* days_since_min_datetime(1970, 1, 1) */ int64_t s = ( PyDateTime_DATE_GET_HOUR(obj) * 3600 + PyDateTime_DATE_GET_MINUTE(obj) * 60 + PyDateTime_DATE_GET_SECOND(obj) ); int64_t us = PyDateTime_DATE_GET_MICROSECOND(obj); *seconds = 86400 * d + s; *nanoseconds = us * 1000; } /* Python datetimes bounded between (inclusive) * [0001-01-01T00:00:00.000000, 9999-12-31T23:59:59.999999] UTC */ #define MS_EPOCH_SECS_MAX 253402300800 #define MS_EPOCH_SECS_MIN -62135596800 #define MS_DAYS_PER_400Y (365*400 + 97) #define MS_DAYS_PER_100Y (365*100 + 24) #define MS_DAYS_PER_4Y (365*4 + 1) /* Epoch -> datetime conversion borrowed and modified from the implementation * in musl, found at * http://git.musl-libc.org/cgit/musl/tree/src/time/__secs_to_tm.c. musl is * copyright Rich Felker et. al, and is licensed under the standard MIT * license. */ static PyObject * datetime_from_epoch( int64_t epoch_secs, uint32_t epoch_nanos, TypeNode *type, PathNode *path ) { /* Error on out-of-bounds datetimes. This leaves ample space in an int, so * no need to check for overflow later. */ if (epoch_secs < MS_EPOCH_SECS_MIN || epoch_secs > MS_EPOCH_SECS_MAX) { return ms_error_with_path("Timestamp is out of range %U", path); } int64_t years, days, secs; int micros, months, remdays, remsecs, remyears; int qc_cycles, c_cycles, q_cycles; /* Round nanos to nearest microsecond, adjusting seconds as needed */ micros = DIV_ROUND_CLOSEST(epoch_nanos, 1000); if (micros == 1000000) { micros = 0; epoch_secs++; } /* Start in Mar not Jan, so leap day is on end */ static const char days_in_month[] = {31, 30, 31, 30, 31, 31, 30, 31, 30, 31, 31, 29}; /* Offset to 2000-03-01, a mod 400 year, immediately after feb 29 */ secs = epoch_secs - (946684800LL + 86400 * (31 + 29)); days = secs / 86400; remsecs = secs % 86400; if (remsecs < 0) { remsecs += 86400; days--; } qc_cycles = days / MS_DAYS_PER_400Y; remdays = days % MS_DAYS_PER_400Y; if (remdays < 0) { remdays += MS_DAYS_PER_400Y; qc_cycles--; } c_cycles = remdays / MS_DAYS_PER_100Y; if (c_cycles == 4) c_cycles--; remdays -= c_cycles * MS_DAYS_PER_100Y; q_cycles = remdays / MS_DAYS_PER_4Y; if (q_cycles == 25) q_cycles--; remdays -= q_cycles * MS_DAYS_PER_4Y; remyears = remdays / 365; if (remyears == 4) remyears--; remdays -= remyears * 365; years = remyears + 4*q_cycles + 100*c_cycles + 400LL*qc_cycles; for (months = 0; days_in_month[months] <= remdays; months++) remdays -= days_in_month[months]; if (months >= 10) { months -= 12; years++; } if (!ms_passes_tz_constraint(PyDateTime_TimeZone_UTC, type, path)) return NULL; return PyDateTimeAPI->DateTime_FromDateAndTime( years + 2000, months + 3, remdays + 1, remsecs / 3600, remsecs / 60 % 60, remsecs % 60, micros, PyDateTime_TimeZone_UTC, PyDateTimeAPI->DateTimeType ); } static inline const char * ms_read_fixint(const char *buf, int width, int *out) { int x = 0; for (int i = 0; i < width; i++) { char c = *buf++; if (!is_digit(c)) return NULL; x = x * 10 + (c - '0'); } *out = x; return buf; } /* Requires 10 bytes of scratch space */ static void ms_encode_date(PyObject *obj, char *out) { uint32_t year = PyDateTime_GET_YEAR(obj); uint8_t month = PyDateTime_GET_MONTH(obj); uint8_t day = PyDateTime_GET_DAY(obj); write_u32_4_digits(year, out); *(out + 4) = '-'; write_u32_2_digits(month, out + 5); *(out + 7) = '-'; write_u32_2_digits(day, out + 8); } /* Requires 21 bytes of scratch space */ static int ms_encode_time_parts( MsgspecState *mod, PyObject *datetime_or_none, uint8_t hour, uint8_t minute, uint8_t second, uint32_t microsecond, PyObject *tzinfo, char *out, int out_offset ) { char *p = out + out_offset; write_u32_2_digits(hour, p); p += 2; *p++ = ':'; write_u32_2_digits(minute, p); p += 2; *p++ = ':'; write_u32_2_digits(second, p); p += 2; if (microsecond) { *p++ = '.'; write_u32_6_digits(microsecond, p); p += 6; } if (tzinfo != Py_None) { int32_t offset_days = 0, offset_secs = 0; if (tzinfo != PyDateTime_TimeZone_UTC) { PyObject *offset = PyObject_CallMethodOneArg( tzinfo, mod->str_utcoffset, datetime_or_none ); if (offset == NULL) { return -1; } else if (PyDelta_Check(offset)) { offset_days = PyDateTime_DELTA_GET_DAYS(offset); offset_secs = PyDateTime_DELTA_GET_SECONDS(offset); Py_DECREF(offset); } else if (offset == Py_None) { Py_DECREF(offset); goto done; } else if (offset != Py_None) { PyErr_SetString( PyExc_TypeError, "tzinfo.utcoffset returned a non-timedelta object" ); Py_DECREF(offset); return -1; } } if (MS_LIKELY(offset_secs == 0)) { *p++ = 'Z'; } else { char sign = '+'; if (offset_days == -1) { sign = '-'; offset_secs = 86400 - offset_secs; } uint8_t offset_hour = offset_secs / 3600; uint8_t offset_min = (offset_secs / 60) % 60; /* If the offset isn't an even number of minutes, RFC 3339 * indicates that the offset should be rounded to the nearest * possible hour:min pair */ bool round_up = (offset_secs - (offset_hour * 3600 + offset_min * 60)) > 30; if (MS_UNLIKELY(round_up)) { offset_min++; if (offset_min == 60) { offset_min = 0; offset_hour++; if (offset_hour == 24) { offset_hour = 0; } } } if (offset_hour == 0 && offset_min == 0) { *p++ = 'Z'; } else { *p++ = sign; write_u32_2_digits(offset_hour, p); p += 2; *p++ = ':'; write_u32_2_digits(offset_min, p); p += 2; } } } done: return p - out; } /* Requires 21 bytes of scratch space max. * * Returns +nbytes if successful, -1 on failure */ static int ms_encode_time(MsgspecState *mod, PyObject *obj, char *out) { uint8_t hour = PyDateTime_TIME_GET_HOUR(obj); uint8_t minute = PyDateTime_TIME_GET_MINUTE(obj); uint8_t second = PyDateTime_TIME_GET_SECOND(obj); uint32_t microsecond = PyDateTime_TIME_GET_MICROSECOND(obj); PyObject *tzinfo = MS_TIME_GET_TZINFO(obj); return ms_encode_time_parts( mod, Py_None, hour, minute, second, microsecond, tzinfo, out, 0 ); } /* Requires 32 bytes of scratch space max. * * Returns +nbytes if successful, -1 on failure */ static int ms_encode_datetime(MsgspecState *mod, PyObject *obj, char *out) { uint8_t hour = PyDateTime_DATE_GET_HOUR(obj); uint8_t minute = PyDateTime_DATE_GET_MINUTE(obj); uint8_t second = PyDateTime_DATE_GET_SECOND(obj); uint32_t microsecond = PyDateTime_DATE_GET_MICROSECOND(obj); PyObject *tzinfo = MS_DATE_GET_TZINFO(obj); ms_encode_date(obj, out); out[10] = 'T'; return ms_encode_time_parts( mod, obj, hour, minute, second, microsecond, tzinfo, out, 11 ); } static PyObject * ms_decode_date(const char *buf, Py_ssize_t size, PathNode *path) { int year, month, day; /* A valid date is 10 characters in length */ if (size != 10) goto invalid; /* Parse date */ if ((buf = ms_read_fixint(buf, 4, &year)) == NULL) goto invalid; if (*buf++ != '-') goto invalid; if ((buf = ms_read_fixint(buf, 2, &month)) == NULL) goto invalid; if (*buf++ != '-') goto invalid; if ((buf = ms_read_fixint(buf, 2, &day)) == NULL) goto invalid; /* Ensure all numbers are valid */ if (year == 0) goto invalid; if (month == 0 || month > 12) goto invalid; if (day == 0 || day > days_in_month(year, month)) goto invalid; return PyDateTimeAPI->Date_FromDate(year, month, day, PyDateTimeAPI->DateType); invalid: return ms_error_with_path("Invalid RFC3339 encoded date%U", path); } static PyObject * ms_decode_time(const char *buf, Py_ssize_t size, TypeNode *type, PathNode *path) { int hour, minute, second, microsecond = 0; const char *buf_end = buf + size; bool round_up_micros = false; PyObject *tz = NULL; char c; /* A valid time is at least 8 characters in length */ if (size < 8) goto invalid; /* Parse time */ if ((buf = ms_read_fixint(buf, 2, &hour)) == NULL) goto invalid; if (*buf++ != ':') goto invalid; if ((buf = ms_read_fixint(buf, 2, &minute)) == NULL) goto invalid; if (*buf++ != ':') goto invalid; if ((buf = ms_read_fixint(buf, 2, &second)) == NULL) goto invalid; /* Remaining reads require bounds check */ #define next_or_null() (buf == buf_end) ? '\0' : *buf++ c = next_or_null(); if (c == '.') { int ndigits = 0; while (ndigits < 6) { c = next_or_null(); if (!is_digit(c)) goto end_decimal; ndigits++; microsecond = microsecond * 10 + (c - '0'); } c = next_or_null(); if (is_digit(c)) { /* This timestamp has higher precision than microseconds; parse * the next digit to support rounding, then skip all remaining * digits */ if ((c - '0') >= 5) { round_up_micros = true; } while (true) { c = next_or_null(); if (!is_digit(c)) break; } } end_decimal: /* Error if no digits after decimal */ if (ndigits == 0) goto invalid; int pow10[6] = {100000, 10000, 1000, 100, 10, 1}; /* Scale microseconds appropriately */ microsecond *= pow10[ndigits - 1]; } #undef next_or_null if (c != '\0') { /* Parse timezone */ int offset = 0; if (c == 'Z' || c == 'z') { /* Check for trailing characters */ if (buf != buf_end) goto invalid; } else { int offset_hour, offset_min; if (c == '-') { offset = -1; } else if (c == '+') { offset = 1; } else { goto invalid; } if (buf_end - buf < 3) goto invalid; if ((buf = ms_read_fixint(buf, 2, &offset_hour)) == NULL) goto invalid; /* RFC3339 requires a ':' separator, ISO8601 doesn't. We support * either */ if (*buf == ':') buf++; if (buf_end - buf != 2) goto invalid; if ((buf = ms_read_fixint(buf, 2, &offset_min)) == NULL) goto invalid; if (offset_hour > 23 || offset_min > 59) goto invalid; offset *= (offset_hour * 60 + offset_min); } if (offset == 0) { tz = PyDateTime_TimeZone_UTC; Py_INCREF(tz); } else { tz = timezone_from_offset(offset); if (tz == NULL) goto error; } } else { tz = Py_None; Py_INCREF(tz); } /* Ensure all numbers are valid */ if (hour > 23) goto invalid; if (minute > 59) goto invalid; if (second > 59) goto invalid; if (MS_UNLIKELY(round_up_micros)) { time_round_up_micros(&hour, &minute, &second, µsecond); } if (!ms_passes_tz_constraint(tz, type, path)) goto error; PyObject *out = PyDateTimeAPI->Time_FromTime( hour, minute, second, microsecond, tz, PyDateTimeAPI->TimeType ); Py_XDECREF(tz); return out; invalid: ms_error_with_path("Invalid RFC3339 encoded time%U", path); error: Py_XDECREF(tz); return NULL; } static PyObject * ms_decode_datetime_from_int64( int64_t timestamp, TypeNode *type, PathNode *path ) { return datetime_from_epoch(timestamp, 0, type, path); } static PyObject * ms_decode_datetime_from_uint64( uint64_t timestamp, TypeNode *type, PathNode *path ) { if (timestamp > LLONG_MAX) { timestamp = LLONG_MAX; /* will raise out of range error later */ } return datetime_from_epoch((int64_t)timestamp, 0, type, path); } static PyObject * ms_decode_datetime_from_float( double timestamp, TypeNode *type, PathNode *path ) { if (MS_UNLIKELY(!isfinite(timestamp))) { return ms_error_with_path("Invalid epoch timestamp%U", path); } int64_t secs = trunc(timestamp); int32_t nanos = 1000000000 * (timestamp - secs); if (nanos && timestamp < 0) { secs--; nanos += 1000000000; } return datetime_from_epoch(secs, nanos, type, path); } static PyObject * ms_decode_datetime_from_str( const char *buf, Py_ssize_t size, TypeNode *type, PathNode *path ) { int year, month, day, hour, minute, second, microsecond = 0; const char *buf_end = buf + size; bool round_up_micros = false; PyObject *tz = NULL; char c; /* A valid datetime is at least 19 characters in length */ if (size < 19) goto invalid; /* Parse date */ if ((buf = ms_read_fixint(buf, 4, &year)) == NULL) goto invalid; if (*buf++ != '-') goto invalid; if ((buf = ms_read_fixint(buf, 2, &month)) == NULL) goto invalid; if (*buf++ != '-') goto invalid; if ((buf = ms_read_fixint(buf, 2, &day)) == NULL) goto invalid; /* RFC3339 date/time separator can be T or t. We also support ' ', which is * ISO8601 compatible. */ c = *buf++; if (!(c == 'T' || c == 't' || c == ' ')) goto invalid; /* Parse time */ if ((buf = ms_read_fixint(buf, 2, &hour)) == NULL) goto invalid; if (*buf++ != ':') goto invalid; if ((buf = ms_read_fixint(buf, 2, &minute)) == NULL) goto invalid; if (*buf++ != ':') goto invalid; if ((buf = ms_read_fixint(buf, 2, &second)) == NULL) goto invalid; /* Remaining reads require bounds check */ #define next_or_null() (buf == buf_end) ? '\0' : *buf++ c = next_or_null(); /* Parse decimal if present. * * Python datetime's only supports microsecond precision, but RFC3339 * doesn't specify a decimal precision limit. To work around this we * support infinite decimal digits, but round to the closest microsecond. * This means that nanosecond timestamps won't properly roundtrip through * datetime objects, but there's not much we can do about that. Other * systems commonly accept 3 or 6 digits, support for/usage of nanosecond * precision is rare. */ if (c == '.') { int ndigits = 0; while (ndigits < 6) { c = next_or_null(); if (!is_digit(c)) goto end_decimal; ndigits++; microsecond = microsecond * 10 + (c - '0'); } c = next_or_null(); if (is_digit(c)) { /* This timestamp has higher precision than microseconds; parse * the next digit to support rounding, then skip all remaining * digits */ if ((c - '0') >= 5) { round_up_micros = true; } while (true) { c = next_or_null(); if (!is_digit(c)) break; } } end_decimal: /* Error if no digits after decimal */ if (ndigits == 0) goto invalid; int pow10[6] = {100000, 10000, 1000, 100, 10, 1}; /* Scale microseconds appropriately */ microsecond *= pow10[ndigits - 1]; } #undef next_or_null if (c != '\0') { /* Parse timezone */ int offset = 0; if (c == 'Z' || c == 'z') { /* Check for trailing characters */ if (buf != buf_end) goto invalid; } else { int offset_hour, offset_min; if (c == '-') { offset = -1; } else if (c == '+') { offset = 1; } else { goto invalid; } if (buf_end - buf < 3) goto invalid; if ((buf = ms_read_fixint(buf, 2, &offset_hour)) == NULL) goto invalid; /* RFC3339 requires a ':' separator, ISO8601 doesn't. We support * either */ if (*buf == ':') buf++; if (buf_end - buf != 2) goto invalid; if ((buf = ms_read_fixint(buf, 2, &offset_min)) == NULL) goto invalid; if (offset_hour > 23 || offset_min > 59) goto invalid; offset *= (offset_hour * 60 + offset_min); } if (offset == 0) { tz = PyDateTime_TimeZone_UTC; Py_INCREF(tz); } else { tz = timezone_from_offset(offset); if (tz == NULL) goto error; } } else { tz = Py_None; Py_INCREF(tz); } /* Ensure all numbers are valid */ if (year == 0) goto invalid; if (month == 0 || month > 12) goto invalid; if (day == 0 || day > days_in_month(year, month)) goto invalid; if (hour > 23) goto invalid; if (minute > 59) goto invalid; if (second > 59) goto invalid; if (MS_UNLIKELY(round_up_micros)) { if ( datetime_round_up_micros( &year, &month, &day, &hour, &minute, &second, µsecond ) < 0 ) goto invalid; } if (!ms_passes_tz_constraint(tz, type, path)) goto error; PyObject *out = PyDateTimeAPI->DateTime_FromDateAndTime( year, month, day, hour, minute, second, microsecond, tz, PyDateTimeAPI->DateTimeType ); Py_XDECREF(tz); return out; invalid: ms_error_with_path("Invalid RFC3339 encoded datetime%U", path); error: Py_XDECREF(tz); return NULL; } /* Requires 26 bytes of scratch space */ static int ms_encode_timedelta(PyObject *obj, char *out) { const char *start = out; int days = PyDateTime_DELTA_GET_DAYS(obj); int secs = PyDateTime_DELTA_GET_SECONDS(obj); int micros = PyDateTime_DELTA_GET_MICROSECONDS(obj); if (days < 0) { *out++ = '-'; days = -days; if (secs != 0 || micros != 0) { days--; if (micros != 0) { micros = 1000000 - micros; secs += 1; } secs = 86400 - secs; } } *out++ = 'P'; if (days != 0) { out = write_u64(days, out); *out++ = 'D'; } if (secs != 0 || micros != 0) { *out++ = 'T'; out = write_u64(secs, out); if (micros != 0) { *out++ = '.'; write_u32_6_digits(micros, out); out += 6; while (*(out - 1) == '0') { out--; } } *out++ = 'S'; } else if (days == 0) { *out++ = '0'; *out++ = 'D'; } return out - start; } #define MS_TIMEDELTA_MAX_SECONDS (86399999999999LL) #define MS_TIMEDELTA_MIN_SECONDS (-86399999913600LL) static PyObject * ms_timedelta_from_parts(int64_t secs, int micros) { int64_t days = secs / (24 * 60 * 60); secs -= days * (24 * 60 * 60); return PyDelta_FromDSU(days, secs, micros); } static PyObject * ms_decode_timedelta_from_uint64(uint64_t x, PathNode *path) { if (x > (uint64_t)MS_TIMEDELTA_MAX_SECONDS) { return ms_error_with_path("Duration is out of range%U", path); } return ms_timedelta_from_parts((int64_t)x, 0); } static PyObject * ms_decode_timedelta_from_int64(int64_t x, PathNode *path) { if ((x > MS_TIMEDELTA_MAX_SECONDS) || (x < MS_TIMEDELTA_MIN_SECONDS)) { return ms_error_with_path("Duration is out of range%U", path); } return ms_timedelta_from_parts(x, 0); } static PyObject * ms_decode_timedelta_from_float(double x, PathNode *path) { if ( (!isfinite(x)) || (x > (double)MS_TIMEDELTA_MAX_SECONDS) || (x < (double)MS_TIMEDELTA_MIN_SECONDS) ) { return ms_error_with_path("Duration is out of range%U", path); } int64_t secs = trunc(x); long micros = lround(1000000 * (x - secs)); return ms_timedelta_from_parts(secs, micros); } enum timedelta_parse_state { TIMEDELTA_START = 0, TIMEDELTA_D = 1, TIMEDELTA_T = 2, TIMEDELTA_H = 3, TIMEDELTA_M = 4, TIMEDELTA_S = 5, }; /* Parses a timedelta from an extended ISO8601 Duration. We try to follow the * ISO8601-2 spec as closely as possible, extrapolating as needed when the spec * is vague. We've also limited support for some units/ranges as needed to fit * python's timedelta model. * * Values parsed here are compatible with Java's `Time.Duration.parse`, as well * as the proposed javascript `Temporal.Duration.from` API. * * We accept the following format: [-/+]P#DT#H#M#S * * where # is a number with optional decimal component. Characters are case * insensitive. * * Additional restrictions, mostly taken from the ISO spec. Extrapolations or * self-imposed restrictions are noted. * * - The units D (days), H (hours), M (minutes) and S (seconds) may be omitted * if their value is 0. * * - At least one value must be present (`P0D` is a valid 0 duration, but `P` * is not). * * - If present, the values must be in the proper unit order (D, H, M, S). * * - If a unit value contains a fractional number, it must be the last unit. * `PT1H1.5S` and `PT1.5H` are valid but `PT1.5H1S` is not. * * - Unlike JSON numbers, leading 0s are fine. `P001D` and `P1D` are * equivalent. * * - If `T` is present, there must be at least one time component after it. * This isn't explicitly said in the spec, but is enforced by both Java and * Temporal APIs. * * - A leading `-` or `+` may be used to indicate a negative or positive * duration. This is part of the extended spec in ISO8601-2, and is supported * by both Java and Temporal apis. * * - We don't support relative duration units (Y (year), M (month), W (week)). * Python's timedeltas are absolute deltas composed of fixed-length days, * seconds, and microseconds. There's no way to accurately store a relative * quantity like "months". Java's Duration implementation has the same * restriction. * * - This implementation will error for durations that exceed python's * timedelta range limits. The ISO spec provides no restrictions on duration * range. */ static PyObject * ms_decode_timedelta( const char *p, Py_ssize_t size, TypeNode *type, PathNode *path ) { bool neg = false; const char *end = p + size; if (p == end) goto invalid; if (*p == '-') { neg = true; p++; if (p == end) goto invalid; } else if (*p == '+') { p++; if (p == end) goto invalid; } if (*p != 'P' && *p != 'p') goto invalid; p++; if (p == end) goto invalid; int64_t seconds = 0; int micros = 0; enum timedelta_parse_state parse_state = TIMEDELTA_START; while (true) { if (p == end) goto invalid; /* Missing segment */ if (*p == 'T' || *p == 't') { if (parse_state >= TIMEDELTA_T) goto invalid; parse_state = TIMEDELTA_T; p++; continue; } uint32_t scale; bool has_frac = false; uint64_t x = 0, frac_num = 0, frac_den = 10; /* Read integral part */ if (!is_digit(*p)) goto invalid; x = *p - '0'; p++; while (true) { if (p == end) goto invalid; /* missing unit */ if (!is_digit(*p)) break; x = x * 10 + (uint64_t)(*p - '0'); if (x > (1ULL << 47)) goto out_of_range; p++; } if (*p == '.') { /* Read fractional part */ has_frac = true; p++; if (p == end) goto invalid; if (!is_digit(*p)) goto invalid; frac_num = *p - '0'; p++; /* Parse up to 10 more decimal digits. * * Since the largest unit we support is days, and python's * timedelta has microsecond precision, only 11 decimal digits need * to be read. Any further precision will have no effect on the * output. */ for (int i = 0; i < 10; i++) { if (p == end) goto invalid; /* missing unit */ if (!is_digit(*p)) goto parse_unit; frac_num = frac_num * 10 + (uint64_t)(*p - '0'); frac_den *= 10; p++; } /* Remaining digits won't have any effect on output, skip them */ while (true) { if (p == end) goto invalid; /* missing unit */ if (!is_digit(*p)) goto parse_unit; p++; } } parse_unit: switch (*p++) { case 'D': case 'd': { if (parse_state >= TIMEDELTA_D) goto invalid; parse_state = TIMEDELTA_D; scale = 24 * 60 * 60; break; }; case 'H': case 'h': { if (parse_state < TIMEDELTA_T || parse_state >= TIMEDELTA_H) goto invalid; parse_state = TIMEDELTA_H; scale = 60 * 60; break; } case 'M': case 'm': { if (parse_state < TIMEDELTA_T) goto unsupported; if (parse_state >= TIMEDELTA_M) goto invalid; parse_state = TIMEDELTA_M; scale = 60; break; }; case 'S': case 's': { if (parse_state < TIMEDELTA_T || parse_state >= TIMEDELTA_S) goto invalid; parse_state = TIMEDELTA_S; scale = 1; break; }; case 'W': case 'w': case 'Y': case 'y': goto unsupported; default: goto invalid; } /* Apply integral part */ seconds += scale * x; if (has_frac) { /* Apply fractional part */ frac_num *= scale; int64_t extra_secs = frac_num / frac_den; int extra_micros = DIV_ROUND_CLOSEST(1000000 * (frac_num - (extra_secs * frac_den)), frac_den); micros += extra_micros; if (micros >= 1000000) { extra_secs++; micros -= 1000000; } seconds += extra_secs; } /* Ensure seconds are still in-bounds */ if (seconds > MS_TIMEDELTA_MAX_SECONDS) goto out_of_range; if (p == end) { break; } else if (has_frac) { goto invalid; /* decimal segment must be last */ } } if (neg) { seconds = -seconds; if (micros) { micros = 1000000 - micros; seconds -= 1; } /* abs(lower_limit) < upper_limit, so we need to recheck it here */ if (seconds < MS_TIMEDELTA_MIN_SECONDS) goto out_of_range; } int64_t days = seconds / (24 * 60 * 60); seconds -= days * (24 * 60 * 60); return PyDelta_FromDSU(days, seconds, micros); invalid: return ms_error_with_path("Invalid ISO8601 duration%U", path); out_of_range: return ms_error_with_path("Duration is out of range%U", path); unsupported: return ms_error_with_path( "Only units 'D', 'H', 'M', and 'S' are supported when parsing ISO8601 durations%U", path ); } /************************************************************************* * Base64 Encoder * *************************************************************************/ static Py_ssize_t ms_encode_base64_size(MsgspecState *mod, Py_ssize_t input_size) { if (input_size >= (1LL << 32)) { PyErr_SetString( mod->EncodeError, "Can't encode bytes-like objects longer than 2**32 - 1" ); return -1; } /* ceil(4/3 * input_size) */ return 4 * ((input_size + 2) / 3); } static void ms_encode_base64(const char *input, Py_ssize_t input_size, char *out) { int nbits = 0; unsigned int charbuf = 0; for (; input_size > 0; input_size--, input++) { charbuf = (charbuf << 8) | (unsigned char)(*input); nbits += 8; while (nbits >= 6) { unsigned char ind = (charbuf >> (nbits - 6)) & 0x3f; nbits -= 6; *out++ = base64_encode_table[ind]; } } if (nbits == 2) { *out++ = base64_encode_table[(charbuf & 3) << 4]; *out++ = '='; *out++ = '='; } else if (nbits == 4) { *out++ = base64_encode_table[(charbuf & 0xf) << 2]; *out++ = '='; } } /************************************************************************* * UUID Utilities * *************************************************************************/ static int ms_uuid_to_16_bytes(MsgspecState *mod, PyObject *obj, unsigned char *buf) { PyObject *int128 = PyObject_GetAttr(obj, mod->str_int); if (int128 == NULL) return -1; if (MS_UNLIKELY(!PyLong_CheckExact(int128))) { PyErr_SetString(PyExc_TypeError, "uuid.int must be an int"); return -1; } #if PY313_PLUS int out = (int)PyLong_AsNativeBytes( int128, buf, 16, Py_ASNATIVEBYTES_BIG_ENDIAN | Py_ASNATIVEBYTES_UNSIGNED_BUFFER ); #else int out = _PyLong_AsByteArray((PyLongObject *)int128, buf, 16, 0, 0); #endif Py_DECREF(int128); return out; } static PyObject * ms_uuid_from_16_bytes(const unsigned char *buf) { PyObject *int128 = _PyLong_FromByteArray(buf, 16, 0, 0); if (int128 == NULL) return NULL; MsgspecState *mod = msgspec_get_global_state(); PyTypeObject *uuid_type = (PyTypeObject *)(mod->UUIDType); PyObject *out = uuid_type->tp_alloc(uuid_type, 0); if (out == NULL) goto error; /* UUID objects are immutable, use GenericSetAttr instead of SetAttr */ if (PyObject_GenericSetAttr(out, mod->str_int, int128) < 0) goto error; if (PyObject_GenericSetAttr(out, mod->str_is_safe, mod->uuid_safeuuid_unknown) < 0) goto error; Py_DECREF(int128); return out; error: Py_DECREF(int128); Py_XDECREF(out); return NULL; } /* Requires up to 36 bytes of space */ static int ms_encode_uuid(MsgspecState *mod, PyObject *obj, char *out, bool canonical) { unsigned char scratch[16]; unsigned char *buf = scratch; if (ms_uuid_to_16_bytes(mod, obj, scratch) < 0) return -1; for (int i = 0; i < 4; i++) { unsigned char c = *buf++; *out++ = hex_encode_table[c >> 4]; *out++ = hex_encode_table[c & 0xF]; } if (canonical) *out++ = '-'; for (int j = 0; j < 3; j++) { for (int i = 0; i < 2; i++) { unsigned char c = *buf++; *out++ = hex_encode_table[c >> 4]; *out++ = hex_encode_table[c & 0xF]; } if (canonical) *out++ = '-'; } for (int i = 0; i < 6; i++) { unsigned char c = *buf++; *out++ = hex_encode_table[c >> 4]; *out++ = hex_encode_table[c & 0xF]; } return 0; } static PyObject * ms_decode_uuid_from_str(const char *buf, Py_ssize_t size, PathNode *path) { unsigned char scratch[16]; unsigned char *decoded = scratch; int segments[] = {4, 2, 2, 2, 6}; /* A valid uuid is 32 or 36 characters in length */ if (size != 32 && size != 36) goto invalid; bool has_hyphens = size == 36; for (int i = 0; i < 5; i++) { for (int j = 0; j < segments[i]; j++) { char hi = *buf++; if (hi >= '0' && hi <= '9') { hi -= '0'; } else if (hi >= 'a' && hi <= 'f') { hi = hi - 'a' + 10; } else if (hi >= 'A' && hi <= 'F') { hi = hi - 'A' + 10; } else { goto invalid; } char lo = *buf++; if (lo >= '0' && lo <= '9') { lo -= '0'; } else if (lo >= 'a' && lo <= 'f') { lo = lo - 'a' + 10; } else if (lo >= 'A' && lo <= 'F') { lo = lo - 'A' + 10; } else { goto invalid; } *decoded++ = ((unsigned char)hi << 4) + (unsigned char)lo; } if (has_hyphens && i < 4 && *buf++ != '-') goto invalid; } return ms_uuid_from_16_bytes(scratch); invalid: return ms_error_with_path("Invalid UUID%U", path); } static PyObject * ms_decode_uuid_from_bytes(const char *buf, Py_ssize_t size, PathNode *path) { if (size == 16) { return ms_uuid_from_16_bytes((unsigned char *)buf); } return ms_error_with_path("Invalid UUID bytes%U", path); } /************************************************************************* * Decimal Utilities * *************************************************************************/ static PyObject * ms_decode_decimal_from_pyobj(PyObject *str, PathNode *path, MsgspecState *mod) { if (mod == NULL) { mod = msgspec_get_global_state(); } return PyObject_CallOneArg(mod->DecimalType, str); } static PyObject * ms_decode_decimal_from_pystr(PyObject *str, PathNode *path, MsgspecState *mod) { PyObject *out = ms_decode_decimal_from_pyobj(str, path, mod); if (out == NULL) { ms_error_with_path("Invalid decimal string%U", path); } return out; } static PyObject * ms_decode_decimal( const char *view, Py_ssize_t size, bool is_ascii, PathNode *path, MsgspecState *mod ) { PyObject *str; if (MS_LIKELY(is_ascii)) { str = PyUnicode_New(size, 127); if (str == NULL) return NULL; memcpy(ascii_get_buffer(str), view, size); } else { str = PyUnicode_DecodeUTF8(view, size, NULL); if (str == NULL) return NULL; } PyObject *out = ms_decode_decimal_from_pystr(str, path, mod); Py_DECREF(str); return out; } static PyObject * ms_decode_decimal_from_int64(int64_t x, PathNode *path) { PyObject *temp = PyLong_FromLongLong(x); if (temp == NULL) return NULL; PyObject *out = ms_decode_decimal_from_pyobj(temp, path, NULL); Py_DECREF(temp); return out; } static PyObject * ms_decode_decimal_from_uint64(uint64_t x, PathNode *path) { PyObject *temp = PyLong_FromUnsignedLongLong(x); if (temp == NULL) return NULL; PyObject *out = ms_decode_decimal_from_pyobj(temp, path, NULL); Py_DECREF(temp); return out; } static PyObject * ms_decode_decimal_from_float(double val, PathNode *path, MsgspecState *mod) { if (MS_LIKELY(isfinite(val))) { /* For finite values, render as the nearest IEEE754 double in string * form, then call decimal.Decimal to parse */ char buf[24]; int n = write_f64(val, buf, false); return ms_decode_decimal(buf, n, true, path, mod); } else { /* For nonfinite values, convert to float obj and go through python */ PyObject *temp = PyFloat_FromDouble(val); if (temp == NULL) return NULL; PyObject *out = ms_decode_decimal_from_pyobj(temp, path, mod); Py_DECREF(temp); return out; } } /************************************************************************* * strict=False Utilities * *************************************************************************/ static bool maybe_parse_number( const char *, Py_ssize_t, TypeNode *, PathNode *, bool, PyObject ** ); static PyObject * ms_decode_str_lax( const char *view, Py_ssize_t size, TypeNode *type, PathNode *path, bool *invalid ) { if (type->types & ( MS_TYPE_INT | MS_TYPE_INTENUM | MS_TYPE_INTLITERAL | MS_TYPE_BOOL | MS_TYPE_FLOAT | MS_TYPE_DECIMAL | MS_TYPE_DATETIME | MS_TYPE_TIMEDELTA ) ) { PyObject *out; if (maybe_parse_number(view, size, type, path, false, &out)) { return out; } } if (type->types & MS_TYPE_BOOL) { if (size == 4) { if ( (view[0] == 't' || view[0] == 'T') && (view[1] == 'r' || view[1] == 'R') && (view[2] == 'u' || view[2] == 'U') && (view[3] == 'e' || view[3] == 'E') ) { Py_RETURN_TRUE; } } else if (size == 5) { if ( (view[0] == 'f' || view[0] == 'F') && (view[1] == 'a' || view[1] == 'A') && (view[2] == 'l' || view[2] == 'L') && (view[3] == 's' || view[3] == 'S') && (view[4] == 'e' || view[4] == 'E') ) { Py_RETURN_FALSE; } } } if (type->types & MS_TYPE_NONE) { if (size == 4 && (view[0] == 'n' || view[0] == 'N') && (view[1] == 'u' || view[1] == 'U') && (view[2] == 'l' || view[2] == 'L') && (view[3] == 'l' || view[3] == 'L') ) { Py_RETURN_NONE; } } *invalid = true; return NULL; } /************************************************************************* * Shared Post-Decode Handlers * *************************************************************************/ static PyObject * ms_post_decode_int64( int64_t x, TypeNode *type, PathNode *path, bool strict, bool from_str ) { if (MS_LIKELY(type->types & (MS_TYPE_ANY | MS_TYPE_INT))) { return ms_decode_int(x, type, path); } else if (type->types & (MS_TYPE_INTENUM | MS_TYPE_INTLITERAL)) { return ms_decode_int_enum_or_literal_int64(x, type, path); } else if (type->types & MS_TYPE_FLOAT) { return ms_decode_float(x, type, path); } else if (type->types & MS_TYPE_DECIMAL) { return ms_decode_decimal_from_int64(x, path); } else if (!strict) { if (type->types & MS_TYPE_BOOL) { PyObject *out = ms_maybe_decode_bool_from_int64(x); if (out != NULL) return out; } if (type->types & MS_TYPE_DATETIME) { return ms_decode_datetime_from_int64(x, type, path); } if (type->types & MS_TYPE_TIMEDELTA) { return ms_decode_timedelta_from_int64(x, path); } } return ms_validation_error(from_str ? "str" : "int", type, path); } static PyObject * ms_post_decode_uint64( uint64_t x, TypeNode *type, PathNode *path, bool strict, bool from_str ) { if (MS_LIKELY(type->types & (MS_TYPE_ANY | MS_TYPE_INT))) { return ms_decode_uint(x, type, path); } else if (type->types & (MS_TYPE_INTENUM | MS_TYPE_INTLITERAL)) { return ms_decode_int_enum_or_literal_uint64(x, type, path); } else if (type->types & MS_TYPE_FLOAT) { return ms_decode_float(x, type, path); } else if (type->types & MS_TYPE_DECIMAL) { return ms_decode_decimal_from_uint64(x, path); } else if (!strict) { if (type->types & MS_TYPE_BOOL) { PyObject *out = ms_maybe_decode_bool_from_uint64(x); if (out != NULL) return out; } if (type->types & MS_TYPE_DATETIME) { return ms_decode_datetime_from_uint64(x, type, path); } if (type->types & MS_TYPE_TIMEDELTA) { return ms_decode_timedelta_from_uint64(x, path); } } return ms_validation_error(from_str ? "str" : "int", type, path); } static bool double_as_int64(double x, int64_t *out) { if (fmod(x, 1.0) != 0.0) return false; if (x > (1LL << 53)) return false; if (x < -(1LL << 53)) return false; *out = (int64_t)x; return true; } static PyObject * ms_post_decode_float( double x, TypeNode *type, PathNode *path, bool strict, bool from_str ) { if (type->types & (MS_TYPE_ANY | MS_TYPE_FLOAT)) { return ms_decode_float(x, type, path); } else if (!strict) { if (type->types & MS_TYPE_INT) { int64_t out; if (double_as_int64(x, &out)) { return ms_post_decode_int64(out, type, path, strict, from_str); } } if (type->types & MS_TYPE_DATETIME) { return ms_decode_datetime_from_float(x, type, path); } if (type->types & MS_TYPE_TIMEDELTA) { return ms_decode_timedelta_from_float(x, path); } } return ms_validation_error(from_str ? "str" : "float", type, path); } /************************************************************************* * Number Parser * *************************************************************************/ #define ONE_E18 1000000000000000000ULL #define ONE_E19_MINUS_ONE 9999999999999999999ULL static MS_NOINLINE PyObject * parse_number_fallback( const unsigned char* integer_start, const unsigned char* integer_end, const unsigned char* fraction_start, const unsigned char* fraction_end, int32_t exp_part, bool is_negative, TypeNode *type, PathNode *path, bool strict, bool from_str ) { uint32_t nd = 0; int32_t dp = 0; ms_hpd dec; dec.num_digits = 0; dec.decimal_point = 0; dec.negative = is_negative; dec.truncated = false; /* Parse integer */ const unsigned char *p = integer_start; if (*p != '0') { while (p < integer_end) { if (MS_LIKELY(nd < MS_HPD_MAX_DIGITS)) { dec.digits[nd++] = (uint8_t)(*p - '0'); } else if (*p != '0') { dec.truncated = true; } dp++; p++; } } p = fraction_start; while (p < fraction_end) { if (*p == '0') { if (nd == 0) { /* Track leading zeros implicitly */ dp--; } else if (nd < MS_HPD_MAX_DIGITS) { dec.digits[nd++] = (uint8_t)(*p - '0'); } } else if ('1' <= *p && *p <= '9') { if (nd < MS_HPD_MAX_DIGITS) { dec.digits[nd++] = (uint8_t)(*p - '0'); } else { dec.truncated = true; } } p++; } dp += exp_part; dec.num_digits = nd; if (dp < -MS_HPD_DP_RANGE) { dec.decimal_point = -(MS_HPD_DP_RANGE + 1); } else if (dp > MS_HPD_DP_RANGE) { dec.decimal_point = (MS_HPD_DP_RANGE + 1); } else { dec.decimal_point = dp; } ms_hpd_trim(&dec); double res = ms_hpd_to_double(&dec); if (Py_IS_INFINITY(res)) { return ms_error_with_path("Number out of range%U", path); } return ms_post_decode_float(res, type, path, strict, from_str); } static MS_NOINLINE PyObject * parse_number_nonfinite( const unsigned char *start, bool is_negative, const unsigned char *p, const unsigned char *pend, const char **errmsg, TypeNode *type, PathNode *path, bool strict ) { size_t size = pend - p; double val; if (size == 3) { if ( (p[0] == 'n' || p[0] == 'N') && (p[1] == 'a' || p[1] == 'A') && (p[2] == 'n' || p[2] == 'N') ) { val = NAN; goto done; } else if ( (p[0] == 'i' || p[0] == 'I') && (p[1] == 'n' || p[1] == 'N') && (p[2] == 'f' || p[2] == 'F') ) { val = INFINITY; goto done; } } else if (size == 8) { if ( (p[0] == 'i' || p[0] == 'I') && (p[1] == 'n' || p[1] == 'N') && (p[2] == 'f' || p[2] == 'F') && (p[3] == 'i' || p[3] == 'I') && (p[4] == 'n' || p[4] == 'N') && (p[5] == 'i' || p[5] == 'I') && (p[6] == 't' || p[6] == 'T') && (p[7] == 'y' || p[7] == 'Y') ) { val = INFINITY; goto done; } } *errmsg = "invalid number"; return NULL; done: if ( MS_UNLIKELY( !(type->types & (MS_TYPE_ANY | MS_TYPE_FLOAT)) && type->types & MS_TYPE_DECIMAL ) ) { return ms_decode_decimal( (char *)start, pend - start, true, path, NULL ); } if (is_negative) { val = -val; } return ms_post_decode_float(val, type, path, strict, true); } static MS_NOINLINE PyObject * json_float_hook( const char *buf, Py_ssize_t size, PathNode *path, PyObject *float_hook ) { PyObject *str = PyUnicode_New(size, 127); if (str == NULL) return NULL; memcpy(ascii_get_buffer(str), buf, size); PyObject *out = PyObject_CallOneArg(float_hook, str); Py_DECREF(str); if (out == NULL) { ms_maybe_wrap_validation_error(path); return NULL; } return out; } static MS_INLINE PyObject * parse_number_inline( const unsigned char *p, const unsigned char *pend, const unsigned char **pout, const char **errmsg, TypeNode *type, PathNode *path, bool strict, PyObject *float_hook, bool from_str ) { uint64_t mantissa = 0; int64_t exponent = 0; int32_t exp_part = 0; bool is_negative = false; bool is_float = false; bool is_truncated = false; const unsigned char *start = p; /* We know there is at least one byte available when this function is * called */ if (*p == '-') { /* Parse minus sign */ p++; if (p == pend) goto invalid_number; is_negative = true; } const unsigned char *integer_start = p; /* Parse integer */ if (MS_UNLIKELY(*p == '0')) { p++; if (MS_UNLIKELY(p != pend && is_digit(*p))) goto invalid_number; } else { unsigned char c = *p; while (MS_LIKELY(is_digit(c))) { mantissa = mantissa * 10 + (uint8_t)(c - '0'); p++; if (MS_UNLIKELY(p == pend)) break; c = *p; } /* There must be at least one digit */ if (MS_UNLIKELY(integer_start == p)) { if (MS_UNLIKELY(from_str)) { return parse_number_nonfinite( start, is_negative, p, pend, errmsg, type, path, strict ); } else { goto invalid_character; } } } const unsigned char *integer_end = p; int64_t digit_count = integer_end - integer_start; const unsigned char *fraction_start = NULL; const unsigned char *fraction_end = NULL; if (MS_UNLIKELY(p == pend)) goto end_parsing; if (*p == '.') { is_float = true; p++; /* Parse fraction */ fraction_start = p; while (MS_LIKELY(p != pend && is_digit(*p))) { mantissa = mantissa * 10 + (uint8_t)(*p - '0'); p++; } /* Error if no digits after decimal */ if (MS_UNLIKELY(fraction_start == p)) goto invalid_number; fraction_end = p; exponent = fraction_start - p; digit_count -= exponent; if (MS_UNLIKELY(p == pend)) goto end_parsing; } if (*p == 'e' || *p == 'E') { is_float = true; int32_t exp_sign = 1; p++; if (p == pend) goto invalid_number; /* Parse exponent sign (if any) */ if (*p == '+') { p++; } else if (*p == '-') { p++; exp_sign = -1; } /* Parse exponent digits */ const unsigned char *start_exponent = p; while (p != pend && is_digit(*p)) { if (MS_LIKELY(exp_part < 10000)) { exp_part = exp_part * 10 + (uint8_t)(*p - '0'); } p++; } /* Error if no digits in exponent */ if (MS_UNLIKELY(start_exponent == p)) goto invalid_number; exp_part *= exp_sign; exponent += exp_part; } if (MS_UNLIKELY(from_str)) { if (MS_UNLIKELY(p != pend)) goto invalid_number; } end_parsing: /* Check for overflow and maybe reparse if needed */ if (MS_UNLIKELY(digit_count > 19)) { const unsigned char *cur = integer_start; while ((cur != pend) && (*cur == '0' || *cur == '.')) { if (*cur == '0') { digit_count--; } cur++; } if ( (digit_count > 19) && ( (is_float) || ((integer_end - integer_start) != 20) || (*integer_start != '1') || (mantissa <= ONE_E19_MINUS_ONE) ) ) { /* We overflowed. Redo parsing, truncating at 19 digits */ is_truncated = true; const unsigned char *cur = integer_start; mantissa = 0; while ((mantissa < ONE_E18) && (cur != integer_end)) { mantissa = mantissa * 10 + (uint64_t)(*cur - '0'); cur++; } if (mantissa >= ONE_E18) { exponent = integer_end - cur + exp_part; } else { cur = fraction_start; while ((mantissa < ONE_E18) && (cur != fraction_end)) { mantissa = mantissa * 10 + (uint64_t)(*cur - '0'); cur++; } exponent = fraction_start - cur + exp_part; } } } /* Forward output position */ *pout = p; if (!is_float) { if (is_negative) { is_truncated |= (mantissa > (1ull << 63)); } if (MS_UNLIKELY(is_truncated)) { if (type->types & (MS_TYPE_ANY | MS_TYPE_INT)) { return ms_decode_bigint((char *)start, p - start, type, path); } } else { if (is_negative) { return ms_post_decode_int64( -1 * (int64_t)(mantissa), type, path, strict, from_str ); } else { return ms_post_decode_uint64(mantissa, type, path, strict, from_str); } } } if ( MS_UNLIKELY( !(type->types & (MS_TYPE_ANY | MS_TYPE_FLOAT)) && type->types & MS_TYPE_DECIMAL ) ) { return ms_decode_decimal( (char *)start, p - start, true, path, NULL ); } else if (MS_UNLIKELY(float_hook != NULL && type->types & MS_TYPE_ANY)) { return json_float_hook((char *)start, p - start, path, float_hook); } else { if (MS_UNLIKELY(exponent > 288 || exponent < -307)) { /* Exponent is out of bounds */ goto fallback; } double val; if (MS_LIKELY((-22 <= exponent) && (exponent <= 22) && ((mantissa >> 53) == 0))) { /* If both `mantissa` and `10 ** exponent` can be exactly * represented as a double, we can take a fast path */ val = (double)(mantissa); if (exponent >= 0) { val *= ms_atof_f64_powers_of_10[exponent]; } else { val /= ms_atof_f64_powers_of_10[-exponent]; } } else if (MS_UNLIKELY(mantissa == 0)) { /* Special case 0 handling. This is only hit if the mantissa is 0 * and the exponent is out of bounds above (i.e. rarely) */ val = 0.0; } else { int64_t r1 = eisel_lemire(mantissa, exponent); if (MS_UNLIKELY(r1 < 0)) goto fallback; if (MS_UNLIKELY(is_truncated)) { int64_t r2 = eisel_lemire(mantissa + 1, exponent); if (r1 != r2) goto fallback; } uint64_t bits = ((uint64_t)r1); memcpy(&val, &bits, sizeof(double)); } if (is_negative) { val = -val; } return ms_post_decode_float(val, type, path, strict, from_str); } fallback: return parse_number_fallback( integer_start, integer_end, fraction_start, fraction_end, exp_part, is_negative, type, path, strict, from_str ); invalid_number: if (pout != NULL) *pout = p; *errmsg = "invalid number"; return NULL; invalid_character: if (pout != NULL) *pout = p; *errmsg = "invalid character"; return NULL; } static MS_NOINLINE bool maybe_parse_number( const char *view, Py_ssize_t size, TypeNode *type, PathNode *path, bool strict, PyObject **out ) { const char *errmsg = NULL; const unsigned char *pout; *out = parse_number_inline( (const unsigned char *)view, (const unsigned char *)(view + size), &pout, &errmsg, type, path, strict, NULL, true ); return (*out != NULL || errmsg == NULL); } /************************************************************************* * MessagePack Encoder * *************************************************************************/ PyDoc_STRVAR(Encoder__doc__, "Encoder(*, enc_hook=None, decimal_format='string', uuid_format='canonical', order=None)\n" "--\n" "\n" "A MessagePack encoder.\n" "\n" "Parameters\n" "----------\n" "enc_hook : callable, optional\n" " A callable to call for objects that aren't supported msgspec types. Takes\n" " the unsupported object and should return a supported object, or raise a\n" " ``NotImplementedError`` if unsupported.\n" "decimal_format : {'string', 'number'} or callable, optional\n" " The format to use for encoding `decimal.Decimal` objects. If 'string'\n" " they're encoded as strings, if 'number', they're encoded as floats. If\n" " a callable is provided, it will be called with the `decimal.Decimal`\n" " object and must return a JSON-serializable value (but **not** another\n" " `decimal.Decimal` or a nested structure containing `decimal.Decimal`).\n" " Defaults to 'string', which is the recommended value since 'number' may\n" " result in precision loss when decoding.\n" "uuid_format : {'canonical', 'hex', 'bytes'}, optional\n" " The format to use for encoding `uuid.UUID` objects. The 'canonical'\n" " and 'hex' formats encode them as strings with and without hyphens\n" " respectively. The 'bytes' format encodes them as big-endian binary\n" " representations of the corresponding 128-bit integers. Defaults to\n" " 'canonical'.\n" "order : {None, 'deterministic', 'sorted'}, optional\n" " The ordering to use when encoding unordered compound types.\n" "\n" " - ``None``: All objects are encoded in the most efficient manner matching\n" " their in-memory representations. The default.\n" " - `'deterministic'`: Dict keys and set elements are sorted so that values\n" " which compare equal produce identical encoded output, regardless of\n" " insertion or iteration order. Useful when comparison/hashing of the\n" " encoded binary output is necessary.\n" " - `'sorted'`: Like `'deterministic'`, but *all* object-like types (structs,\n" " dataclasses, ...) are also sorted by field name before encoding. This is\n" " slower than `'deterministic'`, but may produce more human-readable output." ); enum mpack_code { MP_NIL = '\xc0', MP_FALSE = '\xc2', MP_TRUE = '\xc3', MP_FLOAT32 = '\xca', MP_FLOAT64 = '\xcb', MP_UINT8 = '\xcc', MP_UINT16 = '\xcd', MP_UINT32 = '\xce', MP_UINT64 = '\xcf', MP_INT8 = '\xd0', MP_INT16 = '\xd1', MP_INT32 = '\xd2', MP_INT64 = '\xd3', MP_FIXSTR = '\xa0', MP_STR8 = '\xd9', MP_STR16 = '\xda', MP_STR32 = '\xdb', MP_BIN8 = '\xc4', MP_BIN16 = '\xc5', MP_BIN32 = '\xc6', MP_FIXARRAY = '\x90', MP_ARRAY16 = '\xdc', MP_ARRAY32 = '\xdd', MP_FIXMAP = '\x80', MP_MAP16 = '\xde', MP_MAP32 = '\xdf', MP_FIXEXT1 = '\xd4', MP_FIXEXT2 = '\xd5', MP_FIXEXT4 = '\xd6', MP_FIXEXT8 = '\xd7', MP_FIXEXT16 = '\xd8', MP_EXT8 = '\xc7', MP_EXT16 = '\xc8', MP_EXT32 = '\xc9', }; static int mpack_encode_inline(EncoderState *self, PyObject *obj); static int mpack_encode_dict_key_inline(EncoderState *self, PyObject *obj); static int mpack_encode(EncoderState *self, PyObject *obj); static int mpack_encode_none(EncoderState *self) { const char op = MP_NIL; return ms_write(self, &op, 1); } static int mpack_encode_bool(EncoderState *self, PyObject *obj) { const char op = (obj == Py_True) ? MP_TRUE : MP_FALSE; return ms_write(self, &op, 1); } static MS_NOINLINE int mpack_encode_long(EncoderState *self, PyObject *obj) { bool overflow, neg; uint64_t ux; overflow = fast_long_extract_parts(obj, &neg, &ux); if (MS_UNLIKELY(overflow)) { PyErr_SetString( PyExc_OverflowError, "can't serialize ints < -2**63 or > 2**64 - 1" ); return -1; } if (MS_UNLIKELY(neg)) { int64_t x = -ux; if(x < -(1LL<<5)) { if(x < -(1LL<<15)) { if(x < -(1LL<<31)) { char buf[9]; buf[0] = MP_INT64; _msgspec_store64(&buf[1], x); return ms_write(self, buf, 9); } else { char buf[5]; buf[0] = MP_INT32; _msgspec_store32(&buf[1], (int32_t)x); return ms_write(self, buf, 5); } } else { if(x < -(1<<7)) { char buf[3]; buf[0] = MP_INT16; _msgspec_store16(&buf[1], (int16_t)x); return ms_write(self, buf, 3); } else { char buf[2] = {MP_INT8, (x & 0xff)}; return ms_write(self, buf, 2); } } } else { char buf[1] = {(x & 0xff)}; return ms_write(self, buf, 1); } } else { if (ux < (1<<7)) { char buf[1] = {(ux & 0xff)}; return ms_write(self, buf, 1); } else { if(ux < (1<<16)) { if(ux < (1<<8)) { char buf[2] = {MP_UINT8, (ux & 0xff)}; return ms_write(self, buf, 2); } else { char buf[3]; buf[0] = MP_UINT16; _msgspec_store16(&buf[1], (uint16_t)ux); return ms_write(self, buf, 3); } } else { if(ux < (1LL<<32)) { char buf[5]; buf[0] = MP_UINT32; _msgspec_store32(&buf[1], (uint32_t)ux); return ms_write(self, buf, 5); } else { char buf[9]; buf[0] = MP_UINT64; _msgspec_store64(&buf[1], ux); return ms_write(self, buf, 9); } } } } } static MS_NOINLINE int mpack_encode_float(EncoderState *self, PyObject *obj) { char buf[9]; double x = PyFloat_AS_DOUBLE(obj); uint64_t ux = 0; memcpy(&ux, &x, sizeof(double)); buf[0] = MP_FLOAT64; _msgspec_store64(&buf[1], ux); return ms_write(self, buf, 9); } static MS_NOINLINE int mpack_encode_cstr(EncoderState *self, const char *buf, Py_ssize_t len) { if (buf == NULL) { return -1; } if (len < 32) { char header[1] = {MP_FIXSTR | (uint8_t)len}; if (ms_write(self, header, 1) < 0) return -1; } else if (len < (1 << 8)) { char header[2] = {MP_STR8, (uint8_t)len}; if (ms_write(self, header, 2) < 0) return -1; } else if (len < (1 << 16)) { char header[3]; header[0] = MP_STR16; _msgspec_store16(&header[1], (uint16_t)len); if (ms_write(self, header, 3) < 0) return -1; } else if (len < (1LL << 32)) { char header[5]; header[0] = MP_STR32; _msgspec_store32(&header[1], (uint32_t)len); if (ms_write(self, header, 5) < 0) return -1; } else { PyErr_SetString( self->mod->EncodeError, "Can't encode strings longer than 2**32 - 1" ); return -1; } return len > 0 ? ms_write(self, buf, len) : 0; } static MS_INLINE int mpack_encode_str(EncoderState *self, PyObject *obj) { Py_ssize_t len; const char* buf = unicode_str_and_size(obj, &len); if (buf == NULL) return -1; return mpack_encode_cstr(self, buf, len); } static int mpack_encode_bin(EncoderState *self, const char* buf, Py_ssize_t len) { if (buf == NULL) { return -1; } if (len < (1 << 8)) { char header[2] = {MP_BIN8, (uint8_t)len}; if (ms_write(self, header, 2) < 0) return -1; } else if (len < (1 << 16)) { char header[3]; header[0] = MP_BIN16; _msgspec_store16(&header[1], (uint16_t)len); if (ms_write(self, header, 3) < 0) return -1; } else if (len < (1LL << 32)) { char header[5]; header[0] = MP_BIN32; _msgspec_store32(&header[1], (uint32_t)len); if (ms_write(self, header, 5) < 0) return -1; } else { PyErr_SetString( self->mod->EncodeError, "Can't encode bytes-like objects longer than 2**32 - 1" ); return -1; } return len > 0 ? ms_write(self, buf, len) : 0; } static int mpack_encode_bytes(EncoderState *self, PyObject *obj) { Py_ssize_t len = PyBytes_GET_SIZE(obj); const char* buf = PyBytes_AS_STRING(obj); return mpack_encode_bin(self, buf, len); } static int mpack_encode_bytearray(EncoderState *self, PyObject *obj) { Py_ssize_t len = PyByteArray_GET_SIZE(obj); int ret = 0; Py_BEGIN_CRITICAL_SECTION(obj); const char* buf = PyByteArray_AS_STRING(obj); ret = mpack_encode_bin(self, buf, len); Py_END_CRITICAL_SECTION(); return ret; } static int mpack_encode_memoryview(EncoderState *self, PyObject *obj) { int out; Py_buffer buffer; if (PyObject_GetBuffer(obj, &buffer, PyBUF_CONTIG_RO) < 0) return -1; out = mpack_encode_bin(self, buffer.buf, buffer.len); PyBuffer_Release(&buffer); return out; } static int mpack_encode_raw(EncoderState *self, PyObject *obj) { Raw *raw = (Raw *)obj; return ms_write(self, raw->buf, raw->len); } static int mpack_encode_array_header(EncoderState *self, Py_ssize_t len, const char* typname) { if (len < 16) { char header[1] = {MP_FIXARRAY | len}; if (ms_write(self, header, 1) < 0) return -1; } else if (len < (1 << 16)) { char header[3]; header[0] = MP_ARRAY16; _msgspec_store16(&header[1], (uint16_t)len); if (ms_write(self, header, 3) < 0) return -1; } else if (len < (1LL << 32)) { char header[5]; header[0] = MP_ARRAY32; _msgspec_store32(&header[1], (uint32_t)len); if (ms_write(self, header, 5) < 0) return -1; } else { PyErr_Format( self->mod->EncodeError, "Can't encode %s longer than 2**32 - 1", typname ); return -1; } return 0; } static MS_INLINE int mpack_encode_empty_array(EncoderState *self) { char header[1] = {MP_FIXARRAY}; return ms_write(self, header, 1); } static MS_NOINLINE int mpack_encode_list(EncoderState *self, PyObject *obj) { Py_ssize_t i, len; int status = 0; len = PyList_GET_SIZE(obj); if (len == 0) return mpack_encode_empty_array(self); if (mpack_encode_array_header(self, len, "list") < 0) return -1; if (Py_EnterRecursiveCall(" while serializing an object")) return -1; Py_BEGIN_CRITICAL_SECTION(obj); for (i = 0; i < len; i++) { if (mpack_encode_inline(self, PyList_GET_ITEM(obj, i)) < 0) { status = -1; break; } } Py_END_CRITICAL_SECTION(); Py_LeaveRecursiveCall(); return status; } static int mpack_encode_set(EncoderState *self, PyObject *obj) { Py_ssize_t len = 0; PyObject *item; int status = -1; len = PySet_GET_SIZE(obj); if (len == 0) return mpack_encode_empty_array(self); if (MS_UNLIKELY(self->order != ORDER_DEFAULT)) { PyObject *temp = PySequence_List(obj); if (temp == NULL) return -1; if (PyList_Sort(temp) == 0) { status = mpack_encode_list(self, temp); } Py_DECREF(temp); return status; } if (mpack_encode_array_header(self, len, "set") < 0) return -1; if (Py_EnterRecursiveCall(" while serializing an object")) return -1; PyObject *iter = PyObject_GetIter(obj); if (iter == NULL) goto cleanup; while ((item = PyIter_Next(iter))) { int status = mpack_encode_inline(self, item); Py_DECREF(item); if (status < 0) goto cleanup; } status = 0; cleanup: Py_LeaveRecursiveCall(); Py_XDECREF(iter); return status; } static int mpack_encode_tuple(EncoderState *self, PyObject *obj) { Py_ssize_t i, len; int status = 0; len = PyTuple_GET_SIZE(obj); if (len == 0) return mpack_encode_empty_array(self); if (mpack_encode_array_header(self, len, "tuples") < 0) return -1; if (Py_EnterRecursiveCall(" while serializing an object")) return -1; for (i = 0; i < len; i++) { if (mpack_encode_inline(self, PyTuple_GET_ITEM(obj, i)) < 0) { status = -1; break; } } Py_LeaveRecursiveCall(); return status; } static int mpack_encode_map_header(EncoderState *self, Py_ssize_t len, const char* typname) { if (len < 16) { char header[1] = {MP_FIXMAP | len}; if (ms_write(self, header, 1) < 0) return -1; } else if (len < (1 << 16)) { char header[3]; header[0] = MP_MAP16; _msgspec_store16(&header[1], (uint16_t)len); if (ms_write(self, header, 3) < 0) return -1; } else if (len < (1LL << 32)) { char header[5]; header[0] = MP_MAP32; _msgspec_store32(&header[1], (uint32_t)len); if (ms_write(self, header, 5) < 0) return -1; } else { PyErr_Format( self->mod->EncodeError, "Can't encode %s longer than 2**32 - 1", typname ); return -1; } return 0; } static int mpack_encode_and_free_assoclist(EncoderState *self, AssocList *list) { if (list == NULL) return -1; int status = -1; AssocList_Sort(list); if (mpack_encode_map_header(self, list->size, "dicts") < 0) goto cleanup2; if (Py_EnterRecursiveCall(" while serializing an object")) return -1; for (Py_ssize_t i = 0; i < list->size; i++) { AssocItem *item = &(list->items[i]); if (mpack_encode_cstr(self, item->key, item->key_size) < 0) goto cleanup; if (mpack_encode_inline(self, item->val) < 0) goto cleanup; } status = 0; cleanup: Py_LeaveRecursiveCall(); cleanup2: AssocList_Free(list); return status; } static MS_NOINLINE int mpack_encode_dict(EncoderState *self, PyObject *obj) { PyObject *key, *val; Py_ssize_t pos = 0; int status = -1; Py_ssize_t len = PyDict_GET_SIZE(obj); if (MS_UNLIKELY(len == 0)) { char header[1] = {MP_FIXMAP}; return ms_write(self, header, 1); } if (MS_UNLIKELY(self->order != ORDER_DEFAULT)) { return mpack_encode_and_free_assoclist(self, AssocList_FromDict(obj)); } if (mpack_encode_map_header(self, len, "dicts") < 0) return -1; if (Py_EnterRecursiveCall(" while serializing an object")) return -1; Py_BEGIN_CRITICAL_SECTION(obj); while (PyDict_Next(obj, &pos, &key, &val)) { if (mpack_encode_dict_key_inline(self, key) < 0) goto cleanup; if (mpack_encode_inline(self, val) < 0) goto cleanup; } status = 0; cleanup:; Py_END_CRITICAL_SECTION(); Py_LeaveRecursiveCall(); return status; } static int mpack_encode_dataclass(EncoderState *self, PyObject *obj, PyObject *fields) { if (MS_UNLIKELY(self->order == ORDER_SORTED)) { return mpack_encode_and_free_assoclist(self, AssocList_FromDataclass(obj, fields)); } if (Py_EnterRecursiveCall(" while serializing an object")) return -1; int status = -1; DataclassIter iter; if (!dataclass_iter_setup(&iter, obj, fields)) goto cleanup; /* Cache header offset in case we need to adjust the header after writing */ Py_ssize_t header_offset = self->output_len; Py_ssize_t max_size = PyDict_GET_SIZE(fields); if (mpack_encode_map_header(self, max_size, "objects") < 0) goto cleanup; Py_ssize_t size = 0; PyObject *field, *val; while (dataclass_iter_next(&iter, &field, &val)) { size++; Py_ssize_t field_len; const char* field_buf = unicode_str_and_size(field, &field_len); bool errored = ( (field_buf == NULL) || (mpack_encode_cstr(self, field_buf, field_len) < 0) || (mpack_encode(self, val) < 0) ); Py_DECREF(val); if (errored) goto cleanup; } if (MS_UNLIKELY(size != max_size)) { /* Some fields were skipped, need to adjust header. We write the header * using the width type of `max_size`, but the value of `size`. */ char *header_loc = self->output_buffer_raw + header_offset; if (max_size < 16) { *header_loc = MP_FIXMAP | size; } else if (max_size < (1 << 16)) { *header_loc++ = MP_MAP16; _msgspec_store16(header_loc, (uint16_t)size); } else { *header_loc++ = MP_MAP32; _msgspec_store32(header_loc, (uint32_t)size); } } status = 0; cleanup: Py_LeaveRecursiveCall(); dataclass_iter_cleanup(&iter); return status; } /* This method encodes an object as a map, with fields taken from `__dict__`, * followed by all `__slots__` in the class hierarchy. Any unset slots are * ignored, and `__weakref__` is not included. */ static int mpack_encode_object(EncoderState *self, PyObject *obj) { if (MS_UNLIKELY(self->order == ORDER_SORTED)) { return mpack_encode_and_free_assoclist(self, AssocList_FromObject(obj)); } int status = -1; Py_ssize_t size = 0, max_size; if (Py_EnterRecursiveCall(" while serializing an object")) return -1; /* Calculate the maximum number of fields that could be part of this object. * This is roughly equal to: * max_size = size = len(getattr(obj, '__dict__', {})) * max_size += sum(len(getattr(c, '__slots__', ())) for c in type(obj).mro()) */ PyObject *dict = PyObject_GenericGetDict(obj, NULL); if (MS_UNLIKELY(dict == NULL)) { PyErr_Clear(); max_size = 0; } else { max_size = PyDict_GET_SIZE(dict); } PyTypeObject *type = Py_TYPE(obj); while (type != NULL) { max_size += Py_SIZE(type); type = type->tp_base; } /* Cache header offset in case we need to adjust the header after writing */ Py_ssize_t header_offset = self->output_len; if (mpack_encode_map_header(self, max_size, "objects") < 0) goto cleanup; Py_BEGIN_CRITICAL_SECTION(obj); /* First encode everything in `__dict__` */ if (dict != NULL) { PyObject *key, *val; Py_ssize_t pos = 0; int err = 0; Py_BEGIN_CRITICAL_SECTION(dict); while (PyDict_Next(dict, &pos, &key, &val)) { if (MS_LIKELY(PyUnicode_CheckExact(key))) { Py_ssize_t key_len; if (MS_UNLIKELY(val == UNSET)) continue; const char* key_buf = unicode_str_and_size(key, &key_len); if (MS_UNLIKELY(key_buf == NULL)) { err = 1; break; } if (MS_UNLIKELY(*key_buf == '_')) continue; if (MS_UNLIKELY(mpack_encode_cstr(self, key_buf, key_len) < 0)) { err = 1; break; } if (MS_UNLIKELY(mpack_encode(self, val) < 0)) { err = 1; break; } size++; } } Py_END_CRITICAL_SECTION(); if (MS_UNLIKELY(err)) goto cleanup; } /* Then encode everything in slots */ type = Py_TYPE(obj); while (type != NULL) { Py_ssize_t n = Py_SIZE(type); if (n) { PyMemberDef *mp = MS_PyHeapType_GET_MEMBERS((PyHeapTypeObject *)type); for (Py_ssize_t i = 0; i < n; i++, mp++) { if (MS_LIKELY(mp->type == T_OBJECT_EX && !(mp->flags & READONLY))) { char *addr = (char *)obj + mp->offset; PyObject *val = *(PyObject **)addr; if (MS_UNLIKELY(val == UNSET)) continue; if (MS_UNLIKELY(val == NULL)) continue; if (MS_UNLIKELY(*mp->name == '_')) continue; if (MS_UNLIKELY(mpack_encode_cstr(self, mp->name, strlen(mp->name)) < 0)) goto cleanup; if (MS_UNLIKELY(mpack_encode(self, val) < 0)) goto cleanup; size++; } } } type = type->tp_base; } if (MS_UNLIKELY(size != max_size)) { /* Some fields were NULL, need to adjust header. We write the header * using the width type of `max_size`, but the value of `size`. */ char *header_loc = self->output_buffer_raw + header_offset; if (max_size < 16) { *header_loc = MP_FIXMAP | size; } else if (max_size < (1 << 16)) { *header_loc++ = MP_MAP16; _msgspec_store16(header_loc, (uint16_t)size); } else { *header_loc++ = MP_MAP32; _msgspec_store32(header_loc, (uint32_t)size); } } status = 0; cleanup: Py_XDECREF(dict); Py_END_CRITICAL_SECTION(); Py_LeaveRecursiveCall(); return status; } static int mpack_encode_struct_array( EncoderState *self, StructMetaObject *struct_type, PyObject *obj ) { int status = -1; PyObject *tag_value = struct_type->struct_tag_value; int tagged = tag_value != NULL; PyObject *fields = struct_type->struct_encode_fields; Py_ssize_t nfields = PyTuple_GET_SIZE(fields); Py_ssize_t len = nfields + tagged; if (Py_EnterRecursiveCall(" while serializing an object")) return -1; if (mpack_encode_array_header(self, len, "structs") < 0) goto cleanup; if (tagged) { if (mpack_encode(self, tag_value) < 0) goto cleanup; } for (Py_ssize_t i = 0; i < nfields; i++) { PyObject *val = Struct_get_index(obj, i); if (val == NULL || mpack_encode(self, val) < 0) goto cleanup; } status = 0; cleanup: Py_LeaveRecursiveCall(); return status; } static int mpack_encode_struct_object( EncoderState *self, StructMetaObject *struct_type, PyObject *obj ) { if (MS_UNLIKELY(self->order == ORDER_SORTED)) { return mpack_encode_and_free_assoclist(self, AssocList_FromStruct(obj)); } int status = -1; PyObject *tag_field = struct_type->struct_tag_field; PyObject *tag_value = struct_type->struct_tag_value; int tagged = tag_value != NULL; PyObject *fields = struct_type->struct_encode_fields; Py_ssize_t nfields = PyTuple_GET_SIZE(fields); Py_ssize_t len = nfields + tagged; if (Py_EnterRecursiveCall(" while serializing an object")) return -1; Py_ssize_t header_offset = self->output_len; if (mpack_encode_map_header(self, len, "structs") < 0) goto cleanup; if (tagged) { if (mpack_encode_str(self, tag_field) < 0) goto cleanup; if (mpack_encode(self, tag_value) < 0) goto cleanup; } Py_ssize_t nunchecked = nfields, actual_len = len; if (struct_type->omit_defaults == OPT_TRUE) { nunchecked -= PyTuple_GET_SIZE(struct_type->struct_defaults); } for (Py_ssize_t i = 0; i < nunchecked; i++) { PyObject *key = PyTuple_GET_ITEM(fields, i); PyObject *val = Struct_get_index(obj, i); if (MS_UNLIKELY(val == NULL)) goto cleanup; if (MS_UNLIKELY(val == UNSET)) { actual_len--; } else { if (mpack_encode_str(self, key) < 0) goto cleanup; if (mpack_encode(self, val) < 0) goto cleanup; } } for (Py_ssize_t i = nunchecked; i < nfields; i++) { PyObject *key = PyTuple_GET_ITEM(fields, i); PyObject *val = Struct_get_index(obj, i); if (val == NULL) goto cleanup; PyObject *default_val = PyTuple_GET_ITEM( struct_type->struct_defaults, i - nunchecked ); if (val == UNSET || is_default(val, default_val)) { actual_len--; } else { if (mpack_encode_str(self, key) < 0) goto cleanup; if (mpack_encode(self, val) < 0) goto cleanup; } } if (MS_UNLIKELY(actual_len != len)) { /* Fixup the header length after we know how many fields were * actually written */ char *header_loc = self->output_buffer_raw + header_offset; if (len < 16) { *header_loc = MP_FIXMAP | actual_len; } else if (len < (1 << 16)) { *header_loc++ = MP_MAP16; _msgspec_store16(header_loc, (uint16_t)actual_len); } else { *header_loc++ = MP_MAP32; _msgspec_store32(header_loc, (uint32_t)actual_len); } } status = 0; cleanup: Py_LeaveRecursiveCall(); return status; } static int mpack_encode_struct(EncoderState *self, PyObject *obj) { StructMetaObject *struct_type = (StructMetaObject *)Py_TYPE(obj); if (struct_type->array_like == OPT_TRUE) { return mpack_encode_struct_array(self, struct_type, obj); } return mpack_encode_struct_object(self, struct_type, obj); } static int mpack_encode_ext(EncoderState *self, PyObject *obj) { Ext *ex = (Ext *)obj; Py_ssize_t len; int status = -1, header_len = 2; char header[6]; const char* data; Py_buffer buffer; buffer.buf = NULL; if (PyBytes_CheckExact(ex->data)) { len = PyBytes_GET_SIZE(ex->data); data = PyBytes_AS_STRING(ex->data); } else if (PyByteArray_CheckExact(ex->data)) { len = PyByteArray_GET_SIZE(ex->data); data = PyByteArray_AS_STRING(ex->data); } else { if (PyObject_GetBuffer(ex->data, &buffer, PyBUF_CONTIG_RO) < 0) return -1; len = buffer.len; data = buffer.buf; } if (len == 1) { header[0] = MP_FIXEXT1; header[1] = ex->code; } else if (len == 2) { header[0] = MP_FIXEXT2; header[1] = ex->code; } else if (len == 4) { header[0] = MP_FIXEXT4; header[1] = ex->code; } else if (len == 8) { header[0] = MP_FIXEXT8; header[1] = ex->code; } else if (len == 16) { header[0] = MP_FIXEXT16; header[1] = ex->code; } else if (len < (1<<8)) { header[0] = MP_EXT8; header[1] = len; header[2] = ex->code; header_len = 3; } else if (len < (1<<16)) { header[0] = MP_EXT16; _msgspec_store16(&header[1], (uint16_t)len); header[3] = ex->code; header_len = 4; } else if (len < (1LL<<32)) { header[0] = MP_EXT32; _msgspec_store32(&header[1], (uint32_t)len); header[5] = ex->code; header_len = 6; } else { PyErr_SetString( self->mod->EncodeError, "Can't encode Ext objects with data longer than 2**32 - 1" ); goto done; } if (ms_write(self, header, header_len) < 0) goto done; status = len > 0 ? ms_write(self, data, len) : 0; done: if (buffer.buf != NULL) PyBuffer_Release(&buffer); return status; } static int mpack_encode_enum(EncoderState *self, PyObject *obj) { if (PyLong_Check(obj)) return mpack_encode_long(self, obj); if (PyUnicode_Check(obj)) return mpack_encode_str(self, obj); PyObject *value = PyObject_GetAttr(obj, self->mod->str__value_); if (value == NULL) return -1; int status = mpack_encode(self, value); Py_DECREF(value); return status; } static int mpack_encode_uuid(EncoderState *self, PyObject *obj) { char buf[36]; if (MS_UNLIKELY(self->uuid_format == UUID_FORMAT_BYTES)) { if (ms_uuid_to_16_bytes(self->mod, obj, (unsigned char *)buf) < 0) return -1; return mpack_encode_bin(self, buf, 16); } bool canonical = self->uuid_format == UUID_FORMAT_CANONICAL; if (ms_encode_uuid(self->mod, obj, buf, canonical) < 0) return -1; return mpack_encode_cstr(self, buf, canonical ? 36 : 32); } static int mpack_encode_decimal(EncoderState *self, PyObject *obj) { PyObject *temp; int out; if (MS_LIKELY(self->decimal_format == DECIMAL_FORMAT_STRING)) { temp = PyObject_Str(obj); if (temp == NULL) return -1; out = mpack_encode_str(self, temp); } else if (self->decimal_format == DECIMAL_FORMAT_NUMBER) { temp = PyNumber_Float(obj); if (temp == NULL) return -1; out = mpack_encode_float(self, temp); } else { if (self->in_decimal_callable) { return ms_decimal_format_error(); } temp = PyObject_CallFunctionObjArgs(self->decimal_callable, obj, NULL); if (temp == NULL) return -1; self->in_decimal_callable = true; out = mpack_encode(self, temp); self->in_decimal_callable = false; } Py_DECREF(temp); return out; } static int mpack_encode_date(EncoderState *self, PyObject *obj) { char buf[10]; ms_encode_date(obj, buf); return mpack_encode_cstr(self, buf, 10); } static int mpack_encode_time(EncoderState *self, PyObject *obj) { char buf[21]; int size = ms_encode_time(self->mod, obj, buf); if (size < 0) return -1; return mpack_encode_cstr(self, buf, size); } static int mpack_encode_timedelta(EncoderState *self, PyObject *obj) { char buf[26]; int size = ms_encode_timedelta(obj, buf); return mpack_encode_cstr(self, buf, size); } static int mpack_encode_datetime(EncoderState *self, PyObject *obj) { int64_t seconds; int32_t nanoseconds; PyObject *tzinfo = MS_DATE_GET_TZINFO(obj); if (tzinfo == Py_None) { char buf[32]; int size = ms_encode_datetime(self->mod, obj, buf); if (size < 0) return -1; return mpack_encode_cstr(self, buf, size); } if (tzinfo == PyDateTime_TimeZone_UTC) { datetime_to_epoch(obj, &seconds, &nanoseconds); } else { PyObject *temp = PyObject_CallFunctionObjArgs( self->mod->astimezone, obj, PyDateTime_TimeZone_UTC, NULL ); if (temp == NULL) return -1; datetime_to_epoch(temp, &seconds, &nanoseconds); Py_DECREF(temp); } if ((seconds >> 34) == 0) { uint64_t data64 = ((uint64_t)nanoseconds << 34) | (uint64_t)seconds; if ((data64 & 0xffffffff00000000L) == 0) { /* timestamp 32 */ char buf[6]; buf[0] = MP_FIXEXT4; buf[1] = -1; uint32_t data32 = (uint32_t)data64; _msgspec_store32(&buf[2], data32); if (ms_write(self, buf, 6) < 0) return -1; } else { /* timestamp 64 */ char buf[10]; buf[0] = MP_FIXEXT8; buf[1] = -1; _msgspec_store64(&buf[2], data64); if (ms_write(self, buf, 10) < 0) return -1; } } else { /* timestamp 96 */ char buf[15]; buf[0] = MP_EXT8; buf[1] = 12; buf[2] = -1; _msgspec_store32(&buf[3], nanoseconds); _msgspec_store64(&buf[7], seconds); if (ms_write(self, buf, 15) < 0) return -1; } return 0; } static MS_NOINLINE int mpack_encode_uncommon(EncoderState *self, PyTypeObject *type, PyObject *obj) { if (obj == Py_None) { return mpack_encode_none(self); } else if (type == &PyBool_Type) { return mpack_encode_bool(self, obj); } else if (ms_is_struct_type(type)) { return mpack_encode_struct(self, obj); } else if (type == &PyBytes_Type) { return mpack_encode_bytes(self, obj); } else if (type == &PyByteArray_Type) { return mpack_encode_bytearray(self, obj); } else if (type == &PyMemoryView_Type) { return mpack_encode_memoryview(self, obj); } else if (PyTuple_Check(obj)) { return mpack_encode_tuple(self, obj); } else if (type == PyDateTimeAPI->DateTimeType) { return mpack_encode_datetime(self, obj); } else if (type == PyDateTimeAPI->DateType) { return mpack_encode_date(self, obj); } else if (type == PyDateTimeAPI->TimeType) { return mpack_encode_time(self, obj); } else if (type == PyDateTimeAPI->DeltaType) { return mpack_encode_timedelta(self, obj); } else if (type == &Ext_Type) { return mpack_encode_ext(self, obj); } else if (type == &Raw_Type) { return mpack_encode_raw(self, obj); } else if (PyType_IsSubtype(Py_TYPE(type), self->mod->EnumMetaType)) { return mpack_encode_enum(self, obj); } else if (type == (PyTypeObject *)(self->mod->DecimalType)) { return mpack_encode_decimal(self, obj); } else if (PyType_IsSubtype(type, (PyTypeObject *)(self->mod->UUIDType))) { return mpack_encode_uuid(self, obj); } else if (PyAnySet_Check(obj)) { return mpack_encode_set(self, obj); } else if (!PyType_Check(obj) && type->tp_dict != NULL) { PyObject *fields = ms_get_dataclass_fields(self->mod, type, obj); if (fields != NULL) { int status = mpack_encode_dataclass(self, obj, fields); Py_DECREF(fields); return status; } if (PyDict_Contains(type->tp_dict, self->mod->str___attrs_attrs__)) { return mpack_encode_object(self, obj); } } if (self->enc_hook != NULL) { int status = -1; PyObject *temp; temp = PyObject_CallOneArg(self->enc_hook, obj); if (temp == NULL) return -1; if (!Py_EnterRecursiveCall(" while serializing an object")) { status = mpack_encode(self, temp); Py_LeaveRecursiveCall(); } Py_DECREF(temp); return status; } return ms_encode_err_type_unsupported(type); } static MS_INLINE int mpack_encode_inline(EncoderState *self, PyObject *obj) { PyTypeObject *type = Py_TYPE(obj); if (type == &PyUnicode_Type) { return mpack_encode_str(self, obj); } else if (type == &PyLong_Type) { return mpack_encode_long(self, obj); } else if (type == &PyFloat_Type) { return mpack_encode_float(self, obj); } else if (PyList_Check(obj)) { return mpack_encode_list(self, obj); } else if (PyDict_Check(obj)) { return mpack_encode_dict(self, obj); } #if PY315_PLUS else if (PyFrozenDict_Check(obj)) { return mpack_encode_dict(self, obj); } #endif else { return mpack_encode_uncommon(self, type, obj); } } static MS_INLINE int mpack_encode_dict_key_inline(EncoderState *self, PyObject *obj) { PyTypeObject *type = Py_TYPE(obj); if (PyUnicode_Check(obj)) { return mpack_encode_str(self, obj); } else if (type == &PyLong_Type) { return mpack_encode_long(self, obj); } else if (type == &PyFloat_Type) { return mpack_encode_float(self, obj); } else if (PyList_Check(obj)) { return mpack_encode_list(self, obj); } else if (PyDict_Check(obj)) { return mpack_encode_dict(self, obj); } else { return mpack_encode_uncommon(self, type, obj); } } static int mpack_encode(EncoderState *self, PyObject *obj) { return mpack_encode_inline(self, obj); } static PyObject* Encoder_encode_into(Encoder *self, PyObject *const *args, Py_ssize_t nargs) { return encoder_encode_into_common(self, args, nargs, &mpack_encode); } static PyObject* Encoder_encode(Encoder *self, PyObject *const *args, Py_ssize_t nargs) { return encoder_encode_common(self, args, nargs, &mpack_encode); } static struct PyMethodDef Encoder_methods[] = { { "encode", (PyCFunction) Encoder_encode, METH_FASTCALL, Encoder_encode__doc__, }, { "encode_into", (PyCFunction) Encoder_encode_into, METH_FASTCALL, Encoder_encode_into__doc__, }, {NULL, NULL} /* sentinel */ }; static PyTypeObject Encoder_Type = { PyVarObject_HEAD_INIT(NULL, 0) .tp_name = "msgspec.msgpack.Encoder", .tp_doc = Encoder__doc__, .tp_basicsize = sizeof(Encoder), .tp_dealloc = (destructor)Encoder_dealloc, .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, .tp_traverse = (traverseproc)Encoder_traverse, .tp_clear = (inquiry)Encoder_clear, .tp_new = PyType_GenericNew, .tp_init = (initproc)Encoder_init, .tp_methods = Encoder_methods, .tp_members = Encoder_members, .tp_getset = Encoder_getset, }; PyDoc_STRVAR(msgspec_msgpack_encode__doc__, "msgpack_encode(obj, /, *, enc_hook=None, order=None)\n" "--\n" "\n" "Serialize an object as MessagePack.\n" "\n" "Parameters\n" "----------\n" "obj : Any\n" " The object to serialize.\n" "enc_hook : callable, optional\n" " A callable to call for objects that aren't supported msgspec types. Takes\n" " the unsupported object and should return a supported object, or raise a\n" " ``NotImplementedError`` if unsupported.\n" "order : {None, 'deterministic', 'sorted'}, optional\n" " The ordering to use when encoding unordered compound types.\n" "\n" " - ``None``: All objects are encoded in the most efficient manner matching\n" " their in-memory representations. The default.\n" " - `'deterministic'`: Dict keys and set elements are sorted so that values\n" " which compare equal produce identical encoded output, regardless of\n" " insertion or iteration order. Useful when comparison/hashing of the\n" " encoded binary output is necessary.\n" " - `'sorted'`: Like `'deterministic'`, but *all* object-like types (structs,\n" " dataclasses, ...) are also sorted by field name before encoding. This is\n" " slower than `'deterministic'`, but may produce more human-readable output.\n" "\n" "Returns\n" "-------\n" "data : bytes\n" " The serialized object.\n" "\n" "See Also\n" "--------\n" "Encoder.encode" ); static PyObject* msgspec_msgpack_encode(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { return encode_common(self, args, nargs, kwnames, &mpack_encode); } /************************************************************************* * JSON Encoder * *************************************************************************/ PyDoc_STRVAR(JSONEncoder__doc__, "Encoder(*, enc_hook=None, decimal_format='string', uuid_format='canonical', order=None)\n" "--\n" "\n" "A JSON encoder.\n" "\n" "Parameters\n" "----------\n" "enc_hook : callable, optional\n" " A callable to call for objects that aren't supported msgspec types. Takes\n" " the unsupported object and should return a supported object, or raise a\n" " ``NotImplementedError`` if unsupported.\n" "decimal_format : {'string', 'number'} or callable, optional\n" " The format to use for encoding `decimal.Decimal` objects. If 'string'\n" " they're encoded as strings, if 'number', they're encoded as floats. If\n" " a callable is provided, it will be called with the `decimal.Decimal`\n" " object and must return a JSON-serializable value (but **not** another\n" " `decimal.Decimal` or a nested structure containing `decimal.Decimal`).\n" " Defaults to 'string', which is the recommended value since 'number' may\n" " result in precision loss when decoding for some JSON library implementations.\n" "uuid_format : {'canonical', 'hex'}, optional\n" " The format to use for encoding `uuid.UUID` objects. The 'canonical'\n" " and 'hex' formats encode them as strings with and without hyphens\n" " respectively. Defaults to 'canonical'.\n" "order : {None, 'deterministic', 'sorted'}, optional\n" " The ordering to use when encoding unordered compound types.\n" "\n" " - ``None``: All objects are encoded in the most efficient manner matching\n" " their in-memory representations. The default.\n" " - `'deterministic'`: Dict keys and set elements are sorted so that values\n" " which compare equal produce identical encoded output, regardless of\n" " insertion or iteration order. Useful when comparison/hashing of the\n" " encoded binary output is necessary.\n" " - `'sorted'`: Like `'deterministic'`, but *all* object-like types (structs,\n" " dataclasses, ...) are also sorted by field name before encoding. This is\n" " slower than `'deterministic'`, but may produce more human-readable output." ); static int json_encode_inline(EncoderState*, PyObject*); static int json_encode(EncoderState*, PyObject*); static MS_NOINLINE int json_encode_long_fallback(EncoderState *self, PyObject *obj) { int out = -1; PyObject *encoded = PyLong_Type.tp_repr(obj); if (MS_LIKELY(encoded != NULL)) { Py_ssize_t len; const char* buf = unicode_str_and_size(encoded, &len); if (MS_LIKELY(buf != NULL)) { out = ms_write(self, buf, len); } Py_DECREF(encoded); } return out; } static MS_NOINLINE int json_encode_long(EncoderState *self, PyObject *obj) { uint64_t x; bool neg, overflow; overflow = fast_long_extract_parts(obj, &neg, &x); if (MS_UNLIKELY(overflow)) { return json_encode_long_fallback(self, obj); } if (ms_ensure_space(self, 20) < 0) return -1; char *p = self->output_buffer_raw + self->output_len; if (neg) { *p++ = '-'; } self->output_len = write_u64(x, p) - self->output_buffer_raw; return 0; } static int json_encode_long_as_str(EncoderState *self, PyObject *obj) { if (ms_write(self, "\"", 1) < 0) return -1; if (json_encode_long(self, obj) < 0) return -1; return ms_write(self, "\"", 1); } static MS_NOINLINE int json_encode_float(EncoderState *self, PyObject *obj) { double x = PyFloat_AS_DOUBLE(obj); if (ms_ensure_space(self, 24) < 0) return -1; char *p = self->output_buffer_raw + self->output_len; self->output_len += write_f64(x, p, false); return 0; } static MS_NOINLINE int json_encode_float_as_str(EncoderState *self, PyObject *obj) { double x = PyFloat_AS_DOUBLE(obj); if (ms_ensure_space(self, 26) < 0) return -1; char *p = self->output_buffer_raw + self->output_len; *p = '"'; int n = write_f64(x, p + 1, true); *(p + 1 + n) = '"'; self->output_len += n + 2; return 0; } /* A table of escape characters to use for each byte (0 if no escape needed) */ static const char escape_table[256] = { 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'b', 't', 'n', 'u', 'f', 'r', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 0, 0, '"', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '\\', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; static int json_str_requires_escaping(PyObject *obj) { Py_ssize_t i, len; const char* buf = unicode_str_and_size(obj, &len); if (buf == NULL) return -1; for (i = 0; i < len; i++) { char escape = escape_table[(uint8_t)buf[i]]; if (escape != 0) { return 1; } } return 0; } static MS_INLINE int json_encode_cstr_inline(EncoderState *self, const char *src, Py_ssize_t len) { const char* src_end = src + len; if (ms_ensure_space(self, len + 2) < 0) return -1; char *out = self->output_buffer_raw + self->output_len; char *out_end = self->output_buffer_raw + self->max_output_len; *out++ = '"'; noescape: #define write_ascii_pre(i) \ if (MS_UNLIKELY(escape_table[(uint8_t)src[i]])) goto write_ascii_##i; #define write_ascii_post(i) \ write_ascii_##i: \ memcpy(out, src, i); \ out += i; \ src += i; \ goto escape; while (src_end - src >= 8) { repeat8(write_ascii_pre); memcpy(out, src, 8); out += 8; src += 8; } while (MS_LIKELY(src_end > src)) { write_ascii_pre(0); *out++ = *src++; } *out++ = '"'; self->output_len = out - self->output_buffer_raw; return 0; repeat8(write_ascii_post); escape: { char c = *src++; char escape = escape_table[(uint8_t)c]; /* Ensure enough space for the escape, final quote, and any remaining characters */ Py_ssize_t remaining = 7 + src_end - src; if (MS_UNLIKELY(remaining > out_end - out)) { Py_ssize_t output_len = out - self->output_buffer_raw; if (MS_UNLIKELY(ms_resize(self, remaining + output_len) < 0)) return -1; out = self->output_buffer_raw + output_len; out_end = self->output_buffer_raw + self->max_output_len; } /* Write the escaped character */ char escaped[6] = {'\\', escape, '0', '0'}; if (MS_UNLIKELY(escape == 'u')) { escaped[4] = hex_encode_table[c >> 4]; escaped[5] = hex_encode_table[c & 0xF]; memcpy(out, escaped, 6); out += 6; } else { memcpy(out, escaped, 2); out += 2; } goto noescape; } } static int json_encode_cstr(EncoderState *self, const char *src, Py_ssize_t len) { return json_encode_cstr_inline(self, src, len); } static MS_NOINLINE int json_encode_str(EncoderState *self, PyObject *obj) { Py_ssize_t len; const char* buf = unicode_str_and_size(obj, &len); if (buf == NULL) return -1; return json_encode_cstr_inline(self, buf, len); } static MS_INLINE int json_encode_cstr_noescape(EncoderState *self, const char *str, Py_ssize_t size) { if (ms_ensure_space(self, size + 2) < 0) return -1; char *p = self->output_buffer_raw + self->output_len; *p++ = '"'; memcpy(p, str, size); *(p + size) = '"'; self->output_len += size + 2; return 0; } static inline int json_encode_str_noescape(EncoderState *self, PyObject *obj) { Py_ssize_t len; const char* buf = unicode_str_and_size_nocheck(obj, &len); return json_encode_cstr_noescape(self, buf, len); } static int json_encode_bin(EncoderState *self, const char* buf, Py_ssize_t len) { /* Preallocate the buffer (ceil(4/3 * len) + 2) */ Py_ssize_t encoded_len = ms_encode_base64_size(self->mod, len); if (encoded_len < 0) return -1; if (ms_ensure_space(self, encoded_len + 2) < 0) return -1; /* Write to the buffer directly */ char *out = self->output_buffer_raw + self->output_len; *out++ = '"'; ms_encode_base64(buf, len, out); out += encoded_len; *out++ = '"'; self->output_len += encoded_len + 2; return 0; } static int json_encode_bytes(EncoderState *self, PyObject *obj) { Py_ssize_t len = PyBytes_GET_SIZE(obj); const char* buf = PyBytes_AS_STRING(obj); return json_encode_bin(self, buf, len); } static int json_encode_bytearray(EncoderState *self, PyObject *obj) { Py_ssize_t len = PyByteArray_GET_SIZE(obj); const char* buf = PyByteArray_AS_STRING(obj); return json_encode_bin(self, buf, len); } static int json_encode_memoryview(EncoderState *self, PyObject *obj) { int out; Py_buffer buffer; if (PyObject_GetBuffer(obj, &buffer, PyBUF_CONTIG_RO) < 0) return -1; out = json_encode_bin(self, buffer.buf, buffer.len); PyBuffer_Release(&buffer); return out; } static int json_encode_raw(EncoderState *self, PyObject *obj) { Raw *raw = (Raw *)obj; return ms_write(self, raw->buf, raw->len); } static int json_encode_dict_key_noinline(EncoderState *, PyObject *); static int json_encode_enum(EncoderState *self, PyObject *obj, bool is_key) { if (PyLong_Check(obj)) { return is_key ? json_encode_long_as_str(self, obj) : json_encode_long(self, obj); } if (PyUnicode_Check(obj)) { return json_encode_str(self, obj); } PyObject *value = PyObject_GetAttr(obj, self->mod->str__value_); if (value == NULL) return -1; int status; if (is_key) { /* A str value must be written as a JSON object key directly. * json_encode_dict_key_noinline only handles non-str keys (str keys * are fast-pathed in json_encode_dict_key), so recursing into it with * a str value would wrongly raise "unsupported key" - e.g. for a plain * Enum whose members have str values when used as a dict key. */ status = PyUnicode_Check(value) ? json_encode_str(self, value) : json_encode_dict_key_noinline(self, value); } else { status = json_encode(self, value); } Py_DECREF(value); return status; } static int json_encode_uuid(EncoderState *self, PyObject *obj) { char buf[38]; buf[0] = '"'; bool canonical = self->uuid_format == UUID_FORMAT_CANONICAL; if (ms_encode_uuid(self->mod, obj, buf + 1, canonical) < 0) return -1; int size = canonical ? 36 : 32; buf[size + 1] = '"'; return ms_write(self, buf, size + 2); } static int json_encode_decimal(EncoderState *self, PyObject *obj) { PyObject *temp; if (self->decimal_format == DECIMAL_FORMAT_CALLABLE) { if (self->in_decimal_callable) { return ms_decimal_format_error(); } temp = PyObject_CallFunctionObjArgs(self->decimal_callable, obj, NULL); if (temp == NULL) return -1; self->in_decimal_callable = true; int out = json_encode(self, temp); self->in_decimal_callable = false; Py_DECREF(temp); return out; } temp = PyObject_Str(obj); if (temp == NULL) return -1; Py_ssize_t size; const char* buf = unicode_str_and_size_nocheck(temp, &size); bool decimal_as_string = (self->decimal_format == DECIMAL_FORMAT_STRING); Py_ssize_t required = size + (2 * decimal_as_string); if (ms_ensure_space(self, size + 2) < 0) { Py_DECREF(temp); return -1; } char *p = self->output_buffer_raw + self->output_len; if (MS_LIKELY(decimal_as_string)) *p++ = '"'; memcpy(p, buf, size); if (MS_LIKELY(decimal_as_string)) *(p + size) = '"'; self->output_len += required; Py_DECREF(temp); return 0; } static int json_encode_date(EncoderState *self, PyObject *obj) { if (ms_ensure_space(self, 12) < 0) return -1; char *p = self->output_buffer_raw + self->output_len; *p = '"'; ms_encode_date(obj, p + 1); *(p + 11) = '"'; self->output_len += 12; return 0; } static int json_encode_time(EncoderState *self, PyObject *obj) { if (ms_ensure_space(self, 23) < 0) return -1; char *p = self->output_buffer_raw + self->output_len; *p = '"'; int size = ms_encode_time(self->mod, obj, p + 1); if (size < 0) return -1; *(p + size + 1) = '"'; self->output_len += (size + 2); return 0; } static int json_encode_datetime(EncoderState *self, PyObject *obj) { if (ms_ensure_space(self, 34) < 0) return -1; char *p = self->output_buffer_raw + self->output_len; *p = '"'; int size = ms_encode_datetime(self->mod, obj, p + 1); if (size < 0) return -1; *(p + size + 1) = '"'; self->output_len += (size + 2); return 0; } static int json_encode_timedelta(EncoderState *self, PyObject *obj) { char buf[28]; buf[0] = '"'; int n = ms_encode_timedelta(obj, buf + 1); buf[1 + n] = '"'; return ms_write(self, buf, 2 + n); } static MS_INLINE int json_encode_sequence(EncoderState *self, Py_ssize_t size, PyObject **arr) { int status = -1; if (size == 0) return ms_write(self, "[]", 2); if (ms_write(self, "[", 1) < 0) return -1; if (Py_EnterRecursiveCall(" while serializing an object")) return -1; for (Py_ssize_t i = 0; i < size; i++) { if (json_encode_inline(self, *(arr + i)) < 0) goto cleanup; if (ms_write(self, ",", 1) < 0) goto cleanup; } /* Overwrite trailing comma with ] */ *(self->output_buffer_raw + self->output_len - 1) = ']'; status = 0; cleanup: Py_LeaveRecursiveCall(); return status; } static MS_NOINLINE int json_encode_list(EncoderState *self, PyObject *obj) { int ret; Py_BEGIN_CRITICAL_SECTION(obj); ret = json_encode_sequence( self, PyList_GET_SIZE(obj), ((PyListObject *)obj)->ob_item ); Py_END_CRITICAL_SECTION(); return ret; } static MS_NOINLINE int json_encode_tuple(EncoderState *self, PyObject *obj) { return json_encode_sequence( self, PyTuple_GET_SIZE(obj), ((PyTupleObject *)obj)->ob_item ); } static int json_encode_set(EncoderState *self, PyObject *obj) { Py_ssize_t len = 0; PyObject *item; int status = -1; len = PySet_GET_SIZE(obj); if (len == 0) return ms_write(self, "[]", 2); if (MS_UNLIKELY(self->order != ORDER_DEFAULT)) { PyObject *temp = PySequence_List(obj); if (temp == NULL) return -1; if (PyList_Sort(temp) == 0) { status = json_encode_list(self, temp); } Py_DECREF(temp); return status; } if (ms_write(self, "[", 1) < 0) return -1; if (Py_EnterRecursiveCall(" while serializing an object")) return -1; PyObject *iter = PyObject_GetIter(obj); if (iter == NULL) goto cleanup; while ((item = PyIter_Next(iter))) { int status = json_encode_inline(self, item); Py_DECREF(item); if (status < 0) goto cleanup; if (ms_write(self, ",", 1) < 0) goto cleanup; } /* Overwrite trailing comma with ] */ *(self->output_buffer_raw + self->output_len - 1) = ']'; status = 0; cleanup: Py_LeaveRecursiveCall(); Py_XDECREF(iter); return status; } static MS_INLINE int json_encode_dict_key(EncoderState *self, PyObject *key) { if (MS_LIKELY(PyUnicode_Check(key))) { return json_encode_str(self, key); } return json_encode_dict_key_noinline(self, key); } static MS_NOINLINE int json_encode_dict_key_noinline(EncoderState *self, PyObject *obj) { PyTypeObject *type = Py_TYPE(obj); if (type == &PyLong_Type) { return json_encode_long_as_str(self, obj); } else if (type == &PyFloat_Type) { return json_encode_float_as_str(self, obj); } else if (PyType_IsSubtype(Py_TYPE(type), self->mod->EnumMetaType)) { return json_encode_enum(self, obj, true); } else if (type == PyDateTimeAPI->DateTimeType) { return json_encode_datetime(self, obj); } else if (type == PyDateTimeAPI->DateType) { return json_encode_date(self, obj); } else if (type == PyDateTimeAPI->TimeType) { return json_encode_time(self, obj); } else if (type == PyDateTimeAPI->DeltaType) { return json_encode_timedelta(self, obj); } else if (type == &PyBytes_Type) { return json_encode_bytes(self, obj); } else if (type == (PyTypeObject *)(self->mod->DecimalType)) { return json_encode_decimal(self, obj); } else if (PyType_IsSubtype(type, (PyTypeObject *)(self->mod->UUIDType))) { return json_encode_uuid(self, obj); } else if (self->enc_hook != NULL) { int status = -1; PyObject *temp; temp = PyObject_CallOneArg(self->enc_hook, obj); if (temp == NULL) return -1; if (!Py_EnterRecursiveCall(" while serializing an object")) { status = json_encode_dict_key(self, temp); Py_LeaveRecursiveCall(); } Py_DECREF(temp); return status; } else { PyErr_SetString( PyExc_TypeError, "Only dicts with str-like or number-like keys are supported" ); return -1; } } static int json_encode_and_free_assoclist(EncoderState *self, AssocList *list, bool escape) { if (list == NULL) return -1; int status = -1; AssocList_Sort(list); if (Py_EnterRecursiveCall(" while serializing an object")) goto cleanup2; if (ms_write(self, "{", 1) < 0) goto cleanup; Py_ssize_t start_len = self->output_len; if (escape) { for (Py_ssize_t i = 0; i < list->size; i++) { AssocItem *item = &(list->items[i]); if (json_encode_cstr(self, item->key, item->key_size) < 0) goto cleanup; if (ms_write(self, ":", 1) < 0) goto cleanup; if (json_encode_inline(self, item->val) < 0) goto cleanup; if (ms_write(self, ",", 1) < 0) goto cleanup; } } else { for (Py_ssize_t i = 0; i < list->size; i++) { AssocItem *item = &(list->items[i]); if (json_encode_cstr_noescape(self, item->key, item->key_size) < 0) goto cleanup; if (ms_write(self, ":", 1) < 0) goto cleanup; if (json_encode_inline(self, item->val) < 0) goto cleanup; if (ms_write(self, ",", 1) < 0) goto cleanup; } } if (MS_UNLIKELY(start_len == self->output_len)) { /* Empty, append "}" */ if (ms_write(self, "}", 1) < 0) goto cleanup; } else { /* Overwrite trailing comma with } */ *(self->output_buffer_raw + self->output_len - 1) = '}'; } status = 0; cleanup: Py_LeaveRecursiveCall(); cleanup2: AssocList_Free(list); return status; } static MS_NOINLINE int json_encode_dict(EncoderState *self, PyObject *obj) { PyObject *key, *val; Py_ssize_t len, pos = 0; int status = -1; len = PyDict_GET_SIZE(obj); if (len == 0) return ms_write(self, "{}", 2); if (MS_UNLIKELY(self->order != ORDER_DEFAULT)) { return json_encode_and_free_assoclist(self, AssocList_FromDict(obj), true); } if (ms_write(self, "{", 1) < 0) return -1; if (Py_EnterRecursiveCall(" while serializing an object")) return -1; Py_BEGIN_CRITICAL_SECTION(obj); while (PyDict_Next(obj, &pos, &key, &val)) { if (json_encode_dict_key(self, key) < 0) goto cleanup; if (ms_write(self, ":", 1) < 0) goto cleanup; if (json_encode_inline(self, val) < 0) goto cleanup; if (ms_write(self, ",", 1) < 0) goto cleanup; } /* Overwrite trailing comma with } */ *(self->output_buffer_raw + self->output_len - 1) = '}'; status = 0; cleanup:; Py_END_CRITICAL_SECTION(); Py_LeaveRecursiveCall(); return status; } static int json_encode_dataclass(EncoderState *self, PyObject *obj, PyObject *fields) { if (MS_UNLIKELY(self->order == ORDER_SORTED)) { return json_encode_and_free_assoclist( self, AssocList_FromDataclass(obj, fields), false ); } if (Py_EnterRecursiveCall(" while serializing an object")) return -1; int status = -1; DataclassIter iter; if (!dataclass_iter_setup(&iter, obj, fields)) goto cleanup; if (ms_write(self, "{", 1) < 0) goto cleanup; Py_ssize_t start_offset = self->output_len; PyObject *field, *val; while (dataclass_iter_next(&iter, &field, &val)) { Py_ssize_t field_len; const char* field_buf = unicode_str_and_size(field, &field_len); bool errored = ( (field_buf == NULL) || (json_encode_cstr_noescape(self, field_buf, field_len) < 0) || (ms_write(self, ":", 1) < 0) || (json_encode(self, val) < 0) || (ms_write(self, ",", 1) < 0) ); Py_DECREF(val); if (errored) goto cleanup; } /* If any fields written, overwrite trailing comma with }, otherwise append } */ if (MS_LIKELY(self->output_len != start_offset)) { *(self->output_buffer_raw + self->output_len - 1) = '}'; status = 0; } else { status = ms_write(self, "}", 1); } cleanup: Py_LeaveRecursiveCall(); dataclass_iter_cleanup(&iter); return status; } /* This method encodes an object as a map, with fields taken from `__dict__`, * followed by all `__slots__` in the class hierarchy. Any unset slots are * ignored, and `__weakref__` is not included. */ static int json_encode_object(EncoderState *self, PyObject *obj) { if (MS_UNLIKELY(self->order == ORDER_SORTED)) { return json_encode_and_free_assoclist(self, AssocList_FromObject(obj), false); } int status = -1; if (ms_write(self, "{", 1) < 0) return -1; Py_ssize_t start_offset = self->output_len; if (Py_EnterRecursiveCall(" while serializing an object")) return -1; /* First encode everything in `__dict__` */ PyObject *dict = PyObject_GenericGetDict(obj, NULL); Py_BEGIN_CRITICAL_SECTION(obj); if (MS_UNLIKELY(dict == NULL)) { PyErr_Clear(); } else { PyObject *key, *val; Py_ssize_t pos = 0; int err = 0; Py_BEGIN_CRITICAL_SECTION(dict); while (PyDict_Next(dict, &pos, &key, &val)) { if (MS_LIKELY(PyUnicode_CheckExact(key))) { Py_ssize_t key_len; const char* key_buf = unicode_str_and_size(key, &key_len); if (MS_UNLIKELY(val == UNSET)) continue; if (MS_UNLIKELY(key_buf == NULL)) { err = 1; break; } if (MS_UNLIKELY(*key_buf == '_')) continue; if (MS_UNLIKELY(json_encode_cstr_noescape(self, key_buf, key_len) < 0)) { err = 1; break; } if (MS_UNLIKELY(ms_write(self, ":", 1) < 0)) { err = 1; break; } if (MS_UNLIKELY(json_encode(self, val) < 0)) { err = 1; break; } if (MS_UNLIKELY(ms_write(self, ",", 1) < 0)) { err = 1; break; } } } Py_END_CRITICAL_SECTION(); if (MS_UNLIKELY(err)) goto cleanup; } /* Then encode everything in slots */ PyTypeObject *type = Py_TYPE(obj); while (type != NULL) { Py_ssize_t n = Py_SIZE(type); if (n) { PyMemberDef *mp = MS_PyHeapType_GET_MEMBERS((PyHeapTypeObject *)type); for (Py_ssize_t i = 0; i < n; i++, mp++) { if (MS_LIKELY(mp->type == T_OBJECT_EX && !(mp->flags & READONLY))) { char *addr = (char *)obj + mp->offset; PyObject *val = *(PyObject **)addr; if (MS_UNLIKELY(val == NULL)) continue; if (MS_UNLIKELY(val == UNSET)) continue; if (MS_UNLIKELY(*mp->name == '_')) continue; if (MS_UNLIKELY(json_encode_cstr_noescape(self, mp->name, strlen(mp->name)) < 0)) goto cleanup; if (MS_UNLIKELY(ms_write(self, ":", 1) < 0)) goto cleanup; if (MS_UNLIKELY(json_encode(self, val) < 0)) goto cleanup; if (MS_UNLIKELY(ms_write(self, ",", 1) < 0)) goto cleanup; } } } type = type->tp_base; } /* If any fields written, overwrite trailing comma with }, otherwise append } */ if (MS_LIKELY(self->output_len != start_offset)) { *(self->output_buffer_raw + self->output_len - 1) = '}'; status = 0; } else { status = ms_write(self, "}", 1); } cleanup:; Py_END_CRITICAL_SECTION(); Py_XDECREF(dict); Py_LeaveRecursiveCall(); return status; } static int json_encode_struct_tag(EncoderState *self, PyObject *obj) { PyTypeObject *type = Py_TYPE(obj); if (type == &PyUnicode_Type) { return json_encode_str(self, obj); } else { return json_encode_long(self, obj); } } static int json_encode_struct_object( EncoderState *self, StructMetaObject *struct_type, PyObject *obj ) { if (MS_UNLIKELY(self->order == ORDER_SORTED)) { return json_encode_and_free_assoclist(self, AssocList_FromStruct(obj), false); } PyObject *key, *val, *fields, *defaults, *tag_field, *tag_value; Py_ssize_t i, nfields, nunchecked; int status = -1; tag_field = struct_type->struct_tag_field; tag_value = struct_type->struct_tag_value; fields = struct_type->struct_encode_fields; defaults = struct_type->struct_defaults; nfields = PyTuple_GET_SIZE(fields); nunchecked = nfields; if (struct_type->omit_defaults == OPT_TRUE) { nunchecked -= PyTuple_GET_SIZE(defaults); } if (ms_write(self, "{", 1) < 0) return -1; Py_ssize_t start_len = self->output_len; if (Py_EnterRecursiveCall(" while serializing an object")) return -1; if (tag_value != NULL) { if (json_encode_str(self, tag_field) < 0) goto cleanup; if (ms_write(self, ":", 1) < 0) goto cleanup; if (json_encode_struct_tag(self, tag_value) < 0) goto cleanup; if (ms_write(self, ",", 1) < 0) goto cleanup; } for (i = 0; i < nunchecked; i++) { key = PyTuple_GET_ITEM(fields, i); val = Struct_get_index(obj, i); if (MS_UNLIKELY(val == NULL)) goto cleanup; if (MS_UNLIKELY(val == UNSET)) continue; if (json_encode_str_noescape(self, key) < 0) goto cleanup; if (ms_write(self, ":", 1) < 0) goto cleanup; if (json_encode(self, val) < 0) goto cleanup; if (ms_write(self, ",", 1) < 0) goto cleanup; } for (i = nunchecked; i < nfields; i++) { key = PyTuple_GET_ITEM(fields, i); val = Struct_get_index(obj, i); if (MS_UNLIKELY(val == NULL)) goto cleanup; if (MS_UNLIKELY(val == UNSET)) continue; PyObject *default_val = PyTuple_GET_ITEM(defaults, i - nunchecked); if (!is_default(val, default_val)) { if (json_encode_str_noescape(self, key) < 0) goto cleanup; if (ms_write(self, ":", 1) < 0) goto cleanup; if (json_encode(self, val) < 0) goto cleanup; if (ms_write(self, ",", 1) < 0) goto cleanup; } } if (MS_UNLIKELY(start_len == self->output_len)) { /* Empty struct, append "}" */ if (ms_write(self, "}", 1) < 0) goto cleanup; } else { /* Overwrite trailing comma with } */ *(self->output_buffer_raw + self->output_len - 1) = '}'; } status = 0; cleanup: Py_LeaveRecursiveCall(); return status; } static int json_encode_struct_array( EncoderState *self, StructMetaObject *struct_type, PyObject *obj ) { int status = -1; PyObject *tag_value = struct_type->struct_tag_value; PyObject *fields = struct_type->struct_encode_fields; Py_ssize_t nfields = PyTuple_GET_SIZE(fields); if (nfields == 0 && tag_value == NULL) return ms_write(self, "[]", 2); if (ms_write(self, "[", 1) < 0) return -1; if (Py_EnterRecursiveCall(" while serializing an object")) return -1; if (tag_value != NULL) { if (json_encode_struct_tag(self, tag_value) < 0) goto cleanup; if (ms_write(self, ",", 1) < 0) goto cleanup; } for (Py_ssize_t i = 0; i < nfields; i++) { PyObject *val = Struct_get_index(obj, i); if (val == NULL) goto cleanup; if (json_encode(self, val) < 0) goto cleanup; if (ms_write(self, ",", 1) < 0) goto cleanup; } /* Overwrite trailing comma with ] */ *(self->output_buffer_raw + self->output_len - 1) = ']'; status = 0; cleanup: Py_LeaveRecursiveCall(); return status; } static int json_encode_struct(EncoderState *self, PyObject *obj) { StructMetaObject *struct_type = (StructMetaObject *)Py_TYPE(obj); if (struct_type->array_like == OPT_TRUE) { return json_encode_struct_array(self, struct_type, obj); } return json_encode_struct_object(self, struct_type, obj); } static MS_NOINLINE int json_encode_uncommon(EncoderState *self, PyTypeObject *type, PyObject *obj) { if (obj == Py_None) { return ms_write(self, "null", 4); } else if (obj == Py_True) { return ms_write(self, "true", 4); } else if (obj == Py_False) { return ms_write(self, "false", 5); } else if (ms_is_struct_type(type)) { return json_encode_struct(self, obj); } else if (PyTuple_Check(obj)) { return json_encode_tuple(self, obj); } else if (type == PyDateTimeAPI->DateTimeType) { return json_encode_datetime(self, obj); } else if (type == PyDateTimeAPI->DateType) { return json_encode_date(self, obj); } else if (type == PyDateTimeAPI->TimeType) { return json_encode_time(self, obj); } else if (type == PyDateTimeAPI->DeltaType) { return json_encode_timedelta(self, obj); } else if (type == &PyBytes_Type) { return json_encode_bytes(self, obj); } else if (type == &PyByteArray_Type) { return json_encode_bytearray(self, obj); } else if (type == &PyMemoryView_Type) { return json_encode_memoryview(self, obj); } else if (type == &Raw_Type) { return json_encode_raw(self, obj); } else if (PyType_IsSubtype(Py_TYPE(type), self->mod->EnumMetaType)) { return json_encode_enum(self, obj, false); } else if (PyType_IsSubtype(type, (PyTypeObject *)(self->mod->UUIDType))) { return json_encode_uuid(self, obj); } else if (type == (PyTypeObject *)(self->mod->DecimalType)) { return json_encode_decimal(self, obj); } else if (PyAnySet_Check(obj)) { return json_encode_set(self, obj); } else if (!PyType_Check(obj) && type->tp_dict != NULL) { PyObject *fields = ms_get_dataclass_fields(self->mod, type, obj); if (fields != NULL) { int status = json_encode_dataclass(self, obj, fields); Py_DECREF(fields); return status; } if (PyDict_Contains(type->tp_dict, self->mod->str___attrs_attrs__)) { return json_encode_object(self, obj); } } if (self->enc_hook != NULL) { int status = -1; PyObject *temp; temp = PyObject_CallOneArg(self->enc_hook, obj); if (temp == NULL) return -1; if (!Py_EnterRecursiveCall(" while serializing an object")) { status = json_encode(self, temp); Py_LeaveRecursiveCall(); } Py_DECREF(temp); return status; } return ms_encode_err_type_unsupported(type); } static MS_INLINE int json_encode_inline(EncoderState *self, PyObject *obj) { PyTypeObject *type = Py_TYPE(obj); if (type == &PyUnicode_Type) { return json_encode_str(self, obj); } else if (type == &PyLong_Type) { return json_encode_long(self, obj); } else if (type == &PyFloat_Type) { return json_encode_float(self, obj); } else if (PyList_Check(obj)) { return json_encode_list(self, obj); } else if (PyDict_Check(obj)) { return json_encode_dict(self, obj); } #if PY315_PLUS else if (PyFrozenDict_Check(obj)) { return json_encode_dict(self, obj); } #endif else { return json_encode_uncommon(self, type, obj); } } static int json_encode(EncoderState *self, PyObject *obj) { return json_encode_inline(self, obj); } static PyObject* JSONEncoder_encode_into(Encoder *self, PyObject *const *args, Py_ssize_t nargs) { return encoder_encode_into_common(self, args, nargs, &json_encode); } static PyObject* JSONEncoder_encode(Encoder *self, PyObject *const *args, Py_ssize_t nargs) { return encoder_encode_common(self, args, nargs, &json_encode); } PyDoc_STRVAR(JSONEncoder_encode_lines__doc__, "encode_lines($self, items, /)\n" "--\n" "\n" "Encode an iterable of items as newline-delimited JSON, one item per line.\n" "\n" "Parameters\n" "----------\n" "items : iterable\n" " An iterable of items to encode.\n" "\n" "Returns\n" "-------\n" "data : bytes\n" " The items encoded as newline-delimited JSON, one item per line.\n" "\n" "Examples\n" "--------\n" ">>> import msgspec\n" ">>> items = [{\"name\": \"alice\"}, {\"name\": \"ben\"}]\n" ">>> encoder = msgspec.json.Encoder()\n" ">>> encoder.encode_lines(items)\n" "b'{\"name\":\"alice\"}\\n{\"name\":\"ben\"}\\n'" ); static PyObject * JSONEncoder_encode_lines(Encoder *self, PyObject *const *args, Py_ssize_t nargs) { if (!check_positional_nargs(nargs, 1, 1)) return NULL; EncoderState state = { .mod = self->mod, .enc_hook = self->enc_hook, .decimal_format = self->decimal_format, .decimal_callable = self->decimal_callable, .in_decimal_callable = false, .uuid_format = self->uuid_format, .order = self->order, .output_len = 0, .max_output_len = ENC_LINES_INIT_BUFSIZE, .resize_buffer = &ms_resize_bytes }; state.output_buffer = PyBytes_FromStringAndSize(NULL, state.max_output_len); if (state.output_buffer == NULL) return NULL; state.output_buffer_raw = PyBytes_AS_STRING(state.output_buffer); PyObject *input = args[0]; if (MS_LIKELY(PyList_Check(input))) { for (Py_ssize_t i = 0; i < PyList_GET_SIZE(input); i++) { if (json_encode(&state, PyList_GET_ITEM(input, i)) < 0) goto error; if (ms_write(&state, "\n", 1) < 0) goto error; } } else { PyObject *iter = PyObject_GetIter(input); if (iter == NULL) goto error; PyObject *item; while ((item = PyIter_Next(iter))) { int status = json_encode(&state, item); Py_DECREF(item); if (status < 0) goto error; if (ms_write(&state, "\n", 1) < 0) goto error; } if (PyErr_Occurred()) goto error; } FAST_BYTES_SHRINK(state.output_buffer, state.output_len); return state.output_buffer; error: Py_DECREF(state.output_buffer); return NULL; } static struct PyMethodDef JSONEncoder_methods[] = { { "encode", (PyCFunction) JSONEncoder_encode, METH_FASTCALL, Encoder_encode__doc__, }, { "encode_into", (PyCFunction) JSONEncoder_encode_into, METH_FASTCALL, Encoder_encode_into__doc__, }, { "encode_lines", (PyCFunction) JSONEncoder_encode_lines, METH_FASTCALL, JSONEncoder_encode_lines__doc__, }, {NULL, NULL} /* sentinel */ }; static PyTypeObject JSONEncoder_Type = { PyVarObject_HEAD_INIT(NULL, 0) .tp_name = "msgspec.json.Encoder", .tp_doc = JSONEncoder__doc__, .tp_basicsize = sizeof(Encoder), .tp_dealloc = (destructor)Encoder_dealloc, .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, .tp_traverse = (traverseproc)Encoder_traverse, .tp_clear = (inquiry)Encoder_clear, .tp_new = PyType_GenericNew, .tp_init = (initproc)Encoder_init, .tp_methods = JSONEncoder_methods, .tp_members = Encoder_members, .tp_getset = Encoder_getset, }; PyDoc_STRVAR(msgspec_json_encode__doc__, "json_encode(obj, /, *, enc_hook=None, order=None)\n" "--\n" "\n" "Serialize an object as JSON.\n" "\n" "Parameters\n" "----------\n" "obj : Any\n" " The object to serialize.\n" "enc_hook : callable, optional\n" " A callable to call for objects that aren't supported msgspec types. Takes\n" " the unsupported object and should return a supported object, or raise a\n" " ``NotImplementedError`` if unsupported.\n" "order : {None, 'deterministic', 'sorted'}, optional\n" " The ordering to use when encoding unordered compound types.\n" "\n" " - ``None``: All objects are encoded in the most efficient manner matching\n" " their in-memory representations. The default.\n" " - `'deterministic'`: Dict keys and set elements are sorted so that values\n" " which compare equal produce identical encoded output, regardless of\n" " insertion or iteration order. Useful when comparison/hashing of the\n" " encoded binary output is necessary.\n" " - `'sorted'`: Like `'deterministic'`, but *all* object-like types (structs,\n" " dataclasses, ...) are also sorted by field name before encoding. This is\n" " slower than `'deterministic'`, but may produce more human-readable output.\n" "\n" "Returns\n" "-------\n" "data : bytes\n" " The serialized object.\n" "\n" "See Also\n" "--------\n" "Encoder.encode" ); static PyObject* msgspec_json_encode(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { return encode_common(self, args, nargs, kwnames, &json_encode); } /************************************************************************* * MessagePack Decoder * *************************************************************************/ typedef struct DecoderState { /* Configuration */ TypeNode *type; PyObject *dec_hook; PyObject *ext_hook; bool strict; /* Per-message attributes */ PyObject *buffer_obj; char *input_start; char *input_pos; char *input_end; } DecoderState; typedef struct Decoder { PyObject_HEAD PyObject *orig_type; /* Configuration */ TypeNode *type; char strict; PyObject *dec_hook; PyObject *ext_hook; } Decoder; PyDoc_STRVAR(Decoder__doc__, "Decoder(type='Any', *, strict=True, dec_hook=None, ext_hook=None)\n" "--\n" "\n" "A MessagePack decoder.\n" "\n" "Parameters\n" "----------\n" "type : type, optional\n" " A Python type (in type annotation form) to decode the object as. If\n" " provided, the message will be type checked and decoded as the specified\n" " type. Defaults to `Any`, in which case the message will be decoded using\n" " the default MessagePack types.\n" "strict : bool, optional\n" " Whether type coercion rules should be strict. Setting to False enables a\n" " wider set of coercion rules from string to non-string types for all values.\n" " Default is True.\n" "dec_hook : callable, optional\n" " An optional callback for handling decoding custom types. Should have the\n" " signature ``dec_hook(type: Type, obj: Any) -> Any``, where ``type`` is the\n" " expected message type, and ``obj`` is the decoded representation composed\n" " of only basic MessagePack types. This hook should transform ``obj`` into\n" " type ``type``, or raise a ``NotImplementedError`` if unsupported.\n" "ext_hook : callable, optional\n" " An optional callback for decoding MessagePack extensions. Should have the\n" " signature ``ext_hook(code: int, data: memoryview) -> Any``. If provided,\n" " this will be called to deserialize all extension types found in the\n" " message. Note that ``data`` is a memoryview into the larger message\n" " buffer - any references created to the underlying buffer without copying\n" " the data out will cause the full message buffer to persist in memory.\n" " If not provided, extension types will decode as ``msgspec.Ext`` objects." ); static int Decoder_init(Decoder *self, PyObject *args, PyObject *kwds) { char *kwlist[] = {"type", "strict", "dec_hook", "ext_hook", NULL}; MsgspecState *st = msgspec_get_global_state(); PyObject *type = st->typing_any; PyObject *ext_hook = NULL; PyObject *dec_hook = NULL; int strict = 1; if (!PyArg_ParseTupleAndKeywords( args, kwds, "|O$pOO", kwlist, &type, &strict, &dec_hook, &ext_hook )) { return -1; } /* Handle strict */ self->strict = strict; /* Handle dec_hook */ if (dec_hook == Py_None) { dec_hook = NULL; } if (dec_hook != NULL) { if (!PyCallable_Check(dec_hook)) { PyErr_SetString(PyExc_TypeError, "dec_hook must be callable"); return -1; } Py_INCREF(dec_hook); } self->dec_hook = dec_hook; /* Handle ext_hook */ if (ext_hook == Py_None) { ext_hook = NULL; } if (ext_hook != NULL) { if (!PyCallable_Check(ext_hook)) { PyErr_SetString(PyExc_TypeError, "ext_hook must be callable"); return -1; } Py_INCREF(ext_hook); } self->ext_hook = ext_hook; /* Handle type */ self->type = TypeNode_Convert(type); if (self->type == NULL) { return -1; } Py_INCREF(type); self->orig_type = type; return 0; } static int Decoder_traverse(Decoder *self, visitproc visit, void *arg) { int out = TypeNode_traverse(self->type, visit, arg); if (out != 0) return out; Py_VISIT(self->orig_type); Py_VISIT(self->dec_hook); Py_VISIT(self->ext_hook); return 0; } static void Decoder_dealloc(Decoder *self) { PyObject_GC_UnTrack(self); TypeNode_Free(self->type); Py_XDECREF(self->orig_type); Py_XDECREF(self->dec_hook); Py_XDECREF(self->ext_hook); Py_TYPE(self)->tp_free((PyObject *)self); } static PyObject * Decoder_repr(Decoder *self) { int recursive; PyObject *typstr, *out = NULL; recursive = Py_ReprEnter((PyObject *)self); if (recursive != 0) { return (recursive < 0) ? NULL : PyUnicode_FromString("..."); /* cpylint-ignore */ } typstr = PyObject_Repr(self->orig_type); if (typstr != NULL) { out = PyUnicode_FromFormat("msgspec.msgpack.Decoder(%U)", typstr); } Py_XDECREF(typstr); Py_ReprLeave((PyObject *)self); return out; } static MS_INLINE int mpack_read1(DecoderState *self, char *s) { if (MS_UNLIKELY(self->input_pos == self->input_end)) { return ms_err_truncated(); } *s = *self->input_pos++; return 0; } static MS_INLINE int mpack_read(DecoderState *self, char **s, Py_ssize_t n) { if (MS_LIKELY(n <= self->input_end - self->input_pos)) { *s = self->input_pos; self->input_pos += n; return 0; } return ms_err_truncated(); } static MS_INLINE bool mpack_has_trailing_characters(DecoderState *self) { if (self->input_pos != self->input_end) { PyErr_Format( msgspec_get_global_state()->DecodeError, "MessagePack data is malformed: trailing characters (byte %zd)", (Py_ssize_t)(self->input_pos - self->input_start) ); return true; } return false; } static MS_INLINE Py_ssize_t mpack_decode_size1(DecoderState *self) { char s = 0; if (mpack_read1(self, &s) < 0) return -1; return (Py_ssize_t)((unsigned char)s); } static MS_INLINE Py_ssize_t mpack_decode_size2(DecoderState *self) { char *s = NULL; if (mpack_read(self, &s, 2) < 0) return -1; return (Py_ssize_t)(_msgspec_load16(uint16_t, s)); } static MS_INLINE Py_ssize_t mpack_decode_size4(DecoderState *self) { char *s = NULL; if (mpack_read(self, &s, 4) < 0) return -1; #if SIZEOF_VOID_P > 4 return (Py_ssize_t)(_msgspec_load32(uint32_t, s)); #else uint32_t size = _msgspec_load32(uint32_t, s); /* MessagePack uint32 sizes can exceed Py_ssize_t on 32-bit builds, so * reject them before they become negative sentinel values. */ if (MS_UNLIKELY(size > PY_SSIZE_T_MAX)) { return ms_err_truncated(); } return (Py_ssize_t)size; #endif } static PyObject * mpack_error_expected(char op, char *expected, PathNode *path) { char *got; if (('\x00' <= op && op <= '\x7f') || ('\xe0' <= op && op <= '\xff')) { got = "int"; } else if ('\xa0' <= op && op <= '\xbf') { got = "str"; } else if ('\x90' <= op && op <= '\x9f') { got = "array"; } else if ('\x80' <= op && op <= '\x8f') { got = "object"; } else { switch ((enum mpack_code)op) { case MP_NIL: got = "null"; break; case MP_TRUE: case MP_FALSE: got = "bool"; break; case MP_UINT8: case MP_UINT16: case MP_UINT32: case MP_UINT64: case MP_INT8: case MP_INT16: case MP_INT32: case MP_INT64: got = "int"; break; case MP_FLOAT32: case MP_FLOAT64: got = "float"; break; case MP_STR8: case MP_STR16: case MP_STR32: got = "str"; break; case MP_BIN8: case MP_BIN16: case MP_BIN32: got = "bytes"; break; case MP_ARRAY16: case MP_ARRAY32: got = "array"; break; case MP_MAP16: case MP_MAP32: got = "object"; break; case MP_FIXEXT1: case MP_FIXEXT2: case MP_FIXEXT4: case MP_FIXEXT8: case MP_FIXEXT16: case MP_EXT8: case MP_EXT16: case MP_EXT32: got = "ext"; break; default: got = "unknown"; break; } } ms_raise_validation_error(path, "Expected `%s`, got `%s`%U", expected, got); return NULL; } static MS_INLINE Py_ssize_t mpack_decode_cstr(DecoderState *self, char ** out, PathNode *path) { char op = 0; Py_ssize_t size; if (mpack_read1(self, &op) < 0) return -1; if ('\xa0' <= op && op <= '\xbf') { size = op & 0x1f; } else if (op == MP_STR8) { size = mpack_decode_size1(self); } else if (op == MP_STR16) { size = mpack_decode_size2(self); } else if (op == MP_STR32) { size = mpack_decode_size4(self); } else { mpack_error_expected(op, "str", path); return -1; } if (mpack_read(self, out, size) < 0) return -1; return size; } /* Decode an integer. If the value fits in an int64_t, it will be stored in * `out`, otherwise it will be stored in `uout`. A return value of -1 indicates * an error. */ static int mpack_decode_cint(DecoderState *self, int64_t *out, uint64_t *uout, PathNode *path) { char op = 0; char *s = NULL; if (mpack_read1(self, &op) < 0) return -1; if (('\x00' <= op && op <= '\x7f') || ('\xe0' <= op && op <= '\xff')) { *out = *((int8_t *)(&op)); } else if (op == MP_UINT8) { if (MS_UNLIKELY(mpack_read(self, &s, 1) < 0)) return -1; *out = *(uint8_t *)s; } else if (op == MP_UINT16) { if (MS_UNLIKELY(mpack_read(self, &s, 2) < 0)) return -1; *out = _msgspec_load16(uint16_t, s); } else if (op == MP_UINT32) { if (MS_UNLIKELY(mpack_read(self, &s, 4) < 0)) return -1; *out = _msgspec_load32(uint32_t, s); } else if (op == MP_UINT64) { if (MS_UNLIKELY(mpack_read(self, &s, 8) < 0)) return -1; uint64_t ux = _msgspec_load64(uint64_t, s); if (ux > LLONG_MAX) { *uout = ux; } else { *out = ux; } } else if (op == MP_INT8) { if (MS_UNLIKELY(mpack_read(self, &s, 1) < 0)) return -1; *out = *(int8_t *)s; } else if (op == MP_INT16) { if (MS_UNLIKELY(mpack_read(self, &s, 2) < 0)) return -1; *out = _msgspec_load16(int16_t, s); } else if (op == MP_INT32) { if (MS_UNLIKELY(mpack_read(self, &s, 4) < 0)) return -1; *out = _msgspec_load32(int32_t, s); } else if (op == MP_INT64) { if (MS_UNLIKELY(mpack_read(self, &s, 8) < 0)) return -1; *out = _msgspec_load64(int64_t, s); } else { mpack_error_expected(op, "int", path); return -1; } return 0; } static PyObject * mpack_decode_datetime( DecoderState *self, const char *data_buf, Py_ssize_t size, TypeNode *type, PathNode *path ) { uint64_t data64; uint32_t nanoseconds; int64_t seconds; switch (size) { case 4: seconds = _msgspec_load32(uint32_t, data_buf); nanoseconds = 0; break; case 8: data64 = _msgspec_load64(uint64_t, data_buf); seconds = data64 & 0x00000003ffffffffL; nanoseconds = data64 >> 34; break; case 12: nanoseconds = _msgspec_load32(uint32_t, data_buf); seconds = _msgspec_load64(uint64_t, data_buf + 4); break; default: return ms_error_with_path( "Invalid MessagePack timestamp%U", path ); } if (nanoseconds > 999999999) { return ms_error_with_path( "Invalid MessagePack timestamp: nanoseconds out of range%U", path ); } return datetime_from_epoch(seconds, nanoseconds, type, path); } static int mpack_skip(DecoderState *self); static int mpack_skip_array(DecoderState *self, Py_ssize_t size) { int status = -1; Py_ssize_t i; if (size < 0) return -1; if (size == 0) return 0; if (Py_EnterRecursiveCall(" while deserializing an object")) return -1; for (i = 0; i < size; i++) { if (mpack_skip(self) < 0) goto done; } status = 0; done: Py_LeaveRecursiveCall(); return status; } static int mpack_skip_map(DecoderState *self, Py_ssize_t size) { return mpack_skip_array(self, size * 2); } static int mpack_skip_ext(DecoderState *self, Py_ssize_t size) { char *s; if (size < 0) return -1; return mpack_read(self, &s, size + 1); } static int mpack_skip(DecoderState *self) { char *s = NULL; char op = 0; Py_ssize_t size; if (mpack_read1(self, &op) < 0) return -1; if (('\x00' <= op && op <= '\x7f') || ('\xe0' <= op && op <= '\xff')) { return 0; } else if ('\xa0' <= op && op <= '\xbf') { return mpack_read(self, &s, op & 0x1f); } else if ('\x90' <= op && op <= '\x9f') { return mpack_skip_array(self, op & 0x0f); } else if ('\x80' <= op && op <= '\x8f') { return mpack_skip_map(self, op & 0x0f); } switch ((enum mpack_code)op) { case MP_NIL: case MP_TRUE: case MP_FALSE: return 0; case MP_UINT8: case MP_INT8: return mpack_read1(self, &op); case MP_UINT16: case MP_INT16: return mpack_read(self, &s, 2); case MP_UINT32: case MP_INT32: case MP_FLOAT32: return mpack_read(self, &s, 4); case MP_UINT64: case MP_INT64: case MP_FLOAT64: return mpack_read(self, &s, 8); case MP_STR8: case MP_BIN8: if ((size = mpack_decode_size1(self)) < 0) return -1; return mpack_read(self, &s, size); case MP_STR16: case MP_BIN16: if ((size = mpack_decode_size2(self)) < 0) return -1; return mpack_read(self, &s, size); case MP_STR32: case MP_BIN32: if ((size = mpack_decode_size4(self)) < 0) return -1; return mpack_read(self, &s, size); case MP_ARRAY16: return mpack_skip_array(self, mpack_decode_size2(self)); case MP_ARRAY32: return mpack_skip_array(self, mpack_decode_size4(self)); case MP_MAP16: return mpack_skip_map(self, mpack_decode_size2(self)); case MP_MAP32: return mpack_skip_map(self, mpack_decode_size4(self)); case MP_FIXEXT1: return mpack_skip_ext(self, 1); case MP_FIXEXT2: return mpack_skip_ext(self, 2); case MP_FIXEXT4: return mpack_skip_ext(self, 4); case MP_FIXEXT8: return mpack_skip_ext(self, 8); case MP_FIXEXT16: return mpack_skip_ext(self, 16); case MP_EXT8: return mpack_skip_ext(self, mpack_decode_size1(self)); case MP_EXT16: return mpack_skip_ext(self, mpack_decode_size2(self)); case MP_EXT32: return mpack_skip_ext(self, mpack_decode_size4(self)); default: PyErr_Format( msgspec_get_global_state()->DecodeError, "MessagePack data is malformed: invalid opcode '\\x%02x' (byte %zd)", (unsigned char)op, (Py_ssize_t)(self->input_pos - self->input_start - 1) ); return -1; } } static PyObject * mpack_decode( DecoderState *self, TypeNode *type, PathNode *path, bool is_key ); static PyObject * mpack_decode_none(DecoderState *self, TypeNode *type, PathNode *path) { if (type->types & (MS_TYPE_ANY | MS_TYPE_NONE)) { Py_INCREF(Py_None); return Py_None; } return ms_validation_error("None", type, path); } static PyObject * mpack_decode_bool(DecoderState *self, PyObject *val, TypeNode *type, PathNode *path) { if (type->types & (MS_TYPE_ANY | MS_TYPE_BOOL)) { Py_INCREF(val); return val; } if (val == Py_True && (type->types & MS_TYPE_BOOLLITERAL_TRUE)) { Py_INCREF(Py_True); return Py_True; } if (val == Py_False && (type->types & MS_TYPE_BOOLLITERAL_FALSE)) { Py_INCREF(Py_False); return Py_False; } if (type->types & (MS_TYPE_BOOLLITERAL_TRUE | MS_TYPE_BOOLLITERAL_FALSE)) { ms_raise_validation_error(path, "Invalid enum value %R%U", val); return NULL; } return ms_validation_error("bool", type, path); } static PyObject * mpack_decode_float(DecoderState *self, double x, TypeNode *type, PathNode *path) { if (MS_LIKELY(type->types & (MS_TYPE_ANY | MS_TYPE_FLOAT))) { return ms_decode_float(x, type, path); } else if (type->types & MS_TYPE_DECIMAL) { return ms_decode_decimal_from_float(x, path, NULL); } else if (!self->strict) { if (type->types & MS_TYPE_INT) { int64_t out; if (double_as_int64(x, &out)) { return ms_post_decode_int64(out, type, path, self->strict, false); } } if (type->types & MS_TYPE_DATETIME) { return ms_decode_datetime_from_float(x, type, path); } if (type->types & MS_TYPE_TIMEDELTA) { return ms_decode_timedelta_from_float(x, path); } } return ms_validation_error("float", type, path); } static PyObject * mpack_decode_str(DecoderState *self, Py_ssize_t size, TypeNode *type, PathNode *path) { char *s = NULL; if (MS_UNLIKELY(mpack_read(self, &s, size) < 0)) return NULL; if (MS_LIKELY(type->types & (MS_TYPE_STR | MS_TYPE_ANY))) { return ms_check_str_constraints( PyUnicode_DecodeUTF8(s, size, NULL), type, path ); } else if (MS_UNLIKELY(!self->strict)) { bool invalid = false; PyObject *out = ms_decode_str_lax(s, size, type, path, &invalid); if (!invalid) return out; } if (MS_UNLIKELY(type->types & (MS_TYPE_ENUM | MS_TYPE_STRLITERAL))) { return ms_decode_str_enum_or_literal(s, size, type, path); } else if (MS_UNLIKELY(type->types & MS_TYPE_DATETIME)) { return ms_decode_datetime_from_str(s, size, type, path); } else if (MS_UNLIKELY(type->types & MS_TYPE_DATE)) { return ms_decode_date(s, size, path); } else if (MS_UNLIKELY(type->types & MS_TYPE_TIME)) { return ms_decode_time(s, size, type, path); } else if (MS_UNLIKELY(type->types & MS_TYPE_TIMEDELTA)) { return ms_decode_timedelta(s, size, type, path); } else if (MS_UNLIKELY(type->types & MS_TYPE_UUID)) { return ms_decode_uuid_from_str(s, size, path); } else if (MS_UNLIKELY(type->types & MS_TYPE_DECIMAL)) { return ms_decode_decimal(s, size, false, path, NULL); } return ms_validation_error("str", type, path); } static PyObject * mpack_decode_bin( DecoderState *self, Py_ssize_t size, TypeNode *type, PathNode *path ) { if (MS_UNLIKELY(size < 0)) return NULL; if (MS_UNLIKELY(!ms_passes_bytes_constraints(size, type, path))) return NULL; char *s = NULL; if (MS_UNLIKELY(mpack_read(self, &s, size) < 0)) return NULL; if (type->types & (MS_TYPE_ANY | MS_TYPE_BYTES)) { return PyBytes_FromStringAndSize(s, size); } else if (type->types & MS_TYPE_BYTEARRAY) { return PyByteArray_FromStringAndSize(s, size); } else if (type->types & MS_TYPE_UUID) { return ms_decode_uuid_from_bytes(s, size, path); } else if (type->types & MS_TYPE_MEMORYVIEW) { PyObject *view = PyMemoryView_GetContiguous( self->buffer_obj, PyBUF_READ, 'C' ); if (view == NULL) return NULL; Py_buffer *buffer = PyMemoryView_GET_BUFFER(view); buffer->buf = s; buffer->len = size; buffer->shape = &(buffer->len); return view; } return ms_validation_error("bytes", type, path); } static PyObject * mpack_decode_list( DecoderState *self, Py_ssize_t size, TypeNode *el_type, PathNode *path ) { Py_ssize_t i; PyObject *res, *item; /* XXX: Preallocate all elements for lists <= 16 elements in length. * * This minimizes the ability of malicious messages to cause a massive * overallocation, while not penalizing decoding speed for small lists. * With this restriction, a malicious message can preallocate at most: * * sys.getsizeof(list(range(16))) * sys.getrecursionlimit() * * bytes, which should be low enough to not matter (500 KiB on my machine). * Dropping this optimization (resulting in the same allocation pattern as * the JSON decoder would reduce this to * * sys.getsizeof([]) * sys.getrecursionlimit() * * which is roughly 1/3 the size. This reduction is deemed not worth it. */ res = PyList_New(Py_MIN(16, size)); if (res == NULL) return NULL; Py_SET_SIZE(res, 0); if (size == 0) return res; if (Py_EnterRecursiveCall(" while deserializing an object")) { Py_DECREF(res); return NULL; /* cpylint-ignore */ } for (i = 0; i < size; i++) { PathNode el_path = {path, i}; item = mpack_decode(self, el_type, &el_path, false); if (MS_UNLIKELY(item == NULL)) { Py_CLEAR(res); break; } /* Append item to list */ if (MS_LIKELY((LIST_CAPACITY(res) > Py_SIZE(res)))) { PyList_SET_ITEM(res, Py_SIZE(res), item); Py_SET_SIZE(res, Py_SIZE(res) + 1); } else { int status = PyList_Append(res, item); Py_DECREF(item); if (MS_UNLIKELY(status < 0)) { Py_CLEAR(res); break; } } } Py_LeaveRecursiveCall(); return res; } static PyObject * mpack_decode_set( DecoderState *self, bool mutable, Py_ssize_t size, TypeNode *el_type, PathNode *path ) { Py_ssize_t i; PyObject *res, *item; res = mutable ? PySet_New(NULL) : PyFrozenSet_New(NULL); if (res == NULL) return NULL; if (size == 0) return res; if (Py_EnterRecursiveCall(" while deserializing an object")) { Py_DECREF(res); return NULL; /* cpylint-ignore */ } for (i = 0; i < size; i++) { PathNode el_path = {path, i}; item = mpack_decode(self, el_type, &el_path, true); if (MS_UNLIKELY(item == NULL || PySet_Add(res, item) < 0)) { Py_XDECREF(item); Py_CLEAR(res); break; } Py_DECREF(item); } Py_LeaveRecursiveCall(); return res; } static PyObject * mpack_decode_vartuple( DecoderState *self, Py_ssize_t size, TypeNode *el_type, PathNode *path, bool is_key ) { if (MS_UNLIKELY(size > 16)) { /* For variadic tuples of length > 16, we fallback to decoding into a * list, then converting to a tuple. This lets us avoid pre-allocating * extremely large tuples. See the comment in `mpack_decode_list` for * more info. */ PyObject *temp = mpack_decode_list(self, size, el_type, path); if (temp == NULL) return NULL; PyObject *res = PyList_AsTuple(temp); Py_DECREF(temp); return res; } PyObject *res = PyTuple_New(size); if (res == NULL) return NULL; if (size == 0) return res; if (Py_EnterRecursiveCall(" while deserializing an object")) { Py_DECREF(res); return NULL; /* cpylint-ignore */ } for (Py_ssize_t i = 0; i < size; i++) { PathNode el_path = {path, i}; PyObject *item = mpack_decode(self, el_type, &el_path, is_key); if (MS_UNLIKELY(item == NULL)) { Py_CLEAR(res); break; } PyTuple_SET_ITEM(res, i, item); } Py_LeaveRecursiveCall(); return res; } static PyObject * mpack_decode_fixtuple( DecoderState *self, Py_ssize_t size, TypeNode *type, PathNode *path, bool is_key ) { PyObject *res, *item; Py_ssize_t i, fixtuple_size, offset; TypeNode_get_fixtuple(type, &offset, &fixtuple_size); if (size != fixtuple_size) { /* tuple is the incorrect size, raise and return */ ms_raise_validation_error( path, "Expected `array` of length %zd, got %zd%U", fixtuple_size, size ); return NULL; } res = PyTuple_New(size); if (res == NULL) return NULL; if (size == 0) return res; if (Py_EnterRecursiveCall(" while deserializing an object")) { Py_DECREF(res); return NULL; /* cpylint-ignore */ } for (i = 0; i < fixtuple_size; i++) { PathNode el_path = {path, i}; item = mpack_decode(self, type->details[offset + i].pointer, &el_path, is_key); if (MS_UNLIKELY(item == NULL)) { Py_CLEAR(res); break; } PyTuple_SET_ITEM(res, i, item); } Py_LeaveRecursiveCall(); return res; } static PyObject * mpack_decode_namedtuple( DecoderState *self, Py_ssize_t size, TypeNode *type, PathNode *path, bool is_key ) { NamedTupleInfo *info = TypeNode_get_namedtuple_info(type); Py_ssize_t nfields = Py_SIZE(info); Py_ssize_t ndefaults = info->defaults == NULL ? 0 : PyTuple_GET_SIZE(info->defaults); Py_ssize_t nrequired = nfields - ndefaults; if (size < nrequired || nfields < size) { /* tuple is the incorrect size, raise and return */ if (ndefaults == 0) { ms_raise_validation_error( path, "Expected `array` of length %zd, got %zd%U", nfields, size ); } else { ms_raise_validation_error( path, "Expected `array` of length %zd to %zd, got %zd%U", nrequired, nfields, size ); } return NULL; } if (Py_EnterRecursiveCall(" while deserializing an object")) return NULL; PyTypeObject *nt_type = (PyTypeObject *)(info->class); PyObject *res = nt_type->tp_alloc(nt_type, nfields); if (res == NULL) goto error; MS_TUPLE_RESET_HASH(res); for (Py_ssize_t i = 0; i < nfields; i++) { PyTuple_SET_ITEM(res, i, NULL); } for (Py_ssize_t i = 0; i < size; i++) { PathNode el_path = {path, i}; PyObject *item = mpack_decode(self, info->types[i], &el_path, is_key); if (MS_UNLIKELY(item == NULL)) goto error; PyTuple_SET_ITEM(res, i, item); } for (Py_ssize_t i = size; i < nfields; i++) { PyObject *item = PyTuple_GET_ITEM(info->defaults, i - nrequired); Py_INCREF(item); PyTuple_SET_ITEM(res, i, item); } Py_LeaveRecursiveCall(); return res; error: Py_LeaveRecursiveCall(); Py_CLEAR(res); return NULL; } static int mpack_ensure_tag_matches( DecoderState *self, PathNode *path, PyObject *expected_tag ) { if (PyUnicode_CheckExact(expected_tag)) { char *tag = NULL; Py_ssize_t tag_size; tag_size = mpack_decode_cstr(self, &tag, path); if (tag_size < 0) return -1; /* Check that tag matches expected tag value */ Py_ssize_t expected_size; const char *expected_str = unicode_str_and_size_nocheck( expected_tag, &expected_size ); if (tag_size != expected_size || memcmp(tag, expected_str, expected_size) != 0) { /* Tag doesn't match the expected value, error nicely */ ms_invalid_cstr_value(tag, tag_size, path); return -1; } } else { int64_t tag = 0; uint64_t utag = 0; if (mpack_decode_cint(self, &tag, &utag, path) < 0) return -1; int64_t expected = PyLong_AsLongLong(expected_tag); /* Tags must be int64s, if utag != 0 then we know the tags don't match. * We parse the full uint64 value only to validate the message and * raise a nice error */ if (utag != 0) { ms_invalid_cuint_value(utag, path); return -1; } if (tag != expected) { ms_invalid_cint_value(tag, path); return -1; } } return 0; } static StructInfo * mpack_decode_tag_and_lookup_type( DecoderState *self, Lookup *lookup, PathNode *path ) { StructInfo *out = NULL; if (Lookup_IsStrLookup(lookup)) { Py_ssize_t tag_size; char *tag = NULL; tag_size = mpack_decode_cstr(self, &tag, path); if (tag_size < 0) return NULL; out = (StructInfo *)StrLookup_Get((StrLookup *)lookup, tag, tag_size); if (out == NULL) { ms_invalid_cstr_value(tag, tag_size, path); } } else { int64_t tag = 0; uint64_t utag = 0; if (mpack_decode_cint(self, &tag, &utag, path) < 0) return NULL; if (utag == 0) { out = (StructInfo *)IntLookup_GetInt64((IntLookup *)lookup, tag); if (out == NULL) { ms_invalid_cint_value(tag, path); } } else { out = (StructInfo *)IntLookup_GetUInt64((IntLookup *)lookup, utag); if (out == NULL) { ms_invalid_cuint_value(utag, path); } } } return out; } static PyObject * mpack_decode_struct_array_inner( DecoderState *self, Py_ssize_t size, bool tag_already_read, StructInfo *info, PathNode *path, bool is_key ) { Py_ssize_t i, nfields, ndefaults, nrequired, npos; PyObject *res, *val = NULL; StructMetaObject *st_type = info->class; bool is_gc, should_untrack; bool tagged = st_type->struct_tag_value != NULL; PathNode item_path = {path, 0}; nfields = PyTuple_GET_SIZE(st_type->struct_encode_fields); ndefaults = PyTuple_GET_SIZE(st_type->struct_defaults); nrequired = tagged + nfields - st_type->n_trailing_defaults; npos = nfields - ndefaults; if (size < nrequired) { ms_raise_validation_error( path, "Expected `array` of at least length %zd, got %zd%U", nrequired, size ); return NULL; } if (tagged) { if (!tag_already_read) { if (mpack_ensure_tag_matches(self, &item_path, st_type->struct_tag_value) < 0) { return NULL; } } size--; item_path.index++; } if (Py_EnterRecursiveCall(" while deserializing an object")) return NULL; res = Struct_alloc((PyTypeObject *)(st_type)); if (res == NULL) goto error; is_gc = MS_TYPE_IS_GC(st_type); should_untrack = is_gc; for (i = 0; i < nfields; i++) { if (size > 0) { val = mpack_decode(self, info->types[i], &item_path, is_key); if (MS_UNLIKELY(val == NULL)) goto error; size--; item_path.index++; } else { val = get_default( PyTuple_GET_ITEM(st_type->struct_defaults, i - npos) ); if (val == NULL) goto error; } Struct_set_index(res, i, val); if (should_untrack) { should_untrack = !MS_MAYBE_TRACKED(val); } } if (MS_UNLIKELY(size > 0)) { if (MS_UNLIKELY(st_type->forbid_unknown_fields == OPT_TRUE)) { ms_raise_validation_error( path, "Expected `array` of at most length %zd, got %zd%U", nfields, nfields + size ); goto error; } else { /* Ignore all trailing fields */ while (size > 0) { if (mpack_skip(self) < 0) goto error; size--; } } } if (Struct_decode_post_init(st_type, res, path) < 0) goto error; Py_LeaveRecursiveCall(); if (is_gc && should_untrack && MS_IS_TRACKED(res)) PyObject_GC_UnTrack(res); return res; error: Py_LeaveRecursiveCall(); Py_XDECREF(res); return NULL; } static PyObject * mpack_decode_struct_array( DecoderState *self, Py_ssize_t size, TypeNode *type, PathNode *path, bool is_key ) { StructInfo *info = TypeNode_get_struct_info(type); return mpack_decode_struct_array_inner(self, size, false, info, path, is_key); } static PyObject * mpack_decode_struct_array_union( DecoderState *self, Py_ssize_t size, TypeNode *type, PathNode *path, bool is_key ) { Lookup *lookup = TypeNode_get_struct_union(type); if (size == 0) { return ms_error_with_path( "Expected `array` of at least length 1, got 0%U", path ); } /* Decode and lookup tag */ PathNode tag_path = {path, 0}; StructInfo *info = mpack_decode_tag_and_lookup_type(self, lookup, &tag_path); if (info == NULL) return NULL; /* Finish decoding the rest of the struct */ return mpack_decode_struct_array_inner(self, size, true, info, path, is_key); } static PyObject * mpack_decode_array( DecoderState *self, Py_ssize_t size, TypeNode *type, PathNode *path, bool is_key ) { if (MS_UNLIKELY(!ms_passes_array_constraints(size, type, path))) return NULL; if (type->types & MS_TYPE_ANY) { TypeNode type_any = {MS_TYPE_ANY}; if (is_key) { return mpack_decode_vartuple(self, size, &type_any, path, is_key); } else { return mpack_decode_list(self, size, &type_any, path); } } else if (type->types & MS_TYPE_LIST) { return mpack_decode_list(self, size, TypeNode_get_array(type), path); } else if (type->types & (MS_TYPE_SET | MS_TYPE_FROZENSET)) { return mpack_decode_set( self, type->types & MS_TYPE_SET, size, TypeNode_get_array(type), path ); } else if (type->types & MS_TYPE_VARTUPLE) { return mpack_decode_vartuple(self, size, TypeNode_get_array(type), path, is_key); } else if (type->types & MS_TYPE_FIXTUPLE) { return mpack_decode_fixtuple(self, size, type, path, is_key); } else if (type->types & MS_TYPE_NAMEDTUPLE) { return mpack_decode_namedtuple(self, size, type, path, is_key); } else if (type->types & MS_TYPE_STRUCT_ARRAY) { return mpack_decode_struct_array(self, size, type, path, is_key); } else if (type->types & MS_TYPE_STRUCT_ARRAY_UNION) { return mpack_decode_struct_array_union(self, size, type, path, is_key); } return ms_validation_error("array", type, path); } /* Specialized mpack_decode for dict keys, handling caching of short string keys */ static PyObject * mpack_decode_key(DecoderState *self, TypeNode *type, PathNode *path) { char op; if (MS_UNLIKELY(self->input_pos == self->input_end)) { ms_err_truncated(); return NULL; } /* Peek at the next op */ op = *self->input_pos; bool is_str = type->types == MS_TYPE_ANY || type->types == MS_TYPE_STR; if (MS_LIKELY(is_str && '\xa0' <= op && op <= '\xbf')) { /* A short (<= 31 byte) unicode str */ self->input_pos++; /* consume op */ Py_ssize_t size = op & 0x1f; /* Don't cache the empty string */ if (MS_UNLIKELY(size == 0)) return PyUnicode_New(0, 127); /* Read in the string buffer */ char *str; if (MS_UNLIKELY(mpack_read(self, &str, size) < 0)) return NULL; #ifndef Py_GIL_DISABLED /* Attempt a cache lookup. We don't know if it's ascii yet, but * checking if it's ascii is more expensive than just doing a lookup, * and most dict key strings are ascii */ uint32_t hash = murmur2(str, size); uint32_t index = hash % STRING_CACHE_SIZE; PyObject *existing = string_cache[index]; if (MS_LIKELY(existing != NULL)) { Py_ssize_t e_size = ((PyASCIIObject *)existing)->length; char *e_str = ascii_get_buffer(existing); if (MS_LIKELY(size == e_size && memcmp(str, e_str, size) == 0)) { Py_INCREF(existing); return existing; } } #endif /* Cache miss, create a new string */ PyObject *new = PyUnicode_DecodeUTF8(str, size, NULL); if (new == NULL) return NULL; /* If ascii, add it to the cache */ if (PyUnicode_IS_COMPACT_ASCII(new)) { #ifndef Py_GIL_DISABLED Py_INCREF(new); Py_XDECREF(existing); string_cache[index] = new; #endif } return new; } /* Fallback to standard decode */ return mpack_decode(self, type, path, true); } static PyObject * mpack_decode_dict( DecoderState *self, Py_ssize_t size, TypeNode *key_type, TypeNode *val_type, PathNode *path ) { Py_ssize_t i; PyObject *res, *key = NULL, *val = NULL; PathNode key_path = {path, PATH_KEY, NULL}; PathNode val_path = {path, PATH_ELLIPSIS, NULL}; res = PyDict_New(); if (res == NULL) return NULL; if (size == 0) return res; if (Py_EnterRecursiveCall(" while deserializing an object")) { Py_DECREF(res); return NULL; /* cpylint-ignore */ } for (i = 0; i < size; i++) { key = mpack_decode_key(self, key_type, &key_path); if (MS_UNLIKELY(key == NULL)) goto error; val = mpack_decode(self, val_type, &val_path, false); if (MS_UNLIKELY(val == NULL)) goto error; if (MS_UNLIKELY(PyDict_SetItem(res, key, val) < 0)) { if (PyErr_ExceptionMatches(PyExc_TypeError)) { PyErr_Clear(); PyErr_Format( msgspec_get_global_state()->DecodeError, "MessagePack data is malformed: map keys must be hashable (byte %zd)", (Py_ssize_t)(self->input_pos - self->input_start) ); } goto error; } Py_CLEAR(key); Py_CLEAR(val); } Py_LeaveRecursiveCall(); return res; error: Py_LeaveRecursiveCall(); Py_XDECREF(key); Py_XDECREF(val); Py_DECREF(res); return NULL; } #if PY315_PLUS static PyObject * mpack_decode_frozendict( DecoderState *self, Py_ssize_t size, TypeNode *key_type, TypeNode *val_type, PathNode *path ) { PyObject *dict = mpack_decode_dict(self, size, key_type, val_type, path); return _PyFrozenDict_NewSteal(dict); } #endif static PyObject * mpack_decode_typeddict( DecoderState *self, Py_ssize_t size, TypeNode *type, PathNode *path ) { if (Py_EnterRecursiveCall(" while deserializing an object")) return NULL; PyObject *res = PyDict_New(); if (res == NULL) goto error; TypedDictInfo *info = TypeNode_get_typeddict_info(type); Py_ssize_t nrequired = 0, pos = 0; for (Py_ssize_t i = 0; i < size; i++) { char *key; PathNode key_path = {path, PATH_KEY, NULL}; Py_ssize_t key_size = mpack_decode_cstr(self, &key, &key_path); if (MS_UNLIKELY(key_size < 0)) goto error; TypeNode *field_type; PyObject *field = TypedDictInfo_lookup_key(info, key, key_size, &field_type, &pos); if (field != NULL) { PathNode field_path = {path, PATH_STR, field}; PyObject *val = mpack_decode(self, field_type, &field_path, false); if (val == NULL) goto error; /* We want to keep a count of required fields we've decoded. Since * duplicates can occur, we stash the current dict size, then only * increment if the dict size has changed _and_ the field is * required. */ Py_ssize_t cur_size = PyDict_GET_SIZE(res); int status = PyDict_SetItem(res, field, val); /* Always decref value, no need to decref key since it's a borrowed * reference. */ Py_DECREF(val); if (status < 0) goto error; if ((PyDict_GET_SIZE(res) != cur_size) && (field_type->types & MS_EXTRA_FLAG)) { nrequired++; } } else { /* Unknown field, skip */ if (mpack_skip(self) < 0) goto error; } } if (nrequired < info->nrequired) { /* A required field is missing, determine which one and raise */ TypedDictInfo_error_missing(info, res, path); goto error; } Py_LeaveRecursiveCall(); return res; error: Py_LeaveRecursiveCall(); Py_XDECREF(res); return NULL; } static PyObject * mpack_decode_dataclass( DecoderState *self, Py_ssize_t size, TypeNode *type, PathNode *path ) { if (Py_EnterRecursiveCall(" while deserializing an object")) return NULL; DataclassInfo *info = TypeNode_get_dataclass_info(type); PyTypeObject *dataclass_type = (PyTypeObject *)(info->class); PyObject *out = dataclass_type->tp_alloc(dataclass_type, 0); if (out == NULL) goto error; if (info->pre_init != NULL) { PyObject *res = PyObject_CallOneArg(info->pre_init, out); if (res == NULL) goto error; Py_DECREF(res); } Py_ssize_t pos = 0; for (Py_ssize_t i = 0; i < size; i++) { char *key; PathNode key_path = {path, PATH_KEY, NULL}; Py_ssize_t key_size = mpack_decode_cstr(self, &key, &key_path); if (MS_UNLIKELY(key_size < 0)) goto error; TypeNode *field_type; PyObject *field = DataclassInfo_lookup_key(info, key, key_size, &field_type, &pos); if (field != NULL) { PathNode field_path = {path, PATH_STR, field}; PyObject *val = mpack_decode(self, field_type, &field_path, false); if (val == NULL) goto error; int status = PyObject_GenericSetAttr(out, field, val); Py_DECREF(val); if (status < 0) goto error; } else { /* Unknown field, skip */ if (mpack_skip(self) < 0) goto error; } } if (DataclassInfo_post_decode(info, out, path) < 0) goto error; Py_LeaveRecursiveCall(); return out; error: Py_LeaveRecursiveCall(); Py_XDECREF(out); return NULL; } static PyObject * mpack_decode_struct_map( DecoderState *self, Py_ssize_t size, StructInfo *info, PathNode *path, bool is_key ) { StructMetaObject *st_type = info->class; Py_ssize_t i, key_size, field_index, pos = 0; char *key = NULL; PyObject *res, *val = NULL; if (Py_EnterRecursiveCall(" while deserializing an object")) return NULL; res = Struct_alloc((PyTypeObject *)(st_type)); if (res == NULL) goto error; for (i = 0; i < size; i++) { PathNode key_path = {path, PATH_KEY, NULL}; key_size = mpack_decode_cstr(self, &key, &key_path); if (MS_UNLIKELY(key_size < 0)) goto error; field_index = StructMeta_get_field_index(st_type, key, key_size, &pos); if (field_index < 0) { if (MS_UNLIKELY(field_index == -2)) { PathNode tag_path = {path, PATH_STR, st_type->struct_tag_field}; if (mpack_ensure_tag_matches(self, &tag_path, st_type->struct_tag_value) < 0) { goto error; } } else { /* Unknown field */ if (MS_UNLIKELY(st_type->forbid_unknown_fields == OPT_TRUE)) { ms_error_unknown_field(key, key_size, path); goto error; } else { if (mpack_skip(self) < 0) goto error; } } } else { PathNode field_path = {path, field_index, (PyObject *)st_type}; val = mpack_decode(self, info->types[field_index], &field_path, is_key); if (val == NULL) goto error; Struct_set_index(res, field_index, val); } } if (Struct_fill_in_defaults(st_type, res, path) < 0) goto error; Py_LeaveRecursiveCall(); return res; error: Py_LeaveRecursiveCall(); Py_XDECREF(res); return NULL; } static PyObject * mpack_decode_struct_union( DecoderState *self, Py_ssize_t size, TypeNode *type, PathNode *path, bool is_key ) { Lookup *lookup = TypeNode_get_struct_union(type); PathNode key_path = {path, PATH_KEY, NULL}; Py_ssize_t tag_field_size; const char *tag_field = unicode_str_and_size_nocheck( Lookup_tag_field(lookup), &tag_field_size ); /* Cache the current input position in case we need to reset it once the * tag is found */ char *orig_input_pos = self->input_pos; for (Py_ssize_t i = 0; i < size; i++) { Py_ssize_t key_size; char *key = NULL; key_size = mpack_decode_cstr(self, &key, &key_path); if (key_size < 0) return NULL; if (key_size == tag_field_size && memcmp(key, tag_field, key_size) == 0) { /* Decode and lookup tag */ PathNode tag_path = {path, PATH_STR, Lookup_tag_field(lookup)}; StructInfo *info = mpack_decode_tag_and_lookup_type(self, lookup, &tag_path); if (info == NULL) return NULL; if (i == 0) { /* Common case, tag is first field. No need to reset, just mark * that the first field has been read. */ size--; } else { self->input_pos = orig_input_pos; } return mpack_decode_struct_map(self, size, info, path, is_key); } else { /* Not the tag field, skip the value and try again */ if (mpack_skip(self) < 0) return NULL; } } ms_missing_required_field(Lookup_tag_field(lookup), path); return NULL; } static PyObject * mpack_decode_map( DecoderState *self, Py_ssize_t size, TypeNode *type, PathNode *path, bool is_key ) { if (type->types & MS_TYPE_STRUCT) { StructInfo *info = TypeNode_get_struct_info(type); return mpack_decode_struct_map(self, size, info, path, is_key); } else if (type->types & MS_TYPE_TYPEDDICT) { return mpack_decode_typeddict(self, size, type, path); } else if (type->types & MS_TYPE_DATACLASS) { return mpack_decode_dataclass(self, size, type, path); } else if (type->types & (MS_ANY_DICT | MS_TYPE_ANY)) { if (MS_UNLIKELY(!ms_passes_map_constraints(size, type, path))) { return NULL; } TypeNode *key, *val; TypeNode type_any = {MS_TYPE_ANY}; if (type->types & MS_TYPE_ANY) { key = &type_any; val = &type_any; } else { TypeNode_get_dict(type, &key, &val); } #if PY315_PLUS if (type->types & MS_TYPE_FROZENDICT) { return mpack_decode_frozendict(self, size, key, val, path); } #endif return mpack_decode_dict(self, size, key, val, path); } else if (type->types & MS_TYPE_STRUCT_UNION) { return mpack_decode_struct_union(self, size, type, path, is_key); } return ms_validation_error("object", type, path); } static PyObject * mpack_decode_ext( DecoderState *self, Py_ssize_t size, TypeNode *type, PathNode *path ) { Py_buffer *buffer; char c_code = 0, *data_buf = NULL; long code; PyObject *data, *pycode = NULL, *view = NULL, *out = NULL; if (size < 0) return NULL; if (mpack_read1(self, &c_code) < 0) return NULL; code = *((int8_t *)(&c_code)); if (mpack_read(self, &data_buf, size) < 0) return NULL; if (type->types & MS_TYPE_DATETIME && code == -1) { return mpack_decode_datetime(self, data_buf, size, type, path); } else if (type->types & MS_TYPE_EXT) { data = PyBytes_FromStringAndSize(data_buf, size); if (data == NULL) return NULL; /* Ext_New doesn't steal the reference to data */ out = Ext_New(code, data); Py_DECREF(data); return out; } else if (!(type->types & MS_TYPE_ANY)) { return ms_validation_error("ext", type, path); } /* Decode Any. * - datetime if code == -1 * - call ext_hook if available * - otherwise return Ext object * */ if (code == -1) { return mpack_decode_datetime(self, data_buf, size, type, path); } else if (self->ext_hook == NULL) { data = PyBytes_FromStringAndSize(data_buf, size); if (data == NULL) return NULL; /* Ext_New doesn't steal the reference to data */ out = Ext_New(code, data); Py_DECREF(data); return out; } else { pycode = PyLong_FromLong(code); if (pycode == NULL) goto done; } view = PyMemoryView_GetContiguous(self->buffer_obj, PyBUF_READ, 'C'); if (view == NULL) goto done; buffer = PyMemoryView_GET_BUFFER(view); buffer->buf = data_buf; buffer->len = size; buffer->shape = &(buffer->len); out = PyObject_CallFunctionObjArgs(self->ext_hook, pycode, view, NULL); done: Py_XDECREF(pycode); Py_XDECREF(view); return out; } static MS_NOINLINE PyObject * mpack_decode_raw(DecoderState *self) { char *start = self->input_pos; if (mpack_skip(self) < 0) return NULL; Py_ssize_t size = self->input_pos - start; return Raw_FromView(self->buffer_obj, start, size); } static MS_INLINE PyObject * mpack_decode_nocustom( DecoderState *self, TypeNode *type, PathNode *path, bool is_key ) { char op = 0; char *s = NULL; if (mpack_read1(self, &op) < 0) { return NULL; } if (('\x00' <= op && op <= '\x7f') || ('\xe0' <= op && op <= '\xff')) { return ms_post_decode_int64(*((int8_t *)(&op)), type, path, self->strict, false); } else if ('\xa0' <= op && op <= '\xbf') { return mpack_decode_str(self, op & 0x1f, type, path); } else if ('\x90' <= op && op <= '\x9f') { return mpack_decode_array(self, op & 0x0f, type, path, is_key); } else if ('\x80' <= op && op <= '\x8f') { return mpack_decode_map(self, op & 0x0f, type, path, is_key); } switch ((enum mpack_code)op) { case MP_NIL: return mpack_decode_none(self, type, path); case MP_TRUE: return mpack_decode_bool(self, Py_True, type, path); case MP_FALSE: return mpack_decode_bool(self, Py_False, type, path); case MP_UINT8: if (MS_UNLIKELY(mpack_read(self, &s, 1) < 0)) return NULL; return ms_post_decode_uint64(*(uint8_t *)s, type, path, self->strict, false); case MP_UINT16: if (MS_UNLIKELY(mpack_read(self, &s, 2) < 0)) return NULL; return ms_post_decode_uint64(_msgspec_load16(uint16_t, s), type, path, self->strict, false); case MP_UINT32: if (MS_UNLIKELY(mpack_read(self, &s, 4) < 0)) return NULL; return ms_post_decode_uint64(_msgspec_load32(uint32_t, s), type, path, self->strict, false); case MP_UINT64: if (MS_UNLIKELY(mpack_read(self, &s, 8) < 0)) return NULL; return ms_post_decode_uint64(_msgspec_load64(uint64_t, s), type, path, self->strict, false); case MP_INT8: if (MS_UNLIKELY(mpack_read(self, &s, 1) < 0)) return NULL; return ms_post_decode_int64(*(int8_t *)s, type, path, self->strict, false); case MP_INT16: if (MS_UNLIKELY(mpack_read(self, &s, 2) < 0)) return NULL; return ms_post_decode_int64(_msgspec_load16(int16_t, s), type, path, self->strict, false); case MP_INT32: if (MS_UNLIKELY(mpack_read(self, &s, 4) < 0)) return NULL; return ms_post_decode_int64(_msgspec_load32(int32_t, s), type, path, self->strict, false); case MP_INT64: if (MS_UNLIKELY(mpack_read(self, &s, 8) < 0)) return NULL; return ms_post_decode_int64(_msgspec_load64(int64_t, s), type, path, self->strict, false); case MP_FLOAT32: { float f = 0; uint32_t uf; if (mpack_read(self, &s, 4) < 0) return NULL; uf = _msgspec_load32(uint32_t, s); memcpy(&f, &uf, 4); return mpack_decode_float(self, f, type, path); } case MP_FLOAT64: { double f = 0; uint64_t uf; if (mpack_read(self, &s, 8) < 0) return NULL; uf = _msgspec_load64(uint64_t, s); memcpy(&f, &uf, 8); return mpack_decode_float(self, f, type, path); } case MP_STR8: { Py_ssize_t size = mpack_decode_size1(self); if (MS_UNLIKELY(size < 0)) return NULL; return mpack_decode_str(self, size, type, path); } case MP_STR16: { Py_ssize_t size = mpack_decode_size2(self); if (MS_UNLIKELY(size < 0)) return NULL; return mpack_decode_str(self, size, type, path); } case MP_STR32: { Py_ssize_t size = mpack_decode_size4(self); if (MS_UNLIKELY(size < 0)) return NULL; return mpack_decode_str(self, size, type, path); } case MP_BIN8: return mpack_decode_bin(self, mpack_decode_size1(self), type, path); case MP_BIN16: return mpack_decode_bin(self, mpack_decode_size2(self), type, path); case MP_BIN32: return mpack_decode_bin(self, mpack_decode_size4(self), type, path); case MP_ARRAY16: { Py_ssize_t size = mpack_decode_size2(self); if (MS_UNLIKELY(size < 0)) return NULL; return mpack_decode_array(self, size, type, path, is_key); } case MP_ARRAY32: { Py_ssize_t size = mpack_decode_size4(self); if (MS_UNLIKELY(size < 0)) return NULL; return mpack_decode_array(self, size, type, path, is_key); } case MP_MAP16: { Py_ssize_t size = mpack_decode_size2(self); if (MS_UNLIKELY(size < 0)) return NULL; return mpack_decode_map(self, size, type, path, is_key); } case MP_MAP32: { Py_ssize_t size = mpack_decode_size4(self); if (MS_UNLIKELY(size < 0)) return NULL; return mpack_decode_map(self, size, type, path, is_key); } case MP_FIXEXT1: return mpack_decode_ext(self, 1, type, path); case MP_FIXEXT2: return mpack_decode_ext(self, 2, type, path); case MP_FIXEXT4: return mpack_decode_ext(self, 4, type, path); case MP_FIXEXT8: return mpack_decode_ext(self, 8, type, path); case MP_FIXEXT16: return mpack_decode_ext(self, 16, type, path); case MP_EXT8: return mpack_decode_ext(self, mpack_decode_size1(self), type, path); case MP_EXT16: return mpack_decode_ext(self, mpack_decode_size2(self), type, path); case MP_EXT32: return mpack_decode_ext(self, mpack_decode_size4(self), type, path); default: PyErr_Format( msgspec_get_global_state()->DecodeError, "MessagePack data is malformed: invalid opcode '\\x%02x' (byte %zd)", (unsigned char)op, (Py_ssize_t)(self->input_pos - self->input_start - 1) ); return NULL; } } static PyObject * mpack_decode( DecoderState *self, TypeNode *type, PathNode *path, bool is_key ) { if (MS_UNLIKELY(type->types == 0)) { return mpack_decode_raw(self); } PyObject *obj = mpack_decode_nocustom(self, type, path, is_key); if (MS_UNLIKELY(type->types & (MS_TYPE_CUSTOM | MS_TYPE_CUSTOM_GENERIC))) { return ms_decode_custom(obj, self->dec_hook, type, path); } return obj; } PyDoc_STRVAR(Decoder_decode__doc__, "decode($self, buf, /)\n" "--\n" "\n" "Deserialize an object from MessagePack.\n" "\n" "Parameters\n" "----------\n" "buf : bytes-like\n" " The message to decode.\n" "\n" "Returns\n" "-------\n" "obj : Any\n" " The deserialized object.\n" ); static PyObject* Decoder_decode(Decoder *self, PyObject *const *args, Py_ssize_t nargs) { if (!check_positional_nargs(nargs, 1, 1)) { return NULL; } DecoderState state = { .type = self->type, .strict = self->strict, .dec_hook = self->dec_hook, .ext_hook = self->ext_hook }; Py_buffer buffer; buffer.buf = NULL; if (PyObject_GetBuffer(args[0], &buffer, PyBUF_CONTIG_RO) >= 0) { state.buffer_obj = args[0]; state.input_start = buffer.buf; state.input_pos = buffer.buf; state.input_end = state.input_pos + buffer.len; PyObject *res = mpack_decode(&state, state.type, NULL, false); if (res != NULL && mpack_has_trailing_characters(&state)) { Py_CLEAR(res); } PyBuffer_Release(&buffer); return res; } return NULL; } static struct PyMethodDef Decoder_methods[] = { { "decode", (PyCFunction) Decoder_decode, METH_FASTCALL, Decoder_decode__doc__, }, {"__class_getitem__", Py_GenericAlias, METH_O|METH_CLASS}, {NULL, NULL} /* sentinel */ }; static PyMemberDef Decoder_members[] = { {"type", T_OBJECT_EX, offsetof(Decoder, orig_type), READONLY, "The Decoder type"}, {"strict", T_BOOL, offsetof(Decoder, strict), READONLY, "The Decoder strict setting"}, {"dec_hook", T_OBJECT, offsetof(Decoder, dec_hook), READONLY, "The Decoder dec_hook"}, {"ext_hook", T_OBJECT, offsetof(Decoder, ext_hook), READONLY, "The Decoder ext_hook"}, {NULL}, }; static PyTypeObject Decoder_Type = { PyVarObject_HEAD_INIT(NULL, 0) .tp_name = "msgspec.msgpack.Decoder", .tp_doc = Decoder__doc__, .tp_basicsize = sizeof(Decoder), .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, .tp_new = PyType_GenericNew, .tp_init = (initproc)Decoder_init, .tp_traverse = (traverseproc)Decoder_traverse, .tp_dealloc = (destructor)Decoder_dealloc, .tp_repr = (reprfunc)Decoder_repr, .tp_methods = Decoder_methods, .tp_members = Decoder_members, }; PyDoc_STRVAR(msgspec_msgpack_decode__doc__, "msgpack_decode(buf, /, *, type='Any', strict=True, dec_hook=None, ext_hook=None)\n" "--\n" "\n" "Deserialize an object from MessagePack.\n" "\n" "Parameters\n" "----------\n" "buf : bytes-like\n" " The message to decode.\n" "type : type, optional\n" " A Python type (in type annotation form) to decode the object as. If\n" " provided, the message will be type checked and decoded as the specified\n" " type. Defaults to `Any`, in which case the message will be decoded using\n" " the default MessagePack types.\n" "strict : bool, optional\n" " Whether type coercion rules should be strict. Setting to False enables a\n" " wider set of coercion rules from string to non-string types for all values.\n" " Default is True.\n" "dec_hook : callable, optional\n" " An optional callback for handling decoding custom types. Should have the\n" " signature ``dec_hook(type: Type, obj: Any) -> Any``, where ``type`` is the\n" " expected message type, and ``obj`` is the decoded representation composed\n" " of only basic MessagePack types. This hook should transform ``obj`` into\n" " type ``type``, or raise a ``NotImplementedError`` if unsupported.\n" "ext_hook : callable, optional\n" " An optional callback for decoding MessagePack extensions. Should have the\n" " signature ``ext_hook(code: int, data: memoryview) -> Any``. If provided,\n" " this will be called to deserialize all extension types found in the\n" " message. Note that ``data`` is a memoryview into the larger message\n" " buffer - any references created to the underlying buffer without copying\n" " the data out will cause the full message buffer to persist in memory.\n" " If not provided, extension types will decode as ``msgspec.Ext`` objects.\n" "\n" "Returns\n" "-------\n" "obj : Any\n" " The deserialized object.\n" "\n" "See Also\n" "--------\n" "Decoder.decode" ); static PyObject* msgspec_msgpack_decode(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *res = NULL, *buf = NULL, *type = NULL, *strict_obj = NULL; PyObject *dec_hook = NULL, *ext_hook = NULL; MsgspecState *mod = msgspec_get_state(self); int strict = 1; /* Parse arguments */ if (!check_positional_nargs(nargs, 1, 1)) return NULL; buf = args[0]; if (kwnames != NULL) { Py_ssize_t nkwargs = PyTuple_GET_SIZE(kwnames); if ((type = find_keyword(kwnames, args + nargs, mod->str_type)) != NULL) nkwargs--; if ((strict_obj = find_keyword(kwnames, args + nargs, mod->str_strict)) != NULL) nkwargs--; if ((dec_hook = find_keyword(kwnames, args + nargs, mod->str_dec_hook)) != NULL) nkwargs--; if ((ext_hook = find_keyword(kwnames, args + nargs, mod->str_ext_hook)) != NULL) nkwargs--; if (nkwargs > 0) { PyErr_SetString( PyExc_TypeError, "Extra keyword arguments provided" ); return NULL; } } /* Handle strict */ if (strict_obj != NULL) { strict = PyObject_IsTrue(strict_obj); if (strict < 0) return NULL; } /* Handle dec_hook */ if (dec_hook == Py_None) { dec_hook = NULL; } if (dec_hook != NULL) { if (!PyCallable_Check(dec_hook)) { PyErr_SetString(PyExc_TypeError, "dec_hook must be callable"); return NULL; } } /* Handle ext_hook */ if (ext_hook == Py_None) { ext_hook = NULL; } if (ext_hook != NULL) { if (!PyCallable_Check(ext_hook)) { PyErr_SetString(PyExc_TypeError, "ext_hook must be callable"); return NULL; } } DecoderState state = { .strict = strict, .dec_hook = dec_hook, .ext_hook = ext_hook }; /* Allocate Any & Struct type nodes (simple, common cases) on the stack, * everything else on the heap */ TypeNode typenode_any = {MS_TYPE_ANY}; TypeNodeSimple typenode_struct; if (type == NULL || type == mod->typing_any) { state.type = &typenode_any; } else if (ms_is_struct_cls(type)) { PyObject *info = StructInfo_Convert(type); if (info == NULL) return NULL; bool array_like = ((StructMetaObject *)type)->array_like == OPT_TRUE; typenode_struct.types = array_like ? MS_TYPE_STRUCT_ARRAY : MS_TYPE_STRUCT; typenode_struct.details[0].pointer = info; state.type = (TypeNode *)(&typenode_struct); } else { state.type = TypeNode_Convert(type); if (state.type == NULL) return NULL; } Py_buffer buffer; buffer.buf = NULL; if (PyObject_GetBuffer(buf, &buffer, PyBUF_CONTIG_RO) >= 0) { state.buffer_obj = buf; state.input_start = buffer.buf; state.input_pos = buffer.buf; state.input_end = state.input_pos + buffer.len; res = mpack_decode(&state, state.type, NULL, false); PyBuffer_Release(&buffer); if (res != NULL && mpack_has_trailing_characters(&state)) { Py_CLEAR(res); } } if (state.type == (TypeNode *)&typenode_struct) { Py_DECREF(typenode_struct.details[0].pointer); } else if (state.type != &typenode_any) { TypeNode_Free(state.type); } return res; } /************************************************************************* * JSON Decoder * *************************************************************************/ typedef struct JSONDecoderState { /* Configuration */ TypeNode *type; PyObject *dec_hook; PyObject *float_hook; bool strict; /* Temporary scratch space */ unsigned char *scratch; Py_ssize_t scratch_capacity; Py_ssize_t scratch_len; /* Per-message attributes */ PyObject *buffer_obj; unsigned char *input_start; unsigned char *input_pos; unsigned char *input_end; } JSONDecoderState; typedef struct JSONDecoder { PyObject_HEAD PyObject *orig_type; /* Configuration */ TypeNode *type; char strict; PyObject *dec_hook; PyObject *float_hook; } JSONDecoder; PyDoc_STRVAR(JSONDecoder__doc__, "Decoder(type='Any', *, strict=True, dec_hook=None, float_hook=None)\n" "--\n" "\n" "A JSON decoder.\n" "\n" "Parameters\n" "----------\n" "type : type, optional\n" " A Python type (in type annotation form) to decode the object as. If\n" " provided, the message will be type checked and decoded as the specified\n" " type. Defaults to `Any`, in which case the message will be decoded using\n" " the default JSON types.\n" "strict : bool, optional\n" " Whether type coercion rules should be strict. Setting to False enables a\n" " wider set of coercion rules from string to non-string types for all values.\n" " Default is True.\n" "dec_hook : callable, optional\n" " An optional callback for handling decoding custom types. Should have the\n" " signature ``dec_hook(type: Type, obj: Any) -> Any``, where ``type`` is the\n" " expected message type, and ``obj`` is the decoded representation composed\n" " of only basic JSON types. This hook should transform ``obj`` into type\n" " ``type``, or raise a ``NotImplementedError`` if unsupported.\n" "float_hook : callable, optional\n" " An optional callback for handling decoding untyped float literals. Should\n" " have the signature ``float_hook(val: str) -> Any``, where ``val`` is the\n" " raw string value of the JSON float. This hook is called to decode any\n" " \"untyped\" float value (e.g. ``typing.Any`` typed). The default is\n" " equivalent to ``float_hook=float``, where all untyped JSON floats are\n" " decoded as python floats. Specifying ``float_hook=decimal.Decimal``\n" " will decode all untyped JSON floats as decimals instead." ); static int JSONDecoder_init(JSONDecoder *self, PyObject *args, PyObject *kwds) { char *kwlist[] = {"type", "strict", "dec_hook", "float_hook", NULL}; MsgspecState *st = msgspec_get_global_state(); PyObject *type = st->typing_any; PyObject *dec_hook = NULL; PyObject *float_hook = NULL; int strict = 1; if (!PyArg_ParseTupleAndKeywords( args, kwds, "|O$pOO", kwlist, &type, &strict, &dec_hook, &float_hook) ) { return -1; } /* Handle dec_hook */ if (dec_hook == Py_None) { dec_hook = NULL; } if (dec_hook != NULL) { if (!PyCallable_Check(dec_hook)) { PyErr_SetString(PyExc_TypeError, "dec_hook must be callable"); return -1; } Py_INCREF(dec_hook); } self->dec_hook = dec_hook; /* Handle float_hook */ if (float_hook == Py_None) { float_hook = NULL; } if (float_hook != NULL) { if (!PyCallable_Check(float_hook)) { PyErr_SetString(PyExc_TypeError, "float_hook must be callable"); return -1; } Py_INCREF(float_hook); } self->float_hook = float_hook; /* Handle strict */ self->strict = strict; /* Handle type */ self->type = TypeNode_Convert(type); if (self->type == NULL) return -1; Py_INCREF(type); self->orig_type = type; return 0; } static int JSONDecoder_traverse(JSONDecoder *self, visitproc visit, void *arg) { int out = TypeNode_traverse(self->type, visit, arg); if (out != 0) return out; Py_VISIT(self->orig_type); Py_VISIT(self->dec_hook); Py_VISIT(self->float_hook); return 0; } static void JSONDecoder_dealloc(JSONDecoder *self) { PyObject_GC_UnTrack(self); TypeNode_Free(self->type); Py_XDECREF(self->orig_type); Py_XDECREF(self->dec_hook); Py_XDECREF(self->float_hook); Py_TYPE(self)->tp_free((PyObject *)self); } static PyObject * JSONDecoder_repr(JSONDecoder *self) { int recursive; PyObject *typstr, *out = NULL; recursive = Py_ReprEnter((PyObject *)self); if (recursive != 0) { return (recursive < 0) ? NULL : PyUnicode_FromString("..."); /* cpylint-ignore */ } typstr = PyObject_Repr(self->orig_type); if (typstr != NULL) { out = PyUnicode_FromFormat("msgspec.json.Decoder(%U)", typstr); } Py_XDECREF(typstr); Py_ReprLeave((PyObject *)self); return out; } static MS_INLINE bool json_read1(JSONDecoderState *self, unsigned char *c) { if (MS_UNLIKELY(self->input_pos == self->input_end)) { ms_err_truncated(); return false; } *c = *self->input_pos; self->input_pos += 1; return true; } static MS_INLINE char json_peek_or_null(JSONDecoderState *self) { if (MS_UNLIKELY(self->input_pos == self->input_end)) return '\0'; return *self->input_pos; } static MS_INLINE bool json_peek_skip_ws(JSONDecoderState *self, unsigned char *s) { while (true) { if (MS_UNLIKELY(self->input_pos == self->input_end)) { ms_err_truncated(); return false; } unsigned char c = *self->input_pos; if (MS_LIKELY(c != ' ' && c != '\n' && c != '\r' && c != '\t')) { *s = c; return true; } self->input_pos++; } } static MS_INLINE bool json_remaining(JSONDecoderState *self, ptrdiff_t remaining) { return self->input_end - self->input_pos >= remaining; } static PyObject * json_err_invalid(JSONDecoderState *self, const char *msg) { PyErr_Format( msgspec_get_global_state()->DecodeError, "JSON is malformed: %s (byte %zd)", msg, (Py_ssize_t)(self->input_pos - self->input_start) ); return NULL; } static MS_INLINE bool json_has_trailing_characters(JSONDecoderState *self) { while (self->input_pos != self->input_end) { unsigned char c = *self->input_pos++; if (MS_UNLIKELY(!(c == ' ' || c == '\n' || c == '\t' || c == '\r'))) { json_err_invalid(self, "trailing characters"); return true; } } return false; } static int json_skip(JSONDecoderState *self); static PyObject * json_decode( JSONDecoderState *self, TypeNode *type, PathNode *path ); static PyObject * json_decode_none(JSONDecoderState *self, TypeNode *type, PathNode *path) { self->input_pos++; /* Already checked as 'n' */ if (MS_UNLIKELY(!json_remaining(self, 3))) { ms_err_truncated(); return NULL; } unsigned char c1 = *self->input_pos++; unsigned char c2 = *self->input_pos++; unsigned char c3 = *self->input_pos++; if (MS_UNLIKELY(c1 != 'u' || c2 != 'l' || c3 != 'l')) { return json_err_invalid(self, "invalid character"); } if (type->types & (MS_TYPE_ANY | MS_TYPE_NONE)) { Py_INCREF(Py_None); return Py_None; } return ms_validation_error("null", type, path); } static PyObject * json_decode_true(JSONDecoderState *self, TypeNode *type, PathNode *path) { self->input_pos++; /* Already checked as 't' */ if (MS_UNLIKELY(!json_remaining(self, 3))) { ms_err_truncated(); return NULL; } unsigned char c1 = *self->input_pos++; unsigned char c2 = *self->input_pos++; unsigned char c3 = *self->input_pos++; if (MS_UNLIKELY(c1 != 'r' || c2 != 'u' || c3 != 'e')) { return json_err_invalid(self, "invalid character"); } if (type->types & (MS_TYPE_ANY | MS_TYPE_BOOL | MS_TYPE_BOOLLITERAL_TRUE)) { Py_INCREF(Py_True); return Py_True; } if (type->types & MS_TYPE_BOOLLITERAL_FALSE) { ms_raise_validation_error(path, "Invalid enum value %R%U", Py_True); return NULL; } return ms_validation_error("bool", type, path); } static PyObject * json_decode_false(JSONDecoderState *self, TypeNode *type, PathNode *path) { self->input_pos++; /* Already checked as 'f' */ if (MS_UNLIKELY(!json_remaining(self, 4))) { ms_err_truncated(); return NULL; } unsigned char c1 = *self->input_pos++; unsigned char c2 = *self->input_pos++; unsigned char c3 = *self->input_pos++; unsigned char c4 = *self->input_pos++; if (MS_UNLIKELY(c1 != 'a' || c2 != 'l' || c3 != 's' || c4 != 'e')) { return json_err_invalid(self, "invalid character"); } if (type->types & (MS_TYPE_ANY | MS_TYPE_BOOL | MS_TYPE_BOOLLITERAL_FALSE)) { Py_INCREF(Py_False); return Py_False; } if (type->types & MS_TYPE_BOOLLITERAL_TRUE) { ms_raise_validation_error(path, "Invalid enum value %R%U", Py_False); return NULL; } return ms_validation_error("bool", type, path); } #define JS_SCRATCH_MAX_SIZE 1024 static int json_scratch_resize(JSONDecoderState *state, Py_ssize_t size) { unsigned char *temp = PyMem_Realloc(state->scratch, size); if (MS_UNLIKELY(temp == NULL)) { PyErr_NoMemory(); return -1; } state->scratch = temp; state->scratch_capacity = size; return 0; } static MS_NOINLINE int json_scratch_expand(JSONDecoderState *state, Py_ssize_t required) { size_t new_size = Py_MAX(8, 1.5 * required); return json_scratch_resize(state, new_size); } static int json_scratch_extend(JSONDecoderState *state, const void *buf, Py_ssize_t size) { Py_ssize_t required = state->scratch_len + size; if (MS_UNLIKELY(required >= state->scratch_capacity)) { if (MS_UNLIKELY(json_scratch_expand(state, required) < 0)) return -1; } memcpy(state->scratch + state->scratch_len, buf, size); state->scratch_len += size; return 0; } /* -1: '\', '"', and forbidden characters * 0: ascii * 1: non-ascii */ static const int8_t char_types[256] = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, }; /* Is char `"`, `\`, or nonascii? */ static MS_INLINE bool char_is_special_or_nonascii(unsigned char c) { return char_types[c] != 0; } /* Is char `"` or `\`? */ static MS_INLINE bool char_is_special(unsigned char c) { return char_types[c] < 0; } static int json_read_codepoint(JSONDecoderState *self, unsigned int *out) { unsigned char c; unsigned int cp = 0; if (!json_remaining(self, 4)) return ms_err_truncated(); for (int i = 0; i < 4; i++) { c = *self->input_pos++; if (c >= '0' && c <= '9') { c -= '0'; } else if (c >= 'a' && c <= 'f') { c = c - 'a' + 10; } else if (c >= 'A' && c <= 'F') { c = c - 'A' + 10; } else { json_err_invalid(self, "invalid character in unicode escape"); return -1; } cp = (cp << 4) + c; } *out = cp; return 0; } static MS_NOINLINE int json_handle_unicode_escape(JSONDecoderState *self) { unsigned int cp; if (json_read_codepoint(self, &cp) < 0) return -1; if (0xDC00 <= cp && cp <= 0xDFFF) { json_err_invalid(self, "invalid utf-16 surrogate pair"); return -1; } else if (0xD800 <= cp && cp <= 0xDBFF) { /* utf-16 pair, parse 2nd pair */ unsigned int cp2; if (!json_remaining(self, 6)) return ms_err_truncated(); if (self->input_pos[0] != '\\' || self->input_pos[1] != 'u') { json_err_invalid(self, "unexpected end of escaped utf-16 surrogate pair"); return -1; } self->input_pos += 2; if (json_read_codepoint(self, &cp2) < 0) return -1; if (cp2 < 0xDC00 || cp2 > 0xDFFF) { json_err_invalid(self, "invalid utf-16 surrogate pair"); return -1; } cp = 0x10000 + (((cp - 0xD800) << 10) | (cp2 - 0xDC00)); } /* Encode the codepoint as utf-8 */ unsigned char *p = self->scratch + self->scratch_len; if (cp < 0x80) { *p++ = cp; self->scratch_len += 1; } else if (cp < 0x800) { *p++ = 0xC0 | (cp >> 6); *p++ = 0x80 | (cp & 0x3F); self->scratch_len += 2; } else if (cp < 0x10000) { *p++ = 0xE0 | (cp >> 12); *p++ = 0x80 | ((cp >> 6) & 0x3F); *p++ = 0x80 | (cp & 0x3F); self->scratch_len += 3; } else { *p++ = 0xF0 | (cp >> 18); *p++ = 0x80 | ((cp >> 12) & 0x3F); *p++ = 0x80 | ((cp >> 6) & 0x3F); *p++ = 0x80 | (cp & 0x3F); self->scratch_len += 4; } return 0; } #define parse_ascii_pre(i) \ if (MS_UNLIKELY(char_is_special_or_nonascii(self->input_pos[i]))) goto parse_ascii_##i; #define parse_ascii_post(i) \ parse_ascii_##i: \ self->input_pos += i; \ goto parse_ascii_end; #define parse_unicode_pre(i) \ if (MS_UNLIKELY(char_is_special(self->input_pos[i]))) goto parse_unicode_##i; #define parse_unicode_post(i) \ parse_unicode_##i: \ self->input_pos += i; \ goto parse_unicode_end; static MS_NOINLINE Py_ssize_t json_decode_string_view_copy( JSONDecoderState *self, char **out, bool *is_ascii, unsigned char *start ) { unsigned char c; self->scratch_len = 0; top: OPT_FORCE_RELOAD(*self->input_pos); c = *self->input_pos; if (c == '\\') { /* Write the current block to scratch */ Py_ssize_t block_size = self->input_pos - start; /* An escape string requires at most 4 bytes to decode */ Py_ssize_t required = self->scratch_len + block_size + 4; if (MS_UNLIKELY(required >= self->scratch_capacity)) { if (MS_UNLIKELY(json_scratch_expand(self, required) < 0)) return -1; } memcpy(self->scratch + self->scratch_len, start, block_size); self->scratch_len += block_size; self->input_pos++; if (!json_read1(self, &c)) return -1; switch (c) { case 'n': { *(self->scratch + self->scratch_len) = '\n'; self->scratch_len++; break; } case '"': { *(self->scratch + self->scratch_len) = '"'; self->scratch_len++; break; } case 't': { *(self->scratch + self->scratch_len) = '\t'; self->scratch_len++; break; } case 'r': { *(self->scratch + self->scratch_len) = '\r'; self->scratch_len++; break; } case '\\': { *(self->scratch + self->scratch_len) = '\\'; self->scratch_len++; break; } case '/': { *(self->scratch + self->scratch_len) = '/'; self->scratch_len++; break; } case 'b': { *(self->scratch + self->scratch_len) = '\b'; self->scratch_len++; break; } case 'f': { *(self->scratch + self->scratch_len) = '\f'; self->scratch_len++; break; } case 'u': { *is_ascii = false; if (json_handle_unicode_escape(self) < 0) return -1; break; } default: json_err_invalid(self, "invalid escape character in string"); return -1; } start = self->input_pos; } else if (c == '"') { if (json_scratch_extend(self, start, self->input_pos - start) < 0) return -1; self->input_pos++; *out = (char *)(self->scratch); return self->scratch_len; } else { json_err_invalid(self, "invalid character"); return -1; } /* Loop until `"`, `\`, or a non-ascii character */ while (self->input_end - self->input_pos >= 8) { repeat8(parse_ascii_pre); self->input_pos += 8; continue; repeat8(parse_ascii_post); } while (true) { if (MS_UNLIKELY(self->input_pos == self->input_end)) return ms_err_truncated(); if (MS_UNLIKELY(char_is_special_or_nonascii(*self->input_pos))) break; self->input_pos++; } parse_ascii_end: OPT_FORCE_RELOAD(*self->input_pos); if (MS_UNLIKELY(*self->input_pos & 0x80)) { *is_ascii = false; /* Loop until `"` or `\` */ while (self->input_end - self->input_pos >= 8) { repeat8(parse_unicode_pre); self->input_pos += 8; continue; repeat8(parse_unicode_post); } while (true) { if (MS_UNLIKELY(self->input_pos == self->input_end)) return ms_err_truncated(); if (MS_UNLIKELY(char_is_special(*self->input_pos))) break; self->input_pos++; } } parse_unicode_end: goto top; } static Py_ssize_t json_decode_string_view(JSONDecoderState *self, char **out, bool *is_ascii) { self->input_pos++; /* Skip '"' */ unsigned char *start = self->input_pos; /* Loop until `"`, `\`, or a non-ascii character */ while (self->input_end - self->input_pos >= 8) { repeat8(parse_ascii_pre); self->input_pos += 8; continue; repeat8(parse_ascii_post); } while (true) { if (MS_UNLIKELY(self->input_pos == self->input_end)) return ms_err_truncated(); if (MS_UNLIKELY(char_is_special_or_nonascii(*self->input_pos))) break; self->input_pos++; } parse_ascii_end: OPT_FORCE_RELOAD(*self->input_pos); if (MS_LIKELY(*self->input_pos == '"')) { Py_ssize_t size = self->input_pos - start; self->input_pos++; *out = (char *)start; return size; } if (MS_UNLIKELY(*self->input_pos & 0x80)) { *is_ascii = false; /* Loop until `"` or `\` */ while (self->input_end - self->input_pos >= 8) { repeat8(parse_unicode_pre); self->input_pos += 8; continue; repeat8(parse_unicode_post); } while (true) { if (MS_UNLIKELY(self->input_pos == self->input_end)) return ms_err_truncated(); if (MS_UNLIKELY(char_is_special(*self->input_pos))) break; self->input_pos++; } } parse_unicode_end: OPT_FORCE_RELOAD(*self->input_pos); if (MS_LIKELY(*self->input_pos == '"')) { Py_ssize_t size = self->input_pos - start; self->input_pos++; *out = (char *)start; return size; } return json_decode_string_view_copy(self, out, is_ascii, start); } static int json_skip_string(JSONDecoderState *self) { self->input_pos++; /* Skip '"' */ parse_unicode: /* Loop until `"` or `\` */ while (self->input_end - self->input_pos >= 8) { repeat8(parse_unicode_pre); self->input_pos += 8; continue; repeat8(parse_unicode_post); } while (true) { if (MS_UNLIKELY(self->input_pos == self->input_end)) return ms_err_truncated(); if (MS_UNLIKELY(char_is_special(*self->input_pos))) break; self->input_pos++; } parse_unicode_end: OPT_FORCE_RELOAD(*self->input_pos); if (MS_LIKELY(*self->input_pos == '"')) { self->input_pos++; return 0; } else if (*self->input_pos == '\\') { self->input_pos++; if (MS_UNLIKELY(self->input_pos == self->input_end)) return ms_err_truncated(); switch (*self->input_pos) { case '"': case '\\': case '/': case 'b': case 'f': case 'n': case 'r': case 't': self->input_pos++; break; case 'u': { self->input_pos++; unsigned int cp; if (json_read_codepoint(self, &cp) < 0) return -1; if (0xDC00 <= cp && cp <= 0xDFFF) { json_err_invalid(self, "invalid utf-16 surrogate pair"); return -1; } else if (0xD800 <= cp && cp <= 0xDBFF) { /* utf-16 pair, parse 2nd pair */ unsigned int cp2; if (!json_remaining(self, 6)) return ms_err_truncated(); if (self->input_pos[0] != '\\' || self->input_pos[1] != 'u') { json_err_invalid(self, "unexpected end of hex escape"); return -1; } self->input_pos += 2; if (json_read_codepoint(self, &cp2) < 0) return -1; if (cp2 < 0xDC00 || cp2 > 0xDFFF) { json_err_invalid(self, "invalid utf-16 surrogate pair"); return -1; } cp = 0x10000 + (((cp - 0xD800) << 10) | (cp2 - 0xDC00)); } break; } default: { json_err_invalid(self, "invalid escaped character"); return -1; } } goto parse_unicode; } else { json_err_invalid(self, "invalid character"); return -1; } } #undef parse_ascii_pre #undef parse_ascii_post #undef parse_unicode_pre #undef parse_unicode_post /* A table of the corresponding base64 value for each character, or -1 if an * invalid character in the base64 alphabet (note the padding char '=' is * handled elsewhere, so is marked as invalid here as well) */ static const uint8_t base64_decode_table[] = { -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,62, -1,-1,-1,63, 52,53,54,55, 56,57,58,59, 60,61,-1,-1, -1,-1,-1,-1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10, 11,12,13,14, 15,16,17,18, 19,20,21,22, 23,24,25,-1, -1,-1,-1,-1, -1,26,27,28, 29,30,31,32, 33,34,35,36, 37,38,39,40, 41,42,43,44, 45,46,47,48, 49,50,51,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, }; static PyObject * json_decode_binary( const char *buffer, Py_ssize_t size, TypeNode *type, PathNode *path ) { PyObject *out = NULL; char *bin_buffer; Py_ssize_t bin_size, i; if (size % 4 != 0) goto invalid; int npad = 0; if (size > 0 && buffer[size - 1] == '=') npad++; if (size > 1 && buffer[size - 2] == '=') npad++; bin_size = (size / 4) * 3 - npad; if (!ms_passes_bytes_constraints(bin_size, type, path)) return NULL; if (type->types & MS_TYPE_BYTES) { out = PyBytes_FromStringAndSize(NULL, bin_size); if (out == NULL) return NULL; bin_buffer = PyBytes_AS_STRING(out); } else if (type->types & MS_TYPE_BYTEARRAY) { out = PyByteArray_FromStringAndSize(NULL, bin_size); if (out == NULL) return NULL; bin_buffer = PyByteArray_AS_STRING(out); } else { PyObject *temp = PyBytes_FromStringAndSize(NULL, bin_size); if (temp == NULL) return NULL; bin_buffer = PyBytes_AS_STRING(temp); out = PyMemoryView_FromObject(temp); Py_DECREF(temp); if (out == NULL) return NULL; } int quad = 0; uint8_t left_c = 0; for (i = 0; i < size - npad; i++) { uint8_t c = base64_decode_table[(uint8_t)(buffer[i])]; if (c >= 64) goto invalid; switch (quad) { case 0: quad = 1; left_c = c; break; case 1: quad = 2; *bin_buffer++ = (left_c << 2) | (c >> 4); left_c = c & 0x0f; break; case 2: quad = 3; *bin_buffer++ = (left_c << 4) | (c >> 2); left_c = c & 0x03; break; case 3: quad = 0; *bin_buffer++ = (left_c << 6) | c; left_c = 0; break; } } return out; invalid: Py_XDECREF(out); return ms_error_with_path("Invalid base64 encoded string%U", path); } static PyObject * json_decode_string(JSONDecoderState *self, TypeNode *type, PathNode *path) { char *view = NULL; bool is_ascii = true; Py_ssize_t size = json_decode_string_view(self, &view, &is_ascii); if (size < 0) return NULL; if (MS_LIKELY(type->types & (MS_TYPE_STR | MS_TYPE_ANY))) { PyObject *out; if (MS_LIKELY(is_ascii)) { out = PyUnicode_New(size, 127); memcpy(ascii_get_buffer(out), view, size); } else { out = PyUnicode_DecodeUTF8(view, size, NULL); } return ms_check_str_constraints(out, type, path); } else if (MS_UNLIKELY(!self->strict)) { bool invalid = false; PyObject *out = ms_decode_str_lax(view, size, type, path, &invalid); if (!invalid) return out; } if (MS_UNLIKELY(type->types & MS_TYPE_DATETIME)) { return ms_decode_datetime_from_str(view, size, type, path); } else if (MS_UNLIKELY(type->types & MS_TYPE_DATE)) { return ms_decode_date(view, size, path); } else if (MS_UNLIKELY(type->types & MS_TYPE_TIME)) { return ms_decode_time(view, size, type, path); } else if (MS_UNLIKELY(type->types & MS_TYPE_TIMEDELTA)) { return ms_decode_timedelta(view, size, type, path); } else if (MS_UNLIKELY(type->types & MS_TYPE_UUID)) { return ms_decode_uuid_from_str(view, size, path); } else if (MS_UNLIKELY(type->types & MS_TYPE_DECIMAL)) { return ms_decode_decimal(view, size, is_ascii, path, NULL); } else if ( MS_UNLIKELY(type->types & (MS_TYPE_BYTES | MS_TYPE_BYTEARRAY | MS_TYPE_MEMORYVIEW) ) ) { return json_decode_binary(view, size, type, path); } else if (MS_UNLIKELY(type->types & (MS_TYPE_ENUM | MS_TYPE_STRLITERAL))) { return ms_decode_str_enum_or_literal(view, size, type, path); } return ms_validation_error("str", type, path); } static PyObject * json_decode_dict_key_fallback( JSONDecoderState *self, const char *view, Py_ssize_t size, bool is_ascii, TypeNode *type, PathNode *path ) { if (type->types & (MS_TYPE_STR | MS_TYPE_ANY)) { PyObject *out; if (is_ascii) { out = PyUnicode_New(size, 127); if (MS_UNLIKELY(out == NULL)) return NULL; memcpy(ascii_get_buffer(out), view, size); } else { out = PyUnicode_DecodeUTF8(view, size, NULL); } if (MS_UNLIKELY(type->types & (MS_TYPE_CUSTOM | MS_TYPE_CUSTOM_GENERIC))) { return ms_decode_custom(out, self->dec_hook, type, path); } return ms_check_str_constraints(out, type, path); } if (type->types & ( MS_TYPE_INT | MS_TYPE_INTENUM | MS_TYPE_INTLITERAL | MS_TYPE_FLOAT | MS_TYPE_DECIMAL | ((!self->strict) * (MS_TYPE_DATETIME | MS_TYPE_TIMEDELTA)) ) ) { PyObject *out; if (maybe_parse_number(view, size, type, path, self->strict, &out)) { return out; } } if (type->types & (MS_TYPE_ENUM | MS_TYPE_STRLITERAL)) { return ms_decode_str_enum_or_literal(view, size, type, path); } else if (type->types & MS_TYPE_UUID) { return ms_decode_uuid_from_str(view, size, path); } else if (type->types & MS_TYPE_DATETIME) { return ms_decode_datetime_from_str(view, size, type, path); } else if (type->types & MS_TYPE_DATE) { return ms_decode_date(view, size, path); } else if (type->types & MS_TYPE_TIME) { return ms_decode_time(view, size, type, path); } else if (type->types & MS_TYPE_TIMEDELTA) { return ms_decode_timedelta(view, size, type, path); } else if (type->types & (MS_TYPE_BYTES | MS_TYPE_MEMORYVIEW)) { return json_decode_binary(view, size, type, path); } else { return ms_validation_error("str", type, path); } } static PyObject * json_decode_dict_key(JSONDecoderState *self, TypeNode *type, PathNode *path) { bool is_ascii = true; char *view = NULL; Py_ssize_t size; size = json_decode_string_view(self, &view, &is_ascii); if (size < 0) return NULL; #ifndef Py_GIL_DISABLED bool is_str = type->types == MS_TYPE_ANY || type->types == MS_TYPE_STR; bool cacheable = is_str && is_ascii && size > 0 && size <= STRING_CACHE_MAX_STRING_LENGTH; if (MS_UNLIKELY(!cacheable)) { return json_decode_dict_key_fallback(self, view, size, is_ascii, type, path); } uint32_t hash = murmur2(view, size); uint32_t index = hash % STRING_CACHE_SIZE; PyObject *existing = string_cache[index]; if (MS_LIKELY(existing != NULL)) { Py_ssize_t e_size = ((PyASCIIObject *)existing)->length; char *e_str = ascii_get_buffer(existing); if (MS_LIKELY(size == e_size && memcmp(view, e_str, size) == 0)) { Py_INCREF(existing); return existing; } } /* Create a new ASCII str object */ PyObject *new = PyUnicode_New(size, 127); if (MS_UNLIKELY(new == NULL)) return NULL; memcpy(ascii_get_buffer(new), view, size); /* Swap out the str in the cache */ Py_XDECREF(existing); Py_INCREF(new); string_cache[index] = new; return new; #else return json_decode_dict_key_fallback(self, view, size, is_ascii, type, path); #endif } static PyObject * json_decode_list(JSONDecoderState *self, TypeNode *type, TypeNode *el_type, PathNode *path) { unsigned char c; bool first = true; PathNode el_path = {path, 0, NULL}; self->input_pos++; /* Skip '[' */ PyObject *out = PyList_New(0); if (out == NULL) return NULL; if (Py_EnterRecursiveCall(" while deserializing an object")) { Py_DECREF(out); return NULL; /* cpylint-ignore */ } while (true) { if (MS_UNLIKELY(!json_peek_skip_ws(self, &c))) goto error; /* Parse ']' or ',', then peek the next character */ if (c == ']') { self->input_pos++; break; } else if (c == ',' && !first) { self->input_pos++; if (MS_UNLIKELY(!json_peek_skip_ws(self, &c))) goto error; } else if (first) { /* Only the first item doesn't need a comma delimiter */ first = false; } else { json_err_invalid(self, "expected ',' or ']'"); goto error; } if (MS_UNLIKELY(c == ']')) { json_err_invalid(self, "trailing comma in array"); goto error; } /* Parse item */ PyObject *item = json_decode(self, el_type, &el_path); if (item == NULL) goto error; el_path.index++; /* Append item to list */ if (MS_LIKELY((LIST_CAPACITY(out) > Py_SIZE(out)))) { PyList_SET_ITEM(out, Py_SIZE(out), item); Py_SET_SIZE(out, Py_SIZE(out) + 1); } else { int status = PyList_Append(out, item); Py_DECREF(item); if (MS_UNLIKELY(status < 0)) goto error; } } if (MS_UNLIKELY(!ms_passes_array_constraints(PyList_GET_SIZE(out), type, path))) { goto error; } Py_LeaveRecursiveCall(); return out; error: Py_LeaveRecursiveCall(); Py_DECREF(out); return NULL; } static PyObject * json_decode_set( JSONDecoderState *self, TypeNode *type, TypeNode *el_type, PathNode *path ) { PyObject *out, *item = NULL; unsigned char c; bool first = true; PathNode el_path = {path, 0, NULL}; self->input_pos++; /* Skip '[' */ out = (type->types & MS_TYPE_SET) ? PySet_New(NULL) : PyFrozenSet_New(NULL); if (out == NULL) return NULL; if (Py_EnterRecursiveCall(" while deserializing an object")) { Py_DECREF(out); return NULL; /* cpylint-ignore */ } while (true) { if (MS_UNLIKELY(!json_peek_skip_ws(self, &c))) goto error; /* Parse ']' or ',', then peek the next character */ if (c == ']') { self->input_pos++; break; } else if (c == ',' && !first) { self->input_pos++; if (MS_UNLIKELY(!json_peek_skip_ws(self, &c))) goto error; } else if (first) { /* Only the first item doesn't need a comma delimiter */ first = false; } else { json_err_invalid(self, "expected ',' or ']'"); goto error; } if (MS_UNLIKELY(c == ']')) { json_err_invalid(self, "trailing comma in array"); goto error; } /* Parse item */ item = json_decode(self, el_type, &el_path); if (item == NULL) goto error; el_path.index++; /* Append item to set */ if (PySet_Add(out, item) < 0) goto error; Py_CLEAR(item); } if (MS_UNLIKELY(!ms_passes_array_constraints(PySet_GET_SIZE(out), type, path))) { goto error; } Py_LeaveRecursiveCall(); return out; error: Py_LeaveRecursiveCall(); Py_DECREF(out); Py_XDECREF(item); return NULL; } static PyObject * json_decode_vartuple(JSONDecoderState *self, TypeNode *type, TypeNode *el_type, PathNode *path) { PyObject *list, *item, *out = NULL; Py_ssize_t size, i; list = json_decode_list(self, type, el_type, path); if (list == NULL) return NULL; size = PyList_GET_SIZE(list); out = PyTuple_New(size); if (out != NULL) { for (i = 0; i < size; i++) { item = PyList_GET_ITEM(list, i); PyTuple_SET_ITEM(out, i, item); PyList_SET_ITEM(list, i, NULL); /* Drop reference in old list */ } } Py_DECREF(list); return out; } static PyObject * json_decode_fixtuple(JSONDecoderState *self, TypeNode *type, PathNode *path) { PyObject *out, *item; unsigned char c; bool first = true; PathNode el_path = {path, 0, NULL}; Py_ssize_t i = 0, offset, fixtuple_size; TypeNode_get_fixtuple(type, &offset, &fixtuple_size); self->input_pos++; /* Skip '[' */ out = PyTuple_New(fixtuple_size); if (out == NULL) return NULL; if (Py_EnterRecursiveCall(" while deserializing an object")) { Py_DECREF(out); return NULL; /* cpylint-ignore */ } while (true) { if (MS_UNLIKELY(!json_peek_skip_ws(self, &c))) goto error; /* Parse ']' or ',', then peek the next character */ if (c == ']') { self->input_pos++; if (MS_UNLIKELY(i < fixtuple_size)) goto size_error; break; } else if (c == ',' && !first) { self->input_pos++; if (MS_UNLIKELY(!json_peek_skip_ws(self, &c))) goto error; } else if (first) { /* Only the first item doesn't need a comma delimiter */ first = false; } else { json_err_invalid(self, "expected ',' or ']'"); goto error; } if (MS_UNLIKELY(c == ']')) { json_err_invalid(self, "trailing comma in array"); goto error; } /* Check we don't have too many elements */ if (MS_UNLIKELY(i >= fixtuple_size)) goto size_error; /* Parse item */ item = json_decode(self, type->details[offset + i].pointer, &el_path); if (item == NULL) goto error; el_path.index++; /* Add item to tuple */ PyTuple_SET_ITEM(out, i, item); i++; } Py_LeaveRecursiveCall(); return out; size_error: ms_raise_validation_error( path, "Expected `array` of length %zd%U", fixtuple_size ); error: Py_LeaveRecursiveCall(); Py_DECREF(out); return NULL; } static PyObject * json_decode_namedtuple(JSONDecoderState *self, TypeNode *type, PathNode *path) { unsigned char c; bool first = true; Py_ssize_t nfields, ndefaults, nrequired; NamedTupleInfo *info = TypeNode_get_namedtuple_info(type); nfields = Py_SIZE(info); ndefaults = info->defaults == NULL ? 0 : PyTuple_GET_SIZE(info->defaults); nrequired = nfields - ndefaults; self->input_pos++; /* Skip '[' */ if (Py_EnterRecursiveCall(" while deserializing an object")) return NULL; PyTypeObject *nt_type = (PyTypeObject *)(info->class); PyObject *out = nt_type->tp_alloc(nt_type, nfields); if (out == NULL) goto error; MS_TUPLE_RESET_HASH(out); for (Py_ssize_t i = 0; i < nfields; i++) { PyTuple_SET_ITEM(out, i, NULL); } Py_ssize_t i = 0; while (true) { if (MS_UNLIKELY(!json_peek_skip_ws(self, &c))) goto error; /* Parse ']' or ',', then peek the next character */ if (c == ']') { self->input_pos++; if (MS_UNLIKELY(i < nrequired)) goto size_error; break; } else if (c == ',' && !first) { self->input_pos++; if (MS_UNLIKELY(!json_peek_skip_ws(self, &c))) goto error; } else if (first) { /* Only the first item doesn't need a comma delimiter */ first = false; } else { json_err_invalid(self, "expected ',' or ']'"); goto error; } if (MS_UNLIKELY(c == ']')) { json_err_invalid(self, "trailing comma in array"); goto error; } /* Check we don't have too many elements */ if (MS_UNLIKELY(i >= nfields)) goto size_error; /* Parse item */ PathNode el_path = {path, i, NULL}; PyObject *item = json_decode(self, info->types[i], &el_path); if (item == NULL) goto error; /* Add item to tuple */ PyTuple_SET_ITEM(out, i, item); i++; } Py_LeaveRecursiveCall(); /* Fill in defaults */ for (; i < nfields; i++) { PyObject *item = PyTuple_GET_ITEM(info->defaults, i - nrequired); Py_INCREF(item); PyTuple_SET_ITEM(out, i, item); } return out; size_error: if (ndefaults == 0) { ms_raise_validation_error( path, "Expected `array` of length %zd%U", nfields ); } else { ms_raise_validation_error( path, "Expected `array` of length %zd to %zd%U", nrequired, nfields ); } error: Py_LeaveRecursiveCall(); Py_DECREF(out); return NULL; } static PyObject * json_decode_struct_array_inner( JSONDecoderState *self, StructInfo *info, PathNode *path, Py_ssize_t starting_index ) { Py_ssize_t nfields, ndefaults, nrequired, npos, i = 0; PyObject *out, *item = NULL; unsigned char c; bool is_gc, should_untrack; bool first = starting_index == 0; StructMetaObject *st_type = info->class; PathNode item_path = {path, starting_index}; out = Struct_alloc((PyTypeObject *)(st_type)); if (out == NULL) return NULL; nfields = PyTuple_GET_SIZE(st_type->struct_encode_fields); ndefaults = PyTuple_GET_SIZE(st_type->struct_defaults); nrequired = nfields - st_type->n_trailing_defaults; npos = nfields - ndefaults; is_gc = MS_TYPE_IS_GC(st_type); should_untrack = is_gc; if (Py_EnterRecursiveCall(" while deserializing an object")) { Py_DECREF(out); return NULL; /* cpylint-ignore */ } while (true) { if (MS_UNLIKELY(!json_peek_skip_ws(self, &c))) goto error; /* Parse ']' or ',', then peek the next character */ if (c == ']') { self->input_pos++; break; } else if (c == ',' && !first) { self->input_pos++; if (MS_UNLIKELY(!json_peek_skip_ws(self, &c))) goto error; } else if (first) { /* Only the first item doesn't need a comma delimiter */ first = false; } else { json_err_invalid(self, "expected ',' or ']'"); goto error; } if (MS_UNLIKELY(c == ']')) { json_err_invalid(self, "trailing comma in array"); goto error; } if (MS_LIKELY(i < nfields)) { /* Parse item */ item = json_decode(self, info->types[i], &item_path); if (MS_UNLIKELY(item == NULL)) goto error; Struct_set_index(out, i, item); if (should_untrack) { should_untrack = !MS_MAYBE_TRACKED(item); } i++; item_path.index++; } else { if (MS_UNLIKELY(st_type->forbid_unknown_fields == OPT_TRUE)) { ms_raise_validation_error( path, "Expected `array` of at most length %zd", nfields ); goto error; } else { /* Skip trailing fields */ if (json_skip(self) < 0) goto error; } } } /* Check for missing required fields */ if (i < nrequired) { ms_raise_validation_error( path, "Expected `array` of at least length %zd, got %zd%U", nrequired + starting_index, i + starting_index ); goto error; } /* Fill in missing fields with defaults */ for (; i < nfields; i++) { item = get_default( PyTuple_GET_ITEM(st_type->struct_defaults, i - npos) ); if (item == NULL) goto error; Struct_set_index(out, i, item); if (should_untrack) { should_untrack = !MS_MAYBE_TRACKED(item); } } if (Struct_decode_post_init(st_type, out, path) < 0) goto error; Py_LeaveRecursiveCall(); if (is_gc && should_untrack && MS_IS_TRACKED(out)) PyObject_GC_UnTrack(out); return out; error: Py_LeaveRecursiveCall(); Py_DECREF(out); return NULL; } /* Decode an integer. If the value fits in an int64_t, it will be stored in * `out`, otherwise it will be stored in `uout`. A return value of -1 indicates * an error. */ static int json_decode_cint(JSONDecoderState *self, int64_t *out, uint64_t *uout, PathNode *path) { uint64_t mantissa = 0; bool is_negative = false; unsigned char c; unsigned char *orig_input_pos = self->input_pos; if (MS_UNLIKELY(!json_peek_skip_ws(self, &c))) return -1; /* Parse minus sign (if present) */ if (c == '-') { self->input_pos++; c = json_peek_or_null(self); is_negative = true; } /* Parse integer */ if (MS_UNLIKELY(c == '0')) { /* Ensure at most one leading zero */ self->input_pos++; c = json_peek_or_null(self); if (MS_UNLIKELY(is_digit(c))) { json_err_invalid(self, "invalid number"); return -1; } } else { /* Parse the integer part of the number. * * We can read the first 19 digits safely into a uint64 without * checking for overflow. Removing overflow checks from the loop gives * a measurable performance boost. */ size_t remaining = self->input_end - self->input_pos; size_t n_safe = Py_MIN(19, remaining); while (n_safe) { c = *self->input_pos; if (!is_digit(c)) goto end_integer; self->input_pos++; n_safe--; mantissa = mantissa * 10 + (uint64_t)(c - '0'); } if (MS_UNLIKELY(remaining > 19)) { /* Reading a 20th digit may or may not cause overflow. Any * additional digits definitely will. Read the 20th digit (and * check for a 21st), taking the slow path upon overflow. */ c = *self->input_pos; if (MS_UNLIKELY(is_digit(c))) { self->input_pos++; uint64_t mantissa2 = mantissa * 10 + (uint64_t)(c - '0'); bool overflowed = (mantissa2 < mantissa) || ((mantissa2 - (uint64_t)(c - '0')) / 10) != mantissa; if (MS_UNLIKELY(overflowed || is_digit(json_peek_or_null(self)))) { goto error_not_int; } mantissa = mantissa2; c = json_peek_or_null(self); } } end_integer: /* There must be at least one digit */ if (MS_UNLIKELY(mantissa == 0)) goto error_not_int; } if (c == '.' || c == 'e' || c == 'E') goto error_not_int; if (is_negative) { if (mantissa > 1ull << 63) goto error_not_int; *out = -1 * (int64_t)mantissa; } else { if (mantissa > LLONG_MAX) { *uout = mantissa; } else { *out = mantissa; } } return 0; error_not_int: /* Use skip to catch malformed JSON */ self->input_pos = orig_input_pos; if (json_skip(self) < 0) return -1; ms_error_with_path("Expected `int`%U", path); return -1; } static Py_ssize_t json_decode_cstr(JSONDecoderState *self, char **out, PathNode *path) { unsigned char c; if (MS_UNLIKELY(!json_peek_skip_ws(self, &c))) return -1; if (c != '"') { /* Use skip to catch malformed JSON */ if (json_skip(self) < 0) return -1; /* JSON is valid but the wrong type */ ms_error_with_path("Expected `str`%U", path); return -1; } bool is_ascii = true; return json_decode_string_view(self, out, &is_ascii); } static int json_ensure_array_nonempty( JSONDecoderState *self, StructMetaObject *st_type, PathNode *path ) { unsigned char c; /* Check for an early end to the array */ if (MS_UNLIKELY(!json_peek_skip_ws(self, &c))) return -1; if (c == ']') { Py_ssize_t expected_size; if (st_type == NULL) { /* If we don't know the type, the most we know is that the minimum * size is 1 */ expected_size = 1; } else { /* n_fields - n_optional_fields + 1 tag */ expected_size = PyTuple_GET_SIZE(st_type->struct_encode_fields) - PyTuple_GET_SIZE(st_type->struct_defaults) + 1; } ms_raise_validation_error( path, "Expected `array` of at least length %zd, got 0%U", expected_size ); return -1; } return 0; } static int json_ensure_tag_matches( JSONDecoderState *self, PathNode *path, PyObject *expected_tag ) { if (PyUnicode_CheckExact(expected_tag)) { char *tag = NULL; Py_ssize_t tag_size; tag_size = json_decode_cstr(self, &tag, path); if (tag_size < 0) return -1; /* Check that tag matches expected tag value */ Py_ssize_t expected_size; const char *expected_str = unicode_str_and_size_nocheck( expected_tag, &expected_size ); if (tag_size != expected_size || memcmp(tag, expected_str, expected_size) != 0) { /* Tag doesn't match the expected value, error nicely */ ms_invalid_cstr_value(tag, tag_size, path); return -1; } } else { int64_t tag = 0; uint64_t utag = 0; if (json_decode_cint(self, &tag, &utag, path) < 0) return -1; int64_t expected = PyLong_AsLongLong(expected_tag); /* Tags must be int64s, if utag != 0 then we know the tags don't match. * We parse the full uint64 value only to validate the message and * raise a nice error */ if (utag != 0) { ms_invalid_cuint_value(utag, path); return -1; } if (tag != expected) { ms_invalid_cint_value(tag, path); return -1; } } return 0; } static StructInfo * json_decode_tag_and_lookup_type( JSONDecoderState *self, Lookup *lookup, PathNode *path ) { StructInfo *out = NULL; if (Lookup_IsStrLookup(lookup)) { Py_ssize_t tag_size; char *tag = NULL; tag_size = json_decode_cstr(self, &tag, path); if (tag_size < 0) return NULL; out = (StructInfo *)StrLookup_Get((StrLookup *)lookup, tag, tag_size); if (out == NULL) { ms_invalid_cstr_value(tag, tag_size, path); } } else { int64_t tag = 0; uint64_t utag = 0; if (json_decode_cint(self, &tag, &utag, path) < 0) return NULL; if (utag == 0) { out = (StructInfo *)IntLookup_GetInt64((IntLookup *)lookup, tag); if (out == NULL) { ms_invalid_cint_value(tag, path); } } else { /* tags can't be uint64 values, we only decode to give a nice error */ ms_invalid_cuint_value(utag, path); } } return out; } static PyObject * json_decode_struct_array( JSONDecoderState *self, TypeNode *type, PathNode *path ) { Py_ssize_t starting_index = 0; StructInfo *info = TypeNode_get_struct_info(type); self->input_pos++; /* Skip '[' */ /* If this is a tagged struct, first read and validate the tag */ if (info->class->struct_tag_value != NULL) { PathNode tag_path = {path, 0}; if (json_ensure_array_nonempty(self, info->class, path) < 0) return NULL; if (json_ensure_tag_matches(self, &tag_path, info->class->struct_tag_value) < 0) return NULL; starting_index = 1; } /* Decode the rest of the struct */ return json_decode_struct_array_inner(self, info, path, starting_index); } static PyObject * json_decode_struct_array_union( JSONDecoderState *self, TypeNode *type, PathNode *path ) { PathNode tag_path = {path, 0}; Lookup *lookup = TypeNode_get_struct_union(type); self->input_pos++; /* Skip '[' */ /* Decode & lookup struct type from tag */ if (json_ensure_array_nonempty(self, NULL, path) < 0) return NULL; StructInfo *info = json_decode_tag_and_lookup_type(self, lookup, &tag_path); if (info == NULL) return NULL; /* Finish decoding the rest of the struct */ return json_decode_struct_array_inner(self, info, path, 1); } static PyObject * json_decode_array( JSONDecoderState *self, TypeNode *type, PathNode *path ) { if (type->types & MS_TYPE_ANY) { TypeNode type_any = {MS_TYPE_ANY}; return json_decode_list(self, type, &type_any, path); } else if (type->types & MS_TYPE_LIST) { return json_decode_list(self, type, TypeNode_get_array(type), path); } else if (type->types & (MS_TYPE_SET | MS_TYPE_FROZENSET)) { return json_decode_set(self, type, TypeNode_get_array(type), path); } else if (type->types & MS_TYPE_VARTUPLE) { return json_decode_vartuple(self, type, TypeNode_get_array(type), path); } else if (type->types & MS_TYPE_FIXTUPLE) { return json_decode_fixtuple(self, type, path); } else if (type->types & MS_TYPE_NAMEDTUPLE) { return json_decode_namedtuple(self, type, path); } else if (type->types & MS_TYPE_STRUCT_ARRAY) { return json_decode_struct_array(self, type, path); } else if (type->types & MS_TYPE_STRUCT_ARRAY_UNION) { return json_decode_struct_array_union(self, type, path); } return ms_validation_error("array", type, path); } static PyObject * json_decode_dict( JSONDecoderState *self, TypeNode *type, TypeNode *key_type, TypeNode *val_type, PathNode *path ) { PyObject *out, *key = NULL, *val = NULL; unsigned char c; bool first = true; PathNode key_path = {path, PATH_KEY, NULL}; PathNode val_path = {path, PATH_ELLIPSIS, NULL}; self->input_pos++; /* Skip '{' */ out = PyDict_New(); if (out == NULL) return NULL; if (Py_EnterRecursiveCall(" while deserializing an object")) { Py_DECREF(out); return NULL; /* cpylint-ignore */ } while (true) { /* Parse '}' or ',', then peek the next character */ if (MS_UNLIKELY(!json_peek_skip_ws(self, &c))) goto error; if (c == '}') { self->input_pos++; break; } else if (c == ',' && !first) { self->input_pos++; if (MS_UNLIKELY(!json_peek_skip_ws(self, &c))) goto error; } else if (first) { /* Only the first item doesn't need a comma delimiter */ first = false; } else { json_err_invalid(self, "expected ',' or '}'"); goto error; } /* Parse a string key */ if (c == '"') { key = json_decode_dict_key(self, key_type, &key_path); if (key == NULL) goto error; } else if (c == '}') { json_err_invalid(self, "trailing comma in object"); goto error; } else { json_err_invalid(self, "object keys must be strings"); goto error; } /* Parse colon */ if (MS_UNLIKELY(!json_peek_skip_ws(self, &c))) goto error; if (c != ':') { json_err_invalid(self, "expected ':'"); goto error; } self->input_pos++; /* Parse value */ val = json_decode(self, val_type, &val_path); if (val == NULL) goto error; /* Add item to dict */ if (MS_UNLIKELY(PyDict_SetItem(out, key, val) < 0)) goto error; Py_CLEAR(key); Py_CLEAR(val); } if (MS_UNLIKELY(!ms_passes_map_constraints(PyDict_GET_SIZE(out), type, path))) goto error; Py_LeaveRecursiveCall(); return out; error: Py_LeaveRecursiveCall(); Py_XDECREF(key); Py_XDECREF(val); Py_DECREF(out); return NULL; } #if PY315_PLUS static PyObject * json_decode_frozendict( JSONDecoderState *self, TypeNode *type, TypeNode *key_type, TypeNode *val_type, PathNode *path ) { PyObject *dict = json_decode_dict(self, type, key_type, val_type, path); return _PyFrozenDict_NewSteal(dict); } #endif static PyObject * json_decode_typeddict( JSONDecoderState *self, TypeNode *type, PathNode *path ) { PyObject *out; unsigned char c; char *key = NULL; bool first = true; Py_ssize_t key_size, nrequired = 0, pos = 0; TypedDictInfo *info = TypeNode_get_typeddict_info(type); self->input_pos++; /* Skip '{' */ if (Py_EnterRecursiveCall(" while deserializing an object")) return NULL; out = PyDict_New(); if (out == NULL) goto error; while (true) { /* Parse '}' or ',', then peek the next character */ if (MS_UNLIKELY(!json_peek_skip_ws(self, &c))) goto error; if (c == '}') { self->input_pos++; break; } else if (c == ',' && !first) { self->input_pos++; if (MS_UNLIKELY(!json_peek_skip_ws(self, &c))) goto error; } else if (first) { /* Only the first item doesn't need a comma delimiter */ first = false; } else { json_err_invalid(self, "expected ',' or '}'"); goto error; } /* Parse a string key */ if (c == '"') { bool is_ascii = true; key_size = json_decode_string_view(self, &key, &is_ascii); if (key_size < 0) goto error; } else if (c == '}') { json_err_invalid(self, "trailing comma in object"); goto error; } else { json_err_invalid(self, "object keys must be strings"); goto error; } /* Parse colon */ if (MS_UNLIKELY(!json_peek_skip_ws(self, &c))) goto error; if (c != ':') { json_err_invalid(self, "expected ':'"); goto error; } self->input_pos++; /* Parse value */ TypeNode *field_type; PyObject *field = TypedDictInfo_lookup_key(info, key, key_size, &field_type, &pos); if (field != NULL) { PathNode field_path = {path, PATH_STR, field}; PyObject *val = json_decode(self, field_type, &field_path); if (val == NULL) goto error; /* We want to keep a count of required fields we've decoded. Since * duplicates can occur, we stash the current dict size, then only * increment if the dict size has changed _and_ the field is * required. */ Py_ssize_t cur_size = PyDict_GET_SIZE(out); int status = PyDict_SetItem(out, field, val); /* Always decref value, no need to decref key since it's a borrowed * reference. */ Py_DECREF(val); if (status < 0) goto error; if ((PyDict_GET_SIZE(out) != cur_size) && (field_type->types & MS_EXTRA_FLAG)) { nrequired++; } } else { /* Skip unknown fields */ if (json_skip(self) < 0) goto error; } } if (nrequired < info->nrequired) { /* A required field is missing, determine which one and raise */ TypedDictInfo_error_missing(info, out, path); goto error; } Py_LeaveRecursiveCall(); return out; error: Py_LeaveRecursiveCall(); Py_DECREF(out); return NULL; } static PyObject * json_decode_dataclass( JSONDecoderState *self, TypeNode *type, PathNode *path ) { PyObject *out; unsigned char c; char *key = NULL; bool first = true; Py_ssize_t key_size, pos = 0; DataclassInfo *info = TypeNode_get_dataclass_info(type); if (Py_EnterRecursiveCall(" while deserializing an object")) return NULL; PyTypeObject *dataclass_type = (PyTypeObject *)(info->class); out = dataclass_type->tp_alloc(dataclass_type, 0); if (out == NULL) goto error; if (info->pre_init != NULL) { PyObject *res = PyObject_CallOneArg(info->pre_init, out); if (res == NULL) goto error; Py_DECREF(res); } self->input_pos++; /* Skip '{' */ while (true) { /* Parse '}' or ',', then peek the next character */ if (MS_UNLIKELY(!json_peek_skip_ws(self, &c))) goto error; if (c == '}') { self->input_pos++; break; } else if (c == ',' && !first) { self->input_pos++; if (MS_UNLIKELY(!json_peek_skip_ws(self, &c))) goto error; } else if (first) { /* Only the first item doesn't need a comma delimiter */ first = false; } else { json_err_invalid(self, "expected ',' or '}'"); goto error; } /* Parse a string key */ if (c == '"') { bool is_ascii = true; key_size = json_decode_string_view(self, &key, &is_ascii); if (key_size < 0) goto error; } else if (c == '}') { json_err_invalid(self, "trailing comma in object"); goto error; } else { json_err_invalid(self, "object keys must be strings"); goto error; } /* Parse colon */ if (MS_UNLIKELY(!json_peek_skip_ws(self, &c))) goto error; if (c != ':') { json_err_invalid(self, "expected ':'"); goto error; } self->input_pos++; /* Parse value */ TypeNode *field_type; PyObject *field = DataclassInfo_lookup_key(info, key, key_size, &field_type, &pos); if (field != NULL) { PathNode field_path = {path, PATH_STR, field}; PyObject *val = json_decode(self, field_type, &field_path); if (val == NULL) goto error; int status = PyObject_GenericSetAttr(out, field, val); Py_DECREF(val); if (status < 0) goto error; } else { /* Skip unknown fields */ if (json_skip(self) < 0) goto error; } } if (DataclassInfo_post_decode(info, out, path) < 0) goto error; Py_LeaveRecursiveCall(); return out; error: Py_LeaveRecursiveCall(); Py_XDECREF(out); return NULL; } static PyObject * json_decode_struct_map_inner( JSONDecoderState *self, StructInfo *info, PathNode *path, Py_ssize_t starting_index ) { PyObject *out, *val = NULL; Py_ssize_t key_size, field_index, pos = 0; unsigned char c; char *key = NULL; bool first = starting_index == 0; StructMetaObject *st_type = info->class; PathNode field_path = {path, 0, (PyObject *)st_type}; out = Struct_alloc((PyTypeObject *)(st_type)); if (out == NULL) return NULL; if (Py_EnterRecursiveCall(" while deserializing an object")) { Py_DECREF(out); return NULL; /* cpylint-ignore */ } while (true) { /* Parse '}' or ',', then peek the next character */ if (MS_UNLIKELY(!json_peek_skip_ws(self, &c))) goto error; if (c == '}') { self->input_pos++; break; } else if (c == ',' && !first) { self->input_pos++; if (MS_UNLIKELY(!json_peek_skip_ws(self, &c))) goto error; } else if (first) { /* Only the first item doesn't need a comma delimiter */ first = false; } else { json_err_invalid(self, "expected ',' or '}'"); goto error; } /* Parse a string key */ if (c == '"') { bool is_ascii = true; key_size = json_decode_string_view(self, &key, &is_ascii); if (key_size < 0) goto error; } else if (c == '}') { json_err_invalid(self, "trailing comma in object"); goto error; } else { json_err_invalid(self, "object keys must be strings"); goto error; } /* Parse colon */ if (MS_UNLIKELY(!json_peek_skip_ws(self, &c))) goto error; if (c != ':') { json_err_invalid(self, "expected ':'"); goto error; } self->input_pos++; /* Parse value */ field_index = StructMeta_get_field_index(st_type, key, key_size, &pos); if (MS_LIKELY(field_index >= 0)) { field_path.index = field_index; TypeNode *type = info->types[field_index]; assert(type != NULL); val = json_decode(self, type, &field_path); if (val == NULL) goto error; Struct_set_index(out, field_index, val); } else if (MS_UNLIKELY(field_index == -2)) { /* Decode and check that the tag value matches the expected value */ PathNode tag_path = {path, PATH_STR, st_type->struct_tag_field}; if (json_ensure_tag_matches(self, &tag_path, st_type->struct_tag_value) < 0) { goto error; } } else { /* Unknown field */ if (MS_UNLIKELY(st_type->forbid_unknown_fields == OPT_TRUE)) { ms_error_unknown_field(key, key_size, path); goto error; } else { if (json_skip(self) < 0) goto error; } } } if (Struct_fill_in_defaults(st_type, out, path) < 0) goto error; Py_LeaveRecursiveCall(); return out; error: Py_LeaveRecursiveCall(); Py_DECREF(out); return NULL; } static PyObject * json_decode_struct_map( JSONDecoderState *self, TypeNode *type, PathNode *path ) { StructInfo *info = TypeNode_get_struct_info(type); self->input_pos++; /* Skip '{' */ return json_decode_struct_map_inner(self, info, path, 0); } static PyObject * json_decode_struct_union( JSONDecoderState *self, TypeNode *type, PathNode *path ) { Lookup *lookup = TypeNode_get_struct_union(type); PathNode tag_path = {path, PATH_STR, Lookup_tag_field(lookup)}; Py_ssize_t tag_field_size; const char *tag_field = unicode_str_and_size_nocheck( Lookup_tag_field(lookup), &tag_field_size ); self->input_pos++; /* Skip '{' */ /* Cache the current input position in case we need to reset it once the * tag is found */ unsigned char *orig_input_pos = self->input_pos; for (Py_ssize_t i = 0; ; i++) { unsigned char c; /* Parse '}' or ',', then peek the next character */ if (MS_UNLIKELY(!json_peek_skip_ws(self, &c))) return NULL; if (c == '}') { self->input_pos++; break; } else if (c == ',' && (i != 0)) { self->input_pos++; if (MS_UNLIKELY(!json_peek_skip_ws(self, &c))) return NULL; } else if (i != 0) { return json_err_invalid(self, "expected ',' or '}'"); } /* Parse a string key */ Py_ssize_t key_size; char *key = NULL; if (c == '"') { bool is_ascii = true; key_size = json_decode_string_view(self, &key, &is_ascii); if (key_size < 0) return NULL; } else if (c == '}') { return json_err_invalid(self, "trailing comma in object"); } else { return json_err_invalid(self, "object keys must be strings"); } /* Check if key matches tag_field */ bool tag_found = false; if (key_size == tag_field_size && memcmp(key, tag_field, key_size) == 0) { tag_found = true; } /* Parse colon */ if (MS_UNLIKELY(!json_peek_skip_ws(self, &c))) return NULL; if (c != ':') { return json_err_invalid(self, "expected ':'"); } self->input_pos++; /* Parse value */ if (tag_found) { /* Decode & lookup struct type from tag */ StructInfo *info = json_decode_tag_and_lookup_type(self, lookup, &tag_path); if (info == NULL) return NULL; if (i != 0) { /* tag wasn't first field, reset decoder position */ self->input_pos = orig_input_pos; } return json_decode_struct_map_inner(self, info, path, i == 0 ? 1 : 0); } else { if (json_skip(self) < 0) return NULL; } } ms_missing_required_field(Lookup_tag_field(lookup), path); return NULL; } static PyObject * json_decode_object( JSONDecoderState *self, TypeNode *type, PathNode *path ) { if (type->types & MS_TYPE_ANY) { TypeNode type_any = {MS_TYPE_ANY}; return json_decode_dict(self, type, &type_any, &type_any, path); } else if (type->types & MS_ANY_DICT) { TypeNode *key, *val; TypeNode_get_dict(type, &key, &val); #if PY315_PLUS if (type->types & MS_TYPE_FROZENDICT) { return json_decode_frozendict(self, type, key, val, path); } #endif return json_decode_dict(self, type, key, val, path); } else if (type->types & MS_TYPE_TYPEDDICT) { return json_decode_typeddict(self, type, path); } else if (type->types & MS_TYPE_DATACLASS) { return json_decode_dataclass(self, type, path); } else if (type->types & MS_TYPE_STRUCT) { return json_decode_struct_map(self, type, path); } else if (type->types & MS_TYPE_STRUCT_UNION) { return json_decode_struct_union(self, type, path); } return ms_validation_error("object", type, path); } static PyObject * json_maybe_decode_number(JSONDecoderState *self, TypeNode *type, PathNode *path) { const char *errmsg = NULL; const unsigned char *pout; PyObject *out = parse_number_inline( self->input_pos, self->input_end, &pout, &errmsg, type, path, self->strict, self->float_hook, false ); self->input_pos = (unsigned char *)pout; if (MS_UNLIKELY(out == NULL)) { if (errmsg != NULL) { json_err_invalid(self, errmsg); } } return out; } static MS_NOINLINE PyObject * json_decode_raw(JSONDecoderState *self) { unsigned char c; if (MS_UNLIKELY(!json_peek_skip_ws(self, &c))) return NULL; const unsigned char *start = self->input_pos; if (json_skip(self) < 0) return NULL; Py_ssize_t size = self->input_pos - start; return Raw_FromView(self->buffer_obj, (char *)start, size); } static MS_INLINE PyObject * json_decode_nocustom( JSONDecoderState *self, TypeNode *type, PathNode *path ) { unsigned char c; if (MS_UNLIKELY(!json_peek_skip_ws(self, &c))) return NULL; switch (c) { case 'n': return json_decode_none(self, type, path); case 't': return json_decode_true(self, type, path); case 'f': return json_decode_false(self, type, path); case '[': return json_decode_array(self, type, path); case '{': return json_decode_object(self, type, path); case '"': return json_decode_string(self, type, path); default: return json_maybe_decode_number(self, type, path); } } static PyObject * json_decode( JSONDecoderState *self, TypeNode *type, PathNode *path ) { if (MS_UNLIKELY(type->types == 0)) { return json_decode_raw(self); } PyObject *obj = json_decode_nocustom(self, type, path); if (MS_UNLIKELY(type->types & (MS_TYPE_CUSTOM | MS_TYPE_CUSTOM_GENERIC))) { return ms_decode_custom(obj, self->dec_hook, type, path); } return obj; } static int json_skip_ident(JSONDecoderState *self, const char *ident, size_t len) { self->input_pos++; /* Already checked first char */ if (MS_UNLIKELY(!json_remaining(self, len))) return ms_err_truncated(); if (memcmp(self->input_pos, ident, len) != 0) { json_err_invalid(self, "invalid character"); return -1; } self->input_pos += len; return 0; } static int json_skip_array(JSONDecoderState *self) { unsigned char c; bool first = true; int out = -1; self->input_pos++; /* Skip '[' */ if (Py_EnterRecursiveCall(" while deserializing an object")) return -1; while (true) { if (MS_UNLIKELY(!json_peek_skip_ws(self, &c))) break; if (c == ']') { self->input_pos++; out = 0; break; } else if (c == ',' && !first) { self->input_pos++; if (MS_UNLIKELY(!json_peek_skip_ws(self, &c))) break; } else if (first) { first = false; } else { json_err_invalid(self, "expected ',' or ']'"); break; } if (MS_UNLIKELY(c == ']')) { json_err_invalid(self, "trailing comma in array"); break; } if (json_skip(self) < 0) break; } Py_LeaveRecursiveCall(); return out; } static int json_skip_object(JSONDecoderState *self) { unsigned char c; bool first = true; int out = -1; self->input_pos++; /* Skip '{' */ if (Py_EnterRecursiveCall(" while deserializing an object")) return -1; while (true) { if (MS_UNLIKELY(!json_peek_skip_ws(self, &c))) break; if (c == '}') { self->input_pos++; out = 0; break; } else if (c == ',' && !first) { self->input_pos++; if (MS_UNLIKELY(!json_peek_skip_ws(self, &c))) break; } else if (first) { first = false; } else { json_err_invalid(self, "expected ',' or '}'"); break; } /* Skip key */ if (c == '"') { if (json_skip_string(self) < 0) break; } else if (c == '}') { json_err_invalid(self, "trailing comma in object"); break; } else { json_err_invalid(self, "expected '\"'"); break; } /* Parse colon */ if (MS_UNLIKELY(!json_peek_skip_ws(self, &c))) break; if (c != ':') { json_err_invalid(self, "expected ':'"); break; } self->input_pos++; /* Skip value */ if (json_skip(self) < 0) break; } Py_LeaveRecursiveCall(); return out; } static int json_maybe_skip_number(JSONDecoderState *self) { /* We know there is at least one byte available when this function is * called */ char c = *self->input_pos; /* Parse minus sign (if present) */ if (c == '-') { self->input_pos++; c = json_peek_or_null(self); } /* Parse integer */ if (MS_UNLIKELY(c == '0')) { /* Ensure at most one leading zero */ self->input_pos++; c = json_peek_or_null(self); if (MS_UNLIKELY(is_digit(c))) { json_err_invalid(self, "invalid number"); return -1; } } else { /* Skip the integer part of the number. */ unsigned char *cur_pos = self->input_pos; while (self->input_pos < self->input_end && is_digit(*self->input_pos)) { self->input_pos++; } /* There must be at least one digit */ if (MS_UNLIKELY(cur_pos == self->input_pos)) { json_err_invalid(self, "invalid character"); return -1; } } c = json_peek_or_null(self); if (c == '.') { self->input_pos++; /* Skip remaining digits until invalid/unknown character */ unsigned char *cur_pos = self->input_pos; while (self->input_pos < self->input_end && is_digit(*self->input_pos)) { self->input_pos++; } /* Error if no digits after decimal */ if (MS_UNLIKELY(cur_pos == self->input_pos)) { json_err_invalid(self, "invalid number"); return -1; } c = json_peek_or_null(self); } if (c == 'e' || c == 'E') { self->input_pos++; /* Parse exponent sign (if any) */ c = json_peek_or_null(self); if (c == '+' || c == '-') { self->input_pos++; } /* Parse exponent digits */ unsigned char *cur_pos = self->input_pos; while (self->input_pos < self->input_end && is_digit(*self->input_pos)) { self->input_pos++; } /* Error if no digits in exponent */ if (MS_UNLIKELY(cur_pos == self->input_pos)) { json_err_invalid(self, "invalid number"); return -1; } } return 0; } static int json_skip(JSONDecoderState *self) { unsigned char c; if (MS_UNLIKELY(!json_peek_skip_ws(self, &c))) return -1; switch (c) { case 'n': return json_skip_ident(self, "ull", 3); case 't': return json_skip_ident(self, "rue", 3); case 'f': return json_skip_ident(self, "alse", 4); case '"': return json_skip_string(self); case '[': return json_skip_array(self); case '{': return json_skip_object(self); default: return json_maybe_skip_number(self); } } static int json_format( JSONDecoderState *, EncoderState *, Py_ssize_t indent, Py_ssize_t cur_indent ); static int json_write_indent(EncoderState *self, Py_ssize_t indent, Py_ssize_t cur_indent) { if (indent <= 0) return 0; if (ms_ensure_space(self, cur_indent + 1) < 0) return -1; char *p = self->output_buffer_raw + self->output_len; *p++ = '\n'; for (Py_ssize_t i = 0; i < cur_indent; i++) { *p++ = ' '; } self->output_len += cur_indent + 1; return 0; } static int json_format_array( JSONDecoderState *dec, EncoderState *enc, Py_ssize_t indent, Py_ssize_t cur_indent ) { unsigned char c; bool first = true; int out = -1; Py_ssize_t el_indent = cur_indent + indent; dec->input_pos++; /* Skip '[' */ if (ms_write(enc, "[", 1) < 0) return -1; if (Py_EnterRecursiveCall(" while deserializing an object")) return -1; while (true) { if (MS_UNLIKELY(!json_peek_skip_ws(dec, &c))) break; if (c == ']') { dec->input_pos++; if (!first) { if (MS_UNLIKELY(json_write_indent(enc, indent, cur_indent) < 0)) break; } out = ms_write(enc, "]", 1); break; } else if (c == ',' && !first) { dec->input_pos++; if (indent == 0) { if (MS_UNLIKELY(ms_write(enc, ", ", 2) < 0)) break; } else { if (MS_UNLIKELY(ms_write(enc, ",", 1) < 0)) break; } if (MS_UNLIKELY(!json_peek_skip_ws(dec, &c))) break; } else if (first) { first = false; } else { json_err_invalid(dec, "expected ',' or ']'"); break; } if (MS_UNLIKELY(c == ']')) { json_err_invalid(dec, "trailing comma in array"); break; } if (json_write_indent(enc, indent, el_indent) < 0) break; if (json_format(dec, enc, indent, el_indent) < 0) break; } Py_LeaveRecursiveCall(); return out; } static int json_format_object( JSONDecoderState *dec, EncoderState *enc, Py_ssize_t indent, Py_ssize_t cur_indent ) { unsigned char c; bool first = true; int out = -1; Py_ssize_t el_indent = cur_indent + indent; dec->input_pos++; /* Skip '{' */ if (ms_write(enc, "{", 1) < 0) return -1; if (Py_EnterRecursiveCall(" while deserializing an object")) return -1; while (true) { if (MS_UNLIKELY(!json_peek_skip_ws(dec, &c))) break; if (c == '}') { dec->input_pos++; if (!first) { if (MS_UNLIKELY(json_write_indent(enc, indent, cur_indent) < 0)) break; } out = ms_write(enc, "}", 1); break; } else if (c == ',' && !first) { dec->input_pos++; if (indent == 0) { if (MS_UNLIKELY(ms_write(enc, ", ", 2) < 0)) break; } else { if (MS_UNLIKELY(ms_write(enc, ",", 1) < 0)) break; } if (MS_UNLIKELY(!json_peek_skip_ws(dec, &c))) break; } else if (first) { first = false; } else { json_err_invalid(dec, "expected ',' or '}'"); break; } if (c == '"') { if (json_write_indent(enc, indent, el_indent) < 0) break; if (json_format(dec, enc, indent, el_indent) < 0) break; } else if (c == '}') { json_err_invalid(dec, "trailing comma in object"); break; } else { json_err_invalid(dec, "expected '\"'"); break; } if (MS_UNLIKELY(!json_peek_skip_ws(dec, &c))) break; if (c != ':') { json_err_invalid(dec, "expected ':'"); break; } dec->input_pos++; if (indent >= 0) { if (ms_write(enc, ": ", 2) < 0) break; } else { if (ms_write(enc, ":", 1) < 0) break; } if (json_format(dec, enc, indent, el_indent) < 0) break; } Py_LeaveRecursiveCall(); return out; } static int json_format( JSONDecoderState *dec, EncoderState *enc, Py_ssize_t indent, Py_ssize_t cur_indent ) { unsigned char c; if (MS_UNLIKELY(!json_peek_skip_ws(dec, &c))) return -1; if (c == '[') { return json_format_array(dec, enc, indent, cur_indent); } else if (c == '{') { return json_format_object(dec, enc, indent, cur_indent); } else { unsigned char *start = dec->input_pos; if (json_skip(dec) < 0) return -1; unsigned char *end = dec->input_pos; return ms_write(enc, (char *)start, end - start); } } PyDoc_STRVAR(msgspec_json_format__doc__, "json_format(buf, *, indent=2)\n" "--\n" "\n" "Format an existing JSON message, usually to be more human readable.\n" "\n" "Parameters\n" "----------\n" "buf : bytes-like or str\n" " The JSON message to format.\n" "indent : int, optional\n" " How many spaces to indent for a single indentation level. Defaults to 2.\n" " Set to 0 to format the message as a single line, with spaces added between\n" " items for readability. Set to a negative number to strip all unnecessary\n" " whitespace, minimizing the message size.\n" "\n" "Returns\n" "-------\n" "output : bytes or str\n" " The formatted JSON message. Returns a str if input is a str, bytes otherwise." ); static PyObject* msgspec_json_format(PyObject *self, PyObject *args, PyObject *kwargs) { int status; Py_buffer buffer; PyObject *out = NULL, *buf = NULL; char *kwlist[] = {"buf", "indent", NULL}; Py_ssize_t indent = 2; /* Parse arguments */ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|$n", kwlist, &buf, &indent)) return NULL; if (indent < 0) { indent = -1; } buffer.buf = NULL; if (ms_get_buffer(buf, &buffer) >= 0) { JSONDecoderState dec; EncoderState enc; /* Init decoder */ dec.dec_hook = NULL; dec.float_hook = NULL; dec.type = NULL; dec.scratch = NULL; dec.scratch_capacity = 0; dec.scratch_len = 0; dec.buffer_obj = buf; dec.input_start = buffer.buf; dec.input_pos = buffer.buf; dec.input_end = dec.input_pos + buffer.len; /* Init encoder */ enc.mod = msgspec_get_state(self); enc.enc_hook = NULL; /* Assume pretty-printing will take at least as much space as the * input. This is true unless there's existing whitespace. */ enc.max_output_len = (indent >= 0) ? buffer.len : ENC_INIT_BUFSIZE; enc.output_len = 0; enc.output_buffer = PyBytes_FromStringAndSize(NULL, enc.max_output_len); if (enc.output_buffer != NULL) { enc.output_buffer_raw = PyBytes_AS_STRING(enc.output_buffer); enc.resize_buffer = &ms_resize_bytes; status = json_format(&dec, &enc, indent, 0); if (status == 0 && json_has_trailing_characters(&dec)) { status = -1; } if (status == 0) { if (PyUnicode_CheckExact(buf)) { /* str input, str output */ out = PyUnicode_FromStringAndSize( enc.output_buffer_raw, enc.output_len ); Py_CLEAR(enc.output_buffer); } else { /* Trim output to length */ out = enc.output_buffer; FAST_BYTES_SHRINK(out, enc.output_len); } } else { /* Error, drop buffer */ Py_CLEAR(enc.output_buffer); } } ms_release_buffer(&buffer); } return out; } PyDoc_STRVAR(JSONDecoder_decode__doc__, "decode($self, buf, /)\n" "--\n" "\n" "Deserialize an object from JSON.\n" "\n" "Parameters\n" "----------\n" "buf : bytes-like or str\n" " The message to decode.\n" "\n" "Returns\n" "-------\n" "obj : Any\n" " The deserialized object.\n" ); static PyObject* JSONDecoder_decode(JSONDecoder *self, PyObject *const *args, Py_ssize_t nargs) { if (!check_positional_nargs(nargs, 1, 1)) { return NULL; } JSONDecoderState state = { .type = self->type, .strict = self->strict, .dec_hook = self->dec_hook, .float_hook = self->float_hook, .scratch = NULL, .scratch_capacity = 0, .scratch_len = 0 }; Py_buffer buffer; buffer.buf = NULL; if (ms_get_buffer(args[0], &buffer) >= 0) { state.buffer_obj = args[0]; state.input_start = buffer.buf; state.input_pos = buffer.buf; state.input_end = state.input_pos + buffer.len; PyObject *res = json_decode(&state, state.type, NULL); if (res != NULL && json_has_trailing_characters(&state)) { Py_CLEAR(res); } ms_release_buffer(&buffer); PyMem_Free(state.scratch); return res; } return NULL; } PyDoc_STRVAR(JSONDecoder_decode_lines__doc__, "decode_lines($self, buf, /)\n" "--\n" "\n" "Decode a list of items from newline-delimited JSON.\n" "\n" "Parameters\n" "----------\n" "buf : bytes-like or str\n" " The message to decode.\n" "\n" "Returns\n" "-------\n" "items : list\n" " A list of decoded objects.\n" "Examples\n" "--------\n" ">>> import msgspec\n" ">>> msg = \"\"\"\n" "... {\"x\": 1, \"y\": 2}\n" "... {\"x\": 3, \"y\": 4}\n" "... \"\"\"\n" ">>> dec = msgspec.json.Decoder()\n" ">>> dec.decode_lines(msg)\n" "[{'x': 1, 'y': 2}, {'x': 3, 'y': 4}]" ); static PyObject* JSONDecoder_decode_lines(JSONDecoder *self, PyObject *const *args, Py_ssize_t nargs) { if (!check_positional_nargs(nargs, 1, 1)) { return NULL; } JSONDecoderState state = { .type = self->type, .strict = self->strict, .dec_hook = self->dec_hook, .float_hook = self->float_hook, .scratch = NULL, .scratch_capacity = 0, .scratch_len = 0 }; Py_buffer buffer; buffer.buf = NULL; if (ms_get_buffer(args[0], &buffer) >= 0) { state.buffer_obj = args[0]; state.input_start = buffer.buf; state.input_pos = buffer.buf; state.input_end = state.input_pos + buffer.len; PathNode path = {NULL, 0, NULL}; PyObject *out = PyList_New(0); if (out == NULL) return NULL; while (true) { /* Skip until first non-whitespace character, or return if buffer * exhausted */ while (true) { if (state.input_pos == state.input_end) { goto done; } unsigned char c = *state.input_pos; if (MS_LIKELY(c != ' ' && c != '\n' && c != '\r' && c != '\t')) { break; } state.input_pos++; } /* Read and append next item */ PyObject *item = json_decode(&state, state.type, &path); path.index++; if (item == NULL) { Py_CLEAR(out); goto done; } int status = PyList_Append(out, item); Py_DECREF(item); if (status < 0) { Py_CLEAR(out); goto done; } } done: ms_release_buffer(&buffer); PyMem_Free(state.scratch); return out; } return NULL; } static struct PyMethodDef JSONDecoder_methods[] = { { "decode", (PyCFunction) JSONDecoder_decode, METH_FASTCALL, JSONDecoder_decode__doc__, }, { "decode_lines", (PyCFunction) JSONDecoder_decode_lines, METH_FASTCALL, JSONDecoder_decode_lines__doc__, }, {"__class_getitem__", Py_GenericAlias, METH_O|METH_CLASS}, {NULL, NULL} /* sentinel */ }; static PyMemberDef JSONDecoder_members[] = { {"type", T_OBJECT_EX, offsetof(JSONDecoder, orig_type), READONLY, "The Decoder type"}, {"strict", T_BOOL, offsetof(JSONDecoder, strict), READONLY, "The Decoder strict setting"}, {"dec_hook", T_OBJECT, offsetof(JSONDecoder, dec_hook), READONLY, "The Decoder dec_hook"}, {"float_hook", T_OBJECT, offsetof(JSONDecoder, float_hook), READONLY, "The Decoder float_hook"}, {NULL}, }; static PyTypeObject JSONDecoder_Type = { PyVarObject_HEAD_INIT(NULL, 0) .tp_name = "msgspec.json.Decoder", .tp_doc = JSONDecoder__doc__, .tp_basicsize = sizeof(JSONDecoder), .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, .tp_new = PyType_GenericNew, .tp_init = (initproc)JSONDecoder_init, .tp_traverse = (traverseproc)JSONDecoder_traverse, .tp_dealloc = (destructor)JSONDecoder_dealloc, .tp_repr = (reprfunc)JSONDecoder_repr, .tp_methods = JSONDecoder_methods, .tp_members = JSONDecoder_members, }; PyDoc_STRVAR(msgspec_json_decode__doc__, "json_decode(buf, /, *, type='Any', strict=True, dec_hook=None)\n" "--\n" "\n" "Deserialize an object from JSON.\n" "\n" "Parameters\n" "----------\n" "buf : bytes-like or str\n" " The message to decode.\n" "type : type, optional\n" " A Python type (in type annotation form) to decode the object as. If\n" " provided, the message will be type checked and decoded as the specified\n" " type. Defaults to `Any`, in which case the message will be decoded using\n" " the default JSON types.\n" "strict : bool, optional\n" " Whether type coercion rules should be strict. Setting to False enables a\n" " wider set of coercion rules from string to non-string types for all values.\n" " Default is True.\n" "dec_hook : callable, optional\n" " An optional callback for handling decoding custom types. Should have the\n" " signature ``dec_hook(type: Type, obj: Any) -> Any``, where ``type`` is the\n" " expected message type, and ``obj`` is the decoded representation composed\n" " of only basic JSON types. This hook should transform ``obj`` into type\n" " ``type``, or raise a ``NotImplementedError`` if unsupported.\n" "\n" "Returns\n" "-------\n" "obj : Any\n" " The deserialized object.\n" "\n" "See Also\n" "--------\n" "Decoder.decode" ); static PyObject* msgspec_json_decode(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *res = NULL, *buf = NULL, *type = NULL, *dec_hook = NULL, *strict_obj = NULL; int strict = 1; MsgspecState *mod = msgspec_get_state(self); /* Parse arguments */ if (!check_positional_nargs(nargs, 1, 1)) return NULL; buf = args[0]; if (kwnames != NULL) { Py_ssize_t nkwargs = PyTuple_GET_SIZE(kwnames); if ((type = find_keyword(kwnames, args + nargs, mod->str_type)) != NULL) nkwargs--; if ((strict_obj = find_keyword(kwnames, args + nargs, mod->str_strict)) != NULL) nkwargs--; if ((dec_hook = find_keyword(kwnames, args + nargs, mod->str_dec_hook)) != NULL) nkwargs--; if (nkwargs > 0) { PyErr_SetString( PyExc_TypeError, "Extra keyword arguments provided" ); return NULL; } } /* Handle dec_hook */ if (dec_hook == Py_None) { dec_hook = NULL; } if (dec_hook != NULL) { if (!PyCallable_Check(dec_hook)) { PyErr_SetString(PyExc_TypeError, "dec_hook must be callable"); return NULL; } } /* Handle strict */ if (strict_obj != NULL) { strict = PyObject_IsTrue(strict_obj); if (strict < 0) return NULL; } JSONDecoderState state = { .strict = strict, .dec_hook = dec_hook, .float_hook = NULL, .scratch = NULL, .scratch_capacity = 0, .scratch_len = 0 }; /* Allocate Any & Struct type nodes (simple, common cases) on the stack, * everything else on the heap */ TypeNode typenode_any = {MS_TYPE_ANY}; TypeNodeSimple typenode_struct; if (type == NULL || type == mod->typing_any) { state.type = &typenode_any; } else if (ms_is_struct_cls(type)) { PyObject *info = StructInfo_Convert(type); if (info == NULL) return NULL; bool array_like = ((StructMetaObject *)type)->array_like == OPT_TRUE; typenode_struct.types = array_like ? MS_TYPE_STRUCT_ARRAY : MS_TYPE_STRUCT; typenode_struct.details[0].pointer = info; state.type = (TypeNode *)(&typenode_struct); } else { state.type = TypeNode_Convert(type); if (state.type == NULL) return NULL; } Py_buffer buffer; buffer.buf = NULL; if (ms_get_buffer(buf, &buffer) >= 0) { state.buffer_obj = buf; state.input_start = buffer.buf; state.input_pos = buffer.buf; state.input_end = state.input_pos + buffer.len; res = json_decode(&state, state.type, NULL); if (res != NULL && json_has_trailing_characters(&state)) { Py_CLEAR(res); } ms_release_buffer(&buffer); } PyMem_Free(state.scratch); if (state.type == (TypeNode *)&typenode_struct) { Py_DECREF(typenode_struct.details[0].pointer); } else if (state.type != &typenode_any) { TypeNode_Free(state.type); } return res; } /************************************************************************* * to_builtins * *************************************************************************/ #define MS_BUILTIN_BYTES (1ull << 0) #define MS_BUILTIN_BYTEARRAY (1ull << 1) #define MS_BUILTIN_MEMORYVIEW (1ull << 2) #define MS_BUILTIN_DATETIME (1ull << 3) #define MS_BUILTIN_DATE (1ull << 4) #define MS_BUILTIN_TIME (1ull << 5) #define MS_BUILTIN_UUID (1ull << 6) #define MS_BUILTIN_DECIMAL (1ull << 7) #define MS_BUILTIN_TIMEDELTA (1ull << 8) #define MS_BUILTIN_FROZENDICT (1ull << 9) typedef struct { MsgspecState *mod; PyObject *enc_hook; bool str_keys; enum order_mode order; uint32_t builtin_types; PyObject *builtin_types_seq; } ToBuiltinsState; static PyObject * to_builtins(ToBuiltinsState *, PyObject *, bool); static PyObject * to_builtins_enum(ToBuiltinsState *self, PyObject *obj) { return PyObject_GetAttr(obj, self->mod->str__value_); } static PyObject * to_builtins_binary(ToBuiltinsState *self, const char *buf, Py_ssize_t size) { Py_ssize_t output_size = ms_encode_base64_size(self->mod, size); if (output_size < 0) return NULL; PyObject *out = PyUnicode_New(output_size, 127); if (out == NULL) return NULL; ms_encode_base64(buf, size, ascii_get_buffer(out)); return out; } static PyObject * to_builtins_datetime(ToBuiltinsState *self, PyObject *obj) { char buf[32]; int size = ms_encode_datetime(self->mod, obj, buf); if (size < 0) return NULL; PyObject *out = PyUnicode_New(size, 127); memcpy(ascii_get_buffer(out), buf, size); return out; } static PyObject * to_builtins_date(ToBuiltinsState *self, PyObject *obj) { PyObject *out = PyUnicode_New(10, 127); if (out == NULL) return NULL; ms_encode_date(obj, ascii_get_buffer(out)); return out; } static PyObject * to_builtins_time(ToBuiltinsState *self, PyObject *obj) { char buf[21]; int size = ms_encode_time(self->mod, obj, buf); if (size < 0) return NULL; PyObject *out = PyUnicode_New(size, 127); memcpy(ascii_get_buffer(out), buf, size); return out; } static PyObject * to_builtins_timedelta(ToBuiltinsState *self, PyObject *obj) { char buf[26]; int size = ms_encode_timedelta(obj, buf); PyObject *out = PyUnicode_New(size, 127); memcpy(ascii_get_buffer(out), buf, size); return out; } static PyObject * to_builtins_uuid(ToBuiltinsState *self, PyObject *obj) { PyObject *out = PyUnicode_New(36, 127); if (out == NULL) return NULL; if (ms_encode_uuid(self->mod, obj, ascii_get_buffer(out), true) < 0) { Py_CLEAR(out); } return out; } static PyObject * to_builtins_decimal(ToBuiltinsState *self, PyObject *obj) { return PyObject_Str(obj); } static PyObject * to_builtins_list(ToBuiltinsState *self, PyObject *obj) { if (Py_EnterRecursiveCall(" while serializing an object")) return NULL; Py_ssize_t size = PyList_GET_SIZE(obj); PyObject *out = PyList_New(size); if (out == NULL) goto cleanup; for (Py_ssize_t i = 0; i < size; i++) { PyObject *item = PyList_GET_ITEM(obj, i); PyObject *new = to_builtins(self, item, false); if (new == NULL) { Py_CLEAR(out); goto cleanup; } PyList_SET_ITEM(out, i, new); } cleanup: Py_LeaveRecursiveCall(); return out; } static PyObject * to_builtins_tuple(ToBuiltinsState *self, PyObject *obj, bool is_key) { if (Py_EnterRecursiveCall(" while serializing an object")) return NULL; Py_ssize_t size = PyTuple_GET_SIZE(obj); PyObject *out = PyTuple_New(size); if (out == NULL) goto cleanup; for (Py_ssize_t i = 0; i < size; i++) { PyObject *item = PyTuple_GET_ITEM(obj, i); PyObject *new = to_builtins(self, item, is_key); if (new == NULL) { Py_CLEAR(out); goto cleanup; } PyTuple_SET_ITEM(out, i, new); } cleanup: Py_LeaveRecursiveCall(); return out; } static PyObject * to_builtins_set(ToBuiltinsState *self, PyObject *obj, bool is_key) { PyObject *out = NULL; if (Py_EnterRecursiveCall(" while serializing an object")) return NULL; PyObject *list = PySequence_List(obj); if (list == NULL) goto cleanup; if (self->order != ORDER_DEFAULT) { if (PyList_Sort(list) < 0) goto cleanup; } Py_ssize_t size = PyList_GET_SIZE(list); for (Py_ssize_t i = 0; i < size; i++) { PyObject *orig_item = PyList_GET_ITEM(list, i); PyObject *new_item = to_builtins(self, orig_item, is_key); if (new_item == NULL) goto cleanup; PyList_SET_ITEM(list, i, new_item); Py_DECREF(orig_item); } if (is_key) { out = PyList_AsTuple(list); } else { Py_INCREF(list); out = list; } cleanup: Py_LeaveRecursiveCall(); Py_XDECREF(list); return out; } static void sort_dict_inplace(PyObject **dict) { PyObject *out = NULL, *new = NULL, *keys = NULL; new = PyDict_New(); if (new == NULL) goto error; keys = PyDict_Keys(*dict); if (keys == NULL) goto error; if (PyList_Sort(keys) < 0) goto error; Py_ssize_t size = PyList_GET_SIZE(keys); for (Py_ssize_t i = 0; i < size; i++) { PyObject *key = PyList_GET_ITEM(keys, i); PyObject *val = PyDict_GetItem(*dict, key); if (val == NULL) goto error; if (PyDict_SetItem(new, key, val) < 0) goto error; } Py_INCREF(new); out = new; error: Py_XDECREF(new); Py_XDECREF(keys); Py_XDECREF(*dict); *dict = out; } static PyObject * to_builtins_dict(ToBuiltinsState *self, PyObject *obj) { if (Py_EnterRecursiveCall(" while serializing an object")) return NULL; PyObject *new_key = NULL, *new_val = NULL, *key, *val; bool ok = false; PyObject *out = PyDict_New(); Py_BEGIN_CRITICAL_SECTION(obj); if (out == NULL) goto cleanup; Py_ssize_t pos = 0; while (PyDict_Next(obj, &pos, &key, &val)) { new_key = to_builtins(self, key, true); if (new_key == NULL) goto cleanup; if (self->str_keys) { if (PyLong_CheckExact(new_key) || PyFloat_CheckExact(new_key)) { PyObject *temp = PyObject_Str(new_key); if (temp == NULL) goto cleanup; Py_DECREF(new_key); new_key = temp; } else if (!PyUnicode_CheckExact(new_key)) { PyErr_SetString( PyExc_TypeError, "Only dicts with str-like or number-like keys are supported" ); goto cleanup; } } new_val = to_builtins(self, val, false); if (new_val == NULL) goto cleanup; if (PyDict_SetItem(out, new_key, new_val) < 0) goto cleanup; Py_CLEAR(new_key); Py_CLEAR(new_val); } if (MS_UNLIKELY(self->order != ORDER_DEFAULT)) { sort_dict_inplace(&out); } ok = true; cleanup:; Py_END_CRITICAL_SECTION(); Py_LeaveRecursiveCall(); if (!ok) { Py_CLEAR(out); Py_XDECREF(new_key); Py_XDECREF(new_val); } return out; } #if PY315_PLUS static PyObject * to_builtins_frozendict(ToBuiltinsState *self, PyObject *obj) { PyObject *out = to_builtins_dict(self, obj); if (self->builtin_types & MS_BUILTIN_FROZENDICT) { return _PyFrozenDict_NewSteal(out); } return out; } #endif static PyObject * to_builtins_struct(ToBuiltinsState *self, PyObject *obj, bool is_key) { if (Py_EnterRecursiveCall(" while serializing an object")) return NULL; bool ok = false; PyObject *out = NULL; StructMetaObject *struct_type = (StructMetaObject *)Py_TYPE(obj); PyObject *tag_field = struct_type->struct_tag_field; PyObject *tag_value = struct_type->struct_tag_value; PyObject *fields = struct_type->struct_encode_fields; PyObject *defaults = struct_type->struct_defaults; Py_ssize_t nfields = PyTuple_GET_SIZE(fields); Py_ssize_t npos = nfields - PyTuple_GET_SIZE(defaults); bool omit_defaults = struct_type->omit_defaults == OPT_TRUE; if (struct_type->array_like == OPT_TRUE) { Py_ssize_t tagged = (tag_value != NULL); Py_ssize_t size = nfields + tagged; if (is_key) { out = PyTuple_New(size); } else { out = PyList_New(size); } if (out == NULL) goto cleanup; if (tagged) { Py_INCREF(tag_value); if (is_key) { PyTuple_SET_ITEM(out, 0, tag_value); } else { PyList_SET_ITEM(out, 0, tag_value); } } for (Py_ssize_t i = 0; i < nfields; i++) { PyObject *val = Struct_get_index(obj, i); if (val == NULL) goto cleanup; PyObject *val2 = to_builtins(self, val, is_key); if (val2 == NULL) goto cleanup; if (is_key) { PyTuple_SET_ITEM(out, i + tagged, val2); } else { PyList_SET_ITEM(out, i + tagged, val2); } } } else { out = PyDict_New(); if (out == NULL) goto cleanup; if (tag_value != NULL) { if (PyDict_SetItem(out, tag_field, tag_value) < 0) goto cleanup; } for (Py_ssize_t i = 0; i < nfields; i++) { PyObject *key = PyTuple_GET_ITEM(fields, i); PyObject *val = Struct_get_index(obj, i); if (MS_UNLIKELY(val == NULL)) goto cleanup; if (MS_UNLIKELY(val == UNSET)) continue; if ( !omit_defaults || i < npos || !is_default(val, PyTuple_GET_ITEM(defaults, i - npos)) ) { PyObject *val2 = to_builtins(self, val, false); if (val2 == NULL) goto cleanup; int status = PyDict_SetItem(out, key, val2); Py_DECREF(val2); if (status < 0) goto cleanup; } } if (MS_UNLIKELY(self->order == ORDER_SORTED)) { sort_dict_inplace(&out); } } ok = true; cleanup: Py_LeaveRecursiveCall(); if (!ok) { Py_CLEAR(out); } return out; } static PyObject * to_builtins_dataclass(ToBuiltinsState *self, PyObject *obj, PyObject *fields) { if (Py_EnterRecursiveCall(" while serializing an object")) return NULL; bool ok = false; PyObject *out = NULL; DataclassIter iter; if (!dataclass_iter_setup(&iter, obj, fields)) goto cleanup; out = PyDict_New(); if (out == NULL) goto cleanup; PyObject *field, *val; while (dataclass_iter_next(&iter, &field, &val)) { PyObject *val2 = to_builtins(self, val, false); int status = ( (val2 == NULL) ? -1 : PyDict_SetItem(out, field, val2) ); Py_DECREF(val); Py_XDECREF(val2); if (status < 0) goto cleanup; } if (MS_UNLIKELY(self->order == ORDER_SORTED)) { sort_dict_inplace(&out); } ok = true; cleanup: Py_LeaveRecursiveCall(); dataclass_iter_cleanup(&iter); if (!ok) { Py_CLEAR(out); } return out; } static PyObject* to_builtins_object(ToBuiltinsState *self, PyObject *obj) { bool ok = false; PyObject *dict = NULL, *out = NULL; if (Py_EnterRecursiveCall(" while serializing an object")) return NULL; out = PyDict_New(); Py_BEGIN_CRITICAL_SECTION(obj); if (out == NULL) goto cleanup; /* First encode everything in `__dict__` */ dict = PyObject_GenericGetDict(obj, NULL); if (MS_UNLIKELY(dict == NULL)) { PyErr_Clear(); } else { PyObject *key, *val; Py_ssize_t pos = 0; int err = 0; Py_BEGIN_CRITICAL_SECTION(dict); while (PyDict_Next(dict, &pos, &key, &val)) { if (MS_LIKELY(PyUnicode_CheckExact(key))) { Py_ssize_t key_len; if (MS_UNLIKELY(val == UNSET)) continue; const char* key_buf = unicode_str_and_size(key, &key_len); if (MS_UNLIKELY(key_buf == NULL)) { err = 1; break; } if (MS_UNLIKELY(*key_buf == '_')) continue; PyObject *val2 = to_builtins(self, val, false); if (val2 == NULL) { err = 1; break; } int status = PyDict_SetItem(out, key, val2); Py_DECREF(val2); if (status < 0) { err = 1; break; } } } Py_END_CRITICAL_SECTION(); if (MS_UNLIKELY(err)) goto cleanup; } /* Then encode everything in slots */ PyTypeObject *type = Py_TYPE(obj); while (type != NULL) { Py_ssize_t n = Py_SIZE(type); if (n) { PyMemberDef *mp = MS_PyHeapType_GET_MEMBERS((PyHeapTypeObject *)type); for (Py_ssize_t i = 0; i < n; i++, mp++) { if (MS_LIKELY(mp->type == T_OBJECT_EX && !(mp->flags & READONLY))) { char *addr = (char *)obj + mp->offset; PyObject *val = *(PyObject **)addr; if (MS_UNLIKELY(val == UNSET)) continue; if (MS_UNLIKELY(val == NULL)) continue; if (MS_UNLIKELY(*mp->name == '_')) continue; PyObject *key = PyUnicode_InternFromString(mp->name); if (key == NULL) goto cleanup; int status = -1; PyObject *val2 = to_builtins(self, val, false); if (val2 != NULL) { status = PyDict_SetItem(out, key, val2); Py_DECREF(val2); } Py_DECREF(key); if (status < 0) goto cleanup; } } } type = type->tp_base; } if (MS_UNLIKELY(self->order == ORDER_SORTED)) { sort_dict_inplace(&out); } ok = true; cleanup: Py_XDECREF(dict); Py_END_CRITICAL_SECTION(); Py_LeaveRecursiveCall(); if (!ok) { Py_CLEAR(out); } return out; } static PyObject * to_builtins(ToBuiltinsState *self, PyObject *obj, bool is_key) { PyTypeObject *type = Py_TYPE(obj); if ( obj == Py_None || type == &PyBool_Type || type == &PyLong_Type || type == &PyFloat_Type || type == &PyUnicode_Type ) { goto builtin; } else if (type == &PyBytes_Type) { if (self->builtin_types & MS_BUILTIN_BYTES) goto builtin; return to_builtins_binary( self, PyBytes_AS_STRING(obj), PyBytes_GET_SIZE(obj) ); } else if (type == &PyByteArray_Type) { if (self->builtin_types & MS_BUILTIN_BYTEARRAY) goto builtin; return to_builtins_binary( self, PyByteArray_AS_STRING(obj), PyByteArray_GET_SIZE(obj) ); } else if (type == &PyMemoryView_Type) { if (self->builtin_types & MS_BUILTIN_MEMORYVIEW) goto builtin; PyObject *out; Py_buffer buffer; if (PyObject_GetBuffer(obj, &buffer, PyBUF_CONTIG_RO) < 0) return NULL; out = to_builtins_binary(self, buffer.buf, buffer.len); PyBuffer_Release(&buffer); return out; } else if (type == PyDateTimeAPI->DateTimeType) { if (self->builtin_types & MS_BUILTIN_DATETIME) goto builtin; return to_builtins_datetime(self, obj); } else if (type == PyDateTimeAPI->DateType) { if (self->builtin_types & MS_BUILTIN_DATE) goto builtin; return to_builtins_date(self, obj); } else if (type == PyDateTimeAPI->TimeType) { if (self->builtin_types & MS_BUILTIN_TIME) goto builtin; return to_builtins_time(self, obj); } else if (type == PyDateTimeAPI->DeltaType) { if (self->builtin_types & MS_BUILTIN_TIMEDELTA) goto builtin; return to_builtins_timedelta(self, obj); } else if (type == (PyTypeObject *)(self->mod->DecimalType)) { if (self->builtin_types & MS_BUILTIN_DECIMAL) goto builtin; return to_builtins_decimal(self, obj); } else if (PyList_Check(obj)) { return to_builtins_list(self, obj); } else if (PyTuple_Check(obj)) { return to_builtins_tuple(self, obj, is_key); } else if (PyDict_Check(obj)) { return to_builtins_dict(self, obj); } #if PY315_PLUS else if (PyFrozenDict_Check(obj)) { return to_builtins_frozendict(self, obj); } #endif else if (ms_is_struct_type(type)) { return to_builtins_struct(self, obj, is_key); } else if (PyType_IsSubtype(Py_TYPE(type), self->mod->EnumMetaType)) { return to_builtins_enum(self, obj); } else if (is_key & PyUnicode_Check(obj)) { return PyObject_Str(obj); } else if (PyType_IsSubtype(type, (PyTypeObject *)(self->mod->UUIDType))) { if (self->builtin_types & MS_BUILTIN_UUID) goto builtin; return to_builtins_uuid(self, obj); } else if (PyAnySet_Check(obj)) { return to_builtins_set(self, obj, is_key); } else if (!PyType_Check(obj) && type->tp_dict != NULL) { PyObject *fields = ms_get_dataclass_fields(self->mod, type, obj); if (fields != NULL) { PyObject *out = to_builtins_dataclass(self, obj, fields); Py_DECREF(fields); return out; } if (PyDict_Contains(type->tp_dict, self->mod->str___attrs_attrs__)) { return to_builtins_object(self, obj); } } if (self->builtin_types_seq != NULL) { PyObject **items = PySequence_Fast_ITEMS(self->builtin_types_seq); Py_ssize_t size = PySequence_Fast_GET_SIZE(self->builtin_types_seq); for (Py_ssize_t i = 0; i < size; i++) { if (((PyObject *)type) == *(items + i)) goto builtin; } } if (self->enc_hook != NULL) { PyObject *out = NULL; PyObject *temp; temp = PyObject_CallOneArg(self->enc_hook, obj); if (temp == NULL) return NULL; if (!Py_EnterRecursiveCall(" while serializing an object")) { out = to_builtins(self, temp, is_key); Py_LeaveRecursiveCall(); } Py_DECREF(temp); return out; } else { ms_encode_err_type_unsupported(type); return NULL; } builtin: Py_INCREF(obj); return obj; } static int ms_process_builtin_types( MsgspecState *mod, PyObject *builtin_types, uint32_t *mask, PyObject **custom_types ) { if (builtin_types == NULL || builtin_types == Py_None) return 0; bool forward_builtins_seq = false; const char *invalid_type_err = "builtin_types must be an iterable of types"; PyObject *seq = PySequence_Fast(builtin_types, invalid_type_err); if (seq == NULL) return -1; Py_ssize_t size = PySequence_Fast_GET_SIZE(seq); PyObject **items = PySequence_Fast_ITEMS(seq); for (Py_ssize_t i = 0; i < size; i++) { PyObject *type = *(items + i); if (type == (PyObject *)(&PyBytes_Type)) { *mask |= MS_BUILTIN_BYTES; } else if (type == (PyObject *)(&PyByteArray_Type)) { *mask |= MS_BUILTIN_BYTEARRAY; } else if (type == (PyObject *)(&PyMemoryView_Type)) { *mask |= MS_BUILTIN_MEMORYVIEW; } #if PY315_PLUS else if (type == (PyObject *)(&PyFrozenDict_Type)) { *mask |= MS_BUILTIN_FROZENDICT; } #endif else if (type == (PyObject *)(PyDateTimeAPI->DateTimeType)) { *mask |= MS_BUILTIN_DATETIME; } else if (type == (PyObject *)(PyDateTimeAPI->DateType)) { *mask |= MS_BUILTIN_DATE; } else if (type == (PyObject *)(PyDateTimeAPI->TimeType)) { *mask |= MS_BUILTIN_TIME; } else if (type == (PyObject *)(PyDateTimeAPI->DeltaType)) { *mask |= MS_BUILTIN_TIMEDELTA; } else if (type == mod->UUIDType) { *mask |= MS_BUILTIN_UUID; } else if (type == mod->DecimalType) { *mask |= MS_BUILTIN_DECIMAL; } else if (!PyType_Check(type)) { PyErr_SetString(PyExc_TypeError, invalid_type_err); goto error; } else if (custom_types != NULL) { forward_builtins_seq = true; } else { PyErr_Format(PyExc_TypeError, "Cannot treat %R as a builtin type", type); goto error; } } if (forward_builtins_seq) { *custom_types = seq; } else { Py_DECREF(seq); } return 0; error: Py_DECREF(seq); return -1; } PyDoc_STRVAR(msgspec_to_builtins__doc__, "to_builtins(obj, *, str_keys=False, builtin_types=None, enc_hook=None, order=None)\n" "--\n" "\n" "Convert a complex object to one composed only of simpler builtin types\n" "commonly supported by Python serialization libraries.\n" "\n" "This is mainly useful for adding msgspec support for other protocols, or\n" "for cases where msgspec is only processing part of a message. The\n" "conversion applies the same semantics as `msgspec.json.encode` and\n" "`msgspec.msgpack.encode`:\n" "\n" "- Struct-level settings are honored: ``rename``, ``omit_defaults``,\n" " ``array_like``, and ``tag`` for tagged unions.\n" "- Fields containing `msgspec.UNSET` are omitted from the output.\n" "- Nested `msgspec.Struct` / `dataclasses.dataclass` / attrs /\n" " `typing.TypedDict` / `typing.NamedTuple` values are recursively\n" " expanded.\n" "- Types without a direct builtin equivalent (`bytes`, `datetime.datetime`,\n" " `uuid.UUID`, `decimal.Decimal`, `enum.Enum`, ...) are converted to their\n" " serializable representations. See :ref:`to-builtins-vs-asdict` for the\n" " full list.\n" "\n" "In contrast, `msgspec.structs.asdict` and `msgspec.structs.astuple`\n" "perform a plain one-to-one conversion, applying none of the above.\n" "\n" "Parameters\n" "----------\n" "obj: Any\n" " The object to convert.\n" "builtin_types: Iterable[type], optional\n" " An iterable of types to treat as additional builtin types. These types will\n" " be passed through ``to_builtins`` unchanged. Currently supports `bytes`,\n" " `bytearray`, `memoryview`, `frozendict`, `datetime.datetime`, `datetime.time`,\n" " `datetime.date`, `datetime.timedelta`, `uuid.UUID`, `decimal.Decimal`,\n" " and custom types.\n" "str_keys: bool, optional\n" " Whether to convert all object keys to strings. Default is False.\n" "enc_hook : callable, optional\n" " A callable to call for objects that aren't supported msgspec types. Takes\n" " the unsupported object and should return a supported object, or raise a\n" " ``NotImplementedError`` if unsupported.\n" "order : {None, 'deterministic', 'sorted'}, optional\n" " The ordering to use when converting unordered compound types.\n" "\n" " - ``None``: All objects are converted in the most efficient manner matching\n" " their in-memory representations. The default.\n" " - `'deterministic'`: Dict keys and set elements are sorted so that values\n" " which compare equal produce identical converted output, regardless of\n" " insertion or iteration order. Useful when comparison/hashing of the\n" " converted output is necessary.\n" " - `'sorted'`: Like `'deterministic'`, but *all* object-like types (structs,\n" " dataclasses, ...) are also sorted by field name before encoding. This is\n" " slower than `'deterministic'`, but may produce more human-readable output.\n" "\n" "Returns\n" "-------\n" "Any\n" " The converted object.\n" "\n" "Examples\n" "--------\n" ">>> import msgspec\n" ">>> class Example(msgspec.Struct):\n" "... x: set[int]\n" "... y: bytes\n" ">>> msg = Example({1, 2, 3}, b'\\x01\\x02')\n" "\n" "Convert the message to a simpler set of builtin types. Note that by default\n" "all bytes-like objects are base64-encoded and converted to strings.\n" "\n" ">>> msgspec.to_builtins(msg)\n" "{'x': [1, 2, 3], 'y': 'AQI='}\n" "\n" "If the downstream code supports binary objects natively, you can\n" "disable conversion by passing in the types to ``builtin_types``.\n" "\n" ">>> msgspec.to_builtins(msg, builtin_types=(bytes, bytearray, memoryview))\n" "{'x': [1, 2, 3], 'y': b'\\x01\\x02'}\n" "\n" "See Also\n" "--------\n" "msgspec.convert\n" "msgspec.structs.asdict\n" "msgspec.structs.astuple" ); static PyObject* msgspec_to_builtins(PyObject *self, PyObject *args, PyObject *kwargs) { PyObject *obj = NULL, *builtin_types = NULL, *enc_hook = NULL, *order = NULL; int str_keys = 0; ToBuiltinsState state; char *kwlist[] = {"obj", "builtin_types", "str_keys", "enc_hook", "order", NULL}; /* Parse arguments */ if (!PyArg_ParseTupleAndKeywords( args, kwargs, "O|$OpOO", kwlist, &obj, &builtin_types, &str_keys, &enc_hook, &order )) { return NULL; } state.mod = msgspec_get_state(self); state.str_keys = str_keys; state.builtin_types = 0; state.builtin_types_seq = NULL; state.order = parse_order_arg(order); if (state.order == ORDER_INVALID) return NULL; if (enc_hook == Py_None) { enc_hook = NULL; } else if (enc_hook != NULL && !PyCallable_Check(enc_hook)) { PyErr_SetString(PyExc_TypeError, "enc_hook must be callable"); return NULL; } state.enc_hook = enc_hook; if ( ms_process_builtin_types( state.mod, builtin_types, &(state.builtin_types), &(state.builtin_types_seq) ) < 0 ) { return NULL; } PyObject *out = to_builtins(&state, obj, false); Py_XDECREF(state.builtin_types_seq); return out; } /************************************************************************* * convert * *************************************************************************/ typedef struct ConvertState { MsgspecState *mod; PyObject *dec_hook; uint32_t builtin_types; bool str_keys; bool from_attributes; bool strict; } ConvertState; static PyObject * convert(ConvertState *, PyObject *, TypeNode *, PathNode *); static PyObject * convert_int_uncommon( ConvertState *self, PyObject *obj, TypeNode *type, PathNode *path ) { if (!self->strict) { uint64_t ux; bool neg, overflow; overflow = fast_long_extract_parts(obj, &neg, &ux); if ((type->types & MS_TYPE_BOOL) && !overflow && !neg) { if (ux == 0) { Py_RETURN_FALSE; } else if (ux == 1) { Py_RETURN_TRUE; } } if (type->types & (MS_TYPE_DATETIME | MS_TYPE_TIMEDELTA)) { int64_t seconds; if (overflow || ux > LLONG_MAX) { seconds = LLONG_MAX; } else { seconds = ux; if (neg) { seconds *= -1; } } if (type->types & MS_TYPE_DATETIME) { return datetime_from_epoch(seconds, 0, type, path); } return ms_decode_timedelta_from_int64(seconds, path); } } return ms_validation_error("int", type, path); } static PyObject * convert_int( ConvertState *self, PyObject *obj, TypeNode *type, PathNode *path ) { if (MS_LIKELY(type->types & MS_TYPE_INT)) { return ms_decode_pyint(obj, type, path); } else if (type->types & (MS_TYPE_INTENUM | MS_TYPE_INTLITERAL)) { return ms_decode_int_enum_or_literal_pyint(obj, type, path); } else if (type->types & MS_TYPE_FLOAT) { double val = PyLong_AsDouble(obj); if (val == -1.0 && PyErr_Occurred()) { /* `obj` is out of range for a C double (PyLong_AsDouble sets * OverflowError but still returns -1.0); without this check * that error leaks past this function as a SystemError. */ return ms_error_with_path("Number out of range%U", path); } return ms_decode_float(val, type, path); } else if ( type->types & MS_TYPE_DECIMAL && !(self->builtin_types & MS_BUILTIN_DECIMAL) ) { return ms_decode_decimal_from_pyobj(obj, path, self->mod); } return convert_int_uncommon(self, obj, type, path); } static PyObject * convert_float( ConvertState *self, PyObject *obj, TypeNode *type, PathNode *path ) { if (type->types & MS_TYPE_FLOAT) { Py_INCREF(obj); return ms_check_float_constraints(obj, type, path); } else if ( type->types & MS_TYPE_DECIMAL && !(self->builtin_types & MS_BUILTIN_DECIMAL) ) { return ms_decode_decimal_from_float( PyFloat_AS_DOUBLE(obj), path, self->mod ); } else if (!self->strict) { double val = PyFloat_AS_DOUBLE(obj); if (type->types & MS_TYPE_INT) { int64_t out; if (double_as_int64(val, &out)) { return ms_post_decode_int64(out, type, path, self->strict, false); } } if (type->types & MS_TYPE_DATETIME) { return ms_decode_datetime_from_float(val, type, path); } else if (type->types & MS_TYPE_TIMEDELTA) { return ms_decode_timedelta_from_float(val, path); } } return ms_validation_error("float", type, path); } static PyObject * convert_bool( ConvertState *self, PyObject *obj, TypeNode *type, PathNode *path ) { if (type->types & MS_TYPE_BOOL) { Py_INCREF(obj); return obj; } if (obj == Py_True && (type->types & MS_TYPE_BOOLLITERAL_TRUE)) { Py_INCREF(Py_True); return Py_True; } if (obj == Py_False && (type->types & MS_TYPE_BOOLLITERAL_FALSE)) { Py_INCREF(Py_False); return Py_False; } if (type->types & (MS_TYPE_BOOLLITERAL_TRUE | MS_TYPE_BOOLLITERAL_FALSE)) { ms_raise_validation_error(path, "Invalid enum value %R%U", obj); return NULL; } return ms_validation_error("bool", type, path); } static PyObject * convert_none( ConvertState *self, PyObject *obj, TypeNode *type, PathNode *path ) { if (type->types & MS_TYPE_NONE) { Py_INCREF(obj); return obj; } return ms_validation_error("null", type, path); } static PyObject * convert_str_uncommon( ConvertState *self, PyObject *obj, const char *view, Py_ssize_t size, bool is_key, TypeNode *type, PathNode *path ) { if (is_key && self->str_keys && ( type->types & ( MS_TYPE_INT | MS_TYPE_INTENUM | MS_TYPE_INTLITERAL | MS_TYPE_FLOAT | MS_TYPE_DECIMAL | ((!self->strict) * (MS_TYPE_DATETIME | MS_TYPE_TIMEDELTA)) ) ) ) { PyObject *out; if (maybe_parse_number(view, size, type, path, self->strict, &out)) { return out; } } if (type->types & (MS_TYPE_ENUM | MS_TYPE_STRLITERAL)) { return ms_decode_str_enum_or_literal(view, size, type, path); } else if ( (type->types & MS_TYPE_DATETIME) && !(self->builtin_types & MS_BUILTIN_DATETIME) ) { return ms_decode_datetime_from_str(view, size, type, path); } else if ( (type->types & MS_TYPE_DATE) && !(self->builtin_types & MS_BUILTIN_DATE) ) { return ms_decode_date(view, size, path); } else if ( (type->types & MS_TYPE_TIME) && !(self->builtin_types & MS_BUILTIN_TIME) ) { return ms_decode_time(view, size, type, path); } else if ( (type->types & MS_TYPE_TIMEDELTA) && !(self->builtin_types & MS_BUILTIN_TIMEDELTA) ) { return ms_decode_timedelta(view, size, type, path); } else if ( (type->types & MS_TYPE_UUID) && !(self->builtin_types & MS_BUILTIN_UUID) ) { return ms_decode_uuid_from_str(view, size, path); } else if ( (type->types & MS_TYPE_DECIMAL) && !(self->builtin_types & MS_BUILTIN_DECIMAL) ) { return ms_decode_decimal_from_pystr(obj, path, self->mod); } else if ( (type->types & MS_TYPE_BYTES) && !(self->builtin_types & MS_BUILTIN_BYTES) ) { return json_decode_binary(view, size, type, path); } else if ( (type->types & MS_TYPE_BYTEARRAY) && !(self->builtin_types & MS_BUILTIN_BYTEARRAY) ) { return json_decode_binary(view, size, type, path); } else if ( (type->types & MS_TYPE_MEMORYVIEW) && !(self->builtin_types & MS_BUILTIN_MEMORYVIEW) ) { return json_decode_binary(view, size, type, path); } return ms_validation_error("str", type, path); } static PyObject * convert_str( ConvertState *self, PyObject *obj, bool is_key, TypeNode *type, PathNode *path ) { if (type->types & (MS_TYPE_ANY | MS_TYPE_STR)) { Py_INCREF(obj); return ms_check_str_constraints(obj, type, path); } Py_ssize_t size; const char* view = unicode_str_and_size(obj, &size); if (view == NULL) return NULL; if (MS_UNLIKELY(!self->strict)) { bool invalid = false; PyObject *out = ms_decode_str_lax(view, size, type, path, &invalid); if (!invalid) return out; } return convert_str_uncommon(self, obj, view, size, is_key, type, path); } static PyObject * convert_bytes( ConvertState *self, PyObject *obj, TypeNode *type, PathNode *path ) { if (type->types & (MS_TYPE_BYTES | MS_TYPE_BYTEARRAY | MS_TYPE_MEMORYVIEW)) { if (!ms_passes_bytes_constraints(PyBytes_GET_SIZE(obj), type, path)) { return NULL; } if (type->types & MS_TYPE_BYTES) { return PyBytes_FromObject(obj); } else if (type->types & MS_TYPE_BYTEARRAY) { return PyByteArray_FromObject(obj); } else { return PyMemoryView_FromObject(obj); } } if ( (type->types & MS_TYPE_UUID) && !(self->builtin_types & MS_BUILTIN_UUID) ) { return ms_decode_uuid_from_bytes( PyBytes_AS_STRING(obj), PyBytes_GET_SIZE(obj), path ); } return ms_validation_error("bytes", type, path); } static PyObject * convert_bytearray( ConvertState *self, PyObject *obj, TypeNode *type, PathNode *path ) { if (type->types & (MS_TYPE_BYTES | MS_TYPE_BYTEARRAY | MS_TYPE_MEMORYVIEW)) { if (!ms_passes_bytes_constraints(PyByteArray_GET_SIZE(obj), type, path)) { return NULL; } if (type->types & MS_TYPE_BYTEARRAY) { Py_INCREF(obj); return obj; } else if (type->types & MS_TYPE_BYTES) { return PyBytes_FromObject(obj); } else { return PyMemoryView_FromObject(obj); } } if ( (type->types & MS_TYPE_UUID) && !(self->builtin_types & MS_BUILTIN_UUID) ) { return ms_decode_uuid_from_bytes( PyByteArray_AS_STRING(obj), PyByteArray_GET_SIZE(obj), path ); } return ms_validation_error("bytes", type, path); } static PyObject * convert_memoryview( ConvertState *self, PyObject *obj, TypeNode *type, PathNode *path ) { if (type->types & (MS_TYPE_BYTES | MS_TYPE_BYTEARRAY | MS_TYPE_MEMORYVIEW)) { Py_ssize_t len = PyMemoryView_GET_BUFFER(obj)->len; if (!ms_passes_bytes_constraints(len, type, path)) return NULL; if (type->types & MS_TYPE_MEMORYVIEW) { Py_INCREF(obj); return obj; } else if (type->types & MS_TYPE_BYTES) { return PyBytes_FromObject(obj); } else { return PyByteArray_FromObject(obj); } } if ( (type->types & MS_TYPE_UUID) && !(self->builtin_types & MS_BUILTIN_UUID) ) { Py_buffer buffer; if (PyObject_GetBuffer(obj, &buffer, PyBUF_CONTIG_RO) < 0) return NULL; PyObject *out = ms_decode_uuid_from_bytes( buffer.buf, buffer.len, path ); PyBuffer_Release(&buffer); return out; } return ms_validation_error("bytes", type, path); } static PyObject * convert_datetime( ConvertState *self, PyObject *obj, TypeNode *type, PathNode *path ) { if (type->types & MS_TYPE_DATETIME) { PyObject *tz = MS_DATE_GET_TZINFO(obj); if (!ms_passes_tz_constraint(tz, type, path)) return NULL; Py_INCREF(obj); return obj; } return ms_validation_error("datetime", type, path); } static PyObject * convert_time( ConvertState *self, PyObject *obj, TypeNode *type, PathNode *path ) { if (type->types & MS_TYPE_TIME) { PyObject *tz = MS_TIME_GET_TZINFO(obj); if (!ms_passes_tz_constraint(tz, type, path)) return NULL; Py_INCREF(obj); return obj; } return ms_validation_error("time", type, path); } static PyObject * convert_enum( ConvertState *self, PyObject *obj, TypeNode *type, PathNode *path ) { if (type->types & MS_TYPE_ENUM) { StrLookup *lookup = TypeNode_get_str_enum_or_literal(type); /* Check that the type matches. Note that enums that are also int or * str subclasses will be handled by `convert_int`/`convert_str`, not * here */ if (lookup->common.cls != NULL && Py_TYPE(obj) == (PyTypeObject *)(lookup->common.cls)) { Py_INCREF(obj); return obj; } } return ms_validation_error(Py_TYPE(obj)->tp_name, type, path); } static PyObject * convert_decimal( ConvertState *self, PyObject *obj, TypeNode *type, PathNode *path ) { if (type->types & MS_TYPE_DECIMAL) { Py_INCREF(obj); return obj; } else if (type->types & MS_TYPE_FLOAT) { PyObject *temp = PyNumber_Float(obj); if (temp == NULL) return NULL; PyObject *out = convert_float(self, temp, type, path); Py_DECREF(temp); return out; } return ms_validation_error("decimal", type, path); } static PyObject * convert_immutable( ConvertState *self, uint64_t mask, const char *expected, PyObject *obj, TypeNode *type, PathNode *path ) { if (type->types & mask) { Py_INCREF(obj); return obj; } return ms_validation_error(expected, type, path); } static PyObject * convert_raw( ConvertState *self, PyObject *obj, TypeNode *type, PathNode *path ) { if (type->types == 0) { Py_INCREF(obj); return obj; } return ms_validation_error("raw", type, path); } static PyObject * convert_seq_to_list( ConvertState *self, PyObject **items, Py_ssize_t size, TypeNode *item_type, PathNode *path ) { PyObject *out = PyList_New(size); if (out == NULL) return NULL; if (size == 0) return out; if (Py_EnterRecursiveCall(" while deserializing an object")) { Py_DECREF(out); return NULL; /* cpylint-ignore */ } for (Py_ssize_t i = 0; i < size; i++) { PathNode item_path = {path, i}; PyObject *val = convert(self, items[i], item_type, &item_path); if (val == NULL) { Py_CLEAR(out); break; } PyList_SET_ITEM(out, i, val); } Py_LeaveRecursiveCall(); return out; } static PyObject * convert_seq_to_set( ConvertState *self, PyObject **items, Py_ssize_t size, bool mutable, TypeNode *item_type, PathNode *path ) { PyObject *out = mutable ? PySet_New(NULL) : PyFrozenSet_New(NULL); if (out == NULL) return NULL; if (size == 0) return out; if (Py_EnterRecursiveCall(" while deserializing an object")) { Py_DECREF(out); return NULL; /* cpylint-ignore */ } for (Py_ssize_t i = 0; i < size; i++) { PathNode item_path = {path, i}; PyObject *val = convert(self, items[i], item_type, &item_path); if (MS_UNLIKELY(val == NULL || PySet_Add(out, val) < 0)) { Py_XDECREF(val); Py_CLEAR(out); break; } Py_DECREF(val); } Py_LeaveRecursiveCall(); return out; } static PyObject * convert_seq_to_vartuple( ConvertState *self, PyObject **items, Py_ssize_t size, TypeNode *item_type, PathNode *path ) { PyObject *out = PyTuple_New(size); if (out == NULL) return NULL; if (size == 0) return out; if (Py_EnterRecursiveCall(" while deserializing an object")) { Py_DECREF(out); return NULL; /* cpylint-ignore */ } for (Py_ssize_t i = 0; i < size; i++) { PathNode item_path = {path, i}; PyObject *val = convert(self, items[i], item_type, &item_path); if (val == NULL) { Py_CLEAR(out); break; } PyTuple_SET_ITEM(out, i, val); } Py_LeaveRecursiveCall(); return out; } static PyObject * convert_seq_to_fixtuple( ConvertState *self, PyObject **items, Py_ssize_t size, TypeNode *type, PathNode *path ) { Py_ssize_t fixtuple_size, offset; TypeNode_get_fixtuple(type, &offset, &fixtuple_size); if (size != fixtuple_size) { /* tuple is the incorrect size, raise and return */ ms_raise_validation_error( path, "Expected `array` of length %zd, got %zd%U", fixtuple_size, size ); return NULL; } PyObject *out = PyTuple_New(size); if (out == NULL) return NULL; if (size == 0) return out; if (Py_EnterRecursiveCall(" while deserializing an object")) { Py_DECREF(out); return NULL; /* cpylint-ignore */ } for (Py_ssize_t i = 0; i < fixtuple_size; i++) { PathNode item_path = {path, i}; PyObject *val = convert( self, items[i], type->details[offset + i].pointer, &item_path ); if (MS_UNLIKELY(val == NULL)) { Py_CLEAR(out); break; } PyTuple_SET_ITEM(out, i, val); } Py_LeaveRecursiveCall(); return out; } static PyObject * convert_seq_to_namedtuple( ConvertState *self, PyObject **items, Py_ssize_t size, TypeNode *type, PathNode *path ) { NamedTupleInfo *info = TypeNode_get_namedtuple_info(type); Py_ssize_t nfields = Py_SIZE(info); Py_ssize_t ndefaults = info->defaults == NULL ? 0 : PyTuple_GET_SIZE(info->defaults); Py_ssize_t nrequired = nfields - ndefaults; if (size < nrequired || nfields < size) { /* tuple is the incorrect size, raise and return */ if (ndefaults == 0) { ms_raise_validation_error( path, "Expected `array` of length %zd, got %zd%U", nfields, size ); } else { ms_raise_validation_error( path, "Expected `array` of length %zd to %zd, got %zd%U", nrequired, nfields, size ); } return NULL; } if (Py_EnterRecursiveCall(" while deserializing an object")) return NULL; PyTypeObject *nt_type = (PyTypeObject *)(info->class); PyObject *out = nt_type->tp_alloc(nt_type, nfields); if (out == NULL) goto error; MS_TUPLE_RESET_HASH(out); for (Py_ssize_t i = 0; i < nfields; i++) { PyTuple_SET_ITEM(out, i, NULL); } for (Py_ssize_t i = 0; i < size; i++) { PathNode item_path = {path, i}; PyObject *item = convert(self, items[i], info->types[i], &item_path); if (MS_UNLIKELY(item == NULL)) goto error; PyTuple_SET_ITEM(out, i, item); } for (Py_ssize_t i = size; i < nfields; i++) { PyObject *item = PyTuple_GET_ITEM(info->defaults, i - nrequired); Py_INCREF(item); PyTuple_SET_ITEM(out, i, item); } Py_LeaveRecursiveCall(); return out; error: Py_LeaveRecursiveCall(); Py_DECREF(out); return NULL; } static bool convert_tag_matches( ConvertState *self, PyObject *tag, PyObject *expected_tag, PathNode *path ) { if (PyUnicode_CheckExact(expected_tag)) { if (!PyUnicode_CheckExact(tag)) goto wrong_type; } else if (!PyLong_CheckExact(tag)) { goto wrong_type; } int status = PyObject_RichCompareBool(tag, expected_tag, Py_EQ); if (status == 1) return true; if (status == 0) { ms_raise_validation_error(path, "Invalid value %R%U", tag); } return false; wrong_type: ms_raise_validation_error( path, "Expected `%s`, got `%s`%U", (PyUnicode_CheckExact(expected_tag) ? "str" : "int"), Py_TYPE(tag)->tp_name ); return false; } static StructInfo * convert_lookup_tag( ConvertState *self, Lookup *lookup, PyObject *tag, PathNode *path ) { StructInfo *out = NULL; if (Lookup_IsStrLookup(lookup)) { if (!PyUnicode_CheckExact(tag)) goto wrong_type; Py_ssize_t size; const char *buf = unicode_str_and_size(tag, &size); if (buf == NULL) return NULL; out = (StructInfo *)StrLookup_Get((StrLookup *)lookup, buf, size); } else { if (!PyLong_CheckExact(tag)) goto wrong_type; uint64_t ux; bool neg, overflow; overflow = fast_long_extract_parts(tag, &neg, &ux); if (overflow) goto invalid_value; if (neg) { out = (StructInfo *)IntLookup_GetInt64((IntLookup *)lookup, -(int64_t)ux); } else { out = (StructInfo *)IntLookup_GetUInt64((IntLookup *)lookup, ux); } } if (out != NULL) return out; invalid_value: ms_raise_validation_error(path, "Invalid value %R%U", tag); return NULL; wrong_type: ms_raise_validation_error( path, "Expected `%s`, got `%s`%U", (Lookup_IsStrLookup(lookup) ? "str" : "int"), Py_TYPE(tag)->tp_name ); return NULL; } static PyObject * convert_seq_to_struct_array_inner( ConvertState *self, PyObject **items, Py_ssize_t size, bool tag_already_read, StructInfo *info, PathNode *path ) { StructMetaObject *st_type = info->class; PathNode item_path = {path, 0}; bool tagged = st_type->struct_tag_value != NULL; Py_ssize_t nfields = PyTuple_GET_SIZE(st_type->struct_encode_fields); Py_ssize_t ndefaults = PyTuple_GET_SIZE(st_type->struct_defaults); Py_ssize_t nrequired = tagged + nfields - st_type->n_trailing_defaults; Py_ssize_t npos = nfields - ndefaults; if (size < nrequired) { ms_raise_validation_error( path, "Expected `array` of at least length %zd, got %zd%U", nrequired, size ); return NULL; } if (tagged) { if (!tag_already_read) { if ( !convert_tag_matches( self, items[item_path.index], st_type->struct_tag_value, &item_path ) ) { return NULL; } } size--; item_path.index++; } if (Py_EnterRecursiveCall(" while deserializing an object")) return NULL; PyObject *out = Struct_alloc((PyTypeObject *)(st_type)); if (out == NULL) goto error; bool is_gc = MS_TYPE_IS_GC(st_type); bool should_untrack = is_gc; for (Py_ssize_t i = 0; i < nfields; i++) { PyObject *val; if (size > 0) { val = convert( self, items[item_path.index], info->types[i], &item_path ); if (MS_UNLIKELY(val == NULL)) goto error; size--; item_path.index++; } else { val = get_default( PyTuple_GET_ITEM(st_type->struct_defaults, i - npos) ); if (val == NULL) goto error; } Struct_set_index(out, i, val); if (should_untrack) { should_untrack = !MS_MAYBE_TRACKED(val); } } if (MS_UNLIKELY(size > 0)) { if (MS_UNLIKELY(st_type->forbid_unknown_fields == OPT_TRUE)) { ms_raise_validation_error( path, "Expected `array` of at most length %zd, got %zd%U", nfields, nfields + size ); goto error; } } if (Struct_decode_post_init(st_type, out, path) < 0) goto error; Py_LeaveRecursiveCall(); if (is_gc && should_untrack && MS_IS_TRACKED(out)) PyObject_GC_UnTrack(out); return out; error: Py_LeaveRecursiveCall(); Py_XDECREF(out); return NULL; } static PyObject * convert_seq_to_struct_array( ConvertState *self, PyObject **items, Py_ssize_t size, TypeNode *type, PathNode *path ) { return convert_seq_to_struct_array_inner( self, items, size, false, TypeNode_get_struct_info(type), path ); } static PyObject * convert_seq_to_struct_array_union( ConvertState *self, PyObject **items, Py_ssize_t size, TypeNode *type, PathNode *path ) { Lookup *lookup = TypeNode_get_struct_union(type); if (size == 0) { return ms_error_with_path( "Expected `array` of at least length 1, got 0%U", path ); } PathNode tag_path = {path, 0}; StructInfo *info = convert_lookup_tag(self, lookup, items[0], &tag_path); if (info == NULL) return NULL; return convert_seq_to_struct_array_inner(self, items, size, true, info, path); } static PyObject * convert_seq( ConvertState *self, PyObject **items, Py_ssize_t size, TypeNode *type, PathNode *path ) { if (!ms_passes_array_constraints(size, type, path)) return NULL; if (type->types & MS_TYPE_LIST) { return convert_seq_to_list( self, items, size, TypeNode_get_array(type), path ); } else if (type->types & (MS_TYPE_SET | MS_TYPE_FROZENSET)) { return convert_seq_to_set( self, items, size, (type->types & MS_TYPE_SET), TypeNode_get_array(type), path ); } else if (type->types & MS_TYPE_VARTUPLE) { return convert_seq_to_vartuple( self, items, size, TypeNode_get_array(type), path ); } else if (type->types & MS_TYPE_FIXTUPLE) { return convert_seq_to_fixtuple(self, items, size, type, path); } else if (type->types & MS_TYPE_NAMEDTUPLE) { return convert_seq_to_namedtuple(self, items, size, type, path); } else if (type->types & MS_TYPE_STRUCT_ARRAY) { return convert_seq_to_struct_array(self, items, size, type, path); } else if (type->types & MS_TYPE_STRUCT_ARRAY_UNION) { return convert_seq_to_struct_array_union(self, items, size, type, path); } return ms_validation_error("array", type, path); } static PyObject * convert_any_set( ConvertState *self, PyObject *obj, TypeNode *type, PathNode *path ) { PyObject *seq = PySequence_Tuple(obj); if (seq == NULL) return NULL; PyObject **items = PySequence_Fast_ITEMS(seq); Py_ssize_t size = PySequence_Fast_GET_SIZE(seq); PyObject *out = NULL; if (!ms_passes_array_constraints(size, type, path)) goto done; if (type->types & MS_TYPE_LIST) { out = convert_seq_to_list( self, items, size, TypeNode_get_array(type), path ); } else if (type->types & (MS_TYPE_SET | MS_TYPE_FROZENSET)) { out = convert_seq_to_set( self, items, size, (type->types & MS_TYPE_SET), TypeNode_get_array(type), path ); } else if (type->types & MS_TYPE_VARTUPLE) { out = convert_seq_to_vartuple( self, items, size, TypeNode_get_array(type), path ); } else { ms_validation_error("set", type, path); } done: Py_DECREF(seq); return out; } static PyObject * convert_dict_to_dict( ConvertState *self, PyObject *obj, TypeNode *type, PathNode *path ) { Py_ssize_t size = PyDict_GET_SIZE(obj); if (!ms_passes_map_constraints(size, type, path)) return NULL; TypeNode *key_type, *val_type; TypeNode_get_dict(type, &key_type, &val_type); PathNode key_path = {path, PATH_KEY, NULL}; PathNode val_path = {path, PATH_ELLIPSIS, NULL}; PyObject *out = PyDict_New(); if (out == NULL) return NULL; if (PyDict_GET_SIZE(obj) == 0) return out; if (Py_EnterRecursiveCall(" while deserializing an object")) { Py_DECREF(out); return NULL; /* cpylint-ignore */ } PyObject *key_obj = NULL, *val_obj = NULL; Py_ssize_t pos = 0; while (PyDict_Next(obj, &pos, &key_obj, &val_obj)) { PyObject *key; if (PyUnicode_CheckExact(key_obj)) { key = convert_str(self, key_obj, true, key_type, &key_path); } else { key = convert(self, key_obj, key_type, &key_path); } if (MS_UNLIKELY(key == NULL)) goto error; PyObject *val = convert(self, val_obj, val_type, &val_path); if (MS_UNLIKELY(val == NULL)) { Py_DECREF(key); goto error; } int status = PyDict_SetItem(out, key, val); Py_DECREF(key); Py_DECREF(val); if (status < 0) goto error; } Py_LeaveRecursiveCall(); return out; error: Py_LeaveRecursiveCall(); Py_DECREF(out); return NULL; } #if PY315_PLUS static PyObject * convert_dict_to_frozendict( ConvertState *self, PyObject *obj, TypeNode *type, PathNode *path ) { PyObject *dict = convert_dict_to_dict(self, obj, type, path); return _PyFrozenDict_NewSteal(dict); } #endif static PyObject * convert_mapping_to_dict( ConvertState *self, PyObject *obj, TypeNode *type, PathNode *path ) { PyObject *out = NULL; PyObject *temp = PyDict_New(); if (temp == NULL) return NULL; if (PyDict_Merge(temp, obj, 1) == 0) { out = convert_dict_to_dict(self, temp, type, path); } Py_DECREF(temp); return out; } static bool convert_is_str_key(PyObject *key, PathNode *path) { if (PyUnicode_CheckExact(key)) return true; PathNode key_path = {path, PATH_KEY, NULL}; ms_error_with_path("Expected `str`%U", &key_path); return false; } static PyObject * convert_dict_to_struct( ConvertState *self, PyObject *obj, StructInfo *info, PathNode *path, bool tag_already_read ) { StructMetaObject *struct_type = info->class; if (Py_EnterRecursiveCall(" while deserializing an object")) return NULL; PyObject *out = Struct_alloc((PyTypeObject *)(struct_type)); if (out == NULL) goto error; Py_ssize_t pos = 0, pos_obj = 0; PyObject *key_obj, *val_obj; while (PyDict_Next(obj, &pos_obj, &key_obj, &val_obj)) { if (!convert_is_str_key(key_obj, path)) goto error; Py_ssize_t key_size; const char *key = unicode_str_and_size(key_obj, &key_size); if (key == NULL) goto error; Py_ssize_t field_index = StructMeta_get_field_index(struct_type, key, key_size, &pos); if (field_index < 0) { if (MS_UNLIKELY(field_index == -2)) { if (tag_already_read) continue; PathNode tag_path = {path, PATH_STR, struct_type->struct_tag_field}; if ( !convert_tag_matches( self, val_obj, struct_type->struct_tag_value, &tag_path ) ) { goto error; } } else { /* Unknown field */ if (MS_UNLIKELY(struct_type->forbid_unknown_fields == OPT_TRUE)) { ms_error_unknown_field(key, key_size, path); goto error; } } } else { PathNode field_path = {path, field_index, (PyObject *)struct_type}; PyObject *val = convert( self, val_obj, info->types[field_index], &field_path ); if (val == NULL) goto error; Struct_set_index(out, field_index, val); } } if (Struct_fill_in_defaults(struct_type, out, path) < 0) goto error; Py_LeaveRecursiveCall(); return out; error: Py_LeaveRecursiveCall(); Py_XDECREF(out); return NULL; } static PyObject * convert_dict_to_struct_union( ConvertState *self, PyObject *obj, TypeNode *type, PathNode *path ) { Lookup *lookup = TypeNode_get_struct_union(type); PyObject *tag_field = Lookup_tag_field(lookup); PyObject *value = PyDict_GetItem(obj, tag_field); if (value != NULL) { PathNode tag_path = {path, PATH_STR, tag_field}; StructInfo *info = convert_lookup_tag( self, lookup, value, &tag_path ); if (info == NULL) return NULL; return convert_dict_to_struct(self, obj, info, path, true); } ms_missing_required_field(tag_field, path); return NULL; } static PyObject * convert_dict_to_typeddict( ConvertState *self, PyObject *obj, TypeNode *type, PathNode *path ) { if (Py_EnterRecursiveCall(" while deserializing an object")) return NULL; PyObject *out = PyDict_New(); if (out == NULL) goto error; TypedDictInfo *info = TypeNode_get_typeddict_info(type); Py_ssize_t nrequired = 0, pos = 0, pos_obj = 0; PyObject *key_obj, *val_obj; while (PyDict_Next(obj, &pos_obj, &key_obj, &val_obj)) { if (!convert_is_str_key(key_obj, path)) goto error; Py_ssize_t key_size; const char *key = unicode_str_and_size(key_obj, &key_size); if (key == NULL) goto error; TypeNode *field_type; PyObject *field = TypedDictInfo_lookup_key( info, key, key_size, &field_type, &pos ); if (field != NULL) { if (field_type->types & MS_EXTRA_FLAG) nrequired++; PathNode field_path = {path, PATH_STR, field}; PyObject *val = convert(self, val_obj, field_type, &field_path); if (val == NULL) goto error; int status = PyDict_SetItem(out, field, val); Py_DECREF(val); if (status < 0) goto error; } } if (nrequired < info->nrequired) { /* A required field is missing, determine which one and raise */ TypedDictInfo_error_missing(info, out, path); goto error; } Py_LeaveRecursiveCall(); return out; error: Py_LeaveRecursiveCall(); Py_XDECREF(out); return NULL; } static PyObject * convert_dict_to_dataclass( ConvertState *self, PyObject *obj, TypeNode *type, PathNode *path ) { if (Py_EnterRecursiveCall(" while deserializing an object")) return NULL; DataclassInfo *info = TypeNode_get_dataclass_info(type); PyTypeObject *dataclass_type = (PyTypeObject *)(info->class); PyObject *out = dataclass_type->tp_alloc(dataclass_type, 0); if (out == NULL) goto error; if (info->pre_init != NULL) { PyObject *res = PyObject_CallOneArg(info->pre_init, out); if (res == NULL) goto error; Py_DECREF(res); } Py_ssize_t pos = 0, pos_obj = 0; PyObject *key_obj = NULL, *val_obj = NULL; while (PyDict_Next(obj, &pos_obj, &key_obj, &val_obj)) { if (!convert_is_str_key(key_obj, path)) goto error; Py_ssize_t key_size; const char *key = unicode_str_and_size(key_obj, &key_size); if (MS_UNLIKELY(key == NULL)) goto error; TypeNode *field_type; PyObject *field = DataclassInfo_lookup_key( info, key, key_size, &field_type, &pos ); if (field != NULL) { PathNode field_path = {path, PATH_STR, field}; PyObject *val = convert(self, val_obj, field_type, &field_path); if (val == NULL) goto error; int status = PyObject_GenericSetAttr(out, field, val); Py_DECREF(val); if (status < 0) goto error; } } if (DataclassInfo_post_decode(info, out, path) < 0) goto error; Py_LeaveRecursiveCall(); return out; error: Py_LeaveRecursiveCall(); Py_XDECREF(out); return NULL; } static PyObject * convert_dict( ConvertState *self, PyObject *obj, TypeNode *type, PathNode *path ) { PyObject *res = NULL; Py_BEGIN_CRITICAL_SECTION(obj); if (type->types & MS_TYPE_DICT) { res = convert_dict_to_dict(self, obj, type, path); } #if PY315_PLUS else if (type->types & MS_TYPE_FROZENDICT) { res = convert_dict_to_frozendict(self, obj, type, path); } #endif else if (type->types & MS_TYPE_STRUCT) { StructInfo *info = TypeNode_get_struct_info(type); res = convert_dict_to_struct(self, obj, info, path, false); } else if (type->types & MS_TYPE_STRUCT_UNION) { res = convert_dict_to_struct_union(self, obj, type, path); } else if (type->types & MS_TYPE_TYPEDDICT) { res = convert_dict_to_typeddict(self, obj, type, path); } else if (type->types & MS_TYPE_DATACLASS) { res = convert_dict_to_dataclass(self, obj, type, path); } else { res = ms_validation_error("object", type, path); } Py_END_CRITICAL_SECTION(); return res; } static PyObject * convert_object_to_struct( ConvertState *self, PyObject *obj, StructInfo *info, PathNode *path, PyObject* (*getter)(PyObject *, PyObject *), bool tag_already_read ) { StructMetaObject *struct_type = info->class; Py_ssize_t nfields = PyTuple_GET_SIZE(struct_type->struct_encode_fields); Py_ssize_t ndefaults = PyTuple_GET_SIZE(struct_type->struct_defaults); if (struct_type->struct_tag_value != NULL && !tag_already_read) { PyObject *attr = getter(obj, struct_type->struct_tag_field); if (attr != NULL) { PathNode tag_path = {path, PATH_STR, struct_type->struct_tag_field}; bool ok = convert_tag_matches( self, attr, struct_type->struct_tag_value, &tag_path ); Py_DECREF(attr); if (!ok) return NULL; } else { /* Tag not present, ignore and continue */ PyErr_Clear(); } } if (Py_EnterRecursiveCall(" while deserializing an object")) return NULL; PyObject *out = Struct_alloc((PyTypeObject *)(struct_type)); if (out == NULL) goto error; bool is_gc = MS_TYPE_IS_GC(struct_type); bool should_untrack = is_gc; /* If no fields are renamed we only have one fields tuple to choose from */ PyObject *fields = NULL; if (struct_type->struct_fields == struct_type->struct_encode_fields) { fields = struct_type->struct_fields; } for (Py_ssize_t i = 0; i < nfields; i++) { PyObject *field, *attr, *val; if (MS_LIKELY(fields != NULL)) { /* fields tuple already determined, just get the next field name */ field = PyTuple_GET_ITEM(fields, i); attr = getter(obj, field); } else { /* fields tuple undetermined. Try the attribute name first */ PyObject *encode_field; field = PyTuple_GET_ITEM(struct_type->struct_fields, i); encode_field = PyTuple_GET_ITEM(struct_type->struct_encode_fields, i); attr = getter(obj, field); if (field != encode_field) { /* The field _was_ renamed */ if (attr != NULL) { /* Got a match, lock-in using attribute names */ fields = struct_type->struct_fields; } else { /* No match. Try using the renamed name */ PyErr_Clear(); attr = getter(obj, encode_field); if (attr != NULL) { /* Got a match, lock-in using renamed names */ field = encode_field; fields = struct_type->struct_encode_fields; } } } } if (attr != NULL) { PathNode field_path = {path, PATH_STR, field}; val = convert(self, attr, info->types[i], &field_path); Py_DECREF(attr); } else { PyErr_Clear(); PyObject *default_val = NULL; if (MS_LIKELY(i >= (nfields - ndefaults))) { default_val = PyTuple_GET_ITEM( struct_type->struct_defaults, i - (nfields - ndefaults) ); if (MS_UNLIKELY(default_val == NODEFAULT)) { default_val = NULL; } } if (default_val == NULL) { ms_missing_required_field(field, path); goto error; } val = get_default(default_val); } if (val == NULL) goto error; Struct_set_index(out, i, val); if (should_untrack) { should_untrack = !MS_MAYBE_TRACKED(val); } } if (Struct_decode_post_init(struct_type, out, path) < 0) goto error; Py_LeaveRecursiveCall(); if (is_gc && should_untrack && MS_IS_TRACKED(out)) PyObject_GC_UnTrack(out); return out; error: Py_LeaveRecursiveCall(); Py_XDECREF(out); return NULL; } static PyObject * convert_object_to_struct_union( ConvertState *self, PyObject *obj, TypeNode *type, PathNode *path, PyObject* (*getter)(PyObject *, PyObject *) ) { Lookup *lookup = TypeNode_get_struct_union(type); PyObject *tag_field = Lookup_tag_field(lookup); PyObject *value = getter(obj, tag_field); if (value != NULL) { PathNode tag_path = {path, PATH_STR, tag_field}; StructInfo *info = convert_lookup_tag( self, lookup, value, &tag_path ); Py_DECREF(value); if (info == NULL) return NULL; return convert_object_to_struct(self, obj, info, path, getter, true); } ms_missing_required_field(tag_field, path); return NULL; } static PyObject * convert_object_to_dataclass( ConvertState *self, PyObject *obj, TypeNode *type, PathNode *path, PyObject* (*getter)(PyObject *, PyObject *) ) { DataclassInfo *info = TypeNode_get_dataclass_info(type); Py_ssize_t nfields = Py_SIZE(info); Py_ssize_t ndefaults = PyTuple_GET_SIZE(info->defaults); if (Py_EnterRecursiveCall(" while deserializing an object")) return NULL; PyTypeObject *dataclass_type = (PyTypeObject *)(info->class); PyObject *out = dataclass_type->tp_alloc(dataclass_type, 0); if (out == NULL) goto error; if (info->pre_init != NULL) { PyObject *res = PyObject_CallOneArg(info->pre_init, out); if (res == NULL) goto error; Py_DECREF(res); } for (Py_ssize_t i = 0; i < nfields; i++) { PyObject *field = info->fields[i].key; PyObject *attr = getter(obj, field); PyObject *val; if (attr == NULL) { PyErr_Clear(); if (MS_LIKELY(i >= (nfields - ndefaults))) { PyObject *default_val = PyTuple_GET_ITEM( info->defaults, i - (nfields - ndefaults) ); bool is_factory = info->fields[i].type->types & MS_EXTRA_FLAG; if (is_factory) { val = PyObject_CallNoArgs(default_val); } else { Py_INCREF(default_val); val = default_val; } } else { ms_missing_required_field(field, path); goto error; } } else { PathNode field_path = {path, PATH_STR, field}; val = convert(self, attr, info->fields[i].type, &field_path); Py_DECREF(attr); } if (val == NULL) goto error; int status = PyObject_GenericSetAttr(out, field, val); Py_DECREF(val); if (status < 0) goto error; } if (info->post_init != NULL) { PyObject *res = PyObject_CallOneArg(info->post_init, out); if (res == NULL) { ms_maybe_wrap_validation_error(path); goto error; } Py_DECREF(res); } Py_LeaveRecursiveCall(); return out; error: Py_LeaveRecursiveCall(); Py_XDECREF(out); return NULL; } static bool Lookup_union_contains_type(Lookup *lookup, PyTypeObject *cls) { if (Lookup_IsStrLookup(lookup)) { StrLookup *lk = (StrLookup *)lookup; for (Py_ssize_t i = 0; i < Py_SIZE(lk); i++) { StructInfo *info = (StructInfo *)(lk->table[i].value); if (info != NULL && ((PyTypeObject *)(info->class) == cls)) { return true; } } } else { if (((IntLookup *)lookup)->compact) { IntLookupCompact *lk = (IntLookupCompact *)lookup; for (Py_ssize_t i = 0; i < Py_SIZE(lk); i++) { StructInfo *info = (StructInfo *)(lk->table[i]); if (info != NULL && ((PyTypeObject *)(info->class) == cls)) { return true; } } } else { IntLookupHashmap *lk = (IntLookupHashmap *)lookup; for (Py_ssize_t i = 0; i < Py_SIZE(lk); i++) { StructInfo *info = (StructInfo *)(lk->table[i].value); if (info != NULL && ((PyTypeObject *)(info->class) == cls)) { return true; } } } } return false; } static PyObject * getattr_then_getitem(PyObject *obj, PyObject *key) { PyObject *out = PyObject_GetAttr(obj, key); if (out == NULL) { PyErr_Clear(); out = PyObject_GetItem(obj, key); } return out; } static PyObject * convert_other( ConvertState *self, PyObject *obj, TypeNode *type, PathNode *path ) { PyTypeObject *pytype = Py_TYPE(obj); /* First check if instance matches requested type for builtin user-defined * collection types. */ if (type->types & (MS_TYPE_STRUCT | MS_TYPE_STRUCT_ARRAY)) { StructInfo *info = TypeNode_get_struct_info(type); if (pytype == (PyTypeObject *)(info->class)) { Py_INCREF(obj); return obj; } } else if (type->types & (MS_TYPE_STRUCT_UNION | MS_TYPE_STRUCT_ARRAY_UNION)) { Lookup *lookup = TypeNode_get_struct_union(type); if (Lookup_union_contains_type(lookup, pytype)) { Py_INCREF(obj); return obj; } } else if (type->types & MS_TYPE_DATACLASS) { DataclassInfo *info = TypeNode_get_dataclass_info(type); if (pytype == (PyTypeObject *)(info->class)) { Py_INCREF(obj); return obj; } } else if (type->types & MS_TYPE_NAMEDTUPLE) { NamedTupleInfo *info = TypeNode_get_namedtuple_info(type); if (pytype == (PyTypeObject *)(info->class)) { Py_INCREF(obj); return obj; } } /* No luck. Next check if it's a tuple subclass (standard tuples are * handled earlier), and if so try converting it as a sequence */ if (PyTuple_Check(obj)) { return convert_seq(self, TUPLE_ITEMS(obj), PyTuple_GET_SIZE(obj), type, path); } /* Next try converting from a mapping or by attribute */ bool is_mapping = PyMapping_Check(obj); if (is_mapping) { if (type->types & MS_TYPE_DICT) { return convert_mapping_to_dict(self, obj, type, path); } #if PY315_PLUS if (type->types & MS_TYPE_FROZENDICT) { PyObject *dict = convert_mapping_to_dict(self, obj, type, path); return _PyFrozenDict_NewSteal(dict); } #endif } if (is_mapping || self->from_attributes) { PyObject* (*getter)(PyObject *, PyObject *); /* We want to exclude array_like structs when converting from a * mapping, but include them when converting by attribute */ bool matches_struct, matches_struct_union; if (self->from_attributes) { getter = (is_mapping) ? getattr_then_getitem : PyObject_GetAttr; matches_struct = type->types & (MS_TYPE_STRUCT | MS_TYPE_STRUCT_ARRAY); matches_struct_union = type->types & (MS_TYPE_STRUCT_UNION | MS_TYPE_STRUCT_ARRAY_UNION); } else { getter = getattr_then_getitem; matches_struct = type->types & MS_TYPE_STRUCT; matches_struct_union = type->types & MS_TYPE_STRUCT_UNION; } if (matches_struct) { StructInfo *info = TypeNode_get_struct_info(type); return convert_object_to_struct(self, obj, info, path, getter, false); } else if (matches_struct_union) { return convert_object_to_struct_union(self, obj, type, path, getter); } else if (type->types & MS_TYPE_DATACLASS) { return convert_object_to_dataclass(self, obj, type, path, getter); } } return ms_validation_error(Py_TYPE(obj)->tp_name, type, path); } static PyObject * convert( ConvertState *self, PyObject *obj, TypeNode *type, PathNode *path ) { if (MS_UNLIKELY(type->types & (MS_TYPE_CUSTOM | MS_TYPE_CUSTOM_GENERIC | MS_TYPE_ANY))) { Py_INCREF(obj); if (MS_UNLIKELY(type->types & (MS_TYPE_CUSTOM | MS_TYPE_CUSTOM_GENERIC))) { return ms_decode_custom(obj, self->dec_hook, type, path); } return obj; } PyTypeObject *pytype = Py_TYPE(obj); if (PyUnicode_Check(obj)) { return convert_str(self, obj, false, type, path); } else if (pytype == &PyBool_Type) { return convert_bool(self, obj, type, path); } else if (PyLong_Check(obj)) { return convert_int(self, obj, type, path); } else if (pytype == &PyFloat_Type) { return convert_float(self, obj, type, path); } else if (PyList_Check(obj)) { return convert_seq(self, LIST_ITEMS(obj), PyList_GET_SIZE(obj), type, path); } else if (pytype == &PyTuple_Type) { /* Tuple subclasses are handled later on */ return convert_seq(self, TUPLE_ITEMS(obj), PyTuple_GET_SIZE(obj), type, path); } else if (PyDict_Check(obj)) { return convert_dict(self, obj, type, path); } #if PY315_PLUS else if (PyFrozenDict_Check(obj)) { return convert_dict(self, obj, type, path); } #endif else if (obj == Py_None) { return convert_none(self, obj, type, path); } else if (PyBytes_Check(obj)) { return convert_bytes(self, obj, type, path); } else if (pytype == &PyByteArray_Type) { return convert_bytearray(self, obj, type, path); } else if (pytype == &PyMemoryView_Type) { return convert_memoryview(self, obj, type, path); } else if (pytype == PyDateTimeAPI->DateTimeType) { return convert_datetime(self, obj, type, path); } else if (pytype == PyDateTimeAPI->TimeType) { return convert_time(self, obj, type, path); } else if (pytype == PyDateTimeAPI->DateType) { return convert_immutable(self, MS_TYPE_DATE, "date", obj, type, path); } else if (pytype == PyDateTimeAPI->DeltaType) { return convert_immutable(self, MS_TYPE_TIMEDELTA, "duration", obj, type, path); } else if (PyType_IsSubtype(pytype, (PyTypeObject *)(self->mod->UUIDType))) { return convert_immutable(self, MS_TYPE_UUID, "uuid", obj, type, path); } else if (pytype == (PyTypeObject *)self->mod->DecimalType) { return convert_decimal(self, obj, type, path); } else if (PyType_IsSubtype(Py_TYPE(pytype), self->mod->EnumMetaType)) { return convert_enum(self, obj, type, path); } else if (pytype == &Ext_Type) { return convert_immutable(self, MS_TYPE_EXT, "ext", obj, type, path); } else if (pytype == &Raw_Type) { return convert_raw(self, obj, type, path); } else if (PyAnySet_Check(obj)) { return convert_any_set(self, obj, type, path); } else { return convert_other(self, obj, type, path); } } PyDoc_STRVAR(msgspec_convert__doc__, "convert(obj, type, *, strict=True, from_attributes=False, dec_hook=None, str_keys=False, builtin_types=None)\n" "--\n" "\n" "Convert the input object to the specified type, or error accordingly.\n" "\n" "Parameters\n" "----------\n" "obj: Any\n" " The object to convert.\n" "type: Type\n" " A Python type (in type annotation form) to convert the object to.\n" "strict: bool, optional\n" " Whether type coercion rules should be strict. Setting to False enables a\n" " wider set of coercion rules from string to non-string types for all values.\n" " Setting ``strict=False`` implies ``str_keys=True, builtin_types=None``.\n" " Default is True.\n" "from_attributes: bool, optional\n" " If True, input objects may be coerced to ``Struct``/``dataclass``/``attrs``\n" " types by extracting attributes from the input matching fields in the output\n" " type. One use case is converting database query results (ORM or otherwise)\n" " to msgspec structured types. Default is False.\n" "dec_hook: callable, optional\n" " An optional callback for handling decoding custom types. Should have the\n" " signature ``dec_hook(type: Type, obj: Any) -> Any``, where ``type`` is the\n" " expected message type, and ``obj`` is the decoded representation composed\n" " of only basic MessagePack types. This hook should transform ``obj`` into\n" " type ``type``, or raise a ``NotImplementedError`` if unsupported.\n" "builtin_types: Iterable[type], optional\n" " Useful for wrapping other serialization protocols. An iterable of types to\n" " treat as additional builtin types. Passing a type here indicates that the\n" " wrapped protocol natively supports that type, disabling any coercion to\n" " that type provided by `convert`. For example, passing\n" " ``builtin_types=(datetime,)`` disables the default ``str`` to ``datetime``\n" " conversion; the wrapped protocol must provide a ``datetime`` object\n" " directly. Currently supports `bytes`, `bytearray`, `datetime.datetime`,\n" " `datetime.time`, `datetime.date`, `datetime.timedelta`, `uuid.UUID`, and\n" " `decimal.Decimal`.\n" "str_keys: bool, optional\n" " Useful for wrapping other serialization protocols. Indicates whether the\n" " wrapped protocol only supports string keys. Setting to True enables a wider\n" " set of coercion rules from string to non-string types for dict keys.\n" " Default is False.\n" "\n" "Returns\n" "-------\n" "Any\n" " The converted object of the specified ``type``.\n" "\n" "Examples\n" "--------\n" ">>> import msgspec\n" ">>> class Example(msgspec.Struct):\n" "... x: set[int]\n" "... y: bytes\n" ">>> msg = {'x': [1, 2, 3], 'y': 'AQI='}\n" "\n" "Construct the message from a simpler set of builtin types.\n" "\n" ">>> msgspec.convert(msg, Example)\n" "Example({1, 2, 3}, b'\\x01\\x02')\n" "\n" "See Also\n" "--------\n" "to_builtins" ); static PyObject* msgspec_convert(PyObject *self, PyObject *args, PyObject *kwargs) { PyObject *obj = NULL, *pytype = NULL, *builtin_types = NULL, *dec_hook = NULL; int str_keys = false, strict = true, from_attributes = false; ConvertState state; char *kwlist[] = { "obj", "type", "strict", "from_attributes", "dec_hook", "builtin_types", "str_keys", NULL }; /* Parse arguments */ if (!PyArg_ParseTupleAndKeywords( args, kwargs, "OO|$ppOOp", kwlist, &obj, &pytype, &strict, &from_attributes, &dec_hook, &builtin_types, &str_keys )) { return NULL; } state.mod = msgspec_get_state(self); state.builtin_types = 0; state.from_attributes = from_attributes; state.strict = strict; if (strict) { state.str_keys = str_keys; if (ms_process_builtin_types(state.mod, builtin_types, &(state.builtin_types), NULL) < 0) { return NULL; } } else { state.str_keys = true; } if (dec_hook == Py_None) { dec_hook = NULL; } else if (dec_hook != NULL && !PyCallable_Check(dec_hook)) { PyErr_SetString(PyExc_TypeError, "dec_hook must be callable"); return NULL; } state.dec_hook = dec_hook; /* Avoid allocating a new TypeNode for struct types */ if (ms_is_struct_cls(pytype)) { PyObject *info = StructInfo_Convert(pytype); if (info == NULL) return NULL; bool array_like = ((StructMetaObject *)pytype)->array_like == OPT_TRUE; TypeNodeSimple type; type.types = array_like ? MS_TYPE_STRUCT_ARRAY : MS_TYPE_STRUCT; type.details[0].pointer = info; PyObject *out = convert(&state, obj, (TypeNode *)(&type), NULL); Py_DECREF(info); return out; } TypeNode *type = TypeNode_Convert(pytype); if (type == NULL) return NULL; PyObject *out = convert(&state, obj, type, NULL); TypeNode_Free(type); return out; } /************************************************************************* * Module Setup * *************************************************************************/ static struct PyMethodDef msgspec_methods[] = { { "replace", (PyCFunction) struct_replace, METH_FASTCALL | METH_KEYWORDS, struct_replace__doc__, }, { "asdict", (PyCFunction) struct_asdict, METH_FASTCALL, struct_asdict__doc__, }, { "astuple", (PyCFunction) struct_astuple, METH_FASTCALL, struct_astuple__doc__, }, { "defstruct", (PyCFunction) msgspec_defstruct, METH_VARARGS | METH_KEYWORDS, msgspec_defstruct__doc__, }, { "force_setattr", (PyCFunction) struct_force_setattr, METH_FASTCALL, struct_force_setattr__doc__, }, { "msgpack_encode", (PyCFunction) msgspec_msgpack_encode, METH_FASTCALL | METH_KEYWORDS, msgspec_msgpack_encode__doc__, }, { "msgpack_decode", (PyCFunction) msgspec_msgpack_decode, METH_FASTCALL | METH_KEYWORDS, msgspec_msgpack_decode__doc__, }, { "json_encode", (PyCFunction) msgspec_json_encode, METH_FASTCALL | METH_KEYWORDS, msgspec_json_encode__doc__, }, { "json_decode", (PyCFunction) msgspec_json_decode, METH_FASTCALL | METH_KEYWORDS, msgspec_json_decode__doc__, }, { "json_format", (PyCFunction) msgspec_json_format, METH_VARARGS | METH_KEYWORDS, msgspec_json_format__doc__, }, { "to_builtins", (PyCFunction) msgspec_to_builtins, METH_VARARGS | METH_KEYWORDS, msgspec_to_builtins__doc__, }, { "convert", (PyCFunction) msgspec_convert, METH_VARARGS | METH_KEYWORDS, msgspec_convert__doc__, }, {NULL, NULL} /* sentinel */ }; static int msgspec_clear(PyObject *m) { MsgspecState *st = msgspec_get_state(m); Py_CLEAR(st->MsgspecError); Py_CLEAR(st->EncodeError); Py_CLEAR(st->DecodeError); Py_CLEAR(st->ValidationError); Py_CLEAR(st->StructType); Py_CLEAR(st->EnumMetaType); Py_CLEAR(st->ABCMetaType); Py_CLEAR(st->_abc_init); Py_CLEAR(st->struct_lookup_cache); Py_CLEAR(st->str___weakref__); Py_CLEAR(st->str___dict__); Py_CLEAR(st->str___msgspec_cached_hash__); Py_CLEAR(st->str__value2member_map_); Py_CLEAR(st->str___msgspec_cache__); Py_CLEAR(st->str__value_); Py_CLEAR(st->str__missing_); Py_CLEAR(st->str_type); Py_CLEAR(st->str_enc_hook); Py_CLEAR(st->str_dec_hook); Py_CLEAR(st->str_ext_hook); Py_CLEAR(st->str_strict); Py_CLEAR(st->str_order); Py_CLEAR(st->str_utcoffset); Py_CLEAR(st->str___origin__); Py_CLEAR(st->str___args__); Py_CLEAR(st->str___metadata__); Py_CLEAR(st->str___total__); Py_CLEAR(st->str___required_keys__); Py_CLEAR(st->str__fields); Py_CLEAR(st->str__field_defaults); Py_CLEAR(st->str___post_init__); Py_CLEAR(st->str___dataclass_fields__); Py_CLEAR(st->str___attrs_attrs__); Py_CLEAR(st->str___supertype__); #if PY312_PLUS Py_CLEAR(st->str___value__); #endif Py_CLEAR(st->str___bound__); Py_CLEAR(st->str___constraints__); Py_CLEAR(st->str_int); Py_CLEAR(st->str_is_safe); Py_CLEAR(st->UUIDType); Py_CLEAR(st->uuid_safeuuid_unknown); Py_CLEAR(st->DecimalType); Py_CLEAR(st->typing_union); Py_CLEAR(st->typing_any); Py_CLEAR(st->typing_literal); Py_CLEAR(st->typing_classvar); Py_CLEAR(st->typing_typevar); Py_CLEAR(st->typing_final); Py_CLEAR(st->typing_generic); Py_CLEAR(st->typing_generic_alias); Py_CLEAR(st->typing_annotated_alias); Py_CLEAR(st->concrete_types); Py_CLEAR(st->get_type_hints); Py_CLEAR(st->get_class_annotations); Py_CLEAR(st->call_annotate_forwardref); Py_CLEAR(st->get_typeddict_info); Py_CLEAR(st->get_dataclass_info); Py_CLEAR(st->rebuild); Py_CLEAR(st->types_uniontype); Py_CLEAR(st->convert_generic_alias); #if PY312_PLUS Py_CLEAR(st->typing_typealiastype); #endif Py_CLEAR(st->astimezone); Py_CLEAR(st->re_compile); return 0; } static void msgspec_free(PyObject *m) { msgspec_clear(m); } static int msgspec_traverse(PyObject *m, visitproc visit, void *arg) { MsgspecState *st = msgspec_get_state(m); /* Clear the string cache every 10 major GC passes. * * The string cache can help improve performance in 2 different situations: * * - Calling untyped `json.decode` on a large message, where many keys are * repeated within the same message. * - Calling untyped `json.decode` in a hot loop on many messages that * share the same structure. * * In both cases, the string cache helps because common keys are more * likely to remain in cache. We do want to periodically clear the cache so * the allocator can free up old pages and reduce fragmentation, but we * want to do so as infrequently as possible. I've arbitrarily picked 10 * major GC passes here as a heuristic. * * With the current configuration, the string cache may consume up to 20 * KiB at a time, but that's with 100% of slots filled (unlikely due to * collisions). 50% filled is more likely, so 12 KiB max is a reasonable * estimate. */ st->gc_cycle++; if (st->gc_cycle == 10) { st->gc_cycle = 0; #ifndef Py_GIL_DISABLED string_cache_clear(); timezone_cache_clear(); #endif } Py_VISIT(st->MsgspecError); Py_VISIT(st->EncodeError); Py_VISIT(st->DecodeError); Py_VISIT(st->ValidationError); Py_VISIT(st->StructType); Py_VISIT(st->EnumMetaType); Py_VISIT(st->ABCMetaType); Py_VISIT(st->_abc_init); Py_VISIT(st->struct_lookup_cache); Py_VISIT(st->typing_union); Py_VISIT(st->typing_any); Py_VISIT(st->typing_literal); Py_VISIT(st->typing_classvar); Py_VISIT(st->typing_typevar); Py_VISIT(st->typing_final); Py_VISIT(st->typing_generic); Py_VISIT(st->typing_generic_alias); Py_VISIT(st->typing_annotated_alias); Py_VISIT(st->concrete_types); Py_VISIT(st->get_type_hints); Py_VISIT(st->get_class_annotations); Py_VISIT(st->call_annotate_forwardref); Py_VISIT(st->get_typeddict_info); Py_VISIT(st->get_dataclass_info); Py_VISIT(st->rebuild); Py_VISIT(st->types_uniontype); Py_VISIT(st->convert_generic_alias); #if PY312_PLUS Py_VISIT(st->typing_typealiastype); #endif Py_VISIT(st->UUIDType); Py_VISIT(st->uuid_safeuuid_unknown); Py_VISIT(st->DecimalType); Py_VISIT(st->astimezone); Py_VISIT(st->re_compile); return 0; } static struct PyModuleDef msgspecmodule = { PyModuleDef_HEAD_INIT, .m_name = "msgspec._core", .m_size = sizeof(MsgspecState), .m_methods = msgspec_methods, .m_traverse = msgspec_traverse, .m_clear = msgspec_clear, .m_free =(freefunc)msgspec_free }; PyMODINIT_FUNC PyInit__core(void) { PyObject *m, *temp_module, *temp_obj; MsgspecState *st; PyDateTime_IMPORT; m = PyState_FindModule(&msgspecmodule); if (m) { Py_INCREF(m); return m; } StructMetaType.tp_base = &PyType_Type; if (PyType_Ready(&NoDefault_Type) < 0) return NULL; if (PyType_Ready(&Unset_Type) < 0) return NULL; if (PyType_Ready(&Factory_Type) < 0) return NULL; if (PyType_Ready(&Field_Type) < 0) return NULL; if (PyType_Ready(&IntLookup_Type) < 0) return NULL; if (PyType_Ready(&StrLookup_Type) < 0) return NULL; if (PyType_Ready(&LiteralInfo_Type) < 0) return NULL; if (PyType_Ready(&TypedDictInfo_Type) < 0) return NULL; if (PyType_Ready(&DataclassInfo_Type) < 0) return NULL; if (PyType_Ready(&NamedTupleInfo_Type) < 0) return NULL; if (PyType_Ready(&StructInfo_Type) < 0) return NULL; if (PyType_Ready(&Meta_Type) < 0) return NULL; if (PyType_Ready(&StructMetaType) < 0) return NULL; if (PyType_Ready(&StructMixinType) < 0) return NULL; if (PyType_Ready(&StructConfig_Type) < 0) return NULL; if (PyType_Ready(&Encoder_Type) < 0) return NULL; if (PyType_Ready(&Decoder_Type) < 0) return NULL; if (PyType_Ready(&Ext_Type) < 0) return NULL; if (PyType_Ready(&Raw_Type) < 0) return NULL; if (PyType_Ready(&JSONEncoder_Type) < 0) return NULL; if (PyType_Ready(&JSONDecoder_Type) < 0) return NULL; /* Create the module */ m = PyModule_Create(&msgspecmodule); if (m == NULL) return NULL; /* Add types */ if (PyModule_AddObjectRef(m, "Factory", (PyObject *)&Factory_Type) < 0) return NULL; if (PyModule_AddObjectRef(m, "Field", (PyObject *)&Field_Type) < 0) return NULL; if (PyModule_AddObjectRef(m, "Meta", (PyObject *)&Meta_Type) < 0) return NULL; if (PyModule_AddObjectRef(m, "StructConfig", (PyObject *)&StructConfig_Type) < 0) return NULL; if (PyModule_AddObjectRef(m, "Ext", (PyObject *)&Ext_Type) < 0) return NULL; if (PyModule_AddObjectRef(m, "Raw", (PyObject *)&Raw_Type) < 0) return NULL; if (PyModule_AddObjectRef(m, "MsgpackEncoder", (PyObject *)&Encoder_Type) < 0) return NULL; if (PyModule_AddObjectRef(m, "MsgpackDecoder", (PyObject *)&Decoder_Type) < 0) return NULL; if (PyModule_AddObjectRef(m, "JSONEncoder", (PyObject *)&JSONEncoder_Type) < 0) return NULL; if (PyModule_AddObjectRef(m, "JSONDecoder", (PyObject *)&JSONDecoder_Type) < 0) return NULL; if (PyModule_AddObjectRef(m, "UnsetType", (PyObject *)&Unset_Type) < 0) return NULL; if (PyModule_AddObjectRef(m, "StructMeta", (PyObject *)&StructMetaType) < 0) { return NULL; } st = msgspec_get_state(m); /* Initialize GC counter */ st->gc_cycle = 0; /* Add NODEFAULT singleton */ if (PyModule_AddObjectRef(m, "NODEFAULT", NODEFAULT) < 0) return NULL; /* Add UNSET singleton */ if (PyModule_AddObjectRef(m, "UNSET", UNSET) < 0) return NULL; /* Initialize the exceptions. */ st->MsgspecError = PyErr_NewExceptionWithDoc( "msgspec.MsgspecError", "Base class for all Msgspec exceptions", NULL, NULL ); if (st->MsgspecError == NULL) return NULL; st->EncodeError = PyErr_NewExceptionWithDoc( "msgspec.EncodeError", "An error occurred while encoding an object", st->MsgspecError, NULL ); if (st->EncodeError == NULL) return NULL; temp_obj = PyTuple_Pack(2, st->MsgspecError, PyExc_ValueError); if (temp_obj == NULL) return NULL; st->DecodeError = PyErr_NewExceptionWithDoc( "msgspec.DecodeError", "An error occurred while decoding an object", temp_obj, NULL ); Py_XDECREF(temp_obj); if (st->DecodeError == NULL) return NULL; st->ValidationError = PyErr_NewExceptionWithDoc( "msgspec.ValidationError", "The message didn't match the expected schema", st->DecodeError, NULL ); if (st->ValidationError == NULL) return NULL; if (PyModule_AddObjectRef(m, "MsgspecError", st->MsgspecError) < 0) return NULL; if (PyModule_AddObjectRef(m, "EncodeError", st->EncodeError) < 0) return NULL; if (PyModule_AddObjectRef(m, "DecodeError", st->DecodeError) < 0) return NULL; if (PyModule_AddObjectRef(m, "ValidationError", st->ValidationError) < 0) return NULL; /* Initialize the struct_lookup_cache */ st->struct_lookup_cache = PyDict_New(); if (PyModule_AddObjectRef(m, "_struct_lookup_cache", st->struct_lookup_cache) < 0) return NULL; #define SET_REF(attr, name) \ do { \ st->attr = PyObject_GetAttrString(temp_module, name); \ if (st->attr == NULL) return NULL; \ } while (0) /* Get all imports from the typing module */ temp_module = PyImport_ImportModule("typing"); if (temp_module == NULL) return NULL; SET_REF(typing_union, "Union"); SET_REF(typing_any, "Any"); SET_REF(typing_literal, "Literal"); SET_REF(typing_classvar, "ClassVar"); SET_REF(typing_typevar, "TypeVar"); SET_REF(typing_final, "Final"); SET_REF(typing_generic, "Generic"); SET_REF(typing_generic_alias, "_GenericAlias"); #if PY312_PLUS SET_REF(typing_typealiastype, "TypeAliasType"); #endif Py_DECREF(temp_module); temp_module = PyImport_ImportModule("msgspec._utils"); if (temp_module == NULL) return NULL; SET_REF(concrete_types, "_CONCRETE_TYPES"); SET_REF(get_type_hints, "get_type_hints"); SET_REF(get_class_annotations, "get_class_annotations"); SET_REF(call_annotate_forwardref, "call_annotate_forwardref"); SET_REF(get_typeddict_info, "get_typeddict_info"); SET_REF(get_dataclass_info, "get_dataclass_info"); SET_REF(typing_annotated_alias, "_AnnotatedAlias"); SET_REF(rebuild, "rebuild"); SET_REF(convert_generic_alias, "convert_generic_alias"); Py_DECREF(temp_module); temp_module = PyImport_ImportModule("types"); if (temp_module == NULL) return NULL; SET_REF(types_uniontype, "UnionType"); Py_DECREF(temp_module); /* Get the EnumMeta type */ temp_module = PyImport_ImportModule("enum"); if (temp_module == NULL) return NULL; temp_obj = PyObject_GetAttrString(temp_module, "EnumMeta"); Py_DECREF(temp_module); if (temp_obj == NULL) return NULL; if (!PyType_Check(temp_obj)) { Py_DECREF(temp_obj); PyErr_SetString(PyExc_TypeError, "enum.EnumMeta should be a type"); return NULL; } st->EnumMetaType = (PyTypeObject *)temp_obj; /* Get the abc.ABCMeta type and _abc_init helper */ temp_module = PyImport_ImportModule("abc"); if (temp_module == NULL) return NULL; temp_obj = PyObject_GetAttrString(temp_module, "ABCMeta"); if (temp_obj == NULL) { Py_DECREF(temp_module); return NULL; } if (!PyType_Check(temp_obj)) { Py_DECREF(temp_obj); Py_DECREF(temp_module); PyErr_SetString(PyExc_TypeError, "abc.ABCMeta should be a type"); return NULL; } st->ABCMetaType = (PyTypeObject *)temp_obj; temp_obj = PyObject_GetAttrString(temp_module, "_abc_init"); Py_DECREF(temp_module); if (temp_obj == NULL) return NULL; st->_abc_init = temp_obj; /* Get the datetime.datetime.astimezone method */ temp_module = PyImport_ImportModule("datetime"); if (temp_module == NULL) return NULL; temp_obj = PyObject_GetAttrString(temp_module, "datetime"); Py_DECREF(temp_module); if (temp_obj == NULL) return NULL; st->astimezone = PyObject_GetAttrString(temp_obj, "astimezone"); Py_DECREF(temp_obj); if (st->astimezone == NULL) return NULL; /* uuid module imports */ temp_module = PyImport_ImportModule("uuid"); if (temp_module == NULL) return NULL; st->UUIDType = PyObject_GetAttrString(temp_module, "UUID"); if (st->UUIDType == NULL) return NULL; temp_obj = PyObject_GetAttrString(temp_module, "SafeUUID"); if (temp_obj == NULL) return NULL; st->uuid_safeuuid_unknown = PyObject_GetAttrString(temp_obj, "unknown"); Py_DECREF(temp_obj); if (st->uuid_safeuuid_unknown == NULL) return NULL; /* decimal module imports */ temp_module = PyImport_ImportModule("decimal"); if (temp_module == NULL) return NULL; st->DecimalType = PyObject_GetAttrString(temp_module, "Decimal"); if (st->DecimalType == NULL) return NULL; /* Get the re.compile function */ temp_module = PyImport_ImportModule("re"); if (temp_module == NULL) return NULL; st->re_compile = PyObject_GetAttrString(temp_module, "compile"); Py_DECREF(temp_module); if (st->re_compile == NULL) return NULL; /* Initialize cached constant strings */ #define CACHED_STRING(attr, str) \ if ((st->attr = PyUnicode_InternFromString(str)) == NULL) return NULL CACHED_STRING(str___weakref__, "__weakref__"); CACHED_STRING(str___dict__, "__dict__"); CACHED_STRING(str___msgspec_cached_hash__, "__msgspec_cached_hash__"); CACHED_STRING(str__value2member_map_, "_value2member_map_"); CACHED_STRING(str___msgspec_cache__, "__msgspec_cache__"); CACHED_STRING(str__value_, "_value_"); CACHED_STRING(str__missing_, "_missing_"); CACHED_STRING(str_type, "type"); CACHED_STRING(str_enc_hook, "enc_hook"); CACHED_STRING(str_dec_hook, "dec_hook"); CACHED_STRING(str_ext_hook, "ext_hook"); CACHED_STRING(str_strict, "strict"); CACHED_STRING(str_order, "order"); CACHED_STRING(str_utcoffset, "utcoffset"); CACHED_STRING(str___origin__, "__origin__"); CACHED_STRING(str___args__, "__args__"); CACHED_STRING(str___metadata__, "__metadata__"); CACHED_STRING(str___total__, "__total__"); CACHED_STRING(str___required_keys__, "__required_keys__"); CACHED_STRING(str__fields, "_fields"); CACHED_STRING(str__field_defaults, "_field_defaults"); CACHED_STRING(str___post_init__, "__post_init__"); CACHED_STRING(str___dataclass_fields__, "__dataclass_fields__"); CACHED_STRING(str___attrs_attrs__, "__attrs_attrs__"); CACHED_STRING(str___supertype__, "__supertype__"); #if PY312_PLUS CACHED_STRING(str___value__, "__value__"); #endif CACHED_STRING(str___bound__, "__bound__"); CACHED_STRING(str___constraints__, "__constraints__"); CACHED_STRING(str_int, "int"); CACHED_STRING(str_is_safe, "is_safe"); /* Initialize the Struct Type */ PyState_AddModule(m, &msgspecmodule); st->StructType = PyObject_CallFunction( (PyObject *)&StructMetaType, "s(O){ssss}", "Struct", &StructMixinType, "__module__", "msgspec", "__doc__", Struct__doc__ ); if (PyModule_AddObjectRef(m, "Struct", st->StructType) < 0) return NULL; #ifdef Py_GIL_DISABLED PyUnstable_Module_SetGIL(m, Py_MOD_GIL_NOT_USED); #endif return m; } python-msgspec-0.22.0/src/msgspec/_json_schema.py000066400000000000000000000434641525673062400220320ustar00rootroot00000000000000from __future__ import annotations import re import textwrap from collections.abc import Callable, Iterable from typing import Any, Final from . import inspect as mi, to_builtins __all__ = ("schema", "schema_components") _REF_TEMPLATE: Final = "#/$defs/{name}" def schema( type: Any, *, schema_hook: Callable[[type], dict[str, Any]] | None = None, ref_template: str = _REF_TEMPLATE, ) -> dict[str, Any]: """Generate a JSON Schema for a given type. Any schemas for (potentially) shared components are extracted and stored in a top-level ``"$defs"`` field. If you want to generate schemas for multiple types, or to have more control over the generated schema you may want to use ``schema_components`` instead. Parameters ---------- type : type The type to generate the schema for. schema_hook : callable, optional An optional callback to use for generating JSON schemas of custom types. Will be called with the custom type, and should return a dict representation of the JSON schema for that type. ref_template : str, optional A template to use when generating ``"$ref"`` fields. This template is formatted with the type name as ``template.format(name=name)``. This can be useful if you intend to store the ``components`` mapping somewhere other than a top-level ``"$defs"`` field. For example, you might use ``ref_template="#/components/{name}"`` if generating an OpenAPI schema. Returns ------- schema : dict The generated JSON Schema. See Also -------- schema_components """ (out,), components = schema_components( (type,), schema_hook=schema_hook, ref_template=ref_template, ) if components: out["$defs"] = components return out def schema_components( types: Iterable[Any], *, schema_hook: Callable[[type], dict[str, Any]] | None = None, ref_template: str = _REF_TEMPLATE, ) -> tuple[tuple[dict[str, Any], ...], dict[str, Any]]: """Generate JSON Schemas for one or more types. Any schemas for (potentially) shared components are extracted and returned in a separate ``components`` dict. Parameters ---------- types : Iterable[type] An iterable of one or more types to generate schemas for. schema_hook : callable, optional An optional callback to use for generating JSON schemas of custom types. Will be called with the custom type, and should return a dict representation of the JSON schema for that type. ref_template : str, optional A template to use when generating ``"$ref"`` fields. This template is formatted with the type name as ``template.format(name=name)``. This can be useful if you intend to store the ``components`` mapping somewhere other than a top-level ``"$defs"`` field. For example, you might use ``ref_template="#/components/{name}"`` if generating an OpenAPI schema. Returns ------- schemas : tuple[dict] A tuple of JSON Schemas, one for each type in ``types``. components : dict A mapping of name to schema for any shared components used by ``schemas``. See Also -------- schema """ type_infos = mi.multi_type_info(types) component_types = _collect_component_types(type_infos) name_map = _build_name_map(component_types) gen = _SchemaGenerator(name_map, schema_hook, ref_template) schemas = tuple(gen.to_schema(t) for t in type_infos) components = { name_map[cls]: gen.to_schema(t, False) for cls, t in component_types.items() } return schemas, components def _collect_component_types(type_infos: Iterable[mi.Type]) -> dict[Any, mi.Type]: """Find all types in the type tree that are "nameable" and worthy of being extracted out into a shared top-level components mapping. Currently this looks for Struct, Dataclass, NamedTuple, TypedDict, and Enum types. """ components = {} def collect(t): if isinstance( t, (mi.StructType, mi.TypedDictType, mi.DataclassType, mi.NamedTupleType) ): if t.cls not in components: components[t.cls] = t for f in t.fields: collect(f.type) elif isinstance(t, mi.EnumType): components[t.cls] = t elif isinstance(t, mi.Metadata): collect(t.type) elif isinstance(t, mi.CollectionType): collect(t.item_type) elif isinstance(t, mi.TupleType): for st in t.item_types: collect(st) elif isinstance(t, (mi.DictType, mi.FrozenDictType)): collect(t.key_type) collect(t.value_type) elif isinstance(t, mi.UnionType): for st in t.types: collect(st) for t in type_infos: collect(t) return components def _type_repr(obj): return obj.__name__ if isinstance(obj, type) else repr(obj) def _get_class_name(cls: Any) -> str: if hasattr(cls, "__origin__"): name = cls.__origin__.__name__ args = ", ".join(_type_repr(a) for a in cls.__args__) return f"{name}[{args}]" return cls.__name__ def _get_doc(t: mi.Type) -> str: assert hasattr(t, "cls") cls = getattr(t.cls, "__origin__", t.cls) doc = getattr(cls, "__doc__", "") if not doc: return "" doc = textwrap.dedent(doc).strip("\r\n") if isinstance(t, mi.EnumType): if doc == "An enumeration.": return "" elif isinstance(t, (mi.NamedTupleType, mi.DataclassType)): if doc.startswith(f"{cls.__name__}(") and doc.endswith(")"): return "" return doc def _build_name_map(component_types: dict[Any, mi.Type]) -> dict[Any, str]: """A mapping from nameable subcomponents to a generated name. The generated name is usually a normalized version of the class name. In the case of conflicts, the name will be expanded to also include the full import path. """ def normalize(name): return re.sub(r"[^a-zA-Z0-9.\-_]", "_", name) def fullname(cls): return normalize(f"{cls.__module__}.{cls.__qualname__}") conflicts = set() names: dict[str, Any] = {} for cls in component_types: name = normalize(_get_class_name(cls)) if name in names: old = names.pop(name) conflicts.add(name) names[fullname(old)] = old if name in conflicts: names[fullname(cls)] = cls else: names[name] = cls return {v: k for k, v in names.items()} class _SchemaGenerator: def __init__( self, name_map: dict[Any, str], schema_hook: Callable[[type], dict[str, Any]] | None = None, ref_template: str = "#/$defs/{name}", ): self.name_map = name_map self.schema_hook = schema_hook self.ref_template = ref_template def to_schema(self, t: mi.Type, check_ref: bool = True) -> dict[str, Any]: """Converts a Type to a json-schema.""" schema: dict[str, Any] = {} while isinstance(t, mi.Metadata): schema = mi._merge_json(schema, t.extra_json_schema) t = t.type if check_ref and hasattr(t, "cls"): if name := self.name_map.get(t.cls): schema["$ref"] = self.ref_template.format(name=name) return schema if isinstance(t, (mi.AnyType, mi.RawType)): pass elif isinstance(t, mi.NoneType): schema["type"] = "null" elif isinstance(t, mi.BoolType): schema["type"] = "boolean" elif isinstance(t, (mi.IntType, mi.FloatType)): schema["type"] = "integer" if isinstance(t, mi.IntType) else "number" if t.ge is not None: schema["minimum"] = t.ge if t.gt is not None: schema["exclusiveMinimum"] = t.gt if t.le is not None: schema["maximum"] = t.le if t.lt is not None: schema["exclusiveMaximum"] = t.lt if t.multiple_of is not None: schema["multipleOf"] = t.multiple_of elif isinstance(t, mi.StrType): schema["type"] = "string" if t.max_length is not None: schema["maxLength"] = t.max_length if t.min_length is not None: schema["minLength"] = t.min_length if t.pattern is not None: schema["pattern"] = t.pattern elif isinstance(t, (mi.BytesType, mi.ByteArrayType, mi.MemoryViewType)): schema["type"] = "string" schema["contentEncoding"] = "base64" if t.max_length is not None: schema["maxLength"] = 4 * ((t.max_length + 2) // 3) if t.min_length is not None: schema["minLength"] = 4 * ((t.min_length + 2) // 3) elif isinstance(t, mi.DateTimeType): schema["type"] = "string" if t.tz is True: schema["format"] = "date-time" elif isinstance(t, mi.TimeType): schema["type"] = "string" if t.tz is True: schema["format"] = "time" elif t.tz is False: schema["format"] = "partial-time" elif isinstance(t, mi.DateType): schema["type"] = "string" schema["format"] = "date" elif isinstance(t, mi.TimeDeltaType): schema["type"] = "string" schema["format"] = "duration" elif isinstance(t, mi.UUIDType): schema["type"] = "string" schema["format"] = "uuid" elif isinstance(t, mi.DecimalType): schema["type"] = "string" schema["format"] = "decimal" elif isinstance(t, mi.CollectionType): schema["type"] = "array" if not isinstance(t.item_type, mi.AnyType): schema["items"] = self.to_schema(t.item_type) if t.max_length is not None: schema["maxItems"] = t.max_length if t.min_length is not None: schema["minItems"] = t.min_length if isinstance(t, (mi.SetType, mi.FrozenSetType)): schema["uniqueItems"] = True elif isinstance(t, mi.TupleType): schema["type"] = "array" schema["minItems"] = schema["maxItems"] = len(t.item_types) if t.item_types: schema["prefixItems"] = [self.to_schema(i) for i in t.item_types] schema["items"] = False elif isinstance(t, (mi.DictType, mi.FrozenDictType)): schema["type"] = "object" # If keys have schema metadata or constraints, include them as propertyNames key_type = t.key_type while isinstance(key_type, mi.Metadata): key_type = key_type.type if isinstance(key_type, mi.StrType): property_names = self.to_schema(t.key_type) # Object property names are always strings, so omit the redundant type property_names.pop("type", None) if property_names: schema["propertyNames"] = property_names if not isinstance(t.value_type, mi.AnyType): schema["additionalProperties"] = self.to_schema(t.value_type) if t.max_length is not None: schema["maxProperties"] = t.max_length if t.min_length is not None: schema["minProperties"] = t.min_length elif isinstance(t, mi.UnionType): structs = {} other = [] none_member = None tag_field = None for subtype in t.types: real_type = subtype while isinstance(real_type, mi.Metadata): real_type = real_type.type if isinstance(real_type, mi.StructType) and not real_type.array_like: tag_field = real_type.tag_field structs[real_type.tag] = real_type elif isinstance(real_type, mi.NoneType): none_member = subtype else: other.append(subtype) options = [self.to_schema(a) for a in other] if len(structs) >= 2: mapping = { k: self.ref_template.format(name=self.name_map[v.cls]) for k, v in structs.items() } struct_schema = { "anyOf": [self.to_schema(v) for v in structs.values()], "discriminator": {"propertyName": tag_field, "mapping": mapping}, } if options: options.append(struct_schema) if none_member is not None: options.append(self.to_schema(none_member)) schema["anyOf"] = options elif none_member is not None: schema["anyOf"] = [struct_schema, self.to_schema(none_member)] else: schema.update(struct_schema) elif len(structs) == 1: _, subtype = structs.popitem() options.append(self.to_schema(subtype)) if none_member is not None: options.append(self.to_schema(none_member)) schema["anyOf"] = options else: if none_member is not None: options.append(self.to_schema(none_member)) schema["anyOf"] = options elif isinstance(t, mi.LiteralType): # `t.values` may mix types (e.g. `Literal[1, None]`), which a plain # `sorted` can't order; reuse the same type-aware sort as # `inspect.type_info` so the two entry points agree and neither # crashes. schema["enum"] = list(mi._sort_literal_args(t.values)) elif isinstance(t, mi.EnumType): schema.setdefault("title", t.cls.__name__) if doc := _get_doc(t): schema.setdefault("description", doc) schema["enum"] = sorted(e.value for e in t.cls) elif isinstance(t, mi.StructType): schema.setdefault("title", _get_class_name(t.cls)) if doc := _get_doc(t): schema.setdefault("description", doc) required = [] names = [] fields = [] if t.tag_field is not None: required.append(t.tag_field) names.append(t.tag_field) fields.append({"enum": [t.tag]}) for field in t.fields: field_schema = self.to_schema(field.type) if field.required: required.append(field.encode_name) elif field.default is not mi.NODEFAULT: field_schema["default"] = to_builtins(field.default, str_keys=True) elif field.default_factory in (list, dict, set, bytearray): field_schema["default"] = to_builtins( field.default_factory(), str_keys=True ) names.append(field.encode_name) fields.append(field_schema) if t.array_like: n_trailing_defaults = 0 for f in reversed(t.fields): if f.required: break n_trailing_defaults += 1 schema["type"] = "array" schema["prefixItems"] = fields schema["minItems"] = len(fields) - n_trailing_defaults if t.forbid_unknown_fields: schema["maxItems"] = len(fields) else: schema["type"] = "object" schema["properties"] = dict(zip(names, fields)) schema["required"] = required if t.forbid_unknown_fields: schema["additionalProperties"] = False elif isinstance(t, (mi.TypedDictType, mi.DataclassType, mi.NamedTupleType)): schema.setdefault("title", _get_class_name(t.cls)) if doc := _get_doc(t): schema.setdefault("description", doc) names = [] fields = [] required = [] for field in t.fields: field_schema = self.to_schema(field.type) if field.required: required.append(field.encode_name) elif field.default is not mi.NODEFAULT: field_schema["default"] = to_builtins(field.default, str_keys=True) names.append(field.encode_name) fields.append(field_schema) if isinstance(t, mi.NamedTupleType): schema["type"] = "array" schema["prefixItems"] = fields schema["minItems"] = len(required) schema["maxItems"] = len(fields) else: schema["type"] = "object" schema["properties"] = dict(zip(names, fields)) schema["required"] = required elif isinstance(t, mi.ExtType): raise TypeError("json-schema doesn't support msgpack Ext types") elif isinstance(t, mi.CustomType): if self.schema_hook: try: schema = mi._merge_json(self.schema_hook(t.cls), schema) except NotImplementedError: pass if not schema: raise TypeError( "Generating JSON schema for custom types requires either:\n" "- specifying a `schema_hook`\n" "- annotating the type with `Meta(extra_json_schema=...)`\n" "\n" f"type {t.cls!r} is not supported" ) else: # This should be unreachable raise TypeError(f"json-schema doesn't support type {t!r}") return schema python-msgspec-0.22.0/src/msgspec/_typing_utils.py000066400000000000000000000023371525673062400222650ustar00rootroot00000000000000from __future__ import annotations from . import StructMeta def is_struct(obj: object) -> bool: """Check whether ``obj`` is a `msgspec.Struct`-like instance. Parameters ---------- obj: Object to check. Returns ------- bool `True` if ``obj`` is an instance of a class whose metaclass is `msgspec.StructMeta` (or a subclass of it), and `False` otherwise. Static type checkers treat a successful ``is_struct(obj)`` check as narrowing ``obj`` to `msgspec.Struct` within the true branch, even if the runtime class does not literally inherit `msgspec.Struct`. """ return isinstance(type(obj), StructMeta) def is_struct_type(tp: object) -> bool: """Check whether ``tp`` is a `msgspec.Struct`-like class. Parameters ---------- tp: Object to check, typically a class object. Returns ------- bool `True` if ``tp`` is a class whose metaclass is `msgspec.StructMeta` (or a subclass of it), and `False` otherwise. Static type checkers treat a successful ``is_struct_type(tp)`` check as narrowing ``tp`` to `type[msgspec.Struct]` within the true branch. """ return isinstance(tp, StructMeta) python-msgspec-0.22.0/src/msgspec/_typing_utils.pyi000066400000000000000000000002521525673062400224300ustar00rootroot00000000000000from typing_extensions import TypeIs from . import Struct def is_struct(obj: object) -> TypeIs[Struct]: ... def is_struct_type(tp: object) -> TypeIs[type[Struct]]: ... python-msgspec-0.22.0/src/msgspec/_utils.py000066400000000000000000000334461525673062400207000ustar00rootroot00000000000000# type: ignore import collections import sys import types import typing from typing import _AnnotatedAlias, _GenericAlias # noqa: F401 try: from typing_extensions import get_type_hints as _get_type_hints except Exception: from typing import get_type_hints as _get_type_hints try: from typing_extensions import NotRequired, Required except Exception: try: from typing import NotRequired, Required except Exception: Required = NotRequired = None def get_type_hints(obj): return _get_type_hints(obj, include_extras=True) PY_312PLUS = sys.version_info >= (3, 12) # The `is_class` argument was new in 3.11, but was backported to 3.9 and 3.10. # It's _likely_ to be available for 3.9/3.10, but may not be. Easiest way to # check is to try it and see. This check can be removed when we drop support # for Python 3.10. try: typing.ForwardRef("Foo", is_class=True) except TypeError: def _forward_ref(value): return typing.ForwardRef(value, is_argument=False) else: def _forward_ref(value): return typing.ForwardRef(value, is_argument=False, is_class=True) # Python 3.13 adds a new mandatory type_params kwarg to _eval_type if sys.version_info >= (3, 13): def _eval_type(t, globalns, localns): return typing._eval_type(t, globalns, localns, ()) else: _eval_type = typing._eval_type if sys.version_info >= (3, 14): from annotationlib import ( Format as _AnnotationFormat, call_annotate_function as _call_annotate_function, get_annotations as _get_class_annotations, ) def call_annotate_forwardref(annotate): """Evaluate a class annotate function without requiring names to exist. Metaclasses should use ``Format.FORWARDREF`` (via ``call_annotate_function``, which implements the format when the annotate function only supports ``VALUE``). """ return _call_annotate_function(annotate, _AnnotationFormat.FORWARDREF) else: def _get_class_annotations(cls): return cls.__dict__.get("__annotations__", {}) def call_annotate_forwardref(annotate): return annotate(1) # annotationlib.Format.VALUE def _apply_params(obj, mapping): if isinstance(obj, typing.TypeVar): return mapping.get(obj, obj) try: parameters = tuple(obj.__parameters__) except Exception: # Not parameterized or __parameters__ is invalid, ignore return obj if not parameters: # Not parametrized return obj # Parametrized args = tuple(mapping.get(p, p) for p in parameters) return obj[args] def _get_class_mro_and_typevar_mappings(obj): mapping = {} # in Python 3.10 a natively produced 'types.GenericAlias' (e.g. 'list[int]', or the # 'Base[int]' produced when a 'Generic' subclass inherits a builtin's # '__class_getitem__') satisfies 'isinstance(_, type)', unlike on 3.11+. we still # want to treat those as parametrised aliases, not bare classes if isinstance(obj, type) and not isinstance(obj, types.GenericAlias): cls = obj else: cls = obj.__origin__ def inner(c, scope): if isinstance(c, type) and not isinstance(c, types.GenericAlias): cls = c new_scope = {} else: cls = typing.get_origin(c) if cls in (None, object, typing.Generic) or cls in mapping: return if hasattr(cls, "__parameters__"): # 'cls' carries its own type vars. This covers both ordinary # 'typing._GenericAlias' bases and the 'types.GenericAlias' that # get produced when a user-defined 'Generic' subclass inherits a # builtin's '__class_getitem__' (e.g. 'class Base(Mapping[str, T])', # whose 'Base[...]' is a 'types.GenericAlias'). Map cls's own # type vars onto the resolved args, applying '_apply_params' so any # outer bindings in 'scope' (e.g. 'U -> int') are propagated. params = cls.__parameters__ args = tuple(_apply_params(a, scope) for a in typing.get_args(c)) assert len(params) == len(args) new_scope = dict(zip(params, args)) else: # a true built-in generic (e.g. 'collections.abc.Mapping[str, T]') # whose '__origin__' has no '__parameters__'; the unresolved type # vars and args live on the alias itself, not the origin. new_scope = dict(zip(c.__parameters__, typing.get_args(c))) mapping[cls] = new_scope if issubclass(cls, typing.Generic): bases = getattr(cls, "__orig_bases__", cls.__bases__) for b in bases: inner(b, new_scope) inner(obj, {}) return cls.__mro__, mapping def get_class_annotations(obj): """Get the annotations for a class. This is similar to ``typing.get_type_hints``, except: - We maintain it - It leaves extras like ``Annotated``/``ClassVar`` alone - It resolves any parametrized generics in the class mro. The returned mapping may still include ``TypeVar`` values, but those should be treated as their unparametrized variants (i.e. equal to ``Any`` for the common case). Note that this function doesn't check that Generic types are being used properly - invalid uses of `Generic` may slip through without complaint. The assumption here is that the user is making use of a static analysis tool like ``mypy``/``pyright`` already, which would catch misuse of these APIs. """ hints = {} mro, typevar_mappings = _get_class_mro_and_typevar_mappings(obj) for cls in mro: if cls in (typing.Generic, object): continue mapping = typevar_mappings.get(cls) cls_locals = dict(vars(cls)) if PY_312PLUS: # resolve type parameters (e.g. class Foo[T]: pass) cls_locals.update({p.__name__: p for p in cls.__type_params__}) try: cls_module = cls.__module__ except AttributeError: cls_globals = {} else: cls_globals = getattr(sys.modules.get(cls_module, None), "__dict__", {}) ann = _get_class_annotations(cls) for name, value in ann.items(): if name in hints: continue if isinstance(value, str): value = _forward_ref(value) value = _eval_type(value, cls_locals, cls_globals) if mapping is not None: value = _apply_params(value, mapping) if value is None: value = type(None) hints[name] = value return hints # A mapping from a type annotation (or annotation __origin__) to the concrete # python type that msgspec will use when decoding. THIS IS PRIVATE FOR A # REASON. DON'T MUCK WITH THIS. _CONCRETE_TYPES = { list: list, tuple: tuple, set: set, frozenset: frozenset, dict: dict, typing.List: list, typing.Tuple: tuple, typing.Set: set, typing.FrozenSet: frozenset, typing.Dict: dict, typing.Collection: list, typing.MutableSequence: list, typing.Sequence: list, typing.MutableMapping: dict, typing.Mapping: dict, typing.MutableSet: set, typing.AbstractSet: set, collections.abc.Collection: list, collections.abc.MutableSequence: list, collections.abc.Sequence: list, collections.abc.MutableSet: set, collections.abc.Set: set, collections.abc.MutableMapping: dict, collections.abc.Mapping: dict, } if sys.version_info >= (3, 15): _CONCRETE_TYPES.update({frozendict: frozendict}) # noqa: F821 def get_typeddict_info(obj): if isinstance(obj, type): cls = obj else: cls = obj.__origin__ raw_hints = get_class_annotations(obj) if hasattr(cls, "__required_keys__"): required = set(cls.__required_keys__) elif cls.__total__: required = set(raw_hints) else: required = set() # Both `typing.TypedDict` and `typing_extensions.TypedDict` have a bug # where `Required`/`NotRequired` aren't properly detected at runtime when # `__future__.annotations` is enabled, meaning the `__required_keys__` # isn't correct. This code block works around this issue by amending the # set of required keys as needed, while also stripping off any # `Required`/`NotRequired` wrappers. hints = {} for k, v in raw_hints.items(): origin = getattr(v, "__origin__", False) if origin is Required: required.add(k) hints[k] = v.__args__[0] elif origin is NotRequired: required.discard(k) hints[k] = v.__args__[0] else: hints[k] = v # This can happen if there is a bug in the TypedDict implementation; # such a bug was present in Python 3.14. if not all(k in hints for k in required): raise RuntimeError( f"Required set {required} contains keys that are no in hints: {hints.keys()}" ) return hints, required def get_dataclass_info(obj): if isinstance(obj, type): cls = obj else: cls = obj.__origin__ hints = get_class_annotations(obj) required = [] optional = [] defaults = [] if hasattr(cls, "__dataclass_fields__"): from dataclasses import _FIELD, _FIELD_INITVAR, MISSING for field in cls.__dataclass_fields__.values(): if field._field_type is not _FIELD: if field._field_type is _FIELD_INITVAR: raise TypeError( "dataclasses with `InitVar` fields are not supported" ) continue name = field.name typ = hints[name] if field.default is not MISSING: defaults.append(field.default) optional.append((name, typ, False)) elif field.default_factory is not MISSING: defaults.append(field.default_factory) optional.append((name, typ, True)) else: required.append((name, typ, False)) required.extend(optional) pre_init = None post_init = getattr(cls, "__post_init__", None) else: from attrs import NOTHING, Factory fields_with_validators = [] for field in cls.__attrs_attrs__: name = field.name typ = hints[name] default = field.default if default is not NOTHING: if isinstance(default, Factory): if default.takes_self: raise NotImplementedError( "Support for default factories with `takes_self=True` " "is not implemented. File a GitHub issue if you need " "this feature!" ) defaults.append(default.factory) optional.append((name, typ, True)) else: defaults.append(default) optional.append((name, typ, False)) else: required.append((name, typ, False)) if field.validator is not None: fields_with_validators.append(field) required.extend(optional) pre_init = getattr(cls, "__attrs_pre_init__", None) post_init = getattr(cls, "__attrs_post_init__", None) if fields_with_validators: post_init = _wrap_attrs_validators(fields_with_validators, post_init) return cls, tuple(required), tuple(defaults), pre_init, post_init def _wrap_attrs_validators(fields, post_init): def inner(obj): for field in fields: field.validator(obj, field, getattr(obj, field.name)) if post_init is not None: post_init(obj) return inner def rebuild(cls, kwargs): """Used to unpickle Structs with keyword-only fields""" return cls(**kwargs) def convert_generic_alias(origin, args): # subscribed typing._GenericAlias instances are cached within the typing module # we make use of this fact, by storing a __msgspec_cache__ attribute on the # subscribed instance. only subscribed types are cached, so # 'typing._GenericAlias(list, int) is typing._GenericAlias(list, int)' would be # false. # to achieve the same behaviour when re-creating a typing._GenericAlias from a # types.GenericAlias, we first construct a temporary *unbound* # typing._GenericAlias, on which we then call __getattr__. effectively doing # typing._GenericAlias(list, T)[int], for which # 'typing._GenericAlias(list, T)[int] is typing._GenericAlias(list, T)[int]' # holds true try: params = origin.__parameters__ except AttributeError: if not isinstance(origin, type): # a special form such as 'typing.Literal', whose args are values rather than # type parameters. Ordinary subscription yields the canonical, interned # alias of the right subclass (e.g. 'typing.Literal[...]' -> '_LiteralGenericAlias'). return origin[args] # a non-generic class with type arguments. only reachable for e.g. # manually-built 'types.GenericAlias' instances and is probably nonsense or at # least not somthing we can meaningfully represent, so complain about it here, # rather than silently dropping the arguments. raise TypeError(f"{origin.__name__!r} is not a generic type") # a regularly-parametrised generic. Create a new typing._GenericAlias with the # origin's unbound type params (e.g. for a 'Mapping[str, int]' this is a # '_GenericAlias(Mapping, (~K, ~V))'), then bind it to the concrete args by # subscripting with the args *tuple* (i.e. 'alias[(int, str)]', not # 'alias[int, str]'), so generics with more than one type var work alias = _GenericAlias(origin, params) return alias[args] python-msgspec-0.22.0/src/msgspec/atof.h000066400000000000000000000265671525673062400201370ustar00rootroot00000000000000/* This file implements the core float parsing routines used in msgspec. * * It contains an implementation of the Eisel-Lemire algorithm, as described in * https://nigeltao.github.io/blog/2020/eisel-lemire.html. Much of the * implementation is based on the one available in Wuffs * (https://github.com/google/wuffs/blob/c104ae296c3557f946e4bd5ee8b85511f12c141c/internal/cgen/base/floatconv-submodule-code.c#L989). * * It also contains a fallback implementation using a High Precision Double * (HPD). This method is based on the following blogpost by Nigel Tao ( * https://nigeltao.github.io/blog/2020/parse-number-f64-simple.html), as well * as the implementation in Wuffs * (https://github.com/google/wuffs/blob/c104ae296c3557f946e4bd5ee8b85511f12c141c/internal/cgen/base/floatconv-submodule-code.c#L1307-L1308). * * The Wuffs license is copied below: * * """ Copyright 2020 The Wuffs Authors. * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy * of the License at * * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations * under the License. """ * * */ #ifndef MS_ATOF_H #define MS_ATOF_H #include #include #if defined(_MSC_VER) #include #endif #include "atof_consts.h" typedef struct ms_uint128 { uint64_t lo; uint64_t hi; } ms_uint128; static inline ms_uint128 ms_mulu64(uint64_t x, uint64_t y) { #if defined(__SIZEOF_INT128__) ms_uint128 out; __uint128_t z = ((__uint128_t)x) * ((__uint128_t)y); out.lo = (uint64_t)z; out.hi = (uint64_t)(z >> 64); return out; #else ms_uint128 out; uint64_t x0 = x & 0xFFFFFFFF; uint64_t x1 = x >> 32; uint64_t y0 = y & 0xFFFFFFFF; uint64_t y1 = y >> 32; uint64_t w0 = x0 * y0; uint64_t t = (x1 * y0) + (w0 >> 32); uint64_t w1 = t & 0xFFFFFFFF; uint64_t w2 = t >> 32; w1 += x0 * y1; out.lo = x * y; out.hi = (x1 * y1) + w2 + (w1 >> 32); return out; #endif } static inline uint32_t ms_clzll(uint64_t x) { #if defined(_MSC_VER) && (defined(_M_X64) || defined(_M_ARM64) || defined(_M_IA64)) uint32_t index = 0; _BitScanReverse64(&index, x); return (int)(63 - index); #elif defined(__GNUC__) return (uint32_t)__builtin_clzll(x); #else uint32_t out; if ((x >> 32) == 0) { out |= 32; x <<= 32; } if ((x >> 48) == 0) { out |= 16; x <<= 16; } if ((x >> 56) == 0) { out |= 8; x <<= 8; } if ((x >> 60) == 0) { out |= 4; x <<= 4; } if ((x >> 62) == 0) { out |= 2; x <<= 2; } if ((x >> 63) == 0) { out |= 1; x <<= 1; } return out; #endif } static inline int64_t eisel_lemire(uint64_t man, int32_t exp) { /* The short comment headers below correspond to section titles in Nigel * Tao's blogpost. See * https://nigeltao.github.io/blog/2020/eisel-lemire.html for a more * in-depth description of the algorithm */ /* Normalization */ const uint64_t* po10 = ms_atof_powers_of_10[exp + 307]; uint32_t clz = ms_clzll(man); man <<= clz; uint64_t ret_exp2 = ((uint64_t)(((217706 * exp) >> 16) + 1087)) - ((uint64_t)clz); /* Multiplication */ ms_uint128 x = ms_mulu64(man, po10[1]); uint64_t x_hi = x.hi; uint64_t x_lo = x.lo; /* Apply a wider Approximation if needed */ if (((x_hi & 0x1FF) == 0x1FF) && ((x_lo + man) < man)) { ms_uint128 y = ms_mulu64(man, po10[0]); uint64_t y_hi = y.hi; uint64_t y_lo = y.lo; uint64_t merged_hi = x_hi; uint64_t merged_lo = x_lo + y_hi; if (merged_lo < x_lo) { merged_hi++; } /* If the result is still ambiguous at this approximation, abort */ if (((merged_hi & 0x1FF) == 0x1FF) && ((merged_lo + 1) == 0) && (y_lo + man < man)) { return -1; } x_hi = merged_hi; x_lo = merged_lo; } /* Shift to 54 bits */ uint64_t msb = x_hi >> 63; uint64_t ret_mantissa = x_hi >> (msb + 9); ret_exp2 -= 1 ^ msb; /* Check for a half-way ambiguity, and abort if present */ if ((x_lo == 0) && ((x_hi & 0x1FF) == 0) && ((ret_mantissa & 3) == 1)) { return -1; } /* From 54 to 53 bits */ ret_mantissa += ret_mantissa & 1; ret_mantissa >>= 1; if ((ret_mantissa >> 53) > 0) { ret_mantissa >>= 1; ret_exp2++; } /* Construct final output */ ret_mantissa &= 0x000FFFFFFFFFFFFF; return ((int64_t)(ret_mantissa | (ret_exp2 << 52))); } /* Fallback parsing method using a High Precision Double (HPD) */ #define MS_HPD_MAX_DIGITS 800 #define MS_HPD_DP_RANGE 2047 #define MS_HPD_MAX_SHIFT 60 typedef struct ms_hpd { uint32_t num_digits; int32_t decimal_point; bool negative; bool truncated; uint8_t digits[800]; } ms_hpd; static inline void ms_hpd_trim(ms_hpd *dec) { while ((dec->num_digits > 0) && (dec->digits[dec->num_digits - 1] == 0)) { dec->num_digits--; } if (dec->num_digits == 0) { dec->decimal_point = 0; } } static uint32_t ms_hpd_lshift_num_new_digits(ms_hpd *hpd, uint32_t shift) { shift &= 63; uint32_t x_a = ms_atof_left_shift[shift]; uint32_t x_b = ms_atof_left_shift[shift + 1]; uint32_t num_new_digits = x_a >> 11; uint32_t pow5_a = 0x7FF & x_a; uint32_t pow5_b = 0x7FF & x_b; const uint8_t* pow5 = &ms_atof_powers_of_5[pow5_a]; uint32_t i = 0; uint32_t n = pow5_b - pow5_a; for (; i < n; i++) { if (i >= hpd->num_digits) { return num_new_digits - 1; } else if (hpd->digits[i] == pow5[i]) { continue; } else if (hpd->digits[i] < pow5[i]) { return num_new_digits - 1; } else { return num_new_digits; } } return num_new_digits; } static uint64_t ms_hpd_rounded_integer(ms_hpd *hpd) { if ((hpd->num_digits == 0) || (hpd->decimal_point < 0)) { return 0; } else if (hpd->decimal_point > 18) { return UINT64_MAX; } uint32_t dp = (uint32_t)(hpd->decimal_point); uint64_t n = 0; uint32_t i = 0; for (; i < dp; i++) { n = (10 * n) + ((i < hpd->num_digits) ? hpd->digits[i] : 0); } bool round_up = false; if (dp < hpd->num_digits) { round_up = hpd->digits[dp] >= 5; if ((hpd->digits[dp] == 5) && (dp + 1 == hpd->num_digits)) { round_up = hpd->truncated || ((dp > 0) && (1 & hpd->digits[dp - 1])); } } if (round_up) { n++; } return n; } static void ms_hpd_small_lshift(ms_hpd *hpd, uint32_t shift) { if (hpd->num_digits == 0) { return; } uint32_t num_new_digits = ms_hpd_lshift_num_new_digits(hpd, shift); uint32_t rx = hpd->num_digits - 1; // Read index. uint32_t wx = hpd->num_digits - 1 + num_new_digits; // Write index. uint64_t n = 0; while (((int32_t)rx) >= 0) { n += ((uint64_t)(hpd->digits[rx])) << shift; uint64_t quo = n / 10; uint64_t rem = n - (10 * quo); if (wx < MS_HPD_MAX_DIGITS) { hpd->digits[wx] = (uint8_t)rem; } else if (rem > 0) { hpd->truncated = true; } n = quo; wx--; rx--; } while (n > 0) { uint64_t quo = n / 10; uint64_t rem = n - (10 * quo); if (wx < MS_HPD_MAX_DIGITS) { hpd->digits[wx] = (uint8_t)rem; } else if (rem > 0) { hpd->truncated = true; } n = quo; wx--; } hpd->num_digits += num_new_digits; if (hpd->num_digits > MS_HPD_MAX_DIGITS) { hpd->num_digits = MS_HPD_MAX_DIGITS; } hpd->decimal_point += (int32_t)num_new_digits; ms_hpd_trim(hpd); } static void ms_hpd_small_rshift(ms_hpd *hpd, uint32_t shift) { uint32_t rx = 0; uint32_t wx = 0; uint64_t n = 0; while ((n >> shift) == 0) { if (rx < hpd->num_digits) { n = (10 * n) + hpd->digits[rx++]; } else if (n == 0) { return; } else { while ((n >> shift) == 0) { n = 10 * n; rx++; } break; } } hpd->decimal_point -= ((int32_t)(rx - 1)); if (hpd->decimal_point < -MS_HPD_DP_RANGE) { hpd->num_digits = 0; hpd->decimal_point = 0; hpd->truncated = false; return; } uint64_t mask = (((uint64_t)(1)) << shift) - 1; while (rx < hpd->num_digits) { uint8_t new_digit = ((uint8_t)(n >> shift)); n = (10 * (n & mask)) + hpd->digits[rx++]; hpd->digits[wx++] = new_digit; } while (n > 0) { uint8_t new_digit = ((uint8_t)(n >> shift)); n = 10 * (n & mask); if (wx < MS_HPD_MAX_DIGITS) { hpd->digits[wx++] = new_digit; } else if (new_digit > 0) { hpd->truncated = true; } } hpd->num_digits = wx; ms_hpd_trim(hpd); } static double ms_hpd_to_double(ms_hpd *hpd) { static const uint32_t num_powers = 19; static const uint8_t powers[19] = { 0, 3, 6, 9, 13, 16, 19, 23, 26, 29, 33, 36, 39, 43, 46, 49, 53, 56, 59, }; if ((hpd->num_digits == 0) || (hpd->decimal_point < -326)) { goto zero; } else if (hpd->decimal_point > 310) { goto infinity; } const int32_t f64_bias = -1023; int32_t exp2 = 0; while (hpd->decimal_point > 0) { uint32_t n = (uint32_t)(+hpd->decimal_point); uint32_t shift = (n < num_powers) ? powers[n] : MS_HPD_MAX_SHIFT; ms_hpd_small_rshift(hpd, shift); if (hpd->decimal_point < -MS_HPD_DP_RANGE) { goto zero; } exp2 += (int32_t)shift; } while (hpd->decimal_point <= 0) { uint32_t shift; if (hpd->decimal_point == 0) { if (hpd->digits[0] >= 5) { break; } shift = (hpd->digits[0] < 2) ? 2 : 1; } else { uint32_t n = (uint32_t)(-hpd->decimal_point); shift = (n < num_powers) ? powers[n] : MS_HPD_MAX_SHIFT; } ms_hpd_small_lshift(hpd, shift); if (hpd->decimal_point > +MS_HPD_DP_RANGE) { goto infinity; } exp2 -= (int32_t)shift; } exp2--; while ((f64_bias + 1) > exp2) { uint32_t n = (uint32_t)((f64_bias + 1) - exp2); if (n > MS_HPD_MAX_SHIFT) { n = MS_HPD_MAX_SHIFT; } ms_hpd_small_rshift(hpd, n); exp2 += (int32_t)n; } if ((exp2 - f64_bias) >= 0x07FF) { goto infinity; } ms_hpd_small_lshift(hpd, 53); uint64_t man2 = ms_hpd_rounded_integer(hpd); if ((man2 >> 53) != 0) { man2 >>= 1; exp2++; if ((exp2 - f64_bias) >= 0x07FF) { goto infinity; } } if ((man2 >> 52) == 0) { exp2 = f64_bias; } uint64_t exp2_bits = (uint64_t)((exp2 - f64_bias) & 0x07FF); uint64_t bits = ( (man2 & 0x000FFFFFFFFFFFFF) | (exp2_bits << 52) | (hpd->negative ? 0x8000000000000000 : 0) ); double ret; memcpy(&ret, &bits, sizeof(double)); return ret; zero: return hpd->negative ? -0.0 : 0.0; infinity: return hpd->negative ? -INFINITY : INFINITY; } #endif python-msgspec-0.22.0/src/msgspec/atof_consts.h000066400000000000000000001072431525673062400215170ustar00rootroot00000000000000/* DO NOT EDIT - generated by scripts/generate_atof_consts.py */ #ifndef MSGSPEC_ATOF_CONSTS_H #define MSGSPEC_ATOF_CONSTS_H static const uint64_t ms_atof_powers_of_10[596][2] = { {0xa5d3b6d479f8e056, 0x8fd0c16206306bab}, // 1e-307 {0x8f48a4899877186c, 0xb3c4f1ba87bc8696}, // 1e-306 {0x331acdabfe94de87, 0xe0b62e2929aba83c}, // 1e-305 {0x9ff0c08b7f1d0b14, 0x8c71dcd9ba0b4925}, // 1e-304 {0x07ecf0ae5ee44dd9, 0xaf8e5410288e1b6f}, // 1e-303 {0xc9e82cd9f69d6150, 0xdb71e91432b1a24a}, // 1e-302 {0xbe311c083a225cd2, 0x892731ac9faf056e}, // 1e-301 {0x6dbd630a48aaf406, 0xab70fe17c79ac6ca}, // 1e-300 {0x092cbbccdad5b108, 0xd64d3d9db981787d}, // 1e-299 {0x25bbf56008c58ea5, 0x85f0468293f0eb4e}, // 1e-298 {0xaf2af2b80af6f24e, 0xa76c582338ed2621}, // 1e-297 {0x1af5af660db4aee1, 0xd1476e2c07286faa}, // 1e-296 {0x50d98d9fc890ed4d, 0x82cca4db847945ca}, // 1e-295 {0xe50ff107bab528a0, 0xa37fce126597973c}, // 1e-294 {0x1e53ed49a96272c8, 0xcc5fc196fefd7d0c}, // 1e-293 {0x25e8e89c13bb0f7a, 0xff77b1fcbebcdc4f}, // 1e-292 {0x77b191618c54e9ac, 0x9faacf3df73609b1}, // 1e-291 {0xd59df5b9ef6a2417, 0xc795830d75038c1d}, // 1e-290 {0x4b0573286b44ad1d, 0xf97ae3d0d2446f25}, // 1e-289 {0x4ee367f9430aec32, 0x9becce62836ac577}, // 1e-288 {0x229c41f793cda73f, 0xc2e801fb244576d5}, // 1e-287 {0x6b43527578c1110f, 0xf3a20279ed56d48a}, // 1e-286 {0x830a13896b78aaa9, 0x9845418c345644d6}, // 1e-285 {0x23cc986bc656d553, 0xbe5691ef416bd60c}, // 1e-284 {0x2cbfbe86b7ec8aa8, 0xedec366b11c6cb8f}, // 1e-283 {0x7bf7d71432f3d6a9, 0x94b3a202eb1c3f39}, // 1e-282 {0xdaf5ccd93fb0cc53, 0xb9e08a83a5e34f07}, // 1e-281 {0xd1b3400f8f9cff68, 0xe858ad248f5c22c9}, // 1e-280 {0x23100809b9c21fa1, 0x91376c36d99995be}, // 1e-279 {0xabd40a0c2832a78a, 0xb58547448ffffb2d}, // 1e-278 {0x16c90c8f323f516c, 0xe2e69915b3fff9f9}, // 1e-277 {0xae3da7d97f6792e3, 0x8dd01fad907ffc3b}, // 1e-276 {0x99cd11cfdf41779c, 0xb1442798f49ffb4a}, // 1e-275 {0x40405643d711d583, 0xdd95317f31c7fa1d}, // 1e-274 {0x482835ea666b2572, 0x8a7d3eef7f1cfc52}, // 1e-273 {0xda3243650005eecf, 0xad1c8eab5ee43b66}, // 1e-272 {0x90bed43e40076a82, 0xd863b256369d4a40}, // 1e-271 {0x5a7744a6e804a291, 0x873e4f75e2224e68}, // 1e-270 {0x711515d0a205cb36, 0xa90de3535aaae202}, // 1e-269 {0x0d5a5b44ca873e03, 0xd3515c2831559a83}, // 1e-268 {0xe858790afe9486c2, 0x8412d9991ed58091}, // 1e-267 {0x626e974dbe39a872, 0xa5178fff668ae0b6}, // 1e-266 {0xfb0a3d212dc8128f, 0xce5d73ff402d98e3}, // 1e-265 {0x7ce66634bc9d0b99, 0x80fa687f881c7f8e}, // 1e-264 {0x1c1fffc1ebc44e80, 0xa139029f6a239f72}, // 1e-263 {0xa327ffb266b56220, 0xc987434744ac874e}, // 1e-262 {0x4bf1ff9f0062baa8, 0xfbe9141915d7a922}, // 1e-261 {0x6f773fc3603db4a9, 0x9d71ac8fada6c9b5}, // 1e-260 {0xcb550fb4384d21d3, 0xc4ce17b399107c22}, // 1e-259 {0x7e2a53a146606a48, 0xf6019da07f549b2b}, // 1e-258 {0x2eda7444cbfc426d, 0x99c102844f94e0fb}, // 1e-257 {0xfa911155fefb5308, 0xc0314325637a1939}, // 1e-256 {0x793555ab7eba27ca, 0xf03d93eebc589f88}, // 1e-255 {0x4bc1558b2f3458de, 0x96267c7535b763b5}, // 1e-254 {0x9eb1aaedfb016f16, 0xbbb01b9283253ca2}, // 1e-253 {0x465e15a979c1cadc, 0xea9c227723ee8bcb}, // 1e-252 {0x0bfacd89ec191ec9, 0x92a1958a7675175f}, // 1e-251 {0xcef980ec671f667b, 0xb749faed14125d36}, // 1e-250 {0x82b7e12780e7401a, 0xe51c79a85916f484}, // 1e-249 {0xd1b2ecb8b0908810, 0x8f31cc0937ae58d2}, // 1e-248 {0x861fa7e6dcb4aa15, 0xb2fe3f0b8599ef07}, // 1e-247 {0x67a791e093e1d49a, 0xdfbdcece67006ac9}, // 1e-246 {0xe0c8bb2c5c6d24e0, 0x8bd6a141006042bd}, // 1e-245 {0x58fae9f773886e18, 0xaecc49914078536d}, // 1e-244 {0xaf39a475506a899e, 0xda7f5bf590966848}, // 1e-243 {0x6d8406c952429603, 0x888f99797a5e012d}, // 1e-242 {0xc8e5087ba6d33b83, 0xaab37fd7d8f58178}, // 1e-241 {0xfb1e4a9a90880a64, 0xd5605fcdcf32e1d6}, // 1e-240 {0x5cf2eea09a55067f, 0x855c3be0a17fcd26}, // 1e-239 {0xf42faa48c0ea481e, 0xa6b34ad8c9dfc06f}, // 1e-238 {0xf13b94daf124da26, 0xd0601d8efc57b08b}, // 1e-237 {0x76c53d08d6b70858, 0x823c12795db6ce57}, // 1e-236 {0x54768c4b0c64ca6e, 0xa2cb1717b52481ed}, // 1e-235 {0xa9942f5dcf7dfd09, 0xcb7ddcdda26da268}, // 1e-234 {0xd3f93b35435d7c4c, 0xfe5d54150b090b02}, // 1e-233 {0xc47bc5014a1a6daf, 0x9efa548d26e5a6e1}, // 1e-232 {0x359ab6419ca1091b, 0xc6b8e9b0709f109a}, // 1e-231 {0xc30163d203c94b62, 0xf867241c8cc6d4c0}, // 1e-230 {0x79e0de63425dcf1d, 0x9b407691d7fc44f8}, // 1e-229 {0x985915fc12f542e4, 0xc21094364dfb5636}, // 1e-228 {0x3e6f5b7b17b2939d, 0xf294b943e17a2bc4}, // 1e-227 {0xa705992ceecf9c42, 0x979cf3ca6cec5b5a}, // 1e-226 {0x50c6ff782a838353, 0xbd8430bd08277231}, // 1e-225 {0xa4f8bf5635246428, 0xece53cec4a314ebd}, // 1e-224 {0x871b7795e136be99, 0x940f4613ae5ed136}, // 1e-223 {0x28e2557b59846e3f, 0xb913179899f68584}, // 1e-222 {0x331aeada2fe589cf, 0xe757dd7ec07426e5}, // 1e-221 {0x3ff0d2c85def7621, 0x9096ea6f3848984f}, // 1e-220 {0x0fed077a756b53a9, 0xb4bca50b065abe63}, // 1e-219 {0xd3e8495912c62894, 0xe1ebce4dc7f16dfb}, // 1e-218 {0x64712dd7abbbd95c, 0x8d3360f09cf6e4bd}, // 1e-217 {0xbd8d794d96aacfb3, 0xb080392cc4349dec}, // 1e-216 {0xecf0d7a0fc5583a0, 0xdca04777f541c567}, // 1e-215 {0xf41686c49db57244, 0x89e42caaf9491b60}, // 1e-214 {0x311c2875c522ced5, 0xac5d37d5b79b6239}, // 1e-213 {0x7d633293366b828b, 0xd77485cb25823ac7}, // 1e-212 {0xae5dff9c02033197, 0x86a8d39ef77164bc}, // 1e-211 {0xd9f57f830283fdfc, 0xa8530886b54dbdeb}, // 1e-210 {0xd072df63c324fd7b, 0xd267caa862a12d66}, // 1e-209 {0x4247cb9e59f71e6d, 0x8380dea93da4bc60}, // 1e-208 {0x52d9be85f074e608, 0xa46116538d0deb78}, // 1e-207 {0x67902e276c921f8b, 0xcd795be870516656}, // 1e-206 {0x00ba1cd8a3db53b6, 0x806bd9714632dff6}, // 1e-205 {0x80e8a40eccd228a4, 0xa086cfcd97bf97f3}, // 1e-204 {0x6122cd128006b2cd, 0xc8a883c0fdaf7df0}, // 1e-203 {0x796b805720085f81, 0xfad2a4b13d1b5d6c}, // 1e-202 {0xcbe3303674053bb0, 0x9cc3a6eec6311a63}, // 1e-201 {0xbedbfc4411068a9c, 0xc3f490aa77bd60fc}, // 1e-200 {0xee92fb5515482d44, 0xf4f1b4d515acb93b}, // 1e-199 {0x751bdd152d4d1c4a, 0x991711052d8bf3c5}, // 1e-198 {0xd262d45a78a0635d, 0xbf5cd54678eef0b6}, // 1e-197 {0x86fb897116c87c34, 0xef340a98172aace4}, // 1e-196 {0xd45d35e6ae3d4da0, 0x9580869f0e7aac0e}, // 1e-195 {0x8974836059cca109, 0xbae0a846d2195712}, // 1e-194 {0x2bd1a438703fc94b, 0xe998d258869facd7}, // 1e-193 {0x7b6306a34627ddcf, 0x91ff83775423cc06}, // 1e-192 {0x1a3bc84c17b1d542, 0xb67f6455292cbf08}, // 1e-191 {0x20caba5f1d9e4a93, 0xe41f3d6a7377eeca}, // 1e-190 {0x547eb47b7282ee9c, 0x8e938662882af53e}, // 1e-189 {0xe99e619a4f23aa43, 0xb23867fb2a35b28d}, // 1e-188 {0x6405fa00e2ec94d4, 0xdec681f9f4c31f31}, // 1e-187 {0xde83bc408dd3dd04, 0x8b3c113c38f9f37e}, // 1e-186 {0x9624ab50b148d445, 0xae0b158b4738705e}, // 1e-185 {0x3badd624dd9b0957, 0xd98ddaee19068c76}, // 1e-184 {0xe54ca5d70a80e5d6, 0x87f8a8d4cfa417c9}, // 1e-183 {0x5e9fcf4ccd211f4c, 0xa9f6d30a038d1dbc}, // 1e-182 {0x7647c3200069671f, 0xd47487cc8470652b}, // 1e-181 {0x29ecd9f40041e073, 0x84c8d4dfd2c63f3b}, // 1e-180 {0xf468107100525890, 0xa5fb0a17c777cf09}, // 1e-179 {0x7182148d4066eeb4, 0xcf79cc9db955c2cc}, // 1e-178 {0xc6f14cd848405530, 0x81ac1fe293d599bf}, // 1e-177 {0xb8ada00e5a506a7c, 0xa21727db38cb002f}, // 1e-176 {0xa6d90811f0e4851c, 0xca9cf1d206fdc03b}, // 1e-175 {0x908f4a166d1da663, 0xfd442e4688bd304a}, // 1e-174 {0x9a598e4e043287fe, 0x9e4a9cec15763e2e}, // 1e-173 {0x40eff1e1853f29fd, 0xc5dd44271ad3cdba}, // 1e-172 {0xd12bee59e68ef47c, 0xf7549530e188c128}, // 1e-171 {0x82bb74f8301958ce, 0x9a94dd3e8cf578b9}, // 1e-170 {0xe36a52363c1faf01, 0xc13a148e3032d6e7}, // 1e-169 {0xdc44e6c3cb279ac1, 0xf18899b1bc3f8ca1}, // 1e-168 {0x29ab103a5ef8c0b9, 0x96f5600f15a7b7e5}, // 1e-167 {0x7415d448f6b6f0e7, 0xbcb2b812db11a5de}, // 1e-166 {0x111b495b3464ad21, 0xebdf661791d60f56}, // 1e-165 {0xcab10dd900beec34, 0x936b9fcebb25c995}, // 1e-164 {0x3d5d514f40eea742, 0xb84687c269ef3bfb}, // 1e-163 {0x0cb4a5a3112a5112, 0xe65829b3046b0afa}, // 1e-162 {0x47f0e785eaba72ab, 0x8ff71a0fe2c2e6dc}, // 1e-161 {0x59ed216765690f56, 0xb3f4e093db73a093}, // 1e-160 {0x306869c13ec3532c, 0xe0f218b8d25088b8}, // 1e-159 {0x1e414218c73a13fb, 0x8c974f7383725573}, // 1e-158 {0xe5d1929ef90898fa, 0xafbd2350644eeacf}, // 1e-157 {0xdf45f746b74abf39, 0xdbac6c247d62a583}, // 1e-156 {0x6b8bba8c328eb783, 0x894bc396ce5da772}, // 1e-155 {0x066ea92f3f326564, 0xab9eb47c81f5114f}, // 1e-154 {0xc80a537b0efefebd, 0xd686619ba27255a2}, // 1e-153 {0xbd06742ce95f5f36, 0x8613fd0145877585}, // 1e-152 {0x2c48113823b73704, 0xa798fc4196e952e7}, // 1e-151 {0xf75a15862ca504c5, 0xd17f3b51fca3a7a0}, // 1e-150 {0x9a984d73dbe722fb, 0x82ef85133de648c4}, // 1e-149 {0xc13e60d0d2e0ebba, 0xa3ab66580d5fdaf5}, // 1e-148 {0x318df905079926a8, 0xcc963fee10b7d1b3}, // 1e-147 {0xfdf17746497f7052, 0xffbbcfe994e5c61f}, // 1e-146 {0xfeb6ea8bedefa633, 0x9fd561f1fd0f9bd3}, // 1e-145 {0xfe64a52ee96b8fc0, 0xc7caba6e7c5382c8}, // 1e-144 {0x3dfdce7aa3c673b0, 0xf9bd690a1b68637b}, // 1e-143 {0x06bea10ca65c084e, 0x9c1661a651213e2d}, // 1e-142 {0x486e494fcff30a62, 0xc31bfa0fe5698db8}, // 1e-141 {0x5a89dba3c3efccfa, 0xf3e2f893dec3f126}, // 1e-140 {0xf89629465a75e01c, 0x986ddb5c6b3a76b7}, // 1e-139 {0xf6bbb397f1135823, 0xbe89523386091465}, // 1e-138 {0x746aa07ded582e2c, 0xee2ba6c0678b597f}, // 1e-137 {0xa8c2a44eb4571cdc, 0x94db483840b717ef}, // 1e-136 {0x92f34d62616ce413, 0xba121a4650e4ddeb}, // 1e-135 {0x77b020baf9c81d17, 0xe896a0d7e51e1566}, // 1e-134 {0x0ace1474dc1d122e, 0x915e2486ef32cd60}, // 1e-133 {0x0d819992132456ba, 0xb5b5ada8aaff80b8}, // 1e-132 {0x10e1fff697ed6c69, 0xe3231912d5bf60e6}, // 1e-131 {0xca8d3ffa1ef463c1, 0x8df5efabc5979c8f}, // 1e-130 {0xbd308ff8a6b17cb2, 0xb1736b96b6fd83b3}, // 1e-129 {0xac7cb3f6d05ddbde, 0xddd0467c64bce4a0}, // 1e-128 {0x6bcdf07a423aa96b, 0x8aa22c0dbef60ee4}, // 1e-127 {0x86c16c98d2c953c6, 0xad4ab7112eb3929d}, // 1e-126 {0xe871c7bf077ba8b7, 0xd89d64d57a607744}, // 1e-125 {0x11471cd764ad4972, 0x87625f056c7c4a8b}, // 1e-124 {0xd598e40d3dd89bcf, 0xa93af6c6c79b5d2d}, // 1e-123 {0x4aff1d108d4ec2c3, 0xd389b47879823479}, // 1e-122 {0xcedf722a585139ba, 0x843610cb4bf160cb}, // 1e-121 {0xc2974eb4ee658828, 0xa54394fe1eedb8fe}, // 1e-120 {0x733d226229feea32, 0xce947a3da6a9273e}, // 1e-119 {0x0806357d5a3f525f, 0x811ccc668829b887}, // 1e-118 {0xca07c2dcb0cf26f7, 0xa163ff802a3426a8}, // 1e-117 {0xfc89b393dd02f0b5, 0xc9bcff6034c13052}, // 1e-116 {0xbbac2078d443ace2, 0xfc2c3f3841f17c67}, // 1e-115 {0xd54b944b84aa4c0d, 0x9d9ba7832936edc0}, // 1e-114 {0x0a9e795e65d4df11, 0xc5029163f384a931}, // 1e-113 {0x4d4617b5ff4a16d5, 0xf64335bcf065d37d}, // 1e-112 {0x504bced1bf8e4e45, 0x99ea0196163fa42e}, // 1e-111 {0xe45ec2862f71e1d6, 0xc06481fb9bcf8d39}, // 1e-110 {0x5d767327bb4e5a4c, 0xf07da27a82c37088}, // 1e-109 {0x3a6a07f8d510f86f, 0x964e858c91ba2655}, // 1e-108 {0x890489f70a55368b, 0xbbe226efb628afea}, // 1e-107 {0x2b45ac74ccea842e, 0xeadab0aba3b2dbe5}, // 1e-106 {0x3b0b8bc90012929d, 0x92c8ae6b464fc96f}, // 1e-105 {0x09ce6ebb40173744, 0xb77ada0617e3bbcb}, // 1e-104 {0xcc420a6a101d0515, 0xe55990879ddcaabd}, // 1e-103 {0x9fa946824a12232d, 0x8f57fa54c2a9eab6}, // 1e-102 {0x47939822dc96abf9, 0xb32df8e9f3546564}, // 1e-101 {0x59787e2b93bc56f7, 0xdff9772470297ebd}, // 1e-100 {0x57eb4edb3c55b65a, 0x8bfbea76c619ef36}, // 1e-99 {0xede622920b6b23f1, 0xaefae51477a06b03}, // 1e-98 {0xe95fab368e45eced, 0xdab99e59958885c4}, // 1e-97 {0x11dbcb0218ebb414, 0x88b402f7fd75539b}, // 1e-96 {0xd652bdc29f26a119, 0xaae103b5fcd2a881}, // 1e-95 {0x4be76d3346f0495f, 0xd59944a37c0752a2}, // 1e-94 {0x6f70a4400c562ddb, 0x857fcae62d8493a5}, // 1e-93 {0xcb4ccd500f6bb952, 0xa6dfbd9fb8e5b88e}, // 1e-92 {0x7e2000a41346a7a7, 0xd097ad07a71f26b2}, // 1e-91 {0x8ed400668c0c28c8, 0x825ecc24c873782f}, // 1e-90 {0x728900802f0f32fa, 0xa2f67f2dfa90563b}, // 1e-89 {0x4f2b40a03ad2ffb9, 0xcbb41ef979346bca}, // 1e-88 {0xe2f610c84987bfa8, 0xfea126b7d78186bc}, // 1e-87 {0x0dd9ca7d2df4d7c9, 0x9f24b832e6b0f436}, // 1e-86 {0x91503d1c79720dbb, 0xc6ede63fa05d3143}, // 1e-85 {0x75a44c6397ce912a, 0xf8a95fcf88747d94}, // 1e-84 {0xc986afbe3ee11aba, 0x9b69dbe1b548ce7c}, // 1e-83 {0xfbe85badce996168, 0xc24452da229b021b}, // 1e-82 {0xfae27299423fb9c3, 0xf2d56790ab41c2a2}, // 1e-81 {0xdccd879fc967d41a, 0x97c560ba6b0919a5}, // 1e-80 {0x5400e987bbc1c920, 0xbdb6b8e905cb600f}, // 1e-79 {0x290123e9aab23b68, 0xed246723473e3813}, // 1e-78 {0xf9a0b6720aaf6521, 0x9436c0760c86e30b}, // 1e-77 {0xf808e40e8d5b3e69, 0xb94470938fa89bce}, // 1e-76 {0xb60b1d1230b20e04, 0xe7958cb87392c2c2}, // 1e-75 {0xb1c6f22b5e6f48c2, 0x90bd77f3483bb9b9}, // 1e-74 {0x1e38aeb6360b1af3, 0xb4ecd5f01a4aa828}, // 1e-73 {0x25c6da63c38de1b0, 0xe2280b6c20dd5232}, // 1e-72 {0x579c487e5a38ad0e, 0x8d590723948a535f}, // 1e-71 {0x2d835a9df0c6d851, 0xb0af48ec79ace837}, // 1e-70 {0xf8e431456cf88e65, 0xdcdb1b2798182244}, // 1e-69 {0x1b8e9ecb641b58ff, 0x8a08f0f8bf0f156b}, // 1e-68 {0xe272467e3d222f3f, 0xac8b2d36eed2dac5}, // 1e-67 {0x5b0ed81dcc6abb0f, 0xd7adf884aa879177}, // 1e-66 {0x98e947129fc2b4e9, 0x86ccbb52ea94baea}, // 1e-65 {0x3f2398d747b36224, 0xa87fea27a539e9a5}, // 1e-64 {0x8eec7f0d19a03aad, 0xd29fe4b18e88640e}, // 1e-63 {0x1953cf68300424ac, 0x83a3eeeef9153e89}, // 1e-62 {0x5fa8c3423c052dd7, 0xa48ceaaab75a8e2b}, // 1e-61 {0x3792f412cb06794d, 0xcdb02555653131b6}, // 1e-60 {0xe2bbd88bbee40bd0, 0x808e17555f3ebf11}, // 1e-59 {0x5b6aceaeae9d0ec4, 0xa0b19d2ab70e6ed6}, // 1e-58 {0xf245825a5a445275, 0xc8de047564d20a8b}, // 1e-57 {0xeed6e2f0f0d56712, 0xfb158592be068d2e}, // 1e-56 {0x55464dd69685606b, 0x9ced737bb6c4183d}, // 1e-55 {0xaa97e14c3c26b886, 0xc428d05aa4751e4c}, // 1e-54 {0xd53dd99f4b3066a8, 0xf53304714d9265df}, // 1e-53 {0xe546a8038efe4029, 0x993fe2c6d07b7fab}, // 1e-52 {0xde98520472bdd033, 0xbf8fdb78849a5f96}, // 1e-51 {0x963e66858f6d4440, 0xef73d256a5c0f77c}, // 1e-50 {0xdde7001379a44aa8, 0x95a8637627989aad}, // 1e-49 {0x5560c018580d5d52, 0xbb127c53b17ec159}, // 1e-48 {0xaab8f01e6e10b4a6, 0xe9d71b689dde71af}, // 1e-47 {0xcab3961304ca70e8, 0x9226712162ab070d}, // 1e-46 {0x3d607b97c5fd0d22, 0xb6b00d69bb55c8d1}, // 1e-45 {0x8cb89a7db77c506a, 0xe45c10c42a2b3b05}, // 1e-44 {0x77f3608e92adb242, 0x8eb98a7a9a5b04e3}, // 1e-43 {0x55f038b237591ed3, 0xb267ed1940f1c61c}, // 1e-42 {0x6b6c46dec52f6688, 0xdf01e85f912e37a3}, // 1e-41 {0x2323ac4b3b3da015, 0x8b61313bbabce2c6}, // 1e-40 {0xabec975e0a0d081a, 0xae397d8aa96c1b77}, // 1e-39 {0x96e7bd358c904a21, 0xd9c7dced53c72255}, // 1e-38 {0x7e50d64177da2e54, 0x881cea14545c7575}, // 1e-37 {0xdde50bd1d5d0b9e9, 0xaa242499697392d2}, // 1e-36 {0x955e4ec64b44e864, 0xd4ad2dbfc3d07787}, // 1e-35 {0xbd5af13bef0b113e, 0x84ec3c97da624ab4}, // 1e-34 {0xecb1ad8aeacdd58e, 0xa6274bbdd0fadd61}, // 1e-33 {0x67de18eda5814af2, 0xcfb11ead453994ba}, // 1e-32 {0x80eacf948770ced7, 0x81ceb32c4b43fcf4}, // 1e-31 {0xa1258379a94d028d, 0xa2425ff75e14fc31}, // 1e-30 {0x096ee45813a04330, 0xcad2f7f5359a3b3e}, // 1e-29 {0x8bca9d6e188853fc, 0xfd87b5f28300ca0d}, // 1e-28 {0x775ea264cf55347d, 0x9e74d1b791e07e48}, // 1e-27 {0x95364afe032a819d, 0xc612062576589dda}, // 1e-26 {0x3a83ddbd83f52204, 0xf79687aed3eec551}, // 1e-25 {0xc4926a9672793542, 0x9abe14cd44753b52}, // 1e-24 {0x75b7053c0f178293, 0xc16d9a0095928a27}, // 1e-23 {0x5324c68b12dd6338, 0xf1c90080baf72cb1}, // 1e-22 {0xd3f6fc16ebca5e03, 0x971da05074da7bee}, // 1e-21 {0x88f4bb1ca6bcf584, 0xbce5086492111aea}, // 1e-20 {0x2b31e9e3d06c32e5, 0xec1e4a7db69561a5}, // 1e-19 {0x3aff322e62439fcf, 0x9392ee8e921d5d07}, // 1e-18 {0x09befeb9fad487c2, 0xb877aa3236a4b449}, // 1e-17 {0x4c2ebe687989a9b3, 0xe69594bec44de15b}, // 1e-16 {0x0f9d37014bf60a10, 0x901d7cf73ab0acd9}, // 1e-15 {0x538484c19ef38c94, 0xb424dc35095cd80f}, // 1e-14 {0x2865a5f206b06fb9, 0xe12e13424bb40e13}, // 1e-13 {0xf93f87b7442e45d3, 0x8cbccc096f5088cb}, // 1e-12 {0xf78f69a51539d748, 0xafebff0bcb24aafe}, // 1e-11 {0xb573440e5a884d1b, 0xdbe6fecebdedd5be}, // 1e-10 {0x31680a88f8953030, 0x89705f4136b4a597}, // 1e-9 {0xfdc20d2b36ba7c3d, 0xabcc77118461cefc}, // 1e-8 {0x3d32907604691b4c, 0xd6bf94d5e57a42bc}, // 1e-7 {0xa63f9a49c2c1b10f, 0x8637bd05af6c69b5}, // 1e-6 {0x0fcf80dc33721d53, 0xa7c5ac471b478423}, // 1e-5 {0xd3c36113404ea4a8, 0xd1b71758e219652b}, // 1e-4 {0x645a1cac083126e9, 0x83126e978d4fdf3b}, // 1e-3 {0x3d70a3d70a3d70a3, 0xa3d70a3d70a3d70a}, // 1e-2 {0xcccccccccccccccc, 0xcccccccccccccccc}, // 1e-1 {0x0000000000000000, 0x8000000000000000}, // 1e0 {0x0000000000000000, 0xa000000000000000}, // 1e1 {0x0000000000000000, 0xc800000000000000}, // 1e2 {0x0000000000000000, 0xfa00000000000000}, // 1e3 {0x0000000000000000, 0x9c40000000000000}, // 1e4 {0x0000000000000000, 0xc350000000000000}, // 1e5 {0x0000000000000000, 0xf424000000000000}, // 1e6 {0x0000000000000000, 0x9896800000000000}, // 1e7 {0x0000000000000000, 0xbebc200000000000}, // 1e8 {0x0000000000000000, 0xee6b280000000000}, // 1e9 {0x0000000000000000, 0x9502f90000000000}, // 1e10 {0x0000000000000000, 0xba43b74000000000}, // 1e11 {0x0000000000000000, 0xe8d4a51000000000}, // 1e12 {0x0000000000000000, 0x9184e72a00000000}, // 1e13 {0x0000000000000000, 0xb5e620f480000000}, // 1e14 {0x0000000000000000, 0xe35fa931a0000000}, // 1e15 {0x0000000000000000, 0x8e1bc9bf04000000}, // 1e16 {0x0000000000000000, 0xb1a2bc2ec5000000}, // 1e17 {0x0000000000000000, 0xde0b6b3a76400000}, // 1e18 {0x0000000000000000, 0x8ac7230489e80000}, // 1e19 {0x0000000000000000, 0xad78ebc5ac620000}, // 1e20 {0x0000000000000000, 0xd8d726b7177a8000}, // 1e21 {0x0000000000000000, 0x878678326eac9000}, // 1e22 {0x0000000000000000, 0xa968163f0a57b400}, // 1e23 {0x0000000000000000, 0xd3c21bcecceda100}, // 1e24 {0x0000000000000000, 0x84595161401484a0}, // 1e25 {0x0000000000000000, 0xa56fa5b99019a5c8}, // 1e26 {0x0000000000000000, 0xcecb8f27f4200f3a}, // 1e27 {0x4000000000000000, 0x813f3978f8940984}, // 1e28 {0x5000000000000000, 0xa18f07d736b90be5}, // 1e29 {0xa400000000000000, 0xc9f2c9cd04674ede}, // 1e30 {0x4d00000000000000, 0xfc6f7c4045812296}, // 1e31 {0xf020000000000000, 0x9dc5ada82b70b59d}, // 1e32 {0x6c28000000000000, 0xc5371912364ce305}, // 1e33 {0xc732000000000000, 0xf684df56c3e01bc6}, // 1e34 {0x3c7f400000000000, 0x9a130b963a6c115c}, // 1e35 {0x4b9f100000000000, 0xc097ce7bc90715b3}, // 1e36 {0x1e86d40000000000, 0xf0bdc21abb48db20}, // 1e37 {0x1314448000000000, 0x96769950b50d88f4}, // 1e38 {0x17d955a000000000, 0xbc143fa4e250eb31}, // 1e39 {0x5dcfab0800000000, 0xeb194f8e1ae525fd}, // 1e40 {0x5aa1cae500000000, 0x92efd1b8d0cf37be}, // 1e41 {0xf14a3d9e40000000, 0xb7abc627050305ad}, // 1e42 {0x6d9ccd05d0000000, 0xe596b7b0c643c719}, // 1e43 {0xe4820023a2000000, 0x8f7e32ce7bea5c6f}, // 1e44 {0xdda2802c8a800000, 0xb35dbf821ae4f38b}, // 1e45 {0xd50b2037ad200000, 0xe0352f62a19e306e}, // 1e46 {0x4526f422cc340000, 0x8c213d9da502de45}, // 1e47 {0x9670b12b7f410000, 0xaf298d050e4395d6}, // 1e48 {0x3c0cdd765f114000, 0xdaf3f04651d47b4c}, // 1e49 {0xa5880a69fb6ac800, 0x88d8762bf324cd0f}, // 1e50 {0x8eea0d047a457a00, 0xab0e93b6efee0053}, // 1e51 {0x72a4904598d6d880, 0xd5d238a4abe98068}, // 1e52 {0x47a6da2b7f864750, 0x85a36366eb71f041}, // 1e53 {0x999090b65f67d924, 0xa70c3c40a64e6c51}, // 1e54 {0xfff4b4e3f741cf6d, 0xd0cf4b50cfe20765}, // 1e55 {0xbff8f10e7a8921a4, 0x82818f1281ed449f}, // 1e56 {0xaff72d52192b6a0d, 0xa321f2d7226895c7}, // 1e57 {0x9bf4f8a69f764490, 0xcbea6f8ceb02bb39}, // 1e58 {0x02f236d04753d5b4, 0xfee50b7025c36a08}, // 1e59 {0x01d762422c946590, 0x9f4f2726179a2245}, // 1e60 {0x424d3ad2b7b97ef5, 0xc722f0ef9d80aad6}, // 1e61 {0xd2e0898765a7deb2, 0xf8ebad2b84e0d58b}, // 1e62 {0x63cc55f49f88eb2f, 0x9b934c3b330c8577}, // 1e63 {0x3cbf6b71c76b25fb, 0xc2781f49ffcfa6d5}, // 1e64 {0x8bef464e3945ef7a, 0xf316271c7fc3908a}, // 1e65 {0x97758bf0e3cbb5ac, 0x97edd871cfda3a56}, // 1e66 {0x3d52eeed1cbea317, 0xbde94e8e43d0c8ec}, // 1e67 {0x4ca7aaa863ee4bdd, 0xed63a231d4c4fb27}, // 1e68 {0x8fe8caa93e74ef6a, 0x945e455f24fb1cf8}, // 1e69 {0xb3e2fd538e122b44, 0xb975d6b6ee39e436}, // 1e70 {0x60dbbca87196b616, 0xe7d34c64a9c85d44}, // 1e71 {0xbc8955e946fe31cd, 0x90e40fbeea1d3a4a}, // 1e72 {0x6babab6398bdbe41, 0xb51d13aea4a488dd}, // 1e73 {0xc696963c7eed2dd1, 0xe264589a4dcdab14}, // 1e74 {0xfc1e1de5cf543ca2, 0x8d7eb76070a08aec}, // 1e75 {0x3b25a55f43294bcb, 0xb0de65388cc8ada8}, // 1e76 {0x49ef0eb713f39ebe, 0xdd15fe86affad912}, // 1e77 {0x6e3569326c784337, 0x8a2dbf142dfcc7ab}, // 1e78 {0x49c2c37f07965404, 0xacb92ed9397bf996}, // 1e79 {0xdc33745ec97be906, 0xd7e77a8f87daf7fb}, // 1e80 {0x69a028bb3ded71a3, 0x86f0ac99b4e8dafd}, // 1e81 {0xc40832ea0d68ce0c, 0xa8acd7c0222311bc}, // 1e82 {0xf50a3fa490c30190, 0xd2d80db02aabd62b}, // 1e83 {0x792667c6da79e0fa, 0x83c7088e1aab65db}, // 1e84 {0x577001b891185938, 0xa4b8cab1a1563f52}, // 1e85 {0xed4c0226b55e6f86, 0xcde6fd5e09abcf26}, // 1e86 {0x544f8158315b05b4, 0x80b05e5ac60b6178}, // 1e87 {0x696361ae3db1c721, 0xa0dc75f1778e39d6}, // 1e88 {0x03bc3a19cd1e38e9, 0xc913936dd571c84c}, // 1e89 {0x04ab48a04065c723, 0xfb5878494ace3a5f}, // 1e90 {0x62eb0d64283f9c76, 0x9d174b2dcec0e47b}, // 1e91 {0x3ba5d0bd324f8394, 0xc45d1df942711d9a}, // 1e92 {0xca8f44ec7ee36479, 0xf5746577930d6500}, // 1e93 {0x7e998b13cf4e1ecb, 0x9968bf6abbe85f20}, // 1e94 {0x9e3fedd8c321a67e, 0xbfc2ef456ae276e8}, // 1e95 {0xc5cfe94ef3ea101e, 0xefb3ab16c59b14a2}, // 1e96 {0xbba1f1d158724a12, 0x95d04aee3b80ece5}, // 1e97 {0x2a8a6e45ae8edc97, 0xbb445da9ca61281f}, // 1e98 {0xf52d09d71a3293bd, 0xea1575143cf97226}, // 1e99 {0x593c2626705f9c56, 0x924d692ca61be758}, // 1e100 {0x6f8b2fb00c77836c, 0xb6e0c377cfa2e12e}, // 1e101 {0x0b6dfb9c0f956447, 0xe498f455c38b997a}, // 1e102 {0x4724bd4189bd5eac, 0x8edf98b59a373fec}, // 1e103 {0x58edec91ec2cb657, 0xb2977ee300c50fe7}, // 1e104 {0x2f2967b66737e3ed, 0xdf3d5e9bc0f653e1}, // 1e105 {0xbd79e0d20082ee74, 0x8b865b215899f46c}, // 1e106 {0xecd8590680a3aa11, 0xae67f1e9aec07187}, // 1e107 {0xe80e6f4820cc9495, 0xda01ee641a708de9}, // 1e108 {0x3109058d147fdcdd, 0x884134fe908658b2}, // 1e109 {0xbd4b46f0599fd415, 0xaa51823e34a7eede}, // 1e110 {0x6c9e18ac7007c91a, 0xd4e5e2cdc1d1ea96}, // 1e111 {0x03e2cf6bc604ddb0, 0x850fadc09923329e}, // 1e112 {0x84db8346b786151c, 0xa6539930bf6bff45}, // 1e113 {0xe612641865679a63, 0xcfe87f7cef46ff16}, // 1e114 {0x4fcb7e8f3f60c07e, 0x81f14fae158c5f6e}, // 1e115 {0xe3be5e330f38f09d, 0xa26da3999aef7749}, // 1e116 {0x5cadf5bfd3072cc5, 0xcb090c8001ab551c}, // 1e117 {0x73d9732fc7c8f7f6, 0xfdcb4fa002162a63}, // 1e118 {0x2867e7fddcdd9afa, 0x9e9f11c4014dda7e}, // 1e119 {0xb281e1fd541501b8, 0xc646d63501a1511d}, // 1e120 {0x1f225a7ca91a4226, 0xf7d88bc24209a565}, // 1e121 {0x3375788de9b06958, 0x9ae757596946075f}, // 1e122 {0x0052d6b1641c83ae, 0xc1a12d2fc3978937}, // 1e123 {0xc0678c5dbd23a49a, 0xf209787bb47d6b84}, // 1e124 {0xf840b7ba963646e0, 0x9745eb4d50ce6332}, // 1e125 {0xb650e5a93bc3d898, 0xbd176620a501fbff}, // 1e126 {0xa3e51f138ab4cebe, 0xec5d3fa8ce427aff}, // 1e127 {0xc66f336c36b10137, 0x93ba47c980e98cdf}, // 1e128 {0xb80b0047445d4184, 0xb8a8d9bbe123f017}, // 1e129 {0xa60dc059157491e5, 0xe6d3102ad96cec1d}, // 1e130 {0x87c89837ad68db2f, 0x9043ea1ac7e41392}, // 1e131 {0x29babe4598c311fb, 0xb454e4a179dd1877}, // 1e132 {0xf4296dd6fef3d67a, 0xe16a1dc9d8545e94}, // 1e133 {0x1899e4a65f58660c, 0x8ce2529e2734bb1d}, // 1e134 {0x5ec05dcff72e7f8f, 0xb01ae745b101e9e4}, // 1e135 {0x76707543f4fa1f73, 0xdc21a1171d42645d}, // 1e136 {0x6a06494a791c53a8, 0x899504ae72497eba}, // 1e137 {0x0487db9d17636892, 0xabfa45da0edbde69}, // 1e138 {0x45a9d2845d3c42b6, 0xd6f8d7509292d603}, // 1e139 {0x0b8a2392ba45a9b2, 0x865b86925b9bc5c2}, // 1e140 {0x8e6cac7768d7141e, 0xa7f26836f282b732}, // 1e141 {0x3207d795430cd926, 0xd1ef0244af2364ff}, // 1e142 {0x7f44e6bd49e807b8, 0x8335616aed761f1f}, // 1e143 {0x5f16206c9c6209a6, 0xa402b9c5a8d3a6e7}, // 1e144 {0x36dba887c37a8c0f, 0xcd036837130890a1}, // 1e145 {0xc2494954da2c9789, 0x802221226be55a64}, // 1e146 {0xf2db9baa10b7bd6c, 0xa02aa96b06deb0fd}, // 1e147 {0x6f92829494e5acc7, 0xc83553c5c8965d3d}, // 1e148 {0xcb772339ba1f17f9, 0xfa42a8b73abbf48c}, // 1e149 {0xff2a760414536efb, 0x9c69a97284b578d7}, // 1e150 {0xfef5138519684aba, 0xc38413cf25e2d70d}, // 1e151 {0x7eb258665fc25d69, 0xf46518c2ef5b8cd1}, // 1e152 {0xef2f773ffbd97a61, 0x98bf2f79d5993802}, // 1e153 {0xaafb550ffacfd8fa, 0xbeeefb584aff8603}, // 1e154 {0x95ba2a53f983cf38, 0xeeaaba2e5dbf6784}, // 1e155 {0xdd945a747bf26183, 0x952ab45cfa97a0b2}, // 1e156 {0x94f971119aeef9e4, 0xba756174393d88df}, // 1e157 {0x7a37cd5601aab85d, 0xe912b9d1478ceb17}, // 1e158 {0xac62e055c10ab33a, 0x91abb422ccb812ee}, // 1e159 {0x577b986b314d6009, 0xb616a12b7fe617aa}, // 1e160 {0xed5a7e85fda0b80b, 0xe39c49765fdf9d94}, // 1e161 {0x14588f13be847307, 0x8e41ade9fbebc27d}, // 1e162 {0x596eb2d8ae258fc8, 0xb1d219647ae6b31c}, // 1e163 {0x6fca5f8ed9aef3bb, 0xde469fbd99a05fe3}, // 1e164 {0x25de7bb9480d5854, 0x8aec23d680043bee}, // 1e165 {0xaf561aa79a10ae6a, 0xada72ccc20054ae9}, // 1e166 {0x1b2ba1518094da04, 0xd910f7ff28069da4}, // 1e167 {0x90fb44d2f05d0842, 0x87aa9aff79042286}, // 1e168 {0x353a1607ac744a53, 0xa99541bf57452b28}, // 1e169 {0x42889b8997915ce8, 0xd3fa922f2d1675f2}, // 1e170 {0x69956135febada11, 0x847c9b5d7c2e09b7}, // 1e171 {0x43fab9837e699095, 0xa59bc234db398c25}, // 1e172 {0x94f967e45e03f4bb, 0xcf02b2c21207ef2e}, // 1e173 {0x1d1be0eebac278f5, 0x8161afb94b44f57d}, // 1e174 {0x6462d92a69731732, 0xa1ba1ba79e1632dc}, // 1e175 {0x7d7b8f7503cfdcfe, 0xca28a291859bbf93}, // 1e176 {0x5cda735244c3d43e, 0xfcb2cb35e702af78}, // 1e177 {0x3a0888136afa64a7, 0x9defbf01b061adab}, // 1e178 {0x088aaa1845b8fdd0, 0xc56baec21c7a1916}, // 1e179 {0x8aad549e57273d45, 0xf6c69a72a3989f5b}, // 1e180 {0x36ac54e2f678864b, 0x9a3c2087a63f6399}, // 1e181 {0x84576a1bb416a7dd, 0xc0cb28a98fcf3c7f}, // 1e182 {0x656d44a2a11c51d5, 0xf0fdf2d3f3c30b9f}, // 1e183 {0x9f644ae5a4b1b325, 0x969eb7c47859e743}, // 1e184 {0x873d5d9f0dde1fee, 0xbc4665b596706114}, // 1e185 {0xa90cb506d155a7ea, 0xeb57ff22fc0c7959}, // 1e186 {0x09a7f12442d588f2, 0x9316ff75dd87cbd8}, // 1e187 {0x0c11ed6d538aeb2f, 0xb7dcbf5354e9bece}, // 1e188 {0x8f1668c8a86da5fa, 0xe5d3ef282a242e81}, // 1e189 {0xf96e017d694487bc, 0x8fa475791a569d10}, // 1e190 {0x37c981dcc395a9ac, 0xb38d92d760ec4455}, // 1e191 {0x85bbe253f47b1417, 0xe070f78d3927556a}, // 1e192 {0x93956d7478ccec8e, 0x8c469ab843b89562}, // 1e193 {0x387ac8d1970027b2, 0xaf58416654a6babb}, // 1e194 {0x06997b05fcc0319e, 0xdb2e51bfe9d0696a}, // 1e195 {0x441fece3bdf81f03, 0x88fcf317f22241e2}, // 1e196 {0xd527e81cad7626c3, 0xab3c2fddeeaad25a}, // 1e197 {0x8a71e223d8d3b074, 0xd60b3bd56a5586f1}, // 1e198 {0xf6872d5667844e49, 0x85c7056562757456}, // 1e199 {0xb428f8ac016561db, 0xa738c6bebb12d16c}, // 1e200 {0xe13336d701beba52, 0xd106f86e69d785c7}, // 1e201 {0xecc0024661173473, 0x82a45b450226b39c}, // 1e202 {0x27f002d7f95d0190, 0xa34d721642b06084}, // 1e203 {0x31ec038df7b441f4, 0xcc20ce9bd35c78a5}, // 1e204 {0x7e67047175a15271, 0xff290242c83396ce}, // 1e205 {0x0f0062c6e984d386, 0x9f79a169bd203e41}, // 1e206 {0x52c07b78a3e60868, 0xc75809c42c684dd1}, // 1e207 {0xa7709a56ccdf8a82, 0xf92e0c3537826145}, // 1e208 {0x88a66076400bb691, 0x9bbcc7a142b17ccb}, // 1e209 {0x6acff893d00ea435, 0xc2abf989935ddbfe}, // 1e210 {0x0583f6b8c4124d43, 0xf356f7ebf83552fe}, // 1e211 {0xc3727a337a8b704a, 0x98165af37b2153de}, // 1e212 {0x744f18c0592e4c5c, 0xbe1bf1b059e9a8d6}, // 1e213 {0x1162def06f79df73, 0xeda2ee1c7064130c}, // 1e214 {0x8addcb5645ac2ba8, 0x9485d4d1c63e8be7}, // 1e215 {0x6d953e2bd7173692, 0xb9a74a0637ce2ee1}, // 1e216 {0xc8fa8db6ccdd0437, 0xe8111c87c5c1ba99}, // 1e217 {0x1d9c9892400a22a2, 0x910ab1d4db9914a0}, // 1e218 {0x2503beb6d00cab4b, 0xb54d5e4a127f59c8}, // 1e219 {0x2e44ae64840fd61d, 0xe2a0b5dc971f303a}, // 1e220 {0x5ceaecfed289e5d2, 0x8da471a9de737e24}, // 1e221 {0x7425a83e872c5f47, 0xb10d8e1456105dad}, // 1e222 {0xd12f124e28f77719, 0xdd50f1996b947518}, // 1e223 {0x82bd6b70d99aaa6f, 0x8a5296ffe33cc92f}, // 1e224 {0x636cc64d1001550b, 0xace73cbfdc0bfb7b}, // 1e225 {0x3c47f7e05401aa4e, 0xd8210befd30efa5a}, // 1e226 {0x65acfaec34810a71, 0x8714a775e3e95c78}, // 1e227 {0x7f1839a741a14d0d, 0xa8d9d1535ce3b396}, // 1e228 {0x1ede48111209a050, 0xd31045a8341ca07c}, // 1e229 {0x934aed0aab460432, 0x83ea2b892091e44d}, // 1e230 {0xf81da84d5617853f, 0xa4e4b66b68b65d60}, // 1e231 {0x36251260ab9d668e, 0xce1de40642e3f4b9}, // 1e232 {0xc1d72b7c6b426019, 0x80d2ae83e9ce78f3}, // 1e233 {0xb24cf65b8612f81f, 0xa1075a24e4421730}, // 1e234 {0xdee033f26797b627, 0xc94930ae1d529cfc}, // 1e235 {0x169840ef017da3b1, 0xfb9b7cd9a4a7443c}, // 1e236 {0x8e1f289560ee864e, 0x9d412e0806e88aa5}, // 1e237 {0xf1a6f2bab92a27e2, 0xc491798a08a2ad4e}, // 1e238 {0xae10af696774b1db, 0xf5b5d7ec8acb58a2}, // 1e239 {0xacca6da1e0a8ef29, 0x9991a6f3d6bf1765}, // 1e240 {0x17fd090a58d32af3, 0xbff610b0cc6edd3f}, // 1e241 {0xddfc4b4cef07f5b0, 0xeff394dcff8a948e}, // 1e242 {0x4abdaf101564f98e, 0x95f83d0a1fb69cd9}, // 1e243 {0x9d6d1ad41abe37f1, 0xbb764c4ca7a4440f}, // 1e244 {0x84c86189216dc5ed, 0xea53df5fd18d5513}, // 1e245 {0x32fd3cf5b4e49bb4, 0x92746b9be2f8552c}, // 1e246 {0x3fbc8c33221dc2a1, 0xb7118682dbb66a77}, // 1e247 {0x0fabaf3feaa5334a, 0xe4d5e82392a40515}, // 1e248 {0x29cb4d87f2a7400e, 0x8f05b1163ba6832d}, // 1e249 {0x743e20e9ef511012, 0xb2c71d5bca9023f8}, // 1e250 {0x914da9246b255416, 0xdf78e4b2bd342cf6}, // 1e251 {0x1ad089b6c2f7548e, 0x8bab8eefb6409c1a}, // 1e252 {0xa184ac2473b529b1, 0xae9672aba3d0c320}, // 1e253 {0xc9e5d72d90a2741e, 0xda3c0f568cc4f3e8}, // 1e254 {0x7e2fa67c7a658892, 0x8865899617fb1871}, // 1e255 {0xddbb901b98feeab7, 0xaa7eebfb9df9de8d}, // 1e256 {0x552a74227f3ea565, 0xd51ea6fa85785631}, // 1e257 {0xd53a88958f87275f, 0x8533285c936b35de}, // 1e258 {0x8a892abaf368f137, 0xa67ff273b8460356}, // 1e259 {0x2d2b7569b0432d85, 0xd01fef10a657842c}, // 1e260 {0x9c3b29620e29fc73, 0x8213f56a67f6b29b}, // 1e261 {0x8349f3ba91b47b8f, 0xa298f2c501f45f42}, // 1e262 {0x241c70a936219a73, 0xcb3f2f7642717713}, // 1e263 {0xed238cd383aa0110, 0xfe0efb53d30dd4d7}, // 1e264 {0xf4363804324a40aa, 0x9ec95d1463e8a506}, // 1e265 {0xb143c6053edcd0d5, 0xc67bb4597ce2ce48}, // 1e266 {0xdd94b7868e94050a, 0xf81aa16fdc1b81da}, // 1e267 {0xca7cf2b4191c8326, 0x9b10a4e5e9913128}, // 1e268 {0xfd1c2f611f63a3f0, 0xc1d4ce1f63f57d72}, // 1e269 {0xbc633b39673c8cec, 0xf24a01a73cf2dccf}, // 1e270 {0xd5be0503e085d813, 0x976e41088617ca01}, // 1e271 {0x4b2d8644d8a74e18, 0xbd49d14aa79dbc82}, // 1e272 {0xddf8e7d60ed1219e, 0xec9c459d51852ba2}, // 1e273 {0xcabb90e5c942b503, 0x93e1ab8252f33b45}, // 1e274 {0x3d6a751f3b936243, 0xb8da1662e7b00a17}, // 1e275 {0x0cc512670a783ad4, 0xe7109bfba19c0c9d}, // 1e276 {0x27fb2b80668b24c5, 0x906a617d450187e2}, // 1e277 {0xb1f9f660802dedf6, 0xb484f9dc9641e9da}, // 1e278 {0x5e7873f8a0396973, 0xe1a63853bbd26451}, // 1e279 {0xdb0b487b6423e1e8, 0x8d07e33455637eb2}, // 1e280 {0x91ce1a9a3d2cda62, 0xb049dc016abc5e5f}, // 1e281 {0x7641a140cc7810fb, 0xdc5c5301c56b75f7}, // 1e282 {0xa9e904c87fcb0a9d, 0x89b9b3e11b6329ba}, // 1e283 {0x546345fa9fbdcd44, 0xac2820d9623bf429}, // 1e284 {0xa97c177947ad4095, 0xd732290fbacaf133}, // 1e285 {0x49ed8eabcccc485d, 0x867f59a9d4bed6c0}, // 1e286 {0x5c68f256bfff5a74, 0xa81f301449ee8c70}, // 1e287 {0x73832eec6fff3111, 0xd226fc195c6a2f8c}, // 1e288 }; static const double ms_atof_f64_powers_of_10[23] = { 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19, 1e20, 1e21, 1e22 }; static const uint16_t ms_atof_left_shift[65] = { 0x0000, 0x0800, 0x0801, 0x0803, 0x1006, 0x1009, 0x100D, 0x1812, 0x1817, 0x181D, 0x2024, 0x202B, 0x2033, 0x203C, 0x2846, 0x2850, 0x285B, 0x3067, 0x3073, 0x3080, 0x388E, 0x389C, 0x38AB, 0x38BB, 0x40CC, 0x40DD, 0x40EF, 0x4902, 0x4915, 0x4929, 0x513E, 0x5153, 0x5169, 0x5180, 0x5998, 0x59B0, 0x59C9, 0x61E3, 0x61FD, 0x6218, 0x6A34, 0x6A50, 0x6A6D, 0x6A8B, 0x72AA, 0x72C9, 0x72E9, 0x7B0A, 0x7B2B, 0x7B4D, 0x8370, 0x8393, 0x83B7, 0x83DC, 0x8C02, 0x8C28, 0x8C4F, 0x9477, 0x949F, 0x94C8, 0x9CF2, 0x051C, 0x051C, 0x051C, 0x051C }; static const uint8_t ms_atof_powers_of_5[1308] = { 5, 2, 5, 1, 2, 5, 6, 2, 5, 3, 1, 2, 5, 1, 5, 6, 2, 5, 7, 8, 1, 2, 5, 3, 9, 0, 6, 2, 5, 1, 9, 5, 3, 1, 2, 5, 9, 7, 6, 5, 6, 2, 5, 4, 8, 8, 2, 8, 1, 2, 5, 2, 4, 4, 1, 4, 0, 6, 2, 5, 1, 2, 2, 0, 7, 0, 3, 1, 2, 5, 6, 1, 0, 3, 5, 1, 5, 6, 2, 5, 3, 0, 5, 1, 7, 5, 7, 8, 1, 2, 5, 1, 5, 2, 5, 8, 7, 8, 9, 0, 6, 2, 5, 7, 6, 2, 9, 3, 9, 4, 5, 3, 1, 2, 5, 3, 8, 1, 4, 6, 9, 7, 2, 6, 5, 6, 2, 5, 1, 9, 0, 7, 3, 4, 8, 6, 3, 2, 8, 1, 2, 5, 9, 5, 3, 6, 7, 4, 3, 1, 6, 4, 0, 6, 2, 5, 4, 7, 6, 8, 3, 7, 1, 5, 8, 2, 0, 3, 1, 2, 5, 2, 3, 8, 4, 1, 8, 5, 7, 9, 1, 0, 1, 5, 6, 2, 5, 1, 1, 9, 2, 0, 9, 2, 8, 9, 5, 5, 0, 7, 8, 1, 2, 5, 5, 9, 6, 0, 4, 6, 4, 4, 7, 7, 5, 3, 9, 0, 6, 2, 5, 2, 9, 8, 0, 2, 3, 2, 2, 3, 8, 7, 6, 9, 5, 3, 1, 2, 5, 1, 4, 9, 0, 1, 1, 6, 1, 1, 9, 3, 8, 4, 7, 6, 5, 6, 2, 5, 7, 4, 5, 0, 5, 8, 0, 5, 9, 6, 9, 2, 3, 8, 2, 8, 1, 2, 5, 3, 7, 2, 5, 2, 9, 0, 2, 9, 8, 4, 6, 1, 9, 1, 4, 0, 6, 2, 5, 1, 8, 6, 2, 6, 4, 5, 1, 4, 9, 2, 3, 0, 9, 5, 7, 0, 3, 1, 2, 5, 9, 3, 1, 3, 2, 2, 5, 7, 4, 6, 1, 5, 4, 7, 8, 5, 1, 5, 6, 2, 5, 4, 6, 5, 6, 6, 1, 2, 8, 7, 3, 0, 7, 7, 3, 9, 2, 5, 7, 8, 1, 2, 5, 2, 3, 2, 8, 3, 0, 6, 4, 3, 6, 5, 3, 8, 6, 9, 6, 2, 8, 9, 0, 6, 2, 5, 1, 1, 6, 4, 1, 5, 3, 2, 1, 8, 2, 6, 9, 3, 4, 8, 1, 4, 4, 5, 3, 1, 2, 5, 5, 8, 2, 0, 7, 6, 6, 0, 9, 1, 3, 4, 6, 7, 4, 0, 7, 2, 2, 6, 5, 6, 2, 5, 2, 9, 1, 0, 3, 8, 3, 0, 4, 5, 6, 7, 3, 3, 7, 0, 3, 6, 1, 3, 2, 8, 1, 2, 5, 1, 4, 5, 5, 1, 9, 1, 5, 2, 2, 8, 3, 6, 6, 8, 5, 1, 8, 0, 6, 6, 4, 0, 6, 2, 5, 7, 2, 7, 5, 9, 5, 7, 6, 1, 4, 1, 8, 3, 4, 2, 5, 9, 0, 3, 3, 2, 0, 3, 1, 2, 5, 3, 6, 3, 7, 9, 7, 8, 8, 0, 7, 0, 9, 1, 7, 1, 2, 9, 5, 1, 6, 6, 0, 1, 5, 6, 2, 5, 1, 8, 1, 8, 9, 8, 9, 4, 0, 3, 5, 4, 5, 8, 5, 6, 4, 7, 5, 8, 3, 0, 0, 7, 8, 1, 2, 5, 9, 0, 9, 4, 9, 4, 7, 0, 1, 7, 7, 2, 9, 2, 8, 2, 3, 7, 9, 1, 5, 0, 3, 9, 0, 6, 2, 5, 4, 5, 4, 7, 4, 7, 3, 5, 0, 8, 8, 6, 4, 6, 4, 1, 1, 8, 9, 5, 7, 5, 1, 9, 5, 3, 1, 2, 5, 2, 2, 7, 3, 7, 3, 6, 7, 5, 4, 4, 3, 2, 3, 2, 0, 5, 9, 4, 7, 8, 7, 5, 9, 7, 6, 5, 6, 2, 5, 1, 1, 3, 6, 8, 6, 8, 3, 7, 7, 2, 1, 6, 1, 6, 0, 2, 9, 7, 3, 9, 3, 7, 9, 8, 8, 2, 8, 1, 2, 5, 5, 6, 8, 4, 3, 4, 1, 8, 8, 6, 0, 8, 0, 8, 0, 1, 4, 8, 6, 9, 6, 8, 9, 9, 4, 1, 4, 0, 6, 2, 5, 2, 8, 4, 2, 1, 7, 0, 9, 4, 3, 0, 4, 0, 4, 0, 0, 7, 4, 3, 4, 8, 4, 4, 9, 7, 0, 7, 0, 3, 1, 2, 5, 1, 4, 2, 1, 0, 8, 5, 4, 7, 1, 5, 2, 0, 2, 0, 0, 3, 7, 1, 7, 4, 2, 2, 4, 8, 5, 3, 5, 1, 5, 6, 2, 5, 7, 1, 0, 5, 4, 2, 7, 3, 5, 7, 6, 0, 1, 0, 0, 1, 8, 5, 8, 7, 1, 1, 2, 4, 2, 6, 7, 5, 7, 8, 1, 2, 5, 3, 5, 5, 2, 7, 1, 3, 6, 7, 8, 8, 0, 0, 5, 0, 0, 9, 2, 9, 3, 5, 5, 6, 2, 1, 3, 3, 7, 8, 9, 0, 6, 2, 5, 1, 7, 7, 6, 3, 5, 6, 8, 3, 9, 4, 0, 0, 2, 5, 0, 4, 6, 4, 6, 7, 7, 8, 1, 0, 6, 6, 8, 9, 4, 5, 3, 1, 2, 5, 8, 8, 8, 1, 7, 8, 4, 1, 9, 7, 0, 0, 1, 2, 5, 2, 3, 2, 3, 3, 8, 9, 0, 5, 3, 3, 4, 4, 7, 2, 6, 5, 6, 2, 5, 4, 4, 4, 0, 8, 9, 2, 0, 9, 8, 5, 0, 0, 6, 2, 6, 1, 6, 1, 6, 9, 4, 5, 2, 6, 6, 7, 2, 3, 6, 3, 2, 8, 1, 2, 5, 2, 2, 2, 0, 4, 4, 6, 0, 4, 9, 2, 5, 0, 3, 1, 3, 0, 8, 0, 8, 4, 7, 2, 6, 3, 3, 3, 6, 1, 8, 1, 6, 4, 0, 6, 2, 5, 1, 1, 1, 0, 2, 2, 3, 0, 2, 4, 6, 2, 5, 1, 5, 6, 5, 4, 0, 4, 2, 3, 6, 3, 1, 6, 6, 8, 0, 9, 0, 8, 2, 0, 3, 1, 2, 5, 5, 5, 5, 1, 1, 1, 5, 1, 2, 3, 1, 2, 5, 7, 8, 2, 7, 0, 2, 1, 1, 8, 1, 5, 8, 3, 4, 0, 4, 5, 4, 1, 0, 1, 5, 6, 2, 5, 2, 7, 7, 5, 5, 5, 7, 5, 6, 1, 5, 6, 2, 8, 9, 1, 3, 5, 1, 0, 5, 9, 0, 7, 9, 1, 7, 0, 2, 2, 7, 0, 5, 0, 7, 8, 1, 2, 5, 1, 3, 8, 7, 7, 7, 8, 7, 8, 0, 7, 8, 1, 4, 4, 5, 6, 7, 5, 5, 2, 9, 5, 3, 9, 5, 8, 5, 1, 1, 3, 5, 2, 5, 3, 9, 0, 6, 2, 5, 6, 9, 3, 8, 8, 9, 3, 9, 0, 3, 9, 0, 7, 2, 2, 8, 3, 7, 7, 6, 4, 7, 6, 9, 7, 9, 2, 5, 5, 6, 7, 6, 2, 6, 9, 5, 3, 1, 2, 5, 3, 4, 6, 9, 4, 4, 6, 9, 5, 1, 9, 5, 3, 6, 1, 4, 1, 8, 8, 8, 2, 3, 8, 4, 8, 9, 6, 2, 7, 8, 3, 8, 1, 3, 4, 7, 6, 5, 6, 2, 5, 1, 7, 3, 4, 7, 2, 3, 4, 7, 5, 9, 7, 6, 8, 0, 7, 0, 9, 4, 4, 1, 1, 9, 2, 4, 4, 8, 1, 3, 9, 1, 9, 0, 6, 7, 3, 8, 2, 8, 1, 2, 5, 8, 6, 7, 3, 6, 1, 7, 3, 7, 9, 8, 8, 4, 0, 3, 5, 4, 7, 2, 0, 5, 9, 6, 2, 2, 4, 0, 6, 9, 5, 9, 5, 3, 3, 6, 9, 1, 4, 0, 6, 2, 5 }; #endif python-msgspec-0.22.0/src/msgspec/common.h000066400000000000000000000010161525673062400204540ustar00rootroot00000000000000#ifndef MS_COMMON_H #define MS_COMMON_H #ifdef __GNUC__ #define MS_LIKELY(pred) __builtin_expect(!!(pred), 1) #define MS_UNLIKELY(pred) __builtin_expect(!!(pred), 0) #else #define MS_LIKELY(pred) (pred) #define MS_UNLIKELY(pred) (pred) #endif #ifdef __GNUC__ #define MS_INLINE __attribute__((always_inline)) inline #define MS_NOINLINE __attribute__((noinline)) #elif defined(_MSC_VER) #define MS_INLINE __forceinline #define MS_NOINLINE __declspec(noinline) #else #define MS_INLINE inline #define MS_NOINLINE #endif #endif python-msgspec-0.22.0/src/msgspec/inspect.py000066400000000000000000000727401525673062400210460ustar00rootroot00000000000000from __future__ import annotations import datetime import decimal import enum import sys import uuid from collections.abc import Iterable from types import UnionType as _types_UnionType from typing import Any, Final, Literal, TypeVar, Union try: from typing import TypeAliasType as _TypeAliasType # type: ignore except Exception: _TypeAliasType = type("TypeAliasType", (), {}) # type: ignore import msgspec from msgspec import NODEFAULT, UNSET, UnsetType as _UnsetType from ._core import ( # type: ignore Factory as _Factory, to_builtins as _to_builtins, ) from ._typing_utils import is_struct, is_struct_type from ._utils import ( # type: ignore _CONCRETE_TYPES, _AnnotatedAlias, get_class_annotations as _get_class_annotations, get_dataclass_info as _get_dataclass_info, get_typeddict_info as _get_typeddict_info, ) __all__ = ( "type_info", "multi_type_info", "Type", "Metadata", "AnyType", "NoneType", "BoolType", "IntType", "FloatType", "StrType", "BytesType", "ByteArrayType", "MemoryViewType", "DateTimeType", "TimeType", "DateType", "TimeDeltaType", "UUIDType", "DecimalType", "ExtType", "RawType", "EnumType", "LiteralType", "CustomType", "UnionType", "CollectionType", "ListType", "SetType", "FrozenSetType", "VarTupleType", "TupleType", "DictType", "Field", "TypedDictType", "NamedTupleType", "DataclassType", "StructType", "is_struct", "is_struct_type", "FrozenDictType", ) _PY315_PLUS = sys.version_info >= (3, 15) def __dir__(): return __all__ class Type(msgspec.Struct): """The base Type.""" class Metadata(Type): """A type wrapping a subtype with additional metadata. Parameters ---------- type: Type The subtype. extra_json_schema: dict, optional A dict of extra fields to set for the subtype when generating a json-schema. extra: dict, optional A dict of extra user-defined metadata attached to the subtype. """ type: Type extra_json_schema: dict | None = None extra: dict | None = None class AnyType(Type): """A type corresponding to `typing.Any`.""" class NoneType(Type): """A type corresponding to `None`.""" class BoolType(Type): """A type corresponding to `bool`.""" class IntType(Type): """A type corresponding to `int`. Parameters ---------- gt: int, optional If set, an instance of this type must be greater than ``gt``. ge: int, optional If set, an instance of this type must be greater than or equal to ``ge``. lt: int, optional If set, an instance of this type must be less than to ``lt``. le: int, optional If set, an instance of this type must be less than or equal to ``le``. multiple_of: int, optional If set, an instance of this type must be a multiple of ``multiple_of``. """ gt: int | None = None ge: int | None = None lt: int | None = None le: int | None = None multiple_of: int | None = None class FloatType(Type): """A type corresponding to `float`. Parameters ---------- gt: float, optional If set, an instance of this type must be greater than ``gt``. ge: float, optional If set, an instance of this type must be greater than or equal to ``ge``. lt: float, optional If set, an instance of this type must be less than to ``lt``. le: float, optional If set, an instance of this type must be less than or equal to ``le``. multiple_of: float, optional If set, an instance of this type must be a multiple of ``multiple_of``. """ gt: float | None = None ge: float | None = None lt: float | None = None le: float | None = None multiple_of: float | None = None class StrType(Type): """A type corresponding to `str`. Parameters ---------- min_length: int, optional If set, an instance of this type must have length greater than or equal to ``min_length``. max_length: int, optional If set, an instance of this type must have length less than or equal to ``max_length``. pattern: str, optional If set, an instance of this type must match against this regex pattern. Note that the pattern is treated as **unanchored**. """ min_length: int | None = None max_length: int | None = None pattern: str | None = None class BytesType(Type): """A type corresponding to `bytes`. Parameters ---------- min_length: int, optional If set, an instance of this type must have length greater than or equal to ``min_length``. max_length: int, optional If set, an instance of this type must have length less than or equal to ``max_length``. """ min_length: int | None = None max_length: int | None = None class ByteArrayType(Type): """A type corresponding to `bytearray`. Parameters ---------- min_length: int, optional If set, an instance of this type must have length greater than or equal to ``min_length``. max_length: int, optional If set, an instance of this type must have length less than or equal to ``max_length``. """ min_length: int | None = None max_length: int | None = None class MemoryViewType(Type): """A type corresponding to `memoryview`. Parameters ---------- min_length: int, optional If set, an instance of this type must have length greater than or equal to ``min_length``. max_length: int, optional If set, an instance of this type must have length less than or equal to ``max_length``. """ min_length: int | None = None max_length: int | None = None class DateTimeType(Type): """A type corresponding to `datetime.datetime`. Parameters ---------- tz: bool The timezone-requirements for an instance of this type. ``True`` indicates a timezone-aware value is required, ``False`` indicates a timezone-naive value is required. The default is ``None``, which accepts either timezone-aware or timezone-naive values. """ tz: bool | None = None class TimeType(Type): """A type corresponding to `datetime.time`. Parameters ---------- tz: bool The timezone-requirements for an instance of this type. ``True`` indicates a timezone-aware value is required, ``False`` indicates a timezone-aware value is required. The default is ``None``, which accepts either timezone-aware or timezone-naive values. """ tz: bool | None = None class DateType(Type): """A type corresponding to `datetime.date`.""" class TimeDeltaType(Type): """A type corresponding to `datetime.timedelta`.""" class UUIDType(Type): """A type corresponding to `uuid.UUID`.""" class DecimalType(Type): """A type corresponding to `decimal.Decimal`.""" class ExtType(Type): """A type corresponding to `msgspec.msgpack.Ext`.""" class RawType(Type): """A type corresponding to `msgspec.Raw`.""" class EnumType(Type): """A type corresponding to an `enum.Enum` type. Parameters ---------- cls: type The corresponding `enum.Enum` type. """ cls: type[enum.Enum] class LiteralType(Type): """A type corresponding to a `typing.Literal` type. Parameters ---------- values: tuple A tuple of possible values for this literal instance. Only `bool`, `str`, `int`, or `None` literals are supported, and a single literal may mix these types (e.g. ``Literal[1, None]``). """ values: tuple[bool | str | int | None, ...] class CustomType(Type): """A custom type. Parameters ---------- cls: type The corresponding custom type. """ cls: type class UnionType(Type): """A union type. Parameters ---------- types: tuple[type, ...] A tuple of possible types for this union. """ types: tuple[Type, ...] @property def includes_none(self) -> bool: """A helper for checking whether ``None`` is included in this union.""" return any(isinstance(t, NoneType) for t in self.types) class CollectionType(Type): """A collection type. This is the base type shared by collection types like `ListType`, `SetType`, etc. Parameters ---------- item_type: Type The item type. min_length: int, optional If set, an instance of this type must have length greater than or equal to ``min_length``. max_length: int, optional If set, an instance of this type must have length less than or equal to ``max_length``. """ item_type: Type min_length: int | None = None max_length: int | None = None class ListType(CollectionType): """A type corresponding to a `list`. Parameters ---------- item_type: Type The item type. min_length: int, optional If set, an instance of this type must have length greater than or equal to ``min_length``. max_length: int, optional If set, an instance of this type must have length less than or equal to ``max_length``. """ class VarTupleType(CollectionType): """A type corresponding to a variadic `tuple`. Parameters ---------- item_type: Type The item type. min_length: int, optional If set, an instance of this type must have length greater than or equal to ``min_length``. max_length: int, optional If set, an instance of this type must have length less than or equal to ``max_length``. """ class SetType(CollectionType): """A type corresponding to a `set`. Parameters ---------- item_type: Type The item type. min_length: int, optional If set, an instance of this type must have length greater than or equal to ``min_length``. max_length: int, optional If set, an instance of this type must have length less than or equal to ``max_length``. """ class FrozenSetType(CollectionType): """A type corresponding to a `frozenset`. Parameters ---------- item_type: Type The item type. min_length: int, optional If set, an instance of this type must have length greater than or equal to ``min_length``. max_length: int, optional If set, an instance of this type must have length less than or equal to ``max_length``. """ class TupleType(Type): """A type corresponding to `tuple`. Parameters ---------- item_types: tuple[Type, ...] A tuple of types for each element in the tuple. """ item_types: tuple[Type, ...] class DictType(Type): """A type corresponding to `dict`. Parameters ---------- key_type: Type The key type. value_type: Type The value type. min_length: int, optional If set, an instance of this type must have length greater than or equal to ``min_length``. max_length: int, optional If set, an instance of this type must have length less than or equal to ``max_length``. """ key_type: Type value_type: Type min_length: int | None = None max_length: int | None = None class FrozenDictType(Type): """A type corresponding to `frozendict`. Can only be emitted on Python 3.15+. Parameters ---------- key_type: Type The key type. value_type: Type The value type. min_length: int, optional If set, an instance of this type must have length greater than or equal to ``min_length``. max_length: int, optional If set, an instance of this type must have length less than or equal to ``max_length``. """ key_type: Type value_type: Type min_length: Union[int, None] = None max_length: Union[int, None] = None class Field(msgspec.Struct): """A record describing a field in an object-like type. Parameters ---------- name: str The field name as seen by Python code (e.g. ``field_one``). encode_name: str The name used when encoding/decoding the field. This may differ if the field is renamed (e.g. ``fieldOne``). type: Type The field type. required: bool, optional Whether the field is required. Note that if `required` is False doesn't necessarily mean that `default` or `default_factory` will be set - optional fields may exist with no default value. default: Any, optional A default value for the field. Will be `NODEFAULT` if no default value is set. default_factory: Any, optional A callable that creates a default value for the field. Will be `NODEFAULT` if no ``default_factory`` is set. """ name: str encode_name: str type: Type required: bool = True default: Any = msgspec.field(default_factory=lambda: NODEFAULT) default_factory: Any = msgspec.field(default_factory=lambda: NODEFAULT) class TypedDictType(Type): """A type corresponding to a `typing.TypedDict` type. Parameters ---------- cls: type The corresponding TypedDict type. fields: tuple[Field, ...] A tuple of fields in the TypedDict. """ cls: type fields: tuple[Field, ...] class NamedTupleType(Type): """A type corresponding to a `typing.NamedTuple` type. Parameters ---------- cls: type The corresponding NamedTuple type. fields: tuple[Field, ...] A tuple of fields in the NamedTuple. """ cls: type fields: tuple[Field, ...] class DataclassType(Type): """A type corresponding to a `dataclasses` or `attrs` type. Parameters ---------- cls: type The corresponding dataclass type. fields: tuple[Field, ...] A tuple of fields in the dataclass. """ cls: type fields: tuple[Field, ...] class StructType(Type): """A type corresponding to a `msgspec.Struct` type. Parameters ---------- cls: type The corresponding Struct type. fields: tuple[Field, ...] A tuple of fields in the Struct. tag_field: str or None, optional If set, the field name used for the tag in a tagged union. tag: str, int, or None, optional If set, the value used for the tag in a tagged union. array_like: bool, optional Whether the struct is encoded as an array rather than an object. forbid_unknown_fields: bool, optional If ``False`` (the default) unknown fields are ignored when decoding. If ``True`` any unknown fields will result in an error. """ cls: type[msgspec.Struct] fields: tuple[Field, ...] tag_field: str | None = None tag: str | int | None = None array_like: bool = False forbid_unknown_fields: bool = False def multi_type_info(types: Iterable[Any]) -> tuple[Type, ...]: """Get information about multiple msgspec-compatible types. Parameters ---------- types: an iterable of types The types to get info about. Returns ------- tuple[Type, ...] Examples -------- >>> msgspec.inspect.multi_type_info([int, float, list[str]]) # doctest: +NORMALIZE_WHITESPACE (IntType(gt=None, ge=None, lt=None, le=None, multiple_of=None), FloatType(gt=None, ge=None, lt=None, le=None, multiple_of=None), ListType(item_type=StrType(min_length=None, max_length=None, pattern=None), min_length=None, max_length=None)) """ return _Translator(types).run() def type_info(type: Any) -> Type: """Get information about a msgspec-compatible type. Note that if you need to inspect multiple types it's more efficient to call `multi_type_info` once with a sequence of types than calling `type_info` multiple times. Parameters ---------- type: type The type to get info about. Returns ------- Type Examples -------- >>> msgspec.inspect.type_info(bool) BoolType() >>> msgspec.inspect.type_info(int) IntType(gt=None, ge=None, lt=None, le=None, multiple_of=None) >>> msgspec.inspect.type_info(list[int]) # doctest: +NORMALIZE_WHITESPACE ListType(item_type=IntType(gt=None, ge=None, lt=None, le=None, multiple_of=None), min_length=None, max_length=None) """ return multi_type_info([type])[0] # Implementation details def _origin_args_metadata(t): # Strip wrappers (Annotated, NewType, Final) until we hit a concrete type metadata = [] while True: try: origin = _CONCRETE_TYPES.get(t) except TypeError: # t is not hashable origin = None if origin is not None: args = None break origin = getattr(t, "__origin__", None) if origin is not None: if type(t) is _AnnotatedAlias: metadata.extend(m for m in t.__metadata__ if type(m) is msgspec.Meta) t = origin elif origin == Final: t = t.__args__[0] elif type(origin) is _TypeAliasType: t = origin.__value__[t.__args__] else: args = getattr(t, "__args__", None) origin = _CONCRETE_TYPES.get(origin, origin) break else: supertype = getattr(t, "__supertype__", None) if supertype is not None: t = supertype elif type(t) is _TypeAliasType: t = t.__value__ else: origin = t args = None break if type(origin) is _types_UnionType: args = origin.__args__ origin = Union return origin, args, tuple(metadata) def _sort_literal_args(args): # `Literal` may mix value types (e.g. `Literal[1, None]`), which a plain # `sorted` can't order since Python 3 forbids comparing across types. Sort # by type name first so members of the same type stay ordered as before, # while mixed-type literals are grouped deterministically instead of # crashing. try: return tuple(sorted(args, key=lambda x: (type(x).__name__, x))) except TypeError: return tuple(args) def _is_enum(t): return type(t) is enum.EnumMeta def _is_dataclass(t): return hasattr(t, "__dataclass_fields__") def _is_attrs(t): return hasattr(t, "__attrs_attrs__") def _is_typeddict(t): try: return issubclass(t, dict) and hasattr(t, "__total__") except TypeError: return False def _is_namedtuple(t): try: return issubclass(t, tuple) and hasattr(t, "_fields") except TypeError: return False def _merge_json(a, b): if b: a = a.copy() for key, b_val in b.items(): if key in a: a_val = a[key] if isinstance(a_val, dict) and isinstance(b_val, dict): a[key] = _merge_json(a_val, b_val) elif isinstance(a_val, (list, tuple)) and isinstance( b_val, (list, tuple) ): a[key] = list(a_val) + list(b_val) else: a[key] = b_val else: a[key] = b_val return a class _Translator: def __init__(self, types): self.types = tuple(types) self.type_hints = {} self.cache = {} def _get_class_annotations(self, t): """A cached version of `get_class_annotations`""" try: return self.type_hints[t] except KeyError: out = self.type_hints[t] = _get_class_annotations(t) return out def run(self): # First construct a decoder to validate the types are valid from ._core import MsgpackDecoder MsgpackDecoder(tuple[self.types]) return tuple(self.translate(t) for t in self.types) def translate(self, typ): t, args, metadata = _origin_args_metadata(typ) # Extract and merge components of any `Meta` annotations constrs = {} extra_json_schema = {} extra = {} for meta in metadata: for attr in ( "ge", "gt", "le", "lt", "multiple_of", "pattern", "min_length", "max_length", "tz", ): if (val := getattr(meta, attr)) is not None: constrs[attr] = val for attr in ("title", "description", "examples"): if (val := getattr(meta, attr)) is not None: extra_json_schema[attr] = val if meta.extra_json_schema is not None: extra_json_schema = _merge_json( extra_json_schema, _to_builtins(meta.extra_json_schema, str_keys=True), ) if meta.extra is not None: extra.update(meta.extra) out = self._translate_inner(t, args, **constrs) if extra_json_schema or extra: # If extra metadata is present, wrap the output type in a Metadata # wrapper object return Metadata( out, extra_json_schema=extra_json_schema or None, extra=extra or None ) return out def _translate_inner( self, t, args, ge=None, gt=None, le=None, lt=None, multiple_of=None, pattern=None, min_length=None, max_length=None, tz=None, ): if t is Any: return AnyType() elif isinstance(t, TypeVar): if t.__bound__ is not None: return self.translate(t.__bound__) return AnyType() elif t is None or t is type(None): return NoneType() elif t is bool: return BoolType() elif t is int: return IntType(ge=ge, gt=gt, le=le, lt=lt, multiple_of=multiple_of) elif t is float: return FloatType(ge=ge, gt=gt, le=le, lt=lt, multiple_of=multiple_of) elif t is str: return StrType( min_length=min_length, max_length=max_length, pattern=pattern ) elif t is bytes: return BytesType(min_length=min_length, max_length=max_length) elif t is bytearray: return ByteArrayType(min_length=min_length, max_length=max_length) elif t is memoryview: return MemoryViewType(min_length=min_length, max_length=max_length) elif t is datetime.datetime: return DateTimeType(tz=tz) elif t is datetime.time: return TimeType(tz=tz) elif t is datetime.date: return DateType() elif t is datetime.timedelta: return TimeDeltaType() elif t is uuid.UUID: return UUIDType() elif t is decimal.Decimal: return DecimalType() elif t is msgspec.Raw: return RawType() elif t is msgspec.msgpack.Ext: return ExtType() elif t is list: return ListType( self.translate(args[0]) if args else AnyType(), min_length=min_length, max_length=max_length, ) elif t is set: return SetType( self.translate(args[0]) if args else AnyType(), min_length=min_length, max_length=max_length, ) elif t is frozenset: return FrozenSetType( self.translate(args[0]) if args else AnyType(), min_length=min_length, max_length=max_length, ) elif t is tuple: # Handle an annoying compatibility issue: # - Tuple[()] has args == ((),) # - tuple[()] has args == () if args == ((),): args = () if args is None: return VarTupleType( AnyType(), min_length=min_length, max_length=max_length ) elif len(args) == 2 and args[-1] is ...: return VarTupleType( self.translate(args[0]), min_length=min_length, max_length=max_length, ) else: return TupleType(tuple(self.translate(a) for a in args)) elif t is dict: return DictType( self.translate(args[0]) if args else AnyType(), self.translate(args[1]) if args else AnyType(), min_length=min_length, max_length=max_length, ) elif _PY315_PLUS and t is frozendict: # noqa: F821 return FrozenDictType( self.translate(args[0]) if args else AnyType(), self.translate(args[1]) if args else AnyType(), min_length=min_length, max_length=max_length, ) elif t is Union: args = tuple(self.translate(a) for a in args if a is not _UnsetType) return args[0] if len(args) == 1 else UnionType(args) elif t is Literal: return LiteralType(_sort_literal_args(args)) elif _is_enum(t): return EnumType(t) elif is_struct_type(t): cls = t[args] if args else t if cls in self.cache: return self.cache[cls] config = t.__struct_config__ self.cache[cls] = out = StructType( cls, (), tag_field=config.tag_field, tag=config.tag, array_like=config.array_like, forbid_unknown_fields=config.forbid_unknown_fields, ) hints = self._get_class_annotations(cls) npos = len(t.__struct_fields__) - len(t.__struct_defaults__) fields = [] for name, encode_name, default_obj in zip( t.__struct_fields__, t.__struct_encode_fields__, (NODEFAULT,) * npos + t.__struct_defaults__, ): if default_obj is NODEFAULT: required = True default = default_factory = NODEFAULT elif isinstance(default_obj, _Factory): required = False default = NODEFAULT default_factory = default_obj.factory else: required = False default = NODEFAULT if default_obj is UNSET else default_obj default_factory = NODEFAULT field = Field( name=name, encode_name=encode_name, type=self.translate(hints[name]), required=required, default=default, default_factory=default_factory, ) fields.append(field) out.fields = tuple(fields) return out elif _is_typeddict(t): cls = t[args] if args else t if cls in self.cache: return self.cache[cls] self.cache[cls] = out = TypedDictType(cls, ()) hints, required = _get_typeddict_info(cls) out.fields = tuple( Field( name=name, encode_name=name, type=self.translate(field_type), required=name in required, ) for name, field_type in sorted(hints.items()) ) return out elif _is_dataclass(t) or _is_attrs(t): cls = t[args] if args else t if cls in self.cache: return self.cache[cls] self.cache[cls] = out = DataclassType(cls, ()) _, info, defaults, _, _ = _get_dataclass_info(cls) defaults = ((NODEFAULT,) * (len(info) - len(defaults))) + defaults fields = [] for (name, typ, is_factory), default_obj in zip(info, defaults): if default_obj is NODEFAULT: required = True default = default_factory = NODEFAULT elif is_factory: required = False default = NODEFAULT default_factory = default_obj else: required = False default = NODEFAULT if default_obj is UNSET else default_obj default_factory = NODEFAULT fields.append( Field( name=name, encode_name=name, type=self.translate(typ), required=required, default=default, default_factory=default_factory, ) ) out.fields = tuple(fields) return out elif _is_namedtuple(t): cls = t[args] if args else t if cls in self.cache: return self.cache[cls] self.cache[cls] = out = NamedTupleType(cls, ()) hints = self._get_class_annotations(cls) out.fields = tuple( Field( name=name, encode_name=name, type=self.translate(hints.get(name, Any)), required=name not in t._field_defaults, default=t._field_defaults.get(name, NODEFAULT), ) for name in t._fields ) return out else: return CustomType(t) python-msgspec-0.22.0/src/msgspec/itoa.h000066400000000000000000000210251525673062400201220ustar00rootroot00000000000000/* This code is a modified and condensed version of the int -> str routines * found in yyjson (https://github.com/ibireme/yyjson). The yyjson license * is copied below: * * Copyright (c) 2020 YaoYuan * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ #ifndef MS_ITOA_H #define MS_ITOA_H #include #include "common.h" static const char DIGIT_TABLE[200] = { '0','0','0','1','0','2','0','3','0','4','0','5','0','6','0','7','0','8','0','9', '1','0','1','1','1','2','1','3','1','4','1','5','1','6','1','7','1','8','1','9', '2','0','2','1','2','2','2','3','2','4','2','5','2','6','2','7','2','8','2','9', '3','0','3','1','3','2','3','3','3','4','3','5','3','6','3','7','3','8','3','9', '4','0','4','1','4','2','4','3','4','4','4','5','4','6','4','7','4','8','4','9', '5','0','5','1','5','2','5','3','5','4','5','5','5','6','5','7','5','8','5','9', '6','0','6','1','6','2','6','3','6','4','6','5','6','6','6','7','6','8','6','9', '7','0','7','1','7','2','7','3','7','4','7','5','7','6','7','7','7','8','7','9', '8','0','8','1','8','2','8','3','8','4','8','5','8','6','8','7','8','8','8','9', '9','0','9','1','9','2','9','3','9','4','9','5','9','6','9','7','9','8','9','9' }; static MS_INLINE void write_u32_8_digits(uint32_t x, char *buf) { uint32_t aabb, ccdd, aa, bb, cc, dd; aabb = (uint32_t)(((uint64_t)x * 109951163) >> 40); /* (x / 10000) */ ccdd = x - aabb * 10000; /* (x % 10000) */ aa = (aabb * 5243) >> 19; /* (aabb / 100) */ bb = aabb - aa * 100; /* (aabb % 100) */ cc = (ccdd * 5243) >> 19; /* (ccdd / 100) */ dd = ccdd - cc * 100; /* (ccdd % 100) */ memcpy(buf + 0, DIGIT_TABLE + aa * 2, 2); memcpy(buf + 2, DIGIT_TABLE + bb * 2, 2); memcpy(buf + 4, DIGIT_TABLE + cc * 2, 2); memcpy(buf + 6, DIGIT_TABLE + dd * 2, 2); } static MS_INLINE void write_u32_6_digits(uint32_t x, char *buf) { uint32_t aa, bbcc, bb, cc; aa = (uint32_t)(((uint64_t)x * 109951163) >> 40); /* (x / 10000) */ bbcc = x - aa * 10000; /* (x % 10000) */ bb = (bbcc * 5243) >> 19; /* (bbcc / 100) */ cc = bbcc - bb * 100; /* (bbcc % 100) */ memcpy(buf + 0, DIGIT_TABLE + aa * 2, 2); memcpy(buf + 2, DIGIT_TABLE + bb * 2, 2); memcpy(buf + 4, DIGIT_TABLE + cc * 2, 2); } static MS_INLINE void write_u32_4_digits(uint32_t x, char *buf) { uint32_t aa, bb; aa = (x * 5243) >> 19; /* (x / 100) */ bb = x - aa * 100; /* (x % 100) */ memcpy(buf + 0, DIGIT_TABLE + aa * 2, 2); memcpy(buf + 2, DIGIT_TABLE + bb * 2, 2); } static MS_INLINE void write_u32_2_digits(uint32_t x, char *buf) { memcpy(buf, DIGIT_TABLE + x * 2, 2); } static MS_INLINE char * write_u32_1_to_8_digits(uint32_t x, char *buf) { uint32_t aa, bb, cc, dd, aabb, bbcc, ccdd, lz; if (x < 100) { /* 1-2 digits */ lz = x < 10; memcpy(buf + 0, DIGIT_TABLE + x * 2 + lz, 2); buf -= lz; return buf + 2; } else if (x < 10000) { /* 3-4 digits */ aa = (x * 5243) >> 19; /* (x / 100) */ bb = x - aa * 100; /* (x % 100) */ lz = aa < 10; memcpy(buf + 0, DIGIT_TABLE + aa * 2 + lz, 2); buf -= lz; memcpy(buf + 2, DIGIT_TABLE + bb * 2, 2); return buf + 4; } else if (x < 1000000) { /* 5-6 digits */ aa = (uint32_t)(((uint64_t)x * 429497) >> 32); /* (x / 10000) */ bbcc = x - aa * 10000; /* (x % 10000) */ bb = (bbcc * 5243) >> 19; /* (bbcc / 100) */ cc = bbcc - bb * 100; /* (bbcc % 100) */ lz = aa < 10; memcpy(buf + 0, DIGIT_TABLE + aa * 2 + lz, 2); buf -= lz; memcpy(buf + 2, DIGIT_TABLE + bb * 2, 2); memcpy(buf + 4, DIGIT_TABLE + cc * 2, 2); return buf + 6; } else { /* 7-8 digits */ aabb = (uint32_t)(((uint64_t)x * 109951163) >> 40); /* (x / 10000) */ ccdd = x - aabb * 10000; /* (x % 10000) */ aa = (aabb * 5243) >> 19; /* (aabb / 100) */ bb = aabb - aa * 100; /* (aabb % 100) */ cc = (ccdd * 5243) >> 19; /* (ccdd / 100) */ dd = ccdd - cc * 100; /* (ccdd % 100) */ lz = aa < 10; memcpy(buf + 0, DIGIT_TABLE + aa * 2 + lz, 2); buf -= lz; memcpy(buf + 2, DIGIT_TABLE + bb * 2, 2); memcpy(buf + 4, DIGIT_TABLE + cc * 2, 2); memcpy(buf + 6, DIGIT_TABLE + dd * 2, 2); return buf + 8; } } static MS_INLINE char * write_u64_5_to_8_digits(uint32_t x, char *buf) { uint32_t aa, bb, cc, dd, aabb, bbcc, ccdd, lz; if (x < 1000000) { /* 5-6 digits */ aa = (uint32_t)(((uint64_t)x * 429497) >> 32); /* (x / 10000) */ bbcc = x - aa * 10000; /* (x % 10000) */ bb = (bbcc * 5243) >> 19; /* (bbcc / 100) */ cc = bbcc - bb * 100; /* (bbcc % 100) */ lz = aa < 10; memcpy(buf + 0, DIGIT_TABLE + aa * 2 + lz, 2); buf -= lz; memcpy(buf + 2, DIGIT_TABLE + bb * 2, 2); memcpy(buf + 4, DIGIT_TABLE + cc * 2, 2); return buf + 6; } else { /* 7-8 digits */ aabb = (uint32_t)(((uint64_t)x * 109951163) >> 40); /* (x / 10000) */ ccdd = x - aabb * 10000; /* (x % 10000) */ aa = (aabb * 5243) >> 19; /* (aabb / 100) */ bb = aabb - aa * 100; /* (aabb % 100) */ cc = (ccdd * 5243) >> 19; /* (ccdd / 100) */ dd = ccdd - cc * 100; /* (ccdd % 100) */ lz = aa < 10; memcpy(buf + 0, DIGIT_TABLE + aa * 2 + lz, 2); buf -= lz; memcpy(buf + 2, DIGIT_TABLE + bb * 2, 2); memcpy(buf + 4, DIGIT_TABLE + cc * 2, 2); memcpy(buf + 6, DIGIT_TABLE + dd * 2, 2); return buf + 8; } } /* Write a uint64 to buf, requires 20 bytes of space */ static inline char * write_u64(uint64_t x, char *buf) { uint64_t tmp, hgh; uint32_t mid, low; if (x < 100000000) { /* 1-8 digits */ return write_u32_1_to_8_digits((uint32_t)x, buf); } else if (x < (uint64_t)100000000 * 100000000) { /* 9-16 digits */ hgh = x / 100000000; /* (x / 100000000) */ low = (uint32_t)(x - hgh * 100000000); /* (x % 100000000) */ char *cur = write_u32_1_to_8_digits((uint32_t)hgh, buf); write_u32_8_digits(low, cur); return cur + 8; } else { /* 17-20 digits */ tmp = x / 100000000; /* (x / 100000000) */ low = (uint32_t)(x - tmp * 100000000); /* (x % 100000000) */ hgh = (uint32_t)(tmp / 10000); /* (tmp / 10000) */ mid = (uint32_t)(tmp - hgh * 10000); /* (tmp % 10000) */ char *cur = write_u64_5_to_8_digits((uint32_t)hgh, buf); write_u32_4_digits(mid, cur); write_u32_8_digits(low, cur + 4); return cur + 12; } } #endif // MS_ITOA_H python-msgspec-0.22.0/src/msgspec/json.py000066400000000000000000000003241525673062400203370ustar00rootroot00000000000000from ._core import ( JSONDecoder as Decoder, JSONEncoder as Encoder, json_decode as decode, json_encode as encode, json_format as format, ) from ._json_schema import schema, schema_components python-msgspec-0.22.0/src/msgspec/json.pyi000066400000000000000000000056751525673062400205260ustar00rootroot00000000000000import decimal from collections.abc import Callable, Iterable from types import GenericAlias from typing import ( Any, Generic, Literal, Type, TypeAlias, TypeVar, final, overload, ) from typing_extensions import Buffer _T = TypeVar("_T") _EncHookSig: TypeAlias = Callable[[Any], Any] | None _DecHookSig: TypeAlias = Callable[[type, Any], Any] | None _FloatHookSig: TypeAlias = Callable[[str], Any] | None _SchemaHookSig: TypeAlias = Callable[[type], dict[str, Any]] | None _DecimalFormatSig: TypeAlias = ( Callable[[decimal.Decimal], Any] | Literal["string", "number"] ) @final class Encoder: enc_hook: _EncHookSig decimal_format: _DecimalFormatSig uuid_format: Literal["canonical", "hex"] order: Literal["deterministic", "sorted"] | None def __init__( self, *, enc_hook: _EncHookSig = None, decimal_format: _DecimalFormatSig = "string", uuid_format: Literal["canonical", "hex"] = "canonical", order: Literal["deterministic", "sorted"] | None = None, ): ... def encode(self, obj: Any, /) -> bytes: ... def encode_lines(self, items: Iterable[Any], /) -> bytes: ... def encode_into(self, obj: Any, buffer: bytearray, offset: int = 0, /) -> None: ... @final class Decoder(Generic[_T]): type: Type[_T] # needed for mypy, because of the same name strict: bool dec_hook: _DecHookSig float_hook: _FloatHookSig @overload def __init__( self: Decoder[_T], type: Type[_T], *, strict: bool = True, dec_hook: _DecHookSig = None, float_hook: _FloatHookSig = None, ) -> None: ... @overload def __init__( self: Decoder[Any], type: Any = ..., *, strict: bool = True, dec_hook: _DecHookSig = None, float_hook: _FloatHookSig = None, ) -> None: ... def decode(self, buf: Buffer | str, /) -> _T: ... def decode_lines(self, buf: Buffer | str, /) -> list[_T]: ... def __class_getitem__(cls, item: Any, /) -> GenericAlias: ... @overload def decode( buf: Buffer | str, /, *, type: type[_T], strict: bool = True, dec_hook: _DecHookSig = None, ) -> _T: ... @overload def decode( buf: Buffer | str, /, *, type: Any = ..., strict: bool = True, dec_hook: _DecHookSig = None, ) -> Any: ... def encode( obj: Any, /, *, enc_hook: _EncHookSig = None, order: Literal["deterministic", "sorted"] | None = None, ) -> bytes: ... def schema( type: Any, *, schema_hook: _SchemaHookSig = None, ref_template: str = "#/$defs/{name}", ) -> dict[str, Any]: ... def schema_components( types: Iterable[Any], *, schema_hook: _SchemaHookSig = None, ref_template: str = "#/$defs/{name}", ) -> tuple[tuple[dict[str, Any], ...], dict[str, Any]]: ... @overload def format(buf: str, *, indent: int = 2) -> str: ... @overload def format(buf: Buffer, *, indent: int = 2) -> bytes: ... python-msgspec-0.22.0/src/msgspec/msgpack.py000066400000000000000000000002321525673062400210110ustar00rootroot00000000000000from ._core import ( Ext, MsgpackDecoder as Decoder, MsgpackEncoder as Encoder, msgpack_decode as decode, msgpack_encode as encode, ) python-msgspec-0.22.0/src/msgspec/msgpack.pyi000066400000000000000000000047241525673062400211740ustar00rootroot00000000000000import decimal from collections.abc import Callable from types import GenericAlias from typing import ( Any, Generic, Literal, Type, TypeAlias, TypeVar, final, overload, ) from typing_extensions import Buffer _T = TypeVar("_T") _EncHookSig: TypeAlias = Callable[[Any], Any] | None _ExtHookSig: TypeAlias = Callable[[int, memoryview], Any] | None _DecHookSig: TypeAlias = Callable[[type[Any], Any], Any] | None _DecimalFormatSig: TypeAlias = ( Callable[[decimal.Decimal], Any] | Literal["string", "number"] ) @final class Ext: code: int data: Buffer def __init__(self, code: int, data: Buffer, /) -> None: ... @final class Decoder(Generic[_T]): type: Type[_T] # needed for mypy, because of the same name strict: bool dec_hook: _DecHookSig ext_hook: _ExtHookSig @overload def __init__( self: Decoder[_T], type: Type[_T], *, strict: bool = True, dec_hook: _DecHookSig = None, ext_hook: _ExtHookSig = None, ) -> None: ... @overload def __init__( self: Decoder[Any], type: Any = ..., *, strict: bool = True, dec_hook: _DecHookSig = None, ext_hook: _ExtHookSig = None, ) -> None: ... def decode(self, buf: Buffer, /) -> _T: ... def __class_getitem__(cls, item: Any, /) -> GenericAlias: ... @final class Encoder: enc_hook: _EncHookSig decimal_format: _DecimalFormatSig uuid_format: Literal["canonical", "hex", "bytes"] order: Literal["deterministic", "sorted"] | None def __init__( self, *, enc_hook: _EncHookSig = None, decimal_format: _DecimalFormatSig = "string", uuid_format: Literal["canonical", "hex", "bytes"] = "canonical", order: Literal["deterministic", "sorted"] | None = None, ) -> None: ... def encode(self, obj: Any, /) -> bytes: ... def encode_into(self, obj: Any, buffer: bytearray, offset: int = 0, /) -> None: ... @overload def decode( buf: Buffer, /, *, type: type[_T], strict: bool = True, dec_hook: _DecHookSig = None, ext_hook: _ExtHookSig = None, ) -> _T: ... @overload def decode( buf: Buffer, /, *, type: Any = ..., strict: bool = True, dec_hook: _DecHookSig = None, ext_hook: _ExtHookSig = None, ) -> Any: ... def encode( obj: Any, /, *, enc_hook: _EncHookSig = None, order: Literal["deterministic", "sorted"] | None = None, ) -> bytes: ... python-msgspec-0.22.0/src/msgspec/py.typed000066400000000000000000000000001525673062400205020ustar00rootroot00000000000000python-msgspec-0.22.0/src/msgspec/ryu.h000066400000000000000000001566541525673062400200260ustar00rootroot00000000000000/* This code is a modified and condensed version of the ryu library, found at * https://github.com/ulfjack/ryu. The formatting routine also mirrors some * ideas taken from https://github.com/dtolnay/ryu, which was direct rust * translation of the above (and has the same license as the above). That * license is copied below. * * Copyright 2018 Ulf Adams * * The contents of this file may be used under the terms of the Apache License, * Version 2.0. * * (See accompanying file LICENSE-Apache or copy at * http://www.apache.org/licenses/LICENSE-2.0) * * Alternatively, the contents of this file may be used under the terms of * the Boost Software License, Version 1.0. * (See accompanying file LICENSE-Boost or copy at * https://www.boost.org/LICENSE_1_0.txt) * * Unless required by applicable law or agreed to in writing, this software * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. */ #ifndef RYU_H #define RYU_H #include #include #include #include #include #include "common.h" #include "itoa.h" #define DOUBLE_MANTISSA_BITS 52 #define DOUBLE_EXPONENT_BITS 11 #define DOUBLE_BIAS 1023 #define DOUBLE_POW5_INV_BITCOUNT 125 #define DOUBLE_POW5_BITCOUNT 125 #define DOUBLE_POW5_INV_TABLE_SIZE 342 #define DOUBLE_POW5_TABLE_SIZE 326 static const uint64_t DOUBLE_POW5_INV_SPLIT[DOUBLE_POW5_INV_TABLE_SIZE][2] = { { 1u, 2305843009213693952u }, { 11068046444225730970u, 1844674407370955161u }, { 5165088340638674453u, 1475739525896764129u }, { 7821419487252849886u, 1180591620717411303u }, { 8824922364862649494u, 1888946593147858085u }, { 7059937891890119595u, 1511157274518286468u }, { 13026647942995916322u, 1208925819614629174u }, { 9774590264567735146u, 1934281311383406679u }, { 11509021026396098440u, 1547425049106725343u }, { 16585914450600699399u, 1237940039285380274u }, { 15469416676735388068u, 1980704062856608439u }, { 16064882156130220778u, 1584563250285286751u }, { 9162556910162266299u, 1267650600228229401u }, { 7281393426775805432u, 2028240960365167042u }, { 16893161185646375315u, 1622592768292133633u }, { 2446482504291369283u, 1298074214633706907u }, { 7603720821608101175u, 2076918743413931051u }, { 2393627842544570617u, 1661534994731144841u }, { 16672297533003297786u, 1329227995784915872u }, { 11918280793837635165u, 2126764793255865396u }, { 5845275820328197809u, 1701411834604692317u }, { 15744267100488289217u, 1361129467683753853u }, { 3054734472329800808u, 2177807148294006166u }, { 17201182836831481939u, 1742245718635204932u }, { 6382248639981364905u, 1393796574908163946u }, { 2832900194486363201u, 2230074519853062314u }, { 5955668970331000884u, 1784059615882449851u }, { 1075186361522890384u, 1427247692705959881u }, { 12788344622662355584u, 2283596308329535809u }, { 13920024512871794791u, 1826877046663628647u }, { 3757321980813615186u, 1461501637330902918u }, { 10384555214134712795u, 1169201309864722334u }, { 5547241898389809503u, 1870722095783555735u }, { 4437793518711847602u, 1496577676626844588u }, { 10928932444453298728u, 1197262141301475670u }, { 17486291911125277965u, 1915619426082361072u }, { 6610335899416401726u, 1532495540865888858u }, { 12666966349016942027u, 1225996432692711086u }, { 12888448528943286597u, 1961594292308337738u }, { 17689456452638449924u, 1569275433846670190u }, { 14151565162110759939u, 1255420347077336152u }, { 7885109000409574610u, 2008672555323737844u }, { 9997436015069570011u, 1606938044258990275u }, { 7997948812055656009u, 1285550435407192220u }, { 12796718099289049614u, 2056880696651507552u }, { 2858676849947419045u, 1645504557321206042u }, { 13354987924183666206u, 1316403645856964833u }, { 17678631863951955605u, 2106245833371143733u }, { 3074859046935833515u, 1684996666696914987u }, { 13527933681774397782u, 1347997333357531989u }, { 10576647446613305481u, 2156795733372051183u }, { 15840015586774465031u, 1725436586697640946u }, { 8982663654677661702u, 1380349269358112757u }, { 18061610662226169046u, 2208558830972980411u }, { 10759939715039024913u, 1766847064778384329u }, { 12297300586773130254u, 1413477651822707463u }, { 15986332124095098083u, 2261564242916331941u }, { 9099716884534168143u, 1809251394333065553u }, { 14658471137111155161u, 1447401115466452442u }, { 4348079280205103483u, 1157920892373161954u }, { 14335624477811986218u, 1852673427797059126u }, { 7779150767507678651u, 1482138742237647301u }, { 2533971799264232598u, 1185710993790117841u }, { 15122401323048503126u, 1897137590064188545u }, { 12097921058438802501u, 1517710072051350836u }, { 5988988032009131678u, 1214168057641080669u }, { 16961078480698431330u, 1942668892225729070u }, { 13568862784558745064u, 1554135113780583256u }, { 7165741412905085728u, 1243308091024466605u }, { 11465186260648137165u, 1989292945639146568u }, { 16550846638002330379u, 1591434356511317254u }, { 16930026125143774626u, 1273147485209053803u }, { 4951948911778577463u, 2037035976334486086u }, { 272210314680951647u, 1629628781067588869u }, { 3907117066486671641u, 1303703024854071095u }, { 6251387306378674625u, 2085924839766513752u }, { 16069156289328670670u, 1668739871813211001u }, { 9165976216721026213u, 1334991897450568801u }, { 7286864317269821294u, 2135987035920910082u }, { 16897537898041588005u, 1708789628736728065u }, { 13518030318433270404u, 1367031702989382452u }, { 6871453250525591353u, 2187250724783011924u }, { 9186511415162383406u, 1749800579826409539u }, { 11038557946871817048u, 1399840463861127631u }, { 10282995085511086630u, 2239744742177804210u }, { 8226396068408869304u, 1791795793742243368u }, { 13959814484210916090u, 1433436634993794694u }, { 11267656730511734774u, 2293498615990071511u }, { 5324776569667477496u, 1834798892792057209u }, { 7949170070475892320u, 1467839114233645767u }, { 17427382500606444826u, 1174271291386916613u }, { 5747719112518849781u, 1878834066219066582u }, { 15666221734240810795u, 1503067252975253265u }, { 12532977387392648636u, 1202453802380202612u }, { 5295368560860596524u, 1923926083808324180u }, { 4236294848688477220u, 1539140867046659344u }, { 7078384693692692099u, 1231312693637327475u }, { 11325415509908307358u, 1970100309819723960u }, { 9060332407926645887u, 1576080247855779168u }, { 14626963555825137356u, 1260864198284623334u }, { 12335095245094488799u, 2017382717255397335u }, { 9868076196075591040u, 1613906173804317868u }, { 15273158586344293478u, 1291124939043454294u }, { 13369007293925138595u, 2065799902469526871u }, { 7005857020398200553u, 1652639921975621497u }, { 16672732060544291412u, 1322111937580497197u }, { 11918976037903224966u, 2115379100128795516u }, { 5845832015580669650u, 1692303280103036413u }, { 12055363241948356366u, 1353842624082429130u }, { 841837113407818570u, 2166148198531886609u }, { 4362818505468165179u, 1732918558825509287u }, { 14558301248600263113u, 1386334847060407429u }, { 12225235553534690011u, 2218135755296651887u }, { 2401490813343931363u, 1774508604237321510u }, { 1921192650675145090u, 1419606883389857208u }, { 17831303500047873437u, 2271371013423771532u }, { 6886345170554478103u, 1817096810739017226u }, { 1819727321701672159u, 1453677448591213781u }, { 16213177116328979020u, 1162941958872971024u }, { 14873036941900635463u, 1860707134196753639u }, { 15587778368262418694u, 1488565707357402911u }, { 8780873879868024632u, 1190852565885922329u }, { 2981351763563108441u, 1905364105417475727u }, { 13453127855076217722u, 1524291284333980581u }, { 7073153469319063855u, 1219433027467184465u }, { 11317045550910502167u, 1951092843947495144u }, { 12742985255470312057u, 1560874275157996115u }, { 10194388204376249646u, 1248699420126396892u }, { 1553625868034358140u, 1997919072202235028u }, { 8621598323911307159u, 1598335257761788022u }, { 17965325103354776697u, 1278668206209430417u }, { 13987124906400001422u, 2045869129935088668u }, { 121653480894270168u, 1636695303948070935u }, { 97322784715416134u, 1309356243158456748u }, { 14913111714512307107u, 2094969989053530796u }, { 8241140556867935363u, 1675975991242824637u }, { 17660958889720079260u, 1340780792994259709u }, { 17189487779326395846u, 2145249268790815535u }, { 13751590223461116677u, 1716199415032652428u }, { 18379969808252713988u, 1372959532026121942u }, { 14650556434236701088u, 2196735251241795108u }, { 652398703163629901u, 1757388200993436087u }, { 11589965406756634890u, 1405910560794748869u }, { 7475898206584884855u, 2249456897271598191u }, { 2291369750525997561u, 1799565517817278553u }, { 9211793429904618695u, 1439652414253822842u }, { 18428218302589300235u, 2303443862806116547u }, { 7363877012587619542u, 1842755090244893238u }, { 13269799239553916280u, 1474204072195914590u }, { 10615839391643133024u, 1179363257756731672u }, { 2227947767661371545u, 1886981212410770676u }, { 16539753473096738529u, 1509584969928616540u }, { 13231802778477390823u, 1207667975942893232u }, { 6413489186596184024u, 1932268761508629172u }, { 16198837793502678189u, 1545815009206903337u }, { 5580372605318321905u, 1236652007365522670u }, { 8928596168509315048u, 1978643211784836272u }, { 18210923379033183008u, 1582914569427869017u }, { 7190041073742725760u, 1266331655542295214u }, { 436019273762630246u, 2026130648867672343u }, { 7727513048493924843u, 1620904519094137874u }, { 9871359253537050198u, 1296723615275310299u }, { 4726128361433549347u, 2074757784440496479u }, { 7470251503888749801u, 1659806227552397183u }, { 13354898832594820487u, 1327844982041917746u }, { 13989140502667892133u, 2124551971267068394u }, { 14880661216876224029u, 1699641577013654715u }, { 11904528973500979224u, 1359713261610923772u }, { 4289851098633925465u, 2175541218577478036u }, { 18189276137874781665u, 1740432974861982428u }, { 3483374466074094362u, 1392346379889585943u }, { 1884050330976640656u, 2227754207823337509u }, { 5196589079523222848u, 1782203366258670007u }, { 15225317707844309248u, 1425762693006936005u }, { 5913764258841343181u, 2281220308811097609u }, { 8420360221814984868u, 1824976247048878087u }, { 17804334621677718864u, 1459980997639102469u }, { 17932816512084085415u, 1167984798111281975u }, { 10245762345624985047u, 1868775676978051161u }, { 4507261061758077715u, 1495020541582440929u }, { 7295157664148372495u, 1196016433265952743u }, { 7982903447895485668u, 1913626293225524389u }, { 10075671573058298858u, 1530901034580419511u }, { 4371188443704728763u, 1224720827664335609u }, { 14372599139411386667u, 1959553324262936974u }, { 15187428126271019657u, 1567642659410349579u }, { 15839291315758726049u, 1254114127528279663u }, { 3206773216762499739u, 2006582604045247462u }, { 13633465017635730761u, 1605266083236197969u }, { 14596120828850494932u, 1284212866588958375u }, { 4907049252451240275u, 2054740586542333401u }, { 236290587219081897u, 1643792469233866721u }, { 14946427728742906810u, 1315033975387093376u }, { 16535586736504830250u, 2104054360619349402u }, { 5849771759720043554u, 1683243488495479522u }, { 15747863852001765813u, 1346594790796383617u }, { 10439186904235184007u, 2154551665274213788u }, { 15730047152871967852u, 1723641332219371030u }, { 12584037722297574282u, 1378913065775496824u }, { 9066413911450387881u, 2206260905240794919u }, { 10942479943902220628u, 1765008724192635935u }, { 8753983955121776503u, 1412006979354108748u }, { 10317025513452932081u, 2259211166966573997u }, { 874922781278525018u, 1807368933573259198u }, { 8078635854506640661u, 1445895146858607358u }, { 13841606313089133175u, 1156716117486885886u }, { 14767872471458792434u, 1850745787979017418u }, { 746251532941302978u, 1480596630383213935u }, { 597001226353042382u, 1184477304306571148u }, { 15712597221132509104u, 1895163686890513836u }, { 8880728962164096960u, 1516130949512411069u }, { 10793931984473187891u, 1212904759609928855u }, { 17270291175157100626u, 1940647615375886168u }, { 2748186495899949531u, 1552518092300708935u }, { 2198549196719959625u, 1242014473840567148u }, { 18275073973719576693u, 1987223158144907436u }, { 10930710364233751031u, 1589778526515925949u }, { 12433917106128911148u, 1271822821212740759u }, { 8826220925580526867u, 2034916513940385215u }, { 7060976740464421494u, 1627933211152308172u }, { 16716827836597268165u, 1302346568921846537u }, { 11989529279587987770u, 2083754510274954460u }, { 9591623423670390216u, 1667003608219963568u }, { 15051996368420132820u, 1333602886575970854u }, { 13015147745246481542u, 2133764618521553367u }, { 3033420566713364587u, 1707011694817242694u }, { 6116085268112601993u, 1365609355853794155u }, { 9785736428980163188u, 2184974969366070648u }, { 15207286772667951197u, 1747979975492856518u }, { 1097782973908629988u, 1398383980394285215u }, { 1756452758253807981u, 2237414368630856344u }, { 5094511021344956708u, 1789931494904685075u }, { 4075608817075965366u, 1431945195923748060u }, { 6520974107321544586u, 2291112313477996896u }, { 1527430471115325346u, 1832889850782397517u }, { 12289990821117991246u, 1466311880625918013u }, { 17210690286378213644u, 1173049504500734410u }, { 9090360384495590213u, 1876879207201175057u }, { 18340334751822203140u, 1501503365760940045u }, { 14672267801457762512u, 1201202692608752036u }, { 16096930852848599373u, 1921924308174003258u }, { 1809498238053148529u, 1537539446539202607u }, { 12515645034668249793u, 1230031557231362085u }, { 1578287981759648052u, 1968050491570179337u }, { 12330676829633449412u, 1574440393256143469u }, { 13553890278448669853u, 1259552314604914775u }, { 3239480371808320148u, 2015283703367863641u }, { 17348979556414297411u, 1612226962694290912u }, { 6500486015647617283u, 1289781570155432730u }, { 10400777625036187652u, 2063650512248692368u }, { 15699319729512770768u, 1650920409798953894u }, { 16248804598352126938u, 1320736327839163115u }, { 7551343283653851484u, 2113178124542660985u }, { 6041074626923081187u, 1690542499634128788u }, { 12211557331022285596u, 1352433999707303030u }, { 1091747655926105338u, 2163894399531684849u }, { 4562746939482794594u, 1731115519625347879u }, { 7339546366328145998u, 1384892415700278303u }, { 8053925371383123274u, 2215827865120445285u }, { 6443140297106498619u, 1772662292096356228u }, { 12533209867169019542u, 1418129833677084982u }, { 5295740528502789974u, 2269007733883335972u }, { 15304638867027962949u, 1815206187106668777u }, { 4865013464138549713u, 1452164949685335022u }, { 14960057215536570740u, 1161731959748268017u }, { 9178696285890871890u, 1858771135597228828u }, { 14721654658196518159u, 1487016908477783062u }, { 4398626097073393881u, 1189613526782226450u }, { 7037801755317430209u, 1903381642851562320u }, { 5630241404253944167u, 1522705314281249856u }, { 814844308661245011u, 1218164251424999885u }, { 1303750893857992017u, 1949062802279999816u }, { 15800395974054034906u, 1559250241823999852u }, { 5261619149759407279u, 1247400193459199882u }, { 12107939454356961969u, 1995840309534719811u }, { 5997002748743659252u, 1596672247627775849u }, { 8486951013736837725u, 1277337798102220679u }, { 2511075177753209390u, 2043740476963553087u }, { 13076906586428298482u, 1634992381570842469u }, { 14150874083884549109u, 1307993905256673975u }, { 4194654460505726958u, 2092790248410678361u }, { 18113118827372222859u, 1674232198728542688u }, { 3422448617672047318u, 1339385758982834151u }, { 16543964232501006678u, 2143017214372534641u }, { 9545822571258895019u, 1714413771498027713u }, { 15015355686490936662u, 1371531017198422170u }, { 5577825024675947042u, 2194449627517475473u }, { 11840957649224578280u, 1755559702013980378u }, { 16851463748863483271u, 1404447761611184302u }, { 12204946739213931940u, 2247116418577894884u }, { 13453306206113055875u, 1797693134862315907u }, { 3383947335406624054u, 1438154507889852726u }, { 16482362180876329456u, 2301047212623764361u }, { 9496540929959153242u, 1840837770099011489u }, { 11286581558709232917u, 1472670216079209191u }, { 5339916432225476010u, 1178136172863367353u }, { 4854517476818851293u, 1885017876581387765u }, { 3883613981455081034u, 1508014301265110212u }, { 14174937629389795797u, 1206411441012088169u }, { 11611853762797942306u, 1930258305619341071u }, { 5600134195496443521u, 1544206644495472857u }, { 15548153800622885787u, 1235365315596378285u }, { 6430302007287065643u, 1976584504954205257u }, { 16212288050055383484u, 1581267603963364205u }, { 12969830440044306787u, 1265014083170691364u }, { 9683682259845159889u, 2024022533073106183u }, { 15125643437359948558u, 1619218026458484946u }, { 8411165935146048523u, 1295374421166787957u }, { 17147214310975587960u, 2072599073866860731u }, { 10028422634038560045u, 1658079259093488585u }, { 8022738107230848036u, 1326463407274790868u }, { 9147032156827446534u, 2122341451639665389u }, { 11006974540203867551u, 1697873161311732311u }, { 5116230817421183718u, 1358298529049385849u }, { 15564666937357714594u, 2173277646479017358u }, { 1383687105660440706u, 1738622117183213887u }, { 12174996128754083534u, 1390897693746571109u }, { 8411947361780802685u, 2225436309994513775u }, { 6729557889424642148u, 1780349047995611020u }, { 5383646311539713719u, 1424279238396488816u }, { 1235136468979721303u, 2278846781434382106u }, { 15745504434151418335u, 1823077425147505684u }, { 16285752362063044992u, 1458461940118004547u }, { 5649904260166615347u, 1166769552094403638u }, { 5350498001524674232u, 1866831283351045821u }, { 591049586477829062u, 1493465026680836657u }, { 11540886113407994219u, 1194772021344669325u }, { 18673707743239135u, 1911635234151470921u }, { 14772334225162232601u, 1529308187321176736u }, { 8128518565387875758u, 1223446549856941389u }, { 1937583260394870242u, 1957514479771106223u }, { 8928764237799716840u, 1566011583816884978u }, { 14521709019723594119u, 1252809267053507982u }, { 8477339172590109297u, 2004494827285612772u }, { 17849917782297818407u, 1603595861828490217u }, { 6901236596354434079u, 1282876689462792174u }, { 18420676183650915173u, 2052602703140467478u }, { 3668494502695001169u, 1642082162512373983u }, { 10313493231639821582u, 1313665730009899186u }, { 9122891541139893884u, 2101865168015838698u }, { 14677010862395735754u, 1681492134412670958u }, { 673562245690857633u, 1345193707530136767u } }; static const uint64_t DOUBLE_POW5_SPLIT[DOUBLE_POW5_TABLE_SIZE][2] = { { 0u, 1152921504606846976u }, { 0u, 1441151880758558720u }, { 0u, 1801439850948198400u }, { 0u, 2251799813685248000u }, { 0u, 1407374883553280000u }, { 0u, 1759218604441600000u }, { 0u, 2199023255552000000u }, { 0u, 1374389534720000000u }, { 0u, 1717986918400000000u }, { 0u, 2147483648000000000u }, { 0u, 1342177280000000000u }, { 0u, 1677721600000000000u }, { 0u, 2097152000000000000u }, { 0u, 1310720000000000000u }, { 0u, 1638400000000000000u }, { 0u, 2048000000000000000u }, { 0u, 1280000000000000000u }, { 0u, 1600000000000000000u }, { 0u, 2000000000000000000u }, { 0u, 1250000000000000000u }, { 0u, 1562500000000000000u }, { 0u, 1953125000000000000u }, { 0u, 1220703125000000000u }, { 0u, 1525878906250000000u }, { 0u, 1907348632812500000u }, { 0u, 1192092895507812500u }, { 0u, 1490116119384765625u }, { 4611686018427387904u, 1862645149230957031u }, { 9799832789158199296u, 1164153218269348144u }, { 12249790986447749120u, 1455191522836685180u }, { 15312238733059686400u, 1818989403545856475u }, { 14528612397897220096u, 2273736754432320594u }, { 13692068767113150464u, 1421085471520200371u }, { 12503399940464050176u, 1776356839400250464u }, { 15629249925580062720u, 2220446049250313080u }, { 9768281203487539200u, 1387778780781445675u }, { 7598665485932036096u, 1734723475976807094u }, { 274959820560269312u, 2168404344971008868u }, { 9395221924704944128u, 1355252715606880542u }, { 2520655369026404352u, 1694065894508600678u }, { 12374191248137781248u, 2117582368135750847u }, { 14651398557727195136u, 1323488980084844279u }, { 13702562178731606016u, 1654361225106055349u }, { 3293144668132343808u, 2067951531382569187u }, { 18199116482078572544u, 1292469707114105741u }, { 8913837547316051968u, 1615587133892632177u }, { 15753982952572452864u, 2019483917365790221u }, { 12152082354571476992u, 1262177448353618888u }, { 15190102943214346240u, 1577721810442023610u }, { 9764256642163156992u, 1972152263052529513u }, { 17631875447420442880u, 1232595164407830945u }, { 8204786253993389888u, 1540743955509788682u }, { 1032610780636961552u, 1925929944387235853u }, { 2951224747111794922u, 1203706215242022408u }, { 3689030933889743652u, 1504632769052528010u }, { 13834660704216955373u, 1880790961315660012u }, { 17870034976990372916u, 1175494350822287507u }, { 17725857702810578241u, 1469367938527859384u }, { 3710578054803671186u, 1836709923159824231u }, { 26536550077201078u, 2295887403949780289u }, { 11545800389866720434u, 1434929627468612680u }, { 14432250487333400542u, 1793662034335765850u }, { 8816941072311974870u, 2242077542919707313u }, { 17039803216263454053u, 1401298464324817070u }, { 12076381983474541759u, 1751623080406021338u }, { 5872105442488401391u, 2189528850507526673u }, { 15199280947623720629u, 1368455531567204170u }, { 9775729147674874978u, 1710569414459005213u }, { 16831347453020981627u, 2138211768073756516u }, { 1296220121283337709u, 1336382355046097823u }, { 15455333206886335848u, 1670477943807622278u }, { 10095794471753144002u, 2088097429759527848u }, { 6309871544845715001u, 1305060893599704905u }, { 12499025449484531656u, 1631326116999631131u }, { 11012095793428276666u, 2039157646249538914u }, { 11494245889320060820u, 1274473528905961821u }, { 532749306367912313u, 1593091911132452277u }, { 5277622651387278295u, 1991364888915565346u }, { 7910200175544436838u, 1244603055572228341u }, { 14499436237857933952u, 1555753819465285426u }, { 8900923260467641632u, 1944692274331606783u }, { 12480606065433357876u, 1215432671457254239u }, { 10989071563364309441u, 1519290839321567799u }, { 9124653435777998898u, 1899113549151959749u }, { 8008751406574943263u, 1186945968219974843u }, { 5399253239791291175u, 1483682460274968554u }, { 15972438586593889776u, 1854603075343710692u }, { 759402079766405302u, 1159126922089819183u }, { 14784310654990170340u, 1448908652612273978u }, { 9257016281882937117u, 1811135815765342473u }, { 16182956370781059300u, 2263919769706678091u }, { 7808504722524468110u, 1414949856066673807u }, { 5148944884728197234u, 1768687320083342259u }, { 1824495087482858639u, 2210859150104177824u }, { 1140309429676786649u, 1381786968815111140u }, { 1425386787095983311u, 1727233711018888925u }, { 6393419502297367043u, 2159042138773611156u }, { 13219259225790630210u, 1349401336733506972u }, { 16524074032238287762u, 1686751670916883715u }, { 16043406521870471799u, 2108439588646104644u }, { 803757039314269066u, 1317774742903815403u }, { 14839754354425000045u, 1647218428629769253u }, { 4714634887749086344u, 2059023035787211567u }, { 9864175832484260821u, 1286889397367007229u }, { 16941905809032713930u, 1608611746708759036u }, { 2730638187581340797u, 2010764683385948796u }, { 10930020904093113806u, 1256727927116217997u }, { 18274212148543780162u, 1570909908895272496u }, { 4396021111970173586u, 1963637386119090621u }, { 5053356204195052443u, 1227273366324431638u }, { 15540067292098591362u, 1534091707905539547u }, { 14813398096695851299u, 1917614634881924434u }, { 13870059828862294966u, 1198509146801202771u }, { 12725888767650480803u, 1498136433501503464u }, { 15907360959563101004u, 1872670541876879330u }, { 14553786618154326031u, 1170419088673049581u }, { 4357175217410743827u, 1463023860841311977u }, { 10058155040190817688u, 1828779826051639971u }, { 7961007781811134206u, 2285974782564549964u }, { 14199001900486734687u, 1428734239102843727u }, { 13137066357181030455u, 1785917798878554659u }, { 11809646928048900164u, 2232397248598193324u }, { 16604401366885338411u, 1395248280373870827u }, { 16143815690179285109u, 1744060350467338534u }, { 10956397575869330579u, 2180075438084173168u }, { 6847748484918331612u, 1362547148802608230u }, { 17783057643002690323u, 1703183936003260287u }, { 17617136035325974999u, 2128979920004075359u }, { 17928239049719816230u, 1330612450002547099u }, { 17798612793722382384u, 1663265562503183874u }, { 13024893955298202172u, 2079081953128979843u }, { 5834715712847682405u, 1299426220705612402u }, { 16516766677914378815u, 1624282775882015502u }, { 11422586310538197711u, 2030353469852519378u }, { 11750802462513761473u, 1268970918657824611u }, { 10076817059714813937u, 1586213648322280764u }, { 12596021324643517422u, 1982767060402850955u }, { 5566670318688504437u, 1239229412751781847u }, { 2346651879933242642u, 1549036765939727309u }, { 7545000868343941206u, 1936295957424659136u }, { 4715625542714963254u, 1210184973390411960u }, { 5894531928393704067u, 1512731216738014950u }, { 16591536947346905892u, 1890914020922518687u }, { 17287239619732898039u, 1181821263076574179u }, { 16997363506238734644u, 1477276578845717724u }, { 2799960309088866689u, 1846595723557147156u }, { 10973347230035317489u, 1154122327223216972u }, { 13716684037544146861u, 1442652909029021215u }, { 12534169028502795672u, 1803316136286276519u }, { 11056025267201106687u, 2254145170357845649u }, { 18439230838069161439u, 1408840731473653530u }, { 13825666510731675991u, 1761050914342066913u }, { 3447025083132431277u, 2201313642927583642u }, { 6766076695385157452u, 1375821026829739776u }, { 8457595869231446815u, 1719776283537174720u }, { 10571994836539308519u, 2149720354421468400u }, { 6607496772837067824u, 1343575221513417750u }, { 17482743002901110588u, 1679469026891772187u }, { 17241742735199000331u, 2099336283614715234u }, { 15387775227926763111u, 1312085177259197021u }, { 5399660979626290177u, 1640106471573996277u }, { 11361262242960250625u, 2050133089467495346u }, { 11712474920277544544u, 1281333180917184591u }, { 10028907631919542777u, 1601666476146480739u }, { 7924448521472040567u, 2002083095183100924u }, { 14176152362774801162u, 1251301934489438077u }, { 3885132398186337741u, 1564127418111797597u }, { 9468101516160310080u, 1955159272639746996u }, { 15140935484454969608u, 1221974545399841872u }, { 479425281859160394u, 1527468181749802341u }, { 5210967620751338397u, 1909335227187252926u }, { 17091912818251750210u, 1193334516992033078u }, { 12141518985959911954u, 1491668146240041348u }, { 15176898732449889943u, 1864585182800051685u }, { 11791404716994875166u, 1165365739250032303u }, { 10127569877816206054u, 1456707174062540379u }, { 8047776328842869663u, 1820883967578175474u }, { 836348374198811271u, 2276104959472719343u }, { 7440246761515338900u, 1422565599670449589u }, { 13911994470321561530u, 1778206999588061986u }, { 8166621051047176104u, 2222758749485077483u }, { 2798295147690791113u, 1389224218428173427u }, { 17332926989895652603u, 1736530273035216783u }, { 17054472718942177850u, 2170662841294020979u }, { 8353202440125167204u, 1356664275808763112u }, { 10441503050156459005u, 1695830344760953890u }, { 3828506775840797949u, 2119787930951192363u }, { 86973725686804766u, 1324867456844495227u }, { 13943775212390669669u, 1656084321055619033u }, { 3594660960206173375u, 2070105401319523792u }, { 2246663100128858359u, 1293815875824702370u }, { 12031700912015848757u, 1617269844780877962u }, { 5816254103165035138u, 2021587305976097453u }, { 5941001823691840913u, 1263492066235060908u }, { 7426252279614801142u, 1579365082793826135u }, { 4671129331091113523u, 1974206353492282669u }, { 5225298841145639904u, 1233878970932676668u }, { 6531623551432049880u, 1542348713665845835u }, { 3552843420862674446u, 1927935892082307294u }, { 16055585193321335241u, 1204959932551442058u }, { 10846109454796893243u, 1506199915689302573u }, { 18169322836923504458u, 1882749894611628216u }, { 11355826773077190286u, 1176718684132267635u }, { 9583097447919099954u, 1470898355165334544u }, { 11978871809898874942u, 1838622943956668180u }, { 14973589762373593678u, 2298278679945835225u }, { 2440964573842414192u, 1436424174966147016u }, { 3051205717303017741u, 1795530218707683770u }, { 13037379183483547984u, 2244412773384604712u }, { 8148361989677217490u, 1402757983365377945u }, { 14797138505523909766u, 1753447479206722431u }, { 13884737113477499304u, 2191809349008403039u }, { 15595489723564518921u, 1369880843130251899u }, { 14882676136028260747u, 1712351053912814874u }, { 9379973133180550126u, 2140438817391018593u }, { 17391698254306313589u, 1337774260869386620u }, { 3292878744173340370u, 1672217826086733276u }, { 4116098430216675462u, 2090272282608416595u }, { 266718509671728212u, 1306420176630260372u }, { 333398137089660265u, 1633025220787825465u }, { 5028433689789463235u, 2041281525984781831u }, { 10060300083759496378u, 1275800953740488644u }, { 12575375104699370472u, 1594751192175610805u }, { 1884160825592049379u, 1993438990219513507u }, { 17318501580490888525u, 1245899368887195941u }, { 7813068920331446945u, 1557374211108994927u }, { 5154650131986920777u, 1946717763886243659u }, { 915813323278131534u, 1216698602428902287u }, { 14979824709379828129u, 1520873253036127858u }, { 9501408849870009354u, 1901091566295159823u }, { 12855909558809837702u, 1188182228934474889u }, { 2234828893230133415u, 1485227786168093612u }, { 2793536116537666769u, 1856534732710117015u }, { 8663489100477123587u, 1160334207943823134u }, { 1605989338741628675u, 1450417759929778918u }, { 11230858710281811652u, 1813022199912223647u }, { 9426887369424876662u, 2266277749890279559u }, { 12809333633531629769u, 1416423593681424724u }, { 16011667041914537212u, 1770529492101780905u }, { 6179525747111007803u, 2213161865127226132u }, { 13085575628799155685u, 1383226165704516332u }, { 16356969535998944606u, 1729032707130645415u }, { 15834525901571292854u, 2161290883913306769u }, { 2979049660840976177u, 1350806802445816731u }, { 17558870131333383934u, 1688508503057270913u }, { 8113529608884566205u, 2110635628821588642u }, { 9682642023980241782u, 1319147268013492901u }, { 16714988548402690132u, 1648934085016866126u }, { 11670363648648586857u, 2061167606271082658u }, { 11905663298832754689u, 1288229753919426661u }, { 1047021068258779650u, 1610287192399283327u }, { 15143834390605638274u, 2012858990499104158u }, { 4853210475701136017u, 1258036869061940099u }, { 1454827076199032118u, 1572546086327425124u }, { 1818533845248790147u, 1965682607909281405u }, { 3442426662494187794u, 1228551629943300878u }, { 13526405364972510550u, 1535689537429126097u }, { 3072948650933474476u, 1919611921786407622u }, { 15755650962115585259u, 1199757451116504763u }, { 15082877684217093670u, 1499696813895630954u }, { 9630225068416591280u, 1874621017369538693u }, { 8324733676974063502u, 1171638135855961683u }, { 5794231077790191473u, 1464547669819952104u }, { 7242788847237739342u, 1830684587274940130u }, { 18276858095901949986u, 2288355734093675162u }, { 16034722328366106645u, 1430222333808546976u }, { 1596658836748081690u, 1787777917260683721u }, { 6607509564362490017u, 2234722396575854651u }, { 1823850468512862308u, 1396701497859909157u }, { 6891499104068465790u, 1745876872324886446u }, { 17837745916940358045u, 2182346090406108057u }, { 4231062170446641922u, 1363966306503817536u }, { 5288827713058302403u, 1704957883129771920u }, { 6611034641322878003u, 2131197353912214900u }, { 13355268687681574560u, 1331998346195134312u }, { 16694085859601968200u, 1664997932743917890u }, { 11644235287647684442u, 2081247415929897363u }, { 4971804045566108824u, 1300779634956185852u }, { 6214755056957636030u, 1625974543695232315u }, { 3156757802769657134u, 2032468179619040394u }, { 6584659645158423613u, 1270292612261900246u }, { 17454196593302805324u, 1587865765327375307u }, { 17206059723201118751u, 1984832206659219134u }, { 6142101308573311315u, 1240520129162011959u }, { 3065940617289251240u, 1550650161452514949u }, { 8444111790038951954u, 1938312701815643686u }, { 665883850346957067u, 1211445438634777304u }, { 832354812933696334u, 1514306798293471630u }, { 10263815553021896226u, 1892883497866839537u }, { 17944099766707154901u, 1183052186166774710u }, { 13206752671529167818u, 1478815232708468388u }, { 16508440839411459773u, 1848519040885585485u }, { 12623618533845856310u, 1155324400553490928u }, { 15779523167307320387u, 1444155500691863660u }, { 1277659885424598868u, 1805194375864829576u }, { 1597074856780748586u, 2256492969831036970u }, { 5609857803915355770u, 1410308106144398106u }, { 16235694291748970521u, 1762885132680497632u }, { 1847873790976661535u, 2203606415850622041u }, { 12684136165428883219u, 1377254009906638775u }, { 11243484188358716120u, 1721567512383298469u }, { 219297180166231438u, 2151959390479123087u }, { 7054589765244976505u, 1344974619049451929u }, { 13429923224983608535u, 1681218273811814911u }, { 12175718012802122765u, 2101522842264768639u }, { 14527352785642408584u, 1313451776415480399u }, { 13547504963625622826u, 1641814720519350499u }, { 12322695186104640628u, 2052268400649188124u }, { 16925056528170176201u, 1282667750405742577u }, { 7321262604930556539u, 1603334688007178222u }, { 18374950293017971482u, 2004168360008972777u }, { 4566814905495150320u, 1252605225005607986u }, { 14931890668723713708u, 1565756531257009982u }, { 9441491299049866327u, 1957195664071262478u }, { 1289246043478778550u, 1223247290044539049u }, { 6223243572775861092u, 1529059112555673811u }, { 3167368447542438461u, 1911323890694592264u }, { 1979605279714024038u, 1194577431684120165u }, { 7086192618069917952u, 1493221789605150206u }, { 18081112809442173248u, 1866527237006437757u }, { 13606538515115052232u, 1166579523129023598u }, { 7784801107039039482u, 1458224403911279498u }, { 507629346944023544u, 1822780504889099373u }, { 5246222702107417334u, 2278475631111374216u }, { 3278889188817135834u, 1424047269444608885u }, { 8710297504448807696u, 1780059086805761106u } }; #if defined(_M_IX86) || defined(_M_ARM) #define RYU_32_BIT_PLATFORM #endif #if defined(__SIZEOF_INT128__) && !defined(_MSC_VER) && !defined(RYU_ONLY_64_BIT_OPS) #define HAS_UINT128 #elif defined(_MSC_VER) && !defined(RYU_ONLY_64_BIT_OPS) && defined(_M_X64) #define HAS_64_BIT_INTRINSICS #endif #if defined(HAS_UINT128) typedef __uint128_t uint128_t; #endif #if defined(HAS_64_BIT_INTRINSICS) #include static inline uint64_t umul128(const uint64_t a, const uint64_t b, uint64_t* const productHi) { return _umul128(a, b, productHi); } // Returns the lower 64 bits of (hi*2^64 + lo) >> dist, with 0 < dist < 64. static inline uint64_t shiftright128(const uint64_t lo, const uint64_t hi, const uint32_t dist) { // For the __shiftright128 intrinsic, the shift value is always // modulo 64. // In the current implementation of the double-precision version // of Ryu, the shift value is always < 64. (In the case // RYU_OPTIMIZE_SIZE == 0, the shift value is in the range [49, 58]. // Otherwise in the range [2, 59].) // However, this function is now also called by s2d, which requires supporting // the larger shift range (TODO: what is the actual range?). // Check this here in case a future change requires larger shift // values. In this case this function needs to be adjusted. assert(dist < 64); return __shiftright128(lo, hi, (unsigned char) dist); } #else // defined(HAS_64_BIT_INTRINSICS) static inline uint64_t umul128(const uint64_t a, const uint64_t b, uint64_t* const productHi) { // The casts here help MSVC to avoid calls to the __allmul library function. const uint32_t aLo = (uint32_t)a; const uint32_t aHi = (uint32_t)(a >> 32); const uint32_t bLo = (uint32_t)b; const uint32_t bHi = (uint32_t)(b >> 32); const uint64_t b00 = (uint64_t)aLo * bLo; const uint64_t b01 = (uint64_t)aLo * bHi; const uint64_t b10 = (uint64_t)aHi * bLo; const uint64_t b11 = (uint64_t)aHi * bHi; const uint32_t b00Lo = (uint32_t)b00; const uint32_t b00Hi = (uint32_t)(b00 >> 32); const uint64_t mid1 = b10 + b00Hi; const uint32_t mid1Lo = (uint32_t)(mid1); const uint32_t mid1Hi = (uint32_t)(mid1 >> 32); const uint64_t mid2 = b01 + mid1Lo; const uint32_t mid2Lo = (uint32_t)(mid2); const uint32_t mid2Hi = (uint32_t)(mid2 >> 32); const uint64_t pHi = b11 + mid1Hi + mid2Hi; const uint64_t pLo = ((uint64_t)mid2Lo << 32) | b00Lo; *productHi = pHi; return pLo; } static inline uint64_t shiftright128(const uint64_t lo, const uint64_t hi, const uint32_t dist) { // We don't need to handle the case dist >= 64 here (see above). assert(dist < 64); assert(dist > 0); return (hi << (64 - dist)) | (lo >> dist); } #endif // defined(HAS_64_BIT_INTRINSICS) #if defined(RYU_32_BIT_PLATFORM) // Returns the high 64 bits of the 128-bit product of a and b. static inline uint64_t umulh(const uint64_t a, const uint64_t b) { // Reuse the umul128 implementation. // Optimizers will likely eliminate the instructions used to compute the // low part of the product. uint64_t hi; umul128(a, b, &hi); return hi; } // On 32-bit platforms, compilers typically generate calls to library // functions for 64-bit divisions, even if the divisor is a constant. // // E.g.: // https://bugs.llvm.org/show_bug.cgi?id=37932 // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=17958 // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=37443 // // The functions here perform division-by-constant using multiplications // in the same way as 64-bit compilers would do. // // NB: // The multipliers and shift values are the ones generated by clang x64 // for expressions like x/5, x/10, etc. static inline uint64_t div5(const uint64_t x) { return umulh(x, 0xCCCCCCCCCCCCCCCDu) >> 2; } static inline uint64_t div10(const uint64_t x) { return umulh(x, 0xCCCCCCCCCCCCCCCDu) >> 3; } static inline uint64_t div100(const uint64_t x) { return umulh(x >> 2, 0x28F5C28F5C28F5C3u) >> 2; } #else // defined(RYU_32_BIT_PLATFORM) static inline uint64_t div5(const uint64_t x) { return x / 5; } static inline uint64_t div10(const uint64_t x) { return x / 10; } static inline uint64_t div100(const uint64_t x) { return x / 100; } #endif // defined(RYU_32_BIT_PLATFORM) static inline uint32_t pow5Factor(uint64_t value) { const uint64_t m_inv_5 = 14757395258967641293u; // 5 * m_inv_5 = 1 (mod 2^64) const uint64_t n_div_5 = 3689348814741910323u; // #{ n | n = 0 (mod 2^64) } = 2^64 / 5 uint32_t count = 0; for (;;) { assert(value != 0); value *= m_inv_5; if (value > n_div_5) break; ++count; } return count; } // Returns true if value is divisible by 5^p. static inline bool multipleOfPowerOf5(const uint64_t value, const uint32_t p) { // I tried a case distinction on p, but there was no performance difference. return pow5Factor(value) >= p; } // Returns true if value is divisible by 2^p. static inline bool multipleOfPowerOf2(const uint64_t value, const uint32_t p) { assert(value != 0); assert(p < 64); // __builtin_ctzll doesn't appear to be faster here. return (value & ((1ull << p) - 1)) == 0; } // We need a 64x128-bit multiplication and a subsequent 128-bit shift. // Multiplication: // The 64-bit factor is variable and passed in, the 128-bit factor comes // from a lookup table. We know that the 64-bit factor only has 55 // significant bits (i.e., the 9 topmost bits are zeros). The 128-bit // factor only has 124 significant bits (i.e., the 4 topmost bits are // zeros). // Shift: // In principle, the multiplication result requires 55 + 124 = 179 bits to // represent. However, we then shift this value to the right by j, which is // at least j >= 115, so the result is guaranteed to fit into 179 - 115 = 64 // bits. This means that we only need the topmost 64 significant bits of // the 64x128-bit multiplication. // // There are several ways to do this: // 1. Best case: the compiler exposes a 128-bit type. // We perform two 64x64-bit multiplications, add the higher 64 bits of the // lower result to the higher result, and shift by j - 64 bits. // // We explicitly cast from 64-bit to 128-bit, so the compiler can tell // that these are only 64-bit inputs, and can map these to the best // possible sequence of assembly instructions. // x64 machines happen to have matching assembly instructions for // 64x64-bit multiplications and 128-bit shifts. // // 2. Second best case: the compiler exposes intrinsics for the x64 assembly // instructions mentioned in 1. // // 3. We only have 64x64 bit instructions that return the lower 64 bits of // the result, i.e., we have to use plain C. // Our inputs are less than the full width, so we have three options: // a. Ignore this fact and just implement the intrinsics manually. // b. Split both into 31-bit pieces, which guarantees no internal overflow, // but requires extra work upfront (unless we change the lookup table). // c. Split only the first factor into 31-bit pieces, which also guarantees // no internal overflow, but requires extra work since the intermediate // results are not perfectly aligned. #if defined(HAS_UINT128) // Best case: use 128-bit type. static inline uint64_t mulShift64(const uint64_t m, const uint64_t* const mul, const int32_t j) { const uint128_t b0 = ((uint128_t) m) * mul[0]; const uint128_t b2 = ((uint128_t) m) * mul[1]; return (uint64_t) (((b0 >> 64) + b2) >> (j - 64)); } static inline uint64_t mulShiftAll64(const uint64_t m, const uint64_t* const mul, const int32_t j, uint64_t* const vp, uint64_t* const vm, const uint32_t mmShift) { // m <<= 2; // uint128_t b0 = ((uint128_t) m) * mul[0]; // 0 // uint128_t b2 = ((uint128_t) m) * mul[1]; // 64 // // uint128_t hi = (b0 >> 64) + b2; // uint128_t lo = b0 & 0xffffffffffffffffull; // uint128_t factor = (((uint128_t) mul[1]) << 64) + mul[0]; // uint128_t vpLo = lo + (factor << 1); // *vp = (uint64_t) ((hi + (vpLo >> 64)) >> (j - 64)); // uint128_t vmLo = lo - (factor << mmShift); // *vm = (uint64_t) ((hi + (vmLo >> 64) - (((uint128_t) 1ull) << 64)) >> (j - 64)); // return (uint64_t) (hi >> (j - 64)); *vp = mulShift64(4 * m + 2, mul, j); *vm = mulShift64(4 * m - 1 - mmShift, mul, j); return mulShift64(4 * m, mul, j); } #elif defined(HAS_64_BIT_INTRINSICS) static inline uint64_t mulShift64(const uint64_t m, const uint64_t* const mul, const int32_t j) { // m is maximum 55 bits uint64_t high1; // 128 const uint64_t low1 = umul128(m, mul[1], &high1); // 64 uint64_t high0; // 64 umul128(m, mul[0], &high0); // 0 const uint64_t sum = high0 + low1; if (sum < high0) { ++high1; // overflow into high1 } return shiftright128(sum, high1, j - 64); } static inline uint64_t mulShiftAll64(const uint64_t m, const uint64_t* const mul, const int32_t j, uint64_t* const vp, uint64_t* const vm, const uint32_t mmShift) { *vp = mulShift64(4 * m + 2, mul, j); *vm = mulShift64(4 * m - 1 - mmShift, mul, j); return mulShift64(4 * m, mul, j); } #else // !defined(HAS_UINT128) && !defined(HAS_64_BIT_INTRINSICS) static inline uint64_t mulShift64(const uint64_t m, const uint64_t* const mul, const int32_t j) { // m is maximum 55 bits uint64_t high1; // 128 const uint64_t low1 = umul128(m, mul[1], &high1); // 64 uint64_t high0; // 64 umul128(m, mul[0], &high0); // 0 const uint64_t sum = high0 + low1; if (sum < high0) { ++high1; // overflow into high1 } return shiftright128(sum, high1, j - 64); } // This is faster if we don't have a 64x64->128-bit multiplication. static inline uint64_t mulShiftAll64(uint64_t m, const uint64_t* const mul, const int32_t j, uint64_t* const vp, uint64_t* const vm, const uint32_t mmShift) { m <<= 1; // m is maximum 55 bits uint64_t tmp; const uint64_t lo = umul128(m, mul[0], &tmp); uint64_t hi; const uint64_t mid = tmp + umul128(m, mul[1], &hi); hi += mid < tmp; // overflow into hi const uint64_t lo2 = lo + mul[0]; const uint64_t mid2 = mid + mul[1] + (lo2 < lo); const uint64_t hi2 = hi + (mid2 < mid); *vp = shiftright128(mid2, hi2, (uint32_t) (j - 64 - 1)); if (mmShift == 1) { const uint64_t lo3 = lo - mul[0]; const uint64_t mid3 = mid - mul[1] - (lo3 > lo); const uint64_t hi3 = hi - (mid3 > mid); *vm = shiftright128(mid3, hi3, (uint32_t) (j - 64 - 1)); } else { const uint64_t lo3 = lo + lo; const uint64_t mid3 = mid + mid + (lo3 < lo); const uint64_t hi3 = hi + hi + (mid3 < mid); const uint64_t lo4 = lo3 - mul[0]; const uint64_t mid4 = mid3 - mul[1] - (lo4 > lo3); const uint64_t hi4 = hi3 - (mid4 > mid3); *vm = shiftright128(mid4, hi4, (uint32_t) (j - 64)); } return shiftright128(mid, hi, (uint32_t) (j - 64 - 1)); } #endif // Returns e == 0 ? 1 : ceil(log_2(5^e)); requires 0 <= e <= 3528. static inline int32_t pow5bits(const int32_t e) { // This approximation works up to the point that the multiplication overflows at e = 3529. // If the multiplication were done in 64 bits, it would fail at 5^4004 which is just greater // than 2^9297. assert(e >= 0); assert(e <= 3528); return (int32_t) (((((uint32_t) e) * 1217359) >> 19) + 1); } // Returns floor(log_10(2^e)); requires 0 <= e <= 1650. static inline uint32_t log10Pow2(const int32_t e) { // The first value this approximation fails for is 2^1651 which is just greater than 10^297. assert(e >= 0); assert(e <= 1650); return (((uint32_t) e) * 78913) >> 18; } // Returns floor(log_10(5^e)); requires 0 <= e <= 2620. static inline uint32_t log10Pow5(const int32_t e) { // The first value this approximation fails for is 5^2621 which is just greater than 10^1832. assert(e >= 0); assert(e <= 2620); return (((uint32_t) e) * 732923) >> 20; } static inline uint64_t double_to_bits(const double d) { uint64_t bits = 0; memcpy(&bits, &d, sizeof(double)); return bits; } // A floating decimal representing m * 10^e. typedef struct floating_decimal_64 { uint64_t mantissa; // Decimal exponent's range is -324 to 308 // inclusive, and can fit in a short if needed. int32_t exponent; } floating_decimal_64; static inline floating_decimal_64 d2d(const uint64_t ieeeMantissa, const uint32_t ieeeExponent) { int32_t e2; uint64_t m2; if (ieeeExponent == 0) { // We subtract 2 so that the bounds computation has 2 additional bits. e2 = 1 - DOUBLE_BIAS - DOUBLE_MANTISSA_BITS - 2; m2 = ieeeMantissa; } else { e2 = (int32_t) ieeeExponent - DOUBLE_BIAS - DOUBLE_MANTISSA_BITS - 2; m2 = (1ull << DOUBLE_MANTISSA_BITS) | ieeeMantissa; } const bool even = (m2 & 1) == 0; const bool acceptBounds = even; // Step 2: Determine the interval of valid decimal representations. const uint64_t mv = 4 * m2; // Implicit bool -> int conversion. True is 1, false is 0. const uint32_t mmShift = ieeeMantissa != 0 || ieeeExponent <= 1; // We would compute mp and mm like this: // uint64_t mp = 4 * m2 + 2; // uint64_t mm = mv - 1 - mmShift; // Step 3: Convert to a decimal power base using 128-bit arithmetic. uint64_t vr, vp, vm; int32_t e10; bool vmIsTrailingZeros = false; bool vrIsTrailingZeros = false; if (e2 >= 0) { // I tried special-casing q == 0, but there was no effect on performance. // This expression is slightly faster than max(0, log10Pow2(e2) - 1). const uint32_t q = log10Pow2(e2) - (e2 > 3); e10 = (int32_t) q; const int32_t k = DOUBLE_POW5_INV_BITCOUNT + pow5bits((int32_t) q) - 1; const int32_t i = -e2 + (int32_t) q + k; vr = mulShiftAll64(m2, DOUBLE_POW5_INV_SPLIT[q], i, &vp, &vm, mmShift); if (q <= 21) { // This should use q <= 22, but I think 21 is also safe. Smaller values // may still be safe, but it's more difficult to reason about them. // Only one of mp, mv, and mm can be a multiple of 5, if any. const uint32_t mvMod5 = ((uint32_t) mv) - 5 * ((uint32_t) div5(mv)); if (mvMod5 == 0) { vrIsTrailingZeros = multipleOfPowerOf5(mv, q); } else if (acceptBounds) { // Same as min(e2 + (~mm & 1), pow5Factor(mm)) >= q // <=> e2 + (~mm & 1) >= q && pow5Factor(mm) >= q // <=> true && pow5Factor(mm) >= q, since e2 >= q. vmIsTrailingZeros = multipleOfPowerOf5(mv - 1 - mmShift, q); } else { // Same as min(e2 + 1, pow5Factor(mp)) >= q. vp -= multipleOfPowerOf5(mv + 2, q); } } } else { // This expression is slightly faster than max(0, log10Pow5(-e2) - 1). const uint32_t q = log10Pow5(-e2) - (-e2 > 1); e10 = (int32_t) q + e2; const int32_t i = -e2 - (int32_t) q; const int32_t k = pow5bits(i) - DOUBLE_POW5_BITCOUNT; const int32_t j = (int32_t) q - k; vr = mulShiftAll64(m2, DOUBLE_POW5_SPLIT[i], j, &vp, &vm, mmShift); if (q <= 1) { // {vr,vp,vm} is trailing zeros if {mv,mp,mm} has at least q trailing 0 bits. // mv = 4 * m2, so it always has at least two trailing 0 bits. vrIsTrailingZeros = true; if (acceptBounds) { // mm = mv - 1 - mmShift, so it has 1 trailing 0 bit iff mmShift == 1. vmIsTrailingZeros = mmShift == 1; } else { // mp = mv + 2, so it always has at least one trailing 0 bit. --vp; } } else if (q < 63) { // TODO(ulfjack): Use a tighter bound here. // We want to know if the full product has at least q trailing zeros. // We need to compute min(p2(mv), p5(mv) - e2) >= q // <=> p2(mv) >= q && p5(mv) - e2 >= q // <=> p2(mv) >= q (because -e2 >= q) vrIsTrailingZeros = multipleOfPowerOf2(mv, q); } } // Step 4: Find the shortest decimal representation in the interval of valid representations. int32_t removed = 0; uint8_t lastRemovedDigit = 0; uint64_t output; // On average, we remove ~2 digits. if (vmIsTrailingZeros || vrIsTrailingZeros) { // General case, which happens rarely (~0.7%). for (;;) { const uint64_t vpDiv10 = div10(vp); const uint64_t vmDiv10 = div10(vm); if (vpDiv10 <= vmDiv10) { break; } const uint32_t vmMod10 = ((uint32_t) vm) - 10 * ((uint32_t) vmDiv10); const uint64_t vrDiv10 = div10(vr); const uint32_t vrMod10 = ((uint32_t) vr) - 10 * ((uint32_t) vrDiv10); vmIsTrailingZeros &= vmMod10 == 0; vrIsTrailingZeros &= lastRemovedDigit == 0; lastRemovedDigit = (uint8_t) vrMod10; vr = vrDiv10; vp = vpDiv10; vm = vmDiv10; ++removed; } if (vmIsTrailingZeros) { for (;;) { const uint64_t vmDiv10 = div10(vm); const uint32_t vmMod10 = ((uint32_t) vm) - 10 * ((uint32_t) vmDiv10); if (vmMod10 != 0) { break; } const uint64_t vpDiv10 = div10(vp); const uint64_t vrDiv10 = div10(vr); const uint32_t vrMod10 = ((uint32_t) vr) - 10 * ((uint32_t) vrDiv10); vrIsTrailingZeros &= lastRemovedDigit == 0; lastRemovedDigit = (uint8_t) vrMod10; vr = vrDiv10; vp = vpDiv10; vm = vmDiv10; ++removed; } } if (vrIsTrailingZeros && lastRemovedDigit == 5 && vr % 2 == 0) { // Round even if the exact number is .....50..0. lastRemovedDigit = 4; } // We need to take vr + 1 if vr is outside bounds or we need to round up. output = vr + ((vr == vm && (!acceptBounds || !vmIsTrailingZeros)) || lastRemovedDigit >= 5); } else { // Specialized for the common case (~99.3%). Percentages below are relative to this. bool roundUp = false; const uint64_t vpDiv100 = div100(vp); const uint64_t vmDiv100 = div100(vm); if (vpDiv100 > vmDiv100) { // Optimization: remove two digits at a time (~86.2%). const uint64_t vrDiv100 = div100(vr); const uint32_t vrMod100 = ((uint32_t) vr) - 100 * ((uint32_t) vrDiv100); roundUp = vrMod100 >= 50; vr = vrDiv100; vp = vpDiv100; vm = vmDiv100; removed += 2; } // Loop iterations below (approximately), without optimization above: // 0: 0.03%, 1: 13.8%, 2: 70.6%, 3: 14.0%, 4: 1.40%, 5: 0.14%, 6+: 0.02% // Loop iterations below (approximately), with optimization above: // 0: 70.6%, 1: 27.8%, 2: 1.40%, 3: 0.14%, 4+: 0.02% for (;;) { const uint64_t vpDiv10 = div10(vp); const uint64_t vmDiv10 = div10(vm); if (vpDiv10 <= vmDiv10) { break; } const uint64_t vrDiv10 = div10(vr); const uint32_t vrMod10 = ((uint32_t) vr) - 10 * ((uint32_t) vrDiv10); roundUp = vrMod10 >= 5; vr = vrDiv10; vp = vpDiv10; vm = vmDiv10; ++removed; } // We need to take vr + 1 if vr is outside bounds or we need to round up. output = vr + (vr == vm || roundUp); } const int32_t exp = e10 + removed; floating_decimal_64 fd; fd.exponent = exp; fd.mantissa = output; return fd; } static inline int write_exponent(int32_t k, char* buf) { int sign = k < 0; if (sign) { *buf++ = '-'; k = -k; } if (k >= 100) { *buf++ = '0' + (k / 100); k %= 100; memcpy(buf, DIGIT_TABLE + (k * 2), 2); return sign + 3; } else if (k >= 10) { memcpy(buf, DIGIT_TABLE + (k * 2), 2); return sign + 2; } else { *buf = '0' + k; return sign + 1; } } /* Write a double to buf, requires 24 bytes of space */ static inline int write_f64(double f, char* buf, bool allow_nonfinite) { const uint64_t bits = double_to_bits(f); const int sign = ((bits >> (DOUBLE_MANTISSA_BITS + DOUBLE_EXPONENT_BITS)) & 1) != 0; const uint64_t ieee_mantissa = bits & ((1ull << DOUBLE_MANTISSA_BITS) - 1); const uint32_t ieee_exponent = (uint32_t) ((bits >> DOUBLE_MANTISSA_BITS) & ((1u << DOUBLE_EXPONENT_BITS) - 1)); /* Serialize all non-finite numbers as null */ if (MS_UNLIKELY(ieee_exponent == ((1 << DOUBLE_EXPONENT_BITS) - 1))) { if (MS_LIKELY(!allow_nonfinite)) { memcpy(buf, "null", 4); return 4; } else { if (ieee_mantissa == 0) { if (sign) { memcpy(buf, "-inf", 4); return 4; } memcpy(buf, "inf", 3); return 3; } memcpy(buf, "nan", 3); return 3; } } if (sign) { *buf++ = '-'; } if (ieee_exponent == 0 && ieee_mantissa == 0) { memcpy(buf, "0.0", 3); return sign + 3; } floating_decimal_64 v = d2d(ieee_mantissa, ieee_exponent); int length = write_u64(v.mantissa, buf) - buf; int32_t k = v.exponent; int32_t kk = length + k; if (0 <= k && kk <= 16) { /* XYZ00.0 */ memset(buf + length, '0', k + 2); *(buf + kk) = '.'; return sign + kk + 2; } else if (0 < kk && kk <= 16) { /* XY.Z */ memmove(buf + kk + 1, buf + kk, length - kk); *(buf + kk) = '.'; return sign + length + 1; } else if (-5 < kk && kk <= 0) { /* 0.0XYZ */ int offset = 2 - kk; memmove(buf + offset, buf, length); memset(buf, '0', offset); *(buf + 1) = '.'; return sign + length + offset; } else { /* X.YZe123 if length > 1 else Xe123 */ int offset = 0; if (length > 1) { offset = length; memmove(buf + 2, buf + 1, length - 1); *(buf + 1) = '.'; } *(buf + offset + 1) = 'e'; return sign + offset + 2 + write_exponent(kk - 1, buf + offset + 2); } } #endif // RYU_H python-msgspec-0.22.0/src/msgspec/structs.py000066400000000000000000000057401525673062400211040ustar00rootroot00000000000000from __future__ import annotations from typing import Any from . import NODEFAULT, Struct, field from ._core import ( # noqa Factory as _Factory, StructConfig, StructMeta, asdict, astuple, force_setattr, replace, ) from ._utils import get_class_annotations as _get_class_annotations __all__ = ( "FieldInfo", "StructConfig", "asdict", "astuple", "fields", "force_setattr", "replace", ) def __dir__(): return __all__ class FieldInfo(Struct): """A record describing a field in a struct type. Parameters ---------- name: str The field name as seen by Python code (e.g. ``field_one``). encode_name: str The name used when encoding/decoding the field. This may differ if the field is renamed (e.g. ``fieldOne``). type: Any The full field type annotation. default: Any, optional A default value for the field. Will be `NODEFAULT` if no default value is set. default_factory: Any, optional A callable that creates a default value for the field. Will be `NODEFAULT` if no ``default_factory`` is set. """ name: str encode_name: str type: Any default: Any = field(default_factory=lambda: NODEFAULT) default_factory: Any = field(default_factory=lambda: NODEFAULT) @property def required(self) -> bool: """A helper for checking whether a field is required""" return self.default is NODEFAULT and self.default_factory is NODEFAULT def fields(type_or_instance: Struct | type[Struct]) -> tuple[FieldInfo]: """Get information about the fields in a Struct. Parameters ---------- type_or_instance: A struct type or instance. Returns ------- tuple[FieldInfo] """ obj = type_or_instance # Struct class if isinstance(obj, StructMeta): annotated_cls = cls = obj # Struct instance elif isinstance(type(obj), StructMeta): annotated_cls = cls = type(obj) # Generic alias else: annotated_cls = obj cls = getattr(obj, "__origin__", obj) if not isinstance(cls, StructMeta): raise TypeError("Must be called with a struct type or instance") hints = _get_class_annotations(annotated_cls) npos = len(cls.__struct_fields__) - len(cls.__struct_defaults__) fields = [] for name, encode_name, default_obj in zip( cls.__struct_fields__, cls.__struct_encode_fields__, (NODEFAULT,) * npos + cls.__struct_defaults__, ): default = default_factory = NODEFAULT if isinstance(default_obj, _Factory): default_factory = default_obj.factory elif default_obj is not NODEFAULT: default = default_obj field = FieldInfo( name=name, encode_name=encode_name, type=hints[name], default=default, default_factory=default_factory, ) fields.append(field) return tuple(fields) python-msgspec-0.22.0/src/msgspec/structs.pyi000066400000000000000000000020271525673062400212500ustar00rootroot00000000000000from typing import Any, TypeVar, final from . import NODEFAULT, Struct __all__ = ( "FieldInfo", "StructConfig", "asdict", "astuple", "fields", "force_setattr", "replace", ) _S = TypeVar("_S", bound=Struct) def replace(struct: _S, /, **changes: Any) -> _S: ... def asdict(struct: Struct, /) -> dict[str, Any]: ... def astuple(struct: Struct, /) -> tuple[Any, ...]: ... def force_setattr(struct: Struct, name: str, value: Any, /) -> None: ... @final class StructConfig: frozen: bool eq: bool order: bool array_like: bool gc: bool repr_omit_defaults: bool omit_defaults: bool forbid_unknown_fields: bool weakref: bool dict: bool cache_hash: bool tag: str | int | None tag_field: str | None class FieldInfo(Struct): name: str encode_name: str type: Any default: Any = NODEFAULT default_factory: Any = NODEFAULT @property def required(self) -> bool: ... def fields(type_or_instance: Struct | type[Struct]) -> tuple[FieldInfo, ...]: ... python-msgspec-0.22.0/src/msgspec/toml.py000066400000000000000000000126211525673062400203440ustar00rootroot00000000000000from __future__ import annotations import datetime as _datetime from typing import TYPE_CHECKING, Any, TypeVar, overload from . import ( DecodeError as _DecodeError, convert as _convert, to_builtins as _to_builtins, ) if TYPE_CHECKING: from collections.abc import Callable from typing import Literal from typing_extensions import Buffer __all__ = ("encode", "decode") def __dir__(): return __all__ def _import_tomllib(): try: import tomllib # type: ignore return tomllib except ImportError: pass try: import tomli # type: ignore return tomli except ImportError: raise ImportError( "`msgspec.toml.decode` requires `tomli` be installed.\n\n" "Please either `pip` or `conda` install it as follows:\n\n" " $ python -m pip install tomli # using pip\n" " $ conda install tomli # or using conda" ) from None def _import_tomli_w(): try: import tomli_w # type: ignore return tomli_w except ImportError: raise ImportError( "`msgspec.toml.encode` requires `tomli_w` be installed.\n\n" "Please either `pip` or `conda` install it as follows:\n\n" " $ python -m pip install tomli_w # using pip\n" " $ conda install tomli_w # or using conda" ) from None def encode( obj: Any, *, enc_hook: Callable[[Any], Any] | None = None, order: Literal["deterministic", "sorted"] | None = None, ) -> bytes: """Serialize an object as TOML. Parameters ---------- obj : Any The object to serialize. enc_hook : callable, optional A callable to call for objects that aren't supported msgspec types. Takes the unsupported object and should return a supported object, or raise a ``NotImplementedError`` if unsupported. order : {None, 'deterministic', 'sorted'}, optional The ordering to use when encoding unordered compound types. - ``None``: All objects are encoded in the most efficient manner matching their in-memory representations. The default. - `'deterministic'`: Dict keys and set elements are sorted so that values which compare equal produce identical encoded output, regardless of insertion or iteration order. Useful when comparison/hashing of the encoded binary output is necessary. - `'sorted'`: Like `'deterministic'`, but *all* object-like types (structs, dataclasses, ...) are also sorted by field name before encoding. This is slower than `'deterministic'`, but may produce more human-readable output. Returns ------- data : bytes The serialized object. See Also -------- decode """ toml = _import_tomli_w() msg = _to_builtins( obj, builtin_types=(_datetime.datetime, _datetime.date, _datetime.time), str_keys=True, enc_hook=enc_hook, order=order, ) return toml.dumps(msg).encode("utf-8") _T = TypeVar("_T") @overload def decode( buf: Buffer | str, *, type: type[_T], strict: bool = True, dec_hook: Callable[[type[Any], Any], Any] | None = None, ) -> _T: ... @overload def decode( buf: Buffer | str, *, type: Any = ..., strict: bool = True, dec_hook: Callable[[type[Any], Any], Any] | None = None, ) -> Any: ... def decode( buf: Buffer | str, *, type: Any = Any, strict: bool = True, dec_hook: Callable[[type[Any], Any], Any] | None = None, ) -> Any: """Deserialize an object from TOML. Parameters ---------- buf : bytes-like or str The message to decode. type : type, optional A Python type (in type annotation form) to decode the object as. If provided, the message will be type checked and decoded as the specified type. Defaults to `Any`, in which case the message will be decoded using the default TOML types. strict : bool, optional Whether type coercion rules should be strict. Setting to False enables a wider set of coercion rules from string to non-string types for all values. Default is True. dec_hook : callable, optional An optional callback for handling decoding custom types. Should have the signature ``dec_hook(type: Type, obj: Any) -> Any``, where ``type`` is the expected message type, and ``obj`` is the decoded representation composed of only basic TOML types. This hook should transform ``obj`` into type ``type``, or raise a ``NotImplementedError`` if unsupported. Returns ------- obj : Any The deserialized object. See Also -------- encode """ toml = _import_tomllib() if isinstance(buf, str): str_buf = buf elif isinstance(buf, (bytes, bytearray)): str_buf = buf.decode("utf-8") else: # call `memoryview` first, since `bytes(1)` is actually valid str_buf = bytes(memoryview(buf)).decode("utf-8") try: obj = toml.loads(str_buf) except toml.TOMLDecodeError as exc: raise _DecodeError(str(exc)) from None if type is Any: return obj return _convert( obj, type, builtin_types=(_datetime.datetime, _datetime.date, _datetime.time), str_keys=True, strict=strict, dec_hook=dec_hook, ) python-msgspec-0.22.0/src/msgspec/yaml.py000066400000000000000000000124201525673062400203300ustar00rootroot00000000000000from __future__ import annotations import datetime as _datetime from typing import TYPE_CHECKING, Any, TypeVar, overload from . import ( DecodeError as _DecodeError, convert as _convert, to_builtins as _to_builtins, ) if TYPE_CHECKING: from collections.abc import Callable from typing import Literal from typing_extensions import Buffer __all__ = ("encode", "decode") def __dir__(): return __all__ def _import_pyyaml(name): try: import yaml # type: ignore except ImportError: raise ImportError( f"`msgspec.yaml.{name}` requires PyYAML be installed.\n\n" "Please either `pip` or `conda` install it as follows:\n\n" " $ python -m pip install pyyaml # using pip\n" " $ conda install pyyaml # or using conda" ) from None else: return yaml def encode( obj: Any, *, enc_hook: Callable[[Any], Any] | None = None, order: Literal["deterministic", "sorted"] | None = None, ) -> bytes: """Serialize an object as YAML. Parameters ---------- obj : Any The object to serialize. enc_hook : callable, optional A callable to call for objects that aren't supported msgspec types. Takes the unsupported object and should return a supported object, or raise a ``NotImplementedError`` if unsupported. order : {None, 'deterministic', 'sorted'}, optional The ordering to use when encoding unordered compound types. - ``None``: All objects are encoded in the most efficient manner matching their in-memory representations. The default. - `'deterministic'`: Dict keys and set elements are sorted so that values which compare equal produce identical encoded output, regardless of insertion or iteration order. Useful when comparison/hashing of the encoded binary output is necessary. - `'sorted'`: Like `'deterministic'`, but *all* object-like types (structs, dataclasses, ...) are also sorted by field name before encoding. This is slower than `'deterministic'`, but may produce more human-readable output. Returns ------- data : bytes The serialized object. Notes ----- This function requires that the third-party `PyYAML library `_ is installed. See Also -------- decode """ yaml = _import_pyyaml("encode") # Use the C extension if available Dumper = getattr(yaml, "CSafeDumper", yaml.SafeDumper) return yaml.dump_all( [ _to_builtins( obj, builtin_types=(_datetime.datetime, _datetime.date), enc_hook=enc_hook, order=order, ) ], encoding="utf-8", Dumper=Dumper, allow_unicode=True, sort_keys=False, ) _T = TypeVar("_T") @overload def decode( buf: Buffer | str, *, type: type[_T], strict: bool = True, dec_hook: Callable[[type[Any], Any], Any] | None = None, ) -> _T: ... @overload def decode( buf: Buffer | str, *, type: Any = ..., strict: bool = True, dec_hook: Callable[[type[Any], Any], Any] | None = None, ) -> Any: ... def decode( buf: Buffer | str, *, type: Any = Any, strict: bool = True, dec_hook: Callable[[type[Any], Any], Any] | None = None, ) -> Any: """Deserialize an object from YAML. Parameters ---------- buf : bytes-like or str The message to decode. type : type, optional A Python type (in type annotation form) to decode the object as. If provided, the message will be type checked and decoded as the specified type. Defaults to `Any`, in which case the message will be decoded using the default YAML types. strict : bool, optional Whether type coercion rules should be strict. Setting to False enables a wider set of coercion rules from string to non-string types for all values. Default is True. dec_hook : callable, optional An optional callback for handling decoding custom types. Should have the signature ``dec_hook(type: Type, obj: Any) -> Any``, where ``type`` is the expected message type, and ``obj`` is the decoded representation composed of only basic YAML types. This hook should transform ``obj`` into type ``type``, or raise a ``NotImplementedError`` if unsupported. Returns ------- obj : Any The deserialized object. Notes ----- This function requires that the third-party `PyYAML library `_ is installed. See Also -------- encode """ yaml = _import_pyyaml("decode") # Use the C extension if available Loader = getattr(yaml, "CSafeLoader", yaml.SafeLoader) if not isinstance(buf, (str, bytes)): # call `memoryview` first, since `bytes(1)` is actually valid buf = bytes(memoryview(buf)) try: obj = yaml.load(buf, Loader) except yaml.YAMLError as exc: raise _DecodeError(str(exc)) from None if type is Any: return obj return _convert( obj, type, builtin_types=(_datetime.datetime, _datetime.date), strict=strict, dec_hook=dec_hook, ) python-msgspec-0.22.0/tests/000077500000000000000000000000001525673062400157275ustar00rootroot00000000000000python-msgspec-0.22.0/tests/__init__.py000066400000000000000000000000001525673062400200260ustar00rootroot00000000000000python-msgspec-0.22.0/tests/prof/000077500000000000000000000000001525673062400166755ustar00rootroot00000000000000python-msgspec-0.22.0/tests/prof/__init__.py000066400000000000000000000000001525673062400207740ustar00rootroot00000000000000python-msgspec-0.22.0/tests/prof/perf/000077500000000000000000000000001525673062400176315ustar00rootroot00000000000000python-msgspec-0.22.0/tests/prof/perf/__init__.py000066400000000000000000000000001525673062400217300ustar00rootroot00000000000000python-msgspec-0.22.0/tests/prof/perf/conftest.py000066400000000000000000000006371525673062400220360ustar00rootroot00000000000000import pytest # codspeed CI does not allow running a matrix, or submitting the same benchmarks twice # under the same name (e.g. one run under arm, one under amd). easiest way around this # was to use autoparametrisation to pretend the tests are different, and then select # them in CI via '-k '. @pytest.fixture(autouse=True, params=["amd", "arm"]) def provide_fake_arch(request): return request.param python-msgspec-0.22.0/tests/prof/perf/test_encode_decode.py000066400000000000000000000176771525673062400240240ustar00rootroot00000000000000import datetime import decimal import enum import random import uuid from typing import Literal import pytest from pytest_codspeed import BenchmarkFixture import msgspec.json import msgspec.msgpack from benchmarks.bench_encodings import Directory from benchmarks.generate_data import make_filesystem_data @pytest.fixture() def file_system_data(): return make_filesystem_data(1000) json_decoder = msgspec.json.Decoder(type=Directory) json_encoder = msgspec.json.Encoder() msgpack_decoder = msgspec.json.Decoder(type=Directory) msgspec_encoder = msgspec.json.Encoder() @pytest.mark.parametrize( "encoder", [ pytest.param(json_encoder.encode, id="json"), pytest.param(msgspec_encoder.encode, id="msgpack"), ], ) def test_encode(benchmark: BenchmarkFixture, encoder, file_system_data): res = benchmark(encoder, file_system_data) assert isinstance(res, bytes) @pytest.mark.parametrize( "encoder,decoder", [ pytest.param(json_encoder.encode, json_decoder.decode, id="json"), pytest.param(msgspec_encoder.encode, msgpack_decoder.decode, id="msgpack"), ], ) def test_decode(benchmark: BenchmarkFixture, encoder, decoder, file_system_data): data = encoder(file_system_data) res = benchmark(decoder, data) assert isinstance(res, Directory) @pytest.mark.parametrize( "encoder,decoder", [ pytest.param(json_encoder.encode, json_decoder.decode, id="json"), pytest.param(msgspec_encoder.encode, msgpack_decoder.decode, id="msgpack"), ], ) def test_roundtrip(benchmark: BenchmarkFixture, encoder, decoder, file_system_data): def func(data): return decoder(encoder(data)) res = benchmark(func, file_system_data) assert isinstance(res, Directory) @pytest.mark.memory @pytest.mark.parametrize( "encoder,decoder", [ pytest.param(json_encoder.encode, json_decoder.decode, id="json"), pytest.param(msgspec_encoder.encode, msgpack_decoder.decode, id="msgpack"), ], ) def test_roundtrip_memory(benchmark: BenchmarkFixture, encoder, decoder): def func(data): return decoder(encoder(data)) res = benchmark(func, make_filesystem_data(1000)) assert isinstance(res, Directory) class SomeEnum(enum.Enum): FIELD_1 = enum.auto() FIELD_2 = enum.auto() FIELD_3 = enum.auto() FIELD_4 = enum.auto() FIELD_5 = enum.auto() FIELD_6 = enum.auto() FIELD_7 = enum.auto() FIELD_8 = enum.auto() FIELD_9 = enum.auto() FIELD_10 = enum.auto() @pytest.fixture( params=[ pytest.param(msgspec.json, id="json"), pytest.param(msgspec.msgpack, id="msgpack"), ] ) def proto(request): return request.param sample_data_mark = pytest.mark.parametrize( "make_data,target_type", [ pytest.param( lambda: random.sample(range(-100_000, 100_000), 10_000), list[int], id="int" ), pytest.param( lambda: [random.uniform(-100_000.0, 100_000.0) for _ in range(10_000)], list[float], id="float", ), pytest.param( lambda: [ decimal.Decimal(random.uniform(-100_000.0, 100_000.0)) for _ in range(10_000) ], list[decimal.Decimal], id="decimal", ), pytest.param( lambda: [ datetime.date(2000, 1, 1) + datetime.timedelta(days=i) for i in range(1, 10_000) ], list[datetime.date], id="date", ), pytest.param( lambda: [ datetime.datetime(2000, 1, 1) + datetime.timedelta(seconds=i) for i in range(1, 10_000) ], list[datetime.datetime], id="datetime", ), pytest.param( lambda: [ datetime.datetime(2000, 1, 1, tzinfo=datetime.UTC) + datetime.timedelta(seconds=i) for i in range(1, 10_000) ], list[datetime.datetime], id="datetimetz", ), pytest.param( lambda: [datetime.timedelta(seconds=i) for i in range(1, 10_000)], list[datetime.timedelta], id="timedelta", ), pytest.param( lambda: [ datetime.time(h, m, s) for h in range(24) for m in range(60) for s in range(60) ], list[datetime.time], id="time", ), pytest.param( lambda: [None for _ in range(10_000)], list[None], id="None", ), pytest.param( lambda: [False for _ in range(10_000)], list[Literal[False]], id="False", ), pytest.param( lambda: [True for _ in range(10_000)], list[Literal[True]], id="True", ), pytest.param( lambda: random.randbytes(10_000), bytes, id="bytes", ), pytest.param( lambda: random.randbytes(10_000), bytearray, id="bytearray", ), pytest.param( lambda: random.randbytes(10_000), memoryview, id="memoryview", ), pytest.param( lambda: random.randbytes(10_000).hex(), str, id="long_string", ), pytest.param( lambda: [[] * 10_000], list[list], id="list", ), pytest.param( lambda: tuple(() * 10_000), tuple[tuple, ...], id="tuple", ), pytest.param( lambda: [set() for _ in range(10_000)], list[set], id="set", ), pytest.param( lambda: [frozenset() for _ in range(10_000)], list[frozenset], id="frozenset", ), pytest.param( lambda: {str(i): i for i in range(10_000)}, dict[str, int], id="dict", ), pytest.param( lambda: [ uuid.uuid5(uuid.NAMESPACE_DNS, f"test-{i}") for i in range(10_000) ], list[uuid.UUID], id="uuid", ), pytest.param( lambda: [random.choice(list(SomeEnum)) for _ in range(10_000)], list[SomeEnum], id="enum", ), ], ) @sample_data_mark def test_decode_type(benchmark: BenchmarkFixture, proto, make_data, target_type): data = make_data() encoded = proto.encode(data) res = benchmark.pedantic( proto.decode, args=(encoded,), kwargs={"type": target_type}, warmup_rounds=10, ) assert res == data @sample_data_mark def test_encode_type(benchmark: BenchmarkFixture, proto, make_data, target_type): data = make_data() res = benchmark.pedantic( proto.encode, args=(data,), warmup_rounds=10, ) assert res == proto.encode(data) @pytest.mark.parametrize( "make_data,target_type", [ pytest.param( lambda: random.sample(range(-100_000, 100_000), 10_000), list[int], id="int" ), pytest.param( lambda: [random.uniform(-100_000.0, 100_000.0) for _ in range(10_000)], list[float], id="float", ), ], ) @pytest.mark.parametrize( "encode,decode", [ pytest.param(msgspec.json.encode, msgspec.json.decode, id="json"), pytest.param(msgspec.msgpack.encode, msgspec.msgpack.decode, id="msgpack"), pytest.param(lambda v: v, msgspec.convert, id="convert"), ], ) def test_decode_convert_type_non_strict( benchmark: BenchmarkFixture, decode, encode, make_data, target_type ): data = make_data() encoded = encode(data) res = benchmark.pedantic( decode, args=(encoded,), kwargs={"strict": False, "type": target_type}, warmup_rounds=10, ) assert res == data python-msgspec-0.22.0/tests/prof/perf/test_gc.py000066400000000000000000000011731525673062400216350ustar00rootroot00000000000000import gc from unittest.mock import patch import pytest from pytest_codspeed import BenchmarkFixture from benchmarks.bench_gc import Point, PointClass, PointClassSlots, PointGCFalse @pytest.mark.parametrize("cls", [Point, PointClass, PointClassSlots, PointGCFalse]) def test_gc_times(cls, benchmark: BenchmarkFixture): data = {i: cls(i, i, i) for i in range(1_000_000)} # noqa: F841 # benchmark() internally already calls 'gc.collect()' unless gc is disabled, so we # pretend it is disabled with patch("pytest_codspeed.plugin.gc.isenabled") as mock: mock.return_value = True benchmark(gc.collect) python-msgspec-0.22.0/tests/prof/perf/test_module.py000066400000000000000000000014231525673062400225270ustar00rootroot00000000000000import subprocess import sys import pytest @pytest.mark.parametrize( "module_name", [ "msgspec", "msgspec.structs", "msgspec.json", "msgspec.msgpack", "msgspec.inspect", "msgspec.yaml", "msgspec.toml", ], ) def test_import_time(benchmark, module_name): # also measures interpreter startup etc., but is the best we can do now, since we # don't have a fully isolated module, and some per-process global state, so # re-importing purely within the current interpreter doesn't get reliable timings def do_import(): subprocess.run([sys.executable, "-c", f"import {module_name}"], check=True) do_import() # execute once to reduce possibility of a super cold FS cache benchmark(do_import) python-msgspec-0.22.0/tests/prof/perf/test_structs.py000066400000000000000000000143611525673062400227560ustar00rootroot00000000000000import copy import pickle import random from typing import Annotated import pytest from pytest_codspeed import BenchmarkFixture import msgspec import msgspec.structs from msgspec import defstruct from msgspec.structs import replace as msgspec_replace TEMPLATE = """ class C{n}(Struct, order=True): a: int b: int c: int d: int e: int """ TEMPLATE_EMPTY = """ class C{n}(Struct, order=True): pass """ TEMPLATE_WITH_TAG_TRUE = """ class C{n}(Struct, order=True, tag=True): a: int b: int c: int d: int e: int """ TEMPLATE_WITH_CUSTOM_TAG = """ class C{n}(Struct, order=True, tag='my_tag'): a: int b: int c: int d: int e: int """ TEMPLATE_WITH_CUSTOM_TAG_FIELD = """ class C{n}(Struct, order=True, tag_field="my_tag_field"): a: int b: int c: int d: int e: int """ N = 1000 class Item(msgspec.Struct, order=True): a: int b: int c: int d: int e: int class EmptyStruct(msgspec.Struct): pass class Point(msgspec.Struct, order=True): x: int y: int class Account(msgspec.Struct, order=True): id: int balance: float active: bool class Address(msgspec.Struct, order=True): street: str city: str location: Point class Person(msgspec.Struct, order=True): name: str age: int address: Address accounts: list[Account] def make_person(i: int) -> Person: return Person( name=f"person-{i}", age=i, address=Address( street=f"{i} Main St", city="Springfield", location=Point(i, i) ), accounts=[ Account(id=i * 10 + j, balance=float(i), active=bool(j % 2)) for j in range(3) ], ) @pytest.mark.parametrize( "template", [ pytest.param(TEMPLATE_EMPTY, id="empty"), pytest.param(TEMPLATE, id="basic"), pytest.param(TEMPLATE_WITH_TAG_TRUE, id="tagged"), pytest.param(TEMPLATE_WITH_CUSTOM_TAG, id="custom_tag"), pytest.param(TEMPLATE_WITH_CUSTOM_TAG_FIELD, id="custom_tag_field"), ], ) def test_define(benchmark: BenchmarkFixture, template: str): source = "\n".join(template.format(n=i) for i in range(200)) code_obj = compile(source, "__main__", "exec") def fn(): ns = {"Struct": msgspec.Struct} exec(code_obj, ns) benchmark.pedantic(fn, warmup_rounds=10) def test_defstruct(benchmark: BenchmarkFixture): fields = [ "one", "two", "three", "four", ("int", int), ("str", str), ("list", list[str]), ("dict_str", dict[str, str]), ("dict_int", dict[str, int]), ("tuple_str", tuple[str, ...]), ("int_default", int, 10), ("str_default", str, ""), ("tuple_default", tuple[str, ...], ()), ("int_annotated", Annotated[int, msgspec.Meta(gt=1)], 1), ("str_annotated", Annotated[str, msgspec.Meta(min_length=2)], "ab"), ("str_pattern", Annotated[str, msgspec.Meta(pattern=r"\w\w")], "ab"), ] def fn(): return defstruct("SomeStruct", fields) res = benchmark.pedantic(fn, warmup_rounds=10) assert issubclass(res, msgspec.Struct) @pytest.mark.memory def test_create(benchmark): benchmark.pedantic( lambda: [Item(i, i, i, i, i) for i in range(N)], warmup_rounds=10, ) @pytest.mark.memory def test_empty_struct_create(benchmark: BenchmarkFixture): # empty struct to measure pure overhead without any type nodes benchmark.pedantic( lambda: [EmptyStruct() for _ in range(N)], warmup_rounds=10, ) @pytest.mark.memory def test_equality(benchmark): needle = Item(N - 1, N - 1, N - 1, N - 1, N - 1) haystack = [Item(i, i, i, i, i) for i in range(N)] random.shuffle(haystack) benchmark(haystack.index, needle) def test_equality_complex(benchmark: BenchmarkFixture): needle = make_person(N - 1) haystack = [make_person(i) for i in range(N)] random.shuffle(haystack) benchmark(haystack.index, needle) @pytest.mark.memory def test_order(benchmark: BenchmarkFixture): haystack = [Item(i, i, i, i, i) for i in range(N)] random.shuffle(haystack) benchmark(sorted, haystack) def test_pickle_dump(benchmark: BenchmarkFixture): items = [Item(i, i, i, i, i) for i in range(N)] res = benchmark.pedantic( pickle.dumps, args=(items,), warmup_rounds=10, ) assert pickle.loads(res) == items def test_pickle_load(benchmark: BenchmarkFixture): items = [Item(i, i, i, i, i) for i in range(N)] dumped = pickle.dumps(items) res = benchmark.pedantic( pickle.loads, args=(dumped,), warmup_rounds=10, ) assert res == items @pytest.fixture( params=[ "msgspec", pytest.param( "copy", marks=[ pytest.mark.skipif( "sys.version_info < (3, 13)", reason="only available on 3.13+", ) ], ), ] ) def replace_fn(request): if request.param == "msgspec": return msgspec_replace return copy.replace def test_replace(benchmark: BenchmarkFixture, replace_fn): item = Item(1, 2, 3, 4, 5) res = benchmark.pedantic( replace_fn, args=(item,), kwargs={"a": 0}, warmup_rounds=10, ) assert res == Item(0, 2, 3, 4, 5) def test_copy(benchmark: BenchmarkFixture): item = Item(1, 2, 3, 4, 5) res = benchmark.pedantic( copy.copy, args=(item,), warmup_rounds=10, ) assert res == item def test_copy_complex(benchmark: BenchmarkFixture): person = make_person(1) res = benchmark.pedantic( copy.copy, args=(person,), warmup_rounds=10, ) assert res == person @pytest.mark.parametrize( "cls_or_instance", [ pytest.param(Item, id="class"), pytest.param(Person, id="complex_class"), pytest.param(Item(1, 2, 3, 4, 5), id="instance"), pytest.param(make_person(1), id="complex_instance"), ], ) def test_fields(benchmark: BenchmarkFixture, cls_or_instance): res = benchmark.pedantic( msgspec.structs.fields, args=(cls_or_instance,), warmup_rounds=10, ) assert res == msgspec.structs.fields(cls_or_instance) python-msgspec-0.22.0/tests/typing/000077500000000000000000000000001525673062400172415ustar00rootroot00000000000000python-msgspec-0.22.0/tests/typing/basic_typing_examples.py000077500000000000000000001056371525673062400242030ustar00rootroot00000000000000# fmt: off from __future__ import annotations import array from collections.abc import Callable import decimal import pickle from typing import Annotated, Any, Final, Literal, final import msgspec from typing_extensions import assert_type, Buffer def check___version__() -> None: assert_type(msgspec.__version__, str) def check_exceptions() -> None: assert_type(msgspec.MsgspecError, type[msgspec.MsgspecError]) assert_type(msgspec.EncodeError, type[msgspec.EncodeError]) assert_type(msgspec.DecodeError, type[msgspec.DecodeError]) assert_type(msgspec.ValidationError, type[msgspec.ValidationError]) def check_unset() -> None: assert_type(msgspec.UNSET, Literal[msgspec.UnsetType.UNSET]) assert_type(type(msgspec.UNSET), type[msgspec.UnsetType]) str(msgspec.UNSET) pickle.dumps(msgspec.UNSET) def check_unset_type_lowering(x: int | msgspec.UnsetType) -> None: if x is msgspec.UNSET: # this is a bug in `pyrefly` https://github.com/facebook/pyrefly/issues/3820: assert_type(x, Literal[msgspec.UnsetType.UNSET]) # pyrefly: ignore[assert-type] else: assert_type(x, int) def check_unset_type_truthiness_lowering(x: str | msgspec.UnsetType) -> None: if x: assert_type(x, str) def check_nodefault() -> None: assert_type(msgspec.NODEFAULT, Literal[msgspec._NoDefault.NODEFAULT]) str(msgspec.NODEFAULT) pickle.dumps(msgspec.NODEFAULT) ########################################################## # Structs # ########################################################## def check_struct() -> None: class Test(msgspec.Struct): x: int y: str t = Test(1, "foo") assert_type(t, Test) assert_type(t.x, int) assert_type(t.y, str) t2 = Test(x=2, y="bar") assert_type(t2, Test) assert_type(t2.x, int) assert_type(t2.y, str) def check_struct_field() -> None: class Test(msgspec.Struct): a: int b: int = msgspec.field(name="b_field") x: int = msgspec.field(default=1) y: list[int] = msgspec.field(default_factory=lambda: [1, 2, 3]) x2: int = msgspec.field(default=1, name="x2_field") y2: list[int] = msgspec.field(default_factory=lambda: [1, 2, 3], name="y2_field") Test(1, 2) Test(1, 2, 3) Test(1, 2, 3, [4]) Test(1, 2, 3, [4], 5) Test(1, 2, 3, [4], 5, [6]) msgspec.field(default=1, default_factory=int) # type: ignore[call-overload] # pyright: ignore[reportCallIssue] # pyrefly: ignore[no-matching-overload] def check_struct_kw_only() -> None: class Test(msgspec.Struct, kw_only=True): x: int y: str t = Test(y="foo", x=1) def check_struct_kw_only_base_class() -> None: class Base(msgspec.Struct, kw_only=True): d: bytes c: str = "default" class Test(Base): a: int b: list[int] = [] Test(1, d=b"foo") Test(1, [1, 2, 3], d=b"foo", c="test") def check_struct_kw_only_subclass() -> None: class Base(msgspec.Struct): d: bytes c: str = "default" class Test(Base, kw_only=True): a: int b: list[int] = [] Test(b"foo", a=1) Test(b"foo", "test", a=1, b=[1, 2, 3]) def check_struct_final_fields() -> None: """Test that type checkers support `Final` fields for dataclass_transform""" class Test(msgspec.Struct): x: Final[int] = 0 y: Final = 1 t = Test(0, 1) assert_type(t.x, int) assert_type(t.y, Literal[1]) t2 = Test(x=0, y=1) assert_type(t2.x, int) assert_type(t2.y, Literal[1]) def check_struct_repr_omit_defaults() -> None: class Test(msgspec.Struct, repr_omit_defaults=True): x: int y: str t = Test(1, "foo") assert_type(t.x, int) assert_type(t.y, str) def check_struct_omit_defaults() -> None: class Test(msgspec.Struct, omit_defaults=True): x: int y: str t = Test(1, "foo") assert_type(t, Test) assert_type(t.x, int) assert_type(t.y, str) def check_struct_forbid_unknown_fields() -> None: class Test(msgspec.Struct, forbid_unknown_fields=True): x: int y: str t = Test(1, "foo") assert_type(t, Test) assert_type(t.x, int) assert_type(t.y, str) def check_struct_rename() -> None: class TestLower(msgspec.Struct, rename="lower"): x: int class TestUpper(msgspec.Struct, rename="upper"): x: int class TestCamel(msgspec.Struct, rename="camel"): x: int class TestPascal(msgspec.Struct, rename="pascal"): x: int class TestKebab(msgspec.Struct, rename="kebab"): x: int class TestCallable(msgspec.Struct, rename=lambda x: x.title()): x: int class TestCallableNone(msgspec.Struct, rename=lambda x: None): x: int class TestMapping(msgspec.Struct, rename={"x": "X"}): x: int class TestNone(msgspec.Struct, rename=None): x: int assert_type(TestLower(1).x, int) assert_type(TestUpper(2).x, int) assert_type(TestCamel(3).x, int) assert_type(TestPascal(4).x, int) assert_type(TestCallable(5).x, int) assert_type(TestNone(6).x, int) def check_struct_array_like() -> None: class Test(msgspec.Struct, array_like=True): x: int y: str t = Test(1, "foo") assert_type(t, Test) assert_type(t.x, int) assert_type(t.y, str) def check_struct_frozen() -> None: class Test(msgspec.Struct, frozen=True): x: int y: str t = Test(1, "foo") assert_type(t, Test) assert_type(t.x, int) assert_type(t.y, str) def check_struct_eq() -> None: class Test(msgspec.Struct, eq=False): x: int y: str t = Test(1, "foo") t2 = Test(1, "foo") assert_type(t == t2, bool) assert_type(t, Test) assert_type(t.x, int) assert_type(t.y, str) def check_struct_order() -> None: class Test(msgspec.Struct, order=True): x: int y: str t = Test(1, "foo") assert_type(t, Test) assert_type(t.x, int) assert_type(t.y, str) def check_struct_gc() -> None: class Test(msgspec.Struct, gc=False): x: int y: str t = Test(1, "foo") assert_type(t, Test) assert_type(t.x, int) assert_type(t.y, str) def check_struct_weakref() -> None: class Test(msgspec.Struct, weakref=True): x: int y: str t = Test(1, "foo") assert_type(t, Test) assert_type(t.x, int) assert_type(t.y, str) def check_struct_dict() -> None: class Test(msgspec.Struct, dict=True): x: int y: str t = Test(1, "foo") assert_type(t, Test) assert_type(t.x, int) assert_type(t.y, str) def check_struct_cache_hash() -> None: class Test(msgspec.Struct, cache_hash=True): x: int y: str t = Test(1, "foo") assert_type(t, Test) assert_type(t.x, int) assert_type(t.y, str) def check_struct_tag_tag_field() -> None: class Test1(msgspec.Struct, tag=None): pass class Test2(msgspec.Struct, tag=True): pass class Test3(msgspec.Struct, tag=False): pass class Test4(msgspec.Struct, tag="mytag"): pass class Test5(msgspec.Struct, tag=123): pass class Test6(msgspec.Struct, tag=str.lower): pass class Test7(msgspec.Struct, tag=lambda n: len(n)): pass class Test8(msgspec.Struct, tag_field=None): pass class Test9(msgspec.Struct, tag_field="type"): pass def check_struct_methods() -> None: class Point(msgspec.Struct): x: int y: int a = Point(1, 2) b = Point(3, 4) assert_type(a == b, bool) a.x = a.x + b.y repr(a) for item in a.__rich_repr__(): assert_type(item, tuple[str, Any]) def check_struct_attributes() -> None: class Point(msgspec.Struct): x: int y: int assert_type(Point.__struct_fields__, tuple[str, ...]) assert_type(Point.__struct_defaults__, tuple[Any, ...]) for field in Point.__match_args__: # mypy inferences `field` as `str`, # pyright inferences `field` as `Literal['x', 'y']` _field_str: str = field p = Point(1, 2) assert_type(p.__struct_fields__, tuple[str, ...]) assert_type(p.__struct_encode_fields__, tuple[str, ...]) assert_type(p.__struct_defaults__, tuple[Any, ...]) def check_struct_config() -> None: class Point(msgspec.Struct): x: int y: int config = Point.__struct_config__ assert_type(config, msgspec.structs.StructConfig) assert_type(config.frozen, bool) assert_type(config.eq, bool) assert_type(config.order, bool) assert_type(config.array_like, bool) assert_type(config.gc, bool) assert_type(config.repr_omit_defaults, bool) assert_type(config.omit_defaults, bool) assert_type(config.forbid_unknown_fields, bool) assert_type(config.weakref, bool) assert_type(config.dict, bool) assert_type(config.cache_hash, bool) assert_type(config.tag, str | int | None) assert_type(config.tag_field, str | None) ########################################################## # defstruct # ########################################################## def check_defstruct() -> None: Test = msgspec.defstruct("Test", ["x", "y"]) for field in Test.__struct_fields__: assert_type(field, str) Test(1, y=2) def check_defstruct_field_types() -> None: Test = msgspec.defstruct( "Test", ( "x", ("a", int), ("b", int | None), ("c", list[int]), ("d", Annotated[int, msgspec.Meta(ge=0)]), ("e", Literal["a", "b"]), ("f", str, "default"), ), ) def check_defstruct_bases() -> None: class Base(msgspec.Struct): pass class Mixin: pass msgspec.defstruct("Test", ["x", "y"], bases=(Mixin, Base)) msgspec.defstruct("Test2", ["x", "y"], bases=None) def check_defstruct_namespace() -> None: msgspec.defstruct("Test", ["x", "y"], namespace={"classval": 1}) msgspec.defstruct("Test2", ["x", "y"], namespace=None) def check_defstruct_module() -> None: msgspec.defstruct("Test", ["x", "y"], module="mymod") msgspec.defstruct("Test2", ["x", "y"], module=None) def check_defstruct_config_options() -> None: Test = msgspec.defstruct( "Test", ("x", "y"), omit_defaults=True, forbid_unknown_fields=True, frozen=True, order=True, eq=True, kw_only=True, repr_omit_defaults=True, array_like=True, dict=True, weakref=True, cache_hash=True, gc=False, tag="mytag", tag_field="mytagfield", rename="lower" ) ########################################################## # msgspec.structs # ########################################################## def check_replace() -> None: class Test(msgspec.Struct): x: int y: int struct: int struct = Test(1, 2, 3) assert_type(msgspec.structs.replace(struct), Test) assert_type(msgspec.structs.replace(struct, x=1), Test) assert_type(msgspec.structs.replace(struct, struct=1), Test) msgspec.structs.replace(object(), x=1) # type: ignore[type-var] # pyright: ignore[reportArgumentType] # pyrefly: ignore[bad-specialization] def check_asdict() -> None: class Test(msgspec.Struct): x: int y: int x = Test(1, 2) o = msgspec.structs.asdict(x) assert_type(o, dict[str, Any]) assert_type(o["foo"], Any) msgspec.structs.asdict(struct=x) # type: ignore[call-arg] # pyright: ignore[reportCallIssue] # pyrefly: ignore[unexpected-keyword] def check_astuple() -> None: class Test(msgspec.Struct): x: int y: int x = Test(1, 2) o = msgspec.structs.astuple(x) assert_type(o, tuple[Any, ...]) assert_type(o[0], Any) msgspec.structs.astuple(struct=x) # type: ignore[call-arg] # pyright: ignore[reportCallIssue] # pyrefly: ignore[unexpected-keyword] def check_force_setattr() -> None: class Point(msgspec.Struct, frozen=True): x: int y: int obj = Point(1, 2) msgspec.structs.force_setattr(obj, "x", 3) msgspec.structs.force_setattr(struct=obj, name="x", value=3) # type: ignore[call-arg] # pyright: ignore[reportCallIssue] # pyrefly: ignore[unexpected-keyword] def check_fields() -> None: class Test(msgspec.Struct): x: int y: int x = Test(1, 2) res1 = msgspec.structs.fields(x) assert_type(res1, tuple[msgspec.structs.FieldInfo, ...]) res2 = msgspec.structs.fields(Test) assert_type(res2, tuple[msgspec.structs.FieldInfo, ...]) for field in res1: assert_type(field, msgspec.structs.FieldInfo) assert_type(field.required, bool) assert_type(field.name, str) ########################################################## # Meta # ########################################################## def check_meta_constructor() -> None: msgspec.Meta() for val in [1, 1.5, None]: msgspec.Meta(gt=val) msgspec.Meta(ge=val) msgspec.Meta(lt=val) msgspec.Meta(le=val) msgspec.Meta(multiple_of=val) for val2 in ["string", None]: msgspec.Meta(pattern=val2) msgspec.Meta(title=val2) msgspec.Meta(description=val2) for val3 in [1, None]: msgspec.Meta(min_length=val3) msgspec.Meta(max_length=val3) for val4 in [True, False, None]: msgspec.Meta(tz=val4) for val5 in [[1, 2, 3], None]: msgspec.Meta(examples=val5) for val6 in [{"foo": "bar"}, None]: msgspec.Meta(extra_json_schema=val6) msgspec.Meta(extra=val6) Meta = msgspec.Meta # Numeric cases: Meta(gt=1, lt=5) Meta(gt=1, le=5) Meta(ge=1, lt=5) Meta(ge=1, le=5) Meta(gt=1, lt=5, multiple_of=2) Meta(gt=1, le=5, multiple_of=0.5) Meta(ge=1.0, lt=5.0, multiple_of=0.5) Meta( ge=1, le=5, multiple_of=1, title='title', examples=[1, 2], description='descr', extra={}, extra_json_schema={}, ) # Other: Meta(min_length=1, max_length=5) Meta( min_length=1, max_length=5, title='title', examples=[1, 2], description='descr', extra={'extra': 'extra'}, extra_json_schema={'extra': 'extra'}, ) # Invalid cases: Meta(gt=1, ge=5) # type: ignore[call-overload] # pyright: ignore[reportCallIssue] # pyrefly: ignore[no-matching-overload] Meta(le=1, lt=5) # type: ignore[call-overload] # pyright: ignore[reportCallIssue] # pyrefly: ignore[no-matching-overload] Meta(le=1, min_length=1) # type: ignore[call-overload] # pyright: ignore[reportCallIssue] # pyrefly: ignore[no-matching-overload] Meta(gt=1.0, max_length=1.5) # type: ignore[call-overload] # pyright: ignore[reportCallIssue] # pyrefly: ignore[no-matching-overload] Meta(multiple_of=1, max_length=1.5) # type: ignore[call-overload] # pyright: ignore[reportCallIssue] # pyrefly: ignore[no-matching-overload] def check_meta_attributes() -> None: c = msgspec.Meta() assert_type(c.title, str | None) assert_type(c.description, str | None) assert_type(c.tz, bool | None) def check_meta_equal() -> None: c1 = msgspec.Meta() c2 = msgspec.Meta() assert_type(c1 == c2, bool) def check_meta_methods() -> None: c = msgspec.Meta() for field in c.__rich_repr__(): assert_type(field, tuple[str, Any]) ########################################################## # Raw # ########################################################## def check_raw_constructor() -> None: r = msgspec.Raw() r2 = msgspec.Raw(b"test") r3 = msgspec.Raw(bytearray(b"test")) r4 = msgspec.Raw(memoryview(b"test")) r2 = msgspec.Raw("test") msgspec.Raw(msg=b"test") # type: ignore[call-overload] # pyright: ignore[reportCallIssue] # pyrefly: ignore[no-matching-overload] def check_raw_copy() -> None: r = msgspec.Raw() r2 = r.copy() assert_type(r2, msgspec.Raw) def check_raw_methods() -> None: r1 = msgspec.Raw(b"a") r2 = msgspec.Raw(b"b") assert_type(r1 == r2, bool) memoryview(r1) # buffer protocol def check_raw_pass_to_decode() -> None: r = msgspec.Raw() res = msgspec.json.decode(r) res2 = msgspec.msgpack.decode(r) ########################################################## # MessagePack # ########################################################## def check_msgpack_Encoder_encode() -> None: enc = msgspec.msgpack.Encoder() b = enc.encode([1, 2, 3]) assert_type(b, bytes) def check_msgpack_Encoder_encode_into() -> None: enc = msgspec.msgpack.Encoder() buf = bytearray(48) enc.encode_into([1, 2, 3], buf) enc.encode_into([1, 2, 3], buf, 2) enc.encode_into([1, 2, 3], buf, None) # type: ignore[arg-type] # pyright: ignore[reportArgumentType] # pyrefly: ignore[bad-argument-type] def check_msgpack_encode() -> None: b = msgspec.msgpack.encode([1, 2, 3]) assert_type(b, bytes) def check_msgpack_Decoder_decode_any() -> None: dec = msgspec.msgpack.Decoder() b = msgspec.msgpack.encode([1, 2, 3]) o = dec.decode(b) assert_type(dec, msgspec.msgpack.Decoder[Any]) assert_type(o, Any) def check_msgpack_Decoder_decode_typed() -> None: dec = msgspec.msgpack.Decoder(list[int]) b = msgspec.msgpack.encode([1, 2, 3]) o = dec.decode(b) assert_type(dec, msgspec.msgpack.Decoder[list[int]]) assert_type(o, list[int]) def check_msgpack_Decoder_decode_union() -> None: # Pyright doesn't require the annotation, but mypy does until TypeForm # is supported. This is mostly checking that no error happens here. dec: msgspec.msgpack.Decoder[int | str] = msgspec.msgpack.Decoder(int | str) o = dec.decode(b'') assert_type(o, int | str) def check_msgpack_Decoder_decode_type_comment() -> None: dec = msgspec.msgpack.Decoder() # type: msgspec.msgpack.Decoder[list[int]] # pyright: ignore[reportTypeCommentUsage] b = msgspec.msgpack.encode([1, 2, 3]) o = dec.decode(b) # pyrefly does not support type comments: assert_type(dec, msgspec.msgpack.Decoder[list[int]]) # pyrefly: ignore[assert-type] assert_type(o, list[int]) # pyrefly: ignore[assert-type] def check_msgpack_decode_any() -> None: b = msgspec.msgpack.encode([1, 2, 3]) o = msgspec.msgpack.decode(b) assert_type(o, Any) def check_msgpack_decode_typed() -> None: b = msgspec.msgpack.encode([1, 2, 3]) o = msgspec.msgpack.decode(b, type=list[int]) assert_type(o, list[int]) def check_msgpack_decode_from_buffer() -> None: msg = msgspec.msgpack.encode([1, 2, 3]) msgspec.toml.decode(memoryview(msg)) def check_msgpack_decode_typed_union() -> None: o: int | str = msgspec.msgpack.decode(b"", type=int | str) assert_type(o, int | str) def check_msgpack_encode_enc_hook() -> None: msgspec.msgpack.encode(object(), enc_hook=lambda x: None) def check_msgpack_Encoder_enc_hook() -> None: msgspec.msgpack.Encoder(enc_hook=lambda x: None) def check_msgpack_order() -> None: enc = msgspec.msgpack.Encoder(order=None) msgspec.msgpack.Encoder(order='deterministic') msgspec.msgpack.Encoder(order='sorted') assert_type(enc.order, Literal['deterministic', 'sorted'] | None) msgspec.msgpack.encode({"a": 1}, order=None) msgspec.msgpack.encode({"a": 1}, order='deterministic') msgspec.msgpack.encode({"a": 1}, order='sorted') def check_msgpack_Encoder_decimal_format() -> None: enc = msgspec.msgpack.Encoder(decimal_format="string") msgspec.msgpack.Encoder(decimal_format="number") msgspec.msgpack.Encoder(decimal_format=lambda x: str(x)) assert_type(enc.decimal_format, Literal['string', 'number'] | Callable[[decimal.Decimal], Any]) def check_msgpack_Encoder_uuid_format() -> None: enc = msgspec.msgpack.Encoder(uuid_format="canonical") msgspec.msgpack.Encoder(uuid_format="hex") msgspec.msgpack.Encoder(uuid_format="bytes") assert_type(enc.uuid_format, Literal['canonical', 'hex', 'bytes']) def check_msgpack_decode_dec_hook() -> None: def dec_hook(typ: type, obj: Any) -> Any: return typ(obj) msgspec.msgpack.decode(b"test", dec_hook=dec_hook) msgspec.msgpack.Decoder(dec_hook=dec_hook) def check_msgpack_decode_ext_hook() -> None: def ext_hook(code: int, data: memoryview) -> Any: return pickle.loads(data) msgspec.msgpack.decode(b"test", ext_hook=ext_hook) msgspec.msgpack.Decoder(ext_hook=ext_hook) def check_msgpack_Decoder_strict() -> None: dec = msgspec.msgpack.Decoder(list[int], strict=False) assert_type(dec.strict, bool) def check_msgpack_decode_strict() -> None: out = msgspec.msgpack.decode(b'', type=list[int], strict=False) assert_type(out, list[int]) def check_msgpack_Ext() -> None: ext = msgspec.msgpack.Ext(1, b"test") assert_type(ext.code, int) assert_type(ext.data, Buffer) assert_type(msgspec.msgpack.Ext(1, bytearray()), msgspec.msgpack.Ext) assert_type(msgspec.msgpack.Ext(1, memoryview(b'')), msgspec.msgpack.Ext) assert_type(msgspec.msgpack.Ext(1, array.array('i', [1, 2, 3])), msgspec.msgpack.Ext) msgspec.msgpack.Ext(code=1, data=b"test") # type: ignore[call-arg] # pyright: ignore[reportCallIssue] # pyrefly: ignore[unexpected-keyword] # Non buffers: msgspec.msgpack.Ext(1, {}) # type: ignore[arg-type] # pyright: ignore[reportArgumentType] # pyrefly: ignore[bad-argument-type] ########################################################## # JSON # ########################################################## def check_json_Encoder_encode() -> None: enc = msgspec.json.Encoder() b = enc.encode([1, 2, 3]) assert_type(b, bytes) def check_json_Encoder_encode_lines() -> None: enc = msgspec.json.Encoder() items = [{"x": 1}, 2] b = enc.encode_lines(items) b2 = enc.encode_lines(i for i in items) assert_type(b, bytes) assert_type(b2, bytes) def check_json_Encoder_encode_into() -> None: enc = msgspec.json.Encoder() buf = bytearray(48) enc.encode_into([1, 2, 3], buf) enc.encode_into([1, 2, 3], buf, 2) enc.encode_into([1, 2, 3], buf, None) # type: ignore[arg-type] # pyright: ignore[reportArgumentType] # pyrefly: ignore[bad-argument-type] def check_json_encode() -> None: b = msgspec.json.encode([1, 2, 3]) assert_type(b, bytes) def check_json_Decoder_decode_any() -> None: dec = msgspec.json.Decoder() b = msgspec.json.encode([1, 2, 3]) o = dec.decode(b) assert_type(dec, msgspec.json.Decoder[Any]) assert_type(o, Any) def check_json_Decoder_decode_typed() -> None: dec = msgspec.json.Decoder(list[int]) b = msgspec.json.encode([1, 2, 3]) o = dec.decode(b) assert_type(dec, msgspec.json.Decoder[list[int]]) assert_type(o, list[int]) def check_json_Decoder_decode_type_comment() -> None: dec = msgspec.json.Decoder() # type: msgspec.json.Decoder[list[int]] # pyright: ignore[reportTypeCommentUsage] b = msgspec.json.encode([1, 2, 3]) o = dec.decode(b) # pyrefly does not support type comments: assert_type(dec, msgspec.json.Decoder[list[int]]) # pyrefly: ignore[assert-type] assert_type(o, list[int]) # pyrefly: ignore[assert-type] def check_json_Decoder_decode_union() -> None: dec: msgspec.json.Decoder[int | str] = msgspec.json.Decoder(int | str) o = dec.decode(b'') assert_type(o, int | str) def check_json_Decoder_decode_from_str() -> None: dec = msgspec.json.Decoder(list[int]) o = dec.decode("[1, 2, 3]") assert_type(o, list[int]) def check_json_Decoder_decode_lines_any() -> None: dec = msgspec.json.Decoder() o = dec.decode_lines(b'1\n2\n3') assert_type(o, list[Any]) def check_json_Decoder_decode_lines_typed() -> None: dec = msgspec.json.Decoder(int) o = dec.decode_lines(b'1\n2\n3') assert_type(o, list[int]) def check_json_decode_any() -> None: b = msgspec.json.encode([1, 2, 3]) o = msgspec.json.decode(b) assert_type(o, Any) def check_json_decode_typed() -> None: b = msgspec.json.encode([1, 2, 3]) o = msgspec.json.decode(b, type=list[int]) assert_type(o, list[int]) def check_json_decode_typed_union() -> None: o: int | str = msgspec.json.decode(b"", type=int | str) assert_type(o, int | str) def check_json_decode_from_str() -> None: msgspec.json.decode("[1, 2, 3]") o = msgspec.json.decode("[1, 2, 3]", type=list[int]) assert_type(o, list[int]) def check_json_decode_from_buffer() -> None: msgspec.json.decode(memoryview(b"[1, 2, 3]")) def check_json_encode_enc_hook() -> None: msgspec.json.encode(object(), enc_hook=lambda x: None) def check_json_Encoder_enc_hook() -> None: msgspec.json.Encoder(enc_hook=lambda x: None) def check_json_order() -> None: enc = msgspec.json.Encoder(order=None) msgspec.json.Encoder(order='deterministic') msgspec.json.Encoder(order='sorted') assert_type(enc.order, Literal['deterministic', 'sorted'] | None) msgspec.json.encode({"a": 1}, order=None) msgspec.json.encode({"a": 1}, order='deterministic') msgspec.json.encode({"a": 1}, order='sorted') def check_json_Encoder_decimal_format() -> None: enc = msgspec.json.Encoder(decimal_format="string") msgspec.json.Encoder(decimal_format="number") msgspec.json.Encoder(decimal_format=lambda x: str(x)) assert_type(enc.decimal_format, Literal['string', 'number'] | Callable[[decimal.Decimal], Any]) def check_json_Encoder_uuid_format() -> None: enc = msgspec.json.Encoder(uuid_format="canonical") msgspec.json.Encoder(uuid_format="hex") assert_type(enc.uuid_format, Literal['canonical', 'hex']) def check_json_decode_dec_hook() -> None: def dec_hook(typ: type, obj: Any) -> Any: return typ(obj) msgspec.json.decode(b"test", dec_hook=dec_hook) msgspec.json.Decoder(dec_hook=dec_hook) def check_json_Decoder_float_hook() -> None: msgspec.json.Decoder(float_hook=None) msgspec.json.Decoder(float_hook=float) dec = msgspec.json.Decoder(float_hook=decimal.Decimal) if dec.float_hook is not None: assert_type(dec.float_hook("1.5"), Any) def check_json_Decoder_strict() -> None: dec = msgspec.json.Decoder(list[int], strict=False) assert_type(dec.strict, bool) def check_json_decode_strict() -> None: out = msgspec.json.decode(b'', type=list[int], strict=False) assert_type(out, list[int]) def check_json_format() -> None: assert_type(msgspec.json.format(b"test"), bytes) assert_type(msgspec.json.format(b"test", indent=4), bytes) assert_type(msgspec.json.format("test"), str) assert_type(msgspec.json.format("test", indent=4), str) ########################################################## # YAML # ########################################################## def check_yaml_encode() -> None: b = msgspec.yaml.encode([1, 2, 3]) assert_type(b, bytes) def check_yaml_decode_any() -> None: assert_type(msgspec.yaml.decode(b"[1, 2, 3]"), Any) assert_type(msgspec.yaml.decode("[1, 2, 3]"), Any) assert_type(msgspec.yaml.decode(bytearray()), Any) assert_type(msgspec.yaml.decode(memoryview(b'')), Any) # Not buffers: msgspec.yaml.decode([]) # type: ignore[call-overload] # pyright: ignore[reportArgumentType] # pyrefly: ignore[bad-argument-type] def check_yaml_decode_typed() -> None: assert_type(msgspec.yaml.decode(b"[1, 2, 3]", type=list[int]), list[int]) assert_type(msgspec.yaml.decode("[]", type=list[str]), list[str]) def check_yaml_decode_typed_union() -> None: o: int | str = msgspec.yaml.decode(b"1", type=int | str) assert_type(o, int | str) def check_yaml_decode_from_str() -> None: msgspec.yaml.decode("[1, 2, 3]") o = msgspec.yaml.decode("[1, 2, 3]", type=list[int]) assert_type(o, list[int]) def check_yaml_encode_enc_hook() -> None: assert_type(msgspec.yaml.encode(object(), enc_hook=lambda x: None), bytes) def check_yaml_encode_order() -> None: assert_type(msgspec.yaml.encode(object(), order=None), bytes) assert_type(msgspec.yaml.encode(object(), order="deterministic"), bytes) assert_type(msgspec.yaml.encode(object(), order="sorted"), bytes) def check_yaml_decode_dec_hook() -> None: def dec_hook(typ: type, obj: Any) -> Any: return typ(obj) assert_type(msgspec.yaml.decode(b"test", dec_hook=dec_hook), Any) def check_yaml_decode_strict() -> None: out = msgspec.yaml.decode(b'', type=list[int], strict=False) assert_type(out, list[int]) ########################################################## # TOML # ########################################################## def check_toml_encode() -> None: b = msgspec.toml.encode({"a": 1}) assert_type(b, bytes) def check_toml_decode_any() -> None: o = msgspec.toml.decode(b"a = 1") assert_type(o, Any) def check_toml_decode_typed() -> None: o = msgspec.toml.decode(b"a = 1", type=dict[str, int]) assert_type(o, dict[str, int]) def check_toml_decode_from_str() -> None: msgspec.toml.decode("a = 1") o = msgspec.toml.decode("a = 1", type=dict[str, int]) assert_type(o, dict[str, int]) def check_toml_decode_from_buffer() -> None: assert_type(msgspec.toml.decode(bytearray()), Any) assert_type(msgspec.toml.decode(memoryview(b"a = 1")), Any) # Non buffers: msgspec.toml.decode({}) # type: ignore[call-overload] # pyright: ignore[reportArgumentType] # pyrefly: ignore[bad-argument-type] def check_toml_encode_enc_hook() -> None: assert_type(msgspec.toml.encode(object(), enc_hook=lambda x: None), bytes) def check_toml_encode_order() -> None: assert_type(msgspec.toml.encode(object(), order=None), bytes) assert_type(msgspec.toml.encode(object(), order="deterministic"), bytes) assert_type(msgspec.toml.encode(object(), order="sorted"), bytes) def check_toml_decode_dec_hook() -> None: def dec_hook(typ: type, obj: Any) -> Any: return typ(obj) assert_type(msgspec.toml.decode(b"a = 1", dec_hook=dec_hook), Any) def check_toml_decode_strict() -> None: out = msgspec.toml.decode(b'', type=list[int], strict=False) assert_type(out, list[int]) ########################################################## # msgspec.inspect # ########################################################## def check_inspect_type_info() -> None: assert_type(msgspec.inspect.type_info(list[int]), msgspec.inspect.Type) assert_type(msgspec.inspect.type_info(int), msgspec.inspect.Type) assert_type(msgspec.inspect.type_info(list), msgspec.inspect.Type) assert_type(msgspec.inspect.type_info(None), msgspec.inspect.Type) def check_inspect_multi_type_info() -> None: o = msgspec.inspect.multi_type_info([int, float]) assert_type(o, tuple[msgspec.inspect.Type, ...]) o2 = msgspec.inspect.multi_type_info((int, float)) assert_type(o2, tuple[msgspec.inspect.Type, ...]) def max_depth(t: msgspec.inspect.Type, depth: int = 0) -> int: # This isn't actually a complete max_depth implementation if isinstance(t, msgspec.inspect.CollectionType): assert_type(t.item_type, msgspec.inspect.Type) return max_depth(t.item_type, depth + 1) elif isinstance(t, msgspec.inspect.DictType): assert_type(t.key_type, msgspec.inspect.Type) return max( max_depth(t.key_type, depth + 1), max_depth(t.value_type, depth + 1) ) elif isinstance(t, msgspec.inspect.TupleType): assert_type(t.item_types, tuple[msgspec.inspect.Type, ...]) return max(max_depth(a, depth + 1) for a in t.item_types) else: return depth def check_consume_inspect_types() -> None: t = msgspec.inspect.type_info(list[int]) o = max_depth(t) assert_type(o, int) t = msgspec.inspect.UnionType( (msgspec.inspect.IntType(), msgspec.inspect.NoneType()) ) assert_type(t.includes_none, bool) def check_inspect_is_struct() -> None: class Point(msgspec.Struct): x: int obj: Point | str = Point(1) if msgspec.inspect.is_struct(obj): assert_type(obj, Point) else: assert_type(obj, str) ns: object = object() if msgspec.inspect.is_struct(ns): assert_type(ns, msgspec.Struct) else: assert_type(ns, object) def check_inspect_is_struct_type() -> None: class Point(msgspec.Struct): x: int @final class Other: ... tp: type[Point] | type[Other] = Point if msgspec.inspect.is_struct_type(tp): assert_type(tp, type[Point]) else: assert_type(tp, type[Other]) other: type[Any] = type("NotStruct", (), {}) if msgspec.inspect.is_struct_type(other): assert_type(other, type[msgspec.Struct]) else: _other_type: type[Any] = other ########################################################## # JSON Schema # ########################################################## def check_json_schema() -> None: o1 = msgspec.json.schema(list[int]) assert_type(o1, dict[str, Any]) o2 = msgspec.json.schema(list[int], schema_hook=lambda t: {"type": "object"}) assert_type(o2, dict[str, Any]) def check_json_schema_components() -> None: s1, c1 = msgspec.json.schema_components([list[int]]) assert_type(s1, tuple[dict[str, Any], ...]) assert_type(c1, dict[str, Any]) s2, c2 = msgspec.json.schema_components([list[int]], ref_template="#/definitions/{name}") assert_type(s2, tuple[dict[str, Any], ...]) assert_type(c2, dict[str, Any]) s3, c3 = msgspec.json.schema_components( [list[int]], schema_hook=lambda t: {"type": "object"} ) assert_type(s3, tuple[dict[str, Any], ...]) assert_type(c3, dict[str, Any]) ########################################################## # Converters # ########################################################## def check_to_builtins() -> None: msgspec.to_builtins(1) msgspec.to_builtins({1: 2}, str_keys=False) msgspec.to_builtins(b"test", builtin_types=(bytes, bytearray, memoryview)) msgspec.to_builtins([1, 2, 3], enc_hook=lambda x: None) msgspec.to_builtins([1, 2, 3], order=None) msgspec.to_builtins([1, 2, 3], order="deterministic") msgspec.to_builtins([1, 2, 3], order="sorted") def check_convert() -> None: o1 = msgspec.convert(1, int) assert_type(o1, int) o2 = msgspec.convert([1, 2], list[float]) assert_type(o2, list[float]) o3 = msgspec.convert(1, int, strict=False) assert_type(o3, int) o4 = msgspec.convert(1, int, from_attributes=True) assert_type(o4, int) o5 = msgspec.convert(1, int, dec_hook=lambda typ, x: None) assert_type(o5, int) o6 = msgspec.convert(1, int, builtin_types=(bytes, bytearray, memoryview)) assert_type(o6, int) o7 = msgspec.convert("1", int, str_keys=True) assert_type(o7, int) python-msgspec-0.22.0/tests/typing/stubtest_allowlist.txt000066400000000000000000000021551525673062400237540ustar00rootroot00000000000000# Allowlist for `python -m mypy.stubtest msgspec`, run via scripts/stubtest.py. # # Each entry is a regex matched against the fully-qualified name of a stubtest # finding. Entries here are known false positives or intentional gaps; real # stub/runtime drift should be fixed rather than added here. # # This file holds entries that apply to every supported Python version. Entries # that only surface from a given version onwards belong in # stubtest_allowlist_py_plus.txt instead. stubtest runs without # --ignore-unused-allowlist, so an entry that stops matching fails the run. # msgspec.Struct subclasses get a per-class __init__ synthesized in C. stubtest # can't see through it, so every Struct subtype reports an __init__ mismatch # against the generic stub. Same story for the C types with a custom __new__. msgspec\.Struct\.__init__ msgspec\.Meta\.__init__ msgspec\.Meta\.__new__ msgspec\.structs\.FieldInfo\.__init__ msgspec\.inspect\..*\.__init__ msgspec\.msgpack\.Ext\.__init__ msgspec\.msgpack\.Ext\.__new__ msgspec\.UnsetType\.__new__ # Private, intentionally unstubbed helper module. msgspec\._utils\..* python-msgspec-0.22.0/tests/typing/stubtest_allowlist_py313_plus.txt000066400000000000000000000007001525673062400257500ustar00rootroot00000000000000# Allowlist entries that only surface on Python 3.13 and later. # See scripts/stubtest.py for how this file is selected. # Struct.__init_subclass__ is stubbed with the config kwargs (via # dataclass_transform) so type checkers accept `class Foo(Struct, frozen=True)`. # At runtime those kwargs are handled by the metaclass, so __init_subclass__ # itself takes none. stubtest only reports this from 3.13 onwards. msgspec\.Struct\.__init_subclass__ python-msgspec-0.22.0/tests/unit/000077500000000000000000000000001525673062400167065ustar00rootroot00000000000000python-msgspec-0.22.0/tests/unit/__init__.py000066400000000000000000000000001525673062400210050ustar00rootroot00000000000000python-msgspec-0.22.0/tests/unit/conftest.py000066400000000000000000000024341525673062400211100ustar00rootroot00000000000000import math import random import string import struct import pytest class Rand: """Random source, pulled out into fixture with repr so the seed is displayed on failing tests""" def __init__(self, seed=0): self.seed = seed or random.randint(0, 2**32 - 1) self.rand = random.Random(self.seed) def __repr__(self): return f"Rand({self.seed})" def str(self, n, m=0): """ str(n) -> random string of length `n`. str(n, m) -> random string between lengths `n` & `m` """ if m: n = self.rand.randint(n, m) return "".join(self.rand.choices(string.ascii_letters, k=n)) def bytes(self, n): """random bytes of length `n`""" return self.rand.getrandbits(8 * n).to_bytes(n, "little") def float(self): """random finite float""" while True: dbytes = self.rand.getrandbits(64).to_bytes(8, "big") x = struct.unpack("!d", dbytes)[0] if math.isfinite(x): return x def shuffle(self, obj): """random shuffle""" self.rand.shuffle(obj) @pytest.fixture def rand(): yield Rand() @pytest.fixture(scope="session") def package_dir(pytestconfig): return pytestconfig.rootpath.joinpath("src", "msgspec") python-msgspec-0.22.0/tests/unit/test_JSONTestSuite.py000066400000000000000000012705431525673062400227560ustar00rootroot00000000000000"""These test cases are from https://github.com/nst/JSONTestSuite. They don't check the correctness of the parsing, only whether a JSON message is accepted/rejected appropriately.""" import itertools import pytest import msgspec from .utils import emscripten_stack_limited def _max_container_depth(case): depth = max_depth = 0 for char in case: if char in (ord("["), ord("{")): depth += 1 max_depth = max(depth, max_depth) elif char in (ord("]"), ord("}")): depth -= 1 return max_depth def _case_param(case): # JSONTestSuite includes 100,000-deep invalid inputs; Pyodide hits # the JS/Wasm stack before msgspec can raise RecursionError. if _max_container_depth(case) > 1000: return pytest.param(case, marks=emscripten_stack_limited) return case valid_cases = [ b"[1e-2]", b'["\\uD834\\uDd1e"]', b'["\xe2\x80\xa8"]', b'["\\u0061\\u30af\\u30EA\\u30b9"]', b'["\\""]', b"[1,null,null,null,2]", b'["\xe2\x82\xac\xf0\x9d\x84\x9e"]', b"[null]", b"[1E-2]", b'{"a":"b","a":"c"}', b"[1E+2]", b'{"a":[]}', b"[ 4]", b" [1]", b"[-1]", b'["\xe2\x80\xa9"]', b'{"foo\\u0000bar": 42}', b" [] ", b'["\\u2064"]', b'["\xcf\x80"]', b'["new\\u000Aline"]', b'["\\u002c"]', b'["\\uD83F\\uDFFE"]', b'["\\u0123"]', b"[1\n]", b"[20e1]", b'["\\u0022"]', b"[true]", b'["\\u0821"]', b'["\\uD801\\udc37"]', b'["\x7f"]', b"[123e65]", b'{"":0}', b'""', b'["\\uDBFF\\uDFFF"]', b"[-0]", b'["\\\\a"]', b"true", b"[123.456789]", b'["\\uFFFE"]', b'{"asd":"sdf"}', b"[]", b'["a"]', b"[-123]", b'["\\\\n"]', b"[1E22]", b'["\\u0012"]', b'["asd "]', b'["\\ud83d\\ude39\\ud83d\\udc8d"]', b'["\\u0060\\u012a\\u12AB"]', b'["\\"\\\\\\/\\b\\f\\n\\r\\t"]', b'["\\uA66D"]', b'"asd"', b"[0e+1]", b'{\n"a": "b"\n}', b'["\\\\u0000"]', b"[false]", b'[ "asd"]', b'["\\u200B"]', b'["new\\u00A0line"]', b"{}", b'["\xf0\x9b\xbf\xbf"]', b'["\xe2\x8d\x82\xe3\x88\xb4\xe2\x8d\x82"]', b"[1e+2]", b'{"x":[{"id": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"}], "id": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"}', b'["\\u005C"]', b"-0.1", b'["a\x7fa"]', b"[123.456e78]", b'["\xef\xbf\xbf"]', b'["asd"]', b'[null, 1, "1", {}]', b'["a"]\n', b"[123e45]", b"[123]", b'["\\uFFFF"]', b'["\xf4\x8f\xbf\xbf"]', b'[""]', b"42", b'["\\uFDD0"]', b'" "', b'["\\uDBFF\\uDFFE"]', b'{"asd":"sdf", "dfg":"fgh"}', b"null", b"[-0]", b'{ "min": -1.0e+28, "max": 1.0e+28 }', b'["a/*b*/c/*d//e"]', b'["\\u0000"]', b'{"a":"b","a":"b"}', b'{"title":"\\u041f\\u043e\\u043b\\u0442\\u043e\\u0440\\u0430 \\u0417\\u0435\\u043c\\u043b\\u0435\\u043a\\u043e\\u043f\\u0430" }', b"[-0.000000000000000000000000000000000000000000000000000000000000000000000000000001]\n", b"[0e1]", b"[[] ]", b"false", b"[2] ", ] invalid_cases = [ b"['single quote']", b'{"":', b'["\\\\\\"]', b"[1e\xe5]", b"[Infinity]", b"[1,]", b"[0.1.2]", b"{,", b"[++1234]", b"[-]", b"[1", b"[-01]", b'["\\uqqqq"]', b"[9.e+]", b"[-foo]", b'["a",\n4\n,1,', b'[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":\n', b'["\\uD800\\u1"]', b'{"x", null}', b"<.>", b"[+1]", b"[1.2a-3]", b"[-123.123foo]", b"[0x42]", b'[\\u0020"asd"]', b"{'a':0}", b"{]", b'{"a" "b"}', b'{[: "x"}\n', b"[tru]", b"[ false, tru", b'{"a":"b"}/**//', b"[nul]", b'{"a"', b"]", b"[\xe2\x81\xa0]", b"[\xff]", b"[1ea]", b'{"a":"b"}/**/', b"[0\xe5]\n", b"[1.0e]", b'["",]', b'["\\\t"]', b"{'a'", b'["\\\x00"]', b'{"a":"a', b'{"a":"a" 123}', b" ", b"{null:null,null:null}", b"[1.0e+]", b"[\xe2\x81\xa0]", b'["a', b"\xe5", b'["a\x00a"]', b'[""', b'{"a": true} "x"', b"", b"\xe9", b"[.2e-3]", b'["\\uD800\\uD800\\x"]', b'["\\x00"]', b"[012]", b"[0.e1]", b"[1.0e-]", b'["\\a"]', b"[1,\n1\n,1", b"[{}", b"[0x1]", b'{"a":"b"}//', b"[", b"[1 000.0]", b"[-1x]", b"1]", b'{"a" b}', b'["\\uD800\\u"]', b'{"a":"b"}#{}', b'{"x": true,', b"[0E+]", b"{}}", b"2@", b'"', b'{"a":"b"}#', b"[-2.]", b"[- 1]", b'"\\UA66D"', b'{"a":"b"}/', b"[1+2]", b"[a\xe5]", b'["\\uD834\\uDd"]', b"[.-1]", b'["\\uD800\\u1x"]', b'["new\nline"]', b"\xc3\xa5", b"[,1]", b"[\x00]", b"['", b"[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[", b"[1,", b'["": 1]', b'["\\{["\\{["\\{["\\{', b"\xef\xbb{}", b'["\x0ba"\\f]', b"[.123]", b'["\\"]', b"[x", b"[2.e+3]", b"[+Inf]", b"[1,,]", b"[0E]", b"[ true, fals", b"{key: 'value'}", b'{"a', b"\xef\xbb\xbf", b"a\xc3\xa5", b"[1:2]", b"[-1.0.]", b'{"a":/*comment*/"b"}', b"[-Infinity]", b"[1eE2]", b"[ false, nul", b"[\\n]", b"[,", b"{[", b"[-NaN]", b"[NaN]", b'["a"', b"{", b'["x"', b'{"x"::"b"}', b"[][]", b'["\\\xe5"]', b'["x"]]', b'[ , ""]', b"[2.e3]", b"[0e+-1]", b"[,]", b'{"\xb9":"0",}', b'["\\u\xe5"]', b"[0e+]", b"[{", b"[1.8011670033376514H-308]", b'{"id":0,,,,,}', b'{ "foo" : "bar", "a" }', b"[0e]", b"[1]]", b'{"asd":"asd"', b'["\t"]', b"[fals]", b"[1 true]", b"{9999E9999:1}", b'["\\', b"[Inf]", b'["\\\xf0\x9f\x8c\x80"]', b"[1,,2]", b"[123\xe5]", b"[True]", b'{:"b"}', b"[-012]", b"[0.3e+]", b"abc", b'[""],', b'["asd]', b"[*]", b'{a: "b"}', b'[\\u000A""]', b'["\\u00A"]', b"*", b'["x", truth]', b"[\xef\xbc\x91]", b"[]", b"{1:1}", b"[0.3e]", b'{"id":0,}', b"[1]x", b"{\xf0\x9f\x87\xa8\xf0\x9f\x87\xad}", b"[1e1\xe5]", b"[2.e-3]", b"[\x0c]", b'["\\uD800\\"]', b'{"a":"b",,"c":"d"}', b"[1.]", b'""x', b"[-.123]", b"[\xc3\xa9]", b"123\x00", b"[3[4]]", b'["x",,]', b'{"a":', ] invalid_cases = [_case_param(case) for case in invalid_cases] @pytest.mark.parametrize("case", valid_cases, ids=itertools.count()) def test_valid(case): msgspec.json.decode(case) @pytest.mark.parametrize("case", invalid_cases, ids=itertools.count()) def test_invalid(case): expected_errors = (msgspec.DecodeError, UnicodeDecodeError, RecursionError) with pytest.raises(expected_errors): msgspec.json.decode(case) python-msgspec-0.22.0/tests/unit/test_common.py000066400000000000000000005451751525673062400216300ustar00rootroot00000000000000from __future__ import annotations import base64 import collections import datetime import decimal import enum import gc import inspect import sys import textwrap import types import typing import uuid import weakref from collections import namedtuple from dataclasses import dataclass, field, make_dataclass from datetime import timedelta from typing import ( Annotated, Any, Callable, ClassVar, Deque, Final, Generic, Literal, NamedTuple, NewType, TypedDict, TypeVar, Union, ) import pytest from .utils import ( emscripten_stack_limited, max_call_depth, py315_or_later_only, temp_module, win_arm64_py312_stack_limited, ) try: import attrs except ImportError: attrs = None import msgspec from msgspec import UNSET, Meta, Struct, UnsetType, ValidationError if sys.version_info >= (3, 15): # This is needed for `ruff` to recognize `frozendict` name # and to not raise `F821`: from builtins import frozendict UTC = datetime.timezone.utc PY311 = sys.version_info[:2] >= (3, 11) PY312 = sys.version_info[:2] >= (3, 12) py311_plus = pytest.mark.skipif(not PY311, reason="3.11+ only") py312_plus = pytest.mark.skipif(not PY312, reason="3.12+ only") T = TypeVar("T") def make_new_alias(alias): """Replicate the logic to produce a typing._GenericAlias from a types.GenericAlias""" return typing._GenericAlias(alias.__origin__, alias.__origin__.__parameters__)[ alias.__args__ ] def assert_eq(x, y): assert x == y assert type(x) is type(y) @pytest.fixture(params=["json", "msgpack"]) def proto(request): if request.param == "json": return msgspec.json elif request.param == "msgpack": return msgspec.msgpack try: from enum import StrEnum except ImportError: class StrEnum(str, enum.Enum): pass class FruitInt(enum.IntEnum): APPLE = 1 BANANA = 2 class FruitStr(enum.Enum): APPLE = "apple" BANANA = "banana" class VeggieInt(enum.IntEnum): CARROT = 1 LETTUCE = 2 class VeggieStr(enum.Enum): CARROT = "carrot" LETTUCE = "banana" class Person(Struct): first: str last: str age: int class PersonArray(Struct, array_like=True): first: str last: str age: int class PersonDict(TypedDict): first: str last: str age: int @dataclass class PersonDataclass: first: str last: str age: int class PersonTuple(NamedTuple): first: str last: str age: int class Custom: def __init__(self, x, y): self.x = x self.y = y def __eq__(self, other): return self.x == other.x and self.y == other.y class TestEncodeSubclasses: def test_encode_dict_subclass(self, proto): class subclass(dict): pass for msg in [{}, {"a": 1, "b": 2}]: assert proto.encode(subclass(msg)) == proto.encode(msg) @pytest.mark.parametrize("cls", [list, tuple, set, frozenset]) def test_encode_sequence_subclass(self, cls, proto): class subclass(cls): pass for msg in [[], [1, 2]]: assert proto.encode(subclass(msg)) == proto.encode(cls(msg)) class TestDecoder: def test_decoder_runtime_type_parameters(self, proto): dec = proto.Decoder[int](int) assert isinstance(dec, proto.Decoder) msg = proto.encode(2) assert dec.decode(msg) == 2 def test_decoder_dec_hook_attribute(self, proto): def dec_hook(typ, obj): pass dec = proto.Decoder() assert dec.dec_hook is None dec = proto.Decoder(dec_hook=None) assert dec.dec_hook is None dec = proto.Decoder(dec_hook=dec_hook) assert dec.dec_hook is dec_hook def test_decoder_dec_hook_not_callable(self, proto): with pytest.raises(TypeError): proto.Decoder(dec_hook=1) def test_decode_dec_hook(self, proto): def dec_hook(typ, obj): assert typ is Custom return typ(*obj) msg = proto.encode([1, 2]) res = proto.decode(msg, type=Custom, dec_hook=dec_hook) assert res == Custom(1, 2) assert isinstance(res, Custom) def test_decoder_dec_hook(self, proto): called = False def dec_hook(typ, obj): nonlocal called called = True assert typ is Custom return Custom(*obj) dec = proto.Decoder(type=list[Custom], dec_hook=dec_hook) buf = proto.encode([[1, 2], [3, 4], [5, 6]]) msg = dec.decode(buf) assert called assert msg == [Custom(1, 2), Custom(3, 4), Custom(5, 6)] assert isinstance(msg[0], Custom) def test_decoder_dec_hook_optional_custom_type(self, proto): called = False def dec_hook(typ, obj): nonlocal called called = True dec = proto.Decoder(type=Custom | None, dec_hook=dec_hook) msg = dec.decode(proto.encode(None)) assert not called assert msg is None @pytest.mark.parametrize("err_cls", [TypeError, ValueError]) def test_decode_dec_hook_errors_wrapped(self, err_cls, proto): def dec_hook(typ, obj): assert obj == "some string" raise err_cls("Oh no!") msg = proto.encode("some string") with pytest.raises(msgspec.ValidationError, match="Oh no!") as rec: proto.decode(msg, type=Custom, dec_hook=dec_hook) assert rec.value.__cause__ is rec.value.__context__ assert type(rec.value.__cause__) is err_cls msg = proto.encode(["some string"]) with pytest.raises(msgspec.ValidationError, match=r"Oh no! - at `\$\[0\]`"): proto.decode(msg, type=list[Custom], dec_hook=dec_hook) def test_decode_dec_hook_errors_passthrough(self, proto): def dec_hook(typ, obj): assert obj == "some string" raise NotImplementedError("Oh no!") msg = proto.encode("some string") with pytest.raises(NotImplementedError, match="Oh no!"): proto.decode(msg, type=Custom, dec_hook=dec_hook) msg = proto.encode(["some string"]) with pytest.raises(NotImplementedError, match=r"Oh no!"): proto.decode(msg, type=list[Custom], dec_hook=dec_hook) def test_decode_dec_hook_wrong_type(self, proto): dec = proto.Decoder(type=Custom, dec_hook=lambda t, o: o) msg = proto.encode([1, 2]) with pytest.raises( msgspec.ValidationError, match="Expected `Custom`, got `list`", ): dec.decode(msg) def test_decode_dec_hook_wrong_type_in_struct(self, proto): class Test(Struct): point: Custom other: int dec = proto.Decoder(type=Test, dec_hook=lambda t, o: o) msg = proto.encode({"point": [1, 2], "other": 3}) with pytest.raises(msgspec.ValidationError) as rec: dec.decode(msg) assert "Expected `Custom`, got `list` - at `$.point`" == str(rec.value) def test_decode_dec_hook_wrong_type_generic(self, proto): dec = proto.Decoder(type=Deque[int], dec_hook=lambda t, o: o) msg = proto.encode([1, 2, 3]) with pytest.raises(msgspec.ValidationError) as rec: dec.decode(msg) assert "Expected `collections.deque`, got `list`" == str(rec.value) def test_decode_dec_hook_isinstance_errors(self, proto): class Metaclass(type): def __instancecheck__(self, obj): raise TypeError("Oh no!") class Custom(metaclass=Metaclass): pass dec = proto.Decoder(type=Custom) msg = proto.encode(1) with pytest.raises(TypeError, match="Oh no!"): dec.decode(msg) @pytest.mark.parametrize( "base_error_cls", [msgspec.ValidationError, msgspec.DecodeError] ) def test_dec_hook_validation_error_subclass_propagates_directly( self, proto, base_error_cls ): class MyError(base_error_cls): pass class Foo: pass def dec_hook(tp, val): raise MyError("custom message") dec = proto.Decoder(type=Foo, dec_hook=dec_hook) with pytest.raises(MyError, match="custom message"): dec.decode(b"[]") @pytest.mark.skipif( PY312, reason=( "Python 3.12 harcodes the C recursion limit, making this " "behavior harder to test in CI" ), ) class TestRecursion: @staticmethod def nested(n, is_array): if is_array: obj = [] for _ in range(n): obj = [obj] else: obj = {} for _ in range(n): obj = {"": obj} return obj @pytest.mark.parametrize("is_array", [True, False]) def test_encode_highly_recursive_msg_errors(self, is_array, proto): N = 200 obj = self.nested(N, is_array) # Errors if above the recursion limit with max_call_depth(N // 2): with pytest.raises(RecursionError): proto.encode(obj) # Works if below the recursion limit with max_call_depth(N * 2): proto.encode(obj) @pytest.mark.parametrize("is_array", [True, False]) def test_decode_highly_recursive_msg_errors(self, is_array, proto): """Ensure recursion is properly handled when decoding. Test case seen in https://github.com/ijl/orjson/issues/458.""" N = 200 obj = self.nested(N, is_array) with max_call_depth(N * 2): msg = proto.encode(obj) # Errors if above the recursion limit with max_call_depth(N // 2): with pytest.raises(RecursionError): proto.decode(msg) # Works if below the recursion limit with max_call_depth(N * 2): obj2 = proto.decode(msg) assert obj2 class TestThreadSafe: def test_encode_threadsafe(self, proto): class Nested: def __init__(self, x): self.x = x def enc_hook(obj): return base64.b64encode(enc.encode(obj.x)).decode("utf-8") enc = proto.Encoder(enc_hook=enc_hook) res = enc.encode({"x": Nested(1)}) sol = proto.encode({"x": base64.b64encode(proto.encode(1)).decode("utf-8")}) assert res == sol def test_decode_threadsafe(self, proto): class Custom: def __init__(self, node): self.node = node def __eq__(self, other): return type(other) is Custom and self.node == other.node def dec_hook(typ, obj): msg = base64.b64decode(obj) return Custom(dec.decode(msg)) dec = proto.Decoder(tuple[Custom | None, int], dec_hook=dec_hook) msg = proto.encode( (base64.b64encode(proto.encode((None, 1))).decode("utf-8"), 2) ) sol = (Custom((None, 1)), 2) res = dec.decode(msg) assert res == sol class TestIntEnum: def test_empty_errors(self, proto): class Empty(enum.IntEnum): pass with pytest.raises(TypeError, match="Enum types must have at least one item"): proto.Decoder(Empty) @pytest.mark.parametrize("base_cls", [enum.IntEnum, enum.Enum]) def test_encode(self, proto, base_cls): class Test(base_cls): A = 1 B = 2 assert proto.encode(Test.A) == proto.encode(1) @pytest.mark.parametrize("base_cls", [enum.IntEnum, enum.Enum]) def test_decode(self, proto, base_cls): class Test(base_cls): A = 1 B = 2 dec = proto.Decoder(Test) assert dec.decode(proto.encode(1)) is Test.A assert dec.decode(proto.encode(2)) is Test.B with pytest.raises(ValidationError, match="Invalid enum value 3"): dec.decode(proto.encode(3)) def test_decode_nested(self, proto): class Test(Struct): fruit: FruitInt dec = proto.Decoder(Test) dec.decode(proto.encode({"fruit": 1})) == Test(FruitInt.APPLE) with pytest.raises( ValidationError, match=r"Invalid enum value 3 - at `\$.fruit`" ): dec.decode(proto.encode({"fruit": 3})) def test_intenum_missing(self, proto): class Ex(enum.IntEnum): A = 1 B = 2 @classmethod def _missing_(cls, val): if val == 3: return cls.A elif val == -4: return cls.B elif val == 5: raise ValueError("oh no!") else: return None dec = proto.Decoder(Ex) def roundtrip(msg): return dec.decode(proto.encode(msg)) assert roundtrip(1) is Ex.A assert roundtrip(3) is Ex.A assert roundtrip(-4) is Ex.B with pytest.raises(ValidationError, match="Invalid enum value 5"): roundtrip(5) with pytest.raises(ValidationError, match="Invalid enum value 6"): roundtrip(6) def test_intflag(self, proto): class Ex(enum.IntFlag): A = 0b001 B = 0b010 C = 0b100 obj = Ex.A | Ex.C msg = proto.encode(obj) assert msg == proto.encode(int(obj)) assert proto.decode(msg, type=Ex) == obj def test_int_lookup_reused(self): class Test(enum.IntEnum): A = 1 B = 2 dec = msgspec.msgpack.Decoder(Test) # noqa count = sys.getrefcount(Test.__msgspec_cache__) dec2 = msgspec.msgpack.Decoder(Test) count2 = sys.getrefcount(Test.__msgspec_cache__) assert count2 == count + 1 # Reference count decreases when decoder is dropped del dec2 gc.collect() count3 = sys.getrefcount(Test.__msgspec_cache__) assert count == count3 def test_int_lookup_gc(self): class Test(enum.IntEnum): A = 1 B = 2 dec = msgspec.msgpack.Decoder(Test) assert gc.is_tracked(Test.__msgspec_cache__) # Deleting all references and running GC cleans up cycle ref = weakref.ref(Test) del Test del dec gc.collect() assert ref() is None @pytest.mark.parametrize( "values", [ [0, 1, 2, -(2**63) - 1], [0, 1, 2, 2**63], ], ) def test_int_lookup_values_out_of_range(self, values): myenum = enum.IntEnum("myenum", [(f"x{i}", v) for i, v in enumerate(values)]) with pytest.raises(NotImplementedError): msgspec.msgpack.Decoder(myenum) def test_msgspec_cache_overwritten(self): class Test(enum.IntEnum): A = 1 Test.__msgspec_cache__ = 1 with pytest.raises(RuntimeError, match="__msgspec_cache__"): msgspec.msgpack.Decoder(Test) @pytest.mark.parametrize( "values", [ [0], [1], [-1], [3, 4, 5, 2, 1], [4, 3, 1, 2, 7], [-4, -3, -2, -1, 0, 1, 2, 3, 4], [-4, -3, -1, -2, -7], [-4, -3, 1, 0, -2, -1], [2**63 - 1, 2**63 - 2, 2**63 - 3], [-(2**63) + 1, -(2**63) + 2, -(2**63) + 3], ], ) def test_compact(self, values): myenum = enum.IntEnum("myenum", [(f"x{i}", v) for i, v in enumerate(values)]) dec = msgspec.msgpack.Decoder(myenum) assert hasattr(myenum, "__msgspec_cache__") for val in myenum: msg = msgspec.msgpack.encode(val) val2 = dec.decode(msg) assert val == val2 for bad in [-1000, min(values) - 1, max(values) + 1, 1000]: with pytest.raises(ValidationError): dec.decode(msgspec.msgpack.encode(bad)) @pytest.mark.parametrize( "values", [ [-(2**63), 2**63 - 1, 0], [2**63 - 2, 2**63 - 3, 2**63 - 1], [2**63 - 2, 2**63 - 3, 2**63 - 1, 0, 2, 3, 4, 5, 6], ], ) def test_hashtable(self, values): myenum = enum.IntEnum("myenum", [(f"x{i}", v) for i, v in enumerate(values)]) dec = msgspec.msgpack.Decoder(myenum) assert hasattr(myenum, "__msgspec_cache__") for val in myenum: msg = msgspec.msgpack.encode(val) val2 = dec.decode(msg) assert val == val2 for bad in [-2000, -1, 1, 2000]: with pytest.raises(ValidationError): dec.decode(msgspec.msgpack.encode(bad)) @pytest.mark.parametrize( "values", [ [8, 16, 24, 32, 40, 48], [-8, -16, -24, -32, -40, -48], ], ) def test_hashtable_collisions(self, values): myenum = enum.IntEnum("myenum", [(f"x{i}", v) for i, v in enumerate(values)]) dec = msgspec.msgpack.Decoder(myenum) for val in myenum: msg = msgspec.msgpack.encode(val) val2 = dec.decode(msg) assert val == val2 for bad in [0, 7, 9, 56, -min(values), -max(values), 2**64 - 1, -(2**63)]: with pytest.raises(ValidationError): dec.decode(msgspec.msgpack.encode(bad)) class TestEnum: def test_empty_errors(self, proto): class Empty(enum.Enum): pass with pytest.raises(TypeError, match="Enum types must have at least one item"): proto.Decoder(Empty) def test_encode_complex(self, proto): class Complex(enum.Enum): A = 1.5 res = proto.encode(Complex.A) sol = proto.encode(1.5) assert res == sol res = proto.encode({Complex.A: 1}) sol = proto.encode({1.5: 1}) assert res == sol def test_decode_complex_errors(self, proto): class Complex(enum.Enum): A = 1.5 with pytest.raises(TypeError) as rec: proto.Decoder(Complex) assert "Enums must contain either all str or all int values" in str(rec.value) assert repr(Complex) in str(rec.value) @pytest.mark.parametrize( "values", [ [("A", 1), ("B", 2), ("C", "c")], [("A", "a"), ("B", "b"), ("C", 3)], ], ) def test_mixed_value_types_errors(self, values, proto): Bad = enum.Enum("Bad", values) with pytest.raises(TypeError) as rec: proto.Decoder(Bad) assert "Enums must contain either all str or all int values" in str(rec.value) assert repr(Bad) in str(rec.value) @pytest.mark.parametrize("base_cls", [StrEnum, enum.Enum]) def test_encode(self, proto, base_cls): class Test(base_cls): A = "apple" B = "banana" assert proto.encode(Test.A) == proto.encode("apple") @pytest.mark.parametrize( "base_metacls", [enum.EnumMeta] + ([enum.EnumType] if PY311 else []) ) def test_enum_with_custom_enum_metaclass(self, proto, base_metacls): class ChoicesMeta(base_metacls): """My custom enum metaclass""" class Test(enum.Enum, metaclass=ChoicesMeta): A = "apple" B = "banana" assert proto.encode(Test.A) == proto.encode("apple") assert proto.decode(proto.encode("apple"), type=Test) is Test.A @pytest.mark.parametrize("base_cls", [StrEnum, enum.Enum]) def test_decode(self, proto, base_cls): class Test(base_cls): A = "apple" B = "banana" dec = proto.Decoder(Test) assert dec.decode(proto.encode("apple")) is Test.A assert dec.decode(proto.encode("banana")) is Test.B with pytest.raises(ValidationError, match="Invalid enum value 'cherry'"): dec.decode(proto.encode("cherry")) def test_decode_nested(self, proto): class Test(Struct): fruit: FruitStr dec = proto.Decoder(Test) dec.decode(proto.encode({"fruit": "apple"})) == Test(FruitStr.APPLE) with pytest.raises( ValidationError, match=r"Invalid enum value 'cherry' - at `\$.fruit`", ): dec.decode(proto.encode({"fruit": "cherry"})) def test_str_lookup_reused(self): class Test(enum.Enum): A = "a" B = "b" dec = msgspec.msgpack.Decoder(Test) # noqa count = sys.getrefcount(Test.__msgspec_cache__) dec2 = msgspec.msgpack.Decoder(Test) count2 = sys.getrefcount(Test.__msgspec_cache__) assert count2 == count + 1 # Reference count decreases when decoder is dropped del dec2 gc.collect() count3 = sys.getrefcount(Test.__msgspec_cache__) assert count == count3 def test_str_lookup_gc(self): class Test(enum.Enum): A = "a" B = "b" dec = msgspec.msgpack.Decoder(Test) assert gc.is_tracked(Test.__msgspec_cache__) # Deleting all references and running GC cleans up cycle ref = weakref.ref(Test) del Test del dec gc.collect() assert ref() is None def test_msgspec_cache_overwritten(self): class Test(enum.Enum): A = 1 Test.__msgspec_cache__ = 1 with pytest.raises(RuntimeError, match="__msgspec_cache__"): msgspec.msgpack.Decoder(Test) @pytest.mark.parametrize("length", [2, 8, 16]) @pytest.mark.parametrize("nitems", [1, 3, 6, 12, 24, 48]) def test_random_enum_same_lengths(self, rand, length, nitems): def strgen(length): """Yields unique random fixed-length strings""" seen = set() while True: x = rand.str(length) if x in seen: continue seen.add(x) yield x unique_str = strgen(length).__next__ myenum = enum.Enum( "myenum", [(unique_str(), unique_str()) for _ in range(nitems)] ) dec = msgspec.msgpack.Decoder(myenum) for val in myenum: msg = msgspec.msgpack.encode(val.value) val2 = dec.decode(msg) assert val == val2 for _ in range(10): key = unique_str() with pytest.raises(ValidationError): dec.decode(msgspec.msgpack.encode(key)) # Try bad of different lengths for bad_length in [1, 7, 15, 30]: assert bad_length != length key = rand.str(bad_length) with pytest.raises(ValidationError): dec.decode(msgspec.msgpack.encode(key)) @pytest.mark.parametrize("nitems", [1, 3, 6, 12, 24, 48]) def test_random_enum_different_lengths(self, rand, nitems): def strgen(): """Yields unique random strings""" seen = set() while True: x = rand.str(1, 32) if x in seen: continue seen.add(x) yield x unique_str = strgen().__next__ myenum = enum.Enum( "myenum", [(unique_str(), unique_str()) for _ in range(nitems)] ) dec = msgspec.msgpack.Decoder(myenum) for val in myenum: msg = msgspec.msgpack.encode(val.value) val2 = dec.decode(msg) assert val == val2 for _ in range(10): key = unique_str() with pytest.raises(ValidationError): dec.decode(msgspec.msgpack.encode(key)) def test_enum_missing(self, proto): class Ex(enum.Enum): A = "a" B = "b" @classmethod def _missing_(cls, val): if val == "return-A": return cls.A elif val == "return-B": return cls.B elif val == "error": raise ValueError("oh no!") else: return None dec = proto.Decoder(Ex) def roundtrip(msg): return dec.decode(proto.encode(msg)) assert roundtrip("a") is Ex.A assert roundtrip("return-A") is Ex.A assert roundtrip("return-B") is Ex.B with pytest.raises(ValidationError, match="Invalid enum value 'error'"): roundtrip("error") with pytest.raises(ValidationError, match="Invalid enum value 'other'"): roundtrip("other") class TestLiterals: def test_empty_errors(self): with pytest.raises( TypeError, match="Literal types must have at least one item" ): msgspec.msgpack.Decoder(Literal[()]) def test_native_literal_generic_alias(self): typ = Literal[1, 2] assert type(typ) is typing._LiteralGenericAlias dec = msgspec.json.Decoder(typ) info = typ.__msgspec_cache__ assert info is not None # a second decoder reuses the info cached on the alias itself dec2 = msgspec.json.Decoder(typ) assert typ.__msgspec_cache__ is info assert dec.decode(b"2") == 2 assert dec2.decode(b"1") == 1 with pytest.raises(ValidationError): dec.decode(b"3") def test_types_generic_alias_literal(self): typ = types.GenericAlias(typing.Literal, (1, 2)) assert type(typ) is types.GenericAlias dec = msgspec.json.Decoder(typ) assert dec.decode(b"1") == 1 assert dec.decode(b"2") == 2 with pytest.raises(ValidationError): dec.decode(b"3") # building a second decoder must not error either assert msgspec.json.Decoder(typ).decode(b"2") == 2 @pytest.mark.parametrize( "values", [ [0, 1, 2, 2**63], [0, 1, 2, -(2**63) - 1], ], ) def test_int_literal_values_out_of_range(self, values): literal = Literal[tuple(values)] with pytest.raises(NotImplementedError): msgspec.msgpack.Decoder(literal) @pytest.mark.parametrize( "typ", [ Literal["ok", b"bad"], Literal[1, object()], Literal[1, 2, list[int]], Literal[1, 2, list], ], ) def test_invalid_values(self, typ): with pytest.raises(TypeError, match="not supported"): msgspec.msgpack.Decoder(typ) def test_decode_literal_int_str_and_none_uncached_and_cached(self): values = (45987, "an_unlikely_string", None) literal = Literal[values] assert not hasattr(literal, "__msgspec_cache__") uncached = msgspec.msgpack.Decoder(literal) assert hasattr(literal, "__msgspec_cache__") cached = msgspec.msgpack.Decoder(literal) for val in values: assert uncached.decode(msgspec.msgpack.encode(val)) == val assert cached.decode(msgspec.msgpack.encode(val)) == val def test_cache_refcounts(self): literal = Literal[1, 2, "three", "four"] dec = msgspec.msgpack.Decoder(literal) # noqa cache = literal.__msgspec_cache__ count = sys.getrefcount(cache) dec2 = msgspec.msgpack.Decoder(literal) assert sys.getrefcount(cache) == count del dec2 gc.collect() assert sys.getrefcount(cache) == count @pytest.mark.parametrize("val", [None, (), (1,), (1, 2), (1, 2, 3)]) def test_msgspec_cache_overwritten(self, val): literal = Literal["a", "highly", "improbable", "set", "of", "strings"] literal.__msgspec_cache__ = val with pytest.raises(RuntimeError, match="__msgspec_cache__"): msgspec.msgpack.Decoder(literal) def test_multiple_literals(self): integers = Literal[-1, -2, -3] strings = Literal["apple", "banana"] both = integers | strings dec = msgspec.msgpack.Decoder(both) assert not hasattr(both, "__msgspec_cache__") for val in [-1, -2, -3, "apple", "banana"]: assert dec.decode(msgspec.msgpack.encode(val)) == val with pytest.raises(ValidationError, match="Invalid enum value 4"): dec.decode(msgspec.msgpack.encode(4)) with pytest.raises(ValidationError, match="Invalid enum value 'carrot'"): dec.decode(msgspec.msgpack.encode("carrot")) def test_nested_literals(self): integers = Literal[-1, -2, -3] strings = Literal["apple", "banana"] both = Literal[integers, strings] dec = msgspec.msgpack.Decoder(both) assert hasattr(both, "__msgspec_cache__") for val in [-1, -2, -3, "apple", "banana"]: assert dec.decode(msgspec.msgpack.encode(val)) == val with pytest.raises(ValidationError, match="Invalid enum value 4"): dec.decode(msgspec.msgpack.encode(4)) with pytest.raises(ValidationError, match="Invalid enum value 'carrot'"): dec.decode(msgspec.msgpack.encode("carrot")) @pytest.mark.parametrize( "typ, good, bad", [ (Literal[True], [True], [False]), (Literal[False], [False], [True]), (Literal[True, False], [True, False], []), (Literal[1, False], [1, False], [True]), (Literal[True, "yes", None], [True, "yes", None], [False]), ], ) def test_literal_bool(self, typ, good, bad): dec = msgspec.msgpack.Decoder(typ) for val in good: assert dec.decode(msgspec.msgpack.encode(val)) == val for val in bad: with pytest.raises(ValidationError): dec.decode(msgspec.msgpack.encode(val)) def test_literal_bool_error_message(self): dec = msgspec.msgpack.Decoder(Literal[True]) with pytest.raises(ValidationError, match="Invalid enum value False"): dec.decode(msgspec.msgpack.encode(False)) def test_mix_bool_and_bool_literal(self): dec = msgspec.msgpack.Decoder(Literal[True] | bool) assert dec.decode(msgspec.msgpack.encode(True)) is True assert dec.decode(msgspec.msgpack.encode(False)) is False def test_mix_int_and_int_literal(self): dec = msgspec.msgpack.Decoder(Literal[-1, 1] | int) for x in [-1, 1, 10]: assert dec.decode(msgspec.msgpack.encode(x)) == x def test_mix_str_and_str_literal(self): dec = msgspec.msgpack.Decoder(Literal["a", "b"] | str) for x in ["a", "b", "c"]: assert dec.decode(msgspec.msgpack.encode(x)) == x class TestCallable: @pytest.mark.parametrize( "typ", [ pytest.param(typing.Callable[[int], str], id="typing"), pytest.param(collections.abc.Callable[[int], str], id="collections.abc"), ], ) def test_callable_generic_alias(self, typ): # 'Callable[...]' is a '_CallableGenericAlias'. The 'typing' flavour subclasses # 'typing._GenericAlias' while the 'collections.abc' flavour subclasses # 'types.GenericAlias' - but neither is an *exact* 'types.GenericAlias', so the # conversion leaves both untouched dec = msgspec.json.Decoder(typ) with pytest.raises(ValidationError, match="Expected `Callable`"): dec.decode(b"null") class TestUnionTypeErrors: def test_decoder_unsupported_type(self, proto): with pytest.raises(TypeError): proto.Decoder(1) def test_decoder_validates_struct_definition_unsupported_types(self, proto): """Struct definitions aren't validated until first use""" class Test(Struct): a: 1 with pytest.raises(TypeError): proto.Decoder(Test) @pytest.mark.parametrize("typ", [int | Deque, Deque | int]) def test_err_union_with_custom_type(self, typ, proto): with pytest.raises(TypeError) as rec: proto.Decoder(typ) assert "custom type" in str(rec.value) assert repr(typ) in str(rec.value) @pytest.mark.parametrize( "typ", [ dict | Person, Person | dict, PersonDict | dict, PersonDataclass | dict, Person | PersonDict, ], ) def test_err_union_with_multiple_dict_like_types(self, typ, proto): with pytest.raises(TypeError) as rec: proto.Decoder(typ) assert "more than one dict-like type" in str(rec.value) assert repr(typ) in str(rec.value) @py315_or_later_only def test_err_union_frozendict_dict_like_types(self, proto): for typ in [ frozendict | Person, Person | frozendict, PersonDict | frozendict, Union[PersonDataclass, frozendict], ]: with pytest.raises(TypeError) as rec: proto.Decoder(typ) assert "more than one dict-like type" in str(rec.value) assert repr(typ) in str(rec.value) @py315_or_later_only def test_err_union_frozendict_and_dict(self, proto): for typ in [ frozendict | dict, dict | frozendict, dict[str, int] | frozendict, frozendict[str, int] | dict, frozendict[str, int] | dict[str, bool], ]: with pytest.raises(TypeError) as rec: proto.Decoder(typ) assert "more than one dict type" in str(rec.value) assert repr(typ) in str(rec.value) @pytest.mark.parametrize( "typ", [ PersonArray | list, tuple | PersonArray, PersonArray | PersonTuple, PersonTuple | frozenset, Union[PersonArray, list], ], ) def test_err_union_with_struct_array_like_and_array(self, typ, proto): with pytest.raises(TypeError) as rec: proto.Decoder(typ) assert "more than one array-like type" in str(rec.value) assert repr(typ) in str(rec.value) @pytest.mark.parametrize( "typ", [ FruitInt | int, FruitInt | Literal[1, 2], Union[FruitInt, int], ], ) def test_err_union_with_multiple_int_like_types(self, typ, proto): with pytest.raises(TypeError) as rec: proto.Decoder(typ) assert "int-like" in str(rec.value) assert repr(typ) in str(rec.value) @pytest.mark.parametrize( "typ", [ str, Literal["one", "two"], datetime.datetime, datetime.date, datetime.time, uuid.UUID, ], ) def test_err_union_with_multiple_str_like_types(self, typ, proto): union = FruitStr | typ with pytest.raises(TypeError) as rec: proto.Decoder(union) assert "str-like" in str(rec.value) assert repr(union) in str(rec.value) @pytest.mark.parametrize( "typ,kind", [ (FruitInt | VeggieInt, "int enum"), (FruitStr | VeggieStr, "str enum"), (dict[int, float] | dict, "dict"), (list[int] | list[float], "array-like"), (list[int] | tuple, "array-like"), (set | tuple, "array-like"), (tuple[int, ...] | list, "array-like"), (tuple[int, float, str] | set, "array-like"), (Deque | int | Custom, "custom"), ], ) def test_err_union_conflicts(self, typ, kind, proto): with pytest.raises(TypeError) as rec: proto.Decoder(typ) assert f"more than one {kind}" in str(rec.value) assert repr(typ) in str(rec.value) def test_310_union_types(self, proto): dec = proto.Decoder(int | str | None) for msg in [1, "abc", None]: assert dec.decode(proto.encode(msg)) == msg with pytest.raises(ValidationError): assert dec.decode(proto.encode(1.5)) class TestStructUnion: def test_err_union_struct_mix_array_like(self, proto): class Test1(Struct, tag=True, array_like=True): x: int class Test2(Struct, tag=True, array_like=False): x: int typ = Test1 | Test2 with pytest.raises(TypeError) as rec: proto.Decoder(typ) assert "not supported" in str(rec.value) assert "array_like" in str(rec.value) assert repr(typ) in str(rec.value) @pytest.mark.parametrize("array_like", [False, True]) @pytest.mark.parametrize("tag1", [False, True]) def test_err_union_struct_not_tagged(self, array_like, tag1, proto): class Test1(Struct, tag=tag1, array_like=array_like): x: int class Test2(Struct, array_like=array_like): x: int typ = Test1 | Test2 with pytest.raises(TypeError) as rec: proto.Decoder(typ) assert "not supported" in str(rec.value) assert "must be tagged" in str(rec.value) assert repr(typ) in str(rec.value) @pytest.mark.parametrize("array_like", [False, True]) def test_err_union_conflict_with_basic_type(self, array_like, proto): class Test1(Struct, tag=True, array_like=array_like): x: int class Test2(Struct, tag=True, array_like=array_like): x: int other = list if array_like else dict typ = Test1 | Test2 | other with pytest.raises(TypeError) as rec: proto.Decoder(typ) assert "not supported" in str(rec.value) if array_like: assert "more than one array-like type" in str(rec.value) else: assert "more than one dict-like type" in str(rec.value) assert repr(typ) in str(rec.value) @pytest.mark.parametrize("array_like", [False, True]) def test_err_union_struct_different_fields(self, proto, array_like): class Test1(Struct, tag_field="foo", array_like=array_like): x: int class Test2(Struct, tag_field="bar", array_like=array_like): x: int typ = Test1 | Test2 with pytest.raises(TypeError) as rec: proto.Decoder(typ) assert "not supported" in str(rec.value) assert "the same `tag_field`" in str(rec.value) assert repr(typ) in str(rec.value) @pytest.mark.parametrize("array_like", [False, True]) def test_err_union_struct_mix_int_str_tags(self, proto, array_like): class Test1(Struct, tag=1, array_like=array_like): x: int class Test2(Struct, tag="two", array_like=array_like): x: int typ = Test1 | Test2 with pytest.raises(TypeError) as rec: proto.Decoder(typ) assert "not supported" in str(rec.value) assert "both `int` and `str` tags" in str(rec.value) assert repr(typ) in str(rec.value) @pytest.mark.parametrize("array_like", [False, True]) @pytest.mark.parametrize( "tags", [ ("a", "b", "b"), ("a", "a", "b"), ("a", "b", "a"), (1, 2, 2), (1, 1, 2), (1, 2, 1), ], ) def test_err_union_struct_non_unique_tag_values(self, proto, array_like, tags): class Test1(Struct, tag=tags[0], array_like=array_like): x: int class Test2(Struct, tag=tags[1], array_like=array_like): x: int class Test3(Struct, tag=tags[2], array_like=array_like): x: int typ = Test1 | Test2 | Test3 with pytest.raises(TypeError) as rec: proto.Decoder(typ) assert "not supported" in str(rec.value) assert "unique `tag`" in str(rec.value) assert repr(typ) in str(rec.value) @pytest.mark.parametrize( "tag1, tag2, unknown", [ ("Test1", "Test2", "Test3"), (0, 1, 2), (123, -123, 0), ], ) def test_decode_struct_union(self, proto, tag1, tag2, unknown): class Test1(Struct, tag=tag1): a: int b: int c: int = 0 class Test2(Struct, tag=tag2): x: int y: int dec = proto.Decoder(Test1 | Test2) enc = proto.Encoder() # Tag can be in any position assert dec.decode(enc.encode({"type": tag1, "a": 1, "b": 2})) == Test1(1, 2) assert dec.decode(enc.encode({"a": 1, "type": tag1, "b": 2})) == Test1(1, 2) assert dec.decode(enc.encode({"x": 1, "y": 2, "type": tag2})) == Test2(1, 2) # Optional fields still work assert dec.decode(enc.encode({"type": tag1, "a": 1, "b": 2, "c": 3})) == Test1( 1, 2, 3 ) assert dec.decode(enc.encode({"a": 1, "b": 2, "c": 3, "type": tag1})) == Test1( 1, 2, 3 ) # Extra fields still ignored assert dec.decode(enc.encode({"a": 1, "b": 2, "d": 4, "type": tag1})) == Test1( 1, 2 ) # Tag missing with pytest.raises(ValidationError) as rec: dec.decode(enc.encode({"a": 1, "b": 2})) assert "missing required field `type`" in str(rec.value) # Tag wrong type with pytest.raises(ValidationError) as rec: dec.decode(enc.encode({"type": 123.456, "a": 1, "b": 2})) assert f"Expected `{type(tag1).__name__}`" in str(rec.value) assert "`$.type`" in str(rec.value) # Tag unknown with pytest.raises(ValidationError) as rec: dec.decode(enc.encode({"type": unknown, "a": 1, "b": 2})) assert f"Invalid value {unknown!r} - at `$.type`" == str(rec.value) @pytest.mark.parametrize( "tag1, tag2, tag3, unknown", [ ("Test1", "Test2", "Test3", "Test4"), (0, 1, 2, 3), (123, -123, 0, -1), ], ) def test_decode_struct_array_union(self, proto, tag1, tag2, tag3, unknown): class Test1(Struct, tag=tag1, array_like=True): a: int b: int c: int = 0 class Test2(Struct, tag=tag2, array_like=True): x: int y: int class Test3(Struct, tag=tag3, array_like=True): pass dec = proto.Decoder(Test1 | Test2 | Test3) enc = proto.Encoder() # Decoding works assert dec.decode(enc.encode([tag1, 1, 2])) == Test1(1, 2) assert dec.decode(enc.encode([tag2, 3, 4])) == Test2(3, 4) assert dec.decode(enc.encode([tag3])) == Test3() # Optional & Extra fields still respected assert dec.decode(enc.encode([tag1, 1, 2, 3])) == Test1(1, 2, 3) assert dec.decode(enc.encode([tag1, 1, 2, 3, 4])) == Test1(1, 2, 3) # Missing required field with pytest.raises(ValidationError) as rec: dec.decode(enc.encode([tag1, 1])) assert "Expected `array` of at least length 3, got 2" in str(rec.value) # Type error has correct field index with pytest.raises(ValidationError) as rec: dec.decode(enc.encode([tag1, 1, "bad", 2])) assert "Expected `int`, got `str` - at `$[2]`" == str(rec.value) # Tag missing with pytest.raises(ValidationError) as rec: dec.decode(enc.encode([])) assert "Expected `array` of at least length 1, got 0" == str(rec.value) # Tag wrong type with pytest.raises(ValidationError) as rec: dec.decode(enc.encode([123.456, 2, 3, 4])) assert f"Expected `{type(tag1).__name__}`" in str(rec.value) assert "`$[0]`" in str(rec.value) # Tag unknown with pytest.raises(ValidationError) as rec: dec.decode(enc.encode([unknown, 1, 2, 3])) assert f"Invalid value {unknown!r} - at `$[0]`" == str(rec.value) @pytest.mark.parametrize("array_like", [False, True]) def test_decode_struct_union_with_non_struct_types(self, array_like, proto): class Test1(Struct, tag=True, array_like=array_like): a: int b: int class Test2(Struct, tag=True, array_like=array_like): x: int y: int dec = proto.Decoder(Test1 | Test2 | int | str | None) enc = proto.Encoder() for msg in [Test1(1, 2), Test2(3, 4), None, 5, 6]: assert dec.decode(enc.encode(msg)) == msg with pytest.raises(ValidationError) as rec: dec.decode(enc.encode(True)) typ = "array" if array_like else "object" assert f"Expected `int | str | {typ} | null`, got `bool`" == str(rec.value) @pytest.mark.parametrize("array_like", [False, True]) def test_struct_union_cached(self, array_like, proto): from msgspec._core import _struct_lookup_cache as cache cache.clear() class Test1(Struct, tag=True, array_like=array_like): a: int b: int class Test2(Struct, tag=True, array_like=array_like): x: int y: int typ1 = Test2 | Test1 typ2 = Test1 | Test2 typ3 = Test1 | Test2 | int | None for typ in [typ1, typ2, typ3]: for msg in [Test1(1, 2), Test2(3, 4)]: assert proto.decode(proto.encode(msg), type=typ) == msg assert len(cache) == 1 assert frozenset((Test1, Test2)) in cache def test_struct_union_cache_evicted(self, proto): from msgspec._core import _struct_lookup_cache as cache MAX_CACHE_SIZE = 64 # XXX: update if hardcoded value in `_core.c` changes cache.clear() def call_with_new_types(): class Test1(Struct, tag=True): a: int class Test2(Struct, tag=True): x: int typ = (Test1, Test2) proto.decode(proto.encode(Test1(1)), type=Union[typ]) return frozenset(typ) first = call_with_new_types() assert first in cache # Fill up the cache for _ in range(MAX_CACHE_SIZE - 1): call_with_new_types() # Check that first item is still in cache and is first in order assert len(cache) == MAX_CACHE_SIZE assert first in cache assert first == list(cache.keys())[0] # Add a new item, causing an item to be popped from the cache new = call_with_new_types() assert len(cache) == MAX_CACHE_SIZE assert first not in cache assert frozenset(new) in cache class TestGenericStruct: def test_generic_struct_info_cached(self, proto): class Ex(Struct, Generic[T]): x: T typ = Ex[int] assert Ex[int] is typ dec = proto.Decoder(typ) info = typ.__msgspec_cache__ assert info is not None assert sys.getrefcount(info) <= 4 # info + attr + decoder + func call dec2 = proto.Decoder(typ) assert typ.__msgspec_cache__ is info assert sys.getrefcount(info) <= 5 del dec del dec2 assert sys.getrefcount(info) <= 3 def test_generic_struct_invalid_types_not_cached(self, proto): class Ex(Struct, Generic[T]): x: list[T] | tuple[float] for typ in [Ex, Ex[int]]: for _ in range(2): with pytest.raises(TypeError, match="not supported"): proto.Decoder(typ) assert not hasattr(typ, "__msgspec_cache__") def test_msgspec_cache_overwritten(self, proto): class Ex(Struct, Generic[T]): x: T typ = Ex[int] typ.__msgspec_cache__ = 1 with pytest.raises(RuntimeError, match="__msgspec_cache__"): proto.Decoder(typ) @pytest.mark.parametrize("array_like", [False, True]) def test_generic_struct(self, proto, array_like): class Ex(Struct, Generic[T], array_like=array_like): x: T y: list[T] sol = Ex(1, [1, 2]) msg = proto.encode(sol) res = proto.decode(msg, type=Ex) assert res == sol res = proto.decode(msg, type=Ex[int]) assert res == sol res = proto.decode(msg, type=Ex[int | str]) assert res == sol res = proto.decode(msg, type=Ex[float]) assert type(res.x) is float with pytest.raises(ValidationError, match="Expected `str`, got `int`"): proto.decode(msg, type=Ex[str]) @py312_plus def test_generic_with_typevar_syntax(self, proto): source = """ from msgspec import Struct class Ex[T](Struct): x: T y: list[T] """ with temp_module(source) as mod: sol = mod.Ex(1, [1, 2]) msg = proto.encode(sol) res = proto.decode(msg, type=mod.Ex) assert res == sol res = proto.decode(msg, type=mod.Ex[int]) assert res == sol res = proto.decode(msg, type=mod.Ex[Union[int, str]]) assert res == sol res = proto.decode(msg, type=mod.Ex[int | str]) assert res == sol res = proto.decode(msg, type=mod.Ex[float]) assert type(res.x) is float with pytest.raises(ValidationError, match="Expected `str`, got `int`"): proto.decode(msg, type=mod.Ex[str]) @pytest.mark.parametrize( "optional_union", [ pytest.param("Ex[T] | None", id="native-union"), pytest.param("Optional[Ex[T]]", id="typing.Optional"), ], ) @pytest.mark.parametrize("array_like", [False, True]) def test_recursive_generic_struct(self, proto, array_like, optional_union): source = f""" from __future__ import annotations from typing import Union, Generic, TypeVar, Optional from msgspec import Struct T = TypeVar("T") class Ex(Struct, Generic[T], array_like={array_like}): a: T b: {optional_union} """ with temp_module(source) as mod: msg = mod.Ex(a=1, b=mod.Ex(a=2, b=None)) msg2 = mod.Ex(a=1, b=mod.Ex(a="bad", b=None)) assert proto.decode(proto.encode(msg), type=mod.Ex) == msg assert proto.decode(proto.encode(msg2), type=mod.Ex) == msg2 assert proto.decode(proto.encode(msg), type=mod.Ex[int]) == msg with pytest.raises(ValidationError) as rec: proto.decode(proto.encode(msg2), type=mod.Ex[int]) if array_like: assert "`$[1][0]`" in str(rec.value) else: assert "`$.b.a`" in str(rec.value) assert "Expected `int`, got `str`" in str(rec.value) @pytest.mark.parametrize("array_like", [False, True]) def test_generic_struct_union(self, proto, array_like): class Test1(Struct, Generic[T], tag=True, array_like=array_like): a: T | None b: int class Test2(Struct, Generic[T], tag=True, array_like=array_like): x: T y: int typ = Test1[T] | Test2[T] msg1 = Test1(1, 2) s1 = proto.encode(msg1) msg2 = Test2("three", 4) s2 = proto.encode(msg2) msg3 = Test1(None, 4) s3 = proto.encode(msg3) assert proto.decode(s1, type=typ) == msg1 assert proto.decode(s2, type=typ) == msg2 assert proto.decode(s3, type=typ) == msg3 assert proto.decode(s1, type=typ[int]) == msg1 assert proto.decode(s3, type=typ[int]) == msg3 assert proto.decode(s2, type=typ[str]) == msg2 assert proto.decode(s3, type=typ[str]) == msg3 with pytest.raises(ValidationError) as rec: proto.decode(s1, type=typ[str]) assert "Expected `str | null`, got `int`" in str(rec.value) loc = "$[1]" if array_like else "$.a" assert loc in str(rec.value) with pytest.raises(ValidationError) as rec: proto.decode(s2, type=typ[int]) assert "Expected `int`, got `str`" in str(rec.value) loc = "$[1]" if array_like else "$.x" assert loc in str(rec.value) def test_unbound_typevars_use_bound_if_set(self, proto): T = TypeVar("T", bound=int | str) dec = proto.Decoder(list[T]) sol = [1, "two", 3, "four"] msg = proto.encode(sol) assert dec.decode(msg) == sol bad = proto.encode([1, {}]) with pytest.raises( ValidationError, match=r"Expected `int \| str`, got `object` - at `\$\[1\]`", ): dec.decode(bad) def test_unbound_typevars_with_constraints_unsupported(self, proto): T = TypeVar("T", int, str) with pytest.raises(TypeError) as rec: proto.Decoder(list[T]) assert "Unbound TypeVar `~T` has constraints" in str(rec.value) @pytest.mark.parametrize( "future", [pytest.param(False, id="no future"), pytest.param(True, id="future")], ) @pytest.mark.parametrize( "mapping_type", ["collections.abc.Mapping", "typing.Mapping"] ) def test_inherited_builtin_generic(self, mapping_type: str, future: bool): source = f""" from msgspec import Struct, StructMeta import collections import abc import typing T = typing.TypeVar("T") class CombinedMeta(StructMeta, abc.ABCMeta): pass class Foo({mapping_type}[str, T], Struct, typing.Generic[T], metaclass=CombinedMeta): data: dict[str, T] def __getitem__(self, x): return self.data[x] def __len__(self): return len(self.data) def __iter__(self): return iter(self.data) """ if future: source = "from __future__ import annotations\n" + textwrap.dedent(source) with temp_module(source) as mod, pytest.raises(ValidationError): msgspec.msgpack.decode( msgspec.msgpack.encode(mod.Foo({"x": "foo"})), type=mod.Foo[int] ) msgspec.msgpack.decode( msgspec.msgpack.encode(mod.Foo({"x": 1})), type=mod.Foo[int] ) @pytest.mark.parametrize("leaf", ["Child1", "Child2", "Child3"]) @pytest.mark.parametrize( "future", [pytest.param(False, id="no future"), pytest.param(True, id="future")], ) @pytest.mark.parametrize( "mapping_type", ["collections.abc.Mapping", "typing.Mapping"] ) def test_inherited_builtin_generic_multilevel( self, mapping_type: str, future: bool, leaf: str ): # the builtin generic must be listed *before* 'typing.Generic[T]'. With # 'Generic' first its '__class_getitem__' wins, so 'Base[U]' resolves to a # 'typing._GenericAlias' instead of a 'types.GenericAlias' source = f""" from msgspec import Struct, StructMeta import collections import abc import typing T = typing.TypeVar("T") U = typing.TypeVar("U") V = typing.TypeVar("V") W = typing.TypeVar("W") class CombinedMeta(StructMeta, abc.ABCMeta): pass class Base({mapping_type}[str, T], Struct, typing.Generic[T], metaclass=CombinedMeta): data: dict[str, T] def __getitem__(self, x): return self.data[x] def __len__(self): return len(self.data) def __iter__(self): return iter(self.data) class Child1(Base[U], typing.Generic[U]): pass class Child2(Child1[V], typing.Generic[V]): pass class Child3(Child2[W], typing.Generic[W]): pass """ if future: source = "from __future__ import annotations\n" + textwrap.dedent(source) with temp_module(source) as mod: typ = getattr(mod, leaf)[int] msgspec.json.decode(b'{"data": {"x": 1}}', type=typ) with pytest.raises(ValidationError): msgspec.json.decode(b'{"data": {"x": "not_an_int"}}', type=typ) @pytest.mark.parametrize("leaf", ["Child1", "Child2", "Child3"]) @pytest.mark.parametrize( "mapping_type", ["collections.abc.Mapping", "typing.Mapping"] ) @py312_plus def test_inherited_builtin_generic_multilevel_typevar_syntax( self, mapping_type: str, leaf: str ): source = f""" from msgspec import Struct, StructMeta import collections import abc import typing class CombinedMeta(StructMeta, abc.ABCMeta): pass class Base[T]({mapping_type}[str, T], Struct, metaclass=CombinedMeta): data: dict[str, T] def __getitem__(self, x): return self.data[x] def __len__(self): return len(self.data) def __iter__(self): return iter(self.data) class Child1[U](Base[U]): pass class Child2[V](Child1[V]): pass class Child3[W](Child2[W]): pass """ with temp_module(source) as mod: typ = getattr(mod, leaf)[int] msgspec.json.decode(b'{"data": {"x": 1}}', type=typ) with pytest.raises(ValidationError): msgspec.json.decode(b'{"data": {"x": "not_an_int"}}', type=typ) @pytest.mark.parametrize( "future", [pytest.param(False, id="no future"), pytest.param(False, id="future")], ) @pytest.mark.parametrize( "mapping_type", ["collections.abc.Mapping", "typing.Mapping"] ) @py312_plus def test_inherited_builtin_generic_typevar_syntax( self, mapping_type: str, future: bool ): source = f""" from msgspec import Struct, StructMeta import collections import abc import typing class CombinedMeta(StructMeta, abc.ABCMeta): pass class Foo[T]({mapping_type}[str, T], Struct, metaclass=CombinedMeta): data: dict[str, T] def __getitem__(self, x): return self.data[x] def __len__(self): return len(self.data) def __iter__(self): return iter(self.data) """ if future: source = "from __future__ import annotations\n" + source with temp_module(source) as mod, pytest.raises(ValidationError): msgspec.msgpack.decode( msgspec.msgpack.encode(mod.Foo({"x": "foo"})), type=mod.Foo[int] ) msgspec.msgpack.decode( msgspec.msgpack.encode(mod.Foo({"x": 1})), type=mod.Foo[int] ) @pytest.mark.parametrize( "mapping_type", ["collections.abc.Mapping", "typing.Mapping"] ) @py312_plus def test_inherited_builtin_generic_typevar_syntax_info_cached( self, mapping_type: str ): source = f""" from msgspec import Struct, StructMeta import collections import abc import typing class CombinedMeta(StructMeta, abc.ABCMeta): pass class Foo[T]({mapping_type}[str, T], Struct, metaclass=CombinedMeta): data: dict[str, T] def __getitem__(self, x): return self.data[x] def __len__(self): return len(self.data) def __iter__(self): return iter(self.data) """ with temp_module(source) as mod: typ = mod.Foo[int] dec = msgspec.json.Decoder(typ) info = make_new_alias(typ).__msgspec_cache__ gc.collect() assert info is not None assert sys.getrefcount(info) <= 4 # info + attr + decoder + func call dec2 = msgspec.json.Decoder(typ) gc.collect() assert make_new_alias(typ).__msgspec_cache__ is info assert sys.getrefcount(info) <= 5 del dec del dec2 gc.collect() assert sys.getrefcount(info) <= 3 @pytest.mark.parametrize( "future", [pytest.param(False, id="no future"), pytest.param(True, id="future")], ) @pytest.mark.parametrize( "mapping_type", ["collections.abc.Mapping", "typing.Mapping"] ) def test_inherited_builtin_generic_multiple_typevars( self, mapping_type: str, future: bool ): # struct inheriting a builtin generic with *two* type vars. 'Pair[int, str]' # is a 'types.GenericAlias' carrying two args; the conversion must subscript # the rebuilt alias with the args *tuple* (not spread the args), otherwise # generics with more than one type var raise a 'TypeError' source = f""" from msgspec import Struct, StructMeta import collections import abc import typing K = typing.TypeVar("K") V = typing.TypeVar("V") class CombinedMeta(StructMeta, abc.ABCMeta): pass class Pair({mapping_type}[K, V], Struct, typing.Generic[K, V], metaclass=CombinedMeta): key: K val: V def __getitem__(self, x): return getattr(self, x) def __len__(self): return 2 def __iter__(self): return iter(("key", "val")) """ if future: source = "from __future__ import annotations\n" + textwrap.dedent(source) with temp_module(source) as mod: typ = mod.Pair[int, str] assert type(typ) is types.GenericAlias assert msgspec.json.decode(b'{"key": 1, "val": "a"}', type=typ) == mod.Pair( 1, "a" ) with pytest.raises(ValidationError, match="Expected `int`"): msgspec.json.decode(b'{"key": "x", "val": "a"}', type=typ) with pytest.raises(ValidationError, match="Expected `str`"): msgspec.json.decode(b'{"key": 1, "val": 2}', type=typ) # the 'types.GenericAlias' must also be normalised when nested inside a # union (collected via recursion) or a container (collected as its own # node), not just at the top level msg = b'{"key": 1, "val": "a"}' assert msgspec.json.decode(msg, type=typing.Optional[typ]) == mod.Pair( 1, "a" ) assert msgspec.json.decode(b"[" + msg + b"]", type=list[typ]) == [ mod.Pair(1, "a") ] def test_manual_types_generic_alias_robustness(self): # 'types.GenericAlias' instances can be built manually around arbitrary # origins (e.g. 'types.GenericAlias(...)' or a C-level 'Py_GenericAlias'), # not just via ordinary subscription. Feeding such aliases to msgspec used to # segfault when the origin wasn't a regularly-parametrised generic; ensure # they now either decode or raise a clean Python error. class GenericStruct(Struct, Generic[T]): x: T class PlainStruct(Struct): x: int # well-formed manual alias behaves exactly like the native subscription alias = types.GenericAlias(GenericStruct, (int,)) assert msgspec.json.decode(b'{"x": 1}', type=alias) == GenericStruct(1) with pytest.raises(ValidationError, match="Expected `int`"): msgspec.json.decode(b'{"x": "bad"}', type=alias) # parametrising a non-generic type is meaningless with pytest.raises(TypeError, match="not a generic type"): msgspec.json.Decoder(types.GenericAlias(PlainStruct, (int,))) # too many with pytest.raises(TypeError): msgspec.json.Decoder(types.GenericAlias(GenericStruct, (int, str))) class TestStructPostInit: @pytest.mark.parametrize("array_like", [False, True]) @pytest.mark.parametrize("union", [False, True]) def test_struct_post_init(self, array_like, union, proto): count = 0 singleton = object() class Ex(Struct, array_like=array_like, tag=union): x: int def __post_init__(self): nonlocal count count += 1 return singleton if union: class Ex2(Struct, array_like=array_like, tag=True): pass typ = Ex | Ex2 else: typ = Ex msg = Ex(1) buf = proto.encode(msg) res = proto.decode(buf, type=typ) assert res == msg assert count == 2 # 1 for Ex(), 1 for decode assert sys.getrefcount(singleton) <= 2 # 1 for ref, 1 for call @pytest.mark.parametrize("array_like", [False, True]) @pytest.mark.parametrize("union", [False, True]) @pytest.mark.parametrize("exc_class", [ValueError, TypeError, OSError]) def test_struct_post_init_errors(self, array_like, union, exc_class, proto): error = False class Ex(Struct, array_like=array_like, tag=union): x: int def __post_init__(self): if error: raise exc_class("Oh no!") if union: class Ex2(Struct, array_like=array_like, tag=True): pass typ = Ex | Ex2 else: typ = Ex msg = proto.encode([Ex(1)]) error = True if exc_class in (ValueError, TypeError): expected = ValidationError else: expected = exc_class with pytest.raises(expected, match="Oh no!") as rec: proto.decode(msg, type=list[typ]) if expected is ValidationError: assert "- at `$[0]`" in str(rec.value) @pytest.fixture(params=["dataclass", "attrs"]) def decorator(request): if request.param == "dataclass": return dataclass elif request.param == "attrs": if attrs is None: pytest.skip(reason="attrs not installed") return attrs.define class TestGenericDataclassOrAttrs: def test_generic_info_cached(self, decorator, proto): @decorator class Ex(Generic[T]): x: T typ = Ex[int] assert Ex[int] is typ dec = proto.Decoder(typ) info = typ.__msgspec_cache__ assert info is not None assert sys.getrefcount(info) <= 4 # info + attr + decoder + func call dec2 = proto.Decoder(typ) assert typ.__msgspec_cache__ is info assert sys.getrefcount(info) <= 5 del dec del dec2 assert sys.getrefcount(info) <= 3 def test_generic_invalid_types_not_cached(self, decorator, proto): @decorator class Ex(Generic[T]): x: list[T] | tuple[float] for typ in [Ex, Ex[int]]: for _ in range(2): with pytest.raises(TypeError, match="not supported"): proto.Decoder(typ) assert not hasattr(typ, "__msgspec_cache__") def test_msgspec_cache_overwritten(self, decorator, proto): @decorator class Ex(Generic[T]): x: T typ = Ex[int] typ.__msgspec_cache__ = 1 with pytest.raises(RuntimeError, match="__msgspec_cache__"): proto.Decoder(typ) def test_generic_dataclass(self, decorator, proto): @decorator class Ex(Generic[T]): x: T y: list[T] sol = Ex(1, [1, 2]) msg = proto.encode(sol) res = proto.decode(msg, type=Ex) assert res == sol res = proto.decode(msg, type=Ex[int]) assert res == sol res = proto.decode(msg, type=Ex[int | str]) assert res == sol res = proto.decode(msg, type=Ex[float]) assert type(res.x) is float with pytest.raises(ValidationError, match="Expected `str`, got `int`"): proto.decode(msg, type=Ex[str]) @pytest.mark.parametrize("module", ["dataclasses", "attrs"]) def test_recursive_generic(self, module, proto): pytest.importorskip(module) if module == "dataclasses": import_ = "from dataclasses import dataclass as decorator" else: import_ = "from attrs import define as decorator" source = f""" from __future__ import annotations from typing import Union, Generic, TypeVar from msgspec import Struct {import_} T = TypeVar("T") @decorator class Ex(Generic[T]): a: T b: Ex[T] | None """ with temp_module(source) as mod: msg = mod.Ex(a=1, b=mod.Ex(a=2, b=None)) msg2 = mod.Ex(a=1, b=mod.Ex(a="bad", b=None)) assert proto.decode(proto.encode(msg), type=mod.Ex) == msg assert proto.decode(proto.encode(msg2), type=mod.Ex) == msg2 assert proto.decode(proto.encode(msg), type=mod.Ex[int]) == msg with pytest.raises(ValidationError) as rec: proto.decode(proto.encode(msg2), type=mod.Ex[int]) assert "`$.b.a`" in str(rec.value) assert "Expected `int`, got `str`" in str(rec.value) @pytest.mark.parametrize("module", ["dataclasses", "attrs"]) @py312_plus def test_typevar_syntax(self, module, proto): pytest.importorskip(module) if module == "dataclasses": import_ = "from dataclasses import dataclass as decorator" else: import_ = "from attrs import define as decorator" source = f""" from __future__ import annotations from typing import Union from msgspec import Struct {import_} @decorator class Ex[T]: a: T b: Union[Ex[T], None] """ with temp_module(source) as mod: msg = mod.Ex(a=1, b=mod.Ex(a=2, b=None)) msg2 = mod.Ex(a=1, b=mod.Ex(a="bad", b=None)) assert proto.decode(proto.encode(msg), type=mod.Ex) == msg assert proto.decode(proto.encode(msg2), type=mod.Ex) == msg2 assert proto.decode(proto.encode(msg), type=mod.Ex[int]) == msg with pytest.raises(ValidationError) as rec: proto.decode(proto.encode(msg2), type=mod.Ex[int]) assert "`$.b.a`" in str(rec.value) assert "Expected `int`, got `str`" in str(rec.value) def test_unbound_typevars_use_bound_if_set(self, proto): T = TypeVar("T", bound=int | str) dec = proto.Decoder(list[T]) sol = [1, "two", 3, "four"] msg = proto.encode(sol) assert dec.decode(msg) == sol bad = proto.encode([1, {}]) with pytest.raises( ValidationError, match=r"Expected `int \| str`, got `object` - at `\$\[1\]`", ): dec.decode(bad) def test_unbound_typevars_with_constraints_unsupported(self, proto): T = TypeVar("T", int, str) with pytest.raises(TypeError) as rec: proto.Decoder(list[T]) assert "Unbound TypeVar `~T` has constraints" in str(rec.value) @pytest.mark.parametrize( "future", [pytest.param(False, id="no future"), pytest.param(False, id="future")], ) @pytest.mark.parametrize( "mapping_type", ["collections.abc.Mapping", "typing.Mapping"] ) def test_inherited_builtin_generic(self, mapping_type: str, future: bool): source = f""" import typing import dataclasses import collections T = typing.TypeVar("T") @dataclasses.dataclass class Foo(typing.Generic[T], {mapping_type}[str, T]): data: dict[str, T] def __getitem__(self, x): return self.data[x] def __len__(self): return len(self.data) def __iter__(self): return iter(self.data) """ if future: source = "from __future__ import annotations\n" + source with temp_module(source) as mod, pytest.raises(ValidationError): msgspec.msgpack.decode( msgspec.msgpack.encode(mod.Foo({"x": "foo"})), type=mod.Foo[int] ) msgspec.msgpack.decode( msgspec.msgpack.encode(mod.Foo({"x": 1})), type=mod.Foo[int] ) @pytest.mark.parametrize("leaf", ["Child1", "Child2", "Child3"]) @pytest.mark.parametrize( "future", [pytest.param(False, id="no future"), pytest.param(True, id="future")], ) @pytest.mark.parametrize( "mapping_type", ["collections.abc.Mapping", "typing.Mapping"] ) def test_inherited_builtin_generic_multilevel( self, mapping_type: str, future: bool, leaf: str ): # the builtin generic must be listed *before* 'typing.Generic[T]'. With # 'Generic' first its '__class_getitem__' wins, so 'Base[U]' resolves to a # 'typing._GenericAlias' instead of a 'types.GenericAlias' source = f""" import typing import dataclasses import collections T = typing.TypeVar("T") U = typing.TypeVar("U") V = typing.TypeVar("V") W = typing.TypeVar("W") @dataclasses.dataclass class Base({mapping_type}[str, T], typing.Generic[T]): data: dict[str, T] def __getitem__(self, x): return self.data[x] def __len__(self): return len(self.data) def __iter__(self): return iter(self.data) @dataclasses.dataclass class Child1(Base[U], typing.Generic[U]): pass @dataclasses.dataclass class Child2(Child1[V], typing.Generic[V]): pass @dataclasses.dataclass class Child3(Child2[W], typing.Generic[W]): pass """ if future: source = "from __future__ import annotations\n" + textwrap.dedent(source) with temp_module(source) as mod: typ = getattr(mod, leaf)[int] msgspec.json.decode(b'{"data": {"x": 1}}', type=typ) with pytest.raises(ValidationError): msgspec.json.decode(b'{"data": {"x": "not_an_int"}}', type=typ) @pytest.mark.parametrize("leaf", ["Child1", "Child2", "Child3"]) @pytest.mark.parametrize( "mapping_type", ["collections.abc.Mapping", "typing.Mapping"] ) @py312_plus def test_inherited_builtin_generic_multilevel_typevar_syntax( self, mapping_type: str, leaf: str ): source = f""" import typing import dataclasses import collections @dataclasses.dataclass class Base[T]({mapping_type}[str, T]): data: dict[str, T] def __getitem__(self, x): return self.data[x] def __len__(self): return len(self.data) def __iter__(self): return iter(self.data) @dataclasses.dataclass class Child1[U](Base[U]): pass @dataclasses.dataclass class Child2[V](Child1[V]): pass @dataclasses.dataclass class Child3[W](Child2[W]): pass """ with temp_module(source) as mod: typ = getattr(mod, leaf)[int] msgspec.json.decode(b'{"data": {"x": 1}}', type=typ) with pytest.raises(ValidationError): msgspec.json.decode(b'{"data": {"x": "not_an_int"}}', type=typ) @pytest.mark.parametrize( "future", [pytest.param(False, id="no future"), pytest.param(False, id="future")], ) @pytest.mark.parametrize( "mapping_type", ["collections.abc.Mapping", "typing.Mapping"] ) @py312_plus def test_inherited_builtin_generic_typevar_syntax( self, mapping_type: str, future: bool ): source = f""" import dataclasses import collections import typing @dataclasses.dataclass class Foo[T]({mapping_type}[str, T]): data: dict[str, T] def __getitem__(self, x): return self.data[x] def __len__(self): return len(self.data) def __iter__(self): return iter(self.data) """ if future: source = "from __future__ import annotations\n" + source with temp_module(source) as mod, pytest.raises(ValidationError): msgspec.msgpack.decode( msgspec.msgpack.encode(mod.Foo({"x": "foo"})), type=mod.Foo[int] ) msgspec.msgpack.decode( msgspec.msgpack.encode(mod.Foo({"x": 1})), type=mod.Foo[int] ) @pytest.mark.parametrize( "mapping_type", ["collections.abc.Mapping", "typing.Mapping"] ) @py312_plus def test_inherited_builtin_generic_typevar_syntax_info_cached( self, mapping_type: str ): source = f""" import dataclasses import collections import typing @dataclasses.dataclass class Foo[T]({mapping_type}[str, T]): data: dict[str, T] def __getitem__(self, x): return self.data[x] def __len__(self): return len(self.data) def __iter__(self): return iter(self.data) """ with temp_module(source) as mod: typ = mod.Foo[int] dec = msgspec.json.Decoder(typ) info = make_new_alias(typ).__msgspec_cache__ assert info is not None assert sys.getrefcount(info) <= 4 # info + attr + decoder + func call dec2 = msgspec.json.Decoder(typ) assert make_new_alias(typ).__msgspec_cache__ is info assert sys.getrefcount(info) <= 5 del dec del dec2 assert sys.getrefcount(info) <= 3 @pytest.mark.parametrize( "future", [pytest.param(False, id="no future"), pytest.param(True, id="future")], ) @pytest.mark.parametrize( "mapping_type", ["collections.abc.Mapping", "typing.Mapping"] ) def test_inherited_builtin_generic_multiple_typevars( self, mapping_type: str, future: bool ): # builtin generic is listed *before* 'typing.Generic' so that # 'Pair[int, str]' is a 'types.GenericAlias' (see # test_inherited_builtin_generic_multilevel). it carries two args, so the # conversion must subscript the rebuilt alias with the args *tuple* rather # than spreading them, else generics with more than one type var raise. source = f""" import typing import dataclasses import collections K = typing.TypeVar("K") V = typing.TypeVar("V") @dataclasses.dataclass class Pair({mapping_type}[K, V], typing.Generic[K, V]): key: K val: V def __getitem__(self, x): return getattr(self, x) def __len__(self): return 2 def __iter__(self): return iter(("key", "val")) """ if future: source = "from __future__ import annotations\n" + textwrap.dedent(source) with temp_module(source) as mod: typ = mod.Pair[int, str] assert type(typ) is types.GenericAlias assert msgspec.json.decode(b'{"key": 1, "val": "a"}', type=typ) == mod.Pair( 1, "a" ) with pytest.raises(ValidationError, match="Expected `int`"): msgspec.json.decode(b'{"key": "x", "val": "a"}', type=typ) with pytest.raises(ValidationError, match="Expected `str`"): msgspec.json.decode(b'{"key": 1, "val": 2}', type=typ) class TestStructOmitDefaults: def test_omit_defaults(self, proto): class Test(Struct, omit_defaults=True): a: int = 0 b: bool = False c: str | None = None d: list = [] e: list | set = set() f: dict = {} cases = [ (Test(), {}), (Test(1), {"a": 1}), (Test(1, False), {"a": 1}), (Test(1, True), {"a": 1, "b": True}), (Test(1, c=None), {"a": 1}), (Test(1, c="test"), {"a": 1, "c": "test"}), (Test(1, d=[1]), {"a": 1, "d": [1]}), (Test(1, e={1}), {"a": 1, "e": [1]}), (Test(1, e=[]), {"a": 1, "e": []}), (Test(1, f={"a": 1}), {"a": 1, "f": {"a": 1}}), ] for obj, sol in cases: res = proto.decode(proto.encode(obj)) assert res == sol @pytest.mark.parametrize("typ", [tuple, list, set, frozenset, dict]) def test_omit_defaults_collections(self, proto, typ): """Check that using empty collections as default values are detected regardless if they're specified by value or as a default_factory.""" class Test(Struct, omit_defaults=True): a: typ = msgspec.field(default_factory=typ) b: typ = msgspec.field(default=typ()) c: typ = typ() ex = {"x": 1} if typ is dict else [1] assert proto.encode(Test()) == proto.encode({}) for n in ["a", "b", "c"]: assert proto.encode(Test(**{n: typ(ex)})) == proto.encode({n: ex}) def test_omit_defaults_positional(self, proto): class Test(Struct, omit_defaults=True): a: int b: bool = False cases = [ (Test(1), {"a": 1}), (Test(1, False), {"a": 1}), (Test(1, True), {"a": 1, "b": True}), ] for obj, sol in cases: res = proto.decode(proto.encode(obj)) assert res == sol def test_omit_defaults_tagged(self, proto): class Test(Struct, omit_defaults=True, tag=True): a: int b: bool = False cases = [ (Test(1), {"type": "Test", "a": 1}), (Test(1, False), {"type": "Test", "a": 1}), (Test(1, True), {"type": "Test", "a": 1, "b": True}), ] for obj, sol in cases: res = proto.decode(proto.encode(obj)) assert res == sol def test_omit_defaults_ignored_for_array_like(self, proto): class Test(Struct, omit_defaults=True, array_like=True): a: int b: bool = False cases = [ (Test(1), [1, False]), (Test(1, False), [1, False]), (Test(1, True), [1, True]), ] for obj, sol in cases: res = proto.decode(proto.encode(obj)) assert res == sol class TestStructForbidUnknownFields: def test_forbid_unknown_fields(self, proto): class Test(Struct, forbid_unknown_fields=True): x: int y: int good = Test(1, 2) assert proto.decode(proto.encode(good), type=Test) == good bad = proto.encode({"x": 1, "y": 2, "z": 3}) with pytest.raises(ValidationError, match="Object contains unknown field `z`"): proto.decode(bad, type=Test) def test_forbid_unknown_fields_array_like(self, proto): class Test(Struct, forbid_unknown_fields=True, array_like=True): x: int y: int good = Test(1, 2) assert proto.decode(proto.encode(good), type=Test) == good bad = proto.encode([1, 2, 3]) with pytest.raises( ValidationError, match="Expected `array` of at most length 2" ): proto.decode(bad, type=Test) class PointUpper(Struct, rename="upper"): x: int y: int class TestStructRename: def test_rename_encode_struct(self, proto): res = proto.encode(PointUpper(1, 2)) exp = proto.encode({"X": 1, "Y": 2}) assert res == exp def test_rename_decode_struct(self, proto): msg = proto.encode({"X": 1, "Y": 2}) res = proto.decode(msg, type=PointUpper) assert res == PointUpper(1, 2) def test_rename_decode_struct_wrong_type(self, proto): msg = proto.encode({"X": 1, "Y": "bad"}) with pytest.raises(ValidationError) as rec: proto.decode(msg, type=PointUpper) assert "Expected `int`, got `str` - at `$.Y`" == str(rec.value) def test_rename_decode_struct_missing_field(self, proto): msg = proto.encode({"X": 1}) with pytest.raises(ValidationError) as rec: proto.decode(msg, type=PointUpper) assert "Object missing required field `Y`" == str(rec.value) class TestStructKeywordOnly: def test_keyword_only_object(self, proto): class Test(Struct, kw_only=True): a: int b: int = 2 c: int d: int = 4 sol = Test(a=1, b=2, c=3, d=4) msg = proto.encode({"a": 1, "b": 2, "c": 3, "d": 4}) res = proto.decode(msg, type=Test) assert res == sol msg = proto.encode({"a": 1, "c": 3}) res = proto.decode(msg, type=Test) assert res == sol sol = Test(a=1, b=3, c=5) msg = proto.encode({"a": 1, "b": 3, "c": 5}) res = proto.decode(msg, type=Test) assert res == sol msg = proto.encode({"a": 1, "b": 2}) with pytest.raises( ValidationError, match="missing required field `c`", ): proto.decode(msg, type=Test) msg = proto.encode({"c": 1, "b": 2}) with pytest.raises( ValidationError, match="missing required field `a`", ): proto.decode(msg, type=Test) def test_keyword_only_array(self, proto): class Test(Struct, kw_only=True, array_like=True): a: int b: int = 2 c: int d: int = 4 msg = proto.encode([5, 6, 7, 8]) res = proto.decode(msg, type=Test) assert res == Test(a=5, b=6, c=7, d=8) msg = proto.encode([5, 6, 7]) res = proto.decode(msg, type=Test) assert res == Test(a=5, b=6, c=7, d=4) msg = proto.encode([5, 6]) with pytest.raises( ValidationError, match="Expected `array` of at least length 3, got 2", ): proto.decode(msg, type=Test) msg = proto.encode([]) with pytest.raises( ValidationError, match="Expected `array` of at least length 3, got 0", ): proto.decode(msg, type=Test) class TestStructDefaults: def test_struct_defaults(self, proto): class Test(Struct): a: int = 1 b: list = [] c: int = msgspec.field(default=2) d: dict = msgspec.field(default_factory=dict) sol = Test() res = proto.decode(proto.encode(sol), type=Test) assert res == sol res = proto.decode(proto.encode({}), type=Test) assert res == sol def test_struct_default_factory_errors(self, proto): def bad(): raise ValueError("Oh no!") class Test(Struct): a: int = msgspec.field(default_factory=bad) msg = proto.encode({}) with pytest.raises(Exception, match="Oh no!"): proto.decode(msg, type=Test) class TestTypedDict: def test_types_generic_alias_non_generic_errors(self): # mostly a smoke test to weed out some bogus stuff that may get passed to us. # parametrising a non-generic TypedDict via a manually-built # 'types.GenericAlias' is meaningless and shoulf raise class Ex(TypedDict): a: int with pytest.raises(TypeError, match="not a generic type"): msgspec.json.Decoder(types.GenericAlias(Ex, (int,))) def test_type_cached(self, proto): class Ex(TypedDict): a: int b: str msg = {"a": 1, "b": "two"} dec = proto.Decoder(Ex) info = Ex.__msgspec_cache__ assert info is not None dec2 = proto.Decoder(Ex) assert Ex.__msgspec_cache__ is info assert dec.decode(proto.encode(msg)) == msg assert dec2.decode(proto.encode(msg)) == msg def test_msgspec_cache_overwritten(self, proto): class Ex(TypedDict): x: int Ex.__msgspec_cache__ = 1 with pytest.raises(RuntimeError, match="__msgspec_cache__"): proto.Decoder(Ex) def test_multiple_typeddict_errors(self, proto): class Ex1(TypedDict): a: int class Ex2(TypedDict): b: int with pytest.raises(TypeError, match="may not contain more than one TypedDict"): proto.Decoder(Ex1 | Ex2) with pytest.raises(TypeError, match="may not contain more than one TypedDict"): proto.Decoder(Union[Ex1, Ex2]) def test_subtype_error(self, proto): class Ex(TypedDict): a: int b: list | tuple with pytest.raises(TypeError, match="may not contain more than one array-like"): proto.Decoder(Ex) assert not hasattr(Ex, "__msgspec_cache__") def test_recursive_type(self, proto): source = """ from __future__ import annotations from typing import TypedDict, Union class Ex(TypedDict): a: int b: Ex | None """ with temp_module(source) as mod: msg = {"a": 1, "b": {"a": 2, "b": None}} dec = proto.Decoder(mod.Ex) assert dec.decode(proto.encode(msg)) == msg with pytest.raises(ValidationError) as rec: dec.decode(proto.encode({"a": 1, "b": {"a": "bad"}})) assert "`$.b.a`" in str(rec.value) assert "Expected `int`, got `str`" in str(rec.value) def test_total_true(self, proto): class Ex(TypedDict): a: int b: str dec = proto.Decoder(Ex) x = {"a": 1, "b": "two"} assert dec.decode(proto.encode(x)) == x x2 = {"a": 1, "b": "two", "c": "extra"} assert dec.decode(proto.encode(x2)) == x with pytest.raises(ValidationError) as rec: dec.decode(proto.encode({"b": "two"})) assert "Object missing required field `a`" == str(rec.value) with pytest.raises(ValidationError) as rec: dec.decode(proto.encode({"a": 1, "b": 2})) assert "Expected `str`, got `int` - at `$.b`" == str(rec.value) def test_duplicate_keys(self, proto): """Validating if all required keys are present is done with a count. We need to ensure that duplicate required keys don't increment the count, masking a missing field.""" class Ex(TypedDict): a: int b: str dec = proto.Decoder(Ex) temp = proto.encode({"a": 1, "b": "two", "x": 2}) msg = temp.replace(b"x", b"a") assert dec.decode(msg) == {"a": 2, "b": "two"} msg = temp.replace(b"x", b"a").replace(b"b", b"c") with pytest.raises(ValidationError) as rec: dec.decode(msg) assert "Object missing required field `b`" == str(rec.value) def test_total_false(self, proto): class Ex(TypedDict, total=False): a: int b: str dec = proto.Decoder(Ex) x = {"a": 1, "b": "two"} assert dec.decode(proto.encode(x)) == x x2 = {"a": 1, "b": "two", "c": "extra"} assert dec.decode(proto.encode(x2)) == x x3 = {"b": "two"} assert dec.decode(proto.encode(x3)) == x3 x4 = {} assert dec.decode(proto.encode(x4)) == x4 @pytest.mark.parametrize("use_typing_extensions", [False, True]) def test_total_partially_optional(self, proto, use_typing_extensions): if use_typing_extensions: tex = pytest.importorskip("typing_extensions") cls = tex.TypedDict else: cls = TypedDict class Base(cls): a: int b: str class Ex(Base, total=False): c: str dec = proto.Decoder(Ex) x = {"a": 1, "b": "two", "c": "extra"} assert dec.decode(proto.encode(x)) == x x2 = {"a": 1, "b": "two"} assert dec.decode(proto.encode(x2)) == x2 with pytest.raises(ValidationError) as rec: dec.decode(proto.encode({"b": "two"})) assert "Object missing required field `a`" == str(rec.value) @pytest.mark.parametrize("use_typing_extensions", [False, True]) def test_broken_typeddict(self, proto, use_typing_extensions): # Check that we don't crash if a TypedDict has incorrect # introspection data. if use_typing_extensions: tex = pytest.importorskip("typing_extensions") cls = tex.TypedDict else: cls = TypedDict class Ex(cls, total=False): c: str Ex.__annotations__ = {"c": "str"} Ex.__required_keys__ = {"a", "b"} with pytest.raises(RuntimeError): proto.Decoder(Ex) @pytest.mark.parametrize("use_typing_extensions", [False, True]) def test_required_and_notrequired(self, proto, use_typing_extensions): if use_typing_extensions: module = "typing_extensions" else: module = "typing" ns = pytest.importorskip(module) if not hasattr(ns, "Required"): pytest.skip(f"{module}.Required is not available") source = f""" from __future__ import annotations from {module} import TypedDict, Required, NotRequired class Base(TypedDict): a: int b: NotRequired[str] class Ex(Base, total=False): c: str d: Required[bool] """ with temp_module(source) as mod: dec = proto.Decoder(mod.Ex) x = {"a": 1, "b": "two", "c": "extra", "d": False} assert dec.decode(proto.encode(x)) == x x2 = {"a": 1, "d": False} assert dec.decode(proto.encode(x2)) == x2 with pytest.raises(ValidationError) as rec: dec.decode(proto.encode({"d": False})) assert "Object missing required field `a`" == str(rec.value) with pytest.raises(ValidationError) as rec: dec.decode(proto.encode({"a": 2})) assert "Object missing required field `d`" == str(rec.value) def test_keys_are_their_interned_values(self, proto): """Ensure that we're not allocating new keys here, but reusing the existing keys on the TypedDict schema""" class Ex(TypedDict): key_name_1: int key_name_2: int dec = proto.Decoder(Ex) msg = dec.decode(proto.encode({"key_name_1": 1, "key_name_2": 2})) for k1, k2 in zip(sorted(Ex.__annotations__), sorted(msg)): assert k1 is k2 def test_generic_typeddict_info_cached(self, proto): TypedDict = pytest.importorskip("typing_extensions").TypedDict class Ex(TypedDict, Generic[T]): x: T typ = Ex[int] assert Ex[int] is typ dec = proto.Decoder(typ) info = typ.__msgspec_cache__ assert info is not None assert sys.getrefcount(info) <= 4 # info + attr + decoder + func call dec2 = proto.Decoder(typ) assert typ.__msgspec_cache__ is info assert sys.getrefcount(info) <= 5 del dec del dec2 assert sys.getrefcount(info) <= 3 def test_generic_typeddict_invalid_types_not_cached(self, proto): TypedDict = pytest.importorskip("typing_extensions").TypedDict class Ex(TypedDict, Generic[T]): x: list[T] | tuple[float] for typ in [Ex, Ex[int]]: for _ in range(2): with pytest.raises(TypeError, match="not supported"): proto.Decoder(typ) assert not hasattr(typ, "__msgspec_cache__") def test_generic_typeddict(self, proto): TypedDict = pytest.importorskip("typing_extensions").TypedDict class Ex(TypedDict, Generic[T]): x: T y: list[T] sol = Ex(x=1, y=[1, 2]) msg = proto.encode(sol) res = proto.decode(msg, type=Ex) assert res == sol res = proto.decode(msg, type=Ex[int]) assert res == sol res = proto.decode(msg, type=Ex[int | str]) assert res == sol res = proto.decode(msg, type=Ex[float]) assert type(res["x"]) is float with pytest.raises(ValidationError, match="Expected `str`, got `int`"): proto.decode(msg, type=Ex[str]) def test_recursive_generic_typeddict(self, proto): pytest.importorskip("typing_extensions") source = """ from __future__ import annotations from typing import Union, Generic, TypeVar from typing_extensions import TypedDict T = TypeVar("T") class Ex(TypedDict, Generic[T]): a: T b: Ex[T] | None """ with temp_module(source) as mod: msg = mod.Ex(a=1, b=mod.Ex(a=2, b=None)) msg2 = mod.Ex(a=1, b=mod.Ex(a="bad", b=None)) assert proto.decode(proto.encode(msg), type=mod.Ex) == msg assert proto.decode(proto.encode(msg2), type=mod.Ex) == msg2 assert proto.decode(proto.encode(msg), type=mod.Ex[int]) == msg with pytest.raises(ValidationError) as rec: proto.decode(proto.encode(msg2), type=mod.Ex[int]) assert "`$.b.a`" in str(rec.value) assert "Expected `int`, got `str`" in str(rec.value) class TestNamedTuple: def test_types_generic_alias_non_generic_errors(self): # Parametrizing a non-generic NamedTuple via a manually-built # 'types.GenericAlias' is meaningless and must raise, not silently ignore the # args. class Ex(NamedTuple): a: int with pytest.raises(TypeError, match="not a generic type"): msgspec.json.Decoder(types.GenericAlias(Ex, (int,))) def test_type_cached(self, proto): class Ex(NamedTuple): a: int b: str msg = (1, "two") dec = proto.Decoder(Ex) info = Ex.__msgspec_cache__ assert info is not None dec2 = proto.Decoder(Ex) assert Ex.__msgspec_cache__ is info assert dec.decode(proto.encode(msg)) == msg assert dec2.decode(proto.encode(msg)) == msg def test_msgspec_cache_overwritten(self, proto): class Ex(NamedTuple): x: int Ex.__msgspec_cache__ = 1 with pytest.raises(RuntimeError, match="__msgspec_cache__"): proto.Decoder(Ex) def test_multiple_namedtuple_errors(self, proto): class Ex1(NamedTuple): a: int class Ex2(NamedTuple): b: int with pytest.raises(TypeError, match="may not contain more than one NamedTuple"): proto.Decoder(Ex1 | Ex2) with pytest.raises(TypeError, match="may not contain more than one NamedTuple"): proto.Decoder(Union[Ex1, Ex2]) def test_subtype_error(self, proto): class Ex(NamedTuple): a: int b: list | tuple with pytest.raises(TypeError, match="may not contain more than one array-like"): proto.Decoder(Ex) assert not hasattr(Ex, "__msgspec_cache__") def test_recursive_type(self, proto): source = """ from __future__ import annotations from typing import NamedTuple, Union class Ex(NamedTuple): a: int b: Ex | None """ with temp_module(source) as mod: msg = mod.Ex(1, mod.Ex(2, None)) dec = proto.Decoder(mod.Ex) assert dec.decode(proto.encode(msg)) == msg with pytest.raises(ValidationError) as rec: dec.decode(proto.encode(mod.Ex(1, ("bad", "two")))) assert "`$[1][0]`" in str(rec.value) assert "Expected `int`, got `str`" in str(rec.value) @pytest.mark.parametrize("use_typing", [True, False]) def test_decode_namedtuple_no_defaults(self, proto, use_typing): if use_typing: class Example(NamedTuple): a: int b: int c: int else: Example = namedtuple("Example", "a b c") dec = proto.Decoder(Example) msg = Example(1, 2, 3) res = dec.decode(proto.encode(msg)) assert res == msg suffix = ", got 1" if proto is msgspec.msgpack else "" with pytest.raises(ValidationError, match=f"length 3{suffix}"): dec.decode(proto.encode((1,))) suffix = ", got 6" if proto is msgspec.msgpack else "" with pytest.raises(ValidationError, match=f"length 3{suffix}"): dec.decode(proto.encode((1, 2, 3, 4, 5, 6))) @pytest.mark.parametrize("use_typing", [True, False]) def test_decode_namedtuple_with_defaults(self, proto, use_typing): if use_typing: class Example(NamedTuple): a: int b: int c: int = -3 d: int = -4 e: int = -5 else: Example = namedtuple("Example", "a b c d e", defaults=(-3, -4, -5)) dec = proto.Decoder(Example) for args in [(1, 2), (1, 2, 3), (1, 2, 3, 4), (1, 2, 3, 4, 5)]: msg = Example(*args) res = dec.decode(proto.encode(msg)) assert res == msg suffix = ", got 1" if proto is msgspec.msgpack else "" with pytest.raises(ValidationError, match=f"length 2 to 5{suffix}"): dec.decode(proto.encode((1,))) suffix = ", got 6" if proto is msgspec.msgpack else "" with pytest.raises(ValidationError, match=f"length 2 to 5{suffix}"): dec.decode(proto.encode((1, 2, 3, 4, 5, 6))) def test_decode_namedtuple_field_wrong_type(self, proto): dec = proto.Decoder(PersonTuple) msg = proto.encode((1, "bad", 2)) with pytest.raises( ValidationError, match=r"Expected `str`, got `int` - at `\$\[0\]`" ): dec.decode(msg) def test_decode_namedtuple_not_array(self, proto): dec = proto.Decoder(PersonTuple) msg = proto.encode({}) with pytest.raises(ValidationError, match="Expected `array`, got `object`"): dec.decode(msg) def test_generic_namedtuple_info_cached(self, proto): NamedTuple = pytest.importorskip("typing_extensions").NamedTuple class Ex(NamedTuple, Generic[T]): x: T typ = Ex[int] assert Ex[int] is typ dec = proto.Decoder(typ) info = typ.__msgspec_cache__ assert info is not None assert sys.getrefcount(info) <= 4 # info + attr + decoder + func call dec2 = proto.Decoder(typ) assert typ.__msgspec_cache__ is info assert sys.getrefcount(info) <= 5 del dec del dec2 assert sys.getrefcount(info) <= 3 def test_generic_namedtuple_invalid_types_not_cached(self, proto): NamedTuple = pytest.importorskip("typing_extensions").NamedTuple class Ex(NamedTuple, Generic[T]): x: list[T] | tuple[float] for typ in [Ex, Ex[int]]: for _ in range(2): with pytest.raises(TypeError, match="not supported"): proto.Decoder(typ) assert not hasattr(typ, "__msgspec_cache__") def test_generic_namedtuple(self, proto): NamedTuple = pytest.importorskip("typing_extensions").NamedTuple class Ex(NamedTuple, Generic[T]): x: T y: list[T] sol = Ex(1, [1, 2]) msg = proto.encode(sol) res = proto.decode(msg, type=Ex) assert res == sol res = proto.decode(msg, type=Ex[int]) assert res == sol res = proto.decode(msg, type=Ex[int | str]) assert res == sol res = proto.decode(msg, type=Ex[float]) assert type(res.x) is float with pytest.raises(ValidationError, match="Expected `str`, got `int`"): proto.decode(msg, type=Ex[str]) def test_recursive_generic_namedtuple(self, proto): pytest.importorskip("typing_extensions") source = """ from __future__ import annotations from typing import Union, Generic, TypeVar from typing_extensions import NamedTuple T = TypeVar("T") class Ex(NamedTuple, Generic[T]): a: T b: Ex[T] | None """ with temp_module(source) as mod: msg = mod.Ex(a=1, b=mod.Ex(a=2, b=None)) msg2 = mod.Ex(a=1, b=mod.Ex(a="bad", b=None)) assert proto.decode(proto.encode(msg), type=mod.Ex) == msg assert proto.decode(proto.encode(msg2), type=mod.Ex) == msg2 assert proto.decode(proto.encode(msg), type=mod.Ex[int]) == msg with pytest.raises(ValidationError) as rec: proto.decode(proto.encode(msg2), type=mod.Ex[int]) assert "`$[1][0]`" in str(rec.value) assert "Expected `int`, got `str`" in str(rec.value) def test_namedtuple_hash_preserved_after_roundtrip(self, proto): """Hash of deserialized NamedTuple matches hash of original. Regression test for gh-967. In Python 3.14+, tuples cache their hash in ob_hash. When msgspec allocates NamedTuples via tp_alloc (which zero-initializes memory), ob_hash was left at 0 — a valid cached hash — so hash() returned 0 for all deserialized NamedTuples.""" class Key(NamedTuple): value: int original = Key(value=42) encoded = proto.encode(original) decoded = proto.decode(encoded, type=Key) assert original == decoded assert hash(original) == hash(decoded) # Verify dict lookup works (requires matching hash) d = {original: "found"} assert decoded in d assert d[decoded] == "found" class TestDataclass: def test_encode_dataclass_err_invalid_dataclass_fields(self, proto): @dataclass class Ex: x: int Ex.__dataclass_fields__ = () with pytest.raises(RuntimeError, match="is not a dict"): proto.encode(Ex(1)) def test_encode_dataclass_class_errors(self, proto): @dataclass class Ex: x: int with pytest.raises(TypeError, match="Encoding objects of type type"): proto.encode(Ex) def test_encode_dataclass_no_slots(self, proto): @dataclass class Test: x: int y: int x = Test(1, 2) res = proto.encode(x) sol = proto.encode({"x": 1, "y": 2}) assert res == sol def test_encode_dataclass_slots(self, proto): @dataclass(slots=True) class Test: x: int y: int x = Test(1, 2) res = proto.encode(x) sol = proto.encode({"x": 1, "y": 2}) assert res == sol @pytest.mark.parametrize("slots", [True, False]) def test_encode_dataclass_missing_fields(self, proto, slots): @dataclass(slots=slots) class Test: x: int y: int z: int x = Test(1, 2, 3) sol = {"x": 1, "y": 2, "z": 3} for key in "xyz": delattr(x, key) del sol[key] res = proto.decode(proto.encode(x)) assert res == sol @pytest.mark.parametrize("slots_base", [True, False]) @pytest.mark.parametrize("slots", [True, False]) def test_encode_dataclass_subclasses(self, proto, slots_base, slots): @dataclass(slots=slots_base) class Base: x: int y: int @dataclass(slots=slots) class Test(Base): y: int z: int x = Test(1, 2, 3) res = proto.decode(proto.encode(x)) assert res == {"x": 1, "y": 2, "z": 3} # Missing attribute ignored del x.y res = proto.decode(proto.encode(x)) assert res == {"x": 1, "z": 3} @py311_plus def test_encode_dataclass_weakref_slot(self, proto): @dataclass(slots=True, weakref_slot=True) class Test: x: int y: int x = Test(1, 2) ref = weakref.ref(x) # noqa res = proto.decode(proto.encode(x)) assert res == {"x": 1, "y": 2} def test_encode_dataclass_classvars_ignored(self, proto): @dataclass class Ex: a: int b: ClassVar[int] = 2 msg = proto.encode(Ex(a=1)) assert msg == proto.encode({"a": 1}) def test_encode_dataclass_extra_fields_ignored(self, proto): @dataclass class Ex: a: int b: int x = Ex(1, 2) x.c = 3 msg = proto.encode(Ex(1, 2)) assert msg == proto.encode({"a": 1, "b": 2}) @pytest.mark.parametrize("order", ["acb", "bca", "cba"]) def test_encode_dataclass_dict_reordered(self, proto, order): @dataclass class Ex: a: int b: int c: int x = Ex(1, 2, 3) x.__dict__.clear() x.__dict__.update(dict(zip(order, range(3)))) res = proto.encode(x) sol = proto.encode(dict(sorted(zip(order, range(3))))) assert res == sol @pytest.mark.parametrize("present", ["ab", "a", "b", ""]) def test_encode_dataclass_ducktyped(self, proto, present): """gel.Object looks like a dataclass, but the implementation doesn't match the one from dataclasses. This ducktyped implementation tries to mirror the one in gel for testing purposes. Ref: https://docs.geldata.com/reference/using/python/api/types#gel.Object""" @dataclass class Ex: a: int b: int msg = {k: v for k, v in zip("ab", range(2)) if k in present} class Ex2: def __getattr__(self, key): return msg[key] __dataclass_fields__ = {} x = Ex2() x.__dataclass_fields__ = Ex.__dataclass_fields__ res = proto.encode(x) sol = proto.encode(msg) assert res == sol def test_encode_non_dataclass_skips_instance_getattr(self, proto): calls = [] class Ex: def __getattr__(self, key): calls.append(key) raise AttributeError(key) res = proto.encode([Ex()], enc_hook=lambda x: "hook") assert res == proto.encode(["hook"]) assert calls == [] @pytest.mark.parametrize("field", "xyz") def test_encode_dataclass_invalid_field_errors(self, proto, field): @dataclass class Test: x: int y: int z: int x = Test(1, 2, 3) setattr(x, field, object()) with pytest.raises(TypeError, match="unsupported"): proto.encode(x) def test_type_cached(self, proto): @dataclass class Ex: a: int b: str msg = Ex(a=1, b="two") dec = proto.Decoder(Ex) info = Ex.__msgspec_cache__ assert info is not None dec2 = proto.Decoder(Ex) assert Ex.__msgspec_cache__ is info assert dec.decode(proto.encode(msg)) == msg assert dec2.decode(proto.encode(msg)) == msg def test_decode_dataclass_subclasses(self, proto): @dataclass class Base: x: int @dataclass class Sub(Base): y: int msg = proto.encode({"x": 1, "y": 2}) assert proto.decode(msg, type=Base) == Base(1) assert proto.decode(msg, type=Sub) == Sub(1, 2) def test_multiple_dataclasses_errors(self, proto): @dataclass class Ex1: a: int @dataclass class Ex2: b: int with pytest.raises(TypeError, match="may not contain more than one dataclass"): proto.Decoder(Union[Ex1, Ex2]) def test_subtype_error(self, proto): @dataclass class Ex: a: int b: list | tuple with pytest.raises(TypeError, match="may not contain more than one array-like"): proto.Decoder(Ex) assert not hasattr(Ex, "__msgspec_cache__") def test_recursive_type(self, proto): source = """ from __future__ import annotations from typing import Union from dataclasses import dataclass @dataclass class Ex: a: int b: Ex | None """ with temp_module(source) as mod: msg = mod.Ex(a=1, b=mod.Ex(a=2, b=None)) dec = proto.Decoder(mod.Ex) assert dec.decode(proto.encode(msg)) == msg with pytest.raises(ValidationError) as rec: dec.decode(proto.encode({"a": 1, "b": {"a": "bad"}})) assert "`$.b.a`" in str(rec.value) assert "Expected `int`, got `str`" in str(rec.value) def test_classvars_ignored(self, proto): source = """ from __future__ import annotations from typing import ClassVar from dataclasses import dataclass @dataclass class Ex: a: int other: ClassVar[int] """ with temp_module(source) as mod: msg = mod.Ex(a=1) dec = proto.Decoder(mod.Ex) res = dec.decode(proto.encode({"a": 1, "other": 2})) assert res == msg assert not hasattr(res, "other") def test_initvars_forbidden(self, proto): source = """ from dataclasses import dataclass, InitVar @dataclass class Ex: a: int other: InitVar[int] """ with temp_module(source) as mod: with pytest.raises(TypeError, match="`InitVar` fields are not supported"): proto.Decoder(mod.Ex) @pytest.mark.parametrize("slots", [False, True]) def test_decode_dataclass(self, proto, slots): if slots: kws = {"slots": True} else: kws = {} @dataclass(**kws) class Example: a: int b: int c: int dec = proto.Decoder(Example) msg = Example(1, 2, 3) res = dec.decode(proto.encode(msg)) assert res == msg # Extra fields ignored res = dec.decode( proto.encode({"x": -1, "a": 1, "y": -2, "b": 2, "z": -3, "c": 3, "": -4}) ) assert res == msg # Missing fields error with pytest.raises(ValidationError, match="missing required field `b`"): dec.decode(proto.encode({"a": 1})) # Incorrect field types error with pytest.raises( ValidationError, match=r"Expected `int`, got `str` - at `\$.a`" ): dec.decode(proto.encode({"a": "bad"})) @pytest.mark.parametrize("frozen", [False, True]) @pytest.mark.parametrize("slots", [False, True]) def test_decode_dataclass_defaults(self, proto, frozen, slots): if slots: kws = {"slots": True} else: kws = {} @dataclass(frozen=frozen, **kws) class Example: a: int b: int c: int = -3 d: int = -4 e: int = field(default_factory=lambda: -1000) dec = proto.Decoder(Example) for args in [(1, 2), (1, 2, 3), (1, 2, 3, 4), (1, 2, 3, 4, 5)]: sol = Example(*args) msg = dict(zip("abcde", args)) res = dec.decode(proto.encode(msg)) assert res == sol # Missing fields error with pytest.raises(ValidationError, match="missing required field `a`"): dec.decode(proto.encode({"c": 1, "d": 2, "e": 3})) def test_decode_dataclass_default_factory_errors(self, proto): def bad(): raise ValueError("Oh no!") @dataclass class Example: a: int = field(default_factory=bad) with pytest.raises(ValueError, match="Oh no!"): proto.decode(proto.encode({}), type=Example) def test_decode_dataclass_frozen(self, proto): @dataclass(frozen=True) class Point: x: int y: int msg = proto.encode(Point(1, 2)) res = proto.decode(msg, type=Point) assert res == Point(1, 2) def test_decode_dataclass_post_init(self, proto): called = False @dataclass class Example: a: int def __post_init__(self): nonlocal called called = True res = proto.decode(proto.encode({"a": 1}), type=Example) assert res.a == 1 assert called @pytest.mark.parametrize("exc_class", [ValueError, TypeError, OSError]) def test_decode_dataclass_post_init_errors(self, proto, exc_class): @dataclass class Example: a: int def __post_init__(self): raise exc_class("Oh no!") expected = ( ValidationError if exc_class in (ValueError, TypeError) else exc_class ) with pytest.raises(expected, match="Oh no!") as rec: proto.decode(proto.encode([{"a": 1}]), type=list[Example]) if expected is ValidationError: assert "- at `$[0]`" in str(rec.value) def test_decode_dataclass_not_object(self, proto): @dataclass class Example: a: int b: int dec = proto.Decoder(Example) msg = proto.encode([]) with pytest.raises(ValidationError, match="Expected `object`, got `array`"): dec.decode(msg) @pytest.mark.skipif(attrs is None, reason="attrs not installed") class TestAttrs: def test_factory_takes_self_not_implemented(self, proto): """This feature is doable, but not yet implemented""" @attrs.define class Test: x: int = attrs.Factory(lambda self: 0, takes_self=True) with pytest.raises(NotImplementedError): proto.Decoder(Test) @pytest.mark.parametrize("slots", [True, False]) def test_encode_attrs(self, proto, slots): @attrs.define(slots=slots) class Test: x: int y: int x = Test(1, 2) res = proto.encode(x) sol = proto.encode({"x": 1, "y": 2}) assert res == sol @pytest.mark.parametrize("slots", [True, False]) def test_encode_attrs_missing_fields(self, proto, slots): @attrs.define(slots=slots) class Test: x: int y: int z: int x = Test(1, 2, 3) sol = {"x": 1, "y": 2, "z": 3} for key in "xyz": delattr(x, key) del sol[key] res = proto.decode(proto.encode(x)) assert res == sol @pytest.mark.parametrize("slots_base", [True, False]) @pytest.mark.parametrize("slots", [True, False]) def test_encode_attrs_subclasses(self, proto, slots_base, slots): @attrs.define(slots=slots_base) class Base: x: int y: int @attrs.define(slots=slots) class Test(Base): y: int z: int x = Test(1, 2, 3) res = proto.decode(proto.encode(x)) assert res == {"x": 1, "y": 2, "z": 3} # Missing attribute ignored del x.y res = proto.decode(proto.encode(x)) assert res == {"x": 1, "z": 3} def test_encode_attrs_weakref_slot(self, proto): @attrs.define(slots=True, weakref_slot=True) class Test: x: int y: int x = Test(1, 2) ref = weakref.ref(x) # noqa res = proto.decode(proto.encode(x)) assert res == {"x": 1, "y": 2} @pytest.mark.parametrize("slots", [True, False]) def test_encode_attrs_skip_leading_underscore(self, proto, slots): @attrs.define(slots=slots) class Test: x: int y: int _z: int x = Test(1, 2, 3) res = proto.encode(x) sol = proto.encode({"x": 1, "y": 2}) assert res == sol @pytest.mark.parametrize("slots", [False, True]) def test_decode_attrs(self, proto, slots): @attrs.define(slots=slots) class Example: a: int b: int c: int dec = proto.Decoder(Example) msg = Example(1, 2, 3) res = dec.decode(proto.encode(msg)) assert res == msg # Extra fields ignored res = dec.decode( proto.encode({"x": -1, "a": 1, "y": -2, "b": 2, "z": -3, "c": 3, "": -4}) ) assert res == msg # Missing fields error with pytest.raises(ValidationError, match="missing required field `b`"): dec.decode(proto.encode({"a": 1})) # Incorrect field types error with pytest.raises( ValidationError, match=r"Expected `int`, got `str` - at `\$.a`" ): dec.decode(proto.encode({"a": "bad"})) @pytest.mark.parametrize("frozen", [False, True]) @pytest.mark.parametrize("slots", [False, True]) def test_decode_attrs_defaults(self, proto, frozen, slots): @attrs.define(frozen=frozen, slots=slots) class Example: a: int b: int c: int = -3 d: int = -4 e: int = attrs.field(factory=lambda: -1000) dec = proto.Decoder(Example) for args in [(1, 2), (1, 2, 3), (1, 2, 3, 4), (1, 2, 3, 4, 5)]: sol = Example(*args) msg = dict(zip("abcde", args)) res = dec.decode(proto.encode(msg)) assert res == sol # Missing fields error with pytest.raises(ValidationError, match="missing required field `a`"): dec.decode(proto.encode({"c": 1, "d": 2, "e": 3})) def test_decode_attrs_default_factory_errors(self, proto): def bad(): raise ValueError("Oh no!") @attrs.define class Example: a: int = attrs.field(factory=bad) with pytest.raises(ValueError, match="Oh no!"): proto.decode(proto.encode({}), type=Example) def test_decode_attrs_frozen(self, proto): @attrs.define(frozen=True) class Example: x: int y: int msg = Example(1, 2) res = proto.decode(proto.encode(msg), type=Example) assert res == Example(1, 2) def test_decode_attrs_post_init(self, proto): called = False @attrs.define class Example: a: int def __attrs_post_init__(self): nonlocal called called = True res = proto.decode(proto.encode({"a": 1}), type=Example) assert res.a == 1 assert called @pytest.mark.parametrize("exc_class", [ValueError, TypeError, OSError]) def test_decode_attrs_post_init_errors(self, proto, exc_class): @attrs.define class Example: a: int def __attrs_post_init__(self): raise exc_class("Oh no!") expected = ( ValidationError if exc_class in (ValueError, TypeError) else exc_class ) with pytest.raises(expected, match="Oh no!") as rec: proto.decode(proto.encode([{"a": 1}]), type=list[Example]) if expected is ValidationError: assert "- at `$[0]`" in str(rec.value) def test_decode_attrs_pre_init(self, proto): called = False @attrs.define class Example: a: int def __attrs_pre_init__(self): nonlocal called called = True res = proto.decode(proto.encode({"a": 1}), type=Example) assert res.a == 1 assert called def test_decode_attrs_pre_init_errors(self, proto): @attrs.define class Example: a: int def __attrs_pre_init__(self): raise ValueError("Oh no!") with pytest.raises(ValueError, match="Oh no!"): proto.decode(proto.encode({"a": 1}), type=Example) def test_decode_attrs_validators(self, proto): def not2(self, attr, value): if value == 2: raise ValueError("Oh no!") @attrs.define class Example: a: int = attrs.field(validator=[attrs.validators.gt(0), not2]) res = proto.decode(proto.encode({"a": 1}), type=Example) assert res.a == 1 with pytest.raises(ValidationError): res = proto.decode(proto.encode({"a": -1}), type=Example) with pytest.raises(ValidationError, match="Oh no!"): res = proto.decode(proto.encode({"a": 2}), type=Example) def test_decode_attrs_not_object(self, proto): @attrs.define class Example: a: int b: int dec = proto.Decoder(Example) msg = proto.encode([]) with pytest.raises(ValidationError, match="Expected `object`, got `array`"): dec.decode(msg) class TestDate: def test_encode_date(self, proto): # All fields, zero padded x = datetime.date(1, 2, 3) s = proto.decode(proto.encode(x)) assert s == "0001-02-03" # All fields, no zeros x = datetime.date(1234, 12, 31) s = proto.decode(proto.encode(x)) assert s == "1234-12-31" @pytest.mark.parametrize( "s", [ "0001-01-01", "9999-12-31", "0001-02-03", "2020-02-29", ], ) def test_decode_date(self, proto, s): sol = datetime.date.fromisoformat(s) res = proto.decode(proto.encode(s), type=datetime.date) assert type(res) is datetime.date assert res == sol def test_decode_date_wrong_type(self, proto): msg = proto.encode([]) with pytest.raises(ValidationError, match="Expected `date`, got `array`"): proto.decode(msg, type=datetime.date) @pytest.mark.parametrize( "s", [ # Incorrect field lengths "001-02-03", "0001-2-03", "0001-02-3", # Trailing data "0001-02-0300", # Truncated "0001-02-", # Invalid characters "000a-02-03", "0001-0a-03", "0001-02-0a", # Year out of range "0000-02-03", # Month out of range "0001-00-03", "0001-13-03", # Day out of range for month "0001-02-00", "0001-02-29", "2000-02-30", ], ) def test_decode_date_malformed(self, proto, s): msg = proto.encode(s) with pytest.raises(ValidationError, match="Invalid RFC3339"): proto.decode(msg, type=datetime.date) class TestTime: @staticmethod def parse(t_str): t_str = t_str.replace("Z", "+00:00") return datetime.time.fromisoformat(t_str) @pytest.mark.parametrize( "t", [ "00:00:00", "01:02:03", "01:02:03.000004", "12:34:56.789000", "23:59:59.999999", ], ) def test_encode_time_naive(self, proto, t): res = proto.encode(self.parse(t)) sol = proto.encode(t) assert res == sol @pytest.mark.parametrize( "t", [ "00:00:00", "01:02:03", "01:02:03.000004", "12:34:56.789000", "23:59:59.999999", ], ) def test_decode_time_naive(self, proto, t): sol = self.parse(t) res = proto.decode(proto.encode(t), type=datetime.time) assert type(res) is datetime.time assert res == sol def test_decode_time_wrong_type(self, proto): msg = proto.encode([]) with pytest.raises(ValidationError, match="Expected `time`, got `array`"): proto.decode(msg, type=datetime.time) @pytest.mark.parametrize( "offset", [ datetime.timedelta(0), datetime.timedelta(days=1, microseconds=-1), datetime.timedelta(days=-1, microseconds=1), datetime.timedelta(days=1, seconds=-29), datetime.timedelta(days=-1, seconds=29), datetime.timedelta(days=0, seconds=30), datetime.timedelta(days=0, seconds=-30), ], ) def test_encode_time_offset_is_appx_equal_to_utc(self, proto, offset): x = datetime.time(14, 56, 27, 123456, datetime.timezone(offset)) res = proto.encode(x) sol = proto.encode("14:56:27.123456Z") assert res == sol @pytest.mark.parametrize( "offset, t_str", [ ( datetime.timedelta(days=1, seconds=-30), "14:56:27.123456+23:59", ), ( datetime.timedelta(days=-1, seconds=30), "14:56:27.123456-23:59", ), ( datetime.timedelta(minutes=19, seconds=32, microseconds=130000), "14:56:27.123456+00:20", ), ], ) def test_encode_time_offset_rounds_to_nearest_minute(self, proto, offset, t_str): x = datetime.time(14, 56, 27, 123456, datetime.timezone(offset)) res = proto.encode(x) sol = proto.encode(t_str) assert res == sol def test_encode_time_zoneinfo(self): import zoneinfo try: x = datetime.datetime( 2023, 1, 2, 3, 4, 5, 678, zoneinfo.ZoneInfo("America/Chicago") ) except zoneinfo.ZoneInfoNotFoundError: # Some envs in CI do not have `tzdata`: pytest.skip(reason="Failed to load timezone") sol = msgspec.json.encode(x.isoformat()) res = msgspec.json.encode(x) assert res == sol @pytest.mark.parametrize( "dt", [ "04:05:06.000007", "04:05:06.007", "04:05:06", "21:19:22.123456", ], ) @pytest.mark.parametrize("suffix", ["", "Z", "+00:00", "-00:00"]) def test_decode_time_utc(self, proto, dt, suffix): dt += suffix sol = self.parse(dt) msg = proto.encode(sol) res = proto.decode(msg, type=datetime.time) assert res == sol @pytest.mark.parametrize("t", ["00:00:01", "12:01:01"]) @pytest.mark.parametrize("sign", ["-", "+"]) @pytest.mark.parametrize("hour", [0, 8, 12, 16, 23]) @pytest.mark.parametrize("minute", [0, 30]) def test_decode_time_with_timezone(self, proto, t, sign, hour, minute): s = f"{t}{sign}{hour:02}:{minute:02}" msg = proto.encode(s) res = proto.decode(msg, type=datetime.time) sol = self.parse(s) assert res == sol @pytest.mark.parametrize("z", ["Z", "z"]) def test_decode_time_not_case_sensitive(self, proto, z): """Z can be upper/lowercase""" sol = datetime.time(4, 5, 6, 7, UTC) res = proto.decode(proto.encode(f"04:05:06.000007{z}"), type=datetime.time) assert res == sol @pytest.mark.parametrize( "lax, strict", [ ("03:04:05+0102", "03:04:05+01:02"), ("03:04:05-0102", "03:04:05-01:02"), ], ) def test_decode_time_rfc3339_relaxed(self, lax, strict, proto): """msgspec supports a few relaxations of the RFC3339 format.""" sol = datetime.time.fromisoformat(strict) msg = proto.encode(lax) res = proto.decode(msg, type=datetime.time) assert res == sol @pytest.mark.parametrize( "t, sol", [ ( "03:04:05.1234564Z", datetime.time(3, 4, 5, 123456, UTC), ), ( "03:04:05.1234565Z", datetime.time(3, 4, 5, 123457, UTC), ), ( "03:04:05.12345650000000000001Z", datetime.time(3, 4, 5, 123457, UTC), ), ( "03:04:05.9999995Z", datetime.time(3, 4, 6, 0, UTC), ), ( "03:04:59.9999995Z", datetime.time(3, 5, 0, 0, UTC), ), ( "03:59:59.9999995Z", datetime.time(4, 0, 0, 0, UTC), ), ( "23:59:59.9999995Z", datetime.time(0, 0, 0, 0, UTC), ), ], ) def test_decode_time_nanos(self, proto, t, sol): msg = proto.encode(t) res = proto.decode(msg, type=datetime.time) assert res == sol @pytest.mark.parametrize( "s", [ # Incorrect field lengths "1:02:03.0000004Z", "01:2:03.0000004Z", "01:02:3.0000004Z", "01:02:03.0000004+5:06", "01:02:03.0000004+05:6", "01:02:03.0000004+056", "01:02:03.0000004+05600", # Trailing data "01:02:030", "01:02:03a", "01:02:03.a", "01:02:03.0a", "01:02:03.0000004a", "01:02:03.0000004+00:000", "01:02:03.0000004+00000", "01:02:03.0000004Z0", # Truncated "01:02:3", # Missing +/- "01:02:0300:00", # Missing digits after decimal "01:02:03.", "01:02:03.Z", # Invalid characters "0a:02:03.004+05:06", "01:0a:03.004+05:06", "01:02:0a.004+05:06", "01:02:03.00a+05:06", "01:02:03.004+0a:06", "01:02:03.004+05:0a", "01:02:03.004+0a06", "01:02:03.004+050a", # Hour out of range "24:02:03.004", # Minute out of range "01:60:03.004", # Second out of range "01:02:60.004", # Timezone hour out of range "01:02:03.004+24:00", "01:02:03.004-24:00", # Timezone minute out of range "01:02:03.004+00:60", "01:02:03.004-00:60", ], ) def test_decode_time_malformed(self, proto, s): msg = proto.encode(s) with pytest.raises(ValidationError, match="Invalid RFC3339"): proto.decode(msg, type=datetime.time) class TestTimeDelta: @pytest.mark.parametrize("neg", [False, True]) @pytest.mark.parametrize( "td, msg", [ (timedelta(), "P0D"), (timedelta(1), "P1D"), (timedelta(10), "P10D"), (timedelta(123456789), "P123456789D"), (timedelta(0, 1), "PT1S"), (timedelta(0, 10), "PT10S"), (timedelta(0, 12345), "PT12345S"), (timedelta(0, 0, 1), "PT0.000001S"), (timedelta(0, 0, 10), "PT0.00001S"), (timedelta(0, 0, 100), "PT0.0001S"), (timedelta(0, 0, 1000), "PT0.001S"), (timedelta(0, 0, 10000), "PT0.01S"), (timedelta(0, 0, 100000), "PT0.1S"), (timedelta(123456789, 54321, 123456), "P123456789DT54321.123456S"), (timedelta(0, 86399, 999999), "PT86399.999999S"), ], ) def test_roundtrip_timedelta(self, proto, td, msg, neg): if neg and td: td = -td msg = "-" + msg buf = proto.encode(td) res = proto.decode(buf) assert res == msg td2 = proto.decode(buf, type=timedelta) assert td2 == td @pytest.mark.parametrize( "msg, sol", [ ("PT0S", timedelta()), ("+P1DT2S", timedelta(1, 2)), ("-P1DT2S", -timedelta(1, 2)), ("P000DT000.000S", timedelta()), ("-P000DT000.000S", timedelta()), ("P00012DT0045.670000000S", timedelta(12, 45, 670000)), ("P123456789.12345678912D", timedelta(123456789, 10666, 666580)), ("P123456789.12345678912999D", timedelta(123456789, 10666, 666580)), ("P123456789.12345678913D", timedelta(123456789, 10666, 666581)), ("PT0123H", timedelta(0, 123 * 60 * 60)), ("PT0123.456H", timedelta(0, 123.456 * 60 * 60)), ("PT0123M", timedelta(0, 123 * 60)), ("PT0123.456M", timedelta(0, 123.456 * 60)), ], ) def test_decode_timedelta(self, proto, msg, sol): buf = proto.encode(msg) res = proto.decode(buf, type=timedelta) assert res == sol def test_decode_timedelta_case_insensitive(self, proto): buf = proto.encode("p1dt2h3m4s") res = proto.decode(buf, type=timedelta) assert res == timedelta(1, 2 * 60 * 60 + 3 * 60 + 4) @pytest.mark.parametrize( "msg", [ "P999999999DT86399.999999S", "P999999998DT24H86399.999999S", "P999999999DT86399.9999994S", ], ) def test_decode_timedelta_max(self, proto, msg): buf = proto.encode(msg) res = proto.decode(buf, type=timedelta) assert res == timedelta.max @pytest.mark.parametrize( "msg", [ "-P999999999D", "-P999999998DT24H", "-P999999998DT23H3600S", "-P999999998DT86399.9999995S", ], ) def test_decode_timedelta_min(self, proto, msg): buf = proto.encode(msg) res = proto.decode(buf, type=timedelta) assert res == timedelta.min def test_decode_timedelta_wrong_type(self, proto): bad = proto.encode([]) with pytest.raises(ValidationError, match="Expected `duration`, got `array`"): proto.decode(bad, type=timedelta) @pytest.mark.parametrize( "msg", [ # No P "", "-", "+", # Just P "P", "-P", "+P", # Missing Number "PD", "P.0D", # Missing digit after decimal place "P123.", "P123.D", # Missing Unit "P0", "P0.0", "P0.00", "P0.000000000000123", # Trailing T "PT", "P0DT", # Missing T "P1D2H", "P1D2S", # Repeat T "PTT0S", # Repeat Units "P1D2D", "PT1H2H", "PT1M2M", "PT1S2S", # Units in wrong order "PT1H1D", "PT1M1H", "PT1S1M", # Non-fractional after fractional "PT1.2H1M", "P1.2DT1H", "PT1.2H0S", # Invalid characters "1P1D", "P-1D", "P1.-D", "P1.0-D", "P1.000000000000123-D", "P1D-", ], ) def test_decode_timedelta_malformed(self, proto, msg): encoded = proto.encode(msg) with pytest.raises(ValidationError, match="Invalid ISO8601 duration"): proto.decode(encoded, type=timedelta) @pytest.mark.parametrize( "msg", [ "P1000000000D", "PT140737488355329S", "P999999999DT86399.9999995S", "-P999999999DT0.0000005S", "P999999998DT48H", "-P999999998DT24H01S", ], ) def test_decode_timedelta_out_of_range(self, proto, msg): encoded = proto.encode(msg) with pytest.raises(ValidationError, match="Duration is out of range"): proto.decode(encoded, type=timedelta) @pytest.mark.parametrize("unit", ["Y", "M", "W"]) def test_decode_timedelta_unsupported_unit(self, proto, unit): upper = f"P1{unit}" for msg in [upper, upper.lower()]: encoded = proto.encode(msg) with pytest.raises(ValidationError, match="Only units 'D'"): proto.decode(encoded, type=timedelta) class TestUUID: def test_encoder_uuid_format(self, proto): assert proto.Encoder().uuid_format == "canonical" assert proto.Encoder(uuid_format="canonical").uuid_format == "canonical" assert proto.Encoder(uuid_format="hex").uuid_format == "hex" if proto is msgspec.msgpack: assert proto.Encoder(uuid_format="bytes").uuid_format == "bytes" else: with pytest.raises( ValueError, match="`uuid_format` must be 'canonical' or 'hex', got 'bytes'", ): proto.Encoder(uuid_format="bytes") def test_encoder_invalid_uuid_format(self, proto): if proto is msgspec.json: msg = "`uuid_format` must be 'canonical' or 'hex', got {!r}" else: msg = "`uuid_format` must be 'canonical', 'hex', or 'bytes', got {!r}" for bad in ["bad", 1]: with pytest.raises(ValueError, match=msg.format(bad)): proto.Encoder(uuid_format=bad) @pytest.mark.parametrize("format", ["canonical", "hex"]) def test_encode_uuid(self, format, proto): u = uuid.uuid4() enc = proto.Encoder(uuid_format=format) res = enc.encode(u) if format == "canonical": sol = enc.encode(str(u)) else: sol = enc.encode(u.hex) assert res == sol def test_encode_uuid_bytes(self): u = uuid.uuid4() enc = msgspec.msgpack.Encoder(uuid_format="bytes") res = enc.encode(u) sol = enc.encode(u.bytes) assert res == sol def test_encode_uuid_subclass(self, proto): class Ex(uuid.UUID): pass s = "4184defa-4d1a-4497-a140-fd1ec0b22383" assert proto.encode(Ex(s)) == proto.encode(s) def test_encode_uuid_malformed_internals(self, proto): """Ensure that if some other code mutates the uuid object, we error nicely rather than segfaulting""" u = uuid.uuid4() object.__delattr__(u, "int") with pytest.raises(AttributeError): proto.encode(u) u = uuid.uuid4() object.__setattr__(u, "int", "oops") with pytest.raises(TypeError): proto.encode(u) @pytest.mark.parametrize("upper", [False, True]) @pytest.mark.parametrize("hyphens", [False, True]) def test_decode_uuid(self, proto, upper, hyphens): u = uuid.uuid4() s = str(u) if hyphens else u.hex if upper: s = s.upper() msg = proto.encode(s) res = proto.decode(msg, type=uuid.UUID) assert res == u assert res.is_safe == u.is_safe def test_decode_uuid_from_bytes(self): sol = uuid.uuid4() msg = msgspec.msgpack.encode(sol.bytes) res = msgspec.msgpack.decode(msg, type=uuid.UUID) assert res == sol bad_msg = msgspec.msgpack.encode(b"x" * 8) with pytest.raises(msgspec.ValidationError, match="Invalid UUID bytes"): msgspec.msgpack.decode(bad_msg, type=uuid.UUID) @pytest.mark.parametrize( "uuid_str", [ # Truncated "12345678-1234-1234-1234-1234567890a", "123456781234123412341234567890a", # Truncated segments "1234567-1234-1234-1234-1234567890abc", "12345678-123-1234-1234-1234567890abc", "12345678-1234-123-1234-1234567890abc", "12345678-1234-1234-123-1234567890abc", "12345678-1234-1234-1234-1234567890a-", # Invalid character "123456x81234123412341234567890ab", "123456x8-1234-1234-1234-1234567890ab", "1234567x-1234-1234-1234-1234567890ab", "12345678-123x-1234-1234-1234567890ab", "12345678-1234-123x-1234-1234567890ab", "12345678-1234-1234-123x-1234567890ab", "12345678-1234-1234-1234-1234567890ax", # Invalid dash "12345678.1234-1234-1234-1234567890ab", "12345678-1234.1234-1234-1234567890ab", "12345678-1234-1234.1234-1234567890ab", "12345678-1234-1234-1234.1234567890ab", # Trailing data "12345678-1234-1234-1234-1234567890ab-", "12345678-1234-1234-1234-1234567890abc", ], ) def test_decode_uuid_malformed(self, proto, uuid_str): msg = proto.encode(uuid_str) with pytest.raises(ValidationError, match="Invalid UUID"): proto.decode(msg, type=uuid.UUID) class TestNewType: def test_decode_newtype(self, proto): UserId = NewType("UserId", int) assert proto.decode(proto.encode(1), type=UserId) == 1 with pytest.raises(ValidationError): proto.decode(proto.encode("bad"), type=UserId) # Nested NewId works UserId2 = NewType("UserId2", UserId) assert proto.decode(proto.encode(1), type=UserId2) == 1 with pytest.raises(ValidationError): proto.decode(proto.encode("bad"), type=UserId2) def test_decode_annotated_newtype(self, proto): UserId = NewType("UserId", int) dec = proto.Decoder(Annotated[UserId, msgspec.Meta(ge=0)]) assert dec.decode(proto.encode(1)) == 1 with pytest.raises(ValidationError): dec.decode(proto.encode(-1)) def test_decode_newtype_annotated(self, proto): UserId = NewType("UserId", Annotated[int, msgspec.Meta(ge=0)]) dec = proto.Decoder(UserId) assert dec.decode(proto.encode(1)) == 1 with pytest.raises(ValidationError): dec.decode(proto.encode(-1)) def test_decode_annotated_newtype_annotated(self, proto): UserId = Annotated[ NewType("UserId", Annotated[int, msgspec.Meta(ge=0)]), msgspec.Meta(le=10) ] dec = proto.Decoder(UserId) assert dec.decode(proto.encode(1)) == 1 for bad in [-1, 11]: with pytest.raises(ValidationError): dec.decode(proto.encode(bad)) class TestTypeAlias: @py312_plus def test_simple(self, proto): with temp_module("type Ex = str | None") as mod: dec = proto.Decoder(mod.Ex) assert dec.decode(proto.encode("test")) == "test" assert dec.decode(proto.encode(None)) is None with pytest.raises(ValidationError): dec.decode(proto.encode(1)) @py312_plus def test_generic(self, proto): with temp_module("type Pair[T] = tuple[T, T]") as mod: dec = proto.Decoder(mod.Pair) assert dec.decode(proto.encode((1, 2))) == (1, 2) for bad in [1, [1, 2, 3]]: with pytest.raises(ValidationError): dec.decode(proto.encode(bad)) @py312_plus def test_parametrized_generic(self, proto): with temp_module("type Pair[T] = tuple[T, T]") as mod: dec = proto.Decoder(mod.Pair[int]) assert dec.decode(proto.encode((1, 2))) == (1, 2) for bad in [1, [1, 2, 3], [1, "a"]]: with pytest.raises(ValidationError): dec.decode(proto.encode(bad)) @py312_plus def test_typealias_wrapping_typealias(self, proto): src = """ type Pair[T] = tuple[T, T] type Pairs[T] = list[Pair[T]] """ with temp_module(src) as mod: dec = proto.Decoder(mod.Pairs) for good in [[], [(1, 2), (3, 4)]]: assert dec.decode(proto.encode(good)) == good for bad in [1, [1], [(1, 2, 3)]]: with pytest.raises(ValidationError): dec.decode(proto.encode(bad)) dec = proto.Decoder(mod.Pairs[int]) for good in [[], [(1, 2)], [(1, 2), (3, 4)]]: assert dec.decode(proto.encode(good)) == good for bad in [1, [1], [(1, "a")]]: with pytest.raises(ValidationError): dec.decode(proto.encode(bad)) @py312_plus def test_typealias_with_constraints(self, proto): src = """ import msgspec from typing import Annotated type Key = Annotated[str, msgspec.Meta(max_length=4)] """ with temp_module(src) as mod: dec = proto.Decoder(mod.Key) for good in ["", "abc", "abcd"]: assert dec.decode(proto.encode(good)) == good for bad in [1, "abcde"]: with pytest.raises(ValidationError): dec.decode(proto.encode(bad)) @py312_plus def test_typealias_parametrized_generic_too_many_parameters(self): with temp_module("type Pair[T] = tuple[T, T]") as mod: with pytest.raises(TypeError): msgspec.json.Decoder(mod.Pair[int, int]) @py312_plus @pytest.mark.parametrize( "src", [ "type Ex = Ex | None", "type Ex = tuple[Ex, int]", "type Ex[T] = tuple[T, Ex[T]]", "type Temp[T] = tuple[T, Temp[T]]; Ex = Temp[int]", "type Temp[T] = tuple[T, Ex[T]]; type Ex[T] = tuple[Temp[T], T];", ], ) @emscripten_stack_limited @win_arm64_py312_stack_limited def test_recursive_typealias_errors(self, src): """Eventually we should support this, but for now just test that it errors cleanly""" with temp_module(src) as mod: with pytest.raises(RecursionError): msgspec.json.Decoder(mod.Ex) @py312_plus def test_typealias_invalid_type(self): with temp_module("type Ex = int | complex") as mod: with pytest.raises(TypeError): msgspec.json.Decoder(mod.Ex) class TestDecimal: def test_encoder_decimal_format(self, proto): assert proto.Encoder().decimal_format == "string" assert proto.Encoder(decimal_format="string").decimal_format == "string" assert proto.Encoder(decimal_format="number").decimal_format == "number" def fn(x): return str(x) enc = proto.Encoder(decimal_format=fn) assert enc.decimal_format is fn @pytest.mark.parametrize("decimal_format", ["bad", 1, {}]) def test_encoder_invalid_decimal_format(self, proto, decimal_format): with pytest.raises( ValueError, match=f"must be 'string', 'number', or a callable, got {decimal_format!r}", ): proto.Encoder(decimal_format=decimal_format) @pytest.mark.parametrize( ("value", "expected"), [ (decimal.Decimal("1.3449"), "1.345"), ([decimal.Decimal("1.3449")], ["1.345"]), ( [decimal.Decimal("1.3449"), [decimal.Decimal("1.3449")]], ["1.345", ["1.345"]], ), ( (decimal.Decimal("1.3449"), decimal.Decimal("1.3449")), ("1.345", "1.345"), ), ( {"key": decimal.Decimal("1.3449"), decimal.Decimal("1.3449"): "value"}, {"key": "1.345", "1.345": "value"}, ), ( { "key": { "sub_key": [ decimal.Decimal("1.3449"), decimal.Decimal("1.3449"), ] } }, {"key": {"sub_key": ["1.345", "1.345"]}}, ), ], ) def test_encoder_decimal_callable_convert_value_to_string( self, proto, value, expected ): enc = proto.Encoder( decimal_format=lambda d: str(d.quantize(decimal.Decimal("0.000"))) ) msg = enc.encode(value) assert msg == enc.encode(expected) @pytest.mark.parametrize( ("fn", "expected"), [ (lambda x: [str(x), str(x)], ["1.21", "1.21"]), (lambda x: {"key": str(x)}, {"key": "1.21"}), (lambda x: {str(x): "value"}, {"1.21": "value"}), (lambda x: {str(x)}, {"1.21"}), (lambda x: (str(x),), ("1.21",)), (lambda x: float(x.quantize(decimal.Decimal("0.0"))), 1.2), (lambda x: int(x.quantize(decimal.Decimal("0.0")) * 100), 120), ], ) def test_encoder_decimal_callable_convert_value_into_different_types( self, proto, fn, expected ): enc = proto.Encoder(decimal_format=lambda d: fn(d)) msg = enc.encode(decimal.Decimal("1.21")) assert msg == enc.encode(expected) @pytest.mark.parametrize( "fn", [ lambda x: [x], lambda x: {"key": x}, lambda x: {x: "value"}, lambda x: {x}, lambda x: (x,), lambda x: x.quantize(decimal.Decimal("0.0")), ], ) def test_encoder_decimal_callable_returned_a_value_containing_a_decimal( self, proto, fn: Callable[[decimal.Decimal], Any], ): enc = proto.Encoder(decimal_format=fn) with pytest.raises( TypeError, match="callable returned a value containing a Decimal" ): enc.encode(decimal.Decimal("1")) def test_encoder_decimal_callable_raise_error(self, proto): def bad_fn(x): raise NotImplementedError enc = proto.Encoder(decimal_format=bad_fn) with pytest.raises(NotImplementedError): enc.encode(decimal.Decimal("1.5")) def test_encoder_encode_decimal(self, proto): enc = proto.Encoder() d = decimal.Decimal("1.5") s = str(d) assert enc.encode(d) == enc.encode(s) def test_Encoder_encode_decimal_string(self, proto): enc = proto.Encoder(decimal_format="string") d = decimal.Decimal("1.5") sol = enc.encode(str(d)) assert enc.encode(d) == sol buf = bytearray() enc.encode_into(d, buf) assert buf == sol def test_Encoder_encode_decimal_number(self, proto): enc = proto.Encoder(decimal_format="number") d = decimal.Decimal("1.5") sol = enc.encode(float(d)) assert enc.encode(d) == sol buf = bytearray() enc.encode_into(d, buf) assert buf == sol def test_encode_decimal(self, proto): d = decimal.Decimal("1.5") s = str(d) assert proto.encode(d) == proto.encode(s) @pytest.mark.parametrize( "val", ["1.5", "InF", "-iNf", "iNfInItY", "-InFiNiTy", "NaN"] ) def test_decode_decimal_str(self, val, proto): sol = decimal.Decimal(val) msg = proto.encode(sol) res = proto.decode(msg, type=decimal.Decimal) assert str(res) == str(sol) assert type(res) is decimal.Decimal def test_decode_decimal_str_invalid(self, proto): msg = proto.encode("1..5") with pytest.raises(ValidationError, match="Invalid decimal string"): proto.decode(msg, type=decimal.Decimal) @pytest.mark.parametrize("val", [-1, -1234, 1, 1234]) def test_decode_decimal_int(self, val, proto): msg = proto.encode(val) sol = decimal.Decimal(str(val)) res = proto.decode(msg, type=decimal.Decimal) assert type(res) is decimal.Decimal assert res == sol @pytest.mark.parametrize( "val", [0.0, 1.3, float("nan"), float("inf"), float("-inf")] ) def test_decode_decimal_float(self, val, proto): msg = proto.encode(val) if msg == b"null": pytest.skip("nonfinite values not supported") sol = decimal.Decimal(str(val)) res = proto.decode(msg, type=decimal.Decimal) assert str(res) == str(sol) assert type(res) is decimal.Decimal class TestAbstractTypes: @pytest.mark.parametrize( "typ", [ typing.Collection, typing.MutableSequence, typing.Sequence, collections.abc.Collection, collections.abc.MutableSequence, collections.abc.Sequence, typing.MutableSet, typing.AbstractSet, collections.abc.MutableSet, collections.abc.Set, ], ) def test_abstract_sequence(self, proto, typ): # Hacky, but it works if "Set" in str(typ): sol = {1, 2} else: sol = [1, 2] msg = proto.encode(sol) assert proto.decode(msg, type=typ) == sol with pytest.raises(ValidationError, match="Expected `array`, got `str`"): proto.decode(proto.encode("a"), type=typ) assert proto.decode(msg, type=typ[int]) == sol with pytest.raises(ValidationError, match="Expected `int`, got `str`"): proto.decode(proto.encode(["a"]), type=typ[int]) @pytest.mark.parametrize( "typ", [ typing.MutableMapping, typing.Mapping, collections.abc.MutableMapping, collections.abc.Mapping, ], ) def test_abstract_mapping(self, proto, typ): sol = {"x": 1, "y": 2} msg = proto.encode(sol) assert proto.decode(msg, type=typ) == sol with pytest.raises(ValidationError, match="Expected `object`, got `str`"): proto.decode(proto.encode("a"), type=typ) assert proto.decode(msg, type=typ[str, int]) == sol with pytest.raises(ValidationError, match="Expected `int`, got `str`"): proto.decode(proto.encode({"a": "b"}), type=typ[str, int]) @py315_or_later_only @pytest.mark.parametrize( "typ", [ typing.MutableMapping, typing.Mapping, collections.abc.MutableMapping, collections.abc.Mapping, ], ) def test_abstract_mapping_frozendict(self, proto, typ): sol = frozendict({"x": 1, "y": 2}) msg = proto.encode(sol) res = proto.decode(msg, type=typ) assert res == sol assert type(res) is dict # does not roundtrip with pytest.raises(ValidationError, match="Expected `object`, got `str`"): proto.decode(proto.encode("a"), type=typ) assert proto.decode(msg, type=typ[str, int]) == sol with pytest.raises(ValidationError, match="Expected `int`, got `str`"): proto.decode(proto.encode(frozendict({"a": "b"})), type=typ[str, int]) class TestUnset: def test_unset_type_annotation_ignored(self, proto): class Ex(Struct): x: int | UnsetType dec = proto.Decoder(Ex) msg = proto.encode({"x": 1}) assert dec.decode(msg) == Ex(1) def test_encode_unset_errors_other_contexts(self, proto): with pytest.raises(TypeError): proto.encode(UNSET) @pytest.mark.parametrize("kind", ["struct", "dataclass", "attrs"]) def test_unset_encode(self, kind, proto): if kind == "struct": class Ex(Struct): x: int | UnsetType y: int | UnsetType elif kind == "dataclass": @dataclass class Ex: x: int | UnsetType y: int | UnsetType elif kind == "attrs": attrs = pytest.importorskip("attrs") @attrs.define class Ex: x: int | UnsetType y: int | UnsetType res = proto.encode(Ex(1, UNSET)) sol = proto.encode({"x": 1}) assert res == sol res = proto.encode(Ex(UNSET, 2)) sol = proto.encode({"y": 2}) assert res == sol res = proto.encode(Ex(UNSET, UNSET)) sol = proto.encode({}) assert res == sol def test_unset_encode_struct_omit_defaults(self, proto): class Ex(Struct, omit_defaults=True): x: int | UnsetType = UNSET y: int | UnsetType = UNSET z: int = 0 for x, y in [(Ex(), {}), (Ex(y=2), {"y": 2}), (Ex(z=1), {"z": 1})]: res = proto.encode(x) sol = proto.encode(y) assert res == sol class TestSet: def test_encode_set_doesnt_leak_item_refs(self, proto): class Ex: pass items = {Ex(), Ex(), Ex()} refs = [weakref.ref(item) for item in items] proto.Encoder(enc_hook=lambda x: None).encode(items) del items gc.collect() assert all(ref() is None for ref in refs) class TestOrder: def test_encoder_order_attribute(self, proto): enc = proto.Encoder() assert enc.order is None enc = proto.Encoder(order=None) assert enc.order is None enc = proto.Encoder(order="deterministic") assert enc.order == "deterministic" enc = proto.Encoder(order="sorted") assert enc.order == "sorted" def test_order_invalid(self, proto): with pytest.raises(ValueError, match="`order` must be one of"): proto.Encoder(order="bad") with pytest.raises(ValueError, match="`order` must be one of"): proto.encode(1, order="bad") @pytest.mark.parametrize("msg", [{}, {"y": 1, "x": 2, "z": 3}]) @pytest.mark.parametrize("order", [None, "deterministic", "sorted"]) @pytest.mark.parametrize("use_encoder", [False, True]) def test_order_dict(self, msg, order, use_encoder, proto): if use_encoder: res = proto.Encoder(order=order).encode(msg) else: res = proto.encode(msg, order=order) if order is not None: sol = proto.encode(dict(sorted(msg.items()))) else: sol = proto.encode(msg) assert res == sol def test_order_dict_non_str_errors(self, proto): with pytest.raises(TypeError, match="Only dicts with str keys"): proto.encode({"b": 2, 1: "a"}, order="deterministic") def test_order_dict_unsortable(self, proto): with pytest.raises(TypeError): proto.encode({"x": 1, 1: 2}, order="deterministic") @py315_or_later_only @pytest.mark.parametrize("msg", [{}, {"y": 1, "x": 2, "z": 3}]) @pytest.mark.parametrize("order", [None, "deterministic", "sorted"]) @pytest.mark.parametrize("use_encoder", [False, True]) def test_order_frozendict(self, msg, order, use_encoder, proto): if use_encoder: res = proto.Encoder(order=order).encode(frozendict(msg)) else: res = proto.encode(frozendict(msg), order=order) # `frozendict` must be equal to the regular `dict`: assert isinstance(msg, dict) if order is not None: sol = proto.encode(dict(sorted(msg.items()))) else: sol = proto.encode(msg) assert isinstance(res, bytes) assert res == sol @py315_or_later_only def test_order_frozendict_non_str_errors(self, proto): with pytest.raises(TypeError, match="Only dicts with str keys"): proto.encode(frozendict({"b": 2, 1: "a"}), order="deterministic") @py315_or_later_only def test_order_frozendict_unsortable(self, proto): with pytest.raises(TypeError): proto.encode(frozendict({"x": 1, 1: 2}), order="deterministic") @pytest.mark.parametrize("typ", [set, frozenset]) @pytest.mark.parametrize("order", ["deterministic", "sorted"]) def test_order_set(self, typ, proto, rand, order): assert proto.encode(typ(), order=order) == proto.encode([]) msg = typ(rand.str(10) for _ in range(20)) res = proto.encode(msg, order=order) sol = proto.encode(list(sorted(msg))) assert res == sol res = proto.encode(msg) sol = proto.encode(list(msg)) assert res == sol def test_order_set_unsortable(self, proto): with pytest.raises(TypeError): proto.encode({"x", 1}, order="deterministic") @pytest.mark.parametrize("n", [0, 1, 2]) @pytest.mark.parametrize( "kind", [ "struct", "dataclass", "attrs", "attrs-dict", ], ) def test_order_object(self, kind, n, proto): fields = [f"x{i}" for i in range(n)] fields.reverse() if kind == "struct": cls = msgspec.defstruct("Test", fields) elif kind == "dataclass": cls = make_dataclass("Test", fields) else: attrs = pytest.importorskip("attrs") cls = attrs.make_class("Test", fields, slots=(kind == "attrs")) msg = cls(*range(n)) if kind in ("struct", "dataclass"): # we currently don't guarantee field order with attrs types sol = proto.encode(dict(zip(fields, range(n)))) res = proto.encode(msg) assert res == sol res = proto.encode(msg, order="deterministic") assert res == sol res = proto.encode(msg, order="sorted") sol = proto.encode(dict(sorted(zip(fields, range(n))))) assert res == sol @pytest.mark.parametrize("kind", ["struct", "dataclass", "attrs", "attrs-dict"]) def test_order_unset(self, kind, proto): if kind == "struct": class Ex(Struct): z: int | UnsetType = UNSET x: int | UnsetType = UNSET elif kind == "dataclass": @dataclass class Ex: z: int | UnsetType = UNSET x: int | UnsetType = UNSET else: attrs = pytest.importorskip("attrs") @attrs.define(slots=(kind == "attrs")) class Ex: z: int | UnsetType = UNSET x: int | UnsetType = UNSET res = proto.encode(Ex(), order="sorted") sol = proto.encode({}) assert res == sol res = proto.encode(Ex(z=10), order="sorted") sol = proto.encode({"z": 10}) assert res == sol res = proto.encode(Ex(z=10, x=-1), order="sorted") sol = proto.encode({"x": -1, "z": 10}) assert res == sol def test_order_struct_omit_defaults(self, proto): class Ex(Struct, omit_defaults=True): z: int = 0 x: int = 1 y: int = 2 res = proto.encode(Ex(), order="sorted") sol = proto.encode({}) assert res == sol res = proto.encode(Ex(z=10), order="sorted") sol = proto.encode({"z": 10}) assert res == sol res = proto.encode(Ex(z=10, x=-1), order="sorted") sol = proto.encode({"x": -1, "z": 10}) assert res == sol def test_order_struct_tag(self, proto): class Ex(Struct, tag_field="y", tag=2): z: int x: int res = proto.encode(Ex(0, 1), order="sorted") sol = proto.encode({"x": 1, "y": 2, "z": 0}) assert res == sol @pytest.mark.parametrize("n", [0, 2, 3, 7, 15, 16, 17, 32, 100, 500, 1000, 10000]) def test_order_sort_implementation(self, rand, n): keys = [f"x_{i}" for i in range(n)] rand.shuffle(keys) msg = dict(zip(keys, range(n))) res = msgspec.json.encode(msg, order="deterministic") sol = msgspec.json.encode(dict(sorted(msg.items()))) assert res == sol class TestFinal: def test_decode_final(self, proto): dec = proto.Decoder(Final[int]) assert dec.decode(proto.encode(1)) == 1 with pytest.raises(ValidationError): dec.decode(proto.encode("bad")) def test_decode_final_annotated(self, proto): dec = proto.Decoder(Final[Annotated[int, msgspec.Meta(ge=0)]]) assert dec.decode(proto.encode(1)) == 1 with pytest.raises(ValidationError): dec.decode(proto.encode(-1)) def test_decode_final_newtype(self, proto): UserId = NewType("UserId", int) dec = proto.Decoder(Final[UserId]) assert dec.decode(proto.encode(1)) == 1 with pytest.raises(ValidationError): dec.decode(proto.encode("bad")) class TestLax: @pytest.mark.parametrize("strict", [True, False]) def test_strict_lax_decoder(self, proto, strict): dec = proto.Decoder(list[int], strict=strict) assert dec.strict is strict msg = proto.encode(["1", "2"]) if strict: with pytest.raises(ValidationError): dec.decode(msg) else: assert dec.decode(msg) == [1, 2] def test_lax_none(self, proto): for x in ["null", "Null", "nUll", "nuLl", "nulL"]: msg = proto.encode(x) assert proto.decode(msg, type=None, strict=False) is None for x in ["xull", "nxll", "nuxl", "nulx"]: msg = proto.encode(x) with pytest.raises(ValidationError, match="Expected `null`, got `str`"): proto.decode(msg, type=None, strict=False) def test_lax_bool_true(self, proto): for x in [1, "1", "true", "True", "tRue", "trUe", "truE"]: msg = proto.encode(x) assert proto.decode(msg, type=bool, strict=False) is True for x in [-1, 3, "x", "xx", "xrue", "txue", "trxe", "trux"]: msg = proto.encode(x) typ = type(x).__name__ with pytest.raises(ValidationError, match=f"Expected `bool`, got `{typ}`"): assert proto.decode(msg, type=bool, strict=False) def test_lax_bool_false(self, proto): for x in [0, "0", "false", "False", "fAlse", "faLse", "falSe", "falsE"]: msg = proto.encode(x) assert proto.decode(msg, type=bool, strict=False) is False for x in [-1, 3, "x", "xx", "xalse", "fxlse", "faxse", "falxe", "falsx"]: msg = proto.encode(x) typ = type(x).__name__ with pytest.raises(ValidationError, match=f"Expected `bool`, got `{typ}`"): assert proto.decode(msg, type=bool, strict=False) def test_lax_int(self, proto): for x in ["1", "-1", "123456"]: msg = proto.encode(x) assert proto.decode(msg, type=int, strict=False) == int(x) for x in ["a", "1a", "1.5", "1..", "nan", "inf"]: msg = proto.encode(x) with pytest.raises(ValidationError, match="Expected `int`, got `str`"): proto.decode(msg, type=int, strict=False) def test_lax_int_from_float(self, proto): bound = float(1 << 53) for x in [-bound, -1.0, -0.0, 0.0, 1.0, bound]: msg = proto.encode(x) assert proto.decode(msg, type=int, strict=False) == int(x) for x in [-bound - 2, -1.5, 0.001, 1.5, bound + 2]: msg = proto.encode(x) with pytest.raises(ValidationError, match="Expected `int`, got `float`"): proto.decode(msg, type=int, strict=False) def test_lax_int_constr(self, proto): typ = Annotated[int, Meta(ge=0)] msg = proto.encode("1") assert proto.decode(msg, type=typ, strict=False) == 1 msg = proto.encode("-1") with pytest.raises(ValidationError): proto.decode(msg, type=typ, strict=False) def test_lax_int_enum(self, proto): class Ex(enum.IntEnum): x = 1 y = -2 def roundtrip(msg): return proto.decode(proto.encode(msg), type=Ex, strict=False) assert roundtrip("1") is Ex.x assert roundtrip("-2") is Ex.y with pytest.raises(ValidationError, match="Invalid enum value 3"): roundtrip("3") with pytest.raises(ValidationError, match="Expected `int`, got `str`"): roundtrip("A") def test_lax_int_literal(self, proto): typ = Literal[1, -2] def roundtrip(msg): return proto.decode(proto.encode(msg), type=typ, strict=False) assert roundtrip("1") == 1 assert roundtrip("-2") == -2 with pytest.raises(ValidationError, match="Invalid enum value 3"): roundtrip("3") with pytest.raises(ValidationError, match="Expected `int`, got `str`"): roundtrip("A") def test_lax_float(self, proto): for x in ["1", "-1", "123456", "1.5", "-1.5", "inf"]: msg = proto.encode(x) assert proto.decode(msg, type=float, strict=False) == float(x) for x in ["a", "1a", "1.0.0", "1.."]: msg = proto.encode(x) with pytest.raises(ValidationError, match="Expected `float`, got `str`"): proto.decode(msg, type=float, strict=False) def test_lax_float_constr(self, proto): msg = proto.encode("1.5") assert proto.decode(msg, type=Annotated[float, Meta(ge=0)], strict=False) == 1.5 msg = proto.encode("-1.0") with pytest.raises(ValidationError): proto.decode(msg, type=Annotated[float, Meta(ge=0)], strict=False) def test_lax_str(self, proto): for x in ["1", "1.5", "false", "null"]: msg = proto.encode(x) assert proto.decode(msg, type=str, strict=False) == x def test_lax_str_constr(self, proto): typ = Annotated[str, Meta(max_length=10)] msg = proto.encode("xxx") assert proto.decode(msg, type=typ, strict=False) == "xxx" msg = proto.encode("x" * 20) with pytest.raises(ValidationError): proto.decode(msg, type=typ, strict=False) @pytest.mark.parametrize( "x", [ 1234.0000004, 1234.0000006, 1234.000567, 1234.567, 1234.0, 0.123, 0.0, 1234, 0, ], ) @pytest.mark.parametrize("sign", [-1, 1]) @pytest.mark.parametrize("transform", [None, str]) def test_lax_datetime(self, x, sign, transform, proto): timestamp = x * sign msg = proto.encode(transform(timestamp) if transform else timestamp) sol = datetime.datetime.fromtimestamp(timestamp, UTC) res = proto.decode(msg, type=datetime.datetime, strict=False) assert res == sol def test_lax_datetime_nonfinite_values(self, proto): values = ["nan", "-inf", "inf"] if proto is msgspec.msgpack: values.extend([float(v) for v in values]) for val in values: msg = proto.encode(val) with pytest.raises(ValidationError, match="Invalid epoch timestamp"): proto.decode(msg, type=datetime.datetime, strict=False) @pytest.mark.parametrize("val", [-62135596801, 253402300801]) @pytest.mark.parametrize("type", [int, float, str]) def test_lax_datetime_out_of_range(self, val, type, proto): msg = proto.encode(type(val)) with pytest.raises(ValidationError, match="out of range"): proto.decode(msg, type=datetime.datetime, strict=False) def test_lax_datetime_invalid_numeric_str(self, proto): for bad in ["", "12e", "1234a", "1234-1", "1234.a"]: msg = proto.encode(bad) with pytest.raises(ValidationError, match="Invalid"): proto.decode(msg, type=datetime.datetime, strict=False) @pytest.mark.parametrize("val", [123, -123, 123.456, "123.456"]) def test_lax_datetime_naive_required(self, val, proto): msg = proto.encode(val) with pytest.raises(ValidationError, match="no timezone component"): proto.decode( msg, type=Annotated[datetime.datetime, Meta(tz=False)], strict=False ) @pytest.mark.parametrize( "x", [ 1234.0000004, 1234.0000006, 1234.000567, 1234.567, 1234.0, 0.123, 0.0, 1234, 0, ], ) @pytest.mark.parametrize("sign", [-1, 1]) @pytest.mark.parametrize("transform", [None, str]) def test_lax_timedelta(self, x, sign, transform, proto): timestamp = x * sign msg = proto.encode(transform(timestamp) if transform else timestamp) sol = datetime.timedelta(seconds=timestamp) res = proto.decode(msg, type=datetime.timedelta, strict=False) assert res == sol def test_lax_timedelta_nonfinite_values(self, proto): values = ["nan", "-inf", "inf"] if proto is msgspec.msgpack: values.extend([float(v) for v in values]) for val in values: msg = proto.encode(val) with pytest.raises(ValidationError, match="out of range"): proto.decode(msg, type=datetime.timedelta, strict=False) @pytest.mark.parametrize("val", [86400000000001, -86399999913601]) @pytest.mark.parametrize("type", [int, float, str]) def test_lax_timedelta_out_of_range(self, val, type, proto): msg = proto.encode(type(val)) with pytest.raises(ValidationError, match="out of range"): proto.decode(msg, type=datetime.timedelta, strict=False) def test_lax_timedelta_invalid_numeric_str(self, proto): for bad in ["", "12e", "1234a", "1234-1", "1234.a"]: msg = proto.encode(bad) with pytest.raises(ValidationError, match="Invalid"): proto.decode(msg, type=datetime.timedelta, strict=False) @pytest.mark.parametrize( "x, sol", [ ("1", 1), ("0", 0), ("-1", -1), ("12.5", 12.5), ("inf", float("inf")), ("true", True), ("false", False), ("null", None), ], ) def test_lax_union_valid(self, x, sol, proto): typ = int | float | bool | None msg = proto.encode(x) assert_eq(proto.decode(msg, type=typ, strict=False), sol) @pytest.mark.parametrize("x", ["1a", "1.5a", "falsx", "trux", "nulx"]) def test_lax_union_invalid(self, x, proto): typ = int | float | bool | None msg = proto.encode(x) with pytest.raises( ValidationError, match="Expected `int | float | bool | null`" ): proto.decode(msg, type=typ, strict=False) @pytest.mark.parametrize( "x, err", [ ("-1", "`int` >= 0"), ("2000", "`int` <= 1000"), ("18446744073709551616", "`int` <= 1000"), ("-9223372036854775809", "`int` >= 0"), ("100.5", "`float` <= 100.0"), ], ) def test_lax_union_invalid_constr(self, x, err, proto): """Ensure that values that parse properly but don't meet the specified constraints error with a specific constraint error""" msg = proto.encode(x) typ = Annotated[int, Meta(ge=0), Meta(le=1000)] | Annotated[float, Meta(le=100)] with pytest.raises(ValidationError, match=err): proto.decode(msg, type=typ, strict=False) @pytest.mark.parametrize( "x, sol", [ ("1", 1), ("1.5", 1.5), ("false", False), ("true", True), ("null", None), ("2022-05-02", datetime.date(2022, 5, 2)), ], ) def test_lax_union_extended(self, proto, x, sol): typ = int | float | bool | datetime.date | None msg = proto.encode(x) assert_eq(proto.decode(msg, type=typ, strict=False), sol) @py315_or_later_only class TestFrozendict: def test_decode_frozendict_not_object(self, proto): dec = proto.Decoder(frozendict[str, int]) msg = proto.encode([]) with pytest.raises(ValidationError, match="Expected `object`, got `array`"): dec.decode(msg) def test_decode_frozendict_typed(self, proto): dec = proto.Decoder(frozendict[str, int]) msg = proto.encode(frozendict({"abc": 1})) res = dec.decode(msg) assert res == {"abc": 1} assert type(res) is frozendict msg = proto.encode(frozendict({"abc": "xyz"})) with pytest.raises(ValidationError, match="Expected `int`, got `str`"): dec.decode(msg) @pytest.mark.parametrize( "func, expected", [ pytest.param(msgspec.Raw, "(msg=b'', /)", id="Raw"), pytest.param(msgspec.msgpack.Ext, "(code, data, /)", id="Ext"), pytest.param(msgspec.structs.replace, "(struct, /, **changes)", id="replace"), pytest.param(msgspec.structs.asdict, "(struct, /)", id="asdict"), pytest.param(msgspec.structs.astuple, "(struct, /)", id="astuple"), pytest.param( msgspec.structs.force_setattr, "(struct, name, value, /)", id="force_setattr", ), pytest.param(msgspec.Raw(b"1").copy, "()", id="Raw.copy"), pytest.param( msgspec.json.Encoder().encode, "(obj, /)", id="json.Encoder.encode" ), pytest.param( msgspec.json.Encoder().encode_into, "(obj, buffer, offset=0, /)", id="json.Encoder.encode_into", ), pytest.param( msgspec.json.Encoder().encode_lines, "(items, /)", id="json.Encoder.encode_lines", ), pytest.param( msgspec.json.Decoder().decode, "(buf, /)", id="json.Decoder.decode" ), pytest.param( msgspec.json.Decoder().decode_lines, "(buf, /)", id="json.Decoder.decode_lines", ), pytest.param( msgspec.msgpack.Encoder().encode, "(obj, /)", id="msgpack.Encoder.encode" ), pytest.param( msgspec.msgpack.Encoder().encode_into, "(obj, buffer, offset=0, /)", id="msgpack.Encoder.encode_into", ), pytest.param( msgspec.msgpack.Decoder().decode, "(buf, /)", id="msgpack.Decoder.decode" ), ], ) def test_reported_signature(func, expected): """The reported signature must match how the callable is really called""" assert str(inspect.signature(func)) == expected def test_structmeta_text_signature_is_valid(): """`StructMeta` has a `__signature__` getset, so only the text form is checkable""" text_signature = msgspec.StructMeta.__text_signature__ exec(compile(f"def _f{text_signature}: pass", "", "exec"), {}) python-msgspec-0.22.0/tests/unit/test_constraints.py000066400000000000000000000661631525673062400227020ustar00rootroot00000000000000import datetime import math import re import sys from typing import Annotated import pytest import msgspec from msgspec import Meta @pytest.fixture(params=["json", "msgpack"]) def proto(request): if request.param == "json": return msgspec.json elif request.param == "msgpack": return msgspec.msgpack FIELDS = { "gt": 0, "ge": 0, "lt": 10, "le": 10, "multiple_of": 1, "pattern": "^foo$", "min_length": 0, "max_length": 10, "tz": True, "title": "example title", "description": "example description", "examples": ["example 1", "example 2"], "extra_json_schema": {"foo": "bar"}, "extra": {"fizz": "buzz"}, } def assert_eq(a, b): assert a == b assert not a != b def assert_ne(a, b): assert a != b assert not a == b class TestMetaObject: def test_init_nokwargs(self): c = Meta() for f in FIELDS: assert getattr(c, f) is None @pytest.mark.parametrize("field", FIELDS) def test_init_explicit_none(self, field): c = Meta(**{field: None}) for f in FIELDS: assert getattr(c, f) is None @pytest.mark.parametrize("field", FIELDS) def test_init(self, field): c = Meta(**{field: FIELDS[field]}) for f in FIELDS: sol = FIELDS[field] if f == field else None assert getattr(c, f) == sol def test_repr_empty(self): assert repr(Meta()) == "msgspec.Meta()" for field in FIELDS: c = Meta(**{field: None}) assert repr(c) == "msgspec.Meta()" def test_repr_error(self): class Oops: def __repr__(self): raise ValueError("Oh no!") m = Meta(extra_json_schema={"oops": Oops()}) with pytest.raises(ValueError, match="Oh no!"): repr(m) @pytest.mark.parametrize("field", FIELDS) def test_repr_one_field(self, field): c = Meta(**{field: FIELDS[field]}) assert repr(c) == f"msgspec.Meta({field}={FIELDS[field]!r})" def test_repr_multiple_fields(self): c = Meta(gt=0, lt=1) assert repr(c) == "msgspec.Meta(gt=0, lt=1)" def test_rich_repr_empty(self): assert Meta().__rich_repr__() == [] @pytest.mark.parametrize("field", FIELDS) def test_rich_repr_one_field(self, field): m = Meta(**{field: FIELDS[field]}) assert m.__rich_repr__() == [(field, FIELDS[field])] def test_rich_repr_multiple_fields(self): m = Meta(gt=0, lt=1) assert m.__rich_repr__() == [("gt", 0), ("lt", 1)] def test_equality(self): assert_eq(Meta(), Meta()) assert_ne(Meta(), None) with pytest.raises(TypeError): Meta() > Meta() with pytest.raises(TypeError): Meta() > None def test_hash(self): def samples(): return [ Meta(), Meta(ge=0), Meta(ge=1, le=2), Meta(ge=1, le=2, examples=["stuff"]), ] lk = {k: k for k in samples()} for key in samples(): assert lk[key] == key @pytest.mark.parametrize("field", FIELDS) def test_field_equality(self, field): val = FIELDS[field] if isinstance(val, dict): val2 = {} elif isinstance(val, list): val2 = [] elif isinstance(val, bool): val2 = not val elif isinstance(val, int): val2 = val + 25 else: val2 = "foobar" c = Meta(**{field: val}) c2 = Meta(**{field: val}) c3 = Meta(**{field: val2}) c4 = Meta() assert_eq(c, c) assert_eq(c, c2) assert_ne(c, c3) assert_ne(c, c4) assert_ne(c4, c) @pytest.mark.parametrize("field", ["gt", "ge", "lt", "le", "multiple_of"]) def test_numeric_fields(self, field): Meta(**{field: 1}) Meta(**{field: 2.5}) with pytest.raises( TypeError, match=f"`{field}` must be an int or float, got str" ): Meta(**{field: "bad"}) with pytest.raises(ValueError, match=f"`{field}` must be finite"): Meta(**{field: float("inf")}) @pytest.mark.parametrize("val", [0, 0.0]) def test_multiple_of_bounds(self, val): with pytest.raises(ValueError, match=r"`multiple_of` must be > 0"): Meta(multiple_of=val) @pytest.mark.parametrize("field", ["min_length", "max_length"]) def test_nonnegative_integer_fields(self, field): Meta(**{field: 0}) Meta(**{field: 10}) Meta(**{field: sys.maxsize}) with pytest.raises(TypeError, match=f"`{field}` must be an int, got float"): Meta(**{field: 1.5}) with pytest.raises(ValueError, match=f"`{field}` must be >= 0, got -1"): Meta(**{field: -1}) with pytest.raises(ValueError, match=f"`{field}` must be >= 0, got -10"): Meta(**{field: -10}) with pytest.raises( ValueError, match=f"`{field}` must be >= 0, got {-sys.maxsize - 1}" ): Meta(**{field: -sys.maxsize - 1}) @pytest.mark.parametrize("field", ["min_length", "max_length"]) @pytest.mark.parametrize( "val", [sys.maxsize + 1, -sys.maxsize - 2, 10**400, -(10**400)] ) def test_nonnegative_integer_fields_out_of_range(self, field, val): # Values outside Py_ssize_t need a range error in either direction. with pytest.raises(ValueError, match=f"`{field}` is out of range"): Meta(**{field: val}) @pytest.mark.parametrize("field", ["pattern", "title", "description"]) def test_string_fields(self, field): Meta(**{field: "good"}) with pytest.raises(TypeError, match=f"`{field}` must be a str, got bytes"): Meta(**{field: b"bad"}) @pytest.mark.parametrize("field", ["tz"]) def test_bool_fields(self, field): Meta(**{field: True}) Meta(**{field: False}) with pytest.raises(TypeError, match=f"`{field}` must be a bool, got float"): Meta(**{field: 1.5}) @pytest.mark.parametrize("field", ["examples"]) def test_list_fields(self, field): Meta(**{field: ["good", "stuff"]}) with pytest.raises(TypeError, match=f"`{field}` must be a list, got str"): Meta(**{field: "bad"}) @pytest.mark.parametrize("field", ["extra_json_schema", "extra"]) def test_dict_fields(self, field): Meta(**{field: {"good": "stuff"}}) with pytest.raises(TypeError, match=f"`{field}` must be a dict, got str"): Meta(**{field: "bad"}) def test_invalid_pattern_errors(self): with pytest.raises(re.error): Meta(pattern="[abc") def test_conflicting_bounds_errors(self): with pytest.raises(ValueError, match="both `gt` and `ge`"): Meta(gt=0, ge=1) with pytest.raises(ValueError, match="both `lt` and `le`"): Meta(lt=0, le=1) def test_mixing_numeric_and_nonnumeric_constraints_errors(self): with pytest.raises(ValueError, match="Cannot mix numeric constraints"): Meta(gt=0, pattern="foo") class TestInvalidConstraintAnnotations: """Constraint validity is applied in two places: - Type checks on constraint values in the `Meta` constructor - Type checks on type & constraint annotations in Decoder constructors The tests here check the latter. """ @pytest.mark.parametrize("name", ["ge", "gt", "le", "lt", "multiple_of"]) def test_invalid_numeric_constraints(self, name): with pytest.raises(TypeError, match=f"Can only set `{name}` on a numeric type"): msgspec.json.Decoder(Annotated[str, Meta(**{name: 1})]) def test_invalid_pattern_constraint(self): with pytest.raises(TypeError, match="Can only set `pattern` on a str type"): msgspec.json.Decoder(Annotated[int, Meta(pattern="ok")]) @pytest.mark.parametrize("name", ["min_length", "max_length"]) def test_invalid_length_constraint(self, name): with pytest.raises( TypeError, match=f"Can only set `{name}` on a str, bytes, or collection type", ): msgspec.json.Decoder(Annotated[int, Meta(**{name: 1})]) def test_invalid_tz_constraint(self): with pytest.raises( TypeError, match="Can only set `tz` on a datetime or time type", ): msgspec.json.Decoder(Annotated[int, Meta(tz=True)]) @pytest.mark.parametrize( "name, val", [("ge", 2**63), ("gt", 2**63 - 1), ("le", 2**63), ("lt", -(2**63))], ) def test_invalid_integer_bounds(self, name, val): with pytest.raises(ValueError) as rec: msgspec.json.Decoder(Annotated[int, Meta(**{name: val})]) assert name in str(rec.value) assert "not supported" in str(rec.value) def test_invalid_multiple_meta_annotations_conflict(self): with pytest.raises(TypeError, match="Multiple `Meta` annotations"): msgspec.json.Decoder(Annotated[int, Meta(ge=1), Meta(ge=2)]) def test_invalid_gt_and_ge_conflict(self): with pytest.raises(TypeError, match="Cannot set both `gt` and `ge`"): msgspec.json.Decoder(Annotated[int, Meta(gt=1), Meta(ge=2)]) def test_invalid_lt_and_le_conflict(self): with pytest.raises(TypeError, match="Cannot set both `lt` and `le`"): msgspec.json.Decoder(Annotated[int, Meta(lt=2), Meta(le=1)]) class TestIntConstraints: @pytest.mark.parametrize( "name, bound, good, bad", [ ("ge", -1, [-1, 2**63, 2**65], [-(2**64), -2]), ("gt", -1, [0, 2**63, 2**65], [-(2**64), -1]), ("le", -1, [-(2**64), -1], [0, 2**63, 2**65]), ("lt", -1, [-(2**64), -2], [-1, 2**63, 2**65]), ], ) def test_bounds(self, proto, name, bound, good, bad): if proto is msgspec.msgpack: # msgpack only supports int64/uint64 values good = [i for i in good if -(2**63) - 1 <= i <= 2**64] bad = [i for i in bad if -(2**63) - 1 <= i <= 2**64] class Ex(msgspec.Struct): x: Annotated[int, Meta(**{name: bound})] dec = proto.Decoder(Ex) for x in good: assert dec.decode(proto.encode(Ex(x))).x == x op = ">=" if name.startswith("g") else "<=" offset = {"lt": -1, "gt": 1}.get(name, 0) err_msg = rf"Expected `int` {op} {bound + offset} - at `\$.x`" for x in bad: with pytest.raises(msgspec.ValidationError, match=err_msg): dec.decode(proto.encode(Ex(x))) def test_multiple_of(self, proto): good = [-(2**64), -2, 0, 2, 40, 2**63 + 2, 2**65] bad = [1, -1, 2**63 + 1, 2**65 + 1] if proto is msgspec.msgpack: # msgpack only supports int64/uint64 values good = [i for i in good if -(2**63) - 1 <= i <= 2**64] bad = [i for i in bad if -(2**63) - 1 <= i <= 2**64] class Ex(msgspec.Struct): x: Annotated[int, Meta(multiple_of=2)] dec = proto.Decoder(Ex) for x in good: assert dec.decode(proto.encode(Ex(x))).x == x err_msg = r"Expected `int` that's a multiple of 2 - at `\$.x`" for x in bad: with pytest.raises(msgspec.ValidationError, match=err_msg): dec.decode(proto.encode(Ex(x))) @pytest.mark.parametrize( "meta, good, bad", [ (Meta(ge=0, le=10, multiple_of=2), [0, 2, 10], [-1, 1, 11]), (Meta(ge=0, multiple_of=2), [0, 2**63 + 2], [-2, 2**63 + 1]), (Meta(le=0, multiple_of=2), [0, -(2**63)], [-1, 2, 2**63]), (Meta(ge=0, le=10), [0, 10], [-1, 11]), (Meta(gt=0, lt=10), [1, 2, 9], [-1, 0, 10]), ], ) def test_combinations(self, proto, meta, good, bad): class Ex(msgspec.Struct): x: Annotated[int, meta] dec = proto.Decoder(Ex) for x in good: assert dec.decode(proto.encode(Ex(x))).x == x for x in bad: with pytest.raises(msgspec.ValidationError): dec.decode(proto.encode(Ex(x))) class TestFloatConstraints: @pytest.mark.parametrize("name", ["ge", "gt", "le", "lt"]) def test_bound_constraint_uint64_valid_for_floats(self, name): typ = Annotated[float, Meta(**{name: 2**63})] msgspec.json.Decoder(typ) def get_bounds_cases(self, name, bound): def ceilp1(x): return int(math.ceil(x + 1)) def floorm1(x): return int(math.floor(x - 1)) if name.startswith("g"): good_dir = math.inf good_round = ceilp1 bad_round = floorm1 else: good_dir = -math.inf good_round = floorm1 bad_round = ceilp1 if name.endswith("e"): good = bound bad = math.nextafter(bound, -good_dir) else: good = math.nextafter(bound, good_dir) bad = bound good_cases = [good, good_round(good), float(good_round(good))] bad_cases = [bad, bad_round(bad), float(bad_round(bad))] op = ">" if name.startswith("g") else "<" if name.endswith("e"): op += "=" return good_cases, bad_cases, op @pytest.mark.parametrize("name", ["ge", "gt", "le", "lt"]) @pytest.mark.parametrize("bound", [1.5, -1.5, 10.0]) def test_bounds(self, proto, name, bound): class Ex(msgspec.Struct): x: Annotated[float, Meta(**{name: bound})] dec = proto.Decoder(Ex) good, bad, op = self.get_bounds_cases(name, bound) for x in good: assert dec.decode(proto.encode(Ex(x))).x == x err_msg = rf"Expected `float` {op} {bound} - at `\$.x`" for x in bad: with pytest.raises(msgspec.ValidationError, match=err_msg): dec.decode(proto.encode(Ex(x))) def test_multiple_of(self, proto): """multipleOf for floats will always have precisions issues. This check just ensures that _some_ cases work. See https://github.com/json-schema-org/json-schema-spec/issues/312 for more info.""" class Ex(msgspec.Struct): x: Annotated[float, Meta(multiple_of=0.1)] dec = proto.Decoder(Ex) for x in [0, 0.0, 0.1, -0.1, 0.2, -0.2]: assert dec.decode(proto.encode(Ex(x))).x == x err_msg = r"Expected `float` that's a multiple of 0.1 - at `\$.x`" for x in [0.01, -0.15]: with pytest.raises(msgspec.ValidationError, match=err_msg): dec.decode(proto.encode(Ex(x))) @pytest.mark.parametrize( "meta, good, bad", [ (Meta(ge=0.0, le=10.0, multiple_of=2.0), [0, 2.0, 10], [-2, 11, 3]), (Meta(ge=0.0, multiple_of=2.0), [0, 2, 10.0], [-2, 3]), (Meta(le=10.0, multiple_of=2.0), [-2.0, 10.0], [11.0, 3.0]), (Meta(ge=0.0, le=10.0), [0.0, 2.0, 10.0], [-1.0, 11.5, 11]), ], ) def test_combinations(self, proto, meta, good, bad): class Ex(msgspec.Struct): x: Annotated[float, meta] dec = proto.Decoder(Ex) for x in good: assert dec.decode(proto.encode(Ex(x))).x == x for x in bad: with pytest.raises(msgspec.ValidationError): assert dec.decode(proto.encode(Ex(x))) class TestStrConstraints: def test_min_length(self, proto): class Ex(msgspec.Struct): x: Annotated[str, Meta(min_length=2)] dec = proto.Decoder(Ex) for x in ["xx", "xxx", "�x"]: assert dec.decode(proto.encode(Ex(x))).x == x err_msg = r"Expected `str` of length >= 2 - at `\$.x`" for x in ["x", "�", ""]: with pytest.raises(msgspec.ValidationError, match=err_msg): dec.decode(proto.encode(Ex(x))) def test_max_length(self, proto): class Ex(msgspec.Struct): x: Annotated[str, Meta(max_length=2)] dec = proto.Decoder(Ex) for x in ["", "xx", "�x"]: assert dec.decode(proto.encode(Ex(x))).x == x err_msg = r"Expected `str` of length <= 2 - at `\$.x`" for x in ["xxx", "�xx"]: with pytest.raises(msgspec.ValidationError, match=err_msg): dec.decode(proto.encode(Ex(x))) @pytest.mark.parametrize( "pattern, good, bad", [ ("", ["", "test"], []), ("as", ["as", "ease", "ast", "pass"], ["", "nope"]), ("^pre[123]*$", ["pre1", "pre123"], ["apre1", "pre1two"]), ], ) def test_pattern(self, proto, pattern, good, bad): class Ex(msgspec.Struct): x: Annotated[str, Meta(pattern=pattern)] dec = proto.Decoder(Ex) for x in good: assert dec.decode(proto.encode(Ex(x))).x == x err_msg = f"Expected `str` matching regex {pattern!r} - at `$.x`" for x in bad: with pytest.raises(msgspec.ValidationError) as rec: dec.decode(proto.encode(Ex(x))) assert str(rec.value) == err_msg @pytest.mark.parametrize( "meta, good, bad", [ ( Meta(min_length=2, max_length=3, pattern="x"), ["xy", "xyz"], ["x", "yy", "wxyz"], ), (Meta(min_length=2, max_length=4), ["xx", "xxxx"], ["x", "xxxxx"]), (Meta(min_length=2, pattern="x"), ["xy", "wxyz"], ["x", "bad"]), (Meta(max_length=3, pattern="x"), ["xy", "xyz"], ["y", "wxyz"]), ], ) def test_combinations(self, proto, meta, good, bad): class Ex(msgspec.Struct): x: Annotated[str, meta] dec = proto.Decoder(Ex) for x in good: assert dec.decode(proto.encode(Ex(x))).x == x for x in bad: with pytest.raises(msgspec.ValidationError): dec.decode(proto.encode(Ex(x))) @pytest.mark.parametrize( "meta, good, bad", [ (Meta(min_length=2), ["xy", "�xy"], ["", "�"]), (Meta(pattern="as"), ["as", "pass", "�as"], ["", "nope", "�"]), ], ) def test_str_constraints_on_dict_keys(self, proto, meta, good, bad): dec = proto.Decoder(dict[Annotated[str, meta], int]) for x in good: assert dec.decode(proto.encode({x: 1})) == {x: 1} for x in bad: with pytest.raises(msgspec.ValidationError): dec.decode(proto.encode({x: 1})) class TestDateTimeConstraints: @staticmethod def roundtrip(proto, cls, aware, as_str): dt = datetime.datetime.now(datetime.timezone.utc if aware else None) if as_str: s = proto.encode(cls(dt.isoformat())) else: s = proto.encode(cls(dt)) res = proto.decode(s, type=cls) assert res.x == dt @pytest.mark.parametrize("as_str", [True, False]) def test_tz_none(self, proto, as_str): class Ex(msgspec.Struct): x: Annotated[datetime.datetime, Meta(tz=None)] self.roundtrip(proto, Ex, True, as_str) self.roundtrip(proto, Ex, False, as_str) @pytest.mark.parametrize("as_str", [True, False]) def test_tz_false(self, proto, as_str): class Ex(msgspec.Struct): x: Annotated[datetime.datetime, Meta(tz=False)] self.roundtrip(proto, Ex, False, as_str) err_msg = r"Expected `datetime` with no timezone component - at `\$.x`" with pytest.raises(msgspec.ValidationError, match=err_msg): self.roundtrip(proto, Ex, True, as_str) @pytest.mark.parametrize("as_str", [True, False]) def test_tz_true(self, proto, as_str): class Ex(msgspec.Struct): x: Annotated[datetime.datetime, Meta(tz=True)] self.roundtrip(proto, Ex, True, as_str) err_msg = r"Expected `datetime` with a timezone component - at `\$.x`" with pytest.raises(msgspec.ValidationError, match=err_msg): self.roundtrip(proto, Ex, False, as_str) class TestTimeConstraints: @staticmethod def roundtrip(proto, cls, aware, as_str): dt = datetime.datetime.now(datetime.timezone.utc if aware else None).timetz() if as_str: s = proto.encode(cls(dt.isoformat())) else: s = proto.encode(cls(dt)) res = proto.decode(s, type=cls) assert res.x == dt @pytest.mark.parametrize("as_str", [True, False]) def test_tz_none(self, proto, as_str): class Ex(msgspec.Struct): x: Annotated[datetime.time, Meta(tz=None)] self.roundtrip(proto, Ex, True, as_str) self.roundtrip(proto, Ex, False, as_str) @pytest.mark.parametrize("as_str", [True, False]) def test_tz_false(self, proto, as_str): class Ex(msgspec.Struct): x: Annotated[datetime.time, Meta(tz=False)] self.roundtrip(proto, Ex, False, as_str) err_msg = r"Expected `time` with no timezone component - at `\$.x`" with pytest.raises(msgspec.ValidationError, match=err_msg): self.roundtrip(proto, Ex, True, as_str) @pytest.mark.parametrize("as_str", [True, False]) def test_tz_true(self, proto, as_str): class Ex(msgspec.Struct): x: Annotated[datetime.time, Meta(tz=True)] self.roundtrip(proto, Ex, True, as_str) err_msg = r"Expected `time` with a timezone component - at `\$.x`" with pytest.raises(msgspec.ValidationError, match=err_msg): self.roundtrip(proto, Ex, False, as_str) class TestBytesConstraints: @pytest.mark.parametrize("typ", [bytes, bytearray, memoryview]) def test_min_length(self, proto, typ): class Ex(msgspec.Struct): x: Annotated[typ, Meta(min_length=2)] dec = proto.Decoder(Ex) for x in [b"xx", b"xxx"]: assert bytes(dec.decode(proto.encode(Ex(x))).x) == x err_msg = r"Expected `bytes` of length >= 2 - at `\$.x`" for x in [b"", b"x"]: with pytest.raises(msgspec.ValidationError, match=err_msg): dec.decode(proto.encode(Ex(x))) @pytest.mark.parametrize("typ", [bytes, bytearray, memoryview]) def test_max_length(self, proto, typ): class Ex(msgspec.Struct): x: Annotated[typ, Meta(max_length=2)] dec = proto.Decoder(Ex) for x in [b"", b"xx"]: assert bytes(dec.decode(proto.encode(Ex(x))).x) == x err_msg = r"Expected `bytes` of length <= 2 - at `\$.x`" with pytest.raises(msgspec.ValidationError, match=err_msg): dec.decode(proto.encode(Ex(b"xxx"))) @pytest.mark.parametrize("typ", [bytes, bytearray, memoryview]) def test_combinations(self, proto, typ): class Ex(msgspec.Struct): x: Annotated[typ, Meta(min_length=2, max_length=4)] dec = proto.Decoder(Ex) for x in [b"xx", b"xxx", b"xxxx"]: assert bytes(dec.decode(proto.encode(Ex(x))).x) == x for x in [b"x", b"xxxxx"]: with pytest.raises(msgspec.ValidationError): dec.decode(proto.encode(Ex(x))) class TestArrayConstraints: @pytest.mark.parametrize("typ", [list, tuple, set, frozenset]) def test_min_length(self, proto, typ): class Ex(msgspec.Struct): x: Annotated[typ, Meta(min_length=2)] dec = proto.Decoder(Ex) for n in [2, 3]: x = typ(range(n)) assert dec.decode(proto.encode(Ex(x))).x == x err_msg = r"Expected `array` of length >= 2 - at `\$.x`" for n in [0, 1]: x = typ(range(n)) with pytest.raises(msgspec.ValidationError, match=err_msg): dec.decode(proto.encode(Ex(x))) @pytest.mark.parametrize("typ", [list, tuple, set, frozenset]) def test_max_length(self, proto, typ): class Ex(msgspec.Struct): x: Annotated[typ, Meta(max_length=2)] dec = proto.Decoder(Ex) for n in [0, 2]: x = typ(range(n)) assert dec.decode(proto.encode(Ex(x))).x == x err_msg = r"Expected `array` of length <= 2 - at `\$.x`" with pytest.raises(msgspec.ValidationError, match=err_msg): dec.decode(proto.encode(Ex(typ(range(3))))) @pytest.mark.parametrize("typ", [list, tuple, set, frozenset]) def test_combinations(self, proto, typ): class Ex(msgspec.Struct): x: Annotated[typ, Meta(min_length=2, max_length=4)] dec = proto.Decoder(Ex) for n in [2, 3, 4]: x = typ(range(n)) assert dec.decode(proto.encode(Ex(x))).x == x for n in [1, 5]: x = typ(range(n)) with pytest.raises(msgspec.ValidationError): dec.decode(proto.encode(Ex(x))) class TestMapConstraints: def test_min_length(self, proto): class Ex(msgspec.Struct): x: Annotated[dict[str, int], Meta(min_length=2)] dec = proto.Decoder(Ex) for n in [2, 3]: x = {str(i): i for i in range(n)} assert dec.decode(proto.encode(Ex(x))).x == x err_msg = r"Expected `object` of length >= 2 - at `\$.x`" for n in [0, 1]: x = {str(i): i for i in range(n)} with pytest.raises(msgspec.ValidationError, match=err_msg): dec.decode(proto.encode(Ex(x))) def test_max_length(self, proto): class Ex(msgspec.Struct): x: Annotated[dict[str, int], Meta(max_length=2)] dec = proto.Decoder(Ex) for n in [0, 2]: x = {str(i): i for i in range(n)} assert dec.decode(proto.encode(Ex(x))).x == x err_msg = r"Expected `object` of length <= 2 - at `\$.x`" x = {"1": 1, "2": 2, "3": 3} with pytest.raises(msgspec.ValidationError, match=err_msg): dec.decode(proto.encode(Ex(x))) def test_combinations(self, proto): class Ex(msgspec.Struct): x: Annotated[dict[str, int], Meta(min_length=2, max_length=4)] dec = proto.Decoder(Ex) for n in [2, 3, 4]: x = {str(i): i for i in range(n)} assert dec.decode(proto.encode(Ex(x))).x == x for n in [1, 5]: x = {str(i): i for i in range(n)} with pytest.raises(msgspec.ValidationError): dec.decode(proto.encode(Ex(x))) class TestUnionConstraints: def test_mix_float_and_int(self, proto): class Ex(msgspec.Struct): x: ( Annotated[int, Meta(ge=0, le=10)] | Annotated[float, Meta(ge=1000, le=2000)] ) dec = proto.Decoder(Ex) for x in [0, 5, 10, 1000.0, 1234.5, 2000.0]: assert dec.decode(proto.encode(Ex(x))).x == x for x in [0.0, 10.0, 1000, 2000]: with pytest.raises(msgspec.ValidationError): dec.decode(proto.encode(Ex(x))) def test_mix_length_constraints(self, proto): class Ex(msgspec.Struct): x: ( Annotated[dict[str, int], Meta(min_length=1, max_length=2)] | Annotated[list[int], Meta(min_length=3, max_length=4)] | Annotated[str, Meta(min_length=5, max_length=6)] ) dec = proto.Decoder(Ex) for x in [{"x": 1}, [1, 2, 3], "xxxxx"]: assert dec.decode(proto.encode(Ex(x))).x == x for x in [{}, [1], "x"]: with pytest.raises(msgspec.ValidationError): dec.decode(proto.encode(Ex(x))) python-msgspec-0.22.0/tests/unit/test_convert.py000066400000000000000000002645571525673062400220220ustar00rootroot00000000000000import datetime import decimal import enum import gc import math import sys import uuid from base64 import b64encode from collections.abc import MutableMapping from dataclasses import dataclass, field from typing import ( Annotated, Any, Dict, Generic, Literal, NamedTuple, TypedDict, TypeVar, ) import pytest import msgspec from msgspec import Meta, Struct, ValidationError, convert, to_builtins from .utils import ( emscripten_stack_limited, max_call_depth, py315_or_later_only, temp_module, ) try: import attrs except ImportError: attrs = None if sys.version_info >= (3, 15): # This is needed for `ruff` to recognize `frozendict` name # and to not raise `F821`: from builtins import frozendict PY311 = sys.version_info[:2] >= (3, 11) PY312 = sys.version_info[:2] >= (3, 12) UTC = datetime.timezone.utc T = TypeVar("T") class GetAttrObj: def __init__(self, _data=None, **kwargs): self._data = _data or {} self._data.update(kwargs) def __getattr__(self, key): try: return self._data[key] except KeyError: raise AttributeError(key) from None class GetItemObj(MutableMapping): def __init__(self, _data=None, **kwargs): self._data = _data or {} self._data.update(kwargs) def __getitem__(self, key): return self._data[key] def __setitem__(self, key, val): self._data[key] = val def __delitem__(self, key): del self._data[key] def __iter__(self): return iter(self._data) def __len__(self): return len(self._data) class GetAttrOrItemObj: def __init__(self, _data=None, **kwargs): self._attrs = _data or {} self._attrs.update(kwargs) self._items = {} if self._attrs: k, v = self._attrs.popitem() self._items[k] = v def __getitem__(self, key): return self._items[key] def __getattr__(self, key): try: return self._attrs[key] except KeyError: raise AttributeError(key) from None def KWList(**kwargs): return list(kwargs.values()) class SubList(list): pass class SubTuple(tuple): pass class SubSet(set): pass class SubFrozenSet(frozenset): pass class SubDict(dict): pass mapcls_and_from_attributes = pytest.mark.parametrize( "mapcls, from_attributes", [ (dict, False), (SubDict, False), (GetAttrObj, True), (GetAttrOrItemObj, True), (GetItemObj, False), ], ) mapcls_from_attributes_and_array_like = pytest.mark.parametrize( "mapcls, from_attributes, array_like", [ (dict, False, False), (SubDict, False, False), (KWList, False, True), (GetAttrObj, True, True), (GetAttrObj, True, False), (GetAttrOrItemObj, True, True), (GetAttrOrItemObj, True, False), (GetAttrOrItemObj, False, False), (GetItemObj, False, False), ], ) seq_in_type = pytest.mark.parametrize( "in_type", [ list, tuple, set, frozenset, SubList, SubTuple, SubSet, SubFrozenSet, ], ) @pytest.fixture(params=["dict", "subclass", "mapping"]) def dictcls(request): if request.param == "dict": return dict elif request.param == "subclass": return SubDict else: return GetItemObj @pytest.fixture(params=["frozendict", "subclass", "mapping"]) def frozendictcls(request): assert sys.version_info >= (3, 15), "Do not use frozendictcls on <3.15" if request.param == "frozendict": return frozendict elif request.param == "subclass": class SubFrozenDict(frozendict): ... return SubFrozenDict else: return GetItemObj def assert_eq(x, y): assert type(x) is type(y) if type(x) is float and math.isnan(x): return math.isnan(y) assert x == y def roundtrip(obj, typ): return convert(to_builtins(obj), typ) class TestConvert: def test_bad_calls(self): with pytest.raises(TypeError): convert() with pytest.raises(TypeError): convert(1) with pytest.raises( TypeError, match="builtin_types must be an iterable of types" ): convert(1, int, builtin_types=1) with pytest.raises(TypeError) as rec: convert(1, int, builtin_types=(int,)) assert "Cannot treat" in str(rec.value) assert "int" in str(rec.value) with pytest.raises(TypeError, match="dec_hook must be callable"): convert(1, int, dec_hook=1) def test_dec_hook_explicit_none(self): assert convert(1, int, dec_hook=None) == 1 def test_custom_input_type(self): class Custom: pass with pytest.raises(ValidationError, match="Expected `int`, got `Custom`"): convert(Custom(), int) def test_custom_input_type_works_with_any(self): class Custom: pass x = Custom() res = convert(x, Any) assert res is x assert sys.getrefcount(x) <= 3 # x + res + 1 def test_custom_input_type_works_with_custom(self): class Custom: pass x = Custom() res = convert(x, Custom) assert res is x assert sys.getrefcount(x) <= 3 # x + res + 1 def test_custom_input_type_works_with_dec_hook(self): class Custom: pass class Custom2: pass def dec_hook(typ, x): if typ is Custom2: assert isinstance(x, Custom) return Custom2() raise TypeError x = Custom() res = convert(x, Custom2, dec_hook=dec_hook) assert isinstance(res, Custom2) assert sys.getrefcount(res) <= 2 # res + 1 assert sys.getrefcount(x) <= 2 # x + 1 def test_unsupported_output_type(self): with pytest.raises(TypeError, match="more than one array-like"): convert({}, list[int] | tuple[str, ...]) @pytest.mark.parametrize( "val, got", [ (None, "null"), (True, "bool"), (1, "int"), (1.5, "float"), ("a", "str"), (b"b", "bytes"), (bytearray(b"c"), "bytes"), (datetime.datetime(2022, 1, 2), "datetime"), (datetime.time(12, 34), "time"), (datetime.date(2022, 1, 2), "date"), (uuid.uuid4(), "uuid"), (decimal.Decimal("1.5"), "decimal"), ([1], "array"), ((1,), "array"), ({"a": 1}, "object"), ], ) def test_wrong_type(self, val, got): # An arbitrary wrong type, if isinstance(val, int): typ = str expected = "str" else: typ = int expected = "int" msg = f"Expected `{expected}`, got `{got}`" with pytest.raises(ValidationError, match=msg): convert(val, typ) class TestAny: @pytest.mark.parametrize("msg", [(1, 2), {"a": 1}, object(), {1, 2}]) def test_any_passthrough(self, msg): assert convert(msg, Any) is msg class TestNone: def test_none(self): assert convert(None, Any) is None assert convert(None, None) is None with pytest.raises(ValidationError, match="Expected `null`, got `int`"): convert(1, None) class TestBool: @pytest.mark.parametrize("val", [True, False]) def test_bool(self, val): assert convert(val, Any) is val assert convert(val, bool) is val def test_bool_invalid(self): with pytest.raises(ValidationError, match="Expected `bool`, got `int`"): convert(1, bool) with pytest.raises(ValidationError, match="Expected `bool`, got `str`"): convert("true", bool) class TestInt: def test_int(self): assert convert(1, Any) == 1 assert convert(1, int) == 1 with pytest.raises(ValidationError, match="Expected `int`, got `float`"): convert(1.5, int) @pytest.mark.parametrize("val", [2**64, -(2**63) - 1]) def test_convert_big_ints(self, val): class myint(int): pass assert_eq(convert(val, int), val) assert_eq(convert(myint(val), int), val) @pytest.mark.parametrize( "name, bound, good, bad", [ ("ge", -1, [-1, 2**63, 2**65], [-(2**64), -2]), ("gt", -1, [0, 2**63, 2**65], [-(2**64), -1]), ("le", -1, [-(2**64), -1], [0, 2**63, 2**65]), ("lt", -1, [-(2**64), -2], [-1, 2**63, 2**65]), ], ) def test_int_constr_bounds(self, name, bound, good, bad): class Ex(Struct): x: Annotated[int, Meta(**{name: bound})] for x in good: assert convert({"x": x}, Ex).x == x op = ">=" if name.startswith("g") else "<=" offset = {"lt": -1, "gt": 1}.get(name, 0) err_msg = rf"Expected `int` {op} {bound + offset} - at `\$.x`" for x in bad: with pytest.raises(ValidationError, match=err_msg): convert({"x": x}, Ex) def test_int_constr_multiple_of(self): class Ex(Struct): x: Annotated[int, Meta(multiple_of=2)] for x in [-(2**64), -2, 0, 2, 40, 2**63 + 2, 2**65]: assert convert({"x": x}, Ex).x == x err_msg = r"Expected `int` that's a multiple of 2 - at `\$.x`" for x in [1, -(2**64) + 1, -1, 2**63 + 1, 2**65 + 1]: with pytest.raises(ValidationError, match=err_msg): convert({"x": x}, Ex) @pytest.mark.parametrize( "meta, good, bad", [ (Meta(ge=0, le=10, multiple_of=2), [0, 2, 10], [-1, 1, 11]), (Meta(ge=0, multiple_of=2), [0, 2**63 + 2], [-2, 2**63 + 1]), (Meta(le=0, multiple_of=2), [0, -(2**63)], [-1, 2, 2**63]), (Meta(ge=0, le=10), [0, 10], [-1, 11]), ], ) def test_int_constrs(self, meta, good, bad): class Ex(Struct): x: Annotated[int, meta] for x in good: assert convert({"x": x}, Ex).x == x for x in bad: with pytest.raises(ValidationError): convert({"x": x}, Ex) def test_int_subclass(self): class MyInt(int): pass for val in [10, 0, -10]: sol = convert(MyInt(val), int) assert type(sol) is int assert sol == val x = MyInt(100) sol = convert(x, MyInt) assert sol is x assert sys.getrefcount(x) <= 3 # x + sol + 1 class TestFloat: def test_float(self): assert convert(1.5, Any) == 1.5 assert convert(1.5, float) == 1.5 res = convert(1, float) assert res == 1.0 assert isinstance(res, float) with pytest.raises(ValidationError, match="Expected `float`, got `null`"): convert(None, float) @pytest.mark.parametrize("strict", [True, False]) def test_float_from_int_out_of_range(self, strict): # A python int too large to represent as a C double must raise a # ValidationError, matching json.decode, rather than leaking the # OverflowError PyLong_AsDouble sets as a SystemError. big = 10**400 with pytest.raises(ValidationError, match="Number out of range"): convert(big, float, strict=strict) with pytest.raises(ValidationError, match="Number out of range"): convert({"x": big}, dict[str, float], strict=strict) @pytest.mark.parametrize( "meta, good, bad", [ (Meta(ge=0.0, le=10.0, multiple_of=2.0), [0, 2.0, 10], [-2, 11, 3]), (Meta(ge=0.0, multiple_of=2.0), [0, 2, 10.0], [-2, 3]), (Meta(le=10.0, multiple_of=2.0), [-2.0, 10.0], [11.0, 3.0]), (Meta(ge=0.0, le=10.0), [0.0, 2.0, 10.0], [-1.0, 11.5, 11]), ], ) def test_float_constrs(self, meta, good, bad): class Ex(Struct): x: Annotated[float, meta] for x in good: assert convert({"x": x}, Ex).x == x for x in bad: with pytest.raises(ValidationError): convert({"x": x}, Ex) def test_float_from_decimal(self): res = convert(decimal.Decimal("1.5"), float) assert res == 1.5 assert type(res) is float def test_constr_float_from_decimal(self): typ = Annotated[float, Meta(ge=0)] res = convert(decimal.Decimal("1.5"), typ) assert res == 1.5 assert type(res) is float with pytest.raises(ValidationError, match="Expected `float` >= 0.0"): convert(decimal.Decimal("-1.5"), typ) class TestStr: def test_str(self): assert convert("test", Any) == "test" assert convert("test", str) == "test" with pytest.raises(ValidationError, match="Expected `str`, got `bytes`"): convert(b"test", str) @pytest.mark.parametrize( "meta, good, bad", [ ( Meta(min_length=2, max_length=3, pattern="x"), ["xy", "xyz"], ["x", "yy", "wxyz"], ), (Meta(min_length=2, max_length=4), ["xx", "xxxx"], ["x", "xxxxx"]), (Meta(min_length=2, pattern="x"), ["xy", "wxyz"], ["x", "bad"]), (Meta(max_length=3, pattern="x"), ["xy", "xyz"], ["y", "wxyz"]), ], ) def test_str_constrs(self, meta, good, bad): class Ex(Struct): x: Annotated[str, meta] for x in good: assert convert({"x": x}, Ex).x == x for x in bad: with pytest.raises(ValidationError): convert({"x": x}, Ex) class TestBinary: @pytest.mark.parametrize("out_type", [bytes, bytearray, memoryview]) def test_binary_wrong_type(self, out_type): with pytest.raises(ValidationError, match="Expected `bytes`, got `int`"): convert(1, out_type) @pytest.mark.parametrize("in_type", [bytes, bytearray, memoryview]) @pytest.mark.parametrize("out_type", [bytes, bytearray, memoryview]) def test_binary_builtin(self, in_type, out_type): res = convert(in_type(b"test"), out_type) assert res == b"test" assert isinstance(res, out_type) @pytest.mark.parametrize("out_type", [bytes, bytearray, memoryview]) def test_binary_base64(self, out_type): res = convert("AQI=", out_type) assert res == b"\x01\x02" assert isinstance(res, out_type) @pytest.mark.parametrize("out_type", [bytes, bytearray, memoryview]) def test_binary_base64_disabled(self, out_type): with pytest.raises(ValidationError, match="Expected `bytes`, got `str`"): convert("AQI=", out_type, builtin_types=(bytes, bytearray, memoryview)) @pytest.mark.parametrize("in_type", [bytes, bytearray, memoryview, str]) @pytest.mark.parametrize("out_type", [bytes, bytearray, memoryview]) def test_binary_constraints(self, in_type, out_type): class Ex(Struct): x: Annotated[out_type, Meta(min_length=2, max_length=4)] for x in [b"xx", b"xxx", b"xxxx"]: if in_type is str: msg = {"x": b64encode(x).decode("utf-8")} else: msg = {"x": in_type(x)} assert convert(msg, Ex).x == x for x in [b"x", b"xxxxx"]: if in_type is str: msg = {"x": b64encode(x).decode("utf-8")} else: msg = {"x": in_type(x)} with pytest.raises(ValidationError): convert(msg, Ex) def test_bytes_subclass(self): class MyBytes(bytes): pass msg = MyBytes(b"abc") for typ in [bytes, bytearray, memoryview]: sol = convert(msg, typ) assert type(sol) is typ assert sol == b"abc" del sol assert sys.getrefcount(msg) <= 2 # msg + 1 sol = convert(msg, MyBytes) assert sol is msg assert sys.getrefcount(msg) <= 3 # msg + sol + 1 class TestDateTime: def test_datetime_wrong_type(self): with pytest.raises(ValidationError, match="Expected `datetime`, got `int`"): convert(1, datetime.datetime) @pytest.mark.parametrize("tz", [False, True]) def test_datetime_builtin(self, tz): dt = datetime.datetime.now(UTC if tz else None) assert convert(dt, datetime.datetime) is dt @pytest.mark.parametrize("tz", [False, True]) def test_datetime_str(self, tz): sol = datetime.datetime(1, 2, 3, 4, 5, 6, 7, UTC if tz else None) msg = "0001-02-03T04:05:06.000007" + ("Z" if tz else "") res = convert(msg, datetime.datetime) assert res == sol def test_datetime_str_disabled(self): with pytest.raises(ValidationError, match="Expected `datetime`, got `str`"): convert( "0001-02-03T04:05:06.000007Z", datetime.datetime, builtin_types=(datetime.datetime,), ) @pytest.mark.parametrize("as_str", [False, True]) def test_datetime_constrs(self, as_str): class Ex(Struct): x: Annotated[datetime.datetime, Meta(tz=True)] builtin_types = None if as_str else (datetime.datetime,) aware = Ex(datetime.datetime(1, 2, 3, 4, 5, 6, 7, UTC)) aware_msg = to_builtins(aware, builtin_types=builtin_types) naive = Ex(datetime.datetime(1, 2, 3, 4, 5, 6, 7)) naive_msg = to_builtins(naive, builtin_types=builtin_types) assert convert(aware_msg, Ex) == aware with pytest.raises(ValidationError): convert(naive_msg, Ex) class TestTime: def test_time_wrong_type(self): with pytest.raises(ValidationError, match="Expected `time`, got `int`"): convert(1, datetime.time) @pytest.mark.parametrize("tz", [False, True]) def test_time_builtin(self, tz): t = datetime.time(12, 34, tzinfo=(UTC if tz else None)) assert convert(t, datetime.time) is t @pytest.mark.parametrize("tz", [False, True]) def test_time_str(self, tz): sol = datetime.time(12, 34, tzinfo=(UTC if tz else None)) msg = "12:34:00" + ("Z" if tz else "") res = convert(msg, datetime.time) assert res == sol def test_time_str_disabled(self): with pytest.raises(ValidationError, match="Expected `time`, got `str`"): convert("12:34:00Z", datetime.time, builtin_types=(datetime.time,)) @pytest.mark.parametrize("as_str", [False, True]) def test_time_constrs(self, as_str): class Ex(Struct): x: Annotated[datetime.time, Meta(tz=True)] builtin_types = None if as_str else (datetime.time,) aware = Ex(datetime.time(12, 34, tzinfo=UTC)) aware_msg = to_builtins(aware, builtin_types=builtin_types) naive = Ex(datetime.time(12, 34)) naive_msg = to_builtins(naive, builtin_types=builtin_types) assert convert(aware_msg, Ex) == aware with pytest.raises(ValidationError): convert(naive_msg, Ex) class TestDate: def test_date_wrong_type(self): with pytest.raises(ValidationError, match="Expected `date`, got `int`"): convert(1, datetime.date) def test_date_builtin(self): dt = datetime.date.today() assert convert(dt, datetime.date) is dt def test_date_str(self): sol = datetime.date.today() res = convert(sol.isoformat(), datetime.date) assert res == sol def test_date_str_disabled(self): with pytest.raises(ValidationError, match="Expected `date`, got `str`"): convert("2022-01-02", datetime.date, builtin_types=(datetime.date,)) class TestTimeDelta: def test_timedelta_wrong_type(self): with pytest.raises(ValidationError, match="Expected `duration`, got `array`"): convert([], datetime.timedelta) def test_timedelta_builtin(self): td = datetime.timedelta(1) assert convert(td, datetime.timedelta) is td def test_timedelta_str(self): sol = datetime.timedelta(1, 2) res = convert("P1DT2S", datetime.timedelta) assert res == sol def test_timedelta_str_disabled(self): with pytest.raises(ValidationError, match="Expected `duration`, got `str`"): convert("P1DT2S", datetime.timedelta, builtin_types=(datetime.timedelta,)) class TestUUID: def test_uuid_wrong_type(self): with pytest.raises(ValidationError, match="Expected `uuid`, got `int`"): convert(1, uuid.UUID) def test_uuid_builtin(self): x = uuid.uuid4() assert convert(x, uuid.UUID) is x def test_uuid_str(self): sol = uuid.uuid4() res = convert(str(sol), uuid.UUID) assert res == sol @pytest.mark.parametrize("input_type", [bytes, bytearray, memoryview]) def test_uuid_bytes(self, input_type): sol = uuid.uuid4() msg = input_type(sol.bytes) res = convert(msg, uuid.UUID) assert res == sol bad_msg = input_type(b"x" * 8) with pytest.raises(msgspec.ValidationError, match="Invalid UUID bytes"): convert(bad_msg, type=uuid.UUID) def test_uuid_disabled(self): u = uuid.uuid4() with pytest.raises(ValidationError, match="Expected `uuid`, got `str`"): convert(str(u), uuid.UUID, builtin_types=(uuid.UUID,)) for typ in [bytes, bytearray]: with pytest.raises(ValidationError, match="Expected `uuid`, got `bytes`"): convert(typ(u.bytes), uuid.UUID, builtin_types=(uuid.UUID,)) def test_convert_uuid_subclass(self): class UUID2(uuid.UUID): ... u1 = uuid.uuid4() u2 = UUID2(str(u1)) assert convert(u2, uuid.UUID) is u2 class TestDecimal: def test_decimal_wrong_type(self): with pytest.raises(ValidationError, match="Expected `decimal`, got `array`"): convert([], decimal.Decimal) def test_decimal_builtin(self): x = decimal.Decimal("1.5") assert convert(x, decimal.Decimal) is x def test_decimal_str(self): sol = decimal.Decimal("1.5") res = convert("1.5", decimal.Decimal) assert res == sol assert type(res) is decimal.Decimal @pytest.mark.parametrize("val", [1.3, float("nan"), float("inf"), float("-inf")]) def test_decimal_float(self, val): sol = decimal.Decimal(str(val)) res = convert(val, decimal.Decimal) assert str(res) == str(sol) # compare strs to support NaN assert type(res) is decimal.Decimal @pytest.mark.parametrize("val", [0, 1234, -1234]) def test_decimal_int(self, val): sol = decimal.Decimal(val) res = convert(val, decimal.Decimal) assert res == sol assert type(res) is decimal.Decimal @pytest.mark.parametrize("val, typ", [("1.5", "str"), (123, "int"), (1.3, "float")]) def test_decimal_conversion_disabled(self, val, typ): with pytest.raises(ValidationError, match=f"Expected `decimal`, got `{typ}`"): convert(val, decimal.Decimal, builtin_types=(decimal.Decimal,)) class TestExt: def test_ext(self): x = msgspec.msgpack.Ext(1, b"123") assert convert(x, msgspec.msgpack.Ext) is x def test_ext_errors(self): with pytest.raises(ValidationError, match="Expected `ext`, got `int`"): convert(1, msgspec.msgpack.Ext) with pytest.raises(ValidationError, match="Expected `int`, got `ext`"): convert(msgspec.msgpack.Ext(1, b"123"), int) class TestEnum: def test_enum(self): class Ex(enum.Enum): x = "A" y = "B" class Ex2(enum.Enum): x = "A" assert convert(Ex.x, Ex) is Ex.x assert convert("A", Ex) is Ex.x assert convert("B", Ex) is Ex.y with pytest.raises(ValidationError, match="Invalid enum value 'C'"): convert("C", Ex) with pytest.raises(ValidationError, match="Expected `str`, got `int`"): convert(1, Ex) with pytest.raises(ValidationError, match="got `Ex2`"): convert(Ex2.x, Ex) def test_int_enum(self): class Ex(enum.IntEnum): x = 1 y = 2 class Ex2(enum.IntEnum): a = 1 b = 3 assert convert(Ex.x, Ex) is Ex.x assert convert(1, Ex) is Ex.x assert convert(2, Ex) is Ex.y assert convert(Ex2.a, Ex) is Ex.x with pytest.raises(ValidationError, match="Invalid enum value 3"): convert(3, Ex) with pytest.raises(ValidationError, match="Invalid enum value 3"): convert(Ex2.b, Ex) with pytest.raises(ValidationError, match="Expected `int`, got `str`"): convert("A", Ex) def test_str_enum(self): if not hasattr(enum, "StrEnum"): pytest.skip(reason="StrEnum not available") class Ex(enum.StrEnum): x = "A" y = "B" class Ex2(enum.StrEnum): a = "A" b = "C" assert convert(Ex.x, Ex) is Ex.x assert convert("A", Ex) is Ex.x assert convert("B", Ex) is Ex.y assert convert(Ex2.a, Ex) is Ex.x with pytest.raises(ValidationError, match="Invalid enum value 'C'"): convert("C", Ex) with pytest.raises(ValidationError, match="Invalid enum value 'C'"): convert(Ex2.b, Ex) with pytest.raises(ValidationError, match="Expected `str`, got `int`"): convert(3, Ex) def test_int_enum_int_subclass(self): class MyInt(int): pass class Ex(enum.IntEnum): x = 1 y = 2 msg = MyInt(1) assert convert(msg, Ex) is Ex.x assert sys.getrefcount(msg) <= 2 # msg + 1 assert convert(MyInt(2), Ex) is Ex.y def test_enum_missing(self): class Ex(enum.Enum): A = "a" B = "b" @classmethod def _missing_(cls, val): if val == "return-A": return cls.A elif val == "return-B": return cls.B elif val == "error": raise ValueError("oh no!") else: return None assert msgspec.convert("a", Ex) is Ex.A assert msgspec.convert("return-A", Ex) is Ex.A assert msgspec.convert("return-B", Ex) is Ex.B with pytest.raises(ValidationError, match="Invalid enum value 'error'"): msgspec.convert("error", Ex) with pytest.raises(ValidationError, match="Invalid enum value 'other'"): msgspec.convert("other", Ex) def test_intenum_missing(self): class Ex(enum.IntEnum): A = 1 B = 2 @classmethod def _missing_(cls, val): if val == 3: return cls.A elif val == -4: return cls.B elif val == 5: raise ValueError("oh no!") else: return None assert msgspec.convert(1, Ex) is Ex.A assert msgspec.convert(3, Ex) is Ex.A assert msgspec.convert(-4, Ex) is Ex.B with pytest.raises(ValidationError, match="Invalid enum value 5"): msgspec.convert(5, Ex) with pytest.raises(ValidationError, match="Invalid enum value 6"): msgspec.convert(6, Ex) @pytest.mark.parametrize( "base_metacls", [enum.EnumMeta] + ([enum.EnumType] if PY311 else []) ) def test_enum_with_custom_metaclass(self, base_metacls): class ChoicesMeta(base_metacls): """My custom enum metaclass""" class Test(enum.Enum, metaclass=ChoicesMeta): A = "apple" B = "banana" assert convert(Test.A, Test) is Test.A assert convert("apple", Test) is Test.A assert convert("banana", Test) is Test.B with pytest.raises(ValidationError, match="Invalid enum value 'ceeee'"): convert("ceeee", Test) with pytest.raises(ValidationError, match="Expected `str`, got `int`"): convert(1, Test) class TestLiteral: def test_str_literal(self): typ = Literal["A", "B"] assert convert("A", typ) == "A" assert convert("B", typ) == "B" with pytest.raises(ValidationError, match="Invalid enum value 'C'"): convert("C", typ) with pytest.raises(ValidationError, match="Expected `str`, got `int`"): convert(1, typ) def test_int_literal(self): typ = Literal[1, -2] assert convert(1, typ) == 1 assert convert(-2, typ) == -2 with pytest.raises(ValidationError, match="Invalid enum value 3"): convert(3, typ) with pytest.raises(ValidationError, match="Invalid enum value -3"): convert(-3, typ) with pytest.raises(ValidationError, match="Expected `int`, got `str`"): convert("A", typ) def test_bool_literal(self): assert convert(True, Literal[True]) is True assert convert(False, Literal[False]) is False assert convert(True, Literal[True, False]) is True assert convert(False, Literal[True, False]) is False with pytest.raises(ValidationError, match="Invalid enum value False"): convert(False, Literal[True]) with pytest.raises(ValidationError, match="Invalid enum value True"): convert(True, Literal[False]) with pytest.raises(ValidationError, match="Expected `bool`, got `str`"): convert("yes", Literal[True]) class TestSequences: def test_any_sequence(self): msg = (1, 2, 3) assert convert(msg, Any) is msg @seq_in_type @pytest.mark.parametrize("out_type", [list, tuple, set, frozenset]) def test_empty_sequence(self, in_type, out_type): assert convert(in_type(), out_type) == out_type() @seq_in_type @pytest.mark.parametrize( "out_type_annot", [(list, list), (tuple, tuple), (set, set), (frozenset, frozenset)], ) @pytest.mark.parametrize("item_annot", [None, int]) def test_sequence(self, in_type, out_type_annot, item_annot): out_type, out_annot = out_type_annot if item_annot is not None: if out_annot is tuple: out_annot = out_annot[item_annot, ...] else: out_annot = out_annot[item_annot] res = convert(in_type([1, 2]), out_annot) sol = out_type([1, 2]) assert res == sol assert isinstance(res, out_type) @seq_in_type @pytest.mark.parametrize( "out_annot", [list[int], tuple[int, ...], set[int], frozenset[int]] ) def test_sequence_wrong_item_type(self, in_type, out_annot): with pytest.raises( ValidationError, match=r"Expected `int`, got `str` - at `\$\[0\]`" ): assert convert(in_type(["bad"]), out_annot) @pytest.mark.parametrize("out_type", [list, tuple, set, frozenset]) def test_sequence_wrong_type(self, out_type): with pytest.raises(ValidationError, match=r"Expected `array`, got `int`"): assert convert(1, out_type) @pytest.mark.parametrize("kind", ["list", "tuple", "fixtuple", "set"]) @pytest.mark.skipif( PY312, reason="CPython 3.12 internal changes prevent testing for recursion issues this way", ) def test_sequence_cyclic_recursion(self, kind): depth = 50 if kind == "list": typ = list[int] for _ in range(depth): typ = list[typ] elif kind == "tuple": typ = tuple[int, ...] for _ in range(depth): typ = tuple[typ, ...] elif kind == "fixtuple": typ = tuple[int] for _ in range(depth): typ = tuple[typ] elif kind == "set": typ = frozenset[int] for _ in range(depth): typ = frozenset[typ] class Cache(Struct): value: typ msgspec.json.Decoder(Cache) arr = [] arr.append(arr) msg = {"value": arr} with pytest.raises(RecursionError): with max_call_depth(5): convert(msg, Cache) @pytest.mark.parametrize("out_type", [list, tuple, set, frozenset]) def test_sequence_constrs(self, out_type): class Ex(Struct): x: Annotated[out_type, Meta(min_length=2, max_length=4)] for n in [2, 4]: x = out_type(range(n)) assert convert({"x": list(range(n))}, Ex).x == x for n in [1, 5]: x = out_type(range(n)) with pytest.raises(ValidationError): convert({"x": list(range(n))}, Ex) def test_fixtuple_any(self): typ = tuple[Any, Any, Any] sol = (1, "two", False) res = convert([1, "two", False], typ) assert res == sol with pytest.raises(ValidationError, match="Expected `array`, got `int`"): convert(1, typ) with pytest.raises(ValidationError, match="Expected `array`, got `set`"): convert({1, 2, 3}, typ) with pytest.raises(ValidationError, match="Expected `array` of length 3"): convert((1, "two"), typ) def test_fixtuple_typed(self): typ = tuple[int, str, bool] sol = (1, "two", False) res = convert([1, "two", False], typ) assert res == sol with pytest.raises(ValidationError, match="Expected `bool`"): convert([1, "two", "three"], typ) with pytest.raises(ValidationError, match="Expected `array`, got `set`"): convert({1, 2, 3}, typ) with pytest.raises(ValidationError, match="Expected `array` of length 3"): convert((1, "two"), typ) class TestNamedTuple: def test_namedtuple_no_defaults(self): class Example(NamedTuple): a: int b: int c: int msg = Example(1, 2, 3) res = convert([1, 2, 3], Example) assert res == msg with pytest.raises(ValidationError, match="length 3, got 1"): convert([1], Example) with pytest.raises(ValidationError, match="length 3, got 6"): convert([1, 2, 3, 4, 5, 6], Example) def test_namedtuple_with_defaults(self): class Example(NamedTuple): a: int b: int c: int = -3 d: int = -4 e: int = -5 for args in [(1, 2), (1, 2, 3), (1, 2, 3, 4), (1, 2, 3, 4, 5)]: msg = Example(*args) res = convert(args, Example) assert res == msg with pytest.raises(ValidationError, match="length 2 to 5, got 1"): convert([1], Example) with pytest.raises(ValidationError, match="length 2 to 5, got 6"): convert([1, 2, 3, 4, 5, 6], Example) def test_namedtuple_field_wrong_type(self): class Example(NamedTuple): a: int b: str with pytest.raises( ValidationError, match=r"Expected `int`, got `str` - at `\$\[0\]`" ): convert(("bad", 1), Example) def test_namedtuple_not_array(self): class Example(NamedTuple): a: int b: str with pytest.raises(ValidationError, match="Expected `array`, got `object`"): convert({"a": 1, "b": "two"}, Example) @emscripten_stack_limited def test_namedtuple_cyclic_recursion(self): source = """ from __future__ import annotations from typing import NamedTuple, Union, Dict class Ex(NamedTuple): a: int b: Ex | None """ with temp_module(source) as mod: msg = [1] msg.append(msg) with pytest.raises(RecursionError): assert convert(msg, mod.Ex) def test_namedtuple_to_namedtuple(self): class Ex1(NamedTuple): x: int class Ex2(NamedTuple): x: int class Ex3(NamedTuple): x: str msg = Ex1(1) assert convert(msg, Ex1) is msg assert convert(msg, Ex2) == Ex2(1) with pytest.raises(ValidationError, match="Expected `str`, got `int`"): convert(msg, Ex3) def test_namedtuple_hash_preserved(self): """Hash of converted NamedTuple matches hash of original. Regression test for gh-967.""" class Key(NamedTuple): value: int original = Key(value=42) converted = convert([42], Key) assert original == converted assert hash(original) == hash(converted) d = {original: "found"} assert converted in d class TestDict: def test_any_dict(self, dictcls): assert convert(dictcls({"one": 1, 2: "two"}), Any) == {"one": 1, 2: "two"} def test_empty_dict(self, dictcls): assert convert(dictcls({}), dict) == {} assert convert(dictcls({}), dict[int, int]) == {} def test_typed_dict(self, dictcls): res = convert(dictcls({"x": 1, "y": 2}), dict[str, float]) assert res == {"x": 1.0, "y": 2.0} assert all(type(v) is float for v in res.values()) with pytest.raises( ValidationError, match=r"Expected `str`, got `int` - at `\$\[\.\.\.\]`" ): convert(dictcls({"x": 1}), dict[str, str]) with pytest.raises( ValidationError, match=r"Expected `int`, got `str` - at `key` in `\$`" ): convert(dictcls({"x": 1}), dict[int, str]) def test_dict_wrong_type(self): with pytest.raises(ValidationError, match=r"Expected `object`, got `int`"): assert convert(1, dict) def test_str_formatted_keys(self): msg = {uuid.uuid4(): 1, uuid.uuid4(): 2} res = convert(to_builtins(msg), dict[uuid.UUID, int]) assert res == msg @pytest.mark.parametrize("key_type", ["int", "enum", "literal"]) def test_int_keys(self, dictcls, key_type): msg = dictcls({1: "A", 2: "B"}) if key_type == "enum": Key = enum.IntEnum("Key", ["one", "two"]) sol = {Key.one: "A", Key.two: "B"} elif key_type == "literal": Key = Literal[1, 2] sol = msg else: Key = int sol = msg res = convert(msg, dict[Key, str]) assert res == sol res = convert(msg, dict[Key, str], str_keys=True) assert res == sol str_msg = dictcls(to_builtins(dict(msg), str_keys=True)) res = convert(str_msg, dict[Key, str], str_keys=True) assert res == sol with pytest.raises( ValidationError, match=r"Expected `int`, got `str` - at `key` in `\$`" ): convert(str_msg, dict[Key, str]) def test_non_str_keys(self, dictcls): convert(dictcls({1.5: 1}), dict[float, int]) == {1.5: 1} with pytest.raises(ValidationError): convert(dictcls({"x": 1}), dict[tuple[int, int], int], str_keys=True) @pytest.mark.skipif( PY312, reason="CPython 3.12 internal changes prevent testing for recursion issues this way", ) def test_dict_cyclic_recursion(self, dictcls): depth = 50 typ = dict[str, int] for _ in range(depth): typ = dict[str, typ] class Cache(Struct): value: typ msgspec.json.Decoder(Cache) map = dictcls() map["x"] = map msg = {"value": map} with pytest.raises(RecursionError): with max_call_depth(5): convert(msg, Cache) def test_dict_constrs(self, dictcls): class Ex(Struct): x: Annotated[dict, Meta(min_length=2, max_length=4)] for n in [2, 4]: x = dictcls({str(i): i for i in range(n)}) assert convert(dictcls({"x": x}), Ex).x == x for n in [1, 5]: x = {str(i): i for i in range(n)} with pytest.raises(ValidationError): convert(dictcls({"x": x}), Ex) @py315_or_later_only class TestFrozenDict: def check_frozen(self, val, expected): assert isinstance(expected, frozendict) assert type(val) is type(expected) assert val == expected def check_non_frozen(self, val, expected): assert isinstance(expected, dict) assert type(val) is type(expected) assert val == expected def test_any_frozendict(self, frozendictcls): if frozendictcls is GetItemObj: return # `GetItemObj` will be converted to `dict` by default with `Any` self.check_frozen( convert(frozendictcls({"one": 1, 2: "two"}), Any), frozendictcls({"one": 1, 2: "two"}), ) def test_empty_frozendict(self, frozendictcls): self.check_frozen( convert(frozendictcls({}), frozendict), frozendict(), ) self.check_frozen( convert(frozendictcls({}), frozendict[str, int]), frozendict(), ) self.check_frozen( convert(frozendictcls({}), frozendict[str, int]), frozendict(), ) self.check_non_frozen(convert(frozendictcls({}), dict), {}) self.check_non_frozen(convert(frozendictcls({}), Dict[int, int]), {}) self.check_non_frozen(convert(frozendictcls({}), dict[int, int]), {}) def test_typed_frozendict(self, frozendictcls): res = convert(frozendictcls({"x": 1, "y": 2}), frozendict[str, float]) self.check_frozen(res, frozendict({"x": 1.0, "y": 2.0})) assert all(type(v) is float for v in res.values()) with pytest.raises( ValidationError, match=r"Expected `str`, got `int` - at `\$\[\.\.\.\]`" ): convert(frozendictcls({"x": 1}), frozendict[str, str]) with pytest.raises( ValidationError, match=r"Expected `int`, got `str` - at `key` in `\$`" ): convert(frozendictcls({"x": 1}), frozendict[int, str]) def test_frozendict_wrong_type(self): with pytest.raises(ValidationError, match=r"Expected `object`, got `int`"): assert convert(1, frozendict) def test_str_formatted_keys(self): msg = frozendict({uuid.uuid4(): 1, uuid.uuid4(): 2}) res = convert(to_builtins(msg), frozendict[uuid.UUID, int]) self.check_frozen(res, msg) @pytest.mark.parametrize("key_type", ["int", "enum", "literal"]) def test_int_keys(self, frozendictcls, key_type): msg = frozendictcls({1: "A", 2: "B"}) if key_type == "enum": Key = enum.IntEnum("Key", ["one", "two"]) sol = frozendict({Key.one: "A", Key.two: "B"}) elif key_type == "literal": Key = Literal[1, 2] sol = frozendict(msg) else: Key = int sol = frozendict(msg) res = convert(msg, frozendict[Key, str]) self.check_frozen(res, sol) res = convert(msg, frozendict[Key, str], str_keys=True) self.check_frozen(res, sol) str_msg = frozendictcls(to_builtins(dict(msg), str_keys=True)) res = convert(str_msg, frozendict[Key, str], str_keys=True) self.check_frozen(res, sol) with pytest.raises( ValidationError, match=r"Expected `int`, got `str` - at `key` in `\$`" ): convert(str_msg, frozendict[Key, str]) def test_non_str_keys(self, frozendictcls): self.check_frozen( convert(frozendictcls({1.5: 1}), frozendict[float, int]), frozendict({1.5: 1}), ) self.check_non_frozen( convert(frozendictcls({1.5: 1}), dict[float, int]), {1.5: 1}, ) with pytest.raises(ValidationError, match="Expected `array`, got `str`"): convert( frozendictcls({"x": 1}), frozendict[tuple[int, int], int], str_keys=True, ) # Recursion error can't happen, because `frozendict` is immutable. def test_frozendict_constrs(self, frozendictcls): class Ex(Struct): x: Annotated[frozendict, Meta(min_length=2, max_length=4)] for n in [2, 4]: x = frozendictcls({str(i): i for i in range(n)}) self.check_frozen(convert(frozendictcls({"x": x}), Ex).x, frozendict(x)) for n in [1, 5]: x = {str(i): i for i in range(n)} with pytest.raises(ValidationError): convert(frozendictcls({"x": x}), Ex) class TestTypedDict: def test_typeddict_total_true(self): class Ex(TypedDict): a: int b: str x = {"a": 1, "b": "two"} assert convert(x, Ex) == x x2 = {"a": 1, "b": "two", "c": "extra"} assert convert(x2, Ex) == x with pytest.raises(ValidationError) as rec: convert({"b": "two"}, Ex) assert "Object missing required field `a`" == str(rec.value) with pytest.raises(ValidationError) as rec: convert({"a": 1, "b": 2}, Ex) assert "Expected `str`, got `int` - at `$.b`" == str(rec.value) with pytest.raises(ValidationError) as rec: convert({"a": 1, 1: 2}, Ex) assert "Expected `str` - at `key` in `$`" == str(rec.value) def test_typeddict_total_false(self): class Ex(TypedDict, total=False): a: int b: str x = {"a": 1, "b": "two"} assert convert(x, Ex) == x x2 = {"a": 1, "b": "two", "c": "extra"} assert convert(x2, Ex) == x x3 = {"b": "two"} assert convert(x3, Ex) == x3 x4 = {} assert convert(x4, Ex) == x4 def test_typeddict_total_partially_optional(self): class Base(TypedDict): a: int b: str class Ex(Base, total=False): c: str x = {"a": 1, "b": "two", "c": "extra"} assert convert(x, Ex) == x x2 = {"a": 1, "b": "two"} assert convert(x2, Ex) == x2 with pytest.raises(ValidationError) as rec: convert({"b": "two"}, Ex) assert "Object missing required field `a`" == str(rec.value) class TestDataclass: @pytest.mark.parametrize("slots", [False, True]) @mapcls_and_from_attributes def test_dataclass(self, slots, mapcls, from_attributes): if slots: kws = {"slots": True} else: kws = {} @dataclass(**kws) class Example: a: int b: int c: int sol = Example(1, 2, 3) msg = mapcls(a=1, b=2, c=3) res = convert(msg, Example, from_attributes=from_attributes) assert res == sol # Extra fields ignored res = convert( mapcls({"x": -1, "a": 1, "y": -2, "b": 2, "z": -3, "c": 3, "": -4}), Example, from_attributes=from_attributes, ) assert res == sol # Missing fields error with pytest.raises(ValidationError, match="missing required field `b`"): convert(mapcls(a=1), Example, from_attributes=from_attributes) # Incorrect field types error with pytest.raises( ValidationError, match=r"Expected `int`, got `str` - at `\$.a`" ): convert(mapcls(a="bad"), Example, from_attributes=from_attributes) def test_dict_to_dataclass_errors(self): @dataclass class Example: a: int with pytest.raises(ValidationError, match=r"Expected `str` - at `key` in `\$`"): convert({"a": 1, 1: 2}, Example) def test_from_attributes_option_disables_attribute_coercion(self): class Bad: def __init__(self): self.x = 1 msg = Bad() @dataclass class Ex: x: int with pytest.raises(ValidationError, match="Expected `object`, got `Bad`"): convert(msg, Ex) assert convert(msg, Ex, from_attributes=True) == Ex(1) @pytest.mark.parametrize("frozen", [False, True]) @pytest.mark.parametrize("slots", [False, True]) @mapcls_and_from_attributes def test_dataclass_defaults(self, frozen, slots, mapcls, from_attributes): if slots: kws = {"slots": True} else: kws = {} @dataclass(frozen=frozen, **kws) class Example: a: int b: int c: int = -3 d: int = -4 e: int = field(default_factory=lambda: -1000) for args in [(1, 2), (1, 2, 3), (1, 2, 3, 4), (1, 2, 3, 4, 5)]: sol = Example(*args) msg = mapcls(dict(zip("abcde", args))) res = convert(msg, Example, from_attributes=from_attributes) assert res == sol # Missing fields error with pytest.raises(ValidationError, match="missing required field `a`"): convert(mapcls(c=1, d=2, e=3), Example, from_attributes=from_attributes) @mapcls_and_from_attributes def test_dataclass_default_factory_errors(self, mapcls, from_attributes): def bad(): raise ValueError("Oh no!") @dataclass class Example: a: int = field(default_factory=bad) msg = mapcls() with pytest.raises(ValueError, match="Oh no!"): convert(msg, Example, from_attributes=from_attributes) @mapcls_and_from_attributes def test_dataclass_post_init(self, mapcls, from_attributes): called = False @dataclass class Example: a: int def __post_init__(self): nonlocal called called = True msg = mapcls(a=1) res = convert(msg, Example, from_attributes=from_attributes) assert res.a == 1 assert called @mapcls_and_from_attributes def test_dataclass_post_init_errors(self, mapcls, from_attributes): @dataclass class Example: a: int def __post_init__(self): raise ValueError("Oh no!") msg = mapcls(a=1) with pytest.raises(ValidationError, match="Oh no!"): convert(msg, Example, from_attributes=from_attributes) @mapcls_and_from_attributes def test_dataclass_not_object(self, mapcls, from_attributes): @dataclass class Example: a: int b: int with pytest.raises(ValidationError, match="Expected `object`, got `array`"): convert([], Example, from_attributes=from_attributes) def test_dataclass_to_dataclass(self): @dataclass class Ex1: x: int @dataclass class Ex2: x: int msg = Ex1(1) assert convert(msg, Ex1) is msg with pytest.raises(ValidationError, match="got `Ex1`"): convert(msg, Ex2) assert convert(msg, Ex2, from_attributes=True) == Ex2(1) def test_struct_to_dataclass(self): @dataclass class Ex1: x: int class Ex2(Struct): x: int assert convert(Ex1(1), Ex2, from_attributes=True) == Ex2(1) @pytest.mark.skipif(attrs is None, reason="attrs is not installed") class TestAttrs: @pytest.mark.parametrize("slots", [False, True]) @mapcls_and_from_attributes def test_attrs(self, slots, mapcls, from_attributes): @attrs.define(slots=slots) class Example: a: int b: int c: int sol = Example(1, 2, 3) msg = mapcls(a=1, b=2, c=3) res = convert(msg, Example, from_attributes=from_attributes) assert res == sol # Extra fields ignored res = convert( mapcls({"x": -1, "a": 1, "y": -2, "b": 2, "z": -3, "c": 3, "": -4}), Example, from_attributes=from_attributes, ) assert res == sol # Missing fields error with pytest.raises(ValidationError, match="missing required field `b`"): convert(mapcls(a=1), Example, from_attributes=from_attributes) # Incorrect field types error with pytest.raises( ValidationError, match=r"Expected `int`, got `str` - at `\$.a`" ): convert({"a": "bad"}, Example, from_attributes=from_attributes) def test_dict_to_attrs_errors(self): @attrs.define class Example: a: int with pytest.raises(ValidationError, match=r"Expected `str` - at `key` in `\$`"): convert({"a": 1, 1: 2}, Example) def test_from_attributes_option_disables_attribute_coercion(self): class Bad: def __init__(self): self.x = 1 msg = Bad() @attrs.define class Ex: x: int with pytest.raises(ValidationError, match="Expected `object`, got `Bad`"): convert(msg, Ex) assert convert(msg, Ex, from_attributes=True) == Ex(1) @pytest.mark.parametrize("frozen", [False, True]) @pytest.mark.parametrize("slots", [False, True]) @mapcls_and_from_attributes def test_attrs_defaults(self, frozen, slots, mapcls, from_attributes): @attrs.define(frozen=frozen, slots=slots) class Example: a: int b: int c: int = -3 d: int = -4 e: int = attrs.field(factory=lambda: -1000) for args in [(1, 2), (1, 2, 3), (1, 2, 3, 4), (1, 2, 3, 4, 5)]: sol = Example(*args) msg = mapcls(dict(zip("abcde", args))) res = convert(msg, Example, from_attributes=from_attributes) assert res == sol # Missing fields error with pytest.raises(ValidationError, match="missing required field `a`"): convert(mapcls(c=1, d=2, e=3), Example, from_attributes=from_attributes) @mapcls_and_from_attributes def test_attrs_frozen(self, mapcls, from_attributes): @attrs.define(frozen=True) class Example: x: int y: int sol = Example(1, 2) msg = mapcls(x=1, y=2) res = convert(msg, Example, from_attributes=from_attributes) assert res == sol @mapcls_and_from_attributes def test_attrs_pre_init(self, mapcls, from_attributes): called = False @attrs.define class Example: a: int def __attrs_pre_init__(self): nonlocal called called = True res = convert(mapcls(a=1), Example, from_attributes=from_attributes) assert res.a == 1 assert called @mapcls_and_from_attributes def test_attrs_pre_init_errors(self, mapcls, from_attributes): @attrs.define class Example: a: int def __attrs_pre_init__(self): raise ValueError("Oh no!") with pytest.raises(ValueError, match="Oh no!"): convert(mapcls(a=1), Example, from_attributes=from_attributes) @mapcls_and_from_attributes def test_attrs_post_init(self, mapcls, from_attributes): called = False @attrs.define class Example: a: int def __attrs_post_init__(self): nonlocal called called = True res = convert(mapcls(a=1), Example, from_attributes=from_attributes) assert res.a == 1 assert called @mapcls_and_from_attributes def test_attrs_post_init_errors(self, mapcls, from_attributes): @attrs.define class Example: a: int def __attrs_post_init__(self): raise ValueError("Oh no!") with pytest.raises(ValidationError, match="Oh no!"): convert(mapcls(a=1), Example, from_attributes=from_attributes) def test_attrs_to_attrs(self): @attrs.define class Ex1: x: int @attrs.define class Ex2: x: int msg = Ex1(1) assert convert(msg, Ex1) is msg with pytest.raises(ValidationError, match="got `Ex1`"): convert(msg, Ex2) assert convert(msg, Ex2, from_attributes=True) == Ex2(1) def test_struct_to_attrs(self): @attrs.define class Ex1: x: int class Ex2(Struct): x: int assert convert(Ex1(1), Ex2, from_attributes=True) == Ex2(1) class TestStruct: class Account(Struct, kw_only=True): first: str last: str verified: bool = False age: int @mapcls_and_from_attributes def test_struct(self, mapcls, from_attributes): msg = mapcls(first="alice", last="munro", age=91, verified=True) sol = self.Account(first="alice", last="munro", verified=True, age=91) res = convert(msg, self.Account, from_attributes=from_attributes) assert res == sol with pytest.raises(ValidationError, match="Expected `object`, got `array`"): convert([], self.Account, from_attributes=from_attributes) with pytest.raises( ValidationError, match=r"Expected `str`, got `int` - at `\$.last`" ): convert( mapcls(first="alice", last=1), self.Account, from_attributes=from_attributes, ) with pytest.raises( ValidationError, match="Object missing required field `age`" ): convert( mapcls(first="alice", last="munro"), self.Account, from_attributes=from_attributes, ) def test_dict_to_struct_errors(self): with pytest.raises(ValidationError, match=r"Expected `str` - at `key` in `\$`"): convert({"age": 1, 1: 2}, self.Account) def test_from_attributes_option_disables_attribute_coercion(self): class Bad: def __init__(self): self.x = 1 msg = Bad() class Ex(Struct): x: int with pytest.raises(ValidationError, match="Expected `object`, got `Bad`"): convert(msg, Ex) assert convert(msg, Ex, from_attributes=True) == Ex(1) @pytest.mark.parametrize("mapcls", [GetAttrObj, GetItemObj]) def test_object_to_struct_with_renamed_fields(self, mapcls): class Ex(Struct, rename="camel"): fa: int f_b: int fc: int f_d: int sol = Ex(1, 2, 3, 4) # Use attribute names msg = mapcls(fa=1, f_b=2, fc=3, f_d=4) assert convert(msg, Ex, from_attributes=True) == sol # Use renamed names msg = mapcls(fa=1, fB=2, fc=3, fD=4) assert convert(msg, Ex, from_attributes=True) == sol # Priority to attribute names msg = mapcls(fa=1, f_b=2, fB=100, fc=3, f_d=4, fD=100) assert convert(msg, Ex, from_attributes=True) == sol # Don't allow renamed names if determined to be attributes msg = mapcls(fa=1, f_b=2, fc=3, fD=4) with pytest.raises(ValidationError, match="missing required field `f_d`"): convert(msg, Ex, from_attributes=True) # Don't allow attributes if determined to be renamed names msg = mapcls(fa=1, fB=2, fc=3, f_d=4) with pytest.raises(ValidationError, match="missing required field `fD`"): convert(msg, Ex, from_attributes=True) # Errors use attribute name if using attributes msg = mapcls(fa=1, f_b=2, fc=3, f_d="bad") with pytest.raises( ValidationError, match=r"Expected `int`, got `str` - at `\$.f_d`" ): convert(msg, Ex, from_attributes=True) # Errors use renamed name if using renamed names msg = mapcls(fa=1, fB=2, fc=3, fD="bad") with pytest.raises( ValidationError, match=r"Expected `int`, got `str` - at `\$.fD`" ): convert(msg, Ex, from_attributes=True) # Errors use attribute name if undecided msg = mapcls(fa="bad") with pytest.raises( ValidationError, match=r"Expected `int`, got `str` - at `\$.fa`" ): convert(msg, Ex, from_attributes=True) @pytest.mark.parametrize("forbid_unknown_fields", [False, True]) @mapcls_and_from_attributes def test_struct_extra_fields(self, forbid_unknown_fields, mapcls, from_attributes): class Ex(Struct, forbid_unknown_fields=forbid_unknown_fields): a: int b: int msg = mapcls(x=1, a=2, y=3, b=4, z=5) if forbid_unknown_fields and issubclass(mapcls, dict): with pytest.raises(ValidationError, match="unknown field `x`"): convert(msg, Ex, from_attributes=from_attributes) else: res = convert(msg, Ex, from_attributes=from_attributes) assert res == Ex(2, 4) @mapcls_and_from_attributes def test_struct_defaults_missing_fields(self, mapcls, from_attributes): msg = mapcls(first="alice", last="munro", age=91) res = convert(msg, self.Account, from_attributes=from_attributes) assert res == self.Account(first="alice", last="munro", age=91) @mapcls_from_attributes_and_array_like def test_struct_gc_maybe_untracked_on_decode( self, mapcls, from_attributes, array_like ): class Test(Struct, array_like=array_like): x: Any y: Any z: tuple = () ts = [ mapcls(x=1, y=2), mapcls(x=3, y="hello"), mapcls(x=[], y=[]), mapcls(x={}, y={}), mapcls(x=None, y=None, z=()), ] a, b, c, d, e = convert(ts, list[Test], from_attributes=from_attributes) assert not gc.is_tracked(a) assert not gc.is_tracked(b) assert gc.is_tracked(c) assert gc.is_tracked(d) assert not gc.is_tracked(e) @mapcls_from_attributes_and_array_like def test_struct_gc_false_always_untracked_on_decode( self, mapcls, from_attributes, array_like ): class Test(Struct, array_like=array_like, gc=False): x: Any y: Any ts = [ mapcls(x=1, y=2), mapcls(x=[], y=[]), mapcls(x={}, y={}), ] for obj in convert(ts, list[Test], from_attributes=from_attributes): assert not gc.is_tracked(obj) @pytest.mark.parametrize("tag", ["Test", 123, -123]) @mapcls_and_from_attributes def test_tagged_struct(self, tag, mapcls, from_attributes): class Test(Struct, tag=tag): a: int b: int # Test with and without tag for msg in [ mapcls(a=1, b=2), mapcls(type=tag, a=1, b=2), mapcls(a=1, type=tag, b=2), ]: res = convert(msg, Test, from_attributes=from_attributes) assert res == Test(1, 2) # Tag incorrect type with pytest.raises(ValidationError) as rec: convert(mapcls(type=123.456), Test, from_attributes=from_attributes) assert f"Expected `{type(tag).__name__}`" in str(rec.value) assert "`$.type`" in str(rec.value) # Tag incorrect value bad = -3 if isinstance(tag, int) else "bad" with pytest.raises(ValidationError) as rec: convert(mapcls(type=bad), Test, from_attributes=from_attributes) assert f"Invalid value {bad!r}" in str(rec.value) assert "`$.type`" in str(rec.value) @pytest.mark.parametrize("tag_val", [2**64 - 1, 2**64, -(2**63) - 1]) @mapcls_and_from_attributes def test_tagged_struct_int_tag_not_int64_always_invalid( self, tag_val, mapcls, from_attributes ): """Tag values that don't fit in an int64 are currently unsupported, but we still want to raise a good error message.""" class Test(Struct, tag=123): pass with pytest.raises(ValidationError) as rec: convert(mapcls(type=tag_val), Test, from_attributes=from_attributes) assert f"Invalid value {tag_val}" in str(rec.value) assert "`$.type`" in str(rec.value) @pytest.mark.parametrize("tag", ["Test", 123, -123]) @mapcls_and_from_attributes def test_tagged_empty_struct(self, tag, mapcls, from_attributes): class Test(Struct, tag=tag): pass # Tag missing res = convert(mapcls(), Test, from_attributes=from_attributes) assert res == Test() # Tag present res = convert(mapcls(type=tag), Test, from_attributes=from_attributes) assert res == Test() @pytest.mark.parametrize("array_like", [False, True]) def test_struct_to_struct(self, array_like): class Ex1(Struct, array_like=array_like): x: int class Ex2(Struct, array_like=array_like): x: int msg = Ex1(1) assert convert(msg, Ex1) is msg with pytest.raises(ValidationError, match="got `Ex1`"): convert(msg, Ex2) assert convert(msg, Ex2, from_attributes=True) == Ex2(1) @pytest.mark.parametrize("array_like", [False, True]) def test_dataclass_to_struct(self, array_like): @dataclass class Ex1: x: int class Ex2(Struct, array_like=array_like): x: int assert convert(Ex1(1), Ex2, from_attributes=True) == Ex2(1) def test_exec_and_module(self): ns = {} exec( """if True: import msgspec Int = int # global name def make_struct_type(): return msgspec.defstruct("S", [("x", Int)]) S = make_struct_type() res = msgspec.convert({"x": 1}, type=S) """, ns, ns, ) assert "__module__" not in ns assert issubclass(ns["S"], msgspec.Struct) fields = msgspec.structs.fields(ns["res"]) assert fields[0].type is int assert ns["res"].x == 1 class TestStructArray: class Account(Struct, array_like=True): first: str last: str age: int verified: bool = False def test_struct_array_like(self): msg = self.Account("alice", "munro", 91, True) res = roundtrip(msg, self.Account) assert res == msg with pytest.raises(ValidationError, match="Expected `array`, got `int`"): roundtrip(1, self.Account) # Wrong field type with pytest.raises( ValidationError, match=r"Expected `int`, got `str` - at `\$\[2\]`" ): roundtrip(("alice", "munro", "bad"), self.Account) # Missing fields with pytest.raises( ValidationError, match="Expected `array` of at least length 3, got 2", ): roundtrip(("alice", "munro"), self.Account) with pytest.raises( ValidationError, match="Expected `array` of at least length 3, got 0", ): roundtrip((), self.Account) @pytest.mark.parametrize("forbid_unknown_fields", [False, True]) def test_struct_extra_fields(self, forbid_unknown_fields): class Ex(Struct, array_like=True, forbid_unknown_fields=forbid_unknown_fields): a: int b: int msg = (1, 2, 3, 4) if forbid_unknown_fields: with pytest.raises( ValidationError, match="Expected `array` of at most length 2, got 4" ): roundtrip(msg, Ex) else: res = roundtrip(msg, Ex) assert res == Ex(1, 2) def test_struct_defaults_missing_fields(self): res = roundtrip(("alice", "munro", 91), self.Account) assert res == self.Account("alice", "munro", 91) @pytest.mark.parametrize("tag", ["Test", -123, 123]) def test_tagged_struct(self, tag): class Test(Struct, tag=tag, array_like=True): a: int b: int c: int = 0 # Decode with tag res = roundtrip((tag, 1, 2), Test) assert res == Test(1, 2) res = roundtrip((tag, 1, 2, 3), Test) assert res == Test(1, 2, 3) # Trailing fields ignored res = roundtrip((tag, 1, 2, 3, 4), Test) assert res == Test(1, 2, 3) # Missing required field errors with pytest.raises(ValidationError) as rec: roundtrip((tag, 1), Test) assert "Expected `array` of at least length 3, got 2" in str(rec.value) # Tag missing with pytest.raises(ValidationError) as rec: roundtrip((), Test) assert "Expected `array` of at least length 3, got 0" in str(rec.value) # Tag incorrect type with pytest.raises(ValidationError) as rec: roundtrip((123.456, 2, 3), Test) assert f"Expected `{type(tag).__name__}`" in str(rec.value) assert "`$[0]`" in str(rec.value) # Tag incorrect value bad = -3 if isinstance(tag, int) else "bad" with pytest.raises(ValidationError) as rec: roundtrip((bad, 1, 2), Test) assert f"Invalid value {bad!r}" in str(rec.value) assert "`$[0]`" in str(rec.value) # Field incorrect type correct index with pytest.raises(ValidationError) as rec: roundtrip((tag, "a", 2), Test) assert "Expected `int`, got `str`" in str(rec.value) assert "`$[1]`" in str(rec.value) @pytest.mark.parametrize("tag", ["Test", 123, -123]) def test_tagged_empty_struct(self, tag): class Test(Struct, tag=tag, array_like=True): pass # Decode with tag res = roundtrip((tag, 1, 2), Test) assert res == Test() # Tag missing with pytest.raises(ValidationError) as rec: roundtrip((), Test) assert "Expected `array` of at least length 1, got 0" in str(rec.value) class TestStructUnion: @pytest.mark.parametrize( "tag1, tag2, unknown", [ ("Test1", "Test2", "Test3"), (0, 1, 2), (123, -123, 0), ], ) @mapcls_and_from_attributes def test_struct_union(self, tag1, tag2, unknown, mapcls, from_attributes): def decode(msg): return convert(mapcls(msg), Test1 | Test2, from_attributes=from_attributes) class Test1(Struct, tag=tag1): a: int b: int c: int = 0 class Test2(Struct, tag=tag2): x: int y: int # Tag can be in any position assert decode({"type": tag1, "a": 1, "b": 2}) == Test1(1, 2) assert decode({"a": 1, "type": tag1, "b": 2}) == Test1(1, 2) assert decode({"x": 1, "y": 2, "type": tag2}) == Test2(1, 2) # Optional fields still work assert decode({"type": tag1, "a": 1, "b": 2, "c": 3}) == Test1(1, 2, 3) assert decode({"a": 1, "b": 2, "c": 3, "type": tag1}) == Test1(1, 2, 3) # Extra fields still ignored assert decode({"a": 1, "b": 2, "d": 4, "type": tag1}) == Test1(1, 2) # Tag missing with pytest.raises(ValidationError) as rec: decode({"a": 1, "b": 2}) assert "missing required field `type`" in str(rec.value) # Tag wrong type with pytest.raises(ValidationError) as rec: decode({"type": 123.456, "a": 1, "b": 2}) assert f"Expected `{type(tag1).__name__}`" in str(rec.value) assert "`$.type`" in str(rec.value) # Tag unknown with pytest.raises(ValidationError) as rec: decode({"type": unknown, "a": 1, "b": 2}) assert f"Invalid value {unknown!r} - at `$.type`" == str(rec.value) @pytest.mark.parametrize( "tag1, tag2, tag3, unknown", [ ("Test1", "Test2", "Test3", "Test4"), (0, 1, 2, 3), (123, -123, 0, -1), ], ) def test_struct_array_union(self, tag1, tag2, tag3, unknown): class Test1(Struct, tag=tag1, array_like=True): a: int b: int c: int = 0 class Test2(Struct, tag=tag2, array_like=True): x: int y: int class Test3(Struct, tag=tag3, array_like=True): pass typ = Test1 | Test2 | Test3 # Decoding works assert roundtrip([tag1, 1, 2], typ) == Test1(1, 2) assert roundtrip([tag2, 3, 4], typ) == Test2(3, 4) assert roundtrip([tag3], typ) == Test3() # Optional & Extra fields still respected assert roundtrip([tag1, 1, 2, 3], typ) == Test1(1, 2, 3) assert roundtrip([tag1, 1, 2, 3, 4], typ) == Test1(1, 2, 3) # Missing required field with pytest.raises(ValidationError) as rec: roundtrip([tag1, 1], typ) assert "Expected `array` of at least length 3, got 2" in str(rec.value) # Type error has correct field index with pytest.raises(ValidationError) as rec: roundtrip([tag1, 1, "bad", 2], typ) assert "Expected `int`, got `str` - at `$[2]`" == str(rec.value) # Tag missing with pytest.raises(ValidationError) as rec: roundtrip([], typ) assert "Expected `array` of at least length 1, got 0" == str(rec.value) # Tag wrong type with pytest.raises(ValidationError) as rec: roundtrip([123.456, 2, 3, 4], typ) assert f"Expected `{type(tag1).__name__}`" in str(rec.value) assert "`$[0]`" in str(rec.value) # Tag unknown with pytest.raises(ValidationError) as rec: roundtrip([unknown, 1, 2, 3], typ) assert f"Invalid value {unknown!r} - at `$[0]`" == str(rec.value) @pytest.mark.parametrize("tags", [(1, 2), (-10000, 10000), ("A", "B")]) @pytest.mark.parametrize("array_like", [False, True]) def test_struct_to_struct_union(self, tags, array_like): class Ex1(Struct, array_like=array_like, tag=tags[0]): x: int class Ex2(Struct, array_like=array_like, tag=tags[1]): x: int class Ex3(Struct, array_like=array_like): x: int typ = Ex1 | Ex2 msg = Ex1(1) assert convert(msg, typ) is msg with pytest.raises(ValidationError, match="got `Ex3`"): convert(Ex3(1), typ) class TestGenericStruct: @mapcls_from_attributes_and_array_like def test_generic_struct(self, mapcls, from_attributes, array_like): class Ex(Struct, Generic[T], array_like=array_like): x: T y: list[T] sol = Ex(1, [1, 2]) msg = mapcls(x=1, y=[1, 2]) res = convert(msg, Ex, from_attributes=from_attributes) assert res == sol res = convert(msg, Ex[int], from_attributes=from_attributes) assert res == sol res = convert(msg, Ex[int | str], from_attributes=from_attributes) assert res == sol res = convert(msg, Ex[float], from_attributes=from_attributes) assert type(res.x) is float with pytest.raises(ValidationError, match="Expected `str`, got `int`"): convert(msg, Ex[str], from_attributes=from_attributes) @mapcls_from_attributes_and_array_like def test_generic_struct_union(self, mapcls, from_attributes, array_like): class Test1(Struct, Generic[T], tag=True, array_like=array_like): a: T | None b: int class Test2(Struct, Generic[T], tag=True, array_like=array_like): x: T y: int typ = Test1[T] | Test2[T] msg1 = Test1(1, 2) s1 = mapcls(type="Test1", a=1, b=2) msg2 = Test2("three", 4) s2 = mapcls(type="Test2", x="three", y=4) msg3 = Test1(None, 4) s3 = mapcls(type="Test1", a=None, b=4) assert convert(s1, typ, from_attributes=from_attributes) == msg1 assert convert(s2, typ, from_attributes=from_attributes) == msg2 assert convert(s3, typ, from_attributes=from_attributes) == msg3 assert convert(s1, typ[int], from_attributes=from_attributes) == msg1 assert convert(s3, typ[int], from_attributes=from_attributes) == msg3 assert convert(s2, typ[str], from_attributes=from_attributes) == msg2 assert convert(s3, typ[str], from_attributes=from_attributes) == msg3 with pytest.raises(ValidationError) as rec: convert(s1, typ[str], from_attributes=from_attributes) assert "Expected `str | null`, got `int`" in str(rec.value) loc = "$[1]" if array_like and not from_attributes else "$.a" assert loc in str(rec.value) with pytest.raises(ValidationError) as rec: convert(s2, typ[int], from_attributes=from_attributes) assert "Expected `int`, got `str`" in str(rec.value) loc = "$[1]" if array_like and not from_attributes else "$.x" assert loc in str(rec.value) class TestStructPostInit: @pytest.mark.parametrize("union", [False, True]) @mapcls_from_attributes_and_array_like def test_struct_post_init(self, union, mapcls, from_attributes, array_like): called = False singleton = object() class Ex(Struct, array_like=array_like, tag=union): x: int def __post_init__(self): nonlocal called called = True return singleton if union: class Ex2(Struct, array_like=array_like, tag=True): pass typ = Ex | Ex2 else: typ = Ex msg = mapcls(type="Ex", x=1) if union else mapcls(x=1) res = convert(msg, type=typ, from_attributes=from_attributes) assert type(res) is Ex assert called assert sys.getrefcount(singleton) <= 2 # 1 for ref, 1 for call @pytest.mark.parametrize("union", [False, True]) @pytest.mark.parametrize("exc_class", [ValueError, TypeError, OSError]) @mapcls_from_attributes_and_array_like def test_struct_post_init_errors( self, union, exc_class, mapcls, from_attributes, array_like ): class Ex(Struct, array_like=array_like, tag=union): x: int def __post_init__(self): raise exc_class("Oh no!") if union: class Ex2(Struct, array_like=array_like, tag=True): pass typ = Ex | Ex2 else: typ = Ex msg = [mapcls(type="Ex", x=1) if union else mapcls(x=1)] if exc_class in (ValueError, TypeError): expected = ValidationError else: expected = exc_class with pytest.raises(expected, match="Oh no!") as rec: convert(msg, type=list[typ], from_attributes=from_attributes) if expected is ValidationError: assert "- at `$[0]`" in str(rec.value) class TestLax: def test_lax_none(self): for x in ["null", "Null", "nUll", "nuLl", "nulL"]: assert convert(x, None, strict=False) is None for x in ["xull", "nxll", "nuxl", "nulx"]: with pytest.raises(ValidationError, match="Expected `null`, got `str`"): convert(x, None, strict=False) def test_lax_bool_true(self): for x in [1, "1", "true", "True", "tRue", "trUe", "truE"]: assert convert(x, bool, strict=False) is True def test_lax_bool_false(self): for x in [0, "0", "false", "False", "fAlse", "faLse", "falSe", "falsE"]: assert convert(x, bool, strict=False) is False def test_lax_bool_true_invalid(self): for x in [-1, 3, "x", "xx", "xrue", "txue", "trxe", "trux"]: typ = type(x).__name__ with pytest.raises(ValidationError, match=f"Expected `bool`, got `{typ}`"): assert convert(x, bool, strict=False) def test_lax_bool_false_invalid(self): for x in [-1, 3, "x", "xx", "xalse", "fxlse", "faxse", "falxe", "falsx"]: typ = type(x).__name__ with pytest.raises(ValidationError, match=f"Expected `bool`, got `{typ}`"): assert convert(x, bool, strict=False) def test_lax_int_from_str(self): for x in ["1", "-1", "123456", "1.0"]: assert convert(x, int, strict=False) == int(float(x)) for x in ["a", "1a", "1.5", "1..", "nan", "inf"]: with pytest.raises(ValidationError, match="Expected `int`, got `str`"): convert(x, int, strict=False) def test_lax_int_from_float(self): bound = float(1 << 53) for x in [-bound, -1.0, -0.0, 0.0, 1.0, bound]: assert convert(x, int, strict=False) == int(x) for x in [-bound - 2, -1.5, 0.001, 1.5, bound + 2, float("inf"), float("nan")]: with pytest.raises(ValidationError, match="Expected `int`, got `float`"): convert(x, int, strict=False) def test_lax_int_constr(self): typ = Annotated[int, Meta(ge=0)] assert convert("1", typ, strict=False) == 1 with pytest.raises(ValidationError): convert("-1", typ, strict=False) def test_lax_int_enum(self): class Ex(enum.IntEnum): x = 1 y = -2 assert convert("1", Ex, strict=False) is Ex.x assert convert("-2", Ex, strict=False) is Ex.y with pytest.raises(ValidationError, match="Invalid enum value 3"): convert("3", Ex, strict=False) with pytest.raises(ValidationError, match="Expected `int`, got `str`"): convert("A", Ex, strict=False) def test_lax_int_literal(self): typ = Literal[1, -2] assert convert("1", typ, strict=False) == 1 assert convert("-2", typ, strict=False) == -2 with pytest.raises(ValidationError, match="Invalid enum value 3"): convert("3", typ, strict=False) with pytest.raises(ValidationError, match="Expected `int`, got `str`"): convert("A", typ, strict=False) def test_lax_float(self): for x in ["1", "-1", "123456", "1.5", "-1.5", "inf"]: assert convert(x, float, strict=False) == float(x) for x in ["a", "1a", "1.0.0", "1.."]: with pytest.raises(ValidationError, match="Expected `float`, got `str`"): convert(x, float, strict=False) @pytest.mark.parametrize("str_value", ["nan", "infinity"]) @pytest.mark.parametrize("negative", [False, True]) def test_lax_float_nonfinite(self, str_value, negative): prefix = "-" if negative else "" for i in range(len(str_value)): msg = prefix + str_value[:i] + str_value[i].upper() + str_value[i + 1 :] sol = float(msg) res = convert(msg, float, strict=False) assert_eq(res, sol) def test_lax_float_nonfinite_invalid(self): for bad in ["abcd", "-abcd", "inx", "-inx", "infinitx", "-infinitx", "nax"]: for msg in [bad, bad.upper()]: with pytest.raises( ValidationError, match="Expected `float`, got `str`" ): convert(msg, float, strict=False) def test_lax_float_constr(self): assert convert("1.5", Annotated[float, Meta(ge=0)], strict=False) == 1.5 with pytest.raises(ValidationError): convert("-1.0", Annotated[float, Meta(ge=0)], strict=False) def test_lax_str(self): for x in ["1", "1.5", "false", "null"]: assert convert(x, str, strict=False) == x def test_lax_str_constr(self): typ = Annotated[str, Meta(max_length=10)] assert convert("xxx", typ, strict=False) == "xxx" with pytest.raises(ValidationError): convert("x" * 20, typ, strict=False) @pytest.mark.parametrize( "x", [ 1234.0000004, 1234.0000006, 1234.000567, 1234.567, 1234.0, 0.123, 0.0, 1234, 0, ], ) @pytest.mark.parametrize("sign", [-1, 1]) @pytest.mark.parametrize("transform", [None, str]) def test_lax_datetime(self, x, sign, transform): timestamp = x * sign msg = transform(timestamp) if transform else timestamp sol = datetime.datetime.fromtimestamp(timestamp, UTC) res = convert(msg, type=datetime.datetime, strict=False) assert res == sol def test_lax_datetime_nonfinite_values(self): for msg in ["nan", "-inf", "inf", float("nan"), float("inf"), float("-inf")]: with pytest.raises(ValidationError, match="Invalid epoch timestamp"): convert(msg, type=datetime.datetime, strict=False) @pytest.mark.parametrize("val", [-62135596801, 253402300801]) @pytest.mark.parametrize("type", [int, float, str]) def test_lax_datetime_out_of_range(self, val, type): msg = type(val) with pytest.raises(ValidationError, match="out of range"): convert(msg, type=datetime.datetime, strict=False) def test_lax_datetime_invalid_numeric_str(self): for msg in ["", "12e", "1234a", "1234-1", "1234.a"]: with pytest.raises(ValidationError, match="Invalid"): convert(msg, type=datetime.datetime, strict=False) @pytest.mark.parametrize("msg", [123, -123, 123.456, "123.456"]) def test_lax_datetime_naive_required(self, msg): with pytest.raises(ValidationError, match="no timezone component"): convert( msg, type=Annotated[datetime.datetime, Meta(tz=False)], strict=False ) @pytest.mark.parametrize( "x", [ 1234.0000004, 1234.0000006, 1234.000567, 1234.567, 1234.0, 0.123, 0.0, 1234, 0, ], ) @pytest.mark.parametrize("sign", [-1, 1]) @pytest.mark.parametrize("transform", [None, str]) def test_lax_timedelta(self, x, sign, transform): timestamp = x * sign msg = transform(timestamp) if transform else timestamp sol = datetime.timedelta(seconds=timestamp) res = convert(msg, type=datetime.timedelta, strict=False) assert res == sol def test_lax_timedelta_nonfinite_values(self): for msg in ["nan", "-inf", "inf", float("nan"), float("inf"), float("-inf")]: with pytest.raises(ValidationError, match="Duration is out of range"): convert(msg, type=datetime.timedelta, strict=False) @pytest.mark.parametrize("val", [86400000000001, -86399999913601]) @pytest.mark.parametrize("type", [int, float, str]) def test_lax_timedelta_out_of_range(self, val, type): msg = type(val) with pytest.raises(ValidationError, match="out of range"): convert(msg, type=datetime.timedelta, strict=False) def test_lax_timedelta_invalid_numeric_str(self): for msg in ["", "12e", "1234a", "1234-1", "1234.a"]: with pytest.raises(ValidationError, match="Invalid"): convert(msg, type=datetime.timedelta, strict=False) @pytest.mark.parametrize( "msg, sol", [ ("1", 1), ("0", 0), ("-1", -1), ("12.5", 12.5), ("inf", float("inf")), ("true", True), ("false", False), ("null", None), ], ) def test_lax_union_valid(self, msg, sol): typ = int | float | bool | None assert_eq(convert(msg, typ, strict=False), sol) @pytest.mark.parametrize("msg", ["1a", "1.5a", "falsx", "trux", "nulx"]) def test_lax_union_invalid(self, msg): typ = int | float | bool | None with pytest.raises( ValidationError, match="Expected `int | float | bool | null`" ): convert(msg, typ, strict=False) @pytest.mark.parametrize( "msg, err", [ ("-1", "`int` >= 0"), ("2000", "`int` <= 1000"), ("18446744073709551616", "`int` <= 1000"), ("-9223372036854775809", "`int` >= 0"), ("100.5", "`float` <= 100.0"), ], ) def test_lax_union_invalid_constr(self, msg, err): """Ensure that values that parse properly but don't meet the specified constraints error with a specific constraint error""" typ = Annotated[int, Meta(ge=0), Meta(le=1000)] | Annotated[float, Meta(le=100)] with pytest.raises(ValidationError, match=err): convert(msg, typ, strict=False) def test_lax_union_extended(self): typ = int | float | bool | datetime.datetime | None dt = datetime.datetime.now() assert_eq(convert("1", typ, strict=False), 1) assert_eq(convert("1.5", typ, strict=False), 1.5) assert_eq(convert("false", typ, strict=False), False) assert_eq(convert("null", typ, strict=False), None) assert_eq(convert(dt.isoformat(), typ, strict=False), dt) def test_lax_implies_str_keys(self): res = convert({"1": False}, dict[int, bool], strict=False) assert res == {1: False} def test_lax_implies_no_builtin_types(self): sol = uuid.uuid4() msg = str(sol) res = convert(msg, uuid.UUID, strict=False, builtin_types=(uuid.UUID,)) assert res == sol class TestCustom: def test_custom(self): def dec_hook(typ, x): assert typ is complex return complex(*x) msg = {"x": (1, 2)} sol = {"x": complex(1, 2)} res = convert(msg, dict[str, complex], dec_hook=dec_hook) assert res == sol def test_custom_no_dec_hook(self): with pytest.raises(ValidationError, match="Expected `complex`, got `str`"): convert({"x": "oh no"}, dict[str, complex]) def test_custom_dec_hook_errors(self): def dec_hook(typ, x): raise TypeError("Oops!") with pytest.raises(ValidationError, match="Oops!") as rec: convert({"x": (1, 2)}, dict[str, complex], dec_hook=dec_hook) assert rec.value.__cause__ is rec.value.__context__ assert type(rec.value.__cause__) is TypeError class TestRaw: def test_raw(self): raw = msgspec.Raw(b"123") class Ex(Struct): x: msgspec.Raw sol = Ex(x=raw) assert convert({"x": raw}, type=Ex) == sol @pytest.mark.parametrize( "value", [1, "a", [1, 2], {"a": 1}], ids=["int", "str", "array", "object"] ) def test_raw_mismatch_error_message(self, value): """Regression test for gh#1136 -- convert() only accepts an already `Raw` instance for a `Raw`-typed field (e.g. via `yaml.decode`, `toml.decode`, or `convert` on already-parsed data). The mismatch error previously claimed `any` was acceptable, which contradicted the `ValidationError` being raised.""" class Ex(Struct): x: msgspec.Raw with pytest.raises(ValidationError, match=r"^Expected `raw`, got `\w+`"): convert({"x": value}, type=Ex) @pytest.mark.parametrize("total", [False, True]) @pytest.mark.parametrize("value, kind", [(None, "null"), (1, "int")]) def test_raw_typeddict_error_message(self, total, value, kind): class Ex(TypedDict, total=total): x: msgspec.Raw with pytest.raises(ValidationError) as rec: convert({"x": value}, type=Ex) assert str(rec.value) == f"Expected `raw`, got `{kind}` - at `$.x`" @pytest.mark.parametrize("default_factory", [False, True]) @pytest.mark.parametrize("value, kind", [(None, "null"), (1, "int")]) def test_raw_dataclass_error_message(self, default_factory, value, kind): @dataclass class Ex: x: msgspec.Raw = ( field(default_factory=msgspec.Raw) if default_factory else field() ) with pytest.raises(ValidationError) as rec: convert({"x": value}, type=Ex) assert str(rec.value) == f"Expected `raw`, got `{kind}` - at `$.x`" python-msgspec-0.22.0/tests/unit/test_cpylint.py000066400000000000000000000030361525673062400220030ustar00rootroot00000000000000"""This file contains some simple linters for catching some common but easy to catch cpython capi bugs. These are naive string-munging checks, if you write some code that _is_ correct but is failing, add `/* cpylint-ignore */` on the failing source line and it will be ignored.""" import pytest @pytest.fixture def source(package_dir): with package_dir.joinpath("_core.c").open() as f: return f.read().splitlines() def test_recursive_call_blocks(source): """Ensure all code that calls `Py_EnterRecursiveCall` doesn't return without calling `Py_LeaveRecursiveCall`""" in_block = False for lineno, line in enumerate(source, 1): if "cpylint-ignore" in line: continue if "Py_EnterRecursiveCall" in line: in_block = True elif "return " in line and in_block: raise ValueError( f"return without calling Py_LeaveRecursiveCall on line {lineno}" ) elif "Py_LeaveRecursiveCall" in line: in_block = False def test_recursive_repr_blocks(source): """Ensure all code that calls `Py_ReprEnter` doesn't return without calling `Py_ReprLeave`""" in_block = False for lineno, line in enumerate(source, 1): if "cpylint-ignore" in line: continue if "Py_ReprEnter" in line: in_block = True elif "return " in line and in_block: raise ValueError(f"return without calling Py_ReprLeave on line {lineno}") elif "Py_ReprLeave" in line: in_block = False python-msgspec-0.22.0/tests/unit/test_inspect.py000066400000000000000000000533721525673062400217760ustar00rootroot00000000000000import collections import datetime import decimal import enum import sys import typing import uuid from collections import namedtuple from copy import deepcopy from dataclasses import dataclass, field from typing import ( Annotated, Any, Dict, Final, FrozenSet, Generic, List, Literal, NamedTuple, NewType, Set, Tuple, TypedDict, TypeVar, Union, ) import pytest import msgspec import msgspec.inspect as mi from msgspec import Meta from .utils import py315_or_later_only, temp_module if sys.version_info >= (3, 15): # This is needed for `ruff` to recognize `frozendict` name # and to not raise `F821`: from builtins import frozendict PY312 = sys.version_info[:2] >= (3, 12) py312_plus = pytest.mark.skipif(not PY312, reason="3.12+ only") T = TypeVar("T") @pytest.mark.parametrize( "a,b,sol", [ ( {"a": {"b": {"c": 1}}}, {"a": {"b": {"d": 2}}}, {"a": {"b": {"c": 1, "d": 2}}}, ), ({"a": {"b": {"c": 1}}}, {"a": {"b": 2}}, {"a": {"b": 2}}), ({"a": [1, 2]}, {"a": [3, 4]}, {"a": [1, 2, 3, 4]}), ({"a": {"b": 1}}, {"a2": 3}, {"a": {"b": 1}, "a2": 3}), ({"a": 1}, {}, {"a": 1}), ], ) def test_merge_json(a, b, sol): a_orig = deepcopy(a) b_orig = deepcopy(b) res = mi._merge_json(a, b) assert res == sol assert a == a_orig assert b == b_orig def test_inspect_module_dir(): assert mi.__dir__() == mi.__all__ def test_any(): assert mi.type_info(Any) == mi.AnyType() def test_typevar(): assert mi.type_info(T) == mi.AnyType() def test_bound_typevar(): T = TypeVar("T", bound=int | str) assert mi.type_info(T) == mi.UnionType((mi.IntType(), mi.StrType())) def test_none(): assert mi.type_info(None) == mi.NoneType() def test_bool(): assert mi.type_info(bool) == mi.BoolType() @pytest.mark.parametrize( "kw", [{}, dict(ge=2), dict(gt=2), dict(le=2), dict(lt=2), dict(multiple_of=2)] ) @pytest.mark.parametrize("typ, info_type", [(int, mi.IntType), (float, mi.FloatType)]) def test_numeric(kw, typ, info_type): if kw: typ = Annotated[typ, Meta(**kw)] assert mi.type_info(typ) == info_type(**kw) @pytest.mark.parametrize( "kw", [{}, dict(pattern="[a-z]*"), dict(min_length=0), dict(max_length=3)], ) def test_string(kw): typ = str if kw: typ = Annotated[typ, Meta(**kw)] assert mi.type_info(typ) == mi.StrType(**kw) @pytest.mark.parametrize( "kw", [{}, dict(min_length=0), dict(max_length=3)], ) @pytest.mark.parametrize( "typ, info_type", [ (bytes, mi.BytesType), (bytearray, mi.ByteArrayType), (memoryview, mi.MemoryViewType), ], ) def test_binary(kw, typ, info_type): if kw: typ = Annotated[typ, Meta(**kw)] assert mi.type_info(typ) == info_type(**kw) @pytest.mark.parametrize( "kw", [{}, dict(tz=None), dict(tz=True), dict(tz=False)], ) def test_datetime(kw): typ = datetime.datetime if kw: typ = Annotated[typ, Meta(**kw)] assert mi.type_info(typ) == mi.DateTimeType(**kw) @pytest.mark.parametrize( "kw", [{}, dict(tz=None), dict(tz=True), dict(tz=False)], ) def test_time(kw): typ = datetime.time if kw: typ = Annotated[typ, Meta(**kw)] assert mi.type_info(typ) == mi.TimeType(**kw) def test_date(): assert mi.type_info(datetime.date) == mi.DateType() def test_timedelta(): assert mi.type_info(datetime.timedelta) == mi.TimeDeltaType() def test_uuid(): assert mi.type_info(uuid.UUID) == mi.UUIDType() def test_decimal(): assert mi.type_info(decimal.Decimal) == mi.DecimalType() def test_raw(): assert mi.type_info(msgspec.Raw) == mi.RawType() def test_msgpack_ext(): assert mi.type_info(msgspec.msgpack.Ext) == mi.ExtType() def test_newtype(): UserId = NewType("UserId", str) assert mi.type_info(UserId) == mi.StrType() assert mi.type_info(Annotated[UserId, Meta(max_length=10)]) == mi.StrType( max_length=10 ) # Annotated in NewType UserId = NewType("UserId", Annotated[str, Meta(max_length=10)]) assert mi.type_info(UserId) == mi.StrType(max_length=10) assert mi.type_info(Annotated[UserId, Meta(min_length=2)]) == mi.StrType( min_length=2, max_length=10 ) # NewType in NewType UserId2 = NewType("UserId2", UserId) assert mi.type_info(UserId2) == mi.StrType(max_length=10) assert mi.type_info(Annotated[UserId2, Meta(min_length=2)]) == mi.StrType( min_length=2, max_length=10 ) @py312_plus @pytest.mark.parametrize( "src, typ", [ ("type Ex = str | None", str | None), ("type Ex[T] = tuple[T, int]", tuple[Any, int]), ("type Temp[T] = tuple[T, int]; Ex = Temp[str]", tuple[str, int]), ], ) def test_typealias(src, typ): with temp_module(src) as mod: assert mi.type_info(mod.Ex) == mi.type_info(typ) def test_final(): cases = [ (int, mi.IntType()), (Annotated[int, Meta(ge=0)], mi.IntType(ge=0)), (NewType("UserId", Annotated[int, Meta(ge=0)]), mi.IntType(ge=0)), ] for typ, sol in cases: class Ex(msgspec.Struct): x: Final[typ] info = mi.type_info(Ex) assert info.fields[0].type == sol def test_custom(): assert mi.type_info(complex) == mi.CustomType(complex) @pytest.mark.parametrize( "kw", [{}, dict(min_length=0), dict(max_length=3)], ) @pytest.mark.parametrize( "typ, info_type", [ (list, mi.ListType), (tuple, mi.VarTupleType), (set, mi.SetType), (frozenset, mi.FrozenSetType), (List, mi.ListType), (Tuple, mi.VarTupleType), (Set, mi.SetType), (FrozenSet, mi.FrozenSetType), ], ) @pytest.mark.parametrize("has_item_type", [False, True]) def test_sequence(kw, typ, info_type, has_item_type): if has_item_type: item_type = mi.IntType() if info_type is mi.VarTupleType: typ = typ[int, ...] else: typ = typ[int] else: item_type = mi.AnyType() if kw: typ = Annotated[typ, Meta(**kw)] sol = info_type(item_type=item_type, **kw) assert mi.type_info(typ) == sol @pytest.mark.parametrize("typ", [Tuple, tuple]) def test_tuple(typ): assert mi.type_info(typ[()]) == mi.TupleType(()) assert mi.type_info(typ[int]) == mi.TupleType((mi.IntType(),)) assert mi.type_info(typ[int, float]) == mi.TupleType((mi.IntType(), mi.FloatType())) @pytest.mark.parametrize("typ", [Dict, dict]) @pytest.mark.parametrize("kw", [{}, dict(min_length=0), dict(max_length=3)]) @pytest.mark.parametrize("has_args", [False, True]) def test_dict(typ, kw, has_args): if has_args: typ = typ[int, float] key = mi.IntType() val = mi.FloatType() else: key = val = mi.AnyType() if kw: typ = Annotated[typ, Meta(**kw)] sol = mi.DictType(key_type=key, value_type=val, **kw) assert mi.type_info(typ) == sol @py315_or_later_only @pytest.mark.parametrize("kw", [{}, dict(min_length=0), dict(max_length=3)]) @pytest.mark.parametrize("has_args", [False, True]) def test_frozendict(kw, has_args): if has_args: typ = frozendict[int, float] key = mi.IntType() val = mi.FloatType() else: typ = frozendict key = val = mi.AnyType() if kw: typ = Annotated[typ, Meta(**kw)] sol = mi.FrozenDictType(key_type=key, value_type=val, **kw) assert mi.type_info(typ) == sol @pytest.mark.parametrize( "typ", [ typing.Collection, typing.MutableSequence, typing.Sequence, collections.abc.Collection, collections.abc.MutableSequence, collections.abc.Sequence, typing.MutableSet, typing.AbstractSet, collections.abc.MutableSet, collections.abc.Set, ], ) def test_abstract_sequence(typ): if "Set" in str(typ): col_type = mi.SetType else: col_type = mi.ListType assert mi.type_info(typ) == col_type(mi.AnyType()) assert mi.type_info(typ[int]) == col_type(mi.IntType()) @pytest.mark.parametrize( "typ", [ typing.MutableMapping, typing.Mapping, collections.abc.MutableMapping, collections.abc.Mapping, ], ) def test_abstract_mapping(typ): assert mi.type_info(typ) == mi.DictType(mi.AnyType(), mi.AnyType()) assert mi.type_info(typ[str, int]) == mi.DictType(mi.StrType(), mi.IntType()) @pytest.mark.parametrize("use_union_operator", [False, True]) def test_union(use_union_operator): if use_union_operator: typ = int | str else: typ = Union[int, str] sol = mi.UnionType((mi.IntType(), mi.StrType())) assert mi.type_info(typ) == sol assert not sol.includes_none assert mi.type_info(Union[int, None]).includes_none assert mi.type_info(int | None).includes_none def test_int_literal(): assert mi.type_info(Literal[3, 1, 2]) == mi.LiteralType((1, 2, 3)) def test_str_literal(): assert mi.type_info(Literal["c", "a", "b"]) == mi.LiteralType(("a", "b", "c")) def test_bool_literal(): assert mi.type_info(Literal[True]) == mi.LiteralType((True,)) assert mi.type_info(Literal[True, False]) == mi.LiteralType((False, True)) def test_mixed_literal(): # Literals may mix value types; `type_info` shouldn't crash trying to sort # values of incomparable types (gh#1018). assert mi.type_info(Literal[1, None]) == mi.LiteralType((None, 1)) assert mi.type_info(Literal[True, "yes"]) == mi.LiteralType((True, "yes")) def test_int_enum(): class Example(enum.IntEnum): B = 3 A = 2 assert mi.type_info(Example) == mi.EnumType(Example) def test_enum(): class Example(enum.Enum): B = "z" A = "y" assert mi.type_info(Example) == mi.EnumType(Example) @pytest.mark.parametrize( "kw", [ {}, {"array_like": True}, {"forbid_unknown_fields": True}, {"tag": "Example", "tag_field": "type"}, ], ) def test_struct(kw): def factory(): return "foo" class Example(msgspec.Struct, **kw): x: int y: int = 0 z: int = msgspec.field(default_factory=factory) sol = mi.StructType( cls=Example, fields=( mi.Field(name="x", encode_name="x", type=mi.IntType()), mi.Field( name="y", encode_name="y", type=mi.IntType(), required=False, default=0 ), mi.Field( name="z", encode_name="z", type=mi.IntType(), required=False, default_factory=factory, ), ), **kw, ) assert mi.type_info(Example) == sol def test_struct_no_fields(): class Example(msgspec.Struct): pass sol = mi.StructType(Example, fields=()) assert mi.type_info(Example) == sol def test_struct_keyword_only(): class Example(msgspec.Struct, kw_only=True): a: int b: int = 1 c: int d: int = 2 sol = mi.StructType( Example, fields=( mi.Field("a", "a", mi.IntType()), mi.Field("b", "b", mi.IntType(), required=False, default=1), mi.Field("c", "c", mi.IntType()), mi.Field("d", "d", mi.IntType(), required=False, default=2), ), ) assert mi.type_info(Example) == sol def test_struct_encode_name(): class Example(msgspec.Struct, rename="camel"): field_one: int field_two: int sol = mi.StructType( Example, fields=( mi.Field("field_one", "fieldOne", mi.IntType()), mi.Field("field_two", "fieldTwo", mi.IntType()), ), ) assert mi.type_info(Example) == sol def test_generic_struct(): class Example(msgspec.Struct, Generic[T]): a: T b: list[T] sol = mi.StructType( Example, fields=( mi.Field("a", "a", mi.AnyType()), mi.Field("b", "b", mi.ListType(mi.AnyType())), ), ) assert mi.type_info(Example) == sol sol = mi.StructType( Example[int], fields=( mi.Field("a", "a", mi.IntType()), mi.Field("b", "b", mi.ListType(mi.IntType())), ), ) assert mi.type_info(Example[int]) == sol def test_typing_namedtuple(): class Example(NamedTuple): a: str b: bool c: int = 0 sol = mi.NamedTupleType( Example, fields=( mi.Field("a", "a", mi.StrType()), mi.Field("b", "b", mi.BoolType()), mi.Field("c", "c", mi.IntType(), required=False, default=0), ), ) assert mi.type_info(Example) == sol def test_collections_namedtuple(): Example = namedtuple("Example", ["a", "b", "c"], defaults=(0,)) sol = mi.NamedTupleType( Example, fields=( mi.Field("a", "a", mi.AnyType()), mi.Field("b", "b", mi.AnyType()), mi.Field("c", "c", mi.AnyType(), required=False, default=0), ), ) assert mi.type_info(Example) == sol def test_generic_namedtuple(): NamedTuple = pytest.importorskip("typing_extensions").NamedTuple class Example(NamedTuple, Generic[T]): a: T b: list[T] sol = mi.NamedTupleType( Example, fields=( mi.Field("a", "a", mi.AnyType()), mi.Field("b", "b", mi.ListType(mi.AnyType())), ), ) assert mi.type_info(Example) == sol sol = mi.NamedTupleType( Example[int], fields=( mi.Field("a", "a", mi.IntType()), mi.Field("b", "b", mi.ListType(mi.IntType())), ), ) assert mi.type_info(Example[int]) == sol @pytest.mark.parametrize("use_typing_extensions", [False, True]) def test_typeddict(use_typing_extensions): if use_typing_extensions: tex = pytest.importorskip("typing_extensions") cls = tex.TypedDict else: cls = TypedDict class Example(cls): a: str b: bool c: int sol = mi.TypedDictType( Example, fields=( mi.Field("a", "a", mi.StrType()), mi.Field("b", "b", mi.BoolType()), mi.Field("c", "c", mi.IntType()), ), ) assert mi.type_info(Example) == sol @pytest.mark.parametrize("use_typing_extensions", [False, True]) def test_typeddict_optional(use_typing_extensions): if use_typing_extensions: tex = pytest.importorskip("typing_extensions") cls = tex.TypedDict else: cls = TypedDict class Base(cls): a: str b: bool class Example(Base, total=False): c: int sol = mi.TypedDictType( Example, fields=( mi.Field("a", "a", mi.StrType()), mi.Field("b", "b", mi.BoolType()), mi.Field("c", "c", mi.IntType(), required=False), ), ) assert mi.type_info(Example) == sol def test_generic_typeddict(): TypedDict = pytest.importorskip("typing_extensions").TypedDict class Example(TypedDict, Generic[T]): a: T b: list[T] sol = mi.TypedDictType( Example, fields=( mi.Field("a", "a", mi.AnyType()), mi.Field("b", "b", mi.ListType(mi.AnyType())), ), ) assert mi.type_info(Example) == sol sol = mi.TypedDictType( Example[int], fields=( mi.Field("a", "a", mi.IntType()), mi.Field("b", "b", mi.ListType(mi.IntType())), ), ) assert mi.type_info(Example[int]) == sol def test_dataclass(): @dataclass class Example: x: int y: int = 0 z: str = field(default_factory=str) sol = mi.DataclassType( Example, fields=( mi.Field("x", "x", mi.IntType()), mi.Field("y", "y", mi.IntType(), required=False, default=0), mi.Field("z", "z", mi.StrType(), required=False, default_factory=str), ), ) assert mi.type_info(Example) == sol def test_attrs(): attrs = pytest.importorskip("attrs") @attrs.define class Example: x: int y: int = 0 z: str = attrs.field(factory=str) sol = mi.DataclassType( Example, fields=( mi.Field("x", "x", mi.IntType()), mi.Field("y", "y", mi.IntType(), required=False, default=0), mi.Field("z", "z", mi.StrType(), required=False, default_factory=str), ), ) assert mi.type_info(Example) == sol @pytest.mark.parametrize("module", ["dataclasses", "attrs"]) def test_generic_dataclass_or_attrs(module): m = pytest.importorskip(module) decorator = m.define if module == "attrs" else m.dataclass @decorator class Example(Generic[T]): a: T b: list[T] sol = mi.DataclassType( Example, fields=( mi.Field("a", "a", mi.AnyType()), mi.Field("b", "b", mi.ListType(mi.AnyType())), ), ) assert mi.type_info(Example) == sol sol = mi.DataclassType( Example[int], fields=( mi.Field("a", "a", mi.IntType()), mi.Field("b", "b", mi.ListType(mi.IntType())), ), ) assert mi.type_info(Example[int]) == sol @pytest.mark.parametrize("kind", ["struct", "dataclass", "attrs"]) def test_unset_fields(kind): if kind == "struct": class Ex(msgspec.Struct): x: int | msgspec.UnsetType = msgspec.UNSET elif kind == "dataclass": @dataclass class Ex: x: int | msgspec.UnsetType = msgspec.UNSET elif kind == "attrs": attrs = pytest.importorskip("attrs") @attrs.define class Ex: x: int | msgspec.UnsetType = msgspec.UNSET res = mi.type_info(Ex) assert res.fields == (mi.Field("x", "x", mi.IntType(), required=False),) @pytest.mark.parametrize("kind", ["struct", "namedtuple", "typeddict", "dataclass"]) def test_self_referential_objects(kind): if kind == "struct": code = """ import msgspec class Node(msgspec.Struct): child: "Node" """ elif kind == "namedtuple": code = """ from typing import NamedTuple class Node(NamedTuple): child: "Node" """ elif kind == "typeddict": code = """ from typing import TypedDict class Node(TypedDict): child: "Node" """ elif kind == "dataclass": code = """ from dataclasses import dataclass @dataclass class Node: child: "Node" """ with temp_module(code) as mod: res = mi.type_info(mod.Node) assert res.cls is mod.Node assert res.fields[0].name == "child" assert res.fields[0].type is res def test_metadata(): typ = Annotated[int, Meta(gt=1, title="a"), Meta(description="b")] assert mi.type_info(typ) == mi.Metadata( mi.IntType(gt=1), {"title": "a", "description": "b"} ) typ = Annotated[ int, Meta(extra_json_schema={"title": "a", "description": "b"}), Meta(extra_json_schema={"title": "c", "examples": [1, 2]}), ] assert mi.type_info(typ) == mi.Metadata( mi.IntType(), {"title": "c", "description": "b", "examples": [1, 2]} ) typ = Annotated[ int, Meta(extra={"a": 1, "b": 2}), Meta(extra={"a": 3, "c": 4}), ] assert mi.type_info(typ) == mi.Metadata( mi.IntType(), extra={"a": 3, "b": 2, "c": 4} ) def test_inspect_with_unhashable_metadata(): typ = Annotated[int, {"unhashable"}] assert mi.type_info(typ) == mi.IntType() def test_multi_type_info(): class Example(msgspec.Struct): x: int y: int ex_type = mi.StructType( Example, fields=( mi.Field("x", "x", mi.IntType()), mi.Field("y", "y", mi.IntType()), ), ) assert mi.multi_type_info([]) == () res = mi.multi_type_info([Example, list[Example]]) assert res == (ex_type, mi.ListType(ex_type)) assert res[0] is res[1].item_type def test_type_info_custom_base_class(): class CustomMeta(msgspec.StructMeta): pass class Base(metaclass=CustomMeta): pass class Model(Base): foo: str assert mi.type_info(Model) == mi.StructType( cls=Model, fields=( mi.Field( name="foo", encode_name="foo", type=mi.StrType(min_length=None, max_length=None, pattern=None), required=True, default=msgspec.NODEFAULT, default_factory=msgspec.NODEFAULT, ), ), tag_field=None, tag=None, array_like=False, forbid_unknown_fields=False, ) def test_is_struct_runtime(): class Base(msgspec.Struct): x: int class Derived(Base): pass Generated = msgspec.defstruct("InspectStructRuntime", ["x"]) class CustomMeta(msgspec.StructMeta): pass class CustomBase(metaclass=CustomMeta): x: int class Custom(CustomBase): pass class NotStruct: pass assert mi.is_struct(Base(1)) assert mi.is_struct(Derived(1)) assert mi.is_struct(Generated(1)) assert mi.is_struct(Custom(1)) assert not mi.is_struct(NotStruct()) assert not mi.is_struct(object()) def test_is_struct_type_runtime(): class Base(msgspec.Struct): x: int class Derived(Base): pass Generated = msgspec.defstruct("InspectStructTypeRuntime", ["x"]) class CustomMeta(msgspec.StructMeta): pass class CustomBase(metaclass=CustomMeta): pass class Custom(CustomBase): x: int class NotStruct: pass assert mi.is_struct_type(Base) assert mi.is_struct_type(Derived) assert mi.is_struct_type(Generated) assert mi.is_struct_type(Custom) assert not mi.is_struct_type(NotStruct) assert not mi.is_struct_type(object) python-msgspec-0.22.0/tests/unit/test_integration.py000066400000000000000000000016241525673062400226450ustar00rootroot00000000000000import datetime import sys import pytest import msgspec @pytest.fixture(params=["json", "msgpack"]) def proto(request): if request.param == "json": return msgspec.json elif request.param == "msgpack": return msgspec.msgpack def test_decode_naive_datetime(proto): """See https://github.com/msgspec/msgspec/issues/408""" dt = datetime.datetime(2001, 2, 3, 4, 5, 6, 7) msg = proto.encode(dt) start = sys.getrefcount(None) for _ in range(1000): proto.decode(msg, type=datetime.datetime) end = sys.getrefcount(None) assert start == end def test_decode_naive_time(proto): """See https://github.com/msgspec/msgspec/issues/408""" dt = datetime.time(12, 20) msg = proto.encode(dt) start = sys.getrefcount(None) for _ in range(1000): proto.decode(msg, type=datetime.time) end = sys.getrefcount(None) assert start == end python-msgspec-0.22.0/tests/unit/test_json.py000066400000000000000000003353001525673062400212740ustar00rootroot00000000000000from __future__ import annotations import base64 import datetime import decimal import enum import gc import itertools import json import math import string import sys import uuid from dataclasses import dataclass from decimal import Decimal from typing import Annotated, Any, Literal, NamedTuple, TypedDict, Union import pytest import msgspec from .utils import emscripten_stack_limited UTC = datetime.timezone.utc class FruitInt(enum.IntEnum): APPLE = -1 BANANA = 2 class FruitStr(enum.Enum): APPLE = "apple" BANANA = "banana" class Person(msgspec.Struct): first: str last: str age: int prefect: bool = False class PersonArray(msgspec.Struct, array_like=True): first: str last: str age: int prefect: bool = False class Node(msgspec.Struct): left: Node | None = None right: Node | None = None class Custom: def __init__(self, x, y): self.x = x self.y = y def __eq__(self, other): return self.x == other.x and self.y == other.y class TestInvalidJSONTypes: def test_invalid_type_union(self): literal = Literal["a", "b"] types = [ FruitStr, literal, str, datetime.datetime, datetime.date, bytes, bytearray, ] for length in [2, 3, 4]: for types in itertools.combinations(types, length): if set(types) in ({bytes, bytearray}, {str, literal}): continue with pytest.raises(TypeError, match="not supported"): msgspec.json.Decoder(Union[types]) def test_invalid_dict_key_type_errors_at_runtime(self): # We used to check this statically at TypeNode build time, but this was # a pain. We now just ensure invalid types error at runtime. with pytest.raises( msgspec.ValidationError, match="Expected `array`, got `str`" ): msgspec.json.decode(b'{"x": 1}', type=dict[tuple[int, int], int]) class TestEncodeFunction: def test_encode(self): assert msgspec.json.encode(1) == b"1" def test_encode_error(self): with pytest.raises(TypeError): msgspec.json.encode(object()) def test_encode_large_object(self): """Check that buffer resize works""" data = "x" * 4097 assert msgspec.json.encode(data) == f'"{data}"'.encode() def test_encode_no_enc_hook(self): class Foo: pass with pytest.raises( TypeError, match="Encoding objects of type Foo is unsupported" ): msgspec.json.encode(Foo()) def test_encode_enc_hook(self): unsupported = object() def enc_hook(x): assert x is unsupported return "hello" orig_refcount = sys.getrefcount(enc_hook) res = msgspec.json.encode(unsupported, enc_hook=enc_hook) assert msgspec.json.encode("hello") == res assert sys.getrefcount(enc_hook) == orig_refcount def test_encode_enc_hook_errors(self): def enc_hook(x): raise TypeError("bad") orig_refcount = sys.getrefcount(enc_hook) with pytest.raises(TypeError, match="bad"): msgspec.json.encode(object(), enc_hook=enc_hook) assert sys.getrefcount(enc_hook) == orig_refcount def test_encode_parse_arguments_errors(self): with pytest.raises(TypeError, match="Missing 1 required argument"): msgspec.json.encode() with pytest.raises(TypeError, match="Extra positional arguments"): msgspec.json.encode(1, lambda x: None) with pytest.raises(TypeError, match="Extra positional arguments"): msgspec.json.encode(1, 2, 3) with pytest.raises(TypeError, match="Extra keyword arguments"): msgspec.json.encode(1, bad=1) with pytest.raises(TypeError, match="Extra keyword arguments"): msgspec.json.encode(1, enc_hook=lambda x: None, extra="extra") class TestEncoderMisc: def rec_obj1(self): o = [] o.append(o) return o def rec_obj2(self): o = ([],) o[0].append(o) return o def rec_obj3(self): o = {} o["a"] = o return o def rec_obj4(self): class Box(msgspec.Struct): a: Box o = Box(None) o.a = o return o @pytest.mark.parametrize("case", [1, 2, 3, 4]) @emscripten_stack_limited def test_encode_infinite_recursive_object_errors(self, case): enc = msgspec.json.Encoder() o = getattr(self, "rec_obj%d" % case)() with pytest.raises(RecursionError): enc.encode(o) def test_encode_no_enc_hook(self): class Foo: pass enc = msgspec.json.Encoder() assert enc.enc_hook is None with pytest.raises( TypeError, match="Encoding objects of type Foo is unsupported" ): enc.encode(Foo()) def test_encode_enc_hook(self): unsupported = object() def enc_hook(x): assert x is unsupported return "hello" orig_refcount = sys.getrefcount(enc_hook) enc = msgspec.json.Encoder(enc_hook=enc_hook) assert enc.enc_hook is enc_hook assert sys.getrefcount(enc.enc_hook) == orig_refcount + 2 assert sys.getrefcount(enc_hook) == orig_refcount + 1 res = enc.encode(unsupported) assert enc.encode("hello") == res del enc assert sys.getrefcount(enc_hook) == orig_refcount def test_encode_enc_hook_errors(self): def enc_hook(x): raise TypeError("bad") enc = msgspec.json.Encoder(enc_hook=enc_hook) with pytest.raises(TypeError, match="bad"): enc.encode(object()) def test_encode_enc_hook_recurses(self): class Node: def __init__(self, a): self.a = a def enc_hook(x): return {"type": "Node", "a": x.a} enc = msgspec.json.Encoder(enc_hook=enc_hook) msg = enc.encode(Node(Node(1))) res = json.loads(msg) assert res == {"type": "Node", "a": {"type": "Node", "a": 1}} @emscripten_stack_limited def test_encode_enc_hook_recursion_error(self): enc = msgspec.json.Encoder(enc_hook=lambda x: x) with pytest.raises(RecursionError): enc.encode(object()) def test_encode_into_bad_arguments(self): enc = msgspec.json.Encoder() with pytest.raises(TypeError, match="bytearray"): enc.encode_into(1, b"test") with pytest.raises(TypeError): enc.encode_into(1, bytearray(), "bad") with pytest.raises(TypeError): enc.encode_into(1, bytearray(), None) with pytest.raises(ValueError, match="offset"): enc.encode_into(1, bytearray(), -2) @pytest.mark.parametrize("buf_size", [0, 1, 16, 55, 60]) def test_encode_into(self, buf_size): enc = msgspec.json.Encoder() msg = {"key": "x" * 48} encoded = msgspec.json.encode(msg) buf = bytearray(buf_size) out = enc.encode_into(msg, buf) assert out is None assert buf == encoded def test_encode_into_offset(self): enc = msgspec.json.Encoder() msg = {"key": "value"} encoded = enc.encode(msg) # Offset 0 is default buf = bytearray() enc.encode_into(msg, buf, 0) assert buf == encoded # Offset in bounds uses the provided offset buf = bytearray(b"01234") enc.encode_into(msg, buf, 2) assert buf == b"01" + encoded # Offset out of bounds extends buf = bytearray(b"01234") enc.encode_into(msg, buf, 10) assert buf[:5] == b"01234" assert buf[10:] == encoded # Offset -1 means append at end buf = bytearray(b"01234") enc.encode_into(msg, buf, -1) assert buf == b"01234" + encoded def test_encode_into_handles_errors_properly(self): enc = msgspec.json.Encoder() out1 = enc.encode([1, 2, 3]) msg = [1, 2, object()] buf = bytearray() with pytest.raises(TypeError): enc.encode_into(msg, buf) assert buf # buffer isn't reset upon error # Encoder still works out2 = enc.encode([1, 2, 3]) assert out1 == out2 @pytest.mark.parametrize("n", range(3)) @pytest.mark.parametrize("iterable", [False, True]) def test_encode_lines(self, n, iterable): class custom: def __init__(self, x): self.x = x def __str__(self): return f"<{self.x}>" enc = msgspec.json.Encoder(enc_hook=str) items = [{"x": i, "y": custom(i)} for i in range(n)] sol = b"".join(enc.encode(i) + b"\n" for i in items) if iterable: items = (i for i in items) res = enc.encode_lines(items) assert res == sol @pytest.mark.parametrize("iterable", [False, True]) def test_encode_lines_iterable_unsupported_item_errors(self, iterable): enc = msgspec.json.Encoder() def gen(): yield 1 yield object() items = gen() if iterable else list(gen()) with pytest.raises(TypeError): enc.encode_lines(items) def test_encode_lines_iterable_iter_error(self): enc = msgspec.json.Encoder() class noiter: def __iter__(self): raise ValueError("Oh no!") with pytest.raises(ValueError, match="Oh no!"): enc.encode_lines(noiter()) def test_encode_lines_iterable_next_error(self): enc = msgspec.json.Encoder() def gen(): yield 1 raise ValueError("Oh no!") with pytest.raises(ValueError, match="Oh no!"): enc.encode_lines(gen()) class TestDecodeFunction: def test_decode(self): assert msgspec.json.decode(b"[1, 2, 3]") == [1, 2, 3] def test_decode_from_str(self): assert msgspec.json.decode("[1, 2, 3]") == [1, 2, 3] with pytest.raises(msgspec.DecodeError, match="truncated"): assert msgspec.json.decode("[1, 2, 3") def test_decode_type_keyword(self): assert msgspec.json.decode(b"[1, 2, 3]", type=set[int]) == {1, 2, 3} with pytest.raises(msgspec.ValidationError): assert msgspec.json.decode(b"[1, 2, 3]", type=set[str]) def test_decode_type_any(self): assert msgspec.json.decode(b"[1, 2, 3]", type=Any) == [1, 2, 3] @pytest.mark.parametrize("array_like", [False, True]) def test_decode_type_struct(self, array_like): class Point(msgspec.Struct, array_like=array_like): x: int y: int msg = msgspec.json.encode(Point(1, 2)) for _ in range(2): assert msgspec.json.decode(msg, type=Point) == Point(1, 2) def test_decode_type_struct_invalid_type(self): class Test(msgspec.Struct): x: 1 with pytest.raises(TypeError): msgspec.json.decode(b"{}", type=Test) def test_decode_invalid_type(self): with pytest.raises(TypeError, match="Type '1' is not supported"): msgspec.json.decode(b"[]", type=1) def test_decode_invalid_buf(self): with pytest.raises(TypeError): msgspec.json.decode(1) def test_decode_parse_arguments_errors(self): buf = b"[1, 2, 3]" with pytest.raises(TypeError, match="Missing 1 required argument"): msgspec.json.decode() with pytest.raises(TypeError, match="Extra positional arguments"): msgspec.json.decode(buf, list[int]) with pytest.raises(TypeError, match="Extra positional arguments"): msgspec.json.decode(buf, 2, 3) with pytest.raises(TypeError, match="Extra keyword arguments"): msgspec.json.decode(buf, bad=1) with pytest.raises(TypeError, match="Extra keyword arguments"): msgspec.json.decode(buf, type=list[int], extra=1) def test_decode_with_trailing_characters_errors(self): with pytest.raises(msgspec.DecodeError): msgspec.json.decode(b'[1, 2, 3]"trailing"') class TestDecoderMisc: def test_decode_from_str(self): dec = msgspec.json.Decoder() assert dec.decode("[1, 2, 3]") == [1, 2, 3] with pytest.raises(msgspec.DecodeError, match="truncated"): assert dec.decode("[1, 2, 3") def test_decoder_type_attribute(self): dec = msgspec.json.Decoder() assert dec.type is Any dec = msgspec.json.Decoder(int) assert dec.type is int def test_decoder_repr(self): typ = list[dict[str, float]] dec = msgspec.json.Decoder(typ) assert repr(dec) == f"msgspec.json.Decoder({typ!r})" dec = msgspec.json.Decoder() assert repr(dec) == f"msgspec.json.Decoder({Any!r})" def test_decode_with_trailing_characters_errors(self): dec = msgspec.json.Decoder() with pytest.raises(msgspec.DecodeError): dec.decode(b'[1, 2, 3]"trailing"') @pytest.mark.parametrize( "msg", ["", "\n", "1", " 1", "1\t\r\n", "1\n\r\t 2", "1\n2\n", "1\n2\n3\n"], ) def test_decode_lines(self, msg): dec = msgspec.json.Decoder() sol = [] for part in msg.splitlines(): if part := part.strip(): sol.append(dec.decode(part)) res = dec.decode_lines(msg) assert res == sol def test_decode_lines_typed(self): class Ex(msgspec.Struct): x: int sol = [Ex(1), Ex(2)] buf = msgspec.json.Encoder().encode_lines(sol) res = msgspec.json.Decoder(Ex).decode_lines(buf) assert res == sol def test_decode_lines_typed_error(self): class Ex(msgspec.Struct): x: int buf = b'{"x": 1}\n{"x": "bad"}\n' dec = msgspec.json.Decoder(Ex) with pytest.raises(msgspec.ValidationError) as rec: dec.decode_lines(buf) assert "Expected `int`, got `str`" in str(rec.value) assert "`$[1].x" in str(rec.value) def test_decode_lines_malformed(self): buf = b'{"x": 1}\n{"x": efg' dec = msgspec.json.Decoder() with pytest.raises(msgspec.DecodeError, match="malformed"): dec.decode_lines(buf) def test_decode_lines_bad_call(self): dec = msgspec.json.Decoder() with pytest.raises(TypeError): dec.decode() with pytest.raises(TypeError): dec.decode("{}", 2) with pytest.raises(TypeError): dec.decode(1) def test_decoder_init_float_hook(self): dec = msgspec.json.Decoder() assert dec.float_hook is None dec = msgspec.json.Decoder(float_hook=None) assert dec.float_hook is None dec = msgspec.json.Decoder(float_hook=decimal.Decimal) assert dec.float_hook is decimal.Decimal with pytest.raises(TypeError): dec = msgspec.json.Decoder(float_hook=1) class TestBoolAndNone: def test_encode_none(self): assert msgspec.json.encode(None) == b"null" def test_decode_none(self): assert msgspec.json.decode(b"null") is None assert msgspec.json.decode(b" null ") is None @pytest.mark.parametrize("s", [b"nul", b"nulll", b"nuul", b"nulp"]) def test_decode_none_malformed(self, s): with pytest.raises(msgspec.DecodeError): msgspec.json.decode(s) def test_decode_none_typed(self): with pytest.raises( msgspec.ValidationError, match="Expected `int | null`, got `str`" ): msgspec.json.decode(b'"test"', type=int | None) def test_encode_true(self): assert msgspec.json.encode(True) == b"true" def test_decode_true(self): assert msgspec.json.decode(b"true") is True assert msgspec.json.decode(b" true ") is True @pytest.mark.parametrize("s", [b"tru", b"truee", b"trru", b"trup"]) def test_decode_true_malformed(self, s): with pytest.raises(msgspec.DecodeError): msgspec.json.decode(s) def test_encode_false(self): assert msgspec.json.encode(False) == b"false" def test_decode_false(self): assert msgspec.json.decode(b"false") is False assert msgspec.json.decode(b" false ") is False @pytest.mark.parametrize("s", [b"fals", b"falsee", b"faase", b"falsp"]) def test_decode_false_malformed(self, s): with pytest.raises(msgspec.DecodeError): msgspec.json.decode(s) def test_decode_bool_typed(self): with pytest.raises(msgspec.ValidationError, match="Expected `bool`, got `str`"): msgspec.json.decode(b'"test"', type=bool) class TestStrings: STRINGS = [ ("", b'""'), ("a", b'"a"'), (" a b c d", b'" a b c d"'), ("123 á 456", b'"123 \xc3\xa1 456"'), ("á 456", b'"\xc3\xa1 456"'), ("123 á", b'"123 \xc3\xa1"'), ("123 � 456", b'"123 \xf0\x9d\x84\x9e 456"'), ("� 456", b'"\xf0\x9d\x84\x9e 456"'), ("123 �", b'"123 \xf0\x9d\x84\x9e"'), ('123 \b\n\f\r\t"\\ 456', b'"123 \\b\\n\\f\\r\\t\\"\\\\ 456"'), ('\b\n\f\r\t"\\ 456', b'"\\b\\n\\f\\r\\t\\"\\\\ 456"'), ('123 \b\n\f\r\t"\\', b'"123 \\b\\n\\f\\r\\t\\"\\\\"'), ("123 \x01\x02\x03 456", b'"123 \\u0001\\u0002\\u0003 456"'), ("\x01\x02\x03 456", b'"\\u0001\\u0002\\u0003 456"'), ("123 \x01\x02\x03", b'"123 \\u0001\\u0002\\u0003"'), ] @pytest.mark.parametrize("decoded, encoded", STRINGS) def test_encode_str(self, decoded, encoded): assert msgspec.json.encode(decoded) == encoded @pytest.mark.parametrize("length", [*range(1, 17), 25, 33, 63, 255]) @pytest.mark.parametrize("esc1", ["\n", "\x01"]) @pytest.mark.parametrize("esc2", ["\n", "\x01"]) @pytest.mark.parametrize("adjacent", [False, True]) def test_encode_str_unroll_escapes(self, length, esc1, esc2, adjacent): """Exercise all the branches in the unrolled loops in the JSON str encoding functions""" base = list(itertools.islice(itertools.cycle(string.ascii_letters), length)) if adjacent: def gen(): for i in range(length - 1): s = base.copy() s[i] = esc1 s[i + 1] = esc2 yield "".join(s) else: def gen(): for i in range(length): s = base.copy() s[i] = esc1 if i + 2 < length: s[i + 2] = esc2 else: s[0] = esc2 yield "".join(s) for s in gen(): sol = json.dumps(s, ensure_ascii=False).encode("utf-8") res = msgspec.json.encode(s) assert res == sol @pytest.mark.parametrize("decoded, encoded", STRINGS) def test_decode_str(self, decoded, encoded): assert msgspec.json.decode(encoded) == decoded @pytest.mark.parametrize( "decoded, encoded", [ ("123 � 456", b'"123 \\u00C1 456"'), ("� 456", b'"\\u00C1 456"'), ("123 �", b'"123 \\u00C1"'), ("123 � 456", b'"123 \\ud834\\udd1e 456"'), ("� 456", b'"\\ud834\\udd1e 456"'), ("123 �", b'"123 \\ud834\\udd1e"'), ("123 � 456", b'"123 \\uD834\\uDD1E 456"'), ], ) def test_decode_str_unicode_escapes(self, decoded, encoded): assert msgspec.json.decode(encoded) == decoded @pytest.mark.parametrize( "s, error", [ (b'"\\u00cz 123"', "invalid character in unicode escape"), (b'"\\ud834\\uddz0 123"', "invalid character in unicode escape"), (b'"\\ud834"', "truncated"), (b'"\\ud834 1234567"', "unexpected end of escaped utf-16 surrogate pair"), (b'"\\udc00"', "invalid utf-16 surrogate pair"), (b'"\\udfff"', "invalid utf-16 surrogate pair"), (b'"\\ud834\\udb99"', "invalid utf-16 surrogate pair"), (b'"\\ud834\\ue000"', "invalid utf-16 surrogate pair"), (b'"\\v"', "invalid escape character in string"), ], ) def test_decode_str_malformed_escapes(self, s, error): with pytest.raises(msgspec.DecodeError, match=error): msgspec.json.decode(s) def test_decode_str_invalid_byte(self): with pytest.raises(msgspec.DecodeError, match="invalid character"): msgspec.json.decode(b'"123 \x00 456"') with pytest.raises(msgspec.DecodeError, match="invalid character"): msgspec.json.decode(b'"123 \x01 456"') def test_decode_str_missing_closing_quote(self): with pytest.raises(msgspec.DecodeError, match="truncated"): msgspec.json.decode(b'"test') @pytest.mark.parametrize("length", range(10)) @pytest.mark.parametrize("in_list", [False, True]) @pytest.mark.parametrize("unicode", [False, True]) @pytest.mark.parametrize("escape", [False, True]) def test_decode_str_lengths(self, length, in_list, unicode, escape): """A test designed to get full coverage of the unrolled loops in the string parsing routine""" if unicode: prefix = "�\n�\t\n��" if escape else "��" else: prefix = "a\nb\t\ncd" if escape else "" s = prefix + string.ascii_letters[:length] sol = [s, 1] if in_list else s buf = msgspec.json.encode(sol) res = msgspec.json.decode(buf) assert res == sol left, _, right = buf.rpartition(b'"') buf2 = left + b'\x01"' + right with pytest.raises(msgspec.DecodeError, match="invalid character"): msgspec.json.decode(buf2) # Test str skipping class Test(msgspec.Struct): x: int buf3 = msgspec.json.encode({"y": sol, "x": 1}) msgspec.json.decode(buf3, type=Test) class TestBinary: @pytest.mark.parametrize( "x", [b"", b"a", b"ab", b"abc", b"abcd", b"abcde", b"abcdef", b"\x00\xff"] ) @pytest.mark.parametrize("type", [bytes, bytearray, memoryview]) def test_encode_binary(self, x, type): x = type(x) s = msgspec.json.encode(x) expected = b'"' + base64.b64encode(x) + b'"' assert s == expected @pytest.mark.parametrize( "x", [b"", b"a", b"ab", b"abc", b"abcd", b"abcde", b"abcdef", b"\x00\xff"] ) @pytest.mark.parametrize("type", [bytes, bytearray, memoryview]) def test_decode_binary(self, x, type): s = b'"' + base64.b64encode(x) + b'"' res = msgspec.json.decode(s, type=type) assert res == bytes(x) assert isinstance(res, type) @pytest.mark.parametrize("n", [1023, 1024, 1025]) def test_roundtrip_random(self, n, rand): for _ in range(10): x = rand.bytes(n) s = msgspec.json.encode(x) x2 = msgspec.json.decode(s, type=bytes) assert x == x2 @pytest.mark.parametrize( "s", [b'"Y"', b'"YQ"', b'"YQ="', b'"YQI"', b'"YQI=="', b'"YQJj="', b'"AB*D"'] ) def test_malformed_base64_encoding(self, s): with pytest.raises( msgspec.ValidationError, match="Invalid base64 encoded string" ): msgspec.json.decode(s, type=bytes) class TestDatetime: def test_encode_datetime(self): # All fields, zero padded x = datetime.datetime(1, 2, 3, 4, 5, 6, 7, UTC) s = msgspec.json.encode(x) assert s == b'"0001-02-03T04:05:06.000007Z"' # All fields, no zeros x = datetime.datetime(1234, 12, 31, 14, 56, 27, 123456, UTC) s = msgspec.json.encode(x) assert s == b'"1234-12-31T14:56:27.123456Z"' def test_encode_datetime_no_microsecond(self): x = datetime.datetime(1234, 12, 31, 14, 56, 27, 0, UTC) s = msgspec.json.encode(x) assert s == b'"1234-12-31T14:56:27Z"' @pytest.mark.parametrize( "dt, sol", [ (datetime.datetime(1, 2, 3, 4, 5, 6), b'"0001-02-03T04:05:06"'), (datetime.datetime(1234, 12, 31, 14, 56, 27, 0), b'"1234-12-31T14:56:27"'), ( datetime.datetime(1234, 12, 31, 14, 56, 27, 7), b'"1234-12-31T14:56:27.000007"', ), ( datetime.datetime(1234, 12, 31, 14, 56, 27, 123456), b'"1234-12-31T14:56:27.123456"', ), ], ) def test_encode_datetime_naive(self, dt, sol): res = msgspec.json.encode(dt) assert res == sol @pytest.mark.parametrize( "offset", [ datetime.timedelta(0), datetime.timedelta(days=1, microseconds=-1), datetime.timedelta(days=-1, microseconds=1), datetime.timedelta(days=1, seconds=-29), datetime.timedelta(days=-1, seconds=29), datetime.timedelta(days=0, seconds=30), datetime.timedelta(days=0, seconds=-30), ], ) def test_encode_datetime_offset_is_appx_equal_to_utc(self, offset): tz = datetime.timezone(offset) x = datetime.datetime(1234, 12, 31, 14, 56, 27, 123456, tz) s = msgspec.json.encode(x) assert s == b'"1234-12-31T14:56:27.123456Z"' @pytest.mark.parametrize( "offset, expected", [ ( datetime.timedelta(days=1, seconds=-30), b'"1234-12-31T14:56:27.123456+23:59"', ), ( datetime.timedelta(days=-1, seconds=30), b'"1234-12-31T14:56:27.123456-23:59"', ), ( datetime.timedelta(minutes=19, seconds=32, microseconds=130000), b'"1234-12-31T14:56:27.123456+00:20"', ), ], ) def test_encode_datetime_offset_rounds_to_nearest_minute(self, offset, expected): tz = datetime.timezone(offset) x = datetime.datetime(1234, 12, 31, 14, 56, 27, 123456, tz) s = msgspec.json.encode(x) assert s == expected def test_encode_datetime_zoneinfo(self): import zoneinfo try: x = datetime.datetime( 2023, 1, 2, 3, 4, 5, 678, zoneinfo.ZoneInfo("America/Chicago") ) except zoneinfo.ZoneInfoNotFoundError: # Some envs in CI do not have `tzdata`: pytest.skip(reason="Failed to load timezone") sol = msgspec.json.encode(x.isoformat()) res = msgspec.json.encode(x) assert res == sol @pytest.mark.parametrize( "dt", [ "0001-02-03T04:05:06.000007", "0001-02-03T04:05:06.007", "0001-02-03T04:05:06", "2021-12-11T21:19:22.123456", ], ) @pytest.mark.parametrize("suffix", ["Z", "+00:00", "-00:00"]) def test_decode_datetime_utc(self, dt, suffix): dt += suffix exp = datetime.datetime.fromisoformat(dt.replace("Z", "+00:00")) s = f'"{dt}"'.encode() res = msgspec.json.decode(s, type=datetime.datetime) assert res == exp @pytest.mark.parametrize( "dt", [ "2000-12-31T12:00:01", "2000-01-01T00:00:01", "2000-01-31T12:01:01", "2000-02-01T12:01:01", "2000-02-28T12:01:01", "2000-02-29T12:01:01", "2000-03-01T12:01:01", ], ) @pytest.mark.parametrize("sign", ["-", "+"]) @pytest.mark.parametrize("hour", [0, 8, 12, 16, 23]) @pytest.mark.parametrize("minute", [0, 30]) def test_decode_datetime_with_timezone(self, dt, sign, hour, minute): s = f"{dt}{sign}{hour:02}:{minute:02}" json_s = f'"{s}"'.encode() exp = datetime.datetime.fromisoformat(s) res = msgspec.json.decode(json_s, type=datetime.datetime) assert res == exp @pytest.mark.skipif( hasattr(sys.flags, "gil") and not sys.flags.gil, reason="cache is disabled without GIL", ) def test_decode_timezone_cache(self): msg = b'"2000-01-01T00:00:01+03:02"' tz = msgspec.json.decode(msg, type=datetime.datetime).tzinfo tz2 = msgspec.json.decode(msg, type=datetime.datetime).tzinfo assert tz is tz2 del tz2 assert sys.getrefcount(tz) <= 3 # 1 tz, 1 cache, 1 func call for _ in range(10): gc.collect() # cache is cleared every 10 full collections # Since tz still has refcnt > 1, shouldn't be cleared tz2 = msgspec.json.decode(msg, type=datetime.datetime).tzinfo assert tz is tz2 @pytest.mark.parametrize( "s", [ "1234-01-02T03:04:05", "1234-01-02T03:04:05.123", "1234-01-02T03:04:05.123456", ], ) def test_decode_datetime_naive(self, s): sol = datetime.datetime.fromisoformat(s) msg = f'"{s}"'.encode() res = msgspec.json.decode(msg, type=datetime.datetime) assert sol == res @pytest.mark.parametrize("t", ["T", "t"]) @pytest.mark.parametrize("z", ["Z", "z"]) def test_decode_datetime_not_case_sensitive(self, t, z): """Both T & Z can be upper/lowercase""" s = f'"0001-02-03{t}04:05:06.000007{z}"'.encode() exp = datetime.datetime(1, 2, 3, 4, 5, 6, 7, UTC) res = msgspec.json.decode(s, type=datetime.datetime) assert res == exp def test_decode_min_datetime(self): res = msgspec.json.decode(b'"0001-01-01T00:00:00Z"', type=datetime.datetime) exp = datetime.datetime.min.replace(tzinfo=UTC) assert res == exp def test_decode_max_datetime(self): res = msgspec.json.decode( b'"9999-12-31T23:59:59.999999Z"', type=datetime.datetime ) exp = datetime.datetime.max.replace(tzinfo=UTC) assert res == exp @pytest.mark.parametrize( "msg, sol", [ ( b'"2022-01-02T03:04:05.1234564Z"', datetime.datetime(2022, 1, 2, 3, 4, 5, 123456, UTC), ), ( b'"2022-01-02T03:04:05.1234565Z"', datetime.datetime(2022, 1, 2, 3, 4, 5, 123457, UTC), ), ( b'"2022-01-02T03:04:05.12345650000000000001Z"', datetime.datetime(2022, 1, 2, 3, 4, 5, 123457, UTC), ), ( b'"2022-01-02T03:04:05.9999995Z"', datetime.datetime(2022, 1, 2, 3, 4, 6, 0, UTC), ), ( b'"2022-01-02T03:04:59.9999995Z"', datetime.datetime(2022, 1, 2, 3, 5, 0, 0, UTC), ), ( b'"2022-01-02T03:59:59.9999995Z"', datetime.datetime(2022, 1, 2, 4, 0, 0, 0, UTC), ), ( b'"2022-01-02T23:59:59.9999995Z"', datetime.datetime(2022, 1, 3, 0, 0, 0, 0, UTC), ), ( b'"2022-02-28T23:59:59.9999995Z"', datetime.datetime(2022, 3, 1, 0, 0, 0, 0, UTC), ), ], ) def test_decode_datetime_nanos(self, msg, sol): res = msgspec.json.decode(msg, type=datetime.datetime) assert res == sol @pytest.mark.parametrize( "lax, strict", [ ("2022-01-02T03:04:05+0102", "2022-01-02T03:04:05+01:02"), ("2022-01-02T03:04:05-0102", "2022-01-02T03:04:05-01:02"), ("2022-01-02 03:04:05", "2022-01-02T03:04:05"), ], ) def test_decode_datetime_rfc3339_relaxed(self, lax, strict): """msgspec supports a few relaxations of the RFC3339 format.""" sol = datetime.datetime.fromisoformat(strict) msg = msgspec.json.encode(lax) res = msgspec.json.decode(msg, type=datetime.datetime) assert res == sol @pytest.mark.parametrize( "s", [ # Incorrect field lengths b'"001-02-03T04:05:06.000007Z"', b'"0001-2-03T04:05:06.000007Z"', b'"0001-02-3T04:05:06.000007Z"', b'"0001-02-03T4:05:06.000007Z"', b'"0001-02-03T04:5:06.000007Z"', b'"0001-02-03T04:05:6.000007Z"', b'"0001-02-03T04:05:06.000007+0:00"', b'"0001-02-03T04:05:06.000007+00:0"', b'"0001-02-03T04:05:06.000007+000"', # Trailing data b'"0001-02-03T04:05:06.000007+00:000"', b'"0001-02-03T04:05:06.000007+00000"', b'"0001-02-03T04:05:06.000007Z0"', b'"0001-02-03T04:05:06a"', b'"0001-02-03T04:05:06.000007a"', # Truncated b'"0001-02-03T04:05:"', # Missing +/- b'"0001-02-03T04:05:06.00000700:00"', # Missing digits after decimal b'"0001-02-03T04:05:06."', b'"0001-02-03T04:05:06.Z"', # Invalid characters b'"000a-02-03T04:05:06.000007Z"', b'"0001-0a-03T04:05:06.000007Z"', b'"0001-02-0aT04:05:06.000007Z"', b'"0001-02-03T0a:05:06.000007Z"', b'"0001-02-03T04:0a:06.000007Z"', b'"0001-02-03T04:05:0a.000007Z"', b'"0001-02-03T04:05:06.00000aZ"', b'"0001-02-03T04:05:06.000007a"', b'"0001-02-03T04:05:06.000007+0a:00"', b'"0001-02-03T04:05:06.000007+00:0a"', b'"0001-02-03T04:05:06.000007+0a00"', b'"0001-02-03T04:05:06.000007+000a"', # Year out of range b'"0000-02-03T04:05:06.000007Z"', # Month out of range b'"0001-00-03T04:05:06.000007Z"', b'"0001-13-03T04:05:06.000007Z"', # Day out of range for month b'"0001-02-00T01:05:06.000007Z"', b'"0001-02-29T01:05:06.000007Z"', b'"2000-02-30T01:05:06.000007Z"', # Hour out of range b'"0001-02-03T24:05:06.000007Z"', # Minute out of range b'"0001-02-03T04:60:06.000007Z"', # Second out of range b'"0001-02-03T04:05:60.000007Z"', # Timezone hour out of range b'"0001-02-03T04:05:06.000007+24:00"', b'"0001-02-03T04:05:06.000007-24:00"', # Timezone minute out of range b'"0001-02-03T04:05:06.000007+00:60"', b'"0001-02-03T04:05:06.000007-00:60"', ], ) def test_decode_datetime_malformed(self, s): with pytest.raises(msgspec.ValidationError, match="Invalid RFC3339"): msgspec.json.decode(s, type=datetime.datetime) class TestIntegers: @pytest.mark.parametrize("ndigits", range(21)) def test_encode_int(self, ndigits): if ndigits == 0: s = b"0" else: s = "".join( itertools.islice(itertools.cycle("123456789"), ndigits) ).encode() x = int(s) assert msgspec.json.encode(x) == s if 0 < ndigits < 20: assert msgspec.json.encode(-x) == b"-" + s @pytest.mark.parametrize("x", [-(2**63 + 1), -(2**63), 2**64 - 1, 2**64]) def test_encode_big_integers(self, x): assert msgspec.json.encode(x) == str(x).encode() @pytest.mark.parametrize("ndigits", range(21)) def test_decode_int(self, ndigits): if ndigits == 0: s = b"0" else: s = "".join( itertools.islice(itertools.cycle("123456789"), ndigits) ).encode() x = int(s) assert msgspec.json.decode(s) == x if 0 < ndigits < 20: assert msgspec.json.decode(b"-" + s) == -x @pytest.mark.parametrize("x", [2**63 - 1, 2**63, 2**63 + 1]) def test_decode_int_19_digit_overflow_boundary(self, x): s = str(x).encode("utf-8") # Add extra trailing 0 to ensure no out-of-bounds reads buffer = memoryview(s + b"0")[:-1] assert msgspec.json.decode(buffer) == x @pytest.mark.parametrize("x", [-(2**63), 2**64 - 1]) def test_decode_int_boundaries(self, x): s = str(x).encode() x2 = msgspec.json.decode(s) assert isinstance(x2, int) assert x2 == x @pytest.mark.parametrize( "x", [ -(2**63) - 1, 2**64, 2**64 + 10**18, 2**64 + 10**18 + 1, 19999999999999999999, 20000000000000000000, 2**64 + 10**19, # mantissa overflows to 20 digits 2**64 + 10**19 - 1, -(2**64), -(2**64) + 10**18, -(2**64) + 10**18 + 1, -19999999999999999999, -20000000000000000000, -(2**64 + 10**19), -(2**64 + 10**19 - 1), ], ) @pytest.mark.parametrize("type", [Any, int]) def test_decode_big_int(self, x, type): s = str(x).encode() x2 = msgspec.json.decode(s, type=type) assert isinstance(x2, int) assert x2 == x @pytest.mark.parametrize("max_length", [None, 1000]) def test_decode_big_int_max_length(self, max_length): if max_length is not None: try: orig = sys.get_int_max_str_digits() sys.set_int_max_str_digits(max_length) except AttributeError: # TODO: remove when 3.10 support is dropped: pytest.skip(reason="sys.set_int_max_str_digits is not available") def cleanup(): sys.set_int_max_str_digits(orig) s = "1" * (max_length + 1) else: cleanup = None s = "1" * 4301 try: with pytest.raises( msgspec.ValidationError, match="Integer value out of range" ): msgspec.json.decode(s, type=int) finally: if cleanup: cleanup() @pytest.mark.parametrize("s", [b" 123 ", b" -123 "]) def test_decode_int_whitespace(self, s): assert msgspec.json.decode(s) == int(s) @pytest.mark.parametrize("s", [b"- 123", b"-n123", b"1 2", b"12n3", b"123n"]) def test_decode_int_malformed(self, s): with pytest.raises(msgspec.DecodeError): msgspec.json.decode(s) def test_decode_int_converts_to_float_if_requested(self): x = msgspec.json.decode(b"123", type=float) assert isinstance(x, float) assert x == 123.0 x = msgspec.json.decode(b"-123", type=float) assert isinstance(x, float) assert x == -123.0 def test_decode_int_type_error(self): with pytest.raises(msgspec.ValidationError, match="Expected `str`, got `int`"): msgspec.json.decode(b"123", type=str) class TestLiteral: @pytest.mark.parametrize( "values", [ (1, 2, 3), ("one", "two", "three"), (1, 2, "three", "four"), (1, None), ("one", None), (True,), (False,), (True, False), (True, 1, "yes"), ], ) def test_literal(self, values): literal = Literal[values] dec = msgspec.json.Decoder(literal) for val in values: assert dec.decode(msgspec.json.encode(val)) == val for bad in ["bad", 1234]: with pytest.raises(msgspec.ValidationError): dec.decode(msgspec.json.encode(bad)) def test_int_literal_errors(self): dec = msgspec.json.Decoder(Literal[1, 2, 3]) with pytest.raises(msgspec.ValidationError, match="Invalid enum value 4"): dec.decode(b"4") with pytest.raises(msgspec.ValidationError, match="Expected `int`, got `str`"): dec.decode(b'"bad"') def test_str_literal_errors(self): dec = msgspec.json.Decoder(Literal["one", "two", "three"]) with pytest.raises(msgspec.ValidationError, match="Expected `str`, got `int`"): dec.decode(b"4") with pytest.raises(msgspec.ValidationError, match="Invalid enum value 'bad'"): dec.decode(b'"bad"') def test_bool_literal_true_only(self): dec = msgspec.json.Decoder(Literal[True]) assert dec.decode(b"true") is True with pytest.raises(msgspec.ValidationError, match="Invalid enum value False"): dec.decode(b"false") def test_bool_literal_false_only(self): dec = msgspec.json.Decoder(Literal[False]) assert dec.decode(b"false") is False with pytest.raises(msgspec.ValidationError, match="Invalid enum value True"): dec.decode(b"true") def test_bool_literal_errors(self): dec = msgspec.json.Decoder(Literal[True]) with pytest.raises(msgspec.ValidationError, match="Expected `bool`, got `int`"): dec.decode(b"42") with pytest.raises(msgspec.ValidationError, match="Expected `bool`, got `str`"): dec.decode(b'"hello"') with pytest.raises( msgspec.ValidationError, match="Expected `bool`, got `null`" ): dec.decode(b"null") class TestFloat: @pytest.mark.parametrize( "x", [ 0.1 + 0.2, -0.1 - 0.2, 1.0, -1.0, sys.float_info.min, sys.float_info.max, 1.0 / 3, 2.0**-24, 2.0**-14, 2.0**-149, 2.0**-126, sys.float_info.min / 2, sys.float_info.min / 10, sys.float_info.min / 1000, sys.float_info.min / 100000, 5e-324, 2.9802322387695312e-8, 2.109808898695963e16, 4.940656e-318, 1.18575755e-316, 2.989102097996e-312, 9.0608011534336e15, 4.708356024711512e18, 9.409340012568248e18, 1.2345678, 5.764607523034235e39, 1.152921504606847e40, 2.305843009213694e40, 4.294967294, 4.294967295, 4.294967296, 4.294967297, 4.294967298, 1.7800590868057611e-307, 2.8480945388892175e-306, 2.446494580089078e-296, 4.8929891601781557e-296, 1.8014398509481984e16, 3.6028797018963964e16, 2.900835519859558e-216, 5.801671039719115e-216, 3.196104012172126e-27, 9.007199254740991e15, 9.007199254740992e15, 3.1462737709539517e18, ], ) def test_roundtrip_float_tricky_cases(self, x): """Tricky float values, many taken from https://github.com/ulfjack/ryu/blob/master/ryu/tests/d2s_test.cc""" s = msgspec.json.encode(x) x2 = msgspec.json.decode(s) assert x == x2 @pytest.mark.parametrize("x", [-0.0, 0.0]) def test_roundtrip_signed_zero(self, x): s = msgspec.json.encode(x) x2 = msgspec.json.decode(s) assert x == x2 assert math.copysign(1.0, x) == math.copysign(1.0, x2) @pytest.mark.parametrize("n", range(-15, 15)) def test_roundtrip_float_powers_10(self, n): x = 10.0**n s = msgspec.json.encode(x) x2 = msgspec.json.decode(s) assert x == x2 @pytest.mark.parametrize("n", range(-15, 14)) def test_roundtrip_float_lots_of_middle_zeros(self, n): x = 1e15 + 10.0**n s = msgspec.json.encode(x) x2 = msgspec.json.decode(s) assert x == x2 @pytest.mark.parametrize("n", range(1, 17)) def test_roundtrip_float_integers(self, n): x = float("".join(itertools.islice(itertools.cycle("123456789"), n))) s = msgspec.json.encode(x) x2 = msgspec.json.decode(s) assert x == x2 @pytest.mark.parametrize("scale", [0.0001, 1, 1000]) @pytest.mark.parametrize("n", range(54)) def test_roundtrip_float_powers_of_2(self, n, scale): x = (2.0**n) * scale s = msgspec.json.encode(x) x2 = msgspec.json.decode(s) assert x == x2 def test_roundtrip_float_random_checks(self, rand): for _ in range(1000): x = rand.float() s = msgspec.json.encode(x) x2 = msgspec.json.decode(s) assert x == x2 @pytest.mark.parametrize( "s", [ str(2**64 - 1).encode(), # 20 digits, no overflow str(2**64).encode(), # 20 digits, overflow str(2**64 + 1).encode(), # 20 digits, overflow str(2**68).encode(), # 21 digits ], ) @pytest.mark.parametrize("i", [-5, 0, 5]) def test_decode_float_long_mantissa(self, s, i): if i > 0: s = s[:i] + b"." + s[i:] elif i == 0: s += b".0" else: s = b"0." + b"0" * (-i) + s x = msgspec.json.decode(s) x2 = msgspec.json.decode(s, type=float) assert float(s) == x == x2 with pytest.raises( msgspec.ValidationError, match="Expected `int`, got `float`" ): msgspec.json.decode(s, type=int) @pytest.mark.parametrize("n", [5, 20, 300, 500]) def test_decode_float_lots_of_leading_zeros(self, n): s = b"0." + b"0" * n + b"123" x = msgspec.json.decode(s) x2 = msgspec.json.decode(s, type=float) assert x == x2 == float(s) @pytest.mark.parametrize("n", [5, 20, 300, 500]) def test_decode_float_lots_of_middle_leading_zeros(self, n): s = b"1." + b"0" * n + b"123" x = msgspec.json.decode(s) x2 = msgspec.json.decode(s, type=float) assert x == x2 == float(s) @pytest.mark.parametrize("prefix", [b"0", b"0.0", b"0.0001", b"123", b"123.000"]) @pytest.mark.parametrize("e", [b"e", b"E"]) @pytest.mark.parametrize("sign", [b"+", b"-", b""]) @pytest.mark.parametrize("exp", [b"0", b"000", b"12", b"300"]) def test_decode_float_with_exponent(self, prefix, e, sign, exp): s = prefix + e + sign + exp x = msgspec.json.decode(s) x2 = msgspec.json.decode(s, type=float) assert x == x2 == float(s) def test_decode_float_long_decimal_large_exponent(self): s = b"0." + b"0" * 500 + b"123e500" x = msgspec.json.decode(s) assert x == float(s) @pytest.mark.parametrize("s", [b"123e308", b"-123e308", b"123e50000", b"123e50000"]) def test_decode_float_boundaries_errors(self, s): with pytest.raises(msgspec.ValidationError, match="Number out of range"): msgspec.json.decode(s) @pytest.mark.parametrize( "s", [ "-2.2222222222223e-322", "9007199254740993.0", "860228122.6654514319E+90", "10000000000000000000", "10000000000000000000000000000001000000000000", "10000000000000000000000000000000000000000001", "1.1920928955078125e-07", ( "9355950000000000000.0000000000000000000000000000000000184467440737095516160000" "018446744073709551616184467440737095516140737095516161844674407370955161600018" "446744073709551616600000184467440737095516161844674407370955161407370955161618" "446744073709551616000184467440737095516160184467440737095567445161618446744073" "709551614073709551616184467440737095516160001844674407370955161601844674407370" "955161161600018446744073709500184467440737095516160018446744073709551616001844" "674407370955116816446744073709551616000184407370955161601844674407370955161618" "446744073709551616000184467440753691075160161161600018446744073709500184467440" "737095516160018446744073709551616001844674407370955161618446744073709551616000" "1844955161618446744073709551616000184467440753691075160018446744073709" ), ( "2.2250738585072021241887014792022203290724052827943903781430313383743510731924" "419468675440643256388185138218821850243806999994773301300564988410779192874134" "192929720097048195199306799329096904278406473168204156592672863293363047467012" "331685298342215274451726083585965456631928283524478778779989431077978383369915" "928859455521371418112845825114558431922307989750439508685941245723089173894616" "936837232119137365897797772328669884035639025104444303545739673370658398105542" "045669382465841374760715598117657387762674766591238719993190400631733470900301" "279018817520344719025002806127777791679839109057858400646471594381051148915428" "277504117468219413395246668250343130618158782937900420539237507208336669324158" "0002758391118854188641513168478436313080237596295773983001708984375e-308" ), "1.0000000000000006661338147750939242541790008544921875", "1090544144181609348835077142190", "2.2250738585072013e-308", "-92666518056446206563E3", "-92666518056446206563E3", "-42823146028335318693e-128", "90054602635948575728E72", ( "1.0000000000000018855892087022346387017456602069175351539464355066307055836837" "3221972569761144603605635692374830246134201063722058e-309" ), "0e9999999999999999999999999999", "-2402844368454405395.2", "2402844368454405395.2", "7.0420557077594588669468784357561207962098443483187940792729600000e+59", "7.0420557077594588669468784357561207962098443483187940792729600000e+59", "-1.7339253062092163730578609458683877051596800000000000000000000000e+42", "-2.0972622234386619214559824785284023792871122537545728000000000000e+52", "-1.0001803374372191849407179462120053338028379051879898808320000000e+57", "-1.8607245283054342363818436991534856973992070520151142825984000000e+58", "-1.9189205311132686907264385602245237137907390376574976000000000000e+52", "-2.8184483231688951563253238886553506793085187889855201280000000000e+54", "-1.7664960224650106892054063261344555646357024359107788800000000000e+53", "-2.1470977154320536489471030463761883783915110400000000000000000000e+45", "-4.4900312744003159009338275160799498340862630046359789166919680000e+61", "1.797693134862315700000000000000001e308", "1.00000006e+09", "4.9406564584124653e-324", "4.9406564584124654e-324", "2.2250738585072009e-308", "2.2250738585072014e-308", "1.7976931348623157e308", "1.7976931348623158e308", "4503599627370496.5", "4503599627475352.5", "4503599627475353.5", "2251799813685248.25", "1125899906842624.125", "1125899906842901.875", "2251799813685803.75", "4503599627370497.5", "45035996.273704995", "45035996.273704985", ( "0.0000000000000000000000000000000000000000000000000000000000000000000000000000" "000000000000000000000000000000000000000000000000000000000000000000000000000000" "000000000000000000000000000000000000000000000000000000000000000000000000000000" "000000000000000000000000000000000000000000000000000000000000000000000000000445" "014771701440227211481959341826395186963909270329129604685221944964444404215389" "103305904781627017582829831782607924221374017287738918929105531441481564124348" "675997628212653465850710457376274429802596224490290377969811444461457051026631" "151003182879495279596682360399864792509657803421416370138126133331198987655154" "514403152612538132666529513060001849177663286607555958373922409899478075565940" "981010216121988146052587425791790000716759993441450860872056815779154359230189" "103349648694206140521828924314457976051636509036065141403772174422625615902446" "685257673724464300755133324500796506867194913776884780053099639677097589658441" "378944337966219939673169362804570848666132067970177289160800206986794085513437" "28867675409720757232455434770912461317493580281734466552734375" ), ( "0.0000000000000000000000000000000000000000000000000000000000000000000000000000" "000000000000000000000000000000000000000000000000000000000000000000000000000000" "000000000000000000000000000000000000000000000000000000000000000000000000000000" "000000000000000000000000000000000000000000000000000000000000000000000000000222" "507385850720088902458687608585988765042311224095946549352480256244000922823569" "517877588880375915526423097809504343120858773871583572918219930202943792242235" "598198275012420417889695713117910822610439719796040004548973919380791989360815" "256131133761498420432717510336273915497827315941438281362751138386040942494649" "422863166954291050802018159266421349966065178030950759130587198464239060686371" "020051087232827846788436319445158661350412234790147923695852083215976210663754" "016137365830441936037147783553066828345356340050740730401356029680463759185831" "631242245215992625464943008368518617194224176464551371354201322170313704965832" "101546540680353974179060225895030235019375197730309457631732108525072993050897" "61582519159720757232455434770912461317493580281734466552734375" ), ( "143845666314139027352611820764223558118322784524633123116263665379036815209139" "419693036582863468763794815794077659918279138752713535303473835713411031060945" "569390082419354977279201654318268051974058035436546798544018359870131225762454" "556233139701832992861319612559027418772007391481806253083031653315809862498411" "888929828137181228878953731059903752911341543873895489475212472498306724110876" "448834645437669901867307840475112141480493722424080599312381693232622368309077" "056159757045779393298582616260425588452913412639628220212652625338938342180672" "795458852559611437980126909409632980505480308929973699687095125857301087740440" "745195384669860919821392688269207855703322826525930548119852605981316446918758" "669325733577952202040764549868426333992190522755661669812996741289128223168550" "466067127792719829000982468018631975097866573457668378425580226970891736171946" "604317520115884909788137047711185017157986905601606166617302905958843377601564" "443970505037755427769614392827809345379280384625271596601673322264644238289212" "394005244134682242972159388437821255870100435692424303005951748934664657772462" "249891975259738209522250031112418182351225107135618176937657765139002829779615" "620881537508915912839494571051586133448626710179749711112590927250519479287088" "961717975870344260801614334326215999814970060659779253557445756042922697427344" "363032381874773077131676339857211087495998192373246307688452867739265415001026" "982223940199342748237651323138921235358357356637691557265091686655361236618737" "895955498356671276709337290603018897622016905802535497362221166650454931695827" "188097569714354656446980679135870731887307570838334500409015197406832583817753" "126695417740666139222980134999469594150993565535565298572378215357008408956013" "9142231.7384750423625968754491545523922995489471381620816941686753406778438076" "131297804493233637590270129724669873709218168131626587547265451210905455072402" "670004565947865409496052607224619378706306348749917293982080264676981318986918" "30012167897399682179601734569071423681e-1500" ), "-2240084132271013504.131248280843119943687942846658579428", ], ids=itertools.count(), ) def test_decode_float_cases_from_fastfloat(self, s): """Some tricky test cases from https://github.com/fastfloat/fast_float/blob/main/tests/basictest.cpp""" x = msgspec.json.decode(s.encode(), type=float) assert x == float(s) @pytest.mark.parametrize("negative", [True, False]) def test_decode_long_float_rounds_to_zero(self, negative): s = b"0." + b"0" * 400 + b"1" if negative: s = b"-" + s x = msgspec.json.decode(s) assert x == 0.0 assert (math.copysign(1.0, x) < 0) == negative @pytest.mark.parametrize( "s", [ "0." + "0" * 900 + "123451e875", "0." + "0" * 900 + "12345" * 40 + "1e875", "0." + "0" * 900 + "12345" * 400 + "1e875", "1" * 30000 + "e-30000", ], ids=itertools.count(), ) def test_decode_long_float_truncated_but_exp_brings_back_in_bounds(self, s): """The digits part of these would put them over the limit to inf, but the exponent bit brings them back in range""" x = msgspec.json.decode(s.encode()) assert x == float(s) @pytest.mark.parametrize( "s, error", [ (b"1.", "invalid number"), (b"1..", "invalid number"), (b"1.2.", "trailing characters"), (b".123", "invalid character"), (b"001.2", "invalid number"), (b"00.2", "invalid number"), (b"1a2", "trailing characters"), (b"1.e2", "invalid number"), (b"1.2e", "invalid number"), (b"1.2e+", "invalid number"), (b"1.2e-", "invalid number"), (b"1.2ea", "invalid number"), (b"1.2e1a", "trailing characters"), (b"1.2e1-2", "trailing characters"), (b"123 456", "trailing characters"), (b"123. 456", "invalid number"), (b"123.456 e2", "trailing characters"), (b"123.456e 2", "invalid number"), ], ) def test_decode_float_malformed(self, s, error): with pytest.raises(msgspec.DecodeError, match=error): msgspec.json.decode(s) @pytest.mark.parametrize( "s, error", [ (b"1" * 25 + b".", "invalid number"), (b"1" * 25 + b".2.", "trailing characters"), (b"1" * 25 + b".e", "invalid number"), (b"1" * 25 + b".e2", "invalid number"), (b"1" * 25 + b".2e", "invalid number"), (b"1" * 25 + b".2e-", "invalid number"), (b"1" * 25 + b".2e+", "invalid number"), (b"1" * 25 + b".2ea", "invalid number"), ], ids=itertools.count(), ) def test_decode_long_float_malformed(self, s, error): with pytest.raises(msgspec.DecodeError, match=error): msgspec.json.decode(s) @pytest.mark.parametrize( "s", [ b"1e500", b"-1e500", b"123456789e301", b"-123456789e301", b"0.01e311", b"-0.01e311", b"1" * 3000 + b"e-2600", b"-" + b"1" * 3000 + b"e-2600", ], ids=itertools.count(), ) def test_decode_float_out_of_bounds(self, s): with pytest.raises(msgspec.ValidationError, match="out of range"): msgspec.json.decode(s) @pytest.mark.parametrize("s", [b"1.23e3", b"1.2", b"1e2"]) def test_decode_float_err_expected_int(self, s): with pytest.raises( msgspec.ValidationError, match="Expected `int`, got `float`" ): msgspec.json.decode(s, type=int) def test_float_hook_untyped(self): dec = msgspec.json.Decoder(float_hook=decimal.Decimal) res = dec.decode(b"1.33") assert res == decimal.Decimal("1.33") assert type(res) is decimal.Decimal def test_float_hook_typed(self): class Ex(msgspec.Struct): a: float b: decimal.Decimal c: Any d: Any class MyFloat(NamedTuple): x: str dec = msgspec.json.Decoder(Ex, float_hook=MyFloat) res = dec.decode(b'{"a": 1.5, "b": 1.3, "c": 1.3, "d": 123}') sol = Ex(1.5, decimal.Decimal("1.3"), MyFloat("1.3"), 123) assert res == sol def test_float_hook_error(self): def float_hook(val): raise ValueError("Oh no!") class Ex(msgspec.Struct): a: float b: Any dec = msgspec.json.Decoder(Ex, float_hook=float_hook) assert dec.decode(b'{"a": 1.5, "b": 2}') == Ex(a=1.5, b=2) with pytest.raises(msgspec.ValidationError) as rec: dec.decode(b'{"a": 1.5, "b": 2.5}') assert "Oh no!" in str(rec.value) assert "at `$.b`" in str(rec.value) class TestDecimal: """Most decimal tests are in test_common.py, the ones here are for json specific behaviors""" def test_decimal_to_number_keeps_precision(self): enc = msgspec.json.Encoder(decimal_format="number") msg = enc.encode(Decimal("1.3000")) assert msg == b"1.3000" @pytest.mark.parametrize( "msg", [ "123", "-123", "1e3", "-1e3", "1.0100", "-1.0100", "0.123456789123456789123456789", "-0.123456789123456789123456789", "123456789123456789123456789", "-123456789123456789123456789", ], ) def test_decimal_from_number_keeps_precision(self, msg): res = msgspec.json.decode(msg, type=Decimal) sol = Decimal(msg) assert res == sol assert str(res) == str(sol) # check trailing 0s @pytest.mark.parametrize( "msg", [ "123_", "123_45", "123._", "123.", "123.45_", "123.45_6", "123456789123456789123456789_", "123456789123456789123456789.", "0.123456789123456789123456789_", ], ) def test_decimal_from_number_still_errors_on_invalid_number(self, msg): """Check that decimal strings that `decimal.Decimal` will happily parse but aren't valid JSON still error as invalid JSON""" Decimal(msg) with pytest.raises(msgspec.DecodeError) as rec: msgspec.json.decode(msg) # not ValidationError, a subclass assert type(rec.value) is msgspec.DecodeError assert "JSON is malformed" in str(rec.value) def test_decimal_from_number_priority(self): posint = "123" negint = "-123" bigint = "123456789" * 3 double = "123.45" extdouble = "123." + ("123456789" * 3) cases = [ (posint, Decimal, Decimal), (negint, Decimal, Decimal), (bigint, Decimal, Decimal), (double, Decimal, Decimal), (extdouble, Decimal, Decimal), (posint, Decimal | int, int), (negint, Decimal | int, int), (bigint, Decimal | int, int), (double, Decimal | int, Decimal), (extdouble, Decimal | int, Decimal), (posint, Decimal | float, float), (negint, Decimal | float, float), (bigint, Decimal | float, float), (double, Decimal | float, float), (extdouble, Decimal | float, float), (posint, Decimal | int | float, int), (negint, Decimal | int | float, int), (bigint, Decimal | int | float, int), (double, Decimal | int | float, float), (extdouble, Decimal | int | float, float), ] for msg, request_type, out_type in cases: out = msgspec.json.decode(msg, type=request_type) assert type(out) is out_type class TestSequences: @pytest.mark.parametrize("x", [[], [1], [1, "two", False]]) @pytest.mark.parametrize("type", [list, set, frozenset, tuple]) def test_roundtrip_sequence(self, x, type): x = type(x) s = msgspec.json.encode(x) x2 = msgspec.json.decode(s, type=type) assert x == x2 assert isinstance(x2, type) @pytest.mark.parametrize( "s, x", [ (b"[\t\n\r ]", []), (b"[\t\n 1\r ]", [1]), (b"[ 1\n ,\t 2\r ]", [1, 2]), (b" \t [\n 1 , 2 \t ]\r ", [1, 2]), ], ) @pytest.mark.parametrize("type", [list, set, frozenset, tuple]) def test_decode_sequence_ignores_whitespace(self, s, x, type): x2 = msgspec.json.decode(s, type=type) assert isinstance(x2, type) assert type(x) == type(x2) def test_decode_typed_list(self): dec = msgspec.json.Decoder(list[int]) assert dec.decode(b"[]") == [] assert dec.decode(b"[1]") == [1] assert dec.decode(b"[1,2]") == [1, 2] def test_decode_typed_set(self): dec = msgspec.json.Decoder(set[int]) assert dec.decode(b"[]") == set() assert dec.decode(b"[1]") == {1} assert dec.decode(b"[1,2]") == {1, 2} def test_decode_typed_frozenset(self): dec = msgspec.json.Decoder(frozenset[int]) assert dec.decode(b"[]") == frozenset() assert dec.decode(b"[1]") == frozenset({1}) assert dec.decode(b"[1,2]") == frozenset({1, 2}) def test_decode_typed_vartuple(self): dec = msgspec.json.Decoder(tuple[int, ...]) assert dec.decode(b"[]") == () assert dec.decode(b"[1]") == (1,) assert dec.decode(b"[1,2]") == ( 1, 2, ) @pytest.mark.parametrize("type", [list[int], set[int], tuple[int, ...]]) @pytest.mark.parametrize("bad_index", [0, 9, 10, 91, 1234]) def test_decode_typed_list_wrong_element_type(self, type, bad_index): dec = msgspec.json.Decoder(type) data = [1] * (bad_index + 1) data[bad_index] = "oops" msg = msgspec.json.encode(data) err_msg = rf"Expected `int`, got `str` - at `\$\[{bad_index}\]`" with pytest.raises(msgspec.ValidationError, match=err_msg): dec.decode(msg) @pytest.mark.parametrize( "s, error", [ (b"[", "truncated"), (b"[1", "truncated"), (b"[,]", "invalid character"), (b"[, 1]", "invalid character"), (b"[1, ]", "trailing comma in array"), (b"[1, 2 3]", r"expected ',' or ']'"), ], ) @pytest.mark.parametrize("type", [list, set, tuple, tuple[int, int, int]]) def test_decode_sequence_malformed(self, s, error, type): with pytest.raises(msgspec.DecodeError, match=error): msgspec.json.decode(s, type=type) def test_decode_fixtuple_any(self): dec = msgspec.json.Decoder(tuple[Any, Any, Any]) x = (1, "two", False) res = dec.decode(b'[1, "two", false]') assert res == x with pytest.raises( msgspec.ValidationError, match="Expected `array`, got `int`" ): dec.decode(b"1") with pytest.raises( msgspec.ValidationError, match="Expected `array` of length 3" ): dec.decode(b'[1, "two"]') def test_decode_fixtuple_typed(self): dec = msgspec.json.Decoder(tuple[int, str, bool]) x = (1, "two", False) res = dec.decode(b'[1, "two", false]') assert res == x with pytest.raises(msgspec.ValidationError, match="Expected `bool`"): dec.decode(b'[1, "two", "three"]') with pytest.raises( msgspec.ValidationError, match="Expected `array` of length 3" ): dec.decode(b'[1, "two"]') class TestNamedTuple: """Most tests are in `test_common`, this just tests some JSON peculiarities""" @pytest.mark.parametrize( "s, x", [(b"[\t\n\r ]", ()), (b" [ 1 , 2 ] ", (1, 2))], ) def test_decode_namedtuple_ignores_whitespace(self, s, x): class Test(NamedTuple): a: int = 0 b: int = 1 x2 = msgspec.json.decode(s, type=Test) assert x2 == Test(*x) @pytest.mark.parametrize( "s, error", [ (b"[", "truncated"), (b"[1", "truncated"), (b"[,]", "invalid character"), (b"[, 1]", "invalid character"), (b"[1, ]", "trailing comma in array"), (b"[1, 2 3]", r"expected ',' or ']'"), ], ) def test_decode_namedtuple_malformed(self, s, error): class Test(NamedTuple): a: int b: int with pytest.raises(msgspec.DecodeError, match=error): msgspec.json.decode(s, type=Test) class TestDict: def test_encode_dict_raises_non_string_or_numeric_keys(self): with pytest.raises( TypeError, match="Only dicts with str-like or number-like keys are supported", ): msgspec.json.encode({"a": 1, (1, 2): "bad"}) @pytest.mark.parametrize("x", [{}, {"a": 1}, {"a": 1, "b": 2}]) def test_roundtrip_dict(self, x): s = msgspec.json.encode(x) x2 = msgspec.json.decode(s) assert x == x2 assert json.loads(s) == x def test_decode_any_dict(self): x = msgspec.json.decode(b'{"a": 1, "b": "two", "c": false}') assert x == {"a": 1, "b": "two", "c": False} @pytest.mark.parametrize( "s, x", [ (b"{\t\n\r }", {}), (b'{\t\n\r "a" : 1}', {"a": 1}), (b'{ "a"\t : 1 \n, "b": \r 2 }', {"a": 1, "b": 2}), (b' { "a"\t : 1 \n, "b": \r 2 } ', {"a": 1, "b": 2}), ], ) def test_decode_dict_ignores_whitespace(self, s, x): x2 = msgspec.json.decode(s) assert x == x2 def test_decode_dict_wrong_element_type(self): dec = msgspec.json.Decoder(dict[str, int]) with pytest.raises( msgspec.ValidationError, match=r"Expected `int`, got `str` - at `\$\[...\]`" ): dec.decode(b'{"a": "bad"}') def test_decode_dict_literal_key(self): dec = msgspec.json.Decoder(dict[Literal["a", "b"], int]) assert dec.decode(b'{"a": 1, "b": 2}') == {"a": 1, "b": 2} with pytest.raises(msgspec.ValidationError, match="Invalid enum value 'c'"): dec.decode(b'{"a": 1, "c": 2}') def test_decode_dict_enum_key(self): dec = msgspec.json.Decoder(dict[FruitStr, int]) assert dec.decode(b'{"apple": 1, "banana": 2}') == { FruitStr.APPLE: 1, FruitStr.BANANA: 2, } with pytest.raises( msgspec.ValidationError, match="Invalid enum value 'carrot'" ): dec.decode(b'{"apple": 1, "carrot": 2}') def test_decode_dict_str_key_constraints(self): dec = msgspec.json.Decoder( dict[Annotated[str, msgspec.Meta(min_length=3)], int] ) assert dec.decode(b'{"abc": 1, "def": 2}') == {"abc": 1, "def": 2} with pytest.raises( msgspec.ValidationError, match="Expected `str` of length >= 3" ): dec.decode(b'{"a": 1}') @pytest.mark.parametrize("length", [3, 32, 33]) @pytest.mark.skipif( hasattr(sys.flags, "gil") and not sys.flags.gil, reason="cache is disabled without GIL", ) def test_decode_dict_string_cache(self, length): key = "x" * length msg = [{key: 1}, {key: 2}, {key: 3}] res = msgspec.json.decode(msgspec.json.encode(msg)) assert msg == res ids = {id(k) for d in res for k in d.keys()} if length > 32: assert len(ids) == 3 else: assert len(ids) == 1 def test_decode_dict_string_cache_ascii_only(self): """Short non-ascii strings aren't cached""" s = "123 á 456" msg = [{s: 1}, {s: 2}, {s: 3}] res = msgspec.json.decode(msgspec.json.encode(msg)) ids = {id(k) for d in res for k in d.keys()} assert len(ids) == 3 @pytest.mark.parametrize( "key", [ 1, 1.5, FruitInt.APPLE, FruitStr.APPLE, uuid.uuid4(), datetime.datetime.now(), datetime.date.today(), datetime.datetime.now().time(), datetime.timedelta(1.5), b"test", Decimal("1.5"), ], ) def test_roundtrip_dict_key_types(self, key): msg = {key: 100} sol = msgspec.json.encode(msgspec.to_builtins(msg, str_keys=True)) res = msgspec.json.encode(msg) assert res == sol msg2 = msgspec.json.decode(sol, type=dict[type(key), int]) assert msg == msg2 def test_encode_dict_plain_enum_str_key(self): # Regression: a plain `enum.Enum` with str values, used as a dict key. # json.encode previously raised "Only dicts with str-like or # number-like keys are supported", even though `dict[FruitStr, int]` is # an accepted decode type and both msgpack and to_builtins handle it. msg = {FruitStr.APPLE: 1, FruitStr.BANANA: 2} res = msgspec.json.encode(msg) assert res == b'{"apple":1,"banana":2}' # JSON must agree with the msgpack encoder and with to_builtins. expected = {"apple": 1, "banana": 2} assert msgspec.msgpack.decode(msgspec.msgpack.encode(msg)) == expected assert msgspec.to_builtins(msg, str_keys=True) == expected # Full round-trip through the accepted decode type. assert msgspec.json.decode(res, type=dict[FruitStr, int]) == msg def test_encode_dict_plain_enum_str_key_nested(self): # The same must hold when the dict is nested inside a Struct field. class Rec(msgspec.Struct): fruits: dict[FruitStr, int] rec = Rec(fruits={FruitStr.APPLE: 5}) res = msgspec.json.encode(rec) assert res == b'{"fruits":{"apple":5}}' assert msgspec.json.decode(res, type=Rec) == rec def test_encode_dict_plain_int_enum_key(self): # A plain Enum with int values (not IntEnum) must keep round-tripping. class IntVals(enum.Enum): A = 1 B = 2 msg = {IntVals.A: 9, IntVals.B: 8} res = msgspec.json.encode(msg) assert res == b'{"1":9,"2":8}' assert msgspec.json.decode(res, type=dict[IntVals, int]) == msg def test_decode_dict_int_enum_key(self): dec = msgspec.json.Decoder(dict[FruitInt, int]) assert dec.decode(b'{"-1": 10, "2": 20}') == { FruitInt.APPLE: 10, FruitInt.BANANA: 20, } with pytest.raises(msgspec.ValidationError, match="Invalid enum value 3"): dec.decode(b'{"-1": 1, "3": 2}') @pytest.mark.parametrize("x", [-(2**63), 2**64 - 1]) def test_encode_dict_int_key(self, x): msg = {-(2**63): "a", 0: "b", 2**64 - 1: "c"} s = msgspec.json.encode(msg) assert s == b'{"-9223372036854775808":"a","0":"b","18446744073709551615":"c"}' for x in [-(2**63) - 1, 2**64]: s = msgspec.json.encode({x: "a"}) assert s == f'{{"{x}":"a"}}'.encode() def test_decode_dict_int_key(self): msg = {-(2**63): "a", 0: "b", 2**64 - 1: "c"} buf = msgspec.json.encode(msg) res = msgspec.json.decode(buf, type=dict[int, str]) assert res == msg @pytest.mark.parametrize("s", ['""', '"-"', '"a"', '"-a"', '"01"', '"1a"']) def test_decode_dict_int_key_malformed(self, s): bad = ("{%s: 1}" % s).encode("utf-8") with pytest.raises(msgspec.ValidationError, match="Expected `int`, got `str`"): msgspec.json.decode(bad, type=dict[int, int]) @pytest.mark.parametrize("x", [-(2**63) - 1, 2**64, 2**65]) def test_decode_dict_big_int(self, x): msg = {str(x): 1} buf = msgspec.json.encode(msg) res = msgspec.json.decode(buf, type=dict[int, int]) assert res == {x: 1} assert type(list(res)[0]) is int def test_decode_dict_int_key_constraints(self): dec = msgspec.json.Decoder(dict[Annotated[int, msgspec.Meta(ge=3)], int]) assert dec.decode(b'{"4": 1, "5": 2}') == {4: 1, 5: 2} with pytest.raises(msgspec.ValidationError, match="Expected `int` >= 3"): dec.decode(b'{"2": 1}') def test_decode_dict_int_literal_key(self): dec = msgspec.json.Decoder(dict[Literal[-1, 2], int]) assert dec.decode(b'{"-1": 10, "2": 20}') == {-1: 10, 2: 20} with pytest.raises(msgspec.ValidationError, match="Invalid enum value 3"): dec.decode(b'{"-1": 10, "3": 20}') def test_encode_dict_float_key(self): msg = { 1.5: 1, -1.5: 2, 0.0: 3, float("-inf"): 4, float("inf"): 5, float("nan"): 6, } sol = msgspec.json.encode({str(k): v for k, v in msg.items()}) res = msgspec.json.encode(msg) assert res == sol def test_decode_dict_float_key(self): msg = {"1.5": 1, "inf": 2, "-inf": 3, "0": 4, "-1.5e12": 5, "123": 6} buf = msgspec.json.encode(msg) sol = {float(k): v for k, v in msg.items()} res = msgspec.json.decode(buf, type=dict[float, int]) assert res == sol def test_decode_dict_int_or_float_key(self): buf = b'{"1.5": "a", "123": "b"}' sol = {1.5: "a", 123: "b"} res = msgspec.json.decode(buf, type=dict[int | float, str]) assert res == sol assert type(list(res.keys())[-1]) is int def test_encode_dict_str_subclass_key(self): class mystr(str): pass msg = msgspec.json.encode({mystr("test"): 1}) assert msg == b'{"test":1}' def test_encode_dict_custom_key(self): class Custom: def __init__(self, value): self.value = value msg = msgspec.json.encode( {Custom("a"): 1, Custom("b"): 2}, enc_hook=lambda x: x.value ) assert msg == b'{"a":1,"b":2}' def enc_hook(x): raise TypeError("Oh no!") with pytest.raises(TypeError): msgspec.json.encode({Custom("x"): 1}, enc_hook=enc_hook) @emscripten_stack_limited def test_encode_dict_custom_key_recursion_error(self): class Custom: def __init__(self, value): self.value = value with pytest.raises(RecursionError): msgspec.json.encode({Custom("x"): 1}, enc_hook=lambda x: x) def test_decode_dict_custom_key(self): class Custom: def __init__(self, value): self.value = value def __hash__(self): return hash(self.value) def __eq__(self, other): return self.value == other.value def dec_hook(typ, obj): if typ == Custom: return Custom(obj) raise NotImplementedError msg = b'{"a":1,"b":2}' obj = msgspec.json.decode(msg, type=dict[Custom, int], dec_hook=dec_hook) assert obj == {Custom("a"): 1, Custom("b"): 2} @pytest.mark.parametrize( "s, error", [ (b"{", "truncated"), (b'{"a"', "truncated"), (b"{,}", "object keys must be strings"), (b"{:}", "object keys must be strings"), (b"{1: 2}", "object keys must be strings"), (b'{"a": 1, }', "trailing comma in object"), (b'{"a": 1, "b" 2}', "expected ':'"), (b'{"a": 1, "b": 2 "c"}', r"expected ',' or '}'"), ], ) @pytest.mark.parametrize("type", [dict, Any]) def test_decode_dict_malformed(self, s, error, type): with pytest.raises(msgspec.DecodeError, match=error): msgspec.json.decode(s, type=type) def test_encode_dict_order_escape(self): msg = {"test\nkey": 1, "another\t\rkey": 2} res = msgspec.json.encode(msg, order="deterministic") sol = b'{"another\\t\\rkey":2,"test\\nkey":1}' assert res == sol class TestTypedDict: """Most tests are in `test_common`, this just tests some JSON peculiarities""" @pytest.mark.parametrize( "s, x", [ (b"{\t\n\r }", {}), (b'{\t\n\r "a" : 1}', {"a": 1}), (b'{ "a"\t : 1 \n, "b": \r 2 }', {"a": 1, "b": 2}), (b' { "a"\t : 1 \n, "b": \r 2 } ', {"a": 1, "b": 2}), ], ) def test_decode_typeddict_ignores_whitespace(self, s, x): class Test(TypedDict, total=False): a: int b: int x2 = msgspec.json.decode(s, type=Test) assert x == x2 @pytest.mark.parametrize( "s, error", [ (b"{", "truncated"), (b'{"a"', "truncated"), (b"{,}", "object keys must be strings"), (b"{:}", "object keys must be strings"), (b"{1: 2}", "object keys must be strings"), (b'{"a": 1, }', "trailing comma in object"), (b'{"a": 1, "b" 2}', "expected ':'"), (b'{"a": 1, "b": 2 "c"}', r"expected ',' or '}'"), ], ) def test_decode_typeddict_malformed(self, s, error): class Test(TypedDict, total=False): a: int b: int with pytest.raises(msgspec.DecodeError, match=error): msgspec.json.decode(s, type=Test) class TestDataclass: """Most tests are in `test_common`, this just tests some JSON peculiarities""" @pytest.mark.parametrize( "s, x", [ (b"{\t\n\r }", {}), (b'{\t\n\r "a" : 1}', {"a": 1}), (b'{ "a"\t : 1 \n, "b": \r 2 }', {"a": 1, "b": 2}), (b' { "a"\t : 1 \n, "b": \r 2 } ', {"a": 1, "b": 2}), ], ) def test_decode_dataclass_ignores_whitespace(self, s, x): @dataclass class Test: a: int = -1 b: int = -2 x2 = msgspec.json.decode(s, type=Test) assert x2 == Test(**x) @pytest.mark.parametrize( "s, error", [ (b"{", "truncated"), (b'{"a"', "truncated"), (b"{,}", "object keys must be strings"), (b"{:}", "object keys must be strings"), (b"{1: 2}", "object keys must be strings"), (b'{"a": 1, }', "trailing comma in object"), (b'{"a": 1, "b" 2}', "expected ':'"), (b'{"a": 1, "b": 2 "c"}', r"expected ',' or '}'"), ], ) def test_decode_typeddict_malformed(self, s, error): @dataclass class Test: a: int b: int with pytest.raises(msgspec.DecodeError, match=error): msgspec.json.decode(s, type=Test) class TestStruct: @pytest.mark.parametrize("tag", [False, "Test", 123]) def test_encode_empty_struct(self, tag): class Test(msgspec.Struct, tag=tag): pass s = msgspec.json.encode(Test()) if tag: expected = msgspec.json.encode({"type": tag}) assert s == expected else: assert s == b"{}" @pytest.mark.parametrize("tag", [False, "Test", 123]) def test_encode_one_field_struct(self, tag): class Test(msgspec.Struct, tag=tag): a: int s = msgspec.json.encode(Test(a=1)) if tag: expected = msgspec.json.encode({"type": tag, "a": 1}) assert s == expected else: assert s == b'{"a":1}' @pytest.mark.parametrize("tag", [False, "Test", 123]) def test_encode_two_field_struct(self, tag): class Test(msgspec.Struct, tag=tag): a: int b: str s = msgspec.json.encode(Test(a=1, b="two")) if tag: expected = msgspec.json.encode({"type": tag, "a": 1, "b": "two"}) assert s == expected else: assert s == b'{"a":1,"b":"two"}' def test_decode_struct(self): dec = msgspec.json.Decoder(Person) msg = b'{"first": "harry", "last": "potter", "age": 13, "prefect": false}' x = dec.decode(msg) assert x == Person("harry", "potter", 13, False) # one for struct, one for output of getattr, and one for getrefcount assert sys.getrefcount(x.first) <= 3 with pytest.raises( msgspec.ValidationError, match="Expected `object`, got `int`" ): dec.decode(b"1") def test_decode_struct_field_wrong_type(self): dec = msgspec.json.Decoder(Person) msg = b'{"first": "harry", "last": "potter", "age": "bad"}' with pytest.raises( msgspec.ValidationError, match=r"Expected `int`, got `str` - at `\$.age`" ): dec.decode(msg) def test_decode_struct_missing_fields(self): bad = b'{"first": "harry", "last": "potter"}' with pytest.raises( msgspec.ValidationError, match="Object missing required field `age`" ): msgspec.json.decode(bad, type=Person) bad = b"{}" with pytest.raises( msgspec.ValidationError, match="Object missing required field `first`" ): msgspec.json.decode(bad, type=Person) bad = b'[{"first": "harry", "last": "potter"}]' with pytest.raises( msgspec.ValidationError, match=r"Object missing required field `age` - at `\$\[0\]`", ): msgspec.json.decode(bad, type=list[Person]) def test_decode_struct_fields_mixed_order(self): class Test(msgspec.Struct): a: int b: int c: int d: int sol = Test(0, 1, 2, 3) dec = msgspec.json.Decoder(Test) pairs = list(zip("abcdef", range(6))) for data in itertools.permutations(pairs): msg = msgspec.json.encode(dict(data)) res = dec.decode(msg) assert res == sol @pytest.mark.parametrize( "extra", [ None, False, True, 1, 2.0, "three", [1, 2], {"a": 1}, ], ) def test_decode_struct_ignore_extra_fields(self, extra): dec = msgspec.json.Decoder(Person) a = msgspec.json.encode( { "extra1": extra, "first": "harry", "extra2": extra, "last": "potter", "age": 13, "extra3": extra, } ) res = dec.decode(a) assert res == Person("harry", "potter", 13) def test_decode_struct_defaults_missing_fields(self): dec = msgspec.json.Decoder(Person) a = b'{"first": "harry", "last": "potter", "age": 13}' res = dec.decode(a) assert res == Person("harry", "potter", 13) assert res.prefect is False @pytest.mark.parametrize( "s, error", [ (b"{", "truncated"), (b'{"first"', "truncated"), (b"{,}", "object keys must be strings"), (b"{:}", "object keys must be strings"), (b"{1: 2}", "object keys must be strings"), (b'{"age": 13, }', "trailing comma in object"), (b'{"age": 13, "first" "harry"}', "expected ':'"), (b'{"age": 13, "first": "harry" "c"}', r"expected ',' or '}'"), ], ) def test_decode_struct_malformed(self, s, error): with pytest.raises(msgspec.DecodeError, match=error): msgspec.json.decode(s, type=Person) @pytest.mark.parametrize("array_like", [False, True]) def test_struct_gc_maybe_untracked_on_decode(self, array_like): class Test(msgspec.Struct, array_like=array_like): x: Any y: Any z: tuple = () enc = msgspec.json.Encoder() dec = msgspec.json.Decoder(list[Test]) ts = [ Test(1, 2), Test(3, "hello"), Test([], []), Test({}, {}), Test(None, None, ()), ] a, b, c, d, e = dec.decode(enc.encode(ts)) assert not gc.is_tracked(a) assert not gc.is_tracked(b) assert gc.is_tracked(c) assert gc.is_tracked(d) assert not gc.is_tracked(e) @pytest.mark.parametrize("array_like", [False, True]) def test_struct_gc_false_always_untracked_on_decode(self, array_like): class Test(msgspec.Struct, array_like=array_like, gc=False): x: Any y: Any dec = msgspec.json.Decoder(list[Test]) ts = [ Test(1, 2), Test([], []), Test({}, {}), ] for obj in dec.decode(msgspec.json.encode(ts)): assert not gc.is_tracked(obj) def test_struct_recursive_definition(self): enc = msgspec.json.Encoder() dec = msgspec.json.Decoder(Node) x = Node(Node(Node(), Node(Node()))) s = enc.encode(x) res = dec.decode(s) assert res == x @pytest.mark.parametrize("tag", ["Test", 0, 2**63 - 1, -(2**63)]) def test_decode_tagged_struct(self, tag): class Test(msgspec.Struct, tag=tag): a: int b: int dec = msgspec.json.Decoder(Test) # Test decode with and without tag for msg in [ {"a": 1, "b": 2}, {"type": tag, "a": 1, "b": 2}, {"a": 1, "type": tag, "b": 2}, ]: res = dec.decode(msgspec.json.encode(msg)) assert res == Test(1, 2) # Tag incorrect type for bad in [False, 123.456]: with pytest.raises(msgspec.ValidationError) as rec: dec.decode(msgspec.json.encode({"type": bad})) assert f"Expected `{type(tag).__name__}`" in str(rec.value) assert "`$.type`" in str(rec.value) # Tag incorrect value bad = -3 if isinstance(tag, int) else "bad" with pytest.raises(msgspec.ValidationError) as rec: dec.decode(msgspec.json.encode({"type": bad})) assert f"Invalid value {bad!r}" in str(rec.value) assert "`$.type`" in str(rec.value) @pytest.mark.parametrize("tag", ["Test", 123, -123]) def test_decode_tagged_empty_struct(self, tag): class Test(msgspec.Struct, tag=tag): pass dec = msgspec.json.Decoder(Test) # Tag missing res = dec.decode(msgspec.json.encode({})) assert res == Test() # Tag present res = dec.decode(msgspec.json.encode({"type": tag})) assert res == Test() @pytest.mark.parametrize( "s, error", [ (b"{", "truncated"), (b'{"type"', "truncated"), (b"{,}", "object keys must be strings"), (b"{:}", "object keys must be strings"), (b"{1: 2}", "object keys must be strings"), (b'{"type": "Test1", }', "trailing comma in object"), (b'{"type": "Test1", "a" 1}', "expected ':'"), (b'{"type": "Test1", "a": 1 "b"}', r"expected ',' or '}'"), (b'{"type": nulp}', r"invalid character"), (b'{"type": "nulp}', r"truncated"), (b'{"a": 1, }', "trailing comma in object"), (b'{"a": 1, "b" 1}', "expected ':'"), (b'{"a": 1 "b"}', r"expected ',' or '}'"), ], ) def test_decode_struct_tag_malformed(self, s, error): class Test1(msgspec.Struct, tag=True): a: int b: int with pytest.raises(msgspec.DecodeError, match=error): msgspec.json.decode(s, type=Test1) @pytest.mark.parametrize("ndigits", range(19)) @pytest.mark.parametrize("negative", [False, True]) def test_decode_tagged_struct_int_tag(self, ndigits, negative): if ndigits == 0: s = b"0" else: s = "".join( itertools.islice(itertools.cycle("123456789"), ndigits) ).encode() tag = int(s) if negative: tag = -tag class Test(msgspec.Struct, tag=tag): x: int t = Test(1) msg = msgspec.json.encode(t) assert msgspec.json.decode(msg, type=Test) == t def test_decode_tagged_struct_int_tag_uint64_always_invalid(self): """Uint64 values aren't currently valid tag values, but we still want to raise a good error message.""" class Test(msgspec.Struct, tag=123): pass with pytest.raises(msgspec.ValidationError) as rec: msgspec.json.decode(msgspec.json.encode({"type": 2**64 - 1}), type=Test) assert f"Invalid value {2**64 - 1}" in str(rec.value) assert "`$.type`" in str(rec.value) @pytest.mark.parametrize( "s, error", [ (b'{"type": 00}', "invalid number"), (b'{"type": -n123}', "invalid character"), (b'{"type": 123n}', "expected ',' or '}'"), (b'{"type": 123.}', "invalid number"), (b'{"type": 123.n}', "invalid number"), (b'{"type": 123e}', "invalid number"), (b'{"type": 123en}', "invalid number"), (b'{"type": 123, }', "trailing comma in object"), (b'{"type": 123, "a" 1}', "expected ':'"), (b'{"type": 123, "a": 1 "b"}', "expected ',' or '}'"), (b'{"type": nulp}', "invalid character"), (b'{"type": "bad}', "truncated"), (b'{"type": bad}', "invalid character"), ], ) def test_decode_struct_int_tag_malformed(self, s, error): class Test1(msgspec.Struct, tag=123): a: int b: int with pytest.raises(msgspec.DecodeError, match=error): msgspec.json.decode(s, type=Test1) class TestStructUnion: """Most functionality is tested in `test_common.py:TestStructUnion`, this only checks for malformed inputs and whitespace handling""" @pytest.mark.parametrize( "s, error", [ (b"{", "truncated"), (b'{"type"', "truncated"), (b"{,}", "object keys must be strings"), (b"{:}", "object keys must be strings"), (b"{1: 2}", "object keys must be strings"), (b'{"type": "Test1", }', "trailing comma in object"), (b'{"type": "Test1", "a" 1}', "expected ':'"), (b'{"type": "Test1", "a": 1 "b"}', r"expected ',' or '}'"), (b'{"type": nulp}', r"invalid character"), (b'{"a": 1, }', "trailing comma in object"), (b'{"a": 1, "b" 1}', "expected ':'"), (b'{"a": 1 "b"}', r"expected ',' or '}'"), ], ) def test_decode_struct_union_malformed(self, s, error): class Test1(msgspec.Struct, tag=True): a: int b: int class Test2(msgspec.Struct, tag=True): pass with pytest.raises(msgspec.DecodeError, match=error): msgspec.json.decode(s, type=Test1 | Test2) @pytest.mark.parametrize( "s, error", [ (b'{"type": 00}', "invalid number"), (b'{"type": -n123}', "invalid character"), (b'{"type": 123n}', "expected ',' or '}'"), (b'{"type": 123.}', "invalid number"), (b'{"type": 123.n}', "invalid number"), (b'{"type": 123e}', "invalid number"), (b'{"type": 123en}', "invalid number"), (b'{"type": 123, }', "trailing comma in object"), (b'{"type": 123, "a" 1}', "expected ':'"), (b'{"type": 123, "a": 1 "b"}', "expected ',' or '}'"), (b'{"type": nulp}', "invalid character"), (b'{"type": "bad}', "truncated"), (b'{"type": bad}', "invalid character"), ], ) def test_decode_struct_union_int_tag_malformed(self, s, error): class Test1(msgspec.Struct, tag=-123): a: int b: int class Test2(msgspec.Struct, tag=123): pass with pytest.raises(msgspec.DecodeError, match=error): msgspec.json.decode(s, type=Test1 | Test2) @pytest.mark.parametrize( "s", [ b' { "type" : "Test1" , "a" : 1 , "b" : 2 } ', b' { "a" : 1 , "type" : "Test1" , "b" : 2 } ', b' { "a" : 1 , "b" : 2 , "type" : "Test1" } ', ], ) def test_decode_struct_union_ignores_whitespace(self, s): class Test1(msgspec.Struct, tag=True): a: int b: int class Test2(msgspec.Struct, tag=True): pass res = msgspec.json.decode(s, type=Test1 | Test2) assert res == Test1(1, 2) @pytest.mark.parametrize( "s", [ b' { "type" : -123 , "a" : 1 , "b" : 2 } ', b' { "a" : 1 , "type" : -123 , "b" : 2 } ', b' { "a" : 1 , "b" : 2 , "type" : -123 } ', ], ) def test_decode_struct_union_int_tag_ignores_whitespace(self, s): class Test1(msgspec.Struct, tag=-123): a: int b: int class Test2(msgspec.Struct, tag=123): pass res = msgspec.json.decode(s, type=Test1 | Test2) assert res == Test1(1, 2) class TestStructArray: @pytest.mark.parametrize("tag", [False, True]) def test_encode_empty_struct(self, tag): class Test(msgspec.Struct, array_like=True, tag=tag): pass s = msgspec.json.encode(Test()) if tag: assert s == b'["Test"]' else: assert s == b"[]" @pytest.mark.parametrize("tag", [False, True]) def test_encode_one_field_struct(self, tag): class Test(msgspec.Struct, array_like=True, tag=tag): a: int s = msgspec.json.encode(Test(a=1)) if tag: assert s == b'["Test",1]' else: assert s == b"[1]" @pytest.mark.parametrize("tag", [False, True]) def test_encode_two_field_struct(self, tag): class Test(msgspec.Struct, array_like=True, tag=tag): a: int b: str s = msgspec.json.encode(Test(a=1, b="two")) if tag: assert s == b'["Test",1,"two"]' else: assert s == b'[1,"two"]' def test_struct_array_like(self): dec = msgspec.json.Decoder(PersonArray) x = PersonArray(first="harry", last="potter", age=13) a = msgspec.json.encode(x) assert msgspec.json.encode(("harry", "potter", 13, False)) == a assert dec.decode(a) == x with pytest.raises( msgspec.ValidationError, match="Expected `array`, got `int`" ): dec.decode(b"1") # Wrong field type bad = msgspec.json.encode(("harry", "potter", "thirteen")) with pytest.raises( msgspec.ValidationError, match=r"Expected `int`, got `str` - at `\$\[2\]`" ): dec.decode(bad) # Missing fields bad = msgspec.json.encode(("harry", "potter")) with pytest.raises( msgspec.ValidationError, match="Expected `array` of at least length 3, got 2", ): dec.decode(bad) bad = msgspec.json.encode(()) with pytest.raises( msgspec.ValidationError, match="Expected `array` of at least length 3, got 0", ): dec.decode(bad) # Extra fields ignored dec2 = msgspec.json.Decoder(list[PersonArray]) msg = msgspec.json.encode( [ ("harry", "potter", 13, False, 1, 2, 3, 4), ("ron", "weasley", 13, False, 5, 6), ] ) res = dec2.decode(msg) assert res == [ PersonArray("harry", "potter", 13), PersonArray("ron", "weasley", 13), ] # Defaults applied res = dec.decode(msgspec.json.encode(("harry", "potter", 13))) assert res == PersonArray("harry", "potter", 13) assert res.prefect is False def test_struct_map_and_array_like_messages_cant_mix(self): array_msg = msgspec.json.encode(("harry", "potter", 13)) map_msg = msgspec.json.encode({"first": "harry", "last": "potter", "age": 13}) sol = Person("harry", "potter", 13) array_sol = PersonArray("harry", "potter", 13) dec = msgspec.json.Decoder(Person) array_dec = msgspec.json.Decoder(PersonArray) assert array_dec.decode(array_msg) == array_sol assert dec.decode(map_msg) == sol with pytest.raises( msgspec.ValidationError, match="Expected `object`, got `array`" ): dec.decode(array_msg) with pytest.raises( msgspec.ValidationError, match="Expected `array`, got `object`" ): array_dec.decode(map_msg) @pytest.mark.parametrize( "s, error", [ (b"[", "truncated"), (b"[1", "truncated"), (b"[,]", "invalid character"), (b"[, 1]", "invalid character"), (b"[1, ]", "trailing comma in array"), (b"[1, 2 3]", r"expected ',' or ']'"), ], ) def test_decode_struct_array_like_malformed(self, s, error): class Point(msgspec.Struct, array_like=True): x: int y: int z: int with pytest.raises(msgspec.DecodeError, match=error): msgspec.json.decode(s, type=Point) @pytest.mark.parametrize("tag", ["Test", 123]) def test_decode_tagged_struct(self, tag): class Test(msgspec.Struct, tag=tag, array_like=True): a: int b: int c: int = 0 dec = msgspec.json.Decoder(Test) # Decode with tag res = dec.decode(msgspec.json.encode([tag, 1, 2])) assert res == Test(1, 2) res = dec.decode(msgspec.json.encode([tag, 1, 2, 3])) assert res == Test(1, 2, 3) # Trailing fields ignored res = dec.decode(msgspec.json.encode([tag, 1, 2, 3, 4])) assert res == Test(1, 2, 3) # Missing required field errors with pytest.raises(msgspec.ValidationError) as rec: dec.decode(msgspec.json.encode([tag, 1])) assert "Expected `array` of at least length 3, got 2" in str(rec.value) # Tag missing with pytest.raises(msgspec.ValidationError) as rec: dec.decode(msgspec.json.encode([])) assert "Expected `array` of at least length 3, got 0" in str(rec.value) # Tag incorrect type with pytest.raises(msgspec.ValidationError) as rec: dec.decode(msgspec.json.encode([123.456, 2, 3])) assert f"Expected `{type(tag).__name__}`" in str(rec.value) assert "`$[0]`" in str(rec.value) # Tag incorrect value bad = 0 if isinstance(tag, int) else "bad" with pytest.raises(msgspec.ValidationError) as rec: dec.decode(msgspec.json.encode([bad, 1, 2])) assert f"Invalid value {bad!r}" in str(rec.value) assert "`$[0]`" in str(rec.value) # Field incorrect type correct index with pytest.raises(msgspec.ValidationError) as rec: dec.decode(msgspec.json.encode([tag, "a", 2])) assert "Expected `int`, got `str`" in str(rec.value) assert "`$[1]`" in str(rec.value) @pytest.mark.parametrize("tag", ["Test", 123]) def test_decode_tagged_empty_struct(self, tag): class Test(msgspec.Struct, tag=tag, array_like=True): pass dec = msgspec.json.Decoder(Test) # Decode with tag res = dec.decode(msgspec.json.encode([tag, 1, 2])) assert res == Test() # Tag missing with pytest.raises(msgspec.ValidationError) as rec: dec.decode(msgspec.json.encode([])) assert "Expected `array` of at least length 1, got 0" in str(rec.value) class TestStructArrayUnion: """Most functionality is tested in `test_common.py:TestStructUnion`, this only checks for malformed inputs and whitespace handling""" @pytest.mark.parametrize( "s, error", [ (b"[,]", "invalid character"), (b"[, 1]", "invalid character"), (b"[nulp]", "invalid character"), (b'["Test1", nulp]', "invalid character"), (b"[", "truncated"), (b'["Test1', "truncated"), (b'["Test1"', "truncated"), (b'["Test1",', "truncated"), (b'["Test1]', "truncated"), (b'["Test1", ]', "trailing comma in array"), (b'["Test1" g', r"expected ',' or ']'"), (b'["Test1", 1 g', r"expected ',' or ']'"), (b'["Test1", 2 3]', r"expected ',' or ']'"), ], ) def test_decode_struct_array_like_union_malformed(self, s, error): class Test1(msgspec.Struct, tag=True, array_like=True): x: int y: int z: int class Test2(msgspec.Struct, tag=True, array_like=True): pass with pytest.raises(msgspec.DecodeError, match=error): msgspec.json.decode(s, type=Test1 | Test2) @pytest.mark.parametrize( "s, error", [ (b"[,]", "invalid character"), (b"[, 1]", "invalid character"), (b"[nulp]", "invalid character"), (b"[123, nulp]", "invalid character"), (b"[", "truncated"), (b"[123.n,", "invalid number"), (b"[123en,", "invalid number"), (b"[123", "truncated"), (b"[123,", "truncated"), (b"[123, ]", "trailing comma in array"), (b"[123 g", r"expected ',' or ']'"), (b"[123, 1 g", r"expected ',' or ']'"), ], ) def test_decode_struct_array_like_union_int_tag_malformed(self, s, error): class Test1(msgspec.Struct, tag=123, array_like=True): x: int y: int z: int class Test2(msgspec.Struct, tag=-123, array_like=True): pass with pytest.raises(msgspec.DecodeError, match=error): msgspec.json.decode(s, type=Test1 | Test2) def test_decode_struct_array_union_ignores_whitespace(self): s = b' [ "Test1" , 1 , 2 ] ' class Test1(msgspec.Struct, tag=True, array_like=True): a: int b: int class Test2(msgspec.Struct, tag=True, array_like=True): pass res = msgspec.json.decode(s, type=Test1 | Test2) assert res == Test1(1, 2) def test_decode_struct_array_union_int_tag_ignores_whitespace(self): s = b" [ 123 , 1 , 2 ] " class Test1(msgspec.Struct, tag=123, array_like=True): a: int b: int class Test2(msgspec.Struct, tag=-123, array_like=True): pass res = msgspec.json.decode(s, type=Test1 | Test2) assert res == Test1(1, 2) class TestRaw: def test_encode_raw(self): b = b'{"x":1}' r = msgspec.Raw(b) assert msgspec.json.encode(r) == b assert msgspec.json.encode({"y": r}) == b'{"y":{"x":1}}' def test_decode_raw_field(self): class Test(msgspec.Struct): x: int y: msgspec.Raw s = b'{"x": 1, "y": [1, 2, 3] }' res = msgspec.json.decode(s, type=Test) assert res.x == 1 assert bytes(res.y) == b"[1, 2, 3]" def test_decode_raw_optional_field(self): default = msgspec.Raw() class Test(msgspec.Struct): x: int y: msgspec.Raw = default s = b'{"x": 1, "y": [1, 2, 3] }' res = msgspec.json.decode(s, type=Test) assert res.x == 1 assert bytes(res.y) == b"[1, 2, 3]" s = b'{"x": 1}' res = msgspec.json.decode(s, type=Test) assert res.x == 1 assert res.y is default def test_decode_raw_malformed_data(self): class Test(msgspec.Struct): x: int y: msgspec.Raw s = b'{"x": 1, "y": [1, 2,]}' with pytest.raises(msgspec.DecodeError, match="malformed"): msgspec.json.decode(s, type=Test) def test_decode_raw_is_view(self): s = b' {"x": 1} ' r = msgspec.json.decode(s, type=msgspec.Raw) assert bytes(r) == b'{"x": 1}' assert r.copy() is not r # actual copy indicates a view @pytest.mark.parametrize("wrap", [False, True]) def test_decode_raw_from_str(self, wrap): msg = '[{"x": 1}]' if wrap else '{"x": 1}' c = sys.getrefcount(msg) if wrap: [r] = msgspec.json.decode(msg, type=list[msgspec.Raw]) else: r = msgspec.json.decode(msg, type=msgspec.Raw) assert bytes(r) == b'{"x": 1}' # Raw holds a ref to the original str assert sys.getrefcount(msg) <= c + 1 del r assert sys.getrefcount(msg) == c def test_raw_in_union_works_but_doesnt_change_anything(self): class Test(msgspec.Struct): x: int | str | msgspec.Raw r = msgspec.json.decode(b'{"x": 1}', type=Test) assert r == Test(1) def test_raw_can_be_mixed_with_custom_type(self): class Test(msgspec.Struct): x: Custom | msgspec.Raw def dec_hook(typ, obj): assert typ is Custom return typ(*obj) res = msgspec.json.decode(b'{"x": [1, 2]}', type=Test, dec_hook=dec_hook) assert res == Test(Custom(1, 2)) class TestFormat: @pytest.mark.parametrize( "msg", [ b"null", b"false", b"true", b" true \n", b"1", b" \n1\t\r", b"1.5", b'"abc"', b' \t"abc" \n\t', b"[]", b"[ \t ]", b"[1]", b"[1, 2]", b"{}", b"{ }", b'{"a": 1}', b'{"a": 1, "b": 2}', b'{"a": {"x": 1, "y": [1, false]}, "b": ["foo", []]}', b'\n{ "a" : \t[ 1, \t\n\r 2]\n} ', ], ) @pytest.mark.parametrize("indent", [-1, 0, 2, 4]) def test_format(self, msg, indent): if indent > 0: kwargs = {"separators": None, "indent": indent} elif indent == 0: kwargs = {"separators": None, "indent": None} elif indent < 0: kwargs = {"separators": (",", ":"), "indent": None} sol = json.dumps(json.loads(msg), **kwargs).encode() res = msgspec.json.format(msg, indent=indent) assert res == sol def test_format_str(self): assert msgspec.json.format("[1, 2]", indent=0) == "[1, 2]" def test_format_bad_calls(self): with pytest.raises(TypeError): msgspec.json.format(1) with pytest.raises(TypeError): msgspec.json.format(b"[]", indent=None) with pytest.raises(TypeError): msgspec.json.format(b"[]", 2) with pytest.raises(TypeError): msgspec.json.format(b"[]", bad=2) @pytest.mark.parametrize( "msg, err", [ (b"nulx", "invalid character"), (b"trux", "invalid character"), (b"falsx", "invalid character"), (b"x1", "invalid character"), (b"1.", "invalid number"), (b"1x", "trailing characters"), (b'"abc', "truncated"), (b'"\\u00cz 123"', "invalid character in unicode escape"), (b"[", "truncated"), (b"[1", "truncated"), (b"[,]", "invalid character"), (b"[, 1]", "invalid character"), (b"[1, ]", "trailing comma in array"), (b"[1, 2 3]", r"expected ',' or ']'"), (b"{", "truncated"), (b'{"a"', "truncated"), (b"{,}", "expected '\"'"), (b"{:}", "expected '\"'"), (b"{1: 2}", "expected '\"'"), (b'{"a": 1, }', "trailing comma in object"), (b'{"a": 1, "b" 2}', "expected ':'"), (b'{"a": 1, "b": 2 "c"}', r"expected ',' or '}'"), ], ) def test_format_malformed(self, msg, err): with pytest.raises(msgspec.DecodeError, match=err): msgspec.json.format(msg) python-msgspec-0.22.0/tests/unit/test_msgpack.py000066400000000000000000002034301525673062400217460ustar00rootroot00000000000000from __future__ import annotations import array import datetime import enum import gc import itertools import math import pickle import struct import sys from typing import ( Any, Dict, FrozenSet, List, Literal, Optional, Set, Tuple, Union, ) import pytest import msgspec from .utils import emscripten_stack_limited UTC = datetime.timezone.utc class FruitInt(enum.IntEnum): APPLE = 1 BANANA = 2 class FruitStr(enum.Enum): APPLE = "apple" BANANA = "banana" class Person(msgspec.Struct): first: str last: str age: int prefect: bool = False class PersonArray(msgspec.Struct, array_like=True): first: str last: str age: int prefect: bool = False PERSON = Person("harry", "potter", 13) PERSON_AA = PersonArray("harry", "potter", 13) class Node(msgspec.Struct): left: Node | None = None right: Node | None = None class Custom: def __init__(self, x, y): self.x = x self.y = y def __eq__(self, other): return self.x == other.x and self.y == other.y INTS = [ -(2**63), -(2**31 + 1), -(2**31), -(2**15 + 1), -(2**15), -(2**7 + 1), -(2**7), -(2**5 + 1), -(2**5), -1, 0, 1, 2**7 - 1, 2**7, 2**8 - 1, 2**8, 2**16 - 1, 2**16, 2**32 - 1, 2**32, 2**63 - 1, 2**64 - 1, ] FLOATS = [ -1.5, 0.0, 1.5, -float("inf"), float("inf"), float("nan"), sys.float_info.max, sys.float_info.min, -sys.float_info.max, -sys.float_info.min, ] SIZES = [0, 1, 31, 32, 2**8 - 1, 2**8, 2**16 - 1, 2**16] def assert_eq(x, y): if isinstance(x, float) and math.isnan(x): assert math.isnan(y) else: assert x == y class TestEncodeFunction: def test_encode(self): dec = msgspec.msgpack.Decoder() assert dec.decode(msgspec.msgpack.encode(1)) == 1 def test_encode_bad_arguments(self): with pytest.raises(TypeError, match="Missing 1 required arguments"): msgspec.msgpack.encode() with pytest.raises(TypeError, match="Extra positional"): msgspec.msgpack.encode(1, 2) with pytest.raises(TypeError, match="enc_hook must be callable"): msgspec.msgpack.encode(1, enc_hook="bad") def test_encode_error(self): with pytest.raises(TypeError): msgspec.msgpack.encode(object()) def test_encode_large_object(self): """Check that buffer resize works""" data = b"x" * 4097 dec = msgspec.msgpack.Decoder() assert dec.decode(msgspec.msgpack.encode(data)) == data def test_encode_no_enc_hook(self): class Foo: pass with pytest.raises( TypeError, match="Encoding objects of type Foo is unsupported" ): msgspec.msgpack.encode(Foo()) with pytest.raises( TypeError, match="Encoding objects of type Foo is unsupported" ): msgspec.msgpack.encode(Foo(), enc_hook=None) def test_encode_enc_hook(self): unsupported = object() def enc_hook(x): assert x is unsupported return "hello" orig_refcount = sys.getrefcount(enc_hook) res = msgspec.msgpack.encode(unsupported, enc_hook=enc_hook) assert msgspec.msgpack.encode("hello") == res assert sys.getrefcount(enc_hook) == orig_refcount def test_encode_enc_hook_errors(self): def enc_hook(x): raise TypeError("bad") orig_refcount = sys.getrefcount(enc_hook) with pytest.raises(TypeError, match="bad"): msgspec.msgpack.encode(object(), enc_hook=enc_hook) assert sys.getrefcount(enc_hook) == orig_refcount def test_encode_parse_arguments_errors(self): with pytest.raises(TypeError, match="Missing 1 required argument"): msgspec.msgpack.encode() with pytest.raises(TypeError, match="Extra positional arguments"): msgspec.msgpack.encode(1, lambda x: None) with pytest.raises(TypeError, match="Extra positional arguments"): msgspec.msgpack.encode(1, 2, 3) with pytest.raises(TypeError, match="Extra keyword arguments"): msgspec.msgpack.encode(1, bad=1) with pytest.raises(TypeError, match="Extra keyword arguments"): msgspec.msgpack.encode(1, enc_hook=lambda x: None, extra="extra") class TestDecodeFunction: def setup_method(self): self.buf = msgspec.msgpack.encode([1, 2, 3]) def test_decode(self): assert msgspec.msgpack.decode(self.buf) == [1, 2, 3] def test_decode_type_keyword(self): assert msgspec.msgpack.decode(self.buf, type=list[int]) == [1, 2, 3] with pytest.raises(msgspec.ValidationError): assert msgspec.msgpack.decode(self.buf, type=list[str]) def test_decode_type_any(self): assert msgspec.msgpack.decode(self.buf, type=Any) == [1, 2, 3] @pytest.mark.parametrize("array_like", [False, True]) def test_decode_type_struct(self, array_like): class Point(msgspec.Struct, array_like=array_like): x: int y: int msg = msgspec.msgpack.encode(Point(1, 2)) for _ in range(2): assert msgspec.msgpack.decode(msg, type=Point) == Point(1, 2) def test_decode_type_struct_not_json_compatible(self): class Test(msgspec.Struct): x: dict[int, str] msg = msgspec.msgpack.encode(Test({1: "two"})) msgspec.msgpack.decode(msg, type=Test) == Test({1, "two"}) def test_decode_type_struct_invalid_type(self): class Test(msgspec.Struct): x: 1 with pytest.raises(TypeError): msgspec.msgpack.decode(b"{}", type=Test) def test_decode_invalid_type(self): with pytest.raises(TypeError, match="Type '1' is not supported"): msgspec.msgpack.decode(self.buf, type=1) def test_decode_invalid_buf(self): with pytest.raises(TypeError): msgspec.msgpack.decode(1) def test_decode_parse_arguments_errors(self): with pytest.raises(TypeError, match="Missing 1 required argument"): msgspec.msgpack.decode() with pytest.raises(TypeError, match="Extra positional arguments"): msgspec.msgpack.decode(self.buf, list[int]) with pytest.raises(TypeError, match="Extra positional arguments"): msgspec.msgpack.decode(self.buf, 2, 3) with pytest.raises(TypeError, match="Extra keyword arguments"): msgspec.msgpack.decode(self.buf, bad=1) with pytest.raises(TypeError, match="Extra keyword arguments"): msgspec.msgpack.decode(self.buf, type=list[int], extra=1) def test_decode_with_trailing_characters_errors(self): msg = msgspec.msgpack.encode([1, 2, 3]) + b"trailing" with pytest.raises(msgspec.DecodeError): msgspec.msgpack.decode(msg) class TestEncoderMisc: def test_encoder_init_errors(self): with pytest.raises(TypeError): msgspec.msgpack.Encoder(bad=1) with pytest.raises(TypeError, match="enc_hook must be callable"): msgspec.msgpack.Encoder(enc_hook=1) @pytest.mark.parametrize("x", [-(2**63) - 1, 2**64]) def test_encode_integer_limits(self, x): enc = msgspec.msgpack.Encoder() with pytest.raises(OverflowError): enc.encode(x) def rec_obj1(self): o = [] o.append(o) return o def rec_obj2(self): o = ([],) o[0].append(o) return o def rec_obj3(self): o = {} o["a"] = o return o def rec_obj4(self): class Box(msgspec.Struct): a: Box o = Box(None) o.a = o return o @pytest.mark.parametrize("case", [1, 2, 3, 4]) @emscripten_stack_limited def test_encode_infinite_recursive_object_errors(self, case): enc = msgspec.msgpack.Encoder() o = getattr(self, "rec_obj%d" % case)() with pytest.raises(RecursionError): enc.encode(o) def test_encode_no_enc_hook(self): class Foo: pass enc = msgspec.msgpack.Encoder() assert enc.enc_hook is None enc = msgspec.msgpack.Encoder(enc_hook=None) assert enc.enc_hook is None with pytest.raises( TypeError, match="Encoding objects of type Foo is unsupported" ): enc.encode(Foo()) def test_encode_enc_hook(self): unsupported = object() def enc_hook(x): assert x is unsupported return "hello" orig_refcount = sys.getrefcount(enc_hook) enc = msgspec.msgpack.Encoder(enc_hook=enc_hook) assert enc.enc_hook is enc_hook assert sys.getrefcount(enc.enc_hook) == orig_refcount + 2 assert sys.getrefcount(enc_hook) == orig_refcount + 1 res = enc.encode(unsupported) assert enc.encode("hello") == res del enc assert sys.getrefcount(enc_hook) == orig_refcount def test_encode_enc_hook_errors(self): def enc_hook(x): raise TypeError("bad") enc = msgspec.msgpack.Encoder(enc_hook=enc_hook) with pytest.raises(TypeError, match="bad"): enc.encode(object()) def test_encode_enc_hook_recurses(self): class Node: def __init__(self, a): self.a = a def enc_hook(x): return {"type": "Node", "a": x.a} enc = msgspec.msgpack.Encoder(enc_hook=enc_hook) msg = enc.encode(Node(Node(1))) res = msgspec.msgpack.decode(msg) assert res == {"type": "Node", "a": {"type": "Node", "a": 1}} @emscripten_stack_limited def test_encode_enc_hook_recursion_error(self): enc = msgspec.msgpack.Encoder(enc_hook=lambda x: x) with pytest.raises(RecursionError): enc.encode(object()) def test_encode_bad_arguments(self): enc = msgspec.msgpack.Encoder() with pytest.raises(TypeError, match="Missing 1 required arguments"): enc.encode() with pytest.raises(TypeError, match="Extra positional"): enc.encode(1, 2) def test_encode_into_bad_arguments(self): enc = msgspec.msgpack.Encoder() with pytest.raises(TypeError, match="bytearray"): enc.encode_into(1, b"test") with pytest.raises(TypeError): enc.encode_into(1, bytearray(), "bad") with pytest.raises(TypeError): enc.encode_into(1, bytearray(), None) with pytest.raises(ValueError, match="offset"): enc.encode_into(1, bytearray(), -2) with pytest.raises(TypeError, match="Missing 1 required arguments"): enc.encode_into(1) with pytest.raises(TypeError, match="Extra positional"): enc.encode_into(1, bytearray(), 2, 3) @pytest.mark.parametrize("buf_size", [0, 1, 16, 55, 60]) def test_encode_into(self, buf_size): enc = msgspec.msgpack.Encoder() msg = {"key": "x" * 48} encoded = msgspec.msgpack.encode(msg) buf = bytearray(buf_size) out = enc.encode_into(msg, buf) assert out is None assert buf == encoded def test_encode_into_offset(self): enc = msgspec.msgpack.Encoder() msg = {"key": "value"} encoded = enc.encode(msg) # Offset 0 is default buf = bytearray() enc.encode_into(msg, buf, 0) assert buf == encoded # Offset in bounds uses the provided offset buf = bytearray(b"01234") enc.encode_into(msg, buf, 2) assert buf == b"01" + encoded # Offset out of bounds extends buf = bytearray(b"01234") enc.encode_into(msg, buf, 10) assert buf[:5] == b"01234" assert buf[10:] == encoded # Offset -1 means append at end buf = bytearray(b"01234") enc.encode_into(msg, buf, -1) assert buf == b"01234" + encoded def test_encode_into_handles_errors_properly(self): enc = msgspec.msgpack.Encoder() out1 = enc.encode([1, 2, 3]) msg = [1, 2, object()] buf = bytearray() with pytest.raises(TypeError): enc.encode_into(msg, buf) assert buf # buffer isn't reset upon error # Encoder still works out2 = enc.encode([1, 2, 3]) assert out1 == out2 @pytest.mark.parametrize( "dt, dt_str", [ (datetime.datetime(1, 2, 3, 4, 5, 6), "0001-02-03T04:05:06"), ( datetime.datetime(1234, 12, 31, 14, 56, 27, 123456), "1234-12-31T14:56:27.123456", ), ], ) def test_encode_datetime_naive(self, dt, dt_str): res = msgspec.msgpack.encode(dt) sol = msgspec.msgpack.encode(dt_str) assert res == sol def test_encode_datetime_non_utc_tzinfo(self): tzinfo = datetime.timezone(datetime.timedelta(hours=1)) x = datetime.datetime.now(tzinfo) x2 = x.astimezone(datetime.timezone.utc) res = msgspec.msgpack.encode(x) sol = msgspec.msgpack.encode(x2) assert res == sol class TestDecoderMisc: def test_decoder_type_attribute(self): dec = msgspec.msgpack.Decoder() assert dec.type is Any dec = msgspec.msgpack.Decoder(int) assert dec.type is int def test_decoder_ext_hook_attribute(self): def ext_hook(code, buf): pass dec = msgspec.msgpack.Decoder() assert dec.ext_hook is None dec = msgspec.msgpack.Decoder(ext_hook=None) assert dec.ext_hook is None dec = msgspec.msgpack.Decoder(ext_hook=ext_hook) assert dec.ext_hook is ext_hook def test_decoder_bad_args(self): with pytest.raises(TypeError): msgspec.msgpack.Decoder(bad=1) def test_decoder_ext_hook_not_callable(self): with pytest.raises(TypeError): msgspec.msgpack.Decoder(ext_hook=1) def test_decoder_repr(self): typ = list[dict[int, float]] dec = msgspec.msgpack.Decoder(typ) assert repr(dec) == f"msgspec.msgpack.Decoder({typ!r})" dec = msgspec.msgpack.Decoder() assert repr(dec) == f"msgspec.msgpack.Decoder({Any!r})" def test_decode_with_trailing_characters_errors(self): dec = msgspec.msgpack.Decoder() msg = msgspec.msgpack.encode([1, 2, 3]) + b"trailing" with pytest.raises(msgspec.DecodeError): dec.decode(msg) def test_decode_invalid_opcode_error(self): with pytest.raises(msgspec.DecodeError, match="invalid opcode '\\\\xc1'"): msgspec.msgpack.decode(b"\xc1abc") @pytest.mark.parametrize( "hex_data", [ "818001", # map used as map key "878048", # map used as map key "8bd4ec5c03", # ext used as map key ], ) def test_decode_unhashable_map_key_raises_decode_error(self, hex_data): with pytest.raises(msgspec.DecodeError, match="map keys must be hashable"): msgspec.msgpack.decode(bytes.fromhex(hex_data)) def test_decode_hashable_array_map_key_ok(self): assert msgspec.msgpack.decode(bytes.fromhex("819001")) == {(): 1} def test_decode_skip_invalid_submessage_raises(self): """Ensure errors in submessage skipping are raised""" class Test(msgspec.Struct): x: int msg = msgspec.msgpack.encode({"x": 1, "y": ["one", "two", "three"]}) # Break the message msg = msg.replace(b"three", b"tree") with pytest.raises(msgspec.DecodeError, match="truncated"): msgspec.msgpack.decode(msg, type=Test) @pytest.mark.parametrize("length", [3, 31, 33]) @pytest.mark.parametrize("typed", [False, True]) @pytest.mark.skipif( hasattr(sys.flags, "gil") and not sys.flags.gil, reason="cache is disabled without GIL", ) def test_decode_dict_string_cache(self, length, typed): key = "x" * length msg = [{key: 1}, {key: 2}, {key: 3}] if typed: dec = msgspec.msgpack.Decoder(list[dict[str, int]]) else: dec = msgspec.msgpack.Decoder() res = dec.decode(msgspec.msgpack.encode(msg)) assert msg == res ids = {id(k) for d in res for k in d.keys()} if length > 32: assert len(ids) == 3 else: assert len(ids) == 1 def test_decode_dict_string_cache_ascii_only(self): """Short non-ascii strings aren't cached""" s = "123 á 456" msg = [{s: 1}, {s: 2}, {s: 3}] res = msgspec.msgpack.decode(msgspec.msgpack.encode(msg)) ids = {id(k) for d in res for k in d.keys()} assert len(ids) == 3 @pytest.mark.parametrize("type", [None, list, tuple, set]) def test_decoding_large_arrays_doesnt_preallocate(self, type): # b = b"\xdd\xff\xff\xff\xff" with pytest.raises(msgspec.DecodeError, match="truncated"): if type is None: msgspec.msgpack.decode(b) else: msgspec.msgpack.decode(b, type=type) def test_decoding_large_arrays_as_keys_doesnt_preallocate(self): # {"x": } b = b"\x81\xa1x\xdd\xff\xff\xff\xff" with pytest.raises(msgspec.DecodeError, match="truncated"): msgspec.msgpack.decode(b) class TestTypedDecoder: def check_unexpected_type(self, dec_type, val, msg): dec = msgspec.msgpack.Decoder(dec_type) s = msgspec.msgpack.Encoder().encode(val) with pytest.raises(msgspec.ValidationError, match=msg): dec.decode(s) def test_any(self): dec = msgspec.msgpack.Decoder(Any) assert dec.decode(msgspec.msgpack.encode([1, 2, 3])) == [1, 2, 3] # A union that includes `Any` is just `Any` dec = msgspec.msgpack.Decoder(Any | float | int | None) assert dec.decode(msgspec.msgpack.encode([1, 2, 3])) == [1, 2, 3] def test_none(self): enc = msgspec.msgpack.Encoder() dec = msgspec.msgpack.Decoder(None) assert dec.decode(enc.encode(None)) is None with pytest.raises(msgspec.ValidationError, match="Expected `null`"): assert dec.decode(enc.encode(1)) @pytest.mark.parametrize("x", [False, True]) def test_bool(self, x): enc = msgspec.msgpack.Encoder() dec = msgspec.msgpack.Decoder(bool) assert dec.decode(enc.encode(x)) is x def test_bool_unexpected_type(self): self.check_unexpected_type(bool, "a", "Expected `bool`") @pytest.mark.parametrize("x", INTS) def test_int(self, x): enc = msgspec.msgpack.Encoder() dec = msgspec.msgpack.Decoder(int) assert dec.decode(enc.encode(x)) == x def test_int_unexpected_type(self): self.check_unexpected_type(int, "a", "Expected `int`") @pytest.mark.parametrize("x", FLOATS + INTS) def test_float(self, x): enc = msgspec.msgpack.Encoder() dec = msgspec.msgpack.Decoder(float) res = dec.decode(enc.encode(x)) sol = float(x) if math.isnan(sol): assert math.isnan(res) else: assert res == sol def test_float_unexpected_type(self): self.check_unexpected_type(float, "a", "Expected `float`") def test_decode_float4(self): x = 1.2 packed = struct.pack(">f", x) # Loss of resolution in float32 leads to some rounding error x4 = struct.unpack(">f", packed)[0] msg = b"\xca" + packed assert msgspec.msgpack.decode(msg) == x4 assert msgspec.msgpack.decode(msg, type=float) == x4 @pytest.mark.parametrize("size", SIZES) def test_str(self, size): enc = msgspec.msgpack.Encoder() dec = msgspec.msgpack.Decoder(str) x = "a" * size res = dec.decode(enc.encode(x)) assert res == x def test_str_unexpected_type(self): self.check_unexpected_type(str, 1, "Expected `str`") @pytest.mark.parametrize("size", SIZES) @pytest.mark.parametrize("typ", [bytes, bytearray, memoryview]) def test_binary(self, size, typ): enc = msgspec.msgpack.Encoder() dec = msgspec.msgpack.Decoder(typ) sol = b"a" * size res = dec.decode(enc.encode(typ(sol))) assert isinstance(res, typ) assert bytes(res) == sol @pytest.mark.parametrize("typ", [bytes, bytearray, memoryview]) def test_binary_unexpected_type(self, typ): self.check_unexpected_type(typ, 1, "Expected `bytes`") @pytest.mark.parametrize("input_type", [bytes, bytearray, memoryview]) def test_decode_memoryview_zerocopy(self, input_type): msg = msgspec.msgpack.encode(b"abcde") ref = msg if input_type is memoryview else None msg = input_type(msg) res = msgspec.msgpack.decode(msg, type=memoryview) assert isinstance(res, memoryview) assert bytes(res) == b"abcde" assert len(res) == 5 if input_type is memoryview: assert sys.getrefcount(ref) <= 3 del msg assert sys.getrefcount(ref) <= 3 del res assert sys.getrefcount(ref) <= 2 elif input_type is bytes: assert sys.getrefcount(msg) <= 3 def test_datetime_aware_ext(self): dec = msgspec.msgpack.Decoder(datetime.datetime) x = datetime.datetime.now(UTC) res = dec.decode(msgspec.msgpack.encode(x)) assert x == res @pytest.mark.parametrize( "s", [ "1234-01-02T03:04:05Z", "1234-01-02T03:04:05.123Z", "1234-01-02T03:04:05.123+00:00", ], ) def test_decode_datetime_aware_str(self, s): sol = datetime.datetime.fromisoformat(s.replace("Z", "+00:00")) msg = msgspec.msgpack.encode(s) res = msgspec.msgpack.decode(msg, type=datetime.datetime) assert sol == res @pytest.mark.parametrize( "s", [ "1234-01-02T03:04:05", "1234-01-02T03:04:05.123", "1234-01-02T03:04:05.123456", ], ) def test_decode_datetime_naive(self, s): sol = datetime.datetime.fromisoformat(s) msg = msgspec.msgpack.encode(s) res = msgspec.msgpack.decode(msg, type=datetime.datetime) assert sol == res def test_datetime_unexpected_type(self): self.check_unexpected_type(datetime.datetime, 1, "Expected `datetime`") self.check_unexpected_type( datetime.datetime, msgspec.msgpack.Ext(1, b"test"), "Expected `datetime`" ) def test_datetime_invalid(self): msg = msgspec.msgpack.encode(msgspec.msgpack.Ext(-1, b"\x01\x02\x03")) with pytest.raises( msgspec.ValidationError, match="Invalid MessagePack timestamp" ): msgspec.msgpack.decode(msg, type=datetime.datetime) @pytest.mark.parametrize("size", SIZES) def test_list_lengths(self, size): enc = msgspec.msgpack.Encoder() dec = msgspec.msgpack.Decoder(list) x = list(range(size)) res = dec.decode(enc.encode(x)) assert res == x @pytest.mark.parametrize("typ", [List, list, list[Any]]) def test_list_any(self, typ): enc = msgspec.msgpack.Encoder() dec = msgspec.msgpack.Decoder(typ) x = [1, "two", b"three"] res = dec.decode(enc.encode(x)) assert res == x with pytest.raises(msgspec.ValidationError, match="Expected `array`"): dec.decode(enc.encode(1)) def test_list_typed(self): enc = msgspec.msgpack.Encoder() dec = msgspec.msgpack.Decoder(list[int]) x = [1, 2, 3] res = dec.decode(enc.encode(x)) assert res == x with pytest.raises( msgspec.ValidationError, match=r"Expected `int`, got `str` - at `\$\[2\]`", ): dec.decode(enc.encode([1, 2, "three"])) @pytest.mark.parametrize("size", SIZES) @pytest.mark.parametrize("typ", [set, frozenset]) def test_set_lengths(self, size, typ): enc = msgspec.msgpack.Encoder() dec = msgspec.msgpack.Decoder(typ) x = typ(range(size)) res = dec.decode(enc.encode(x)) assert res == x assert isinstance(res, typ) @pytest.mark.parametrize( "typ", [ Set, Set[Any], set, set[Any], FrozenSet, FrozenSet[Any], frozenset, frozenset[Any], ], ) def test_set_any(self, typ): enc = msgspec.msgpack.Encoder() dec = msgspec.msgpack.Decoder(typ) real_type = getattr(typ, "__origin__", typ) x = {1, "two", b"three"} res = dec.decode(enc.encode(x)) assert res == x assert type(res) is real_type with pytest.raises(msgspec.ValidationError, match="Expected `array`"): dec.decode(enc.encode(1)) @pytest.mark.parametrize("typ", [set, frozenset, Set, FrozenSet]) def test_set_typed(self, typ): enc = msgspec.msgpack.Encoder() dec = msgspec.msgpack.Decoder(typ[int]) x = {1, 2, 3} res = dec.decode(enc.encode(x)) assert res == x assert type(res) is getattr(typ, "__origin__", typ) with pytest.raises( msgspec.ValidationError, match=r"Expected `int`, got `str` - at `\$\[2\]`", ): dec.decode(enc.encode([1, 2, "three"])) @pytest.mark.parametrize("size", SIZES) def test_vartuple_lengths(self, size): enc = msgspec.msgpack.Encoder() dec = msgspec.msgpack.Decoder(tuple) x = tuple(f"x{i}x" for i in range(size)) res = dec.decode(enc.encode(x)) assert res == x if res: assert sys.getrefcount(res[0]) <= 3 # 1 tuple, 1 index, 1 func call @pytest.mark.parametrize("typ", [Tuple, Tuple[Any, ...], tuple, tuple[Any, ...]]) def test_vartuple_any(self, typ): enc = msgspec.msgpack.Encoder() dec = msgspec.msgpack.Decoder(typ) x = (1, "two", b"three") res = dec.decode(enc.encode(x)) assert res == x with pytest.raises( msgspec.ValidationError, match="Expected `array`, got `int`" ): dec.decode(enc.encode(1)) def test_vartuple_typed(self): enc = msgspec.msgpack.Encoder() dec = msgspec.msgpack.Decoder(tuple[int, ...]) x = (1, 2, 3) res = dec.decode(enc.encode(x)) assert res == x with pytest.raises( msgspec.ValidationError, match=r"Expected `int`, got `str` - at `\$\[2\]`", ): dec.decode(enc.encode((1, 2, "three"))) def test_fixtuple_any(self): enc = msgspec.msgpack.Encoder() dec = msgspec.msgpack.Decoder(tuple[Any, Any, Any]) x = (1, "two", b"three") res = dec.decode(enc.encode(x)) assert res == x with pytest.raises( msgspec.ValidationError, match="Expected `array`, got `int`" ): dec.decode(enc.encode(1)) with pytest.raises( msgspec.ValidationError, match="Expected `array` of length 3, got 2" ): dec.decode(enc.encode((1, 2))) def test_fixtuple_typed(self): enc = msgspec.msgpack.Encoder() dec = msgspec.msgpack.Decoder(tuple[int, str, bytes]) x = (1, "two", b"three") res = dec.decode(enc.encode(x)) assert res == x with pytest.raises(msgspec.ValidationError, match="Expected `bytes`"): dec.decode(enc.encode((1, "two", "three"))) with pytest.raises( msgspec.ValidationError, match="Expected `array` of length 3, got 2" ): dec.decode(enc.encode((1, 2))) @pytest.mark.parametrize("size", SIZES) def test_dict_lengths(self, size): enc = msgspec.msgpack.Encoder() dec = msgspec.msgpack.Decoder(dict) x = {i: i for i in range(size)} res = dec.decode(enc.encode(x)) assert res == x @pytest.mark.parametrize("typ", [Dict, dict, dict[Any, Any]]) def test_dict_any_any(self, typ): enc = msgspec.msgpack.Encoder() dec = msgspec.msgpack.Decoder(typ) x = {1: "one", "two": 2, b"three": 3.0} res = dec.decode(enc.encode(x)) assert res == x with pytest.raises( msgspec.ValidationError, match=r"Expected `object`, got `int`" ): dec.decode(enc.encode(1)) def test_dict_any_val(self): enc = msgspec.msgpack.Encoder() dec = msgspec.msgpack.Decoder(dict[str, Any]) x = {"a": 1, "b": "two", "c": b"three"} res = dec.decode(enc.encode(x)) assert res == x with pytest.raises( msgspec.ValidationError, match=r"Expected `str`, got `int` - at `key` in `\$`", ): dec.decode(enc.encode({1: 2})) def test_dict_any_key(self): enc = msgspec.msgpack.Encoder() dec = msgspec.msgpack.Decoder(dict[Any, str]) x = {1: "a", "two": "b", b"three": "c"} res = dec.decode(enc.encode(x)) assert res == x with pytest.raises( msgspec.ValidationError, match=r"Expected `str`, got `int` - at `\$\[...\]`" ): dec.decode(enc.encode({1: 2})) def test_dict_str_subclass_key(self): class mystr(str): pass msg1 = msgspec.msgpack.encode({mystr("test"): 1}) msg2 = msgspec.msgpack.encode({"test": 1}) assert msg1 == msg2 def test_dict_typed(self): enc = msgspec.msgpack.Encoder() dec = msgspec.msgpack.Decoder(dict[str, int]) x = {"a": 1, "b": 2} res = dec.decode(enc.encode(x)) assert res == x with pytest.raises( msgspec.ValidationError, match=r"Expected `str`, got `int` - at `key` in `\$`", ): dec.decode(enc.encode({1: 2})) with pytest.raises( msgspec.ValidationError, match=r"Expected `int`, got `str` - at `\$\[...\]`" ): dec.decode(enc.encode({"a": "two"})) def test_dict_typed_non_str_key(self): enc = msgspec.msgpack.Encoder() dec = msgspec.msgpack.Decoder(dict[int, int]) x = {0: 1, 2: 3} res = dec.decode(enc.encode(x)) assert res == x with pytest.raises( msgspec.ValidationError, match=r"Expected `int`, got `str` - at `key` in `\$`", ): dec.decode(enc.encode({"bad": 2})) def test_enum(self): enc = msgspec.msgpack.Encoder() dec = msgspec.msgpack.Decoder(FruitStr) a = enc.encode(FruitStr.APPLE) assert enc.encode("apple") == a assert dec.decode(a) == FruitStr.APPLE with pytest.raises(msgspec.DecodeError, match="truncated"): dec.decode(a[:-2]) with pytest.raises( msgspec.ValidationError, match="Invalid enum value 'MISSING'" ): dec.decode(enc.encode("MISSING")) with pytest.raises( msgspec.ValidationError, match=r"Invalid enum value 'MISSING' - at `\$\[0\]`", ): msgspec.msgpack.decode(enc.encode(["MISSING"]), type=list[FruitStr]) with pytest.raises(msgspec.ValidationError): dec.decode(enc.encode(1)) def test_int_enum(self): enc = msgspec.msgpack.Encoder() dec = msgspec.msgpack.Decoder(FruitInt) a = enc.encode(FruitInt.APPLE) assert enc.encode(1) == a assert dec.decode(a) == FruitInt.APPLE with pytest.raises(msgspec.DecodeError, match="truncated"): dec.decode(a[:-2]) with pytest.raises(msgspec.ValidationError, match="Invalid enum value 1000"): dec.decode(enc.encode(1000)) with pytest.raises( msgspec.ValidationError, match=r"Invalid enum value 1000 - at `\$\[0\]`" ): msgspec.msgpack.decode(enc.encode([1000]), type=list[FruitInt]) with pytest.raises(msgspec.ValidationError): dec.decode(enc.encode("INVALID")) def test_str_literal(self): literal = Literal["one", "two"] enc = msgspec.msgpack.Encoder() dec = msgspec.msgpack.Decoder(literal) assert dec.decode(enc.encode("one")) == "one" with pytest.raises( msgspec.ValidationError, match="Invalid enum value 'MISSING'" ): dec.decode(enc.encode("MISSING")) with pytest.raises( msgspec.ValidationError, match=r"Invalid enum value 'MISSING' - at `\$\[0\]`", ): msgspec.msgpack.decode(enc.encode(["MISSING"]), type=list[literal]) def test_int_literal(self): literal = Literal[1, 2, 3] enc = msgspec.msgpack.Encoder() dec = msgspec.msgpack.Decoder(literal) assert dec.decode(enc.encode(1)) == 1 with pytest.raises(msgspec.ValidationError, match="Invalid enum value 1000"): dec.decode(enc.encode(1000)) with pytest.raises( msgspec.ValidationError, match=r"Invalid enum value 1000 - at `\$\[0\]`" ): msgspec.msgpack.decode(enc.encode([1000]), type=list[literal]) @pytest.mark.parametrize( "typ, value", [ (bool, False), (bool, True), (int, 1), (float, 2.5), (str, "a"), (bytes, b"a"), (bytearray, bytearray(b"a")), (FruitInt, FruitInt.APPLE), (FruitStr, FruitStr.APPLE), (Person, Person("harry", "potter", 13)), (list, [1]), (set, {1}), (tuple, (1, 2)), (tuple[int, int], (1, 2)), (dict, {1: 2}), (datetime.datetime, datetime.datetime.now(UTC)), ], ) @pytest.mark.parametrize( "optional_builder", [ lambda typ: Optional[typ], lambda typ: typ | None, ], ) def test_optional(self, typ, value, optional_builder): enc = msgspec.msgpack.Encoder() dec = msgspec.msgpack.Decoder(optional_builder(typ)) s = enc.encode(value) s2 = enc.encode(None) assert dec.decode(s) == value assert dec.decode(s2) is None dec = msgspec.msgpack.Decoder(typ) with pytest.raises(msgspec.ValidationError): dec.decode(s2) @pytest.mark.parametrize( "typ, value", [ (list[Optional[int]], [1, None]), (list[int | None], [1, None]), (tuple[int | None, int], (None, 1)), (set[int | None], {1, None}), (frozenset[int | None], frozenset({1, None})), (dict[str, int | None], {"a": 1, "b": None}), (dict[str | None, int], {"a": 1, None: 2}), ], ) def test_optional_nested(self, typ, value): enc = msgspec.msgpack.Encoder() dec = msgspec.msgpack.Decoder(typ) s = enc.encode(value) assert dec.decode(s) == value @pytest.mark.parametrize( "types, vals", [ ([int, float], [1, 2.5]), ( [float, msgspec.msgpack.Ext, int, str], [1.5, msgspec.msgpack.Ext(1, b"two"), 1, "two"], ), ([bool, None, float, str], [True, None, 1.5, "test"]), ], ) def test_old_union(self, types, vals): dec = msgspec.msgpack.Decoder(list[Union[tuple(types)]]) s = msgspec.msgpack.encode(vals) res = dec.decode(s) assert res == vals for t, v in zip(types, res): if t is not None: t = getattr(t, "__origin__", t) assert type(v) == t @pytest.mark.parametrize( "typ, vals", [ (int | float, [1, 2.5]), ( float | msgspec.msgpack.Ext | int | str, [1.5, msgspec.msgpack.Ext(1, b"two"), 1, "two"], ), (bool | float | str | None, [True, None, 1.5, "test"]), ], ) def test_union(self, typ, vals): dec = msgspec.msgpack.Decoder(list[typ]) s = msgspec.msgpack.encode(vals) res = dec.decode(s) assert res == vals for v in res: assert isinstance(v, typ) @pytest.mark.parametrize( "types, vals", [ ( [PersonArray, FruitInt, FruitStr, dict[int, str]], [PERSON_AA, FruitInt.APPLE, FruitStr.BANANA, {1: "two"}], ), ( [Person, FruitInt, FruitStr, tuple[int, ...]], [PERSON, FruitInt.APPLE, FruitStr.BANANA, (1, 2, 3)], ), ( [Person, FruitInt, FruitStr, list[int]], [PERSON, FruitInt.APPLE, FruitStr.BANANA, [1, 2, 3]], ), ( [Person, FruitInt, FruitStr, set[int]], [PERSON, FruitInt.APPLE, FruitStr.BANANA, {1, 2, 3}], ), ( [Person, FruitInt, FruitStr, tuple[int, str, float]], [PERSON, FruitInt.APPLE, FruitStr.BANANA, (1, "two", 3.5)], ), ( [dict[int, str], FruitInt, FruitStr, tuple[int, ...]], [{1: "two"}, FruitInt.APPLE, FruitStr.BANANA, (1, 2, 3)], ), ( [dict[int, str], FruitInt, FruitStr, list[int]], [{1: "two"}, FruitInt.APPLE, FruitStr.BANANA, [1, 2, 3]], ), ( [dict[int, str], FruitInt, FruitStr, set[int]], [{1: "two"}, FruitInt.APPLE, FruitStr.BANANA, {1, 2, 3}], ), ( [dict[int, str], FruitInt, FruitStr, tuple[int, str, float]], [{1: "two"}, FruitInt.APPLE, FruitStr.BANANA, (1, "two", 3.5)], ), ], ) def test_compound_type_unions(self, types, vals): typ_vals = list(zip(types, vals)) for N in range(2, len(typ_vals)): for typ_vals_subset in itertools.combinations(typ_vals, N): types, vals = zip(*typ_vals_subset) vals = list(vals) dec = msgspec.msgpack.Decoder(list[Union[types]]) s = msgspec.msgpack.encode(vals) res = dec.decode(s) assert res == vals for t, v in zip(types, res): t = getattr(t, "__origin__", t) assert type(v) == t def test_union_error(self): msg = msgspec.msgpack.encode(1) with pytest.raises( msgspec.ValidationError, match="Expected `bool | string`, got `int`" ): msgspec.msgpack.decode(msg, type=bool | str) def test_decoding_error_no_struct_toplevel(self): b = msgspec.msgpack.Encoder().encode([{"a": 1}]) dec = msgspec.msgpack.Decoder(list[dict[str, str]]) with pytest.raises( msgspec.ValidationError, match=r"Expected `str`, got `int` - at `\$\[0\]\[...\]`", ): dec.decode(b) class TestExt: @pytest.mark.parametrize("data", [b"test", bytearray(b"test"), memoryview(b"test")]) def test_init(self, data): x = msgspec.msgpack.Ext(1, data) assert x.code == 1 assert x.data == data def test_init_bad_arguments(self): with pytest.raises(TypeError, match="Ext takes no keyword arguments"): msgspec.msgpack.Ext(code=1, data=b"two") with pytest.raises(TypeError, match="expected 2 arguments, got 3"): msgspec.msgpack.Ext(1, b"two", 3) with pytest.raises(TypeError, match="expected 2 arguments, got 0"): msgspec.msgpack.Ext() def test_compare(self): x = msgspec.msgpack.Ext(1, b"two") x2 = msgspec.msgpack.Ext(1, b"two") x3 = msgspec.msgpack.Ext(1, b"three") x4 = msgspec.msgpack.Ext(2, b"two") assert x == x2 assert not (x != x2) assert x != x3 assert not (x == x3) assert x != x4 assert not (x == x4) assert not (x == 1) assert x != 1 with pytest.raises(TypeError): x >= x2 @pytest.mark.parametrize("code", [-128, -2, 0, 2, 127]) def test_code_roundtrip(self, code): ext = msgspec.msgpack.Ext(code, b"") assert ext.code == code ext2 = msgspec.msgpack.decode(msgspec.msgpack.encode(ext)) assert ext2.code == code @pytest.mark.parametrize("code", [-129, 128, 2**65]) def test_code_out_of_range(self, code): with pytest.raises(ValueError): msgspec.msgpack.Ext(code, b"bad") def test_data_wrong_type(self): with pytest.raises(TypeError): msgspec.msgpack.Ext(1, 2) def test_code_wrong_type(self): with pytest.raises(TypeError): msgspec.msgpack.Ext(b"bad", b"bad") def test_immutable(self): x = msgspec.msgpack.Ext(1, b"two") with pytest.raises(AttributeError): x.code = 2 @pytest.mark.parametrize("protocol", range(pickle.HIGHEST_PROTOCOL + 1)) def test_pickleable(self, protocol): x = msgspec.msgpack.Ext(1, b"two") x2 = pickle.loads(pickle.dumps(x, protocol=protocol)) assert x2.code == 1 assert x2.data == b"two" @pytest.mark.parametrize("size", sorted({0, 1, 2, 4, 8, 16, *SIZES})) def test_serialize_compatibility(self, size): msgpack = pytest.importorskip("msgpack") data = b"x" * size code = 5 msgspec_bytes = msgspec.msgpack.encode(msgspec.msgpack.Ext(code, data)) msgpack_bytes = msgpack.dumps(msgpack.ExtType(code, data)) assert msgspec_bytes == msgpack_bytes @pytest.mark.parametrize("typ", [bytearray, memoryview]) def test_serialize_other_types(self, typ): buf = b"test" a = msgspec.msgpack.encode(msgspec.msgpack.Ext(1, buf)) ext = msgspec.msgpack.Ext(1, typ(buf)) assert isinstance(ext.data, typ) b = msgspec.msgpack.encode(ext) assert a == b decoded = msgspec.msgpack.decode(b) assert isinstance(decoded.data, bytes) assert decoded.data == buf def test_other_buffers(self): buf = array.array("i", [1, 2, 3, 4]) out = msgspec.msgpack.decode( msgspec.msgpack.encode(msgspec.msgpack.Ext(1, buf)), ) assert isinstance(out.data, bytes) assert array.array("i", out.data) == buf @pytest.mark.parametrize("size", sorted({0, 1, 2, 4, 8, 16, *SIZES})) def test_roundtrip(self, size): data = b"x" * size code = 5 buf = msgspec.msgpack.encode(msgspec.msgpack.Ext(code, data)) out = msgspec.msgpack.decode(buf) assert out.code == code assert out.data == data @pytest.mark.parametrize("size", sorted({0, 1, 2, 4, 8, 16, *SIZES})) def test_roundtrip_typed_decoder(self, size): dec = msgspec.msgpack.Decoder(msgspec.msgpack.Ext) ext = msgspec.msgpack.Ext(5, b"x" * size) buf = msgspec.msgpack.encode(ext) out = dec.decode(buf) assert out == ext @pytest.mark.parametrize("type", [None, msgspec.msgpack.Ext]) def test_decode_ext_no_reference_leak(self, type): """https://github.com/msgspec/msgspec/issues/1108""" buf = msgspec.msgpack.encode(msgspec.msgpack.Ext(5, b"ext-leak-test-payload")) kwargs = {} if type is None else {"type": type} ext = msgspec.msgpack.decode(buf, **kwargs) data = ext.data del ext assert sys.getrefcount(data) <= 2 # `data` + getrefcount argument def test_typed_decoder_skips_ext_hook(self): def ext_hook(code, data): assert False, "shouldn't ever get called" msg = [None, msgspec.msgpack.Ext(1, b"test")] dec = msgspec.msgpack.Decoder(list[msgspec.msgpack.Ext | None]) buf = msgspec.msgpack.encode(msg) out = dec.decode(buf) assert out == msg def test_ext_typed_decoder_error(self): dec = msgspec.msgpack.Decoder(msgspec.msgpack.Ext) with pytest.raises(msgspec.ValidationError, match="Expected `ext`, got `int`"): assert dec.decode(msgspec.msgpack.encode(1)) @pytest.mark.parametrize("use_function", [True, False]) @pytest.mark.parametrize("protocol", range(pickle.HIGHEST_PROTOCOL + 1)) def test_decoder_ext_hook(self, use_function, protocol): obj = {"x": range(10)} def enc_hook(x): return msgspec.msgpack.Ext(5, pickle.dumps(x, protocol=protocol)) def ext_hook(code, buf): assert isinstance(buf, memoryview) assert code == 5 return pickle.loads(buf) msg = msgspec.msgpack.encode(obj, enc_hook=enc_hook) if use_function: out = msgspec.msgpack.decode(msg, ext_hook=ext_hook) else: dec = msgspec.msgpack.Decoder(ext_hook=ext_hook) out = dec.decode(msg) assert out == obj def test_decoder_ext_hook_bad_signature(self): msg = msgspec.msgpack.encode( range(5), enc_hook=lambda x: msgspec.msgpack.Ext(1, b"test") ) with pytest.raises(TypeError): msgspec.msgpack.decode(msg, ext_hook=lambda: None) def test_decoder_ext_hook_raises(self): class CustomError(Exception): pass def ext_hook(code, buf): raise CustomError msg = msgspec.msgpack.encode( range(5), enc_hook=lambda x: msgspec.msgpack.Ext(1, b"test") ) with pytest.raises(CustomError): msgspec.msgpack.decode(msg, ext_hook=ext_hook) class TestTimestampExt: def check(self, dt, msg): assert msgspec.msgpack.encode(dt) == msg assert msgspec.msgpack.decode(msg) == dt def test_timestamp32_lower(self): dt = datetime.datetime.fromtimestamp(0, UTC) msg = b"\xd6\xff\x00\x00\x00\x00" self.check(dt, msg) def test_timestamp32_upper(self): dt = datetime.datetime.fromtimestamp(2**32 - 1, UTC) msg = b"\xd6\xff\xff\xff\xff\xff" self.check(dt, msg) def test_timestamp64_lower(self): dt = datetime.datetime.fromtimestamp(1e-6, UTC) msg = b"\xd7\xff\x00\x00\x0f\xa0\x00\x00\x00\x00" self.check(dt, msg) def test_timestamp64_upper(self): dt = datetime.datetime.fromtimestamp(2**34, UTC) - datetime.timedelta( microseconds=1 ) msg = b"\xd7\xff\xeek\x18c\xff\xff\xff\xff" self.check(dt, msg) def test_timestamp96_lower(self): dt = datetime.datetime.fromtimestamp(-1e-6, UTC) msg = b"\xc7\x0c\xff;\x9a\xc6\x18\xff\xff\xff\xff\xff\xff\xff\xff" self.check(dt, msg) def test_timestamp96_upper(self): dt = datetime.datetime.fromtimestamp(2**34, UTC) msg = b"\xc7\x0c\xff\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00" self.check(dt, msg) @pytest.mark.parametrize( "msg, secs, micros", [ (b"\xd7\xff\x00\x00\x07\xd0\x00\x00\x00\x00", 0, 1), (b"\xd7\xff\x00\x00\x07\xcc\x00\x00\x00\x00", 0, 0), (b"\xd7\xff\xeek 0\x00\x00\x00\x00", 1, 0), (b"\xd7\xff\xeek ,\x00\x00\x00\x00", 0, 999999), ], ) def test_timestamp_rounds_nanos(self, msg, secs, micros): res = msgspec.msgpack.decode(msg) assert res.second == secs assert res.microsecond == micros class CommonTypeTestBase: """Test msgspec untyped encode/decode""" def test_none(self): self.check(None) @pytest.mark.parametrize("x", [False, True]) def test_bool(self, x): self.check(x) @pytest.mark.parametrize("x", INTS) def test_int(self, x): self.check(x) @pytest.mark.parametrize("x", FLOATS) def test_float(self, x): self.check(x) @pytest.mark.parametrize("size", SIZES) def test_str(self, size): self.check(" " * size) @pytest.mark.parametrize("size", SIZES) def test_bytes(self, size): self.check(b" " * size) @pytest.mark.parametrize("size", SIZES) def test_dict(self, size): self.check({str(i): i for i in range(size)}) @pytest.mark.parametrize("size", SIZES) def test_list(self, size): self.check(list(range(size))) class TestDecodeArrayTypeUsesTupleIfHashableRequired: def test_decode_tuple_dict_keys_as_tuples(self): orig = {(1, 2): [1, 2, [3, 4]], (1, (2, 3)): [4, 5, 6], tuple(range(32)): []} data = msgspec.msgpack.encode(orig) out = msgspec.msgpack.decode(data) assert orig == out @pytest.mark.parametrize( "typ", [ dict[tuple[int, tuple[int, int]], list[int]], dict[tuple[int, tuple[int, ...]], Any], dict[tuple, list[int]], dict[tuple[Any, ...], Any], dict[tuple[Any, Any], Any], ], ) def test_decode_dict_key_status_forwarded_through_typed_tuples(self, typ): orig = {(1, (2, 3)): [1, 2, 3]} data = msgspec.msgpack.encode(orig) out = msgspec.msgpack.Decoder(typ).decode(data) assert orig == out def test_decode_tuple_set_keys_as_tuples(self): orig = {(1, 2), (3, (4, 5)), 6} data = msgspec.msgpack.encode(orig) out = msgspec.msgpack.decode(data, type=set) assert orig == out def test_decode_hashable_struct_in_key(self): class Test(msgspec.Struct): data: list[int] def __hash__(self): return hash(tuple(self.data)) orig = {(1, Test([1, 2])): [1, 2]} data = msgspec.msgpack.encode(orig) out = msgspec.msgpack.Decoder(dict[tuple[int, Test], list[int]]).decode(data) assert orig == out class TestUntypedDecoder(CommonTypeTestBase): """Check the untyped deserializer works for common types""" def check(self, x): enc = msgspec.msgpack.Encoder() dec = msgspec.msgpack.Decoder() assert_eq(dec.decode(enc.encode(x)), x) class TestCompatibility(CommonTypeTestBase): """Test compatibility with the existing python msgpack library""" def check(self, x): msgpack = pytest.importorskip("msgpack") enc = msgspec.msgpack.Encoder() dec = msgspec.msgpack.Decoder() assert_eq(dec.decode(msgpack.dumps(x)), x) assert_eq(msgpack.loads(enc.encode(x)), x) class TestStruct: @pytest.mark.parametrize("tag", [False, "Test", 123]) def test_encode_empty_struct(self, tag): class Test(msgspec.Struct, tag=tag): pass if tag: msg = {"type": tag} else: msg = {} s = msgspec.msgpack.encode(Test()) s2 = msgspec.msgpack.encode(msg) assert s == s2 @pytest.mark.parametrize("tag", [False, "Test", 123]) def test_encode_one_field_struct(self, tag): class Test(msgspec.Struct, tag=tag): a: int if tag: msg = {"type": tag, "a": 1} else: msg = {"a": 1} s = msgspec.msgpack.encode(Test(a=1)) s2 = msgspec.msgpack.encode(msg) assert s == s2 @pytest.mark.parametrize("tag", [False, "Test", 123]) def test_encode_two_field_struct(self, tag): class Test(msgspec.Struct, tag=tag): a: int b: str if tag: msg = {"type": tag, "a": 1, "b": "two"} else: msg = {"a": 1, "b": "two"} s = msgspec.msgpack.encode(Test(a=1, b="two")) s2 = msgspec.msgpack.encode(msg) assert s == s2 def test_decode_struct(self): dec = msgspec.msgpack.Decoder(Person) msg = msgspec.msgpack.encode( {"first": "harry", "last": "potter", "age": 13, "prefect": False} ) x = dec.decode(msg) assert x == Person("harry", "potter", 13, False) with pytest.raises( msgspec.ValidationError, match="Expected `object`, got `int`" ): dec.decode(msgspec.msgpack.encode(1)) def test_decode_struct_field_wrong_type(self): dec = msgspec.msgpack.Decoder(Person) msg = msgspec.msgpack.encode({"first": "harry", "last": "potter", "age": "bad"}) with pytest.raises( msgspec.ValidationError, match=r"Expected `int`, got `str` - at `\$.age`" ): dec.decode(msg) def test_decode_struct_missing_fields(self): bad = msgspec.msgpack.encode({"first": "harry", "last": "potter"}) with pytest.raises( msgspec.ValidationError, match="Object missing required field `age`" ): msgspec.msgpack.decode(bad, type=Person) bad = msgspec.msgpack.encode({}) with pytest.raises( msgspec.ValidationError, match="Object missing required field `first`" ): msgspec.msgpack.decode(bad, type=Person) bad = msgspec.msgpack.encode([{"first": "harry", "last": "potter"}]) with pytest.raises( msgspec.ValidationError, match=r"Object missing required field `age` - at `\$\[0\]`", ): msgspec.msgpack.decode(bad, type=list[Person]) @pytest.mark.parametrize( "extra", [ None, False, True, 1, 2.0, "three", b"four", [1, 2], {3: 4}, msgspec.msgpack.Ext(1, b"12345"), msgspec.msgpack.Ext(1, b""), ], ) def test_decode_struct_ignore_extra_fields(self, extra): enc = msgspec.msgpack.Encoder() dec = msgspec.msgpack.Decoder(Person) a = enc.encode( { "extra1": extra, "first": "harry", "extra2": extra, "last": "potter", "age": 13, "extra3": extra, } ) res = dec.decode(a) assert res == Person("harry", "potter", 13) def test_decode_struct_defaults_missing_fields(self): dec = msgspec.msgpack.Decoder(Person) a = msgspec.msgpack.encode({"first": "harry", "last": "potter", "age": 13}) res = dec.decode(a) assert res == Person("harry", "potter", 13) assert res.prefect is False @pytest.mark.parametrize("array_like", [False, True]) def test_struct_gc_maybe_untracked_on_decode(self, array_like): class Test(msgspec.Struct, array_like=array_like): x: Any y: Any z: tuple = () enc = msgspec.msgpack.Encoder() dec = msgspec.msgpack.Decoder(list[Test]) ts = [ Test(1, 2), Test(3, "hello"), Test([], []), Test({}, {}), Test(None, None, ()), ] a, b, c, d, e = dec.decode(enc.encode(ts)) assert not gc.is_tracked(a) assert not gc.is_tracked(b) assert gc.is_tracked(c) assert gc.is_tracked(d) assert not gc.is_tracked(e) @pytest.mark.parametrize("array_like", [False, True]) def test_struct_gc_false_always_untracked_on_decode(self, array_like): class Test(msgspec.Struct, array_like=array_like, gc=False): x: Any y: Any dec = msgspec.msgpack.Decoder(list[Test]) ts = [ Test(1, 2), Test([], []), Test({}, {}), ] for obj in dec.decode(msgspec.msgpack.encode(ts)): assert not gc.is_tracked(obj) def test_struct_recursive_definition(self): enc = msgspec.msgpack.Encoder() dec = msgspec.msgpack.Decoder(Node) x = Node(Node(Node(), Node(Node()))) s = enc.encode(x) res = dec.decode(s) assert res == x @pytest.mark.parametrize("tag", ["Test", 123, -123]) def test_decode_tagged_struct(self, tag): class Test(msgspec.Struct, tag=tag): a: int b: int dec = msgspec.msgpack.Decoder(Test) # Test decode with and without tag for msg in [ {"a": 1, "b": 2}, {"type": tag, "a": 1, "b": 2}, {"a": 1, "type": tag, "b": 2}, ]: res = dec.decode(msgspec.msgpack.encode(msg)) assert res == Test(1, 2) # Tag incorrect type with pytest.raises(msgspec.ValidationError) as rec: dec.decode(msgspec.msgpack.encode({"type": 123.456})) assert f"Expected `{type(tag).__name__}`" in str(rec.value) assert "`$.type`" in str(rec.value) # Tag incorrect value bad = -3 if isinstance(tag, int) else "bad" with pytest.raises(msgspec.ValidationError) as rec: dec.decode(msgspec.msgpack.encode({"type": bad})) assert f"Invalid value {bad!r}" in str(rec.value) assert "`$.type`" in str(rec.value) @pytest.mark.parametrize("tag", [i for i in INTS if -(2**63) <= i < 2**63]) def test_decode_tagged_struct_int_ranges(self, tag): class Test(msgspec.Struct, tag=tag): a: int b: int dec = msgspec.msgpack.Decoder(Test) t = Test(1, 2) assert dec.decode(msgspec.msgpack.encode(t)) def test_decode_tagged_struct_int_tag_uint64_always_invalid(self): """Uint64 values aren't currently valid tag values, but we still want to raise a good error message.""" class Test(msgspec.Struct, tag=123): pass with pytest.raises(msgspec.ValidationError) as rec: msgspec.msgpack.decode( msgspec.msgpack.encode({"type": 2**64 - 1}), type=Test ) assert f"Invalid value {2**64 - 1}" in str(rec.value) assert "`$.type`" in str(rec.value) @pytest.mark.parametrize("tag", ["Test", 123, -123]) def test_decode_tagged_empty_struct(self, tag): class Test(msgspec.Struct, tag=tag): pass dec = msgspec.msgpack.Decoder(Test) # Tag missing res = dec.decode(msgspec.msgpack.encode({})) assert res == Test() # Tag present res = dec.decode(msgspec.msgpack.encode({"type": tag})) assert res == Test() class TestStructArray: @pytest.mark.parametrize("tag", [False, "Test", 123]) def test_encode_empty_struct(self, tag): class Test(msgspec.Struct, array_like=True, tag=tag): pass s = msgspec.msgpack.encode(Test()) if tag: msg = [tag] else: msg = [] s2 = msgspec.msgpack.encode(msg) assert s == s2 @pytest.mark.parametrize("tag", [False, "Test", 123]) def test_encode_one_field_struct(self, tag): class Test(msgspec.Struct, array_like=True, tag=tag): a: int s = msgspec.msgpack.encode(Test(a=1)) if tag: msg = [tag, 1] else: msg = [1] s2 = msgspec.msgpack.encode(msg) assert s == s2 @pytest.mark.parametrize("tag", [False, "Test", 123]) def test_encode_two_field_struct(self, tag): class Test(msgspec.Struct, array_like=True, tag=tag): a: int b: str s = msgspec.msgpack.encode(Test(a=1, b="two")) if tag: msg = [tag, 1, "two"] else: msg = [1, "two"] s2 = msgspec.msgpack.encode(msg) assert s == s2 def test_struct_array_like(self): dec = msgspec.msgpack.Decoder(PersonArray) x = PersonArray(first="harry", last="potter", age=13) a = msgspec.msgpack.encode(x) assert msgspec.msgpack.encode(("harry", "potter", 13, False)) == a assert dec.decode(a) == x with pytest.raises( msgspec.ValidationError, match="Expected `array`, got `int`" ): dec.decode(b"1") # Wrong field type bad = msgspec.msgpack.encode(("harry", "potter", "thirteen")) with pytest.raises( msgspec.ValidationError, match=r"Expected `int`, got `str` - at `\$\[2\]`" ): dec.decode(bad) # Missing fields bad = msgspec.msgpack.encode(("harry", "potter")) with pytest.raises( msgspec.ValidationError, match="Expected `array` of at least length 3, got 2", ): dec.decode(bad) bad = msgspec.msgpack.encode(()) with pytest.raises( msgspec.ValidationError, match="Expected `array` of at least length 3, got 0", ): dec.decode(bad) # Extra fields ignored dec2 = msgspec.msgpack.Decoder(list[PersonArray]) msg = msgspec.msgpack.encode( [ ("harry", "potter", 13, False, 1, 2, 3, 4), ("ron", "weasley", 13, False, 5, 6), ] ) res = dec2.decode(msg) assert res == [ PersonArray("harry", "potter", 13), PersonArray("ron", "weasley", 13), ] # Defaults applied res = dec.decode(msgspec.msgpack.encode(("harry", "potter", 13))) assert res == PersonArray("harry", "potter", 13) assert res.prefect is False def test_struct_map_and_array_like_messages_cant_mix(self): array_msg = msgspec.msgpack.encode(("harry", "potter", 13)) map_msg = msgspec.msgpack.encode( {"first": "harry", "last": "potter", "age": 13} ) sol = Person("harry", "potter", 13) array_sol = PersonArray("harry", "potter", 13) dec = msgspec.msgpack.Decoder(Person) array_dec = msgspec.msgpack.Decoder(PersonArray) assert array_dec.decode(array_msg) == array_sol assert dec.decode(map_msg) == sol with pytest.raises( msgspec.ValidationError, match="Expected `object`, got `array`" ): dec.decode(array_msg) with pytest.raises( msgspec.ValidationError, match="Expected `array`, got `object`" ): array_dec.decode(map_msg) @pytest.mark.parametrize("tag", ["Test", -123, 123]) def test_decode_tagged_struct(self, tag): class Test(msgspec.Struct, tag=tag, array_like=True): a: int b: int c: int = 0 dec = msgspec.msgpack.Decoder(Test) # Decode with tag res = dec.decode(msgspec.msgpack.encode([tag, 1, 2])) assert res == Test(1, 2) res = dec.decode(msgspec.msgpack.encode([tag, 1, 2, 3])) assert res == Test(1, 2, 3) # Trailing fields ignored res = dec.decode(msgspec.msgpack.encode([tag, 1, 2, 3, 4])) assert res == Test(1, 2, 3) # Missing required field errors with pytest.raises(msgspec.ValidationError) as rec: dec.decode(msgspec.msgpack.encode([tag, 1])) assert "Expected `array` of at least length 3, got 2" in str(rec.value) # Tag missing with pytest.raises(msgspec.ValidationError) as rec: dec.decode(msgspec.msgpack.encode([])) assert "Expected `array` of at least length 3, got 0" in str(rec.value) # Tag incorrect type with pytest.raises(msgspec.ValidationError) as rec: dec.decode(msgspec.msgpack.encode([123.456, 2, 3])) assert f"Expected `{type(tag).__name__}`" in str(rec.value) assert "`$[0]`" in str(rec.value) # Tag incorrect value bad = -3 if isinstance(tag, int) else "bad" with pytest.raises(msgspec.ValidationError) as rec: dec.decode(msgspec.msgpack.encode([bad, 1, 2])) assert f"Invalid value {bad!r}" in str(rec.value) assert "`$[0]`" in str(rec.value) # Field incorrect type correct index with pytest.raises(msgspec.ValidationError) as rec: dec.decode(msgspec.msgpack.encode([tag, "a", 2])) assert "Expected `int`, got `str`" in str(rec.value) assert "`$[1]`" in str(rec.value) @pytest.mark.parametrize("tag", ["Test", 123, -123]) def test_decode_tagged_empty_struct(self, tag): class Test(msgspec.Struct, tag=tag, array_like=True): pass dec = msgspec.msgpack.Decoder(Test) # Decode with tag res = dec.decode(msgspec.msgpack.encode([tag, 1, 2])) assert res == Test() # Tag missing with pytest.raises(msgspec.ValidationError) as rec: dec.decode(msgspec.msgpack.encode([])) assert "Expected `array` of at least length 1, got 0" in str(rec.value) class TestRaw: def test_encode_raw(self): b = msgspec.msgpack.encode({"x": 1}) r = msgspec.Raw(b) assert msgspec.msgpack.encode(r) == b assert msgspec.msgpack.encode({"y": r}) == msgspec.msgpack.encode( {"y": {"x": 1}} ) def test_decode_raw_field(self): class Test(msgspec.Struct): x: int y: msgspec.Raw s = msgspec.msgpack.encode({"x": 1, "y": [1, 2, 3]}) res = msgspec.msgpack.decode(s, type=Test) assert res.x == 1 assert bytes(res.y) == msgspec.msgpack.encode([1, 2, 3]) def test_decode_raw_optional_field(self): default = msgspec.Raw() class Test(msgspec.Struct): x: int y: msgspec.Raw = default s = msgspec.msgpack.encode({"x": 1, "y": [1, 2, 3]}) res = msgspec.msgpack.decode(s, type=Test) assert res.x == 1 assert bytes(res.y) == msgspec.msgpack.encode([1, 2, 3]) s = msgspec.msgpack.encode({"x": 1}) res = msgspec.msgpack.decode(s, type=Test) assert res.x == 1 assert res.y is default def test_decode_raw_malformed_data(self): class Test(msgspec.Struct): x: int y: msgspec.Raw s = msgspec.msgpack.encode({"x": 1, "y": [1, 2]})[:3] with pytest.raises(msgspec.DecodeError): msgspec.msgpack.decode(s, type=Test) def test_decode_raw_is_view(self): s = msgspec.msgpack.encode({"x": 1}) r = msgspec.msgpack.decode(s, type=msgspec.Raw) assert bytes(r) == s assert r.copy() is not r # actual copy indicates a view def test_raw_in_union_works_but_doesnt_change_anything(self): class Test(msgspec.Struct): x: int | str | msgspec.Raw s = msgspec.msgpack.encode({"x": 1}) r = msgspec.msgpack.decode(s, type=Test) assert r == Test(1) def test_raw_can_be_mixed_with_custom_type(self): class Test(msgspec.Struct): x: Custom | msgspec.Raw def dec_hook(typ, obj): assert typ is Custom return typ(*obj) s = msgspec.msgpack.encode({"x": [1, 2]}) res = msgspec.msgpack.decode(s, type=Test, dec_hook=dec_hook) assert res == Test(Custom(1, 2)) python-msgspec-0.22.0/tests/unit/test_performance.py000066400000000000000000000021721525673062400226220ustar00rootroot00000000000000import textwrap import msgspec from .utils import temp_module def test_process_large_recursive_union(): """ A recursive schema processing perf test from https://github.com/pydantic/pydantic/issues/8499 This test is mostly to ensure that processing deeply recursive schemas with unions succeeds. """ def gen_code(): yield "from __future__ import annotations" yield "from msgspec import Struct" yield "from typing import Union" for i in range(50): yield textwrap.dedent( f""" class Node{i}(Struct, tag='node{i}'): data: Union[Node, None] """ ) yield "Node = Union[" for i in range(50): yield f" Node{i}," yield "]" code = "\n".join(gen_code()) with temp_module(code) as mod: dec = msgspec.json.Decoder(mod.Node) msg = b""" { "type": "node25", "data": { "type": "node13", "data": null } } """ sol = mod.Node25(mod.Node13(None)) assert dec.decode(msg) == sol python-msgspec-0.22.0/tests/unit/test_raw.py000066400000000000000000000064571525673062400211240ustar00rootroot00000000000000import operator import subprocess import sys import textwrap import weakref import pytest import msgspec requires_subprocess = pytest.mark.skipif( not getattr(subprocess, "_can_fork_exec", True), reason="subprocess support required", ) def test_raw_noargs(): r = msgspec.Raw() assert bytes(r) == b"" assert len(r) == 0 assert not r @pytest.mark.parametrize("typ", [bytes, bytearray, memoryview, str]) def test_raw_constructor(typ): msg = "test" if typ is str else typ(b"test") r = msgspec.Raw(msg) assert bytes(r) == b"test" assert len(r) == 4 assert r def test_raw_constructor_errors(): with pytest.raises(TypeError): msgspec.Raw(1) with pytest.raises(TypeError): msgspec.Raw(msg=b"test") with pytest.raises(TypeError): msgspec.Raw(b"test", b"extra") def test_raw_from_view(): r = msgspec.Raw(memoryview(b"123456")[:3]) assert bytes(r) == b"123" assert len(r) == 3 assert r def test_raw_copy(): r = msgspec.Raw(b"test") c1 = sys.getrefcount(r) r2 = r.copy() c2 = sys.getrefcount(r) assert c1 + 1 == c2 assert r2 is r r = msgspec.Raw() assert r.copy() is r m = memoryview(b"test") ref = weakref.ref(m) r = msgspec.Raw(m) del m # Raw holds a ref assert ref() is not None r2 = r.copy() # Actually copied assert r2 is not r assert bytes(r2) == b"test" # Copy doesn't accidentally release buffer assert ref() is not None del r # Copy doesn't hold a reference to original view assert ref() is None @requires_subprocess def test_raw_copy_doesnt_leak(): """See https://github.com/msgspec/msgspec/pull/709""" script = textwrap.dedent( """ import msgspec import tracemalloc tracemalloc.start() raw = msgspec.Raw(bytearray(1000)) for _ in range(10000): raw.copy() _, peak = tracemalloc.get_traced_memory() print(peak) """ ) output = subprocess.check_output([sys.executable, "-c", script]) peak = int(output.decode().strip()) assert peak < 10_000 # should really be ~2000 def test_raw_pickle_bytes(): orig_buffer = b"test" r = msgspec.Raw(orig_buffer) o = r.__reduce__() assert o == (msgspec.Raw, (b"test",)) assert o[1][0] is orig_buffer def test_raw_pickle_str(): orig_buffer = "test" r = msgspec.Raw(orig_buffer) o = r.__reduce__() assert o == (msgspec.Raw, ("test",)) assert o[1][0] is orig_buffer def test_raw_pickle_view(): r = msgspec.Raw(memoryview(b"test")[:3]) o = r.__reduce__() assert o == (msgspec.Raw, (b"tes",)) def test_raw_comparison(): r = msgspec.Raw() assert r == r assert not r != r assert msgspec.Raw() == msgspec.Raw() assert msgspec.Raw(b"") == msgspec.Raw() assert not msgspec.Raw(b"") == msgspec.Raw(b"other") assert msgspec.Raw(b"test") == msgspec.Raw(memoryview(b"testy")[:4]) assert msgspec.Raw(b"test") != msgspec.Raw(b"tesp") assert msgspec.Raw(b"test") != msgspec.Raw(b"") assert msgspec.Raw(b"") != msgspec.Raw(b"test") assert msgspec.Raw() != 1 assert 1 != msgspec.Raw() for op in [operator.lt, operator.gt, operator.le, operator.ge]: with pytest.raises(TypeError): op(msgspec.Raw(), msgspec.Raw()) python-msgspec-0.22.0/tests/unit/test_schema.py000066400000000000000000001160401525673062400215610ustar00rootroot00000000000000import datetime import decimal import enum import json import sys import typing import uuid from base64 import b64encode from collections import namedtuple from dataclasses import dataclass from typing import ( Annotated, Any, Dict, FrozenSet, Generic, List, Literal, NamedTuple, NewType, Optional, Set, Tuple, TypedDict, TypeVar, Union, ) import pytest import msgspec from msgspec import Meta from .utils import py315_or_later_only, temp_module if sys.version_info >= (3, 15): # This is needed for `ruff` to recognize `frozendict` name # and to not raise `F821`: from builtins import frozendict T = TypeVar("T") def test_any(): assert msgspec.json.schema(Any) == {} def test_raw(): assert msgspec.json.schema(msgspec.Raw) == {} def test_msgpack_ext(): with pytest.raises(TypeError): assert msgspec.json.schema(msgspec.msgpack.Ext) def test_custom(): with pytest.raises(TypeError, match="Generating JSON schema for custom types"): assert msgspec.json.schema(complex) schema = {"type": "string", "format": "complex"} assert ( msgspec.json.schema(Annotated[complex, Meta(extra_json_schema=schema)]) == schema ) def test_custom_schema_hook(): schema = {"type": "string", "format": "complex"} def schema_hook(cls): if cls is complex: return schema raise NotImplementedError assert msgspec.json.schema(complex, schema_hook=schema_hook) == schema assert msgspec.json.schema( Annotated[complex, Meta(extra_json_schema={"title": "A complex field"})], schema_hook=schema_hook, ) == {**schema, "title": "A complex field"} with pytest.raises(TypeError, match="Generating JSON schema for custom types"): msgspec.json.schema(slice, schema_hook=schema_hook) def test_none(): assert msgspec.json.schema(None) == {"type": "null"} def test_bool(): assert msgspec.json.schema(bool) == {"type": "boolean"} def test_int(): assert msgspec.json.schema(int) == {"type": "integer"} def test_float(): assert msgspec.json.schema(float) == {"type": "number"} def test_string(): assert msgspec.json.schema(str) == {"type": "string"} @pytest.mark.parametrize("typ", [bytes, bytearray, memoryview]) def test_binary(typ): assert msgspec.json.schema(typ) == { "type": "string", "contentEncoding": "base64", } @pytest.mark.parametrize( "annot, extra", [ (None, {}), (Meta(tz=None), {}), (Meta(tz=True), {"format": "date-time"}), (Meta(tz=False), {}), ], ) def test_datetime(annot, extra): typ = datetime.datetime if annot is not None: typ = Annotated[typ, annot] assert msgspec.json.schema(typ) == {"type": "string", **extra} @pytest.mark.parametrize( "annot, extra", [ (None, {}), (Meta(tz=None), {}), (Meta(tz=True), {"format": "time"}), (Meta(tz=False), {"format": "partial-time"}), ], ) def test_time(annot, extra): typ = datetime.time if annot is not None: typ = Annotated[typ, annot] assert msgspec.json.schema(typ) == {"type": "string", **extra} def test_date(): assert msgspec.json.schema(datetime.date) == { "type": "string", "format": "date", } def test_timedelta(): assert msgspec.json.schema(datetime.timedelta) == { "type": "string", "format": "duration", } def test_uuid(): assert msgspec.json.schema(uuid.UUID) == { "type": "string", "format": "uuid", } def test_decimal(): assert msgspec.json.schema(decimal.Decimal) == { "type": "string", "format": "decimal", } def test_newtype(): UserId = NewType("UserId", str) assert msgspec.json.schema(UserId) == {"type": "string"} assert msgspec.json.schema(Annotated[UserId, Meta(max_length=10)]) == { "type": "string", "maxLength": 10, } @pytest.mark.parametrize("typ", [list, tuple, List, Tuple]) def test_sequence_any(typ): assert msgspec.json.schema(typ) == {"type": "array"} @pytest.mark.parametrize("cls", [list, tuple, List, Tuple]) def test_sequence_typed(cls): args = (int, ...) if cls in (tuple, Tuple) else int typ = cls[args] assert msgspec.json.schema(typ) == {"type": "array", "items": {"type": "integer"}} @pytest.mark.parametrize("typ", [set, frozenset, Set, FrozenSet]) def test_set_any(typ): assert msgspec.json.schema(typ) == {"type": "array", "uniqueItems": True} @pytest.mark.parametrize("cls", [set, frozenset, Set, FrozenSet]) def test_set_typed(cls): typ = cls[int] assert msgspec.json.schema(typ) == { "type": "array", "uniqueItems": True, "items": {"type": "integer"}, } @pytest.mark.parametrize("cls", [tuple, Tuple]) def test_tuple(cls): typ = cls[int, float, str] assert msgspec.json.schema(typ) == { "type": "array", "minItems": 3, "maxItems": 3, "items": False, "prefixItems": [ {"type": "integer"}, {"type": "number"}, {"type": "string"}, ], } @pytest.mark.parametrize("cls", [tuple, Tuple]) def test_empty_tuple(cls): typ = cls[()] assert msgspec.json.schema(typ) == { "type": "array", "minItems": 0, "maxItems": 0, } @pytest.mark.parametrize("typ", [dict, Dict]) def test_dict_any(typ): assert msgspec.json.schema(typ) == {"type": "object"} @pytest.mark.parametrize("cls", [dict, Dict]) def test_dict_typed(cls): typ = cls[str, int] assert msgspec.json.schema(typ) == { "type": "object", "additionalProperties": {"type": "integer"}, } @py315_or_later_only def test_frozendict_any(): assert msgspec.json.schema(frozendict) == {"type": "object"} @py315_or_later_only def test_frozendict_typed(): typ = frozendict[str, bool] assert msgspec.json.schema(typ) == { "type": "object", "additionalProperties": {"type": "boolean"}, } def test_abstract_sequence(): # Only testing one here, the main tests are in `test_inspect` typ = typing.Sequence[int] assert msgspec.json.schema(typ) == {"type": "array", "items": {"type": "integer"}} def test_abstract_mapping(): # Only testing one here, the main tests are in `test_inspect` typ = typing.MutableMapping[str, int] assert msgspec.json.schema(typ) == { "type": "object", "additionalProperties": {"type": "integer"}, } def test_int_enum(): class Example(enum.IntEnum): C = 1 B = 3 A = 2 assert msgspec.json.schema(Example) == { "$ref": "#/$defs/Example", "$defs": {"Example": {"title": "Example", "enum": [1, 2, 3]}}, } def test_enum(): class Example(enum.Enum): """A docstring""" C = "x" B = "z" A = "y" assert msgspec.json.schema(Example) == { "$ref": "#/$defs/Example", "$defs": { "Example": { "title": "Example", "description": "A docstring", "enum": ["x", "y", "z"], } }, } def test_int_literal(): assert msgspec.json.schema(Literal[3, 1, 2]) == {"enum": [1, 2, 3]} def test_str_literal(): assert msgspec.json.schema(Literal["c", "a", "b"]) == {"enum": ["a", "b", "c"]} def test_mixed_literal(): # A Literal may mix value types; building its schema must not crash trying # to sort values of incomparable types (gh#1018). assert msgspec.json.schema(Literal[1, None]) == {"enum": [None, 1]} assert msgspec.json.schema(Literal[True, "yes"]) == {"enum": [True, "yes"]} def test_struct_object(): class Point(msgspec.Struct, forbid_unknown_fields=True): x: int y: int class Polygon(msgspec.Struct): """An example docstring""" vertices: list[Point] name: str | None = None metadata: dict[str, str] = {} assert msgspec.json.schema(Polygon) == { "$ref": "#/$defs/Polygon", "$defs": { "Polygon": { "title": "Polygon", "description": "An example docstring", "type": "object", "properties": { "vertices": { "type": "array", "items": {"$ref": "#/$defs/Point"}, }, "name": { "anyOf": [{"type": "string"}, {"type": "null"}], "default": None, }, "metadata": { "type": "object", "additionalProperties": {"type": "string"}, "default": {}, }, }, "required": ["vertices"], }, "Point": { "title": "Point", "type": "object", "properties": { "x": {"type": "integer"}, "y": {"type": "integer"}, }, "required": ["x", "y"], "additionalProperties": False, }, }, } @pytest.mark.parametrize( "factory, default", [ (list, []), (dict, {}), (set, []), (bytearray, ""), ], ) def test_struct_default_factory_default(factory, default): class Example(msgspec.Struct): x: factory = msgspec.field(default_factory=factory) schema = msgspec.json.schema(Example)["$defs"]["Example"] assert schema["properties"]["x"]["default"] == default json.dumps(schema) @pytest.mark.parametrize("forbid_unknown_fields", [False, True]) def test_struct_array_like(forbid_unknown_fields): class Example( msgspec.Struct, array_like=True, forbid_unknown_fields=forbid_unknown_fields ): """An example docstring""" a: int b: str c: list[int] = [] d: dict[str, int] = {} sol = { "$ref": "#/$defs/Example", "$defs": { "Example": { "title": "Example", "description": "An example docstring", "type": "array", "prefixItems": [ {"type": "integer"}, {"type": "string"}, {"type": "array", "items": {"type": "integer"}, "default": []}, { "type": "object", "additionalProperties": {"type": "integer"}, "default": {}, }, ], "minItems": 2, } }, } if forbid_unknown_fields: sol["$defs"]["Example"]["maxItems"] = 4 assert msgspec.json.schema(Example) == sol @pytest.mark.parametrize( "tag, min_items, payload", [(False, 0, b"[]"), (True, 1, b'["Example"]')], ) def test_struct_array_like_all_fields_optional(tag, min_items, payload): class Example(msgspec.Struct, array_like=True, tag=tag): a: int = 1 b: list[int] = msgspec.field(default_factory=list) schema = msgspec.json.schema(Example)["$defs"]["Example"] assert msgspec.json.decode(payload, type=Example) == Example() assert schema["minItems"] == min_items def test_struct_no_fields(): class Example(msgspec.Struct): pass assert msgspec.json.schema(Example) == { "$ref": "#/$defs/Example", "$defs": { "Example": { "title": "Example", "type": "object", "properties": {}, "required": [], } }, } def test_struct_object_tagged(): class Point(msgspec.Struct, tag=True): x: int y: int assert msgspec.json.schema(Point) == { "$ref": "#/$defs/Point", "$defs": { "Point": { "title": "Point", "type": "object", "properties": { "type": {"enum": ["Point"]}, "x": {"type": "integer"}, "y": {"type": "integer"}, }, "required": ["type", "x", "y"], } }, } def test_struct_array_tagged(): class Point(msgspec.Struct, tag=True, array_like=True): x: int y: int assert msgspec.json.schema(Point) == { "$ref": "#/$defs/Point", "$defs": { "Point": { "title": "Point", "type": "array", "prefixItems": [ {"enum": ["Point"]}, {"type": "integer"}, {"type": "integer"}, ], "minItems": 3, } }, } def test_struct_keyword_only(): class Base(msgspec.Struct, kw_only=True): x: int = 1 y: int z: int = 2 class Test(Base): a: int b: int = 0 assert msgspec.json.schema(Test) == { "$ref": "#/$defs/Test", "$defs": { "Test": { "title": "Test", "type": "object", "properties": { "a": {"type": "integer"}, "b": {"type": "integer", "default": 0}, "x": {"type": "integer", "default": 1}, "y": {"type": "integer"}, "z": {"type": "integer", "default": 2}, }, "required": ["a", "y"], } }, } def test_struct_array_keyword_only(): class Base(msgspec.Struct, kw_only=True, array_like=True): x: int = 1 y: int z: int = 2 class Test(Base): a: int b: int = 0 assert msgspec.json.schema(Test) == { "$ref": "#/$defs/Test", "$defs": { "Test": { "title": "Test", "type": "array", "prefixItems": [ {"type": "integer"}, {"type": "integer", "default": 0}, {"type": "integer", "default": 1}, {"type": "integer"}, {"type": "integer", "default": 2}, ], "minItems": 4, } }, } def test_typing_namedtuple(): class Example(NamedTuple): """An example docstring""" a: str b: bool c: int = 0 assert msgspec.json.schema(Example) == { "$ref": "#/$defs/Example", "$defs": { "Example": { "title": "Example", "description": "An example docstring", "type": "array", "prefixItems": [ {"type": "string"}, {"type": "boolean"}, {"type": "integer", "default": 0}, ], "minItems": 2, "maxItems": 3, } }, } def test_collections_namedtuple(): Example = namedtuple("Example", ["a", "b", "c"], defaults=(0,)) assert msgspec.json.schema(Example) == { "$ref": "#/$defs/Example", "$defs": { "Example": { "title": "Example", "type": "array", "prefixItems": [{}, {}, {"default": 0}], "minItems": 2, "maxItems": 3, } }, } def test_generic_namedtuple(): NamedTuple = pytest.importorskip("typing_extensions").NamedTuple class Ex(NamedTuple, Generic[T]): """An example docstring""" x: T y: list[T] assert msgspec.json.schema(Ex) == { "$ref": "#/$defs/Ex", "$defs": { "Ex": { "title": "Ex", "description": "An example docstring", "type": "array", "prefixItems": [{}, {"type": "array"}], "minItems": 2, "maxItems": 2, }, }, } assert msgspec.json.schema(Ex[int]) == { "$ref": "#/$defs/Ex_int_", "$defs": { "Ex_int_": { "title": "Ex[int]", "description": "An example docstring", "type": "array", "prefixItems": [ {"type": "integer"}, {"type": "array", "items": {"type": "integer"}}, ], "minItems": 2, "maxItems": 2, }, }, } @pytest.mark.parametrize("use_typing_extensions", [False, True]) def test_typeddict(use_typing_extensions): if use_typing_extensions: tex = pytest.importorskip("typing_extensions") cls = tex.TypedDict else: cls = TypedDict class Example(cls): """An example docstring""" a: str b: bool c: int assert msgspec.json.schema(Example) == { "$ref": "#/$defs/Example", "$defs": { "Example": { "title": "Example", "description": "An example docstring", "type": "object", "properties": { "a": {"type": "string"}, "b": {"type": "boolean"}, "c": {"type": "integer"}, }, "required": ["a", "b", "c"], } }, } @pytest.mark.parametrize("use_typing_extensions", [False, True]) def test_typeddict_optional(use_typing_extensions): if use_typing_extensions: tex = pytest.importorskip("typing_extensions") cls = tex.TypedDict else: cls = TypedDict class Base(cls): a: str b: bool class Example(Base, total=False): """An example docstring""" c: int assert msgspec.json.schema(Example) == { "$ref": "#/$defs/Example", "$defs": { "Example": { "title": "Example", "description": "An example docstring", "type": "object", "properties": { "a": {"type": "string"}, "b": {"type": "boolean"}, "c": {"type": "integer"}, }, "required": ["a", "b"], } }, } def test_generic_typeddict(): TypedDict = pytest.importorskip("typing_extensions").TypedDict class Ex(TypedDict, Generic[T]): """An example docstring""" x: T y: list[T] assert msgspec.json.schema(Ex) == { "$ref": "#/$defs/Ex", "$defs": { "Ex": { "title": "Ex", "description": "An example docstring", "type": "object", "properties": { "x": {}, "y": {"type": "array"}, }, "required": ["x", "y"], }, }, } assert msgspec.json.schema(Ex[int]) == { "$ref": "#/$defs/Ex_int_", "$defs": { "Ex_int_": { "title": "Ex[int]", "description": "An example docstring", "type": "object", "properties": { "x": {"type": "integer"}, "y": {"type": "array", "items": {"type": "integer"}}, }, "required": ["x", "y"], }, }, } @pytest.mark.parametrize("module", ["dataclasses", "attrs"]) def test_dataclass_or_attrs(module): m = pytest.importorskip(module) if module == "attrs": decorator = m.define factory_default = m.field(factory=dict) else: decorator = m.dataclass factory_default = m.field(default_factory=dict) @decorator class Point: x: int y: int @decorator class Polygon: """An example docstring""" vertices: list[Point] name: str | None = None metadata: dict[str, str] = factory_default assert msgspec.json.schema(Polygon) == { "$ref": "#/$defs/Polygon", "$defs": { "Polygon": { "title": "Polygon", "description": "An example docstring", "type": "object", "properties": { "vertices": { "type": "array", "items": {"$ref": "#/$defs/Point"}, }, "name": { "anyOf": [{"type": "string"}, {"type": "null"}], "default": None, }, "metadata": { "type": "object", "additionalProperties": {"type": "string"}, }, }, "required": ["vertices"], }, "Point": { "title": "Point", "type": "object", "properties": { "x": {"type": "integer"}, "y": {"type": "integer"}, }, "required": ["x", "y"], }, }, } @pytest.mark.parametrize("module", ["dataclasses", "attrs"]) def test_generic_dataclass_or_attrs(module): m = pytest.importorskip(module) decorator = m.define if module == "attrs" else m.dataclass @decorator class Ex(Generic[T]): """An example docstring""" x: T y: list[T] assert msgspec.json.schema(Ex) == { "$ref": "#/$defs/Ex", "$defs": { "Ex": { "title": "Ex", "description": "An example docstring", "type": "object", "properties": { "x": {}, "y": {"type": "array"}, }, "required": ["x", "y"], }, }, } assert msgspec.json.schema(Ex[int]) == { "$ref": "#/$defs/Ex_int_", "$defs": { "Ex_int_": { "title": "Ex[int]", "description": "An example docstring", "type": "object", "properties": { "x": {"type": "integer"}, "y": {"type": "array", "items": {"type": "integer"}}, }, "required": ["x", "y"], }, }, } def test_optional_struct_null_last(): class Example(msgspec.Struct): x: int assert msgspec.json.schema(Optional[Example]) == { "anyOf": [{"$ref": "#/$defs/Example"}, {"type": "null"}], "$defs": { "Example": { "title": "Example", "type": "object", "properties": {"x": {"type": "integer"}}, "required": ["x"], } }, } def test_optional_union_null_last(): assert msgspec.json.schema(Union[int, None, str]) == { "anyOf": [{"type": "integer"}, {"type": "string"}, {"type": "null"}], } @pytest.mark.parametrize("use_union_operator", [False, True]) def test_union(use_union_operator): class Example(msgspec.Struct): x: int y: int if use_union_operator: typ = int | str | Example else: typ = Union[int, str, Example] assert msgspec.json.schema(typ) == { "anyOf": [ {"type": "integer"}, {"type": "string"}, {"$ref": "#/$defs/Example"}, ], "$defs": { "Example": { "title": "Example", "type": "object", "properties": {"x": {"type": "integer"}, "y": {"type": "integer"}}, "required": ["x", "y"], } }, } def test_struct_tagged_union(): class Point(msgspec.Struct, tag=True): x: int y: int class Point3D(Point): z: int assert msgspec.json.schema(Point | Point3D) == { "anyOf": [{"$ref": "#/$defs/Point"}, {"$ref": "#/$defs/Point3D"}], "discriminator": { "mapping": {"Point": "#/$defs/Point", "Point3D": "#/$defs/Point3D"}, "propertyName": "type", }, "$defs": { "Point": { "properties": { "type": {"enum": ["Point"]}, "x": {"type": "integer"}, "y": {"type": "integer"}, }, "required": ["type", "x", "y"], "title": "Point", "type": "object", }, "Point3D": { "properties": { "type": {"enum": ["Point3D"]}, "x": {"type": "integer"}, "y": {"type": "integer"}, "z": {"type": "integer"}, }, "required": ["type", "x", "y", "z"], "title": "Point3D", "type": "object", }, }, } assert msgspec.json.schema(Point | Point3D) == msgspec.json.schema( Union[Point, Point3D] ) def test_struct_tagged_union_with_none(): class Point(msgspec.Struct, tag=True): x: int y: int class Point3D(Point): z: int schema = msgspec.json.schema(Union[Point, Point3D, None]) assert schema["anyOf"] == [ { "anyOf": [{"$ref": "#/$defs/Point"}, {"$ref": "#/$defs/Point3D"}], "discriminator": { "mapping": {"Point": "#/$defs/Point", "Point3D": "#/$defs/Point3D"}, "propertyName": "type", }, }, {"type": "null"}, ] assert "discriminator" not in schema def test_struct_tagged_union_mixed_types(): class Point(msgspec.Struct, tag=True): x: int y: int class Point3D(Point): z: int assert msgspec.json.schema(Point | Point3D | int | float) == { "anyOf": [ {"type": "integer"}, {"type": "number"}, { "anyOf": [{"$ref": "#/$defs/Point"}, {"$ref": "#/$defs/Point3D"}], "discriminator": { "mapping": {"Point": "#/$defs/Point", "Point3D": "#/$defs/Point3D"}, "propertyName": "type", }, }, ], "$defs": { "Point": { "properties": { "type": {"enum": ["Point"]}, "x": {"type": "integer"}, "y": {"type": "integer"}, }, "required": ["type", "x", "y"], "title": "Point", "type": "object", }, "Point3D": { "properties": { "type": {"enum": ["Point3D"]}, "x": {"type": "integer"}, "y": {"type": "integer"}, "z": {"type": "integer"}, }, "required": ["type", "x", "y", "z"], "title": "Point3D", "type": "object", }, }, } def test_struct_tagged_union_with_none_and_other(): class Point(msgspec.Struct, tag=True): x: int y: int class Point3D(Point): z: int schema = msgspec.json.schema(Union[Point, Point3D, int, None]) assert schema["anyOf"] == [ {"type": "integer"}, { "anyOf": [{"$ref": "#/$defs/Point"}, {"$ref": "#/$defs/Point3D"}], "discriminator": { "mapping": {"Point": "#/$defs/Point", "Point3D": "#/$defs/Point3D"}, "propertyName": "type", }, }, {"type": "null"}, ] assert "discriminator" not in schema def test_optional_union_null_member_metadata_preserved(): NullWithMeta = Annotated[None, msgspec.Meta(description="explicitly unset")] assert msgspec.json.schema(Union[int, NullWithMeta]) == { "anyOf": [ {"type": "integer"}, {"type": "null", "description": "explicitly unset"}, ], } def test_struct_array_union(): class Point(msgspec.Struct, array_like=True, tag=True): x: int y: int class Point3D(Point): z: int assert msgspec.json.schema(Point | Point3D) == { "anyOf": [{"$ref": "#/$defs/Point"}, {"$ref": "#/$defs/Point3D"}], "$defs": { "Point": { "minItems": 3, "prefixItems": [ {"enum": ["Point"]}, {"type": "integer"}, {"type": "integer"}, ], "title": "Point", "type": "array", }, "Point3D": { "minItems": 4, "prefixItems": [ {"enum": ["Point3D"]}, {"type": "integer"}, {"type": "integer"}, {"type": "integer"}, ], "title": "Point3D", "type": "array", }, }, } def test_struct_unset_fields(): class Ex(msgspec.Struct): x: int | msgspec.UnsetType = msgspec.UNSET assert msgspec.json.schema(Ex) == { "$ref": "#/$defs/Ex", "$defs": { "Ex": { "properties": {"x": {"type": "integer"}}, "required": [], "title": "Ex", "type": "object", } }, } def test_generic_struct(): class Ex(msgspec.Struct, Generic[T]): """An example docstring""" x: T y: list[T] assert msgspec.json.schema(Ex) == { "$ref": "#/$defs/Ex", "$defs": { "Ex": { "title": "Ex", "description": "An example docstring", "type": "object", "properties": { "x": {}, "y": {"type": "array"}, }, "required": ["x", "y"], }, }, } assert msgspec.json.schema(Ex[int]) == { "$ref": "#/$defs/Ex_int_", "$defs": { "Ex_int_": { "title": "Ex[int]", "description": "An example docstring", "type": "object", "properties": { "x": {"type": "integer"}, "y": {"type": "array", "items": {"type": "integer"}}, }, "required": ["x", "y"], }, }, } def test_generic_struct_tagged_union(): class Point(msgspec.Struct, Generic[T], tag=True): x: T y: T class Point3D(Point[T]): z: T sol = { "anyOf": [{"$ref": "#/$defs/Point_int_"}, {"$ref": "#/$defs/Point3D_int_"}], "discriminator": { "mapping": { "Point": "#/$defs/Point_int_", "Point3D": "#/$defs/Point3D_int_", }, "propertyName": "type", }, "$defs": { "Point_int_": { "properties": { "type": {"enum": ["Point"]}, "x": {"type": "integer"}, "y": {"type": "integer"}, }, "required": ["type", "x", "y"], "title": "Point[int]", "type": "object", }, "Point3D_int_": { "properties": { "type": {"enum": ["Point3D"]}, "x": {"type": "integer"}, "y": {"type": "integer"}, "z": {"type": "integer"}, }, "required": ["type", "x", "y", "z"], "title": "Point3D[int]", "type": "object", }, }, } res = msgspec.json.schema(Point[int] | Point3D[int]) assert res == sol @pytest.mark.parametrize( "field, constraint", [ ("ge", "minimum"), ("gt", "exclusiveMinimum"), ("le", "maximum"), ("lt", "exclusiveMaximum"), ("multiple_of", "multipleOf"), ], ) def test_numeric_metadata(field, constraint): typ = Annotated[int, Meta(**{field: 2})] assert msgspec.json.schema(typ) == {"type": "integer", constraint: 2} @pytest.mark.parametrize( "field, val, constraint", [ ("pattern", "[a-z]*", "pattern"), ("min_length", 0, "minLength"), ("max_length", 3, "maxLength"), ], ) def test_string_metadata(field, val, constraint): typ = Annotated[str, Meta(**{field: val})] assert msgspec.json.schema(typ) == {"type": "string", constraint: val} @pytest.mark.parametrize( "field, val, constraint", [ ("pattern", "[a-z]*", "pattern"), ("min_length", 0, "minLength"), ("max_length", 3, "maxLength"), ], ) def test_dict_key_metadata(field, val, constraint): typ = Annotated[str, Meta(**{field: val})] assert msgspec.json.schema(dict[typ, int]) == { "type": "object", "additionalProperties": {"type": "integer"}, "propertyNames": {constraint: val}, } @pytest.mark.parametrize( "meta, property_names", [ (Meta(title="key"), {"title": "key"}), ( Meta(title="key", pattern="^A$"), {"title": "key", "pattern": "^A$"}, ), ], ) def test_dict_key_metadata_with_schema_metadata(meta, property_names): typ = Annotated[str, meta] assert msgspec.json.schema(dict[typ, int]) == { "type": "object", "additionalProperties": {"type": "integer"}, "propertyNames": property_names, } @pytest.mark.parametrize("typ", [bytes, bytearray, memoryview]) @pytest.mark.parametrize( "field, n, constraint", [("min_length", 2, "minLength"), ("max_length", 7, "maxLength")], ) def test_binary_metadata(typ, field, n, constraint): n2 = len(b64encode(b"x" * n)) typ = Annotated[typ, Meta(**{field: n})] assert msgspec.json.schema(typ) == { "type": "string", constraint: n2, "contentEncoding": "base64", } @pytest.mark.parametrize("typ", [list, tuple]) @pytest.mark.parametrize( "field, constraint", [("min_length", "minItems"), ("max_length", "maxItems")], ) def test_array_metadata(typ, field, constraint): typ = Annotated[typ, Meta(**{field: 2})] assert msgspec.json.schema(typ) == {"type": "array", constraint: 2} @pytest.mark.parametrize("typ", [set, frozenset]) @pytest.mark.parametrize( "field, constraint", [("min_length", "minItems"), ("max_length", "maxItems")], ) def test_set_metadata(typ, field, constraint): typ = Annotated[typ[int], Meta(**{field: 2})] assert msgspec.json.schema(typ) == { "type": "array", "uniqueItems": True, "items": {"type": "integer"}, constraint: 2, } @pytest.mark.parametrize( "field, constraint", [("min_length", "minProperties"), ("max_length", "maxProperties")], ) def test_object_metadata(field, constraint): typ = Annotated[dict, Meta(**{field: 2})] assert msgspec.json.schema(typ) == {"type": "object", constraint: 2} def test_generic_metadata(): typ = Annotated[ int, Meta( title="the title", description="the description", examples=[1, 2, 3], extra_json_schema={"title": "an override", "default": 1}, ), ] assert msgspec.json.schema(typ) == { "type": "integer", "title": "an override", "description": "the description", "examples": [1, 2, 3], "default": 1, } def test_component_names_collide(): s1 = """ import msgspec Ex = msgspec.defstruct("Ex", [("x", int), ("y", int)]) """ s2 = """ import msgspec Ex = msgspec.defstruct("Ex", [("a", str), ("b", str)]) """ with temp_module(s1) as m1, temp_module(s2) as m2: (r1, r2), components = msgspec.json.schema_components([m1.Ex, m2.Ex]) assert r1 == {"$ref": f"#/$defs/{m1.__name__}.Ex"} assert r2 == {"$ref": f"#/$defs/{m2.__name__}.Ex"} assert components == { f"{m1.__name__}.Ex": { "properties": {"x": {"type": "integer"}, "y": {"type": "integer"}}, "required": ["x", "y"], "title": "Ex", "type": "object", }, f"{m2.__name__}.Ex": { "properties": {"a": {"type": "string"}, "b": {"type": "string"}}, "required": ["a", "b"], "title": "Ex", "type": "object", }, } def test_schema_components_collects_subtypes(): class ExEnum(enum.Enum): A = 1 class ExStruct(msgspec.Struct): b: set[frozenset[ExEnum]] | int class ExDict(TypedDict): c: tuple[ExStruct, ...] class ExTuple(NamedTuple): d: list[ExDict] @dataclass class ExDataclass: e: list[ExTuple] (s,), components = msgspec.json.schema_components([dict[str, ExDataclass]]) r1 = {"$ref": "#/$defs/ExEnum"} r2 = {"$ref": "#/$defs/ExStruct"} r3 = {"$ref": "#/$defs/ExDict"} r4 = {"$ref": "#/$defs/ExTuple"} r5 = {"$ref": "#/$defs/ExDataclass"} assert s == {"type": "object", "additionalProperties": r5} assert components == { "ExEnum": {"enum": [1], "title": "ExEnum"}, "ExStruct": { "type": "object", "title": "ExStruct", "properties": { "b": { "anyOf": [ { "items": { "items": r1, "type": "array", "uniqueItems": True, }, "type": "array", "uniqueItems": True, }, {"type": "integer"}, ] } }, "required": ["b"], }, "ExDict": { "title": "ExDict", "type": "object", "properties": {"c": {"items": r2, "type": "array"}}, "required": ["c"], }, "ExTuple": { "title": "ExTuple", "type": "array", "prefixItems": [{"items": r3, "type": "array"}], "maxItems": 1, "minItems": 1, }, "ExDataclass": { "title": "ExDataclass", "type": "object", "properties": {"e": {"items": r4, "type": "array"}}, "required": ["e"], }, } def test_ref_template(): class Ex1(msgspec.Struct): a: int class Ex2(msgspec.Struct): b: Ex1 (s1, s2), components = msgspec.json.schema_components( [Ex1, Ex2], ref_template="#/definitions/{name}" ) assert s1 == {"$ref": "#/definitions/Ex1"} assert s2 == {"$ref": "#/definitions/Ex2"} assert components == { "Ex1": { "title": "Ex1", "type": "object", "properties": {"a": {"type": "integer"}}, "required": ["a"], }, "Ex2": { "title": "Ex2", "type": "object", "properties": {"b": s1}, "required": ["b"], }, } def test_multiline_docstring(): class Example(msgspec.Struct): """ indented first line last line. """ pass assert msgspec.json.schema(Example) == { "$ref": "#/$defs/Example", "$defs": { "Example": { "description": " indented first line\n\nlast line.", "title": "Example", "type": "object", "properties": {}, "required": [], } }, } python-msgspec-0.22.0/tests/unit/test_struct.py000066400000000000000000002406541525673062400216560ustar00rootroot00000000000000import copy import datetime import enum import gc import operator import pickle import sys import textwrap import weakref from contextlib import contextmanager from inspect import Parameter, Signature from typing import Any, Generic, TypeVar import pytest import msgspec from msgspec import NODEFAULT, UNSET, Struct, defstruct, field from msgspec.structs import StructConfig from .utils import temp_module if hasattr(copy, "replace"): # Added in Python 3.13 copy_replace = copy.replace else: def copy_replace(s, **changes): return s.__replace__(**changes) @contextmanager def nogc(): """Temporarily disable GC""" try: gc.disable() yield finally: gc.enable() class Fruit(enum.IntEnum): APPLE = 1 BANANA = 2 def as_tuple(x): return tuple(getattr(x, f) for f in x.__struct_fields__) @pytest.mark.parametrize("obj, str_obj", [(UNSET, "UNSET"), (NODEFAULT, "NODEFAULT")]) @pytest.mark.parametrize("protocol", range(pickle.HIGHEST_PROTOCOL + 1)) def test_singletons(obj, str_obj, protocol): assert str(obj) == str_obj assert pickle.loads(pickle.dumps(obj, protocol=protocol)) is obj cls = type(obj) assert cls() is obj with pytest.raises(TypeError): cls(1) with pytest.raises(TypeError): cls(foo=1) if obj is UNSET: assert bool(obj) is False else: assert bool(obj) is True def test_field(): f1 = msgspec.field() assert f1.default is NODEFAULT assert f1.default_factory is NODEFAULT assert f1.name is None f2 = msgspec.field(default=1) assert f2.default == 1 assert f2.default_factory is NODEFAULT assert f2.name is None f3 = msgspec.field(default_factory=int) assert f3.default is NODEFAULT assert f3.default_factory is int assert f3.name is None f4 = msgspec.field(name="foo") assert f4.name == "foo" f5 = msgspec.field(name=None) assert f5.name is None with pytest.raises(TypeError, match="Cannot set both"): msgspec.field(default=1, default_factory=int) with pytest.raises(TypeError, match="must be callable"): msgspec.field(default_factory=1) with pytest.raises(TypeError, match="must be a str or None"): msgspec.field(name=b"bad") def test_struct_class_attributes(): assert Struct.__struct_fields__ == () assert Struct.__struct_encode_fields__ == () assert Struct.__struct_defaults__ == () assert Struct.__match_args__ == () assert Struct.__slots__ == () assert Struct.__module__ == "msgspec" assert isinstance(Struct.__struct_config__, StructConfig) def test_struct_class_and_instance_dir(): expected = {"__struct_fields__", "__struct_config__"} assert expected.issubset(dir(Struct)) assert expected.issubset(dir(Struct())) def test_struct_instance_attributes(): class Test(Struct): c: int b: float a: str = "hello" x = Test(1, 2.0, a="goodbye") assert x.__struct_fields__ == ("c", "b", "a") assert x.__struct_encode_fields__ == ("c", "b", "a") assert x.__struct_fields__ is x.__struct_encode_fields__ assert x.__struct_defaults__ == ("hello",) assert x.__slots__ == ("a", "b", "c") assert isinstance(x.__struct_config__, StructConfig) assert x.c == 1 assert x.b == 2.0 assert x.a == "goodbye" def test_struct_subclass_forbids_init_new_slots(): with pytest.raises(TypeError, match="__init__"): class Test1(Struct): a: int def __init__(self, a): pass with pytest.raises(TypeError, match="__new__"): class Test2(Struct): a: int def __new__(self, a): pass with pytest.raises(TypeError, match="__slots__"): class Test3(Struct): __slots__ = ("a",) a: int def test_struct_subclass_forbidden_field_names(): with pytest.raises( TypeError, match="Cannot have a struct field named '__weakref__'" ): class Test1(Struct): __weakref__: int with pytest.raises(TypeError, match="Cannot have a struct field named '__dict__'"): class Test2(Struct): __dict__: int with pytest.raises( TypeError, match="Cannot have a struct field named '__msgspec_cached_hash__'" ): class Test3(Struct): __msgspec_cached_hash__: int class TestMixins: def test_mixin_no_slots(self): class Mixin: def method(self): pass class Test1(Struct, Mixin): pass assert issubclass(Test1, Mixin) assert Test1.__dictoffset__ != 0 assert Test1.__weakrefoffset__ != 0 class Test2(Struct, Mixin, dict=True, weakref=True): pass assert Test2.__dictoffset__ != 0 assert Test2.__weakrefoffset__ != 0 def test_mixin_slots(self): class Mixin: __slots__ = () def method(self): pass class Test1(Struct, Mixin): pass assert issubclass(Test1, Mixin) assert Test1.__dictoffset__ == 0 assert Test1.__weakrefoffset__ == 0 class Test2(Struct, Mixin, dict=True, weakref=True): pass assert Test2.__dictoffset__ != 0 assert Test2.__weakrefoffset__ != 0 def test_mixin_nonempty_slots(self): class Mixin: __slots__ = "_state" def method(self): try: return self._state except AttributeError: self._state = self.x + 1 return self._state class Test(Struct, Mixin): x: int assert Test.__dictoffset__ == 0 t = Test(1) assert t.method() == 2 assert t.method() == 2 def test_mixin_forbids_init(self): class Mixin: def __init__(self): pass with pytest.raises(TypeError, match="cannot define __init__"): class Test(Struct, Mixin): pass def test_mixin_forbids_new(self): class Mixin: def __new__(self): pass with pytest.raises(TypeError, match="cannot define __new__"): class Test(Struct, Mixin): pass def test_mixin_builtin_type_errors(self): with pytest.raises(TypeError): class Test(Struct, Exception): pass def test_struct_subclass_forbids_non_types(): # Currently this failcase is handled by CPython's internals, but it's good # to make sure this user error actually errors. class Foo: pass with pytest.raises(TypeError): class Test(msgspec.Struct, Foo()): pass def test_struct_subclass_forbids_mixed_layouts(): class A(Struct): a: int b: int class B(Struct): c: int d: int # This error is raised by cpython with pytest.raises(TypeError, match="lay-out conflict"): class C(A, B): pass def test_struct_errors_nicely_if_used_in_init_subclass(): ran = False class Test(Struct): def __init_subclass__(cls): # Class attributes aren't yet defined, error nicely for attr in [ "__struct_fields__", "__struct_encode_fields__", "__match_args__", "__struct_defaults__", ]: with pytest.raises(AttributeError): getattr(cls, attr) # Init doesn't work with pytest.raises(Exception): cls() # Decoder/decode doesn't work for proto in [msgspec.json, msgspec.msgpack]: with pytest.raises(ValueError, match="isn't fully defined"): proto.Decoder(cls) with pytest.raises(ValueError, match="isn't fully defined"): proto.decode(b"", type=cls) nonlocal ran ran = True class Subclass(Test): x: int assert ran class TestStructParameterOrdering: """Tests for parsing parameter types & defaults from one or more class definitions.""" def test_no_args(self): class Test(Struct): pass assert Test.__struct_fields__ == () assert Test.__struct_defaults__ == () assert Test.__match_args__ == () assert Test.__slots__ == () def test_all_positional(self): class Test(Struct): y: float x: int assert Test.__struct_fields__ == ("y", "x") assert Test.__struct_defaults__ == () assert Test.__match_args__ == ("y", "x") assert Test.__slots__ == ("x", "y") def test_all_positional_with_defaults(self): class Test(Struct): y: int = 1 x: float = 2.0 assert Test.__struct_fields__ == ("y", "x") assert Test.__struct_defaults__ == (1, 2.0) assert Test.__match_args__ == ("y", "x") assert Test.__slots__ == ("x", "y") def test_subclass_no_change(self): class Test(Struct): y: float x: int class Test2(Test): pass assert Test2.__struct_fields__ == ("y", "x") assert Test2.__struct_defaults__ == () assert Test2.__match_args__ == ("y", "x") assert Test2.__slots__ == () def test_subclass_extends(self): class Test(Struct): c: int b: float d: int = 1 a: float = 2.0 class Test2(Test): e: str = "3.0" f: float = 4.0 assert Test2.__struct_fields__ == ("c", "b", "d", "a", "e", "f") assert Test2.__struct_defaults__ == (1, 2.0, "3.0", 4.0) assert Test2.__match_args__ == ("c", "b", "d", "a", "e", "f") assert Test2.__slots__ == ("e", "f") def test_subclass_overrides(self): class Test(Struct): c: int b: int d: int = 1 a: float = 2.0 class Test2(Test): b: float = 3 # switch to keyword, change type d: int = 4 # change default e: float = 5.0 # new assert Test2.__struct_fields__ == ("c", "b", "d", "a", "e") assert Test2.__struct_defaults__ == (3, 4, 2.0, 5.0) assert Test2.__match_args__ == ("c", "b", "d", "a", "e") assert Test2.__slots__ == ("e",) def test_subclass_with_mixin(self): class A(Struct): b: int a: float = 1.0 class Mixin(Struct): pass class B(A, Mixin): a: float = 2.0 assert B.__struct_fields__ == ("b", "a") assert B.__struct_defaults__ == (2.0,) assert B.__match_args__ == ("b", "a") assert B.__slots__ == () def test_positional_after_keyword_errors(self): with pytest.raises(TypeError) as rec: class Test(Struct): a: int b: int = 1 c: float assert "Required field 'c' cannot follow optional fields" in str(rec.value) def test_positional_after_keyword_subclass_errors(self): class Base(Struct): a: int b: int = 1 with pytest.raises(TypeError) as rec: class Test(Base): c: float assert "Required field 'c' cannot follow optional fields" in str(rec.value) def test_kw_only_positional(self): class Test(Struct, kw_only=True): b: int a: int assert Test.__struct_fields__ == ("b", "a") assert Test.__struct_defaults__ == () assert Test.__match_args__ == () assert Test.__slots__ == ("a", "b") def test_kw_only_mixed(self): class Test(Struct, kw_only=True): b: int a: int = 0 c: int d: int = 1 assert Test.__struct_fields__ == ("b", "a", "c", "d") assert Test.__struct_defaults__ == (0, NODEFAULT, 1) assert Test.__match_args__ == () assert Test.__slots__ == ("a", "b", "c", "d") def test_kw_only_positional_base_class(self): class Base(Struct, kw_only=True): b: int a: int class S1(Base): d: int c: int class S2(Base): d: int c: int = 1 assert S1.__struct_fields__ == ("d", "c", "b", "a") assert S1.__struct_defaults__ == () assert S1.__match_args__ == ("d", "c") assert S1.__slots__ == ("c", "d") assert S2.__struct_fields__ == ("d", "c", "b", "a") assert S2.__struct_defaults__ == (1, NODEFAULT, NODEFAULT) assert S2.__match_args__ == ("d", "c") assert S2.__slots__ == ("c", "d") def test_kw_only_base_class(self): class Base(Struct, kw_only=True): b: int = 1 a: int class S1(Base): d: int c: int = 2 assert S1.__struct_fields__ == ("d", "c", "b", "a") assert S1.__struct_defaults__ == (2, 1, NODEFAULT) assert S1.__match_args__ == ("d", "c") assert S1.__slots__ == ("c", "d") def test_kw_only_subclass(self): class Base(Struct): b: int a: int class S1(Base, kw_only=True): d: int c: int assert S1.__struct_fields__ == ("b", "a", "d", "c") assert S1.__struct_defaults__ == () assert S1.__match_args__ == ("b", "a") assert S1.__slots__ == ("c", "d") def test_kw_only_defaults_subclass(self): class Base(Struct): b: int a: int = 0 class S1(Base, kw_only=True): d: int c: int = 1 assert S1.__struct_fields__ == ("b", "a", "d", "c") assert S1.__struct_defaults__ == (0, NODEFAULT, 1) assert S1.__match_args__ == ("b", "a") assert S1.__slots__ == ("c", "d") def test_kw_only_overrides(self): class Base(Struct): b: int a: int = 2 class S1(Base, kw_only=True): b: int c: int = 3 assert S1.__struct_fields__ == ("a", "b", "c") assert S1.__struct_defaults__ == (2, NODEFAULT, 3) assert S1.__match_args__ == ("a",) assert S1.__slots__ == ("c",) def test_kw_only_overridden(self): class Base(Struct, kw_only=True): b: int a: int = 2 class S1(Base): b: int c: int = 3 assert S1.__struct_fields__ == ("b", "c", "a") assert S1.__struct_defaults__ == (3, 2) assert S1.__match_args__ == ("b", "c") assert S1.__slots__ == ("c",) class TestStructInit: def test_init_positional(self): class Test(Struct): a: int b: float c: int = 3 d: float = 4.0 assert as_tuple(Test(1, 2.0)) == (1, 2.0, 3, 4.0) assert as_tuple(Test(1, b=2.0)) == (1, 2.0, 3, 4.0) assert as_tuple(Test(a=1, b=2.0)) == (1, 2.0, 3, 4.0) assert as_tuple(Test(1, b=2.0, c=5)) == (1, 2.0, 5, 4.0) assert as_tuple(Test(1, b=2.0, d=5.0)) == (1, 2.0, 3, 5.0) assert as_tuple(Test(1, 2.0, 5)) == (1, 2.0, 5, 4.0) assert as_tuple(Test(1, 2.0, 5, 6.0)) == (1, 2.0, 5, 6.0) with pytest.raises(TypeError, match="Missing required argument 'a'"): Test() with pytest.raises(TypeError, match="Missing required argument 'b'"): Test(1) with pytest.raises(TypeError, match="Extra positional arguments provided"): Test(1, 2, 3, 4, 5) with pytest.raises(TypeError, match="Argument 'a' given by name and position"): Test(1, 2, a=3) with pytest.raises(TypeError, match="Unexpected keyword argument 'e'"): Test(1, 2, e=5) def test_init_kw_only(self): class Test(Struct, kw_only=True): a: int b: float = 2.0 c: int = 3 assert as_tuple(Test(a=1)) == (1, 2.0, 3) assert as_tuple(Test(a=1, b=4.0)) == (1, 4.0, 3) assert as_tuple(Test(a=1, c=4)) == (1, 2.0, 4) assert as_tuple(Test(a=1, b=4.0, c=5)) == (1, 4.0, 5) with pytest.raises(TypeError, match="Missing required argument 'a'"): Test() with pytest.raises(TypeError, match="Extra positional arguments provided"): Test(1) with pytest.raises(TypeError, match="Unexpected keyword argument 'e'"): Test(a=1, e=5) def test_init_kw_only_mixed(self): class Base(Struct, kw_only=True): c: int = 3 d: float = 4.0 class Test(Base): a: int b: float = 2.0 assert as_tuple(Test(1)) == (1, 2.0, 3, 4.0) assert as_tuple(Test(1, 5.0)) == (1, 5.0, 3, 4.0) assert as_tuple(Test(a=1)) == (1, 2.0, 3, 4.0) assert as_tuple(Test(a=1, b=5.0)) == (1, 5.0, 3, 4.0) assert as_tuple(Test(1, c=5)) == (1, 2.0, 5, 4.0) with pytest.raises(TypeError, match="Missing required argument 'a'"): Test() with pytest.raises(TypeError, match="Argument 'a' given by name and position"): Test(1, b=3.0, c=4, a=3) with pytest.raises(TypeError, match="Extra positional arguments provided"): Test(1, 5.0, 3) with pytest.raises(TypeError, match="Unexpected keyword argument 'e'"): Test(1, e=5) class TestSignature: def test_signature_no_args(self): class Test(Struct): pass sig = Signature(parameters=[]) assert Test.__signature__ == sig def test_signature_positional(self): class Test(Struct): b: float a: int = 1 sig = Signature( parameters=[ Parameter("b", Parameter.POSITIONAL_OR_KEYWORD, annotation=float), Parameter( "a", Parameter.POSITIONAL_OR_KEYWORD, default=1, annotation=int, ), ] ) assert Test.__signature__ == sig def test_signature_kw_only(self): class Base(Struct, kw_only=True): c: float d: int = 2 class Test(Base): b: float a: int = 1 sig = Signature( parameters=[ Parameter("b", Parameter.POSITIONAL_OR_KEYWORD, annotation=float), Parameter( "a", Parameter.POSITIONAL_OR_KEYWORD, default=1, annotation=int, ), Parameter("c", Parameter.KEYWORD_ONLY, annotation=float), Parameter("d", Parameter.KEYWORD_ONLY, default=2, annotation=int), ] ) assert Test.__signature__ == sig class TestRepr: def test_repr_base(self): x = Struct() assert repr(x) == "Struct()" assert x.__rich_repr__() == [] def test_repr_empty(self): class Test(Struct): pass x = Test() assert repr(x) == "Test()" assert x.__rich_repr__() == [] def test_repr_one_field(self): class Test(Struct): a: int x = Test(1) assert repr(x) == "Test(a=1)" assert x.__rich_repr__() == [("a", 1)] def test_repr_two_fields(self): class Test(Struct): a: int b: str x = Test(1, "y") assert repr(x) == "Test(a=1, b='y')" assert x.__rich_repr__() == [("a", 1), ("b", "y")] def test_repr_omit_defaults_empty(self): class Test(Struct, repr_omit_defaults=True): pass x = Test() assert repr(x) == "Test()" assert x.__rich_repr__() == [] def test_repr_omit_defaults_one_field(self): class Test(Struct, repr_omit_defaults=True): a: int = 0 x = Test(0) assert repr(x) == "Test()" assert x.__rich_repr__() == [] x = Test(1) assert repr(x) == "Test(a=1)" assert x.__rich_repr__() == [("a", 1)] def test_repr_omit_defaults_multiple_fields(self): class Test(Struct, repr_omit_defaults=True): a: int b: int = 0 c: str = "" x = Test(0) assert repr(x) == "Test(a=0)" assert x.__rich_repr__() == [("a", 0)] x = Test(0, b=1) assert repr(x) == "Test(a=0, b=1)" assert x.__rich_repr__() == [("a", 0), ("b", 1)] x = Test(0, c="two") assert repr(x) == "Test(a=0, c='two')" assert x.__rich_repr__() == [("a", 0), ("c", "two")] x = Test(0, b=1, c="two") assert repr(x) == "Test(a=0, b=1, c='two')" assert x.__rich_repr__() == [("a", 0), ("b", 1), ("c", "two")] def test_repr_recursive(self): class Test(Struct): a: int b: Any t = Test(1, Test(2, None)) t.b.b = t assert repr(t) == "Test(a=1, b=Test(a=2, b=...))" def test_repr_missing_attr_errors(self): class Test(Struct): a: int b: str t = Test(1, "hello") del t.b with pytest.raises(AttributeError): repr(t) with pytest.raises(AttributeError): t.__rich_repr__() def test_repr_errors(self): msg = "Oh no!" class Bad: def __repr__(self): raise ValueError(msg) class Test(Struct): a: object b: object t = Test(1, Bad()) with pytest.raises(ValueError, match=msg): repr(t) def test_struct_copy(): x = copy.copy(Struct()) assert type(x) is Struct class Test(Struct): b: int a: int x = copy.copy(Test(1, 2)) assert type(x) is Test assert x.b == 1 assert x.a == 2 class FrozenPoint(Struct, frozen=True): x: int y: int @pytest.mark.parametrize( "default", [ None, False, True, 1, 2.0, 1.5 + 2.32j, b"test", "test", (), frozenset(), frozenset((1, (2, 3, 4), 5)), Fruit.APPLE, datetime.time(1), datetime.date.today(), datetime.timedelta(seconds=2), datetime.datetime.now(), FrozenPoint(1, 2), ], ) def test_struct_immutable_defaults_use_instance(default): class Test(Struct): value: object = default t = Test() assert t.value is default @pytest.mark.parametrize("default", [[], {}, set()]) def test_struct_empty_mutable_defaults_fast_copy(default): class Test(Struct): value: object = default t = Test() assert t.value == default assert t.value is not default class Point(Struct): x: int y: int class PointKWOnly(Struct, kw_only=True): x: int y: int @pytest.mark.parametrize("default", [[], {}, set(), bytearray()]) def test_struct_empty_mutable_defaults_work(default): class Test(Struct): value: object = default x = Test().value x == default assert x is not default @pytest.mark.parametrize( "default", [Point(1, 2), [1], {"a": "b"}, {1, 2}, bytearray(b"test")], ) def test_struct_nonempty_mutable_defaults_error(default): with pytest.raises(TypeError) as rec: class Test(Struct): value: object = default assert "as a default value is unsafe" in str(rec.value) assert repr(default) in str(rec.value) def test_struct_defaults_from_field(): default = [] class Test(Struct): req: int = field() x: int = field(default=1) y: int = field(default_factory=lambda: 2) z: list[int] = field(default=default) t = Test(100) assert t.req == 100 assert t.x == 1 assert t.y == 2 assert t.z == [] assert t.z is not default def test_struct_default_factory_errors(): def bad(): raise ValueError("Oh no") class Test(Struct): x: int = field(default_factory=bad) with pytest.raises(ValueError): Test() def test_struct_reference_counting(): """Test that struct operations that access fields properly decref""" class Test(Struct): value: list data = [1, 2, 3] t = Test(data) assert sys.getrefcount(data) <= 3 repr(t) assert sys.getrefcount(data) <= 3 t2 = t.__copy__() assert sys.getrefcount(data) <= 4 assert t == t2 assert sys.getrefcount(data) <= 4 def test_struct_definition_does_not_leak_annotations(): """Defining a struct type must not retain its `__annotations__` dict""" class Annotation: pass ref = weakref.ref(Annotation) cls = defstruct("Temp", [("x", Annotation)]) del cls, Annotation gc.collect() assert ref() is None def test_struct_definition_does_not_leak_class_body_annotations(): """A class body must not retain the annotations built for it""" def define_struct_type(): class Annotation: pass class Example(Struct): x: Annotation return weakref.ref(Annotation) refs = [define_struct_type() for _ in range(3)] gc.collect() assert [ref() for ref in refs] == [None, None, None] @pytest.mark.parametrize("spelling", ["ClassVar", "typing.ClassVar"]) def test_struct_definition_does_not_leak_module_namespace(spelling): """A string `ClassVar` annotation must not retain the module namespace""" class Sentinel: pass def define_in_temp_module(): with temp_module( "import typing\nfrom typing import ClassVar\nimport msgspec\n" ) as mod: sentinel = Sentinel() mod.__dict__["sentinel"] = sentinel exec( "from __future__ import annotations\n" "class Ex(msgspec.Struct):\n" f" a: {spelling}[int] = 1\n" " x: int = 0\n", mod.__dict__, ) # The leak only exists while the annotations are strings assert mod.Ex.__annotations__["x"] == "int" return weakref.ref(sentinel) refs = [define_in_temp_module() for _ in range(3)] gc.collect() assert [ref() for ref in refs] == [None, None, None] def test_struct_definition_does_not_leak_non_struct_base_dict(): """Defining a struct must not retain the type dict of a non-struct base""" class Sentinel: pass def define_struct_type(): sentinel = Sentinel() Mixin = type("Mixin", (), {"sentinel": sentinel}) class Example(Mixin, Struct): x: int return weakref.ref(sentinel) refs = [define_struct_type() for _ in range(3)] gc.collect() assert [ref() for ref in refs] == [None, None, None] def test_struct_gc_not_added_if_not_needed(): """Structs aren't tracked by GC until/unless they reference a container type""" class Test(Struct): x: object y: object assert not gc.is_tracked(Test(1, 2)) assert not gc.is_tracked(Test("hello", "world")) assert gc.is_tracked(Test([1, 2, 3], 1)) assert gc.is_tracked(Test(1, [1, 2, 3])) # Tuples are all tracked on creation, but through GC passes eventually # become untracked if they don't contain tracked types untracked_tuple = (1, 2, 3) for i in range(5): gc.collect() if not gc.is_tracked(untracked_tuple): break else: assert False, "something has changed with Python's GC, investigate" assert not gc.is_tracked(Test(1, untracked_tuple)) tracked_tuple = ([],) assert gc.is_tracked(Test(1, tracked_tuple)) # On mutation, if a tracked objected is stored on a struct, an untracked # struct will become tracked t = Test(1, 2) assert not gc.is_tracked(t) t.x = 3 assert not gc.is_tracked(t) t.x = untracked_tuple assert not gc.is_tracked(t) t.x = [] assert gc.is_tracked(t) # An error in setattr doesn't change tracked status t = Test(1, 2) assert not gc.is_tracked(t) with pytest.raises(AttributeError): t.z = [] assert not gc.is_tracked(t) class TestStructGC: @pytest.mark.skipif( hasattr(sys.flags, "gil") and not sys.flags.gil, reason="object layout is different on free-threading builds", ) def test_memory_layout(self): sizes = {} for has_gc in [False, True]: class Test(Struct, gc=has_gc): x: object y: object sizes[has_gc] = sys.getsizeof(Test(1, 2)) # Currently gc=False structs are 16 bytes smaller than gc=True structs, # but that's a cpython implementation detail. This test is mainly to # check that the smaller layout is being actually used. assert sizes[False] < sizes[True] def test_init(self): class Test(Struct, gc=False): x: object y: object assert not gc.is_tracked(Test(1, 2)) assert not gc.is_tracked(Test([1, 2, 3], 1)) assert not gc.is_tracked(Test(1, [1, 2, 3])) def test_setattr(self): class Test(Struct, gc=False): x: object y: object # Tracked status doesn't change on mutation t = Test(1, 2) assert not gc.is_tracked(t) t.x = [] assert not gc.is_tracked(t) def test_gc_false_inherit_from_gc_true(self): class HasGC(Struct): x: object class NoGC(HasGC, gc=False): y: object assert gc.is_tracked(HasGC([])) assert not gc.is_tracked(NoGC(1, 2)) assert not gc.is_tracked(NoGC(1, [])) x = NoGC([], 2) assert not gc.is_tracked(x) x.y = [] assert not gc.is_tracked(x) def test_gc_true_inherit_from_gc_false(self): class NoGC(Struct, gc=False): y: object class HasGC(NoGC, gc=True): x: object assert gc.is_tracked(HasGC(1, [])) assert gc.is_tracked(HasGC([], 1)) x = HasGC(1, 2) assert not gc.is_tracked(x) x.x = [] assert gc.is_tracked(x) @pytest.mark.parametrize("has_gc", [False, True]) def test_struct_gc_set_on_copy(self, has_gc): """Copying doesn't go through the struct constructor""" class Test(Struct, gc=has_gc): x: object y: object assert not gc.is_tracked(copy.copy(Test(1, 2))) assert not gc.is_tracked(copy.copy(Test(1, ()))) assert gc.is_tracked(copy.copy(Test(1, []))) == has_gc def test_struct_gc_false_cannot_inherit_from_non_slots_classes(self): class Base: pass with pytest.raises( ValueError, match="Cannot set gc=False when inheriting from non-struct types with a __dict__", ): class Test(Struct, Base, gc=False): pass def test_struct_gc_false_can_inherit_from_slots_class_mixin(self): class Base: __slots__ = () class Test(Struct, Base, gc=False): x: int t = Test(1) assert not gc.is_tracked(t) @pytest.mark.parametrize("case", ["base-dict", "base-nogc", "nobase"]) def test_struct_gc_false_forbids_dict_true(self, case): if case == "base-dict": class Base(Struct, dict=True): pass opts = {"gc": False} elif case == "base-nogc": class Base(Struct, gc=False): pass opts = {"dict": True} elif case == "nobase": Base = Struct opts = {"gc": False, "dict": True} with pytest.raises(ValueError, match="Cannot set gc=False and dict=True"): class Test(Base, **opts): pass @staticmethod def assert_gc_false_with_weakref_rejected(base, **opts): with pytest.raises(ValueError, match="Cannot set gc=False and weakref=True"): class Test(base, **opts): pass def test_struct_gc_false_forbids_weakref_true(self): self.assert_gc_false_with_weakref_rejected(Struct, gc=False, weakref=True) def test_struct_gc_false_forbids_weakref_base(self): class Base(Struct, weakref=True): pass self.assert_gc_false_with_weakref_rejected(Base, gc=False) def test_struct_gc_false_base_forbids_weakref_true(self): class Base(Struct, gc=False): pass self.assert_gc_false_with_weakref_rejected(Base, weakref=True) def test_struct_gc_false_forbids_weakref_grandparent(self): class Grandparent(Struct, weakref=True): pass class Base(Grandparent): pass self.assert_gc_false_with_weakref_rejected(Base, gc=False) def test_struct_gc_false_forbids_weakref_slot_from_mixin(self): class Mixin: __slots__ = ("__weakref__",) class Base(Mixin, Struct): pass self.assert_gc_false_with_weakref_rejected(Base, gc=False) def test_struct_gc_false_forbids_weakref_true_defstruct(self): with pytest.raises(ValueError, match="Cannot set gc=False and weakref=True"): defstruct("Test", ["x"], gc=False, weakref=True) def test_struct_gc_false_and_weakref_still_allowed_apart(self): class NoGC(Struct, gc=False): x: list class SubNoGC(NoGC, gc=False): y: list class WithWeakRef(Struct, weakref=True): x: list assert not gc.is_tracked(NoGC([1])) assert not gc.is_tracked(SubNoGC([1], [2])) obj = WithWeakRef([1]) assert gc.is_tracked(obj) assert weakref.ref(obj)() is obj class TestStructDealloc: @pytest.mark.parametrize("has_gc", [False, True]) def test_struct_dealloc_decrefs_type(self, has_gc): class Test1(Struct, gc=has_gc): x: int y: int class Test2(Struct, gc=has_gc): x: int y: int with nogc(): orig_1 = sys.getrefcount(Test1) orig_2 = sys.getrefcount(Test2) t = Test1(1, 2) assert sys.getrefcount(Test1) <= orig_1 + 1 del t assert sys.getrefcount(Test1) <= orig_1 t = Test2(1, 2) assert sys.getrefcount(Test1) <= orig_1 assert sys.getrefcount(Test2) <= orig_2 + 1 del t assert sys.getrefcount(Test1) <= orig_1 assert sys.getrefcount(Test2) <= orig_2 gc.collect() assert sys.getrefcount(Test1) == orig_1 assert sys.getrefcount(Test2) == orig_2 @pytest.mark.parametrize("has_gc", [False, True]) def test_struct_dealloc_calls_finalizer(self, has_gc): for _ in range(3): called = False class Test(Struct, gc=has_gc): x: int y: int def __del__(self): nonlocal called called = True t = Test(1, 2) if hasattr(gc, "is_finalized"): assert not gc.is_finalized(t) del t assert called @pytest.mark.parametrize("has_gc", [False, True]) def test_struct_dealloc_supports_finalizer_resurrection(self, has_gc): for _ in range(3): called = False new_ref = None class Test(Struct, gc=has_gc): x: int y: int def __del__(self): # XXX: Python will only run `__del__` once, even if it's # resurrected FOR GC TYPES ONLY. If gc=False, cpython will # happily run `__del__` every time the refcount drops to 0 nonlocal called nonlocal new_ref if not called: called = True new_ref = self t = Test(1, 2) del t assert called assert new_ref is not None del new_ref @pytest.mark.parametrize("has_gc", [False, True]) def test_struct_dealloc_trashcan(self, has_gc): N = 100 called = set() class Node(Struct, gc=has_gc): child: "Node | None" = None def __del__(self): called.add(id(self)) node = None for _ in range(N): node = Node(node) del node assert len(called) == N @pytest.mark.parametrize("has_gc", [False, True]) def test_struct_dealloc_decrefs_fields(self, has_gc): class Test(Struct, gc=has_gc): x: Any x = object() t = Test(x) count = sys.getrefcount(x) del t assert sys.getrefcount(x) == count - 1 @pytest.mark.parametrize("has_gc", [False, True]) def test_struct_dealloc_works_with_missing_fields(self, has_gc): class Test(Struct, gc=has_gc): x: Any y: Any x = object() t = Test(x, None) del t.y count = sys.getrefcount(x) del t assert sys.getrefcount(x) == count - 1 def test_struct_dealloc_dict(self): class Test(Struct, dict=True): x: int called = False class Flag: def __del__(self): nonlocal called called = True t = Test(1) t.flag = Flag() del t assert called def test_struct_dealloc_weakref(self): class Test(Struct, weakref=True): x: int t = Test(1) # smoketest dealloc weakrefable struct doesn't crash del t t = Test(1) ref = weakref.ref(t) assert ref() is not None del t assert ref() is None def test_struct_dealloc_in_gc_properly_handles_type_decref(self): def inner(): class Box(msgspec.Struct): a: Any gc.collect() o = Box(None) o.a = o for _ in range(5): inner() gc.collect() @pytest.mark.parametrize("kw_only", [False, True]) @pytest.mark.parametrize("protocol", range(pickle.HIGHEST_PROTOCOL + 1)) def test_struct_pickle(kw_only, protocol): cls = PointKWOnly if kw_only else Point a = cls(x=1, y=2) b = cls(x=3, y=4) assert pickle.loads(pickle.dumps(a, protocol=protocol)) == a assert pickle.loads(pickle.dumps(b, protocol=protocol)) == b del a.x with pytest.raises(AttributeError, match="Struct field 'x' is unset"): pickle.dumps(a, protocol=protocol) def test_struct_handles_missing_attributes(): """If an attribute is unset, raise an AttributeError appropriately""" class MyStruct(Struct): x: int y: int z: str = "default" t = MyStruct(1, 2) del t.y t2 = MyStruct(1, 2) match = "Struct field 'y' is unset" with pytest.raises(AttributeError, match=match): repr(t) with pytest.raises(AttributeError, match=match): copy.copy(t) with pytest.raises(AttributeError, match=match): t == t2 with pytest.raises(AttributeError, match=match): t2 == t @pytest.mark.parametrize( "option, default", [ ("frozen", False), ("order", False), ("eq", True), ("repr_omit_defaults", False), ("array_like", False), ("gc", True), ("omit_defaults", False), ("forbid_unknown_fields", False), ], ) def test_struct_option_precedence(option, default): def get(cls): return getattr(cls.__struct_config__, option) class Default(Struct): pass assert get(Default) is default class Enabled(Struct, **{option: True}): pass assert get(Enabled) is True class Disabled(Struct, **{option: False}): pass assert get(Disabled) is False class T(Enabled): pass assert get(T) is True class T(Enabled, **{option: False}): pass assert get(T) is False class T(Enabled, Default): pass assert get(T) is True class T(Default, Enabled): pass assert get(T) is True class T(Default, Disabled, Enabled): pass assert get(T) is False def test_weakref_option(): class Default(Struct): pass assert Default.__weakrefoffset__ == 0 class Enabled(Struct, weakref=True): pass assert Enabled.__weakrefoffset__ != 0 assert Enabled.__struct_config__.weakref class Disabled(Struct, weakref=False): pass assert Disabled.__weakrefoffset__ == 0 assert not Disabled.__struct_config__.weakref class T(Enabled): pass assert T.__weakrefoffset__ != 0 assert T.__struct_config__.weakref class T(Enabled, Default): pass assert T.__weakrefoffset__ != 0 assert T.__struct_config__.weakref class T(Default, Disabled, Enabled): pass assert T.__weakrefoffset__ != 0 assert T.__struct_config__.weakref with pytest.raises(ValueError, match="Cannot set `weakref=False`"): class T(Enabled, weakref=False): pass def test_dict_option(): class Default(Struct): pass assert Default.__dictoffset__ == 0 class Enabled(Struct, dict=True): pass assert Enabled.__dictoffset__ != 0 assert Enabled.__struct_config__.dict class Disabled(Struct, dict=False): pass assert Disabled.__dictoffset__ == 0 assert not Disabled.__struct_config__.dict class T(Enabled): pass assert T.__dictoffset__ != 0 assert T.__struct_config__.dict class T(Enabled, Default): pass assert T.__dictoffset__ != 0 assert T.__struct_config__.dict class T(Default, Disabled, Enabled): pass assert T.__dictoffset__ != 0 assert T.__struct_config__.dict with pytest.raises(ValueError, match="Cannot set `dict=False`"): class T(Enabled, dict=False): pass def test_cache_hash_option(): with pytest.raises( ValueError, match="Cannot set cache_hash=True without frozen=True" ): class Invalid(Struct, cache_hash=True): pass class Default(Struct, frozen=True): pass assert "__msgspec_cached_hash__" not in Default.__slots__ assert not Default.__struct_config__.cache_hash class Enabled(Struct, cache_hash=True, frozen=True): pass assert "__msgspec_cached_hash__" in Enabled.__slots__ assert Enabled.__struct_config__.cache_hash class Disabled(Struct, cache_hash=False, frozen=True): pass assert "__msgspec_cached_hash__" not in Disabled.__slots__ assert not Disabled.__struct_config__.cache_hash class T(Enabled): pass assert "__msgspec_cached_hash__" not in T.__slots__ assert T.__struct_config__.cache_hash class T(Enabled, Default): pass assert "__msgspec_cached_hash__" not in T.__slots__ assert T.__struct_config__.cache_hash class T(Default, Disabled, Enabled): pass assert "__msgspec_cached_hash__" not in T.__slots__ assert T.__struct_config__.cache_hash with pytest.raises(ValueError, match="Cannot set `cache_hash=False`"): class T(Enabled, cache_hash=False): pass def test_invalid_option_raises(): with pytest.raises(TypeError): class Foo(Struct, invalid=True): pass class FrozenPoint(Struct, frozen=True): x: int y: int class TestHash: def test_frozen_objects_hashable(self): p1 = FrozenPoint(1, 2) p2 = FrozenPoint(1, 2) p3 = FrozenPoint(1, 3) assert hash(p1) == hash(p2) assert hash(p1) != hash(p3) assert p1 == p2 assert p1 != p3 def test_frozen_objects_hash_errors_if_field_unhashable(self): p = FrozenPoint(1, [2]) with pytest.raises(TypeError): hash(p) def test_frozen_hash_mutable_objects_hash_errors(self): p = Point(1, 2) with pytest.raises(TypeError, match="unhashable type"): hash(p) def test_hash_includes_type(self): Ex1 = defstruct("Ex1", ["x"], frozen=True) Ex2 = defstruct("Ex2", ["x"], frozen=True) Ex3 = defstruct("Ex3", [], frozen=True) Ex4 = defstruct("Ex4", [], frozen=True) assert hash(Ex1(1)) == hash(Ex1(1)) assert hash(Ex1(1)) != hash(Ex2(1)) assert hash(Ex3()) == hash(Ex3()) assert hash(Ex3()) != hash(Ex4()) def test_cache_hash(self): class Inner: def __init__(self): self.hash_calls = 0 def __hash__(self): self.hash_calls += 1 return 123 class Cached(Struct, frozen=True, cache_hash=True): x: int y: Inner assert "__msgspec_cached_hash__" in Cached.__slots__ obj = Cached(1, Inner()) assert not hasattr(obj, "__msgspec_cached_hash__") assert hash(obj) == hash(obj) assert obj.__msgspec_cached_hash__ == hash(obj) assert obj.y.hash_calls == 1 class TestSetAttr: def test_frozen_objects_no_setattr(self): p = FrozenPoint(1, 2) with pytest.raises(AttributeError, match="immutable type: 'FrozenPoint'"): p.x = 3 @pytest.mark.parametrize("base_gc", [True, None, False]) @pytest.mark.parametrize("base_frozen", [True, False]) @pytest.mark.parametrize("has_gc", [True, None, False]) def test_override_setattr(self, has_gc, base_gc, base_frozen): called = False class Base(Struct, gc=base_gc, frozen=base_frozen): pass class Test(Struct, gc=has_gc, frozen=False): x: Any def __setattr__(self, name, value): nonlocal called called = True super().__setattr__(name, value) t = Test(1) assert not called t.x = 2 assert called if has_gc: assert not gc.is_tracked(t) t.x = [1] assert gc.is_tracked(t) @pytest.mark.parametrize("base_gc", [True, None, False]) @pytest.mark.parametrize("has_gc", [True, None, False]) def test_override_setattr_inherit(self, base_gc, has_gc): called = False class Base(Struct, gc=base_gc): x: Any def __setattr__(self, name, value): nonlocal called called = True super().__setattr__(name, value) class Test(Base, gc=has_gc): pass t = Test(1) assert not called t.x = 2 assert called if has_gc: assert not gc.is_tracked(t) t.x = [1] assert gc.is_tracked(t) def test_force_setattr(self): class Ex(Struct, frozen=True): x: Any obj = Ex(1) res = msgspec.structs.force_setattr(obj, "x", 2) assert res is None assert obj.x == 2 with pytest.raises(AttributeError): msgspec.structs.force_setattr(obj, "oops", 3) with pytest.raises(TypeError): msgspec.structs.force_setattr(1, "oops", 3) class TestOrderAndEq: @staticmethod def assert_eq(a, b): assert a == b assert not a != b @staticmethod def assert_neq(a, b): assert a != b assert not a == b def test_order_no_eq_errors(self): with pytest.raises(ValueError, match="Cannot set eq=False and order=True"): class Test(Struct, order=True, eq=False): pass def test_struct_eq_false(self): class Point(Struct, eq=False): x: int y: int p = Point(1, 2) # identity based equality self.assert_eq(p, p) self.assert_neq(p, Point(1, 2)) # identity based hash assert hash(p) == hash(p) assert hash(p) != hash(Point(1, 2)) def test_struct_eq(self): class Test(Struct): a: int b: int class Test2(Test): pass x = Struct() self.assert_eq(x, Struct()) self.assert_neq(x, None) x = Test(1, 2) self.assert_eq(x, Test(1, 2)) self.assert_neq(x, None) self.assert_neq(x, Test(1, 3)) self.assert_neq(x, Test(2, 2)) self.assert_neq(x, Test2(1, 2)) def test_struct_override_eq(self): class Ex(Struct): a: int b: int def __eq__(self, other): return self.a == other.a x = Ex(1, 2) y = Ex(1, 3) z = Ex(2, 3) self.assert_eq(x, y) self.assert_neq(x, z) def test_struct_eq_identity_fastpath(self): class Bad: def __eq__(self, other): raise ValueError("Oh no!") class Test(Struct): a: int b: Bad t = Test(1, Bad()) self.assert_eq(t, t) @pytest.mark.parametrize("op", ["le", "lt", "ge", "gt"]) def test_struct_order(self, op): func = getattr(operator, op) class Point(Struct, order=True): x: int y: int origin = Point(0, 0) for x in [-1, 0, 1]: for y in [-1, 0, 1]: sol = func((0, 0), (x, y)) res = func(origin, Point(x, y)) assert res == sol assert func(origin, origin) == func(1, 1) @pytest.mark.parametrize("eq, order", [(False, False), (True, False), (True, True)]) def test_struct_compare_returns_notimplemented(self, eq, order): class Test(Struct, eq=eq, order=order): x: int t1 = Test(1) t2 = Test(2) assert t1.__eq__(t2) is (False if eq else NotImplemented) assert t1.__lt__(t2) is (True if order else NotImplemented) assert t1.__eq__(None) is NotImplemented assert t1.__lt__(None) is NotImplemented @pytest.mark.parametrize("op", ["eq", "ne", "le", "lt", "ge", "gt"]) def test_struct_compare_errors(self, op): func = getattr(operator, op) class Bad: def __eq__(self, other): raise ValueError("Oh no!") class Test(Struct, order=True): a: object b: object t = Test(1, Bad()) t2 = Test(1, 2) with pytest.raises(ValueError, match="Oh no!"): func(t, t2) with pytest.raises(ValueError, match="Oh no!"): func(t2, t) class TestTagAndTagField: @pytest.mark.parametrize( "opts, tag_field, tag", [ # Default & explicit NULL ({}, None, None), ({"tag": None, "tag_field": None}, None, None), # tag=True ({"tag": True}, "type", "Test"), ({"tag": True, "tag_field": "test"}, "test", "Test"), # tag=False ({"tag": False}, None, None), ({"tag": False, "tag_field": "kind"}, None, None), # tag str ({"tag": "test"}, "type", "test"), (dict(tag="test", tag_field="kind"), "kind", "test"), # tag int ({"tag": 1}, "type", 1), (dict(tag=1, tag_field="kind"), "kind", 1), # tag callable (dict(tag=lambda n: n.lower()), "type", "test"), (dict(tag=lambda n: n.lower(), tag_field="kind"), "kind", "test"), # tag_field alone (dict(tag_field="kind"), "kind", "Test"), ], ) def test_config(self, opts, tag_field, tag): class Test(Struct, **opts): x: int y: int assert Test.__struct_config__.tag_field == tag_field assert Test.__struct_config__.tag == tag @pytest.mark.parametrize( "opts1, opts2, tag_field, tag", [ # tag=True ({"tag": True}, {}, "type", "S2"), ({"tag": True}, {"tag": None}, "type", "S2"), ({"tag": True}, {"tag": False}, None, None), ({"tag": True}, {"tag_field": "foo"}, "foo", "S2"), # tag str ({"tag": "test"}, {}, "type", "test"), ({"tag": "test"}, {"tag": "test2"}, "type", "test2"), ({"tag": "test"}, {"tag": None}, "type", "test"), ({"tag": "test"}, {"tag_field": "foo"}, "foo", "test"), # tag int ({"tag": 1}, {}, "type", 1), ({"tag": 1}, {"tag": "test2"}, "type", "test2"), ({"tag": 1}, {"tag": None}, "type", 1), ({"tag": 1}, {"tag_field": "foo"}, "foo", 1), # tag callable ({"tag": lambda n: n.lower()}, {}, "type", "s2"), ({"tag": lambda n: n.lower()}, {"tag": False}, None, None), ({"tag": lambda n: n.lower()}, {"tag": None}, "type", "s2"), ({"tag": lambda n: n.lower()}, {"tag_field": "foo"}, "foo", "s2"), ], ) def test_inheritance(self, opts1, opts2, tag_field, tag): class S1(Struct, **opts1): pass class S2(S1, **opts2): pass assert S2.__struct_config__.tag_field == tag_field assert S2.__struct_config__.tag == tag def test_tag_uses_simple_qualname(self): class S1(Struct, tag=True): class S2(Struct, tag=True): pass assert S1.__struct_config__.tag == "S1" assert S1.S2.__struct_config__.tag == "S1.S2" class S1(Struct, tag=str.lower): class S2(Struct, tag=str.lower): pass assert S1.__struct_config__.tag == "s1" assert S1.S2.__struct_config__.tag == "s1.s2" @pytest.mark.parametrize("tag", [b"bad", lambda n: b"bad"]) def test_tag_wrong_type(self, tag): with pytest.raises(TypeError, match="`tag` must be a `str` or an `int`"): class Test(Struct, tag=tag): pass @pytest.mark.parametrize("tag", [-(2**63) - 1, 2**63]) def test_tag_integer_out_of_range(self, tag): with pytest.raises(ValueError, match="Integer `tag` values must be"): class Test(Struct, tag=tag): pass def test_tag_field_wrong_type(self): with pytest.raises(TypeError, match="`tag_field` must be a `str`"): class Test(Struct, tag_field=b"bad"): pass def test_tag_field_collision(self): with pytest.raises(ValueError, match="tag_field='y'"): class Test(Struct, tag_field="y"): x: int y: int def test_tag_field_inheritance_collision(self): # Inherit the tag field class Base(Struct, tag_field="y"): pass with pytest.raises(ValueError, match="tag_field='y'"): class Test(Base): x: int y: int # Inherit the field class Base(Struct): x: int y: int with pytest.raises(ValueError, match="tag_field='y'"): class Test(Base, tag_field="y"): # noqa pass class TestRename: def test_field_name(self): class Test(Struct): x: int = field(name="field_x") assert Test.__struct_encode_fields__ == ("field_x",) def test_rename_mixed_with_field_name(self): class Test(Struct, rename="upper"): x: int = field(name="field_x") y: int assert Test.__struct_encode_fields__ == ("field_x", "Y") def test_rename_no_change(self): class Test(Struct, rename="lower"): x: int assert Test.__struct_fields__ is Test.__struct_encode_fields__ def test_field_name_no_change(self): class Test(Struct): x: int = field(name="x") assert Test.__struct_fields__ is Test.__struct_encode_fields__ def test_field_name_none(self): class Test(Struct): x: int = field(name=None) assert Test.__struct_fields__ is Test.__struct_encode_fields__ class Test(Struct, rename="upper"): x: int = field(name=None) assert Test.__struct_encode_fields__ == ("X",) def test_rename_explicit_none(self): class Test(Struct, rename=None): field_one: int field_two: str assert Test.__struct_encode_fields__ == ("field_one", "field_two") assert Test.__struct_fields__ is Test.__struct_encode_fields__ def test_rename_lower(self): class Test(Struct, rename="lower"): field_One: int field_Two: str assert Test.__struct_encode_fields__ == ("field_one", "field_two") def test_rename_upper(self): class Test(Struct, rename="upper"): field_one: int field_two: str assert Test.__struct_encode_fields__ == ("FIELD_ONE", "FIELD_TWO") def test_rename_kebab(self): class Test(Struct, rename="kebab"): field_one: int field_two_with_suffix: str __field_three__: bool field4: float _field_five: int assert Test.__struct_encode_fields__ == ( "field-one", "field-two-with-suffix", "field-three", "field4", "field-five", ) def test_rename_camel(self): class Test(Struct, rename="camel"): field_one: int field_two_with_suffix: str __field__three__: bool field4: float _field_five: int assert Test.__struct_encode_fields__ == ( "fieldOne", "fieldTwoWithSuffix", "__fieldThree", "field4", "_fieldFive", ) def test_rename_pascal(self): class Test(Struct, rename="pascal"): field_one: int field_two_with_suffix: str __field__three__: bool field4: float _field_five: int assert Test.__struct_encode_fields__ == ( "FieldOne", "FieldTwoWithSuffix", "__FieldThree", "Field4", "_FieldFive", ) def test_rename_callable(self): class Test(Struct, rename=str.title): field_one: int field_two: str assert Test.__struct_encode_fields__ == ("Field_One", "Field_Two") def test_rename_callable_returns_none(self): class Test(Struct, rename={"from_": "from"}.get): from_: str to: str assert Test.__struct_encode_fields__ == ("from", "to") def test_rename_callable_returns_non_string(self): with pytest.raises( TypeError, match="Expected calling `rename` to return a `str` or `None`, got `int`", ): class Test(Struct, rename=lambda x: 1): aa1: int aa2: int ab1: int def test_rename_mapping(self): class Test(Struct, rename={"from_": "from"}): from_: str to: str assert Test.__struct_encode_fields__ == ("from", "to") def test_rename_bad_value(self): with pytest.raises(ValueError, match="rename='invalid' is unsupported"): class Test(Struct, rename="invalid"): x: int def test_rename_bad_type(self): with pytest.raises(TypeError, match="str, callable, or mapping"): class Test(Struct, rename=1): x: int def test_rename_fields_collide(self): with pytest.raises(ValueError, match="Multiple fields rename to the same name"): class Test(Struct, rename=lambda x: x[:2]): aa1: int aa2: int ab1: int @pytest.mark.parametrize("field", ["foo\\bar", 'foo"bar', "foo\tbar"]) def test_rename_field_invalid_characters(self, field): with pytest.raises(ValueError) as rec: class Test(Struct, rename=lambda x: field): x: int assert field in str(rec.value) assert "must not contain" in str(rec.value) def test_rename_inherit(self): class Base(Struct, rename="upper"): pass class Test1(Base): x: int assert Test1.__struct_encode_fields__ == ("X",) class Test2(Base, rename="camel"): my_field: int assert Test2.__struct_encode_fields__ == ("myField",) class Test3(Test2, rename="kebab"): my_other_field: int assert Test3.__struct_encode_fields__ == ("myField", "my-other-field") class Test4(Base, rename=None): my_field: int assert Test4.__struct_encode_fields__ == ("my_field",) def test_field_name_override_inherited(self): class Base(Struct): x: int = field(name="_x") class Test1(Base): x: int = field(name="x") assert Test1.__struct_encode_fields__ == ("x",) class Test2(Base): x: int = 1 assert Test2.__struct_encode_fields__ == ("_x",) def test_rename_override_inherited(self): class Base(Struct, rename="upper"): x: int class Test(Base, rename="lower"): x: int assert Test.__struct_encode_fields__ == ("x",) def test_rename_fields_only_used_for_encode_and_decode(self): """Check that the renamed fields don't show up elsewhere""" class Test(Struct, rename="upper"): one: int two: str t = Test(one=1, two="test") assert t.one == 1 assert t.two == "test" assert repr(t) == "Test(one=1, two='test')" with pytest.raises(TypeError, match="Missing required argument 'two'"): Test(one=1) class TestDefStruct: def test_defstruct_simple(self): Point = defstruct("Point", ["x", "y"]) assert issubclass(Point, Struct) assert as_tuple(Point(1, 2)) == (1, 2) assert Point.__module__ == "tests.unit.test_struct" def test_defstruct_empty(self): Empty = defstruct("Empty", []) assert as_tuple(Empty()) == () def test_defstruct_fields(self): Test = defstruct("Point", ["x", ("y", int), ("z", int, 0)]) assert Test.__struct_fields__ == ("x", "y", "z") assert Test.__struct_defaults__ == (0,) assert Test.__annotations__ == {"x": Any, "y": int, "z": int} assert as_tuple(Test(1, 2)) == (1, 2, 0) assert as_tuple(Test(1, 2, 3)) == (1, 2, 3) def test_defstruct_fields_iterable(self): Test = defstruct("Point", ((n, int) for n in "xyz")) assert Test.__struct_fields__ == ("x", "y", "z") assert Test.__annotations__ == {"x": int, "y": int, "z": int} def test_defstruct_errors(self): with pytest.raises(TypeError, match="must be str, not int"): defstruct(1) with pytest.raises(TypeError, match="`fields` must be an iterable"): defstruct("Test", 1) with pytest.raises(TypeError, match="items in `fields` must be one of"): defstruct("Test", ["x", 1]) with pytest.raises(TypeError, match="items in `fields` must be one of"): defstruct("Test", ["x", (1, 2)]) with pytest.raises(TypeError, match="must be a tuple or None"): defstruct("Test", [], bases=[]) with pytest.raises(TypeError, match="must be a str or None"): defstruct("Test", [], module=1) with pytest.raises(TypeError, match="must be a dict or None"): defstruct("Test", [], namespace=1) def test_defstruct_bases(self): class Base(Struct): z: int Point = defstruct("Point", ["x", "y"], bases=(Base,)) assert issubclass(Point, Base) assert issubclass(Point, Struct) assert as_tuple(Point(1, 2, 0)) == (1, 2, 0) assert as_tuple(Point(1, 2, 3)) == (1, 2, 3) def test_defstruct_bases_none(self): Point = defstruct("Point", ["x", "y"], bases=None) assert Point.mro() == [Point, *Struct.mro()] assert Point(1, 2) == Point(1, 2) def test_defstruct_module(self): Test = defstruct("Test", [], module="testmod") assert Test.__module__ == "testmod" def test_defstruct_module_none(self): Test = defstruct("Test", [], module=None) assert Test.__module__ == "tests.unit.test_struct" def test_defstruct_namespace(self): Test = defstruct( "Test", ["x", "y"], namespace={"add": lambda self: self.x + self.y} ) t = Test(1, 2) assert t.add() == 3 def test_defstruct_namespace_none(self): Test = defstruct("Test", [], namespace=None) assert Test() == Test() # smoketest def test_defstruct_kw_only(self): Test = defstruct("Test", ["x", "y"], kw_only=True) t = Test(x=1, y=2) assert t.x == 1 and t.y == 2 with pytest.raises(TypeError, match="Extra positional arguments"): Test(1, 2) @pytest.mark.parametrize( "option, default", [ ("repr_omit_defaults", False), ("omit_defaults", False), ("forbid_unknown_fields", False), ("frozen", False), ("order", False), ("eq", True), ("array_like", False), ("gc", True), ], ) def test_defstruct_bool_options(self, option, default): Test = defstruct("Test", [], **{option: True}) assert getattr(Test.__struct_config__, option) is True Test = defstruct("Test", [], **{option: False}) assert getattr(Test.__struct_config__, option) is False Test = defstruct("Test", []) assert getattr(Test.__struct_config__, option) is default def test_defstruct_weakref(self): Test = defstruct("Test", []) assert Test.__weakrefoffset__ == 0 assert not Test.__struct_config__.weakref Test = defstruct("Test", [], weakref=False) assert Test.__weakrefoffset__ == 0 assert not Test.__struct_config__.weakref Test = defstruct("Test", [], weakref=True) assert Test.__weakrefoffset__ != 0 assert Test.__struct_config__.weakref def test_defstruct_dict(self): Test = defstruct("Test", []) assert not hasattr(Test(), "__dict__") assert not Test.__struct_config__.dict Test = defstruct("Test", [], dict=False) assert not hasattr(Test(), "__dict__") assert not Test.__struct_config__.dict Test = defstruct("Test", [], dict=True) assert hasattr(Test(), "__dict__") assert Test.__struct_config__.dict def test_defstruct_cache_hash(self): Test = defstruct("Test", [], frozen=True) assert not Test.__struct_config__.cache_hash Test = defstruct("Test", [], frozen=True, cache_hash=False) assert not Test.__struct_config__.cache_hash Test = defstruct("Test", [], frozen=True, cache_hash=True) assert Test.__struct_config__.cache_hash def test_defstruct_tag_and_tag_field(self): Test = defstruct("Test", [], tag=True) assert Test.__struct_config__.tag == "Test" Test = defstruct("Test", [], namespace={"__qualname__": "Foo.Test"}, tag=True) assert Test.__struct_config__.tag == "Foo.Test" Test = defstruct("Test", [], tag="mytag", tag_field="mytagfield") config = Test.__struct_config__ assert config.tag_field == "mytagfield" assert config.tag == "mytag" def test_defstruct_rename(self): Test = defstruct("Test", ["my_field"], rename="camel") assert Test.__struct_fields__ == ("my_field",) assert Test.__struct_encode_fields__ == ("myField",) @pytest.fixture(params=["structs.replace", "copy.replace"]) def replace(request): if request.param == "structs.replace": return msgspec.structs.replace else: return copy_replace class TestReplace: def test_replace_not_a_struct(self): with pytest.raises(TypeError, match="`struct` must be a `msgspec.Struct`"): msgspec.structs.replace(1, x=2) def test_replace_no_kwargs(self, replace): p = Point(1, 2) assert replace(p) == p def test_replace_kwargs(self, replace): p = Point(1, 2) assert replace(p, x=3) == Point(3, 2) assert replace(p, y=4) == Point(1, 4) assert replace(p, x=3, y=4) == Point(3, 4) def test_replace_unknown_field(self, replace): p = Point(1, 2) with pytest.raises(TypeError, match="`Point` has no field 'oops'"): replace(p, oops=3) def test_replace_errors_unset_fields(self, replace): p = Point(1, 2) del p.x with pytest.raises(AttributeError, match="Struct field 'x' is unset"): replace(p) with pytest.raises(AttributeError, match="Struct field 'x' is unset"): replace(p, y=1) assert replace(p, x=3) == Point(3, 2) def test_replace_frozen(self, replace): class Test(msgspec.Struct, frozen=True): x: int y: int assert replace(Test(1, 2), x=3) == Test(3, 2) def test_replace_gc_delayed_tracking(self, replace): class Test(msgspec.Struct): x: int y: list[int] | None obj = Test(1, None) assert not gc.is_tracked(replace(obj)) assert not gc.is_tracked(replace(obj, x=10)) assert not gc.is_tracked(replace(obj, y=None)) assert gc.is_tracked(replace(obj, y=[1, 2, 3])) obj = Test(1, [1, 2, 3]) assert gc.is_tracked(replace(obj)) assert gc.is_tracked(replace(obj, x=1)) assert not gc.is_tracked(replace(obj, y=None)) def test_replace_gc_false(self, replace): class Test(msgspec.Struct, gc=False): x: int y: list[int] res = replace(Test(1, [1, 2]), x=3) assert res == Test(3, [1, 2]) assert not gc.is_tracked(res) def test_replace_reference_counts(self, replace): class Test(msgspec.Struct): x: Any y: int x = object() t = Test(x, 1) x_count = sys.getrefcount(x) t2 = replace(t) assert sys.getrefcount(x) == x_count + 1 del t2 t2 = replace(t, x=None) assert sys.getrefcount(x) == x_count del t2 t2 = replace(t, y=2) assert sys.getrefcount(x) == x_count + 1 del t2 x2 = object() x2_count = sys.getrefcount(x2) t2 = replace(t, x=x2) assert sys.getrefcount(x) == x_count assert sys.getrefcount(x2) == x2_count + 1 del t2 def test_replace_calls_post_init(self, replace): count = 0 class Ex(Struct): def __post_init__(self): nonlocal count count += 1 x1 = Ex() assert count == 1 x2 = replace(x1) assert x1 == x2 assert count == 2 class TestAsDictAndAsTuple: def test_asdict(self): x = Point(1, 2) assert msgspec.structs.asdict(x) == {"x": 1, "y": 2} def test_astuple(self): x = Point(1, 2) assert msgspec.structs.astuple(x) == (1, 2) @pytest.mark.parametrize("func", [msgspec.structs.asdict, msgspec.structs.astuple]) def test_errors(self, func): with pytest.raises(TypeError): func(1) x = Point(1, 2) del x.y with pytest.raises(AttributeError): func(x) class TestInspectFields: def test_fields_bad_arg(self): T = TypeVar("T") class Bad(Generic[T]): x: T for val in [1, int, Bad, Bad[int]]: with pytest.raises(TypeError, match="struct type or instance"): msgspec.structs.fields(val) def test_fields_struct_meta(self): class CustomMeta(msgspec.StructMeta): pass class Base(metaclass=CustomMeta): pass class Model(Base): pass assert msgspec.structs.fields(Model) == () def test_fields_struct_meta_instance(self): class CustomMeta(msgspec.StructMeta): pass class Base(metaclass=CustomMeta): pass class Model(Base): pass assert msgspec.structs.fields(Model()) == () def test_fields_no_fields(self): assert msgspec.structs.fields(msgspec.Struct) == () @pytest.mark.parametrize("instance", [False, True]) def test_fields(self, instance): def factory(): return 1 class Example(msgspec.Struct): x: int y: int = 0 z: int = msgspec.field(default_factory=factory) arg = Example(1, 2, 3) if instance else Example fields = msgspec.structs.fields(arg) x_field, y_field, z_field = fields assert x_field.required assert x_field.default is NODEFAULT assert x_field.default_factory is NODEFAULT assert not y_field.required assert y_field.default == 0 assert y_field.default_factory is NODEFAULT assert not z_field.required assert z_field.default is NODEFAULT assert z_field.default_factory is factory def test_fields_keyword_only(self): class Example(msgspec.Struct, kw_only=True): a: int b: int = 1 c: int d: int = 2 sol = ( msgspec.structs.FieldInfo("a", "a", int), msgspec.structs.FieldInfo("b", "b", int, default=1), msgspec.structs.FieldInfo("c", "c", int), msgspec.structs.FieldInfo("d", "d", int, default=2), ) assert msgspec.structs.fields(Example) == sol def test_fields_encode_name(self): class Example(msgspec.Struct, rename="camel"): field_one: int field_two: int sol = ( msgspec.structs.FieldInfo("field_one", "fieldOne", int), msgspec.structs.FieldInfo("field_two", "fieldTwo", int), ) assert msgspec.structs.fields(Example) == sol def test_fields_generic(self): T = TypeVar("T") class Example(msgspec.Struct, Generic[T]): x: T y: int sol = ( msgspec.structs.FieldInfo("x", "x", T), msgspec.structs.FieldInfo("y", "y", int), ) assert msgspec.structs.fields(Example) == sol assert msgspec.structs.fields(Example(1, 2)) == sol sol = ( msgspec.structs.FieldInfo("x", "x", str), msgspec.structs.FieldInfo("y", "y", int), ) assert msgspec.structs.fields(Example[str]) class TestClassVar: def case1(self): return """ from typing import ClassVar from msgspec import Struct class Ex(Struct): a: int cv1: ClassVar b: int cv2: ClassVar[int] = 1 """ def case2(self): return """ import typing from msgspec import Struct class Ex(Struct): a: int cv1: typing.ClassVar b: int cv2: typing.ClassVar[int] = 1 """ def case3(self): return """ import typing from msgspec import Struct ClassVar = typing.List class Ex(Struct): a: ClassVar b: ClassVar[int] cv2: typing.ClassVar[int] = 1 """ def case4(self): return """ from typing import ClassVar, List from msgspec import Struct class typing: ClassVar = List class Ex(Struct): a: typing.ClassVar b: typing.ClassVar[int] cv2: ClassVar[int] = 1 """ def case5(self): """Annotations that start with `ClassVar`/`typing.ClassVar` but don't end there aren't treated as false-positives""" return """ from typing import ClassVar, List from msgspec import Struct ClassVariable = List class typing: ClassVariable = List class Ex(Struct): a: typing.ClassVariable b: ClassVariable[int] cv2: ClassVar[int] = 1 """ @pytest.mark.parametrize("case", [1, 2, 3, 4, 5]) @pytest.mark.parametrize("future_annotations", [True, False]) def test_classvar(self, case, future_annotations): source = getattr(self, f"case{case}")() if future_annotations: source = "from __future__ import annotations\n" + textwrap.dedent(source) with temp_module(source) as mod: assert mod.Ex.__struct_fields__ == ("a", "b") assert not hasattr(mod.Ex, "cv1") assert mod.Ex.cv2 == 1 def test_wrong_classvar(self): # See https://github.com/msgspec/msgspec/issues/1096 source = """ from __future__ import annotations from msgspec import Struct class typing: pass class Ex(Struct): a: typing.ClassVar """ with pytest.raises( AttributeError, match="'typing' has no attribute 'ClassVar'", ): temp_module(source).__enter__() # It used to crash, but must not! class TestPostInit: def test_post_init(self): called = False singleton = object() class Ex(Struct): x: int def __post_init__(self): nonlocal called called = True return singleton Ex(1) assert called # Return value is decref'd assert sys.getrefcount(singleton) <= 2 # 1 for ref, 1 for call def test_post_init_errors(self): class Ex(Struct): x: int def __post_init__(self): raise ValueError("Oh no!") with pytest.raises(ValueError, match="Oh no!"): Ex(1) def test_post_init_invalid(self): class Bad1(Struct): __post_init__ = 1 class Bad2(Struct): def __post_init__(self, other): pass with pytest.raises(TypeError): Bad1() with pytest.raises(TypeError): Bad2() def test_post_init_inheritance(self): called = False class Base: def __post_init__(self): nonlocal called called = True class Ex(Struct, Base): x: int Ex(1) assert called def test_post_init_not_called_on_copy(self): count = 0 class Ex(Struct): def __post_init__(self): nonlocal count count += 1 x1 = Ex() assert count == 1 x2 = x1.__copy__() assert x1 == x2 assert count == 1 class TestForwardReferences: """Quoted forward refs work on all supported Pythons. Unquoted forward refs are only valid under PEP 649 deferred annotations (3.14+). """ def test_quoted_forward_reference_struct_fields(self): source = """ import msgspec class Outer(msgspec.Struct): inner: "Inner" class Inner(msgspec.Struct): value: int """ with temp_module(source) as mod: assert mod.Outer.__struct_fields__ == ("inner",) msg = mod.Outer(mod.Inner(1)) assert msgspec.json.decode(msgspec.json.encode(msg), type=mod.Outer) == msg def test_future_annotations_forward_reference_struct_fields(self): source = """ from __future__ import annotations import msgspec class Outer(msgspec.Struct): inner: Inner class Inner(msgspec.Struct): value: int """ with temp_module(source) as mod: assert mod.Outer.__struct_fields__ == ("inner",) msg = mod.Outer(mod.Inner(1)) assert msgspec.json.decode(msgspec.json.encode(msg), type=mod.Outer) == msg @pytest.mark.skipif( sys.version_info < (3, 14), reason="unquoted forward references require PEP 649 (Python 3.14+)", ) def test_unquoted_forward_reference_struct_fields(self): source = """ import msgspec class Outer(msgspec.Struct): inner: Inner class Inner(msgspec.Struct): value: int """ with temp_module(source) as mod: assert mod.Outer.__struct_fields__ == ("inner",) assert mod.Outer.__annotations__["inner"] is mod.Inner msg = mod.Outer(mod.Inner(1)) assert msgspec.json.decode(msgspec.json.encode(msg), type=mod.Outer) == msg @pytest.mark.skipif( sys.version_info < (3, 14), reason="unquoted forward references require PEP 649 (Python 3.14+)", ) def test_unquoted_forward_reference_generic_container(self): source = """ import msgspec class Outer(msgspec.Struct): items: list[Inner] class Inner(msgspec.Struct): value: int """ with temp_module(source) as mod: assert mod.Outer.__struct_fields__ == ("items",) msg = mod.Outer([mod.Inner(1), mod.Inner(2)]) assert msgspec.json.decode(msgspec.json.encode(msg), type=mod.Outer) == msg @pytest.mark.skipif( sys.version_info < (3, 14), reason="unquoted forward references require PEP 649 (Python 3.14+)", ) def test_unquoted_mutual_forward_references(self): source = """ import msgspec class Node(msgspec.Struct): value: int child: Node | None = None """ with temp_module(source) as mod: assert mod.Node.__struct_fields__ == ("value", "child") msg = mod.Node(1, mod.Node(2)) assert msgspec.json.decode(msgspec.json.encode(msg), type=mod.Node) == msg python-msgspec-0.22.0/tests/unit/test_struct_meta.py000066400000000000000000000455641525673062400226670ustar00rootroot00000000000000"""Tests for the exposed StructMeta metaclass.""" import gc import re import secrets from abc import ABCMeta, _abc_init, abstractmethod import pytest import msgspec from msgspec import Struct, StructMeta from msgspec.structs import asdict, astuple, force_setattr, replace def test_struct_meta_exists(): """Test that StructMeta is properly exposed.""" assert hasattr(msgspec, "StructMeta") assert isinstance(Struct, StructMeta) assert issubclass(StructMeta, type) def test_struct_meta_direct_usage(): """Test that StructMeta can be used directly as a metaclass.""" class CustomStruct(metaclass=StructMeta): x: int y: str # Verify the struct works as expected instance = CustomStruct(x=1, y="test") assert instance.x == 1 assert instance.y == "test" assert isinstance(instance, CustomStruct) assert isinstance(CustomStruct, StructMeta) def test_struct_meta_options(): """Test that StructMeta properly handles struct options.""" class CustomStruct(metaclass=StructMeta, frozen=True): x: int # Verify options were applied instance = CustomStruct(x=1) with pytest.raises(AttributeError): instance.x = 2 # Should be frozen def test_struct_meta_field_processing(): """Test that StructMeta properly processes fields.""" class CustomStruct(metaclass=StructMeta): x: int y: str = "default" # Verify struct functionality instance = CustomStruct(x=1) assert instance.x == 1 assert instance.y == "default" # Check struct metadata assert hasattr(CustomStruct, "__struct_fields__") assert "x" in CustomStruct.__struct_fields__ assert "y" in CustomStruct.__struct_fields__ def test_struct_meta_with_struct_base(): """Test using StructMeta with Struct as a base class.""" class CustomStruct(Struct): x: int y: str # Verify the struct works as expected instance = CustomStruct(x=1, y="test") assert instance.x == 1 assert instance.y == "test" assert isinstance(instance, CustomStruct) assert isinstance(CustomStruct, StructMeta) def test_struct_meta_validation(): """Test that StructMeta validation works.""" # Should raise TypeError for invalid field name with pytest.raises(TypeError): class InvalidStruct(metaclass=StructMeta): __dict__: int # __dict__ is a reserved name def test_struct_meta_with_options(): """Test StructMeta with various options.""" class Point(metaclass=StructMeta, frozen=True, eq=True, order=True): x: int y: int p1 = Point(x=1, y=2) p2 = Point(x=1, y=3) # Test frozen with pytest.raises(AttributeError): p1.x = 10 # Test eq - note that we need to compare fields manually # since equality is based on identity by default assert p1.x == Point(x=1, y=2).x and p1.y == Point(x=1, y=2).y assert p1.x == p2.x and p1.y != p2.y # Test order - we can't directly compare instances # but we can compare their field values assert (p1.x, p1.y) < (p2.x, p2.y) def test_struct_meta_inheritance(): """Test that StructMeta can be inherited in Python code.""" class CustomMeta(StructMeta): """A custom metaclass that inherits from StructMeta. This metaclass adds a kw_only_default parameter that can be used to set the default kw_only value for all subclasses. When a class is created with this metaclass: 1. If kw_only is explicitly specified, use that value 2. If kw_only is not specified but kw_only_default is, use kw_only_default 3. If neither is specified but a parent class has kw_only_default defined, use the parent's kw_only_default 4. Otherwise, default to False """ # Class attribute to store kw_only_default settings for each class _kw_only_default_settings = {} def __new__(mcls, name, bases, namespace, **kwargs): # Check if kw_only is explicitly specified kw_only_specified = "kw_only" in kwargs # Process kw_only_default parameter kw_only_default = kwargs.pop("kw_only_default", None) # If kw_only_default is specified, store it if kw_only_default is not None: # Remember this setting for future subclasses mcls._kw_only_default_settings[name] = kw_only_default else: # Check if any parent class has kw_only_default defined for base in bases: base_name = base.__name__ if base_name in mcls._kw_only_default_settings: # Use parent's kw_only_default kw_only_default = mcls._kw_only_default_settings[base_name] break # If kw_only is not specified but kw_only_default is available, use it if not kw_only_specified and kw_only_default is not None: kwargs["kw_only"] = kw_only_default # Create the class return super().__new__(mcls, name, bases, namespace, **kwargs) # Test basic functionality - without kw_only_default class SimpleModel(metaclass=CustomMeta): x: int y: str # Verify the class was created correctly assert isinstance(SimpleModel, CustomMeta) assert issubclass(CustomMeta, StructMeta) # Test creating an instance with positional arguments (should work) instance = SimpleModel(1, "test") assert instance.x == 1 assert instance.y == "test" # Test setting kw_only_default=True class KwOnlyBase(metaclass=CustomMeta, kw_only_default=True): """Base class that sets kw_only_default=True""" # Test a simple child class, should inherit kw_only_default class SimpleChild(KwOnlyBase): x: int # Should only allow keyword arguments with pytest.raises(TypeError): SimpleChild(1) class BadFieldOrder(KwOnlyBase): x: int = 0 y: int BadFieldOrder(y=10) # Create instance with keyword arguments child = SimpleChild(x=1) assert child.x == 1 # Test overriding inherited kw_only_default class NonKwOnlyChild(KwOnlyBase, kw_only=False): x: int # Should allow positional arguments non_kw_child = NonKwOnlyChild(1) assert non_kw_child.x == 1 # Test independent class, not inheriting kw_only_default class IndependentModel(metaclass=CustomMeta): x: int y: str # Should allow positional arguments independent = IndependentModel(1, "test") assert independent.x == 1 assert independent.y == "test" # Print debug information print( f"KwOnlyBase in _kw_only_default_settings: {'KwOnlyBase' in CustomMeta._kw_only_default_settings}" ) print( f"KwOnlyBase default: {CustomMeta._kw_only_default_settings.get('KwOnlyBase')}" ) print( f"SimpleChild in _kw_only_default_settings: {'SimpleChild' in CustomMeta._kw_only_default_settings}" ) # Test that kw_only_default values are correctly passed assert "KwOnlyBase" in CustomMeta._kw_only_default_settings assert CustomMeta._kw_only_default_settings["KwOnlyBase"] is True # Test asdict d = asdict(independent) assert d["x"] == 1 assert d["y"] == "test" def test_struct_meta_subclass_functions(): """Test if structs created by StructMeta subclasses support various function operations.""" # Define a custom metaclass class CustomMeta(StructMeta): """Custom metaclass that inherits from StructMeta""" # Use the custom metaclass to create a struct class class CustomStruct(metaclass=CustomMeta): x: int y: str z: float = 3.14 # Create an instance obj = CustomStruct(x=1, y="test") assert obj.x == 1 assert obj.y == "test" assert obj.z == 3.14 # Test asdict function d = asdict(obj) assert isinstance(d, dict) assert d["x"] == 1 assert d["y"] == "test" assert d["z"] == 3.14 # Test astuple function t = astuple(obj) assert isinstance(t, tuple) assert t == (1, "test", 3.14) # Test replace function obj2 = replace(obj, y="replaced") assert obj2.x == 1 assert obj2.y == "replaced" assert obj2.z == 3.14 # Test force_setattr function force_setattr(obj, "x", 100) assert obj.x == 100 # Test nested structs class NestedStruct(metaclass=CustomMeta): inner: CustomStruct name: str nested = NestedStruct(inner=obj, name="nested") assert nested.inner.x == 100 assert nested.inner.y == "test" assert nested.name == "nested" # Test asdict with nested structs nested_dict = asdict(nested) assert isinstance(nested_dict, dict) # Note: asdict doesn't recursively convert nested struct objects, so inner remains a CustomStruct object assert isinstance(nested_dict["inner"], CustomStruct) assert nested_dict["inner"].x == 100 assert nested_dict["inner"].y == "test" assert nested_dict["name"] == "nested" def test_struct_meta_subclass_inheritance(): """Test multi-level inheritance of StructMeta subclasses.""" # Define the first level custom metaclass class BaseMeta(StructMeta): """Base custom metaclass""" # Define the second level custom metaclass class DerivedMeta(BaseMeta): """Derived custom metaclass""" # Use the second level custom metaclass to create a struct class class DerivedStruct(metaclass=DerivedMeta): a: int b: str # Create an instance obj = DerivedStruct(a=42, b="derived") assert obj.a == 42 assert obj.b == "derived" # Test various functions # asdict d = asdict(obj) assert d["a"] == 42 assert d["b"] == "derived" # astuple t = astuple(obj) assert t == (42, "derived") # replace obj2 = replace(obj, a=99) assert obj2.a == 99 assert obj2.b == "derived" def test_struct_meta_subclass_with_encoder(): """Test compatibility of structs created by StructMeta subclasses with encoders.""" # Define a custom metaclass class EncoderMeta(StructMeta): """Custom metaclass for testing encoders""" # Use the custom metaclass to create a struct class class EncoderStruct(metaclass=EncoderMeta): id: int name: str tags: list[str] = [] # Create an instance obj = EncoderStruct(id=123, name="test") # Test JSON encoding and decoding json_bytes = msgspec.json.encode(obj) decoded = msgspec.json.decode(json_bytes, type=EncoderStruct) assert decoded.id == 123 assert decoded.name == "test" assert decoded.tags == [] # Test encoding and decoding with nested structs class Container(metaclass=EncoderMeta): item: EncoderStruct count: int container = Container(item=obj, count=1) json_bytes = msgspec.json.encode(container) decoded = msgspec.json.decode(json_bytes, type=Container) assert decoded.count == 1 assert decoded.item.id == 123 assert decoded.item.name == "test" def test_structmeta_abcmeta_mixed_behaves_like_abc(): class IntegerStructMeta(StructMeta, ABCMeta): pass class IntegerStructBase(Struct, metaclass=IntegerStructMeta): @abstractmethod def to_integer(self) -> int: ... @classmethod @abstractmethod def from_integer(cls, val: int) -> "IntegerStructBase": ... class ConcreteIntStruct(IntegerStructBase): val: int def to_integer(self) -> int: return self.val << 2 @classmethod def from_integer(cls, val: int) -> "ConcreteIntStruct": return cls(val) # Abstract base cannot be instantiated when there are abstract methods with pytest.raises( TypeError, match=( r"^Can't instantiate abstract class IntegerStructBase without an " r"implementation for abstract methods 'from_integer', 'to_integer'$" ), ): IntegerStructBase() # Concrete subclass is fine when all abstract methods are implemented obj = ConcreteIntStruct(1) assert obj.to_integer() == 4 # ABC semantics: issubclass / isinstance must work and not raise assert issubclass(ConcreteIntStruct, IntegerStructBase) assert isinstance(obj, IntegerStructBase) # msgspec roundtrip still works encoded = msgspec.json.encode(obj) decoded = msgspec.json.decode(encoded, type=ConcreteIntStruct) assert decoded == obj # Repeated checks must continue working (no latent _abc_impl issues) for _ in range(5): assert issubclass(ConcreteIntStruct, IntegerStructBase) assert isinstance(obj, IntegerStructBase) def test_structmeta_abcmeta_intermediate_still_abstract_and_message(): class IntegerStructMeta(StructMeta, ABCMeta): pass class IntegerStructBase(Struct, metaclass=IntegerStructMeta): @abstractmethod def to_integer(self) -> int: ... @classmethod @abstractmethod def from_integer(cls, val: int) -> "IntegerStructBase": ... class Intermediate(IntegerStructBase): # Implement only one of the abstract methods @classmethod def from_integer(cls, val: int) -> "Intermediate": return cls() # Intermediate remains abstract: only to_integer is missing with pytest.raises( TypeError, match=( r"^Can't instantiate abstract class Intermediate without an " r"implementation for abstract method 'to_integer'$" ), ): Intermediate() def test_structmeta_abcmeta_single_abstract_method_message(): class IntegerStructMeta(StructMeta, ABCMeta): pass class SingleAbstract(Struct, metaclass=IntegerStructMeta): @abstractmethod def only(self) -> int: ... with pytest.raises( TypeError, match=( r"^Can't instantiate abstract class SingleAbstract without an " r"implementation for abstract method 'only'$" ), ): SingleAbstract() def test_structmeta_abcmeta_mixed_reverse_order(): class IntegerStructMeta(ABCMeta, StructMeta): pass class IntegerStructBase(Struct, metaclass=IntegerStructMeta): @abstractmethod def to_integer(self) -> int: ... @classmethod @abstractmethod def from_integer(cls, val: int) -> "IntegerStructBase": ... class ConcreteIntStruct(IntegerStructBase): val: int def to_integer(self) -> int: return self.val + 1 @classmethod def from_integer(cls, val: int) -> "ConcreteIntStruct": return cls(val) obj = ConcreteIntStruct(10) assert issubclass(ConcreteIntStruct, IntegerStructBase) assert isinstance(obj, IntegerStructBase) encoded = msgspec.json.encode(obj) decoded = msgspec.json.decode(encoded, type=ConcreteIntStruct) assert decoded == obj def test_structmeta_abcmeta_mixed_supports_register(): class IntegerStructMeta(StructMeta, ABCMeta): pass class IntegerStructBase(Struct, metaclass=IntegerStructMeta): @abstractmethod def to_integer(self) -> int: ... @classmethod @abstractmethod def from_integer(cls, val: int) -> "IntegerStructBase": ... class OtherStruct(Struct): val: int # Register a non-subclass as a virtual subclass IntegerStructBase.register(OtherStruct) other = OtherStruct(5) # Virtual subclassing should work assert issubclass(OtherStruct, IntegerStructBase) assert isinstance(other, IntegerStructBase) # msgspec usage should still be fine encoded = msgspec.json.encode(other) decoded = msgspec.json.decode(encoded, type=OtherStruct) assert decoded == other def test_plain_struct_not_treated_as_abc(): class Plain(Struct): x: int obj = Plain(1) # Normal msgspec behaviour works encoded = msgspec.json.encode(obj) decoded = msgspec.json.decode(encoded, type=Plain) assert decoded == obj # Sanity: Plain should not suddenly be an ABC # (we don't rely on _abc_impl directly, but this is a cheap guard) assert not any( base.__module__ == "abc" and base.__name__ == "ABC" for base in Plain.__mro__ ) def test_structmeta_abcmeta_mixed_nested_subclass(): class IntegerStructMeta(StructMeta, ABCMeta): pass class IntegerStructBase(Struct, metaclass=IntegerStructMeta): @abstractmethod def to_integer(self) -> int: ... @classmethod @abstractmethod def from_integer(cls, val: int) -> "IntegerStructBase": ... class Intermediate(IntegerStructBase): @classmethod def from_integer(cls, val: int) -> "Intermediate": return cls() class Concrete(Intermediate): val: int def to_integer(self) -> int: return self.val @classmethod def from_integer(cls, val: int) -> "Concrete": return cls(val) obj = Concrete(7) assert issubclass(Concrete, IntegerStructBase) assert isinstance(obj, IntegerStructBase) assert isinstance(obj, Intermediate) def test_structmeta_abcmeta_with_no_abstract_methods_is_concrete(): class IntegerStructMeta(StructMeta, ABCMeta): pass class ConcreteBase(Struct, metaclass=IntegerStructMeta): # no @abstractmethod def foo(self) -> int: return 1 # Should be instantiable (no TypeError) obj = ConcreteBase() assert obj.foo() == 1 # And should not be considered abstract assert getattr(ConcreteBase, "__abstractmethods__", frozenset()) in ( frozenset(), set(), ) def test_struct_abc_via_init_subclass_and__abc_init(): class ABCStruct(Struct): def __init_subclass__(cls, **kwargs): super().__init_subclass__(**kwargs) _abc_init(cls) class Base(ABCStruct): @abstractmethod def foo(self) -> int: ... # Base is abstract; instantiation should fail with pytest.raises( TypeError, match=r"Can't instantiate abstract class Base without an implementation for abstract method 'foo'", ): Base() class Concrete(Base): x: int def foo(self) -> int: return self.x c = Concrete(5) assert c.foo() == 5 def test_struct_meta_pattern_ref_leak(): # ensure that we're not keeping around references to re.Pattern longer than necessary # see https://github.com/msgspec/msgspec/pull/899 for details # clear cache to get a baseline re.purge() # use a random string to create a pattern, to ensure there can never be an overlap # with any cached pattern pattern_string = secrets.token_hex() msgspec.Meta(pattern=pattern_string) # purge cache and gc again re.purge() gc.collect() # there shouldn't be an re.Pattern with our pattern any more. if there is, it's # being kept alive by some reference assert not any( o for o in gc.get_objects() if isinstance(o, re.Pattern) and o.pattern == pattern_string ) python-msgspec-0.22.0/tests/unit/test_to_builtins.py000066400000000000000000000600511525673062400226540ustar00rootroot00000000000000import base64 import datetime import decimal import enum import os import sys import uuid import weakref from dataclasses import dataclass, make_dataclass from typing import Any, NamedTuple import pytest from msgspec import UNSET, Struct, UnsetType, defstruct, to_builtins from .utils import emscripten_stack_limited, py315_or_later_only if sys.version_info >= (3, 15): # This is needed for `ruff` to recognize `frozendict` name # and to not raise `F821`: from builtins import frozendict PY311 = sys.version_info[:2] >= (3, 11) py311_plus = pytest.mark.skipif(not PY311, reason="3.11+ only") slots_params = [False, True] class FruitInt(enum.IntEnum): APPLE = -1 BANANA = 2 def __eq__(self, other): assert type(other) is type(self) return super().__eq__(other) def __hash__(self): return super().__hash__() class FruitStr(enum.Enum): APPLE = "apple" BANANA = "banana" def __eq__(self, other): assert type(other) is type(self) return super().__eq__(other) def __hash__(self): return super().__hash__() class Bad: """A type that msgspec doesn't natively handle""" class TestToBuiltins: def test_to_builtins_bad_calls(self): with pytest.raises(TypeError): to_builtins() with pytest.raises( TypeError, match="builtin_types must be an iterable of types" ): to_builtins([1], builtin_types=1) with pytest.raises( TypeError, match="builtin_types must be an iterable of types" ): to_builtins([1], builtin_types=(1,)) with pytest.raises(TypeError, match="enc_hook must be callable"): to_builtins([1], enc_hook=1) def test_to_builtins_builtin_types_explicit_none(self): assert to_builtins(1, builtin_types=None) == 1 def test_to_builtins_enc_hook_explicit_none(self): assert to_builtins(1, enc_hook=None) == 1 @pytest.mark.parametrize("case", [1, 2, 3, 4, 5]) @emscripten_stack_limited def test_to_builtins_recursive(self, case): if case == 1: o = [] o.append(o) elif case == 2: o = ([],) o[0].append(o) elif case == 3: o = {} o["a"] = o elif case == 4: class Box(Struct): a: "Box" o = Box(None) o.a = o elif case == 5: @dataclass class Box: a: "Box" o = Box(None) o.a = o with pytest.raises(RecursionError): to_builtins(o) def test_none(self): assert to_builtins(None) is None def test_bool(self): assert to_builtins(False) is False assert to_builtins(True) is True def test_int(self): assert to_builtins(1) == 1 def test_float(self): assert to_builtins(1.5) == 1.5 def test_str(self): assert to_builtins("abc") == "abc" @pytest.mark.parametrize("typ", [bytes, bytearray, memoryview]) @pytest.mark.parametrize("size", range(5)) def test_binary(self, typ, size): msg = typ(os.urandom(size)) res = to_builtins(msg) sol = base64.b64encode(msg).decode("utf-8") assert res == sol @pytest.mark.parametrize("typ", [bytes, bytearray, memoryview]) def test_binary_builtin_types(self, typ): msg = typ(b"\x01\x02\x03") res = to_builtins(msg, builtin_types=(typ,)) assert res is msg @pytest.mark.parametrize("tzinfo", [None, datetime.timezone.utc]) @pytest.mark.parametrize("microsecond", [123456, 123, 0]) def test_datetime(self, tzinfo, microsecond): msg = datetime.datetime.now(tzinfo).replace(microsecond=microsecond) res = to_builtins(msg) sol = msg.isoformat().replace("+00:00", "Z") assert res == sol def test_datetime_builtin_types(self): msg = datetime.datetime.now() res = to_builtins(msg, builtin_types=(datetime.datetime,)) assert res is msg def test_date(self): msg = datetime.date.today() res = to_builtins(msg) sol = msg.isoformat() assert res == sol def test_date_builtin_types(self): msg = datetime.date.today() res = to_builtins(msg, builtin_types=(datetime.date,)) assert res is msg @pytest.mark.parametrize("tzinfo", [None, datetime.timezone.utc]) @pytest.mark.parametrize("microsecond", [123456, 123, 0]) def test_time(self, tzinfo, microsecond): msg = datetime.datetime.now(tzinfo).replace(microsecond=microsecond).timetz() res = to_builtins(msg) sol = msg.isoformat().replace("+00:00", "Z") assert res == sol def test_time_builtin_types(self): msg = datetime.datetime.now().time() res = to_builtins(msg, builtin_types=(datetime.time,)) assert res is msg def test_timedelta(self): msg = datetime.timedelta(1, 2, 300) res = to_builtins(msg) assert res == "P1DT2.0003S" def test_timedelta_builtin_types(self): msg = datetime.timedelta(1, 2, 300) res = to_builtins(msg, builtin_types=(datetime.timedelta,)) assert res is msg def test_uuid(self): msg = uuid.uuid4() assert to_builtins(msg) == str(msg) def test_uuid_subclass(self): class Ex(uuid.UUID): pass s = "4184defa-4d1a-4497-a140-fd1ec0b22383" assert to_builtins(Ex(s)) == s def test_uuid_builtin_types(self): msg = uuid.uuid4() res = to_builtins(msg, builtin_types=(uuid.UUID,)) assert res is msg def test_decimal(self): msg = decimal.Decimal("1.5") assert to_builtins(msg) == str(msg) def test_decimal_builtin_types(self): msg = decimal.Decimal("1.5") res = to_builtins(msg, builtin_types=(decimal.Decimal,)) assert res is msg def test_intenum(self): res = to_builtins(FruitInt.APPLE) assert res == -1 assert type(res) is int def test_enum(self): res = to_builtins(FruitStr.APPLE) assert res == "apple" assert type(res) is str def test_enum_complex(self): class Complex(enum.Enum): x = (1, 2) res = to_builtins(Complex.x) assert res is Complex.x.value @pytest.mark.parametrize( "in_type, out_type", [(list, list), (tuple, tuple), (set, list), (frozenset, list)], ) @pytest.mark.parametrize("subclass", [False, True]) def test_sequence(self, in_type, out_type, subclass): if subclass: class in_type(in_type): pass msg = in_type([1, FruitInt.APPLE]) res = to_builtins(msg) assert res == out_type([1, -1]) assert res is not msg res = to_builtins(in_type()) assert res == out_type() @pytest.mark.parametrize("in_type", [list, tuple, set, frozenset]) def test_sequence_unsupported_item(self, in_type): msg = in_type([1, Bad(), 3]) with pytest.raises(TypeError, match="Encoding objects of type Bad"): to_builtins(msg) def test_namedtuple(self): class Point(NamedTuple): x: int y: FruitInt assert to_builtins(Point(1, FruitInt.APPLE)) == (1, -1) @pytest.mark.parametrize("subclass", [False, True]) def test_dict(self, subclass): if subclass: class in_type(dict): pass else: in_type = dict msg = in_type({FruitStr.BANANA: 1, "b": [FruitInt.APPLE], 3: "three"}) sol = {"banana": 1, "b": [-1], 3: "three"} res = to_builtins(msg) assert res == sol assert res is not msg res = to_builtins(in_type()) assert res == {} def test_dict_str_subclass_key(self): class mystr(str): pass msg = to_builtins({mystr("test"): 1}) assert msg == {"test": 1} assert type(list(msg.keys())[0]) is str def test_dict_unsupported_key(self): msg = {Bad(): 1} with pytest.raises(TypeError, match="Encoding objects of type Bad"): to_builtins(msg) def test_dict_unsupported_value(self): msg = {"x": Bad()} with pytest.raises(TypeError, match="Encoding objects of type Bad"): to_builtins(msg) def test_dict_str_keys(self): assert to_builtins({FruitStr.BANANA: 1}, str_keys=True) == {"banana": 1} assert to_builtins({"banana": 1}, str_keys=True) == {"banana": 1} assert to_builtins({FruitInt.BANANA: 1}, str_keys=True) == {"2": 1} assert to_builtins({2: 1}, str_keys=True) == {"2": 1} def test_dict_sequence_keys(self): msg = {frozenset([1, 2]): 1} assert to_builtins(msg) == {(1, 2): 1} with pytest.raises( TypeError, match="Only dicts with str-like or number-like keys are supported", ): to_builtins(msg, str_keys=True) def check_non_frozen(self, val, expected): assert type(val) is dict assert type(expected) is dict assert val == expected def check_frozen(self, val, expected): assert type(val) is frozendict assert type(expected) is frozendict assert val == expected @py315_or_later_only @pytest.mark.parametrize("subclass", [False, True]) def test_frozendict(self, subclass): if subclass: class in_type(frozendict): pass else: in_type = frozendict raw = {FruitStr.BANANA: 1, "b": [FruitInt.APPLE], 3: "three"} msg = in_type(raw) res = to_builtins(msg) self.check_non_frozen(res, {"banana": 1, "b": [-1], 3: "three"}) assert res is not msg self.check_frozen( to_builtins(msg, builtin_types=[frozendict]), frozendict({"banana": 1, "b": [-1], 3: "three"}), ) self.check_non_frozen( to_builtins(raw, builtin_types=[frozendict]), {"banana": 1, "b": [-1], 3: "three"}, ) self.check_non_frozen(to_builtins(in_type()), {}) self.check_frozen( to_builtins(in_type(), builtin_types=[frozendict]), frozendict(), ) @py315_or_later_only def test_frozendict_builtin_types(self): msg = to_builtins(frozendict({"test": 1}), builtin_types=(frozendict,)) assert type(msg) is frozendict assert msg == frozendict({"test": 1}) msg = to_builtins( frozendict( { "test": frozendict({1: "a"}), FruitStr.BANANA: 1, "b": [FruitInt.APPLE], } ), builtin_types=(frozendict,), ) assert type(msg) is frozendict assert type(msg["test"]) is frozendict assert type(list(msg.keys())[1]) is str assert msg == frozendict( { "test": frozendict({1: "a"}), "banana": 1, "b": [-1], } ) @py315_or_later_only def test_frozendict_str_subclass_key(self): class mystr(str): pass msg = to_builtins(frozendict({mystr("test"): 1})) self.check_non_frozen(msg, {"test": 1}) assert type(list(msg.keys())[0]) is str @py315_or_later_only def test_frozendict_unsupported_key(self): msg = frozendict({Bad(): 1}) with pytest.raises(TypeError, match="Encoding objects of type Bad"): to_builtins(msg) @py315_or_later_only def test_frozendict_unsupported_value(self): msg = frozendict({"x": Bad()}) with pytest.raises(TypeError, match="Encoding objects of type Bad"): to_builtins(msg) @py315_or_later_only def test_frozendict_str_keys(self): self.check_non_frozen( to_builtins(frozendict({FruitStr.BANANA: 1}), str_keys=True), {"banana": 1}, ) self.check_non_frozen( to_builtins(frozendict({"banana": 1}), str_keys=True), {"banana": 1}, ) self.check_non_frozen( to_builtins(frozendict({FruitInt.BANANA: 1}), str_keys=True), {"2": 1}, ) self.check_non_frozen( to_builtins(frozendict({2: 1}), str_keys=True), {"2": 1}, ) @py315_or_later_only def test_frozendict_sequence_keys(self): msg = frozendict({frozenset([1, 2]): 1}) self.check_non_frozen(to_builtins(msg), {(1, 2): 1}) with pytest.raises( TypeError, match="Only dicts with str-like or number-like keys are supported", ): to_builtins(msg, str_keys=True) @pytest.mark.parametrize("tagged", [False, True]) def test_struct_object(self, tagged): class Ex(Struct, tag=tagged): x: int y: FruitInt sol = {"type": "Ex", "x": 1, "y": -1} if tagged else {"x": 1, "y": -1} assert to_builtins(Ex(1, FruitInt.APPLE)) == sol def test_struct_object_omit_defaults(self): class Ex(Struct, omit_defaults=True): x: int a: list = [] b: FruitStr = FruitStr.BANANA c: FruitInt = FruitInt.APPLE assert to_builtins(Ex(1)) == {"x": 1} assert to_builtins(Ex(1, a=[2])) == {"x": 1, "a": [2]} assert to_builtins(Ex(1, b=FruitStr.APPLE)) == {"x": 1, "b": "apple"} @pytest.mark.parametrize("tagged", [False, True]) def test_struct_array(self, tagged): class Ex(Struct, array_like=True, tag=tagged): x: int y: FruitInt sol = ["Ex", 1, -1] if tagged else [1, -1] assert to_builtins(Ex(1, FruitInt.APPLE)) == sol @pytest.mark.parametrize("tagged", [False, True]) def test_struct_array_keys(self, tagged): class Ex(Struct, array_like=True, tag=tagged, frozen=True): x: int y: FruitInt msg = {Ex(1, FruitInt.APPLE): "abc"} sol = {("Ex", 1, -1) if tagged else (1, -1): "abc"} assert to_builtins(msg) == sol @pytest.mark.parametrize("tagged", [False, True]) @pytest.mark.parametrize("is_key", [False, True]) @pytest.mark.parametrize("error", [False, True]) def test_struct_array_field_refcounts(self, tagged, is_key, error): class Ex(Struct, array_like=True, tag=tagged, frozen=True): x: Any y: Any value = float("1.5") obj = Ex((value,), Bad() if error else value) msg = {obj: None} if is_key else obj count = sys.getrefcount(value) if error: with pytest.raises(TypeError, match="Encoding objects of type Bad"): to_builtins(msg) else: to_builtins(msg) assert sys.getrefcount(value) == count @pytest.mark.parametrize("array_like", [False, True]) def test_struct_unsupported_value(self, array_like): class Ex(Struct): a: Any b: Any msg = Ex(1, Bad()) with pytest.raises(TypeError, match="Encoding objects of type Bad"): to_builtins(msg) @pytest.mark.parametrize("slots", slots_params) def test_dataclass(self, slots): @dataclass(**({"slots": True} if slots else {})) class Ex: x: int y: FruitInt msg = Ex(1, FruitInt.APPLE) assert to_builtins(msg) == {"x": 1, "y": -1} @pytest.mark.parametrize("slots", slots_params) def test_dataclass_missing_fields(self, slots): @dataclass(**({"slots": True} if slots else {})) class Ex: x: int y: int z: int x = Ex(1, 2, 3) sol = {"x": 1, "y": 2, "z": 3} for key in "xyz": delattr(x, key) del sol[key] assert to_builtins(x) == sol @pytest.mark.parametrize("slots_base", slots_params) @pytest.mark.parametrize("slots", slots_params) def test_dataclass_subclasses(self, slots_base, slots): @dataclass(**({"slots": True} if slots_base else {})) class Base: x: int y: int @dataclass(**({"slots": True} if slots else {})) class Ex(Base): y: int z: int x = Ex(1, 2, 3) res = to_builtins(x) assert res == {"x": 1, "y": 2, "z": 3} # Missing attribute ignored del x.y res = to_builtins(x) assert res == {"x": 1, "z": 3} @py311_plus def test_dataclass_weakref_slot(self): @dataclass(slots=True, weakref_slot=True) class Ex: x: int y: int x = Ex(1, 2) ref = weakref.ref(x) # noqa res = to_builtins(x) assert res == {"x": 1, "y": 2} @pytest.mark.parametrize("slots", slots_params) def test_dataclass_unsupported_value(self, slots): @dataclass(**({"slots": True} if slots else {})) class Ex: x: Any y: Any msg = Ex(1, Bad()) with pytest.raises(TypeError, match="Encoding objects of type Bad"): to_builtins(msg) def test_dataclass_class_errors(self): @dataclass class Ex: x: int with pytest.raises(TypeError, match="Encoding objects of type type"): to_builtins(Ex) @pytest.mark.parametrize("slots", [True, False]) def test_attrs(self, slots): attrs = pytest.importorskip("attrs") @attrs.define(slots=slots) class Ex: x: int y: FruitInt msg = Ex(1, FruitInt.APPLE) assert to_builtins(msg) == {"x": 1, "y": -1} @pytest.mark.parametrize("slots", [True, False]) def test_attrs_skip_leading_underscore(self, slots): attrs = pytest.importorskip("attrs") @attrs.define(slots=slots) class Ex: x: int y: int _z: int x = Ex(1, 2, 3) res = to_builtins(x) assert res == {"x": 1, "y": 2} @pytest.mark.parametrize("kind", ["struct", "dataclass", "attrs"]) def test_unset_fields(self, kind): if kind == "struct": class Ex(Struct): x: int | UnsetType y: int | UnsetType elif kind == "dataclass": @dataclass class Ex: x: int | UnsetType y: int | UnsetType elif kind == "attrs": attrs = pytest.importorskip("attrs") @attrs.define class Ex: x: int | UnsetType y: int | UnsetType res = to_builtins(Ex(1, UNSET)) assert res == {"x": 1} res = to_builtins(Ex(UNSET, 2)) assert res == {"y": 2} res = to_builtins(Ex(UNSET, UNSET)) assert res == {} def test_unset_errors_in_other_contexts(self): with pytest.raises(TypeError): to_builtins(UNSET) def test_custom(self): with pytest.raises(TypeError, match="Encoding objects of type Bad"): to_builtins(Bad()) assert to_builtins(Bad(), enc_hook=lambda x: "bad") == "bad" @pytest.mark.parametrize("col_type", [tuple, list, set]) def test_custom_builtin_types(self, col_type): class C1: pass class C2: pass builtins = col_type([C1, bytes, C2]) count = sys.getrefcount(builtins) for msg in [C1(), C2(), b"test"]: assert to_builtins(msg, builtin_types=builtins) is msg with pytest.raises(TypeError, match="Encoding objects of type Bad"): to_builtins(Bad(), builtin_types=builtins) assert sys.getrefcount(builtins) == count class TestOrder: def test_order_invalid(self): with pytest.raises(ValueError, match="`order` must be one of"): to_builtins(1, order="bad") @staticmethod def assert_eq(left, right, typ=dict): assert left == right if isinstance(left, typ): assert list(left) == list(right) @pytest.mark.parametrize("msg", [{}, {"y": 1, "x": 2, "z": 3}]) @pytest.mark.parametrize("order", [None, "deterministic", "sorted"]) def test_order_dict(self, msg, order): res = to_builtins(msg, order=order) sol = dict(sorted(msg.items())) if order else msg self.assert_eq(res, sol) def test_order_dict_non_str_errors(self): with pytest.raises(TypeError): to_builtins({"b": 2, 1: "a"}, order="deterministic") def test_order_dict_unsortable(self): with pytest.raises(TypeError): to_builtins({"x": 1, 1: 2}, order="deterministic") @py315_or_later_only @pytest.mark.parametrize("msg", [{}, {"y": 1, "x": 2, "z": 3}]) @pytest.mark.parametrize("order", [None, "deterministic", "sorted"]) def test_frozendict_builtin_types_sorted(self, msg, order): msg = frozendict(msg) res = to_builtins(msg, builtin_types=[frozendict], order=order) sol = frozendict(sorted(msg.items())) if order else msg self.assert_eq(res, sol) assert type(res) is frozendict @pytest.mark.parametrize("typ", [set, frozenset]) @pytest.mark.parametrize("order", ["deterministic", "sorted"]) def test_order_set(self, typ, rand, order): assert to_builtins(typ(), order=order) == [] msg = typ(rand.str(10) for _ in range(20)) res = to_builtins(msg, order=order) self.assert_eq(res, sorted(msg)) res = to_builtins(msg) self.assert_eq(res, list(msg)) def test_order_set_unsortable(self): with pytest.raises(TypeError): to_builtins({"x", 1}, order="deterministic") @pytest.mark.parametrize("n", [0, 1, 2]) @pytest.mark.parametrize( "kind", [ "struct", "dataclass", "attrs", "attrs-dict", ], ) def test_order_object(self, kind, n): fields = [f"x{i}" for i in range(n)] fields.reverse() if kind == "struct": cls = defstruct("Test", fields) elif kind == "dataclass": cls = make_dataclass("Test", fields) else: attrs = pytest.importorskip("attrs") cls = attrs.make_class("Test", fields, slots=(kind == "attrs")) msg = cls(*range(n)) if kind in ("struct", "dataclass"): # we currently don't guarantee field order with attrs types res = to_builtins(msg) sol = dict(zip(fields, range(n))) self.assert_eq(res, sol) res = to_builtins(msg, order="deterministic") self.assert_eq(res, sol) res = to_builtins(msg, order="sorted") sol = dict(sorted(zip(fields, range(n)))) self.assert_eq(res, sol) @pytest.mark.parametrize("kind", ["struct", "dataclass", "attrs", "attrs-dict"]) def test_order_unset(self, kind): if kind == "struct": class Ex(Struct): z: int | UnsetType = UNSET x: int | UnsetType = UNSET elif kind == "dataclass": @dataclass class Ex: z: int | UnsetType = UNSET x: int | UnsetType = UNSET else: attrs = pytest.importorskip("attrs") @attrs.define(slots=(kind == "attrs")) class Ex: z: int | UnsetType = UNSET x: int | UnsetType = UNSET res = to_builtins(Ex(), order="sorted") self.assert_eq(res, {}) res = to_builtins(Ex(z=10), order="sorted") self.assert_eq(res, {"z": 10}) res = to_builtins(Ex(z=10, x=-1), order="sorted") self.assert_eq(res, {"x": -1, "z": 10}) def test_order_struct_omit_defaults(self): class Ex(Struct, omit_defaults=True): z: int = 0 x: int = 1 y: int = 2 res = to_builtins(Ex(), order="sorted") self.assert_eq(res, {}) res = to_builtins(Ex(z=10), order="sorted") self.assert_eq(res, {"z": 10}) res = to_builtins(Ex(z=10, x=-1), order="sorted") self.assert_eq(res, {"x": -1, "z": 10}) def test_order_struct_tag(self): class Ex(Struct, tag_field="y", tag=2): z: int x: int res = to_builtins(Ex(0, 1), order="sorted") self.assert_eq(res, {"x": 1, "y": 2, "z": 0}) python-msgspec-0.22.0/tests/unit/test_toml.py000066400000000000000000000133021525673062400212710ustar00rootroot00000000000000import dataclasses import datetime import enum import sys import uuid from decimal import Decimal import pytest import msgspec try: import tomllib except ImportError: try: import tomli as tomllib except ImportError: tomllib = None try: import tomli_w except ImportError: tomli_w = None from .utils import py315_or_later_only if sys.version_info >= (3, 15): # This is needed for `ruff` to recognize `frozendict` name # and to not raise `F821`: from builtins import frozendict needs_decode = pytest.mark.skipif( tomllib is None, reason="Neither tomllib or tomli are installed" ) needs_encode = pytest.mark.skipif(tomli_w is None, reason="tomli_w is not installed") PY311 = sys.version_info[:2] >= (3, 11) UTC = datetime.timezone.utc class ExStruct(msgspec.Struct): x: int y: str @dataclasses.dataclass class ExDataclass: x: int y: str class ExEnum(enum.Enum): one = "one" two = "two" class ExIntEnum(enum.IntEnum): one = 1 two = 2 def test_module_dir(): assert set(dir(msgspec.toml)) == {"encode", "decode"} @pytest.mark.skipif(PY311, reason="tomllib is builtin in 3.11+") def test_tomli_not_installed_error(monkeypatch): monkeypatch.setitem(sys.modules, "tomli", None) with pytest.raises(ImportError, match="conda install"): msgspec.toml.decode("a = 1", type=int) def test_tomli_w_not_installed_error(monkeypatch): monkeypatch.setitem(sys.modules, "tomli_w", None) with pytest.raises(ImportError, match="conda install"): msgspec.toml.encode({"a": 1}) @pytest.mark.parametrize( "val", [ True, False, 1, 1.5, "fizz", datetime.datetime(2022, 1, 2, 3, 4, 5, 6), datetime.datetime(2022, 1, 2, 3, 4, 5, 6, UTC), datetime.date(2022, 1, 2), datetime.time(12, 34), [1, 2], {"one": 2}, ], ) @needs_encode @needs_decode def test_roundtrip_any(val): msg = msgspec.toml.encode({"x": val}) res = msgspec.toml.decode(msg)["x"] assert res == val @pytest.mark.parametrize( "val, type", [ (True, bool), (False, bool), (1, int), (1.5, float), ("fizz", str), (b"fizz", bytes), (b"fizz", bytearray), (datetime.datetime(2022, 1, 2, 3, 4, 5, 6), datetime.datetime), (datetime.datetime(2022, 1, 2, 3, 4, 5, 6, UTC), datetime.datetime), (datetime.date(2022, 1, 2), datetime.date), (datetime.time(12, 34), datetime.time), (uuid.uuid4(), uuid.UUID), (ExEnum.one, ExEnum), (ExIntEnum.one, ExIntEnum), ([1, 2], list[int]), ((1, 2), tuple[int, ...]), ({1, 2}, set[int]), (frozenset({1, 2}), frozenset[int]), (("one", 2), tuple[str, int]), ({"one": 2}, dict[str, int]), ({1: "two"}, dict[int, str]), (ExStruct(1, "two"), ExStruct), (ExDataclass(1, "two"), ExDataclass), ], ) @needs_encode @needs_decode def test_roundtrip_typed(val, type): msg = msgspec.toml.encode({"x": val}) res = msgspec.toml.decode(msg, type=dict[str, type])["x"] assert res == val @py315_or_later_only @needs_encode @needs_decode def test_roundtrip_frozendict(): val = frozendict({"x": 1}) msg = msgspec.toml.encode(val) res = msgspec.toml.decode(msg, type=frozendict[str, int]) assert res == val assert type(res) is frozendict @needs_encode def test_encode_output_type(): msg = msgspec.toml.encode({"x": 1}) assert isinstance(msg, bytes) @needs_encode def test_encode_error(): class Oops: pass with pytest.raises(TypeError, match="Encoding objects of type Oops is unsupported"): msgspec.toml.encode({"x": Oops()}) @needs_encode @needs_decode def test_encode_enc_hook(): msg = msgspec.toml.encode({"x": Decimal(1.5)}, enc_hook=str) assert msgspec.toml.decode(msg) == {"x": "1.5"} @needs_encode @pytest.mark.parametrize("order", [None, "deterministic"]) def test_encode_order(order): msg = {"y": 1, "x": ({"n": 1, "m": 2},), "z": [{"b": 1, "a": 2}]} res = msgspec.toml.encode(msg, order=order) if order: sol_msg = {"x": ({"m": 2, "n": 1},), "y": 1, "z": [{"a": 2, "b": 1}]} else: sol_msg = msg sol = tomli_w.dumps(sol_msg).encode("utf-8") assert res == sol @needs_decode def test_decode_str_or_bytes_like(): assert msgspec.toml.decode("a = 1") == {"a": 1} assert msgspec.toml.decode(b"a = 1") == {"a": 1} assert msgspec.toml.decode(bytearray(b"a = 1")) == {"a": 1} assert msgspec.toml.decode(memoryview(b"a = 1")) == {"a": 1} with pytest.raises(TypeError): msgspec.toml.decode(1) @needs_decode @pytest.mark.parametrize("msg", [b"{{", b"!!binary 123"]) def test_decode_parse_error(msg): with pytest.raises(msgspec.DecodeError): msgspec.toml.decode(msg) @needs_decode def test_decode_validation_error(): with pytest.raises(msgspec.ValidationError, match="Expected `str`"): msgspec.toml.decode(b"a = [1, 2, 3]", type=dict[str, list[str]]) @needs_decode @pytest.mark.parametrize("strict", [True, False]) def test_decode_strict_or_lax(strict): msg = b"a = ['1', '2']" typ = dict[str, list[int]] if strict: with pytest.raises(msgspec.ValidationError, match="Expected `int`"): msgspec.toml.decode(msg, type=typ, strict=strict) else: res = msgspec.toml.decode(msg, type=typ, strict=strict) assert res == {"a": [1, 2]} @needs_decode def test_decode_dec_hook(): def dec_hook(typ, val): if typ is Decimal: return Decimal(val) raise TypeError res = msgspec.toml.decode("a = '1.5'", type=dict[str, Decimal], dec_hook=dec_hook) assert res == {"a": Decimal("1.5")} python-msgspec-0.22.0/tests/unit/test_utils.py000066400000000000000000000125731525673062400214670ustar00rootroot00000000000000from __future__ import annotations from typing import Generic, TypeVar import pytest from msgspec._utils import get_class_annotations from .utils import temp_module T = TypeVar("T") S = TypeVar("S") U = TypeVar("U") class Base(Generic[T]): x: T class Base2(Generic[T, S]): a: T b: S class TestGetClassAnnotations: @pytest.mark.parametrize("future_annotations", [False, True]) def test_eval_scopes(self, future_annotations): header = "from __future__ import annotations" if future_annotations else "" source = f""" {header} STR = str class Ex: LOCAL = float x: int y: LOCAL z: STR """ with temp_module(source) as mod: assert get_class_annotations(mod.Ex) == {"x": int, "y": float, "z": str} def test_none_to_nonetype(self): class Ex: x: None assert get_class_annotations(Ex) == {"x": type(None)} def test_subclass(self): class Base: x: int y: str class Sub(Base): x: float z: list class Base2: a: int class Sub2(Sub, Base2): b: float y: list assert get_class_annotations(Base) == {"x": int, "y": str} assert get_class_annotations(Sub) == {"x": float, "y": str, "z": list} assert get_class_annotations(Sub2) == { "x": float, "y": list, "z": list, "a": int, "b": float, } def test_simple_generic(self): class Test(Generic[T]): x: T y: list[T] z: int assert get_class_annotations(Test) == {"x": T, "y": list[T], "z": int} assert get_class_annotations(Test[int]) == {"x": int, "y": list[int], "z": int} assert get_class_annotations(Test[set[T]]) == { "x": set[T], "y": list[set[T]], "z": int, } def test_generic_sub1(self): class Sub(Base): y: int assert get_class_annotations(Sub) == {"x": T, "y": int} def test_generic_sub2(self): class Sub(Base, Generic[T]): y: list[T] assert get_class_annotations(Sub) == {"x": T, "y": list[T]} assert get_class_annotations(Sub[int]) == {"x": T, "y": list[int]} def test_generic_sub3(self): class Sub(Base[int], Generic[T]): y: list[T] assert get_class_annotations(Sub) == {"x": int, "y": list[T]} assert get_class_annotations(Sub[float]) == {"x": int, "y": list[float]} def test_generic_sub4(self): class Sub(Base[T]): y: list[T] assert get_class_annotations(Sub) == {"x": T, "y": list[T]} assert get_class_annotations(Sub[int]) == {"x": int, "y": list[int]} def test_generic_sub5(self): class Sub(Base[T], Generic[T]): y: list[T] assert get_class_annotations(Sub) == {"x": T, "y": list[T]} assert get_class_annotations(Sub[int]) == {"x": int, "y": list[int]} def test_generic_sub6(self): class Sub(Base[S]): y: list[S] assert get_class_annotations(Sub) == {"x": S, "y": list[S]} assert get_class_annotations(Sub[int]) == {"x": int, "y": list[int]} def test_generic_sub7(self): class Sub(Base[list[T]]): y: set[T] assert get_class_annotations(Sub) == {"x": list[T], "y": set[T]} assert get_class_annotations(Sub[int]) == {"x": list[int], "y": set[int]} def test_generic_sub8(self): class Sub(Base[int], Base2[float, str]): pass assert get_class_annotations(Sub) == {"x": int, "a": float, "b": str} def test_generic_sub9(self): class Sub(Base[U], Base2[list[U], U]): y: str assert get_class_annotations(Sub) == {"y": str, "x": U, "a": list[U], "b": U} assert get_class_annotations(Sub[int]) == { "y": str, "x": int, "a": list[int], "b": int, } class Sub2(Sub[int]): x: list assert get_class_annotations(Sub2) == { "x": list, "y": str, "a": list[int], "b": int, } def test_generic_sub10(self): class Sub(Base[U], Base2[list[U], U]): y: str class Sub3(Sub[list[T]]): c: T assert get_class_annotations(Sub3) == { "c": T, "y": str, "x": list[T], "a": list[list[T]], "b": list[T], } assert get_class_annotations(Sub3[int]) == { "c": int, "y": str, "x": list[int], "a": list[list[int]], "b": list[int], } def test_generic_sub11(self): class Sub(Base[int]): y: float class Sub2(Sub, Base[int]): z: str assert get_class_annotations(Sub2) == {"x": int, "y": float, "z": str} def test_generic_invalid_parameters(self): class Invalid: @property def __parameters__(self): pass class Sub(Base[Invalid]): pass assert get_class_annotations(Sub) == {"x": Invalid} def test_union_backport_installed(self): class Ex: x: int | None = None assert get_class_annotations(Ex) == {"x": int | None} python-msgspec-0.22.0/tests/unit/test_yaml.py000066400000000000000000000112451525673062400212640ustar00rootroot00000000000000import dataclasses import datetime import enum import sys import uuid from decimal import Decimal import pytest import msgspec try: import yaml # noqa except ImportError: pytestmark = pytest.mark.skip(reason="PyYAML is not installed") from .utils import py315_or_later_only if sys.version_info >= (3, 15): # This is needed for `ruff` to recognize `frozendict` name # and to not raise `F821`: from builtins import frozendict UTC = datetime.timezone.utc class ExStruct(msgspec.Struct): x: int y: str @dataclasses.dataclass class ExDataclass: x: int y: str class ExEnum(enum.Enum): one = "one" two = "two" class ExIntEnum(enum.IntEnum): one = 1 two = 2 def test_module_dir(): assert set(dir(msgspec.yaml)) == {"encode", "decode"} def test_pyyaml_not_installed_error(monkeypatch): monkeypatch.setitem(sys.modules, "yaml", None) with pytest.raises(ImportError, match="PyYAML"): msgspec.yaml.encode(1) with pytest.raises(ImportError, match="PyYAML"): msgspec.yaml.decode("1", type=int) @pytest.mark.parametrize( "val", [ None, True, False, 1, 1.5, "fizz", datetime.datetime(2022, 1, 2, 3, 4, 5, 6), datetime.datetime(2022, 1, 2, 3, 4, 5, 6, UTC), datetime.date(2022, 1, 2), [1, 2], {"one": 2}, {1: "two"}, ], ) def test_roundtrip_any(val): msg = msgspec.yaml.encode(val) res = msgspec.yaml.decode(msg) assert res == val @pytest.mark.parametrize( "val, type", [ (None, None), (True, bool), (False, bool), (1, int), (1.5, float), ("fizz", str), (b"fizz", bytes), (b"fizz", bytearray), (datetime.datetime(2022, 1, 2, 3, 4, 5, 6), datetime.datetime), (datetime.datetime(2022, 1, 2, 3, 4, 5, 6, UTC), datetime.datetime), (datetime.date(2022, 1, 2), datetime.date), (datetime.time(12, 34), datetime.time), (uuid.uuid4(), uuid.UUID), (ExEnum.one, ExEnum), (ExIntEnum.one, ExIntEnum), ([1, 2], list[int]), ((1, 2), tuple[int, ...]), ({1, 2}, set[int]), (frozenset({1, 2}), frozenset[int]), (("one", 2), tuple[str, int]), ({"one": 2}, dict[str, int]), ({1: "two"}, dict[int, str]), (ExStruct(1, "two"), ExStruct), (ExDataclass(1, "two"), ExDataclass), ], ) def test_roundtrip_typed(val, type): msg = msgspec.yaml.encode(val) res = msgspec.yaml.decode(msg, type=type) assert res == val @py315_or_later_only def test_roundtrip_frozendict(): val = frozendict({"x": 1}) msg = msgspec.yaml.encode(val) res = msgspec.yaml.decode(msg, type=frozendict[str, int]) assert res == val assert type(res) is frozendict def test_encode_error(): class Oops: pass with pytest.raises(TypeError, match="Encoding objects of type Oops is unsupported"): msgspec.yaml.encode(Oops()) def test_encode_enc_hook(): msg = msgspec.yaml.encode(Decimal(1.5), enc_hook=str) assert msgspec.yaml.decode(msg) == "1.5" @pytest.mark.parametrize("order", [None, "deterministic"]) def test_encode_order(order): msg = {"y": 1, "x": 2, "z": 3} res = msgspec.yaml.encode(msg, order=order) sol = yaml.safe_dump(msg, sort_keys=bool(order)).encode("utf-8") assert res == sol def test_decode_str_or_bytes_like(): assert msgspec.yaml.decode("[1, 2]") == [1, 2] assert msgspec.yaml.decode(b"[1, 2]") == [1, 2] assert msgspec.yaml.decode(bytearray(b"[1, 2]")) == [1, 2] assert msgspec.yaml.decode(memoryview(b"[1, 2]")) == [1, 2] with pytest.raises(TypeError): msgspec.yaml.decode(1) @pytest.mark.parametrize("msg", [b"{{", b"!!binary 123"]) def test_decode_parse_error(msg): with pytest.raises(msgspec.DecodeError): msgspec.yaml.decode(msg) def test_decode_validation_error(): with pytest.raises(msgspec.ValidationError, match="Expected `str`"): msgspec.yaml.decode(b"[1, 2, 3]", type=list[str]) @pytest.mark.parametrize("strict", [True, False]) def test_decode_strict_or_lax(strict): msg = b"a: ['1', '2']" typ = dict[str, list[int]] if strict: with pytest.raises(msgspec.ValidationError, match="Expected `int`"): msgspec.yaml.decode(msg, type=typ, strict=strict) else: res = msgspec.yaml.decode(msg, type=typ, strict=strict) assert res == {"a": [1, 2]} def test_decode_dec_hook(): def dec_hook(typ, val): if typ is Decimal: return Decimal(val) raise TypeError res = msgspec.yaml.decode("'1.5'", type=Decimal, dec_hook=dec_hook) assert res == Decimal("1.5") python-msgspec-0.22.0/tests/unit/utils.py000066400000000000000000000045451525673062400204300ustar00rootroot00000000000000import inspect import sys import sysconfig import textwrap import types import uuid from contextlib import contextmanager import pytest emscripten_stack_limited = pytest.mark.skipif( sys.platform == "emscripten", reason="Pyodide can overflow the JS/Wasm stack before raising RecursionError", ) # The C recursion limit on Windows ARM64 was lowered from 3000 to 1000 in # CPython 3.13 (python/cpython#117008); 3.12 still uses 3000. win_arm64_py312_stack_limited = pytest.mark.skipif( sysconfig.get_platform() == "win-arm64" and sys.version_info[:2] == (3, 12), reason="Python 3.12 on Windows ARM64 can overflow the C stack before raising RecursionError", ) py315_or_later_only = pytest.mark.skipif( sys.version_info < (3, 15), reason="frozendict was added in 3.15" ) @contextmanager def temp_module(code): """Mutually recursive struct types defined inside functions don't work (and probably never will). To avoid populating a bunch of test structs in the top level of this module, we instead create a temporary module per test to exec whatever is needed for that test""" code = textwrap.dedent(code) name = f"temp_{uuid.uuid4().hex}" mod = types.ModuleType(name) sys.modules[name] = mod try: exec(code, mod.__dict__) yield mod finally: sys.modules.pop(name, None) @contextmanager def max_call_depth(n): cur_depth = len(inspect.stack(0)) orig = sys.getrecursionlimit() try: # Our measure of the current stack depth can be off by a bit. Trying to # set a recursionlimit < the current depth will raise a RecursionError. # We just try again with a slightly higher limit, bailing after an # unreasonable amount of adjustments. for i in range(64): try: sys.setrecursionlimit(cur_depth + i + n) break except RecursionError: pass else: raise ValueError( "Failed to set low recursion limit, something is wrong here" ) yield finally: sys.setrecursionlimit(orig) @contextmanager def package_not_installed(name): try: orig = sys.modules.get(name) sys.modules[name] = None yield finally: if orig is not None: sys.modules[name] = orig else: del sys.modules[name]